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\Debug.c" /> | ||||
|     <ClCompile Include="src\dengine.c" /> | ||||
|     <ClCompile Include="src\Entity.c" /> | ||||
|     <ClCompile Include="src\Platform.c" /> | ||||
|     <ClCompile Include="src\Renderer.c" /> | ||||
|     <ClCompile Include="src\Shader.c" /> | ||||
|  | ||||
| @ -48,6 +48,9 @@ | ||||
|     <ClCompile Include="src\Audio.c"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="src\Entity.c"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <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 "Dengine/Debug.h" | ||||
| #include "Dengine/Platform.h" | ||||
| #include "Dengine/Audio.h" | ||||
| #include "Dengine/Debug.h" | ||||
| #include "Dengine/Entity.h" | ||||
| #include "Dengine/Platform.h" | ||||
| 
 | ||||
| enum State | ||||
| { | ||||
| @ -11,82 +12,12 @@ enum State | ||||
| 	state_win, | ||||
| }; | ||||
| 
 | ||||
| INTERNAL Entity *getHeroEntity(World *world) | ||||
| Entity *getHeroEntity(World *world) | ||||
| { | ||||
| 	Entity *result = &world->entities[world->heroIndex]; | ||||
| 	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) | ||||
| { | ||||
| 	AssetManager *assetManager = &state->assetManager; | ||||
| @ -126,40 +57,6 @@ INTERNAL void rendererInit(GameState *state, v2 windowSize) | ||||
| 	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!
 | ||||
| #include <time.h> | ||||
| #include <stdlib.h> | ||||
| @ -345,10 +242,10 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize) | ||||
| 				enum Direction dir = direction_null; | ||||
| 				Texture *tex = asset_getTexture(assetManager, world->texType); | ||||
| 				b32 collides = FALSE; | ||||
| 				Entity *tile = addEntity(arena, world, pos, size, type, dir, | ||||
| 				Entity *tile = entity_add(arena, world, pos, size, type, dir, | ||||
| 				                          tex, collides); | ||||
| 
 | ||||
| 				addAnim(assetManager, animlist_terrain, tile); | ||||
| 				entity_addAnim(assetManager, tile, animlist_terrain); | ||||
| 				tile->currAnimId = animlist_terrain; | ||||
| 			} | ||||
| 		} | ||||
| @ -366,11 +263,11 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize) | ||||
| 	Texture *tex         = NULL; | ||||
| 	b32 collides         = FALSE; | ||||
| 	Entity *soundscape = | ||||
| 	    addEntity(arena, world, pos, size, type, dir, tex, collides); | ||||
| 	    entity_add(arena, world, pos, size, type, dir, tex, collides); | ||||
| 
 | ||||
| 	world->soundscape = soundscape; | ||||
| 	soundscape->audio = PLATFORM_MEM_ALLOC(arena, 1, AudioRenderer); | ||||
| 	soundscape->audio->sourceIndex = AUDIO_SOURCE_UNASSIGNED; | ||||
| 	soundscape->audioRenderer = PLATFORM_MEM_ALLOC(arena, 1, AudioRenderer); | ||||
| 	soundscape->audioRenderer->sourceIndex = AUDIO_SOURCE_UNASSIGNED; | ||||
| 
 | ||||
| 	/* Init hero entity */ | ||||
| 	world->heroIndex   = world->freeEntityIndex; | ||||
| @ -381,14 +278,14 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize) | ||||
| 	dir             = direction_east; | ||||
| 	tex             = asset_getTexture(assetManager, texlist_hero); | ||||
| 	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 */ | ||||
| 	addAnim(assetManager, animlist_hero_idle, hero); | ||||
| 	addAnim(assetManager, animlist_hero_walk, hero); | ||||
| 	addAnim(assetManager, animlist_hero_wave, hero); | ||||
| 	addAnim(assetManager, animlist_hero_battlePose, hero); | ||||
| 	addAnim(assetManager, animlist_hero_tackle, hero); | ||||
| 	entity_addAnim(assetManager, hero, animlist_hero_idle); | ||||
| 	entity_addAnim(assetManager, hero, animlist_hero_walk); | ||||
| 	entity_addAnim(assetManager, hero, animlist_hero_wave); | ||||
| 	entity_addAnim(assetManager, hero, animlist_hero_battlePose); | ||||
| 	entity_addAnim(assetManager, hero, animlist_hero_tackle); | ||||
| 	hero->currAnimId = animlist_hero_idle; | ||||
| 
 | ||||
| 	/* Create a NPC */ | ||||
| @ -398,16 +295,16 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize) | ||||
| 	dir         = direction_null; | ||||
| 	tex         = hero->tex; | ||||
| 	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 */ | ||||
| 	addAnim(assetManager, animlist_hero_wave, npc); | ||||
| 	entity_addAnim(assetManager, npc, animlist_hero_wave); | ||||
| 	npc->currAnimId = animlist_hero_wave; | ||||
| 
 | ||||
| 	/* Create a Mob */ | ||||
| 	pos = V2(renderer->size.w - (renderer->size.w / 3.0f), | ||||
| 	         CAST(f32) state->tileSize); | ||||
| 	addGenericMob(arena, assetManager, world, pos); | ||||
| 	entity_addGenericMob(arena, assetManager, world, pos); | ||||
| #ifdef DENGINE_DEBUG | ||||
| 	DEBUG_LOG("World populated"); | ||||
| #endif | ||||
| @ -415,23 +312,6 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize) | ||||
| 	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) | ||||
| { | ||||
| 	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); | ||||
| 
 | ||||
