Пример #1
0
        /// <summary>
        /// SV_CloseEnough
        /// </summary>
        private Boolean CloseEnough(MemoryEdict ent, MemoryEdict goal, Single dist)
        {
            if (goal.v.absmin.x > ent.v.absmax.x + dist)
            {
                return(false);
            }
            if (goal.v.absmin.y > ent.v.absmax.y + dist)
            {
                return(false);
            }
            if (goal.v.absmin.z > ent.v.absmax.z + dist)
            {
                return(false);
            }

            if (goal.v.absmax.x < ent.v.absmin.x - dist)
            {
                return(false);
            }
            if (goal.v.absmax.y < ent.v.absmin.y - dist)
            {
                return(false);
            }
            if (goal.v.absmax.z < ent.v.absmin.z - dist)
            {
                return(false);
            }

            return(true);
        }
Пример #2
0
        /// <summary>
        /// SV_StepDirection
        /// Turns to the movement direction, and walks the current distance if facing it.
        /// </summary>
        private bool StepDirection(MemoryEdict ent, float yaw, float dist)
        {
            ent.v.ideal_yaw = yaw;
            this.Host.ProgramsBuiltIn.PF_changeyaw();

            yaw = ( float )(yaw * Math.PI * 2.0 / 360);
            Vector3 move;

            move.X = ( float )Math.Cos(yaw) * dist;
            move.Y = ( float )Math.Sin(yaw) * dist;
            move.Z = 0;

            var oldorigin = ent.v.origin;

            if (this.MoveStep(ent, ref move, false))
            {
                var delta = ent.v.angles.Y - ent.v.ideal_yaw;
                if (delta > 45 && delta < 315)
                {
                    // not turned far enough, so don't take the step
                    ent.v.origin = oldorigin;
                }

                this.LinkEdict(ent, true);
                return(true);
            }

            this.LinkEdict(ent, true);

            return(false);
        }
Пример #3
0
        /// <summary>
        /// SV_StepDirection
        /// Turns to the movement direction, and walks the current distance if facing it.
        /// </summary>
        private Boolean StepDirection(MemoryEdict ent, Single yaw, Single dist)
        {
            ent.v.ideal_yaw = yaw;
            Host.ProgramsBuiltIn.PF_changeyaw();

            yaw = ( Single )(yaw * Math.PI * 2.0 / 360);
            Vector3f move;

            move.x = ( Single )Math.Cos(yaw) * dist;
            move.y = ( Single )Math.Sin(yaw) * dist;
            move.z = 0;

            var oldorigin = ent.v.origin;

            if (MoveStep(ent, ref move, false))
            {
                var delta = ent.v.angles.y - ent.v.ideal_yaw;
                if (delta > 45 && delta < 315)
                {
                    // not turned far enough, so don't take the step
                    ent.v.origin = oldorigin;
                }
                LinkEdict(ent, true);
                return(true);
            }
            LinkEdict(ent, true);

            return(false);
        }
Пример #4
0
		/// <summary>
		/// SV_Physics_Pusher
		/// </summary>
		private void Physics_Pusher( MemoryEdict ent )
		{
			var oldltime = ent.v.ltime;
			var thinktime = ent.v.nextthink;
			Single movetime;
			if ( thinktime < ent.v.ltime + Host.FrameTime )
			{
				movetime = thinktime - ent.v.ltime;
				if ( movetime < 0 )
					movetime = 0;
			}
			else
				movetime = ( Single ) Host.FrameTime;

			if ( movetime != 0 )
			{
				PushMove( ent, movetime );  // advances ent.v.ltime if not blocked
			}

			if ( thinktime > oldltime && thinktime <= ent.v.ltime )
			{
				ent.v.nextthink = 0;
				Host.Programs.GlobalStruct.time = ( Single ) sv.time;
				Host.Programs.GlobalStruct.self = EdictToProg( ent );
				Host.Programs.GlobalStruct.other = EdictToProg( sv.edicts[0] );
				Host.Programs.Execute( ent.v.think );
				if ( ent.free )
					return;
			}
		}
