Esempio n. 1
0
        public void Punch(Player player)
        {
            var random = world.Random;

            var damage = (random.Next() % 10 + 1) << 1;

            if (player.Powers[(int)PowerType.Strength] != 0)
            {
                damage *= 10;
            }

            var hs = world.Hitscan;

            var angle = player.Mobj.Angle;

            angle += new Angle((random.Next() - random.Next()) << 18);

            var slope = hs.AimLineAttack(player.Mobj, angle, MeleeRange);

            hs.LineAttack(player.Mobj, angle, MeleeRange, slope, damage);

            // Turn to face target.
            if (hs.LineTarget != null)
            {
                world.StartSound(player.Mobj, Sfx.PUNCH, SfxType.Weapon);

                player.Mobj.Angle = Geometry.PointToAngle(
                    player.Mobj.X, player.Mobj.Y,
                    hs.LineTarget.X, hs.LineTarget.Y);
            }
        }
Esempio n. 2
0
        public Mobj SpawnMissile(Mobj source, Mobj dest, MobjType type)
        {
            var missile = SpawnMobj(
                source.X,
                source.Y,
                source.Z + Fixed.FromInt(32), type);

            if (missile.Info.SeeSound != 0)
            {
                world.StartSound(missile, missile.Info.SeeSound);
            }

            // Where it came from?
            missile.Target = source;

            var angle = Geometry.PointToAngle(
                source.X, source.Y,
                dest.X, dest.Y);

            // Fuzzy player.
            if ((dest.Flags & MobjFlags.Shadow) != 0)
            {
                var random = world.Random;
                angle += new Angle((random.Next() - random.Next()) << 20);
            }

            var speed = GetMissileSpeed(missile.Type);

            missile.Angle = angle;
            missile.MomX  = new Fixed(speed) * Trig.Cos(angle);
            missile.MomY  = new Fixed(speed) * Trig.Sin(angle);

            var dist = Geometry.AproxDistance(
                dest.X - source.X,
                dest.Y - source.Y);

            var num = (dest.Z - source.Z).Data;
            var den = (dist / speed).Data;

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

            missile.MomZ = new Fixed(num / den);

            CheckMissileSpawn(missile);

            return(missile);
        }
Esempio n. 3
0
        public override void Run()
        {
            SectorActionResult result;

            var sa = world.SectorAction;

            result = sa.MovePlane(
                sector,
                speed,
                floorDestHeight,
                crush,
                0,
                direction);

            if (((world.LevelTime + sector.Number) & 7) == 0)
            {
                world.StartSound(sector.SoundOrigin, Sfx.STNMOV, SfxType.Misc);
            }

            if (result == SectorActionResult.PastDestination)
            {
                sector.SpecialData = null;

                if (direction == 1)
                {
                    switch (type)
                    {
                    case FloorMoveType.DonutRaise:
                        sector.Special   = newSpecial;
                        sector.FloorFlat = texture;
                        break;
                    }
                }
                else if (direction == -1)
                {
                    switch (type)
                    {
                    case FloorMoveType.LowerAndChange:
                        sector.Special   = newSpecial;
                        sector.FloorFlat = texture;
                        break;
                    }
                }

                world.Thinkers.Remove(this);

                world.StartSound(sector.SoundOrigin, Sfx.PSTOP, SfxType.Misc);
            }
        }
Esempio n. 4
0
        private bool UseTraverse(Intercept intercept)
        {
            var mc = world.MapCollision;

            if (intercept.Line.Special == 0)
            {
                mc.LineOpening(intercept.Line);
                if (mc.OpenRange <= Fixed.Zero)
                {
                    world.StartSound(useThing, Sfx.NOWAY, SfxType.Voice);

                    // Can't use through a wall.
                    return(false);
                }

                // Not a special line, but keep checking.
                return(true);
            }

            var side = 0;

            if (Geometry.PointOnLineSide(useThing.X, useThing.Y, intercept.Line) == 1)
            {
                side = 1;
            }

            UseSpecialLine(useThing, intercept.Line, side);

            // Can't use for than one special line in a row.
            return(false);
        }
Esempio n. 5
0
        private bool PTR_UseTraverse(Intercept ic)
        {
            var mc = world.MapCollision;

            if (ic.Line.Special == 0)
            {
                mc.LineOpening(ic.Line);
                if (mc.OpenRange <= Fixed.Zero)
                {
                    world.StartSound(usething, Sfx.NOWAY);

                    // can't use through a wall
                    return(false);
                }

                // not a special line, but keep checking
                return(true);
            }

            var side = 0;

            if (Geometry.PointOnLineSide(usething.X, usething.Y, ic.Line) == 1)
            {
                side = 1;
            }

            // don't use back side
            //return false;

            UseSpecialLine(usething, ic.Line, side);

            // can't use for than one special line in a row
            return(false);
        }
Esempio n. 6
0
        /// <summary>
        /// Starts bringing the pending weapon up from the bottom of the screen.
        /// </summary>
        public void BringUpWeapon(Player player)
        {
            if (player.PendingWeapon == WeaponType.NoChange)
            {
                player.PendingWeapon = player.ReadyWeapon;
            }

            if (player.PendingWeapon == WeaponType.Chainsaw)
            {
                world.StartSound(player.Mobj, Sfx.SAWUP, SfxType.Weapon);
            }

            var newState = DoomInfo.WeaponInfos[(int)player.PendingWeapon].UpState;

            player.PendingWeapon = WeaponType.NoChange;
            player.PlayerSprites[(int)PlayerSprite.Weapon].Sy = WeaponBehavior.WeaponBottom;

            SetPlayerSprite(player, PlayerSprite.Weapon, newState);
        }
