AIOrder.SetOrderFlags operation - problem fixed.

Discuss the new AI features ("NoAI") introduced into OpenTTD 0.7, allowing you to implement custom AIs, and the new Game Scripts available in OpenTTD 1.2 and higher.

Moderator: OpenTTD Developers

Post Reply
Attila7
Engineer
Engineer
Posts: 37
Joined: 31 May 2010 21:06

AIOrder.SetOrderFlags operation - problem fixed.

Post by Attila7 »

I am trying to use the AIOrder.SetOrderFlags function. It's operation seems a bit strange.

I have an order to a stop (Full load any cargo) initially added with AIOF_FULL_LOAD_ANY.
I want to change this to (Unload and leave empty) with SetOrderFlags(AIOF_UNLOAD | AIOF_NO_LOAD).
When I do this, I get (Unload and wait for any full load).
If I execute the same call a second time, I get the desired (Unload and leave empty)

Things are even stranger if I set just one order at a time:

Setting AIOF_FULL_LOAD_ANY on (Unload and leave empty) produces (No loading)
then setting AIOF_UNLOAD on (No loading) produces (Unload and leave empty)

How is this function supposed to be used?
Last edited by Attila7 on 14 Jul 2010 23:31, edited 1 time in total.
Attila
"Artificial intelligence is no match for natural stupidity."
User avatar
fanioz
Transport Coordinator
Transport Coordinator
Posts: 320
Joined: 19 Dec 2008 05:03
Location: Indonesia
Contact:

Re: AIOrder.SetOrderFlags operation

Post by fanioz »

IMO, AIOrderFlags are only bits set. You have to do bit operation to modify these flags.
Your question was still not clear enough. Are you modify existing flag order on a vehicle or just set a flag order on it. Perhaps, some line of code could explain what is in your mind. :)
Correct me If I am wrong - PM me if my English was bad :D

**[OpenTTD AI]** Image
***[NewGRF] *** Image
Attila7
Engineer
Engineer
Posts: 37
Joined: 31 May 2010 21:06

Re: AIOrder.SetOrderFlags operation

Post by Attila7 »

Yes, I am trying to modify an existing order that has a vehicle going to a station with orders (Full load any cargo) initially added with AIOF_FULL_LOAD_ANY.

I then want to modify this order to be (Unload and leave empty).

I use a single line of code: AIOrder.SetOrderFlags(id,idx,AIOrder.AIOF_UNLOAD | AIOrder.AIOF_NO_LOAD);

When I do this, I get (Unload and wait for any full load) instead of what I want. Executing the above statement a second time results in the desired order, however I don't understand the logic behind this.

I guess I will check the source code and see what is going on. I would expect that this function should replace the flag bits, but it obviously does some bit manipulation instead.
Attila
"Artificial intelligence is no match for natural stupidity."
Kogut
Tycoon
Tycoon
Posts: 2493
Joined: 26 Aug 2009 06:33
Location: Poland

Re: AIOrder.SetOrderFlags operation

Post by Kogut »

You can set AIOF_NONE before further messing with flags.
Correct me If I am wrong - PM me if my English is bad
AIAI - AI for OpenTTD
Attila7
Engineer
Engineer
Posts: 37
Joined: 31 May 2010 21:06

Re: AIOrder.SetOrderFlags operation

Post by Attila7 »

Kogut wrote:You can set AIOF_NONE before further messing with flags.
This does not work either!

Setting AIOF_NONE on an order that had AIOF_NON_STOP_INTERMEDIATE | AIOrder.AIOF_FULL_LOAD_ANY (Go non-stop xxx (Full load any cargo)) results in (Full load any cargo).

I looked at the source code and it appears rather complicated and its logic is not apparent. However there is the following comment in there:

Code: Select all

* Callback handler as SetOrderFlags possibly needs multiple DoCommand calls
 * to be able to set all order flags correctly. As we need to wait till the
 * command has completed before we know the next bits to change we need to
 * call the function multiple times. Each time it'll reduce the difference
 * between the wanted and the current order.
