Back to the Vavoom Forum Archives


Forum

Patch for fixing Strife bugs and some additions

Wed, 10 Feb 2010 15:20:58

Firebrand

I've got a new diff patch:
Index: basev/common/actors/strife/acolyte.txt
===================================================================
--- basev/common/actors/strife/acolyte.txt	(revision 4123)
+++ basev/common/actors/strife/acolyte.txt	(working copy)
@@ -10,6 +10,7 @@
 	PainChance 150
 	MinMissileChance 150
 	Monster
+	+NeverRespawn
 	+SeesDaggers
 	+NoSplashAlert
 	+FloorClip
@@ -18,6 +19,7 @@
 	AttackSound "acolyte/rifle"
 	PainSound "acolyte/pain"
 	DeathSound "acolyte/death"
+	CrushPainSound "misc/pcrush"
 	Obituary "$ob_acolyte"
 
 	action native A_AcolyteBits();
@@ -182,7 +184,8 @@
 	Height 56
 	PainChance 256
 	-CountKill
-	-IsMonster
+//	-IsMonster
+	-NeverRespawn
 	DeathSound "becoming/death"
 
 	action native A_HideDecepticon();
Index: basev/common/actors/strife/alienspectres.txt
===================================================================
--- basev/common/actors/strife/alienspectres.txt	(revision 4123)
+++ basev/common/actors/strife/alienspectres.txt	(working copy)
@@ -13,6 +13,7 @@
 	MinMissileChance 150
 	RenderStyle Translucent
 	Alpha 0.666
+	+NeverRespawn
 	+Shadow
 	+NoGravity
 	+LookAllAround
@@ -105,6 +106,7 @@
 	Radius 24
 	PainChance 50
 	+SpawnCeiling
+	+LowSpectralResist
 	DropItem "Sigil3"
 
 	action native A_Spectre3Attack();
Index: basev/common/actors/strife/loremaster.txt
===================================================================
--- basev/common/actors/strife/loremaster.txt	(revision 4123)
+++ basev/common/actors/strife/loremaster.txt	(working copy)
@@ -11,6 +11,7 @@
 	FloatSpeed 5
 	MinMissileChance 150
 	Monster
+	+NeverRespawn
 	+FloorClip
 	+NoGravity
 	+LookAllAround
Index: basev/common/actors/strife/merchants.txt
===================================================================
--- basev/common/actors/strife/merchants.txt	(revision 4123)
+++ basev/common/actors/strife/merchants.txt	(working copy)
@@ -10,6 +10,7 @@
 	+Shootable
 	+NotDMatch
 	+NoDamage
