I'm trying to do a crude pirate behavior. Upon its creation, it selects a ship to attack. When the ship is destroyed, it loots the remains. After that, it heads to a jump point (e.g. stargate) to exit the system.
I tried to refer to the traget's wreck using the target's object ID. I get a crash at exactly that point. That object ID no longer seems valid after target is destroyed, when pirate's OnOrdersCompleted event is fired.
So what can I do now ? Is there any other way to find the wreck ? Or should I make the pirate ship listen to its target's events ? In that cas, how is that done ? Could anyone provide my with small hints ? Comprehensive explanation is not needed, just a direction to search further in. Thanks in advance ^-^
For now, I don't know if having my code could help as I think I've found the error, but can't see exactly what to use instead to achieve the desired effect. However, the code is the following :
Code: Select all
<?xml version="1.0" ?>
<!DOCTYPE TranscendenceExtension
[
<!ENTITY unidExtension "0xD4100006">
<!ENTITY scCaravellePirate "0xD4103005">
<!ENTITY rsCaravelleImage2 "0xD410F00B">
]
>
<TranscendenceExtension
UNID="&unidExtension;"
version="0.99c"
>
<!-- This is an addon to define pirate ships in the Hoshikaze 2250 universe.
ID notation
My Modder ID : 0xD410
Entity IDs : 0xD410TNNN
T : Type
0 Adventure/Extension
1 Stellar System Type
2 Station Type
3 Ship Class
F Resource String
NNN : Number in type
Includes :
- Pirate version of the Caravelle Freighter
-->
<!-- Pirate Caravelle Freighter
Data :
Status :
statusCreated Ship has just been created
statusAttacking Ship is spaceborne and on its way to its target
statusLooting Ship is docked with a wreck of its victim for a given amount of time
statusRetreating Ship is spaceborne and on its way to its exit jump point
Target
Ship The ship that is under attack from the pirate ship
Events :
OnCreate Ship sets a status marker
OnOrdersCompleted If ship has just been created
Ship waits for a very small amount of time (1 tick)
else (=has destroyed its target)
Ship loots its target
else (=has looted its target)
Ship flee through a jump point
OnTimerSetTarget Ship acquires a target and heads towards it
onTimerSetExitPoint Ship acquires a jump point, go to it and jumps out
The ship reuses one of the Caravelle Freighter graphics, with enhanced ship properties
-->
<ShipClass UNID="&scCaravellePirate;"
manufacturer= "Customized captured Freighter"
class= "Pirate Caravelle"
type= "pirate"
score= "540"
techOrder= "mech"
mass= "1500"
cargoSpace= "5000"
thrust= "1000"
maneuver= "20"
maxSpeed= "50"
canAttack= "true"
leavesWreck= "100"
attributes= "pirate,genericClass,hk2250"
>
<Armor>
<ArmorSection start="345" span="30" armorID="&itLightPlasteelPlate;" />
<ArmorSection start="315" span="30" armorID="&itLightPlasteelPlate;" nonCritial="general"/>
<ArmorSection start="285" span="30" armorID="&itLightPlasteelPlate;" nonCritial="general"/>
<ArmorSection start="255" span="30" armorID="&itLightPlasteelPlate;" nonCritial="general"/>
<ArmorSection start="225" span="30" armorID="&itLightPlasteelPlate;" nonCritial="general"/>
<ArmorSection start="195" span="30" armorID="&itLightPlasteelPlate;" />
<ArmorSection start="165" span="30" armorID="&itLightPlasteelPlate;" />
<ArmorSection start="135" span="30" armorID="&itLightPlasteelPlate;" />
<ArmorSection start="105" span="30" armorID="&itLightPlasteelPlate;" nonCritial="general"/>
<ArmorSection start="75" span="30" armorID="&itLightPlasteelPlate;" nonCritial="general"/>
<ArmorSection start="45" span="30" armorID="&itLightPlasteelPlate;" nonCritial="general"/>
<ArmorSection start="15" span="30" armorID="&itLightPlasteelPlate;" nonCritial="general"/>
</Armor>
<Devices>
<Device deviceID="&itDualLaserCannon;" omnidirectional="true"/>
<Device deviceID="&itNAMIMissileLauncher;" omnidirectional="true"/>
<Device deviceID="&itHullPlateIonizer;"/>
</Devices>
<Items>
<Item count="5d3" item="&itKM500Missile;"/>
</Items>
<Image imageID="&rsCaravelleImage2;" imageX="0" imageY="0" imageWidth="128" imageHeight="128"/>
<Names noArticle="true">
Rônin Azuka; Renegade Dragon; Jade Blow;
</Names>
<AISettings
fireRateAdj= "60"
fireAccuracy= "90"
perception= "10"
combatStyle= "standOff"
/>
<Events>
<onCreate>
(block Nil
(socPirateOnCreate gSource)
)
</onCreate>
<OnOrdersCompleted>
(block Nil
(socPirateOnOrdersCompleted gSource)
)
</OnOrdersCompleted>
<OnTimerSetTarget>
(block Nil
(socPirateOnTimerSetTarget gSource)
)
</OnTimerSetTarget>
<OnTimerSetExitPoint>
(block Nil
(socPirateOnTimerSetExitPoint gSource)
)
</OnTimerSetExitPoint>
</Events>
<Communications>
<Message name="Status" key="S">
(socPirateSendStatusMessage gSender gSource)
</Message>
</Communications>
</ShipClass>
<Globals>
<!-- Single block Nil for enclosing all the defines -->
(block Nil
<!--
socPirateOnCreate
When ?
Called by OnCreate Event on pirate ships
What ?
Only initialize ship status
-->
(setq socPirateOnCreate
<!-- Function definition with arguments list -->
(lambda (sourceShip)
<!-- Function code itself : begin -->
(block (message oldStatus newStatus)
; Set variables
(setq oldStatus (objGetData sourceShip "status"))
(setq newStatus "statusCreated")
; Set status data
(objSetData sourceShip "status" newStatus)
)
<!-- Function code itself : end -->
)
)
<!-- Function end -->
<!--
socPirateOnOrdersCompleted
When ?
Called by OnOrdersCompleted Event on pirate ships
What ?
Update ship status
If statusCreated, chooses a target and attack
If statusAttacking, then attack was successful, go to the wreck and loot it
If statusLooting, looting time is ended, begin to retreat
-->
(setq socPirateOnOrdersCompleted
(lambda (sourceShip)
<!-- Function code itself : begin -->
(block (message oldStatus newStatus)
; Log beginning of event
(setq message (cat "Pirate Ship " (objGetName sourceShip) " #" sourceShip " : Entering OnOrdersCompleted event"))
(dbgLog message)
; Set variables
(setq oldStatus (objGetData sourceShip "status"))
; Log current status
(setq message (cat "Pirate Ship " (objGetName sourceShip) " #" sourceShip " : Old status : " oldStatus))
(dbgLog message)
; Compute new status from old
(switch
(eq oldStatus "statusCreated")
(block (timeWait)
; Set variables
(setq newStatus "statusAttacking")
(setq timeWait 1)
; Activate timer for next orders and actually set ship status
(sysAddObjTimerEvent timeWait sourceShip "OnTimerSetTarget")
(objSetData sourceShip "status" newStatus)
)
(eq oldStatus "statusAttacking")
(block (theTarget)
; Set variables
(setq newStatus "statusLooting")
(setq theTarget (objGetData sourceShip "target"))
; Log target
(setq message (cat "Pirate Ship " (objGetName sourceShip) " #" sourceShip " : Target destroyed"))
(dbgLog message)
; Log target
(setq message (cat "Pirate Ship " (objGetName sourceShip) " #" sourceShip " : Target : " (objGetName theTarget)))
(dbgLog message)
; Set orders to loot destroyed target and set new status
(shpCancelOrders sourceShip)
(shpOrderLoot sourceShip theTarget)
(objSetData sourceShip "status" newStatus)
)
)
; Log end of event
(setq message (cat "Pirate Ship " (objGetName sourceShip) " #" sourceShip " : Exiting OnOrdersCompleted event"))
(dbgLog message)
)
<!-- Function code itself : end -->
)
)
<!-- Function end -->
<!--
socPirateOnTimerSetTarget
When ?
Called by OnTimerSetTarget Event on pirate ships
What ?
Update ship status
Choose a random target among ships
-->
(setq socPirateOnTimerSetTarget
(lambda (sourceShip)
<!-- Function code itself : begin -->
(block (message oldStatus newStatus nextTarget targetsList)
; Log beginning of event
(setq message (cat "Pirate Ship " (objGetName sourceShip) " #" sourceShip " : Entering OnTimerSetTarget event"))
(dbgLog message)
; Set variables
(setq oldStatus (objGetData sourceShip "status"))
(setq newStatus "statusAttacking")
; Log old status
(setq message (cat "Pirate Ship " (objGetName sourceShip) " #" sourceShip " : Status : " oldStatus))
(dbgLog message)
; Find next target, can include player ship
(setq targetsList (sysFindObject sourceShip "s"))
(setq nextTarget (random targetsList))
; Log selected target
(setq message (cat "Pirate Ship " (objGetName sourceShip) " #" sourceShip " : targetting " (objGetName nextTarget)))
(dbgLog message)
; Store new target into ship data
(objSetData sourceShip "target" nextTarget)
; Set new orders and actually change status
(shpCancelOrders sourceShip)
(shpOrderAttack sourceShip nextTarget)
(objSetData sourceShip "status" newStatus)
; Log end of event
(setq message (cat "Pirate Ship " (objGetName sourceShip) " #" sourceShip " : Exiting OnTimerSetTarget event"))
(dbgLog message)
)
<!-- Function code itself : end -->
)
)
<!-- Function end -->
<!--
socPirateOnTimerSetExitPoint
When ?
Called when a pirate ship has killed and looted its target
What ?
Select a jump point and order outbound jump
-->
(setq socPirateOnTimerSetExitPoint
(lambda (sourceShip)
<!-- Function code itself : begin -->
(block (message oldStatus newStatus nextWaypoint waypointsList)
; Log beginning of event
(setq message (cat "Pirate Ship " (objGetName sourceShip) " #" sourceShip " : Entering OnTimerSetExitPoint event"))
(dbgLog message)
; Set variables
(setq oldStatus (objGetData sourceShip "status"))
; Log status
(setq message (cat "Pirate Ship " (objGetName sourceShip) " #" sourceShip " : Status : " oldStatus))
(dbgLog message)
; Log end of event
(setq message (cat "Pirate Ship " (objGetName sourceShip) " #" sourceShip " : Exiting OnTimerSetExitPoint event"))
(dbgLog message)
)
<!-- Function code itself : end -->
)
)
<!-- Function end -->
<!--
socPirateSendStatus
When ?
Called by the communication message "Status Request"
What ?
Sends a status message to the player
-->
(setq socPirateSendStatusMessage
(lambda (questionningShip answeringShip target status)
<!-- Function code itself : begin -->
(block (message)
; Log beginning of event
;(setq message (cat "Pirate Ship " (objGetName answeringShip) " #" answeringShip " : Entering SendStatusMessage communication"))
;(dbgLog message)
; Get info from the ship
(setq status (objGetData answeringShip "status"))
(setq target (objGetData answeringShip "target"))
(if (eq status "statusAttacking")
; Ship is attacking a target
(setq message (cat "Pirate Ship " (objGetName answeringShip) " #" answeringShip " attacking " (objGetName target)))
)
; Sending identity and destination
(objSendMessage questionningShip answeringShip message)
; Log end of event
;(setq message (cat "Pirate Ship " (objGetName answeringShip) " #" answeringShip " : Exiting SendStatusMessage communication"))
;(dbgLog message)
)
<!-- Function code itself : end -->
)
)
<!-- Function end -->
<!--
socPiratesRandomClass
When ?
Called by any script to get a random class for creating a new pirate
Eliminates the need to declare pirate classes on other files
What ?
Return a random class among existing SoC Pirates
-->
(setq socPiratesRandomClass
(lambda Nil
<!-- Function code itself : begin -->
(random '(&scCaravellePirate;))
<!-- Function code itself : end -->
)
)
<!-- Function end -->
)
</Globals>
</TranscendenceExtension>