Major compatibility issues (functions are all methods of the object returned by GetRelaunchRule())
* Rule_Restart needs to be replaced by EnablePlayerRestart()
* Rule_BaseRespawn needs to be replaced by SetBaseRespawn(true)
* FreeCrew and InventoryTransfer can be set by calling SetInventoryTransfer(true/false) and SetFreeCrew(true/false)
* Remove all existing respawn code in the scenario, it isn't needed any more.
* If the game mode is melee, the default relaunch count is 5, otherwise, it is nil (unlimited relaunches). You can set it with SetDefaultRelaunches(relaunches).

Also, your inventory doesn't get transferred.
In general, I'd appreciate a function to disable respawning of script players. That's the addition I had to make in my campaign.


ERROR: symbol not found in any symbol table: pos (in Scenario.Prototype.OnClonkLeftRelaunch, Arena.ocf\Overcast.ocs\Script.c:343:31)
ERROR: symbol not found in any symbol table: pos (in Scenario.Prototype.OnClonkLeftRelaunch, Arena.ocf\Overcast.ocs\Script.c:343:38)
by: Scenario->OnClonkLeftRelaunch(Object(448)) (Arena.ocf\Overcast.ocs\Script.c:0)
ERROR: syntax error: symbol not found in any symbol table: pos (in Scenario.Prototype.OnClonkLeftRelaunch, Arena.ocf\Overcast.ocs\Script.c:343:31)
by: Object(460)->GameCall("OnClonkLeftRelaunch",Object(448)) (System.ocg\Action.c:36)
by: Object(460)->RelaunchClonk() (Objects.ocd\Rules.ocd\Relaunch.ocd\RelaunchContainer.ocd\Script.c:115)
by: Object(460)->FxIntTimeLimitTimer(Object(460),effect {Name = "IntTimeLimit"},36) (Objects.ocd\Rules.ocd\Relaunch.ocd\RelaunchContainer.ocd\Script.c:79)
[15:30:49] by: Object(239)->DoRelaunch(0,0,0,true) (/home/maikel/openclonk/repos/build/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c:292)
[15:30:49] by: Object(239)->InitializePlayer(0,319,264) (/home/maikel/openclonk/repos/build/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c:175)
ERROR: symbol not found in any symbol table: respawn_script_players (in Rule_Relaunch.OnClonkDeath, /home/maikel/openclonk/repos/build/planet/Objects.ocd/Rules.ocd/Relaunch.ocd/Script.c:183:33)

Okay, this is odd. The commit on the branch fulgen-master has the Set() - function, after the cherry-pick, it didn't.
And what is the reason for using both function chaining and proplist setting? What is wrong with calling a series of setters?


Set*
functions are the definition of the public interface of the object. It's pretty much standard to user interfaces like this (see e.g. https://en.wikipedia.org/wiki/Mutator_method for a few languages).It's a standard we use in all objects and the engine (e.g. SetColor(...), not Set("color", ...)). Please don't invent new standards. Even if they make sense on their own, it complicates things to have both variants.
Set
function that simply sets a local variable is rather pointless. You could as well have written object.variable = setting;
then.
>A Set function that simply sets a local variable is rather pointless. You could as well have written object.variable = setting; then.
I am not saying we should or should not use that, but there are actually good practical reasons for using a setter for simple variable assignments.
E.g. forward compatibility:
Imagine a library. For the sake of the argument we'll call it Library_Stackable. And this library had to safe whether the contained stack was infinite. In one version it used
this.count = -1;
in another version it used this.infinite = true;
. A setter SetInfinite
would have worked in both cases even though it would simply replace a variable assignment in one.

> A setter SetInfinite would have worked in both cases even though it would simply replace a variable assignment in one.
Yes, that's why I'm advocating the use of a setter.
But the relaunch rule used
Set(setting_name, value)
, and Set
was basically defined as this[setting_name] = value;
.I'm not against having SetX functions for every property X. I'm just against having one generic Set function. We could as well remove all functions from an object and replace it by one big "Do" function. Like
some_object->Do("Explode")
. But there's no reason to build another layer of abstraction.You are correct that
foo->Set("setting_name", value) is probably better than foo.setting_name = value;
because could put compatibility shims into such a generic setter (if (setting_name == "stack_count") do_something_special()
). But in the long run, that will be pretty hard to maintain.
>put everything into larger commits that work on their own and don't need other commits. Each of the separate commits should work by themselves.
Well, in fact, this isn't really easy. E.g., you cannot pick one commit which adapts the scenarios without picking the commit where the new rule was introduced.

* Rule_Restart needs to be replaced by AllowPlayerRestart() (this allows players to restart in the F menu).
* An option to disable handling restarts (so that the Parkour goal can do it properly for Parkours).
I really hope these are the last bugs.
>An option to disable handling restarts (so that the Parkour goal can do it properly for Parkours).
Just return true in OnPlayerRestart(), this aborts the restart.
>Rule_Restart needs to be replaced by AllowPlayerRestart() (this allows players to restart in the F menu).
Don't know exactly what you mean. When restarting is activated, activating Rule_Relaunch in the menu restarts the player.

> * An option to disable handling restarts (so that the Parkour goal can do it properly for Parkours).
My plan was that the restart rule also handles restarts in parkour levels. The parkour goal would only provide the restart position (e.g. by hooking into the same GameCallEx that can also be used by scenarios to define respawn positions). That way, we can remove the duplicate restart functionality in the parkour goal and we gain all the extra respawn options that could be used in parkours as well (transfer inventory, restart costs gold, weapon chooser, respawn delay, etc.).
The whole point of having the restart rule was that every scenario and game goal duplicated some of the restart code.
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].
* 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.
* GetPlayerRelaunchCount(int plr): get player relaunch count.
* DoPlayerRelaunchCount(int plr, int value): add to player relaunch count.
* HasUnlimitedRelaunches(): whether the players have infinite relaunches.
Still todo is proper scenario saving, but for now there is no round yet which places this object anywhere, so that is fine.

- Dark Castle, Raid, Deep Sea Mining, Treasure Hunt: respawn time is 35 seconds
- Crash Landing: Respawn time is instant, but respawn position makes you stuck
- Shiver Peak: relaunch rule isn't configured thus broken (why is the default respawn time 360 seconds?!)


> * SetAllowPlayerRestart(bool on): whether a player can select restart in the rule menu.
Is this intended as a new symbol besides the respawn rule to click on?
Any objections?
Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill