Help modifying code. Targeting System.

Discuss programming in the QuakeC language.
Post Reply
Blackstar1000
Posts: 52
Joined: Mon Sep 13, 2010 5:16 pm

Help modifying code. Targeting System.

Post by Blackstar1000 »

Essentially I like the power that is contained in the code for the "Targeting System" from the tutorial on your main page.

I have broken it down to this

Code: Select all

void() target_system =
{
	local float mega;  // variable to see how far to find enemies
		mega = 900;
	local entity en1;
	en1 = findradius (self.origin, mega);  // find you some enemies
	while (en1)
	{
		if ((en1.takedamage == DAMAGE_AIM && en1 != self) && visible(en1))
		{
			particle (en1.origin, '0 0 20', 244, 20);  // make my beautiful effects
			centerprint (self, "Enemy Target");  //  reports any enemies found
		}
		en1 = en1.chain;  // do over and find another
	}
};
Though I think it may be simplified even more.... :: MY QUESTION IS:

Can I replace the part of it that spawns the "Particle" and instead spawn a sprite? I have a sprite called - "guy.spr32" and I have come so close, but have been stumped for an entire day... HELP!
Knives out. Catch the mouse. Squash his head. Put him in your mouth.
necros
Posts: 77
Joined: Thu Dec 16, 2004 10:32 pm

Re: Help modifying code. Targeting System.

Post by necros »

sure. you'll need to do a little bit more house keeping with a sprite, since it will be an actual entity, instead of a tempentity that is removed by the engine.

essentially, you just put in the standard spawning stuff in the place of the particle call:

entity guy;
guy = spawn();
setmodel(guy, "progs/guy.spr");
setorigin(guy, en1.origin);

the above will spawn a new entity with the guy sprite. now, for the house keeping:

guy.nextthink = time + 1; //some random time... whatever you want
guy.think = SUB_Remove; //remove after a while.

this will remove the sprite after 1 second.

now... i have no idea what the targeting system is, or how it works, but from your post, it looks like it just continuously spawns particles on the targetted entity.
this will probably not work well with the sprite. what you want is the sprite to spawn and stay spawned while the entity is targetted.
a simple (but wasteful) way of doing that would be to set guy.owner to en1.
then, before spawning the guy sprite, first check (again, with a nested while) if there is any entity spawned with .owner pointing to en1. if true, then bump the .nextthink a bit to avoid removing it and skip the spawning section.

edit: you'll also want to update the origin since the monster or whatever probably moved since the last time you checked.
Blackstar1000
Posts: 52
Joined: Mon Sep 13, 2010 5:16 pm

Re: Help modifying code. Targeting System.

Post by Blackstar1000 »

Ugh, Im still so confused. I just cant manage to spawn only one of them and I can't seem to get just one to follow the character around using your method. My understanding of quakeC is still inadequate. I would ask for someone to help clarify, I have wasted my only two nights off on this :|.

I just want to find the nearest entity and apply a sprite that will be tied to it as you get within a certain range. My starting place may have been wrong. It only seemed so right. These things were so easy in hammer ;(
Knives out. Catch the mouse. Squash his head. Put him in your mouth.
tZork
Posts: 2
Joined: Tue Jun 21, 2011 8:59 pm

Re: Help modifying code. Targeting System.

Post by tZork »

Here is how i would do it to track the closest target. Code assumes you use a non arcane qcc.

Code: Select all

.entity my_targ;    // Keep track of last-best target.
float  target_system(float range)
{
    entity targ;                                                    // Chain of ents in range
    entity best_target;                                             // Closest valid target
    float dist;                                                     // Distance to target evaluated
    float best_dist = range + 1;                                    // Distance to closest target

    if(!self.my_targ)                                               // Spawn the sprite entity if missing ..
    {
        self.my_targ = spawn();
        self.my_targ.think = SUB_Remove;                            // .. and make sure it gets removed 
        self.my_targ.nextthink = time + 2;                          // .. if not updated for 2 seconds
    }
        
    targ = findradius(self.origin, range);                          // Find every entity within 'range' units of self
    while(targ)
    {
                                                                    // Eval if targ is a valid target       
        if((targ.takedamage == DAMAGE_AIM && targ != self) && visible(targ))
        {
            dist = vlen(targ.origin - self.origin);                 // Get distance to target 
            if(dist < best_dist)                                    // See if distance is less then previous target 
            {
                best_target = targ;                                 // If so, switch best target to this..
                best_dist = dist;                                   // .. and remeber how far away the current best target is
            }
        }
        targ = targ.chain;                                          // Advance to next target in chain.
    }
    
    if(best_target)                                                 // Did we find a good target?
    {        
        setorigin(self.my_targ, best_target.origin + '0 0 64');     // If so, relocate target marker to best target's origin ..
        setmodel(self.my_targ, "path/to/guy.spr32");                // .. and set target marker's model ..
        self.my_targ.nextthink = time + 2;                          // .. and make sure target marker lives another 2 seconds (at least) ..
        self.my_targ.enemy = best_target;                           // .. and store what that target is ..
        return 1;                                                   // .. and signal success.
    }
    else
    {
        setmodel(self.my_targ, "");                                 // If not, make the marker sprite go away ..
        self.my_targ.enemy = world;                                 // .. and un-set my current target (comment out this line to keep targets even if they go out of range) ..
        return 0;                                                   // .. and signal fail.
    }        
}
Implementation notes:
Unlike the original this function takes a param (range) for how far to look. So instead of "target_system();" you would do "target_system(900)" for the same range as the op code.
This func also returns a status indicating if it had success in locating a target or not. thus you could so sth like

Code: Select all

if(target_system(1234))
{
    ...
}
Above code also store what that 'best target' is as 'self.my_targ.enemy' so you can do further processing.
Post Reply