diff --git a/common.mk b/common.mk index 484a958..6b393f4 100644 --- a/common.mk +++ b/common.mk @@ -2,7 +2,7 @@ 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/game src/system src/util src/widgets src/world +SEARCHPATH += src src/combat src/game src/system src/util src/widgets src/world vpath %.c $(SEARCHPATH) vpath %.h $(SEARCHPATH) @@ -10,6 +10,7 @@ DEPS += defs.h structs.h OBJS += camera.o OBJS += draw.o +OBJS += combat.o OBJS += entities.o OBJS += game.o OBJS += hud.o diff --git a/src/combat/combat.c b/src/combat/combat.c new file mode 100644 index 0000000..2eb4fe3 --- /dev/null +++ b/src/combat/combat.c @@ -0,0 +1,120 @@ +/* +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 "combat.h" + +static int isBlockedByMap(Entity *src, Entity *dest); +static int isBlockedByEntities(Entity *src, Entity *dest); + +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) +{ + return (!isBlockedByMap(src, dest) && !isBlockedByEntities(src, dest)); +} + +static int isBlockedByMap(Entity *src, Entity *dest) +{ + SDL_Rect mapBlock; + int x, y, x1, y1, x2, y2, mx, my; + + x1 = (int) MIN(src->x, dest->x); + y1 = (int) MIN(src->y, dest->y); + x2 = (int) MAX(src->x, dest->x); + y2 = (int) MAX(src->y, dest->y); + + for (x = x1; x <= x2; x++) + { + for (y = y1; y <= y2; y++) + { + mx = x / MAP_TILE_SIZE; + my = y / MAP_TILE_SIZE; + + if (isSolid(mx, my)) + { + mapBlock.x = x; + mapBlock.y = y; + mapBlock.w = MAP_TILE_SIZE; + mapBlock.h = MAP_TILE_SIZE; + + if (lineIntersectsRect(mapBlock, src->x, src->y, dest->x, dest->y)) + { + return 1; + } + } + } + } + + return 0; +} + +static int isBlockedByEntities(Entity *src, Entity *dest) +{ + Entity **candidates, *e; + SDL_Rect losBounds; + int i; + + losBounds.x = (int) MIN(src->x, dest->x); + losBounds.y = (int) MIN(src->y, dest->y); + losBounds.w = (int) (MAX(src->x, dest->x) - losBounds.x); + losBounds.h = (int) (MAX(src->y, dest->y) - losBounds.y); + + candidates = getAllEntsWithin(losBounds.x, losBounds.y, losBounds.w, losBounds.h, NULL); + + for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) + { + if (e == src || e == dest || !e->isSolid) + { + continue; + } + + if (lineIntersectsRect(e->bounds, src->x, src->y, dest->x, dest->y)) + { + return 1; + } + } + + return 0; +} diff --git a/src/combat/combat.h b/src/combat/combat.h new file mode 100644 index 0000000..ed91f43 --- /dev/null +++ b/src/combat/combat.h @@ -0,0 +1,27 @@ +/* +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 isSolid(int x, int y); +extern int lineIntersectsRect(SDL_Rect r, int x1, int y1, int x2, int y2); +extern Entity **getAllEntsWithin(int x, int y, int w, int h, Entity *ignore); + +extern World world; diff --git a/src/defs.h b/src/defs.h index 9847b2d..e1d7eb0 100644 --- a/src/defs.h +++ b/src/defs.h @@ -74,12 +74,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MAP_TILE_OUTSIDE 255 #define MAP_TILE_MAX 256 +#define JUMP_POWER 1 + #define ET_ENEMY 0 #define ET_KEY 1 #define ET_MIA 2 #define EF_NONE 0 #define EF_HEART_CELL (2 << 0) +#define EF_WEIGHTLESS (2 << 1) + +enum +{ + FACING_RIGHT, + FACING_LEFT +}; enum { diff --git a/src/structs.h b/src/structs.h index 3dd985a..502b3a5 100644 --- a/src/structs.h +++ b/src/structs.h @@ -82,7 +82,17 @@ struct Entity { int w; int h; int alive; + float dx; + float dy; + int reload; + int isOnGround; + int facing; + int shotsToFire; + int isSolid; long flags; + SDL_Rect bounds; + void (*walk)(void); + void (*attack)(void); Entity *next; }; diff --git a/src/util/maths.c b/src/util/maths.c index 7a762bd..2ef90eb 100644 --- a/src/util/maths.c +++ b/src/util/maths.c @@ -77,6 +77,11 @@ void getSlope(int x1, int y1, int x2, int y2, float *dx, float *dy) *dy /= steps; } +int lineIntersectsRect(SDL_Rect r, int x1, int y1, int x2, int y2) +{ + return 0; +} + unsigned long hashcode(const char *str) { unsigned long hash = 5381; diff --git a/src/util/maths.h b/src/util/maths.h index c3b03ff..8ad0dc9 100644 --- a/src/util/maths.h +++ b/src/util/maths.h @@ -19,4 +19,3 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../common.h" -