Page 1 of 1

Dynamic Script - Scripts

PostPosted: 04 Dec 2013, 11:36
by RandomLyrics
Hi, here everyone can put here own universal scripts. Mod: could you sticky this topic? So every mapmaker can fast and easily find searching script.

HEX COLORS: http://docwiki.embarcadero.com/RADStudi ... ors_in_VCL
TABLES: https://code.google.com/p/castlesand/wi ... ptsLookups
NATIVE SCRIPTS: https://code.google.com/p/castlesand/wi ... ptsDynamic

Test(a: integer) - use for every test if your script run, type any variables or just: 1, 2, 3... etc.
  Code:
procedure Test(a: integer); begin Actions.ShowMsg(-1, 'test: ' + inttostr(a)); end;
HouseTypeToWorkerType(aType: integer): integer - return worker type for specific house type.
  Code:
function HouseTypeToWorkerType(aType: integer): integer; begin case aType of 9: RESULT := 1; //woodcutters 14: RESULT := 10; //quarry 0: RESULT :=5; //sawmill 20:RESULT :=5; //armour workshop 19:RESULT :=5; //weapons workshop 8: RESULT := 4; //farm 16: RESULT := 3; //pig farm 22: RESULT := 6; // mill 12:RESULT :=3; //stables 25: RESULT := 7; // tannery 7: RESULT := 6; // bakery 24: RESULT := 7; // butchers 28: RESULT := 4; //vineyard 6: RESULT := 8; //fishers 3: RESULT := 2; // coal mine 4: RESULT := 2; // iron mine 5: RESULT := 2; // gold mine 15:RESULT :=12; //metallurgists 1:RESULT :=12; //iron smithy 10:RESULT := 11; //armour smithy 2:RESULT := 11; //weapon smithy 17:RESULT := 13; //watch tower 21: RESULT := 13; //barracks else RESULT := -1; end end;
WareTypeToSellPrice(aWareType: integer): integer - now its return gold price for my own map, but you can easily change the value its just a list of all wares.
  Code:
function WareTypeToSellPrice(aWareType: integer): integer; begin case aWareType of 0: RESULT:= 10; //tree trunk 1: RESULT:= 6; //stone 2: RESULT:= 15; // timber 3: RESULT:= 25; //iron ore 4: RESULT:= 25; //gold ore 5: RESULT:= 20; //coal 6: RESULT:= 50; //iron 7: RESULT:= 50; //gold 8: RESULT:= 30; //vine 9: RESULT:= 30; //corn 10: RESULT:= 30; //loaves 11: RESULT:= 30; //flour 12: RESULT:= 30; //leather 13: RESULT:= 30; //sausages 14: RESULT:= 50; //pig 15: RESULT:= 40; //skin 16: RESULT:= 40; //wooden shield 17: RESULT:= 40; //long shield 18: RESULT:= 40; //leather armour 19: RESULT:= 40; //iron armament 20: RESULT:= 40; //handaxe 21: RESULT:= 40; //long sword 22: RESULT:= 40; //lance 23: RESULT:= 40; //pike 24: RESULT:= 40; //longbow 25: RESULT:= 40; //crossbow 26: RESULT:= 40; //horse 27: RESULT:= 40; //fish else RESULT:= 0; end end;
HouseChangeOwner(aHouse, toPlayer: integer): integer - changing owner and return ID of new house.
  Code:
function HouseChangeOwner(aHouse, toPlayer: integer): integer; var t, x, y: integer; begin if (aHouse > 0) and InRange(toPlayer, 0, MAX_PLAYERS-1) then begin t:= States.HouseType(aHouse); x:= States.HousePositionX(aHouse); y:= States.HousePositionY(aHouse); Actions.HouseDestroy(aHouse, true); result:= Actions.GiveHouse(toPlayer, t, x, y); end else result:= -1; end;
CamJumpTo(aPlayer, X, Y: integer); - instalny jumps the players screen to X,Y.
  Code:
