Merge pull request #25 from devZoGok/imp-24-construction-gui

Imp 24 construction gui
This commit is contained in:
devZoGok
2023-09-27 16:21:49 +00:00
committed by GitHub
21 changed files with 356 additions and 147 deletions
+14
View File
@@ -0,0 +1,14 @@
numGui = 1
res = graphics.resolution
gui = {
{
pos = {x = res.x - 200, y = res.y - 200},
size = {x = 100, y = 100},
name = 'Structure',
guiType = GuiType.BUTTON,
buttonType = ButtonType.BUILD,
trigger = 66,
structureId = 3
}
}
+2 -1
View File
@@ -22,7 +22,8 @@ ButtonType = {
RESUME = 18,
CONSOLE = 19,
MAIN_MENU = 20,
CONSOLE_COMMAND_OK = 21
CONSOLE_COMMAND_OK = 21,
BUILD = 22
}
ListboxType = {
+8 -8
View File
@@ -54,14 +54,14 @@ unitCornerPoints = {
{x = .5, y = 2, z = 3.4}
},
{
{x = .5, y = -.25, z = -4.8},
{x = -.5, y = -.25, z = -4.8},
{x = -.5, y = -.25, z = 4.7},
{x = .5, y = -.25, z = 4.7},
{x = .5, y = .8, z = -4.8},
{x = -.5, y = .8, z = -4.8},
{x = -.5, y = .8, z = 4.7},
{x = .5, y = .8, z = 4.7}
{x = 1, y = -.25, z = -1},
{x = -1, y = -.25, z = -1},
{x = -1, y = -.25, z = 1},
{x = 1, y = -.25, z = 1},
{x = 1, y = .8, z = -1},
{x = -1, y = .8, z = -1},
{x = -1, y = .8, z = 1},
{x = 1, y = .8, z = 1}
},
{
{x = .7, y = -.3, z = -4},
+2 -1
View File
@@ -8,10 +8,11 @@ set(CMAKE_BUILD_TYPE Debug)
set(BUILD_TESTS ON)
cmake_policy(SET CMP0015 NEW)
set(UNIT_BUTTONS unitButton.cpp buildButton.cpp)
set(OPTIONS_BUTTONS optionsButton.cpp tabButton.cpp okButton.cpp defaultsButton.cpp)
set(IN_GAME_APP_STATE_BUTTONS mainMenuButton.cpp)
set(MAP_EDITOR_BUTTONS mapEditorButton.cpp newMapButton.cpp loadMapButton.cpp exportButton.cpp)
set(BUTTONS singlePlayerButton.cpp exitButton.cpp backButton.cpp consoleCommand.cpp playButton.cpp ${OPTIONS_BUTTONS} ${IN_GAME_APP_STATE_BUTTONS} ${MAP_EDITOR_BUTTONS})
set(BUTTONS singlePlayerButton.cpp exitButton.cpp backButton.cpp consoleCommand.cpp playButton.cpp ${OPTIONS_BUTTONS} ${IN_GAME_APP_STATE_BUTTONS} ${MAP_EDITOR_BUTTONS} ${UNIT_BUTTONS})
set(LISTBOXES skyboxTextureListbox.cpp landTextureListbox.cpp unitListbox.cpp)
set(GUI tooltip.cpp concreteGuiManager.cpp ${BUTTONS} ${LISTBOXES})
+45 -36
View File
@@ -22,6 +22,7 @@
#include "tooltip.h"
#include "unitFrameController.h"
#include "cameraController.h"
#include "concreteGuiManager.h"
using namespace vb01;
using namespace vb01Gui;
@@ -115,6 +116,9 @@ namespace battleship{
UnitFrameController *ufCtr = UnitFrameController::getSingleton();
ufCtr->removeUnitFrames();
ufCtr->setPlacingFrames(false);
ConcreteGuiManager::getSingleton()->removeAllGuiElements();
buttons.clear();
}
//TODO fix fog of war for hostile units
@@ -141,6 +145,11 @@ namespace battleship{
mainPlayer->selectUnit(u);
u->toggleSelection(true);
if(engineersSelected()){
ConcreteGuiManager *guiManager = ConcreteGuiManager::getSingleton();
guiManager->readLuaScreenScript("engineerCommands.lua");
}
}
}
@@ -216,22 +225,21 @@ namespace battleship{
break;
}
Order o;
o.type = type;
o.targets = targets;
targets.push_back(Order::Target());
if(o.type == Order::TYPE::PATROL)
if(type == Order::TYPE::PATROL)
for(int i = targets.size() - 2; i >= 0; i--)
targets[i + 1] = targets[i];
LineRenderer *lineRenderer = LineRenderer::getSingleton();
Order order;
for (int i = 0; i < mainPlayer->getNumSelectedUnits(); ++i) {
Unit *u = mainPlayer->getSelectedUnit(i);
lineRenderer->addLine(u->getPos(), o.targets[i].pos, color);
lineRenderer->addLine(u->getPos(), targets[i].pos, color);
vector<LineRenderer::Line> lines = lineRenderer->getLines();
o.line = lines[lines.size() - 1];
LineRenderer::Line line = lines[lines.size() - 1];
order = Order(type, line, targets);
if (type != Order::TYPE::LAUNCH) {
if(type == Order::TYPE::PATROL){
@@ -240,9 +248,9 @@ namespace battleship{
}
if (addOrder)
u->addOrder(o);
u->addOrder(order);
else
u->setOrder(o);
u->setOrder(order);
}
}
@@ -270,7 +278,8 @@ namespace battleship{
UnitFrameController *ufCtr = UnitFrameController::getSingleton();
if(ufCtr->isPlacingFrames()){
unit = new Structure(mainPlayer, ufCtr->getUnitFrame(0).id, results[0].pos, ufCtr->getUnitFrame(0).model->getOrientation());
Model *model = ufCtr->getUnitFrame(0).model;
unit = new Structure(mainPlayer, ufCtr->getUnitFrame(0).id, model->getPosition(), model->getOrientation());
mainPlayer->addUnit(unit);
}
@@ -304,6 +313,14 @@ namespace battleship{
targets.push_back(Order::Target((it != unitData.end() ? unitData[node] : unit), results[0].pos));
}
}
bool ActiveGameState::engineersSelected(){
for(Unit *u : mainPlayer->getSelectedUnits())
if(u->getUnitClass() == UnitClass::ENGINEER)
return true;
return false;
}
void ActiveGameState::onAction(int bind, bool isPressed) {
GameManager *gm = GameManager::getSingleton();
@@ -328,6 +345,7 @@ namespace battleship{
else if(ufCtr->isPlacingFrames()){
type = Order::TYPE::BUILD;
ufCtr->setPlacingFrames(false);
ufCtr->setRotatingFrames(false);
ufCtr->removeUnitFrames();
}
@@ -371,8 +389,24 @@ namespace battleship{
if(isPressed) depth -= 0.05;
break;
case Bind::LEFT_SHIFT:
shiftPressed = isPressed;
if(isPressed) depth += 0.05;
{
shiftPressed = isPressed;
UnitFrameController *ufCtr = UnitFrameController::getSingleton();
ufCtr->setPaintSelecting(shiftPressed);
if(isPressed){
depth += 0.05;
Vector3 startPos = Root::getSingleton()->getCamera()->getPosition();
vector<Ray::CollisionResult> results;
Ray::retrieveCollisions(startPos, (screenToSpace(getCursorPos()) - startPos).norm(), Map::getSingleton()->getNodeParent()->getChild(0), results);
Ray::sortResults(results);
if(!results.empty())
ufCtr->setPaintSelectRowStart(results[0].pos);
}
}
break;
case Bind::SELECT_PATROL_POINTS:
selectingPatrolPoints = isPressed;
@@ -415,31 +449,6 @@ namespace battleship{
}
break;
case Bind::SELECT_STRUCTURE:
{
if(isPressed){
bool engineersSelected = false;
for(Unit *u : mainPlayer->getSelectedUnits())
if(u->getUnitClass() == UnitClass::ENGINEER){
engineersSelected = true;
break;
}
if(!engineersSelected)
break;
//TODO fix the magic value
int id = 3;
sol::state_view SOL_LUA_STATE = generateView();
string modelPath = (string)SOL_LUA_STATE["basePath"][id + 1] + (string)SOL_LUA_STATE["meshPath"][id + 1];
ufCtr->addUnitFrame(UnitFrameController::UnitFrame(modelPath, id, (int)UnitType::LAND));
ufCtr->setPlacingFrames(true);
}
break;
}
case Bind::DESELECT_STRUCTURE:
ufCtr->removeUnitFrames();
ufCtr->setPlacingFrames(false);
+8
View File
@@ -10,6 +10,10 @@ namespace vb01{
class Node;
}
namespace vb01Gui{
class Button;
}
namespace battleship{
class ActiveGameState : public gameBase::AbstractAppState {
public:
@@ -20,6 +24,8 @@ namespace battleship{
void update();
void onAction(int, bool);
void onAnalog(int, float);
inline void addButton(vb01Gui::Button *b){buttons.push_back(b);}
inline std::vector<vb01Gui::Button*> getButtons(){return buttons;}
inline Player* getPlayer(){return mainPlayer;}
inline std::vector<Unit*>& getUnitGroup(int i){return unitGroups[i];}
private:
@@ -32,6 +38,7 @@ namespace battleship{
void addTarget();
void issueOrder(Order::TYPE, bool);
bool isInLineOfSight(vb01::Vector3, float, Unit*);
bool engineersSelected();
GuiAppState *guiState;
Player *mainPlayer;
@@ -42,6 +49,7 @@ namespace battleship{
std::vector<vb01::Node*> unitLightNodes;
std::vector<Unit*> unitGroups[9];
std::vector<Order::Target> targets;
std::vector<vb01Gui::Button*> buttons;
bool isSelectionBox = false, shiftPressed = false, controlPressed = false, selectingPatrolPoints = false, selectingGuidedMissileTarget = false;
int playerId, zooms = 0;
const int NUM_MAX_ZOOMS = 10;
+27
View File
@@ -0,0 +1,27 @@
#include "buildButton.h"
#include "gameManager.h"
#include "unit.h"
#include "unitFrameController.h"
#include <solUtil.h>
namespace battleship{
using namespace sol;
using namespace std;
using namespace vb01;
using namespace vb01Gui;
using namespace gameBase;
BuildButton::BuildButton(Vector2 pos, Vector2 size, int structureId, string name, int trigger, string imagePath) : UnitButton(pos, size, name, GameManager::getSingleton()->getPath() + "Fonts/batang.ttf", trigger, imagePath){
this->structureId = structureId;
}
void BuildButton::onClick(){
sol::state_view SOL_LUA_STATE = generateView();
string modelPath = (string)SOL_LUA_STATE["basePath"][structureId + 1] + (string)SOL_LUA_STATE["meshPath"][structureId + 1];
UnitFrameController *ufCtr = UnitFrameController::getSingleton();
ufCtr->addUnitFrame(UnitFrameController::UnitFrame(modelPath, structureId, (int)UnitType::LAND));
ufCtr->setPlacingFrames(true);
}
}
+16
View File
@@ -0,0 +1,16 @@
#ifndef BUILD_BUTTON_H
#define BUILD_BUTTON_H
#include "unitButton.h"
namespace battleship{
class BuildButton : public UnitButton{
public:
BuildButton(vb01::Vector2, vb01::Vector2, int, std::string, int, std::string);
void onClick();
private:
int structureId;
};
}
#endif
+13 -3
View File
@@ -19,6 +19,7 @@
#include "playButton.h"
#include "inGameAppState.h"
#include "mainMenuButton.h"
#include "buildButton.h"
namespace battleship{
using namespace std;
@@ -154,6 +155,9 @@ namespace battleship{
button = new InGameAppState::ConsoleButton::ConsoleCommandEntryButton(textbox, listbox, pos, size, name);
break;
}
case BUILD:
button = new BuildButton(pos, size, (int)guiTable["structureId"], name, (int)guiTable["trigger"], "");
break;
}
int typeArr[2]{(int)GuiElementType::BUTTON, (int)type};
@@ -334,9 +338,15 @@ namespace battleship{
return textbox;
}
void ConcreteGuiManager::readLuaScreenScript(string script){
removeAllGuiElements();
void ConcreteGuiManager::readLuaScreenScript(
string script,
vector<Button*> buttonExceptions,
vector<Listbox*> listboxExceptions,
vector<Checkbox*> checkboxExceptions,
vector<Slider*> sliderExceptions,
vector<Textbox*> textboxExceptions
){
removeAllGuiElements(buttonExceptions, listboxExceptions, checkboxExceptions, sliderExceptions, textboxExceptions);
guiElements.clear();
string basePath = GameManager::getSingleton()->getPath() + "Scripts/Gui/";
+10 -2
View File
@@ -31,7 +31,8 @@ namespace battleship{
RESUME,
CONSOLE_SCREEN,
MAIN_MENU,
CONSOLE_COMMAND_OK
CONSOLE_COMMAND_OK,
BUILD
};
enum ListboxType {
CONTROLS,
@@ -48,7 +49,14 @@ namespace battleship{
class ConcreteGuiManager : public vb01Gui::AbstractGuiManager{
public:
static ConcreteGuiManager* getSingleton();
void readLuaScreenScript(std::string);
void readLuaScreenScript(
std::string,
std::vector<vb01Gui::Button*> = std::vector<vb01Gui::Button*>{},
std::vector<vb01Gui::Listbox*> = std::vector<vb01Gui::Listbox*>{},
std::vector<vb01Gui::Checkbox*> = std::vector<vb01Gui::Checkbox*>{},
std::vector<vb01Gui::Slider*> = std::vector<vb01Gui::Slider*>{},
std::vector<vb01Gui::Textbox*> = std::vector<vb01Gui::Textbox*>{}
);
private:
ConcreteGuiManager(){}
vb01Gui::Button* parseButton(int);
+6 -5
View File
@@ -10,11 +10,6 @@ namespace battleship{
}
void Engineer::build(Order order){
navigate(order, 0.5 * Map::getSingleton()->getCellSize().x);
if(type == UnitType::LAND)
alignToSurface();
if(pathPoints.empty()){
if(!order.targets[0].unit){
player->addUnit(order.targets[0].unit);
@@ -30,5 +25,11 @@ namespace battleship{
removeOrder(0);
}
}
else{
navigate(order, 0.5 * Map::getSingleton()->getCellSize().x);
if(type == UnitType::LAND)
alignToSurface();
}
}
}
+2 -2
View File
@@ -112,7 +112,7 @@ namespace battleship{
isMainMenuActive = true;
gm->getStateManager()->dettachAppState(activeState);
guiManager->readLuaScreenScript("gamePaused.lua");
guiManager->readLuaScreenScript("gamePaused.lua", activeState->getButtons());
}
else {
isMainMenuActive = false;
@@ -120,7 +120,7 @@ namespace battleship{
AssetManager::getSingleton()->load(gm->getPath() + (string)generateView()["modelPrefix"], true);
guiManager->readLuaScreenScript("inGame.lua");
guiManager->readLuaScreenScript("inGame.lua", activeState->getButtons());
for(Player *p : Map::getSingleton()->getPlayers())
for(Unit *u : p->getUnits())
+15
View File
@@ -1,5 +1,7 @@
#include "structure.h"
#include <node.h>
using namespace gameBase;
using namespace vb01;
using namespace std;
@@ -7,5 +9,18 @@ using namespace std;
namespace battleship{
Structure::Structure(Player *player, int id, Vector3 pos, Quaternion rot, int buildStatus) : Unit(player, id, pos, rot){
this->buildStatus = buildStatus;
buildStatusBackground = createBar(Unit::lenHpBar, Vector4(0, 0, 0, 1));
buildStatusForeground = createBar(Unit::lenHpBar, Vector4(0, 0, 1, 1));
}
void Structure::update(){
Unit::update();
if(selected && buildStatus < 100)
Unit::displayUnitStats(buildStatusForeground, buildStatusBackground, buildStatus, 100, Vector2(0, -10));
else{
buildStatusBackground->setVisible(false);
buildStatusForeground->setVisible(false);
}
}
}
+6
View File
@@ -3,14 +3,20 @@
#include "unit.h"
namespace vb01{
class Node;
}
namespace battleship{
class Structure : public Unit{
public:
Structure(Player*, int, vb01::Vector3, vb01::Quaternion, int = 0);
inline int getBuildStatus(){return buildStatus;}
inline void incrementBuildStatus(){buildStatus++;}
virtual void update();
private:
int buildStatus = 0;
vb01::Node *buildStatusBackground, *buildStatusForeground;
};
}
+33 -30
View File
@@ -111,28 +111,26 @@ namespace battleship{
orientUnit(rot);
}
void Unit::initUnitStats(){
Node* Unit::createBar(float initLen, Vector4 color){
Root *root = Root::getSingleton();
Material *mat = new Material(root->getLibPath() + "gui");
mat->addBoolUniform("texturingEnabled", false);
mat->addVec4Uniform("diffuseColor", color);
hpBackground = new Quad(Vector3(lenHpBar, 10, 0), false);
string libPath = root->getLibPath();
Material *hpBackgroundMat = new Material(libPath + "gui");
hpBackgroundMat->addBoolUniform("texturingEnabled", false);
hpBackgroundMat->addVec4Uniform("diffuseColor", Vector4(0, 0, 0, 1));
hpBackground->setMaterial(hpBackgroundMat);
hpBackgroundNode = new Node();
hpBackgroundNode->attachMesh(hpBackground);
Node *guiNode = root->getGuiNode();
guiNode->attachChild(hpBackgroundNode);
Quad *quad = new Quad(Vector3(initLen, 10, 0), false);
quad->setMaterial(mat);
hpForeground = new Quad(Vector3(lenHpBar, 10, 0), false);
Material *hpForegroundMat = new Material(libPath + "gui");
hpForegroundMat->addBoolUniform("texturingEnabled", false);
hpForegroundMat->addVec4Uniform("diffuseColor", Vector4(0, 1, 0, 1));
hpForeground->setMaterial(hpForegroundMat);
hpForegroundNode = new Node();
hpForegroundNode->attachMesh(hpForeground);
guiNode->attachChild(hpForegroundNode);
Node *node = new Node();
node->attachMesh(quad);
node->setVisible(false);
root->getGuiNode()->attachChild(node);
return node;
}
void Unit::initUnitStats(){
hpBackgroundNode = createBar(lenHpBar, Vector4(0, 0, 0, 1));
hpForegroundNode = createBar(lenHpBar, Vector4(0, 1, 0, 1));
}
void Unit::update() {
@@ -149,11 +147,7 @@ namespace battleship{
executeOrders();
screenPos = spaceToScreen(pos);
hpBackgroundNode->setVisible(selected);
hpForegroundNode->setVisible(selected);
if (selected)
displayUnitStats();
displayUnitStats(hpForegroundNode, hpBackgroundNode, health, maxHealth);
if (health <= 0)
blowUp();
@@ -163,14 +157,23 @@ namespace battleship{
working = false;
}
void Unit::displayUnitStats() {
float shiftedX = screenPos.x - 0.5 * lenHpBar;
hpForegroundNode->setPosition(Vector3(shiftedX, screenPos.y, 0));
hpForeground->setSize(Vector3(health / maxHealth * lenHpBar, 10, 0));
hpBackgroundNode->setPosition(Vector3(shiftedX, screenPos.y, .1));
void Unit::displayUnitStats(Node *foreground, Node *background, int currVal, int maxVal, Vector2 offset) {
foreground->setVisible(selected);
background->setVisible(selected);
if(selected){
Vector3 offset3d = Vector3(offset.x, offset.y, 0);
float shiftedX = screenPos.x - 0.5 * lenHpBar;
background->setPosition(Vector3(shiftedX, screenPos.y, .1) + offset3d);
Quad *fgQuad = (Quad*)foreground->getMesh(0);
fgQuad->setSize(Vector3((float)currVal / maxVal * lenHpBar, 10, 0));
fgQuad->updateVerts(fgQuad->getMeshBase());
foreground->setPosition(Vector3(shiftedX, screenPos.y, 0) + offset3d);
}
}
//TODO factor out non mutual order methods
void Unit::executeOrders() {
if (orders.size() > 0) {
Order order = orders[0];
+6 -4
View File
@@ -37,6 +37,9 @@ namespace battleship{
TYPE type;
vb01::LineRenderer::Line line;
std::vector<Target> targets;
Order(){}
Order(TYPE t, vb01::LineRenderer::Line l, std::vector<Target> targ) : type(t), line(l), targets(targ){}
};
enum class MoveDir {LEFT, UP, FORW};
@@ -85,15 +88,12 @@ namespace battleship{
inline vb01::Vector3 getUpVec() {return upVec;}
private:
void updateScreenCoordinates();
void displayUnitStats();
inline bool canDisplayOrderLine(){return vb01::getTime() - orderLineDispTime < orderVecDispLength;}
const int orderVecDispLength = 2000;
sf::SoundBuffer *selectionSfxBuffer;
sf::Sound *selectionSfx = nullptr;
vb01::Quad *hpBackground = nullptr, *hpForeground = nullptr;
vb01::Node *hpBackgroundNode = nullptr, *hpForegroundNode = nullptr;
int lenHpBar = 200;
protected:
Player *player;
UnitClass unitClass;
@@ -102,13 +102,14 @@ namespace battleship{
std::vector<Order> orders;
vb01::Vector3 pos = vb01::Vector3(0, 0, 0), upVec = vb01::Vector3(0, 1, 0), dirVec = vb01::Vector3(0, 0, 1), leftVec = vb01::Vector3(1, 0, 0), corners[8];
vb01::Quaternion rot = vb01::Quaternion::QUAT_W;
int health, maxHealth, cost, id, playerId;
int health, maxHealth, cost, id, playerId, lenHpBar = 200;
s64 orderLineDispTime = 0;
vb01::Model *model;
bool selected = false, selectable, debugging = false, working = true;
float lineOfSight, range, width, height, length;
void removeOrder(int);
void displayUnitStats(vb01::Node*, vb01::Node*, int, int, vb01::Vector2 = vb01::Vector2::VEC_ZERO);
virtual void initProperties();
virtual void destroyModel();
virtual void initModel();
@@ -121,6 +122,7 @@ namespace battleship{
virtual void move(Order){}
virtual void patrol(Order){}
virtual void launch(Order){}
vb01::Node* createBar(float, vb01::Vector4);
};
}
+20
View File
@@ -0,0 +1,20 @@
#include "unitButton.h"
#include "gameManager.h"
#include "activeGameState.h"
#include <stateManager.h>
namespace battleship{
using namespace std;
using namespace vb01;
using namespace vb01Gui;
using namespace gameBase;
UnitButton::UnitButton(Vector2 pos, Vector2 size, string name, string fontPath, int trigger, string imagePath) : Button(pos, size, name, fontPath, trigger, true, imagePath){
StateManager *stateManager = GameManager::getSingleton()->getStateManager();
ActiveGameState *activeState = (ActiveGameState*)stateManager->getAppStateByType((int)AppStateType::ACTIVE_STATE);
if(activeState)
activeState->addButton(this);
}
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef UNIT_BUTTON_H
#define UNIT_BUTTON_H
#include <button.h>
namespace battleship{
class Unit;
class UnitButton : public vb01Gui::Button{
public:
UnitButton(vb01::Vector2, vb01::Vector2, std::string, std::string, int, std::string);
protected:
std::vector<Unit*> units;
};
}
#endif
+93 -53
View File
@@ -1,6 +1,7 @@
#include <solUtil.h>
#include "unitFrameController.h"
#include "unit.h"
#include "util.h"
#include "map.h"
@@ -20,7 +21,7 @@ namespace battleship{
static UnitFrameController *unitFrameController = nullptr;
UnitFrameController::UnitFrame::UnitFrame(string modelPath, int i, int t) : id(i), type(t) {
UnitFrameController::UnitFrame::UnitFrame(string modelPath, int i, int t, Vector3 pos, Quaternion rot) : id(i), type(t) {
Root *root = Root::getSingleton();
Material *mat = new Material(root->getLibPath() + "texture");
mat->addBoolUniform("texturingEnabled", false);
@@ -30,6 +31,8 @@ namespace battleship{
model = new Model(modelPath);
model->setWireframe(true);
model->setMaterial(mat);
model->setPosition(pos);
model->setOrientation(rot);
root->getRootNode()->attachChild(model);
}
@@ -40,72 +43,109 @@ namespace battleship{
return unitFrameController;
}
void UnitFrameController::paintSelect(Vector3 rowEnd, float width, float length){
Vector3 rowDir = rowEnd - paintSelectRowStart;
float lenRow = rowDir.getLength();
float hypothenuse = sqrt(width * width + length * length);
int numStructsInRow = int(lenRow / hypothenuse);
while(unitFrames.size() > numStructsInRow)
removeUnitFrame(unitFrames.size() - 1);
if(unitFrames.size() < numStructsInRow){
int structureId = unitFrames[0].id;
sol::state_view SOL_LUA_STATE = generateView();
string modelPath = (string)SOL_LUA_STATE["basePath"][structureId + 1] + (string)SOL_LUA_STATE["meshPath"][structureId + 1];
Vector3 buildDir = rowDir;
if(unitFrames.size() > 1)
buildDir = unitFrames[1].model->getPosition() - unitFrames[0].model->getPosition();
Vector3 pos = paintSelectRowStart + buildDir.norm() * hypothenuse * unitFrames.size();
addUnitFrame(UnitFrame(modelPath, structureId, (int)UnitType::LAND, pos));
}
}
//TODO implement terrain evenness check
void UnitFrameController::update(){
void UnitFrameController::placeUnitFrame(int id, Vector3 newPos, float width, float length){
UnitFrame &s = unitFrames[id];
if(!rotatingStructure)
s.model->setPosition(newPos);
Map *map = Map::getSingleton();
MeshData meshData = map->getNodeParent()->getChild(0)->getMesh(0)->getMeshBase();
MeshData::Vertex *verts = meshData.vertices;
int numVerts = 3 * meshData.numTris;
sol::state_view SOL_LUA_STATE = generateView();
float maxUnevenness = SOL_LUA_STATE["maxUnevenness"];
float maxUnevenness = generateView()["maxUnevenness"], unevenness = 0;
Camera *cam = Root::getSingleton()->getCamera();
Vector3 startPos = cam->getPosition();
Vector3 endPos = screenToSpace(getCursorPos());
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);
for(UnitFrame &s : unitFrames){
vector<Ray::CollisionResult> results;
Ray::retrieveCollisions(startPos, (endPos - startPos).norm(), map->getNodeParent()->getChild(0), results);
Ray::sortResults(results);
if(diffX < 0.5 * width && diffZ < 0.5 * length && diffY > unevenness){
unevenness = diffY;
if(!results.empty()){
if(!rotatingStructure)
s.model->setPosition(results[0].pos);
sol::table unitTable = SOL_LUA_STATE["unitCornerPoints"][s.id + 1];
float width = (float)unitTable[1]["x"] - (float)unitTable[2]["x"];
float length = (float)unitTable[4]["z"] - (float)unitTable[1]["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);
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::update(){
Vector3 startPos = Root::getSingleton()->getCamera()->getPosition();
vector<Ray::CollisionResult> results;
Ray::retrieveCollisions(startPos, (screenToSpace(getCursorPos()) - startPos).norm(), Map::getSingleton()->getNodeParent()->getChild(0), results);
Ray::sortResults(results);
if(results.empty()) return;
Vector3 newPos, rowEnd;
sol::state_view SOL_LUA_STATE = generateView();
sol::table unitTable = SOL_LUA_STATE["unitCornerPoints"][unitFrames[0].id + 1];
float width = (float)unitTable[1]["x"] - (float)unitTable[2]["x"];
float length = (float)unitTable[4]["z"] - (float)unitTable[1]["z"];
if(paintSelecting)
paintSelect(results[0].pos, width, length);
else if(!(paintSelecting || rotatingStructure))
newPos = results[0].pos;
for(int i = 0; i < unitFrames.size(); i++){
if(paintSelecting){
float hypothenuse = sqrt(width * width + length * length);
Vector3 dir = (results[0].pos - paintSelectRowStart).norm();
newPos = paintSelectRowStart + dir * hypothenuse * i;
}
placeUnitFrame(i, newPos, width, length);
}
}
void UnitFrameController::removeUnitFrames(){
for(UnitFrame &u : unitFrames){
u.model->getParent()->dettachChild(u.model);
delete u.model;
}
void UnitFrameController::removeUnitFrame(int i){
unitFrames[i].model->getParent()->dettachChild(unitFrames[i].model);
delete unitFrames[i].model;
unitFrames.erase(unitFrames.begin() + i);
}
unitFrames.clear();
void UnitFrameController::removeUnitFrames(){
while(unitFrames.size() > 0)
removeUnitFrame(0);
}
void UnitFrameController::rotateUnitFrames(float angle){
+13 -2
View File
@@ -4,6 +4,9 @@
#include <vector>
#include <string>
#include <vector.h>
#include <quaternion.h>
namespace vb01{
class Model;
}
@@ -14,7 +17,7 @@ namespace battleship{
struct UnitFrame{
enum Status{PLACEABLE, NOT_PLACEABLE, PLACED};
UnitFrame(std::string, int, int);
UnitFrame(std::string, int, int, vb01::Vector3 = vb01::Vector3::VEC_ZERO, vb01::Quaternion = vb01::Quaternion::QUAT_W);
~UnitFrame(){}
void update();
@@ -25,19 +28,27 @@ namespace battleship{
static UnitFrameController* getSingleton();
void update();
void removeUnitFrame(int);
void removeUnitFrames();
void rotateUnitFrames(float);
inline int getNumUnitFrames(){return unitFrames.size();}
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 isPaintSelecting(){return paintSelecting;}
inline void setPaintSelecting(bool ps){paintSelecting = ps;}
inline bool isRotatingFrames(){return rotatingStructure;}
inline void setRotatingFrames(bool rs){rotatingStructure = rs;}
inline void setPaintSelectRowStart(vb01::Vector3 st){paintSelectRowStart = st;}
private:
UnitFrameController(){}
void paintSelect(vb01::Vector3, float, float);
void placeUnitFrame(int, vb01::Vector3, float, float);
std::vector<UnitFrame> unitFrames;
bool placingStructures = false, rotatingStructure = false;
vb01::Vector3 paintSelectRowStart, rowDir;
bool placingStructures = false, paintSelecting = false, rotatingStructure = false;
};
}