+	CrushPainSound "misc/pcrush"
 	states
 	{
 	Spawn:
Index: basev/common/actors/strife/peasants.txt
===================================================================
--- basev/common/actors/strife/peasants.txt	(revision 4123)
+++ basev/common/actors/strife/peasants.txt	(working copy)
@@ -11,8 +11,10 @@
 	AttackSound "peasant/attack"
 	PainSound "peasant/pain"
 	DeathSound "peasant/death"
+	CrushPainSound "misc/pcrush"
 	Obituary "$ob_peasant"
 	Monster
+	+NeverRespawn
 	-CountKill
 	+Friendly
 	states
Index: basev/common/actors/strife/ratbuddy.txt
===================================================================
--- basev/common/actors/strife/ratbuddy.txt	(revision 4123)
+++ basev/common/actors/strife/ratbuddy.txt	(working copy)
@@ -13,6 +13,7 @@
 	SeeSound "rat/sight"
 	ActiveSound "rat/active"
 	DeathSound "rat/death"
+	CrushPainSound "misc/pcrush"
 	+IsMonster
 	+FloorClip
 	+CanPass
Index: basev/common/actors/strife/rebels.txt
===================================================================
--- basev/common/actors/strife/rebels.txt	(revision 4123)
+++ basev/common/actors/strife/rebels.txt	(working copy)
@@ -12,10 +12,12 @@
 	-CountKill
 	+FloorClip
 	+Friendly
+	+NeverRespawn
 	SeeSound "rebel/sight"
 	ActiveSound "rebel/active"
 	PainSound "rebel/pain"
 	DeathSound "rebel/death"
+	CrushPainSound "misc/pcrush"
 	Obituary "$ob_rebel"
 	states
 	{
@@ -68,6 +70,7 @@
 	game Strife
 	ConversationID 43, 42, 43
 	DropItem "ClipOfBullets"
+	-NeverRespawn
 }
 
 //------------------------------------------------------------------------------
Index: basev/common/actors/strife/sentinel.txt
===================================================================
--- basev/common/actors/strife/sentinel.txt	(revision 4123)
+++ basev/common/actors/strife/sentinel.txt	(working copy)
@@ -12,6 +12,7 @@
 	PainChance 255
 	MinMissileChance 150
 	Monster
+	+NeverRespawn
 	+SpawnCeiling
 	+NoGravity
 	+DropOff
Index: basev/common/actors/strife/spectral.txt
===================================================================
--- basev/common/actors/strife/spectral.txt	(revision 4123)
+++ basev/common/actors/strife/spectral.txt	(working copy)
@@ -60,6 +60,7 @@
 	Speed 22
 	Damage 100
 	Projectile
+	DamageType "SpectralLow"
 	+Spectral
 	states
 	{
@@ -85,6 +86,7 @@
 	ReactionTime 70
 	RenderStyle Translucent
 	Alpha 0.6
+	DamageType "SpectralLow"
 	+NoBlockmap
 	+NoBlockMonst
 	+NoDropOff
@@ -110,6 +112,7 @@
 	Speed 30
 	Damage 70
 	Projectile
+	DamageType "SpectralLow"
 	+Spectral
 
 	action native A_SpectralLightningTail();
@@ -161,6 +164,7 @@
 	Speed 30
 	Damage 70
 	Projectile
+	DamageType "SpectralLow"
 	+Spectral
 	states
 	{
Index: basev/common/actors/strife/strifebishop.txt
===================================================================
--- basev/common/actors/strife/strifebishop.txt	(revision 4123)
+++ basev/common/actors/strife/strifebishop.txt	(working copy)
@@ -18,6 +18,7 @@
 	Obituary "$ob_stfbishop"
 	DropItem "CrateOfMissiles", 256, 20
 	Monster
+	+NeverRespawn
 	+FloorClip
 	+InCombat
 	+NoBlood
Index: basev/common/actors/strife/strifehumanoid.txt
===================================================================
--- basev/common/actors/strife/strifehumanoid.txt	(revision 4123)
+++ basev/common/actors/strife/strifehumanoid.txt	(working copy)
@@ -3,6 +3,7 @@
 {
 	MaxDropoffHeight 32
 	MaxStepHeight 16
+	CrushPainSound "misc/pcrush"
 	states
 	{
 	Burn:
Index: basev/common/actors/strife/strifeplayer.txt
===================================================================
--- basev/common/actors/strife/strifeplayer.txt	(revision 4123)
+++ basev/common/actors/strife/strifeplayer.txt	(working copy)
@@ -13,6 +13,7 @@
 	Player.ColorRange 128, 143
 	Player.DisplayName "Rebel"
 	Player.StartItem "PunchDagger"
+	CrushPainSound "misc/pcrush"
 	states
 	{
 	Spawn:
Index: basev/common/actors/strife/templar.txt
===================================================================
--- basev/common/actors/strife/templar.txt	(revision 4123)
+++ basev/common/actors/strife/templar.txt	(working copy)
@@ -19,6 +19,7 @@
 	ActiveSound "templar/active"
 	PainSound "templar/pain"
 	DeathSound "templar/death"
+	CrushPainSound "misc/pcrush"
 	Obituary "$ob_templar"
 	HitObituary "$ob_templarhit"
 
Index: basev/common/actors/strife/zombie.txt
===================================================================
--- basev/common/actors/strife/zombie.txt	(revision 4123)
+++ basev/common/actors/strife/zombie.txt	(working copy)
@@ -8,6 +8,7 @@
 	Height 56
 	Translation 0
 	DeathSound "zombie/death"
+	CrushPainSound "misc/pcrush"
 	+Solid
 	+Shootable
 	+ActivateMCross
Index: basev/common/vavoom_decorate_defs.xml
===================================================================
--- basev/common/vavoom_decorate_defs.xml	(revision 4123)
+++ basev/common/vavoom_decorate_defs.xml	(working copy)
@@ -20,6 +20,7 @@
 		<prop_vspeed name="VSpeed" />
 		<prop_speed name="FastSpeed" property="FastSpeed" />
 		<prop_speed name="FloatSpeed" property="FloatSpeed" />
+		<prop_speed name="JumpVelZ" property="JumpVelZ" />
 		<!-- Collision and physics -->
 		<prop_float name="Radius" property="Radius" />
 		<prop_float name="Height" property="Height" />
@@ -36,6 +37,7 @@
 		<prop_name name="SeeSound" property="SightSound" />
 		<prop_name name="AttackSound" property="AttackSound" />
 		<prop_name name="PainSound" property="PainSound" />
+		<prop_name name="CrushPainSound" property="CrushPainSound" />
 		<prop_name name="DeathSound" property="DeathSound" />
 		<prop_name name="ActiveSound" property="ActiveSound" />
 		<prop_name name="HowlSound" property="HowlSound" />
@@ -147,6 +149,7 @@
 		<flag name="ShieldReflect" property="bShieldReflect" />
 		<flag name="Deflect" property="bDeflect" />
 		<flag name="FireResist" property="bFireResist" />
+		<flag name="LowSpectralResist" property="bLowSpectralResist" />
 		<flag name="NoRadiusDmg" property="bNoRadiusDamage" />
 		<flag name="DontBlast" property="bDontBlast" />
 		<flag name="NoTarget" property="bNeverTarget" />
@@ -207,6 +210,7 @@
 		<flag name="DehExplosion" property="bDehExplosion" />
 		<flag_name name="FireDamage" property="DamageType" true_value="Fire" false_value="None" />
 		<flag_name name="IceDamage" property="DamageType" true_value="Ice" false_value="None" />
+		<flag_name name="SpectralLow" property="DamageType" true_value="SpectralLow" false_value="None" />
 		<!-- Miscellaneous -->
 		<flag name="Dropped" property="bDropped" />
 		<flag name="IsMonster" property="bMonster" />
@@ -226,6 +230,7 @@
 		<flag name="FastMelee" property="bFastMelee" />
 		<flag name="BossDeath" property="bBossDeath" />
 		<flag name="UseSpecial" property="bUseSpecial" />
+		<flag name="Touchy" property="bTouchy" />
 		<flag_unsupported name="OldRadiusDmg" />
 		<flag_unsupported name="ClientSideOnly" />
 		<flag_unsupported name="NoInteraction" />
@@ -239,6 +244,7 @@
 		<flag name="JustAttacked" property="bJustAttacked" />
 		<flag name="Teleport" property="bTeleport" />
 		<flag name="SeesDaggers" property="bSeesDaggers" />
+		<flag name="NeverRespawn" property="bNeverRespawn" />
 		<flag_noclip name="NoClip" />
 		<flag_unsupported name="ForceYBillboard" />
 		<flag_unsupported name="ForceXYBillboard" />
@@ -254,6 +260,8 @@
 		<!-- Vavoom specific -->
 		<flag name="FallingFriction" property="bFallingFriction" />
 		<flag name="CantAutoAim" property="bCantAutoAim" />
+		<flag name="CanJump" property="bCanJump" />
+		<flag name="JumpDown" property="bJumpDown" />
 	</class>
 
 	<class name="Inventory">
Index: basev/strife/mapinfo.txt
===================================================================
--- basev/strife/mapinfo.txt	(revision 4123)
+++ basev/strife/mapinfo.txt	(working copy)
@@ -35,7 +35,7 @@
 skill nightmare
 AmmoFactor 2
 FastMonsters
-DisableCheats
+//DisableCheats
 RespawnTime 16
 SpawnFilter Nightmare
 PicName "m_nmare"
Index: basev/strife/sndinfo.txt
===================================================================
--- basev/strife/sndinfo.txt	(revision 4123)
+++ basev/strife/sndinfo.txt	(working copy)
@@ -248,19 +248,19 @@
 entity/sight					dsmnalse
 entity/active					dsalnact
 entity/melee					dsrevbld
-entity/pain						dsalnpn
+entity/pain					dsalnpn
 entity/death					dsmnaldt
 
 // Kneeling guy
 
-misc/chant						dschant
-misc/static						dsstatic
+misc/chant					dschant
+misc/static					dsstatic
 
 // Rat
 
-rat/sight						dsratact
-rat/active						dsratact
-rat/death						dsratact
+rat/sight					dsratact
+rat/active					dsratact
+rat/death					dsratact
 $singular rat/sight
 
 //==========================================================================
@@ -271,12 +271,12 @@
 
 // Alarm
 
-misc/alarm						dsalarm
+misc/alarm					dsalarm
 $singular misc/alarm
 
 // Water
 
-world/river						dswriver
+world/river					dswriver
 world/waterfall					dswfall
 world/waterdrip					dswdrip
 world/watersplash				dswsplsh
@@ -303,7 +303,7 @@
 world/smallfire					dssmfire
 world/largefire					dslgfire
 woodenbarrel/death				dswbrldt
-ore/explode						dsexplod
+ore/explode					dsexplod
 misc/explosion					dsexplod
 
 world/glassbreak				dsbglass
@@ -320,18 +320,18 @@
 switches/fool					dsdifool
 switches/valve					dsvalve
 switches/sizzle					dsfirxpl
-$alias switches/exitbutn 		switches/normbutn
+$alias switches/exitbutn 			switches/normbutn
 
 // Doors
 
-doors/small_metal_open			dsdrsmto // FIXME
-doors/small_metal_close			dsdrsmtc // FIXME
-doors/large_metal_open			dsdrlmto
-doors/large_metal_close			dsdrlmtc
-doors/large_wood_open			dsdrlwud
-doors/large_wood_close			dsdrlwud
-doors/small_wood_open			dsdrswud
-doors/small_wood_close			dsdrswud
+doors/small_metal_open				dsdrsmto // FIXME
+doors/small_metal_close				dsdrsmtc // FIXME
+doors/large_metal_open				dsdrlmto
+doors/large_metal_close				dsdrlmtc
+doors/large_wood_open				dsdrlwud
+doors/large_wood_close				dsdrlwud
+doors/small_wood_open				dsdrswud
+doors/small_wood_close				dsdrswud
 doors/stone_open				dsdrston
 doors/stone_close				dsdrston
 doors/dr2_open					dsbdopn
@@ -359,6 +359,8 @@
 // Shared by player and others
 
 misc/pcrush						dspcrush
+$limit misc/pcrush 0
+
 misc/gibbed						dsslop
 human/imonfire					dsburnme
 misc/disruptordeath				dsdsrptr
Index: basev/strife/sndseq.txt
===================================================================
--- basev/strife/sndseq.txt	(revision 4123)
+++ basev/strife/sndseq.txt	(working copy)
@@ -40,7 +40,7 @@
 end
 
 :DoorCloseSmallWood
-	play		doors/large_wood_open
+	play		doors/small_wood_close
 	nostopcutoff
 end
 
@@ -134,20 +134,20 @@
 ]
 
 :CeilingNormal
-	playrepeat	plats/pt1_mid
+	playrepeat		plats/pt1_mid
 end
 
 :CeilingSemiSilent
-	stopsound	plats/pt1_stop
+	stopsound		plats/pt1_stop
 end
 
 :Floor
-	playrepeat	plats/pt1_mid
-	stopsound	plats/pt1_stop
+	playrepeat		plats/pt1_mid
+	stopsound		plats/pt1_stop
 end
 
 :Platform
-	playuntildone   plats/pt1_strt
+	playuntildone   	plats/pt1_strt
 	stopsound		plats/pt1_stop
 end
 
Index: progs/common/engine/Entity.vc
===================================================================
--- progs/common/engine/Entity.vc	(revision 4123)
+++ progs/common/engine/Entity.vc	(working copy)
@@ -277,6 +277,7 @@
 bool bActLikeBridge;	// Always allow obkects to pass.
 bool bNoDropOff;		// Can't drop off under any circumstances
 bool bBright;			// Always render full bright
+bool bCanJump;			// A dedicated flag instead of the BOUNCES+FLOAT+sentient as in MBF
 
 int				Health;
 
Index: progs/common/linespec/Actor.Strife.vc
===================================================================
--- progs/common/linespec/Actor.Strife.vc	(revision 4123)
+++ progs/common/linespec/Actor.Strife.vc	(working copy)
@@ -862,7 +862,10 @@
 	emitter.bInCombat = true;
 
 	emitter.Target = target;
-	emitter.SetState(emitter.FindState('Pain'));
+	if (emitter.FindState('Pain'))
+	{
+		emitter.SetState(emitter.FindState('Pain'));
+	}
 
 	for (looker = Sector->ThingList; looker; looker = looker.SNext)
 	{
@@ -880,10 +883,13 @@
 			if (!looker.CanSee(target) && !looker.CanSee(emitter))
 				continue;
 
-			EntityEx(looker).Target = target;
-			looker.PlaySound(SightSound, CHAN_VOICE);
-			looker.SetState(EntityEx(looker).SeeState);
-			EntityEx(looker).bInCombat = true;
+			if (EntityEx(looker).FindState('See'))
+			{
+				EntityEx(looker).Target = target;
+				looker.PlaySound(SightSound, CHAN_VOICE);
+				looker.SetState(EntityEx(looker).FindState('See'));
+				EntityEx(looker).bInCombat = true;
+			}
 		}
 	}
 }
Index: progs/common/linespec/ArtiBlastRadius.vc
===================================================================
--- progs/common/linespec/ArtiBlastRadius.vc	(revision 4123)
+++ progs/common/linespec/ArtiBlastRadius.vc	(working copy)
@@ -63,9 +63,10 @@
 		{
 			continue;
 		}
-		else if (!mo.bMonster && !mo.bIsPlayer && !mo.bMissile)
+		else if (!mo.bMonster && !mo.bCanBlast && !mo.bIsPlayer && !mo.bMissile &&
+				 !mo.bTouchy)
 		{
-			// Must be monster, player, or missile
+			// Must be monster, player, missile or touchy
 			continue;
 		}
 		if (mo.bDormant)
@@ -176,6 +177,12 @@
 			victim.bSlide = true;
 			victim.bBlasted = true;
 		}
+		// Touchy objects die when blasted
+		if (victim.bTouchy)
+		{
+			victim.bArmed = false; // Disarm
+			Damage(victim, source, victim.Health);
+		}
 	}
 }
 
Index: progs/common/linespec/EntityEx.AiUtils.vc
===================================================================
--- progs/common/linespec/EntityEx.AiUtils.vc	(revision 4123)
+++ progs/common/linespec/EntityEx.AiUtils.vc	(working copy)
@@ -1,4 +1,4 @@
-//**************************************************************************
+?//**************************************************************************
 //**
 //**    ##   ##    ##    ##   ##   ####     ####   ###     ###
 //**    ##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
@@ -638,6 +638,7 @@
 	float yspeed;
 	int i;
 	bool try_ok;
+	bool dropoff = false;
 
 	line_t *ld;
 	int good;
@@ -653,15 +654,15 @@
 
 	// Instead of yanking non-floating monsters to the ground,
 	// let gravity drop them down, unless they're moving down a step.
-	if (!bNoGravity && Origin.z > FloorZ /*&& !bOnMobj*/)
+	if (!bNoGravity && Origin.z > FloorZ && !bOnMobj)
 	{
-		if (Origin.z > FloorZ + MaxStepHeight)
+		if (Origin.z <= FloorZ + MaxStepHeight)
 		{
-			return false;
+			Origin.z = FloorZ;
 		}
 		else
 		{
-			Origin.z = FloorZ;
+			return false;
 		}
 	}
 
@@ -708,8 +709,18 @@
 	tmtrace_t tmtrace;
 	for (i = 1; i < steps; i++)
 	{
+		// killough 10/98: allow actors to drop off of taller ledges sometimes.
+		// dropoff==1 means only up to 128 high, and only if the target is
+		// immediately on the other side of the line.
+		if (bJumpDown && Target && !Target.IsFriend(self) &&
+			DistTo(Target) < 144.0 && P_Random() < 235 &&
+			!(tmtrace.FloorZ - tmtrace.DropOffZ > 128.0 ||
+			  !Target || Target.Origin.z > tmtrace.DropOffZ))
+		{
+			dropoff = true;
+		}
 		try_ok = TryMoveEx(&tmtrace, vector(origx + (deltax / itof(steps * i)), origy +
-					(deltay / itof(steps * i)), Origin.z), false);
+					(deltay / itof(steps * i)), Origin.z), dropoff);
 		if (!try_ok)
 		{
 			break;
@@ -719,7 +730,17 @@
 	// killough 3/15/98: don't jump over dropoffs:
 	if (try_ok)
 	{
-		try_ok = TryMoveEx(&tmtrace, vector(tryx, tryy, Origin.z), false);
+		// killough 10/98: allow actors to drop off of taller ledges sometimes.
+		// dropoff==1 means only up to 128 high, and only if the target is
+		// immediately on the other side of the line.
+		if (bJumpDown && Target && !Target.IsFriend(self) &&
+			DistTo(Target) < 144.0 && P_Random() < 235 &&
+			!(tmtrace.FloorZ - tmtrace.DropOffZ > 128.0 ||
+			  !Target || Target.Origin.z > tmtrace.DropOffZ))
+		{
+			dropoff = true;
+		}
+		try_ok = TryMoveEx(&tmtrace, vector(tryx, tryy, Origin.z), dropoff);
 	}
 
 	if (!try_ok)
@@ -739,7 +760,45 @@
 			bInFloat = true;
 			return true;
 		}