Esempio n. 7
0
        /// <summary>
        /// Called when the missile hits something (wall or thing).
        /// </summary>
        public void ExplodeMissile(Mobj thing)
        {
            thing.MomX = thing.MomY = thing.MomZ = Fixed.Zero;

            thing.SetState(DoomInfo.MobjInfos[(int)thing.Type].DeathState);

            thing.Tics -= world.Random.Next() & 3;

            if (thing.Tics < 1)
            {
                thing.Tics = 1;
            }

            thing.Flags &= ~MobjFlags.Missile;

            if (thing.Info.DeathSound != 0)
            {
                world.StartSound(thing, thing.Info.DeathSound, SfxType.Misc);
            }
        }
Esempio n. 8
0
        public override void Run()
        {
            SectorActionResult res;

            var sa = world.SectorAction;

            switch (Direction)
            {
            case 0:
                // IN STASIS
                break;

            case 1:
                // UP
                res = sa.MovePlane(
                    Sector,
                    Speed,
                    TopHeight,
                    false, 1, Direction);

                if ((world.levelTime & 7) == 0)
                {
                    switch (Type)
                    {
                    case CeilingMoveType.SilentCrushAndRaise:
                        break;

                    default:
                        world.StartSound(Sector.SoundOrigin, Sfx.STNMOV);
                        // ?
                        break;
                    }
                }

                if (res == SectorActionResult.PastDestination)
                {
                    switch (Type)
                    {
                    case CeilingMoveType.RaiseToHighest:
                        sa.RemoveActiveCeiling(this);
                        break;

                    case CeilingMoveType.SilentCrushAndRaise:
                    case CeilingMoveType.FastCrushAndRaise:
                    case CeilingMoveType.CrushAndRaise:
                        if (Type == CeilingMoveType.SilentCrushAndRaise)
                        {
                            world.StartSound(Sector.SoundOrigin, Sfx.PSTOP);
                        }
                        Direction = -1;
                        break;

                    default:
                        break;
                    }
                }
                break;

            case -1:
                // DOWN
                res = sa.MovePlane(
                    Sector,
                    Speed,
                    BottomHeight,
                    Crush, 1, Direction);

                if ((world.levelTime & 7) == 0)
                {
                    switch (Type)
                    {
                    case CeilingMoveType.SilentCrushAndRaise:
                        break;

                    default:
                        world.StartSound(Sector.SoundOrigin, Sfx.STNMOV);
                        break;
                    }
                }

                if (res == SectorActionResult.PastDestination)
                {
                    switch (Type)
                    {
                    case CeilingMoveType.SilentCrushAndRaise:
                    case CeilingMoveType.CrushAndRaise:
                    case CeilingMoveType.FastCrushAndRaise:
                        if (Type == CeilingMoveType.SilentCrushAndRaise)
                        {
                            world.StartSound(Sector.SoundOrigin, Sfx.PSTOP);
                        }
                        if (Type == CeilingMoveType.CrushAndRaise)
                        {
                            Speed = SectorAction.CEILSPEED;
                        }
                        Direction = 1;
                        break;

                    case CeilingMoveType.LowerAndCrush:
                    case CeilingMoveType.LowerToFloor:
                        sa.RemoveActiveCeiling(this);
                        break;

                    default:
                        break;
                    }
                }
                else                         // ( res != pastdest )
                {
                    if (res == SectorActionResult.Crushed)
                    {
                        switch (Type)
                        {
                        case CeilingMoveType.SilentCrushAndRaise:
                        case CeilingMoveType.CrushAndRaise:
                        case CeilingMoveType.LowerAndCrush:
                            Speed = SectorAction.CEILSPEED / 8;
                            break;

                        default:
                            break;
                        }
                    }
                }
                break;
            }
        }
Esempio n. 9
0
        public void ChangeSwitchTexture(LineDef line, bool useAgain)
        {
            if (!useAgain)
            {
                line.Special = 0;
            }

            var texTop = line.Side0.TopTexture;
            var texMid = line.Side0.MiddleTexture;
            var texBot = line.Side0.BottomTexture;

            var sound = Sfx.SWTCHN;

            // EXIT SWITCH?
            if ((int)line.Special == 11)
            {
                sound = Sfx.SWTCHX;
            }

            var switchList = world.Map.Textures.SwitchList;

            for (var i = 0; i < switchList.Length; i++)
            {
                if (switchList[i] == texTop)
                {
                    world.StartSound(line.SoundOrigin, sound);
                    line.Side0.TopTexture = switchList[i ^ 1];

                    if (useAgain)
                    {
                        StartButton(line, ButtonPosition.Top, switchList[i], BUTTONTIME);
                    }

                    return;
                }
                else
                {
                    if (switchList[i] == texMid)
                    {
                        world.StartSound(line.SoundOrigin, sound);
                        line.Side0.MiddleTexture = switchList[i ^ 1];

                        if (useAgain)
                        {
                            StartButton(line, ButtonPosition.Middle, switchList[i], BUTTONTIME);
                        }

                        return;
                    }
                    else
                    {
                        if (switchList[i] == texBot)
                        {
                            world.StartSound(line.SoundOrigin, sound);
                            line.Side0.BottomTexture = switchList[i ^ 1];

                            if (useAgain)
                            {
                                StartButton(line, ButtonPosition.Bottom, switchList[i], BUTTONTIME);
                            }

                            return;
                        }
                    }
                }
            }
        }
