Teleporter Weapon/Ability Rewrite Help

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
User avatar
Exosphere
Posts: 168
Joined: Sun Jun 11, 2017 11:42 am
Location: New England, US

Teleporter Weapon/Ability Rewrite Help

Post by Exosphere »

One of the abilities my mod has is a "personal teleport" that is meant to function virtually identically to Ranger's Dire Orb from Quake Champions. With the assistance of others, I was able to write something that functions similar to the Dire orb, but not entirely. The code itself is also pretty old, so it probably uses techniques that are redundant or unnecessary:

Code: Select all

class InFlightToken  : Inventory{ Default{ Inventory.MaxAmount 1;}}
class ReadyForTeleToken : Inventory{ Default{ Inventory.MaxAmount 1;}}

class Tesseract : Actor
{
    Default
    {
        Projectile;
        Damage 10;
        Speed 60;
        +RIPPER;
        +BLOODLESSIMPACT;
		Alpha 0.85;
    }
    
    States
    {
        Spawn:
			POST ABCDE 1 Bright;
			TNT1 A 0 A_GiveInventory("InFlightToken");
            Loop;
        Death:
			TNT1 A 1 A_TeleportPlayer();
			TNT1 A 1 A_StartSound("misc/teleport", CHAN_AUTO);
			TESS ABABCDEFGH 1 Bright;
			TNT1 A 1 A_Print("Teleported");
			TNT1 A 1 A_TakeInventory("InFlightToken");
            Stop;
    }
    
    action void A_TeleportPlayer()
    {
        if (target == null){ return; }
        else
        { target.SetOrigin(pos, false); }
    }
}

class TesseractManager : EventHandler
{
	override bool InputProcess(InputEvent e)
	{
		if (e.Type == InputEvent.Type_KeyDown)
		{ SendNetworkEvent("tesseract_use", e.KeyScan); }
		return false;
	}
	
	override void NetworkProcess(ConsoleEvent e)
	{
		actor plr;
		if (e.Name == "tesseract_use")
		{
			int k1, k2;
			let plr = players[e.Player].mo;
			[k1, k2] = Bindings.GetKeysForCommand("tesseract");
			if ((k1&&k1 == e.Args[0]) || (k2&&k2 == e.Args[0]))
			{
				//let plr = players[e.Player].mo; //mo = Map Object
				plr.SpawnPlayerMissile("Tesseract");
			}
		}
	}
}
The issues I am having is that
1. I am able to "fire" multiple orbs instead of just only once.
2. When I press the "fire" button again while the orb is still in flight, it doesn't teleport me to where the orb currently is in space. The projectile will only teleport me when it hits another object or surface.

Does anyone know what I would need to add/write to make this ability function exactly like the Dire Orb?
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Teleporter Weapon/Ability Rewrite Help

Post by Player701 »

First of all, I don't see a need to use Bindings.GetKeysForCommand here. Not only that, but it's called in NetworkProcess, which would likely cause the game to go out of sync in multiplayer if different players have different bindings for this command. (Why isn't GetKeysForCommand restricted to the UI scope? That's a question for the GZDoom dev team...)

To rectify this, add alias tesseract "netevent tesseract_use" to your KEYCONF. Then you will not need InputProcess or GetKeysForCommand anymore.

Now, for the next question:
Exosphere wrote: Mon Sep 12, 2022 10:07 amDoes anyone know what I would need to add/write to make this ability function exactly like the Dire Orb?
Unfortunately, I've never played Quake Champions so I don't know how the Dire Orb is supposed to function. But I might be able to help if you could describe it to me, preferably in as much detail as possible.
User avatar
Exosphere
Posts: 168
Joined: Sun Jun 11, 2017 11:42 am
Location: New England, US

Re: Teleporter Weapon/Ability Rewrite Help

Post by Exosphere »

