예제 #1
0
        // Sbar_SortFrags
        private static void SortFrags()
        {
            client_state_t cl = client.cl;

            // sort by frags
            _ScoreBoardLines = 0;
            for (int i = 0; i < cl.maxclients; i++)
            {
                if (!String.IsNullOrEmpty(cl.scores[i].name))
                {
                    _FragSort[_ScoreBoardLines] = i;
                    _ScoreBoardLines++;
                }
            }

            for (int i = 0; i < _ScoreBoardLines; i++)
            {
                for (int j = 0; j < _ScoreBoardLines - 1 - i; j++)
                {
                    if (cl.scores[_FragSort[j]].frags < cl.scores[_FragSort[j + 1]].frags)
                    {
                        int k = _FragSort[j];
                        _FragSort[j]     = _FragSort[j + 1];
                        _FragSort[j + 1] = k;
                    }
                }
            }
        }
예제 #2
0
        // V_CalcBob
        private static float CalcBob()
        {
            client_state_t cl       = client.cl;
            float          bobCycle = _ClBobCycle.Value;
            float          bobUp    = _ClBobUp.Value;
            float          cycle    = (float)(cl.time - (int)(cl.time / bobCycle) * bobCycle);

            cycle /= bobCycle;
            if (cycle < bobUp)
            {
                cycle = (float)Math.PI * cycle / bobUp;
            }
            else
            {
                cycle = (float)(Math.PI + Math.PI * (cycle - bobUp) / (1.0 - bobUp));
            }

            // bob is proportional to velocity in the xy plane
            // (don't count Z, or jumping messes it up)
            Vector2 tmp = cl.velocity.Xy;
            double  bob = tmp.Length * _ClBob.Value;

            bob = bob * 0.3 + bob * 0.7 * Math.Sin(cycle);
            if (bob > 4)
            {
                bob = 4;
            }
            else if (bob < -7)
            {
                bob = -7;
            }
            return((float)bob);
        }
예제 #3
0
        // Sbar_SoloScoreboard
        private static void SoloScoreboard()
        {
            StringBuilder  sb = new StringBuilder(80);
            client_state_t cl = client.cl;

            sb.AppendFormat("Monsters:{0,3:d} /{1,3:d}", cl.stats[QStats.STAT_MONSTERS], client.cl.stats[QStats.STAT_TOTALMONSTERS]);
            DrawString(8, 4, sb.ToString());

            sb.Length = 0;
            sb.AppendFormat("Secrets :{0,3:d} /{1,3:d}", cl.stats[QStats.STAT_SECRETS], cl.stats[QStats.STAT_TOTALSECRETS]);
            DrawString(8, 12, sb.ToString());

            // time
            int minutes = (int)(cl.time / 60.0);
            int seconds = (int)(cl.time - 60 * minutes);
            int tens    = seconds / 10;
            int units   = seconds - 10 * tens;

            sb.Length = 0;
            sb.AppendFormat("Time :{0,3}:{1}{2}", minutes, tens, units);
            DrawString(184, 4, sb.ToString());

            // draw level name
            int l = cl.levelname.Length;

            DrawString(232 - l * 4, 12, cl.levelname);
        }
예제 #4
0
        // V_StopPitchDrift
        public static void StopPitchDrift()
        {
            client_state_t cl = client.cl;

            cl.laststop = cl.time;
            cl.nodrift  = true;
            cl.pitchvel = 0;
        }
예제 #5
0
        // V_BonusFlash_f
        //
        // When you run over an item, the server sends this command
        private static void BonusFlash_f()
        {
            client_state_t cl = client.cl;

            cl.cshifts[ColorShift.CSHIFT_BONUS].destcolor[0] = 215;
            cl.cshifts[ColorShift.CSHIFT_BONUS].destcolor[1] = 186;
            cl.cshifts[ColorShift.CSHIFT_BONUS].destcolor[2] = 69;
            cl.cshifts[ColorShift.CSHIFT_BONUS].percent      = 50;
        }
