fp: Rejig the mob spawner to use a fixed-waypoint path
This commit is contained in:
		
							parent
							
								
									bff3fc759d
								
							
						
					
					
						commit
						30a69e40e9
					
				@ -205,6 +205,7 @@ void TELY_DLL_Init(void *user_data)
 | 
				
			|||||||
    // NOTE: Hero
 | 
					    // NOTE: Hero
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        FP_GameEntity *entity           = FP_Game_MakeEntityPointerF(game, "Terry");
 | 
					        FP_GameEntity *entity           = FP_Game_MakeEntityPointerF(game, "Terry");
 | 
				
			||||||
 | 
					        entity->type                    = FP_EntityType_Terry;
 | 
				
			||||||
        entity->local_pos               = Dqn_V2_InitNx2(1334, 396);
 | 
					        entity->local_pos               = Dqn_V2_InitNx2(1334, 396);
 | 
				
			||||||
        entity->action_to_anim_mapping  = game->terry_action_mappings;
 | 
					        entity->action_to_anim_mapping  = game->terry_action_mappings;
 | 
				
			||||||
        entity->size_scale              = Dqn_V2_InitNx1(0.25f);
 | 
					        entity->size_scale              = Dqn_V2_InitNx1(0.25f);
 | 
				
			||||||
@ -282,13 +283,31 @@ void TELY_DLL_Init(void *user_data)
 | 
				
			|||||||
    // NOTE: Mob spawner ===========================================================================
 | 
					    // NOTE: Mob spawner ===========================================================================
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        FP_GameEntity *entity = FP_Game_MakeEntityPointerF(game, "Mob spawner");
 | 
					        FP_GameEntity *entity = FP_Game_MakeEntityPointerF(game, "Mob spawner");
 | 
				
			||||||
        entity->local_pos     = Dqn_V2_InitNx2(0, platform->core.window_size.y * .5f);
 | 
					        entity->local_pos     = Dqn_V2_InitNx2(50.f, platform->core.window_size.y * .5f);
 | 
				
			||||||
        entity->flags        |= FP_GameEntityFlag_Clickable;
 | 
					        entity->flags        |= FP_GameEntityFlag_Clickable;
 | 
				
			||||||
        entity->flags        |= FP_GameEntityFlag_MoveByKeyboard;
 | 
					        entity->flags        |= FP_GameEntityFlag_MoveByKeyboard;
 | 
				
			||||||
        entity->flags        |= FP_GameEntityFlag_MoveByMouse;
 | 
					        entity->flags        |= FP_GameEntityFlag_MoveByMouse;
 | 
				
			||||||
        entity->flags        |= FP_GameEntityFlag_MoveByGamepad;
 | 
					        entity->flags        |= FP_GameEntityFlag_MoveByGamepad;
 | 
				
			||||||
        entity->flags        |= FP_GameEntityFlag_MobSpawner;
 | 
					        entity->flags        |= FP_GameEntityFlag_MobSpawner;
 | 
				
			||||||
        entity->spawn_cap     = 1;
 | 
					
 | 
				
			||||||
 | 
					        entity->spawn_cap        = 16;
 | 
				
			||||||
 | 
					        entity->spawn_list       = TELY_ChunkPool_New(game->chunk_pool, FP_GameEntitySpawnList);
 | 
				
			||||||
 | 
					        entity->spawn_list->next = entity->spawn_list;
 | 
				
			||||||
 | 
					        entity->spawn_list->prev = entity->spawn_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        FP_Game_PushParentEntity(game, entity->handle);
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                FP_GameEntity *waypoint = FP_Game_MakeEntityPointerF(game, "Waypoint");
 | 
				
			||||||
 | 
					                waypoint->local_pos     = Dqn_V2_InitNx2(800.f, 100.f);
 | 
				
			||||||
 | 
					                waypoint->flags        |= FP_GameEntityFlag_Clickable;
 | 
				
			||||||
 | 
					                waypoint->flags        |= FP_GameEntityFlag_MoveByKeyboard;
 | 
				
			||||||
 | 
					                waypoint->flags        |= FP_GameEntityFlag_MoveByMouse;
 | 
				
			||||||
 | 
					                waypoint->flags        |= FP_GameEntityFlag_MoveByGamepad;
 | 
				
			||||||
 | 
					                waypoint->flags        |= FP_GameEntityFlag_MobSpawnerWaypoint;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        FP_Game_PopParentEntity(game);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint16_t font_size        = 18;
 | 
					    uint16_t font_size        = 18;
 | 
				
			||||||