| 			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; | ||||
| 		} | ||||
| 		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); | ||||
| 		if (hero->currAnimId == animlist_hero_walk) | ||||
| 		{ | ||||
| 			setActiveEntityAnim(hero, animlist_hero_idle); | ||||
| 			entity_setActiveAnim(hero, 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; | ||||
| @ -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) | ||||
| { | ||||
| 	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) | ||||
| { | ||||
| 	updateWorldBattleEntities(world, entity, ENTITY_NOT_IN_BATTLE); | ||||
| 	setActiveEntityAnim(entity, animlist_hero_idle); | ||||
| 	entity_setActiveAnim(entity, animlist_hero_idle); | ||||
| 	entity->stats->busyDuration     = 0; | ||||
| 	entity->stats->actionTimer      = entity->stats->actionRate; | ||||
| 	entity->stats->queuedAttack     = entityattack_invalid; | ||||
| @ -744,7 +592,7 @@ INTERNAL void beginAttack(World *world, Entity *attacker) | ||||
| 		f32 busyDuration       = attackAnim.anim->frameDuration * | ||||
| 		                   CAST(f32) attackAnim.anim->numFrames; | ||||
| 		attacker->stats->busyDuration = busyDuration; | ||||
| 		setActiveEntityAnim(attacker, animlist_hero_tackle); | ||||
| 		entity_setActiveAnim(attacker, animlist_hero_tackle); | ||||
| 		if (attacker->direction == direction_east) | ||||
| 			attacker->dPos.x += (1.0f * METERS_TO_PIXEL); | ||||
| 		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
 | ||||
| 		// or not (i.e. has moved out of frame last frame).
 | ||||
| 		case entitystate_dead: | ||||
| 			setActiveEntityAnim(entity, animlist_hero_idle); | ||||
| 			entity_setActiveAnim(entity, animlist_hero_idle); | ||||
| 			entity->stats->busyDuration     = 0; | ||||
| 			entity->stats->actionTimer      = entity->stats->actionRate; | ||||
| 			entity->stats->queuedAttack     = entityattack_invalid; | ||||
| @ -896,7 +744,7 @@ INTERNAL void entityStateSwitch(World *world, Entity *entity, | ||||
| 		{ | ||||
| 		case entitystate_battle: | ||||
| 			endAttack(world, entity); | ||||
| 			setActiveEntityAnim(entity, animlist_hero_battlePose); | ||||
| 			entity_setActiveAnim(entity, animlist_hero_battlePose); | ||||
| 			entity->stats->actionTimer  = entity->stats->actionRate; | ||||
| 			entity->stats->busyDuration = 0; | ||||
| 			break; | ||||
| @ -956,9 +804,9 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) | ||||
| 	{ | ||||
| 		Entity *const entity = &world->entities[i]; | ||||
| 
 | ||||
| 		if (entity->audio) | ||||
| 		if (entity->audioRenderer) | ||||
| 		{ | ||||
| 			AudioRenderer *audioRenderer = entity->audio; | ||||
| 			AudioRenderer *audioRenderer = entity->audioRenderer; | ||||
| 			if (world->numEntitiesInBattle > 0) | ||||
| 			{ | ||||
| 				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) | ||||
| @ -1002,7 +850,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) | ||||
| 			// an entity dies
 | ||||
| #if 1 | ||||
| 			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
 | ||||
| 			i--; | ||||
| @ -1113,7 +961,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) | ||||
| 		 */ | ||||
| 		if (entity->tex) | ||||
| 		{ | ||||
| 			updateEntityAnim(entity, dt); | ||||
| 			entity_updateAnim(entity, dt); | ||||
| 			/* Calculate region to render */ | ||||
| 			renderer_entity(renderer, cameraBounds, entity, V2(0, 0), 0, | ||||
| 			                V4(1, 1, 1, 1)); | ||||
| @ -1138,7 +986,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) | ||||
| 		{ | ||||
| 			hero->state                       = entitystate_idle; | ||||
| 			world->entityIdInBattle[hero->id] = FALSE; | ||||
| 			setActiveEntityAnim(hero, animlist_hero_idle); | ||||
| 			entity_setActiveAnim(hero, animlist_hero_idle); | ||||
| 		} | ||||
| 		hero->stats->entityIdToAttack = -1; | ||||
| 		hero->stats->actionTimer      = hero->stats->actionRate; | ||||
|  | ||||
| @ -3,9 +3,12 @@ | ||||
| 
 | ||||
| #include "Dengine/Common.h" | ||||
| #include "Dengine/Math.h" | ||||
| #include "Dengine/Texture.h" | ||||
| 
 | ||||
| typedef struct AssetManager AssetManager; | ||||
| typedef struct AudioRenderer AudioRenderer; | ||||
| typedef struct Texture Texture; | ||||
| typedef struct Animation Animation; | ||||
| typedef struct World World; | ||||
| 
 | ||||
| enum Direction | ||||
| { | ||||
| @ -91,7 +94,17 @@ typedef struct Entity | ||||
| 	enum AnimList currAnimId; | ||||
| 
 | ||||
| 	EntityStats *stats; | ||||
| 	AudioRenderer *audio; | ||||
| 	AudioRenderer *audioRenderer; | ||||
| 	i32 numAudioRenderers; | ||||
| } 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 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user