ship orders help please

Freeform discussion about anything related to modding Transcendence.
Post Reply
relanat
Militia Captain
Militia Captain
Posts: 941
Joined: Tue Nov 05, 2013 9:56 am

The EI Freighter Auton mod lets the player buy up to 2 EI freighters which can be controlled as autons.

I would like to add a 'loot' feature where the autons will dock at every wreck or container within 50 or 100 ls and collect any items in the wreck. This will also use the new 'explored' property to change the color of the wreck in the LRS.
Creating a list of objects to loot is no problem. But I'm struggling with ship orders. Simple ones like "Form up" and "Wait" are easy.

This code (based on PSD code, ty PM) sorta works, the auton will sequentially dock with each wreck, but the color change happens instantly to all wrecks in the list on giving the 'Loot' command.

Code: Select all

(block Nil
	(objSetData gSource 'behavior 'looting)
	(objSendMessage gSender gSource "Looting")
	(enum finalList list
		(block Nil
			(shpOrder gSource 'dock list)
			(objSetProperty list 'explored True)
		)
	)
	(shpOrder gSource 'escort gPlayership (objGetData gSource 'formAngle))
)
From what I can determine ATM there would need to be a sequence where the auton flew to a wreck and docked with it. When it docked the wreck color would change and all the items would be moved from the wreck to the auton. There would need to be a check for cargo space which I believe would need to be done per item before it was extracted from the wreck (although a quick check for all items mass vs cargo space could be used to see if everything will fit). Object data would also be added to the wreck to prevent it from being looted again and again. Ideally this data would clear on system exit.
Then the auton would fly to the next wreck and repeat until either all the wrecks within the given distance were looted or the auton was full.

Any tips on how to do this? Would there need to be separate Events for travelling to the wreck, a sort of <WhenDocked> event on docking with it and changing the color, another for the procedural looting, then again for the travel to the next wreck, if any? I'm not sure why the 'explored' code is running all at once before the auton reaches the wreck.

Additionally it would be good if both autons could be looting at the same time, but not the same wrecks. I think this would just involve splitting the list unless there is some other way?
Stupid code. Do what I want, not what I typed in!
User avatar
AssumedPseudonym
Fleet Officer
Fleet Officer
Posts: 1190
Joined: Thu Aug 29, 2013 5:18 am
Location: On the other side of the screen.

 Code inside an event all runs at the same time. I can see what it’s doing here. Basically, it’s running the whole enum on finalList, creating a big stack of orders for the auton to go through, and marking them as explored. What you’d need for the effect you’re going for is probably a lambda (to simplify things) and an <OnOrdersCompleted> event, to have each item on finalList run separately.

 Pseudocode version, because I’m not going to try coding before caffeinating:

Code: Select all

The lambda:
Create finalList.
Grab desired object from finalList (first, closest, random, et cetera).
Go dock with that object.
Mark the object as explored.
Remove the entry from finalList (or just scratch finalList altogether).

The order to the auton:
Check that there’s a valid entry in (or to add to) finalList.
If no valid entry, message the player.
Otherwise, call the lambda.

The <OnOrdersCompleted> event:
Check that there’s a valid entry in (or to add to) finalList.
If there’s a valid entry, call the lambda.
Otherwise:
Message the player that looting is done.
Resume escorting.
 There may need to be a call to <OnOrdersCompleted> in there somewhere, too. Not sure. Hopefully this will get things pointed the right direction and you can fine tune it from there, though.
Image

Mod prefixes: 0xA010 (registered) and 0xDCC8 (miscellaneous)

My mods on Xelerus: Click here!

Of all the things I’ve lost in life, I miss my mind the least. (I’m having a lot more fun without it!)
NMS
Militia Captain
Militia Captain
Posts: 569
Joined: Tue Mar 05, 2013 8:26 am

Actually, it does seem like it would be useful to use an event handler here. Just create a generic Type with the necessary Communications, Events, and Language elements, then you can add that code with eventHandler= in the ShipClass or (objSetEventHandler obj unid). If you use the latter, you might need to add it again after gating though, maybe with a recurring event on another type.

You should probably set the object's 'behavior data (perhaps to 'looting) when you give it the order. You could also use the OnShow event in the Communications Message to prevent it from appearing if they're already looting (or already looting the specified target if the order sends a target). Look at RPGAutons and RPGWingmen for examples.

Autons and wingmen already have OnOrdersCompleted events, so it's probably better to use something else. When you issue the order you could add a recurring custom event that does something like this:
- Stop the event timer if the 'behavior is not 'looting.
- If it's docked with an appropriate object to loot, moves as many as possible of the first item that will fit from that object to its cargo. (This will make it take some time to move large numbers of items, depending on the event frequency.) Then order it to undock and dock with the next object to loot if the object is empty or no items fit. Perhaps send the player a message when done or if the items don't fit.
- If there are no more objects to loot, return to formation, reset 'behavior, and stop the timer.
relanat
Militia Captain
Militia Captain
Posts: 941
Joined: Tue Nov 05, 2013 9:56 am

Ah. That helps. Thanks.
So 'shpOrder' isn't the action of docking, it is the command to do the dock action. So lots of commands can stack before the actions actually happen. In my code the auton would be playing catch up, so to speak, until it completed all the dock actions.
Running the 'shpOrder' function inside the lambda however will let the action happen before the next command is given.
If fact a lot of stuff makes sense now. Giving a new order to a ship often doesn't work, or seem to work. That's because it has got the order but won't do it until it has done all the rest of its current orders (I probably would have seen this if I wasn't so impatient when modding!). That's why 'shpCancelOrders' is so common in code, and I guess 'shpOrderImmediate' might shove an order into the stack so it gets done either instantly or as the next order after the current one.

I'm a bit hazy on the <OnOrdersCompleted> event. There is one in the auton base class I copied and have been modifiying but how does it work? Although I have changed some things successfully I don't really understand what I'm doing. Does it run after the individual dock action finishes as opposed to when the dock command is given, or after the last order in the stack is completed (so no further orders remain) or the last action?
Here's the current code. I can't remember what I've changed.

Code: Select all

	
<OnOrdersCompleted>
	(block (behavior theTarget)
		(setq behavior (objGetData gSource 'behavior))

			;Set orders and state
		(switch
			(eq behavior 'looting)
				(block Nil
					(shpOrder gSource 'escort gPlayership (objGetData gSource 'formAngle))
					(objSetData gSource 'behavior 'escorting)
				)

			(eq behavior 'docking)
				Nil

			(not (objGetProperty gSource 'playerWingman))
				Nil

			(and (eq behavior 'attackingAtWill)
				(setq theTarget (sysFindObject gPlayerShip "sTEAN"))
				(leq (objGetDistance gPlayerShip theTarget) 100)
			)
				(shpOrder gSource 'attack theTarget)

			gPlayerShip
				(block Nil
					(shpOrder gSource 'escort gPlayerShip (objGetData gSource 'formAngle))
					(objSetData gSource 'behavior 'escorting)
				)

			(block Nil
				(shpOrder gSource 'hold)
				(objSetData gSource 'behavior 'waiting)
			)
		)
	)
</OnOrdersCompleted>
But an event handler might be good. I was thinking of 'hijacking' other autons which have a cargoAuton attribute so they could also be commanded like the mod autons. It looks like their 'handling' code can be reset by this, even if it has to be re-reset every so often. I'll search the source code for examples.

I think (he says with fingers crossed) I understand the messaging code so that's all good.

PMs PSD looting code uses a random wait of 1 or 2 ticks when the drones dock. I'll try to get the autons to wait for a time that is determined by item numbers or total item mass so the player can greedily rub their hands together and smile if the auton takes a while. The longer the docking time, the more the loot!

And as with most things I'm trying for the first time, there may be more questions! :)
Stupid code. Do what I want, not what I typed in!
NMS
Militia Captain
Militia Captain
Posts: 569
Joined: Tue Mar 05, 2013 8:26 am

Again, I don't think you actually want to use an OnOrdersCompleted event for this. For one thing, it would replace the existing event on autons and wingmen if you add the code to them. So you'd have to include the functionality of those events, and keep it up to date when they change. Yours already seems to be based on an out of date version.

But more importantly, many orders don't actually complete at all. E.g. 'attack completes when the target is destroyed, but 'dock doesn't complete. The ship just stays docked until the order is cancelled.
User avatar
AssumedPseudonym
Fleet Officer
Fleet Officer
Posts: 1190
Joined: Thu Aug 29, 2013 5:18 am
Location: On the other side of the screen.

 Actually, you don’t really want the 'dock order, anyway, you want the 'loot order. That will dock the ship, transfer the loot (though it will also grab the damaged stuff, which you may need to manually transfer back to the wreck if you want it excluded), and then properly complete to be ready for the next order.
Image

Mod prefixes: 0xA010 (registered) and 0xDCC8 (miscellaneous)

My mods on Xelerus: Click here!

Of all the things I’ve lost in life, I miss my mind the least. (I’m having a lot more fun without it!)
NMS
Militia Captain
Militia Captain
Posts: 569
Joined: Tue Mar 05, 2013 8:26 am

Oh, huh, that is a built-in order. It may or may not do what you want in terms of how long it takes, which items it loots if cargo space is too full for all of them, etc.
relanat
Militia Captain
Militia Captain
Posts: 941
Joined: Tue Nov 05, 2013 9:56 am

I'll use an event handler as that seems like it will allow the hijacking of other autons. But I want to make other changes to the Comms and behaviour as well so understanding <OnOrdersCompeted> will help with that (Plus it will help with a mod that changes Nomad behaviour). But in the end it will be whatever I can get working! By the time I get them working my mods rarely resemble the original design!
NMS wrote:
Sat Apr 20, 2019 8:24 pm
many orders don't actually complete at all. E.g. 'attack completes when the target is destroyed, but 'dock doesn't complete. The ship just stays docked until the order is cancelled.
That's important info. Thanks for that.


Also, NMS is correct. To quote PM from a PSD comment. "; We cannot use 'loot because the drone will take everything even if it does not have the space." In theory the 'loot order could have criteria added to it and all sorts of fancy features but it has such a limited application that IMO it isn't worth the time needed to do that.
Stupid code. Do what I want, not what I typed in!
Post Reply