예제 #6
0
        // Sbar_DrawFrags
        private static void DrawFrags()
        {
            SortFrags();

            // draw the text
            int            l = _ScoreBoardLines <= 4 ? _ScoreBoardLines : 4;
            int            xofs, x = 23;
            client_state_t cl = client.cl;

            if (cl.gametype == protocol.GAME_DEATHMATCH)
            {
                xofs = 0;
            }
            else
            {
                xofs = (Scr.vid.width - 320) >> 1;
            }

            int y = Scr.vid.height - SBAR_HEIGHT - 23;

            for (int i = 0; i < l; i++)
            {
                int          k = _FragSort[i];
                scoreboard_t s = cl.scores[k];
                if (String.IsNullOrEmpty(s.name))
                {
                    continue;
                }

                // draw background
                int top    = s.colors & 0xf0;
                int bottom = (s.colors & 15) << 4;
                top    = ColorForMap(top);
                bottom = ColorForMap(bottom);

                Drawer.Fill(xofs + x * 8 + 10, y, 28, 4, top);
                Drawer.Fill(xofs + x * 8 + 10, y + 4, 28, 3, bottom);

                // draw number
                int    f   = s.frags;
                string num = f.ToString().PadLeft(3);
                //sprintf(num, "%3i", f);

                DrawCharacter((x + 1) * 8, -24, num[0]);
                DrawCharacter((x + 2) * 8, -24, num[1]);
                DrawCharacter((x + 3) * 8, -24, num[2]);

                if (k == cl.viewentity - 1)
                {
                    DrawCharacter(x * 8 + 2, -24, 16);
                    DrawCharacter((x + 4) * 8 - 4, -24, 17);
                }
                x += 4;
            }
        }
예제 #7
0
        // V_StartPitchDrift
        public static void StartPitchDrift()
        {
            client_state_t cl = client.cl;

            if (cl.laststop == cl.time)
            {
                return; // something else is keeping it from drifting
            }
            if (cl.nodrift || cl.pitchvel == 0)
            {
                cl.pitchvel  = _CenterSpeed.Value;
                cl.nodrift   = false;
                cl.driftmove = 0;
            }
        }
예제 #8
0
        // V_CalcViewRoll
        //
        // Roll is induced by movement and damage
        private static void CalcViewRoll()
        {
            client_state_t cl   = client.cl;
            refdef_t       rdef = render.RefDef;
            float          side = CalcRoll(ref client.ViewEntity.angles, ref cl.velocity);

            rdef.viewangles.Z += side;

            if (_DmgTime > 0)
            {
                rdef.viewangles.Z += _DmgTime / _KickTime.Value * _DmgRoll;
                rdef.viewangles.X += _DmgTime / _KickTime.Value * _DmgPitch;
                _DmgTime          -= (float)host.FrameTime;
            }

            if (cl.stats[QStats.STAT_HEALTH] <= 0)
            {
                rdef.viewangles.Z = 80; // dead view angle
                return;
            }
        }
예제 #9
0
        // V_CalcPowerupCshift
        private static void CalcPowerupCshift()
        {
            client_state_t cl = client.cl;

            if (cl.HasItems(QItems.IT_QUAD))
            {
                cl.cshifts[ColorShift.CSHIFT_POWERUP].destcolor[0] = 0;
                cl.cshifts[ColorShift.CSHIFT_POWERUP].destcolor[1] = 0;
                cl.cshifts[ColorShift.CSHIFT_POWERUP].destcolor[2] = 255;
                cl.cshifts[ColorShift.CSHIFT_POWERUP].percent      = 30;
            }
            else if (cl.HasItems(QItems.IT_SUIT))
            {
                cl.cshifts[ColorShift.CSHIFT_POWERUP].destcolor[0] = 0;
                cl.cshifts[ColorShift.CSHIFT_POWERUP].destcolor[1] = 255;
                cl.cshifts[ColorShift.CSHIFT_POWERUP].destcolor[2] = 0;
                cl.cshifts[ColorShift.CSHIFT_POWERUP].percent      = 20;
            }
            else if (cl.HasItems(QItems.IT_INVISIBILITY))
            {
                cl.cshifts[ColorShift.CSHIFT_POWERUP].destcolor[0] = 100;
                cl.cshifts[ColorShift.CSHIFT_POWERUP].destcolor[1] = 100;
                cl.cshifts[ColorShift.CSHIFT_POWERUP].destcolor[2] = 100;
                cl.cshifts[ColorShift.CSHIFT_POWERUP].percent      = 100;
            }
            else if (cl.HasItems(QItems.IT_INVULNERABILITY))
            {
                cl.cshifts[ColorShift.CSHIFT_POWERUP].destcolor[0] = 255;
                cl.cshifts[ColorShift.CSHIFT_POWERUP].destcolor[1] = 255;
                cl.cshifts[ColorShift.CSHIFT_POWERUP].destcolor[2] = 0;
                cl.cshifts[ColorShift.CSHIFT_POWERUP].percent      = 30;
            }
            else
            {
                cl.cshifts[ColorShift.CSHIFT_POWERUP].percent = 0;
            }
        }