Player701 wrote: Wed Sep 14, 2022 1:32 am Now, for the next question:
Exosphere wrote: Mon Sep 12, 2022 10:07 amDoes anyone know what I would need to add/write to make this ability function exactly like the Dire Orb?
Unfortunately, I've never played Quake Champions so I don't know how the Dire Orb is supposed to function. But I might be able to help if you could describe it to me, preferably in as much detail as possible.
So the Dire Orb is an ability unique only to Ranger (the original Quake protagonist) in QC, which is bound by default to F. It is a spiky ball of energy that will fly to where the player was aiming at, like a rocket projectile. While it is flying, two things can happen:
1. It will continue to fly until it collides with a solid surface, where it will stick to said surface, explode after a few seconds, and the ability will now be on cooldown. This explosion can damage enemies. However, if the player presses the ability button after the orb has landed, the player will instantly teleport to the spot where the orb landed. The orb will also damage any enemy or player it passes through while in flight.
2. The player presses the ability button while the orb is still flying and hasn't hit anything, and the player is teleported to the location where the orb was mid-flight.
3. If the player presses the ability button again, while the orb is in mid-flight and has intersected any enemy (in QC's case, another enemy player), the player that threw the orb will telefrag the enemy where the orb intersected.

The in-game description for Ranger's ability:
"Ranger throws an ethereal orb that damages enemies and explodes when it hits a surface. At any time prior to it exploding, Ranger can teleport himself to the Dire Orb's location."

Here is the in-game tutorial video for the Dire Orb


I hope all of that helps in understanding how the original Dire Orb works. Plus, if you want to play around with it, download Quake Champions: Doom Edition. It functions virtually the same, but with some minor differences, mainly a much longer cooldown time.

One last thing, here is also the Quake Wiki entry for the Dire Orb:
https://quake.fandom.com/wiki/Dire_Orb

----

My version of the "Dire Orb" is a little different. My version removes the "sticky" feature, it will immediately teleport the player as soon as it collides with a surface; no need to press the ability button again. It retains its "damaging enemies it passes through" and "telefrag" abilities. It also doesn't have a cooldown after a player has teleported. The issues I have been having with my teleporter (the Tesseract) were mentioned in the first post of this thread.
User avatar
openroadracer
Posts: 496
Joined: Mon Sep 23, 2019 1:03 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 7 Professional 64-bit SP1
Graphics Processor: ATI/AMD with Vulkan/Metal Support
Location: Doomworld Forums
Contact:

Re: Teleporter Weapon/Ability Rewrite Help

Post by openroadracer »

Player701 wrote: Wed Sep 14, 2022 1:32 amUnfortunately, I've never played Quake Champions so I don't know how the Dire Orb is supposed to function. But I might be able to help if you could describe it to me, preferably in as much detail as possible.
If you want an example you can play with yourself, you could always try Quake Champions: Doom Edition. It faithfully recreates Ranger's "Dire Orb" ability from the retail QC.
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Teleporter Weapon/Ability Rewrite Help

Post by Player701 »

Exosphere wrote: Sat Sep 17, 2022 2:43 pm So the Dire Orb is an ability unique only to Ranger (the original Quake protagonist) in QC, which is bound by default to F. It is a spiky ball of energy that will fly to where the player was aiming at, like a rocket projectile. While it is flying, two things can happen:
1. It will continue to fly until it collides with a solid surface, where it will stick to said surface, explode after a few seconds, and the ability will now be on cooldown. This explosion can damage enemies. However, if the player presses the ability button after the orb has landed, the player will instantly teleport to the spot where the orb landed. The orb will also damage any enemy or player it passes through while in flight.
2. The player presses the ability button while the orb is still flying and hasn't hit anything, and the player is teleported to the location where the orb was mid-flight.
3. If the player presses the ability button again, while the orb is in mid-flight and has intersected any enemy (in QC's case, another enemy player), the player that threw the orb will telefrag the enemy where the orb intersected.

The in-game description for Ranger's ability:
"Ranger throws an ethereal orb that damages enemies and explodes when it hits a surface. At any time prior to it exploding, Ranger can teleport himself to the Dire Orb's location."
Sorry for a late reply. Thank you very much for the description. Unfortunately, I won't be able to provide an extensive answer until the beginning of the next week at the very least (because I'm not at home right now and not due to return until then). But I see you mentioned telefragging, this won't work if you use SetOrigin. You have to use Teleport instead, e.g.:

Code: Select all

void A_TeleportPlayer()
{
    if (Target != null)
    {
        Target.Teleport(Pos, Target.Angle, TF_TELEFRAG);
    }
}
Replace Target.Angle with Angle if you want to make the player face the direction the projectile is travelling instead of keeping their current angle.
User avatar
ramon.dexter
Posts: 1562
Joined: Tue Oct 20, 2015 12:50 pm
Graphics Processor: nVidia with Vulkan support
Location: Kozolupy, Bohemia

Re: Teleporter Weapon/Ability Rewrite Help

Post by ramon.dexter »

Okay, this thing also interests me. But I'm looking for a little different thing. I made it with help of ACS, but I would really like to remove the ACS part and make it only in zscript. Point is that I don't know how to properly write the syntax for this....

So, my quicktravel thingie works in the following way:
- player activates a inventory item
- the inventory item places a visible beacon and a tagged TeleportDestination, that is later used for return and gives player new inv item that has an ACS script in it

- the second inv item calls acs script, that teleports player to the tagged placed teleportDestination, removes the beacon and re-tags the teleportdest.

As I can see here, I think that the teleportDestination is not required in zscript. That is good. But still, I don't know how to write the syntax for this. I just don't know how to properly cast the placed beacon, so I can later reference it.
User avatar
Exosphere
Posts: 168
Joined: Sun Jun 11, 2017 11:42 am
Location: New England, US

Re: Teleporter Weapon/Ability Rewrite Help

Post by Exosphere »

Player701 wrote: Tue Sep 20, 2022 10:00 am Sorry for a late reply. Thank you very much for the description. Unfortunately, I won't be able to provide an extensive answer until the beginning of the next week at the very least (because I'm not at home right now and not due to return until then). But I see you mentioned telefragging, this won't work if you use SetOrigin. You have to use Teleport instead, e.g.:

Code: Select all

void A_TeleportPlayer()
{
    if (Target != null)
    {
        Target.Teleport(Pos, Target.Angle, TF_TELEFRAG);
    }
}
Replace Target.Angle with Angle if you want to make the player face the direction the projectile is travelling instead of keeping their current angle.
Thank you very much for your assistance, you are welcome for the description, and hope your trip goes well. I do want to clarify something regarding the Dire Orb; I should not have said that I want my mod's "Dire Orb' to function exactly like the one in QC, cause that wasn't my initial intention. There are a few functions I still want it to have:
1. I still want it to immediately teleport the player as soon as it touches a surface.
2. I still want there to be no cool down in between using it, or have it be an extremely short cooldown.

However, if you were already aware of this, then you can disregard it. Once again, thank you for your help.
User avatar
Virathas
Posts: 254
Joined: Thu Aug 10, 2017 9:38 am

Re: Teleporter Weapon/Ability Rewrite Help

Post by Virathas »

@Ramon.dexter
I believe this quickly made item is of use to you (in attachment, replaces chainsaw to quickly show how it works)

EDIT: I can't seem to upload files, so just the raw ZSCRIPT file:
Spoiler:
User avatar
ramon.dexter
Posts: 1562
Joined: Tue Oct 20, 2015 12:50 pm
Graphics Processor: nVidia with Vulkan support
Location: Kozolupy, Bohemia

Re: Teleporter Weapon/Ability Rewrite Help

Post by ramon.dexter »

Virathas wrote: Thu Sep 22, 2022 11:47 am @Ramon.dexter
I believe this quickly made item is of use to you (in attachment, replaces chainsaw to quickly show how it works)

EDIT: I can't seem to upload files, so just the raw ZSCRIPT file:
Spoiler:
Hi, thanks for a quick response. I'll test it later, but it looks exactly like what I have in mind.
User avatar
ramon.dexter
Posts: 1562
Joined: Tue Oct 20, 2015 12:50 pm
Graphics Processor: nVidia with Vulkan support
Location: Kozolupy, Bohemia

Re: Teleporter Weapon/Ability Rewrite Help

Post by ramon.dexter »

Virathas wrote: Thu Sep 22, 2022 11:47 am @Ramon.dexter
I believe this quickly made item is of use to you (in attachment, replaces chainsaw to quickly show how it works)
Rad! Works like a charm, exactly the thing I was looking for. Many thanks, Virathas! :D
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Teleporter Weapon/Ability Rewrite Help

Post by Player701 »

Exosphere wrote: Thu Sep 22, 2022 10:36 amThank you very much for your assistance, you are welcome for the description, and hope your trip goes well. I do want to clarify something regarding the Dire Orb; I should not have said that I want my mod's "Dire Orb' to function exactly like the one in QC, cause that wasn't my initial intention. There are a few functions I still want it to have:
1. I still want it to immediately teleport the player as soon as it touches a surface.
2. I still want there to be no cool down in between using it, or have it be an extremely short cooldown.

However, if you were already aware of this, then you can disregard it. Once again, thank you for your help.
Thanks for the clarification. Here's some code that implements an item that functions exactly like described. There is no extra cooldown: when the projectile explodes, the item can be used again. Note that the player will only be teleported if there's enough space at the potential destination.

Code: Select all

class TeleportShooter : Inventory
{
    Default
    {
        Inventory.PickupMessage "TODO";
        Inventory.PickupSound "misc/p_pkup";
        Inventory.Icon "BFS1A0";
        Scale 0.5;

        +FLOATBOB;
        +INVENTORY.INVBAR;
    }

    States
    {
        Spawn:
            BFS1 AB 1 Bright;
            Loop;
    }