+		if (bCanJump && !bFloat && tmtrace.bFloatOk && 
+			(Origin.z <= FloorZ || bOnMobj) && !JumpTime)
+		{
+			if (tmtrace.FloorZ - Origin.z <= 48.0 && Target &&
+				tmtrace.FloorZ - Target.Origin.z <= 48.0)
+			{
+				float DeltaX;
+				float DeltaY;
+				TVec dir;
+				TAVec ang;
 
+				CheckDropOff(DeltaX, DeltaY);
+				dir = Target.Origin - Origin;
+				VectorAngles(&dir, &ang);
+
+				if (DeltaX > 0.0)
+				{
+					Velocity.x += 0.6 * 35.0 * cos(ang.yaw);
+				}
+				else
+				{
+					Velocity.x += 0.6 * 35.0 * cos(-ang.yaw);
+				}
+				
+				if (DeltaY > 0.0)
+				{
+					Velocity.y += 0.6 * 35.0 * sin(ang.yaw);
+				}
+				else
+				{
+					Velocity.y += 0.6 * 35.0 * sin(-ang.yaw);
+				}
+				Velocity.z = (JumpVelZ * 1.1) * 35.0;
+				bOnMobj = false;
+				JumpTime = 0.5;
+				return true;
+			}
+		}
+
 		if (!tmtrace.SpecHit.Num)
 		{
 			return false;
@@ -768,13 +827,12 @@
 		{
 			ld = tmtrace.SpecHit[tmtrace.SpecHit.Num - 1];
 			tmtrace.SpecHit.Num = tmtrace.SpecHit.Num - 1;
-			// if the special is not a door
-			// that can be opened,
-			// return false
+			// if the special is not a door that can be opened
+			// then return false
 			if ((bCanUseWalls && LineSpecialLevelInfo(Level).ActivateLine(ld, self, 0, SPAC_Use)) ||
 			    (bActivatePushWall && LineSpecialLevelInfo(Level).ActivateLine(ld, self, 0, SPAC_Push)))
 			{
-				good |= ld == tmtrace.BlockingLine ? 1 : 2;//true;
+				good |= ld == tmtrace.BlockingLine ? 1 : 2; //true;
 			}
 		}
 		return good && ((P_Random() >= 203) ^ (good & 1));
@@ -1028,16 +1086,18 @@
 		dist = DistTo(Target);
 
 		if (Target.Health > 0)
-	    {   // Live enemy target
+	    {
+			// Enemy target is alive
 			if (GetCvar('monster_backing') && MissileState &&
 				/*actor->type != MT_SKULL &&*/
 				((!Target.MissileState && dist < MELEERANGE * 2.0) ||
 				(Target.Player && PlayerEx(Target.Player).ReadyWeapon.bBotMelee &&
 				dist < MELEERANGE * 3.0)))
-			{       // Back away from melee attacker
-					strafecount = P_Random() & 15;
-					deltax = -deltax;
-					deltay = -deltay;
+			{
+				// Back away from melee attacker
+				strafecount = P_Random() & 15;
+				deltax = -deltax;
+				deltay = -deltay;
 			}
 		}
 	}
@@ -1096,7 +1156,6 @@
 
 	// If the actor elects to continue in its current direction, let it do
 	// so unless the way is blocked. Then it must turn.
-
 	turndir = (P_Random() & 1) ? -1 : 1;
 
 	if (olddir == DI_NODIR)
Index: progs/common/linespec/EntityEx.Damage.vc
===================================================================
--- progs/common/linespec/EntityEx.Damage.vc	(revision 4123)
+++ progs/common/linespec/EntityEx.Damage.vc	(working copy)
@@ -1,4 +1,4 @@
-//**************************************************************************
+?//**************************************************************************
 //**
 //**    ##   ##    ##    ##   ##   ####     ####   ###     ###
 //**    ##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
@@ -39,7 +39,7 @@
 final void Damage(EntityEx inflictor, EntityEx source, int damage,
 	optional name DmgType, optional bool NoArmor)
 {
-	int			i;
+	int	i;
 
 	if (!bShootable)
 	{
@@ -137,6 +137,11 @@
 		}
 	}
 
+	if (DmgType == 'SpectralLow' && bLowSpectralResist)
+	{
+		damage = 0;
+	}
+
 	if (DmgType == 'Fire' && bFireResist)
 	{
 		damage >>= 1;
Index: progs/common/linespec/EntityEx.Defaults.vc
===================================================================
--- progs/common/linespec/EntityEx.Defaults.vc	(revision 4123)
+++ progs/common/linespec/EntityEx.Defaults.vc	(working copy)
@@ -43,6 +43,7 @@
 	MeleeRange = 44.0;	//	MELEERANGE(64.0) - 20.0
 	MissileHeight = 32.0;
 	WoundHealth = 6;
+	JumpVelZ = 9.5;
 	BloodType = Blood;
 	BloodSplatterType = BloodSplatter;
 	AxeBloodType = AxeBlood;
Index: progs/common/linespec/EntityEx.Head.vc
===================================================================
--- progs/common/linespec/EntityEx.Head.vc	(revision 4123)
+++ progs/common/linespec/EntityEx.Head.vc	(working copy)
@@ -135,6 +135,7 @@
 name			ActiveSound;
 name			AttackSound;
 name			PainSound;
+name			CrushPainSound;
 name			DeathSound;
 name			HowlSound;
 
@@ -257,6 +258,7 @@
 bool bDeflect;			// Different projectile reflection style
 bool bDontReflect;		// Projectile cannot be reflected
 bool bFireResist;		// Actor takes half damage from fire.
+bool bLowSpectralResist;	// Actor resists full damage from first sigil projectiles.
 bool bDontSquash;		// Death ball can't squash this actor
 bool bNoTeleOther;		// Monster is not affected by teleport other artifact
 bool bDontHurtSpecies;	// Don't hurt own species with explosions.
@@ -280,8 +282,11 @@
 bool bBloodSplatter;	// Use blood splatter like in Raven games.
 bool bDehExplosion;		// Use explosion style specified using DeHackEd.
 bool bNoVerticalMeleeRange;	// Does not check vertical distance for melee range
-bool bSummonedMonster;
+bool bSummonedMonster;  // Flag MinotaurFriend and other summoned monsters (i.e. by powerups, etc.)
 bool bSeesDaggers;		// Actor is able to hear dagger attacks
+bool bTouchy;			// killough 11/98: Dies when solids touch it
+bool bArmed;			// Object is armed (for touchy objects)
+bool bJumpDown;			// Generalization of dog behavior with dropoffs.
 
 //  Params
 float			Speed;
@@ -415,6 +420,11 @@
 
 int				SkillRespawnCount;
 
+//	Customiseable Jump Velocity
+float			JumpVelZ;
+
+float			JumpTime;
+
 replication
 {
 	reliable if (Role == ROLE_Authority && bNetOwner)
Index: progs/common/linespec/EntityEx.Misc.vc
===================================================================
--- progs/common/linespec/EntityEx.Misc.vc	(revision 4123)
+++ progs/common/linespec/EntityEx.Misc.vc	(working copy)
@@ -1,4 +1,4 @@
-//**************************************************************************
+?//**************************************************************************
 //**
 //**    ##   ##    ##    ##   ##   ####     ####   ###     ###
 //**    ##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
@@ -644,205 +644,232 @@
 
 	Other = EntityEx(InOther);
 
-	//	For Korax Arena
-	if (Other.IsTouched(self))
+	if (Other)
 	{
-		return !Other.bSolid && !Other.bSpecial && !Other.bShootable;
-	}
-	
-	if (!Other.bSolid && !Other.bSpecial && !Other.bShootable)
-	{
-		return true;
-	}
-
-	// check for skulls slamming into things
-	if (bSkullFly && Health > 0)
-	{
-		return Slam(Other);
-	}
-
-	// Check for blasted thing running into another
-	if (bBlasted && Other.bShootable)
-	{
-		if (!Other.bBoss && Other.bMonster)
+		//	For Korax Arena
+		if (Other.IsTouched(self))
 		{
-			Other.Velocity.x += Velocity.x;
-			Other.Velocity.y += Velocity.y;
-			if ((Other.Velocity.x + Other.Velocity.y) > 3.0 * 35.0)
-			{
-				damage = (ftoi(Mass) / 100) + 1;
-				Other.Damage(self, self, damage);
-				damage = (ftoi(Other.Mass) / 100) + 1;
-				Damage(Other, Other, damage >> 2);
-			}
-			return false;
+			return !Other.bSolid && !Other.bSpecial && (!Other.bShootable || !Other.bTouchy);
 		}
-	}
-
-	// missiles can hit other things
-	if (bMissile)
-	{
-		// Check for a non-shootable mobj
-		if (Other.bNonShootable)
+		
+		if (!Other.bSolid && !Other.bSpecial && (!Other.bShootable || !Other.bTouchy))
 		{
 			return true;
 		}
-		// Check for passing through a ghost
-		if (Other.bGhost && bThruGhost)
+
+		// touchy object is alive, toucher is solid
+		if (Other.bTouchy && bSolid && Other.Health > 0 &&
+			// Thing is an armed mine or a sentient thing
+			(Other.bArmed || Other.IsSentient()) &&
+			// either different classes or players
+			(Other.bIsPlayer || Other.Class != Class) &&
+			// or different species if DONTHARMSPECIES
+		   (!(Other.bDontHurtSpecies) || Other.GetSpecies() != GetSpecies()) &&
+		   // touches vertically
+		   Other.Origin.z + Other.Height >= Origin.z && Origin.z + Height >= Other.Origin.z &&
+		   // prevents lost souls from exploding when fired by pain elementals
+		   (Other.Master != self && Master != Other))
+		// Difference with MBF: MBF hardcodes the LS/PE check and lets actors of the same species
+		// but different classes trigger the touchiness, but that seems less straightforwards.
 		{
+			bArmed = false; // Disarm
+			Other.Damage(none, none, Other.Health);  // kill object
 			return true;
 		}
 
-		if ((BounceType == BOUNCE_Doom || BounceType == BOUNCE_Hexen) &&
-			MissileDamage == 0)
+		// check for skulls slamming into things
+		if (bSkullFly && Health > 0)
 		{
-			return Target == Other || !Other.bSolid;
+			return Slam(Other);
 		}
 
-		switch (SpecialMissileHit(Other))
+		// Check for blasted thing running into another
+		if (bBlasted && Other.bShootable)
 		{
-		case 0:
-			return false;
-		case 1:
-			return true;
+			if (!Other.bBoss && Other.bMonster)
+			{
+				Other.Velocity.x += Velocity.x;
+				Other.Velocity.y += Velocity.y;
+				if ((Other.Velocity.x + Other.Velocity.y) > 3.0 * 35.0)
+				{
+					damage = (ftoi(Mass) / 100) + 1;
+					Other.Damage(self, self, damage);
+					damage = (ftoi(Other.Mass) / 100) + 1;
+					Damage(Other, Other, damage >> 2);
+				}
+				return false;
+			}
 		}
 
-		if (Target)
+		// missiles can hit other things
+		if (bMissile)
 		{
-			// Don't hit same species as originator.
-			if (Other == Target)
+			// Check for a non-shootable mobj
+			if (Other.bNonShootable)
 			{
-				// Don't missile self
 				return true;
 			}
-			//	Let players missile other players.
-			if (!Target.bIsPlayer && !Other.bIsPlayer)
+			// Check for passing through a ghost
+			if (Other.bGhost && bThruGhost)
 			{
-				int Inf = Target.GetInfighting();
-				if (Inf < 0)
+				return true;
+			}
+
+			if ((BounceType == BOUNCE_Doom || BounceType == BOUNCE_Hexen) &&
+				MissileDamage == 0)
+			{
+				return Target == Other || !Other.bSolid;
+			}
+
+			switch (SpecialMissileHit(Other))
+			{
+			case 0:
+				return false;
+			case 1:
+				return true;
+			}
+
+			if (Target)
+			{
+				// Don't hit same species as originator.
+				if (Other == Target)
 				{
-					//	Monsters can't hurt each other, but make exception
-					// depending on friendliness and hate status.
-					if (Target.bShootable)
+					// Don't missile self
+					return true;
+				}
+				//	Let players missile other players.
+				if (!Target.bIsPlayer && !Other.bIsPlayer)
+				{
+					int Inf = Target.GetInfighting();
+					if (Inf < 0)
 					{
-						if (!Other.bMonster)
+						//	Monsters can't hurt each other, but make exception
+						// depending on friendliness and hate status.
+						if (Target.bShootable)
 						{
-							return false;
-						}
-						//	Hostile monsters can always hurt each other.
-						if (!Other.IsHostile(Target))
-						{
-							//	The same if the shooter hates the target.
-							if (!Other.TID || Target.TIDToHate != Other.TID)
+							if (!Other.bMonster)
 							{
 								return false;
 							}
+							//	Hostile monsters can always hurt each other.
+							if (!Other.IsHostile(Target))
+							{
+								//	The same if the shooter hates the target.
+								if (!Other.TID || Target.TIDToHate != Other.TID)
+								{
+									return false;
+								}
+							}
 						}
 					}
-				}
-				else if (Inf == 0)
-				{
-					if (Other.IsFriend(Target))
+					else if (Inf == 0)
 					{
-						//	Don't hurt friends.
-						return false;
-					}
-					if (Other.TIDToHate && Other.TIDToHate == Target.TIDToHate)
-					{
-						//	Don't hurt monsters that hate the same thing as you do.
-						return false;
-					}
-					if (Target.GetSpecies() == Other.GetSpecies())
-					{
-						//	Don't hurt same species, but only if the target
-						// isn't one's hostile.
-						if (!Other.IsHostile(Target))
+						if (Other.IsFriend(Target))
 						{
-							//	Allow hurting monsters the shooter hates.
-							if (Other.TID == 0 || Target.TIDToHate != Other.TID)
+							//	Don't hurt friends.
+							return false;
+						}
+						if (Other.TIDToHate && Other.TIDToHate == Target.TIDToHate)
+						{
+							//	Don't hurt monsters that hate the same thing as you do.
+							return false;
+						}
+						if (Target.GetSpecies() == Other.GetSpecies())
+						{
+							//	Don't hurt same species, but only if the target
+							// isn't one's hostile.
+							if (!Other.IsHostile(Target))
 							{
-								return false;
+								//	Allow hurting monsters the shooter hates.
+								if (Other.TID == 0 || Target.TIDToHate != Other.TID)
+								{
+									return false;
+								}
 							}
 						}
 					}
 				}
 			}
-		}
 
-		if (!Other.bShootable)
-		{
-			// didn't do any damage
-			return !Other.bSolid;
-		}
+			if (!Other.bShootable)
+			{
+				// didn't do any damage
+				return !Other.bSolid;
+			}
 
-		//	Don't hit spectres with non-sigil weapons.
-		if (Other.bSpectral && !bSpectral)
-		{
-			return true;
-		}
+			//	Don't hit spectres with non-sigil weapons.
+			if (Other.bSpectral && !bSpectral)
+			{
+				return true;
+			}
 
-		if (bRip && !Other.bDontRip)
-		{
-			if (!Other.bNoBlood && !Other.bReflective && !Other.bInvulnerable)
+			if (bRip && !Other.bDontRip)
 			{
-				// Ok to spawn some blood
-				SpawnRipperBlood();
+				if (!Other.bNoBlood && !Other.bReflective && !Other.bInvulnerable)
+				{
+					// Ok to spawn some blood
+					SpawnRipperBlood();
+				}
+				PlaySound('misc/ripslop', CHAN_BODY);
+				damage = GetMissileDamage(3, 2);
+				Other.Damage(self, Target, damage, DamageType);
+				if (Other.bPushable && !bCannotPush)
+				{
+					// Push thing
+					Other.Velocity.x += Velocity.x / 4.0;
+					Other.Velocity.y += Velocity.y / 4.0;
+				}
+	//WHAT A FUCK IS THIS???????			numspechit = 0;
+				return true;
 			}
-			PlaySound('misc/ripslop', CHAN_BODY);
-			damage = GetMissileDamage(3, 2);
-			Other.Damage(self, Target, damage, DamageType);
-			if (Other.bPushable && !bCannotPush)
+
+			// damage / explode
+			damage = GetMissileDamage(bStrifeDamage ? 3 : 7, 1);
+			if (damage > 0)
 			{
-				// Push thing
-				Other.Velocity.x += Velocity.x / 4.0;
-				Other.Velocity.y += Velocity.y / 4.0;
+				if (bBloodSplatter && !Other.bNoBlood && !Other.bReflective &&
+					!Other.bInvulnerable && !Other.bDormant &&
+					!bBloodlessImpact && P_Random() < 192)
+				{
+					Other.SpawnBloodSplatter(Origin, damage);
+				}
+				Other.Damage(self, Target, damage, DamageType);
 			}
-//WHAT A FUCK IS THIS???????			numspechit = 0;
-			return true;
+			// don't traverse any more
+			return false;
 		}
 
-		// damage / explode
-		damage = GetMissileDamage(bStrifeDamage ? 3 : 7, 1);
-		if (damage > 0)
+		if (Other.bPushable && !bCannotPush)
 		{
-			if (bBloodSplatter && !Other.bNoBlood && !Other.bReflective &&
-				!Other.bInvulnerable && !Other.bDormant &&
-				!bBloodlessImpact && P_Random() < 192)
+			// Push thing
+			Other.Velocity.x += Velocity.x / 4.0;
+			Other.Velocity.y += Velocity.y / 4.0;
+		}
+
+		solid = Other.bSolid &&
+				Other.bColideWithThings &&
+				bSolid;
+
+		// check for special pickup
+		if (Other.bSpecial /*&&
+			Other.Origin.z < Origin.z + Height - MaxStepHeight*/)
+		{
+			if (Other.bDehackedSpecial)
 			{
-				Other.SpawnBloodSplatter(Origin, damage);
+				Other.TouchDehackedSpecial(self);
 			}
-			Other.Damage(self, Target, damage, DamageType);
+			else
+			{
+				Other.TouchSpecial(self);	// Can remove thing
+			}
 		}
-		// don't traverse any more
-		return false;
-	}
 
-	if (Other.bPushable && !bCannotPush)
-	{
-		// Push thing
-		Other.Velocity.x += Velocity.x / 4.0;
-		Other.Velocity.y += Velocity.y / 4.0;
+		return !solid;
 	}
-
-	solid = Other.bSolid &&
-			Other.bColideWithThings &&
-			bSolid;
-
-	// check for special pickup
-	if (Other.bSpecial/* &&
-		Other.Origin.z < Origin.z + Height - MaxStepHeight*/)
+	else
 	{
-		if (Other.bDehackedSpecial)
-		{
-			Other.TouchDehackedSpecial(self);
-		}
-		else
-		{
-			Other.TouchSpecial(self);	// Can remove thing
-		}
+		return true;
 	}
-
-	return !solid;
 }
 
 //==========================================================================
@@ -1489,6 +1516,15 @@
 		}
 	}
 
+	if (JumpTime)
+	{
+		JumpTime -= deltaTime;
+		if (JumpTime <= 0.0)
+		{
+			JumpTime = 0.0;
+		}
+	}
+
 	if (!Physics(deltaTime))
 	{
 		return;
@@ -1613,6 +1649,14 @@
 		return true;
 	}
 
+	// killough 11/98: kill touchy things immediately
+	if (bTouchy && (bArmed || IsSentient()))
+   	{
+		bArmed = false;; // Disarm
+		Damage(none, none, default.Health);  // kill object
+		return true;
+   	}
+
 	if (!bShootable)
 	{
 		//	Assume it is bloody gibs or something
@@ -1634,6 +1678,10 @@
 				A.Translation = BloodTranslation;
 			}
 		}
