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(PROJECTILES projectile.cpp missile.cpp cruiseMissile.cpp shell.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(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})
+21
View File
@@ -156,6 +156,27 @@ namespace battleship{
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(){
deathSfxBuffer = new sf::SoundBuffer();
string sfxPath = generateView()[getGameObjTableName()][id + 1]["deathSfx"];
+1
View File
@@ -28,6 +28,7 @@ namespace battleship{
std::string getGameObjTableName();
void updateGameStats(Unit*);
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::Vector3 getCorner(int i){return corners[i];}
inline bool isSelectable(){return selectable;}
+3
View File
@@ -11,6 +11,7 @@
#include "researchStruct.h"
#include "missile.h"
#include "cruiseMissile.h"
#include "iceSheet.h"
#include "shell.h"
#include "defConfigs.h"
@@ -51,6 +52,8 @@ namespace battleship{
return new Extractor(player, id, pos, rot, buildStatus);
case UnitClass::LAB:
return new ResearchStruct(player, id, pos, rot, buildStatus);
case UnitClass::ICE_SHEET:
return new IceSheet(player, id, pos, rot, buildStatus);
default:
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();
}
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(){
sol::state_view SOL_LUA_VIEW = generateView();
int numSpawnPoints = getNumMapSpawnPoints();
+2
View File
@@ -78,6 +78,8 @@ namespace battleship{
bool isPointWithinTerrainObject(vb01::Vector3, int);
void loadPlayerGameObjects();
int getNumMapSpawnPoints(std::string = "");
void blockCells(Unit*);
void unblockCells(Unit*);
inline std::string getMapName(){return mapName;}
inline vb01::Node* getNodeParent(){return terrainNode;}
inline vb01::Vector3 getCellSize(){return CELL_SIZE;}
+2 -18
View File
@@ -378,6 +378,7 @@ namespace battleship{
}
Unit::~Unit() {
Map::getSingleton()->unblockCells(this);
removeBar(hpBackgroundNode);
removeBar(hpForegroundNode);
destroyWeapons();
@@ -826,24 +827,7 @@ namespace battleship{
//TODO select only the closest cells based on unit size
void Unit::placeAt(Vector3 p){
GameObject::placeAt(p);
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);
}
Map::getSingleton()->blockCells(this);
}
vector<Player*> Unit::getSelectingPlayers(){