How to use shpOrderLoot ?

Freeform discussion about anything related to modding Transcendence.
Post Reply
User avatar
Mutos
Militia Lieutenant
Militia Lieutenant
Posts: 218
Joined: Thu Aug 14, 2008 3:31 am
Location: Near Paris, France
Contact:

Sat Oct 18, 2008 6:45 am

Hi all,


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>
@+

Benoît 'Mutos' ROBIN
Hoshikaze 2250 Project

Apemant
Commonwealth Pilot
Commonwealth Pilot
Posts: 94
Joined: Mon Dec 03, 2007 12:51 pm

Sat Oct 18, 2008 3:06 pm

Mutos wrote:I tried to refer to the traget's wreck using the target's object ID.
... which is why it doesn't work, because shipwrecks have nothing to do with ships.

Ships are <ShipClass> whereas shipwrecks are <StationType>. Neither their UNIDs nor their pointers are the same. When you destroy a ship, it's gone - it gets replaced by the appropriate station (shipwreck). You could get that wreck with sysfindObject - but as of 0.99, <OnDestroy> event on ships gets the 'aWreckObj' global variable which is a pointer (handle) to the resulting wreck (if any).

Of course, that's perhaps not that cool because it is an event from the destroyed ship class, and not the pirate... so you can't use it in a 'clean' way... except if you have <OnDestroy> event handlers on ALL ship types and somehow expose that aWreckObj to whoever might need it. Anyway, it would be kinda clumsy.

Another way it to just sysFindObject - but then you wouldn't be sure you got the right wreck. :?

User avatar
Bobby
Militia Captain
Militia Captain
Posts: 675
Joined: Wed Jul 25, 2007 7:39 pm

Sat Oct 18, 2008 6:01 pm

you could plant an item on the target ship, then when the ship is destroyed, it should be on the wreck.

find the wreck with that item and you have the right wreck.

sure it's not the best way, but dsLoot could be changed to hide the item, OR it could be a virtual item.

to avoid pirates confusing wrecks with other pirate's target's wrecks you could have them track the position of the target ship, and search for wrecks close to there. or perhaps randomly change some attribute of the item to lock on to.

User avatar
Mutos
Militia Lieutenant
Militia Lieutenant
Posts: 218
Joined: Thu Aug 14, 2008 3:31 am
Location: Near Paris, France
Contact:

Sat Oct 18, 2008 6:23 pm

Hi all,


Thanks Apemant and Bobby for your answers. It leaves a number of ways open, but neither seems that easy...

I think I'll try the event way. It seems to me the cleaner. I'll try to have the pirate register on its target's events, so as to trap its OnDestroy event. Then I'll add an OnDestroy event handler on the pirate, that will see if the destroyed ship is its target and get the correct wreck from the event. I'll let you know if it works...

I would like to known if the target ship needs to have an OnDestroy event handler too ? I have other pending questions, but Xelerus and some source should be enough. Otherwise I'll post back there...
@+

Benoît 'Mutos' ROBIN
Hoshikaze 2250 Project

F50
Militia Captain
Militia Captain
Posts: 995
Joined: Sat Mar 11, 2006 5:25 pm

Sun Oct 19, 2008 1:07 am

Intresting idea mutos...

If you register the target for events with the pirate, then you may be able to use <OnObjDestroyed> (not OnDestroy, OnDestroy will only run if the pirate is destroyed) which may return aWrekObj. I'm not entirely sure that you can put those functions on a ship, similar to the way that you can't put <OnAttackedByPlayer> on ships.

If that doesn't work, do try the item planting. It souldn't be that hard to do. Create an item with "virtual = "true"", that means that the player can never see it. Then add the item to the target ship (one function, possibly wtih a nested one inside), then when the object is destroyed (when (objGetTarget gSource) does not equal the target that you want it to loot), do (sysfindobj gSource "s") and then use enum and/or filter to find the nearest object that contains the virtual item. Using the nearest such object should prevent pirates looting the wrong ship. You might also be able to use (sysfindobj target "sN:20") and just use the first object with the item.

