I think that it is possible to implement sequential turn in MP using current SDK and modding 2 system file on local PCs. Below you can find description of this idea and sample code.
Ok, let;s start with basic plan, requirements and assumption:
1) I want to implement "Player Units Moving Turn" during standard simultaneous turn.
2) I want to implement all change transparently to single player games and all others MODs. Basically by adding ScripData by map script and checking it in system function that I have to change.
3) At the beginning of all turns I want to set zero movements points for all units. So nobody can move their units before turn sequence but players can change setting and e.g cities...
4) I want to active Moving Player sequential from Player[0] to Player[21]
5) I want to set movements points to max for all units of Moving Player at the beginning o his Moving Turn.
6) I want change again moving point to zero after finishing Moving Turn by relevant player who has ended his Moving Turn.
Ok, now description how i want to do it.
Step #1:
First thing it is to change to zero movement points of all players and active first Moving Player. I will use for this Events.ActivePlayerTurnStart
Sample code (I plan use ScripData to mark current Moving Player):
Step #2:
Next step it is to change Moving Player to next one. First we need function that will change movements points (old Moving Player points to zero and new Moving Player to maximum). It is example of such function:
Step #3 is to trigger local function DoNextPlr() on all PCs when we want to change Moving Player. I plan to do it by:
a) adding context window with name of current moving player and button "Next Player" that will launch DoNextPlr() --> local player can activate Moving Turn change by pressing "Next Player" button
b) adding to players list update function trigger that will monitor pPlayer:HasReceivedNetTurnComplete() status and launch DoNextPlr() when Moving Player finish his turn on remote PCs --> automatic activation Moving Turn change on remote PC
Step #3a:
Adding contest window is ease. We need xml file e.g NextPlr.xml
and add it to core system file: InGame.xml (first system file that we have to change). Just add such line:
It will add window defined in InGame.xml and include InGame.lue where you can past DoNextPlr() and Events.ActivePlayerTurnStart.Add
Step #3b is ease also. You have to change "if" from line 180 in MPlist.lua (second system file that we have to change)
and this is it.
If you see any logical problem according this procedure pls let me know.
Ok, let;s start with basic plan, requirements and assumption:
1) I want to implement "Player Units Moving Turn" during standard simultaneous turn.
2) I want to implement all change transparently to single player games and all others MODs. Basically by adding ScripData by map script and checking it in system function that I have to change.
3) At the beginning of all turns I want to set zero movements points for all units. So nobody can move their units before turn sequence but players can change setting and e.g cities...
4) I want to active Moving Player sequential from Player[0] to Player[21]
5) I want to set movements points to max for all units of Moving Player at the beginning o his Moving Turn.
6) I want change again moving point to zero after finishing Moving Turn by relevant player who has ended his Moving Turn.
Ok, now description how i want to do it.
Step #1:
First thing it is to change to zero movement points of all players and active first Moving Player. I will use for this Events.ActivePlayerTurnStart
Sample code (I plan use ScripData to mark current Moving Player):
Spoiler :
Code:
Events.ActivePlayerTurnStart.Add(function()
for iPlayer_ID = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
if iPlayer_ID ~= 0 then
local pPlayer = Players[iPlayer_ID];
if ( pPlayer ~= nil and pPlayer:GetStartingPlot() ~= nil and pPlayer:IsAlive() == true) then --if valid
if (pPlayer:IsHuman() == true and pPlayer:IsBarbarian() == false) then
local sInfoText = nil;
for u in pPlayer:Units() do
u:SetName("Waiting!");
u:SetMoves(0);
end
local SetScriptDataTxt = tostring(0);
pPlayer:SetScriptData(SetScriptDataTxt);
end
end
else
local pPlayer = Players[iPlayer_ID];
for u in pPlayer:Units() do
u:SetMoves(u:MaxMoves());
u:SetName("Idle!");
end
end
end
end);
Step #2:
Next step it is to change Moving Player to next one. First we need function that will change movements points (old Moving Player points to zero and new Moving Player to maximum). It is example of such function:
Spoiler :
Code:
function DoNextPlr()
local iActPlayer_ID = nil;
for i = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
local YourTurn = Players[i]:GetScriptData();
if tonumber(YourTurn) == 1 then
iActPlayer_ID = i;
break
end
end
if iActPlayer_ID ~= nil then
if iActPlayer_ID ~= Game.GetActivePlayer() then
local labelText = "This is " .. Players[iActPlayer_ID]:GetName() .. " turn! Pls try later!"
Controls.NextPlrLabel:LocalizeAndSetText(labelText);
Controls.Grid:DoAutoSize();
return
end
else
ContextPtr:SetHide( true );
return
end
if Game.GetGameTurn() > 5 then
local pActPlayer = Players[iActPlayer_ID];
----
--deactive player
----
if (pActPlayer:IsHuman() == true and pActPlayer:IsBarbarian() == false) then
for u in pActPlayer:Units() do
local sInfoText = nil;
u:SetName("End!");
u:SetMoves(0);
end
local SetScriptDataTxt = tostring(0);
pActPlayer:SetScriptData(SetScriptDataTxt);
end
----
--active next player
----
for nextPlr_ID = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
local nextPlr = Players[nextPlr_ID];
if ( nextPlr ~= nil and nextPlr:GetStartingPlot() ~= nil and nextPlr:IsAlive() == true) then --if valid
if (nextPlr:IsHuman() == true and nextPlr:IsBarbarian() == false and nextPlr_ID > iActPlayer_ID ) then --if next human
local YourTurn = Players[nextPlr_ID]:GetScriptData();
if (tonumber(YourTurn) == 0 or tonumber(YourTurn) == nil) then --if not active (to be sure)
for u in nextPlr:Units() do
u:SetMoves(u:MaxMoves());
u:SetName("Idle!");
end
Players[nextPlr_ID]:AddNotification(NotificationTypes.NOTIFICATION_GENERIC, "Your turn, you can move your units now." , "Your turn.");
local labelText = Players[nextPlr_ID]:GetName() .. " is moving.";
Controls.NextPlrLabel:LocalizeAndSetText(labelText);
Controls.Grid:DoAutoSize();
local SetScriptDataTxt = tostring(1);
Players[nextPlr_ID]:SetScriptData(SetScriptDataTxt);
break
end
end
end -- valid end
end --for end
end --end game turn if
end
Step #3 is to trigger local function DoNextPlr() on all PCs when we want to change Moving Player. I plan to do it by:
a) adding context window with name of current moving player and button "Next Player" that will launch DoNextPlr() --> local player can activate Moving Turn change by pressing "Next Player" button
b) adding to players list update function trigger that will monitor pPlayer:HasReceivedNetTurnComplete() status and launch DoNextPlr() when Moving Player finish his turn on remote PCs --> automatic activation Moving Turn change on remote PC
Step #3a:
Adding contest window is ease. We need xml file e.g NextPlr.xml
Spoiler :
Code:
<Context ColorSet="Beige_Black_Alpha" Font="TwCenMT16" FontStyle="Shadow">
<Grid ID="Grid" Offset="0,-10" Anchor="C,T" Size="300,60" Color="White.256" Style="Grid9DetailSix140" Padding="70,60" ConsumeMouse="1">
<Label Anchor="L,C" Offset="30,-5" Font="TwCenMT20" ColorSet="Beige_Black_Alpha" FontStyle="Shadow" ID="NextPlrLabel">
<GridButton Offset="10,-10" Font="TwCenMT16" Anchor="R,B" AnchorSide="o,i" Size="100,27" Style="SmallButton" String="Next Player" ID="NextPlr"/>
</Label>
</Grid>
</Context>
and add it to core system file: InGame.xml (first system file that we have to change). Just add such line:
Spoiler :
Code:
<Container Size="F,F" ID="BulkUI" >
[B]<LuaContext FileName="Assets/UI/InGame/NextPlr" ID="NextPlr" Hidden="True"/>[/B]
/Container>
It will add window defined in InGame.xml and include InGame.lue where you can past DoNextPlr() and Events.ActivePlayerTurnStart.Add
Step #3b is ease also. You have to change "if" from line 180 in MPlist.lua (second system file that we have to change)
Spoiler :
Code:
-- turn finished
if( pPlayer:HasReceivedNetTurnComplete() or not pPlayer:IsAlive() ) then
controlTable.Name:SetAlpha( 0.5 );
controlTable.IconBox:SetAlpha( 0.2 );
[B] ---- change
DoNextPlr();
----[/B]
else
controlTable.Name:SetAlpha( 1 );
controlTable.IconBox:SetAlpha( 1 );
end
and this is it.
If you see any logical problem according this procedure pls let me know.