Пример #5
0
        private void WriteClientPunches(MemoryEdict ent, MessageWriter msg, int bits)
        {
            if ((bits & ProtocolDef.SU_PUNCH1) != 0)
            {
                msg.WriteChar(( int )ent.v.punchangle.X);
            }
            if ((bits & ProtocolDef.SU_VELOCITY1) != 0)
            {
                msg.WriteChar(( int )(ent.v.velocity.X / 16));
            }

            if ((bits & ProtocolDef.SU_PUNCH2) != 0)
            {
                msg.WriteChar(( int )ent.v.punchangle.Y);
            }
            if ((bits & ProtocolDef.SU_VELOCITY2) != 0)
            {
                msg.WriteChar(( int )(ent.v.velocity.Y / 16));
            }

            if ((bits & ProtocolDef.SU_PUNCH3) != 0)
            {
                msg.WriteChar(( int )ent.v.punchangle.Z);
            }
            if ((bits & ProtocolDef.SU_VELOCITY3) != 0)
            {
                msg.WriteChar(( int )(ent.v.velocity.Z / 16));
            }
        }
Пример #6
0
        /// <summary>
        /// SV_CheckWaterTransition
        /// </summary>
        private void CheckWaterTransition(MemoryEdict ent)
        {
            var org  = Utilities.ToVector(ref ent.v.origin);
            var cont = PointContents(ref org);

            if (ent.v.watertype == 0)
            {
                // just spawned here
                ent.v.watertype  = cont;
                ent.v.waterlevel = 1;
                return;
            }

            if (cont <= ( Int32 )Q1Contents.Water)
            {
                if (ent.v.watertype == ( Int32 )Q1Contents.Empty)
                {
                    // just crossed into water
                    StartSound(ent, 0, "misc/h2ohit1.wav", 255, 1);
                }
                ent.v.watertype  = cont;
                ent.v.waterlevel = 1;
            }
            else
            {
                if (ent.v.watertype != ( Int32 )Q1Contents.Empty)
                {
                    // just crossed into water
                    StartSound(ent, 0, "misc/h2ohit1.wav", 255, 1);
                }
                ent.v.watertype  = ( Int32 )Q1Contents.Empty;
                ent.v.waterlevel = cont;
            }
        }
Пример #7
0
        /// <summary>
        /// SV_Physics_Step
        /// </summary>
        private void Physics_Step(MemoryEdict ent)
        {
            Boolean hitsound;

            // freefall if not onground
            if ((( Int32 )ent.v.flags & (EdictFlags.FL_ONGROUND | EdictFlags.FL_FLY | EdictFlags.FL_SWIM)) == 0)
            {
                if (ent.v.velocity.z < Host.Cvars.Gravity.Get <Single>() * -0.1)
                {
                    hitsound = true;
                }
                else
                {
                    hitsound = false;
                }

                AddGravity(ent);
                CheckVelocity(ent);
                FlyMove(ent, ( Single )Host.FrameTime, null);
                LinkEdict(ent, true);

                if ((( Int32 )ent.v.flags & EdictFlags.FL_ONGROUND) != 0)                       // just hit ground
                {
                    if (hitsound)
                    {
                        StartSound(ent, 0, "demon/dland2.wav", 255, 1);
                    }
                }
            }

            // regular thinking
            RunThink(ent);

            CheckWaterTransition(ent);
        }
Пример #8
0
        /// <summary>
        /// SV_WriteClientdataToMessage
        /// </summary>
        public void WriteClientDataToMessage(MemoryEdict ent, MessageWriter msg)
        {
            //
            // send a damage message
            //
            this.WriteClientDamageMessage(ent, msg);

            //
            // send the current viewpos offset from the view entity
            //
            this.SetIdealPitch();                    // how much to look up / down ideally

            // a fixangle might get lost in a dropped packet.  Oh well.
            this.WriteClientFixAngle(ent, msg);

            var bits = this.GenerateClientBits(ent, out var items);

            // send the data
            this.WriteClientHeader(msg, bits);
            this.WriteClientView(ent, msg, bits);
            this.WriteClientPunches(ent, msg, bits);

            // always sent
            this.WriteClientItems(ent, msg, items, bits);
            this.WriteClientHealth(ent, msg);
            this.WriteClientAmmo(ent, msg);
            this.WriteClientWeapons(ent, msg);
        }
