diff --git a/Assets/Scripts/Core/player.lua b/Assets/Scripts/Core/player.lua
index bb3fd9d..b92186e 100644
--- a/Assets/Scripts/Core/player.lua
+++ b/Assets/Scripts/Core/player.lua
@@ -11,7 +11,6 @@ Player.taskForceData = {
Player.taskForces = {}
---TODO use enum-like values instead of literals for order types
--TODO simplify building construction
function Player:buildFort(arguments)
forts = self:getUnitsByClass(UnitClass.FORT, 1)
@@ -47,7 +46,7 @@ function Player:buildFort(arguments)
angle = self.baseDir:getAngleBetween(Vector3:new(0, 0, 1)) * (right and -1 or 1)
fort = GameObjectFactory.createUnit(self, UnitId.FORT, sp, Quaternion:new(angle, Vector3:new(0, 1, 0)), 0)
self:addUnit(fort)
- self:issueOrder(1, Vector3:new(0, 0, 0), {Target:new(fort, Vector3:new(0, 0, 0))}, false)
+ self:issueOrder(OrderType.BUILD, Vector3:new(0, 0, 0), {Target:new(fort, Vector3:new(0, 0, 0))}, false)
return BTNodeResult.RUNNING
end
@@ -85,7 +84,7 @@ function Player:buildStructure(engineer, buildingId, buildPos, buildAngle)
building = GameObjectFactory.createUnit(self, buildingId, buildPos, Quaternion:new(1, 0, 0, 0), 0)
self:addUnit(building)
- self:issueOrder(1, Vector3:new(0, 0, 0), {Target:new(building, Vector3:new(0, 0, 0))}, false)
+ self:issueOrder(OrderType.BUILD, Vector3:new(0, 0, 0), {Target:new(building, Vector3:new(0, 0, 0))}, false)
end
building = self:getUnitsByClass(unitClass, 1)[1]
@@ -156,7 +155,7 @@ function Player:startHarvesting()
self:deselectUnits()
self:selectUnits({harvesters[1]})
- self:issueOrder(7, Vector3:new(0, 0, 0), {Target:new(extractor, Vector3:new(0, 0, 0))}, false)
+ self:issueOrder(OrderType.SUPPLY, Vector3:new(0, 0, 0), {Target:new(extractor, Vector3:new(0, 0, 0))}, false)
return BTNodeResult.SUCCESS
end
@@ -259,7 +258,7 @@ function Player:clearNearEnemies(arguments)
if not taskForce.clearing and targUnit then
self:deselectUnits()
self:selectUnits(taskForce.units)
- self:issueOrder(2, Vector3:new(0, 0, 0), {Target:new(targUnit, Vector3:new(0, 0, 0))}, false)
+ self:issueOrder(OrderType.MOVE, Vector3:new(0, 0, 0), {Target:new(targUnit, Vector3:new(0, 0, 0))}, false)
self.taskForces[arguments.tfId].clearing = true
elseif taskForce.clearing and not targUnit then
@@ -281,7 +280,7 @@ function Player:attackSpawnPoint(arguments)
for i = 1, #taskForce.units do taskForce.units[i]:setState(0) end
enemySpawnPoint = Map.getSingleton():getSpawnPoint(taskForce.spawnPointId)
- self:issueOrder(2, Vector3:new(0, 0, 0), {Target:new(nil, enemySpawnPoint)}, false)
+ self:issueOrder(OrderType.MOVE, Vector3:new(0, 0, 0), {Target:new(nil, enemySpawnPoint)}, false)
self.taskForces[arguments.tfId].attacking = true
return BTNodeResult.RUNNING
diff --git a/Assets/Scripts/GameObjects/Units/unitData.lua b/Assets/Scripts/GameObjects/Units/unitData.lua
index 2b35f4e..e2c7d88 100644
--- a/Assets/Scripts/GameObjects/Units/unitData.lua
+++ b/Assets/Scripts/GameObjects/Units/unitData.lua
@@ -1,4 +1,15 @@
---TYPE = {ATTACK = 0, BUILD = 1, MOVE = 2, GARRISON = 3, EJECT = 4, PATROL = 5, LAUNCH = 6};
+OrderType = {
+ HALT = -1,
+ ATTACK = 0,
+ BUILD = 1,
+ MOVE = 2,
+ GARRISON = 3,
+ EJECT = 4,
+ PATROL = 5,
+ LAUNCH = 6,
+ SUPPLY = 7,
+ HACK = 8
+}
UnitId = {
WAR_MECH = 0,
TANK = 1,
@@ -254,15 +265,16 @@ units = {
{type = WeaponClass.HITSCAN, rateOfFire = 2000, fireSfx = PATH .. 'Sounds/Units/WarMechs/fire.ogg', damage = 20, maxRange = 8},
},
buildableUnits = {
- {id = UnitId.LAND_FACTORY, buildable = true},
- {id = UnitId.NAVAL_FACTORY, buildable = true},
- {id = UnitId.TRADE_CENTER, buildable = true},
- {id = UnitId.LAB, buildable = true},
- {id = UnitId.POINT_DEFENSE, buildable = true},
- {id = UnitId.FORT, buildable = true},
- {id = UnitId.EXTRACTOR, buildable = true},
- {id = UnitId.REFINERY, buildable = true},
+ {id = UnitId.LAND_FACTORY, buildable = true, trigger = 76},
+ {id = UnitId.NAVAL_FACTORY, buildable = true, trigger = 78},
+ {id = UnitId.TRADE_CENTER, buildable = true, trigger = 77},
+ {id = UnitId.LAB, buildable = true, trigger = 84},
+ {id = UnitId.POINT_DEFENSE, buildable = true, trigger = 80},
+ {id = UnitId.FORT, buildable = true, trigger = 70},
+ {id = UnitId.EXTRACTOR, buildable = true, trigger = 69},
+ {id = UnitId.REFINERY, buildable = true, trigger = 82},
},
+ abilityButtons = {{buttonType = ButtonType.ORDER, name = 'Hack', orderType = OrderType.HACK}},
unitClass = UnitClass.ENGINEER,
unitType = UnitType.HOVER,
armor = {ArmorType.MECHANIC},
@@ -280,7 +292,6 @@ units = {
albedoPath = 'engineer.jpg',
colorNodes = {'Cube.008'},
meshPath = 'engineer2.xml',
- guiScreen = 'engineerCommands.lua',
selectionSfx = PATH .. 'Sounds/Units/Engineers/selection.ogg',
deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg',
speed = .1,
@@ -342,6 +353,7 @@ units = {
},
{
weapons = {},
+ abilityButtons = {{buttonType = ButtonType.ORDER, name = 'Supply', orderType = OrderType.SUPPLY}},
unitClass = UnitClass.RESOURCE_ROVER,
unitType = UnitType.HOVER,
armor = {ArmorType.CAST},
@@ -777,10 +789,10 @@ units = {
},
{
buildableUnits = {
- {id = UnitId.WAR_MECH, buildable = true},
- {id = UnitId.TANK, buildable = true},
- {id = UnitId.ARTILLERY, buildable = true},
- {id = UnitId.RESOURCE_ROVER, buildable = true}
+ {id = UnitId.WAR_MECH, buildable = true, trigger = 87},
+ {id = UnitId.TANK, buildable = true, trigger = 84},
+ {id = UnitId.ARTILLERY, buildable = true, trigger = 65},
+ {id = UnitId.RESOURCE_ROVER, buildable = true, trigger = 82}
},
unitClass = UnitClass.LAND_FACTORY,
unitType = UnitType.LAND,
@@ -796,7 +808,6 @@ units = {
albedoPath = 'factory.jpg',
basePath = PATH .. structurePrefix .. 'LandFactories/',
meshPath = 'landFactory.xml',
- guiScreen = 'landFactoryCommands.lua',
selectionSfx = PATH .. 'Sounds/Units/Sample/selection.ogg',
deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg',
},
@@ -814,13 +825,18 @@ units = {
basePath = PATH .. structurePrefix .. 'NavalFactories/',
meshPath = 'navalFactory.xml',
albedoPath = 'factory.jpg',
- guiScreen = 'navalFactoryCommands.lua',
selectionSfx = PATH .. 'Sounds/Units/Sample/selection.ogg',
deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg',
},
{
unitClass = UnitClass.TRADE_CENTER,
unitType = UnitType.LAND,
+ abilityButtons = {
+ {buttonType = ButtonType.BUY_REFINEDS, name = 'Buy ref', trigger = 73},
+ {buttonType = ButtonType.SELL_REFINEDS, name = 'Sell ref', trigger = 79},
+ {buttonType = ButtonType.BUY_RESEARCH, name = 'Buy rsch', trigger = 75},
+ {buttonType = ButtonType.SELL_RESEARCH, name = 'Sell rsch', trigger = 76}
+ },
isVehicle = false,
health = 500,
buildTime = 1000,
@@ -833,13 +849,13 @@ units = {
basePath = PATH .. structurePrefix .. 'TradeCenters/',
meshPath = 'tradeCenter.xml',
albedoPath = 'tradeCenter.jpg',
- guiScreen = 'tradingCenterCommands.lua',
selectionSfx = PATH .. 'Sounds/Units/Sample/selection.ogg',
deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg',
},
{
unitClass = UnitClass.LAB,
unitType = UnitType.LAND,
+ abilityButtons = {{buttonType = ButtonType.ACTIVE_GAME_STATE, name = 'Tech tree', guiScreen = 'techTree.lua'}},
isVehicle = false,
health = 500,
buildTime = 1000,
@@ -855,7 +871,6 @@ units = {
basePath = PATH .. structurePrefix .. 'Labs/',
meshPath = 'lab2.xml',
albedoPath = 'lab.jpg',
- guiScreen = 'researchStructCommands.lua',
selectionSfx = PATH .. 'Sounds/Units/Sample/selection.ogg',
deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg',
},
@@ -957,7 +972,7 @@ units = {
deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg',
},
{
- buildableUnits = {{id = UnitId.ENGINEER, buildable = true}},
+ buildableUnits = {{id = UnitId.ENGINEER, buildable = true, trigger = 69}},
unitClass = UnitClass.FORT,
unitType = UnitType.LAND,
isVehicle = false,
@@ -972,7 +987,6 @@ units = {
meshPath = 'fort2.xml',
colorNodes = {'Cube.004'},
albedoPath = 'fort.jpg',
- guiScreen = 'fortCommands.lua',
selectionSfx = PATH .. 'Sounds/Units/Sample/selection.ogg',
deathSfx = PATH .. 'Sounds/SFX/Explosions/explosion01.ogg',
},
diff --git a/Assets/Scripts/Gui/activeGameState.lua b/Assets/Scripts/Gui/activeGameState.lua
index ff32bd7..83a4dcc 100644
--- a/Assets/Scripts/Gui/activeGameState.lua
+++ b/Assets/Scripts/Gui/activeGameState.lua
@@ -6,13 +6,18 @@ s = 40
eyeIcon = 'eye.png'
refIcon = 'refineds.png'
minimapSize = {x = 200, y = 200}
-minimapPos = {x = res.x - minimapSize.x, y = 0, z = .9}
+minimapPos = {x = 0, y = res.y - minimapSize.y, z = .9}
resTextScale = {x = .5, y = .5}
resIconBasePath = 'Icons/Resources/'
pointerTex = 'pointer.png'
attackTex = 'attack.png'
garrisonTex = 'garrison.png'
+supplyTex = 'supply.png'
+hackTex = 'hack.png'
+noGarrisonTex = 'noGarrison.png'
+noSupplyTex = 'noSupply.png'
+noHackTex = 'noHack.png'
gui = {
{
@@ -38,7 +43,7 @@ gui = {
guiType = GuiType.TEXT,
name = 'wealth',
text = '',
- pos = {x = 200 + s, y = s, z = 0},
+ pos = {x = s, y = 2 * s, z = 0},
scale = resTextScale,
font = 'batang.ttf',
fontFirstChar = 0,
@@ -49,7 +54,7 @@ gui = {
guiType = GuiType.TEXT,
name = 'research',
text = '',
- pos = {x = 400 + s, y = s, z = 0},
+ pos = {x = s, y = 3 * s, z = 0},
scale = resTextScale,
font = 'batang.ttf',
fontFirstChar = 0,
@@ -66,14 +71,14 @@ gui = {
{
guiType = GuiType.GUI_RECTANGLE,
name = 'wealth',
- pos = {x = 200, y = 0, z = 0},
+ pos = {x = 0, y = 1 * s, z = 0},
size = {x = s, y = s},
imagePath = resIconBasePath .. 'wealth.png',
},
{
guiType = GuiType.GUI_RECTANGLE,
name = 'research',
- pos = {x = 400, y = 0, z = 0},
+ pos = {x = 0, y = 2 * s, z = 0},
size = {x = s, y = s},
imagePath = resIconBasePath .. 'research.png',
},
@@ -93,26 +98,14 @@ gui = {
buttonType = ButtonType.PLAYER_TRADE,
name = 'Trade',
guiScreen = 'tradingHub.lua',
- pos = {x = res.x - Size.x, y = 200, z = 0},
- size = Size,
+ pos = {x = minimapSize.x, y = res.y - minimapSize.y, z = 0},
+ size = {x = Size.x, y = minimapSize.y - .75 * sz},
trigger = 10
},
{
guiType = GuiType.GUI_RECTANGLE,
- pos = {x = res.x - sz, y = res.y - sz, z = 0},
- size = {x = sz, y = sz},
- color = {x = .6, y = .6, z = .6, w = .4}
- },
- {
- guiType = GuiType.GUI_RECTANGLE,
- pos = {x = 0, y = res.y - sz, z = 0},
- size = {x = sz, y = sz},
- color = {x = .6, y = .6, z = .6, w = .4}
- },
- {
- guiType = GuiType.GUI_RECTANGLE,
- pos = {x = sz, y = res.y - .75 * sz, z = 0},
- size = {x = res.x - 2 * sz, y = sz * .75},
+ pos = {x = minimapPos.x, y = res.y - .75 * sz, z = 0},
+ size = {x = res.x - minimapPos.x, y = sz * .75},
color = {x = .6, y = .6, z = .6, w = .4}
},
}
diff --git a/Assets/Scripts/Gui/main.lua b/Assets/Scripts/Gui/main.lua
index 0affb41..5664fdb 100644
--- a/Assets/Scripts/Gui/main.lua
+++ b/Assets/Scripts/Gui/main.lua
@@ -24,21 +24,21 @@ ButtonType = {
MAIN_MENU = 20,
CONSOLE_COMMAND_OK = 21,
BUILD = 22,
- LAND_FACTORY_TRAIN = 23,
- NAVAL_FACTORY_TRAIN = 24,
- FORT_TRAIN = 25,
- STATISTICS = 26,
- RESEARCH = 27,
- BUY_REFINEDS = 28,
- SELL_REFINEDS = 29,
- BUY_RESEARCH = 30,
- SELL_RESEARCH = 31,
- ACTIVE_GAME_STATE = 32,
- PLAYER_TRADE = 33,
- TRADING_SCREEN = 34,
- TRADE_OFFER = 35,
- RESOURCE_AMMOUNT = 36,
- MINIMAP = 37
+ TRAIN = 23,
+ STATISTICS = 24,
+ RESEARCH = 25,
+ BUY_REFINEDS = 26,
+ SELL_REFINEDS = 27,
+ BUY_RESEARCH = 28,
+ SELL_RESEARCH = 29,
+ ACTIVE_GAME_STATE = 30,
+ PLAYER_TRADE = 31,
+ TRADING_SCREEN = 32,
+ TRADE_OFFER = 33,
+ RESOURCE_AMMOUNT = 34,
+ UNIT_STATE = 35,
+ ORDER = 36,
+ MINIMAP = 37,
}
ListboxType = {
diff --git a/Assets/Scripts/Gui/tradingCenterCommands.lua b/Assets/Scripts/Gui/tradingCenterCommands.lua
deleted file mode 100644
index 4a4dbda..0000000
--- a/Assets/Scripts/Gui/tradingCenterCommands.lua
+++ /dev/null
@@ -1,39 +0,0 @@
-res = graphics.resolution
-Size = {x = 70, y = 70}
-margin = 10
-sz = {x = Size.x - margin, y = Size.y - margin}
-
-gui = {
- {
- pos = {x = res.x - Size.x, y = res.y - Size.y, z = 0},
- size = sz,
- name = 'Buy ref',
- guiType = GuiType.BUTTON,
- buttonType = ButtonType.BUY_REFINEDS,
- trigger = 73,
- },
- {
- pos = {x = res.x - 2 * Size.x, y = res.y - Size.y, z = 0},
- size = sz,
- name = 'Sell ref',
- guiType = GuiType.BUTTON,
- buttonType = ButtonType.SELL_REFINEDS,
- trigger = 79,
- },
- {
- pos = {x = res.x - Size.x, y = res.y - 2 * Size.y, z = 0},
- size = sz,
- name = 'Buy rsch',
- guiType = GuiType.BUTTON,
- buttonType = ButtonType.BUY_RESEARCH,
- trigger = 75,
- },
- {
- pos = {x = res.x - 2 * Size.x, y = res.y - 2 * Size.y, z = 0},
- size = sz,
- name = 'Sell rsch',
- guiType = GuiType.BUTTON,
- buttonType = ButtonType.SELL_RESEARCH,
- trigger = 76,
- }
-}
diff --git a/Assets/Scripts/Gui/unitGui.lua b/Assets/Scripts/Gui/unitGui.lua
new file mode 100644
index 0000000..deb6fbf
--- /dev/null
+++ b/Assets/Scripts/Gui/unitGui.lua
@@ -0,0 +1,102 @@
+res = graphics.resolution
+sz = 210
+
+resTextScale = {x = .5, y = .5}
+buttonInitPos = {x = sz, y = res.y - .65 * sz, z = 0}
+buttonSize = {x = 50, y = 50}
+buttonSpace = {x = 10, y = 10}
+
+function generateButton(numGui, buttonData)
+ xOffset = math.floor(.5 * numGui) * (buttonSize.x + buttonSpace.x)
+ yOffset = (numGui + 1) % 2 == 0 and (buttonSize.y + buttonSpace.y) or 0
+
+ button = {
+ pos = {x = buttonInitPos.x + xOffset, y = buttonInitPos.y + yOffset, z = .5},
+ size = buttonSize,
+ guiType = GuiType.BUTTON,
+ name = buttonData.name,
+ imagePath = buttonData.imagePath,
+ buttonType = buttonData.buttonType,
+ trigger = (buttonData.trigger or -1),
+ orderType = buttonData.orderType,
+ factoryId = buttonData.factoryId,
+ engineerId = buttonData.engineerId,
+ guiScreen = buttonData.guiScreen,
+ slotId = buttonData.slotId
+ }
+
+ return button
+end
+
+function generateGui(unitId)
+ local gui = {}
+ vehicleButtonData = {
+ {buttonType = ButtonType.UNIT_STATE, imagePath = 'Icons/Buttons/chase.png'},
+ {buttonType = ButtonType.ORDER, orderType = OrderType.GARRISON, name = 'Garrison'},
+ {buttonType = ButtonType.ORDER, orderType = OrderType.PATROL, name = 'Patrol'},
+ {buttonType = ButtonType.ORDER, orderType = OrderType.HALT, name = 'Halt'},
+ }
+ structureButtonData = {
+ {buttonType = ButtonType.ORDER, orderType = OrderType.HALT, name = 'Halt'}
+ }
+
+ mainUnit = units[unitId + 1]
+ unitButtonData = mainUnit.isVehicle and vehicleButtonData or structureButtonData
+
+ if mainUnit.garrisonCapacity then
+ unitButtonData[#unitButtonData + 1] = {
+ buttonType = ButtonType.ORDER,
+ orderType = OrderType.EJECT,
+ name = 'Eject'
+ }
+ end
+
+ for i = 1, #unitButtonData do
+ gui[#gui + 1] = generateButton(#gui, unitButtonData[i])
+ end
+
+ if mainUnit.abilityButtons then
+ for i = 1, #mainUnit.abilityButtons do
+ abilButton = mainUnit.abilityButtons[i]
+
+ buttonData = {
+ trigger = abilButton.trigger,
+ name = abilButton.name,
+ buttonType = abilButton.buttonType,
+ guiScreen = abilButton.guiScreen,
+ orderType = abilButton.orderType
+ }
+ gui[#gui + 1] = generateButton(#gui, buttonData)
+ end
+ end
+
+ if mainUnit.buildableUnits then
+ for i = 1, #mainUnit.buildableUnits do
+ buildUnit = mainUnit.buildableUnits[i]
+
+ if not buildUnit.buildable then goto continue end
+
+ isFactory = (
+ mainUnit.unitClass == UnitClass.LAND_FACTORY or
+ mainUnit.unitClass == UnitClass.NAVAL_FACTORY or
+ mainUnit.unitClass == UnitClass.FORT
+ )
+
+ buttonData = {
+ trigger = buildUnit.trigger,
+ name = units[buildUnit.id + 1].name,
+ buttonType = (mainUnit.isVehicle and ButtonType.BUILD or ButtonType.TRAIN),
+ factoryId = (isFactory and unitId or nil),
+ engineerId = (mainUnit.unitClass == UnitClass.ENGINEER and unitId or nil),
+ slotId = (ButtonType.BUILD and i - 1 or nil)
+ }
+ gui[#gui + 1] = generateButton(#gui, buttonData)
+
+ ::continue::
+ end
+ end
+
+ return gui
+end
+
+gui = generateGui(_mainUnitId)
diff --git a/Assets/Textures/Icons/Buttons/chase.png b/Assets/Textures/Icons/Buttons/chase.png
new file mode 100644
index 0000000..75ec3fc
Binary files /dev/null and b/Assets/Textures/Icons/Buttons/chase.png differ
diff --git a/Assets/Textures/Icons/Buttons/holdFire.png b/Assets/Textures/Icons/Buttons/holdFire.png
new file mode 100644
index 0000000..f5c34f4
Binary files /dev/null and b/Assets/Textures/Icons/Buttons/holdFire.png differ
diff --git a/Assets/Textures/Icons/Buttons/standGround.png b/Assets/Textures/Icons/Buttons/standGround.png
new file mode 100644
index 0000000..4a56b92
Binary files /dev/null and b/Assets/Textures/Icons/Buttons/standGround.png differ
diff --git a/Assets/Textures/Icons/Buttons/state.svg b/Assets/Textures/Icons/Buttons/state.svg
new file mode 100644
index 0000000..9eba101
--- /dev/null
+++ b/Assets/Textures/Icons/Buttons/state.svg
@@ -0,0 +1,98 @@
+
+
+
+
diff --git a/Assets/Textures/Icons/Cursors/hack.png b/Assets/Textures/Icons/Cursors/hack.png
new file mode 100644
index 0000000..d096ca8
Binary files /dev/null and b/Assets/Textures/Icons/Cursors/hack.png differ
diff --git a/Assets/Textures/Icons/Cursors/noGarrison.png b/Assets/Textures/Icons/Cursors/noGarrison.png
new file mode 100644
index 0000000..fa4ff20
Binary files /dev/null and b/Assets/Textures/Icons/Cursors/noGarrison.png differ
diff --git a/Assets/Textures/Icons/Cursors/noGarrison.svg b/Assets/Textures/Icons/Cursors/noGarrison.svg
new file mode 100644
index 0000000..d542f82
--- /dev/null
+++ b/Assets/Textures/Icons/Cursors/noGarrison.svg
@@ -0,0 +1,63 @@
+
+
+
+
diff --git a/Assets/Textures/Icons/Cursors/noHack.png b/Assets/Textures/Icons/Cursors/noHack.png
new file mode 100644
index 0000000..9b01432
Binary files /dev/null and b/Assets/Textures/Icons/Cursors/noHack.png differ
diff --git a/Assets/Textures/Icons/Cursors/noHack.svg b/Assets/Textures/Icons/Cursors/noHack.svg
new file mode 100644
index 0000000..e919fa9
--- /dev/null
+++ b/Assets/Textures/Icons/Cursors/noHack.svg
@@ -0,0 +1,92 @@
+
+
+
+
diff --git a/Assets/Textures/Icons/Cursors/noSupply.png b/Assets/Textures/Icons/Cursors/noSupply.png
new file mode 100644
index 0000000..f8bacac
Binary files /dev/null and b/Assets/Textures/Icons/Cursors/noSupply.png differ
diff --git a/Assets/Textures/Icons/Cursors/noSupply.svg b/Assets/Textures/Icons/Cursors/noSupply.svg
new file mode 100644
index 0000000..0818b29
--- /dev/null
+++ b/Assets/Textures/Icons/Cursors/noSupply.svg
@@ -0,0 +1,96 @@
+
+
+
+
diff --git a/Assets/Textures/Icons/Cursors/supply.png b/Assets/Textures/Icons/Cursors/supply.png
new file mode 100644
index 0000000..17b1bb6
Binary files /dev/null and b/Assets/Textures/Icons/Cursors/supply.png differ
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 50058ef..4c6d671 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,7 +15,7 @@ set(BUILD_TESTS ON)
set(BUILD_SHARED_LIBS OFF CACHE BOOL FORCED)
cmake_policy(SET CMP0015 NEW)
-set(UNIT_BUTTONS unitButton.cpp tradeButton.cpp buildButton.cpp trainButton.cpp researchButton.cpp)
+set(UNIT_BUTTONS unitButton.cpp tradeButton.cpp buildButton.cpp trainButton.cpp researchButton.cpp orderButton.cpp stateToggleButton.cpp)
set(OPTIONS_BUTTONS optionsButton.cpp tabButton.cpp okButton.cpp defaultsButton.cpp)
set(TRADING_BUTTONS playerTradeButton.cpp tradingScreenButton.cpp offerButton.cpp resourceAmmountButton.cpp)
set(MENU_BUTTONS mainMenuButton.cpp singlePlayerButton.cpp exitButton.cpp backButton.cpp playButton.cpp)
diff --git a/activeGameState.cpp b/activeGameState.cpp
index 7472049..efdf7f4 100755
--- a/activeGameState.cpp
+++ b/activeGameState.cpp
@@ -27,6 +27,9 @@
#include "gameObjectFrameController.h"
#include "gameObjectFactory.h"
#include "cameraController.h"
+#include "unitButton.h"
+#include "extractor.h"
+#include "resourceDeposit.h"
#include "concreteGuiManager.h"
using namespace vb01;
@@ -74,12 +77,27 @@ namespace battleship{
string pt = SOL_LUA_VIEW["pointerTex"],
at = SOL_LUA_VIEW["attackTex"],
gt = SOL_LUA_VIEW["garrisonTex"],
+ st = SOL_LUA_VIEW["supplyTex"],
+ ht = SOL_LUA_VIEW["hackTex"],
+ ngt = SOL_LUA_VIEW["noGarrisonTex"],
+ nst = SOL_LUA_VIEW["noSupplyTex"],
+ nht = SOL_LUA_VIEW["noHackTex"],
p1[]{basePath + pt},
p2[]{basePath + at},
- p3[]{basePath + gt};
+ p3[]{basePath + gt},
+ p4[]{basePath + st},
+ p5[]{basePath + ht},
+ p6[]{basePath + ngt},
+ p7[]{basePath + nst},
+ p8[]{basePath + nht};
pointerTex = new Texture(p1, 1, false);
attackTex = new Texture(p2, 1, false);
garrisonTex = new Texture(p3, 1, false);
+ supplyTex = new Texture(p4, 1, false);
+ hackTex = new Texture(p5, 1, false);
+ noGarrisonTex = new Texture(p6, 1, false);
+ noSupplyTex = new Texture(p7, 1, false);
+ noHackTex = new Texture(p8, 1, false);
Root *root = Root::getSingleton();
Material *mat = new Material(root->getLibPath() + "gui");
@@ -114,13 +132,52 @@ namespace battleship{
Vector2 cursorPos = getCursorPos();
cursorNode->setPosition(Vector3(cursorPos.x, cursorPos.y, .8));
- bool canSelect = canSelectHoveredOnGameObj();
- bool ownGameObj = (gameObjHoveredOn && gameObjHoveredOn->getPlayer()->getTeam() == mainPlayer->getTeam());
+ if(mainPlayer->getNumSelectedUnits() > 0){
+ bool ownGameObj = (gameObjHoveredOn && gameObjHoveredOn->getPlayer()->getTeam() == mainPlayer->getTeam());
+ bool gameObjUnit = (gameObjHoveredOn && gameObjHoveredOn->getType() == GameObject::Type::UNIT);
+ bool gameObjTransport = (gameObjUnit && ((Unit*)gameObjHoveredOn)->getNumGarrisonSlots() > 0);
+ bool canGarrison = true;
- if(controlPressed || (gameObjHoveredOn && !ownGameObj && gameObjHoveredOn->getType() == GameObject::Type::UNIT))
- cursorState = CursorState::ATTACK;
- else
- cursorState = CursorState::NORMAL;
+ if(gameObjUnit && gameObjTransport)
+ for(int i = 0; i < mainPlayer->getNumSelectedUnits(); i++)
+ if(!((Unit*)gameObjHoveredOn)->canGarrison((Vehicle*)mainPlayer->getSelectedUnit(i))){
+ canGarrison = false;
+ break;
+ }
+
+ bool supply = (
+ gameObjUnit &&
+ ((Unit*)gameObjHoveredOn)->getUnitClass() == UnitClass::EXTRACTOR &&
+ mainPlayer->getSelectedUnit(0)->getUnitClass() == UnitClass::RESOURCE_ROVER
+ );
+
+ if(!forceCursorState){
+ if(gameObjUnit && gameObjTransport){
+ orderPossible = (ownGameObj && canGarrison);
+ cursorState = CursorState::GARRISON;
+ }
+ else if(supply){
+ orderPossible = (ownGameObj && ((Extractor*)gameObjHoveredOn)->getDeposit()->getAmmount());
+ cursorState = CursorState::SUPPLY;
+ }
+ else if(gameObjUnit && !ownGameObj)
+ cursorState = CursorState::ATTACK;
+ else
+ cursorState = CursorState::NORMAL;
+ }
+ else{
+ if(cursorState == CursorState::GARRISON)
+ orderPossible = (ownGameObj && gameObjTransport && canGarrison);
+ else if(cursorState == CursorState::SUPPLY)
+ orderPossible = (ownGameObj && supply && ((Extractor*)gameObjHoveredOn)->getDeposit()->getAmmount());
+ else if(cursorState == CursorState::HACK)
+ orderPossible = (!ownGameObj && gameObjUnit && mainPlayer->getSelectedUnit(0)->getUnitClass() == UnitClass::ENGINEER);
+ else if(gameObjUnit)
+ cursorState = CursorState::ATTACK;
+ else
+ cursorState = CursorState::NORMAL;
+ }
+ }
cursorNode->setVisible(cursorState != CursorState::NORMAL);
Texture *tex = nullptr;
@@ -130,7 +187,13 @@ namespace battleship{
tex = attackTex;
break;
case CursorState::GARRISON:
- tex = garrisonTex;
+ tex = (orderPossible ? garrisonTex : noGarrisonTex);
+ break;
+ case CursorState::SUPPLY:
+ tex = (orderPossible ? supplyTex : noSupplyTex);
+ break;
+ case CursorState::HACK:
+ tex = (orderPossible ? hackTex : noHackTex);
break;
}
@@ -182,6 +245,13 @@ namespace battleship{
renderUnits();
+ vector currSelectedUnits = mainPlayer->getSelectedUnits();
+
+ if(prevSelectedUnits != currSelectedUnits){
+ addUnitGui();
+ prevSelectedUnits = currSelectedUnits;
+ }
+
if(fc->isRotating() || fc->isPlacingOnSurface() || fc->isPlacingVertically())
fc->update();
@@ -351,14 +421,6 @@ namespace battleship{
if(!u->getLosLightNode()) u->initLosLight();
model->setVisible(true);
-
- Vector2 pos = u->getScreenPos();
- string guiScreen = u->getGuiScreen();
-
- if(!selUnits.empty() && u == selUnits[0] && guiScreen != "" && guiScreen != unitGuiScreen){
- guiManager->readLuaScreenScript(u->getGuiScreen(), buttons, listboxes, checkboxes, sliders, textboxes, guiRects, texts);
- unitGuiScreen = guiScreen;
- }
}
else{
if(u->getLosLightNode()) u->destroyLosLight();
@@ -435,6 +497,7 @@ namespace battleship{
}
mainPlayer->issueOrder(type, destDir, targets, addOrder);
+ forceCursorState = false;
this->targets.clear();
}
@@ -457,6 +520,24 @@ namespace battleship{
for(Unit *unit : selectedUnits)
unit->setState(state);
}
+
+ void ActiveGameState::addUnitGui(){
+ vector currSelectedUnits = mainPlayer->getSelectedUnits();
+
+ if(currSelectedUnits.empty()) return;
+
+ ConcreteGuiManager *guiManager = ConcreteGuiManager::getSingleton();
+
+ sol::state_view SOL_LUA_VIEW = generateView();
+ SOL_LUA_VIEW.script("_mainUnitId = " + to_string(currSelectedUnits[0]->getId()));
+ guiManager->readLuaScreenScriptDel("unitGui.lua", unitButtons);
+
+ SOL_LUA_VIEW.script("numGui = #gui");
+ int numButtons = SOL_LUA_VIEW["numGui"];
+
+ for(int i = 0; i < numButtons; i++)
+ unitButtons.push_back(guiManager->getButtons()[guiManager->getButtons().size() - (i + 1)]);
+ }
void ActiveGameState::onAction(int bind, bool isPressed) {
GameObjectFrameController *ufCtr = GameObjectFrameController::getSingleton();
@@ -523,29 +604,25 @@ namespace battleship{
}
}
else if(!isSelectionBox){
- bool canSelect = canSelectHoveredOnGameObj();
bool ownGameObj = (gameObjHoveredOn && gameObjHoveredOn->getPlayer()->getTeam() == mainPlayer->getTeam());
- if(gameObjHoveredOn && gameObjHoveredOn->getType() == GameObject::Type::UNIT && ownGameObj && ((Unit*)gameObjHoveredOn)->getNumGarrisonSlots() > 0){
- bool canGarrison = true;
-
- for(int i = 0; i < mainPlayer->getNumSelectedUnits(); i++)
- if(!((Unit*)gameObjHoveredOn)->canGarrison((Vehicle*)mainPlayer->getSelectedUnit(i))){
- canGarrison = false;
- break;
- }
-
- if(canGarrison)
- issueOrder(Order::TYPE::GARRISON, vector{Order::Target((Unit*)gameObjHoveredOn, gameObjHoveredOn->getPos())}, shiftPressed);
+ if(cursorState == CursorState::GARRISON){
+ if(orderPossible) issueOrder(Order::TYPE::GARRISON, vector{Order::Target((Unit*)gameObjHoveredOn, gameObjHoveredOn->getPos())}, shiftPressed);
}
- else if(gameObjHoveredOn && ownGameObj && ((Unit*)gameObjHoveredOn)->getUnitClass() == UnitClass::EXTRACTOR && !controlPressed){
- issueOrder(Order::TYPE::SUPPLY, vector{Order::Target((Unit*)gameObjHoveredOn)}, shiftPressed);
+ else if(cursorState == CursorState::SUPPLY){
+ if(orderPossible) issueOrder(Order::TYPE::SUPPLY, vector{Order::Target((Unit*)gameObjHoveredOn)}, shiftPressed);
}
- else if(gameObjHoveredOn && (controlPressed || (!ownGameObj && gameObjHoveredOn->getType() == GameObject::Type::UNIT)))
- issueOrder(Order::TYPE::ATTACK, vector{Order::Target((Unit*)gameObjHoveredOn, gameObjHoveredOn->getPos())}, shiftPressed);
- else if(controlPressed && !gameObjHoveredOn){
- castRayToTerrain();
- issueOrder(Order::TYPE::ATTACK, targets, shiftPressed);
+ else if(cursorState == CursorState::ATTACK){
+ if(controlPressed && !gameObjHoveredOn){
+ castRayToTerrain();
+ issueOrder(Order::TYPE::ATTACK, targets, shiftPressed);
+ }
+ else{
+ if(orderPossible) issueOrder(Order::TYPE::ATTACK, vector{Order::Target((Unit*)gameObjHoveredOn, gameObjHoveredOn->getPos())}, shiftPressed);
+ }
+ }
+ else if(cursorState == CursorState::HACK){
+ if(orderPossible) issueOrder(Order::TYPE::HACK, vector{Order::Target((Unit*)gameObjHoveredOn)}, shiftPressed);
}
else if(selectedUnits[0]->getUnitClass() == UnitClass::ENGINEER && ufCtr->isPlacingOnSurface()){
castRayToTerrain();
@@ -561,7 +638,7 @@ namespace battleship{
buildableStructSelected = false;
}
- else if(!canSelect){
+ else if(!canSelectHoveredOnGameObj()){
if(targets.empty()) castRayToTerrain();
issueOrder(Order::TYPE::MOVE, targets, shiftPressed);
@@ -591,6 +668,7 @@ namespace battleship{
}
break;
+ /*
case Bind::HACK:
if(isPressed){
if(gameObjHoveredOn && gameObjHoveredOn->getType() == GameObject::Type::UNIT && gameObjHoveredOn->getPlayer()->getTeam() != mainPlayer->getTeam())
@@ -598,6 +676,7 @@ namespace battleship{
break;
}
+ */
case Bind::SHIFT_SUB_DEPTH:
ufCtr->toggleFrameTransformations(false, false, isPressed);
break;
@@ -626,7 +705,10 @@ namespace battleship{
break;
//TODO reimplement submarine diving mechanic
case Bind::LEFT_CONTROL:
- controlPressed = isPressed;
+ if(isPressed) cursorState = CursorState::ATTACK;
+
+ forceCursorState = isPressed;
+ controlPressed = isPressed;
break;
case Bind::LEFT_SHIFT:
{
@@ -676,6 +758,7 @@ namespace battleship{
break;
case Bind::DESELECT_STRUCTURE:
+ forceCursorState = false;
buildableStructSelected = false;
ufCtr->toggleFrameTransformations(false, false, false);
ufCtr->removeGameObjectFrames();
diff --git a/activeGameState.h b/activeGameState.h
index 358125b..579e50e 100755
--- a/activeGameState.h
+++ b/activeGameState.h
@@ -19,9 +19,19 @@ namespace vb01Gui{
namespace battleship{
class GameObject;
+ class Unit;
+ class UnitButton;
class ActiveGameState : public gameBase::AbstractAppState {
public:
+ enum CursorState{
+ NORMAL,
+ ATTACK,
+ GARRISON,
+ SUPPLY,
+ HACK
+ };
+
ActiveGameState(GuiAppState*, int);
~ActiveGameState();
void onAttached();
@@ -30,6 +40,8 @@ namespace battleship{
void onAction(int, bool);
void onAnalog(int, float);
void onRawMouseWheelScroll(bool);
+ inline CursorState getCursorState(){return cursorState;}
+ inline void setCursorState(CursorState cs){this->cursorState = cs;}
inline void addButton(vb01Gui::Button *b){buttons.push_back(b);}
inline std::vector getButtons(){return buttons;}
inline Player* getPlayer(){return mainPlayer;}
@@ -37,14 +49,9 @@ namespace battleship{
inline void setBuildableStructSelected(bool bss){this->buildableStructSelected = bss;}
inline bool isBuildableStructSelected(){return buildableStructSelected;}
inline float getDepth(){return depth;}
+ inline void setForceCursorState(bool force){this->forceCursorState = force;}
+ inline bool isForceCursorState(){return forceCursorState;}
private:
- enum CursorState{
- NORMAL,
- ATTACK,
- GARRISON,
- SUPPLY
- };
-
bool selectedUnitsAmongst(std::vector);
void updateGameObjHoveredOn();
void initCursor();
@@ -60,6 +67,7 @@ namespace battleship{
void issueOrder(Order::TYPE, std::vector, bool);
bool isInLineOfSight(vb01::Vector3, float, Unit*);
void enableUnitState(Unit::State);
+ void addUnitGui();
inline bool canSelectHoveredOnGameObj(){return gameObjHoveredOn && gameObjHoveredOn->isSelectable() && gameObjHoveredOn->getPlayer() == mainPlayer;}
CursorState cursorState = CursorState::NORMAL;
@@ -69,9 +77,9 @@ namespace battleship{
GameObject *gameObjHoveredOn = nullptr;
vb01::Node *dragboxNode = nullptr;
vb01::Vector2 clickPoint;
- std::vector unitGroups[9];
+ std::vector unitGroups[9], prevSelectedUnits;
std::vector targets;
- std::vector buttons;
+ std::vector buttons, unitButtons;
bool isSelectionBox = false;
bool shiftPressed = false;
bool controlPressed = false;
@@ -80,12 +88,14 @@ namespace battleship{
bool buildableStructSelected = false;
bool selectingPatrolPoints = false;
bool selectingDestOrient = false;
+ bool forceCursorState = false;
+ bool orderPossible = false;
int playerId, zooms = 0;
const int NUM_MAX_ZOOMS = 10;
float depth = 1;
vb01::s64 lastSelectMouseClicked = 0, lastOrderMouseClicked = 0;
vb01::Node *cursorNode = nullptr;
- vb01::Texture *pointerTex = nullptr, *attackTex = nullptr, *garrisonTex = nullptr;
+ vb01::Texture *pointerTex = nullptr, *attackTex = nullptr, *garrisonTex = nullptr, *noGarrisonTex = nullptr, *supplyTex = nullptr, *noSupplyTex = nullptr, *hackTex = nullptr, *noHackTex = nullptr;
};
}
diff --git a/activeStateButton.cpp b/activeStateButton.cpp
index 275feec..529495d 100644
--- a/activeStateButton.cpp
+++ b/activeStateButton.cpp
@@ -27,24 +27,6 @@ namespace battleship{
}
void ActiveStateButton::onClick(){
- ConcreteGuiManager *guiManager = ConcreteGuiManager::getSingleton();
-
- vector listboxes{};
- vector checkboxes{};
- vector sliders{};
- vector textboxes{};
- vector guiRects{
- guiManager->getGuiRectangle("refineds"),
- guiManager->getGuiRectangle("wealth"),
- guiManager->getGuiRectangle("research"),
- };
- vector texts{
- guiManager->getText("depth"),
- guiManager->getText("refineds"),
- guiManager->getText("wealth"),
- guiManager->getText("research")
- };
-
- guiManager->readLuaScreenScript(guiScreen, buttons, listboxes, checkboxes, sliders, textboxes, guiRects, texts);
+ ConcreteGuiManager::getSingleton()->parseLuaScript(guiScreen);
}
}
diff --git a/concreteGuiManager.cpp b/concreteGuiManager.cpp
index d994c6a..3ef3762 100644
--- a/concreteGuiManager.cpp
+++ b/concreteGuiManager.cpp
@@ -3,6 +3,7 @@
#include
#include "concreteGuiManager.h"
+#include "unit.h"
#include "gameManager.h"
#include "singlePlayerButton.h"
#include "mapEditorButton.h"
@@ -32,6 +33,8 @@
#include "tradingScreenButton.h"
#include "offerButton.h"
#include "resourceAmmountButton.h"
+#include "orderButton.h"
+#include "stateToggleButton.h"
#include "minimapButton.h"
namespace battleship{
@@ -181,37 +184,11 @@ namespace battleship{
break;
}
case BUILD:
- {
- int unitId = SOL_LUA_STATE["UnitId"]["ENGINEER"];
- int strId = SOL_LUA_STATE["units"][unitId + 1]["buildableUnits"][guiId + 1]["id"];
- string buttonName = SOL_LUA_STATE["units"][strId + 1]["name"];
- button = new BuildButton(pos, size, buttonName, (int)guiTable["trigger"], imagePath, unitId, guiId);
+ button = new BuildButton(pos, size, name, (int)guiTable["trigger"], imagePath, (int)guiTable["engineerId"], (int)guiTable["slotId"]);
break;
- }
- case LAND_FACTORY_TRAIN:
- {
- int facId = SOL_LUA_STATE["UnitId"]["LAND_FACTORY"];
- int unitId = SOL_LUA_STATE["units"][facId + 1]["buildableUnits"][guiId + 1]["id"];
- string buttonName = SOL_LUA_STATE["units"][unitId + 1]["name"];
- button = new TrainButton(pos, size, buttonName, (int)guiTable["trigger"], imagePath, facId, guiId);
+ case TRAIN:
+ button = new TrainButton(pos, size, name, (int)guiTable["trigger"], imagePath, (int)guiTable["factoryId"], (int)guiTable["slotId"]);
break;
- }
- case NAVAL_FACTORY_TRAIN:
- {
- int facId = SOL_LUA_STATE["UnitId"]["NAVAL_FACTORY"];
- int unitId = SOL_LUA_STATE["units"][facId + 1]["buildableUnits"][guiId + 1]["id"];
- string buttonName = SOL_LUA_STATE["units"][unitId + 1]["name"];
- button = new TrainButton(pos, size, buttonName, (int)guiTable["trigger"], imagePath, facId, guiId);
- break;
- }
- case FORT_TRAIN:
- {
- int facId = SOL_LUA_STATE["UnitId"]["FORT"];
- int unitId = SOL_LUA_STATE["units"][facId + 1]["buildableUnits"][guiId + 1]["id"];
- string buttonName = SOL_LUA_STATE["units"][unitId + 1]["name"];
- button = new TrainButton(pos, size, buttonName, (int)guiTable["trigger"], imagePath, facId, guiId);
- break;
- }
case STATISTICS:
button = new StatsButton(pos, size, name, (int)guiTable["trigger"], imagePath);
break;
@@ -252,6 +229,12 @@ namespace battleship{
case RESOURCE_AMMOUNT:
button = new ResourceAmmountButton(pos, size, name, (int)guiTable["ammount"], (int)guiTable["trigger"], imagePath);
break;
+ case ORDER:
+ button = new OrderButton(pos, size, name, (int)guiTable["trigger"], imagePath, (int)guiTable["orderType"]);
+ break;
+ case UNIT_STATE:
+ button = new StateToggleButton(pos, size, name, (int)guiTable["trigger"], imagePath);
+ break;
case MINIMAP:{
string minimapPath = GameManager::getSingleton()->getPath() + "Models/Maps/" + Map::getSingleton()->getMapName() + "/minimap.jpg";
button = new MinimapButton(pos, size, minimapPath);
@@ -547,10 +530,32 @@ namespace battleship{
vector checkboxExceptions,
vector sliderExceptions,
vector textboxExceptions,
- vector guiRecttboxExceptions,
+ vector guiRectboxExceptions,
vector textExceptions
){
- removeAllGuiElements(buttonExceptions, listboxExceptions, checkboxExceptions, sliderExceptions, textboxExceptions, guiRecttboxExceptions, textExceptions);
+ removeAllGuiElements(buttonExceptions, listboxExceptions, checkboxExceptions, sliderExceptions, textboxExceptions, guiRectboxExceptions, textExceptions);
+ guiElements.clear();
+ parseLuaScript(script);
+ }
+
+ void ConcreteGuiManager::readLuaScreenScriptDel(
+ string script,
+ vector