Map Database  •  FAQ  •  RSS  •  Login

New Dynamic Script Ideas

<<

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 28 May 2013, 02:06

Re: New Dynamic Script Ideas

What about something like Actions.ShareVision(Player1, Player2, True/False)? That would be much more flexible and would allow to change vision during the game (as I had planned :P). Static script is... static. It could work but won't be as nice (and useful).
That won't work well because the revealed map areas are synced between allies, and there's currently no way to undo that. So when you set ShareVision to false you will still see everything your ally already shared with you (but not anything new he sees), which means you will always see what your ally sees at the start (his map revealers in the .dat script will be shared with you even if you change it in OnMissionStart)
<<

Krom

User avatar

Knights Province Developer

Posts: 3280

Joined: 09 May 2006, 22:00

KaM Skill Level: Fair

Location: Russia

Post 28 May 2013, 06:02

Re: New Dynamic Script Ideas

If you dynamically script a map that is quite fixable by explicitly adding FOW circle over opponents village (say radius 40) right after unsharing the vision.
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
<<

Vas

User avatar

Rogue

Posts: 55

Joined: 17 Sep 2010, 22:00

Post 29 May 2013, 11:20

Re: New Dynamic Script Ideas

I would like to have:
  Code:
Actions.SetScreenPosition(iPlayer, iX, iY);
Function which centers the screen at a definite position.
  Code:
Actions.ShowPosMsg(iPlayer, sText, iX, iY);
Text message with 'Go To' button to the defined position.

:)

I have problems with Actions.UnitOrderWalk(unit, x, y);. The units don't walk (function returns false), but they are on idle...
<<

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 29 May 2013, 12:48

Re: New Dynamic Script Ideas

If you dynamically script a map that is quite fixable by explicitly adding FOW circle over opponents village (say radius 40) right after unsharing the vision.
True, I guess it's unimportant then and we can implement it as a dynamic script command.

@Vas:
- Center screen of the player kind of seems like a bad idea, I usually find it annoying in RTS games when I'm playing and the game suddenly grabs my screen and places it somewhere when I was in the middle of something. There would be no warning, you could even be scrolling across the map and suddenly it jumps. Also there'd be no way to stop the player looking away without a proper cutscene mode. I think we might eventually implement a cutscene mode where you can remove control from the player and move his screen around (possibly even with a command like "move screen to XY over 5 seconds" and it moves it smoothly from the current position). It should also indicate to the player somehow that the game is in a cutscene so he can't control it. What do you think?
- ShowPosMsg is a good idea, I've added it to the proposals list :)
- UnitOrderWalk: Can you send us an example? (with steps to reproduce). I didn't test it so there could be issues with that command. Although note that "idle" means not walking or being pushed, just standing there with nothing to do at all (moving units when they are doing something could cause all sorts of issues, so they have to be completely idle)
<<

Vas

User avatar

Rogue

Posts: 55

Joined: 17 Sep 2010, 22:00

Post 29 May 2013, 13:58

Re: New Dynamic Script Ideas

Okay good arguments. That would be like in C&C how you've wrote it. Could be nice.
Although note that "idle" means not walking or being pushed, just standing there with nothing to do at all (moving units when they are doing something could [*]cause all sorts of issues, so they have to be completely idle)
:D Yes of cause! They are just standig there with question marks over their heads.. I send you the mission via mail.
<<

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 31 May 2013, 04:22

Re: New Dynamic Script Ideas

:D Yes of cause! They are just standig there with question marks over their heads.. I send you the mission via mail.
There was a problem which caused Actions.UnitOrderWalk not to work on newly created units (they were locked for 10 ticks after being created). It's fixed now and your mission appears to work correctly (after I defeat the troops the serfs and labourers are created and walk down to my storehouse) :)
Thanks for the report!
<<

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

Re: New Dynamic Script Ideas

Firstly a group means a collection of soldiers, one with a flag. If you split a group you get 2 groups. A group will always have one guy with a flag, and every guy with a flag in the game belongs to a different group.
A GroupID in script is a pointer or handle which lets you access a single group (only one). It lets you tell the game which group you are referring to.

