Rework input
This commit is contained in:
@@ -4,8 +4,6 @@ ECS_TAG_DECLARE(TextureTerrain);
|
||||
ECS_TAG_DECLARE(TextureBuildings);
|
||||
ECS_TAG_DECLARE(TextureEntities);
|
||||
|
||||
ECS_TAG_DECLARE(UnitSelected);
|
||||
|
||||
ECS_COMPONENT_DECLARE(Resource);
|
||||
|
||||
ECS_COMPONENT_DECLARE(TilePosition);
|
||||
@@ -13,26 +11,34 @@ ECS_COMPONENT_DECLARE(TileSize);
|
||||
ECS_COMPONENT_DECLARE(Owner);
|
||||
|
||||
ECS_COMPONENT_DECLARE(SpatialGridID);
|
||||
|
||||
ECS_COMPONENT_DECLARE(Position);
|
||||
ECS_COMPONENT_DECLARE(Size);
|
||||
ECS_COMPONENT_DECLARE(Velocity);
|
||||
ECS_COMPONENT_DECLARE(TargetPosition);
|
||||
ECS_COMPONENT_DECLARE(Steering);
|
||||
ECS_COMPONENT_DECLARE(Rotation);
|
||||
ECS_COMPONENT_DECLARE(Steering);
|
||||
ECS_COMPONENT_DECLARE(TargetPosition);
|
||||
ECS_COMPONENT_DECLARE(Path);
|
||||
|
||||
ECS_COMPONENT_DECLARE(TextureRegion);
|
||||
|
||||
ECS_COMPONENT_DECLARE(Animation);
|
||||
ECS_COMPONENT_DECLARE(AnimationType);
|
||||
ECS_COMPONENT_DECLARE(Path);
|
||||
|
||||
ECS_TAG_DECLARE(Selectable);
|
||||
ECS_TAG_DECLARE(Selected);
|
||||
|
||||
ECS_TAG_DECLARE(Unit);
|
||||
ECS_TAG_DECLARE(Worker);
|
||||
ECS_TAG_DECLARE(Harvestable);
|
||||
ECS_TAG_DECLARE(Buildable);
|
||||
ECS_TAG_DECLARE(Workable);
|
||||
ECS_TAG_DECLARE(Attackable);
|
||||
|
||||
void initComponentIDs(ecs_world_t *ecs) {
|
||||
ECS_TAG_DEFINE(ecs, TextureTerrain);
|
||||
ECS_TAG_DEFINE(ecs, TextureBuildings);
|
||||
ECS_TAG_DEFINE(ecs, TextureEntities);
|
||||
|
||||
ECS_TAG_DEFINE(ecs, UnitSelected);
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, Resource);
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, TilePosition);
|
||||
@@ -40,16 +46,26 @@ void initComponentIDs(ecs_world_t *ecs) {
|
||||
ECS_COMPONENT_DEFINE(ecs, Owner);
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, SpatialGridID);
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, Position);
|
||||
ECS_COMPONENT_DEFINE(ecs, Size);
|
||||
ECS_COMPONENT_DEFINE(ecs, Velocity);
|
||||
ECS_COMPONENT_DEFINE(ecs, TargetPosition);
|
||||
ECS_COMPONENT_DEFINE(ecs, Steering);
|
||||
ECS_COMPONENT_DEFINE(ecs, Rotation);
|
||||
ECS_COMPONENT_DEFINE(ecs, Steering);
|
||||
ECS_COMPONENT_DEFINE(ecs, TargetPosition);
|
||||
ECS_COMPONENT_DEFINE(ecs, Path);
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, TextureRegion);
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, Animation);
|
||||
ECS_COMPONENT_DEFINE(ecs, AnimationType);
|
||||
ECS_COMPONENT_DEFINE(ecs, Path);
|
||||
|
||||
ECS_TAG_DEFINE(ecs, Selectable);
|
||||
ECS_TAG_DEFINE(ecs, Selected);
|
||||
|
||||
ECS_TAG_DEFINE(ecs, Unit);
|
||||
ECS_TAG_DEFINE(ecs, Worker);
|
||||
ECS_TAG_DEFINE(ecs, Harvestable);
|
||||
ECS_TAG_DEFINE(ecs, Buildable);
|
||||
ECS_TAG_DEFINE(ecs, Workable);
|
||||
ECS_TAG_DEFINE(ecs, Attackable);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ extern ECS_TAG_DECLARE(TextureTerrain);
|
||||
extern ECS_TAG_DECLARE(TextureBuildings);
|
||||
extern ECS_TAG_DECLARE(TextureEntities);
|
||||
|
||||
extern ECS_TAG_DECLARE(UnitSelected);
|
||||
|
||||
typedef enum ResourceType {
|
||||
RES_IRON,
|
||||
@@ -21,6 +20,16 @@ typedef enum ResourceType {
|
||||
RES_COUNT,
|
||||
} ResourceType;
|
||||
|
||||
static const char *getResourceTypePrettyName(ResourceType type) {
|
||||
switch (type) {
|
||||
case RES_IRON: return "Iron";
|
||||
case RES_WOOD: return "Wood";
|
||||
case RES_GOLD: return "Gold";
|
||||
case RES_FOOD: return "Food";
|
||||
default: return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct Resource {
|
||||
ResourceType type;
|
||||
i32 amount;
|
||||
@@ -44,39 +53,24 @@ typedef struct Owner {
|
||||
} Owner;
|
||||
extern ECS_COMPONENT_DECLARE(Owner);
|
||||
|
||||
|
||||
|
||||
/**********************************************************
|
||||
* Movement components
|
||||
*********************************************************/
|
||||
|
||||
typedef BzSpatialGridID SpatialGridID;
|
||||
extern ECS_COMPONENT_DECLARE(SpatialGridID);
|
||||
|
||||
typedef Vector2 Position, Size, Velocity, TargetPosition, Steering;
|
||||
typedef f32 Rotation;
|
||||
|
||||
extern ECS_COMPONENT_DECLARE(Position);
|
||||
extern ECS_COMPONENT_DECLARE(Size);
|
||||
extern ECS_COMPONENT_DECLARE(Velocity);
|
||||
extern ECS_COMPONENT_DECLARE(TargetPosition);
|
||||
extern ECS_COMPONENT_DECLARE(Steering);
|
||||
typedef f32 Rotation;
|
||||
extern ECS_COMPONENT_DECLARE(Rotation);
|
||||
|
||||
typedef struct TextureRegion {
|
||||
Texture2D texture;
|
||||
Rectangle rec;
|
||||
f32 rotation;
|
||||
bool flipX : 1;
|
||||
bool flipY : 1;
|
||||
} TextureRegion;
|
||||
extern ECS_COMPONENT_DECLARE(TextureRegion);
|
||||
|
||||
typedef struct Animation {
|
||||
EntityType entityType;
|
||||
AnimationType animType;
|
||||
AnimationSequence sequence;
|
||||
BzTileset *tileset;
|
||||
i32 curFrame;
|
||||
f32 frameDuration;
|
||||
f32 elapsed;
|
||||
} Animation;
|
||||
extern ECS_COMPONENT_DECLARE(Animation);
|
||||
|
||||
extern ECS_COMPONENT_DECLARE(AnimationType);
|
||||
extern ECS_COMPONENT_DECLARE(Steering);
|
||||
extern ECS_COMPONENT_DECLARE(TargetPosition);
|
||||
|
||||
#define PATH_DATA_SIZE 8
|
||||
typedef struct PathData {
|
||||
@@ -91,12 +85,66 @@ typedef struct Path {
|
||||
} Path;
|
||||
extern ECS_COMPONENT_DECLARE(Path);
|
||||
|
||||
/**********************************************************
|
||||
* Render components
|
||||
*********************************************************/
|
||||
|
||||
typedef struct TextureRegion {
|
||||
Texture2D texture;
|
||||
Rectangle rec;
|
||||
f32 rotation;
|
||||
bool flipX : 1;
|
||||
bool flipY : 1;
|
||||
} TextureRegion;
|
||||
extern ECS_COMPONENT_DECLARE(TextureRegion);
|
||||
|
||||
/**********************************************************
|
||||
* Animation components
|
||||
*********************************************************/
|
||||
|
||||
typedef struct Animation {
|
||||
EntityType entityType;
|
||||
AnimationType animType;
|
||||
AnimationSequence sequence;
|
||||
BzTileset *tileset;
|
||||
i32 curFrame;
|
||||
f32 frameDuration;
|
||||
f32 elapsed;
|
||||
} Animation;
|
||||
extern ECS_COMPONENT_DECLARE(Animation);
|
||||
|
||||
extern ECS_COMPONENT_DECLARE(AnimationType);
|
||||
|
||||
|
||||
|
||||
typedef struct EntityArms {
|
||||
ecs_entity_t left;
|
||||
ecs_entity_t right;
|
||||
} EntityArms;
|
||||
//extern ECS_COMPONENT_DECLARE(EntityArms);
|
||||
|
||||
/**********************************************************
|
||||
* Gameplay components
|
||||
*********************************************************/
|
||||
|
||||
extern ECS_TAG_DECLARE(Selectable);
|
||||
extern ECS_TAG_DECLARE(Selected);
|
||||
|
||||
// Unit can:
|
||||
// - Attack
|
||||
extern ECS_TAG_DECLARE(Unit);
|
||||
|
||||
// Worker can:
|
||||
// - Harvest
|
||||
// - Build
|
||||
// - Work
|
||||
// - Attack (since it is also a unit)
|
||||
extern ECS_TAG_DECLARE(Worker);
|
||||
|
||||
extern ECS_TAG_DECLARE(Harvestable);
|
||||
extern ECS_TAG_DECLARE(Buildable);
|
||||
extern ECS_TAG_DECLARE(Workable);
|
||||
extern ECS_TAG_DECLARE(Attackable);
|
||||
|
||||
void initComponentIDs(ecs_world_t *ecs);
|
||||
|
||||
|
||||
@@ -29,13 +29,18 @@ typedef struct InputState {
|
||||
bool buildingCanPlace;
|
||||
TilePosition buildingPos;
|
||||
TileSize buildingSize;
|
||||
// SELECTED_UNITS
|
||||
/*
|
||||
* 1: Position
|
||||
* 2: Size
|
||||
* 3: UnitSelected
|
||||
*/
|
||||
ecs_query_t *unitSelectedQuery;
|
||||
// Units
|
||||
Rectangle pickArea;
|
||||
|
||||
struct {
|
||||
/* Selected units
|
||||
* 1: Position
|
||||
* 2: Size
|
||||
* 3: UnitSelected
|
||||
*/
|
||||
ecs_query_t *selected;
|
||||
//ecs_query_t *selectedBuilding;
|
||||
} queries;
|
||||
Position *unitPositions;
|
||||
// SELECTED_OBJECT
|
||||
// SELECTED_BUILDING
|
||||
|
||||
37
game/main.c
37
game/main.c
@@ -71,11 +71,13 @@ bool init(void *userData) {
|
||||
input->ESC = KEY_ESCAPE;
|
||||
input->CLICK_LIMIT = 0.2f;
|
||||
|
||||
input->unitSelectedQuery = ecs_query(ECS, {
|
||||
// Create queries
|
||||
input->queries.selected = ecs_query(ECS, {
|
||||
.filter.terms = {
|
||||
{ ecs_id(Position) }, { ecs_id(Size) }, { ecs_id(UnitSelected) }
|
||||
{ ecs_id(Position) }, { ecs_id(Size) }, { ecs_id(Selected) }
|
||||
}
|
||||
});
|
||||
|
||||
input->unitPositions = bzArrayCreate(Position, 16);
|
||||
|
||||
|
||||
@@ -94,7 +96,7 @@ bool init(void *userData) {
|
||||
game->camera.target = (Vector2) {0, 0};
|
||||
game->camera.offset = (Vector2) {screenWidth / 2.0f, screenHeight / 2.0f};
|
||||
game->camera.rotation = 0.0f;
|
||||
game->camera.zoom = 1.0f;
|
||||
game->camera.zoom = 3.0f;
|
||||
game->frameDuration = 0.16f;
|
||||
|
||||
game->terrainTileset = bzTilesetCreate( &(BzTilesetDesc) {
|
||||
@@ -188,6 +190,9 @@ void deinit(void *userData) {
|
||||
Game gameCopy = *game;
|
||||
InputState inputCopy = *input;
|
||||
|
||||
// Destroy queries
|
||||
ecs_query_fini(inputCopy.queries.selected);
|
||||
|
||||
ecs_fini(ECS);
|
||||
ECS = NULL;
|
||||
|
||||
@@ -265,19 +270,33 @@ void imguiRender(float dt, void *userData) {
|
||||
igText("Input state: %s", inputState);
|
||||
if (igCollapsingHeader_TreeNodeFlags("Selection", 0)) {
|
||||
switch (input->state) {
|
||||
case INPUT_SELECTED_UNITS:
|
||||
case INPUT_SELECTED_UNITS: {
|
||||
igText("Selected units:");
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->unitSelectedQuery);
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->queries.selected);
|
||||
while (ecs_iter_next(&it)) {
|
||||
for (i32 i = 0; i < it.count; i++) {
|
||||
igText("\t%llu", it.entities[i]);
|
||||
ecs_entity_t entity = it.entities[i];
|
||||
igText("\tEntity %llu", entity);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case INPUT_SELECTED_OBJECT:
|
||||
break;
|
||||
case INPUT_SELECTED_BUILDING:
|
||||
}
|
||||
case INPUT_SELECTED_OBJECT: {
|
||||
igText("Selected objects:");
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->queries.selected);
|
||||
while (ecs_iter_next(&it)) {
|
||||
for (i32 i = 0; i < it.count; i++) {
|
||||
ecs_entity_t entity = it.entities[i];
|
||||
if (ecs_has(ECS, entity, Harvestable) &&
|
||||
ecs_has(ECS, entity, Resource)) {
|
||||
Resource res = *ecs_get(ECS, entity, Resource);
|
||||
const char *resName = getResourceTypePrettyName(res.type);
|
||||
igText("\tEntity %llu: %d %s", entity, res.amount, resName);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
igText("NONE");
|
||||
break;
|
||||
|
||||
@@ -47,6 +47,9 @@ bool initEntityObjectsLayer(BzTileMap *map, BzTileObjectGroup *objectGroup) {
|
||||
.elapsed=i * 0.1f,
|
||||
});
|
||||
ecs_set(ECS, e, AnimationType, {ANIM_IDLE});
|
||||
ecs_add_id(ECS, e, Selectable);
|
||||
ecs_add_id(ECS, e, Unit);
|
||||
ecs_add_id(ECS, e, Worker);
|
||||
//EntityArms arms = {
|
||||
// .left=ecs_new_id(ECS),
|
||||
// .right=ecs_new_id(ECS),
|
||||
@@ -84,6 +87,7 @@ bool initBuildingsLayer(BzTileMap *map, BzTileLayer *layer) {
|
||||
ownerTile = bzTilesetGetTile(buildingTileset, ownerTile);
|
||||
ownerTile = getTileBuilding(ownerTile);
|
||||
ecs_set(ECS, e, Owner, {.playerID=ownerTile});
|
||||
ecs_add_id(ECS, e, Selectable);
|
||||
|
||||
//bzTileMapUpdateCollider(&GAME.map, x, y);
|
||||
}
|
||||
@@ -118,6 +122,8 @@ bool initTreesLayer(BzTileMap *map, BzTileLayer *layer) {
|
||||
ecs_set(ECS, e, Rotation, {0});
|
||||
ecs_set(ECS, e, TextureRegion, {tileset->tiles, bzTilesetGetTileRegion(tileset, layerTile)});
|
||||
ecs_set(ECS, e, Resource, {RES_WOOD, 20});
|
||||
ecs_add_id(ECS, e, Selectable);
|
||||
ecs_add_id(ECS, e, Harvestable);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
Rectangle calculateEntityBounds(Position pos, Size size);
|
||||
bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Rectangle *outBounds);
|
||||
void pickEntity(BzSpatialGrid *entityGrid, Vector2 point);
|
||||
void pickEntities(BzSpatialGrid *entityGrid, Rectangle area);
|
||||
bool pickEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag);
|
||||
void pickUnits(BzSpatialGrid *entityGrid, Rectangle area);
|
||||
|
||||
static void iterateSelectedUnits(ecs_query_t *query, void (*fn)(ecs_entity_t entity, Position *pos, Size *size));
|
||||
static void iterRemovePaths(ecs_entity_t entity, Position *pos, Size *size);
|
||||
@@ -23,7 +23,7 @@ static bool wasInputDragged(InputState *input) {
|
||||
return IsMouseButtonReleased(input->LMB) && input->mouseDownElapsed > input->CLICK_LIMIT;
|
||||
}
|
||||
static bool wasInputClicked(InputState *input) {
|
||||
return IsMouseButtonReleased(input->LMB);
|
||||
return IsMouseButtonReleased(input->LMB) && input->mouseDownElapsed <= input->CLICK_LIMIT;
|
||||
}
|
||||
|
||||
void updatePlayerInput() {
|
||||
@@ -34,10 +34,10 @@ void updatePlayerInput() {
|
||||
|
||||
Game *game = ecs_singleton_get_mut(ECS, Game);
|
||||
InputState *input = ecs_singleton_get_mut(ECS, InputState);
|
||||
if (IsKeyDown(KEY_W)) game->camera.target.y -= 20;
|
||||
if (IsKeyDown(KEY_S)) game->camera.target.y += 20;
|
||||
if (IsKeyDown(KEY_A)) game->camera.target.x -= 20;
|
||||
if (IsKeyDown(KEY_D)) game->camera.target.x += 20;
|
||||
if (IsKeyDown(KEY_W)) game->camera.target.y -= 5;
|
||||
if (IsKeyDown(KEY_S)) game->camera.target.y += 5;
|
||||
if (IsKeyDown(KEY_A)) game->camera.target.x -= 5;
|
||||
if (IsKeyDown(KEY_D)) game->camera.target.x += 5;
|
||||
|
||||
if (IsKeyDown(KEY_Q)) game->camera.rotation--;
|
||||
if (IsKeyDown(KEY_E)) game->camera.rotation++;
|
||||
@@ -57,30 +57,39 @@ void updatePlayerInput() {
|
||||
Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera);
|
||||
BzTile tileX = 0, tileY = 0;
|
||||
bzTileMapPosToTile(map, worldPos, &tileX, &tileY);
|
||||
i32 selectedUnitCount = ecs_query_entity_count(input->unitSelectedQuery);
|
||||
switch (input->state) {
|
||||
case INPUT_NONE:
|
||||
if (wasInputDragged(input)) {
|
||||
if (selectedUnitCount > 0) {
|
||||
input->state = INPUT_SELECTED_UNITS;
|
||||
break;
|
||||
case INPUT_NONE: {
|
||||
if (isInputDragged(input)) {
|
||||
Vector2 start = input->mouseDownWorld;
|
||||
Vector2 end = worldPos;
|
||||
if (start.x > end.x) {
|
||||
f32 tmp = start.x;
|
||||
start.x = end.x;
|
||||
end.x = tmp;
|
||||
}
|
||||
|
||||
} else if (wasInputClicked(input)) {
|
||||
// Click
|
||||
|
||||
// 1. Entity
|
||||
if (selectedUnitCount > 0) {
|
||||
input->state = INPUT_SELECTED_UNITS;
|
||||
break;
|
||||
if (start.y > end.y) {
|
||||
f32 tmp = start.y;
|
||||
start.y = end.y;
|
||||
end.y = tmp;
|
||||
}
|
||||
|
||||
// 2. Object
|
||||
|
||||
// 3. Building
|
||||
input->pickArea = (Rectangle) {start.x, start.y, end.x - start.x, end.y - start.y};
|
||||
pickUnits(game->entityGrid, input->pickArea);
|
||||
}
|
||||
i32 selectedCount = ecs_query_entity_count(input->queries.selected);
|
||||
if (wasInputClicked(input)) {
|
||||
if (pickEntity(game->entityGrid, input->mouseDownWorld, Unit)) {
|
||||
input->state = INPUT_SELECTED_UNITS;
|
||||
} else if (pickEntity(game->entityGrid, input->mouseDownWorld, Harvestable)) {
|
||||
input->state = INPUT_SELECTED_OBJECT;
|
||||
} else if (pickEntity(game->entityGrid, input->mouseDownWorld, Buildable)) {
|
||||
input->state = INPUT_SELECTED_BUILDING;
|
||||
}
|
||||
} else if (wasInputDragged(input) && selectedCount > 0) {
|
||||
input->state = INPUT_SELECTED_UNITS;
|
||||
}
|
||||
break;
|
||||
case INPUT_BUILDING:
|
||||
}
|
||||
case INPUT_BUILDING: {
|
||||
if (IsKeyPressed(input->ESC) ||
|
||||
IsMouseButtonPressed(input->RMB) ||
|
||||
input->building == 0) {
|
||||
@@ -99,15 +108,17 @@ void updatePlayerInput() {
|
||||
input->buildingPos = (TilePosition) {tileX, tileY};
|
||||
input->buildingSize = (TileSize) {sizeX, sizeY};
|
||||
break;
|
||||
case INPUT_SELECTED_UNITS:
|
||||
}
|
||||
case INPUT_SELECTED_UNITS: {
|
||||
if (IsKeyPressed(input->ESC) || IsMouseButtonPressed(input->RMB)) {
|
||||
ecs_remove_all(ECS, UnitSelected);
|
||||
ecs_remove_all(ECS, Selected);
|
||||
input->state = INPUT_NONE;
|
||||
break;
|
||||
}
|
||||
if (selectedUnitCount > 1 && wasInputDragged(input)) {
|
||||
i32 selectedCount = ecs_query_entity_count(input->queries.selected);
|
||||
if (selectedCount > 1 && wasInputDragged(input)) {
|
||||
// TODO: For click it should just move them
|
||||
i32 numUnits = selectedUnitCount;
|
||||
i32 numUnits = selectedCount;
|
||||
f32 unitSpacing = 3.5f;
|
||||
bzArrayClear(input->unitPositions);
|
||||
placeUnits(numUnits, unitSpacing, input->mouseDownWorld, worldPos,
|
||||
@@ -117,10 +128,10 @@ void updatePlayerInput() {
|
||||
i32 unitPosIdx = 0;
|
||||
|
||||
ecs_defer_begin(ECS);
|
||||
iterateSelectedUnits(input->unitSelectedQuery, iterRemovePaths);
|
||||
iterateSelectedUnits(input->queries.selected, iterRemovePaths);
|
||||
ecs_defer_end(ECS);
|
||||
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->unitSelectedQuery);
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->queries.selected);
|
||||
ecs_defer_begin(ECS);
|
||||
while (ecs_iter_next(&it)) {
|
||||
Position *pos = ecs_field(&it, Position, 1);
|
||||
@@ -149,10 +160,10 @@ void updatePlayerInput() {
|
||||
ecs_defer_end(ECS);
|
||||
} else if (wasInputClicked(input)) {
|
||||
ecs_defer_begin(ECS);
|
||||
iterateSelectedUnits(input->unitSelectedQuery, iterRemovePaths);
|
||||
iterateSelectedUnits(input->queries.selected, iterRemovePaths);
|
||||
ecs_defer_end(ECS);
|
||||
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->unitSelectedQuery);
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->queries.selected);
|
||||
|
||||
ecs_defer_begin(ECS);
|
||||
while (ecs_iter_next(&it)) {
|
||||
@@ -163,12 +174,12 @@ void updatePlayerInput() {
|
||||
|
||||
Path path = {NULL, 0};
|
||||
pathfindAStar(&(PathfindingDesc) {
|
||||
.start=pos[i],
|
||||
.target=worldPos,
|
||||
.map=map,
|
||||
.outPath=&path,
|
||||
.pool=game->pools.pathData,
|
||||
.alloc=&game->stackAlloc
|
||||
.start=pos[i],
|
||||
.target=worldPos,
|
||||
.map=map,
|
||||
.outPath=&path,
|
||||
.pool=game->pools.pathData,
|
||||
.alloc=&game->stackAlloc
|
||||
});
|
||||
if (!path.paths) continue;
|
||||
ecs_set_ptr(ECS, entity, Path, &path);
|
||||
@@ -178,10 +189,16 @@ void updatePlayerInput() {
|
||||
ecs_defer_end(ECS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INPUT_SELECTED_OBJECT:
|
||||
break;
|
||||
case INPUT_SELECTED_BUILDING:
|
||||
if (IsKeyPressed(input->ESC) || IsMouseButtonPressed(input->RMB)) {
|
||||
ecs_remove_all(ECS, Selected);
|
||||
input->state = INPUT_NONE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,26 +208,12 @@ void drawPlayerInputUI() {
|
||||
BzTileMap *map = &game->map;
|
||||
Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera);
|
||||
|
||||
i32 selectedUnitCount = ecs_count_id(ECS, UnitSelected);
|
||||
i32 selectedUnitCount = ecs_count_id(ECS, Selected);
|
||||
switch (input->state) {
|
||||
case INPUT_NONE:
|
||||
if (isInputDragged(input)) {
|
||||
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 area = {start.x, start.y, end.x - start.x, end.y - start.y};
|
||||
Rectangle area = input->pickArea;
|
||||
DrawRectangleLines(area.x, area.y, area.width, area.height, RED);
|
||||
|
||||
pickEntities(game->entityGrid, area);
|
||||
}
|
||||
break;
|
||||
case INPUT_BUILDING: {
|
||||
@@ -243,12 +246,8 @@ void drawPlayerInputUI() {
|
||||
|
||||
break;
|
||||
}
|
||||
case INPUT_SELECTED_OBJECT:
|
||||
break;
|
||||
case INPUT_SELECTED_BUILDING:
|
||||
break;
|
||||
}
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->unitSelectedQuery);
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->queries.selected);
|
||||
rlSetLineWidth(2.0f);
|
||||
while (ecs_query_next(&it)) {
|
||||
Position *pos = ecs_field(&it, Position, 1);
|
||||
@@ -298,13 +297,15 @@ bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Recta
|
||||
return true;
|
||||
}
|
||||
|
||||
void pickEntity(BzSpatialGrid *entityGrid, Vector2 point) {
|
||||
ecs_remove_all(ECS, UnitSelected);
|
||||
bool pickEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag) {
|
||||
ecs_remove_all(ECS, Selected);
|
||||
BzSpatialGridIter it = bzSpatialGridIter(entityGrid, point.x, point.y, 0.0f, 0.0f);
|
||||
f32 closestDst = INFINITY;
|
||||
ecs_entity_t closest = 0;
|
||||
while (bzSpatialGridQueryNext(&it)) {
|
||||
ecs_entity_t entity = *(ecs_entity_t *) it.data;
|
||||
if (!ecs_has_id(ECS, entity, Selectable)) continue;
|
||||
if (!ecs_has_id(ECS, entity, tag)) continue;
|
||||
Vector2 pos;
|
||||
Rectangle bounds;
|
||||
if (!getEntityBounds(entity, &pos, NULL, &bounds)) continue;
|
||||
@@ -318,20 +319,23 @@ void pickEntity(BzSpatialGrid *entityGrid, Vector2 point) {
|
||||
}
|
||||
}
|
||||
if (closest) {
|
||||
ecs_add(ECS, closest, UnitSelected);
|
||||
ecs_add(ECS, closest, Selected);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void pickEntities(BzSpatialGrid *entityGrid, Rectangle area) {
|
||||
ecs_remove_all(ECS, UnitSelected);
|
||||
void pickUnits(BzSpatialGrid *entityGrid, Rectangle area) {
|
||||
ecs_remove_all(ECS, Selected);
|
||||
BzSpatialGridIter it = bzSpatialGridIter(entityGrid, area.x, area.y, area.width, area.height);
|
||||
while (bzSpatialGridQueryNext(&it)) {
|
||||
ecs_entity_t entity = *(ecs_entity_t *) it.data;
|
||||
if (!ecs_has_id(ECS, entity, Unit)) continue;
|
||||
Rectangle bounds;
|
||||
if (!getEntityBounds(entity, NULL, NULL, &bounds)) continue;
|
||||
|
||||
if (!CheckCollisionRecs(area, bounds)) continue;
|
||||
ecs_add(ECS, entity, UnitSelected);
|
||||
ecs_add(ECS, entity, Selected);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user