예제 #10
0
        /// <summary>
        /// CalcGunAngle
        /// </summary>
        private static void CalcGunAngle()
        {
            refdef_t rdef  = render.RefDef;
            float    yaw   = rdef.viewangles.Y;
            float    pitch = -rdef.viewangles.X;

            yaw = AngleDelta(yaw - rdef.viewangles.Y) * 0.4f;
            if (yaw > 10)
            {
                yaw = 10;
            }
            if (yaw < -10)
            {
                yaw = -10;
            }
            pitch = AngleDelta(-pitch - rdef.viewangles.X) * 0.4f;
            if (pitch > 10)
            {
                pitch = 10;
            }
            if (pitch < -10)
            {
                pitch = -10;
            }
            float move = (float)host.FrameTime * 20;

            if (yaw > _OldYaw)
            {
                if (_OldYaw + move < yaw)
                {
                    yaw = _OldYaw + move;
                }
            }
            else
            {
                if (_OldYaw - move > yaw)
                {
                    yaw = _OldYaw - move;
                }
            }

            if (pitch > _OldPitch)
            {
                if (_OldPitch + move < pitch)
                {
                    pitch = _OldPitch + move;
                }
            }
            else
            {
                if (_OldPitch - move > pitch)
                {
                    pitch = _OldPitch - move;
                }
            }

            _OldYaw   = yaw;
            _OldPitch = pitch;

            client_state_t cl = client.cl;

            cl.viewent.angles.Y = rdef.viewangles.Y + yaw;
            cl.viewent.angles.X = -(rdef.viewangles.X + pitch);

            float idleScale = _IdleScale.Value;

            cl.viewent.angles.Z -= (float)(idleScale * Math.Sin(cl.time * _IRollCycle.Value) * _IRollLevel.Value);
            cl.viewent.angles.X -= (float)(idleScale * Math.Sin(cl.time * _IPitchCycle.Value) * _IPitchLevel.Value);
            cl.viewent.angles.Y -= (float)(idleScale * Math.Sin(cl.time * _IYawCycle.Value) * _IYawLevel.Value);
        }
예제 #11
0
 public client(Host host)
 {
     Host    = host;
     _Static = new client_static_t();
     _State  = new client_state_t();
 }