Пример #9
0
        /// <summary>
        /// PushEntity
        /// Does not change the entities velocity at all
        /// </summary>
        private Trace_t PushEntity(MemoryEdict ent, ref Vector3f push)
        {
            Vector3f end;

            MathLib.VectorAdd(ref ent.v.origin, ref push, out end);

            Trace_t trace;

            if (ent.v.movetype == Movetypes.MOVETYPE_FLYMISSILE)
            {
                trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref end, MOVE_MISSILE, ent);
            }
            else if (ent.v.solid == Solids.SOLID_TRIGGER || ent.v.solid == Solids.SOLID_NOT)
            {
                // only clip against bmodels
                trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref end, MOVE_NOMONSTERS, ent);
            }
            else
            {
                trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref end, MOVE_NORMAL, ent);
            }

            MathLib.Copy(ref trace.endpos, out ent.v.origin);
            LinkEdict(ent, true);

            if (trace.ent != null)
            {
                Impact(ent, trace.ent);
            }

            return(trace);
        }
Пример #10
0
        /// <summary>
        /// SV_Physics_Step
        /// </summary>
        private void Physics_Step(MemoryEdict ent)
        {
            bool hitsound;

            // freefall if not onground
            if ((( int )ent.v.flags & (EdictFlags.FL_ONGROUND | EdictFlags.FL_FLY | EdictFlags.FL_SWIM)) == 0)
            {
                if (ent.v.velocity.Z < this.Host.Cvars.Gravity.Get <float>() * -0.1)
                {
                    hitsound = true;
                }
                else
                {
                    hitsound = false;
                }

                this.AddGravity(ent);
                this.CheckVelocity(ent);
                this.FlyMove(ent, ( float )this.Host.FrameTime, null);
                this.LinkEdict(ent, true);

                if ((( int )ent.v.flags & EdictFlags.FL_ONGROUND) != 0)                       // just hit ground
                {
                    if (hitsound)
                    {
                        this.StartSound(ent, 0, "demon/dland2.wav", 255, 1);
                    }
                }
            }

            // regular thinking
            this.RunThink(ent);

            this.CheckWaterTransition(ent);
        }
Пример #11
0
        private Boolean TryRandomChaseDir(Single turnaround, MemoryEdict actor, Single dist)
        {
            if ((MathLib.Random() & 1) != 0)                    //randomly determine direction of search
            {
                for (var tdir = 0; tdir <= 315; tdir += 45)
                {
                    if (tdir != turnaround && StepDirection(actor, tdir, dist))
                    {
                        return(false);
                    }
                }
            }
            else
            {
                for (var tdir = 315; tdir >= 0; tdir -= 45)
                {
                    if (tdir != turnaround && StepDirection(actor, tdir, dist))
                    {
                        return(false);
                    }
                }
            }

            if (turnaround != DI_NODIR && StepDirection(actor, turnaround, dist))
            {
                return(false);
            }

            return(true);
        }
Пример #12
0
		/// <summary>
		/// SV_CheckStuck
		/// This is a big hack to try and fix the rare case of getting stuck in the world
		/// clipping hull.
		/// </summary>
		private void CheckStuck( MemoryEdict ent )
		{
			if ( TestEntityPosition( ent ) == null )
			{
				ent.v.oldorigin = ent.v.origin;
				return;
			}

			var org = ent.v.origin;
			ent.v.origin = ent.v.oldorigin;
			if ( TestEntityPosition( ent ) == null )
			{
				Host.Console.DPrint( "Unstuck.\n" );
				LinkEdict( ent, true );
				return;
			}

			for ( var z = 0; z < 18; z++ )
				for ( var i = -1; i <= 1; i++ )
					for ( var j = -1; j <= 1; j++ )
					{
						ent.v.origin.x = org.x + i;
						ent.v.origin.y = org.y + j;
						ent.v.origin.z = org.z + z;
						if ( TestEntityPosition( ent ) == null )
						{
							Host.Console.DPrint( "Unstuck.\n" );
							LinkEdict( ent, true );
							return;
						}
					}

			ent.v.origin = org;
			Host.Console.DPrint( "player is stuck.\n" );
		}