Esempio n. 10
0
        public override void Run()
        {
            var sa = world.SectorAction;

            SectorActionResult res;

            switch (Direction)
            {
            case 0:
                // WAITING
                if (--TopCountDown == 0)
                {
                    switch (Type)
                    {
                    case VlDoorType.BlazeRaise:
                        // time to go back down
                        Direction = -1;
                        world.StartSound(Sector.SoundOrigin, Sfx.BDCLS);
                        break;

                    case VlDoorType.Normal:
                        // time to go back down
                        Direction = -1;
                        world.StartSound(Sector.SoundOrigin, Sfx.DORCLS);
                        break;

                    case VlDoorType.Close30ThenOpen:
                        Direction = 1;
                        world.StartSound(Sector.SoundOrigin, Sfx.DOROPN);
                        break;

                    default:
                        break;
                    }
                }
                break;

            case 2:
                //  INITIAL WAIT
                if (--TopCountDown == 0)
                {
                    switch (Type)
                    {
                    case VlDoorType.RaiseIn5Mins:
                        Direction = 1;
                        Type      = VlDoorType.Normal;
                        world.StartSound(Sector.SoundOrigin, Sfx.DOROPN);
                        break;

                    default:
                        break;
                    }
                }
                break;

            case -1:
                // DOWN
                res = sa.MovePlane(
                    Sector,
                    Speed,
                    Sector.FloorHeight,
                    false, 1, Direction);
                if (res == SectorActionResult.PastDestination)
                {
                    switch (Type)
                    {
                    case VlDoorType.BlazeRaise:
                    case VlDoorType.BlazeClose:
                        Sector.SpecialData = null;
                        // unlink and free
                        world.Thinkers.Remove(this);
                        world.StartSound(Sector.SoundOrigin, Sfx.BDCLS);
                        break;

                    case VlDoorType.Normal:
                    case VlDoorType.Close:
                        Sector.SpecialData = null;
                        // unlink and free
                        world.Thinkers.Remove(this);
                        break;

                    case VlDoorType.Close30ThenOpen:
                        Direction    = 0;
                        TopCountDown = 35 * 30;
                        break;

                    default:
                        break;
                    }
                }
                else if (res == SectorActionResult.Crushed)
                {
                    switch (Type)
                    {
                    case VlDoorType.BlazeClose:
                    case VlDoorType.Close:                                     // DO NOT GO BACK UP!
                        break;

                    default:
                        Direction = 1;
                        world.StartSound(Sector.SoundOrigin, Sfx.DOROPN);
                        break;
                    }
                }
                break;

            case 1:
                // UP
                res = sa.MovePlane(
                    Sector,
                    Speed,
                    TopHeight,
                    false, 1, Direction);

                if (res == SectorActionResult.PastDestination)
                {
                    switch (Type)
                    {
                    case VlDoorType.BlazeRaise:
                    case VlDoorType.Normal:
                        Direction    = 0;                                      // wait at top
                        TopCountDown = TopWait;
                        break;

                    case VlDoorType.Close30ThenOpen:
                    case VlDoorType.BlazeOpen:
                    case VlDoorType.Open:
                        Sector.SpecialData = null;
                        world.Thinkers.Remove(this);                                         // unlink and free
                        break;

                    default:
                        break;
                    }
                }
                break;
            }
        }
Esempio n. 11
0
        public void ZMovement(Mobj thing)
        {
            // Check for smooth step up.
            if (thing.Player != null && thing.Z < thing.FloorZ)
            {
                thing.Player.ViewHeight -= thing.FloorZ - thing.Z;

                thing.Player.DeltaViewHeight =
                    (Player.NormalViewHeight - thing.Player.ViewHeight) >> 3;
            }

            // Adjust height.
            thing.Z += thing.MomZ;

            if ((thing.Flags & MobjFlags.Float) != 0 && thing.Target != null)
            {
                // Float down towards target if too close.
                if ((thing.Flags & MobjFlags.SkullFly) == 0 &&
                    (thing.Flags & MobjFlags.InFloat) == 0)
                {
                    var dist = Geometry.AproxDistance(
                        thing.X - thing.Target.X,
                        thing.Y - thing.Target.Y);

                    var delta = (thing.Target.Z + (thing.Height >> 1)) - thing.Z;

                    if (delta < Fixed.Zero && dist < -(delta * 3))
                    {
                        thing.Z -= FloatSpeed;
                    }
                    else if (delta > Fixed.Zero && dist < (delta * 3))
                    {
                        thing.Z += FloatSpeed;
                    }
                }
            }

            // Clip movement.
            if (thing.Z <= thing.FloorZ)
            {
                // Hit the floor.

                //
                // The lost soul bounce fix below is based on Chocolate Doom's implementation.
                //

                var correctLostSoulBounce = world.Options.GameVersion >= GameVersion.Ultimate;

                if (correctLostSoulBounce && (thing.Flags & MobjFlags.SkullFly) != 0)
                {
                    // The skull slammed into something.
                    thing.MomZ = -thing.MomZ;
                }

                if (thing.MomZ < Fixed.Zero)
                {
                    if (thing.Player != null && thing.MomZ < -gravity * 8)
                    {
                        // Squat down.
                        // Decrease viewheight for a moment after hitting the ground (hard),
                        // and utter appropriate sound.
                        thing.Player.DeltaViewHeight = (thing.MomZ >> 3);
                        world.StartSound(thing, Sfx.OOF, SfxType.Voice);
                    }
                    thing.MomZ = Fixed.Zero;
                }
                thing.Z = thing.FloorZ;

                if (!correctLostSoulBounce &&
                    (thing.Flags & MobjFlags.SkullFly) != 0)
                {
                    thing.MomZ = -thing.MomZ;
                }

                if ((thing.Flags & MobjFlags.Missile) != 0 &&
                    (thing.Flags & MobjFlags.NoClip) == 0)
                {
                    world.ThingInteraction.ExplodeMissile(thing);
                    return;
                }
            }
            else if ((thing.Flags & MobjFlags.NoGravity) == 0)
            {
                if (thing.MomZ == Fixed.Zero)
                {
                    thing.MomZ = -gravity * 2;
                }
                else
                {
                    thing.MomZ -= gravity;
                }
            }

            if (thing.Z + thing.Height > thing.CeilingZ)
            {
                // Hit the ceiling.
                if (thing.MomZ > Fixed.Zero)
                {
                    thing.MomZ = Fixed.Zero;
                }

                {
                    thing.Z = thing.CeilingZ - thing.Height;
                }

                if ((thing.Flags & MobjFlags.SkullFly) != 0)
                {
                    // The skull slammed into something.
                    thing.MomZ = -thing.MomZ;
                }

                if ((thing.Flags & MobjFlags.Missile) != 0 &&
                    (thing.Flags & MobjFlags.NoClip) == 0)
                {
                    world.ThingInteraction.ExplodeMissile(thing);
                    return;
                }
            }
        }