예제 #12
0
        // Sbar_DrawInventory
        private static void DrawInventory()
        {
            int flashon;

            client_state_t cl = client.cl;

            if (common.GameKind == GameKind.Rogue)
            {
                if (cl.stats[QStats.STAT_ACTIVEWEAPON] >= QItems.RIT_LAVA_NAILGUN)
                {
                    DrawPic(0, -24, _RInvBar[0]);
                }
                else
                {
                    DrawPic(0, -24, _RInvBar[1]);
                }
            }
            else
            {
                DrawPic(0, -24, _IBar);
            }

            // weapons
            for (int i = 0; i < 7; i++)
            {
                if (cl.HasItems(QItems.IT_SHOTGUN << i))
                {
                    float time = cl.item_gettime[i];
                    flashon = (int)((cl.time - time) * 10);
                    if (flashon >= 10)
                    {
                        if (cl.stats[QStats.STAT_ACTIVEWEAPON] == (QItems.IT_SHOTGUN << i))
                        {
                            flashon = 1;
                        }
                        else
                        {
                            flashon = 0;
                        }
                    }
                    else
                    {
                        flashon = (flashon % 5) + 2;
                    }

                    DrawPic(i * 24, -16, _Weapons[flashon, i]);

                    if (flashon > 1)
                    {
                        _Updates = 0; // force update to remove flash
                    }
                }
            }

            // MED 01/04/97
            // hipnotic weapons
            if (common.GameKind == GameKind.Hipnotic)
            {
                int grenadeflashing = 0;
                for (int i = 0; i < 4; i++)
                {
                    if (cl.HasItems(1 << _HipWeapons[i]))
                    {
                        float time = cl.item_gettime[_HipWeapons[i]];
                        flashon = (int)((cl.time - time) * 10);
                        if (flashon >= 10)
                        {
                            if (cl.stats[QStats.STAT_ACTIVEWEAPON] == (1 << _HipWeapons[i]))
                            {
                                flashon = 1;
                            }
                            else
                            {
                                flashon = 0;
                            }
                        }
                        else
                        {
                            flashon = (flashon % 5) + 2;
                        }

                        // check grenade launcher
                        if (i == 2)
                        {
                            if (cl.HasItems(QItems.HIT_PROXIMITY_GUN))
                            {
                                if (flashon > 0)
                                {
                                    grenadeflashing = 1;
                                    DrawPic(96, -16, _HWeapons[flashon, 2]);
                                }
                            }
                        }
                        else if (i == 3)
                        {
                            if (cl.HasItems(QItems.IT_SHOTGUN << 4))
                            {
                                if (flashon > 0 && grenadeflashing == 0)
                                {
                                    DrawPic(96, -16, _HWeapons[flashon, 3]);
                                }
                                else if (grenadeflashing == 0)
                                {
                                    DrawPic(96, -16, _HWeapons[0, 3]);
                                }
                            }
                            else
                            {
                                DrawPic(96, -16, _HWeapons[flashon, 4]);
                            }
                        }
                        else
                        {
                            DrawPic(176 + (i * 24), -16, _HWeapons[flashon, i]);
                        }
                        if (flashon > 1)
                        {
                            _Updates = 0; // force update to remove flash
                        }
                    }
                }
            }

            if (common.GameKind == GameKind.Rogue)
            {
                // check for powered up weapon.
                if (cl.stats[QStats.STAT_ACTIVEWEAPON] >= QItems.RIT_LAVA_NAILGUN)
                {
                    for (int i = 0; i < 5; i++)
                    {
                        if (cl.stats[QStats.STAT_ACTIVEWEAPON] == (QItems.RIT_LAVA_NAILGUN << i))
                        {
                            DrawPic((i + 2) * 24, -16, _RWeapons[i]);
                        }
                    }
                }
            }

            // ammo counts
            for (int i = 0; i < 4; i++)
            {
                string num = cl.stats[QStats.STAT_SHELLS + i].ToString().PadLeft(3);
                //sprintf(num, "%3i", cl.stats[QStats.STAT_SHELLS + i]);
                if (num[0] != ' ')
                {
                    DrawCharacter((6 * i + 1) * 8 - 2, -24, 18 + num[0] - '0');
                }
                if (num[1] != ' ')
                {
                    DrawCharacter((6 * i + 2) * 8 - 2, -24, 18 + num[1] - '0');
                }
                if (num[2] != ' ')
                {
                    DrawCharacter((6 * i + 3) * 8 - 2, -24, 18 + num[2] - '0');
                }
            }

            flashon = 0;
            // items
            for (int i = 0; i < 6; i++)
            {
                if (cl.HasItems(1 << (17 + i)))
                {
                    float time = cl.item_gettime[17 + i];
                    if (time > 0 && time > cl.time - 2 && flashon > 0)
                    {  // flash frame
                        _Updates = 0;
                    }
                    else
                    {
                        //MED 01/04/97 changed keys
                        if (common.GameKind != GameKind.Hipnotic || (i > 1))
                        {
                            DrawPic(192 + i * 16, -16, _Items[i]);
                        }
                    }
                    if (time > 0 && time > cl.time - 2)
                    {
                        _Updates = 0;
                    }
                }
            }

            //MED 01/04/97 added hipnotic items
            // hipnotic items
            if (common.GameKind == GameKind.Hipnotic)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (cl.HasItems(1 << (24 + i)))
                    {
                        float time = cl.item_gettime[24 + i];
                        if (time > 0 && time > cl.time - 2 && flashon > 0)
                        {  // flash frame
                            _Updates = 0;
                        }
                        else
                        {
                            DrawPic(288 + i * 16, -16, _HItems[i]);
                        }
                        if (time > 0 && time > cl.time - 2)
                        {
                            _Updates = 0;
                        }
                    }
                }
            }

            if (common.GameKind == GameKind.Rogue)
            {
                // new rogue items
                for (int i = 0; i < 2; i++)
                {
                    if (cl.HasItems(1 << (29 + i)))
                    {
                        float time = cl.item_gettime[29 + i];

                        if (time > 0 && time > cl.time - 2 && flashon > 0)
                        {       // flash frame
                            _Updates = 0;
                        }
                        else
                        {
                            DrawPic(288 + i * 16, -16, _RItems[i]);
                        }

                        if (time > 0 && time > cl.time - 2)
                        {
                            _Updates = 0;
                        }
                    }
                }
            }
            else
            {
                // sigils
                for (int i = 0; i < 4; i++)
                {
                    if (cl.HasItems(1 << (28 + i)))
                    {
                        float time = cl.item_gettime[28 + i];
                        if (time > 0 && time > cl.time - 2 && flashon > 0)
                        {       // flash frame
                            _Updates = 0;
                        }
                        else
                        {
                            DrawPic(320 - 32 + i * 8, -16, _Sigil[i]);
                        }
                        if (time > 0 && time > cl.time - 2)
                        {
                            _Updates = 0;
                        }
                    }
                }
            }
        }
