3
\$\begingroup\$

In Xonotic for some kills (and maybe even just hits?) the game plays a sound clip saying "Impressive!". I was wondering how does the game recognize that a kill was impressive. In Xonotic it feels like giving larger damage faster (somehow) increases a probability of this announcement.

Does anyone know how are these things implemented? I can imagine it being easy(-ish) for hitscan weapons like a sniper rifle, where I can just take how fast was the target going across my screen and score the hit based on this. But what about rocket launchers where it might take time before shooting and hitting? I can't think of any reasonable rule for this.

In particular I'm trying to fit this idea onto a fast top down shooter with keyboard movement and mouse aiming and with weapons similar to Xonotic or UT99.

What exactly I'm interested in:

  • How do existing algorithms for detecting interesting hits / kills work?
  • Do these handle non-hitscan weapons?
  • How can they be extended to support them non-hitscan if they don't?
\$\endgroup\$
  • \$\begingroup\$ We can't answer something that you are not even sure what you are asking. \$\endgroup\$ – DH. Dec 9 '16 at 18:13
  • \$\begingroup\$ I am sure what I'm asking :) I'll try to clarify the question. \$\endgroup\$ – cube Dec 9 '16 at 18:15
  • 1
    \$\begingroup\$ My first guess is that each entity has a value/worth, if the value >= x, It's worth a notification. Damage notifications could also be done the same way, in that any damage over a certain threshold will yield a notification, such as Overkill or what have you. \$\endgroup\$ – Krythic Dec 9 '16 at 18:54
  • 1
    \$\begingroup\$ It's generally difficult for us to answer "how does game X implement Y" - unless you happen to catch someone who worked on game X, it ends up being speculation. And even if you learn that they implemented Y using "method Z," that doesn't mean method Z is the right choice for the game you're making. It's often more constructive to ask about implementing the feature in terms of your own game. What kinds of kill mechanics do you have? As a creator and player of your game, what kinds of kills do you find interesting? Describe that, and we can help you with algorithms to detect these cases. \$\endgroup\$ – DMGregory Dec 9 '16 at 19:43
  • \$\begingroup\$ @DMGregory This particular game is open source. \$\endgroup\$ – Dan Dec 9 '16 at 21:36
11
\$\begingroup\$

Well, I didn't, but fortunately for us Xonotic is open source.

A quick grep for the word impressive told me it is an announcement message:

MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_IMPRESSIVE, CH_INFO, "impressive", VOL_BASEVOICE, ATTEN_NONE)

It also shows up in w_vaporizer.qc and w_vortex.qc which I can only assume are the names of two of the weapons in this game.

A stripped version of W_Vaporizer_Attack looks like this:

void W_Vaporizer_Attack(void)
{
    damage_goodhits = 0;
    FireRailgunBullet(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, 10000, 800, 0, 0, 0, 0, WEP_VAPORIZER);

    if(damage_goodhits && self.vaporizer_lasthit)
    {
        Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_ACHIEVEMENT_IMPRESSIVE);
        damage_goodhits = 0; // only every second time
    }

    self.vaporizer_lasthit = damage_goodhits;
}

A stripped version of W_Vortex_Attack looks incredibly similar:

void W_Vortex_Attack(float issecondary)
{
    damage_goodhits = 0;
    FireRailgunBullet(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, WEP_VORTEX);

    if(damage_goodhits && self.vortex_lasthit)
    {
        Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_ACHIEVEMENT_IMPRESSIVE);
        damage_goodhits = 0; // only every second time
    }

    self.vortex_lasthit = damage_goodhits;
}

But what is damage_goodhits? That can be found in the server source file g_damage.qc:

if(targ != attacker)
{
    entity victim;
    if((targ.vehicle_flags & VHF_ISVEHICLE) && targ.owner)
        victim = targ.owner;
    else
        victim = targ;

    if(IS_PLAYER(victim) || (victim.turrcaps_flags & TFL_TURRCAPS_ISTURRET) || (victim.flags & FL_MONSTER))
    {
        if(DIFF_TEAM(victim, attacker) && !victim.frozen)
        {
            if(damage > 0)
            {
                damage_goodhits += 1;
                damage_gooddamage += damage;
            }
        }
    }
}

So to trigger the "Impressive" achievement in Xonotic you must:

  • Be using the Vaporizer or Vortex weapon.
  • Be shooting at a player, a vehicle containing a player, a turret, or a monster.
  • The target must not be yourself.
  • The target must be on a different team.
  • The target must not be frozen.
  • You must successfully hit the target twice consecutively with the same weapon.

If you want to answer more questions like this, you can acquire Xonotic's source code via their Download page: http://www.xonotic.org/download/

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.