Map Database  •  FAQ  •  RSS  •  Login

Dynamic Script Usage Questions

<<

pawel95

Castle Guard Swordsman

Posts: 1912

Joined: 03 Oct 2008, 22:00

KaM Skill Level: Skilled

Location: "Pawel95" on Youtube.com

Post 11 Jun 2013, 13:41

Re: Dynamic Script Usage

Btw guys, have you played the campaign of vas? There is a mission: Mission 06. This mission works with thaaaaaaaaaaaaaaaaaaaaaaaaat many Scripts, like AI building at certain places, transforming units, "ship ariving(with storehouse placement)", Patrol of horses.....
So you shouldnt just copy any lines, but maybe it would help you(specialy Islar) to understand the commands and implement such similar command in your own mission :wink:
<<

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 11 Jun 2013, 14:14

Re: Dynamic Script Usage

@sado: Pseudo code (I won't write it so you can write it yourself):

procedure OnUnitTrained(Unit):
School := States.HouseAt(UnitPositionX(Unit), UnitPositionY(Unit) - 1); //1 tile above so it definitely hits the school, they might have started to walk out already
if School <> -1 then //School could have been destroyed at that exact moment or something, better to be safe
AddWareTo(School)

Regarding using other people's scripts, if you get explicit permission from the author then they can allow you to copy lines from their scripts, but you should probably cite it somewhere (have a comment saying "this was taken from Lewin's script with permission" or at the top of your file "part of this script taken from Lewin's work with permission" something similar. It goes without saying that any examples I post here (like the stuff above) you are free to use, unless it was modified from someone else's work. Taking someone's idea without permission is a bit of a grey area because ideas can be more generic, for example if someone made another script with exploding units after seeing that guy doing it here (without asking his permission) then it's hard to say if that's wrong or not, because it's just the idea. It would certainly be polite to cite in a comment "idea from Lewin" or whoever it was.

Looking at other people's scripts to learn things is definitely a good idea, but be aware that many of those people are also still learning and might make minor mistakes (a few places in his scripts Vas has "if something = true then", which could be replaced by "if something then"). Also people have different coding standards (indentation, formatting, commenting, etc.) which could teach you bad habits (I've tried to use good formatting in the scripts I wrote such as Annie and Coastal Encounter Scored)
<<

Tef

User avatar

Lance Carrier

Posts: 64

Joined: 15 Apr 2013, 15:12

KaM Skill Level: Skilled

Post 11 Jun 2013, 14:30

Re: Dynamic Script Usage

Can anyone think of a better way to make infinite gold without having to deal with serfs, food, inn etc.?
Depends on other assumptions and realism you want to have. Examples
- if you have the assumption the AI will/may not build demolished schools, you could use PlayerGetAllHouses only at the start of a mission, filter all the schools out and store them in a AllSchools array. Then, OnUnitTrained, search in this AllSchools array if the schools still exist and which one needs more gold.
- HouseAt(x,y) = school, as suggested by Lewin is another approach. However, making the cpu search 256x256 tiles on large maps is also some cpu work, I guess?
- since schools with infinite gold is non-realistic, you might as well skip the gold-adding to schools and just plop in new recruits in front of the school in a given interval, as long as the school exists.
- to remove some more realism: forget schools! Just draw a mountain with a magical cliff near the barracks. Then plop recruits in a interval in that cliff. Look, there you have your mad recruit savages from the magic mountain all wanting to fight you! (H) :mrgreen:
<<

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 11 Jun 2013, 14:39

Re: Dynamic Script Usage

- HouseAt(x,y) = school, as suggested by Lewin is another approach. However, making the cpu search 256x256 tiles on large maps is also some cpu work, I guess?
My script doesn't search the entire map because it knows where the school will be: It's just above the newly trained unit. That's assuming you only want to add gold to the school when a unit is trained, which should be the only requirement for infinite gold, since that's the time when the gold gets removed irreversibly (if you cancel the gold can be returned before the training is complete, but once OnUnitTrained happens it can't be cancelled)
<<

Tef

User avatar

Lance Carrier

Posts: 64

Joined: 15 Apr 2013, 15:12

KaM Skill Level: Skilled

Post 11 Jun 2013, 14:47

Re: Dynamic Script Usage

@ lewin: apologies. I was reading too quickly. Your solution now sounds like a pretty good idea! :)
<<

