fp: First draft swarming on entity
This commit is contained in:
		
							parent
							
								
									9fde0594e1
								
							
						
					
					
						commit
						3829a2bdc9
					
				@ -880,35 +880,54 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
 | 
			
		||||
                if (closest_terry_dist < DQN_SQUARED(FP_Game_MetersToPixelsNx1(game, 2.f))) {
 | 
			
		||||
                    FP_SentinelListLink<FP_GameWaypoint> *first_waypoint = FP_SentinelList_Front(&entity->waypoints);
 | 
			
		||||
                    if (first_waypoint->data.entity != closest_terry->handle) {
 | 
			
		||||
 | 
			
		||||
                        FP_GameDirection aggro_direction = FP_GameDirection_Count;
 | 
			
		||||
                        DQN_FOR_UINDEX(dir_index, FP_GameDirection_Count) {
 | 
			
		||||
                            FP_GameEntityHandle slot_entity_handle = closest_terry->aggro_slot[dir_index];
 | 
			
		||||
                            FP_GameEntity *slot_entity             = FP_Game_GetEntity(game, slot_entity_handle);
 | 
			
		||||
                            if (FP_Game_IsNilEntity(slot_entity)) {
 | 
			
		||||
                                aggro_direction = DQN_CAST(FP_GameDirection)dir_index;
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        FP_SentinelListLink<FP_GameWaypoint> *link = FP_SentinelList_MakeBefore(&entity->waypoints, first_waypoint, game->chunk_pool);
 | 
			
		||||
                        link->data.entity                          = closest_terry->handle;
 | 
			
		||||
                        FP_GameWaypoint *waypoint                  = &link->data;
 | 
			
		||||
                        waypoint->entity                           = closest_terry->handle;
 | 
			
		||||
 | 
			
		||||
                        if (aggro_direction != FP_GameDirection_Count) {
 | 
			
		||||
                            waypoint->type                             = FP_GameWaypointType_Side;
 | 
			
		||||
                            waypoint->type_direction                   = aggro_direction;
 | 
			
		||||
                            closest_terry->aggro_slot[aggro_direction] = entity->handle;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            while (entity->waypoints.size) {
 | 
			
		||||
                FP_SentinelListLink<FP_GameWaypoint> *waypoint_link = entity->waypoints.sentinel->next;
 | 
			
		||||
                FP_GameEntity *waypoint = FP_Game_GetEntity(game, waypoint_link->data.entity);
 | 
			
		||||
                if (FP_Game_IsNilEntity(waypoint)) {
 | 
			
		||||
                FP_GameWaypoint const *waypoint                     = &waypoint_link->data;
 | 
			
		||||
                FP_GameEntity *waypoint_entity                      = FP_Game_GetEntity(game, waypoint_link->data.entity);
 | 
			
		||||
                if (FP_Game_IsNilEntity(waypoint_entity)) {
 | 
			
		||||
                    FP_SentinelList_Erase(&entity->waypoints, waypoint_link, game->chunk_pool);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // NOTE: We found a waypoint that is valid to move towards
 | 
			
		||||
                Dqn_V2 waypoint_pos       = FP_Game_CalcEntityWorldPos(game, waypoint->handle);
 | 
			
		||||
                Dqn_V2 entity_to_waypoint = waypoint_pos - entity_pos;
 | 
			
		||||
                Dqn_V2 target_pos         = FP_Game_CalcWaypointWorldPos(game, waypoint);
 | 
			
		||||
                Dqn_V2 entity_to_waypoint = target_pos - entity_pos;
 | 
			
		||||
 | 
			
		||||
                // NOTE: Check if we've arrived at the waypoint
 | 
			
		||||
                Dqn_f32 dist_to_waypoint_sq = Dqn_V2_LengthSq(entity_to_waypoint);
 | 
			
		||||
 | 
			
		||||
                Dqn_f32 arrival_threshold = {};
 | 
			
		||||
                switch (waypoint_link->data.arrive) {
 | 
			
		||||
                switch (waypoint->arrive) {
 | 
			
		||||
                    case FP_GameWaypointArrive_Default: {
 | 
			
		||||
                        arrival_threshold = FP_Game_MetersToPixelsNx1(game, 1.f);
 | 
			
		||||
                    } break;
 | 
			
		||||
 | 
			
		||||
                    case FP_GameWaypointArrive_WhenWithinEntitySize: {
 | 
			
		||||
                        arrival_threshold = DQN_MAX(waypoint->local_hit_box_size.w, waypoint->local_hit_box_size.h) * waypoint_link->data.value;
 | 
			
		||||
                        arrival_threshold = DQN_MAX(waypoint_entity->local_hit_box_size.w, waypoint_entity->local_hit_box_size.h) * waypoint_link->data.value;
 | 
			
		||||
                    } break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -920,7 +939,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // NOTE: We have arrived at the waypoint
 | 
			
		||||
                if ((entity->flags & FP_GameEntityFlag_AggrosWhenNearTerry) && waypoint->type == FP_EntityType_Terry) {
 | 
			
		||||
                if ((entity->flags & FP_GameEntityFlag_AggrosWhenNearTerry) && waypoint_entity->type == FP_EntityType_Terry) {
 | 
			
		||||
                    // NOTE: We had a waypoint to move to Terry because he has
 | 
			
		||||
                    // drawn our aggro and we've arrived at Terry
 | 
			
		||||
 | 
			
		||||
@ -1330,6 +1349,7 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
 | 
			
		||||
            TELY_Render_TextureColourV4(renderer, sprite->asset.sheet->tex_handle, src_rect, dest_rect, TELY_COLOUR_WHITE_V4);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // NOTE: Render waypoint entities ==========================================================
 | 
			
		||||
        if (entity->flags & FP_GameEntityFlag_MobSpawner) {
 | 
			
		||||
            Dqn_V2 start = world_pos;
 | 
			
		||||
            for (FP_GameEntity *waypoint_entity = entity->first_child; waypoint_entity; waypoint_entity = waypoint_entity->next) {
 | 
			
		||||
@ -1357,19 +1377,12 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
 | 
			
		||||
            TELY_Render_RectColourV4(renderer, world_hit_box, TELY_RenderShapeMode_Line, TELY_COLOUR_WHITE_PALE_GOLDENROD_V4);
 | 
			
		||||
 | 
			
		||||
            // NOTE: Draw the waypoints that the entity is moving along
 | 
			
		||||
            if (entity->waypoints.size) {
 | 
			
		||||
                Dqn_V2 start = world_pos;
 | 
			
		||||
                for (FP_SentinelListLink<FP_GameWaypoint> *link = nullptr; FP_SentinelList_Iterate(&entity->waypoints, &link); ) {
 | 
			
		||||
                    FP_GameEntity *waypoint = FP_Game_GetEntity(game, link->data.entity);
 | 
			
		||||
                    if (FP_Game_IsNilEntity(waypoint))
 | 
			
		||||
                        continue;
 | 
			
		||||
 | 
			
		||||
                    Dqn_V2 end = FP_Game_CalcEntityWorldPos(game, waypoint->handle);
 | 
			
		||||
                    TELY_Render_LineColourV4(renderer, start, end, TELY_COLOUR_WHITE_PALE_GOLDENROD_V4, 2.f);
 | 
			
		||||
                    start      = end;
 | 
			
		||||
                }
 | 
			
		||||
            Dqn_V2 start = world_pos;
 | 
			
		||||
            for (FP_SentinelListLink<FP_GameWaypoint> *link = nullptr; FP_SentinelList_Iterate(&entity->waypoints, &link); ) {
 | 
			
		||||
                Dqn_V2 end = FP_Game_CalcWaypointWorldPos(game, &link->data);
 | 
			
		||||
                TELY_Render_LineColourV4(renderer, start, end, TELY_COLOUR_WHITE_PALE_GOLDENROD_V4, 2.f);
 | 
			
		||||
                start      = end;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } else if (game->hot_entity == entity->handle || (entity->flags & FP_GameEntityFlag_DrawHitBox)) {
 | 
			
		||||
            Dqn_V4 hot_colour = game->hot_entity == entity->handle ? TELY_COLOUR_RED_TOMATO_V4 : TELY_Colour_V4Alpha(TELY_COLOUR_YELLOW_SANDY_V4, .5f);
 | 
			
		||||
            TELY_Render_RectColourV4(renderer, world_hit_box, TELY_RenderShapeMode_Line, hot_colour);
 | 
			
		||||
 | 
			
		||||
@ -630,3 +630,48 @@ static Dqn_Slice<Dqn_V2I> FP_Game_AStarPathFind(FP_Game            *game,
 | 
			
		||||
    DQN_ASSERT(result.size == slice_size);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Dqn_V2 FP_Game_CalcWaypointWorldPos(FP_Game *game, FP_GameWaypoint const *waypoint)
 | 
			
		||||
{
 | 
			
		||||
    Dqn_V2 result = {};
 | 
			
		||||
    if (!game || !waypoint)
 | 
			
		||||
        return result;
 | 
			
		||||
 | 
			
		||||
    FP_GameEntity *waypoint_entity = FP_Game_GetEntity(game, waypoint->entity);
 | 
			
		||||
    if (FP_Game_IsNilEntity(waypoint_entity))
 | 
			
		||||
        return result;
 | 
			
		||||
 | 
			
		||||
    // NOTE: We found a waypoint that is valid to move towards
 | 
			
		||||
    switch (waypoint->type) {
 | 
			
		||||
        case FP_GameWaypointType_At: {
 | 
			
		||||
            result = FP_Game_CalcEntityWorldPos(game, waypoint_entity->handle);
 | 
			
		||||
        } break;
 | 
			
		||||
 | 
			
		||||
        case FP_GameWaypointType_Side: {
 | 
			
		||||
            Dqn_Rect entity_rect = FP_Game_CalcEntityWorldHitBox(game, waypoint_entity->handle);
 | 
			
		||||
            switch (waypoint->type_direction) {
 | 
			
		||||
                case FP_GameDirection_Up: {
 | 
			
		||||
                    result = Dqn_V2_InitNx2(entity_rect.pos.x + entity_rect.size.w * .5f, entity_rect.pos.y - entity_rect.size.h * .5f);
 | 
			
		||||
                } break;
 | 
			
		||||
 | 
			
		||||
                case FP_GameDirection_Down: {
 | 
			
		||||
                    result = Dqn_V2_InitNx2(entity_rect.pos.x + entity_rect.size.w * .5f, entity_rect.pos.y + entity_rect.size.h + (entity_rect.size.h * .5f));
 | 
			
		||||
                } break;
 | 
			
		||||
 | 
			
		||||
                case FP_GameDirection_Left: {
 | 
			
		||||
                    result = Dqn_V2_InitNx2(entity_rect.pos.x - entity_rect.size.w * .5f, entity_rect.pos.y + entity_rect.size.h * .5f);
 | 
			
		||||
                } break;
 | 
			
		||||
 | 
			
		||||
                case FP_GameDirection_Right: {
 | 
			
		||||
                    result = Dqn_V2_InitNx2(entity_rect.pos.x + entity_rect.size.w + entity_rect.size.w * .5f, entity_rect.pos.y + entity_rect.size.h * .5f);
 | 
			
		||||
                } break;
 | 
			
		||||
 | 
			
		||||
                case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
 | 
			
		||||
            }
 | 
			
		||||
        } break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -63,8 +63,25 @@ enum FP_GameWaypointArrive
 | 
			
		||||
    FP_GameWaypointArrive_WhenWithinEntitySize,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum FP_GameWaypointType
 | 
			
		||||
{
 | 
			
		||||
    FP_GameWaypointType_At,    // Move to the specified entity
 | 
			
		||||
    FP_GameWaypointType_Side, // Move to the side of the entity specified by the direction
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum FP_GameDirection
 | 
			
		||||
{
 | 
			
		||||
    FP_GameDirection_Up,
 | 
			
		||||
    FP_GameDirection_Down,
 | 
			
		||||
    FP_GameDirection_Left,
 | 
			
		||||
    FP_GameDirection_Right,
 | 
			
		||||
    FP_GameDirection_Count,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct FP_GameWaypoint
 | 
			
		||||
{
 | 
			
		||||
    FP_GameWaypointType   type;
 | 
			
		||||
    FP_GameDirection      type_direction;
 | 
			
		||||
    FP_GameEntityHandle   entity;
 | 
			
		||||
    FP_GameWaypointArrive arrive;
 | 
			
		||||
    Dqn_f32               value;
 | 
			
		||||
@ -93,14 +110,6 @@ struct FP_GameEntityAction
 | 
			
		||||
    uint64_t                 end_at_clock_ms;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum FP_GameDirection
 | 
			
		||||
{
 | 
			
		||||
    FP_GameDirection_Up,
 | 
			
		||||
    FP_GameDirection_Down,
 | 
			
		||||
    FP_GameDirection_Left,
 | 
			
		||||
    FP_GameDirection_Right,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct FP_GameRenderSprite
 | 
			
		||||
{
 | 
			
		||||
    Dqn_V2                   offset;
 | 
			
		||||
@ -134,6 +143,7 @@ struct FP_GameEntity
 | 
			
		||||
    Dqn_FArray<FP_GameRenderSprite, 2>    extra_cosmetic_anims;
 | 
			
		||||
 | 
			
		||||
    FP_SentinelList<FP_GameWaypoint>      waypoints;
 | 
			
		||||
    FP_GameEntityHandle                   aggro_slot[FP_GameDirection_Count];
 | 
			
		||||
 | 
			
		||||
    // NOTE: The entity hit box is positioned at the center of the entity.
 | 
			
		||||
    Dqn_V2                                local_hit_box_size;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user