TM2020-Gamemodes/PhysicsControler.Script.txt

633 lines
33 KiB
Plaintext
Raw Normal View History

#Extends "Modes/TrackMania/TM_TimeAttack_Online.Script.txt"
#Setting S_TrustClientSimu False
#Setting S_AdminPlayers "" as "Comma separated admin to manage all players physics"
#Setting S_ForcePlayersToBeControledBySpectators False as "Force Players to be controlled by Spectators"
#Setting S_AllowPlayersToBeControledBySpectators True as "Allow Players to be controlled by Spectators"
#Struct K_PlayerPhysics {
Real AccelCoef;
Real AdherenceCoef;
Boolean Boost2Down;
Boolean Boost2Up;
Boolean BoostDown;
Boolean BoostUp;
Real ControlCoef;
Real Cruise;
Boolean ForceEngine;
Boolean Fragile;
Real GravityCoef;
Boolean NoBrakes;
Boolean NoEngine;
Boolean NoSteer;
Boolean SlowMotion;
}
***Match_StartServer***
***
UIModules_Record::Reset();
UIModules_Record::SetSpecialVisibility(False);
***
***Match_AfterLoadHud***
***
SetML();
***
***Match_InitMap***
***
declare K_PlayerPhysics AllPlayersPhysics = InitPlayerPhysicsVariable();
declare Text Last_AdminPlayers;
declare netwrite Boolean Net_ServerForcePlayersToBeControledBySpectators for Teams[0] = S_ForcePlayersToBeControledBySpectators;
declare netwrite Boolean Net_ServerAllowPlayersToBeControledBySpectators for Teams[0] = S_AllowPlayersToBeControledBySpectators;
***
***Match_PlayLoop***
***
foreach (Event in PendingEvents) {
Log::Log("[PendingEvents] Event.Type: " ^ Event.Type);
if (Event.Type == CSmModeEvent::EType::OnPlayerAdded) {
if (Event.Player != Null) {
declare netwrite Boolean Net_PlayerIsAdmin for Event.Player = False;
Net_PlayerIsAdmin = TL::Split(",", S_AdminPlayers).exists(Event.Player.User.Login);
declare netwrite K_PlayerPhysics Net_PlayerPhysics for Event.Player = InitPlayerPhysicsVariable();
Net_PlayerPhysics = AllPlayersPhysics;
}
}
}
// Manage Custom UI Events
foreach (Event in UIManager.PendingEvents) { // TODO: Add Secure token to admins
Log::Log("[UIManager] Event.Type: " ^ Event.Type);
if (TL::StartsWith("Request.PlayerPhysics.", Event.CustomEventType)) {
declare Text EventName = TL::Split(".", Event.CustomEventType)[2];
declare Text Target = Event.CustomEventData[0];
declare Text Value = Event.CustomEventData[1];
if (Target == "all") {
AllPlayersPhysics = GetUpdatedPlayerPhysicsVariable(EventName, Value, AllPlayersPhysics);
foreach (Player in Players) {
SetPhysicsChange(EventName, Value, Player);
declare netwrite K_PlayerPhysics Net_PlayerPhysics for Player = InitPlayerPhysicsVariable();
Net_PlayerPhysics = AllPlayersPhysics;
}
} else {
declare CSmPlayer Player = GetPlayer(Target);
if (Player != Null && Player.SpawnStatus == CSmPlayer::ESpawnStatus::Spawned) {
SetPhysicsChange(EventName, Value, Player);
declare netwrite K_PlayerPhysics Net_PlayerPhysics for Player = InitPlayerPhysicsVariable();
Net_PlayerPhysics = GetUpdatedPlayerPhysicsVariable(EventName, Value, Net_PlayerPhysics);
}
}
} else if (Event.CustomEventType == "Request.ControlBySpectators") {
declare Text Target = Event.CustomEventData[0];
declare Text Value = Event.CustomEventData[1];
declare Boolean Allowed = (Value == "1");
declare CSmPlayer Player = GetPlayer(Target);
if (Player != Null) {
declare netwrite Boolean Net_PlayerAllowToBeControledBySpectators for Player = True;
Net_PlayerAllowToBeControledBySpectators = Allowed;
}
} else if (Event.CustomEventType == "Request.AdminLock") {
declare Boolean Locked = (Event.CustomEventData[1] == "1");
declare netwrite Boolean Net_ControledByAdmins for Teams[0];
Net_ControledByAdmins = Locked;
AllPlayersPhysics = InitPlayerPhysicsVariable();
if (Locked) {
foreach (Player in Players) {
SetPhysicsChange("Reset", "", Player);
declare netwrite K_PlayerPhysics Net_PlayerPhysics for Player = InitPlayerPhysicsVariable();
Net_PlayerPhysics = AllPlayersPhysics;
}
}
}
}
foreach (Event in RacePendingEvents) {
Log::Log("[RacePendingEvents] Event.Type: " ^ Event.Type);
if (Event.Type == Events::C_Type_StartLine || Event.Type == Events::C_Type_GiveUp || (Event.Type == Events::C_Type_Waypoint && Event.IsEndRace)) {
declare netwrite K_PlayerPhysics Net_PlayerPhysics for Event.Player = InitPlayerPhysicsVariable();
ApplyPhysicsAtRespawn(Event.Player, Net_PlayerPhysics);
} else if (Event.Type == Events::C_Type_Respawn) {
declare netwrite K_PlayerPhysics Net_PlayerPhysics for Event.Player = InitPlayerPhysicsVariable();
while (Event.Player.SpawnStatus != CSmPlayer::ESpawnStatus::Spawned) MB_Yield();
SetPhysicsChange("Reset", "", Event.Player);
ApplyPhysicsAtRespawn(Event.Player, Net_PlayerPhysics);
}
}
if (Last_AdminPlayers != S_AdminPlayers) {
Last_AdminPlayers = S_AdminPlayers;
declare Text[] Admin = TL::Split(",", S_AdminPlayers);
foreach (Player in Players) {
declare netwrite Boolean Net_PlayerIsAdmin for Player = False;
Net_PlayerIsAdmin = Admin.exists(Player.User.Login);
}
}
if (Net_ServerForcePlayersToBeControledBySpectators != S_ForcePlayersToBeControledBySpectators) {
Net_ServerForcePlayersToBeControledBySpectators = S_ForcePlayersToBeControledBySpectators;
}
if (Net_ServerAllowPlayersToBeControledBySpectators != S_AllowPlayersToBeControledBySpectators) {
Net_ServerAllowPlayersToBeControledBySpectators = S_AllowPlayersToBeControledBySpectators;
}
***
K_PlayerPhysics InitPlayerPhysicsVariable() {
return K_PlayerPhysics {
AccelCoef = 1.,
AdherenceCoef = 1.,
ControlCoef = 1.,
Cruise = 0.,
GravityCoef = 1.
};
}
Boolean SetPhysicsChange(Text _EventName, Text _EventValue, CSmPlayer _Player) {
if (_Player.SpawnStatus == CSmPlayer::ESpawnStatus::Spawned) {
while (SetPlayer_DelayedIsFull(_Player)) MB_Yield();
switch (_EventName) {
case "AccelCoef": SetPlayer_Delayed_AccelCoef(_Player, TL::ToReal(_EventValue));
case "AdherenceCoef": SetPlayer_Delayed_AdherenceCoef(_Player, TL::ToReal(_EventValue));
case "Boost2Down": SetPlayer_Delayed_Boost2Down(_Player, (_EventValue == "1"));
case "Boost2Up": SetPlayer_Delayed_Boost2Up(_Player, (_EventValue == "1"));
case "BoostDown": SetPlayer_Delayed_BoostDown(_Player, (_EventValue == "1"));
case "BoostUp": SetPlayer_Delayed_BoostUp(_Player, (_EventValue == "1"));
case "ControlCoef": SetPlayer_Delayed_ControlCoef(_Player, TL::ToReal(_EventValue));
case "Cruise": SetPlayer_Delayed_Cruise(_Player, (_EventValue != "0"), TL::ToReal(_EventValue));
case "ForceEngine": SetPlayer_Delayed_ForceEngine(_Player, (_EventValue == "1"));
case "Fragile": SetPlayer_Delayed_Fragile(_Player, (_EventValue == "1"));
case "GravityCoef": SetPlayer_Delayed_GravityCoef(_Player, TL::ToReal(_EventValue));
case "NoBrakes": SetPlayer_Delayed_NoBrakes(_Player, (_EventValue == "1"));
case "NoEngine": SetPlayer_Delayed_NoEngine(_Player, (_EventValue == "1"));
case "NoSteer": SetPlayer_Delayed_NoSteer(_Player, (_EventValue == "1"));
case "Reset": SetPlayer_Delayed_Reset(_Player);
case "SlowMotion": SetPlayer_Delayed_SlowMotion(_Player, (_EventValue == "1"));
}
return True;
}
return False;
}
K_PlayerPhysics GetUpdatedPlayerPhysicsVariable(Text _EventName, Text _EventValue, K_PlayerPhysics _PlayerPhysics) {
declare K_PlayerPhysics NewPlayerPhysics = _PlayerPhysics;
switch (_EventName) {
case "AccelCoef": NewPlayerPhysics.AccelCoef = TL::ToReal(_EventValue);
case "AdherenceCoef": NewPlayerPhysics.AdherenceCoef = TL::ToReal(_EventValue);
case "Boost2Down": {
NewPlayerPhysics.Boost2Down = (_EventValue == "1");
NewPlayerPhysics.Boost2Up = False;
NewPlayerPhysics.BoostDown = False;
NewPlayerPhysics.BoostUp = False;
}
case "Boost2Up": {
NewPlayerPhysics.Boost2Down = False;
NewPlayerPhysics.Boost2Up = (_EventValue == "1");
NewPlayerPhysics.BoostDown = False;
NewPlayerPhysics.BoostUp = False;
}
case "BoostDown": {
NewPlayerPhysics.Boost2Down = False;
NewPlayerPhysics.Boost2Up = False;
NewPlayerPhysics.BoostDown = (_EventValue == "1");
NewPlayerPhysics.BoostUp = False;
}
case "BoostUp": {
NewPlayerPhysics.Boost2Down = False;
NewPlayerPhysics.Boost2Up = False;
NewPlayerPhysics.BoostDown = False;
NewPlayerPhysics.BoostUp = (_EventValue == "1");
}
case "ControlCoef": NewPlayerPhysics.ControlCoef = TL::ToReal(_EventValue);
case "Cruise": NewPlayerPhysics.Cruise = TL::ToReal(_EventValue);
case "ForceEngine": {
NewPlayerPhysics.NoEngine = False;
NewPlayerPhysics.ForceEngine = (_EventValue == "1");
}
case "Fragile": NewPlayerPhysics.Fragile = (_EventValue == "1");
case "GravityCoef": NewPlayerPhysics.GravityCoef = TL::ToReal(_EventValue);
case "NoBrakes": NewPlayerPhysics.NoBrakes = (_EventValue == "1");
case "NoEngine": {
NewPlayerPhysics.NoEngine = (_EventValue == "1");
NewPlayerPhysics.ForceEngine = False;
}
case "NoSteer": NewPlayerPhysics.NoSteer = (_EventValue == "1");
case "Reset": NewPlayerPhysics = InitPlayerPhysicsVariable();
case "SlowMotion": NewPlayerPhysics.SlowMotion = (_EventValue == "1");
}
return NewPlayerPhysics;
}
Void ApplyPhysicsAtRespawn(CSmPlayer _Player, K_PlayerPhysics _PlayerPhysics) {
declare K_PlayerPhysics DefaultPlayerPhysics = InitPlayerPhysicsVariable();
while (_Player.SpawnStatus != CSmPlayer::ESpawnStatus::Spawned) MB_Yield();
if (DefaultPlayerPhysics.AccelCoef != _PlayerPhysics.AccelCoef) SetPhysicsChange("AccelCoef", TL::ToText(_PlayerPhysics.AccelCoef), _Player);
if (DefaultPlayerPhysics.AdherenceCoef != _PlayerPhysics.AdherenceCoef) SetPhysicsChange("AdherenceCoef", TL::ToText(_PlayerPhysics.AdherenceCoef), _Player);
if (DefaultPlayerPhysics.Boost2Down != _PlayerPhysics.Boost2Down) SetPhysicsChange("Boost2Down", "1", _Player);
if (DefaultPlayerPhysics.Boost2Up != _PlayerPhysics.Boost2Up) SetPhysicsChange("Boost2Up", "1", _Player);
if (DefaultPlayerPhysics.BoostDown != _PlayerPhysics.BoostDown) SetPhysicsChange("BoostDown", "1", _Player);
if (DefaultPlayerPhysics.BoostUp != _PlayerPhysics.BoostUp) SetPhysicsChange("BoostUp", "1", _Player);
if (DefaultPlayerPhysics.ControlCoef != _PlayerPhysics.ControlCoef) SetPhysicsChange("ControlCoef", TL::ToText(_PlayerPhysics.ControlCoef), _Player);
if (DefaultPlayerPhysics.Cruise != _PlayerPhysics.Cruise) SetPhysicsChange("Cruise", TL::ToText(_PlayerPhysics.Cruise), _Player);
if (DefaultPlayerPhysics.ForceEngine != _PlayerPhysics.ForceEngine) SetPhysicsChange("ForceEngine", "1", _Player);
if (DefaultPlayerPhysics.Fragile != _PlayerPhysics.Fragile) SetPhysicsChange("Fragile", "1", _Player);
if (DefaultPlayerPhysics.GravityCoef != _PlayerPhysics.GravityCoef) SetPhysicsChange("GravityCoef", TL::ToText(_PlayerPhysics.GravityCoef), _Player);
if (DefaultPlayerPhysics.NoBrakes != _PlayerPhysics.NoBrakes) SetPhysicsChange("NoBrakes", "1", _Player);
if (DefaultPlayerPhysics.NoEngine != _PlayerPhysics.NoEngine) SetPhysicsChange("NoEngine", "1", _Player);
if (DefaultPlayerPhysics.NoSteer != _PlayerPhysics.NoSteer) SetPhysicsChange("NoSteer", "1", _Player);
if (DefaultPlayerPhysics.SlowMotion != _PlayerPhysics.SlowMotion) SetPhysicsChange("SlowMotion", "1", _Player);
}
Void SetML() {
declare Text MLText = """
<manialink name="PhysicsDiscovery_UI" version="3">
<script><!--
#Include "TextLib" as TL
#Include "MathLib" as ML
#Include "Libs/Nadeo/CommonLibs/Common/Log.Script.txt" as Log
#Struct K_PlayerPhysics {
Real AccelCoef;
Real AdherenceCoef;
Boolean Boost2Down;
Boolean Boost2Up;
Boolean BoostDown;
Boolean BoostUp;
Real ControlCoef;
Real Cruise;
Boolean ForceEngine;
Boolean Fragile;
Real GravityCoef;
Boolean NoBrakes;
Boolean NoEngine;
Boolean NoSteer;
Boolean SlowMotion;
}
Void Sleep(Integer _Duration) {
declare EndTime = Now + _Duration;
while (Now < EndTime) {
yield;
}
}
Text BooleanToText(Boolean _Value) {
if (_Value) return "1";
return "0";
}
Void UpdateSliderValues() {
declare Slider_Cruise <=> (Page.GetFirstChild("Cruise_Slider") as CMlSlider);
declare Slider_AccelCoef <=> (Page.GetFirstChild("AccelCoef_Slider") as CMlSlider);
declare Slider_AdherenceCoef <=> (Page.GetFirstChild("AdherenceCoef_Slider") as CMlSlider);
declare Slider_ControlCoef <=> (Page.GetFirstChild("ControlCoef_Slider") as CMlSlider);
declare Slider_GravityCoef <=> (Page.GetFirstChild("GravityCoef_Slider") as CMlSlider);
declare Label_Cruise <=> (Page.GetFirstChild("Cruise_Label") as CMlLabel);
declare Label_AccelCoef <=> (Page.GetFirstChild("AccelCoef_Label") as CMlLabel);
declare Label_AdherenceCoef <=> (Page.GetFirstChild("AdherenceCoef_Label") as CMlLabel);
declare Label_ControlCoef <=> (Page.GetFirstChild("ControlCoef_Label") as CMlLabel);
declare Label_GravityCoef <=> (Page.GetFirstChild("GravityCoef_Label") as CMlLabel);
Label_Cruise.Value = TL::ToText(ML::FloorInteger(Slider_Cruise.Value));
Label_AccelCoef.Value = TL::ToText(ML::FloorInteger(Slider_AccelCoef.Value * 100));
Label_AdherenceCoef.Value = TL::ToText(ML::FloorInteger(Slider_AdherenceCoef.Value * 100));
Label_ControlCoef.Value = TL::ToText(ML::FloorInteger(Slider_ControlCoef.Value * 100));
Label_GravityCoef.Value = TL::ToText(ML::FloorInteger(Slider_GravityCoef.Value * 100));
}
Void UpdateUIButtons(K_PlayerPhysics _PlayerPhysics) {
declare Quad_Boost2Down_EffectButton <=> (Page.GetFirstChild("Boost2Down_EffectButton") as CMlQuad);
declare Quad_Boost2Up_EffectButton <=> (Page.GetFirstChild("Boost2Up_EffectButton") as CMlQuad);
declare Quad_BoostDown_EffectButton <=> (Page.GetFirstChild("BoostDown_EffectButton") as CMlQuad);
declare Quad_BoostUp_EffectButton <=> (Page.GetFirstChild("BoostUp_EffectButton") as CMlQuad);
declare Quad_NoBrakes_EffectButton <=> (Page.GetFirstChild("NoBrakes_EffectButton") as CMlQuad);
declare Quad_NoEngine_EffectButton <=> (Page.GetFirstChild("NoEngine_EffectButton") as CMlQuad);
declare Quad_ForceEngine_EffectButton <=> (Page.GetFirstChild("ForceEngine_EffectButton") as CMlQuad);
declare Quad_NoSteer_EffectButton <=> (Page.GetFirstChild("NoSteer_EffectButton") as CMlQuad);
declare Quad_SlowMotion_EffectButton <=> (Page.GetFirstChild("SlowMotion_EffectButton") as CMlQuad);
declare Quad_Fragile_EffectButton <=> (Page.GetFirstChild("Fragile_EffectButton") as CMlQuad);
if (_PlayerPhysics.Boost2Down) Quad_Boost2Down_EffectButton.ModulateColor= <1., 1., 1.>;
else Quad_Boost2Down_EffectButton.ModulateColor= <0., 0., 0.>;
if (_PlayerPhysics.Boost2Up) Quad_Boost2Up_EffectButton.ModulateColor= <1., 1., 1.>;
else Quad_Boost2Up_EffectButton.ModulateColor= <0., 0., 0.>;
if (_PlayerPhysics.BoostDown) Quad_BoostDown_EffectButton.ModulateColor= <1., 1., 1.>;
else Quad_BoostDown_EffectButton.ModulateColor= <0., 0., 0.>;
if (_PlayerPhysics.BoostUp) Quad_BoostUp_EffectButton.ModulateColor= <1., 1., 1.>;
else Quad_BoostUp_EffectButton.ModulateColor= <0., 0., 0.>;
if (_PlayerPhysics.ForceEngine) Quad_ForceEngine_EffectButton.ModulateColor= <1., 1., 1.>;
else Quad_ForceEngine_EffectButton.ModulateColor= <0., 0., 0.>;
if (_PlayerPhysics.Fragile) Quad_Fragile_EffectButton.ModulateColor= <1., 1., 1.>;
else Quad_Fragile_EffectButton.ModulateColor= <0., 0., 0.>;
if (_PlayerPhysics.NoBrakes) Quad_NoBrakes_EffectButton.ModulateColor= <1., 1., 1.>;
else Quad_NoBrakes_EffectButton.ModulateColor= <0., 0., 0.>;
if (_PlayerPhysics.NoEngine) Quad_NoEngine_EffectButton.ModulateColor= <1., 1., 1.>;
else Quad_NoEngine_EffectButton.ModulateColor= <0., 0., 0.>;
if (_PlayerPhysics.NoSteer) Quad_NoSteer_EffectButton.ModulateColor= <1., 1., 1.>;
else Quad_NoSteer_EffectButton.ModulateColor= <0., 0., 0.>;
if (_PlayerPhysics.SlowMotion) Quad_SlowMotion_EffectButton.ModulateColor= <1., 1., 1.>;
else Quad_SlowMotion_EffectButton.ModulateColor= <0., 0., 0.>;
}
Void UpdateUISlider(K_PlayerPhysics _PlayerPhysics) {
declare Slider_Cruise <=> (Page.GetFirstChild("Cruise_Slider") as CMlSlider);
declare Slider_AccelCoef <=> (Page.GetFirstChild("AccelCoef_Slider") as CMlSlider);
declare Slider_AdherenceCoef <=> (Page.GetFirstChild("AdherenceCoef_Slider") as CMlSlider);
declare Slider_ControlCoef <=> (Page.GetFirstChild("ControlCoef_Slider") as CMlSlider);
declare Slider_GravityCoef <=> (Page.GetFirstChild("GravityCoef_Slider") as CMlSlider);
Slider_Cruise.Value = _PlayerPhysics.Cruise;
Slider_AccelCoef.Value = _PlayerPhysics.AccelCoef;
Slider_AdherenceCoef.Value = _PlayerPhysics.AdherenceCoef;
Slider_ControlCoef.Value = _PlayerPhysics.ControlCoef;
Slider_GravityCoef.Value = _PlayerPhysics.GravityCoef;
yield; // Wait UI changed before load value
UpdateSliderValues();
}
Text GetValueOfAnEffect(K_PlayerPhysics _PlayerPhysics, Text _Effect) {
switch (_Effect) {
case "AccelCoef": return TL::ToText(_PlayerPhysics.AccelCoef);
case "AdherenceCoef": return TL::ToText(_PlayerPhysics.AdherenceCoef);
case "Boost2Down": return BooleanToText(_PlayerPhysics.Boost2Down);
case "Boost2Up": return BooleanToText(_PlayerPhysics.Boost2Up);
case "BoostDown": return BooleanToText(_PlayerPhysics.BoostDown);
case "BoostUp": return BooleanToText(_PlayerPhysics.BoostUp);
case "ControlCoef": return TL::ToText(_PlayerPhysics.ControlCoef);
case "Cruise": return TL::ToText(ML::FloorInteger(_PlayerPhysics.Cruise));
case "ForceEngine": return BooleanToText(_PlayerPhysics.ForceEngine);
case "Fragile": return BooleanToText(_PlayerPhysics.Fragile);
case "GravityCoef": return TL::ToText(_PlayerPhysics.GravityCoef);
case "NoBrakes": return BooleanToText(_PlayerPhysics.NoBrakes);
case "NoEngine": return BooleanToText(_PlayerPhysics.NoEngine);
case "NoSteer": return BooleanToText(_PlayerPhysics.NoSteer);
case "SlowMotion": return BooleanToText(_PlayerPhysics.SlowMotion);
}
return "";
}
K_PlayerPhysics InitPlayerPhysicsVariable() {
return K_PlayerPhysics {
AccelCoef = 1.,
AdherenceCoef = 1.,
ControlCoef = 1.,
Cruise = 0.,
GravityCoef = 1.
};
}
main() {
declare Quad_Bg <=> (Page.GetFirstChild("quad-bg") as CMlQuad);
declare Quad_Fg <=> (Page.GetFirstChild("quad-fg") as CMlQuad);
declare Label_Warning <=> (Page.GetFirstChild("label-warning") as CMlLabel);
declare Quad_ControledByAdmins <=> (Page.GetFirstChild("ControledByAdmins_SettingButton") as CMlQuad);
declare Quad_AllowSpectatorsControl <=> (Page.GetFirstChild("AllowSpectatorsControl_SettingButton") as CMlQuad);
declare Frame_AllowSpectatorsControl <=> (Page.GetFirstChild("AllowSpectatorsControl_Frame") as CMlFrame);
declare Frame_Admin <=> (Page.GetFirstChild("Admin_Frame") as CMlFrame);
declare K_PlayerPhysics Last_PlayerPhysics = InitPlayerPhysicsVariable();
declare netread Boolean Net_ServerAllowPlayersToBeControledBySpectators for Teams[0] = True;
declare netread Boolean Net_ControledByAdmins for Teams[0];
declare Boolean Last_ControledByAdmins = False;
declare Boolean Last_PlayerIsAdmin = False;
declare Boolean Last_PlayerAllowToBeControledBySpectators = True;
declare Boolean Last_UIAllowToBeControledBySpectators = False;
declare Text Last_SliderValueToSend;
declare Integer Timer_NeedToSendCommandSlider = 0;
declare CSmPlayer Owner;
if (GUIPlayer != Null) Owner <=> GUIPlayer;
else Owner <=> InputPlayer;
UpdateUIButtons(Last_PlayerPhysics);
UpdateUISlider(Last_PlayerPhysics);
while(True) {
yield;
declare CSmPlayer Owner;
if (GUIPlayer != Null) Owner <=> GUIPlayer;
else Owner <=> InputPlayer;
if (Owner != Null) {
declare netread Boolean Net_PlayerAllowToBeControledBySpectators for Owner = True;
declare netread Boolean Net_PlayerIsAdmin for InputPlayer;
declare netread K_PlayerPhysics Net_PlayerPhysics for Owner = InitPlayerPhysicsVariable();
if (Last_ControledByAdmins != Net_ControledByAdmins || Last_PlayerAllowToBeControledBySpectators != Net_PlayerAllowToBeControledBySpectators) {
Last_ControledByAdmins = Net_ControledByAdmins;
Quad_ControledByAdmins.StyleSelected = Last_ControledByAdmins;
Last_PlayerAllowToBeControledBySpectators = Net_PlayerAllowToBeControledBySpectators;
Quad_AllowSpectatorsControl.StyleSelected = Last_PlayerAllowToBeControledBySpectators;
if ((!Net_PlayerIsAdmin && Last_ControledByAdmins) || (!Last_PlayerAllowToBeControledBySpectators && InputPlayer != Null && InputPlayer.User.Login != Owner.User.Login)) {
Label_Warning.Visible = True;
Quad_Fg.Visible = True;
if (Last_ControledByAdmins) Label_Warning.Value = "Managed by an Admin";
else Label_Warning.Value = "Player refuses to be managed by a spectator";
} else {
Label_Warning.Visible = False;
Quad_Fg.Visible = False;
}
}
if (Last_UIAllowToBeControledBySpectators && (!Net_ServerAllowPlayersToBeControledBySpectators || GUIPlayer == Null || (InputPlayer != Null && InputPlayer.User.Login != Owner.User.Login))) {
Last_UIAllowToBeControledBySpectators = False;
Quad_Bg.Size = <60., 74.>;
Quad_Fg.Size = <60., 74.>;
Frame_AllowSpectatorsControl.Visible = False;
} else if (!Last_UIAllowToBeControledBySpectators && Net_ServerAllowPlayersToBeControledBySpectators && GUIPlayer != Null && InputPlayer != Null && InputPlayer.User.Login == Owner.User.Login) {
Last_UIAllowToBeControledBySpectators = True;
Quad_Bg.Size = <60., 85.>;
Quad_Fg.Size = <60., 85.>;
Frame_AllowSpectatorsControl.Visible = True;
}
if (Last_PlayerIsAdmin != Net_PlayerIsAdmin) {
Last_PlayerIsAdmin = Net_PlayerIsAdmin;
Frame_Admin.Visible = Last_PlayerIsAdmin;
}
if (Last_PlayerPhysics != Net_PlayerPhysics) {
Last_PlayerPhysics = Net_PlayerPhysics;
UpdateUIButtons(Last_PlayerPhysics);
UpdateUISlider(Last_PlayerPhysics);
}
// Events
foreach(Event in PendingEvents) {
if (Owner != Null && Owner.SpawnStatus == CSmPlayer::ESpawnStatus::Spawned) {
if (Event.Type == CMlScriptEvent::Type::MouseClick && TL::Find("_EffectButton", Event.ControlId, True, True)) {
declare Text Effect = TL::Replace(Event.ControlId, "_EffectButton", "");
declare Text Target;
if (Net_PlayerIsAdmin && Last_ControledByAdmins) Target = "all";
else Target = Owner.User.Login;
Log::Log("[main] Request of " ^ Effect ^ " to " ^ Target);
if (GetValueOfAnEffect(Last_PlayerPhysics, Effect) == "1") SendCustomEvent("Request.PlayerPhysics." ^ Effect, [Target, "0"]);
else SendCustomEvent("Request.PlayerPhysics." ^ Effect, [Target, "1"]);
} else if (Event.Type == CMlScriptEvent::Type::MouseOver && TL::Find("_EffectButton", Event.ControlId, True, True)) {
declare Quad <=> (Page.GetFirstChild(Event.ControlId) as CMlQuad);
Quad.Opacity = 0.7;
} else if (Event.Type == CMlScriptEvent::Type::MouseOut && TL::Find("_EffectButton", Event.ControlId, True, True)) {
declare Quad <=> (Page.GetFirstChild(Event.ControlId) as CMlQuad);
Quad.Opacity = 0.5;
} else if (Event.Type == CMlScriptEvent::Type::MouseClick && TL::Find("_Slider", Event.ControlId, True, True)) {
Timer_NeedToSendCommandSlider = Now + 100;
Last_SliderValueToSend = Event.ControlId;
UpdateSliderValues();
} else if (Event.Type == CMlScriptEvent::Type::MouseClick && Event.ControlId == "AllowSpectatorsControl_SettingButton") {
Log::Log("[main] Request ControlBySpectators " ^ !Last_PlayerAllowToBeControledBySpectators ^ " to " ^ Owner.User.Login);
if (Last_PlayerAllowToBeControledBySpectators) SendCustomEvent("Request.ControlBySpectators", [Owner.User.Login, "0"]);
else SendCustomEvent("Request.ControlBySpectators", [Owner.User.Login, "1"]);
} else if (Event.Type == CMlScriptEvent::Type::MouseClick && Event.ControlId == "ControledByAdmins_SettingButton") {
Log::Log("[main] Request ControledByAdmins " ^ !Last_ControledByAdmins ^ " by " ^ Owner.User.Login);
if (Last_ControledByAdmins) SendCustomEvent("Request.AdminLock", ["", "0"]); // TODO: Secure with a token
else SendCustomEvent("Request.AdminLock", ["", "1"]);
}
} else {
UpdateUISlider(Last_PlayerPhysics); // Can't disable control
}
}
if (Timer_NeedToSendCommandSlider > 0 && Now > Timer_NeedToSendCommandSlider ) {
Log::Log("[main] Value of the slider " ^ Last_SliderValueToSend ^ " sent");
Timer_NeedToSendCommandSlider = 0;
declare Slider <=> (Page.GetFirstChild(Last_SliderValueToSend) as CMlSlider);
declare Text Target;
if (Net_PlayerIsAdmin && Last_ControledByAdmins) Target = "all";
else Target = Owner.User.Login;
SendCustomEvent("Request.PlayerPhysics." ^ TL::Replace(Last_SliderValueToSend, "_Slider", ""), [Target, TL::ToText(Slider.Value)]);
}
}
}
}
--></script>
<stylesheet>
<style class="text-label" textfont="GameFontSemiBold" textcolor="ffffff" textsize="1.5" halign="left" valign="center" textprefix="$i$t"/>
<style class="slider" iconidbar="Slider_light" iconidcursor="SliderCursor_light" textcolor="ffffff" valign="center" />
<style class="text-value" textfont="GameFontBlack" textcolor="ffffff" textsize="1.5" halign="right" valign="center"/>
<style class="text-suffix" textfont="GameFontBlack" textcolor="ffffff" textsize="0.7" halign="center" valign="center" textprefix="$i$t"/>
<style class="quad-effects" halign="center" valign="center" />
</stylesheet>
<frame pos="-160 40">
<quad id="quad-bg" pos="0 0" z-index="-1" size="60 74" bgcolor="000" opacity="0.5" /> <!-- 85 for regular, 74 without spec control-->
<quad id="quad-fg" pos="0 0" z-index="5" size="60 74" bgcolor="000" opacity="0.5" hidden=1 scriptevents="1" />
<label id="label-warning" class="text-suffix" hidden=1 z-index="6" pos="30 -35" textsize="2.5" size="50 10" autonewline="1"/>
<label class="text-suffix" pos="30 -5" textsize="3" z-index="0" size="50 10" text="Physics Control"/>
<frame pos="0.5 -6">
<frame pos="30 0">
<quad class="quad-effects" pos="-3 -7.5" z-index="1" size="3 3'" opacity="0.7" image="http://files.virtit.fr/TrackMania/Images/EffectsIcons/Reset.dds" />
<label class="text-suffix" pos="3 -7.2" z-index="0" size="20 5" text="RESET"/>
<quad id="Reset_EffectButton" class="quad-effects" pos="0 -7.5" z-index="0" size="52.5 5" opacity="0.5" style="UICommon64_1" substyle="BgFrame1" modulatecolor="000" scriptevents="1"/>
</frame>
<frame pos="0 -9">
<frame pos="0 0">
<quad class=quad-effects pos="7.5 -7.5" z-index="1" size="7 7" opacity="0.7" image="http://files.virtit.fr/TrackMania/Images/EffectsIcons/ReactorBoost.dds" rot=180 />
<quad id="BoostUp_EffectButton" class=quad-effects pos="7.5 -7.5" z-index="0" size="9 9" opacity="0.5" style="UICommon64_1" substyle="BgFrame1" modulatecolor="000" scriptevents="1"/>
</frame>
<frame pos="11 0">
<quad class=quad-effects pos="7.5 -7.5" z-index="1" size="7 7" opacity="0.7" image="http://files.virtit.fr/TrackMania/Images/EffectsIcons/ReactorBoost2.dds" rot=180 />
<quad id="Boost2Up_EffectButton" class=quad-effects pos="7.5 -7.5" z-index="0" size="9 9" opacity="0.5" style="UICommon64_1" substyle="BgFrame1" modulatecolor="000" scriptevents="1"/>
</frame>
<frame pos="22 0">
<quad class=quad-effects pos="7.5 -7.5" z-index="1" size="7 7" opacity="0.7" image="http://files.virtit.fr/TrackMania/Images/EffectsIcons/NoBrakes.dds" rot=180 />
<quad id="NoBrakes_EffectButton" class=quad-effects pos="7.5 -7.5" z-index="0" size="9 9" opacity="0.5" style="UICommon64_1" substyle="BgFrame1" modulatecolor="000" scriptevents="1"/>
</frame>
<frame pos="33 0">
<quad class=quad-effects pos="7.5 -7.5" z-index="1" size="7 7" opacity="0.7" image="http://files.virtit.fr/TrackMania/Images/EffectsIcons/FreeWheeling.dds" />
<quad id="NoEngine_EffectButton" class=quad-effects pos="7.5 -7.5" z-index="0" size="9 9" opacity="0.5" style="UICommon64_1" substyle="BgFrame1" modulatecolor="000" scriptevents="1"/>
</frame>
<frame pos="44 0">
<quad class=quad-effects pos="7.5 -7.5" z-index="1" size="7 7" opacity="0.7" image="http://files.virtit.fr/TrackMania/Images/EffectsIcons/ForceAcceleration.dds"/>
<quad id="ForceEngine_EffectButton" class=quad-effects pos="7.5 -7.5" z-index="0" size="9 9" opacity="0.5" style="UICommon64_1" substyle="BgFrame1" modulatecolor="000" scriptevents="1"/>
</frame>
</frame>
<frame pos="0 -20">
<frame pos="0 0">
<quad class=quad-effects pos="7.5 -7.5" z-index="1" size="7 7" opacity="0.7" image="http://files.virtit.fr/TrackMania/Images/EffectsIcons/ReactorBoost.dds"/>
<quad id="BoostDown_EffectButton" class=quad-effects pos="7.5 -7.5" z-index="0" size="9 9" opacity="0.5" style="UICommon64_1" substyle="BgFrame1" modulatecolor="000" scriptevents="1"/>
</frame>
<frame pos="11 0">
<quad class=quad-effects pos="7.5 -7.5" z-index="1" size="7 7" opacity="0.7" image="http://files.virtit.fr/TrackMania/Images/EffectsIcons/ReactorBoost2.dds" />
<quad id="Boost2Down_EffectButton" class=quad-effects pos="7.5 -7.5" z-index="0" size="9 9" opacity="0.5" style="UICommon64_1" substyle="BgFrame1" modulatecolor="000" scriptevents="1"/>
</frame>
<frame pos="22 0">
<quad class=quad-effects pos="7.5 -7.5" z-index="1" size="7 7" opacity="0.7" image="http://files.virtit.fr/TrackMania/Images/EffectsIcons/NoSteering.dds" />
<quad id="NoSteer_EffectButton" class=quad-effects pos="7.5 -7.5" z-index="0" size="9 9" opacity="0.5" style="UICommon64_1" substyle="BgFrame1" modulatecolor="000" scriptevents="1"/>
</frame>
<frame pos="33 0">
<quad class=quad-effects pos="7.5 -7.5" z-index="1" size="7 7" opacity="0.7" image="http://files.virtit.fr/TrackMania/Images/EffectsIcons/SlowMotion.dds" />
<quad id="SlowMotion_EffectButton" class=quad-effects pos="7.5 -7.5" z-index="0" size="9 9" opacity="0.5" style="UICommon64_1" substyle="BgFrame1" modulatecolor="000" scriptevents="1"/>
</frame>
<frame pos="44 0">
<quad class=quad-effects pos="7.5 -7.5" z-index="1" size="7 7" opacity="0.7" image="http://files.virtit.fr/TrackMania/Images/EffectsIcons/Fragile.dds" />
<quad id="Fragile_EffectButton" class=quad-effects pos="7.5 -7.5" z-index="0" size="9 9" opacity="0.5" style="UICommon64_1" substyle="BgFrame1" modulatecolor="000" scriptevents="1"/>
</frame>
</frame>
</frame>
<frame pos="2 -42">
<frame pos="0 0">
<label class="text-label" pos="0 0" z-index="0" size="22 5" text="Cruise" />
<slider id="Cruise_Slider" class="slider" pos="34 -0.3" value="0." range="-999 999" size="21 5" z-index="1" scriptevents="1" tooltip="test"/>
<label id="Cruise_Label" class="text-value" pos="53 0" z-index="0" size="10 5" text="0" />
<label class="text-suffix" pos="55 0" z-index="0" size="4 4" text="kph" />
</frame>
<frame pos="0 -7">
<label class="text-label" pos="0 0" z-index="0" size="22 5" text="Acceleration" />
<slider id="AccelCoef_Slider" class="slider" pos="34 -0.3" value="1." range="0.01 1." size="21 5" z-index="1" scriptevents="1" tooltip="test"/>
<label id="AccelCoef_Label" class="text-value" pos="53 0" z-index="0" size="10 5" text="100" />
<label class="text-suffix" pos="55 0" z-index="0" size="4 4" text="%" />
</frame>
<frame pos="0 -14">
<label class="text-label" pos="0 0" z-index="0" size="22 5" text="Adherence" />
<slider id="AdherenceCoef_Slider" class="slider" pos="34 -0.3" value="1." range="0.01 1." size="21 5" z-index="1" scriptevents="1" tooltip="test"/>
<label id="AdherenceCoef_Label" class="text-value" pos="53 0" z-index="0" size="10 5" text="100" />
<label class="text-suffix" pos="55 0" z-index="0" size="10 5" text="%" />
</frame>
<frame pos="0 -21">
<label class="text-label" pos="0 0" z-index="0" size="22 5" text="Control" />
<slider id="ControlCoef_Slider" class="slider" pos="34 -0.3" value="1." range="0.01 1." size="21 5" z-index="1" scriptevents="1" tooltip="test"/>
<label id="ControlCoef_Label" class="text-value" pos="53 0" z-index="0" size="10 5" text="100" />
<label class="text-suffix" pos="55 0" z-index="0" size="10 5" text="%" />
</frame>
<frame pos="0 -28">
<label class="text-label" pos="0 0" z-index="0" size="22 5" text="Gravity" />
<slider id="GravityCoef_Slider" class="slider" pos="34 -0.3" value="1." range="0.01 1." size="21 5" z-index="1" scriptevents="1" tooltip="test"/>
<label id="GravityCoef_Label" class="text-value" pos="53 0" z-index="0" size="10 5" text="100" />
<label class="text-suffix" pos="55 0" z-index="0" size="10 5" text="%" />
</frame>
</frame>
<frame id="AllowSpectatorsControl_Frame" hidden=1 pos="5 -79">
<quad id="AllowSpectatorsControl_SettingButton" pos="0 0.5" z-index="1" size="5 5" bgcolor="FFF" halign="center" valign="center" style="UICommon64_1" substyle="CheckboxCircle_light" scriptevents="1" opacity="0.7" styleselected="1"/>
<label class="text-label" halign="left" pos="5 0.5" z-index="1" size="50 10" textprefix="$i" text="Allow a spectator to control your physics" autonewline="1"/>
</frame>
<frame id="Admin_Frame" hidden=1 pos="0 -88">
<quad pos="0 0" z-index="-1" size="60 10" bgcolor="000" opacity="0.5"/>
<frame pos="5 -5.5">
<quad id="ControledByAdmins_SettingButton" pos="0 0.5" z-index="1" size="5 5" bgcolor="FFF" halign="center" valign="center" style="UICommon64_1" substyle="CheckboxCircle_light" scriptevents="1" opacity="0.7" />
<label class="text-label" halign="left" pos="5 0.5" z-index="1" size="50 10" textprefix="$i" text="Control all players physics (admin only)" autonewline="1"/>
</frame>
</frame>
</frame>
</manialink>
""";
Layers::Create("PhysicsDiscovery_UI", MLText);
Layers::SetType("PhysicsDiscovery_UI", CUILayer::EUILayerType::Normal);
Layers::Attach("PhysicsDiscovery_UI");
}