Map Database  •  FAQ  •  RSS  •  Login

Dynamic Script Usage Questions

<<

Lewin

User avatar

KaM Remake Developer

Posts: 3822

Joined: 16 Sep 2007, 22:00

KaM Skill Level: Skilled

ICQ: 269127056

Website: http://lewin.hodgman.id.au

Yahoo Messenger: lewinlewinhodgman

Location: Australia

Post 14 Apr 2013, 03:03

Re: Dynamic Script Usage

We would encourage you to store text in a LIBX file so it can be translated, but of course you can do that later if you like.

It would be cool to support classes, maybe one day ;) Right now we haven't seen any suggestions that really need classes... but as people's ideas get more and more complicated maybe we will.
<<

Ben

User avatar

Former Site Admin

Posts: 3814

Joined: 08 Jan 2009, 23:00

Location: California - Pacific Time (UTC -8/-7 Summer Time)

Post 14 Apr 2013, 05:18

Re: Dynamic Script Usage

But speaking of feature support:
is there a way to prevent enemy (but not allied) troops from entering a specific area? Will this be possible?
This can easily be done by having the game order any units in the restricted area to move out of the restricted area (every game tick, the game checks if there are units in the restricted area. If yes, then all units in selected area are moved out of it).

Of course, we'd need to be able to have commands to move units by area detection.

EDIT:

OH MY GOODNESS!!
I thought that I'd try making a script to disable towers after a player makes a certain amount. I was successful without asking for help! :D
I know that it is such a simple script, but I am so happy to see this milestone in my work. I'm finally getting this :)

EDIT 2:

How can I make comments in my script? I tried googling Pascal Comments, but all I couldn't find anything useful :?
I used to spam this forum so much...
<<

Krom

User avatar

Knights Province Developer

Posts: 3280

Joined: 09 May 2006, 22:00

KaM Skill Level: Fair

Location: Russia

Post 14 Apr 2013, 06:20

Re: Dynamic Script Usage

// Comment

{Multiline
block
of comments}

{commented
out
code}

;)
Knights Province at: http://www.knightsprovince.com
KaM Remake at: http://www.kamremake.com
Original MBWR/WR2/AFC/FVR tools at: http://krom.reveur.de
<<

Ben

User avatar

Former Site Admin

Posts: 3814

Joined: 08 Jan 2009, 23:00

Location: California - Pacific Time (UTC -8/-7 Summer Time)

Post 14 Apr 2013, 06:52

Re: Dynamic Script Usage

Thanks, Krom :)

Tell me if I'm wrong -> Everything other than constants and global variables must be within an event handler. That is, I cannot have an action, event, or state that doesn't have an event handler with it.

One more thing: My tower-limiting script doesn't actually work because players can still place as many tower plans as they want before the towers are actually built. However ,there is no state that detects how many houseplans are laid out, so I can't figure out a way around this...
I used to spam this forum so much...
<<

Krom

User avatar

Knights Province Developer

Posts: 3280

Joined: 09 May 2006, 22:00

KaM Skill Level: Fair

Location: Russia

Post 14 Apr 2013, 07:32

Re: Dynamic Script Usage

You can add additional functions and procedures for your own use.

rough examples:

procedure StartAttackWave(Multiplier: Integer);
begin
AddGroup, Set Attack order, etc,
end;

procedure ShowTextToHumans(aIndex: Integer);
begin
for I := 0 to fPlayer.Count - 1 do
if PlayerEnabled then
ShowMessage(I, aIndex)
end;
Knights Province at: http://www.knightsprovince.com
KaM Remake at: http://www.kamremake.com
Original MBWR/WR2/AFC/FVR tools at: http://krom.reveur.de
<<

The Dark Lord

User avatar

King Karolus Servant

Posts: 2154

Joined: 29 Aug 2007, 22:00

KaM Skill Level: Veteran

Location: In his dark thunderstormy castle

Post 14 Apr 2013, 09:14

Re: Dynamic Script Usage

It's working now, thanks. :)
Meanwhile I'm trying to use Actions.SetOverlayText to display a message for all players, e.g. "The Dark Lord has defeated the first attack wave!" I got this message working, but then I want to erase it again. How can I do this? I'm trying to overwrite the text with an empty string, but I want it to be delayed (lets say after 5 seconds).

Currently I have added this code:
  Code:
const DELAY = 50; var DelayedErase: Boolean; DelayedTime: Integer; procedure HideOverlayMsg; begin if (DelayedErase = true) and (DelayedTime = (States.GameTime + DELAY)) then begin Actions.SetOverlayText(0, States.Text(29)); Actions.SetOverlayText(1, States.Text(29)); Actions.SetOverlayText(2, States.Text(29)); Actions.SetOverlayText(3, States.Text(29)); DelayedErase := false; end; end;
DelayedErase becomes true after defeating the first attack wave.
It's a very dirty way of hiding the text, and it doesn't even work. :P I'm guessing my use of DelayedTime is wrong? HELP!!! :mrgreen:
Lewin? Krom? I desperately need a hand. ;)
<<

Lewin

User avatar

KaM Remake Developer

Posts: 3822

Joined: 16 Sep 2007, 22:00

KaM Skill Level: Skilled

ICQ: 269127056

Website: http://lewin.hodgman.id.au

Yahoo Messenger: lewinlewinhodgman

Location: Australia

Post 14 Apr 2013, 10:41

Re: Dynamic Script Usage

Lewin? Krom? I desperately need a hand. ;)
The problem is you never set DelayedTime to anything, you only ever compare its value to something else, so it will be uninitialised. When you set DelayedErase to true you need to set DelayedTime to something as well. But I'm not sure you have the condition right anyway:
(DelayedTime = (States.GameTime + DELAY))
should probably be:
(States.GameTime = DelayedTime)
Then when you show a message you can set:
DelayedTime := States.GameTime + DELAY

So that means "DelayedTime" means "What tick should we erase the message?" (now + 50 ticks). When you reach that tick you erase it.

Also, I noticed that you're not initialising any of your global variables. Given that your script works, it looks like the compiler initialises them all to zero or false anyway (or you're just lucky that the memory allocated to them was already zero), but it's good practice to initialise them. Add something like this:
  Code:
procedure OnMissionStart; begin Message0Sent := False; DelayedErase := False; .... end;
Then it's clear to someone reading your script what the global variables all start as.

Another tip, replace this:
  Code:
procedure ShowMsgToPlayers(aMsg: Integer); begin Actions.ShowMsg(0, States.Text(aMsg)) Actions.ShowMsg(1, States.Text(aMsg)) Actions.ShowMsg(2, States.Text(aMsg)) Actions.ShowMsg(3, States.Text(aMsg)) end;
with this:
  Code:
procedure ShowMsgToPlayers(aMsg: Integer); var I: Integer; begin for I := 0 to 3 do Actions.ShowMsg(I, States.Text(aMsg)); end;
There's so many places where you do something to all 4 players in your code which could be done using a for loop. It's easier to read, easier to change later, and harder to make mistakes (otherwise the code could be slightly different for each player and you might not notice).
Cheers,
Lewin.
<<

The Dark Lord

User avatar

King Karolus Servant

Posts: 2154

Joined: 29 Aug 2007, 22:00

KaM Skill Level: Veteran

Location: In his dark thunderstormy castle

Post 14 Apr 2013, 11:57

Re: Dynamic Script Usage

Thanks. Going through my nooby scripts probably takes some of your time, I'm sorry for that. But it's important for me to try it myself, otherwise I'll never learn it and I'd have to keep asking.
Lewin? Krom? I desperately need a hand. ;)
The problem is you never set DelayedTime to anything, you only ever compare its value to something else, so it will be uninitialised. When you set DelayedErase to true you need to set DelayedTime to something as well. But I'm not sure you have the condition right anyway:
(DelayedTime = (States.GameTime + DELAY))
should probably be:
(States.GameTime = DelayedTime)
Then when you show a message you can set:
DelayedTime := States.GameTime + DELAY

So that means "DelayedTime" means "What tick should we erase the message?" (now + 50 ticks). When you reach that tick you erase it.
I'll try this, thanks.
Also, I noticed that you're not initialising any of your global variables. Given that your script works, it looks like the compiler initialises them all to zero or false anyway (or you're just lucky that the memory allocated to them was already zero), but it's good practice to initialise them. Add something like this:
  Code:
procedure OnMissionStart; begin Message0Sent := False; DelayedErase := False; .... end;
Then it's clear to someone reading your script what the global variables all start as.
Yes, I actually assumed they were all initialized false at the start. And it seems to work like that. :P
Another tip, replace this:
  Code:
