Cause minion to attack anything under player crosshairs?

Fri Jan 28, 2022 11:02 am

Hi all!

Okay, I have been building a drone weapon and it currently spawns a friendly creature (based off of High Noon Drifter's Radio item). I am still adding features, and one thing I think would be cool is if you spawn the drone by tapping secondary fire, then holding secondary fire would cause the drone to do certain actions based on what you're looking at (kind of like Bosco the Drone in Deep Rock Galactic).

My goal is to make it so that if you look at an enemy, the drone will switch targets to that individual, and if you target an item, it will fly toward the item and pick it up (similar to High Noon Drifter's boomerang-fetch). My current code so far is:

Weapon code (in DECORATE lump)
Spoiler:


Drone code (in ZSCRIPT lump)
Spoiler:


So, questions:

1. I have been looking around the Zdoom wiki and found the following under SetPointer:

This script will cause any monster with provided TID to attack the calling player's current target. It could be used for summoned minions and the script could be activated via a hot-key.

Script "AttackTarget" (int TID) NET
{
int oldTID, target;
if(SetActivator(0,AAPTR_PLAYER_GETTARGET)) // Get the target of the activator. If it fails because there is none nothing will happen.
{
oldTID = ActivatorTID(); // Save the TID of the target.
target = UniqueTID(); // Get a new unique TID for the target actor.
Thing_ChangeTID(0, target); // Set that TID to the actor.
SetActivator(TID); // Set the activator to the actor with the given TID.
SetPointer(AAPTR_TARGET, target); // Give a new target to it.
Thing_ChangeTID(target,oldTID); // Restore the previous TID, because it might be used already by other scripts.
}


How in the heck am I supposed to use this script, or put it in a weapon?

2. How could you make a weapon that has different behavior depending on tap vs hold?

3. How can you make an actor tell the difference between the player looking at an item and looking at an enemy actor? What about differentiating between friendly vs hostile actors?

Example mods or code would help in everything. I am very literal-minded, and have only been programming ZSCRIPT for about 14 hours. I got the weapon from a Youtube video that showed how to build one, then have been inspecting various mods that do the various things I want to do in one form or another. Figuring out all the nuances is a killer just like with any of the languages I know, such as having to put Zscript code in a lump called ZSCRIPT (that little irritation took almost 6 hours). All told, maybe I will get this somewhere close to complete by the time I die! :roll:

Re: Cause minion to attack anything under player crosshairs?

Fri Jan 28, 2022 7:08 pm

Good thing is - it's all possible! Bad thing is, I'm very tired and drunk, so commenting to save this for later.
Drunk hints - actor referencing (iterators?) on weapons, line tracing to check the target, custom variables on monsters (bool isMonster) to quickly check if it's a monster / or just check for bISMONSTER flag...
Also - tap vs hold could be done with some clever tick counting with OnTick() and GetPlayerInput stuff.

Sounds fun, mate, will try to help you out... like tomorrow or something. Cheers!

Re: Cause minion to attack anything under player crosshairs?

Sun Jan 30, 2022 10:01 pm

I appreciate it! I am a bit worried, though, as I was hoping to avoid the problems of multiple line traces like here:
viewtopic.php?f=122&t=74479

I am not quite sure how to do line tracing, and what Sir Robin is doing seems like a much more complicated version of what I am doing. Definitely related, though.

Does GZDoom not have intrinsic function to tell an actor’s viewing vector?

Ultimately I want to do several things with this.

Secondary fire:

-TAP to launch/recall the drone
-HOLD to fire a laser pointer. The drone will stop its AI pathfinding and hunting for enemies on its own and fly directly towards the laser point if the pointer is on a wall (similar to a laser-guided rocket from Project Brutality or Half Life). The drone will resume its AI without the laser: I want the player to be able to send the drone into rooms and such to clear them out. If you hit an enemy with a laser pointer (sweep over them) they become primary target for the drone. If you sweep over an item the drone will fetch the item and bring it to you (like High Noon Drifter’s boomerang can).

Primary fire: causes the drone to shoot. If the drone is deployed by tapping Secondary Fire, behaves as you would expect. If it is NOT deployed, the drone (which is intended to look like an orb with a wrist-mounted launcher) will fire like a turret mounted to your wrist.

Other functions may be implented in TAP vs HOLD on Primary fire.

Finally, hitting Reload will act as a Tertiary Fire. It will either cause the player to take direct control of the deployed drone (forward back left right up down and shoot) or shoot a controlled drone if none exists. So you can actually fly your drone, not just spawn an actor!

I know this is possible because there is a sniper rifle/railgun in Russian Overkill that does this (only there you “shoot” a player-controlled black orb you can then fly around and hit fire to shoot railgun blasts out of).

So currently I can spawn an AI companion. Next is the laser pointer, as that will be a pain and I want to know if I can yet. Beyond that I just take code from, say, remotely detonated pipebomb weapons and instead alter it to make the drone fire (instead of a bomb explode). Get some nice graphics and I should have Version 1. Afterwards I will implement the wrist turret function, then finally the “Reload for Tertiary Fire for Out Of Body experience”.

Then it will just be miscellaneous stuff, like making sure a player-flying drone can pick up and deliver items, the drone uses ammo to fire and won’t fire without it, and the sprites all look good. Ultimately I want this to be compatible with other mods (particularly Project Brutality).

I am not really concerned with balance at this point, though perhaps in the future a multiplayer version of this where players on really large city, mountain, and forest maps hunt each other with drones and no other weapons might be nice. Kind of a sneak/recon/instakill mod with a high tech hide-and-seek vibe? Maybe call it RC Deathmatch or something. Currently I am making a single player version mostly for myself and I want people to go “Oh hell yeah, that is so cool!”

Plus it is illegal to strap weapons on drones in real life and hunt down the people that annoy us… :lol: :roll:

But first things first! Hope you get to feeling better soon!

Re: Cause minion to attack anything under player crosshairs?

Tue Feb 01, 2022 10:06 am

It's been a while longer than a day... :(

Look, I found something interesting, A_JumpIfTargetInLOS. Now, I *need* an answer to this because the ZDoom Wiki isn't making sense to me - it says that:

This script will cause any monster with provided TID to attack the calling player's current target. It could be used for summoned minions and the script could be activated via a hot-key.

Script "AttackTarget" (int TID) NET
{
int oldTID, target;
if(SetActivator(0,AAPTR_PLAYER_GETTARGET)) // Get the target of the activator. If it fails because there is none nothing will happen.
{
oldTID = ActivatorTID(); // Save the TID of the target.
target = UniqueTID(); // Get a new unique TID for the target actor.
Thing_ChangeTID(0, target); // Set that TID to the actor.
SetActivator(TID); // Set the activator to the actor with the given TID.
SetPointer(AAPTR_TARGET, target); // Give a new target to it.
Thing_ChangeTID(target,oldTID); // Restore the previous TID, because it might be used already by other scripts.
}


What is the TID? I need to know how to capture the Player, the (preferably SPECIFIC) Drone actor I spawned, and the thing I am looking at. How am I supposed to fill in in that script? Where do I put it? I need more context!

So for example, if I have a weapon that spawns the drone (an actor called Drone) with primary fire and I want it to attack the target I am looking at, would I have a weapon code that looked like:

Code:
   Fire:
       TNT1 A 0
       TNT1 A 0 A_JumpIfTargetInLOS("OpenFire")
       Goto Ready
   AltFire:
          HSKL E 0 A_PlaySound("weapon/firedrone", CHAN_WEAPON, 0.7)
      HSKL E 0 A_Recoil(4)
      HSKL E 5 A_SpawnItemEx("Drone", 40, 0, 35, 0, 0, 0, 0, SXF_TRANSFERPOINTERS) // Should this be TID = A_SpawnItemEx("Drone", 40, 0, 35, 0, 0, 0, 0, SXF_TRANSFERPOINTERS) or something to capture the drone for future reference?
      HSKL D 5
      HSKL D 0 A_Refire("SkullinazorFire")
      Goto Ready
   OpenFire:
       TNT1 A 0 AttackTarget(Drone) //Would this assign the script "AttackTarget" to the Drone?
       Goto Ready

Script "AttackTarget" (int TID) NET
{
 int oldTID, target;
 if(SetActivator(0,AAPTR_PLAYER_GETTARGET)) // Get the target of the activator. If it fails because there is none nothing will happen.
{
  oldTID = ActivatorTID(); // Save the TID of the target.
  target = UniqueTID(); // Get a new unique TID for the target actor.
  Thing_ChangeTID(0, target); // Set that TID to the actor.
  SetActivator(TID); // Set the activator to the actor with the given TID.
  SetPointer(AAPTR_TARGET, target); // Give a new target to it.
  Thing_ChangeTID(target,oldTID); // Restore the previous TID, because it might be used already by other scripts.
}


Is that supposed to work? What is "int TID", "NET", "oldTID", "target", and all of those tags supposed to be? How do I assign them? I am not understanding any of this, so any help would be highly appreciated!!!

Re: Cause minion to attack anything under player crosshairs?

Wed Feb 02, 2022 10:15 am

First and foremost - you need to keep an eye on which function is in which language. For GZDoom, we have DECORATE, ACS and ZScript.

The script function is an ACS function, which means it is not directly compatible with DECORATE/ZScript.

So, to be frank, this will not help with what you want to do, unless you want to add an ACS lump, put that code in there, compile it, and only then access the function.

But! Let's think what we can actually do!

While i will not be able to help with the "targetting" an item, as while it is fully doable, it is more than i can help "ad-hoc".

Let's start with something simple: Tap vs Hold.

It should be as straightforward as possible, we don't have to go to ZScript specific functions

We can simply check at the start of fire state, if the fire button is pressed. If not, we do tap action, if yes, we do the hold action.
Code:
Fire:
TNT1 A 1; // Non zero duration, so we have "time" to stop holding fire. It might require more than a single tick though.
TNT1 A 0 A_Refire("HoldAction");
Goto TapAction;


Now, the more fun, and important part - making the drones attack our target!

This will not be as easy as others, and it will use ZScript.

First, we will need to get a trace from the player to find an enemy. The easiest solution for me, is to copy a function that i know works. In this case i'll steal from wiki - LineTrace.

Let's grab the example and edit for our use:
Code:
action bool A_AttackMyEnemyDrone()
 {
            FLineTraceData RemoteRay;
            bool hit = LineTrace(
               angle,
               2048,
               pitch,
               offsetz: height-12,
               data: RemoteRay
            );

            if (hit && RemoteRay.HitType == TRACE_HitActor) // Check if we hit an actor
            {
if (HitActor) // This is what we hit, but, just in case, let's check if it is non-null
{
// Now we have the target we want to kill. We need to find our drone now, and order it to attack. The following part will assume that each drone the player has refers to the player with it's "master" field.
   
   ThinkerIterator Searcher = ThinkerIterator.Create("Drone ");
      Drone Iterated;
      while (Iterated = Drone(Searcher.Next()))
      {
if (Iterated.master == invoker.owner) // Just our drones, don't steal!
{
// This part is actually what i am least certain will work, we need to actually order the drone to attack. I believe just changing pointers of the drone will be enough:
Iterated.target = HitActor;
Iterated.lasttarget = HitActor;
Iterated.soundtarget = HitActor;
}
      }


}
            }
        }


Note that non of the code was tested, but it should be enough to nudge you towards the solution!

Re: Cause minion to attack anything under player crosshairs?

Thu Feb 03, 2022 10:27 pm

Hi! I was reading your post, thinking, wow that's kind of what I'm doing. I'll post a link to my topic so they can see how I'm doing it, but I see you already found it!

So I think what I'm doing right now might be helpful to you. I'm writing a RPG style game play mod and right now I'm working on the "look" function. It works like this: You hold the look key, it puts a 3d cursor out in the world to indicate what you are looking at. You can move your view around and the cursor will move along with you. When you release the look key, it checks to see what is under that cursor and prints it to the user.

You could take the code I have and just change that printing function to be a function that hands a target to your drone, and you're set. If you want the drone to attack anything you swipe over, instead of just what you land on, you'll have to change it just a bit, but the functionality is still there.

Here's working code, you can try it out for yourself. Be sure to set the look key if the autobind didn't work.
UW_Look.pk3

Re: Cause minion to attack anything under player crosshairs?

Sun Feb 06, 2022 10:25 pm

I appreciate it, Sir Robin. Actually, I did see your thread before I posted mine and frankly I was hoping that the solution would not be nearly as convoluted as what you’ve had to go through.

I am sure your code will prove useful, but I wish someone could explain that snippet of code that I got off of the ZDoom wiki to me. The wiki clearly states that it should cause minions to attack whatever is under the player crosshairs, no ghost projectile hitscan ray tracing required. My goal is to *avoid* having the player shoot a bunch of ghost projectiles or hitscans every single time I’m trying to activate this, AND avoid dealing with sector and sector flag headaches. It looks like it should be doable in some form or fashion from the Wiki script template, but I need someone to explain it to me in a way I can understand…

That’s the nice thing about coding: once I finally get what I need working the first time, it’s just copy and paste anytime in the future!

I think the biggest difference between our two projects is that you may want it to detect when it is hitting walls and non-actors (like decorations). At least that was my understanding from some things on your thread. The hardwired functions in GZDoom don’t seem to detect when players are looking at anything except actors with specific flags. That leads me to think there may be more elegant (read, more efficient, less intensive, and more universally applicable) solution to my problem since it requires less thorough detection and discrimination capability than your goal.

So that is where I am coming from. Your work is way beyond what I had originally wanted to get involved in at this point, but I will look through your code and maybe I will come up with all kinds of crazy ideas!

Thanks again! And to everyone else: my question still stands. How the heck do I use that script template off of the ZDoom Wiki?

Re: Cause minion to attack anything under player crosshairs?

Mon Feb 07, 2022 6:43 am

Maahes wrote:I appreciate it, Sir Robin. Actually, I did see your thread before I posted mine and frankly I was hoping that the solution would not be nearly as convoluted as what you’ve had to go through.

Most of what we were doing in that thread was figuring out the math needed to place the 3d cursor into the world. If you want a 3d cursor, you're in luck because we figured it out. If you don't then just skip that part of the code.

Maahes wrote:I am sure your code will prove useful, but I wish someone could explain that snippet of code that I got off of the ZDoom wiki to me. The wiki clearly states that it should cause minions to attack whatever is under the player crosshairs, no ghost projectile hitscan ray tracing required. My goal is to *avoid* having the player shoot a bunch of ghost projectiles or hitscans every single time I’m trying to activate this, AND avoid dealing with sector and sector flag headaches. It looks like it should be doable in some form or fashion from the Wiki script template, but I need someone to explain it to me in a way I can understand…

I'm not the best person to help you completely, I've only been at this for about 2 months, so by no means an expert in any part of it, but I'll explain the things I've learned so far. Maybe that will help you until someone more experienced comes by to help you out.

One thing to understand is that ZDoom has several scripting implementations, the biggest ones are Decorate, ACS, and ZScript. Most of the the wiki describes the older ones, Decorate and ACS, so unless the page specifically mentions ZScript, it's probably one of the others. Those languages had limitations so they had to do things in more convoluted ways that ZScript can do more directly. Did you see Virathas's post right before mine? They gave you examples of what you can do in ZScript to get where you're trying to go.

Maahes wrote:I think the biggest difference between our two projects is that you may want it to detect when it is hitting walls and non-actors (like decorations). At least that was my understanding from some things on your thread. The hardwired functions in GZDoom don’t seem to detect when players are looking at anything except actors with specific flags. That leads me to think there may be more elegant (read, more efficient, less intensive, and more universally applicable) solution to my problem since it requires less thorough detection and discrimination capability than your goal.

Something to understand is that all things in the 3d world are actors. So to say "non-actors (like decorations)" is a misunderstanding. Walls, floors, and ceilings are level geometry, but everything else is actors - players, monsters, decorations, pickups, projectiles, bullet puffs, blood splats, etc - all these things are actors.
The linetrace can hit several things. If you are not interested in level geometry, simply ignore those hits. If you are not interested in non-solid non-shootable actors (like decorations and effects) then simply ignore those hits. You filter out the stuff you don't want until you only have the things that you do want. You also give flags to the linetrace to tell it what actors to pass through.

Maahes wrote:So that is where I am coming from. Your work is way beyond what I had originally wanted to get involved in at this point, but I will look through your code and maybe I will come up with all kinds of crazy ideas!

I put all my code into an inventory object so that it is isolated and portable. You'd probably want to put yours directly into your weapon, since that's the only place you need it to be. Also, see the code I added to Nash's RadiusDebug. Maybe you can use that to put a box around the drone's target. Also look in that code for how I filter the actors - monsters, shootables, pickups, drops, etc.

Maahes wrote:Thanks again! And to everyone else: my question still stands. How the heck do I use that script template off of the ZDoom Wiki?

Virathas and I are both telling you that's ACS code and not the best way to get what you want. Look at all the ZScript examples that Virathas provided.

Re: Cause minion to attack anything under player crosshairs?

Mon Feb 07, 2022 9:03 pm

I don't have a code example, but I just saw this video of a boomerang weapon that works similar to how you want your drones to work. The user points where they want it to go and it goes. If it hits a wall it comes back. If it hits a monster it does damage. If it finds a pickup, it bring it to the user. Maybe you could track down the mod in this video and look at the code for examples for your drones.

Hope that helps

Re: Cause minion to attack anything under player crosshairs?

Mon Feb 07, 2022 9:55 pm

Oh booger... I didn't even see Virathas' post! I've been ill and couldn't even get out of bed, so I was posting from my teeny little phone screen (it's one of the original iPhone SE's - I try to take care of my stuff because new stuff is too expensive!) Being awake for 36 hours with a bleeding sinus infection and meds that take me out of it sure aren't fun, and apparently don't do anything for my situational awareness.

Thank you again, Sir Robin, and ALSO to you, Virathas! That was actually really good, I need to see code in actual form to "get" it. I dunno, it's some kind of weird quirk I have: the abstract general solution forms don't help me as much until I see a real problem worked out first. We will see if I can implement it or not.

You're also right on the money with that video. That is by TerminusEst13, he later implemented a different-ish version of that into his High Noon Drifter mod. Very good mod, check it out if you haven't! The HND's boomerang can also be fired at ammo, health, and other items, "grabs" them and can bring them back to the player. And yes, I am already cutting apart his coding but some of it is way beyond me for the moment.

*sigh* I hate learning new computer languages, especially ones where I can't find a good, in-depth manual with examples and I don't have someone hostage to show me how to get past parts I'm beating my head against. It's really easy to understand after a good explanation, you know? Things will go much more smoothly once I get everything working in some form, because afterwards I can just version-control it and start playing with the code (and revert if I break something). I learn best by doing, but if I keep getting error messages whenever I start up then it's hard to visualize the problem when it could literally be anything (as far as I know). I can mod in nearly a dozen languages, but right now I'm learning C# and trying to build a investing/trading robot with NinjaTrader, get through a divorce from an abusive wife, and find a job (lost my old one 5 weeks after my wife got herself arrested for domestic assault after saying *I* did it... it pays to be 9" taller and 130 lbs heavier, it is reeaally obvious who punched whom). Then my sinuses... it was kind of nice to be out of it, honestly, but there is so much to do afterwards!

I can't tell, but I don't think I'm over the sleep deprivation or meds, honestly.

Re: Cause minion to attack anything under player crosshairs?

Thu Feb 10, 2022 9:54 am

At first I was going to say "Hope you feel better!" but the more i read into your post the more I'm like "wow he's got a lot going on!" Well I hope it all works out for ya, sounds rough.

I tried out that HND mod - wow! Nice! That boomerang is pretty over-powered though. It uses no ammo, silent, always comes back, does about as much damage as the shotgun, and kills projectiles? I barely found time to even try the other weapons.