procedure CamJumpTo(aPlayer, X, Y: integer); begin if (X >= 0) and ( Y >= 0 ) and ( aPlayer >= 0 ) and ( aPlayer < 8 ) then begin Actions.CinematicStart(aPlayer); Actions.CinematicPanTo(aPlayer, X, Y, 0); Actions.CinematicEnd(aPlayer); end; end;
function ChangeUnitType(aUnit, aType: integer): integer - changes type of specific unit and returns ID of new unit.
  Code:
function ChangeUnitType(aUnit, aType: integer): integer; var owner, x, y: integer; begin if (aUnit > 0 ) and (aType >= 0 ) and (aType < 37) then begin owner:= States.UnitOwner(aUnit); x:= States.UnitPositionX(aUnit); y:= States.UnitPositionY(aUnit); Actions.UnitKill(aUnit, true); result:= States.GroupMember(Actions.GiveGroup(owner, aType, x, y, 4, 1, 1), 0); end else begin result:= -1; end; end;
//my older scripts - maybe some of them needs to be changed, but works 100%.
ClosestEnemyGroup(aPlayer, X, Y, radius:Integer): Integer - returns id of cloest enemy group. const MAX_PLAYERS = 0..8
  Code:
function ClosestEnemyGroup(aPlayer, X, Y, radius:Integer): Integer; var Groups: array of Integer; i, j, BestDistanceSqr, ThisDistanceSqr, DX, DY, fUnit: Integer; begin Result := -1; for j := 0 to MAX_PLAYERS-1 do begin if (States.PlayerEnabled(j) = true) and (States.PlayerDefeated(j) = false) and (j <> aPlayer) then begin if( States.PlayerAllianceCheck(aPlayer, j) <> true ) then begin Groups := States.PlayerGetAllGroups(j); for i := 0 to Length(Groups) -1 do begin fUnit:=States.GroupMember(Groups[i], 0); DX := X - States.UnitPositionX(fUnit); DY := Y - States.UnitPositionY(fUnit); ThisDistanceSqr := (DX*DX) + (DY*DY); if ((Abs(DX)<radius) and (Abs(DY)<radius)) and ((Result = -1) or (ThisDistanceSqr < BestDistanceSqr)) then begin BestDistanceSqr := ThisDistanceSqr; Result := Groups[i]; end; //end; end; end; end; end; end;

ClosestEnemyHouse(aPlayer, X, Y:Integer): Integer - returns ID of closest enemy house. const MAX_PLAYERS = 0..8
  Code:
function ClosestEnemyHouse(aPlayer, X, Y:Integer): Integer; var Houses: array of Integer; i, j, BestDistanceSqr, ThisDistanceSqr, DX, DY: Integer; begin Result := -1; for j := 0 to MAX_PLAYERS-1 do begin if (States.PlayerEnabled(j) = true) and (States.PlayerDefeated(j) = false) and (j <> aPlayer) then begin if( States.PlayerAllianceCheck(aPlayer, j) <> true ) then begin Houses := States.PlayerGetAllHouses(j); for i := 0 to Length(Houses) -1 do begin DX := X - States.HousePositionX(Houses[i]); DY := Y - States.HousePositionY(Houses[i]); ThisDistanceSqr := (DX*DX) + (DY*DY); if ((Result = -1) or (ThisDistanceSqr < BestDistanceSqr) ) and CheckObjectIDTable(Houses[i], PLAYERS_MAIN_TOWER) then begin BestDistanceSqr := ThisDistanceSqr; Result := Houses[i]; end; //end; end; end; end; end; end;
CheckObjectIDTable(aID: integer; aArray: array of integer): boolean - returns true if specific ID is in specific array. const NULL = -1;
  Code:
function CheckObjectIDTable(aID: integer; aArray: array of integer): boolean; var counter1: integer; begin for counter1:= 0 to Length(aArray)-1 do begin if( (aArray[counter1]<>NULL) and (aID <> NULL ) ) then begin if(aArray[counter1]=aID) then begin Result:= true; exit; end; end; end; end;

Re: Dynamic Script - Scripts

