Outpost Universe Forums

Projects & Development => Outpost 2 Programming & Development => Topic started by: Angellus Mortis on January 18, 2010, 09:39:51 AM

Title: Something Better Then Recordbuilding?
Post by: Angellus Mortis on January 18, 2010, 09:39:51 AM
I am trying to make a function that is faster then RecordBuilding. It is so painfully slow and the AI builds slower then the human player. Not good. So here is my solution that uses IUnit:

Enumerate for a idle SF (not producing), have it build the kit, then have a idle ConVec come and collect the kit and go build it. After the building is started, record the building it is place so it will be rebulit later if it is destroyed. This is the code I have so far:

void BuildStruct(int ai, BuildingGroup build, enum map_id building, enum map_id weapon, LOCATION buildloc)
{
    IUnit AIb, AIv;
    PlayerBuildingEnum IdleSF(ai, mapStructureFactory);
    GroupEnumerator IdleConVec(build);
    while (IdleSF.GetNext(AIb))
    {
      if (!AIb.GetBusy() == ctMoProduce)
        {
            AIb.Produce(building, weapon);
            while (IdleConVec.GetNext(AIv)
            {
            //make the ConVec move to the dock
            }
            while (AIb.GetBusy() == ctMoProduce);
         //now that the SF is done building kit, test for bay and transfer to the ConVec
         AIv.Bulid(buildloc);
         build.RecordBuilding(builloc, builing, weapon);
        }
    }
}

The comments show what I need help on. Thanks.
Title: Something Better Then Recordbuilding?
Post by: AmIMeYet on January 18, 2010, 10:18:09 AM
I won't be able to help you with your question, but I do have a question for you:
Is this threaded?
If not, wouldn't while (AIb.GetBusy() == ctMoProduce); produce an eternal loop? since the game is unable to progress.
Title: Something Better Then Recordbuilding?
Post by: Angellus Mortis on January 18, 2010, 11:35:41 AM
No it would not, because when it was no longer producing it would break... and I do need to add breaks to exit the enumeraters
Title: Something Better Then Recordbuilding?
Post by: TH300 on January 18, 2010, 02:28:28 PM
Moving the cenvec to the dock can be done by first determining the position of the dock and then using "void DoMove(struct LOCATION loc);". But I find that so ugly, that I'd rather try to use building groups anyway, if I were you.

I don't know exactly how op2 works internally, but if you call this function from AIProc(), it will let the game hang till the function exits, i.e. till the sf has produced the kit. You should use triggers instead, but I can't explain them to you.

If the kit has been produced, you'll have to make sure that the convec is still on the dock (it may have been pushed away by other vehicles) and then call IUnits "TransferCargo". I guess, you'll need to know the bay # for that and you can get that by testing all bays in a loop with "GetFactoryCargo".


I want to remind you though. that all this is ugly, even IUnit itself is ugly, because it hacks into the game and may cause unexpected errors. If you can find a solution that uses build groups somehow, you should use that instead.
Title: Something Better Then Recordbuilding?
Post by: Angellus Mortis on January 19, 2010, 09:29:39 AM
I tired building groups. If I have one building group for a SF it is unbelievely slow. If I do more then one building group per SF, it glitches because the ConVecs fight over the dock and I had 20 Agridomes built on the VFs beside the SF. This is the only way I am finding to do it. If you think of a new way, please do share.
Title: Something Better Then Recordbuilding?
Post by: Hidiot on January 19, 2010, 09:53:31 AM
Using stacks. I had begun such a project, though I later stopped due to dynamic allocation causing crashes with OP2. Using only static allocation will impose some restrictions, which make it less flexible. It will also make for some less streamlined processing.
Title: Something Better Then Recordbuilding?
Post by: TH300 on January 19, 2010, 11:34:26 AM
Here is an idea:

Don't have an arbitrary number of build-groups. 2 will likely be enough. Let them be A and B. Now, if you want a new building, you record it in Group A. The sf will start building the kit and when it has done that, it will be loaded into the convec, then the convec will build it. Of course you do already know what to build next, as soon as production of the first kit has finished. So, you record that in group B exactly in this moment. It will be built, loaded into the convec and the building will be built.

That doesn't solve the problem with the convecs fighting for the dock (unless you have only one convec in each group). One simple solution would be to make sure that all convecs which are currently unused are in one single build group, i.e. in the group which is waiting for the next kit.

For a bigger colony 2 groups are probably not enough. But this idea should be easily generalizable to work with an arbitrary number of build-groups.
 
Title: Something Better Then Recordbuilding?
Post by: Hooman on January 20, 2010, 12:20:16 AM
By slow I assume you mean that the SF builds a kit, and only after it's started (or was it only after it completes building), does it move the ConVec in place. The ConVec then goes to deploy the kit, and only after construction has started does it start building the next kit. Hence, the whole operation isn't very pipelined?


They're right not to use busy loops, like your while loop. You should listen to them. The InitProc, AIProc, and Trigger callback functions all run in the same thread as the main game engine. The game will not progress until those functions return. If in one of those functions you have a while loop waiting for a condition to come true, which can only happen by the game progressing in time, then it will deadlock. What you have there simply won't work.

Also, busy wait loops are bad even if they don't deadlock your app since they cause the CPU to max out it's usage. This is especially bad for people using laptops on battery power. It's also bad for people who have noisy fans, and overheating their chips will cause the fan to activate. It also slows down whatever else is running on their computer, so that your app can go merrily about wasting CPU time doing nothing. And of course, you're destroying our environment. Now don't you feel bad about your busy wait loops?  ;)


Perhaps a simpler way to get the effect you want, without resorting to IUnit or other similar methods, is to use two structure factories?
 
Title: Something Better Then Recordbuilding?
Post by: CK9 on January 20, 2010, 09:25:19 AM
Is there not a way to tell units to move to a specified point?  Why not triger a convec move at the same time as a kit build?
Title: Something Better Then Recordbuilding?
Post by: Angellus Mortis on January 22, 2010, 05:00:57 PM
Quote
Perhaps a simpler way to get the effect you want, without resorting to IUnit or other similar methods, is to use two structure factories?
It is a big colony. I already have three. One for guard post and two for structures. :(
Title: Something Better Then Recordbuilding?
Post by: Eddy-B on January 31, 2010, 06:14:16 AM
angellus, i toyed with this b4 and soon realized it was too much of a hassle to rewrite the code. I decided to just use existing build code ...
but as you all know, my AI never got finished :(

And with a "slow" building AI, i can still whoop your @ss,  angellus, the few extra seconds won't matter too much.
Title: Something Better Then Recordbuilding?
Post by: Angellus Mortis on January 31, 2010, 07:56:42 AM
Lol Eddy. Still, you see what I am trying to do. Is it possible to make it work?
Title: Something Better Then Recordbuilding?
Post by: Hidiot on January 31, 2010, 02:19:45 PM
If your AI has advantages built-in the map. But if you want to put a human player with an AI on the same level, then the AI will suffer from its slow building times.