예제 #13
0
        // Sbar_Draw
        // called every frame by screen
        public static void Draw()
        {
            viddef_t vid = Scr.vid;

            if (Scr.ConCurrent == vid.height)
            {
                return;         // console is full screen
            }
            if (_Updates >= vid.numpages)
            {
                return;
            }

            Scr.CopyEverithing = true;

            _Updates++;

            if (sbar.Lines > 0 && vid.width > 320)
            {
                Drawer.TileClear(0, vid.height - sbar.Lines, vid.width, sbar.Lines);
            }

            if (sbar.Lines > 24)
            {
                DrawInventory();
                if (client.cl.maxclients != 1)
                {
                    DrawFrags();
                }
            }

            client_state_t cl = client.cl;

            if (_ShowScores || cl.stats[QStats.STAT_HEALTH] <= 0)
            {
                DrawPic(0, 0, _ScoreBar);
                DrawScoreboard();
                _Updates = 0;
            }
            else if (sbar.Lines > 0)
            {
                DrawPic(0, 0, _SBar);

                // keys (hipnotic only)
                //MED 01/04/97 moved keys here so they would not be overwritten
                if (common.GameKind == GameKind.Hipnotic)
                {
                    if (cl.HasItems(QItems.IT_KEY1))
                    {
                        DrawPic(209, 3, _Items[0]);
                    }
                    if (cl.HasItems(QItems.IT_KEY2))
                    {
                        DrawPic(209, 12, _Items[1]);
                    }
                }
                // armor
                if (cl.HasItems(QItems.IT_INVULNERABILITY))
                {
                    DrawNum(24, 0, 666, 3, 1);
                    DrawPic(0, 0, Drawer.Disc);
                }
                else
                {
                    if (common.GameKind == GameKind.Rogue)
                    {
                        DrawNum(24, 0, cl.stats[QStats.STAT_ARMOR], 3, cl.stats[QStats.STAT_ARMOR] <= 25 ? 1 : 0);   // uze: corrected color param
                        if (cl.HasItems(QItems.RIT_ARMOR3))
                        {
                            DrawPic(0, 0, _Armor[2]);
                        }
                        else if (cl.HasItems(QItems.RIT_ARMOR2))
                        {
                            DrawPic(0, 0, _Armor[1]);
                        }
                        else if (cl.HasItems(QItems.RIT_ARMOR1))
                        {
                            DrawPic(0, 0, _Armor[0]);
                        }
                    }
                    else
                    {
                        DrawNum(24, 0, cl.stats[QStats.STAT_ARMOR], 3, cl.stats[QStats.STAT_ARMOR] <= 25 ? 1 : 0);
                        if (cl.HasItems(QItems.IT_ARMOR3))
                        {
                            DrawPic(0, 0, _Armor[2]);
                        }
                        else if (cl.HasItems(QItems.IT_ARMOR2))
                        {
                            DrawPic(0, 0, _Armor[1]);
                        }
                        else if (cl.HasItems(QItems.IT_ARMOR1))
                        {
                            DrawPic(0, 0, _Armor[0]);
                        }
                    }
                }

                // face
                DrawFace();

                // health
                DrawNum(136, 0, cl.stats[QStats.STAT_HEALTH], 3, cl.stats[QStats.STAT_HEALTH] <= 25 ? 1 : 0);

                // ammo icon
                if (common.GameKind == GameKind.Rogue)
                {
                    if (cl.HasItems(QItems.RIT_SHELLS))
                    {
                        DrawPic(224, 0, _Ammo[0]);
                    }
                    else if (cl.HasItems(QItems.RIT_NAILS))
                    {
                        DrawPic(224, 0, _Ammo[1]);
                    }
                    else if (cl.HasItems(QItems.RIT_ROCKETS))
                    {
                        DrawPic(224, 0, _Ammo[2]);
                    }
                    else if (cl.HasItems(QItems.RIT_CELLS))
                    {
                        DrawPic(224, 0, _Ammo[3]);
                    }
                    else if (cl.HasItems(QItems.RIT_LAVA_NAILS))
                    {
                        DrawPic(224, 0, _RAmmo[0]);
                    }
                    else if (cl.HasItems(QItems.RIT_PLASMA_AMMO))
                    {
                        DrawPic(224, 0, _RAmmo[1]);
                    }
                    else if (cl.HasItems(QItems.RIT_MULTI_ROCKETS))
                    {
                        DrawPic(224, 0, _RAmmo[2]);
                    }
                }
                else
                {
                    if (cl.HasItems(QItems.IT_SHELLS))
                    {
                        DrawPic(224, 0, _Ammo[0]);
                    }
                    else if (cl.HasItems(QItems.IT_NAILS))
                    {
                        DrawPic(224, 0, _Ammo[1]);
                    }
                    else if (cl.HasItems(QItems.IT_ROCKETS))
                    {
                        DrawPic(224, 0, _Ammo[2]);
                    }
                    else if (cl.HasItems(QItems.IT_CELLS))
                    {
                        DrawPic(224, 0, _Ammo[3]);
                    }
                }

                DrawNum(248, 0, cl.stats[QStats.STAT_AMMO], 3, cl.stats[QStats.STAT_AMMO] <= 10 ? 1 : 0);
            }

            if (vid.width > 320)
            {
                if (client.cl.gametype == protocol.GAME_DEATHMATCH)
                {
                    MiniDeathmatchOverlay();
                }
            }
        }
