Page 2 of 2
Re: Script changes in RC3
PostPosted: 05 Jun 2013, 06:22
by Lewin
PascalScript certainly has its limitations, but I didn't expect one this significant. As far as I can see there is no way to add a variable into a set. I've tried everything I can think of, but even the most simple code like this doesn't work:
- Code:
type
TDay = (dMon, dTue, dWed, dThu, dFri, dSat, dSun);
procedure OnMissionStart;
var
b: TDay;
a: set of TDay;
begin
b := dWed;
a := [dMon];
a := a + [b];
end;
When you use "mySet := mySet + [myVar]" it doesn't work because it is unable to interpret "[myVar]" as a set (it always treats that as a dynamic array I think). You can do "mySet := mySet + [123]" because it can handle creating a set of constants inline (123 is the constant in this case). It just can't handle creating sets from variables as far as I can see.
The other obvious way to do it is using the Include function (and Exclude for removing). Unfortunately these functions aren't defined by PascalScript.
I managed to define Include/Exclude myself after some hacking around in the compiler/runtime code (which is tricky because the compiler is over 15,000 lines and the runtime is over 12,000). I looked at making it be able to interpret "[myVar]" as a set but it looks like that won't be easier. Include/Exclude should be enough anyway. I'll discuss it with Krom, we can probably include these functions in the next release.
Re: Script changes in RC3
PostPosted: 05 Jun 2013, 06:44
by Siegfried
At least it's calming that it's not my own incompetence (again) that this does not work.
Well, I think you can skip fixing of this, I will find a way around (using arrays insted and padding them with -1).
@Krom
I did want to avoid the definition of a type that basically only is the same as the already natively existing byte.
But I've tried your suggestion and it does not work with variables of byte either.
I think Lewin's answer is correct then, the parser does not really know that the might be a set, not neccessarily an array. Which is strange still, because it knows that [2] might be a set.
Re: Script changes in RC3
PostPosted: 05 Jun 2013, 07:01
by Lewin
@Siegfried: I think it's actually more efficient to define your own type, since then the compiler knows it can contain a maximum of 8 elements and so the set can fit in just 1 byte (so there are 8 bits that represent whether each element of the set is enabled). If you have a "set of byte" it's actually using 32 bytes to represent the set, since it needs 256 bits. I don't think the PascalScript compiler takes advantage of this fact (it doesn't do a lot of optimisations), but Delphi/FPC might. Enumerations are mostly treated the same as a byte by the compiler in other cases anyway, as far as I know there's no performance cost to defining your own type rather than using a byte.
Re: Script changes in RC3
PostPosted: 05 Jun 2013, 07:18
by thunder
Hi!
I dont know exactly where can i address my question, but is there possibilities to write a sript what is give goldore to goldmountains or non renewable resources to the hills or coals to the empty fields?
I know that NON-renewable...
PS: imagine a goldmountain with 2tiles and 300goldoresXD
Re: Script changes in RC3
PostPosted: 05 Jun 2013, 08:37
by Lewin
@Thunder: Not yet, we do plan to add commands that let you query/manipulate terrain eventually, but not for this release. Lots of interesting things would be possible like "rebuilding" bridges, infinite resources, etc. There are some challenges to sort out, like making sure you can't change the terrain that a unit is standing on (which would cause an instant crash)
EDIT:
Just to keep you updated on the issues Siegfried pointed out, we have made the following changes to PascalScript
1. You can now iterate over an enumeration, for example:
- Code:
type
TDay = (dMon, dTue, dWed, dThu, dFri, dSat, dSun);
procedure OnMissionStart;
var i: TDay;
begin
for i:=dTue to dSat do
something;
end;
2. Added standard Pascal functions Include and Exclude for adding/removing variables from sets:
- Code:
type
TDay = (dMon, dTue, dWed, dThu, dFri, dSat, dSun);
procedure OnMissionStart;
var
MyDay: TDay;
MySet: set of TDay;
begin
MyDay := dMon;
MySet := [dTue, dThu];
Include(MySet, MyDay); //MySet now contains: [dMon, dTue, dThu]
MyDay := dThu;
Exclude(MySet, MyDay); //MySet now contains: [dMon, dTue]
Include(MySet, dSat); //MySet now contains: [dMon, dTue, dSat]
Exclude(MySet, dTue); //MySet now contains: [dMon, dSat]
end;
We have submitted these code changes to PascalScript's Gitgub, hopefully they'll include them so other developers using PascalScript can benefit from them too

