From 7a2529d2502e851abd4bd1bd92c5746a399b536a Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 25 Jan 2018 08:11:45 +0000 Subject: [PATCH] Teeka. --- common.mk | 2 +- src/combat/weapons.c | 4 +- src/world/entities.c | 176 ------------------- src/world/entities.h | 30 ---- src/world/entities/blobs/teeka.c | 161 +++++++++++++++++ src/world/{unit.h => entities/blobs/teeka.h} | 20 +-- src/world/{ => entities}/unit.c | 6 +- 7 files changed, 174 insertions(+), 225 deletions(-) delete mode 100644 src/world/entities.c delete mode 100644 src/world/entities.h create mode 100644 src/world/entities/blobs/teeka.c rename src/world/{unit.h => entities/blobs/teeka.h} (66%) rename src/world/{ => entities}/unit.c (97%) diff --git a/common.mk b/common.mk index f200928..48d6508 100644 --- a/common.mk +++ b/common.mk @@ -31,7 +31,7 @@ OBJS += objectives.o OBJS += particles.o player.o OBJS += quadtree.o OBJS += sound.o sprites.o -OBJS += text.o textures.o title.o triggers.o +OBJS += teeka.o text.o textures.o title.o triggers.o OBJS += unit.o util.o OBJS += weapons.o widgets.o diff --git a/src/combat/weapons.c b/src/combat/weapons.c index ff2ed49..49d52bc 100644 --- a/src/combat/weapons.c +++ b/src/combat/weapons.c @@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "weapons.h" -static Entity *createBaseBullet(Entity *owner); +Entity *createBaseBullet(Entity *owner); static int bulletSprite[2]; static int plasmaSprite[2]; @@ -230,7 +230,7 @@ void fireMissile(Entity *owner) playSound(SND_MISSILE, CH_WEAPON); } -static Entity *createBaseBullet(Entity *owner) +Entity *createBaseBullet(Entity *owner) { Entity *bullet; diff --git a/src/world/entities.c b/src/world/entities.c deleted file mode 100644 index b795677..0000000 --- a/src/world/entities.c +++ /dev/null @@ -1,176 +0,0 @@ -/* -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.h b/src/world/entities.h deleted file mode 100644 index 53a495d..0000000 --- a/src/world/entities.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -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/blobs/teeka.c b/src/world/entities/blobs/teeka.c new file mode 100644 index 0000000..47889d4 --- /dev/null +++ b/src/world/entities/blobs/teeka.c @@ -0,0 +1,161 @@ +/* +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 "teeka.h" + +static void tick(void); +static void lookForEnemies(void); +static void preFire(void); +static void attack(void); + +static Entity *target; +static int aimedSprite; +static int exitMission; + +void initTeeka(Entity *e) +{ + e->type = ET_TEEKA; + + aimedSprite = getSpriteIndex("AimedShot"); + + e->flags |= EF_IMMUNE; + + e->currentAction = 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) +{ + self->health = self->healthMax = 9999; + + if (target != NULL) + { + self->facing = (target->x < self->x) ? FACING_LEFT : FACING_RIGHT; + + if (target->alive == ALIVE_DEAD) + { + target = NULL; + + self->currentAction = lookForEnemies; + } + } + + unitTick(); +} + +static void lookForEnemies(void) +{ + Entity *e; + float distance, range; + + self->thinkTime = rrnd(FPS / 2, FPS); + + target = NULL; + + distance = 800; + + for (e = world.entityHead.next ; e != NULL ; e = e->next) + { + if (e->type == ET_ENEMY) + { + range = getDistance(self->x, self->y, e->x, e->y); + + if (range < distance) + { + if (hasLineOfSight(self, e)) + { + target = e; + distance = range; + } + } + } + } + + if (target != NULL) + { + self->shotsToFire = rrnd(3, 5); + + self->currentAction = preFire; + } + else if (exitMission) + { + addTeleportStars(self); + self->alive = ALIVE_DEAD; + playSound(SND_APPEAR, CH_ANY); + } + else + { + self->facing = rand() % 2 == 0 ? FACING_LEFT : FACING_RIGHT; + } +} + +static void preFire(void) +{ + if (self->reload > 0) + { + return; + } + + if (target->y < self->y && self->isOnGround && rand() % 10 == 0) + { + self->dy = JUMP_POWER; + } + + attack(); + + self->shotsToFire--; + + if (self->shotsToFire == 0) + { + self->thinkTime = FPS; + } +} + +static void attack(void) +{ + Entity *bullet; + float dx, dy; + + getSlope(target->x, target->y, self->x, self->y, &dx, &dy); + + bullet = createBaseBullet(self); + bullet->x = self->x; + bullet->y = (self->y + self->h / 2) - 3; + bullet->facing = self->facing; + bullet->damage = 1; + bullet->owner = self; + bullet->health = FPS * 3; + bullet->weaponType = WPN_AIMED_PISTOL; + bullet->dx = dx * 9; + bullet->dy = dy * 9; + bullet->sprite[0] = bullet->sprite[1] = aimedSprite; + bullet->health *= 2; + + self->reload = 5; +} diff --git a/src/world/unit.h b/src/world/entities/blobs/teeka.h similarity index 66% rename from src/world/unit.h rename to src/world/entities/blobs/teeka.h index 3bfc598..941b500 100644 --- a/src/world/unit.h +++ b/src/world/entities/blobs/teeka.h @@ -18,24 +18,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "../common.h" +#include "../../../common.h" -extern void initEntity(Entity *e); -extern void lookForPlayer(void); +extern void lookForEnemy(void); +extern void unitTick(void); +extern int getSpriteIndex(char *name); extern int rrnd(int low, int high); -extern float limit(float i, float a, float b); +extern Entity *createBaseBullet(Entity *owner); +extern void getSlope(int x1, int y1, int x2, int y2, float *dx, float *dy); extern int getDistance(int x1, int y1, int x2, int y2); +extern int hasLineOfSight(Entity *src, Entity *dest); 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; diff --git a/src/world/unit.c b/src/world/entities/unit.c similarity index 97% rename from src/world/unit.c rename to src/world/entities/unit.c index d49274c..21986d8 100644 --- a/src/world/unit.c +++ b/src/world/entities/unit.c @@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "unit.h" -static void tick(void); +void unitTick(void); static void attack(void); void initUnit(Entity *e) @@ -41,7 +41,7 @@ void initUnit(Entity *e) e->startX = e->startY = -1; - e->tick = tick; + e->tick = unitTick; e->currentAction = lookForPlayer; e->attack = attack; } @@ -60,7 +60,7 @@ void reInitUnit(Entity *e) } } -static void tick(void) +void unitTick(void) { if (self->alive == ALIVE_ALIVE) {