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); } }
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); }
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); } }
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); }
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); }
/// <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); }
/// <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); } }
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; } }
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; } } } } }
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; } }
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; } } }
// // 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); }
/// <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); }
// // 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); }
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); }
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); }
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); }
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; } }
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; } }
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; } } } } }
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; } }
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; } }
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; } } }