+		if (CrushPainSound && !bInvulnerable)
+		{
+			PlaySound(CrushPainSound, CHAN_VOICE);
+		}
 	}
 	return false;	//	Don't fit
 }
@@ -3286,6 +3334,21 @@
 
 //==========================================================================
 //
+//	IsSentient
+//
+//  killough 11/98:
+//  Whether an object is "sentient" or not.
+//  Used for environmental influences.
+//
+//==========================================================================
+
+final bool IsSentient()
+{
+	return Health > 0 && SeeState;
+}
+
+//==========================================================================
+//
 //	IsFast
 //
 //==========================================================================
Index: progs/common/linespec/EntityEx.Physics.vc
===================================================================
--- progs/common/linespec/EntityEx.Physics.vc	(revision 4123)
+++ progs/common/linespec/EntityEx.Physics.vc	(working copy)
@@ -37,6 +37,7 @@
 
 bool Physics(float DeltaTime)
 {
+	float oldfloorz;
 	float CummX = 0.0;
 	float CummY = 0.0;
 	if (Sector->AffectorData && bColideWithWorld && !bNoSector)
@@ -121,7 +122,7 @@
 
 	// momentum movement
 	// Handle X and Y momentums
-	XYMovement(DeltaTime, CummX, CummY);
+	oldfloorz = XYMovement(DeltaTime, CummX, CummY);
 	if (IsDestroyed())
 	{
 		// mobj was removed
@@ -165,7 +166,7 @@
 			{
 				if (bIsPlayer)
 				{
-					if (Velocity.z < -DEFAULT_GRAVITY * 0.25 && !bFly)
+					if (Velocity.z < -DEFAULT_GRAVITY * 0.25 && !bFly && !bNoGravity)
 					{
 						PlayerLandedOnThing();
 					}
@@ -184,6 +185,7 @@
 				}
 				bOnMobj = true;
 				Velocity.z = 0.0;
+				Crash();
 
 				if (onmo.bOnmobjCopyVel)
 				{
@@ -206,7 +208,7 @@
 			}
 			else
 			{
-				ZMovement(DeltaTime);
+				ZMovement(DeltaTime, oldfloorz);
 				bOnMobj = false;
 			}
 			if (IsDestroyed())
@@ -218,7 +220,7 @@
 		else
 		{
 			// Handle Z momentum and gravity
-			ZMovement(DeltaTime);
+			ZMovement(DeltaTime, oldfloorz);
 			if (IsDestroyed())
 			{
 				// entity was removed
@@ -235,13 +237,14 @@
 //
 //==========================================================================
 
-final void XYMovement(float DeltaTime, float ScrollX, float ScrollY)
+final float XYMovement(float DeltaTime, float ScrollX, float ScrollY)
 {
 	float	ptryx;
 	float	ptryy;
 	float	xmove;
 	float	ymove;
 	int		special;
+	float   oldfloorz = FloorZ;
 
 	if (bWindThrust)
 	{
@@ -323,7 +326,12 @@
 			// Reset to not blasted when momentums are gone
 			ResetBlasted();
 		}
-		return;
+		if (bTouchy && !IsSentient())
+		{
+			// Arm a mine which has come to rest
+			bArmed = true;
+		}
+		return oldfloorz;
 	}
 
 	//	Split move in multiple steps if moving too fast.
@@ -367,10 +375,12 @@
 			{
 				HitLine(&tmtrace, DeltaTime / itof(Steps));
 			}
-			return;
+			return oldfloorz;
 		}
 	}
 	while (Step++ < Steps);
+	
+	return oldfloorz;
 }
 
 //==========================================================================
@@ -379,12 +389,28 @@
 //
 //==========================================================================
 
-final void ZMovement(float DeltaTime)
+final void ZMovement(float DeltaTime, float OldFloorZ)
 {
 	float	dist;
 	float	delta;
 	float	OldZ = Origin.z;
 
+	// [RH] Double gravity only if running off a ledge. Coming down from
+	// an upward thrust (e.g. a jump) should not double it.
+	if (Origin.z > FloorZ && !bNoGravity)
+	{
+		float grav = (Gravity * Level.Gravity * Sector->Gravity) / 14.95361328125; // 81.92
+
+		if (Velocity.z == 0.0 && OldFloorZ > FloorZ && Origin.z == OldFloorZ)
+		{
+			Velocity.z -= (grav + grav) * DeltaTime;
+		}
+		else
+		{
+			Velocity.z -= grav * DeltaTime;
+		}
+	}
+
 	// check for smooth step up
 	if (bIsPlayer && Origin.z < FloorZ)
 	{
@@ -394,7 +420,10 @@
 	}
 
 	// adjust height
-	Origin.z += Velocity.z * DeltaTime;
+	if (!bFloatBob)
+	{
+		Origin.z += Velocity.z * DeltaTime;
+	}
 
 	if (bFloat && !bDormant && Target)
 	{
@@ -628,6 +657,15 @@
 			SectorAction::SECSPAC_HitFloor);
 	}
 
+	// killough 11/98: touchy objects explode on impact
+	// Allow very short drops to be safe, so that a touchy can be summoned without exploding.
+	if (bTouchy && (bArmed || IsSentient()) && (Velocity.z < -5.0))
+	{
+		bArmed = false; // Disarm
+		Damage(none, none, Health);  // kill object
+		return true;
+	}
+
 	if (bMissile && (bColideWithWorld ||
 		!LineSpecialGameInfo(Level.Game).bNoClipIgnoreFloor))
 	{
@@ -663,6 +701,10 @@
 		}
 	}
 	Origin.z = FloorZ;
+	if (bCanJump)
+	{
+		JumpTime = 0.2;	// delay any jumping for a short time
+	}
 	if (vdot < -0.1)
 	{
 		// Spawn splashes, etc.
Index: progs/common/linespec/Macil1.vc
===================================================================
--- progs/common/linespec/Macil1.vc	(revision 4123)
+++ progs/common/linespec/Macil1.vc	(working copy)
@@ -93,6 +93,7 @@
 	bNoIceDeath = true;
 	bFireResist = true;
 	bNoDamage = true;
+	bNeverRespawn = true;
 	SightSound = 'macil/sight';
 	ActiveSound = 'macil/active';
 	PainSound = 'macil/pain';
Index: progs/common/linespec/Oracle.vc
===================================================================
--- progs/common/linespec/Oracle.vc	(revision 4123)
+++ progs/common/linespec/Oracle.vc	(working copy)
@@ -82,7 +82,8 @@
 	bFloorClip = true;
 	bPassMobj = true;
 	bCanUseWalls = true;
+	bNoDeathmatch = true;
 	bNoBlood = true;
-	bNoDeathmatch = true;
 	bFireResist = true;
+	bLowSpectralResist = true;
 }
Index: progs/common/linespec/SpectralMonster.vc
===================================================================
--- progs/common/linespec/SpectralMonster.vc	(revision 4123)
+++ progs/common/linespec/SpectralMonster.vc	(working copy)
@@ -194,6 +194,17 @@
 		if (!Target)
 			return;
 
+		Actor A;
+
+		foreach AllThinkers(Oracle, A)
+		{
+			if (A && A.bMonster && A.Health > 0)
+			{
+				// Kill the oracle if his specter dies...
+				EntityEx(A).Damage(none, none, 10000);
+			}
+		}
+
 		Target.Player.cprint("$txt_killed_oracle");
 		Target.GiveInventoryType(QuestItem23);
 		if (Target.FindInventory(QuestItem21))
Index: source/d3d_poly.cpp
===================================================================
--- source/d3d_poly.cpp	(revision 4123)
+++ source/d3d_poly.cpp	(working copy)
@@ -545,6 +545,8 @@
 		SetTexture(Texture1, CMap);
 		TexStage = 1;
 		SetTexture(Texture2, CMap);
+		TexStage = 1;
+		SetTexture(Texture1, CMap);
 		TexStage = 0;
 		for (i = 0; i < surf->count; i++)
 		{
Index: source/d3d_tex.cpp
===================================================================
--- source/d3d_tex.cpp	(revision 4123)
+++ source/d3d_tex.cpp	(working copy)
@@ -222,6 +222,8 @@
 		RenderDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)Tex->DriverData);
 	}
 
