Page 1 of 1

Help with dynamic scripting in an own new campaign

PostPosted: 07 Apr 2017, 22:00
by Guest
Hello everyone :)
I started creating new campaign and of course I'm using dynamic scripting. I am not good enough, so I need your help. Firstly, please do not close this topic until I finish my campaign. Who wants to know I am just only scripting, my friend makes only maps, so I can aim only on scripting.
And maybe to keep messages clear if I solve problem, I (or admin) will write a post with solution step by step and all previous tips concerned only this exact problem will be removed.

So, my first problem:
1. I want to order groups to attack next building, but this group(s) just only are "trying" to do something and stay in place - it looks like bug. Script code
  Code:
procedure OnTick if States.HouseDestroyed(gospo3) then begin Actions.GroupOrderAttackHouse(oddzial7, gospo2); Actions.GroupOrderAttackHouse(oddzial8, gospo2); end;
This lines have been written correctly, it works, but problem is with units, which are trying to go, but they can not, just still trying to go.
How could I write to have properly working script?

Additional info : 'oddzial(number)' is a group of units, not important what type; 'gospo(number)' is a building, exactly farm; Kenji is a unit swordsmen.

What is more, if I use command "OnHouseDestroyed" and then "Actions.GroupAttackUnit" or "Actions.GroupAttackHouse" it works properly.

Re: Help with dynamic scripting in an own new campaign

PostPosted: 07 Apr 2017, 22:02
by Annihilus
Sorry for spam, but it is my topic and first message, but I have not been logged and haven't seen it before.

Re: Help with dynamic scripting in an own new campaign

PostPosted: 08 Apr 2017, 08:36
by Krom
Looking at the code - Do you order the group to attack the house on EACH and EVERY tick? I don't recall details, but this could be a problem. See if you can place an order on 1 tick and then don't repeat it.

Re: Help with dynamic scripting in an own new campaign

PostPosted: 08 Apr 2017, 08:53
by The Dark Lord
Yes, Krom is right.
Right now, your script is issuing the soldiers to attack every tick (that means 10 times in a second). Try to see for yourself what happens if you select a soldier and right click on a building repeatedly very fast: the soldier will start to attack the building, but every time you click, it will start all over again and start with the animation where it rises its weapon, thus not effectively attacking the building.
To prevent this, you can adjust your script so it checks if the group is idle, and only carries out an order if it is.

Re: Help with dynamic scripting in an own new campaign

PostPosted: 08 Apr 2017, 10:57
by Annihilus
Oh, so procedure "OnTick" provides performing each order 10 times a second. So how script should be written to do order only 1 time? (And now I know why I have always problems with this command)

Re: Help with dynamic scripting in an own new campaign

PostPosted: 08 Apr 2017, 19:03
by Toxic
Oh, so procedure "OnTick" provides performing each order 10 times a second.
Right -> 10 times per a second when you have game speed 1x.
So how script should be written to do order only 1 time? (And now I know why I have always problems with this command)
It is simple - use modulo:
  Code:
procedure OnTick; begin //This will cause RunSlowCode to occur on ticks 10, 20, 30, etc. if States.GameTime mod 10 = 0 then RunSlowCode; end;
More examples here:
https://github.com/Kromster80/kam_remak ... erformance

Re: Help with dynamic scripting in an own new campaign

PostPosted: 08 Apr 2017, 19:37
by Annihilus
So I did like you said and:
1. If I use "RunSlowCode;" the game says "Error (...) Unknown identifier 'RunSlowCode' "
2. If I do not use this line, the command works almost good, but there is still a little bugged animation, but it works. And it's why RunSlowCode should be used, am I right?

I want use procedure OnTick to change purpose of unit/group because one building is destroyed and these soldiers do nothing; they attack only when my soldier come to them by 4 meters/units (I know how to change amount of units). And my next question, is it possible to set "attacking everything in the range of unit"?

Re: Help with dynamic scripting in an own new campaign

PostPosted: 08 Apr 2017, 19:58
by Toxic
"RunSlowCode" is just another procedure. You have have to write something like this:
  Code:
procedure OnTick begin if States.GameTime mod 20 = 0 then begin // Here must be your "slower" code - for example: if States.HouseDestroyed(gospo3) then begin Actions.GroupOrderAttackHouse(oddzial7, gospo2); Actions.GroupOrderAttackHouse(oddzial8, gospo2); end; end; end;
"RunSlowCode" is just another procedure. You have have to write something like this:
  Code:
procedure OnTick begin if States.GameTime mod 20 = 0 then begin // Here must be your "slower" code - for example: if States.HouseDestroyed(gospo3) then begin Actions.GroupOrderAttackHouse(oddzial7, gospo2); Actions.GroupOrderAttackHouse(oddzial8, gospo2); end; end; end;
And my next question, is it possible to set "attacking everything in the range of unit"?
Yes it is possible.
First way is to set AI attack in map editor.
Second way is via AI defence positions in map editor (but it strongly depends on the situation).
Third way are dynamic scripts. You have to use States.ClosestUnit (or States.ClosestGroup) to find a hostile unit. When you have ID of this unit you have to calculate distance between your and hostile units: States.UnitPositionX and States.UnitPositionY will give you those coordinates. In the dependence on distance you can call GroupOrderAttackUnit.

Re: Help with dynamic scripting in an own new campaign

PostPosted: 08 Apr 2017, 20:34
by Annihilus
Yes, of course. I did like you wrote before you posted again, my code:
  Code:
procedure OnTick; begin if States.GameTime mod 10 = 0 then begin RunSlowCode; if States.HouseDestroyed(spichrz) then begin Actions.GroupOrderAttackHouse(wrog, szkola); end; end; end;
and it causes problem "Error (...) Unknown identifier 'RunSlowCode' " and nothing is working of course

and code :
  Code:
procedure OnTick; begin if States.GameTime mod 10 = 0 then begin if States.HouseDestroyed(spichrz) then begin Actions.GroupOrderAttackHouse(wrog, szkola); end; end; end;
causes point 2. The command works almost good, but there is still a little bugged animation, every 20 ticks, it is 2 seconds.

And, when I use procedure OnTick and then Actions.OrderGroupAttackUnit(...) it is everything good, problems are coming when I try to use this procedure to order soldiers to attack next house.

The solution of this problem will be command that will be done on specified tick in game, I think I could use procedure "OnHouseDestroyed" but is it possible not to define this command by "aHouse: Integer; aDestroyerIndex: Integer;" just only by "aHouse" something like:
  Code:
procedure OnHouseDestroyed begin [b]if States.HouseType(building1)[/b] then begin //building1 and 2 definied before by "var" Actions.OrderGroupAttackHouse(knights, building2) // this line I know how to use end; end;

I can not use editor to make an attack because I want to attack 3 buildings by 1 group and it is impossible to make 3 orders for 1 unit, im I right?
And you said way 3 - I want to attack every near buildings, it is something like : group1, 2 ,3 and 3 buildings (a big shortcut) and : these 3 groups are attacking building1, then building is destroyed and I want to order to attack 2nd building, building2 is destroyed and again I want to order next attack - building3

Re: Help with dynamic scripting in an own new campaign

PostPosted: 08 Apr 2017, 21:11
by Toxic
... but there is still a little bugged animation, every 20 ticks, it is 2 seconds.
Change:
  Code:
From: States.GameTime mod 10 = 0 To States.GameTime mod 50 = 0
I think I could use procedure "OnHouseDestroyed" but is it possible not to define this command by "aHouse: Integer; aDestroyerIndex: Integer;" ...
Yep you can use this event but it must be defined as follows:
  Code:
procedure OnHouseDestroyed (aHouse: Integer; aDestroyerIndex: Integer;) begin // Code here will happen when someone {aDestroyerIndex} destroy a building // Here can be "arbitrary" code end;
-> you don't have to use those parameters {aHouse,aDestroyerIndex} but they must be in declaration of procedure.
... it is impossible to make 3 orders for 1 unit, im I right?
1 unit can have max 1 task in 1 time.
And you said way 3 - I want to attack every near buildings, it is something like : group1, 2 ,3 and 3 buildings (a big shortcut) and : these 3 groups are attacking building1, then building is destroyed and I want to order to attack 2nd building, building2 is destroyed and again I want to order next attack - building3
You can use the same process like when you attack closest group ... use States.ClosestHouse to find closest house from your group and for attack command Actions.GroupOrderAttackHouse.