Re: Script changes in RC3
PostPosted: 05 Jun 2013, 09:41
by Siegfried
Excellent.
Is it possible that you do a quick compilation and send the exe files over to me so I can work with this?
Re: Script changes in RC3
PostPosted: 11 Jun 2013, 20:12
by Siegfried
I know it's a double post, but I found something out:
- Code:
type
loc_type = (undef, p1, p2, p3, p4, p5, p6, p7, p8);
var
TEAM_MEMBERS: array[1..8] of set of loc_type;
procedure UpdateTextDEBUG;
var
k: integer;
lt: loc_type;
begin
for k := 1 to 8 do
begin
for lt := p1 to p8 do if (lt IN TEAM_MEMBERS[k]) then DoSomething;
end;
end;
This works. Notice that inside the 'for lt'-loop, everything is done in one step.
Change that and it gives the array boundary error.
- Code:
type
loc_type = (undef, p1, p2, p3, p4, p5, p6, p7, p8);
var
TEAM_MEMBERS: array[1..8] of set of loc_type;
procedure UpdateTextDEBUG;
var
k: integer;
lts: set of loc_type;
lt: loc_type;
begin
for k := 1 to 8 do
begin
lts := TEAM_MEMBERS[k];
for lt := p1 to p8 do if (lt IN lts) then DoSomething;
end;
end;
So if you're using sets and encounter those index-errors you have no idea where they might come from, think of this. It's enough that it has cost me one hour, no need to waste that time for other people, too.

Re: Script changes in RC3
PostPosted: 12 Jun 2013, 01:18
by Lewin
That SHOULD work and WOULD work in Delphi/Lazarus, there's nothing actually wrong with it. However, once you define your set as your own type, PascalScript accepts it:
- Code:
type
loc_type = (undef, p1, p2, p3, p4, p5, p6, p7, p8);
TLocSet = set of loc_type;
var
TEAM_MEMBERS: array[1..8] of TLocSet;
procedure OnMissionStart;
begin
TEAM_MEMBERS[3] := [p5, p1];
end;
procedure OnTick;
var
k: integer;
lts: TLocSet;
lt: loc_type;
begin
for k := 1 to 8 do
begin
lts := TEAM_MEMBERS[k];
for lt := p1 to p8 do if (lt IN lts) then
Actions.ShowMsg(-1, 'lt IN lts');
end;
end;
Unfortunately that seems to be a limitation of PascalScript, it can't tell that two sets are the same type unless you make them a separate data type. So I suggest you do that with your sets from now on if you plan to use them in multiple places. The other annoying thing is that the error occurs at runtime rather than at compile time...
By the way, the error I got was "type mismatch" (meaning it thinks "lts" is not the same type as "TEAM_MEMBERS[k]"), but you said you got a bounds error? That could be a different problem, although the code above works.
Re: Script changes in RC3
PostPosted: 12 Jun 2013, 08:20
by Siegfried
By the way, the error I got was "type mismatch" (meaning it thinks "lts" is not the same type as "TEAM_MEMBERS[k]"), but you said you got a bounds error? That could be a different problem, although the code above works.
Well, it's possible, but as soon as I've merged everything, it worked as intended. Strange things happen
I can just hope to find that bug before I'm shipping my code.
You can now use the follow types as global variables:
I may be mistaken again, but multi-dimenstional arrays don't work as I thought.
I thought, a multi-dimensional array would be something like this:
- Code:
array2d = array[1..2,1..3] of integer;
array2d[2,3] := 0;
What actually works is known to me as an array of arrays:
- Code:
array2step = array[1..2] of array[1..3] of integer;
array2step[2][3] := 0;
Re: Script changes in RC3
PostPosted: 12 Jun 2013, 12:33
by Lewin
Yes, I also found that PascalScript doesn't support the "," (array[1..2,1..3]) syntax of Pascal for some reason... But it's not much more effort to write "array[1..2] of array[1..3] of integer" (a multidimensional array is just an array of arrays underneath anyway)
Re: Script changes in RC3
PostPosted: 12 Jun 2013, 19:54
by Siegfried
Well, we should not forget that this is meant to be a script language. So it aims at small things that can be manipulated at runtime.
What we are actually doing is way more than that. We're programming, with depending functions, complex data structures and so on. That's way more than just scripting. So nothing to complain about
The array of arrays is not about the effort, it's about the looks
- Code:
IntToStr(SCORES[PLAYER_OWNS_FLAG[flg]][flg])

Re: Script changes in RC3
PostPosted: 01 Jul 2013, 12:13
by The Dark Lord
The new message system causes some trouble for me. It is impossible to send a message like 'The enemy's troops are coming'. It gives a 'comma expected' error, because it sees the ' between enemy and s as the end of the message... I could change the text, but I think it's rather stupid that it's impossible to use possessive adjectives. What about using " instead?
Re: Script changes in RC3
PostPosted: 01 Jul 2013, 12:23
by sado1
Lewin will probably tell you what exactly you need to do, but my guesses so far, for using an apostrophe, are:
- use \'
- use <'>
- include the text with an apostrophe in the libx file
Not sure if any of these will work though

Re: Script changes in RC3
PostPosted: 01 Jul 2013, 12:27
by Krom
When you want to have a ' in your script you need to type it like so: varname := 'Don''t go there'; //Placing two ' symbols together
Re: Script changes in RC3
PostPosted: 01 Jul 2013, 12:32
by Lewin
Text like "The enemy's troops are coming" should really go in the LIBX file anyway so it can be translated, but if you do want it in the script for some reason do what Krom said.