コード例 #1
0
        /**
         * T_RadiusDamage.
         */
        public static void T_RadiusDamage(edict_t inflictor, edict_t attacker, float damage, edict_t ignore, float radius, int mod)
        {
            float         points;
            EdictIterator edictit = null;

            float[] v   = { 0, 0, 0 };
            float[] dir = { 0, 0, 0 };

            while ((edictit = GameBase.findradius(edictit, inflictor.s.origin, radius)) != null)
            {
                var ent = edictit.o;

                if (ent == ignore)
                {
                    continue;
                }

                if (ent.takedamage == 0)
                {
                    continue;
                }

                Math3D.VectorAdd(ent.mins, ent.maxs, v);
                Math3D.VectorMA(ent.s.origin, 0.5f, v, v);
                Math3D.VectorSubtract(inflictor.s.origin, v, v);
                points = damage - 0.5f * Math3D.VectorLength(v);

                if (ent == attacker)
                {
                    points = points * 0.5f;
                }

                if (points > 0)
                {
                    if (GameCombat.CanDamage(ent, inflictor))
                    {
                        Math3D.VectorSubtract(ent.s.origin, inflictor.s.origin, dir);

                        GameCombat.T_Damage(
                            ent,
                            inflictor,
                            attacker,
                            dir,
                            inflictor.s.origin,
                            Globals.vec3_origin,
                            (int)points,
                            (int)points,
                            Defines.DAMAGE_RADIUS,
                            mod
                            );
                    }
                }
            }
        }
コード例 #2
0
ファイル: GameUtil.cs プロジェクト: optimus-code/Quake2Sharp
        /**
         * Kills all entities that would touch the proposed new positioning of ent.
         * Ent should be unlinked before calling this!
         */
        public static bool KillBox(edict_t ent)
        {
            trace_t tr;

            while (true)
            {
                tr = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs, ent.s.origin, null, Defines.MASK_PLAYERSOLID);

                if (tr.ent == null || tr.ent == GameBase.g_edicts[0])
                {
                    break;
                }

                // nail it
                GameCombat.T_Damage(
                    tr.ent,
                    ent,
                    ent,
                    Globals.vec3_origin,
                    ent.s.origin,
                    Globals.vec3_origin,
                    100000,
                    0,
                    Defines.DAMAGE_NO_PROTECTION,
                    Defines.MOD_TELEFRAG
                    );

                // if we didn't kill it, fail
                if (tr.ent.solid != 0)
                {
                    return(false);
                }
            }

            return(true);            // all clear
        }
