Page 9 of 26

Re: Dynamic Script Usage

PostPosted: 24 May 2013, 15:07
by Islar
how do i put more than one message for one map?
i think not like this.

procedure OnTick;
begin
if States.GameTime =(100) then
Actions.ShowMsg(0, 'The village in the north is being attacked by an unknown army. Thou shalt defend it and defeat that army. Do not let them destroy it.');
end;
begin
if States.GameTime =(1500) then
Actions.ShowMsg(0, 'Now we must resume our request. Thou must defeat The Barbarians. Because there is aproaching a huge wave of Barbarians thou must arm more militia and bowmen!');
end;
begin
if States.GameTime =(3000) then
Actions.ShowMsg(0, 'A few barbarians are still on the borderline protecting their settlement. Thou shalt destroy this. This shalt done our doing here.');
end;

How can i do it on the propper way?

Re: Dynamic Script Usage

PostPosted: 24 May 2013, 15:33
by Lewin
You seem to have mixed up the begins/ends. It should go something like "if..begin..end" And you can remove the brackets around the numbers, each if-statement should just be something like:
if States.GameTime = 100 then

Also, you should use LIBX files for the text so it can be translated (using States.Text, look at how the original campaigns have done it).

The complete correct code would be:
  Code:
procedure OnTick; begin if States.GameTime = 100 then begin Actions.ShowMsg(0, 'The village in the north is being attacked by an unknown army. Thou shalt defend it and defeat that army. Do not let them destroy it.'); end; if States.GameTime = 1500 then begin Actions.ShowMsg(0, 'Now we must resume our request. Thou must defeat The Barbarians. Because there is aproaching a huge wave of Barbarians thou must arm more militia and bowmen!'); end; if States.GameTime = 3000 then begin Actions.ShowMsg(0, 'A few barbarians are still on the borderline protecting their settlement. Thou shalt destroy this. This shalt done our doing here.'); end; end;

Re: Dynamic Script Usage

PostPosted: 24 May 2013, 15:52
by Islar
You seem to have mixed up the begins/ends. It should go something like "if..begin..end" And you can remove the brackets around the numbers, each if-statement should just be something like:
if States.GameTime = 100 then

Also, you should use LIBX files for the text so it can be translated (using States.Text, look at how the original campaigns have done it).

The complete correct code would be:
  Code:
procedure OnTick; begin if States.GameTime = 100 then begin Actions.ShowMsg(0, 'The village in the north is being attacked by an unknown army. Thou shalt defend it and defeat that army. Do not let them destroy it.'); end; if States.GameTime = 1500 then begin Actions.ShowMsg(0, 'Now we must resume our request. Thou must defeat The Barbarians. Because there is aproaching a huge wave of Barbarians thou must arm more militia and bowmen!'); end; if States.GameTime = 3000 then begin Actions.ShowMsg(0, 'A few barbarians are still on the borderline protecting their settlement. Thou shalt destroy this. This shalt done our doing here.'); end; end;
Thanks, it works now

Re: Dynamic Script Usage

PostPosted: 30 May 2013, 17:59
by Ben
Alright, the noob is back in town with scripting! I think that I'll give this another shot.

Very simple: I'm trying to make the objective a (singleplayer) mission be to destroy a building, but I don't know how to return the "id" or whatever of the particular building I want. How do I specify it in the code?

Re: Dynamic Script Usage

PostPosted: 30 May 2013, 23:34
by Lewin
Alright, the noob is back in town with scripting! I think that I'll give this another shot.

Very simple: I'm trying to make the objective a (singleplayer) mission be to destroy a building, but I don't know how to return the "id" or whatever of the particular building I want. How do I specify it in the code?
States.HouseAt will give you the ID of the house at a specific location.
Or you could use Actions.GiveHouse in OnMissionStart (instead of adding the house in the .dat) then remember the ID in a global variable for later.

Re: Dynamic Script Usage

PostPosted: 03 Jun 2013, 17:12
by Siegfried
*edit:
nevermind, found it myself ...
it was a mistake in := and = ...

Re: Dynamic Script Usage

PostPosted: 04 Jun 2013, 14:28
by Islar
Hi

i use a this but something really weird happened.

procedure OnTick;
begin
if States.GameTime = 10 then
Actions.ShowMsg(0, States.Text(0));
if States.GameTime = 625 then
Actions.ShowMsg(0, States.Text(1));
if States.GameTime = 21000 then
Actions.GiveGroup (7, 23, 11, 13, 4, 21, 7);
Actions.GiveGroup (7, 27, 20, 13, 4, 21, 7);
end;

you can see in the picture. I just want to have one group of vagabonds and babarians after 21000 seconds. But i think i did something wrong in the script.
And those groups are just coming and coming and...

could someone help my?

Re: Dynamic Script Usage