    private Actor tp;

    override bool Use(bool pickup)
    {
        if (tp != null && !tp.InStateSequence(tp.CurState, tp.FindState('Death')))
        {
            // Teleporter projectile still in flight
            return false;
        }

        // Spawn teleporter projectile
        tp = Owner.SpawnPlayerMissile('TeleportProjectile');

        // Do not remove the item
        return false;
    }
}

class TeleportProjectile : Actor
{
    Default
    {
        DeathSound "misc/teleport";
        Speed 16;
        Scale 0.5;
        Projectile;
        -ACTIVATEPCROSS;
        -ACTIVATEIMPACT;
    }

    States
    {
        Spawn:
            BFS1 AB 1 Bright;
            Loop;
        Death:
            TFOG A 6 Bright A_TeleportPlayer;
            TFOG BABCDEFGHIJ 6 Bright;
            Stop;
    }

    vector3 startVel;

    override void PostBeginPlay()
    {
        Super.PostBeginPlay();

        // Record the initial velocity because it gets zeroed on impact
        startVel = Vel;
    }

    override int DoSpecialDamage(Actor target, int damage, Name damagetype)
    {
        // This projectile does not damage enemies
        return -1;
    }

    void A_TeleportPlayer()
    {
        if (Target == null || Target.Health <= 0)
        {
            // Do not teleport dead and non-existing players
            return;
        }

        // Test for suitable destination at current location
        let testPos = Pos;

        bool result;
        vector3 newPos;
        [result, newPos] = CanTeleportTargetTo(testPos);

        if (!result && startVel.Length() > 0)
        {
            // If we've hit a wall, the initial position test will fail,
            // let's step back a bit and hope it gives us some room
            double dist = Sqrt(2)*Target.Radius/2;      
            testPos -= startVel.Unit() * dist;

            // Repeat the test
            [result, newPos] = CanTeleportTargetTo(testPos);
        }

        if (result)
        {
            // OK, teleport the target
            Target.Teleport(newPos, Target.Angle, TELF_DESTFOG);

            // Do not show teleport fog from death animation
            Destroy();
        }
    }

    private bool, vector3 CanTeleportTargetTo(vector3 testPos)
    {
        // Adjust Z coordinate for adequate results
        testPos.Z += (Height - Target.Height)/2;

        // Temporarily change position
        let oldPos = Target.Pos;
        Target.SetOrigin(testPos, false);

        // Make sure we're not stuck in the floor/ceiling
        testPos.Z = Clamp(testPos.Z, Target.FloorZ, Target.CeilingZ - Target.Height);
        Target.SetOrigin(testPos, false);

        // Call TestMobjLocation and restore old position
        bool result = Target.TestMobjLocation();
        let newPos = Target.Pos;
        Target.SetOrigin(oldPos, false);

        return result, newPos;
    }
}
Also, a correction of my previous reply:
Player701 wrote: Tue Sep 20, 2022 10:00 am But I see you mentioned telefragging, this won't work if you use SetOrigin. You have to use Teleport instead, e.g.:

Code: Select all

void A_TeleportPlayer()
{
    if (Target != null)
    {
        Target.Teleport(Pos, Target.Angle, TF_TELEFRAG);
    }
}
TF_* flags are applicable only to A_Teleport, not Teleport. These functions are very different: the former is used to teleport to a randomly chosen SpecialSpot-derived actor, while the latter can be used to teleport to arbitrary coordinates. Flags for Teleport begin with TELF_*, see full list here.
User avatar
Exosphere
Posts: 168
Joined: Sun Jun 11, 2017 11:42 am
Location: New England, US

Re: Teleporter Weapon/Ability Rewrite Help

Post by Exosphere »

Thank you so, so much for your help, Player. I do have one question though.

Is it still possible for me to map this new teleport ability to an event manager like my original version? I would like to be able to bind it to the F key in-game.
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Teleporter Weapon/Ability Rewrite Help

Post by Player701 »

There is no need for any events, just add a binding for "use TeleportShooter" via KEYCONF. Note that this will work even if you remove the INVBAR flag.
User avatar
Exosphere
Posts: 168
Joined: Sun Jun 11, 2017 11:42 am
Location: New England, US

Re: Teleporter Weapon/Ability Rewrite Help

Post by Exosphere »

Player701 wrote: Wed Sep 28, 2022 8:07 am There is no need for any events, just add a binding for "use TeleportShooter" via KEYCONF. Note that this will work even if you remove the INVBAR flag.
Awesome! Once again, thank you so so much for helping me with this.
Post Reply

Return to “Scripting”