I have no idea what this means, however it is not being done correctly. The only way to achieve the desired flag changes right now is for the AI script to execute the exact same SetOrderFLags command multiple times until the desired bits are set.

I think an AI script should only have to set the flag bits once and the internal code should take care of doing multiple commands to achieve the desired result or anyone trying to modify orders will be in for a lot of trial and error experimenting and code that seems to be redundant.
Attila
"Artificial intelligence is no match for natural stupidity."
User avatar
fanioz
Transport Coordinator
Transport Coordinator
Posts: 320
Joined: 19 Dec 2008 05:03
Location: Indonesia
Contact:

Re: AIOrder.SetOrderFlags operation

Post by fanioz »

Code: Select all

local flag = AIOrder.GetOrderFlags(vhc, number);

//turn of flag
flag = flag & ~AIOrder.AIOF_FULL_LOAD_ANY;

//set new flag
flag = flag | AIOrder.AIOF_UNLOAD | AIOrder.AIOF_NO_LOAD;

//set on vehicle
AIOrder.SetOrderFlags(vhc, number, flag);
* not tested yet
Correct me If I am wrong - PM me if my English was bad :D

**[OpenTTD AI]** Image
***[NewGRF] *** Image
Attila7
Engineer
Engineer
Posts: 37
Joined: 31 May 2010 21:06

Re: AIOrder.SetOrderFlags operation

Post by Attila7 »

What you are essentially doing is resetting the current flags (not in the game), so your flag variable becomes zero, which you then OR with the desired flags. So, you are doing the same thing I am trying to do, except with far more instructions.

The bottom line is that when you call AIOrder.SetOrderFlags with some bits, the function returns True, when in fact it did not do what you want.

The more I look at this, the more I think this is clearly a bug.
Attila
"Artificial intelligence is no match for natural stupidity."
User avatar
fanioz
Transport Coordinator
Transport Coordinator
Posts: 320
Joined: 19 Dec 2008 05:03
Location: Indonesia
Contact:

Re: AIOrder.SetOrderFlags operation

Post by fanioz »

what if ....

Code: Select all

local flag = AIOrder.GetOrderFlags(vhc, number);

//turn of flag
flag = flag & ~AIOrder.AIOF_FULL_LOAD_ANY;

//set on vehicle
AIOrder.SetOrderFlags(vhc, number, flag);

//set new flag
flag = AIOrder.AIOF_UNLOAD | AIOrder.AIOF_NO_LOAD;

//set on vehicle
AIOrder.SetOrderFlags(vhc, number, flag);
or

Code: Select all

local flag = AIOrder.GetOrderFlags(vhc, number);

//set new flag
flag = AIOrder.AIOF_UNLOAD | AIOrder.AIOF_NO_LOAD & ~AIOrder.AIOF_FULL_LOAD_ANY;

//set on vehicle
AIOrder.SetOrderFlags(vhc, number, flag);
* not tested yet
Correct me If I am wrong - PM me if my English was bad :D

**[OpenTTD AI]** Image
***[NewGRF] *** Image
Rubidium
OpenTTD Developer
OpenTTD Developer
Posts: 3815
Joined: 09 Feb 2006 19:15

Re: AIOrder.SetOrderFlags operation

Post by Rubidium »

I have tried to reproduce your behaviour in trunk but I cannot reproduce it. If I add two flags to a SetOrderFlags it sets both flags and it looks fine in-game. What version of OpenTTD are you using that has this (bad) behaviour?
Attila7
Engineer
Engineer
Posts: 37
Joined: 31 May 2010 21:06

Re: AIOrder.SetOrderFlags operation

Post by Attila7 »

Thanks for testing this for me. It appears the bug was in my code as it was not executing the orders I thought it was doing.

Sorry for the wild-goose chase.
Attila
"Artificial intelligence is no match for natural stupidity."
Post Reply

Return to “OpenTTD AIs and Game Scripts”

Who is online

Users browsing this forum: No registered users and 7 guests