+	RenderDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, magfilter);
+	RenderDevice->SetSamplerState(0, D3DSAMP_MINFILTER, minfilter);
 	RenderDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
 	RenderDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
 	tex_iw = 1.0 / Tex->GetWidth();
Index: source/gl_poly.cpp
===================================================================
--- source/gl_poly.cpp	(revision 4123)
+++ source/gl_poly.cpp	(working copy)
@@ -649,6 +649,7 @@
 
 	SetSpriteLump(Tex, Translation, CMap);
 
+	glEnable(GL_ALPHA_TEST);
 	if (blend_sprites || Additive || Alpha < 1.0)
 	{
 		glAlphaFunc(GL_GREATER, 0.0);
@@ -658,7 +659,6 @@
 	{
 		glBlendFunc(GL_SRC_ALPHA, GL_ONE);
 	}
-	glEnable(GL_ALPHA_TEST);
 
 	vuint32 alpha = (int)(255 * Alpha);
 	SetColour((light & 0x00ffffff) | (alpha << 24));
Index: source/p_entity.h
===================================================================
--- source/p_entity.h	(revision 4123)
+++ source/p_entity.h	(working copy)
@@ -230,6 +230,7 @@
 		EF_ActLikeBridge		= 0x08000000,	// Always allow obkects to pass.
 		EF_NoDropOff			= 0x10000000,	// Can't drop off under any circumstances
 		EF_Bright				= 0x20000000,	// Always render full bright
+		EF_CanJump				= 0x40000000,	// This entity can jump to high places
 	};
 	vuint32			EntityFlags;
 
Index: source/p_entity_world.cpp
===================================================================
--- source/p_entity_world.cpp	(revision 4123)
+++ source/p_entity_world.cpp	(working copy)
@@ -1225,12 +1225,14 @@
 			O->CeilingZ - (O->Origin.z + O->Height) < Height ||
 			tmtrace.CeilingZ - (O->Origin.z + O->Height) < Height)
 		{
+			// Can't step up or doesn't fit
 			PushLine(tmtrace);
 			return false;
 		}
 		if (!(EntityFlags & EF_PassMobj) || compat_nopassover ||
 			(Level->LevelInfoFlags2 & VLevelInfo::LIF2_CompatNoPassOver))
 		{
+			// Can't go over
 			return false;
 		}
 	}
@@ -1263,8 +1265,8 @@
 				PushLine(tmtrace);
 				return false;
 			}
