I was working at a variation of the pitateAI.plist. According to the code it is intended that all pirates make a hyper jump after their hold is full. It is just that i never witnessed such thing in all those years. I added pirates and cargo around me an waited. When their hold was full they didn't jump.
With an AI trace I noticed that when the hold was full, it first got an NOTHING_FOUND message and after that the HOLD_FULL message. However, the NOTHING_FOUND message already made that the AI switched to the next state. And that state got the HOLD_FULL message. And that state was not programmed to react on that message:
When I followed the trace I was surprised that the CARGO_SCOOPED message even arrived another state later.
Code: Select all
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'COLLECT_LOOT' receives message 'ENTER'
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action setSpeedTo: 0.0
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action performIdle
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action scanForLoot <--- here scanning
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action pauseAI: 5.0
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'COLLECT_LOOT' receives message 'TARGET_FOUND'
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action setTargetToFoundTarget
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action setStateTo: LOOT
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'COLLECT_LOOT' receives message 'EXIT'
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'LOOT' receives message 'ENTER'
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action performCollect <--- start collection
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'LOOT' receives message 'TARGET_LOST' <--- here scooped up, hold full.
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action setStateTo: COLLECT_LOOT
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'LOOT' receives message 'EXIT'
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'COLLECT_LOOT' receives message 'ENTER'
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action setSpeedTo: 0.0
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action performIdle
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action scanForLoot
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action pauseAI: 5.0
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'COLLECT_LOOT' receives message 'NOTHING_FOUND'
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action setStateTo: CONSIDER_DOCKING
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'COLLECT_LOOT' receives message 'EXIT'
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'CONSIDER_DOCKING' receives message 'ENTER'
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action checkForMotherStation
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'CONSIDER_DOCKING' receives message 'HOLD_FULL' <-- only here the reaction
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'CONSIDER_DOCKING' receives message 'CARGO_SCOOPED' <-- only here the reaction
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'CONSIDER_DOCKING' receives message 'NOTHING_FOUND'
Oolite [ai.takeAction] -[AI takeAction:] (AI.m:411): Krait 256 to take action setStateTo: LURK
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'CONSIDER_DOCKING' receives message 'EXIT'
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI pirateAI.plist for Krait 256 in state 'LURK' receives message 'ENTER'
So I added the HOLD_FULL message also to the next state of the AI. In my case the TRAVEL_TO_LURK_AREA state. This way it (almost) worked as it should and all the pirate with full hold made its hyperspace jump.
Problem with pirates is that some are defined with a cargo bay of zero capacity. (like the oolite-asp) These ships will immediately generate a HOLD_FULL and jump. Yesterday I tries some time to rewrite the pirateAI so ships with cargo bay jump when their hold was full and others with a zero cargo bay stayed in the system. But how I tried, I could not get a good Working AI.
Problem is that the
checkForHoldFull only generates a message when the hold is full. So when using it in a state, that state must also have a command that lets it proceed to an other state. And this results in receiving the HOLD_FULL message in an other state. I only could come up with something when using dices. But that looks as a bad approach.
What we actually need is that the
checkForHoldFull generates 3 different messages:
HOLD_FULL,
STILL_HUNGRY and [NO_CARGO_BAY[/i]. This way you can write code that ensures that it always proceeds to an next state when using the
command checkForHoldFull.
**Having pirates without cargo bay is kind of a bug itself.**
The main purpose of pirates is attack traders for their cargo and scoop it. According the pirateAI they should turn into normal traders when their hold is full. With a full hold there is no reason to attack other ships. Currently that part of the pirateAI does not work as it was written. Maybe it worked in the old days, but messages like
TARGET_LOST spoil this now. But those messages are also needed.
When we want to have pirates that only attack and have no bay, we should rewrite the code a bit so the
HOLD_FULL is only generated with ships that can carry cargo. That way it becomes much easier to write an AI that let only traders that actually scooped their bay full become traders.