Page 1 of 1

Script error when gibbing/removing dead corpses

Posted: Wed Feb 05, 2020 1:33 am
by Gunter
Trying to call Remove() or Gib() inside a PlayerDeathCallback listener throws an exception

Code: Select all

//Throws script exception and corpse gets removed on first try only
public void OnStartup() {
	Events.PlayerDeathCallback.Start((deadPlayer) => {
		if (deadPlayer != null ) deadPlayer.Gib();
	});
}
this is the throw exception

Code: Select all

--- Exception ---
Object reference not set to an instance of an object.
   at ScriptEngine.Sandbox.ExecuteInstanceMethodInScript.Run(Boolean debuggingScript, Action callback, MethodInfo methodInfo, Object classInstanceObject, Object[] parameters)
   at SFD.GameWorld.RunScriptCallbacks[T](Func`2 handleCallback)
template map for testing

Also, I made some extra tests to check a few things, hope it helps

Code: Select all

//Gives script exception on first try but corpses are getting removed correctly
public void OnStartup() {
	Events.PlayerDeathCallback.Start((deadPlayer) =>
		Events.UpdateCallback.Start((t) => { 
			if (deadPlayer != null) deadPlayer.Gib(); }, 100, 1)
	);
}

//This approach works
public void OnStartup() {
	Events.PlayerDeathCallback.Start((deadPlayer) => {
		if (deadPlayer != null)
			deadPlayer.SetWorldPosition(new Vector2(0, Game.GetWorldBottom()));
	});
}

Re: Script error when gibbing/removing dead corpses

Posted: Wed Feb 05, 2020 8:07 pm
by Gurt
Fixed after v.1.3.3.
Thanks for reaching out.
This is actually the same problem as: https://www.mythologicinteractiveforums ... =20&t=3900 which is scheduled for the next update which we will release soon!

Core problematic is that callbacks within callbacks just didn't work. Imagine that you in your PlayerDeathCallback create a player and then also kill it, this will trigger the PlayerDeathCallback recursively. IPlayer.Gib() removes a player which also triggers the PlayerDeathCallback... This will work as intended in the next version allowing the below code to work as expected:

Events.PlayerDeathCallback.Start((deadOrRemovedPlayer) => {
if (!deadOrRemovedPlayer.IsRemoved) {
deadOrRemovedPlayer.Gib();
}
});