Start of entity loading.

This commit is contained in:
Steve 2018-01-29 22:12:18 +00:00
parent 7f237e3c8f
commit d999c14776
53 changed files with 1995 additions and 104 deletions

View File

@ -9,6 +9,7 @@ SEARCHPATH += src/entities/blobs
SEARCHPATH += src/entities/boss
SEARCHPATH += src/entities/cannons
SEARCHPATH += src/entities/decoration
SEARCHPATH += src/entities/evilBlobs
SEARCHPATH += src/entities/items
SEARCHPATH += src/entities/misc
SEARCHPATH += src/entities/structures
@ -27,19 +28,19 @@ vpath %.h $(SEARCHPATH)
DEPS += defs.h structs.h
OBJS += atlas.o atlasTest.o
OBJS += atlas.o atlasTest.o aquaBlob.o
OBJS += battery.o blaze.o bob.o boss.o blobBoss.o
OBJS += camera.o cannon.o cardReader.o cell.o cherry.o combat.o consumable.o
OBJS += debris.o destructable.o door.o draw.o
OBJS += effects.o entities.o exit.o explosions.o eyeDroidCommander.o
OBJS += effects.o entities.o entityFactory.o exit.o explosions.o eyeDroidCommander.o evilBlob.o
OBJS += fleshChunk.o frost.o
OBJS += game.o
OBJS += game.o grenade.o
OBJS += heart.o horizontalDoor.o horizontalLaserTrap.o hub.o hud.o
OBJS += i18n.o init.o infoPoint.o input.o io.o item.o items.o itemPad.o
OBJS += cJSON.o
OBJS += key.o keycard.o
OBJS += laserTrap.o lift.o lookup.o
OBJS += main.o map.o maths.o mia.o
OBJS += laser.o laserTrap.o lift.o lookup.o
OBJS += main.o map.o maths.o mia.o missile.o
OBJS += objectives.o
OBJS += particles.o player.o powerPoint.o powerPool.o pressurePlate.o pushBlock.o
OBJS += quadtree.o

View File

@ -64,7 +64,7 @@ void addExplosion(float x, float y, int radius, Entity *owner)
if (e->type == ET_BOB)
{
stunPlayer();
stunBob();
}
if (e->health <= 0)

View File

@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../common.h"
extern int rrnd(int low, int high);
extern void stunPlayer(void);
extern void stunBob(void);
extern void addExplosionEffect(int x, int y, int dx, int dy);
extern void playSound(int snd, int ch);
extern Entity **getAllEntsWithin(int x, int y, int w, int h, Entity *ignore);

132
src/combat/grenade.c Normal file
View File

@ -0,0 +1,132 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "grenade.h"
static void tick(void);
static void touch(Entity *other);
static float bounce(float x);
static float (*superBounce)(float x);
static void die(void);
static void explode(void);
void initGrenade(Bullet *b)
{
b->flags |= EF_BOUNCES | EF_IGNORE_BULLETS | EF_KILL_OFFSCREEN | EF_FRICTIONLESS | EF_NO_TELEPORT;
superBounce = b->bounce;
b->tick = tick;
b->touch = touch;
b->bounce = bounce;
b->die = die;
}
static void tick(void)
{
Bullet *b;
b = (Bullet*)self;
b->health--;
if (b->x <= 0 || b->y <= 0 || b->x >= (MAP_WIDTH * MAP_TILE_SIZE) - b->w || b->y >= (MAP_HEIGHT * MAP_TILE_SIZE) - b->h)
{
b->alive = ALIVE_DEAD;
}
}
static void touch(Entity *other)
{
Bullet *b;
b = (Bullet*)self;
if (b->alive == ALIVE_ALIVE)
{
/* don't bounce too high */
if (b->dy < -8)
{
b->dy = -8;
}
if (other != b->owner)
{
if (other != NULL && (!(other->flags & EF_IGNORE_BULLETS)) && !other->isSolid && b->owner->type != other->type && other->type != ET_LIFT)
{
if (other->flags & EF_EXPLODES)
{
addSparkParticles(b->x, b->y);
}
else
{
addSmallFleshChunk(b->x, b->y);
}
if (b->owner->type == world.bob->type)
{
game.statShotsHit[WPN_GRENADES]++;
}
if (!(other->flags & EF_BOMB_SHIELD))
{
other->applyDamage(25);
}
explode();
}
}
}
}
static float bounce(float x)
{
Bullet *b;
b = (Bullet*)self;
if (b->environment == ENV_AIR)
{
playSound(SND_GRENADE_BOUNCE, CH_EFFECTS);
}
return superBounce(x);
}
static void die(void)
{
explode();
}
static void explode(void)
{
Bullet *b;
int mx, my;
b = (Bullet*)self;
addExplosion(b->x, b->y, 100, b->owner);
b->alive = ALIVE_DEAD;
mx = (int) ((b->x + (b->w / 2)) / MAP_TILE_SIZE);
my = (int) (b->y / MAP_TILE_SIZE) + 1;
addScorchDecal(mx, my);
}

32
src/combat/grenade.h Normal file
View File

@ -0,0 +1,32 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../common.h"
extern void playSound(int snd, int ch);
extern void initGrenade(Bullet *b);
extern void addSmallFleshChunk(float x, float y);
extern void addSparkParticles(float x, float y);
extern void addExplosion(float x, float y, int radius, Entity *owner);
extern void addScorchDecal(int x, int y);
extern Entity *self;
extern Game game;
extern World world;

87
src/combat/laser.c Normal file
View File