Пример #13
0
        /// <summary>
        /// SV_RunClients
        /// </summary>
        public void RunClients()
        {
            for (var i = 0; i < this.svs.maxclients; i++)
            {
                this.Host.HostClient = this.svs.clients[i];
                if (!this.Host.HostClient.active)
                {
                    continue;
                }

                this._Player = this.Host.HostClient.edict;

                if (!this.ReadClientMessage())
                {
                    this.DropClient(false);     // client misbehaved...
                    continue;
                }

                if (!this.Host.HostClient.spawned)
                {
                    // clear client movement until a new packet is received
                    this.Host.HostClient.cmd.Clear();
                    continue;
                }

                // always pause in single player if in console or menus
                if (!this.sv.paused && (this.svs.maxclients > 1 || this.Host.Keyboard.Destination == KeyDestination.key_game))
                {
                    this.ClientThink();
                }
            }
        }
Пример #14
0
        /// <summary>
        /// SV_ClipMoveToEntity
        /// Handles selection or creation of a clipping hull, and offseting (and
        /// eventually rotation) of the end points
        /// </summary>
        private Trace_t ClipMoveToEntity(MemoryEdict ent, ref Vector3 start, ref Vector3 mins, ref Vector3 maxs, ref Vector3 end)
        {
            var trace = new Trace_t();

            // fill in a default trace
            trace.fraction = 1;
            trace.allsolid = true;
            trace.endpos   = end;

            // get the clipping hull
            Vector3 offset;
            var     hull = HullForEntity(ent, ref mins, ref maxs, out offset);

            var start_l = start - offset;
            var end_l   = end - offset;

            // trace a line through the apropriate clipping hull
            RecursiveHullCheck(hull, hull.firstclipnode, 0, 1, ref start_l, ref end_l, trace);

            // fix trace up by the offset
            if (trace.fraction != 1)
            {
                trace.endpos += offset;
            }

            // did we clip the move?
            if (trace.fraction < 1 || trace.startsolid)
            {
                trace.ent = ent;
            }

            return(trace);
        }
Пример #15
0
		/// <summary>
		/// SV_AddGravity
		/// </summary>
		private void AddGravity( MemoryEdict ent )
		{
			var val = Host.Programs.GetEdictFieldFloat( ent, "gravity" );
			if ( val == 0 )
				val = 1;
			ent.v.velocity.z -= ( Single ) ( val * Host.Cvars.Gravity.Get<Single>() * Host.FrameTime );
		}
Пример #16
0
        private void WriteClientPunches(MemoryEdict ent, MessageWriter msg, Int32 bits)
        {
            if ((bits & ProtocolDef.SU_PUNCH1) != 0)
            {
                msg.WriteChar(( Int32 )ent.v.punchangle.x);
            }
            if ((bits & ProtocolDef.SU_VELOCITY1) != 0)
            {
                msg.WriteChar(( Int32 )(ent.v.velocity.x / 16));
            }

            if ((bits & ProtocolDef.SU_PUNCH2) != 0)
            {
                msg.WriteChar(( Int32 )ent.v.punchangle.y);
            }
            if ((bits & ProtocolDef.SU_VELOCITY2) != 0)
            {
                msg.WriteChar(( Int32 )(ent.v.velocity.y / 16));
            }

            if ((bits & ProtocolDef.SU_PUNCH3) != 0)
            {
                msg.WriteChar(( Int32 )ent.v.punchangle.z);
            }
            if ((bits & ProtocolDef.SU_VELOCITY3) != 0)
            {
                msg.WriteChar(( Int32 )(ent.v.velocity.z / 16));
            }
        }