sado1

User avatar

Council Member

Posts: 1430

Joined: 21 May 2012, 19:13

KaM Skill Level: Skilled

Post 11 Jun 2013, 15:18

Re: Dynamic Script Usage

- since schools with infinite gold is non-realistic, you might as well skip the gold-adding to schools and just plop in new recruits in front of the school in a given interval, as long as the school exists.
- to remove some more realism: forget schools! Just draw a mountain with a magical cliff near the barracks. Then plop recruits in a interval in that cliff. Look, there you have your mad recruit savages from the magic mountain all wanting to fight you! (H) :mrgreen:
if I make too many recruits at once there might be a problem with getting the troops out of the barracks. If I get too many recruits as a whole, then they'll start coming out of the barracks because they're hungry, which might make quite a traffic jam. So, I think I'll just stick to Lewin's advice. I can't directly control the number of recruits yet (thats what I needed GiveRecruit for), but this solution is good enough. Thanks Lewin!

By the way (sorry for being a bit offtopic)... it's possible that I will want to lazily and shamelessly copy the Battle of Octumn script for my winning conditions. Was it done by Ben or Lewin? Either way, do I have your permission to use it?
<<

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 11 Jun 2013, 15:48

Re: Dynamic Script Usage

By the way (sorry for being a bit offtopic)... it's possible that I will want to lazily and shamelessly copy the Battle of Octumn script for my winning conditions. Was it done by Ben or Lewin? Either way, do I have your permission to use it?
It was done by me, and I give you permission to use it if you cite that it's written by me in a comment :)
<<

Islar

Pikeman

Posts: 180

Joined: 22 Apr 2013, 20:18

KaM Skill Level: Average

Location: The Netherlands

Post 11 Jun 2013, 17:41

Re: Dynamic Script Usage

Hi

i have this from the tutorial http://code.google.com/p/castlesand/wik ... icTutorial and i want it to use it to make the AI build a quarry after finishing a school. But i get an error saying ''Invalid number of parameters''
  Code:
procedure OnHouseBuilt(aHouseID: Integer); begin if States.HouseOwner(aHouseID) <> 3 then Exit; if (States.HouseType(aHouseID) = 13) then begin Actions.PlanAddHouse(14, 39, 94); Actions.PlanAddRoad(39, 95); Actions.PlanAddRoad(38, 95); Actions.PlanAddRoad(37, 95); end; end;
I only know how to use Ontick with if states.gametime = ... and OnMissionStart with some actions :$
<<

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 11 Jun 2013, 18:26

Re: Dynamic Script Usage

You're missing the player index in the PlanAdd commands. Put the player index as the first parameter of those commands (so for player 3 put: "Actions.PlanAddRoad(3, 39, 95);") and then it should work.
<<

Islar

Pikeman

Posts: 180

Joined: 22 Apr 2013, 20:18

KaM Skill Level: Average

Location: The Netherlands

Post 11 Jun 2013, 19:00

Re: Dynamic Script Usage

You're missing the player index in the PlanAdd commands. Put the player index as the first parameter of those commands (so for player 3 put: "Actions.PlanAddRoad(3, 39, 95);") and then it should work.
thank you. If i want to build a woodcutter house after building a two quarries, how do i make that? i don't want the AI to start building the woodcutter house when one of the two quarries is not finished. :$
<<

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 11 Jun 2013, 19:46

Re: Dynamic Script Usage

The easiest way would be to have a global variable boolean (true or false) to say whether you've placed the woodcutter yet. Put this at the top of your script (outside of any procedures):
var PlacedWoodcutter: Boolean;

Then in OnMissionStart put this line:
PlacedWoodcutter := False;

Then in OnHouseBuilt add this:
  Code:
if (States.HouseType(aHouseID) = 14) and not PlacedWoodcutter then begin PlacedWoodcutter := True; //Your code to place woodcutters goes here end;
"not PlacedWoodcutter" is just a neat was to write "(PlacedWoodcutter = False)"
How it works:
1. At the start of the mission, PlacedWoodcutter is set to false
2. When we notice the AI finishes a quarry, we check PlacedWoodcutter
3. If PlacedWoodcutter = True, we do nothing
4. If PlacedWoodcutter = False, we place the woodcutter and set PlacedWoodcutter to True, so when the next quarry is built, it will not place the woodcutter again.

