Cowardly Ships
From FreeSpace Wiki
I found a need to have ships evade their attackers rather than fly on without responding to incoming fire. Probably an edge case! Could be useful for making escape pods harder to shoot down (or conversely easier to escort?)
NOTE: I need to fix this by removing the for-loop searches for the ship name and replace with mn.Ships[NAME] & isValid() check (where it doesn't already exist).
#Conditional Hooks $Application: FS2_Open $On Game Init: [ OD = {} function OD:Init() --[[ allow sexps to set order state; i.e. evade to start with if ship has state set; and was hit/attacked set goal (e.g. ai-evade-ship its attacker) after goal Duration has elapsed, remove goal ]]-- self.ShipList = {} self.Duration = 9 self.CheckInterval = 1 self.LastRun = 0 self.addKey = "9" self.delKey = "0" self.DEBUG = true end function OD:wasAttacked(ship,weapon) if ship:isValid() then local numShips = #self.ShipList for i=1, numShips do if ship.Name == self.ShipList[i].Name then curTime = mn.getMissionTime() if self.ShipList[i].Time < curTime then self.ShipList[i].Time = curTime + OD.Duration if self.DEBUG then local numOrders = #ship.Orders for i=1, numOrders do ba.warning(tostring(ship.Orders[i]:getType())) ba.warning(ship.Orders[i].Priority) end end if weapon.Parent:isValid() then ship:giveOrder(ORDER_EVADE,weapon.Parent,nil,1.0) end end end end end end function OD:evalRemove() now = mn.getMissionTime() if self.LastRun + self.CheckInterval < now then self.LastRun = now local numShips = #self.ShipList for i=1, numShips do if self.ShipList[i].Time < now then OD:removeOrder(self.ShipList[i]) end end end end function OD:removeOrder(item) local ship = mn.getObjectFromSignature(item.sig) if not ship:isValid() then return end if not ship.Orders:isValid() then return end local numOrders = #ship.Orders for i=1, numOrders do if tostring(ship.Orders[i]:getType()) == item.Order then ship.Orders[i]:remove() end end end function OD:as(shipname,order) -- addShip to ShipList local allships = #mn.Ships for i=1, allships do if mn.Ships[i].Name == shipname then local tmp = {} tmp.Name = mn.Ships[i].Name tmp.sig = mn.Ships[i]:getSignature() tmp.Time = 0 tmp.Order = OD:OrderLookup(order) self.ShipList[#self.ShipList+1] = tmp break end end if self.DEBUG then ba.warning('ran OD:as') end end function OD:ds(shipname,order) -- deleteShip from ShipList -- also remove the order if its active local ships = #self.ShipList for i=1, ships do if self.ShipList[i].Name == shipname then if self.ShipList[i].Order == OD:OrderLookup(order) then OD:removeOrder(self.ShipList[i]) table.remove(self.ShipList,i) break end end end if self.DEBUG then ba.warning('ran OD:ds') end end function OD:OrderLookup(order) if order == 'evade' then return 'ORDER_EVADE' else return 'UNKNOWN' end end ] $On Gameplay Start: [ OD:Init() ] $Object Type: Weapon $On Ship Collision: [ -- do not treat ramming as an attack OD:wasAttacked(hv.Object,hv.Weapon) ] $State: GS_STATE_GAME_PLAY $On Key Released: [ if OD.DEBUG then local shipname = "Glich" -- testing only local order = 'evade' if hv.Key == OD.addKey then OD:as(shipname,order) elseif hv.Key == OD.delKey then OD:ds(shipname,order) end end ] $State: GS_STATE_GAME_PLAY $On Frame: [ OD:evalRemove() ] #End