fp: Slow patron after club terry
This commit is contained in:
parent
e467abf922
commit
fbf94b12b9
@ -339,7 +339,7 @@ void TELY_DLL_Init(void *user_data)
|
|||||||
// NOTE: Mob spawner ===========================================================================
|
// NOTE: Mob spawner ===========================================================================
|
||||||
{
|
{
|
||||||
Dqn_V2 mob_spawner_pos = FP_Game_MetersToPixelsNx2(game, 2.f, 5.f);
|
Dqn_V2 mob_spawner_pos = FP_Game_MetersToPixelsNx2(game, 2.f, 5.f);
|
||||||
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, mob_spawner_pos, 128 /*spawn_cap*/, "Mob spawner");
|
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, mob_spawner_pos, 1 /*spawn_cap*/, "Mob spawner");
|
||||||
FP_Game_PushParentEntity(game, mob_spawner);
|
FP_Game_PushParentEntity(game, mob_spawner);
|
||||||
FP_Entity_CreateWaypointF(game, FP_Game_MetersToPixelsNx2(game, 2.f, 4.f), "Waypoint A");
|
FP_Entity_CreateWaypointF(game, FP_Game_MetersToPixelsNx2(game, 2.f, 4.f), "Waypoint A");
|
||||||
FP_Entity_CreateWaypointF(game, FP_Game_MetersToPixelsNx2(game, 14.f, 8.f), "Waypoint B");
|
FP_Entity_CreateWaypointF(game, FP_Game_MetersToPixelsNx2(game, 14.f, 8.f), "Waypoint B");
|
||||||
@ -854,9 +854,28 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_PlatformInput *input, FP_Ga
|
|||||||
uint64_t duration_ms = FP_GAME_ENTITY_ACTION_INFINITE_TIMER;
|
uint64_t duration_ms = FP_GAME_ENTITY_ACTION_INFINITE_TIMER;
|
||||||
FP_Game_EntityActionReset(game, entity->handle, duration_ms, sprite);
|
FP_Game_EntityActionReset(game, entity->handle, duration_ms, sprite);
|
||||||
}
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FP_EntityClubTerryState_PartyTime: {
|
||||||
|
if (entering_new_state) {
|
||||||
|
TELY_AssetAnimatedSprite sprite = TELY_Asset_MakeAnimatedSprite(sheet, g_anim_names.club_terry_alive, TELY_AssetFlip_No);
|
||||||
|
uint64_t duration_ms = 5000;
|
||||||
|
FP_Game_EntityActionReset(game, entity->handle, duration_ms, sprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action_has_finished) {
|
||||||
|
if (!FP_Game_IsNilEntityHandle(game, entity->club_terry_patron)) {
|
||||||
|
FP_GameEntity *patron = FP_Game_GetEntity(game, entity->club_terry_patron);
|
||||||
|
patron->flags |= FP_GameEntityFlag_ExperiencedClubTerry;
|
||||||
|
patron->flags &= ~FP_GameEntityFlag_PartyingAtClubTerry;
|
||||||
|
patron->base_acceleration_per_s.meters *= .5f;
|
||||||
|
entity->club_terry_patron = {};
|
||||||
|
}
|
||||||
|
action->next_state = FP_EntityClubTerryState_Idle;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case FP_EntityType_Nil: break;
|
case FP_EntityType_Nil: break;
|
||||||
@ -923,6 +942,9 @@ 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)
|
||||||
|
continue;
|
||||||
|
|
||||||
// NOTE: Move entity by keyboard and gamepad ===============================================
|
// NOTE: Move entity by keyboard and gamepad ===============================================
|
||||||
Dqn_V2 acceleration_meters_per_s = {};
|
Dqn_V2 acceleration_meters_per_s = {};
|
||||||
if (game->clicked_entity == entity->handle) {
|
if (game->clicked_entity == entity->handle) {
|
||||||
@ -951,7 +973,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (move_entity) {
|
if (move_entity) {
|
||||||
acceleration_meters_per_s = dir_vector * 8;
|
acceleration_meters_per_s = dir_vector * entity->base_acceleration_per_s.meters;
|
||||||
if (dir_vector.x)
|
if (dir_vector.x)
|
||||||
entity->direction = dir_vector.x > 0.f ? FP_GameDirection_Right : FP_GameDirection_Left;
|
entity->direction = dir_vector.x > 0.f ? FP_GameDirection_Right : FP_GameDirection_Left;
|
||||||
else if (dir_vector.y)
|
else if (dir_vector.y)
|
||||||
@ -1006,7 +1028,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity->flags & FP_GameEntityFlag_RespondsToClubTerry) {
|
if (entity->flags & FP_GameEntityFlag_RespondsToClubTerry && (entity->flags & FP_GameEntityFlag_ExperiencedClubTerry) == 0) {
|
||||||
FP_GameFindClosestEntityResult closest_club = FP_Game_FindClosestEntityWithType(game, entity->handle, FP_EntityType_ClubTerry);
|
FP_GameFindClosestEntityResult closest_club = FP_Game_FindClosestEntityWithType(game, entity->handle, FP_EntityType_ClubTerry);
|
||||||
if (closest_club.dist_squared < DQN_SQUARED(FP_Game_MetersToPixelsNx1(game, 4.f))) {
|
if (closest_club.dist_squared < DQN_SQUARED(FP_Game_MetersToPixelsNx1(game, 4.f))) {
|
||||||
|
|
||||||
@ -1069,15 +1091,33 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
// NOTE: We haven't arrived yet, calculate an acceleration vector to the waypoint
|
// NOTE: We haven't arrived yet, calculate an acceleration vector to the waypoint
|
||||||
if (dist_to_waypoint_sq > DQN_SQUARED(arrival_threshold)) {
|
if (dist_to_waypoint_sq > DQN_SQUARED(arrival_threshold)) {
|
||||||
Dqn_V2 entity_to_waypoint_norm = Dqn_V2_Normalise(entity_to_waypoint);
|
Dqn_V2 entity_to_waypoint_norm = Dqn_V2_Normalise(entity_to_waypoint);
|
||||||
acceleration_meters_per_s = entity_to_waypoint_norm * 2.f;
|
acceleration_meters_per_s = entity_to_waypoint_norm * (entity->base_acceleration_per_s.meters * 0.25f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 club_terry_response = (entity->flags & FP_GameEntityFlag_RespondsToClubTerry) && waypoint_entity->type == FP_EntityType_ClubTerry;
|
bool club_terry_response = (entity->flags & FP_GameEntityFlag_RespondsToClubTerry) &&
|
||||||
|
((entity->flags & FP_GameEntityFlag_ExperiencedClubTerry) == 0) &&
|
||||||
|
waypoint_entity->type == FP_EntityType_ClubTerry;
|
||||||
if (((waypoint->flags & FP_GameWaypointFlag_NonInterruptible) == 0) && (aggro_on_terry || club_terry_response)) {
|
if (((waypoint->flags & FP_GameWaypointFlag_NonInterruptible) == 0) && (aggro_on_terry || club_terry_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) {
|
||||||
|
FP_GameEntity *club = waypoint_entity;
|
||||||
|
if (FP_Game_IsNilEntityHandle(game, club->club_terry_patron)) {
|
||||||
|
club->club_terry_patron = entity->handle;
|
||||||
|
club->action.next_state = FP_EntityClubTerryState_PartyTime;
|
||||||
|
entity->flags |= FP_GameEntityFlag_PartyingAtClubTerry;
|
||||||
|
|
||||||
|
Dqn_Rect hit_box = FP_Game_CalcEntityWorldHitBox(game, club->handle);
|
||||||
|
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
|
||||||
|
can_attack = false;
|
||||||
|
FP_SentinelList_Erase(&entity->waypoints, waypoint_link, game->chunk_pool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (can_attack) {
|
if (can_attack) {
|
||||||
Dqn_V2 attack_dir_vectors[FP_GameDirection_Count] = {};
|
Dqn_V2 attack_dir_vectors[FP_GameDirection_Count] = {};
|
||||||
attack_dir_vectors[FP_GameDirection_Up] = Dqn_V2_InitNx2(+0, -1);
|
attack_dir_vectors[FP_GameDirection_Up] = Dqn_V2_InitNx2(+0, -1);
|
||||||
@ -1311,6 +1351,9 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
|
|||||||
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_PartyingAtClubTerry)
|
||||||
|
continue;
|
||||||
|
|
||||||
// NOTE: Render shapes in entity ===========================================================
|
// NOTE: Render shapes in entity ===========================================================
|
||||||
Dqn_V2 world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
Dqn_V2 world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
||||||
for (FP_GameShape const &shape_ : entity->shapes) {
|
for (FP_GameShape const &shape_ : entity->shapes) {
|
||||||
|
@ -53,4 +53,5 @@ enum FP_EntityClubTerryState
|
|||||||
{
|
{
|
||||||
FP_EntityClubTerryState_Nil,
|
FP_EntityClubTerryState_Nil,
|
||||||
FP_EntityClubTerryState_Idle,
|
FP_EntityClubTerryState_Idle,
|
||||||
|
FP_EntityClubTerryState_PartyTime,
|
||||||
};
|
};
|
||||||
|
@ -53,6 +53,7 @@ static FP_GameEntityHandle FP_Entity_CreateClinger(FP_Game *game, Dqn_V2 pos, DQ
|
|||||||
entity->type = FP_EntityType_Clinger;
|
entity->type = FP_EntityType_Clinger;
|
||||||
entity->hp = 1;
|
entity->hp = 1;
|
||||||
entity->is_dying = false;
|
entity->is_dying = false;
|
||||||
|
entity->base_acceleration_per_s.meters = 8.f;
|
||||||
entity->local_pos = pos;
|
entity->local_pos = pos;
|
||||||
entity->sprite_height.meters = 1.6f;
|
entity->sprite_height.meters = 1.6f;
|
||||||
|
|
||||||
@ -72,6 +73,7 @@ static FP_GameEntityHandle FP_Entity_CreateSmoochie(FP_Game *game, Dqn_V2 pos, D
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
entity->type = FP_EntityType_Smoochie;
|
entity->type = FP_EntityType_Smoochie;
|
||||||
|
entity->base_acceleration_per_s.meters = 8.f;
|
||||||
entity->hp = 1;
|
entity->hp = 1;
|
||||||
entity->is_dying = false;
|
entity->is_dying = false;
|
||||||
entity->local_pos = pos;
|
entity->local_pos = pos;
|
||||||
@ -138,6 +140,7 @@ static FP_GameEntityHandle FP_Entity_CreateTerry(FP_Game *game, Dqn_V2 pos, DQN_
|
|||||||
|
|
||||||
entity->type = FP_EntityType_Terry;
|
entity->type = FP_EntityType_Terry;
|
||||||
entity->local_pos = pos;
|
entity->local_pos = pos;
|
||||||
|
entity->base_acceleration_per_s.meters = 8.f;
|
||||||
entity->sprite_height.meters = 1.8f;
|
entity->sprite_height.meters = 1.8f;
|
||||||
entity->local_hit_box_size = FP_Game_MetersToPixelsNx2(game, 0.5f, entity->sprite_height.meters * .6f);
|
entity->local_hit_box_size = FP_Game_MetersToPixelsNx2(game, 0.5f, entity->sprite_height.meters * .6f);
|
||||||
FP_Entity_AddDebugEditorFlags(game, result);
|
FP_Entity_AddDebugEditorFlags(game, result);
|
||||||
|
@ -17,6 +17,8 @@ enum FP_GameEntityFlag
|
|||||||
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_RespondsToClubTerry = 1 << 11,
|
||||||
|
FP_GameEntityFlag_PartyingAtClubTerry = 1 << 12,
|
||||||
|
FP_GameEntityFlag_ExperiencedClubTerry = 1 << 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FP_GameShapeType
|
enum FP_GameShapeType
|
||||||
@ -144,6 +146,7 @@ struct FP_GameEntity
|
|||||||
// is scaled uniformly with respect to the height.
|
// is scaled uniformly with respect to the height.
|
||||||
FP_Meters sprite_height;
|
FP_Meters sprite_height;
|
||||||
FP_GameEntityAction action;
|
FP_GameEntityAction action;
|
||||||
|
FP_Meters base_acceleration_per_s;
|
||||||
Dqn_V2 velocity;
|
Dqn_V2 velocity;
|
||||||
|
|
||||||
// Extra animations that are to be executed, but, don't affect the state
|
// Extra animations that are to be executed, but, don't affect the state
|
||||||
@ -154,6 +157,8 @@ 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;
|
||||||
|
|
||||||
// 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;
|
||||||
Dqn_V2 local_hit_box_offset;
|
Dqn_V2 local_hit_box_offset;
|
||||||
|
Loading…
Reference in New Issue
Block a user