-			else if (Origin.z < tmtrace.FloorZ
-				&& tmtrace.FloorZ - tmtrace.DropOffZ > MaxStepHeight)
+			else if (Origin.z < tmtrace.FloorZ &&
+				tmtrace.FloorZ - tmtrace.DropOffZ > MaxStepHeight)
 			{
 				Velocity.z = 8.0 * 35.0;
 				PushLine(tmtrace);
@@ -1276,8 +1278,20 @@
 			if (tmtrace.FloorZ - Origin.z > MaxStepHeight)
 			{
 				// Too big a step up
-				PushLine(tmtrace);
-				return false;
+				if (EntityFlags & EF_CanJump)
+				{
+					// Check to make sure there's nothing in the way for the step up
+					if (TestMobjZ(TVec(newPos.x, newPos.y, tmtrace.FloorZ)))
+					{
+						PushLine(tmtrace);
+						return false;
+					}
+				}
+				else
+				{
+					PushLine(tmtrace);
+					return false;
+				}
 			}
 			if (Origin.z < tmtrace.FloorZ)
 			{
@@ -1769,7 +1783,6 @@
 	if (!(EntityFlags & EF_NoGravity) && (Origin.z > FloorZ ||
 		Floor->normal.z <= 0.7))
 	{
-		//	Add gravity
 		if (WaterLevel < 2)
 		{
 			Velocity.z -= Gravity * Level->Gravity * Sector->Gravity *
Index: source/r_main.cpp
===================================================================
--- source/r_main.cpp	(revision 4123)
+++ source/r_main.cpp	(working copy)
@@ -470,7 +470,7 @@
 
 VCvarI			r_chasecam("r_chasecam", "0", CVAR_Archive);
 VCvarF			r_chase_dist("r_chase_dist", "32.0", CVAR_Archive);
-VCvarF			r_chase_up("r_chase_up", "32.0", CVAR_Archive);
+VCvarF			r_chase_up("r_chase_up", "128.0", CVAR_Archive);
 VCvarF			r_chase_right("r_chase_right", "0", CVAR_Archive);
 VCvarI			r_chase_front("r_chase_front", "0", CVAR_Archive);
 
Index: source/r_tex_png.cpp
===================================================================
--- source/r_tex_png.cpp	(revision 4123)
+++ source/r_tex_png.cpp	(working copy)
@@ -265,7 +265,7 @@
 	}
 	if (ColourType == PNG_COLOR_TYPE_GRAY && BitDepth < 8)
 	{
-		png_set_gray_1_2_4_to_8(png_ptr);
+		png_set_expand_gray_1_2_4_to_8(png_ptr);
 	}
 	if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
 	{
Index: source/screen.cpp
===================================================================
--- source/screen.cpp	(revision 4123)
+++ source/screen.cpp	(working copy)
@@ -471,7 +471,7 @@
 
 //**************************************************************************
 //
-//	General (pubic) stuff
+//	General (public) stuff
 //
 //**************************************************************************
 
Index: source/snd_win32.cpp
===================================================================
--- source/snd_win32.cpp	(revision 4123)
+++ source/snd_win32.cpp	(working copy)
@@ -175,7 +175,7 @@
 	caps.dwSize = sizeof(caps);
 	DSound->GetCaps(&caps);
 	if (caps.dwFreeHw3DStaticBuffers && caps.dwFreeHwMixingStaticBuffers && 
-		!GArgs.CheckParm("-no3dsound"))
+		GArgs.CheckParm("-3dsound"))
 	{
 		Sound3D = true;
 		GCon->Log(NAME_Init, "3D sound on");
Index: utils/vlaunch/vlaunch.cpp
===================================================================
--- utils/vlaunch/vlaunch.cpp	(revision 4123)
+++ utils/vlaunch/vlaunch.cpp	(working copy)
@@ -50,9 +50,13 @@
 public:
 	wxComboBox*		Game;
 	wxComboBox*		RendererBox;
+	wxComboBox*		Resolution;
+	wxComboBox*		Colour;
+	wxTextCtrl*		Particles;
+	wxTextCtrl*		CacheMemory;
 	wxCheckBox*		CheckBoxNoSound;
 	wxCheckBox*		CheckBoxNoSfx;
-	wxCheckBox*		CheckBoxNo3DSound;
+	wxCheckBox*		CheckBox3DSound;
 	wxCheckBox*		CheckBoxNoMusic;
 	wxCheckBox*		CheckBoxNoCDAudio;
 	wxCheckBox*		CheckBoxUseOpenAL;
@@ -148,20 +152,6 @@
 	Game = new wxComboBox(page, -1, GameChoices[0], wxDefaultPosition, wxDefaultSize, 8, GameChoices, wxCB_READONLY);
 	gsizer->Add(Game, 0, wxALL, 4);
 
-	gsizer->Add(new wxStaticText(page, -1, wxT("Renderer:")), 0, wxALL, 4);
-	wxString RendChoices[3];
-	RendChoices[0] = wxT("Software");
-	RendChoices[1] = wxT("OpenGL");
-	RendChoices[2] = wxT("Direct3D");
-	RendererBox = new wxComboBox(page, -1, RendChoices[1], wxDefaultPosition, wxDefaultSize,
-#ifdef _WIN32
-		3,
-#else
-		2,
-#endif
-		RendChoices, wxCB_READONLY);
-	gsizer->Add(RendererBox, 0, wxALL, 4);
-
 	gsizer->Add(new wxStaticText(page, -1, wxT("Custom game:")), 0, wxALL, 4);
 	EditGame = new wxTextCtrl(page, -1, wxT(""), wxDefaultPosition, wxSize(128, -1));
 	gsizer->Add(EditGame, 0, wxALL, 4);
@@ -183,6 +173,53 @@
 	page->SetSizer(gsizer);
 	gsizer->Layout();
 
+	//	Video options
+	page = new wxPanel(nbook);
+	nbook->AddPage(page, wxT("Video"));
+	wxFlexGridSizer* vsizer = new wxFlexGridSizer(2);
+
+	vsizer->Add(new wxStaticText(page, -1, wxT(" ")), 0, wxALL, 4);
+	vsizer->Add(new wxStaticText(page, -1, wxT(" ")), 0, wxALL, 4);
+
+	vsizer->Add(new wxStaticText(page, -1, wxT("Renderer:")), 0, wxALL, 4);
+	wxString RendChoices[3];
+	RendChoices[0] = wxT("Software");
+	RendChoices[1] = wxT("OpenGL");
+	RendChoices[2] = wxT("Direct3D");
+	RendererBox = new wxComboBox(page, -1, RendChoices[1], wxDefaultPosition, wxDefaultSize,
+#ifdef _WIN32
+		3,
+#else
+		2,
+#endif
+		RendChoices, wxCB_READONLY);
+	vsizer->Add(RendererBox, 0, wxALL, 4);
+	vsizer->Add(new wxStaticText(page, -1, wxT("Resolution:")), 0, wxALL, 4);
+	wxString ResolutionChoices[6];
+	ResolutionChoices[0] = wxT("640x480");
+	ResolutionChoices[1] = wxT("800x600");
+	ResolutionChoices[2] = wxT("1024x768");
+	ResolutionChoices[3] = wxT("1152x864");
+	ResolutionChoices[4] = wxT("1280x1024");
+	ResolutionChoices[5] = wxT("1600x1200");
+	Resolution = new wxComboBox(page, -1, ResolutionChoices[0], wxDefaultPosition, wxDefaultSize, 6, ResolutionChoices, wxCB_READONLY);
+	vsizer->Add(Resolution, 0, wxALL, 4);
+	vsizer->Add(new wxStaticText(page, -1, wxT("Color Depth:")), 0, wxALL, 4);
+	wxString ColourChoices[3];
+	ColourChoices[0] = wxT("8 bits");
+	ColourChoices[1] = wxT("16 bits");
+	ColourChoices[2] = wxT("32 bits");
+	Colour = new wxComboBox(page, -1, ColourChoices[0], wxDefaultPosition, wxDefaultSize, 3, ColourChoices, wxCB_READONLY);
+	vsizer->Add(Colour, 0, wxALL, 4);
+	vsizer->Add(new wxStaticText(page, -1, wxT("Particles:")), 0, wxALL, 4);
+	Particles = new wxTextCtrl(page, -1, wxT(""), wxDefaultPosition, wxSize(128, -1));
+	vsizer->Add(Particles, 0, wxALL, 4);
+	vsizer->Add(new wxStaticText(page, -1, wxT("Surface Cache Memory (kb):")), 0, wxALL, 4);
+	CacheMemory = new wxTextCtrl(page, -1, wxT(""), wxDefaultPosition, wxSize(128, -1));
+	vsizer->Add(CacheMemory, 0, wxALL, 4);
+	page->SetSizer(vsizer);
+	vsizer->Layout();
+
 	//	Sound options
 	page = new wxPanel(nbook);
 	nbook->AddPage(page, wxT("Sound"));
@@ -191,12 +228,12 @@
 	bsizer->Add(CheckBoxNoSound, 0, wxALL, 4);
 	CheckBoxNoSfx = new wxCheckBox(page, -1, wxT("No sounds"));
 	bsizer->Add(CheckBoxNoSfx, 0, wxALL, 4);
-	CheckBoxNo3DSound = new wxCheckBox(page, -1, wxT("No 3D sound"));
-	bsizer->Add(CheckBoxNo3DSound, 0, wxALL, 4);
 	CheckBoxNoMusic = new wxCheckBox(page, -1, wxT("No music"));
 	bsizer->Add(CheckBoxNoMusic, 0, wxALL, 4);
 	CheckBoxNoCDAudio = new wxCheckBox(page, -1, wxT("No CD audio"));
 	bsizer->Add(CheckBoxNoCDAudio, 0, wxALL, 4);
+	CheckBox3DSound = new wxCheckBox(page, -1, wxT("Use 3D sound"));
+	bsizer->Add(CheckBox3DSound, 0, wxALL, 4);
 	CheckBoxUseOpenAL = new wxCheckBox(page, -1, wxT("Use OpenAL"));
 	bsizer->Add(CheckBoxUseOpenAL, 0, wxALL, 4);
 	page->SetSizer(bsizer);
@@ -240,9 +277,13 @@
 	wxConfigBase* Conf = wxConfigBase::Get();
 	Game->SetSelection(Conf->Read(wxT("Game"), 0l));
 	RendererBox->SetSelection(Conf->Read(wxT("Renderer"), 0l));
+	Resolution->SetSelection(Conf->Read(wxT("Resolution"), 0l));
+	Colour->SetSelection(Conf->Read(wxT("Colour"), 0l));
+	Particles->SetValue(Conf->Read(wxT("Particles"), wxT("")));
+	CacheMemory->SetValue(Conf->Read(wxT("CacheMemory"), wxT("")));
 	CheckBoxNoSound->SetValue(!!Conf->Read(wxT("NoSound"), 0l));
 	CheckBoxNoSfx->SetValue(!!Conf->Read(wxT("NoSfx"), 0l));
-	CheckBoxNo3DSound->SetValue(!!Conf->Read(wxT("No3DSound"), 0l));
+	CheckBox3DSound->SetValue(!!Conf->Read(wxT("3DSound"), 0l));
 	CheckBoxNoMusic->SetValue(!!Conf->Read(wxT("NoMusic"), 0l));
 	CheckBoxNoCDAudio->SetValue(!!Conf->Read(wxT("NoCDAudio"), 0l));
 	CheckBoxUseOpenAL->SetValue(!!Conf->Read(wxT("UseOpenAL"), 0l));
@@ -271,9 +312,13 @@
 	wxConfigBase* Conf = wxConfigBase::Get();
 	Conf->Write(wxT("Game"), Game->GetSelection());
 	Conf->Write(wxT("Renderer"), RendererBox->GetSelection());
+	Conf->Write(wxT("Resolution"), Resolution->GetSelection());
+	Conf->Write(wxT("Colour"), Colour->GetSelection());
+	Conf->Write(wxT("Particles"), Particles->GetValue());
+	Conf->Write(wxT("CacheMemory"), CacheMemory->GetValue());
 	Conf->Write(wxT("NoSound"), CheckBoxNoSound->IsChecked());
 	Conf->Write(wxT("NoSfx"), CheckBoxNoSfx->IsChecked());
-	Conf->Write(wxT("No3DSound"), CheckBoxNo3DSound->IsChecked());
+	Conf->Write(wxT("3DSound"), CheckBox3DSound->IsChecked());
 	Conf->Write(wxT("NoMusic"), CheckBoxNoMusic->IsChecked());
 	Conf->Write(wxT("NoCDAudio"), CheckBoxNoCDAudio->IsChecked());
 	Conf->Write(wxT("UseOpenAL"), CheckBoxUseOpenAL->IsChecked());
@@ -336,17 +381,25 @@
 		break;
 	}
 
+	// Particles
+	if (Particles->GetValue().Length())
+		CmdLine += wxT(" -particles ") + EditMisc->GetValue();
+
+	// Cache Memory
+	if (CacheMemory->GetValue().Length())
+		CmdLine += wxT(" -surfcache ") + EditMisc->GetValue();
+
 	// Sound
 	if (CheckBoxNoSound->IsChecked())
 		CmdLine += wxT(" -nosound");
 	if (CheckBoxNoSfx->IsChecked())
 		CmdLine += wxT(" -nosfx");
-	if (CheckBoxNo3DSound->IsChecked())
-		CmdLine += wxT(" -no3dsound");
 	if (CheckBoxNoMusic->IsChecked())
 		CmdLine += wxT(" -nomusic");
 	if (CheckBoxNoCDAudio->IsChecked())
 		CmdLine += wxT(" -nocdaudio");
+	if (CheckBox3DSound->IsChecked())
+		CmdLine += wxT(" -3dsound");
 	if (CheckBoxUseOpenAL->IsChecked())
 		CmdLine += wxT(" -openal");
 
@@ -382,6 +435,42 @@
 	if (EditMisc->GetValue().Length())
 		CmdLine += wxT(" ") + EditMisc->GetValue();
 
+	// Set Resolution
+	switch (Resolution->GetSelection())
+	{
+	case 0:
+		CmdLine += wxT(" +setresolution 640 480");
+		break;
+	case 1:
+		CmdLine += wxT(" +setresolution 800 600");
+		break;
+	case 2:
+		CmdLine += wxT(" +setresolution 1024 768");
+		break;
+	case 3:
+		CmdLine += wxT(" +setresolution 1152 864");
+		break;
+	case 4:
+		CmdLine += wxT(" +setresolution 1280 1024");
+		break;
+	case 5:
+		CmdLine += wxT(" +setresolution 1600 1200");
+		break;
+	}
+
+	switch (Colour->GetSelection())
+	{
+	case 0:
+		CmdLine += wxT(" 8");
+		break;
+	case 1:
+		CmdLine += wxT(" 16");
+		break;
+	case 2:
+		CmdLine += wxT(" 32");
+		break;
+	}
+
 	//	Run game
 	wxExecute(CmdLine, wxEXEC_SYNC);
 }
This one fixes most of the bugs reported for Strife, adds video options to the launcher, adds gravity for Z Movement and allows monsters to jump down of dropoffs and jump up in small ledges, let me know what you think.
Sat, 27 Feb 2010 19:48:43

Janis Legzdinsh

Index: basev/strife/mapinfo.txt
===================================================================
--- basev/strife/mapinfo.txt	(revision 4123)
+++ basev/strife/mapinfo.txt	(working copy)
@@ -35,7 +35,7 @@
 skill nightmare
 AmmoFactor 2
 FastMonsters
-DisableCheats
+//DisableCheats
 RespawnTime 16
 SpawnFilter Nightmare
 PicName "m_nmare"
No
Index: progs/common/linespec/Actor.Strife.vc
===================================================================
--- progs/common/linespec/Actor.Strife.vc	(revision 4123)
+++ progs/common/linespec/Actor.Strife.vc	(working copy)
@@ -880,10 +883,13 @@
 			if (!looker.CanSee(target) && !looker.CanSee(emitter))
 				continue;
 
-			EntityEx(looker).Target = target;
-			looker.PlaySound(SightSound, CHAN_VOICE);
-			looker.SetState(EntityEx(looker).SeeState);
-			EntityEx(looker).bInCombat = true;
+			if (EntityEx(looker).FindState('See'))
+			{
+				EntityEx(looker).Target = target;
+				looker.PlaySound(SightSound, CHAN_VOICE);
+				looker.SetState(EntityEx(looker).FindState('See'));
+				EntityEx(looker).bInCombat = true;
+			}
 		}
 	}
 }
