Page 1 of 1

Choose Wisely - map idea

PostPosted: 11 Nov 2015, 16:38
by Nightry
Hi all :D
I have a map idea but need help with dynamic scripting :/
I think about a map in which the players choose units by moving the barbarian(or another unit,idk yet) to them and they spawn near the players barracks.It could be for 4 or 8 players.
Jednostki.png
Jadnostki 2.png
Next lvl units would unlock after reaching:
Lvl 1: 0-100 kills
Lvl 2: 101-200
Lvl 3: 201-300
The goal is to destroy the enemy barracks.


What do you think ?
Can someone do such a script or will it be too difficult :/ ?

Re: Choose Wisely - map idea

PostPosted: 11 Nov 2015, 18:34
by Ben
It wouldn't be hard to script at all. This reminds me of a the "blood" maps in AoE. The game mode can be made more interesting by making a center bonus/king of the hill bonus or something similar.

Re: Choose Wisely - map idea

PostPosted: 11 Nov 2015, 22:30
by Esthlos
Maybe it would be even easier and neater using a road plan instead of a barbarian?

Something like
(The 8 values under "const" have to be set as needed)
(Edit the code under "function aGetUnitLevel" if you want to add or change the levels)
  Code:
const cNeutralPlayer = 0; //The id of the player whose units act as a placeholder in the selection area; player 1's id is 0, player 2's is 1, etc cSpawnDelay = 0; //Ticks to skip between spawns; 1 tick equals 0,1 seconds cKillsPerLevel = 100; //After how many kills your level increases cMaxLevel = 3; //Highest level achievable //Limits of the selection area: cAreaXMin = 0; //The X coordinate of the leftmost edge cAreaXMax = 300; //The X coordinate of the rightmost edge cAreaYMin = 0; //The Y coordinate of the top edge cAreaYMax = 300; //The Y coordinate of the bottom edge ////////////////////////////////////////////////////////// var aChoiceLoc: array of Record aX, aY, aUnit, aLevel, aBX, aBY: Integer; end; aDelay: Integer; function aGetUnitLevel(aType: Integer): Integer; begin result := cMaxLevel+1; // Skip unforeseen units case aType of 24, 25, 27: result := 1; 14, 15, 17, 19, 21: result := 2; 16, 18, 20, 22, 26: result := 3; end; end; procedure OnMissionStart; var i, i2, iHouses: Integer; begin SetLength(aChoiceLoc, States.LocationCount); for i := 0 to States.LocationCount-1 do begin aChoiceLoc[i].aUnit := -1; aChoiceLoc[i].aLevel := 1; iHouses := States.PlayerGetAllHouses(i); for i2 := 0 to Length(iHouses)-1 do if States.HouseType(iHouses[i2]) = 21 then begin aChoiceLoc[i].aBX := States.HousePositionX(iHouses[i2]); aChoiceLoc[i].aBY := States.HousePositionY(iHouses[i2])+1; end; end; Actions.ShowMsg(-1, 'Place a Road plan near the unit you want to spawn; as you level up, you'll gain access to more powerful spawns.'); end; procedure OnPlanRoadPlaced(aIndex, X, Y: Integer); var iUnits: array of Integer; i, iDist, iDistBest: Integer; begin if (X < cAreaXMin) OR (X > cAreaXMax) then Exit; if (Y < cAreaYMin) OR (Y > cAreaYMax) then Exit; if aChoiceLoc[aIndex].aUnit > -1 then Actions.PlanRemove(aIndex, aChoiceLoc[aIndex].aX, aChoiceLoc[aIndex].aY); aChoiceLoc[aIndex].aX := X; aChoiceLoc[aIndex].aX := Y; iUnits := States.PlayerGetAllUnits(cNeutralPlayer); iDistBest := -1; for i := 0 to Length(iUnits)-1 do if (aGetUnitLevel(States.UnitType(iUnits[i])) <= aChoiceLoc[aIndex].aLevel) then begin iDist := (X-States.UnitPositionX(iUnits[i]))*(X-States.UnitPositionX(iUnits[i]))+(Y-States.UnitPositionY(iUnits[i]))*(Y-States.UnitPositionY(iUnits[i])); if (iDist < iDistBest) OR (iDistBest = -1) then begin iDistBest := iDist; aChoiceLoc[aIndex].aUnit := States.UnitType(iUnits[i]); end; end; end; procedure OnTick; var iUnits: array of Integer; i, iLevel: Integer; begin Inc(aDelay); if aDelay >= cSpawnDelay then begin aDelay := -1; for i := 0 to States.LocationCount-1 do if (aChoiceLoc[i].aUnit > -1) AND (aChoiceLoc[i].aLevel > 0) then begin if aChoiceLoc[i].aLevel < cMaxLevel then begin iLevel := (States.StatUnitKilledMultipleTypesCount(i, [14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27]) div (cKillsPerLevel+1)); if iLevel <> aChoiceLoc[i].aLevel then Actions.ShowMsg(i, 'Level up!||You can now choose a more powerful unit'); aChoiceLoc[i].aLevel := iLevel; end; Actions.GiveGroup(i, aChoiceLoc[i].aUnit, aChoiceLoc[i].aBX, aChoiceLoc[i].aBY, 4, 1, 1); end; //Making sure the placeholders don't starve iUnits := States.PlayerGetAllUnits(cNeutralPlayer); for i := 0 to Length(iUnits)-1 do UnitHungerSet(iUnits[i], States.UnitMaxHunger); end; end; procedure OnHouseDestroyed(aHouseID, aDestroyerIndex: Integer); var iP: Integer; begin if States.HouseType(aHouseID) = 21 then begin iP := States.HouseOwner(aHouseID); aChoiceLoc[iP].aLevel := -1; aChoiceLoc[iP].aUnit := -1; Actions.ShowMsg(iP, 'You have been defeated'); end; end;

