fp: Make the building behaviours generic and work across multiple buildings
This commit is contained in:
parent
bfe2fef528
commit
57a09d6f9a
166
feely_pona.cpp
166
feely_pona.cpp
@ -1001,13 +1001,12 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action_has_finished) {
|
if (action_has_finished) {
|
||||||
if (!FP_Game_IsNilEntityHandle(game, entity->club_terry_patron)) {
|
if (!FP_Game_IsNilEntityHandle(game, entity->building_patron)) {
|
||||||
FP_GameEntity *patron = FP_Game_GetEntity(game, entity->club_terry_patron);
|
FP_GameEntity *patron = FP_Game_GetEntity(game, entity->building_patron);
|
||||||
patron->flags |= FP_GameEntityFlag_ExperiencedClubTerry;
|
patron->flags &= ~FP_GameEntityFlag_OccupiedInBuilding;
|
||||||
patron->flags &= ~FP_GameEntityFlag_PartyingAtClubTerry;
|
|
||||||
patron->base_acceleration_per_s.meters *= .5f;
|
patron->base_acceleration_per_s.meters *= .5f;
|
||||||
entity->club_terry_patron = {};
|
|
||||||
}
|
}
|
||||||
|
entity->building_patron = {};
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClubTerryState_Idle);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityClubTerryState_Idle);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -1063,6 +1062,19 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case FP_EntityAirportTerryState_FlyPassenger: {
|
case FP_EntityAirportTerryState_FlyPassenger: {
|
||||||
|
if (entering_new_state) {
|
||||||
|
uint64_t duration_ms = 5000;
|
||||||
|
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action_has_finished) {
|
||||||
|
if (!FP_Game_IsNilEntityHandle(game, entity->building_patron)) {
|
||||||
|
FP_GameEntity *patron = FP_Game_GetEntity(game, entity->building_patron);
|
||||||
|
patron->flags &= ~FP_GameEntityFlag_OccupiedInBuilding;
|
||||||
|
}
|
||||||
|
entity->building_patron = {};
|
||||||
|
FP_Game_EntityTransitionState(game, entity, FP_EntityAirportTerryState_Idle);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -1182,7 +1194,22 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case FP_EntityChurchTerryState_ConvertPatron: break;
|
|
||||||
|
case FP_EntityChurchTerryState_ConvertPatron: {
|
||||||
|
if (entering_new_state) {
|
||||||
|
uint64_t duration_ms = 5000;
|
||||||
|
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action_has_finished) {
|
||||||
|
if (!FP_Game_IsNilEntityHandle(game, entity->building_patron)) {
|
||||||
|
FP_GameEntity *patron = FP_Game_GetEntity(game, entity->building_patron);
|
||||||
|
patron->flags &= ~FP_GameEntityFlag_OccupiedInBuilding;
|
||||||
|
}
|
||||||
|
entity->building_patron = {};
|
||||||
|
FP_Game_EntityTransitionState(game, entity, FP_EntityChurchTerryState_Idle);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
@ -1286,7 +1313,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
FP_GameEntity *entity = it.entity;
|
FP_GameEntity *entity = it.entity;
|
||||||
entity->alive_time_s += PHYSICS_STEP;
|
entity->alive_time_s += PHYSICS_STEP;
|
||||||
|
|
||||||
if (entity->flags & FP_GameEntityFlag_PartyingAtClubTerry)
|
if (entity->flags & FP_GameEntityFlag_OccupiedInBuilding)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// NOTE: Move entity by keyboard and gamepad ===============================================
|
// NOTE: Move entity by keyboard and gamepad ===============================================
|
||||||
@ -1344,7 +1371,6 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
Dqn_V2 entity_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
Dqn_V2 entity_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
||||||
|
|
||||||
if (entity->flags & FP_GameEntityFlag_AggrosWhenNearTerry) {
|
if (entity->flags & FP_GameEntityFlag_AggrosWhenNearTerry) {
|
||||||
|
|
||||||
FP_GameFindClosestEntityResult closest_result = FP_Game_FindClosestEntityWithType(game, entity->handle, FP_EntityType_Terry);
|
FP_GameFindClosestEntityResult closest_result = FP_Game_FindClosestEntityWithType(game, entity->handle, FP_EntityType_Terry);
|
||||||
Dqn_f32 aggro_dist_threshold = FP_Game_MetersToPixelsNx1(game, 4.f);
|
Dqn_f32 aggro_dist_threshold = FP_Game_MetersToPixelsNx1(game, 4.f);
|
||||||
|
|
||||||
@ -1391,31 +1417,62 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity->flags & FP_GameEntityFlag_RespondsToClubTerry && (entity->flags & FP_GameEntityFlag_ExperiencedClubTerry) == 0) {
|
if (entity->flags & FP_GameEntityFlag_RespondsToBuildings) {
|
||||||
FP_GameFindClosestEntityResult closest_club = FP_Game_FindClosestEntityWithType(game, entity->handle, FP_EntityType_ClubTerry);
|
FP_GameFindClosestEntityResult closest_building = {};
|
||||||
if (closest_club.dist_squared < DQN_SQUARED(FP_Game_MetersToPixelsNx1(game, 4.f))) {
|
closest_building.dist_squared = DQN_F32_MAX;
|
||||||
|
closest_building.pos = Dqn_V2_InitNx1(DQN_F32_MAX);
|
||||||
|
|
||||||
bool has_waypoint_to_club = false;
|
for (FP_GameEntityIterator building_it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &building_it, game->root_entity); ) {
|
||||||
for (FP_SentinelListLink<FP_GameWaypoint> *link = nullptr;
|
FP_GameEntity *it_entity = building_it.entity;
|
||||||
!has_waypoint_to_club && FP_SentinelList_Iterate<FP_GameWaypoint>(&entity->waypoints, &link); ) {
|
if (it_entity->type != FP_EntityType_ClubTerry &&
|
||||||
has_waypoint_to_club = link->data.entity == closest_club.entity;
|
it_entity->type != FP_EntityType_AirportTerry &&
|
||||||
|
it_entity->type != FP_EntityType_ChurchTerry)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool already_visited_building = false;
|
||||||
|
for (FP_SentinelListLink<FP_GameEntityHandle> *link_it = {};
|
||||||
|
!already_visited_building && FP_SentinelList_Iterate(&entity->buildings_visited, &link_it);
|
||||||
|
) {
|
||||||
|
FP_GameEntityHandle visit_item = link_it->data;
|
||||||
|
already_visited_building = visit_item == it_entity->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_waypoint_to_club) {
|
if (already_visited_building)
|
||||||
Dqn_Rect club_hit_box = FP_Game_CalcEntityWorldHitBox(game, closest_club.entity);
|
continue;
|
||||||
Dqn_V2 club_top_left = Dqn_Rect_TopLeft(club_hit_box);
|
|
||||||
Dqn_V2 club_top_right = Dqn_Rect_TopRight(club_hit_box);
|
Dqn_V2 pos = FP_Game_CalcEntityWorldPos(game, it_entity->handle);
|
||||||
|
Dqn_f32 dist = Dqn_V2_LengthSq_V2x2(pos, entity_pos);
|
||||||
|
if (dist < closest_building.dist_squared) {
|
||||||
|
closest_building.pos = pos;
|
||||||
|
closest_building.dist_squared = dist;
|
||||||
|
closest_building.entity = it_entity->handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FP_Game_IsNilEntityHandle(game, closest_building.entity) &&
|
||||||
|
closest_building.dist_squared < DQN_SQUARED(FP_Game_MetersToPixelsNx1(game, 5.f))) {
|
||||||
|
|
||||||
|
bool has_waypoint_to_building = false;
|
||||||
|
for (FP_SentinelListLink<FP_GameWaypoint> *link = nullptr;
|
||||||
|
!has_waypoint_to_building && FP_SentinelList_Iterate<FP_GameWaypoint>(&entity->waypoints, &link); ) {
|
||||||
|
has_waypoint_to_building = link->data.entity == closest_building.entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!has_waypoint_to_building) {
|
||||||
|
Dqn_Rect hit_box = FP_Game_CalcEntityWorldHitBox(game, closest_building.entity);
|
||||||
|
Dqn_V2 top_left = Dqn_Rect_TopLeft(hit_box);
|
||||||
|
Dqn_V2 top_right = Dqn_Rect_TopRight(hit_box);
|
||||||
|
|
||||||
FP_SentinelListLink<FP_GameWaypoint> *link = FP_SentinelList_MakeBefore(&entity->waypoints, FP_SentinelList_Front(&entity->waypoints), game->chunk_pool);
|
FP_SentinelListLink<FP_GameWaypoint> *link = FP_SentinelList_MakeBefore(&entity->waypoints, FP_SentinelList_Front(&entity->waypoints), game->chunk_pool);
|
||||||
FP_GameWaypoint *waypoint = &link->data;
|
FP_GameWaypoint *waypoint = &link->data;
|
||||||
waypoint->entity = closest_club.entity;
|
waypoint->entity = closest_building.entity;
|
||||||
waypoint->type = FP_GameWaypointType_Side;
|
waypoint->type = FP_GameWaypointType_Side;
|
||||||
|
|
||||||
if (entity_pos.x <= club_top_left.x) {
|
if (entity_pos.x <= top_left.x) {
|
||||||
waypoint->type_direction = FP_GameDirection_Left;
|
waypoint->type_direction = FP_GameDirection_Left;
|
||||||
} else if (entity_pos.x >= club_top_right.x) {
|
} else if (entity_pos.x >= top_right.x) {
|
||||||
waypoint->type_direction = FP_GameDirection_Right;
|
waypoint->type_direction = FP_GameDirection_Right;
|
||||||
} else if (entity_pos.y <= club_top_left.y) {
|
} else if (entity_pos.y <= top_left.y) {
|
||||||
waypoint->type_direction = FP_GameDirection_Up;
|
waypoint->type_direction = FP_GameDirection_Up;
|
||||||
} else {
|
} else {
|
||||||
waypoint->type_direction = FP_GameDirection_Down;
|
waypoint->type_direction = FP_GameDirection_Down;
|
||||||
@ -1493,28 +1550,36 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
|
|
||||||
// NOTE: We have arrived at the waypoint
|
// NOTE: We have arrived at the waypoint
|
||||||
bool aggro_on_terry = (entity->flags & FP_GameEntityFlag_AggrosWhenNearTerry) && waypoint_entity->type == FP_EntityType_Terry;
|
bool aggro_on_terry = (entity->flags & FP_GameEntityFlag_AggrosWhenNearTerry) && waypoint_entity->type == FP_EntityType_Terry;
|
||||||
|
bool building_response = (entity->flags & FP_GameEntityFlag_RespondsToBuildings) &&
|
||||||
bool club_terry_response = (entity->flags & FP_GameEntityFlag_RespondsToClubTerry) &&
|
waypoint_entity->type == FP_EntityType_ClubTerry ||
|
||||||
((entity->flags & FP_GameEntityFlag_ExperiencedClubTerry) == 0) &&
|
waypoint_entity->type == FP_EntityType_AirportTerry ||
|
||||||
waypoint_entity->type == FP_EntityType_ClubTerry;
|
waypoint_entity->type == FP_EntityType_ChurchTerry;
|
||||||
|
|
||||||
bool heart_response = (entity->flags & FP_GameEntityFlag_PointOfInterestHeart) && waypoint_entity->type == FP_EntityType_Heart;
|
bool heart_response = (entity->flags & FP_GameEntityFlag_PointOfInterestHeart) && waypoint_entity->type == FP_EntityType_Heart;
|
||||||
|
|
||||||
if (((waypoint->flags & FP_GameWaypointFlag_NonInterruptible) == 0) && (aggro_on_terry || club_terry_response || heart_response)) {
|
if (((waypoint->flags & FP_GameWaypointFlag_NonInterruptible) == 0) && (aggro_on_terry || building_response || heart_response)) {
|
||||||
bool can_attack = !entity->is_dying; // TODO(doyle): State transition needs to check if it's valid to move to making this not necessary
|
bool can_attack = !entity->is_dying; // TODO(doyle): State transition needs to check if it's valid to move to making this not necessary
|
||||||
|
|
||||||
if (club_terry_response) {
|
if (building_response) {
|
||||||
FP_GameEntity *club = waypoint_entity;
|
FP_GameEntity *building = waypoint_entity;
|
||||||
if (FP_Game_IsNilEntityHandle(game, club->club_terry_patron)) {
|
if (FP_Game_IsNilEntityHandle(game, building->building_patron)) {
|
||||||
club->club_terry_patron = entity->handle;
|
building->building_patron = entity->handle;
|
||||||
FP_Game_EntityTransitionState(game, club, FP_EntityClubTerryState_PartyTime);
|
|
||||||
entity->flags |= FP_GameEntityFlag_PartyingAtClubTerry;
|
|
||||||
|
|
||||||
Dqn_Rect hit_box = FP_Game_CalcEntityWorldHitBox(game, club->handle);
|
if (building->type == FP_EntityType_ClubTerry) {
|
||||||
|
FP_Game_EntityTransitionState(game, building, FP_EntityClubTerryState_PartyTime);
|
||||||
|
} else if (building->type == FP_EntityType_AirportTerry) {
|
||||||
|
FP_Game_EntityTransitionState(game, building, FP_EntityAirportTerryState_FlyPassenger);
|
||||||
|
} else {
|
||||||
|
DQN_ASSERT(building->type == FP_EntityType_ChurchTerry);
|
||||||
|
FP_Game_EntityTransitionState(game, building, FP_EntityChurchTerryState_ConvertPatron);
|
||||||
|
}
|
||||||
|
|
||||||
|
entity->flags |= FP_GameEntityFlag_OccupiedInBuilding;
|
||||||
|
Dqn_Rect hit_box = FP_Game_CalcEntityWorldHitBox(game, building->handle);
|
||||||
Dqn_V2 exit_pos = Dqn_Rect_InterpolatedPoint(hit_box, Dqn_V2_InitNx2(0.5f, 1.1f));
|
Dqn_V2 exit_pos = Dqn_Rect_InterpolatedPoint(hit_box, Dqn_V2_InitNx2(0.5f, 1.1f));
|
||||||
entity->local_pos = exit_pos; // TODO(doyle): Only works when parent world pos is 0,0
|
entity->local_pos = exit_pos; // TODO(doyle): Only works when parent world pos is 0,0
|
||||||
can_attack = false;
|
can_attack = false;
|
||||||
FP_SentinelList_Erase(&entity->waypoints, waypoint_link, game->chunk_pool);
|
FP_SentinelList_Erase(&entity->waypoints, waypoint_link, game->chunk_pool);
|
||||||
|
FP_SentinelList_Add(&entity->buildings_visited, game->chunk_pool, building->handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1557,12 +1622,9 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
DQN_ASSERT(entity->type == FP_EntityType_Clinger);
|
DQN_ASSERT(entity->type == FP_EntityType_Clinger);
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Attack);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Attack);
|
||||||
}
|
}
|
||||||
|
|
||||||
entity->direction = best_attack_dir;
|
entity->direction = best_attack_dir;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case FP_EntityType_Count: DQN_INVALID_CODE_PATH; break;
|
|
||||||
|
|
||||||
case FP_EntityType_Nil: break;
|
case FP_EntityType_Nil: break;
|
||||||
case FP_EntityType_ClubTerry: break;
|
case FP_EntityType_ClubTerry: break;
|
||||||
case FP_EntityType_Map: break;
|
case FP_EntityType_Map: break;
|
||||||
@ -1571,9 +1633,11 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
case FP_EntityType_MerchantGraveyard: break;
|
case FP_EntityType_MerchantGraveyard: break;
|
||||||
case FP_EntityType_MerchantGym: break;
|
case FP_EntityType_MerchantGym: break;
|
||||||
case FP_EntityType_MerchantPhoneCompany: break;
|
case FP_EntityType_MerchantPhoneCompany: break;
|
||||||
case FP_EntityType_AirportTerry:
|
case FP_EntityType_AirportTerry: break;
|
||||||
case FP_EntityType_ChurchTerry:
|
case FP_EntityType_ChurchTerry: break;
|
||||||
case FP_EntityType_KennelTerry: break;
|
case FP_EntityType_KennelTerry: break;
|
||||||
|
case FP_EntityType_PhoneMessageProjectile: break;
|
||||||
|
case FP_EntityType_Count: DQN_INVALID_CODE_PATH; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1731,7 +1795,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
FP_GameEntity *mob = FP_Game_GetEntity(game, link->data);
|
FP_GameEntity *mob = FP_Game_GetEntity(game, link->data);
|
||||||
mob->waypoints = FP_SentinelList_Init<FP_GameWaypoint>(game->chunk_pool);
|
mob->waypoints = FP_SentinelList_Init<FP_GameWaypoint>(game->chunk_pool);
|
||||||
mob->flags |= FP_GameEntityFlag_AggrosWhenNearTerry;
|
mob->flags |= FP_GameEntityFlag_AggrosWhenNearTerry;
|
||||||
mob->flags |= FP_GameEntityFlag_RespondsToClubTerry;
|
mob->flags |= FP_GameEntityFlag_RespondsToBuildings;
|
||||||
|
|
||||||
for (FP_GameEntity *waypoint_entity = entity->first_child; waypoint_entity; waypoint_entity = waypoint_entity->next) {
|
for (FP_GameEntity *waypoint_entity = entity->first_child; waypoint_entity; waypoint_entity = waypoint_entity->next) {
|
||||||
if ((waypoint_entity->flags & FP_GameEntityFlag_MobSpawnerWaypoint) == 0)
|
if ((waypoint_entity->flags & FP_GameEntityFlag_MobSpawnerWaypoint) == 0)
|
||||||
@ -1879,8 +1943,7 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
|
|||||||
// NOTE: Draw entities =========================================================================
|
// NOTE: Draw entities =========================================================================
|
||||||
for (FP_GameEntityIterator it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &it, game->root_entity); ) {
|
for (FP_GameEntityIterator it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &it, game->root_entity); ) {
|
||||||
FP_GameEntity *entity = it.entity;
|
FP_GameEntity *entity = it.entity;
|
||||||
|
if (entity->flags & FP_GameEntityFlag_OccupiedInBuilding)
|
||||||
if (entity->flags & FP_GameEntityFlag_PartyingAtClubTerry)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// NOTE: Render shapes in entity ===========================================================
|
// NOTE: Render shapes in entity ===========================================================
|
||||||
@ -2009,12 +2072,17 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
|
|||||||
TELY_COLOUR_WHITE_V4);
|
TELY_COLOUR_WHITE_V4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity->type == FP_EntityType_ClubTerry) {
|
if (entity->type == FP_EntityType_ClubTerry ||
|
||||||
FP_EntityClubTerryState *state = DQN_CAST(FP_EntityClubTerryState *)&entity->action.state;
|
entity->type == FP_EntityType_AirportTerry ||
|
||||||
if (*state == FP_EntityClubTerryState_PartyTime) {
|
entity->type == FP_EntityType_ChurchTerry) {
|
||||||
Dqn_f32 duration = entity->action.end_at_clock_ms - DQN_CAST(Dqn_f32)entity->action.started_at_clock_ms;
|
|
||||||
Dqn_f32 elapsed = DQN_CAST(Dqn_f32)(game->clock_ms - entity->action.started_at_clock_ms);
|
|
||||||
|
|
||||||
|
FP_GameEntityAction const *action = &entity->action;
|
||||||
|
bool draw_timer = entity->type == FP_EntityType_ClubTerry && action->state == FP_EntityClubTerryState_PartyTime ||
|
||||||
|
entity->type == FP_EntityType_AirportTerry && action->state == FP_EntityAirportTerryState_FlyPassenger ||
|
||||||
|
entity->type == FP_EntityType_ChurchTerry && action->state == FP_EntityChurchTerryState_ConvertPatron;
|
||||||
|
if (draw_timer) {
|
||||||
|
Dqn_f32 duration = action->end_at_clock_ms - DQN_CAST(Dqn_f32)action->started_at_clock_ms;
|
||||||
|
Dqn_f32 elapsed = DQN_CAST(Dqn_f32)(game->clock_ms - action->started_at_clock_ms);
|
||||||
Dqn_f32 t01 = DQN_MIN(1.f, elapsed / duration);
|
Dqn_f32 t01 = DQN_MIN(1.f, elapsed / duration);
|
||||||
Dqn_Rect rect = {};
|
Dqn_Rect rect = {};
|
||||||
rect.pos = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0, -0.3f));
|
rect.pos = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0, -0.3f));
|
||||||
|
@ -222,6 +222,7 @@ static FP_GameEntity *FP_Game_MakeEntityPointerFV(FP_Game *game, DQN_FMT_STRING_
|
|||||||
result->sprite_height.meters = 1;
|
result->sprite_height.meters = 1;
|
||||||
result->parent = FP_Game_ActiveParentEntityPointer(game);
|
result->parent = FP_Game_ActiveParentEntityPointer(game);
|
||||||
result->name = TELY_ChunkPool_AllocFmtFV(game->chunk_pool, fmt, args);
|
result->name = TELY_ChunkPool_AllocFmtFV(game->chunk_pool, fmt, args);
|
||||||
|
result->buildings_visited = FP_SentinelList_Init<FP_GameEntityHandle>(game->chunk_pool);
|
||||||
|
|
||||||
// NOTE: Attach entity as a child to the parent
|
// NOTE: Attach entity as a child to the parent
|
||||||
FP_GameEntity *parent = result->parent;
|
FP_GameEntity *parent = result->parent;
|
||||||
@ -317,6 +318,7 @@ static void FP_Game_DetachEntityIntoFreeList(FP_Game *game, FP_GameEntityHandle
|
|||||||
|
|
||||||
FP_SentinelList_Deinit(&entity->spawn_list, game->chunk_pool);
|
FP_SentinelList_Deinit(&entity->spawn_list, game->chunk_pool);
|
||||||
FP_SentinelList_Deinit(&entity->waypoints, game->chunk_pool);
|
FP_SentinelList_Deinit(&entity->waypoints, game->chunk_pool);
|
||||||
|
FP_SentinelList_Deinit(&entity->buildings_visited, game->chunk_pool);
|
||||||
|
|
||||||
if (new_entity_generation > entity_generation) {
|
if (new_entity_generation > entity_generation) {
|
||||||
// NOTE: Update the incremented handle disassociating all prior handles
|
// NOTE: Update the incremented handle disassociating all prior handles
|
||||||
@ -763,6 +765,27 @@ static void FP_Game_EntityTransitionState(FP_Game *game, FP_GameEntity *entity,
|
|||||||
entity->last_attack_timestamp = game->clock_ms;
|
entity->last_attack_timestamp = game->clock_ms;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case FP_EntityType_AirportTerry: {
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FP_EntityType_ChurchTerry: {
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FP_EntityType_ClubTerry: {
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FP_EntityType_Nil:
|
||||||
|
case FP_EntityType_Catfish:
|
||||||
|
case FP_EntityType_Heart:
|
||||||
|
case FP_EntityType_KennelTerry:
|
||||||
|
case FP_EntityType_Map:
|
||||||
|
case FP_EntityType_MerchantGraveyard:
|
||||||
|
case FP_EntityType_MerchantGym:
|
||||||
|
case FP_EntityType_MerchantPhoneCompany:
|
||||||
|
case FP_EntityType_MerchantTerry:
|
||||||
|
case FP_EntityType_PhoneMessageProjectile:
|
||||||
|
case FP_EntityType_Count: break;
|
||||||
}
|
}
|
||||||
// NOTE: If no returns are hit above we proceed with the state change
|
// NOTE: If no returns are hit above we proceed with the state change
|
||||||
entity->action.next_state = desired_state;
|
entity->action.next_state = desired_state;
|
||||||
|
@ -16,10 +16,9 @@ enum FP_GameEntityFlag
|
|||||||
FP_GameEntityFlag_MobSpawnerWaypoint = 1 << 8,
|
FP_GameEntityFlag_MobSpawnerWaypoint = 1 << 8,
|
||||||
FP_GameEntityFlag_AggrosWhenNearTerry = 1 << 9,
|
FP_GameEntityFlag_AggrosWhenNearTerry = 1 << 9,
|
||||||
FP_GameEntityFlag_Attackable = 1 << 10,
|
FP_GameEntityFlag_Attackable = 1 << 10,
|
||||||
FP_GameEntityFlag_RespondsToClubTerry = 1 << 11,
|
FP_GameEntityFlag_RespondsToBuildings = 1 << 11,
|
||||||
FP_GameEntityFlag_PartyingAtClubTerry = 1 << 12,
|
FP_GameEntityFlag_OccupiedInBuilding = 1 << 12,
|
||||||
FP_GameEntityFlag_ExperiencedClubTerry = 1 << 13,
|
FP_GameEntityFlag_PointOfInterestHeart = 1 << 13,
|
||||||
FP_GameEntityFlag_PointOfInterestHeart = 1 << 11,
|
|
||||||
FP_GameEntityFlag_CameraTracking = 1 << 14,
|
FP_GameEntityFlag_CameraTracking = 1 << 14,
|
||||||
FP_GameEntityFlag_BuildZone = 1 << 15,
|
FP_GameEntityFlag_BuildZone = 1 << 15,
|
||||||
FP_GameEntityFlag_TTL = 1 << 16,
|
FP_GameEntityFlag_TTL = 1 << 16,
|
||||||
@ -162,7 +161,7 @@ struct FP_GameEntity
|
|||||||
FP_SentinelList<FP_GameWaypoint> waypoints;
|
FP_SentinelList<FP_GameWaypoint> waypoints;
|
||||||
FP_GameEntityHandle aggro_slot[FP_GameDirection_Count];
|
FP_GameEntityHandle aggro_slot[FP_GameDirection_Count];
|
||||||
|
|
||||||
FP_GameEntityHandle club_terry_patron;
|
FP_GameEntityHandle building_patron;
|
||||||
|
|
||||||
// NOTE: The entity hit box is positioned at the center of the entity.
|
// NOTE: The entity hit box is positioned at the center of the entity.
|
||||||
Dqn_V2 local_hit_box_size;
|
Dqn_V2 local_hit_box_size;
|
||||||
@ -193,6 +192,7 @@ struct FP_GameEntity
|
|||||||
Dqn_FArray<FP_GameShape, 4> shapes;
|
Dqn_FArray<FP_GameShape, 4> shapes;
|
||||||
Dqn_FArray<FP_GameEntityHandle, 4> projectiles;
|
Dqn_FArray<FP_GameEntityHandle, 4> projectiles;
|
||||||
uint64_t ttl_end_timestamp;
|
uint64_t ttl_end_timestamp;
|
||||||
|
FP_SentinelList<FP_GameEntityHandle> buildings_visited;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FP_GameEntityIterator
|
struct FP_GameEntityIterator
|
||||||
|
Loading…
Reference in New Issue
Block a user