Alternatively you could place the <OnDestroy> event on all possible targets, but then you would need to save reference data on the target ships and in <OnDestroy> check to see if the reference data exists and then set reference data on the pirate ship pointing to the wreak, so the <OnDestroy> function might not be so easy (I don't know how to safely check to see if certain data exists).

Hope this helps

User avatar
Mutos
Militia Lieutenant
Militia Lieutenant
Posts: 218
Joined: Thu Aug 14, 2008 3:31 am
Location: Near Paris, France
Contact:

Sun Oct 19, 2008 6:50 am

Hi all,


Thanks for the help, I finally got the code working with the events method, getting inspiration from CharonPirates.XML.

It's quite a straightforward and primitive behavior for now.
- When ship is created, it selects a random ship and attacks it,
- When its target is destroyed, it gets the wreck and loots it,
- When looting is over, it retreats through a random jump point.

It also has some bugs, for instance on ship properties balance, often leading to the pirate needing dozens of approach runs to dock to something.

However, no point for now... I'll add balance, subtlety and randomness later. For now I'm only building the base bricks...

Code involves a ShipClass with events and communications to test the ship's status, and a Global section that holds all the code. It uses my Stars of Call resources as images, apart from that, you can reuse it. It 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
				"targetToAttack"
					Ship					The ship that is under attack from the pirate ship
				"targetToLoot"
					Wreck Object			The wreck of the destroyed target 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
				OnObjDestroyed			Uses when the target ship has been destroyed
			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=			"10"
			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>
			<OnObjDestroyed>
				(block Nil
					; On this event, gSource is the listening ship, here the pirate
					(socPirateOnObjDestroyed gSource aObjDestroyed aWreckObj)
				)
			</OnObjDestroyed>
		</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)
						; Set variables
						(setq oldStatus (objGetData sourceShip "status"))

						; Compute new status from old
						(switch
							(eq oldStatus "statusCreated")
								(block (timeWait)
									; Set variables
									(setq newStatus "statusAttacking")
                		            (setq timeWait 1)

									; Activate timer for selecting a target and actually set ship status
									(sysAddObjTimerEvent timeWait sourceShip "OnTimerSetTarget")
									(objSetData sourceShip "status" newStatus)
                		        )
							(eq oldStatus "statusLooting")
								(block Nil
									; Set variables
									(setq newStatus "statusRetreating")
                		            (setq timeWait 1)

									; Activate timer for selecting a target and actually set ship status
									(sysAddObjTimerEvent timeWait sourceShip "OnTimerSetExitPoint")
									(objSetData sourceShip "status" newStatus)
                		        )
						)
					)
					<!-- 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 nextTarget targetsList)
						; Set variables
						(setq oldStatus (objGetData sourceShip "status"))

						; Find next target, can include player ship

						(setq targetsList (sysFindObject sourceShip "s"))
						(setq nextTarget (random targetsList))

						; Store new target into ship data
						(objSetData sourceShip "targetToAttack" nextTarget)

						; Set new orders, actually change the status and listen to the target's events
						(shpCancelOrders sourceShip)
						(shpOrderAttack sourceShip nextTarget)
						(objRegisterForEvents sourceShip nextTarget)
					)
					<!-- 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 nextWaypoint waypointsList)
						; Set variables
						(setq oldStatus (objGetData sourceShip "status"))

						; Find an exit jump point
						(setq waypointsList (sysFindObject sourceShip "G"))
						(setq nextWaypoint (random waypointsList))

						; Erase target and loot data
						(objSetData sourceShip "targetToLoot" Nil)
						(objSetData sourceShip "targetToAttack" Nil)

						; Set new orders
						(shpCancelOrders sourceShip)
						(shpOrderGate sourceShip nextWaypoint)
						(objSetData sourceShip "jumpPoint" nextWaypoint)
					)
					<!-- Function code itself : end -->
				)
			)
			<!-- Function end -->

			<!--
				socPiratesRandomClass
					When ?
						Called when the pirate's target is destroyed
					What ?
						Allow the pirate ship to locate and loot the wreck
			-->
			(setq socPirateOnObjDestroyed
				(lambda (pirateShip targetShip objWreck)
					<!-- Function code itself : begin -->
					(block (message)
						; If target ship got destroyed, dock with its wreck
						(eq targetShip (objGetData pirateShip "targetToAttack")
							(block Nil
								(if objWreck
									; If we have a wreck, dock with it
									(block Nil
										; Set variables on the pirate ship
										(objSetData pirateShip "status" "statusLooting")
										(objSetData pirateShip "targetToAttack" Nil)
										(objSetData pirateShip "targetToLoot" aWreckObj)

										; Reorder the pirate ship to loot the wreck
										(shpCancelOrders pirateShip)
										(shpOrderLoot pirateShip objWreck)
									)

									; Otherwise, select a new target
									(block Nil
										; Set pirate ship status to attack
										(objSetData pirateShip "status" "statusAttacking")

										; Activate timer for selecting a new target
										(sysAddObjTimerEvent 1 pirateShip "OnTimerSetTarget")
									)
								)
							)
						)
					)
					<!-- 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)
					<!-- Function code itself : begin -->
					(block (message status targetToAttack targetToLoot jumpPoint)
						; Get info from the ship
						(setq status (objGetData answeringShip "status"))
						(setq targetToAttack (objGetName (objGetData answeringShip "targetToAttack")))
						(setq targetToLoot (objGetName (objGetData answeringShip "targetToLoot")))
						(setq jumpPoint (objGetName (objGetData answeringShip "jumpPoint")))

						(switch
							(eq status "statusCreated")
								(block Nil
									; Ship has just been created
									(setq message (cat "Pirate Ship " (objGetName answeringShip) " #" answeringShip " has just been created"))
								)
							(eq status "statusAttacking")
								(block Nil
									; Ship is attacking a target
									(setq message (cat "Pirate Ship " (objGetName answeringShip) " #" answeringShip " attacking " targetToAttack))
								)
							(eq status "statusLooting")
								(block Nil
									; Ship is looting a wreck
									(setq message (cat "Pirate Ship " (objGetName answeringShip) " #" answeringShip " looting " targetToLoot))
								)
							(eq status "statusRetreating")
								(block Nil
									; Ship is retreating to a jump point
									(setq message (cat "Pirate Ship " (objGetName answeringShip) " #" answeringShip " retreating to " jumpPoint))
								)
						)

						; Sending identity and destination
						(objSendMessage questionningShip answeringShip 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>
@+

Benoît 'Mutos' ROBIN
Hoshikaze 2250 Project

F50
Militia Captain
Militia Captain
Posts: 995
Joined: Sat Mar 11, 2006 5:25 pm

Sun Oct 19, 2008 7:11 pm

nice see that <OnObjDestroyed> works, I'll make sure to keep that in mind for later.

Post Reply