OK, but use SeeState instead of FindState('See').
Index: progs/common/linespec/ArtiBlastRadius.vc
===================================================================
--- progs/common/linespec/ArtiBlastRadius.vc	(revision 4123)
+++ progs/common/linespec/ArtiBlastRadius.vc	(working copy)
@@ -63,9 +63,10 @@
 		{
 			continue;
 		}
-		else if (!mo.bMonster && !mo.bIsPlayer && !mo.bMissile)
+		else if (!mo.bMonster && !mo.bCanBlast && !mo.bIsPlayer && !mo.bMissile &&
+				 !mo.bTouchy)
 		{
-			// Must be monster, player, or missile
+			// Must be monster, player, missile or touchy
 			continue;
 		}
 		if (mo.bDormant)
bCanBlast is already handled earlier and is pointless here.
Index: progs/common/linespec/EntityEx.AiUtils.vc
===================================================================
--- progs/common/linespec/EntityEx.AiUtils.vc	(revision 4123)
+++ progs/common/linespec/EntityEx.AiUtils.vc	(working copy)
@@ -1,4 +1,4 @@
-//**************************************************************************
+?//**************************************************************************
 //**
 //**    ##   ##    ##    ##   ##   ####     ####   ###     ###
 //**    ##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
Save it properly.
Index: progs/common/linespec/EntityEx.Damage.vc
===================================================================
--- progs/common/linespec/EntityEx.Damage.vc	(revision 4123)
+++ progs/common/linespec/EntityEx.Damage.vc	(working copy)
@@ -1,4 +1,4 @@
-//**************************************************************************
+?//**************************************************************************
 //**
 //**    ##   ##    ##    ##   ##   ####     ####   ###     ###
 //**    ##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
Again.
Index: progs/common/linespec/EntityEx.Misc.vc
===================================================================
--- progs/common/linespec/EntityEx.Misc.vc	(revision 4123)
+++ progs/common/linespec/EntityEx.Misc.vc	(working copy)
@@ -1,4 +1,4 @@
-//**************************************************************************
+?//**************************************************************************
 //**
 //**    ##   ##    ##    ##   ##   ####     ####   ###     ###
 //**    ##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
Again.
@@ -644,205 +644,232 @@
 
 	Other = EntityEx(InOther);
 
