Integrate sfx audio into battle
This commit is contained in:
parent
5cccd3ebe8
commit
4c38abc672
@ -833,7 +833,7 @@ const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena,
|
|||||||
PlatformFileRead fileRead = {0};
|
PlatformFileRead fileRead = {0};
|
||||||
platform_readFileToBuffer(arena, path, &fileRead);
|
platform_readFileToBuffer(arena, path, &fileRead);
|
||||||
|
|
||||||
entry->data = PLATFORM_MEM_ALLOC(arena, 1, AudioVorbis);
|
entry->data = PLATFORM_MEM_ALLOC(arena, 1, AudioVorbis);
|
||||||
|
|
||||||
i32 error;
|
i32 error;
|
||||||
AudioVorbis *audio = CAST(AudioVorbis *) entry->data;
|
AudioVorbis *audio = CAST(AudioVorbis *) entry->data;
|
||||||
|
10
src/Audio.c
10
src/Audio.c
@ -215,12 +215,15 @@ INTERNAL const i32 rendererRelease(MemoryArena *arena, AudioManager *audioManage
|
|||||||
PLATFORM_MEM_FREE(arena, audioRenderer->audio, sizeof(AudioVorbis));
|
PLATFORM_MEM_FREE(arena, audioRenderer->audio, sizeof(AudioVorbis));
|
||||||
}
|
}
|
||||||
|
|
||||||
audioRenderer->audio = NULL;
|
|
||||||
audioRenderer->numPlays = 0;
|
|
||||||
|
|
||||||
u32 sourceIndexToFree = audioRenderer->sourceIndex;
|
u32 sourceIndexToFree = audioRenderer->sourceIndex;
|
||||||
audioRenderer->sourceIndex = AUDIO_SOURCE_UNASSIGNED;
|
audioRenderer->sourceIndex = AUDIO_SOURCE_UNASSIGNED;
|
||||||
|
|
||||||
|
audioRenderer->audio = NULL;
|
||||||
|
audioRenderer->numPlays = 0;
|
||||||
|
|
||||||
|
audioRenderer->isStreaming = FALSE;
|
||||||
|
audioRenderer->state = audiostate_stopped;
|
||||||
|
|
||||||
audioManager->sourceList[sourceIndexToFree].isFree = TRUE;
|
audioManager->sourceList[sourceIndexToFree].isFree = TRUE;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -280,6 +283,7 @@ const i32 audio_playVorbis(MemoryArena *arena, AudioManager *audioManager,
|
|||||||
|
|
||||||
audioRenderer->audio = vorbis;
|
audioRenderer->audio = vorbis;
|
||||||
audioRenderer->isStreaming = FALSE;
|
audioRenderer->isStreaming = FALSE;
|
||||||
|
audioRenderer->state = audiostate_playing;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,8 @@ void entity_clearData(MemoryArena *const arena, World *const world,
|
|||||||
PLATFORM_MEM_FREE(arena, entity->stats, sizeof(EntityStats));
|
PLATFORM_MEM_FREE(arena, entity->stats, sizeof(EntityStats));
|
||||||
|
|
||||||
if (entity->audioRenderer)
|
if (entity->audioRenderer)
|
||||||
PLATFORM_MEM_FREE(arena, entity->audioRenderer, sizeof(AudioRenderer));
|
PLATFORM_MEM_FREE(arena, entity->audioRenderer,
|
||||||
|
sizeof(AudioRenderer) * entity->numAudioRenderers);
|
||||||
|
|
||||||
entity->type = entitytype_null;
|
entity->type = entitytype_null;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ INTERNAL Entity *getHeroEntity(World *world)
|
|||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void addGenericMob(MemoryArena *arena, AssetManager *assetManager,
|
INTERNAL void addGenericMob(MemoryArena *arena, AssetManager *assetManager,
|
||||||
World *world, v2 pos)
|
World *world, v2 pos)
|
||||||
{
|
{
|
||||||
#ifdef DENGINE_DEBUG
|
#ifdef DENGINE_DEBUG
|
||||||
DEBUG_LOG("Mob entity spawned");
|
DEBUG_LOG("Mob entity spawned");
|
||||||
@ -57,8 +57,12 @@ INTERNAL void addGenericMob(MemoryArena *arena, AssetManager *assetManager,
|
|||||||
b32 collides = TRUE;
|
b32 collides = TRUE;
|
||||||
Entity *mob = entity_add(arena, world, pos, size, type, dir, tex, collides);
|
Entity *mob = entity_add(arena, world, pos, size, type, dir, tex, collides);
|
||||||
|
|
||||||
mob->audioRenderer = PLATFORM_MEM_ALLOC(arena, 1, AudioRenderer);
|
mob->numAudioRenderers = 4;
|
||||||
mob->audioRenderer->sourceIndex = AUDIO_SOURCE_UNASSIGNED;
|
mob->audioRenderer =
|
||||||
|
PLATFORM_MEM_ALLOC(arena, mob->numAudioRenderers, AudioRenderer);
|
||||||
|
|
||||||
|
for (i32 i = 0; i < mob->numAudioRenderers; i++)
|
||||||
|
mob->audioRenderer[i].sourceIndex = AUDIO_SOURCE_UNASSIGNED;
|
||||||
|
|
||||||
/* Populate mob animation references */
|
/* Populate mob animation references */
|
||||||
entity_addAnim(assetManager, mob, "claudeIdle");
|
entity_addAnim(assetManager, mob, "claudeIdle");
|
||||||
@ -251,6 +255,17 @@ INTERNAL void assetInit(GameState *state)
|
|||||||
asset_addAnimation(assetManager, arena, "claudeVictory",
|
asset_addAnimation(assetManager, arena, "claudeVictory",
|
||||||
claudeAtlas, claudeVictory, numRects, duration);
|
claudeAtlas, claudeVictory, numRects, duration);
|
||||||
|
|
||||||
|
char *claudeEnergySword[6] = {"ClaudeSprite_Attack_EnergySword_01",
|
||||||
|
"ClaudeSprite_Attack_EnergySword_02",
|
||||||
|
"ClaudeSprite_Attack_EnergySword_03",
|
||||||
|
"ClaudeSprite_Attack_EnergySword_04",
|
||||||
|
"ClaudeSprite_Attack_EnergySword_05",
|
||||||
|
"ClaudeSprite_Attack_EnergySword_06"};
|
||||||
|
numRects = ARRAY_COUNT(claudeEnergySword);
|
||||||
|
duration = 0.1f;
|
||||||
|
asset_addAnimation(assetManager, arena, "claudeEnergySword",
|
||||||
|
claudeAtlas, claudeEnergySword, numRects,
|
||||||
|
duration);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -283,6 +298,77 @@ INTERNAL void assetInit(GameState *state)
|
|||||||
|
|
||||||
/* Load sound */
|
/* Load sound */
|
||||||
|
|
||||||
|
i32 before = arena->bytesAllocated;
|
||||||
|
|
||||||
|
char *sfxListPath = "data/audio/sfx/sfx.txt";
|
||||||
|
PlatformFileRead sfxList = {0};
|
||||||
|
result = platform_readFileToBuffer(arena, sfxListPath, &sfxList);
|
||||||
|
|
||||||
|
char *sfxAudioNames[256];
|
||||||
|
i32 sfxAudioIndex = 0;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
char string[256] = {0};
|
||||||
|
i32 stringIndex = 0;
|
||||||
|
for (i32 i = 0; i < sfxList.size; i++)
|
||||||
|
{
|
||||||
|
char c = (CAST(char *)sfxList.buffer)[i];
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case 0x0a:
|
||||||
|
{
|
||||||
|
i32 actualStrLen = common_strlen(string) + 1;
|
||||||
|
sfxAudioNames[sfxAudioIndex] =
|
||||||
|
PLATFORM_MEM_ALLOC(arena, actualStrLen, char);
|
||||||
|
common_strncpy(sfxAudioNames[sfxAudioIndex++], string,
|
||||||
|
actualStrLen);
|
||||||
|
|
||||||
|
common_memset(string, 0, ARRAY_COUNT(string));
|
||||||
|
stringIndex = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if (c >= ' ' && c <= '~')
|
||||||
|
{
|
||||||
|
string[stringIndex++] = c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *sfxDir = "data/audio/sfx/";
|
||||||
|
char *sfxExtension = ".ogg";
|
||||||
|
i32 sfxDirLen = common_strlen(sfxDir);
|
||||||
|
i32 sfxExtensionLen = common_strlen(sfxExtension);
|
||||||
|
|
||||||
|
for (i32 i = 0; i < sfxAudioIndex; i++)
|
||||||
|
{
|
||||||
|
char *sfxName = sfxAudioNames[i];
|
||||||
|
i32 sfxNameLen = common_strlen(sfxName);
|
||||||
|
|
||||||
|
i32 sfxFullPathLen = sfxDirLen + sfxExtensionLen + sfxNameLen + 1;
|
||||||
|
char *sfxFullPath = PLATFORM_MEM_ALLOC(arena, sfxFullPathLen, char);
|
||||||
|
|
||||||
|
common_strncat(sfxFullPath, sfxDir, sfxDirLen);
|
||||||
|
common_strncat(sfxFullPath, sfxName, sfxNameLen);
|
||||||
|
common_strncat(sfxFullPath, sfxExtension, sfxExtensionLen);
|
||||||
|
|
||||||
|
i32 result = asset_loadVorbis(assetManager, arena, sfxFullPath, sfxName);
|
||||||
|
if (result) DEBUG_LOG("Failed to load sfx file");
|
||||||
|
|
||||||
|
// TODO(doyle): Need better string type to account for null terminating
|
||||||
|
// character, having to remember to +1 on allocation AND freeing since
|
||||||
|
// strlen only counts until null char is going to leave memory leaks
|
||||||
|
// everywhere
|
||||||
|
PLATFORM_MEM_FREE(arena, sfxName, sfxNameLen * sizeof(char) + 1);
|
||||||
|
PLATFORM_MEM_FREE(arena, sfxFullPath, sfxFullPathLen * sizeof(char));
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_closeFileRead(arena, &sfxList);
|
||||||
|
|
||||||
char *audioPath =
|
char *audioPath =
|
||||||
"data/audio/Motoi Sakuraba - Stab the sword of justice.ogg";
|
"data/audio/Motoi Sakuraba - Stab the sword of justice.ogg";
|
||||||
asset_loadVorbis(assetManager, arena, audioPath, "audio_battle");
|
asset_loadVorbis(assetManager, arena, audioPath, "audio_battle");
|
||||||
@ -370,8 +456,11 @@ INTERNAL void entityInit(GameState *state, v2 windowSize)
|
|||||||
entity_add(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->audioRenderer = PLATFORM_MEM_ALLOC(arena, 1, AudioRenderer);
|
soundscape->numAudioRenderers = 1;
|
||||||
soundscape->audioRenderer->sourceIndex = AUDIO_SOURCE_UNASSIGNED;
|
soundscape->audioRenderer =
|
||||||
|
PLATFORM_MEM_ALLOC(arena, soundscape->numAudioRenderers, AudioRenderer);
|
||||||
|
for (i32 i = 0; i < soundscape->numAudioRenderers; i++)
|
||||||
|
soundscape->audioRenderer[i].sourceIndex = AUDIO_SOURCE_UNASSIGNED;
|
||||||
|
|
||||||
/* Init hero entity */
|
/* Init hero entity */
|
||||||
size = V2(58.0f, 98.0f);
|
size = V2(58.0f, 98.0f);
|
||||||
@ -383,8 +472,13 @@ INTERNAL void entityInit(GameState *state, v2 windowSize)
|
|||||||
Entity *hero =
|
Entity *hero =
|
||||||
entity_add(arena, world, pos, size, type, dir, tex, collides);
|
entity_add(arena, world, pos, size, type, dir, tex, collides);
|
||||||
|
|
||||||
hero->audioRenderer = PLATFORM_MEM_ALLOC(arena, 1, AudioRenderer);
|
hero->numAudioRenderers = 4;
|
||||||
hero->audioRenderer->sourceIndex = AUDIO_SOURCE_UNASSIGNED;
|
hero->audioRenderer =
|
||||||
|
PLATFORM_MEM_ALLOC(arena, hero->numAudioRenderers, AudioRenderer);
|
||||||
|
|
||||||
|
for (i32 i = 0; i < hero->numAudioRenderers; i++)
|
||||||
|
hero->audioRenderer[i].sourceIndex = AUDIO_SOURCE_UNASSIGNED;
|
||||||
|
|
||||||
world->heroId = hero->id;
|
world->heroId = hero->id;
|
||||||
world->cameraFollowingId = hero->id;
|
world->cameraFollowingId = hero->id;
|
||||||
|
|
||||||
@ -393,6 +487,7 @@ INTERNAL void entityInit(GameState *state, v2 windowSize)
|
|||||||
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, "claudeEnergySword");
|
||||||
entity_setActiveAnim(hero, "claudeIdle");
|
entity_setActiveAnim(hero, "claudeIdle");
|
||||||
|
|
||||||
/* Create a NPC */
|
/* Create a NPC */
|
||||||
@ -884,6 +979,7 @@ INTERNAL void beginAttack(EventQueue *eventQueue, World *world,
|
|||||||
switch (attacker->stats->queuedAttack)
|
switch (attacker->stats->queuedAttack)
|
||||||
{
|
{
|
||||||
case entityattack_tackle:
|
case entityattack_tackle:
|
||||||
|
{
|
||||||
entity_setActiveAnim(attacker, "claudeAttack");
|
entity_setActiveAnim(attacker, "claudeAttack");
|
||||||
EntityAnim attackAnim = attacker->animList[attacker->currAnimId];
|
EntityAnim attackAnim = attacker->animList[attacker->currAnimId];
|
||||||
f32 busyDuration = attackAnim.anim->frameDuration *
|
f32 busyDuration = attackAnim.anim->frameDuration *
|
||||||
@ -895,6 +991,18 @@ INTERNAL void beginAttack(EventQueue *eventQueue, World *world,
|
|||||||
else
|
else
|
||||||
attacker->dPos.x -= (1.0f * METERS_TO_PIXEL);
|
attacker->dPos.x -= (1.0f * METERS_TO_PIXEL);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case entityattack_energySword:
|
||||||
|
{
|
||||||
|
entity_setActiveAnim(attacker, "claudeEnergySword");
|
||||||
|
EntityAnim attackAnim = attacker->animList[attacker->currAnimId];
|
||||||
|
f32 busyDuration = attackAnim.anim->frameDuration *
|
||||||
|
CAST(f32) attackAnim.anim->numFrames;
|
||||||
|
attacker->stats->busyDuration = busyDuration;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#ifdef DENGINE_DEBUG
|
#ifdef DENGINE_DEBUG
|
||||||
ASSERT(INVALID_CODE_PATH);
|
ASSERT(INVALID_CODE_PATH);
|
||||||
@ -923,6 +1031,17 @@ INTERNAL void endAttack(MemoryArena *arena, EventQueue *eventQueue,
|
|||||||
attacker->dPos.x += (1.0f * METERS_TO_PIXEL);
|
attacker->dPos.x += (1.0f * METERS_TO_PIXEL);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case entityattack_energySword:
|
||||||
|
attacker->stats->health += 80;
|
||||||
|
|
||||||
|
AttackSpec *attackSpec = PLATFORM_MEM_ALLOC(arena, 1, AttackSpec);
|
||||||
|
attackSpec->attacker = attacker;
|
||||||
|
attackSpec->defender = attacker;
|
||||||
|
attackSpec->damage = 30;
|
||||||
|
registerEvent(eventQueue, eventtype_end_attack, attackSpec);
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#ifdef DENGINE_DEBUG
|
#ifdef DENGINE_DEBUG
|
||||||
ASSERT(INVALID_CODE_PATH);
|
ASSERT(INVALID_CODE_PATH);
|
||||||
@ -978,6 +1097,12 @@ INTERNAL void endAttack(MemoryArena *arena, EventQueue *eventQueue,
|
|||||||
if (attacker->type == entitytype_hero)
|
if (attacker->type == entitytype_hero)
|
||||||
{
|
{
|
||||||
defender->stats->health -= damage;
|
defender->stats->health -= damage;
|
||||||
|
if (defender->stats->health <= 0.0f) defender->stats->health = 10.0f;
|
||||||
|
}
|
||||||
|
else if (attacker->type == entitytype_mob)
|
||||||
|
{
|
||||||
|
defender->stats->health -= damage * 0.25f;
|
||||||
|
if (defender->stats->health <= 0.0f) defender->stats->health = 10.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defender->stats->health <= 0)
|
if (defender->stats->health <= 0)
|
||||||
@ -1013,6 +1138,33 @@ INTERNAL void sortWorldEntityList(World *world)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL enum EntityAttack selectBestAttack(Entity *entity)
|
||||||
|
{
|
||||||
|
if (entity->stats->health <= 50.0f && entity->type == entitytype_hero)
|
||||||
|
{
|
||||||
|
return entityattack_energySword;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return entityattack_tackle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL i32 entityGetFreeAudioRendererIndex(Entity *entity)
|
||||||
|
{
|
||||||
|
i32 result = -1;
|
||||||
|
for (i32 i = 0; i < entity->numAudioRenderers; i++)
|
||||||
|
{
|
||||||
|
if (entity->audioRenderer[i].state == audiostate_stopped)
|
||||||
|
{
|
||||||
|
result = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct DamageDisplay
|
typedef struct DamageDisplay
|
||||||
{
|
{
|
||||||
char damageStr[12];
|
char damageStr[12];
|
||||||
@ -1151,7 +1303,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
|
|
||||||
if (entity->type == entitytype_soundscape)
|
if (entity->type == entitytype_soundscape)
|
||||||
{
|
{
|
||||||
AudioRenderer *audioRenderer = entity->audioRenderer;
|
AudioRenderer *audioRenderer = &entity->audioRenderer[0];
|
||||||
if (!state->config.playWorldAudio)
|
if (!state->config.playWorldAudio)
|
||||||
{
|
{
|
||||||
// TODO(doyle): Use is playing flag, not just streaming flag
|
// TODO(doyle): Use is playing flag, not just streaming flag
|
||||||
@ -1244,7 +1396,37 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
newState = entitystate_idle;
|
newState = entitystate_idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i32 numEntitiesInBattleBefore = world->numEntitiesInBattle;
|
||||||
entityStateSwitch(&eventQueue, world, entity, newState);
|
entityStateSwitch(&eventQueue, world, entity, newState);
|
||||||
|
|
||||||
|
if (numEntitiesInBattleBefore == 0 &&
|
||||||
|
world->numEntitiesInBattle > 0)
|
||||||
|
{
|
||||||
|
i32 freeAudioIndex = entityGetFreeAudioRendererIndex(hero);
|
||||||
|
if (freeAudioIndex != -1)
|
||||||
|
{
|
||||||
|
char *battleTaunt[11] = {
|
||||||
|
"Battle_come_on",
|
||||||
|
"Battle_heh",
|
||||||
|
"Battle_heres_the_enemy",
|
||||||
|
"Battle_hey",
|
||||||
|
"Battle_oh_its_just_them",
|
||||||
|
"Battle_shouldnt_you_run_away",
|
||||||
|
"Battle_things_will_work_out_somehow",
|
||||||
|
"Battle_things_will_work_out",
|
||||||
|
"Battle_were_gonna_win",
|
||||||
|
"Battle_we_can_win_this",
|
||||||
|
"Battle_you_think_you_can_win_over_the_hero_of_light"};
|
||||||
|
|
||||||
|
i32 battleTauntSfxIndex = rand() % ARRAY_COUNT(battleTaunt);
|
||||||
|
audio_playVorbis(
|
||||||
|
arena, audioManager,
|
||||||
|
&hero->audioRenderer[freeAudioIndex],
|
||||||
|
asset_getVorbis(assetManager,
|
||||||
|
battleTaunt[battleTauntSfxIndex]),
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1432,7 +1614,10 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
{
|
{
|
||||||
stats->actionTimer = 0;
|
stats->actionTimer = 0;
|
||||||
if (stats->queuedAttack == entityattack_invalid)
|
if (stats->queuedAttack == entityattack_invalid)
|
||||||
stats->queuedAttack = entityattack_tackle;
|
{
|
||||||
|
enum EntityAttack attack = selectBestAttack(entity);
|
||||||
|
stats->queuedAttack = attack;
|
||||||
|
}
|
||||||
|
|
||||||
/* Launch up attack animation */
|
/* Launch up attack animation */
|
||||||
beginAttack(&eventQueue, world, entity);
|
beginAttack(&eventQueue, world, entity);
|
||||||
@ -1456,10 +1641,10 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
* Update Entity
|
* Update Entity
|
||||||
****************
|
****************
|
||||||
*/
|
*/
|
||||||
if (entity->audioRenderer)
|
for (i32 i = 0; i < entity->numAudioRenderers; i++)
|
||||||
{
|
{
|
||||||
audio_updateAndPlay(&state->arena, &state->audioManager,
|
audio_updateAndPlay(&state->arena, &state->audioManager,
|
||||||
entity->audioRenderer);
|
&entity->audioRenderer[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity->tex)
|
if (entity->tex)
|
||||||
@ -1490,9 +1675,75 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
Entity *attacker = attackSpec->attacker;
|
Entity *attacker = attackSpec->attacker;
|
||||||
Entity *defender = attackSpec->defender;
|
Entity *defender = attackSpec->defender;
|
||||||
|
|
||||||
audio_playVorbis(arena, audioManager, attacker->audioRenderer,
|
if (attacker->stats->queuedAttack == entityattack_tackle)
|
||||||
asset_getVorbis(assetManager, "audio_tackle"),
|
{
|
||||||
1);
|
i32 freeAudioIndex = entityGetFreeAudioRendererIndex(attacker);
|
||||||
|
if (freeAudioIndex != -1)
|
||||||
|
{
|
||||||
|
char *attackSfx[19] = {"Attack_1",
|
||||||
|
"Attack_2",
|
||||||
|
"Attack_3",
|
||||||
|
"Attack_4",
|
||||||
|
"Attack_5",
|
||||||
|
"Attack_6",
|
||||||
|
"Attack_7",
|
||||||
|
"Attack_hit_it",
|
||||||
|
"Attack_take_that",
|
||||||
|
"Attack_hya",
|
||||||
|
"Attack_air_slash",
|
||||||
|
"Attack_Dragon_howl",
|
||||||
|
"Attack_burn",
|
||||||
|
"Attack_burst_knuckle",
|
||||||
|
"Attack_mirror_slice",
|
||||||
|
"Attack_shooting_star",
|
||||||
|
"Attack_sword_bomber",
|
||||||
|
"Attack_tear_into_pieces",
|
||||||
|
"Attack_twin_slash"};
|
||||||
|
|
||||||
|
i32 attackSfxIndex = rand() % ARRAY_COUNT(attackSfx);
|
||||||
|
audio_playVorbis(arena, audioManager,
|
||||||
|
&attacker->audioRenderer[freeAudioIndex],
|
||||||
|
asset_getVorbis(assetManager,
|
||||||
|
attackSfx[attackSfxIndex]),
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
|
freeAudioIndex = entityGetFreeAudioRendererIndex(defender);
|
||||||
|
if (freeAudioIndex != -1)
|
||||||
|
{
|
||||||
|
char *hurtSfx[10] = {"Hurt_1", "Hurt_2",
|
||||||
|
"Hurt_3", "Hurt_hows_this",
|
||||||
|
"Hurt_battlecry", "Hurt_ow",
|
||||||
|
"Hurt_uh_oh", "Hurt_ugh",
|
||||||
|
"Hurt_woah", "Hurt_yearning"};
|
||||||
|
|
||||||
|
i32 hurtSfxIndex = rand() % ARRAY_COUNT(hurtSfx);
|
||||||
|
|
||||||
|
audio_playVorbis(
|
||||||
|
arena, audioManager,
|
||||||
|
&defender->audioRenderer[freeAudioIndex],
|
||||||
|
asset_getVorbis(assetManager, hurtSfx[hurtSfxIndex]),
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (attacker->stats->queuedAttack == entityattack_energySword)
|
||||||
|
{
|
||||||
|
i32 freeAudioIndex = entityGetFreeAudioRendererIndex(attacker);
|
||||||
|
if (freeAudioIndex != -1)
|
||||||
|
{
|
||||||
|
audio_playVorbis(
|
||||||
|
arena, audioManager,
|
||||||
|
&attacker->audioRenderer[freeAudioIndex],
|
||||||
|
asset_getVorbis(assetManager, "Attack_energy_sword"),
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(INVALID_CODE_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
attacker->stats->queuedAttack = entityattack_invalid;
|
||||||
|
|
||||||
/* Get first free string position and store the damage str data */
|
/* Get first free string position and store the damage str data */
|
||||||
for (i32 i = 0; i < ARRAY_COUNT(battleState.damageDisplay); i++)
|
for (i32 i = 0; i < ARRAY_COUNT(battleState.damageDisplay); i++)
|
||||||
@ -1528,8 +1779,11 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
if (!event.data) continue;
|
if (!event.data) continue;
|
||||||
|
|
||||||
Entity *entity = (CAST(Entity *) event.data);
|
Entity *entity = (CAST(Entity *) event.data);
|
||||||
audio_stopVorbis(&state->arena, audioManager,
|
for (i32 i = 0; i < entity->numAudioRenderers; i++)
|
||||||
entity->audioRenderer);
|
{
|
||||||
|
audio_stopVorbis(&state->arena, audioManager,
|
||||||
|
&entity->audioRenderer[i]);
|
||||||
|
}
|
||||||
entity_clearData(&state->arena, world, entity);
|
entity_clearData(&state->arena, world, entity);
|
||||||
numDeadEntities++;
|
numDeadEntities++;
|
||||||
break;
|
break;
|
||||||
@ -1554,7 +1808,9 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
// NOTE(doyle): If battle entities is 1 then only the hero left
|
// NOTE(doyle): If battle entities is 1 then only the hero left
|
||||||
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);
|
||||||
|
@ -45,6 +45,7 @@ enum EntityState
|
|||||||
enum EntityAttack
|
enum EntityAttack
|
||||||
{
|
{
|
||||||
entityattack_tackle,
|
entityattack_tackle,
|
||||||
|
entityattack_energySword,
|
||||||
entityattack_count,
|
entityattack_count,
|
||||||
entityattack_invalid,
|
entityattack_invalid,
|
||||||
};
|
};
|
||||||
@ -90,6 +91,8 @@ typedef struct Entity
|
|||||||
i32 currAnimId;
|
i32 currAnimId;
|
||||||
|
|
||||||
EntityStats *stats;
|
EntityStats *stats;
|
||||||
|
|
||||||
|
// TODO(doyle): Audio mixing instead of multiple renderers
|
||||||
AudioRenderer *audioRenderer;
|
AudioRenderer *audioRenderer;
|
||||||
i32 numAudioRenderers;
|
i32 numAudioRenderers;
|
||||||
} Entity;
|
} Entity;
|
||||||
|
Loading…
Reference in New Issue
Block a user