PostPosted: 04 Jun 2013, 14:39
by Lewin
You need begin..end to make the "if .. then" statement apply to more than one line of code (otherwise it only affects one statement after it). This means your last GiveGroup command was running every time OnTick occurred, because there was no if-statement affecting it.

You can also use indentation and spacing to make your code easier to read. That makes it harder to be confused. Try this:
  Code:
procedure OnTick; begin if States.GameTime = 10 then Actions.ShowMsg(0, States.Text(0)); if States.GameTime = 625 then Actions.ShowMsg(0, States.Text(1)); if States.GameTime = 21000 then begin Actions.GiveGroup (7, 23, 11, 13, 4, 21, 7); Actions.GiveGroup (7, 27, 20, 13, 4, 21, 7); end; end;

Re: Dynamic Script Usage

PostPosted: 04 Jun 2013, 15:20
by sado1
First, if you use "if" statement, you have to use begin and end if you have more than 1 command in that if. For example:
  Code:
if GameTime = 1000 then Actions.GiveHouse(blahblah);
is good, but if you have more than one thing below if, then it has to look like that:
  Code:
if GameTime = 1000 then begin Actions.GiveHouse(blahblah); Actions.GiveHouse(blahblah); end;
because the game doesn't know how many things under if, should be included in if, and which ones shouldn't. Also, I don't think you wanted to make groups of 21x7=147 units, so you might want to change the end of these 2 last lines.
edit: ... Why on earth the forums didn't show Lewin's post to me? ;o

Re: Dynamic Script Usage

PostPosted: 04 Jun 2013, 15:21
by Islar
Thanks Lewin,

Could you tell my what's wrong with this. I think with the begin and end. Could also tell my how that works
  Code:
procedure OnTick; begin if States.GameTime = 100 then begin Actions.GiveHouse (0, 11, 12, 12); Actions.GiveHouse (1, 11, 17, 12); if States.GameTime = 200 then begin Actions.GiveWares (0, 1, 30); Actions.GiveWares (0, 2, 50); end; end; end;

Re: Dynamic Script Usage

PostPosted: 04 Jun 2013, 15:43
by Lewin
Programming is more complicated than you think. If-statements can be nested inside each other, that's what you've done here. Imagine the game engine running your code line by line every tick (10 times per second), that's how it gets executed. Here's a flow chart of your code:
http://i.imgur.com/aRafxDt.png

As you can see, the "if State.GameTime = 200" will never be "yes" because we've already checked "if State.GameTime = 100". You've put it INSIDE the "begin..end" block from the first if-statement. So the condition "if State.GameTime = 200" will always be false because that bit of code is ONLY executed if we've already checked that "States.GameTime = 100".

An if-statement means:
- If the condition is true: run the next block of code, meaning if it's a begin..end block, run the code inside it. If it's just one line of code, run it.
- If the condition is true: skip the next block of code, meaning if it's a begin..end block, skip all the code inside the begin..end. If it's just one line of code, skip it and then run the line after.

Re: Dynamic Script Usage

PostPosted: 04 Jun 2013, 20:11
by Siegfried
  Code:
procedure OnTick; { if States.GameTime = 100 { Actions.GiveHouse (0, 11, 12, 12); Actions.GiveHouse (1, 11, 17, 12); if States.GameTime = 200 { Actions.GiveWares (0, 1, 30); Actions.GiveWares (0, 2, 50); } } }
I changed your code into a syntax that used brackets so it's more obvious what you are doing here.

Now that you are not distracted from the many words any more you'll notice very easily, that the "if States.GameTime = 200" is called within the "if States.GameTime = 100". So this can never be true and therefore the things within the call for 200 will never be executed

Re: Dynamic Script Usage

PostPosted: 05 Jun 2013, 05:19
by Krom
And that is why formatting is your friend )
Without nice formatting you would not see the difference between clauses.

Re: Dynamic Script Usage

PostPosted: 09 Jun 2013, 16:52
by Islar
what means Unit ID? The position and type and playercount of the unit? i want to use UnitKill and how do i use Silent: Boolean?

Re: Dynamic Script Usage

PostPosted: 09 Jun 2013, 17:06
by Lewin
what means Unit ID?
It gives you a "handle" to that unit (a unit is a person in KaM) so you can refer to it from within the script. You can get a UnitID with commands like Action.GiveUnit and States.UnitAt. You can then use that UnitID in other commands. So lets say I always want to kill the unit standing on the tile X=12, Y=34, if it belongs to player 0. This script would do it:
  Code:
procedure OnTick; var U: Integer; begin U := States.UnitAt(12, 34); if (U <> -1) and (States.UnitOwner(U) = 0) then Actions.UnitKill(U, False); end;
i want to use UnitKill and how do i use Silent: Boolean?
The Silent parameter should be True or False (that's what Boolean means). If it's True, then the unit will disappear silently. If it's False, the unit will die with the normal animation. In my above example I used False, but you could put True there instead.