Page 1 of 1
Choose Wisely - map idea
PostPosted: 11 Nov 2015, 16:38
by Nightry
Hi all
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.
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
Nope
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
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.
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