factored out unit frame handling

This commit is contained in:
devZoGok
2023-01-03 15:54:26 +02:00
parent 64218bc82a
commit eeefa41f41
7 changed files with 198 additions and 127 deletions
+2 -1
View File
@@ -10,7 +10,8 @@ cmake_policy(SET CMP0015 NEW)
set(STATES activeGameState.cpp inGameAppState.cpp guiAppState.cpp mapEditorAppState.cpp)
set(UTIL util.cpp binds.h)
set(GUI tooltip.cpp optionsButton.cpp exitButton.cpp consoleCommand.cpp)
set(CORE gameManager.cpp defConfigs.cpp cameraController.cpp)
set(CONTROLLERS unitFrameController.cpp cameraController.cpp)
set(CORE gameManager.cpp defConfigs.cpp ${CONTROLLERS})
set(PROJECTILES projectile.cpp)
set(FX explosion.cpp)
set(VEHICLES vehicle.cpp engineer.cpp)
+24 -109
View File
@@ -20,6 +20,7 @@
#include "structure.h"
#include "util.h"
#include "tooltip.h"
#include "unitFrameController.h"
#include "cameraController.h"
using namespace vb01;
@@ -30,22 +31,6 @@ namespace battleship{
using namespace configData;
using namespace gameBase;
ActiveGameState::StructureFrame::StructureFrame(string modelPath, int i, int t) : id(i), type(t) {
Root *root = Root::getSingleton();
Material *mat = new Material(root->getLibPath() + "texture");
mat->addBoolUniform("texturingEnabled", false);
mat->addBoolUniform("lightingEnabled", false);
mat->addVec4Uniform("diffuseColor", Vector4::VEC_ZERO);
model = new Model(modelPath);
model->setWireframe(true);
model->setMaterial(mat);
root->getRootNode()->attachChild(model);
}
ActiveGameState::StructureFrame::~StructureFrame(){
}
ActiveGameState::ActiveGameState(GuiAppState *guiState, int playerId) : AbstractAppState(
AppStateType::ACTIVE_STATE,
configData::calcSumBinds(AppStateType::ACTIVE_STATE, true),
@@ -119,14 +104,17 @@ namespace battleship{
if(!camCtr->isLookingAround())
camCtr->updateCameraPosition();
if(placingStructures)
updateStructureFrames();
UnitFrameController *ufCtr = UnitFrameController::getSingleton();
if(ufCtr->isPlacingFrames())
ufCtr->update();
}
void ActiveGameState::deselectUnits(){
mainPlayer->deselectUnits();
removeStructtureFrames();
placingStructures = false;
UnitFrameController *ufCtr = UnitFrameController::getSingleton();
ufCtr->removeUnitFrames();
ufCtr->setPlacingFrames(false);
}
//TODO fix fog of war for hostile units
@@ -209,69 +197,6 @@ namespace battleship{
dragboxNode->setPosition(Vector3(selectionBoxOrigin.x, selectionBoxOrigin.y, 0));
}
//TODO implement terrain evenness check
void ActiveGameState::updateStructureFrames(){
Map *map = Map::getSingleton();
MeshData meshData = map->getTerrainObject(0).node->getChild(0)->getMesh(0)->getMeshBase();
MeshData::Vertex *verts = meshData.vertices;
int numVerts = 3 * meshData.numTris;
LuaManager *lm = LuaManager::getSingleton();
float maxUnevenness = lm->getFloat("maxUnevenness");
string table = "unitCornerPoints";
for(StructureFrame s : structureFrames){
Camera *cam = Root::getSingleton()->getCamera();
Vector3 startPos = cam->getPosition();
Vector3 endPos = screenToSpace(getCursorPos());
vector<Ray::CollisionResult> results;
Ray::retrieveCollisions(startPos, (endPos - startPos).norm(), map->getTerrainObject(0).node, results);
Ray::sortResults(results);
if(!results.empty()){
if(!rotatingStructure)
s.model->setPosition(results[0].pos);
float width =
lm->getFloatFromTable(table, vector<Index>{Index(s.id + 1), Index(1), Index("x")}) -
lm->getFloatFromTable(table, vector<Index>{Index(s.id + 1), Index(2), Index("x")});
float length =
lm->getFloatFromTable(table, vector<Index>{Index(s.id + 1), Index(4), Index("z")}) -
lm->getFloatFromTable(table, vector<Index>{Index(s.id + 1), Index(1), Index("z")});
float unevenness = 0;
for(int i = 0; i < numVerts; i++){
float diffX = fabs(s.model->getPosition().x - verts[i].pos.x);
float diffY = fabs(s.model->getPosition().y - verts[i].pos.y);
float diffZ = fabs(s.model->getPosition().z - verts[i].pos.z);
if(diffX < 0.5 * width && diffZ < 0.5 * length && diffY > unevenness){
unevenness = diffY;
if(unevenness > maxUnevenness)
break;
}
}
Vector4 color;
if(unevenness > maxUnevenness){
color = Vector4(1, 0, 0, 1);
s.status = StructureFrame::NOT_PLACEABLE;
}
else{
color = Vector4(0, 1, 0, 1);
s.status = StructureFrame::PLACEABLE;
}
Material *mat = s.model->getMaterial();
mat->setVec4Uniform("diffuseColor", color);
}
}
}
void ActiveGameState::issueOrder(Order::TYPE type, bool addOrder) {
Vector3 color;
@@ -342,9 +267,10 @@ namespace battleship{
std::map<Node*, Unit*>::iterator it = unitData.find(node);
Unit *unit = nullptr;
UnitFrameController *ufCtr = UnitFrameController::getSingleton();
if(placingStructures){
unit = new Structure(mainPlayer, structureFrames[0].id, results[0].pos, structureFrames[0].model->getOrientation());
if(ufCtr->isPlacingFrames()){
unit = new Structure(mainPlayer, ufCtr->getUnitFrame(0).id, results[0].pos, ufCtr->getUnitFrame(0).model->getOrientation());
mainPlayer->addUnit(unit);
}
@@ -371,6 +297,7 @@ namespace battleship{
void ActiveGameState::onAction(int bind, bool isPressed) {
GameManager *gm = GameManager::getSingleton();
InGameAppState *inGameState = (InGameAppState*) gm->getStateManager()->getAppStateByType((int)AppStateType::IN_GAME_STATE);
UnitFrameController *ufCtr = UnitFrameController::getSingleton();
switch((Bind)bind){
case Bind::DRAG_BOX:
@@ -387,10 +314,10 @@ namespace battleship{
if(controlPressed || (targets[0].unit && targets[0].unit->getPlayer()->getSide() != mainPlayer->getSide()))
type = Order::TYPE::ATTACK;
else if(placingStructures){
else if(ufCtr->isPlacingFrames()){
type = Order::TYPE::BUILD;
placingStructures = false;
removeStructtureFrames();
ufCtr->setPlacingFrames(false);
ufCtr->removeUnitFrames();
}
issueOrder(type, shiftPressed);
@@ -400,7 +327,7 @@ namespace battleship{
break;
case Bind::DESELECT:
if(placingStructures) rotatingStructure = isPressed;
if(ufCtr->isPlacingFrames()) ufCtr->setRotatingFrames(isPressed);
if (!isPressed) deselectUnits();
break;
case Bind::TOGGLE_SUB:
@@ -420,7 +347,7 @@ namespace battleship{
}
break;
case Bind::LOOK_AROUND:
if(!placingStructures)
if(!ufCtr->isPlacingFrames())
CameraController::getSingleton()->setLookingAround(isPressed);
break;
case Bind::HALT:
@@ -495,31 +422,23 @@ namespace battleship{
int id = 3;
LuaManager *lm = LuaManager::getSingleton();
string modelPath = lm->getStringFromTable("basePath", vector<Index>{Index(id + 1)}) + lm->getStringFromTable("meshPath", vector<Index>{Index(id + 1)});
structureFrames.push_back(StructureFrame(modelPath, id, (int)UnitType::LAND));
ufCtr->addUnitFrame(UnitFrameController::UnitFrame(modelPath, id, (int)UnitType::LAND));
placingStructures = true;
ufCtr->setPlacingFrames(true);
}
break;
}
case Bind::DESELECT_STRUCTURE:
removeStructtureFrames();
placingStructures = false;
ufCtr->removeUnitFrames();
ufCtr->setPlacingFrames(false);
break;
}
}
void ActiveGameState::removeStructtureFrames(){
for(StructureFrame s : structureFrames){
Root::getSingleton()->getRootNode()->dettachChild(s.model);
delete s.model;
}
structureFrames.clear();
}
void ActiveGameState::onAnalog(int bind, float strength) {
CameraController *camCtr = CameraController::getSingleton();
UnitFrameController *ufCtr = UnitFrameController::getSingleton();
switch((Bind)bind){
case Bind::LOOK_UP:
@@ -535,12 +454,8 @@ namespace battleship{
case Bind::LOOK_RIGHT:
if(camCtr->isLookingAround())
CameraController::getSingleton()->orientCamera(Vector3(0, 1, 0), strength);
else if(placingStructures && rotatingStructure)
for(StructureFrame &s : structureFrames)
if(s.status != StructureFrame::PLACED){
Quaternion rot = s.model->getOrientation();
s.model->setOrientation(Quaternion(100 * strength, Vector3::VEC_J) * rot);
}
else if(ufCtr->isPlacingFrames() && ufCtr->isRotatingFrames())
ufCtr->rotateUnitFrames(100 * strength);
break;
}
+1 -16
View File
@@ -13,17 +13,6 @@ namespace vb01{
namespace battleship{
class ActiveGameState : public gameBase::AbstractAppState {
public:
struct StructureFrame{
enum Status{PLACEABLE, NOT_PLACEABLE, PLACED};
vb01::Model *model;
int id, type;
Status status;
StructureFrame(std::string, int, int);
~StructureFrame();
};
ActiveGameState(GuiAppState*, int);
~ActiveGameState();
void onAttached();
@@ -31,8 +20,6 @@ namespace battleship{
void update();
void onAction(int, bool);
void onAnalog(int, float);
inline bool isPlacingStructures(){return placingStructures;}
inline void setSelectingLaunchPoint(bool s){this->selectingGuidedMissileTarget=s;}
inline Player* getPlayer(){return mainPlayer;}
inline std::vector<Unit*>& getUnitGroup(int i){return unitGroups[i];}
private:
@@ -44,11 +31,9 @@ namespace battleship{
void updateStructureFrames();
void addTarget();
void issueOrder(Order::TYPE, bool);
void removeStructtureFrames();
bool isInLineOfSight(vb01::Vector3, float, Unit*);
GuiAppState *guiState;
std::vector<StructureFrame> structureFrames;
Player *mainPlayer;
vb01::Quad *dragbox = nullptr;
vb01::Node *dragboxNode = nullptr, *textNode = nullptr;
@@ -57,7 +42,7 @@ namespace battleship{
std::vector<vb01::Node*> unitLightNodes;
std::vector<Unit*> unitGroups[9];
std::vector<Order::Target> targets;
bool isSelectionBox = false, shiftPressed = false, controlPressed = false, selectingPatrolPoints = false, selectingGuidedMissileTarget = false, placingStructures = false, rotatingStructure = false;
bool isSelectionBox = false, shiftPressed = false, controlPressed = false, selectingPatrolPoints = false, selectingGuidedMissileTarget = false;
int playerId, zooms = 0;
const int NUM_MAX_ZOOMS = 10;
float depth = 1;
+2 -1
View File
@@ -11,6 +11,7 @@
#include "defConfigs.h"
#include "inGameAppState.h"
#include "consoleCommand.h"
#include "unitFrameController.h"
#include "vessel.h"
using namespace vb01;
@@ -252,7 +253,7 @@ namespace battleship{
void InGameAppState::onAction(int bind, bool isPressed) {
switch((Bind)bind){
case Bind::TOGGLE_MAIN_MENU:
if(isPressed && !activeState->isPlacingStructures())
if(isPressed && !UnitFrameController::getSingleton()->isPlacingFrames())
toggleMainMenu();
break;
}
+3
View File
@@ -4,6 +4,7 @@
#include "guiAppState.h"
#include "defConfigs.h"
#include "cameraController.h"
#include "player.h"
#include "map.h"
#include "mesh.h"
#include "util.h"
@@ -29,6 +30,8 @@ namespace battleship{
map = Map::getSingleton();
map->load(name, true);
map->addPlayer(new Player(0, 0, 0));
generatePlane(size);
prepareGui();
+122
View File
@@ -0,0 +1,122 @@
#include "unitFrameController.h"
#include "util.h"
#include "map.h"
#include <material.h>
#include <meshData.h>
#include <mesh.h>
#include <model.h>
#include <root.h>
#include <ray.h>
#include <luaManager.h>
#include <string>
namespace battleship{
using namespace std;
using namespace vb01;
using namespace gameBase;
static UnitFrameController *unitFrameController = nullptr;
UnitFrameController::UnitFrame::UnitFrame(string modelPath, int i, int t) : id(i), type(t) {
Root *root = Root::getSingleton();
Material *mat = new Material(root->getLibPath() + "texture");
mat->addBoolUniform("texturingEnabled", false);
mat->addBoolUniform("lightingEnabled", false);
mat->addVec4Uniform("diffuseColor", Vector4::VEC_ZERO);
model = new Model(modelPath);
model->setWireframe(true);
model->setMaterial(mat);
root->getRootNode()->attachChild(model);
}
UnitFrameController* UnitFrameController::getSingleton(){
if(!unitFrameController)
unitFrameController = new UnitFrameController();
return unitFrameController;
}
//TODO implement terrain evenness check
void UnitFrameController::update(){
Map *map = Map::getSingleton();
MeshData meshData = map->getTerrainObject(0).node->getChild(0)->getMesh(0)->getMeshBase();
MeshData::Vertex *verts = meshData.vertices;
int numVerts = 3 * meshData.numTris;
LuaManager *lm = LuaManager::getSingleton();
float maxUnevenness = lm->getFloat("maxUnevenness");
string table = "unitCornerPoints";
Camera *cam = Root::getSingleton()->getCamera();
Vector3 startPos = cam->getPosition();
Vector3 endPos = screenToSpace(getCursorPos());
for(UnitFrame &s : unitFrames){
vector<Ray::CollisionResult> results;
Ray::retrieveCollisions(startPos, (endPos - startPos).norm(), map->getTerrainObject(0).node, results);
Ray::sortResults(results);
if(!results.empty()){
if(!rotatingStructure)
s.model->setPosition(results[0].pos);
float width =
lm->getFloatFromTable(table, vector<Index>{Index(s.id + 1), Index(1), Index("x")}) -
lm->getFloatFromTable(table, vector<Index>{Index(s.id + 1), Index(2), Index("x")});
float length =
lm->getFloatFromTable(table, vector<Index>{Index(s.id + 1), Index(4), Index("z")}) -
lm->getFloatFromTable(table, vector<Index>{Index(s.id + 1), Index(1), Index("z")});
float unevenness = 0;
for(int i = 0; i < numVerts; i++){
float diffX = fabs(s.model->getPosition().x - verts[i].pos.x);
float diffY = fabs(s.model->getPosition().y - verts[i].pos.y);
float diffZ = fabs(s.model->getPosition().z - verts[i].pos.z);
if(diffX < 0.5 * width && diffZ < 0.5 * length && diffY > unevenness){
unevenness = diffY;
if(unevenness > maxUnevenness)
break;
}
}
Vector4 color;
if(unevenness > maxUnevenness){
color = Vector4(1, 0, 0, 1);
s.status = UnitFrame::NOT_PLACEABLE;
}
else{
color = Vector4(0, 1, 0, 1);
s.status = UnitFrame::PLACEABLE;
}
Material *mat = s.model->getMaterial();
mat->setVec4Uniform("diffuseColor", color);
}
}
}
void UnitFrameController::removeUnitFrames(){
for(UnitFrame &u : unitFrames){
u.model->getParent()->dettachChild(u.model);
delete u.model;
}
unitFrames.clear();
}
void UnitFrameController::rotateUnitFrames(float angle){
for(UnitFrame &s : unitFrames)
if(s.status != UnitFrame::PLACED){
Quaternion rot = s.model->getOrientation();
s.model->setOrientation(Quaternion(angle, Vector3::VEC_J) * rot);
}
}
}
+44
View File
@@ -0,0 +1,44 @@
#ifndef UNIT_FRAME_CONTROLLER_H
#define UNIT_FRAME_CONTROLLER_H
#include <vector>
#include <string>
namespace vb01{
class Model;
}
namespace battleship{
class UnitFrameController{
public:
struct UnitFrame{
enum Status{PLACEABLE, NOT_PLACEABLE, PLACED};
UnitFrame(std::string, int, int);
~UnitFrame(){}
void update();
vb01::Model *model;
int id, type;
Status status;
};
static UnitFrameController* getSingleton();
void update();
void removeUnitFrames();
void rotateUnitFrames(float);
inline void addUnitFrame(UnitFrame u){unitFrames.push_back(u);}
inline UnitFrame& getUnitFrame(int i){return unitFrames[i];}
inline bool isPlacingFrames(){return placingStructures;}
inline void setPlacingFrames(bool ps){placingStructures = ps;}
inline bool isRotatingFrames(){return rotatingStructure;}
inline void setRotatingFrames(bool rs){rotatingStructure = rs;}
private:
UnitFrameController(){}
std::vector<UnitFrame> unitFrames;
bool placingStructures = false, rotatingStructure = false;
};
}
#endif