procedure ShowMsgToPlayers(aMsg: Integer); begin Actions.ShowMsg(0, States.Text(aMsg)) Actions.ShowMsg(1, States.Text(aMsg)) Actions.ShowMsg(2, States.Text(aMsg)) Actions.ShowMsg(3, States.Text(aMsg)) end;
with this:
  Code:
procedure ShowMsgToPlayers(aMsg: Integer); var I: Integer; begin for I := 0 to 3 do Actions.ShowMsg(I, States.Text(aMsg)); end;
There's so many places where you do something to all 4 players in your code which could be done using a for loop. It's easier to read, easier to change later, and harder to make mistakes (otherwise the code could be slightly different for each player and you might not notice).
Ah yes, I wanted to do something like this but tried something like "Actions.ShowMsg((0; 1; 2; 3), States.Text(aMsg))" but that didn't work. :P
<<

Lewin

User avatar

KaM Remake Developer

Posts: 3822

Joined: 16 Sep 2007, 22:00

KaM Skill Level: Skilled

ICQ: 269127056

Website: http://lewin.hodgman.id.au

Yahoo Messenger: lewinlewinhodgman

Location: Australia

Post 14 Apr 2013, 12:14

Re: Dynamic Script Usage

I'm quite happy to help, hopefully other people learn from this too because it's on the forum :)
A few more hints:
- Use States.PlayerEnabled to not do the attack waves for players who were not selected in the lobby (otherwise you get a big pile up of soldiers for those players)
- Use OnHouseDestroyed to detect when the tower is destroyed and Actions.PlayerDefeat to make them lose
- Don't spawn/launch attack waves if the player's tower is already destroyed (causes lag while the units try to find a place to stand near the tower)
- Use Actions.GroupOrderAttackHouse instead of AI attacks (more efficient and more logical to keep stuff in the .script rather than .dat)

Let me know if you need any more help :)
Cheers,
Lewin.
<<

The Dark Lord

User avatar

King Karolus Servant

Posts: 2154

Joined: 29 Aug 2007, 22:00

KaM Skill Level: Veteran

Location: In his dark thunderstormy castle

Post 14 Apr 2013, 12:40

Re: Dynamic Script Usage

I certainly do need more help. :P Deleting that message still doesn't work. Could it be because if I say States.GameTime = DelayedTime, then DelayedTime := States.GameTime + DELAY will never happen because it is actually saying States.GameTime = States.GameTime + DELAY, which is something like 5 = 5 + 1 (which obviously can never be true)? If so, then how can I 'delay' something properly?

Also, I noticed a 'bug' (which should be fixed if I use States.PlayerEnabled I guess): players that aren't in the game still receive troops, but they are invisible (although they DO appear on the minimap, and I can click on them to attack them).

Another issue that I need to address, is the tower itself. Players will get messages that it's not occupied. Since it will never be occupied, that might get annoying after a while. :mrgreen: Is there a way to fix this?
<<

Lewin

User avatar

KaM Remake Developer

Posts: 3822

Joined: 16 Sep 2007, 22:00

KaM Skill Level: Skilled

ICQ: 269127056

Website: http://lewin.hodgman.id.au

Yahoo Messenger: lewinlewinhodgman

Location: Australia

Post 14 Apr 2013, 14:33

Re: Dynamic Script Usage

Only set "DelayedTime := States.GameTime + DELAY" at the moment you display the message, the same place where you reward the player with wares. That means it will only happen once. Lets say it's tick 100 when the player defeats the attack wave. The player is given his reward, the message is displayed, and we set DelayedTime to 150 (States.GameTime + DELAY). Then when we get to tick 150, States.GameTime = DelayedTime so the message will be erased.

I'm not sure what you mean about invisible troops. For me the players who aren't in the game still receive troops but they ARE visible, they just stand there with no tower to go attack. What did you do to make them invisible?

Yes, we might need a way to disable "not occupied" messages for certain houses. I can imagine other scripted missions where they would be a useful feature, so I'll add it to the list.
<<

The Dark Lord

User avatar

King Karolus Servant

Posts: 2154

Joined: 29 Aug 2007, 22:00

KaM Skill Level: Veteran

Location: In his dark thunderstormy castle

Post 14 Apr 2013, 15:19

Re: Dynamic Script Usage

