Separate entity functions to own file
This commit is contained in:
parent
1427ee3fde
commit
8a3886a60e
@ -125,6 +125,7 @@
|
|||||||
<ClCompile Include="src\Common.c" />
|
<ClCompile Include="src\Common.c" />
|
||||||
<ClCompile Include="src\Debug.c" />
|
<ClCompile Include="src\Debug.c" />
|
||||||
<ClCompile Include="src\dengine.c" />
|
<ClCompile Include="src\dengine.c" />
|
||||||
|
<ClCompile Include="src\Entity.c" />
|
||||||
<ClCompile Include="src\Platform.c" />
|
<ClCompile Include="src\Platform.c" />
|
||||||
<ClCompile Include="src\Renderer.c" />
|
<ClCompile Include="src\Renderer.c" />
|
||||||
<ClCompile Include="src\Shader.c" />
|
<ClCompile Include="src\Shader.c" />
|
||||||
|
@ -48,6 +48,9 @@
|
|||||||
<ClCompile Include="src\Audio.c">
|
<ClCompile Include="src\Audio.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\Entity.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="data\shaders\default.vert.glsl" />
|
<None Include="data\shaders\default.vert.glsl" />
|
||||||
|
161
src/Entity.c
Normal file
161
src/Entity.c
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#include "Dengine/AssetManager.h"
|
||||||
|
#include "Dengine/MemoryArena.h"
|
||||||
|
#include "Dengine/Platform.h"
|
||||||
|
#include "Dengine/Debug.h"
|
||||||
|
|
||||||
|
#include "Dengine/Entity.h"
|
||||||
|
|
||||||
|
#include "WorldTraveller/WorldTraveller.h"
|
||||||
|
|
||||||
|
void entity_setActiveAnim(Entity *entity, enum AnimList animId)
|
||||||
|
{
|
||||||
|
#ifdef DENGINE_DEBUG
|
||||||
|
ASSERT(animId < animlist_count);
|
||||||
|
ASSERT(entity->anim[animId].anim);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Reset current anim data */
|
||||||
|
EntityAnim_ *currAnim = &entity->anim[entity->currAnimId];
|
||||||
|
currAnim->currDuration = currAnim->anim->frameDuration;
|
||||||
|
currAnim->currFrame = 0;
|
||||||
|
|
||||||
|
/* Set entity active animation */
|
||||||
|
entity->currAnimId = animId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entity_updateAnim(Entity *entity, f32 dt)
|
||||||
|
{
|
||||||
|
if (!entity->tex) return;
|
||||||
|
|
||||||
|
// TODO(doyle): Recheck why we have this twice
|
||||||
|
EntityAnim_ *entityAnim = &entity->anim[entity->currAnimId];
|
||||||
|
Animation anim = *entityAnim->anim;
|
||||||
|
i32 frameIndex = anim.frameIndex[entityAnim->currFrame];
|
||||||
|
v4 texRect = anim.atlas->texRect[frameIndex];
|
||||||
|
|
||||||
|
entityAnim->currDuration -= dt;
|
||||||
|
if (entityAnim->currDuration <= 0.0f)
|
||||||
|
{
|
||||||
|
entityAnim->currFrame++;
|
||||||
|
entityAnim->currFrame = entityAnim->currFrame % anim.numFrames;
|
||||||
|
frameIndex = entityAnim->anim->frameIndex[entityAnim->currFrame];
|
||||||
|
texRect = anim.atlas->texRect[frameIndex];
|
||||||
|
entityAnim->currDuration = anim.frameDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(doyle): If humanoid entity, let animation dictate render size which
|
||||||
|
// may exceed the hitbox size of the entity
|
||||||
|
switch (entity->type)
|
||||||
|
{
|
||||||
|
case entitytype_hero:
|
||||||
|
case entitytype_mob:
|
||||||
|
case entitytype_npc:
|
||||||
|
entity->renderSize = math_getRectSize(texRect);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void entity_addAnim(AssetManager *assetManager, Entity *entity, i32 animId)
|
||||||
|
{
|
||||||
|
Animation *anim = asset_getAnim(assetManager, animId);
|
||||||
|
entity->anim[animId].anim = anim;
|
||||||
|
entity->anim[animId].currFrame = 0;
|
||||||
|
entity->anim[animId].currDuration = anim->frameDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entity_addGenericMob(MemoryArena *arena, AssetManager *assetManager,
|
||||||
|
World *world, v2 pos)
|
||||||
|
{
|
||||||
|
#ifdef DENGINE_DEBUG
|
||||||
|
DEBUG_LOG("Mob entity spawned");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Entity *hero = &world->entities[world->heroIndex];
|
||||||
|
|
||||||
|
v2 size = V2(58.0f, 98.0f);
|
||||||
|
enum EntityType type = entitytype_mob;
|
||||||
|
enum Direction dir = direction_west;
|
||||||
|
Texture *tex = asset_getTexture(assetManager, texlist_hero);
|
||||||
|
b32 collides = TRUE;
|
||||||
|
Entity *mob = entity_add(arena, world, pos, size, type, dir, tex, collides);
|
||||||
|
|
||||||
|
/* Populate mob animation references */
|
||||||
|
entity_addAnim(assetManager, mob, animlist_hero_idle);
|
||||||
|
entity_addAnim(assetManager, mob, animlist_hero_walk);
|
||||||
|
entity_addAnim(assetManager, mob, animlist_hero_wave);
|
||||||
|
entity_addAnim(assetManager, mob, animlist_hero_battlePose);
|
||||||
|
entity_addAnim(assetManager, mob, animlist_hero_tackle);
|
||||||
|
mob->currAnimId = animlist_hero_idle;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity *entity_add(MemoryArena *arena, World *world, v2 pos, v2 size,
|
||||||
|
enum EntityType type, enum Direction direction,
|
||||||
|
Texture *tex, b32 collides)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef DENGINE_DEBUG
|
||||||
|
ASSERT(world);
|
||||||
|
ASSERT(world->freeEntityIndex < world->maxEntities);
|
||||||
|
ASSERT(type < entitytype_count);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Entity entity = {0};
|
||||||
|
entity.id = world->uniqueIdAccumulator++;
|
||||||
|
entity.pos = pos;
|
||||||
|
entity.hitboxSize = size;
|
||||||
|
entity.renderSize = size;
|
||||||
|
entity.type = type;
|
||||||
|
entity.direction = direction;
|
||||||
|
entity.tex = tex;
|
||||||
|
entity.collides = collides;
|
||||||
|
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case entitytype_hero:
|
||||||
|
entity.stats = PLATFORM_MEM_ALLOC(arena, 1, EntityStats);
|
||||||
|
entity.stats->maxHealth = 100;
|
||||||
|
entity.stats->health = entity.stats->maxHealth;
|
||||||
|
entity.stats->actionRate = 100;
|
||||||
|
entity.stats->actionTimer = entity.stats->actionRate;
|
||||||
|
entity.stats->actionSpdMul = 100;
|
||||||
|
entity.stats->entityIdToAttack = -1;
|
||||||
|
entity.stats->queuedAttack = entityattack_invalid;
|
||||||
|
entity.state = entitystate_idle;
|
||||||
|
break;
|
||||||
|
case entitytype_mob:
|
||||||
|
{
|
||||||
|
entity.stats = PLATFORM_MEM_ALLOC(arena, 1, EntityStats);
|
||||||
|
entity.stats->maxHealth = 100;
|
||||||
|
entity.stats->health = entity.stats->maxHealth;
|
||||||
|
entity.stats->actionRate = 100;
|
||||||
|
entity.stats->actionTimer = entity.stats->actionRate;
|
||||||
|
entity.stats->actionSpdMul = 100;
|
||||||
|
entity.stats->entityIdToAttack = -1;
|
||||||
|
entity.stats->queuedAttack = entityattack_invalid;
|
||||||
|
entity.state = entitystate_idle;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
world->entities[world->freeEntityIndex++] = entity;
|
||||||
|
Entity *result = &world->entities[world->freeEntityIndex-1];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entity_delete(MemoryArena *arena, World *world, i32 entityIndex)
|
||||||
|
{
|
||||||
|
Entity *entity = &world->entities[entityIndex];
|
||||||
|
PLATFORM_MEM_FREE(arena, entity->stats, sizeof(EntityStats));
|
||||||
|
|
||||||
|
// TODO(doyle): Inefficient shuffle down all elements
|
||||||
|
for (i32 i = entityIndex; i < world->freeEntityIndex-1; i++)
|
||||||
|
world->entities[i] = world->entities[i+1];
|
||||||
|
|
||||||
|
world->freeEntityIndex--;
|
||||||
|
}
|
@ -1,8 +1,9 @@
|
|||||||
#include "WorldTraveller/WorldTraveller.h"
|
#include "WorldTraveller/WorldTraveller.h"
|
||||||
|
|
||||||
#include "Dengine/Debug.h"
|
|
||||||
#include "Dengine/Platform.h"
|
|
||||||
#include "Dengine/Audio.h"
|
#include "Dengine/Audio.h"
|
||||||
|
#include "Dengine/Debug.h"
|
||||||
|
#include "Dengine/Entity.h"
|
||||||
|
#include "Dengine/Platform.h"
|
||||||
|
|
||||||
enum State
|
enum State
|
||||||
{
|
{
|
||||||
@ -11,82 +12,12 @@ enum State
|
|||||||
state_win,
|
state_win,
|
||||||
};
|
};
|
||||||
|
|
||||||
INTERNAL Entity *getHeroEntity(World *world)
|
Entity *getHeroEntity(World *world)
|
||||||
{
|
{
|
||||||
Entity *result = &world->entities[world->heroIndex];
|
Entity *result = &world->entities[world->heroIndex];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL Entity *addEntity(MemoryArena *arena, World *world, v2 pos, v2 size,
|
|
||||||
enum EntityType type, enum Direction direction,
|
|
||||||
Texture *tex, b32 collides)
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef DENGINE_DEBUG
|
|
||||||
ASSERT(world);
|
|
||||||
ASSERT(world->freeEntityIndex < world->maxEntities);
|
|
||||||
ASSERT(type < entitytype_count);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Entity entity = {0};
|
|
||||||
entity.id = world->uniqueIdAccumulator++;
|
|
||||||
entity.pos = pos;
|
|
||||||
entity.hitboxSize = size;
|
|
||||||
entity.renderSize = size;
|
|
||||||
entity.type = type;
|
|
||||||
entity.direction = direction;
|
|
||||||
entity.tex = tex;
|
|
||||||
entity.collides = collides;
|
|
||||||
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case entitytype_hero:
|
|
||||||
entity.stats = PLATFORM_MEM_ALLOC(arena, 1, EntityStats);
|
|
||||||
entity.stats->maxHealth = 100;
|
|
||||||
entity.stats->health = entity.stats->maxHealth;
|
|
||||||
entity.stats->actionRate = 100;
|
|
||||||
entity.stats->actionTimer = entity.stats->actionRate;
|
|
||||||
entity.stats->actionSpdMul = 100;
|
|
||||||
entity.stats->entityIdToAttack = -1;
|
|
||||||
entity.stats->queuedAttack = entityattack_invalid;
|
|
||||||
entity.state = entitystate_idle;
|
|
||||||
break;
|
|
||||||
case entitytype_mob:
|
|
||||||
{
|
|
||||||
entity.stats = PLATFORM_MEM_ALLOC(arena, 1, EntityStats);
|
|
||||||
entity.stats->maxHealth = 100;
|
|
||||||
entity.stats->health = entity.stats->maxHealth;
|
|
||||||
entity.stats->actionRate = 100;
|
|
||||||
entity.stats->actionTimer = entity.stats->actionRate;
|
|
||||||
entity.stats->actionSpdMul = 100;
|
|
||||||
entity.stats->entityIdToAttack = -1;
|
|
||||||
entity.stats->queuedAttack = entityattack_invalid;
|
|
||||||
entity.state = entitystate_idle;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
world->entities[world->freeEntityIndex++] = entity;
|
|
||||||
Entity *result = &world->entities[world->freeEntityIndex-1];
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL void deleteEntity(MemoryArena *arena, World *world, i32 entityIndex)
|
|
||||||
{
|
|
||||||
Entity *entity = &world->entities[entityIndex];
|
|
||||||
PLATFORM_MEM_FREE(arena, entity->stats, sizeof(EntityStats));
|
|
||||||
|
|
||||||
// TODO(doyle): Inefficient shuffle down all elements
|
|
||||||
for (i32 i = entityIndex; i < world->freeEntityIndex-1; i++)
|
|
||||||
world->entities[i] = world->entities[i+1];
|
|
||||||
|
|
||||||
world->freeEntityIndex--;
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL void rendererInit(GameState *state, v2 windowSize)
|
INTERNAL void rendererInit(GameState *state, v2 windowSize)
|
||||||
{
|
{
|
||||||
AssetManager *assetManager = &state->assetManager;
|
AssetManager *assetManager = &state->assetManager;
|
||||||
@ -126,40 +57,6 @@ INTERNAL void rendererInit(GameState *state, v2 windowSize)
|
|||||||
GL_CHECK_ERROR();
|
GL_CHECK_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void addAnim(AssetManager *assetManager, i32 animId, Entity *entity)
|
|
||||||
{
|
|
||||||
Animation *anim = asset_getAnim(assetManager, animId);
|
|
||||||
entity->anim[animId].anim = anim;
|
|
||||||
entity->anim[animId].currFrame = 0;
|
|
||||||
entity->anim[animId].currDuration = anim->frameDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL void addGenericMob(MemoryArena *arena, AssetManager *assetManager,
|
|
||||||
World *world, v2 pos)
|
|
||||||
{
|
|
||||||
#ifdef DENGINE_DEBUG
|
|
||||||
DEBUG_LOG("Mob entity spawned");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Entity *hero = &world->entities[world->heroIndex];
|
|
||||||
|
|
||||||
v2 size = V2(58.0f, 98.0f);
|
|
||||||
enum EntityType type = entitytype_mob;
|
|
||||||
enum Direction dir = direction_west;
|
|
||||||
Texture *tex = asset_getTexture(assetManager, texlist_hero);
|
|
||||||
b32 collides = TRUE;
|
|
||||||
Entity *mob = addEntity(arena, world, pos, size, type, dir, tex, collides);
|
|
||||||
|
|
||||||
/* Populate mob animation references */
|
|
||||||
addAnim(assetManager, animlist_hero_idle, mob);
|
|
||||||
addAnim(assetManager, animlist_hero_walk, mob);
|
|
||||||
addAnim(assetManager, animlist_hero_wave, mob);
|
|
||||||
addAnim(assetManager, animlist_hero_battlePose, mob);
|
|
||||||
addAnim(assetManager, animlist_hero_tackle, mob);
|
|
||||||
mob->currAnimId = animlist_hero_idle;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(doyle): Remove and implement own random generator!
|
// TODO(doyle): Remove and implement own random generator!
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -345,10 +242,10 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize)
|
|||||||
enum Direction dir = direction_null;
|
enum Direction dir = direction_null;
|
||||||
Texture *tex = asset_getTexture(assetManager, world->texType);
|
Texture *tex = asset_getTexture(assetManager, world->texType);
|
||||||
b32 collides = FALSE;
|
b32 collides = FALSE;
|
||||||
Entity *tile = addEntity(arena, world, pos, size, type, dir,
|
Entity *tile = entity_add(arena, world, pos, size, type, dir,
|
||||||
tex, collides);
|
tex, collides);
|
||||||
|
|
||||||
addAnim(assetManager, animlist_terrain, tile);
|
entity_addAnim(assetManager, tile, animlist_terrain);
|
||||||
tile->currAnimId = animlist_terrain;
|
tile->currAnimId = animlist_terrain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -366,11 +263,11 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize)
|
|||||||
Texture *tex = NULL;
|
Texture *tex = NULL;
|
||||||
b32 collides = FALSE;
|
b32 collides = FALSE;
|
||||||
Entity *soundscape =
|
Entity *soundscape =
|
||||||
addEntity(arena, world, pos, size, type, dir, tex, collides);
|
entity_add(arena, world, pos, size, type, dir, tex, collides);
|
||||||
|
|
||||||
world->soundscape = soundscape;
|
world->soundscape = soundscape;
|
||||||
soundscape->audio = PLATFORM_MEM_ALLOC(arena, 1, AudioRenderer);
|
soundscape->audioRenderer = PLATFORM_MEM_ALLOC(arena, 1, AudioRenderer);
|
||||||
soundscape->audio->sourceIndex = AUDIO_SOURCE_UNASSIGNED;
|
soundscape->audioRenderer->sourceIndex = AUDIO_SOURCE_UNASSIGNED;
|
||||||
|
|
||||||
/* Init hero entity */
|
/* Init hero entity */
|
||||||
world->heroIndex = world->freeEntityIndex;
|
world->heroIndex = world->freeEntityIndex;
|
||||||
@ -381,14 +278,14 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize)
|
|||||||
dir = direction_east;
|
dir = direction_east;
|
||||||
tex = asset_getTexture(assetManager, texlist_hero);
|
tex = asset_getTexture(assetManager, texlist_hero);
|
||||||
collides = TRUE;
|
collides = TRUE;
|
||||||
Entity *hero = addEntity(arena, world, pos, size, type, dir, tex, collides);
|
Entity *hero = entity_add(arena, world, pos, size, type, dir, tex, collides);
|
||||||
|
|
||||||
/* Populate hero animation references */
|
/* Populate hero animation references */
|
||||||
addAnim(assetManager, animlist_hero_idle, hero);
|
entity_addAnim(assetManager, hero, animlist_hero_idle);
|
||||||
addAnim(assetManager, animlist_hero_walk, hero);
|
entity_addAnim(assetManager, hero, animlist_hero_walk);
|
||||||
addAnim(assetManager, animlist_hero_wave, hero);
|
entity_addAnim(assetManager, hero, animlist_hero_wave);
|
||||||
addAnim(assetManager, animlist_hero_battlePose, hero);
|
entity_addAnim(assetManager, hero, animlist_hero_battlePose);
|
||||||
addAnim(assetManager, animlist_hero_tackle, hero);
|
entity_addAnim(assetManager, hero, animlist_hero_tackle);
|
||||||
hero->currAnimId = animlist_hero_idle;
|
hero->currAnimId = animlist_hero_idle;
|
||||||
|
|
||||||
/* Create a NPC */
|
/* Create a NPC */
|
||||||
@ -398,16 +295,16 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize)
|
|||||||
dir = direction_null;
|
dir = direction_null;
|
||||||
tex = hero->tex;
|
tex = hero->tex;
|
||||||
collides = FALSE;
|
collides = FALSE;
|
||||||
Entity *npc = addEntity(arena, world, pos, size, type, dir, tex, collides);
|
Entity *npc = entity_add(arena, world, pos, size, type, dir, tex, collides);
|
||||||
|
|
||||||
/* Populate npc animation references */
|
/* Populate npc animation references */
|
||||||
addAnim(assetManager, animlist_hero_wave, npc);
|
entity_addAnim(assetManager, npc, animlist_hero_wave);
|
||||||
npc->currAnimId = animlist_hero_wave;
|
npc->currAnimId = animlist_hero_wave;
|
||||||
|
|
||||||
/* Create a Mob */
|
/* Create a Mob */
|
||||||
pos = V2(renderer->size.w - (renderer->size.w / 3.0f),
|
pos = V2(renderer->size.w - (renderer->size.w / 3.0f),
|
||||||
CAST(f32) state->tileSize);
|
CAST(f32) state->tileSize);
|
||||||
addGenericMob(arena, assetManager, world, pos);
|
entity_addGenericMob(arena, assetManager, world, pos);
|
||||||
#ifdef DENGINE_DEBUG
|
#ifdef DENGINE_DEBUG
|
||||||
DEBUG_LOG("World populated");
|
DEBUG_LOG("World populated");
|
||||||
#endif
|
#endif
|
||||||
@ -415,23 +312,6 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize)
|
|||||||
srand(CAST(u32)(time(NULL)));
|
srand(CAST(u32)(time(NULL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL inline void setActiveEntityAnim(Entity *entity,
|
|
||||||
enum AnimList animId)
|
|
||||||
{
|
|
||||||
#ifdef DENGINE_DEBUG
|
|
||||||
ASSERT(animId < animlist_count);
|
|
||||||
ASSERT(entity->anim[animId].anim);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Reset current anim data */
|
|
||||||
EntityAnim_ *currAnim = &entity->anim[entity->currAnimId];
|
|
||||||
currAnim->currDuration = currAnim->anim->frameDuration;
|
|
||||||
currAnim->currFrame = 0;
|
|
||||||
|
|
||||||
/* Set entity active animation */
|
|
||||||
entity->currAnimId = animId;
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL inline v4 getEntityScreenRect(Entity entity)
|
INTERNAL inline v4 getEntityScreenRect(Entity entity)
|
||||||
{
|
{
|
||||||
v4 result = math_getRect(entity.pos, entity.hitboxSize);
|
v4 result = math_getRect(entity.pos, entity.hitboxSize);
|
||||||
@ -503,7 +383,8 @@ INTERNAL void parseInput(GameState *state, const f32 dt)
|
|||||||
f32 xModifier = 5.0f - CAST(f32)(rand() % 3);
|
f32 xModifier = 5.0f - CAST(f32)(rand() % 3);
|
||||||
|
|
||||||
v2 pos = V2(renderer->size.w - (renderer->size.w / xModifier), yPos);
|
v2 pos = V2(renderer->size.w - (renderer->size.w / xModifier), yPos);
|
||||||
addGenericMob(&state->arena, &state->assetManager, world, pos);
|
entity_addGenericMob(&state->arena, &state->assetManager, world,
|
||||||
|
pos);
|
||||||
spaceBarWasDown = TRUE;
|
spaceBarWasDown = TRUE;
|
||||||
}
|
}
|
||||||
else if (!state->keys[GLFW_KEY_SPACE])
|
else if (!state->keys[GLFW_KEY_SPACE])
|
||||||
@ -522,12 +403,12 @@ INTERNAL void parseInput(GameState *state, const f32 dt)
|
|||||||
hero->dPos = V2(0.0f, 0.0f);
|
hero->dPos = V2(0.0f, 0.0f);
|
||||||
if (hero->currAnimId == animlist_hero_walk)
|
if (hero->currAnimId == animlist_hero_walk)
|
||||||
{
|
{
|
||||||
setActiveEntityAnim(hero, animlist_hero_idle);
|
entity_setActiveAnim(hero, animlist_hero_idle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (hero->currAnimId == animlist_hero_idle)
|
else if (hero->currAnimId == animlist_hero_idle)
|
||||||
{
|
{
|
||||||
setActiveEntityAnim(hero, animlist_hero_walk);
|
entity_setActiveAnim(hero, animlist_hero_walk);
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 heroSpeed = 6.2f * METERS_TO_PIXEL;
|
f32 heroSpeed = 6.2f * METERS_TO_PIXEL;
|
||||||
@ -598,39 +479,6 @@ INTERNAL void parseInput(GameState *state, const f32 dt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void updateEntityAnim(Entity *entity, f32 dt)
|
|
||||||
{
|
|
||||||
if (!entity->tex) return;
|
|
||||||
|
|
||||||
// TODO(doyle): Recheck why we have this twice
|
|
||||||
EntityAnim_ *entityAnim = &entity->anim[entity->currAnimId];
|
|
||||||
Animation anim = *entityAnim->anim;
|
|
||||||
i32 frameIndex = anim.frameIndex[entityAnim->currFrame];
|
|
||||||
v4 texRect = anim.atlas->texRect[frameIndex];
|
|
||||||
|
|
||||||
entityAnim->currDuration -= dt;
|
|
||||||
if (entityAnim->currDuration <= 0.0f)
|
|
||||||
{
|
|
||||||
entityAnim->currFrame++;
|
|
||||||
entityAnim->currFrame = entityAnim->currFrame % anim.numFrames;
|
|
||||||
frameIndex = entityAnim->anim->frameIndex[entityAnim->currFrame];
|
|
||||||
texRect = anim.atlas->texRect[frameIndex];
|
|
||||||
entityAnim->currDuration = anim.frameDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(doyle): If humanoid entity, let animation dictate render size which
|
|
||||||
// may exceed the hitbox size of the entity
|
|
||||||
switch (entity->type)
|
|
||||||
{
|
|
||||||
case entitytype_hero:
|
|
||||||
case entitytype_mob:
|
|
||||||
case entitytype_npc:
|
|
||||||
entity->renderSize = math_getRectSize(texRect);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL v4 createCameraBounds(World *world, v2 size)
|
INTERNAL v4 createCameraBounds(World *world, v2 size)
|
||||||
{
|
{
|
||||||
v4 result = math_getRect(world->cameraPos, size);
|
v4 result = math_getRect(world->cameraPos, size);
|
||||||
@ -723,7 +571,7 @@ INTERNAL inline void updateWorldBattleEntities(World *world, Entity *entity,
|
|||||||
INTERNAL inline void resetEntityState(World *world, Entity *entity)
|
INTERNAL inline void resetEntityState(World *world, Entity *entity)
|
||||||
{
|
{
|
||||||
updateWorldBattleEntities(world, entity, ENTITY_NOT_IN_BATTLE);
|
updateWorldBattleEntities(world, entity, ENTITY_NOT_IN_BATTLE);
|
||||||
setActiveEntityAnim(entity, animlist_hero_idle);
|
entity_setActiveAnim(entity, animlist_hero_idle);
|
||||||
entity->stats->busyDuration = 0;
|
entity->stats->busyDuration = 0;
|
||||||
entity->stats->actionTimer = entity->stats->actionRate;
|
entity->stats->actionTimer = entity->stats->actionRate;
|
||||||
entity->stats->queuedAttack = entityattack_invalid;
|
entity->stats->queuedAttack = entityattack_invalid;
|
||||||
@ -744,7 +592,7 @@ INTERNAL void beginAttack(World *world, Entity *attacker)
|
|||||||
f32 busyDuration = attackAnim.anim->frameDuration *
|
f32 busyDuration = attackAnim.anim->frameDuration *
|
||||||
CAST(f32) attackAnim.anim->numFrames;
|
CAST(f32) attackAnim.anim->numFrames;
|
||||||
attacker->stats->busyDuration = busyDuration;
|
attacker->stats->busyDuration = busyDuration;
|
||||||
setActiveEntityAnim(attacker, animlist_hero_tackle);
|
entity_setActiveAnim(attacker, animlist_hero_tackle);
|
||||||
if (attacker->direction == direction_east)
|
if (attacker->direction == direction_east)
|
||||||
attacker->dPos.x += (1.0f * METERS_TO_PIXEL);
|
attacker->dPos.x += (1.0f * METERS_TO_PIXEL);
|
||||||
else
|
else
|
||||||
@ -859,7 +707,7 @@ INTERNAL void entityStateSwitch(World *world, Entity *entity,
|
|||||||
// attacking it since there's no check before attack if entity is idle
|
// attacking it since there's no check before attack if entity is idle
|
||||||
// or not (i.e. has moved out of frame last frame).
|
// or not (i.e. has moved out of frame last frame).
|
||||||
case entitystate_dead:
|
case entitystate_dead:
|
||||||
setActiveEntityAnim(entity, animlist_hero_idle);
|
entity_setActiveAnim(entity, animlist_hero_idle);
|
||||||
entity->stats->busyDuration = 0;
|
entity->stats->busyDuration = 0;
|
||||||
entity->stats->actionTimer = entity->stats->actionRate;
|
entity->stats->actionTimer = entity->stats->actionRate;
|
||||||
entity->stats->queuedAttack = entityattack_invalid;
|
entity->stats->queuedAttack = entityattack_invalid;
|
||||||
@ -896,7 +744,7 @@ INTERNAL void entityStateSwitch(World *world, Entity *entity,
|
|||||||
{
|
{
|
||||||
case entitystate_battle:
|
case entitystate_battle:
|
||||||
endAttack(world, entity);
|
endAttack(world, entity);
|
||||||
setActiveEntityAnim(entity, animlist_hero_battlePose);
|
entity_setActiveAnim(entity, animlist_hero_battlePose);
|
||||||
entity->stats->actionTimer = entity->stats->actionRate;
|
entity->stats->actionTimer = entity->stats->actionRate;
|
||||||
entity->stats->busyDuration = 0;
|
entity->stats->busyDuration = 0;
|
||||||
break;
|
break;
|
||||||
@ -956,9 +804,9 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
{
|
{
|
||||||
Entity *const entity = &world->entities[i];
|
Entity *const entity = &world->entities[i];
|
||||||
|
|
||||||
if (entity->audio)
|
if (entity->audioRenderer)
|
||||||
{
|
{
|
||||||
AudioRenderer *audioRenderer = entity->audio;
|
AudioRenderer *audioRenderer = entity->audioRenderer;
|
||||||
if (world->numEntitiesInBattle > 0)
|
if (world->numEntitiesInBattle > 0)
|
||||||
{
|
{
|
||||||
AudioVorbis *battleTheme =
|
AudioVorbis *battleTheme =
|
||||||
@ -981,7 +829,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
audio_updateAndPlay(&state->audioManager, entity->audio);
|
audio_updateAndPlay(&state->audioManager, entity->audioRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity->state == entitystate_dead)
|
if (entity->state == entitystate_dead)
|
||||||
@ -1002,7 +850,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
// an entity dies
|
// an entity dies
|
||||||
#if 1
|
#if 1
|
||||||
i32 entityIndexInArray = i;
|
i32 entityIndexInArray = i;
|
||||||
deleteEntity(&state->arena, world, entityIndexInArray);
|
entity_delete(&state->arena, world, entityIndexInArray);
|
||||||
|
|
||||||
// TODO(doyle): DeleteEntity moves elements down 1, so account for i
|
// TODO(doyle): DeleteEntity moves elements down 1, so account for i
|
||||||
i--;
|
i--;
|
||||||
@ -1113,7 +961,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
*/
|
*/
|
||||||
if (entity->tex)
|
if (entity->tex)
|
||||||
{
|
{
|
||||||
updateEntityAnim(entity, dt);
|
entity_updateAnim(entity, dt);
|
||||||
/* Calculate region to render */
|
/* Calculate region to render */
|
||||||
renderer_entity(renderer, cameraBounds, entity, V2(0, 0), 0,
|
renderer_entity(renderer, cameraBounds, entity, V2(0, 0), 0,
|
||||||
V4(1, 1, 1, 1));
|
V4(1, 1, 1, 1));
|
||||||
@ -1138,7 +986,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
{
|
{
|
||||||
hero->state = entitystate_idle;
|
hero->state = entitystate_idle;
|
||||||
world->entityIdInBattle[hero->id] = FALSE;
|
world->entityIdInBattle[hero->id] = FALSE;
|
||||||
setActiveEntityAnim(hero, animlist_hero_idle);
|
entity_setActiveAnim(hero, animlist_hero_idle);
|
||||||
}
|
}
|
||||||
hero->stats->entityIdToAttack = -1;
|
hero->stats->entityIdToAttack = -1;
|
||||||
hero->stats->actionTimer = hero->stats->actionRate;
|
hero->stats->actionTimer = hero->stats->actionRate;
|
||||||
|
@ -3,9 +3,12 @@
|
|||||||
|
|
||||||
#include "Dengine/Common.h"
|
#include "Dengine/Common.h"
|
||||||
#include "Dengine/Math.h"
|
#include "Dengine/Math.h"
|
||||||
#include "Dengine/Texture.h"
|
|
||||||
|
|
||||||
|
typedef struct AssetManager AssetManager;
|
||||||
typedef struct AudioRenderer AudioRenderer;
|
typedef struct AudioRenderer AudioRenderer;
|
||||||
|
typedef struct Texture Texture;
|
||||||
|
typedef struct Animation Animation;
|
||||||
|
typedef struct World World;
|
||||||
|
|
||||||
enum Direction
|
enum Direction
|
||||||
{
|
{
|
||||||
@ -91,7 +94,17 @@ typedef struct Entity
|
|||||||
enum AnimList currAnimId;
|
enum AnimList currAnimId;
|
||||||
|
|
||||||
EntityStats *stats;
|
EntityStats *stats;
|
||||||
AudioRenderer *audio;
|
AudioRenderer *audioRenderer;
|
||||||
|
i32 numAudioRenderers;
|
||||||
} Entity;
|
} Entity;
|
||||||
|
|
||||||
|
void entity_setActiveAnim(Entity *entity, enum AnimList animId);
|
||||||
|
void entity_updateAnim(Entity *entity, f32 dt);
|
||||||
|
void entity_addAnim(AssetManager *assetManager, Entity *entity, i32 animId);
|
||||||
|
void entity_addGenericMob(MemoryArena *arena, AssetManager *assetManager, World *world,
|
||||||
|
v2 pos);
|
||||||
|
Entity *entity_add(MemoryArena *arena, World *world, v2 pos, v2 size,
|
||||||
|
enum EntityType type, enum Direction direction, Texture *tex,
|
||||||
|
b32 collides);
|
||||||
|
void entity_delete(MemoryArena *arena, World *world, i32 entityIndex);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user