diff --git a/common.mk b/common.mk index 3897eb2..f200928 100644 --- a/common.mk +++ b/common.mk @@ -2,7 +2,17 @@ VERSION = 0.1 REVISION = $(shell git rev-list HEAD 2>/dev/null | wc -l) LOCALE_MO = $(patsubst %.po,%.mo,$(wildcard locale/*.po)) -SEARCHPATH += src src/combat src/game src/hub src/system src/util src/widgets src/world +SEARCHPATH += src +SEARCHPATH += src/combat +SEARCHPATH += src/game +SEARCHPATH += src/hub +SEARCHPATH += src/system +SEARCHPATH += src/util +SEARCHPATH += src/widgets +SEARCHPATH += src/world +SEARCHPATH += src/world/entities +SEARCHPATH += src/world/entities/blobs + vpath %.c $(SEARCHPATH) vpath %.h $(SEARCHPATH) @@ -16,7 +26,7 @@ OBJS += game.o OBJS += hub.o hud.o OBJS += init.o input.o io.o items.o OBJS += lookup.o -OBJS += main.o map.o maths.o +OBJS += main.o map.o maths.o mia.o OBJS += objectives.o OBJS += particles.o player.o OBJS += quadtree.o diff --git a/src/combat/combat.c b/src/combat/combat.c index b80b7b7..b19a1c4 100644 --- a/src/combat/combat.c +++ b/src/combat/combat.c @@ -23,6 +23,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static int isBlockedByMap(Entity *src, Entity *dest); static int isBlockedByEntities(Entity *src, Entity *dest); +void nothing(void) +{ +} + void lookForPlayer(void) { diff --git a/src/structs.h b/src/structs.h index ae20642..d62dbc1 100644 --- a/src/structs.h +++ b/src/structs.h @@ -117,6 +117,9 @@ struct Entity { int canCarryItem; int spawnedIn; int spawnedInTimer; + int shudderTimer; + int starTimer; + int teleportTimer; long flags; SDL_Rect bounds; int sprite[3]; @@ -129,6 +132,7 @@ struct Entity { void (*attack)(void); void (*touch)(Entity *other); void (*tick)(void); + void (*reset)(void); Entity *next; }; diff --git a/src/world/entities/blobs/mia.c b/src/world/entities/blobs/mia.c new file mode 100644 index 0000000..383d68d --- /dev/null +++ b/src/world/entities/blobs/mia.c @@ -0,0 +1,134 @@ +/* +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 "mia.h" + +static void reset(void); +static void tick(void); +static void touch(Entity *other); +static void preTeleport(void); +static void teleport(void); +static void addRescuedMIA(void); + +void initMIA(Entity *e) +{ + e->tx = e->ty = -1; + + e->sprite[FACING_LEFT] = getSpriteIndex("MIA"); + e->sprite[FACING_RIGHT] = getSpriteIndex("MIA"); + e->sprite[FACING_DIE] = getSpriteIndex("MIA"); + + e->flags |= EF_IGNORE_BULLETS; + + /* blink at random intervals */ + e->spriteFrame = 0; + e->spriteTime = rand() % 180; + + e->currentAction = nothing; + e->reset = reset; + e->tick = tick; + e->touch = touch; + + e->isMissionTarget = 1; +} + +void reinitMIA(Entity *e) +{ + if (e->tx == -1 && e->ty == -1) + { + e->tx = e->x; + e->ty = e->y; + } +} + +static void reset(void) +{ + self->tx = self->ty = -1; +} + +static void tick(void) +{ + self->shudderTimer--; + if (self->shudderTimer <= 0) + { + self->x = (self->tx + rand() % 4); + self->shudderTimer = 2; + } + + if (self->currentAction != nothing) + { + self->starTimer--; + if (self->starTimer <= 0) + { + addMIATeleportStars(self->x + rand() % self->w, self->y + rand() % self->h); + self->starTimer = 1; + } + } +} + +static void touch(Entity *other) +{ + if (self->currentAction == nothing && other == world.bob) + { + self->currentAction = preTeleport; + self->teleportTimer = FPS * 3; + setGameplayMessage(MSG_OBJECTIVE, "Rescued %s", self->name); + self->isMissionTarget = 0; + self->flags |= EF_ALWAYS_PROCESS; + playSound(SND_MIA, CH_ANY); + } +} + +static void preTeleport(void) +{ + self->teleportTimer--; + if (self->teleportTimer <= FPS) + { + self->currentAction = teleport; + self->flags |= (EF_NO_CLIP | EF_WEIGHTLESS); + self->dy = -5; + } +} + +static void teleport(void) +{ + self->teleportTimer--; + if (self->teleportTimer <= 0) + { + addTeleportStars(self); + addRescuedMIA(); + updateObjective("MIA"); + self->alive = ALIVE_DEAD; + } +} + +static void addRescuedMIA(void) +{ + int i; + + for (i = 0 ; i < game.totalMIAs ; i++) + { + if (strcmp(game.mias[i], "") == 0) + { + STRNCPY(game.mias[i], self->name, MAX_NAME_LENGTH); + return; + } + } +} diff --git a/src/world/entities/blobs/mia.h b/src/world/entities/blobs/mia.h new file mode 100644 index 0000000..331a3c4 --- /dev/null +++ b/src/world/entities/blobs/mia.h @@ -0,0 +1,33 @@ +/* +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 getSpriteIndex(char *name); +extern void nothing(void); +extern void addMIATeleportStars(float x, float y); +extern void addTeleportStars(Entity *e); +extern void setGameplayMessage(int type, char *format, ...); +extern void playSound(int snd, int ch); +extern void updateObjective(char *targetName); + +extern Entity *self; +extern Game game; +extern World world; diff --git a/src/world/entities/entities.c b/src/world/entities/entities.c new file mode 100644 index 0000000..b795677 --- /dev/null +++ b/src/world/entities/entities.c @@ -0,0 +1,176 @@ +/* +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 "entities.h" + +Entity *createEntity(void) +{ + Entity *e; + + e = malloc(sizeof(Entity)); + memset(e, 0, sizeof(Entity)); + world.entityTail->next = e; + world.entityTail = e; + + e->uniqueId = game.entityCounter++; + + return e; +} + +void initEntity(Entity *e) +{ + e->sprite[0] = e->sprite[1] = e->sprite[2] = -1; + + e->environment = ENV_AIR; + e->alive = ALIVE_ALIVE; + + e->isOnGround = 0; + e->isSolid = 0; + e->isStatic = 0; + e->isMissionTarget = 0; + + e->health = e->healthMax = 1; + + e->facing = FACING_LEFT; + + e->spriteFrame = -1; + e->spriteTime = 0; + + e->dx = e->dy = 0; + + e->flags = 0; + + e->owner = NULL; + + e->thinkTime = 0; + + e->plane = PLANE_BACKGROUND; +} + +SDL_Rect *getEntityBounds(Entity *e) +{ + e->bounds.x = e->x; + e->bounds.y = e->y; + e->bounds.w = e->w; + e->bounds.h = e->h; + + return &e->bounds; +} + +int getCurrentEntitySprite(Entity *e) +{ + if (e->alive == ALIVE_ALIVE) + { + return e->sprite[e->facing]; + } + + return e->sprite[FACING_DIE]; +} + +void animateEntity(Entity *e) +{ + Sprite *spr; + + if (e->spriteTime != -1) + { + e->spriteTime--; + + if (e->spriteTime <= 0) + { + spr = getSpriteByIndex(getCurrentEntitySprite(e)); + e->spriteFrame = wrap(e->spriteFrame + 1, 0, 1); + e->spriteTime = 0; + e->w = spr->w; + e->h = spr->h; + } + } +} + +void setEntitySize(Entity *e) +{ + Sprite *spr; + + spr = getSpriteByIndex(getCurrentEntitySprite(e)); + e->w = spr->w; + e->h = spr->h; +} + +float bounce(Entity *e, float x) +{ + if (!(e->flags & EF_BOUNCES)) + { + return 0; + } + else if (e->flags & EF_FRICTIONLESS) + { + return -x; + } + + x = -x * FRICTION; + + if (x > -1 && x < 1) + { + e->flags &= ~EF_BOUNCES; + x = 0; + } + + return x; +} + +void teleport(Entity *e, float tx, float ty) +{ + e->tx = tx; + e->ty = ty; + + e->flags |= EF_TELEPORTING; + + addTeleportStars(e); +} + +void activateEntities(char *names, int activate) +{ +} + +void applyEntityDamage(Entity *e, int damage) +{ + if (e->health < 0) + { + e->health = 0; + e->alive = ALIVE_ALIVE; + } + + e->health -= damage; + + if (e->health > 0) + { + e->thinkTime = 0; + + e->facing = e->x < world.bob->x ? FACING_RIGHT : FACING_LEFT; + + if (e->isMissionTarget && rand() % 10 == 0) + { + e->currentAction = unitReappear; + e->flags |= EF_GONE; + e->thinkTime = rand() % FPS; + addTeleportStars(e); + playSound(SND_APPEAR, CH_ANY); + } + } +} diff --git a/src/world/entities/entities.h b/src/world/entities/entities.h new file mode 100644 index 0000000..4d4f8f3 --- /dev/null +++ b/src/world/entities/entities.h @@ -0,0 +1,30 @@ +/* +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 Sprite *getSpriteByIndex(int x); +extern float wrap(float value, float low, float high); +extern void addTeleportStars(Entity *e); +extern void unitReappear(void); +extern void playSound(int snd, int ch); + +extern Game game; +extern World world; diff --git a/src/world/entities/unit.h b/src/world/entities/unit.h new file mode 100644 index 0000000..06163d8 --- /dev/null +++ b/src/world/entities/unit.h @@ -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 initEntity(Entity *e); +extern void lookForPlayer(void); +extern int rrnd(int low, int high); +extern float limit(float i, float a, float b); +extern int getDistance(int x1, int y1, int x2, int y2); +extern void addTeleportStars(Entity *e); +extern void playSound(int snd, int ch); +extern int canFire(Entity *target); +extern void fireAimedShot(Entity *e); +extern void fireMachineGun(Entity *e); +extern void fireGrenade(Entity *e); +extern void firePlasma(Entity *e); +extern void fireSpread(Entity *e, int n); +extern void fireLaser(Entity *e); +extern void fireShotgun(Entity *e); +extern void fireMissile(Entity *e); + +extern Entity *self; +extern World world;