diff --git a/game/systems_input.c b/game/systems_input.c index 8ddaec8..f7e12cd 100644 --- a/game/systems_input.c +++ b/game/systems_input.c @@ -9,8 +9,13 @@ bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Recta void pickEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t **outEntities); void pickEntities(BzSpatialGrid *entityGrid, Rectangle area, ecs_entity_t **outEntities); -static void placeUnits(i32 numUnits, f32 unitSpacing, Vector2 start, Vector2 end, BzTileMap *map, Vector2 **outPlaces); +void placeUnits(i32 numUnits, f32 unitSpacing, Vector2 start, Vector2 end, BzTileMap *map, Vector2 **outPlaces); +void drawSelectionCircles(ecs_entity_t **selected); + +static bool isInputDragged(InputState *input) { + return IsMouseButtonDown(input->LMB && input->mouseDownElapsed > input->CLICK_LIMIT); +} static bool wasInputDragged(InputState *input) { return IsMouseButtonReleased(input->LMB) && input->mouseDownElapsed > input->CLICK_LIMIT; } @@ -52,23 +57,6 @@ void updatePlayerInput(ecs_iter_t *it) { switch (input->state) { case INPUT_NONE: if (wasInputDragged(input)) { - // Dragging - - Vector2 start = input->mouseDownWorld; - Vector2 end = worldPos; - if (start.x > end.x) { - f32 tmp = start.x; - start.x = end.x; - end.x = tmp; - } - if (start.y > end.y) { - f32 tmp = start.y; - start.y = end.y; - end.y = tmp; - } - Rectangle pickArea = {start.x, start.y, end.x - start.x, end.y - start.y}; - - pickEntities(game->entityGrid, pickArea, &input->entities); if (bzArraySize(input->entities) > 0) { input->state = INPUT_SELECTED_UNITS; break; @@ -78,7 +66,6 @@ void updatePlayerInput(ecs_iter_t *it) { // Click // 1. Entity - pickEntity(game->entityGrid, worldPos, &input->entities); if (bzArraySize(input->entities) > 0) { input->state = INPUT_SELECTED_UNITS; break; @@ -109,7 +96,8 @@ void updatePlayerInput(ecs_iter_t *it) { input->buildingSize = (TileSize) {sizeX, sizeY}; break; case INPUT_SELECTED_UNITS: - if (IsKeyPressed(input->ESC)) { + if (IsKeyPressed(input->ESC) || IsMouseButtonPressed(input->RMB)) { + bzArrayClear(input->entities); input->state = INPUT_NONE; break; } @@ -138,7 +126,6 @@ void updatePlayerInput(ecs_iter_t *it) { }); if (!path.paths) continue; ecs_set_ptr(ECS, entity, Path, &path); - input->state = INPUT_NONE; } } else if (wasInputClicked(input)) { bzArrayFor(input->entities, i) { @@ -156,7 +143,6 @@ void updatePlayerInput(ecs_iter_t *it) { }); if (!path.paths) continue; ecs_set_ptr(ECS, entity, Path, &path); - input->state = INPUT_NONE; } } @@ -171,11 +157,12 @@ void updatePlayerInput(ecs_iter_t *it) { void drawPlayerInputUI(ecs_iter_t *it) { Game *game = ecs_singleton_get_mut(ECS, Game); InputState *input = ecs_singleton_get_mut(ECS, InputState); + BzTileMap *map = &game->map; Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera); switch (input->state) { case INPUT_NONE: - if (IsMouseButtonDown(input->LMB) && input->mouseDownElapsed > input->CLICK_LIMIT) { + if (isInputDragged(input)) { Vector2 start = input->mouseDownWorld; Vector2 end = worldPos; if (start.x > end.x) { @@ -190,6 +177,8 @@ void drawPlayerInputUI(ecs_iter_t *it) { } Rectangle area = {start.x, start.y, end.x - start.x, end.y - start.y}; DrawRectangleLines(area.x, area.y, area.width, area.height, RED); + + pickEntities(game->entityGrid, area, &input->entities); } break; case INPUT_BUILDING: { @@ -206,16 +195,20 @@ void drawPlayerInputUI(ecs_iter_t *it) { break; } case INPUT_SELECTED_UNITS: { - bzArrayFor(input->entities, i) { - ecs_entity_t entity = bzArrayGet(input->entities, i); - Position pos = {0}; - if (!getEntityBounds(entity, &pos, NULL, NULL)) - continue; - DrawCircleLines(pos.x, pos.y, 4.5f, GREEN); + if (bzArraySize(input->entities) > 1 && isInputDragged(input)) { + i32 numUnits = bzArraySize(input->entities); + f32 unitSpacing = 3.5f; + bzArrayClear(input->unitPositions); + placeUnits(numUnits, unitSpacing, input->mouseDownWorld, worldPos, + map, &input->unitPositions); + + BZ_ASSERT(bzArraySize(input->unitPositions) == numUnits); + bzArrayFor(input->unitPositions, i) { + Position pos = bzArrayGet(input->unitPositions, i); + DrawCircle(pos.x, pos.y, 2.0f, ORANGE); + } } - - break; } case INPUT_SELECTED_OBJECT: @@ -223,10 +216,8 @@ void drawPlayerInputUI(ecs_iter_t *it) { case INPUT_SELECTED_BUILDING: break; } - bzArrayFor(input->unitPositions, i) { - Position pos = bzArrayGet(input->unitPositions, i); - DrawCircle(pos.x, pos.y, 2.0f, ORANGE); - } + drawSelectionCircles(&input->entities); + } @@ -336,3 +327,15 @@ void placeUnits(i32 numUnits, f32 unitSpacing, Vector2 start, Vector2 end, BzTil pos.x += unitSpacing * 2.0f; } } + +void drawSelectionCircles(ecs_entity_t **selected) { + bzArrayFor(*selected, i) { + ecs_entity_t entity = bzArrayGet(*selected, i); + Position pos = {0}; + if (!getEntityBounds(entity, &pos, NULL, NULL)) + continue; + DrawCircleLines(pos.x, pos.y, 4.5f, GREEN); + + + } +}