Player701 wrote:This has something to do with the way the movement code is written. I've tried running it in a debugger, and it seems that the player's movement for the current tick is processed after the teleport special is executed, overriding the player's coordinates as a result. I'm not yet sure if these is a way to work around this. See further below for a workaround solution.
Thanks for looking into this. Is it worth reporting as a bug / feature request? I would think that a teleport function call should reset any movement logic in the actor(s) it is affecting.
Player701 wrote:Consider using an ACS script with [wiki]GetActorZ[/wiki] and/or [wiki]GetActorFloorZ[/wiki] for line triggers to achieve the desired effect.
I understand there are different ways to do this, I was experimenting to see pros/cons of different approaches. What I like about using an actor is the simplicity. An editor like UDB will see the teleport special, find it's target, and indicate the relationship with a line or whatever is configured to do, so it is easy to graphically understand the relationship. I could have a line special call a script and that script call a teleport and that teleport point to a destination, but now that's 3 things I have to look at manually to understand what is happening.
Player701 wrote:Workaround for the original setup: use an inventory item that will call the special as soon as it appears in the owner's inventory, and then destroy itself. This delays the call until the player's movement for the current tick has been fully processed.
Excellent! Thanks for taking the time to work this out!
I saw your first post about the timing and tried moving that special call. I didn't think to move it to an inventory item, but I did try moving it from the touch to the tick function of the trigger object and that works for the teleport issue:
Code: Select all
bool DelayedSpecial;
actor SpecialToucher;
override void Touch(Actor toucher)
{
if (TouchCountdown>0) {return;}
console.printf(GetCharacterName().."@"..level.time..": Touched by "..toucher.GetCharacterName());//DEBUG
DelayedSpecial=true;
SpecialToucher=toucher;
TouchCountdown=TouchTimeout;
}
override void tick()
{
if (TouchCountdown>0){TouchCountdown--;}
super.tick();
if (DelayedSpecial && SpecialToucher)
{
SpecialToucher.A_CallSpecial(special, args[0], args[1], args[2], args[3], args[4]);
}
DelayedSpecial=false;
SpecialToucher=null;
}