Esempio n. 12
0
        //
        // P_NightmareRespawn
        //
        private void NightmareRespawn()
        {
            MapThing sp;

            if (SpawnPoint != null)
            {
                sp = SpawnPoint;
            }
            else
            {
                sp = MapThing.Empty;
            }

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

            // somthing is occupying it's position?
            if (!world.ThingMovement.CheckPosition(this, x, y))
            {
                // no respwan
                return;
            }

            // spawn a teleport fog at old spot
            // because of removal of the body?
            var mo = world.ThingAllocation.SpawnMobj(
                X, Y, Subsector.Sector.FloorHeight, MobjType.Tfog);

            // initiate teleport sound
            world.StartSound(mo, Sfx.TELEPT);

            // spawn a teleport fog at the new spot
            var ss = Geometry.PointInSubsector(x, y, world.Map);

            mo = world.ThingAllocation.SpawnMobj(
                x, y, ss.Sector.FloorHeight, MobjType.Tfog);

            world.StartSound(mo, Sfx.TELEPT);

            // spawn the new monster
            var mthing = sp;

            // spawn it
            Fixed z;

            if ((Info.Flags & MobjFlags.SpawnCeiling) != 0)
            {
                z = OnCeilingZ;
            }
            else
            {
                z = OnFloorZ;
            }

            // inherit attributes from deceased one
            mo            = world.ThingAllocation.SpawnMobj(x, y, z, Type);
            mo.SpawnPoint = SpawnPoint;
            mo.Angle      = mthing.Angle;

            if ((mthing.Flags & ThingFlags.Ambush) != 0)
            {
                mo.Flags |= MobjFlags.Ambush;
            }

            mo.ReactionTime = 18;

            // remove the old monster,
            world.ThingAllocation.RemoveMobj(this);
        }
Esempio n. 13
0
        /// <summary>
        /// Give the weapon to the player.
        /// </summary>
        /// <param name="dropped">
        /// True if the weapons is dropped by a monster.
        /// </param>
        public bool GiveWeapon(Player player, WeaponType weapon, bool dropped)
        {
            if (world.Options.NetGame && (world.Options.Deathmatch != 2) && !dropped)
            {
                // Leave placed weapons forever on net games.
                if (player.WeaponOwned[(int)weapon])
                {
                    return(false);
                }

                player.BonusCount += bonusAdd;
                player.WeaponOwned[(int)weapon] = true;

                if (world.Options.Deathmatch != 0)
                {
                    GiveAmmo(player, DoomInfo.WeaponInfos[(int)weapon].Ammo, 5);
                }
                else
                {
                    GiveAmmo(player, DoomInfo.WeaponInfos[(int)weapon].Ammo, 2);
                }

                player.PendingWeapon = weapon;

                if (player == world.ConsolePlayer)
                {
                    world.StartSound(player.Mobj, Sfx.WPNUP, SfxType.Misc);
                }

                return(false);
            }

            bool gaveAmmo;

            if (DoomInfo.WeaponInfos[(int)weapon].Ammo != AmmoType.NoAmmo)
            {
                // Give one clip with a dropped weapon, two clips with a found weapon.
                if (dropped)
                {
                    gaveAmmo = GiveAmmo(player, DoomInfo.WeaponInfos[(int)weapon].Ammo, 1);
                }
                else
                {
                    gaveAmmo = GiveAmmo(player, DoomInfo.WeaponInfos[(int)weapon].Ammo, 2);
                }
            }
            else
            {
                gaveAmmo = false;
            }

            bool gaveWeapon;

            if (player.WeaponOwned[(int)weapon])
            {
                gaveWeapon = false;
            }
            else
            {
                gaveWeapon = true;
                player.WeaponOwned[(int)weapon] = true;
                player.PendingWeapon            = weapon;
            }

            return(gaveWeapon || gaveAmmo);
        }
Esempio n. 14
0
        //
        // P_GiveWeapon
        // The weapon name may have a MF_DROPPED flag ored in.
        //
        public bool GiveWeapon(Player player, WeaponType weapon, bool dropped)
        {
            if (world.Options.NetGame && (world.Options.Deathmatch != 2) &&
                !dropped)
            {
                // leave placed weapons forever on net games
                if (player.WeaponOwned[(int)weapon])
                {
                    return(false);
                }

                player.BonusCount += BONUSADD;
                player.WeaponOwned[(int)weapon] = true;

                if (world.Options.Deathmatch != 0)
                {
                    GiveAmmo(player, DoomInfo.WeaponInfos[(int)weapon].Ammo, 5);
                }
                else
                {
                    GiveAmmo(player, DoomInfo.WeaponInfos[(int)weapon].Ammo, 2);
                }

                player.PendingWeapon = weapon;

                if (player == world.Players[world.consoleplayer])
                {
                    world.StartSound(null, Sfx.WPNUP);
                }

                return(false);
            }

            bool gaveammo;

            if (DoomInfo.WeaponInfos[(int)weapon].Ammo != AmmoType.NoAmmo)
            {
                // give one clip with a dropped weapon,
                // two clips with a found weapon
                if (dropped)
                {
                    gaveammo = GiveAmmo(player, DoomInfo.WeaponInfos[(int)weapon].Ammo, 1);
                }
                else
                {
                    gaveammo = GiveAmmo(player, DoomInfo.WeaponInfos[(int)weapon].Ammo, 2);
                }
            }
            else
            {
                gaveammo = false;
            }

            bool gaveweapon;

            if (player.WeaponOwned[(int)weapon])
            {
                gaveweapon = false;
            }
            else
            {
                gaveweapon = true;
                player.WeaponOwned[(int)weapon] = true;
                player.PendingWeapon            = weapon;
            }

            return(gaveweapon || gaveammo);
        }
