Files
PlanetFleet/Assets/Scripts/Core/player.lua
T

339 lines
9.8 KiB
Lua

Player.numStartEngis = 3
Player.baseDir = nil
Player.numDefWarMechs = 1
Player.numTaskForceWarMechs = 5
Player.numTaskForceTanks = 1
Player.numTaskForceArtillery = 1
Player.taskForceClearing = false
Player.movingToHostileSpawnPoint = false
--TODO use enum-like values instead of literals for order types
--TODO simplify building construction
function Player:buildFort()
forts = self:getUnitsByClass(UnitClass.FORT, 1)
if #forts > 0 then
return forts[1]:toStructure():getBuildStatus() >= 100 and BTNodeResult.SUCCESS or BTNodeResult.RUNNING
end
engis = self:getUnitsByClass(UnitClass.ENGINEER, 1)
if #engis == 0 then return BTNodeResult.FAILURE end
self:deselectUnits()
self:selectUnits({engis[1]})
map = Map.getSingleton()
sp = map:getSpawnPoint(self:getSpawnPointId())
minDistId = nil
for i = 0, map:getNumSpawnPoints() - 1 do
if i == self:getSpawnPointId() then goto continue end
if minDistId == nil then minDistId = i end
if map:getSpawnPoint(i):getDistanceFrom(sp) < map:getSpawnPoint(minDistId):getDistanceFrom(sp) then
minDistId = i
end
::continue::
end
self.baseDir = map:getSpawnPoint(minDistId):subtr(sp):norm()
right = (self.baseDir:getAngleBetween(Vector3:new(1, 0, 0)) > 1.57)
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)
return BTNodeResult.RUNNING
end
function Player:trainEngineers()
fort = self:getUnitsByClass(UnitClass.FORT, 1)[1]:toFactory()
engineers = self:getUnitsByClass(UnitClass.ENGINEER, -1)
engineerDiffNum = self.numStartEngis - #engineers
queueDiff = engineerDiffNum - #fort:getQueue()
for i = 1, queueDiff do fort:appendToQueue(0) end
engisStartNumBuilt = (#self:getUnitsByClass(UnitClass.ENGINEER, -1) == self.numStartEngis)
return (engisStartNumBuilt and BTNodeResult.SUCCESS or BTNodeResult.RUNNING)
end
--Correct resource deposit selection
function Player:buildExtractor()
if #self:getUnitsByClass(UnitClass.EXTRACTOR, 1) > 0 then
return true
end
engineer = self:getUnitsByClass(UnitClass.ENGINEER, -1)[1]
self:deselectUnits()
self:selectUnits({engineer})
deposits = {}
players = Game.getSingleton():getPlayers()
for i = 1, #players do
deps = players[i]:getResourceDeposits()
table.move(deps, 1, #deps, #deposits + 1, deposits)
end
if #deposits == 0 then return false end
depPos = deposits[1]:getPos()
spawnPoint = Map.getSingleton():getSpawnPoint(self:getSpawnPointId())
for i = 1, #deposits do
if deposits[i]:getPos():getDistanceFrom(spawnPoint) < depPos:getDistanceFrom(spawnPoint) then
depPos = deposits[i]:getPos()
end
end
extractor = GameObjectFactory.createUnit(self, UnitId.EXTRACTOR, depPos, Quaternion:new(1, 0, 0, 0), 0)
self:addUnit(extractor)
self:issueOrder(1, Vector3:new(0, 0, 0), {Target:new(extractor, Vector3:new(0, 0, 0))}, false)
return true
end
function Player:startBuilding(buildingId, engiId, angle)
engineer = self:getUnitsByClass(UnitClass.ENGINEER, -1)[engiId]
self:deselectUnits()
self:selectUnits({engineer})
dirVec = Quaternion:new(angle, Vector3:new(0, 1, 0)):multVec(baseDir)
refPos = Map.getSingleton():getSpawnPoint(self:getSpawnPointId()):add(dirVec:mult(20))
building = GameObjectFactory.createUnit(self, buildingId, refPos, 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)
end
function Player:buildRefinery()
if #self:getUnitsByClass(UnitClass.REFINERY, 1) == 0 then
self:startBuilding(UnitId.REFINERY, 2, -.6)
end
refineries = self:getUnitsByClass(UnitClass.REFINERY, -1)
refineryBuilt = false
for i = 1, #refineries do
if refineries[i]:toStructure():getBuildStatus() == 100 then
refineryBuilt = true
break
end
end
return refineryBuilt
end
function Player:buildLandFactory()
if #self:getUnitsByClass(UnitClass.LAND_FACTORY, 1) == 0 then
self:startBuilding(UnitId.LAND_FACTORY, 3, .6)
end
factories = self:getUnitsByClass(UnitClass.LAND_FACTORY, -1)
factoryBuilt = false
for i = 1, #factories do
if factories[i]:toStructure():getBuildStatus() == 100 then
factoryBuilt = true
break
end
end
return factoryBuilt
end
function Player:buildHarvester()
if #self:getUnitsByClass(UnitClass.RESOURCE_ROVER, 1) > 0 then
return true
end
landFactories = self:getUnitsByClass(UnitClass.LAND_FACTORY, 1)
if #landFactories == 0 then return false end
factory = landFactories[1]:toFactory()
if #factory:getQueue() == 0 then
factory:appendToQueue(3)
end
return false
end
function Player:startHarvesting()
harvesters = self:getUnitsByClass(UnitClass.RESOURCE_ROVER, -1)
for i = 1, #harvesters do
if harvesters[i]:getNumOrders() > 0 and harvesters[i]:getOrder(0).type == 7 then
return true
end
end
extrs = self:getUnitsByClass(UnitClass.EXTRACTOR, 1)
if #extrs == 0 then return false end
self:deselectUnits()
self:selectUnits({harvesters[1]})
self:issueOrder(7, Vector3:new(0, 0, 0), {Target:new(extrs[1], Vector3:new(0, 0, 0))}, false)
return true
end
function Player:buildTaskforceUnitGroup(numUnits, currNumUnits, factory, buId)
if currNumUnits < numUnits then
for i = 1, numUnits - currNumUnits do
factory:appendToQueue(buId)
end
end
end
function Player:buildTaskforce()
currNumBuiltWarMechs = #self:getUnitsByClass(UnitClass.WAR_MECH, -1)
currNumBuiltTanks = #self:getUnitsByClass(UnitClass.TANK, -1)
currNumBuiltArtillery = #self:getUnitsByClass(UnitClass.ARTILLERY, -1)
currNumWarMechs = currNumBuiltWarMechs
currNumTanks = currNumBuiltTanks
currNumArtillery = currNumBuiltArtillery
currLandFactories = self:getUnitsByClass(UnitClass.LAND_FACTORY, -1)
for i = 1, #currLandFactories do
currNumWarMechs = currNumWarMechs + currLandFactories[i]:toFactory():getNumQueueUnitsById(0)
currNumTanks = currNumTanks + currLandFactories[i]:toFactory():getNumQueueUnitsById(1)
currNumArtillery = currNumArtillery + currLandFactories[i]:toFactory():getNumQueueUnitsById(2)
end
numWarMechs = self.numDefWarMechs + self.numTaskForceWarMechs
numTanks = self.numTaskForceTanks
numArtillery = self.numTaskForceArtillery
if currNumBuiltWarMechs >= numWarMechs and currNumBuiltTanks >= numTanks and currNumBuiltArtillery >= numArtillery then
return true
end
landFactory = currLandFactories[1]:toFactory()
self:buildTaskforceUnitGroup(numWarMechs, currNumWarMechs, landFactory, 0)
self:buildTaskforceUnitGroup(numTanks, currNumTanks, landFactory, 1)
self:buildTaskforceUnitGroup(numArtillery, currNumArtillery, landFactory, 2)
return false
end
function Player:enemiesCloseBy()
--if self.taskForceClearing then return true end
self:selectUnits(self:getUnitsByClass(UnitClass.WAR_MECH, self.numTaskForceWarMechs))
self:selectUnits(self:getUnitsByClass(UnitClass.TANK, self.numTaskForceTanks))
self:selectUnits(self:getUnitsByClass(UnitClass.ARTILLERY, self.numTaskForceArtillery))
taskForce = self:getSelectedUnits()
uns = {}
players = Game.getSingleton():getPlayers()
for i = 1, #players do
if players[i] == self or players[i]:getTeam() == self:getTeam() then goto continue end
un = players[i]:getUnits()
uns = table.move(un, 1, #un, #uns + 1, uns)
::continue::
end
targUnit = nil
for i = 1, #uns do
for j = 1, #taskForce do
if taskForce[j]:getPos():getDistanceFrom(uns[i]:getPos()) < taskForce[j]:getLineOfSight() then
targUnit = uns[i]
break
end
end
if targUnit then break end
end
if not self.taskForceClearing and targUnit then
print('clearing...')
self.taskForceClearing = true
self:deselectUnits()
self:selectUnits(taskForce)
self:issueOrder(2, Vector3:new(0, 0, 0), {Target:new(targUnit, Vector3:new(0, 0, 0))}, false)
elseif self.taskForceClearing and not targUnit then
print('clearing finished...')
self.taskForceClearing = false
end
return self.taskForceClearing
end
function Player:attackSpawnPoint()
if self.movingToHostileSpawnPoint then return true end
print('advancing')
taskForceMechs = self:getUnitsByClass(UnitClass.WAR_MECH, self.numTaskForceWarMechs)
taskForceTanks = self:getUnitsByClass(UnitClass.TANK, self.numTaskForceTanks)
taskForceArtillery = self:getUnitsByClass(UnitClass.ARTILLERY, self.numTaskForceArtillery)
self:deselectUnits()
self:selectUnits(taskForceMechs)
self:selectUnits(taskForceTanks)
self:selectUnits(taskForceArtillery)
taskForce = self:getSelectedUnits()
for i = 1, #taskForce do
taskForce[i]:setState(0)
end
map = Map.getSingleton()
numSpawnPoints = map:getNumSpawnPoints()
enemySpawnPoint = nil
players = Game.getSingleton():getPlayers()
for i = 1, numSpawnPoints do
if i - 1 ~= self:getSpawnPointId() then
enemySpawnPoint = map:getSpawnPoint(players[i]:getSpawnPointId())
break
end
end
self:issueOrder(2, Vector3:new(0, 0, 0), {Target:new(nil, enemySpawnPoint)}, false)
self.movingToHostileSpawnPoint = true
return true
end
Player.behaviour = {
type = BTNodeType.SEQUENCE,
children = {
{type = BTNodeType.FUNCTION, func = 'buildFort'},
{type = BTNodeType.FUNCTION, func = 'trainEngineers'},
--[[{
{type = BTNodeType.FUNCTION, func = 'buildExtractor'},
{type = BTNodeType.FUNCTION, func = 'buildRefinery'},
{type = BTNodeType.FUNCTION, func = 'buildLandFactory'},
{type = BTNodeType.FUNCTION, func = 'buildHarvester'},
{type = BTNodeType.FUNCTION, func = 'startHarvesting'},
{type = BTNodeType.FUNCTION, func = 'buildTaskforce'},
{
type = BTNodeType.SELECTOR,
children = {
{type = BTNodeType.FUNCTION, func = 'enemiesCloseBy'},
{type = BTNodeType.FUNCTION, func = 'attackSpawnPoint'}
}
},
type = BTNodeType.PARALLEL,
numMinSuccesses = 2,
children = {
{type = BTNodeType.FUNCTION, func = 'enemiesCloseBy'},
{type = BTNodeType.FUNCTION, func = 'attackSpawnPoint'}
}
},]]--
}
}