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