Army1 = Cavalry1 + Sword1: No, that will just give you an invalid ID in the Army1 variable. A group ID only stores 1 group.

"And what would happen if I give every group the same ID and use that ID later on?" - You can't give a group an ID. The engine assigns each group an ID when they are created and that ID never changes, unless the group gets linked into another one or all the soldiers in the group die (either way that group is considered dead because it has no members left).

Imagine you are the game engine, every time a group is created you hand the group a piece of paper with a number written on it (first group gets 1, second group gets 2, etc.). That number uniquely identifies the group, and you tell the script what the ID is if the group was created using Actions.GiveGroup. So when the script tells you "group 5 move to 57,23" you can find the group with ID 5, and tell them to move. That's all a group ID is, it makes it possible for the script and the game to identify a specific group.

If you want to store a collection of groups you can use an array to store every group's ID, which I'll show you in my example below.

"There are no real attack scripts" - I plan to add a function named something like "PlayerGetClosest###" (groups/houses/units). Then you can do your attack like this:

  Code:
var AIArmy: array of Integer; procedure OnMissionStart; begin SetLength(AIArmy, 4); //Allocate space to store 4 items (groups in this case) AIArmy[0] := Actions.GiveGroup(...); //Could also use GroupAt if you'd prefer to create the groups in the .DAT AIArmy[1] := Actions.GiveGroup(...); AIArmy[2] := Actions.GiveGroup(...); AIArmy[3] := Actions.GiveGroup(...); end; procedure OnTick; var TargetUnit: Integer; I: Integer; begin //AI gets reinforcements after 1 minute if States.GameTime = 600 then begin SetLength(AIArmy, Length(AIArmy)+2); //Allocate space to store 2 extra items //The last item in the array will be Length(AIArmy)-1, and the second last item -2 //these are the extra 2 spaces we added, in this case 4 and 5 because the array length is now 6 and before it was 4 AIArmy[Length(AIArmy)-2] := Actions.GiveGroup(...); AIArmy[Length(AIArmy)-1] := Actions.GiveGroup(...); end; //Player's closest unit is attacked after 10 minutes if States.GameTime = 6000 then begin TargetUnit := States.GetClosestUnit(0, 20, 30); //Player 0's closest unit to 20, 30 if TargetUnit <> -1 then //All the player's units might be dead for I:=0 to Length(AIArmy)-1 do if not States.GroupDead(AIArmy[I]) then Actions.GroupOrderAttackUnit(AIArmy[I], TargetUnit); end; end;
Note that using a dynamic (resizable) array as a global variable won't work in r5116, but it will work in the next RC.
You don't have to use the array if you don't want to, I was just showing what's possible. You could also do something like:
AIGroup1 := Actions.GiveGroup(...);
AIGroup2 := Actions.GiveGroup(...);
AIGroup3 := Actions.GiveGroup(...);
and
Actions.GroupOrderAttackUnit(AIGroup1, TargetUnit);
Actions.GroupOrderAttackUnit(AIGroup2, TargetUnit);
Actions.GroupOrderAttackUnit(AIGroup3, TargetUnit);

Cheers,
Lewin.
What about this 'PlayerGetClosest(...)' or 'GetClosestUnit'? :)
<<

Siegfried

User avatar

Knight

Posts: 494

Joined: 24 Jul 2009, 22:00

Post 18 Jun 2013, 22:34

Re: New Dynamic Script Ideas

What about this 'PlayerGetClosest(...)' or 'GetClosestUnit'? :)
That is actually possible with the current means.

You get the x & y-coordiantes of the current unit with 'States.UnitPositionX'.

Then you can either go in spirals around this and stop a the very first 'States.UnitAt > -1'
Or you take the lazy way and do squares around the (x,y). Like this pseudo-code:
  Code:
FOR distance := 0 TO size_of_map div 2 DO FOR z := x - distance TO x + distance DO IF States.UnitAt(z, y - distance) OR States.UnitAt(z, y + distance) > -1 THEN return unitID and break loop FOR z := y - distance TO y + distance DO IF States.UnitAt(x - distance, z) OR States.UnitAt(y + distance, z) > -1 THEN return unitID and break loop
an there you have the id of your closest unit :)
<<

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 18 Jun 2013, 22:39