AWWWW YEAH! A simple 'HideOverlayMsg;' after OnTick solved everything... Didn't know I had to call upon a procedure. Oops.
I'm not sure what you mean about invisible troops. For me the players who aren't in the game still receive troops but they ARE visible, they just stand there with no tower to go attack. What did you do to make them invisible?
I mean exactly what I said: they are really invisible. :P I did nothing to make them invisible, they just are... Could it be related to the SET_USER_PLAYER issue (since you didn't have trouble with that either, but I had)?
<<

Bence791

Knight

Posts: 618

Joined: 20 Jul 2012, 20:25

KaM Skill Level: Beginner

Location: Hungary

Post 14 Apr 2013, 16:44

Re: Dynamic Script Usage

  Code:
procedure OnHouseLost(aHouseID: Integer); var Tower01: Integer; begin Tower01 := States.HouseAt(49, 78); if States.HouseDestroyed(Tower01) then Actions.GroupOrderWalkTo(Warriors01, 122, 57, 6); Actions.GroupOrderWalkTo(Knights01, 112, 49, 5); Actions.GroupOrderWalkTo(Crossbows01, 113, 55, 6); end;
I run my mission, and the game says: "Unknown identifier GROUPORDERWALKTO". What have I mistaken? Warriors01, Knights01 and Crossbows01:
  Code:
var Warriors01: Integer; var Knights01: Integer; var Crossbows01: Integer; procedure OnMissionStart; begin Warriors01 := States.GroupAt(53, 81); Knights01 := States.GroupAt(50, 77); Crossbows01 := States.GroupAt (55, 77); end;
If I have done something else wrongly, then please correct me :D As long as I saw, the Remake says what is wrong and I didn't get an error message about the variables. Only the stuff mentioned above (ID).
The Kamper is always taking my colour!

<<

Lewin

User avatar

KaM Remake Developer

Posts: 3822

Joined: 16 Sep 2007, 22:00

KaM Skill Level: Skilled

ICQ: 269127056

Website: http://lewin.hodgman.id.au

Yahoo Messenger: lewinlewinhodgman

Location: Australia

Post 14 Apr 2013, 16:52

Re: Dynamic Script Usage

AWWWW YEAH! A simple 'HideOverlayMsg;' after OnTick solved everything... Didn't know I had to call upon a procedure. Oops.
Procedures/functions defined in your script are just utilities that you can call from within your script. If you never call them, they will never be run ;)
I'm not sure what you mean about invisible troops. For me the players who aren't in the game still receive troops but they ARE visible, they just stand there with no tower to go attack. What did you do to make them invisible?
I mean exactly what I said: they are really invisible. :P I did nothing to make them invisible, they just are... Could it be related to the SET_USER_PLAYER issue (since you didn't have trouble with that either, but I had)?
That's really weird. The version you emailed to me didn't have invisible units. Could you send me the files which cause the units to be invisible, including the .mi file? (and tell me how you set up the lobby and what you did in game to get the invisible units)
I run my mission, and the game says: "Unknown identifier GROUPORDERWALKTO". What have I mistaken?.
That error is trying to tell you that the game doesn't know about a procedure called "GroupOrderWalkTo". If you made a mistake with the parameters the error would be different. It can't find it because it should be "GroupOrderWalk". There's no "To" :P
<<

The Dark Lord

User avatar

King Karolus Servant

Posts: 2154

Joined: 29 Aug 2007, 22:00

KaM Skill Level: Veteran

Location: In his dark thunderstormy castle

Post 14 Apr 2013, 17:04

Re: Dynamic Script Usage

I'm not sure what you mean about invisible troops. For me the players who aren't in the game still receive troops but they ARE visible, they just stand there with no tower to go attack. What did you do to make them invisible?
I mean exactly what I said: they are really invisible. :P I did nothing to make them invisible, they just are... Could it be related to the SET_USER_PLAYER issue (since you didn't have trouble with that either, but I had)?
That's really weird. The version you emailed to me didn't have invisible units. Could you send me the files which cause the units to be invisible, including the .mi file? (and tell me how you set up the lobby and what you did in game to get the invisible units)
I put myself on location 1, and an AI player on location 5. I didn't set teams. I played with 3x speed, but it also happens at normal speed. And I played with black, while the AI had a random colour.
I didn't do anything special in game, just trained 10 recruits and turned them into crossbowmen.

Return to “Dynamic Scripting”

Who is online

Users browsing this forum: No registered users and 16 guests