Re: Choose Wisely - map idea

PostPosted: 13 Nov 2015, 05:38
by Nightry
Thanks ;)
You are right. I have played somethink like this in aom and aoe.
I will work on the map tomorrow.
Is the script for the road or barbarian choose method ??
Im really a noob in delphy but i will try xd

Re: Choose Wisely - map idea

PostPosted: 13 Nov 2015, 10:54
by Esthlos
Is the script for the road or barbarian choose method ??
Road.
It can be changed to Barbarian if you really want to, but I think it is neater and more efficient this way instead.

Re: Choose Wisely - map idea

PostPosted: 13 Nov 2015, 11:37
by Nightry
So I need to place the road near the unit i want spawn yep ?

Re: Choose Wisely - map idea

PostPosted: 13 Nov 2015, 12:58
by Esthlos
So I need to place the road near the unit i want spawn yep ?
Yup, the script looks for the closest placeholder unit when you place a road plan.

Please note that I didn't test the script, so there may be typos or other bugs.

Re: Choose Wisely - map idea

PostPosted: 13 Nov 2015, 15:14
by Nightry
Soo i want the selection area to be x=30 and y=20 from the left top corner in the editor.
  Code:
//Limits of the selection area: cAreaXMin = 30; //The X coordinate of the leftmost edge cAreaXMax = 0; //The X coordinate of the rightmost edge cAreaYMin = 20; //The Y coordinate of the top edge cAreaYMax = 0; //The Y coordinate of the bottom edge
Right ?

I also get this mistake :/
  Code:
2015-11-13 16:13:05.937 Script compile errors: [Error] (38:44): Type mismatch

Re: Choose Wisely - map idea

PostPosted: 13 Nov 2015, 21:24
by Esthlos
Right ?
Nope :P

The point [0;0] is at the top-left corner... in the editor you can see the coordinates of the tile your cursor is on :wink:
I also get this mistake :/
  Code:
2015-11-13 16:13:05.937 Script compile errors: [Error] (38:44): Type mismatch
As predicted, there were typos :$

Here the fixed code:
  Code:
const cNeutralPlayer = 0; //The id of the player whose units act as a placeholder in the selection area; player 1's id is 0, player 2's is 1, etc cSpawnDelay = 50; //Ticks to skip between spawns; 1 tick equals 0,1 seconds cKillsPerLevel = 100; //After how many kills your level increases cMaxLevel = 3; //Highest level achievable //Limits of the selection area: cAreaXMin = 0; //The X coordinate of the leftmost edge cAreaXMax = 30; //The X coordinate of the rightmost edge cAreaYMin = 0; //The Y coordinate of the top edge cAreaYMax = 20; //The Y coordinate of the bottom edge ////////////////////////////////////////////////////////// var aChoiceLoc: array of Record aX, aY, aUnit, aLevel, aEndLevel, aBX, aBY: Integer; end; aDelay: Integer; function aGetUnitLevel(aType: Integer): Integer; begin result := cMaxLevel+1; // Skip unforeseen units case aType of 24, 25, 27: result := 1; 14, 15, 17, 19, 21: result := 2; 16, 18, 20, 22, 26: result := 3; end; end; procedure aUpdateAvailable(aPlayer: Integer); var iUnits: array of Integer; i: Integer; begin iUnits := States.PlayerGetAllUnits(cNeutralPlayer); for i := 0 to Length(iUnits)-1 do if aGetUnitLevel(States.UnitType(iUnits[i])) <= aChoiceLoc[aPlayer].aLevel then Actions.PlanRemove(aPlayer, States.UnitPositionX(iUnits[i]), States.UnitPositionY(iUnits[i])) else Actions.PlanAddWinefield(aPlayer, States.UnitPositionX(iUnits[i]), States.UnitPositionY(iUnits[i])); end; procedure OnMissionStart; var i, i2: Integer; iHouses: array of Integer; begin SetLength(aChoiceLoc, States.LocationCount); for i := 0 to States.LocationCount-1 do if i <> cNeutralPlayer then begin aChoiceLoc[i].aUnit := -1; aChoiceLoc[i].aLevel := 1; aChoiceLoc[i].aEndLevel := 1; iHouses := States.PlayerGetAllHouses(i); for i2 := 0 to Length(iHouses)-1 do if States.HouseType(iHouses[i2]) = 21 then begin aChoiceLoc[i].aBX := States.HousePositionX(iHouses[i2]); aChoiceLoc[i].aBY := States.HousePositionY(iHouses[i2])+1; end; aUpdateAvailable(i); end; Actions.ShowMsg(-1, 'Place a Road plan near the unit you want to spawn; as you level up, you''ll gain access to more powerful spawns.'); aDelay := cSpawnDelay; end; procedure OnPlanRoadPlaced(aIndex, X, Y: Integer); var iUnits: array of Integer; i, iDist, iDistBest: Integer; begin if (X < cAreaXMin) OR (X > cAreaXMax) then Exit; if (Y < cAreaYMin) OR (Y > cAreaYMax) then Exit; if aChoiceLoc[aIndex].aUnit > -1 then Actions.PlanRemove(aIndex, aChoiceLoc[aIndex].aX, aChoiceLoc[aIndex].aY); aChoiceLoc[aIndex].aX := X; aChoiceLoc[aIndex].aY := Y; if aChoiceLoc[aIndex].aLevel = -1 then Exit; iUnits := States.PlayerGetAllUnits(cNeutralPlayer); iDistBest := -1; for i := 0 to Length(iUnits)-1 do if (aGetUnitLevel(States.UnitType(iUnits[i])) <= aChoiceLoc[aIndex].aLevel) then begin iDist := (X-States.UnitPositionX(iUnits[i]))*(X-States.UnitPositionX(iUnits[i]))+(Y-States.UnitPositionY(iUnits[i]))*(Y-States.UnitPositionY(iUnits[i])); if (iDist < iDistBest) OR (iDistBest = -1) then begin iDistBest := iDist; aChoiceLoc[aIndex].aUnit := States.UnitType(iUnits[i]); end; end; end; procedure OnPlanRoadRemoved(aIndex, X, Y: Integer); begin if (X = aChoiceLoc[aIndex].aX) AND (Y = aChoiceLoc[aIndex].aY) then aChoiceLoc[aIndex].aUnit := -1; end; procedure OnPlanWinefieldRemoved(aIndex, X, Y: Integer); begin if (X < cAreaXMin) OR (X > cAreaXMax) then Exit; if (Y < cAreaYMin) OR (Y > cAreaYMax) then Exit; Actions.PlanAddWinefield(aIndex, X, Y); end; procedure OnPlanWinefieldPlaced(aIndex, X, Y: Integer); begin if (X < cAreaXMin) OR (X > cAreaXMax) then Exit; if (Y < cAreaYMin) OR (Y > cAreaYMax) then Exit; Actions.PlanRemove(aIndex, X, Y); end; procedure OnPlanFieldRemoved(aIndex, X, Y: Integer); begin if (X < cAreaXMin) OR (X > cAreaXMax) then Exit; if (Y < cAreaYMin) OR (Y > cAreaYMax) then Exit; Actions.PlanAddField(aIndex, X, Y); end; procedure OnPlanFieldPlaced(aIndex, X, Y: Integer); begin if (X < cAreaXMin) OR (X > cAreaXMax) then Exit; if (Y < cAreaYMin) OR (Y > cAreaYMax) then Exit; Actions.PlanRemove(aIndex, X, Y); end; procedure OnTick; var iUnits: array of Integer; i, i2, iG, iG2, iLevel: Integer; begin Inc(aDelay); if aDelay >= cSpawnDelay then begin aDelay := -1; Actions.OverlayTextSet(-1, 'Killed units:'); for i := 0 to States.LocationCount-1 do if aChoiceLoc[i].aLevel <> 0 then begin i2 := States.StatUnitKilledMultipleTypesCount(i, [14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27]); if aChoiceLoc[i].aLevel <> -1 then begin if aChoiceLoc[i].aLevel < cMaxLevel then begin iLevel := (i2 div (cKillsPerLevel+1))+1; if iLevel > aChoiceLoc[i].aLevel then begin Actions.ShowMsg(i, 'Level '+IntToStr(iLevel)+'||You can now choose a more powerful unit!'); aChoiceLoc[i].aLevel := iLevel; aUpdateAvailable(i); end; end; aChoiceLoc[i].aEndLevel := aChoiceLoc[i].aLevel; end; //Overlay texts Actions.OverlayTextAppend(-1, '|'); if aChoiceLoc[i].aLevel = -1 then Actions.OverlayTextAppend(-1, '[$c2c2c2]'); Actions.OverlayTextAppend(-1, IntToStr(i2)+' by '); if aChoiceLoc[i].aLevel <> -1 then Actions.OverlayTextAppend(-1, '[$'+States.PlayerColorText(i)+']'); Actions.OverlayTextAppend(-1, States.PlayerName(i)); if aChoiceLoc[i].aLevel <> -1 then Actions.OverlayTextAppend(-1, '[]'); Actions.OverlayTextAppend(-1, '('+IntToStr(aChoiceLoc[i].aEndLevel)+')'); if aChoiceLoc[i].aLevel = -1 then Actions.OverlayTextAppend(-1, '[]'); if aChoiceLoc[i].aUnit > -1 then begin iG := Actions.GiveGroup(i, aChoiceLoc[i].aUnit, aChoiceLoc[i].aBX, aChoiceLoc[i].aBY, 0, 1, 1); if States.GroupAt(aChoiceLoc[i].aBX, aChoiceLoc[i].aBY) > 0 then begin iG2 := States.GroupAt(aChoiceLoc[i].aBX, aChoiceLoc[i].aBY); if (States.GroupOwner(iG2) = i) AND (iG2 <> iG) AND (States.GroupType(iG2) = States.GroupType(iG)) then begin Actions.GroupOrderLink(iG, iG2); Actions.GroupSetFormation(iG2, Round(Sqrt(States.GroupMemberCount(iG2)))); end; end; end; end; //Making sure the placeholders don't starve iUnits := States.PlayerGetAllUnits(cNeutralPlayer); for i := 0 to Length(iUnits)-1 do Actions.UnitHungerSet(iUnits[i], States.UnitMaxHunger); end; end; procedure OnHouseDestroyed(aHouseID, aDestroyerIndex: Integer); var iP: Integer; begin if States.HouseType(aHouseID) = 21 then begin iP := States.HouseOwner(aHouseID); aChoiceLoc[iP].aLevel := -1; aChoiceLoc[iP].aUnit := -1; Actions.ShowMsg(iP, 'You have been defeated'); Actions.ShowMsg(aDestroyerIndex, States.PlayerName(iP)+' fell before your might!'); end; end;

Re: Choose Wisely - map idea

PostPosted: 14 Nov 2015, 06:29
by Nightry
The script is working fine.Only this appears if there are less than 8 players.
players.png

Re: Choose Wisely - map idea

PostPosted: 16 Nov 2015, 18:19
by Nightry
Soo...
After a weekend of hard work here it is !

Download and play :D