@ -676,8 +695,11 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer,
 | 
				
			|||||||
                        FP_EntitySmoochieState *state = DQN_CAST(FP_EntitySmoochieState *)&entity->action.state;
 | 
					                        FP_EntitySmoochieState *state = DQN_CAST(FP_EntitySmoochieState *)&entity->action.state;
 | 
				
			||||||
                        move_entity                 = *state == FP_EntitySmoochieState_Run || *state == FP_EntitySmoochieState_Idle;
 | 
					                        move_entity                 = *state == FP_EntitySmoochieState_Run || *state == FP_EntitySmoochieState_Idle;
 | 
				
			||||||
                    } break;
 | 
					                    } break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case FP_EntityType_Merchant: break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (move_entity) {
 | 
				
			||||||
                    acceleration = dir_vector * 10000000.f;
 | 
					                    acceleration = dir_vector * 10000000.f;
 | 
				
			||||||
                    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;
 | 
				
			||||||
@ -685,6 +707,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer,
 | 
				
			|||||||
                        entity->direction = dir_vector.y > 0.f ? FP_GameDirection_Down : FP_GameDirection_Up;
 | 
					                        entity->direction = dir_vector.y > 0.f ? FP_GameDirection_Down : FP_GameDirection_Up;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // NOTE: Stalk entity ======================================================================
 | 
					        // NOTE: Stalk entity ======================================================================
 | 
				
			||||||
        Dqn_V2 entity_world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
 | 
					        Dqn_V2 entity_world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
 | 
				
			||||||
@ -718,17 +741,18 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer,
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // NOTE: Render the waypoints
 | 
					        // NOTE: Render the waypoints
 | 
				
			||||||
        for (FP_GameWaypoint *waypoint = entity->waypoints->next; waypoint != entity->waypoints; waypoint = waypoint->next) {
 | 
					        for (FP_GameWaypoint *waypoint = entity->waypoints->next; waypoint != entity->waypoints; waypoint = waypoint->next) {
 | 
				
			||||||
                Dqn_V2 circle_pos = Dqn_V2_InitNx2(waypoint->pos.x * game->tile_size + game->tile_size * .5f, waypoint->pos.y * game->tile_size + game->tile_size * .5f);
 | 
					            Dqn_V2 circle_pos = Dqn_V2_InitNx2(waypoint->pos.x, waypoint->pos.y);
 | 
				
			||||||
            TELY_Render_CircleColourV4(renderer, circle_pos, 4.f, TELY_RenderShapeMode_Fill, TELY_COLOUR_MAGENTA_V4);
 | 
					            TELY_Render_CircleColourV4(renderer, circle_pos, 4.f, TELY_RenderShapeMode_Fill, TELY_COLOUR_MAGENTA_V4);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (entity->waypoints->next != entity->waypoints) {
 | 
					        if (entity->waypoints->next != entity->waypoints) {
 | 
				
			||||||
            FP_GameWaypoint *waypoint   = entity->waypoints->next;
 | 
					            FP_GameWaypoint *waypoint   = entity->waypoints->next;
 | 
				
			||||||
                Dqn_V2I target_tile         = entity->waypoints->next->pos;
 | 
					            Dqn_V2 target_pos           = Dqn_V2_InitV2I(entity->waypoints->next->pos);
 | 
				
			||||||
                Dqn_V2 target_pos           = Dqn_V2_InitNx2(target_tile.x * game->tile_size + game->tile_size *.5f, target_tile.y * game->tile_size + game->tile_size * .5f);
 | 
					 | 
				
			||||||
            Dqn_V2 entity_to_target_pos = target_pos - entity_world_pos;
 | 
					            Dqn_V2 entity_to_target_pos = target_pos - entity_world_pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (Dqn_V2_LengthSq(entity_to_target_pos) < DQN_SQUARED(entity->local_hit_box_size.x * .5f)) {
 | 
					            if (Dqn_V2_LengthSq(entity_to_target_pos) < DQN_SQUARED(entity->local_hit_box_size.x * .5f)) {
 | 
				
			||||||
@ -738,12 +762,10 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer,
 | 
				
			|||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                Dqn_V2 entity_to_target_pos_norm = Dqn_V2_Normalise(entity_to_target_pos);
 | 
					                Dqn_V2 entity_to_target_pos_norm = Dqn_V2_Normalise(entity_to_target_pos);
 | 
				
			||||||
                if (acceleration.x == 0 && acceleration.y == 0) {
 | 
					                if (acceleration.x == 0 && acceleration.y == 0) {
 | 
				
			||||||
                        acceleration = entity_to_target_pos_norm * 700'000.f;
 | 
					                    acceleration = entity_to_target_pos_norm * 1'000'000.f;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        #endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // NOTE: Core equations of motion ==========================================================
 | 
					        // NOTE: Core equations of motion ==========================================================
 | 
				
			||||||
        bool has_collision = false;
 | 
					        bool has_collision = false;
 | 
				
			||||||
@ -869,12 +891,51 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // NOTE: Mob spawner =======================================================================
 | 
					        // NOTE: Mob spawner =======================================================================
 | 
				
			||||||
        if (entity->flags & FP_GameEntityFlag_MobSpawner) {
 | 
					        if (entity->flags & FP_GameEntityFlag_MobSpawner) {
 | 
				
			||||||
            if (entity->spawn_count < entity->spawn_cap) {
 | 
					            // NOTE: Check if any spawned entities dies to remove it from the spawn cap tracker
 | 
				
			||||||
 | 
					            for (FP_GameEntitySpawnList *link = entity->spawn_list->next; link != entity->spawn_list;) {
 | 
				
			||||||
 | 
					                FP_GameEntity *spawned_entity = FP_Game_GetEntity(game, link->entity);
 | 
				
			||||||
 | 
					                if (spawned_entity) {
 | 
				
			||||||
 | 
					                    // NOTE: Spawned entity is still alive
 | 
				
			||||||
 | 
					                    link = link->next;
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                DQN_ASSERT(entity->spawn_count);
 | 
				
			||||||
 | 
					                entity->spawn_count--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // NOTE: Entity is dead remove it from the linked list
 | 
				
			||||||
 | 
					                FP_GameEntitySpawnList *link_to_delete = link;
 | 
				
			||||||
 | 
					                link->next->prev                       = link->prev;
 | 
				
			||||||
 | 
					                link->prev->next                       = link->next;
 | 
				
			||||||
 | 
					                link                                   = link->next;
 | 
				
			||||||
 | 
					                TELY_ChunkPool_Dealloc(game->chunk_pool, link_to_delete);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (entity->spawn_count < entity->spawn_cap) { // NOTE: Spawn new entities
 | 
				
			||||||
                if (input->timer_s >= entity->next_spawn_timestamp_s) {
 | 
					                if (input->timer_s >= entity->next_spawn_timestamp_s) {
 | 
				
			||||||
                    entity->next_spawn_timestamp_s = DQN_CAST(uint64_t)(input->timer_s + 5.f);
 | 
					                    entity->next_spawn_timestamp_s = DQN_CAST(uint64_t)(input->timer_s + 5.f);
 | 
				
			||||||
                    entity->spawn_count++;
 | 
					                    entity->spawn_count++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    FP_Game_EntityAddMob(game, entity_world_pos);
 | 
					                    FP_GameEntitySpawnList *item = TELY_ChunkPool_New(game->chunk_pool, FP_GameEntitySpawnList);
 | 
				
			||||||
 | 
					                    item->entity                 = FP_Game_EntityAddMob(game, entity_world_pos);
 | 
				
			||||||
 | 
					                    FP_SentinelDoublyLinkedList_Insert(entity->spawn_list, item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // NOTE: Setup the mob with a sentinel waypoint
 | 
				
			||||||
 | 
					                    FP_GameEntity *mob = FP_Game_GetEntity(game, item->entity);
 | 
				
			||||||
 | 
					                    mob->waypoints     = TELY_ChunkPool_New(game->chunk_pool, FP_GameWaypoint);
 | 
				
			||||||
 | 
					                    mob->waypoints->next = mob->waypoints;
 | 
				
			||||||
 | 
					                    mob->waypoints->prev = mob->waypoints;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    for (FP_GameEntity *waypoint_entity = entity->first_child; waypoint_entity; waypoint_entity = waypoint_entity->next) {
 | 
				
			||||||
 | 
					                        if ((waypoint_entity->flags & FP_GameEntityFlag_MobSpawnerWaypoint) == 0)
 | 
				
			||||||
 | 
					                            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // NOTE: Add the waypoint
 | 
				
			||||||
 | 
					                        FP_GameWaypoint *waypoint = TELY_ChunkPool_New(game->chunk_pool, FP_GameWaypoint);
 | 
				
			||||||
 | 
					                        Dqn_V2 waypoint_pos       = FP_Game_CalcEntityWorldPos(game, waypoint_entity->handle);
 | 
				
			||||||
 | 
					                        waypoint->pos             = Dqn_V2I_InitV2(waypoint_pos);
 | 
				
			||||||
 | 
					                        FP_SentinelDoublyLinkedList_Insert(mob->waypoints, waypoint);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,12 @@
 | 
				
			|||||||
#include "feely_pona_unity.h"
 | 
					#include "feely_pona_unity.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FP_SentinelDoublyLinkedList_Insert(list, item) \
 | 
				
			||||||
 | 
					    item->next       = list; \
 | 
				
			||||||
 | 
					    item->prev       = list->prev; \
 | 
				
			||||||
 | 
					    item->next->prev = item; \
 | 
				
			||||||
 | 
					    item->prev->next = item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum FP_ProfileZone
 | 
					enum FP_ProfileZone
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    FP_ProfileZone_FPUpdate = TELY_ProfileZone_Count,
 | 
					    FP_ProfileZone_FPUpdate = TELY_ProfileZone_Count,
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
enum FP_EntityType
 | 
					enum FP_EntityType
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    FP_EntityType_Nil,
 | 
				
			||||||
    FP_EntityType_Terry,
 | 
					    FP_EntityType_Terry,
 | 
				
			||||||
    FP_EntityType_Smoochie,
 | 
					    FP_EntityType_Smoochie,
 | 
				
			||||||
    FP_EntityType_Merchant,
 | 
					    FP_EntityType_Merchant,
 | 
				
			||||||
 | 
				
			|||||||
@ -292,6 +292,9 @@ static void FP_Game_DetachEntityIntoFreeList(FP_Game *game, FP_GameEntityHandle
 | 
				
			|||||||
    if (entity->name.size)
 | 
					    if (entity->name.size)
 | 
				
			||||||
        TELY_ChunkPool_Dealloc(game->chunk_pool, entity->name.data);
 | 
					        TELY_ChunkPool_Dealloc(game->chunk_pool, entity->name.data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (entity->spawn_list)
 | 
				
			||||||
 | 
					        TELY_ChunkPool_Dealloc(game->chunk_pool, entity->spawn_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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
 | 
				
			||||||
        // to this entity which would reference older generation values
 | 
					        // to this entity which would reference older generation values
 | 
				
			||||||
@ -672,7 +675,7 @@ static FP_GameEntityHandle FP_Game_EntityAddMob(FP_Game *game, Dqn_V2 pos)
 | 
				
			|||||||
    entity->local_pos               = pos;
 | 
					    entity->local_pos               = pos;
 | 
				
			||||||
    entity->size_scale              = Dqn_V2_InitNx1(.25f);
 | 
					    entity->size_scale              = Dqn_V2_InitNx1(.25f);
 | 
				
			||||||
    entity->action_to_anim_mapping  = game->smoochie_action_mappings;
 | 
					    entity->action_to_anim_mapping  = game->smoochie_action_mappings;
 | 
				
			||||||
    entity->local_hit_box_size      = Dqn_V2_InitV2I(game->smoochie_sprite_sheet.sprite_size);
 | 
					    entity->local_hit_box_size      = Dqn_V2_InitNx2(428, 471) * entity->size_scale;
 | 
				
			||||||
    entity->flags                  |= FP_GameEntityFlag_Clickable;
 | 
					    entity->flags                  |= FP_GameEntityFlag_Clickable;
 | 
				
			||||||
    entity->flags                  |= FP_GameEntityFlag_MoveByKeyboard;
 | 
					    entity->flags                  |= FP_GameEntityFlag_MoveByKeyboard;
 | 
				
			||||||
    entity->flags                  |= FP_GameEntityFlag_MoveByMouse;
 | 
					    entity->flags                  |= FP_GameEntityFlag_MoveByMouse;
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@ enum FP_GameEntityFlag
 | 
				
			|||||||
    FP_GameEntityFlag_DeriveHitBoxFromChildrenBoundingBox = 1 << 5,
 | 
					    FP_GameEntityFlag_DeriveHitBoxFromChildrenBoundingBox = 1 << 5,
 | 
				
			||||||
    FP_GameEntityFlag_NonTraversable                      = 1 << 6,
 | 
					    FP_GameEntityFlag_NonTraversable                      = 1 << 6,
 | 
				
			||||||
    FP_GameEntityFlag_MobSpawner                          = 1 << 7,
 | 
					    FP_GameEntityFlag_MobSpawner                          = 1 << 7,
 | 
				
			||||||
 | 
					    FP_GameEntityFlag_MobSpawnerWaypoint                  = 1 << 8,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum FP_GameShapeType
 | 
					enum FP_GameShapeType
 | 
				
			||||||
@ -52,6 +53,13 @@ struct FP_GameWaypoint
 | 
				
			|||||||
    FP_GameWaypoint *prev;
 | 
					    FP_GameWaypoint *prev;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct FP_GameEntitySpawnList
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    FP_GameEntityHandle     entity;
 | 
				
			||||||
 | 
					    FP_GameEntitySpawnList *next;
 | 
				
			||||||
 | 
					    FP_GameEntitySpawnList *prev;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum FP_GameEntityActionFlag
 | 
					enum FP_GameEntityActionFlag
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    FP_GameEntityActionFlag_StateTransition = 1 << 0,
 | 
					    FP_GameEntityActionFlag_StateTransition = 1 << 0,
 | 
				
			||||||
@ -112,6 +120,8 @@ struct FP_GameEntity
 | 
				
			|||||||
    Dqn_V2                                 attack_box_size;
 | 
					    Dqn_V2                                 attack_box_size;
 | 
				
			||||||
    Dqn_V2                                 attack_box_offset;
 | 
					    Dqn_V2                                 attack_box_offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Dqn_FArray<Dqn_V2, 8>                  spawner_waypoints;
 | 
				
			||||||
 | 
					    FP_GameEntitySpawnList                *spawn_list;
 | 
				
			||||||
    uint64_t                               next_spawn_timestamp_s;
 | 
					    uint64_t                               next_spawn_timestamp_s;
 | 
				
			||||||
    uint64_t                               spawn_count;
 | 
					    uint64_t                               spawn_count;
 | 
				
			||||||
    uint64_t                               spawn_cap;
 | 
					    uint64_t                               spawn_cap;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user