diff --git a/makefile b/makefile index d29c7ae..9f5d563 100644 --- a/makefile +++ b/makefile @@ -30,7 +30,7 @@ OBJS += load.o lookup.o OBJS += main.o mission.o missionInfo.o OBJS += objectives.o options.o OBJS += player.o -OBJS += radar.o +OBJS += radar.o rope.o OBJS += save.o sound.o starfield.o starSystems.o stats.o OBJS += testMission.o textures.o text.o title.o transition.o triggers.o OBJS += util.o diff --git a/src/battle/entities.c b/src/battle/entities.c index 6c349f4..a15fdf4 100644 --- a/src/battle/entities.c +++ b/src/battle/entities.c @@ -92,6 +92,8 @@ void doEntities(void) break; } + doRope(e); + restrictToGrid(e); e->x += e->dx; @@ -228,6 +230,8 @@ void drawEntities(void) } drawTargetRects(e); + + drawRope(e); } } diff --git a/src/battle/entities.h b/src/battle/entities.h index b07a4a4..8e11a75 100644 --- a/src/battle/entities.h +++ b/src/battle/entities.h @@ -29,6 +29,8 @@ extern void doFighter(void); extern void addToGrid(Entity *e); extern void removeFromGrid(Entity *e); extern Entity **getAllEntsWithin(int x, int y, int w, int h, Entity *ignore); +extern void doRope(Entity *e); +extern void drawRope(Entity *e); extern App app; extern Battle battle; diff --git a/src/battle/extractionPoint.c b/src/battle/extractionPoint.c index d756f8b..6421af5 100644 --- a/src/battle/extractionPoint.c +++ b/src/battle/extractionPoint.c @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static void think(void); static void handleFleeingEntities(void); +static void cutTowRope(Entity *e); Entity *spawnExtractionPoint(void) { @@ -63,6 +64,21 @@ static void handleFleeingEntities(void) if (e->health > 0 && e->flags & EF_FLEEING && getDistance(e->x, e->y, self->x, self->y) <= 64) { e->alive = ALIVE_ESCAPED; + + cutTowRope(e); + } + } +} + +static void cutTowRope(Entity *attachment) +{ + Entity *e; + + for (e = battle.entityHead.next ; e != NULL ; e = e->next) + { + if (e->towing == attachment) + { + e->towing = NULL; } } } diff --git a/src/battle/extractionPoint.h b/src/battle/extractionPoint.h index b24b9dd..b14545b 100644 --- a/src/battle/extractionPoint.h +++ b/src/battle/extractionPoint.h @@ -27,6 +27,7 @@ extern SDL_Texture *getTexture(char *filename); extern Entity *spawnEntity(void); extern Entity **getAllEntsWithin(int x, int y, int w, int h, Entity *ignore); extern int getDistance(int x1, int y1, int x2, int y2); +extern void destroyRope(Entity *owner); extern Battle battle; extern Entity *self; diff --git a/src/battle/fighters.c b/src/battle/fighters.c index 56dfc43..3e4a6a9 100644 --- a/src/battle/fighters.c +++ b/src/battle/fighters.c @@ -27,6 +27,7 @@ static void spinDie(void); static void straightDie(void); static void randomizeDart(Entity *dart); static void randomizeDartGuns(Entity *dart); +static void attachRope(void); Entity *spawnFighter(char *name, int x, int y, int side) { @@ -174,6 +175,8 @@ void doFighter(void) separate(); } + attachRope(); + self->reload = MAX(self->reload - 1, 0); self->shieldRecharge = MAX(self->shieldRecharge - 1, 0); self->armourHit = MAX(self->armourHit - 25, 0); @@ -207,7 +210,7 @@ void doFighter(void) battle.missionTarget = NULL; } } - else if (self->systemPower <= 0) + else if (self->systemPower <= 0 || (self->flags & EF_DISABLED)) { self->dx *= 0.99; self->dy *= 0.99; @@ -332,6 +335,30 @@ static void separate(void) } } +static void attachRope(void) +{ + int i, distance; + Entity *e, **candidates; + + if ((self->flags & EF_HAS_ROPE) && self->towing == NULL) + { + candidates = getAllEntsWithin(self->x, self->y, self->w, self->h, self); + + for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) + { + if ((e->flags & EF_DISABLED) && e->alive == ALIVE_ALIVE) + { + distance = getDistance(e->x, e->y, self->x, self->y); + + if (distance > 0 && distance <= 32) + { + self->towing = e; + } + } + } + } +} + void drawFighter(Entity *e) { SDL_Texture *shieldHitTexture = getTexture("gfx/battle/shieldHit.png"); diff --git a/src/battle/fighters.h b/src/battle/fighters.h index dcce3b4..a9c43ee 100644 --- a/src/battle/fighters.h +++ b/src/battle/fighters.h @@ -42,6 +42,7 @@ extern void checkTrigger(char *name, int type); extern Entity **getAllEntsWithin(int x, int y, int w, int h, Entity *ignore); extern Entity *spawnEntity(void); extern void adjustObjectiveTargetValue(char *name, int type, int amount); +extern void addRope(Entity *src, Entity *dest); extern App app; extern Battle battle; diff --git a/src/battle/rope.c b/src/battle/rope.c new file mode 100644 index 0000000..4e006dd --- /dev/null +++ b/src/battle/rope.c @@ -0,0 +1,57 @@ +/* +Copyright (C) 2015 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 "rope.h" + +void doRope(Entity *owner) +{ + float dx, dy, angle, force; + int distance; + + if (owner->towing) + { + distance = getDistance(owner->towing->x, owner->towing->y, owner->x, owner->y); + + if (distance > ROPE_DISTANCE) + { + angle = getAngle(owner->x, owner->y, owner->towing->x, owner->towing->y); + + dx = sin(TO_RAIDANS(angle)); + dy = -cos(TO_RAIDANS(angle)); + force = (distance - ROPE_DISTANCE) * 0.02; + + owner->towing->dx -= (dx * force); + owner->towing->dy -= (dy * force); + } + + owner->towing->dx *= 0.985; + owner->towing->dy *= 0.985; + } +} + +void drawRope(Entity *owner) +{ + if (owner->towing) + { + SDL_SetRenderDrawColor(app.renderer, 200, 200, 200, SDL_ALPHA_OPAQUE); + + SDL_RenderDrawLine(app.renderer, owner->x - battle.camera.x, owner->y - battle.camera.y, owner->towing->x - battle.camera.x, owner->towing->y - battle.camera.y); + } +} diff --git a/src/battle/rope.h b/src/battle/rope.h new file mode 100644 index 0000000..b5f608f --- /dev/null +++ b/src/battle/rope.h @@ -0,0 +1,32 @@ +/* +Copyright (C) 2015 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 "SDL2/SDL.h" + +#include "../defs.h" +#include "../structs.h" + +#define ROPE_DISTANCE 128 + +extern float getAngle(int x1, int y1, int x2, int y2); +extern int getDistance(int x1, int y1, int x2, int y2); + +extern App app; +extern Battle battle; diff --git a/src/structs.h b/src/structs.h index 4d94d9e..8731b96 100644 --- a/src/structs.h +++ b/src/structs.h @@ -109,6 +109,7 @@ struct Entity { Weapon missiles; long flags; SDL_Point targetLocation; + Entity *towing; Entity *target; void (*action)(void); void (*defaultAction)(void);