"companion drone" type units?

"companion drone" type units?

Discuss game development here, from a distinct game project to an accessible third-party mutator, down to the interaction and design of individual units if you like.

Moderator: Moderators

Post Reply
yanom
Posts: 323
Joined: 10 Jul 2009, 23:34

"companion drone" type units?

Post by yanom »

So I have this one flying drone unit with pre-programmed unitdef/attack patterns/behavior/everything, and currently it's built either the boring old way in a factory, or built on the battlefield by a constructor (ever played ZeroK? think about how the Athena builds things).

But then i've also got this second unit, a large assault walker, and I want to set it up so that each walker has a "swarm" of 20 or so of these things that it maintains, and when one of the 20 is destroyed, the walker produces and launches another one for free (ever played ZeroK? think about the Companion Drone for the commander. Like that).

I don't want the drones constricted to within a certain distance of the walker, like the companion drones are in ZK. The "swarm" of 20 doesn't have to stay together as a single pack either, I just want them buzzing around the map, doing what they already do.

How do I set this up?
User avatar
Beherith
Posts: 5145
Joined: 26 Oct 2007, 16:21

Re: "companion drone" type units?

Post by Beherith »

Look at the carrier in ZK.
User avatar
FLOZi
MC: Legacy & Spring 1944 Developer
Posts: 6242
Joined: 29 Apr 2005, 01:14

Re: "companion drone" type units?

Post by FLOZi »

Or the drones in THIS.
yanom
Posts: 323
Joined: 10 Jul 2009, 23:34

Re: "companion drone" type units?

Post by yanom »

Beherith wrote:Look at the carrier in ZK.
found the unitdef. What am I looking for here?

Edit: I found a few lua scripts that appear to operate the drones: unit_carrier_drones.lua and drone_defs.lua
User avatar
Beherith
Posts: 5145
Joined: 26 Oct 2007, 16:21

Re: "companion drone" type units?

Post by Beherith »

Yep those are it. You will have to read the code and modify things to your needs. If you get stuck, I recommend asking in #zkdev, those guys are really nice and helpful.
yanom
Posts: 323
Joined: 10 Jul 2009, 23:34

Re: "companion drone" type units?

Post by yanom »

FLOZi wrote:Or the drones in THIS.
whatever happened to THIS?

anyway, now I've got a second problem. I've got the lua gadget:

Code: Select all

-- $Id: unit_carrier_drones.lua 3291 2008-11-25 00:36:20Z licho $
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
--  file:    unit_carrier_drones.lua
--  brief:   Spawns drones for aircraft carriers
--  author:  
--
--  Copyright (C) 2007.
--  Licensed under the terms of the GNU GPL, v2 or later.
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

function gadget:GetInfo()
  return {
    name      = "CarrierDrones",
    desc      = "Spawns drones for aircraft carriers",
    author    = "TheFatConroller, modified by KingRaptor",
    date      = "12.01.2008",
    license   = "GNU GPL, v2 or later",
    layer     = 0,
    enabled   = true  --  loaded by default?
  }
end

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

-- SYNCED CODE
if (not gadgetHandler:IsSyncedCode()) then
  return
end


--Speed-ups

local GetUnitPosition   = Spring.GetUnitPosition
local CreateUnit        = Spring.CreateUnit
local AddUnitDamage     = Spring.AddUnitDamage
local GiveOrderToUnit   = Spring.GiveOrderToUnit
local GetCommandQueue   = Spring.GetCommandQueue
local SetUnitPosition   = Spring.SetUnitPosition
local SetUnitNoSelect   = Spring.SetUnitNoSelect
local random            = math.random
local CMD_ATTACK                = CMD.ATTACK

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

local carrierDefs = include "LuaRules/Configs/drone_defs.lua"

local DEFAULT_UPDATE_ORDER_FREQUENCY = 60       -- gameframes
local DEFAULT_MAX_DRONE_RANGE = 1500

local carrierList = {}
local droneList = {}

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

local function InitCarrier(unitDefID, unitAllyID)
        local carrierData = carrierDefs[unitDefID]
        return {unitDefID = unitDefID, unitAllyID = unitAllyID, droneCount = 0, reload = carrierData.reloadTime, drones = {}, managed=carrierData.managed}
