From 0a131e25c0f56d4a6401dc18040415658812fdbe Mon Sep 17 00:00:00 2001 From: Steve Date: Sat, 3 Feb 2018 10:01:14 +0000 Subject: [PATCH] Implemented more entity handling code. --- src/world/entities.c | 271 ++++++++++++++++++++++++++++++++++++++++++- src/world/entities.h | 2 +- src/world/map.c | 5 - src/world/world.c | 8 +- src/world/world.h | 1 - 5 files changed, 273 insertions(+), 14 deletions(-) diff --git a/src/world/entities.c b/src/world/entities.c index 436641b..3e30caa 100644 --- a/src/world/entities.c +++ b/src/world/entities.c @@ -30,6 +30,10 @@ static void haltAtEdge(void); static int canWalkOnEntity(float x, float y); static void moveToOthers(float dx, float dy, PointF *position); static void addTouched(Entity *e); +static int pushEntity(Entity *e, float dx, float dy); +static void moveToMap(float dx, float dy, PointF *position); +static int hasHitWorld(int mx, int my); +static void compareEnvironments(void); static SDL_Rect srcRect; static Entity *riders[MAX_RIDERS]; @@ -52,7 +56,8 @@ void initEntities(void) void doEntities(void) { - int camMidX, camMidY, flicker; + Entity *prev; + int camMidX, camMidY, flicker, i; memset(riders, 0, sizeof(Entity*) * MAX_RIDERS); @@ -65,6 +70,8 @@ void doEntities(void) flicker = world.frameCounter % 3 > 0; + prev = &world.entityHead; + for (self = world.entityHead.next ; self != NULL ; self = self->next) { removeFromQuadtree(self, &world.quadtree); @@ -74,6 +81,7 @@ void doEntities(void) if (self->flags & EF_TELEPORTING) { handleTeleport(); + prev = self; continue; } @@ -127,7 +135,58 @@ void doEntities(void) } self->animate(); + + for (i = 0 ; i < MAX_TOUCHED ; i++) + { + if (touched[i]) + { + self->touch(touched[i]); + } + + if (touched[i]->isStatic) + { + touched[i]->touch(self); /* for objects that never move */ + } + } + + if (!(self->flags & EF_NO_ENVIRONMENT)) + { + compareEnvironments(); + + /* + * Always sink if not in the air + */ + if (self->environment != ENV_AIR && (!(self->flags & EF_SWIMS))) + { + self->dy = 0.5f; + } + } + + if ((!(self->flags & EF_FLICKER)) && flicker) + { + self->isOnScreen = 0; + } + + if (self->alive == ALIVE_ALIVE && self->health <= 0) + { + self->alive = ALIVE_DYING; + self->die(); + } + + if (self->alive == ALIVE_DEAD) + { + prev->next = self->next; + + if (self == world.entityTail) + { + world.entityTail = prev; + } + + self = prev; + } } + + prev = self; } } @@ -226,12 +285,12 @@ static void moveEntity(void) position.y = self->x; position.x += self->dx; moveToOthers(self->dx, 0, &position); - moveToMap(self->dx, 0, position); + moveToMap(self->dx, 0, &position); // Deal with Y movement position.y += self->dy; moveToOthers(0, self->dy, &position); - moveToMap(0, self->dy, position); + moveToMap(0, self->dy, &position); if (self->dy > 0 && self->riding != NULL) { @@ -455,6 +514,212 @@ static void moveToOthers(float dx, float dy, PointF *position) while (hit); } +static int pushEntity(Entity *e, float dx, float dy) +{ + float expectedX, expectedY; + PointF position; + Entity *oldSelf; + + oldSelf = self; + + expectedX = e->x + dx; + expectedY = e->y + dy; + + position.x = e->x; + position.y = e->y; + + if (dx != 0) + { + position.x += dx; + moveToOthers(dx, 0, &position); + moveToMap(dx, 0, &position); + e->x = position.x; + } + + if (dy != 0) + { + position.y += dy; + moveToOthers(0, dy, &position); + moveToMap(0, dy, &position); + e->y = position.y; + } + + self = oldSelf; + + return (e->x == expectedX && e->y == expectedY); +} + +static void moveToMap(float dx, float dy, PointF *position) +{ + int i, mx, my, width, height, adjX, adjY, hit; + + width = self->w; + height = self->h; + adjX = adjY = 0; + + if (self->flags & EF_NO_CLIP) + { + return; + } + + if (dx != 0) + { + width = (dx > 0) ? self->w + 1 : -1; + adjX = (dx > 0) ? self->w : -MAP_TILE_SIZE; + } + + if (dy != 0) + { + height = (dy > 0) ? self->h + 1 : -1; + adjY = (dy > 0) ? self->h : -MAP_TILE_SIZE; + } + + hit = 0; + + mx = (position->x + width) / MAP_TILE_SIZE; + my = (position->y + height) / MAP_TILE_SIZE; + + if (mx < 0 || my < 0) + { + return; + } + + /* X Axis */ + + if (dx != 0) + { + for (i = 0; i < self->h - 1; i += MAP_TILE_SIZE) + { + my = (position->y + i) / MAP_TILE_SIZE; + + hit = (hasHitWorld(mx, my) ? 1 : hit); + } + + my = (position->y + self->h - 1) / MAP_TILE_SIZE; + + hit = (hasHitWorld(mx, my) ? 1 : hit); + } + + /* Y Axis */ + + if (dy != 0) + { + for (i = 0; i < self->w - 1; i += MAP_TILE_SIZE) + { + mx = (position->x + i) / MAP_TILE_SIZE; + + hit = (hasHitWorld(mx, my) ? 1 : hit); + } + + mx = (position->x + self->w - 1) / MAP_TILE_SIZE; + + hit = (hasHitWorld(mx, my) ? 1 : hit); + } + + if (hit) + { + if (dx != 0) + { + position->x = (mx * MAP_TILE_SIZE) - adjX; + self->dx = self->bounce(self->dx); + } + + if (dy != 0) + { + if (dy > 0) + { + self->isOnGround = 1; + } + + position->y = (my * MAP_TILE_SIZE) - adjY; + self->dy = self->bounce(self->dy); + self->dy = limit(self->dy, JUMP_POWER, -JUMP_POWER); + } + + self->touch(NULL); + } +} + +static int hasHitWorld(int mx, int my) +{ + if (mx < 0 || mx >= MAP_WIDTH || my < 0 || my >= MAP_HEIGHT) + { + return 0; + } + + if (isSolid(mx, my)) + { + return 1; + } + + return 0; +} + +static void compareEnvironments(void) +{ + int prevEnv, x, y; + + prevEnv = self->environment; + + self->environment = ENV_AIR; + x = self->x / MAP_TILE_SIZE; + y = self->y / MAP_TILE_SIZE; + + if (x < 0 || x >= MAP_WIDTH || y < 0 || y >= MAP_HEIGHT) + { + return; + } + + switch (world.map.data[x][y]) + { + case MAP_TILE_LAVA: + self->environment = ENV_LAVA; + break; + + case MAP_TILE_WATER: + self->environment = ENV_WATER; + break; + + case MAP_TILE_SLIME: + self->environment = ENV_SLIME; + break; + } + + if (self->environment == prevEnv) + { + return; + } + + switch (prevEnv) + { + case ENV_WATER: + playSound(SND_WATER_OUT, CH_EFFECTS); + if ((self->environment == ENV_AIR) && (self->dy < 0)) + { + self->dy = JUMP_POWER; + } + break; + + case ENV_AIR: + self->dx = 0; + self->dy = 0.25f; + if (self->environment == ENV_WATER) + { + playSound(SND_WATER_IN, CH_EFFECTS); + } + else + { + playSound(SND_SLIME, CH_EFFECTS); + } + break; + + default: + break; + } + + self->changeEnvironment(); +} + static int isObserving(void) { int i; diff --git a/src/world/entities.h b/src/world/entities.h index 60de724..b3a377a 100644 --- a/src/world/entities.h +++ b/src/world/entities.h @@ -29,7 +29,6 @@ extern void addTeleportStars(Entity *e); extern void removeFromQuadtree(Entity *e, Quadtree *root); extern Sprite *getSprite(char *name); extern void playSound(int snd, int ch); -extern void addTeleportStars(Entity *e); extern void addTeleportStar(float x, float y); extern int collision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2); extern int getDistance(int x1, int y1, int x2, int y2); @@ -37,6 +36,7 @@ extern void addToQuadtree(Entity *e, Quadtree *root); extern float limit(float i, float a, float b); extern int isWalkable(int x, int y); extern int isLiquid(int x, int y); +extern int isSolid(int x, int y); extern Entity *self; extern Camera camera; diff --git a/src/world/map.c b/src/world/map.c index b34f077..1a69b43 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -168,11 +168,6 @@ int isWalkable(int x, int y) return isSolid(x, y); } -int isBreakable(int x, int y) -{ - return 0; -} - static void calculateMapBounds(void) { int x, y; diff --git a/src/world/world.c b/src/world/world.c index a379656..a76c612 100644 --- a/src/world/world.c +++ b/src/world/world.c @@ -194,7 +194,7 @@ static void doWorldInProgress(void) if (world.observationTimer == FPS * 1.5) { - world.entityToTrack = entitiesToObserve[0]; + world.entityToTrack = world.entitiesToObserve[0]; world.state = WS_OBSERVING; } @@ -217,7 +217,7 @@ static void doWorldObserving(void) } } - memset(entitiesToObserve, 0, sizeof(Entity*) * MAX_ENTS_TO_OBSERVE); + memset(world.entitiesToObserve, 0, sizeof(Entity*) * MAX_ENTS_TO_OBSERVE); world.entityToTrack = (Entity*)world.bob; world.state = WS_IN_PROGRESS; } @@ -467,9 +467,9 @@ void observeActivation(Entity *e) { for (i = 0 ; i < MAX_ENTS_TO_OBSERVE ; i++) { - if (entitiesToObserve[i] == NULL) + if (world.entitiesToObserve[i] == NULL) { - entitiesToObserve[i] = e; + world.entitiesToObserve[i] = e; world.observationTimer = FPS * 2; } } diff --git a/src/world/world.h b/src/world/world.h index ff6265d..278950f 100644 --- a/src/world/world.h +++ b/src/world/world.h @@ -53,7 +53,6 @@ extern void blitScaled(SDL_Texture *texture, int x, int y, int w, int h, int cen extern void clearScreen(void); extern App app; -extern Camera camera; extern Dev dev; extern Game game; extern World world;