Ejemplo n.º 1
0
        /// <summary>
        /// Spawn a mobj at the mapthing.
        /// </summary>
        public void SpawnMapThing(MapThing mt)
        {
            // Count deathmatch start positions.
            if (mt.Type == 11)
            {
                if (this.deathmatchStarts.Count < 10)
                {
                    this.deathmatchStarts.Add(mt);
                }

                return;
            }

            // Check for players specially.
            if (mt.Type <= 4)
            {
                var playerNumber = mt.Type - 1;

                // This check is neccesary in Plutonia MAP12,
                // which contains an unknown thing with type 0.
                if (playerNumber < 0)
                {
                    return;
                }

                // Save spots for respawning in network games.
                this.playerStarts[playerNumber] = mt;

                if (this.world.Options.Deathmatch == 0)
                {
                    this.SpawnPlayer(mt);
                }

                return;
            }

            if (mt.Type == 11 || mt.Type <= 4)
            {
                return;
            }

            // Check for apropriate skill level.
            if (!this.world.Options.NetGame && ((int)mt.Flags & 16) != 0)
            {
                return;
            }

            int bit;

            if (this.world.Options.Skill == GameSkill.Baby)
            {
                bit = 1;
            }
            else if (this.world.Options.Skill == GameSkill.Nightmare)
            {
                bit = 4;
            }
            else
            {
                bit = 1 << ((int)this.world.Options.Skill - 1);
            }

            if (((int)mt.Flags & bit) == 0)
            {
                return;
            }

            // Find which type to spawn.
            int i;

            for (i = 0; i < DoomInfo.MobjInfos.Length; i++)
            {
                if (mt.Type == DoomInfo.MobjInfos[i].DoomEdNum)
                {
                    break;
                }
            }

            if (i == DoomInfo.MobjInfos.Length)
            {
                throw new Exception("Unknown type!");
            }

            // Don't spawn keycards and players in deathmatch.
            if (this.world.Options.Deathmatch != 0 && (DoomInfo.MobjInfos[i].Flags & MobjFlags.NotDeathmatch) != 0)
            {
                return;
            }

            // Don't spawn any monsters if -nomonsters.
            if (this.world.Options.NoMonsters && (i == (int)MobjType.Skull || (DoomInfo.MobjInfos[i].Flags & MobjFlags.CountKill) != 0))
            {
                return;
            }

            // Spawn it.
            Fixed x = mt.X;
            Fixed y = mt.Y;
            Fixed z;

            if ((DoomInfo.MobjInfos[i].Flags & MobjFlags.SpawnCeiling) != 0)
            {
                z = Mobj.OnCeilingZ;
            }
            else
            {
                z = Mobj.OnFloorZ;
            }

            var mobj = this.SpawnMobj(x, y, z, (MobjType)i);

            mobj.SpawnPoint = mt;

            if (mobj.Tics > 0)
            {
                mobj.Tics = 1 + (this.world.Random.Next() % mobj.Tics);
            }

            if ((mobj.Flags & MobjFlags.CountKill) != 0)
            {
                this.world.TotalKills++;
            }

            if ((mobj.Flags & MobjFlags.CountItem) != 0)
            {
                this.world.TotalItems++;
            }

            mobj.Angle = mt.Angle;

            if ((mt.Flags & ThingFlags.Ambush) != 0)
            {
                mobj.Flags |= MobjFlags.Ambush;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Called when a player is spawned on the level.
        /// Most of the player structure stays unchanged between levels.
        /// </summary>
        public void SpawnPlayer(MapThing mt)
        {
            var players      = this.world.Options.Players;
            var playerNumber = mt.Type - 1;

            // Not playing?
            if (!players[playerNumber].InGame)
            {
                return;
            }

            var player = players[playerNumber];

            if (player.PlayerState == PlayerState.Reborn)
            {
                players[playerNumber].Reborn();
            }

            var x    = mt.X;
            var y    = mt.Y;
            var z    = Mobj.OnFloorZ;
            var mobj = this.SpawnMobj(x, y, z, MobjType.Player);

            if (mt.Type - 1 == this.world.Options.ConsolePlayer)
            {
                this.world.StatusBar?.Reset();
                this.world.Options.Sound.SetListener(mobj);
            }

            // Set color translations for player sprites.
            if (playerNumber >= 1)
            {
                mobj.Flags |= (MobjFlags)((mt.Type - 1) << (int)MobjFlags.TransShift);
            }

            mobj.Angle  = mt.Angle;
            mobj.Player = player;
            mobj.Health = player.Health;

            player.Mobj          = mobj;
            player.PlayerState   = PlayerState.Live;
            player.Refire        = 0;
            player.Message       = null;
            player.MessageTime   = 0;
            player.DamageCount   = 0;
            player.BonusCount    = 0;
            player.ExtraLight    = 0;
            player.FixedColorMap = 0;
            player.ViewHeight    = Player.NormalViewHeight;

            // Setup gun psprite.
            this.world.PlayerBehavior.SetupPlayerSprites(player);

            // Give all cards in death match mode.
            if (this.world.Options.Deathmatch != 0)
            {
                for (var i = 0; i < (int)CardType.Count; i++)
                {
                    player.Cards[i] = true;
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns false if the player cannot be respawned at the given
        /// mapthing spot because something is occupying it.
        /// </summary>
        public bool CheckSpot(int playernum, MapThing mthing)
        {
            var players = this.world.Options.Players;

            if (players[playernum].Mobj == null)
            {
                // First spawn of level, before corpses.
                for (var i = 0; i < playernum; i++)
                {
                    if (players[i].Mobj.X == mthing.X && players[i].Mobj.Y == mthing.Y)
                    {
                        return(false);
                    }
                }

                return(true);
            }

            var x = mthing.X;
            var y = mthing.Y;

            if (!this.world.ThingMovement.CheckPosition(players[playernum].Mobj, x, y))
            {
                return(false);
            }

            // Flush an old corpse if needed.
            if (this.bodyQueSlot >= ThingAllocation.bodyQueSize)
            {
                this.RemoveMobj(this.bodyQue[this.bodyQueSlot % ThingAllocation.bodyQueSize]);
            }

            this.bodyQue[this.bodyQueSlot % ThingAllocation.bodyQueSize] = players[playernum].Mobj;
            this.bodyQueSlot++;

            // Spawn a teleport fog.
            var subsector = Geometry.PointInSubsector(x, y, this.world.Map);

            var angle = (Angle.Ang45.Data >> Trig.AngleToFineShift) * ((int)Math.Round(mthing.Angle.ToDegree()) / 45);

            //
            // The code below to reproduce respawn fog bug in deathmath
            // is based on Chocolate Doom's implementation.
            //

            Fixed xa;
            Fixed ya;

            switch (angle)
            {
            case 4096:                     // -4096:
                xa = Trig.Tan(2048);       // finecosine[-4096]
                ya = Trig.Tan(0);          // finesine[-4096]

                break;

            case 5120:                     // -3072:
                xa = Trig.Tan(3072);       // finecosine[-3072]
                ya = Trig.Tan(1024);       // finesine[-3072]

                break;

            case 6144:                     // -2048:
                xa = Trig.Sin(0);          // finecosine[-2048]
                ya = Trig.Tan(2048);       // finesine[-2048]

                break;

            case 7168:                     // -1024:
                xa = Trig.Sin(1024);       // finecosine[-1024]
                ya = Trig.Tan(3072);       // finesine[-1024]

                break;

            case 0:
            case 1024:
            case 2048:
            case 3072:
                xa = Trig.Cos((int)angle);
                ya = Trig.Sin((int)angle);

                break;

            default:
                throw new Exception("Unexpected angle: " + angle);
            }

            var mo = this.SpawnMobj(x + 20 * xa, y + 20 * ya, subsector.Sector.FloorHeight, MobjType.Tfog);

            if (!this.world.FirstTicIsNotYetDone)
            {
                // Don't start sound on first frame.
                this.world.StartSound(mo, Sfx.TELEPT, SfxType.Misc);
            }

            return(true);
        }
 public StackOverflowExample()
 {
     _map        = new MapThing();
     _mapActions = new Dictionary <string, Action>
     {
         { "orange", _map.functionOrange },