@ -0,0 +1,87 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "laser.h"
static void tick(void);
static void touch(Entity *other);
void initLaser(Bullet *b)
{
b->flags |= EF_WEIGHTLESS | EF_BOUNCES | EF_FRICTIONLESS | EF_NO_ENVIRONMENT | EF_IGNORE_BULLETS | EF_KILL_OFFSCREEN | EF_NO_TELEPORT;
b->tick = tick;
b->touch = touch;
}
static void tick(void)
{
Bullet *b;
b = (Bullet*)self;
b->health--;
if (b->x <= 0 || b->y <= 0 || b->x >= (MAP_WIDTH * MAP_TILE_SIZE) - b->w || b->y >= (MAP_HEIGHT * MAP_TILE_SIZE) - b->h)
{
b->alive = ALIVE_DEAD;
}
}
static void touch(Entity *other)
{
Bullet *b;
b = (Bullet*)self;
if (b->alive == ALIVE_ALIVE)
{
if (other != b->owner)
{
if (other != NULL && (!(other->flags & EF_IGNORE_BULLETS)) && b->owner->type != other->type)
{
if (other->flags & EF_EXPLODES)
{
addSparkParticles(b->x, b->y);
playSound(SND_METAL_HIT, CH_ANY);
}
else
{
addSmallFleshChunk(b->x, b->y);
playSound(SND_FLESH_HIT, CH_ANY);
}
other->applyDamage(2);
if (b->owner->type == world.bob->type)
{
game.statShotsHit[WPN_LASER]++;
}
if (other->type == ET_BOB && !world.bob->stunTimer > 0)
{
other->dx = rrnd(-8, 8);
other->dy = rrnd(-12, 0);
stunBob();
}
}
}
}
}

32
src/combat/laser.h Normal file
View File

@ -0,0 +1,32 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../common.h"
extern void playSound(int snd, int ch);
extern int rrnd(int low, int high);
extern void initLaser(Bullet *b);
extern void addSmallFleshChunk(float x, float y);
extern void addSparkParticles(float x, float y);
extern void stunBob(void);
extern Entity *self;
extern Game game;
extern World world;

71
src/combat/missile.c Normal file
View File

@ -0,0 +1,71 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "missile.h"
static void tick(void);
static void touch(Entity *other);
void initMissile(Bullet *b)
{
b->flags |= EF_WEIGHTLESS | EF_NO_ENVIRONMENT | EF_IGNORE_BULLETS | EF_KILL_OFFSCREEN | EF_NO_TELEPORT;
b->tick = tick;
b->touch = touch;
}
static void tick(void)
{
Bullet *b;
b = (Bullet*)self;
b->health--;
if (b->x <= 0 || b->y <= 0 || b->x >= (MAP_WIDTH * MAP_TILE_SIZE) - b->w || b->y >= (MAP_HEIGHT * MAP_TILE_SIZE) - b->h)
{
b->alive = ALIVE_DEAD;
}
if (b->health % 2)
{
addFlameParticles(b->x + (b->facing * 35) + rrnd(-1, 1), b->y);
}
}
static void touch(Entity *other)
{
Bullet *b;
b = (Bullet*)self;
if (other == NULL)
{
addExplosion(b->x, b->y, 65, b->owner);
b->alive = ALIVE_DEAD;
}
else if (other != b->owner && (!(other->flags & EF_IGNORE_BULLETS)) && b->owner->type != other->type)
{
addExplosion(b->x, b->y, 65, b->owner);
b->alive = ALIVE_DEAD;
}
}

28
src/combat/missile.h Normal file
View File

@ -0,0 +1,28 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../common.h"
extern int rrnd(int low, int high);
extern void initMissile(Bullet *b);
extern void addExplosion(float x, float y, int radius, Entity *owner);
extern void addFlameParticles(float x, float y);
extern Entity *self;

View File