예제 #14
0
        // V_DriftPitch
        //
        // Moves the client pitch angle towards cl.idealpitch sent by the server.
        //
        // If the user is adjusting pitch manually, either with lookup/lookdown,
        // mlook and mouse, or klook and keyboard, pitch drifting is constantly stopped.
        //
        // Drifting is enabled when the center view key is hit, mlook is released and
        // lookspring is non 0, or when
        private static void DriftPitch()
        {
            client_state_t cl = client.cl;

            if (host.NoClipAngleHack || !cl.onground || client.cls.demoplayback)
            {
                cl.driftmove = 0;
                cl.pitchvel  = 0;
                return;
            }

            // don't count small mouse motion
            if (cl.nodrift)
            {
                if (Math.Abs(cl.cmd.forwardmove) < client.ForwardSpeed)
                {
                    cl.driftmove = 0;
                }
                else
                {
                    cl.driftmove += (float)host.FrameTime;
                }

                if (cl.driftmove > _CenterMove.Value)
                {
                    StartPitchDrift();
                }
                return;
            }

            float delta = cl.idealpitch - cl.viewangles.X;

            if (delta == 0)
            {
                cl.pitchvel = 0;
                return;
            }

            float move = (float)host.FrameTime * cl.pitchvel;

            cl.pitchvel += (float)host.FrameTime * _CenterSpeed.Value;

            if (delta > 0)
            {
                if (move > delta)
                {
                    cl.pitchvel = 0;
                    move        = delta;
                }
                cl.viewangles.X += move;
            }
            else if (delta < 0)
            {
                if (move > -delta)
                {
                    cl.pitchvel = 0;
                    move        = -delta;
                }
                cl.viewangles.X -= move;
            }
        }