Esempio n. 15
0
        public void Look(Mobj actor)
        {
            // Any shot will wake up.
            actor.Threshold = 0;

            var target = actor.Subsector.Sector.SoundTarget;

            if (target != null && (target.Flags & MobjFlags.Shootable) != 0)
            {
                actor.Target = target;

                if ((actor.Flags & MobjFlags.Ambush) != 0)
                {
                    if (world.VisibilityCheck.CheckSight(actor, actor.Target))
                    {
                        goto seeYou;
                    }
                }
                else
                {
                    goto seeYou;
                }
            }

            if (!LookForPlayers(actor, false))
            {
                return;
            }

            // Go into chase state.
seeYou:
            if (actor.Info.SeeSound != 0)
            {
                int sound;

                switch (actor.Info.SeeSound)
                {
                case Sfx.POSIT1:
                case Sfx.POSIT2:
                case Sfx.POSIT3:
                    sound = (int)Sfx.POSIT1 + world.Random.Next() % 3;
                    break;

                case Sfx.BGSIT1:
                case Sfx.BGSIT2:
                    sound = (int)Sfx.BGSIT1 + world.Random.Next() % 2;
                    break;

                default:
                    sound = (int)actor.Info.SeeSound;
                    break;
                }

                if (actor.Type == MobjType.Spider || actor.Type == MobjType.Cyborg)
                {
                    // Full volume for boss monsters.
                    world.StartSound(null, (Sfx)sound);
                }
                else
                {
                    world.StartSound(actor, (Sfx)sound);
                }
            }

            actor.SetState(actor.Info.SeeState);
        }
Esempio n. 16
0
        private void NightmareRespawn()
        {
            MapThing sp;

            if (spawnPoint != null)
            {
                sp = spawnPoint;
            }
            else
            {
                sp = MapThing.Empty;
            }

            // Somthing is occupying it's position?
            if (!world.ThingMovement.CheckPosition(this, sp.X, sp.Y))
            {
                // No respwan.
                return;
            }

            var ta = world.ThingAllocation;

            // Spawn a teleport fog at old spot.
            var fog1 = ta.SpawnMobj(
                x, y,
                subsector.Sector.FloorHeight,
                MobjType.Tfog);

            // Initiate teleport sound.
            world.StartSound(fog1, Sfx.TELEPT, SfxType.Misc);

            // Spawn a teleport fog at the new spot.
            var ss = Geometry.PointInSubsector(sp.X, sp.Y, world.Map);

            var fog2 = ta.SpawnMobj(
                sp.X, sp.Y,
                ss.Sector.FloorHeight, MobjType.Tfog);

            world.StartSound(fog2, Sfx.TELEPT, SfxType.Misc);

            // Spawn the new monster.
            Fixed z;

            if ((info.Flags & MobjFlags.SpawnCeiling) != 0)
            {
                z = OnCeilingZ;
            }
            else
            {
                z = OnFloorZ;
            }

            // Inherit attributes from deceased one.
            var mobj = ta.SpawnMobj(sp.X, sp.Y, z, type);

            mobj.SpawnPoint = spawnPoint;
            mobj.Angle      = sp.Angle;

            if ((sp.Flags & ThingFlags.Ambush) != 0)
            {
                mobj.Flags |= MobjFlags.Ambush;
            }

            mobj.ReactionTime = 18;

            // Remove the old monster.
            world.ThingAllocation.RemoveMobj(this);
        }
Esempio n. 17
0
        public void WeaponReady(Player player, PlayerSpriteDef psp)
        {
            var pb = world.PlayerBehavior;

            // Get out of attack state.
            if (player.Mobj.State == DoomInfo.States[(int)MobjState.PlayAtk1] ||
                player.Mobj.State == DoomInfo.States[(int)MobjState.PlayAtk2])
            {
                player.Mobj.SetState(MobjState.Play);
            }

            if (player.ReadyWeapon == WeaponType.Chainsaw &&
                psp.State == DoomInfo.States[(int)MobjState.Saw])
            {
                world.StartSound(player.Mobj, Sfx.SAWIDL);
            }

            // Check for weapon change.
            // If player is dead, put the weapon away.
            if (player.PendingWeapon != WeaponType.NoChange || player.Health == 0)
            {
                // Change weapon.
                // Pending weapon should allready be validated.
                var newState = DoomInfo.WeaponInfos[(int)player.ReadyWeapon].DownState;
                pb.SetPlayerSprite(player, PlayerSprite.Weapon, newState);
                return;
            }

            // Check for fire.
            // The missile launcher and bfg do not auto fire.
            if ((player.Cmd.Buttons & TicCmdButtons.Attack) != 0)
            {
                if (!player.AttackDown ||
                    (player.ReadyWeapon != WeaponType.Missile && player.ReadyWeapon != WeaponType.Bfg))
                {
                    player.AttackDown = true;
                    FireWeapon(player);
                    return;
                }
            }
            else
            {
                player.AttackDown = false;
            }

            // Bob the weapon based on movement speed.
            var angle = (128 * player.Mobj.World.levelTime) & Trig.FineMask;

            psp.Sx = Fixed.One + player.Bob * Trig.Cos(angle);

            angle &= Trig.FineAngleCount / 2 - 1;
            psp.Sy = WeaponTop + player.Bob * Trig.Sin(angle);
        }