@ -33,6 +33,9 @@ static int alienGrenadeSprite;
static int shotgunPelletSprite;
static int missileSprite[2];
static void tick(void);
static void touch(Entity *other);
void initWeapons(void)
{
bulletSprite[0] = getSpriteIndex("BulletRight");
@ -160,6 +163,8 @@ void fireLaser(Unit *owner)
laser->health = FPS * 3;
laser->sprite[0] = laser->sprite[1] = (owner->type == ET_BOB) ? laserSprite[0] : laserSprite[1];
initLaser(laser);
owner->reload = owner->type == ET_BOB ? FPS / 2 : FPS;
playSound(SND_LASER, owner->type == ET_BOB ? CH_PLAYER : CH_WEAPON);
@ -176,9 +181,10 @@ void fireGrenade(Unit *owner)
grenade->health = FPS * 3;
grenade->dx = owner->facing == FACING_RIGHT ? 8 : -8;
grenade->sprite[0] = grenade->sprite[1] = (owner->type == ET_BOB) ? grenadeSprite : alienGrenadeSprite;
grenade->dy = -6;
initGrenade(grenade);
owner->reload = FPS / 2;
playSound(SND_THROW, owner->type == ET_BOB ? CH_PLAYER : CH_WEAPON);
@ -222,6 +228,8 @@ void fireMissile(Unit *owner)
missile->sprite[0] = missileSprite[0];
missile->sprite[1] = missileSprite[1];
initMissile(missile);
owner->reload = FPS / 2;
playSound(SND_MISSILE, CH_WEAPON);
@ -236,6 +244,8 @@ Bullet *createBaseBullet(Unit *owner)
world.entityTail->next = (Entity*)bullet;
world.entityTail = (Entity*)bullet;
initEntity((Entity*)bullet);
bullet->x = (owner->x + owner->w / 2);
bullet->y = (owner->y + owner->h / 2) - 3;
bullet->dx = owner->facing == FACING_RIGHT ? 15 : -15;
@ -245,9 +255,86 @@ Bullet *createBaseBullet(Unit *owner)
bullet->health = FPS * 3;
bullet->flags |= EF_WEIGHTLESS | EF_IGNORE_BULLETS | EF_NO_ENVIRONMENT | EF_KILL_OFFSCREEN | EF_NO_TELEPORT;
bullet->tick = tick;
bullet->touch = touch;
return bullet;
}
static void tick(void)
{
Bullet *b;
b = (Bullet*)self;
b->health--;
if (b->x <= 0 || b->y <= 0 || b->x >= (MAP_WIDTH * MAP_TILE_SIZE) - b->w || b->y >= (MAP_HEIGHT * MAP_TILE_SIZE) - b->h)
{
b->alive = ALIVE_DEAD;
}
// don't allow the player to kill everything on the map by firing
// constantly
if (b->owner->type == ET_BOB)
{
if (b->x < camera.x || b->y < camera.y || b->x > camera.x + SCREEN_WIDTH || b->y > camera.y + SCREEN_HEIGHT)
{
b->alive = ALIVE_DEAD;
}
}
}
static void touch(Entity *other)
{
Bullet *b;
b = (Bullet*)self;
if (b->alive == ALIVE_ALIVE)
{
if (other == NULL)
{
addSparkParticles(b->x, b->y);
b->alive = ALIVE_DEAD;
if (rand() % 2)
{
playSound(SND_RICO_1, CH_ANY);
}
else
{
playSound(SND_RICO_2, CH_ANY);
}
}
else if (other != b->owner && (!(other->flags & EF_IGNORE_BULLETS)) && b->owner->type != other->type)
{
other->applyDamage(b->damage);
if (other->flags & EF_EXPLODES)
{
playSound(SND_METAL_HIT, CH_ANY);
addSparkParticles(b->x, b->y);
}
else
{
playSound(SND_FLESH_HIT, CH_ANY);
addSmallFleshChunk(b->x, b->y);
}
b->alive = ALIVE_DEAD;
if (b->owner->type == world.bob->type)
{
game.statShotsHit[b->weaponType]++;
}
}
}
}
int getRandomPlayerWeapon(int excludeGrenades)
{
if (excludeGrenades)

View File

@ -24,5 +24,14 @@ extern int getSpriteIndex(char *name);
extern void playSound(int snd, int ch);
extern int rrnd(int low, int high);
extern void getSlope(int x1, int y1, int x2, int y2, float *dx, float *dy);
extern void initLaser(Bullet *b);
extern void initGrenade(Bullet *b);
extern void initMissile(Bullet *b);
extern void initEntity(Entity *e);
extern void addSmallFleshChunk(float x, float y);
extern void addSparkParticles(float x, float y);
extern Camera camera;
extern Entity *self;
extern Game game;
extern World world;

View File

@ -20,9 +20,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "bob.h"
void initBob(Entity *e)
void initBob(void)
{
e->type = ET_BOB;
Unit *u;
u = createUnit();
u->type = ET_BOB;
}
void addBobItem(Item *i)

View File

@ -19,3 +19,5 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../../common.h"
extern Unit *createUnit(void);

View File

@ -26,13 +26,12 @@ static void touch(Entity *other);
static void preTeleport(void);
static void teleport(void);
void initMIA(Entity *e)
void initMIA(void)
{
MIA *m;
initUnit(e);
m = (MIA*)e;
m = malloc(sizeof(MIA));
memset(m, 0, sizeof(MIA));
m->type = ET_MIA;

View File

@ -28,7 +28,6 @@ extern void setGameplayMessage(int type, char *format, ...);
extern void playSound(int snd, int ch);
extern void updateObjective(char *targetName);
extern void addRescuedMIA(char *name);
extern void initUnit(Entity *e);
extern Entity *self;
extern World world;

View File

@ -29,13 +29,11 @@ static Entity *target;
static int aimedSprite;
static int exitMission;
void initTeeka(Entity *e)
void initTeeka(void)
{
Unit *u;
initUnit(e);
u = (Unit*)e;
u = createUnit();
u->type = ET_TEEKA;
@ -49,7 +47,7 @@ void initTeeka(Entity *e)
u->sprite[FACING_RIGHT] = getSpriteIndex("TeekaRight");
u->sprite[FACING_DIE] = getSpriteIndex("TeekaLeft");
u->health = e->healthMax = 9999;
u->health = u->healthMax = 9999;
u->tick = tick;

View File

@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../../common.h"
extern void initUnit(Entity *e);
extern Unit *createUnit(void);
extern void unitTick(void);
extern int getSpriteIndex(char *name);
extern int rrnd(int low, int high);

View File

@ -28,13 +28,11 @@ static SDL_Rect *getBounds(void);
static int canFire(Entity *target);
static void preFire(void);
void initCannon(Entity *e)
void initCannon(void)
{
Unit *u;
initUnit(e);
u = (Unit*)self;
u = createUnit();
u->type = ET_ENEMY;

View File

@ -20,7 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../../common.h"
extern void initUnit(Entity *e);
extern void addExplosion(float x, float y, int radius, Entity *owner);
extern int rrnd(int low, int high);
extern int getSpriteIndex(char *name);
@ -30,6 +29,7 @@ extern void updateObjective(char *targetName);
extern void fireTriggers(char *targetName);
extern void dropCarriedItem(void);
extern void addScorchDecal(int x, int y);
extern Unit *createUnit(void);
extern Dev dev;
extern Entity *self;

View File

@ -25,75 +25,10 @@ static void applyDamage(int damage);
static float bounce(float x);
static SDL_Rect *getBounds(void);
Entity *createEntity(int type)
{
Entity *e;
switch (type)
{
case ET_BOB:
e = malloc(sizeof(Bob));
memset(e, 0, sizeof(Bob));
break;
case ET_ENEMY:
case ET_TEEKA:
e = malloc(sizeof(Unit));
memset(e, 0, sizeof(Unit));
break;
case ET_BOSS:
e = malloc(sizeof(Boss));
memset(e, 0, sizeof(Boss));
break;
case ET_HEART_CELL:
case ET_KEY:
case ET_ITEM:
case ET_CONSUMABLE:
e = malloc(sizeof(Item));
memset(e, 0, sizeof(Item));
break;
case ET_MIA:
e = malloc(sizeof(MIA));
memset(e, 0, sizeof(MIA));
break;
case ET_DECORATION:
e = malloc(sizeof(Decoration));
memset(e, 0, sizeof(Decoration));
break;
case ET_DOOR:
case ET_LIFT:
case ET_PUSHBLOCK:
case ET_DESTRUCTABLE:
case ET_POWER_POINT:
case ET_CARD_READER:
case ET_PRESSURE_PLATE:
case ET_TELEPORTER:
case ET_ITEM_PAD:
case ET_POOL:
case ET_TRAP:
case ET_EXIT:
case ET_INFO_POINT:
e = malloc(sizeof(Structure));
memset(e, 0, sizeof(Structure));
break;
}
world.entityTail->next = e;
world.entityTail = e;
e->type = type;
e->uniqueId = world.entityCounter++;
return e;
}
void initEntity(Entity *e)
{
e->uniqueId = world.entityCounter++;
e->sprite[0] = e->sprite[1] = e->sprite[2] = -1;
e->environment = ENV_AIR;
@ -116,6 +51,9 @@ void initEntity(Entity *e)
e->applyDamage = applyDamage;
e->bounce = bounce;
e->getBounds = getBounds;
world.entityTail->next = e;
world.entityTail = e;
}
static SDL_Rect *getBounds(void)

View File

@ -23,5 +23,4 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern void addTeleportStars(Entity *e);
extern Entity *self;
extern Game game;
extern World world;

View File

@ -0,0 +1,68 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "entityFactory.h"
static void addEntityDef(char *name, int type, Entity *(*initFunc)(void));
static EntityDef head;
static EntityDef *tail;
void initEntityFactory(void)
{
memset(&head, 0, sizeof(EntityDef));
tail = &head;
addEntityDef("AquaBlob", ET_ENEMY, initAquaBlob);
addEntityDef("Bob", ET_BOB, initBob);
}
Entity *createEntity(char *name)
{
EntityDef *def;
for (def = head.next ; def != NULL ; def = def->next)
{
if (strcmp(def->name, name) == 0)
{
return def->initFunc();
}
}
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "No such entity definition '%s'", name);
exit(1);
return NULL;
}
static void addEntityDef(char *name, int type, Entity *(*initFunc)(void))
{
EntityDef *def;
def = malloc(sizeof(EntityDef));
memset(def, 0, sizeof(EntityDef));
tail->next = def;
tail = def;
STRNCPY(def->name, name, MAX_NAME_LENGTH);
def->type = type;
def->initFunc = initFunc;
}

View File

@ -0,0 +1,24 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../common.h"
extern Entity *initAquaBlob(void);
extern Entity *initBob(void);

View File

@ -0,0 +1,49 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "aquaBlob.h"
static int canFire(Entity *target);
void initAquaBlob(void)
{
Unit *u;
u = createUnit();
initEvilBlob(u);
u->sprite[FACING_LEFT] = getSpriteIndex("AquaBlobLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("AquaBlobRight");
u->sprite[FACING_DIE] = getSpriteIndex("AquaBlobSpin");
u->weaponType = WPN_AIMED_PISTOL;
u->flags |= EF_SWIMS | EF_WATER_BREATHING;
u->maxShotsToFire = 3;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return 1;
}

View File

@ -0,0 +1,25 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../../common.h"
extern Unit *createUnit(void);
extern void initEvilBlob(Unit *u);
extern int getSpriteIndex(char *name);

View File

@ -0,0 +1,311 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "evilBlob.h"
static void (*superAnimate)(void);
static void die(void);
static void die2(void);
static void returnToStart(void);
static void lookForPlayer(void);
static void walk(void);
static void animate(void);
void initEvilBlob(Unit *u)
{
u->reload = 0;
u->returnToStartTimer = 0;
u->flags |= EF_HALT_AT_EDGE;
superAnimate = u->animate;
u->walk = walk;
u->animate = animate;
u->die = die;
}
static void die2(void)
{
Unit *u;
int mx, my;
u = (Unit*)self;
u->health--;
/* burst on impact, due to speed */
if (u->dy > 15)
{
u->health = -FPS;
}
if (u->health <= -FPS && (u->isOnGround || u->environment != ENV_AIR))
{
dropCarriedItem();
u->alive = ALIVE_DEAD;
throwFleshChunks(u->x + u->w / 2, u->y + u->h / 2, rrnd(3, 6));
if (rand() % 10 < 3)
{
addRandomWeapon(u->x, u->y);
}
addRandomItems(u->x, u->y);
updateObjective(u->name);
updateObjective("ENEMY");
fireTriggers(u->name);
if (u->isMissionTarget)
{
addDefeatedTarget(u->name);
}
game.enemiesKilled++;
mx = (int) ((u->x + (u->w / 2)) / MAP_TILE_SIZE);
my = (int) (u->y / MAP_TILE_SIZE) + 1;
addBloodDecal(mx, my);
playSound(SND_SPLAT, CH_ANY);
}
}
static void moveTowardsPlayer(void)
{
Unit *u;
u = (Unit*)self;
if (world.bob->x < u->x)
{
u->dx = -2;
u->facing = FACING_LEFT;
}
else if (world.bob->x > u->x)
{
u->dx = 2;
u->facing = FACING_RIGHT;
}
if (u->flags & EF_SWIMS)
{
u->dx = limit(u->dx, -1, 1);
if (world.bob->y < u->y)
{
u->dy = -1;
}
else
{
u->dy = 1;
}
}
}
static void patrol(void)
{
Unit *u;
u = (Unit*)self;
if (u->returnToStartTimer > 0)
{
returnToStart();
return;
}
if (!u->spawnedIn && rand() % 100 < 25)
{
u->returnToStartTimer = FPS * 3;
}
u->facing = rand() % 100 < 50 ? FACING_LEFT : FACING_RIGHT;
u->dx = rrnd(-1, 1);
u->thinkTime = rrnd(FPS / 2, FPS);
if (u->dx == -1)
{
u->facing = FACING_LEFT;
}
else if (u->dx == 1)
{
u->facing = FACING_RIGHT;
}
if (u->flags & EF_SWIMS)
{
u->dy = rrnd(-1, 1);
}
}
static void returnToStart(void)
{
Unit *u;
u = (Unit*)self;
u->returnToStartTimer--;
u->thinkTime = 10;
/* jump up if your start is above you */
if (u->startY - u->y < -64 && u->isOnGround && u->dx == 0)
{
u->dy = JUMP_POWER;
u->isOnGround = 0;
}
u->facing = u->startX < u->x ? FACING_LEFT : FACING_RIGHT;
u->dx = u->facing == FACING_LEFT ? -1 : 1;
if (!u->isOnGround)
{
u->thinkTime = 0;
u->returnToStartTimer = MAX(u->returnToStartTimer, FPS);
u->dx *= 2;
}
if (u->flags & EF_SWIMS)
{
u->dy = u->startY < u->y ? -1 : -1;
}
if (abs(u->startX - u->x) <= MAP_TILE_SIZE)
{
u->returnToStartTimer = 0;
}
}
static void lookForPlayer(void)
{
Unit *u;
float r;
u = (Unit*)self;
u->thinkTime = (int) rrnd(FPS / 2, FPS);
if (world.state != WS_IN_PROGRESS || dev.cheatBlind)
{
patrol();
return;
}
if ((u->facing == FACING_LEFT && world.bob->x > u->x) || (u->facing == FACING_RIGHT && world.bob->x < u->x))
{
patrol();
return;
}
if (getDistance(world.bob->x, world.bob->y, u->x, u->y) > 650)
{
patrol();
return;
}
if (!enemyCanSeePlayer(self))
{
patrol();
return;
}
r = randF();
if (u->isMissionTarget)
{
r = randF() * 0.3;
}
if (r < 0.125)
{
moveTowardsPlayer();
u->shotsToFire = rrnd(1, u->maxShotsToFire);
u->action = u->preFire;
}
else if (r < 0.25)
{
u->dx = 0;
u->shotsToFire = rrnd(1, u->maxShotsToFire);
u->action = u->preFire;
}
else if (r < 0.5)
{
u->dx = 0;
}
else
{
moveTowardsPlayer();
}
}
static void walk(void)
{
self->action = lookForPlayer;
}
static void die(void)
{
Unit *u;
u = (Unit*)self;
u->flags |= EF_BOUNCES | EF_ALWAYS_PROCESS;
u->action = die2;
u->thinkTime = 0;
u->spriteTime = 0;
u->spriteFrame = 0;
if (u->environment == ENV_AIR)
{
u->dy = -9;
}
u->dx = (randF() - randF()) * 5;
u->flags &= ~EF_HALT_AT_EDGE;
switch (rand() % 3)
{
case 0:
playSound(SND_DEATH_1, CH_DEATH);
break;
case 1:
playSound(SND_DEATH_2, CH_DEATH);
break;
case 2:
playSound(SND_DEATH_3, CH_DEATH);
break;
}
}
static void animate(void)
{
if (self->dx != 0 || self->health <= 0)
{
superAnimate();
}
}

View File

@ -0,0 +1,41 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../../common.h"
extern void dropCarriedItem(void);
extern int getDistance(int x1, int y1, int x2, int y2);
extern double randF(void);
extern void throwFleshChunks(double x, double y, int amount);
extern void addRandomWeapon(double x, double y);
extern float limit(float i, float a, float b);
extern void playSound(int snd, int ch);
extern void addBloodDecal(int x, int y);
extern void updateObjective(char *targetName);
extern int enemyCanSeePlayer(Entity *e);
extern void addDefeatedTarget(char *name);
extern void fireTriggers(char *name);
extern void addRandomItems(float x, float y);
extern int rrnd(int low, int high);
extern Dev dev;
extern Entity *self;
extern Game game;
extern World world;

View File

@ -0,0 +1,60 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "grenadeBlob.h"
static void preFire2(void);
static int canFire(Entity *target);
void initGrenadeBlob(Unit *u)
{
initEvilBlob(u);
u->sprite[FACING_LEFT] = getSpriteIndex("GrenadeBlobLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("GrenadeBlobRight");
u->sprite[FACING_DIE] = getSpriteIndex("GrenadeBlobSpin");
u->weaponType = WPN_GRENADES;
u->preFire = preFire2;
u->canFire = canFire;
}
static void preFire2(void)
{
preFire(this);
if (u->shotsToFire == 0)
{
if (rand() % 100 < 25)
{
u->weaponType = WPN_AIMED_PISTOL;
}
else
{
u->weaponType = WPN_GRENADES;
}
}
}
static int canFire(Entity *target)
{
return abs(target->y - self->y) <= MAP_TILE_SIZE * 2;
}

View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "laserBlob.h"
static int canFire(Entity *target);
void initLaserBlob(Unit *u)
{
initEvilBlob(u);
u->sprite[FACING_LEFT] = getSpriteIndex("LaserBlobLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("LaserBlobRight");
u->sprite[FACING_DIE] = getSpriteIndex("LaserBlobSpin");
u->weaponType = WPN_LASER;
u->maxShotsToFire = 1;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return abs(target->y - self->y) <= MAP_TILE_SIZE * 2;
}

View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "machineGunBlob.h"
static int canFire(Entity *target);
void initMachineGunBlob(Unit *u)
{
initEvilBlob(u);
u->sprite[FACING_LEFT] = getSpriteIndex("MachineGunBlobLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("MachineGunBlobRight");
u->sprite[FACING_DIE] = getSpriteIndex("MachineGunBlobSpin");
u->weaponType = WPN_MACHINE_GUN;
u->maxShotsToFire = 5;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return abs(target->y - self->y) <= MAP_TILE_SIZE * 2;
}

View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "pistolBlob.h"
static int canFire(Entity *target);
void initPistolBlob(Unit *u)
{
initEvilBlob(u);
u->sprite[FACING_LEFT] = getSpriteIndex("PistolBlobLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("PistolBlobRight");
u->sprite[FACING_DIE] = getSpriteIndex("PistolBlobSpin");
u->weaponType = WPN_AIMED_PISTOL;
u->maxShotsToFire = 3;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return true;
}

View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "plasmaBlob.h"
static int canFire(Entity *target);
void initPlasmaBlob(Unit *u)
{
initEvilBlob(u);
u->sprite[FACING_LEFT] = getSpriteIndex("PlasmaBlobLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("PlasmaBlobRight");
u->sprite[FACING_DIE] = getSpriteIndex("PlasmaBlobSpin");
u->weaponType = WPN_PLASMA;
u->maxShotsToFire = 6;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return abs(target->y - self->y) <= MAP_TILE_SIZE * 2;
}

View File

@ -0,0 +1,44 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "shotgunBlob.h"
static int canFire(Entity *target);
void initShotgunBlob(Unit *u)
{
initEvilBlob(u);
u->sprite[FACING_LEFT] = getSpriteIndex("ShotgunBlobLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("ShotgunBlobRight");
u->sprite[FACING_DIE] = getSpriteIndex("ShotgunBlobSpin");
u->weaponType = WPN_SHOTGUN;
u->maxShotsToFire = 2;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return true;
}

View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "spreadGunBlob.h"
static int canFire(Entity *target);
void initSpreadGunBlob(Unit *u)
{
initEvilBlob(u);
u->sprite[FACING_LEFT] = getSpriteIndex("SpreadGunBlobLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("SpreadGunBlobRight");
u->sprite[FACING_DIE] = getSpriteIndex("SpreadGunBlobSpin");
u->weaponType = WPN_SPREAD;
u->maxShotsToFire = 3;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return abs(target->y - u->y) <= MAP_TILE_SIZE * 5;
}

View File

@ -0,0 +1,243 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "eyeDroid.h"
static void tick(void);
static void superTick(void);
static void touch(void);
static void superTouch(void);
void initEyeDroid(void)
{
u->flags |= FL_WEIGHTLESS | FL_HALT_AT_EDGE | FL_EXPLODES;
superTick = u->tick;
superTouch = u->touch;
u->tick = tick;
u->touch = touch;
}
static void tick(void)
{
Unit *u;
u = (Unit*)self;
superTick();
if (u->alive == ALIVE_DYING)
{
addSmokeParticles(u->x + (u->w / 2), u->y);
}
}
static void touch(Entity *other)
{
Unit *u;
int mx, my;
u = (Unit*)self;
superTouch();
if (u->alive == ALIVE_DYING && (other == NULL || other->isSolid))
{
dropCarriedItem();
u->alive = ALIVE_DEAD;
addExplosion(u->x, u->y, 80, self);
throwDebris(u->x + u->w / 2, u->y + u->h / 2, rrnd(3, 5));
if (rand() % 100 < 30)
{
addRandomWeapon(u->x, u->y);
}
addRandomItems((int) u->x, (int) u->y);
updateObjectives();
if (u->isMissionTarget)
{
addDefeatedTarget(u->name);
}
game.enemiesKilled++;
mx = (int) ((u->x + (u->w / 2)) / MAP_TILE_SIZE);
my = (int) ((u->y + u->h) / MAP_TILE_SIZE) + 1;
addScorchDecal(mx, my);
}
}
static void unitDie(void)
{
if (self->environment != Environment.AIR)
{
touch(NULL);
}
}
static void die(void)
{
Unit *u;
u = (Unit*)self;
u->dx = (fRand() - fRand()) * 3;
u->spriteTime = 0;
u->spriteFrame = 0;
u->action = unitDie;
u->thinkTime = 0;
u->flags |= EF_ALWAYS_PROCESS;
u->flags &= ~(EF_WEIGHTLESS | EF_HALT_AT_EDGE);
u->dy = JUMP_POWER;
if (rand() % 2)
{
playSound(SND_DROID_DIE_1, CH_DEATH);
}
else
{
playSound(SND_DROID_DIE_2, CH_DEATH);
}
}
static void chase(void)
{
Unit *u;
u = (Unit*)self;
u->dx = world.bob->x - u->x;
u->dy = world.bob->y - u->y;
u->dx = limit(u->dx, -1, 1);
u->dy = limit(u->dy, -1, 1);
u->thinkTime = (int) rrnd(FPS / 2, FPS);
u->facing = (u->dx >= 0) ? FACING_RIGHT : FACING_LEFT;
}
static void patrol(void)
{
Unit *u;
u = (Unit*)self;
switch (rand() % 3)
{
case 0:
u->dx = 0;
u->facing = rand() % 2 ? FACING_LEFT : FACING_RIGHT;
u->thinkTime = rrnd(FPS / 2, FPS);
break;
case 1:
u->dx = rrnd(-100, 100);
u->dy = rrnd(-100, 100);
u->dx *= 0.01;
u->dy *= 0.01;
u->thinkTime = rrnd(FPS / 2, FPS);
u->facing = (u->dx >= 0) ? FACING_RIGHT : FACING_LEFT;
break;
case 2:
u->dx = 0;
u->thinkTime = rrnd(FPS / 2, FPS);
break;
}
}
static void lookForPlayer(void)
{
Unit *u;
double distance, r;
u = (Unit*)self;
u->dx *= 0.5;
u->dy *= 0.5;
u->thinkTime = rrnd(FPS / 2, FPS);
if (world.state != WS_IN_PROGRESS || game.cheatBlind)
{
patrol();
return;
}
distance = getDistance(world.bob->x, world.bob->y, u->x, u->y);
if (distance > 650)
{
patrol();
return;
}
if (!enemyCanSeePlayer(self))
{
patrol();
return;
}
r = fRand();
if (u->isMissionTarget)
{
r = fRand() * 0.3;
}
if (r < 0.125)
{
chase();
u->shotsToFire = rrnd(1, u->maxShotsToFire);
u->action = preFire;
}
else if (r < 0.25)
{
u->dx = 0;
u->shotsToFire = rrnd(1, u->maxShotsToFire);
u->action = preFire;
}
else if (r < 0.5)
{
u->dx = 0;
}
else
{
chase();
}
u->thinkTime = rrnd(FPS / 2, FPS);
}
static void walk(void)
{
self->action = lookForPlayer;
}

View File

@ -0,0 +1,64 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "grenadeDroid.h"
static void preFire2(void);
static int canFire(Entity *target);
void initGrenadeDroid(Unit *u)
{
initEyeDroid(u);
u->sprite[FACING_LEFT] = getSpriteIndex("GrenadeDroidLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("GrenadeDroidRight");
u->sprite[FACING_DIE] = getSpriteIndex("GrenadeDroidDie");
u->weaponType = WPN_GRENADES;
u->preFire = preFire2;
u->canFire = canFire;
}
static void preFire2(void)
{
Unit *u;
u = (Unit*)self;
preFire(self);
if (u->shotsToFire == 0)
{
if (rand() % 100 < 25)
{
u->weaponType = WPN_AIMED_PISTOL;
}
else
{
u->weaponType = WPN_GRENADES;
}
}
}
static int canFire(Entity *target)
{
return abs(target->y - y) <= MAP_TILE_SIZE * 2;
}

View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "laserDroid.h"
static int canFire(Entity *target);
void initLaserDroid(Unit *u)
{
initEyeDroid(u);
u->sprite[FACING_LEFT] = getSpriteIndex("LaserDroidLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("LaserDroidRight");
u->sprite[FACING_DIE] = getSpriteIndex("LaserDroidDie");
u->weaponType = WPN_LASER;
u->maxShotsToFire = 1;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return abs(target->y - self->y) <= MAP_TILE_SIZE * 2;
}

View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "machineGunDroid.h"
static int canFire(Entity *target);
void initMachineGunDroid(Unit *u)
{
initEyeDroid(u);
u->sprite[FACING_LEFT] = getSpriteIndex("MachineGunDroidLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("MachineGunDroidRight");
u->sprite[FACING_DIE] = getSpriteIndex("MachineGunDroidDie");
u->weaponType = WPN_MACHINE_GUN;
u->maxShotsToFire = 5;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return abs(target->y - self->y) <= MAP_TILE_SIZE * 2;
}

View File

@ -0,0 +1,41 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "pistolDroid.h"
static int canFire(Entity *target);
void initPistolDroid(Unit *u)
{
u->sprite[FACING_LEFT] = getSpriteIndex("PistolDroidLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("PistolDroidRight");
u->sprite[FACING_DIE] = getSpriteIndex("PistolDroidDie");
u->weaponType = WPN_AIMED_PISTOL;
u->maxShotsToFire = 3;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return true;
}

View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "plasmaDroid.h"
static int canFire(Entity *target);
void initPlasmaDroid(Unit *u)
{
initEyeDroid(u);
u->sprite[FACING_LEFT] = getSpriteIndex("PlasmaDroidLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("PlasmaDroidRight");
u->sprite[FACING_DIE] = getSpriteIndex("PlasmaDroidDie");
u->weaponType = WPN_PLASMA;
u->maxShotsToFire = 6;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return abs(target->y - self->y) <= MAP_TILE_SIZE * 2;
}

View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "shotgunDroid.h"
static int canFire(Entity *target);
void initShotgunDroid(Unit *u)
{
initEyeDroid(u);
u->sprite[FACING_LEFT] = getSpriteIndex("ShotgunDroidLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("ShotgunDroidRight");
u->sprite[FACING_DIE] = getSpriteIndex("ShotgunDroidDie");
u->weaponType = WPN_SHOTGUN;
u->maxShotsToFire = 2;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return true;
}

View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2018 Parallel Realities
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "spreadGunDroid.h"
static int canFire(Entity *target);
void initSpreadGunDroid(Unit *u)
{
initEyeDroid(u);
u->sprite[FACING_LEFT] = getSpriteIndex("SpreadGunDroidLeft");
u->sprite[FACING_RIGHT] = getSpriteIndex("SpreadGunDroidRight");
u->sprite[FACING_DIE] = getSpriteIndex("SpreadGunDroidDie");
u->weaponType = WPN_SPREAD;
u->maxShotsToFire = 3;
u->canFire = canFire;
}
static int canFire(Entity *target)
{
return abs(target->y - self->y) <= MAP_TILE_SIZE * 5;
}

View File

@ -130,7 +130,7 @@ static void touch(Entity *other)
if (other == (Entity*)world.bob && world.bob->stunTimer == 0)
{
stunPlayer();
stunBob();
}
}

View File

@ -26,7 +26,7 @@ extern int isOnScreen(Entity *e);
extern void setGameplayMessage(int type, char *format, ...);
extern int getSpriteIndex(char *name);
extern int rrnd(int low, int high);
extern void stunPlayer(void);
extern void stunBob(void);
extern void addSparkParticles(float x, float y);
extern void addSmallFleshChunk(float x, float y);

View File

@ -23,14 +23,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
void unitTick(void);
static void attack(void);
static int canFire(Entity *target);
static void preFire(void);
void initUnit(Entity *e)
Unit *createUnit(void)
{
Unit *u;
initEntity(e);
u = malloc(sizeof(Unit));
memset(u, 0, sizeof(Unit));
world.entityTail->next = (Entity*)u;
world.entityTail = (Entity*)u;
u = (Unit*)e;
initEntity((Entity*)u);
u->oxygen = MAX_OXYGEN;
@ -48,8 +52,11 @@ void initUnit(Entity *e)
u->tick = unitTick;
u->action = lookForPlayer;
u->preFire = preFire;
u->attack = attack;
u->canFire = canFire;
return u;
}
void reInitUnit(Entity *e)
@ -177,6 +184,37 @@ static void attack(void)
}
}
static void preFire(void)
{
Unit *u;
u = (Unit*)self;
if (!(u->flags & EF_WEIGHTLESS))
{
if (world.bob->y < u->y && u->isOnGround && rand() % 4 == 0)
{
u->dy = JUMP_POWER;
}
}
u->facing = (world.bob->x < u->x) ? FACING_LEFT : FACING_RIGHT;
if (u->reload > 0)
{
return;
}
u->attack();
u->shotsToFire--;
if (u->shotsToFire == 0)
{
u->walk();
}
}
static int canFire(Entity *target)
{
return 0;

View File

@ -31,6 +31,7 @@ typedef struct HubMission HubMission;
typedef struct Widget Widget;
typedef struct Atlas Atlas;
typedef struct Bucket Bucket;
typedef struct EntityDef EntityDef;
typedef struct Entity Entity;
typedef struct EntityExt EntityExt;
@ -92,6 +93,13 @@ struct Lookup {
Lookup *next;
};
struct EntityDef {
char name[MAX_NAME_LENGTH];
int type;
Entity *(*initFunc)(void);
EntityDef *next;
};
typedef struct {
void (*logic)(void);
void (*draw)(void);
@ -160,7 +168,9 @@ struct Unit {
int spawnedInTimer;
int oxygen;
int spawnedIn;
int returnToStartTimer;
int startX, startY;
void (*preFire)(void);
void (*attack)(void);
int (*canFire)(Entity *target);
};

View File

@ -72,7 +72,8 @@ void initGameSystem(void)
initFonts,
initAtlas,
initSounds,
initSprites
initSprites,
initEntityFactory
};
numInitFuns = sizeof(initFuncs) / sizeof(void*);

View File

@ -31,6 +31,7 @@ extern void initFonts(void);
extern void initAtlas(void);
extern void initSounds(void);
extern void initSprites(void);
extern void initEntityFactory(void);
extern void destroyLookups(void);
extern void destroyFonts(void);
extern void destroyTextures(void);

View File

@ -167,7 +167,7 @@ void dropBattery(double x, double y)
throwItem(i);
}
void addRandomItems(double x, double y)
void addRandomItems(float x, float y)
{
if (rand() % 100 < 25)
{

View File

@ -23,5 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern int rrnd(int low, int high);
extern int getRandomPlayerWeapon(int excludeGrenades);
extern int getSpriteIndex(char *name);
extern void addRandomItems(float x, float y);
extern World world;

View File

@ -20,6 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "player.h"
void stunPlayer(void)
void stunBob(void)
{
}

View File

@ -128,7 +128,7 @@ static void loadBob(cJSON *root)
{
Bob *b;
b = (Bob*)createEntity(ET_BOB);
b = (Bob*)createEntity("Bob");
b->x = cJSON_GetObjectItem(root, "x")->valueint;
b->y = cJSON_GetObjectItem(root, "y")->valueint;
b->facing = lookup(cJSON_GetObjectItem(root, "facing")->valuestring);
@ -138,8 +138,32 @@ static void loadBob(cJSON *root)
static void loadEntities(cJSON *root)
{
cJSON *node;
for (node = root->child ; node != NULL ; node = node->next)
{
createEntity(cJSON_GetObjectItem(node, "type")->valuestring);
}
}
static void loadObjectives(cJSON *root)
{
Objective *o;
cJSON *node;
for (node = root->child ; node != NULL ; node = node->next)
{
o = malloc(sizeof(Objective));
memset(o, 0, sizeof(Objective));
world.objectiveTail->next = o;
world.objectiveTail = o;
STRNCPY(o->id, cJSON_GetObjectItem(node, "id")->valuestring, MAX_NAME_LENGTH);
STRNCPY(o->targetName, cJSON_GetObjectItem(node, "targetName")->valuestring, MAX_NAME_LENGTH);
STRNCPY(o->description, cJSON_GetObjectItem(node, "description")->valuestring, MAX_DESCRIPTION_LENGTH);
o->totalValue = cJSON_GetObjectItem(node, "totalValue")->valueint;
o->targetValue = cJSON_GetObjectItem(node, "totalValue")->valueint;
o->currentValue = cJSON_GetObjectItem(node, "currentValue")->valueint;
o->required = cJSON_GetObjectItem(node, "required")->valueint;
}
}

View File

@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern char *readFile(const char *filename);
extern void loadSprite(cJSON *root);
extern Entity *createEntity(int type);
extern Entity *createEntity(char *typeStr);
extern long lookup(const char *name);
extern void initBob(Bob *b);