コード例 #3
0
        /**
         * General effect handling for a player.
         */
        public static void P_WorldEffects()
        {
            bool breather;
            bool envirosuit;
            int  waterlevel, old_waterlevel;

            if (PlayerView.current_player.movetype == Defines.MOVETYPE_NOCLIP)
            {
                PlayerView.current_player.air_finished = GameBase.level.time + 12;                 // don't

                // need air
                return;
            }

            waterlevel     = PlayerView.current_player.waterlevel;
            old_waterlevel = PlayerView.current_client.old_waterlevel;
            PlayerView.current_client.old_waterlevel = waterlevel;

            breather   = PlayerView.current_client.breather_framenum > GameBase.level.framenum;
            envirosuit = PlayerView.current_client.enviro_framenum > GameBase.level.framenum;

            //
            // if just entered a water volume, play a sound
            //
            if (old_waterlevel == 0 && waterlevel != 0)
            {
                PlayerWeapon.PlayerNoise(PlayerView.current_player, PlayerView.current_player.s.origin, Defines.PNOISE_SELF);

                if ((PlayerView.current_player.watertype & Defines.CONTENTS_LAVA) != 0)
                {
                    GameBase.gi.sound(PlayerView.current_player, Defines.CHAN_BODY, GameBase.gi.soundindex("player/lava_in.wav"), 1, Defines.ATTN_NORM, 0);
                }
                else if ((PlayerView.current_player.watertype & Defines.CONTENTS_SLIME) != 0)
                {
                    GameBase.gi.sound(PlayerView.current_player, Defines.CHAN_BODY, GameBase.gi.soundindex("player/watr_in.wav"), 1, Defines.ATTN_NORM, 0);
                }
                else if ((PlayerView.current_player.watertype & Defines.CONTENTS_WATER) != 0)
                {
                    GameBase.gi.sound(PlayerView.current_player, Defines.CHAN_BODY, GameBase.gi.soundindex("player/watr_in.wav"), 1, Defines.ATTN_NORM, 0);
                }

                PlayerView.current_player.flags |= Defines.FL_INWATER;

                // clear damage_debounce, so the pain sound will play immediately
                PlayerView.current_player.damage_debounce_time = GameBase.level.time - 1;
            }

            //
            // if just completely exited a water volume, play a sound
            //
            if (old_waterlevel != 0 && waterlevel == 0)
            {
                PlayerWeapon.PlayerNoise(PlayerView.current_player, PlayerView.current_player.s.origin, Defines.PNOISE_SELF);
                GameBase.gi.sound(PlayerView.current_player, Defines.CHAN_BODY, GameBase.gi.soundindex("player/watr_out.wav"), 1, Defines.ATTN_NORM, 0);
                PlayerView.current_player.flags &= ~Defines.FL_INWATER;
            }

            //
            // check for head just going under water
            //
            if (old_waterlevel != 3 && waterlevel == 3)
            {
                GameBase.gi.sound(PlayerView.current_player, Defines.CHAN_BODY, GameBase.gi.soundindex("player/watr_un.wav"), 1, Defines.ATTN_NORM, 0);
            }

            //
            // check for head just coming out of water
            //
            if (old_waterlevel == 3 && waterlevel != 3)
            {
                if (PlayerView.current_player.air_finished < GameBase.level.time)
                {
                    // gasp for
                    // air
                    GameBase.gi.sound(PlayerView.current_player, Defines.CHAN_VOICE, GameBase.gi.soundindex("player/gasp1.wav"), 1, Defines.ATTN_NORM, 0);
                    PlayerWeapon.PlayerNoise(PlayerView.current_player, PlayerView.current_player.s.origin, Defines.PNOISE_SELF);
                }
                else if (PlayerView.current_player.air_finished < GameBase.level.time + 11)
                {
                    // just
                    // break
                    // surface
                    GameBase.gi.sound(PlayerView.current_player, Defines.CHAN_VOICE, GameBase.gi.soundindex("player/gasp2.wav"), 1, Defines.ATTN_NORM, 0);
                }
            }

            //
            // check for drowning
            //
            if (waterlevel == 3)
            {
                // breather or envirosuit give air
                if (breather || envirosuit)
                {
                    PlayerView.current_player.air_finished = GameBase.level.time + 10;

                    if ((int)(PlayerView.current_client.breather_framenum - GameBase.level.framenum) % 25 == 0)
                    {
                        if (PlayerView.current_client.breather_sound == 0)
                        {
                            GameBase.gi.sound(
                                PlayerView.current_player,
                                Defines.CHAN_AUTO,
                                GameBase.gi.soundindex("player/u_breath1.wav"),
                                1,
                                Defines.ATTN_NORM,
                                0
                                );
                        }
                        else
                        {
                            GameBase.gi.sound(
                                PlayerView.current_player,
                                Defines.CHAN_AUTO,
                                GameBase.gi.soundindex("player/u_breath2.wav"),
                                1,
                                Defines.ATTN_NORM,
                                0
                                );
                        }

                        PlayerView.current_client.breather_sound ^= 1;
                        PlayerWeapon.PlayerNoise(PlayerView.current_player, PlayerView.current_player.s.origin, Defines.PNOISE_SELF);

                        //FIXME: release a bubble?
                    }
                }

                // if out of air, start drowning
                if (PlayerView.current_player.air_finished < GameBase.level.time)
                {
                    // drown!
                    if (PlayerView.current_player.client.next_drown_time < GameBase.level.time && PlayerView.current_player.health > 0)
                    {
                        PlayerView.current_player.client.next_drown_time = GameBase.level.time + 1;

                        // take more damage the longer underwater
                        PlayerView.current_player.dmg += 2;

                        if (PlayerView.current_player.dmg > 15)
                        {
                            PlayerView.current_player.dmg = 15;
                        }

                        // play a gurp sound instead of a normal pain sound
                        if (PlayerView.current_player.health <= PlayerView.current_player.dmg)
                        {
                            GameBase.gi.sound(
                                PlayerView.current_player,
                                Defines.CHAN_VOICE,
                                GameBase.gi.soundindex("player/drown1.wav"),
                                1,
                                Defines.ATTN_NORM,
                                0
                                );
                        }
                        else if ((Lib.rand() & 1) != 0)
                        {
                            GameBase.gi.sound(PlayerView.current_player, Defines.CHAN_VOICE, GameBase.gi.soundindex("*gurp1.wav"), 1, Defines.ATTN_NORM, 0);
                        }
                        else
                        {
                            GameBase.gi.sound(PlayerView.current_player, Defines.CHAN_VOICE, GameBase.gi.soundindex("*gurp2.wav"), 1, Defines.ATTN_NORM, 0);
                        }

                        PlayerView.current_player.pain_debounce_time = GameBase.level.time;

                        GameCombat.T_Damage(
                            PlayerView.current_player,
                            GameBase.g_edicts[0],
                            GameBase.g_edicts[0],
                            Globals.vec3_origin,
                            PlayerView.current_player.s.origin,
                            Globals.vec3_origin,
                            PlayerView.current_player.dmg,
                            0,
                            Defines.DAMAGE_NO_ARMOR,
                            Defines.MOD_WATER
                            );
                    }
                }
            }
            else
            {
                PlayerView.current_player.air_finished = GameBase.level.time + 12;
                PlayerView.current_player.dmg          = 2;
            }

            //
            // check for sizzle damage
            //
            if (waterlevel != 0 && 0 != (PlayerView.current_player.watertype & (Defines.CONTENTS_LAVA | Defines.CONTENTS_SLIME)))
            {
                if ((PlayerView.current_player.watertype & Defines.CONTENTS_LAVA) != 0)
                {
                    if (PlayerView.current_player.health > 0 &&
                        PlayerView.current_player.pain_debounce_time <= GameBase.level.time &&
                        PlayerView.current_client.invincible_framenum < GameBase.level.framenum)
                    {
                        if ((Lib.rand() & 1) != 0)
                        {
                            GameBase.gi.sound(
                                PlayerView.current_player,
                                Defines.CHAN_VOICE,
                                GameBase.gi.soundindex("player/burn1.wav"),
                                1,
                                Defines.ATTN_NORM,
                                0
                                );
                        }
                        else
                        {
                            GameBase.gi.sound(
                                PlayerView.current_player,
                                Defines.CHAN_VOICE,
                                GameBase.gi.soundindex("player/burn2.wav"),
                                1,
                                Defines.ATTN_NORM,
                                0
                                );
                        }

                        PlayerView.current_player.pain_debounce_time = GameBase.level.time + 1;
                    }

                    if (envirosuit)                     // take 1/3 damage with envirosuit
                    {
                        GameCombat.T_Damage(
                            PlayerView.current_player,
                            GameBase.g_edicts[0],
                            GameBase.g_edicts[0],
                            Globals.vec3_origin,
                            PlayerView.current_player.s.origin,
                            Globals.vec3_origin,
                            1 * waterlevel,
                            0,
                            0,
                            Defines.MOD_LAVA
                            );
                    }
                    else
                    {
                        GameCombat.T_Damage(
                            PlayerView.current_player,
                            GameBase.g_edicts[0],
                            GameBase.g_edicts[0],
                            Globals.vec3_origin,
                            PlayerView.current_player.s.origin,
                            Globals.vec3_origin,
                            3 * waterlevel,
                            0,
                            0,
                            Defines.MOD_LAVA
                            );
                    }
                }

                if ((PlayerView.current_player.watertype & Defines.CONTENTS_SLIME) != 0)
                {
                    if (!envirosuit)
                    {
                        // no damage from slime with envirosuit
                        GameCombat.T_Damage(
                            PlayerView.current_player,
                            GameBase.g_edicts[0],
                            GameBase.g_edicts[0],
                            Globals.vec3_origin,
                            PlayerView.current_player.s.origin,
                            Globals.vec3_origin,
                            1 * waterlevel,
                            0,
                            0,
                            Defines.MOD_SLIME
                            );
                    }
                }
            }
        }
