Using anonymous structures to shrink size of Entity object.
This commit is contained in:
parent
b56cb72aec
commit
53c8c4984e
2
makefile
2
makefile
|
@ -22,7 +22,7 @@ include common.mk
|
|||
CXXFLAGS += `sdl2-config --cflags` -DVERSION=$(VERSION) -DREVISION=$(REVISION) -DDATA_DIR=\"$(DATA_DIR)\" -DLOCALE_DIR=\"$(LOCALE_DIR)\"
|
||||
CXXFLAGS += -Wall -Wempty-body -ansi -pedantic -Werror -Wstrict-prototypes -Werror=maybe-uninitialized -Warray-bounds
|
||||
CXXFLAGS += -g -lefence
|
||||
CXXFLAGS += -fms-extensions
|
||||
CXXFLAGS += -fms-extensions -std=gnu11
|
||||
|
||||
LDFLAGS += `sdl2-config --libs` -lSDL2_mixer -lSDL2_image -lSDL2_ttf -lm
|
||||
|
||||
|
|
|
@ -32,33 +32,6 @@ void lookForPlayer(void)
|
|||
|
||||
}
|
||||
|
||||
void preFire(Entity *e)
|
||||
{
|
||||
if (e->flags & EF_WEIGHTLESS)
|
||||
{
|
||||
if (world.bob->y < e->y && e->isOnGround && (int) (rand() % 4) == 0)
|
||||
{
|
||||
e->dy = JUMP_POWER;
|
||||
}
|
||||
}
|
||||
|
||||
e->facing = (world.bob->x < e->x) ? FACING_LEFT : FACING_RIGHT;
|
||||
|
||||
if (e->reload > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
e->attack();
|
||||
|
||||
e->shotsToFire--;
|
||||
|
||||
if (e->shotsToFire == 0)
|
||||
{
|
||||
e->walk();
|
||||
}
|
||||
}
|
||||
|
||||
int hasLineOfSight(Entity *src, Entity *dest)
|
||||
{
|
||||
return (!isBlockedByMap(src, dest) && !isBlockedByEntities(src, dest));
|
||||
|
@ -130,10 +103,5 @@ static int isBlockedByEntities(Entity *src, Entity *dest)
|
|||
|
||||
int enemyCanSeePlayer(Entity *e)
|
||||
{
|
||||
return hasLineOfSight(e, world.bob);
|
||||
}
|
||||
|
||||
int canFire(Entity *target)
|
||||
{
|
||||
return 0;
|
||||
return hasLineOfSight(e, (Entity*)world.bob);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "weapons.h"
|
||||
|
||||
Bullet *createBaseBullet(Entity *owner);
|
||||
Bullet *createBaseBullet(Unit *owner);
|
||||
|
||||
static int bulletSprite[2];
|
||||
static int plasmaSprite[2];
|
||||
|
@ -58,7 +58,7 @@ void initWeapons(void)
|
|||
missileSprite[1] = getSpriteIndex("MissileLeft");
|
||||
}
|
||||
|
||||
void firePistol(Entity *owner)
|
||||
void firePistol(Unit *owner)
|
||||
{
|
||||
Bullet *bullet;
|
||||
|
||||
|
@ -73,7 +73,7 @@ void firePistol(Entity *owner)
|
|||
playSound(SND_PISTOL, CH_PLAYER);
|
||||
}
|
||||
|
||||
void fireAimedShot(Entity *owner)
|
||||
void fireAimedShot(Unit *owner)
|
||||
{
|
||||
int x, y;
|
||||
float dx, dy;
|
||||
|
@ -96,7 +96,7 @@ void fireAimedShot(Entity *owner)
|
|||
playSound(SND_PISTOL, CH_WEAPON);
|
||||
}
|
||||
|
||||
void fireMachineGun(Entity *owner)
|
||||
void fireMachineGun(Unit *owner)
|
||||
{
|
||||
Bullet *bullet;
|
||||
|
||||
|
@ -109,7 +109,7 @@ void fireMachineGun(Entity *owner)
|
|||
playSound(SND_MACHINE_GUN, CH_WEAPON);
|
||||
}
|
||||
|
||||
void firePlasma(Entity *owner)
|
||||
void firePlasma(Unit *owner)
|
||||
{
|
||||
Bullet *bullet;
|
||||
|
||||
|
@ -124,7 +124,7 @@ void firePlasma(Entity *owner)
|
|||
playSound(SND_PLASMA, owner->type == ET_BOB ? CH_PLAYER : CH_WEAPON);
|
||||
}
|
||||
|
||||
void fireSpread(Entity *owner, int numberOfShots)
|
||||
void fireSpread(Unit *owner, int numberOfShots)
|
||||
{
|
||||
Bullet *bullet;
|
||||
int i;
|
||||
|
@ -148,7 +148,7 @@ void fireSpread(Entity *owner, int numberOfShots)
|
|||
playSound(SND_SPREAD, owner->type == ET_BOB ? CH_PLAYER : CH_WEAPON);
|
||||
}
|
||||
|
||||
void fireLaser(Entity *owner)
|
||||
void fireLaser(Unit *owner)
|
||||
{
|
||||
Bullet *laser;
|
||||
|
||||
|
@ -157,7 +157,6 @@ void fireLaser(Entity *owner)
|
|||
laser->y = owner->y + owner->h / 2;
|
||||
laser->facing = owner->facing;
|
||||
laser->dx = owner->facing == FACING_RIGHT ? 20 : -20;
|
||||
laser->owner = owner;
|
||||
laser->health = FPS * 3;
|
||||
laser->sprite[0] = laser->sprite[1] = (owner->type == ET_BOB) ? laserSprite[0] : laserSprite[1];
|
||||
|
||||
|
@ -166,7 +165,7 @@ void fireLaser(Entity *owner)
|
|||
playSound(SND_LASER, owner->type == ET_BOB ? CH_PLAYER : CH_WEAPON);
|
||||
}
|
||||
|
||||
void fireGrenade(Entity *owner)
|
||||
void fireGrenade(Unit *owner)
|
||||
{
|
||||
Bullet *grenade;
|
||||
|
||||
|
@ -174,7 +173,6 @@ void fireGrenade(Entity *owner)
|
|||
grenade->x = owner->x + owner->w / 2;
|
||||
grenade->y = owner->y;
|
||||
grenade->facing = owner->facing;
|
||||
grenade->owner = owner;
|
||||
grenade->health = FPS * 3;
|
||||
grenade->dx = owner->facing == FACING_RIGHT ? 8 : -8;
|
||||
grenade->sprite[0] = grenade->sprite[1] = (owner->type == ET_BOB) ? grenadeSprite : alienGrenadeSprite;
|
||||
|
@ -186,7 +184,7 @@ void fireGrenade(Entity *owner)
|
|||
playSound(SND_THROW, owner->type == ET_BOB ? CH_PLAYER : CH_WEAPON);
|
||||
}
|
||||
|
||||
void fireShotgun(Entity *owner)
|
||||
void fireShotgun(Unit *owner)
|
||||
{
|
||||
int i;
|
||||
float dx, dy;
|
||||
|
@ -211,7 +209,7 @@ void fireShotgun(Entity *owner)
|
|||
playSound(SND_SHOTGUN, CH_WEAPON);
|
||||
}
|
||||
|
||||
void fireMissile(Entity *owner)
|
||||
void fireMissile(Unit *owner)
|
||||
{
|
||||
Bullet *missile;
|
||||
|
||||
|
@ -220,7 +218,6 @@ void fireMissile(Entity *owner)
|
|||
missile->y = owner->y + 10;
|
||||
missile->facing = owner->facing;
|
||||
missile->dx = owner->facing == FACING_RIGHT ? 10 : -10;
|
||||
missile->owner = owner;
|
||||
missile->health = FPS * 3;
|
||||
missile->sprite[0] = missileSprite[0];
|
||||
missile->sprite[1] = missileSprite[1];
|
||||
|
@ -230,21 +227,21 @@ void fireMissile(Entity *owner)
|
|||
playSound(SND_MISSILE, CH_WEAPON);
|
||||
}
|
||||
|
||||
Bullet *createBaseBullet(Entity *owner)
|
||||
Bullet *createBaseBullet(Unit *owner)
|
||||
{
|
||||
Bullet *bullet;
|
||||
|
||||
bullet = malloc(sizeof(Bullet));
|
||||
memset(bullet, 0, sizeof(Bullet));
|
||||
world.bulletTail->next = bullet;
|
||||
world.bulletTail = bullet;
|
||||
world.entityTail->next = (Entity*)bullet;
|
||||
world.entityTail = (Entity*)bullet;
|
||||
|
||||
bullet->x = (owner->x + owner->w / 2);
|
||||
bullet->y = (owner->y + owner->h / 2) - 3;
|
||||
bullet->dx = owner->facing == FACING_RIGHT ? 15 : -15;
|
||||
bullet->facing = owner->facing;
|
||||
bullet->damage = 1;
|
||||
bullet->owner = owner;
|
||||
bullet->owner = (Entity*)owner;
|
||||
bullet->health = FPS * 3;
|
||||
bullet->flags |= EF_WEIGHTLESS | EF_IGNORE_BULLETS | EF_NO_ENVIRONMENT | EF_KILL_OFFSCREEN | EF_NO_TELEPORT;
|
||||
|
||||
|
|
198
src/structs.h
198
src/structs.h
|
@ -21,7 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
typedef struct Texture Texture;
|
||||
typedef struct Lookup Lookup;
|
||||
typedef struct Quadtree Quadtree;
|
||||
typedef struct Entity Entity;
|
||||
typedef struct Objective Objective;
|
||||
typedef struct Trigger Trigger;
|
||||
typedef struct Marker Marker;
|
||||
|
@ -31,7 +30,18 @@ typedef struct Tuple Tuple;
|
|||
typedef struct HubMission HubMission;
|
||||
typedef struct Widget Widget;
|
||||
typedef struct Atlas Atlas;
|
||||
|
||||
typedef struct Entity Entity;
|
||||
typedef struct EntityExt EntityExt;
|
||||
typedef struct Bob Bob;
|
||||
typedef struct Boss Boss;
|
||||
typedef struct Bullet Bullet;
|
||||
typedef struct Decoration Decoration;
|
||||
typedef struct Item Item;
|
||||
typedef struct MIA MIA;
|
||||
typedef struct Structure Structure;
|
||||
typedef struct Trap Trap;
|
||||
typedef struct Unit Unit;
|
||||
|
||||
typedef struct {
|
||||
int debug;
|
||||
|
@ -91,97 +101,131 @@ typedef struct {
|
|||
|
||||
struct Entity {
|
||||
unsigned long uniqueId;
|
||||
char name[MAX_NAME_LENGTH];
|
||||
char spriteName[MAX_NAME_LENGTH];
|
||||
char targetNames[MAX_DESCRIPTION_LENGTH];
|
||||
int type;
|
||||
float x;
|
||||
float y;
|
||||
int w;
|
||||
int h;
|
||||
int health;
|
||||
int healthMax;
|
||||
char name[MAX_NAME_LENGTH];
|
||||
float x, y;
|
||||
int w, h;
|
||||
int tx, ty;
|
||||
float dx, dy;
|
||||
int health, healthMax;
|
||||
int alive;
|
||||
int oxygen;
|
||||
int startX;
|
||||
int startY;
|
||||
float dx;
|
||||
float dy;
|
||||
int tx;
|
||||
int ty;
|
||||
int reload;
|
||||
int isOnGround;
|
||||
int effectType;
|
||||
int bleedTime;
|
||||
int active;
|
||||
int environment;
|
||||
int thinkTime;
|
||||
int facing;
|
||||
int damage;
|
||||
int sprite[3];
|
||||
int plane;
|
||||
int isSolid;
|
||||
int isStatic;
|
||||
int isOnGround;
|
||||
int isMissionTarget;
|
||||
SDL_Rect bounds;
|
||||
unsigned long flags;
|
||||
void (*init)(void);
|
||||
void (*action)(void);
|
||||
void (*touch)(Entity *other);
|
||||
void (*tick)(void);
|
||||
void (*reset)(void);
|
||||
void (*die)(void);
|
||||
void (*animate)(void);
|
||||
void (*walk)(void);
|
||||
void (*setSize)(void);
|
||||
float (*bounce)(float x);
|
||||
void (*teleport)(float tx, float ty);
|
||||
void (*activate)(int active);
|
||||
void (*applyDamage)(int amount);
|
||||
void (*changeEnvironment)(void);
|
||||
int (*getCurrentSprite)(void);
|
||||
int (*preSave)(void);
|
||||
SDL_Rect *(*getBounds)(void);
|
||||
Entity *next;
|
||||
};
|
||||
|
||||
struct EntityExt {
|
||||
struct Entity;
|
||||
char spriteName[MAX_NAME_LENGTH];
|
||||
int spriteTime;
|
||||
int spriteFrame;
|
||||
Item *carriedItem;
|
||||
};
|
||||
|
||||
struct Unit {
|
||||
struct EntityExt;
|
||||
int weaponType;
|
||||
int canCarryItem;
|
||||
int reload;
|
||||
int shotsToFire;
|
||||
int maxShotsToFire;
|
||||
int isSolid;
|
||||
int environment;
|
||||
int isStatic;
|
||||
int isMissionTarget;
|
||||
int thinkTime;
|
||||
int plane;
|
||||
int value;
|
||||
int canCarryItem;
|
||||
int spawnedIn;
|
||||
int spawnedInTimer;
|
||||
int oxygen;
|
||||
int spawnedIn;
|
||||
int startX, startY;
|
||||
void (*attack)(void);
|
||||
int (*canFire)(Entity *target);
|
||||
};
|
||||
|
||||
struct MIA {
|
||||
struct Unit;
|
||||
int shudderTimer;
|
||||
int starTimer;
|
||||
int teleportTimer;
|
||||
int stunTimer;
|
||||
};
|
||||
|
||||
struct Boss {
|
||||
struct Unit;
|
||||
int weakAgainst;
|
||||
int teleportTimer;
|
||||
int stunTimer;
|
||||
};
|
||||
|
||||
struct Item {
|
||||
struct EntityExt;
|
||||
int startX, startY;
|
||||
int power;
|
||||
int powerMax;
|
||||
int value;
|
||||
int weaponType;
|
||||
int provided;
|
||||
int collected;
|
||||
int canBeCarried;
|
||||
int canBePickedUp;
|
||||
int provided;
|
||||
int firstTouch;
|
||||
int active;
|
||||
float sinVal;
|
||||
};
|
||||
|
||||
struct Bob {
|
||||
struct Unit;
|
||||
int stunTimer;
|
||||
int power, powerMax;
|
||||
};
|
||||
|
||||
struct Structure {
|
||||
struct EntityExt;
|
||||
int bobTouching;
|
||||
int messageTimer;
|
||||
char message[MAX_DESCRIPTION_LENGTH];
|
||||
char requiredCard[MAX_NAME_LENGTH];
|
||||
char requiredKey[MAX_NAME_LENGTH];
|
||||
char requiredItem[MAX_NAME_LENGTH];
|
||||
int requiredPower;
|
||||
long flags;
|
||||
SDL_Rect bounds;
|
||||
int sprite[3];
|
||||
int spriteTime;
|
||||
int spriteFrame;
|
||||
int isLocked;
|
||||
int closedX;
|
||||
int closedY;
|
||||
char targetNames[MAX_DESCRIPTION_LENGTH];
|
||||
char message[MAX_DESCRIPTION_LENGTH];
|
||||
int state;
|
||||
int speed;
|
||||
int waitTime;
|
||||
int startX, startY;
|
||||
int closedX, closedY;
|
||||
int isLocked;
|
||||
int speed;
|
||||
int messageTimer;
|
||||
int firstTouch;
|
||||
int requiredPower;
|
||||
int isWeighted;
|
||||
float weightApplied;
|
||||
int weightApplied;
|
||||
float sinVal;
|
||||
};
|
||||
|
||||
struct Decoration {
|
||||
struct Entity;
|
||||
int effectType;
|
||||
int bleedTime;
|
||||
};
|
||||
|
||||
struct Trap {
|
||||
struct EntityExt;
|
||||
int onTime;
|
||||
int offTime;
|
||||
Entity *carriedItem;
|
||||
Entity *owner;
|
||||
void (*init)(void);
|
||||
void (*action)(void);
|
||||
void (*walk)(void);
|
||||
void (*attack)(void);
|
||||
void (*touch)(Entity *other);
|
||||
void (*tick)(void);
|
||||
void (*die)(void);
|
||||
int (*canFire)(Entity *target);
|
||||
void (*reset)(void);
|
||||
void (*activate)(int active);
|
||||
void (*changeEnvironment)(void);
|
||||
int (*getCurrentSprite)(void);
|
||||
void (*animate)(void);
|
||||
void (*applyDamage)(int amount);
|
||||
SDL_Rect (*getBounds)(void);
|
||||
Entity *next;
|
||||
};
|
||||
|
||||
struct Objective {
|
||||
|
@ -357,24 +401,17 @@ struct Particle {
|
|||
};
|
||||
|
||||
struct Bullet {
|
||||
int x;
|
||||
int y;
|
||||
int facing;
|
||||
struct Entity;
|
||||
int damage;
|
||||
int health;
|
||||
int weaponType;
|
||||
float dx;
|
||||
float dy;
|
||||
int sprite[2];
|
||||
long flags;
|
||||
Entity *owner;
|
||||
Bullet *next;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char id[MAX_NAME_LENGTH];
|
||||
int state;
|
||||
Entity *bob, *boss;
|
||||
Bob *bob;
|
||||
Boss *boss;
|
||||
Map map;
|
||||
int allObjectivesComplete;
|
||||
int frameCounter;
|
||||
|
@ -388,7 +425,6 @@ typedef struct {
|
|||
Quadtree quadtree;
|
||||
Entity entityHead, *entityTail;
|
||||
Particle particleHead, *particleTail;
|
||||
Bullet bulletHead, *bulletTail;
|
||||
Objective objectiveHead, *objectiveTail;
|
||||
Trigger triggerHead, *triggerTail;
|
||||
} World;
|
||||
|
|
|
@ -40,12 +40,12 @@ void addExplosionEffect(int x, int y, float dx, float dy)
|
|||
|
||||
void addSmallFleshChunk(double x, double y)
|
||||
{
|
||||
Entity *chunk;
|
||||
Decoration *chunk;
|
||||
|
||||
chunk = malloc(sizeof(Entity));
|
||||
memset(chunk, 0, sizeof(Entity));
|
||||
world.entityTail->next = chunk;
|
||||
world.entityTail = chunk;
|
||||
chunk = malloc(sizeof(Decoration));
|
||||
memset(chunk, 0, sizeof(Decoration));
|
||||
world.entityTail->next = (Entity*)chunk;
|
||||
world.entityTail = (Entity*)chunk;
|
||||
|
||||
chunk->x = x;
|
||||
chunk->y = y;
|
||||
|
@ -58,14 +58,14 @@ void addSmallFleshChunk(double x, double y)
|
|||
void throwFleshChunks(double x, double y, int amount)
|
||||
{
|
||||
int i;
|
||||
Entity *chunk;
|
||||
Decoration *chunk;
|
||||
|
||||
for (i = 0; i < amount; i++)
|
||||
{
|
||||
chunk = malloc(sizeof(Entity));
|
||||
memset(chunk, 0, sizeof(Entity));
|
||||
world.entityTail->next = chunk;
|
||||
world.entityTail = chunk;
|
||||
chunk = malloc(sizeof(Decoration));
|
||||
memset(chunk, 0, sizeof(Decoration));
|
||||
world.entityTail->next = (Entity*)chunk;
|
||||
world.entityTail = (Entity*)chunk;
|
||||
|
||||
chunk->x = x;
|
||||
chunk->y = y;
|
||||
|
|
|
@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "bob.h"
|
||||
|
||||
void addBobItem(Entity *e)
|
||||
void addBobItem(Item *i)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -28,24 +28,30 @@ static void teleport(void);
|
|||
|
||||
void initMIA(Entity *e)
|
||||
{
|
||||
e->tx = e->ty = -1;
|
||||
MIA *m;
|
||||
|
||||
initUnit(e);
|
||||
|
||||
m = (MIA*)e;
|
||||
|
||||
m->tx = m->ty = -1;
|
||||
|
||||
e->sprite[FACING_LEFT] = getSpriteIndex("MIA");
|
||||
e->sprite[FACING_RIGHT] = getSpriteIndex("MIA");
|
||||
e->sprite[FACING_DIE] = getSpriteIndex("MIA");
|
||||
m->sprite[FACING_LEFT] = getSpriteIndex("MIA");
|
||||
m->sprite[FACING_RIGHT] = getSpriteIndex("MIA");
|
||||
m->sprite[FACING_DIE] = getSpriteIndex("MIA");
|
||||
|
||||
e->flags |= EF_IGNORE_BULLETS;
|
||||
m->flags |= EF_IGNORE_BULLETS;
|
||||
|
||||
/* blink at random intervals */
|
||||
e->spriteFrame = 0;
|
||||
e->spriteTime = rand() % 180;
|
||||
m->spriteFrame = 0;
|
||||
m->spriteTime = rand() % 180;
|
||||
|
||||
e->action = nothing;
|
||||
e->reset = reset;
|
||||
e->tick = tick;
|
||||
e->touch = touch;
|
||||
m->action = nothing;
|
||||
m->reset = reset;
|
||||
m->tick = tick;
|
||||
m->touch = touch;
|
||||
|
||||
e->isMissionTarget = 1;
|
||||
m->isMissionTarget = 1;
|
||||
}
|
||||
|
||||
void reinitMIA(Entity *e)
|
||||
|
@ -64,56 +70,72 @@ static void reset(void)
|
|||
|
||||
static void tick(void)
|
||||
{
|
||||
self->shudderTimer--;
|
||||
if (self->shudderTimer <= 0)
|
||||
MIA *m;
|
||||
|
||||
m = (MIA*)self;
|
||||
|
||||
m->shudderTimer--;
|
||||
if (m->shudderTimer <= 0)
|
||||
{
|
||||
self->x = (self->tx + rand() % 4);
|
||||
self->shudderTimer = 2;
|
||||
m->x = (m->tx + rand() % 4);
|
||||
m->shudderTimer = 2;
|
||||
}
|
||||
|
||||
if (self->action != nothing)
|
||||
if (m->action != nothing)
|
||||
{
|
||||
self->starTimer--;
|
||||
if (self->starTimer <= 0)
|
||||
m->starTimer--;
|
||||
if (m->starTimer <= 0)
|
||||
{
|
||||
addMIATeleportStars(self->x + rand() % self->w, self->y + rand() % self->h);
|
||||
self->starTimer = 1;
|
||||
addMIATeleportStars(m->x + rand() % m->w, m->y + rand() % m->h);
|
||||
m->starTimer = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
if (self->action == nothing && other == world.bob)
|
||||
MIA *m;
|
||||
|
||||
m = (MIA*)self;
|
||||
|
||||
if (m->action == nothing && other == (Entity*)world.bob)
|
||||
{
|
||||
self->action = preTeleport;
|
||||
self->teleportTimer = FPS * 3;
|
||||
setGameplayMessage(MSG_OBJECTIVE, "Rescued %s", self->name);
|
||||
self->isMissionTarget = 0;
|
||||
self->flags |= EF_ALWAYS_PROCESS;
|
||||
m->action = preTeleport;
|
||||
m->teleportTimer = FPS * 3;
|
||||
setGameplayMessage(MSG_OBJECTIVE, "Rescued %s", m->name);
|
||||
m->isMissionTarget = 0;
|
||||
m->flags |= EF_ALWAYS_PROCESS;
|
||||
playSound(SND_MIA, CH_ANY);
|
||||
}
|
||||
}
|
||||
|
||||
static void preTeleport(void)
|
||||
{
|
||||
self->teleportTimer--;
|
||||
if (self->teleportTimer <= FPS)
|
||||
MIA *m;
|
||||
|
||||
m = (MIA*)self;
|
||||
|
||||
m->teleportTimer--;
|
||||
if (m->teleportTimer <= FPS)
|
||||
{
|
||||
self->action = teleport;
|
||||
self->flags |= (EF_NO_CLIP | EF_WEIGHTLESS);
|
||||
self->dy = -5;
|
||||
m->action = teleport;
|
||||
m->flags |= (EF_NO_CLIP | EF_WEIGHTLESS);
|
||||
m->dy = -5;
|
||||
}
|
||||
}
|
||||
|
||||
static void teleport(void)
|
||||
{
|
||||
self->teleportTimer--;
|
||||
if (self->teleportTimer <= 0)
|
||||
MIA *m;
|
||||
|
||||
m = (MIA*)self;
|
||||
|
||||
m->teleportTimer--;
|
||||
if (m->teleportTimer <= 0)
|
||||
{
|
||||
addTeleportStars(self);
|
||||
addRescuedMIA(self->name);
|
||||
addRescuedMIA(m->name);
|
||||
updateObjective("MIA");
|
||||
self->alive = ALIVE_DEAD;
|
||||
m->alive = ALIVE_DEAD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ extern void setGameplayMessage(int type, char *format, ...);
|
|||
extern void playSound(int snd, int ch);
|
||||
extern void updateObjective(char *targetName);
|
||||
extern void addRescuedMIA(char *name);
|
||||
extern void initUnit(Entity *e);
|
||||
|
||||
extern Entity *self;
|
||||
extern World world;
|
||||
|
|
|
@ -31,23 +31,29 @@ static int exitMission;
|
|||
|
||||
void initTeeka(Entity *e)
|
||||
{
|
||||
e->type = ET_TEEKA;
|
||||
Unit *u;
|
||||
|
||||
initUnit(e);
|
||||
|
||||
u = (Unit*)e;
|
||||
|
||||
u->type = ET_TEEKA;
|
||||
|
||||
u->flags |= EF_IMMUNE;
|
||||
|
||||
u->action = lookForEnemies;
|
||||
|
||||
u->weaponType = WPN_AIMED_PISTOL;
|
||||
|
||||
u->sprite[FACING_LEFT] = getSpriteIndex("TeekaLeft");
|
||||
u->sprite[FACING_RIGHT] = getSpriteIndex("TeekaRight");
|
||||
u->sprite[FACING_DIE] = getSpriteIndex("TeekaLeft");
|
||||
|
||||
u->health = e->healthMax = 9999;
|
||||
|
||||
u->tick = tick;
|
||||
|
||||
aimedSprite = getSpriteIndex("AimedShot");
|
||||
|
||||
e->flags |= EF_IMMUNE;
|
||||
|
||||
e->action = lookForEnemies;
|
||||
|
||||
e->weaponType = WPN_AIMED_PISTOL;
|
||||
|
||||
e->sprite[FACING_LEFT] = getSpriteIndex("TeekaLeft");
|
||||
e->sprite[FACING_RIGHT] = getSpriteIndex("TeekaRight");
|
||||
e->sprite[FACING_DIE] = getSpriteIndex("TeekaLeft");
|
||||
|
||||
e->health = e->healthMax = 9999;
|
||||
|
||||
e->tick = tick;
|
||||
}
|
||||
|
||||
static void tick(void)
|
||||
|
@ -73,8 +79,11 @@ static void lookForEnemies(void)
|
|||
{
|
||||
Entity *e;
|
||||
float distance, range;
|
||||
Unit *u;
|
||||
|
||||
self->thinkTime = rrnd(FPS / 2, FPS);
|
||||
u = (Unit*)self;
|
||||
|
||||
u->thinkTime = rrnd(FPS / 2, FPS);
|
||||
|
||||
target = NULL;
|
||||
|
||||
|
@ -84,7 +93,7 @@ static void lookForEnemies(void)
|
|||
{
|
||||
if (e->type == ET_ENEMY)
|
||||
{
|
||||
range = getDistance(self->x, self->y, e->x, e->y);
|
||||
range = getDistance(u->x, u->y, e->x, e->y);
|
||||
|
||||
if (range < distance)
|
||||
{
|
||||
|
@ -99,41 +108,45 @@ static void lookForEnemies(void)
|
|||
|
||||
if (target != NULL)
|
||||
{
|
||||
self->shotsToFire = rrnd(3, 5);
|
||||
u->shotsToFire = rrnd(3, 5);
|
||||
|
||||
self->action = preFire;
|
||||
u->action = preFire;
|
||||
}
|
||||
else if (exitMission)
|
||||
{
|
||||
addTeleportStars(self);
|
||||
self->alive = ALIVE_DEAD;
|
||||
u->alive = ALIVE_DEAD;
|
||||
playSound(SND_APPEAR, CH_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->facing = rand() % 2 == 0 ? FACING_LEFT : FACING_RIGHT;
|
||||
u->facing = rand() % 2 == 0 ? FACING_LEFT : FACING_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
static void preFire(void)
|
||||
{
|
||||
if (self->reload > 0)
|
||||
Unit *u;
|
||||
|
||||
u = (Unit*)self;
|
||||
|
||||
if (u->reload > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (target->y < self->y && self->isOnGround && rand() % 10 == 0)
|
||||
if (target->y < u->y && u->isOnGround && rand() % 10 == 0)
|
||||
{
|
||||
self->dy = JUMP_POWER;
|
||||
u->dy = JUMP_POWER;
|
||||
}
|
||||
|
||||
attack();
|
||||
|
||||
self->shotsToFire--;
|
||||
u->shotsToFire--;
|
||||
|
||||
if (self->shotsToFire == 0)
|
||||
if (u->shotsToFire == 0)
|
||||
{
|
||||
self->thinkTime = FPS;
|
||||
u->thinkTime = FPS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,7 +157,7 @@ static void attack(void)
|
|||
|
||||
getSlope(target->x, target->y, self->x, self->y, &dx, &dy);
|
||||
|
||||
bullet = createBaseBullet(self);
|
||||
bullet = createBaseBullet((Unit*)self);
|
||||
bullet->x = self->x;
|
||||
bullet->y = (self->y + self->h / 2) - 3;
|
||||
bullet->facing = self->facing;
|
||||
|
@ -157,7 +170,7 @@ static void attack(void)
|
|||
bullet->sprite[0] = bullet->sprite[1] = aimedSprite;
|
||||
bullet->health *= 2;
|
||||
|
||||
self->reload = 5;
|
||||
((Unit*)self)->reload = 5;
|
||||
}
|
||||
|
||||
void teekaExitMission(void)
|
||||
|
|
|
@ -20,10 +20,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "../../../common.h"
|
||||
|
||||
extern void initUnit(Entity *e);
|
||||
extern void unitTick(void);
|
||||
extern int getSpriteIndex(char *name);
|
||||
extern int rrnd(int low, int high);
|
||||
extern Bullet *createBaseBullet(Entity *owner);
|
||||
extern Bullet *createBaseBullet(Unit *owner);
|
||||
extern void getSlope(int x1, int y1, int x2, int y2, float *dx, float *dy);
|
||||
extern int getDistance(int x1, int y1, int x2, int y2);
|
||||
extern int hasLineOfSight(Entity *src, Entity *dest);
|
||||
|
|
|
@ -22,13 +22,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
void initBlaze(Entity *e)
|
||||
{
|
||||
initBlobBoss(e);
|
||||
Boss *b;
|
||||
|
||||
e->weakAgainst = ENV_WATER;
|
||||
b = (Boss*)e;
|
||||
|
||||
STRNCPY(e->name, "Blaze", MAX_NAME_LENGTH);
|
||||
initBlobBoss(b);
|
||||
|
||||
b->weakAgainst = ENV_WATER;
|
||||
|
||||
STRNCPY(b->name, "Blaze", MAX_NAME_LENGTH);
|
||||
|
||||
e->sprite[FACING_LEFT] = getSpriteIndex("BlazeLeft");
|
||||
e->sprite[FACING_RIGHT] = getSpriteIndex("BlazeRight");
|
||||
e->sprite[FACING_DIE] = getSpriteIndex("BlazeSpin");
|
||||
b->sprite[FACING_LEFT] = getSpriteIndex("BlazeLeft");
|
||||
b->sprite[FACING_RIGHT] = getSpriteIndex("BlazeRight");
|
||||
b->sprite[FACING_DIE] = getSpriteIndex("BlazeSpin");
|
||||
}
|
||||
|
|
|
@ -20,5 +20,5 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "../../../common.h"
|
||||
|
||||
extern void initBlobBoss(Entity *e);
|
||||
extern void initBlobBoss(Boss *b);
|
||||
extern int getSpriteIndex(char *name);
|
||||
|
|
|
@ -38,24 +38,28 @@ static int aimedSprite;
|
|||
|
||||
void initBlobBoss(Entity *e)
|
||||
{
|
||||
Boss *b;
|
||||
|
||||
initBoss(e);
|
||||
|
||||
b = (Boss*)e;
|
||||
|
||||
b->flags |= EF_HALT_AT_EDGE;
|
||||
|
||||
b->health = b->healthMax = 250;
|
||||
|
||||
b->teleportTimer = FPS * rrnd(4, 6);
|
||||
|
||||
b->activate = activate;
|
||||
b->walk = walk;
|
||||
b->tick = tick;
|
||||
b->changeEnvironment = changeEnvironment;
|
||||
b->getCurrentSprite = getCurrentSprite;
|
||||
b->animate = animate;
|
||||
b->applyDamage = applyDamage;
|
||||
b->die = die1;
|
||||
|
||||
aimedSprite = getSpriteIndex("AimedShot");
|
||||
|
||||
e->flags |= EF_HALT_AT_EDGE;
|
||||
|
||||
e->health = e->healthMax = 250;
|
||||
|
||||
e->teleportTimer = FPS * rrnd(4, 6);
|
||||
|
||||
e->activate = activate;
|
||||
e->walk = walk;
|
||||
e->tick = tick;
|
||||
e->changeEnvironment = changeEnvironment;
|
||||
e->getCurrentSprite = getCurrentSprite;
|
||||
e->animate = animate;
|
||||
e->applyDamage = applyDamage;
|
||||
e->die = die1;
|
||||
}
|
||||
|
||||
static void activate(int activate)
|
||||
|
@ -74,32 +78,36 @@ static void activate(int activate)
|
|||
|
||||
static void tick(void)
|
||||
{
|
||||
if (self->health > 0)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
if (b->health > 0)
|
||||
{
|
||||
self->stunTimer = MAX(self->stunTimer - 1, 0);
|
||||
b->stunTimer = MAX(b->stunTimer - 1, 0);
|
||||
|
||||
if (self->environment == self->weakAgainst)
|
||||
if (b->environment == b->weakAgainst)
|
||||
{
|
||||
self->health -= 2;
|
||||
b->health -= 2;
|
||||
|
||||
world.boss = self;
|
||||
world.boss = b;
|
||||
}
|
||||
|
||||
if (self->stunTimer == 0)
|
||||
if (b->stunTimer == 0)
|
||||
{
|
||||
self->facing = (world.bob->x < self->x) ? FACING_LEFT : FACING_RIGHT;
|
||||
b->facing = (world.bob->x < b->x) ? FACING_LEFT : FACING_RIGHT;
|
||||
|
||||
self->reload = limit(--self->reload, 0, FPS);
|
||||
b->reload = limit(--b->reload, 0, FPS);
|
||||
|
||||
self->teleportTimer = limit(self->teleportTimer - 1, 0, 9999);
|
||||
b->teleportTimer = limit(b->teleportTimer - 1, 0, 9999);
|
||||
|
||||
if (self->isOnGround)
|
||||
if (b->isOnGround)
|
||||
{
|
||||
self->flags |= EF_HALT_AT_EDGE;
|
||||
b->flags |= EF_HALT_AT_EDGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->flags &= ~EF_HALT_AT_EDGE;
|
||||
b->flags &= ~EF_HALT_AT_EDGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,35 +115,43 @@ static void tick(void)
|
|||
|
||||
static void changeEnvironment()
|
||||
{
|
||||
if (self->environment == self->weakAgainst)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
if (b->environment == b->weakAgainst)
|
||||
{
|
||||
self->teleportTimer = 0;
|
||||
self->stunTimer = 90;
|
||||
self->spriteFrame = self->spriteTime = 0;
|
||||
b->teleportTimer = 0;
|
||||
b->stunTimer = 90;
|
||||
b->spriteFrame = b->spriteTime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->teleportTimer = 0;
|
||||
b->teleportTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void die1(void)
|
||||
{
|
||||
self->flags |= EF_BOUNCES;
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
b->flags |= EF_BOUNCES;
|
||||
|
||||
self->thinkTime = 0;
|
||||
b->thinkTime = 0;
|
||||
|
||||
self->spriteTime = 0;
|
||||
self->spriteFrame = 0;
|
||||
b->spriteTime = 0;
|
||||
b->spriteFrame = 0;
|
||||
|
||||
if (self->environment == ENV_AIR)
|
||||
if (b->environment == ENV_AIR)
|
||||
{
|
||||
self->dy = -9;
|
||||
b->dy = -9;
|
||||
}
|
||||
|
||||
self->dx = (randF() - randF()) * 5;
|
||||
b->dx = (randF() - randF()) * 5;
|
||||
|
||||
self->flags &= ~EF_HALT_AT_EDGE;
|
||||
b->flags &= ~EF_HALT_AT_EDGE;
|
||||
|
||||
switch (rand() % 3)
|
||||
{
|
||||
|
@ -152,22 +168,30 @@ static void die1(void)
|
|||
break;
|
||||
}
|
||||
|
||||
self->action = die2;
|
||||
b->action = die2;
|
||||
}
|
||||
|
||||
static int getCurrentSprite(void)
|
||||
{
|
||||
if (self->stunTimer > 0 || self->health <= 0)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
if (b->stunTimer > 0 || b->health <= 0)
|
||||
{
|
||||
return self->sprite[FACING_DIE];
|
||||
return b->sprite[FACING_DIE];
|
||||
}
|
||||
|
||||
return self->sprite[self->facing];
|
||||
return b->sprite[b->facing];
|
||||
}
|
||||
|
||||
static void animate(void)
|
||||
{
|
||||
if (self->dx != 0 || self->health <= 0 || self->stunTimer > 0)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
if (b->dx != 0 || b->health <= 0 || b->stunTimer > 0)
|
||||
{
|
||||
animateEntity(self);
|
||||
}
|
||||
|
@ -175,9 +199,13 @@ static void animate(void)
|
|||
|
||||
static void lookForPlayer(void)
|
||||
{
|
||||
self->thinkTime = rrnd(0, FPS / 2);
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
b->thinkTime = rrnd(0, FPS / 2);
|
||||
|
||||
if (getDistance(world.bob->x, world.bob->y, self->x, self->y) > 650)
|
||||
if (getDistance(world.bob->x, world.bob->y, b->x, b->y) > 650)
|
||||
{
|
||||
moveTowardsPlayer();
|
||||
return;
|
||||
|
@ -191,8 +219,8 @@ static void lookForPlayer(void)
|
|||
|
||||
if (rand() % 100 < 15)
|
||||
{
|
||||
self->shotsToFire = rrnd(1, 12);
|
||||
self->action = preFire;
|
||||
b->shotsToFire = rrnd(1, 12);
|
||||
b->action = preFire;
|
||||
}
|
||||
|
||||
moveTowardsPlayer();
|
||||
|
@ -200,48 +228,56 @@ static void lookForPlayer(void)
|
|||
|
||||
static void moveTowardsPlayer(void)
|
||||
{
|
||||
self->dx = 0;
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
b->dx = 0;
|
||||
|
||||
if (rand() % 100 < 20)
|
||||
{
|
||||
if (world.bob->x < self->x)
|
||||
if (world.bob->x < b->x)
|
||||
{
|
||||
self->dx = -3.5;
|
||||
b->dx = -3.5;
|
||||
}
|
||||
|
||||
if (world.bob->x > self->x)
|
||||
if (world.bob->x > b->x)
|
||||
{
|
||||
self->dx = 3.5;
|
||||
b->dx = 3.5;
|
||||
}
|
||||
|
||||
if (world.bob->y <= self->y && rand() % 2 == 0 && self->isOnGround)
|
||||
if (world.bob->y <= b->y && rand() % 2 == 0 && b->isOnGround)
|
||||
{
|
||||
self->dy = JUMP_POWER;
|
||||
b->dy = JUMP_POWER;
|
||||
}
|
||||
}
|
||||
|
||||
if (self->stunTimer == 0 && self->teleportTimer == 0)
|
||||
if (b->stunTimer == 0 && b->teleportTimer == 0)
|
||||
{
|
||||
teleport();
|
||||
|
||||
self->teleportTimer = FPS * rrnd(4, 6);
|
||||
b->teleportTimer = FPS * rrnd(4, 6);
|
||||
}
|
||||
}
|
||||
|
||||
static void preFire(void)
|
||||
{
|
||||
if (self->reload > 0)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
if (b->reload > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
attack();
|
||||
|
||||
self->shotsToFire--;
|
||||
b->shotsToFire--;
|
||||
|
||||
if (self->shotsToFire == 0)
|
||||
if (b->shotsToFire == 0)
|
||||
{
|
||||
self->walk();
|
||||
b->walk();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,7 +292,7 @@ static void attack(void)
|
|||
|
||||
getSlope(bx, by, self->x, self->y, &dx, &dy);
|
||||
|
||||
bullet = createBaseBullet(self);
|
||||
bullet = createBaseBullet((Unit*)self);
|
||||
bullet->x = self->x;
|
||||
bullet->y = (self->y + self->h / 2) - 3;
|
||||
bullet->facing = self->facing;
|
||||
|
@ -268,7 +304,7 @@ static void attack(void)
|
|||
bullet->dy = dy * 12;
|
||||
bullet->sprite[0] = bullet->sprite[1] = aimedSprite;
|
||||
|
||||
self->reload = 4;
|
||||
((Boss*)self)->reload = 4;
|
||||
|
||||
playSound(SND_MACHINE_GUN, CH_WEAPON);
|
||||
}
|
||||
|
@ -315,7 +351,7 @@ static void applyDamage(int amount)
|
|||
teleport();
|
||||
}
|
||||
|
||||
world.boss = self;
|
||||
world.boss = (Boss*)self;
|
||||
}
|
||||
|
||||
static void teleport(void)
|
||||
|
@ -329,19 +365,23 @@ static void teleport(void)
|
|||
|
||||
static void die2(void)
|
||||
{
|
||||
self->health--;
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
b->health--;
|
||||
|
||||
if (self->health <= -FPS)
|
||||
if (b->health <= -FPS)
|
||||
{
|
||||
addTeleportStars(self);
|
||||
|
||||
playSound(SND_APPEAR, CH_ANY);
|
||||
|
||||
self->alive = ALIVE_DEAD;
|
||||
b->alive = ALIVE_DEAD;
|
||||
|
||||
updateObjective(self->name);
|
||||
updateObjective(b->name);
|
||||
|
||||
addDefeatedTarget(self->name);
|
||||
addDefeatedTarget(b->name);
|
||||
|
||||
game.enemiesKilled++;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ extern float limit(float i, float a, float b);
|
|||
extern double randF(void);
|
||||
extern void playSound(int snd, int ch);
|
||||
extern void animateEntity(Entity *e);
|
||||
extern Bullet *createBaseBullet(Entity *owner);
|
||||
extern Bullet *createBaseBullet(Unit *owner);
|
||||
extern int getSpriteIndex(char *name);
|
||||
extern int getDistance(int x1, int y1, int x2, int y2);
|
||||
extern void getSlope(int x1, int y1, int x2, int y2, float *dx, float *dy);
|
||||
|
|
|
@ -22,18 +22,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
void initBoss(Entity *e)
|
||||
{
|
||||
Boss *b;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
e->sprite[FACING_LEFT] = e->sprite[FACING_RIGHT] = e->sprite[FACING_DIE] = getSpriteIndex("Boss");
|
||||
b = (Boss*)e;
|
||||
|
||||
e->isMissionTarget = 1;
|
||||
b->sprite[FACING_LEFT] = b->sprite[FACING_RIGHT] = b->sprite[FACING_DIE] = getSpriteIndex("Boss");
|
||||
|
||||
b->isMissionTarget = 1;
|
||||
|
||||
e->action = lookForPlayer;
|
||||
b->action = lookForPlayer;
|
||||
|
||||
e->spriteFrame = 0;
|
||||
e->spriteTime = 0;
|
||||
b->spriteFrame = 0;
|
||||
b->spriteTime = 0;
|
||||
|
||||
world.boss = e;
|
||||
world.boss = b;
|
||||
|
||||
e->flags |= EF_ALWAYS_PROCESS | EF_BOMB_SHIELD | EF_GONE;
|
||||
b->flags |= EF_ALWAYS_PROCESS | EF_BOMB_SHIELD | EF_GONE;
|
||||
}
|
||||
|
|
|
@ -42,23 +42,27 @@ static int plasmaSprite[2];
|
|||
|
||||
void initEyeDroidCommander(Entity *e)
|
||||
{
|
||||
Boss *b;
|
||||
|
||||
initBoss(e);
|
||||
|
||||
STRNCPY(e->name, "EyeDroid Commander", MAX_NAME_LENGTH);
|
||||
|
||||
e->sprite[FACING_LEFT] = getSpriteIndex("DroidCommanderLeft");
|
||||
e->sprite[FACING_RIGHT] = getSpriteIndex("DroidCommanderRight");
|
||||
e->sprite[FACING_DIE] = getSpriteIndex("DroidCommanderDie");
|
||||
b = (Boss*)e;
|
||||
|
||||
e->flags |= EF_WEIGHTLESS | EF_EXPLODES;
|
||||
STRNCPY(b->name, "EyeDroid Commander", MAX_NAME_LENGTH);
|
||||
|
||||
e->health = e->healthMax = 250;
|
||||
b->sprite[FACING_LEFT] = getSpriteIndex("DroidCommanderLeft");
|
||||
b->sprite[FACING_RIGHT] = getSpriteIndex("DroidCommanderRight");
|
||||
b->sprite[FACING_DIE] = getSpriteIndex("DroidCommanderDie");
|
||||
|
||||
e->walk = walk;
|
||||
e->tick = tick;
|
||||
e->activate = activate;
|
||||
e->applyDamage = applyDamage;
|
||||
e->getCurrentSprite = getCurrentSprite;
|
||||
b->flags |= EF_WEIGHTLESS | EF_EXPLODES;
|
||||
|
||||
b->health = b->healthMax = 250;
|
||||
|
||||
b->walk = walk;
|
||||
b->tick = tick;
|
||||
b->activate = activate;
|
||||
b->applyDamage = applyDamage;
|
||||
b->getCurrentSprite = getCurrentSprite;
|
||||
|
||||
brakingTimer = 0;
|
||||
|
||||
|
@ -84,23 +88,27 @@ static void activate(int activate)
|
|||
|
||||
static void tick(void)
|
||||
{
|
||||
if (self->health > 0)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
if (b->health > 0)
|
||||
{
|
||||
self->facing = (world.bob->x < self->x) ? FACING_LEFT : FACING_RIGHT;
|
||||
b->facing = (world.bob->x < b->x) ? FACING_LEFT : FACING_RIGHT;
|
||||
|
||||
self->reload = (int) limit(self->reload - 1, 0, FPS);
|
||||
b->reload = (int) limit(b->reload - 1, 0, FPS);
|
||||
|
||||
brakingTimer = (int) limit(--brakingTimer, 0, FPS);
|
||||
|
||||
if (brakingTimer > 0)
|
||||
{
|
||||
self->dx *= 0.95;
|
||||
self->dy *= 0.95;
|
||||
b->dx *= 0.95;
|
||||
b->dy *= 0.95;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addSmokeParticles(self->x + (self->w / 2), self->y);
|
||||
addSmokeParticles(b->x + (b->w / 2), b->y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,23 +143,27 @@ static void lookForPlayer(void)
|
|||
|
||||
static void selectWeapon(void)
|
||||
{
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
if (world.bob->isOnGround || abs(self->y - world.bob->y) > 64)
|
||||
{
|
||||
self->weaponType = WPN_AIMED_PISTOL;
|
||||
self->shotsToFire = rrnd(1, 12);
|
||||
self->action = preFire;
|
||||
b->weaponType = WPN_AIMED_PISTOL;
|
||||
b->shotsToFire = rrnd(1, 12);
|
||||
b->action = preFire;
|
||||
}
|
||||
else if (rand() % 4 == 0)
|
||||
{
|
||||
self->weaponType = WPN_MISSILE;
|
||||
self->shotsToFire = rrnd(1, 3);
|
||||
self->action = preFire;
|
||||
b->weaponType = WPN_MISSILE;
|
||||
b->shotsToFire = rrnd(1, 3);
|
||||
b->action = preFire;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->weaponType = WPN_PLASMA;
|
||||
self->shotsToFire = rrnd(1, 12);
|
||||
self->action = preFire;
|
||||
b->weaponType = WPN_PLASMA;
|
||||
b->shotsToFire = rrnd(1, 12);
|
||||
b->action = preFire;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,24 +203,32 @@ static void moveTowardsPlayer(void)
|
|||
|
||||
static void preFire(void)
|
||||
{
|
||||
if (self->reload > 0)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
if (b->reload > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
attack();
|
||||
|
||||
self->shotsToFire--;
|
||||
b->shotsToFire--;
|
||||
|
||||
if (self->shotsToFire == 0)
|
||||
if (b->shotsToFire == 0)
|
||||
{
|
||||
self->walk();
|
||||
b->walk();
|
||||
}
|
||||
}
|
||||
|
||||
static void attack(void)
|
||||
{
|
||||
switch (self->weaponType)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
switch (b->weaponType)
|
||||
{
|
||||
case WPN_AIMED_PISTOL:
|
||||
attackPistol();
|
||||
|
@ -229,13 +249,16 @@ static void attackPistol(void)
|
|||
int bx, by;
|
||||
float dx, dy;
|
||||
Bullet *bullet;
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
bx = world.bob->x + rrnd(-8, 24);
|
||||
by = world.bob->y + rrnd(-8, 24);
|
||||
|
||||
getSlope(bx, by, self->x, self->y, &dx, &dy);
|
||||
|
||||
bullet = createBaseBullet(self);
|
||||
bullet = createBaseBullet((Unit*)self);
|
||||
bullet->x = (self->x + self->w / 2);
|
||||
bullet->y = (self->y + self->h / 2) - 3;
|
||||
bullet->facing = self->facing;
|
||||
|
@ -247,16 +270,19 @@ static void attackPistol(void)
|
|||
bullet->dy = dy * 12;
|
||||
bullet->sprite[0] = bullet->sprite[1] = aimedSprite;
|
||||
|
||||
self->reload = 4;
|
||||
b->reload = 4;
|
||||
|
||||
playSound(SND_MACHINE_GUN, CH_WEAPON);
|
||||
}
|
||||
|
||||
static void attackPlasma(void)
|
||||
{
|
||||
Boss *b;
|
||||
Bullet *bullet;
|
||||
|
||||
bullet = createBaseBullet(self);
|
||||
b = (Boss*)self;
|
||||
|
||||
bullet = createBaseBullet((Unit*)self);
|
||||
bullet->x = (self->x + self->w / 2);
|
||||
bullet->y = (self->y + self->h / 2) - 3;
|
||||
bullet->facing = self->facing;
|
||||
|
@ -269,26 +295,29 @@ static void attackPlasma(void)
|
|||
bullet->sprite[0] = plasmaSprite[0];
|
||||
bullet->sprite[1] = plasmaSprite[1];
|
||||
|
||||
self->reload = 4;
|
||||
b->reload = 4;
|
||||
|
||||
playSound(SND_PLASMA, CH_WEAPON);
|
||||
}
|
||||
|
||||
static void attackMissile(void)
|
||||
{
|
||||
Boss *b;
|
||||
Bullet *missile;
|
||||
|
||||
missile = createBaseBullet(self);
|
||||
missile->x = self->x + self->w / 2;
|
||||
missile->y = self->y + self->h / 2;
|
||||
missile->facing = self->facing;
|
||||
missile->dx = self->facing == FACING_RIGHT ? 15 : -15;
|
||||
b = (Boss*)self;
|
||||
|
||||
missile = createBaseBullet((Unit*)self);
|
||||
missile->x = b->x + b->w / 2;
|
||||
missile->y = b->y + b->h / 2;
|
||||
missile->facing = b->facing;
|
||||
missile->dx = b->facing == FACING_RIGHT ? 15 : -15;
|
||||
missile->owner = self;
|
||||
missile->health = FPS * 3;
|
||||
missile->sprite[0] = missileSprite[0];
|
||||
missile->sprite[1] = missileSprite[1];
|
||||
|
||||
self->reload = 15;
|
||||
b->reload = 15;
|
||||
|
||||
playSound(SND_MISSILE, CH_WEAPON);
|
||||
}
|
||||
|
@ -306,16 +335,20 @@ static void applyDamage(int amount)
|
|||
|
||||
static void die1(void)
|
||||
{
|
||||
self->dx = (randF() - randF()) * 3;
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
b->dx = (randF() - randF()) * 3;
|
||||
|
||||
self->spriteTime = 0;
|
||||
self->spriteFrame = 0;
|
||||
b->spriteTime = 0;
|
||||
b->spriteFrame = 0;
|
||||
|
||||
self->action = die2;
|
||||
self->thinkTime = 0;
|
||||
self->flags &= ~(EF_WEIGHTLESS | EF_HALT_AT_EDGE);
|
||||
b->action = die2;
|
||||
b->thinkTime = 0;
|
||||
b->flags &= ~(EF_WEIGHTLESS | EF_HALT_AT_EDGE);
|
||||
|
||||
self->dy = JUMP_POWER;
|
||||
b->dy = JUMP_POWER;
|
||||
|
||||
if (rand() % 2)
|
||||
{
|
||||
|
@ -329,17 +362,21 @@ static void die1(void)
|
|||
|
||||
static void die2()
|
||||
{
|
||||
if (self->isOnGround)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
if (b->isOnGround)
|
||||
{
|
||||
addTeleportStars(self);
|
||||
|
||||
playSound(SND_APPEAR, CH_ANY);
|
||||
|
||||
self->alive = ALIVE_DEAD;
|
||||
b->alive = ALIVE_DEAD;
|
||||
|
||||
updateObjective(self->name);
|
||||
updateObjective(b->name);
|
||||
|
||||
addDefeatedTarget(self->name);
|
||||
addDefeatedTarget(b->name);
|
||||
|
||||
game.enemiesKilled++;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ extern void addDefeatedTarget(char *name);
|
|||
extern void updateObjective(char *targetName);
|
||||
extern double randF(void);
|
||||
extern void playSound(int snd, int ch);
|
||||
extern Bullet *createBaseBullet(Entity *owner);
|
||||
extern Bullet *createBaseBullet(Unit *owner);
|
||||
extern void getSlope(int x1, int y1, int x2, int y2, float *dx, float *dy);
|
||||
extern void addExplosion(float x, float y, int radius, Entity *owner);
|
||||
|
||||
|
|
|
@ -22,13 +22,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
void initFrost(Entity *e)
|
||||
{
|
||||
Boss *b;
|
||||
|
||||
initBlobBoss(e);
|
||||
|
||||
e->weakAgainst = ENV_LAVA;
|
||||
b = (Boss*)e;
|
||||
|
||||
STRNCPY(e->name, "Frost", MAX_NAME_LENGTH);
|
||||
b->weakAgainst = ENV_LAVA;
|
||||
|
||||
STRNCPY(b->name, "Frost", MAX_NAME_LENGTH);
|
||||
|
||||
e->sprite[FACING_LEFT] = getSpriteIndex("FrostLeft");
|
||||
e->sprite[FACING_RIGHT] = getSpriteIndex("FrostRight");
|
||||
e->sprite[FACING_DIE] = getSpriteIndex("FrostSpin");
|
||||
b->sprite[FACING_LEFT] = getSpriteIndex("FrostLeft");
|
||||
b->sprite[FACING_RIGHT] = getSpriteIndex("FrostRight");
|
||||
b->sprite[FACING_DIE] = getSpriteIndex("FrostSpin");
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ static void die1(void);
|
|||
static void die2(void);
|
||||
static void attack(void);
|
||||
static void applyDamage(int amount);
|
||||
static SDL_Rect getBounds(void);
|
||||
static SDL_Rect *getBounds(void);
|
||||
static void preFire(void);
|
||||
static void selectWeapon(void);
|
||||
static void moveTowardsPlayer(void);
|
||||
|
@ -41,28 +41,32 @@ static int aimedSprite;
|
|||
|
||||
void initTankCommander(Entity *e)
|
||||
{
|
||||
Boss *b;
|
||||
|
||||
initBoss(e);
|
||||
|
||||
b = (Boss*)e;
|
||||
|
||||
STRNCPY(e->name, "Tank Commander", MAX_NAME_LENGTH);
|
||||
|
||||
e->sprite[FACING_LEFT] = getSpriteIndex("TankCommanderLeft");
|
||||
e->sprite[FACING_RIGHT] = getSpriteIndex("TankCommanderRight");
|
||||
e->sprite[FACING_DIE] = getSpriteIndex("TankCommanderDie");
|
||||
b->sprite[FACING_LEFT] = getSpriteIndex("TankCommanderLeft");
|
||||
b->sprite[FACING_RIGHT] = getSpriteIndex("TankCommanderRight");
|
||||
b->sprite[FACING_DIE] = getSpriteIndex("TankCommanderDie");
|
||||
|
||||
e->flags |= EF_EXPLODES;
|
||||
b->flags |= EF_EXPLODES;
|
||||
|
||||
e->health = e->healthMax = 400;
|
||||
b->health = e->healthMax = 400;
|
||||
|
||||
e->activate = activate;
|
||||
e->walk = walk;
|
||||
e->tick = tick;
|
||||
e->die = die1;
|
||||
e->applyDamage = applyDamage;
|
||||
e->getBounds = getBounds;
|
||||
b->activate = activate;
|
||||
b->walk = walk;
|
||||
b->tick = tick;
|
||||
b->die = die1;
|
||||
b->applyDamage = applyDamage;
|
||||
b->getBounds = getBounds;
|
||||
|
||||
brakingTimer = 0;
|
||||
|
||||
world.boss = e;
|
||||
world.boss = b;
|
||||
|
||||
aimedSprite = getSpriteIndex("AimedShot");
|
||||
|
||||
|
@ -74,7 +78,11 @@ void initTankCommander(Entity *e)
|
|||
|
||||
static void activate(int activate)
|
||||
{
|
||||
self->flags &= ~EF_GONE;
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
b->flags &= ~EF_GONE;
|
||||
tankTrack->flags &= ~EF_GONE;
|
||||
|
||||
world.isBossActive = 1;
|
||||
|
@ -87,32 +95,40 @@ static void activate(int activate)
|
|||
|
||||
static void tick(void)
|
||||
{
|
||||
if (self->health > 0)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
if (b->health > 0)
|
||||
{
|
||||
self->facing = (world.bob->x < self->x) ? FACING_LEFT : FACING_RIGHT;
|
||||
b->facing = (world.bob->x < b->x) ? FACING_LEFT : FACING_RIGHT;
|
||||
|
||||
self->reload = limit(self->reload - 1, 0, FPS);
|
||||
b->reload = limit(b->reload - 1, 0, FPS);
|
||||
|
||||
brakingTimer = limit(brakingTimer - 1, 0, FPS);
|
||||
|
||||
if (brakingTimer > 0)
|
||||
{
|
||||
self->dx *= 0.9;
|
||||
self->dy *= 0.9;
|
||||
b->dx *= 0.9;
|
||||
b->dy *= 0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void lookForPlayer(void)
|
||||
{
|
||||
self->thinkTime = rrnd(0, FPS / 2);
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
b->thinkTime = rrnd(0, FPS / 2);
|
||||
|
||||
if (rand() % 10 == 0)
|
||||
{
|
||||
brakingTimer = rrnd(60, 120);
|
||||
}
|
||||
|
||||
if (getDistance(world.bob->x, world.bob->y, self->x, self->y) > 650)
|
||||
if (getDistance(world.bob->x, world.bob->y, b->x, b->y) > 650)
|
||||
{
|
||||
moveTowardsPlayer();
|
||||
return;
|
||||
|
@ -157,23 +173,31 @@ static void moveTowardsPlayer(void)
|
|||
|
||||
static void selectWeapon(void)
|
||||
{
|
||||
if (abs(self->y - world.bob->y) > 64)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
if (abs(b->y - world.bob->y) > 64)
|
||||
{
|
||||
self->weaponType = WPN_AIMED_PISTOL;
|
||||
self->shotsToFire = rrnd(4, 12);
|
||||
self->action = preFire;
|
||||
b->weaponType = WPN_AIMED_PISTOL;
|
||||
b->shotsToFire = rrnd(4, 12);
|
||||
b->action = preFire;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->weaponType = WPN_MISSILE;
|
||||
self->shotsToFire = rrnd(1, 3);
|
||||
self->action = preFire;
|
||||
b->weaponType = WPN_MISSILE;
|
||||
b->shotsToFire = rrnd(1, 3);
|
||||
b->action = preFire;
|
||||
}
|
||||
}
|
||||
|
||||
static void preFire(void)
|
||||
{
|
||||
if (self->reload > 0)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
if (b->reload > 0)
|
||||
{
|
||||
moveTowardsPlayer();
|
||||
return;
|
||||
|
@ -181,17 +205,21 @@ static void preFire(void)
|
|||
|
||||
attack();
|
||||
|
||||
self->shotsToFire--;
|
||||
b->shotsToFire--;
|
||||
|
||||
if (self->shotsToFire == 0)
|
||||
if (b->shotsToFire == 0)
|
||||
{
|
||||
self->walk();
|
||||
b->walk();
|
||||
}
|
||||
}
|
||||
|
||||
static void attack(void)
|
||||
{
|
||||
switch (self->weaponType)
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
switch (b->weaponType)
|
||||
{
|
||||
case WPN_AIMED_PISTOL:
|
||||
attackPistol();
|
||||
|
@ -209,16 +237,19 @@ static void attackPistol(void)
|
|||
int bx, by;
|
||||
float dx, dy;
|
||||
Bullet *bullet;
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
bx = world.bob->x + rrnd(-8, 24);
|
||||
by = world.bob->y + rrnd(-8, 24);
|
||||
|
||||
getSlope(bx, by, self->x, self->y, &dx, &dy);
|
||||
getSlope(bx, by, b->x, b->y, &dx, &dy);
|
||||
|
||||
bullet = createBaseBullet(self);
|
||||
bullet->x = (self->x + self->w / 2);
|
||||
bullet->y = self->y + 30;
|
||||
bullet->facing = self->facing;
|
||||
bullet = createBaseBullet((Unit*)self);
|
||||
bullet->x = (b->x + b->w / 2);
|
||||
bullet->y = b->y + 30;
|
||||
bullet->facing = b->facing;
|
||||
bullet->damage = 1;
|
||||
bullet->owner = self;
|
||||
bullet->health = FPS * 3;
|
||||
|
@ -227,7 +258,7 @@ static void attackPistol(void)
|
|||
bullet->dy = dy * 12;
|
||||
bullet->sprite[0] = bullet->sprite[1] = aimedSprite;
|
||||
|
||||
self->reload = 4;
|
||||
b->reload = 4;
|
||||
|
||||
playSound(SND_MACHINE_GUN, CH_WEAPON);
|
||||
}
|
||||
|
@ -235,12 +266,15 @@ static void attackPistol(void)
|
|||
static void attackMissile(void)
|
||||
{
|
||||
Bullet *missile;
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
missile = createBaseBullet(self);
|
||||
missile->x = self->x + self->w / 2;
|
||||
missile->y = self->y + 30;
|
||||
missile->facing = self->facing;
|
||||
missile->dx = self->facing == FACING_RIGHT ? 15 : -15;
|
||||
missile = createBaseBullet((Unit*)self);
|
||||
missile->x = b->x + b->w / 2;
|
||||
missile->y = b->y + 30;
|
||||
missile->facing = b->facing;
|
||||
missile->dx = b->facing == FACING_RIGHT ? 15 : -15;
|
||||
missile->dy = world.bob->y - missile->y;
|
||||
missile->dy *= 0.01;
|
||||
missile->owner = self;
|
||||
|
@ -248,50 +282,57 @@ static void attackMissile(void)
|
|||
missile->sprite[0] = missileSprite[0];
|
||||
missile->sprite[1] = missileSprite[1];
|
||||
|
||||
self->reload = 15;
|
||||
b->reload = 15;
|
||||
|
||||
playSound(SND_MISSILE, CH_WEAPON);
|
||||
}
|
||||
|
||||
static void die1(void)
|
||||
{
|
||||
self->flags |= EF_BOUNCES;
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
b->flags |= EF_BOUNCES;
|
||||
|
||||
self->action = die2;
|
||||
self->thinkTime = 0;
|
||||
b->action = die2;
|
||||
b->thinkTime = 0;
|
||||
|
||||
self->spriteTime = 0;
|
||||
self->spriteFrame = 0;
|
||||
b->spriteTime = 0;
|
||||
b->spriteFrame = 0;
|
||||
}
|
||||
|
||||
static void die2(void)
|
||||
{
|
||||
int mx, my;
|
||||
Boss *b;
|
||||
|
||||
b = (Boss*)self;
|
||||
|
||||
self->health--;
|
||||
b->health--;
|
||||
|
||||
if (self->health % 3 == 0)
|
||||
if (b->health % 3 == 0)
|
||||
{
|
||||
mx = (int) ((self->x + (self->w / 2)) / MAP_TILE_SIZE);
|
||||
my = (int) ((self->y + self->h) / MAP_TILE_SIZE);
|
||||
mx = (int) ((b->x + (b->w / 2)) / MAP_TILE_SIZE);
|
||||
my = (int) ((b->y + b->h) / MAP_TILE_SIZE);
|
||||
|
||||
addScorchDecal(mx, my);
|
||||
|
||||
addExplosion(self->x + rand() % self->w, self->y + rand() % self->h, 50, self);
|
||||
addExplosion(b->x + rand() % b->w, b->y + rand() % b->h, 50, self);
|
||||
}
|
||||
|
||||
if (self->health <= -100)
|
||||
if (b->health <= -100)
|
||||
{
|
||||
addTeleportStars(self);
|
||||
addTeleportStars(tankTrack);
|
||||
|
||||
playSound(SND_APPEAR, CH_ANY);
|
||||
|
||||
self->alive = tankTrack->alive = ALIVE_DEAD;
|
||||
b->alive = tankTrack->alive = ALIVE_DEAD;
|
||||
|
||||
updateObjective(self->name);
|
||||
updateObjective(b->name);
|
||||
|
||||
addDefeatedTarget(self->name);
|
||||
addDefeatedTarget(b->name);
|
||||
|
||||
game.enemiesKilled++;
|
||||
}
|
||||
|
@ -308,7 +349,7 @@ static void applyDamage(int amount)
|
|||
}
|
||||
}
|
||||
|
||||
static SDL_Rect getBounds(void)
|
||||
static SDL_Rect *getBounds(void)
|
||||
{
|
||||
if (self->facing == FACING_LEFT)
|
||||
{
|
||||
|
@ -325,5 +366,5 @@ static SDL_Rect getBounds(void)
|
|||
self->bounds.h = self->h;
|
||||
}
|
||||
|
||||
return self->bounds;
|
||||
return &self->bounds;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ extern int enemyCanSeePlayer(Entity *e);
|
|||
extern void addDefeatedTarget(char *name);
|
||||
extern void updateObjective(char *targetName);
|
||||
extern void playSound(int snd, int ch);
|
||||
extern Bullet *createBaseBullet(Entity *owner);
|
||||
extern Bullet *createBaseBullet(Unit *owner);
|
||||
extern void getSlope(int x1, int y1, int x2, int y2, float *dx, float *dy);
|
||||
extern void addExplosion(float x, float y, int radius, Entity *owner);
|
||||
extern void addScorchDecal(int x, int y);
|
||||
|
|
|
@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
static Entity *tankCommander;
|
||||
static void tick(void);
|
||||
static void touch(Entity *other);
|
||||
static SDL_Rect getBounds(void);
|
||||
static SDL_Rect *getBounds(void);
|
||||
static void animate(void);
|
||||
static void (*superAnimate)(void);
|
||||
|
||||
|
@ -72,7 +72,7 @@ static void touch(Entity *other)
|
|||
{
|
||||
if (other != NULL)
|
||||
{
|
||||
if (other == world.bob && !world.bob->stunTimer && (world.bob->flags & EF_IMMUNE) == 0)
|
||||
if (other == (Entity*)world.bob && !world.bob->stunTimer && (world.bob->flags & EF_IMMUNE) == 0)
|
||||
{
|
||||
playSound(SND_FLESH_HIT, CH_ANY);
|
||||
world.bob->dx = rrnd(-5, 5);
|
||||
|
@ -88,14 +88,14 @@ static void touch(Entity *other)
|
|||
}
|
||||
}
|
||||
|
||||
static SDL_Rect getBounds(void)
|
||||
static SDL_Rect *getBounds(void)
|
||||
{
|
||||
self->bounds.x = self->x + 16;
|
||||
self->bounds.y = self->y;
|
||||
self->bounds.w = self->w - 32;
|
||||
self->bounds.h = self->h;
|
||||
|
||||
return self->bounds;
|
||||
return &self->bounds;
|
||||
}
|
||||
|
||||
static void animate(void)
|
||||
|
|
|
@ -24,36 +24,40 @@ static void applyDamage(int damage);
|
|||
static void walk(void);
|
||||
static void die(void);
|
||||
static void animate(void);
|
||||
static SDL_Rect getBounds(void);
|
||||
static SDL_Rect *getBounds(void);
|
||||
static int canFire(Entity *target);
|
||||
static void preFire(void);
|
||||
|
||||
void initCannon(Entity *e)
|
||||
{
|
||||
Unit *u;
|
||||
|
||||
initUnit(e);
|
||||
|
||||
u = (Unit*)self;
|
||||
|
||||
e->sprite[FACING_LEFT] = getSpriteIndex("CannonLeft");
|
||||
e->sprite[FACING_RIGHT] = getSpriteIndex("CannonRight");
|
||||
e->sprite[FACING_DIE] = getSpriteIndex("CannonLeft");
|
||||
u->sprite[FACING_LEFT] = getSpriteIndex("CannonLeft");
|
||||
u->sprite[FACING_RIGHT] = getSpriteIndex("CannonRight");
|
||||
u->sprite[FACING_DIE] = getSpriteIndex("CannonLeft");
|
||||
|
||||
e->weaponType = WPN_MISSILE;
|
||||
u->weaponType = WPN_MISSILE;
|
||||
|
||||
e->maxShotsToFire = 4;
|
||||
u->maxShotsToFire = 4;
|
||||
|
||||
e->reload = 0;
|
||||
u->reload = 0;
|
||||
|
||||
e->canCarryItem = 1;
|
||||
u->canCarryItem = 1;
|
||||
|
||||
e->health = e->healthMax = 50;
|
||||
u->health = u->healthMax = 50;
|
||||
|
||||
e->flags |= EF_EXPLODES;
|
||||
u->flags |= EF_EXPLODES;
|
||||
|
||||
e->animate = animate;
|
||||
e->applyDamage = applyDamage;
|
||||
e->walk = walk;
|
||||
e->die = die;
|
||||
e->getBounds= getBounds;
|
||||
e->canFire = canFire;
|
||||
u->animate = animate;
|
||||
u->applyDamage = applyDamage;
|
||||
u->walk = walk;
|
||||
u->die = die;
|
||||
u->getBounds= getBounds;
|
||||
u->canFire = canFire;
|
||||
}
|
||||
|
||||
static void applyDamage(int damage)
|
||||
|
@ -70,28 +74,31 @@ static void applyDamage(int damage)
|
|||
|
||||
static void die(void)
|
||||
{
|
||||
Unit *u;
|
||||
int mx, my;
|
||||
|
||||
u = (Unit*)self;
|
||||
|
||||
self->health--;
|
||||
u->health--;
|
||||
|
||||
if (self->health % 3 == 0)
|
||||
if (u->health % 3 == 0)
|
||||
{
|
||||
mx = (int) ((self->x + (self->w / 2)) / MAP_TILE_SIZE);
|
||||
my = (int) ((self->y + self->h) / MAP_TILE_SIZE);
|
||||
mx = (int) ((u->x + (u->w / 2)) / MAP_TILE_SIZE);
|
||||
my = (int) ((u->y + u->h) / MAP_TILE_SIZE);
|
||||
addScorchDecal(mx, my);
|
||||
|
||||
addExplosion(self->x, self->y, 50, self);
|
||||
addExplosion(u->x, u->y, 50, self);
|
||||
}
|
||||
|
||||
if (self->health <= -50)
|
||||
if (u->health <= -50)
|
||||
{
|
||||
updateObjective(self->name);
|
||||
updateObjective(u->name);
|
||||
updateObjective("ENEMY");
|
||||
fireTriggers(self->name);
|
||||
fireTriggers(u->name);
|
||||
|
||||
dropCarriedItem();
|
||||
|
||||
self->alive = ALIVE_DEAD;
|
||||
u->alive = ALIVE_DEAD;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,9 +111,12 @@ static void patrol(void)
|
|||
|
||||
static void lookForPlayer(void)
|
||||
{
|
||||
Unit *u;
|
||||
int r;
|
||||
|
||||
u = (Unit*)self;
|
||||
|
||||
self->thinkTime = rrnd(FPS / 2, FPS);
|
||||
u->thinkTime = rrnd(FPS / 2, FPS);
|
||||
|
||||
if (world.state != WS_IN_PROGRESS || dev.cheatBlind)
|
||||
{
|
||||
|
@ -114,13 +124,13 @@ static void lookForPlayer(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((self->facing == FACING_LEFT && world.bob->x > self->x) || (self->facing == FACING_RIGHT && world.bob->x < self->x))
|
||||
if ((u->facing == FACING_LEFT && world.bob->x > u->x) || (u->facing == FACING_RIGHT && world.bob->x < u->x))
|
||||
{
|
||||
patrol();
|
||||
return;
|
||||
}
|
||||
|
||||
if (getDistance(world.bob->x, world.bob->y, self->x, self->y) > 650)
|
||||
if (getDistance(world.bob->x, world.bob->y, u->x, u->y) > 650)
|
||||
{
|
||||
patrol();
|
||||
return;
|
||||
|
@ -134,34 +144,38 @@ static void lookForPlayer(void)
|
|||
|
||||
r = rand() % 100;
|
||||
|
||||
if (self->isMissionTarget)
|
||||
if (u->isMissionTarget)
|
||||
{
|
||||
r = rand() % 20;
|
||||
}
|
||||
|
||||
if (r < 15)
|
||||
{
|
||||
self->shotsToFire = rrnd(1, self->maxShotsToFire);
|
||||
self->action = preFire;
|
||||
u->shotsToFire = rrnd(1, u->maxShotsToFire);
|
||||
u->action = preFire;
|
||||
}
|
||||
}
|
||||
|
||||
static void preFire(void)
|
||||
{
|
||||
self->facing = (world.bob->x < self->x) ? FACING_LEFT : FACING_RIGHT;
|
||||
Unit *u;
|
||||
|
||||
u = (Unit*)self;
|
||||
|
||||
u->facing = (world.bob->x < u->x) ? FACING_LEFT : FACING_RIGHT;
|
||||
|
||||
if (self->reload > 0)
|
||||
if (u->reload > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->attack();
|
||||
u->attack();
|
||||
|
||||
self->shotsToFire--;
|
||||
u->shotsToFire--;
|
||||
|
||||
if (self->shotsToFire == 0)
|
||||
if (u->shotsToFire == 0)
|
||||
{
|
||||
self->walk();
|
||||
u->walk();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,14 +189,14 @@ static void animate(void)
|
|||
|
||||
}
|
||||
|
||||
static SDL_Rect getBounds(void)
|
||||
static SDL_Rect *getBounds(void)
|
||||
{
|
||||
self->bounds.x = self->x + 36;
|
||||
self->bounds.y = self->y;
|
||||
self->bounds.w = 36;
|
||||
self->bounds.h = self->h;
|
||||
|
||||
return self->bounds;
|
||||
return &self->bounds;
|
||||
}
|
||||
|
||||
static int canFire(Entity *target)
|
||||
|
|
|
@ -26,15 +26,19 @@ static void touch(Entity *other);
|
|||
|
||||
void initDebris(Entity *e)
|
||||
{
|
||||
Decoration *d;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
e->effectType = rand() % 2;
|
||||
d = (Decoration*)self;
|
||||
|
||||
d->effectType = rand() % 2;
|
||||
|
||||
e->flags |= EF_BOUNCES | EF_IGNORE_BULLETS | EF_KILL_OFFSCREEN | EF_NO_TELEPORT;
|
||||
d->flags |= EF_BOUNCES | EF_IGNORE_BULLETS | EF_KILL_OFFSCREEN | EF_NO_TELEPORT;
|
||||
|
||||
e->tick = tick;
|
||||
e->action = action;
|
||||
e->touch = touch;
|
||||
d->tick = tick;
|
||||
d->action = action;
|
||||
d->touch = touch;
|
||||
}
|
||||
|
||||
static void tick(void)
|
||||
|
@ -44,13 +48,17 @@ static void tick(void)
|
|||
|
||||
static void action(void)
|
||||
{
|
||||
if (self->effectType == 0)
|
||||
Decoration *d;
|
||||
|
||||
d = (Decoration*)self;
|
||||
|
||||
if (d->effectType == 0)
|
||||
{
|
||||
addFlameParticles(self->x + (rand() % self->w), self->y + (rand() % self->h));
|
||||
addFlameParticles(d->x + (rand() % d->w), d->y + (rand() % d->h));
|
||||
}
|
||||
else
|
||||
{
|
||||
addSmokeParticles(self->x + (rand() % self->w), self->y + (rand() % self->h));
|
||||
addSmokeParticles(d->x + (rand() % d->w), d->y + (rand() % d->h));
|
||||
}
|
||||
|
||||
self->thinkTime = 1;
|
||||
|
@ -58,8 +66,12 @@ static void action(void)
|
|||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
Decoration *d;
|
||||
|
||||
d = (Decoration*)self;
|
||||
|
||||
if (other == NULL)
|
||||
{
|
||||
self->dx *= 0.9;
|
||||
d->dx *= 0.9;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,31 +26,43 @@ static void touch(Entity *other);
|
|||
|
||||
void initFleshChunk(Entity *e)
|
||||
{
|
||||
Decoration *d;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
d = (Decoration*)e;
|
||||
|
||||
e->flags |= EF_BOUNCES | EF_IGNORE_BULLETS | EF_KILL_OFFSCREEN | EF_NO_TELEPORT;
|
||||
d->flags |= EF_BOUNCES | EF_IGNORE_BULLETS | EF_KILL_OFFSCREEN | EF_NO_TELEPORT;
|
||||
|
||||
e->bleedTime = FPS * 3;
|
||||
d->bleedTime = FPS * 3;
|
||||
|
||||
e->tick = tick;
|
||||
e->action = action;
|
||||
e->touch = touch;
|
||||
d->tick = tick;
|
||||
d->action = action;
|
||||
d->touch = touch;
|
||||
}
|
||||
|
||||
static void tick(void)
|
||||
{
|
||||
self->health--;
|
||||
self->bleedTime--;
|
||||
Decoration *d;
|
||||
|
||||
d = (Decoration*)self;
|
||||
|
||||
d->health--;
|
||||
d->bleedTime--;
|
||||
}
|
||||
|
||||
static void action(void)
|
||||
{
|
||||
if (self->bleedTime > 0)
|
||||
Decoration *d;
|
||||
|
||||
d = (Decoration*)self;
|
||||
|
||||
if (d->bleedTime > 0)
|
||||
{
|
||||
addBlood(self->x + (rand() % self->w), self->y + (rand() % self->h));
|
||||
addBlood(d->x + (rand() % d->w), d->y + (rand() % d->h));
|
||||
}
|
||||
|
||||
self->thinkTime = 1;
|
||||
d->thinkTime = 1;
|
||||
}
|
||||
|
||||
static void touch(Entity *other)
|
||||
|
|
|
@ -22,16 +22,71 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
void animateEntity(void);
|
||||
static void applyDamage(int damage);
|
||||
static float bounce(float x);
|
||||
static SDL_Rect *getBounds(void);
|
||||
|
||||
Entity *createEntity(void)
|
||||
Entity *createEntity(int type)
|
||||
{
|
||||
Entity *e;
|
||||
|
||||
e = malloc(sizeof(Entity));
|
||||
memset(e, 0, sizeof(Entity));
|
||||
switch (type)
|
||||
{
|
||||
case ET_BOB:
|
||||
e = malloc(sizeof(Bob));
|
||||
memset(e, 0, sizeof(Bob));
|
||||
break;
|
||||
|
||||
case ET_ENEMY:
|
||||
case ET_TEEKA:
|
||||
e = malloc(sizeof(Unit));
|
||||
memset(e, 0, sizeof(Unit));
|
||||
break;
|
||||
|
||||
case ET_BOSS:
|
||||
e = malloc(sizeof(Boss));
|
||||
memset(e, 0, sizeof(Boss));
|
||||
break;
|
||||
|
||||
case ET_HEART_CELL:
|
||||
case ET_KEY:
|
||||
case ET_ITEM:
|
||||
case ET_CONSUMABLE:
|
||||
e = malloc(sizeof(Item));
|
||||
memset(e, 0, sizeof(Item));
|
||||
break;
|
||||
|
||||
case ET_MIA:
|
||||
e = malloc(sizeof(MIA));
|
||||
memset(e, 0, sizeof(MIA));
|
||||
break;
|
||||
|
||||
case ET_DECORATION:
|
||||
e = malloc(sizeof(Decoration));
|
||||
memset(e, 0, sizeof(Decoration));
|
||||
break;
|
||||
|
||||
case ET_DOOR:
|
||||
case ET_LIFT:
|
||||
case ET_PUSHBLOCK:
|
||||
case ET_DESTRUCTABLE:
|
||||
case ET_POWER_POINT:
|
||||
case ET_CARD_READER:
|
||||
case ET_PRESSURE_PLATE:
|
||||
case ET_TELEPORTER:
|
||||
case ET_ITEM_PAD:
|
||||
case ET_POOL:
|
||||
case ET_TRAP:
|
||||
case ET_EXIT:
|
||||
case ET_INFO_POINT:
|
||||
e = malloc(sizeof(Structure));
|
||||
memset(e, 0, sizeof(Structure));
|
||||
break;
|
||||
}
|
||||
|
||||
world.entityTail->next = e;
|
||||
world.entityTail = e;
|
||||
|
||||
e->type = type;
|
||||
e->uniqueId = game.entityCounter++;
|
||||
|
||||
return e;
|
||||
|
@ -49,38 +104,31 @@ void initEntity(Entity *e)
|
|||
e->isStatic = 0;
|
||||
e->isMissionTarget = 0;
|
||||
|
||||
e->health = e->healthMax = 1;
|
||||
e->health = 1;
|
||||
|
||||
e->facing = FACING_LEFT;
|
||||
|
||||
e->spriteFrame = -1;
|
||||
e->spriteTime = 0;
|
||||
|
||||
e->dx = e->dy = 0;
|
||||
|
||||
e->flags = 0;
|
||||
|
||||
e->owner = NULL;
|
||||
|
||||
e->thinkTime = 0;
|
||||
|
||||
e->plane = PLANE_BACKGROUND;
|
||||
|
||||
e->animate = animateEntity;
|
||||
e->applyDamage = applyDamage;
|
||||
e->bounce = bounce;
|
||||
e->getBounds = getBounds;
|
||||
}
|
||||
|
||||
SDL_Rect *getEntityBounds(Entity *e)
|
||||
static SDL_Rect *getBounds(void)
|
||||
{
|
||||
e->bounds.x = e->x;
|
||||
e->bounds.y = e->y;
|
||||
e->bounds.w = e->w;
|
||||
e->bounds.h = e->h;
|
||||
self->bounds.x = self->x;
|
||||
self->bounds.y = self->y;
|
||||
self->bounds.w = self->w;
|
||||
self->bounds.h = self->h;
|
||||
|
||||
return &e->bounds;
|
||||
return &self->bounds;
|
||||
}
|
||||
|
||||
int getCurrentEntitySprite(Entity *e)
|
||||
int getCurrentEntitySprite(EntityExt *e)
|
||||
{
|
||||
if (e->alive == ALIVE_ALIVE)
|
||||
{
|
||||
|
@ -92,39 +140,19 @@ int getCurrentEntitySprite(Entity *e)
|
|||
|
||||
void animateEntity(void)
|
||||
{
|
||||
Sprite *spr;
|
||||
|
||||
if (self->spriteTime != -1)
|
||||
{
|
||||
self->spriteTime--;
|
||||
|
||||
if (self->spriteTime <= 0)
|
||||
{
|
||||
spr = getSpriteByIndex(getCurrentEntitySprite(self));
|
||||
self->spriteFrame = wrap(self->spriteFrame + 1, 0, 1);
|
||||
self->spriteTime = 0;
|
||||
self->w = spr->w;
|
||||
self->h = spr->h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setEntitySize(Entity *e)
|
||||
{
|
||||
Sprite *spr;
|
||||
|
||||
spr = getSpriteByIndex(getCurrentEntitySprite(e));
|
||||
e->w = spr->w;
|
||||
e->h = spr->h;
|
||||
}
|
||||
|
||||
float bounce(Entity *e, float x)
|
||||
static float bounce(float x)
|
||||
{
|
||||
if (!(e->flags & EF_BOUNCES))
|
||||
if (!(self->flags & EF_BOUNCES))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (e->flags & EF_FRICTIONLESS)
|
||||
else if (self->flags & EF_FRICTIONLESS)
|
||||
{
|
||||
return -x;
|
||||
}
|
||||
|
@ -133,7 +161,7 @@ float bounce(Entity *e, float x)
|
|||
|
||||
if (x > -1 && x < 1)
|
||||
{
|
||||
e->flags &= ~EF_BOUNCES;
|
||||
self->flags &= ~EF_BOUNCES;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
|
@ -160,27 +188,29 @@ void teleportEntity(Entity *e, float tx, float ty)
|
|||
|
||||
static void applyDamage(int damage)
|
||||
{
|
||||
if (self->health < 0)
|
||||
|
||||
}
|
||||
|
||||
void dropCarriedItem(void)
|
||||
{
|
||||
EntityExt *e;
|
||||
Item *i;
|
||||
|
||||
e = (EntityExt*)self;
|
||||
|
||||
if (e->carriedItem != NULL)
|
||||
{
|
||||
self->health = 0;
|
||||
self->alive = ALIVE_ALIVE;
|
||||
}
|
||||
i = e->carriedItem;
|
||||
|
||||
i->x = (e->x + e->w / 2) - i->w / 2;
|
||||
i->y = e->y;
|
||||
|
||||
self->health -= damage;
|
||||
i->dx = i->dy = 0;
|
||||
|
||||
if (self->health > 0)
|
||||
{
|
||||
self->thinkTime = 0;
|
||||
world.entityTail->next = (Entity*)i;
|
||||
world.entityTail = (Entity*)i;
|
||||
world.entityTail->next = NULL;
|
||||
|
||||
self->facing = self->x < world.bob->x ? FACING_RIGHT : FACING_LEFT;
|
||||
|
||||
if (self->isMissionTarget && rand() % 10 == 0)
|
||||
{
|
||||
self->action = unitReappear;
|
||||
self->flags |= EF_GONE;
|
||||
self->thinkTime = rand() % FPS;
|
||||
addTeleportStars(self);
|
||||
playSound(SND_APPEAR, CH_ANY);
|
||||
}
|
||||
e->carriedItem = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,19 +22,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
void initBattery(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initConsumable(e);
|
||||
|
||||
i = (Item*)e;
|
||||
|
||||
e->spriteFrame = 0;
|
||||
e->spriteTime = -1;
|
||||
i->spriteFrame = 0;
|
||||
i->spriteTime = -1;
|
||||
}
|
||||
|
||||
void touch(Entity *other)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
if (touchedPlayer(other))
|
||||
{
|
||||
world.bob->power = MIN(world.bob->power + self->power, world.bob->powerMax);
|
||||
world.bob->power = MIN(world.bob->power + i->power, world.bob->powerMax);
|
||||
|
||||
setGameplayMessage(MSG_STANDARD, "Picked up a %s", self->name);
|
||||
setGameplayMessage(MSG_STANDARD, "Picked up a %s", i->name);
|
||||
|
||||
pickupItem();
|
||||
|
||||
|
|
|
@ -24,18 +24,22 @@ static void touch(Entity *other);
|
|||
|
||||
void initCell(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initItem(e);
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
e->isMissionTarget = 1;
|
||||
i->isMissionTarget = 1;
|
||||
|
||||
STRNCPY(e->spriteName, "Battery", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->spriteName, "Battery", MAX_NAME_LENGTH);
|
||||
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = getSpriteIndex("Battery");
|
||||
i->sprite[0] = i->sprite[1] = i->sprite[2] = getSpriteIndex("Battery");
|
||||
|
||||
e->spriteFrame = 0;
|
||||
e->spriteTime = -1;
|
||||
i->spriteFrame = 0;
|
||||
i->spriteTime = -1;
|
||||
|
||||
e->touch = touch;
|
||||
i->touch = touch;
|
||||
}
|
||||
|
||||
static void touch(Entity *other)
|
||||
|
|
|
@ -31,11 +31,15 @@ void initCherry(Entity *e)
|
|||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
if (touchedPlayer(other))
|
||||
{
|
||||
world.bob->health = limit(world.bob->health + self->value, 0, world.bob->healthMax);
|
||||
world.bob->health = limit(world.bob->health + i->value, 0, world.bob->healthMax);
|
||||
|
||||
setGameplayMessage(MSG_STANDARD, "Picked up a %s", self->name);
|
||||
setGameplayMessage(MSG_STANDARD, "Picked up a %s", i->name);
|
||||
|
||||
pickupItem();
|
||||
|
||||
|
|
|
@ -35,20 +35,24 @@ void initConsumable(Entity *e)
|
|||
|
||||
static void tick(void)
|
||||
{
|
||||
if (self->isOnGround)
|
||||
Item *i;
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
if (i->isOnGround)
|
||||
{
|
||||
self->dx *= 0.05;
|
||||
i->dx *= 0.05;
|
||||
}
|
||||
|
||||
self->health--;
|
||||
i->health--;
|
||||
|
||||
if ((int) self->health == FPS * 2)
|
||||
if ((int) i->health == FPS * 2)
|
||||
{
|
||||
self->flags |= EF_FLICKER;
|
||||
i->flags |= EF_FLICKER;
|
||||
}
|
||||
else if (self->health <= 0)
|
||||
else if (i->health <= 0)
|
||||
{
|
||||
self->alive = ALIVE_DEAD;
|
||||
i->alive = ALIVE_DEAD;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,12 +63,16 @@ int touchedPlayer(Entity *other)
|
|||
|
||||
void pickupItem(void)
|
||||
{
|
||||
self->alive = (self->environment == ENV_AIR) ? ALIVE_DYING : ALIVE_DEAD;
|
||||
self->health = FPS / 2;
|
||||
self->thinkTime = 0;
|
||||
self->dy = -2;
|
||||
self->dx = 0;
|
||||
self->flags |= EF_FLICKER | EF_WEIGHTLESS;
|
||||
Item *i;
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
i->alive = (i->environment == ENV_AIR) ? ALIVE_DYING : ALIVE_DEAD;
|
||||
i->health = FPS / 2;
|
||||
i->thinkTime = 0;
|
||||
i->dy = -2;
|
||||
i->dx = 0;
|
||||
i->flags |= EF_FLICKER | EF_WEIGHTLESS;
|
||||
}
|
||||
|
||||
static void die(void)
|
||||
|
|
|
@ -25,19 +25,23 @@ static void touch(Entity *other);
|
|||
|
||||
void initHeart(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initItem(e);
|
||||
|
||||
i = (Item*)e;
|
||||
|
||||
e->isMissionTarget = 1;
|
||||
i->isMissionTarget = 1;
|
||||
|
||||
STRNCPY(e->spriteName, "Heart", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->spriteName, "Heart", MAX_NAME_LENGTH);
|
||||
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = getSpriteIndex("Heart");
|
||||
i->sprite[0] = i->sprite[1] = i->sprite[2] = getSpriteIndex("Heart");
|
||||
|
||||
e->spriteFrame = 0;
|
||||
e->spriteTime = -1;
|
||||
i->spriteFrame = 0;
|
||||
i->spriteTime = -1;
|
||||
|
||||
e->action = action;
|
||||
e->touch = touch;
|
||||
i->action = action;
|
||||
i->touch = touch;
|
||||
}
|
||||
|
||||
static void action(void)
|
||||
|
|
|
@ -25,36 +25,44 @@ static void tick(void);
|
|||
static void touch(Entity *other);
|
||||
static void changeEnvironment(void);
|
||||
static void die(void);
|
||||
static void destructablePickupItem(Entity *e);
|
||||
static void enemyPickupItem(Entity *e);
|
||||
static void destructablePickupItem(Structure *s);
|
||||
static void enemyPickupItem(Unit *u);
|
||||
static void bobPickupItem(void);
|
||||
|
||||
void initItem(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
i = (Item*)e;
|
||||
|
||||
STRNCPY(e->spriteName, "Weapon", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->spriteName, "Weapon", MAX_NAME_LENGTH);
|
||||
|
||||
e->flags |= EF_IGNORE_BULLETS;
|
||||
i->flags |= EF_IGNORE_BULLETS;
|
||||
|
||||
e->isMissionTarget = 1;
|
||||
e->canBePickedUp = 1;
|
||||
e->canBeCarried = 0;
|
||||
e->collected = 0;
|
||||
i->isMissionTarget = 1;
|
||||
i->canBePickedUp = 1;
|
||||
i->canBeCarried = 0;
|
||||
i->collected = 0;
|
||||
|
||||
e->sprite[FACING_LEFT] = e->sprite[FACING_RIGHT] = e->sprite[FACING_DIE] = getSpriteIndex(e->spriteName);
|
||||
i->sprite[FACING_LEFT] = i->sprite[FACING_RIGHT] = i->sprite[FACING_DIE] = getSpriteIndex(i->spriteName);
|
||||
|
||||
e->tick = tick;
|
||||
e->touch = touch;
|
||||
e->changeEnvironment = changeEnvironment;
|
||||
e->reset = reset;
|
||||
e->die = die;
|
||||
i->tick = tick;
|
||||
i->touch = touch;
|
||||
i->changeEnvironment = changeEnvironment;
|
||||
i->reset = reset;
|
||||
i->die = die;
|
||||
}
|
||||
|
||||
static void reset(void)
|
||||
{
|
||||
self->startX = (int) self->x;
|
||||
self->startY = (int) self->y;
|
||||
Item *i;
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
i->startX = (int) self->x;
|
||||
i->startY = (int) self->y;
|
||||
}
|
||||
|
||||
static void tick(void)
|
||||
|
@ -70,7 +78,11 @@ static void tick(void)
|
|||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
if (self->alive == ALIVE_ALIVE && other != NULL && self->canBePickedUp)
|
||||
Item *i;
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
if (i->alive == ALIVE_ALIVE && other != NULL && i->canBePickedUp)
|
||||
{
|
||||
if (other->type == ET_BOB && !world.bob->stunTimer)
|
||||
{
|
||||
|
@ -78,27 +90,31 @@ static void touch(Entity *other)
|
|||
}
|
||||
else if (other->type == ET_ENEMY)
|
||||
{
|
||||
enemyPickupItem(other);
|
||||
enemyPickupItem((Unit*)other);
|
||||
}
|
||||
else if (other->type == ET_DESTRUCTABLE)
|
||||
{
|
||||
destructablePickupItem(other);
|
||||
destructablePickupItem((Structure*)other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bobPickupItem(void)
|
||||
{
|
||||
if (!self->isMissionTarget)
|
||||
Item *i;
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
if (!i->isMissionTarget)
|
||||
{
|
||||
if (self->thinkTime == 0)
|
||||
if (i->thinkTime == 0)
|
||||
{
|
||||
self->alive = ALIVE_DEAD;
|
||||
addKey(self->name);
|
||||
i->alive = ALIVE_DEAD;
|
||||
addKey(i->name);
|
||||
game.keysFound++;
|
||||
updateObjective("KEY");
|
||||
|
||||
setGameplayMessage(MSG_STANDARD, "Picked up a %s", self->name);
|
||||
setGameplayMessage(MSG_STANDARD, "Picked up a %s", i->name);
|
||||
|
||||
playSound(SND_KEY, CH_ITEM);
|
||||
}
|
||||
|
@ -107,21 +123,21 @@ static void bobPickupItem(void)
|
|||
setGameplayMessage(MSG_GAMEPLAY, "Can't carry any more keys");
|
||||
}
|
||||
}
|
||||
else if (self->canBeCarried)
|
||||
else if (i->canBeCarried)
|
||||
{
|
||||
if (numCarriedItems() < MAX_ITEMS)
|
||||
{
|
||||
self->flags |= EF_GONE;
|
||||
i->flags |= EF_GONE;
|
||||
|
||||
if (!self->collected)
|
||||
if (!i->collected)
|
||||
{
|
||||
updateObjective(self->name);
|
||||
self->collected = 1;
|
||||
updateObjective(i->name);
|
||||
i->collected = 1;
|
||||
}
|
||||
|
||||
addBobItem(self);
|
||||
addBobItem(i);
|
||||
|
||||
setGameplayMessage(MSG_STANDARD, "Picked up a %s", self->name);
|
||||
setGameplayMessage(MSG_STANDARD, "Picked up a %s", i->name);
|
||||
|
||||
playSound(SND_ITEM, CH_ITEM);
|
||||
}
|
||||
|
@ -132,45 +148,57 @@ static void bobPickupItem(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
self->alive = ALIVE_DEAD;
|
||||
updateObjective(self->name);
|
||||
i->alive = ALIVE_DEAD;
|
||||
updateObjective(i->name);
|
||||
|
||||
if (strcmp(world.id, "teeka") != 0)
|
||||
{
|
||||
setGameplayMessage(MSG_STANDARD, "Picked up a %s", self->name);
|
||||
setGameplayMessage(MSG_STANDARD, "Picked up a %s", i->name);
|
||||
}
|
||||
|
||||
playSound(SND_ITEM, CH_ITEM);
|
||||
}
|
||||
}
|
||||
|
||||
static void enemyPickupItem(Entity *e)
|
||||
static void enemyPickupItem(Unit *u)
|
||||
{
|
||||
if (e->canCarryItem && e->carriedItem == NULL && e->alive == ALIVE_ALIVE)
|
||||
Item *i;
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
if (u->canCarryItem && u->carriedItem == NULL && u->alive == ALIVE_ALIVE)
|
||||
{
|
||||
e->carriedItem = self;
|
||||
u->carriedItem = i;
|
||||
|
||||
self->flags |= EF_GONE;
|
||||
i->flags |= EF_GONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void destructablePickupItem(Entity *e)
|
||||
static void destructablePickupItem(Structure *s)
|
||||
{
|
||||
if (e->carriedItem == NULL && e->alive == ALIVE_ALIVE)
|
||||
Item *i;
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
if (s->carriedItem == NULL && s->alive == ALIVE_ALIVE)
|
||||
{
|
||||
e->carriedItem = self;
|
||||
s->carriedItem = i;
|
||||
|
||||
self->flags |= EF_GONE;
|
||||
i->flags |= EF_GONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void changeEnvironment(void)
|
||||
{
|
||||
if (self->environment == ENV_SLIME || self->environment == ENV_LAVA)
|
||||
Item *i;
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
if (i->environment == ENV_SLIME || i->environment == ENV_LAVA)
|
||||
{
|
||||
addTeleportStars(self);
|
||||
self->x = self->startX;
|
||||
self->y = self->startY;
|
||||
i->x = i->startX;
|
||||
i->y = i->startY;
|
||||
addTeleportStars(self);
|
||||
playSound(SND_APPEAR, CH_ANY);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ extern void setGameplayMessage(int type, char *format, ...);
|
|||
extern void addTeleportStars(Entity *e);
|
||||
extern void initEntity(Entity *e);
|
||||
extern int getSpriteIndex(char *name);
|
||||
extern void addBobItem(Entity *e);
|
||||
extern void addBobItem(Item *i);
|
||||
extern int numCarriedItems(void);
|
||||
extern void addKey(char *name);
|
||||
extern void updateObjective(char *targetName);
|
||||
|
|
|
@ -22,24 +22,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
void initBronzeKey(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initItem(e);
|
||||
|
||||
i = (Item*)e;
|
||||
|
||||
STRNCPY(e->name, "Bronze Key", MAX_NAME_LENGTH);
|
||||
STRNCPY(e->spriteName, "BronzeKey", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->name, "Bronze Key", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->spriteName, "BronzeKey", MAX_NAME_LENGTH);
|
||||
}
|
||||
|
||||
void initSilverKey(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initItem(e);
|
||||
|
||||
i = (Item*)e;
|
||||
|
||||
STRNCPY(e->name, "Silver Key", MAX_NAME_LENGTH);
|
||||
STRNCPY(e->spriteName, "SilverKey", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->name, "Silver Key", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->spriteName, "SilverKey", MAX_NAME_LENGTH);
|
||||
}
|
||||
|
||||
void initGoldKey(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initItem(e);
|
||||
|
||||
i = (Item*)e;
|
||||
|
||||
STRNCPY(e->name, "Gold Key", MAX_NAME_LENGTH);
|
||||
STRNCPY(e->spriteName, "GoldKey", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->name, "Gold Key", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->spriteName, "GoldKey", MAX_NAME_LENGTH);
|
||||
}
|
||||
|
|
|
@ -25,53 +25,73 @@ static void touchWhiteKeycard(Entity *other);
|
|||
|
||||
void initRedKeycard(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initItem(e);
|
||||
|
||||
i = (Item*)e;
|
||||
|
||||
STRNCPY(e->name, "Red Keycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(e->spriteName, "RedKeycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->name, "Red Keycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->spriteName, "RedKeycard", MAX_NAME_LENGTH);
|
||||
}
|
||||
|
||||
void initBlueKeycard(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initItem(e);
|
||||
|
||||
i = (Item*)e;
|
||||
|
||||
STRNCPY(e->name, "Blue Keycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(e->spriteName, "BlueKeycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->name, "Blue Keycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->spriteName, "BlueKeycard", MAX_NAME_LENGTH);
|
||||
}
|
||||
|
||||
void initGreenKeycard(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initItem(e);
|
||||
|
||||
i = (Item*)e;
|
||||
|
||||
STRNCPY(e->name, "Green Keycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(e->spriteName, "GreenKeycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->name, "Green Keycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->spriteName, "GreenKeycard", MAX_NAME_LENGTH);
|
||||
}
|
||||
|
||||
void initYellowKeycard(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initItem(e);
|
||||
|
||||
i = (Item*)e;
|
||||
|
||||
STRNCPY(e->name, "Yellow Keycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(e->spriteName, "YellowKeycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->name, "Yellow Keycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->spriteName, "YellowKeycard", MAX_NAME_LENGTH);
|
||||
}
|
||||
|
||||
void initWhiteKeycard(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initItem(e);
|
||||
|
||||
i = (Item*)e;
|
||||
|
||||
STRNCPY(e->name, "White Keycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(e->spriteName, "WhiteKeycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->name, "White Keycard", MAX_NAME_LENGTH);
|
||||
STRNCPY(i->spriteName, "WhiteKeycard", MAX_NAME_LENGTH);
|
||||
|
||||
itemTouch = e->touch;
|
||||
itemTouch = i->touch;
|
||||
|
||||
e->touch = touchWhiteKeycard;
|
||||
i->touch = touchWhiteKeycard;
|
||||
}
|
||||
|
||||
static void touchWhiteKeycard(Entity *other)
|
||||
{
|
||||
itemTouch(other);
|
||||
|
||||
if (other == world.bob)
|
||||
if (other == (Entity*)world.bob)
|
||||
{
|
||||
updateObjective("White Keycard");
|
||||
|
||||
|
|
|
@ -34,51 +34,63 @@ static char *description[] = {
|
|||
|
||||
void initWeaponPickup(Entity *e)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
initConsumable(e);
|
||||
|
||||
i = (Item*)e;
|
||||
|
||||
e->weaponType = WPN_PISTOL;
|
||||
i->weaponType = WPN_PISTOL;
|
||||
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = getSpriteIndex("Weapon");
|
||||
e->spriteFrame = e->weaponType;
|
||||
e->spriteTime = -1;
|
||||
i->sprite[0] = i->sprite[1] = i->sprite[2] = getSpriteIndex("Weapon");
|
||||
i->spriteFrame = i->weaponType;
|
||||
i->spriteTime = -1;
|
||||
|
||||
setEntitySize(e);
|
||||
|
||||
if (e->provided)
|
||||
if (i->provided)
|
||||
{
|
||||
e->health = 9999;
|
||||
i->health = 9999;
|
||||
}
|
||||
|
||||
itemTick = e->tick;
|
||||
itemTick = i->tick;
|
||||
|
||||
e->tick = tick;
|
||||
e->touch = touch;
|
||||
i->tick = tick;
|
||||
i->touch = touch;
|
||||
}
|
||||
|
||||
static void tick(void)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
itemTick();
|
||||
|
||||
if (self->provided && self->alive == ALIVE_ALIVE)
|
||||
if (i->provided && i->alive == ALIVE_ALIVE)
|
||||
{
|
||||
self->health = 9999;
|
||||
i->health = 9999;
|
||||
}
|
||||
}
|
||||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
Item *i;
|
||||
|
||||
i = (Item*)self;
|
||||
|
||||
if (touchedPlayer(other))
|
||||
{
|
||||
world.bob->weaponType = self->weaponType;
|
||||
world.bob->weaponType = i->weaponType;
|
||||
|
||||
switch (self->weaponType)
|
||||
switch (i->weaponType)
|
||||
{
|
||||
case WPN_GRENADES:
|
||||
setGameplayMessage(MSG_STANDARD, "Got some Grenades");
|
||||
break;
|
||||
|
||||
default:
|
||||
setGameplayMessage(MSG_STANDARD, "Picked up a %s", description[self->weaponType]);
|
||||
setGameplayMessage(MSG_STANDARD, "Picked up a %s", description[i->weaponType]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,20 +25,24 @@ static void action(void);
|
|||
|
||||
void initDestructable(Entity *e)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
e->isMissionTarget = 1;
|
||||
|
||||
STRNCPY(e->spriteName, "Crate4", MAX_NAME_LENGTH);
|
||||
|
||||
e->flags |= EF_EXPLODES;
|
||||
|
||||
e->health = e->healthMax = 10;
|
||||
s = (Structure*)e;
|
||||
|
||||
e->sprite[FACING_LEFT] = e->sprite[FACING_RIGHT] = e->sprite[FACING_DIE] = getSpriteIndex(e->spriteName);
|
||||
s->isMissionTarget = 1;
|
||||
|
||||
STRNCPY(s->spriteName, "Crate4", MAX_NAME_LENGTH);
|
||||
|
||||
s->flags |= EF_EXPLODES;
|
||||
|
||||
s->health = s->healthMax = 10;
|
||||
|
||||
e->applyDamage = applyDamage;
|
||||
e->action = action;
|
||||
s->sprite[FACING_LEFT] = s->sprite[FACING_RIGHT] = s->sprite[FACING_DIE] = getSpriteIndex(s->spriteName);
|
||||
|
||||
s->applyDamage = applyDamage;
|
||||
s->action = action;
|
||||
}
|
||||
|
||||
static void applyDamage(int amount)
|
||||
|
@ -51,35 +55,38 @@ static void applyDamage(int amount)
|
|||
|
||||
static void action(void)
|
||||
{
|
||||
Structure *s;
|
||||
int mx, my;
|
||||
|
||||
if (self->health <= 0)
|
||||
s = (Structure*)self;
|
||||
|
||||
if (s->health <= 0)
|
||||
{
|
||||
self->health--;
|
||||
s->health--;
|
||||
|
||||
if (self->health % 3 == 0)
|
||||
if (s->health % 3 == 0)
|
||||
{
|
||||
mx = (int) ((self->x + (self->w / 2)) / MAP_TILE_SIZE);
|
||||
my = (int) ((self->y + self->h) / MAP_TILE_SIZE);
|
||||
mx = (int) ((s->x + (s->w / 2)) / MAP_TILE_SIZE);
|
||||
my = (int) ((s->y + s->h) / MAP_TILE_SIZE);
|
||||
addScorchDecal(mx, my);
|
||||
|
||||
addExplosion(self->x, self->y, 50, self);
|
||||
self->dx = rrnd(-10, 10);
|
||||
self->dy = rrnd(-10, 10);
|
||||
addExplosion(s->x, s->y, 50, self);
|
||||
s->dx = rrnd(-10, 10);
|
||||
s->dy = rrnd(-10, 10);
|
||||
}
|
||||
|
||||
if (self->health <= -50)
|
||||
if (s->health <= -50)
|
||||
{
|
||||
dropCarriedItem();
|
||||
|
||||
updateObjective(self->name);
|
||||
updateObjective(s->name);
|
||||
|
||||
if (strlen(self->targetNames) > 0)
|
||||
if (strlen(s->targetNames) > 0)
|
||||
{
|
||||
activateEntities(self->targetNames, 1);
|
||||
activateEntities(s->targetNames, 1);
|
||||
}
|
||||
|
||||
self->alive = ALIVE_DEAD;
|
||||
s->alive = ALIVE_DEAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,57 +25,68 @@ static void touch(Entity *other);
|
|||
|
||||
void initInfoPoint(Entity *e)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = getSpriteIndex("InfoPoint");
|
||||
|
||||
e->flags |= EF_WEIGHTLESS | EF_IGNORE_BULLETS | EF_NO_CLIP | EF_NO_ENVIRONMENT;
|
||||
s = (Structure*)e;
|
||||
|
||||
e->ty = e->y;
|
||||
s->sprite[0] = s->sprite[1] = s->sprite[2] = getSpriteIndex("InfoPoint");
|
||||
|
||||
e->firstTouch = 1;
|
||||
s->flags |= EF_WEIGHTLESS | EF_IGNORE_BULLETS | EF_NO_CLIP | EF_NO_ENVIRONMENT;
|
||||
|
||||
e->tick = tick;
|
||||
e->touch = touch;
|
||||
s->ty = s->y;
|
||||
|
||||
s->firstTouch = 1;
|
||||
|
||||
s->tick = tick;
|
||||
s->touch = touch;
|
||||
}
|
||||
|
||||
static void tick(void)
|
||||
{
|
||||
self->sinVal -= 0.05;
|
||||
self->y += (float) sin(self->sinVal) * 0.1;
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
s->sinVal -= 0.05;
|
||||
s->y += (float) sin(s->sinVal) * 0.1;
|
||||
}
|
||||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
Structure *s;
|
||||
int showMessage;
|
||||
|
||||
if (other == world.bob)
|
||||
s = (Structure*)self;
|
||||
|
||||
if (other == (Entity*)world.bob)
|
||||
{
|
||||
showMessage = 0;
|
||||
|
||||
if (self->firstTouch)
|
||||
if (s->firstTouch)
|
||||
{
|
||||
self->firstTouch = 0;
|
||||
s->firstTouch = 0;
|
||||
showMessage = 1;
|
||||
self->messageTimer = FPS;
|
||||
s->messageTimer = FPS;
|
||||
}
|
||||
else if (world.bob->dx == 0 && world.bob->dy == 0 && world.bob->isOnGround)
|
||||
{
|
||||
self->messageTimer++;
|
||||
s->messageTimer++;
|
||||
|
||||
if (self->messageTimer == FPS)
|
||||
if (s->messageTimer == FPS)
|
||||
{
|
||||
showMessage = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self->messageTimer = 0;
|
||||
s->messageTimer = 0;
|
||||
}
|
||||
|
||||
if (showMessage)
|
||||
{
|
||||
showInfoMessage(self->message);
|
||||
showInfoMessage(s->message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,60 +25,72 @@ static void touch(Entity *other);
|
|||
|
||||
void initCardReader(Entity *e)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
e->flags |= EF_WEIGHTLESS | EF_NO_CLIP | EF_NO_ENVIRONMENT | EF_IGNORE_BULLETS | EF_NO_TELEPORT;
|
||||
|
||||
STRNCPY(e->requiredCard, "Black Keycard", MAX_NAME_LENGTH);
|
||||
|
||||
e->isStatic = 1;
|
||||
s = (Structure*)e;
|
||||
|
||||
if (!e->active)
|
||||
s->flags |= EF_WEIGHTLESS | EF_NO_CLIP | EF_NO_ENVIRONMENT | EF_IGNORE_BULLETS | EF_NO_TELEPORT;
|
||||
|
||||
STRNCPY(s->requiredItem, "Black Keycard", MAX_NAME_LENGTH);
|
||||
|
||||
s->isStatic = 1;
|
||||
|
||||
if (!s->active)
|
||||
{
|
||||
e->sprite[FACING_LEFT] = e->sprite[FACING_RIGHT] = e->sprite[FACING_DIE] = getSpriteIndex("CardReaderIdle");
|
||||
s->sprite[FACING_LEFT] = s->sprite[FACING_RIGHT] = s->sprite[FACING_DIE] = getSpriteIndex("CardReaderIdle");
|
||||
}
|
||||
else
|
||||
{
|
||||
e->sprite[FACING_LEFT] = e->sprite[FACING_RIGHT] = e->sprite[FACING_DIE] = getSpriteIndex("CardReader");
|
||||
s->sprite[FACING_LEFT] = s->sprite[FACING_RIGHT] = s->sprite[FACING_DIE] = getSpriteIndex("CardReader");
|
||||
}
|
||||
|
||||
e->tick = tick;
|
||||
e->touch = touch;
|
||||
s->tick = tick;
|
||||
s->touch = touch;
|
||||
}
|
||||
|
||||
static void tick(void)
|
||||
{
|
||||
if (!self->active)
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if (!s->active)
|
||||
{
|
||||
self->bobTouching = MAX(self->bobTouching - 1, 0);
|
||||
s->bobTouching = MAX(s->bobTouching - 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
if (!self->active && other->type == ET_BOB)
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if (!s->active && other->type == ET_BOB)
|
||||
{
|
||||
if (hasItem(self->requiredCard) || dev.cheatKeys)
|
||||
if (hasItem(s->requiredItem) || dev.cheatKeys)
|
||||
{
|
||||
activateEntities(self->targetNames, 1);
|
||||
activateEntities(s->targetNames, 1);
|
||||
|
||||
setGameplayMessage(MSG_GAMEPLAY, "%s removed", self->requiredCard);
|
||||
setGameplayMessage(MSG_GAMEPLAY, "%s removed", s->requiredItem);
|
||||
|
||||
removeItem(self->requiredCard);
|
||||
removeItem(s->requiredItem);
|
||||
|
||||
self->active = 1;
|
||||
self->sprite[FACING_LEFT] = self->sprite[FACING_RIGHT] = self->sprite[FACING_DIE] = getSpriteIndex("CardReader");
|
||||
self->spriteTime = 0;
|
||||
self->spriteFrame = 0;
|
||||
s->active = 1;
|
||||
s->sprite[FACING_LEFT] = s->sprite[FACING_RIGHT] = s->sprite[FACING_DIE] = getSpriteIndex("CardReader");
|
||||
s->spriteTime = 0;
|
||||
s->spriteFrame = 0;
|
||||
|
||||
playSound(SND_CONFIRMED, CH_TOUCH);
|
||||
}
|
||||
else if (self->bobTouching == 0)
|
||||
else if (s->bobTouching == 0)
|
||||
{
|
||||
setGameplayMessage(MSG_GAMEPLAY, "%s required", self->requiredCard);
|
||||
setGameplayMessage(MSG_GAMEPLAY, "%s required", s->requiredItem);
|
||||
playSound(SND_DENIED, CH_TOUCH);
|
||||
}
|
||||
|
||||
self->bobTouching = 2;
|
||||
s->bobTouching = 2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,103 +29,123 @@ static int isClosing(void);
|
|||
|
||||
void initDoor(Entity *e)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
e->isSolid = 1;
|
||||
|
||||
e->flags |= EF_WEIGHTLESS | EF_NO_ENVIRONMENT | EF_NO_CLIP | EF_EXPLODES | EF_NO_TELEPORT;
|
||||
|
||||
e->closedX = e->closedY = -1;
|
||||
|
||||
e->state = DOOR_CLOSED;
|
||||
|
||||
e->speed = 8;
|
||||
|
||||
e->isLocked = 1;
|
||||
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = getSpriteIndex("Door");
|
||||
s = (Structure*)e;
|
||||
|
||||
if (e->closedX == -1 && e->closedY == -1)
|
||||
s->isSolid = 1;
|
||||
|
||||
s->flags |= EF_WEIGHTLESS | EF_NO_ENVIRONMENT | EF_NO_CLIP | EF_EXPLODES | EF_NO_TELEPORT;
|
||||
|
||||
s->closedX = s->closedY = -1;
|
||||
|
||||
s->state = DOOR_CLOSED;
|
||||
|
||||
s->speed = 8;
|
||||
|
||||
s->isLocked = 1;
|
||||
|
||||
s->sprite[0] = s->sprite[1] = s->sprite[2] = getSpriteIndex("Door");
|
||||
|
||||
if (s->closedX == -1 && s->closedY == -1)
|
||||
{
|
||||
e->closedX = (int) e->x;
|
||||
e->closedY = (int) e->y;
|
||||
s->closedX = (int) s->x;
|
||||
s->closedY = (int) s->y;
|
||||
}
|
||||
|
||||
e->tick = tick;
|
||||
e->touch = touch;
|
||||
s->tick = tick;
|
||||
s->touch = touch;
|
||||
}
|
||||
|
||||
void initBronzeDoor(Entity *e)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
initDoor(e);
|
||||
|
||||
STRNCPY(e->requiredKey, "Bronze Key", MAX_NAME_LENGTH);
|
||||
s = (Structure*)e;
|
||||
|
||||
STRNCPY(s->requiredItem, "Bronze Key", MAX_NAME_LENGTH);
|
||||
|
||||
e->speed = 2;
|
||||
s->speed = 2;
|
||||
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = getSpriteIndex("BronzeDoor");
|
||||
s->sprite[0] = s->sprite[1] = s->sprite[2] = getSpriteIndex("BronzeDoor");
|
||||
}
|
||||
|
||||
void initSilverDoor(Entity *e)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
initDoor(e);
|
||||
|
||||
STRNCPY(e->requiredKey, "Silver Key", MAX_NAME_LENGTH);
|
||||
s = (Structure*)e;
|
||||
|
||||
STRNCPY(s->requiredItem, "Silver Key", MAX_NAME_LENGTH);
|
||||
|
||||
e->speed = 2;
|
||||
s->speed = 2;
|
||||
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = getSpriteIndex("SilverDoor");
|
||||
s->sprite[0] = s->sprite[1] = s->sprite[2] = getSpriteIndex("SilverDoor");
|
||||
}
|
||||
|
||||
void initGoldDoor(Entity *e)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
initDoor(e);
|
||||
|
||||
STRNCPY(e->requiredKey, "Gold Key", MAX_NAME_LENGTH);
|
||||
s = (Structure*)e;
|
||||
|
||||
STRNCPY(s->requiredItem, "Gold Key", MAX_NAME_LENGTH);
|
||||
|
||||
e->speed = 2;
|
||||
s->speed = 2;
|
||||
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = getSpriteIndex("GoldDoor");
|
||||
s->sprite[0] = s->sprite[1] = e->sprite[2] = getSpriteIndex("GoldDoor");
|
||||
}
|
||||
|
||||
static void tick(void)
|
||||
{
|
||||
self->dx = self->dy = 0;
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
s->dx = s->dy = 0;
|
||||
|
||||
if (isOpening())
|
||||
{
|
||||
getSlope(self->tx, self->ty, self->x, self->y, &self->dx, &self->dy);
|
||||
getSlope(s->tx, s->ty, s->x, s->y, &s->dx, &s->dy);
|
||||
|
||||
self->dx *= self->speed;
|
||||
self->dy *= self->speed;
|
||||
s->dx *= s->speed;
|
||||
s->dy *= s->speed;
|
||||
|
||||
if (abs(self->x - self->tx) < self->speed && abs(self->y - self->ty) < self->speed)
|
||||
if (abs(s->x - s->tx) < s->speed && abs(s->y - s->ty) < s->speed)
|
||||
{
|
||||
self->x = self->tx;
|
||||
self->y = self->ty;
|
||||
s->x = s->tx;
|
||||
s->y = s->ty;
|
||||
}
|
||||
|
||||
self->isStatic = 0;
|
||||
s->isStatic = 0;
|
||||
}
|
||||
else if (isClosing())
|
||||
{
|
||||
getSlope(self->closedX, self->closedY, self->x, self->y, &self->dx, &self->dy);
|
||||
getSlope(s->closedX, s->closedY, s->x, s->y, &s->dx, &s->dy);
|
||||
|
||||
self->dx *= self->speed;
|
||||
self->dy *= self->speed;
|
||||
s->dx *= s->speed;
|
||||
s->dy *= s->speed;
|
||||
|
||||
if (abs(self->x - self->closedX) < self->speed && abs(self->y - self->closedY) < self->speed)
|
||||
if (abs(s->x - s->closedX) < s->speed && abs(self->y - s->closedY) < s->speed)
|
||||
{
|
||||
self->x = self->closedX;
|
||||
self->y = self->closedY;
|
||||
s->x = s->closedX;
|
||||
s->y = s->closedY;
|
||||
}
|
||||
|
||||
self->isStatic = 0;
|
||||
s->isStatic = 0;
|
||||
}
|
||||
|
||||
if (self->dx == 0 && self->dy == 0 && !self->isStatic)
|
||||
if (s->dx == 0 && s->dy == 0 && !s->isStatic)
|
||||
{
|
||||
self->isStatic = 1;
|
||||
s->isStatic = 1;
|
||||
|
||||
playSound(SND_DOOR_FINISH, CH_MECHANICAL);
|
||||
}
|
||||
|
@ -133,27 +153,31 @@ static void tick(void)
|
|||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
if ((other->type != ET_BOB && self->isLocked) || (other->type != ET_BOB && other->type != ET_ENEMY))
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if ((other->type != ET_BOB && s->isLocked) || (other->type != ET_BOB && other->type != ET_ENEMY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->isLocked && !dev.cheatKeys)
|
||||
if (s->isLocked && !dev.cheatKeys)
|
||||
{
|
||||
if (isClosed())
|
||||
{
|
||||
if (strlen(self->requiredKey) != 0)
|
||||
if (strlen(s->requiredItem) != 0)
|
||||
{
|
||||
openWithKey();
|
||||
}
|
||||
else if (self->thinkTime == 0)
|
||||
else if (s->thinkTime == 0)
|
||||
{
|
||||
setGameplayMessage(MSG_GAMEPLAY, "Door is locked");
|
||||
|
||||
playSound(SND_DENIED, CH_MECHANICAL);
|
||||
}
|
||||
|
||||
self->thinkTime = 2;
|
||||
s->thinkTime = 2;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -163,56 +187,66 @@ static void touch(Entity *other)
|
|||
}
|
||||
}
|
||||
|
||||
if (self->state != DOOR_OPEN)
|
||||
if (s->state != DOOR_OPEN)
|
||||
{
|
||||
playSound(SND_DOOR_START, CH_MECHANICAL);
|
||||
}
|
||||
|
||||
self->state = DOOR_OPEN;
|
||||
s->state = DOOR_OPEN;
|
||||
}
|
||||
|
||||
static void openWithKey(void)
|
||||
{
|
||||
if (hasItem(self->requiredKey))
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if (hasItem(s->requiredItem))
|
||||
{
|
||||
if (self->thinkTime <= 0)
|
||||
if (s->thinkTime <= 0)
|
||||
{
|
||||
setGameplayMessage(MSG_GAMEPLAY, "%s required", self->requiredKey);
|
||||
setGameplayMessage(MSG_GAMEPLAY, "%s required", s->requiredItem);
|
||||
|
||||
playSound(SND_DENIED, CH_MECHANICAL);
|
||||
}
|
||||
|
||||
self->thinkTime = 2;
|
||||
s->thinkTime = 2;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
removeItem(self->requiredKey);
|
||||
removeItem(s->requiredItem);
|
||||
|
||||
setGameplayMessage(MSG_GAMEPLAY, "%s removed", self->requiredKey);
|
||||
setGameplayMessage(MSG_GAMEPLAY, "%s removed", s->requiredItem);
|
||||
|
||||
STRNCPY(self->requiredKey, "", MAX_NAME_LENGTH);
|
||||
self->isLocked = 0;
|
||||
STRNCPY(s->requiredItem, "", MAX_NAME_LENGTH);
|
||||
s->isLocked = 0;
|
||||
|
||||
if (self->state != DOOR_OPEN)
|
||||
if (s->state != DOOR_OPEN)
|
||||
{
|
||||
playSound(SND_DOOR_START, CH_MECHANICAL);
|
||||
}
|
||||
|
||||
self->state = DOOR_OPEN;
|
||||
s->state = DOOR_OPEN;
|
||||
}
|
||||
|
||||
static int isOpening(void)
|
||||
{
|
||||
return (self->state == DOOR_OPEN && ((int) self->x != (int) self->tx || (int) self->y != (int) self->ty));
|
||||
Structure *s = (Structure*)self;
|
||||
|
||||
return (s->state == DOOR_OPEN && ((int) s->x != (int) s->tx || (int) s->y != (int) s->ty));
|
||||
}
|
||||
|
||||
static int isClosing(void)
|
||||
{
|
||||
return (self->state == DOOR_CLOSED && ((int) self->x != self->closedX || (int) self->y != self->closedY));
|
||||
Structure *s = (Structure*)self;
|
||||
|
||||
return (s->state == DOOR_CLOSED && ((int) s->x != s->closedX || (int) s->y != s->closedY));
|
||||
}
|
||||
|
||||
static int isClosed(void)
|
||||
{
|
||||
return (self->state == DOOR_CLOSED && ((int) self->x == self->closedX && (int) self->y == self->closedY));
|
||||
Structure *s = (Structure*)self;
|
||||
|
||||
return (s->state == DOOR_CLOSED && ((int) s->x == s->closedX && (int) s->y == s->closedY));
|
||||
}
|
||||
|
|
|
@ -23,75 +23,92 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
static void tick(void);
|
||||
static void action(void);
|
||||
static void touch(Entity *other);
|
||||
static SDL_Rect getBounds(void);
|
||||
static SDL_Rect *getBounds(void);
|
||||
|
||||
void initExit(Entity *e)
|
||||
{
|
||||
e->sprite[FACING_LEFT] = e->sprite[FACING_RIGHT] = e->sprite[FACING_DIE] = getSpriteIndex("Exit");
|
||||
|
||||
e->flags |= EF_WEIGHTLESS | EF_NO_CLIP | EF_NO_ENVIRONMENT | EF_IGNORE_BULLETS;
|
||||
|
||||
e->isStatic = 1;
|
||||
|
||||
e->active = 0;
|
||||
Structure *s;
|
||||
|
||||
if (!e->active)
|
||||
initEntity(e);
|
||||
|
||||
s = (Structure*)e;
|
||||
|
||||
s->sprite[FACING_LEFT] = s->sprite[FACING_RIGHT] = s->sprite[FACING_DIE] = getSpriteIndex("Exit");
|
||||
|
||||
s->flags |= EF_WEIGHTLESS | EF_NO_CLIP | EF_NO_ENVIRONMENT | EF_IGNORE_BULLETS;
|
||||
|
||||
s->isStatic = 1;
|
||||
|
||||
s->active = 0;
|
||||
|
||||
if (!s->active)
|
||||
{
|
||||
e->spriteFrame = 0;
|
||||
s->spriteFrame = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
e->spriteFrame = 1;
|
||||
s->spriteFrame = 1;
|
||||
}
|
||||
|
||||
e->spriteTime = -1;
|
||||
s->spriteTime = -1;
|
||||
|
||||
e->tick = tick;
|
||||
e->action = action;
|
||||
e->touch = touch;
|
||||
e->getBounds = getBounds;
|
||||
s->tick = tick;
|
||||
s->action = action;
|
||||
s->touch = touch;
|
||||
s->getBounds = getBounds;
|
||||
}
|
||||
|
||||
static void tick(void)
|
||||
{
|
||||
if (!self->active)
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if (!s->active)
|
||||
{
|
||||
self->bobTouching = MAX(self->bobTouching - 1, 0);
|
||||
s->bobTouching = MAX(s->bobTouching - 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void action(void)
|
||||
{
|
||||
Objective *o;
|
||||
Structure *s;
|
||||
|
||||
if (!self->active)
|
||||
s = (Structure*)self;
|
||||
|
||||
if (!s->active)
|
||||
{
|
||||
self->active = 1;
|
||||
s->active = 1;
|
||||
|
||||
for (o = world.objectiveHead.next ; o != NULL ; o = o->next)
|
||||
{
|
||||
if (o->required && strcmp(o->targetName, "EXIT") != 0 && o->currentValue < o->targetValue)
|
||||
{
|
||||
self->active = 0;
|
||||
s->active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (self->active)
|
||||
if (s->active)
|
||||
{
|
||||
self->spriteFrame = 1;
|
||||
s->spriteFrame = 1;
|
||||
}
|
||||
}
|
||||
|
||||
self->thinkTime = FPS;
|
||||
s->thinkTime = FPS;
|
||||
}
|
||||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if (other->type == ET_BOB && !world.isReturnVisit)
|
||||
{
|
||||
if (self->bobTouching == 0)
|
||||
if (s->bobTouching == 0)
|
||||
{
|
||||
if (self->active)
|
||||
if (s->active)
|
||||
{
|
||||
updateObjective("EXIT");
|
||||
world.missionCompleteTimer = (int) (FPS * 1.5);
|
||||
|
@ -105,16 +122,16 @@ static void touch(Entity *other)
|
|||
}
|
||||
}
|
||||
|
||||
self->bobTouching = 2;
|
||||
s->bobTouching = 2;
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_Rect getBounds(void)
|
||||
static SDL_Rect *getBounds(void)
|
||||
{
|
||||
self->bounds.x = self->x + 64;
|
||||
self->bounds.y = self->y;
|
||||
self->bounds.w = 2;
|
||||
self->bounds.h = self->h;
|
||||
|
||||
return self->bounds;
|
||||
return &self->bounds;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ extern int getSpriteIndex(char *name);
|
|||
extern void updateObjective(char *targetName);
|
||||
extern void setGameplayMessage(int type, char *format, ...);
|
||||
extern void stopMusic(void);
|
||||
extern void initEntity(Entity *e);
|
||||
|
||||
extern Entity *self;
|
||||
extern World world;
|
||||
|
|
|
@ -31,19 +31,19 @@ void initBronzeHorizontalDoor(Entity *e)
|
|||
{
|
||||
initHorizontalDoor(e);
|
||||
|
||||
STRNCPY(e->requiredKey, "Bronze Key", MAX_NAME_LENGTH);
|
||||
STRNCPY(((Structure*)e)->requiredItem, "Bronze Key", MAX_NAME_LENGTH);
|
||||
}
|
||||
|
||||
void initSilverHorizontalDoor(Entity *e)
|
||||
{
|
||||
initHorizontalDoor(e);
|
||||
|
||||
STRNCPY(e->requiredKey, "Silver Key", MAX_NAME_LENGTH);
|
||||
STRNCPY(((Structure*)e)->requiredItem, "Silver Key", MAX_NAME_LENGTH);
|
||||
}
|
||||
|
||||
void initGoldHorizontalDoor(Entity *e)
|
||||
{
|
||||
initHorizontalDoor(e);
|
||||
|
||||
STRNCPY(e->requiredKey, "Gold Key", MAX_NAME_LENGTH);
|
||||
STRNCPY(((Structure*)e)->requiredItem, "Gold Key", MAX_NAME_LENGTH);
|
||||
}
|
||||
|
|
|
@ -48,16 +48,23 @@ void initItemPad(Entity *e)
|
|||
|
||||
static void tick(void)
|
||||
{
|
||||
self->bobTouching = MAX(self->bobTouching - 1, 0);
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
s->bobTouching = MAX(s->bobTouching - 1, 0);
|
||||
}
|
||||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
Entity *i;
|
||||
Structure *s;
|
||||
Item *i;
|
||||
|
||||
if (other->type == ET_BOB && !self->active)
|
||||
s = (Structure*)self;
|
||||
|
||||
if (other->type == ET_BOB && !s->active)
|
||||
{
|
||||
i = getItem(self->requiredItem);
|
||||
i = getItem(s->requiredItem);
|
||||
|
||||
if (i != NULL)
|
||||
{
|
||||
|
@ -65,26 +72,26 @@ static void touch(Entity *other)
|
|||
|
||||
i->flags &= ~EF_GONE;
|
||||
|
||||
i->x = self->x + (self->w / 2) - (i->w / 2);
|
||||
i->y = self->y - i->h;
|
||||
i->x = s->x + (s->w / 2) - (i->w / 2);
|
||||
i->y = s->y - i->h;
|
||||
|
||||
i->canBeCarried = i->canBePickedUp = i->isMissionTarget = 0;
|
||||
|
||||
self->active = 1;
|
||||
s->active = 1;
|
||||
|
||||
setGameplayMessage(MSG_GAMEPLAY, "%s removed", self->requiredItem);
|
||||
setGameplayMessage(MSG_GAMEPLAY, "%s removed", s->requiredItem);
|
||||
|
||||
self->sprite[FACING_LEFT] = self->sprite[FACING_RIGHT] = self->sprite[FACING_DIE] = getSpriteIndex("ItemPadActive");
|
||||
s->sprite[FACING_LEFT] = s->sprite[FACING_RIGHT] = s->sprite[FACING_DIE] = getSpriteIndex("ItemPadActive");
|
||||
|
||||
self->spriteFrame = 0;
|
||||
s->spriteFrame = 0;
|
||||
|
||||
updateObjective(self->name);
|
||||
updateObjective(s->name);
|
||||
}
|
||||
else if (!self->bobTouching)
|
||||
else if (!s->bobTouching)
|
||||
{
|
||||
setGameplayMessage(MSG_GAMEPLAY, "%s required", self->requiredItem);
|
||||
setGameplayMessage(MSG_GAMEPLAY, "%s required", s->requiredItem);
|
||||
}
|
||||
|
||||
self->bobTouching = 2;
|
||||
s->bobTouching = 2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,6 @@ extern int getSpriteIndex(char *name);
|
|||
extern void updateObjective(char *targetName);
|
||||
extern void setGameplayMessage(int type, char *format, ...);
|
||||
extern void removeItem(char *name);
|
||||
extern Entity *getItem(char *name);
|
||||
extern Item *getItem(char *name);
|
||||
|
||||
extern Entity *self;
|
||||
|
|
|
@ -25,62 +25,70 @@ static void activate(int active);
|
|||
|
||||
void initLift(Entity *e)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
e->state = LIFT_GOTO_FINISH;
|
||||
|
||||
e->flags |= EF_WEIGHTLESS | EF_NO_ENVIRONMENT | EF_EXPLODES | EF_NO_CLIP | EF_ALWAYS_PROCESS | EF_NO_TELEPORT;
|
||||
|
||||
e->speed = 2;
|
||||
|
||||
e->waitTime = 2;
|
||||
|
||||
e->startX = e->startY = -1;
|
||||
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = getSpriteIndex("Lift");
|
||||
|
||||
e->active = 1;
|
||||
s = (Structure*)e;
|
||||
|
||||
e->action = action;
|
||||
e->activate = activate;
|
||||
s->state = LIFT_GOTO_FINISH;
|
||||
|
||||
s->flags |= EF_WEIGHTLESS | EF_NO_ENVIRONMENT | EF_EXPLODES | EF_NO_CLIP | EF_ALWAYS_PROCESS | EF_NO_TELEPORT;
|
||||
|
||||
s->speed = 2;
|
||||
|
||||
s->waitTime = 2;
|
||||
|
||||
s->startX = s->startY = -1;
|
||||
|
||||
s->sprite[0] = s->sprite[1] = s->sprite[2] = getSpriteIndex("Lift");
|
||||
|
||||
s->active = 1;
|
||||
|
||||
s->action = action;
|
||||
s->activate = activate;
|
||||
}
|
||||
|
||||
static void action(void)
|
||||
{
|
||||
self->dx = self->dy = 0;
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
s->dx = s->dy = 0;
|
||||
|
||||
if (self->active)
|
||||
if (s->active)
|
||||
{
|
||||
if (self->state == LIFT_GOTO_START)
|
||||
if (s->state == LIFT_GOTO_START)
|
||||
{
|
||||
getSlope(self->startX, self->startY, self->x, self->y, &self->dx, &self->dy);
|
||||
getSlope(s->startX, s->startY, s->x, s->y, &s->dx, &s->dy);
|
||||
|
||||
self->dx *= self->speed;
|
||||
self->dy *= self->speed;
|
||||
s->dx *= s->speed;
|
||||
s->dy *= s->speed;
|
||||
|
||||
if (abs(self->x - self->startX) < self->speed && abs(self->y - self->startY) < self->speed)
|
||||
if (abs(s->x - s->startX) < s->speed && abs(s->y - s->startY) < s->speed)
|
||||
{
|
||||
self->x = self->startX;
|
||||
self->y = self->startY;
|
||||
self->state = LIFT_GOTO_FINISH;
|
||||
self->thinkTime = self->waitTime * FPS;
|
||||
self->dx = self->dy = 0;
|
||||
s->x = s->startX;
|
||||
s->y = s->startY;
|
||||
s->state = LIFT_GOTO_FINISH;
|
||||
s->thinkTime = s->waitTime * FPS;
|
||||
s->dx = s->dy = 0;
|
||||
}
|
||||
}
|
||||
else if (self->state == LIFT_GOTO_FINISH)
|
||||
else if (s->state == LIFT_GOTO_FINISH)
|
||||
{
|
||||
getSlope(self->tx, self->ty, self->x, self->y, &self->dx, &self->dy);
|
||||
getSlope(s->tx, s->ty, s->x, s->y, &s->dx, &s->dy);
|
||||
|
||||
self->dx *= self->speed;
|
||||
self->dy *= self->speed;
|
||||
s->dx *= s->speed;
|
||||
s->dy *= s->speed;
|
||||
|
||||
if (abs(self->x - self->tx) < self->speed && abs(self->y - self->ty) < self->speed)
|
||||
if (abs(s->x - s->tx) < s->speed && abs(s->y - s->ty) < s->speed)
|
||||
{
|
||||
self->x = self->tx;
|
||||
self->y = self->ty;
|
||||
self->state = LIFT_GOTO_START;
|
||||
self->thinkTime = self->waitTime * FPS;
|
||||
self->dx = self->dy = 0;
|
||||
s->x = s->tx;
|
||||
s->y = s->ty;
|
||||
s->state = LIFT_GOTO_START;
|
||||
s->thinkTime = s->waitTime * FPS;
|
||||
s->dx = s->dy = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,72 +26,88 @@ static void touch(Entity *other);
|
|||
|
||||
void initPowerPoint(Entity *e)
|
||||
{
|
||||
initEntity(e);
|
||||
|
||||
e->sprite[FACING_LEFT] = e->sprite[FACING_RIGHT] = e->sprite[FACING_DIE] = getSpriteIndex("PowerPoint");
|
||||
|
||||
e->flags |= EF_WEIGHTLESS | EF_NO_CLIP | EF_NO_ENVIRONMENT | EF_IGNORE_BULLETS;
|
||||
|
||||
e->requiredPower = 100;
|
||||
|
||||
e->isStatic = 1;
|
||||
Structure *s;
|
||||
|
||||
e->tick = tick;
|
||||
e->action = action;
|
||||
e->touch = touch;
|
||||
initEntity(e);
|
||||
|
||||
s = (Structure*)e;
|
||||
|
||||
s->sprite[FACING_LEFT] = s->sprite[FACING_RIGHT] = s->sprite[FACING_DIE] = getSpriteIndex("PowerPoint");
|
||||
|
||||
s->flags |= EF_WEIGHTLESS | EF_NO_CLIP | EF_NO_ENVIRONMENT | EF_IGNORE_BULLETS;
|
||||
|
||||
s->requiredPower = 100;
|
||||
|
||||
s->isStatic = 1;
|
||||
|
||||
s->tick = tick;
|
||||
s->action = action;
|
||||
s->touch = touch;
|
||||
}
|
||||
|
||||
static void tick(void)
|
||||
{
|
||||
if (!self->active)
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if (!s->active)
|
||||
{
|
||||
self->bobTouching = MAX(self->bobTouching - 1, 0);
|
||||
s->bobTouching = MAX(s->bobTouching - 1, 0);
|
||||
|
||||
if (self->bobTouching == 0)
|
||||
if (s->bobTouching == 0)
|
||||
{
|
||||
self->spriteFrame = 0;
|
||||
self->spriteTime = -1;
|
||||
self->thinkTime = FPS / 2;
|
||||
s->spriteFrame = 0;
|
||||
s->spriteTime = -1;
|
||||
s->thinkTime = FPS / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void action(void)
|
||||
{
|
||||
self->spriteFrame = MIN(self->spriteFrame + 1, 3);
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
s->spriteFrame = MIN(s->spriteFrame + 1, 3);
|
||||
|
||||
if (!self->active && self->spriteFrame == 3)
|
||||
if (!s->active && s->spriteFrame == 3)
|
||||
{
|
||||
activateEntities(self->targetNames, 1);
|
||||
activateEntities(s->targetNames, 1);
|
||||
|
||||
setGameplayMessage(MSG_GAMEPLAY, self->message);
|
||||
setGameplayMessage(MSG_GAMEPLAY, s->message);
|
||||
|
||||
if (!dev.cheatPower)
|
||||
{
|
||||
world.bob->power -= self->requiredPower;
|
||||
world.bob->power -= s->requiredPower;
|
||||
}
|
||||
|
||||
self->requiredPower = 0;
|
||||
s->requiredPower = 0;
|
||||
|
||||
self->active = 1;
|
||||
s->active = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->thinkTime = FPS / 2;
|
||||
s->thinkTime = FPS / 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
if (!self->active && other->type == ET_BOB && other->dx == 0)
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if (!s->active && other->type == ET_BOB && other->dx == 0)
|
||||
{
|
||||
if (world.bob->power < self->requiredPower && self->bobTouching == 0 && !dev.cheatPower)
|
||||
if (world.bob->power < s->requiredPower && s->bobTouching == 0 && !dev.cheatPower)
|
||||
{
|
||||
setGameplayMessage(MSG_GAMEPLAY, "Not enough power (%d units required)", self->requiredPower);
|
||||
setGameplayMessage(MSG_GAMEPLAY, "Not enough power (%d units required)", s->requiredPower);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->bobTouching = 2;
|
||||
s->bobTouching = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,57 +26,75 @@ static void touch(Entity *other);
|
|||
|
||||
void initPowerPool(Entity *e)
|
||||
{
|
||||
e->sprite[FACING_LEFT] = e->sprite[FACING_RIGHT] = e->sprite[FACING_DIE] = getSpriteIndex("PowerPool");
|
||||
|
||||
e->flags |= EF_WEIGHTLESS | EF_NO_CLIP | EF_IGNORE_BULLETS;
|
||||
|
||||
e->plane = PLANE_FOREGROUND;
|
||||
|
||||
e->isStatic = 1;
|
||||
Structure *s;
|
||||
|
||||
e->tick = tick;
|
||||
e->action = action;
|
||||
e->touch = touch;
|
||||
initEntity(e);
|
||||
|
||||
s = (Structure*)e;
|
||||
|
||||
s->sprite[FACING_LEFT] = s->sprite[FACING_RIGHT] = s->sprite[FACING_DIE] = getSpriteIndex("PowerPool");
|
||||
|
||||
s->flags |= EF_WEIGHTLESS | EF_NO_CLIP | EF_IGNORE_BULLETS;
|
||||
|
||||
s->plane = PLANE_FOREGROUND;
|
||||
|
||||
s->isStatic = 1;
|
||||
|
||||
s->tick = tick;
|
||||
s->action = action;
|
||||
s->touch = touch;
|
||||
}
|
||||
|
||||
static void tick(void)
|
||||
{
|
||||
if (self->active)
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if (s->active)
|
||||
{
|
||||
self->spriteTime--;
|
||||
if (self->spriteTime <= 0)
|
||||
s->spriteTime--;
|
||||
if (s->spriteTime <= 0)
|
||||
{
|
||||
self->spriteFrame = (int) (1 + (rand() % 6));
|
||||
self->spriteTime = 12;
|
||||
s->spriteFrame = (int) (1 + (rand() % 6));
|
||||
s->spriteTime = 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void action(void)
|
||||
{
|
||||
self->active = 1;
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
s->active = 1;
|
||||
|
||||
if (self->spriteFrame == 0)
|
||||
if (s->spriteFrame == 0)
|
||||
{
|
||||
self->spriteFrame = (int) (1 + (rand() % 6));
|
||||
self->spriteTime = 12;
|
||||
s->spriteFrame = (int) (1 + (rand() % 6));
|
||||
s->spriteTime = 12;
|
||||
}
|
||||
|
||||
self->thinkTime = FPS * 99999;
|
||||
s->thinkTime = FPS * 99999;
|
||||
}
|
||||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
if (self->active && other->type == ET_BOB && world.bob->power < world.bob->powerMax)
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if (s->active && other->type == ET_BOB && world.bob->power < world.bob->powerMax)
|
||||
{
|
||||
world.bob->power = MIN(world.bob->power + 0.05, world.bob->powerMax);
|
||||
|
||||
if (world.bob->power == world.bob->powerMax)
|
||||
{
|
||||
self->thinkTime = FPS * 10;
|
||||
self->spriteTime = -1;
|
||||
self->spriteFrame = 0;
|
||||
self->active = 0;
|
||||
s->thinkTime = FPS * 10;
|
||||
s->spriteTime = -1;
|
||||
s->spriteFrame = 0;
|
||||
s->active = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "../../../common.h"
|
||||
|
||||
extern int getSpriteIndex(char *name);
|
||||
extern void initEntity(Entity *e);
|
||||
|
||||
extern Entity *self;
|
||||
extern World world;
|
||||
|
|
|
@ -25,49 +25,61 @@ static void touch(Entity *other);
|
|||
|
||||
void initPressurePlate(Entity *e)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
e->sprite[FACING_LEFT] = e->sprite[FACING_RIGHT] = e->sprite[FACING_DIE] = getSpriteIndex("PressurePlate");
|
||||
|
||||
e->flags |= EF_WEIGHTLESS | EF_NO_CLIP | EF_NO_ENVIRONMENT | EF_IGNORE_BULLETS;
|
||||
|
||||
e->plane = PLANE_FOREGROUND;
|
||||
|
||||
e->isStatic = 1;
|
||||
s = (Structure*)e;
|
||||
|
||||
e->tick = tick;
|
||||
e->touch = touch;
|
||||
s->sprite[FACING_LEFT] = s->sprite[FACING_RIGHT] = s->sprite[FACING_DIE] = getSpriteIndex("PressurePlate");
|
||||
|
||||
s->flags |= EF_WEIGHTLESS | EF_NO_CLIP | EF_NO_ENVIRONMENT | EF_IGNORE_BULLETS;
|
||||
|
||||
s->plane = PLANE_FOREGROUND;
|
||||
|
||||
s->isStatic = 1;
|
||||
|
||||
s->tick = tick;
|
||||
s->touch = touch;
|
||||
}
|
||||
|
||||
static void tick(void)
|
||||
{
|
||||
if (self->isWeighted)
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if (s->isWeighted)
|
||||
{
|
||||
self->weightApplied = MAX(self->weightApplied - 1, 0);
|
||||
s->weightApplied = MAX(s->weightApplied - 1, 0);
|
||||
|
||||
if (self->active && self->weightApplied == 0)
|
||||
if (s->active && s->weightApplied == 0)
|
||||
{
|
||||
self->active = 0;
|
||||
self->spriteFrame = 0;
|
||||
s->active = 0;
|
||||
s->spriteFrame = 0;
|
||||
|
||||
activateEntities(self->targetNames, 0);
|
||||
activateEntities(s->targetNames, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if (other->type == ET_BOB || other->type == ET_PUSHBLOCK)
|
||||
{
|
||||
if (!self->active)
|
||||
if (!s->active)
|
||||
{
|
||||
activateEntities(self->targetNames, 1);
|
||||
activateEntities(s->targetNames, 1);
|
||||
|
||||
playSound(SND_PRESSURE_PLATE, CH_MECHANICAL);
|
||||
}
|
||||
|
||||
self->active = 1;
|
||||
self->spriteFrame = 1;
|
||||
self->weightApplied = 5;
|
||||
s->active = 1;
|
||||
s->spriteFrame = 1;
|
||||
s->weightApplied = 5;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,25 +24,33 @@ static void activate(int active);
|
|||
|
||||
void initPushBlock(Entity *e)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
e->isSolid = 1;
|
||||
|
||||
e->startX = e->startY = -1;
|
||||
|
||||
e->flags |= EF_EXPLODES | EF_ALWAYS_PROCESS;
|
||||
s = (Structure*)e;
|
||||
|
||||
e->activate = activate;
|
||||
s->isSolid = 1;
|
||||
|
||||
s->startX = s->startY = -1;
|
||||
|
||||
s->flags |= EF_EXPLODES | EF_ALWAYS_PROCESS;
|
||||
|
||||
s->activate = activate;
|
||||
}
|
||||
|
||||
static void activate(int active)
|
||||
{
|
||||
Structure *s;
|
||||
|
||||
s = (Structure*)self;
|
||||
|
||||
if (self->active)
|
||||
{
|
||||
addTeleportStars(self);
|
||||
self->x = self->startX;
|
||||
self->y = self->startY;
|
||||
self->dx = self->dy = 0;
|
||||
s->x = s->startX;
|
||||
s->y = s->startY;
|
||||
s->dx = s->dy = 0;
|
||||
addTeleportStars(self);
|
||||
playSound(SND_APPEAR, CH_ANY);
|
||||
}
|
||||
|
|
|
@ -28,22 +28,26 @@ static void activate(int active);
|
|||
|
||||
void initLaserTrap(Entity *e)
|
||||
{
|
||||
Trap *t;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
e->flags |= EF_WEIGHTLESS | EF_IGNORE_BULLETS | EF_NO_ENVIRONMENT | EF_NO_CLIP | EF_ALWAYS_PROCESS;
|
||||
|
||||
e->onTime = FPS * 2;
|
||||
e->offTime = FPS * 2;
|
||||
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = getSpriteIndex("LaserTrap");
|
||||
|
||||
e->active = 1;
|
||||
t = (Trap*)e;
|
||||
|
||||
e->init = init;
|
||||
e->tick = tick;
|
||||
e->action = action;
|
||||
e->touch = touch;
|
||||
e->activate = activate;
|
||||
t->flags |= EF_WEIGHTLESS | EF_IGNORE_BULLETS | EF_NO_ENVIRONMENT | EF_NO_CLIP | EF_ALWAYS_PROCESS;
|
||||
|
||||
t->onTime = FPS * 2;
|
||||
t->offTime = FPS * 2;
|
||||
|
||||
t->sprite[0] = t->sprite[1] = t->sprite[2] = getSpriteIndex("LaserTrap");
|
||||
|
||||
t->active = 1;
|
||||
|
||||
t->init = init;
|
||||
t->tick = tick;
|
||||
t->action = action;
|
||||
t->touch = touch;
|
||||
t->activate = activate;
|
||||
}
|
||||
|
||||
static void init(void)
|
||||
|
@ -56,40 +60,52 @@ static void init(void)
|
|||
|
||||
static void tick(void)
|
||||
{
|
||||
if (!self->active && self->spriteTime == -1)
|
||||
Trap *t;
|
||||
|
||||
t = (Trap*)self;
|
||||
|
||||
if (!t->active && t->spriteTime == -1)
|
||||
{
|
||||
self->flags |= EF_GONE;
|
||||
t->flags |= EF_GONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void action(void)
|
||||
{
|
||||
if (self->offTime != 0)
|
||||
Trap *t;
|
||||
|
||||
t = (Trap*)self;
|
||||
|
||||
if (t->offTime != 0)
|
||||
{
|
||||
if (!self->active)
|
||||
if (!t->active)
|
||||
{
|
||||
self->thinkTime = self->onTime;
|
||||
self->spriteFrame = 0;
|
||||
self->spriteTime = 0;
|
||||
self->flags &= ~EF_GONE;
|
||||
t->thinkTime = t->onTime;
|
||||
t->spriteFrame = 0;
|
||||
t->spriteTime = 0;
|
||||
t->flags &= ~EF_GONE;
|
||||
}
|
||||
else if (self->offTime > 0)
|
||||
else if (t->offTime > 0)
|
||||
{
|
||||
self->thinkTime = self->offTime;
|
||||
self->spriteTime = 0;
|
||||
t->thinkTime = t->offTime;
|
||||
t->spriteTime = 0;
|
||||
}
|
||||
|
||||
self->active = !self->active;
|
||||
t->active = !t->active;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->spriteTime = -1;
|
||||
self->spriteFrame = 4;
|
||||
t->spriteTime = -1;
|
||||
t->spriteFrame = 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void touch(Entity *other)
|
||||
{
|
||||
Trap *t;
|
||||
|
||||
t = (Trap*)self;
|
||||
|
||||
if (other != NULL && (other->type == ET_BOB || other->type == ET_ENEMY))
|
||||
{
|
||||
if (!(other->flags & EF_IMMUNE))
|
||||
|
@ -99,7 +115,7 @@ static void touch(Entity *other)
|
|||
other->dx = rrnd(-12, 12);
|
||||
other->dy = rrnd(-8, 0);
|
||||
|
||||
if (self->offTime != 0)
|
||||
if (t->offTime != 0)
|
||||
{
|
||||
other->applyDamage((int) (other->healthMax / 4));
|
||||
}
|
||||
|
@ -110,7 +126,7 @@ static void touch(Entity *other)
|
|||
}
|
||||
}
|
||||
|
||||
if (other == world.bob && world.bob->stunTimer == 0)
|
||||
if (other == (Entity*)world.bob && world.bob->stunTimer == 0)
|
||||
{
|
||||
stunPlayer();
|
||||
}
|
||||
|
@ -118,11 +134,11 @@ static void touch(Entity *other)
|
|||
|
||||
if (other->flags & EF_EXPLODES)
|
||||
{
|
||||
addSparkParticles(self->x, self->y);
|
||||
addSparkParticles(t->x, t->y);
|
||||
}
|
||||
else
|
||||
{
|
||||
addSmallFleshChunk(self->x, self->y);
|
||||
addSmallFleshChunk(t->x, t->y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,120 +22,121 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
void unitTick(void);
|
||||
static void attack(void);
|
||||
static int canFire(Entity *target);
|
||||
|
||||
void initUnit(Entity *e)
|
||||
{
|
||||
Unit *u;
|
||||
|
||||
initEntity(e);
|
||||
|
||||
e->oxygen = MAX_OXYGEN;
|
||||
u = (Unit*)e;
|
||||
|
||||
u->oxygen = MAX_OXYGEN;
|
||||
|
||||
e->canCarryItem = rand() % 100 < 85;
|
||||
u->canCarryItem = rand() % 100 < 85;
|
||||
|
||||
if (world.isOutpostMission)
|
||||
{
|
||||
e->canCarryItem = 1;
|
||||
e->health = e->healthMax = rrnd(1, 4);
|
||||
u->canCarryItem = 1;
|
||||
u->health = u->healthMax = rrnd(1, 4);
|
||||
}
|
||||
|
||||
e->spriteFrame = 0;
|
||||
u->spriteFrame = 0;
|
||||
|
||||
e->startX = e->startY = -1;
|
||||
u->startX = u->startY = -1;
|
||||
|
||||
e->tick = unitTick;
|
||||
e->action = lookForPlayer;
|
||||
e->attack = attack;
|
||||
u->tick = unitTick;
|
||||
u->action = lookForPlayer;
|
||||
u->attack = attack;
|
||||
u->canFire = canFire;
|
||||
}
|
||||
|
||||
void reInitUnit(Entity *e)
|
||||
{
|
||||
if (e->startX == -1 && e->startY == -1)
|
||||
Unit *u;
|
||||
|
||||
u = (Unit*)self;
|
||||
|
||||
if (u->startX == -1 && u->startY == -1)
|
||||
{
|
||||
e->startX = (int) e->x;
|
||||
e->startY = (int) e->y;
|
||||
u->startX = (int) u->x;
|
||||
u->startY = (int) u->y;
|
||||
}
|
||||
|
||||
if (e->isMissionTarget)
|
||||
if (u->isMissionTarget)
|
||||
{
|
||||
e->flags |= EF_BOMB_SHIELD;
|
||||
u->flags |= EF_BOMB_SHIELD;
|
||||
}
|
||||
}
|
||||
|
||||
void unitTick(void)
|
||||
{
|
||||
if (self->alive == ALIVE_ALIVE)
|
||||
Unit *u;
|
||||
|
||||
u = (Unit*)self;
|
||||
|
||||
if (u->alive == ALIVE_ALIVE)
|
||||
{
|
||||
self->reload = limit(self->reload - 1, 0, FPS);
|
||||
u->reload = limit(u->reload - 1, 0, FPS);
|
||||
}
|
||||
|
||||
switch (self->environment)
|
||||
switch (u->environment)
|
||||
{
|
||||
case ENV_AIR:
|
||||
self->oxygen = limit(self->oxygen + 4, 0, MAX_OXYGEN);
|
||||
u->oxygen = limit(u->oxygen + 4, 0, MAX_OXYGEN);
|
||||
break;
|
||||
|
||||
case ENV_WATER:
|
||||
self->oxygen = limit(self->oxygen - 1, 0, MAX_OXYGEN);
|
||||
if (self->oxygen == 0 && world.frameCounter % 30 == 0)
|
||||
u->oxygen = limit(u->oxygen - 1, 0, MAX_OXYGEN);
|
||||
if (u->oxygen == 0 && world.frameCounter % 30 == 0)
|
||||
{
|
||||
self->health--;
|
||||
u->health--;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENV_SLIME:
|
||||
case ENV_LAVA:
|
||||
if (self->alive == ALIVE_ALIVE)
|
||||
if (u->alive == ALIVE_ALIVE)
|
||||
{
|
||||
self->health = 0;
|
||||
u->health = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (self->flags & EF_WATER_BREATHING)
|
||||
if (u->flags & EF_WATER_BREATHING)
|
||||
{
|
||||
self->oxygen = MAX_OXYGEN;
|
||||
u->oxygen = MAX_OXYGEN;
|
||||
}
|
||||
|
||||
if (self->spawnedIn)
|
||||
if (u->spawnedIn)
|
||||
{
|
||||
if (getDistance(self->x, self->y, world.bob->x, world.bob->y) < 1000)
|
||||
if (getDistance(u->x, u->y, world.bob->x, world.bob->y) < 1000)
|
||||
{
|
||||
self->spawnedInTimer = FPS * 5;
|
||||
u->spawnedInTimer = FPS * 5;
|
||||
}
|
||||
|
||||
self->spawnedInTimer--;
|
||||
if (self->spawnedInTimer <= 0)
|
||||
u->spawnedInTimer--;
|
||||
if (u->spawnedInTimer <= 0)
|
||||
{
|
||||
self->alive = ALIVE_DEAD;
|
||||
u->alive = ALIVE_DEAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dropCarriedItem(Entity *e)
|
||||
{
|
||||
if (e->carriedItem != NULL)
|
||||
{
|
||||
e->carriedItem->x = (e->x + e->w / 2) - e->carriedItem->w / 2;
|
||||
e->carriedItem->y = e->y;
|
||||
|
||||
e->carriedItem->dx = e->carriedItem->dy = 0;
|
||||
|
||||
world.entityTail->next = e->carriedItem;
|
||||
world.entityTail = e->carriedItem;
|
||||
world.entityTail->next = NULL;
|
||||
|
||||
e->carriedItem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void unitReappear(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void attack(void)
|
||||
{
|
||||
if (canFire(world.bob))
|
||||
Unit *u;
|
||||
|
||||
u = (Unit*)self;
|
||||
|
||||
if (u->canFire((Entity*)world.bob))
|
||||
{
|
||||
switch (self->weaponType)
|
||||
switch (u->weaponType)
|
||||
{
|
||||
case WPN_AIMED_PISTOL:
|
||||
fireAimedShot(self);
|
||||
|
@ -170,10 +171,13 @@ static void attack(void)
|
|||
break;
|
||||
|
||||
default:
|
||||
printf("Can't fire weapon: %d\n", self->weaponType);
|
||||
printf("Can't fire weapon: %d\n", u->weaponType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int canFire(Entity *target)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ extern void lookForPlayer(void);
|
|||
extern int rrnd(int low, int high);
|
||||
extern float limit(float i, float a, float b);
|
||||
extern int getDistance(int x1, int y1, int x2, int y2);
|
||||
extern int canFire(Entity *target);
|
||||
extern void fireAimedShot(Entity *e);
|
||||
extern void fireMachineGun(Entity *e);
|
||||
extern void fireGrenade(Entity *e);
|
||||
|
|
|
@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "items.h"
|
||||
|
||||
static void throwItem(Entity *e);
|
||||
static void throwItem(Item *i);
|
||||
static int getRandomPlayerWeaponAt(int x, int y);
|
||||
|
||||
static int wpnIconSprite;
|
||||
|
@ -39,13 +39,13 @@ void initItems(void)
|
|||
|
||||
void addRandomWeapon(double x, double y)
|
||||
{
|
||||
Entity *wpn;
|
||||
Item *wpn;
|
||||
int type;
|
||||
|
||||
wpn = malloc(sizeof(Entity));
|
||||
memset(wpn, 0, sizeof(Entity));
|
||||
world.entityTail->next = wpn;
|
||||
world.entityTail = wpn;
|
||||
wpn = malloc(sizeof(Item));
|
||||
memset(wpn, 0, sizeof(Item));
|
||||
world.entityTail->next = (Entity*)wpn;
|
||||
world.entityTail = (Entity*)wpn;
|
||||
|
||||
wpn->x = x;
|
||||
wpn->y = y;
|
||||
|
@ -89,82 +89,82 @@ static int getRandomPlayerWeaponAt(int x, int y)
|
|||
|
||||
void dropRandomCherry(double x, double y)
|
||||
{
|
||||
Entity *e;
|
||||
Item *i;
|
||||
double r;
|
||||
|
||||
e = malloc(sizeof(Entity));
|
||||
memset(e, 0, sizeof(Entity));
|
||||
world.entityTail->next = e;
|
||||
world.entityTail = e;
|
||||
i = malloc(sizeof(Item));
|
||||
memset(i, 0, sizeof(Item));
|
||||
world.entityTail->next = (Entity*)i;
|
||||
world.entityTail = (Entity*)i;
|
||||
|
||||
r = rand() % 100;
|
||||
|
||||
if (r < 1)
|
||||
{
|
||||
STRNCPY(e->name, "bunch of cherries", MAX_NAME_LENGTH);
|
||||
e->value = 10;
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = cherrySprite[2];
|
||||
STRNCPY(i->name, "bunch of cherries", MAX_NAME_LENGTH);
|
||||
i->value = 10;
|
||||
i->sprite[0] = i->sprite[1] = i->sprite[2] = cherrySprite[2];
|
||||
}
|
||||
else if (r < 10)
|
||||
{
|
||||
STRNCPY(e->name, "pair of cherries", MAX_NAME_LENGTH);
|
||||
e->value = 3;
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = cherrySprite[1];
|
||||
STRNCPY(i->name, "pair of cherries", MAX_NAME_LENGTH);
|
||||
i->value = 3;
|
||||
i->sprite[0] = i->sprite[1] = i->sprite[2] = cherrySprite[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
STRNCPY(e->name, "small cherry", MAX_NAME_LENGTH);
|
||||
e->value = 1;
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = cherrySprite[0];
|
||||
STRNCPY(i->name, "small cherry", MAX_NAME_LENGTH);
|
||||
i->value = 1;
|
||||
i->sprite[0] = i->sprite[1] = i->sprite[2] = cherrySprite[0];
|
||||
}
|
||||
|
||||
e->x = x;
|
||||
e->y = y;
|
||||
i->x = x;
|
||||
i->y = y;
|
||||
|
||||
throwItem(e);
|
||||
throwItem(i);
|
||||
}
|
||||
|
||||
void dropBattery(double x, double y)
|
||||
{
|
||||
Entity *e;
|
||||
Item *i;
|
||||
double r;
|
||||
|
||||
e = malloc(sizeof(Entity));
|
||||
memset(e, 0, sizeof(Entity));
|
||||
world.entityTail->next = e;
|
||||
world.entityTail = e;
|
||||
i = malloc(sizeof(Item));
|
||||
memset(i, 0, sizeof(Item));
|
||||
world.entityTail->next = (Entity*)i;
|
||||
world.entityTail = (Entity*)i;
|
||||
|
||||
r = rand() % 100;
|
||||
|
||||
if (r < 1)
|
||||
{
|
||||
STRNCPY(e->name, "full battery", MAX_NAME_LENGTH);
|
||||
e->value = 4;
|
||||
STRNCPY(i->name, "full battery", MAX_NAME_LENGTH);
|
||||
i->value = 4;
|
||||
}
|
||||
else if (r < 10)
|
||||
{
|
||||
STRNCPY(e->name, "battery", MAX_NAME_LENGTH);
|
||||
e->value = 3;
|
||||
STRNCPY(i->name, "battery", MAX_NAME_LENGTH);
|
||||
i->value = 3;
|
||||
}
|
||||
else if (r < 25)
|
||||
{
|
||||
STRNCPY(e->name, "used battery", MAX_NAME_LENGTH);
|
||||
e->value = 2;
|
||||
STRNCPY(i->name, "used battery", MAX_NAME_LENGTH);
|
||||
i->value = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
STRNCPY(e->name, "weak battery", MAX_NAME_LENGTH);
|
||||
e->value = 1;
|
||||
STRNCPY(i->name, "weak battery", MAX_NAME_LENGTH);
|
||||
i->value = 1;
|
||||
}
|
||||
|
||||
e->sprite[0] = e->sprite[1] = e->sprite[2] = batterySprite;
|
||||
e->spriteTime = -1;
|
||||
e->spriteFrame = e->value;
|
||||
i->sprite[0] = i->sprite[1] = i->sprite[2] = batterySprite;
|
||||
i->spriteTime = -1;
|
||||
i->spriteFrame = i->value;
|
||||
|
||||
e->x = x;
|
||||
e->y = y;
|
||||
i->x = x;
|
||||
i->y = y;
|
||||
|
||||
throwItem(e);
|
||||
throwItem(i);
|
||||
}
|
||||
|
||||
void addRandomItems(double x, double y)
|
||||
|
@ -180,8 +180,8 @@ void addRandomItems(double x, double y)
|
|||
}
|
||||
}
|
||||
|
||||
static void throwItem(Entity *e)
|
||||
static void throwItem(Item *i)
|
||||
{
|
||||
e->dx = rrnd(-3, 3);
|
||||
e->dy = rrnd(-7, -5);
|
||||
i->dx = rrnd(-3, 3);
|
||||
i->dy = rrnd(-7, -5);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue