Introduce notion of attack spec for battles
An attack spec will be used to hold the stats of both the attacker and defender, grouping the data necessary to determine how much damage the defender takes and other statuses caused by the attack.
This commit is contained in:
parent
b5db6e0e2b
commit
523fe0f2b1
@ -729,6 +729,13 @@ INTERNAL void entityStateSwitch(EventQueue *eventQueue, World *world,
|
||||
entity->state = newState;
|
||||
}
|
||||
|
||||
typedef struct AttackSpec
|
||||
{
|
||||
Entity *attacker;
|
||||
Entity *defender;
|
||||
i32 damage;
|
||||
} AttackSpec;
|
||||
|
||||
INTERNAL void beginAttack(EventQueue *eventQueue, World *world,
|
||||
Entity *attacker)
|
||||
{
|
||||
@ -759,14 +766,16 @@ INTERNAL void beginAttack(EventQueue *eventQueue, World *world,
|
||||
}
|
||||
}
|
||||
|
||||
INTERNAL void endAttack(EventQueue *eventQueue, World *world, Entity *attacker)
|
||||
// TODO(doyle): MemArena here is temporary until we incorporate AttackSpec to
|
||||
// battle in general!
|
||||
INTERNAL void endAttack(MemoryArena *arena, EventQueue *eventQueue,
|
||||
World *world, Entity *attacker)
|
||||
{
|
||||
#ifdef DENGINE_DEBUG
|
||||
ASSERT(attacker->stats->entityIdToAttack != ENTITY_NULL_ID);
|
||||
#endif
|
||||
|
||||
entityStateSwitch(eventQueue, world, attacker, entitystate_battle);
|
||||
registerEvent(eventQueue, eventtype_end_attack, attacker);
|
||||
switch (attacker->stats->queuedAttack)
|
||||
{
|
||||
case entityattack_tackle:
|
||||
@ -821,6 +830,13 @@ INTERNAL void endAttack(EventQueue *eventQueue, World *world, Entity *attacker)
|
||||
if (!noMoreValidTargets)
|
||||
{
|
||||
i32 damage = 50;
|
||||
|
||||
AttackSpec *attackSpec = PLATFORM_MEM_ALLOC(arena, 1, AttackSpec);
|
||||
attackSpec->attacker = attacker;
|
||||
attackSpec->defender = defender;
|
||||
attackSpec->damage = damage;
|
||||
|
||||
registerEvent(eventQueue, eventtype_end_attack, attackSpec);
|
||||
// TODO(doyle): Use attacker stats in battle equations
|
||||
if (attacker->type == entitytype_hero)
|
||||
{
|
||||
@ -1000,7 +1016,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
||||
if (stats->busyDuration <= 0)
|
||||
{
|
||||
/* Apply attack damage */
|
||||
endAttack(&eventQueue, world, entity);
|
||||
endAttack(&state->arena, &eventQueue, world, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1035,10 +1051,28 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
||||
{
|
||||
if (!event.data) continue;
|
||||
|
||||
Entity *entity = (CAST(Entity *) event.data);
|
||||
AttackSpec *attackSpec = (CAST(AttackSpec *)event.data);
|
||||
Entity *attacker = attackSpec->attacker;
|
||||
Entity *defender = attackSpec->defender;
|
||||
|
||||
audio_playVorbis(
|
||||
arena, audioManager, entity->audioRenderer,
|
||||
arena, audioManager, attacker->audioRenderer,
|
||||
asset_getVorbis(assetManager, audiolist_tackle), 1);
|
||||
|
||||
char damageStr[12];
|
||||
common_itoa(attackSpec->damage, damageStr,
|
||||
ARRAY_COUNT(damageStr));
|
||||
|
||||
// TODO(doyle): Incorporate UI into entity list or it's own list
|
||||
// with a rendering lifetime value
|
||||
renderer_string(renderer, &state->arena,
|
||||
cameraBounds, font,
|
||||
damageStr, defender->pos, V2(0, 0),
|
||||
0, V4(1, 1, 1, 1));
|
||||
|
||||
PLATFORM_MEM_FREE(&state->arena, attackSpec,
|
||||
sizeof(AttackSpec));
|
||||
|
||||
break;
|
||||
}
|
||||
// NOTE(doyle): We delete dead entities at the end of the update
|
||||
|
Loading…
Reference in New Issue
Block a user