PostPosted: 05 Dec 2013, 11:19
by Skypper
i see that nobody reacts at this topic, but i think it is quite use full to collect basic scripts.
Thx RandomLyrics :)


aah sorry if you can remove this comment then ;)

Re: Dynamic Script - Scripts

PostPosted: 05 Dec 2013, 11:42
by RandomLyrics
i see that nobody reacts at this topic, but i think it is quite use full to collect basic scripts.
Thx RandomLyrics :)
Coz it only for scripts topic, here should be only script posts ;) but for now its okay. I will update this from time to time

Re: Dynamic Script - Scripts

PostPosted: 06 Dec 2013, 12:06
by RandomLyrics
InRange(aInt, aFrom, aTo: integer): boolean; - return true if value is higher or equal aFrom and value is lower or equal aTo.
  Code:
function InRange(aInt, aFrom, aTo: integer): boolean; begin Result := (aInt >= aFrom) and (aInt <= aTo); end;
States.StatUnitTypeCount = PlayerUnitTypeCount(aPlayer, aType: integer): integer; - return the number count of specific type of unit for specific player.
  Code:
function PlayerUnitTypeCount(aPlayer, aType: integer): integer; var aUnits: array of integer; c, j: integer; begin if InRange(aType, 0, 27) and InRange(aPlayer, 0, MAX_PLAYERS-1) then begin c:=0; aUnits:= States.PlayerGetAllUnits(aPlayer); for j:= 0 to Length(aUnits)-1 do begin if ( States.UnitType(aUnits[j]) = aType ) and ( States.UnitDead(aUnits[j]) = false ) then c:= c + 1; end; result:= c; end else result:= 0; end;

Re: Dynamic Script - Scripts

PostPosted: 06 Dec 2013, 12:16
by Lewin
InRange(aInt, aFrom, aTo: integer): boolean; - return true if value is higher or equal aFrom and value is lower or equal aTo.
  Code:
function InRange(aInt, aFrom, aTo: integer): boolean; begin if (aInt >= aFrom) and (aInt <= aTo) then result:= true else result:= false; end;
Very useful function, it's a shame that PascalScript doesn't provide this by default like Delphi and Lazarus do. Hint: boolean variables can be assigned from boolean statements, so you don't need that if-statement. It can be written like this:
  Code:
function InRange(aInt, aFrom, aTo: integer): boolean; begin Result := (aInt >= aFrom) and (aInt <= aTo); end;
PlayerUnitTypeCount(aPlayer, aType: integer): integer; - return the number count of specific type of unit for specific player.
  Code:
function PlayerUnitTypeCount(aPlayer, aType: integer): integer; var aUnits: array of integer; c, j: integer; begin if InRange(aType, 0, 27) and InRange(aPlayer, 0, MAX_PLAYERS-1) then begin c:=0; aUnits:= States.PlayerGetAllUnits(aPlayer); for j:= 0 to Length(aUnits)-1 do begin if ( States.UnitType(aUnits[j]) = aType ) and ( States.UnitDead(aUnits[j]) = false ) then c:= c + 1; end; result:= c; end else result:= 0; end;
States.StatUnitTypeCount should be equivalent to this, unless there is a bug in our game statistics code.

Re: Dynamic Script - Scripts

PostPosted: 06 Dec 2013, 12:28
by RandomLyrics
oh, there is smth like that. As i rember i use Stat and its not precision, it shows me non realistic values( when unit dies, spawn by script and i want to check it instantly), maybe because Stat is updating once per some ticks . Ill will check it, again in free time.
  Code:
function InRange(aInt, aFrom, aTo: integer): boolean; begin Result := (aInt >= aFrom) and (aInt <= aTo); end;
iv never learnt it xD thanks :)

Re: Dynamic Script - Scripts

PostPosted: 06 Dec 2013, 12:41
by Lewin
oh, there is smth like that. As i rember i use Stat and its not precision, it shows me non realistic values( when unit dies, spawn by script and i want to check it instantly), maybe because Stat is updating once per some ticks . Ill will check it, again in free time.
If you can send me a script where StatUnitTypeCount is not correct I'd be interested to fix it. Stats should always be updated instantly, there's no delay.