コード例 #4
0
        /**
         * Calculates damage and effect when a player falls down.
         */
        public static void P_FallingDamage(edict_t ent)
        {
            float delta;
            int   damage;

            float[] dir = { 0, 0, 0 };

            if (ent.s.modelindex != 255)
            {
                return;                 // not in the player model
            }
            if (ent.movetype == Defines.MOVETYPE_NOCLIP)
            {
                return;
            }

            if (ent.client.oldvelocity[2] < 0 && ent.velocity[2] > ent.client.oldvelocity[2] && null == ent.groundentity)
            {
                delta = ent.client.oldvelocity[2];
            }
            else
            {
                if (ent.groundentity == null)
                {
                    return;
                }

                delta = ent.velocity[2] - ent.client.oldvelocity[2];
            }

            delta = delta * delta * 0.0001f;

            // never take falling damage if completely underwater
            if (ent.waterlevel == 3)
            {
                return;
            }

            if (ent.waterlevel == 2)
            {
                delta *= 0.25f;
            }

            if (ent.waterlevel == 1)
            {
                delta *= 0.5f;
            }

            if (delta < 1)
            {
                return;
            }

            if (delta < 15)
            {
                ent.s.@event = Defines.EV_FOOTSTEP;

                return;
            }

            ent.client.fall_value = delta * 0.5f;

            if (ent.client.fall_value > 40)
            {
                ent.client.fall_value = 40;
            }

            ent.client.fall_time = GameBase.level.time + Defines.FALL_TIME;

            if (delta > 30)
            {
                if (ent.health > 0)
                {
                    if (delta >= 55)
                    {
                        ent.s.@event = Defines.EV_FALLFAR;
                    }
                    else
                    {
                        ent.s.@event = Defines.EV_FALL;
                    }
                }

                ent.pain_debounce_time = GameBase.level.time;                 // no normal pain

                // sound
                damage = (int)((delta - 30) / 2);

                if (damage < 1)
                {
                    damage = 1;
                }

                Math3D.VectorSet(dir, 0, 0, 1);

                if (GameBase.deathmatch.value == 0 || 0 == ((int)GameBase.dmflags.value & Defines.DF_NO_FALLING))
                {
                    GameCombat.T_Damage(
                        ent,
                        GameBase.g_edicts[0],
                        GameBase.g_edicts[0],
                        dir,
                        ent.s.origin,
                        Globals.vec3_origin,
                        damage,
                        0,
                        0,
                        Defines.MOD_FALLING
                        );
                }
            }
            else
            {
                ent.s.@event = Defines.EV_FALLSHORT;

                return;
            }
        }