예제 #15
0
        // V_CalcRefdef
        private static void CalcRefDef()
        {
            DriftPitch();

            // ent is the player model (visible when out of body)
            entity_t ent = client.ViewEntity;
            // view is the weapon model (only visible from inside body)
            entity_t view = client.ViewEnt;

            // transform the view offset by the model's matrix to get the offset from
            // model origin for the view
            ent.angles.Y = client.cl.viewangles.Y;      // the model should face the view dir
            ent.angles.X = -client.cl.viewangles.X;     // the model should face the view dir

            float bob = CalcBob();

            refdef_t       rdef = render.RefDef;
            client_state_t cl   = client.cl;

            // refresh position
            rdef.vieworg    = ent.origin;
            rdef.vieworg.Z += cl.viewheight + bob;

            // never let it sit exactly on a node line, because a water plane can
            // dissapear when viewed with the eye exactly on it.
            // the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis
            rdef.vieworg   += SmallOffset;
            rdef.viewangles = cl.viewangles;

            CalcViewRoll();
            AddIdle(_IdleScale.Value);

            // offsets
            Vector3 angles = ent.angles;

            angles.X = -angles.X; // because entity pitches are actually backward

            Vector3 forward, right, up;

            mathlib.AngleVectors(ref angles, out forward, out right, out up);

            rdef.vieworg += forward * _ScrOfsX.Value + right * _ScrOfsY.Value + up * _ScrOfsZ.Value;

            BoundOffsets();

            // set up gun position
            view.angles = cl.viewangles;

            CalcGunAngle();

            view.origin    = ent.origin;
            view.origin.Z += cl.viewheight;
            view.origin   += forward * bob * 0.4f;
            view.origin.Z += bob;

            // fudge position around to keep amount of weapon visible
            // roughly equal with different FOV
            float viewSize = Scr.ViewSize.Value; // scr_viewsize

            if (viewSize == 110)
            {
                view.origin.Z += 1;
            }
            else if (viewSize == 100)
            {
                view.origin.Z += 2;
            }
            else if (viewSize == 90)
            {
                view.origin.Z += 1;
            }
            else if (viewSize == 80)
            {
                view.origin.Z += 0.5f;
            }

            view.model    = cl.model_precache[cl.stats[QStats.STAT_WEAPON]];
            view.frame    = cl.stats[QStats.STAT_WEAPONFRAME];
            view.colormap = Scr.vid.colormap;

            // set up the refresh position
            rdef.viewangles += cl.punchangle;

            // smooth out stair step ups
            if (cl.onground && ent.origin.Z - _OldZ > 0)
            {
                float steptime = (float)(cl.time - cl.oldtime);
                if (steptime < 0)
                {
                    steptime = 0;
                }

                _OldZ += steptime * 80;
                if (_OldZ > ent.origin.Z)
                {
                    _OldZ = ent.origin.Z;
                }
                if (ent.origin.Z - _OldZ > 12)
                {
                    _OldZ = ent.origin.Z - 12;
                }
                rdef.vieworg.Z += _OldZ - ent.origin.Z;
                view.origin.Z  += _OldZ - ent.origin.Z;
            }
            else
            {
                _OldZ = ent.origin.Z;
            }

            if (chase.IsActive)
            {
                chase.Update();
            }
        }
예제 #16
0
        // Sbar_DrawFace
        private static void DrawFace()
        {
            client_state_t cl = client.cl;

            // PGM 01/19/97 - team color drawing
            // PGM 03/02/97 - fixed so color swatch only appears in CTF modes
            if (common.GameKind == GameKind.Rogue &&
                (client.cl.maxclients != 1) &&
                (host.TeamPlay > 3) &&
                (host.TeamPlay < 7))
            {
                scoreboard_t s = cl.scores[cl.viewentity - 1];

                // draw background
                int top    = s.colors & 0xf0;
                int bottom = (s.colors & 15) << 4;
                top    = ColorForMap(top);
                bottom = ColorForMap(bottom);

                int xofs;
                if (cl.gametype == protocol.GAME_DEATHMATCH)
                {
                    xofs = 113;
                }
                else
                {
                    xofs = ((Scr.vid.width - 320) >> 1) + 113;
                }

                DrawPic(112, 0, _RTeamBord);
                Drawer.Fill(xofs, Scr.vid.height - SBAR_HEIGHT + 3, 22, 9, top);
                Drawer.Fill(xofs, Scr.vid.height - SBAR_HEIGHT + 12, 22, 9, bottom);

                // draw number
                string num = s.frags.ToString().PadLeft(3);
                if (top == 8)
                {
                    if (num[0] != ' ')
                    {
                        DrawCharacter(109, 3, 18 + num[0] - '0');
                    }
                    if (num[1] != ' ')
                    {
                        DrawCharacter(116, 3, 18 + num[1] - '0');
                    }
                    if (num[2] != ' ')
                    {
                        DrawCharacter(123, 3, 18 + num[2] - '0');
                    }
                }
                else
                {
                    DrawCharacter(109, 3, num[0]);
                    DrawCharacter(116, 3, num[1]);
                    DrawCharacter(123, 3, num[2]);
                }

                return;
            }
            // PGM 01/19/97 - team color drawing

            int f, anim;

            if (cl.HasItems(QItems.IT_INVISIBILITY | QItems.IT_INVULNERABILITY))
            {
                DrawPic(112, 0, _FaceInvisInvuln);
                return;
            }
            if (cl.HasItems(QItems.IT_QUAD))
            {
                DrawPic(112, 0, _FaceQuad);
                return;
            }
            if (cl.HasItems(QItems.IT_INVISIBILITY))
            {
                DrawPic(112, 0, _FaceInvis);
                return;
            }
            if (cl.HasItems(QItems.IT_INVULNERABILITY))
            {
                DrawPic(112, 0, _FaceInvuln);
                return;
            }

            if (cl.stats[QStats.STAT_HEALTH] >= 100)
            {
                f = 4;
            }
            else
            {
                f = cl.stats[QStats.STAT_HEALTH] / 20;
            }

            if (cl.time <= cl.faceanimtime)
            {
                anim     = 1;
                _Updates = 0; // make sure the anim gets drawn over
            }
            else
            {
                anim = 0;
            }

            DrawPic(112, 0, _Faces[f, anim]);
        }