Re: Dynamic Script - Scripts

PostPosted: 06 Dec 2013, 12:52
by RandomLyrics
Ill check it by my self ,( i dont rember/know where i have this map with it xD) and if i notice smth wrong ill send it :)
HouseChangeOwner(aHouse, toPlayer: integer) - updated!
Topic updated!

Re: Dynamic Script - Scripts

PostPosted: 07 Dec 2013, 16:07
by RandomLyrics
ArrayHasTrue(aArray: array of boolean) - return true if any element of specific array is true.
  Code:
function ArrayHasTrue(aArray: array of boolean): boolean; var j: integer; begin result:= false; for j:= 0 to Length(aArray)-1 do begin if aArray[j] then begin result:= true; exit; end; end; end;
Can Moderator delete all non-code , posts? ill be very greatefull. it will keep this topic clear

Re: Dynamic Script - Scripts

PostPosted: 08 Dec 2013, 01:03
by Lewin
WareTypeToName - Only supporting English isn't very friendly to non-English speakers, it's better to put any text you use in your mission's LIBX file. However, in the next release there is a function States.WareTypeName that does this job but translated (using a markup that is decoded upon output). The same thing exists for houses and units. It makes sense since the game already has all of those names translated. Thanks RandomLyrics for suggesting it.

Re: Dynamic Script - Scripts

PostPosted: 08 Dec 2013, 13:02
by RandomLyrics
yea, i knew it. But i need this to my new map :)

Re: Dynamic Script - Scripts

PostPosted: 11 Jan 2014, 18:48
by RandomLyrics
ClosestHouse(aPlayer, aType, X, Y, radius: Integer) - returns ID of house. more specific form of States.ClosestHouse ( which is kinda useless without any other options ).
  Code:
function ClosestHouse(aPlayer, aType, X, Y, radius: Integer): Integer; var Houses: array of Integer; i, BestDistanceSqr, ThisDistanceSqr, DX, DY, fhouse: Integer; begin Result := -1; Houses := States.PlayerGetAllHouses(aPlayer); for i := 0 to Length(Houses) -1 do begin fhouse:=Houses[i]; DX := X - States.HousePositionX(fhouse); DY := Y - States.HousePositionY(fhouse); ThisDistanceSqr := (DX*DX) + (DY*DY); if ((Abs(DX)<radius) and (Abs(DY)<radius)) and ((Result = -1) or (ThisDistanceSqr < BestDistanceSqr)) and (aType = States.HouseType(fhouse)) then begin BestDistanceSqr := ThisDistanceSqr; Result := Houses[i]; end; end; end;
ClosestHouse(aPlayer, X, Y, radius: Integer) - without Type.
  Code:
function ClosestHouse(aPlayer, X, Y, radius: Integer): Integer; var Houses: array of Integer; i, BestDistanceSqr, ThisDistanceSqr, DX, DY, fhouse: Integer; begin Result := -1; Houses := States.PlayerGetAllHouses(aPlayer); for i := 0 to Length(Houses) -1 do begin fhouse:=Houses[i]; DX := X - States.HousePositionX(fhouse); DY := Y - States.HousePositionY(fhouse); ThisDistanceSqr := (DX*DX) + (DY*DY); if ((Abs(DX)<radius) and (Abs(DY)<radius)) and ((Result = -1) or (ThisDistanceSqr < BestDistanceSqr)) then begin BestDistanceSqr := ThisDistanceSqr; Result := Houses[i]; end; end; end;
HouseInArea(fType, X, Y, radius: integer): boolean; - returns true if house of specific type is in calling area.
  Code:
function HouseInArea(fType, X, Y, radius: integer): boolean; var j, k, c: integer; begin result:= false; c:= radius/2; if (X-c > 0) and (Y-c > 0 ) then begin for j:= X-c to X+c do begin for k:=Y-c to Y+c do begin if States.HouseAt(j, k) > 0 then begin if ( States.HouseType(States.HouseAt(j, k)) = fType ) then begin result:= true; exit; end; end; end; end; end; end;