Add support for more attack-animations
Exploratory code to determine how to architect the engine for increasing requirements in game play.
This commit is contained in:
parent
fc6f6e086f
commit
5c4f493979
@ -62,9 +62,6 @@ inline char *debug_entityattack_string(i32 val)
|
|||||||
char *string;
|
char *string;
|
||||||
switch(val)
|
switch(val)
|
||||||
{
|
{
|
||||||
case entityattack_tackle:
|
|
||||||
string = "EntityAttack_Tackle";
|
|
||||||
break;
|
|
||||||
case entityattack_count:
|
case entityattack_count:
|
||||||
string = "EntityAttack_Count (Error!)";
|
string = "EntityAttack_Count (Error!)";
|
||||||
break;
|
break;
|
||||||
|
24
src/Entity.c
24
src/Entity.c
@ -3,12 +3,14 @@
|
|||||||
#include "Dengine/Platform.h"
|
#include "Dengine/Platform.h"
|
||||||
#include "Dengine/WorldTraveller.h"
|
#include "Dengine/WorldTraveller.h"
|
||||||
|
|
||||||
void entity_setActiveAnim(Entity *const entity, const char *const animName)
|
void entity_setActiveAnim(EventQueue *eventQueue, Entity *const entity,
|
||||||
|
const char *const animName)
|
||||||
{
|
{
|
||||||
/* Reset current anim data */
|
/* Reset current anim data */
|
||||||
EntityAnim *currEntityAnim = &entity->animList[entity->currAnimId];
|
EntityAnim *currEntityAnim = &entity->animList[entity->currAnimId];
|
||||||
currEntityAnim->currDuration = currEntityAnim->anim->frameDuration;
|
currEntityAnim->currDuration = currEntityAnim->anim->frameDuration;
|
||||||
currEntityAnim->currFrame = 0;
|
currEntityAnim->currFrame = 0;
|
||||||
|
currEntityAnim->timesCompleted = 0;
|
||||||
|
|
||||||
/* Set entity active animation */
|
/* Set entity active animation */
|
||||||
for (i32 i = 0; i < ARRAY_COUNT(entity->animList); i++)
|
for (i32 i = 0; i < ARRAY_COUNT(entity->animList); i++)
|
||||||
@ -24,6 +26,9 @@ void entity_setActiveAnim(Entity *const entity, const char *const animName)
|
|||||||
newEntityAnim->currDuration =
|
newEntityAnim->currDuration =
|
||||||
newEntityAnim->anim->frameDuration;
|
newEntityAnim->anim->frameDuration;
|
||||||
newEntityAnim->currFrame = 0;
|
newEntityAnim->currFrame = 0;
|
||||||
|
|
||||||
|
worldTraveller_registerEvent(eventQueue, eventtype_start_anim,
|
||||||
|
newEntityAnim);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -32,7 +37,8 @@ void entity_setActiveAnim(Entity *const entity, const char *const animName)
|
|||||||
DEBUG_LOG("Entity does not have access to desired anim");
|
DEBUG_LOG("Entity does not have access to desired anim");
|
||||||
}
|
}
|
||||||
|
|
||||||
void entity_updateAnim(Entity *const entity, const f32 dt)
|
void entity_updateAnim(EventQueue *eventQueue, Entity *const entity,
|
||||||
|
const f32 dt)
|
||||||
{
|
{
|
||||||
if (!entity->tex)
|
if (!entity->tex)
|
||||||
return;
|
return;
|
||||||
@ -45,6 +51,13 @@ void entity_updateAnim(Entity *const entity, const f32 dt)
|
|||||||
{
|
{
|
||||||
currEntityAnim->currFrame++;
|
currEntityAnim->currFrame++;
|
||||||
currEntityAnim->currFrame = currEntityAnim->currFrame % anim->numFrames;
|
currEntityAnim->currFrame = currEntityAnim->currFrame % anim->numFrames;
|
||||||
|
if (currEntityAnim->currFrame == 0)
|
||||||
|
{
|
||||||
|
worldTraveller_registerEvent(eventQueue, eventtype_end_anim,
|
||||||
|
currEntityAnim);
|
||||||
|
currEntityAnim->timesCompleted++;
|
||||||
|
}
|
||||||
|
|
||||||
currEntityAnim->currDuration = anim->frameDuration;
|
currEntityAnim->currDuration = anim->frameDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +151,7 @@ Entity *const entity_add(MemoryArena *const arena, World *const world,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case entitytype_projectile:
|
case entitytype_projectile:
|
||||||
|
case entitytype_attackObject:
|
||||||
entity.stats = PLATFORM_MEM_ALLOC(arena, 1, EntityStats);
|
entity.stats = PLATFORM_MEM_ALLOC(arena, 1, EntityStats);
|
||||||
entity.stats->maxHealth = 100;
|
entity.stats->maxHealth = 100;
|
||||||
entity.stats->health = entity.stats->maxHealth;
|
entity.stats->health = entity.stats->maxHealth;
|
||||||
|
@ -13,37 +13,14 @@ enum State
|
|||||||
state_win,
|
state_win,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EventType
|
|
||||||
{
|
|
||||||
eventtype_null = 0,
|
|
||||||
eventtype_start_attack,
|
|
||||||
eventtype_end_attack,
|
|
||||||
eventtype_start_anim,
|
|
||||||
eventtype_end_anim,
|
|
||||||
eventtype_entity_died,
|
|
||||||
eventtype_count,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct Event
|
|
||||||
{
|
|
||||||
enum EventType type;
|
|
||||||
void *data;
|
|
||||||
} Event;
|
|
||||||
|
|
||||||
typedef struct EventQueue
|
|
||||||
{
|
|
||||||
Event queue[1024];
|
|
||||||
i32 numEvents;
|
|
||||||
} EventQueue;
|
|
||||||
|
|
||||||
INTERNAL Entity *getHeroEntity(World *world)
|
INTERNAL Entity *getHeroEntity(World *world)
|
||||||
{
|
{
|
||||||
Entity *result = &world->entities[entity_getIndex(world, world->heroId)];
|
Entity *result = &world->entities[entity_getIndex(world, world->heroId)];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void addGenericMob(MemoryArena *arena, AssetManager *assetManager,
|
INTERNAL void addGenericMob(EventQueue *eventQueue, MemoryArena *arena,
|
||||||
World *world, v2 pos)
|
AssetManager *assetManager, World *world, v2 pos)
|
||||||
{
|
{
|
||||||
#ifdef DENGINE_DEBUG
|
#ifdef DENGINE_DEBUG
|
||||||
DEBUG_LOG("Mob entity spawned");
|
DEBUG_LOG("Mob entity spawned");
|
||||||
@ -71,8 +48,17 @@ INTERNAL void addGenericMob(MemoryArena *arena, AssetManager *assetManager,
|
|||||||
entity_addAnim(assetManager, mob, "claudeIdle");
|
entity_addAnim(assetManager, mob, "claudeIdle");
|
||||||
entity_addAnim(assetManager, mob, "claudeRun");
|
entity_addAnim(assetManager, mob, "claudeRun");
|
||||||
entity_addAnim(assetManager, mob, "claudeBattleIdle");
|
entity_addAnim(assetManager, mob, "claudeBattleIdle");
|
||||||
|
|
||||||
entity_addAnim(assetManager, mob, "claudeAttack");
|
entity_addAnim(assetManager, mob, "claudeAttack");
|
||||||
entity_setActiveAnim(mob, "claudeIdle");
|
entity_addAnim(assetManager, mob, "claudeAttackUp");
|
||||||
|
entity_addAnim(assetManager, mob, "claudeAttackDown");
|
||||||
|
|
||||||
|
entity_addAnim(assetManager, mob, "claudeAirSlash");
|
||||||
|
entity_addAnim(assetManager, mob, "claudeDragonHowl");
|
||||||
|
entity_addAnim(assetManager, mob, "claudeEnergySword");
|
||||||
|
entity_addAnim(assetManager, mob, "claudeRipperBlast");
|
||||||
|
|
||||||
|
entity_setActiveAnim(eventQueue, mob, "claudeIdle");
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void rendererInit(GameState *state, v2 windowSize)
|
INTERNAL void rendererInit(GameState *state, v2 windowSize)
|
||||||
@ -244,6 +230,95 @@ INTERNAL void assetInit(GameState *state)
|
|||||||
asset_addAnimation(assetManager, arena, "claudeAttack", claudeAtlas,
|
asset_addAnimation(assetManager, arena, "claudeAttack", claudeAtlas,
|
||||||
claudeAttack, numRects, duration);
|
claudeAttack, numRects, duration);
|
||||||
|
|
||||||
|
char *claudeAttackDown[7] = {
|
||||||
|
"ClaudeSprite_Attack_Down_01",
|
||||||
|
"ClaudeSprite_Attack_Down_02",
|
||||||
|
"ClaudeSprite_Attack_Down_03",
|
||||||
|
"ClaudeSprite_Attack_Down_04",
|
||||||
|
"ClaudeSprite_Attack_Down_05",
|
||||||
|
"ClaudeSprite_Attack_Down_06",
|
||||||
|
"ClaudeSprite_Attack_Down_07",
|
||||||
|
};
|
||||||
|
|
||||||
|
numRects = ARRAY_COUNT(claudeAttackDown);
|
||||||
|
duration = 0.1f;
|
||||||
|
asset_addAnimation(assetManager, arena, "claudeAttackDown",
|
||||||
|
claudeAtlas, claudeAttackDown, numRects,
|
||||||
|
duration);
|
||||||
|
|
||||||
|
char *claudeAttackUp[3] = {
|
||||||
|
"ClaudeSprite_Attack_Up_01",
|
||||||
|
"ClaudeSprite_Attack_Up_02",
|
||||||
|
"ClaudeSprite_Attack_Up_03",
|
||||||
|
};
|
||||||
|
|
||||||
|
numRects = ARRAY_COUNT(claudeAttackUp);
|
||||||
|
duration = 0.2f;
|
||||||
|
asset_addAnimation(assetManager, arena, "claudeAttackUp",
|
||||||
|
claudeAtlas, claudeAttackUp, numRects,
|
||||||
|
duration);
|
||||||
|
|
||||||
|
char *claudeDragonHowl[3] = {
|
||||||
|
"ClaudeSprite_Attack_DragonHowl_01",
|
||||||
|
"ClaudeSprite_Attack_DragonHowl_02",
|
||||||
|
"ClaudeSprite_Attack_DragonHowl_03",
|
||||||
|
};
|
||||||
|
|
||||||
|
numRects = ARRAY_COUNT(claudeDragonHowl);
|
||||||
|
duration = 0.2f;
|
||||||
|
asset_addAnimation(assetManager, arena, "claudeDragonHowl",
|
||||||
|
claudeAtlas, claudeDragonHowl, numRects,
|
||||||
|
duration);
|
||||||
|
|
||||||
|
char *claudeDragonHowlVfx[7] = {
|
||||||
|
"ClaudeSprite_Attack_DragonHowl_Vfx_01",
|
||||||
|
"ClaudeSprite_Attack_DragonHowl_Vfx_02",
|
||||||
|
"ClaudeSprite_Attack_DragonHowl_Vfx_03",
|
||||||
|
"ClaudeSprite_Attack_DragonHowl_Vfx_04",
|
||||||
|
"ClaudeSprite_Attack_DragonHowl_Vfx_05",
|
||||||
|
"ClaudeSprite_Attack_DragonHowl_Vfx_06",
|
||||||
|
"ClaudeSprite_Attack_DragonHowl_Vfx_07",
|
||||||
|
};
|
||||||
|
|
||||||
|
numRects = ARRAY_COUNT(claudeDragonHowlVfx);
|
||||||
|
duration = 0.1f;
|
||||||
|
asset_addAnimation(assetManager, arena, "claudeDragonHowlVfx",
|
||||||
|
claudeAtlas, claudeDragonHowlVfx, numRects,
|
||||||
|
duration);
|
||||||
|
|
||||||
|
char *claudeRipperBlast[6] = {
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_01",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_02",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_03",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_04",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_05",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_06",
|
||||||
|
};
|
||||||
|
|
||||||
|
numRects = ARRAY_COUNT(claudeRipperBlast);
|
||||||
|
duration = 0.1f;
|
||||||
|
asset_addAnimation(assetManager, arena, "claudeRipperBlast",
|
||||||
|
claudeAtlas, claudeRipperBlast, numRects,
|
||||||
|
duration);
|
||||||
|
|
||||||
|
char *claudeRipperBlastVfx[9] = {
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_Vfx_04",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_Vfx_05",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_Vfx_06",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_Vfx_07",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_Vfx_08",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_Vfx_09",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_Vfx_10",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_Vfx_11",
|
||||||
|
"ClaudeSprite_Attack_RipperBlast_Vfx_12",
|
||||||
|
};
|
||||||
|
|
||||||
|
numRects = ARRAY_COUNT(claudeRipperBlastVfx);
|
||||||
|
duration = 0.1f;
|
||||||
|
asset_addAnimation(assetManager, arena, "claudeRipperBlastVfx",
|
||||||
|
claudeAtlas, claudeRipperBlastVfx, numRects,
|
||||||
|
duration);
|
||||||
|
|
||||||
// Victory animation
|
// Victory animation
|
||||||
char *claudeVictory[8] = {"ClaudeSprite_Battle_Victory_01",
|
char *claudeVictory[8] = {"ClaudeSprite_Battle_Victory_01",
|
||||||
"ClaudeSprite_Battle_Victory_02",
|
"ClaudeSprite_Battle_Victory_02",
|
||||||
@ -318,6 +393,7 @@ INTERNAL void assetInit(GameState *state)
|
|||||||
asset_addAnimation(assetManager, arena, "claudeAttackSlashLeft",
|
asset_addAnimation(assetManager, arena, "claudeAttackSlashLeft",
|
||||||
claudeAtlas, claudeAttackSlashLeft, numRects,
|
claudeAtlas, claudeAttackSlashLeft, numRects,
|
||||||
duration);
|
duration);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -451,6 +527,7 @@ INTERNAL void entityInit(GameState *state, v2 windowSize)
|
|||||||
CAST(i32) windowSize.h / state->tileSize);
|
CAST(i32) windowSize.h / state->tileSize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
EventQueue *eventQueue = &state->eventQueue;
|
||||||
for (i32 i = 0; i < ARRAY_COUNT(state->world); i++)
|
for (i32 i = 0; i < ARRAY_COUNT(state->world); i++)
|
||||||
{
|
{
|
||||||
World *const world = &state->world[i];
|
World *const world = &state->world[i];
|
||||||
@ -488,7 +565,7 @@ INTERNAL void entityInit(GameState *state, v2 windowSize)
|
|||||||
dir, tex, collides);
|
dir, tex, collides);
|
||||||
|
|
||||||
entity_addAnim(assetManager, tile, "terrainGrass");
|
entity_addAnim(assetManager, tile, "terrainGrass");
|
||||||
entity_setActiveAnim(tile, "terrainGrass");
|
entity_setActiveAnim(eventQueue, tile, "terrainGrass");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -552,10 +629,17 @@ INTERNAL void entityInit(GameState *state, v2 windowSize)
|
|||||||
entity_addAnim(assetManager, hero, "claudeIdle");
|
entity_addAnim(assetManager, hero, "claudeIdle");
|
||||||
entity_addAnim(assetManager, hero, "claudeRun");
|
entity_addAnim(assetManager, hero, "claudeRun");
|
||||||
entity_addAnim(assetManager, hero, "claudeBattleIdle");
|
entity_addAnim(assetManager, hero, "claudeBattleIdle");
|
||||||
|
|
||||||
entity_addAnim(assetManager, hero, "claudeAttack");
|
entity_addAnim(assetManager, hero, "claudeAttack");
|
||||||
|
entity_addAnim(assetManager, hero, "claudeAttackUp");
|
||||||
|
entity_addAnim(assetManager, hero, "claudeAttackDown");
|
||||||
|
|
||||||
|
entity_addAnim(assetManager, hero, "claudeDragonHowl");
|
||||||
entity_addAnim(assetManager, hero, "claudeEnergySword");
|
entity_addAnim(assetManager, hero, "claudeEnergySword");
|
||||||
|
entity_addAnim(assetManager, hero, "claudeRipperBlast");
|
||||||
entity_addAnim(assetManager, hero, "claudeAirSlash");
|
entity_addAnim(assetManager, hero, "claudeAirSlash");
|
||||||
entity_setActiveAnim(hero, "claudeIdle");
|
|
||||||
|
entity_setActiveAnim(eventQueue, hero, "claudeIdle");
|
||||||
|
|
||||||
/* Create a NPC */
|
/* Create a NPC */
|
||||||
pos = V2(hero->pos.x * 3, CAST(f32) state->tileSize);
|
pos = V2(hero->pos.x * 3, CAST(f32) state->tileSize);
|
||||||
@ -569,12 +653,12 @@ INTERNAL void entityInit(GameState *state, v2 windowSize)
|
|||||||
|
|
||||||
/* Populate npc animation references */
|
/* Populate npc animation references */
|
||||||
entity_addAnim(assetManager, npc, "claudeVictory");
|
entity_addAnim(assetManager, npc, "claudeVictory");
|
||||||
entity_setActiveAnim(npc, "claudeVictory");
|
entity_setActiveAnim(eventQueue, npc, "claudeVictory");
|
||||||
|
|
||||||
/* 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);
|
addGenericMob(eventQueue, arena, assetManager, world, pos);
|
||||||
|
|
||||||
#ifdef DENGINE_DEBUG
|
#ifdef DENGINE_DEBUG
|
||||||
DEBUG_LOG("World populated");
|
DEBUG_LOG("World populated");
|
||||||
@ -923,17 +1007,18 @@ INTERNAL inline void updateWorldBattleEntities(World *world, Entity *entity,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(doyle): Function too vague
|
// TODO(doyle): Function too vague
|
||||||
INTERNAL inline void resetEntityState(World *world, Entity *entity)
|
INTERNAL inline void resetEntityState(EventQueue *eventQueue, World *world,
|
||||||
|
Entity *entity)
|
||||||
{
|
{
|
||||||
updateWorldBattleEntities(world, entity, ENTITY_NOT_IN_BATTLE);
|
updateWorldBattleEntities(world, entity, ENTITY_NOT_IN_BATTLE);
|
||||||
entity_setActiveAnim(entity, "claudeIdle");
|
entity_setActiveAnim(eventQueue, entity, "claudeIdle");
|
||||||
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;
|
||||||
entity->stats->entityIdToAttack = ENTITY_NULL_ID;
|
entity->stats->entityIdToAttack = ENTITY_NULL_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL registerEvent(EventQueue *eventQueue, enum EventType type, void *data)
|
void worldTraveller_registerEvent(EventQueue *eventQueue, enum EventType type, void *data)
|
||||||
{
|
{
|
||||||
#ifdef DENGINE_DEBUG
|
#ifdef DENGINE_DEBUG
|
||||||
ASSERT(eventQueue && type < eventtype_count);
|
ASSERT(eventQueue && type < eventtype_count);
|
||||||
@ -969,8 +1054,9 @@ INTERNAL void entityStateSwitch(EventQueue *eventQueue, World *world,
|
|||||||
// 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:
|
||||||
registerEvent(eventQueue, eventtype_entity_died, CAST(void *)entity);
|
worldTraveller_registerEvent(eventQueue, eventtype_entity_died,
|
||||||
entity_setActiveAnim(entity, "claudeIdle");
|
CAST(void *) entity);
|
||||||
|
entity_setActiveAnim(eventQueue, entity, "claudeIdle");
|
||||||
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;
|
||||||
@ -993,11 +1079,12 @@ INTERNAL void entityStateSwitch(EventQueue *eventQueue, World *world,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case entitystate_idle:
|
case entitystate_idle:
|
||||||
resetEntityState(world, entity);
|
resetEntityState(eventQueue, world, entity);
|
||||||
break;
|
break;
|
||||||
case entitystate_dead:
|
case entitystate_dead:
|
||||||
registerEvent(eventQueue, eventtype_entity_died, CAST(void *)entity);
|
worldTraveller_registerEvent(eventQueue, eventtype_entity_died,
|
||||||
resetEntityState(world, entity);
|
CAST(void *) entity);
|
||||||
|
resetEntityState(eventQueue, world, entity);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef DENGINE_DEBUG
|
#ifdef DENGINE_DEBUG
|
||||||
@ -1010,17 +1097,18 @@ INTERNAL void entityStateSwitch(EventQueue *eventQueue, World *world,
|
|||||||
switch (newState)
|
switch (newState)
|
||||||
{
|
{
|
||||||
case entitystate_battle:
|
case entitystate_battle:
|
||||||
entity_setActiveAnim(entity, "claudeBattleIdle");
|
entity_setActiveAnim(eventQueue, entity, "claudeBattleIdle");
|
||||||
entity->stats->actionTimer = entity->stats->actionRate;
|
entity->stats->actionTimer = entity->stats->actionRate;
|
||||||
entity->stats->busyDuration = 0;
|
entity->stats->busyDuration = 0;
|
||||||
break;
|
break;
|
||||||
// NOTE(doyle): Entity has been forced out of an attack (out of range)
|
// NOTE(doyle): Entity has been forced out of an attack (out of range)
|
||||||
case entitystate_idle:
|
case entitystate_idle:
|
||||||
resetEntityState(world, entity);
|
resetEntityState(eventQueue, world, entity);
|
||||||
break;
|
break;
|
||||||
case entitystate_dead:
|
case entitystate_dead:
|
||||||
registerEvent(eventQueue, eventtype_entity_died, CAST(void *)entity);
|
worldTraveller_registerEvent(eventQueue, eventtype_entity_died,
|
||||||
resetEntityState(world, entity);
|
CAST(void *) entity);
|
||||||
|
resetEntityState(eventQueue, world, entity);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef DENGINE_DEBUG
|
#ifdef DENGINE_DEBUG
|
||||||
@ -1071,13 +1159,13 @@ INTERNAL void beginAttack(AssetManager *assetManager, MemoryArena *arena,
|
|||||||
entityStateSwitch(eventQueue, world, attacker, entitystate_attack);
|
entityStateSwitch(eventQueue, world, attacker, entitystate_attack);
|
||||||
switch (attacker->stats->queuedAttack)
|
switch (attacker->stats->queuedAttack)
|
||||||
{
|
{
|
||||||
case entityattack_tackle:
|
case entityattack_claudeAttack:
|
||||||
{
|
{
|
||||||
entity_setActiveAnim(attacker, "claudeAttack");
|
entity_setActiveAnim(eventQueue, attacker, "claudeAttack");
|
||||||
if (attacker->stats->weapon)
|
if (attacker->stats->weapon)
|
||||||
{
|
{
|
||||||
attacker->stats->weapon->invisible = FALSE;
|
attacker->stats->weapon->invisible = FALSE;
|
||||||
entity_setActiveAnim(attacker->stats->weapon,
|
entity_setActiveAnim(eventQueue, attacker->stats->weapon,
|
||||||
"claudeAttackSlashLeft");
|
"claudeAttackSlashLeft");
|
||||||
}
|
}
|
||||||
if (attacker->direction == direction_east)
|
if (attacker->direction == direction_east)
|
||||||
@ -1087,27 +1175,106 @@ INTERNAL void beginAttack(AssetManager *assetManager, MemoryArena *arena,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case entityattack_energySword:
|
case entityattack_claudeAttackUp:
|
||||||
{
|
{
|
||||||
entity_setActiveAnim(attacker, "claudeEnergySword");
|
entity_setActiveAnim(eventQueue, attacker, "claudeAttackUp");
|
||||||
|
if (attacker->stats->weapon)
|
||||||
|
{
|
||||||
|
attacker->stats->weapon->invisible = FALSE;
|
||||||
|
entity_setActiveAnim(eventQueue, attacker->stats->weapon,
|
||||||
|
"claudeAttackSlashLeft");
|
||||||
|
}
|
||||||
|
if (attacker->direction == direction_east)
|
||||||
|
attacker->dPos.x += (1.0f * METERS_TO_PIXEL);
|
||||||
|
else
|
||||||
|
attacker->dPos.x -= (1.0f * METERS_TO_PIXEL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case entityattack_airSlash:
|
case entityattack_claudeAttackDown:
|
||||||
{
|
{
|
||||||
entity_setActiveAnim(attacker, "claudeAirSlash");
|
entity_setActiveAnim(eventQueue, attacker, "claudeAttackDown");
|
||||||
|
if (attacker->stats->weapon)
|
||||||
|
{
|
||||||
|
attacker->stats->weapon->invisible = FALSE;
|
||||||
|
entity_setActiveAnim(eventQueue, attacker->stats->weapon,
|
||||||
|
"claudeAttackSlashLeft");
|
||||||
|
}
|
||||||
|
if (attacker->direction == direction_east)
|
||||||
|
attacker->dPos.x += (1.0f * METERS_TO_PIXEL);
|
||||||
|
else
|
||||||
|
attacker->dPos.x -= (1.0f * METERS_TO_PIXEL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case entityattack_claudeDragonHowl:
|
||||||
|
{
|
||||||
|
entity_setActiveAnim(eventQueue, attacker, "claudeDragonHowl");
|
||||||
|
f32 scale = 1.5f;
|
||||||
|
v2 size = V2(40, 40);
|
||||||
|
Entity *projectile = entity_add(
|
||||||
|
arena, world, attacker->pos, size, scale,
|
||||||
|
entitytype_projectile, attacker->direction, attacker->tex, TRUE);
|
||||||
|
|
||||||
|
projectile->collidesWith[entitytype_hero] = TRUE;
|
||||||
|
projectile->collidesWith[entitytype_mob] = TRUE;
|
||||||
|
projectile->collidesWith[attacker->type] = FALSE;
|
||||||
|
|
||||||
|
projectile->stats->entityIdToAttack = attacker->stats->entityIdToAttack;
|
||||||
|
entity_addAnim(assetManager, projectile, "claudeDragonHowlVfx");
|
||||||
|
entity_setActiveAnim(eventQueue, projectile, "claudeDragonHowlVfx");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case entityattack_claudeEnergySword:
|
||||||
|
{
|
||||||
|
entity_setActiveAnim(eventQueue, attacker, "claudeEnergySword");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case entityattack_claudeRipperBlast:
|
||||||
|
{
|
||||||
|
entity_setActiveAnim(eventQueue, attacker, "claudeRipperBlast");
|
||||||
|
f32 scale = 5.0f;
|
||||||
|
v2 size = V2(20, 20);
|
||||||
|
|
||||||
|
Entity *target = entity_get(world, attacker->stats->entityIdToAttack);
|
||||||
|
v2 targetPos = v2_add(attacker->pos, V2(100, 0));
|
||||||
|
if (target)
|
||||||
|
{
|
||||||
|
targetPos = target->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity *projectile = entity_add(
|
||||||
|
arena, world, targetPos, size, scale,
|
||||||
|
entitytype_attackObject, attacker->direction, attacker->tex, TRUE);
|
||||||
|
|
||||||
|
projectile->collidesWith[entitytype_hero] = TRUE;
|
||||||
|
projectile->collidesWith[entitytype_mob] = TRUE;
|
||||||
|
projectile->collidesWith[attacker->type] = FALSE;
|
||||||
|
|
||||||
|
projectile->stats->entityIdToAttack = attacker->stats->entityIdToAttack;
|
||||||
|
entity_addAnim(assetManager, projectile, "claudeRipperBlastVfx");
|
||||||
|
entity_setActiveAnim(eventQueue, projectile, "claudeRipperBlastVfx");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case entityattack_claudeAirSlash:
|
||||||
|
{
|
||||||
|
entity_setActiveAnim(eventQueue, attacker, "claudeAirSlash");
|
||||||
f32 scale = 1.5f;
|
f32 scale = 1.5f;
|
||||||
v2 size = V2(20, 20);
|
v2 size = V2(20, 20);
|
||||||
Entity *projectile = entity_add(
|
Entity *projectile = entity_add(
|
||||||
arena, world, attacker->pos, size, scale,
|
arena, world, attacker->pos, size, scale,
|
||||||
entitytype_projectile, attacker->direction, attacker->tex, TRUE);
|
entitytype_projectile, attacker->direction, attacker->tex, TRUE);
|
||||||
|
|
||||||
projectile->collidesWith[entitytype_hero] = FALSE;
|
projectile->collidesWith[entitytype_hero] = TRUE;
|
||||||
projectile->collidesWith[entitytype_mob] = TRUE;
|
projectile->collidesWith[entitytype_mob] = TRUE;
|
||||||
|
projectile->collidesWith[attacker->type] = FALSE;
|
||||||
|
|
||||||
projectile->stats->entityIdToAttack = attacker->stats->entityIdToAttack;
|
projectile->stats->entityIdToAttack = attacker->stats->entityIdToAttack;
|
||||||
entity_addAnim(assetManager, projectile, "claudeAirSlashVfx");
|
entity_addAnim(assetManager, projectile, "claudeAirSlashVfx");
|
||||||
entity_setActiveAnim(projectile, "claudeAirSlashVfx");
|
entity_setActiveAnim(eventQueue, projectile, "claudeAirSlashVfx");
|
||||||
|
|
||||||
v2 initialOffset = V2(size.x * 0.5f, 0);
|
v2 initialOffset = V2(size.x * 0.5f, 0);
|
||||||
f32 deltaScale = 0.3f;
|
f32 deltaScale = 0.3f;
|
||||||
@ -1128,7 +1295,7 @@ INTERNAL void beginAttack(AssetManager *assetManager, MemoryArena *arena,
|
|||||||
child->stats->entityIdToAttack =
|
child->stats->entityIdToAttack =
|
||||||
projectile->stats->entityIdToAttack;
|
projectile->stats->entityIdToAttack;
|
||||||
entity_addAnim(assetManager, child, "claudeAirSlashVfx");
|
entity_addAnim(assetManager, child, "claudeAirSlashVfx");
|
||||||
entity_setActiveAnim(child, "claudeAirSlashVfx");
|
entity_setActiveAnim(eventQueue, child, "claudeAirSlashVfx");
|
||||||
projectile->childIds[i] = child->id;
|
projectile->childIds[i] = child->id;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1159,7 +1326,9 @@ INTERNAL void endAttack(MemoryArena *arena, EventQueue *eventQueue,
|
|||||||
entityStateSwitch(eventQueue, world, attacker, entitystate_battle);
|
entityStateSwitch(eventQueue, world, attacker, entitystate_battle);
|
||||||
switch (attacker->stats->queuedAttack)
|
switch (attacker->stats->queuedAttack)
|
||||||
{
|
{
|
||||||
case entityattack_tackle:
|
case entityattack_claudeAttack:
|
||||||
|
case entityattack_claudeAttackUp:
|
||||||
|
case entityattack_claudeAttackDown:
|
||||||
// TODO(doyle): Move animation offsets out and into animation type
|
// TODO(doyle): Move animation offsets out and into animation type
|
||||||
|
|
||||||
if (attacker->stats->weapon)
|
if (attacker->stats->weapon)
|
||||||
@ -1174,16 +1343,19 @@ INTERNAL void endAttack(MemoryArena *arena, EventQueue *eventQueue,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case entityattack_airSlash:
|
case entityattack_claudeAirSlash:
|
||||||
|
case entityattack_claudeRipperBlast:
|
||||||
|
case entityattack_claudeDragonHowl:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case entityattack_energySword:
|
case entityattack_claudeEnergySword:
|
||||||
attacker->stats->health += 80;
|
attacker->stats->health += 80;
|
||||||
AttackSpec *attackSpec = PLATFORM_MEM_ALLOC(arena, 1, AttackSpec);
|
AttackSpec *attackSpec = PLATFORM_MEM_ALLOC(arena, 1, AttackSpec);
|
||||||
attackSpec->attacker = attacker;
|
attackSpec->attacker = attacker;
|
||||||
attackSpec->defender = attacker;
|
attackSpec->defender = attacker;
|
||||||
attackSpec->damage = 30;
|
attackSpec->damage = 30;
|
||||||
registerEvent(eventQueue, eventtype_end_attack, attackSpec);
|
worldTraveller_registerEvent(eventQueue, eventtype_end_attack,
|
||||||
|
attackSpec);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1236,7 +1408,8 @@ INTERNAL void endAttack(MemoryArena *arena, EventQueue *eventQueue,
|
|||||||
attackSpec->defender = defender;
|
attackSpec->defender = defender;
|
||||||
attackSpec->damage = damage;
|
attackSpec->damage = damage;
|
||||||
|
|
||||||
registerEvent(eventQueue, eventtype_end_attack, attackSpec);
|
worldTraveller_registerEvent(eventQueue, eventtype_end_attack,
|
||||||
|
attackSpec);
|
||||||
// TODO(doyle): Use attacker stats in battle equations
|
// TODO(doyle): Use attacker stats in battle equations
|
||||||
if (attacker->type == entitytype_hero)
|
if (attacker->type == entitytype_hero)
|
||||||
{
|
{
|
||||||
@ -1286,17 +1459,22 @@ INTERNAL enum EntityAttack selectBestAttack(Entity *entity)
|
|||||||
{
|
{
|
||||||
if (entity->stats->health <= 50.0f && entity->type == entitytype_hero)
|
if (entity->stats->health <= 50.0f && entity->type == entitytype_hero)
|
||||||
{
|
{
|
||||||
return entityattack_energySword;
|
return entityattack_claudeEnergySword;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
enum EntityAttack attack = entityattack_tackle;;
|
enum EntityAttack attack = entityattack_claudeAttack;
|
||||||
if (entity->type == entitytype_hero)
|
i32 choice = rand() % 7;
|
||||||
|
switch(choice)
|
||||||
{
|
{
|
||||||
b32 choice = rand() % 2;
|
case 0: attack = entityattack_claudeAttack; break;
|
||||||
attack =
|
case 1: attack = entityattack_claudeAttackUp; break;
|
||||||
(choice == TRUE) ? entityattack_airSlash : entityattack_tackle;
|
case 2: attack = entityattack_claudeAttackDown; break;
|
||||||
//attack = entityattack_tackle;
|
case 3: attack = entityattack_claudeDragonHowl; break;
|
||||||
|
case 4: attack = entityattack_claudeEnergySword; break;
|
||||||
|
case 5: attack = entityattack_claudeRipperBlast; break;
|
||||||
|
case 6: attack = entityattack_claudeAirSlash; break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return attack;
|
return attack;
|
||||||
@ -1447,6 +1625,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
World *const world = &state->world[state->currWorldIndex];
|
World *const world = &state->world[state->currWorldIndex];
|
||||||
Font *font = &assetManager->font;
|
Font *font = &assetManager->font;
|
||||||
MemoryArena *arena = &state->arena;
|
MemoryArena *arena = &state->arena;
|
||||||
|
EventQueue *eventQueue = &state->eventQueue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
**********************
|
**********************
|
||||||
@ -1526,7 +1705,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
|
|
||||||
v2 pos =
|
v2 pos =
|
||||||
V2(renderer->size.w - (renderer->size.w / xModifier), yPos);
|
V2(renderer->size.w - (renderer->size.w / xModifier), yPos);
|
||||||
addGenericMob(&state->arena, &state->assetManager, world, pos);
|
addGenericMob(eventQueue, &state->arena, &state->assetManager, world, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1535,7 +1714,6 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
* Update entities and render
|
* Update entities and render
|
||||||
******************************
|
******************************
|
||||||
*/
|
*/
|
||||||
EventQueue eventQueue = {0};
|
|
||||||
Rect camera = createWorldBoundedCamera(world, renderer->size);
|
Rect camera = createWorldBoundedCamera(world, renderer->size);
|
||||||
AudioManager *audioManager = &state->audioManager;
|
AudioManager *audioManager = &state->audioManager;
|
||||||
|
|
||||||
@ -1655,7 +1833,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
i32 numEntitiesInBattleBefore = world->numEntitiesInBattle;
|
i32 numEntitiesInBattleBefore = world->numEntitiesInBattle;
|
||||||
entityStateSwitch(&eventQueue, world, entity, newState);
|
entityStateSwitch(eventQueue, world, entity, newState);
|
||||||
|
|
||||||
if (numEntitiesInBattleBefore == 0 &&
|
if (numEntitiesInBattleBefore == 0 &&
|
||||||
world->numEntitiesInBattle > 0)
|
world->numEntitiesInBattle > 0)
|
||||||
@ -1767,14 +1945,14 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
{
|
{
|
||||||
if (common_strcmp(currAnimName, "claudeIdle") == 0)
|
if (common_strcmp(currAnimName, "claudeIdle") == 0)
|
||||||
{
|
{
|
||||||
entity_setActiveAnim(hero, "claudeRun");
|
entity_setActiveAnim(eventQueue, hero, "claudeRun");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (common_strcmp(currAnimName, "claudeRun") == 0)
|
if (common_strcmp(currAnimName, "claudeRun") == 0)
|
||||||
{
|
{
|
||||||
entity_setActiveAnim(hero, "claudeIdle");
|
entity_setActiveAnim(eventQueue, hero, "claudeIdle");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1813,7 +1991,18 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
// TODO(doyle): Unify concept of dead entity for mobs and
|
// TODO(doyle): Unify concept of dead entity for mobs and
|
||||||
// projectiles
|
// projectiles
|
||||||
projectile->state = entitystate_dead;
|
projectile->state = entitystate_dead;
|
||||||
registerEvent(&eventQueue, eventtype_entity_died, projectile);
|
// TODO(doyle): register endattack event
|
||||||
|
worldTraveller_registerEvent(eventQueue, eventtype_entity_died,
|
||||||
|
projectile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (entity->type == entitytype_attackObject)
|
||||||
|
{
|
||||||
|
if (entity->animList[entity->currAnimId].timesCompleted == 1)
|
||||||
|
{
|
||||||
|
entity->state = entitystate_dead;
|
||||||
|
worldTraveller_registerEvent(eventQueue, eventtype_entity_died,
|
||||||
|
entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1846,7 +2035,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Launch up attack animation */
|
/* Launch up attack animation */
|
||||||
beginAttack(assetManager, &state->arena, &eventQueue, world,
|
beginAttack(assetManager, &state->arena, eventQueue, world,
|
||||||
entity);
|
entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1858,7 +2047,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
if (stats->busyDuration <= 0)
|
if (stats->busyDuration <= 0)
|
||||||
{
|
{
|
||||||
/* Apply attack damage */
|
/* Apply attack damage */
|
||||||
endAttack(&state->arena, &eventQueue, world, entity);
|
endAttack(&state->arena, eventQueue, world, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1876,7 +2065,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
|
|
||||||
if (entity->tex)
|
if (entity->tex)
|
||||||
{
|
{
|
||||||
entity_updateAnim(entity, dt);
|
entity_updateAnim(eventQueue, entity, dt);
|
||||||
/* Calculate region to render */
|
/* Calculate region to render */
|
||||||
renderer_entity(renderer, camera, entity,
|
renderer_entity(renderer, camera, entity,
|
||||||
v2_scale(entity->renderSize, 0.5f), 0,
|
v2_scale(entity->renderSize, 0.5f), 0,
|
||||||
@ -1890,9 +2079,13 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
*****************************************
|
*****************************************
|
||||||
*/
|
*/
|
||||||
i32 numDeadEntities = 0;
|
i32 numDeadEntities = 0;
|
||||||
for (i32 i = 0; i < eventQueue.numEvents; i++)
|
for (i32 i = 0; i < eventQueue->numEvents; i++)
|
||||||
{
|
{
|
||||||
Event event = eventQueue.queue[i];
|
Event event = eventQueue->queue[i];
|
||||||
|
|
||||||
|
eventQueue->queue[i].type = eventtype_null;
|
||||||
|
eventQueue->queue[i].data = NULL;
|
||||||
|
|
||||||
switch(event.type)
|
switch(event.type)
|
||||||
{
|
{
|
||||||
case eventtype_end_attack:
|
case eventtype_end_attack:
|
||||||
@ -1903,7 +2096,9 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
Entity *attacker = attackSpec->attacker;
|
Entity *attacker = attackSpec->attacker;
|
||||||
Entity *defender = attackSpec->defender;
|
Entity *defender = attackSpec->defender;
|
||||||
|
|
||||||
if (attacker->stats->queuedAttack == entityattack_tackle)
|
if (attacker->stats->queuedAttack == entityattack_claudeAttack ||
|
||||||
|
attacker->stats->queuedAttack == entityattack_claudeAttackUp ||
|
||||||
|
attacker->stats->queuedAttack == entityattack_claudeAttackDown)
|
||||||
{
|
{
|
||||||
i32 freeAudioIndex = entityGetFreeAudioRendererIndex(attacker);
|
i32 freeAudioIndex = entityGetFreeAudioRendererIndex(attacker);
|
||||||
if (freeAudioIndex != -1)
|
if (freeAudioIndex != -1)
|
||||||
@ -1940,7 +2135,8 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
1);
|
1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (attacker->stats->queuedAttack == entityattack_energySword)
|
else if (attacker->stats->queuedAttack ==
|
||||||
|
entityattack_claudeEnergySword)
|
||||||
{
|
{
|
||||||
i32 freeAudioIndex = entityGetFreeAudioRendererIndex(attacker);
|
i32 freeAudioIndex = entityGetFreeAudioRendererIndex(attacker);
|
||||||
if (freeAudioIndex != -1)
|
if (freeAudioIndex != -1)
|
||||||
@ -1952,7 +2148,8 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
1);
|
1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (attacker->stats->queuedAttack == entityattack_airSlash)
|
else if (attacker->stats->queuedAttack ==
|
||||||
|
entityattack_claudeAirSlash)
|
||||||
{
|
{
|
||||||
i32 freeAudioIndex = entityGetFreeAudioRendererIndex(attacker);
|
i32 freeAudioIndex = entityGetFreeAudioRendererIndex(attacker);
|
||||||
if (freeAudioIndex != -1)
|
if (freeAudioIndex != -1)
|
||||||
@ -1964,6 +2161,32 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
1);
|
1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (attacker->stats->queuedAttack ==
|
||||||
|
entityattack_claudeDragonHowl)
|
||||||
|
{
|
||||||
|
i32 freeAudioIndex = entityGetFreeAudioRendererIndex(attacker);
|
||||||
|
if (freeAudioIndex != -1)
|
||||||
|
{
|
||||||
|
audio_playVorbis(
|
||||||
|
arena, audioManager,
|
||||||
|
&attacker->audioRenderer[freeAudioIndex],
|
||||||
|
asset_getVorbis(assetManager, "Attack_Dragon_howl"),
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (attacker->stats->queuedAttack ==
|
||||||
|
entityattack_claudeRipperBlast)
|
||||||
|
{
|
||||||
|
i32 freeAudioIndex = entityGetFreeAudioRendererIndex(attacker);
|
||||||
|
if (freeAudioIndex != -1)
|
||||||
|
{
|
||||||
|
audio_playVorbis(
|
||||||
|
arena, audioManager,
|
||||||
|
&attacker->audioRenderer[freeAudioIndex],
|
||||||
|
asset_getVorbis(assetManager, "Attack_tear_into_pieces"),
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//ASSERT(INVALID_CODE_PATH);
|
//ASSERT(INVALID_CODE_PATH);
|
||||||
@ -2039,6 +2262,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
eventQueue->numEvents = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
****************************
|
****************************
|
||||||
@ -2053,11 +2277,11 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
if (hero->state == entitystate_battle &&
|
if (hero->state == entitystate_battle &&
|
||||||
world->numEntitiesInBattle == 1)
|
world->numEntitiesInBattle == 1)
|
||||||
{
|
{
|
||||||
entityStateSwitch(&eventQueue, world, hero, entitystate_idle);
|
entityStateSwitch(eventQueue, world, hero, entitystate_idle);
|
||||||
}
|
}
|
||||||
else if (hero->state != entitystate_attack)
|
else if (hero->state != entitystate_attack)
|
||||||
{
|
{
|
||||||
entityStateSwitch(&eventQueue, world, hero, entitystate_battle);
|
entityStateSwitch(eventQueue, world, hero, entitystate_battle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2066,7 +2290,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;
|
||||||
entity_setActiveAnim(hero, "claudeIdle");
|
entity_setActiveAnim(eventQueue, hero, "claudeIdle");
|
||||||
}
|
}
|
||||||
hero->stats->entityIdToAttack = -1;
|
hero->stats->entityIdToAttack = -1;
|
||||||
hero->stats->actionTimer = hero->stats->actionRate;
|
hero->stats->actionTimer = hero->stats->actionRate;
|
||||||
|
@ -10,6 +10,7 @@ typedef struct MemoryArena MemoryArena;
|
|||||||
typedef struct Texture Texture;
|
typedef struct Texture Texture;
|
||||||
typedef struct Animation Animation;
|
typedef struct Animation Animation;
|
||||||
typedef struct World World;
|
typedef struct World World;
|
||||||
|
typedef struct EventQueue EventQueue;
|
||||||
|
|
||||||
typedef struct Entity Entity;
|
typedef struct Entity Entity;
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ enum EntityType
|
|||||||
entitytype_hero,
|
entitytype_hero,
|
||||||
entitytype_weapon,
|
entitytype_weapon,
|
||||||
entitytype_projectile,
|
entitytype_projectile,
|
||||||
|
entitytype_attackObject,
|
||||||
entitytype_npc,
|
entitytype_npc,
|
||||||
entitytype_mob,
|
entitytype_mob,
|
||||||
entitytype_tile,
|
entitytype_tile,
|
||||||
@ -48,9 +50,13 @@ enum EntityState
|
|||||||
|
|
||||||
enum EntityAttack
|
enum EntityAttack
|
||||||
{
|
{
|
||||||
entityattack_tackle,
|
entityattack_claudeAttack,
|
||||||
entityattack_airSlash,
|
entityattack_claudeAttackUp,
|
||||||
entityattack_energySword,
|
entityattack_claudeAttackDown,
|
||||||
|
entityattack_claudeDragonHowl,
|
||||||
|
entityattack_claudeEnergySword,
|
||||||
|
entityattack_claudeRipperBlast,
|
||||||
|
entityattack_claudeAirSlash,
|
||||||
entityattack_count,
|
entityattack_count,
|
||||||
entityattack_invalid,
|
entityattack_invalid,
|
||||||
};
|
};
|
||||||
@ -76,6 +82,8 @@ typedef struct EntityAnim
|
|||||||
Animation *anim;
|
Animation *anim;
|
||||||
i32 currFrame;
|
i32 currFrame;
|
||||||
f32 currDuration;
|
f32 currDuration;
|
||||||
|
|
||||||
|
u32 timesCompleted;
|
||||||
} EntityAnim;
|
} EntityAnim;
|
||||||
|
|
||||||
struct Entity
|
struct Entity
|
||||||
@ -118,8 +126,10 @@ struct Entity
|
|||||||
i32 numAudioRenderers;
|
i32 numAudioRenderers;
|
||||||
};
|
};
|
||||||
|
|
||||||
void entity_setActiveAnim(Entity *const entity, const char *const animName);
|
void entity_setActiveAnim(EventQueue *eventQueue, Entity *const entity,
|
||||||
void entity_updateAnim(Entity *const entity, const f32 dt);
|
const char *const animName);
|
||||||
|
void entity_updateAnim(EventQueue *eventQueue, Entity *const entity,
|
||||||
|
const f32 dt);
|
||||||
void entity_addAnim(AssetManager *const assetManager, Entity *const entity,
|
void entity_addAnim(AssetManager *const assetManager, Entity *const entity,
|
||||||
const char *const animName);
|
const char *const animName);
|
||||||
Entity *const entity_add(MemoryArena *const arena, World *const world,
|
Entity *const entity_add(MemoryArena *const arena, World *const world,
|
||||||
|
@ -16,6 +16,29 @@
|
|||||||
/* Forward declaration */
|
/* Forward declaration */
|
||||||
typedef struct Entity Entity;
|
typedef struct Entity Entity;
|
||||||
|
|
||||||
|
enum EventType
|
||||||
|
{
|
||||||
|
eventtype_null = 0,
|
||||||
|
eventtype_start_attack,
|
||||||
|
eventtype_end_attack,
|
||||||
|
eventtype_start_anim,
|
||||||
|
eventtype_end_anim,
|
||||||
|
eventtype_entity_died,
|
||||||
|
eventtype_count,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Event
|
||||||
|
{
|
||||||
|
enum EventType type;
|
||||||
|
void *data;
|
||||||
|
} Event;
|
||||||
|
|
||||||
|
typedef struct EventQueue
|
||||||
|
{
|
||||||
|
Event queue[1024];
|
||||||
|
i32 numEvents;
|
||||||
|
} EventQueue;
|
||||||
|
|
||||||
enum RectBaseline
|
enum RectBaseline
|
||||||
{
|
{
|
||||||
rectbaseline_top,
|
rectbaseline_top,
|
||||||
@ -73,8 +96,11 @@ typedef struct GameState
|
|||||||
Config config;
|
Config config;
|
||||||
MemoryArena arena;
|
MemoryArena arena;
|
||||||
UiState uiState;
|
UiState uiState;
|
||||||
|
EventQueue eventQueue;
|
||||||
} GameState;
|
} GameState;
|
||||||
|
|
||||||
void worldTraveller_gameInit(GameState *state, v2 windowSize);
|
void worldTraveller_gameInit(GameState *state, v2 windowSize);
|
||||||
void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt);
|
void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt);
|
||||||
|
void worldTraveller_registerEvent(EventQueue *eventQueue, enum EventType type,
|
||||||
|
void *data);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user