Esempio n. 18
0
        public override void Run()
        {
            var sa = world.SectorAction;

            SectorActionResult res;

            switch (Status)
            {
            case PlatformState.Up:
                res = sa.MovePlane(
                    Sector,
                    Speed,
                    High,
                    Crush, 0, 1);

                if (Type == PlatformType.RaiseAndChange ||
                    Type == PlatformType.RaiseToNearestAndChange)
                {
                    if ((world.levelTime & 7) == 0)
                    {
                        world.StartSound(Sector.SoundOrigin, Sfx.STNMOV);
                    }
                }

                if (res == SectorActionResult.Crushed && !Crush)
                {
                    Count  = Wait;
                    Status = PlatformState.Down;
                    world.StartSound(Sector.SoundOrigin, Sfx.PSTART);
                }
                else
                {
                    if (res == SectorActionResult.PastDestination)
                    {
                        Count  = Wait;
                        Status = PlatformState.Waiting;
                        world.StartSound(Sector.SoundOrigin, Sfx.PSTOP);

                        switch (Type)
                        {
                        case PlatformType.BlazeDwus:
                        case PlatformType.DownWaitUpStay:
                            sa.RemoveActivePlat(this);
                            break;

                        case PlatformType.RaiseAndChange:
                        case PlatformType.RaiseToNearestAndChange:
                            sa.RemoveActivePlat(this);
                            break;

                        default:
                            break;
                        }
                    }
                }

                break;

            case PlatformState.Down:
                res = sa.MovePlane(Sector, Speed, Low, false, 0, -1);

                if (res == SectorActionResult.PastDestination)
                {
                    Count  = Wait;
                    Status = PlatformState.Waiting;
                    world.StartSound(Sector.SoundOrigin, Sfx.PSTOP);
                }

                break;

            case PlatformState.Waiting:
                if (--Count == 0)
                {
                    if (Sector.FloorHeight == Low)
                    {
                        Status = PlatformState.Up;
                    }
                    else
                    {
                        Status = PlatformState.Down;
                    }
                    world.StartSound(Sector.SoundOrigin, Sfx.PSTART);
                }

                break;

            case PlatformState.InStasis:
                break;
            }
        }
Esempio n. 19
0
        public override void Run()
        {
            var sa = world.SectorAction;

            SectorActionResult result;

            switch (status)
            {
            case PlatformState.Up:
                result = sa.MovePlane(sector, speed, high, crush, 0, 1);

                if (type == PlatformType.RaiseAndChange ||
                    type == PlatformType.RaiseToNearestAndChange)
                {
                    if (((world.LevelTime + sector.Number) & 7) == 0)
                    {
                        world.StartSound(sector.SoundOrigin, Sfx.STNMOV, SfxType.Misc);
                    }
                }

                if (result == SectorActionResult.Crushed && !crush)
                {
                    count  = wait;
                    status = PlatformState.Down;
                    world.StartSound(sector.SoundOrigin, Sfx.PSTART, SfxType.Misc);
                }
                else
                {
                    if (result == SectorActionResult.PastDestination)
                    {
                        count  = wait;
                        status = PlatformState.Waiting;
                        world.StartSound(sector.SoundOrigin, Sfx.PSTOP, SfxType.Misc);

                        switch (type)
                        {
                        case PlatformType.BlazeDwus:
                        case PlatformType.DownWaitUpStay:
                            sa.RemoveActivePlatform(this);
                            break;

                        case PlatformType.RaiseAndChange:
                        case PlatformType.RaiseToNearestAndChange:
                            sa.RemoveActivePlatform(this);
                            break;

                        default:
                            break;
                        }
                    }
                }

                break;

            case PlatformState.Down:
                result = sa.MovePlane(sector, speed, low, false, 0, -1);

                if (result == SectorActionResult.PastDestination)
                {
                    count  = wait;
                    status = PlatformState.Waiting;
                    world.StartSound(sector.SoundOrigin, Sfx.PSTOP, SfxType.Misc);
                }

                break;

            case PlatformState.Waiting:
                if (--count == 0)
                {
                    if (sector.FloorHeight == low)
                    {
                        status = PlatformState.Up;
                    }
                    else
                    {
                        status = PlatformState.Down;
                    }
                    world.StartSound(sector.SoundOrigin, Sfx.PSTART, SfxType.Misc);
                }

                break;

            case PlatformState.InStasis:
                break;
            }
        }
Esempio n. 20
0
        public void ChangeSwitchTexture(LineDef line, bool useAgain)
        {
            if (!useAgain)
            {
                line.Special = 0;
            }

            var frontSide     = line.FrontSide;
            var topTexture    = frontSide.TopTexture;
            var middleTexture = frontSide.MiddleTexture;
            var bottomTexture = frontSide.BottomTexture;

            var sound = Sfx.SWTCHN;

            // Exit switch?
            if ((int)line.Special == 11)
            {
                sound = Sfx.SWTCHX;
            }

            var switchList = world.Map.Textures.SwitchList;

            for (var i = 0; i < switchList.Length; i++)
            {
                if (switchList[i] == topTexture)
                {
                    world.StartSound(line.SoundOrigin, sound, SfxType.Misc);
                    frontSide.TopTexture = switchList[i ^ 1];

                    if (useAgain)
                    {
                        StartButton(line, ButtonPosition.Top, switchList[i], buttonTime);
                    }

                    return;
                }
                else
                {
                    if (switchList[i] == middleTexture)
                    {
                        world.StartSound(line.SoundOrigin, sound, SfxType.Misc);
                        frontSide.MiddleTexture = switchList[i ^ 1];

                        if (useAgain)
                        {
                            StartButton(line, ButtonPosition.Middle, switchList[i], buttonTime);
                        }

                        return;
                    }
                    else
                    {
                        if (switchList[i] == bottomTexture)
                        {
                            world.StartSound(line.SoundOrigin, sound, SfxType.Misc);
                            frontSide.BottomTexture = switchList[i ^ 1];

                            if (useAgain)
                            {
                                StartButton(line, ButtonPosition.Bottom, switchList[i], buttonTime);
                            }

                            return;
                        }
                    }
                }
            }
        }