Пример #17
0
        /// <summary>
        /// SV_CheckWater
        /// </summary>
        private bool CheckWater(MemoryEdict ent)
        {
            Vector3 point;

            point.X = ent.v.origin.X;
            point.Y = ent.v.origin.Y;
            point.Z = ent.v.origin.Z + ent.v.mins.Z + 1;

            ent.v.waterlevel = 0;
            ent.v.watertype  = ( int )Q1Contents.Empty;
            var cont = this.PointContents(ref point);

            if (cont <= ( int )Q1Contents.Water)
            {
                ent.v.watertype  = cont;
                ent.v.waterlevel = 1;
                point.Z          = ent.v.origin.Z + (ent.v.mins.Z + ent.v.maxs.Z) * 0.5f;
                cont             = this.PointContents(ref point);
                if (cont <= ( int )Q1Contents.Water)
                {
                    ent.v.waterlevel = 2;
                    point.Z          = ent.v.origin.Z + ent.v.view_ofs.Z;
                    cont             = this.PointContents(ref point);
                    if (cont <= ( int )Q1Contents.Water)
                    {
                        ent.v.waterlevel = 3;
                    }
                }
            }

            return(ent.v.waterlevel > 1);
        }
Пример #18
0
        /// <summary>
        /// SV_CheckWater
        /// </summary>
        private Boolean CheckWater(MemoryEdict ent)
        {
            Vector3 point;

            point.X = ent.v.origin.x;
            point.Y = ent.v.origin.y;
            point.Z = ent.v.origin.z + ent.v.mins.z + 1;

            ent.v.waterlevel = 0;
            ent.v.watertype  = ( Int32 )Q1Contents.Empty;
            var cont = PointContents(ref point);

            if (cont <= ( Int32 )Q1Contents.Water)
            {
                ent.v.watertype  = cont;
                ent.v.waterlevel = 1;
                point.Z          = ent.v.origin.z + (ent.v.mins.z + ent.v.maxs.z) * 0.5f;
                cont             = PointContents(ref point);
                if (cont <= ( Int32 )Q1Contents.Water)
                {
                    ent.v.waterlevel = 2;
                    point.Z          = ent.v.origin.z + ent.v.view_ofs.z;
                    cont             = PointContents(ref point);
                    if (cont <= ( Int32 )Q1Contents.Water)
                    {
                        ent.v.waterlevel = 3;
                    }
                }
            }

            return(ent.v.waterlevel > 1);
        }
Пример #19
0
        /// <summary>
        /// SV_CloseEnough
        /// </summary>
        private bool CloseEnough(MemoryEdict ent, MemoryEdict goal, float dist)
        {
            if (goal.v.absmin.X > ent.v.absmax.X + dist)
            {
                return(false);
            }
            if (goal.v.absmin.Y > ent.v.absmax.Y + dist)
            {
                return(false);
            }
            if (goal.v.absmin.Z > ent.v.absmax.Z + dist)
            {
                return(false);
            }

            if (goal.v.absmax.X < ent.v.absmin.X - dist)
            {
                return(false);
            }
            if (goal.v.absmax.Y < ent.v.absmin.Y - dist)
            {
                return(false);
            }
            if (goal.v.absmax.Z < ent.v.absmin.Z - dist)
            {
                return(false);
            }

            return(true);
        }
Пример #20
0
 private void WriteClientAmmo(MemoryEdict ent, MessageWriter msg)
 {
     msg.WriteByte(( int )ent.v.currentammo);
     msg.WriteByte(( int )ent.v.ammo_shells);
     msg.WriteByte(( int )ent.v.ammo_nails);
     msg.WriteByte(( int )ent.v.ammo_rockets);
     msg.WriteByte(( int )ent.v.ammo_cells);
 }