예제 #17
0
        // V_ParseDamage
        public static void ParseDamage()
        {
            int     armor = net.Reader.ReadByte();
            int     blood = net.Reader.ReadByte();
            Vector3 from  = net.Reader.ReadCoords();

            float count = blood * 0.5f + armor * 0.5f;

            if (count < 10)
            {
                count = 10;
            }

            client_state_t cl = client.cl;

            cl.faceanimtime = (float)cl.time + 0.2f; // put sbar face into pain frame

            cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent += (int)(3 * count);
            if (cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent < 0)
            {
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent = 0;
            }
            if (cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent > 150)
            {
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent = 150;
            }

            if (armor > blood)
            {
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[0] = 200;
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[1] = 100;
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[2] = 100;
            }
            else if (armor != 0)
            {
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[0] = 220;
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[1] = 50;
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[2] = 50;
            }
            else
            {
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[0] = 255;
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[1] = 0;
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[2] = 0;
            }

            //
            // calculate view angle kicks
            //
            entity_t ent = client.Entities[cl.viewentity];

            from -= ent.origin; //  VectorSubtract (from, ent->origin, from);
            mathlib.Normalize(ref from);

            Vector3 forward, right, up;

            mathlib.AngleVectors(ref ent.angles, out forward, out right, out up);

            float side = Vector3.Dot(from, right);

            _DmgRoll = count * side * _KickRoll.Value;

            side      = Vector3.Dot(from, forward);
            _DmgPitch = count * side * _KickPitch.Value;

            _DmgTime = _KickTime.Value;
        }
예제 #18
0
        // V_UpdatePalette
        public static void UpdatePalette()
        {
            CalcPowerupCshift();

            bool isnew = false;

            client_state_t cl = client.cl;

            for (int i = 0; i < ColorShift.NUM_CSHIFTS; i++)
            {
                if (cl.cshifts[i].percent != cl.prev_cshifts[i].percent)
                {
                    isnew = true;
                    cl.prev_cshifts[i].percent = cl.cshifts[i].percent;
                }
                for (int j = 0; j < 3; j++)
                {
                    if (cl.cshifts[i].destcolor[j] != cl.prev_cshifts[i].destcolor[j])
                    {
                        isnew = true;
                        cl.prev_cshifts[i].destcolor[j] = cl.cshifts[i].destcolor[j];
                    }
                }
            }

            // drop the damage value
            cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent -= (int)(host.FrameTime * 150);
            if (cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent < 0)
            {
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent = 0;
            }

            // drop the bonus value
            cl.cshifts[ColorShift.CSHIFT_BONUS].percent -= (int)(host.FrameTime * 100);
            if (cl.cshifts[ColorShift.CSHIFT_BONUS].percent < 0)
            {
                cl.cshifts[ColorShift.CSHIFT_BONUS].percent = 0;
            }

            bool force = CheckGamma();

            if (!isnew && !force)
            {
                return;
            }

            CalcBlend();

            float a = Blend.A;
            float r = 255 * Blend.R * a;
            float g = 255 * Blend.G * a;
            float b = 255 * Blend.B * a;

            a = 1 - a;
            for (int i = 0; i < 256; i++)
            {
                int ir = (int)(i * a + r);
                int ig = (int)(i * a + g);
                int ib = (int)(i * a + b);
                if (ir > 255)
                {
                    ir = 255;
                }
                if (ig > 255)
                {
                    ig = 255;
                }
                if (ib > 255)
                {
                    ib = 255;
                }

                _Ramps[0, i] = _GammaTable[ir];
                _Ramps[1, i] = _GammaTable[ig];
                _Ramps[2, i] = _GammaTable[ib];
            }

            byte[] basepal = host.BasePal;
            int    offset  = 0;

            byte[] newpal = new byte[768];

            for (int i = 0; i < 256; i++)
            {
                int ir = basepal[offset + 0];
                int ig = basepal[offset + 1];
                int ib = basepal[offset + 2];

                newpal[offset + 0] = _Ramps[0, ir];
                newpal[offset + 1] = _Ramps[1, ig];
                newpal[offset + 2] = _Ramps[2, ib];

                offset += 3;
            }

            ShiftPalette(newpal);
        }