end

local function NewDrone(unitID, unitDefID, droneName)
  local x, y, z = GetUnitPosition(unitID)
  local angle = math.rad(random(1,360))
  local xS = (x + (math.sin(angle) * 20))
  local zS = (z + (math.cos(angle) * 20))
  local droneID = CreateUnit(droneName,x,y,z,1,carrierList[unitID].unitAllyID)
  carrierList[unitID].reload = carrierDefs[unitDefID].reloadTime
  carrierList[unitID].droneCount = (carrierList[unitID].droneCount + 1)
  carrierList[unitID].drones[droneID] = true
 
  SetUnitPosition(droneID, xS, zS, true)
  GiveOrderToUnit(droneID, CMD.MOVE_STATE, { 2 }, {})
  GiveOrderToUnit(droneID, CMD.IDLEMODE, { 0 }, {})
  if(carrierList[unitID].managed==true) then
    --GiveOrderToUnit(droneID, CMD.AUTOREPAIRLEVEL, { 3 }, {})
    --GiveOrderToUnit(droneID, CMD.FIGHT,  {(x + (random(0,600) - 300)), 60, (z + (random(0,600) - 300))}, {""})
    GiveOrderToUnit(droneID, CMD.GUARD, {unitID} , {"shift"})
  end
  SetUnitNoSelect(droneID,true)
 
  droneList[droneID] = unitID
end

function gadget:UnitDestroyed(unitID, unitDefID, unitTeam)
  if (carrierList[unitID]) then
    for droneID in pairs(carrierList[unitID].drones) do
                droneList[droneID] = nil
                AddUnitDamage(droneID,1000)
    end
    carrierList[unitID] = nil
  elseif (droneList[unitID]) then
    local i = droneList[unitID]
        carrierList[i].droneCount = (carrierList[i].droneCount - 1)
        carrierList[i].drones[unitID] = nil
        droneList[unitID] = nil
  end
end

function gadget:UnitFinished(unitID, unitDefID, unitTeam)
  if (carrierDefs[unitDefID]) then
    carrierList[unitID] = InitCarrier(unitDefID, unitTeam)
  end
end

function gadget:AllowUnitTransfer(unitID, unitDefID, oldTeam, newTeam, capture)
  if (droneList[unitID]) then
        if capture then
                gadget:UnitDestroyed(unitID, unitDefID, oldTeam)
                return true
        end
    return false
  else
    if (carrierList[unitID] ~= nil) then
      gadget:UnitDestroyed(unitID, unitDefID, oldTeam)
      gadget:UnitFinished(unitID, unitDefID, newTeam)
    end    
    return true
  end
end

local function GetDistance(x1, x2, y1, y2)
        return ((x1-x2)^2 + (y1-y2)^2)^0.5
end



function gadget:AllowCommand(unitID, unitDefID, teamID, cmdID, cmdParams, cmdOptions)
  --[[for i,v in pairs(carrierList) do
	--Spring.Echo(carrierList[i].managed)
	if(carrierList[i].managed==true) then --if we find the unit in here, return false
		--Spring.Echo(carrierList[i].managed)
		if(carrierList[i].drones[unitID]==true) then
			return false
		end
	end
  end]]
  return true --modified it so that it will allow drones to be controlled by other scripts
end


function gadget:UnitCommand(unitID, unitDefID, teamID, cmdID, cmdParams, cmdOptions)
        if (carrierList[unitID]) then
			if (carrierList[unitID].managed) then
				UpdateCarrierTarget(unitID)
            end
        end
end


function gadget:GameFrame(n)
  if (((n+1) % 30) < 0.1) then
    for i,_ in pairs(carrierList) do
          local carrier = carrierList[i]
          local carrierDef = carrierDefs[carrier.unitDefID]
      if (carrier.reload > 0) then
        carrier.reload = (carrier.reload - 1)
      elseif (carrier.droneCount < carrierDef.maxDrones) then
                for n=1,carrierDef.spawnSize do
                        if (carrier.droneCount >= carrierDef.maxDrones) then
                                break
                        end
                        NewDrone(i, carrier.unitDefID, carrierDef.drone)
        end
      end
    end
  end
  if ((n % DEFAULT_UPDATE_ORDER_FREQUENCY) < 0.1) then
        for i,_ in pairs(carrierList) do
			if (carrierList[i].managed==true) then
				UpdateCarrierTarget(i)
			end
        end
  end
