Back to the Vavoom Forum Archives


Forum

Patch for DECORATE extensions and fixes to RandomSpawner

Thu, 10 Jun 2010 14:57:54

Firebrand

I've found a newer version of a RandomSpawner MOD that someone did for ZDoom, it had new items and monsters replacing original actors by RandomSpawners (which is what I used to test it when implementing those), I've found that it has some errors when spawning classes and that ZDoom doesn't even send any warnings about it, so I added a way to know that it's at conflict <!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) -->. I've added a way to make replaced actors inherit their light effects to their replacees (only if they also have the same sprite names, of course). Here's the patch, let me know what you think of it.
Index: basev/common/actors/doom/doomdecorations.txt
===================================================================
--- basev/common/actors/doom/doomdecorations.txt	(revision 4300)
+++ basev/common/actors/doom/doomdecorations.txt	(working copy)
@@ -138,7 +138,7 @@
 {
 	Game Doom
 	Radius 16
-	Height 16
+	Height 54
 	+Solid
 	states
 	{
Index: basev/common/actors/nativeclasses.txt
===================================================================
--- basev/common/actors/nativeclasses.txt	(revision 4300)
+++ basev/common/actors/nativeclasses.txt	(working copy)
@@ -17,7 +17,7 @@
 	action native A_ExtChase(eval bool usemelee, eval bool usemissile,
 		optional evalnot bool playactive, optional eval bool nightmarefast);
 	action native A_FaceTarget();
-	action native A_Die();
+	action native A_Die(optional DamageType);
 	action native A_CentaurDefend();
 	action native A_AlertMonsters();
 	action native A_ClearTarget();
@@ -168,7 +168,7 @@
 	action native A_SeekerMissile(eval int threshold, eval int turnmax);
 	action native A_Tracer();
 	action native A_Tracer2();
-	action native A_Fire();
+	action native A_Fire(optional int Height);
 	action native A_BishopMissileWeave();
 	action native A_CStaffMissileSlither();
 	action native A_Countdown();
Index: basev/common/actors/raven/ravenartifacts.txt
===================================================================
--- basev/common/actors/raven/ravenartifacts.txt	(revision 4300)
+++ basev/common/actors/raven/ravenartifacts.txt	(working copy)
@@ -10,6 +10,7 @@
 	+CountItem
 	+FloatBob
 	+Inventory.PickupFlash
+	HealthPickup.Autouse 1
 	states
 	{
 	Spawn:
@@ -30,6 +31,7 @@
 	+CountItem
 	+FloatBob
 	+Inventory.PickupFlash
+	HealthPickup.Autouse 2
 	states
 	{
 	Spawn:
Index: basev/common/actors/strife/strifeitems.txt
===================================================================
--- basev/common/actors/strife/strifeitems.txt	(revision 4300)
+++ basev/common/actors/strife/strifeitems.txt	(working copy)
@@ -10,6 +10,7 @@
 	Inventory.MaxAmount 20
 	Inventory.Icon "i_stmp"
 	+FloorClip
+	HealthPickup.Autouse 3
 	states
 	{
 	Spawn:
@@ -30,6 +31,7 @@
 	Inventory.MaxAmount 15
 	Inventory.Icon "i_mdkt"
 	+FloorClip
+	HealthPickup.Autouse 3
 	states
 	{
 	Spawn:
Index: basev/common/vavoom_decorate_defs.xml
===================================================================
--- basev/common/vavoom_decorate_defs.xml	(revision 4300)
+++ basev/common/vavoom_decorate_defs.xml	(working copy)
@@ -321,6 +321,10 @@
 		<prop_low_message name="Health.LowMessage" />
 	</class>
 
+	<class name="HealthPickup">
+		<prop_int name="HealthPickup.AutoUse"  property="AutoUseMode"  />
+	</class>
+
 	<class name="PowerupGiver">
 		<prop_powerup_colour name="Powerup.Color" />
 		<prop_tics name="Powerup.Duration" property="EffectTime" />
Index: progs/common/linespec/Actor.MissileMovement.vc
===================================================================
--- progs/common/linespec/Actor.MissileMovement.vc	(revision 4300)
+++ progs/common/linespec/Actor.MissileMovement.vc	(working copy)
@@ -178,7 +178,7 @@
 //
 //==========================================================================
 
-final void A_Fire()
+final void A_Fire(optional int Height)
 {
 	if (!Target || !Tracer)
 	{
@@ -194,7 +194,14 @@
 	UnlinkFromWorld();
 	Origin.x = Tracer.Origin.x + 24.0 * cos(Tracer.Angles.yaw);
 	Origin.y = Tracer.Origin.y + 24.0 * sin(Tracer.Angles.yaw);
-	Origin.z = Tracer.Origin.z;
+	if (!specified_Height)
+	{
+		Origin.z = Tracer.Origin.z;
+	}
+	else
+	{
+		Origin.z = Tracer.Origin.z + itof(Height);
+	}
 	LinkToWorld();
 }
 
Index: progs/common/linespec/Actor.MonsterAi.vc
===================================================================
--- progs/common/linespec/Actor.MonsterAi.vc	(revision 4300)
+++ progs/common/linespec/Actor.MonsterAi.vc	(working copy)
@@ -1004,9 +1004,16 @@
 //
 //==========================================================================
 
-final void A_Die()
+final void A_Die(optional name DamageType)
 {
-	Damage(none, none, Health);
+	if (!specified_DamageType)
+	{
+		Damage(none, none, Health);
+	}
+	else
+	{
+		Damage(none, none, Health, DamageType);
+	}
 }
 
 //==========================================================================
Index: progs/common/linespec/EntityEx.Misc.vc
===================================================================
--- progs/common/linespec/EntityEx.Misc.vc	(revision 4300)
+++ progs/common/linespec/EntityEx.Misc.vc	(working copy)
@@ -2790,65 +2790,174 @@
 {
 	int i;
 	int count;
+	int normalhealth = 0;
+	int superhealth = 0;
+	array<Inventory> normal;
+	array<Inventory> super;
+	Inventory inv;
+	int saved = 0;
 
-	Inventory normal = FindInventory(ArtiHealth);
-	Inventory super = FindInventory(ArtiSuperHealth);
-	if (Level.World.bSkillAutoUseHealth && normal &&
-		(normal.Amount * 25 >= saveHealth))
+	for(inv = Inventory; inv; inv = inv.Inventory)
 	{
+		if (inv.Amount > 0 && ClassIsChildOf(inv.Class, HealthPickup))
+		{
+			int mode = HealthPickup(inv).AutoUseMode;
+
+			if (mode == 1)
+			{
+				normal.Num = normal.Num + 1;
+				normal[normal.Num] = inv;
+			}
+			else if (mode == 2)
+			{
+				super.Num = super.Num + 1;
+				super[super.Num] = inv;
+			}
+		}
+	}
+
+	for(i = 0; i < normal.Num; i++)
+	{
+		normalhealth += normal.Amount * normal.Health;
+	}
+
+	for(i = 0; i < super.Num; i++)
+	{
+		superhealth += super.Amount * super.Health;
+	}
+
+	if (Level.World.bSkillAutoUseHealth && normalhealth >= saveHealth)
+	{
 		// Use quartz flasks
-		count = (saveHealth + 24) / 25;
-		for (i = 0; i < count; i++)
+		while (normal.Num > 0 && saveHealth > 0)
 		{
-			Health += 25;
-			if (!(--normal.Amount))
+			int maxhealth = 0;
+			int index = -1;
+
+			// Find the largest item in the list
+			for(i = 0; i < normal.Num; i++)
 			{
-				// Used last of a type - compact the artifact list
-				normal.Destroy();
+				if (normal.Health > maxhealth)
+				{
+					index = i;
+					maxhealth = normal.Health;
+				}
 			}
+
+			// Now apply the health items, using the same logic as Heretic and Hexen.
+			count = (saveHealth + maxhealth - 1) / maxhealth;
+			for(i = 0; i < count; i++)
+			{
+				saved += maxhealth;
+				saveHealth -= maxhealth;
+				if (!(--normal[index].Amount))
+				{
+					// Used last of a type - compact the artifact list
+					normal[index].Destroy();
+				}
+			}
 		}
+
+		Health += saved;
 	}
-	else if (super && super.Amount * 100 >= saveHealth)
-	{
+	else if (superhealth >= saveHealth)
+	{ 
 		// Use mystic urns
-		count = (saveHealth + 99) / 100;
-		for (i = 0; i < count; i++)
+		while (super.Num > 0 && saveHealth > 0)
 		{
-			Health += 100;
-			if (!(--super.Amount))
+			int maxhealth = 0;
+			int index = -1;
+
+			// Find the largest item in the list
+			for(i = 0; i < super.Num; i++)
 			{
-				// Used last of a type - compact the artifact list
-				super.Destroy();
+				if (super.Health > maxhealth)
+				{
+					index = i;
+					maxhealth = super.Health;
+				}
 			}
+
+			// Now apply the health items, using the same logic as Heretic and Hexen.
+			count = (saveHealth + maxhealth - 1) / maxhealth;
+			for(i = 0; i < count; i++)
+			{
+				saved += maxhealth;
+				saveHealth -= maxhealth;
+				if (!(--super[index].Amount))
+				{
+					// Used last of a type - compact the artifact list
+					super[index].Destroy();
+				}
+			}
 		}
+
+		Health += saved;
 	}
-	else if (Level.World.bSkillAutoUseHealth &&
-		((super ? super.Amount * 100 : 0) +
-		(normal ? normal.Amount * 25 : 0) >= saveHealth))
-	{
-		// Use mystic urns and quartz flasks
-		count = (saveHealth + 24) / 25;
-		saveHealth -= count * 25;
-		for (i = 0; normal && i < count; i++)
+	else if (Level.World.bSkillAutoUseHealth && normalhealth + superhealth >= saveHealth)
+	{ // Use mystic urns and quartz flasks
+		while (normal.Num > 0 && saveHealth > 0)
 		{
-			Health += 25;
-			if (!(--normal.Amount))
+			int maxhealth = 0;
+			int index = -1;
+
+			// Find the largest item in the list
+			for(i = 0; i < normal.Num; i++)
 			{
-				// Used last of a type - compact the artifact list
-				normal.Destroy();
-				normal = none;
+				if (normal.Health > maxhealth)
+				{
+					index = i;
+					maxhealth = normal.Health;
+				}
 			}
+
+			// Now apply the health items, using the same logic as Heretic and Hexen.
+			count = (saveHealth + maxhealth - 1) / maxhealth;
+			for(i = 0; i < count; i++)
+			{
+				saved += maxhealth;
+				saveHealth -= maxhealth;
+				if (!(--normal[index].Amount))
+				{
+					// Used last of a type - compact the artifact list
+					normal[index].Destroy();
+				}
+			}
 		}
-		count = (saveHealth + 99) / 100;
-		for (i = 0; super && i < count; i++)
+
+		Health += saved;
+		if (saveHealth > 0)
 		{
-			Health += 100;
-			if (!(--super.Amount))
+			while (super.Num > 0 && saveHealth > 0)
 			{
-				// Used last of a type - compact the artifact list
-				super.Destroy();
-				super = none;
+				int maxhealth = 0;
+				int index = -1;
+
+				// Find the largest item in the list
+				for(i = 0; i < super.Num; i++)
+				{
+					if (super.Health > maxhealth)
+					{
+						index = i;
+						maxhealth = super.Health;
+					}
+				}
+
+				// Now apply the health items, using the same logic as Heretic and Hexen.
+				count = (saveHealth + maxhealth - 1) / maxhealth;
+				for(i = 0; i < count; i++)
+				{
+					saved += maxhealth;
+					saveHealth -= maxhealth;
+					if (!(--super[index].Amount))
+					{
+						// Used last of a type - compact the artifact list
+						super[index].Destroy();
+					}
+				}
 			}
+
+			Health += saved;
 		}
 	}
 	Player.Health = Health;
@@ -2863,38 +2972,61 @@
 final void AutoUseStrifeHealth(int saveHealth)
 {
 	int i;
+	array<Inventory> Items;
+	Inventory inv;
+	int itemshealth;
 
-	Inventory Item = FindInventory(MedicalKit);
-	if (Item && Item.Amount * 25 >= saveHealth)
+	for(inv = Inventory; inv; inv = inv.Inventory)
 	{
-		// Use medical kits
-		i = (saveHealth + 24) / 25;
-		while (i--)
+		if (inv.Amount > 0 && ClassIsChildOf(inv.Class, HealthPickup))
 		{
-			Health += 25;
-			saveHealth -= 25;
-			if (!(--Item.Amount))
+			int mode = HealthPickup(inv).AutoUseMode;
+
+			if (mode == 3)
 			{
-				Item.Destroy();
+				Items.Num = Items.Num + 1;
+				Items[Items.Num] = inv;
 			}
-			PlaySound('misc/invuse', CHAN_BODY);
 		}
 	}
-	
-	Item = FindInventory(MedPatch);
-	if (saveHealth > 0 && Item && Item.Amount * 10 >= saveHealth)
+
+	for(i = 0; i < Items.Num; i++)
 	{
-		i = (saveHealth + 9) / 10;
-		while (i--)
+		itemshealth += Items.Amount * Items.Health;
+	}
+
+	while (Items.Num > 0)
+	{
+		int maxhealth = 0;
+		int index = -1;
+
+		// Find the largest item in the list
+		for(i = 0; i < Items.Num; i++)
 		{
-			Health += 10;
-			if (!(--Item.Amount))
+			if (Items.Health > maxhealth)
 			{
-				Item.Destroy();
+				index = i;
+				maxhealth = Items.Amount;
 			}
-			PlaySound('misc/invuse', CHAN_BODY);
 		}
+
+		while (Health < 50)
+		{
+			if (!UseInventory(Items[index]))
+			{
+				break;
+			}			
+		}
+		if (Health >= 50)
+		{
+			Player.Health = Health;
+			return;
+		}
+		// Using all of this item was not enough so delete it and restart with the next best one
+		Items[index] = none;
+		Items.Num = Items.Num - 1;
 	}
+
 	Player.Health = Health;
 }
 
Index: progs/common/linespec/HealthPickup.vc
===================================================================
--- progs/common/linespec/HealthPickup.vc	(revision 4300)
+++ progs/common/linespec/HealthPickup.vc	(working copy)
@@ -26,6 +26,8 @@
 class HealthPickup : Inventory
 	abstract;
 
+int AutoUseMode;
+
 //==========================================================================
 //
 //	CreateCopy
@@ -91,4 +93,5 @@
 {
 	MaxAmount = DefMaxAmount;
 	bInvBar = true;
+	AutoUseMode = 0;
 }
Index: progs/common/linespec/RandomSpawner.vc
===================================================================
--- progs/common/linespec/RandomSpawner.vc	(revision 4300)
+++ progs/common/linespec/RandomSpawner.vc	(working copy)
@@ -58,6 +58,15 @@
 				n += DropItemList.Amount;
 				i++;
 			}
+			else
+			{
+				// Send a warning that this class can't be found and continue the loop
+				print("WARNING: RandomSpawner type definition is incorrect at element %i", DropItemList.Num - i);
+				// Show that there's a problem.
+				Spawn(Unknown, Origin,,, false);
+				Destroy();
+				return;
+			}
 		}
 		// Then we reset the iterator to the start position...
 		i = 0;
@@ -119,8 +128,9 @@
 
 			if (NewEntity)
 			{
-				// copy everything relevant
+				// Copy everything that is relevant
 				NewEntity.Angles = Angles;
+				NewEntity.Origin = Origin;
 				NewEntity.Special = Special;
 				NewEntity.Args[0] = Args[0];
 				NewEntity.Args[1] = Args[1];
@@ -129,11 +139,30 @@
 				NewEntity.Args[4] = Args[4];
 				EntityEx(NewEntity).Special1 = Special1;
 				EntityEx(NewEntity).Special2 = Special2;
-	//			EntityEx(NewEntity).TID = TID;
+				NewEntity.SetTID(TID);
 				EntityEx(NewEntity).Master = Master;
 				EntityEx(NewEntity).Target = Target;
 				EntityEx(NewEntity).Tracer = Tracer;
 				EntityEx(NewEntity).CopyFriendliness(self, false);
+
+				// Copy Map Spawn flags
+				EntityEx(NewEntity).bAmbush = bAmbush;
+				EntityEx(NewEntity).bStanding = bStanding;
+				if (bDormant)
+				{
+					EntityEx(NewEntity).Deactivate(none);
+				}
+				if (bShadow && RenderStyle == STYLE_Translucent && Alpha == 0.25)
+				{
+					EntityEx(NewEntity).bShadow = true;
+					EntityEx(NewEntity).RenderStyle = STYLE_Translucent;
+					EntityEx(NewEntity).Alpha = 0.25;
+				}
+				if (RenderStyle == STYLE_None)
+				{
+					EntityEx(NewEntity).RenderStyle = STYLE_None;
+				}
+
 				// This handles things such as projectiles with the MF4_SPECTRAL flag that have
 				// a health set to -2 after spawning, for internal reasons.
 				if (Health != default.Health)
Index: source/r_data.cpp
===================================================================
--- source/r_data.cpp	(revision 4300)
+++ source/r_data.cpp	(working copy)
@@ -1783,8 +1783,13 @@
 	{
 		VTempClassEffects& CD = ClassDefs;
 		VClass* Cls = VClass::FindClass(*CD.ClassName);
-		if (!Cls)
+		if (Cls)
 		{
+			// Get class replacement
+			Cls = Cls->GetReplacement();
+		}
+		else
+		{
 			GCon->Logf(NAME_Init, "No such class %s", *CD.ClassName);
 			continue;
 		}
Index: source/vc_decorate.cpp
===================================================================
--- source/vc_decorate.cpp	(revision 4300)
+++ source/vc_decorate.cpp	(working copy)
@@ -4155,7 +4155,7 @@
 	{
 		if (GArgs.CheckParm("-debug_decorate"))
 		{
-			GCon->Logf("Class %s", *DecPkg->ParsedClasses->GetFullName());
+			GCon->Logf("Emiting Class %s", *DecPkg->ParsedClasses->GetFullName());
 		}
 		DecPkg->ParsedClasses->DecorateEmit();
 	}
@@ -4164,7 +4164,7 @@
 	{
 		if (GArgs.CheckParm("-debug_decorate"))
 		{
-			GCon->Logf("Class %s", *DecPkg->ParsedClasses->GetFullName());
+			GCon->Logf("Compiling Class %s", *DecPkg->ParsedClasses->GetFullName());
 		}
 		DecPkg->ParsedClasses->DecoratePostLoad();
 	}
Thu, 10 Jun 2010 20:39:08

Janis Legzdinsh

Looks fine.

Back to the Vavoom Forum Archives