-	//	For Korax Arena
-	if (Other.IsTouched(self))
+	if (Other)
 	{
-		return !Other.bSolid && !Other.bSpecial && !Other.bShootable;
-	}
-	
-	if (!Other.bSolid && !Other.bSpecial && !Other.bShootable)
-	{
-		return true;
-	}
-
-	// check for skulls slamming into things
-	if (bSkullFly && Health > 0)
-	{
-		return Slam(Other);
-	}
-
-	// Check for blasted thing running into another
-	if (bBlasted && Other.bShootable)
-	{
-		if (!Other.bBoss && Other.bMonster)
+		//	For Korax Arena
+		if (Other.IsTouched(self))
 		{
-			Other.Velocity.x += Velocity.x;
-			Other.Velocity.y += Velocity.y;
-			if ((Other.Velocity.x + Other.Velocity.y) > 3.0 * 35.0)
-			{
-				damage = (ftoi(Mass) / 100) + 1;
-				Other.Damage(self, self, damage);
-				damage = (ftoi(Other.Mass) / 100) + 1;
-				Damage(Other, Other, damage >> 2);
-			}
-			return false;
+			return !Other.bSolid && !Other.bSpecial && (!Other.bShootable || !Other.bTouchy);
 		}
-	}
-
-	// missiles can hit other things
-	if (bMissile)
-	{
-		// Check for a non-shootable mobj
-		if (Other.bNonShootable)
+		
+		if (!Other.bSolid && !Other.bSpecial && (!Other.bShootable || !Other.bTouchy))
 		{
 			return true;
 		}
-		// Check for passing through a ghost
-		if (Other.bGhost && bThruGhost)
+
+		// touchy object is alive, toucher is solid
+		if (Other.bTouchy && bSolid && Other.Health > 0 &&
+			// Thing is an armed mine or a sentient thing
+			(Other.bArmed || Other.IsSentient()) &&
+			// either different classes or players
+			(Other.bIsPlayer || Other.Class != Class) &&
+			// or different species if DONTHARMSPECIES
+		   (!(Other.bDontHurtSpecies) || Other.GetSpecies() != GetSpecies()) &&
+		   // touches vertically
+		   Other.Origin.z + Other.Height >= Origin.z && Origin.z + Height >= Other.Origin.z &&
+		   // prevents lost souls from exploding when fired by pain elementals
+		   (Other.Master != self && Master != Other))
+		// Difference with MBF: MBF hardcodes the LS/PE check and lets actors of the same species
+		// but different classes trigger the touchiness, but that seems less straightforwards.
 		{
+			bArmed = false; // Disarm
+			Other.Damage(none, none, Other.Health);  // kill object
 			return true;
 		}
 
-		if ((BounceType == BOUNCE_Doom || BounceType == BOUNCE_Hexen) &&
-			MissileDamage == 0)
+		// check for skulls slamming into things
+		if (bSkullFly && Health > 0)
 		{
-			return Target == Other || !Other.bSolid;
+			return Slam(Other);
 		}
 
-		switch (SpecialMissileHit(Other))
+		// Check for blasted thing running into another
+		if (bBlasted && Other.bShootable)
 		{
-		case 0:
-			return false;
-		case 1:
-			return true;
+			if (!Other.bBoss && Other.bMonster)
+			{
+				Other.Velocity.x += Velocity.x;
+				Other.Velocity.y += Velocity.y;
+				if ((Other.Velocity.x + Other.Velocity.y) > 3.0 * 35.0)
+				{
+					damage = (ftoi(Mass) / 100) + 1;
+					Other.Damage(self, self, damage);
+					damage = (ftoi(Other.Mass) / 100) + 1;
+					Damage(Other, Other, damage >> 2);
+				}
+				return false;
+			}
 		}
 
-		if (Target)
+		// missiles can hit other things
+		if (bMissile)
 		{
-			// Don't hit same species as originator.
-			if (Other == Target)
+			// Check for a non-shootable mobj
+			if (Other.bNonShootable)
 			{
-				// Don't missile self
 				return true;
 			}
-			//	Let players missile other players.
-			if (!Target.bIsPlayer && !Other.bIsPlayer)
+			// Check for passing through a ghost
+			if (Other.bGhost && bThruGhost)
 			{
-				int Inf = Target.GetInfighting();
-				if (Inf < 0)
+				return true;
+			}
+
+			if ((BounceType == BOUNCE_Doom || BounceType == BOUNCE_Hexen) &&
+				MissileDamage == 0)
+			{
+				return Target == Other || !Other.bSolid;
+			}
+
+			switch (SpecialMissileHit(Other))
+			{
+			case 0:
+				return false;
+			case 1:
+				return true;
+			}
+
+			if (Target)
+			{
+				// Don't hit same species as originator.
+				if (Other == Target)
 				{
-					//	Monsters can't hurt each other, but make exception
-					// depending on friendliness and hate status.
-					if (Target.bShootable)
+					// Don't missile self
+					return true;
+				}
+				//	Let players missile other players.
+				if (!Target.bIsPlayer && !Other.bIsPlayer)
+				{
+					int Inf = Target.GetInfighting();
+					if (Inf < 0)
 					{
-						if (!Other.bMonster)
+						//	Monsters can't hurt each other, but make exception
+						// depending on friendliness and hate status.
+						if (Target.bShootable)
 						{
-							return false;
-						}
-						//	Hostile monsters can always hurt each other.
-						if (!Other.IsHostile(Target))
-						{
-							//	The same if the shooter hates the target.
-							if (!Other.TID || Target.TIDToHate != Other.TID)
+							if (!Other.bMonster)
 							{
 								return false;
 							}
+							//	Hostile monsters can always hurt each other.
+							if (!Other.IsHostile(Target))
+							{
+								//	The same if the shooter hates the target.
+								if (!Other.TID || Target.TIDToHate != Other.TID)
+								{
+									return false;
+								}
+							}
 						}
 					}
-				}
-				else if (Inf == 0)
-				{
-					if (Other.IsFriend(Target))
+					else if (Inf == 0)
 					{
-						//	Don't hurt friends.
-						return false;
-					}
-					if (Other.TIDToHate && Other.TIDToHate == Target.TIDToHate)
-					{
-						//	Don't hurt monsters that hate the same thing as you do.
-						return false;
-					}
-					if (Target.GetSpecies() == Other.GetSpecies())
-					{
-						//	Don't hurt same species, but only if the target
-						// isn't one's hostile.
-						if (!Other.IsHostile(Target))
+						if (Other.IsFriend(Target))
 						{
-							//	Allow hurting monsters the shooter hates.
-							if (Other.TID == 0 || Target.TIDToHate != Other.TID)
+							//	Don't hurt friends.
+							return false;
+						}
+						if (Other.TIDToHate && Other.TIDToHate == Target.TIDToHate)
+						{
+							//	Don't hurt monsters that hate the same thing as you do.
+							return false;
+						}
+						if (Target.GetSpecies() == Other.GetSpecies())
+						{
+							//	Don't hurt same species, but only if the target
+							// isn't one's hostile.
+							if (!Other.IsHostile(Target))
 							{
-								return false;
+								//	Allow hurting monsters the shooter hates.
+								if (Other.TID == 0 || Target.TIDToHate != Other.TID)
+								{
+									return false;
+								}
 							}
 						}
 					}
 				}
 			}
-		}
 
-		if (!Other.bShootable)
-		{
-			// didn't do any damage
-			return !Other.bSolid;
-		}
+			if (!Other.bShootable)
+			{
+				// didn't do any damage
+				return !Other.bSolid;
+			}
 
-		//	Don't hit spectres with non-sigil weapons.
-		if (Other.bSpectral && !bSpectral)
-		{
-			return true;
-		}
+			//	Don't hit spectres with non-sigil weapons.
+			if (Other.bSpectral && !bSpectral)
+			{
+				return true;
+			}
 
-		if (bRip && !Other.bDontRip)
-		{
-			if (!Other.bNoBlood && !Other.bReflective && !Other.bInvulnerable)
+			if (bRip && !Other.bDontRip)
 			{
-				// Ok to spawn some blood
-				SpawnRipperBlood();
+				if (!Other.bNoBlood && !Other.bReflective && !Other.bInvulnerable)
+				{
+					// Ok to spawn some blood
+					SpawnRipperBlood();
+				}
+				PlaySound('misc/ripslop', CHAN_BODY);
+				damage = GetMissileDamage(3, 2);
+				Other.Damage(self, Target, damage, DamageType);
+				if (Other.bPushable && !bCannotPush)
+				{
+					// Push thing
+					Other.Velocity.x += Velocity.x / 4.0;
+					Other.Velocity.y += Velocity.y / 4.0;
+				}
+	//WHAT A FUCK IS THIS???????			numspechit = 0;
+				return true;
 			}
-			PlaySound('misc/ripslop', CHAN_BODY);
-			damage = GetMissileDamage(3, 2);
-			Other.Damage(self, Target, damage, DamageType);
-			if (Other.bPushable && !bCannotPush)
+
+			// damage / explode
+			damage = GetMissileDamage(bStrifeDamage ? 3 : 7, 1);
+			if (damage > 0)
 			{
-				// Push thing
-				Other.Velocity.x += Velocity.x / 4.0;
-				Other.Velocity.y += Velocity.y / 4.0;
+				if (bBloodSplatter && !Other.bNoBlood && !Other.bReflective &&
+					!Other.bInvulnerable && !Other.bDormant &&
+					!bBloodlessImpact && P_Random() < 192)
+				{
+					Other.SpawnBloodSplatter(Origin, damage);
+				}
+				Other.Damage(self, Target, damage, DamageType);
 			}
-//WHAT A FUCK IS THIS???????			numspechit = 0;
-			return true;
+			// don't traverse any more
+			return false;
 		}
 
-		// damage / explode
-		damage = GetMissileDamage(bStrifeDamage ? 3 : 7, 1);
-		if (damage > 0)
+		if (Other.bPushable && !bCannotPush)
 		{
-			if (bBloodSplatter && !Other.bNoBlood && !Other.bReflective &&
-				!Other.bInvulnerable && !Other.bDormant &&
-				!bBloodlessImpact && P_Random() < 192)
+			// Push thing
+			Other.Velocity.x += Velocity.x / 4.0;
+			Other.Velocity.y += Velocity.y / 4.0;
+		}
+
+		solid = Other.bSolid &&
+				Other.bColideWithThings &&
+				bSolid;
+
+		// check for special pickup
+		if (Other.bSpecial /*&&
+			Other.Origin.z < Origin.z + Height - MaxStepHeight*/)
+		{
+			if (Other.bDehackedSpecial)
 			{
-				Other.SpawnBloodSplatter(Origin, damage);
+				Other.TouchDehackedSpecial(self);
 			}
-			Other.Damage(self, Target, damage, DamageType);
+			else
+			{
+				Other.TouchSpecial(self);	// Can remove thing
+			}
 		}
-		// don't traverse any more
-		return false;
-	}
 
-	if (Other.bPushable && !bCannotPush)
-	{
-		// Push thing
-		Other.Velocity.x += Velocity.x / 4.0;
-		Other.Velocity.y += Velocity.y / 4.0;
+		return !solid;
 	}
-
-	solid = Other.bSolid &&
-			Other.bColideWithThings &&
-			bSolid;
-
-	// check for special pickup
-	if (Other.bSpecial/* &&
-		Other.Origin.z < Origin.z + Height - MaxStepHeight*/)
+	else
 	{
-		if (Other.bDehackedSpecial)
-		{
-			Other.TouchDehackedSpecial(self);
-		}
-		else
-		{
-			Other.TouchSpecial(self);	// Can remove thing
-		}
+		return true;
 	}
-
-	return !solid;
 }
 
 //==========================================================================
Other cannot be none reference so there's no need to check it.
Index: source/d3d_poly.cpp
===================================================================
--- source/d3d_poly.cpp	(revision 4123)
+++ source/d3d_poly.cpp	(working copy)
@@ -545,6 +545,8 @@
 		SetTexture(Texture1, CMap);
 		TexStage = 1;
 		SetTexture(Texture2, CMap);
+		TexStage = 1;
+		SetTexture(Texture1, CMap);
 		TexStage = 0;
 		for (i = 0; i < surf->count; i++)
 		{
No
Index: source/d3d_tex.cpp
===================================================================
--- source/d3d_tex.cpp	(revision 4123)
+++ source/d3d_tex.cpp	(working copy)
@@ -222,6 +222,8 @@
 		RenderDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)Tex->DriverData);
 	}
 
+	RenderDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, magfilter);
+	RenderDevice->SetSamplerState(0, D3DSAMP_MINFILTER, minfilter);
 	RenderDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
 	RenderDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
 	tex_iw = 1.0 / Tex->GetWidth();
No, there's no need to set it here.

Back to the Vavoom Forum Archives