And that's how you use global variables. They will store values for you which you can use from any place.
<<

Shadaoe

Knight

Posts: 584

Joined: 28 Jul 2011, 22:00

Website: https://www.youtube.com/user/KaMRemake

Post 12 Jun 2013, 14:45

Re: Dynamic Script Usage

I don't manage to get Actions.UnitOrderWalk to work :
First I store many things in a 2 dimension array thanks to a procedure called on mission start. Here is an exemple for 1 unit :
  Code:
RANDOMWALKERS[0][0] := States.UnitAt(166, 4); //get the unit ID RANDOMWALKERS[0][1] := 163; //x minimum RANDOMWALKERS[0][2] := 174; //x maximum RANDOMWALKERS[0][3] := 2; //y minimum RANDOMWALKERS[0][4] := 10; //y maximum RANDOMWALKERS[0][5] := 2; //Don't pay attention to this (number of 5 seconds between random walks(ex : 2 = 10 seconds))
Then every 5 seconds I call a procedure doing this (I cut the unnecessary part, there are many other things to make the process more natural in game) :
  Code:
for i:= 0 to temporaryNumber-1 do begin Actions.UnitOrderWalk(RANDOMWALKERS[i][0], RANDOMWALKERS[i][1]+States.KaMRandomI(RANDOMWALKERS[i][2] - RANDOMWALKERS[i][1]), RANDOMWALKERS[i][3]+States.KaMRandomI(RANDOMWALKERS[i][4] - RANDOMWALKERS[i][3])); end;
It always returns false, however all the units are idle and the terrain is walkable, maybe I didn't understand how UnitOrderWalk works ?
I even tested with a constant x and a constant y to check but no one moves :(
Thanks in advance.
<<

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 12 Jun 2013, 15:41

Re: Dynamic Script Usage

Please use a record instead of that two dimensional array, it's much neater:
  Code:
type TRandomWalker = record UnitID: Integer; xMin, xMax, yMin, yMax: Integer; SecsBetweenWalks: Integer; end; //Not sure what kind of array you want here var RANDOMWALKERS: array[0..9] of TRandomWalker; //Your code: RANDOMWALKERS[0].UnitID := States.UnitAt(166, 4); RANDOMWALKERS[0].xMin := 163; RANDOMWALKERS[0].xMax := 174; RANDOMWALKERS[0].yMin := 2; RANDOMWALKERS[0].yMax := 10; RANDOMWALKERS[0].SecsBetweenWalks := 2; //Don't pay attention to this (number of 5 seconds between random walks(ex : 2 = 10 seconds))
Get the idea?

As to why it's not working, that's hard to say without seeing more of the context. What kind of unit is it? Animals can never be ordered to walk by the way. You should check the latest log file to see if your script is generating errors. If it's not, maybe send me a complete example so I can test it.
<<

Shadaoe

Knight

Posts: 584

Joined: 28 Jul 2011, 22:00

Website: https://www.youtube.com/user/KaMRemake

Post 12 Jun 2013, 16:05

Re: Dynamic Script Usage

Please use a record instead of that two dimensional array, it's much neater:
It looks much better indeed, I'm still unfamiliar with pascal concepts so I use the simple things, will change that.
As to why it's not working, that's hard to say without seeing more of the context. What kind of unit is it? Animals can never be ordered to walk by the way. You should check the latest log file to see if your script is generating errors. If it's not, maybe send me a complete example so I can test it.
I tried on both civilian units (serf and laborer) and a military unit and none work, I could send you the map and script but it would spoil you my contest mission :p I'll try to do a sample map and send it to you ;)
<<

Islar

Pikeman

Posts: 180

Joined: 22 Apr 2013, 20:18

KaM Skill Level: Average

Location: The Netherlands

Post 12 Jun 2013, 17:36

Re: Dynamic Script Usage

Then in OnMissionStart put this line:
PlacedWoodcutter := False;
do you mean like this?
  Code:
procedure OnMissionStart; PlacedWoodcutter := False; begin
or like this?
  Code:
procedure OnMissionStart; PlacedWoodcutter := False; begin
because by both of those i get an error with (4:1); begin expected. And i think (4:1); means 3 or 4 row? because that were i put this.

Return to “Dynamic Scripting”

Who is online

Users browsing this forum: No registered users and 11 guests