Пример #21
0
 /// <summary>
 /// SV_UnlinkEdict
 /// call before removing an entity, and before trying to move one,
 /// so it doesn't clip against itself
 /// flags ent->v.modified
 /// </summary>
 public void UnlinkEdict(MemoryEdict ent)
 {
     if (ent.area.Prev == null)
     {
         return;                     // not linked in anywhere
     }
     ent.area.Remove();              //RemoveLink(&ent->area);
     //ent->area.prev = ent->area.next = NULL;
 }
Пример #22
0
        /// <summary>
        /// SV_AddGravity
        /// </summary>
        private void AddGravity(MemoryEdict ent)
        {
            var val = this.Host.Programs.GetEdictFieldFloat(ent, "gravity");

            if (val == 0)
            {
                val = 1;
            }
            ent.v.velocity.Z -= ( float )(val * this.Host.Cvars.Gravity.Get <float>() * this.Host.FrameTime);
        }
Пример #23
0
		/// <summary>
		/// SV_Physics_Noclip
		/// A moving object that doesn't obey physics
		/// </summary>
		private void Physics_Noclip( MemoryEdict ent )
		{
			// regular thinking
			if ( !RunThink( ent ) )
				return;

			MathLib.VectorMA( ref ent.v.angles, ( Single ) Host.FrameTime, ref ent.v.avelocity, out ent.v.angles );
			MathLib.VectorMA( ref ent.v.origin, ( Single ) Host.FrameTime, ref ent.v.velocity, out ent.v.origin );
			LinkEdict( ent, false );
		}
Пример #24
0
        /// <summary>
        /// NUM_FOR_EDICT
        /// </summary>
        public int NumForEdict(MemoryEdict e)
        {
            var i = Array.IndexOf(this.sv.edicts, e);  // todo: optimize this

            if (i < 0)
            {
                Utilities.Error("NUM_FOR_EDICT: bad pointer");
            }
            return(i);
        }
Пример #25
0
        public MemoryEdict ent;                 // entity the surface is on

        public void CopyFrom(Trace_t src)
        {
            allsolid   = src.allsolid;
            startsolid = src.startsolid;
            inopen     = src.inopen;
            inwater    = src.inwater;
            fraction   = src.fraction;
            endpos     = src.endpos;
            plane      = src.plane;
            ent        = src.ent;
        }
Пример #26
0
        public MemoryEdict ent;       // entity the surface is on

        public void CopyFrom(Trace_t src)
        {
            this.allsolid   = src.allsolid;
            this.startsolid = src.startsolid;
            this.inopen     = src.inopen;
            this.inwater    = src.inwater;
            this.fraction   = src.fraction;
            this.endpos     = src.endpos;
            this.plane      = src.plane;
            this.ent        = src.ent;
        }
Пример #27
0
        public Single GetEdictFieldFloat(MemoryEdict ed, String field, Single defValue = 0)
        {
            var def = CachedSearch(ed, field);

            if (def == null)
            {
                return(defValue);
            }

            return(ed.GetFloat(def.ofs));
        }
Пример #28
0
        public Boolean SetEdictFieldFloat(MemoryEdict ed, String field, Single value)
        {
            var def = CachedSearch(ed, field);

            if (def != null)
            {
                ed.SetFloat(def.ofs, value);
                return(true);
            }
            return(false);
        }
Пример #29
0
 private void WriteClientFixAngle(MemoryEdict ent, MessageWriter msg)
 {
     if (ent.v.fixangle != 0)
     {
         msg.WriteByte(ProtocolDef.svc_setangle);
         msg.WriteAngle(ent.v.angles.X);
         msg.WriteAngle(ent.v.angles.Y);
         msg.WriteAngle(ent.v.angles.Z);
         ent.v.fixangle = 0;
     }
 }
Пример #30
0
        /// <summary>
        /// SV_TestEntityPosition
        /// This could be a lot more efficient...
        /// </summary>
        private MemoryEdict TestEntityPosition(MemoryEdict ent)
        {
            var trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref ent.v.origin, 0, ent);

            if (trace.startsolid)
            {
                return(sv.edicts[0]);
            }

            return(null);
        }