Esempio n. 21
0
        public override void Run()
        {
            var sa = world.SectorAction;

            SectorActionResult result;

            switch (direction)
            {
            case 0:
                // Waiting.
                if (--topCountDown == 0)
                {
                    switch (type)
                    {
                    case VerticalDoorType.BlazeRaise:
                        // Time to go back down.
                        direction = -1;
                        world.StartSound(sector.SoundOrigin, Sfx.BDCLS, SfxType.Misc);
                        break;

                    case VerticalDoorType.Normal:
                        // Time to go back down.
                        direction = -1;
                        world.StartSound(sector.SoundOrigin, Sfx.DORCLS, SfxType.Misc);
                        break;

                    case VerticalDoorType.Close30ThenOpen:
                        direction = 1;
                        world.StartSound(sector.SoundOrigin, Sfx.DOROPN, SfxType.Misc);
                        break;

                    default:
                        break;
                    }
                }
                break;

            case 2:
                // Initial wait.
                if (--topCountDown == 0)
                {
                    switch (type)
                    {
                    case VerticalDoorType.RaiseIn5Mins:
                        direction = 1;
                        type      = VerticalDoorType.Normal;
                        world.StartSound(sector.SoundOrigin, Sfx.DOROPN, SfxType.Misc);
                        break;

                    default:
                        break;
                    }
                }
                break;

            case -1:
                // Down.
                result = sa.MovePlane(
                    sector,
                    speed,
                    sector.FloorHeight,
                    false, 1, direction);
                if (result == SectorActionResult.PastDestination)
                {
                    switch (type)
                    {
                    case VerticalDoorType.BlazeRaise:
                    case VerticalDoorType.BlazeClose:
                        sector.SpecialData = null;
                        // Unlink and free.
                        world.Thinkers.Remove(this);
                        world.StartSound(sector.SoundOrigin, Sfx.BDCLS, SfxType.Misc);
                        break;

                    case VerticalDoorType.Normal:
                    case VerticalDoorType.Close:
                        sector.SpecialData = null;
                        // Unlink and free.
                        world.Thinkers.Remove(this);
                        break;

                    case VerticalDoorType.Close30ThenOpen:
                        direction    = 0;
                        topCountDown = 35 * 30;
                        break;

                    default:
                        break;
                    }
                }
                else if (result == SectorActionResult.Crushed)
                {
                    switch (type)
                    {
                    case VerticalDoorType.BlazeClose:
                    case VerticalDoorType.Close:                                     // Do not go back up!
                        break;

                    default:
                        direction = 1;
                        world.StartSound(sector.SoundOrigin, Sfx.DOROPN, SfxType.Misc);
                        break;
                    }
                }
                break;

            case 1:
                // Up.
                result = sa.MovePlane(
                    sector,
                    speed,
                    topHeight,
                    false, 1, direction);

                if (result == SectorActionResult.PastDestination)
                {
                    switch (type)
                    {
                    case VerticalDoorType.BlazeRaise:
                    case VerticalDoorType.Normal:
                        // Wait at top.
                        direction    = 0;
                        topCountDown = topWait;
                        break;

                    case VerticalDoorType.Close30ThenOpen:
                    case VerticalDoorType.BlazeOpen:
                    case VerticalDoorType.Open:
                        sector.SpecialData = null;
                        // Unlink and free.
                        world.Thinkers.Remove(this);
                        break;

                    default:
                        break;
                    }
                }
                break;
            }
        }
Esempio n. 22
0
        public override void Run()
        {
            SectorActionResult result;

            var sa = world.SectorAction;

            switch (direction)
            {
            case 0:
                // In statis.
                break;

            case 1:
                // Up.
                result = sa.MovePlane(
                    sector,
                    speed,
                    topHeight,
                    false,
                    1,
                    direction);

                if ((world.LevelTime & 7) == 0)
                {
                    switch (type)
                    {
                    case CeilingMoveType.SilentCrushAndRaise:
                        break;

                    default:
                        world.StartSound(sector.SoundOrigin, Sfx.STNMOV, SfxType.Misc);
                        break;
                    }
                }

                if (result == SectorActionResult.PastDestination)
                {
                    switch (type)
                    {
                    case CeilingMoveType.RaiseToHighest:
                        sa.RemoveActiveCeiling(this);
                        break;

                    case CeilingMoveType.SilentCrushAndRaise:
                    case CeilingMoveType.FastCrushAndRaise:
                    case CeilingMoveType.CrushAndRaise:
                        if (type == CeilingMoveType.SilentCrushAndRaise)
                        {
                            world.StartSound(sector.SoundOrigin, Sfx.PSTOP, SfxType.Misc);
                        }
                        direction = -1;
                        break;

                    default:
                        break;
                    }
                }
                break;

            case -1:
                // Down.
                result = sa.MovePlane(
                    sector,
                    speed,
                    bottomHeight,
                    crush,
                    1,
                    direction);

                if ((world.LevelTime & 7) == 0)
                {
                    switch (type)
                    {
                    case CeilingMoveType.SilentCrushAndRaise:
                        break;

                    default:
                        world.StartSound(sector.SoundOrigin, Sfx.STNMOV, SfxType.Misc);
                        break;
                    }
                }

                if (result == SectorActionResult.PastDestination)
                {
                    switch (type)
                    {
                    case CeilingMoveType.SilentCrushAndRaise:
                    case CeilingMoveType.CrushAndRaise:
                    case CeilingMoveType.FastCrushAndRaise:
                        if (type == CeilingMoveType.SilentCrushAndRaise)
                        {
                            world.StartSound(sector.SoundOrigin, Sfx.PSTOP, SfxType.Misc);
                        }
                        if (type == CeilingMoveType.CrushAndRaise)
                        {
                            speed = SectorAction.CeilingSpeed;
                        }
                        direction = 1;
                        break;

                    case CeilingMoveType.LowerAndCrush:
                    case CeilingMoveType.LowerToFloor:
                        sa.RemoveActiveCeiling(this);
                        break;

                    default:
                        break;
                    }
                }
                else
                {
                    if (result == SectorActionResult.Crushed)
                    {
                        switch (type)
                        {
                        case CeilingMoveType.SilentCrushAndRaise:
                        case CeilingMoveType.CrushAndRaise:
                        case CeilingMoveType.LowerAndCrush:
                            speed = SectorAction.CeilingSpeed / 8;
                            break;

                        default:
                            break;
                        }
                    }
                }
                break;
            }
        }