Re: New Dynamic Script Ideas

Yes but Siegfried, you shouldn't forget that this is very hard for noobs like me. :P
<<

Maximilian Cervantes

Post 18 Jun 2013, 22:41

Re: New Dynamic Script Ideas

I really like the ideas for Dynamic Scripting and that you're planning to include the changing of ownership in future realeses it would be perfect for specializing missions, and the matches in general, especially if there's more than two players.
<<

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 19 Jun 2013, 02:15

Re: New Dynamic Script Ideas

Siegfried, that's a very inefficient method if you plan to scan the entire map. It's better to go through all the units/houses of that player and find the closest one, like this:
  Code:
function ClosestUnit(aPlayer, X, Y: Integer): Integer; var Units: array of Integer; i, BestDistanceSqr, ThisDistanceSqr: Integer; begin Result := -1; Units := States.PlayerGetAllUnits(aPlayer); for i:=0 to Length(Units) do begin //Using squares is more efficient than square roots and gives exactly the same result (Pythagoras) ThisDistanceSqr := Sqr(X-States.UnitPositionX(Units[i])) + Sqr(Y-States.UnitPositionY(Units[i])); if (Result = -1) or (ThisDistanceSqr < BestDistanceSqr) then begin BestDistanceSqr := ThisDistanceSqr; Result := Units[i]; end; end; end;
It wouldn't be hard to convert that for houses too. ClosestUnit won't be all that efficient when you have 400 units, but I doubt it will cause any noticeable lag (unless you're using it every tick)
<<

Siegfried

User avatar

Knight

Posts: 494

Joined: 24 Jul 2009, 22:00

Post 19 Jun 2013, 06:25

Re: New Dynamic Script Ideas

Yes but Siegfried, you shouldn't forget that this is very hard for noobs like me. :P
I did not want to be arrogant. It was shortly before I went to bed, so I was too tired to write the real code :)
Siegfried, that's a very inefficient method if you plan to scan the entire map. It's better to go through all the units/houses of that player and find the closest one, like this:
Well, that depends. Your solution has to cycle through all units all the time. So if you have 200 units, it has 200 api calls. That is more efficient if the distance between your units is larger than a few tiles.
If the units stand very close - like they do in a city or a group of troops - then my solution is not as bad as you said. In cities or armies, and if you plan to call this function regularly, then I would suggest to use mine, even though it deviates from the geometric best value by up to 40%. If you call it only a few times, then Lewins function will give you the correct result.

@TDL you must not forget that both functions don't give you a real closest unit in the sense, that the walking time is at minimum. Lewins function gives you the unit which has the smalles geometric distance. It could be possible that two units stand 5 tiles away from each other, but there is a mountain in between. So these units are geometrical closest, but they would need to go around the mountains which can take a while. A real closest unit with the shortest walking distance would need to calculate the pathfinding for each unit and does consume much CPU power.
<<

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 19 Jun 2013, 13:25

Re: New Dynamic Script Ideas

I assumed TDL wanted to use this to launch attacks and similar things, meaning your method would need to scan the entire map. But of course if you want to scan a small area your method is better :)
<<

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 20 Jun 2013, 18:23

Re: New Dynamic Script Ideas

That's right, I need this for an attack. Thanks for your answers. :) But how should/can I use this script? :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 21 Jun 2013, 02:24

Re: New Dynamic Script Ideas

That's right, I need this for an attack. Thanks for your answers. :) But how should/can I use this script? :P
In that case you'll want my solution not Siegfried's. Copy my function into your script so you can use it. Then lets say you have a group G and you want them to attack the closest unit of player P. Do this:

U := ClosestUnit(P, 12, 34); //Put the actual coordinates here
if U <> -1 then
Actions.GroupOrderAttackUnit(G, U);

You'll need "var U: Integer" defined in this procedure. Note that I check if a unit was found, since the player might have zero units.

Return to “Ideas / Suggestions”

Who is online

Users browsing this forum: No registered users and 8 guests