refactored checking if a point is within a cuboid

ice sheets can be crushed
This commit is contained in:
devZoGok
2025-06-04 15:45:27 +03:00
parent 10ae54150d
commit b8051f24df
9 changed files with 91 additions and 19 deletions
+1 -1
View File
@@ -33,7 +33,7 @@ set(CONSOLE console.cpp abstractCommand.cpp addUnitCommand.cpp addResourceComman
set(CORE gameManager.cpp game.cpp fxManager.cpp defConfigs.cpp ${CONSOLE} ${CONTROLLERS}) set(CORE gameManager.cpp game.cpp fxManager.cpp defConfigs.cpp ${CONSOLE} ${CONTROLLERS})
set(PROJECTILES projectile.cpp missile.cpp cruiseMissile.cpp shell.cpp) set(PROJECTILES projectile.cpp missile.cpp cruiseMissile.cpp shell.cpp)
set(VEHICLES vehicle.cpp submarine.cpp engineer.cpp resourceRover.cpp) set(VEHICLES vehicle.cpp submarine.cpp engineer.cpp resourceRover.cpp)
set(STRUCTURES structure.cpp factory.cpp pointDefense.cpp extractor.cpp researchStruct.cpp) set(STRUCTURES structure.cpp factory.cpp pointDefense.cpp extractor.cpp researchStruct.cpp iceSheet.cpp)
set(UNITS gameObjectFactory.cpp unit.cpp ${STRUCTURES} ${VEHICLES}) set(UNITS gameObjectFactory.cpp unit.cpp ${STRUCTURES} ${VEHICLES})
set(CONTENT player.cpp trader.cpp pathfinder.cpp map.cpp gameObject.cpp gameObjectFrame.h resourceDeposit.cpp ${UNITS} ${PROJECTILES}) set(CONTENT player.cpp trader.cpp pathfinder.cpp map.cpp gameObject.cpp gameObjectFrame.h resourceDeposit.cpp ${UNITS} ${PROJECTILES})
set(GAME_SRC ${STATES} ${GUI} ${CORE} ${CONTENT} ${UTIL}) set(GAME_SRC ${STATES} ${GUI} ${CORE} ${CONTENT} ${UTIL})
+21
View File
@@ -156,6 +156,27 @@ namespace battleship{
return sfx; return sfx;
} }
bool GameObject::pointWithinObj(Vector3 point, float deltaLength, float deltaWidth, bool useHeight, float deltaHeight){
Vector3 pointDir = point - pos;
bool within = true;
float forwAngle = std::min(dirVec.getAngleBetween(pointDir.norm()), (-dirVec).getAngleBetween(pointDir.norm()));
float forwDist = pointDir.getLength() * cos(forwAngle);
within &= (forwDist < .5 * (length + deltaLength));
float leftAngle = std::min(leftVec.getAngleBetween(pointDir.norm()), (-leftVec).getAngleBetween(pointDir.norm()));
float leftDist = pointDir.getLength() * cos(leftAngle);
within &= (leftDist < .5 * (width + deltaWidth));
if(useHeight){
float upAngle = std::min(upVec.getAngleBetween(pointDir.norm()), (-upVec).getAngleBetween(pointDir.norm()));
float upDist = pointDir.getLength() * cos(upAngle);
within &= (upDist < .5 * (height + deltaHeight));
}
return within;
}
void GameObject::initSound(){ void GameObject::initSound(){
deathSfxBuffer = new sf::SoundBuffer(); deathSfxBuffer = new sf::SoundBuffer();
string sfxPath = generateView()[getGameObjTableName()][id + 1]["deathSfx"]; string sfxPath = generateView()[getGameObjTableName()][id + 1]["deathSfx"];
+1
View File
@@ -28,6 +28,7 @@ namespace battleship{
std::string getGameObjTableName(); std::string getGameObjTableName();
void updateGameStats(Unit*); void updateGameStats(Unit*);
static sf::Sound* prepareSfx(sf::SoundBuffer*, std::string); static sf::Sound* prepareSfx(sf::SoundBuffer*, std::string);
bool pointWithinObj(vb01::Vector3, float = 0, float = 0, bool = false, float = 0);
inline vb01::Vector2 getScreenPos(){return screenPos;} inline vb01::Vector2 getScreenPos(){return screenPos;}
inline vb01::Vector3 getCorner(int i){return corners[i];} inline vb01::Vector3 getCorner(int i){return corners[i];}
inline bool isSelectable(){return selectable;} inline bool isSelectable(){return selectable;}
+3
View File
@@ -11,6 +11,7 @@
#include "researchStruct.h" #include "researchStruct.h"
#include "missile.h" #include "missile.h"
#include "cruiseMissile.h" #include "cruiseMissile.h"
#include "iceSheet.h"
#include "shell.h" #include "shell.h"
#include "defConfigs.h" #include "defConfigs.h"
@@ -51,6 +52,8 @@ namespace battleship{
return new Extractor(player, id, pos, rot, buildStatus); return new Extractor(player, id, pos, rot, buildStatus);
case UnitClass::LAB: case UnitClass::LAB:
return new ResearchStruct(player, id, pos, rot, buildStatus); return new ResearchStruct(player, id, pos, rot, buildStatus);
case UnitClass::ICE_SHEET:
return new IceSheet(player, id, pos, rot, buildStatus);
default: default:
return new Structure(player, id, pos, rot, buildStatus, Unit::State::STAND_GROUND); return new Structure(player, id, pos, rot, buildStatus, Unit::State::STAND_GROUND);
} }
+24
View File
@@ -0,0 +1,24 @@
#include "iceSheet.h"
#include "player.h"
#include "game.h"
namespace battleship{
using namespace vb01;
using namespace std;
IceSheet::IceSheet(Player *player, int id, Vector3 pos, Quaternion rot, int bldSt) : Structure(player, id, pos, rot, bldSt, Unit::State::STAND_GROUND){}
void IceSheet::update(){
Structure::update();
for(Player *pl : Game::getSingleton()->getPlayers(true)){
vector<Unit*> icebreakers = pl->getUnitsByClass(UnitClass::ICEBREAKER);
for(Unit *icebreaker : icebreakers)
if(icebreaker->pointWithinObj(pos)){
player->removeUnit(this);
return;
}
}
}
}
+15
View File
@@ -0,0 +1,15 @@
#ifndef ICE_SHEET_H
#define ICE_SHEET_H
#include "structure.h"
namespace battleship{
class IceSheet : public Structure{
public:
IceSheet(Player*, int, vb01::Vector3, vb01::Quaternion, int);
void update();
private:
};
}
#endif
+22
View File
@@ -382,6 +382,28 @@ namespace battleship{
return spawnPointsTbl.size(); return spawnPointsTbl.size();
} }
void Map::blockCells(Unit *unit){
for(Cell &cell : cells){
if(cell.blockedBy && cell.blockedBy != unit) continue;
Vector3 cellDir = (cell.pos - unit->getPos()), dirVec = unit->getDirVec(), leftVec = unit->getLeftVec();
float forwAngle = std::min(dirVec.getAngleBetween(cellDir.norm()), (-dirVec).getAngleBetween(cellDir.norm()));
float forwDist = cellDir.getLength() * cos(forwAngle);
float leftAngle = std::min(leftVec.getAngleBetween(cellDir.norm()), (-leftVec).getAngleBetween(cellDir.norm()));
float leftDist = cellDir.getLength() * cos(leftAngle);
bool within = (forwDist < .5 * (unit->getLength() + CELL_SIZE.x) && leftDist < .5 * (unit->getWidth() + CELL_SIZE.z));
cell.blockedBy = (within ? unit : nullptr);
}
}
void Map::unblockCells(Unit *unit){
for(Cell &cell : cells)
if(cell.blockedBy == unit)
cell.blockedBy = nullptr;
}
void Map::loadSpawnPoints(){ void Map::loadSpawnPoints(){
sol::state_view SOL_LUA_VIEW = generateView(); sol::state_view SOL_LUA_VIEW = generateView();
int numSpawnPoints = getNumMapSpawnPoints(); int numSpawnPoints = getNumMapSpawnPoints();
+2
View File
@@ -78,6 +78,8 @@ namespace battleship{
bool isPointWithinTerrainObject(vb01::Vector3, int); bool isPointWithinTerrainObject(vb01::Vector3, int);
void loadPlayerGameObjects(); void loadPlayerGameObjects();
int getNumMapSpawnPoints(std::string = ""); int getNumMapSpawnPoints(std::string = "");
void blockCells(Unit*);
void unblockCells(Unit*);
inline std::string getMapName(){return mapName;} inline std::string getMapName(){return mapName;}
inline vb01::Node* getNodeParent(){return terrainNode;} inline vb01::Node* getNodeParent(){return terrainNode;}
inline vb01::Vector3 getCellSize(){return CELL_SIZE;} inline vb01::Vector3 getCellSize(){return CELL_SIZE;}
+2 -18
View File
@@ -378,6 +378,7 @@ namespace battleship{
} }
Unit::~Unit() { Unit::~Unit() {
Map::getSingleton()->unblockCells(this);
removeBar(hpBackgroundNode); removeBar(hpBackgroundNode);
removeBar(hpForegroundNode); removeBar(hpForegroundNode);
destroyWeapons(); destroyWeapons();
@@ -826,24 +827,7 @@ namespace battleship{
//TODO select only the closest cells based on unit size //TODO select only the closest cells based on unit size
void Unit::placeAt(Vector3 p){ void Unit::placeAt(Vector3 p){
GameObject::placeAt(p); GameObject::placeAt(p);
Map::getSingleton()->blockCells(this);
Map *map = Map::getSingleton();
vector<Map::Cell> &cells = map->getCells();
Vector3 cellSize = map->getCellSize();
for(Map::Cell &cell : cells){
if(cell.blockedBy && cell.blockedBy != this) continue;
Vector3 cellDir = (cell.pos - pos);
float forwAngle = std::min(dirVec.getAngleBetween(cellDir.norm()), (-dirVec).getAngleBetween(cellDir.norm()));
float forwDist = cellDir.getLength() * cos(forwAngle);
float leftAngle = std::min(leftVec.getAngleBetween(cellDir.norm()), (-leftVec).getAngleBetween(cellDir.norm()));
float leftDist = cellDir.getLength() * cos(leftAngle);
bool within = (forwDist < .5 * (length + cellSize.x) && leftDist < .5 * (width + cellSize.z));
cell.blockedBy = (within ? this : nullptr);
}
} }
vector<Player*> Unit::getSelectingPlayers(){ vector<Player*> Unit::getSelectingPlayers(){