Esempio n. 23
0
        public void ZMovement(Mobj thing)
        {
            // Check for smooth step up.
            if (thing.Player != null && thing.Z < thing.FloorZ)
            {
                thing.Player.ViewHeight -= thing.FloorZ - thing.Z;

                thing.Player.DeltaViewHeight = new Fixed((Player.VIEWHEIGHT - thing.Player.ViewHeight).Data >> 3);
            }

            // Adjust height.
            thing.Z += thing.MomZ;

            if ((thing.Flags & MobjFlags.Float) != 0 && thing.Target != null)
            {
                // Float down towards target if too close.
                if ((thing.Flags & MobjFlags.SkullFly) == 0 && (thing.Flags & MobjFlags.InFloat) == 0)
                {
                    var dist = Geometry.AproxDistance(thing.X - thing.Target.X, thing.Y - thing.Target.Y);

                    var delta = (thing.Target.Z + new Fixed(thing.Height.Data >> 1)) - thing.Z;

                    if (delta < Fixed.Zero && dist < -(delta * 3))
                    {
                        thing.Z -= FloatSpeed;
                    }
                    else if (delta > Fixed.Zero && dist < (delta * 3))
                    {
                        thing.Z += FloatSpeed;
                    }
                }
            }

            // Clip movement.
            if (thing.Z <= thing.FloorZ)
            {
                // Hit the floor.

                // Note (id):
                //  somebody left this after the setting momz to 0,
                //  kinda useless there.
                //
                // cph - This was the a bug in the linuxdoom-1.10 source which
                //  caused it not to sync Doom 2 v1.9 demos. Someone
                //  added the above comment and moved up the following code. So
                //  demos would desync in close lost soul fights.
                // Note that this only applies to original Doom 1 or Doom2 demos - not
                //  Final Doom and Ultimate Doom.  So we test demo_compatibility *and*
                //  gamemission. (Note we assume that Doom1 is always Ult Doom, which
                //  seems to hold for most published demos.)
                //
                //  fraggle - cph got the logic here slightly wrong.  There are three
                //  versions of Doom 1.9:
                //
                //  * The version used in registered doom 1.9 + doom2 - no bounce
                //  * The version used in ultimate doom - has bounce
                //  * The version used in final doom - has bounce
                //
                // So we need to check that this is either retail or commercial
                // (but not doom2)

                var correctLostSoulBounce = world.Options.Version >= GameVersion.Ultimate;

                if (correctLostSoulBounce && (thing.Flags & MobjFlags.SkullFly) != 0)
                {
                    // The skull slammed into something.
                    thing.MomZ = -thing.MomZ;
                }

                if (thing.MomZ < Fixed.Zero)
                {
                    if (thing.Player != null && thing.MomZ < -gravity * 8)
                    {
                        // Squat down.
                        // Decrease viewheight for a moment after hitting the ground (hard),
                        // and utter appropriate sound.
                        thing.Player.DeltaViewHeight = new Fixed(thing.MomZ.Data >> 3);
                        world.StartSound(thing, Sfx.OOF);
                    }
                    thing.MomZ = Fixed.Zero;
                }
                thing.Z = thing.FloorZ;

                // cph 2001/05/26 -
                // See lost soul bouncing comment above. We need this here for bug
                // compatibility with original Doom2 v1.9 - if a soul is charging and
                // hit by a raising floor this incorrectly reverses its Y momentum.
                if (!correctLostSoulBounce && (thing.Flags & MobjFlags.SkullFly) != 0)
                {
                    thing.MomZ = -thing.MomZ;
                }

                if ((thing.Flags & MobjFlags.Missile) != 0 && (thing.Flags & MobjFlags.NoClip) == 0)
                {
                    world.ThingInteraction.ExplodeMissile(thing);
                    return;
                }
            }
            else if ((thing.Flags & MobjFlags.NoGravity) == 0)
            {
                if (thing.MomZ == Fixed.Zero)
                {
                    thing.MomZ = -gravity * 2;
                }
                else
                {
                    thing.MomZ -= gravity;
                }
            }

            if (thing.Z + thing.Height > thing.CeilingZ)
            {
                // Hit the ceiling.
                if (thing.MomZ > Fixed.Zero)
                {
                    thing.MomZ = Fixed.Zero;
                }

                {
                    thing.Z = thing.CeilingZ - thing.Height;
                }

                if ((thing.Flags & MobjFlags.SkullFly) != 0)
                {
                    // The skull slammed into something.
                    thing.MomZ = -thing.MomZ;
                }

                if ((thing.Flags & MobjFlags.Missile) != 0 && (thing.Flags & MobjFlags.NoClip) == 0)
                {
                    world.ThingInteraction.ExplodeMissile(thing);
                    return;
                }
            }
        }