From 15cf813c1ca3bd91aaa8b9ed3fb9c92087c66fd1 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 25 Mar 2017 13:41:09 +0100 Subject: [PATCH 01/93] Rename Rule_BaseRespawn to Rule_Relaunch and implement relaunch functionality --- .../Rules.ocd/BaseRespawn.ocd/Script.c | 185 -------- .../Rules.ocd/BaseRespawn.ocd/StringTblDE.txt | 8 - .../Rules.ocd/BaseRespawn.ocd/StringTblUS.txt | 8 - .../DefCore.txt | 2 +- .../Graphics.4.png | Bin .../Rules.ocd/Relaunch.ocd/Script.c | 411 ++++++++++++++++++ .../Rules.ocd/Relaunch.ocd/StringTblDE.txt | 18 + .../Rules.ocd/Relaunch.ocd/StringTblUS.txt | 18 + 8 files changed, 448 insertions(+), 202 deletions(-) delete mode 100644 planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c delete mode 100644 planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/StringTblDE.txt delete mode 100644 planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/StringTblUS.txt rename planet/Objects.ocd/Rules.ocd/{BaseRespawn.ocd => Relaunch.ocd}/DefCore.txt (69%) rename planet/Objects.ocd/Rules.ocd/{BaseRespawn.ocd => Relaunch.ocd}/Graphics.4.png (100%) create mode 100644 planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c create mode 100644 planet/Objects.ocd/Rules.ocd/Relaunch.ocd/StringTblDE.txt create mode 100644 planet/Objects.ocd/Rules.ocd/Relaunch.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c deleted file mode 100644 index 09a45f5d6..000000000 --- a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c +++ /dev/null @@ -1,185 +0,0 @@ -/** - Base Respawn - If neutral flagpoles are available, respawn there (for free). Otherwise, respawn - at the nearest base if sufficient clonks and clunkers are available. - TODO: make more general for all kinds of available crew members. - - @author Maikel, Sven2 -*/ - -// Determines whether the inventory of the crew member is transfered upon respawn. -local inventory_transfer = false; - -// Determines whether a crew member needs to be bought. -local free_crew = false; - -// Delay between clonk death and respawn (in seconds) -local respawn_delay = 2; - -protected func Initialize() -{ - ScheduleCall(this, this.CheckDescription, 1, 1); - return true; -} - -private func CheckDescription() -{ - // If neutral flagpoles exist, update name and description. - if (ObjectCount(Find_ID(Flagpole), Find_Func("IsNeutral"))) - { - SetName("$Name2$"); - this.Description = "$Description2$"; - } - return true; -} - -public func SetInventoryTransfer(bool transfer) -{ - inventory_transfer = transfer; - return true; -} - -public func GetInventoryTransfer() -{ - return inventory_transfer; -} - -public func SetFreeCrew(bool free) -{ - free_crew = free; - return true; -} - -public func GetFreeCrew() -{ - return free_crew; -} - -protected func OnClonkDeath(object clonk) -{ - var plr = clonk->GetOwner(); - // Skip eliminated players, NO_OWNER, etc. - if (!GetPlayerName(plr)) - return true; - - // Only respawn a clonk if it is the last crew member. - if (GetCrewCount(plr) >= 1) - return true; - - // Get the bases at which the clonk can possibly respawn. - var bases = GetBases(clonk), crew; - for (var base in bases) - { - if (!base) - continue; - - // If free crew just create a clonk at the base. - if (free_crew) - { - crew = CreateObjectAbove(Clonk, base->GetX() - GetX(), base->GetY() + base->GetDefHeight() / 2 - GetY(), plr); - crew->MakeCrewMember(plr); - SetCursor(plr, crew); - // Transfer inventory if turned on. - if (inventory_transfer) TransferInventory(clonk, crew); - break; - } - // Try to buy a crew member at the base. - var pay_plr = base->GetOwner(); - // Payment in neutral bases by clonk owner. - if (pay_plr == NO_OWNER) - pay_plr = plr; - crew = base->~DoBuy(Clonk, plr, pay_plr, clonk); - if (crew) - { - crew->Exit(0, base->GetDefHeight() / 2); - SetCursor(plr, crew); - // Transfer inventory if turned on. - if (inventory_transfer) TransferInventory(clonk, crew); - break; - } - } - // Respawn delay (+Weapon choice if desired by scenario) - if (crew && respawn_delay) - { - crew->SetCrewEnabled(false); // will be re-set by relauncher - var relaunch = CreateObject(RelaunchContainer, crew->GetX() - GetX(), crew->GetY() - GetY(), plr); - relaunch->SetRelaunchTime(respawn_delay, false); - relaunch->StartRelaunch(crew); - // But keep view on old corpse because the death might be exciting! - // And sometimes you want to know why you died (just like in real-life!) - var light = CreateLight(clonk->GetX() - GetX(), clonk->GetY() - GetY(), 100, Fx_Light.LGT_Temp, plr, 20, respawn_delay*36); - SetCursor(plr, nil); - SetPlrView(plr, light); - } - return true; -} - -private func TransferInventory(object from, object to) -{ - // Drop some items that cannot be transferred (such as connected pipes and dynamite igniters) - var i = from->ContentsCount(), contents; - while (i--) - if (contents = from->Contents(i)) - if (contents->~IsDroppedOnDeath(from)) - { - contents->Exit(); - } - else - { - // The new clonk doesn't burn. To be consistent, also extinguish contents - contents->Extinguish(); - } - return to->GrabContents(from); -} - -private func GetBases(object clonk) -{ - var plr = clonk->GetOwner(); - // Neutral flagpoles are preferred respawn points, because they are used as the only respawn points in missions. - var bases = clonk->FindObjects(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance()); - // If there are no neutral flagpoles, find closest base owned by the player (or team) and try to buy a clonk. - if (GetLength(bases) <= 0) - bases = clonk->FindObjects(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance()); - return bases; -} - -protected func Activate(int byplr) -{ - MessageWindow(this.Description, byplr); - return true; -} - - -/*-- Scenario saving --*/ - -public func SaveScenarioObject(props, ...) -{ - if (!inherited(props, ...)) - return false; - // Custom properties - props->Remove("Name"); // updated by initialization - props->Remove("Description"); // updated by initialization - if (inventory_transfer) - props->AddCall("InvenctoryTransfer", this, "SetInventoryTransfer", inventory_transfer); - if (free_crew) - props->AddCall("FreeCrew", this, "SetFreeCrew", free_crew); - return true; -} - - -/* Editor */ - -public func Definition(def) -{ - if (!def.EditorProps) def.EditorProps = {}; - def.EditorProps.inventory_transfer = { Name="$InventoryTransfer$", EditorHelp="$InventoryTransferHelp$", Type="bool", Set="SetInventoryTransfer" }; - def.EditorProps.free_crew = { Name="$FreeCrew$", EditorHelp="$FreeCrewHelp$", Type="bool", Set="SetFreeCrew" }; -} - - -/*-- Proplist --*/ - -local Name = "$Name$"; -local Description = "$Description$"; -local Visibility = VIS_Editor; -local EditorPlacementLimit = 1; // Rules are to be placed only once diff --git a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/StringTblDE.txt b/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/StringTblDE.txt deleted file mode 100644 index f33606c37..000000000 --- a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/StringTblDE.txt +++ /dev/null @@ -1,8 +0,0 @@ -Name=Basis Neustart -Name2=Neustart am Flaggenmast -Description=Du wirst in der nächstliegenden Basis wiederbelebt, wenn ausreichend Clonks und Clunker vorhanden sind. -Description2=Du wirst am nächstliegenden Flaggenmast wiederbelebt. -InventoryTransfer=Inventar behalten -InventoryTransferHelp=Ob das Inventar sterbender Clonks beim Respawn zum neuen Clonk teleportiert werden soll. -FreeCrew=Kostenloser Respawn -FreeCrewHelp=Ob man die Clonks umsonst bekommt. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/StringTblUS.txt b/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/StringTblUS.txt deleted file mode 100644 index 4a6309b4f..000000000 --- a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/StringTblUS.txt +++ /dev/null @@ -1,8 +0,0 @@ -Name=Base Respawn -Name2=Respawn at flagpole -Description=You respawn at the nearest base if sufficient clonks and clunkers are available. -Description2=You respawn at the nearest respawn flagpole. -InventoryTransfer=Keep inventory -InventoryTransferHelp=Whether the inventory of dying clonks is beamed to the newly respawned clonk. -FreeCrew=Free respawn -FreeCrewHelp=Whether respawning clonks are free. If not set, respawn happens only if the player has sufficient gold and clonks available for sale. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/DefCore.txt b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/DefCore.txt similarity index 69% rename from planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/DefCore.txt rename to planet/Objects.ocd/Rules.ocd/Relaunch.ocd/DefCore.txt index b597e8be4..17c3326eb 100644 --- a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/DefCore.txt +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/DefCore.txt @@ -1,5 +1,5 @@ [DefCore] -id=Rule_BaseRespawn +id=Rule_Relaunch Version=8,0 Category=C4D_StaticBack | C4D_Rule Width=32 diff --git a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Graphics.4.png b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Graphics.4.png similarity index 100% rename from planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Graphics.4.png rename to planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Graphics.4.png diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c new file mode 100644 index 000000000..2f6972a37 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -0,0 +1,411 @@ +/** + Relaunch Rule + This rule enables and handles relaunches. + @author Maikel, Sven2, Fulgen +*/ + +protected func Initialize() +{ + ScheduleCall(this, this.CheckDescription, 1, 1); + return true; +} + +private func CheckDescription() +{ + // If neutral flagpoles exist, update name and description. + if(respawn_at_base) + { + if(ObjectCount(Find_ID(Flagpole), Find_Func("IsNeutral"))) + { + SetName("$Name2$"); + this.Description = "$Description2$"; + } + else + { + SetName("$Name3$"); + this.Description = "$Description3$"; + } + } + else + { + SetName("$Name$"); + this.Description = "$Description$"; + } + return true; +} + +// Determines whether the inventory of the crew member is transfered upon respawn. +local inventory_transfer = false; + +// Determines whether a crew member needs to be bought. +local free_crew = false; + +//Determines whether the clonk will be respawned at the base +local respawn_at_base = false; + +local DefaultRelaunchCount = 5; +local aRelaunches = []; + +local ClonkType = Clonk; + +local DisableLastWeapon = false; +local LastUsedPlayerWeapons = []; +local RelaunchTime = 36 * 10; +local Hold = false; + +public func SetInventoryTransfer(bool transfer) +{ + inventory_transfer = transfer; + return true; +} + +public func GetInventoryTransfer() +{ + return inventory_transfer; +} + +public func SetFreeCrew(bool free) +{ + free_crew = free; + return true; +} + +public func GetFreeCrew() +{ + return free_crew; +} + +public func SetRespawnDelay(int iDelay) +{ + RelaunchTime = iDelay; + return this; +} + +public func GetRespawnDelay() +{ + return RelaunchTime; +} + +public func SetHolding(bool fHold) +{ + Hold = fHold; + return this; +} + +public func GetHolding() +{ + return Hold; +} + +public func SetLastWeaponUse(bool fUse) +{ + this.DisableLastWeapon = !fUse; + return this; +} + +public func GetLastWeaponUse() +{ + return DisableLastWeapon; +} + +public func SetBaseRespawn(bool fSet) +{ + respawn_at_base = fSet; + return this; +} + +public func GetBaseRespawn() +{ + return respawn_at_base; +} + +public func SetDefaultRelaunches(int iRelaunches) +{ + DefaultRelaunchCount = iRelaunches; +} + +public func InitializePlayer(int iPlr) +{ + _inherited(iPlr, ...); + // Scenario script callback. + aRelaunches[iPlr] = DefaultRelaunchCount; + GameCallEx("OnPlayerRelaunch", iPlr, false); + return DoRelaunch(iPlr, nil, nil, true); +} + +/*public func OnClonkDeath(int plr, object pClonk, int iKiller) +{ + return RelaunchPlayer(plr, iKiller, pClonk); +}*/ + +public func RelaunchPlayer(int plr, int killer, object pClonk) +{ + if(plr == nil || plr == NO_OWNER) return Log("NO PlAYER: %d", plr); + + if(DefaultRelaunchCount != nil) + { + aRelaunches[plr]--; + if(aRelaunches[plr] < 0) + { + EliminatePlayer(plr); + return; + } + } + + GameCall("OnPlayerRelaunch", plr, true); + + return DoRelaunch(plr, pClonk, nil); +} + +public func RespawnAtBase(int plr, object clonk, bool fNoCreation) +{ + // Skip eliminated players, NO_OWNER, etc. + if (!GetPlayerName(plr)) + return; + + // Only respawn a clonk if it is the last crew member. + if (GetCrewCount(plr) >= 1) + return; + + // Get the bases at which the clonk can possibly respawn. + var bases = GetBases(clonk), crew; + for (var base in bases) + { + if (!base) + continue; + + if(fNoCreation) + { + crew = clonk ?? GetCrew(plr); + if(crew) + { + crew->SetPosition(base->GetX(), base->GetY() + base->GetDefHeight() / 2); + break; + } + + } + + // If free crew just create a clonk at the base. + if (free_crew) + { + crew = CreateObjectAbove(ClonkType, base->GetX() - GetX(), base->GetY() + base->GetDefHeight() / 2 - GetY(), plr); + crew->MakeCrewMember(plr); + SetCursor(plr, crew); + // Transfer inventory if turned on. + if (inventory_transfer) TransferInventory(clonk, crew); + break; + } + // Try to buy a crew member at the base. + var pay_plr = base->GetOwner(); + // Payment in neutral bases by clonk owner. + if (pay_plr == NO_OWNER) + pay_plr = plr; + crew = base->~DoBuy(ClonkType, plr, pay_plr, clonk); + if (crew) + { + crew->Exit(0, base->GetDefHeight() / 2); + SetCursor(plr, crew); + // Transfer inventory if turned on. + if (inventory_transfer) TransferInventory(clonk, crew); + break; + } + } + // Respawn delay (+Weapon choice if desired by scenario) + if (crew && RelaunchTime) + { + crew->SetCrewEnabled(false); // will be re-set by relauncher + + crew->CreateObject(RelaunchContainer,nil,nil,plr)->StartRelaunch(clonk); + // But keep view on old corpse because the death might be exciting! + // And sometimes you want to know why you died (just like in real-life!) + if(clonk) + { + var light = clonk->CreateLight(0, 0, 100, Fx_Light.LGT_Temp, plr, 20, RelaunchTime*36); + SetCursor(plr, nil); + SetPlrView(plr, light); + } + } + return true; +} + +private func TransferInventory(object from, object to) +{ + // Drop some items that cannot be transferred (such as connected pipes and dynamite igniters) + var i = from->ContentsCount(), contents; + while (i--) + if (contents = from->Contents(i)) + if (contents->~IsDroppedOnDeath(from)) + { + contents->Exit(); + } + else + { + // The new clonk doesn't burn. To be consistent, also extinguish contents + contents->Extinguish(); + } + return to->GrabContents(from); +} + +private func GetBases(object clonk) +{ + var plr = clonk->GetOwner(); + // Neutral flagpoles are preferred respawn points, because they are used as the only respawn points in missions. + var bases = clonk->FindObjects(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance()); + // If there are no neutral flagpoles, find closest base owned by the player (or team) and try to buy a clonk. + if (GetLength(bases) <= 0) + bases = clonk->FindObjects(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance()); + return bases; +} + +public func DoRelaunch(int iPlr, object pClonk, array position, bool fNoCreation) +{ + if(respawn_at_base) return RespawnAtBase(iPlr, pClonk, fNoCreation); + if(!GetPlayerName(iPlr)) return Log("NO NAME"); + position = (position ?? GameCall("RelaunchPosition", iPlr, GetPlayerTeam(iPlr))) ?? FindRelaunchPos(iPlr); + + var spawn; + + if(GetType(position) == C4V_Array) + { + if(GetType(position[0]) == C4V_Array) + { + spawn = position[Random(GetLength(position))]; + } + else spawn = position; + } + var clonk; + if(!fNoCreation) + { + var clonk = CreateObjectAbove(ClonkType, spawn[0], spawn[1], iPlr); + if(!clonk) return Log("NO CLONK"); + clonk->MakeCrewMember(iPlr); + } + else + { + clonk = GetCrew(iPlr); + if(!clonk) return Log("NO CREW"); + } + + if(!GetCursor(iPlr) || GetCursor(iPlr) == pClonk) SetCursor(iPlr, clonk); + clonk->DoEnergy(100000); + + if(RelaunchTime) + { + clonk->CreateObject(RelaunchContainer,nil,nil,iPlr)->StartRelaunch(clonk); + } + return true; +} + +protected func FindRelaunchPos(int plr) +{ + var tx, ty; // Test position. + for (var i = 0; i < 500; i++) + { + tx = Random(LandscapeWidth()); + ty = Random(LandscapeHeight()); + if (GBackSemiSolid(AbsX(tx), AbsY(ty))) + continue; + if (GBackSemiSolid(AbsX(tx+5), AbsY(ty+10))) + continue; + if (GBackSemiSolid(AbsX(tx+5), AbsY(ty-10))) + continue; + if (GBackSemiSolid(AbsX(tx-5), AbsY(ty+10))) + continue; + if (GBackSemiSolid(AbsX(tx-5), AbsY(ty-10))) + continue; + // Succes. + return [tx, ty]; + } + return nil; +} + +/*-- Scenario saving --*/ + +public func SaveScenarioObject(props, ...) +{ + if (!inherited(props, ...)) + return false; + // Custom properties + props->Remove("Name"); // updated by initialization + props->Remove("Description"); // updated by initialization + if (inventory_transfer) + props->AddCall("InventoryTransfer", this, "SetInventoryTransfer", inventory_transfer); + if (free_crew) + props->AddCall("FreeCrew", this, "SetFreeCrew", free_crew); + return true; +} +/*-- Globals --*/ + +global func SetRelaunchCount(int plr, int value) +{ + if(UnlimitedRelaunches()) return; + GetRelaunchRule().aRelaunches[plr] = value; + Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().aRelaunches[plr]); + return value; +} + +global func GetRelaunchCount(int plr) +{ + return GetRelaunchRule().aRelaunches[plr]; +} + +global func DoRelaunchCount(int plr, int value) +{ + if(UnlimitedRelaunches()) return; + GetRelaunchRule().aRelaunches[plr] += value; + Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().aRelaunches[plr]); + return; +} + +global func UnlimitedRelaunches() +{ + return GetRelaunchRule().DefaultRelaunchCount == nil; +} + +global func GetRelaunchRule() +{ + return FindObject(Find_ID(Rule_Relaunch)) || CreateObject(Rule_Relaunch); +} + +/* Editor */ + +public func Definition(def) +{ + if (!def.EditorProps) def.EditorProps = {}; + def.EditorProps.inventory_transfer = { Name="$InventoryTransfer$", EditorHelp="$InventoryTransferHelp$", Type="bool", Set="SetInventoryTransfer" }; + def.EditorProps.free_crew = { Name="$FreeCrew$", EditorHelp="$FreeCrewHelp$", Type="bool", Set="SetFreeCrew" }; + def.EditorProps.respawn_at_base = { + Name = "$RespawnAtBase$", + EditorHelp = "$RespawnAtBaseHelp$", + Type = "bool", + Set = "SetBaseRespawn" + }; + + def.EditorProps.hold = { + Name = "$Holding$", + EditorHelp = "$HoldingHelp$", + Type = "bool", + Set = "SetHolding" + }; + + def.EditorProps.respawn_delay = { + Name = "$RespawnDelay$", + EditorHelp = "$RespawnDelayHelp$", + Type = "int", + Set = "SetRespawnDelay" + }; + + def.EditorProps.relaunch_count = { + Name = "$RelaunchCount$", + EditorHelp = "$RelaunchCountHelp$", + Type = "int", + Set = "SetDefaultRelaunches" + }; +} + +/*-- Proplist --*/ + +local Name = "$Name$"; +local Description = "$Description$"; +local Visibility = VIS_Editor; +local EditorPlacementLimit = 1; // Rules are to be placed only once diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/StringTblDE.txt b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/StringTblDE.txt new file mode 100644 index 000000000..1d2dad16c --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/StringTblDE.txt @@ -0,0 +1,18 @@ +Name=Relaunches +Name2=Neustart am Flaggenmast +Name3=Neustart in der Basis +Description=Du wirst an einem vorgegebenen Ort in der Landschaft wiederbelebt. +Description2=Du wirst am nächstliegenden Flaggenmast wiederbelebt. +Description3=Du wirst in der nächstliegenden Basis wiederbelebt, wenn ausreichend Clonks und Clunker vorhanden sind. +InventoryTransfer=Inventar behalten +InventoryTransferHelp=Ob das Inventar sterbender Clonks beim Respawn zum neuen Clonk teleportiert werden soll. +FreeCrew=Kostenloser Respawn +FreeCrewHelp=Ob man die Clonks umsonst bekommt. +RespawnAtBase=Respawn bei der Basis +RespawnAtBaseHelp=Ob man bei der Basis spawnt. +Holding=Clonk bleibt im Container +HoldingHelp=Ob der Clonk nach Auswahl einer Waffe im Container bleibt. +RespawnDelay=Respawnzeit +RespawnDelayHelp=Zeit, die vom Tod bis zum Respawn vergeht. +RelaunchCount=Anzahl der Relaunches +RelaunchCountHelp=Anzahl der Relaunches, die man erhält. Auf -1 setzen, um unbegrenzte Relaunches zu ermöglichen. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/StringTblUS.txt b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/StringTblUS.txt new file mode 100644 index 000000000..1849a8d18 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/StringTblUS.txt @@ -0,0 +1,18 @@ +Name=Relaunches +Name2=Respawn at flagpole +Name3=Base respawn +Description=You respawn at a fixed point in the map. +Description2=You respawn at the nearest respawn flagpole. +Description3=You respawn at the nearest base if sufficient clonks and clunkers are available. +InventoryTransfer=Keep inventory +InventoryTransferHelp=Whether the inventory of dying clonks is beamed to the newly respawned clonk. +FreeCrew=Free respawn +FreeCrewHelp=Whether respawning clonks are free. If not set, respawn happens only if the player has sufficient gold and clonks available for sale. +RespawnAtBase=Respawn bei der Basis +RespawnAtBaseHelp=Ob man bei der Basis spawnt. +Holding=Clonks stay in the container +HoldingHelp=Whether respawning clonks stay in the container until the respawn time ends. +RespawnDelay=Respawn delay +RespawnDelayHelp=Time from death to respawning. +RelaunchCount=Relaunch count +RelaunchCountHelp=Amount of relaunches. Set it to -1 to enable infinite relaunches. \ No newline at end of file From 3a39ec9f9498fd55785af81fa84ea8c8c97843e9 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 25 Mar 2017 13:44:24 +0100 Subject: [PATCH 02/93] CaptureTheFlag: Enable unlimited relaunches --- .../Goals.ocd/CaptureTheFlag.ocd/Script.c | 30 ++++++------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c index 69a993435..edff8cfb4 100644 --- a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c @@ -18,6 +18,8 @@ func ScoreboardTeamID(int team) protected func Initialize() { score_list = []; + GetRelaunchRule()->SetRespawnDelay(0); + GetRelaunchRule()->SetDefaultRelaunches(nil); // init scoreboard Scoreboard->Init( @@ -75,38 +77,24 @@ private func EliminateOthers(int win_team) protected func InitializePlayer(int plr, int x, int y, object base, int team) { // Join new clonk. - JoinPlayer(plr); + GetRelaunchRule()->InitializePlayer(plr); + GetRelaunchRule()->DoRelaunch(iPlr, nil, RelaunchPosition(team), true); // make scoreboard entry for team Scoreboard->NewEntry(ScoreboardTeamID(team), GetTaggedTeamName(team)); - - // Broadcast to scenario. - GameCall("OnPlayerRelaunch", plr, false); return _inherited(plr, x, y, base, team, ...); } protected func RelaunchPlayer(int plr) { - // New clonk. - var clonk = CreateObjectAbove(Clonk, 0, 0, plr); - clonk->MakeCrewMember(plr); - SetCursor(plr, clonk); - // Join new clonk. - JoinPlayer(plr); - // Broadcast to scenario. - GameCall("OnPlayerRelaunch", plr, true); - return _inherited(plr, ...); + return GetRelaunchRule()->RelaunchPlayer(plr); } -private func JoinPlayer(int plr) +private func RelaunchPosition(int iTeam) { - var clonk = GetCrew(plr); - clonk->DoEnergy(100000); - var team = GetPlayerTeam(plr); - var base = FindObject(Find_ID(Goal_FlagBase), Find_Func("FindTeam", team)); - if (base) - clonk->SetPosition(base->GetX(), base->GetY() - 10); - return; + var base = FindObject(Find_ID(Goal_FlagBase), Find_Func("FindTeam", team)); + if (base) return [base->GetX(), base->GetY() - 10]; + return nil; } protected func RemovePlayer(int plr) From b31355391bbb7cfc1a59e7baebe99faefb59d64e Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 25 Mar 2017 13:44:42 +0100 Subject: [PATCH 03/93] DeathMatch: Enable unlimited relaunches --- .../Goals.ocd/DeathMatch.ocd/Script.c | 51 +------------------ 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c index d798983e7..eeef508a7 100644 --- a/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c @@ -23,66 +23,19 @@ func Initialize() } maxkills = GameCall("WinKillCount"); if(maxkills == nil || maxkills < 1) maxkills = 4; - return _inherited(...); -} - -protected func InitializePlayer(int plr) -{ - // Join plr. - JoinPlayer(plr); - // Scenario script callback. - GameCall("OnPlayerRelaunch", plr, false); - return _inherited(plr, ...); + GetRelaunchRule()->SetDefaultRelaunches(nil); + return _inherited(...); } protected func RelaunchPlayer(int plr, int killer) { _inherited(plr, killer, ...); - var clonk = CreateObjectAbove(Clonk, 0, 0, plr); - clonk->MakeCrewMember(plr); - SetCursor(plr, clonk); - JoinPlayer(plr); - // Scenario script callback. - GameCall("OnPlayerRelaunch", plr, true); // Show scoreboard for a while DoScoreboardShow(1, plr + 1); Schedule(this,Format("DoScoreboardShow(-1, %d)", plr + 1), 35 * ShowBoardTime); NotifyHUD(); return; } - -protected func JoinPlayer(int plr) -{ - var clonk = GetCrew(plr); - clonk->DoEnergy(100000); - var pos = FindRelaunchPos(plr); - clonk->SetPosition(pos[0], pos[1]); - return; -} - -private func FindRelaunchPos(int plr) -{ - var tx, ty; // Test position. - for (var i = 0; i < 500; i++) - { - tx = Random(LandscapeWidth()); - ty = Random(LandscapeHeight()); - if (GBackSemiSolid(AbsX(tx), AbsY(ty))) - continue; - if (GBackSemiSolid(AbsX(tx+5), AbsY(ty+10))) - continue; - if (GBackSemiSolid(AbsX(tx+5), AbsY(ty-10))) - continue; - if (GBackSemiSolid(AbsX(tx-5), AbsY(ty+10))) - continue; - if (GBackSemiSolid(AbsX(tx-5), AbsY(ty-10))) - continue; - // Succes. - return [tx, ty]; - } - return nil; -} - public func IsFulfilled() { // Check whether someone has reached the limit. From 82f3883486e8a12216caf776cedd632b579041c6 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 25 Mar 2017 13:45:19 +0100 Subject: [PATCH 04/93] Modify RelaunchContainer in order to work with Rule_Relaunch --- .../LastManStanding.ocd/Relaunch.ocd/Script.c | 55 ++++++++----------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c index 8b0c70f86..dc796211c 100644 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c @@ -3,34 +3,20 @@ Author: Maikel This container holds the clonk after relaunches. - * The time the clonk is held can be specified with SetRelaunchTime(int time); + * The time the clonk is held can be specified by calling GetRelaunchRule()->SetRespawnDelay(int time). * After that time the clonk is released and OnClonkLeftRelaunch(object clonk) is called in the scenario script. * Optionally the clonk can choose a weapon if GetRelaunchWeaponList in the scenario script returns a valid id-array. --*/ -local time; local menu; -local hold; local has_selected; local crew; -protected func Initialize() -{ - time = 36 * 10; - return; -} +// Sets the GetRelaunchRule().RelaunchTime, in seconds, the clonk is held in the container. -// Sets the time, in seconds, the clonk is held in the container. -public func SetRelaunchTime(int to_time, bool to_hold) -{ - time = to_time * 36; - hold = to_hold; - return; -} - -// Returns the time, in seconds the clonk is held. -public func GetRelaunchTime() { return time / 36; } +// Returns the GetRelaunchRule().RelaunchTime, in seconds the clonk is held. +public func GetRelaunchTime() { return GetRelaunchRule().RelaunchTime / 36; } // Retrieve weapon list from scenario. private func WeaponList() { return GameCall("RelaunchWeaponList"); } @@ -47,7 +33,6 @@ public func StartRelaunch(object clonk) clonk->Enter(this); ScheduleCall(this, "OpenWeaponMenu", 36, 0, clonk); AddEffect("IntTimeLimit", this, 100, 36, this); - return true; } @@ -62,11 +47,17 @@ private func OpenWeaponMenu(object clonk) { menu = CreateObject(MenuStyle_Default, nil, nil, clonk->GetOwner()); menu->SetPermanent(); - menu->SetTitle(Format("$MsgWeapon$", time / 36)); - clonk->SetMenu(menu, true); + menu->SetTitle(Format("$MsgWeapon$", GetRelaunchRule().RelaunchTime / 36)); + clonk->SetMenu(menu, true); + if(GetType(GetRelaunchRule().LastUsedPlayerWeapons) != C4V_Array) GetRelaunchRule().LastUsedPlayerWeapons = []; for (var weapon in weapons) - menu->AddItem(weapon, weapon->GetName(), nil, this, "OnWeaponSelected", weapon); + { + if(GetRelaunchRule().LastUsedPlayerWeapons[clonk->GetOwner()] != weapon) + { + menu->AddItem(weapon, weapon->GetName(), nil, this, "OnWeaponSelected", weapon); + } + } menu->Open(); } @@ -81,7 +72,7 @@ func FxIntTimeLimitTimer(object target, effect, int fxtime) RemoveObject(); return -1; } - if (fxtime >= time) + if (fxtime >= GetRelaunchRule().RelaunchTime) { if (!has_selected && WeaponList()) GiveWeapon(WeaponList()[Random(GetLength(WeaponList()))]); @@ -89,22 +80,23 @@ func FxIntTimeLimitTimer(object target, effect, int fxtime) return -1; } if (menu) - menu->SetTitle(Format("$MsgWeapon$", (time - fxtime) / 36)); + menu->SetTitle(Format("$MsgWeapon$", (GetRelaunchRule().RelaunchTime - fxtime) / 36)); else - PlayerMessage(clonk->GetOwner(), Format("$MsgRelaunch$", (time - fxtime) / 36)); + PlayerMessage(clonk->GetOwner(), Format("$MsgRelaunch$", (GetRelaunchRule().RelaunchTime - fxtime) / 36)); return 1; } public func OnWeaponSelected(id weapon) { + if(!crew) return; GiveWeapon(weapon); - + if(GetRelaunchRule().DisableLastWeapon) GetRelaunchRule().LastUsedPlayerWeapons[crew->GetOwner()] = weapon; has_selected = true; // Close menu manually, to prevent selecting more weapons. if (menu) menu->Close(); - if (!hold) + if (!GetRelaunchRule().Hold) RelaunchClonk(); return true; } @@ -131,12 +123,9 @@ private func RelaunchClonk() private func GiveWeapon(id weapon_id) { var newobj = CreateObjectAbove(weapon_id); - if (weapon_id == Bow) - newobj->CreateContents(Arrow); - if (weapon_id == Blunderbuss) - newobj->CreateContents(LeadBullet); - crew->Collect(newobj); - return; + newobj->~OnRelaunchCreation(crew); + crew->Collect(newobj); + return true; } public func SaveScenarioObject() { return false; } From 3de5261e8a7286b70265c53a0a25cbc600f0c8c1 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 25 Mar 2017 13:45:45 +0100 Subject: [PATCH 05/93] LastManStanding: Remove relaunch functionality which is handled by Rule_Relaunch --- .../Goals.ocd/LastManStanding.ocd/Script.c | 59 ------------------- 1 file changed, 59 deletions(-) diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Script.c index f68fd9a0c..78c48873a 100644 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Script.c @@ -4,8 +4,6 @@ Premade goal for simple melees with relaunches. Callbacks made to scenario script: - * OnPlayerRelaunch(int plr) made when the player is relaunched and at game start plr init. - * RelaunchCount() should return the number of relaunches. * KillsToRelaunch() should return how many kills will earn the player an extra relaunch. --*/ @@ -19,7 +17,6 @@ #include Scoreboard_Relaunch // Some rule default values -local DefaultRelaunchCount = 5; // Number of relaunches. local DefaultKillsToRelaunch = 4; // Number of kills one needs to make before gaining a relaunch. local ShowBoardTime = 5; // Duration in seconds the scoreboard will be shown to a player on an event. @@ -33,14 +30,6 @@ protected func Initialize() /*-- Scenario callbacks --*/ -private func RelaunchCount() -{ - var relaunch_cnt = GameCall("RelaunchCount"); - if (relaunch_cnt != nil) - return relaunch_cnt; - return DefaultRelaunchCount; -} - private func KillsToRelaunch() { var kills_to_relaunch = GameCall("KillsToRelaunch"); @@ -53,21 +42,12 @@ private func KillsToRelaunch() protected func InitializePlayer(int plr) { - // First process relaunches, etc. _inherited(plr, ...); - // Join plr. - JoinPlayer(plr); - // Scenario script callback. - GameCall("OnPlayerRelaunch", plr, false); - return; } protected func RelaunchPlayer(int plr, int killer) { _inherited(plr, killer, ...); - if (GetRelaunchCount(plr) < 0) - return EliminatePlayer(plr); - // the kill logs rule cares about logging the respawn // .. @@ -82,50 +62,11 @@ protected func RelaunchPlayer(int plr, int killer) Log("$MsgRelaunchGained$", GetPlayerName(killer)); } - var clonk = CreateObjectAbove(Clonk, 0, 0, plr); - clonk->MakeCrewMember(plr); - SetCursor(plr, clonk); - JoinPlayer(plr); - // Scenario script callback. - GameCall("OnPlayerRelaunch", plr, true); // Show scoreboard for a while. DoScoreboardShow(1, plr + 1); Schedule(this,Format("DoScoreboardShow(-1, %d)", plr + 1), 35 * ShowBoardTime); return; } - -protected func JoinPlayer(int plr) -{ - var clonk = GetCrew(plr); - clonk->DoEnergy(100000); - var pos = FindRelaunchPos(plr); - clonk->SetPosition(pos[0], pos[1]); - return; -} - -private func FindRelaunchPos(int plr) -{ - var tx, ty; // Test position. - for (var i = 0; i < 500; i++) - { - tx = Random(LandscapeWidth()); - ty = Random(LandscapeHeight()); - if (GBackSemiSolid(AbsX(tx), AbsY(ty))) - continue; - if (GBackSemiSolid(AbsX(tx+5), AbsY(ty+10))) - continue; - if (GBackSemiSolid(AbsX(tx+5), AbsY(ty-10))) - continue; - if (GBackSemiSolid(AbsX(tx-5), AbsY(ty+10))) - continue; - if (GBackSemiSolid(AbsX(tx-5), AbsY(ty-10))) - continue; - // Succes. - return [tx, ty]; - } - return nil; -} - protected func RemovePlayer(int plr) { return _inherited(plr, ...); From b0219b4614b0fb6a2ba949a5776e06e251df966d Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 25 Mar 2017 13:46:36 +0100 Subject: [PATCH 06/93] Modify Scoreboard_Relaunch in order to work with Rule_Relaunch --- .../Scoreboard.ocd/Relaunch.ocd/Script.c | 46 +++---------------- 1 file changed, 6 insertions(+), 40 deletions(-) diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Script.c index 03ff2bebc..15afb2b31 100644 --- a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Script.c @@ -10,24 +10,14 @@ * RemovePlayer(int plr); --*/ - -local score_relaunch_list; // Here the relaunch count of all players is stored, access through plrid. - -// Overload this. -public func RelaunchCount() -{ - return 5; -} - /*-- Callbacks --*/ protected func Initialize() { - // Make sure it is a list. - score_relaunch_list = []; // init scoreboard // init scoreboard, uses the condition of Scoreboard_Deaths too - Scoreboard->Init( + if(UnlimitedRelaunches()) return; + Scoreboard->Init( [{key = "relaunches", title = Scoreboard_Relaunch, sorted = true, desc = true, default = "", priority = 75, conditional = Scoreboard_Death.ScoreboardCondition}] ); return _inherited(...); @@ -35,20 +25,16 @@ protected func Initialize() protected func InitializePlayer(int plr) { - var plrid = GetPlayerID(plr); - // create scoreboard entry - score_relaunch_list[plrid] = RelaunchCount(); + if(UnlimitedRelaunches()) return; Scoreboard->NewPlayerEntry(plr); - Scoreboard->SetPlayerData(plr, "relaunches", score_relaunch_list[plrid]); + Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchCount(plr)); return _inherited(plr, ...); } protected func RelaunchPlayer(int plr, int killer) { - var plrid = GetPlayerID(plr); - // Modify scoreboard relaunch count entry for this player. - score_relaunch_list[plrid]--; - Scoreboard->SetPlayerData(plr, "relaunches", score_relaunch_list[plrid]); + if(UnlimitedRelaunches()) return; + Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchCount(plr)); return _inherited(plr, killer, ...); } @@ -59,26 +45,6 @@ protected func RemovePlayer(int plr) /*-- Misc --*/ -public func SetRelaunchCount(int plr, int value) -{ - var plrid = GetPlayerID(plr); - score_relaunch_list[plrid] = value; - Scoreboard->SetPlayerData(plr, "relaunches", score_relaunch_list[plrid]); - return; -} -public func GetRelaunchCount(int plr) -{ - var plrid = GetPlayerID(plr); - return score_relaunch_list[plrid]; -} - -public func DoRelaunchCount(int plr, int value) -{ - var plrid = GetPlayerID(plr); - score_relaunch_list[plrid] += value; - Scoreboard->SetPlayerData(plr, "relaunches", score_relaunch_list[plrid]); - return; -} local Name = "Scoreboard Relaunches"; From a4eacd793795469bbde7318d3bd4827a398e3df3 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 25 Mar 2017 13:46:58 +0100 Subject: [PATCH 07/93] Modify Rule_Killogs in order to work with Rule_Relaunch --- planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c index e58e10abe..db5c9c0a3 100644 --- a/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c @@ -42,16 +42,7 @@ func OnClonkDeathEx(object clonk, int plr, int killed_by) log=Format(Translate(Format("Teamkill%d", which_one)), GetTaggedPlayerName(plr), name, GetTaggedPlayerName(killed_by)); else log=Format(Translate(Format("KilledByPlayer%d", which_one)), GetTaggedPlayerName(plr), name, GetTaggedPlayerName(killed_by)); - // okay, why is GetRelaunchCount not a global function..? - // and why are the relaunches not stored in a static variable or a singleton that can be accessed somehow.. - var relaunches=nil; - for(var goal in FindObjects(Find_Or(Find_Category(C4D_Goal), Find_Category(C4D_Rule)))) - { - relaunches = goal->~GetRelaunchCount(plr); - if(relaunches != nil) break; - } - if(relaunches == nil) relaunches=GameCall("GetRelaunchCount", plr); - + var relaunches = GetRelaunchCount(plr); if(relaunches != nil) { var msg=""; From 13303c98af8a3fe7ea2ac2793813ac6577368a15 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 25 Mar 2017 14:28:18 +0100 Subject: [PATCH 08/93] Add Rule_BaseRespawn which sets Rule_Relaunch to base respawn mode in order to prevent breaking scenarios --- planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/DefCore.txt | 7 +++++++ planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/DefCore.txt create mode 100644 planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c diff --git a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/DefCore.txt b/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/DefCore.txt new file mode 100644 index 000000000..b597e8be4 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=Rule_BaseRespawn +Version=8,0 +Category=C4D_StaticBack | C4D_Rule +Width=32 +Height=32 +Offset=-16,-16 \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c new file mode 100644 index 000000000..ef5079937 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c @@ -0,0 +1,7 @@ +/* Converts itself to the Rule_Relaunch rule. */ + +protected func Construction() +{ + GetRelaunchRule()->SetBaseRespawn(true); + return RemoveObject(); +} \ No newline at end of file From 294b393f7e8f7ea6f333522e0d018e69462845f7 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 25 Mar 2017 14:31:00 +0100 Subject: [PATCH 09/93] RelaunchContainer: Use tabs for indentation --- .../LastManStanding.ocd/Relaunch.ocd/Script.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c index dc796211c..6c0ec85e8 100644 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c @@ -50,14 +50,14 @@ private func OpenWeaponMenu(object clonk) menu->SetTitle(Format("$MsgWeapon$", GetRelaunchRule().RelaunchTime / 36)); clonk->SetMenu(menu, true); - if(GetType(GetRelaunchRule().LastUsedPlayerWeapons) != C4V_Array) GetRelaunchRule().LastUsedPlayerWeapons = []; + if(GetType(GetRelaunchRule().LastUsedPlayerWeapons) != C4V_Array) GetRelaunchRule().LastUsedPlayerWeapons = []; for (var weapon in weapons) - { + { if(GetRelaunchRule().LastUsedPlayerWeapons[clonk->GetOwner()] != weapon) - { - menu->AddItem(weapon, weapon->GetName(), nil, this, "OnWeaponSelected", weapon); - } - } + { + menu->AddItem(weapon, weapon->GetName(), nil, this, "OnWeaponSelected", weapon); + } + } menu->Open(); } @@ -88,7 +88,7 @@ func FxIntTimeLimitTimer(object target, effect, int fxtime) public func OnWeaponSelected(id weapon) { - if(!crew) return; + if(!crew) return; GiveWeapon(weapon); if(GetRelaunchRule().DisableLastWeapon) GetRelaunchRule().LastUsedPlayerWeapons[crew->GetOwner()] = weapon; has_selected = true; @@ -124,8 +124,8 @@ private func GiveWeapon(id weapon_id) { var newobj = CreateObjectAbove(weapon_id); newobj->~OnRelaunchCreation(crew); - crew->Collect(newobj); - return true; + crew->Collect(newobj); + return true; } public func SaveScenarioObject() { return false; } From f74ee93b5ce541793a4a5becb6e3e5cb6d9f8d62 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 25 Mar 2017 14:32:52 +0100 Subject: [PATCH 10/93] DeathMatch: Use tabs for indentation --- planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c index eeef508a7..a7c4b489e 100644 --- a/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c @@ -24,7 +24,7 @@ func Initialize() maxkills = GameCall("WinKillCount"); if(maxkills == nil || maxkills < 1) maxkills = 4; GetRelaunchRule()->SetDefaultRelaunches(nil); - return _inherited(...); + return _inherited(...); } protected func RelaunchPlayer(int plr, int killer) @@ -47,7 +47,7 @@ public func IsFulfilled() // Otherwise just check if there are no enemies return Goal_Melee->IsFulfilled(); // Eliminate all players, that are not in a team with one of the winners - for (var i = 0; i < GetPlayerCount(); i++) + for (var i = 0; i < GetPlayerCount(); i++) { var plr = GetPlayerByIndex(i); if (winner == plr) @@ -70,7 +70,7 @@ public func GetDescription(int plr) { var score = GetRelativeScore(plr); if (score.kills > 0) - return Format("$MsgAhead$", score.kills, GetPlayerName(score.best)); + return Format("$MsgAhead$", score.kills, GetPlayerName(score.best)); else if (score.kills < 0) return Format("$MsgBehind$", -score.kills, GetPlayerName(score.best)); else if (score.best == plr) @@ -89,7 +89,7 @@ public func Activate(int byplr) else { var score = GetRelativeScore(byplr); - if(score.kills > 0) MessageWindow(Format("$MsgAhead$", score.kills, GetPlayerName(score.best)), byplr); + if(score.kills > 0) MessageWindow(Format("$MsgAhead$", score.kills, GetPlayerName(score.best)), byplr); else if(score.kills < 0) MessageWindow(Format("$MsgBehind$", -score.kills,GetPlayerName(score.best)), byplr); else if(score.best == byplr) MessageWindow(Format("$MsgYouAreBest$", score.kills), byplr); else MessageWindow(Format("$MsgEqual$", GetPlayerName(score.best)), byplr); From 731bf926c38d110bf23c21425c5c8ad4c26cfa1d Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 25 Mar 2017 14:33:05 +0100 Subject: [PATCH 11/93] CaptureTheFlag: Use tabs for indentation --- .../Goals.ocd/CaptureTheFlag.ocd/Script.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c index edff8cfb4..95df7fbab 100644 --- a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c @@ -18,8 +18,8 @@ func ScoreboardTeamID(int team) protected func Initialize() { score_list = []; - GetRelaunchRule()->SetRespawnDelay(0); - GetRelaunchRule()->SetDefaultRelaunches(nil); + GetRelaunchRule()->SetRespawnDelay(0); + GetRelaunchRule()->SetDefaultRelaunches(nil); // init scoreboard Scoreboard->Init( @@ -77,8 +77,8 @@ private func EliminateOthers(int win_team) protected func InitializePlayer(int plr, int x, int y, object base, int team) { // Join new clonk. - GetRelaunchRule()->InitializePlayer(plr); - GetRelaunchRule()->DoRelaunch(iPlr, nil, RelaunchPosition(team), true); + GetRelaunchRule()->InitializePlayer(plr); + GetRelaunchRule()->DoRelaunch(iPlr, nil, RelaunchPosition(team), true); // make scoreboard entry for team Scoreboard->NewEntry(ScoreboardTeamID(team), GetTaggedTeamName(team)); @@ -92,9 +92,9 @@ protected func RelaunchPlayer(int plr) private func RelaunchPosition(int iTeam) { - var base = FindObject(Find_ID(Goal_FlagBase), Find_Func("FindTeam", team)); + var base = FindObject(Find_ID(Goal_FlagBase), Find_Func("FindTeam", team)); if (base) return [base->GetX(), base->GetY() - 10]; - return nil; + return nil; } protected func RemovePlayer(int plr) From e62938b3e441325c00feb5a9fcc98e24002e5f4f Mon Sep 17 00:00:00 2001 From: Martin Strohmeier Date: Tue, 28 Mar 2017 16:09:35 +0200 Subject: [PATCH 12/93] Add Sandbox to Tutorials.ocf --- planet/Tutorials.ocf/Sandbox.ocs/Authors.txt | 3 + planet/Tutorials.ocf/Sandbox.ocs/DescDE.txt | 15 + planet/Tutorials.ocf/Sandbox.ocs/DescUS.txt | 15 + .../Sandbox.ocs/GodsHand.ocd/DefCore.txt | 7 + .../Sandbox.ocs/GodsHand.ocd/Graphics.png | Bin 0 -> 8345 bytes .../Sandbox.ocs/GodsHand.ocd/Script.c | 35 + .../Sandbox.ocs/GodsHand.ocd/StringTblDE.txt | 2 + .../Sandbox.ocs/GodsHand.ocd/StringTblUS.txt | 2 + planet/Tutorials.ocf/Sandbox.ocs/Map.c | 52 + .../Sandbox.ocs/Marker.ocd/DefCore.txt | 8 + .../Sandbox.ocs/Marker.ocd/Graphics.png | Bin 0 -> 3766 bytes .../Sandbox.ocs/Marker.ocd/Script.c | 55 + .../Sandbox.ocs/Marker.ocd/StringTblDE.txt | 2 + .../Sandbox.ocs/Marker.ocd/StringTblUS.txt | 2 + planet/Tutorials.ocf/Sandbox.ocs/Scenario.txt | 7 + planet/Tutorials.ocf/Sandbox.ocs/Script.c | 38 + .../Sandbox.ocs/Sound.ocg/warp.ogg | Bin 0 -> 10889 bytes .../Sandbox.ocs/SprayCan.ocd/DefCore.txt | 14 + .../Sandbox.ocs/SprayCan.ocd/Graphics.mesh | Bin 0 -> 19603 bytes .../SprayCan.ocd/Graphics.skeleton | Bin 0 -> 93 bytes .../Sandbox.ocs/SprayCan.ocd/Overlay.png | Bin 0 -> 203 bytes .../Sandbox.ocs/SprayCan.ocd/Script.c | 119 + .../Sandbox.ocs/SprayCan.ocd/SprayCan.jpg | Bin 0 -> 6204 bytes .../SprayCan.ocd/SprayCan.material | 37 + .../Sandbox.ocs/SprayCan.ocd/SprayCan.wav | Bin 0 -> 31956 bytes .../Sandbox.ocs/SprayCan.ocd/StringTblDE.txt | 2 + .../Sandbox.ocs/SprayCan.ocd/StringTblUS.txt | 2 + .../Sandbox.ocs/System.ocg/Clonk_SandboxUI.c | 2131 +++++++++++++++++ .../Sandbox.ocs/System.ocg/StringTblDE.txt | 91 + .../Sandbox.ocs/Teleporter.ocd/DefCore.txt | 7 + .../Sandbox.ocs/Teleporter.ocd/Graphics.png | Bin 0 -> 9777 bytes .../Sandbox.ocs/Teleporter.ocd/Script.c | 34 + .../Teleporter.ocd/StringTblDE.txt | 2 + .../Teleporter.ocd/StringTblUS.txt | 2 + planet/Tutorials.ocf/Sandbox.ocs/Title.txt | 2 + 35 files changed, 2686 insertions(+) create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Authors.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/DescDE.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/DescUS.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/DefCore.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/Graphics.png create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/Script.c create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/StringTblDE.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/StringTblUS.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Map.c create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Marker.ocd/DefCore.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Marker.ocd/Graphics.png create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Marker.ocd/Script.c create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Marker.ocd/StringTblDE.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Marker.ocd/StringTblUS.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Scenario.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Script.c create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Sound.ocg/warp.ogg create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/DefCore.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/Graphics.mesh create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/Graphics.skeleton create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/Overlay.png create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/Script.c create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/SprayCan.jpg create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/SprayCan.material create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/SprayCan.wav create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/StringTblDE.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/StringTblUS.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/System.ocg/Clonk_SandboxUI.c create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/System.ocg/StringTblDE.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/DefCore.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/Graphics.png create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/Script.c create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/StringTblDE.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/StringTblUS.txt create mode 100644 planet/Tutorials.ocf/Sandbox.ocs/Title.txt diff --git a/planet/Tutorials.ocf/Sandbox.ocs/Authors.txt b/planet/Tutorials.ocf/Sandbox.ocs/Authors.txt new file mode 100644 index 000000000..3ad84cb4b --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/Authors.txt @@ -0,0 +1,3 @@ +K-Pone - God's Hand (Original hand image comes from Icon_Hand) + +eleazzaar - Teleporter, CC-BY 3.0 http://opengameart.org/content/painterly-spell-icons-part-4 \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/DescDE.txt b/planet/Tutorials.ocf/Sandbox.ocs/DescDE.txt new file mode 100644 index 000000000..8c0979058 --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/DescDE.txt @@ -0,0 +1,15 @@ +Eine Karte zum Unfug treiben, ohne wenn und aber. Hier kannst du dich nach Lust und Laune austoben und kannst hier alles ausprobieren, was du möchtest. + +Folgende Werkzeuge stehen dir hier zur Verfügung: + +Landschaftsgenerator: +Erstelle eine Landschaft, wie sie dir gefällt. Du kannst jederzeit eine neue Landschaft generieren lassen. Du kannst auswählen, was du in der Landschaft vorfinden möchtest. Ob Wüste, Schneelandschaft oder Unterwasserwelt: Du entscheidest. + +Materialpinsel: +Was Entwickler im Editor können, kannst du hier mit diesem Werkzeug erledigen. Die ganze Materialienpalette steht dir zur Verfügung. + +Objekterzeuger: +Was fehlt, kannst du hiermit erschaffen, ganz egal, ob Gegenstände, Gebäuden oder Fahrzeuge. + +Marker: +Ein praktisches, vielseitiges Hilfmittel. Kann als Respawnpunkt und als Teleporter benutzt werden. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/DescUS.txt b/planet/Tutorials.ocf/Sandbox.ocs/DescUS.txt new file mode 100644 index 000000000..36806b2e6 --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/DescUS.txt @@ -0,0 +1,15 @@ +A scenario to play around with all the cool stuff. + +The following tools can be used: + +Landscape Generator: +Create the landscape as you wish. You can choose what kind of things you want to have on the map. Desert, Snowlands or Underwaterworld, it's up to you. + +Material Brush: +What developers can do in the editor can be done by you using this tool. You get the full palette of materials. + +Object Creator: +Whatever is missing, you could create it using this tool, no matter if object, building or vehicle. + +Marker: +A tool to mark the spot. Can be used for Respawns and Teleports. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/DefCore.txt b/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/DefCore.txt new file mode 100644 index 000000000..36d5bdb4b --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=GodsHand +Version=5,2,0,1 +Category=C4D_Object +Width=64 +Height=64 +Offset=-32,-32 \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/Graphics.png b/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/Graphics.png new file mode 100644 index 0000000000000000000000000000000000000000..89b39a4af6cc33f4b36104da0f4b71b0854c3ef1 GIT binary patch literal 8345 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 literal 0 HcmV?d00001 diff --git a/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/Script.c b/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/Script.c new file mode 100644 index 000000000..7b599dc11 --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/Script.c @@ -0,0 +1,35 @@ + +/* + + God's Hand, a tool to create objects. + + @author: K-Pone + +*/ + + +local Name = "$Name$"; +local Description = "$Description$"; + +func Initialize() +{ + +} + +func ControlUse(object clonk, x, y) +{ + var objdef = clonk.ObjectSpawnDefinition; + + + if (objdef == Marker) + { + var marker = clonk->PlaceNewMarker(); + if (marker) marker->SetPosition(clonk->GetX() + x, clonk->GetY() + y); + } + else + { + clonk->CreateObject(objdef, x, y); + } + + Sound("UI::Click", true, nil, clonk->GetOwner()); +} \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/StringTblDE.txt b/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/StringTblDE.txt new file mode 100644 index 000000000..54b201f70 --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Hand Gottes +Description=Erzeugt zeugs. Was du willst, wo du willst. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/StringTblUS.txt b/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/StringTblUS.txt new file mode 100644 index 000000000..9ea7d97cb --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/GodsHand.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=God's Hand +Description=Creates things. What you want, where you want. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/Map.c b/planet/Tutorials.ocf/Sandbox.ocs/Map.c new file mode 100644 index 000000000..3432e6b4d --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/Map.c @@ -0,0 +1,52 @@ + + +func InitializeMap(proplist map) +{ + if (!MapGenPreset) MapGenPreset = "FlatLand"; // For the initial map on scenario start + + // These were set in the MapGen UI + Resize(MapGenSizeWidth ?? 80, MapGenSizeHeight ?? 50); + + if (MapGenPreset == "FlatLand") + { + Draw("Earth", { Algo = MAPALGO_Rect, X = 0, Y = MapGenSizeHeight / 2, Wdt = MapGenSizeWidth, Hgt = MapGenSizeHeight / 2 + 1 } ); + } + else if (MapGenPreset == "Skylands") + { + var islands = + { + Algo = MAPALGO_Turbulence, + Op = { Algo=MAPALGO_RndChecker, Wdt=5, Hgt=2, Ratio = 10 } + }; + + Draw("Earth", islands); + } + else if (MapGenPreset == "Caves") + { + Draw("Earth", { Algo = MAPALGO_Rect, X = 0, Y = 0, Wdt = MapGenSizeWidth, Hgt = MapGenSizeHeight } ); + + + for (var i = 0; i < 3; i++) + { + var tunnels = + { + Algo = MAPALGO_Polygon, + X = [Random(MapGenSizeWidth),Random(MapGenSizeWidth)], + Y = [Random(MapGenSizeHeight),Random(MapGenSizeHeight)], + Wdt = Random(10) + 3, + Empty = true, + Open = true + }; + + Draw("Tunnel", tunnels); + } + } + + + return true; +} + +global func PostMapGen() +{ + // This is called after the map is generated. Should be used to place environment objects. +} \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/Marker.ocd/DefCore.txt b/planet/Tutorials.ocf/Sandbox.ocs/Marker.ocd/DefCore.txt new file mode 100644 index 000000000..527499520 --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/Marker.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Marker +Version=5,2,0,1 +Category=C4D_StaticBack | C4D_IgnoreFoW +Width=20 +Height=20 +Offset=-10,-10 +Picture=0,0,64,64 \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/Marker.ocd/Graphics.png b/planet/Tutorials.ocf/Sandbox.ocs/Marker.ocd/Graphics.png new file mode 100644 index 0000000000000000000000000000000000000000..c828a1cc7c15496766bf4ef146bcd9a540432e14 GIT binary patch literal 3766 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

xRK*h4G!!t88KO8u4;7^VnJ9Z?S&5lTtBnX0V z?BKzJ$Daj&S11&&1wrsPzV8dH1SS2}pS}ZdKQdI}2-S+}^bO9f+tGFQkj8GeF^{pL z0_hrnM*to^eE9JG!-o&gyzUzC4gS(a2TmsggSmM#JKfm`V~iFw164AJqz1 z0X(v8d-dMEd+koA(-F6EvsI~7zG0G>g+V5hc?rNM0A-ha5Eeur+y^iN;NKP(7k{-K z0K9BAd&Bd*fXU)W749K~j7RLdn;MNgbq>I9wgW(@>-yK_a(Rt;fhdYFO*8+}OD`RX zgvf4dj2qUr0{|{wytt%k+7Ao>K@i}&t}-?@_HraTMC{HMZg=9ArfFL~qalPqmgU{X z1K93%_^G(bX0tbfAfOBY#si9??A?Vtuwwwi$B!R>Q!15Kc^pegd3cxdz>WaG zrAwEdXqxstpAKEuRcf``Pj@p9>}1k*wOZ}*K=e8ailXdl9@q&0R8f@ck|eo|2SibX z=Xtf=%mX_CAY55lxm73>R@p1<=RgnaEN(AfzFe=>YIpdrIXuskYqi=R=Xd1D9SZa6m4D)c%D~Fr_=kQGS#kX(oSz6ggDu3_AhPQF0uLm zrIci|*&o-}*XN^s|8wgBxOwyDMx|2uj)g(=B2pe59X+}m^}sNbbxNhuS4fCPPfuZ7cVPT=AY1*CGzCf;4t1s_1JuvJ1wpu; zPNxn2^||MHqpGUz-%UIq4SQp=*)+$-#@@9otIG6%<2a;LDlOLQ^{+9+m)pC^1F*Qb z*w!@dzt{%}0FX|nLjYp{O1}%Zf5=9DhkKo3v3TW$7hX6eNmAK$UE#rl2kqtMWf~D7 g!5{7o(9rF_0Tmj8w4Ze}e*gdg07*qoM6N<$f^ShowSandboxUI(); + + crew->CreateContents(GodsHand); + crew->CreateContents(SprayCan); + crew->CreateContents(Teleporter); + + GiveAllKnowledge(); + + crew.MaxContentsCount = 8; +} + +func GiveAllKnowledge() +{ + var i, id; + while (id = GetDefinition(i++)) + { + SetPlrKnowledge(nil, id); + } +} diff --git a/planet/Tutorials.ocf/Sandbox.ocs/Sound.ocg/warp.ogg b/planet/Tutorials.ocf/Sandbox.ocs/Sound.ocg/warp.ogg new file mode 100644 index 0000000000000000000000000000000000000000..2f73d9b2e9e161e1fd0d38c78eda52f4fad31ae6 GIT binary patch literal 10889 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 M8a`^I06-h?KWYc}7XSbN literal 0 HcmV?d00001 diff --git a/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/Graphics.skeleton b/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/Graphics.skeleton new file mode 100644 index 0000000000000000000000000000000000000000..715b84b45d5d0b8e6b5a2cefe4d0de818c165dcd GIT binary patch literal 93 zcmZP&hz?FI%1q43tV%74FEiA$Fo@+65a3_{0|gZzm7AEE$Hl;qzSY6D*kJaq@*67q mgI*Qyp7l=K2Bhf2?|OR%2XT1=!Isl^o!2B4PZabeesQ^#Lpt-BFRVbVR0ki@R{MD#jP1I{$~`NN>kr6$Pgg&e IbxsLQ0H-7)`2YX_ literal 0 HcmV?d00001 diff --git a/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/Script.c b/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/Script.c new file mode 100644 index 000000000..d8106af50 --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/Script.c @@ -0,0 +1,119 @@ +/* Spray can */ + +local last_x, last_y, last_ldx, last_ldy; +local paint_col; +local paint_bg; +local max_dist = 50; +local brushmode = 1; // 1 = Draw Brush, 2 = Quad Brush, 3 = Eraser + +func Construction() +{ + SetColor(RGB(Random(256),Random(256),Random(256))); +} + +// Impact sound +public func Hit() +{ + Sound("Hits::GeneralHit?"); +} + +// Item activation +public func ControlUseStart(object clonk, int x, int y) +{ + paint_col = clonk.SelectedBrushMaterial; + paint_bg = clonk.SelectedBrushBgMaterial; + brushmode = clonk.SelectedBrushMode; + return ControlUseHolding(clonk, x, y); +} + +public func HoldingEnabled() { return true; } + +public func ControlUseHolding(object clonk, int new_x, int new_y) +{ + // Out of reach? Stop spraying. // Not for Gods like Sandboxers ;) + //if (Distance(0,0,new_x,new_y) > max_dist) + //{ + //SetAction("Idle"); + //return true; + //} + + // Work in global coordinates + new_x += GetX(); new_y += GetY(); + + // (re-)start spraying + if (GetAction() != "Spraying") StartSpraying(clonk, new_x, new_y); + + // Spray paint if position moved + if (new_x==last_x && new_y == last_y) return true; + var wdt = clonk.SelectedBrushSize; + var dx=new_x-last_x, dy=new_y-last_y; + var d = Distance(dx,dy); + var ldx = dy*wdt/d, ldy = -dx*wdt/d; + if (!last_ldx && !last_ldy) { last_ldx=ldx; last_ldy=ldy; } + + if (brushmode == 1) + { + DrawMaterialQuad(paint_col, last_x-last_ldx,last_y-last_ldy, last_x+last_ldx,last_y+last_ldy, new_x+ldx,new_y+ldy, new_x-ldx,new_y-ldy, paint_bg); + } + + else if (brushmode == 2) + { + DrawMaterialQuad(paint_col, new_x - (wdt / 2), new_y - (wdt / 2), new_x + (wdt / 2), new_y - (wdt / 2), new_x + (wdt / 2), new_y + (wdt / 2), new_x - (wdt / 2), new_y + (wdt / 2), paint_bg ); + } + + else if (brushmode == 3) + { + // Draw something to set BG Mat to sky (workaround for not being able to draw Sky via DrawMaterialQuad) + DrawMaterialQuad(paint_col, new_x - (wdt / 2), new_y - (wdt / 2), new_x + (wdt / 2), new_y - (wdt / 2), new_x + (wdt / 2), new_y + (wdt / 2), new_x - (wdt / 2), new_y + (wdt / 2), DMQ_Sky ); + ClearFreeRect(new_x - (wdt / 2), new_y - (wdt / 2), wdt, wdt); + } + + last_x = new_x; last_y = new_y; + last_ldx = ldx; last_ldy = ldy; + return true; +} + +public func ControlUseStop(object clonk, int x, int y) +{ + SetAction("Idle"); + return true; +} + +public func ControlUseCancel(object clonk, int x, int y) +{ + SetAction("Idle"); + return true; +} + +private func StartSpraying(object clonk, int x, int y) +{ + // Go into spray mode and place an initial blob + last_x = x; last_y = y; + last_ldx=last_ldy=0; + var r = Random(90), wdt = 2; + var ldx = Sin(r, wdt), ldy = Cos(r, wdt); + DrawMaterialQuad(paint_col, x-ldx,y-ldy, x-ldy,y+ldx, x+ldx,y+ldy, x+ldy,y-ldx, paint_bg); + SetAction("Spraying"); + return true; +} + + +local ActMap = { + Spraying = { + Prototype = Action, + FacetBase = 1, + Length = 1, + Delay = 1, + Name = "Spraying", + Sound = "SprayCan::SprayCan", + NextAction = "Spraying", + } +}; + +func Definition(def) { + SetProperty("PictureTransformation",Trans_Rotate(-30,0,1,1),def); +} + +local Collectible = 1; +local Name = "$Name$"; +local Description = "$Description$"; diff --git a/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/SprayCan.jpg b/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/SprayCan.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4b287a591ec125cafe6aa4f0c525543c9c771697 GIT binary patch literal 6204 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 literal 0 HcmV?d00001 diff --git a/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/SprayCan.material b/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/SprayCan.material new file mode 100644 index 000000000..c2b7cd5c9 --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/SprayCan.material @@ -0,0 +1,37 @@ +material SprayCan +{ + receive_shadows on + + technique + { + pass SprayCan + { + ambient 0.500000 0.500000 0.500000 1.000000 + diffuse 1.000000 1.000000 1.000000 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 12.500000 + emissive 0.000000 0.000000 0.000000 1.000000 + + texture_unit Overlay + { + texture Overlay.png + tex_address_mode wrap + filtering trilinear + colour_op_ex modulate src_texture src_player_colour + } + texture_unit SprayCan + { + texture SprayCan.jpg + tex_address_mode wrap + filtering trilinear + colour_op_ex blend_current_alpha src_current src_texture + } + texture_unit Light + { + // apply lighting -- note this texture unit does not need an + // actual texture image: no hardware TIU will be used. + colour_op_ex modulate src_current src_diffuse + alpha_op_ex modulate src_current src_diffuse + } + } + } +} diff --git a/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/SprayCan.wav b/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/SprayCan.wav new file mode 100644 index 0000000000000000000000000000000000000000..16ed40fdead75c35ee0d40559d72d5cd9443f966 GIT binary patch literal 31956 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 literal 0 HcmV?d00001 diff --git a/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/StringTblDE.txt b/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/StringTblDE.txt new file mode 100644 index 000000000..e1fbaa874 --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Sprühdose +Description=Lasse den kleinen Künstler in dir heraus! \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/StringTblUS.txt b/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/StringTblUS.txt new file mode 100644 index 000000000..3343a975e --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/SprayCan.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Spray can +Description=Let out the little artist in you! \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/System.ocg/Clonk_SandboxUI.c b/planet/Tutorials.ocf/Sandbox.ocs/System.ocg/Clonk_SandboxUI.c new file mode 100644 index 000000000..20baf5eeb --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/System.ocg/Clonk_SandboxUI.c @@ -0,0 +1,2131 @@ + +#appendto Clonk + +local idHudSandbox; +local idHudOS; + +local idGuiHudOS_catselect = 100; +local idGuiHudOS_objectselect = 101; +local idGuiHudOS_switchspawndest = 102; + +protected func Death(int killed_by) +{ + HideSandboxUI(); + return _inherited(killed_by, ...); +} + +func ShowSandboxUI() +{ + var SandboxUI = + { + Player = GetOwner(), + Style = GUI_Multiple, + + ButtonBar = + { + Left = "10em", + Top = "0.5em", + Bottom = "2.5em", + Right = "20em", + + BtnObjectspawn = + { + Top = "0em", + Bottom = "2em", + Left = "0em", + Right = "2em", + + Symbol = Hammer, + Tooltip = "$TooltipObjectspawn$", + + BackgroundColor = { Std = RGBa(128, 128, 128, 128), Hover = RGBa(128, 255, 128, 128) }, + + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(this, "BtnObjectSpawnClick"), + }, + + BtnLandscapeBrush = + { + Top = "0em", + Bottom = "2em", + Left = "2em", + Right = "4em", + + Symbol = SprayCan, + Tooltip = "$TooltipLandscapeBrush$", + + BackgroundColor = { Std = RGBa(128, 128, 128, 128), Hover = RGBa(128, 255, 128, 128) }, + + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(this, "BtnLandscapeBrushClick"), + }, + + BtnMarker = + { + Top = "0em", + Bottom = "2em", + Left = "4em", + Right = "6em", + + Symbol = ParkourFlag, + Tooltip = "$TooltipMarker$", + + BackgroundColor = { Std = RGBa(128, 128, 128, 128), Hover = RGBa(128, 255, 128, 128) }, + + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(this, "BtnMarkerClick"), + }, + + BtnMapGen = + { + Top = "0em", + Bottom = "2em", + Left = "6em", + Right = "8em", + + Symbol = Icon_World, + Tooltip = "$TooltipMapGen$", + + BackgroundColor = { Std = RGBa(128, 128, 128, 128), Hover = RGBa(128, 255, 128, 128) }, + + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(this, "BtnMapGenClick"), + }, + + BtnTweaks = + { + Top = "0em", + Bottom = "2em", + Left = "8em", + Right = "10em", + + Symbol = Icon_Lightbulb, + Tooltip = "$TooltipTweaks$", + + BackgroundColor = { Std = RGBa(128, 128, 128, 128), Hover = RGBa(128, 255, 128, 128) }, + + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(this, "BtnTweaksClick"), + }, + }, + + GodsHandDisplay = + { + Top = "2.5em", + Left = "10em", + Right = "20em", + Bottom = "3.5em", + BackgroundColor = RGBa(96,96,96,96), + Tooltip = "$GodsHandDisplayTT$", + + icon = + { + Symbol = GodsHand, + Right = "1em", + }, + + icon2 = + { + Symbol = ObjectSpawnDefinition, + Left = "1.5em", + Right = "2.5em", + }, + + text = + { + Text = ObjectSpawnDefinition.Name, + Left = "2.75em", + Style = GUI_TextVCenter, + } + } + }; + + + idHudSandbox = GuiOpen(SandboxUI); + + return idHudSandbox; +} + +func UpdateGodsHandDisplay() +{ + var update = + { + GodsHandDisplay = + { + icon2 = + { + Symbol = ObjectSpawnDefinition + }, + + text = + { + Text = ObjectSpawnDefinition.Name + } + } + }; + + GuiUpdate(update, idHudSandbox); +} + +func HideSandboxUI() +{ + if (idHudSandbox) + { + GuiClose(idHudSandbox); + idHudSandbox = nil; + } +} + +func BtnObjectSpawnClick() +{ + ShowObjectSpawnUI(); +} + +func BtnLandscapeBrushClick() +{ + ShowMaterialBrushUI(); +} + +func BtnMarkerClick() +{ + ShowMarkerUI(); +} + +func BtnMapGenClick() +{ + ShowMapGenUI(); +} + +func BtnTweaksClick() +{ + ShowTweaksUI(); +} + +local ObjectSpawnTarget = 1; // 1 = Spawn on Clonk/Inventory, 2 = God's Hand +local ObjectSpawnDefinition = Wood; // Definition to spawn by God's Hand + +local ObjectSpawnMenuOpts = +{ + ProductionResources = + { + Priority = 2, + Caption = "$OSCatProductionResources$", + Icon = Ore, + Items = [Rock, Ore, Coal, Firestone, Nugget, Metal, Wood, Moss, Ruby, Amethyst, GoldBar, Firestone, Ice] + }, + + Foodstuff = + { + Priority = 3, + Caption = "$OSCatFoodstuff$", + Icon = Bread, + Items = [Bread, Mushroom, CookedMushroom, Sproutberry, Coconut] + }, + + Liquids = + { + Priority = 4, + Caption = "$OSCatLiquids$", + Icon = Water, + Items = [Water, Acid, Lava, DuroLava, Oil, Concrete] + }, + + Tools = + { + Priority = 5, + Caption = "$OSCatTools$", + Icon = Hammer, + Items = [Hammer, Shovel, Axe, Pickaxe, Sickle, TeleGlove, Torch, WallKit, Ropeladder, Ropebridge, GrappleBow, Balloon, Boompack, WindBag, Lantern, Bucket, Barrel, MetalBarrel, Pipe, Crate, Dynamite, DynamiteBox, Lorry] + }, + + Weapons = + { + Priority = 6, + Caption = "$OSCatWeapons$", + Icon = Sword, + Items = [Shield, Helmet, Sword, Club, Bow, Arrow, FireArrow, BombArrow, Blunderbuss, LeadBullet, Javelin, GrenadeLauncher, IronBomb, SmokeBomb, Boompack, Lantern, Cannon, Catapult] + }, + + Explosives = + { + Priority = 7, + Caption = "$OSCatExplosives$", + Icon = Dynamite, + Items = [Firestone, Dynamite, DynamiteBox, IronBomb, PowderKeg, Lantern] + }, + + Vehicles = + { + Priority = 8, + Caption = "$OSCatVehicles$", + Icon = Airship, + Items = [Airship, Airplane] + }, + + Animals = + { + Priority = 9, + Caption = "$OSCatAnimals$", + Icon = Wipf, + Items = [Wipf, Bat, Butterfly, Chippie, Firefly, Fish, Piranha, Puka, Mooq, Shark, Squid, Zap, Mosquito] + }, + + Plants = + { + Priority = 10, + Caption = "$OSCatPlants$", + Icon = Flower, + Items = [Tree_Coniferous, Tree_Coniferous2, Tree_Coniferous3, Tree_Coniferous4, Tree_Deciduous, Tree_Coconut, LargeCaveMushroom, Cotton_Branch, Coral, Seaweed, SproutBerryBush, Lichen, Fern, Grass, Branch, Trunk, Vine, Wheat] + }, + + GodTools = + { + Priority = 99, + Caption = "$OSCatGodTools$", + Icon = GodsHand, + Items = [GodsHand, SprayCan, Teleporter, Marker] + } +}; + +func ShowObjectSpawnUI() +{ + var SpawnUI = + { + Decoration = GUI_MenuDeco, + Player = GetOwner(), + + CatSelect = + { + ID = idGuiHudOS_catselect, + Left = "0%", + Right = "25%", + Top = "2em", + Bottom = "100% - 2em", + + BackgroundColor = RGBa(32,32,32,224), + Style = GUI_VerticalLayout, + }, + + SwitchSpawnDest = + { + ID = idGuiHudOS_switchspawndest, + Top = "100% - 2em", + Right = "25%", + BackgroundColor = { Std = RGBa(32,32,128,128), Hover = RGBa(128,128,192,128) }, + Tooltip = GetObjectSpawnDestTooltip(), + + icon = + { + Symbol = GetObjectSpawnDestSymbol(), + Right = "2em", + }, + + text = + { + Text = GetObjectSpawnDest(), + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "SwitchObjectSpawnDest"), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + ObjectSelect = + { + ID = idGuiHudOS_objectselect, + Left = "25%", + Right = "100%", + Top = "2em", + Bottom = "100% - 2em", + BackgroundColor = RGBa(64,64,64,224), + }, + + HintTarget = + { + Left = "25%", + Top = "100% - 2em", + BackgroundColor = RGBa(128,128,128,224), + + icon = + { + Symbol = Icon_Arrow, + GraphicsName = "Left", + Right = "2em", + }, + + text = + { + Text = "$OSHintTarget$", + Left = "2.5em", + Style = GUI_TextVCenter, + } + } + + }; + + var index = 0; + for (var property in GetProperties(ObjectSpawnMenuOpts)) + { + index++; + var entry = ObjectSpawnMenuOpts[property]; + + var catentry = + { + ID = 1000 + index, + Priority = entry.Priority, + Bottom = "+2em", + Right = "100% - 1em", + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + icon = + { + Symbol = entry.Icon, + Right = "2em" + }, + + text = + { + Text = entry.Caption, + Left = "+2.5em", + Style = GUI_TextVCenter + }, + + OnClick = GuiAction_Call(this, "ObjectSpawnSelectCat", [entry]), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std") + }; + + GuiAddSubwindow(catentry, SpawnUI.CatSelect); + } + + GuiAddCloseButton(SpawnUI, this, "HideObjectSpawnUI"); + + idHudOS = GuiOpen(SpawnUI); + + SetMenu(idHudOS); + + return idHudOS; +} + +func HideObjectSpawnUI() +{ + if (idHudOS) + { + GuiClose(idHudOS); + MenuClosed(); + idHudOS = nil; + } +} + +func GetObjectSpawnDest() +{ + if (ObjectSpawnTarget == 1) return "$OSTargetClonk$"; + if (ObjectSpawnTarget == 2) return "$OSTargetGodsHand$"; +} + +func GetObjectSpawnDestSymbol() +{ + if (ObjectSpawnTarget == 1) return Clonk; + if (ObjectSpawnTarget == 2) return GodsHand; +} + +func GetObjectSpawnDestTooltip() +{ + if (ObjectSpawnTarget == 1) return "$OSTargetClonkTT$"; + if (ObjectSpawnTarget == 2) return "$OSTargetGodsHandTT$"; +} + +func SwitchObjectSpawnDest() +{ + ObjectSpawnTarget++; + if (ObjectSpawnTarget > 2) ObjectSpawnTarget = 1; + + var update = + { + SwitchSpawnDest = + { + ID = idGuiHudOS_switchspawndest, + Top = "100% - 2em", + Right = "25%", + BackgroundColor = { Std = RGBa(32,32,128,128), Hover = RGBa(128,128,192,128) }, + Tooltip = GetObjectSpawnDestTooltip(), + + icon = + { + Symbol = GetObjectSpawnDestSymbol(), + Right = "2em", + }, + + text = + { + Text = GetObjectSpawnDest(), + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "SwitchObjectSpawnDest"), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + }; + + GuiClose(idHudOS, idGuiHudOS_switchspawndest); + GuiUpdate(update, idHudOS); +} + +func ObjectSpawnSelectCat(data, int player, int ID, int subwindowID, object target) +{ + GuiClose(idHudOS, idGuiHudOS_objectselect); + var objectselect = + { + ID = idGuiHudOS_objectselect, + Left = "25%", + Right = "100%", + Top = "2em", + BackgroundColor = RGBa(64,64,64,224), + + Style = GUI_GridLayout, + }; + GuiUpdate({ ObjectSelect = objectselect }, idHudOS); + + var cat = data[0]; + + var index = 0; + for (var item in cat.Items) + { + index++; + + var objentry = + { + ID = 2000 + index, + Priority = index, + Bottom = "+2em", + Right = "+8em", + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + Tooltip = item.Description, + + icon = + { + Symbol = item, + Right = "+2em" + }, + + text = + { + Text = item.Name, + Left = "+2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "ObjectSpawnSelectObject", [item]), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }; + + GuiAddSubwindow(objentry, objectselect); + } + + GuiUpdate(objectselect, idHudOS, idGuiHudOS_objectselect); +} + +func ObjectSpawnSelectObject(data, int player, int ID, int subwindowID, object target) +{ + var clonk = GetCursor(player); + var obj = data[0]; + + if (ObjectSpawnTarget == 1) + { + // Spawn in Clonk Inventory + + if (obj == Marker) + { + PlaceNewMarker(); + return; + } + + var spawnlocation = 2; // 1 = Inventory, 2 = Outside, 3 = Outside Above + + // Normal objects can spawn in Inventory + if (obj->GetCategory() & C4D_Object) + spawnlocation = 1; + + // Livings spawn outside the clonk + if (obj->GetCategory() & C4D_Living) + spawnlocation = 2; + + // Vehicles spawn above to avoid being stuck + if (obj->GetCategory() & C4D_Vehicle) + spawnlocation = 3; + + + //if (spawnlocation == 1) clonk->CreateContents(obj); + if (spawnlocation == 1) clonk->Collect(CreateObject(obj)); + if (spawnlocation == 2) clonk->CreateObject(obj); + if (spawnlocation == 3) clonk->CreateObjectAbove(obj, 0, 0); + } + else if (ObjectSpawnTarget == 2) + { + // Select for God's Hand + clonk.ObjectSpawnDefinition = obj; + HideObjectSpawnUI(); + UpdateGodsHandDisplay(); + } + + // TODO: Prüfung wo das Objekt erzeugt werden soll (Inventar/Aussen) + // TODO: Prüfen, was mit dem ausgewählten Objekt passieren soll (Spawn/Hand of god) +} + +local SelectedBrushMaterial = "Earth-earth"; +local SelectedBrushBgMaterial = "Tunnel-tunnel"; +local SelectedBrushSize = 8; +local SelectedBrushMode = 1; // 1 = Draw Brush, 2 = Quad Brush, 3 = Eraser + +local BrushMaterials = +{ + Earth = { Icon = Earth, Caption = "$MatEarth$", Material = "Earth-earth" }, + EarthSpongy = { Icon = Earth, Caption = "$MatEarthSpongy$", Material = "Earth-earth_spongy" }, + EarthRoot = { Icon = Earth, Caption = "$MatEarthRoot$", Material = "Earth-earth_root" }, + Sand = { Icon = Sand, Caption = "$MatSand$", Material = "Sand-sand" }, + SandDry = { Icon = Sand, Caption = "$MatSandDry$", Material = "SandDry-sand" }, + Ice = { Icon = Ice, Caption = "$MatIce$", Material = "Ice-ice" }, + Ice2 = { Icon = Ice, Caption = "$MatIce2$", Material = "Ice-ice2" }, + Snow = { Icon = Snow, Caption = "$MatSnow$", Material = "Snow-snow1" }, + Rock = { Icon = Rock, Caption = "$MatRock$", Material = "Rock-rock" }, + RockSmooth = { Icon = Rock, Caption = "$MatRockSmooth$", Material = "Rock-rock_smooth" }, + Granite = { Icon = Rock, Caption = "$MatGranite$", Material = "Granite-granite" }, + Ore = { Icon = Ore, Caption = "$MatOre$", Material = "Ore-ore" }, + Gold = { Icon = Nugget, Caption = "$MatGold$", Material = "Gold-gold" }, + Coal = { Icon = Coal, Caption = "$MatCoal$", Material = "Coal-coal" }, + Firestone = { Icon = Firestone, Caption = "$MatFirestone$", Material = "Firestone-firestone" }, + Ruby = { Icon = Ruby, Caption = "$MatRuby$", Material = "Ruby-ruby" }, + Amethyst = { Icon = Amethyst, Caption = "$MatAmethyst$", Material = "Amethyst-amethyst" }, + Ashes = { Icon = Ashes, Caption = "$MatAshes$", Material = "Ashes-ashes" }, + Brick = { Icon = WallKit, Caption = "$MatBrick$", Material = "Brick-brick" }, + BrickSoft = { Icon = WallKit, Caption = "$MatBrickSoft$", Material = "BrickSoft-brick" }, + Everrock = { Icon = Metal, Caption = "$MatEverrock$", Material = "Everrock-everrock" }, + Water = { Icon = Water, Caption = "$MatWater$", Material = "Water-water" }, + Acid = { Icon = Acid, Caption = "$MatAcid$", Material = "Acid-acid" }, + Lava = { Icon = Lava, Caption = "$MatLava$", Material = "Lava-lava_red" }, + DuroLava = { Icon = DuroLava, Caption = "$MatDuroLava$", Material = "DuroLava-lava_red" }, + Oil = { Icon = Oil, Caption = "$MatOil$", Material = "Oil-oil" }, + Tunnel = { Icon = Earth, Caption = "$MatTunnel$", Material = "Tunnel-tunnel" }, + Backwall = { Icon = Earth, Caption = "$MatTunnelBrick$", Material = "Tunnel-brickback" } +}; + +local BrushBackgroundMaterials = +{ + Sky = { Icon = Earth, Caption = "$MatBgSky$", Material = DMQ_Sky }, + Tunnel = { Icon = Earth, Caption = "$MatBgTunnel$", Material = "Tunnel-tunnel" }, + Bricks = { Icon = Earth, Caption = "$MatBgBricks$", Material = "Tunnel-brickback" } +}; + +local idHudMB; + +local idGuiHudMB_MatSelect = 300; +local idGuiHudMB_MatBgSelect = 301; +local idGuiHudMB_SizeSelect = 302; +local idGuiHudMB_ModeSelect = 303; + +func ShowMaterialBrushUI() +{ + var bgBrush = { Std = 0, Hover = RGBa(128,128,192,128) }; + var bgQuad = bgBrush; + var bgErase = bgBrush; + + if (SelectedBrushMode == 1) bgBrush = { Std = RGBa(128,192,128,128), Hover = RGBa(128,128,192,128) }; + if (SelectedBrushMode == 2) bgQuad = { Std = RGBa(128,192,128,128), Hover = RGBa(128,128,192,128) }; + if (SelectedBrushMode == 3) bgErase = { Std = RGBa(128,192,128,128), Hover = RGBa(128,128,192,128) }; + + var BrushUI = + { + Decoration = GUI_MenuDeco, + Player = GetOwner(), + + OptionList = + { + Style = GUI_VerticalLayout, + Top = "2em", + + OptMaterial = + { + Index = 50, + Priority = 1, + Style = GUI_FitChildren, + + Caption = + { + Text = "$MBMaterialFg$", + Bottom = "2em", + Right = "10em", + }, + + Selection = + { + ID = idGuiHudMB_MatSelect, + Style = GUI_FitChildren | GUI_GridLayout, + Left = "10em" + } + }, + + Spacer1 = + { + Bottom = "1em", + Priority = 2, + }, + + OptMaterialBg = + { + Index = 51, + Priority = 3, + Bottom = "4em", + Style = GUI_FitChildren, + + Caption = + { + Text = "$MBMaterialBg$", + Bottom = "2em", + Right = "10em", + }, + + Selection = + { + ID = idGuiHudMB_MatBgSelect, + Style = GUI_FitChildren | GUI_GridLayout, + Left = "10em", + } + }, + + Spacer2 = + { + Bottom = "1em", + Priority = 4, + }, + + OptBrushSize = + { + Index = 52, + Priority = 5, + Bottom = "4em", + Style = GUI_FitChildren, + + Caption = + { + Text = "$MBBrushSize$", + Bottom = "2em", + Right = "10em", + }, + + Selection = + { + ID = idGuiHudMB_SizeSelect, + Style = GUI_FitChildren | GUI_GridLayout, + Left = "10em", + + Minus10 = + { + Priority = 1, + + Symbol = Icon_Number, + GraphicsName = "Minus", + Text = "10", + Style = GUI_TextBottom | GUI_TextRight, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + Right = "2em", + Bottom = "2em", + + OnClick = GuiAction_Call(this, "BrushSizeChange", -10), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + Minus1 = + { + Priority = 2, + + Symbol = Icon_Number, + GraphicsName = "Minus", + Text = "1", + Style = GUI_TextBottom | GUI_TextRight, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + Right = "2em", + Bottom = "2em", + + OnClick = GuiAction_Call(this, "BrushSizeChange", -1), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + Value = + { + Priority = 3, + Style = GUI_TextHCenter | GUI_TextVCenter, + Text = Format("%d", SelectedBrushSize), + + Right = "4em", + Bottom = "2em", + }, + + Plus1 = + { + Priority = 4, + + Symbol = Icon_Number, + GraphicsName = "Plus", + Text = "1", + Style = GUI_TextBottom | GUI_TextRight, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + Right = "2em", + Bottom = "2em", + + OnClick = GuiAction_Call(this, "BrushSizeChange", 1), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + Plus10 = + { + Priority = 5, + + Symbol = Icon_Number, + GraphicsName = "Plus", + Text = "10", + Style = GUI_TextBottom | GUI_TextRight, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + Right = "2em", + Bottom = "2em", + + OnClick = GuiAction_Call(this, "BrushSizeChange", 10), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + } + }, + + Spacer3 = + { + Bottom = "1em", + Priority = 6, + }, + + OptBrushMode = + { + Index = 53, + Priority = 7, + Bottom = "4em", + Style = GUI_FitChildren, + + Caption = + { + Text = "$MBBrushMode$", + Bottom = "2em", + Right = "10em", + }, + + Selection = + { + ID = idGuiHudMB_ModeSelect, + Style = GUI_FitChildren | GUI_GridLayout, + Left = "10em", + + ModeBrush = + { + Priority = 1, + BackgroundColor = bgBrush, + Bottom = "2em", + Right = "10em", + + icon = + { + Symbol = SprayCan, + Right = "2em" + }, + + text = + { + Text = "$MBBrushModeBrush$", + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "SelectBrushMode", 1), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + ModeQuad = + { + Priority = 2, + BackgroundColor = bgQuad, + Bottom = "2em", + Right = "10em", + + icon = + { + Symbol = SprayCan, + Right = "2em" + }, + + text = + { + Text = "$MBBrushModeQuad$", + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "SelectBrushMode", 2), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + ModeErase = + { + Priority = 3, + BackgroundColor = bgErase, + Bottom = "2em", + Right = "10em", + + icon = + { + Symbol = SprayCan, + Right = "2em" + }, + + text = + { + Text = "$MBBrushModeErase$", + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "SelectBrushMode", 3), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + } + }, + } + }; + + GuiAddCloseButton(BrushUI, this, "HideMaterialBrushUI"); + + var index = 0; + for (var property in GetProperties(BrushMaterials)) + { + var entry = BrushMaterials[property]; + index++; + + var stdcolor = 0; + if (entry.Material == SelectedBrushMaterial) stdcolor = RGBa(128,192,128,128); + + var matentry = + { + ID = 2000 + index, + Priority = index, + BackgroundColor = { Std = stdcolor, Hover = RGBa(128,128,192,128) }, + Bottom = "2em", + Right = "10em", + + icon = + { + Symbol = entry.Icon, + Right = "2em" + }, + + text = + { + Text = entry.Caption, + Left = "2.5em", + Style = GUI_TextVCenter + }, + + OnClick = GuiAction_Call(this, "SelectBrushMaterial", entry.Material), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }; + + GuiAddSubwindow(matentry, BrushUI.OptionList.OptMaterial.Selection); + } + + index = 0; + for (var property in GetProperties(BrushBackgroundMaterials)) + { + var entry = BrushBackgroundMaterials[property]; + index++; + + var stdcolor = 0; + if (entry.Material == SelectedBrushBgMaterial) stdcolor = RGBa(128,192,128,128); + + var matentry = + { + ID = 3000 + index, + Priority = index, + BackgroundColor = { Std = stdcolor, Hover = RGBa(128,128,192,128) }, + Bottom = "2em", + Right = "10em", + + icon = + { + Symbol = entry.Icon, + Right = "2em" + }, + + text = + { + Text = entry.Caption, + Left = "2.5em", + Style = GUI_TextVCenter + }, + + OnClick = GuiAction_Call(this, "SelectBrushBackgroundMaterial", entry.Material), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }; + + GuiAddSubwindow(matentry, BrushUI.OptionList.OptMaterialBg.Selection); + } + + idHudMB = GuiOpen(BrushUI); + + SetMenu(idHudMB); + + return idHudMB; +} + +func HideMaterialBrushUI() +{ + if (idHudMB) + { + GuiClose(idHudMB); + idHudMB = nil; + MenuClosed(); + } +} + +func SelectBrushMaterial(data) +{ + SelectedBrushMaterial = data; + + var update = + { + OptionList = + { + OptMaterial = + { + Selection = + { + ID = idGuiHudMB_MatSelect, + Style = GUI_FitChildren | GUI_GridLayout, + Left = "10em" + } + } + } + }; + + var index = 0; + for (var property in GetProperties(BrushMaterials)) + { + var entry = BrushMaterials[property]; + index++; + + var stdcolor = 0; + if (entry.Material == SelectedBrushMaterial) stdcolor = RGBa(128,192,128,128); + + var matentry = + { + ID = 2000 + index, + Priority = index, + BackgroundColor = { Std = stdcolor, Hover = RGBa(128,128,192,128) }, + Bottom = "2em", + Right = "10em", + + icon = + { + Symbol = entry.Icon, + Right = "2em" + }, + + text = + { + Text = entry.Caption, + Left = "2.5em", + Style = GUI_TextVCenter + }, + + OnClick = GuiAction_Call(this, "SelectBrushMaterial", entry.Material), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }; + + GuiAddSubwindow(matentry, update.OptionList.OptMaterial.Selection); + } + + GuiClose(idHudMB, idGuiHudMB_MatSelect); + GuiUpdate(update, idHudMB); +} + +func SelectBrushBackgroundMaterial(data) +{ + SelectedBrushBgMaterial = data; + + var update = + { + OptionList = + { + OptMaterialBg = + { + Selection = + { + ID = idGuiHudMB_MatBgSelect, + Style = GUI_FitChildren | GUI_GridLayout, + Left = "10em" + } + } + } + }; + + var index = 0; + for (var property in GetProperties(BrushBackgroundMaterials)) + { + var entry = BrushBackgroundMaterials[property]; + index++; + + var stdcolor = 0; + if (entry.Material == SelectedBrushBgMaterial) stdcolor = RGBa(128,192,128,128); + + var matentry = + { + ID = 2000 + index, + Priority = index, + BackgroundColor = { Std = stdcolor, Hover = RGBa(128,128,192,128) }, + Bottom = "2em", + Right = "10em", + + icon = + { + Symbol = entry.Icon, + Right = "2em" + }, + + text = + { + Text = entry.Caption, + Left = "2.5em", + Style = GUI_TextVCenter + }, + + OnClick = GuiAction_Call(this, "SelectBrushBackgroundMaterial", entry.Material), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }; + + GuiAddSubwindow(matentry, update.OptionList.OptMaterialBg.Selection); + } + + GuiClose(idHudMB, idGuiHudMB_MatBgSelect); + GuiUpdate(update, idHudMB); +} + +func BrushSizeChange(valuechange) +{ + SelectedBrushSize += valuechange; + if (SelectedBrushSize < 1) SelectedBrushSize = 1; + + var update = + { + OptionList = + { + OptBrushSize = + { + Selection = + { + Value = + { + Text = Format("%d", SelectedBrushSize) + } + } + } + } + }; + + GuiUpdate(update, idHudMB); +} + +func SelectBrushMode(data) +{ + SelectedBrushMode = data; + + var bgBrush = { Std = 0, Hover = RGBa(128,128,192,128) }; + var bgQuad = bgBrush; + var bgErase = bgBrush; + + if (SelectedBrushMode == 1) bgBrush = { Std = RGBa(128,192,128,128), Hover = RGBa(128,128,192,128) }; + if (SelectedBrushMode == 2) bgQuad = { Std = RGBa(128,192,128,128), Hover = RGBa(128,128,192,128) }; + if (SelectedBrushMode == 3) bgErase = { Std = RGBa(128,192,128,128), Hover = RGBa(128,128,192,128) }; + + var update = + { + OptionList = + { + OptBrushMode = + { + Selection = + { + ModeBrush = + { + BackgroundColor = bgBrush + }, + + ModeQuad = + { + BackgroundColor = bgQuad + }, + + ModeErase = + { + BackgroundColor = bgErase + } + } + } + } + }; + + GuiUpdate(update, idHudMB); +} + + +local idHudTW; + +func ShowTweaksUI() +{ + var TweaksUI = + { + Player = GetOwner(), + Decoration = GUI_MenuDeco, + + OptionList = + { + Top = "2em", + Style = GUI_VerticalLayout, + + OptInvincible = + { + ID = 50, + Priority = 1, + Bottom = "2em", + Style = GUI_FitChildren, + + Caption = + { + Right = "12em", + Text = "$TweakInvincible$", + }, + + Selection = + { + Style = GUI_GridLayout | GUI_FitChildren, + Left = "12em", + + BtnEnable = + { + Priority = 1, + Bottom = "2em", + Right = "10em", + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + icon = + { + Symbol = Icon_Ok, + Right = "2em", + }, + + text = + { + Text = "$OptActivate$", + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "SetInvincibility", true), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + BtnDisable = + { + Priority = 2, + Bottom = "2em", + Right = "10em", + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + icon = + { + Symbol = Icon_Cancel, + Right = "2em", + }, + + text = + { + Text = "$OptDeactivate$", + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "SetInvincibility", false), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + } + }, + + OptSkinChoose = + { + ID = 51, + Priority = 2, + Bottom = "2em", + Style = GUI_FitChildren, + + Caption = + { + Right = "12em", + Text = "$TweakSkinChoose$", + }, + + Selection = + { + Style = GUI_GridLayout | GUI_FitChildren, + Left = "12em", + + BtnSkin1 = + { + Priority = 1, + Bottom = "2em", + Right = "10em", + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + icon = + { + Symbol = Clonk, + Right = "2em", + }, + + text = + { + Text = "$OptSkin1$", + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "SetSkin", 0), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + BtnSkin2 = + { + Priority = 2, + Bottom = "2em", + Right = "10em", + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + icon = + { + Symbol = Clonk, + GraphicsName = "Steampunk", + Right = "2em", + }, + + text = + { + Text = "$OptSkin2$", + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "SetSkin", 1), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + BtnSkin3 = + { + Priority = 3, + Bottom = "2em", + Right = "10em", + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + icon = + { + Symbol = Clonk, + GraphicsName = "Alchemist", + Right = "2em", + }, + + text = + { + Text = "$OptSkin3$", + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "SetSkin", 2), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + BtnSkin4 = + { + Priority = 4, + Bottom = "2em", + Right = "10em", + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + icon = + { + Symbol = Clonk, + GraphicsName = "Farmer", + Right = "2em", + }, + + text = + { + Text = "$OptSkin4$", + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "SetSkin", 3), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + + } + } + } + + }; + + GuiAddCloseButton(TweaksUI, this, "HideTweaksUI"); + + idHudTW = GuiOpen(TweaksUI); + + SetMenu(idHudTW); + + return idHudTW; +} + +func HideTweaksUI() +{ + if (idHudTW) + { + GuiClose(idHudTW); + MenuClosed(); + idHudTW = nil; + } +} + + +local idHudMG; +static MapGenSizeWidth; +static MapGenSizeHeight; + +static MapGenPreset; +static MapGenTreesAmount; + +local idGuiHudMG_SizeSelectWidth = 400; +local idGuiHudMG_SizeSelectHeight = 401; +local idGuiHudMG_TypePresetList = 402; + +local MapGenTypePresetOpts = +{ + // Custom = + // { + // Priority = 1, + // Caption = "$MapGenTPCustom$", + // Icon = Hammer, + // Value = "Custom" + // }, + + FlatLand = + { + Priority = 2, + Caption = "$MapGenTPFlatLand$", + Icon = Earth, + Value = "FlatLand" + }, + + Skylands = + { + Priority = 3, + Caption = "$MapGenTPSkylands$", + Icon = Earth, + Value = "Skylands" + }, + + Caves = + { + Priority = 4, + Caption = "$MapGenTPCaves$", + Icon = Earth, + Value = "Caves" + } +}; + +func ShowMapGenUI() +{ + var MapGenUI = + { + Player = GetOwner(), + Decoration = GUI_MenuDeco, + + OptionList = + { + Top = "2em", + Bottom = "100% - 2em", + Style = GUI_VerticalLayout, + + OptMapSizeWidth = + { + Priority = 1, + Style = GUI_FitChildren, + Bottom = "2em", + + Caption = + { + Text = "$MapGenSizeWidth$", + Right = "12em", + }, + + Selection = + { + ID = idGuiHudMG_SizeSelectWidth, + Style = GUI_GridLayout | GUI_FitChildren, + Left = "12em", + + Minus10 = + { + Priority = 1, + + Symbol = Icon_Number, + GraphicsName = "Minus", + Text = "10", + Style = GUI_TextBottom | GUI_TextRight, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + Right = "2em", + Bottom = "2em", + + OnClick = GuiAction_Call(this, "MapGenSizeWidthChange", -10), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + Minus1 = + { + Priority = 2, + + Symbol = Icon_Number, + GraphicsName = "Minus", + Text = "1", + Style = GUI_TextBottom | GUI_TextRight, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + Right = "2em", + Bottom = "2em", + + OnClick = GuiAction_Call(this, "MapGenSizeWidthChange", -1), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + Value = + { + Priority = 3, + Style = GUI_TextHCenter | GUI_TextVCenter, + Text = Format("%d", MapGenSizeWidth), + + Right = "4em", + Bottom = "2em", + }, + + Plus1 = + { + Priority = 4, + + Symbol = Icon_Number, + GraphicsName = "Plus", + Text = "1", + Style = GUI_TextBottom | GUI_TextRight, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + Right = "2em", + Bottom = "2em", + + OnClick = GuiAction_Call(this, "MapGenSizeWidthChange", 1), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + Plus10 = + { + Priority = 5, + + Symbol = Icon_Number, + GraphicsName = "Plus", + Text = "10", + Style = GUI_TextBottom | GUI_TextRight, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + Right = "2em", + Bottom = "2em", + + OnClick = GuiAction_Call(this, "MapGenSizeWidthChange", 10), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + } + }, + + OptMapSizeHeight = + { + Priority = 2, + Style = GUI_FitChildren, + Bottom = "2em", + + Caption = + { + Text = "$MapGenSizeHeight$", + Right = "12em", + }, + + Selection = + { + ID = idGuiHudMG_SizeSelectWidth, + Style = GUI_GridLayout | GUI_FitChildren, + Left = "12em", + + Minus10 = + { + Priority = 1, + + Symbol = Icon_Number, + GraphicsName = "Minus", + Text = "10", + Style = GUI_TextBottom | GUI_TextRight, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + Right = "2em", + Bottom = "2em", + + OnClick = GuiAction_Call(this, "MapGenSizeHeightChange", -10), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + Minus1 = + { + Priority = 2, + + Symbol = Icon_Number, + GraphicsName = "Minus", + Text = "1", + Style = GUI_TextBottom | GUI_TextRight, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + Right = "2em", + Bottom = "2em", + + OnClick = GuiAction_Call(this, "MapGenSizeHeightChange", -1), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + Value = + { + Priority = 3, + Style = GUI_TextHCenter | GUI_TextVCenter, + Text = Format("%d", MapGenSizeHeight), + + Right = "4em", + Bottom = "2em", + }, + + Plus1 = + { + Priority = 4, + + Symbol = Icon_Number, + GraphicsName = "Plus", + Text = "1", + Style = GUI_TextBottom | GUI_TextRight, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + Right = "2em", + Bottom = "2em", + + OnClick = GuiAction_Call(this, "MapGenSizeHeightChange", 1), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + Plus10 = + { + Priority = 5, + + Symbol = Icon_Number, + GraphicsName = "Plus", + Text = "10", + Style = GUI_TextBottom | GUI_TextRight, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + Right = "2em", + Bottom = "2em", + + OnClick = GuiAction_Call(this, "MapGenSizeHeightChange", 10), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + } + }, + + OptPreset = + { + Priority = 3, + Bottom = "2em", + Style = GUI_FitChildren, + + Caption = + { + Text = "$MapGenMapType$", + Right = "12em", + }, + + Selection = + { + ID = idGuiHudMG_TypePresetList, + } + } + }, + + BtnGenerate = + { + Top = "100% - 2em", + Text = "$MapGenButtonGenerate$", + Style = GUI_TextHCenter | GUI_TextVCenter, + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + OnClick = GuiAction_Call(this, "MakeNewMap"), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + } + }; + + GuiAddCloseButton(MapGenUI, this, "HideMapGenUI"); + + idHudMG = GuiOpen(MapGenUI); + + SetMenu(idHudMG); + + UpdateMapGenPresetOptionList(); + + return idHudMG; +} + +func HideMapGenUI() +{ + if (idHudMG) + { + GuiClose(idHudMG); + MenuClosed(); + idHudMG = nil; + } +} + +func UpdateMapGenPresetOptionList() +{ + GuiClose(idHudMG, idGuiHudMG_TypePresetList); + + var update = + { + OptionList = + { + OptPreset = + { + Selection = + { + ID = idGuiHudMG_TypePresetList, + Left = "12em", + Style = GUI_GridLayout | GUI_FitChildren, + } + } + } + }; + + GuiUpdate(update, idHudMG); + + for (var property in GetProperties(MapGenTypePresetOpts)) + { + var entry = MapGenTypePresetOpts[property]; + + var bgcolor = { Std = 0, Hover = RGBa(128,128,192,128) }; + if (MapGenPreset == entry.Value) bgcolor = { Std = RGBa(128,192,128,128), Hover = RGBa(128,128,192,128) }; + + var subentry = + { + Right = "10em", + Bottom = "2em", + Priority = entry.Priority, + BackgroundColor = bgcolor, + + icon = + { + Symbol = entry.Icon, + Right = "2em", + }, + + text = + { + Text = entry.Caption, + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "MapGenSelectPreset", entry.Value), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }; + + GuiAddSubwindow(subentry, update.OptionList.OptPreset.Selection); + } + + GuiUpdate(update, idHudMG); + + +} + +func MapGenSelectPreset(data) +{ + MapGenPreset = data; + UpdateMapGenPresetOptionList(); +} + +func MapGenSizeWidthChange(valuechange) +{ + MapGenSizeWidth += valuechange; + if (MapGenSizeWidth < 1) MapGenSizeWidth = 1; + if (MapGenSizeWidth > 1000) MapGenSizeWidth = 1000; + + var update = + { + OptionList = + { + OptMapSizeWidth = + { + Selection = + { + Value = + { + Text = Format("%d", MapGenSizeWidth) + } + } + } + } + }; + + GuiUpdate(update, idHudMG); +} + +func MapGenSizeHeightChange(valuechange) +{ + MapGenSizeHeight += valuechange; + if (MapGenSizeHeight < 1) MapGenSizeHeight = 1; + if (MapGenSizeHeight > 1000) MapGenSizeHeight = 1000; + + var update = + { + OptionList = + { + OptMapSizeHeight = + { + Selection = + { + Value = + { + Text = Format("%d", MapGenSizeHeight) + } + } + } + } + }; + + GuiUpdate(update, idHudMG); +} + +func MakeNewMap() +{ + var clonks = []; + for (var clonk in FindObjects(Find_OCF(OCF_CrewMember))) + { + var container = clonk->Contained(); + if (container) + { + clonk->Exit(); + container->RemoveObject(); + } + else + { + // Players not waiting for a relaunch get a new Clonk to prevent + // status effects from carrying over to the next round. + var new_clonk = CreateObject(clonk->GetID(), 0, 0, clonk->GetOwner()); + new_clonk->GrabObjectInfo(clonk); + clonk = new_clonk; + } + PushBack(clonks, clonk); + clonk->SetObjectStatus(C4OS_INACTIVE); + } + + LoadScenarioSection("main"); + + for (var clonk in clonks) + { + clonk->SetObjectStatus(C4OS_NORMAL); + SetCursor(clonk->GetOwner(), clonk); + clonk->SetPosition(LandscapeWidth() / 2, LandscapeHeight() / 2); + clonk->Unstick(20); + } + + for(var i = 0; i < GetPlayerCount(); i++) + { + GameCall("InitializePlayer", GetPlayerByIndex(i)); + } + + // Things to do after the Clonks have respawned on new map + PostMapGen(); + +} + + +local idHudMK; +local idGuiHudMK_MarkerList = 610; + +func ShowMarkerUI() +{ + var MarkerUI = + { + Player = GetOwner(), + Decoration = GUI_MenuDeco, + + OptionList = + { + ID = idGuiHudMK_MarkerList, + Top = "2em", + Bottom = "100% - 2em", + Style = GUI_VerticalLayout, + + }, + + BtnPlaceMarker = + { + Top = "100% - 2em", + Text = "$PlaceMarker$", + Style = GUI_TextHCenter | GUI_TextVCenter, + + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + OnClick = GuiAction_Call(this, "PlaceNewMarker"), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + } + }; + + GuiAddCloseButton(MarkerUI, this, "HideMarkerUI"); + + idHudMK = GuiOpen(MarkerUI); + + SetMenu(idHudMK); + + UpdateMarkerList(); + + return idHudMK; +} + +func HideMarkerUI() +{ + if (idHudMK) + { + GuiClose(idHudMK); + MenuClosed(); + idHudMK = nil; + } +} + +func UpdateMarkerList() +{ + if (!idHudMK) return; + + GuiClose(idHudMK, idGuiHudMK_MarkerList); + + var update = + { + ID = idGuiHudMK_MarkerList, + Top = "2em", + Bottom = "100% - 2em", + Style = GUI_VerticalLayout, + }; + GuiUpdate({ OptionList = update }, idHudMK); + + for (var i = 0; i <= 9; i++) + { + var marker = GetMarkerForIndex(i, GetOwner()); + var submarker; + + if (marker) + { + submarker = + { + Priority = i + 1, + Style = GUI_FitChildren, + Bottom = "2em", + + Caption = + { + Right = "4em", + Symbol = Icon_Number, + GraphicsName = Format("%d", i), + }, + + Selection = + { + Bottom = "2em", + Left = "4em", + Style = GUI_GridLayout, + + BtnTeleport = + { + Priority = 1, + Right = "10em", + Bottom = "2em", + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + icon = + { + Symbol = Teleporter, + Right = "2em", + }, + + text = + { + Text = "$GoToMarker$", + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "GoToMarker", marker), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + BtnRemove = + { + Priority = 2, + Right = "10em", + Bottom = "2em", + BackgroundColor = { Std = 0, Hover = RGBa(128,128,192,128) }, + + icon = + { + Symbol = Icon_Cancel, + Right = "2em", + }, + + text = + { + Text = "$RemoveMarker$", + Left = "2.5em", + Style = GUI_TextVCenter, + }, + + OnClick = GuiAction_Call(this, "RemoveMarker", marker), + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + }, + + + } + }; + } + else + { + submarker = + { + Priority = i + 1, + Style = GUI_FitChildren, + Bottom = "2em", + BackgroundColor = RGBa(192,0,0,128), + + Caption = + { + Right = "4em", + Symbol = Icon_Number, + GraphicsName = Format("%d", i), + }, + + Selection = + { + Bottom = "2em", + Text = "$MarkerNotSet$", + Style = GUI_TextHCenter | GUI_TextVCenter, + } + }; + } + + GuiAddSubwindow(submarker, update); + } + GuiUpdate(update, idHudMK, idGuiHudMK_MarkerList); +} + +func PlaceNewMarker() +{ + var newindex = GetNextFreeMarkerIndex(GetOwner()); + + if (newindex != nil) + { + var marker = this->CreateObject(Marker); + + marker->SetIcon(newindex); + + UpdateMarkerList(); + + return marker; + } + else + { + Sound("UI::Error"); + UpdateMarkerList(); + return nil; + } +} + +func RemoveMarker(marker) +{ + marker->RemoveObject(); + UpdateMarkerList(); +} + +func GoToMarker(marker) +{ + this->SetPosition(marker->GetX(), marker->GetY()); + this->Sound("warp"); + this->Fireworks(); +} \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/System.ocg/StringTblDE.txt b/planet/Tutorials.ocf/Sandbox.ocs/System.ocg/StringTblDE.txt new file mode 100644 index 000000000..cdbff25a2 --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/System.ocg/StringTblDE.txt @@ -0,0 +1,91 @@ +TooltipObjectspawn=Objekte erzeugen +TooltipLandscapeBrush=Landschaft zeichnen +TooltipMarker=Marker +TooltipMapGen=Kartengenerator +TooltipTweaks=Cheats und anderes tolles Zeugs +GodsHandDisplayTT=Dieses Objekt wird mit der Hand Gottes platziert (zum Ändern \"Objekte erzeugen\" aufrufen und \"Hand Gottes\" als Ziel auswählen) + +OSCatProductionResources=Rohstoffe +OSCatFoodstuff=Nahrungsmittel +OSCatLiquids=Flüssigkeiten +OSCatTools=Werkzeuge +OSCatWeapons=Waffen +OSCatExplosives=Sprengstoff +OSCatVehicles=Fahrzeuge +OSCatAnimals=Tiere +OSCatPlants=Pflanzen +OSCatGodTools=Götterspielzeug + +OSHintTarget=Tipp! Du kannst hiermit einstellen, wo du Objekte erzeugen möchtest. Stelle dies auf \"Hand Gottes\" um auszuwählen, welches Objekt du mit der Hand Gottes erzeugen möchtest. + +OSTargetClonk=Ziel: Clonk/Inventar +OSTargetGodsHand=Ziel: Hand Gottes +OSTargetClonkTT=Das Objekt wird (wenn möglich) im Inventar des Clonks erzeugt +OSTargetGodsHandTT=Das Objekt kann mit der Hand Gottes erzeugt werden + +MatEarth=Erde +MatEarthSpongy=Erde (Schwammig) +MatEarthRoot=Erde (Rau) +MatSand=Sand +MatSandDry=Trockener Sand +MatIce=Eis +MatIce2=Eis (Anders) +MatSnow=Schnee +MatRock=Stein +MatRockSmooth=Stein (Weich) +MatGranite=Granit +MatOre=Erz +MatGold=Gold +MatCoal=Kohle +MatFirestone=Feuerstein +MatRuby=Rubin +MatAmethyst=Amethyst +MatAshes=Asche +MatBrick=Steinmauer +MatBrickSoft=Steinmauer (Schwach) +MatEverrock=Everrock +MatWater=Wasser +MatAcid=Säure +MatLava=Lava +MatDuroLava=Magma +MatOil=Öl +MatTunnel=Tunnel (Hintergrund) +MatTunnelBrick=Steinmauer (Hintergrund) + +MatBgSky=Himmel +MatBgTunnel=Tunnel +MatBgBricks=Steinmauer + +MBMaterialFg=Material +MBMaterialBg=Hintergrundmaterial +MBBrushSize=Pinselgröße +MBBrushMode=Pinselmodus + +MBBrushModeBrush=Pinsel +MBBrushModeQuad=Quadrat +MBBrushModeErase=Radierer + +MarkerNotSet=Marker nicht gesetzt +PlaceMarker=Marker setzen +RemoveMarker=Marker entfernen +GoToMarker=Teleport + +MapGenButtonGenerate=Karte generieren! +MapGenSizeWidth=Kartenbreite +MapGenSizeHeight=Kartenhöhe +MapGenMapType=Kartentyp + +MapGenTPCustom=Anpassen +MapGenTPFlatLand=Flachland +MapGenTPSkylands=Himmelsinseln +MapGenTPCaves=Höhlen + +TweakInvincible=Unverwundbarkeit (Gott-Modus) +OptActivate=Aktivieren +OptDeactivate=Deaktivieren + +TweakSkinChoose=Skin wechseln +OptSkin1=Abenteurer +OptSkin2=Steampunk +OptSkin3=Alchemist +OptSkin4=Farmer diff --git a/planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/DefCore.txt b/planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/DefCore.txt new file mode 100644 index 000000000..deb115746 --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=Teleporter +Version=5,2,0,1 +Category=C4D_Object +Width=64 +Height=64 +Offset=-32,-32 \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/Graphics.png b/planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/Graphics.png new file mode 100644 index 0000000000000000000000000000000000000000..ee0ca53a9e3708923b3bb1418a234cbe2f4622df GIT binary patch literal 9777 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 + x; + gy = clonk->GetY() + y; + + if (gx < 0 || gx >= LandscapeWidth() || gy < 0 || gy >= LandscapeHeight()) + { + clonk->Sound("UI::Error"); + return; + } + + clonk->SetPosition(gx, gy); + clonk->Fireworks(); + clonk->Sound("warp"); +} \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/StringTblDE.txt b/planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/StringTblDE.txt new file mode 100644 index 000000000..33143d83b --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Teleporter +Description=Fliegen war gestern. Teleportieren ist viel coolerer als wie alles andere. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/StringTblUS.txt b/planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/StringTblUS.txt new file mode 100644 index 000000000..53c82a2f2 --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/Teleporter.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Teleporter +Description=Flying is lame. Teleporting is what the trendy kids do today. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Sandbox.ocs/Title.txt b/planet/Tutorials.ocf/Sandbox.ocs/Title.txt new file mode 100644 index 000000000..d59465d5b --- /dev/null +++ b/planet/Tutorials.ocf/Sandbox.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Sandkasten +US:Sandbox \ No newline at end of file From dcc240e01a682cca77d334bd25ae37ba5eee4fa4 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 13:59:10 +0200 Subject: [PATCH 13/93] Rule_Relaunch: Modify base respawn and add Rule_Restart functionality --- .../Rules.ocd/Relaunch.ocd/Script.c | 542 +++++++++--------- 1 file changed, 274 insertions(+), 268 deletions(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index 2f6972a37..c96b4094d 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -1,47 +1,19 @@ /** - Relaunch Rule - This rule enables and handles relaunches. - @author Maikel, Sven2, Fulgen + Relaunch Rule + This rule enables and handles relaunches. + @author Maikel, Sven2, Fulgen */ -protected func Initialize() -{ - ScheduleCall(this, this.CheckDescription, 1, 1); - return true; -} - -private func CheckDescription() -{ - // If neutral flagpoles exist, update name and description. - if(respawn_at_base) - { - if(ObjectCount(Find_ID(Flagpole), Find_Func("IsNeutral"))) - { - SetName("$Name2$"); - this.Description = "$Description2$"; - } - else - { - SetName("$Name3$"); - this.Description = "$Description3$"; - } - } - else - { - SetName("$Name$"); - this.Description = "$Description$"; - } - return true; -} - // Determines whether the inventory of the crew member is transfered upon respawn. local inventory_transfer = false; // Determines whether a crew member needs to be bought. -local free_crew = false; +local free_crew = true; //Determines whether the clonk will be respawned at the base local respawn_at_base = false; +//Determines whether only the last clonk gets respawned +local RespawnLastClonk = false; local DefaultRelaunchCount = 5; local aRelaunches = []; @@ -52,355 +24,389 @@ local DisableLastWeapon = false; local LastUsedPlayerWeapons = []; local RelaunchTime = 36 * 10; local Hold = false; +local RestartPlayer = false; + +public func Activate(int plr) +{ + if(!RestartPlayer) return MessageWindow(this.Description, plr); + // Notify scenario. + if (!GameCall("OnPlayerRestart", plr)) + return; + // Remove the player's clonk, including contents. + var clonk = GetCrew(plr); + if (clonk && clonk->GetCrewEnabled()) + { + clonk->Kill(clonk, true); + clonk->RemoveObject(); + } +} + +protected func Initialize() +{ + ScheduleCall(this, this.CheckDescription, 1, 1); + return true; +} + +private func CheckDescription() +{ + // If neutral flagpoles exist, update name and description. + if(respawn_at_base) + { + if(ObjectCount(Find_ID(Flagpole), Find_Func("IsNeutral"))) + { + SetName("$Name2$"); + this.Description = "$Description2$"; + } + else + { + SetName("$Name3$"); + this.Description = "$Description3$"; + } + } + else + { + SetName("$Name$"); + this.Description = "$Description$"; + } + return true; +} public func SetInventoryTransfer(bool transfer) { - inventory_transfer = transfer; - return true; + inventory_transfer = transfer; + return true; } public func GetInventoryTransfer() { - return inventory_transfer; + return inventory_transfer; } public func SetFreeCrew(bool free) { - free_crew = free; - return true; + free_crew = free; + return true; } public func GetFreeCrew() { - return free_crew; + return free_crew; } public func SetRespawnDelay(int iDelay) { - RelaunchTime = iDelay; - return this; + RelaunchTime = iDelay * 36; + return this; } public func GetRespawnDelay() { - return RelaunchTime; + return RelaunchTime / 36; } public func SetHolding(bool fHold) { - Hold = fHold; - return this; + Hold = fHold; + return this; } public func GetHolding() { - return Hold; + return Hold; } public func SetLastWeaponUse(bool fUse) { - this.DisableLastWeapon = !fUse; - return this; + this.DisableLastWeapon = !fUse; + return this; } public func GetLastWeaponUse() { - return DisableLastWeapon; + return DisableLastWeapon; } public func SetBaseRespawn(bool fSet) { - respawn_at_base = fSet; - return this; + respawn_at_base = fSet; + return this; } public func GetBaseRespawn() { - return respawn_at_base; + return respawn_at_base; } public func SetDefaultRelaunches(int iRelaunches) { - DefaultRelaunchCount = iRelaunches; + DefaultRelaunchCount = iRelaunches; +} + +public func SetLastClonkRespawn(bool b) +{ + RespawnLastClonk = b; + return this; +} + +public func EnablePlayerRestart() +{ + RestartPlayer = true; + return this; +} + +public func DisablePlayerRestart() +{ + RestartPlayer = false; + return this; +} + +public func GetLastClonkRespawn() +{ + return RespawnLastClonk; } public func InitializePlayer(int iPlr) { - _inherited(iPlr, ...); - // Scenario script callback. - aRelaunches[iPlr] = DefaultRelaunchCount; - GameCallEx("OnPlayerRelaunch", iPlr, false); - return DoRelaunch(iPlr, nil, nil, true); + _inherited(iPlr, ...); + // Scenario script callback. + aRelaunches[iPlr] = DefaultRelaunchCount; + GameCallEx("OnPlayerRelaunch", iPlr, false); + return DoRelaunch(iPlr, nil, nil, true); } /*public func OnClonkDeath(int plr, object pClonk, int iKiller) { - return RelaunchPlayer(plr, iKiller, pClonk); + return RelaunchPlayer(plr, iKiller, pClonk); }*/ public func RelaunchPlayer(int plr, int killer, object pClonk) { - if(plr == nil || plr == NO_OWNER) return Log("NO PlAYER: %d", plr); - - if(DefaultRelaunchCount != nil) - { - aRelaunches[plr]--; - if(aRelaunches[plr] < 0) - { - EliminatePlayer(plr); - return; - } - } - - GameCall("OnPlayerRelaunch", plr, true); - - return DoRelaunch(plr, pClonk, nil); + if(plr == nil || plr == NO_OWNER) return Log("NO PlAYER: %d", plr); + + if(DefaultRelaunchCount != nil) + { + aRelaunches[plr]--; + if(aRelaunches[plr] < 0) + { + EliminatePlayer(plr); + return; + } + } + + GameCall("OnPlayerRelaunch", plr, true); + + return DoRelaunch(plr, pClonk, nil); } -public func RespawnAtBase(int plr, object clonk, bool fNoCreation) +private func RespawnAtBase(int iPlr, object pClonk) { - // Skip eliminated players, NO_OWNER, etc. - if (!GetPlayerName(plr)) - return; - - // Only respawn a clonk if it is the last crew member. - if (GetCrewCount(plr) >= 1) - return; - - // Get the bases at which the clonk can possibly respawn. - var bases = GetBases(clonk), crew; - for (var base in bases) - { - if (!base) - continue; - - if(fNoCreation) - { - crew = clonk ?? GetCrew(plr); - if(crew) - { - crew->SetPosition(base->GetX(), base->GetY() + base->GetDefHeight() / 2); - break; - } - - } - - // If free crew just create a clonk at the base. - if (free_crew) - { - crew = CreateObjectAbove(ClonkType, base->GetX() - GetX(), base->GetY() + base->GetDefHeight() / 2 - GetY(), plr); - crew->MakeCrewMember(plr); - SetCursor(plr, crew); - // Transfer inventory if turned on. - if (inventory_transfer) TransferInventory(clonk, crew); - break; - } - // Try to buy a crew member at the base. - var pay_plr = base->GetOwner(); - // Payment in neutral bases by clonk owner. - if (pay_plr == NO_OWNER) - pay_plr = plr; - crew = base->~DoBuy(ClonkType, plr, pay_plr, clonk); - if (crew) - { - crew->Exit(0, base->GetDefHeight() / 2); - SetCursor(plr, crew); - // Transfer inventory if turned on. - if (inventory_transfer) TransferInventory(clonk, crew); - break; - } - } - // Respawn delay (+Weapon choice if desired by scenario) - if (crew && RelaunchTime) - { - crew->SetCrewEnabled(false); // will be re-set by relauncher - - crew->CreateObject(RelaunchContainer,nil,nil,plr)->StartRelaunch(clonk); - // But keep view on old corpse because the death might be exciting! - // And sometimes you want to know why you died (just like in real-life!) - if(clonk) - { - var light = clonk->CreateLight(0, 0, 100, Fx_Light.LGT_Temp, plr, 20, RelaunchTime*36); - SetCursor(plr, nil); - SetPlrView(plr, light); - } - } - return true; + for(var base in GetBases(pClonk)) + { + if(base) return [base->GetX(), base->GetY() + base->GetDefHeight() / 2]; + } } private func TransferInventory(object from, object to) { - // Drop some items that cannot be transferred (such as connected pipes and dynamite igniters) - var i = from->ContentsCount(), contents; - while (i--) - if (contents = from->Contents(i)) - if (contents->~IsDroppedOnDeath(from)) - { - contents->Exit(); - } - else - { - // The new clonk doesn't burn. To be consistent, also extinguish contents - contents->Extinguish(); - } - return to->GrabContents(from); + if(!from || !to) return; + // Drop some items that cannot be transferred (such as connected pipes and dynamite igniters) + var i = from->ContentsCount(), contents; + while (i--) + if (contents = from->Contents(i)) + if (contents->~IsDroppedOnDeath(from)) + { + contents->Exit(); + } + else + { + // The new clonk doesn't burn. To be consistent, also extinguish contents + contents->Extinguish(); + } + return to->GrabContents(from); } private func GetBases(object clonk) { - var plr = clonk->GetOwner(); - // Neutral flagpoles are preferred respawn points, because they are used as the only respawn points in missions. - var bases = clonk->FindObjects(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance()); - // If there are no neutral flagpoles, find closest base owned by the player (or team) and try to buy a clonk. - if (GetLength(bases) <= 0) - bases = clonk->FindObjects(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance()); - return bases; + var plr = clonk->GetOwner(); + // Neutral flagpoles are preferred respawn points, because they are used as the only respawn points in missions. + var bases = clonk->FindObjects(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance()); + // If there are no neutral flagpoles, find closest base owned by the player (or team) and try to buy a clonk. + if (GetLength(bases) <= 0) + bases = clonk->FindObjects(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance()); + return bases; } public func DoRelaunch(int iPlr, object pClonk, array position, bool fNoCreation) { - if(respawn_at_base) return RespawnAtBase(iPlr, pClonk, fNoCreation); - if(!GetPlayerName(iPlr)) return Log("NO NAME"); - position = (position ?? GameCall("RelaunchPosition", iPlr, GetPlayerTeam(iPlr))) ?? FindRelaunchPos(iPlr); - - var spawn; - - if(GetType(position) == C4V_Array) - { - if(GetType(position[0]) == C4V_Array) - { - spawn = position[Random(GetLength(position))]; - } - else spawn = position; - } - var clonk; - if(!fNoCreation) - { - var clonk = CreateObjectAbove(ClonkType, spawn[0], spawn[1], iPlr); - if(!clonk) return Log("NO CLONK"); - clonk->MakeCrewMember(iPlr); - } - else - { - clonk = GetCrew(iPlr); - if(!clonk) return Log("NO CREW"); - } - - if(!GetCursor(iPlr) || GetCursor(iPlr) == pClonk) SetCursor(iPlr, clonk); - clonk->DoEnergy(100000); - - if(RelaunchTime) - { - clonk->CreateObject(RelaunchContainer,nil,nil,iPlr)->StartRelaunch(clonk); - } - return true; + if(!GetPlayerName(iPlr)) return; + if(RespawnLastClonk && GetCrewCount(iPlr) >= 1) return; + + if(respawn_at_base) position = RespawnAtBase(iPlr, pClonk); + position = (position ?? GameCallEx("RelaunchPosition", iPlr, GetPlayerTeam(iPlr))) ?? FindRelaunchPos(iPlr); + + var spawn; + + + // position array either has the form [x, y] or [[x, y], [x, y], ...] + if(GetType(position) == C4V_Array) + { + if(GetType(position[0]) == C4V_Array) + { + spawn = position[Random(GetLength(position))]; + } + else spawn = position; + } + + var clonk; + if(!fNoCreation) + { + if(free_crew) + { + clonk = CreateObjectAbove(ClonkType, spawn[0], spawn[1],iPlr); + if(!clonk) return; + clonk->MakeCrewMember(iPlr); + } + else + { + // Try to buy a crew member at the base. + var pay_plr = base->GetOwner(); + // Payment in neutral bases by clonk owner. + if (pay_plr == NO_OWNER) + pay_plr = plr; + clonk = base->~DoBuy(ClonkType, plr, pay_plr, pClonk); + if (clonk) + { + clonk->Exit(); + } + } + } + else + { + clonk = GetCrew(iPlr); + if(!clonk) return; + } + + if (inventory_transfer) TransferInventory(pClonk, clonk); + + clonk->SetPosition(spawn[0], spawn[1], iPlr) + + if(!GetCursor(iPlr) || GetCursor(iPlr) == pClonk) SetCursor(iPlr, clonk); + clonk->DoEnergy(clonk.Energy || 100000); + + if(RelaunchTime) + { + clonk->CreateObject(RelaunchContainer,nil,nil,iPlr)->StartRelaunch(clonk); + } + return true; } protected func FindRelaunchPos(int plr) { - var tx, ty; // Test position. - for (var i = 0; i < 500; i++) - { - tx = Random(LandscapeWidth()); - ty = Random(LandscapeHeight()); - if (GBackSemiSolid(AbsX(tx), AbsY(ty))) - continue; - if (GBackSemiSolid(AbsX(tx+5), AbsY(ty+10))) - continue; - if (GBackSemiSolid(AbsX(tx+5), AbsY(ty-10))) - continue; - if (GBackSemiSolid(AbsX(tx-5), AbsY(ty+10))) - continue; - if (GBackSemiSolid(AbsX(tx-5), AbsY(ty-10))) - continue; - // Succes. - return [tx, ty]; - } - return nil; + var tx, ty; // Test position. + for (var i = 0; i < 500; i++) + { + tx = Random(LandscapeWidth()); + ty = Random(LandscapeHeight()); + if (GBackSemiSolid(AbsX(tx), AbsY(ty))) + continue; + if (GBackSemiSolid(AbsX(tx+5), AbsY(ty+10))) + continue; + if (GBackSemiSolid(AbsX(tx+5), AbsY(ty-10))) + continue; + if (GBackSemiSolid(AbsX(tx-5), AbsY(ty+10))) + continue; + if (GBackSemiSolid(AbsX(tx-5), AbsY(ty-10))) + continue; + // Succes. + return [tx, ty]; + } + return nil; } /*-- Scenario saving --*/ public func SaveScenarioObject(props, ...) { - if (!inherited(props, ...)) - return false; - // Custom properties - props->Remove("Name"); // updated by initialization - props->Remove("Description"); // updated by initialization - if (inventory_transfer) - props->AddCall("InventoryTransfer", this, "SetInventoryTransfer", inventory_transfer); - if (free_crew) - props->AddCall("FreeCrew", this, "SetFreeCrew", free_crew); - return true; + if (!inherited(props, ...)) + return false; + // Custom properties + props->Remove("Name"); // updated by initialization + props->Remove("Description"); // updated by initialization + if (inventory_transfer) + props->AddCall("InventoryTransfer", this, "SetInventoryTransfer", inventory_transfer); + if (free_crew) + props->AddCall("FreeCrew", this, "SetFreeCrew", free_crew); + if(respawn_at_base) + props->AddCall("BaseRespawn", this, "SetBaseRespawn", respawn_at_base); + return true; } /*-- Globals --*/ global func SetRelaunchCount(int plr, int value) { - if(UnlimitedRelaunches()) return; - GetRelaunchRule().aRelaunches[plr] = value; - Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().aRelaunches[plr]); - return value; + if(UnlimitedRelaunches()) return; + GetRelaunchRule().aRelaunches[plr] = value; + Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().aRelaunches[plr]); + return value; } global func GetRelaunchCount(int plr) { - return GetRelaunchRule().aRelaunches[plr]; + return GetRelaunchRule().aRelaunches[plr]; } global func DoRelaunchCount(int plr, int value) { - if(UnlimitedRelaunches()) return; - GetRelaunchRule().aRelaunches[plr] += value; - Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().aRelaunches[plr]); - return; + if(UnlimitedRelaunches()) return; + GetRelaunchRule().aRelaunches[plr] += value; + Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().aRelaunches[plr]); + return; } global func UnlimitedRelaunches() { - return GetRelaunchRule().DefaultRelaunchCount == nil; + return GetRelaunchRule().DefaultRelaunchCount == nil; } global func GetRelaunchRule() { - return FindObject(Find_ID(Rule_Relaunch)) || CreateObject(Rule_Relaunch); + return FindObject(Find_ID(Rule_Relaunch)) || CreateObject(Rule_Relaunch); } /* Editor */ public func Definition(def) { - if (!def.EditorProps) def.EditorProps = {}; - def.EditorProps.inventory_transfer = { Name="$InventoryTransfer$", EditorHelp="$InventoryTransferHelp$", Type="bool", Set="SetInventoryTransfer" }; - def.EditorProps.free_crew = { Name="$FreeCrew$", EditorHelp="$FreeCrewHelp$", Type="bool", Set="SetFreeCrew" }; - def.EditorProps.respawn_at_base = { - Name = "$RespawnAtBase$", - EditorHelp = "$RespawnAtBaseHelp$", - Type = "bool", - Set = "SetBaseRespawn" - }; - - def.EditorProps.hold = { - Name = "$Holding$", - EditorHelp = "$HoldingHelp$", - Type = "bool", - Set = "SetHolding" - }; - - def.EditorProps.respawn_delay = { - Name = "$RespawnDelay$", - EditorHelp = "$RespawnDelayHelp$", - Type = "int", - Set = "SetRespawnDelay" - }; - - def.EditorProps.relaunch_count = { - Name = "$RelaunchCount$", - EditorHelp = "$RelaunchCountHelp$", - Type = "int", - Set = "SetDefaultRelaunches" - }; + if (!def.EditorProps) def.EditorProps = {}; + def.EditorProps.inventory_transfer = { Name="$InventoryTransfer$", EditorHelp="$InventoryTransferHelp$", Type="bool", Set="SetInventoryTransfer" }; + def.EditorProps.free_crew = { Name="$FreeCrew$", EditorHelp="$FreeCrewHelp$", Type="bool", Set="SetFreeCrew" }; + def.EditorProps.respawn_at_base = { + Name = "$RespawnAtBase$", + EditorHelp = "$RespawnAtBaseHelp$", + Type = "bool", + Set = "SetBaseRespawn" + }; + + def.EditorProps.hold = { + Name = "$Holding$", + EditorHelp = "$HoldingHelp$", + Type = "bool", + Set = "SetHolding" + }; + + def.EditorProps.respawn_delay = { + Name = "$RespawnDelay$", + EditorHelp = "$RespawnDelayHelp$", + Type = "int", + Set = "SetRespawnDelay" + }; + + def.EditorProps.relaunch_count = { + Name = "$RelaunchCount$", + EditorHelp = "$RelaunchCountHelp$", + Type = "int", + Set = "SetDefaultRelaunches" + }; } /*-- Proplist --*/ From db6047c22a64e740f0d996b63e85a5da4d43d592 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 13:59:27 +0200 Subject: [PATCH 14/93] Remove Rule_Restart --- .../Rules.ocd/Restart.ocd/DefCore.txt | 7 ---- .../Rules.ocd/Restart.ocd/Graphics.2.png | Bin 5301 -> 0 bytes .../Rules.ocd/Restart.ocd/Script.c | 39 ------------------ .../Rules.ocd/Restart.ocd/StringTblDE.txt | 2 - .../Rules.ocd/Restart.ocd/StringTblUS.txt | 2 - 5 files changed, 50 deletions(-) delete mode 100644 planet/Objects.ocd/Rules.ocd/Restart.ocd/DefCore.txt delete mode 100644 planet/Objects.ocd/Rules.ocd/Restart.ocd/Graphics.2.png delete mode 100644 planet/Objects.ocd/Rules.ocd/Restart.ocd/Script.c delete mode 100644 planet/Objects.ocd/Rules.ocd/Restart.ocd/StringTblDE.txt delete mode 100644 planet/Objects.ocd/Rules.ocd/Restart.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Rules.ocd/Restart.ocd/DefCore.txt b/planet/Objects.ocd/Rules.ocd/Restart.ocd/DefCore.txt deleted file mode 100644 index b21e9c58f..000000000 --- a/planet/Objects.ocd/Rules.ocd/Restart.ocd/DefCore.txt +++ /dev/null @@ -1,7 +0,0 @@ -[DefCore] -id=Rule_Restart -Version=8,0 -Category=C4D_StaticBack|C4D_Rule -Width=32 -Height=32 -Offset=-16,-16 \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Restart.ocd/Graphics.2.png b/planet/Objects.ocd/Rules.ocd/Restart.ocd/Graphics.2.png deleted file mode 100644 index d725b854da7afd1d519c79436734d4f700e5137b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5301 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 Hu0mjf%T{$G diff --git a/planet/Objects.ocd/Rules.ocd/Restart.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Restart.ocd/Script.c deleted file mode 100644 index 237f2ce87..000000000 --- a/planet/Objects.ocd/Rules.ocd/Restart.ocd/Script.c +++ /dev/null @@ -1,39 +0,0 @@ -/*-- Restart --*/ - -local remove_contents; - -protected func Initialize() -{ - // Contents are removed - remove_contents = true; - return; -} - -public func Activate(int plr) -{ - // Notify scenario. - if (GameCall("OnPlayerRestart", plr)) - return; - // Remove the player's clonk, including contents. - var clonk = GetCrew(plr); - if (clonk && clonk->GetCrewEnabled()) - { - // Remove contents only if the Base Respawn Rule isn't there otherwise it will handle inventory - if (!ObjectCount(Find_ID(Rule_BaseRespawn)) && remove_contents) - while (clonk->Contents()) - clonk->Contents()->RemoveObject(); - clonk->Kill(clonk, true); - clonk->RemoveObject(); - } -} - -public func SetRemoveContents(bool do_removal) -{ - remove_contents = do_removal; - return; -} - -local Name = "$Name$"; -local Description = "$Description$"; -local Visibility = VIS_Editor; -local EditorPlacementLimit = 1; // Rules are to be placed only once diff --git a/planet/Objects.ocd/Rules.ocd/Restart.ocd/StringTblDE.txt b/planet/Objects.ocd/Rules.ocd/Restart.ocd/StringTblDE.txt deleted file mode 100644 index 5c75a6f5a..000000000 --- a/planet/Objects.ocd/Rules.ocd/Restart.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Neu starten -Description=Diese Spielregel erlaubt dem Spieler nochmal von vorne zu beginnen. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Restart.ocd/StringTblUS.txt b/planet/Objects.ocd/Rules.ocd/Restart.ocd/StringTblUS.txt deleted file mode 100644 index 9ec28cad5..000000000 --- a/planet/Objects.ocd/Rules.ocd/Restart.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Restart -Description=This rule allows the player to start again. \ No newline at end of file From 9b04051e65271329ae9eb12192ad0d1d7c4e386f Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:00:09 +0200 Subject: [PATCH 15/93] CaptureTheFlag: Fix wrong relaunch calls --- planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c index 95df7fbab..a2d0c52ca 100644 --- a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c @@ -77,7 +77,6 @@ private func EliminateOthers(int win_team) protected func InitializePlayer(int plr, int x, int y, object base, int team) { // Join new clonk. - GetRelaunchRule()->InitializePlayer(plr); GetRelaunchRule()->DoRelaunch(iPlr, nil, RelaunchPosition(team), true); // make scoreboard entry for team @@ -85,12 +84,7 @@ protected func InitializePlayer(int plr, int x, int y, object base, int team) return _inherited(plr, x, y, base, team, ...); } -protected func RelaunchPlayer(int plr) -{ - return GetRelaunchRule()->RelaunchPlayer(plr); -} - -private func RelaunchPosition(int iTeam) +public func RelaunchPosition(int iTeam) { var base = FindObject(Find_ID(Goal_FlagBase), Find_Func("FindTeam", team)); if (base) return [base->GetX(), base->GetY() - 10]; From c1d998d93e5295e2976ed385101ef0aa74048e30 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:00:32 +0200 Subject: [PATCH 16/93] RelaunchContainer: Modify OnPlayerLeftRelaunch() call --- .../Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c index 6c0ec85e8..78d7b2dca 100644 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c @@ -112,7 +112,7 @@ private func RelaunchClonk() SetPlrView(clonk->GetOwner(), clonk); } clonk->Exit(); - GameCall("OnClonkLeftRelaunch", clonk); + GameCall("OnClonkLeftRelaunch", clonk, clonk->GetOwner()); if (menu) menu->Close(); PlayerMessage(clonk->GetOwner(), ""); From b9f899a334ee9abcb2db152e377f0c3030955461 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:01:15 +0200 Subject: [PATCH 17/93] Move RelaunchContainer to Objects.ocd\Rules.ocd\Relaunch.ocd\Relaunch.ocd --- .../Relaunch.ocd/Relaunch.ocd/DefCore.txt | 7 + .../Relaunch.ocd/Relaunch.ocd/Graphics.png | Bin 0 -> 9989 bytes .../Relaunch.ocd/Relaunch.ocd/Script.c | 133 ++++++++++++++++++ .../Relaunch.ocd/Relaunch.ocd/StringTblDE.txt | 3 + .../Relaunch.ocd/Relaunch.ocd/StringTblUS.txt | 3 + 5 files changed, 146 insertions(+) create mode 100644 planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/DefCore.txt create mode 100644 planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/Graphics.png create mode 100644 planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/Script.c create mode 100644 planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/StringTblDE.txt create mode 100644 planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/DefCore.txt b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/DefCore.txt new file mode 100644 index 000000000..0e85c1d68 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=RelaunchContainer +Version=6,0 +Category=C4D_StaticBack +ClosedContainer=2 +Picture=0,0,92,92 +HideInCreator=true diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/Graphics.png b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/Graphics.png new file mode 100644 index 0000000000000000000000000000000000000000..e69712f472155e104710fb319ec9fc4fb28783e5 GIT binary patch literal 9989 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 time). + * After that time the clonk is released and OnClonkLeftRelaunch(object clonk) is called in the scenario script. + * Optionally the clonk can choose a weapon if GetRelaunchWeaponList in the scenario script returns a valid id-array. +--*/ + +local menu; +local has_selected; + +local crew; + +// Sets the GetRelaunchRule().RelaunchTime, in seconds, the clonk is held in the container. + +// Returns the GetRelaunchRule().RelaunchTime, in seconds the clonk is held. +public func GetRelaunchTime() { return GetRelaunchRule().RelaunchTime / 36; } + +// Retrieve weapon list from scenario. +private func WeaponList() { return GameCall("RelaunchWeaponList"); } + +public func StartRelaunch(object clonk) +{ + if (!clonk) + return; + // only 1 clonk can be inside + if(crew) + return; + // save clonk for later use + crew = clonk; + clonk->Enter(this); + ScheduleCall(this, "OpenWeaponMenu", 36, 0, clonk); + AddEffect("IntTimeLimit", this, 100, 36, this); + return true; +} + +private func OpenWeaponMenu(object clonk) +{ + if (!clonk) + return; + if (!menu) + { + var weapons = WeaponList(); + if (weapons) + { + menu = CreateObject(MenuStyle_Default, nil, nil, clonk->GetOwner()); + menu->SetPermanent(); + menu->SetTitle(Format("$MsgWeapon$", GetRelaunchRule().RelaunchTime / 36)); + clonk->SetMenu(menu, true); + + if(GetType(GetRelaunchRule().LastUsedPlayerWeapons) != C4V_Array) GetRelaunchRule().LastUsedPlayerWeapons = []; + for (var weapon in weapons) + { + if(GetRelaunchRule().LastUsedPlayerWeapons[clonk->GetOwner()] != weapon) + { + menu->AddItem(weapon, weapon->GetName(), nil, this, "OnWeaponSelected", weapon); + } + } + + menu->Open(); + } + } +} + +func FxIntTimeLimitTimer(object target, effect, int fxtime) +{ + var clonk = crew; + if (!clonk) + { + RemoveObject(); + return -1; + } + if (fxtime >= GetRelaunchRule().RelaunchTime) + { + if (!has_selected && WeaponList()) + GiveWeapon(WeaponList()[Random(GetLength(WeaponList()))]); + RelaunchClonk(); + return -1; + } + if (menu) + menu->SetTitle(Format("$MsgWeapon$", (GetRelaunchRule().RelaunchTime - fxtime) / 36)); + else + PlayerMessage(clonk->GetOwner(), Format("$MsgRelaunch$", (GetRelaunchRule().RelaunchTime - fxtime) / 36)); + return 1; +} + +public func OnWeaponSelected(id weapon) +{ + if(!crew) return; + GiveWeapon(weapon); + if(GetRelaunchRule().DisableLastWeapon) GetRelaunchRule().LastUsedPlayerWeapons[crew->GetOwner()] = weapon; + has_selected = true; + // Close menu manually, to prevent selecting more weapons. + if (menu) + menu->Close(); + + if (!GetRelaunchRule().Hold) + RelaunchClonk(); + return true; +} + +private func RelaunchClonk() +{ + var clonk = crew; + // When relaunching from disabled state (i.e base respawn), reset view to clonk + if (!clonk->GetCrewEnabled()) + { + clonk->SetCrewEnabled(true); + SetCursor(clonk->GetOwner(), clonk); + SetPlrView(clonk->GetOwner(), clonk); + } + clonk->Exit(); + GameCall("OnClonkLeftRelaunch", clonk, clonk->GetOwner()); + if (menu) + menu->Close(); + PlayerMessage(clonk->GetOwner(), ""); + RemoveObject(); + return; +} + +private func GiveWeapon(id weapon_id) +{ + var newobj = CreateObjectAbove(weapon_id); + newobj->~OnRelaunchCreation(crew); + crew->Collect(newobj); + return true; +} + +public func SaveScenarioObject() { return false; } + +local Name = "$Name$"; diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/StringTblDE.txt b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/StringTblDE.txt new file mode 100644 index 000000000..babe88679 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/StringTblDE.txt @@ -0,0 +1,3 @@ +Name=Relaunch container +MsgRelaunch=You will be relaunched in %d seconds. +MsgWeapon=You have %d seconds to choose a weapon. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/StringTblUS.txt b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/StringTblUS.txt new file mode 100644 index 000000000..04f6fccd2 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/StringTblUS.txt @@ -0,0 +1,3 @@ +Name=Relaunch container +MsgRelaunch=You will relaunch in %d seconds. +MsgWeapon=You have %d seconds to choose a weapon. \ No newline at end of file From d4b05c43ffb7194cfe7867e9f834f4dcdab40c30 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:01:35 +0200 Subject: [PATCH 18/93] RelaunchContainer: Rename folder --- .../DefCore.txt | 0 .../Graphics.png | Bin .../Script.c | 0 .../StringTblDE.txt | 0 .../StringTblUS.txt | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename planet/Objects.ocd/Rules.ocd/Relaunch.ocd/{Relaunch.ocd => RelaunchContainer.ocd}/DefCore.txt (100%) rename planet/Objects.ocd/Rules.ocd/Relaunch.ocd/{Relaunch.ocd => RelaunchContainer.ocd}/Graphics.png (100%) rename planet/Objects.ocd/Rules.ocd/Relaunch.ocd/{Relaunch.ocd => RelaunchContainer.ocd}/Script.c (100%) rename planet/Objects.ocd/Rules.ocd/Relaunch.ocd/{Relaunch.ocd => RelaunchContainer.ocd}/StringTblDE.txt (100%) rename planet/Objects.ocd/Rules.ocd/Relaunch.ocd/{Relaunch.ocd => RelaunchContainer.ocd}/StringTblUS.txt (100%) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/DefCore.txt b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/DefCore.txt similarity index 100% rename from planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/DefCore.txt rename to planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/DefCore.txt diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/Graphics.png b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/Graphics.png rename to planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Graphics.png diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c similarity index 100% rename from planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/Script.c rename to planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/StringTblDE.txt b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/StringTblDE.txt similarity index 100% rename from planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/StringTblDE.txt rename to planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/StringTblDE.txt diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/StringTblUS.txt b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/StringTblUS.txt similarity index 100% rename from planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Relaunch.ocd/StringTblUS.txt rename to planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/StringTblUS.txt From 568d04e7da0751f6459fea2e7024f14d09cef2d7 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:02:08 +0200 Subject: [PATCH 19/93] Move RelaunchContainer --- .../Relaunch.ocd/DefCore.txt | 7 - .../Relaunch.ocd/Graphics.png | Bin 9989 -> 0 bytes .../LastManStanding.ocd/Relaunch.ocd/Script.c | 133 ------------------ .../Relaunch.ocd/StringTblDE.txt | 3 - .../Relaunch.ocd/StringTblUS.txt | 3 - 5 files changed, 146 deletions(-) delete mode 100644 planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/DefCore.txt delete mode 100644 planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Graphics.png delete mode 100644 planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c delete mode 100644 planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/StringTblDE.txt delete mode 100644 planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/DefCore.txt b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/DefCore.txt deleted file mode 100644 index 0e85c1d68..000000000 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/DefCore.txt +++ /dev/null @@ -1,7 +0,0 @@ -[DefCore] -id=RelaunchContainer -Version=6,0 -Category=C4D_StaticBack -ClosedContainer=2 -Picture=0,0,92,92 -HideInCreator=true diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Graphics.png b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Graphics.png deleted file mode 100644 index e69712f472155e104710fb319ec9fc4fb28783e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9989 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 time). - * After that time the clonk is released and OnClonkLeftRelaunch(object clonk) is called in the scenario script. - * Optionally the clonk can choose a weapon if GetRelaunchWeaponList in the scenario script returns a valid id-array. ---*/ - -local menu; -local has_selected; - -local crew; - -// Sets the GetRelaunchRule().RelaunchTime, in seconds, the clonk is held in the container. - -// Returns the GetRelaunchRule().RelaunchTime, in seconds the clonk is held. -public func GetRelaunchTime() { return GetRelaunchRule().RelaunchTime / 36; } - -// Retrieve weapon list from scenario. -private func WeaponList() { return GameCall("RelaunchWeaponList"); } - -public func StartRelaunch(object clonk) -{ - if (!clonk) - return; - // only 1 clonk can be inside - if(crew) - return; - // save clonk for later use - crew = clonk; - clonk->Enter(this); - ScheduleCall(this, "OpenWeaponMenu", 36, 0, clonk); - AddEffect("IntTimeLimit", this, 100, 36, this); - return true; -} - -private func OpenWeaponMenu(object clonk) -{ - if (!clonk) - return; - if (!menu) - { - var weapons = WeaponList(); - if (weapons) - { - menu = CreateObject(MenuStyle_Default, nil, nil, clonk->GetOwner()); - menu->SetPermanent(); - menu->SetTitle(Format("$MsgWeapon$", GetRelaunchRule().RelaunchTime / 36)); - clonk->SetMenu(menu, true); - - if(GetType(GetRelaunchRule().LastUsedPlayerWeapons) != C4V_Array) GetRelaunchRule().LastUsedPlayerWeapons = []; - for (var weapon in weapons) - { - if(GetRelaunchRule().LastUsedPlayerWeapons[clonk->GetOwner()] != weapon) - { - menu->AddItem(weapon, weapon->GetName(), nil, this, "OnWeaponSelected", weapon); - } - } - - menu->Open(); - } - } -} - -func FxIntTimeLimitTimer(object target, effect, int fxtime) -{ - var clonk = crew; - if (!clonk) - { - RemoveObject(); - return -1; - } - if (fxtime >= GetRelaunchRule().RelaunchTime) - { - if (!has_selected && WeaponList()) - GiveWeapon(WeaponList()[Random(GetLength(WeaponList()))]); - RelaunchClonk(); - return -1; - } - if (menu) - menu->SetTitle(Format("$MsgWeapon$", (GetRelaunchRule().RelaunchTime - fxtime) / 36)); - else - PlayerMessage(clonk->GetOwner(), Format("$MsgRelaunch$", (GetRelaunchRule().RelaunchTime - fxtime) / 36)); - return 1; -} - -public func OnWeaponSelected(id weapon) -{ - if(!crew) return; - GiveWeapon(weapon); - if(GetRelaunchRule().DisableLastWeapon) GetRelaunchRule().LastUsedPlayerWeapons[crew->GetOwner()] = weapon; - has_selected = true; - // Close menu manually, to prevent selecting more weapons. - if (menu) - menu->Close(); - - if (!GetRelaunchRule().Hold) - RelaunchClonk(); - return true; -} - -private func RelaunchClonk() -{ - var clonk = crew; - // When relaunching from disabled state (i.e base respawn), reset view to clonk - if (!clonk->GetCrewEnabled()) - { - clonk->SetCrewEnabled(true); - SetCursor(clonk->GetOwner(), clonk); - SetPlrView(clonk->GetOwner(), clonk); - } - clonk->Exit(); - GameCall("OnClonkLeftRelaunch", clonk, clonk->GetOwner()); - if (menu) - menu->Close(); - PlayerMessage(clonk->GetOwner(), ""); - RemoveObject(); - return; -} - -private func GiveWeapon(id weapon_id) -{ - var newobj = CreateObjectAbove(weapon_id); - newobj->~OnRelaunchCreation(crew); - crew->Collect(newobj); - return true; -} - -public func SaveScenarioObject() { return false; } - -local Name = "$Name$"; diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/StringTblDE.txt b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/StringTblDE.txt deleted file mode 100644 index babe88679..000000000 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/StringTblDE.txt +++ /dev/null @@ -1,3 +0,0 @@ -Name=Relaunch container -MsgRelaunch=You will be relaunched in %d seconds. -MsgWeapon=You have %d seconds to choose a weapon. \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/StringTblUS.txt b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/StringTblUS.txt deleted file mode 100644 index 04f6fccd2..000000000 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/StringTblUS.txt +++ /dev/null @@ -1,3 +0,0 @@ -Name=Relaunch container -MsgRelaunch=You will relaunch in %d seconds. -MsgWeapon=You have %d seconds to choose a weapon. \ No newline at end of file From f14bfa418b0cf085a3b6a6cadffa38bd36427510 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:02:48 +0200 Subject: [PATCH 20/93] Modify FrozenFortress in order to work with Rule_Relaunch --- planet/Arena.ocf/FrozenFortress.ocs/Script.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/planet/Arena.ocf/FrozenFortress.ocs/Script.c b/planet/Arena.ocf/FrozenFortress.ocs/Script.c index fb24db619..725ff27f2 100644 --- a/planet/Arena.ocf/FrozenFortress.ocs/Script.c +++ b/planet/Arena.ocf/FrozenFortress.ocs/Script.c @@ -10,6 +10,9 @@ protected func Initialize() { // Environment CreateObject(Rule_ObjectFade)->DoFadeTime(10 * 36); + + GetRelaunchRule()->SetLastWeaponUse(false); + var time=CreateObject(Time); time->SetTime(); time->SetCycleSpeed(); @@ -151,16 +154,6 @@ protected func InitializePlayer(int plr) return; } -// Gamecall from CTF goal, on respawning. -protected func OnPlayerRelaunch(int plr) -{ - var clonk = GetCrew(plr); - var relaunch = CreateObjectAbove(RelaunchContainer, clonk->GetX(), clonk->GetY(), clonk->GetOwner()); - relaunch->StartRelaunch(clonk); - relaunch->SetRelaunchTime(8, true); - return; -} - func RelaunchWeaponList() { return [Blunderbuss, Sword, Javelin, FrostboltScroll, Shovel]; } /*-- Chest filler effects --*/ From 8d69713ff2002db5c35cb348ea3be4dcbe4de091 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:03:13 +0200 Subject: [PATCH 21/93] Modify Hideout in order to work with Rule_Relaunch --- planet/Arena.ocf/Hideout.ocs/Script.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/planet/Arena.ocf/Hideout.ocs/Script.c b/planet/Arena.ocf/Hideout.ocs/Script.c index 8505945df..714d1a2b8 100644 --- a/planet/Arena.ocf/Hideout.ocs/Script.c +++ b/planet/Arena.ocf/Hideout.ocs/Script.c @@ -22,6 +22,9 @@ protected func Initialize() CreateObject(Rule_ObjectFade)->DoFadeTime(5 * 36); CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); + GetRelaunchRule()->SetDefaultRelaunchCount(nil); + GetRelaunchRule()->SetRespawnDelay(8); + GetRelaunchRule()->SetLastWeaponUse(false); var lwidth = LandscapeWidth(); @@ -100,16 +103,6 @@ protected func InitializePlayer(int plr) return; } -// Gamecall from CTF goal, on respawning. -protected func OnPlayerRelaunch(int plr) -{ - var clonk = GetCrew(plr); - var relaunch = CreateObjectAbove(RelaunchContainer, clonk->GetX(), clonk->GetY(), clonk->GetOwner()); - relaunch->StartRelaunch(clonk); - relaunch->SetRelaunchTime(8, true); - return; -} - // Game call from RelaunchContainer when a Clonk has left the respawn. public func OnClonkLeftRelaunch(object clonk) { From b88137e97a8a5419974bc18ee94001dd330a59bd Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:03:30 +0200 Subject: [PATCH 22/93] Modify MeltingCastle in order to work with Rule_Relaunch --- planet/Arena.ocf/MeltingCastle.ocs/Script.c | 60 ++++++++------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/planet/Arena.ocf/MeltingCastle.ocs/Script.c b/planet/Arena.ocf/MeltingCastle.ocs/Script.c index 4092c9dc2..be965bea7 100644 --- a/planet/Arena.ocf/MeltingCastle.ocs/Script.c +++ b/planet/Arena.ocf/MeltingCastle.ocs/Script.c @@ -7,6 +7,9 @@ static const EDIT_MAP = false; // Set to true to edit map and Objects.c; avoids func Initialize() { if (EDIT_MAP) return true; + GetRelaunchRule()->SetRelaunchCount(nil); + GetRelaunchRule()->SetRespawnDelay(8); + GetRelaunchRule()->SetLastWeaponUse(false); // Mirror map objects by moving them to the other side, then re-running object initialization for (var o in FindObjects(Find_NoContainer(), Find_Not(Find_Category(C4D_Goal | C4D_Rule)))) { @@ -105,7 +108,6 @@ func InitializePlayer(int plr) ScheduleCall(nil, Scenario.IntroMsg, 10, 1); } // Initial launch - RelaunchPlayer(plr); return true; } @@ -125,56 +127,38 @@ func IntroMsg() return true; } -func LaunchPlayer(int plr) +func LaunchPlayer(object pClonk, int plr) { - // Position at flag - var flagpole = g_respawn_flags[GetPlayerTeam(plr)]; - if (!flagpole) return EliminatePlayer(plr); // Flag lost and clonk died? Game over! - var crew = GetCrew(plr), start_x = flagpole->GetX(), start_y = flagpole->GetY(); - crew->SetPosition(start_x, start_y); // Make sure clonk can move - DigFreeRect(start_x-6,start_y-10,13,18,true); + DigFreeRect(pClonk->GetX()-6,pClonk->GetY()-10,13,18,true); // Crew setup - crew.MaxEnergy = 100000; - crew->DoEnergy(1000); - crew->CreateContents(WindBag); + pClonk.MaxEnergy = 100000; + pClonk->DoEnergy(1000); + pClonk->CreateContents(WindBag); return true; } -func RelaunchPlayer(int plr) +public func OnPlayerRelaunch(iPlr) +{ + if(!g_respawn_flags[GetPlayerTeam(plr)]) return EliminatePlayer(plr); +} + +public func RelaunchPosition(int iPlr, int iTeam) +{ + if(!g_respawn_flags[iTeam]) return; + return [g_respawn_flags[iTeam]->GetX(), g_respawn_flags[iTeam]->GetY()]; +} + +public func OnClonkLeftRelaunch(object pClonk, int plr) { // Find flag for respawn var flagpole = g_respawn_flags[GetPlayerTeam(plr)]; if (!flagpole) return EliminatePlayer(plr); // Flag lost and clonk died? Game over! - // Player positioning. - var start_x = flagpole->GetX(), start_y = flagpole->GetY(); - // Relaunch: New clonk - var crew = GetCrew(plr); - var is_relaunch = (!crew || !crew->GetAlive()); - if (is_relaunch) - { - crew = CreateObject(Clonk, 10,10, plr); - if (!crew) return false; // wat? - crew->MakeCrewMember(plr); - SetCursor(plr, crew, false); - } + // Reset available items in spawns for (var item_spawn in FindObjects(Find_ID(ItemSpawn))) item_spawn->Reset(plr); // Relaunch near current flag pos (will be adjusted on actual relaunch) - crew->SetPosition(start_x, start_y); - var relaunch = CreateObjectAbove(RelaunchContainer, start_x, start_y, plr); - if (relaunch) - { - relaunch->StartRelaunch(crew); - relaunch->SetRelaunchTime(8, is_relaunch); - } - return true; -} - -// GameCall from RelaunchContainer. -func OnClonkLeftRelaunch(object clonk) -{ - if (clonk) return LaunchPlayer(clonk->GetOwner()); + return LaunchPlayer(plr); } func RelaunchWeaponList() { return [Bow, Sword, Club, Javelin, Blunderbuss, Firestone, IceWallKit]; } From f5e0aa40362f875a9d0aecb2c2d351b01d24b989 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:03:49 +0200 Subject: [PATCH 23/93] Modify MoltenMonarch in order to work with Rule_Relaunch --- planet/Arena.ocf/MoltenMonarch.ocs/Script.c | 27 +++------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/planet/Arena.ocf/MoltenMonarch.ocs/Script.c b/planet/Arena.ocf/MoltenMonarch.ocs/Script.c index ea8b3d327..ffc2c9ccb 100644 --- a/planet/Arena.ocf/MoltenMonarch.ocs/Script.c +++ b/planet/Arena.ocf/MoltenMonarch.ocs/Script.c @@ -18,6 +18,7 @@ protected func Initialize() CreateObject(Rule_ObjectFade)->DoFadeTime(7 * 36); CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); + GetRelaunchRule()->SetLastWeaponUse(false); //make lava collapse CreateObjectAbove(Firestone,625,480); @@ -147,31 +148,9 @@ global func CreateChestContents(id obj_id) return; } -protected func InitializePlayer(int plr) +public func RelaunchPosition() { - return JoinPlayer(plr); -} - -// GameCall from RelaunchContainer. -protected func RelaunchPlayer(int plr) -{ - var clonk = CreateObjectAbove(Clonk, 0, 0, plr); - clonk->MakeCrewMember(plr); - SetCursor(plr, clonk); - JoinPlayer(plr); - return; -} - -protected func JoinPlayer(int plr) -{ - var clonk = GetCrew(plr); - clonk->DoEnergy(100000); - var position = [[420,200],[300,440],[130,176],[140,368],[700,192],[670,336],[750,440],[440,392],[45,256]]; - var r=Random(GetLength(position)); - var x = position[r][0], y = position[r][1]; - var relaunch = CreateObjectAbove(RelaunchContainer, x, y, clonk->GetOwner()); - relaunch->StartRelaunch(clonk); - return; + return [[420,200],[300,440],[130,176],[140,368],[700,192],[670,336],[750,440],[440,392],[45,256]]; } func RelaunchWeaponList() { return [Bow, Shield, Sword, Javelin, Blunderbuss, Club]; } From 969cebd03af5d9180f4dd5ff373c7414b3e0cfcc Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:04:02 +0200 Subject: [PATCH 24/93] Modify Overcast in order to work with Rule_Relaunch --- planet/Arena.ocf/Overcast.ocs/Script.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/planet/Arena.ocf/Overcast.ocs/Script.c b/planet/Arena.ocf/Overcast.ocs/Script.c index db1c7af65..2831f51f1 100644 --- a/planet/Arena.ocf/Overcast.ocs/Script.c +++ b/planet/Arena.ocf/Overcast.ocs/Script.c @@ -14,6 +14,7 @@ protected func Initialize() CreateObject(Goal_LastManStanding); CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); + GetRelaunchRule()->SetLastWeaponUse(false); //Enviroment. Cloud->Place(25); @@ -339,27 +340,19 @@ global func CreateChestContents(id obj_id) // GameCall from RelaunchContainer. func OnClonkLeftRelaunch(object clonk) { - var pos = GetRandomSpawn(); - clonk->SetPosition(pos[0],pos[1]); CreateParticle("Air", pos[0],pos[1], PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(5, 10), Overcast_air_particles, 25); return; } -global func GetRandomSpawn() +public func RelaunchPosition() { - var spawns = [[432,270],[136,382],[200,134],[864,190],[856,382],[840,518],[408,86],[536,470]]; - var rand = Random(GetLength(spawns)); - return spawns[rand]; + return [[432,270],[136,382],[200,134],[864,190],[856,382],[840,518],[408,86],[536,470]]; + } - -// Gamecall from LastManStanding goal, on respawning. -protected func OnPlayerRelaunch(int plr) +global func GetRandomSpawn() { - var clonk = GetCrew(plr); - var relaunch = CreateObjectAbove(RelaunchContainer, LandscapeWidth() / 2, LandscapeHeight() / 2, clonk->GetOwner()); - relaunch->StartRelaunch(clonk); - return; + return Scenario->RelaunchPosition(); } func KillsToRelaunch() { return 0; } From c1477818617f44de9380b5a7c3d09d57683cca0a Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:04:16 +0200 Subject: [PATCH 25/93] Modify RockBottom in order to work with Rule_Relaunch --- planet/Arena.ocf/RockBottom.ocs/Script.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/planet/Arena.ocf/RockBottom.ocs/Script.c b/planet/Arena.ocf/RockBottom.ocs/Script.c index 7e198b846..69ed9712f 100644 --- a/planet/Arena.ocf/RockBottom.ocs/Script.c +++ b/planet/Arena.ocf/RockBottom.ocs/Script.c @@ -12,6 +12,7 @@ protected func Initialize() CreateObject(Goal_LastManStanding, 0, 0, NO_OWNER); CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); + GetRelaunchRule()->SetLastWeaponUse(false); // Chests with weapons. var chest = CreateObjectAbove(Chest, 108, 248); @@ -82,16 +83,6 @@ protected func InitializePlayer(int plr) return; } -// Gamecall from LastManStanding goal, on respawning. -protected func OnPlayerRelaunch(int plr) -{ - var clonk = GetCrew(plr); - var relaunch = CreateObjectAbove(RelaunchContainer, LandscapeWidth() / 2, LandscapeHeight() / 2, clonk->GetOwner()); - relaunch->StartRelaunch(clonk); - return; -} - - // Refill/fill chests. global func FxIntFillChestsStart(object target, proplist effect, int temporary, object chest) { @@ -135,5 +126,10 @@ public func OnClonkLeftRelaunch(object clonk) return; } +public func RelaunchPosition() +{ + return [LandscapeWidth() / 2, LandscapeHeight() / 2]; +} + public func KillsToRelaunch() { return 0; } public func RelaunchWeaponList() { return [Bow, Shield, Sword, Firestone, Dynamite, Javelin, Blunderbuss]; } From 6e88fe5d2fcc10513e8311c57ef923c3af270ee1 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:04:29 +0200 Subject: [PATCH 26/93] Modify Ruins in order to work with Rule_Relaunch --- planet/Arena.ocf/Ruins.ocs/Script.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/planet/Arena.ocf/Ruins.ocs/Script.c b/planet/Arena.ocf/Ruins.ocs/Script.c index 46cddada6..a0e754327 100644 --- a/planet/Arena.ocf/Ruins.ocs/Script.c +++ b/planet/Arena.ocf/Ruins.ocs/Script.c @@ -13,6 +13,7 @@ protected func Initialize() CreateObject(Goal_LastManStanding, 0, 0, NO_OWNER); CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); + GetRelaunchRule()->SetLastWeaponUse(false); // Mood. SetSkyAdjust(RGBa(255, 255, 255, 127), RGB(255, 200, 150)); @@ -37,15 +38,6 @@ protected func Initialize() return; } -// Gamecall from LastManStanding goal, on respawning. -protected func OnPlayerRelaunch(int plr) -{ - var clonk = GetCrew(plr); - var relaunch = CreateObjectAbove(RelaunchContainer, LandscapeWidth() / 2, LandscapeHeight() / 2, clonk->GetOwner()); - relaunch->StartRelaunch(clonk); - return; -} - global func FxRainTimer(object pTarget, effect, int timer) { From 689e57d624a82bc1cf9d76479cecdee183fbe407 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:04:44 +0200 Subject: [PATCH 27/93] Modify ScorchedGardens in order to work with Rule_Relaunch --- planet/Arena.ocf/ScorchedGardens.ocs/Script.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/planet/Arena.ocf/ScorchedGardens.ocs/Script.c b/planet/Arena.ocf/ScorchedGardens.ocs/Script.c index bdd2041b8..e842b3dcc 100644 --- a/planet/Arena.ocf/ScorchedGardens.ocs/Script.c +++ b/planet/Arena.ocf/ScorchedGardens.ocs/Script.c @@ -13,6 +13,9 @@ protected func Initialize() CreateObject(Goal_LastManStanding); CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); + GetRelaunchRule() + ->SetRespawnDelay(3) + ->SetLastWeaponUse(false); // Enviroment. CreateObject(Rule_ObjectFade)->DoFadeTime(10 * 36); @@ -73,25 +76,21 @@ private func PlaceGras() return; } -protected func OnPlayerRelaunch(int plr) +public func RelaunchPosition() { - var clonk = GetCrew(plr); - clonk->DoEnergy(100000); var x = RandomX(75,500); var y=100; while(!GBackSolid(x,y)) y+=1; y-=30; - var relaunch = CreateObjectAbove(RelaunchContainer, x, y, clonk->GetOwner()); - relaunch->StartRelaunch(clonk); - relaunch->SetRelaunchTime(3); - clonk->CreateContents(TeleGlove); - return; + + return [x, y]; } public func OnClonkLeftRelaunch(object clonk) { clonk->CreateParticle("Fire", 0, 0, PV_Random(-20, 20), PV_Random(-40, 5), PV_Random(20, 90), Particles_Glimmer(), 30); clonk->SetYDir(-5); + clonk->CreateContents(TeleGlove); return; } @@ -104,5 +103,4 @@ public func OnClonkDeath(object clonk) } // Settings for LMS and DM. -public func RelaunchCount() { return 5; } public func WinKillCount() { return 5; } From 76d8df9676d7c5a7122704203e2ff2a730436961 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:04:58 +0200 Subject: [PATCH 28/93] Modify ThunderousSkies in order to work with Rule_Relaunch --- planet/Arena.ocf/ThunderousSkies.ocs/Script.c | 23 +++---------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/planet/Arena.ocf/ThunderousSkies.ocs/Script.c b/planet/Arena.ocf/ThunderousSkies.ocs/Script.c index cca3d6827..72023d5da 100644 --- a/planet/Arena.ocf/ThunderousSkies.ocs/Script.c +++ b/planet/Arena.ocf/ThunderousSkies.ocs/Script.c @@ -18,6 +18,7 @@ protected func Initialize() AddEffect("BlessTheKing",goal,100,1,nil); CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); + GetRelaunchRule()->SetLastWeaponUse(false); //Enviroment. //SetSkyAdjust(RGBa(250,250,255,128),RGB(200,200,220)); @@ -247,29 +248,11 @@ protected func InitializePlayer(int plr) { // This scenario does not have shadows. SetFoW(false, plr); - return JoinPlayer(plr); } -// GameCall from RelaunchContainer. -protected func RelaunchPlayer(int plr) +public func RelaunchPosition() { - var clonk = CreateObjectAbove(Clonk, 0, 0, plr); - clonk->MakeCrewMember(plr); - SetCursor(plr, clonk); - JoinPlayer(plr); - return; -} - -protected func JoinPlayer(int plr) -{ - var clonk = GetCrew(plr); - clonk->DoEnergy(100000); - var position = [[180,150],[310,320],[600,290],[650,180],[790,110],[440,190]]; - var r=Random(GetLength(position)); - var x = position[r][0], y = position[r][1]; - var relaunch = CreateObjectAbove(RelaunchContainer, x, y + 49, clonk->GetOwner()); - relaunch->StartRelaunch(clonk); - return; + return [[180,150],[310,320],[600,290],[650,180],[790,110],[440,190]]; } func KillsToRelaunch() { return 0; } From 51d61d1b2616d24b1c005687bf298e8eec386c54 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:08:22 +0200 Subject: [PATCH 29/93] Modify GrenadeLauncher in order to work with Rule_Relaunch --- .../Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c index 54995ee3c..3a0f83dca 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c @@ -247,6 +247,12 @@ public func GetCarryTransform(object clonk, bool idle, bool nohand, bool second_ return Trans_Mul(Trans_Rotate(90,1,0,0), Trans_Rotate(-10,0,0,1)); } + +public func OnRelaunchCreation() +{ + CreateContents(IronBomb); +} + func Definition(def) { def.PictureTransformation = Trans_Mul(Trans_Translate(-3000, 1000, 1500),Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1)); From b76cedbe7e1b7035837e51bf8276e2445b1c5cef Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:08:38 +0200 Subject: [PATCH 30/93] Modify Bow in order to work with Rule_Relaunch --- planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Script.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Script.c index 803e45aa5..e46a2c451 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Script.c @@ -232,6 +232,12 @@ public func GetCarrySpecial(clonk) if(fAiming) return "pos_hand2"; } + +public func OnRelaunchCreation() +{ + CreateContents(Arrow); +} + func Definition(def) { def.PictureTransformation = Trans_Mul(Trans_Translate(-4000,-2000,4000),Trans_Rotate(180,0,1,0),Trans_Rotate(-45,0,0,1)); From b7108ff8361b881e13f5d2183c1d9893cbac585d Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 14:08:53 +0200 Subject: [PATCH 31/93] Modify Blunderbuss in order to work with Rule_Relaunch --- .../Items.ocd/Weapons.ocd/Blunderbuss.ocd/Script.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Blunderbuss.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Blunderbuss.ocd/Script.c index d75b6694b..3e1b0e1bb 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Blunderbuss.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Blunderbuss.ocd/Script.c @@ -228,6 +228,11 @@ public func GetCarryTransform() return Trans_Rotate(90, 1, 0, 0); } +public func OnRelaunchCreation() +{ + CreateContents(LeadBullet); +} + public func Definition(def) { SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(1500, 0, -1500), Trans_Rotate(170, 0, 1, 0), Trans_Rotate(30, 0, 0, 1)), def); From 44ca079bf68e40915cf420889fd99dba96ca6ed9 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 19:35:29 +0200 Subject: [PATCH 32/93] Modify Missions.ocf in order to work with Rule_Relaunch - Crash - DarkCastle - DeepSeaMining - Raid - TreasureHunt --- planet/Missions.ocf/Crash.ocs/Objects.c | 6 ------ planet/Missions.ocf/Crash.ocs/Script.c | 6 ++++++ planet/Missions.ocf/DarkCastle.ocs/Objects.c | 5 ----- planet/Missions.ocf/DarkCastle.ocs/Scenario.txt | 2 +- planet/Missions.ocf/DarkCastle.ocs/Script.c | 6 ++++++ planet/Missions.ocf/DeepSeaMining.ocs/Scenario.txt | 2 +- planet/Missions.ocf/DeepSeaMining.ocs/Script.c | 13 +++++++------ planet/Missions.ocf/Raid.ocs/Objects.c | 6 ------ planet/Missions.ocf/Raid.ocs/Scenario.txt | 2 +- planet/Missions.ocf/Raid.ocs/Script.c | 6 ++++++ planet/Missions.ocf/TreasureHunt.ocs/Objects.c | 6 ------ planet/Missions.ocf/TreasureHunt.ocs/Scenario.txt | 2 +- planet/Missions.ocf/TreasureHunt.ocs/Script.c | 6 ++++++ 13 files changed, 35 insertions(+), 33 deletions(-) diff --git a/planet/Missions.ocf/Crash.ocs/Objects.c b/planet/Missions.ocf/Crash.ocs/Objects.c index 58dc37ec8..4821ded62 100644 --- a/planet/Missions.ocf/Crash.ocs/Objects.c +++ b/planet/Missions.ocf/Crash.ocs/Objects.c @@ -9,14 +9,8 @@ func InitializeObjects() var BoilingLava001 = CreateObject(BoilingLava); BoilingLava001->SetIntensity(25); - var Rule_BaseRespawn001 = CreateObject(Rule_BaseRespawn); - Rule_BaseRespawn001->SetInventoryTransfer(true); - Rule_BaseRespawn001->SetFreeCrew(true); - CreateObject(Rule_TeamAccount); - CreateObject(Rule_Restart); - CreateObjectAbove(Tree_Coniferous, 380, 877); var Tree_Coniferous2001 = CreateObjectAbove(Tree_Coniferous2, 562, 563); diff --git a/planet/Missions.ocf/Crash.ocs/Script.c b/planet/Missions.ocf/Crash.ocs/Script.c index 49dc41682..091cdabd4 100644 --- a/planet/Missions.ocf/Crash.ocs/Script.c +++ b/planet/Missions.ocf/Crash.ocs/Script.c @@ -53,6 +53,12 @@ func DoInit(int first_player) // Start intro if not yet started StartSequence("Intro", 0, GetCrew(first_player)); + GetRelaunchRule() + ->SetInventoryTransfer(true) + ->SetLastClonkRespawn(true) + ->SetFreeCrew(true) + ->EnablePlayerRestart(); + return true; } diff --git a/planet/Missions.ocf/DarkCastle.ocs/Objects.c b/planet/Missions.ocf/DarkCastle.ocs/Objects.c index 1f8167608..540c9dda2 100644 --- a/planet/Missions.ocf/DarkCastle.ocs/Objects.c +++ b/planet/Missions.ocf/DarkCastle.ocs/Objects.c @@ -11,9 +11,6 @@ func InitializeObjects() var Grass003 = CreateObjectAbove(Grass, 228, 1180); Grass003->SetClrModulation(0xffa08060); - var Rule_BaseRespawn001 = CreateObject(Rule_BaseRespawn); - Rule_BaseRespawn001->SetInventoryTransfer(true); - Rule_BaseRespawn001->SetFreeCrew(true); var Tree_Coniferous_Burned001 = CreateObject(Tree_Coniferous_Burned, 17, 1097); Tree_Coniferous_Burned001->SetR(10); @@ -543,7 +540,5 @@ func InitializeObjects() CreateObject(Rule_Gravestones); - CreateObject(Rule_Restart); - return true; } diff --git a/planet/Missions.ocf/DarkCastle.ocs/Scenario.txt b/planet/Missions.ocf/DarkCastle.ocs/Scenario.txt index 28314b0fb..139cd02dc 100644 --- a/planet/Missions.ocf/DarkCastle.ocs/Scenario.txt +++ b/planet/Missions.ocf/DarkCastle.ocs/Scenario.txt @@ -11,7 +11,7 @@ Definition1=Objects.ocd Definition2=Decoration.ocd [Game] -Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1;Rule_BaseRespawn=1; +Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1; [Player1] Knowledge=ToolsWorkshop=1;Foundry=1;Flagpole=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;Sword=1;Metal=1;GoldBar=1;Balloon=1;Boompack=1;GrappleBow=1;JarOfWinds=1;Pipe=1;Pump=1;PowderKeg=1;Ropeladder=1;Bow=1;Arrow=1;Club=1;IronBomb=1;Javelin=1;Shield=1;InventorsLab=1;Sawmill=1;BombArrow=1;FireArrow=1;GrenadeLauncher=1;Torch=1;WoodenBridge=1;Basement=1; diff --git a/planet/Missions.ocf/DarkCastle.ocs/Script.c b/planet/Missions.ocf/DarkCastle.ocs/Script.c index 0f0f71c8d..b8d1792bc 100644 --- a/planet/Missions.ocf/DarkCastle.ocs/Script.c +++ b/planet/Missions.ocf/DarkCastle.ocs/Script.c @@ -11,6 +11,12 @@ static npc_pyrit; private func DoInit(int first_player) { + GetRelaunchRule() + ->SetBaseRespawn(true) + ->SetInventoryTransfer(true) + ->SetFreeCrew(true) + ->EnablePlayerRestart() + ->SetLastClonkRespawn(true); // Message when first player enters shroom area ScheduleCall(nil, Scenario.ShroomCaveCheck, 21, 0xffffff); // Scorching village diff --git a/planet/Missions.ocf/DeepSeaMining.ocs/Scenario.txt b/planet/Missions.ocf/DeepSeaMining.ocs/Scenario.txt index 118300ab1..e33512951 100644 --- a/planet/Missions.ocf/DeepSeaMining.ocs/Scenario.txt +++ b/planet/Missions.ocf/DeepSeaMining.ocs/Scenario.txt @@ -11,7 +11,7 @@ Definition2=Decoration.ocd\Misc.ocd\Hat.ocd Definition3=Decoration.ocd\Clonk.ocd\AltSkins.ocd [Game] -Rules=Rule_TeamAccount=1;Rule_BuyAtFlagpole=1;Rule_BaseRespawn=1;Rule_Restart=1; +Rules=Rule_TeamAccount=1;Rule_BuyAtFlagpole=1; Goals=Goal_BuildCrystalCommunicator=1; ValueOverloads=Ruby=10;Amethyst=10 diff --git a/planet/Missions.ocf/DeepSeaMining.ocs/Script.c b/planet/Missions.ocf/DeepSeaMining.ocs/Script.c index 42a11417a..f76dab95b 100644 --- a/planet/Missions.ocf/DeepSeaMining.ocs/Script.c +++ b/planet/Missions.ocf/DeepSeaMining.ocs/Script.c @@ -33,12 +33,13 @@ protected func PostIntroInitialize() } // Rules - var respawn_rule = FindObject(Find_ID(Rule_BaseRespawn)); - if (respawn_rule) - { - respawn_rule->SetInventoryTransfer(true); - respawn_rule->SetFreeCrew(true); - } + GetRelaunchRule() + ->SetDefaultRelaunches() + ->SetInventoryTransfer(true) + ->SetFreeCrew(true) + ->EnablePlayerRestart() + ->SetBaseRespawn(true) + ->SetLastClonkRespawn(true); // Initialize different parts of the scenario. InitializeAmbience(); diff --git a/planet/Missions.ocf/Raid.ocs/Objects.c b/planet/Missions.ocf/Raid.ocs/Objects.c index 80154a4e5..fa8ed99c8 100644 --- a/planet/Missions.ocf/Raid.ocs/Objects.c +++ b/planet/Missions.ocf/Raid.ocs/Objects.c @@ -7,17 +7,11 @@ func InitializeObjects() var Time001 = CreateObject(Time); Time001->SetTime(600); Time001->SetCycleSpeed(20); - - var Rule_BaseRespawn001 = CreateObject(Rule_BaseRespawn); - Rule_BaseRespawn001->SetInventoryTransfer(true); - Rule_BaseRespawn001->SetFreeCrew(true); CreateObject(Rule_NoPowerNeed); CreateObject(Rule_TeamAccount); - CreateObject(Rule_Restart); - CreateObjectAbove(EnvPack_Scarecrow, 1218, 440); CreateObjectAbove(EnvPack_Guidepost, 835, 369); diff --git a/planet/Missions.ocf/Raid.ocs/Scenario.txt b/planet/Missions.ocf/Raid.ocs/Scenario.txt index 8bcade2e4..e72c6e174 100644 --- a/planet/Missions.ocf/Raid.ocs/Scenario.txt +++ b/planet/Missions.ocf/Raid.ocs/Scenario.txt @@ -10,7 +10,7 @@ Definition2=Decoration.ocd [Game] Goals=Goal_Raid=1 -Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1;Rule_BaseRespawn=1; +Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1; [Player1] Knowledge=Foundry=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;GoldBar=1;Metal=1;Pipe=1;WallKit=1;WindGenerator=1; diff --git a/planet/Missions.ocf/Raid.ocs/Script.c b/planet/Missions.ocf/Raid.ocs/Script.c index 2cd841de6..835c6f3fe 100644 --- a/planet/Missions.ocf/Raid.ocs/Script.c +++ b/planet/Missions.ocf/Raid.ocs/Script.c @@ -26,6 +26,12 @@ static g_is_initialized, // intro started func Initialize() { + GetRelaunchRule() + ->SetBaseRespawn(true) + ->SetFairCrew(true) + ->InventoryTransfer(true) + ->EnablePlayerRestart() + ->SetLastClonkRespawn(true); npc_newton->SetAlternativeSkin("MaleBlackHair"); npc_pyrit->SetAlternativeSkin("MaleBrownHair"); npc_woody->SetAlternativeSkin("Youngster"); diff --git a/planet/Missions.ocf/TreasureHunt.ocs/Objects.c b/planet/Missions.ocf/TreasureHunt.ocs/Objects.c index d80cb3e4e..659b51e65 100644 --- a/planet/Missions.ocf/TreasureHunt.ocs/Objects.c +++ b/planet/Missions.ocf/TreasureHunt.ocs/Objects.c @@ -32,16 +32,10 @@ func InitializeObjects() Column001->SetMeshMaterial("AncientColumn", 0); Column001.Plane = 50; - var Rule_BaseRespawn001 = CreateObject(Rule_BaseRespawn); - Rule_BaseRespawn001->SetInventoryTransfer(true); - Rule_BaseRespawn001->SetFreeCrew(true); - CreateObject(Rule_TeamAccount); CreateObject(Rule_NoPowerNeed); - CreateObject(Rule_Restart); - var LargeCaveMushroom001 = CreateObjectAbove(LargeCaveMushroom, 1308, 1038); LargeCaveMushroom001->SetClrModulation(0xffe4effc); var LargeCaveMushroom002 = CreateObjectAbove(LargeCaveMushroom, 1345, 1028); diff --git a/planet/Missions.ocf/TreasureHunt.ocs/Scenario.txt b/planet/Missions.ocf/TreasureHunt.ocs/Scenario.txt index f2a8c24fb..29e6b2ac6 100644 --- a/planet/Missions.ocf/TreasureHunt.ocs/Scenario.txt +++ b/planet/Missions.ocf/TreasureHunt.ocs/Scenario.txt @@ -10,7 +10,7 @@ MissionAccess=S2Sea Definition2=Decoration.ocd [Game] -Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1;Rule_BaseRespawn=1; +Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1; [Player1] Knowledge=ToolsWorkshop=1;Foundry=1;Flagpole=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;Sword=1;Metal=1;Balloon=1;Boompack=1;GrappleBow=1;JarOfWinds=1;Pipe=1;Pump=1;PowderKeg=1;Ropeladder=1;Bow=1;Arrow=1;Club=1;IronBomb=1;Javelin=1;Shield=1;Catapult=1;WallKit=1;WoodenBridge=1;Basement=1; diff --git a/planet/Missions.ocf/TreasureHunt.ocs/Script.c b/planet/Missions.ocf/TreasureHunt.ocs/Script.c index e40f33a98..4200425ba 100644 --- a/planet/Missions.ocf/TreasureHunt.ocs/Script.c +++ b/planet/Missions.ocf/TreasureHunt.ocs/Script.c @@ -15,6 +15,12 @@ static npc_pyrit; func DoInit(int first_player) { + GetRelaunchRule() + ->SetBaseRespawn(true) + ->SetLastClonkRespawn(true) + ->SetInventoryTransfer(true) + ->SetFreeCrew(true) + ->EnablePlayerRestart(); ClearFreeRect(530,1135, 50,2); if (g_last_stone_door) g_last_stone_door->DoDamage(170 - g_last_stone_door->GetDamage()); if (g_golden_idol) From 69e4826a6f60125b4016d3093d5569630a686299 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 19:44:38 +0200 Subject: [PATCH 33/93] Rule_Relaunch: Modify DefaultRelaunchCount setting --- planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index c96b4094d..42324ddd5 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -15,7 +15,7 @@ local respawn_at_base = false; //Determines whether only the last clonk gets respawned local RespawnLastClonk = false; -local DefaultRelaunchCount = 5; +local DefaultRelaunchCount = nil; local aRelaunches = []; local ClonkType = Clonk; @@ -44,6 +44,7 @@ public func Activate(int plr) protected func Initialize() { ScheduleCall(this, this.CheckDescription, 1, 1); + if(GetScenarioVal("Mode", "Game") == "Melee") DefaultRelaunchCount = 5; return true; } From 07005618aad9e2438235c4cc0868cd1e70caad8d Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 19:45:28 +0200 Subject: [PATCH 34/93] Modify IAmRich in order to work with Rule_Relaunch --- planet/Arena.ocf/IAmRich.ocs/Script.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/planet/Arena.ocf/IAmRich.ocs/Script.c b/planet/Arena.ocf/IAmRich.ocs/Script.c index 53c1d77e5..4166ec320 100644 --- a/planet/Arena.ocf/IAmRich.ocs/Script.c +++ b/planet/Arena.ocf/IAmRich.ocs/Script.c @@ -47,7 +47,9 @@ func Initialize() g_goal = CreateObject(Goal_BeRich); CreateObject(Rule_BuyAtFlagpole); - CreateObject(Rule_BaseRespawn); + GetRelaunchRule() + ->SetBaseRespawn(true) + ->SetLastClonkRespawn(true); CreateObject(Rule_KillLogs); CreateObject(Rule_TeamAccount); From 065655076ecde0e291101b08b70cdc285a5a35a7 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 19:53:41 +0200 Subject: [PATCH 35/93] Modify Tutorials.ocf in order to work with Rule_Relaunch --- planet/Tutorials.ocf/Tutorial01.ocs/Script.c | 2 +- planet/Tutorials.ocf/Tutorial02.ocs/Script.c | 2 +- planet/Tutorials.ocf/Tutorial03.ocs/Script.c | 2 +- planet/Tutorials.ocf/Tutorial04.ocs/Script.c | 2 +- planet/Tutorials.ocf/Tutorial05.ocs/Script.c | 2 +- planet/Tutorials.ocf/Tutorial06.ocs/Script.c | 2 +- planet/Tutorials.ocf/Tutorial07.ocs/Script.c | 2 +- planet/Tutorials.ocf/Tutorial08.ocs/Script.c | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/planet/Tutorials.ocf/Tutorial01.ocs/Script.c b/planet/Tutorials.ocf/Tutorial01.ocs/Script.c index 1480bf4b5..c4f019020 100644 --- a/planet/Tutorials.ocf/Tutorial01.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial01.ocs/Script.c @@ -513,7 +513,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar var plr = target->GetOwner(); var clonk = CreateObject(Clonk, 0, 0, plr); clonk->GrabObjectInfo(target); - Rule_BaseRespawn->TransferInventory(target, clonk); + Rule_Relaunch->TransferInventory(target, clonk); SetCursor(plr, clonk); clonk->DoEnergy(100000); restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore"); diff --git a/planet/Tutorials.ocf/Tutorial02.ocs/Script.c b/planet/Tutorials.ocf/Tutorial02.ocs/Script.c index ea8456ee3..154b1a1a1 100644 --- a/planet/Tutorials.ocf/Tutorial02.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial02.ocs/Script.c @@ -485,7 +485,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar var plr = target->GetOwner(); var clonk = CreateObject(Clonk, 0, 0, plr); clonk->GrabObjectInfo(target); - Rule_BaseRespawn->TransferInventory(target, clonk); + Rule_Relaunch->TransferInventory(target, clonk); SetCursor(plr, clonk); clonk->DoEnergy(100000); restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore"); diff --git a/planet/Tutorials.ocf/Tutorial03.ocs/Script.c b/planet/Tutorials.ocf/Tutorial03.ocs/Script.c index 7dd60ff0f..a3e47629d 100644 --- a/planet/Tutorials.ocf/Tutorial03.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial03.ocs/Script.c @@ -637,7 +637,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar var plr = target->GetOwner(); var clonk = CreateObject(Clonk, 0, 0, plr); clonk->GrabObjectInfo(target); - Rule_BaseRespawn->TransferInventory(target, clonk); + Rule_Relaunch->TransferInventory(target, clonk); SetCursor(plr, clonk); clonk->DoEnergy(100000); restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore"); diff --git a/planet/Tutorials.ocf/Tutorial04.ocs/Script.c b/planet/Tutorials.ocf/Tutorial04.ocs/Script.c index 1edf55b71..93d271058 100644 --- a/planet/Tutorials.ocf/Tutorial04.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial04.ocs/Script.c @@ -535,7 +535,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar var plr = target->GetOwner(); var clonk = CreateObject(Clonk, 0, 0, plr); clonk->GrabObjectInfo(target); - Rule_BaseRespawn->TransferInventory(target, clonk); + Rule_Relaunch->TransferInventory(target, clonk); SetCursor(plr, clonk); clonk->DoEnergy(100000); restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore"); diff --git a/planet/Tutorials.ocf/Tutorial05.ocs/Script.c b/planet/Tutorials.ocf/Tutorial05.ocs/Script.c index 272a66720..6f6b73e01 100644 --- a/planet/Tutorials.ocf/Tutorial05.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial05.ocs/Script.c @@ -376,7 +376,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar var plr = target->GetOwner(); var clonk = CreateObject(Clonk, 0, 0, plr); clonk->GrabObjectInfo(target); - Rule_BaseRespawn->TransferInventory(target, clonk); + Rule_Relaunch->TransferInventory(target, clonk); SetCursor(plr, clonk); clonk->DoEnergy(100000); restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore"); diff --git a/planet/Tutorials.ocf/Tutorial06.ocs/Script.c b/planet/Tutorials.ocf/Tutorial06.ocs/Script.c index 33af0889f..679c07bfd 100644 --- a/planet/Tutorials.ocf/Tutorial06.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial06.ocs/Script.c @@ -414,7 +414,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar var plr = target->GetOwner(); var clonk = CreateObject(Clonk, 0, 0, plr); clonk->GrabObjectInfo(target); - Rule_BaseRespawn->TransferInventory(target, clonk); + Rule_Relaunch->TransferInventory(target, clonk); SetCursor(plr, clonk); clonk->DoEnergy(100000); restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore"); diff --git a/planet/Tutorials.ocf/Tutorial07.ocs/Script.c b/planet/Tutorials.ocf/Tutorial07.ocs/Script.c index 6356aac25..b9e53a1e7 100644 --- a/planet/Tutorials.ocf/Tutorial07.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial07.ocs/Script.c @@ -368,7 +368,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar var plr = target->GetOwner(); var clonk = CreateObject(Clonk, 0, 0, plr); clonk->GrabObjectInfo(target); - Rule_BaseRespawn->TransferInventory(target, clonk); + Rule_Relaunch->TransferInventory(target, clonk); SetCursor(plr, clonk); clonk->DoEnergy(100000); // Add an interaction to call the airship. diff --git a/planet/Tutorials.ocf/Tutorial08.ocs/Script.c b/planet/Tutorials.ocf/Tutorial08.ocs/Script.c index 143f0332d..468dea52d 100644 --- a/planet/Tutorials.ocf/Tutorial08.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial08.ocs/Script.c @@ -477,7 +477,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar var plr = target->GetOwner(); var clonk = CreateObject(Clonk, 0, 0, plr); clonk->GrabObjectInfo(target); - Rule_BaseRespawn->TransferInventory(target, clonk); + Rule_Relaunch->TransferInventory(target, clonk); SetCursor(plr, clonk); clonk->DoEnergy(100000); restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore"); From 00cc450331b8d2f70b69462ace0d1a1a4473328d Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 19:54:05 +0200 Subject: [PATCH 36/93] Goal_Parkour: Fix searching Rule_Restart --- planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c index 1d25315eb..c8cae2b69 100644 --- a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c @@ -56,8 +56,7 @@ protected func Initialize(...) private func EnsureRestartRule() { - if (!ObjectCount(Find_ID(Rule_Restart))) - CreateObject(Rule_Restart, Min(64, LandscapeWidth()-GetX()-32), 0, NO_OWNER); + GetRelaunchRule()->EnablePlayerRestart(); return true; } @@ -440,7 +439,7 @@ protected func OnClonkDeath(object clonk, int killed_by) JoinPlayer(plr); // Transfer contents if active. if (transfer_contents) - Rule_BaseRespawn->TransferInventory(clonk, new_clonk); + GetRelaunchRule()->TransferInventory(clonk, new_clonk); // Scenario script callback. GameCall("OnPlayerRespawn", plr, FindRespawnCP(plr)); // Log message. From d429e88dd21f3722a60b5489513a1b41cbf940af Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 20:50:13 +0200 Subject: [PATCH 37/93] Remove Rule_Restart from Arena.ocf (is replaced by Rule_Relaunch) --- planet/Arena.ocf/Hideout.ocs/Script.c | 4 +++- planet/Arena.ocf/MeltingCastle.ocs/Objects.c | 3 +-- planet/Arena.ocf/MeltingCastle.ocs/Script.c | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/planet/Arena.ocf/Hideout.ocs/Script.c b/planet/Arena.ocf/Hideout.ocs/Script.c index 714d1a2b8..16aa318be 100644 --- a/planet/Arena.ocf/Hideout.ocs/Script.c +++ b/planet/Arena.ocf/Hideout.ocs/Script.c @@ -18,7 +18,9 @@ protected func Initialize() goal->SetFlagBase(2, LandscapeWidth() - 120, 502); // Rules - CreateObject(Rule_Restart); + GetRelaunchRule() + ->SetDefaultRelaunchCount(nil) + ->EnablePlayerRestart(); CreateObject(Rule_ObjectFade)->DoFadeTime(5 * 36); CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); diff --git a/planet/Arena.ocf/MeltingCastle.ocs/Objects.c b/planet/Arena.ocf/MeltingCastle.ocs/Objects.c index bdcb83dcc..f991c5022 100644 --- a/planet/Arena.ocf/MeltingCastle.ocs/Objects.c +++ b/planet/Arena.ocf/MeltingCastle.ocs/Objects.c @@ -4,8 +4,7 @@ func InitializeObjects() { CreateObject(Rule_KillLogs, 50, 50); CreateObject(Rule_Gravestones, 50, 50); - CreateObject(Rule_Restart, 50, 50); - + CreateObject(Goal_Melee, 50, 50); ItemSpawn->Create(Firestone,407,389); diff --git a/planet/Arena.ocf/MeltingCastle.ocs/Script.c b/planet/Arena.ocf/MeltingCastle.ocs/Script.c index be965bea7..0f75fb838 100644 --- a/planet/Arena.ocf/MeltingCastle.ocs/Script.c +++ b/planet/Arena.ocf/MeltingCastle.ocs/Script.c @@ -10,6 +10,7 @@ func Initialize() GetRelaunchRule()->SetRelaunchCount(nil); GetRelaunchRule()->SetRespawnDelay(8); GetRelaunchRule()->SetLastWeaponUse(false); + GetRelaunchRule()->EnablePlayerRestart(); // Mirror map objects by moving them to the other side, then re-running object initialization for (var o in FindObjects(Find_NoContainer(), Find_Not(Find_Category(C4D_Goal | C4D_Rule)))) { From 6405e50c805fe5304695812441017bedf0192133 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 20:50:33 +0200 Subject: [PATCH 38/93] Remove Rule_Restart from Defense.ocf --- planet/Defense.ocf/FightForGidl.ocs/Script.c | 2 +- planet/Defense.ocf/KingOfTheHill.ocs/Script.c | 2 +- planet/Defense.ocf/Windmill.ocs/Script.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/planet/Defense.ocf/FightForGidl.ocs/Script.c b/planet/Defense.ocf/FightForGidl.ocs/Script.c index 541c000a0..4f92b5df7 100644 --- a/planet/Defense.ocf/FightForGidl.ocs/Script.c +++ b/planet/Defense.ocf/FightForGidl.ocs/Script.c @@ -46,7 +46,7 @@ func InitializePlayer(int plr, int iX, int iY, object pBase, int iTeam) { g_relaunchs = []; g_scores = []; - Scoreboard->Init([{key = "relaunchs", title = Rule_Restart, sorted = true, desc = true, default = "", priority = 75}, + Scoreboard->Init([{key = "relaunchs", title = Rule_Relaunch, sorted = true, desc = true, default = "", priority = 75}, {key = "score", title = Nugget, sorted = true, desc = true, default = "0", priority = 100}]); } for (var stonedoor in FindObjects(Find_ID(StoneDoor), Find_Owner(NO_OWNER))) stonedoor->SetOwner(plr); diff --git a/planet/Defense.ocf/KingOfTheHill.ocs/Script.c b/planet/Defense.ocf/KingOfTheHill.ocs/Script.c index d7b8b75dd..584af9829 100644 --- a/planet/Defense.ocf/KingOfTheHill.ocs/Script.c +++ b/planet/Defense.ocf/KingOfTheHill.ocs/Script.c @@ -15,7 +15,7 @@ protected func Initialize() // Rules. CreateObject(Rule_BuyAtFlagpole); - CreateObject(Rule_BaseRespawn); + GetRelaunchRule()->SetBaseRespawn(true); CreateObject(Rule_TeamAccount); CreateObject(Rule_NoFriendlyFire); CreateObject(Rule_Gravestones)->SetFadeOut(3 * 36); diff --git a/planet/Defense.ocf/Windmill.ocs/Script.c b/planet/Defense.ocf/Windmill.ocs/Script.c index 5a27a9120..3cf88366e 100644 --- a/planet/Defense.ocf/Windmill.ocs/Script.c +++ b/planet/Defense.ocf/Windmill.ocs/Script.c @@ -45,7 +45,7 @@ func InitializePlayer(int plr, int iX, int iY, object pBase, int iTeam) { g_relaunchs = []; g_scores = []; - Scoreboard->Init([{key = "relaunchs", title = Rule_Restart, sorted = true, desc = true, default = "", priority = 75}, + Scoreboard->Init([{key = "relaunchs", title = Rule_Relaunch, sorted = true, desc = true, default = "", priority = 75}, {key = "score", title = Nugget, sorted = true, desc = true, default = "0", priority = 100}]); } g_relaunchs[plr] = MAX_RELAUNCH; From 22bf8ad1f79975e1250286afed6c42bc90f30de4 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 20:50:50 +0200 Subject: [PATCH 39/93] Remove Rule_Restart from Goal_Parkour --- planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c index c8cae2b69..cbd353a70 100644 --- a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c @@ -497,10 +497,7 @@ public func SaveScenarioObject(props) { if (!inherited(props, ...)) return false; - // Force dependency on restart rule. - var restart_rule = FindObject(Find_ID(Rule_Restart)); - if (restart_rule) - restart_rule->MakeScenarioSaveName(); + props->AddCall("Goal", this, "EnsureRestartRule"); if (no_respawn_handling) props->AddCall("Goal", this, "DisableRespawnHandling"); if (transfer_contents) From 25f77fd12c5bde97d41e96c3c13442a6639ace2b Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 20:51:10 +0200 Subject: [PATCH 40/93] Remove Rule_Restart from Parkour.ocf --- planet/Parkour.ocf/Aerobatics.ocs/Script.c | 7 +++---- planet/Parkour.ocf/Boomshire.ocs/Objects.c | 1 - planet/Parkour.ocf/Boomshire.ocs/Script.c | 2 ++ planet/Parkour.ocf/VolcanoEscape.ocs/Script.c | 1 - planet/Parkour.ocf/VolcanoEscapeEx.ocs/Script.c | 1 - 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/planet/Parkour.ocf/Aerobatics.ocs/Script.c b/planet/Parkour.ocf/Aerobatics.ocs/Script.c index b0ea3255e..525f52746 100644 --- a/planet/Parkour.ocf/Aerobatics.ocs/Script.c +++ b/planet/Parkour.ocf/Aerobatics.ocs/Script.c @@ -45,10 +45,9 @@ protected func Initialize() // Rules: no power and restart with keeping inventory. CreateObject(Rule_NoPowerNeed); - var restart = FindObject(Find_ID(Rule_Restart)); - if (!restart) - restart = CreateObject(Rule_Restart); - restart->SetRemoveContents(false); + GetRelaunchRule() + ->EnablePlayerRestart() + ->SetInventoryTransfer(true); // Initialize parts of the scenario. var amount = BoundBy(SCENPAR_NrCheckPoints, 6, 20); diff --git a/planet/Parkour.ocf/Boomshire.ocs/Objects.c b/planet/Parkour.ocf/Boomshire.ocs/Objects.c index a3b9f7927..6c40114a5 100644 --- a/planet/Parkour.ocf/Boomshire.ocs/Objects.c +++ b/planet/Parkour.ocf/Boomshire.ocs/Objects.c @@ -503,7 +503,6 @@ func InitializeObjects() var Torch018 = CreateObjectAbove(Torch, 1005, 1164); Torch018->AttachToWall(true); - var Rule_Restart001 = CreateObject(Rule_Restart); g_goal = CreateObject(Goal_Parkour); diff --git a/planet/Parkour.ocf/Boomshire.ocs/Script.c b/planet/Parkour.ocf/Boomshire.ocs/Script.c index 2b3319d79..52710b397 100644 --- a/planet/Parkour.ocf/Boomshire.ocs/Script.c +++ b/planet/Parkour.ocf/Boomshire.ocs/Script.c @@ -2,6 +2,8 @@ private func Initialize() { + GetRelaunchRule() + ->EnablePlayerRestart(); // Create dynamite below the first lava basin DrawMaterialQuad("Tunnel",1378,1327-5,1860,1327-5,1860,1330,1387,1330,1); diff --git a/planet/Parkour.ocf/VolcanoEscape.ocs/Script.c b/planet/Parkour.ocf/VolcanoEscape.ocs/Script.c index c45da9005..88b46d067 100644 --- a/planet/Parkour.ocf/VolcanoEscape.ocs/Script.c +++ b/planet/Parkour.ocf/VolcanoEscape.ocs/Script.c @@ -62,7 +62,6 @@ protected func Initialize() // Create Disasters. //Earthquake->SetChance(2); - this is so random...not fair without relaunches - ScheduleCall(nil, Global.RemoveAll, 3, nil, Find_ID(Rule_Restart)); return; } diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Script.c b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Script.c index c8e7aa39e..069188485 100644 --- a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Script.c +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Script.c @@ -42,7 +42,6 @@ protected func Initialize() }; CreateEffect(fx_volcano, 1, 40); - ScheduleCall(nil, Global.RemoveAll, 3, nil, Find_ID(Rule_Restart)); // Bottom is open, so put some stable lava here to prevent remaining lava from just flowing out of the map DrawMaterialQuad("StableLava",0,h0,w,h0,w,h,0,h); return; From 5cc3cf002a669ee7d9b43ed2a82ccbae6776330e Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 30 Mar 2017 20:51:22 +0200 Subject: [PATCH 41/93] Fix Test.ocf/ColorfulLights.ocs --- planet/Tests.ocf/ColorfulLights.ocs/Objects.c | 4 ---- planet/Tests.ocf/ColorfulLights.ocs/Script.c | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Objects.c b/planet/Tests.ocf/ColorfulLights.ocs/Objects.c index d26510d8a..5ff5386e9 100644 --- a/planet/Tests.ocf/ColorfulLights.ocs/Objects.c +++ b/planet/Tests.ocf/ColorfulLights.ocs/Objects.c @@ -11,10 +11,6 @@ func InitializeObjects() var Grass003 = CreateObjectAbove(Grass, 228, 1180); Grass003->SetClrModulation(0xffa08060); - var Rule_BaseRespawn001 = CreateObject(Rule_BaseRespawn); - Rule_BaseRespawn001->SetInventoryTransfer(true); - Rule_BaseRespawn001->SetFreeCrew(true); - var Tree_Coniferous_Burned001 = CreateObject(Tree_Coniferous_Burned, 17, 1097); Tree_Coniferous_Burned001->SetR(10); var Tree_Coniferous_Burned002 = CreateObject(Tree_Coniferous_Burned, 43, 1246); diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Script.c b/planet/Tests.ocf/ColorfulLights.ocs/Script.c index e30f18265..3a4a347f5 100644 --- a/planet/Tests.ocf/ColorfulLights.ocs/Script.c +++ b/planet/Tests.ocf/ColorfulLights.ocs/Script.c @@ -28,6 +28,11 @@ func DoInit(int first_player) enemy->DoEnergy(10000); enemy->AddEnergyBar(); } + + GetRelaunchRule() + ->SetBaseRespawn(true) + ->SetInventoryTransfer(true) + ->SetFreeCrew(true); return true; } From b0a45e01ac248796d95f3bd135982172df781f85 Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Sat, 1 Apr 2017 12:14:11 +0200 Subject: [PATCH 42/93] Install c4groups even with HEADLESS_ONLY --- CMakeLists.txt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 225df50e4..cf7a2d55b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1509,12 +1509,16 @@ foreach(group ${OC_C4GROUPS}) endif() endforeach() +if(NOT APPLE) + # group files (game data) + add_custom_target(groups DEPENDS ${OC_C4GROUPS}) + set_property(TARGET groups PROPERTY FOLDER "Setup") + add_dependencies(data groups) + # Install binaries + install(TARGETS c4group DESTINATION bin) +endif() if(NOT HEADLESS_ONLY) if(NOT APPLE) - add_custom_target(groups DEPENDS ${OC_C4GROUPS}) - set_property(TARGET groups PROPERTY FOLDER "Setup") - add_dependencies(data groups) - # Install new files install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/openclonk.desktop DESTINATION share/applications) # Update the MIME cache -- this makes the clonk:// protocol handler actually work @@ -1525,7 +1529,6 @@ if(NOT HEADLESS_ONLY) # Install binaries install(TARGETS openclonk DESTINATION games) - install(TARGETS c4group DESTINATION bin) else() install(TARGETS openclonk BUNDLE DESTINATION . From f03a1d618da445b88b6c85fef4eb184025010b8d Mon Sep 17 00:00:00 2001 From: Lukas Werling Date: Sat, 1 Apr 2017 20:10:44 +0200 Subject: [PATCH 43/93] Use average texture color for BMP palette Previously, it would just use first pixel of the texture image. With our current textures, this is a pretty bad approximation. For example, firestone ends up yellow rather than red. Additionally, this helps tools like mape/ocmapgen which do not load any texture graphics but just set the texture's average color. This also fixes the sky color which was previously overwritten. --- src/landscape/C4Texture.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/landscape/C4Texture.cpp b/src/landscape/C4Texture.cpp index 66eb58f80..fca567b1c 100644 --- a/src/landscape/C4Texture.cpp +++ b/src/landscape/C4Texture.cpp @@ -551,10 +551,15 @@ void C4TextureMap::StoreMapPalette(CStdPalette *Palette, C4MaterialMap &rMateria bool fSet[C4M_MaxTexIndex]; ZeroMem(&fSet, sizeof (fSet)); int32_t i; - for (i = 0; i < C4M_MaxTexIndex; i++) + for (i = 1; i < C4M_MaxTexIndex; i++) { // Find material - DWORD dwPix = Entry[i].GetPattern().PatternClr(0, 0); + DWORD dwPix; + auto texture = GetTexture(Entry[i].GetTextureName()); + if (texture) + dwPix = texture->GetAverageColor(); + else + dwPix = Entry[i].GetPattern().PatternClr(0, 0); Palette->Colors[i] = dwPix; fSet[i] = true; } From 97bdddba24de5e128e1f10c308f7247ef4b9ad59 Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Sun, 2 Apr 2017 18:22:03 +0200 Subject: [PATCH 44/93] Fix strict aliasing violation, make C4Real pass is_pod --- src/lib/C4Real.h | 4 ++-- src/lib/StdAdaptors.h | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/lib/C4Real.h b/src/lib/C4Real.h index 116dc5fb9..720e599e7 100644 --- a/src/lib/C4Real.h +++ b/src/lib/C4Real.h @@ -74,8 +74,8 @@ public: public: // constructors - inline C4Fixed () { } - inline C4Fixed (const C4Fixed &rCpy): val(rCpy.val) { } + inline C4Fixed () = default; + inline C4Fixed (const C4Fixed &) = default; // Conversion must be done by the conversion routines itofix, fixtoi, ftofix and fixtof // in order to be backward compatible, so everything is private. diff --git a/src/lib/StdAdaptors.h b/src/lib/StdAdaptors.h index e3753c7fa..2d3e6adee 100644 --- a/src/lib/StdAdaptors.h +++ b/src/lib/StdAdaptors.h @@ -240,10 +240,13 @@ struct StdCastAdapt inline void CompileFunc(StdCompiler *pComp) const { // Cast - assert(sizeof(to_t) == sizeof(T)); - to_t vVal = *reinterpret_cast(&rValue); + static_assert(sizeof(to_t) == sizeof(T), "CastAdapt sanity: sizes match"); + static_assert(std::is_pod::value, "CastAdapt sanity: to-type is POD"); + static_assert(std::is_pod::value, "CastAdapt sanity: from-type is POD"); + to_t vVal; + std::memcpy(&vVal, &rValue, sizeof(to_t)); pComp->Value(vVal); - rValue = *reinterpret_cast(&vVal); + std::memcpy(&rValue, &vVal, sizeof(T)); } // Operators for default checking/setting template inline bool operator == (const D &nValue) const { return rValue == nValue; } From 5719524241d2917103cf9544fbfbeef3fac84118 Mon Sep 17 00:00:00 2001 From: Lukas Werling Date: Sun, 2 Apr 2017 00:00:06 +0200 Subject: [PATCH 45/93] Move C4AchievementGraphics to its own file Scenario parameters are useful in a script-only context (such as the one mape uses). C4AchievementGraphics introduces a dependency on C4Surface which isn't available in that context. --- CMakeLists.txt | 2 + src/graphics/C4GraphicsResource.h | 2 +- src/gui/C4StartupScenSelDlg.h | 1 + src/player/C4Achievement.cpp | 72 +++++++++++++++++++++++++++++ src/player/C4Achievement.h | 36 +++++++++++++++ src/player/C4ScenarioParameters.cpp | 57 ----------------------- src/player/C4ScenarioParameters.h | 17 ------- 7 files changed, 112 insertions(+), 75 deletions(-) create mode 100644 src/player/C4Achievement.cpp create mode 100644 src/player/C4Achievement.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cf7a2d55b..c6df5b15b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -721,6 +721,8 @@ set(OC_CLONK_SOURCES src/platform/PlatformAbstraction.cpp src/platform/PlatformAbstraction.h src/platform/StdSync.h + src/player/C4Achievement.cpp + src/player/C4Achievement.h src/player/C4Player.cpp src/player/C4Player.h src/player/C4PlayerList.cpp diff --git a/src/graphics/C4GraphicsResource.h b/src/graphics/C4GraphicsResource.h index 8ce827522..01a036579 100644 --- a/src/graphics/C4GraphicsResource.h +++ b/src/graphics/C4GraphicsResource.h @@ -24,7 +24,7 @@ #include "graphics/C4Surface.h" #include "graphics/C4FacetEx.h" #include "gui/C4Gui.h" -#include "player/C4ScenarioParameters.h" +#include "player/C4Achievement.h" class C4GraphicsResource { diff --git a/src/gui/C4StartupScenSelDlg.h b/src/gui/C4StartupScenSelDlg.h index 36b6f6f4f..afe6cf26d 100644 --- a/src/gui/C4StartupScenSelDlg.h +++ b/src/gui/C4StartupScenSelDlg.h @@ -22,6 +22,7 @@ #include "landscape/C4Scenario.h" #include "gui/C4Folder.h" #include "player/C4ScenarioParameters.h" +#include "player/C4Achievement.h" #include #include diff --git a/src/player/C4Achievement.cpp b/src/player/C4Achievement.cpp new file mode 100644 index 000000000..b6a3bbec3 --- /dev/null +++ b/src/player/C4Achievement.cpp @@ -0,0 +1,72 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 2014-2017, The OpenClonk Team and contributors + * + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. + * + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. + * + * To redistribute this file separately, substitute the full license texts + * for the above references. + */ +#include "C4Include.h" +#include "player/C4Achievement.h" +#include "c4group/C4Components.h" +#include "graphics/C4FacetEx.h" + + +/* C4AchievementGraphics */ + +bool C4AchievementGraphics::Init(C4Group &File) +{ + // Load all graphics matching achievement filename and register them to map + char FileName[_MAX_FNAME]; + File.ResetSearch(); + while (File.FindNextEntry(C4CFN_Achievements, FileName)) + { + C4FacetSurface *new_fct = new C4FacetSurface(); + if (!new_fct->Load(File, FileName, C4FCT_Height, C4FCT_Full, false, 0)) + { + delete new_fct; + LogF(LoadResStr("IDS_PRC_NOGFXFILE"), FileName, LoadResStr("IDS_ERR_NOFILE")); + return false; + } + // Register under filename excluding the leading "Achv" part. Delete any existing file with same name. + RemoveExtension(FileName); + int32_t id_offset = SCharPos('*', C4CFN_Achievements); assert(id_offset>=0); + StdCopyStrBuf sFileName(FileName + id_offset); + auto i = Graphics.find(sFileName); + if (i != Graphics.end()) delete i->second; + Graphics[sFileName] = new_fct; + } + // done. success no matter how many files were loaded. + return true; +} + +bool C4AchievementGraphics::Init(C4GroupSet &Files) +{ + int32_t idNewGrp=0; + C4Group *pGrp = Files.FindEntry(C4CFN_Achievements, nullptr, &idNewGrp); + if (!pGrp) return true; // no achievement gfx. That's OK. + if (idNewGrp == idGrp) return true; // no update + idGrp = idNewGrp; + // OK, load from this group + return Init(*pGrp); +} + +void C4AchievementGraphics::Clear() +{ + for (auto i = Graphics.begin(); i != Graphics.end(); ++i) + delete i->second; + Graphics.clear(); + idGrp = 0; +} + +C4FacetSurface *C4AchievementGraphics::FindByName(const char *name) const +{ + auto i = Graphics.find(StdCopyStrBuf(name)); + if (i != Graphics.end()) return i->second; else return nullptr; +} diff --git a/src/player/C4Achievement.h b/src/player/C4Achievement.h new file mode 100644 index 000000000..94b002e09 --- /dev/null +++ b/src/player/C4Achievement.h @@ -0,0 +1,36 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 2014-2017, The OpenClonk Team and contributors + * + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. + * + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. + * + * To redistribute this file separately, substitute the full license texts + * for the above references. + */ + +#ifndef INC_C4Achievement +#define INC_C4Achievement + +// Maps IDs to achievement graphics to be shown beside scenarios (and maybe other things) +class C4AchievementGraphics +{ + std::map Graphics; + int32_t idGrp; // ID of group file from which achievements were loaded + +public: + C4AchievementGraphics() : idGrp(0) {} + + // Init will always load all achievement files from the first group that contains achievements + bool Init(C4Group &File); + bool Init(C4GroupSet &Files); + void Clear(); + + C4FacetSurface *FindByName(const char *name) const; +}; + +#endif // INC_C4Achievement diff --git a/src/player/C4ScenarioParameters.cpp b/src/player/C4ScenarioParameters.cpp index 9480bc40c..839ecfe82 100644 --- a/src/player/C4ScenarioParameters.cpp +++ b/src/player/C4ScenarioParameters.cpp @@ -17,63 +17,6 @@ #include "player/C4ScenarioParameters.h" #include "c4group/C4Components.h" #include "script/C4Aul.h" -#include "graphics/C4FacetEx.h" - - -/* C4AchievementGraphics */ - -bool C4AchievementGraphics::Init(C4Group &File) -{ - // Load all graphics matching achievement filename and register them to map - char FileName[_MAX_FNAME]; - File.ResetSearch(); - while (File.FindNextEntry(C4CFN_Achievements, FileName)) - { - C4FacetSurface *new_fct = new C4FacetSurface(); - if (!new_fct->Load(File, FileName, C4FCT_Height, C4FCT_Full, false, 0)) - { - delete new_fct; - LogF(LoadResStr("IDS_PRC_NOGFXFILE"), FileName, LoadResStr("IDS_ERR_NOFILE")); - return false; - } - // Register under filename excluding the leading "Achv" part. Delete any existing file with same name. - RemoveExtension(FileName); - int32_t id_offset = SCharPos('*', C4CFN_Achievements); assert(id_offset>=0); - StdCopyStrBuf sFileName(FileName + id_offset); - auto i = Graphics.find(sFileName); - if (i != Graphics.end()) delete i->second; - Graphics[sFileName] = new_fct; - } - // done. success no matter how many files were loaded. - return true; -} - -bool C4AchievementGraphics::Init(C4GroupSet &Files) -{ - int32_t idNewGrp=0; - C4Group *pGrp = Files.FindEntry(C4CFN_Achievements, nullptr, &idNewGrp); - if (!pGrp) return true; // no achievement gfx. That's OK. - if (idNewGrp == idGrp) return true; // no update - idGrp = idNewGrp; - // OK, load from this group - return Init(*pGrp); -} - -void C4AchievementGraphics::Clear() -{ - for (auto i = Graphics.begin(); i != Graphics.end(); ++i) - delete i->second; - Graphics.clear(); - idGrp = 0; -} - -C4FacetSurface *C4AchievementGraphics::FindByName(const char *name) const -{ - auto i = Graphics.find(StdCopyStrBuf(name)); - if (i != Graphics.end()) return i->second; else return nullptr; -} - - // *** C4ScenarioParameters diff --git a/src/player/C4ScenarioParameters.h b/src/player/C4ScenarioParameters.h index 0a8ef83e7..c8fa69e49 100644 --- a/src/player/C4ScenarioParameters.h +++ b/src/player/C4ScenarioParameters.h @@ -20,23 +20,6 @@ #ifndef INC_C4ScenarioParameters #define INC_C4ScenarioParameters -// Maps IDs to achievement graphics to be shown beside scenarios (and maybe other things) -class C4AchievementGraphics -{ - std::map Graphics; - int32_t idGrp; // ID of group file from which achievements were loaded - -public: - C4AchievementGraphics() : idGrp(0) {} - - // Init will always load all achievement files from the first group that contains achievements - bool Init(C4Group &File); - bool Init(C4GroupSet &Files); - void Clear(); - - C4FacetSurface *FindByName(const char *name) const; -}; - // Definition for a custom setting for the scenario class C4ScenarioParameterDef { From 06a1ebe255b6ff51392114b16784991e41e0e7ce Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Mon, 10 Apr 2017 17:24:20 +0200 Subject: [PATCH 46/93] Fix RemoveReproductionEffect() in Animal Library. --- planet/Objects.ocd/Libraries.ocd/Animal.ocd/Script.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planet/Objects.ocd/Libraries.ocd/Animal.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Animal.ocd/Script.c index 672b95b7e..0b57d2cf9 100644 --- a/planet/Objects.ocd/Libraries.ocd/Animal.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Animal.ocd/Script.c @@ -27,7 +27,7 @@ private func AddReproductionEffect() private func RemoveReproductionEffect() { - return RemoveEffect("IntReproduction"); + return RemoveEffect("IntReproduction", this); } From 4d33df9dfe47709cac590e96720e3206c9cb3327 Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Sun, 1 Mar 2015 19:43:50 +0100 Subject: [PATCH 47/93] Add tests for StdMeshVector --- tests/CMakeLists.txt | 7 +++ tests/math/StdMeshVectorTest.cpp | 100 +++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 tests/math/StdMeshVectorTest.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f90be3248..0b3ec00c3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -102,6 +102,13 @@ endfunction() if (GTEST_FOUND AND GMOCK_FOUND) enable_testing() + create_test(StdMeshMath + SOURCES + "../src/lib/StdMeshMath.cpp" + "../src/lib/StdMeshMath.h" + "math/StdMeshVectorTest.cpp" + ) + AUX_SOURCE_DIRECTORY("${CMAKE_CURRENT_LIST_DIR}" TESTS_SOURCES) add_executable(tests EXCLUDE_FROM_ALL ${TESTS_SOURCES} ${C4SCRIPT_SOURCES}) set_property(TARGET "tests" PROPERTY FOLDER "Testing") diff --git a/tests/math/StdMeshVectorTest.cpp b/tests/math/StdMeshVectorTest.cpp new file mode 100644 index 000000000..b34fd5c4c --- /dev/null +++ b/tests/math/StdMeshVectorTest.cpp @@ -0,0 +1,100 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 2015, The OpenClonk Team and contributors + * + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. + * + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. + * + * To redistribute this file separately, substitute the full license texts + * for the above references. + */ + +// Tests StdMeshMath classes + +#include +#include + +#include "C4Include.h" +#include "lib/StdMeshMath.h" + +void PrintTo(const StdMeshVector &vec, ::std::ostream *os) +{ + *os << "{ " << vec.x << ", " << vec.y << ", " << vec.z << " }"; +} + +auto VectorEq = [](float x, float y, float z) { + return ::testing::AllOf( + ::testing::Field(&StdMeshVector::x, ::testing::FloatEq(x)), + ::testing::Field(&StdMeshVector::y, ::testing::FloatEq(y)), + ::testing::Field(&StdMeshVector::z, ::testing::FloatEq(z)) + ); +}; + +TEST(StdMeshVector, InitializerTest) +{ + StdMeshVector z = StdMeshVector::Zero(); + EXPECT_THAT(z, VectorEq(0.0f, 0.0f, 0.0f)); + + StdMeshVector id = StdMeshVector::UnitScale(); + EXPECT_THAT(id, VectorEq(1.0f, 1.0f, 1.0f)); + + StdMeshVector xl = StdMeshVector::Translate(4.0f, 29.0f, 15.0f); + EXPECT_THAT(xl, VectorEq(4.0f, 29.0f, 15.0f)); +} + +TEST(StdMeshVector, VecOpVecTest) +{ + const StdMeshVector v1 = StdMeshVector::Translate(1.0f, 3.0f, 7.0f); + const StdMeshVector v2 = StdMeshVector::Translate(2.0f, 4.0f, 8.0f); + + EXPECT_THAT(v1 + v2, VectorEq(3.0f, 7.0f, 15.0f)); + EXPECT_THAT(v2 + v1, VectorEq(3.0f, 7.0f, 15.0f)); + + EXPECT_THAT(v1 * v2, VectorEq(2.0f, 12.0f, 56.0f)); + EXPECT_THAT(v2 * v1, VectorEq(2.0f, 12.0f, 56.0f)); + + EXPECT_THAT(v1 / v2, VectorEq(0.5f, 0.75f, 0.875f)); + EXPECT_THAT(v2 / v1, VectorEq(2.0f, 1.33333333f, 1.14285719f)); +} + +TEST(StdMeshVector, VecOpFloatTest) +{ + const StdMeshVector v1 = StdMeshVector::Translate(1.0f, 3.0f, 7.0f); + const StdMeshVector v2 = StdMeshVector::Translate(2.0f, 4.0f, 8.0f); + + EXPECT_THAT(v1 * 2.0f, VectorEq(2.0f, 6.0f, 14.0f)); + EXPECT_THAT(3.0f * v2, VectorEq(6.0f, 12.0f, 24.0f)); + EXPECT_THAT(v2 * 0.5f, VectorEq(1.0f, 2.0f, 4.0f)); + + EXPECT_THAT(v2 / 2.0f, VectorEq(1.0f, 2.0f, 4.0f)); + EXPECT_THAT(2.0f / v2, VectorEq(1.0f, 0.5f, 0.25f)); + EXPECT_THAT(v1 / v1, VectorEq(1.0f, 1.0f, 1.0f)); + + EXPECT_THAT(v1 * 0.5f, VectorEq(0.5f, 1.5f, 3.5f)); + EXPECT_THAT(0.5f * v1, VectorEq(0.5f, 1.5f, 3.5f)); + + EXPECT_THAT(v2 / 8.0f, VectorEq(0.25f, 0.5f, 1.0f)); + EXPECT_THAT(8.0f / v2, VectorEq(4.0f, 2.0f, 1.0f)); + + StdMeshVector v3 = v2; + v3 *= 2.0f; + EXPECT_THAT(v3, VectorEq(4.0f, 8.0f, 16.0f)); + + StdMeshVector v4 = v2; + v4 += v1; + EXPECT_THAT(v4, VectorEq(3.0f, 7.0f, 15.0f)); + + StdMeshVector c12 = StdMeshVector::Cross(v1, v2); + EXPECT_THAT(c12, VectorEq(-4.0f, 6.0f, -2.0f)); + StdMeshVector c21 = StdMeshVector::Cross(v2, v1); + EXPECT_THAT(c21, VectorEq(4.0f, -6.0f, 2.0f)); + + StdMeshVector c11 = StdMeshVector::Cross(v1, v1); + EXPECT_THAT(c11, VectorEq(0.0f, 0.0f, 0.0f)); + + EXPECT_THAT(-v1, VectorEq(-1.0f, -3.0f, -7.0f)); +} From 1ee3081de21ad57897f159c42f6d01d4cdf3165b Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Mon, 2 Mar 2015 23:18:32 +0100 Subject: [PATCH 48/93] Add tests for StdMeshQuaternion --- tests/CMakeLists.txt | 1 + tests/math/StdMeshQuaternionTest.cpp | 106 +++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 tests/math/StdMeshQuaternionTest.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0b3ec00c3..fa59eea4a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -107,6 +107,7 @@ if (GTEST_FOUND AND GMOCK_FOUND) "../src/lib/StdMeshMath.cpp" "../src/lib/StdMeshMath.h" "math/StdMeshVectorTest.cpp" + "math/StdMeshQuaternionTest.cpp" ) AUX_SOURCE_DIRECTORY("${CMAKE_CURRENT_LIST_DIR}" TESTS_SOURCES) diff --git a/tests/math/StdMeshQuaternionTest.cpp b/tests/math/StdMeshQuaternionTest.cpp new file mode 100644 index 000000000..f01c76bf7 --- /dev/null +++ b/tests/math/StdMeshQuaternionTest.cpp @@ -0,0 +1,106 @@ +/* +* OpenClonk, http://www.openclonk.org +* +* Copyright (c) 2015, The OpenClonk Team and contributors +* +* Distributed under the terms of the ISC license; see accompanying file +* "COPYING" for details. +* +* "Clonk" is a registered trademark of Matthes Bender, used with permission. +* See accompanying file "TRADEMARK" for details. +* +* To redistribute this file separately, substitute the full license texts +* for the above references. +*/ + +// Tests StdMeshQuaternion + +#include +#include + +#include "C4Include.h" +#include "lib/StdMeshMath.h" + +const float pi = 3.14159265359f; + +void PrintTo(const StdMeshQuaternion &quat, ::std::ostream *os) +{ + *os << "{ " << quat.x << ", " << quat.y << ", " << quat.z << ", w=" << quat.w << " }"; +} + +auto QuatEq = [](float w, float x, float y, float z) { + return ::testing::AllOf( + ::testing::Field(&StdMeshQuaternion::w, ::testing::FloatEq(w)), + ::testing::Field(&StdMeshQuaternion::x, ::testing::FloatEq(x)), + ::testing::Field(&StdMeshQuaternion::y, ::testing::FloatEq(y)), + ::testing::Field(&StdMeshQuaternion::z, ::testing::FloatEq(z)) + ); +}; + +TEST(StdMeshQuaternion, InitializerTest) +{ + const StdMeshQuaternion z = StdMeshQuaternion::Zero(); + EXPECT_THAT(z, QuatEq(0.0f, 0.0f, 0.0f, 0.0f)); + + const StdMeshQuaternion aa1 = StdMeshQuaternion::AngleAxis(0.5f, StdMeshVector::Translate(1.0f, 2.0f, 3.0f)); + EXPECT_THAT(aa1, QuatEq(0.968912422f, 0.247403964f, 0.494807929f, 0.742211878f)); + + const StdMeshQuaternion aa2 = StdMeshQuaternion::AngleAxis(pi, StdMeshVector::Translate(1.0f, 2.0f, 3.0f)); + EXPECT_THAT(aa2, QuatEq(-4.371139e-08f, 1.0f, 2.0f, 3.0f)); +} + +TEST(StdMeshQuaternion, MathTest) +{ + const StdMeshQuaternion z = StdMeshQuaternion::Zero(); + EXPECT_FLOAT_EQ(0.0f, z.LenSqr()); + + const StdMeshQuaternion q1{ 1.0f, 1.0f, 1.0f, 1.0f }; + EXPECT_FLOAT_EQ(4.0f, q1.LenSqr()); + + StdMeshQuaternion q2{ 1.0f, 1.0f, 1.0f, 1.0f }; + q2.Normalize(); + EXPECT_THAT(q2, QuatEq(0.5f, 0.5f, 0.5f, 0.5f)); + + StdMeshQuaternion q3 = StdMeshQuaternion::Nlerp(z, q1, 0.5f); + EXPECT_THAT(q3, QuatEq(0.5f, 0.5f, 0.5f, 0.5f)); + + StdMeshQuaternion q4{ 1.0f, 2.0f, 3.0f, 4.0f }; + EXPECT_FLOAT_EQ(30.0f, q4.LenSqr()); + + StdMeshQuaternion q5 = StdMeshQuaternion::Nlerp(z, q4, 0.4f); + EXPECT_FLOAT_EQ(1.0f, q5.LenSqr()); + EXPECT_THAT(q5, QuatEq(0.1825741858f, 0.365148372f, 0.547722558f, 0.730296743f)); + + StdMeshQuaternion q6{ 1.0f, -3.0f, -4.0f, -5.0f }; + StdMeshQuaternion q7 = StdMeshQuaternion::Nlerp(q6, q1, 0.25f); + // lerp: w=1.0, x=-2.0, y=-2.75, z=-3.5, len=4.981214711 + EXPECT_FLOAT_EQ(1.0f, q7.LenSqr()); + EXPECT_THAT(q7, QuatEq(0.0869565234f, -0.434782594f, -0.565217376f, -0.695652187f)); + + // Any quaternion added to ZERO stays the same + EXPECT_THAT(z + q1, QuatEq(1.0f, 1.0f, 1.0f, 1.0f)); + EXPECT_THAT(q4 + z, QuatEq(1.0f, 2.0f, 3.0f, 4.0f)); + + EXPECT_THAT(q4 + q1, QuatEq(2.0f, 3.0f, 4.0f, 5.0f)); + EXPECT_THAT(q6 + q4, QuatEq(2.0f, -1.0f, -1.0f, -1.0f)); + + EXPECT_THAT(q6 - q1, QuatEq(0.0f, -4.0f, -5.0f, -6.0f)); + EXPECT_THAT(q1 - q4, QuatEq(0.0f, -1.0f, -2.0f, -3.0f)); + + EXPECT_THAT(4.0f * q4, QuatEq(4.0f, 8.0f, 12.0f, 16.0f)); + EXPECT_THAT(q4 * 4.0f, QuatEq(4.0f, 8.0f, 12.0f, 16.0f)); + + // Any quaternion multiplied by ZERO becomes ZERO + EXPECT_THAT(z * q1, QuatEq(0.0f, 0.0f, 0.0f, 0.0f)); + EXPECT_THAT(q3 * z, QuatEq(0.0f, 0.0f, 0.0f, 0.0f)); + + // Any quaternion multiplied by IDENTITY stays the same + StdMeshQuaternion id = StdMeshQuaternion{ 1.0f, 0.0f, 0.0f, 0.0f }; + EXPECT_THAT(q6 * id, QuatEq(1.0f, -3.0f, -4.0f, -5.0f)); + EXPECT_THAT(id * q6, QuatEq(1.0f, -3.0f, -4.0f, -5.0f)); + + EXPECT_THAT(q1 * q6, QuatEq(13.0f, -3.0f, -1.0f, -5.0f)); + EXPECT_THAT(q6 * q1, QuatEq(13.0f, -1.0f, -5.0f, -3.0f)); + + EXPECT_THAT(q1 * q2, QuatEq(-1.0f, 1.0f, 1.0f, 1.0f)); +} From b87f8e3f4797203ad1541707ad6445aadae92145 Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Tue, 11 Apr 2017 14:21:25 +0200 Subject: [PATCH 49/93] C4Script: Add ParseInt function ParseInt() will take a string parameter and try to convert it into an integer. If the conversion fails, it returns nil. --- docs/sdk/script/fn/ParseInt.xml | 30 +++++++++++++++++++++++++ src/lib/Standard.cpp | 9 +++++++- src/script/C4Script.cpp | 11 +++++++++ tests/aul/AulPredefinedFunctionTest.cpp | 19 ++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 docs/sdk/script/fn/ParseInt.xml diff --git a/docs/sdk/script/fn/ParseInt.xml b/docs/sdk/script/fn/ParseInt.xml new file mode 100644 index 000000000..094ea17f2 --- /dev/null +++ b/docs/sdk/script/fn/ParseInt.xml @@ -0,0 +1,30 @@ + + + + + + ParseInt + Arithmetics + 8.0 OC + + int + + + string + value + Absolute coordinate you want to convert to a relative coordinate. + + + + Parses a string representing a base 10 number into an integer value. If the string does not entirely consist of a base 10 number, optionally signed, nil is returned. + + + ParseInt("14") + Returns the integer 14. + ParseInt("fourteen") + Returns nil. + + + + diff --git a/src/lib/Standard.cpp b/src/lib/Standard.cpp index 0acdaebcf..ac2357616 100644 --- a/src/lib/Standard.cpp +++ b/src/lib/Standard.cpp @@ -94,8 +94,9 @@ static int ToNumber(char c) //------------------------------- Strings ------------------------------------------------ -int32_t StrToI32(const char *s, int base, const char **scan_end) +int32_t StrToI32(const char *str, int base, const char **scan_end) { + const char *s = str; int sign = 1; int32_t result = 0; if (*s == '-') @@ -107,6 +108,12 @@ int32_t StrToI32(const char *s, int base, const char **scan_end) { s++; } + if (!*s) + { + // Abort if there are no digits to parse + if (scan_end) *scan_end = str; + return 0; + } while (IsNumber(*s,base)) { int value = ToNumber(*s++); diff --git a/src/script/C4Script.cpp b/src/script/C4Script.cpp index 042a9a4d0..26d3dddcd 100644 --- a/src/script/C4Script.cpp +++ b/src/script/C4Script.cpp @@ -617,6 +617,16 @@ static C4Value FnFormat(C4PropList * _this, C4Value * Pars) return C4VString(FnStringFormat(_this, Pars[0].getStr(), &Pars[1], 9)); } +// Parse a string into an integer. Returns nil if the conversion fails. +static Nillable FnParseInt(C4PropList *_this, C4String *str) +{ + const char *cstr = str->GetCStr(); + const char *end = nullptr; + int32_t result = StrToI32(cstr, 10, &end); + if (end == cstr || *end != '\0') return C4Void(); + return result; +} + static long FnAbs(C4PropList * _this, long iVal) { return Abs(iVal); @@ -1142,6 +1152,7 @@ void InitCoreFunctionMap(C4AulScriptEngine *pEngine) for (C4ScriptFnDef *pDef = &C4ScriptFnMap[0]; pDef->Identifier; pDef++) new C4AulDefFunc(p, pDef); #define F(f) ::AddFunc(p, #f, Fn##f) + F(ParseInt); F(Abs); F(Min); F(Max); diff --git a/tests/aul/AulPredefinedFunctionTest.cpp b/tests/aul/AulPredefinedFunctionTest.cpp index e62d84497..190347cee 100644 --- a/tests/aul/AulPredefinedFunctionTest.cpp +++ b/tests/aul/AulPredefinedFunctionTest.cpp @@ -147,6 +147,25 @@ TEST_F(AulPredefFunctionTest, CreateEffect) EXPECT_EQ(C4VInt(3), RunScript("local A = { Construction=func() { this.Magicnumber = 3; } }; func Main() { return CreateEffect(A, 1).Magicnumber; }")); } +TEST_F(AulPredefFunctionTest, ParseInt) +{ + auto ParseInt = [this](const std::string &value) { return RunExpr("ParseInt(\"" + value + "\")"); }; + EXPECT_EQ(C4VInt(0), ParseInt("0")); + EXPECT_EQ(C4VInt(0), ParseInt("-0")); + EXPECT_EQ(C4VInt(0), ParseInt("+0")); + EXPECT_EQ(C4VINT_MIN, ParseInt("-2147483648")); + EXPECT_EQ(C4VINT_MAX, ParseInt("2147483647")); + + EXPECT_EQ(C4VNull, ParseInt("")); + EXPECT_EQ(C4VNull, ParseInt("-")); + EXPECT_EQ(C4VNull, ParseInt("+")); + EXPECT_EQ(C4VNull, ParseInt("--23")); + EXPECT_EQ(C4VNull, ParseInt("-+1234")); + EXPECT_EQ(C4VNull, ParseInt("a")); + EXPECT_EQ(C4VNull, ParseInt("0a")); + EXPECT_EQ(C4VNull, ParseInt("2147483647a")); +} + TEST_F(AulPredefFunctionTest, Trivial) { EXPECT_EQ(C4VInt(100), RunExpr("Sin(900,100,10)")); From be2f079e2c7f18f8cb68b29ed4270695835d1409 Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Tue, 11 Apr 2017 14:27:50 +0200 Subject: [PATCH 50/93] Docs: Move ParseInt into Script/Strings category It's not really Arithmetics. Also change the parameter description to something that isn't a copy/paste error. --- docs/sdk/script/fn/ParseInt.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/sdk/script/fn/ParseInt.xml b/docs/sdk/script/fn/ParseInt.xml index 094ea17f2..958a52bd8 100644 --- a/docs/sdk/script/fn/ParseInt.xml +++ b/docs/sdk/script/fn/ParseInt.xml @@ -5,7 +5,8 @@ ParseInt - Arithmetics + Script + Strings 8.0 OC int @@ -13,7 +14,7 @@ string value - Absolute coordinate you want to convert to a relative coordinate. + string representation of a number to parse From 94608179f379f3d37689809ee4ea7d2c3648e1cc Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Wed, 12 Apr 2017 11:56:18 +0200 Subject: [PATCH 51/93] CMake: Regenerate build when Git index changes --- cmake/GitGetChangesetID.cmake | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cmake/GitGetChangesetID.cmake b/cmake/GitGetChangesetID.cmake index 387802cec..0258e3840 100644 --- a/cmake/GitGetChangesetID.cmake +++ b/cmake/GitGetChangesetID.cmake @@ -28,6 +28,15 @@ function(git_get_changeset_id VAR) OUTPUT_VARIABLE GIT_STATUS ) string(REGEX MATCH "^[MADRC ][MD ]" WORKDIR_DIRTY "${GIT_STATUS}") + execute_process(WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND "${GIT_EXECUTABLE}" "rev-parse" "--git-path" "index" + OUTPUT_VARIABLE GIT_INDEX + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + "${GIT_INDEX}" + ) endif() endif() if (NOT C4REVISION) From bc5df7f35bf2f9e160a4739fbd96da584893cb55 Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Wed, 12 Apr 2017 12:29:14 +0200 Subject: [PATCH 52/93] CMake: Add date of commit to logfile But only if the build is from a clean index. Otherwise, the logfile will contain the date of build. --- .git_archival | 1 + cmake/GitGetChangesetID.cmake | 15 ++++++++++++++- src/C4Version.h.in | 7 +++++++ src/game/C4Application.cpp | 2 +- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.git_archival b/.git_archival index ff4124fe6..68307f4f1 100644 --- a/.git_archival +++ b/.git_archival @@ -1 +1,2 @@ node: $Format:%H$ +date: $Format:%ci$ diff --git a/cmake/GitGetChangesetID.cmake b/cmake/GitGetChangesetID.cmake index 0258e3840..7c8f6c4e9 100644 --- a/cmake/GitGetChangesetID.cmake +++ b/cmake/GitGetChangesetID.cmake @@ -37,6 +37,11 @@ function(git_get_changeset_id VAR) APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${GIT_INDEX}" ) + execute_process(WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND "${GIT_EXECUTABLE}" "show" "--format=%ci" "-s" "HEAD" + OUTPUT_VARIABLE GIT_TIMESTAMP + OUTPUT_STRIP_TRAILING_WHITESPACE + ) endif() endif() if (NOT C4REVISION) @@ -53,9 +58,17 @@ function(git_get_changeset_id VAR) string(SUBSTRING "${C4REVISION}" 6 12 C4REVISION) endif() unset(revlength) + + file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/.git_archival" C4REVISION_TS + LIMIT_COUNT 1 + REGEX "date: .+" + ) + string(SUBSTRING "${C4REVISION_TS}" 6 -1 GIT_TIMESTAMP) endif() if(WORKDIR_DIRTY) - set(C4REVISION "${C4REVISION}+") + set(WORKDIR_DIRTY 1) endif() set(${VAR} "${C4REVISION}" PARENT_SCOPE) + set(${VAR}_DIRTY ${WORKDIR_DIRTY} PARENT_SCOPE) + set(${VAR}_TS "${GIT_TIMESTAMP}" PARENT_SCOPE) endfunction() diff --git a/src/C4Version.h.in b/src/C4Version.h.in index 43ffa9d97..57efb0f5b 100644 --- a/src/C4Version.h.in +++ b/src/C4Version.h.in @@ -32,7 +32,14 @@ #define C4XVER1 @C4XVER1@ #define C4XVER2 @C4XVER2@ +#cmakedefine01 C4REVISION_DIRTY +#if C4REVISION_DIRTY +#define C4REVISION "@C4REVISION@+" +#define C4REVISION_TS __DATE__ " " __TIME__ +#else #define C4REVISION "@C4REVISION@" +#define C4REVISION_TS "@C4REVISION_TS@" +#endif // Build Options #ifdef _DEBUG diff --git a/src/game/C4Application.cpp b/src/game/C4Application.cpp index f32afca2e..69256d1f3 100644 --- a/src/game/C4Application.cpp +++ b/src/game/C4Application.cpp @@ -104,7 +104,7 @@ bool C4Application::DoInit(int argc, char * argv[]) // Engine header message Log(C4ENGINECAPTION); - LogF("Version: %s %s (%s)", C4VERSION, C4_OS, GetRevision()); + LogF("Version: %s %s (%s - %s)", C4VERSION, C4_OS, GetRevision(), C4REVISION_TS); LogF("ExePath: \"%s\"", Config.General.ExePath.getData()); LogF("SystemDataPath: \"%s\"", Config.General.SystemDataPath); LogF("UserDataPath: \"%s\"", Config.General.UserDataPath); From bf43302da2d07a292cd883006e65fc0c974e6c2f Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 13 Apr 2017 09:53:24 +0200 Subject: [PATCH 53/93] Rule_Restart: Fix handling return values of OnPlayerRestart --- planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index 42324ddd5..89452509d 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -30,7 +30,7 @@ public func Activate(int plr) { if(!RestartPlayer) return MessageWindow(this.Description, plr); // Notify scenario. - if (!GameCall("OnPlayerRestart", plr)) + if (GameCall("OnPlayerRestart", plr)) return; // Remove the player's clonk, including contents. var clonk = GetCrew(plr); From 8042861f0b45731409b359f348d66612169fc5bf Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 13 Apr 2017 18:29:44 +0200 Subject: [PATCH 54/93] Rule_Relaunch: Fix several script errors --- .../Rules.ocd/Relaunch.ocd/Script.c | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index 89452509d..8e8d6afac 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -201,10 +201,8 @@ public func RelaunchPlayer(int plr, int killer, object pClonk) private func RespawnAtBase(int iPlr, object pClonk) { - for(var base in GetBases(pClonk)) - { - if(base) return [base->GetX(), base->GetY() + base->GetDefHeight() / 2]; - } + var base = GetRelaunchBase(pClonk); + if(base) return [base->GetX(), base->GetY() + base->GetDefHeight() / 2]; } private func TransferInventory(object from, object to) @@ -226,15 +224,15 @@ private func TransferInventory(object from, object to) return to->GrabContents(from); } -private func GetBases(object clonk) +private func GetRelaunchBase(object clonk) { var plr = clonk->GetOwner(); // Neutral flagpoles are preferred respawn points, because they are used as the only respawn points in missions. - var bases = clonk->FindObjects(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance()); + var base = clonk->FindObject2(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance()); // If there are no neutral flagpoles, find closest base owned by the player (or team) and try to buy a clonk. - if (GetLength(bases) <= 0) - bases = clonk->FindObjects(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance()); - return bases; + if (!base) + base = clonk->FindObject2(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance()); + return base; } public func DoRelaunch(int iPlr, object pClonk, array position, bool fNoCreation) @@ -269,12 +267,14 @@ public func DoRelaunch(int iPlr, object pClonk, array position, bool fNoCreation } else { + var base = GetRelaunchBase(); + if(!base) return; // Try to buy a crew member at the base. var pay_plr = base->GetOwner(); // Payment in neutral bases by clonk owner. if (pay_plr == NO_OWNER) - pay_plr = plr; - clonk = base->~DoBuy(ClonkType, plr, pay_plr, pClonk); + pay_plr = iPlr; + clonk = base->~DoBuy(ClonkType, iPlr, pay_plr, pClonk); if (clonk) { clonk->Exit(); From 9154ebf79f49d5b9f2c40c18cd51c7d726bb24d1 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 13 Apr 2017 18:30:13 +0200 Subject: [PATCH 55/93] CaptureTheFlag: Fix script errors --- planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c index a2d0c52ca..58711d339 100644 --- a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c @@ -77,7 +77,7 @@ private func EliminateOthers(int win_team) protected func InitializePlayer(int plr, int x, int y, object base, int team) { // Join new clonk. - GetRelaunchRule()->DoRelaunch(iPlr, nil, RelaunchPosition(team), true); + GetRelaunchRule()->DoRelaunch(plr, nil, RelaunchPosition(team), true); // make scoreboard entry for team Scoreboard->NewEntry(ScoreboardTeamID(team), GetTaggedTeamName(team)); @@ -86,7 +86,7 @@ protected func InitializePlayer(int plr, int x, int y, object base, int team) public func RelaunchPosition(int iTeam) { - var base = FindObject(Find_ID(Goal_FlagBase), Find_Func("FindTeam", team)); + var base = FindObject(Find_ID(Goal_FlagBase), Find_Func("FindTeam", iTeam)); if (base) return [base->GetX(), base->GetY() - 10]; return nil; } From f1efb134aa2003f83fefd0612403612763f2ed90 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 13 Apr 2017 18:58:10 +0200 Subject: [PATCH 56/93] Remove hungarian notation and fix some errors --- .../Rules.ocd/Relaunch.ocd/Script.c | 144 +++++++++--------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index 8e8d6afac..b546d66de 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -13,22 +13,22 @@ local free_crew = true; //Determines whether the clonk will be respawned at the base local respawn_at_base = false; //Determines whether only the last clonk gets respawned -local RespawnLastClonk = false; +local respawn_last_clonk = false; -local DefaultRelaunchCount = nil; -local aRelaunches = []; +local default_relaunch_count = nil; +local relaunches = []; -local ClonkType = Clonk; +local clonk_type = Clonk; -local DisableLastWeapon = false; -local LastUsedPlayerWeapons = []; -local RelaunchTime = 36 * 10; -local Hold = false; -local RestartPlayer = false; +local disable_last_weapon = false; +local last_used_player_weapons = []; +local relaunch_time = 36 * 10; +local hold = false; +local restart_player = false; public func Activate(int plr) { - if(!RestartPlayer) return MessageWindow(this.Description, plr); + if(!restart_player) return MessageWindow(this.Description, plr); // Notify scenario. if (GameCall("OnPlayerRestart", plr)) return; @@ -44,7 +44,7 @@ public func Activate(int plr) protected func Initialize() { ScheduleCall(this, this.CheckDescription, 1, 1); - if(GetScenarioVal("Mode", "Game") == "Melee") DefaultRelaunchCount = 5; + if(GetScenarioVal("Mode", "Game") == "Melee") default_relaunch_count = 5; return true; } @@ -94,42 +94,42 @@ public func GetFreeCrew() return free_crew; } -public func SetRespawnDelay(int iDelay) +public func SetRespawnDelay(int delay) { - RelaunchTime = iDelay * 36; + relaunch_time = delay * 36; return this; } public func GetRespawnDelay() { - return RelaunchTime / 36; + return relaunch_time / 36; } -public func SetHolding(bool fHold) +public func SetHolding(bool b) { - Hold = fHold; + hold = b; return this; } public func GetHolding() { - return Hold; + return hold; } -public func SetLastWeaponUse(bool fUse) +public func SetLastWeaponUse(bool use) { - this.DisableLastWeapon = !fUse; + this.disable_last_weapon = !use; return this; } public func GetLastWeaponUse() { - return DisableLastWeapon; + return disable_last_weapon; } -public func SetBaseRespawn(bool fSet) +public func SetBaseRespawn(bool set) { - respawn_at_base = fSet; + respawn_at_base = set; return this; } @@ -138,41 +138,41 @@ public func GetBaseRespawn() return respawn_at_base; } -public func SetDefaultRelaunches(int iRelaunches) +public func SetDefaultRelaunches(int r) { - DefaultRelaunchCount = iRelaunches; + default_relaunch_count = r; } public func SetLastClonkRespawn(bool b) { - RespawnLastClonk = b; + respawn_last_clonk = b; return this; } public func EnablePlayerRestart() { - RestartPlayer = true; + restart_player = true; return this; } public func DisablePlayerRestart() { - RestartPlayer = false; + restart_player = false; return this; } public func GetLastClonkRespawn() { - return RespawnLastClonk; + return respawn_last_clonk; } -public func InitializePlayer(int iPlr) +public func InitializePlayer(int plr) { - _inherited(iPlr, ...); + _inherited(plr, ...); // Scenario script callback. - aRelaunches[iPlr] = DefaultRelaunchCount; - GameCallEx("OnPlayerRelaunch", iPlr, false); - return DoRelaunch(iPlr, nil, nil, true); + relaunches[plr] = default_relaunch_count; + GameCallEx("OnPlayerRelaunch", plr, false); + return DoRelaunch(plr, nil, nil, true); } /*public func OnClonkDeath(int plr, object pClonk, int iKiller) @@ -180,14 +180,14 @@ public func InitializePlayer(int iPlr) return RelaunchPlayer(plr, iKiller, pClonk); }*/ -public func RelaunchPlayer(int plr, int killer, object pClonk) +public func RelaunchPlayer(int plr, int killer, object clonk) { - if(plr == nil || plr == NO_OWNER) return Log("NO PlAYER: %d", plr); + if(plr == nil || plr == NO_OWNER) return; - if(DefaultRelaunchCount != nil) + if(default_relaunch_count != nil) { - aRelaunches[plr]--; - if(aRelaunches[plr] < 0) + relaunches[plr]--; + if(relaunches[plr] < 0) { EliminatePlayer(plr); return; @@ -196,12 +196,12 @@ public func RelaunchPlayer(int plr, int killer, object pClonk) GameCall("OnPlayerRelaunch", plr, true); - return DoRelaunch(plr, pClonk, nil); + return DoRelaunch(plr, clonk, nil); } -private func RespawnAtBase(int iPlr, object pClonk) +private func RespawnAtBase(object clonk) { - var base = GetRelaunchBase(pClonk); + var base = GetRelaunchBase(clonk); if(base) return [base->GetX(), base->GetY() + base->GetDefHeight() / 2]; } @@ -235,13 +235,13 @@ private func GetRelaunchBase(object clonk) return base; } -public func DoRelaunch(int iPlr, object pClonk, array position, bool fNoCreation) +public func DoRelaunch(int plr, object clonk, array position, bool no_creation) { - if(!GetPlayerName(iPlr)) return; - if(RespawnLastClonk && GetCrewCount(iPlr) >= 1) return; + if(!GetPlayerName(plr)) return; + if(respawn_last_clonk && GetCrewCount(plr) >= 1) return; - if(respawn_at_base) position = RespawnAtBase(iPlr, pClonk); - position = (position ?? GameCallEx("RelaunchPosition", iPlr, GetPlayerTeam(iPlr))) ?? FindRelaunchPos(iPlr); + if(respawn_at_base) position = RespawnAtBase(clonk); + position = (position ?? GameCallEx("RelaunchPosition", plr, GetPlayerTeam(plr))) ?? FindRelaunchPos(plr); var spawn; @@ -256,14 +256,14 @@ public func DoRelaunch(int iPlr, object pClonk, array position, bool fNoCreation else spawn = position; } - var clonk; - if(!fNoCreation) + var new_clonk; + if(!no_creation) { if(free_crew) { - clonk = CreateObjectAbove(ClonkType, spawn[0], spawn[1],iPlr); - if(!clonk) return; - clonk->MakeCrewMember(iPlr); + new_clonk = CreateObjectAbove(clonk_type, spawn[0], spawn[1],plr); + if(!new_clonk) return; + new_clonk->MakeCrewMember(plr); } else { @@ -273,30 +273,30 @@ public func DoRelaunch(int iPlr, object pClonk, array position, bool fNoCreation var pay_plr = base->GetOwner(); // Payment in neutral bases by clonk owner. if (pay_plr == NO_OWNER) - pay_plr = iPlr; - clonk = base->~DoBuy(ClonkType, iPlr, pay_plr, pClonk); - if (clonk) + pay_plr = plr; + new_clonk = base->~DoBuy(clonk_type, plr, pay_plr, clonk); + if (new_clonk) { - clonk->Exit(); + new_clonk->Exit(); } } } else { - clonk = GetCrew(iPlr); - if(!clonk) return; + new_clonk = GetCrew(plr); + if(!new_clonk) return; } - if (inventory_transfer) TransferInventory(pClonk, clonk); + if (inventory_transfer) TransferInventory(clonk, new_clonk); - clonk->SetPosition(spawn[0], spawn[1], iPlr) + new_clonk->SetPosition(spawn[0], spawn[1], plr); - if(!GetCursor(iPlr) || GetCursor(iPlr) == pClonk) SetCursor(iPlr, clonk); - clonk->DoEnergy(clonk.Energy || 100000); + if(!GetCursor(plr) || GetCursor(plr) == clonk) SetCursor(plr, new_clonk); + new_clonk->DoEnergy(new_clonk.Energy || 100000); - if(RelaunchTime) + if(relaunch_time) { - clonk->CreateObject(RelaunchContainer,nil,nil,iPlr)->StartRelaunch(clonk); + new_clonk->CreateObject(RelaunchContainer,nil,nil,plr)->StartRelaunch(new_clonk); } return true; } @@ -346,27 +346,27 @@ public func SaveScenarioObject(props, ...) global func SetRelaunchCount(int plr, int value) { if(UnlimitedRelaunches()) return; - GetRelaunchRule().aRelaunches[plr] = value; - Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().aRelaunches[plr]); + GetRelaunchRule().relaunches[plr] = value; + Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().relaunches[plr]); return value; } global func GetRelaunchCount(int plr) { - return GetRelaunchRule().aRelaunches[plr]; + return GetRelaunchRule().relaunches[plr]; } global func DoRelaunchCount(int plr, int value) { if(UnlimitedRelaunches()) return; - GetRelaunchRule().aRelaunches[plr] += value; - Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().aRelaunches[plr]); + GetRelaunchRule().relaunches[plr] += value; + Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().relaunches[plr]); return; } global func UnlimitedRelaunches() { - return GetRelaunchRule().DefaultRelaunchCount == nil; + return GetRelaunchRule().default_relaunch_count == nil; } global func GetRelaunchRule() @@ -389,10 +389,10 @@ public func Definition(def) }; def.EditorProps.hold = { - Name = "$Holding$", - EditorHelp = "$HoldingHelp$", + Name = "$holding$", + EditorHelp = "$holdingHelp$", Type = "bool", - Set = "SetHolding" + Set = "Setholding" }; def.EditorProps.respawn_delay = { From 0df79f5ba362dd2e17fa7880a6062e5111d76e69 Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Thu, 13 Apr 2017 19:06:36 +0200 Subject: [PATCH 57/93] Rule_Relaunch: use correct casing for translations --- planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index b546d66de..cfebc8a11 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -389,8 +389,8 @@ public func Definition(def) }; def.EditorProps.hold = { - Name = "$holding$", - EditorHelp = "$holdingHelp$", + Name = "$Holding$", + EditorHelp = "$HoldingHelp$", Type = "bool", Set = "Setholding" }; From 6030299201582b57b8cb0382d1d458434644c79c Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Thu, 13 Apr 2017 18:58:10 +0200 Subject: [PATCH 58/93] ThunderousSkies: Fix wrong relaunch position and wrong default relaunches --- planet/Arena.ocf/ThunderousSkies.ocs/Script.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/planet/Arena.ocf/ThunderousSkies.ocs/Script.c b/planet/Arena.ocf/ThunderousSkies.ocs/Script.c index 72023d5da..968cebaa1 100644 --- a/planet/Arena.ocf/ThunderousSkies.ocs/Script.c +++ b/planet/Arena.ocf/ThunderousSkies.ocs/Script.c @@ -18,7 +18,9 @@ protected func Initialize() AddEffect("BlessTheKing",goal,100,1,nil); CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); - GetRelaunchRule()->SetLastWeaponUse(false); + GetRelaunchRule() + ->SetLastWeaponUse(false) + ->SetDefaultRelaunches(nil); //Enviroment. //SetSkyAdjust(RGBa(250,250,255,128),RGB(200,200,220)); @@ -252,7 +254,7 @@ protected func InitializePlayer(int plr) public func RelaunchPosition() { - return [[180,150],[310,320],[600,290],[650,180],[790,110],[440,190]]; + return [[180,150],[310,300],[600,290],[650,180],[790,110],[440,190]]; } func KillsToRelaunch() { return 0; } From 7c444e7f963a266a452625613e9cd326226d8587 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Mon, 17 Apr 2017 16:05:20 +0200 Subject: [PATCH 59/93] add lava core animal (made by Win) Original by win, overhaul of script and behavior by Maikel. --- .../Animals.ocd/LavaCore.ocd/DefCore.txt | 18 + .../Animals.ocd/LavaCore.ocd/Graphics.mesh | Bin 0 -> 16869 bytes .../Animals.ocd/LavaCore.ocd/LavaCore.png | Bin 0 -> 64421 bytes .../LavaCore.ocd/LavaCoreNormals.png | Bin 0 -> 221097 bytes .../LavaCoreShell.ocd/DefCore.txt | 14 + .../LavaCoreShell.ocd/Graphics.mesh | Bin 0 -> 42247 bytes .../LavaCoreShell.ocd/LavaCoreShell.png | Bin 0 -> 9279 bytes .../LavaCoreShell.ocd/LavaCoreShellStone.png | Bin 0 -> 7107 bytes .../LavaCoreShell.ocd/Scene.material | 54 +++ .../LavaCore.ocd/LavaCoreShell.ocd/Script.c | 54 +++ .../LavaCoreShell.ocd/SolidMask.png | Bin 0 -> 4040 bytes .../LavaCoreShell.ocd/StringTblDE.txt | 2 + .../LavaCoreShell.ocd/StringTblUS.txt | 2 + .../LavaCore.ocd/LavaCoreStone.png | Bin 0 -> 45140 bytes .../Animals.ocd/LavaCore.ocd/Scene.material | 63 +++ .../Animals.ocd/LavaCore.ocd/Script.c | 416 ++++++++++++++++++ .../Animals.ocd/LavaCore.ocd/StringTblDE.txt | 2 + .../Animals.ocd/LavaCore.ocd/StringTblUS.txt | 2 + .../Animals.ocg/LavaCore.ocg/Fossilize.ogg | Bin 0 -> 19364 bytes planet/Sound.ocg/authors.txt | 1 + 20 files changed, 628 insertions(+) create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/DefCore.txt create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/Graphics.mesh create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCore.png create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreNormals.png create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/DefCore.txt create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Graphics.mesh create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/LavaCoreShell.png create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/LavaCoreShellStone.png create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Scene.material create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Script.c create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/SolidMask.png create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/StringTblDE.txt create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/StringTblUS.txt create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreStone.png create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/Scene.material create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/Script.c create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/StringTblDE.txt create mode 100644 planet/Objects.ocd/Animals.ocd/LavaCore.ocd/StringTblUS.txt create mode 100644 planet/Sound.ocg/Animals.ocg/LavaCore.ocg/Fossilize.ogg diff --git a/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/DefCore.txt b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/DefCore.txt new file mode 100644 index 000000000..2a342c704 --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/DefCore.txt @@ -0,0 +1,18 @@ +[DefCore] +id=LavaCore +Version=8,0 +Category=C4D_Living +Height=40 +Width=40 +Offset=-20,-20 +Vertices=9 +VertexX=0,-19,19, 0, 0,-14, 14,-14,14 +VertexY=0, 0, 0,-19,19,-14,-14, 14,14 +VertexFriction=1,50,50,50,50,50,50,50,50 +VertexCNAT=16,1,2,4,8,5,6,9,10 +Mass=80 +StretchGrowth=1 +Oversize=1 +IncompleteActivity=1 +NoBreath=1 +Float=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/Graphics.mesh b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/Graphics.mesh new file mode 100644 index 0000000000000000000000000000000000000000..513f4d7cf4436d824f71e3bafd56b1237aeceed2 GIT binary patch literal 16869 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

>OjfVv@Doh{5x)FD`Td6~ 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 ehn~x6~8<`uN%=)eOetyd`Rvcx1B@u-{J`lw{YN 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 z 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 literal 0 HcmV?d00001 diff --git a/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/LavaCoreShell.png b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/LavaCoreShell.png new file mode 100644 index 0000000000000000000000000000000000000000..3668658024255b7dba1032e86d5a0fb55c558c50 GIT binary patch literal 9279 zcmbVSRZyJ4vi^5jWO26uA;A(LxGWHypdn~TaJS&@u!LYq(BSS6++CIs+}+)6f#7~Q z=k-3^s{1h2Q#0ND&{H%0&DR~O{6Pi>lM)jE03114DOCUfJxxIX2KY&g2EBhM0T8f;(;U8$q{$CR zF8b7mJ6RS1zT#L8^ZM;K9$I5YNkr9=>mG>>Ej8L)vge?m5obeAOk?O7vHe!Jf_U}t zcHQALxaMlnebZ58dqc2=U(@YPqhdT@D&@emOMn}7MmCAt$Y_{ z#ip%Vy^@uc<$-Gc#$L7!uE}!qvZB>rF|=t;FlbAPFDL2co6x+xQpEywtI_58yb`Ct zlfVO)a9`>$-!#KL=q;X1_VTcF_Ps8bSMy@p+3mc})dw@Hwas*{d-x|iM!j``vbuz8 zt^y{PNb#93C+nz8MJb-cC-aZV5pJSAhrU_f>CcYb&l1Mp2rw2Cr#+H&YaQy{VPL9XqGC==S5teWOb}4$Ej^aeRC6EsF?H#(iS{G>}0*-wfrD(&>MUnFP6D%VOPDJl3%G2kbEd&mM$s4P zXYUoZaPT(k8p&y~=#~ieUSO=Wn-U`g%`OoyK*fyTHDn?#`N;}*bFTunnK$zuhm_;zHFy=WC*34n#y;0eDybOWbjii!wUUwan&iXP^iM|_(0<^-+sV>os8rL?lxl{Cx2r~T3`sYP` z{&N~gp zaARNfidxByU^_W`Y(c2EsSi#FwC$Ar0<;2dZPH8BsDRX^WoK^RV)bGAl)=K`;=(

;b1D4De*b=iDppc1 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ßyrQE& z^?WnSJ{YU3_WJjW&BX=O)uo(; z11diCPfmEp3QTaZWsP8C@+A<^(PTV#$g+{{`e}izei2)5f>}mP%F|$(CdIQzXWro@ zngwcEMhKd7V^yBp$Ir%r`kGWnz0S7VEa_p(ePH*G&)K)MI;p4LBuS>#*UvB1!CFm& zjw-8l-|9zvHzcu7N@)@sqJ6o|^iU!TDsRWvTJHC56 zZ-NYcB+wQv>Q(SzjV3Z(SJ)d6kA5?#0QI%&i{}QfK(z&`qV5Vv%djsSMfA)>o)wZe z&Fq)wS?rg;rD8}lXPGrNae~i^8z6n%QChRVeARC5k7_mh<~M0Tut7?OnDqZ$^+VU% zg?2CPHW)})qXEQ>3pko=KaK0K(~@40-l9YKqPEKtLxy@g2E zt#q1t(bPL;`FS|r&8)GM(^=1lVuppd0t=9oXs|Z;WupH)#Zx>YHP__RMN@SpbOL2N z(SBk7oRriwz}PrRzJvX{S3szwNfV=_Z1dIY7ZR8`um`^Rlj6Wa&sY=(}Oi-`bgdld&bjZz(8jR-eD<+e$T9?^t)BbnYHhYJD*1gF@%0Q<4 z8!yL`gDc5bt>TW&<9>$2Me><6Mj&quMco6@#NGuL>LP?caS9AO!y4^eGS2fi0Y&Mh zfPb7W=m`{{^}go5Kgz0Tr1xINZrgaCN=07eT8gORl2yGP#al7y^p;Y>o@{#Q*pIm) z)BgGsyUR%&pfpc>{aaMDU?R!!Ji;qrdOSB|IlaS= z`AGl-I1E{wu@eY2RO1zmtgtd}40xD%t{#u^n736|qtMTTeGO65%VYT)tlwyg7+GPi zjEMB}?qlV4_?cR2|HKcQU|5rrS(ND;v~h^J+^QV*)8 zzdon@U7Y%mQq?iW@+)BG%ZKB#sSiETUb7?_qiqul`nh{)!+Q&>J?5raD8H9tDep^a z!Obj@LXB!1zVAQfdVjxTMPV0||4yefW%NlwdbeSA=ZLZc$Lcr9N}M86ZRwBYPcrLk zl%m^&{z?b0+%D3<@^76dO+iqJ>TtmIKomI_-b(Iaot7Hw&5kZbD^3@BjJ4$KJ9o zj&Gx3I1CT2Vn1;lKbzli+~>ogW#_{J zj6FB{W_~|eUi)b%83xpskXa=tK7EAPUBVRBx)d55GnP3zXhEz(rbglo(foH6u_72# zXJD8L-_l6;{Py<)QA3vL==&nZvfH=%JUsUApqujQ8mhB8NrRd^Y2q zR{1H5{inZlSb5Kt=B|WLvixJ?RB)utqaI2>lZrV}k+~tuwke`^Kc)Sok<|GD)H(Kx zG`QW+VT#Sm7(F}BxqaxuymGH*ZX(g~gHh`r<4t)-zu}R#$w-$Tjc28{!bY4o^pSt( z$8^0uc}8myg1m(}?j3mdpO6jNWjK{AV3|Q3()ej|acSC?Q&OLE&f=IC+^x`+YUC$d zAtp|^MSr1iS#15iFFHXizbDA;ij8Zp6K-oTB7Aem706$jKe{Y?*RF=DQmvk?j9!t= zp4Xw-u2fG?@rR)6s1nS{W@B<8cl|Kwh1wYi;6wsM<=$abopC>}uUp3;FHjc6Y+aKV z*I=U4zUd{SYbZawzc8@m=+Sl0WkK36a1k_H4`Wu-Y6eN3G(Wqe`*H#6 zef#k@{`KC!Si2r}N;z7chDEzHU3eh9IePx@Vh_51uX*noln}w7{r+JqO?1&D3?COe zZ5Alv9bO8Z>1k@ELyR@e!LDU%E8maz*4r=?dX7EWZj(mK0$x`3y^4ai3}-2ep6!mU ztG=}3Fe1+)C_<8W$m7daw3s2f0{f?4fe6&U{!|$lrW(N~^(EeL*Cxv3r%V%WP?_{x zD>JH!8?ze>r`BoYA@i6}N%iy^2va5NsZo|kP-Z%ndpe$A^}J)i~xX6dFe&cHJe^q(E)XexxvZ_#Y+y1QJ0dXe?i;j*y~TjD_M8 z@?3Ie_MVd{{5#qx_um!ZN-p;zpmWaa=LIBWiUd(WH;O~2Q3f!w_{{xjwi~^t*ZK_H z$5JYg@Im?HaTisL^mr7t?iuz5L^bw`=;BlSY2D)lzY>&GgYSL_au-MV@kJV%qSwxV z*#pZ^UkN28pyQ-sO>`gJN)Rnh8VenY$*i7WAbzWpjuNsU@+Z%Jd1iSH_2ePXgN9>v zzX78g;H!$b=Hf0beb5onG-`e@WgZ^4IO9n3_43N!%xl~)!eYKhMbdSADuraup9_U> z=lE%pY*5`-JT4i7(HyLH~P^m>K%n+;PK&*yl;> zGg3H^5NSP-NTG@AH{)9cKF`JMWpI!`CoN8nKQRInE~>dF{u>!#BIIZQ4E0Ha3@QsO zKDE$>iNBN#DfmeREi;kawS(lf;maBWJCMJ7OmYbGwgG!r$Gm+{g<+_zIA%1iZ?)+Q zoyaQiOm2tK@NAz|%3covPA!<@STtyD+r@-)gXN?-U;VbW$Ens)tZ_TcG1tEBODzbg znyD+6X})p$u`uHUPXeHRoVq$AVnyZdNx3mdvmDaWjoDoHh3PG~-ByV1`ne{KR1f4O za}~H&9RIH7A)yZC;>^0APSh=F?vZzHyL{u{BRNuJ;HG$HhmR=iC0vr{bV>2olDSNv za-NsoV-~@614;2iTDN?V`UD|*P++t;<_&dU6eDF9zR?Z7`Y-!YMSC$4nd)?g zauw8eY2Yws*A0pmrliqV=q32uhe?a!Tf{djKu5JahjYMs+DFyxF?)e$D)hyfY3ZeF z%C!HB_IlW%72ER$^4 zQ7W+LXw-mu3`aWJJ+GJ)Dp?t?}?yA zdK9Cig~ZX3ti2bweI`^-eB}K-rHKKy>BINZSq+r~4P*0bYc!T!g>&P{-+xep&>i@x zM7@sU!i#jtw`-n8O?2teyIEdJfMN>guodM!K+dr;=LA!(l<8Qg84ee7`GS%?bvmPuScO+#Yzy+1)&V$#Fu#x+paj)IKLq%dP8W>F&|_n+zTmOkDt z)viSdlvj8QFFM{1=B6}&@%D(!StjfvAR~yodh&C9ln{z6Dw&os50?S2dh_7NJFycT z29_$^r`%$l;{u0_BzTv9J}G>T&p*Y;QQqPCecUZ*EJ0$~;B1@M({TfNB_R*C z;0cfa`5cmO9_G7xyz#MY52cCa=44;90b`iW@Y}xan@wR8W~PcS%1NeY%M|ii9i|sB zs(|@z48xK^EQH^Ihtv$uXEjDqJD#_#oRh}NIw2ZxX^Q)R($RF6Et>o7*MVQhI`7#X zgvpDx@KM}_sjRZ!fC&+Ojv*#Xv&qi6S16ZC=oda7$ip9gL!Zbd10S36&*mR{At{Mp za5>@e9S((sV{<$=(la|F^%e+nT)tMFadh7zlO>`g2t=*>b*H3Fc&0NueERYkUdZNW zR$9glWng%wZ};QyI#D&4m1O?%M`-qA_&1I99d!GEErnmC)@i{9vudDc`iGkfheRbV zsf7YMc?GYa1`O_AJs}0T6&^kPy81KYdh3siJ;g8l+BjZZt`cTf>(}~vv0q~U!<|<0 zE6cIWhy>z7X<*M1Ng$7gnXtHBgO%JRIhoRX#aiP0M@Jd`AZp8j7ID|keM4-l$@&Bq zd*@d9`3`#c=1as?$IV}>)fq}CdDj;I9Dnm$QT9zpFHEZThbOZDfXYUc_o(UBJLW_s zi^)zzn2%m?O%FAgo%xuMT&J}sR_JCWoqQy;K*~C>k!3G!{+POQAl@|K_0Ts47?hP` zU{JkCrjeL-qOW8lZH$#SOoO-_RjaXF9Y{CYL&h*QU6(2oXO{9S7UBf68 z2FE}-pudxUu+}X`v`VPE^?)wZ-Msa8+FsfNmWz`)tVrFGCDqSq%DMuabq)a#DSo(r zblXE`dm=WF+_dTg_u(oPG=B{q+)WDZ?7Crc8N8NJf3Eiv?`w?^da!4qR|ln2gJ#F1 z+-HuP(x7_}knCnjNw-aG7bY~rL7>_q`-i5mniwYV!1ip>Y*+=)O0BguOHU7wmwzA9?KfWK^Xm)6JrF*mPyidnn#E74^p^#~-oMg+?$*L_Q!_A1Dka2ky41zHrHb zEo4g%l95oTu^R+n4Zl|tp1nSxKUkaOI($VG0vQQumK?T05+GD zZ{^h`s!c7YI`2~~whCRi(?;8l-ZDMBj4G_UV+&3(&;n70zDhYNCXs%md23zt^uarj zV0uvcIC!=EA#6(y!0F_y>>bM;eLUYio~?12DEb>5V;#F}oBawuQ4FWkrXc9#O)G-qER9jKb;S&?A7 zGi4BDWG#i!HSNq$?H4(rn3a>oW}zK-47xbj!o%}a!`Dvp5?+c2&6rFKyC=5#14UJ7 zwUFAmi3Bv-8SvjwXU43Z;*xxO@+bH+cKPDwH$~15N$_VMV%38u0%zCgNe`#@?>?D^SLS8cf<}Q-JO3beXGMOhRtfq5zFwc=iT`&k#*+ z&hO_ADykjFA+eG=Z^~V)Ja?J#tHJ-z28sV)TgCsfG9tKp1OX;{nH z$ML=U{s-S*zVF95kN5fEKD_Viy6)%ebzLX=vF1ZkB6=bSf=E?W6m=j720p?dI3BnS zA!G!=jnGxa$OD3iZ~lA3pv*V4U`2$3g2Lm+_AZ_-9`-J-NL2*|q^rA&t;2I02=bXI z{3YY03!{zLoo&+Qq+heZkTGr{7z(KA@2#@&7*qdEP*%xPbI+2I9}M@`EfACV>b?4y znkMF}*alk=Ob$^a_Vw$_u+W$ku>u4_BFfHBEVAR=9geDZLVw z8)0kxj;S~-tJL5J*+|7Jyc7P}IRBF1q3Bv$`kM?Lg+2)+gymMtGp_u1$K-gohDYIM zR=g#8P6Ynl!rw1Q>%0q%?}VG`@bXanLDY5yFlj&QwNZ3qU!x#P-1ZV(2n)uu&f55* zpV;+Luji9eq7$!)PR(3iUY_qYJ04e+7PJx98EaK@h(>h7gaqb~qDVm|D^GM$QMtx@ zJ*R=$$)Ylkh~0=yulOLwxS$-%b;5J7qHue z9$MdwLc>9pkk3?fG$6>29fHuWAn5c8+*cvUiywm4%^^r49fD|FP_HkCAc*d(s-m2p z&%|c-n!!z@nJ%uowlE>?AFLF5k6T~Blp?m6I!TLd+!%}}y(8(oE|M#2$(<)9iWzH7 z7%QFa7z!!$5aSL6ir#o~pJmYnoc+Xo$;ln=9$Y2ikCxAUua%fQ>1jGP@k*a%B_=1g zgLa-=JiZ2jg8IL|m~2NrJmJ#+C@ZxiAHuogt^d(5F)@*XhDP*wyR}tTNh!jt!hkc? z>GwxVBX0`}sJ4bmP^{A*b>3q=8?YazUz&aFi$WdOdu=?w(%08-_T9feQj74lus}Mt z`HxrIy$XEzML>&ETU+~4;ira%+rk)ebivps8)BQDf`WnwJ|eU@8v1C~B*Dg}T%t!t zPTt~wtXVVb(Sacq78bVWgUhNMZO^v&?%Phbgy$4H=?58X3LkCmjhl2SZwG#MRs;`uZ457!+BQokG?)-zjXXJeas%6@u!deoF_`Fd_{ZhxhJ|LKQN zs1g0{9m|g-kjk;IZuym{bnK~-tFOiG%I0{r8V{khjZM$8J6u+0cw}UNW~RyiOC@Ty z>e-EoJ>~p?vf8TPtDrr-$k6~syd6A=2M^YWorE&GySr`PKsB|sbrqbUVPTA9`@cUL z;lotoUNOrI(r9XF(R^&XxadA7CocK$!Cm)Wcw}U*n43JwGk$pMke;62FB&pp;+yNu z=0T_T%-7#~Q%bzyj&PH1XQ>gZN2?*xyPESwk>guLM*a&9)v>8x3;r*~f$teXg zG5N)%_&*1J+HcRp2w-CUAn$9$+vC+;hYy$}JfpS`Mj6d4z%q~(p?ex^x^8Y&uWwV} zx#r~LFvTx&5ObwI8a2lYFwhG=|0~)S?B(YtVY8i^nOPrnDIwBcK*C3S-Y;`CmFmBH zI3q$I7Zw)Qjx&o>PEJaa*LAnHUW#N6LIe}bL%eNHo*UcS%v4lM2TcG=KB*NI6*L#e zLHj>Ng*wm9&VtU?*emSi;H~!@ot%7Ai;peM;f2?7NX@dSg_f3=OY}G+JFnlk!7S-B z$HN1Mef@E8AQWi%V_-k;H6t4WG zY?*#mVxruA#=X46SEMKSaM{4XKzDaRoB7ySlIrnBt4<;r8JU<)K>+~)F|o0!DRri* zU)%RQ7>@gcak{PM538q5jE#S6Xux4AFToWaPLN5+THTr~#m~<#DCn*!!;Q`SX1Gq>EKr-z-jb@OW_%1yB6ium z&a_Ow!nAI%j?2@_i;y-`vv^3n=3sMUV}IS=<261U{}Rz%mXeYJ_xi8aI6FIAgZG&b zeUsZ1ISj6DXgHR~k|{-Q{)`2$SSuF4-rnBDB^?bl3M<5#^0xTwTA7%bn3}%nv^qUq$&HMRl=5&Y)X7Ln zN=isT?pa{_cr-v^cE9^sGGL$5I@i^3tT2cu#6__P`T5`Tx~{ISR#vPwBr$g$#{aTE-tA-{{yfU`rtt2 z5wx`OJM0EIIDKgwX@z-9j)5Lu|3@b^If$gg+RkpsWRZlN ze6}Sx_=SDJ&{~agS&y~f6|SjF7W~P+><13KBNG$GW@fyYZsr3mm>-~5#GcF2j9lNs&@wQqo#cZ$3Ug0}iSbE!~(-_l@5?sE<*6SSsKDU@2*7Nuyd0 zQL(WXSaV!E>ce72TY)FR-1c_x)|7bv6!y7D@bNS%uk7W;ML?~wbCqEbV0He$dz}&y zmziGCqMFMoTOgzs78cgliWQ^B$H)6bB4=yGxwtj0;5OUD|e z*%m|UIDUioQ1>9!UGX!Sqmh>)kad2=yDa^_%oc(^g()ZKUe zVG^DNEt{mIJ*qTe1AU92 ztgnDr-qn@K&(FVe=T5oe2M>xg8<(lC^F0LLV-~oySq#&>?ipBmc4ahXCA-q1++j_ zRh5E*Vyn+l0>lXugT5A)qyQ1bw=3xtkendB3~a)6f#)I> z1ue}aP3L2I_e;07w!XN`PQ(!5x$+qq87(#D<;?o0L+qMwTxrFkddJ4bN)0MDd0f+p zd$#azpCzugy@I5oaB?&AnGx?&aq2bH@Ho2crHh%z-Bwo$E z0ShKB85|uoc=Dt+=+e)CJBEs=6GM7CDLL8S-=CeGodpVsj*e#8^aR%Tr6d1(oRF}v z7YY>_5mCpAUuT;0`ZXeXJa^&{dRA57~SBKn3Kc1d9ARH;?K_RHq6C|xuC4&8OdDYswKj03Ea+y8L=33;$3A(2H%R9&op=xu!e%~651U3G+5E~0fH{~_VC z#|J^Eq49B5=AswRpKqS-uY`W%$3V0g%e?%2LKeQNy+s%%G7=aG1*f`&1*=5$j=Qxa znW?F@!z^KKJ6OJ!w_$$hKYwi9L&U2eCkB|T!RHn_W5V-MTT_XjJ@S1x`1sgq=2AbC z;Jvk)Z4M;p=MxY!Kc`x1#dt(}AfdL$r6U0D<&7yJbGnx8+Lj$7vXFXEkaQhnlc|WL z0$B;qC(G7jftV2bm(K7UA<6{0+qds5i9g{?U5M6NpT^_h;Bd9~{bU+#62P!m>48n- zL7>%uxTvLr4wutipvi0-c2lVmv1k12cbN$bv;uriUr&$QYXOwEx4xdh>i|;uj~=Oy zsHv&1!Ne4lmA~8N1}f|Bfm68}frb0l4FyJD`pom{M$OGx#4mpT{(ZAp`e+`xxUldi zHZA7m%S~o#!3=I;;gSCSilQQ0%aiWL#>UD@{!G4|g-+u02K@g0qrWEYdo?NnZquw# zp^opts&?ul8zFi%H8p=fKi;SH*5>F%vB{;{w{O8c&8AGhRHvjSHG_E7LWrJOCP-39 z$a80|ZEVc&kzLIC`uf?KpJ&^$ji=|Zy%1#{@5%W&pMRR%7qQOmnWpn(Eor0jTs>ff zw6#NU?AL)GcK7f|m-yi}1@tm)RI!uC19ImV`J!WB5IMugO4boN~IZeHY zc;D1CZ7t|fYkYPw!rSgP1pwERwbQyE`|8!rfNuaqKo>viI{}RZ7*@o{?*FnE$`W-k zYw&hfSC7qlApqE^rx!lMCage0;~PkG=~&#ORjjnS6fkb}w(NwH1#G1eu?j}L+N;CpmVRPVk_|n$s4xqS^?ipNQ=PA`dj6K8P>TG$ zaR|%=;6Y>Ghw}1U7q##ypb4uR8U|{`~p#$&)9bNAb`O z{b#(N1G?&ip7bGc+bU7iOMoB@26z{Ol_YKo5V5|WuRCdP6_%D_&3@u=xRt)_JF)PA zs>UeLFKvugFiQs*jtRT@-=VLdX_f4rQ6P)U3xWTu93P*PcM6d{aX!Vx#cGcp-HO{* zjJmOWh=+^~ro{-*$E|A3M445zxGiFg%cNcBWEB;|ogWK<9%5){XnI;oL`2zzbH(!$ zGamwC8RXgVE-EgLiHS+yCH84M3E5_2g_0;CmIZ2PkOtjmfn@NK61a_q6iLU6O!c(W zAOfUha&mGwhZ=p{^)h$?H_-HniHRLbsF@25JW{*1occ$w$c!PgAzRXy(wXos7g+MW ztBddhFXw4gd7K5MSrYca5y_Pa4x0Sze2{2uL3`uw-gOmK)t z-zb@~EnjO%pDuys5Fs*XVrj`TK^yfHa<97p-)w7ZJ19OlJfxW%x3@Ilk7t3*ou;^H9Gers4gS?&9EZI(vm% zvEXf~DI=hSLllHaA)x~>eMyNBkN3x2_^PQ9*BM${-<5*`lH+0Oq0`;bH`zIki_gx_ zU8d`WB_%g2t-ZZPEN2b!2R1=_R9BaQFsHDf+>B1t($~KwK8-g~X2}iR|*?;u{)dl04{&7Tg4Gwz;`E zEiDZM7kIEV8|Roa!3_069Stq5{d%!Wc}Ku^&`|WW{SK*^C)AAszTxP|8)YgkAtAxV z6*KxDAbo9Zt-a4&ooZ#)l&&7**@85wkxl=2)FB3T-2$qIL(mX?-QS69LR^WTs_ zt5&`zBqNh{TOfERi$bAPRij57rTmY$FGY4hfg&EmT_8TBj7+X;&F9ZYYeU5z!J;A} zMMXtAX5L`z1SV>t8S1MyUlYX8e5wurZ~=q9zvgK+z|*Yp;SNX5ySlpawN9wa{)hl; zHeX0K{nhQ6C5oAmaoL6h6iPD~WGOX~K{F7x7tE~EB=igozpi$e@uu%L5%2w#gRJgy za;^j85kuw=f5)s}Zo2lZ$<+MWH3Yh~Nk&u@H4~{{T3cCJ`QgJ$*Sw)VD4oyTd*Lq( z36UQLfj(mS2lZa`fwy~%`|g4gJ8Lo?m;=fyD9{|?`uh5uM$5$|(;Kf(%*<@@oBjYb zg*s~;hVT$MzPMy=?5$h3r2P)M=c9r51LxFy{r!kz;NDVCDwhGn7HnmC`CYm!gzcEc z9f_U?XJuurbu==9k&_d&APt4 zyo^A*u-0c=)S13$p+4LWzRIe&Q=wUW=Y}C47gyG?>eHuBjg2RCHge1y1;`rrNG-4! zFdBPmXt)}F`@y)XyPw~L2&}TWwl>u@ZFIaBk1q#b&%i)SU7d=C=7HM_U~9%lurtPe zIW&A`h(6W^W{4yteCcpwbm?-sPz)eOd@Eu6xfy34!?-X>1I!2Chbn&YBqu37{h`^Z zC2i5CPwpiO)}<_ytt4}#NM(>Px?8uDIevj_c=%vy5ZsNG7E)6M zbBXZ$##@#!jBJiAn1hxd1Ys=U;zjaHcJ@)js7De-v01@0gr?dtdW zBpv)n*7d>%D8CmhEG}1UeD;f8*5OG=jH7U%5VbbU3Gk4F`cGa919W55e8jd zqA-@ATXtYoOdy2Ak%kX|4a`fofZvq>Eux*REdkw|guk*I>+8SNkdVNq_jdVncyCpo zknzal>U7K$*1fPpHk2wbX4nu_J}7NP$G)4yNw literal 0 HcmV?d00001 diff --git a/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Scene.material b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Scene.material new file mode 100644 index 000000000..6a2dfbc44 --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Scene.material @@ -0,0 +1,54 @@ +material LavaShellMat +{ + receive_shadows off + + technique 0 + { + pass 0 + { + + + ambient 0.500000 0.500000 0.500000 1.000000 + diffuse 0.800000 0.316192 0.800000 1.000000 + specular 0.500000 0.500000 0.500000 1.000000 12.500000 + emissive 0.000000 0.000000 0.000000 1.000000 + scene_blend alpha_blend + depth_write off + + texture_unit + { + texture LavaCoreShell.png + tex_address_mode wrap + filtering trilinear + colour_op_ex source1 src_texture src_texture + } + } + } +} +material LavaShellStoneMat +{ + receive_shadows off + + technique 0 + { + pass 0 + { + + + ambient 0.500000 0.500000 0.500000 1.000000 + diffuse 0.800000 0.316192 0.800000 1.000000 + specular 0.500000 0.500000 0.500000 1.000000 12.500000 + emissive 0.000000 0.000000 0.000000 1.000000 + scene_blend alpha_blend + depth_write off + + texture_unit + { + texture LavaCoreShellStone.png + tex_address_mode wrap + filtering trilinear + colour_op_ex source1 src_texture src_texture + } + } + } +} diff --git a/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Script.c b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Script.c new file mode 100644 index 000000000..e0351241f --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Script.c @@ -0,0 +1,54 @@ +/** + LavaCore Shell + Protects the lava core and provides a solidmask for the clonk to walk on. + + @author Win, Maikel +*/ + + +local size; + +public func InitAttach(object parent) +{ + SetAction("Attach", parent); + SetSize(Max(parent->GetCon(), parent.MinSize)); + return; +} + +public func SetSize(int size) +{ + // Rotate core to solidmask. + var r = -70; + var fsin = Sin(r, 10 * size), fcos = Cos(r, 10 * size); + SetObjDrawTransform(+fcos, +fsin, 0, -fsin, +fcos, 0); + // Update solid mask. + var solid_size = 4 * ((size * 20 / 100 + 2) / 4) + 4; + solid_size = BoundBy(solid_size, 4, 28); + var solid_x = (1 + (solid_size - 4) / 4) * (solid_size - 4) / 2; + SetSolidMask(solid_x, 0, solid_size, solid_size * 2, 28 - solid_size, 28 - solid_size); + return; +} + + +/*-- Saving --*/ + +public func SaveScenarioObject() { return false; } + + +/*-- Properties --*/ + +local Name = "$Name$"; +local Description = "$Description$"; +local Plane = 425; + +local ActMap = { + Attach = { + Prototype = Action, + Name = "Attach", + Procedure = DFA_ATTACH, + Length = 1, + Delay = 0, + FacetBase = 1, + NextAction = "Attach", + } +}; \ No newline at end of file diff --git a/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/SolidMask.png b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/SolidMask.png new file mode 100644 index 0000000000000000000000000000000000000000..edd3d85c0d3247cd6f1a156d8a6bcda6cb654f66 GIT binary patch literal 4040 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 d6J8)#N35tuimNu?72K}(v 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 z z-L?RT8h=z(-#3@b^cIf0CSBTf97-qujgi@nzrNVp2^LImQ&6#UgMBNP1Zen*nPcdp z@-K&!kK!(IZBn0@rIBCIK3Flw?=Ap{Ik1EQVfir}VdyIg+W{5&PtVrZ*Y{2N>qI+b zgbv{&ZWB?Se|^t;*dU=gm-S%GQM&I7+R4ALP+F(A)j=$mwZ?3n(*bfzoN7mhpUeUS zkRn-$D|CXMt;b!ZZ&4O{V&c9y{wC%zI+NFP-lD&25jx8KFWL3up7YjgM8c zbPT$b!6gERgLdSXS@Q!Ay#5Uh;d9ZYa5PU+2LYzCmMZjI7Q%if-q`J_-lL8O&re3Y zPy~2hv%lLcztSw;O0fuev<>%j3Y`aDoDeCertrBIpDd~f_e$LpEGWq&ku`sQ5dbAL z&hF#5L~dV*InitAttach(this); + this.MaxSize = RandomX(40, 50); + // Add a reproduction timer (from the animal library). + AddReproductionEffect(); + // Add an effect to control the lava core. + fx_behavior = CreateEffect(FxCoreBehavior, 100, 1); + return; +} + +public func Initialize() +{ + if (shell) + shell->SetSize(GetCon()); + return; +} + +public func Place(int amount, proplist rectangle, proplist settings) +{ + var max_tries = 2 * amount; + var loc_area = nil; + if (rectangle) loc_area = Loc_InArea(rectangle); + var size_range = nil; + if (settings) + size_range = settings.size_range; + var cores = []; + + while ((amount > 0) && (--max_tries > 0)) + { + var spot = FindLocation(Loc_Material("Lava"), Loc_Space(20), loc_area); + if(!Random(2)) + spot = FindLocation(Loc_Material("DuroLava"), Loc_Space(20), loc_area); + if (!spot) continue; + + var core = CreateObjectAbove(this, spot.x, spot.y, NO_OWNER); + if (!core) continue; + + if (settings.size_range) + { + core.MaxSize = Max(core.MinSize, RandomX(settings.size_range[0], settings.size_range[1])); + core->SetCon(core.MaxSize); + } + if (core->Stuck()) + { + core->RemoveObject(); + continue; + } + --amount; + PushBack(cores, core); + } + return cores; +} + +public func SetCon(int new_size) +{ + if (shell) + shell->SetSize(new_size); + return _inherited(new_size, ...); +} + +public func DoCon(int add_size) +{ + if (shell) + shell->SetSize(GetCon() + add_size); + return _inherited(add_size, ...); +} + +public func Destruction() +{ + if (shell) + shell->RemoveObject(); + return; +} + + +/*-- Core Behaviour --*/ + +local FxCoreBehavior = new Effect +{ + Construction = func() + { + this.fossilized = false; + this.move_vector = [0, 0]; + this.movement_step = 72; + this.frames_per_attack = 9; + this.evading_core = 0; + // Make core swim and able to move. + Target->SetAction("Swim"); + Target->SetComDir(COMD_None); + return; + }, + + Timer = func(int time) + { + // Check if fossilized and change state. + this->CheckFossilized(time); + if (this.fossilized) + return FX_OK; + + // Do growth. + this->DoGrowth(time); + + // Attack prey if possible. + if ((time % this.frames_per_attack) == 0) + this->AttackPrey(time); + + // Do movement. + this->DoMovement(time); + + return FX_OK; + }, + + CheckFossilized = func(int time) + { + if (this.fossilized && !Random(120)) + { + Target->Revive(); + this.fossilized = false; + } + // Fossilize more ofen at surface. + if (!this.fossilized && (!Random(160) || (!Random(100) && !Target->GBackLiquid(0, -6)))) + { + Target->Fossilize(); + this.fossilized = true; + } + return; + }, + + AttackPrey = func(int time) + { + // Only if fully grown and not fossilized. + if (Target->GetCon() < Target.MaxSize || this.fossilized) + return; + + // Shoot a bubble at a nearby prey if the path is free, sometimes randomly shoot a bubble. + var prey = Target->FindObject(Find_OCF(OCF_Alive), Target->Find_Distance(100), Target->Find_PathFree(), Find_Not(Find_ID(LavaCore))); + if (!prey && Random(60)) + return; + + var angle = Random(360); + if (prey) + angle = Angle(Target->GetX(), Target->GetY(), prey->GetX(), prey->GetY()); + var test_x = Sin(angle, Target->GetCon() / 4); + var test_y = -Cos(angle, Target->GetCon() / 4); + if (!PathFree(Target->GetX(), Target->GetY(), Target->GetX() + test_x, Target->GetY() + test_y)) + return; + + var bubble = Target->CreateObject(BoilingLava_Bubble); + bubble->SetVelocity(angle, RandomX(30, 40)); + bubble->DoCon(RandomX(10, 35)); + }, + + DoGrowth = func(int time) + { + if (Target->GetCon() >= Target.MaxSize) + return; + // Only grow in lava. + var mat = MaterialName(Target->GetMaterial(0, 5)); + if (mat == "Lava" || mat == "DuroLava") + if (Target->GetCon() < Target.MaxSize && !Random(45)) + Target->DoCon(1); + return; + }, + + DoMovement = func(int time) + { + // Only perform movement if swimming. + if (Target->GetAction() != "Swim") + return; + + var forced = false; + var speed = Target.MovementSpeed; + + // Evade other cores. This will keep them evenly spread. + var cnat = Target->GetContact(-1); + if (!Target->InLiquid()) + { + //Log("[%d]%v out of liquid", FrameCounter(), Target); + cnat = cnat | CNAT_Top; + } + var other_core = Target->FindObject(Find_ID(LavaCore), Find_Exclude(Target), Target->Find_Distance(20 + Target.MaxSize)); + // Check for contact. + if (cnat & (CNAT_Left | CNAT_Right | CNAT_Top | CNAT_Bottom) && this.evading_move <= 0) + { + this.move_vector = [RandomX(-1, 1), RandomX(-1, 1)]; + if ((cnat & CNAT_Left) && !(cnat & CNAT_Right)) + this.move_vector[0] = 1; + if ((cnat & CNAT_Right) && !(cnat & CNAT_Left)) + this.move_vector[0] = -1; + if ((cnat & CNAT_Top) && !(cnat & CNAT_Bottom)) + this.move_vector[1] = 1; + if ((cnat & CNAT_Bottom) && !(cnat & CNAT_Top)) + this.move_vector[1] = -1; + //Log("[%d]%v has contact: %d and move vector %v", FrameCounter(), Target, cnat, this.move_vector); + this.evading_move = 6; + forced = true; + } + // After contact is dealt with we can evade other cores. + else if (other_core && this.evading_move <= 0) + { + //Log("[%d]other core", FrameCounter()); + this.move_vector[0] = Sign(Target->GetX() - other_core->GetX()); + this.move_vector[1] = Sign(Target->GetY() - other_core->GetY()); + this.evading_move = 16; + forced = true; + } + // Otherwise just do random movement. + else + { + this.move_vector[0] = RandomX(-1, 1); + this.move_vector[1] = RandomX(-1, 1); + // Move upwards more often to stay at surface more often. + if (Random(3)) + this.move_vector[1] = -1; + } + + // Execute the movement. + if ((time % this.movement_step) == 0 || forced) + { + Target->SetXDir(this.move_vector[0] * speed + RandomX(-speed, speed) / 10); + Target->SetYDir(this.move_vector[1] * speed + RandomX(-speed, speed) / 10); + } + if ((time % this.movement_step) == 0 && Target.shell) + Target.shell->SetRDir(5 * (2 * Random(2) - 1)); + + // Dampen movement over time to make movements seem like impulses. + var xdir = Target->GetXDir(1000); + var ydir = Target->GetYDir(1000); + if (xdir > 0) + Target->SetXDir(xdir - 3 * speed, 1000); + else + Target->SetXDir(xdir + 3 * speed, 1000); + if (ydir > 0) + Target->SetYDir(ydir - 3 * speed, 1000); + else + Target->SetYDir(ydir + 3 * speed, 1000); + + this.evading_move--; + return; + }, + + IsFossilized = func() + { + return this.fossilized; + } +}; + +public func StartNonSwim() +{ + if (GBackLiquid()) + { + SetAction("Swim"); + return; + } + return; +} + + +/*-- Reproduction --*/ + +private func ReproductionCondition() +{ + return GetAlive() && GetCon() >= this.MaxSize; +} + +private func SpecialReproductionCondition() +{ + if (fx_behavior) + return !fx_behavior->IsFossilized(); + return false; +} + +public func Birth(object parent) +{ + SetCon(Max(GetCon(), this.MinSize)); + if (shell) + shell->SetSize(GetCon()); + return; +} + + +/*-- Core State --*/ + +// Explode on death. +public func Death() +{ + if (shell) + shell->RemoveObject(); + + Explode(BoundBy(GetCon() / 2, 20, 90)); + return; +} + +// Turns the core into a fossil. +public func Fossilize() +{ + Sound("Animals::LavaCore::Fossilize", {volume = GetCon()}); + SetComDir(COMD_Stop); + SetMeshMaterial("LavaCoreStoneMat"); + if (shell) + { + shell->SetMeshMaterial("LavaShellStoneMat"); + shell->SetRDir(0); + } + return; +} + +// Turns the fossil into a core again. +public func Revive() +{ + SetAction("Swim"); + SetComDir(COMD_None); + SetMeshMaterial("LavaCoreMat"); + if (shell) + shell->SetMeshMaterial("LavaShellMat"); + return; +} + + +/*-- Saving --*/ + +public func SaveScenarioObject(proplist props) +{ + if (!inherited(props, ...)) + return false; + // Avoid saving some stuff that's reinitialized anyway. + props->Remove("MeshMaterial"); + return true; +} + + +/*-- Properties --*/ + +local Name = "$Name$"; +local Description = "$Description$"; +local Plane = 424; +local CorrosionResist = true; +local MaxEnergy = 100000; +local ContactCalls = true; +local MinSize = 15; +local MaxSize = 50; +local MovementSpeed = 20; + +local ActMap = { + Swim = { + Prototype = Action, + Name = "Swim", + Procedure = DFA_SWIM, + Speed = 100, + Accel = 16, + Decel = 16, + Length = 1, + Delay = 0, + FacetBase = 1, + NextAction = "Swim" + }, + Walk = { + Prototype = Action, + Name = "Walk", + Procedure = DFA_WALK, + Speed = 100, + Accel = 16, + Decel = 16, + Length = 1, + Delay = 0, + FacetBase = 1, + NextAction = "Walk", + StartCall = "StartNonSwim", + InLiquidAction = "Swim", + }, + Jump = { + Prototype = Action, + Name = "Jump", + Procedure = DFA_FLIGHT, + Speed = 100, + Accel = 16, + Decel = 16, + Length = 1, + Delay = 0, + FacetBase = 1, + NextAction = "Jump", + StartCall = "StartNonSwim", + InLiquidAction = "Swim" + }, + Dead = { + Prototype = Action, + Name = "Dead", + Procedure = DFA_NONE, + Speed = 10, + Length = 1, + Delay = 0, + FacetBase=1, + Directions = 2, + FlipDir = 1, + NextAction = "Hold", + NoOtherAction = 1, + ObjectDisabled = 1 + } +}; \ No newline at end of file diff --git a/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/StringTblDE.txt b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/StringTblDE.txt new file mode 100644 index 000000000..6ec5ef623 --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Lavakern +Description=The lava high life. Has a hard shell on which a clonk may stand, but dangerous due to spitting out lava. \ No newline at end of file diff --git a/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/StringTblUS.txt b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/StringTblUS.txt new file mode 100644 index 000000000..1ffca2124 --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Lavacore +Description=The lava high life. Has a hard shell on which a clonk may stand, but dangerous due to spitting out lava. \ No newline at end of file diff --git a/planet/Sound.ocg/Animals.ocg/LavaCore.ocg/Fossilize.ogg b/planet/Sound.ocg/Animals.ocg/LavaCore.ocg/Fossilize.ogg new file mode 100644 index 0000000000000000000000000000000000000000..35ebffb2f8ef3f8daae44b430f41deebef6c3f6d GIT binary patch literal 19364 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 DG547W literal 0 HcmV?d00001 diff --git a/planet/Sound.ocg/authors.txt b/planet/Sound.ocg/authors.txt index 7a927e0b5..62ffcde7e 100644 --- a/planet/Sound.ocg/authors.txt +++ b/planet/Sound.ocg/authors.txt @@ -125,3 +125,4 @@ Kane53126 - Click2 (http://www.freesound.org/people/Kane53126/sounds/257944/) Zywx - MosquitoBuzz (http://www.freesound.org/people/Zywx/sounds/188708/) tc630 - Furnace/Start, Furnace/Stop, Furnace/Loop(http://www.freesound.org/people/tc630/sounds/47835/) kolczok - SawmillRipcut (http://freesound.org/people/kolczok/sounds/198988/) +Maikel - Fossilize (no external source) From 85cfbc406534306f9149d34930a4b88edf20c2c6 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Mon, 17 Apr 2017 17:12:14 +0200 Subject: [PATCH 60/93] DarkMine: Fix relaunch handling --- planet/Arena.ocf/DarkMine.ocs/Script.c | 53 +++++++++----------------- 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/planet/Arena.ocf/DarkMine.ocs/Script.c b/planet/Arena.ocf/DarkMine.ocs/Script.c index 1e051ca65..f7a7212f1 100644 --- a/planet/Arena.ocf/DarkMine.ocs/Script.c +++ b/planet/Arena.ocf/DarkMine.ocs/Script.c @@ -19,18 +19,30 @@ protected func Initialize() { // Goals and rules. if (SCENPAR_GameMode == GAMEMODE_Deathmatch) + { CreateObject(Goal_DeathMatch); + GetRelaunchRule()->SetDefaultRelaunches(Max(SCENPAR_NrRelaunchesKills, 0)); + } else if (SCENPAR_GameMode == GAMEMODE_LastManStanding) + { CreateObject(Goal_LastManStanding); + GetRelaunchRule()->SetDefaultRelaunches(Max(SCENPAR_NrRelaunchesKills, 0)); + } + else if (SCENPAR_GameMode == GAMEMODE_KingOfTheHill) { var goal = CreateObject(Goal_KingOfTheHill, LandscapeWidth() / 2, LandscapeHeight() / 2); goal->SetRadius(72); goal->SetPointLimit(Max(SCENPAR_NrRelaunchesKills, 1)); + GetRelaunchRule()->SetDefaultRelaunches(nil); } CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); + GetRelaunchRule() + ->SetLastWeaponUse(false) + ->SetFreeCrew(true); + // Rescale cave coordinates with map zoom and shuffle them. var mapzoom = GetScenarioVal("MapZoom", "Landscape"); for (var cave in cave_list) @@ -53,13 +65,6 @@ protected func Initialize() return; } -// Callback from the last man standing goal. -protected func RelaunchCount() -{ - // Relaunch count depends on scenario setting. - return Max(SCENPAR_NrRelaunchesKills, 0); -} - // Callback from the last man standing goal. protected func KillsToRelaunch() { @@ -73,46 +78,22 @@ public func WinKillCount() return Max(SCENPAR_NrRelaunchesKills, 1); } -// Forward callbacks to OnPlayerRelaunch for KotH goal. -protected func InitializePlayer(int plr) +public func RelaunchPosition(int plr) { - if (SCENPAR_GameMode == GAMEMODE_KingOfTheHill) - GameCall("OnPlayerRelaunch", plr, false); - return _inherited(plr, ...); + return FindStartCave(plr, GetRelaunchCount(plr) != SCENPAR_NrRelaunchesKills); } -// Forward callbacks to OnPlayerRelaunch for KotH goal. -protected func RelaunchPlayer(int plr, int killer) +public func OnClonkLeftRelaunch(object clonk, int plr) { - if (SCENPAR_GameMode == GAMEMODE_KingOfTheHill) - { - var clonk = CreateObjectAbove(Clonk, 0, 0, plr); - clonk->MakeCrewMember(plr); - SetCursor(plr, clonk); - clonk->DoEnergy(100000); - GameCall("OnPlayerRelaunch", plr, true); - } - return _inherited(plr, killer); -} - -// Callback from the last man standing and deathmatch goal. -// Takes over the role of initializing the player. -protected func OnPlayerRelaunch(int plr, bool is_relaunch) -{ - // Get the only clonk of the player. - var clonk = GetCrew(plr); - // Players start in a random small cave, the cave depends on whether it is a relaunch. - var cave = FindStartCave(plr, is_relaunch); - clonk->SetPosition(cave[0], cave[1]); - // Ensure spawn position is free + var cave = [clonk->GetX(), clonk->GetY()]; for (var i=0; i<4; ++i) BlastFree(cave[0], cave[1], 13); // Players start with a shovel, a pickaxe and two firestones. clonk->CreateContents(Shovel); clonk->CreateContents(Pickaxe); // Better weapons after relaunching. - if (!is_relaunch) + if (GetRelaunchCount(plr) != SCENPAR_NrRelaunchesKills) { clonk->CreateContents(Torch); clonk->CreateContents(Firestone, 2); From b77e9a77556bd0c47d46b439824e9102bcef1ee6 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Mon, 17 Apr 2017 17:17:16 +0200 Subject: [PATCH 61/93] RelaunchContainer: Fix using wrong locals due to 52bf2e65bbe497e7d897988765e031f56ce4a980 --- .../RelaunchContainer.ocd/Script.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c index 78d7b2dca..fbe57750c 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c @@ -16,7 +16,7 @@ local crew; // Sets the GetRelaunchRule().RelaunchTime, in seconds, the clonk is held in the container. // Returns the GetRelaunchRule().RelaunchTime, in seconds the clonk is held. -public func GetRelaunchTime() { return GetRelaunchRule().RelaunchTime / 36; } +public func GetRelaunchTime() { return GetRelaunchRule().relaunch_time / 36; } // Retrieve weapon list from scenario. private func WeaponList() { return GameCall("RelaunchWeaponList"); } @@ -47,13 +47,13 @@ private func OpenWeaponMenu(object clonk) { menu = CreateObject(MenuStyle_Default, nil, nil, clonk->GetOwner()); menu->SetPermanent(); - menu->SetTitle(Format("$MsgWeapon$", GetRelaunchRule().RelaunchTime / 36)); + menu->SetTitle(Format("$MsgWeapon$", GetRelaunchRule().relaunch_time / 36)); clonk->SetMenu(menu, true); - if(GetType(GetRelaunchRule().LastUsedPlayerWeapons) != C4V_Array) GetRelaunchRule().LastUsedPlayerWeapons = []; + if(GetType(GetRelaunchRule().last_used_player_weapons) != C4V_Array) GetRelaunchRule().last_used_player_weapons = []; for (var weapon in weapons) { - if(GetRelaunchRule().LastUsedPlayerWeapons[clonk->GetOwner()] != weapon) + if(GetRelaunchRule().last_used_player_weapons[clonk->GetOwner()] != weapon) { menu->AddItem(weapon, weapon->GetName(), nil, this, "OnWeaponSelected", weapon); } @@ -72,7 +72,7 @@ func FxIntTimeLimitTimer(object target, effect, int fxtime) RemoveObject(); return -1; } - if (fxtime >= GetRelaunchRule().RelaunchTime) + if (fxtime >= GetRelaunchRule().relaunch_time) { if (!has_selected && WeaponList()) GiveWeapon(WeaponList()[Random(GetLength(WeaponList()))]); @@ -80,9 +80,9 @@ func FxIntTimeLimitTimer(object target, effect, int fxtime) return -1; } if (menu) - menu->SetTitle(Format("$MsgWeapon$", (GetRelaunchRule().RelaunchTime - fxtime) / 36)); + menu->SetTitle(Format("$MsgWeapon$", (GetRelaunchRule().relaunch_time - fxtime) / 36)); else - PlayerMessage(clonk->GetOwner(), Format("$MsgRelaunch$", (GetRelaunchRule().RelaunchTime - fxtime) / 36)); + PlayerMessage(clonk->GetOwner(), Format("$MsgRelaunch$", (GetRelaunchRule().relaunch_time - fxtime) / 36)); return 1; } @@ -90,13 +90,13 @@ public func OnWeaponSelected(id weapon) { if(!crew) return; GiveWeapon(weapon); - if(GetRelaunchRule().DisableLastWeapon) GetRelaunchRule().LastUsedPlayerWeapons[crew->GetOwner()] = weapon; + if(GetRelaunchRule().disable_last_weapon) GetRelaunchRule().last_used_player_weapons[crew->GetOwner()] = weapon; has_selected = true; // Close menu manually, to prevent selecting more weapons. if (menu) menu->Close(); - if (!GetRelaunchRule().Hold) + if (!GetRelaunchRule().hold) RelaunchClonk(); return true; } From fc1a7a59c8fc61eb49eea6d2d22fdd22019aa1b7 Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Wed, 19 Apr 2017 09:14:39 +0200 Subject: [PATCH 62/93] Use C4Real instead of C4Fixed where representation is irrelevant While C4Real is just a typedef for C4Fixed, it signifies more clearly that we don't care about the memory representation at the point of use. --- src/game/C4GameScript.cpp | 2 +- src/player/C4Player.cpp | 8 ++++---- src/player/C4Player.h | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/game/C4GameScript.cpp b/src/game/C4GameScript.cpp index 6e325e5eb..3d8b46cfa 100644 --- a/src/game/C4GameScript.cpp +++ b/src/game/C4GameScript.cpp @@ -902,7 +902,7 @@ static bool FnSetPlayerZoom(C4PropList * _this, long plr_idx, long zoom, long pr { // zoom factor calculation if (!precision) precision = 1; - C4Fixed fZoom = itofix(zoom, precision); + C4Real fZoom = itofix(zoom, precision); // safety check on player only, so function return result is always in sync C4Player *plr = ::Players.Get(plr_idx); if (!plr) return false; diff --git a/src/player/C4Player.cpp b/src/player/C4Player.cpp index 9497ddcd7..e15a07305 100644 --- a/src/player/C4Player.cpp +++ b/src/player/C4Player.cpp @@ -1818,19 +1818,19 @@ void C4Player::SetMaxZoomByViewRange(int32_t range_wdt, int32_t range_hgt, bool ZoomLimitsToViewports(); } -void C4Player::SetZoom(C4Fixed zoom, bool direct, bool no_increase, bool no_decrease) +void C4Player::SetZoom(C4Real zoom, bool direct, bool no_increase, bool no_decrease) { AdjustZoomParameter(&ZoomVal, zoom, no_increase, no_decrease); ZoomToViewports(direct, no_increase, no_decrease); } -void C4Player::SetMinZoom(C4Fixed zoom, bool no_increase, bool no_decrease) +void C4Player::SetMinZoom(C4Real zoom, bool no_increase, bool no_decrease) { AdjustZoomParameter(&ZoomLimitMinVal, zoom, no_increase, no_decrease); ZoomLimitsToViewports(); } -void C4Player::SetMaxZoom(C4Fixed zoom, bool no_increase, bool no_decrease) +void C4Player::SetMaxZoom(C4Real zoom, bool no_increase, bool no_decrease) { AdjustZoomParameter(&ZoomLimitMaxVal, zoom, no_increase, no_decrease); ZoomLimitsToViewports(); @@ -1882,7 +1882,7 @@ bool C4Player::AdjustZoomParameter(int32_t *range_par, int32_t new_val, bool no_ return true; } -bool C4Player::AdjustZoomParameter(C4Fixed *zoom_par, C4Fixed new_val, bool no_increase, bool no_decrease) +bool C4Player::AdjustZoomParameter(C4Real *zoom_par, C4Real new_val, bool no_increase, bool no_decrease) { // helper function: Adjust *zoom_par to new_val if increase/decrease not forbidden if (new_val < *zoom_par) diff --git a/src/player/C4Player.h b/src/player/C4Player.h index 6ec8f96be..5211a9b01 100644 --- a/src/player/C4Player.h +++ b/src/player/C4Player.h @@ -112,7 +112,7 @@ public: int32_t FlashCom; // NoSave // bool fFogOfWar; int32_t ZoomLimitMinWdt,ZoomLimitMinHgt,ZoomLimitMaxWdt,ZoomLimitMaxHgt,ZoomWdt,ZoomHgt; // zoom limits and last zoom set by script - C4Fixed ZoomLimitMinVal,ZoomLimitMaxVal,ZoomVal; // direct zoom values. + C4Real ZoomLimitMinVal,ZoomLimitMaxVal,ZoomVal; // direct zoom values. // Game int32_t Wealth; int32_t CurrentScore,InitialScore; @@ -254,9 +254,9 @@ public: void SetZoomByViewRange(int32_t range_wdt, int32_t range_hgt, bool direct, bool no_increase, bool no_decrease); void SetMinZoomByViewRange(int32_t range_wdt, int32_t range_hgt, bool no_increase, bool no_decrease); void SetMaxZoomByViewRange(int32_t range_wdt, int32_t range_hgt, bool no_increase, bool no_decrease); - void SetZoom(C4Fixed zoom, bool direct, bool no_increase, bool no_decrease); - void SetMinZoom(C4Fixed zoom, bool no_increase, bool no_decrease); - void SetMaxZoom(C4Fixed zoom, bool no_increase, bool no_decrease); + void SetZoom(C4Real zoom, bool direct, bool no_increase, bool no_decrease); + void SetMinZoom(C4Real zoom, bool no_increase, bool no_decrease); + void SetMaxZoom(C4Real zoom, bool no_increase, bool no_decrease); void ZoomToViewports(bool direct, bool no_increase=false, bool no_decrease=false); void ZoomToViewport(C4Viewport* vp, bool direct, bool no_increase=false, bool no_decrease=false); void ZoomLimitsToViewports(); @@ -264,7 +264,7 @@ public: private: bool AdjustZoomParameter(int32_t *range_par, int32_t new_val, bool no_increase, bool no_decrease); - bool AdjustZoomParameter(C4Fixed *zoom_par, C4Fixed new_val, bool no_increase, bool no_decrease); + bool AdjustZoomParameter(C4Real *zoom_par, C4Real new_val, bool no_increase, bool no_decrease); // Finds a new gamepad to use, returning true on success. bool FindGamepad(); From 81e49fe0f583798464a14085b106c266bfb12f35 Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Wed, 19 Apr 2017 09:24:27 +0200 Subject: [PATCH 63/93] Fix several broken conversions from C4Fixed->bool->int (#1904) This is why non-explicit operator bool is bad. --- src/landscape/C4Particles.cpp | 2 +- src/landscape/C4SolidMask.cpp | 3 ++- src/lib/C4Real.h | 2 +- src/object/C4FindObject.cpp | 2 +- src/object/C4Object.cpp | 2 +- src/object/C4Shape.cpp | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/landscape/C4Particles.cpp b/src/landscape/C4Particles.cpp index 1f0985aa2..5f834885b 100644 --- a/src/landscape/C4Particles.cpp +++ b/src/landscape/C4Particles.cpp @@ -499,7 +499,7 @@ float C4ParticleValueProvider::Wind(C4Particle *forParticle) float C4ParticleValueProvider::Gravity(C4Particle *forParticle) { - return startValue + (speedFactor * ::Landscape.GetGravity()); + return startValue + (speedFactor * fixtof(::Landscape.GetGravity())); } void C4ParticleValueProvider::SetType(C4ParticleValueProviderID what) diff --git a/src/landscape/C4SolidMask.cpp b/src/landscape/C4SolidMask.cpp index 079e829f0..231f93c74 100644 --- a/src/landscape/C4SolidMask.cpp +++ b/src/landscape/C4SolidMask.cpp @@ -411,7 +411,8 @@ C4SolidMask::C4SolidMask(C4Object *pForObject) : pForObject(pForObject) // zero fields MaskPut=false; MaskPutRotation=0; - MaskRemovalX=MaskRemovalY=Fix0; + MaskRemovalX = Fix0; + MaskRemovalY = 0; ppAttachingObjects=nullptr; iAttachingObjectsCount=iAttachingObjectsCapacity=0; MaskMaterial=MCVehic; diff --git a/src/lib/C4Real.h b/src/lib/C4Real.h index 720e599e7..ba9f3c9a6 100644 --- a/src/lib/C4Real.h +++ b/src/lib/C4Real.h @@ -123,7 +123,7 @@ public: inline C4Fixed &operator = (int32_t x) { return *this = C4Fixed(x); } // test value - inline operator bool () const { return !! val; } + explicit operator bool () const { return val != 0; } inline bool operator ! () const { return ! val; } // arithmetic operations diff --git a/src/object/C4FindObject.cpp b/src/object/C4FindObject.cpp index a56f0f64a..0d027157e 100644 --- a/src/object/C4FindObject.cpp +++ b/src/object/C4FindObject.cpp @@ -1027,7 +1027,7 @@ int32_t C4SortObjectRandom::CompareGetValue(C4Object *pFor) int32_t C4SortObjectSpeed::CompareGetValue(C4Object *pFor) { - return pFor->xdir*pFor->xdir + pFor->ydir*pFor->ydir; + return fixtoi(pFor->xdir*pFor->xdir + pFor->ydir*pFor->ydir); } int32_t C4SortObjectMass::CompareGetValue(C4Object *pFor) diff --git a/src/object/C4Object.cpp b/src/object/C4Object.cpp index f2ca40d39..518392073 100644 --- a/src/object/C4Object.cpp +++ b/src/object/C4Object.cpp @@ -3529,7 +3529,7 @@ void C4Object::ExecAction() else if (Action.t_attach & CNAT_Top && Shape.Attach(smpx,smpy,CNAT_Top)) fAttachOK = true; if (!fAttachOK) { ObjectComStopDig(this); return; } - iPhaseAdvance=40*limit; + iPhaseAdvance=fixtoi(itofix(40)*limit); if (xdir < 0) SetDir(DIR_Left); else if (xdir > 0) SetDir(DIR_Right); Action.t_attach=CNAT_None; diff --git a/src/object/C4Shape.cpp b/src/object/C4Shape.cpp index 02628956b..37e40c3a0 100644 --- a/src/object/C4Shape.cpp +++ b/src/object/C4Shape.cpp @@ -44,7 +44,7 @@ void C4Shape::Rotate(C4Real Angle, bool bUpdateVertices) int32_t i = 0; if (Config.General.DebugRec) { - rc.x=x; rc.y=y; rc.wdt=Wdt; rc.hgt=Hgt; rc.r=Angle; + rc.x=x; rc.y=y; rc.wdt=Wdt; rc.hgt=Hgt; rc.r=fixtoi(Angle); for (; i<4; ++i) { rc.VtxX[i]=VtxX[i]; rc.VtxY[i]=VtxY[i]; } AddDbgRec(RCT_RotVtx1, &rc, sizeof(rc)); From c41bd063bd757efd5e0b208cc2274f003851610b Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Wed, 19 Apr 2017 09:40:38 +0200 Subject: [PATCH 64/93] Stop disabling debugrec code by preprocessor The optimizer is going to remove dead code anyway, and has the additional advantage of doing syntax checking, so the code won't silently break when someone changes something. --- src/C4Include.h | 17 ++++++++--------- src/gui/C4Menu.cpp | 4 +--- src/landscape/C4Landscape.cpp | 8 ++------ src/landscape/C4PXS.cpp | 12 +++--------- src/landscape/C4SolidMask.cpp | 7 +++---- src/landscape/C4SolidMask.h | 5 ----- src/object/C4Object.cpp | 12 ++---------- src/player/C4Player.cpp | 4 +--- src/script/C4AulExec.cpp | 8 ++------ 9 files changed, 22 insertions(+), 55 deletions(-) diff --git a/src/C4Include.h b/src/C4Include.h index 942581524..838f4dedf 100644 --- a/src/C4Include.h +++ b/src/C4Include.h @@ -27,17 +27,16 @@ don't need to include this file or any of the files it includes. */ #include "platform/PlatformAbstraction.h" -#define DEBUGREC_SCRIPT -#define DEBUGREC_START_FRAME 0 -#define DEBUGREC_PXS -#define DEBUGREC_OBJCOM -#define DEBUGREC_MATSCAN -#define DEBUGREC_MENU -#define DEBUGREC_OCF -//#define DEBUGREC_RECRUITMENT +constexpr bool DEBUGREC_SCRIPT = true; +constexpr int DEBUGREC_START_FRAME = 0; +constexpr bool DEBUGREC_PXS = true; +constexpr bool DEBUGREC_MATSCAN = true; +constexpr bool DEBUGREC_MENU = true; +constexpr bool DEBUGREC_OCF = true; +constexpr bool DEBUGREC_RECRUITMENT = false; // solidmask debugging -//#define SOLIDMASK_DEBUG +constexpr bool SOLIDMASK_DEBUG = false; #include #include diff --git a/src/gui/C4Menu.cpp b/src/gui/C4Menu.cpp index a901cebfd..3d5236c34 100644 --- a/src/gui/C4Menu.cpp +++ b/src/gui/C4Menu.cpp @@ -391,8 +391,7 @@ bool C4Menu::AddItem(C4MenuItem *pNew, const char *szCaption, const char *szComm int32_t iCount, C4Object *pObject, const char *szInfoCaption, C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, bool fIsSelectable) { -#ifdef DEBUGREC_MENU - if (Config.General.DebugRec) + if (DEBUGREC_MENU && Config.General.DebugRec) if (pObject) { C4RCMenuAdd rc = { pObject ? pObject->Number : -1, iCount, idID, fOwnValue, iValue, fIsSelectable }; @@ -400,7 +399,6 @@ bool C4Menu::AddItem(C4MenuItem *pNew, const char *szCaption, const char *szComm if (szCommand) AddDbgRec(RCT_MenuAddC, szCommand, strlen(szCommand)+1); if (szCommand2) AddDbgRec(RCT_MenuAddC, szCommand2, strlen(szCommand2)+1); } -#endif // Add it to the list pClientWindow->AddElement(pNew); // first menuitem is portrait, if it does not have text but a facet diff --git a/src/landscape/C4Landscape.cpp b/src/landscape/C4Landscape.cpp index 6258dd61b..1602bba36 100644 --- a/src/landscape/C4Landscape.cpp +++ b/src/landscape/C4Landscape.cpp @@ -232,10 +232,8 @@ void C4Landscape::P::ExecuteScan(C4Landscape *d) if (mat >= ::MaterialMap.Num) return; -#ifdef DEBUGREC_MATSCAN - if (Config.General.DebugRec) + if (DEBUGREC_MATSCAN && Config.General.DebugRec) AddDbgRec(RCT_MatScan, &ScanX, sizeof(ScanX)); -#endif for (int32_t cnt = 0; cnt < ScanSpeed; cnt++) { @@ -290,13 +288,11 @@ int32_t C4Landscape::P::DoScan(C4Landscape *d, int32_t cx, int32_t cy, int32_t m // find mat top int32_t mconv = ::MaterialMap.Map[mat].TempConvStrength, mconvs = mconv; -#ifdef DEBUGREC_MATSCAN - if (Config.General.DebugRec) + if (DEBUGREC_MATSCAN && Config.General.DebugRec) { C4RCMatScan rc = { cx, cy, mat, conv_to, dir, mconvs }; AddDbgRec(RCT_MatScanDo, &rc, sizeof(C4RCMatScan)); } -#endif int32_t ydir = (dir == 0 ? +1 : -1), cy2; #ifdef PRETTY_TEMP_CONV // get left pixel diff --git a/src/landscape/C4PXS.cpp b/src/landscape/C4PXS.cpp index 6675687c9..61b7f7d5d 100644 --- a/src/landscape/C4PXS.cpp +++ b/src/landscape/C4PXS.cpp @@ -33,15 +33,13 @@ static const C4Real WindDrift_Factor = itofix(1, 800); void C4PXS::Execute() { -#ifdef DEBUGREC_PXS - if (Config.General.DebugRec) + if (DEBUGREC_PXS && Config.General.DebugRec) { C4RCExecPXS rc; rc.x=x; rc.y=y; rc.iMat=Mat; rc.pos = 0; AddDbgRec(RCT_ExecPXS, &rc, sizeof(rc)); } -#endif int32_t inmat; // Safety @@ -126,29 +124,25 @@ void C4PXS::Execute() // No contact? Free movement x=ctcox; y=ctcoy; -#ifdef DEBUGREC_PXS - if (Config.General.DebugRec) + if (DEBUGREC_PXS && Config.General.DebugRec) { C4RCExecPXS rc; rc.x=x; rc.y=y; rc.iMat=Mat; rc.pos = 1; AddDbgRec(RCT_ExecPXS, &rc, sizeof(rc)); } -#endif return; } void C4PXS::Deactivate() { -#ifdef DEBUGREC_PXS - if (Config.General.DebugRec) + if (DEBUGREC_PXS && Config.General.DebugRec) { C4RCExecPXS rc; rc.x=x; rc.y=y; rc.iMat=Mat; rc.pos = 2; AddDbgRec(RCT_ExecPXS, &rc, sizeof(rc)); } -#endif Mat=MNone; ::PXS.Delete(this); } diff --git a/src/landscape/C4SolidMask.cpp b/src/landscape/C4SolidMask.cpp index 231f93c74..25d8ef79e 100644 --- a/src/landscape/C4SolidMask.cpp +++ b/src/landscape/C4SolidMask.cpp @@ -466,10 +466,11 @@ C4SolidMask * C4SolidMask::First = 0; C4SolidMask * C4SolidMask::Last = 0; -#ifdef SOLIDMASK_DEBUG - bool C4SolidMask::CheckConsistency() { + if (!SOLIDMASK_DEBUG) + return true; + assert(IsSomeVehicle(MaskMaterial)); C4Rect SolidMaskRect(0,0,::Landscape.GetWidth(),::Landscape.GetHeight()); C4SolidMask *pSolid; @@ -486,8 +487,6 @@ bool C4SolidMask::CheckConsistency() return true; } -#endif - CSurface8 *C4SolidMask::LoadMaskFromFile(class C4Group &hGroup, const char *szFilename) { // Construct SolidMask surface from PNG bitmap: diff --git a/src/landscape/C4SolidMask.h b/src/landscape/C4SolidMask.h index d8611a520..22494944d 100644 --- a/src/landscape/C4SolidMask.h +++ b/src/landscape/C4SolidMask.h @@ -82,12 +82,7 @@ public: C4SolidMask(C4Object *pForObject); // ctor ~C4SolidMask(); // dtor -#ifdef SOLIDMASK_DEBUG static bool CheckConsistency(); -#else - static bool CheckConsistency() { return true; } -#endif - static void RemoveSolidMasks(); static void PutSolidMasks(); diff --git a/src/object/C4Object.cpp b/src/object/C4Object.cpp index 518392073..136754de4 100644 --- a/src/object/C4Object.cpp +++ b/src/object/C4Object.cpp @@ -670,9 +670,7 @@ void C4Object::UpdateInMat() void C4Object::SetOCF() { C4PropList* pActionDef = GetAction(); -#ifdef DEBUGREC_OCF uint32_t dwOCFOld = OCF; -#endif // Update the object character flag according to the object's current situation C4Real cspeed=GetSpeed(); #ifdef _DEBUG @@ -756,22 +754,18 @@ void C4Object::SetOCF() // OCF_Container if ((Def->GrabPutGet & C4D_Grab_Put) || (Def->GrabPutGet & C4D_Grab_Get) || (OCF & OCF_Entrance)) OCF|=OCF_Container; -#ifdef DEBUGREC_OCF - if (Config.General.DebugRec) + if (DEBUGREC_OCF && Config.General.DebugRec) { C4RCOCF rc = { dwOCFOld, OCF, false }; AddDbgRec(RCT_OCF, &rc, sizeof(rc)); } -#endif } void C4Object::UpdateOCF() { C4PropList* pActionDef = GetAction(); -#ifdef DEBUGREC_OCF uint32_t dwOCFOld = OCF; -#endif // Update the object character flag according to the object's current situation C4Real cspeed=GetSpeed(); #ifdef _DEBUG @@ -832,13 +826,11 @@ void C4Object::UpdateOCF() // OCF_Container if ((Def->GrabPutGet & C4D_Grab_Put) || (Def->GrabPutGet & C4D_Grab_Get) || (OCF & OCF_Entrance)) OCF|=OCF_Container; -#ifdef DEBUGREC_OCF - if (Config.General.DebugRec) + if (DEBUGREC_OCF && Config.General.DebugRec) { C4RCOCF rc = { dwOCFOld, OCF, true }; AddDbgRec(RCT_OCF, &rc, sizeof(rc)); } -#endif #ifdef _DEBUG DEBUGREC_OFF uint32_t updateOCF = OCF; diff --git a/src/player/C4Player.cpp b/src/player/C4Player.cpp index e15a07305..4e20da049 100644 --- a/src/player/C4Player.cpp +++ b/src/player/C4Player.cpp @@ -516,9 +516,7 @@ void C4Player::PlaceReadyCrew(int32_t tx1, int32_t tx2, int32_t ty, C4Object *Fi if (FirstBase) { nobj->Enter(FirstBase); nobj->SetCommand(C4CMD_Exit); } // OnJoinCrew callback { -#if !defined(DEBUGREC_RECRUITMENT) - C4DebugRecOff DbgRecOff; -#endif + C4DebugRecOff DbgRecOff{ !DEBUGREC_RECRUITMENT }; C4AulParSet parset(Number); nobj->Call(PSF_OnJoinCrew, &parset); } diff --git a/src/script/C4AulExec.cpp b/src/script/C4AulExec.cpp index e0f5cae74..858609367 100644 --- a/src/script/C4AulExec.cpp +++ b/src/script/C4AulExec.cpp @@ -854,8 +854,7 @@ C4AulBCC *C4AulExec::Call(C4AulFunc *pFunc, C4Value *pReturn, C4Value *pPars, C4 if (pContext && !pContext->Status) throw C4AulExecError("using removed object"); -#ifdef DEBUGREC_SCRIPT - if (Config.General.DebugRec) + if (DEBUGREC_SCRIPT && Config.General.DebugRec) { StdStrBuf sCallText; if (pContext && pContext->GetObject()) @@ -885,7 +884,6 @@ C4AulBCC *C4AulExec::Call(C4AulFunc *pFunc, C4Value *pReturn, C4Value *pPars, C4 sCallText.AppendChar(';'); AddDbgRec(RCT_AulFunc, sCallText.getData(), sCallText.getLength()+1); } -#endif // Execute #ifdef _DEBUG @@ -1019,14 +1017,12 @@ void C4AulProfiler::Show() C4Value C4AulExec::DirectExec(C4PropList *p, const char *szScript, const char *szContext, bool fPassErrors, C4AulScriptContext* context, bool parse_function) { -#ifdef DEBUGREC_SCRIPT - if (Config.General.DebugRec) + if (DEBUGREC_SCRIPT && Config.General.DebugRec) { AddDbgRec(RCT_DirectExec, szScript, strlen(szScript)+1); int32_t iObjNumber = p && p->GetPropListNumbered() ? p->GetPropListNumbered()->Number : -1; AddDbgRec(RCT_DirectExec, &iObjNumber, sizeof(int32_t)); } -#endif // profiler StartDirectExec(); C4PropListStatic * script = ::GameScript.GetPropList(); From 95c31df9e9301989198384c5a8fc77e88aa7d401 Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Wed, 19 Apr 2017 10:32:34 +0200 Subject: [PATCH 65/93] Fix assertion-enabled build --- src/landscape/C4SolidMask.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/landscape/C4SolidMask.cpp b/src/landscape/C4SolidMask.cpp index 25d8ef79e..806f200b2 100644 --- a/src/landscape/C4SolidMask.cpp +++ b/src/landscape/C4SolidMask.cpp @@ -471,14 +471,13 @@ bool C4SolidMask::CheckConsistency() if (!SOLIDMASK_DEBUG) return true; - assert(IsSomeVehicle(MaskMaterial)); C4Rect SolidMaskRect(0,0,::Landscape.GetWidth(),::Landscape.GetHeight()); C4SolidMask *pSolid; for (pSolid = C4SolidMask::Last; pSolid; pSolid = pSolid->Prev) { pSolid->RemoveTemporary(SolidMaskRect); } - assert(!::Landscape.MatCount[MVehic]); + assert(!::Landscape.GetMatCount(MVehic)); // Restore Solidmasks for (pSolid = C4SolidMask::First; pSolid; pSolid = pSolid->Next) { From c75ffe39780309cc068d573a91d64b3be27a9f28 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Sat, 22 Apr 2017 16:11:00 +0200 Subject: [PATCH 66/93] improve lavacore solidmask This allows to stand on it more easily and should lead to less frustration for the player. --- .../LavaCore.ocd/LavaCoreShell.ocd/Script.c | 8 ++++---- .../LavaCoreShell.ocd/SolidMask.png | Bin 4040 -> 2386 bytes .../Animals.ocd/LavaCore.ocd/Script.c | 14 +++++++++----- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Script.c b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Script.c index e0351241f..948f98510 100644 --- a/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Script.c +++ b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/Script.c @@ -11,7 +11,7 @@ local size; public func InitAttach(object parent) { SetAction("Attach", parent); - SetSize(Max(parent->GetCon(), parent.MinSize)); + SetSize(BoundBy(parent->GetCon(), parent.SizeLimitMin, parent.SizeLimitMax)); return; } @@ -22,10 +22,10 @@ public func SetSize(int size) var fsin = Sin(r, 10 * size), fcos = Cos(r, 10 * size); SetObjDrawTransform(+fcos, +fsin, 0, -fsin, +fcos, 0); // Update solid mask. - var solid_size = 4 * ((size * 20 / 100 + 2) / 4) + 4; + var solid_size = 2 * ((size * 20 / 100 + 2) / 2) + 4; solid_size = BoundBy(solid_size, 4, 28); - var solid_x = (1 + (solid_size - 4) / 4) * (solid_size - 4) / 2; - SetSolidMask(solid_x, 0, solid_size, solid_size * 2, 28 - solid_size, 28 - solid_size); + var solid_x = (1 + solid_size / 2) * (solid_size - 4); + SetSolidMask(solid_x, 0, solid_size * 2, solid_size * 2, 28 - solid_size, 28 - solid_size); return; } diff --git a/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/SolidMask.png b/planet/Objects.ocd/Animals.ocd/LavaCore.ocd/LavaCoreShell.ocd/SolidMask.png index edd3d85c0d3247cd6f1a156d8a6bcda6cb654f66..69d781ba6b63858b9c65a5a975d820b5e8692d18 100644 GIT binary patch delta 2365 zcmV-D3BvZsAJP&biBL{Q4GJ0x0000DNk~Le0004?0000u2nGNE0K0T7!;_;5F@FRW z4Jr)(JKt0Q00`enL_t(|+U=cBh*eb_$A8mea1jJSLoFmyY%?)M1PT$7xC|jk7|R$C zW|O!{SK_8k7{U}2Injg=gaf*e7HJC?tsHfbF(&^6idv>NWBRml{=GNv+rsncc)Rb- z`*+X%{m%P-VNmBi@BN)~&-s1s?|+=%IY&f9Ab1smTMz((G6csYMG)+P;4B1>+;;)N z9;qP+)==chkbk!w37ghJaN2W(D(tFa>ydix%-hz4-F4fn$?ilMCTqMb znkh%3O#QA+=_*$x@>$_KXPN-ViB<~&!EhFp5u%bIc#wnBzpbHjKrpANlS0q~!IS~# zy$ynM#+>!)WIwg!m=iDJMeF5ADc7fNv?Ez2H3pVf_*-voUJ0JvuX~R~^9o*{>j9YiuZm2B^=y+x7Pl@DI8+>bp z`JYG4MnA1Uk?=7CpMO4o$W2?jRz7^S-{PCM8Ru5J&CbRIp0p7N6J>K_pH+=*0zj8q zjDAKlfX}r6!)_09fX}Rg`IQ3U)0B;08l5Y#4xdl5c)?Xru2W{CIR_zs7~q)qS))U6 z3oS-JH#3ZWvZ}wsIl$+D0{C1|2%jlyk&i|A7L{wwq8jqM$|}e7lnn0sv?^Fn|_whR@3i*ZZ6{5dEApmTJA;x|4H@Ok;!3 zFyT{QMV)8?LhS@lDb%h9A>X2N1kh2<`;RgDX`8+0BY%i~3X#qGbbIqYgiNE6P`%Ex zolZ7D5<;f|=(@7#=OY7|Z%2$pKhH*xc(66{wLSz)1EKtgpB-1vaSZM101)gYfZBTh zd1U}PseG%QRn{i*A^0@{0L2#lyhixsGz8EF2xa!*LOT})04gg3(7f{KXN$qDcFM-# zvmxT>hktMgSm`ruI{W8ZRt++A8nyxeX-hy@;I0R4wRd$)n~X-}3zuUA&{LX?>yobL zMC4nM$F<(<*6&@?^^)&E+id1g;A$!J)#M3vE4Q!DYlmG1>T_cRZQ_;4Uc`sB`|3`J zhJJRd@BeosciwOBfg_*-hv4)^WGVLjW^DNFynpfNr!T@I7XIMyTRb4k;+&zg0Z%>s zfJq3Z08}srpe5q~8jBD>Og@MRK;LC?W=6Q0=OPmqZ^0C4YydUZ?CIX1&Aj*S>p%d- zHvd!N{14Sk!+Fq-p}iIEv7FZgB@+?qwr!dKqWx_sPn3R=x#bzDOS+yBkui}cTTYvy z)aPG1a3h_slt)2zFMIW?ttnjfpFMj9MSoGD-(ogH@W_SJe$-O=dl7=oO}W{R@inLmTz_mJzPB8Y@aMj=#)C<@{{5Jg1>qkS$}VSgcIZfXI7 zTLEks)HY9*V&is;(F6pWB8q};5<(P3W#L?U{md<;YnVPZ3ZcmuAmlbQCV(i4%FM}Z zOYB+!W#=wgh0sJK5aQ{m6h#GbHgomNQ{}M8cf0l>!xWqQeCKU=r|+j31yK|g(&=o0 z;7|W(@06cK_nj>etO{h;KYzv`^o})fRw>6%gb+nhgkxfzkb!Kzt&u?J9w9_g6e0BZ z_=XuxYpgmX5-Jfw6h%>w9pYLDen<|@X_>o9*xHv&_AprAYy90F2qB81sQ;p(5f>RP zrEP`eezyd{OpbO=S{g!3vH!z_?QDD$MNx*F`0i@Ewi~hk4MK>bD1XW}h=yt%AEMm$ zjhqvrD2lQVq74vyk(ggmIhU1U`#nZO6h%>Sz^D&`F$nHEAXS^oDnf8yiOu~G+#rZ3 zilV4IAk+=PsT5eUawv+Ts30JEp$dq&pBzO|6cr3c{f+J~NJvo>MN#dB(M||1x(!+% j)|l5SLGUn3TmA(|`Vs|fCpcvu00000NkvXXu0mjfda71y delta 4030 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.MaxSize); } if (core->Stuck()) @@ -101,6 +102,8 @@ local FxCoreBehavior = new Effect this.movement_step = 72; this.frames_per_attack = 9; this.evading_core = 0; + // Change time to have cores perform actions at different times. + this.Time = Random(this.movement_step); // Make core swim and able to move. Target->SetAction("Swim"); Target->SetComDir(COMD_None); @@ -289,7 +292,7 @@ private func SpecialReproductionCondition() public func Birth(object parent) { - SetCon(Max(GetCon(), this.MinSize)); + SetCon(BoundBy(GetCon(), this.SizeLimitMin, this.SizeLimitMax)); if (shell) shell->SetSize(GetCon()); return; @@ -354,8 +357,9 @@ local Plane = 424; local CorrosionResist = true; local MaxEnergy = 100000; local ContactCalls = true; -local MinSize = 15; -local MaxSize = 50; +local SizeLimitMin = 15; // Min size of all cores. +local SizeLimitMax = 100; // Max size of all cores. +local MaxSize = 50; // To which size this core will grow. local MovementSpeed = 20; local ActMap = { From 200780fba4641c940947ad80c368177be47f3da6 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Sat, 22 Apr 2017 20:42:56 +0200 Subject: [PATCH 67/93] fix definition call to relaunch rule --- planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index cfebc8a11..c80f02bbb 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -28,7 +28,9 @@ local restart_player = false; public func Activate(int plr) { - if(!restart_player) return MessageWindow(this.Description, plr); + // Only restart player if enabled unless this is a definition call. + if (this != Rule_Relaunch && !restart_player) + return MessageWindow(this.Description, plr); // Notify scenario. if (GameCall("OnPlayerRestart", plr)) return; From 38daafc99b310dd4ab2c2fcfe5f3cc49c9adb05b Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 22 Apr 2017 09:41:56 +0200 Subject: [PATCH 68/93] Overcast: Fix script errors --- planet/Arena.ocf/Overcast.ocs/Script.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planet/Arena.ocf/Overcast.ocs/Script.c b/planet/Arena.ocf/Overcast.ocs/Script.c index 2831f51f1..55b550ded 100644 --- a/planet/Arena.ocf/Overcast.ocs/Script.c +++ b/planet/Arena.ocf/Overcast.ocs/Script.c @@ -340,7 +340,7 @@ global func CreateChestContents(id obj_id) // GameCall from RelaunchContainer. func OnClonkLeftRelaunch(object clonk) { - CreateParticle("Air", pos[0],pos[1], PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(5, 10), Overcast_air_particles, 25); + CreateParticle("Air", clonk->GetX(),clonk->GetY(), PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(5, 10), Overcast_air_particles, 25); return; } From 7064d4f6fbc45f3ce7105553e44bd4a573d183bc Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 22 Apr 2017 09:58:59 +0200 Subject: [PATCH 69/93] Rule_Relaunch: Fix return value in SetFreeCrew and SetInventoryTransfer --- planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index b546d66de..2ed4b0ac9 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -75,7 +75,7 @@ private func CheckDescription() public func SetInventoryTransfer(bool transfer) { inventory_transfer = transfer; - return true; + return this; } public func GetInventoryTransfer() @@ -86,7 +86,7 @@ public func GetInventoryTransfer() public func SetFreeCrew(bool free) { free_crew = free; - return true; + return this; } public func GetFreeCrew() From 7fed3ea1c0650494203037d41ce34b62c6944688 Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 22 Apr 2017 19:35:23 +0200 Subject: [PATCH 70/93] Rule_Relaunch: Fix positioning and inventory transfer; add option to prevent initial "relaunch" # Conflicts: # planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c --- .../Rules.ocd/Relaunch.ocd/Script.c | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index 2ed4b0ac9..69eeb0329 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -171,18 +171,14 @@ public func InitializePlayer(int plr) _inherited(plr, ...); // Scenario script callback. relaunches[plr] = default_relaunch_count; - GameCallEx("OnPlayerRelaunch", plr, false); - return DoRelaunch(plr, nil, nil, true); + if(!GameCallEx("OnPlayerRelaunch", plr, false)) return DoRelaunch(plr, nil, nil, true); } -/*public func OnClonkDeath(int plr, object pClonk, int iKiller) +public func OnClonkDeath(object clonk, int killer) { - return RelaunchPlayer(plr, iKiller, pClonk); -}*/ - -public func RelaunchPlayer(int plr, int killer, object clonk) -{ - if(plr == nil || plr == NO_OWNER) return; + if(clonk == nil) return; + var plr = clonk->GetOwner(); + if(plr == NO_OWNER || (!respawn_script_players && GetPlayerType(plr) == C4PT_Script)) return; if(default_relaunch_count != nil) { @@ -228,10 +224,10 @@ private func GetRelaunchBase(object clonk) { var plr = clonk->GetOwner(); // Neutral flagpoles are preferred respawn points, because they are used as the only respawn points in missions. - var base = clonk->FindObject2(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance()); + var base = clonk->FindObject(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance()); // If there are no neutral flagpoles, find closest base owned by the player (or team) and try to buy a clonk. if (!base) - base = clonk->FindObject2(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance()); + base = clonk->FindObject(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance()); return base; } @@ -321,7 +317,7 @@ protected func FindRelaunchPos(int plr) // Succes. return [tx, ty]; } - return nil; + return []; } /*-- Scenario saving --*/ From 750d52e06d3a213e5484c637e493b1a6f7367f6d Mon Sep 17 00:00:00 2001 From: Fulgen301 Date: Sat, 22 Apr 2017 20:50:20 +0200 Subject: [PATCH 71/93] Fix Missions.ocf scenarios in order to work with Rule_Relaunch --- planet/Missions.ocf/Crash.ocs/Script.c | 4 +- planet/Missions.ocf/DarkCastle.ocs/Script.c | 20 +++++++--- .../Missions.ocf/DeepSeaMining.ocs/Script.c | 21 ++++++---- planet/Missions.ocf/FrostySummit.ocs/Script.c | 39 ++++++++++++------- planet/Missions.ocf/Raid.ocs/Script.c | 20 +++++++--- planet/Missions.ocf/TreasureHunt.ocs/Script.c | 19 ++++++--- 6 files changed, 82 insertions(+), 41 deletions(-) diff --git a/planet/Missions.ocf/Crash.ocs/Script.c b/planet/Missions.ocf/Crash.ocs/Script.c index 091cdabd4..a0500e204 100644 --- a/planet/Missions.ocf/Crash.ocs/Script.c +++ b/planet/Missions.ocf/Crash.ocs/Script.c @@ -57,7 +57,9 @@ func DoInit(int first_player) ->SetInventoryTransfer(true) ->SetLastClonkRespawn(true) ->SetFreeCrew(true) - ->EnablePlayerRestart(); + ->EnablePlayerRestart() + ->SetBaseRespawn(true) + ->SetRespawnDelay(0); return true; } diff --git a/planet/Missions.ocf/DarkCastle.ocs/Script.c b/planet/Missions.ocf/DarkCastle.ocs/Script.c index b8d1792bc..6d8c9d2ed 100644 --- a/planet/Missions.ocf/DarkCastle.ocs/Script.c +++ b/planet/Missions.ocf/DarkCastle.ocs/Script.c @@ -11,12 +11,15 @@ static npc_pyrit; private func DoInit(int first_player) { - GetRelaunchRule() - ->SetBaseRespawn(true) - ->SetInventoryTransfer(true) - ->SetFreeCrew(true) - ->EnablePlayerRestart() - ->SetLastClonkRespawn(true); + GetRelaunchRule()->Set({ + inventory_transfer = true, + free_crew = true, + relaunch_time = 36, + respawn_at_base = true, + default_relaunch_count = nil, + player_restart = true, + respawn_last_clonk = true + }); // Message when first player enters shroom area ScheduleCall(nil, Scenario.ShroomCaveCheck, 21, 0xffffff); // Scorching village @@ -122,3 +125,8 @@ public func OnGoalsFulfilled() GainMissionAccess("S2Castle"); return false; } + +public func OnPlayerRelaunch() +{ + return true; +} \ No newline at end of file diff --git a/planet/Missions.ocf/DeepSeaMining.ocs/Script.c b/planet/Missions.ocf/DeepSeaMining.ocs/Script.c index f76dab95b..41572c19e 100644 --- a/planet/Missions.ocf/DeepSeaMining.ocs/Script.c +++ b/planet/Missions.ocf/DeepSeaMining.ocs/Script.c @@ -33,13 +33,15 @@ protected func PostIntroInitialize() } // Rules - GetRelaunchRule() - ->SetDefaultRelaunches() - ->SetInventoryTransfer(true) - ->SetFreeCrew(true) - ->EnablePlayerRestart() - ->SetBaseRespawn(true) - ->SetLastClonkRespawn(true); + GetRelaunchRule()->Set({ + inventory_transfer = true, + free_crew = true, + relaunch_time = 36, + respawn_at_base = true, + default_relaunch_count = nil, + player_restart = true, + respawn_last_clonk = true + }); // Initialize different parts of the scenario. InitializeAmbience(); @@ -313,3 +315,8 @@ global func Particles_Smoke(...) } return p; } + +public func OnPlayerRelaunch() +{ + return true; +} \ No newline at end of file diff --git a/planet/Missions.ocf/FrostySummit.ocs/Script.c b/planet/Missions.ocf/FrostySummit.ocs/Script.c index a0d1e8193..ba1c1840f 100644 --- a/planet/Missions.ocf/FrostySummit.ocs/Script.c +++ b/planet/Missions.ocf/FrostySummit.ocs/Script.c @@ -14,6 +14,15 @@ func Initialize() if (loc = FindLocation(Loc_InRect(0,80*8,40*8,20*8), Loc_Material("Earth"))) CreateObjectAbove(Rock, loc.x, loc.y+3); SetSkyParallax(1, 20,20, 0,0, nil, nil); + GetRelaunchRule()->Set({ + inventory_transfer = true, + free_crew = true, + relaunch_time = 36, + respawn_at_base = false, + default_relaunch_count = nil, + player_restart = true, + respawn_last_clonk = true + }); } static g_was_player_init; @@ -27,7 +36,6 @@ func InitializePlayer(int plr) g_was_player_init = true; } // Position and materials - JoinPlayer(plr); return true; } @@ -55,21 +63,22 @@ func RelaunchPlayer(int plr) return true; } -func JoinPlayer(int plr) +public func OnPlayerRelaunch(int plr, bool is_relaunch) { - var i, crew; - for (i=0; crew=GetCrew(plr,i); ++i) - { - crew->SetPosition(40*8+Random(40), 90*8-10); - if (!i) - { - crew->CreateContents(GrappleBow, 2); - crew->CreateContents(WindBag); - crew->CreateContents(TeleGlove); - crew->CreateContents(Dynamite, 2); - } - } - return true; + if(!is_relaunch) return OnClonkLeftRelaunch(GetCrew(plr), plr); +} + +public func OnClonkLeftRelaunch(object clonk, int plr) +{ + clonk->CreateContents(GrappleBow, 2); + clonk->CreateContents(WindBag); + clonk->CreateContents(TeleGlove); + clonk->CreateContents(Dynamite, 2); +} + +public func RelaunchPosition() +{ + return [40*8 + Random(40), 90*8-10]; } func OnGoalsFulfilled() diff --git a/planet/Missions.ocf/Raid.ocs/Script.c b/planet/Missions.ocf/Raid.ocs/Script.c index 835c6f3fe..ee7a43f31 100644 --- a/planet/Missions.ocf/Raid.ocs/Script.c +++ b/planet/Missions.ocf/Raid.ocs/Script.c @@ -26,12 +26,15 @@ static g_is_initialized, // intro started func Initialize() { - GetRelaunchRule() - ->SetBaseRespawn(true) - ->SetFairCrew(true) - ->InventoryTransfer(true) - ->EnablePlayerRestart() - ->SetLastClonkRespawn(true); + GetRelaunchRule()->Set({ + inventory_transfer = true, + free_crew = true, + relaunch_time = 36, + respawn_at_base = true, + default_relaunch_count = nil, + player_restart = true, + respawn_last_clonk = true + }); npc_newton->SetAlternativeSkin("MaleBlackHair"); npc_pyrit->SetAlternativeSkin("MaleBrownHair"); npc_woody->SetAlternativeSkin("Youngster"); @@ -128,3 +131,8 @@ func OnGoalsFulfilled() GainScenarioAchievement("Done"); return true; // GameOver done by outro } + +public func OnPlayerRelaunch() +{ + return true; +} diff --git a/planet/Missions.ocf/TreasureHunt.ocs/Script.c b/planet/Missions.ocf/TreasureHunt.ocs/Script.c index 4200425ba..eca5811bf 100644 --- a/planet/Missions.ocf/TreasureHunt.ocs/Script.c +++ b/planet/Missions.ocf/TreasureHunt.ocs/Script.c @@ -15,12 +15,15 @@ static npc_pyrit; func DoInit(int first_player) { - GetRelaunchRule() - ->SetBaseRespawn(true) - ->SetLastClonkRespawn(true) - ->SetInventoryTransfer(true) - ->SetFreeCrew(true) - ->EnablePlayerRestart(); + GetRelaunchRule()->Set({ + inventory_transfer = true, + free_crew = true, + relaunch_time = 36, + respawn_at_base = true, + default_relaunch_count = nil, + player_restart = true, + respawn_last_clonk = true + }); ClearFreeRect(530,1135, 50,2); if (g_last_stone_door) g_last_stone_door->DoDamage(170 - g_last_stone_door->GetDamage()); if (g_golden_idol) @@ -182,3 +185,7 @@ func OnInvincibleDamage(object damaged_target) return true; } +public func OnPlayerRelaunch() +{ + return true; +} \ No newline at end of file From 4c8b236ea40256ceebd053bc4ddea08c21093595 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Sun, 23 Apr 2017 18:30:15 +0200 Subject: [PATCH 72/93] fix relaunch finding no spawn Use built-in FindLocation which works better and default to landscape center when really no place to spawn could be found. --- .../Rules.ocd/Relaunch.ocd/Script.c | 68 +++++++++---------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index c80f02bbb..11a16552d 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -239,32 +239,37 @@ private func GetRelaunchBase(object clonk) public func DoRelaunch(int plr, object clonk, array position, bool no_creation) { - if(!GetPlayerName(plr)) return; - if(respawn_last_clonk && GetCrewCount(plr) >= 1) return; + if (!GetPlayerName(plr)) + return; + if (respawn_last_clonk && GetCrewCount(plr) >= 1) + return; - if(respawn_at_base) position = RespawnAtBase(clonk); - position = (position ?? GameCallEx("RelaunchPosition", plr, GetPlayerTeam(plr))) ?? FindRelaunchPos(plr); + if (respawn_at_base) + position = RespawnAtBase(clonk); + position = position ?? GameCallEx("RelaunchPosition", plr, GetPlayerTeam(plr)); + position = position ?? FindRelaunchPos(plr); var spawn; - - - // position array either has the form [x, y] or [[x, y], [x, y], ...] - if(GetType(position) == C4V_Array) + // Position array either has the form [x, y] or [[x, y], [x, y], ...]. + if (GetType(position) == C4V_Array) { - if(GetType(position[0]) == C4V_Array) + if (GetType(position[0]) == C4V_Array) { spawn = position[Random(GetLength(position))]; } else spawn = position; } + // If no spawn has been found set it to the middle of the landscape, this should not happen. + spawn = spawn ?? [LandscapeWidth() / 2, LandscapeHeight() / 2]; var new_clonk; - if(!no_creation) + if (!no_creation) { - if(free_crew) + if (free_crew) { - new_clonk = CreateObjectAbove(clonk_type, spawn[0], spawn[1],plr); - if(!new_clonk) return; + new_clonk = CreateObjectAbove(clonk_type, spawn[0], spawn[1], plr); + if (!new_clonk) + return; new_clonk->MakeCrewMember(plr); } else @@ -286,44 +291,33 @@ public func DoRelaunch(int plr, object clonk, array position, bool no_creation) else { new_clonk = GetCrew(plr); - if(!new_clonk) return; + if (!new_clonk) + return; } - if (inventory_transfer) TransferInventory(clonk, new_clonk); + if (inventory_transfer) + TransferInventory(clonk, new_clonk); new_clonk->SetPosition(spawn[0], spawn[1], plr); - if(!GetCursor(plr) || GetCursor(plr) == clonk) SetCursor(plr, new_clonk); + if (!GetCursor(plr) || GetCursor(plr) == clonk) + SetCursor(plr, new_clonk); new_clonk->DoEnergy(new_clonk.Energy || 100000); - if(relaunch_time) + if (relaunch_time) { - new_clonk->CreateObject(RelaunchContainer,nil,nil,plr)->StartRelaunch(new_clonk); + var container = new_clonk->CreateObject(RelaunchContainer, nil, nil, plr); + container->StartRelaunch(new_clonk); } return true; } protected func FindRelaunchPos(int plr) { - var tx, ty; // Test position. - for (var i = 0; i < 500; i++) - { - tx = Random(LandscapeWidth()); - ty = Random(LandscapeHeight()); - if (GBackSemiSolid(AbsX(tx), AbsY(ty))) - continue; - if (GBackSemiSolid(AbsX(tx+5), AbsY(ty+10))) - continue; - if (GBackSemiSolid(AbsX(tx+5), AbsY(ty-10))) - continue; - if (GBackSemiSolid(AbsX(tx-5), AbsY(ty+10))) - continue; - if (GBackSemiSolid(AbsX(tx-5), AbsY(ty-10))) - continue; - // Succes. - return [tx, ty]; - } - return nil; + var loc = FindLocation(Loc_Or(Loc_Sky(), Loc_Tunnel()), Loc_Space(20, CNAT_Top), Loc_Wall(CNAT_Bottom)); + if (loc == nil) + return nil; + return [loc.x, loc.y]; } /*-- Scenario saving --*/ From 2b56f55da5a8e11e301e9f924d1e48c5800c951f Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 24 Apr 2017 15:10:06 +0200 Subject: [PATCH 73/93] DarkCastle: Fix #1907 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The name entries should be "Hörx" in German and "Harx" in English --- planet/Missions.ocf/DarkCastle.ocs/StringTblDE.txt | 2 +- planet/Missions.ocf/DarkCastle.ocs/StringTblUS.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/planet/Missions.ocf/DarkCastle.ocs/StringTblDE.txt b/planet/Missions.ocf/DarkCastle.ocs/StringTblDE.txt index c5707090f..4b2704014 100644 --- a/planet/Missions.ocf/DarkCastle.ocs/StringTblDE.txt +++ b/planet/Missions.ocf/DarkCastle.ocs/StringTblDE.txt @@ -2,7 +2,7 @@ MsgEncounterCave=Ein Eindringling klaut unser Gold! Schnappt ihn! MsgEncounterOutpost=Halt, im Namen des Königs! MsgEncounterKing=Ah, %s. Ich habe Euch bereits erwartet. MsgEncounterShrooms=Was ist steht denn da Feines in dieser Höhle? Vielleicht kommen wir damit ja ins Schloss hinein. -NameHorax=Horax +NameHorax=Hörx DeathOfHorst=Er hinterlässt Frau und zwei Kinder. DeathOfHanniball=Sein Lachen wird vermisst werden. DeathOfTwonky=Ein vielversprechender, junger Filmstar. diff --git a/planet/Missions.ocf/DarkCastle.ocs/StringTblUS.txt b/planet/Missions.ocf/DarkCastle.ocs/StringTblUS.txt index bbeb5fbab..77e1a7370 100644 --- a/planet/Missions.ocf/DarkCastle.ocs/StringTblUS.txt +++ b/planet/Missions.ocf/DarkCastle.ocs/StringTblUS.txt @@ -2,7 +2,7 @@ MsgEncounterCave=An intruder tries to steal our gold. Catch him! MsgEncounterOutpost=Stop, in the name of the king! MsgEncounterKing=Ah, %s. I have been awaiting you. MsgEncounterShrooms=What is this in the cave? Fireworks? Maybe we can use them to get into the castle. -NameHorax=Hörx +NameHorax=Harx DeathOfHorst=He left a wife and two children. DeathOfHanniball=His laughter will be missed. DeathOfTwonky=A promising young movie star. From a863845ed4c9060bc1f9c35a8ec266cfb1fc027c Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Tue, 25 Apr 2017 09:45:12 +0200 Subject: [PATCH 74/93] add missing variable to relaunch rule --- .../Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index a82bd5945..db541cf94 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -25,6 +25,7 @@ local last_used_player_weapons = []; local relaunch_time = 36 * 10; local hold = false; local restart_player = false; +local respawn_script_players = false; public func Activate(int plr) { @@ -178,11 +179,12 @@ public func InitializePlayer(int plr) public func OnClonkDeath(object clonk, int killer) { - if(clonk == nil) return; + if (clonk == nil) + return; var plr = clonk->GetOwner(); - if(plr == NO_OWNER || (!respawn_script_players && GetPlayerType(plr) == C4PT_Script)) return; + if (plr == NO_OWNER || (!respawn_script_players && GetPlayerType(plr) == C4PT_Script)) return; - if(default_relaunch_count != nil) + if (default_relaunch_count != nil) { relaunches[plr]--; if(relaunches[plr] < 0) @@ -200,7 +202,8 @@ public func OnClonkDeath(object clonk, int killer) private func RespawnAtBase(object clonk) { var base = GetRelaunchBase(clonk); - if(base) return [base->GetX(), base->GetY() + base->GetDefHeight() / 2]; + if (base) + return [base->GetX(), base->GetY() + base->GetDefHeight() / 2]; } private func TransferInventory(object from, object to) @@ -209,7 +212,9 @@ private func TransferInventory(object from, object to) // Drop some items that cannot be transferred (such as connected pipes and dynamite igniters) var i = from->ContentsCount(), contents; while (i--) + { if (contents = from->Contents(i)) + { if (contents->~IsDroppedOnDeath(from)) { contents->Exit(); @@ -219,6 +224,8 @@ private func TransferInventory(object from, object to) // The new clonk doesn't burn. To be consistent, also extinguish contents contents->Extinguish(); } + } + } return to->GrabContents(from); } From cb68f9b26bfdbabbec93889c8dc872ed83369c4f Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Tue, 25 Apr 2017 10:26:27 +0200 Subject: [PATCH 75/93] fix parkour in combination with new relaunch rule --- planet/Arena.ocf/Hideout.ocs/Script.c | 2 +- planet/Arena.ocf/MeltingCastle.ocs/Script.c | 2 +- planet/Missions.ocf/Crash.ocs/Script.c | 2 +- .../Goals.ocd/Parkour.ocd/Script.c | 22 ++++++---- .../Rules.ocd/Relaunch.ocd/Script.c | 44 ++++++++++++------- planet/Parkour.ocf/Aerobatics.ocs/Script.c | 9 ++-- planet/Parkour.ocf/Boomshire.ocs/Script.c | 2 +- 7 files changed, 47 insertions(+), 36 deletions(-) diff --git a/planet/Arena.ocf/Hideout.ocs/Script.c b/planet/Arena.ocf/Hideout.ocs/Script.c index 16aa318be..95c4445ba 100644 --- a/planet/Arena.ocf/Hideout.ocs/Script.c +++ b/planet/Arena.ocf/Hideout.ocs/Script.c @@ -20,7 +20,7 @@ protected func Initialize() // Rules GetRelaunchRule() ->SetDefaultRelaunchCount(nil) - ->EnablePlayerRestart(); + ->AllowPlayerRestart(); CreateObject(Rule_ObjectFade)->DoFadeTime(5 * 36); CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); diff --git a/planet/Arena.ocf/MeltingCastle.ocs/Script.c b/planet/Arena.ocf/MeltingCastle.ocs/Script.c index 0f75fb838..3607a84f4 100644 --- a/planet/Arena.ocf/MeltingCastle.ocs/Script.c +++ b/planet/Arena.ocf/MeltingCastle.ocs/Script.c @@ -10,7 +10,7 @@ func Initialize() GetRelaunchRule()->SetRelaunchCount(nil); GetRelaunchRule()->SetRespawnDelay(8); GetRelaunchRule()->SetLastWeaponUse(false); - GetRelaunchRule()->EnablePlayerRestart(); + GetRelaunchRule()->AllowPlayerRestart(); // Mirror map objects by moving them to the other side, then re-running object initialization for (var o in FindObjects(Find_NoContainer(), Find_Not(Find_Category(C4D_Goal | C4D_Rule)))) { diff --git a/planet/Missions.ocf/Crash.ocs/Script.c b/planet/Missions.ocf/Crash.ocs/Script.c index a0500e204..9b178b394 100644 --- a/planet/Missions.ocf/Crash.ocs/Script.c +++ b/planet/Missions.ocf/Crash.ocs/Script.c @@ -57,7 +57,7 @@ func DoInit(int first_player) ->SetInventoryTransfer(true) ->SetLastClonkRespawn(true) ->SetFreeCrew(true) - ->EnablePlayerRestart() + ->AllowPlayerRestart() ->SetBaseRespawn(true) ->SetRespawnDelay(0); diff --git a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c index cbd353a70..ae769fdd5 100644 --- a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c @@ -56,7 +56,9 @@ protected func Initialize(...) private func EnsureRestartRule() { - GetRelaunchRule()->EnablePlayerRestart(); + var relaunch = GetRelaunchRule(); + relaunch->AllowPlayerRestart(); + relaunch->SetPerformRestart(false); return true; } @@ -447,7 +449,8 @@ protected func OnClonkDeath(object clonk, int killed_by) // Respawn actions var cp = FindRespawnCP(plr); UserAction->EvaluateAction(on_respawn, this, clonk, plr); - if (cp) cp->OnPlayerRespawn(new_clonk, plr); + if (cp) + cp->OnPlayerRespawn(new_clonk, plr); return; } @@ -471,7 +474,8 @@ protected func JoinPlayer(int plr) private func FindRespawnCP(int plr) { var respawn_cp = respawn_list[plr]; - if (!respawn_cp) respawn_cp = respawn_list[plr] = cp_list[0]; + if (!respawn_cp) + respawn_cp = respawn_list[plr] = cp_list[0]; return respawn_cp; } @@ -547,19 +551,19 @@ private func UpdateScoreboard(int plr) /*-- Direction indication --*/ // Effect for direction indication for the clonk. -protected func FxIntDirNextCPStart(object target, effect) +protected func FxIntDirNextCPStart(object target, effect fx) { var arrow = CreateObjectAbove(GUI_GoalArrow, 0, 0, target->GetOwner()); arrow->SetAction("Show", target); - effect.arrow = arrow; + fx.arrow = arrow; return FX_OK; } -protected func FxIntDirNextCPTimer(object target, effect) +protected func FxIntDirNextCPTimer(object target, effect fx) { var plr = target->GetOwner(); var team = GetPlayerTeam(plr); - var arrow = effect.arrow; + var arrow = fx.arrow; // Find nearest CP. var nextcp; for (var cp in FindObjects(Find_ID(ParkourCheckpoint), Find_Func("FindCPMode", PARKOUR_CP_Check | PARKOUR_CP_Finish), Sort_Distance(target->GetX() - GetX(), target->GetY() - GetY()))) @@ -604,9 +608,9 @@ protected func FxIntDirNextCPTimer(object target, effect) return FX_OK; } -protected func FxIntDirNextCPStop(object target, effect) +protected func FxIntDirNextCPStop(object target, effect fx) { - effect.arrow->RemoveObject(); + fx.arrow->RemoveObject(); return; } diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index db541cf94..d6c0986d9 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -6,13 +6,11 @@ // Determines whether the inventory of the crew member is transfered upon respawn. local inventory_transfer = false; - // Determines whether a crew member needs to be bought. local free_crew = true; - -//Determines whether the clonk will be respawned at the base +// Determines whether the clonk will be respawned at the base. local respawn_at_base = false; -//Determines whether only the last clonk gets respawned +// Determines whether only the last clonk gets respawned. local respawn_last_clonk = false; local default_relaunch_count = nil; @@ -24,13 +22,14 @@ local disable_last_weapon = false; local last_used_player_weapons = []; local relaunch_time = 36 * 10; local hold = false; -local restart_player = false; +local allow_restart_player = false; local respawn_script_players = false; +local perform_restart = true; public func Activate(int plr) { // Only restart player if enabled unless this is a definition call. - if (this != Rule_Relaunch && !restart_player) + if (this != Rule_Relaunch && !allow_restart_player) return MessageWindow(this.Description, plr); // Notify scenario. if (GameCall("OnPlayerRestart", plr)) @@ -47,7 +46,8 @@ public func Activate(int plr) protected func Initialize() { ScheduleCall(this, this.CheckDescription, 1, 1); - if(GetScenarioVal("Mode", "Game") == "Melee") default_relaunch_count = 5; + if (GetScenarioVal("Mode", "Game") == "Melee") + default_relaunch_count = 5; return true; } @@ -152,15 +152,15 @@ public func SetLastClonkRespawn(bool b) return this; } -public func EnablePlayerRestart() +public func AllowPlayerRestart() { - restart_player = true; + allow_restart_player = true; return this; } -public func DisablePlayerRestart() +public func DisallowPlayerRestart() { - restart_player = false; + allow_restart_player = false; return this; } @@ -169,6 +169,11 @@ public func GetLastClonkRespawn() return respawn_last_clonk; } +public func SetPerformRestart(bool on) +{ + perform_restart = on; +} + public func InitializePlayer(int plr) { _inherited(plr, ...); @@ -179,12 +184,12 @@ public func InitializePlayer(int plr) public func OnClonkDeath(object clonk, int killer) { - if (clonk == nil) + if (!clonk || !perform_restart) return; var plr = clonk->GetOwner(); - if (plr == NO_OWNER || (!respawn_script_players && GetPlayerType(plr) == C4PT_Script)) return; + if (plr == NO_OWNER || (!respawn_script_players && GetPlayerType(plr) == C4PT_Script)) return; - if (default_relaunch_count != nil) + if (default_relaunch_count != nil) { relaunches[plr]--; if(relaunches[plr] < 0) @@ -278,7 +283,7 @@ public func DoRelaunch(int plr, object clonk, array position, bool no_creation) else { var base = GetRelaunchBase(); - if(!base) return; + if (!base) return; // Try to buy a crew member at the base. var pay_plr = base->GetOwner(); // Payment in neutral bases by clonk owner. @@ -305,7 +310,7 @@ public func DoRelaunch(int plr, object clonk, array position, bool no_creation) if (!GetCursor(plr) || GetCursor(plr) == clonk) SetCursor(plr, new_clonk); - new_clonk->DoEnergy(new_clonk.Energy || 100000); + new_clonk->DoEnergy(new_clonk.Energy ?? 100000); if (relaunch_time) { @@ -323,6 +328,7 @@ protected func FindRelaunchPos(int plr) return [loc.x, loc.y]; } + /*-- Scenario saving --*/ public func SaveScenarioObject(props, ...) @@ -340,6 +346,8 @@ public func SaveScenarioObject(props, ...) props->AddCall("BaseRespawn", this, "SetBaseRespawn", respawn_at_base); return true; } + + /*-- Globals --*/ global func SetRelaunchCount(int plr, int value) @@ -373,7 +381,8 @@ global func GetRelaunchRule() return FindObject(Find_ID(Rule_Relaunch)) || CreateObject(Rule_Relaunch); } -/* Editor */ + +/*-- Editor --*/ public func Definition(def) { @@ -409,6 +418,7 @@ public func Definition(def) }; } + /*-- Proplist --*/ local Name = "$Name$"; diff --git a/planet/Parkour.ocf/Aerobatics.ocs/Script.c b/planet/Parkour.ocf/Aerobatics.ocs/Script.c index 525f52746..f174c7d5b 100644 --- a/planet/Parkour.ocf/Aerobatics.ocs/Script.c +++ b/planet/Parkour.ocf/Aerobatics.ocs/Script.c @@ -6,9 +6,6 @@ */ -static checkpoint_locations; -static inventorslab_location; - protected func Initialize() { // Create the parkour goal. @@ -45,9 +42,9 @@ protected func Initialize() // Rules: no power and restart with keeping inventory. CreateObject(Rule_NoPowerNeed); - GetRelaunchRule() - ->EnablePlayerRestart() - ->SetInventoryTransfer(true); + //GetRelaunchRule() + // ->AllowPlayerRestart() + // ->SetInventoryTransfer(true); // Initialize parts of the scenario. var amount = BoundBy(SCENPAR_NrCheckPoints, 6, 20); diff --git a/planet/Parkour.ocf/Boomshire.ocs/Script.c b/planet/Parkour.ocf/Boomshire.ocs/Script.c index 52710b397..4a5d78c76 100644 --- a/planet/Parkour.ocf/Boomshire.ocs/Script.c +++ b/planet/Parkour.ocf/Boomshire.ocs/Script.c @@ -3,7 +3,7 @@ private func Initialize() { GetRelaunchRule() - ->EnablePlayerRestart(); + ->AllowPlayerRestart(); // Create dynamite below the first lava basin DrawMaterialQuad("Tunnel",1378,1327-5,1860,1327-5,1860,1330,1387,1330,1); From afe4d5a91e2d5cfd9f28128d561709ab07cfcbb8 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Tue, 25 Apr 2017 11:52:50 +0200 Subject: [PATCH 76/93] fix overcast teleport scroll (#1909) --- planet/Arena.ocf/Overcast.ocs/Script.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planet/Arena.ocf/Overcast.ocs/Script.c b/planet/Arena.ocf/Overcast.ocs/Script.c index 55b550ded..5f8834e63 100644 --- a/planet/Arena.ocf/Overcast.ocs/Script.c +++ b/planet/Arena.ocf/Overcast.ocs/Script.c @@ -352,7 +352,7 @@ public func RelaunchPosition() global func GetRandomSpawn() { - return Scenario->RelaunchPosition(); + return RandomElement(Scenario->RelaunchPosition()); } func KillsToRelaunch() { return 0; } From 6f1470dbbdf8157e26d957b791d6780f4983fd76 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Tue, 25 Apr 2017 14:04:43 +0200 Subject: [PATCH 77/93] correctly update barrel graphics when emptied onto existing stack --- .../Items.ocd/Tools.ocd/Barrel.ocd/Script.c | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Script.c index 2fec98cfd..3a42f05a1 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Script.c @@ -42,18 +42,38 @@ func PlayBarrelHitSound() Sound("Hits::Materials::Wood::DullWoodHit?"); } -func Collection2(object item) +public func Collection2(object item) { UpdateLiquidContainer(); return _inherited(item, ...); } -func Ejection(object item) +public func Ejection(object item) { UpdateLiquidContainer(); return _inherited(item, ...); } +public func ContentsDestruction(object item) +{ + ScheduleCall(this, "UpdateLiquidContainer", 1); + return _inherited(item, ...); +} + +public func RemoveLiquid(liquid_name, int amount, object destination) +{ + var res = _inherited(liquid_name, amount, destination, ...); + UpdateLiquidContainer(); + return res; +} + +public func PutLiquid(liquid_name, int amount, object source) +{ + var res = _inherited(liquid_name, amount, source, ...); + UpdateLiquidContainer(); + return res; +} + /*-- Callbacks --*/ public func CollectFromStack(object item) From 3b1ebdcdb0083d9884f2d2c86e408e4c2afb937a Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Tue, 25 Apr 2017 20:12:44 +0200 Subject: [PATCH 78/93] do not move seaweed by tele glove or windbag --- planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Script.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Script.c index b13a138a2..08e48bb57 100644 --- a/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Script.c +++ b/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Script.c @@ -32,6 +32,10 @@ private func Check() if(!GBackLiquid()) SetAction("Limp"); } +// Not moved by tele glove and windbag, in contrast to most plants this plant does not per sé have a vertex that is stuck. +public func RejectTeleGloveControl() { return true; } +public func RejectWindbagForce() { return true; } + func SaveScenarioObject(props) { if (!inherited(props, ...)) return false; From 33a0b4117955a4828bbe2c1cd70c069ecad2708f Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Sat, 29 Apr 2017 14:43:40 +0200 Subject: [PATCH 79/93] Trans_Rotate: disallow rotation around null vector (#1908) Trans_Rotate will now raise at runtime if the user tries to generate a rotation matrix around a null vector instead of crashing with #DE. --- src/script/C4Script.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/script/C4Script.cpp b/src/script/C4Script.cpp index 26d3dddcd..d0cb693bf 100644 --- a/src/script/C4Script.cpp +++ b/src/script/C4Script.cpp @@ -178,6 +178,11 @@ static C4ValueArray *FnTrans_Rotate(C4PropList * _this, long angle, long rx, lon long n = long(sqrt(double(sqrt_val))); if (n * n < sqrt_val) n++; else if (n * n > sqrt_val) n--; + + if (n == 0) + { + throw C4AulExecError("cannot rotate around a null vector"); + } rx = (1000 * rx) / n; ry = (1000 * ry) / n; From 0fead04978b40a29b4e87dcaa48d3bdfad2fcc9b Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Sun, 30 Apr 2017 16:13:57 +0200 Subject: [PATCH 80/93] fix relaunching problems in missions --- planet/Missions.ocf/DarkCastle.ocs/Script.c | 17 +++---- .../Missions.ocf/DeepSeaMining.ocs/Script.c | 17 +++---- planet/Missions.ocf/FrostySummit.ocs/Script.c | 51 ++++++++++--------- planet/Missions.ocf/Raid.ocs/Script.c | 17 +++---- planet/Missions.ocf/TreasureHunt.ocs/Script.c | 17 +++---- .../Rules.ocd/Relaunch.ocd/Script.c | 3 +- 6 files changed, 60 insertions(+), 62 deletions(-) diff --git a/planet/Missions.ocf/DarkCastle.ocs/Script.c b/planet/Missions.ocf/DarkCastle.ocs/Script.c index 6d8c9d2ed..f73386e5c 100644 --- a/planet/Missions.ocf/DarkCastle.ocs/Script.c +++ b/planet/Missions.ocf/DarkCastle.ocs/Script.c @@ -11,15 +11,14 @@ static npc_pyrit; private func DoInit(int first_player) { - GetRelaunchRule()->Set({ - inventory_transfer = true, - free_crew = true, - relaunch_time = 36, - respawn_at_base = true, - default_relaunch_count = nil, - player_restart = true, - respawn_last_clonk = true - }); + var relaunch_rule = GetRelaunchRule(); + relaunch_rule->SetInventoryTransfer(true); + relaunch_rule->SetFreeCrew(true); + relaunch_rule->SetRespawnDelay(1); + relaunch_rule->SetBaseRespawn(true); + relaunch_rule->SetDefaultRelaunches(nil); + relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetLastClonkRespawn(true); // Message when first player enters shroom area ScheduleCall(nil, Scenario.ShroomCaveCheck, 21, 0xffffff); // Scorching village diff --git a/planet/Missions.ocf/DeepSeaMining.ocs/Script.c b/planet/Missions.ocf/DeepSeaMining.ocs/Script.c index 41572c19e..2d666e834 100644 --- a/planet/Missions.ocf/DeepSeaMining.ocs/Script.c +++ b/planet/Missions.ocf/DeepSeaMining.ocs/Script.c @@ -33,15 +33,14 @@ protected func PostIntroInitialize() } // Rules - GetRelaunchRule()->Set({ - inventory_transfer = true, - free_crew = true, - relaunch_time = 36, - respawn_at_base = true, - default_relaunch_count = nil, - player_restart = true, - respawn_last_clonk = true - }); + var relaunch_rule = GetRelaunchRule(); + relaunch_rule->SetInventoryTransfer(true); + relaunch_rule->SetFreeCrew(true); + relaunch_rule->SetRespawnDelay(1); + relaunch_rule->SetBaseRespawn(true); + relaunch_rule->SetDefaultRelaunches(nil); + relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetLastClonkRespawn(true); // Initialize different parts of the scenario. InitializeAmbience(); diff --git a/planet/Missions.ocf/FrostySummit.ocs/Script.c b/planet/Missions.ocf/FrostySummit.ocs/Script.c index ba1c1840f..fcc70db70 100644 --- a/planet/Missions.ocf/FrostySummit.ocs/Script.c +++ b/planet/Missions.ocf/FrostySummit.ocs/Script.c @@ -14,15 +14,14 @@ func Initialize() if (loc = FindLocation(Loc_InRect(0,80*8,40*8,20*8), Loc_Material("Earth"))) CreateObjectAbove(Rock, loc.x, loc.y+3); SetSkyParallax(1, 20,20, 0,0, nil, nil); - GetRelaunchRule()->Set({ - inventory_transfer = true, - free_crew = true, - relaunch_time = 36, - respawn_at_base = false, - default_relaunch_count = nil, - player_restart = true, - respawn_last_clonk = true - }); + var relaunch_rule = GetRelaunchRule(); + relaunch_rule->SetInventoryTransfer(true); + relaunch_rule->SetFreeCrew(true); + relaunch_rule->SetRespawnDelay(1); + relaunch_rule->SetBaseRespawn(false); + relaunch_rule->SetDefaultRelaunches(nil); + relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetLastClonkRespawn(true); } static g_was_player_init; @@ -35,50 +34,52 @@ func InitializePlayer(int plr) InitBase(plr); g_was_player_init = true; } - // Position and materials + // Position. + var clonk = GetCrew(plr); + var pos = RelaunchPosition(); + clonk->SetPosition(pos[0], pos[1]); return true; } private func InitBase(int owner) { // Create standard base owned by player - var y=90*8, x=40*8; - var flag = CreateObjectAbove(Flagpole, x+85,y, owner); + var y = 90 * 8, x=40 * 8; + CreateObjectAbove(Flagpole, x+85,y, owner); var hut = CreateObjectAbove(ToolsWorkshop, x+45,y, owner); if (hut) { hut->CreateContents(Shovel, 1); hut->CreateContents(Loam, 1); } - for (var i=0; i<3; ++i) CreateObjectAbove(Boompack, x+20+i*5+Random(4),y, owner); + for (var i = 0; i < 3; ++i) + CreateObjectAbove(Boompack, x+20+i*5+Random(4),y, owner); return true; } -func RelaunchPlayer(int plr) +public func RelaunchPlayer(int plr) { var clonk = CreateObjectAbove(Clonk, 50, 1000, plr); clonk->MakeCrewMember(plr); SetCursor(plr, clonk); - JoinPlayer(plr); return true; } public func OnPlayerRelaunch(int plr, bool is_relaunch) { - if(!is_relaunch) return OnClonkLeftRelaunch(GetCrew(plr), plr); -} - -public func OnClonkLeftRelaunch(object clonk, int plr) -{ - clonk->CreateContents(GrappleBow, 2); - clonk->CreateContents(WindBag); - clonk->CreateContents(TeleGlove); - clonk->CreateContents(Dynamite, 2); + if (!is_relaunch) + { + var clonk = GetCrew(plr); + clonk->CreateContents(GrappleBow, 2); + clonk->CreateContents(WindBag); + clonk->CreateContents(TeleGlove); + clonk->CreateContents(Dynamite, 2); + } } public func RelaunchPosition() { - return [40*8 + Random(40), 90*8-10]; + return [40 * 8 + Random(40), 90 * 8 - 10]; } func OnGoalsFulfilled() diff --git a/planet/Missions.ocf/Raid.ocs/Script.c b/planet/Missions.ocf/Raid.ocs/Script.c index ee7a43f31..f714d89c8 100644 --- a/planet/Missions.ocf/Raid.ocs/Script.c +++ b/planet/Missions.ocf/Raid.ocs/Script.c @@ -26,15 +26,14 @@ static g_is_initialized, // intro started func Initialize() { - GetRelaunchRule()->Set({ - inventory_transfer = true, - free_crew = true, - relaunch_time = 36, - respawn_at_base = true, - default_relaunch_count = nil, - player_restart = true, - respawn_last_clonk = true - }); + var relaunch_rule = GetRelaunchRule(); + relaunch_rule->SetInventoryTransfer(true); + relaunch_rule->SetFreeCrew(true); + relaunch_rule->SetRespawnDelay(1); + relaunch_rule->SetBaseRespawn(true); + relaunch_rule->SetDefaultRelaunches(nil); + relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetLastClonkRespawn(true); npc_newton->SetAlternativeSkin("MaleBlackHair"); npc_pyrit->SetAlternativeSkin("MaleBrownHair"); npc_woody->SetAlternativeSkin("Youngster"); diff --git a/planet/Missions.ocf/TreasureHunt.ocs/Script.c b/planet/Missions.ocf/TreasureHunt.ocs/Script.c index eca5811bf..b859aa722 100644 --- a/planet/Missions.ocf/TreasureHunt.ocs/Script.c +++ b/planet/Missions.ocf/TreasureHunt.ocs/Script.c @@ -15,15 +15,14 @@ static npc_pyrit; func DoInit(int first_player) { - GetRelaunchRule()->Set({ - inventory_transfer = true, - free_crew = true, - relaunch_time = 36, - respawn_at_base = true, - default_relaunch_count = nil, - player_restart = true, - respawn_last_clonk = true - }); + var relaunch_rule = GetRelaunchRule(); + relaunch_rule->SetInventoryTransfer(true); + relaunch_rule->SetFreeCrew(true); + relaunch_rule->SetRespawnDelay(1); + relaunch_rule->SetBaseRespawn(true); + relaunch_rule->SetDefaultRelaunches(nil); + relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetLastClonkRespawn(true); ClearFreeRect(530,1135, 50,2); if (g_last_stone_door) g_last_stone_door->DoDamage(170 - g_last_stone_door->GetDamage()); if (g_golden_idol) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index d6c0986d9..965f64927 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -179,7 +179,8 @@ public func InitializePlayer(int plr) _inherited(plr, ...); // Scenario script callback. relaunches[plr] = default_relaunch_count; - if(!GameCallEx("OnPlayerRelaunch", plr, false)) return DoRelaunch(plr, nil, nil, true); + if (!GameCallEx("OnPlayerRelaunch", plr, false)) + return DoRelaunch(plr, nil, nil, true); } public func OnClonkDeath(object clonk, int killer) From 18057587d6080282a813113b7deda7d6572d445b Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Sun, 30 Apr 2017 18:42:44 +0200 Subject: [PATCH 81/93] fix relaunching in CTFs --- planet/Arena.ocf/Hideout.ocs/Script.c | 17 ++++++------- .../Goals.ocd/CaptureTheFlag.ocd/Script.c | 23 +++++++++++------- .../Rules.ocd/Relaunch.ocd/Script.c | 24 ++++++++++++------- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/planet/Arena.ocf/Hideout.ocs/Script.c b/planet/Arena.ocf/Hideout.ocs/Script.c index 95c4445ba..6bcac2b37 100644 --- a/planet/Arena.ocf/Hideout.ocs/Script.c +++ b/planet/Arena.ocf/Hideout.ocs/Script.c @@ -14,22 +14,19 @@ protected func Initialize() // Goal: Capture the flag, with bases in both hideouts. var goal = CreateObject(Goal_CaptureTheFlag, 0, 0, NO_OWNER); - goal->SetFlagBase(1, 120, 502); - goal->SetFlagBase(2, LandscapeWidth() - 120, 502); + goal->SetFlagBase(1, 120, 506); + goal->SetFlagBase(2, LandscapeWidth() - 120, 506); // Rules - GetRelaunchRule() - ->SetDefaultRelaunchCount(nil) - ->AllowPlayerRestart(); + var relaunch_rule = GetRelaunchRule(); + relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetRespawnDelay(8); + relaunch_rule->SetLastWeaponUse(false); CreateObject(Rule_ObjectFade)->DoFadeTime(5 * 36); CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); - GetRelaunchRule()->SetDefaultRelaunchCount(nil); - GetRelaunchRule()->SetRespawnDelay(8); - GetRelaunchRule()->SetLastWeaponUse(false); - + var lwidth = LandscapeWidth(); - // Doors and spinwheels. var gate, wheel; gate = CreateObjectAbove(StoneDoor, 364, 448, NO_OWNER); diff --git a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c index 58711d339..c6c639c6a 100644 --- a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c @@ -18,8 +18,12 @@ func ScoreboardTeamID(int team) protected func Initialize() { score_list = []; - GetRelaunchRule()->SetRespawnDelay(0); - GetRelaunchRule()->SetDefaultRelaunches(nil); + + var relaunch_rule = GetRelaunchRule(); + relaunch_rule->SetRespawnDelay(0); + relaunch_rule->SetDefaultRelaunches(nil); + relaunch_rule->AllowPlayerRestart(); + relaunch_rule.FindRelaunchPos = GetID().FindRelaunchPos; // init scoreboard Scoreboard->Init( @@ -43,9 +47,9 @@ private func GetScoreGoal() public func SetFlagBase(int team, int x, int y) { - var base = CreateObject(Goal_FlagBase, x, y, NO_OWNER); + var base = CreateObjectAbove(Goal_FlagBase, x, y, NO_OWNER); base->SetTeam(team); - var flag = CreateObject(Goal_Flag, x, y, NO_OWNER); + var flag = CreateObjectAbove(Goal_Flag, x, y, NO_OWNER); flag->SetAction("AttachBase", base); flag->SetTeam(team); return; @@ -77,23 +81,24 @@ private func EliminateOthers(int win_team) protected func InitializePlayer(int plr, int x, int y, object base, int team) { // Join new clonk. - GetRelaunchRule()->DoRelaunch(plr, nil, RelaunchPosition(team), true); + GetRelaunchRule()->DoRelaunch(plr, nil, FindRelaunchPos(plr), true); // make scoreboard entry for team Scoreboard->NewEntry(ScoreboardTeamID(team), GetTaggedTeamName(team)); return _inherited(plr, x, y, base, team, ...); } -public func RelaunchPosition(int iTeam) +public func FindRelaunchPos(int plr) { - var base = FindObject(Find_ID(Goal_FlagBase), Find_Func("FindTeam", iTeam)); - if (base) return [base->GetX(), base->GetY() - 10]; + var team = GetPlayerTeam(plr); + var base = FindObject(Find_ID(Goal_FlagBase), Find_Func("FindTeam", team)); + if (base) + return [base->GetX(), base->GetY() - 10]; return nil; } protected func RemovePlayer(int plr) { - return _inherited(plr, ...); } diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index 965f64927..006835d84 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -205,9 +205,9 @@ public func OnClonkDeath(object clonk, int killer) return DoRelaunch(plr, clonk, nil); } -private func RespawnAtBase(object clonk) +private func RespawnAtBase(int plr, object clonk) { - var base = GetRelaunchBase(clonk); + var base = GetRelaunchBase(plr, clonk); if (base) return [base->GetX(), base->GetY() + base->GetDefHeight() / 2]; } @@ -235,14 +235,20 @@ private func TransferInventory(object from, object to) return to->GrabContents(from); } -private func GetRelaunchBase(object clonk) +private func GetRelaunchBase(int plr, object clonk) { - var plr = clonk->GetOwner(); + plr = plr ?? clonk->GetOwner(); // Neutral flagpoles are preferred respawn points, because they are used as the only respawn points in missions. - var base = clonk->FindObject(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance()); + var base = FindObject(Find_ID(Flagpole), Find_Func("IsNeutral"), Sort_Random()); + if (clonk) + clonk->FindObject(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance()); // If there are no neutral flagpoles, find closest base owned by the player (or team) and try to buy a clonk. if (!base) - base = clonk->FindObject(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance()); + { + base = FindObject(Find_Func("IsBaseBuilding"), Find_Allied(plr), Sort_Random()); + if (clonk) + base = clonk->FindObject(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance()); + } return base; } @@ -254,9 +260,9 @@ public func DoRelaunch(int plr, object clonk, array position, bool no_creation) return; if (respawn_at_base) - position = RespawnAtBase(clonk); - position = position ?? GameCallEx("RelaunchPosition", plr, GetPlayerTeam(plr)); - position = position ?? FindRelaunchPos(plr); + position = RespawnAtBase(plr, clonk); + position = position ?? GameCall("RelaunchPosition", plr, GetPlayerTeam(plr)); + position = position ?? this->FindRelaunchPos(plr); var spawn; // Position array either has the form [x, y] or [[x, y], [x, y], ...]. From f3291bb84fd9369838fae6f35baef28a984553f2 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Mon, 1 May 2017 11:00:51 +0200 Subject: [PATCH 82/93] clean up and document relaunch rule Also fix script errors in melting castle. --- planet/Arena.ocf/DarkMine.ocs/Script.c | 13 +- planet/Arena.ocf/Hideout.ocs/Script.c | 2 +- planet/Arena.ocf/MeltingCastle.ocs/Script.c | 23 +- planet/Arena.ocf/ThunderousSkies.ocs/Script.c | 2 +- planet/Defense.ocf/KingOfTheHill.ocs/Script.c | 5 +- planet/Missions.ocf/Crash.ocs/Script.c | 2 +- planet/Missions.ocf/DarkCastle.ocs/Script.c | 4 +- .../Missions.ocf/DeepSeaMining.ocs/Script.c | 4 +- planet/Missions.ocf/FrostySummit.ocs/Script.c | 4 +- planet/Missions.ocf/Raid.ocs/Script.c | 4 +- planet/Missions.ocf/TreasureHunt.ocs/Script.c | 4 +- .../Goals.ocd/CaptureTheFlag.ocd/Script.c | 4 +- .../Goals.ocd/DeathMatch.ocd/Script.c | 2 +- .../Goals.ocd/LastManStanding.ocd/Script.c | 2 +- .../Goals.ocd/Parkour.ocd/Script.c | 2 +- .../Scoreboard.ocd/Relaunch.ocd/Script.c | 10 +- .../Rules.ocd/BaseRespawn.ocd/Script.c | 5 +- .../Rules.ocd/Killlogs.ocd/Script.c | 2 +- .../RelaunchContainer.ocd/Script.c | 9 +- .../Rules.ocd/Relaunch.ocd/Script.c | 323 ++++++++++-------- planet/Parkour.ocf/Aerobatics.ocs/Script.c | 3 - planet/Parkour.ocf/Boomshire.ocs/Script.c | 3 +- 22 files changed, 232 insertions(+), 200 deletions(-) diff --git a/planet/Arena.ocf/DarkMine.ocs/Script.c b/planet/Arena.ocf/DarkMine.ocs/Script.c index f7a7212f1..7913eda4d 100644 --- a/planet/Arena.ocf/DarkMine.ocs/Script.c +++ b/planet/Arena.ocf/DarkMine.ocs/Script.c @@ -7,9 +7,6 @@ */ -// List for storing the different large caves. -static cave_list; - // Game modes. static const GAMEMODE_Deathmatch = 0; static const GAMEMODE_LastManStanding = 1; @@ -21,12 +18,12 @@ protected func Initialize() if (SCENPAR_GameMode == GAMEMODE_Deathmatch) { CreateObject(Goal_DeathMatch); - GetRelaunchRule()->SetDefaultRelaunches(Max(SCENPAR_NrRelaunchesKills, 0)); + GetRelaunchRule()->SetDefaultRelaunchCount(Max(SCENPAR_NrRelaunchesKills, 0)); } else if (SCENPAR_GameMode == GAMEMODE_LastManStanding) { CreateObject(Goal_LastManStanding); - GetRelaunchRule()->SetDefaultRelaunches(Max(SCENPAR_NrRelaunchesKills, 0)); + GetRelaunchRule()->SetDefaultRelaunchCount(Max(SCENPAR_NrRelaunchesKills, 0)); } else if (SCENPAR_GameMode == GAMEMODE_KingOfTheHill) @@ -34,7 +31,7 @@ protected func Initialize() var goal = CreateObject(Goal_KingOfTheHill, LandscapeWidth() / 2, LandscapeHeight() / 2); goal->SetRadius(72); goal->SetPointLimit(Max(SCENPAR_NrRelaunchesKills, 1)); - GetRelaunchRule()->SetDefaultRelaunches(nil); + GetRelaunchRule()->SetDefaultRelaunchCount(nil); } CreateObject(Rule_KillLogs); CreateObject(Rule_Gravestones); @@ -80,7 +77,7 @@ public func WinKillCount() public func RelaunchPosition(int plr) { - return FindStartCave(plr, GetRelaunchCount(plr) != SCENPAR_NrRelaunchesKills); + return FindStartCave(plr, GetRelaunchRule()->GetPlayerRelaunchCount(plr) != SCENPAR_NrRelaunchesKills); } public func OnClonkLeftRelaunch(object clonk, int plr) @@ -93,7 +90,7 @@ public func OnClonkLeftRelaunch(object clonk, int plr) clonk->CreateContents(Shovel); clonk->CreateContents(Pickaxe); // Better weapons after relaunching. - if (GetRelaunchCount(plr) != SCENPAR_NrRelaunchesKills) + if (GetRelaunchRule()->GetPlayerRelaunchCount(plr) != SCENPAR_NrRelaunchesKills) { clonk->CreateContents(Torch); clonk->CreateContents(Firestone, 2); diff --git a/planet/Arena.ocf/Hideout.ocs/Script.c b/planet/Arena.ocf/Hideout.ocs/Script.c index 6bcac2b37..3f479fb94 100644 --- a/planet/Arena.ocf/Hideout.ocs/Script.c +++ b/planet/Arena.ocf/Hideout.ocs/Script.c @@ -19,7 +19,7 @@ protected func Initialize() // Rules var relaunch_rule = GetRelaunchRule(); - relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetAllowPlayerRestart(true); relaunch_rule->SetRespawnDelay(8); relaunch_rule->SetLastWeaponUse(false); CreateObject(Rule_ObjectFade)->DoFadeTime(5 * 36); diff --git a/planet/Arena.ocf/MeltingCastle.ocs/Script.c b/planet/Arena.ocf/MeltingCastle.ocs/Script.c index 3607a84f4..6957077d6 100644 --- a/planet/Arena.ocf/MeltingCastle.ocs/Script.c +++ b/planet/Arena.ocf/MeltingCastle.ocs/Script.c @@ -7,10 +7,10 @@ static const EDIT_MAP = false; // Set to true to edit map and Objects.c; avoids func Initialize() { if (EDIT_MAP) return true; - GetRelaunchRule()->SetRelaunchCount(nil); + GetRelaunchRule()->SetDefaultRelaunchCount(nil); GetRelaunchRule()->SetRespawnDelay(8); GetRelaunchRule()->SetLastWeaponUse(false); - GetRelaunchRule()->AllowPlayerRestart(); + GetRelaunchRule()->SetAllowPlayerRestart(true); // Mirror map objects by moving them to the other side, then re-running object initialization for (var o in FindObjects(Find_NoContainer(), Find_Not(Find_Category(C4D_Goal | C4D_Rule)))) { @@ -128,20 +128,21 @@ func IntroMsg() return true; } -func LaunchPlayer(object pClonk, int plr) +func LaunchPlayer(object clonk, int plr) { // Make sure clonk can move - DigFreeRect(pClonk->GetX()-6,pClonk->GetY()-10,13,18,true); + DigFreeRect(clonk->GetX()-6,clonk->GetY()-10,13,18,true); // Crew setup - pClonk.MaxEnergy = 100000; - pClonk->DoEnergy(1000); - pClonk->CreateContents(WindBag); + clonk.MaxEnergy = 100000; + clonk->DoEnergy(1000); + clonk->CreateContents(WindBag); return true; } -public func OnPlayerRelaunch(iPlr) +public func OnPlayerRelaunch(int plr) { - if(!g_respawn_flags[GetPlayerTeam(plr)]) return EliminatePlayer(plr); + if (!g_respawn_flags[GetPlayerTeam(plr)]) + return EliminatePlayer(plr); } public func RelaunchPosition(int iPlr, int iTeam) @@ -150,7 +151,7 @@ public func RelaunchPosition(int iPlr, int iTeam) return [g_respawn_flags[iTeam]->GetX(), g_respawn_flags[iTeam]->GetY()]; } -public func OnClonkLeftRelaunch(object pClonk, int plr) +public func OnClonkLeftRelaunch(object clonk, int plr) { // Find flag for respawn var flagpole = g_respawn_flags[GetPlayerTeam(plr)]; @@ -159,7 +160,7 @@ public func OnClonkLeftRelaunch(object pClonk, int plr) // Reset available items in spawns for (var item_spawn in FindObjects(Find_ID(ItemSpawn))) item_spawn->Reset(plr); // Relaunch near current flag pos (will be adjusted on actual relaunch) - return LaunchPlayer(plr); + return LaunchPlayer(clonk, plr); } func RelaunchWeaponList() { return [Bow, Sword, Club, Javelin, Blunderbuss, Firestone, IceWallKit]; } diff --git a/planet/Arena.ocf/ThunderousSkies.ocs/Script.c b/planet/Arena.ocf/ThunderousSkies.ocs/Script.c index 968cebaa1..2a40b8992 100644 --- a/planet/Arena.ocf/ThunderousSkies.ocs/Script.c +++ b/planet/Arena.ocf/ThunderousSkies.ocs/Script.c @@ -20,7 +20,7 @@ protected func Initialize() CreateObject(Rule_Gravestones); GetRelaunchRule() ->SetLastWeaponUse(false) - ->SetDefaultRelaunches(nil); + ->SetDefaultRelaunchCount(nil); //Enviroment. //SetSkyAdjust(RGBa(250,250,255,128),RGB(200,200,220)); diff --git a/planet/Defense.ocf/KingOfTheHill.ocs/Script.c b/planet/Defense.ocf/KingOfTheHill.ocs/Script.c index 584af9829..964fbf0ec 100644 --- a/planet/Defense.ocf/KingOfTheHill.ocs/Script.c +++ b/planet/Defense.ocf/KingOfTheHill.ocs/Script.c @@ -15,7 +15,10 @@ protected func Initialize() // Rules. CreateObject(Rule_BuyAtFlagpole); - GetRelaunchRule()->SetBaseRespawn(true); + var relaunch_rule = GetRelaunchRule(); + relaunch_rule->SetBaseRespawn(true); + relaunch_rule->SetFreeCrew(false); + relaunch_rule->SetLastClonkRespawn(true); CreateObject(Rule_TeamAccount); CreateObject(Rule_NoFriendlyFire); CreateObject(Rule_Gravestones)->SetFadeOut(3 * 36); diff --git a/planet/Missions.ocf/Crash.ocs/Script.c b/planet/Missions.ocf/Crash.ocs/Script.c index 9b178b394..49cc42b22 100644 --- a/planet/Missions.ocf/Crash.ocs/Script.c +++ b/planet/Missions.ocf/Crash.ocs/Script.c @@ -57,7 +57,7 @@ func DoInit(int first_player) ->SetInventoryTransfer(true) ->SetLastClonkRespawn(true) ->SetFreeCrew(true) - ->AllowPlayerRestart() + ->SetAllowPlayerRestart(true) ->SetBaseRespawn(true) ->SetRespawnDelay(0); diff --git a/planet/Missions.ocf/DarkCastle.ocs/Script.c b/planet/Missions.ocf/DarkCastle.ocs/Script.c index f73386e5c..f49271feb 100644 --- a/planet/Missions.ocf/DarkCastle.ocs/Script.c +++ b/planet/Missions.ocf/DarkCastle.ocs/Script.c @@ -16,8 +16,8 @@ private func DoInit(int first_player) relaunch_rule->SetFreeCrew(true); relaunch_rule->SetRespawnDelay(1); relaunch_rule->SetBaseRespawn(true); - relaunch_rule->SetDefaultRelaunches(nil); - relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetDefaultRelaunchCount(nil); + relaunch_rule->SetAllowPlayerRestart(true); relaunch_rule->SetLastClonkRespawn(true); // Message when first player enters shroom area ScheduleCall(nil, Scenario.ShroomCaveCheck, 21, 0xffffff); diff --git a/planet/Missions.ocf/DeepSeaMining.ocs/Script.c b/planet/Missions.ocf/DeepSeaMining.ocs/Script.c index 2d666e834..4fde0215b 100644 --- a/planet/Missions.ocf/DeepSeaMining.ocs/Script.c +++ b/planet/Missions.ocf/DeepSeaMining.ocs/Script.c @@ -38,8 +38,8 @@ protected func PostIntroInitialize() relaunch_rule->SetFreeCrew(true); relaunch_rule->SetRespawnDelay(1); relaunch_rule->SetBaseRespawn(true); - relaunch_rule->SetDefaultRelaunches(nil); - relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetDefaultRelaunchCount(nil); + relaunch_rule->SetAllowPlayerRestart(true); relaunch_rule->SetLastClonkRespawn(true); // Initialize different parts of the scenario. diff --git a/planet/Missions.ocf/FrostySummit.ocs/Script.c b/planet/Missions.ocf/FrostySummit.ocs/Script.c index fcc70db70..63f271110 100644 --- a/planet/Missions.ocf/FrostySummit.ocs/Script.c +++ b/planet/Missions.ocf/FrostySummit.ocs/Script.c @@ -19,8 +19,8 @@ func Initialize() relaunch_rule->SetFreeCrew(true); relaunch_rule->SetRespawnDelay(1); relaunch_rule->SetBaseRespawn(false); - relaunch_rule->SetDefaultRelaunches(nil); - relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetDefaultRelaunchCount(nil); + relaunch_rule->SetAllowPlayerRestart(true); relaunch_rule->SetLastClonkRespawn(true); } diff --git a/planet/Missions.ocf/Raid.ocs/Script.c b/planet/Missions.ocf/Raid.ocs/Script.c index f714d89c8..48bfced9b 100644 --- a/planet/Missions.ocf/Raid.ocs/Script.c +++ b/planet/Missions.ocf/Raid.ocs/Script.c @@ -31,8 +31,8 @@ func Initialize() relaunch_rule->SetFreeCrew(true); relaunch_rule->SetRespawnDelay(1); relaunch_rule->SetBaseRespawn(true); - relaunch_rule->SetDefaultRelaunches(nil); - relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetDefaultRelaunchCount(nil); + relaunch_rule->SetAllowPlayerRestart(true); relaunch_rule->SetLastClonkRespawn(true); npc_newton->SetAlternativeSkin("MaleBlackHair"); npc_pyrit->SetAlternativeSkin("MaleBrownHair"); diff --git a/planet/Missions.ocf/TreasureHunt.ocs/Script.c b/planet/Missions.ocf/TreasureHunt.ocs/Script.c index b859aa722..c00e7794b 100644 --- a/planet/Missions.ocf/TreasureHunt.ocs/Script.c +++ b/planet/Missions.ocf/TreasureHunt.ocs/Script.c @@ -20,8 +20,8 @@ func DoInit(int first_player) relaunch_rule->SetFreeCrew(true); relaunch_rule->SetRespawnDelay(1); relaunch_rule->SetBaseRespawn(true); - relaunch_rule->SetDefaultRelaunches(nil); - relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetDefaultRelaunchCount(nil); + relaunch_rule->SetAllowPlayerRestart(true); relaunch_rule->SetLastClonkRespawn(true); ClearFreeRect(530,1135, 50,2); if (g_last_stone_door) g_last_stone_door->DoDamage(170 - g_last_stone_door->GetDamage()); diff --git a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c index c6c639c6a..6918ec70b 100644 --- a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c @@ -21,8 +21,8 @@ protected func Initialize() var relaunch_rule = GetRelaunchRule(); relaunch_rule->SetRespawnDelay(0); - relaunch_rule->SetDefaultRelaunches(nil); - relaunch_rule->AllowPlayerRestart(); + relaunch_rule->SetDefaultRelaunchCount(nil); + relaunch_rule->SetAllowPlayerRestart(true); relaunch_rule.FindRelaunchPos = GetID().FindRelaunchPos; // init scoreboard diff --git a/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c index a7c4b489e..e10e84bc7 100644 --- a/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c @@ -23,7 +23,7 @@ func Initialize() } maxkills = GameCall("WinKillCount"); if(maxkills == nil || maxkills < 1) maxkills = 4; - GetRelaunchRule()->SetDefaultRelaunches(nil); + GetRelaunchRule()->SetDefaultRelaunchCount(nil); return _inherited(...); } diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Script.c index 78c48873a..5a1663b7c 100644 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Script.c @@ -58,7 +58,7 @@ protected func RelaunchPlayer(int plr, int killer) if (!(GetPlayerTeam(killer) && GetPlayerTeam(killer) == GetPlayerTeam(plr))) if (KillsToRelaunch() && !(GetKillCount(killer) % KillsToRelaunch()) && GetKillCount(killer)) { - DoRelaunchCount(killer, 1); + GetRelaunchRule()->DoPlayerRelaunchCount(killer, 1); Log("$MsgRelaunchGained$", GetPlayerName(killer)); } diff --git a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c index ae769fdd5..f3a814f4e 100644 --- a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c @@ -57,7 +57,7 @@ protected func Initialize(...) private func EnsureRestartRule() { var relaunch = GetRelaunchRule(); - relaunch->AllowPlayerRestart(); + relaunch->SetAllowPlayerRestart(true); relaunch->SetPerformRestart(false); return true; } diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Script.c index 15afb2b31..db0013ff6 100644 --- a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Script.c @@ -16,7 +16,7 @@ protected func Initialize() { // init scoreboard // init scoreboard, uses the condition of Scoreboard_Deaths too - if(UnlimitedRelaunches()) return; + if (GetRelaunchRule()->HasUnlimitedRelaunches()) return; Scoreboard->Init( [{key = "relaunches", title = Scoreboard_Relaunch, sorted = true, desc = true, default = "", priority = 75, conditional = Scoreboard_Death.ScoreboardCondition}] ); @@ -25,16 +25,16 @@ protected func Initialize() protected func InitializePlayer(int plr) { - if(UnlimitedRelaunches()) return; + if (GetRelaunchRule()->HasUnlimitedRelaunches()) return; Scoreboard->NewPlayerEntry(plr); - Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchCount(plr)); + Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule()->GetPlayerRelaunchCount(plr)); return _inherited(plr, ...); } protected func RelaunchPlayer(int plr, int killer) { - if(UnlimitedRelaunches()) return; - Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchCount(plr)); + if (GetRelaunchRule()->HasUnlimitedRelaunches()) return; + Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule()->GetPlayerRelaunchCount(plr)); return _inherited(plr, killer, ...); } diff --git a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c index ef5079937..5f92a00bf 100644 --- a/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/BaseRespawn.ocd/Script.c @@ -2,6 +2,9 @@ protected func Construction() { - GetRelaunchRule()->SetBaseRespawn(true); + var relaunch_rule = GetRelaunchRule(); + relaunch_rule->SetBaseRespawn(true); + relaunch_rule->SetFreeCrew(false); + relaunch_rule->SetLastClonkRespawn(true); return RemoveObject(); } \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c index db5c9c0a3..abf5a935b 100644 --- a/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c @@ -42,7 +42,7 @@ func OnClonkDeathEx(object clonk, int plr, int killed_by) log=Format(Translate(Format("Teamkill%d", which_one)), GetTaggedPlayerName(plr), name, GetTaggedPlayerName(killed_by)); else log=Format(Translate(Format("KilledByPlayer%d", which_one)), GetTaggedPlayerName(plr), name, GetTaggedPlayerName(killed_by)); - var relaunches = GetRelaunchCount(plr); + var relaunches = GetRelaunchRule()->GetPlayerRelaunchCount(plr); if(relaunches != nil) { var msg=""; diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c index fbe57750c..0c543482b 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c @@ -88,15 +88,16 @@ func FxIntTimeLimitTimer(object target, effect, int fxtime) public func OnWeaponSelected(id weapon) { - if(!crew) return; - GiveWeapon(weapon); - if(GetRelaunchRule().disable_last_weapon) GetRelaunchRule().last_used_player_weapons[crew->GetOwner()] = weapon; + if (!crew) return; + GiveWeapon(weapon); + if (GetRelaunchRule().disable_last_weapon) + GetRelaunchRule().last_used_player_weapons[crew->GetOwner()] = weapon; has_selected = true; // Close menu manually, to prevent selecting more weapons. if (menu) menu->Close(); - if (!GetRelaunchRule().hold) + if (!GetRelaunchRule()->GetHolding()) RelaunchClonk(); return true; } diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index 006835d84..537e814d6 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -1,30 +1,154 @@ /** Relaunch Rule - This rule enables and handles relaunches. + This rule enables and handles relaunches with its various aspects. These are: + * SetInventoryTransfer(bool transfer): inventory of crew is transferred on respawn [default false]. + * SetFreeCrew(bool free): whether the crew is free or needs to be bought [default false]. + * SetBaseRespawn(bool set): whether to respawn at a nearby base [default false]. + * SetLastClonkRespawn(bool b): whether to respawn the last clonk only [default false]. + * SetRespawnDelay(int delay): respawn delay in seconds [default 10]. + * SetAllowPlayerRestart(bool on): whether a player can select restart in the rule menu. + * SetPerformRestart(bool on): whether this rule actually handles the respawn [default true]. + * SetDefaultRelaunchCount(int r): the number of relaunches a player has [default nil == infinte]. + The active relaunch rule can be obtained by the global function GetRelaunchRule(). The rule also + keeps track of player's actual number of relaunches which can be modified and accessed by: + * SetPlayerRelaunchCount(int plr, int value): set player relaunch count. + * GetPlayerRelaunchCount(int plr): get player relaunch count. + * DoPlayerRelaunchCount(int plr, int value): add to player relaunch count. + * HasUnlimitedRelaunches(): whether the players have infinite relaunches. + @author Maikel, Sven2, Fulgen */ + +/*-- Settings --*/ + // Determines whether the inventory of the crew member is transfered upon respawn. local inventory_transfer = false; + +public func SetInventoryTransfer(bool transfer) +{ + inventory_transfer = transfer; + return this; +} + +public func GetInventoryTransfer() { return inventory_transfer; } + + // Determines whether a crew member needs to be bought. local free_crew = true; + +public func SetFreeCrew(bool free) +{ + free_crew = free; + return this; +} + +public func GetFreeCrew() { return free_crew; } + + // Determines whether the clonk will be respawned at the base. local respawn_at_base = false; + +public func SetBaseRespawn(bool set) +{ + respawn_at_base = set; + return this; +} + +public func GetBaseRespawn() { return respawn_at_base; } + + // Determines whether only the last clonk gets respawned. local respawn_last_clonk = false; +public func SetLastClonkRespawn(bool b) +{ + respawn_last_clonk = b; + return this; +} + +public func GetLastClonkRespawn() { return respawn_last_clonk; } + + +// Determines the amount of time in the relaunch container. +local relaunch_time = 36 * 10; + +public func SetRespawnDelay(int delay) +{ + relaunch_time = delay * 36; + return this; +} + +public func GetRespawnDelay() { return relaunch_time / 36; } + + +// Determines whether a player can select to restart in a round via the rule menu. +local allow_restart_player = false; +public func SetAllowPlayerRestart(bool on) +{ + allow_restart_player = on; + return this; +} + +public func GetAllowPlayerRestart() { return allow_restart_player; } + + +// Determines whether a relaunch is performed by the rule. +local perform_restart = true; + +public func SetPerformRestart(bool on) +{ + perform_restart = on; + return this; +} + +public func GetPerformRestart() { return perform_restart; } + + +// Determines the default relaunch count. local default_relaunch_count = nil; local relaunches = []; -local clonk_type = Clonk; +public func SetDefaultRelaunchCount(int r) +{ + default_relaunch_count = r; + return this; +} +public func GetDefaultRelaunchCount() { return default_relaunch_count; } + + +// Determines ... +local hold = false; + +public func SetHolding(bool b) +{ + hold = b; + return this; +} + +public func GetHolding() { return hold; } + + +// Determines ... local disable_last_weapon = false; local last_used_player_weapons = []; -local relaunch_time = 36 * 10; -local hold = false; -local allow_restart_player = false; + +public func SetLastWeaponUse(bool use) +{ + disable_last_weapon = !use; + return this; +} + +public func GetLastWeaponUse() { return disable_last_weapon; } + + +// Not modifiable at the moment. local respawn_script_players = false; -local perform_restart = true; +local clonk_type = Clonk; + + +/*-- Rule Code --*/ public func Activate(int plr) { @@ -41,14 +165,15 @@ public func Activate(int plr) clonk->Kill(clonk, true); clonk->RemoveObject(); } + return; } -protected func Initialize() +public func Initialize() { ScheduleCall(this, this.CheckDescription, 1, 1); if (GetScenarioVal("Mode", "Game") == "Melee") default_relaunch_count = 5; - return true; + return; } private func CheckDescription() @@ -75,105 +200,6 @@ private func CheckDescription() return true; } -public func SetInventoryTransfer(bool transfer) -{ - inventory_transfer = transfer; - return this; -} - -public func GetInventoryTransfer() -{ - return inventory_transfer; -} - -public func SetFreeCrew(bool free) -{ - free_crew = free; - return this; -} - -public func GetFreeCrew() -{ - return free_crew; -} - -public func SetRespawnDelay(int delay) -{ - relaunch_time = delay * 36; - return this; -} - -public func GetRespawnDelay() -{ - return relaunch_time / 36; -} - -public func SetHolding(bool b) -{ - hold = b; - return this; -} - -public func GetHolding() -{ - return hold; -} - -public func SetLastWeaponUse(bool use) -{ - this.disable_last_weapon = !use; - return this; -} - -public func GetLastWeaponUse() -{ - return disable_last_weapon; -} - -public func SetBaseRespawn(bool set) -{ - respawn_at_base = set; - return this; -} - -public func GetBaseRespawn() -{ - return respawn_at_base; -} - -public func SetDefaultRelaunches(int r) -{ - default_relaunch_count = r; -} - -public func SetLastClonkRespawn(bool b) -{ - respawn_last_clonk = b; - return this; -} - -public func AllowPlayerRestart() -{ - allow_restart_player = true; - return this; -} - -public func DisallowPlayerRestart() -{ - allow_restart_player = false; - return this; -} - -public func GetLastClonkRespawn() -{ - return respawn_last_clonk; -} - -public func SetPerformRestart(bool on) -{ - perform_restart = on; -} - public func InitializePlayer(int plr) { _inherited(plr, ...); @@ -193,7 +219,7 @@ public func OnClonkDeath(object clonk, int killer) if (default_relaunch_count != nil) { relaunches[plr]--; - if(relaunches[plr] < 0) + if (relaunches[plr] < 0) { EliminatePlayer(plr); return; @@ -208,8 +234,9 @@ public func OnClonkDeath(object clonk, int killer) private func RespawnAtBase(int plr, object clonk) { var base = GetRelaunchBase(plr, clonk); - if (base) + if (base) return [base->GetX(), base->GetY() + base->GetDefHeight() / 2]; + return; } private func TransferInventory(object from, object to) @@ -269,10 +296,9 @@ public func DoRelaunch(int plr, object clonk, array position, bool no_creation) if (GetType(position) == C4V_Array) { if (GetType(position[0]) == C4V_Array) - { spawn = position[Random(GetLength(position))]; - } - else spawn = position; + else + spawn = position; } // If no spawn has been found set it to the middle of the landscape, this should not happen. spawn = spawn ?? [LandscapeWidth() / 2, LandscapeHeight() / 2]; @@ -290,17 +316,16 @@ public func DoRelaunch(int plr, object clonk, array position, bool no_creation) else { var base = GetRelaunchBase(); - if (!base) return; + if (!base) + return; // Try to buy a crew member at the base. var pay_plr = base->GetOwner(); // Payment in neutral bases by clonk owner. if (pay_plr == NO_OWNER) - pay_plr = plr; + pay_plr = plr; new_clonk = base->~DoBuy(clonk_type, plr, pay_plr, clonk); if (new_clonk) - { new_clonk->Exit(); - } } } else @@ -321,7 +346,7 @@ public func DoRelaunch(int plr, object clonk, array position, bool no_creation) if (relaunch_time) { - var container = new_clonk->CreateObject(RelaunchContainer, nil, nil, plr); + var container = new_clonk->CreateObject(RelaunchContainer, 0, 0, plr); container->StartRelaunch(new_clonk); } return true; @@ -336,7 +361,7 @@ protected func FindRelaunchPos(int plr) } -/*-- Scenario saving --*/ +/*-- Scenario Saving --*/ public func SaveScenarioObject(props, ...) { @@ -357,41 +382,47 @@ public func SaveScenarioObject(props, ...) /*-- Globals --*/ -global func SetRelaunchCount(int plr, int value) -{ - if(UnlimitedRelaunches()) return; - GetRelaunchRule().relaunches[plr] = value; - Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().relaunches[plr]); - return value; -} - -global func GetRelaunchCount(int plr) -{ - return GetRelaunchRule().relaunches[plr]; -} - -global func DoRelaunchCount(int plr, int value) -{ - if(UnlimitedRelaunches()) return; - GetRelaunchRule().relaunches[plr] += value; - Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().relaunches[plr]); - return; -} - -global func UnlimitedRelaunches() -{ - return GetRelaunchRule().default_relaunch_count == nil; -} - +// Returns the active relaunch rule, creates one if no exists. global func GetRelaunchRule() { return FindObject(Find_ID(Rule_Relaunch)) || CreateObject(Rule_Relaunch); } +/*-- Player Relaunches --*/ + +public func SetPlayerRelaunchCount(int plr, int value) +{ + if (HasUnlimitedRelaunches()) + return; + relaunches[plr] = value; + Scoreboard->SetPlayerData(plr, "relaunches", relaunches[plr]); + return; +} + +public func GetPlayerRelaunchCount(int plr) +{ + return relaunches[plr]; +} + +public func DoPlayerRelaunchCount(int plr, int value) +{ + if(HasUnlimitedRelaunches()) + return; + relaunches[plr] += value; + Scoreboard->SetPlayerData(plr, "relaunches", relaunches[plr]); + return; +} + +public func HasUnlimitedRelaunches() +{ + return default_relaunch_count == nil; +} + + /*-- Editor --*/ -public func Definition(def) +public func Definition(proplist def) { if (!def.EditorProps) def.EditorProps = {}; def.EditorProps.inventory_transfer = { Name="$InventoryTransfer$", EditorHelp="$InventoryTransferHelp$", Type="bool", Set="SetInventoryTransfer" }; @@ -421,7 +452,7 @@ public func Definition(def) Name = "$RelaunchCount$", EditorHelp = "$RelaunchCountHelp$", Type = "int", - Set = "SetDefaultRelaunches" + Set = "SetDefaultRelaunchCount" }; } diff --git a/planet/Parkour.ocf/Aerobatics.ocs/Script.c b/planet/Parkour.ocf/Aerobatics.ocs/Script.c index f174c7d5b..d185739f0 100644 --- a/planet/Parkour.ocf/Aerobatics.ocs/Script.c +++ b/planet/Parkour.ocf/Aerobatics.ocs/Script.c @@ -42,9 +42,6 @@ protected func Initialize() // Rules: no power and restart with keeping inventory. CreateObject(Rule_NoPowerNeed); - //GetRelaunchRule() - // ->AllowPlayerRestart() - // ->SetInventoryTransfer(true); // Initialize parts of the scenario. var amount = BoundBy(SCENPAR_NrCheckPoints, 6, 20); diff --git a/planet/Parkour.ocf/Boomshire.ocs/Script.c b/planet/Parkour.ocf/Boomshire.ocs/Script.c index 4a5d78c76..5f7c55f2a 100644 --- a/planet/Parkour.ocf/Boomshire.ocs/Script.c +++ b/planet/Parkour.ocf/Boomshire.ocs/Script.c @@ -2,8 +2,7 @@ private func Initialize() { - GetRelaunchRule() - ->AllowPlayerRestart(); + GetRelaunchRule()->SetAllowPlayerRestart(true); // Create dynamite below the first lava basin DrawMaterialQuad("Tunnel",1378,1327-5,1860,1327-5,1860,1330,1387,1330,1); From cc480be3ebcd07f913aa283bcce6a6b5b890be8a Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Mon, 1 May 2017 11:46:34 +0200 Subject: [PATCH 83/93] relaunch rule: add option to prevent round start relaunch --- planet/Arena.ocf/DarkMine.ocs/Script.c | 6 ++-- planet/Defense.ocf/KingOfTheHill.ocs/Script.c | 1 + planet/Missions.ocf/DarkCastle.ocs/Script.c | 8 ++--- .../Missions.ocf/DeepSeaMining.ocs/Script.c | 6 +--- planet/Missions.ocf/Raid.ocs/Script.c | 6 +--- planet/Missions.ocf/TreasureHunt.ocs/Script.c | 6 +--- .../Rules.ocd/Relaunch.ocd/Script.c | 30 ++++++++++++++----- 7 files changed, 32 insertions(+), 31 deletions(-) diff --git a/planet/Arena.ocf/DarkMine.ocs/Script.c b/planet/Arena.ocf/DarkMine.ocs/Script.c index 7913eda4d..5c27c246e 100644 --- a/planet/Arena.ocf/DarkMine.ocs/Script.c +++ b/planet/Arena.ocf/DarkMine.ocs/Script.c @@ -38,7 +38,8 @@ protected func Initialize() GetRelaunchRule() ->SetLastWeaponUse(false) - ->SetFreeCrew(true); + ->SetFreeCrew(true) + ->SetRespawnDelay(4); // Rescale cave coordinates with map zoom and shuffle them. var mapzoom = GetScenarioVal("MapZoom", "Landscape"); @@ -84,7 +85,8 @@ public func OnClonkLeftRelaunch(object clonk, int plr) { // Players start in a random small cave, the cave depends on whether it is a relaunch. var cave = [clonk->GetX(), clonk->GetY()]; - for (var i=0; i<4; ++i) BlastFree(cave[0], cave[1], 13); + for (var i = 0; i < 4; ++i) + BlastFree(cave[0], cave[1], 13); // Players start with a shovel, a pickaxe and two firestones. clonk->CreateContents(Shovel); diff --git a/planet/Defense.ocf/KingOfTheHill.ocs/Script.c b/planet/Defense.ocf/KingOfTheHill.ocs/Script.c index 964fbf0ec..455801517 100644 --- a/planet/Defense.ocf/KingOfTheHill.ocs/Script.c +++ b/planet/Defense.ocf/KingOfTheHill.ocs/Script.c @@ -19,6 +19,7 @@ protected func Initialize() relaunch_rule->SetBaseRespawn(true); relaunch_rule->SetFreeCrew(false); relaunch_rule->SetLastClonkRespawn(true); + relaunch_rule->SetInitialRelaunch(false); CreateObject(Rule_TeamAccount); CreateObject(Rule_NoFriendlyFire); CreateObject(Rule_Gravestones)->SetFadeOut(3 * 36); diff --git a/planet/Missions.ocf/DarkCastle.ocs/Script.c b/planet/Missions.ocf/DarkCastle.ocs/Script.c index f49271feb..3efbeff39 100644 --- a/planet/Missions.ocf/DarkCastle.ocs/Script.c +++ b/planet/Missions.ocf/DarkCastle.ocs/Script.c @@ -18,7 +18,8 @@ private func DoInit(int first_player) relaunch_rule->SetBaseRespawn(true); relaunch_rule->SetDefaultRelaunchCount(nil); relaunch_rule->SetAllowPlayerRestart(true); - relaunch_rule->SetLastClonkRespawn(true); + relaunch_rule->SetLastClonkRespawn(true); + relaunch_rule->SetInitialRelaunch(false); // Message when first player enters shroom area ScheduleCall(nil, Scenario.ShroomCaveCheck, 21, 0xffffff); // Scorching village @@ -123,9 +124,4 @@ public func OnGoalsFulfilled() GainScenarioAchievement("Done"); GainMissionAccess("S2Castle"); return false; -} - -public func OnPlayerRelaunch() -{ - return true; } \ No newline at end of file diff --git a/planet/Missions.ocf/DeepSeaMining.ocs/Script.c b/planet/Missions.ocf/DeepSeaMining.ocs/Script.c index 4fde0215b..5018d518d 100644 --- a/planet/Missions.ocf/DeepSeaMining.ocs/Script.c +++ b/planet/Missions.ocf/DeepSeaMining.ocs/Script.c @@ -41,6 +41,7 @@ protected func PostIntroInitialize() relaunch_rule->SetDefaultRelaunchCount(nil); relaunch_rule->SetAllowPlayerRestart(true); relaunch_rule->SetLastClonkRespawn(true); + relaunch_rule->SetInitialRelaunch(false); // Initialize different parts of the scenario. InitializeAmbience(); @@ -313,9 +314,4 @@ global func Particles_Smoke(...) p.DampingX = 800; } return p; -} - -public func OnPlayerRelaunch() -{ - return true; } \ No newline at end of file diff --git a/planet/Missions.ocf/Raid.ocs/Script.c b/planet/Missions.ocf/Raid.ocs/Script.c index 48bfced9b..18808b069 100644 --- a/planet/Missions.ocf/Raid.ocs/Script.c +++ b/planet/Missions.ocf/Raid.ocs/Script.c @@ -34,6 +34,7 @@ func Initialize() relaunch_rule->SetDefaultRelaunchCount(nil); relaunch_rule->SetAllowPlayerRestart(true); relaunch_rule->SetLastClonkRespawn(true); + relaunch_rule->SetInitialRelaunch(false); npc_newton->SetAlternativeSkin("MaleBlackHair"); npc_pyrit->SetAlternativeSkin("MaleBrownHair"); npc_woody->SetAlternativeSkin("Youngster"); @@ -130,8 +131,3 @@ func OnGoalsFulfilled() GainScenarioAchievement("Done"); return true; // GameOver done by outro } - -public func OnPlayerRelaunch() -{ - return true; -} diff --git a/planet/Missions.ocf/TreasureHunt.ocs/Script.c b/planet/Missions.ocf/TreasureHunt.ocs/Script.c index c00e7794b..830ad8f7f 100644 --- a/planet/Missions.ocf/TreasureHunt.ocs/Script.c +++ b/planet/Missions.ocf/TreasureHunt.ocs/Script.c @@ -23,6 +23,7 @@ func DoInit(int first_player) relaunch_rule->SetDefaultRelaunchCount(nil); relaunch_rule->SetAllowPlayerRestart(true); relaunch_rule->SetLastClonkRespawn(true); + relaunch_rule->SetInitialRelaunch(false); ClearFreeRect(530,1135, 50,2); if (g_last_stone_door) g_last_stone_door->DoDamage(170 - g_last_stone_door->GetDamage()); if (g_golden_idol) @@ -182,9 +183,4 @@ func OnInvincibleDamage(object damaged_target) } } return true; -} - -public func OnPlayerRelaunch() -{ - return true; } \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index 537e814d6..e0a483c34 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -9,6 +9,7 @@ * SetAllowPlayerRestart(bool on): whether a player can select restart in the rule menu. * SetPerformRestart(bool on): whether this rule actually handles the respawn [default true]. * SetDefaultRelaunchCount(int r): the number of relaunches a player has [default nil == infinte]. + * SetInitialRelaunch(bool on): whether a relaunch on round start is done [default true]. The active relaunch rule can be obtained by the global function GetRelaunchRule(). The rule also keeps track of player's actual number of relaunches which can be modified and accessed by: * SetPlayerRelaunchCount(int plr, int value): set player relaunch count. @@ -117,6 +118,17 @@ public func SetDefaultRelaunchCount(int r) public func GetDefaultRelaunchCount() { return default_relaunch_count; } +// Determines whether a relaunch is needed on round start. +local initial_relaunch = true; + +public func SetInitialRelaunch(bool on) +{ + initial_relaunch = on; + return this; +} + +public func GetInitialRelaunch() { return initial_relaunch; } + // Determines ... local hold = false; @@ -155,8 +167,8 @@ public func Activate(int plr) // Only restart player if enabled unless this is a definition call. if (this != Rule_Relaunch && !allow_restart_player) return MessageWindow(this.Description, plr); - // Notify scenario. - if (GameCall("OnPlayerRestart", plr)) + // Notify scenario and stop execution if handled by scenario. + if (GameCall("OnPlayerActivatedRestart", plr)) return; // Remove the player's clonk, including contents. var clonk = GetCrew(plr); @@ -203,10 +215,14 @@ private func CheckDescription() public func InitializePlayer(int plr) { _inherited(plr, ...); - // Scenario script callback. relaunches[plr] = default_relaunch_count; - if (!GameCallEx("OnPlayerRelaunch", plr, false)) - return DoRelaunch(plr, nil, nil, true); + // Check if relaunch is needed. + if (!initial_relaunch) + return; + // Scenario script callback. + if (GameCall("OnPlayerRelaunch", plr, false)) + return; + return DoRelaunch(plr, nil, nil, true); } public func OnClonkDeath(object clonk, int killer) @@ -225,9 +241,7 @@ public func OnClonkDeath(object clonk, int killer) return; } } - GameCall("OnPlayerRelaunch", plr, true); - return DoRelaunch(plr, clonk, nil); } @@ -315,7 +329,7 @@ public func DoRelaunch(int plr, object clonk, array position, bool no_creation) } else { - var base = GetRelaunchBase(); + var base = GetRelaunchBase(plr, clonk); if (!base) return; // Try to buy a crew member at the base. From 3e0f18f4f34b8b959f9a9c7d3cd639d03a0cca86 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Mon, 1 May 2017 21:26:01 +0200 Subject: [PATCH 84/93] reinstate relaunch container functionality This has been used by external scenarios and there is no reason to put this into the relaunch rule script. --- .../RelaunchContainer.ocd/Script.c | 61 +++++++++++-------- .../RelaunchContainer.ocd/StringTblDE.txt | 1 - .../RelaunchContainer.ocd/StringTblUS.txt | 1 - .../Rules.ocd/Relaunch.ocd/Script.c | 15 ++--- 4 files changed, 44 insertions(+), 34 deletions(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c index 0c543482b..e4a8cdb6e 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/Script.c @@ -10,13 +10,21 @@ local menu; local has_selected; - local crew; -// Sets the GetRelaunchRule().RelaunchTime, in seconds, the clonk is held in the container. +local hold_crew = false; +local relaunch_time = 36 * 10; -// Returns the GetRelaunchRule().RelaunchTime, in seconds the clonk is held. -public func GetRelaunchTime() { return GetRelaunchRule().relaunch_time / 36; } +// Sets the time, in seconds, the clonk is held in the container. +public func SetRelaunchTime(int to_time, bool to_hold) +{ + relaunch_time = to_time * 36; + hold_crew = to_hold; + return; +} + +// Returns the time, in seconds the clonk is held. +public func GetRelaunchTime() { return relaunch_time / 36; } // Retrieve weapon list from scenario. private func WeaponList() { return GameCall("RelaunchWeaponList"); } @@ -25,10 +33,10 @@ public func StartRelaunch(object clonk) { if (!clonk) return; - // only 1 clonk can be inside - if(crew) + // Only 1 clonk can be inside. + if (crew) return; - // save clonk for later use + // Save clonk for later use. crew = clonk; clonk->Enter(this); ScheduleCall(this, "OpenWeaponMenu", 36, 0, clonk); @@ -47,13 +55,14 @@ private func OpenWeaponMenu(object clonk) { menu = CreateObject(MenuStyle_Default, nil, nil, clonk->GetOwner()); menu->SetPermanent(); - menu->SetTitle(Format("$MsgWeapon$", GetRelaunchRule().relaunch_time / 36)); + menu->SetTitle(Format("$MsgWeapon$", relaunch_time / 36)); clonk->SetMenu(menu, true); - if(GetType(GetRelaunchRule().last_used_player_weapons) != C4V_Array) GetRelaunchRule().last_used_player_weapons = []; + if (GetType(GetRelaunchRule().last_used_player_weapons) != C4V_Array) + GetRelaunchRule().last_used_player_weapons = []; for (var weapon in weapons) { - if(GetRelaunchRule().last_used_player_weapons[clonk->GetOwner()] != weapon) + if (GetRelaunchRule().last_used_player_weapons[clonk->GetOwner()] != weapon) { menu->AddItem(weapon, weapon->GetName(), nil, this, "OnWeaponSelected", weapon); } @@ -64,40 +73,41 @@ private func OpenWeaponMenu(object clonk) } } -func FxIntTimeLimitTimer(object target, effect, int fxtime) +public func FxIntTimeLimitTimer(object target, effect fx, int fxtime) { var clonk = crew; if (!clonk) { RemoveObject(); - return -1; + return FX_Execute_Kill; } - if (fxtime >= GetRelaunchRule().relaunch_time) + if (fxtime >= relaunch_time) { if (!has_selected && WeaponList()) - GiveWeapon(WeaponList()[Random(GetLength(WeaponList()))]); + GiveWeapon(RandomElement(WeaponList())); RelaunchClonk(); - return -1; + return FX_Execute_Kill; } if (menu) - menu->SetTitle(Format("$MsgWeapon$", (GetRelaunchRule().relaunch_time - fxtime) / 36)); + menu->SetTitle(Format("$MsgWeapon$", (relaunch_time - fxtime) / 36)); else - PlayerMessage(clonk->GetOwner(), Format("$MsgRelaunch$", (GetRelaunchRule().relaunch_time - fxtime) / 36)); - return 1; + PlayerMessage(clonk->GetOwner(), Format("$MsgRelaunch$", (relaunch_time - fxtime) / 36)); + return FX_OK; } public func OnWeaponSelected(id weapon) { - if (!crew) return; - GiveWeapon(weapon); - if (GetRelaunchRule().disable_last_weapon) + if (!crew) + return; + GiveWeapon(weapon); + if (GetRelaunchRule()->GetLastWeaponUse()) GetRelaunchRule().last_used_player_weapons[crew->GetOwner()] = weapon; has_selected = true; // Close menu manually, to prevent selecting more weapons. if (menu) menu->Close(); - if (!GetRelaunchRule()->GetHolding()) + if (!hold_crew) RelaunchClonk(); return true; } @@ -105,7 +115,7 @@ public func OnWeaponSelected(id weapon) private func RelaunchClonk() { var clonk = crew; - // When relaunching from disabled state (i.e base respawn), reset view to clonk + // When relaunching from disabled state (i.e base respawn), reset view to clonk. if (!clonk->GetCrewEnabled()) { clonk->SetCrewEnabled(true); @@ -129,6 +139,7 @@ private func GiveWeapon(id weapon_id) return true; } -public func SaveScenarioObject() { return false; } -local Name = "$Name$"; +/*-- Saving --*/ + +public func SaveScenarioObject() { return false; } diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/StringTblDE.txt b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/StringTblDE.txt index babe88679..2efff7d9b 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/StringTblDE.txt @@ -1,3 +1,2 @@ -Name=Relaunch container MsgRelaunch=You will be relaunched in %d seconds. MsgWeapon=You have %d seconds to choose a weapon. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/StringTblUS.txt b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/StringTblUS.txt index 04f6fccd2..8404d35f6 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/RelaunchContainer.ocd/StringTblUS.txt @@ -1,3 +1,2 @@ -Name=Relaunch container MsgRelaunch=You will relaunch in %d seconds. MsgWeapon=You have %d seconds to choose a weapon. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index e0a483c34..4078349ff 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -130,19 +130,19 @@ public func SetInitialRelaunch(bool on) public func GetInitialRelaunch() { return initial_relaunch; } -// Determines ... -local hold = false; +// Determines whether the crew is released after weapon selection. +local hold_crew = false; -public func SetHolding(bool b) +public func SetHolding(bool hold) { - hold = b; + hold_crew = hold; return this; } -public func GetHolding() { return hold; } +public func GetHolding() { return hold_crew; } -// Determines ... +// Determines whether the player can select the last weapon again. local disable_last_weapon = false; local last_used_player_weapons = []; @@ -361,6 +361,7 @@ public func DoRelaunch(int plr, object clonk, array position, bool no_creation) if (relaunch_time) { var container = new_clonk->CreateObject(RelaunchContainer, 0, 0, plr); + container->SetRelaunchTime(relaunch_time, hold_crew); container->StartRelaunch(new_clonk); } return true; @@ -388,7 +389,7 @@ public func SaveScenarioObject(props, ...) props->AddCall("InventoryTransfer", this, "SetInventoryTransfer", inventory_transfer); if (free_crew) props->AddCall("FreeCrew", this, "SetFreeCrew", free_crew); - if(respawn_at_base) + if (respawn_at_base) props->AddCall("BaseRespawn", this, "SetBaseRespawn", respawn_at_base); return true; } From 34f736081c6cc83aaefb7430fd086aeb33fc6ad9 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Tue, 2 May 2017 14:50:27 +0200 Subject: [PATCH 85/93] fix relaunch time and unwanted initial relaunch --- planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c index 4078349ff..fcc1512df 100644 --- a/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c @@ -72,11 +72,11 @@ public func GetLastClonkRespawn() { return respawn_last_clonk; } // Determines the amount of time in the relaunch container. -local relaunch_time = 36 * 10; +local relaunch_time = 10; // seconds public func SetRespawnDelay(int delay) { - relaunch_time = delay * 36; + relaunch_time = delay; return this; } @@ -217,7 +217,7 @@ public func InitializePlayer(int plr) _inherited(plr, ...); relaunches[plr] = default_relaunch_count; // Check if relaunch is needed. - if (!initial_relaunch) + if (!initial_relaunch || !perform_restart) return; // Scenario script callback. if (GameCall("OnPlayerRelaunch", plr, false)) @@ -249,13 +249,13 @@ private func RespawnAtBase(int plr, object clonk) { var base = GetRelaunchBase(plr, clonk); if (base) - return [base->GetX(), base->GetY() + base->GetDefHeight() / 2]; + return [base->GetX(), base->GetY() + base->GetBottom()]; return; } private func TransferInventory(object from, object to) { - if(!from || !to) return; + if (!from || !to) return; // Drop some items that cannot be transferred (such as connected pipes and dynamite igniters) var i = from->ContentsCount(), contents; while (i--) @@ -352,7 +352,7 @@ public func DoRelaunch(int plr, object clonk, array position, bool no_creation) if (inventory_transfer) TransferInventory(clonk, new_clonk); - new_clonk->SetPosition(spawn[0], spawn[1], plr); + new_clonk->SetPosition(spawn[0], spawn[1] - new_clonk->GetBottom(), plr); if (!GetCursor(plr) || GetCursor(plr) == clonk) SetCursor(plr, new_clonk); @@ -360,7 +360,7 @@ public func DoRelaunch(int plr, object clonk, array position, bool no_creation) if (relaunch_time) { - var container = new_clonk->CreateObject(RelaunchContainer, 0, 0, plr); + var container = new_clonk->CreateObject(RelaunchContainer, 0, new_clonk->GetBottom(), plr); container->SetRelaunchTime(relaunch_time, hold_crew); container->StartRelaunch(new_clonk); } From 0d32d924dccfd9d0cd535242b31fed42f87ff7e3 Mon Sep 17 00:00:00 2001 From: David Dormagen Date: Tue, 2 May 2017 19:11:11 +0200 Subject: [PATCH 86/93] InteractionMenu: fix script error when custom entry extra_data contains something different from a proplist The check was only meant for inventory menus (where extra_data always is a proplist); it was not in the right if-clause below, though. --- .../ObjectInteractionMenu.ocd/Script.c | 52 +++++++++++-------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/Script.c index 704c4326e..d599ea7d7 100644 --- a/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/Script.c @@ -820,35 +820,41 @@ func OnMenuEntryHover(proplist menu_info, int entry_index, int player) if (!info.menu.callback_target || !info.menu.callback_hover) { var text = Format("%s:|%s", info.entry.symbol->GetName(), info.entry.symbol.Description); - var obj = nil; - if (info.entry.extra_data && info.entry.extra_data.objects) - { - for (var possible in info.entry.extra_data.objects) - { - if (possible == nil) continue; - obj = possible; - break; - } - } + // For contents menus, we can sometimes present additional information about objects. - if (info.menu.flag == InteractionMenu_Contents && obj) + if (info.menu.flag == InteractionMenu_Contents) { - var additional = nil; - if (obj->Contents()) + // Get the first valid object of the clicked stack. + var obj = nil; + if (info.entry.extra_data && info.entry.extra_data.objects) { - additional = "$Contains$ "; - var i = 0, count = obj->ContentsCount(); - // This currently justs lists contents one after the other. - // Items are not stacked, which should be enough for everything we have ingame right now. If this is filed into the bugtracker at some point, fix here. - for (;i < count;++i) + for (var possible in info.entry.extra_data.objects) { - if (i > 0) - additional = Format("%s, ", additional); - additional = Format("%s%s", additional, obj->Contents(i)->GetName()); + if (possible == nil) continue; + obj = possible; + break; } } - if (additional != nil) - text = Format("%s||%s", text, additional); + // ..and use that object to fetch some more information. + if (obj) + { + var additional = nil; + if (obj->Contents()) + { + additional = "$Contains$ "; + var i = 0, count = obj->ContentsCount(); + // This currently justs lists contents one after the other. + // Items are not stacked, which should be enough for everything we have ingame right now. If this is filed into the bugtracker at some point, fix here. + for (;i < count;++i) + { + if (i > 0) + additional = Format("%s, ", additional); + additional = Format("%s%s", additional, obj->Contents(i)->GetName()); + } + } + if (additional != nil) + text = Format("%s||%s", text, additional); + } } GuiUpdateText(text, current_main_menu_id, 1, current_description_box.desc_target); From ad6a986d10638d17493ad3762d4652037d4e989e Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Tue, 2 May 2017 22:50:32 +0200 Subject: [PATCH 87/93] Scripted the Hatch that Ringwaul made ages ago. Can be built on top of basements (or without) to make a vertical opening. --- planet/Experimental.ocd/Hatch.ocd/DefCore.txt | 15 -- .../Experimental.ocd/Hatch.ocd/Graphics.png | Bin 272 -> 0 bytes .../Hatch.ocd/Hatch3DGraphic.ocd/DefCore.txt | 7 - .../Hatch.ocd/Hatch3DGraphic.ocd/Script.c | 45 ---- planet/Experimental.ocd/Hatch.ocd/Script.c | 58 ---- .../Hatch.ocd/StringTblDE.txt | 1 - .../Hatch.ocd/StringTblUS.txt | 1 - .../Structures.ocd/Hatch.ocd/DefCore.txt | 15 ++ .../Structures.ocd/Hatch.ocd}/Graphics.mesh | Bin .../Structures.ocd/Hatch.ocd}/Hatch.png | Bin .../Structures.ocd/Hatch.ocd}/Hatch.skeleton | Bin .../Structures.ocd/Hatch.ocd}/Hatch2.png | Bin .../Hatch.ocd/HatchBasement.ocd/DefCore.txt | 15 ++ .../HatchBasement.ocd/Graphics.6.png | Bin 0 -> 16452 bytes .../Hatch.ocd/HatchBasement.ocd/Script.c | 18 ++ .../Hatch.ocd/HatchBasement.ocd/SolidMask.png | Bin 0 -> 2863 bytes .../HatchBasement.ocd/StringTblDE.txt | 3 + .../HatchBasement.ocd/StringTblUS.txt | 3 + .../Structures.ocd/Hatch.ocd}/Scene.material | 0 .../Structures.ocd/Hatch.ocd/Script.c | 247 ++++++++++++++++++ .../Structures.ocd/Hatch.ocd/SolidMask.png | Bin 0 -> 2818 bytes .../Structures.ocd/Hatch.ocd/StringTblDE.txt | 4 + .../Structures.ocd/Hatch.ocd/StringTblUS.txt | 4 + 23 files changed, 309 insertions(+), 127 deletions(-) delete mode 100644 planet/Experimental.ocd/Hatch.ocd/DefCore.txt delete mode 100644 planet/Experimental.ocd/Hatch.ocd/Graphics.png delete mode 100644 planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/DefCore.txt delete mode 100644 planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Script.c delete mode 100644 planet/Experimental.ocd/Hatch.ocd/Script.c delete mode 100644 planet/Experimental.ocd/Hatch.ocd/StringTblDE.txt delete mode 100644 planet/Experimental.ocd/Hatch.ocd/StringTblUS.txt create mode 100644 planet/Objects.ocd/Structures.ocd/Hatch.ocd/DefCore.txt rename planet/{Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd => Objects.ocd/Structures.ocd/Hatch.ocd}/Graphics.mesh (100%) rename planet/{Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd => Objects.ocd/Structures.ocd/Hatch.ocd}/Hatch.png (100%) rename planet/{Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd => Objects.ocd/Structures.ocd/Hatch.ocd}/Hatch.skeleton (100%) rename planet/{Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd => Objects.ocd/Structures.ocd/Hatch.ocd}/Hatch2.png (100%) create mode 100644 planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/DefCore.txt create mode 100644 planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/Graphics.6.png create mode 100644 planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/Script.c create mode 100644 planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/SolidMask.png create mode 100644 planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/StringTblDE.txt create mode 100644 planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/StringTblUS.txt rename planet/{Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd => Objects.ocd/Structures.ocd/Hatch.ocd}/Scene.material (100%) create mode 100644 planet/Objects.ocd/Structures.ocd/Hatch.ocd/Script.c create mode 100644 planet/Objects.ocd/Structures.ocd/Hatch.ocd/SolidMask.png create mode 100644 planet/Objects.ocd/Structures.ocd/Hatch.ocd/StringTblDE.txt create mode 100644 planet/Objects.ocd/Structures.ocd/Hatch.ocd/StringTblUS.txt diff --git a/planet/Experimental.ocd/Hatch.ocd/DefCore.txt b/planet/Experimental.ocd/Hatch.ocd/DefCore.txt deleted file mode 100644 index a6a473a55..000000000 --- a/planet/Experimental.ocd/Hatch.ocd/DefCore.txt +++ /dev/null @@ -1,15 +0,0 @@ -[DefCore] -id=Hatch -Version=6,0 -Category=C4D_Structure -Width=26 -Height=26 -Offset=-13,-13 -Vertices=5 -VertexX=0,-12,12,-10,10 -VertexY=0,0,0,6,6 -VertexFriction=100,100,100,100,100 -VertexCNAT=64,1,2,1,2 -SolidMask=0,0,20,20,0,0 -Construction=1 -Mass=10 diff --git a/planet/Experimental.ocd/Hatch.ocd/Graphics.png b/planet/Experimental.ocd/Hatch.ocd/Graphics.png deleted file mode 100644 index cf3abf95b71b7379920209fa0371fb86d429ced1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^CO|C3!3HFM+^b&;q!^2X+?^QKos)S9lS| zxv6<2KrRD=b5UwyNotBhd1gt5g1e`0K#E=}J5W5`)5S3);_%z)-h2lXI9y~O|6T7> zer!i(&fiDX+02p>DkshyI_Hs9CEsi;(4xSi$l>U|P}KAOw93~;M~jw6o|B2N&Gy(V zWaupKnHpX-M<}$^^!A}YMYp5#o*a!j_Rsi5csU2d0dxMnuASetAction("Attach", this); - graphic->SetHatchParent(this); - return 1; -} - -func ControlUp(object clonk) -{ - if(GetPhase() != 0) - { - graphic->Anim("Close"); - SetPhase(0); - SetSolidMask(0,0,26,26,0,0); - } -} - -func ControlDown(object clonk) -{ - if(GetPhase() != 1) - { - graphic->Anim("Open"); - SetPhase(1); - SetSolidMask(26,0,26,26,0,0); - } -} - -protected func Definition(def) -{ - SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0,-3000,-5000), Trans_Rotate(-30,1,0,0), Trans_Rotate(30,0,1,0), Trans_Translate(1000,1,0)),def); -} - -local Name = "$Name$"; -local Touchable = 2; -local ActMap = { - Hatch = { - Prototype = Action, - Name = "Hatch", - Procedure = DFA_NONE, - Directions = 1, - FlipDir = 0, - Length = 2, - Delay = 0, - X = 0, - Y = 0, - Wdt = 1, - Hgt = 1, -}, -}; diff --git a/planet/Experimental.ocd/Hatch.ocd/StringTblDE.txt b/planet/Experimental.ocd/Hatch.ocd/StringTblDE.txt deleted file mode 100644 index bf0599ad1..000000000 --- a/planet/Experimental.ocd/Hatch.ocd/StringTblDE.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Hatch diff --git a/planet/Experimental.ocd/Hatch.ocd/StringTblUS.txt b/planet/Experimental.ocd/Hatch.ocd/StringTblUS.txt deleted file mode 100644 index 166659300..000000000 --- a/planet/Experimental.ocd/Hatch.ocd/StringTblUS.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Hatch \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Hatch.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/DefCore.txt new file mode 100644 index 000000000..a9e3af5da --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/DefCore.txt @@ -0,0 +1,15 @@ +[DefCore] +id=Hatch +Version=8,0 +Category=C4D_Structure +Width=26 +Height=26 +Offset=-13,-13 +Vertices=4 +VertexX=-12,-12,12,12 +VertexY=-3,3,-3,3 +VertexFriction=100,100,100,100 +SolidMask=0,0,26,4,0,11 +Construction=1 +Mass=1000 +Exclusive=1 \ No newline at end of file diff --git a/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Graphics.mesh b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/Graphics.mesh similarity index 100% rename from planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Graphics.mesh rename to planet/Objects.ocd/Structures.ocd/Hatch.ocd/Graphics.mesh diff --git a/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch.png b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/Hatch.png similarity index 100% rename from planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch.png rename to planet/Objects.ocd/Structures.ocd/Hatch.ocd/Hatch.png diff --git a/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch.skeleton b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/Hatch.skeleton similarity index 100% rename from planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch.skeleton rename to planet/Objects.ocd/Structures.ocd/Hatch.ocd/Hatch.skeleton diff --git a/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch2.png b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/Hatch2.png similarity index 100% rename from planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch2.png rename to planet/Objects.ocd/Structures.ocd/Hatch.ocd/Hatch2.png diff --git a/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/DefCore.txt new file mode 100644 index 000000000..7353370fa --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/DefCore.txt @@ -0,0 +1,15 @@ +[DefCore] +id=HatchBasement +Version=8,0 +Category=C4D_Structure +Width=40 +Height=8 +Offset=-20,-4 +Vertices=5 +VertexX=0,-20,-20,20,20 +VertexY=0,-4,4,-4,4 +VertexFriction=100,100,100,100,100 +Mass=2000 +Exclusive=1 +Construction=1 +SolidMask=0,0,40,8,0,0 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/Graphics.6.png b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/Graphics.6.png new file mode 100644 index 0000000000000000000000000000000000000000..67fd7604b92ad2c5d6bb6cb019bff6a2a448639f GIT binary patch literal 16452 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 literal 0 HcmV?d00001 diff --git a/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/Script.c new file mode 100644 index 000000000..5698664ef --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/Script.c @@ -0,0 +1,18 @@ +/** + Basement + Provides basements to structures, but can also be built as a single object. + + @author: Maikel +*/ + +#include Basement + +public func IsHammerBuildable() { return false; } + +/*-- Properties --*/ + +local Name = "$Name$"; +local Description ="$Description$"; +local HitPoints = 80; +local Plane = 190; +local Components = {Rock = 2}; diff --git a/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/SolidMask.png b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/SolidMask.png new file mode 100644 index 0000000000000000000000000000000000000000..cf8c2f35dd7966686b21d1407ac0a9fcf3dede05 GIT binary patch literal 2863 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 N002ovPDHLkV1h-EMS%bS literal 0 HcmV?d00001 diff --git a/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/StringTblDE.txt new file mode 100644 index 000000000..2af728280 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/StringTblDE.txt @@ -0,0 +1,3 @@ +Name=Fundament +Description=Eine stabile Basis für Gebäude. +Width=Breite \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/StringTblUS.txt new file mode 100644 index 000000000..05020e136 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/HatchBasement.ocd/StringTblUS.txt @@ -0,0 +1,3 @@ +Name=Basement +Description=A stable base for any building. +Width=Width \ No newline at end of file diff --git a/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/Scene.material similarity index 100% rename from planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Scene.material rename to planet/Objects.ocd/Structures.ocd/Hatch.ocd/Scene.material diff --git a/planet/Objects.ocd/Structures.ocd/Hatch.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/Script.c new file mode 100644 index 000000000..a8b573fa4 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/Script.c @@ -0,0 +1,247 @@ +/* + Hatch + + @authors: Clonkonaut, Ringwaul (Graphics) +*/ + +#include Library_Structure + +local opened = false; + +/*-- Engine Callbacks --*/ + +func Construction() +{ + SetProperty("MeshTransformation", Trans_Mul(Trans_Translate(0,-10000), Trans_Rotate(-10,0,1,0), Trans_Rotate(-8,1,0,0))); + SetCategory(C4D_StaticBack); + + return _inherited(...); +} + +/*-- Callbacks --*/ + +public func IsHammerBuildable() { return true; } + +public func DoConstructionEffects(object construction_site) +{ + // The hatch sets itself a bit lower after it has been placed with the construction previewer + SetPosition(GetX(), GetY()+4); + return false; +} + +public func NoConstructionFlip() { return true; } + +public func ConstructionCombineWith() { return "IsBasement"; } + +public func ConstructionCombineDirection(object other) { return CONSTRUCTION_STICK_Top; } + +public func ConstructionCombineOffset(object other) +{ + return [0, 0]; +} + +public func CombineWith(object stick_to) +{ + if (stick_to && stick_to->~IsBasement()) + stick_to->SetParent(this); + + SetPosition(GetX(), GetY()+1); +} + +/*-- Library overloads --*/ + +func MoveOutOfSolidMask() +{ + // Find all objects inside the solid mask which are stuck. + var lying_around = FindObjects(Find_Or(Find_Category(C4D_Vehicle), Find_Category(C4D_Object), Find_Category(C4D_Living)), Find_InRect(-13, -2, 26, 4), Find_NoContainer()); + // Move up these objects. + for (var obj in lying_around) + { + var x = obj->GetX(); + var y = obj->GetY(); + var delta_y = 0; + var max_delta = obj->GetObjHeight(); + // Move up object until it is not stuck any more. + while (obj->Stuck() || obj->GetContact(-1, CNAT_Bottom)) + { + // Only move up the object by at most its height plus the basements height. + if (delta_y > max_delta) + { + obj->SetPosition(x, y); + break; + } + delta_y++; + obj->SetPosition(x, y - delta_y); + } + } +} + +/*-- Basement --*/ + +public func GetBasementWidth() +{ + return 40; +} + +public func SetBasement(object to_basement) +{ + _inherited(to_basement); + + if (!to_basement) return; + + to_basement->ChangeDef(HatchBasement); +} + +public func GetBasementOffset() { return [0, -15]; } + +/*-- Interaction --*/ + +public func IsInteractable(object clonk) +{ + if (GetCon() < 100) + return false; + if (opened && FindClonkInHatchArea()) + return false; + + if (Hostile(clonk->GetOwner(), GetOwner())) + return false; + + return true; +} + +public func GetInteractionMetaInfo(object clonk) +{ + if (!ActIdle()) + return { Description = "$Close$", IconName = nil, IconID = Icon_Exit, Selected = false }; + return { Description = "$Open$", IconName = nil, IconID = Icon_Enter, Selected = false }; +} + +public func Interact(object clonk) +{ + if (ActIdle()) + return DoOpen(); + if (GetAction() == "Open") + return DoClose(); + return false; +} + +/*-- Open/Close --*/ + +public func DoOpen() +{ + SetAction("Open"); + Sound("Structures::DoorOpen?"); + return true; +} + +public func DoClose() +{ + if (opened) + { + if (FindClonkInHatchArea()) + return false; + SetAction("Close"); + Sound("Structures::DoorClose?"); + opened = false; + return true; + } + if (GetAction() == "Open") + { + var phase = 2 - GetPhase(); + SetAction("Close"); + Sound("Structures::DoorClose?"); + SetPhase(phase); + return true; + } + SetAction("Close"); + Sound("Structures::DoorClose?"); + return true; +} + +func FindClonkInHatchArea() +{ + return FindObject(Find_InRect(-16, -12, 32, 24), Find_OCF(OCF_CrewMember), Find_OCF(OCF_Alive), Find_AnyLayer(), Find_NoContainer()); +} + +func ChangeSolidMask() +{ + if (opened) + return; + if (GetAction() == "Close") // Upon closing, the solid mask must reappear instantaneously + // to prevent clonks from getting stuck + return SetSolidMask(0,0, 26,4, 0,11); + + var phase = GetPhase(); + var width = 26 - 8*phase; + + if (phase == 3) { + ClosingTimer(); + width -= 2; + } + + SetSolidMask(0,0, width,4, 0,11); +} + +func ClosingTimer() +{ + opened = true; + + ScheduleCall(this, "CheckForClose", 15); +} + +func CheckForClose() +{ + if (GetAction() == "Close" || ActIdle()) + return; + + if (!FindClonkInHatchArea()) + return ScheduleCall(this, "CloseForReal", 25); + + ScheduleCall(this, "CheckForClose", 5); +} + +func CloseForReal() +{ + // One final check that the hatch is clear + if (FindClonkInHatchArea()) + return ScheduleCall(this, "CheckForClose", 5); + + DoClose(); +} + +/*-- Display --*/ + +func Definition(def) +{ + SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0,-3000,-5000), Trans_Rotate(-30,1,0,0), Trans_Rotate(30,0,1,0), Trans_Translate(1000,1,0)), def); + return _inherited(def); +} + +/*-- Properties --*/ + +local ActMap = { + Open = { + Prototype = Action, + Name = "Open", + Length = 3, + Delay = 5, + Animation = "Open", + NextAction = "Hold", + PhaseCall = "ChangeSolidMask" + }, + Close = { + Prototype = Action, + Name = "Close", + Length = 3, + Delay = 5, + Animation = "Close", + NextAction = "Idle", + PhaseCall = "ChangeSolidMask" + }, +}; + +local Name = "$Name$"; +local Description = "$Description$"; +local BlastIncinerate = 100; +local HitPoints = 70; +local Components = {Wood = 2}; diff --git a/planet/Objects.ocd/Structures.ocd/Hatch.ocd/SolidMask.png b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/SolidMask.png new file mode 100644 index 0000000000000000000000000000000000000000..ea79858e63ed399e25afbcab8936c3f279e4aed7 GIT binary patch literal 2818 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 Date: Tue, 2 May 2017 22:53:49 +0200 Subject: [PATCH 88/93] New decoration object: tunnel support (graphics by Ringwaul, from a long time ago). Can be stretched using the Extend() function. --- .../Village.ocd/TunnelSupport.ocd/DefCore.txt | 7 +++ .../TunnelSupport.ocd/Graphics.mesh | Bin 0 -> 32818 bytes .../TunnelSupport.ocd/Scene.material | 21 +++++++++ .../Village.ocd/TunnelSupport.ocd/Script.c | 43 ++++++++++++++++++ .../TunnelSupport.ocd/StringTblDE.txt | 1 + .../TunnelSupport.ocd/StringTblUS.txt | 1 + .../TunnelSupport.ocd/TunnelSupport.png | Bin 0 -> 85558 bytes .../TunnelSupport.ocd/TunnelSupport.skeleton | Bin 0 -> 2594 bytes 8 files changed, 73 insertions(+) create mode 100644 planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/DefCore.txt create mode 100644 planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/Graphics.mesh create mode 100644 planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/Scene.material create mode 100644 planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/Script.c create mode 100644 planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/StringTblDE.txt create mode 100644 planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/StringTblUS.txt create mode 100644 planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/TunnelSupport.png create mode 100644 planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/TunnelSupport.skeleton diff --git a/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/DefCore.txt b/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/DefCore.txt new file mode 100644 index 000000000..bceac4aa1 --- /dev/null +++ b/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=Deco_TunnelSupport +Version=8,0 +Category=C4D_StaticBack +Width=30 +Height=30 +Offset=-15,-15 \ No newline at end of file diff --git a/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/Graphics.mesh b/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/Graphics.mesh new file mode 100644 index 0000000000000000000000000000000000000000..a5357faf74617684cd3c7fde546a01ab4d6ebf9f GIT binary patch literal 32818 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 UatsD#43=RJE+Bhx0j1Rc0TEU6!TAddCall("Extension", this, "Extend", extension); + return true; +} + +/*-- Properties --*/ + +local Name = "$Name$"; +local Plane = 701; \ No newline at end of file diff --git a/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/StringTblDE.txt b/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/StringTblDE.txt new file mode 100644 index 000000000..96f273078 --- /dev/null +++ b/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Tunnelstütze \ No newline at end of file diff --git a/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/StringTblUS.txt b/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/StringTblUS.txt new file mode 100644 index 000000000..050b08fb9 --- /dev/null +++ b/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Tunnel support \ No newline at end of file diff --git a/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/TunnelSupport.png b/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/TunnelSupport.png new file mode 100644 index 0000000000000000000000000000000000000000..5fe1c1630b252396bf4af401b6af2e942dce8054 GIT binary patch literal 85558 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ℑ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

Rp}!&$c2AA=n1@2RNK*P|i_wsYkMdb2>S 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 literal 0 HcmV?d00001 diff --git a/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/TunnelSupport.skeleton b/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/TunnelSupport.skeleton new file mode 100644 index 0000000000000000000000000000000000000000..66a3891149fbca66fe1ba1333fa1244659dc8895 GIT binary patch literal 2594 zcma*pUr19?90%~@n5Gw@4K7p=DrBV~Vwuy2Zf@egz#uhH=tgPIy5*)04gb6pY(0pu z7kg0B7n6F(Aq25KSh+AEX3*0JqF7KqIKh`?^wjU}e&;sWIdmR&&(8gvbM8Io{(ko| z%k^%jN9!BXrktLe56)FL)ZCCPmO_>+W#x2e9(TDWyM~9ynugs@$vBbw_hBPT_HgxS zZYeLz6y?`7rW(GPsh)%_6Jt*IfYT$HlIPazAJ}b`Gy=nXBTOdBeEJcxRBS&K}56 z+mQ%YUGbiV3be(zYSC(gqE+Q8T2-iENq*MuruI?4N2RIlN1)1~e7m0ossc)pq5@R~ z^}FJ$K-EA|mJ_H8P=kZN1gZh5)VG^cQI@0Kz6cdv-WMo46y;TcYKCf${S~NoD2i5l zI%4%&Dr)uX>VQ)HCcAzvT{6{GD9Ysaw9spr>Kc?BI3iHJP@{?@P%6}Rq*$PCLD9QI zpa!6PyH+v-15SFpsvvWl^)*<&TYq6F$6qRo#Q literal 0 HcmV?d00001 From 861b0bc08e44657bb915ceadb71910d3b6dc28f9 Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Tue, 2 May 2017 22:57:01 +0200 Subject: [PATCH 89/93] Added a simple static ladder to be used by scenario designers. This thing is a lot faster than the rope ladder. --- .../Structures.ocd/Ladder.ocd/DefCore.txt | 11 ++ .../Structures.ocd/Ladder.ocd/Graphics.png | Bin 0 -> 2828 bytes .../Ladder.ocd/LadderPart.ocd/DefCore.txt | 8 ++ .../Ladder.ocd/LadderPart.ocd/Graphics.10.png | Bin 0 -> 6059 bytes .../LadderPart.ocd/GraphicsBottom.10.png | Bin 0 -> 5730 bytes .../LadderPart.ocd/GraphicsTop.10.png | Bin 0 -> 6659 bytes .../Ladder.ocd/LadderPart.ocd/Script.c | 100 ++++++++++++++++++ .../Structures.ocd/Ladder.ocd/Script.c | 84 +++++++++++++++ .../Structures.ocd/Ladder.ocd/StringTblDE.txt | 1 + .../Structures.ocd/Ladder.ocd/StringTblUS.txt | 1 + 10 files changed, 205 insertions(+) create mode 100644 planet/Objects.ocd/Structures.ocd/Ladder.ocd/DefCore.txt create mode 100644 planet/Objects.ocd/Structures.ocd/Ladder.ocd/Graphics.png create mode 100644 planet/Objects.ocd/Structures.ocd/Ladder.ocd/LadderPart.ocd/DefCore.txt create mode 100644 planet/Objects.ocd/Structures.ocd/Ladder.ocd/LadderPart.ocd/Graphics.10.png create mode 100644 planet/Objects.ocd/Structures.ocd/Ladder.ocd/LadderPart.ocd/GraphicsBottom.10.png create mode 100644 planet/Objects.ocd/Structures.ocd/Ladder.ocd/LadderPart.ocd/GraphicsTop.10.png create mode 100644 planet/Objects.ocd/Structures.ocd/Ladder.ocd/LadderPart.ocd/Script.c create mode 100644 planet/Objects.ocd/Structures.ocd/Ladder.ocd/Script.c create mode 100644 planet/Objects.ocd/Structures.ocd/Ladder.ocd/StringTblDE.txt create mode 100644 planet/Objects.ocd/Structures.ocd/Ladder.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Structures.ocd/Ladder.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/DefCore.txt new file mode 100644 index 000000000..8c8aad245 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/DefCore.txt @@ -0,0 +1,11 @@ +[DefCore] +id=MetalLadder +Version=8,0 +Category=C4D_StaticBack +Width=5 +Height=80 +Offset=-3,-40 +Vertices=3 +VertexX=0,0,0 +VertexY=0,-27,27 +Mass=4 diff --git a/planet/Objects.ocd/Structures.ocd/Ladder.ocd/Graphics.png b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/Graphics.png new file mode 100644 index 0000000000000000000000000000000000000000..f020f1722156db9f34a0d751bc705495ee74311f GIT binary patch literal 2828 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 literal 0 HcmV?d00001 diff --git a/planet/Objects.ocd/Structures.ocd/Ladder.ocd/LadderPart.ocd/GraphicsBottom.10.png b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/LadderPart.ocd/GraphicsBottom.10.png new file mode 100644 index 0000000000000000000000000000000000000000..ca66dd043b4231403e0e44d0121e9324bf7ab02d GIT binary patch literal 5730 zcmV-o7MKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=00004XF*Lt006O$eEU(80000WV@Og>004R=004l4008;_004mL004C` z008P>0026e000+nl3&F}000YpNkl zkKptpPi;A$Y6AfP7u&yFZ)6b|ulczh^biNP?%!H3UFV}x`0o!lc{5QcL#qgvQZyKl zC!c((>&xg?krf&ZyHgfHnngO-ux*P-)5Mk;JB$NF((T4H1Rw%xEFi4HTBsQiYl8skFry|(jVHtI0`+cv008`L1L>7s@6_l~ zA?iVZT9h$RGXQZNCsAs>lloBipL?V=u_fJ+n|)w^r^v3_fLJRaA}B>8{ge)>UlpP2 zRFS?|E*k^8bXB7QWT}s$L~W)b?Mb6Z{2F#_M>_|oqcUU`K>DjCRKF_HYAW}qB7=~f zJK~5We*zJ~Xu+j{fuyMjTNz3m$z+$j;4_t_U9E54N7|Y;@wB;_uX=cA3k-g zNAljnM+BTcF$Vy6@z0CWODLRvkX`4P#BvY#q4xZ0}+^?o;}~CdR=iOO-0%{;%EhH84|0= zxz|?e?=Dmq=MEQcA|f}1XBvR#xhi*PvM_S&KxyjtuU?*x=e*YnKNGTDo>EtIiPqtA z9WWLW7`R%&hK$7v*YKNPy@GmZ??}M(8qTIFA{$kN071}x@v$StH;Z|Fa_+$Bxug3_ zPA=n)W?VJuXtjq3qpqeY&(-^USI=ZzJ);#qq7;p2))88*00B(gQ_i>=qd5@?WIy~ zVt?U-rBdxNZJk^`WJb2xK$Vf_<#?eSkdzpAdS1XZU8%V=ZGzClG^cO9h^5otx_ zIvGr4^K69`f#5m{8LgnS0*k;h!?J*_K%)Aem^oIU_Rb7JAW({+RP-PdwL{Xl=BG43FD^0a(OCv~7@Lf~`b3%ao33%@Gi8(xT_C33QI=kM>wM_DV z%L*Giq*@XFv2YE?J&jV{gAzf#VG&x3(8f=mg%Xw1O2Kh72n@pvW4W0#D2e2?naL^u zLJ*O-MXMmfAR=U3jf|_QT&q7@%KFCvyaE81-mfiosn+Fx{=pYvC#_{F@ub!Y>ek@g z+lyE%*I-#d3SwEL9$17X0%KWVEyFT{g+Zj?Xw{LrOVXdARx+d%n(ij;5ncdKYq(ki zz?U~wt)MP1_v&jY6`g{xA|N3IhVjOwWt6fR6mlN4yd+m1?HH9MDVmmU@aP< z#TyIDxa067JV&9J^{`qEV)se*JfgrQ5NHKBieQ+)5-m=I!LbE}87x3x7-4+&g#|EC z{DK7|pLO6no=cED04{d{`S|g@B1{`1XLr(=gh@@2{$E{fpj-(sUd%udb!-ILwuLpq z=-@$M4C;YJU?R&H+fp?Vfv~`e#3wBxaY?Lez{qA?7;W6uY9d zaVPQ)LS(^OXd!DM#G#qGzkeA3f*^YO4gegz^`mpuwKY^$I!pF;vL_soB*06{QfrM+ zmfvfTiQS>ejW{k4T3dF^0)~JX4gog+n16q% zZkwv*7pJ~8{h?#{@SXR-hCym?C|S6~Wg;m;u`~wH&ta_^P-waBn&h|Abc<$T27&5m z9<;tsu1!EU0*fnab*wiGECY_~p*TJTw>SnszBYHbK*hY%vPh*;nXcFC7#|{Iu_^?Y2Ie+z$n_6)2wU0oH`1QD4r36O$Vk(x3cy-zqJAXpJ- zO>i7XilZeeOddc!pF_P~|4Y!QK6ZY7T~v(PiJ$Uf7>4_6wL0=6V_2^(b_Mws*9D*c z?B{XAk+~*8OOsR3**qHMm5A^v-i=M-0YfY^g~q~g#1mr$)>;V-ld%jN^TqWPMvERM zX6Hc4fzl2DqD;nv>$(Vn;0JQvxl-c+RxIct-oeq|GIdswz^sk z=UH%BM3y{9RcFTY$2}K&A$W6Xwf6hm*j`M}O#Nt|?@#1%xydjLb3|maS)YARo*v6r zez0#+U-|a;UhYc2SJpyK>vJ^&;?&gMt5>gHJ55ASYpn?oSdO?69j_2DTUg5o!w|+8 z01&0rJOf`^tz3Tpz2(|%S5|`GAv%<70PxKR#~Hx6<`W&y<8SltVt)Re2La&Z$rA(s zFTVKOEz9LX&Oxo7eyE3%0QTsk-v9uV%d3*l=b*LjNKcq;+{!elRBD!)Ys~yJ0N+hg zgN3IG5A07*qoM6N<$f-&u#ApigX literal 0 HcmV?d00001 diff --git a/planet/Objects.ocd/Structures.ocd/Ladder.ocd/LadderPart.ocd/GraphicsTop.10.png b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/LadderPart.ocd/GraphicsTop.10.png new file mode 100644 index 0000000000000000000000000000000000000000..9d70448c86b7697cac6a3231738641eaae7c3d4c GIT binary patch literal 6659 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 N002ovPDHLkV1n#!YrFse literal 0 HcmV?d00001 diff --git a/planet/Objects.ocd/Structures.ocd/Ladder.ocd/LadderPart.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/LadderPart.ocd/Script.c new file mode 100644 index 000000000..0f5fb9916 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/LadderPart.ocd/Script.c @@ -0,0 +1,100 @@ +/** + Ladder Segment +*/ + +#include Library_Ladder + +local index; + +// Called from the ladder object to set a master and the segment index. +public func SetMaster(object new_master, int new_index, ...) +{ + // First perform setting the master in the library function. + _inherited(new_master, new_index, ...); + // Then set index and attach to master object. + index = new_index; + AddVertex(0, new_master->GetY() - GetY()); + SetAction("Attach", master); + return; +} + +// Returns whether the ladder can be climbed. +public func CanNotBeClimbed(bool is_climbing) +{ + var test_height = 10; + if (is_climbing) + test_height = 8; + if (GBackSolid(1, test_height) && GBackSolid(-1, test_height)) + return true; + return false; +} + +// Returns the segment (start x, start y, end x, end y, angle) on which the clonk can climb. +// The coordinate value must be specified with a precision of a 1000. +public func GetLadderData() +{ + return [ + GetX(1000), + GetY(1000) + 4000, + GetX(1000), + GetY(1000) - 4000, + 0 + ]; +} + +public func OnLadderGrab(object clonk) +{ + if (master) + master->OnLadderGrab(clonk, this, index); + return; +} + +public func OnLadderClimb(object clonk) +{ + if (master) + master->OnLadderClimb(clonk, this, index); + return; +} + +public func OnLadderReleased(object clonk) +{ + if (master) + master->OnLadderReleased(clonk, this, index); + return; +} + +// Main ladder object is saved. +public func SaveScenarioObject() { return false; } + +/*-- Graphics --*/ + +public func SetPreviousLadder(object ladder) +{ + _inherited(ladder); + + if (!this->GetNextLadder()) + SetGraphics("Top"); + else + SetGraphics(nil); +} + +public func SetNextLadder(object ladder) +{ + _inherited(ladder); + + if (!this->GetPreviousLadder()) + SetGraphics("Bottom"); + else + SetGraphics(nil); +} + +/*-- Properties --*/ + +local ActMap = { + Attach = { + Prototype = Action, + Name = "Attach", + FacetBase = 1, + Procedure = DFA_ATTACH, + }, +}; diff --git a/planet/Objects.ocd/Structures.ocd/Ladder.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/Script.c new file mode 100644 index 000000000..2b6e43105 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/Script.c @@ -0,0 +1,84 @@ +/** + Simple, static ladder + + Cannot be built ingame and must be placed by designers. Use the SetLength() function to make it as long as you wish. + + @authors: Clonkonaut +*/ + +local segments; + +func Initialize() +{ + // Create ladder segments to climb on. + CreateSegments(); +} + +public func SetLength(int segment_count) +{ + if (GetLength(segments) == segment_count) return; + if (segment_count < 2) return; + + for (var segment in segments) + segment->RemoveObject(); + + var new_height = segment_count * 8; + SetShape(-3, new_height / -2, 5, new_height); + CreateSegments(); +} + +/*-- Ladder Control --*/ + +// Creates the segments which control the climbing. +func CreateSegments() +{ + segments = []; + var nr_segments = (GetBottom() - GetTop()) / 8; + for (var index = 0; index < nr_segments; index++) + { + var y = GetTop() + index * 8; + var segment = CreateObject(MetalLadderSegment, 0, y+4); + segment->SetMaster(this, index); + // Store the segments. + PushBack(segments, segment); + // Set next and previous segment for climbing control. + if (index > 0) + { + segments[index - 1]->SetPreviousLadder(segment); + segment->SetNextLadder(segments[index - 1]); + } + } +} + +public func OnLadderGrab(object clonk, object segment, int segment_index) +{ + segment->Sound("Clonk::Action::Grab"); +} + +public func OnLadderClimb(object clonk, object segment, int segment_index) +{ + if (clonk->GetComDir() == COMD_Up || clonk->GetComDir() == COMD_Down) + if (!Random(20)) + segment->Sound("Clonk::Movement::Rustle?", {volume = 35}); +} + +public func OnLadderReleased(object clonk, object segment, int segment_index) +{ + segment->Sound("Clonk::Action::UnGrab", {volume = 50}); +} + +/*-- Saving --*/ + +// Save placed ladder segments in scenarios. +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) + return false; + + props->AddCall("Length", this, "SetLength", GetLength(segments)); + return true; +} + +/*-- Properties --*/ + +local Name = "$Name$"; \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Ladder.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/StringTblDE.txt new file mode 100644 index 000000000..0f52da684 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Leiter \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Ladder.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/StringTblUS.txt new file mode 100644 index 000000000..8e58c5a24 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Ladder.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Ladder \ No newline at end of file From fd5551427981e8cf0134b1ccc7e8a4b2b74deed7 Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Tue, 2 May 2017 23:48:50 +0200 Subject: [PATCH 90/93] Fixed shape of tunnel supports. --- planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/Script.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/Script.c b/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/Script.c index dc8da42c6..70e4b1e39 100644 --- a/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/Script.c +++ b/planet/Decoration.ocd/Village.ocd/TunnelSupport.ocd/Script.c @@ -21,11 +21,11 @@ public func Extend(int percentage) extension = percentage; + var height = 30 + (55 * percentage / 100); percentage = 2500 * percentage / 100; PlayAnimation("extend", 1, Anim_Const(percentage)); - var height = 30 + (55 * percentage / 100); - SetShape(-15, -height/2, 30, height); + SetShape(-15, -15 + (30 - height), 30, height); } public func SaveScenarioObject(props) From d750a574106dd58d2c9b826fb26e85a7560ef12a Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Wed, 3 May 2017 09:42:25 +0200 Subject: [PATCH 91/93] Hatch: combine with basements even if the construction preview hasn't been properly combined. The hatch will automatically attach itself onto basements it finds around its center after it has been built. This makes it easier to use since people probably tend to forget combining the construction preview. Especially since basements are very slim. The hatch will reposition itself in order to attach. This means it is not right where the player placed it. The alternative would be to move the basement and I guess that even more unwanted. --- .../Structures.ocd/Hatch.ocd/Script.c | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/planet/Objects.ocd/Structures.ocd/Hatch.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/Script.c index a8b573fa4..df9a2c91a 100644 --- a/planet/Objects.ocd/Structures.ocd/Hatch.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Hatch.ocd/Script.c @@ -18,6 +18,25 @@ func Construction() return _inherited(...); } +func Initialize() +{ + // If the hatch has not been properly combined with a basement, we might want to correct that + if (!GetBasement()) + { + var basements = FindObjects(Find_AtRect(-1,0, 2,4), Find_Func("IsBasement"), Sort_Distance()); + for (var basement in basements) + { + if (!basement->GetParent() && basement->GetWidth() == 40) + { + SetPosition(basement->GetX(), basement->GetY()-2); + basement->SetParent(this); + break; + } + } + } + return _inherited(...); +} + /*-- Callbacks --*/ public func IsHammerBuildable() { return true; } @@ -35,11 +54,6 @@ public func ConstructionCombineWith() { return "IsBasement"; } public func ConstructionCombineDirection(object other) { return CONSTRUCTION_STICK_Top; } -public func ConstructionCombineOffset(object other) -{ - return [0, 0]; -} - public func CombineWith(object stick_to) { if (stick_to && stick_to->~IsBasement()) From e58a7884e4cbfe20a94738be22f245bf29ccc636 Mon Sep 17 00:00:00 2001 From: Tushar Maheshwari Date: Wed, 3 May 2017 20:28:00 +0200 Subject: [PATCH 92/93] Automatic fixes using clang-tidy See http://forum.openclonk.org/topic_show.pl?tid=3376 for discussion. Close GH-41 --- src/c4group/C4Extra.cpp | 16 +-- src/c4group/C4Group.cpp | 2 +- src/c4group/C4GroupMain.cpp | 2 +- src/c4group/C4GroupSet.cpp | 2 +- src/c4group/C4LangStringTable.cpp | 4 +- src/c4group/C4Language.cpp | 2 +- src/c4group/CStdFile.cpp | 4 +- src/config/C4Config.cpp | 8 +- src/config/C4Reloc.cpp | 10 +- src/control/C4Control.cpp | 20 +-- src/control/C4Control.h | 2 +- src/control/C4GameParameters.cpp | 10 +- src/control/C4GameSave.cpp | 2 +- src/control/C4PlayerControl.cpp | 107 +++++++-------- src/control/C4Record.cpp | 16 +-- src/editor/C4Console.cpp | 36 +++-- src/editor/C4ConsoleQt.cpp | 2 +- .../C4ConsoleQtDefinitionListViewer.cpp | 8 +- src/editor/C4ConsoleQtNewScenario.cpp | 12 +- src/editor/C4ConsoleQtPropListViewer.cpp | 20 ++- src/editor/C4ConsoleQtState.cpp | 35 +++-- src/editor/C4ConsoleWin32.cpp | 64 ++++----- src/editor/C4EditCursor.cpp | 2 +- src/editor/C4ObjectListDlg.cpp | 8 +- src/editor/C4ToolsDlg.cpp | 2 +- src/game/C4Application.cpp | 56 ++++---- src/game/C4FullScreen.cpp | 2 +- src/game/C4Game.cpp | 32 ++--- src/game/C4GameScript.cpp | 76 +++++------ src/game/C4GraphicsSystem.cpp | 2 +- src/game/C4Viewport.cpp | 8 +- src/game/ClonkMain.cpp | 10 +- src/graphics/C4Draw.cpp | 32 ++--- src/graphics/C4DrawGL.cpp | 21 ++- src/graphics/C4DrawGLCtx.cpp | 46 +++---- src/graphics/C4DrawMeshGL.cpp | 21 ++- src/graphics/C4FontLoader.cpp | 2 +- src/graphics/C4GraphicsResource.cpp | 4 +- src/graphics/C4Shader.cpp | 28 ++-- src/graphics/C4Surface.cpp | 16 +-- src/graphics/C4SurfaceLoaders.cpp | 2 +- src/graphics/StdPNG.cpp | 6 +- src/gui/C4ChatDlg.cpp | 10 +- src/gui/C4FileSelDlg.cpp | 4 +- src/gui/C4Gui.cpp | 4 +- src/gui/C4GuiButton.cpp | 4 +- src/gui/C4GuiCheckBox.cpp | 2 +- src/gui/C4GuiComboBox.cpp | 10 +- src/gui/C4GuiDialogs.cpp | 20 +-- src/gui/C4GuiEdit.cpp | 10 +- src/gui/C4GuiLabels.cpp | 4 +- src/gui/C4GuiListBox.cpp | 12 +- src/gui/C4GuiMenu.cpp | 24 ++-- src/gui/C4GuiTabular.cpp | 4 +- src/gui/C4KeyboardInput.cpp | 24 ++-- src/gui/C4KeyboardInput.h | 2 +- src/gui/C4MessageBoard.cpp | 4 +- src/gui/C4MessageInput.cpp | 10 +- src/gui/C4MouseControl.cpp | 4 +- src/gui/C4Scoreboard.cpp | 12 +- src/gui/C4ScriptGuiWindow.cpp | 75 +++++----- src/gui/C4StartupAboutDlg.cpp | 4 +- src/gui/C4StartupMainDlg.cpp | 6 +- src/gui/C4StartupNetDlg.cpp | 10 +- src/gui/C4StartupOptionsDlg.cpp | 18 +-- src/gui/C4StartupPlrSelDlg.cpp | 20 +-- src/gui/C4StartupScenSelDlg.cpp | 34 +++-- src/gui/C4UpperBoard.cpp | 10 +- src/landscape/C4Landscape.cpp | 6 +- src/landscape/C4LandscapeRender.cpp | 44 +++--- src/landscape/C4Map.cpp | 6 +- src/landscape/C4MapCreatorS2.cpp | 10 +- src/landscape/C4MapScript.cpp | 2 +- src/landscape/C4MapScriptAlgo.cpp | 24 ++-- src/landscape/C4Material.cpp | 12 +- src/landscape/C4MaterialList.cpp | 4 +- src/landscape/C4Scenario.cpp | 18 +-- src/landscape/C4Sky.cpp | 2 +- src/landscape/C4SolidMask.cpp | 6 +- src/landscape/C4Texture.cpp | 7 +- src/landscape/C4TransferZone.cpp | 4 +- src/landscape/fow/C4FoW.cpp | 2 +- src/landscape/fow/C4FoWAmbient.cpp | 2 +- src/landscape/fow/C4FoWDrawStrategy.cpp | 8 +- src/landscape/fow/C4FoWLight.cpp | 40 +++--- src/landscape/fow/C4FoWLightSection.cpp | 9 +- src/lib/C4InputValidation.cpp | 4 +- src/lib/C4Markup.cpp | 4 +- src/lib/C4NameList.cpp | 4 +- src/lib/C4Stat.cpp | 26 ++-- src/lib/Standard.cpp | 2 +- src/lib/StdBuf.cpp | 18 +-- src/lib/StdCompiler.cpp | 36 ++--- src/lib/StdMesh.cpp | 117 ++++++++-------- src/lib/StdMeshLoaderBinary.cpp | 8 +- src/lib/StdMeshLoaderBinaryChunks.cpp | 46 +++---- src/lib/StdMeshLoaderXml.cpp | 13 +- src/lib/StdMeshMaterial.cpp | 39 +++--- src/lib/StdMeshMath.cpp | 2 +- src/lib/StdMeshUpdate.cpp | 24 ++-- src/netpuncher/main.cpp | 8 +- src/network/C4Client.cpp | 5 +- src/network/C4NetIO.cpp | 19 +-- src/network/C4Network2IRC.cpp | 2 +- src/network/C4Network2Reference.cpp | 11 +- src/network/C4Network2Res.cpp | 17 +-- src/network/C4Network2Stats.cpp | 14 +- src/network/C4Network2UPnPDummy.cpp | 4 +- src/network/C4Network2UPnPWin32.cpp | 11 +- src/network/C4Packet2.cpp | 23 +--- src/object/C4Action.cpp | 5 +- src/object/C4Command.cpp | 4 +- src/object/C4Def.cpp | 6 +- src/object/C4DefGraphics.cpp | 28 ++-- src/object/C4DefList.cpp | 10 +- src/object/C4GameObjects.cpp | 2 +- src/object/C4Movement.cpp | 8 +- src/object/C4Object.cpp | 128 +++++++++--------- src/object/C4ObjectCom.cpp | 6 +- src/object/C4ObjectList.cpp | 4 +- src/object/C4ObjectMenu.cpp | 8 +- src/object/C4ObjectPtr.cpp | 2 +- src/object/C4ObjectScript.cpp | 16 +-- src/platform/C4AppSDL.cpp | 6 +- src/platform/C4AppT.cpp | 10 +- src/platform/C4CrashHandlerWin32.cpp | 10 +- src/platform/C4FileMonitor.cpp | 6 +- src/platform/C4GamePadCon.cpp | 4 +- src/platform/C4MusicFile.cpp | 12 +- src/platform/C4MusicSystem.cpp | 10 +- src/platform/C4SoundSystem.cpp | 5 +- src/platform/C4StdInProc.cpp | 4 +- src/platform/C4TimeMilliseconds.cpp | 7 +- src/platform/C4WindowSDL.cpp | 4 +- src/platform/C4WindowWin32.cpp | 30 ++-- src/platform/PlatformAbstraction.cpp | 10 +- src/platform/StdFile.cpp | 30 ++-- src/platform/StdRegistry.cpp | 22 +-- src/platform/StdScheduler.cpp | 6 +- src/platform/StdSchedulerPoll.cpp | 2 +- src/player/C4Achievement.cpp | 4 +- src/player/C4Player.cpp | 4 +- src/player/C4PlayerList.cpp | 2 +- src/player/C4ScenarioParameters.cpp | 36 ++--- src/script/C4Aul.cpp | 10 +- src/script/C4AulCompiler.cpp | 126 ++++++++--------- src/script/C4AulDebug.cpp | 8 +- src/script/C4AulExec.cpp | 11 +- src/script/C4AulFunc.cpp | 4 +- src/script/C4AulLink.cpp | 8 +- src/script/C4AulParse.cpp | 116 ++++++++-------- src/script/C4AulScriptFunc.cpp | 2 +- src/script/C4Effect.cpp | 12 +- src/script/C4PropList.cpp | 28 ++-- src/script/C4Script.cpp | 26 ++-- src/script/C4ScriptHost.cpp | 8 +- src/script/C4ScriptMain.cpp | 12 +- src/script/C4ScriptStandalone.cpp | 2 +- src/script/C4ScriptStandaloneStubs.cpp | 4 +- src/script/C4StringTable.cpp | 10 +- src/script/C4Value.cpp | 12 +- src/script/C4ValueMap.cpp | 34 ++--- 162 files changed, 1245 insertions(+), 1403 deletions(-) diff --git a/src/c4group/C4Extra.cpp b/src/c4group/C4Extra.cpp index 98f44c29c..7114ae02e 100644 --- a/src/c4group/C4Extra.cpp +++ b/src/c4group/C4Extra.cpp @@ -23,21 +23,17 @@ #include "game/C4Game.h" #include "lib/C4Log.h" -C4Extra::C4Extra() -{ -} +C4Extra::C4Extra() = default; -C4Extra::~C4Extra() -{ -} +C4Extra::~C4Extra() = default; bool C4Extra::InitGroup() { // register extra root into game group set - for(C4Reloc::iterator iter = Reloc.begin(); iter != Reloc.end(); ++iter) + for(const auto & iter : Reloc) { std::unique_ptr pGroup(new C4Group); - if(pGroup->Open( ((*iter).strBuf + DirSep + C4CFN_Extra).getData())) + if(pGroup->Open( (iter.strBuf + DirSep + C4CFN_Extra).getData())) ExtraGroups.emplace_back(std::move(pGroup)); } @@ -55,9 +51,9 @@ bool C4Extra::Init() char szSegment[_MAX_PATH+1]; for (int cseg=0; SCopySegment(Game.DefinitionFilenames,cseg,szSegment,';',_MAX_PATH); cseg++) { - for(unsigned int i = 0; i < ExtraGroups.size(); ++i) + for(auto & ExtraGroup : ExtraGroups) { - if(LoadDef(*ExtraGroups[i], GetFilename(szSegment))) + if(LoadDef(*ExtraGroup, GetFilename(szSegment))) { break; } diff --git a/src/c4group/C4Group.cpp b/src/c4group/C4Group.cpp index 659be0be4..95087844c 100644 --- a/src/c4group/C4Group.cpp +++ b/src/c4group/C4Group.cpp @@ -551,7 +551,7 @@ bool C4Group::Open(const char *szGroupName, bool fCreate) char szRealGroup[_MAX_FNAME]; SCopy(szGroupNameN,szRealGroup,_MAX_FNAME); do - { if (!TruncatePath(szRealGroup)) return Error(FormatString("Open(\"%s\"): File not found", szGroupNameN).getData()); } + { if (!TruncatePath(szRealGroup)) return Error(FormatString(R"(Open("%s"): File not found)", szGroupNameN).getData()); } while (!FileExists(szRealGroup)); // Open mother and child in exclusive mode diff --git a/src/c4group/C4GroupMain.cpp b/src/c4group/C4GroupMain.cpp index 589ea1880..4931d4936 100644 --- a/src/c4group/C4GroupMain.cpp +++ b/src/c4group/C4GroupMain.cpp @@ -569,7 +569,7 @@ int main(int argc, char *argv[]) break; // Child process case 0: - execl(strExecuteAtEnd, strExecuteAtEnd, static_cast(0)); // currently no parameters are passed to the executed program + execl(strExecuteAtEnd, strExecuteAtEnd, static_cast(nullptr)); // currently no parameters are passed to the executed program exit(1); // Parent process default: diff --git a/src/c4group/C4GroupSet.cpp b/src/c4group/C4GroupSet.cpp index af13621d8..8c81a3d91 100644 --- a/src/c4group/C4GroupSet.cpp +++ b/src/c4group/C4GroupSet.cpp @@ -192,7 +192,7 @@ C4Group *C4GroupSet::FindEntry(const char *szWildcard, int32_t *pPriority, int32 C4Group *C4GroupSet::FindSuitableFile(const char *szName, const char * const extensions[], char *szFileName, int32_t *pID) { - C4Group *pGrp = 0; + C4Group *pGrp = nullptr; C4Group *pGrp2; int iPrio = -1; int32_t iPrio2; diff --git a/src/c4group/C4LangStringTable.cpp b/src/c4group/C4LangStringTable.cpp index 33b9f533d..fb9c2bec7 100644 --- a/src/c4group/C4LangStringTable.cpp +++ b/src/c4group/C4LangStringTable.cpp @@ -68,7 +68,7 @@ void C4LangStringTable::PopulateStringTable() const else if (*data == '\0' || *data == '\n' || *data == '\r') { if (!key.empty() && key[0]!='#') - LogF("%s: string table entry without a value: \"%s\"", GetFilePath() ? GetFilePath() : "", key.c_str()); + LogF(R"(%s: string table entry without a value: "%s")", GetFilePath() ? GetFilePath() : "", key.c_str()); key.clear(); } else @@ -134,7 +134,7 @@ void C4LangStringTable::ReplaceStrings(const StdStrBuf &rBuf, StdStrBuf &rTarget } catch (NoSuchTranslation &) { - LogF("%s: string table entry not found: \"%s\"", GetFilePath() ? GetFilePath() : "", szStringName); + LogF(R"(%s: string table entry not found: "%s")", GetFilePath() ? GetFilePath() : "", szStringName); } } // Alloc new Buffer diff --git a/src/c4group/C4Language.cpp b/src/c4group/C4Language.cpp index 1cf9aa8ee..d4e5a5644 100644 --- a/src/c4group/C4Language.cpp +++ b/src/c4group/C4Language.cpp @@ -320,7 +320,7 @@ void C4Language::LoadInfos(C4Group &hGroup) // of the same code - the system always loads the first string table found for a given code if (!FindInfo(GetFilenameOnly(strEntry) + SLen(GetFilenameOnly(strEntry)) - 2)) // Load language string table - if (hGroup.LoadEntry(strEntry, &strTable, 0, 1)) + if (hGroup.LoadEntry(strEntry, &strTable, nullptr, 1)) { // New language info C4LanguageInfo *pInfo = new C4LanguageInfo; diff --git a/src/c4group/CStdFile.cpp b/src/c4group/CStdFile.cpp index a8e2bdce9..89d81d16b 100644 --- a/src/c4group/CStdFile.cpp +++ b/src/c4group/CStdFile.cpp @@ -27,11 +27,11 @@ #include #include "zlib/gzio.h" -#include +#include #include #include -#include +#include CStdFile::CStdFile() { diff --git a/src/config/C4Config.cpp b/src/config/C4Config.cpp index d3bd9de05..c5552c3fc 100644 --- a/src/config/C4Config.cpp +++ b/src/config/C4Config.cpp @@ -38,7 +38,7 @@ #include #endif #ifdef HAVE_LOCALE_H -#include +#include #endif #ifdef USE_CONSOLE @@ -213,7 +213,7 @@ void C4ConfigSecurity::CompileFunc(StdCompiler *pComp) { pComp->Value(mkNamingAdapt(WasRegistered, "WasRegistered", 0 )); #ifdef _WIN32 - pComp->Value(mkNamingAdapt(s(KeyPath), "KeyPath", "%APPDATA%\\" C4ENGINENAME, false, true)); + pComp->Value(mkNamingAdapt(s(KeyPath), "KeyPath", R"(%APPDATA%\)" C4ENGINENAME, false, true)); #elif defined(__linux__) pComp->Value(mkNamingAdapt(s(KeyPath), "KeyPath", "$HOME/.clonk/" C4ENGINENICK, false, true)); #elif defined(__APPLE__) @@ -498,7 +498,7 @@ void C4ConfigGeneral::DeterminePaths() SCopy(ConfigUserPath, UserDataPath); else #if defined(_WIN32) - SCopy("%APPDATA%\\" C4ENGINENAME, UserDataPath); + SCopy(R"(%APPDATA%\)" C4ENGINENAME, UserDataPath); #elif defined(__APPLE__) SCopy("$HOME/Library/Application Support/" C4ENGINENAME, UserDataPath); #else @@ -718,7 +718,7 @@ const char* C4Config::GetSubkeyPath(const char *strSubkey) { static char key[1024 + 1]; #ifdef _WIN32 - sprintf(key, "Software\\%s\\%s\\%s", C4CFG_Company, C4ENGINENAME, strSubkey); + sprintf(key, R"(Software\%s\%s\%s)", C4CFG_Company, C4ENGINENAME, strSubkey); #else sprintf(key, "%s", strSubkey); #endif diff --git a/src/config/C4Reloc.cpp b/src/config/C4Reloc.cpp index 3e9976100..dd2fde34f 100644 --- a/src/config/C4Reloc.cpp +++ b/src/config/C4Reloc.cpp @@ -52,7 +52,7 @@ bool C4Reloc::AddPath(const char* path, PathType pathType) if(std::find(Paths.begin(), Paths.end(), path) != Paths.end()) return false; - Paths.push_back(PathInfo(StdCopyStrBuf(path), pathType)); + Paths.emplace_back(StdCopyStrBuf(path), pathType); return true; } @@ -70,8 +70,8 @@ bool C4Reloc::Open(C4Group& hGroup, const char* filename) const { if(IsGlobalPath(filename)) return hGroup.Open(filename); - for(iterator iter = begin(); iter != end(); ++iter) - if(hGroup.Open(((*iter).strBuf + DirSep + filename).getData())) + for(const auto & iter : *this) + if(hGroup.Open((iter.strBuf + DirSep + filename).getData())) return true; return false; @@ -85,9 +85,9 @@ bool C4Reloc::LocateItem(const char* filename, StdStrBuf& str) const return true; } - for(iterator iter = begin(); iter != end(); ++iter) + for(const auto & iter : *this) { - str.Copy((*iter).strBuf + DirSep + filename); + str.Copy(iter.strBuf + DirSep + filename); if(ItemExists(str.getData())) return true; } diff --git a/src/control/C4Control.cpp b/src/control/C4Control.cpp index 9d2e5edda..05545afb7 100644 --- a/src/control/C4Control.cpp +++ b/src/control/C4Control.cpp @@ -59,10 +59,7 @@ C4ControlPacket::C4ControlPacket() } -C4ControlPacket::~C4ControlPacket() -{ - -} +C4ControlPacket::~C4ControlPacket() = default; bool C4ControlPacket::LocalControl() const { @@ -82,10 +79,7 @@ void C4ControlPacket::CompileFunc(StdCompiler *pComp) // *** C4Control -C4Control::C4Control() -{ - -} +C4Control::C4Control() = default; C4Control::~C4Control() { @@ -540,7 +534,7 @@ void C4ControlMenuCommand::Execute() const // menu was closed? if (!menu) return; - C4Object *obj = target ? ::Objects.ObjectPointer(target) : 0; + C4Object *obj = target ? ::Objects.ObjectPointer(target) : nullptr; // target has been removed in the meantime? abort now if (target && !obj) return; @@ -751,9 +745,7 @@ void C4ControlPlayerAction::CompileFunc(StdCompiler *pComp) // *** C4ControlSyncCheck -C4ControlSyncCheck::C4ControlSyncCheck() -{ -} +C4ControlSyncCheck::C4ControlSyncCheck() = default; void C4ControlSyncCheck::Set() { @@ -1012,9 +1004,9 @@ void C4ControlClientRemove::CompileFunc(StdCompiler *pComp) // *** C4ControlJoinPlayer -C4ControlJoinPlayer::C4ControlJoinPlayer(const char *szFilename, int32_t iAtClient, int32_t iIDInfo, const C4Network2ResCore &ResCore) +C4ControlJoinPlayer::C4ControlJoinPlayer(const char *szFilename, int32_t iAtClient, int32_t iIDInfo, C4Network2ResCore ResCore) : Filename(szFilename, true), iAtClient(iAtClient), - idInfo(iIDInfo), fByRes(true), ResCore(ResCore) + idInfo(iIDInfo), fByRes(true), ResCore(std::move(ResCore)) { } diff --git a/src/control/C4Control.h b/src/control/C4Control.h index 133d6bc35..77cec36ad 100644 --- a/src/control/C4Control.h +++ b/src/control/C4Control.h @@ -428,7 +428,7 @@ struct C4ControlJoinPlayer : public C4ControlPacket // sync { public: C4ControlJoinPlayer() : iAtClient(-1), idInfo(-1), fByRes(false) { } - C4ControlJoinPlayer(const char *szFilename, int32_t iAtClient, int32_t iIDInfo, const C4Network2ResCore &ResCore); + C4ControlJoinPlayer(const char *szFilename, int32_t iAtClient, int32_t iIDInfo, C4Network2ResCore ResCore); C4ControlJoinPlayer(const char *szFilename, int32_t iAtClient, int32_t iIDInfo); protected: StdStrBuf Filename; diff --git a/src/control/C4GameParameters.cpp b/src/control/C4GameParameters.cpp index 64db662e5..d0f2b3ed7 100644 --- a/src/control/C4GameParameters.cpp +++ b/src/control/C4GameParameters.cpp @@ -374,15 +374,9 @@ void C4GameResList::CompileFunc(StdCompiler *pComp) // *** C4GameParameters -C4GameParameters::C4GameParameters() -{ +C4GameParameters::C4GameParameters() = default; -} - -C4GameParameters::~C4GameParameters() -{ - -} +C4GameParameters::~C4GameParameters() = default; void C4GameParameters::Clear() { diff --git a/src/control/C4GameSave.cpp b/src/control/C4GameSave.cpp index bce653418..e188a4002 100644 --- a/src/control/C4GameSave.cpp +++ b/src/control/C4GameSave.cpp @@ -77,7 +77,7 @@ bool C4GameSave::SaveCore() rC4S.Head.RandomSeed=Game.RandomSeed; } // reset some network flags - rC4S.Head.NetworkGame=0; + rC4S.Head.NetworkGame=false; // Title in language game was started in (not: save scenarios and net references) if (!GetKeepTitle()) { diff --git a/src/control/C4PlayerControl.cpp b/src/control/C4PlayerControl.cpp index a472a344f..97999a7b3 100644 --- a/src/control/C4PlayerControl.cpp +++ b/src/control/C4PlayerControl.cpp @@ -135,9 +135,8 @@ void C4PlayerControlDefs::MergeFrom(const C4PlayerControlDefs &Src) // Clear previous defs if specified in merge set if (Src.clear_previous) Defs.clear(); // copy all defs from source file; overwrite defs of same name if found - for (DefVecImpl::const_iterator i = Src.Defs.begin(); i != Src.Defs.end(); ++i) + for (const auto & SrcDef : Src.Defs) { - const C4PlayerControlDef &SrcDef = *i; // overwrite if def of same name existed int32_t iPrevIdx = GetControlIndexByIdentifier(SrcDef.GetIdentifier()); if (iPrevIdx != CON_None) @@ -285,9 +284,8 @@ bool C4PlayerControlAssignment::ResolveRefs(C4PlayerControlAssignmentSet *pParen iControl = pControlDefs->GetControlIndexByIdentifier(sControlName.getData()); // resolve keys KeyComboVec NewCombo; - for (KeyComboVec::iterator i = KeyCombo.begin(); i != KeyCombo.end(); ++i) + for (auto & rKeyComboItem : KeyCombo) { - KeyComboItem &rKeyComboItem = *i; const char *szKeyName = rKeyComboItem.sKeyName.getData(); // check if this is a key reference. A key reference must be preceded by CON_ // it may also be preceded by modifiers (Shift+), which are already set in rKeyComboItem.Key.dwShift @@ -316,9 +314,8 @@ bool C4PlayerControlAssignment::ResolveRefs(C4PlayerControlAssignmentSet *pParen DWORD ref_shift = rKeyComboItem.Key.dwShift; if (ref_shift) { - for (KeyComboVec::iterator j = pRefAssignment->KeyCombo.begin(); j != pRefAssignment->KeyCombo.end(); ++j) + for (auto assignment_combo_item : pRefAssignment->KeyCombo) { - KeyComboItem assignment_combo_item = *j; assignment_combo_item.Key.dwShift |= ref_shift; NewCombo.push_back(assignment_combo_item); } @@ -340,7 +337,7 @@ bool C4PlayerControlAssignment::ResolveRefs(C4PlayerControlAssignmentSet *pParen // non-reference: check if the assignment was valid #ifndef USE_CONSOLE if (rKeyComboItem.Key == KEY_Default) - LogF("WARNING: Control %s of set %s contains undefined key \"%s\".", GetControlName(), pParentSet->GetName(), szKeyName); + LogF(R"(WARNING: Control %s of set %s contains undefined key "%s".)", GetControlName(), pParentSet->GetName(), szKeyName); #endif // ...and just keep this item. NewCombo.push_back(rKeyComboItem); @@ -352,16 +349,16 @@ bool C4PlayerControlAssignment::ResolveRefs(C4PlayerControlAssignmentSet *pParen if (KeyCombo.size() > 1 && !fComboIsSequence) { int32_t shift = 0; - for (KeyComboVec::iterator i = KeyCombo.begin(); i != KeyCombo.end(); ++i) + for (auto & i : KeyCombo) { - if (i->Key.Key == K_CONTROL_L || i->Key.Key == K_CONTROL_R) shift |= KEYS_Control; - if (i->Key.Key == K_SHIFT_L || i->Key.Key == K_SHIFT_R) shift |= KEYS_Shift; - shift |= i->Key.dwShift; + if (i.Key.Key == K_CONTROL_L || i.Key.Key == K_CONTROL_R) shift |= KEYS_Control; + if (i.Key.Key == K_SHIFT_L || i.Key.Key == K_SHIFT_R) shift |= KEYS_Shift; + shift |= i.Key.dwShift; } - for (KeyComboVec::iterator i = KeyCombo.begin(); i != KeyCombo.end(); ++i) i->Key.dwShift |= shift; + for (auto & i : KeyCombo) i.Key.dwShift |= shift; } // remove control/shift duplications - for (KeyComboVec::iterator i = KeyCombo.begin(); i != KeyCombo.end(); ++i) i->Key.FixShiftKeys(); + for (auto & i : KeyCombo) i.Key.FixShiftKeys(); // the trigger key is always last of the chain if (KeyCombo.size()) TriggerKey = KeyCombo.back().Key; else TriggerKey = C4KeyCodeEx(); // done @@ -379,8 +376,8 @@ bool C4PlayerControlAssignment::IsComboMatched(const C4PlayerControlRecentKeyLis C4TimeMilliseconds tKeyLast = C4TimeMilliseconds::Now(); // combo is a sequence: The last keys of RecentKeys must match the sequence // the last ComboKey is the TriggerKey, which is omitted because it has already been matched and is not to be found in RecentKeys yet - KeyComboVec::const_reverse_iterator i = KeyCombo.rbegin()+1; - for (C4PlayerControlRecentKeyList::const_reverse_iterator ri = RecentKeys.rbegin(); i!=KeyCombo.rend(); ++ri) + auto i = KeyCombo.rbegin()+1; + for (auto ri = RecentKeys.rbegin(); i!=KeyCombo.rend(); ++ri) { // no more keys pressed but combo didn't end? -> no combo match if (ri == RecentKeys.rend()) return false; @@ -403,13 +400,11 @@ bool C4PlayerControlAssignment::IsComboMatched(const C4PlayerControlRecentKeyLis else { // combo requires keys to be down simultanuously: check that all keys of the combo are in the down-list - for (KeyComboVec::const_iterator i = KeyCombo.begin(); i!=KeyCombo.end(); ++i) + for (const auto & k : KeyCombo) { - const KeyComboItem &k = *i; bool fFound = false; - for (C4PlayerControlRecentKeyList::const_iterator di = DownKeys.begin(); di!=DownKeys.end(); ++di) + for (const auto & dk : DownKeys) { - const C4PlayerControlRecentKey &dk = *di; if (dk.matched_key == k.Key) { fFound = true; break; } } if (!fFound) return false; @@ -517,9 +512,8 @@ void C4PlayerControlAssignmentSet::CompileFunc(StdCompiler *pComp) void C4PlayerControlAssignmentSet::MergeFrom(const C4PlayerControlAssignmentSet &Src, MergeMode merge_mode) { // take over all assignments defined in Src - for (C4PlayerControlAssignmentVec::const_iterator i = Src.Assignments.begin(); i != Src.Assignments.end(); ++i) + for (const auto & SrcAssignment : Src.Assignments) { - const C4PlayerControlAssignment &SrcAssignment = *i; bool fIsReleaseKey = !!(SrcAssignment.GetTriggerMode() & C4PlayerControlAssignment::CTM_Release); // overwrite same def and release key state if (merge_mode != MM_LowPrio && SrcAssignment.IsOverrideAssignments()) @@ -546,18 +540,18 @@ void C4PlayerControlAssignmentSet::MergeFrom(const C4PlayerControlAssignmentSet { // if this is low priority, another override control kills this bool any_override = false; - for (C4PlayerControlAssignmentVec::iterator j = Assignments.begin(); j != Assignments.end(); ++j) - if (SEqual((*j).GetControlName(), SrcAssignment.GetControlName())) + for (auto & Assignment : Assignments) + if (SEqual(Assignment.GetControlName(), SrcAssignment.GetControlName())) { - bool fSelfIsReleaseKey = !!((*j).GetTriggerMode() & C4PlayerControlAssignment::CTM_Release); + bool fSelfIsReleaseKey = !!(Assignment.GetTriggerMode() & C4PlayerControlAssignment::CTM_Release); if (fSelfIsReleaseKey == fIsReleaseKey) { any_override = true; // config overloads just change the key of the inherited assignment if (merge_mode == MM_ConfigOverload) { - (*j).CopyKeyFrom(SrcAssignment); - (*j).SetInherited(false); + Assignment.CopyKeyFrom(SrcAssignment); + Assignment.SetInherited(false); } break; } @@ -577,7 +571,7 @@ void C4PlayerControlAssignmentSet::MergeFrom(const C4PlayerControlAssignmentSet C4PlayerControlAssignment *C4PlayerControlAssignmentSet::CreateAssignmentForControl(const char *control_name) { - Assignments.push_back(C4PlayerControlAssignment()); + Assignments.emplace_back(); Assignments.back().SetControlName(control_name); return &Assignments.back(); } @@ -595,12 +589,12 @@ void C4PlayerControlAssignmentSet::RemoveAssignmentByControlName(const char *con bool C4PlayerControlAssignmentSet::ResolveRefs(C4PlayerControlDefs *pDefs) { // reset all resolved flags to allow re-resolve after overloads - for (C4PlayerControlAssignmentVec::iterator i = Assignments.begin(); i != Assignments.end(); ++i) - (*i).ResetRefsResolved(); + for (auto & Assignment : Assignments) + Assignment.ResetRefsResolved(); // resolve in order; ignore already resolved because they might have been resolved by cross reference - for (C4PlayerControlAssignmentVec::iterator i = Assignments.begin(); i != Assignments.end(); ++i) - if (!(*i).IsRefsResolved()) - if (!(*i).ResolveRefs(this, pDefs)) + for (auto & Assignment : Assignments) + if (!Assignment.IsRefsResolved()) + if (!Assignment.ResolveRefs(this, pDefs)) return false; return true; } @@ -620,22 +614,22 @@ C4PlayerControlAssignment *C4PlayerControlAssignmentSet::GetAssignmentByIndex(in C4PlayerControlAssignment *C4PlayerControlAssignmentSet::GetAssignmentByControlName(const char *szControlName) { - for (C4PlayerControlAssignmentVec::iterator i = Assignments.begin(); i != Assignments.end(); ++i) - if (SEqual((*i).GetControlName(), szControlName)) + for (auto & Assignment : Assignments) + if (SEqual(Assignment.GetControlName(), szControlName)) // We don't like release keys... (2do) - if (!((*i).GetTriggerMode() & C4PlayerControlAssignment::CTM_Release)) - return &*i; + if (!(Assignment.GetTriggerMode() & C4PlayerControlAssignment::CTM_Release)) + return &Assignment; return nullptr; } C4PlayerControlAssignment *C4PlayerControlAssignmentSet::GetAssignmentByControl(int32_t control) { // TODO: Might want to stuff this into a vector indexed by control for faster lookup - for (C4PlayerControlAssignmentVec::iterator i = Assignments.begin(); i != Assignments.end(); ++i) - if ((*i).GetControl() == control) + for (auto & Assignment : Assignments) + if (Assignment.GetControl() == control) // We don't like release keys... (2do) - if (!((*i).GetTriggerMode() & C4PlayerControlAssignment::CTM_Release)) - return &*i; + if (!(Assignment.GetTriggerMode() & C4PlayerControlAssignment::CTM_Release)) + return &Assignment; return nullptr; } @@ -649,9 +643,8 @@ void C4PlayerControlAssignmentSet::GetAssignmentsByKey(const C4PlayerControlDefs { assert(pOutVec); // primary match by TriggerKey (todo: Might use a hash map here if matching speed becomes an issue due to large control sets) - for (C4PlayerControlAssignmentVec::const_iterator i = Assignments.begin(); i != Assignments.end(); ++i) + for (const auto & rAssignment : Assignments) { - const C4PlayerControlAssignment &rAssignment = *i; const C4KeyCodeEx &rAssignmentTriggerKey = rAssignment.GetTriggerKey(); if (!(rAssignmentTriggerKey.Key == key.Key)) continue; // special: hold-keys-only ignore shift, because shift state might have been release during hold @@ -680,9 +673,8 @@ void C4PlayerControlAssignmentSet::GetTriggerKeys(const C4PlayerControlDefs &rDe { // put all trigger keys of keyset into output vectors // first all hold keys - for (C4PlayerControlAssignmentVec::const_iterator i = Assignments.begin(); i != Assignments.end(); ++i) + for (const auto & rAssignment : Assignments) { - const C4PlayerControlAssignment &rAssignment = *i; const C4PlayerControlDef *pDef = rDefs.GetControlByIndex(rAssignment.GetControl()); if (pDef && pDef->IsHoldKey()) { @@ -691,9 +683,8 @@ void C4PlayerControlAssignmentSet::GetTriggerKeys(const C4PlayerControlDefs &rDe } } // then all regular keys that aren't in the hold keys list yet - for (C4PlayerControlAssignmentVec::const_iterator i = Assignments.begin(); i != Assignments.end(); ++i) + for (const auto & rAssignment : Assignments) { - const C4PlayerControlAssignment &rAssignment = *i; const C4PlayerControlDef *pDef = rDefs.GetControlByIndex(rAssignment.GetControl()); if (pDef && !pDef->IsHoldKey()) { @@ -749,9 +740,8 @@ void C4PlayerControlAssignmentSets::MergeFrom(const C4PlayerControlAssignmentSet // if source set is flagged to clear previous, do this! if (Src.clear_previous) Sets.clear(); // take over all assignments in known sets and new sets defined in Src - for (AssignmentSetList::const_iterator i = Src.Sets.begin(); i != Src.Sets.end(); ++i) + for (const auto & SrcSet : Src.Sets) { - const C4PlayerControlAssignmentSet &SrcSet = *i; // overwrite if def of same name existed if it's not low priority anyway bool fIsWildcardSet = SrcSet.IsWildcardName(); if (!fIsWildcardSet) @@ -775,9 +765,8 @@ void C4PlayerControlAssignmentSets::MergeFrom(const C4PlayerControlAssignmentSet else { // source is a wildcard: Merge with all matching sets - for (AssignmentSetList::iterator j = Sets.begin(); j != Sets.end(); ++j) + for (auto & DstSet : Sets) { - C4PlayerControlAssignmentSet &DstSet = *j; if (WildcardMatch(SrcSet.GetName(), DstSet.GetName())) { DstSet.MergeFrom(SrcSet, merge_mode); @@ -789,22 +778,22 @@ void C4PlayerControlAssignmentSets::MergeFrom(const C4PlayerControlAssignmentSet bool C4PlayerControlAssignmentSets::ResolveRefs(C4PlayerControlDefs *pDefs) { - for (AssignmentSetList::iterator i = Sets.begin(); i != Sets.end(); ++i) - if (!(*i).ResolveRefs(pDefs)) return false; + for (auto & Set : Sets) + if (!Set.ResolveRefs(pDefs)) return false; return true; } void C4PlayerControlAssignmentSets::SortAssignments() { - for (AssignmentSetList::iterator i = Sets.begin(); i != Sets.end(); ++i) - (*i).SortAssignments(); + for (auto & Set : Sets) + Set.SortAssignments(); } C4PlayerControlAssignmentSet *C4PlayerControlAssignmentSets::GetSetByName(const char *szName) { - for (AssignmentSetList::iterator i = Sets.begin(); i != Sets.end(); ++i) - if (WildcardMatch(szName, (*i).GetName())) - return &*i; + for (auto & Set : Sets) + if (WildcardMatch(szName, Set.GetName())) + return &Set; return nullptr; } @@ -837,7 +826,7 @@ C4PlayerControlAssignmentSet *C4PlayerControlAssignmentSets::GetSetByIndex(int32 C4PlayerControlAssignmentSet *C4PlayerControlAssignmentSets::CreateEmptySetByTemplate(const C4PlayerControlAssignmentSet &template_set) { - Sets.push_back(C4PlayerControlAssignmentSet()); + Sets.emplace_back(); Sets.back().InitEmptyFromTemplate(template_set); return &Sets.back(); } @@ -1378,7 +1367,7 @@ void C4PlayerControl::Clear() { iPlr = NO_OWNER; pControlSet = nullptr; - for (KeyBindingList::iterator i = KeyBindings.begin(); i != KeyBindings.end(); ++i) delete *i; + for (auto & KeyBinding : KeyBindings) delete KeyBinding; KeyBindings.clear(); RecentKeys.clear(); DownKeys.clear(); diff --git a/src/control/C4Record.cpp b/src/control/C4Record.cpp index 32607fb7c..650ef7a04 100644 --- a/src/control/C4Record.cpp +++ b/src/control/C4Record.cpp @@ -106,9 +106,7 @@ C4Record::C4Record() { } -C4Record::~C4Record() -{ -} +C4Record::~C4Record() = default; bool C4Record::Start(bool fInitial) { @@ -493,19 +491,19 @@ bool C4Playback::Open(C4Group &rGrp) { if (!DbgRecFile.Create(Config.General.DebugRecExternalFile)) { - LogFatal(FormatString("DbgRec: Creation of external file \"%s\" failed!", Config.General.DebugRecExternalFile).getData()); + LogFatal(FormatString(R"(DbgRec: Creation of external file "%s" failed!)", Config.General.DebugRecExternalFile).getData()); return false; } - else LogF("DbgRec: Writing to \"%s\"...", Config.General.DebugRecExternalFile); + else LogF(R"(DbgRec: Writing to "%s"...)", Config.General.DebugRecExternalFile); } else { if (!DbgRecFile.Open(Config.General.DebugRecExternalFile)) { - LogFatal(FormatString("DbgRec: Opening of external file \"%s\" failed!", Config.General.DebugRecExternalFile).getData()); + LogFatal(FormatString(R"(DbgRec: Opening of external file "%s" failed!)", Config.General.DebugRecExternalFile).getData()); return false; } - else LogF("DbgRec: Checking against \"%s\"...", Config.General.DebugRecExternalFile); + else LogF(R"(DbgRec: Checking against "%s"...)", Config.General.DebugRecExternalFile); } } // ok @@ -625,7 +623,7 @@ void C4Playback::NextChunk() // end of all chunks if not loading sequential here if (!fLoadSequential) return; // otherwise, get next few chunks - for (chunks_t::iterator i = chunks.begin(); i != chunks.end(); i++) i->Delete(); + for (auto & chunk : chunks) chunk.Delete(); chunks.clear(); currChunk = chunks.end(); NextSequentialChunk(); } @@ -920,7 +918,7 @@ void C4Playback::Finish() void C4Playback::Clear() { // free stuff - for (chunks_t::iterator i = chunks.begin(); i != chunks.end(); i++) i->Delete(); + for (auto & chunk : chunks) chunk.Delete(); chunks.clear(); currChunk = chunks.end(); playbackFile.Close(); sequentialBuffer.Clear(); diff --git a/src/editor/C4Console.cpp b/src/editor/C4Console.cpp index faa2975b8..832b85f54 100644 --- a/src/editor/C4Console.cpp +++ b/src/editor/C4Console.cpp @@ -56,9 +56,7 @@ C4Console::C4Console(): C4ConsoleGUI() #endif } -C4Console::~C4Console() -{ -} +C4Console::~C4Console() = default; C4Window * C4Console::Init(C4AbstractApp * pApp) { @@ -416,14 +414,14 @@ void C4Console::ClearPointers(C4Object *pObj) void C4Console::Default() { EditCursor.Default(); - PropertyDlgObject = 0; + PropertyDlgObject = nullptr; ToolsDlg.Default(); } void C4Console::Clear() { if (pSurface) delete pSurface; - pSurface = 0; + pSurface = nullptr; C4Window::Clear(); C4ConsoleGUI::DeleteConsoleWindow(); @@ -635,8 +633,8 @@ std::list C4Console::GetScriptSuggestions(C4PropList *target, Rece functions.insert(functions.begin(), nullptr); // add pointers into string buffer list // do not iterate with for (auto i : mru) because this would copy the buffer and add stack pointers - for (auto i = mru.begin(); i != mru.end(); ++i) - functions.insert(functions.begin(), i->getData()); + for (const auto & i : mru) + functions.insert(functions.begin(), i.getData()); } return functions; } @@ -647,7 +645,7 @@ void C4Console::RegisterRecentInput(const char *input, RecentScriptInputLists se // remove previous copy (i.e.: Same input just gets pushed to top) mru.remove(StdCopyStrBuf(input)); // register to list - mru.push_back(StdCopyStrBuf(input)); + mru.emplace_back(input); // limit history length if (static_cast(mru.size()) > ::Config.Developer.MaxScriptMRU) mru.erase(mru.begin()); @@ -669,7 +667,7 @@ void C4ConsoleGUI::AddMenuItemForPlayer(C4Player*, StdStrBuf&) {} void C4ConsoleGUI::AddNetMenuItemForPlayer(int32_t, const char *, C4ConsoleGUI::ClientOperation) {} void C4ConsoleGUI::AddNetMenu() {} void C4ConsoleGUI::ToolsDlgClose() {} -bool C4ConsoleGUI::ClearLog() {return 0;} +bool C4ConsoleGUI::ClearLog() {return false;} void C4ConsoleGUI::ClearNetMenu() {} void C4ConsoleGUI::ClearPlayerMenu() {} void C4ConsoleGUI::ClearViewportMenu() {} @@ -683,11 +681,11 @@ bool C4ConsoleGUI::CreateConsoleWindow(C4AbstractApp * pApp) void C4ConsoleGUI::DeleteConsoleWindow() {} void C4ConsoleGUI::DisplayInfoText(C4ConsoleGUI::InfoTextType, StdStrBuf&) {} void C4ConsoleGUI::DoEnableControls(bool) {} -bool C4ConsoleGUI::DoUpdateHaltCtrls(bool) {return 0;} -bool C4ConsoleGUI::FileSelect(StdStrBuf *, char const*, DWORD, bool) {return 0;} -bool C4ConsoleGUI::Message(char const*, bool) {return 0;} +bool C4ConsoleGUI::DoUpdateHaltCtrls(bool) {return false;} +bool C4ConsoleGUI::FileSelect(StdStrBuf *, char const*, DWORD, bool) {return false;} +bool C4ConsoleGUI::Message(char const*, bool) {return false;} void C4ConsoleGUI::Out(char const*) {} -bool C4ConsoleGUI::PropertyDlgOpen() {return 0;} +bool C4ConsoleGUI::PropertyDlgOpen() {return false;} void C4ConsoleGUI::PropertyDlgClose() {} void C4ConsoleGUI::PropertyDlgUpdate(class C4EditCursorSelection &, bool) {} void C4ConsoleGUI::RecordingEnabled() {} @@ -696,22 +694,22 @@ void C4ConsoleGUI::SetCursor(C4ConsoleGUI::Cursor) {} void C4ConsoleGUI::SetInputFunctions(std::list&) {} void C4ConsoleGUI::ShowAboutWithCopyright(StdStrBuf&) {} void C4ConsoleGUI::ToolsDlgInitMaterialCtrls(C4ToolsDlg*) {} -bool C4ConsoleGUI::ToolsDlgOpen(C4ToolsDlg*) {return 0;} +bool C4ConsoleGUI::ToolsDlgOpen(C4ToolsDlg*) {return false;} void C4ConsoleGUI::ToolsDlgSelectMaterial(C4ToolsDlg*, char const*) {} void C4ConsoleGUI::ToolsDlgSelectTexture(C4ToolsDlg*, char const*) {} void C4ConsoleGUI::ToolsDlgSelectBackMaterial(C4ToolsDlg*, char const*) {} void C4ConsoleGUI::ToolsDlgSelectBackTexture(C4ToolsDlg*, char const*) {} -bool C4ConsoleGUI::UpdateModeCtrls(int) {return 0;} +bool C4ConsoleGUI::UpdateModeCtrls(int) {return false;} void C4ToolsDlg::EnableControls() {} void C4ToolsDlg::InitGradeCtrl() {} void C4ToolsDlg::NeedPreviewUpdate() {} -bool C4ToolsDlg::PopMaterial() {return 0;} -bool C4ToolsDlg::PopTextures() {return 0;} +bool C4ToolsDlg::PopMaterial() {return false;} +bool C4ToolsDlg::PopTextures() {return false;} void C4ToolsDlg::UpdateIFTControls() {} void C4ToolsDlg::UpdateLandscapeModeCtrls() {} void C4ToolsDlg::UpdateTextures() {} void C4ToolsDlg::UpdateToolCtrls() {} -bool C4Viewport::ScrollBarsByViewPosition() {return 0;} -bool C4Viewport::TogglePlayerLock() {return 0;} +bool C4Viewport::ScrollBarsByViewPosition() {return false;} +bool C4Viewport::TogglePlayerLock() {return false;} #include "editor/C4ConsoleGUICommon.h" #endif diff --git a/src/editor/C4ConsoleQt.cpp b/src/editor/C4ConsoleQt.cpp index c6228045e..b259c3d68 100644 --- a/src/editor/C4ConsoleQt.cpp +++ b/src/editor/C4ConsoleQt.cpp @@ -165,7 +165,7 @@ bool C4ConsoleGUI::FileSelect(StdStrBuf *sFilename, const char * szFilter, DWORD } #ifdef USE_WIN32_WINDOWS // cwd backup - size_t l = GetCurrentDirectoryW(0, 0); + size_t l = GetCurrentDirectoryW(0, nullptr); std::unique_ptr wd(new wchar_t[l]); GetCurrentDirectoryW(l, wd.get()); #endif diff --git a/src/editor/C4ConsoleQtDefinitionListViewer.cpp b/src/editor/C4ConsoleQtDefinitionListViewer.cpp index 8fdf1ecd9..ef955016b 100644 --- a/src/editor/C4ConsoleQtDefinitionListViewer.cpp +++ b/src/editor/C4ConsoleQtDefinitionListViewer.cpp @@ -51,9 +51,7 @@ C4ConsoleQtDefinitionListModel::C4ConsoleQtDefinitionListModel() ReInit(); } -C4ConsoleQtDefinitionListModel::~C4ConsoleQtDefinitionListModel() -{ -} +C4ConsoleQtDefinitionListModel::~C4ConsoleQtDefinitionListModel() = default; void C4ConsoleQtDefinitionListModel::EnsureInit() { @@ -67,9 +65,9 @@ void C4ConsoleQtDefinitionListModel::ReInit() { // Re-fill definition model with all loaded definitions matching condition // (TODO: Add conditional lists) - root.reset(new DefListNode()); + root = std::make_unique(); int32_t index = 0; C4Def *def; - while (def = ::Definitions.GetDef(index++)) + while ((def = ::Definitions.GetDef(index++))) { // Ignore hidden defs if (def->HideInCreator) continue; diff --git a/src/editor/C4ConsoleQtNewScenario.cpp b/src/editor/C4ConsoleQtNewScenario.cpp index b504f827a..d2755d3b0 100644 --- a/src/editor/C4ConsoleQtNewScenario.cpp +++ b/src/editor/C4ConsoleQtNewScenario.cpp @@ -30,7 +30,7 @@ C4ConsoleQtDefinitionFileListModel::DefFileInfo::DefFileInfo(C4ConsoleQtDefiniti // Delay opening of groups until information is actually requested // Full names into child groups in C4S always delimeted with backslashes if (parent->full_filename.getLength()) - full_filename = parent->full_filename + "\\" + filename; + full_filename = parent->full_filename + R"(\)" + filename; else full_filename = filename; } @@ -184,13 +184,9 @@ void C4ConsoleQtDefinitionFileListModel::DefFileInfo::AddExtraDef(const char *de } -C4ConsoleQtDefinitionFileListModel::C4ConsoleQtDefinitionFileListModel() -{ -} +C4ConsoleQtDefinitionFileListModel::C4ConsoleQtDefinitionFileListModel() = default; -C4ConsoleQtDefinitionFileListModel::~C4ConsoleQtDefinitionFileListModel() -{ -} +C4ConsoleQtDefinitionFileListModel::~C4ConsoleQtDefinitionFileListModel() = default; void C4ConsoleQtDefinitionFileListModel::AddExtraDef(const char *def) { @@ -513,7 +509,7 @@ void C4ConsoleQtNewScenarioDlg::CreatePressed() // (Also replace space, because spaces in filenames suk) static char ReplaceSpecialFilenameChars(char c) { - const char *special_chars = "\\/:<>|$?\" "; + const char *special_chars = R"(\/:<>|$?" )"; return strchr(special_chars, c) ? '_' : c; } diff --git a/src/editor/C4ConsoleQtPropListViewer.cpp b/src/editor/C4ConsoleQtPropListViewer.cpp index c4a54832d..8b87e5f9b 100644 --- a/src/editor/C4ConsoleQtPropListViewer.cpp +++ b/src/editor/C4ConsoleQtPropListViewer.cpp @@ -67,12 +67,12 @@ C4PropertyPath::C4PropertyPath(C4Effect *fx, C4Object *target_obj) : get_path_ty if (ofx == fx) break; else if (!strcmp(ofx->GetName(), name)) ++index; if (target_obj) { - get_path.Format("GetEffect(\"%s\", Object(%d), %d)", name, (int)target_obj->Number, (int)index); + get_path.Format(R"(GetEffect("%s", Object(%d), %d))", name, (int)target_obj->Number, (int)index); root.Format("Object(%d)", (int)target_obj->Number); } else { - get_path.Format("GetEffect(\"%s\", nil, %d)", name, (int)index); + get_path.Format(R"(GetEffect("%s", nil, %d))", name, (int)index); root = ::Strings.P[P_Global].GetData(); } } @@ -332,7 +332,7 @@ void C4PropertyDelegateString::SetModelData(QObject *editor, const C4PropertyPat { QString new_value = line_edit->text(); // TODO: Would be better to handle escaping in the C4Value-to-string code - new_value = new_value.replace("\\", "\\\\").replace("\"", "\\\""); + new_value = new_value.replace(R"(\)", R"(\\)").replace(R"(")", R"(\")"); property_path.SetProperty(C4VString(new_value.toUtf8())); factory->GetPropertyModel()->DoOnUpdateCall(property_path, this); line_edit->commit_pending = false; @@ -842,7 +842,7 @@ void C4StyledItemDelegateWithButton::paint(QPainter *painter, const QStyleOption C4DeepQComboBox::C4DeepQComboBox(QWidget *parent, C4StyledItemDelegateWithButton::ButtonType button_type, bool editable) : QComboBox(parent), last_popup_height(0), is_next_close_blocked(false), editable(editable), manual_text_edited(false) { - item_delegate.reset(new C4StyledItemDelegateWithButton(button_type)); + item_delegate = std::make_unique(button_type); QTreeView *view = new QTreeView(this); view->setFrameShape(QFrame::NoFrame); view->setSelectionBehavior(QTreeView::SelectRows); @@ -2215,10 +2215,10 @@ bool C4PropertyDelegateGraph::IsVertexPasteValid(const C4Value &val) const const C4Value &pt = arr->GetItem(i_pt); const C4PropList *ptp = pt.getPropList(); if (!ptp) return false; - for (int32_t i_prop = 0; i_prop < n_props; ++i_prop) + for (auto & property_name : property_names) { C4Value ptprop; - if (!ptp->GetProperty(property_names[i_prop], &ptprop)) return false; + if (!ptp->GetProperty(property_name, &ptprop)) return false; if (ptprop.GetType() != C4V_Int) return false; } } @@ -2635,9 +2635,7 @@ C4ConsoleQtPropListModel::C4ConsoleQtPropListModel(C4PropertyDelegateFactory *de layout_valid = false; } -C4ConsoleQtPropListModel::~C4ConsoleQtPropListModel() -{ -} +C4ConsoleQtPropListModel::~C4ConsoleQtPropListModel() = default; bool C4ConsoleQtPropListModel::AddPropertyGroup(C4PropList *add_proplist, int32_t group_index, QString name, C4PropList *target_proplist, const C4PropertyPath &group_target_path, C4Object *base_object, C4String *default_selection, int32_t *default_selection_index) { @@ -2835,7 +2833,7 @@ void C4ConsoleQtPropListModel::SetBasePropList(C4PropList *new_proplist) void C4ConsoleQtPropListModel::DescendPath(const C4Value &new_value, C4PropList *new_info_proplist, const C4PropertyPath &new_path) { // Add previous proplist to stack - target_path_stack.push_back(TargetStackEntry(target_path, target_value, info_proplist)); + target_path_stack.emplace_back(target_path, target_value, info_proplist); // descend target_value = new_value; info_proplist.SetPropList(new_info_proplist); @@ -3132,7 +3130,7 @@ void C4ConsoleQtPropListModel::DoOnUpdateCall(const C4PropertyPath &updated_path C4Value q; if (base_proplist && base_proplist->GetProperty(P_EditorPropertyChanged, &q)) { - ::Console.EditCursor.EMControl(CID_Script, new C4ControlScript(FormatString("%s->%s(\"%s\")", updated_path.GetRoot(), ::Strings.P[P_EditorPropertyChanged].GetCStr(), updated_path.GetGetPath()).getData(), 0, false)); + ::Console.EditCursor.EMControl(CID_Script, new C4ControlScript(FormatString(R"(%s->%s("%s"))", updated_path.GetRoot(), ::Strings.P[P_EditorPropertyChanged].GetCStr(), updated_path.GetGetPath()).getData(), 0, false)); } } diff --git a/src/editor/C4ConsoleQtState.cpp b/src/editor/C4ConsoleQtState.cpp index d1651cf2f..ba968a1a0 100644 --- a/src/editor/C4ConsoleQtState.cpp +++ b/src/editor/C4ConsoleQtState.cpp @@ -594,9 +594,7 @@ C4ConsoleGUIState::C4ConsoleGUIState(C4ConsoleGUI *console) : viewport_area(null { } -C4ConsoleGUIState::~C4ConsoleGUIState() -{ -} +C4ConsoleGUIState::~C4ConsoleGUIState() = default; void C4ConsoleGUIState::AddToolbarSpacer(int space) { @@ -631,9 +629,9 @@ bool C4ConsoleGUIState::CreateConsoleWindow(C4AbstractApp *app) // stay valid over the lifetime of the application. static int fake_argc = 1; static const char *fake_argv[] = { "openclonk" }; - application.reset(new QApplication(fake_argc, const_cast(fake_argv))); + application = std::make_unique(fake_argc, const_cast(fake_argv)); application->installTranslator(&qt_translator); - window.reset(new C4ConsoleQtMainWindow(app, this)); + window = std::make_unique(app, this); ui.setupUi(window.get()); // Setup some extra stuff that cannot be done easily in the designer @@ -692,29 +690,29 @@ bool C4ConsoleGUIState::CreateConsoleWindow(C4AbstractApp *app) // (none right now) // Property editor - property_delegate_factory.reset(new C4PropertyDelegateFactory()); + property_delegate_factory = std::make_unique(); ui.propertyTable->setItemDelegateForColumn(1, property_delegate_factory.get()); ui.propertyEditAscendPathButton->setMaximumWidth(ui.propertyEditAscendPathButton->fontMetrics().boundingRect(ui.propertyEditAscendPathButton->text()).width() + 10); ui.propertyTable->setDropIndicatorShown(true); ui.propertyTable->setAcceptDrops(true); - property_name_delegate.reset(new C4PropertyNameDelegate()); + property_name_delegate = std::make_unique(); ui.propertyTable->setItemDelegateForColumn(0, property_name_delegate.get()); ui.propertyTable->setMouseTracking(true); // View models - property_model.reset(new C4ConsoleQtPropListModel(property_delegate_factory.get())); + property_model = std::make_unique(property_delegate_factory.get()); property_delegate_factory->SetPropertyModel(property_model.get()); property_name_delegate->SetPropertyModel(property_model.get()); QItemSelectionModel *m = ui.propertyTable->selectionModel(); ui.propertyTable->setModel(property_model.get()); delete m; property_model->SetSelectionModel(ui.propertyTable->selectionModel()); - object_list_model.reset(new C4ConsoleQtObjectListModel()); + object_list_model = std::make_unique(); m = ui.objectListView->selectionModel(); ui.objectListView->setModel(object_list_model.get()); delete m; window->connect(ui.objectListView->selectionModel(), &QItemSelectionModel::selectionChanged, window.get(), &C4ConsoleQtMainWindow::OnObjectListSelectionChanged); - definition_list_model.reset(new C4ConsoleQtDefinitionListModel()); + definition_list_model = std::make_unique(); property_delegate_factory->SetDefinitionListModel(definition_list_model.get()); m = ui.creatorTreeView->selectionModel(); ui.creatorTreeView->setModel(definition_list_model.get()); @@ -852,12 +850,12 @@ static void SetComboItems(QComboBox *box, std::list &items) { QString text = box->lineEdit()->text(); // remember and restore current text box->clear(); - for (std::list::iterator it = items.begin(); it != items.end(); it++) + for (auto & item : items) { - if (!*it) + if (!item) box->addItem("----------"); else - box->addItem(*it); + box->addItem(item); } box->lineEdit()->setText(text); } @@ -1147,15 +1145,14 @@ bool C4ConsoleGUIState::CreateNewScenario(StdStrBuf *out_filename, bool *out_hos void C4ConsoleGUIState::InitWelcomeScreen() { // Init links - ui.welcomeNewLabel->setText(QString("%1").arg(ui.welcomeNewLabel->text())); - ui.welcomeOpenLabel->setText(QString("%1").arg(ui.welcomeOpenLabel->text())); - ui.welcomeExploreUserPathLabel->setText(QString("%1").arg(ui.welcomeExploreUserPathLabel->text())); + ui.welcomeNewLabel->setText(QString(R"(%1)").arg(ui.welcomeNewLabel->text())); + ui.welcomeOpenLabel->setText(QString(R"(%1)").arg(ui.welcomeOpenLabel->text())); + ui.welcomeExploreUserPathLabel->setText(QString(R"(%1)").arg(ui.welcomeExploreUserPathLabel->text())); // Recently opened scenarios bool any_file = false; int recent_idx = ui.welcomeScrollLayout->indexOf(ui.welcomeRecentLabel); - for (int32_t i = 0; i < CFG_MaxEditorMRU; ++i) + for (auto filename : ::Config.Developer.RecentlyEditedSzenarios) { - const char *filename = ::Config.Developer.RecentlyEditedSzenarios[i]; if (*filename && ::ItemExists(filename)) { StdStrBuf basename(GetFilename(filename), true); @@ -1174,7 +1171,7 @@ void C4ConsoleGUIState::InitWelcomeScreen() ui.welcomeScrollLayout->insertWidget(++recent_idx, link); link->setIndent(ui.welcomeOpenLabel->indent()); link->setTextInteractionFlags(ui.welcomeOpenLabel->textInteractionFlags()); - link->setText(QString("%2").arg(filename).arg(basename.getData())); // let's hope file names never contain " + link->setText(QString(R"(%2)").arg(filename).arg(basename.getData())); // let's hope file names never contain " any_file = true; window->connect(link, SIGNAL(linkActivated(QString)), window.get(), SLOT(WelcomeLinkActivated(QString))); } diff --git a/src/editor/C4ConsoleWin32.cpp b/src/editor/C4ConsoleWin32.cpp index cee5a7ebe..b34a5d28c 100644 --- a/src/editor/C4ConsoleWin32.cpp +++ b/src/editor/C4ConsoleWin32.cpp @@ -515,15 +515,15 @@ public: HBITMAP hbmStatic; HBITMAP hbmExact; - State(C4ToolsDlg *toolsDlg): C4ConsoleGUI::InternalState(toolsDlg), hDialog(0), - hbmBrush(0), hbmBrush2(0), - hbmLine(0), hbmLine2(0), - hbmRect(0), hbmRect2(0), - hbmFill(0), hbmFill2(0), - hbmPicker(0), hbmPicker2(0), - hbmDynamic(0), - hbmStatic(0), - hbmExact(0) + State(C4ToolsDlg *toolsDlg): C4ConsoleGUI::InternalState(toolsDlg), hDialog(nullptr), + hbmBrush(nullptr), hbmBrush2(nullptr), + hbmLine(nullptr), hbmLine2(nullptr), + hbmRect(nullptr), hbmRect2(nullptr), + hbmFill(nullptr), hbmFill2(nullptr), + hbmPicker(nullptr), hbmPicker2(nullptr), + hbmDynamic(nullptr), + hbmStatic(nullptr), + hbmExact(nullptr) { pPreviewWindow = nullptr; } @@ -553,19 +553,19 @@ public: void Clear() { // Unload bitmaps - if (hbmBrush) { DeleteObject(hbmBrush); hbmBrush = 0; } - if (hbmLine) { DeleteObject(hbmLine); hbmLine = 0; } - if (hbmRect) { DeleteObject(hbmRect); hbmRect = 0; } - if (hbmFill) { DeleteObject(hbmFill); hbmFill = 0; } - if (hbmPicker) { DeleteObject(hbmPicker); hbmPicker = 0; } - if (hbmBrush2) { DeleteObject(hbmBrush2); hbmBrush2 = 0; } - if (hbmLine2) { DeleteObject(hbmLine2); hbmLine2 = 0; } - if (hbmRect2) { DeleteObject(hbmRect2); hbmRect2 = 0; } - if (hbmFill2) { DeleteObject(hbmFill2); hbmFill2 = 0; } - if (hbmPicker2) { DeleteObject(hbmPicker2); hbmPicker2 = 0; } - if (hbmDynamic) { DeleteObject(hbmDynamic); hbmDynamic = 0; } - if (hbmStatic) { DeleteObject(hbmStatic); hbmStatic = 0; } - if (hbmExact) { DeleteObject(hbmExact); hbmExact = 0; } + if (hbmBrush) { DeleteObject(hbmBrush); hbmBrush = nullptr; } + if (hbmLine) { DeleteObject(hbmLine); hbmLine = nullptr; } + if (hbmRect) { DeleteObject(hbmRect); hbmRect = nullptr; } + if (hbmFill) { DeleteObject(hbmFill); hbmFill = nullptr; } + if (hbmPicker) { DeleteObject(hbmPicker); hbmPicker = nullptr; } + if (hbmBrush2) { DeleteObject(hbmBrush2); hbmBrush2 = nullptr; } + if (hbmLine2) { DeleteObject(hbmLine2); hbmLine2 = nullptr; } + if (hbmRect2) { DeleteObject(hbmRect2); hbmRect2 = nullptr; } + if (hbmFill2) { DeleteObject(hbmFill2); hbmFill2 = nullptr; } + if (hbmPicker2) { DeleteObject(hbmPicker2); hbmPicker2 = nullptr; } + if (hbmDynamic) { DeleteObject(hbmDynamic); hbmDynamic = nullptr; } + if (hbmStatic) { DeleteObject(hbmStatic); hbmStatic = nullptr; } + if (hbmExact) { DeleteObject(hbmExact); hbmExact = nullptr; } if (pPreviewWindow) { delete pPreviewWindow; @@ -766,7 +766,7 @@ bool C4ConsoleGUI::Win32DialogMessageHandling(MSG *msg) void C4ConsoleGUI::SetCursor(Cursor cursor) { - ::SetCursor(LoadCursor(0,IDC_WAIT)); + ::SetCursor(LoadCursor(nullptr,IDC_WAIT)); } bool C4ConsoleGUI::UpdateModeCtrls(int iMode) @@ -980,8 +980,8 @@ bool C4ConsoleGUI::FileSelect(StdStrBuf *sFilename, const char * szFilter, DWORD ofn.Flags=dwFlags; bool fResult; - size_t l = GetCurrentDirectoryW(0,0); - wchar_t *wd = new wchar_t[l]; + size_t l = GetCurrentDirectoryW(0,nullptr); + auto *wd = new wchar_t[l]; GetCurrentDirectoryW(l,wd); if (fSave) fResult = !!GetSaveFileNameW(&ofn); @@ -990,9 +990,9 @@ bool C4ConsoleGUI::FileSelect(StdStrBuf *sFilename, const char * szFilter, DWORD // Reset working directory to exe path as Windows file dialog might have changed it SetCurrentDirectoryW(wd); delete[] wd; - len = WideCharToMultiByte(CP_UTF8, 0, buffer, ArbitraryMaximumLength, nullptr, 0, 0, 0); + len = WideCharToMultiByte(CP_UTF8, 0, buffer, ArbitraryMaximumLength, nullptr, 0, nullptr, nullptr); sFilename->SetLength(len - 1); - WideCharToMultiByte(CP_UTF8, 0, buffer, ArbitraryMaximumLength, sFilename->getMData(), sFilename->getSize(), 0, 0); + WideCharToMultiByte(CP_UTF8, 0, buffer, ArbitraryMaximumLength, sFilename->getMData(), sFilename->getSize(), nullptr, nullptr); return fResult; } @@ -1071,12 +1071,12 @@ void C4ConsoleGUI::PropertyDlgClose() static void SetComboItems(HWND hCombo, std::list &items) { - for (std::list::iterator it = items.begin(); it != items.end(); it++) + for (auto & item : items) { - if (!*it) + if (!item) SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)L"----------"); else - SendMessage(hCombo,CB_ADDSTRING,0,GetWideLPARAM(*it)); + SendMessage(hCombo,CB_ADDSTRING,0,GetWideLPARAM(item)); } } @@ -1139,12 +1139,12 @@ public: pSurface = new C4Surface(&Application, this); } - ~C4ConsoleGUIPreviewWindow() + ~C4ConsoleGUIPreviewWindow() override { delete pSurface; } - virtual void Close() {} + void Close() override {} }; bool C4ConsoleGUI::ToolsDlgOpen(C4ToolsDlg *dlg) diff --git a/src/editor/C4EditCursor.cpp b/src/editor/C4EditCursor.cpp index 12f69f8d8..afe162f6a 100644 --- a/src/editor/C4EditCursor.cpp +++ b/src/editor/C4EditCursor.cpp @@ -885,7 +885,7 @@ void C4EditCursor::Draw(C4TargetFacet &cgo) creator_def->Shape.Wdt, creator_def->Shape.Hgt, 0, 0, cgo.Zoom, 0, 0); if (!creator_overlay) { - creator_overlay.reset(new C4GraphicsOverlay()); + creator_overlay = std::make_unique(); creator_overlay->SetAsBase(&creator_def->Graphics, C4GFXBLIT_ADDITIVE); } creator_overlay->Draw(cgo_creator, nullptr, NO_OWNER); diff --git a/src/editor/C4ObjectListDlg.cpp b/src/editor/C4ObjectListDlg.cpp index cffdce212..474f19090 100644 --- a/src/editor/C4ObjectListDlg.cpp +++ b/src/editor/C4ObjectListDlg.cpp @@ -24,13 +24,9 @@ #include "script/C4Effect.h" -C4ObjectListDlg::C4ObjectListDlg() -{ -} +C4ObjectListDlg::C4ObjectListDlg() = default; -C4ObjectListDlg::~C4ObjectListDlg() -{ -} +C4ObjectListDlg::~C4ObjectListDlg() = default; void C4ObjectListDlg::Execute() { diff --git a/src/editor/C4ToolsDlg.cpp b/src/editor/C4ToolsDlg.cpp index 77f580f02..6349e4e5e 100644 --- a/src/editor/C4ToolsDlg.cpp +++ b/src/editor/C4ToolsDlg.cpp @@ -130,7 +130,7 @@ void C4ToolsDlg::SetBackTexture(const char *szTexture) bool C4ToolsDlg::SetIFT(bool fIFT) { ModeBack = false; - if (fIFT) ModeIFT = 1; else ModeIFT=0; + if (fIFT) ModeIFT = true; else ModeIFT=false; // Keep sensible default values in BackMaterial / BackTexture if (ModeIFT == 0) diff --git a/src/game/C4Application.cpp b/src/game/C4Application.cpp index 69256d1f3..a25d40b7b 100644 --- a/src/game/C4Application.cpp +++ b/src/game/C4Application.cpp @@ -105,9 +105,9 @@ bool C4Application::DoInit(int argc, char * argv[]) // Engine header message Log(C4ENGINECAPTION); LogF("Version: %s %s (%s - %s)", C4VERSION, C4_OS, GetRevision(), C4REVISION_TS); - LogF("ExePath: \"%s\"", Config.General.ExePath.getData()); - LogF("SystemDataPath: \"%s\"", Config.General.SystemDataPath); - LogF("UserDataPath: \"%s\"", Config.General.UserDataPath); + LogF(R"(ExePath: "%s")", Config.General.ExePath.getData()); + LogF(R"(SystemDataPath: "%s")", Config.General.SystemDataPath); + LogF(R"(UserDataPath: "%s")", Config.General.UserDataPath); // Init C4Group C4Group_SetProcessCallback(&ProcessCallback); @@ -214,7 +214,7 @@ void C4Application::ParseCommandLine(int argc, char * argv[]) Game.NetworkActive = false; isEditor = 2; int c; - while (1) + while (true) { static struct option long_options[] = @@ -231,36 +231,36 @@ void C4Application::ParseCommandLine(int argc, char * argv[]) {"nosignup", no_argument, &Config.Network.MasterServerSignUp, 0}, {"signup", no_argument, &Config.Network.MasterServerSignUp, 1}, - {"debugrecread", required_argument, 0, 'K'}, - {"debugrecwrite", required_argument, 0, 'w'}, + {"debugrecread", required_argument, nullptr, 'K'}, + {"debugrecwrite", required_argument, nullptr, 'w'}, - {"client", required_argument, 0, 'c'}, - {"host", no_argument, 0, 'h'}, - {"debughost", required_argument, 0, 'H'}, - {"debugpass", required_argument, 0, 'P'}, - {"debug", required_argument, 0, 'D'}, - {"data", required_argument, 0, 'd'}, - {"startup", required_argument, 0, 's'}, - {"stream", required_argument, 0, 'e'}, - {"recdump", required_argument, 0, 'R'}, - {"comment", required_argument, 0, 'm'}, - {"pass", required_argument, 0, 'p'}, - {"udpport", required_argument, 0, 'u'}, - {"tcpport", required_argument, 0, 't'}, - {"join", required_argument, 0, 'j'}, - {"language", required_argument, 0, 'L'}, - {"scenpar", required_argument, 0, 'S'}, + {"client", required_argument, nullptr, 'c'}, + {"host", no_argument, nullptr, 'h'}, + {"debughost", required_argument, nullptr, 'H'}, + {"debugpass", required_argument, nullptr, 'P'}, + {"debug", required_argument, nullptr, 'D'}, + {"data", required_argument, nullptr, 'd'}, + {"startup", required_argument, nullptr, 's'}, + {"stream", required_argument, nullptr, 'e'}, + {"recdump", required_argument, nullptr, 'R'}, + {"comment", required_argument, nullptr, 'm'}, + {"pass", required_argument, nullptr, 'p'}, + {"udpport", required_argument, nullptr, 'u'}, + {"tcpport", required_argument, nullptr, 't'}, + {"join", required_argument, nullptr, 'j'}, + {"language", required_argument, nullptr, 'L'}, + {"scenpar", required_argument, nullptr, 'S'}, - {"observe", no_argument, 0, 'o'}, - {"nonetwork", no_argument, 0, 'N'}, - {"network", no_argument, 0, 'n'}, - {"record", no_argument, 0, 'r'}, + {"observe", no_argument, nullptr, 'o'}, + {"nonetwork", no_argument, nullptr, 'N'}, + {"network", no_argument, nullptr, 'n'}, + {"record", no_argument, nullptr, 'r'}, - {"lobby", optional_argument, 0, 'l'}, + {"lobby", optional_argument, nullptr, 'l'}, {"debug-opengl", no_argument, &Config.Graphics.DebugOpenGL, 1}, {"config", required_argument, nullptr, 0}, - {0, 0, 0, 0} + {nullptr, 0, nullptr, 0} }; int option_index = 0; c = getopt_long (argc, argv, "abc:d:f:", diff --git a/src/game/C4FullScreen.cpp b/src/game/C4FullScreen.cpp index 78b7ee967..5a4efe8b6 100644 --- a/src/game/C4FullScreen.cpp +++ b/src/game/C4FullScreen.cpp @@ -64,7 +64,7 @@ void C4FullScreen::Close() void C4FullScreen::Clear() { if (pSurface) delete pSurface; - pSurface = 0; + pSurface = nullptr; C4Window::Clear(); } diff --git a/src/game/C4Game.cpp b/src/game/C4Game.cpp index aed95d6f5..70a365efa 100644 --- a/src/game/C4Game.cpp +++ b/src/game/C4Game.cpp @@ -86,8 +86,8 @@ class C4GameSec1Timer : public C4ApplicationSec1Timer { public: C4GameSec1Timer() { Application.Add(this); } - ~C4GameSec1Timer() { Application.Remove(this); } - void OnSec1Timer(); + ~C4GameSec1Timer() override { Application.Remove(this); } + void OnSec1Timer() override; }; static C4GameParameters GameParameters; @@ -498,7 +498,7 @@ bool C4Game::Init() FullScreen.CloseMenu(); // start statistics (always for now. Make this a config?) - pNetworkStatistics.reset(new C4Network2Stats); + pNetworkStatistics = std::make_unique(); // clear loader screen if (GraphicsSystem.pLoaderScreen) @@ -2119,7 +2119,7 @@ bool C4Game::InitGame(C4Group &hGroup, InitMode init_mode, bool fLoadSky, C4Valu // file monitor if (Config.Developer.AutoFileReload && Application.isEditor && !pFileMonitor) - pFileMonitor.reset(new C4FileMonitor(FileMonitorCallback)); + pFileMonitor = std::make_unique(FileMonitorCallback); // system scripts if (!InitScriptEngine()) @@ -2193,7 +2193,7 @@ bool C4Game::InitGame(C4Group &hGroup, InitMode init_mode, bool fLoadSky, C4Valu // prepare script menus assert(!ScriptGuiRoot); - ScriptGuiRoot.reset(new C4ScriptGuiWindow); + ScriptGuiRoot = std::make_unique(); } else if (fLoadSky) { @@ -2961,33 +2961,33 @@ bool C4Game::InitKeyboard() KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_SUBTRACT, KEYS_Shift), "GameSlowDown", KEYSCOPE_Generic, new C4KeyCB (*this, &C4Game::SlowDown))); // fullscreen menu - Keys.clear(); Keys.push_back(C4KeyCodeEx(K_LEFT)); + Keys.clear(); Keys.emplace_back(K_LEFT); if (Config.Controls.GamepadGuiControl) ControllerKeys::Left(Keys); KeyboardInput.RegisterKey(new C4CustomKey(Keys, "FullscreenMenuLeft", KEYSCOPE_FullSMenu, new C4KeyCBEx (FullScreen, COM_MenuLeft, &C4FullScreen::MenuKeyControl))); - Keys.clear(); Keys.push_back(C4KeyCodeEx(K_RIGHT)); + Keys.clear(); Keys.emplace_back(K_RIGHT); if (Config.Controls.GamepadGuiControl) ControllerKeys::Right(Keys); KeyboardInput.RegisterKey(new C4CustomKey(Keys, "FullscreenMenuRight", KEYSCOPE_FullSMenu, new C4KeyCBEx (FullScreen, COM_MenuRight, &C4FullScreen::MenuKeyControl))); - Keys.clear(); Keys.push_back(C4KeyCodeEx(K_UP)); + Keys.clear(); Keys.emplace_back(K_UP); if (Config.Controls.GamepadGuiControl) ControllerKeys::Up(Keys); KeyboardInput.RegisterKey(new C4CustomKey(Keys, "FullscreenMenuUp", KEYSCOPE_FullSMenu, new C4KeyCBEx (FullScreen, COM_MenuUp, &C4FullScreen::MenuKeyControl))); - Keys.clear(); Keys.push_back(C4KeyCodeEx(K_DOWN)); + Keys.clear(); Keys.emplace_back(K_DOWN); if (Config.Controls.GamepadGuiControl) ControllerKeys::Down(Keys); KeyboardInput.RegisterKey(new C4CustomKey(Keys, "FullscreenMenuDown", KEYSCOPE_FullSMenu, new C4KeyCBEx (FullScreen, COM_MenuDown, &C4FullScreen::MenuKeyControl))); - Keys.clear(); Keys.push_back(C4KeyCodeEx(K_SPACE)); Keys.push_back(C4KeyCodeEx(K_RETURN)); + Keys.clear(); Keys.emplace_back(K_SPACE); Keys.emplace_back(K_RETURN); if (Config.Controls.GamepadGuiControl) ControllerKeys::Ok(Keys); KeyboardInput.RegisterKey(new C4CustomKey(Keys, "FullscreenMenuOK", KEYSCOPE_FullSMenu, new C4KeyCBEx (FullScreen, COM_MenuEnter, &C4FullScreen::MenuKeyControl))); // name used by PlrControlKeyName - Keys.clear(); Keys.push_back(C4KeyCodeEx(K_ESCAPE)); + Keys.clear(); Keys.emplace_back(K_ESCAPE); if (Config.Controls.GamepadGuiControl) ControllerKeys::Cancel(Keys); KeyboardInput.RegisterKey(new C4CustomKey(Keys, "FullscreenMenuCancel", KEYSCOPE_FullSMenu, new C4KeyCBEx (FullScreen, COM_MenuClose, &C4FullScreen::MenuKeyControl))); // name used by PlrControlKeyName - Keys.clear(); Keys.push_back(C4KeyCodeEx(K_SPACE)); + Keys.clear(); Keys.emplace_back(K_SPACE); if (Config.Controls.GamepadGuiControl) ControllerKeys::Any(Keys); KeyboardInput.RegisterKey(new C4CustomKey(Keys, "FullscreenMenuOpen", KEYSCOPE_FreeView, new C4KeyCB (FullScreen, &C4FullScreen::ActivateMenuMain))); // name used by C4MainMenu! KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_RIGHT ), "FilmNextPlayer", KEYSCOPE_FilmView, new C4KeyCB (::Viewports, &C4ViewportList::ViewportNextPlayer))); // chat Keys.clear(); - Keys.push_back(C4KeyCodeEx(K_RETURN)); - Keys.push_back(C4KeyCodeEx(K_F2)); // alternate chat key, if RETURN is blocked by player control + Keys.emplace_back(K_RETURN); + Keys.emplace_back(K_F2); // alternate chat key, if RETURN is blocked by player control KeyboardInput.RegisterKey(new C4CustomKey(Keys, "ChatOpen", KEYSCOPE_Generic, new C4KeyCBEx(MessageInput, false, &C4MessageInput::KeyStartTypeIn))); KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_RETURN, KEYS_Shift), "ChatOpen2Allies", KEYSCOPE_Generic, new C4KeyCBEx(MessageInput, true, &C4MessageInput::KeyStartTypeIn))); @@ -3303,8 +3303,8 @@ bool C4Game::CheckObjectEnumeration() struct Check { - int32_t maxNumber; - Check() : maxNumber(0) {} + int32_t maxNumber{0}; + Check() = default; // Check valid & maximum number & duplicate numbers bool that(C4Object* cObj) { diff --git a/src/game/C4GameScript.cpp b/src/game/C4GameScript.cpp index 3d8b46cfa..fb52c856f 100644 --- a/src/game/C4GameScript.cpp +++ b/src/game/C4GameScript.cpp @@ -226,8 +226,8 @@ static C4ValueArray *FnFindConstructionSite(C4PropList * _this, C4PropList * Pro return nullptr; // Search for real bool result = !!FindConSiteSpot(v1, v2, pDef->Shape.Wdt,pDef->Shape.Hgt, 20); - if(!result) return 0; - C4ValueArray *pArray = new C4ValueArray(2); + if(!result) return nullptr; + auto *pArray = new C4ValueArray(2); pArray->SetItem(0, C4VInt(v1)); pArray->SetItem(1, C4VInt(v2)); return pArray; @@ -1299,7 +1299,7 @@ static C4ValueArray* FnPathFree2(C4PropList * _this, int32_t x1, int32_t y1, int pArray->SetItem(1, C4VInt(y)); return pArray; } - return 0; + return nullptr; } C4Object* FnObject(C4PropList * _this, long iNumber) @@ -1443,11 +1443,11 @@ public: : pszNames(pszNames), iNameCnt(iNameCnt), iEntryNr(iEntryNr) { } - virtual bool isDeserializer() override { return false; } - virtual bool hasNaming() override { return true; } - virtual bool isVerbose() override { return false; } + bool isDeserializer() override { return false; } + bool hasNaming() override { return true; } + bool isVerbose() override { return false; } - virtual bool Name(const char *szName) override + bool Name(const char *szName) override { // match possible? (no match yet / continued match) if (!iMatchStart || haveCurrentMatch()) @@ -1464,13 +1464,13 @@ public: return true; } - virtual bool Default(const char *szName) override + bool Default(const char *szName) override { // Always process values even if they are default! return false; } - virtual void NameEnd(bool fBreak = false) override + void NameEnd(bool fBreak = false) override { // end of matched name section? if (haveCurrentMatch()) @@ -1481,7 +1481,7 @@ public: iDepth--; } - virtual void Begin() override + void Begin() override { // set up iDepth = iMatchStart = iMatchCount = 0; @@ -1509,23 +1509,23 @@ private: } } public: - virtual void DWord(int32_t &rInt) override { MaybeProcessInt(rInt); } - virtual void DWord(uint32_t &rInt) override { MaybeProcessInt(rInt); } - virtual void Word(int16_t &rShort) override { MaybeProcessInt(rShort); } - virtual void Word(uint16_t &rShort) override { MaybeProcessInt(rShort); } - virtual void Byte(int8_t &rByte) override { MaybeProcessInt(rByte); } - virtual void Byte(uint8_t &rByte) override { MaybeProcessInt(rByte); } - virtual void Boolean(bool &rBool) override { if (haveCompleteMatch()) if (!iEntryNr--) ProcessBool(rBool); } - virtual void Character(char &rChar) override { if (haveCompleteMatch()) if (!iEntryNr--) ProcessChar(rChar); } + void DWord(int32_t &rInt) override { MaybeProcessInt(rInt); } + void DWord(uint32_t &rInt) override { MaybeProcessInt(rInt); } + void Word(int16_t &rShort) override { MaybeProcessInt(rShort); } + void Word(uint16_t &rShort) override { MaybeProcessInt(rShort); } + void Byte(int8_t &rByte) override { MaybeProcessInt(rByte); } + void Byte(uint8_t &rByte) override { MaybeProcessInt(rByte); } + void Boolean(bool &rBool) override { if (haveCompleteMatch()) if (!iEntryNr--) ProcessBool(rBool); } + void Character(char &rChar) override { if (haveCompleteMatch()) if (!iEntryNr--) ProcessChar(rChar); } // The C4ID-Adaptor will set RCT_ID for it's strings (see C4Id.h), so we don't have to guess the type. - virtual void String(char *szString, size_t iMaxLength, RawCompileType eType) override + void String(char *szString, size_t iMaxLength, RawCompileType eType) override { if (haveCompleteMatch()) if (!iEntryNr--) ProcessString(szString, iMaxLength, eType == StdCompiler::RCT_ID); } - virtual void String(char **pszString, RawCompileType eType) override + void String(char **pszString, RawCompileType eType) override { if (haveCompleteMatch()) if (!iEntryNr--) ProcessString(pszString, eType == StdCompiler::RCT_ID); } - virtual void String(std::string &str, RawCompileType type) override + void String(std::string &str, RawCompileType type) override { if (haveCompleteMatch()) if (!iEntryNr--) ProcessString(str, type == StdCompiler::RCT_ID); } - virtual void Raw(void *pData, size_t iSize, RawCompileType eType = RCT_Escaped) + void Raw(void *pData, size_t iSize, RawCompileType eType = RCT_Escaped) override { /* C4Script can't handle this */ } private: @@ -1564,15 +1564,15 @@ public: protected: // get values as C4Value - virtual void ProcessInt(int32_t &rInt) override { Res = C4VInt(rInt); } - virtual void ProcessBool(bool &rBool) override { Res = C4VBool(rBool); } - virtual void ProcessChar(char &rChar) override { Res = C4VString(FormatString("%c", rChar)); } + void ProcessInt(int32_t &rInt) override { Res = C4VInt(rInt); } + void ProcessBool(bool &rBool) override { Res = C4VBool(rBool); } + void ProcessChar(char &rChar) override { Res = C4VString(FormatString("%c", rChar)); } - virtual void ProcessString(char *szString, size_t iMaxLength, bool fIsID) override + void ProcessString(char *szString, size_t iMaxLength, bool fIsID) override { Res = (fIsID ? C4VPropList(C4Id2Def(C4ID(szString))) : C4VString(szString)); } - virtual void ProcessString(char **pszString, bool fIsID) override + void ProcessString(char **pszString, bool fIsID) override { Res = (fIsID ? C4VPropList(C4Id2Def(C4ID(*pszString))) : C4VString(*pszString)); } - virtual void ProcessString(std::string &str, bool fIsID) override + void ProcessString(std::string &str, bool fIsID) override { Res = (fIsID ? C4VPropList(C4Id2Def(C4ID(str.c_str()))) : C4VString(str.c_str())); } }; @@ -2212,7 +2212,7 @@ static bool FnSetViewOffset(C4PropList * _this, long iPlayer, long iX, long iY) if (!ValidPlr(iPlayer)) return false; // get player viewport C4Viewport *pView = ::Viewports.GetViewport(iPlayer); - if (!pView) return 1; // sync safety + if (!pView) return true; // sync safety // set pView->SetViewOffset(iX, iY); // ok @@ -3095,14 +3095,14 @@ C4ScriptConstDef C4ScriptGameConstMap[]= C4ScriptFnDef C4ScriptGameFnMap[]= { - { "FindObject", 1, C4V_Object, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnFindObject }, - { "FindObjects", 1, C4V_Array, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnFindObjects }, - { "ObjectCount", 1, C4V_Int, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnObjectCount }, - { "GameCallEx", 1, C4V_Any, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnGameCallEx }, - { "PlayerMessage", 1, C4V_Int, { C4V_Int ,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnPlayerMessage }, - { "Message", 1, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnMessage }, - { "AddMessage", 1, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnAddMessage }, - { "PV_KeyFrames", 1, C4V_Array, { C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnPV_KeyFrames }, + { "FindObject", true, C4V_Object, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnFindObject }, + { "FindObjects", true, C4V_Array, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnFindObjects }, + { "ObjectCount", true, C4V_Int, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnObjectCount }, + { "GameCallEx", true, C4V_Any, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnGameCallEx }, + { "PlayerMessage", true, C4V_Int, { C4V_Int ,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnPlayerMessage }, + { "Message", true, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnMessage }, + { "AddMessage", true, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnAddMessage }, + { "PV_KeyFrames", true, C4V_Array, { C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnPV_KeyFrames }, - { nullptr, 0, C4V_Nil, { C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil}, 0 } + { nullptr, false, C4V_Nil, { C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil}, nullptr } }; diff --git a/src/game/C4GraphicsSystem.cpp b/src/game/C4GraphicsSystem.cpp index c37137c1a..1e94bf009 100644 --- a/src/game/C4GraphicsSystem.cpp +++ b/src/game/C4GraphicsSystem.cpp @@ -154,7 +154,7 @@ void C4GraphicsSystem::Execute() void C4GraphicsSystem::Default() { - MessageBoard.reset(new C4MessageBoard); + MessageBoard = std::make_unique(); InvalidateBg(); ShowVertices=false; ShowAction=false; diff --git a/src/game/C4Viewport.cpp b/src/game/C4Viewport.cpp index 73d711edd..5670997fa 100644 --- a/src/game/C4Viewport.cpp +++ b/src/game/C4Viewport.cpp @@ -667,7 +667,7 @@ bool C4Viewport::Init(int32_t iPlayer, bool fSetTempOnly) { // Console viewport initialization // Create window - pWindow.reset(new C4ViewportWindow(this)); + pWindow = std::make_unique(this); if (!pWindow->Init(Player)) return false; UpdateOutputSize(); @@ -696,7 +696,7 @@ void C4Viewport::EnableFoW() { if (::Landscape.HasFoW() && Player != NO_OWNER) { - pFoW.reset(new C4FoWRegion(::Landscape.GetFoW(), ::Players.Get(Player))); + pFoW = std::make_unique(::Landscape.GetFoW(), ::Players.Get(Player)); } else { @@ -845,9 +845,7 @@ C4ViewportList::C4ViewportList(): { ViewportArea.Default(); } -C4ViewportList::~C4ViewportList() -{ -} +C4ViewportList::~C4ViewportList() = default; void C4ViewportList::Clear() { C4Viewport *next; diff --git a/src/game/ClonkMain.cpp b/src/game/ClonkMain.cpp index 104538d9f..6a4a2ecf4 100644 --- a/src/game/ClonkMain.cpp +++ b/src/game/ClonkMain.cpp @@ -76,9 +76,9 @@ int WINAPI WinMain (HINSTANCE hInst, LPWSTR *curwarg = wargv; while(argc--) { - int arglen = WideCharToMultiByte(CP_UTF8, 0, *curwarg, -1, nullptr, 0, 0, 0); - char *utf8arg = new char[arglen ? arglen : 1]; - WideCharToMultiByte(CP_UTF8, 0, *curwarg, -1, utf8arg, arglen, 0, 0); + int arglen = WideCharToMultiByte(CP_UTF8, 0, *curwarg, -1, nullptr, 0, nullptr, nullptr); + auto *utf8arg = new char[arglen ? arglen : 1]; + WideCharToMultiByte(CP_UTF8, 0, *curwarg, -1, utf8arg, arglen, nullptr, nullptr); argv.push_back(utf8arg); ++curwarg; } @@ -107,7 +107,7 @@ int WINAPI WinMain (HINSTANCE hInst, int main() { - return WinMain(GetModuleHandle(nullptr), 0, 0, 0); + return WinMain(GetModuleHandle(nullptr), nullptr, nullptr, 0); } #else // _WIN32 @@ -203,7 +203,7 @@ static void restart(char * argv[]) for (int fd = 4; fd < open_max; fd++) fcntl (fd, F_SETFD, FD_CLOEXEC); // Execute the new engine - execlp(argv[0], argv[0], static_cast(0)); + execlp(argv[0], argv[0], static_cast(nullptr)); } int main (int argc, char * argv[]) diff --git a/src/graphics/C4Draw.cpp b/src/graphics/C4Draw.cpp index b31b76b2c..567423c04 100644 --- a/src/graphics/C4Draw.cpp +++ b/src/graphics/C4Draw.cpp @@ -32,7 +32,7 @@ #include "graphics/CSurface8.h" #include "lib/StdColors.h" -#include +#include // Instruct Optimus laptops to use nVidia GPU instead of integrated GPU #if defined(_WIN32) && !defined(USE_CONSOLE) @@ -106,7 +106,7 @@ C4Pattern& C4Pattern::operator=(const C4Pattern& nPattern) } else { - CachedPattern = 0; + CachedPattern = nullptr; } Wdt = nPattern.Wdt; Hgt = nPattern.Hgt; @@ -142,7 +142,7 @@ C4Pattern::C4Pattern() { // disable sfcPattern32=nullptr; - CachedPattern = 0; + CachedPattern = nullptr; Zoom=0; } @@ -156,7 +156,7 @@ void C4Pattern::Clear() // clear field sfcPattern32=nullptr; } - delete[] CachedPattern; CachedPattern = 0; + delete[] CachedPattern; CachedPattern = nullptr; } DWORD C4Pattern::PatternClr(unsigned int iX, unsigned int iY) const @@ -443,8 +443,8 @@ bool C4Draw::Blit8(C4Surface * sfcSource, int fx, int fy, int fwdt, int fhgt, Transform *=* pTransform; C4BltTransform TransformBack; TransformBack.SetAsInv(Transform); - float ttx0=(float)tx, tty0=(float)ty, ttx1=(float)(tx+twdt), tty1=(float)(ty+thgt); - float ttx2=(float)ttx0, tty2=(float)tty1, ttx3=(float)ttx1, tty3=(float)tty0; + auto ttx0=(float)tx, tty0=(float)ty, ttx1=(float)(tx+twdt), tty1=(float)(ty+thgt); + auto ttx2=(float)ttx0, tty2=(float)tty1, ttx3=(float)ttx1, tty3=(float)tty0; pTransform->TransformPoint(ttx0, tty0); pTransform->TransformPoint(ttx1, tty1); pTransform->TransformPoint(ttx2, tty2); @@ -653,8 +653,8 @@ void C4Draw::DrawFrameDw(C4Surface * sfcDest, int x1, int y1, int x2, int y2, DW vertices[6] = vertices[5]; vertices[7] = vertices[0]; - for(int i = 0; i < 8; ++i) - DwTo4UB(dwClr, vertices[i].color); + for(auto & vertex : vertices) + DwTo4UB(dwClr, vertex.color); PerformMultiLines(sfcDest, vertices, 8, width, nullptr); } @@ -753,19 +753,19 @@ void C4Draw::SetGamma(float r, float g, float b, int32_t iRampIndex) // Recalculate resulting gamma. Note that we flip gamma direction here, // because higher gammaOut means darker. gammaOut[0] = gammaOut[1] = gammaOut[2] = 1.0f; - for (int i = 0; i < C4MaxGammaRamps; i++) { - gammaOut[0] /= gamma[i][0]; - gammaOut[1] /= gamma[i][1]; - gammaOut[2] /= gamma[i][2]; + for (auto & i : gamma) { + gammaOut[0] /= i[0]; + gammaOut[1] /= i[1]; + gammaOut[2] /= i[2]; } } void C4Draw::ResetGamma() { - for (int i = 0; i < C4MaxGammaRamps; i++) { - gamma[i][0] = 1.0f; - gamma[i][1] = 1.0f; - gamma[i][2] = 1.0f; + for (auto & i : gamma) { + i[0] = 1.0f; + i[1] = 1.0f; + i[2] = 1.0f; } gammaOut[0] = 1.0f; gammaOut[1] = 1.0f; diff --git a/src/graphics/C4DrawGL.cpp b/src/graphics/C4DrawGL.cpp index f6830ac32..2792eb971 100644 --- a/src/graphics/C4DrawGL.cpp +++ b/src/graphics/C4DrawGL.cpp @@ -35,8 +35,8 @@ #define _USE_MATH_DEFINES #endif /* _MSC_VER */ -#include -#include +#include +#include namespace { @@ -105,7 +105,7 @@ namespace #undef USERPARAM_CONST CStdGL::CStdGL(): - pMainCtx(0), CurrentVBO(0), NextVAOID(VAOIDs.end()) + pMainCtx(nullptr), CurrentVBO(0), NextVAOID(VAOIDs.end()) { GenericVBOs[0] = 0; Default(); @@ -146,7 +146,7 @@ void CStdGL::Clear() SpriteShaderLightBaseNormalOverlayMod2.Clear(); // clear context if (pCurrCtx) pCurrCtx->Deselect(); - pMainCtx=0; + pMainCtx=nullptr; C4Draw::Clear(); } @@ -323,9 +323,9 @@ CStdGLCtx *CStdGL::CreateContext(C4Window * pWindow, C4AbstractApp *pApp) // Must log after context creation to get valid results if (first_ctx) { - const char *gl_vendor = reinterpret_cast(glGetString(GL_VENDOR)); - const char *gl_renderer = reinterpret_cast(glGetString(GL_RENDERER)); - const char *gl_version = reinterpret_cast(glGetString(GL_VERSION)); + const auto *gl_vendor = reinterpret_cast(glGetString(GL_VENDOR)); + const auto *gl_renderer = reinterpret_cast(glGetString(GL_RENDERER)); + const auto *gl_version = reinterpret_cast(glGetString(GL_VERSION)); LogF("GL %s on %s (%s)", gl_version ? gl_version : "", gl_renderer ? gl_renderer : "", gl_vendor ? gl_vendor : ""); if (Config.Graphics.DebugOpenGL) @@ -831,8 +831,8 @@ bool CStdGL::InvalidateDeviceObjects() glDeleteBuffers(N_GENERIC_VBOS, GenericVBOs); GenericVBOs[0] = 0; CurrentVBO = 0; - for (unsigned int i = 0; i < N_GENERIC_VBOS * 2; ++i) - FreeVAOID(GenericVAOs[i]); + for (unsigned int GenericVAO : GenericVAOs) + FreeVAOID(GenericVAO); } // invalidate shaders @@ -991,9 +991,8 @@ void CStdGL::FreeVAOID(unsigned int vaoid) // For all other contexts, mark it to be deleted as soon as we select // that context. Otherwise we would need to do a lot of context // switching at this point. - for (std::list::iterator iter = CStdGLCtx::contexts.begin(); iter != CStdGLCtx::contexts.end(); ++iter) + for (auto ctx : CStdGLCtx::contexts) { - CStdGLCtx* ctx = *iter; if (ctx != pCurrCtx && vaoid < ctx->hVAOs.size() && ctx->hVAOs[vaoid] != 0) if (std::find(ctx->VAOsToBeDeleted.begin(), ctx->VAOsToBeDeleted.end(), vaoid) == ctx->VAOsToBeDeleted.end()) ctx->VAOsToBeDeleted.push_back(vaoid); diff --git a/src/graphics/C4DrawGLCtx.cpp b/src/graphics/C4DrawGLCtx.cpp index 26381f294..83a54bd8c 100644 --- a/src/graphics/C4DrawGLCtx.cpp +++ b/src/graphics/C4DrawGLCtx.cpp @@ -42,12 +42,12 @@ void CStdGLCtx::SelectCommon() std::vector toBeDeleted; if (!VAOsToBeDeleted.empty()) { - for (unsigned int i = 0; i < VAOsToBeDeleted.size(); ++i) + for (unsigned int i : VAOsToBeDeleted) { - if (VAOsToBeDeleted[i] < hVAOs.size() && hVAOs[VAOsToBeDeleted[i]] != 0) + if (i < hVAOs.size() && hVAOs[i] != 0) { - toBeDeleted.push_back(hVAOs[VAOsToBeDeleted[i]]); - hVAOs[VAOsToBeDeleted[i]] = 0; + toBeDeleted.push_back(hVAOs[i]); + hVAOs[i] = 0; } } @@ -61,7 +61,7 @@ void CStdGLCtx::SelectCommon() #include static PIXELFORMATDESCRIPTOR pfd; // desired pixel format -static HGLRC hrc = 0; +static HGLRC hrc = nullptr; // Enumerate available pixel formats. Choose the best pixel format in // terms of color and depth buffer bits and then return all formats with @@ -143,17 +143,17 @@ static std::vector EnumeratePixelFormats(HDC hdc) static int GetPixelFormatForMS(HDC hDC, int samples) { std::vector vec = EnumeratePixelFormats(hDC); - for(unsigned int i = 0; i < vec.size(); ++i) + for(int i : vec) { int attributes[] = { WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB }; const unsigned int n_attributes = 2; int results[2]; - if(!wglGetPixelFormatAttribivARB(hDC, vec[i], 0, n_attributes, attributes, results)) continue; + if(!wglGetPixelFormatAttribivARB(hDC, i, 0, n_attributes, attributes, results)) continue; if( (samples == 0 && results[0] == 0) || (samples > 0 && results[0] == 1 && results[1] == samples)) { - return vec[i]; + return i; } } @@ -171,9 +171,9 @@ public: private: static std::string format_error(error_code err) { - LPWSTR buffer = 0; + LPWSTR buffer = nullptr; FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, - 0, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(&buffer), 0, 0); + nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(&buffer), 0, nullptr); StdStrBuf str(buffer); LocalFree(buffer); return std::string(str.getData(), str.getLength()); @@ -188,7 +188,7 @@ class GLTempContext public: GLTempContext() { - wnd = CreateWindowExW(0, L"STATIC", 0, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, 0, 0, GetModuleHandle(0), 0); + wnd = CreateWindowExW(0, L"STATIC", nullptr, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, nullptr, nullptr, GetModuleHandle(nullptr), nullptr); if (!wnd) throw WinAPIError(); dc = GetDC(wnd); @@ -201,7 +201,7 @@ public: int format = ChoosePixelFormat(dc, &pfd); if (!format || !SetPixelFormat(dc, format, &pfd) || - (glrc = wglCreateContext(dc)) == 0) + (glrc = wglCreateContext(dc)) == nullptr) { DWORD err = GetLastError(); ReleaseDC(wnd, dc); @@ -220,22 +220,22 @@ public: ~GLTempContext() { if (glrc == wglGetCurrentContext()) - wglMakeCurrent(dc, 0); + wglMakeCurrent(dc, nullptr); wglDeleteContext(glrc); ReleaseDC(wnd, dc); DestroyWindow(wnd); } }; -CStdGLCtx::CStdGLCtx(): pWindow(0), hDC(0), this_context(contexts.end()) { } +CStdGLCtx::CStdGLCtx(): pWindow(nullptr), hDC(nullptr), this_context(contexts.end()) { } void CStdGLCtx::Clear(bool multisample_change) { Deselect(); if (hDC && pWindow) ReleaseDC(pWindow->renderwnd, hDC); - hDC = 0; - pWindow = 0; + hDC = nullptr; + pWindow = nullptr; if (this_context != contexts.end()) { @@ -247,7 +247,7 @@ void CStdGLCtx::Clear(bool multisample_change) assert(!pGL->pCurrCtx); if (hrc) wglDeleteContext(hrc); - hrc = 0; + hrc = nullptr; } } @@ -257,12 +257,12 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *pApp) if (!pGL || !pWindow) return false; std::unique_ptr tempContext; - if (hrc == 0) + if (hrc == nullptr) { // Create a temporary context to be able to fetch GL extension pointers try { - tempContext.reset(new GLTempContext); + tempContext = std::make_unique(); glewExperimental = GL_TRUE; GLenum err = glewInit(); if(err != GLEW_OK) @@ -330,7 +330,7 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *pApp) 0 }; - hrc = wglCreateContextAttribsARB(hDC, 0, attribs); + hrc = wglCreateContextAttribsARB(hDC, nullptr, attribs); } if (!hrc) @@ -345,7 +345,7 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *pApp) 0 }; pGL->Workarounds.ForceSoftwareTransform = true; - hrc = wglCreateContextAttribsARB(hDC, 0, attribs); + hrc = wglCreateContextAttribsARB(hDC, nullptr, attribs); } } else @@ -390,12 +390,12 @@ std::vector CStdGLCtx::EnumerateMultiSamples() const { std::vector result; std::vector vec = EnumeratePixelFormats(hDC); - for(unsigned int i = 0; i < vec.size(); ++i) + for(int i : vec) { int attributes[] = { WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB }; const unsigned int n_attributes = 2; int results[2]; - if(!wglGetPixelFormatAttribivARB(hDC, vec[i], 0, n_attributes, attributes, results)) continue; + if(!wglGetPixelFormatAttribivARB(hDC, i, 0, n_attributes, attributes, results)) continue; if(results[0] == 1) result.push_back(results[1]); } diff --git a/src/graphics/C4DrawMeshGL.cpp b/src/graphics/C4DrawMeshGL.cpp index 5af080266..4bd45cdf3 100644 --- a/src/graphics/C4DrawMeshGL.cpp +++ b/src/graphics/C4DrawMeshGL.cpp @@ -26,7 +26,7 @@ #include "lib/StdMesh.h" #include "graphics/C4GraphicsResource.h" -#include +#include #include #ifndef USE_CONSOLE @@ -215,9 +215,8 @@ namespace // units that actually use a texture. unsigned int texIndex = 0; StdStrBuf textureUnitCode(""), textureUnitDeclCode(""); - for(unsigned int i = 0; i < pass.TextureUnits.size(); ++i) + for(const auto & texunit : pass.TextureUnits) { - const StdMeshMaterialTextureUnit& texunit = pass.TextureUnits[i]; textureUnitCode.Append(TextureUnitToCode(texIndex, texunit)); if(texunit.HasTexture()) @@ -294,16 +293,15 @@ bool CStdGL::PrepareMaterial(StdMeshMatManager& mat_manager, StdMeshMaterialLoad max_texture_units = std::min(max_texture_units, 16); unsigned int active_texture_units = 0; - for(unsigned int k = 0; k < pass.TextureUnits.size(); ++k) - if(pass.TextureUnits[k].HasTexture()) + for(auto & TextureUnit : pass.TextureUnits) + if(TextureUnit.HasTexture()) ++active_texture_units; if (active_texture_units > static_cast(max_texture_units)) technique.Available = false; - for (unsigned int k = 0; k < pass.TextureUnits.size(); ++k) + for (auto & texunit : pass.TextureUnits) { - StdMeshMaterialTextureUnit& texunit = pass.TextureUnits[k]; for (unsigned int l = 0; l < texunit.GetNumTextures(); ++l) { const C4TexRef& texture = texunit.GetTexture(l); @@ -566,9 +564,8 @@ namespace StdProjectionMatrix matrix = StdProjectionMatrix::Identity(); const double Position = instance.GetTexturePosition(passIndex, texUnitIndex); - for (unsigned int k = 0; k < texunit.Transformations.size(); ++k) + for (const auto & trans : texunit.Transformations) { - const StdMeshMaterialTextureUnit::Transformation& trans = texunit.Transformations[k]; StdProjectionMatrix temp_matrix; switch (trans.TransformType) { @@ -913,12 +910,12 @@ namespace // Set uniforms and instance parameters SetStandardUniforms(call, dwModClr, dwPlayerColor, dwBlitMode, pass.CullHardware != StdMeshMaterialPass::CH_None, pFoW, clipRect, outRect); - for(unsigned int j = 0; j < pass.Program->Parameters.size(); ++j) + for(auto & Parameter : pass.Program->Parameters) { - const int uniform = pass.Program->Parameters[j].UniformIndex; + const int uniform = Parameter.UniformIndex; if(!shader->HaveUniform(uniform)) continue; // optimized out - const StdMeshMaterialShaderParameter* parameter = pass.Program->Parameters[j].Parameter; + const StdMeshMaterialShaderParameter* parameter = Parameter.Parameter; StdMeshMaterialShaderParameter auto_resolved; if(parameter->GetType() == StdMeshMaterialShaderParameter::AUTO) diff --git a/src/graphics/C4FontLoader.cpp b/src/graphics/C4FontLoader.cpp index 4ac823ff8..2d52f5a1f 100644 --- a/src/graphics/C4FontLoader.cpp +++ b/src/graphics/C4FontLoader.cpp @@ -52,7 +52,7 @@ bool C4FontLoader::InitFont(CStdFont * rFont, const char *szFontName, FontType e assert(szFontName); if (!szFontName || !*szFontName) { - LogFatal(FormatString("%s (\"%s\")", LoadResStr("IDS_ERR_INITFONTS"), szFontName ? szFontName : "(null)").getData()); + LogFatal(FormatString(R"(%s ("%s"))", LoadResStr("IDS_ERR_INITFONTS"), szFontName ? szFontName : "(null)").getData()); return false; } // if def has not been found, use the def as font name diff --git a/src/graphics/C4GraphicsResource.cpp b/src/graphics/C4GraphicsResource.cpp index 72c109c8a..37bb3507f 100644 --- a/src/graphics/C4GraphicsResource.cpp +++ b/src/graphics/C4GraphicsResource.cpp @@ -337,8 +337,8 @@ bool C4GraphicsResource::RegisterGlobalGraphics() // then be kept. // The cleanest alternative would be to reinit all the fonts whenever a scenario is reloaded // FIXME: Test whether vector fonts from a scenario are correctly reloaded - C4Group *pMainGfxGrp = new C4Group(); - if (!Reloc.Open(*pMainGfxGrp, C4CFN_Graphics) || !Files.RegisterGroup(*pMainGfxGrp, true, C4GSPrio_Base, C4GSCnt_Graphics, 1)) + auto *pMainGfxGrp = new C4Group(); + if (!Reloc.Open(*pMainGfxGrp, C4CFN_Graphics) || !Files.RegisterGroup(*pMainGfxGrp, true, C4GSPrio_Base, C4GSCnt_Graphics, true)) { // error LogFatal(FormatString(LoadResStr("IDS_PRC_NOGFXFILE"),C4CFN_Graphics,pMainGfxGrp->GetError()).getData()); diff --git a/src/graphics/C4Shader.cpp b/src/graphics/C4Shader.cpp index c1c773b19..b02257b5d 100644 --- a/src/graphics/C4Shader.cpp +++ b/src/graphics/C4Shader.cpp @@ -145,7 +145,7 @@ void C4Shader::AddSlice(ShaderSliceList& slices, int iPos, const char *szText, c void C4Shader::AddSlices(ShaderSliceList& slices, const char *szWhat, const char *szText, const char *szSource, int iSourceTime) { if (std::find(SourceFiles.cbegin(), SourceFiles.cend(), szSource) == SourceFiles.cend()) - SourceFiles.push_back(szSource); + SourceFiles.emplace_back(szSource); const char *pStart = szText, *pPos = szText; int iDepth = -1; @@ -265,9 +265,9 @@ int C4Shader::ParsePosition(const char *szWhat, const char **ppPos) // Lookup name int iPosition = -1; - for (unsigned int i = 0; i < sizeof(C4SH_PosNames) / sizeof(*C4SH_PosNames); i++) { - if (SEqual(Name.getData(), C4SH_PosNames[i].Name)) { - iPosition = C4SH_PosNames[i].Position; + for (auto & PosName : C4SH_PosNames) { + if (SEqual(Name.getData(), PosName.Name)) { + iPosition = PosName.Position; break; } } @@ -540,8 +540,8 @@ bool C4Shader::Refresh() &UniformNames[0], &AttributeNames[0] #else - 0, - 0 + nullptr, + nullptr #endif )) return false; @@ -574,26 +574,26 @@ StdStrBuf C4Shader::Build(const ShaderSliceList &Slices, bool fDebug) // Add all slices at the current level if (fDebug && iPos > 0) Buf.AppendFormat("\t// Position %d:\n", iPos); - for (ShaderSliceList::const_iterator pSlice = Slices.begin(); pSlice != Slices.end(); pSlice++) + for (const auto & Slice : Slices) { - if (pSlice->Position < iPos) continue; - if (pSlice->Position > iPos) + if (Slice.Position < iPos) continue; + if (Slice.Position > iPos) { - iNextPos = std::min(iNextPos, pSlice->Position); + iNextPos = std::min(iNextPos, Slice.Position); continue; } // Same position - add slice! if (fDebug) { - if (pSlice->Source.getLength()) + if (Slice.Source.getLength()) { // GLSL below 3.30 consider the line after a #line N directive to be N + 1; 3.30 and higher consider it N - Buf.AppendFormat("\t// Slice from %s:\n#line %d %d\n", pSlice->Source.getData(), pSlice->SourceLine - (C4Shader_Version < 330), GetSourceFileId(pSlice->Source.getData()) + 1); + Buf.AppendFormat("\t// Slice from %s:\n#line %d %d\n", Slice.Source.getData(), Slice.SourceLine - (C4Shader_Version < 330), GetSourceFileId(Slice.Source.getData()) + 1); } else Buf.Append("\t// Built-in slice:\n#line 1 0\n"); } - Buf.Append(pSlice->Text); + Buf.Append(Slice.Text); if (Buf[Buf.getLength()-1] != '\n') Buf.AppendChar('\n'); } @@ -621,7 +621,7 @@ GLuint C4Shader::Create(GLenum iShaderType, const char *szWhat, const char *szSh pGL->ObjectLabel(GL_SHADER, hShader, -1, szWhat); // Compile - glShaderSource(hShader, 1, &szShader, 0); + glShaderSource(hShader, 1, &szShader, nullptr); glCompileShader(hShader); // Dump any information to log diff --git a/src/graphics/C4Surface.cpp b/src/graphics/C4Surface.cpp index 8111b1732..bd7bb482d 100644 --- a/src/graphics/C4Surface.cpp +++ b/src/graphics/C4Surface.cpp @@ -37,11 +37,11 @@ #include #endif -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include C4Surface::C4Surface() : fIsBackground(false) @@ -142,7 +142,7 @@ void C4Surface::Clear() if (pCtx) { delete pCtx; - pCtx = 0; + pCtx = nullptr; } #endif texture.reset(); @@ -485,7 +485,7 @@ bool C4Surface::Unlock() { // emulated primary locks in OpenGL delete[] PrimarySurfaceLockBits; - PrimarySurfaceLockBits = 0; + PrimarySurfaceLockBits = nullptr; return true; } else @@ -683,7 +683,7 @@ C4TexRef::~C4TexRef() #ifndef USE_CONSOLE if (pGL && pGL->pCurrCtx) glDeleteTextures(1, &texName); #endif - if (pDraw) delete [] static_cast(texLock.pBits); texLock.pBits = 0; + if (pDraw) delete [] static_cast(texLock.pBits); texLock.pBits = nullptr; // remove from texture manager pTexMgr->UnregTex(this); } diff --git a/src/graphics/C4SurfaceLoaders.cpp b/src/graphics/C4SurfaceLoaders.cpp index 0a8934b22..6cb60839f 100644 --- a/src/graphics/C4SurfaceLoaders.cpp +++ b/src/graphics/C4SurfaceLoaders.cpp @@ -235,7 +235,7 @@ extern "C" #undef FAR #include } -#include +#include // Straight from the libjpeg example struct my_error_mgr diff --git a/src/graphics/StdPNG.cpp b/src/graphics/StdPNG.cpp index ac4dbcdc3..480e7d526 100644 --- a/src/graphics/StdPNG.cpp +++ b/src/graphics/StdPNG.cpp @@ -309,13 +309,13 @@ private: static std::list threads; public: CPNGSaveThread(CPNGFile *png, const char *filename); - virtual ~CPNGSaveThread(); + ~CPNGSaveThread() override; static bool HasPendingThreads(); protected: - virtual void Execute(); - virtual bool IsSelfDestruct() { return true; } + void Execute() override; + bool IsSelfDestruct() override { return true; } }; CStdCSec CPNGSaveThread::threads_sec; diff --git a/src/gui/C4ChatDlg.cpp b/src/gui/C4ChatDlg.cpp index ee8f2273e..30d6321ae 100644 --- a/src/gui/C4ChatDlg.cpp +++ b/src/gui/C4ChatDlg.cpp @@ -76,8 +76,8 @@ void C4ChatControl::ChatSheet::NickItem::Update(class C4Network2IRCUser *pByUser int32_t C4ChatControl::ChatSheet::NickItem::SortFunc(const C4GUI::Element *pEl1, const C4GUI::Element *pEl2, void *) { - const NickItem *pNickItem1 = static_cast(pEl1); - const NickItem *pNickItem2 = static_cast(pEl2); + const auto *pNickItem1 = static_cast(pEl1); + const auto *pNickItem2 = static_cast(pEl2); int32_t s1 = pNickItem1->GetStatus(), s2 = pNickItem2->GetStatus(); if (s1 != s2) return s1 - s2; return stricmp(pNickItem2->GetNick(), pNickItem1->GetNick()); @@ -92,7 +92,7 @@ C4ChatControl::ChatSheet::ChatSheet(C4ChatControl *pChatControl, const char *szT if (szIdent) sIdent.Copy(szIdent); // create elements - positioned later C4Rect rcDefault(0,0,10,10); - pChatBox = new C4GUI::TextWindow(rcDefault,0,0,0,100,4096," ",false,0,0,true); + pChatBox = new C4GUI::TextWindow(rcDefault,0,0,0,100,4096," ",false,nullptr,0,true); pChatBox->SetDecoration(false, false, nullptr, false); AddElement(pChatBox); if (eType == CS_Channel) @@ -961,9 +961,7 @@ C4ChatDlg::C4ChatDlg() : C4GUI::Dialog(100, 100, "IRC", false) SetFocus(GetDefaultControl(), false); } -C4ChatDlg::~C4ChatDlg() -{ -} +C4ChatDlg::~C4ChatDlg() = default; C4ChatDlg *C4ChatDlg::ShowChat() { diff --git a/src/gui/C4FileSelDlg.cpp b/src/gui/C4FileSelDlg.cpp index 4e6e80826..f296b0569 100644 --- a/src/gui/C4FileSelDlg.cpp +++ b/src/gui/C4FileSelDlg.cpp @@ -47,9 +47,7 @@ C4FileSelDlg::ListItem::ListItem(const char *szFilename) : C4GUI::Control(C4Rect if (szFilename) sFilename.Copy(szFilename); else sFilename.Clear(); } -C4FileSelDlg::ListItem::~ListItem() -{ -} +C4FileSelDlg::ListItem::~ListItem() = default; // --------------------------------------------------- // C4FileSelDlg::DefaultListItem diff --git a/src/gui/C4Gui.cpp b/src/gui/C4Gui.cpp index b73af6577..9a1942dfc 100644 --- a/src/gui/C4Gui.cpp +++ b/src/gui/C4Gui.cpp @@ -459,9 +459,7 @@ namespace C4GUI // LDownX/Y initialized upon need } - CMouse::~CMouse() - { - } + CMouse::~CMouse() = default; void CMouse::Input(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) { diff --git a/src/gui/C4GuiButton.cpp b/src/gui/C4GuiButton.cpp index 0c4bbcefa..712782a57 100644 --- a/src/gui/C4GuiButton.cpp +++ b/src/gui/C4GuiButton.cpp @@ -36,8 +36,8 @@ namespace C4GUI { // key callbacks C4CustomKey::CodeList keys; - keys.push_back(C4KeyCodeEx(K_SPACE)); - keys.push_back(C4KeyCodeEx(K_RETURN)); + keys.emplace_back(K_SPACE); + keys.emplace_back(K_RETURN); if (Config.Controls.GamepadGuiControl) ControllerKeys::Ok(keys); pKeyButton = new C4KeyBinding(keys, "GUIButtonPress", KEYSCOPE_Gui, diff --git a/src/gui/C4GuiCheckBox.cpp b/src/gui/C4GuiCheckBox.cpp index 5dcbde23b..cc32877c7 100644 --- a/src/gui/C4GuiCheckBox.cpp +++ b/src/gui/C4GuiCheckBox.cpp @@ -43,7 +43,7 @@ namespace C4GUI } // key callbacks: Check/Uncheck on space and primary joy button C4CustomKey::CodeList Keys; - Keys.push_back(C4KeyCodeEx(K_SPACE)); + Keys.emplace_back(K_SPACE); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Ok(Keys); diff --git a/src/gui/C4GuiComboBox.cpp b/src/gui/C4GuiComboBox.cpp index e1256163a..c233b731d 100644 --- a/src/gui/C4GuiComboBox.cpp +++ b/src/gui/C4GuiComboBox.cpp @@ -71,10 +71,10 @@ namespace C4GUI *Text=0; // key callbacks - lots of possibilities to get the dropdown C4CustomKey::CodeList cbKeys; - cbKeys.push_back(C4KeyCodeEx(K_DOWN)); - cbKeys.push_back(C4KeyCodeEx(K_SPACE)); - cbKeys.push_back(C4KeyCodeEx(K_DOWN, KEYS_Alt)); - cbKeys.push_back(C4KeyCodeEx(K_SPACE, KEYS_Alt)); + cbKeys.emplace_back(K_DOWN); + cbKeys.emplace_back(K_SPACE); + cbKeys.emplace_back(K_DOWN, KEYS_Alt); + cbKeys.emplace_back(K_SPACE, KEYS_Alt); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Ok(cbKeys); @@ -83,7 +83,7 @@ namespace C4GUI pKeyOpenCombo = new C4KeyBinding(cbKeys, "GUIComboOpen", KEYSCOPE_Gui, new ControlKeyCB(*this, &ComboBox::KeyDropDown), C4CustomKey::PRIO_Ctrl); cbKeys.clear(); - cbKeys.push_back(C4KeyCodeEx(K_ESCAPE)); + cbKeys.emplace_back(K_ESCAPE); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Cancel(cbKeys); diff --git a/src/gui/C4GuiDialogs.cpp b/src/gui/C4GuiDialogs.cpp index 9f8037f38..3794061ea 100644 --- a/src/gui/C4GuiDialogs.cpp +++ b/src/gui/C4GuiDialogs.cpp @@ -285,7 +285,7 @@ namespace C4GUI SetBounds(C4Rect(0,0,iWdt,iHgt)); // create key callbacks C4CustomKey::CodeList Keys; - Keys.push_back(C4KeyCodeEx(K_TAB)); + Keys.emplace_back(K_TAB); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Right(Keys); @@ -293,7 +293,7 @@ namespace C4GUI pKeyAdvanceControl = new C4KeyBinding(Keys, "GUIAdvanceFocus", KEYSCOPE_Gui, new DlgKeyCBEx(*this, false, &Dialog::KeyAdvanceFocus), C4CustomKey::PRIO_Dlg); Keys.clear(); - Keys.push_back(C4KeyCodeEx(K_TAB, KEYS_Shift)); + Keys.emplace_back(K_TAB, KEYS_Shift); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Left(Keys); @@ -301,12 +301,12 @@ namespace C4GUI pKeyAdvanceControlB = new C4KeyBinding(Keys, "GUIAdvanceFocusBack", KEYSCOPE_Gui, new DlgKeyCBEx(*this, true, &Dialog::KeyAdvanceFocus), C4CustomKey::PRIO_Dlg); Keys.clear(); - Keys.push_back(C4KeyCodeEx(KEY_Any, KEYS_Alt)); - Keys.push_back(C4KeyCodeEx(KEY_Any, C4KeyShiftState(KEYS_Alt | KEYS_Shift))); + Keys.emplace_back(KEY_Any, KEYS_Alt); + Keys.emplace_back(KEY_Any, C4KeyShiftState(KEYS_Alt | KEYS_Shift)); pKeyHotkey = new C4KeyBinding(Keys, "GUIHotkey", KEYSCOPE_Gui, new DlgKeyCBPassKey

(*this, &Dialog::KeyHotkey), C4CustomKey::PRIO_Ctrl); Keys.clear(); - Keys.push_back(C4KeyCodeEx(K_RETURN)); + Keys.emplace_back(K_RETURN); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Ok(Keys); @@ -314,7 +314,7 @@ namespace C4GUI pKeyEnter = new C4KeyBinding(Keys, "GUIDialogOkay", KEYSCOPE_Gui, new DlgKeyCB(*this, &Dialog::KeyEnter), C4CustomKey::PRIO_Dlg); Keys.clear(); - Keys.push_back(C4KeyCodeEx(K_ESCAPE)); + Keys.emplace_back(K_ESCAPE); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Cancel(Keys); @@ -322,8 +322,8 @@ namespace C4GUI pKeyEscape = new C4KeyBinding(Keys, "GUIDialogAbort", KEYSCOPE_Gui, new DlgKeyCB(*this, &Dialog::KeyEscape), C4CustomKey::PRIO_Dlg); Keys.clear(); - Keys.push_back(C4KeyCodeEx(KEY_Any)); - Keys.push_back(C4KeyCodeEx(KEY_Any, KEYS_Shift)); + Keys.emplace_back(KEY_Any); + Keys.emplace_back(KEY_Any, KEYS_Shift); pKeyFocusDefControl = new C4KeyBinding(Keys, "GUIFocusDefault", KEYSCOPE_Gui, new DlgKeyCB(*this, &Dialog::KeyFocusDefault), C4CustomKey::PRIO_Dlg); } @@ -997,7 +997,7 @@ bool MessageDialog::KeyCopy() // ProgressDialog ProgressDialog::ProgressDialog(const char *szMessage, const char *szCaption, int32_t iMaxProgress, int32_t iInitialProgress, Icons icoIcon) - : Dialog(C4GUI_ProgressDlgWdt, std::max(::GraphicsResource.TextFont.BreakMessage(szMessage, C4GUI_ProgressDlgWdt-3*C4GUI_DefDlgIndent-C4GUI_IconWdt, 0, 0, true), C4GUI_IconHgt) + C4GUI_ProgressDlgVRoom, szCaption, false) + : Dialog(C4GUI_ProgressDlgWdt, std::max(::GraphicsResource.TextFont.BreakMessage(szMessage, C4GUI_ProgressDlgWdt-3*C4GUI_DefDlgIndent-C4GUI_IconWdt, nullptr, 0, true), C4GUI_IconHgt) + C4GUI_ProgressDlgVRoom, szCaption, false) { // get positions ComponentAligner caMain(GetClientRect(), C4GUI_DefDlgIndent, C4GUI_DefDlgIndent, true); @@ -1101,7 +1101,7 @@ bool MessageDialog::KeyCopy() InputDialog::InputDialog(const char *szMessage, const char *szCaption, Icons icoIcon, BaseInputCallback *pCB, bool fChatLayout) : Dialog(fChatLayout ? C4GUI::GetScreenWdt()*4/5 : C4GUI_InputDlgWdt, fChatLayout ? C4GUI::Edit::GetDefaultEditHeight() + 2 : - std::max(::GraphicsResource.TextFont.BreakMessage(szMessage, C4GUI_InputDlgWdt - 3 * C4GUI_DefDlgIndent - C4GUI_IconWdt, 0, 0, true), + std::max(::GraphicsResource.TextFont.BreakMessage(szMessage, C4GUI_InputDlgWdt - 3 * C4GUI_DefDlgIndent - C4GUI_IconWdt, nullptr, 0, true), C4GUI_IconHgt) + C4GUI_InputDlgVRoom, szCaption, false), pEdit(nullptr), pCB(pCB), fChatLayout(fChatLayout), pChatLbl(nullptr) { diff --git a/src/gui/C4GuiEdit.cpp b/src/gui/C4GuiEdit.cpp index 7f617150a..e278f9f66 100644 --- a/src/gui/C4GuiEdit.cpp +++ b/src/gui/C4GuiEdit.cpp @@ -103,10 +103,10 @@ namespace C4GUI { // register same op for all shift states; distinction will be done in handling proc C4CustomKey::CodeList KeyList; - KeyList.push_back(C4KeyCodeEx(key)); - KeyList.push_back(C4KeyCodeEx(key, KEYS_Shift)); - KeyList.push_back(C4KeyCodeEx(key, KEYS_Control)); - KeyList.push_back(C4KeyCodeEx(key, C4KeyShiftState(KEYS_Shift | KEYS_Control))); + KeyList.emplace_back(key); + KeyList.emplace_back(key, KEYS_Shift); + KeyList.emplace_back(key, KEYS_Control); + KeyList.emplace_back(key, C4KeyShiftState(KEYS_Shift | KEYS_Control)); return new C4KeyBinding(KeyList, szName, KEYSCOPE_Gui, new ControlKeyCBExPassKey(*this, op, &Edit::KeyCursorOp), eKeyPrio); } @@ -707,7 +707,7 @@ namespace C4GUI else pPrevFocusCtrl=nullptr; // key binding for rename abort C4CustomKey::CodeList keys; - keys.push_back(C4KeyCodeEx(K_ESCAPE)); + keys.emplace_back(K_ESCAPE); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Cancel(keys); diff --git a/src/gui/C4GuiLabels.cpp b/src/gui/C4GuiLabels.cpp index 338b9b197..c036fe1fe 100644 --- a/src/gui/C4GuiLabels.cpp +++ b/src/gui/C4GuiLabels.cpp @@ -467,9 +467,7 @@ namespace C4GUI fctPaint.Create(iSfcWdt, iSfcHgt); } - PaintBox::~PaintBox() - { - } + PaintBox::~PaintBox() = default; // -------------------------------------------------- diff --git a/src/gui/C4GuiListBox.cpp b/src/gui/C4GuiListBox.cpp index 5e5acd6b8..c8fb3966f 100644 --- a/src/gui/C4GuiListBox.cpp +++ b/src/gui/C4GuiListBox.cpp @@ -43,22 +43,22 @@ namespace C4GUI pKeyContext = new C4KeyBinding(C4KeyCodeEx(K_MENU), "GUIListBoxContext", KEYSCOPE_Gui, new ControlKeyCB(*this, &ListBox::KeyContext), C4CustomKey::PRIO_Ctrl); C4CustomKey::CodeList keys; - keys.push_back(C4KeyCodeEx(K_UP)); + keys.emplace_back(K_UP); if (Config.Controls.GamepadGuiControl) ControllerKeys::Up(keys); pKeyUp = new C4KeyBinding(keys, "GUIListBoxUp", KEYSCOPE_Gui, new ControlKeyCB(*this, &ListBox::KeyUp), C4CustomKey::PRIO_Ctrl); keys.clear(); - keys.push_back(C4KeyCodeEx(K_DOWN)); + keys.emplace_back(K_DOWN); if (Config.Controls.GamepadGuiControl) ControllerKeys::Down(keys); pKeyDown = new C4KeyBinding(keys, "GUIListBoxDown", KEYSCOPE_Gui, new ControlKeyCB(*this, &ListBox::KeyDown), C4CustomKey::PRIO_Ctrl); keys.clear(); - keys.push_back(C4KeyCodeEx(K_LEFT)); + keys.emplace_back(K_LEFT); if (Config.Controls.GamepadGuiControl) ControllerKeys::Left(keys); pKeyLeft = new C4KeyBinding(keys, "GUIListBoxLeft", KEYSCOPE_Gui, new ControlKeyCB(*this, &ListBox::KeyLeft), C4CustomKey::PRIO_Ctrl); keys.clear(); - keys.push_back(C4KeyCodeEx(K_RIGHT)); + keys.emplace_back(K_RIGHT); if (Config.Controls.GamepadGuiControl) ControllerKeys::Right(keys); pKeyRight = new C4KeyBinding(keys, "GUIListBoxRight", KEYSCOPE_Gui, new ControlKeyCB(*this, &ListBox::KeyRight), C4CustomKey::PRIO_Ctrl); @@ -72,8 +72,8 @@ namespace C4GUI new ControlKeyCB(*this, &ListBox::KeyEnd), C4CustomKey::PRIO_Ctrl); // "activate" current item keys.clear(); - keys.push_back(C4KeyCodeEx(K_RETURN)); - keys.push_back(C4KeyCodeEx(K_RETURN, KEYS_Alt)); + keys.emplace_back(K_RETURN); + keys.emplace_back(K_RETURN, KEYS_Alt); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Ok(keys); diff --git a/src/gui/C4GuiMenu.cpp b/src/gui/C4GuiMenu.cpp index b8387b097..ecbd4b74e 100644 --- a/src/gui/C4GuiMenu.cpp +++ b/src/gui/C4GuiMenu.cpp @@ -92,7 +92,7 @@ namespace C4GUI rcBounds.Wdt=40; rcBounds.Hgt=7; // key bindings C4CustomKey::CodeList Keys; - Keys.push_back(C4KeyCodeEx(K_UP)); + Keys.emplace_back(K_UP); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Up(Keys); @@ -101,7 +101,7 @@ namespace C4GUI new C4KeyCB(*this, &ContextMenu::KeySelUp), C4CustomKey::PRIO_Context); Keys.clear(); - Keys.push_back(C4KeyCodeEx(K_DOWN)); + Keys.emplace_back(K_DOWN); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Down(Keys); @@ -110,7 +110,7 @@ namespace C4GUI new C4KeyCB(*this, &ContextMenu::KeySelDown), C4CustomKey::PRIO_Context); Keys.clear(); - Keys.push_back(C4KeyCodeEx(K_RIGHT)); + Keys.emplace_back(K_RIGHT); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Right(Keys); @@ -119,7 +119,7 @@ namespace C4GUI new C4KeyCB(*this, &ContextMenu::KeySubmenu), C4CustomKey::PRIO_Context); Keys.clear(); - Keys.push_back(C4KeyCodeEx(K_LEFT)); + Keys.emplace_back(K_LEFT); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Left(Keys); @@ -128,7 +128,7 @@ namespace C4GUI new C4KeyCB(*this, &ContextMenu::KeyBack), C4CustomKey::PRIO_Context); Keys.clear(); - Keys.push_back(C4KeyCodeEx(K_ESCAPE)); + Keys.emplace_back(K_ESCAPE); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Cancel(Keys); @@ -137,7 +137,7 @@ namespace C4GUI new C4KeyCB(*this, &ContextMenu::KeyAbort), C4CustomKey::PRIO_Context); Keys.clear(); - Keys.push_back(C4KeyCodeEx(K_RETURN)); + Keys.emplace_back(K_RETURN); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Ok(Keys); @@ -589,12 +589,12 @@ namespace C4GUI { // reg keys for pressing the context button C4CustomKey::CodeList ContextKeys; - ContextKeys.push_back(C4KeyCodeEx(K_RIGHT)); - ContextKeys.push_back(C4KeyCodeEx(K_DOWN)); - ContextKeys.push_back(C4KeyCodeEx(K_SPACE)); - ContextKeys.push_back(C4KeyCodeEx(K_RIGHT, KEYS_Alt)); - ContextKeys.push_back(C4KeyCodeEx(K_DOWN, KEYS_Alt)); - ContextKeys.push_back(C4KeyCodeEx(K_SPACE, KEYS_Alt)); + ContextKeys.emplace_back(K_RIGHT); + ContextKeys.emplace_back(K_DOWN); + ContextKeys.emplace_back(K_SPACE); + ContextKeys.emplace_back(K_RIGHT, KEYS_Alt); + ContextKeys.emplace_back(K_DOWN, KEYS_Alt); + ContextKeys.emplace_back(K_SPACE, KEYS_Alt); pKeyContext = new C4KeyBinding(ContextKeys, "GUIContextButtonPress", KEYSCOPE_Gui, new ControlKeyCB(*this, &ContextButton::KeyContext), C4CustomKey::PRIO_Ctrl); } diff --git a/src/gui/C4GuiTabular.cpp b/src/gui/C4GuiTabular.cpp index ebdcff516..7478f8b6f 100644 --- a/src/gui/C4GuiTabular.cpp +++ b/src/gui/C4GuiTabular.cpp @@ -179,7 +179,7 @@ namespace C4GUI // Ctrl+(Shift-)Tab works with dialog focus only (assumes max one tabular per dialog) // Arrow keys work if control is focused only C4CustomKey::CodeList Keys; - Keys.push_back(C4KeyCodeEx(K_UP)); + Keys.emplace_back(K_UP); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Up(Keys); @@ -188,7 +188,7 @@ namespace C4GUI new ControlKeyCB(*this, &Tabular::KeySelUp), C4CustomKey::PRIO_Ctrl); Keys.clear(); - Keys.push_back(C4KeyCodeEx(K_DOWN)); + Keys.emplace_back(K_DOWN); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Down(Keys); diff --git a/src/gui/C4KeyboardInput.cpp b/src/gui/C4KeyboardInput.cpp index 3d0c58436..31e865da6 100644 --- a/src/gui/C4KeyboardInput.cpp +++ b/src/gui/C4KeyboardInput.cpp @@ -124,7 +124,7 @@ const C4KeyCodeMapEntry KeyCodeMap[] = { {K_APOSTROPHE, "Apostrophe", "'"}, {K_GRAVE_ACCENT, "GraveAccent", "`"}, {K_SHIFT_L, "LeftShift", "LShift"}, - {K_BACKSLASH, "Backslash", "\\"}, + {K_BACKSLASH, "Backslash", R"(\)"}, {K_Z, "Z", nullptr}, {K_X, "X", nullptr}, {K_C, "C", nullptr}, @@ -247,7 +247,7 @@ C4KeyCode C4KeyCodeEx::String2KeyCode(const StdStrBuf &sName) if (sName.getLength() > 2) { unsigned int dwRVal; - if (sscanf(sName.getData(), "\\x%x", &dwRVal) == 1) return dwRVal; + if (sscanf(sName.getData(), R"(\x%x)", &dwRVal) == 1) return dwRVal; // scan code if (*sName.getData() == '$') return GetKeyByScanCode(sName.getData()); // direct gamepad code @@ -583,8 +583,8 @@ C4CustomKey::C4CustomKey(const C4KeyCodeEx &DefCode, const char *szName, C4KeySc } } -C4CustomKey::C4CustomKey(const CodeList &rDefCodes, const char *szName, C4KeyScope Scope, C4KeyboardCallbackInterface *pCallback, unsigned int uiPriority) - : DefaultCodes(rDefCodes), Scope(Scope), Name(), uiPriority(uiPriority), iRef(0), is_down(false) +C4CustomKey::C4CustomKey(CodeList rDefCodes, const char *szName, C4KeyScope Scope, C4KeyboardCallbackInterface *pCallback, unsigned int uiPriority) + : DefaultCodes(std::move(rDefCodes)), Scope(Scope), Name(), uiPriority(uiPriority), iRef(0), is_down(false) { // ctor for default key Name.Copy(szName); @@ -602,10 +602,10 @@ C4CustomKey::C4CustomKey(const C4CustomKey &rCpy, bool fCopyCallbacks) Name.Copy(rCpy.GetName()); if (fCopyCallbacks) { - for (CBVec::const_iterator i = rCpy.vecCallbacks.begin(); i != rCpy.vecCallbacks.end(); ++i) + for (auto callback : rCpy.vecCallbacks) { - (*i)->Ref(); - vecCallbacks.push_back(*i); + callback->Ref(); + vecCallbacks.push_back(callback); } } } @@ -635,10 +635,10 @@ void C4CustomKey::Update(const C4CustomKey *pByKey) if (pByKey->Codes.size()) Codes = pByKey->Codes; if (pByKey->Scope != KEYSCOPE_None) Scope = pByKey->Scope; if (pByKey->uiPriority != PRIO_None) uiPriority = pByKey->uiPriority; - for (CBVec::const_iterator i = pByKey->vecCallbacks.begin(); i != pByKey->vecCallbacks.end(); ++i) + for (auto callback : pByKey->vecCallbacks) { - (*i)->Ref(); - vecCallbacks.push_back(*i); + callback->Ref(); + vecCallbacks.push_back(callback); } } @@ -669,8 +669,8 @@ bool C4CustomKey::Execute(C4KeyEventType eEv, C4KeyCodeEx key) // remember down-state is_down = (eEv == KEYEV_Down); // execute all callbacks - for (CBVec::iterator i = vecCallbacks.begin(); i != vecCallbacks.end(); ++i) - if ((*i)->OnKeyEvent(key, eEv)) + for (auto & callback : vecCallbacks) + if (callback->OnKeyEvent(key, eEv)) return true; // no event processed it return false; diff --git a/src/gui/C4KeyboardInput.h b/src/gui/C4KeyboardInput.h index 0b2dedb8f..b46324400 100644 --- a/src/gui/C4KeyboardInput.h +++ b/src/gui/C4KeyboardInput.h @@ -451,7 +451,7 @@ public: protected: int iRef; C4CustomKey(const C4KeyCodeEx &DefCode, const char *szName, C4KeyScope Scope, C4KeyboardCallbackInterface *pCallback, unsigned int uiPriority = PRIO_Base); // ctor for default key - C4CustomKey(const CodeList &rDefCodes, const char *szName, C4KeyScope Scope, C4KeyboardCallbackInterface *pCallback, unsigned int uiPriority = PRIO_Base); // ctor for default key with multiple possible keys assigned + C4CustomKey(CodeList rDefCodes, const char *szName, C4KeyScope Scope, C4KeyboardCallbackInterface *pCallback, unsigned int uiPriority = PRIO_Base); // ctor for default key with multiple possible keys assigned friend class C4Game; public: diff --git a/src/gui/C4MessageBoard.cpp b/src/gui/C4MessageBoard.cpp index 71f7aac1e..030e40d1e 100644 --- a/src/gui/C4MessageBoard.cpp +++ b/src/gui/C4MessageBoard.cpp @@ -124,8 +124,8 @@ void C4MessageBoard::Init(C4Facet &cgo, bool fStartup) } // messageboard - ScrollUpBinding.reset(new C4KeyBinding(C4KeyCodeEx(K_UP, KEYS_Shift), "MsgBoardScrollUp", KEYSCOPE_Fullscreen, new C4KeyCB (*GraphicsSystem.MessageBoard, &C4MessageBoard::ControlScrollUp))); - ScrollDownBinding.reset(new C4KeyBinding(C4KeyCodeEx(K_DOWN, KEYS_Shift), "MsgBoardScrollDown", KEYSCOPE_Fullscreen, new C4KeyCB (*GraphicsSystem.MessageBoard, &C4MessageBoard::ControlScrollDown))); + ScrollUpBinding = std::make_unique(C4KeyCodeEx(K_UP, KEYS_Shift), "MsgBoardScrollUp", KEYSCOPE_Fullscreen, new C4KeyCB (*GraphicsSystem.MessageBoard, &C4MessageBoard::ControlScrollUp)); + ScrollDownBinding = std::make_unique(C4KeyCodeEx(K_DOWN, KEYS_Shift), "MsgBoardScrollDown", KEYSCOPE_Fullscreen, new C4KeyCB (*GraphicsSystem.MessageBoard, &C4MessageBoard::ControlScrollDown)); } void C4MessageBoard::Draw(C4Facet &cgo) diff --git a/src/gui/C4MessageInput.cpp b/src/gui/C4MessageInput.cpp index 84e5263b9..d39018622 100644 --- a/src/gui/C4MessageInput.cpp +++ b/src/gui/C4MessageInput.cpp @@ -116,8 +116,8 @@ C4GUI::Edit::InputResult C4ChatInputDialog::OnChatInput(C4GUI::Edit *edt, bool f // no double processing if (fProcessed) return C4GUI::Edit::IR_CloseDlg; // get edit text - C4GUI::Edit *pEdt = reinterpret_cast(edt); - char *szInputText = const_cast(pEdt->GetText()); + auto *pEdt = reinterpret_cast(edt); + auto *szInputText = const_cast(pEdt->GetText()); // Store to back buffer ::MessageInput.StoreBackBuffer(szInputText); // script queried input? @@ -249,7 +249,7 @@ bool C4MessageInput::Init() void C4MessageInput::Default() { // clear backlog - for (int32_t cnt=0; cnt(std::extent::value); ++i) + for (auto & i : todo_filenames) { - StdCopyStrBuf todo_filename(todo_filenames[i]); + StdCopyStrBuf todo_filename(i); todo_filename.Replace("{USERPATH}", Config.General.UserDataPath); int replacements = todo_filename.Replace("{SCENARIO}", Game.ScenarioFile.GetFullName().getData()); // sanity checks for writing scenario TODO file diff --git a/src/gui/C4MouseControl.cpp b/src/gui/C4MouseControl.cpp index 03f407bdf..bbb4546c4 100644 --- a/src/gui/C4MouseControl.cpp +++ b/src/gui/C4MouseControl.cpp @@ -432,7 +432,7 @@ void C4MouseControl::Draw(C4TargetFacet &cgo, const ZoomData &GameZoom) { uint32_t ColorMod = DragImageObject->ColorMod; uint32_t BlitMode = DragImageObject->BlitMode; - DragImageObject->ColorMod = (Drag == C4MC_Drag_Script) ? 0x7fffffff : (/*DragImagePhase*/0 ? 0x8f7f0000 : 0x1f007f00); + DragImageObject->ColorMod = (Drag == C4MC_Drag_Script) ? 0x7fffffff : (/*DragImagePhase*/false ? 0x8f7f0000 : 0x1f007f00); DragImageObject->BlitMode = C4GFXBLIT_MOD2; DragImageObject->DrawPicture(ccgo, false, nullptr); @@ -445,7 +445,7 @@ void C4MouseControl::Draw(C4TargetFacet &cgo, const ZoomData &GameZoom) // draw in special modulation mode pDraw->SetBlitMode(C4GFXBLIT_MOD2); // draw DragImage in red or green, according to the phase to be used - pDraw->ActivateBlitModulation((Drag == C4MC_Drag_Script) ? 0x7fffffff : (/*DragImagePhase*/0 ? 0x8f7f0000 : 0x1f007f00)); + pDraw->ActivateBlitModulation((Drag == C4MC_Drag_Script) ? 0x7fffffff : (/*DragImagePhase*/false ? 0x8f7f0000 : 0x1f007f00)); DragImageDef->Draw(ccgo, false, pPlayer ? pPlayer->ColorDw : 0xff0000ff, nullptr, 0, 0, nullptr); diff --git a/src/gui/C4Scoreboard.cpp b/src/gui/C4Scoreboard.cpp index a50df5f02..b06adccd0 100644 --- a/src/gui/C4Scoreboard.cpp +++ b/src/gui/C4Scoreboard.cpp @@ -34,19 +34,19 @@ private: public: C4ScoreboardDlg(C4Scoreboard *pForScoreboard); - ~C4ScoreboardDlg(); + ~C4ScoreboardDlg() override; protected: void InvalidateRows() { delete [] piColWidths; piColWidths = nullptr; } void Update(); // update row widths and own size and caption - virtual bool DoPlacement(C4GUI::Screen *pOnScreen, const C4Rect &rPreferredDlgRect); - virtual void Draw(C4TargetFacet &cgo); - virtual void DrawElement(C4TargetFacet &cgo); + bool DoPlacement(C4GUI::Screen *pOnScreen, const C4Rect &rPreferredDlgRect) override; + void Draw(C4TargetFacet &cgo) override; + void DrawElement(C4TargetFacet &cgo) override; - virtual const char *GetID() { return "Scoreboard"; } + const char *GetID() override { return "Scoreboard"; } - virtual bool IsMouseControlled() { return false; } + bool IsMouseControlled() override { return false; } friend class C4Scoreboard; }; diff --git a/src/gui/C4ScriptGuiWindow.cpp b/src/gui/C4ScriptGuiWindow.cpp index 86b87d982..4e485c318 100644 --- a/src/gui/C4ScriptGuiWindow.cpp +++ b/src/gui/C4ScriptGuiWindow.cpp @@ -129,13 +129,13 @@ const C4Value C4ScriptGuiWindowAction::ToC4Value(bool first) void C4ScriptGuiWindowAction::ClearPointers(C4Object *pObj) { - C4Object *targetObj = target ? target->GetObject() : 0; + C4Object *targetObj = target ? target->GetObject() : nullptr; if (targetObj == pObj) { // not only forget object, but completely invalidate action action = 0; - target = 0; + target = nullptr; } if (nextAction) nextAction->ClearPointers(pObj); @@ -309,7 +309,7 @@ void C4ScriptGuiWindowProperty::SetNull(C4String *tag) if (!tag) tag = &Strings.P[P_Std]; taggedProperties[tag] = Prop(); current = &taggedProperties[tag]; - current->data = 0; + current->data = nullptr; } void C4ScriptGuiWindowProperty::CleanUp(Prop &prop) @@ -337,11 +337,11 @@ void C4ScriptGuiWindowProperty::CleanUp(Prop &prop) void C4ScriptGuiWindowProperty::CleanUpAll() { - for (std::map::iterator iter = taggedProperties.begin(); iter != taggedProperties.end(); ++iter) + for (auto & taggedProperty : taggedProperties) { - CleanUp(iter->second); - if (iter->first != &Strings.P[P_Std]) - iter->first->DecRef(); + CleanUp(taggedProperty.second); + if (taggedProperty.first != &Strings.P[P_Std]) + taggedProperty.first->DecRef(); } } @@ -355,10 +355,10 @@ const C4Value C4ScriptGuiWindowProperty::ToC4Value() // go through all of the tagged properties and add a property to the proplist containing both the tag name // and the serialzed C4Value of the properties' value - for(std::map::iterator iter = taggedProperties.begin(); iter != taggedProperties.end(); ++iter) + for(auto & taggedProperty : taggedProperties) { - C4String *tagString = iter->first; - const Prop &prop = iter->second; + C4String *tagString = taggedProperty.first; + const Prop &prop = taggedProperty.second; C4Value val; @@ -517,7 +517,7 @@ void C4ScriptGuiWindowProperty::Set(const C4Value &value, C4String *tag) C4PropList *symbol = value.getPropList(); if (symbol) current->obj = symbol->GetObject(); - else current->obj = 0; + else current->obj = nullptr; break; } case C4ScriptGuiWindowPropertyName::symbolDef: @@ -525,7 +525,7 @@ void C4ScriptGuiWindowProperty::Set(const C4Value &value, C4String *tag) C4PropList *symbol = value.getPropList(); if (symbol) current->def = symbol->GetDef(); - else current->def = 0; + else current->def = nullptr; break; } case C4ScriptGuiWindowPropertyName::frameDecoration: @@ -538,7 +538,7 @@ void C4ScriptGuiWindowProperty::Set(const C4Value &value, C4String *tag) if (!current->deco->SetByDef(def)) { delete current->deco; - current->deco = 0; + current->deco = nullptr; } } break; @@ -580,21 +580,21 @@ void C4ScriptGuiWindowProperty::ClearPointers(C4Object *pObj) { // assume that we actually contain an object // go through all the tags and, in case the tag has anything to do with objects, check and clear it - for (std::map::iterator iter = taggedProperties.begin(); iter != taggedProperties.end(); ++iter) + for (auto & taggedProperty : taggedProperties) { switch (type) { case C4ScriptGuiWindowPropertyName::symbolObject: - if (iter->second.obj == pObj) - iter->second.obj = 0; + if (taggedProperty.second.obj == pObj) + taggedProperty.second.obj = nullptr; break; case C4ScriptGuiWindowPropertyName::onClickAction: case C4ScriptGuiWindowPropertyName::onMouseInAction: case C4ScriptGuiWindowPropertyName::onMouseOutAction: case C4ScriptGuiWindowPropertyName::onCloseAction: - if (iter->second.action) - iter->second.action->ClearPointers(pObj); + if (taggedProperty.second.action) + taggedProperty.second.action->ClearPointers(pObj); break; default: return; @@ -614,9 +614,9 @@ bool C4ScriptGuiWindowProperty::SwitchTag(C4String *tag) std::list C4ScriptGuiWindowProperty::GetAllActions() { std::list allActions; - for (std::map::iterator iter = taggedProperties.begin(); iter != taggedProperties.end(); ++iter) + for (auto & taggedProperty : taggedProperties) { - Prop &p = iter->second; + Prop &p = taggedProperty.second; if (p.action) allActions.push_back(p.action); } @@ -681,7 +681,7 @@ void C4ScriptGuiWindow::Init() wasRemoved = false; closeActionWasExecuted = false; currentMouseState = MouseState::None; - target = 0; + target = nullptr; pScrollBar->fAutoHide = true; rcBounds.x = rcBounds.y = 0; @@ -693,8 +693,8 @@ C4ScriptGuiWindow::~C4ScriptGuiWindow() ClearChildren(false); // delete certain properties that contain allocated elements or referenced strings - for (int32_t i = 0; i < C4ScriptGuiWindowPropertyName::_lastProp; ++i) - props[i].CleanUpAll(); + for (auto & prop : props) + prop.CleanUpAll(); if (pScrollBar) delete pScrollBar; @@ -828,7 +828,7 @@ void C4ScriptGuiWindow::SetPositionStringProperties(const C4Value &property, C4S } else // error, abort! (readere is not in a clean state anyway) { - LogF("Warning: Could not parse menu format string \"%s\"!", property.getStr()->GetCStr()); + LogF(R"(Warning: Could not parse menu format string "%s"!)", property.getStr()->GetCStr()); return; } @@ -848,11 +848,11 @@ C4Value C4ScriptGuiWindow::PositionToC4Value(C4ScriptGuiWindowPropertyName relat C4PropList *proplist = nullptr; const bool onlyStdTag = relative.taggedProperties.size() == 1; - for (std::map::iterator iter = relative.taggedProperties.begin(); iter != relative.taggedProperties.end(); ++iter) + for (auto & taggedProperty : relative.taggedProperties) { - C4String *tag = iter->first; + C4String *tag = taggedProperty.first; StdStrBuf buf; - buf.Format("%f%%%+fem", 100.0f * iter->second.f, absolute.taggedProperties[tag].f); + buf.Format("%f%%%+fem", 100.0f * taggedProperty.second.f, absolute.taggedProperties[tag].f); C4String *propString = Strings.RegString(buf); if (onlyStdTag) @@ -918,9 +918,8 @@ const C4Value C4ScriptGuiWindow::ToC4Value() const int32_t entryCount = sizeof(toSave) / sizeof(int32_t); - for (size_t i = 0; i < entryCount; ++i) + for (int prop : toSave) { - int32_t prop = toSave[i]; C4Value val; switch (prop) @@ -1289,7 +1288,7 @@ C4ScriptGuiWindow *C4ScriptGuiWindow::GetSubWindow(int32_t childID, C4Object *ch if (subwindow->GetTarget() != childTarget) continue; return subwindow; } - return 0; + return nullptr; } void C4ScriptGuiWindow::RemoveChild(C4ScriptGuiWindow *child, bool close, bool all) @@ -1327,7 +1326,7 @@ void C4ScriptGuiWindow::RemoveChild(C4ScriptGuiWindow *child, bool close, bool a void C4ScriptGuiWindow::ClearChildren(bool close) { - RemoveChild(0, close, true); + RemoveChild(nullptr, close, true); } void C4ScriptGuiWindow::Close() @@ -1422,8 +1421,8 @@ void C4ScriptGuiWindow::UpdateLayoutGrid() }; // do all the rounding after the calculations - const int32_t childWdt = (int32_t)(childWdtF + 0.5f); - const int32_t childHgt = (int32_t)(childHgtF + 0.5f); + const auto childWdt = (int32_t)(childWdtF + 0.5f); + const auto childHgt = (int32_t)(childHgtF + 0.5f); // Check if the child even fits in the remainder of the row const bool fitsInRow = (width - currentX) >= childWdt; @@ -1469,8 +1468,8 @@ void C4ScriptGuiWindow::UpdateLayoutTightGrid() const float childHgtF = float(child->rcBounds.Hgt) + childTopMargin + childBottomMargin; // do all the rounding after the calculations - const int32_t childWdt = (int32_t)(childWdtF + 0.5f); - const int32_t childHgt = (int32_t)(childHgtF + 0.5f); + const auto childWdt = (int32_t)(childWdtF + 0.5f); + const auto childHgt = (int32_t)(childHgtF + 0.5f); // Look for a free spot. int32_t currentX = borderX; @@ -1606,9 +1605,8 @@ bool C4ScriptGuiWindow::DrawChildren(C4TargetFacet &cgo, int32_t player, int32_t // note that withMultipleFlag only plays a roll for the root-menu bool oneDrawn = false; // was at least one child drawn? //for (auto iter = rbegin(); iter != rend(); ++iter) - for (auto iter = begin(); iter != end(); ++iter) + for (auto element : *this) { - C4GUI::Element *element = *iter; C4ScriptGuiWindow *child = static_cast(element); if (withMultipleFlag != -1) @@ -2310,9 +2308,8 @@ bool C4ScriptGuiWindow::ExecuteCommand(int32_t actionID, int32_t player, int32_t MenuDebugLogF("children:\t%d", GetElementCount()); MenuDebugLogF("all actions:\t%d", props[actionType].GetAllActions().size()); std::list allActions = props[actionType].GetAllActions(); - for (std::list::iterator iter = allActions.begin(); iter != allActions.end(); ++iter) + for (auto action : allActions) { - C4ScriptGuiWindowAction *action = *iter; assert(action && "C4ScriptGuiWindowProperty::GetAllActions returned list with null-pointer"); if (action->ExecuteCommand(actionID, this, player)) diff --git a/src/gui/C4StartupAboutDlg.cpp b/src/gui/C4StartupAboutDlg.cpp index 266ceabf6..06c86eac2 100644 --- a/src/gui/C4StartupAboutDlg.cpp +++ b/src/gui/C4StartupAboutDlg.cpp @@ -49,9 +49,7 @@ C4StartupAboutDlg::C4StartupAboutDlg() : C4StartupDlg(LoadResStr("IDS_DLG_ABOUT" caButtons.GetFromBottom(rUseFont.GetLineHeight()))); } -C4StartupAboutDlg::~C4StartupAboutDlg() -{ -} +C4StartupAboutDlg::~C4StartupAboutDlg() = default; void C4StartupAboutDlg::DoBack() { diff --git a/src/gui/C4StartupMainDlg.cpp b/src/gui/C4StartupMainDlg.cpp index cf7338635..c6a48ef60 100644 --- a/src/gui/C4StartupMainDlg.cpp +++ b/src/gui/C4StartupMainDlg.cpp @@ -86,21 +86,21 @@ C4StartupMainDlg::C4StartupMainDlg() : C4StartupDlg(nullptr) // create w/o title pParticipantsLbl->SetContextHandler(new C4GUI::CBContextHandler(this, &C4StartupMainDlg::OnPlayerSelContext)); // key bindings C4CustomKey::CodeList keys; - keys.push_back(C4KeyCodeEx(K_DOWN)); keys.push_back(C4KeyCodeEx(K_RIGHT)); + keys.emplace_back(K_DOWN); keys.emplace_back(K_RIGHT); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Down(keys); // right will be done by Dialog already } pKeyDown = new C4KeyBinding(keys, "StartupMainCtrlNext", KEYSCOPE_Gui, new C4GUI::DlgKeyCBEx(*this, false, &C4StartupMainDlg::KeyAdvanceFocus), C4CustomKey::PRIO_CtrlOverride); - keys.clear(); keys.push_back(C4KeyCodeEx(K_UP)); keys.push_back(C4KeyCodeEx(K_LEFT)); + keys.clear(); keys.emplace_back(K_UP); keys.emplace_back(K_LEFT); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Up(keys); // left will be done by Dialog already } pKeyUp = new C4KeyBinding(keys, "StartupMainCtrlPrev", KEYSCOPE_Gui, new C4GUI::DlgKeyCBEx(*this, true, &C4StartupMainDlg::KeyAdvanceFocus), C4CustomKey::PRIO_CtrlOverride); - keys.clear(); keys.push_back(C4KeyCodeEx(K_RETURN)); + keys.clear(); keys.emplace_back(K_RETURN); pKeyEnter = new C4KeyBinding(keys, "StartupMainOK", KEYSCOPE_Gui, new C4GUI::DlgKeyCB(*this, &C4StartupMainDlg::KeyEnterDown, &C4StartupMainDlg::KeyEnterUp), C4CustomKey::PRIO_CtrlOverride); } diff --git a/src/gui/C4StartupNetDlg.cpp b/src/gui/C4StartupNetDlg.cpp index 843d41760..59045cedb 100644 --- a/src/gui/C4StartupNetDlg.cpp +++ b/src/gui/C4StartupNetDlg.cpp @@ -49,9 +49,9 @@ C4StartupNetListEntry::C4StartupNetListEntry(C4GUI::ListBox *pForListBox, C4GUI: int32_t iThisWdt = rcIconRect.Wdt; rcIconRect.x = iThisWdt - iIconSize * (iInfoIconCount + 1); rcIconRect.Wdt = rcIconRect.Hgt = iIconSize; - for (int32_t iIcon = 0; iIcon(*this, &C4StartupNetDlg::KeyBack), C4CustomKey::PRIO_Dlg); pKeyRefresh = new C4KeyBinding(C4KeyCodeEx(K_F5), "StartupNetReload", KEYSCOPE_Gui, @@ -771,7 +771,7 @@ void C4StartupNetDlg::OnShown() UpdateUpdateButton(); // in case update check was finished before callback registration UpdateMasterserver(); OnSec1Timer(); - tLastRefresh = time(0); + tLastRefresh = time(nullptr); // also update chat if (pChatCtrl) pChatCtrl->OnShown(); } @@ -1172,7 +1172,7 @@ bool C4StartupNetDlg::DoBack() void C4StartupNetDlg::DoRefresh() { // check min refresh timer - time_t tNow = time(0); + time_t tNow = time(nullptr); if (tLastRefresh && tNow < tLastRefresh + C4NetMinRefreshInterval) { // avoid hammering on refresh key diff --git a/src/gui/C4StartupOptionsDlg.cpp b/src/gui/C4StartupOptionsDlg.cpp index f01b3c0c4..a6bf0f0ed 100644 --- a/src/gui/C4StartupOptionsDlg.cpp +++ b/src/gui/C4StartupOptionsDlg.cpp @@ -318,9 +318,9 @@ void C4StartupOptionsDlg::ControlConfigListBox::SetAssignmentSet(class C4PlayerC std::stable_sort(grouped_assignments.begin(),grouped_assignments.end(),&C4StartupOptionsDlg::ControlConfigListBox::sort_by_group); int32_t current_group = 0; - for (std::vector::iterator i = grouped_assignments.begin(); i != grouped_assignments.end(); ++i) + for (auto & grouped_assignment : grouped_assignments) { - assignment = *i; + assignment = grouped_assignment; bool first_element_of_group = assignment->GetGUIGroup() > current_group; current_group = assignment->GetGUIGroup(); // only show assignments of GUI-named controls @@ -662,11 +662,11 @@ C4StartupOptionsDlg::C4StartupOptionsDlg() : C4StartupDlg(LoadResStrNoAmp("IDS_D // key bindings C4CustomKey::CodeList keys; - keys.push_back(C4KeyCodeEx(K_BACK)); keys.push_back(C4KeyCodeEx(K_LEFT)); + keys.emplace_back(K_BACK); keys.emplace_back(K_LEFT); pKeyBack = new C4KeyBinding(keys, "StartupOptionsBack", KEYSCOPE_Gui, new C4GUI::DlgKeyCB(*this, &C4StartupOptionsDlg::KeyBack), C4CustomKey::PRIO_Dlg); keys.clear(); - keys.push_back(C4KeyCodeEx(K_F3)); // overloading global toggle with higher priority here, so a new name is required + keys.emplace_back(K_F3); // overloading global toggle with higher priority here, so a new name is required pKeyToggleMusic = new C4KeyBinding(keys, "OptionsMusicToggle", KEYSCOPE_Gui, new C4GUI::DlgKeyCB(*this, &C4StartupOptionsDlg::KeyMusicToggle), C4CustomKey::PRIO_Dlg); @@ -918,8 +918,8 @@ C4StartupOptionsDlg::C4StartupOptionsDlg() : C4StartupDlg(LoadResStrNoAmp("IDS_D sLabelTxt.Copy(LoadResStr("IDS_CTL_LOUD")); pUseFont->GetTextExtent(sLabelTxt.getData(), w,q, true); pGroupVolume->AddElement(new C4GUI::Label(sLabelTxt.getData(), caVolumeSlider.GetFromRight(w,q), ACenter, C4StartupFontClr, pUseFont, false, false)); - C4GUI::ParCallbackHandler *pCB = new C4GUI::ParCallbackHandler(this, i ? &C4StartupOptionsDlg::OnSoundVolumeSliderChange : &C4StartupOptionsDlg::OnMusicVolumeSliderChange); - C4GUI::ScrollBar *pSlider = new C4GUI::ScrollBar(caVolumeSlider.GetCentered(caVolumeSlider.GetInnerWidth(), C4GUI_ScrollBarHgt), true, pCB, 101); + auto *pCB = new C4GUI::ParCallbackHandler(this, i ? &C4StartupOptionsDlg::OnSoundVolumeSliderChange : &C4StartupOptionsDlg::OnMusicVolumeSliderChange); + auto *pSlider = new C4GUI::ScrollBar(caVolumeSlider.GetCentered(caVolumeSlider.GetInnerWidth(), C4GUI_ScrollBarHgt), true, pCB, 101); pSlider->SetDecoration(&C4Startup::Get()->Graphics.sfctBookScroll, false); pSlider->SetToolTip(i ? LoadResStr("IDS_DESC_VOLUMESOUND") : LoadResStr("IDS_DESC_VOLUMEMUSIC")); pSlider->SetScrollPos(i ? Config.Sound.SoundVolume : Config.Sound.MusicVolume); @@ -1022,11 +1022,11 @@ void C4StartupOptionsDlg::OnGfxMSComboFill(C4GUI::ComboBox_FillCB *pFiller) Application.pWindow->EnumerateMultiSamples(multisamples); std::sort(multisamples.begin(), multisamples.end()); - for(unsigned int i = 0; i < multisamples.size(); ++i) + for(int multisample : multisamples) { StdStrBuf text; - text.Format("%dx", multisamples[i]); - pFiller->AddEntry(text.getData(), multisamples[i]); + text.Format("%dx", multisample); + pFiller->AddEntry(text.getData(), multisample); } } diff --git a/src/gui/C4StartupPlrSelDlg.cpp b/src/gui/C4StartupPlrSelDlg.cpp index a960d1e6d..cb8137cb0 100644 --- a/src/gui/C4StartupPlrSelDlg.cpp +++ b/src/gui/C4StartupPlrSelDlg.cpp @@ -523,9 +523,9 @@ C4StartupPlrSelDlg::C4StartupPlrSelDlg() : C4StartupDlg("W"), eMode(PSDM_Player) // key bindings C4CustomKey::CodeList keys; - keys.push_back(C4KeyCodeEx(K_BACK)); - keys.push_back(C4KeyCodeEx(K_LEFT)); - keys.push_back(C4KeyCodeEx(K_ESCAPE)); + keys.emplace_back(K_BACK); + keys.emplace_back(K_LEFT); + keys.emplace_back(K_ESCAPE); if (Config.Controls.GamepadGuiControl) { ControllerKeys::Cancel(keys); @@ -998,8 +998,8 @@ typedef std::vector C4StartupPlrSelDlg_Cre int32_t C4StartupPlrSelDlg::CrewSortFunc(const C4GUI::Element *pEl1, const C4GUI::Element *pEl2, void *par) { - const CrewListItem *pItem1 = static_cast(pEl1); - const CrewListItem *pItem2 = static_cast(pEl2); + const auto *pItem1 = static_cast(pEl1); + const auto *pItem2 = static_cast(pEl2); C4StartupPlrSelDlg_CrewSortData &rSortData = *static_cast(par); C4StartupPlrSelDlg_CrewSortData::iterator i = std::find_if(rSortData.begin(), rSortData.end(), C4StartupPlrSelDlg_CrewSortDataMatchType(pItem1->GetCore().id)), j = std::find_if(rSortData.begin(), rSortData.end(), C4StartupPlrSelDlg_CrewSortDataMatchType(pItem2->GetCore().id)); @@ -1022,7 +1022,7 @@ void C4StartupPlrSelDlg::ResortCrew() { C4StartupPlrSelDlg_CrewSortData::iterator i = std::find_if(SortData.begin(), SortData.end(), C4StartupPlrSelDlg_CrewSortDataMatchType(pCrewItem->GetCore().id)); if (i == SortData.end()) - SortData.push_back(C4StartupPlrSelDlg_CrewSortDataEntry(pCrewItem->GetCore().Experience, pCrewItem->GetCore().id)); + SortData.emplace_back(pCrewItem->GetCore().Experience, pCrewItem->GetCore().id); else (*i).iMaxExp = std::max((*i).iMaxExp, pCrewItem->GetCore().Experience); } @@ -1038,7 +1038,7 @@ public: protected: // Event handler - virtual void OnClosed(bool commit); + void OnClosed(bool commit) override; private: class Picker : public C4GUI::Control @@ -1052,9 +1052,9 @@ private: protected: // Event handlers, overridden from C4GUI::Control - virtual void DrawElement(C4TargetFacet &cgo); - virtual void MouseInput(C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam); - virtual void DoDragging(C4GUI::CMouse &rMouse, int32_t iX, int32_t iY, DWORD dwKeyParam); + void DrawElement(C4TargetFacet &cgo) override; + void MouseInput(C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override; + void DoDragging(C4GUI::CMouse &rMouse, int32_t iX, int32_t iY, DWORD dwKeyParam) override; private: static const unsigned int HSPickerCursorSize = 5; diff --git a/src/gui/C4StartupScenSelDlg.cpp b/src/gui/C4StartupScenSelDlg.cpp index 803754d70..f5bc01a4b 100644 --- a/src/gui/C4StartupScenSelDlg.cpp +++ b/src/gui/C4StartupScenSelDlg.cpp @@ -130,7 +130,7 @@ bool C4MapFolderData::Load(C4Group &hGroup, C4ScenarioListLoader::Folder *pScenL // load images if (!fctBackgroundPicture.Load(hGroup, C4CFN_MapFolderBG, C4FCT_Full, C4FCT_Full, false, 0)) { - DebugLogF("C4MapFolderData::Load(%s): Could not load background graphic \"%s\"", hGroup.GetName(), C4CFN_MapFolderBG); + DebugLogF(R"(C4MapFolderData::Load(%s): Could not load background graphic "%s")", hGroup.GetName(), C4CFN_MapFolderBG); return false; } int i; @@ -156,18 +156,18 @@ bool C4MapFolderData::Load(C4Group &hGroup, C4ScenarioListLoader::Folder *pScenL fSuccess = fctDump.Surface->SavePNG(pScen->sBaseImage.getData(), true, false, false); } if (!fSuccess) - DebugLogF("C4MapFolderData::Load(%s): Could not dump graphic \"%s\"", hGroup.GetName(), pScen->sBaseImage.getData()); + DebugLogF(R"(C4MapFolderData::Load(%s): Could not dump graphic "%s")", hGroup.GetName(), pScen->sBaseImage.getData()); continue; } // load images if (pScen->sBaseImage.getLength()>0) if (!pScen->fctBase.Load(hGroup, pScen->sBaseImage.getData(), C4FCT_Full, C4FCT_Full, false, 0)) { - DebugLogF("C4MapFolderData::Load(%s): Could not load base graphic \"%s\"", hGroup.GetName(), pScen->sBaseImage.getData()); + DebugLogF(R"(C4MapFolderData::Load(%s): Could not load base graphic "%s")", hGroup.GetName(), pScen->sBaseImage.getData()); return false; } if (pScen->sOverlayImage.getLength()>0) if (!pScen->fctOverlay.Load(hGroup, pScen->sOverlayImage.getData(), C4FCT_Full, C4FCT_Full, false, 0)) { - DebugLogF("C4MapFolderData::Load(%s): Could not load graphic \"%s\"", hGroup.GetName(), pScen->sOverlayImage.getData()); + DebugLogF(R"(C4MapFolderData::Load(%s): Could not load graphic "%s")", hGroup.GetName(), pScen->sOverlayImage.getData()); return false; } } @@ -176,7 +176,7 @@ bool C4MapFolderData::Load(C4Group &hGroup, C4ScenarioListLoader::Folder *pScenL AccessGfx *pGfx= ppAccessGfxList[i]; if (pGfx->sOverlayImage.getLength()>0) if (!pGfx->fctOverlay.Load(hGroup, pGfx->sOverlayImage.getData(), C4FCT_Full, C4FCT_Full, false, 0)) { - DebugLogF("C4MapFolderData::Load(%s): Could not load graphic \"%s\"", hGroup.GetName(), pGfx->sOverlayImage.getData()); + DebugLogF(R"(C4MapFolderData::Load(%s): Could not load graphic "%s")", hGroup.GetName(), pGfx->sOverlayImage.getData()); return false; } } @@ -680,9 +680,8 @@ bool C4ScenarioListLoader::Scenario::LoadCustomPre(C4Group &rGrp) // achievement images: Loaded from this entry and parent folder nAchievements = 0; const C4ScenarioParameterDefs *deflists[] = { pParent ? pParent->GetAchievementDefs() : nullptr, &ParameterDefs }; - for (size_t def_list_idx=0; def_list_idx<2; ++def_list_idx) + for (auto deflist : deflists) { - const C4ScenarioParameterDefs *deflist = deflists[def_list_idx]; if (!deflist) continue; const C4ScenarioParameterDef *def; size_t idx=0; while ((def = deflist->GetParameterDefByIndex(idx++))) @@ -1046,7 +1045,7 @@ bool C4ScenarioListLoader::SubFolder::DoLoadContents(C4ScenarioListLoader *pLoad // ...and load it if (!pNewEntry->Load(&Group, &sChildFilename, fLoadEx)) { - DebugLogF("Error loading entry \"%s\" in SubFolder \"%s\"!", sChildFilename.getData(), Group.GetFullName().getData()); + DebugLogF(R"(Error loading entry "%s" in SubFolder "%s"!)", sChildFilename.getData(), Group.GetFullName().getData()); delete pNewEntry; } } @@ -1079,8 +1078,7 @@ bool C4ScenarioListLoader::SubFolder::DoLoadContents(C4ScenarioListLoader *pLoad // ------------------------------------ // RegularFolder -C4ScenarioListLoader::RegularFolder::~RegularFolder() -{} +C4ScenarioListLoader::RegularFolder::~RegularFolder() = default; bool C4ScenarioListLoader::RegularFolder::LoadCustom(C4Group &rGrp, bool fNameLoaded, bool fIconLoaded) { @@ -1139,7 +1137,7 @@ bool C4ScenarioListLoader::RegularFolder::DoLoadContents(C4ScenarioListLoader *p // ...and load it if (!pNewEntry->Load(nullptr, &sChildFilename, fLoadEx)) { - DebugLogF("Error loading entry \"%s\" in Folder \"%s\"!", szChildFilename, it->c_str()); + DebugLogF(R"(Error loading entry "%s" in Folder "%s"!)", szChildFilename, it->c_str()); delete pNewEntry; } } @@ -1154,7 +1152,7 @@ bool C4ScenarioListLoader::RegularFolder::DoLoadContents(C4ScenarioListLoader *p void C4ScenarioListLoader::RegularFolder::Merge(const char *szPath) { - contents.push_back(szPath); + contents.emplace_back(szPath); } // ------------------------------------ @@ -1223,8 +1221,8 @@ bool C4ScenarioListLoader::Load(const StdStrBuf &sRootFolder) pCurrFolder = pRootFolder = new RegularFolder(this, nullptr); // Load regular game data if no explicit path specified if(!sRootFolder.getData()) - for(C4Reloc::iterator iter = Reloc.begin(); iter != Reloc.end(); ++iter) - pRootFolder->Merge(iter->strBuf.getData()); + for(const auto & iter : Reloc) + pRootFolder->Merge(iter.strBuf.getData()); bool fSuccess = pRootFolder->LoadContents(this, nullptr, &sRootFolder, false, false); EndActivity(); return fSuccess; @@ -1319,7 +1317,7 @@ C4StartupScenSelDlg::ScenListItem::ScenListItem(C4GUI::ListBox *pForListBox, C4S SetBounds(pIcon->GetBounds()); // add components AddElement(pIcon); AddElement(pNameLabel); - for (int32_t i=0; iGetName().getData()); // add to listbox (will get resized horizontally and moved) - zero indent; no tree structure in this dialog @@ -1338,9 +1336,9 @@ void C4StartupScenSelDlg::ScenListItem::UpdateOwnPos() ParentClass::UpdateOwnPos(); // reposition achievement items C4GUI::ComponentAligner caBounds(GetContainedClientRect(), IconLabelSpacing, IconLabelSpacing); - for (int32_t i=0; iSetBounds(caBounds.GetFromRight(caBounds.GetHeight())); + ppAchievement->SetBounds(caBounds.GetFromRight(caBounds.GetHeight())); } } @@ -1483,7 +1481,7 @@ C4StartupScenSelDlg::C4StartupScenSelDlg(bool fNetwork) : C4StartupDlg(LoadResSt // key bindings C4CustomKey::CodeList keys; - keys.push_back(C4KeyCodeEx(K_BACK)); keys.push_back(C4KeyCodeEx(K_LEFT)); + keys.emplace_back(K_BACK); keys.emplace_back(K_LEFT); pKeyBack = new C4KeyBinding(keys, "StartupScenSelFolderUp", KEYSCOPE_Gui, new C4GUI::DlgKeyCB(*this, &C4StartupScenSelDlg::KeyBack), C4CustomKey::PRIO_CtrlOverride); pKeyRefresh = new C4KeyBinding(C4KeyCodeEx(K_F5), "StartupScenSelReload", KEYSCOPE_Gui, diff --git a/src/gui/C4UpperBoard.cpp b/src/gui/C4UpperBoard.cpp index 32fbc8c2a..5f6d5e491 100644 --- a/src/gui/C4UpperBoard.cpp +++ b/src/gui/C4UpperBoard.cpp @@ -21,20 +21,16 @@ #include "graphics/C4GraphicsResource.h" #include "graphics/C4Draw.h" -C4UpperBoard::C4UpperBoard() -{ -} +C4UpperBoard::C4UpperBoard() = default; -C4UpperBoard::~C4UpperBoard() -{ -} +C4UpperBoard::~C4UpperBoard() = default; void C4UpperBoard::Execute() { if (!Config.Graphics.UpperBoard) return; // Make the time strings sprintf(cTimeString,"%02d:%02d:%02d", Game.Time/3600,(Game.Time%3600)/60,Game.Time%60); - time_t t = time(0); strftime(cTimeString2, sizeof(cTimeString2), "[%H:%M:%S]", localtime(&t)); + time_t t = time(nullptr); strftime(cTimeString2, sizeof(cTimeString2), "[%H:%M:%S]", localtime(&t)); Draw(Output); } diff --git a/src/landscape/C4Landscape.cpp b/src/landscape/C4Landscape.cpp index 1602bba36..04ad5f48c 100644 --- a/src/landscape/C4Landscape.cpp +++ b/src/landscape/C4Landscape.cpp @@ -131,7 +131,7 @@ namespace { bool ForLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, std::function fnCallback, - int32_t *lastx = 0, int32_t *lasty = 0) + int32_t *lastx = nullptr, int32_t *lasty = nullptr) { int d, dx, dy, aincr, bincr, xincr, yincr, x, y; if (Abs(x2 - x1) < Abs(y2 - y1)) @@ -1649,12 +1649,12 @@ bool C4Landscape::Init(C4Group &hGroup, bool fOverloadCurrent, bool fLoadSky, bo // Create FoW assert(p->pFoW == nullptr); if (Game.C4S.Game.FoWEnabled) - p->pFoW.reset(new C4FoW); + p->pFoW = std::make_unique(); // Create renderer #ifndef USE_CONSOLE if (!p->pLandscapeRender) - p->pLandscapeRender.reset(new C4LandscapeRenderGL); + p->pLandscapeRender = std::make_unique(); #endif if (p->pLandscapeRender) diff --git a/src/landscape/C4LandscapeRender.cpp b/src/landscape/C4LandscapeRender.cpp index 63b0a2f50..66a04e715 100644 --- a/src/landscape/C4LandscapeRender.cpp +++ b/src/landscape/C4LandscapeRender.cpp @@ -119,10 +119,10 @@ bool C4LandscapeRenderGL::ReInit(int32_t iWidth, int32_t iHeight) this->iHeight = iHeight; // Clear old landscape textures - for (int i = 0; i < C4LR_SurfaceCount; i++) + for (auto & Surface : Surfaces) { - delete Surfaces[i]; - Surfaces[i] = nullptr; + delete Surface; + Surface = nullptr; } // Allocate new landscape textures @@ -182,10 +182,10 @@ bool C4LandscapeRenderGL::InitLandscapeTexture() int iSfcHgt = iHeight; // Create our surfaces - for(int i = 0; i < C4LR_SurfaceCount; i++) + for(auto & Surface : Surfaces) { - Surfaces[i] = new C4Surface(); - if(!Surfaces[i]->Create(iSfcWdt, iSfcHgt)) + Surface = new C4Surface(); + if(!Surface->Create(iSfcWdt, iSfcHgt)) return false; } @@ -196,7 +196,7 @@ bool C4LandscapeRenderGL::InitMaterialTexture(C4TextureMap *pTexs) { // Populate our map with all needed textures - MaterialTextureMap.push_back(StdCopyStrBuf("")); + MaterialTextureMap.emplace_back(""); AddTexturesFromMap(pTexs); // Determine depth to use @@ -366,10 +366,10 @@ void C4LandscapeRenderGL::Update(C4Rect To, C4Landscape *pSource) // main memory buffer for the box, so that only that box needs to be // sent to the gpu, and not the whole texture, or every pixel // separately. It's an important optimization. - for (int i = 0; i < C4LR_SurfaceCount; i++) + for (auto & Surface : Surfaces) { - if (!Surfaces[i]->Lock()) return; - Surfaces[i]->ClearBoxDw(To.x, To.y, To.Wdt, To.Hgt); + if (!Surface->Lock()) return; + Surface->ClearBoxDw(To.x, To.y, To.Wdt, To.Hgt); } // Initialize up & down placement arrays. These arrays are always updated @@ -509,8 +509,8 @@ void C4LandscapeRenderGL::Update(C4Rect To, C4Landscape *pSource) // done delete[] placementSumsUp; - for (int i = 0; i < C4LR_SurfaceCount; i++) - Surfaces[i]->Unlock(); + for (auto & Surface : Surfaces) + Surface->Unlock(); } /** Returns the data used for the scaler shader for the given pixel. It is a 8-bit bitmask. The bits stand for the 8 @@ -549,12 +549,12 @@ int C4LandscapeRenderGL::CalculateScalerBitmask(int x, int y, C4Rect To, C4Lands // Look for highest-placement material in our surroundings int maxPixel = pixel, maxPlacement = placement; - for(int i = 0; i < 8; i++) + for(int neighbour : neighbours) { - int tempPlacement = MatPlacement(PixCol2Mat(neighbours[i])); - if(tempPlacement > maxPlacement || (tempPlacement == maxPlacement && neighbours[i] > maxPixel) ) + int tempPlacement = MatPlacement(PixCol2Mat(neighbour)); + if(tempPlacement > maxPlacement || (tempPlacement == maxPlacement && neighbour > maxPixel) ) { - maxPixel = neighbours[i]; + maxPixel = neighbour; maxPlacement = tempPlacement; } } @@ -801,17 +801,17 @@ void C4LandscapeRenderGL::AddTextureTransition(const char *szFrom, const char *s if (LookupTextureTransition(szTo, szFrom) >= 0) return; // Single texture? Add it as single if (SEqual(szTo, szFrom)) - MaterialTextureMap.push_back(StdCopyStrBuf(szFrom)); + MaterialTextureMap.emplace_back(szFrom); // Have one of the textures at the end of the list? else if(SEqual(MaterialTextureMap.back().getData(), szFrom)) - MaterialTextureMap.push_back(StdCopyStrBuf(szTo)); + MaterialTextureMap.emplace_back(szTo); else if(SEqual(MaterialTextureMap.back().getData(), szTo)) - MaterialTextureMap.push_back(StdCopyStrBuf(szFrom)); + MaterialTextureMap.emplace_back(szFrom); else { // Otherwise add both - MaterialTextureMap.push_back(StdCopyStrBuf(szFrom)); - MaterialTextureMap.push_back(StdCopyStrBuf(szTo)); + MaterialTextureMap.emplace_back(szFrom); + MaterialTextureMap.emplace_back(szTo); } } @@ -1118,7 +1118,7 @@ void C4LandscapeRenderGL::Draw(const C4TargetFacet &cgo, const C4FoWRegion *Ligh if (Light) glEnableVertexAttribArray(shader->GetAttribute(C4LRA_LightTexCoord)); - glVertexAttribPointer(shader->GetAttribute(C4LRA_Position), 2, GL_FLOAT, GL_FALSE, 0, 0); + glVertexAttribPointer(shader->GetAttribute(C4LRA_Position), 2, GL_FLOAT, GL_FALSE, 0, nullptr); glVertexAttribPointer(shader->GetAttribute(C4LRA_LandscapeTexCoord), 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast(8 * sizeof(float))); if (Light) glVertexAttribPointer(shader->GetAttribute(C4LRA_LightTexCoord), 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast(16 * sizeof(float))); diff --git a/src/landscape/C4Map.cpp b/src/landscape/C4Map.cpp index af6cd651c..c4db60811 100644 --- a/src/landscape/C4Map.cpp +++ b/src/landscape/C4Map.cpp @@ -96,9 +96,9 @@ void C4MapCreator::Create(CSurface8 *sfcMap, // Surface ccol=rTexMap.GetIndexMatTex(rLScape.Material.c_str()); - float amplitude= (float) rLScape.Amplitude.Evaluate(); - float phase= (float) rLScape.Phase.Evaluate(); - float period= (float) rLScape.Period.Evaluate(); + auto amplitude= (float) rLScape.Amplitude.Evaluate(); + auto phase= (float) rLScape.Phase.Evaluate(); + auto period= (float) rLScape.Period.Evaluate(); if (rLScape.MapPlayerExtend) period *= std::min(iPlayerNum, C4S_MaxMapPlayerExtend); float natural= (float) rLScape.Random.Evaluate(); int32_t level0= std::min(MapWdt,MapHgt)/2; diff --git a/src/landscape/C4MapCreatorS2.cpp b/src/landscape/C4MapCreatorS2.cpp index 8f0809242..0cd1d88a5 100644 --- a/src/landscape/C4MapCreatorS2.cpp +++ b/src/landscape/C4MapCreatorS2.cpp @@ -623,7 +623,7 @@ bool C4MCOverlay::PeekPix(int32_t iX, int32_t iY) // start with this one C4MCOverlay *pOvrl=this; bool fLastSetC=false; C4MCTokenType eLastOp=MCT_NONE; BYTE Crap; // loop through op chain - while (1) + while (true) { fLastSetC=pOvrl->RenderPix(iX, iY, Crap, Crap, eLastOp, fLastSetC, false); eLastOp=pOvrl->Op; @@ -1472,7 +1472,7 @@ void C4MCParser::ParseFile(const char *szFilename, C4Group *pGrp) BPos=Code; CPos=Code; ParseTo(MapCreator); - if (0) PrintNodeTree(MapCreator, 0); + if (false) PrintNodeTree(MapCreator, 0); // free code // on errors, this will be done be destructor Clear(); @@ -1486,7 +1486,7 @@ void C4MCParser::Parse(const char *szScript) BPos=szScript; CPos=szScript; ParseTo(MapCreator); - if (0) PrintNodeTree(MapCreator, 0); + if (false) PrintNodeTree(MapCreator, 0); // free code // on errors, this will be done be destructor Clear(); @@ -1759,7 +1759,7 @@ C4MCAlgorithm C4MCAlgoMap[] = { "script", &AlgoScript }, { "rndall", &AlgoRndAll }, { "poly", &AlgoPolygon }, - { "", 0 } + { "", nullptr } }; #define offsC4MCOvrl(x) reinterpret_cast(&C4MCOverlay::x) @@ -1791,6 +1791,6 @@ namespace { { "mask", C4MCV_Boolean, offsC4MCOvrl(Mask) }, { "evalFn", C4MCV_ScriptFunc, offsC4MCOvrl(pEvaluateFunc) }, { "drawFn", C4MCV_ScriptFunc, offsC4MCOvrl(pDrawFunc) }, - { "", C4MCV_None, 0 } + { "", C4MCV_None, nullptr } }; } diff --git a/src/landscape/C4MapScript.cpp b/src/landscape/C4MapScript.cpp index 60cc35c2b..bda30f41e 100644 --- a/src/landscape/C4MapScript.cpp +++ b/src/landscape/C4MapScript.cpp @@ -617,7 +617,7 @@ bool C4MapScriptLayer::FindPos(const C4Rect &search_rect, const C4MapScriptMatTe void C4MapScriptMap::Clear() { // Layers are owned by map. Free them. - for (std::list::iterator i=layers.begin(); i!=layers.end(); ++i) delete *i; + for (auto & layer : layers) delete layer; layers.clear(); } diff --git a/src/landscape/C4MapScriptAlgo.cpp b/src/landscape/C4MapScriptAlgo.cpp index 70a0258c2..0d9e6cd42 100644 --- a/src/landscape/C4MapScriptAlgo.cpp +++ b/src/landscape/C4MapScriptAlgo.cpp @@ -38,7 +38,7 @@ bool C4MapScriptAlgo::GetXYProps(const C4PropList *props, C4PropertyName k, int3 if ((arr = val.getArray())) { if (arr->GetSize() != 2) - throw C4AulExecError(FormatString("C4MapScriptAlgo: Expected either integer or array with two integer elements in property \"%s\".", Strings.P[k].GetCStr()).getData()); + throw C4AulExecError(FormatString(R"(C4MapScriptAlgo: Expected either integer or array with two integer elements in property "%s".)", Strings.P[k].GetCStr()).getData()); out_xy[0] = arr->GetItem(0).getInt(); out_xy[1] = arr->GetItem(1).getInt(); } @@ -54,7 +54,7 @@ C4MapScriptAlgoLayer::C4MapScriptAlgoLayer(const C4PropList *props) // Get MAPALGO_Layer properties C4PropList *layer_pl = props->GetPropertyPropList(P_Layer); if (!layer_pl || !(layer = layer_pl->GetMapScriptLayer())) - throw C4AulExecError("C4MapScriptAlgoLayer: Expected layer in \"Layer\" property."); + throw C4AulExecError(R"(C4MapScriptAlgoLayer: Expected layer in "Layer" property.)"); } bool C4MapScriptAlgoLayer::operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const @@ -143,7 +143,7 @@ C4MapScriptAlgoPolygon::C4MapScriptAlgoPolygon(const C4PropList *props) props->GetProperty(P_X, &vptx); props->GetProperty(P_Y, &vpty); C4ValueArray *ptx = vptx.getArray(), *pty = vpty.getArray(); if (!ptx || !pty || ptx->GetSize() != pty->GetSize()) - throw C4AulExecError("C4MapScriptAlgoPolygon: Expected two equally sized int arrays in properties \"X\" and \"Y\"."); + throw C4AulExecError(R"(C4MapScriptAlgoPolygon: Expected two equally sized int arrays in properties "X" and "Y".)"); poly.resize(ptx->GetSize()); for (int32_t i=0; iGetSize(); ++i) { @@ -195,7 +195,7 @@ C4MapScriptAlgoLines::C4MapScriptAlgoLines(const C4PropList *props) // Get MAPALGO_Lines properties lx = props->GetPropertyInt(P_X); ly = props->GetPropertyInt(P_Y); - if (!lx && !ly) throw C4AulExecError("C4MapScriptAlgoLines: Invalid direction vector. Either \"X\" or \"Y\" must be nonzero!"); + if (!lx && !ly) throw C4AulExecError(R"(C4MapScriptAlgoLines: Invalid direction vector. Either "X" or "Y" must be nonzero!)"); ox = props->GetPropertyInt(P_OffX); oy = props->GetPropertyInt(P_OffY); // use sync-safe distance function to calculate line width @@ -240,7 +240,7 @@ C4MapScriptAlgoModifier::C4MapScriptAlgoModifier(const C4PropList *props, int32_ n = ops->GetSize(); } if (!ops || nmax_ops)) - throw C4AulExecError(FormatString("C4MapScriptAlgo: Expected between %d and %d operands in property \"Op\".", (int)min_ops, (int)max_ops).getData()); + throw C4AulExecError(FormatString(R"(C4MapScriptAlgo: Expected between %d and %d operands in property "Op".)", (int)min_ops, (int)max_ops).getData()); operands.resize(n); try { @@ -249,7 +249,7 @@ C4MapScriptAlgoModifier::C4MapScriptAlgoModifier(const C4PropList *props, int32_ for (int32_t i=0; iGetItem(i).getPropList()); - if (!new_algo) throw C4AulExecError(FormatString("C4MapScriptAlgo: Operand %d in property \"Op\" not valid.", (int)i).getData()); + if (!new_algo) throw C4AulExecError(FormatString(R"(C4MapScriptAlgo: Operand %d in property "Op" not valid.)", (int)i).getData()); operands[i] = new_algo; } } @@ -263,7 +263,7 @@ C4MapScriptAlgoModifier::C4MapScriptAlgoModifier(const C4PropList *props, int32_ void C4MapScriptAlgoModifier::Clear() { // Child algos are owned by this algo, so delete them - for (std::vector::iterator i=operands.begin(); i != operands.end(); ++i) delete *i; + for (auto & operand : operands) delete operand; operands.clear(); } @@ -271,9 +271,9 @@ bool C4MapScriptAlgoAnd::operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t { // Evaluate MAPALGO_And at x,y: // Return 0 if any of the operands is 0. Otherwise, returns value of last operand. - bool val=0; - for (std::vector::const_iterator i=operands.begin(); i != operands.end(); ++i) - if (!(val=(**i)(x, y, fg, bg))) + bool val=false; + for (auto operand : operands) + if (!(val=(*operand)(x, y, fg, bg))) return false; return val; } @@ -283,8 +283,8 @@ bool C4MapScriptAlgoOr::operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& // Evaluate MAPALGO_Or at x,y: // Return first nonzero operand bool val; - for (std::vector::const_iterator i=operands.begin(); i != operands.end(); ++i) - if ((val=(**i)(x, y, fg, bg))) + for (auto operand : operands) + if ((val=(*operand)(x, y, fg, bg))) return val; // If all operands are zero, return zero. return false; diff --git a/src/landscape/C4Material.cpp b/src/landscape/C4Material.cpp index 5000493ea..dee75cb29 100644 --- a/src/landscape/C4Material.cpp +++ b/src/landscape/C4Material.cpp @@ -83,7 +83,7 @@ void C4MaterialReaction::ResolveScriptFuncs(const char *szMatName) { pScriptFunc = ::ScriptEngine.GetPropList()->GetFunc(this->ScriptFunc.getData()); if (!pScriptFunc) - DebugLogF("Error getting function \"%s\" for Material reaction of \"%s\"", this->ScriptFunc.getData(), szMatName); + DebugLogF(R"(Error getting function "%s" for Material reaction of "%s")", this->ScriptFunc.getData(), szMatName); } else pScriptFunc = nullptr; @@ -292,8 +292,8 @@ C4Material::C4Material() void C4Material::UpdateScriptPointers() { - for (uint32_t i = 0; i < CustomReactionList.size(); ++i) - CustomReactionList[i].ResolveScriptFuncs(Name); + for (auto & i : CustomReactionList) + i.ResolveScriptFuncs(Name); } @@ -449,9 +449,9 @@ bool C4MaterialMap::CrossMapMaterials(const char* szEarthMaterial) // Called aft if ((sfcTexture=Texture->Surface32)) Map[cnt].PXSFace.Set(sfcTexture, Map[cnt].PXSGfxRt.x, Map[cnt].PXSGfxRt.y, Map[cnt].PXSGfxRt.Wdt, Map[cnt].PXSGfxRt.Hgt); // evaluate reactions for that material - for (unsigned int iRCnt = 0; iRCnt < pMat->CustomReactionList.size(); ++iRCnt) + for (auto & iRCnt : pMat->CustomReactionList) { - C4MaterialReaction *pReact = &(pMat->CustomReactionList[iRCnt]); + C4MaterialReaction *pReact = &iRCnt; if (pReact->sConvertMat.getLength()) pReact->iConvertMat = Get(pReact->sConvertMat.getData()); else pReact->iConvertMat = -1; // evaluate target spec int32_t tmat; @@ -545,7 +545,7 @@ bool C4MaterialMap::CrossMapMaterials(const char* szEarthMaterial) // Called aft // Get hardcoded system material indices const C4TexMapEntry* earth_entry = ::TextureMap.GetEntry(::TextureMap.GetIndexMatTex(szEarthMaterial)); if(!earth_entry) - { LogFatal(FormatString("Earth material \"%s\" not found!", szEarthMaterial).getData()); return false; } + { LogFatal(FormatString(R"(Earth material "%s" not found!)", szEarthMaterial).getData()); return false; } MVehic = Get("Vehicle"); MCVehic = Mat2PixColDefault(MVehic); MHalfVehic = Get("HalfVehicle"); MCHalfVehic = Mat2PixColDefault(MHalfVehic); diff --git a/src/landscape/C4MaterialList.cpp b/src/landscape/C4MaterialList.cpp index e294f6cf5..2d46867a5 100644 --- a/src/landscape/C4MaterialList.cpp +++ b/src/landscape/C4MaterialList.cpp @@ -42,8 +42,8 @@ void C4MaterialList::Clear() void C4MaterialList::Reset() { - for (int cnt=0; cntNext = this; @@ -462,8 +462,8 @@ void C4SolidMask::PutSolidMasks() } } -C4SolidMask * C4SolidMask::First = 0; -C4SolidMask * C4SolidMask::Last = 0; +C4SolidMask * C4SolidMask::First = nullptr; +C4SolidMask * C4SolidMask::Last = nullptr; bool C4SolidMask::CheckConsistency() diff --git a/src/landscape/C4Texture.cpp b/src/landscape/C4Texture.cpp index fca567b1c..6035ed8f4 100644 --- a/src/landscape/C4Texture.cpp +++ b/src/landscape/C4Texture.cpp @@ -31,7 +31,7 @@ #include "lib/C4Random.h" #include "lib/StdColors.h" -#include +#include #include C4Texture::C4Texture() @@ -279,7 +279,7 @@ int32_t C4TextureMap::LoadMap(C4Group &hGroup, const char *szEntryName, bool *pO std::string::const_iterator separator = std::find(value.cbegin(), value.cend(), '-'); if (separator == value.cend()) { - DebugLogF("TexMap line %u: Texture name \"%s\" is invalid (missing \"-\")", static_cast(line), value.c_str()); + DebugLogF(R"(TexMap line %u: Texture name "%s" is invalid (missing "-"))", static_cast(line), value.c_str()); continue; } @@ -326,9 +326,8 @@ bool C4TextureMap::SaveMap(C4Group &hGroup, const char *szEntryName) if (fOverloadTextures) sTexMapFile.Append("# Import textures from global file as well" LineFeed "OverloadTextures" LineFeed); sTexMapFile.Append(LineFeed); // add entries - for (auto iter = Order.begin(); iter != Order.end(); ++iter) + for (auto i : Order) { - int32_t i = *iter; if (!Entry[i].isNull()) { // compose line diff --git a/src/landscape/C4TransferZone.cpp b/src/landscape/C4TransferZone.cpp index 708fd0758..3d5056415 100644 --- a/src/landscape/C4TransferZone.cpp +++ b/src/landscape/C4TransferZone.cpp @@ -34,9 +34,7 @@ C4TransferZone::C4TransferZone() Used = false; } -C4TransferZone::~C4TransferZone() -{ -} +C4TransferZone::~C4TransferZone() = default; C4TransferZones::C4TransferZones() { diff --git a/src/landscape/fow/C4FoW.cpp b/src/landscape/fow/C4FoW.cpp index 7571635de..1eb295e1a 100644 --- a/src/landscape/fow/C4FoW.cpp +++ b/src/landscape/fow/C4FoW.cpp @@ -18,7 +18,7 @@ #include "landscape/fow/C4FoW.h" #include "graphics/C4Draw.h" -#include +#include C4FoW::C4FoW() diff --git a/src/landscape/fow/C4FoWAmbient.cpp b/src/landscape/fow/C4FoWAmbient.cpp index 517ffc747..cb69ab3b0 100644 --- a/src/landscape/fow/C4FoWAmbient.cpp +++ b/src/landscape/fow/C4FoWAmbient.cpp @@ -60,7 +60,7 @@ double AmbientForPix(int x0, int y0, double R, const LightMap& light_map) // Everything is illuminated, independent of the landscape // This is used to obtain the normalization factor struct LightMapFull { - LightMapFull() {} + LightMapFull() = default; bool operator()(int x, int y) const { return true; } }; diff --git a/src/landscape/fow/C4FoWDrawStrategy.cpp b/src/landscape/fow/C4FoWDrawStrategy.cpp index 3f48e19bf..4ac478438 100644 --- a/src/landscape/fow/C4FoWDrawStrategy.cpp +++ b/src/landscape/fow/C4FoWDrawStrategy.cpp @@ -205,7 +205,7 @@ void C4FoWDrawLightTextureStrategy::End(C4ShaderCall& call) glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX); // Render 1st pass - glDrawElements(GL_TRIANGLES, triangulator.GetNIndices(), GL_UNSIGNED_INT, 0); + glDrawElements(GL_TRIANGLES, triangulator.GetNIndices(), GL_UNSIGNED_INT, nullptr); // Prepare state for 2nd pass //glBlendFunc(GL_ONE, GL_ONE); @@ -224,7 +224,7 @@ void C4FoWDrawLightTextureStrategy::End(C4ShaderCall& call) } // Render 2nd pass - glDrawElements(GL_TRIANGLES, triangulator.GetNIndices(), GL_UNSIGNED_INT, 0); + glDrawElements(GL_TRIANGLES, triangulator.GetNIndices(), GL_UNSIGNED_INT, nullptr); // Prepare state for 3rd pass (color pass) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -246,7 +246,7 @@ void C4FoWDrawLightTextureStrategy::End(C4ShaderCall& call) } // Render 3rd pass - glDrawElements(GL_TRIANGLES, triangulator.GetNIndices(), GL_UNSIGNED_INT, 0); + glDrawElements(GL_TRIANGLES, triangulator.GetNIndices(), GL_UNSIGNED_INT, nullptr); // Reset GL state glBindVertexArray(0); @@ -413,7 +413,7 @@ void C4FoWDrawWireframeStrategy::End(C4ShaderCall& call) const float y_offset[] = { 0.0f, 0.0f }; call.SetUniform2fv(C4FoWRSU_VertexOffset, 1, y_offset); - glDrawElements(GL_TRIANGLES, triangulator.GetNIndices(), GL_UNSIGNED_INT, 0); + glDrawElements(GL_TRIANGLES, triangulator.GetNIndices(), GL_UNSIGNED_INT, nullptr); // Reset GL state glBindVertexArray(0); diff --git a/src/landscape/fow/C4FoWLight.cpp b/src/landscape/fow/C4FoWLight.cpp index 6a7ecfec9..2c1488936 100644 --- a/src/landscape/fow/C4FoWLight.cpp +++ b/src/landscape/fow/C4FoWLight.cpp @@ -47,14 +47,14 @@ C4FoWLight::C4FoWLight(C4Object *pObj) C4FoWLight::~C4FoWLight() { - for(size_t i = 0; i < sections.size(); ++i ) - delete sections[i]; + for(auto & section : sections) + delete section; } void C4FoWLight::Invalidate(C4Rect r) { - for(size_t i = 0; i < sections.size(); ++i ) - sections[i]->Invalidate(r); + for(auto & section : sections) + section->Invalidate(r); } void C4FoWLight::SetReach(int32_t iReach2, int32_t iFadeout2) @@ -68,15 +68,15 @@ void C4FoWLight::SetReach(int32_t iReach2, int32_t iFadeout2) { // Reach decreased? Prune beams iReach = iReach2; - for(size_t i = 0; i < sections.size(); ++i ) - sections[i]->Prune(iReach); + for(auto & section : sections) + section->Prune(iReach); } else { // Reach increased? Dirty beams that might get longer now iReach = iReach2; - for(size_t i = 0; i < sections.size(); ++i ) - sections[i]->Dirty(iReach); + for(auto & section : sections) + section->Dirty(iReach); } } @@ -110,13 +110,13 @@ void C4FoWLight::Update(C4Rect Rec) // Clear if we moved in any way if (iNX != iX || iNY != iY) { - for(size_t i = 0; i < sections.size(); ++i ) - sections[i]->Prune(0); + for(auto & section : sections) + section->Prune(0); iX = iNX; iY = iNY; } - for(size_t i = 0; i < sections.size(); ++i ) - sections[i]->Update(Rec); + for(auto & section : sections) + section->Update(Rec); } void C4FoWLight::Render(C4FoWRegion *region, const C4TargetFacet *onScreen, C4ShaderCall& call) @@ -125,9 +125,9 @@ void C4FoWLight::Render(C4FoWRegion *region, const C4TargetFacet *onScreen, C4Sh bool clip = false; - for(size_t i = 0; i < sections.size(); ++i ) + for(auto & section : sections) { - TriangleList sectionTriangles = sections[i]->CalculateTriangles(region); + TriangleList sectionTriangles = section->CalculateTriangles(region); // if the triangles of one section are clipped completely, the neighbouring triangles // must be marked as clipped @@ -145,9 +145,9 @@ void C4FoWLight::Render(C4FoWRegion *region, const C4TargetFacet *onScreen, C4Sh if (!strategy.get()) { if (onScreen) - strategy.reset(new C4FoWDrawWireframeStrategy(this, onScreen)); + strategy = std::make_unique(this, onScreen); else - strategy.reset(new C4FoWDrawLightTextureStrategy(this)); + strategy = std::make_unique(this); } strategy->Begin(region); @@ -162,10 +162,8 @@ void C4FoWLight::Render(C4FoWRegion *region, const C4TargetFacet *onScreen, C4Sh void C4FoWLight::CalculateFanMaxed(TriangleList &triangles) const { - for (TriangleList::iterator it = triangles.begin(); it != triangles.end(); ++it) + for (auto & tri : triangles) { - C4FoWBeamTriangle &tri = *it; - // Is the left point close enough that normals don't max out? float dist = sqrt(GetSquaredDistanceTo(tri.fanLX, tri.fanLY)); if (dist <= getNormalSize()) { @@ -305,10 +303,8 @@ void C4FoWLight::DrawFade(C4FoWDrawStrategy* pen, TriangleList &triangles) const { pen->BeginFade(); - for (TriangleList::iterator it = triangles.begin(); it != triangles.end(); ++it) + for (auto & tri : triangles) { - C4FoWBeamTriangle &tri = *it; // just for convenience - // The quad will be empty if fan points match if (tri.fanLX == tri.fanRX && tri.fanLY == tri.fanRY) continue; diff --git a/src/landscape/fow/C4FoWLightSection.cpp b/src/landscape/fow/C4FoWLightSection.cpp index 0e6c30f8f..4dae2f4f1 100644 --- a/src/landscape/fow/C4FoWLightSection.cpp +++ b/src/landscape/fow/C4FoWLightSection.cpp @@ -25,7 +25,7 @@ #include "landscape/fow/C4FoWRegion.h" #include "landscape/C4Landscape.h" -#include "float.h" +#include #include @@ -752,10 +752,8 @@ std::list C4FoWLightSection::CalculateTriangles(C4FoWRegion * #endif // Phase 2: Calculate fade points - for (std::list::iterator it = result.begin(); it != result.end(); ++it) + for (auto & tri : result) { - C4FoWBeamTriangle &tri = *it; - // Calculate light bounds. Note that the way light size is calculated // and we are using it below, we need to consider an "asymetrical" light. float lightLX, lightLY, lightRX, lightRY; @@ -797,9 +795,8 @@ std::list C4FoWLightSection::CalculateTriangles(C4FoWRegion * void C4FoWLightSection::transTriangles(std::list &triangles) const { - for (std::list::iterator it = triangles.begin(); it != triangles.end(); ++it) + for (auto & tri : triangles) { - C4FoWBeamTriangle &tri = *it; float x,y; x = tri.fanRX, y = tri.fanRY; diff --git a/src/lib/C4InputValidation.cpp b/src/lib/C4InputValidation.cpp index 44eea312d..6a3857a09 100644 --- a/src/lib/C4InputValidation.cpp +++ b/src/lib/C4InputValidation.cpp @@ -161,7 +161,7 @@ namespace C4InVal assert(!"not yet implemented"); } // issue warning for invalid adjustments - if (0) if (!fValid) + if (false) if (!fValid) { const char *szOption = "unknown"; switch (eOption) @@ -178,7 +178,7 @@ namespace C4InVal case VAL_IRCChannel: szOption = "IRC channel"; break; case VAL_Comment: szOption = "Comment"; break; } - LogF("WARNING: Adjusted invalid user input for \"%s\" to \"%s\"", szOption, rsString.getData()); + LogF(R"(WARNING: Adjusted invalid user input for "%s" to "%s")", szOption, rsString.getData()); } return !fValid; } diff --git a/src/lib/C4Markup.cpp b/src/lib/C4Markup.cpp index 4758e97f0..1651e2d71 100644 --- a/src/lib/C4Markup.cpp +++ b/src/lib/C4Markup.cpp @@ -33,12 +33,12 @@ void C4MarkupTagColor::Apply(C4BltTransform &rBltTrf, bool fDoClr, DWORD &dwClr) bool C4Markup::Read(const char **ppText, bool fSkip) { - char Tag[50]; C4MarkupTag *pNewTag=0; int iTagLen,iParLen; + char Tag[50]; C4MarkupTag *pNewTag=nullptr; int iTagLen,iParLen; // get tag if (!SCopyEnclosed(*ppText, '<', '>', Tag, 49)) return false; iTagLen=SLen(Tag); // split tag to name and pars - char *szPars=0; int iSPos; + char *szPars=nullptr; int iSPos; if ((iSPos=SCharPos(' ', Tag))>-1) { Tag[iSPos]=0; diff --git a/src/lib/C4NameList.cpp b/src/lib/C4NameList.cpp index 969f590f9..c360f9844 100644 --- a/src/lib/C4NameList.cpp +++ b/src/lib/C4NameList.cpp @@ -63,8 +63,8 @@ bool C4NameList::Add(const char *szName, int32_t iCount) bool C4NameList::IsEmpty() { - for (int32_t cnt=0; cntpNext = 0; - pStat->pPrev = 0; + pStat->pNext = nullptr; + pStat->pPrev = nullptr; } else { pStat->pNext = pFirst; pFirst->pPrev = pStat; - pStat->pPrev = 0; + pStat->pPrev = nullptr; pFirst = pStat; } } @@ -53,20 +51,20 @@ void C4MainStat::UnRegStat(C4Stat* pStat) if (!pStat->pPrev) { pFirst = pStat->pNext; - pStat->pNext = 0; + pStat->pNext = nullptr; } // last item? else if (!pStat->pNext) { - pStat->pPrev->pNext = 0; - pStat->pPrev = 0; + pStat->pPrev->pNext = nullptr; + pStat->pPrev = nullptr; } else { pStat->pNext->pPrev = pStat->pPrev; pStat->pPrev->pNext = pStat->pNext; - pStat->pNext = 0; - pStat->pPrev = 0; + pStat->pNext = nullptr; + pStat->pPrev = nullptr; } } @@ -93,8 +91,8 @@ void C4MainStat::Show() iCnt++; // create array - C4Stat** StatArray = new C4Stat*[iCnt]; - bool* bHS = new bool[iCnt]; + auto** StatArray = new C4Stat*[iCnt]; + auto* bHS = new bool[iCnt]; // sort it unsigned int i,ii; diff --git a/src/lib/Standard.cpp b/src/lib/Standard.cpp index ac2357616..00f51fbe2 100644 --- a/src/lib/Standard.cpp +++ b/src/lib/Standard.cpp @@ -121,7 +121,7 @@ int32_t StrToI32(const char *str, int base, const char **scan_end) result *= base; result += value; } - if (scan_end != 0L) *scan_end = s; + if (scan_end != nullptr) *scan_end = s; result *= sign; return result; } diff --git a/src/lib/StdBuf.cpp b/src/lib/StdBuf.cpp index fcc597b24..603c9a783 100644 --- a/src/lib/StdBuf.cpp +++ b/src/lib/StdBuf.cpp @@ -19,8 +19,8 @@ #include "lib/StdAdaptors.h" #include "platform/StdFile.h" -#include -#include +#include +#include #ifdef _WIN32 #include #include "platform/C4windowswrapper.h" @@ -30,7 +30,7 @@ #include #include #endif -#include +#include #include #include @@ -140,9 +140,9 @@ void StdBuf::CompileFunc(StdCompiler *pComp, int iType) #ifdef _WIN32 StdStrBuf::StdStrBuf(const wchar_t * utf16) { - int len = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, nullptr, 0, 0, 0); + int len = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, nullptr, 0, nullptr, nullptr); SetSize(len); - WideCharToMultiByte(CP_UTF8, 0, utf16, -1, getMData(), getSize(), 0, 0); + WideCharToMultiByte(CP_UTF8, 0, utf16, -1, getMData(), getSize(), nullptr, nullptr); } StdStrBuf::wchar_t_holder StdStrBuf::GetWideChar() const { @@ -461,8 +461,8 @@ bool StdStrBuf::EnsureUnicode() { //"€", 0, "‚", "ƒ", "„", "…", "†", "‡", "ˆ", "‰", "Š", "‹", "Œ", 0, "Ž", 0, // 0, "‘", "’", "“", "”", "•", "–", "—", "˜", "™", "š", "›", "œ", 0, "ž", "Ÿ" }; - "\xe2\x82\xac", 0, "\xe2\x80\x9a", "\xc6\x92", "\xe2\x80\x9e", "\xe2\x80\xa6", "\xe2\x80\xa0", "\xe2\x80\xa1", "\xcb\x86", "\xe2\x80\xb0", "\xc5\xa0", "\xe2\x80\xb9", "\xc5\x92", 0, "\xc5\xbd", 0, - 0, "\xe2\x80\x98", "\xe2\x80\x99", "\xe2\x80\x9c", "\xe2\x80\x9d", "\xe2\x80\xa2", "\xe2\x80\x93", "\xe2\x80\x94", "\xcb\x9c", "\xe2\x84\xa2", "\xc5\xa1", "\xe2\x80\xba", "\xc5\x93", 0, "\xc5\xbe", "\xc5\xb8" + "\xe2\x82\xac", nullptr, "\xe2\x80\x9a", "\xc6\x92", "\xe2\x80\x9e", "\xe2\x80\xa6", "\xe2\x80\xa0", "\xe2\x80\xa1", "\xcb\x86", "\xe2\x80\xb0", "\xc5\xa0", "\xe2\x80\xb9", "\xc5\x92", nullptr, "\xc5\xbd", nullptr, + nullptr, "\xe2\x80\x98", "\xe2\x80\x99", "\xe2\x80\x9c", "\xe2\x80\x9d", "\xe2\x80\xa2", "\xe2\x80\x93", "\xe2\x80\x94", "\xcb\x9c", "\xe2\x84\xa2", "\xc5\xa1", "\xe2\x80\xba", "\xc5\x93", nullptr, "\xc5\xbe", "\xc5\xb8" }; buf.Append(extra_chars[c - 0x80]); j += strlen(extra_chars[c - 0x80]); @@ -511,12 +511,12 @@ bool StdStrBuf::TrimSpaces() #ifdef _WIN32 std::string WStrToString(wchar_t *ws) { - int len = WideCharToMultiByte(CP_UTF8, 0, ws, -1, nullptr, 0, 0, 0); + int len = WideCharToMultiByte(CP_UTF8, 0, ws, -1, nullptr, 0, nullptr, nullptr); assert(len >= 0); if (len <= 0) return std::string{}; std::string s(static_cast(len), '\0'); - s.resize(WideCharToMultiByte(CP_UTF8, 0, ws, -1, &s[0], s.size(), 0, 0) - 1); + s.resize(WideCharToMultiByte(CP_UTF8, 0, ws, -1, &s[0], s.size(), nullptr, nullptr) - 1); return s; } #endif diff --git a/src/lib/StdCompiler.cpp b/src/lib/StdCompiler.cpp index 1f5637510..70972a6a6 100644 --- a/src/lib/StdCompiler.cpp +++ b/src/lib/StdCompiler.cpp @@ -16,9 +16,9 @@ #include "C4Include.h" #include "lib/StdCompiler.h" -#include -#include -#include +#include +#include +#include #include "lib/C4Log.h" // *** StdCompiler @@ -393,17 +393,17 @@ void StdCompilerINIWrite::WriteEscaped(const char *szString, const char *pEnd) fLastNumEscape = false; switch (*pPos) { - case '\a': Buf.Append("\\a"); break; - case '\b': Buf.Append("\\b"); break; - case '\f': Buf.Append("\\f"); break; - case '\n': Buf.Append("\\n"); break; - case '\r': Buf.Append("\\r"); break; - case '\t': Buf.Append("\\t"); break; - case '\v': Buf.Append("\\v"); break; - case '\"': Buf.Append("\\\""); break; - case '\\': Buf.Append("\\\\"); break; + case '\a': Buf.Append(R"(\a)"); break; + case '\b': Buf.Append(R"(\b)"); break; + case '\f': Buf.Append(R"(\f)"); break; + case '\n': Buf.Append(R"(\n)"); break; + case '\r': Buf.Append(R"(\r)"); break; + case '\t': Buf.Append(R"(\t)"); break; + case '\v': Buf.Append(R"(\v)"); break; + case '\"': Buf.Append(R"(\")"); break; + case '\\': Buf.Append(R"(\\)"); break; default: - Buf.AppendFormat("\\%o", *reinterpret_cast(pPos)); + Buf.AppendFormat(R"(\%o)", *reinterpret_cast(pPos)); fLastNumEscape = true; } // Set pointer @@ -497,7 +497,7 @@ void StdCompilerINIRead::NameEnd(bool fBreak) { // Report unused entries if (pNode->Pos && !fBreak) - Warn("Unexpected %s \"%s\"!", pNode->Section ? "section" : "value", pNode->Name.getData()); + Warn(R"(Unexpected %s "%s"!)", pNode->Section ? "section" : "value", pNode->Name.getData()); // delete node pNext = pNode->NextChild; delete pNode; @@ -587,7 +587,7 @@ int StdCompilerINIRead::NameCount(const char *szName) const char *StdCompilerINIRead::GetNameByIndex(size_t idx) const { // not in virtual naming - if (iDepth > iRealDepth || !pName) return 0; + if (iDepth > iRealDepth || !pName) return nullptr; // count within current name NameNode *pNode; for (pNode = pName->FirstChild; pNode; pNode = pNode->NextChild) @@ -732,11 +732,11 @@ StdStrBuf StdCompilerINIRead::getPosition() const if (pPos) return FormatString("line %d", getLineNumberOfPos(pPos)); else if (iDepth == iRealDepth) - return FormatString(pName->Section ? "section \"%s\", after line %d" : "value \"%s\", line %d", pName->Name.getData(), getLineNumberOfPos(pName->Pos)); + return FormatString(pName->Section ? R"(section "%s", after line %d)" : R"(value "%s", line %d)", pName->Name.getData(), getLineNumberOfPos(pName->Pos)); else if (iRealDepth) - return FormatString("missing value/section \"%s\" inside section \"%s\" (line %d)", NotFoundName.getData(), pName->Name.getData(), getLineNumberOfPos(pName->Pos)); + return FormatString(R"(missing value/section "%s" inside section "%s" (line %d))", NotFoundName.getData(), pName->Name.getData(), getLineNumberOfPos(pName->Pos)); else - return FormatString("missing value/section \"%s\"", NotFoundName.getData()); + return FormatString(R"(missing value/section "%s")", NotFoundName.getData()); } void StdCompilerINIRead::Begin() diff --git a/src/lib/StdMesh.cpp b/src/lib/StdMesh.cpp index cc8e24cc0..65a2d112d 100644 --- a/src/lib/StdMesh.cpp +++ b/src/lib/StdMesh.cpp @@ -158,7 +158,7 @@ namespace pComp->Value(mkParAdapt(id_str, StdCompiler::RCT_Idtf)); id = StdMeshInstance::SerializableValueProvider::Lookup(id_str.getData()); - if(!id) pComp->excCorrupt("No value provider for ID \"%s\"", id_str.getData()); + if(!id) pComp->excCorrupt(R"(No value provider for ID "%s")", id_str.getData()); } else { @@ -344,8 +344,8 @@ StdMeshAnimation::StdMeshAnimation(const StdMeshAnimation& other): StdMeshAnimation::~StdMeshAnimation() { - for (unsigned int i = 0; i < Tracks.size(); ++i) - delete Tracks[i]; + for (auto & Track : Tracks) + delete Track; } StdMeshAnimation& StdMeshAnimation::operator=(const StdMeshAnimation& other) @@ -355,8 +355,8 @@ StdMeshAnimation& StdMeshAnimation::operator=(const StdMeshAnimation& other) Name = other.Name; Length = other.Length; - for (unsigned int i = 0; i < Tracks.size(); ++i) - delete Tracks[i]; + for (auto & Track : Tracks) + delete Track; Tracks.resize(other.Tracks.size()); @@ -367,30 +367,28 @@ StdMeshAnimation& StdMeshAnimation::operator=(const StdMeshAnimation& other) return *this; } -StdMeshSkeleton::StdMeshSkeleton() -{ -} +StdMeshSkeleton::StdMeshSkeleton() = default; StdMeshSkeleton::~StdMeshSkeleton() { - for (unsigned int i = 0; i < Bones.size(); ++i) - delete Bones[i]; + for (auto & Bone : Bones) + delete Bone; } void StdMeshSkeleton::AddMasterBone(StdMeshBone *bone) { bone->Index = Bones.size(); // Remember index in master bone table Bones.push_back(bone); - for (unsigned int i = 0; i < bone->Children.size(); ++i) - AddMasterBone(bone->Children[i]); + for (auto & i : bone->Children) + AddMasterBone(i); } const StdMeshBone* StdMeshSkeleton::GetBoneByName(const StdStrBuf& name) const { // Lookup parent bone - for (unsigned int i = 0; i < Bones.size(); ++i) - if (Bones[i]->Name == name) - return Bones[i]; + for (auto Bone : Bones) + if (Bone->Name == name) + return Bone; return nullptr; } @@ -407,8 +405,8 @@ std::vector StdMeshSkeleton::GetAnimations() const { std::vector result; result.reserve(Animations.size()); - for (std::map::const_iterator iter = Animations.begin(); iter != Animations.end(); ++iter) - result.push_back(&iter->second); + for (const auto & Animation : Animations) + result.push_back(&Animation.second); return result; } @@ -448,12 +446,12 @@ void StdMeshSkeleton::MirrorAnimation(const StdMeshAnimation& animation) // Mirror all the keyframes of both tracks if (new_anim.Tracks[i] != nullptr) - for (std::map::iterator iter = new_anim.Tracks[i]->Frames.begin(); iter != new_anim.Tracks[i]->Frames.end(); ++iter) - MirrorKeyFrame(iter->second, own_trans, StdMeshTransformation::Inverse(other_own_trans)); + for (auto & Frame : new_anim.Tracks[i]->Frames) + MirrorKeyFrame(Frame.second, own_trans, StdMeshTransformation::Inverse(other_own_trans)); if (new_anim.Tracks[other_bone->Index] != nullptr) - for (std::map::iterator iter = new_anim.Tracks[other_bone->Index]->Frames.begin(); iter != new_anim.Tracks[other_bone->Index]->Frames.end(); ++iter) - MirrorKeyFrame(iter->second, other_own_trans, StdMeshTransformation::Inverse(own_trans)); + for (auto & Frame : new_anim.Tracks[other_bone->Index]->Frames) + MirrorKeyFrame(Frame.second, other_own_trans, StdMeshTransformation::Inverse(own_trans)); } } else if (bone.Name.Compare_(".N", bone.Name.getLength() - 2) != 0) @@ -463,8 +461,8 @@ void StdMeshSkeleton::MirrorAnimation(const StdMeshAnimation& animation) StdMeshTransformation own_trans = bone.Transformation; if (bone.GetParent()) own_trans = bone.GetParent()->InverseTransformation * bone.Transformation; - for (std::map::iterator iter = new_anim.Tracks[i]->Frames.begin(); iter != new_anim.Tracks[i]->Frames.end(); ++iter) - MirrorKeyFrame(iter->second, own_trans, StdMeshTransformation::Inverse(own_trans)); + for (auto & Frame : new_anim.Tracks[i]->Frames) + MirrorKeyFrame(Frame.second, own_trans, StdMeshTransformation::Inverse(own_trans)); } } } @@ -507,14 +505,14 @@ void StdMeshSkeleton::InsertAnimation(const StdMeshSkeleton& source, const StdMe void StdMeshSkeleton::PostInit() { // Mirror .R and .L animations without counterpart - for (std::map::iterator iter = Animations.begin(); iter != Animations.end(); ++iter) + for (auto & Animation : Animations) { // For debugging purposes: // if(iter->second.Name == "Jump") // MirrorAnimation(StdCopyStrBuf("Jump.Mirror"), iter->second); // mirrors only if necessary - MirrorAnimation(iter->second); + MirrorAnimation(Animation.second); } } @@ -773,7 +771,7 @@ void StdSubMeshInstance::CompileFunc(StdCompiler* pComp) if(!material) { StdStrBuf buf; - buf.Format("There is no such material with name \"%s\"", material_name.getData()); + buf.Format(R"(There is no such material with name "%s")", material_name.getData()); pComp->excCorrupt(buf.getData()); } @@ -894,7 +892,7 @@ void StdMeshInstanceAnimationNode::CompileFunc(StdCompiler* pComp, const StdMesh StdCopyStrBuf anim_name; pComp->Value(mkNamingAdapt(toC4CStrBuf(anim_name), "Animation")); Leaf.Animation = Mesh->GetSkeleton().GetAnimationByName(anim_name); - if(!Leaf.Animation) pComp->excCorrupt("No such animation: \"%s\"", anim_name.getData()); + if(!Leaf.Animation) pComp->excCorrupt(R"(No such animation: "%s")", anim_name.getData()); } else { @@ -909,7 +907,7 @@ void StdMeshInstanceAnimationNode::CompileFunc(StdCompiler* pComp, const StdMesh StdCopyStrBuf bone_name; pComp->Value(mkNamingAdapt(toC4CStrBuf(bone_name), "Bone")); const StdMeshBone* bone = Mesh->GetSkeleton().GetBoneByName(bone_name); - if(!bone) pComp->excCorrupt("No such bone: \"%s\"", bone_name.getData()); + if(!bone) pComp->excCorrupt(R"(No such bone: "%s")", bone_name.getData()); Custom.BoneIndex = bone->Index; Custom.Transformation = new StdMeshTransformation; } @@ -1122,9 +1120,9 @@ StdMeshInstance::~StdMeshInstance() assert(AnimationNodes.empty()); // Delete submeshes - for (unsigned int i = 0; i < SubMeshInstances.size(); ++i) + for (auto & SubMeshInstance : SubMeshInstances) { - delete SubMeshInstances[i]; + delete SubMeshInstance; } } @@ -1307,9 +1305,9 @@ void StdMeshInstance::ExecuteAnimation(float dt) #ifndef USE_CONSOLE // Update animated textures - for (unsigned int i = 0; i < SubMeshInstances.size(); ++i) + for (auto & SubMeshInstance : SubMeshInstances) { - StdSubMeshInstance& submesh = *SubMeshInstances[i]; + StdSubMeshInstance& submesh = *SubMeshInstance; const StdMeshMaterial& material = submesh.GetMaterial(); const StdMeshMaterialTechnique& technique = material.Techniques[material.BestTechniqueIndex]; for (unsigned int j = 0; j < submesh.PassData.size(); ++j) @@ -1339,8 +1337,8 @@ void StdMeshInstance::ExecuteAnimation(float dt) #endif // Update animation for attached meshes - for (AttachedMeshList::iterator iter = AttachChildren.begin(); iter != AttachChildren.end(); ++iter) - (*iter)->Child->ExecuteAnimation(dt); + for (auto & iter : AttachChildren) + iter->Child->ExecuteAnimation(dt); } StdMeshInstance::AttachedMesh* StdMeshInstance::AttachMesh(const StdMesh& mesh, AttachedMesh::Denumerator* denumerator, const StdStrBuf& parent_bone, const StdStrBuf& child_bone, const StdMeshMatrix& transformation, uint32_t flags, unsigned int attach_number) @@ -1498,17 +1496,17 @@ bool StdMeshInstance::UpdateBoneTransforms() assert(!parent || parent->Index < i); bool have_transform = false; - for (unsigned int j = 0; j < AnimationStack.size(); ++j) + for (auto & j : AnimationStack) { if (have_transform) { StdMeshTransformation other; - if (AnimationStack[j]->GetBoneTransform(i, other)) + if (j->GetBoneTransform(i, other)) Transformation = StdMeshTransformation::Nlerp(Transformation, other, 1.0f); // TODO: Allow custom weighing for slot combination } else { - have_transform = AnimationStack[j]->GetBoneTransform(i, Transformation); + have_transform = j->GetBoneTransform(i, Transformation); } } @@ -1528,9 +1526,8 @@ bool StdMeshInstance::UpdateBoneTransforms() } // Update attachment's attach transformations. Note this is done recursively. - for (AttachedMeshList::iterator iter = AttachChildren.begin(); iter != AttachChildren.end(); ++iter) + for (auto attach : AttachChildren) { - AttachedMesh* attach = *iter; const bool ChildBoneTransformsDirty = attach->Child->BoneTransformsDirty; attach->Child->UpdateBoneTransforms(); @@ -1566,9 +1563,9 @@ bool StdMeshInstance::UpdateBoneTransforms() void StdMeshInstance::ReorderFaces(StdMeshMatrix* global_trans) { #ifndef USE_CONSOLE - for (unsigned int i = 0; i < SubMeshInstances.size(); ++i) + for (auto & SubMeshInstance : SubMeshInstances) { - StdSubMeshInstance& inst = *SubMeshInstances[i]; + StdSubMeshInstance& inst = *SubMeshInstance; assert((inst.Faces.size() > 0) && "StdMeshInstance sub-mesh instance has zero faces"); if(inst.Faces.size() > 0 && inst.CurrentFaceOrdering != StdSubMeshInstance::FO_Fixed) @@ -1671,42 +1668,42 @@ void StdMeshInstance::CompileFunc(StdCompiler* pComp, AttachedMesh::DenumeratorF int32_t iAnimCnt = AnimationStack.size(); pComp->Value(mkNamingCountAdapt(iAnimCnt, "AnimationNode")); - for(AnimationNodeList::iterator iter = AnimationStack.begin(); iter != AnimationStack.end(); ++iter) - pComp->Value(mkParAdapt(mkNamingPtrAdapt(*iter, "AnimationNode"), Mesh)); + for(auto & iter : AnimationStack) + pComp->Value(mkParAdapt(mkNamingPtrAdapt(iter, "AnimationNode"), Mesh)); int32_t iAttachedCnt = AttachChildren.size(); pComp->Value(mkNamingCountAdapt(iAttachedCnt, "Attached")); - for(unsigned int i = 0; i < AttachChildren.size(); ++i) - pComp->Value(mkNamingAdapt(mkParAdapt(*AttachChildren[i], Factory), "Attached")); + for(auto & i : AttachChildren) + pComp->Value(mkNamingAdapt(mkParAdapt(*i, Factory), "Attached")); } } void StdMeshInstance::DenumeratePointers() { - for(unsigned int i = 0; i < AnimationNodes.size(); ++i) - if(AnimationNodes[i]) - AnimationNodes[i]->DenumeratePointers(); + for(auto & AnimationNode : AnimationNodes) + if(AnimationNode) + AnimationNode->DenumeratePointers(); - for(unsigned int i = 0; i < AttachChildren.size(); ++i) + for(auto & i : AttachChildren) { - AttachChildren[i]->DenumeratePointers(); + i->DenumeratePointers(); } } void StdMeshInstance::ClearPointers(class C4Object* pObj) { - for(unsigned int i = 0; i < AnimationNodes.size(); ++i) - if(AnimationNodes[i]) - AnimationNodes[i]->ClearPointers(pObj); + for(auto & AnimationNode : AnimationNodes) + if(AnimationNode) + AnimationNode->ClearPointers(pObj); std::vector Removal; - for(unsigned int i = 0; i < AttachChildren.size(); ++i) - if(!AttachChildren[i]->ClearPointers(pObj)) - Removal.push_back(AttachChildren[i]->Number); + for(auto & i : AttachChildren) + if(!i->ClearPointers(pObj)) + Removal.push_back(i->Number); - for(unsigned int i = 0; i < Removal.size(); ++i) - DetachMesh(Removal[i]); + for(unsigned int i : Removal) + DetachMesh(i); } template @@ -1909,10 +1906,8 @@ void StdMeshInstance::SetBoneTransformsDirty(bool value) if (value) { // Update attachment's attach transformations. Note this is done recursively. - for (AttachedMeshList::iterator iter = AttachChildren.begin(); iter != AttachChildren.end(); ++iter) + for (auto attach : AttachChildren) { - AttachedMesh* attach = *iter; - if (attach->GetFlags() & AM_MatchSkeleton) { attach->Child->SetBoneTransformsDirty(value); diff --git a/src/lib/StdMeshLoaderBinary.cpp b/src/lib/StdMeshLoaderBinary.cpp index 7f0dcf56a..5e2a7fd28 100644 --- a/src/lib/StdMeshLoaderBinary.cpp +++ b/src/lib/StdMeshLoaderBinary.cpp @@ -247,9 +247,9 @@ void StdMeshSkeletonLoader::RemoveSkeletonsInGroup(const char* groupname) } } - for (unsigned i = 0; i < delete_skeletons.size(); i++) + for (const auto & delete_skeleton : delete_skeletons) { - RemoveSkeleton(delete_skeletons[i]); + RemoveSkeleton(delete_skeleton); } } @@ -560,10 +560,8 @@ StdMesh *StdMeshLoader::LoadMeshBinary(const char *sourcefile, size_t length, co else vertices = &mesh->SharedVertices; - for (unsigned int j = 0; j < vertices->size(); ++j) + for (const auto & vertex : *vertices) { - const StdMeshVertex& vertex = (*vertices)[j]; - const float d = std::sqrt(vertex.x*vertex.x + vertex.y*vertex.y + vertex.z*vertex.z); diff --git a/src/lib/StdMeshLoaderBinaryChunks.cpp b/src/lib/StdMeshLoaderBinaryChunks.cpp index 43c74b1f9..f148b31cc 100644 --- a/src/lib/StdMeshLoaderBinaryChunks.cpp +++ b/src/lib/StdMeshLoaderBinaryChunks.cpp @@ -63,26 +63,26 @@ namespace Ogre std::unique_ptr chunk; switch (id) { - case CID_Header: chunk.reset(new ChunkFileHeader()); break; - case CID_Mesh: chunk.reset(new ChunkMesh()); break; + case CID_Header: chunk = std::make_unique(); break; + case CID_Mesh: chunk = std::make_unique(); break; case CID_Mesh_Bone_Assignment: case CID_Submesh_Bone_Assignment: - chunk.reset(new ChunkMeshBoneAssignments()); break; - case CID_Mesh_Skeleton_Link: chunk.reset(new ChunkMeshSkeletonLink()); break; - case CID_Mesh_Bounds: chunk.reset(new ChunkMeshBounds()); break; - case CID_Submesh: chunk.reset(new ChunkSubmesh()); break; - case CID_Submesh_Op: chunk.reset(new ChunkSubmeshOp()); break; - case CID_Geometry: chunk.reset(new ChunkGeometry()); break; - case CID_Geometry_Vertex_Buffer: chunk.reset(new ChunkGeometryVertexBuffer()); break; - case CID_Geometry_Vertex_Data: chunk.reset(new ChunkGeometryVertexData()); break; - case CID_Geometry_Vertex_Decl: chunk.reset(new ChunkGeometryVertexDecl()); break; - case CID_Geometry_Vertex_Decl_Element: chunk.reset(new ChunkGeometryVertexDeclElement()); break; + chunk = std::make_unique(); break; + case CID_Mesh_Skeleton_Link: chunk = std::make_unique(); break; + case CID_Mesh_Bounds: chunk = std::make_unique(); break; + case CID_Submesh: chunk = std::make_unique(); break; + case CID_Submesh_Op: chunk = std::make_unique(); break; + case CID_Geometry: chunk = std::make_unique(); break; + case CID_Geometry_Vertex_Buffer: chunk = std::make_unique(); break; + case CID_Geometry_Vertex_Data: chunk = std::make_unique(); break; + case CID_Geometry_Vertex_Decl: chunk = std::make_unique(); break; + case CID_Geometry_Vertex_Decl_Element: chunk = std::make_unique(); break; default: LogF("StdMeshLoader: I don't know what to do with a chunk of type 0x%xu", id); // Fall through case CID_Edge_List: case CID_Submesh_Name_Table: // We don't care about these - chunk.reset(new ChunkUnknown()); break; + chunk = std::make_unique(); break; }; chunk->type = id; chunk->size = size; @@ -343,18 +343,18 @@ namespace Ogre std::unique_ptr chunk; switch (id) { - case CID_Header: chunk.reset(new ChunkFileHeader()); break; - case CID_BlendMode: chunk.reset(new ChunkBlendMode()); break; - case CID_Bone: chunk.reset(new ChunkBone()); break; - case CID_Bone_Parent: chunk.reset(new ChunkBoneParent()); break; - case CID_Animation: chunk.reset(new ChunkAnimation()); break; - case CID_Animation_BaseInfo: chunk.reset(new ChunkAnimationBaseInfo()); break; - case CID_Animation_Track: chunk.reset(new ChunkAnimationTrack()); break; - case CID_Animation_Track_KF: chunk.reset(new ChunkAnimationTrackKF()); break; - case CID_Animation_Link: chunk.reset(new ChunkAnimationLink()); break; + case CID_Header: chunk = std::make_unique(); break; + case CID_BlendMode: chunk = std::make_unique(); break; + case CID_Bone: chunk = std::make_unique(); break; + case CID_Bone_Parent: chunk = std::make_unique(); break; + case CID_Animation: chunk = std::make_unique(); break; + case CID_Animation_BaseInfo: chunk = std::make_unique(); break; + case CID_Animation_Track: chunk = std::make_unique(); break; + case CID_Animation_Track_KF: chunk = std::make_unique(); break; + case CID_Animation_Link: chunk = std::make_unique(); break; default: LogF("StdMeshLoader: I don't know what to do with a chunk of type 0x%xu", id); - chunk.reset(new ChunkUnknown()); break; + chunk = std::make_unique(); break; }; chunk->type = id; chunk->size = size; diff --git a/src/lib/StdMeshLoaderXml.cpp b/src/lib/StdMeshLoaderXml.cpp index 0abdd16c3..e5850dd81 100644 --- a/src/lib/StdMeshLoaderXml.cpp +++ b/src/lib/StdMeshLoaderXml.cpp @@ -111,8 +111,8 @@ void StdMeshLoader::StdMeshXML::LoadGeometry(StdMesh& mesh, std::vector Skeleton(new StdMeshSkeleton); // Fill master bone table in hierarchical order: - for (unsigned int i = 0; i < bones.size(); ++i) - if (bones[i]->Parent == nullptr) - Skeleton->AddMasterBone(bones[i]); + for (auto & bone : bones) + if (bone->Parent == nullptr) + Skeleton->AddMasterBone(bone); // Load Animations TiXmlElement* animations_elem = skeleton_elem->FirstChildElement("animations"); diff --git a/src/lib/StdMeshMaterial.cpp b/src/lib/StdMeshMaterial.cpp index a4434bda9..83456bf6e 100644 --- a/src/lib/StdMeshMaterial.cpp +++ b/src/lib/StdMeshMaterial.cpp @@ -27,7 +27,7 @@ #ifdef _MSC_VER #define _USE_MATH_DEFINES #endif /* _MSC_VER */ -#include +#include #ifdef WITH_GLIB #include @@ -246,7 +246,7 @@ public: template void Load(StdMeshMaterialParserCtx& ctx, std::vector& vec); private: - unsigned int CurIndex; + unsigned int CurIndex{0u}; }; StdMeshMaterialParserCtx::StdMeshMaterialParserCtx(StdMeshMatManager& manager, const char* mat_script, const char* filename, StdMeshMaterialLoader& loader): @@ -522,13 +522,10 @@ void StdMeshMaterialParserCtx::ErrorUnexpectedIdentifier(const StdStrBuf& identi void StdMeshMaterialParserCtx::WarningNotSupported(const char* identifier) { - DebugLogF("%s:%d: Warning: \"%s\" is not supported!", FileName.getData(), Line, identifier); + DebugLogF(R"(%s:%d: Warning: "%s" is not supported!)", FileName.getData(), Line, identifier); } -StdMeshMaterialSubLoader::StdMeshMaterialSubLoader() - : CurIndex(0) -{ -} +StdMeshMaterialSubLoader::StdMeshMaterialSubLoader() = default; template void StdMeshMaterialSubLoader::Load(StdMeshMaterialParserCtx& ctx, std::vector& vec) @@ -734,9 +731,7 @@ void StdMeshMaterialShaderParameter::Move(StdMeshMaterialShaderParameter &&other other.type = FLOAT; } -StdMeshMaterialShaderParameters::StdMeshMaterialShaderParameters() -{ -} +StdMeshMaterialShaderParameters::StdMeshMaterialShaderParameters() = default; StdMeshMaterialShaderParameter StdMeshMaterialShaderParameters::LoadConstParameter(StdMeshMaterialParserCtx& ctx) { @@ -780,7 +775,7 @@ StdMeshMaterialShaderParameter StdMeshMaterialShaderParameters::LoadConstParamet } else { - ctx.Error(FormatString("Invalid type: \"%s\"", type_name.getData())); + ctx.Error(FormatString(R"(Invalid type: "%s")", type_name.getData())); return StdMeshMaterialShaderParameter(); } } @@ -840,12 +835,12 @@ bool StdMeshMaterialProgram::AddParameterNames(const StdMeshMaterialShaderParame { // TODO: This is O(n^2) -- not optimal! bool added = false; - for (unsigned int i = 0; i < parameters.NamedParameters.size(); ++i) + for (const auto & NamedParameter : parameters.NamedParameters) { - const std::vector::const_iterator iter = std::find(ParameterNames.begin(), ParameterNames.end(), parameters.NamedParameters[i].first); + const std::vector::const_iterator iter = std::find(ParameterNames.begin(), ParameterNames.end(), NamedParameter.first); if (iter == ParameterNames.end()) { - ParameterNames.push_back(parameters.NamedParameters[i].first); + ParameterNames.push_back(NamedParameter.first); added = true; } } @@ -1031,7 +1026,7 @@ void StdMeshMaterialTextureUnit::LoadTexture(StdMeshMaterialParserCtx& ctx, cons if (surface->Wdt != surface->Hgt) ctx.Error(StdCopyStrBuf("Texture '") + texname + "' is not quadratic"); - Textures.push_back(TexPtr(surface.release())); + Textures.emplace_back(surface.release()); } void StdMeshMaterialTextureUnit::Load(StdMeshMaterialParserCtx& ctx) @@ -1179,8 +1174,8 @@ void StdMeshMaterialTextureUnit::Load(StdMeshMaterialParserCtx& ctx) { Transformation trans; trans.TransformType = Transformation::T_TRANSFORM; - for (int i = 0; i < 16; ++i) - trans.Transform.M[i] = ctx.AdvanceFloat(); + for (float & i : trans.Transform.M) + i = ctx.AdvanceFloat(); Transformations.push_back(trans); } else if (token_name == "wave_xform") @@ -1219,9 +1214,9 @@ StdMeshMaterialPass::ProgramInstance::ProgramInstance(const StdMeshMaterialProgr void StdMeshMaterialPass::ProgramInstance::LoadParameterRefs(const ShaderInstance* instance) { - for(unsigned int i = 0; i < instance->Parameters.NamedParameters.size(); ++i) + for(const auto & NamedParameter : instance->Parameters.NamedParameters) { - const int index = Program->GetParameterIndex(instance->Parameters.NamedParameters[i].first.getData()); + const int index = Program->GetParameterIndex(NamedParameter.first.getData()); assert(index != -1); const std::vector::const_iterator parameter_iter = @@ -1234,7 +1229,7 @@ void StdMeshMaterialPass::ProgramInstance::LoadParameterRefs(const ShaderInstanc else { ParameterRef ref; - ref.Parameter = &instance->Parameters.NamedParameters[i].second; + ref.Parameter = &NamedParameter.second; ref.UniformIndex = index; Parameters.push_back(ref); } @@ -1472,8 +1467,8 @@ bool StdMeshMaterialTechnique::IsOpaque() const // non-opaque passes will just depend on the opaque value drawn in // the previous pass; total result will not depend on original // frame buffer value). - for(unsigned int i = 0; i < Passes.size(); ++i) - if(Passes[i].IsOpaque()) + for(const auto & Pass : Passes) + if(Pass.IsOpaque()) return true; return false; } diff --git a/src/lib/StdMeshMath.cpp b/src/lib/StdMeshMath.cpp index dab67a517..38bc38163 100644 --- a/src/lib/StdMeshMath.cpp +++ b/src/lib/StdMeshMath.cpp @@ -18,7 +18,7 @@ #ifdef _MSC_VER # define _USE_MATH_DEFINES -# include +# include #endif #include "lib/StdMeshMath.h" diff --git a/src/lib/StdMeshUpdate.cpp b/src/lib/StdMeshUpdate.cpp index 8f865a8f7..655de0f61 100644 --- a/src/lib/StdMeshUpdate.cpp +++ b/src/lib/StdMeshUpdate.cpp @@ -26,16 +26,16 @@ StdMeshMaterialUpdate::StdMeshMaterialUpdate(StdMeshMatManager& manager): void StdMeshMaterialUpdate::Update(StdMesh* mesh) const { - for(std::vector::iterator iter = mesh->SubMeshes.begin(); iter != mesh->SubMeshes.end(); ++iter) + for(auto & SubMesh : mesh->SubMeshes) { - std::map::const_iterator mat_iter = Materials.find(iter->Material); + auto mat_iter = Materials.find(SubMesh.Material); if(mat_iter != Materials.end()) { const StdMeshMaterial* new_material = MaterialManager.GetMaterial(mat_iter->second.Name.getData()); if(new_material) { - iter->Material = new_material; + SubMesh.Material = new_material; } else { @@ -44,7 +44,7 @@ void StdMeshMaterialUpdate::Update(StdMesh* mesh) const // going - next time the scenario will be started the mesh will fail // to load because the material cannot be found. MaterialManager.Materials[mat_iter->second.Name] = mat_iter->second; // TODO: could be moved - iter->Material = MaterialManager.GetMaterial(mat_iter->second.Name.getData()); + SubMesh.Material = MaterialManager.GetMaterial(mat_iter->second.Name.getData()); } } } @@ -70,8 +70,8 @@ void StdMeshMaterialUpdate::Update(StdMeshInstance* instance) const void StdMeshMaterialUpdate::Cancel() const { // Reset all materials in manager - for(std::map::const_iterator iter = Materials.begin(); iter != Materials.end(); ++iter) - MaterialManager.Materials[iter->second.Name] = iter->second; // TODO: could be moved + for(const auto & Material : Materials) + MaterialManager.Materials[Material.second.Name] = Material.second; // TODO: could be moved } void StdMeshMaterialUpdate::Add(const StdMeshMaterial* material) @@ -96,8 +96,8 @@ void StdMeshUpdate::Update(StdMeshInstance* instance, const StdMesh& new_mesh) c instance->BoneTransforms = std::vector(new_mesh.GetSkeleton().GetNumBones(), StdMeshMatrix::Identity()); instance->BoneTransformsDirty = true; - for (unsigned int i = 0; i < instance->SubMeshInstances.size(); ++i) - delete instance->SubMeshInstances[i]; + for (auto & SubMeshInstance : instance->SubMeshInstances) + delete SubMeshInstance; instance->SubMeshInstances.resize(new_mesh.GetNumSubMeshes()); for (unsigned int i = 0; i < instance->SubMeshInstances.size(); ++i) { @@ -139,8 +139,8 @@ void StdMeshUpdate::Update(StdMeshInstance* instance, const StdMesh& new_mesh) c } } - for(unsigned int i = 0; i < Removal.size(); ++i) - instance->DetachMesh(Removal[i]); + for(unsigned int i : Removal) + instance->DetachMesh(i); // Update custom nodes in the animation tree. Leaf nodes which refer to an animation that // does not exist anymore are removed. @@ -197,9 +197,9 @@ StdMeshAnimationUpdate::StdMeshAnimationUpdate(const StdMeshSkeletonLoader& skel for(StdMeshSkeletonLoader::skeleton_iterator iter = skeleton_loader.skeletons_begin(); iter != skeleton_loader.skeletons_end(); ++iter) { const StdMeshSkeleton& skeleton = *iter->second; - for (std::map::const_iterator iter = skeleton.Animations.begin(); iter != skeleton.Animations.end(); ++iter) + for (const auto & Animation : skeleton.Animations) { - AnimationNames[&iter->second] = iter->first; + AnimationNames[&Animation.second] = Animation.first; } } } diff --git a/src/netpuncher/main.cpp b/src/netpuncher/main.cpp index aab35dc27..b9f093f16 100644 --- a/src/netpuncher/main.cpp +++ b/src/netpuncher/main.cpp @@ -19,7 +19,7 @@ #include "network/C4Network2.h" #include "netpuncher/C4PuncherPacket.h" -#include +#include #include #include @@ -40,7 +40,7 @@ private: std::unordered_map peer_ids; std::unordered_map peer_addrs; // Event handlers - virtual bool OnConn(const addr_t &AddrPeer, const addr_t &AddrConnect, const addr_t *OwnAddr, C4NetIO *pNetIO) { + bool OnConn(const addr_t &AddrPeer, const addr_t &AddrConnect, const addr_t *OwnAddr, C4NetIO *pNetIO) override { CID nid; do { nid = rng(); @@ -51,7 +51,7 @@ private: printf("Punched %s... #%u\n", AddrPeer.ToString().getData(), nid); return true; } - virtual void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO) { + void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO) override { auto& addr = rPacket.getAddr(); auto unpack = C4NetpuncherPacket::Construct(rPacket); if (!unpack || unpack->GetType() != PID_Puncher_SReq) { Close(addr); return; } @@ -60,7 +60,7 @@ private: Send(C4NetpuncherPacketCReq(other_it->second).PackTo(addr)); Send(C4NetpuncherPacketCReq(addr).PackTo(other_it->second)); } - virtual void OnDisconn(const addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason) { + void OnDisconn(const addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason) override { auto it = peer_ids.find(AddrPeer); if (it == peer_ids.end()) { printf("ERROR: closing connection for %s: (%s) but no connection is known\n", AddrPeer.ToString().getData(), szReason); diff --git a/src/network/C4Client.cpp b/src/network/C4Client.cpp index 3eb1570af..25552b70c 100644 --- a/src/network/C4Client.cpp +++ b/src/network/C4Client.cpp @@ -40,10 +40,7 @@ C4ClientCore::C4ClientCore() Name.Ref(""); CUID.Ref(""); Nick.Ref(""); } -C4ClientCore::~C4ClientCore() -{ - -} +C4ClientCore::~C4ClientCore() = default; void C4ClientCore::SetLocal(int32_t inID, bool fnActivated, bool fnObserver) { diff --git a/src/network/C4NetIO.cpp b/src/network/C4NetIO.cpp index 54dd675a4..79cd4b76f 100644 --- a/src/network/C4NetIO.cpp +++ b/src/network/C4NetIO.cpp @@ -21,8 +21,8 @@ #include "config/C4Config.h" #include -#include -#include +#include +#include #include #include @@ -596,7 +596,7 @@ StdStrBuf C4NetIO::HostAddress::ToString(int flags) const } char buf[INET6_ADDRSTRLEN]; - if (getnameinfo(&gen, sizeof(v6), buf, sizeof(buf), 0, 0, NI_NUMERICHOST) != 0) + if (getnameinfo(&gen, sizeof(v6), buf, sizeof(buf), nullptr, 0, NI_NUMERICHOST) != 0) return StdStrBuf(); return StdStrBuf(buf, true); @@ -726,10 +726,7 @@ C4NetIO::C4NetIO() ResetError(); } -C4NetIO::~C4NetIO() -{ - -} +C4NetIO::~C4NetIO() = default; bool C4NetIO::InitIPv6Socket(SOCKET socket) { @@ -764,9 +761,7 @@ void C4NetIO::SetError(const char *strnError, bool fSockErr) // construction / destruction -C4NetIOPacket::C4NetIOPacket() -{ -} +C4NetIOPacket::C4NetIOPacket() = default; C4NetIOPacket::C4NetIOPacket(const void *pnData, size_t inSize, bool fCopy, const C4NetIO::addr_t &naddr) : StdCopyBuf(pnData, inSize, fCopy), addr(naddr) @@ -2293,7 +2288,7 @@ const unsigned int C4NetIOUDP::iUDPHeaderSize = 8 + 24; // (bytes) // between platforms. struct C4NetIOUDP::BinAddr { - BinAddr() : type(0) {} + BinAddr() {} BinAddr(const C4NetIO::addr_t& addr) { switch (addr.GetFamily()) @@ -2349,7 +2344,7 @@ struct C4NetIOUDP::BinAddr } uint16_t port; - uint8_t type; + uint8_t type{0}; union { uint8_t v4[4]; diff --git a/src/network/C4Network2IRC.cpp b/src/network/C4Network2IRC.cpp index 0ed384a71..1e017c3cd 100644 --- a/src/network/C4Network2IRC.cpp +++ b/src/network/C4Network2IRC.cpp @@ -402,7 +402,7 @@ bool C4Network2IRCClient::Join(const char *szChannel) const char* message = LoadResStr("IDS_ERR_CHANNELNOTALLOWED"); PushMessage(MSG_Status, "", "", message); SetError("Joining this channel not allowed"); - Application.InteractiveThread.ThreadPostAsync(std::bind(&C4GUI::Screen::ShowMessage, ::pGUI, message, LoadResStr("IDS_DLG_CHAT"), C4GUI::Ico_Error, static_cast(0))); + Application.InteractiveThread.ThreadPostAsync(std::bind(&C4GUI::Screen::ShowMessage, ::pGUI, message, LoadResStr("IDS_DLG_CHAT"), C4GUI::Ico_Error, static_cast(nullptr))); return false; } return Send("JOIN", szChannel); diff --git a/src/network/C4Network2Reference.cpp b/src/network/C4Network2Reference.cpp index c016d4cf7..7b4fc2913 100644 --- a/src/network/C4Network2Reference.cpp +++ b/src/network/C4Network2Reference.cpp @@ -35,10 +35,7 @@ C4Network2Reference::C4Network2Reference() } -C4Network2Reference::~C4Network2Reference() -{ - -} +C4Network2Reference::~C4Network2Reference() = default; void C4Network2Reference::SetSourceAddress(const C4NetIO::EndpointAddress &ip) { @@ -255,9 +252,7 @@ C4Network2HTTPClient::C4Network2HTTPClient() C4NetIOTCP::SetCallback(this); } -C4Network2HTTPClient::~C4Network2HTTPClient() -{ -} +C4Network2HTTPClient::~C4Network2HTTPClient() = default; void C4Network2HTTPClient::PackPacket(const C4NetIOPacket &rPacket, StdBuf &rOutBuf) { @@ -320,7 +315,7 @@ bool C4Network2HTTPClient::ReadHeader(StdStrBuf Data) const char *pData = Data.getData(); const char *pContent = SSearch(pData, "\r\n\r\n"); if (!pContent) - return 0; + return false; // Parse header line int iHTTPVer1, iHTTPVer2, iResponseCode, iStatusStringPtr; if (sscanf(pData, "HTTP/%d.%d %d %n", &iHTTPVer1, &iHTTPVer2, &iResponseCode, &iStatusStringPtr) != 3) diff --git a/src/network/C4Network2Res.cpp b/src/network/C4Network2Res.cpp index b3e3e7fa9..32992cf6a 100644 --- a/src/network/C4Network2Res.cpp +++ b/src/network/C4Network2Res.cpp @@ -31,7 +31,7 @@ #ifdef _WIN32 #include #endif -#include +#include #ifdef _MSC_VER #define snprintf _snprintf @@ -143,10 +143,7 @@ C4Network2ResLoad::C4Network2ResLoad(int32_t inChunk, int32_t inByClient) } -C4Network2ResLoad::~C4Network2ResLoad() -{ - -} +C4Network2ResLoad::~C4Network2ResLoad() = default; bool C4Network2ResLoad::CheckTimeout() { @@ -1188,15 +1185,9 @@ bool C4Network2Res::OptimizeStandalone(bool fSilent) // *** C4Network2ResChunk -C4Network2ResChunk::C4Network2ResChunk() -{ +C4Network2ResChunk::C4Network2ResChunk() = default; -} - -C4Network2ResChunk::~C4Network2ResChunk() -{ - -} +C4Network2ResChunk::~C4Network2ResChunk() = default; bool C4Network2ResChunk::Set(C4Network2Res *pRes, uint32_t inChunk) { diff --git a/src/network/C4Network2Stats.cpp b/src/network/C4Network2Stats.cpp index 521ec8e25..69033009d 100644 --- a/src/network/C4Network2Stats.cpp +++ b/src/network/C4Network2Stats.cpp @@ -263,16 +263,16 @@ C4Graph::ValueType C4GraphCollection::GetMaxValue() const int C4GraphCollection::GetSeriesCount() const { int iCount = 0; - for (const_iterator i = begin(); i != end(); ++i) iCount += (*i)->GetSeriesCount(); + for (auto i : *this) iCount += i->GetSeriesCount(); return iCount; } const C4Graph *C4GraphCollection::GetSeries(int iIndex) const { - for (const_iterator i = begin(); i != end(); ++i) + for (auto i : *this) { - int iCnt = (*i)->GetSeriesCount(); - if (iIndex < iCnt) return (*i)->GetSeries(iIndex); + int iCnt = i->GetSeriesCount(); + if (iIndex < iCnt) return i->GetSeries(iIndex); iIndex -= iCnt; } return nullptr; @@ -281,19 +281,19 @@ const C4Graph *C4GraphCollection::GetSeries(int iIndex) const void C4GraphCollection::Update() const { // update all child graphs - for (const_iterator i = begin(); i != end(); ++i) (*i)->Update(); + for (auto i : *this) i->Update(); } void C4GraphCollection::SetAverageTime(int iToTime) { if ((iCommonAvgTime = iToTime)) - for (iterator i = begin(); i != end(); ++i) (*i)->SetAverageTime(iToTime); + for (auto & i : *this) i->SetAverageTime(iToTime); } void C4GraphCollection::SetMultiplier(ValueType fToVal) { if ((fMultiplier = fToVal)) - for (iterator i = begin(); i != end(); ++i) (*i)->SetMultiplier(fToVal); + for (auto & i : *this) i->SetMultiplier(fToVal); } diff --git a/src/network/C4Network2UPnPDummy.cpp b/src/network/C4Network2UPnPDummy.cpp index 497cf251f..892589426 100644 --- a/src/network/C4Network2UPnPDummy.cpp +++ b/src/network/C4Network2UPnPDummy.cpp @@ -17,7 +17,7 @@ #include "C4Include.h" #include "network/C4Network2UPnP.h" -C4Network2UPnP::C4Network2UPnP() {} -C4Network2UPnP::~C4Network2UPnP() {} +C4Network2UPnP::C4Network2UPnP() = default; +C4Network2UPnP::~C4Network2UPnP() = default; void C4Network2UPnP::AddMapping(C4Network2IOProtocol, uint16_t, uint16_t) {} void C4Network2UPnP::ClearMappings() {} diff --git a/src/network/C4Network2UPnPWin32.cpp b/src/network/C4Network2UPnPWin32.cpp index 78ea63c34..4c346142e 100644 --- a/src/network/C4Network2UPnPWin32.cpp +++ b/src/network/C4Network2UPnPWin32.cpp @@ -51,16 +51,13 @@ namespace class C4Network2UPnPP { public: - bool MustReleaseCOM; + bool MustReleaseCOM{false}; // NAT - IStaticPortMappingCollection *mappings; + IStaticPortMappingCollection *mappings{nullptr}; std::set added_mappings; - C4Network2UPnPP() - : MustReleaseCOM(false), - mappings(nullptr) - {} + C4Network2UPnPP() = default; void AddMapping(C4Network2IOProtocol protocol, uint16_t intport, uint16_t extport); void RemoveMapping(C4Network2IOProtocol protocol, uint16_t extport); @@ -72,7 +69,7 @@ C4Network2UPnP::C4Network2UPnP() { Log("UPnP init..."); // Make sure COM is available - if (FAILED(CoInitializeEx(0, COINIT_APARTMENTTHREADED))) + if (FAILED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED))) { // Didn't work, don't do UPnP then Log("UPnP fail (no COM)."); diff --git a/src/network/C4Packet2.cpp b/src/network/C4Packet2.cpp index 0275dbf92..1cda7232f 100644 --- a/src/network/C4Packet2.cpp +++ b/src/network/C4Packet2.cpp @@ -143,15 +143,9 @@ const char *PacketNameByID(C4PacketType eID) // *** C4PacketBase -C4PacketBase::C4PacketBase() -{ +C4PacketBase::C4PacketBase() = default; -} - -C4PacketBase::~C4PacketBase() -{ - -} +C4PacketBase::~C4PacketBase() = default; C4NetIOPacket C4PacketBase::pack(const C4NetIO::addr_t &addr) const { @@ -172,9 +166,7 @@ void C4PacketBase::unpack(const C4NetIOPacket &Pkt, char *pStatus) // *** C4PktBuf -C4PktBuf::C4PktBuf() -{ -} +C4PktBuf::C4PktBuf() = default; C4PktBuf::C4PktBuf(const C4PktBuf &rCopy) : C4PacketBase(rCopy) { @@ -431,9 +423,7 @@ void C4PacketConn::CompileFunc(StdCompiler *pComp) // *** C4PacketConnRe -C4PacketConnRe::C4PacketConnRe() -{ -} +C4PacketConnRe::C4PacketConnRe() = default; C4PacketConnRe::C4PacketConnRe(bool fnOK, bool fWrongPassword, const char *sznMsg) : fOK(fnOK), @@ -532,10 +522,7 @@ void C4PacketPing::CompileFunc(StdCompiler *pComp) // *** C4PacketResStatus -C4PacketResStatus::C4PacketResStatus() -{ - -} +C4PacketResStatus::C4PacketResStatus() = default; C4PacketResStatus::C4PacketResStatus(int32_t iResID, const C4Network2ResChunkData &nChunks) : iResID(iResID), Chunks(nChunks) diff --git a/src/object/C4Action.cpp b/src/object/C4Action.cpp index d504fda8f..a50708610 100644 --- a/src/object/C4Action.cpp +++ b/src/object/C4Action.cpp @@ -25,10 +25,7 @@ C4Action::C4Action() Default(); } -C4Action::~C4Action() -{ - -} +C4Action::~C4Action() = default; void C4Action::Default() { diff --git a/src/object/C4Command.cpp b/src/object/C4Command.cpp index 33a6647f0..d63ff4427 100644 --- a/src/object/C4Command.cpp +++ b/src/object/C4Command.cpp @@ -1152,7 +1152,7 @@ void C4Command::Activate() // Activate object to exit Target->Controller = cObj->Controller; Target->SetCommand(C4CMD_Exit); - Target = 0; + Target = nullptr; } Finish(true); return; @@ -1697,7 +1697,7 @@ void C4Command::Acquire() // No available material found: buy material // This command will fail immediately if buying at bases is not possible // - but the command should be created anyway because it might be overloaded - cObj->AddCommand(C4CMD_Buy,nullptr,0,0,100,nullptr,true,Data,false,0,0,C4CMD_Mode_Sub); + cObj->AddCommand(C4CMD_Buy,nullptr,0,0,100,nullptr,true,Data,false,0,nullptr,C4CMD_Mode_Sub); } diff --git a/src/object/C4Def.cpp b/src/object/C4Def.cpp index 72b215ac6..084ba0bde 100644 --- a/src/object/C4Def.cpp +++ b/src/object/C4Def.cpp @@ -44,7 +44,7 @@ class C4DefAdditionalResourcesLoader: public StdMeshMaterialLoader public: C4DefAdditionalResourcesLoader(C4Group& hGroup): Group(hGroup) {} - virtual C4Surface* LoadTexture(const char* filename) + C4Surface* LoadTexture(const char* filename) override { if (!Group.AccessEntry(filename)) return nullptr; C4Surface* surface = new C4Surface; @@ -55,14 +55,14 @@ public: return surface; } - virtual StdStrBuf LoadShaderCode(const char* filename) + StdStrBuf LoadShaderCode(const char* filename) override { StdStrBuf ret; if (!Group.LoadEntryString(filename, &ret)) return StdStrBuf(); return ret; } - virtual void AddShaderSlices(C4Shader& shader, int ssc) + void AddShaderSlices(C4Shader& shader, int ssc) override { #ifndef USE_CONSOLE // Add mesh-independent slices diff --git a/src/object/C4DefGraphics.cpp b/src/object/C4DefGraphics.cpp index 7f58fd11c..9237a0dd5 100644 --- a/src/object/C4DefGraphics.cpp +++ b/src/object/C4DefGraphics.cpp @@ -353,7 +353,7 @@ void C4DefGraphics::Draw(C4Facet &cgo, DWORD iColor, C4Object *pObj, int32_t iPh } else { - dummy.reset(new StdMeshInstance(*Mesh, 1.0f)); + dummy = std::make_unique(*Mesh, 1.0f); instance = dummy.get(); pDef->GetProperty(P_PictureTransformation, &value); } @@ -398,7 +398,7 @@ void C4DefGraphicsAdapt::CompileFunc(StdCompiler *pComp) pComp->Value(id); // go over two separators ("::"). Expect them if an id was found. if (!pComp->Separator(StdCompiler::SEP_PART2) || !pComp->Separator(StdCompiler::SEP_PART2)) - pComp->excCorrupt("DefGraphics: expected \"::\""); + pComp->excCorrupt(R"(DefGraphics: expected "::")"); // compile name StdStrBuf Name; if (!deserializing) Name = pDefGraphics->GetName(); pComp->Value(mkDefaultAdapt(mkParAdapt(Name, StdCompiler::RCT_Idtf), "")); @@ -409,7 +409,7 @@ void C4DefGraphicsAdapt::CompileFunc(StdCompiler *pComp) C4Def *pDef = ::Definitions.ID2Def(id); // search def-graphics if (!pDef || !( pDefGraphics = pDef->Graphics.Get(Name.getData()) )) - pComp->excCorrupt("DefGraphics: could not find graphics \"%s\" in %s(%s)!", Name.getData(), id.ToString(), pDef ? pDef->GetName() : "def not found"); + pComp->excCorrupt(R"(DefGraphics: could not find graphics "%s" in %s(%s)!)", Name.getData(), id.ToString(), pDef ? pDef->GetName() : "def not found"); } } @@ -604,9 +604,9 @@ void C4DefGraphicsPtrBackupEntry::UpdateAttachedMesh(StdMeshInstance* instance) for(StdMeshInstance::AttachedMeshIter iter = instance->AttachedMeshesBegin(); iter != instance->AttachedMeshesEnd(); ++iter) attached_meshes.push_back(*iter); - for(std::vector::iterator iter = attached_meshes.begin(); iter != attached_meshes.end(); ++iter) + for(auto & attached_mesh : attached_meshes) // TODO: Check that this mesh is still attached? - UpdateAttachedMesh((*iter)->Child); + UpdateAttachedMesh(attached_mesh->Child); } C4DefGraphicsPtrBackup::C4DefGraphicsPtrBackup(): @@ -620,8 +620,8 @@ C4DefGraphicsPtrBackup::~C4DefGraphicsPtrBackup() { if(!fApplied) AssignRemoval(); - for(std::list::iterator iter = Entries.begin(); iter != Entries.end(); ++iter) - delete *iter; + for(auto & Entry : Entries) + delete Entry; } void C4DefGraphicsPtrBackup::Add(C4DefGraphics* pGfx) @@ -649,8 +649,8 @@ void C4DefGraphicsPtrBackup::AssignRemoval() MeshMaterialUpdate.Cancel(); // Remove gfx - for(std::list::iterator iter = Entries.begin(); iter != Entries.end(); ++iter) - (*iter)->AssignRemoval(); + for(auto & Entry : Entries) + Entry->AssignRemoval(); fApplied = true; } @@ -658,13 +658,13 @@ void C4DefGraphicsPtrBackup::AssignRemoval() void C4DefGraphicsPtrBackup::AssignUpdate() { // Update mesh materials for all meshes - for(C4DefList::Table::iterator iter = Definitions.table.begin(); iter != Definitions.table.end(); ++iter) - if(iter->second->Graphics.Type == C4DefGraphics::TYPE_Mesh) - MeshMaterialUpdate.Update(iter->second->Graphics.Mesh); + for(auto & iter : Definitions.table) + if(iter.second->Graphics.Type == C4DefGraphics::TYPE_Mesh) + MeshMaterialUpdate.Update(iter.second->Graphics.Mesh); // Then, update mesh references in instances, attach bones by name, and update sprite gfx - for(std::list::iterator iter = Entries.begin(); iter != Entries.end(); ++iter) - (*iter)->AssignUpdate(); + for(auto & Entry : Entries) + Entry->AssignUpdate(); // Update mesh materials and animations for all mesh instances. for (C4Object *pObj : Objects) diff --git a/src/object/C4DefList.cpp b/src/object/C4DefList.cpp index 9d4932f2b..32c1b50c7 100644 --- a/src/object/C4DefList.cpp +++ b/src/object/C4DefList.cpp @@ -35,7 +35,7 @@ namespace { class C4SkeletonManager : public StdMeshSkeletonLoader { - virtual StdMeshSkeleton* GetSkeletonByDefinition(const char* definition) const + StdMeshSkeleton* GetSkeletonByDefinition(const char* definition) const override { // find the definition C4Def* def = ::Definitions.ID2Def(C4ID(definition)); @@ -443,14 +443,14 @@ float C4DefList::GetFontImageAspect(const char* szImageTag) void C4DefList::Synchronize() { - for (Table::iterator it = table.begin(); it != table.end(); ++it) - it->second->Synchronize(); + for (auto & it : table) + it.second->Synchronize(); } void C4DefList::ResetIncludeDependencies() { - for (Table::iterator it = table.begin(); it != table.end(); ++it) - it->second->ResetIncludeDependencies(); + for (auto & it : table) + it.second->ResetIncludeDependencies(); } void C4DefList::SortByPriority() diff --git a/src/object/C4GameObjects.cpp b/src/object/C4GameObjects.cpp index 111b87dc8..11bd4b17d 100644 --- a/src/object/C4GameObjects.cpp +++ b/src/object/C4GameObjects.cpp @@ -185,7 +185,7 @@ C4Object *C4GameObjects::ObjectPointer(int32_t iNumber) // search own list C4PropList *pObj = C4PropListNumbered::GetByNumber(iNumber); if (pObj) return pObj->GetObject(); - return 0; + return nullptr; } C4Object *C4GameObjects::SafeObjectPointer(int32_t iNumber) diff --git a/src/object/C4Movement.cpp b/src/object/C4Movement.cpp index 9af4878eb..c32e5a699 100644 --- a/src/object/C4Movement.cpp +++ b/src/object/C4Movement.cpp @@ -439,13 +439,13 @@ void C4Object::DoMovement() if (OCF & OCF_HitSpeed2) if (Mass>3) Splash(); fNoAttach=false; - InLiquid=1; + InLiquid=true; } } else // Out of liquid { if (InLiquid) // Leave liquid - InLiquid=0; + InLiquid=false; } // Contact Action if (fAnyContact) @@ -558,7 +558,7 @@ bool C4Object::ExecMovement() // Every Tick1 by Execute // Move object DoMovement(); // Demobilization check - if ((xdir==0) && (ydir==0) && (rdir==0)) Mobile=0; + if ((xdir==0) && (ydir==0) && (rdir==0)) Mobile=false; // Check for stabilization if (rdir==0) Stabilize(); } @@ -571,7 +571,7 @@ bool C4Object::ExecMovement() // Every Tick1 by Execute { // Gravity mobilization xdir=ydir=rdir=0; - Mobile=1; + Mobile=true; } } diff --git a/src/object/C4Object.cpp b/src/object/C4Object.cpp index 136754de4..20d647f18 100644 --- a/src/object/C4Object.cpp +++ b/src/object/C4Object.cpp @@ -87,7 +87,7 @@ void C4Action::GetBridgeData(int32_t &riBridgeTime, bool &rfMoveClonk, bool &rfW C4Object::C4Object() { - FrontParticles = BackParticles = 0; + FrontParticles = BackParticles = nullptr; Default(); } @@ -104,7 +104,7 @@ void C4Object::Default() Mass=OwnMass=0; Damage=0; Energy=0; - Alive=0; + Alive=false; Breath=0; InMat=MNone; Color=0; @@ -113,19 +113,19 @@ void C4Object::Default() lightColor=0xffffffff; fix_x=fix_y=fix_r=0; xdir=ydir=rdir=0; - Mobile=0; + Mobile=false; Unsorted=false; Initializing=false; - OnFire=0; - InLiquid=0; - EntranceStatus=0; + OnFire=false; + InLiquid=false; + EntranceStatus=false; Audible=AudiblePan=0; AudiblePlayer = NO_OWNER; t_contact=0; OCF=0; Action.Default(); Shape.Default(); - fOwnVertices=0; + fOwnVertices=false; Contents.Default(); SolidMask.Default(); PictureRect.Default(); @@ -197,13 +197,13 @@ bool C4Object::Init(C4PropList *pDef, C4Object *pCreator, // Initial mobility if (!!xdir || !!ydir || !!rdir) - Mobile=1; + Mobile=true; // Mass Mass=std::max(Def->Mass*Con/FullCon,1); // Life, energy, breath - if (Category & C4D_Living) Alive=1; + if (Category & C4D_Living) Alive=true; if (Alive) Energy=GetPropertyInt(P_MaxEnergy); Breath=GetPropertyInt(P_MaxBreath); @@ -247,11 +247,11 @@ C4Object::~C4Object() void C4Object::ClearParticleLists() { - if (FrontParticles != 0) + if (FrontParticles != nullptr) Particles.ReleaseParticleList(FrontParticles); - if (BackParticles != 0) + if (BackParticles != nullptr) Particles.ReleaseParticleList(BackParticles); - FrontParticles = BackParticles = 0; + FrontParticles = BackParticles = nullptr; } void C4Object::AssignRemoval(bool fExitContents) @@ -288,7 +288,7 @@ void C4Object::AssignRemoval(bool fExitContents) // remove particles ClearParticleLists(); // Action idle - SetAction(0); + SetAction(nullptr); // Object system operation if (Status == C4OS_INACTIVE) { @@ -530,13 +530,13 @@ void C4Object::DrawFaceImpl(C4TargetFacet &cgo, bool action, float fx, float fy, void C4Object::DrawFace(C4TargetFacet &cgo, float offX, float offY, int32_t iPhaseX, int32_t iPhaseY) const { - const float swdt = float(Def->Shape.Wdt); - const float shgt = float(Def->Shape.Hgt); + const auto swdt = float(Def->Shape.Wdt); + const auto shgt = float(Def->Shape.Hgt); // Grow Type Display - float fx = float(swdt * iPhaseX); - float fy = float(shgt * iPhaseY); - float fwdt = float(swdt); - float fhgt = float(shgt); + auto fx = float(swdt * iPhaseX); + auto fy = float(shgt * iPhaseY); + auto fwdt = float(swdt); + auto fhgt = float(shgt); float stretch_factor = static_cast(Con) / FullCon; float tx = offX + Def->Shape.GetX() * stretch_factor; @@ -583,16 +583,16 @@ void C4Object::DrawActionFace(C4TargetFacet &cgo, float offX, float offY) const C4PropList* pActionDef = GetAction(); // Regular action facet - const float swdt = float(Action.Facet.Wdt); - const float shgt = float(Action.Facet.Hgt); + const auto swdt = float(Action.Facet.Wdt); + const auto shgt = float(Action.Facet.Hgt); int32_t iPhase = Action.Phase; if (pActionDef->GetPropertyInt(P_Reverse)) iPhase = pActionDef->GetPropertyInt(P_Length) - 1 - Action.Phase; // Grow Type Display - float fx = float(Action.Facet.X + swdt * iPhase); - float fy = float(Action.Facet.Y + shgt * Action.DrawDir); - float fwdt = float(swdt); - float fhgt = float(shgt); + auto fx = float(Action.Facet.X + swdt * iPhase); + auto fy = float(Action.Facet.Y + shgt * Action.DrawDir); + auto fwdt = float(swdt); + auto fhgt = float(shgt); // draw stretched towards shape center with transform float stretch_factor = static_cast(Con) / FullCon; @@ -1004,14 +1004,14 @@ void C4Object::AssignDeath(bool fForced) // and prevent recursive death-calls this way // get death causing player before doing effect calls, because those might meddle around with the flags int32_t iDeathCausingPlayer = LastEnergyLossCausePlayer; - Alive=0; + Alive=false; if (pEffects) pEffects->ClearAll(C4FxCall_RemoveDeath); // if the object is alive again, abort here if the kill is not forced if (Alive && !fForced) return; // Action SetActionByName("Dead"); // Values - Alive=0; + Alive=false; ClearCommands(); C4ObjectInfo * pInfo = Info; if (Info) @@ -1054,7 +1054,7 @@ bool C4Object::ChangeDef(C4ID idNew) // Exit container (no Ejection/Departure) if (Contained) Exit(0,0,0,Fix0,Fix0,Fix0,false); // Pre change resets - SetAction(0); + SetAction(nullptr); ResetProperty(&Strings.P[P_Action]); // Enforce ActIdle because SetAction may have failed due to NoOtherAction SetDir(0); // will drop any outdated flipdir if (pSolidMaskData) { delete pSolidMaskData; pSolidMaskData=nullptr; } @@ -1198,7 +1198,7 @@ void C4Object::DoCon(int32_t iChange, bool grow_from_center) while ((cobj=Contents.GetObject())) if (Contained) cobj->Enter(Contained); else cobj->Exit(cobj->GetX(),cobj->GetY()); - SetAction(0); + SetAction(nullptr); } } @@ -1250,8 +1250,8 @@ bool C4Object::Exit(int32_t iX, int32_t iY, int32_t iR, C4Real iXDir, C4Real iYD BoundsCheck(fix_x, fix_y); xdir=iXDir; ydir=iYDir; rdir=iRDir; // Misc updates - Mobile=1; - InLiquid=0; + Mobile=true; + InLiquid=false; CloseMenu(true); UpdateFace(true); SetOCF(); @@ -1347,7 +1347,7 @@ void C4Object::Fling(C4Real txdir, C4Real tydir, bool fAddSpeed) if (!ObjectActionJump(this,txdir,tydir,false)) { xdir=txdir; ydir=tydir; - Mobile=1; + Mobile=true; Action.t_attach&=~CNAT_Bottom; } } @@ -1400,7 +1400,7 @@ bool C4Object::Push(C4Real txdir, C4Real dforce, bool fStraighten) } // Mobilization check - if (!!xdir || !!ydir || !!rdir) Mobile=1; + if (!!xdir || !!ydir || !!rdir) Mobile=true; // Stuck check if (!::Game.iTick35) if (txdir) if (!Def->NoHorizontalMove) @@ -1419,7 +1419,7 @@ bool C4Object::Lift(C4Real tydir, C4Real dforce) if (!Status || !Def || Contained) return false; // Mobilization check if (!Mobile) - { xdir=ydir=Fix0; Mobile=1; } + { xdir=ydir=Fix0; Mobile=true; } // General pushing force vs. object mass dforce=dforce*100/Mass; // If close enough, set tydir @@ -1735,7 +1735,7 @@ bool C4Object::Promote(int32_t torank, bool exception, bool fForceRankName) // call to object Call(PSF_Promotion); - StartSoundEffect("UI::Trumpet",0,100,this); + StartSoundEffect("UI::Trumpet",false,100,this); return true; } @@ -2720,7 +2720,7 @@ bool C4Object::SetAction(C4PropList * Act, C4Object *pTarget, C4Object *pTarget2 // Unfullcon objects no action if (ConIncompleteActivity) - Act = 0; + Act = nullptr; // Reset action time on change if (Act!=LastAction) { @@ -2825,7 +2825,7 @@ bool C4Object::SetActionByName(C4String *ActName, assert(ActName); // If we get the null string or ActIdle by name, set ActIdle if (!ActName || ActName == &Strings.P[P_Idle]) - return SetAction(0,0,0,iCalls,fForce); + return SetAction(nullptr,nullptr,nullptr,iCalls,fForce); C4Value ActMap; GetProperty(P_ActMap, &ActMap); if (!ActMap.getPropList()) return false; C4Value Action; ActMap.getPropList()->GetPropertyByS(ActName, &Action); @@ -2917,7 +2917,7 @@ void C4Object::NoAttachAction() else { DoGravity(this); - Mobile=1; + Mobile=true; } } @@ -3284,15 +3284,15 @@ void C4Object::ExecAction() if (Inside(GetR(),-StableRange,+StableRange)) { Action.t_attach|=Def->UprightAttach; - Mobile=1; + Mobile=true; } C4PropList* pActionDef = GetAction(); // No IncompleteActivity? Reset action if there was one if (!(OCF & OCF_FullCon) && !Def->IncompleteActivity && pActionDef) { - SetAction(0); - pActionDef = 0; + SetAction(nullptr); + pActionDef = nullptr; } // InLiquidAction check @@ -3402,7 +3402,7 @@ void C4Object::ExecAction() iPhaseAdvance=+fixtoi(xdir*10); } - Mobile=1; + Mobile=true; // object is rotateable? adjust to ground, if in horizontal movement or not attached to the center vertex if (Def->Rotateable && Shape.AttachMat != MNone && (!!xdir || Def->Shape.VtxX[Shape.iAttachVtx])) AdjustWalkRotation(20, 20, 100); @@ -3412,7 +3412,7 @@ void C4Object::ExecAction() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case DFA_KNEEL: ydir=0; - Mobile=1; + Mobile=true; break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case DFA_SCALE: @@ -3447,7 +3447,7 @@ void C4Object::ExecAction() if (ydir<0) iPhaseAdvance=-fixtoi(ydir*14); if (ydir>0) iPhaseAdvance=+fixtoi(ydir*14); xdir=0; - Mobile=1; + Mobile=true; break; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3484,7 +3484,7 @@ void C4Object::ExecAction() if (xdir<0) { iPhaseAdvance=-fixtoi(xdir*10); SetDir(DIR_Left); } if (xdir>0) { iPhaseAdvance=+fixtoi(xdir*10); SetDir(DIR_Right); } ydir=0; - Mobile=1; + Mobile=true; break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case DFA_FLIGHT: @@ -3508,7 +3508,7 @@ void C4Object::ExecAction() // Gravity/mobile DoGravity(this); - Mobile=1; + Mobile=true; break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case DFA_DIG: @@ -3525,7 +3525,7 @@ void C4Object::ExecAction() if (xdir < 0) SetDir(DIR_Left); else if (xdir > 0) SetDir(DIR_Right); Action.t_attach=CNAT_None; - Mobile=1; + Mobile=true; break; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3572,12 +3572,12 @@ void C4Object::ExecAction() if (xdir<0) SetDir(DIR_Left); if (xdir>0) SetDir(DIR_Right); iPhaseAdvance=fixtoi(limit*10); - Mobile=1; + Mobile=true; break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case DFA_THROW: - Mobile=1; + Mobile=true; break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case DFA_BRIDGE: @@ -3589,7 +3589,7 @@ void C4Object::ExecAction() case COMD_Right: case COMD_UpRight: SetDir(DIR_Right); break; } ydir=0; xdir=0; - Mobile=1; + Mobile=true; } break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3604,10 +3604,10 @@ void C4Object::ExecAction() switch (Action.ComDir) { case COMD_Left: case COMD_DownLeft: iTXDir=-limit; break; - case COMD_UpLeft: fStraighten=1; iTXDir=-limit; break; + case COMD_UpLeft: fStraighten=true; iTXDir=-limit; break; case COMD_Right: case COMD_DownRight: iTXDir=+limit; break; - case COMD_UpRight: fStraighten=1; iTXDir=+limit; break; - case COMD_Up: fStraighten=1; break; + case COMD_UpRight: fStraighten=true; iTXDir=+limit; break; + case COMD_Up: fStraighten=true; break; case COMD_Stop: case COMD_Down: iTXDir=0; break; } // Push object @@ -3644,7 +3644,7 @@ void C4Object::ExecAction() if (xdir>0) { iPhaseAdvance=+fixtoi(xdir*10); SetDir(DIR_Right); } // No YDir ydir=0; - Mobile=1; + Mobile=true; break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case DFA_PULL: @@ -3720,13 +3720,13 @@ void C4Object::ExecAction() if (xdir>0) { iPhaseAdvance=+fixtoi(xdir*10); SetDir(DIR_Right); } // No YDir ydir=0; - Mobile=1; + Mobile=true; break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case DFA_LIFT: // Valid check - if (!Action.Target) { SetAction(0); return; } + if (!Action.Target) { SetAction(nullptr); return; } // Target lifting force lftspeed=itofix(2); tydir=0; switch (Action.ComDir) @@ -3737,7 +3737,7 @@ void C4Object::ExecAction() } // Lift object if (!Action.Target->Lift(tydir,C4REAL100(50))) - { SetAction(0); return; } + { SetAction(nullptr); return; } // Check LiftTop if (Def->LiftTop) if (Action.Target->GetY()<=(GetY()+Def->LiftTop)) @@ -3799,7 +3799,7 @@ void C4Object::ExecAction() if (xdir>+limit) xdir=+limit; if (xdir<-limit) xdir=-limit; } - Mobile=1; + Mobile=true; break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ATTACH: Force position to target object @@ -3812,7 +3812,7 @@ void C4Object::ExecAction() { if (Status) { - SetAction(0); + SetAction(nullptr); Call(PSF_AttachTargetLost); } return; @@ -3821,7 +3821,7 @@ void C4Object::ExecAction() // Target incomplete and no incomplete activity if (!(Action.Target->OCF & OCF_FullCon)) if (!Action.Target->Def->IncompleteActivity) - { SetAction(0); return; } + { SetAction(nullptr); return; } // Force containment if (Action.Target->Contained!=Contained) @@ -3914,7 +3914,7 @@ void C4Object::ExecAction() // Line fBroke if (fBroke) { - Call(PSF_OnLineBreak,0); + Call(PSF_OnLineBreak,nullptr); AssignRemoval(); return; } @@ -3935,7 +3935,7 @@ void C4Object::ExecAction() if (Action.t_attach) { xdir = ydir = 0; - Mobile = 1; + Mobile = true; } // Free gravity else @@ -4707,13 +4707,13 @@ void C4Object::UpdateInLiquid() { if (OCF & OCF_HitSpeed2) if (Mass>3) Splash(); - InLiquid=1; + InLiquid=true; } } else // Out of liquid { if (InLiquid) // Leave liquid - InLiquid=0; + InLiquid=false; } } diff --git a/src/object/C4ObjectCom.cpp b/src/object/C4ObjectCom.cpp index a9dc06879..d1e923ba2 100644 --- a/src/object/C4ObjectCom.cpp +++ b/src/object/C4ObjectCom.cpp @@ -59,7 +59,7 @@ bool ObjectActionJump(C4Object *cObj, C4Real xdir, C4Real ydir, bool fByCom) // hardcoded jump by action if (!cObj->SetActionByName("Jump")) return false; cObj->xdir=xdir; cObj->ydir=ydir; - cObj->Mobile=1; + cObj->Mobile=true; // unstick from ground, because jump command may be issued in an Action-callback, // where attach-values have already been determined for that frame cObj->Action.t_attach&=~CNAT_Bottom; @@ -70,7 +70,7 @@ bool ObjectActionDive(C4Object *cObj, C4Real xdir, C4Real ydir) { if (!cObj->SetActionByName("Dive")) return false; cObj->xdir=xdir; cObj->ydir=ydir; - cObj->Mobile=1; + cObj->Mobile=true; // unstick from ground, because jump command may be issued in an Action-callback, // where attach-values have already been determined for that frame cObj->Action.t_attach&=~CNAT_Bottom; @@ -407,7 +407,7 @@ bool ObjectComPunch(C4Object *cObj, C4Object *pTarget, int32_t punch) bool ObjectComCancelAttach(C4Object *cObj) { if (cObj->GetProcedure()==DFA_ATTACH) - return cObj->SetAction(0); + return cObj->SetAction(nullptr); return false; } diff --git a/src/object/C4ObjectList.cpp b/src/object/C4ObjectList.cpp index b400df737..5ccb0c87f 100644 --- a/src/object/C4ObjectList.cpp +++ b/src/object/C4ObjectList.cpp @@ -30,12 +30,12 @@ static const C4ObjectLink NULL_LINK = { nullptr, nullptr, nullptr }; -C4ObjectList::C4ObjectList(): FirstIter(0) +C4ObjectList::C4ObjectList(): FirstIter(nullptr) { Default(); } -C4ObjectList::C4ObjectList(const C4ObjectList &List): FirstIter(0) +C4ObjectList::C4ObjectList(const C4ObjectList &List): FirstIter(nullptr) { Default(); Copy(List); diff --git a/src/object/C4ObjectMenu.cpp b/src/object/C4ObjectMenu.cpp index 6a144c0d9..6a4e6caea 100644 --- a/src/object/C4ObjectMenu.cpp +++ b/src/object/C4ObjectMenu.cpp @@ -171,8 +171,8 @@ bool C4ObjectMenu::DoRefillInternal(bool &rfRefilled) fctSymbol.Set(fctSymbol.Surface, 0,0,C4SymbolSize,C4SymbolSize); pObj->Picture2Facet(fctSymbol); // Commands - sprintf(szCommand,"SetCommand(\"Activate\",Object(%d))&&ExecuteCommand()",pObj->Number); - sprintf(szCommand2,"SetCommand(\"Activate\",nil,%d,0,Object(%d),%s)&&ExecuteCommand()",pTarget->Contents.ObjectCount(pDef->id),pTarget->Number,pDef->id.ToString()); + sprintf(szCommand,R"(SetCommand("Activate",Object(%d))&&ExecuteCommand())",pObj->Number); + sprintf(szCommand2,R"(SetCommand("Activate",nil,%d,0,Object(%d),%s)&&ExecuteCommand())",pTarget->Contents.ObjectCount(pDef->id),pTarget->Number,pDef->id.ToString()); // Add menu item Add(szCaption,fctSymbol,szCommand,iCount,pObj,"",pDef->id,szCommand2,true,pObj->GetValue(pTarget, NO_OWNER)); // facet taken over (arrg!) @@ -216,11 +216,11 @@ bool C4ObjectMenu::DoRefillInternal(bool &rfRefilled) fctSymbol.Set(fctSymbol.Surface, 0, 0, C4SymbolSize, C4SymbolSize); pObj->Picture2Facet(fctSymbol); // Primary command: get/activate single object - sprintf(szCommand, "SetCommand(\"%s\", Object(%d)) && ExecuteCommand()", fGet ? "Get" : "Activate", pObj->Number); + sprintf(szCommand, R"(SetCommand("%s", Object(%d)) && ExecuteCommand())", fGet ? "Get" : "Activate", pObj->Number); // Secondary command: get/activate all objects of the chosen type szCommand2[0] = 0; int32_t iAllCount; if ((iAllCount = pTarget->Contents.ObjectCount(pDef->id)) > 1) - sprintf(szCommand2, "SetCommand(\"%s\", nil, %d,0, Object(%d), %s) && ExecuteCommand()", fGet ? "Get" : "Activate", iAllCount, pTarget->Number, pDef->id.ToString()); + sprintf(szCommand2, R"(SetCommand("%s", nil, %d,0, Object(%d), %s) && ExecuteCommand())", fGet ? "Get" : "Activate", iAllCount, pTarget->Number, pDef->id.ToString()); // Add menu item (with object) Add(szCaption, fctSymbol, szCommand, iCount, pObj, "", pDef->id, szCommand2); fctSymbol.Default(); diff --git a/src/object/C4ObjectPtr.cpp b/src/object/C4ObjectPtr.cpp index 32e5505ad..dd4924205 100644 --- a/src/object/C4ObjectPtr.cpp +++ b/src/object/C4ObjectPtr.cpp @@ -22,7 +22,7 @@ #include -const C4ObjectPtr C4ObjectPtr::Null(0); +const C4ObjectPtr C4ObjectPtr::Null(nullptr); void C4ObjectPtr::CompileFunc(StdCompiler* pComp) { diff --git a/src/object/C4ObjectScript.cpp b/src/object/C4ObjectScript.cpp index 8578bcab2..55f4902f1 100644 --- a/src/object/C4ObjectScript.cpp +++ b/src/object/C4ObjectScript.cpp @@ -334,7 +334,7 @@ static void FnSetXDir(C4Object *Obj, long nxdir, long iPrec) if (!iPrec) iPrec=10; // update xdir Obj->xdir=itofix(nxdir, iPrec); - Obj->Mobile=1; + Obj->Mobile=true; } static void FnSetRDir(C4Object *Obj, long nrdir, long iPrec) @@ -343,7 +343,7 @@ static void FnSetRDir(C4Object *Obj, long nrdir, long iPrec) if (!iPrec) iPrec=10; // update rdir Obj->rdir=itofix(nrdir, iPrec); - Obj->Mobile=1; + Obj->Mobile=true; } static void FnSetYDir(C4Object *Obj, long nydir, long iPrec) @@ -352,7 +352,7 @@ static void FnSetYDir(C4Object *Obj, long nydir, long iPrec) if (!iPrec) iPrec=10; // update ydir Obj->ydir=itofix(nydir, iPrec); - Obj->Mobile=1; + Obj->Mobile=true; } static void FnSetR(C4Object *Obj, long nr) @@ -660,7 +660,7 @@ static bool FnSetVertex(C4Object *Obj, long iIndex, long iValueToSet, long iValu if (!Obj->fOwnVertices) { Obj->Shape.CreateOwnOriginalCopy(Obj->Def->Shape); - Obj->fOwnVertices = 1; + Obj->fOwnVertices = true; } // set vertices at end of buffer iIndex += C4D_VertexCpyPos; @@ -887,7 +887,7 @@ static bool FnAddMenuItem(C4Object *Obj, C4String * szCaption, C4String * szComm if (Parameter.getPropList()->GetObject()) sprintf(parameter, "Object(%d)", Parameter.getPropList()->GetObject()->Number); else if (Parameter.getPropList()->GetDef()) - sprintf(parameter, "C4Id(\"%s\")", Parameter.getPropList()->GetDef()->id.ToString()); + sprintf(parameter, R"(C4Id("%s"))", Parameter.getPropList()->GetDef()->id.ToString()); else throw C4AulExecError("proplist as parameter to AddMenuItem"); break; @@ -924,8 +924,8 @@ static bool FnAddMenuItem(C4Object *Obj, C4String * szCaption, C4String * szComm { // Search for "%d" an replace it by "%s" for insertion of formatted parameter SCopy(FnStringPar(szCommand), dummy, 256); - char* pFound = const_cast(SSearch(dummy, "%d")); - if (pFound != 0) + auto* pFound = const_cast(SSearch(dummy, "%d")); + if (pFound != nullptr) *(pFound - 1) = 's'; // Compose left-click command sprintf(command, dummy, parameter, 0); @@ -1045,7 +1045,7 @@ static bool FnAddMenuItem(C4Object *Obj, C4String * szCaption, C4String * szComm { // draw object picture if (!XPar.CheckConversion(C4V_Object)) - throw C4AulExecError(FormatString("call to \"%s\" parameter %d: got \"%s\", but expected \"%s\"!", + throw C4AulExecError(FormatString(R"(call to "%s" parameter %d: got "%s", but expected "%s"!)", "AddMenuItem", 8, XPar.GetTypeName(), GetC4VName(C4V_Object) ).getData()); pGfxObj = XPar.getObj(); diff --git a/src/platform/C4AppSDL.cpp b/src/platform/C4AppSDL.cpp index 97824b8a5..c5c3b0de9 100644 --- a/src/platform/C4AppSDL.cpp +++ b/src/platform/C4AppSDL.cpp @@ -84,9 +84,7 @@ C4AbstractApp::C4AbstractApp(): { } -C4AbstractApp::~C4AbstractApp() -{ -} +C4AbstractApp::~C4AbstractApp() = default; bool C4AbstractApp::Init(int argc, char * argv[]) { @@ -470,5 +468,5 @@ bool C4AbstractApp::IsClipboardFull(bool fClipboard) void C4AbstractApp::MessageDialog(const char * message) { - SDL_ShowSimpleMessageBox(0, C4ENGINECAPTION, message, pWindow ? pWindow->window : 0); + SDL_ShowSimpleMessageBox(0, C4ENGINECAPTION, message, pWindow ? pWindow->window : nullptr); } diff --git a/src/platform/C4AppT.cpp b/src/platform/C4AppT.cpp index b83d1798a..6b0743f29 100644 --- a/src/platform/C4AppT.cpp +++ b/src/platform/C4AppT.cpp @@ -98,15 +98,15 @@ bool C4AbstractApp::FlushMessages() } void C4Window::Clear() {} -C4Window::C4Window() {} -C4Window::~C4Window() {} +C4Window::C4Window() = default; +C4Window::~C4Window() = default; void C4Window::EnumerateMultiSamples(std::vector >&) const {} void C4Window::FlashWindow() {} void C4Window::GrabMouse(bool) {} -bool C4Window::GetSize(C4Rect*) {return 0;} +bool C4Window::GetSize(C4Rect*) {return false;} C4Window* C4Window::Init(C4Window::WindowKind, C4AbstractApp*, char const*, const C4Rect *) {return this;} -bool C4Window::ReInit(C4AbstractApp*) {return 0;} -bool C4Window::RestorePosition(char const*, char const*, bool) {return 0;} +bool C4Window::ReInit(C4AbstractApp*) {return false;} +bool C4Window::RestorePosition(char const*, char const*, bool) {return false;} void C4Window::RequestUpdate() {} void C4Window::SetSize(unsigned int, unsigned int) {} void C4Window::SetTitle(char const*) {} diff --git a/src/platform/C4CrashHandlerWin32.cpp b/src/platform/C4CrashHandlerWin32.cpp index 6a2e0533b..7c25a71ac 100644 --- a/src/platform/C4CrashHandlerWin32.cpp +++ b/src/platform/C4CrashHandlerWin32.cpp @@ -26,12 +26,12 @@ #include "platform/C4windowswrapper.h" #include #include -#include +#include #include #ifdef HAVE_INTTYPES_H -#include +#include #endif -#include +#include #if defined(__CRT_WIDE) || (defined(_MSC_VER) && _MSC_VER >= 1900) #define USE_WIDE_ASSERT #endif @@ -270,7 +270,7 @@ namespace { // Initialize DbgHelp.dll symbol functions SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES); HANDLE process = GetCurrentProcess(); - if (SymInitialize(process, 0, true)) + if (SymInitialize(process, nullptr, true)) { LOG_STATIC_TEXT("\nStack trace:\n"); auto frame = STACKFRAME64(); @@ -300,7 +300,7 @@ namespace { IMAGEHLP_LINE64 *line = reinterpret_cast(SymbolBuffer); static_assert(DumpBufferSize >= sizeof(*line), "IMAGEHLP_LINE64 too large to fit into buffer"); int frame_number = 0; - while (StackWalk64(image_type, process, GetCurrentThread(), &frame, &context, 0, SymFunctionTableAccess64, SymGetModuleBase64, 0)) + while (StackWalk64(image_type, process, GetCurrentThread(), &frame, &context, nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr)) { LOG_DYNAMIC_TEXT("#%3d ", frame_number); module->SizeOfStruct = sizeof(*module); diff --git a/src/platform/C4FileMonitor.cpp b/src/platform/C4FileMonitor.cpp index 0fbaa7f5b..89da347f5 100644 --- a/src/platform/C4FileMonitor.cpp +++ b/src/platform/C4FileMonitor.cpp @@ -93,7 +93,7 @@ bool C4FileMonitor::Execute(int iTimeout, pollfd * pfd) // some other thread void C4FileMonitor::OnThreadEvent(C4InteractiveEventType eEvent, void *pEventData) // main thread { if (eEvent != Ev_FileChange) return; - pCallback((const char *)pEventData, 0); + pCallback((const char *)pEventData, nullptr); } void C4FileMonitor::GetFDs(std::vector & fds) @@ -142,7 +142,7 @@ const DWORD C4FileMonitorNotifies = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_C void C4FileMonitor::AddDirectory(const char *szDir) { // Create file handle - HANDLE hDir = CreateFileW(GetWideChar(szDir), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0); + HANDLE hDir = CreateFileW(GetWideChar(szDir), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, nullptr); if (hDir == INVALID_HANDLE_VALUE) return; // Create tree watch structure TreeWatch *pWatch = new TreeWatch(); @@ -206,7 +206,7 @@ bool C4FileMonitor::Execute(int iTimeout, pollfd *) void C4FileMonitor::OnThreadEvent(C4InteractiveEventType eEvent, void *pEventData) // main thread { if (eEvent != Ev_FileChange) return; - pCallback((const char *)pEventData, 0); + pCallback((const char *)pEventData, nullptr); StdBuf::DeletePointer(pEventData); } diff --git a/src/platform/C4GamePadCon.cpp b/src/platform/C4GamePadCon.cpp index 4576393d0..6e19cf46b 100644 --- a/src/platform/C4GamePadCon.cpp +++ b/src/platform/C4GamePadCon.cpp @@ -262,7 +262,7 @@ void C4GamePadOpener::StopRumble() // Dedicated server and everything else with neither Win32 nor SDL. C4GamePadControl::C4GamePadControl() { Log("WARNING: Engine without Gamepad support"); } -C4GamePadControl::~C4GamePadControl() { } +C4GamePadControl::~C4GamePadControl() = default; void C4GamePadControl::Execute() { } void C4GamePadControl::DoAxisInput() { } int C4GamePadControl::GetGamePadCount() { return 0; } @@ -271,7 +271,7 @@ std::shared_ptr C4GamePadControl::GetGamePadByID(int32_t id) { std::shared_ptr C4GamePadControl::GetAvailableGamePad() { return nullptr; } C4GamePadOpener::C4GamePadOpener(int iGamepad) { } -C4GamePadOpener::~C4GamePadOpener() {} +C4GamePadOpener::~C4GamePadOpener() = default; int32_t C4GamePadOpener::GetID() { return -1; } bool C4GamePadOpener::IsAttached() { return false; } void C4GamePadOpener::PlayRumble(float strength, uint32_t length) { } diff --git a/src/platform/C4MusicFile.cpp b/src/platform/C4MusicFile.cpp index ec2f391f7..5638a434f 100644 --- a/src/platform/C4MusicFile.cpp +++ b/src/platform/C4MusicFile.cpp @@ -177,8 +177,8 @@ C4MusicFileOgg::C4MusicFileOgg() : playing(false), streaming_done(false), loaded(false), channel(0), current_section(0), byte_pos_total(0), volume(1.0f), is_loading_from_file(false), last_source_file_pos(0), last_playback_pos_sec(0), last_interruption_time() { - for (size_t i=0; igetData()); + result.Append(category.getData()); sec = true; } result.AppendChar(']'); @@ -442,8 +442,8 @@ bool C4MusicFileOgg::HasCategory(const char *szcat) const { if (!szcat) return false; // check all stored categories - for (auto i = categories.cbegin(); i != categories.cend(); ++i) - if (WildcardMatch(szcat, i->getData())) + for (const auto & category : categories) + if (WildcardMatch(szcat, category.getData())) return true; return false; } diff --git a/src/platform/C4MusicSystem.cpp b/src/platform/C4MusicSystem.cpp index 6c98b3b07..731066673 100644 --- a/src/platform/C4MusicSystem.cpp +++ b/src/platform/C4MusicSystem.cpp @@ -139,7 +139,7 @@ bool C4MusicSystem::Init(const char * PlayList) LoadMoreMusic(); // set play list SCounter = 0; - if (PlayList) SetPlayList(PlayList); else SetPlayList(0); + if (PlayList) SetPlayList(PlayList); else SetPlayList(nullptr); // set initial volume UpdateVolume(); // ok @@ -183,7 +183,7 @@ bool C4MusicSystem::InitForScenario(C4Group & hGroup) // no music? if (!SongCount) return false; // set play list - SetPlayList(0); + SetPlayList(nullptr); // ok return true; } @@ -414,7 +414,7 @@ bool C4MusicSystem::Play(const char *szSongname, bool fLoop, int fadetime_ms, do // info if (::Config.Sound.Verbose) { - LogF("MusicSystem: Play(\"%s\", %s, %d, %.3lf, %s)", szSongname ? szSongname : "(null)", fLoop ? "true" : "false", fadetime_ms, max_resume_time, allow_break ? "true" : "false"); + LogF(R"(MusicSystem: Play("%s", %s, %d, %.3lf, %s))", szSongname ? szSongname : "(null)", fLoop ? "true" : "false", fadetime_ms, max_resume_time, allow_break ? "true" : "false"); } C4MusicFile* NewFile = nullptr; @@ -560,7 +560,7 @@ bool C4MusicSystem::Play(C4MusicFile *NewFile, bool fLoop, double max_resume_tim // info if (::Config.Sound.Verbose) { - LogF("MusicSystem: PlaySong(\"%s\", %s, %.3lf)", NewFile->GetDebugInfo().getData(), fLoop ? "true" : "false", max_resume_time); + LogF(R"(MusicSystem: PlaySong("%s", %s, %.3lf))", NewFile->GetDebugInfo().getData(), fLoop ? "true" : "false", max_resume_time); } // Play new song directly if (!NewFile->Play(fLoop, max_resume_time)) return false; @@ -693,7 +693,7 @@ int C4MusicSystem::SetPlayList(const char *szPlayList, bool fForceSwitch, int fa // info if (::Config.Sound.Verbose) { - LogF("MusicSystem: SetPlayList(\"%s\", %s, %d, %.3lf)", szPlayList ? szPlayList : "(null)", fForceSwitch ? "true" : "false", fadetime_ms, max_resume_time); + LogF(R"(MusicSystem: SetPlayList("%s", %s, %d, %.3lf))", szPlayList ? szPlayList : "(null)", fForceSwitch ? "true" : "false", fadetime_ms, max_resume_time); } // reset C4MusicFile *pFile; diff --git a/src/platform/C4SoundSystem.cpp b/src/platform/C4SoundSystem.cpp index dec1945ad..3727df8f3 100644 --- a/src/platform/C4SoundSystem.cpp +++ b/src/platform/C4SoundSystem.cpp @@ -35,10 +35,7 @@ C4SoundSystem::C4SoundSystem(): { } -C4SoundSystem::~C4SoundSystem() -{ - -} +C4SoundSystem::~C4SoundSystem() = default; bool C4SoundSystem::Init() { diff --git a/src/platform/C4StdInProc.cpp b/src/platform/C4StdInProc.cpp index 13191fa6b..cddd97b49 100644 --- a/src/platform/C4StdInProc.cpp +++ b/src/platform/C4StdInProc.cpp @@ -59,9 +59,9 @@ bool C4StdInProc::Execute(int iTimeout, pollfd *) #else -C4StdInProc::C4StdInProc() { } +C4StdInProc::C4StdInProc() = default; -C4StdInProc::~C4StdInProc() { } +C4StdInProc::~C4StdInProc() = default; bool C4StdInProc::Execute(int iTimeout, pollfd *) { diff --git a/src/platform/C4TimeMilliseconds.cpp b/src/platform/C4TimeMilliseconds.cpp index ae9a19fe5..c6e20b329 100644 --- a/src/platform/C4TimeMilliseconds.cpp +++ b/src/platform/C4TimeMilliseconds.cpp @@ -69,12 +69,7 @@ StdCopyStrBuf C4TimeMilliseconds::AsString() const return StdCopyStrBuf(string); } -C4TimeMilliseconds& C4TimeMilliseconds::operator=(const C4TimeMilliseconds& rhs) -{ - time = rhs.time; - inf = rhs.inf; - return *this; -} +C4TimeMilliseconds& C4TimeMilliseconds::operator=(const C4TimeMilliseconds& rhs) = default; bool operator==( const C4TimeMilliseconds& lhs, const C4TimeMilliseconds& rhs ) { diff --git a/src/platform/C4WindowSDL.cpp b/src/platform/C4WindowSDL.cpp index b671e0a58..7d4e65104 100644 --- a/src/platform/C4WindowSDL.cpp +++ b/src/platform/C4WindowSDL.cpp @@ -40,7 +40,7 @@ /* C4Window */ C4Window::C4Window (): - Active(false), pSurface(0), eKind(W_Fullscreen), window(nullptr) + Active(false), pSurface(nullptr), eKind(W_Fullscreen), window(nullptr) #ifdef WITH_QT_EDITOR , glwidget(nullptr) #endif @@ -89,7 +89,7 @@ C4Window * C4Window::Init(WindowKind windowKind, C4AbstractApp * pApp, const cha if (!window) { Log(SDL_GetError()); - return 0; + return nullptr; } SDL_SetWindowData(window, "C4Window", this); Active = true; diff --git a/src/platform/C4WindowWin32.cpp b/src/platform/C4WindowWin32.cpp index 6d3ab1499..e913a490b 100644 --- a/src/platform/C4WindowWin32.cpp +++ b/src/platform/C4WindowWin32.cpp @@ -171,7 +171,7 @@ LRESULT APIENTRY FullScreenWinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l { // UTF-8 has 1 to 4 data bytes, and we need a terminating \0 char c[5] = {0,0,0,0,0}; - if(!WideCharToMultiByte(CP_UTF8, 0L, reinterpret_cast(&wParam), 1, c, 4, 0, 0)) + if(!WideCharToMultiByte(CP_UTF8, 0L, reinterpret_cast(&wParam), 1, c, 4, nullptr, nullptr)) return 0; // GUI: forward if (::pGUI->CharIn(c)) @@ -258,11 +258,11 @@ bool ConsoleHandleWin32KeyboardMessage(MSG *msg) if (Game.DoKeyboardInput(msg2scancode(msg), KEYEV_Down, !!(msg->lParam & 0x20000000), GetKeyState(VK_CONTROL) < 0, GetKeyState(VK_SHIFT) < 0, !!(msg->lParam & 0x40000000), nullptr)) return true; break; case WM_KEYUP: - if (Game.DoKeyboardInput(msg2scancode(msg), KEYEV_Up, !!(msg->lParam & 0x20000000), GetKeyState(VK_CONTROL) < 0, GetKeyState(VK_SHIFT) < 0, false, nullptr)) return 0; + if (Game.DoKeyboardInput(msg2scancode(msg), KEYEV_Up, !!(msg->lParam & 0x20000000), GetKeyState(VK_CONTROL) < 0, GetKeyState(VK_SHIFT) < 0, false, nullptr)) return false; break; case WM_SYSKEYDOWN: if (msg->wParam == 18) break; // VK_MENU (Alt) - if (Game.DoKeyboardInput(msg2scancode(msg), KEYEV_Down, !!(msg->lParam & 0x20000000), GetKeyState(VK_CONTROL) < 0, GetKeyState(VK_SHIFT) < 0, !!(msg->lParam & 0x40000000), nullptr)) return 0; + if (Game.DoKeyboardInput(msg2scancode(msg), KEYEV_Down, !!(msg->lParam & 0x20000000), GetKeyState(VK_CONTROL) < 0, GetKeyState(VK_SHIFT) < 0, !!(msg->lParam & 0x40000000), nullptr)) return false; break; } return false; @@ -571,15 +571,13 @@ LRESULT APIENTRY DialogWinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPara return DefWindowProc(hwnd, uMsg, wParam, lParam); } -C4Window::C4Window (): Active(false), pSurface(0), hWindow(0) +C4Window::C4Window (): Active(false), pSurface(nullptr), hWindow(nullptr) #ifdef WITH_QT_EDITOR , glwidget(nullptr) #endif { } -C4Window::~C4Window () -{ -} +C4Window::~C4Window () = default; C4Window * C4Window::Init(C4Window::WindowKind windowKind, C4AbstractApp * pApp, const char * Title, const C4Rect * size) { @@ -702,7 +700,7 @@ C4Window * C4Window::Init(C4Window::WindowKind windowKind, C4AbstractApp * pApp, CW_USEDEFAULT,CW_USEDEFAULT,rtSize.right-rtSize.left,rtSize.bottom-rtSize.top, ::Console.hWindow,nullptr,pApp->GetInstance(),nullptr); renderwnd = hWindow; - return hWindow ? this : 0; + return hWindow ? this : nullptr; } else if (windowKind == W_Control) { @@ -856,9 +854,7 @@ C4AbstractApp::C4AbstractApp() : #endif } -C4AbstractApp::~C4AbstractApp() -{ -} +C4AbstractApp::~C4AbstractApp() = default; bool C4AbstractApp::Init(int argc, char * argv[]) { @@ -890,9 +886,9 @@ bool C4AbstractApp::FlushMessages() void C4AbstractApp::SetLastErrorFromOS() { - LPWSTR buffer = 0; + LPWSTR buffer = nullptr; FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, - 0, ::GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(&buffer), 0, 0); + nullptr, ::GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(&buffer), 0, nullptr); sLastError = WStrToString(buffer); LocalFree(buffer); } @@ -917,7 +913,7 @@ bool C4AbstractApp::GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32 ZeroMemory(&dmode, sizeof(dmode)); dmode.dmSize = sizeof(dmode); StdStrBuf Mon; if (iMonitor) - Mon.Format("\\\\.\\Display%d", iMonitor+1); + Mon.Format(R"(\\.\Display%d)", iMonitor+1); // check if indexed mode exists if (!EnumDisplaySettingsW(Mon.GetWideChar(), iIndex, &dmode)) { @@ -977,7 +973,7 @@ bool C4AbstractApp::SetVideoMode(int iXRes, int iYRes, unsigned int iRefreshRate } StdStrBuf Mon; if (iMonitor) - Mon.Format("\\\\.\\Display%d", iMonitor+1); + Mon.Format(R"(\\.\Display%d)", iMonitor+1); ZeroMemory(&dmode, sizeof(dmode)); dmode.dmSize = sizeof(dmode); @@ -1042,7 +1038,7 @@ bool C4AbstractApp::SetVideoMode(int iXRes, int iYRes, unsigned int iRefreshRate void C4AbstractApp::MessageDialog(const char * message) { - MessageBoxW(0, GetWideChar(message), ADDL(C4ENGINECAPTION), MB_ICONERROR); + MessageBoxW(nullptr, GetWideChar(message), ADDL(C4ENGINECAPTION), MB_ICONERROR); } // Clipboard functions @@ -1054,7 +1050,7 @@ bool C4AbstractApp::Copy(const std::string &text, bool fClipboard) if (!OpenClipboard(pWindow ? pWindow->hWindow : nullptr)) return false; // must empty the global clipboard, so the application clipboard equals the Windows clipboard EmptyClipboard(); - int size = MultiByteToWideChar(CP_UTF8, 0, text.c_str(), text.size() + 1, 0, 0); + int size = MultiByteToWideChar(CP_UTF8, 0, text.c_str(), text.size() + 1, nullptr, 0); HANDLE hglbCopy = GlobalAlloc(GMEM_MOVEABLE, size * sizeof(wchar_t)); if (hglbCopy == nullptr) { CloseClipboard(); return false; } // lock the handle and copy the text to the buffer. diff --git a/src/platform/PlatformAbstraction.cpp b/src/platform/PlatformAbstraction.cpp index 0bd1fbfcb..91dd72a06 100644 --- a/src/platform/PlatformAbstraction.cpp +++ b/src/platform/PlatformAbstraction.cpp @@ -32,13 +32,13 @@ bool EraseItemSafe(const char *szFilename) Filename[SLen(Filename)+1]=0; auto wide_filename = GetWideChar(Filename, true); // wide_filename holds the buffer SHFILEOPSTRUCTW shs; - shs.hwnd=0; + shs.hwnd=nullptr; shs.wFunc=FO_DELETE; shs.pFrom = wide_filename; shs.pTo=nullptr; shs.fFlags=FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT; shs.fAnyOperationsAborted=false; - shs.hNameMappings=0; + shs.hNameMappings=nullptr; shs.lpszProgressTitle=nullptr; auto error = SHFileOperationW(&shs); return !error; @@ -53,7 +53,7 @@ bool IsGermanSystem() bool IsGermanSystem() { - if (strstr(setlocale(LC_MESSAGES, 0), "de")) + if (strstr(setlocale(LC_MESSAGES, nullptr), "de")) return true; else return false; @@ -91,9 +91,9 @@ bool RestartApplication(std::vector parameters) StdStrBuf params; for (auto p : parameters) { - params += "\""; + params += R"(")"; params += p; - params += "\" "; + params += R"(" )"; } intptr_t iError = (intptr_t)::ShellExecute(nullptr, nullptr, buf, params.GetWideChar(), Config.General.ExePath.GetWideChar(), SW_SHOW); if (iError > 32) success = true; diff --git a/src/platform/StdFile.cpp b/src/platform/StdFile.cpp index 9f338c409..a7746a7bb 100644 --- a/src/platform/StdFile.cpp +++ b/src/platform/StdFile.cpp @@ -21,7 +21,7 @@ #include "platform/StdFile.h" #include "lib/StdBuf.h" -#include +#include #ifdef HAVE_IO_H #include #endif @@ -34,9 +34,9 @@ #ifdef _WIN32 #include "platform/C4windowswrapper.h" #endif -#include -#include -#include +#include +#include +#include #include #include #include @@ -45,7 +45,7 @@ /* Path & Filename */ #ifdef _WIN32 -static const char *DirectorySeparators = "/\\"; +static const char *DirectorySeparators = R"(/\)"; #else static const char *DirectorySeparators = "/"; #endif @@ -151,7 +151,7 @@ const char *GetExtension(const char *szFilename) void RealPath(const char *szFilename, char *pFullFilename) { #ifdef _WIN32 - wchar_t *wpath = _wfullpath(0, GetWideChar(szFilename), 0); + wchar_t *wpath = _wfullpath(nullptr, GetWideChar(szFilename), 0); StdStrBuf path(wpath); // I'm pretty sure pFullFilename will always have at least a size of _MAX_PATH, but ughh // This should return a StdStrBuf @@ -421,7 +421,7 @@ void MakeFilenameFromTitle(char *szTitle) else if (static_cast(*szTitle2) > 127) fStrip = true; else - fStrip = (SCharPos(*szTitle2, "!\"'%&/=?+*#:;<>\\.") >= 0); + fStrip = (SCharPos(*szTitle2, R"(!"'%&/=?+*#:;<>\.)") >= 0); if (!fStrip) *szFilename++ = *szTitle2; ++szTitle2; } @@ -614,12 +614,12 @@ const char *GetWorkingDirectory() { #ifdef _WIN32 static StdStrBuf buffer; - wchar_t *widebuf = 0; - DWORD widebufsz = GetCurrentDirectoryW(0, 0); + wchar_t *widebuf = nullptr; + DWORD widebufsz = GetCurrentDirectoryW(0, nullptr); widebuf = new wchar_t[widebufsz]; if (GetCurrentDirectoryW(widebufsz, widebuf) == 0) { delete[] widebuf; - return 0; + return nullptr; } buffer.Take(StdStrBuf(widebuf)); delete[] widebuf; @@ -777,7 +777,7 @@ bool EraseDirectory(const char *szDirName) char path[_MAX_PATH+1]; #ifdef _WIN32 // Get path to directory contents - SCopy(szDirName,path); SAppend("\\*.*",path); + SCopy(szDirName,path); SAppend(R"(\*.*)",path); // Erase subdirectories and files ForEachFile(path,&EraseItem); #else @@ -878,10 +878,10 @@ bool ItemIdentical(const char *szFilename1, const char *szFilename2) struct DirectoryIteratorP { - DirectoryIteratorP() : ref(1) {} + DirectoryIteratorP() {} DirectoryIterator::FileList files; std::string directory; - int ref; + int ref{1}; }; DirectoryIterator::DirectoryIterator() @@ -1015,8 +1015,8 @@ void DirectoryIterator::Read(const char *dirname) #endif // Sort list std::sort(p->files.begin(), p->files.end()); - for (FileList::iterator it = p->files.begin(); it != p->files.end(); ++it) - it->first.insert(0, search_path); // prepend path to all file entries + for (auto & file : p->files) + file.first.insert(0, search_path); // prepend path to all file entries iter = p->files.begin(); p->directory = dirname; } diff --git a/src/platform/StdRegistry.cpp b/src/platform/StdRegistry.cpp index 1dee63fff..f926fae04 100644 --- a/src/platform/StdRegistry.cpp +++ b/src/platform/StdRegistry.cpp @@ -22,7 +22,7 @@ #ifdef _WIN32 #include "platform/C4windowswrapper.h" -#include +#include StdCopyStrBuf GetRegistryString(const char *szSubKey, const char *szValueName) { @@ -254,7 +254,7 @@ StdCompilerConfigWrite::StdCompilerConfigWrite(HKEY hRoot, const char *szPath) { pKey->Name = szPath; pKey->subindex = 0; - pKey->Handle = 0; + pKey->Handle = nullptr; CreateKey(hRoot); } @@ -270,8 +270,8 @@ bool StdCompilerConfigWrite::Name(const char *szName) // Open parent key (if not already done so) CreateKey(); // Push new subkey onto the stack - Key *pnKey = new Key(); - pnKey->Handle = 0; + auto *pnKey = new Key(); + pnKey->Handle = nullptr; pnKey->subindex = 0; if (pKey->LastChildName == szName) pnKey->Name.Format("%s%d", szName, (int)++pKey->subindex); @@ -434,7 +434,7 @@ StdCompilerConfigRead::StdCompilerConfigRead(HKEY hRoot, const char *szPath) if (RegOpenKeyExW(hRoot, GetWideChar(szPath), 0, KEY_READ, &pKey->Handle) != ERROR_SUCCESS) - pKey->Handle = 0; + pKey->Handle = nullptr; } StdCompilerConfigRead::~StdCompilerConfigRead() @@ -462,10 +462,10 @@ bool StdCompilerConfigRead::Name(const char *szName) 0, KEY_READ, &hSubKey) != ERROR_SUCCESS) { - hSubKey = 0; + hSubKey = nullptr; // Try to query value (exists?) if (RegQueryValueExW(pKey->Handle, sName.GetWideChar(), - 0, &dwType, nullptr, nullptr) != ERROR_SUCCESS) + nullptr, &dwType, nullptr, nullptr) != ERROR_SUCCESS) fFound = false; } // Push new subkey on the stack @@ -619,7 +619,7 @@ void StdCompilerConfigRead::String(std::string &str, RawCompileType type) void StdCompilerConfigRead::Raw(void *pData, size_t iSize, RawCompileType eType) { - excCorrupt(0, "Raw values aren't supported for registry compilers!"); + excCorrupt(nullptr, "Raw values aren't supported for registry compilers!"); } void StdCompilerConfigRead::Begin() @@ -645,7 +645,7 @@ uint32_t StdCompilerConfigRead::ReadDWord() // Read uint32_t iVal; DWORD iSize = sizeof(iVal); if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(), - 0, nullptr, + nullptr, nullptr, reinterpret_cast(&iVal), &iSize) != ERROR_SUCCESS) { excNotFound("Could not read value %s!", pKey->Name.getData()); return 0; } @@ -675,7 +675,7 @@ void StdCompilerConfigRead::ReadString() // Get size of string DWORD iSize; if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(), - 0, nullptr, + nullptr, nullptr, nullptr, &iSize) != ERROR_SUCCESS) { @@ -685,7 +685,7 @@ void StdCompilerConfigRead::ReadString() StdBuf Result; Result.SetSize(iSize); // Read if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(), - 0, nullptr, + nullptr, nullptr, reinterpret_cast(Result.getMData()), &iSize) != ERROR_SUCCESS) { diff --git a/src/platform/StdScheduler.cpp b/src/platform/StdScheduler.cpp index acbfeb837..69e2f5f49 100644 --- a/src/platform/StdScheduler.cpp +++ b/src/platform/StdScheduler.cpp @@ -16,10 +16,10 @@ #include "C4Include.h" #include "platform/StdScheduler.h" -#include +#include -#include -#include +#include +#include #include #include diff --git a/src/platform/StdSchedulerPoll.cpp b/src/platform/StdSchedulerPoll.cpp index 31e528a7e..7b26fd3d8 100644 --- a/src/platform/StdSchedulerPoll.cpp +++ b/src/platform/StdSchedulerPoll.cpp @@ -149,7 +149,7 @@ bool StdScheduler::DoScheduleProcs(int iTimeout) auto tProcTick = proc->GetNextTick(tNow); if (tProcTick <= tNow) { - struct pollfd * pfd = 0; + struct pollfd * pfd = nullptr; if (fds_for_proc.find(proc) != fds_for_proc.end()) pfd = &fds[fds_for_proc[proc].first]; if (!proc->Execute(0, pfd)) diff --git a/src/player/C4Achievement.cpp b/src/player/C4Achievement.cpp index b6a3bbec3..f73823902 100644 --- a/src/player/C4Achievement.cpp +++ b/src/player/C4Achievement.cpp @@ -59,8 +59,8 @@ bool C4AchievementGraphics::Init(C4GroupSet &Files) void C4AchievementGraphics::Clear() { - for (auto i = Graphics.begin(); i != Graphics.end(); ++i) - delete i->second; + for (auto & Graphic : Graphics) + delete Graphic.second; Graphics.clear(); idGrp = 0; } diff --git a/src/player/C4Player.cpp b/src/player/C4Player.cpp index 4e20da049..61ecb75ae 100644 --- a/src/player/C4Player.cpp +++ b/src/player/C4Player.cpp @@ -1787,9 +1787,9 @@ void C4Player::HostilitySet::CompileFunc(StdCompiler *pComp) else { pComp->Value(entries); - for (const_iterator it = begin(); it != end(); ++it) + for (auto it : *this) { - int32_t num = (*it)->Number; + int32_t num = it->Number; pComp->Value(num); // Can't use (*it)->Number directly because StdCompiler is dumb about constness } } diff --git a/src/player/C4PlayerList.cpp b/src/player/C4PlayerList.cpp index ca22fa9f5..0e311d9e5 100644 --- a/src/player/C4PlayerList.cpp +++ b/src/player/C4PlayerList.cpp @@ -286,7 +286,7 @@ C4Player* C4PlayerList::Join(const char *szFilename, bool fScenarioInit, int iAt LogF(LoadResStr(fScenarioInit ? "IDS_PRC_JOINPLR" : "IDS_PRC_RECREATE"),pInfo->GetName()); // Too many players - if (1) // replay needs to check, too! + if (true) // replay needs to check, too! if (GetCount()+1>Game.Parameters.MaxPlayers) { LogF(LoadResStr("IDS_PRC_TOOMANYPLRS"),Game.Parameters.MaxPlayers); diff --git a/src/player/C4ScenarioParameters.cpp b/src/player/C4ScenarioParameters.cpp index 839ecfe82..247c93162 100644 --- a/src/player/C4ScenarioParameters.cpp +++ b/src/player/C4ScenarioParameters.cpp @@ -32,9 +32,9 @@ void C4ScenarioParameterDef::Option::CompileFunc(StdCompiler *pComp) const C4ScenarioParameterDef::Option *C4ScenarioParameterDef::GetOptionByValue(int32_t val) const { // search option by value - for (auto i = Options.cbegin(); i != Options.cend(); ++i) - if (i->Value == val) - return &*i; + for (const auto & Option : Options) + if (Option.Value == val) + return &Option; return nullptr; } @@ -90,20 +90,20 @@ void C4ScenarioParameterDefs::RegisterScriptConstants(const C4ScenarioParameters // register constants for all parameters in script engine // old-style: one constant per parameter - for (auto i = Parameters.cbegin(); i != Parameters.cend(); ++i) + for (const auto & Parameter : Parameters) { StdStrBuf constant_name; - constant_name.Format("SCENPAR_%s", i->GetID()); - int32_t constant_value = values.GetValueByID(i->GetID(), i->GetDefault()); + constant_name.Format("SCENPAR_%s", Parameter.GetID()); + int32_t constant_value = values.GetValueByID(Parameter.GetID(), Parameter.GetDefault()); ::ScriptEngine.RegisterGlobalConstant(constant_name.getData(), C4VInt(constant_value)); } // new-style: all constants in a proplist auto scenpar = C4PropList::NewStatic(nullptr, nullptr, &Strings.P[P_SCENPAR]); - for (auto i = Parameters.cbegin(); i != Parameters.cend(); ++i) + for (const auto & Parameter : Parameters) { - int32_t constant_value = values.GetValueByID(i->GetID(), i->GetDefault()); - scenpar->SetPropertyByS(Strings.RegString(StdStrBuf(i->GetID())), C4VInt(constant_value)); + int32_t constant_value = values.GetValueByID(Parameter.GetID(), Parameter.GetDefault()); + scenpar->SetPropertyByS(Strings.RegString(StdStrBuf(Parameter.GetID())), C4VInt(constant_value)); } scenpar->Freeze(); ::ScriptEngine.RegisterGlobalConstant("SCENPAR", C4Value(scenpar)); @@ -117,14 +117,14 @@ void C4ScenarioParameters::Clear() void C4ScenarioParameters::Merge(const C4ScenarioParameters &other) { // Merge lists and keep larger value - for (auto i = other.Parameters.cbegin(); i != other.Parameters.cend(); ++i) + for (const auto & Parameter : other.Parameters) { - auto j = Parameters.find(i->first); + auto j = Parameters.find(Parameter.first); if (j != Parameters.end()) - if (j->second >= i->second) + if (j->second >= Parameter.second) continue; // existing value is same or larger - keep old // update to new value from other list - Parameters[i->first] = i->second; + Parameters[Parameter.first] = Parameter.second; } } @@ -188,18 +188,18 @@ void C4ScenarioParameters::CompileFunc(StdCompiler *pComp) if (pComp->hasNaming()) { // save to INI - for (auto i = Parameters.begin(); i != Parameters.end(); ++i) - pComp->Value(mkNamingAdapt(i->second, i->first.getData())); + for (auto & Parameter : Parameters) + pComp->Value(mkNamingAdapt(Parameter.second, Parameter.first.getData())); } else { // save to binary int32_t name_count=Parameters.size(); pComp->Value(name_count); - for (auto i = Parameters.begin(); i != Parameters.end(); ++i) + for (auto & Parameter : Parameters) { - pComp->Value(const_cast(i->first)); - pComp->Value(i->second); + pComp->Value(const_cast(Parameter.first)); + pComp->Value(Parameter.second); } } } diff --git a/src/script/C4Aul.cpp b/src/script/C4Aul.cpp index 49ecb0634..524d0b2ec 100644 --- a/src/script/C4Aul.cpp +++ b/src/script/C4Aul.cpp @@ -222,7 +222,7 @@ std::list C4AulScriptEngine::GetFunctionNames(C4PropList * p) } delete a; functions.sort(sort_alpha); - if (!functions.empty() && !global_functions.empty()) functions.push_back(0); // separator + if (!functions.empty() && !global_functions.empty()) functions.push_back(nullptr); // separator global_functions.sort(sort_alpha); functions.splice(functions.end(), global_functions); return functions; @@ -237,7 +237,7 @@ int32_t C4AulScriptEngine::CreateUserFile() if ((*i).GetHandle() >= last_handle) last_handle = (*i).GetHandle()+1; // Create new user file - UserFiles.push_back(C4AulUserFile(last_handle)); + UserFiles.emplace_back(last_handle); return last_handle; } @@ -255,10 +255,10 @@ void C4AulScriptEngine::CloseUserFile(int32_t handle) C4AulUserFile *C4AulScriptEngine::GetUserFile(int32_t handle) { // get user file given by handle - for (std::list::iterator i = UserFiles.begin(); i != UserFiles.end(); ++i) - if ((*i).GetHandle() == handle) + for (auto & UserFile : UserFiles) + if (UserFile.GetHandle() == handle) { - return &*i; + return &UserFile; } // not found return nullptr; diff --git a/src/script/C4AulCompiler.cpp b/src/script/C4AulCompiler.cpp index c3c3acee3..631a6f01e 100644 --- a/src/script/C4AulCompiler.cpp +++ b/src/script/C4AulCompiler.cpp @@ -17,8 +17,8 @@ #include "C4Include.h" #include "script/C4AulCompiler.h" -#include -#include +#include +#include #include "script/C4Aul.h" #include "script/C4AulParse.h" @@ -129,17 +129,17 @@ public: PreparseAstVisitor(C4ScriptHost *host, C4ScriptHost *source_host, C4AulScriptFunc *func = nullptr) : target_host(host), host(source_host), Fn(func) {} explicit PreparseAstVisitor(C4AulScriptFunc *func) : Fn(func), target_host(func->pOrgScript), host(target_host) {} - virtual ~PreparseAstVisitor() {} + ~PreparseAstVisitor() override = default; using DefaultRecursiveVisitor::visit; - virtual void visit(const ::aul::ast::RangeLoop *n) override; - virtual void visit(const ::aul::ast::VarDecl *n) override; - virtual void visit(const ::aul::ast::FunctionDecl *n) override; - virtual void visit(const ::aul::ast::CallExpr *n) override; - virtual void visit(const ::aul::ast::ParExpr *n) override; - virtual void visit(const ::aul::ast::AppendtoPragma *n) override; - virtual void visit(const ::aul::ast::IncludePragma *n) override; - virtual void visit(const ::aul::ast::Script *n) override; + void visit(const ::aul::ast::RangeLoop *n) override; + void visit(const ::aul::ast::VarDecl *n) override; + void visit(const ::aul::ast::FunctionDecl *n) override; + void visit(const ::aul::ast::CallExpr *n) override; + void visit(const ::aul::ast::ParExpr *n) override; + void visit(const ::aul::ast::AppendtoPragma *n) override; + void visit(const ::aul::ast::IncludePragma *n) override; + void visit(const ::aul::ast::Script *n) override; }; class C4AulCompiler::CodegenAstVisitor : public ::aul::DefaultRecursiveVisitor @@ -254,38 +254,38 @@ public: CodegenAstVisitor(C4ScriptHost *host, C4ScriptHost *source_host) : target_host(host), host(source_host) {} explicit CodegenAstVisitor(C4AulScriptFunc *func) : Fn(func), target_host(func->pOrgScript), host(target_host) {} - virtual ~CodegenAstVisitor() {} + ~CodegenAstVisitor() override = default; using DefaultRecursiveVisitor::visit; - virtual void visit(const ::aul::ast::Noop *) override; - virtual void visit(const ::aul::ast::StringLit *n) override; - virtual void visit(const ::aul::ast::IntLit *n) override; - virtual void visit(const ::aul::ast::BoolLit *n) override; - virtual void visit(const ::aul::ast::ArrayLit *n) override; - virtual void visit(const ::aul::ast::ProplistLit *n) override; - virtual void visit(const ::aul::ast::NilLit *n) override; - virtual void visit(const ::aul::ast::ThisLit *n) override; - virtual void visit(const ::aul::ast::VarExpr *n) override; - virtual void visit(const ::aul::ast::UnOpExpr *n) override; - virtual void visit(const ::aul::ast::BinOpExpr *n) override; - virtual void visit(const ::aul::ast::AssignmentExpr *n) override; - virtual void visit(const ::aul::ast::SubscriptExpr *n) override; - virtual void visit(const ::aul::ast::SliceExpr *n) override; - virtual void visit(const ::aul::ast::CallExpr *n) override; - virtual void visit(const ::aul::ast::ParExpr *n) override; - virtual void visit(const ::aul::ast::Block *n) override; - virtual void visit(const ::aul::ast::Return *n) override; - virtual void visit(const ::aul::ast::ForLoop *n) override; - virtual void visit(const ::aul::ast::RangeLoop *n) override; - virtual void visit(const ::aul::ast::DoLoop *n) override; - virtual void visit(const ::aul::ast::WhileLoop *n) override; - virtual void visit(const ::aul::ast::Break *n) override; - virtual void visit(const ::aul::ast::Continue *n) override; - virtual void visit(const ::aul::ast::If *n) override; - virtual void visit(const ::aul::ast::VarDecl *n) override; - virtual void visit(const ::aul::ast::FunctionDecl *n) override; - virtual void visit(const ::aul::ast::FunctionExpr *n) override; - virtual void visit(const ::aul::ast::Script *n) override; + void visit(const ::aul::ast::Noop *) override; + void visit(const ::aul::ast::StringLit *n) override; + void visit(const ::aul::ast::IntLit *n) override; + void visit(const ::aul::ast::BoolLit *n) override; + void visit(const ::aul::ast::ArrayLit *n) override; + void visit(const ::aul::ast::ProplistLit *n) override; + void visit(const ::aul::ast::NilLit *n) override; + void visit(const ::aul::ast::ThisLit *n) override; + void visit(const ::aul::ast::VarExpr *n) override; + void visit(const ::aul::ast::UnOpExpr *n) override; + void visit(const ::aul::ast::BinOpExpr *n) override; + void visit(const ::aul::ast::AssignmentExpr *n) override; + void visit(const ::aul::ast::SubscriptExpr *n) override; + void visit(const ::aul::ast::SliceExpr *n) override; + void visit(const ::aul::ast::CallExpr *n) override; + void visit(const ::aul::ast::ParExpr *n) override; + void visit(const ::aul::ast::Block *n) override; + void visit(const ::aul::ast::Return *n) override; + void visit(const ::aul::ast::ForLoop *n) override; + void visit(const ::aul::ast::RangeLoop *n) override; + void visit(const ::aul::ast::DoLoop *n) override; + void visit(const ::aul::ast::WhileLoop *n) override; + void visit(const ::aul::ast::Break *n) override; + void visit(const ::aul::ast::Continue *n) override; + void visit(const ::aul::ast::If *n) override; + void visit(const ::aul::ast::VarDecl *n) override; + void visit(const ::aul::ast::FunctionDecl *n) override; + void visit(const ::aul::ast::FunctionExpr *n) override; + void visit(const ::aul::ast::Script *n) override; template void EmitFunctionCode(const T *n) @@ -335,7 +335,7 @@ private: std::string key; ProplistMagic() = default; - ProplistMagic(bool active, C4PropListStatic *parent, const std::string &key) : active(active), parent(parent), key(key) {} + ProplistMagic(bool active, C4PropListStatic *parent, std::string key) : active(active), parent(parent), key(std::move(key)) {} } proplist_magic; explicit ConstexprEvaluator(C4ScriptHost *host) : host(host) {} @@ -349,7 +349,7 @@ private: { // Typecheck parameter if (!v.CheckParConversion(Type1)) - throw Error(host, host, n, nullptr, "operator \"%s\": got %s, but expected %s", opname, v.GetTypeName(), GetC4VName(Type1)); + throw Error(host, host, n, nullptr, R"(operator "%s": got %s, but expected %s)", opname, v.GetTypeName(), GetC4VName(Type1)); } public: class ExpressionNotConstant : public C4AulParseError @@ -360,21 +360,21 @@ public: }; using AstVisitor::visit; - virtual void visit(const ::aul::ast::StringLit *n) override; - virtual void visit(const ::aul::ast::IntLit *n) override; - virtual void visit(const ::aul::ast::BoolLit *n) override; - virtual void visit(const ::aul::ast::ArrayLit *n) override; - virtual void visit(const ::aul::ast::ProplistLit *n) override; - virtual void visit(const ::aul::ast::NilLit *) override; - virtual void visit(const ::aul::ast::ThisLit *n) override; - virtual void visit(const ::aul::ast::VarExpr *n) override; - virtual void visit(const ::aul::ast::UnOpExpr *n) override; - virtual void visit(const ::aul::ast::BinOpExpr *n) override; - virtual void visit(const ::aul::ast::AssignmentExpr *n) override; - virtual void visit(const ::aul::ast::SubscriptExpr *n) override; - virtual void visit(const ::aul::ast::SliceExpr *n) override; - virtual void visit(const ::aul::ast::CallExpr *n) override; - virtual void visit(const ::aul::ast::FunctionExpr *n) override; + void visit(const ::aul::ast::StringLit *n) override; + void visit(const ::aul::ast::IntLit *n) override; + void visit(const ::aul::ast::BoolLit *n) override; + void visit(const ::aul::ast::ArrayLit *n) override; + void visit(const ::aul::ast::ProplistLit *n) override; + void visit(const ::aul::ast::NilLit *) override; + void visit(const ::aul::ast::ThisLit *n) override; + void visit(const ::aul::ast::VarExpr *n) override; + void visit(const ::aul::ast::UnOpExpr *n) override; + void visit(const ::aul::ast::BinOpExpr *n) override; + void visit(const ::aul::ast::AssignmentExpr *n) override; + void visit(const ::aul::ast::SubscriptExpr *n) override; + void visit(const ::aul::ast::SliceExpr *n) override; + void visit(const ::aul::ast::CallExpr *n) override; + void visit(const ::aul::ast::FunctionExpr *n) override; }; class C4AulCompiler::ConstantResolver : public ::aul::DefaultRecursiveVisitor @@ -405,7 +405,7 @@ public: ConstantResolver r(host); r.visit(script); } - virtual ~ConstantResolver() {} + ~ConstantResolver() override = default; using DefaultRecursiveVisitor::visit; void visit(const ::aul::ast::Script *n) override; @@ -1213,9 +1213,9 @@ void C4AulCompiler::CodegenAstVisitor::visit(const ::aul::ast::CallExpr *n) if (n->callee == C4AUL_DebugBreak) { if (n->context) - throw Error(target_host, host, n, Fn, "\"%s\" can't be called in a different context", cname); + throw Error(target_host, host, n, Fn, R"("%s" can't be called in a different context)", cname); if (!n->args.empty()) - throw Error(target_host, host, n, Fn, "\"%s\" must not have any arguments", cname); + throw Error(target_host, host, n, Fn, R"("%s" must not have any arguments)", cname); AddBCC(n->loc, AB_DEBUG); // Add a pseudo-nil to keep the stack balanced @@ -1229,7 +1229,7 @@ void C4AulCompiler::CodegenAstVisitor::visit(const ::aul::ast::CallExpr *n) // inherited can only be called within the same context if (n->context) { - throw Error(target_host, host, n, Fn, "\"%s\" can't be called in a different context", cname); + throw Error(target_host, host, n, Fn, R"("%s" can't be called in a different context)", cname); } } @@ -1650,7 +1650,7 @@ void C4AulCompiler::CodegenAstVisitor::visit(const ::aul::ast::FunctionDecl *n) Warn(target_host, host, n, Fn, C4AulWarningId::redeclaration, "function", f->GetName()); Fn = f->SFunc(); } - f = f->SFunc() ? f->SFunc()->OwnerOverloaded : 0; + f = f->SFunc() ? f->SFunc()->OwnerOverloaded : nullptr; } if (!Fn && Parent->HasProperty(name)) diff --git a/src/script/C4AulDebug.cpp b/src/script/C4AulDebug.cpp index cd9824be2..ed8a33ec8 100644 --- a/src/script/C4AulDebug.cpp +++ b/src/script/C4AulDebug.cpp @@ -37,8 +37,8 @@ C4AulDebug::C4AulDebug() C4AulDebug::~C4AulDebug() { - for (std::list::iterator it = StackTrace.begin(); it != StackTrace.end(); it++) - {delete *it;} + for (auto & it : StackTrace) + delete it; if (pDebug == this) pDebug = nullptr; } @@ -456,8 +456,8 @@ const char* C4AulDebug::RelativePath(StdStrBuf &path) void C4AulDebug::ObtainStackTrace(C4AulScriptContext* pCtx, C4AulBCC* pCPos) { - for (std::list::iterator it = StackTrace.begin(); it != StackTrace.end(); it++) - {delete *it;} + for (auto & it : StackTrace) + delete it; StackTrace.clear(); for (int ctxNum = pExec->GetContextDepth()-1; ctxNum >= 0; ctxNum--) { diff --git a/src/script/C4AulExec.cpp b/src/script/C4AulExec.cpp index 858609367..558b25531 100644 --- a/src/script/C4AulExec.cpp +++ b/src/script/C4AulExec.cpp @@ -124,7 +124,7 @@ C4String *C4AulExec::FnTranslate(C4PropList * _this, C4String *text) ReturnIfTranslationAvailable(AulExec.pCurCtx[0].Func->pOrgScript, text->GetCStr()); // No translation available, log - DebugLogF("WARNING: Translate: no translation for string \"%s\"", text->GetCStr()); + DebugLogF(R"(WARNING: Translate: no translation for string "%s")", text->GetCStr()); // Trace AulExec.LogCallStack(); return text; @@ -773,7 +773,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos) // Function not found? if (!pFunc) - throw C4AulExecError(FormatString("'->': no function \"%s\" in object \"%s\"", pCPos->Par.s->GetCStr(), pTargetVal->GetDataString().getData()).getData()); + throw C4AulExecError(FormatString(R"('->': no function "%s" in object "%s")", pCPos->Par.s->GetCStr(), pTargetVal->GetDataString().getData()).getData()); // Save current position pCurCtx->CPos = pCPos; @@ -872,9 +872,9 @@ C4AulBCC *C4AulExec::Call(C4AulFunc *pFunc, C4Value *pReturn, C4Value *pPars, C4 sCallText.Append("(Snull)"); else { - sCallText.Append("\""); + sCallText.Append(R"(")"); sCallText.Append(s->GetData()); - sCallText.Append("\""); + sCallText.Append(R"(")"); } } else @@ -1006,9 +1006,8 @@ void C4AulProfiler::Show() Log("Profiler statistics:"); Log("=============================="); typedef std::vector EntryList; - for (EntryList::iterator i = Times.begin(); i!=Times.end(); ++i) + for (auto & e : Times) { - Entry &e = (*i); LogF("%05ums\t%s", e.tProfileTime, e.pFunc ? (e.pFunc->GetFullName().getData()) : "Direct exec"); } Log("=============================="); diff --git a/src/script/C4AulFunc.cpp b/src/script/C4AulFunc.cpp index 08d0f3fbf..3d773794b 100644 --- a/src/script/C4AulFunc.cpp +++ b/src/script/C4AulFunc.cpp @@ -21,7 +21,7 @@ C4AulFunc::C4AulFunc(C4PropListStatic * Parent, const char *pName): Parent(Parent), - Name(pName ? Strings.RegString(pName) : 0), + Name(pName ? Strings.RegString(pName) : nullptr), MapNext(nullptr) { // add to global lookuptable with this name @@ -63,7 +63,7 @@ bool C4AulFunc::CheckParTypes(const C4Value pPars[], bool fPassErrors) const { if (!pPars[i].CheckParConversion(pTypes[i])) { C4AulExecError e(FormatString( - "call to \"%s\" parameter %d: passed %s, but expected %s", + R"(call to "%s" parameter %d: passed %s, but expected %s)", GetName(), i + 1, pPars[i].GetTypeName(), GetC4VName(pTypes[i])).getData()); if (fPassErrors) throw e; diff --git a/src/script/C4AulLink.cpp b/src/script/C4AulLink.cpp index e1615169b..8099cbeab 100644 --- a/src/script/C4AulLink.cpp +++ b/src/script/C4AulLink.cpp @@ -47,11 +47,11 @@ bool C4ScriptHost::ResolveAppends(C4DefList *rDefs) { // resolve local appends if (State != ASS_PREPARSED) return false; - for (std::list::iterator a = Appends.begin(); a != Appends.end(); ++a) + for (auto & Append : Appends) { - if (*a != "*" || !rDefs) + if (Append != "*" || !rDefs) { - C4Def *Def = rDefs ? rDefs->GetByName(*a) : nullptr; + C4Def *Def = rDefs ? rDefs->GetByName(Append) : nullptr; if (Def) { DoAppend(Def); @@ -61,7 +61,7 @@ bool C4ScriptHost::ResolveAppends(C4DefList *rDefs) // save id in buffer because AulWarn will use the buffer of C4IdText // to get the id of the object in which the error occurs... // (stupid static buffers...) - Warn("#appendto %s not found", a->getData()); + Warn("#appendto %s not found", Append.getData()); } } else diff --git a/src/script/C4AulParse.cpp b/src/script/C4AulParse.cpp index c144e9fa4..9c37d94db 100644 --- a/src/script/C4AulParse.cpp +++ b/src/script/C4AulParse.cpp @@ -111,7 +111,7 @@ enum C4AulTokenType : int }; C4AulParse::C4AulParse(C4ScriptHost *a) : - Fn(0), Host(a), pOrgScript(a), Engine(a->Engine), + Fn(nullptr), Host(a), pOrgScript(a), Engine(a->Engine), SPos(a->Script.getData()), TokenSPos(SPos), TokenType(ATT_INVALID), ContextToExecIn(nullptr) @@ -274,50 +274,50 @@ const C4ScriptOpDef C4ScriptOpMap[] = // | | Bytecode | | no second id // | | | | | | RetType ParType1 ParType2 // prefix - { 15, "++", AB_Inc, 0, 1, 0, C4V_Int, C4V_Int, C4V_Any}, - { 15, "--", AB_Dec, 0, 1, 0, C4V_Int, C4V_Int, C4V_Any}, - { 15, "~", AB_BitNot, 0, 0, 0, C4V_Int, C4V_Int, C4V_Any}, - { 15, "!", AB_Not, 0, 0, 0, C4V_Bool, C4V_Bool, C4V_Any}, - { 15, "+", AB_ERR, 0, 0, 0, C4V_Int, C4V_Int, C4V_Any}, - { 15, "-", AB_Neg, 0, 0, 0, C4V_Int, C4V_Int, C4V_Any}, + { 15, "++", AB_Inc, false, true, false, C4V_Int, C4V_Int, C4V_Any}, + { 15, "--", AB_Dec, false, true, false, C4V_Int, C4V_Int, C4V_Any}, + { 15, "~", AB_BitNot, false, false, false, C4V_Int, C4V_Int, C4V_Any}, + { 15, "!", AB_Not, false, false, false, C4V_Bool, C4V_Bool, C4V_Any}, + { 15, "+", AB_ERR, false, false, false, C4V_Int, C4V_Int, C4V_Any}, + { 15, "-", AB_Neg, false, false, false, C4V_Int, C4V_Int, C4V_Any}, // postfix (whithout second statement) - { 16, "++", AB_Inc, 1, 1, 1, C4V_Int, C4V_Int, C4V_Any}, - { 16, "--", AB_Dec, 1, 1, 1, C4V_Int, C4V_Int, C4V_Any}, + { 16, "++", AB_Inc, true, true, true, C4V_Int, C4V_Int, C4V_Any}, + { 16, "--", AB_Dec, true, true, true, C4V_Int, C4V_Int, C4V_Any}, // postfix - { 14, "**", AB_Pow, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int}, - { 13, "/", AB_Div, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int}, - { 13, "*", AB_Mul, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int}, - { 13, "%", AB_Mod, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int}, - { 12, "-", AB_Sub, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int}, - { 12, "+", AB_Sum, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int}, - { 11, "<<", AB_LeftShift, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int}, - { 11, ">>", AB_RightShift, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int}, - { 10, "<", AB_LessThan, 1, 0, 0, C4V_Bool, C4V_Int, C4V_Int}, - { 10, "<=", AB_LessThanEqual, 1, 0, 0, C4V_Bool, C4V_Int, C4V_Int}, - { 10, ">", AB_GreaterThan, 1, 0, 0, C4V_Bool, C4V_Int, C4V_Int}, - { 10, ">=", AB_GreaterThanEqual, 1, 0, 0, C4V_Bool, C4V_Int, C4V_Int}, - { 9, "==", AB_Equal, 1, 0, 0, C4V_Bool, C4V_Any, C4V_Any}, - { 9, "!=", AB_NotEqual, 1, 0, 0, C4V_Bool, C4V_Any, C4V_Any}, - { 8, "&", AB_BitAnd, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int}, - { 6, "^", AB_BitXOr, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int}, - { 6, "|", AB_BitOr, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int}, - { 5, "&&", AB_JUMPAND, 1, 0, 0, C4V_Bool, C4V_Bool, C4V_Bool}, - { 4, "||", AB_JUMPOR, 1, 0, 0, C4V_Bool, C4V_Bool, C4V_Bool}, - { 3, "??", AB_JUMPNNIL, 1, 0, 0, C4V_Any, C4V_Any, C4V_Any}, + { 14, "**", AB_Pow, true, false, false, C4V_Int, C4V_Int, C4V_Int}, + { 13, "/", AB_Div, true, false, false, C4V_Int, C4V_Int, C4V_Int}, + { 13, "*", AB_Mul, true, false, false, C4V_Int, C4V_Int, C4V_Int}, + { 13, "%", AB_Mod, true, false, false, C4V_Int, C4V_Int, C4V_Int}, + { 12, "-", AB_Sub, true, false, false, C4V_Int, C4V_Int, C4V_Int}, + { 12, "+", AB_Sum, true, false, false, C4V_Int, C4V_Int, C4V_Int}, + { 11, "<<", AB_LeftShift, true, false, false, C4V_Int, C4V_Int, C4V_Int}, + { 11, ">>", AB_RightShift, true, false, false, C4V_Int, C4V_Int, C4V_Int}, + { 10, "<", AB_LessThan, true, false, false, C4V_Bool, C4V_Int, C4V_Int}, + { 10, "<=", AB_LessThanEqual, true, false, false, C4V_Bool, C4V_Int, C4V_Int}, + { 10, ">", AB_GreaterThan, true, false, false, C4V_Bool, C4V_Int, C4V_Int}, + { 10, ">=", AB_GreaterThanEqual, true, false, false, C4V_Bool, C4V_Int, C4V_Int}, + { 9, "==", AB_Equal, true, false, false, C4V_Bool, C4V_Any, C4V_Any}, + { 9, "!=", AB_NotEqual, true, false, false, C4V_Bool, C4V_Any, C4V_Any}, + { 8, "&", AB_BitAnd, true, false, false, C4V_Int, C4V_Int, C4V_Int}, + { 6, "^", AB_BitXOr, true, false, false, C4V_Int, C4V_Int, C4V_Int}, + { 6, "|", AB_BitOr, true, false, false, C4V_Int, C4V_Int, C4V_Int}, + { 5, "&&", AB_JUMPAND, true, false, false, C4V_Bool, C4V_Bool, C4V_Bool}, + { 4, "||", AB_JUMPOR, true, false, false, C4V_Bool, C4V_Bool, C4V_Bool}, + { 3, "??", AB_JUMPNNIL, true, false, false, C4V_Any, C4V_Any, C4V_Any}, // changers - { 2, "*=", AB_Mul, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int}, - { 2, "/=", AB_Div, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int}, - { 2, "%=", AB_Mod, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int}, - { 2, "+=", AB_Sum, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int}, - { 2, "-=", AB_Sub, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int}, - { 2, "&=", AB_BitAnd, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int}, - { 2, "|=", AB_BitOr, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int}, - { 2, "^=", AB_BitXOr, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int}, + { 2, "*=", AB_Mul, true, true, false, C4V_Int, C4V_Int, C4V_Int}, + { 2, "/=", AB_Div, true, true, false, C4V_Int, C4V_Int, C4V_Int}, + { 2, "%=", AB_Mod, true, true, false, C4V_Int, C4V_Int, C4V_Int}, + { 2, "+=", AB_Sum, true, true, false, C4V_Int, C4V_Int, C4V_Int}, + { 2, "-=", AB_Sub, true, true, false, C4V_Int, C4V_Int, C4V_Int}, + { 2, "&=", AB_BitAnd, true, true, false, C4V_Int, C4V_Int, C4V_Int}, + { 2, "|=", AB_BitOr, true, true, false, C4V_Int, C4V_Int, C4V_Int}, + { 2, "^=", AB_BitXOr, true, true, false, C4V_Int, C4V_Int, C4V_Int}, - { 0, nullptr, AB_ERR, 0, 0, 0, C4V_Nil, C4V_Nil, C4V_Nil} + { 0, nullptr, AB_ERR, false, false, false, C4V_Nil, C4V_Nil, C4V_Nil} }; int C4AulParse::GetOperator(const char* pScript) @@ -523,7 +523,7 @@ C4AulTokenType C4AulParse::GetNextToken() if (C >= '!' && C <= '~') throw C4AulParseError(this, FormatString("unexpected character '%c' found", C).getData()); else - throw C4AulParseError(this, FormatString("unexpected character \\x%x found", (int)(unsigned char) C).getData()); + throw C4AulParseError(this, FormatString(R"(unexpected character \x%x found)", (int)(unsigned char) C).getData()); } } @@ -645,20 +645,20 @@ void C4AulScriptFunc::DumpByteCode() { switch (c) { - case '\'': es.append("\\'"); break; - case '\"': es.append("\\\""); break; - case '\\': es.append("\\\\"); break; - case '\a': es.append("\\a"); break; - case '\b': es.append("\\b"); break; - case '\f': es.append("\\f"); break; - case '\n': es.append("\\n"); break; - case '\r': es.append("\\r"); break; - case '\t': es.append("\\t"); break; - case '\v': es.append("\\v"); break; + case '\'': es.append(R"(\')"); break; + case '\"': es.append(R"(\")"); break; + case '\\': es.append(R"(\\)"); break; + case '\a': es.append(R"(\a)"); break; + case '\b': es.append(R"(\b)"); break; + case '\f': es.append(R"(\f)"); break; + case '\n': es.append(R"(\n)"); break; + case '\r': es.append(R"(\r)"); break; + case '\t': es.append(R"(\t)"); break; + case '\v': es.append(R"(\v)"); break; default: { std::stringstream hex; - hex << "\\x" << std::hex << std::setw(2) << std::setfill('0') << static_cast((unsigned char)c); + hex << R"(\x)" << std::hex << std::setw(2) << std::setfill('0') << static_cast((unsigned char)c); es.append(hex.str()); break; } @@ -1381,7 +1381,7 @@ std::unique_ptr<::aul::ast::Expr> C4AulParse::Parse_Expression(int iParentPrio) const char *NodeStart = TokenSPos; std::unique_ptr<::aul::ast::Expr> expr; const C4ScriptOpDef * op; - C4AulFunc *FoundFn = 0; + C4AulFunc *FoundFn = nullptr; C4Value val; switch (TokenType) { @@ -1529,7 +1529,7 @@ std::unique_ptr<::aul::ast::Expr> C4AulParse::Parse_Expression(int iParentPrio) assert(expr); - while (1) + while (true) { NodeStart = TokenSPos; switch (TokenType) @@ -1668,7 +1668,7 @@ std::unique_ptr<::aul::ast::VarDecl> C4AulParse::Parse_Var() decl->constant = true; Shift(); } - while (1) + while (true) { // get desired variable name Check(ATT_IDTF, "variable name"); @@ -1750,14 +1750,14 @@ bool C4ScriptHost::Parse() C4PropListStatic * p = GetPropList(); - for (std::list::iterator s = SourceScripts.begin(); s != SourceScripts.end(); ++s) + for (auto & SourceScript : SourceScripts) { - CopyPropList((*s)->LocalValues, p); - if (*s == this) + CopyPropList(SourceScript->LocalValues, p); + if (SourceScript == this) continue; // definition appends - if (GetPropList() && GetPropList()->GetDef() && (*s)->GetPropList() && (*s)->GetPropList()->GetDef()) - GetPropList()->GetDef()->IncludeDefinition((*s)->GetPropList()->GetDef()); + if (GetPropList() && GetPropList()->GetDef() && SourceScript->GetPropList() && SourceScript->GetPropList()->GetDef()) + GetPropList()->GetDef()->IncludeDefinition(SourceScript->GetPropList()->GetDef()); } // generate bytecode diff --git a/src/script/C4AulScriptFunc.cpp b/src/script/C4AulScriptFunc.cpp index 88d6ca151..4bfc59a99 100644 --- a/src/script/C4AulScriptFunc.cpp +++ b/src/script/C4AulScriptFunc.cpp @@ -27,7 +27,7 @@ C4AulScriptFunc::C4AulScriptFunc(C4PropListStatic * Parent, C4ScriptHost *pOrgSc pOrgScript(pOrgScript), tProfileTime(0) { - for (int i = 0; i < C4AUL_MAX_Par; i++) ParType[i] = C4V_Any; + for (auto & i : ParType) i = C4V_Any; AddBCC(AB_EOFN); } diff --git a/src/script/C4Effect.cpp b/src/script/C4Effect.cpp index feaa2fef7..96d06c953 100644 --- a/src/script/C4Effect.cpp +++ b/src/script/C4Effect.cpp @@ -118,7 +118,7 @@ C4Effect * C4Effect::Init(C4PropList *pForObj, int32_t iPrio, const C4Value &rVa // or added to an effect that destroyed itself (iResult = -2) if (pEffect2 != (C4Effect*)C4Fx_Effect_Deny && pEffect2 != (C4Effect*)C4Fx_Effect_Annul) return pEffect2; // effect is still marked dead - return 0; + return nullptr; } } // init effect @@ -131,7 +131,7 @@ C4Effect * C4Effect::Init(C4PropList *pForObj, int32_t iPrio, const C4Value &rVa if (!GetCallbackScript()) { Call(P_Construction, &C4AulParSet(rVal1, rVal2, rVal3, rVal4)).getInt(); - if (pForObj && !pForObj->Status) return 0; + if (pForObj && !pForObj->Status) return nullptr; pFn = GetFunc(P_Start); } else @@ -139,14 +139,14 @@ C4Effect * C4Effect::Init(C4PropList *pForObj, int32_t iPrio, const C4Value &rVa if (fRemoveUpper && pNext && pFn) TempRemoveUpperEffects(false, &pLastRemovedEffect); // bad things may happen - if (pForObj && !pForObj->Status) return 0; // this will be invalid! + if (pForObj && !pForObj->Status) return nullptr; // this will be invalid! iPriority = iPrio; // validate effect now if (CallStart(0, rVal1, rVal2, rVal3, rVal4) == C4Fx_Start_Deny) // the effect denied to start: assume it hasn't, and mark it dead SetDead(); if (fRemoveUpper && pNext && pFn) TempReaddUpperEffects(pLastRemovedEffect); - if (pForObj && !pForObj->Status) return 0; // this will be invalid! + if (pForObj && !pForObj->Status) return nullptr; // this will be invalid! // Update OnFire cache if (!IsDead() && pForObj && WildcardMatch(C4Fx_AnyFire, GetName())) pForObj->SetOnFire(true); @@ -249,7 +249,7 @@ int32_t C4Effect::GetCount(const char *szMask, int32_t iMaxPriority) C4Effect* C4Effect::Check(const char *szCheckEffect, int32_t iPrio, int32_t iTimer, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4) { // priority=1: always OK; no callbacks - if (iPrio == 1) return 0; + if (iPrio == 1) return nullptr; // check this and other effects C4Effect *pAddToEffect = nullptr; bool fDoTempCallsForAdd = false; C4Effect *pLastRemovedEffect=nullptr; @@ -291,7 +291,7 @@ C4Effect* C4Effect::Check(const char *szCheckEffect, int32_t iPrio, int32_t iTim return pAddToEffect; } // added to no effect and not denied - return 0; + return nullptr; } void C4Effect::Execute(C4Effect **ppEffectList) diff --git a/src/script/C4PropList.cpp b/src/script/C4PropList.cpp index 797246377..3b5d2da69 100644 --- a/src/script/C4PropList.cpp +++ b/src/script/C4PropList.cpp @@ -123,8 +123,8 @@ void C4PropListNumbered::ShelveNumberedPropLists() void C4PropListNumbered::UnshelveNumberedPropLists() { // re-insert shelved proplists into main list and give them a number - for (std::vector::iterator i=ShelvedPropLists.begin(); i!=ShelvedPropLists.end(); ++i) - (*i)->AcquireNumber(); + for (auto & ShelvedPropList : ShelvedPropLists) + ShelvedPropList->AcquireNumber(); ShelvedPropLists.clear(); } @@ -365,7 +365,7 @@ C4PropList::~C4PropList() while (FirstRef) { // Manually kill references so DelRef doesn't destroy us again - FirstRef->Data = 0; FirstRef->Type = C4V_Nil; + FirstRef->Data = nullptr; FirstRef->Type = C4V_Nil; C4Value *ref = FirstRef; FirstRef = FirstRef->NextRef; ref->NextRef = nullptr; @@ -644,25 +644,25 @@ void C4PropList::SetName(const char* NewName) C4Object * C4PropList::GetObject() { if (GetPrototype()) return GetPrototype()->GetObject(); - return 0; + return nullptr; } C4Object const * C4PropList::GetObject() const { if (GetPrototype()) return GetPrototype()->GetObject(); - return 0; + return nullptr; } C4Def * C4PropList::GetDef() { if (GetPrototype()) return GetPrototype()->GetDef(); - return 0; + return nullptr; } C4Def const * C4PropList::GetDef() const { if (GetPrototype()) return GetPrototype()->GetDef(); - return 0; + return nullptr; } class C4MapScriptLayer * C4PropList::GetMapScriptLayer() @@ -680,13 +680,13 @@ class C4MapScriptMap * C4PropList::GetMapScriptMap() C4PropListNumbered * C4PropList::GetPropListNumbered() { if (GetPrototype()) return GetPrototype()->GetPropListNumbered(); - return 0; + return nullptr; } C4Effect * C4PropList::GetEffect() { if (GetPrototype()) return GetPrototype()->GetEffect(); - return 0; + return nullptr; } template<> template<> @@ -760,7 +760,7 @@ C4String * C4PropList::GetPropertyStr(C4PropertyName n) const { return GetPrototype()->GetPropertyStr(n); } - return 0; + return nullptr; } C4ValueArray * C4PropList::GetPropertyArray(C4PropertyName n) const @@ -774,7 +774,7 @@ C4ValueArray * C4PropList::GetPropertyArray(C4PropertyName n) const { return GetPrototype()->GetPropertyArray(n); } - return 0; + return nullptr; } C4AulFunc * C4PropList::GetFunc(C4String * k) const @@ -788,7 +788,7 @@ C4AulFunc * C4PropList::GetFunc(C4String * k) const { return GetPrototype()->GetFunc(k); } - return 0; + return nullptr; } C4AulFunc * C4PropList::GetFunc(const char * s) const @@ -798,7 +798,7 @@ C4AulFunc * C4PropList::GetFunc(const char * s) const C4String * k = Strings.FindString(s); // this string is entirely unused if (!k) - return 0; + return nullptr; return GetFunc(k); } @@ -923,7 +923,7 @@ C4String * C4PropList::EnumerateOwnFuncs(C4String * prev) const return p->Key; p = Properties.Next(p); } - return 0; + return nullptr; } void C4PropList::SetPropertyByS(C4String * k, const C4Value & to) diff --git a/src/script/C4Script.cpp b/src/script/C4Script.cpp index d0cb693bf..4691bbab6 100644 --- a/src/script/C4Script.cpp +++ b/src/script/C4Script.cpp @@ -115,9 +115,7 @@ C4AulDefFunc::C4AulDefFunc(C4PropListStatic * Parent, C4ScriptFnDef* pDef): Parent->SetPropertyByS(Name, C4VFunction(this)); } -C4AulDefFunc::~C4AulDefFunc() -{ -} +C4AulDefFunc::~C4AulDefFunc() = default; C4Value C4AulDefFunc::Exec(C4PropList * p, C4Value pPars[], bool fPassErrors) { @@ -413,14 +411,14 @@ static bool FnRemoveEffect(C4PropList * _this, C4String *psEffectName, C4PropLis { pEffect = *FnGetEffectsFor(pTarget); // the object has no effects attached, nothing to look for - if (!pEffect) return 0; + if (!pEffect) return false; // name/wildcard given: find effect by name if (szEffect && *szEffect) pEffect = pEffect->Get(szEffect, 0); } // neither passed nor found - nothing to remove! - if (!pEffect) return 0; + if (!pEffect) return false; // kill it if (fDoNoCalls) @@ -457,7 +455,7 @@ static long FnGetEffectCount(C4PropList * _this, C4String *psEffectName, C4PropL C4Effect *pEffect = *FnGetEffectsFor(pTarget); if (!pEffect) return false; // count effects - if (!*szEffect) szEffect = 0; + if (!*szEffect) szEffect = nullptr; return pEffect->GetCount(szEffect, iMaxPriority); } @@ -465,7 +463,7 @@ static C4Value FnEffectCall(C4PropList * _this, C4Value * Pars) { // evaluate parameters C4PropList *pTarget = Pars[0].getPropList(); - C4Effect * pEffect = Pars[1].getPropList() ? Pars[1].getPropList()->GetEffect() : 0; + C4Effect * pEffect = Pars[1].getPropList() ? Pars[1].getPropList()->GetEffect() : nullptr; const char *szCallFn = FnStringPar(Pars[2].getStr()); // safety if (pTarget && !pTarget->Status) return C4Value(); @@ -1133,14 +1131,14 @@ C4ScriptConstDef C4ScriptConstMap[]= C4ScriptFnDef C4ScriptFnMap[]= { - { "Call", 1, C4V_Any, { C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnCall }, - { "EffectCall", 1, C4V_Any, { C4V_Object ,C4V_PropList,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnEffectCall }, - { "Log", 1, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnLog }, - { "DebugLog", 1, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnDebugLog }, - { "Format", 1, C4V_String, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnFormat }, - { "Trans_Mul", 1, C4V_Array, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnTrans_Mul}, + { "Call", true, C4V_Any, { C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnCall }, + { "EffectCall", true, C4V_Any, { C4V_Object ,C4V_PropList,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnEffectCall }, + { "Log", true, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnLog }, + { "DebugLog", true, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnDebugLog }, + { "Format", true, C4V_String, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnFormat }, + { "Trans_Mul", true, C4V_Array, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnTrans_Mul}, - { nullptr, 0, C4V_Nil, { C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil}, 0 } + { nullptr, false, C4V_Nil, { C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil}, nullptr } }; void InitCoreFunctionMap(C4AulScriptEngine *pEngine) diff --git a/src/script/C4ScriptHost.cpp b/src/script/C4ScriptHost.cpp index a120dc623..e00be37fc 100644 --- a/src/script/C4ScriptHost.cpp +++ b/src/script/C4ScriptHost.cpp @@ -37,7 +37,7 @@ C4ScriptHost::C4ScriptHost(): State(ASS_NONE) // not compiled { Script = nullptr; - stringTable = 0; + stringTable = nullptr; SourceScripts.push_back(this); // prepare include list IncludesResolved = false; @@ -334,7 +334,7 @@ public: C4PropList * proto = C4PropList::NewStatic(ScriptEngine.GetPropList(), this, &::Strings.P[P_Prototype]); C4PropListStatic::SetPropertyByS(&::Strings.P[P_Prototype], C4VPropList(proto)); } - virtual void SetPropertyByS(C4String * k, const C4Value & to) + void SetPropertyByS(C4String * k, const C4Value & to) override { if (k == &Strings.P[P_Prototype]) { @@ -348,7 +348,7 @@ public: /*--- C4GameScriptHost ---*/ C4GameScriptHost::C4GameScriptHost(): ScenPrototype(0), ScenPropList(0) { } -C4GameScriptHost::~C4GameScriptHost() { } +C4GameScriptHost::~C4GameScriptHost() = default; bool C4GameScriptHost::Load(C4Group & g, const char * f, const char * l, C4LangStringTable * t) { @@ -383,7 +383,7 @@ void C4GameScriptHost::Clear() C4PropListStatic * C4GameScriptHost::GetPropList() { C4PropList * p = ScenPrototype._getPropList(); - return p ? p->IsStatic() : 0; + return p ? p->IsStatic() : nullptr; } void C4GameScriptHost::Denumerate(C4ValueNumbers * numbers) diff --git a/src/script/C4ScriptMain.cpp b/src/script/C4ScriptMain.cpp index 3c3c7fe11..96fd4e946 100644 --- a/src/script/C4ScriptMain.cpp +++ b/src/script/C4ScriptMain.cpp @@ -17,8 +17,8 @@ // c4script.h is useable without that. #include "../../include/c4script/c4script.h" -#include -#include +#include +#include #include int usage(const char *argv0) @@ -35,13 +35,13 @@ int main(int argc, char *argv[]) bool check = false; char *runstring = nullptr; - while (1) + while (true) { static option long_options[] = { - {"check", no_argument, 0, 'c'}, - {"execute", required_argument, 0, 'e'}, - {0, 0, 0, 0} + {"check", no_argument, nullptr, 'c'}, + {"execute", required_argument, nullptr, 'e'}, + {nullptr, 0, nullptr, 0} }; int option_index; diff --git a/src/script/C4ScriptStandalone.cpp b/src/script/C4ScriptStandalone.cpp index 3ee70085b..75d5ff907 100644 --- a/src/script/C4ScriptStandalone.cpp +++ b/src/script/C4ScriptStandalone.cpp @@ -25,7 +25,7 @@ /* StandaloneStubs.cpp is shared with mape, which has a real implementation of these */ C4Def* C4DefList::GetByName(const StdStrBuf &) {return nullptr;} -C4Def * C4DefList::GetDef(int) {return 0;} +C4Def * C4DefList::GetDef(int) {return nullptr;} int C4DefList::GetDefCount() {return 0;} void C4DefList::SortByPriority() {} void C4DefList::CallEveryDefinition() {} diff --git a/src/script/C4ScriptStandaloneStubs.cpp b/src/script/C4ScriptStandaloneStubs.cpp index 426254617..6ba56ff85 100644 --- a/src/script/C4ScriptStandaloneStubs.cpp +++ b/src/script/C4ScriptStandaloneStubs.cpp @@ -49,8 +49,8 @@ C4Effect ** FnGetEffectsFor(C4PropList * pTarget) /* Stubs */ C4Config Config; -C4Config::C4Config() {} -C4Config::~C4Config() {} +C4Config::C4Config() = default; +C4Config::~C4Config() = default; const char * C4Config::AtRelativePath(char const*s) {return s;} C4AulDebug *C4AulDebug::pDebug; diff --git a/src/script/C4StringTable.cpp b/src/script/C4StringTable.cpp index f47c77268..cf1e728f4 100644 --- a/src/script/C4StringTable.cpp +++ b/src/script/C4StringTable.cpp @@ -48,9 +48,7 @@ C4String::C4String(StdStrBuf strString) Strings.Set.Add(this); } -C4String::C4String() -{ -} +C4String::C4String() = default; C4String::~C4String() { @@ -327,10 +325,10 @@ C4StringTable::C4StringTable() P[DFA_CONNECT] = "CONNECT"; P[DFA_PULL] = "PULL"; // Prevent the individual strings from being deleted, they are not created with new - for (unsigned int i = 0; i < P_LAST; ++i) + for (auto & i : P) { - assert(P[i].GetCStr()); // all strings should be assigned - P[i].IncRef(); + assert(i.GetCStr()); // all strings should be assigned + i.IncRef(); } } diff --git a/src/script/C4Value.cpp b/src/script/C4Value.cpp index bd663c0bd..7caccf4f1 100644 --- a/src/script/C4Value.cpp +++ b/src/script/C4Value.cpp @@ -158,7 +158,7 @@ StdStrBuf C4Value::GetDataString(int depth, const C4PropListStatic *ignore_refer return DataString; } case C4V_String: - return (Data.Str && Data.Str->GetCStr()) ? FormatString("\"%s\"", Data.Str->GetCStr()) : StdStrBuf("(nullstring)"); + return (Data.Str && Data.Str->GetCStr()) ? FormatString(R"("%s")", Data.Str->GetCStr()) : StdStrBuf("(nullstring)"); case C4V_Array: { if (depth <= 0 && Data.Array->GetSize()) @@ -210,8 +210,8 @@ StdStrBuf C4Value::ToJSON(int depth, const C4PropListStatic *ignore_reference_pa { StdStrBuf str = Data.Str->GetData(); str.EscapeString(); - str.Replace("\n", "\\n"); - return FormatString("\"%s\"", str.getData()); + str.Replace("\n", R"(\n)"); + return FormatString(R"("%s")", str.getData()); } else { @@ -282,8 +282,8 @@ void C4Value::Denumerate(class C4ValueNumbers * numbers) void C4ValueNumbers::Denumerate() { - for (std::vector::iterator i = LoadedValues.begin(); i != LoadedValues.end(); ++i) - i->Denumerate(this); + for (auto & LoadedValue : LoadedValues) + LoadedValue.Denumerate(this); } uint32_t C4ValueNumbers::GetNumberForValue(C4Value * v) @@ -508,7 +508,7 @@ void C4ValueNumbers::CompileFunc(StdCompiler * pComp) // Read entries try { - LoadedValues.push_back(C4Value()); + LoadedValues.emplace_back(); CompileValue(pComp, &LoadedValues.back()); } catch (StdCompiler::NotFoundException *pEx) diff --git a/src/script/C4ValueMap.cpp b/src/script/C4ValueMap.cpp index 3773c091a..7eefeb1cc 100644 --- a/src/script/C4ValueMap.cpp +++ b/src/script/C4ValueMap.cpp @@ -22,13 +22,13 @@ // *** C4ValueMapData *** C4ValueMapData::C4ValueMapData() - : pData(0), pNames(0), bTempNameList(false), pNext(0) + : pData(nullptr), pNames(nullptr), bTempNameList(false), pNext(nullptr) { } C4ValueMapData::C4ValueMapData(const C4ValueMapData &DataToCopy) - : pData(0), pNames(0), bTempNameList(false), pNext(0) + : pData(nullptr), pNames(nullptr), bTempNameList(false), pNext(nullptr) { SetNameList(DataToCopy.pNames); if (pNames) for (int32_t i = 0; i < pNames->iSize; i++) @@ -62,10 +62,10 @@ void C4ValueMapData::Reset() { // unreg from name list (if using one) if (pNames) UnRegister(); - pNames = 0; + pNames = nullptr; // free data delete[] pData; - pData = 0; + pData = nullptr; } void C4ValueMapData::ResetContent() @@ -76,7 +76,7 @@ void C4ValueMapData::ResetContent() else { delete[] pData; - pData = 0; + pData = nullptr; } } @@ -145,7 +145,7 @@ void C4ValueMapData::UnRegister() // delete data array delete[] pData; - pData = 0; + pData = nullptr; } C4ValueMapNames *C4ValueMapData::CreateTempNameList() @@ -160,7 +160,7 @@ C4ValueMapNames *C4ValueMapData::CreateTempNameList() if (pNames != pTempNames) { delete pTempNames; - return 0; + return nullptr; } // set flag @@ -230,9 +230,9 @@ C4Value *C4ValueMapData::GetItem(int32_t iNr) assert(iNr < pNames->iSize); assert(iNr >= 0); // the list is nothing without name list... - if (!pNames) return 0; + if (!pNames) return nullptr; - if (iNr >= pNames->iSize) return 0; + if (iNr >= pNames->iSize) return nullptr; return &pData[iNr]; } @@ -240,12 +240,12 @@ C4Value *C4ValueMapData::GetItem(int32_t iNr) C4Value *C4ValueMapData::GetItem(const char *strName) { assert(pNames); - if (!pNames) return 0; + if (!pNames) return nullptr; int32_t iNr = pNames->GetItemNr(strName); assert(iNr != -1); - if (iNr == -1) return 0; + if (iNr == -1) return nullptr; return &pData[iNr]; } @@ -278,7 +278,7 @@ void C4ValueMapData::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers) pComp->Separator(StdCompiler::SEP_SEP2); // Data char **ppNames = !deserializing ? pNames->pNames : new char * [iValueCnt]; - if (deserializing) for (int32_t i = 0; i < iValueCnt; i++) ppNames[i] = 0; + if (deserializing) for (int32_t i = 0; i < iValueCnt; i++) ppNames[i] = nullptr; C4Value *pValues = !deserializing ? pData : new C4Value [iValueCnt]; // Compile try @@ -326,13 +326,13 @@ void C4ValueMapData::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers) // *** C4ValueMapNames *** C4ValueMapNames::C4ValueMapNames() - : pNames(0), iSize(0), pFirst(0) + : pNames(nullptr), iSize(0), pFirst(nullptr) { } C4ValueMapNames::C4ValueMapNames(const C4ValueMapNames& NamesToCopy) - : pNames(0), iSize(0), pFirst(0) + : pNames(nullptr), iSize(0), pFirst(nullptr) { ChangeNameList(const_cast(NamesToCopy.pNames), NamesToCopy.iSize); } @@ -372,7 +372,7 @@ void C4ValueMapNames::Register(C4ValueMapData *pData) void C4ValueMapNames::UnRegister(C4ValueMapData *pData) { // find in list - C4ValueMapData *pAktData = pFirst, *pLastData = 0; + C4ValueMapData *pAktData = pFirst, *pLastData = nullptr; while (pAktData && pAktData != pData) { pLastData = pAktData; @@ -388,9 +388,9 @@ void C4ValueMapNames::UnRegister(C4ValueMapData *pData) pLastData->pNext = pData->pNext; else pFirst = pData->pNext; - pData->pNext = 0; + pData->pNext = nullptr; - pData->pNames = 0; + pData->pNames = nullptr; } void C4ValueMapNames::ChangeNameList(const char **pnNames, int32_t nSize) From 77dca569fedbee8253c096180f81077d11fc16df Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Sat, 6 May 2017 18:55:27 +0200 Subject: [PATCH 93/93] Switch: properly process and save editor actions --- .../Room.ocd/Switch.ocd/Script.c | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/planet/Decoration.ocd/Room.ocd/Switch.ocd/Script.c b/planet/Decoration.ocd/Room.ocd/Switch.ocd/Script.c index 04b5814ee..ec21efbc1 100644 --- a/planet/Decoration.ocd/Room.ocd/Switch.ocd/Script.c +++ b/planet/Decoration.ocd/Room.ocd/Switch.ocd/Script.c @@ -18,6 +18,7 @@ public func SaveScenarioObject(props) var pos = GetHandlePosition(); if (pos) props->AddCall("Handle", this, "SetSwitchDir", (pos>0)-(pos<0)); } + if (left_action || right_action) props->AddCall("Action", this, "SetActions", left_action, right_action); return true; } @@ -27,6 +28,13 @@ public func SetTarget(object trg) return true; } +public func SetActions(new_left_action, new_right_action) +{ + left_action = new_left_action; + right_action = new_right_action; + return true; +} + public func ConnectNearestDoor() { // EditCursor helper command: Connect to nearest door. Return connected door. @@ -65,7 +73,7 @@ public func ControlRight(object clonk) private func ControlSwitchDir(object clonk, int dir) { - if (!target || !handle) + if (!handle || (!target && !right_action && !left_action)) { Sound("Structures::SwitchStuck"); Message("$MsgStuck$"); @@ -120,7 +128,11 @@ public func SetR(int to_r) private func SwitchingTimer(int dir) { - if (!handle || !target) { Sound("Structures::SwitchStuck"); return SetAction("Idle"); } + if (!handle || (!target && !right_action && !left_action)) + { + Sound("Structures::SwitchStuck"); + return SetAction("Idle"); + } var handle_pos = GetHandlePosition(); var handle_pos_new = BoundBy(handle_pos + HandleSpeed * dir, -MaxHandleAngle, +MaxHandleAngle); if (!handle_pos_new) handle_pos_new = dir; // avoid direct central position, so player cannot force the same direction twice @@ -139,10 +151,11 @@ private func SwitchingTimer(int dir) private func DoSwitchFlip(object clonk, int dir) { // Perform action associated to this switch - if (target) - if (dir>0) + if (dir > 0) + { + // Open/close should be aligned to vertical component of direction + if (target) { - // Open/close should be aligned to vertical component of direction if (GetR() < 0) { target->~OpenDoor(this); @@ -151,12 +164,16 @@ private func DoSwitchFlip(object clonk, int dir) { target->~CloseDoor(this); } - // Action last; it may delete the door/clonk/etc. + } + // Action last; it may delete the door/clonk/etc. + if (right_action) UserAction->EvaluateAction(right_action, this, clonk); - } - else - { - // Open/close should be aligned to vertical component of direction + } + else + { + // Open/close should be aligned to vertical component of direction + if (target) + { if (GetR() < 0) { target->~CloseDoor(this); @@ -165,8 +182,11 @@ private func DoSwitchFlip(object clonk, int dir) { target->~OpenDoor(this); } - UserAction->EvaluateAction(left_action, this, clonk); } + // Action last; it may delete the door/clonk/etc. + if (left_action) + UserAction->EvaluateAction(left_action, this, clonk); + } return false; }