diff --git a/Assets/Scripts/Gui/engineerCommands.lua b/Assets/Scripts/Gui/engineerCommands.lua new file mode 100644 index 0000000..a6b0297 --- /dev/null +++ b/Assets/Scripts/Gui/engineerCommands.lua @@ -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 + } +} diff --git a/Assets/Scripts/Gui/main.lua b/Assets/Scripts/Gui/main.lua index 29964e7..3436c20 100644 --- a/Assets/Scripts/Gui/main.lua +++ b/Assets/Scripts/Gui/main.lua @@ -22,7 +22,8 @@ ButtonType = { RESUME = 18, CONSOLE = 19, MAIN_MENU = 20, - CONSOLE_COMMAND_OK = 21 + CONSOLE_COMMAND_OK = 21, + BUILD = 22 } ListboxType = { diff --git a/Assets/Scripts/Gui/vehicleCommands.lua b/Assets/Scripts/Gui/vehicleCommands.lua new file mode 100644 index 0000000..e69de29 diff --git a/Assets/Scripts/unitData.lua b/Assets/Scripts/unitData.lua index 769fd71..eff811b 100644 --- a/Assets/Scripts/unitData.lua +++ b/Assets/Scripts/unitData.lua @@ -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}, diff --git a/CMakeLists.txt b/CMakeLists.txt index 562ea13..0ae7005 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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}) diff --git a/activeGameState.cpp b/activeGameState.cpp index f141e9c..6a8dd7e 100755 --- a/activeGameState.cpp +++ b/activeGameState.cpp @@ -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 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 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); diff --git a/activeGameState.h b/activeGameState.h index e321222..2db8e28 100755 --- a/activeGameState.h +++ b/activeGameState.h @@ -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 getButtons(){return buttons;} inline Player* getPlayer(){return mainPlayer;} inline std::vector& 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 unitLightNodes; std::vector unitGroups[9]; std::vector targets; + std::vector buttons; bool isSelectionBox = false, shiftPressed = false, controlPressed = false, selectingPatrolPoints = false, selectingGuidedMissileTarget = false; int playerId, zooms = 0; const int NUM_MAX_ZOOMS = 10; diff --git a/buildButton.cpp b/buildButton.cpp new file mode 100644 index 0000000..b5f93cc --- /dev/null +++ b/buildButton.cpp @@ -0,0 +1,27 @@ +#include "buildButton.h" +#include "gameManager.h" +#include "unit.h" +#include "unitFrameController.h" + +#include + +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); + } +} diff --git a/buildButton.h b/buildButton.h new file mode 100644 index 0000000..ae4802b --- /dev/null +++ b/buildButton.h @@ -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 diff --git a/concreteGuiManager.cpp b/concreteGuiManager.cpp index c82e13f..bec5f96 100644 --- a/concreteGuiManager.cpp +++ b/concreteGuiManager.cpp @@ -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 buttonExceptions, + vector listboxExceptions, + vector checkboxExceptions, + vector sliderExceptions, + vector textboxExceptions + ){ + removeAllGuiElements(buttonExceptions, listboxExceptions, checkboxExceptions, sliderExceptions, textboxExceptions); guiElements.clear(); string basePath = GameManager::getSingleton()->getPath() + "Scripts/Gui/"; diff --git a/concreteGuiManager.h b/concreteGuiManager.h index 23886a6..606413f 100644 --- a/concreteGuiManager.h +++ b/concreteGuiManager.h @@ -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 = std::vector{}, + std::vector = std::vector{}, + std::vector = std::vector{}, + std::vector = std::vector{}, + std::vector = std::vector{} + ); private: ConcreteGuiManager(){} vb01Gui::Button* parseButton(int); diff --git a/engineer.cpp b/engineer.cpp index f09a96c..433af48 100644 --- a/engineer.cpp +++ b/engineer.cpp @@ -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(); + } } } diff --git a/inGameAppState.cpp b/inGameAppState.cpp index ab48332..188bf82 100755 --- a/inGameAppState.cpp +++ b/inGameAppState.cpp @@ -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()) diff --git a/structure.cpp b/structure.cpp index 45e632d..9e9724d 100644 --- a/structure.cpp +++ b/structure.cpp @@ -1,5 +1,7 @@ #include "structure.h" +#include + 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); + } } } diff --git a/structure.h b/structure.h index a31deb0..412d861 100644 --- a/structure.h +++ b/structure.h @@ -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; }; } diff --git a/unit.cpp b/unit.cpp index 03140a3..a8cfaf2 100755 --- a/unit.cpp +++ b/unit.cpp @@ -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]; diff --git a/unit.h b/unit.h index 05ed3ee..cc6f9ac 100755 --- a/unit.h +++ b/unit.h @@ -37,6 +37,9 @@ namespace battleship{ TYPE type; vb01::LineRenderer::Line line; std::vector targets; + + Order(){} + Order(TYPE t, vb01::LineRenderer::Line l, std::vector 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 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); }; } diff --git a/unitButton.cpp b/unitButton.cpp new file mode 100644 index 0000000..3a0d8ba --- /dev/null +++ b/unitButton.cpp @@ -0,0 +1,20 @@ +#include "unitButton.h" +#include "gameManager.h" +#include "activeGameState.h" + +#include + +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); + } +} diff --git a/unitButton.h b/unitButton.h new file mode 100644 index 0000000..696ae1e --- /dev/null +++ b/unitButton.h @@ -0,0 +1,17 @@ +#ifndef UNIT_BUTTON_H +#define UNIT_BUTTON_H + +#include + +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 units; + }; +} + +#endif diff --git a/unitFrameController.cpp b/unitFrameController.cpp index 60580dd..060c3c8 100644 --- a/unitFrameController.cpp +++ b/unitFrameController.cpp @@ -1,6 +1,7 @@ #include #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 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 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){ diff --git a/unitFrameController.h b/unitFrameController.h index cfe1ac7..1c889b9 100644 --- a/unitFrameController.h +++ b/unitFrameController.h @@ -4,6 +4,9 @@ #include #include +#include +#include + 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 unitFrames; - bool placingStructures = false, rotatingStructure = false; + vb01::Vector3 paintSelectRowStart, rowDir; + bool placingStructures = false, paintSelecting = false, rotatingStructure = false; }; }