end

function UpdateCarrierTarget(carrierID)
		--Spring.Echo("updating carrier target!")
        local cQueueC = GetCommandQueue(carrierID, 1)
        if cQueueC and cQueueC[1] and cQueueC[1].id == CMD_ATTACK then
                local ox,oy,oz = GetUnitPosition(carrierID)
                local params = cQueueC[1].params
                local px,py,pz
                if #params == 1 then
                        px,py,pz = Spring.GetUnitPosition(params[1])
                else
                        px,py,pz = unpack(params)
                end
                if not px then return end
                -- check range
                local dist = GetDistance(ox,px,oz,pz)
                if dist > carrierDefs[carrierList[carrierID].unitDefID].range then
                        return
                end
               
                for droneID in pairs(carrierList[carrierID].drones) do
                        --[[
                        local cQueue = GetCommandQueue(droneID, 1)
                        local engaged = false
                        if cQueue and cQueue[1] and cQueue[1].id == CMD_ATTACK then
                                engaged = true
                        end
                        ]]--
                        --if not engaged then
                                --Spring.Echo("Ordering drone " .. droneID .. " to attack")
                                droneList[droneID] = nil        -- to keep AllowCommand from blocking the order
                                GiveOrderToUnit(droneID, CMD.FIGHT, {(px + (random(0,200) - 100)), (py+120), (pz + (random(0,200) - 100))} , {""})
                                GiveOrderToUnit(droneID, CMD.GUARD, {carrierID} , {"shift"})
                                droneList[droneID] = carrierID
                        --end
                end
        else
                for droneID in pairs(carrierList[carrierID].drones) do
                        local cQueue = GetCommandQueue(droneID)
                        local engaged = false
                        for i=1, (cQueue and #cQueue or 0) do
                                if cQueue[i].id == CMD.FIGHT then
                                        engaged = true
                                        break
                                end
                        end
                        if not engaged then
                                local px,py,pz = GetUnitPosition(carrierID)
                                droneList[droneID] = nil        -- to keep AllowCommand from blocking the order
                                GiveOrderToUnit(droneID, CMD.FIGHT, {(px + (random(0,200) - 100)), (py+120), (pz + (random(0,200) - 100))} , {""})
                                GiveOrderToUnit(droneID, CMD.GUARD, {carrierID} , {"shift"})
                                droneList[droneID] = carrierID
                        end
                end    
        end
end

--[[
function gadget:Initialize()
        for udid,data in pairs(carrierDefs) do
                if data.weapon then
                        Script.SetWatchWeapon(WeaponDefNames[data.weapon].id)
                end
        end
end

]]
[code]
and it feeds from this config datafile:
[code]
local carrierDefs = {}

local carrierDefNames = {
        --armcarry = {drone = UnitDefNames.carrydrone.id, reloadTime = 15, maxDrones = 8, spawnSize = 2, range = 1600}, -- this line was from Zero-K
        lengineer = {drone = UnitDefNames.kdroneminerflyer.id, reloadTime = 15, maxDrones = 6, spawnSize = 1, range = 1600, managed=false},
        lbigwalker = {drone = UnitDefNames.lwarrior.id, reloadTime = 10, maxDrones = 6, spawnSize = 2, range = 10, managed=true},
}

for name, data in pairs(carrierDefNames) do
        if UnitDefNames[name] then carrierDefs[UnitDefNames[name].id] = data    end
end

return carrierDefs
But that current setup only accepts 1 swarm of 1 drone type per carrier/"host" unit. And I've been wanting to make it possible for one carrier to have two different swarms, each with a different drone type. Has anyone done this before? Or can someone with more Lua skill than me take a crack at this and tell me how to fix?
Post Reply

Return to “Game Development”