Jump to content

How to Spawn Items without SuburbsDistribution Inserts


Talksintext

Recommended Posts

First, this all comes from NCrawler, who seems to have left the community 6 months back. It's from a beta of his YAWM that never was released. I have it since I was a beta tester for him at the time he left.

 

The purpose of this is to allow the modder far more flexibility in how his items are spawned, when, and with what. It also allows a modder to set values lower than 0.01 for probability, in fact as low as desired (1 in 10,000, okay!). Some of this has been heavily altered by me for personal use with the KY firearms mod that's currently out in this forum, but it can work with any items mod you like.

 

This works through the media\lua\server\Items subfolder.

 

Add this to the bottom to start. The random value generator is used an awful lot, and the Events line is what calls the script to run each time a container is "filled" by the game engine. Without that, nothing will happen.

--From RoboMat's RMUtility Modfunction rnd(_value)	return ZombRand(_value) + 1;endEvents.OnFillContainer.Add(spawnNCStuff);

Next is the main function. Note that "OnFillContainer" will pass 3 values to this, the room name (the first value we see in SuburbsDistribution tables, like "kitchen"), the type of container (the second value, "all" or "metal_shelves"), and the specific container being filled:

function spawnNCStuff(_roomName, _containerType, _containerFilled)-- ALL THE IF AND WHILE LOOPS DISCUSSED BELOW GO IN HEREend

Now we can use these in IF statements to specify when to spawn things depending on room type or container type:

	if _containerType == "wardrobe" then-- STUFFend	if _roomName ~= "kitchen" then	if _containerType == "counter" or _containerType == "locker" or _containerType == "metal_shelves" then-- STUFFendend

Within these, we can set how rare the spawn is thusly:

		--Roll for firearm (0.2% chance)		if rnd(1000) >= 999 then-- STUFFend

The next part is a bit trickier. It requires two things. First, the code within the above IF statements. Second, a separate array outside of this entire function. Let's start with the array. Here's an example for guns and their respective ammo:

gun_array = {	"RKFmod.ColtPython",	"RKFmod.TaurusModel444RagingBull",	"RKFmod.Kimber1911",	"RKFmod.Ruger1022ArchangelNomad",	"RKFmod.Ruger1022",	"RKFmod.MarlinModel795",	"RKFmod.MarlinModel795",	"RKFmod.MarlinModel795",	"RKFmod.MarlinModel795",};ammo_array = {	"RKFmod.357Mrounds",	"RKFmod.44rounds",	"RKFmod.45rounds",	"RKFmod.Ruger1022ArchangelNomadMag",	"RKFmod.Ruger1022Mag",	"RKFmod.MarlinModel795Mag",	"RKFmod.MarlinModel795Mag",	"RKFmod.MarlinModel795Mag",	"RKFmod.MarlinModel795Mag",};

Notice how the first member of the array in gun_array matches the first member of ammo_array, and so on to the end? This is important if you want to spawn matching items together.

 

Also notice how we've had the Marlin 795 repeated 3 times, so it takes up 4 of the 8 choices? That means it has a 50% chance of spawning IF any gun is spawned from its array. This is how to make specific entries more or less likely within the array.

 

Now, let's assume we have several such paired arrays, one for long rifles, one for pistols, one for AR-15s, etc. We want to choose randomly which to pick from when spawning.

 

Next the code for the main function:

			weaponType = rnd(100);			if weaponType <= 50 then --pistols-- STUFF						elseif weaponType > 50 and weaponType <= 90 then --rifles-- STUFF			elseif weaponType > 90 then --AR-15s-- STUFF			end

So here you can see we are choosing between which set of arrays to spawn from. Next, to pick a member of the array to spawn:

				gun_Index = rnd(#gun_array);				_containerFilled:AddItem(gun_array[gun_index]);

#gun_array means that it counts the number of entires in our gun_array. The rnd function picks a random number within that range. Then we have the main "doer" of this whole thing, the AddItem() command. This adds in the selected item to the specific container. You could just replace (gun_array[gun_index]) with ("mymod.my_gun") and it'd work just as well.

 

Now here's a fun twist. You can add specific ammo/magazines/etc to the spawn as well:

				NCY_ammovar = rnd(100);				if NCY_ammovar >= 40 then --Add 1 magazine for that weapon(60% chance)					_containerFilled:AddItem(ammo_array[gun_index]);					if NCY_ammovar >= 75 then --Another mag (25% chance)						_containerFilled:AddItem(ammo_array[gun_index]);						if NCY_ammovar >= 92 then --2 more mags (8% chance)							_containerFilled:AddItem(ammo_array[gun_index]);							_containerFilled:AddItem(ammo_array[gun_index]);						end					end				end

Let's walk through that a bit slowly. First, we have a new random value, this is just used to see if we want to spawn something or not. You could just make this 100, so something always spawns (or nix the IF statements and just follow with an AddItem() command). But here it's random, and the first checks to see if it's >= 40, which means 60% of the time we'll get ammo spawned with the gun. Notice that we're using the SAME gun_index value as before, we haven't rerandomized it, but now with the ammo array? Yes, this is how we get a matching gun/magazine/ammo spawn.

 

Then you can see that there are two additional IF checks, for rarer likelihood of further spare ammo. This can be tailored however you like, once you understand the basic syntax of what's going on here.

 

There's a lot more you can do with this stuff, like spawning a melee if a gun doesn't spawn, using an ELSE statement that follows the original IF statement way above. Sky's the limit. I'm not going to say this is the most streamlined code imaginable, but it works and it's pretty easy to edit on the fly and adjust to how you like it. Anyway, let's look at a finished version of what we just did (different names for some things, but exact same structure/commands):

function spawnNCStuff(_roomName, _containerType, _containerFilled)	if _containerType == "wardrobe" then		--Roll for firearm (1.5% chance)		if rnd(1000) >= 985 then			--Find which type of firearm to spawn (50% basic, 40% hunter, 10% enth)			weaponType = rnd(100);			if weaponType <= 50 then --basic				basicIndex = rnd(#basicweaponsTable);				_containerFilled:AddItem(basicweaponsTable[basicIndex]);				NCY_ammovar = rnd(100);				if NCY_ammovar >= 40 then --Add 1 magazine for that weapon(60% chance)					_containerFilled:AddItem(basicmagTable[basicIndex]);					if NCY_ammovar >= 75 then --Another mag (25% chance)						_containerFilled:AddItem(basicmagTable[basicIndex]);						if NCY_ammovar >= 92 then --2 more mags (8% chance)							_containerFilled:AddItem(basicmagTable[basicIndex]);							_containerFilled:AddItem(basicmagTable[basicIndex]);						end					end				end				--Now again for boxed rounds				NCY_ammovar = rnd(100);				if NCY_ammovar >= 70 then --Add 1 box for that weapon(30% chance)					_containerFilled:AddItem(basicboxTable[basicIndex]);					if NCY_ammovar >= 93 then --Another mag (7% chance)						_containerFilled:AddItem(basicboxTable[basicIndex]);					end				end			elseif weaponType > 50 and weaponType <= 90 then --Hunter				hunterIndex = rnd(#hunterweaponsTable);				_containerFilled:AddItem(hunterweaponsTable[hunterIndex]);				NCY_ammovar = rnd(100);				if NCY_ammovar >= 40 then --Add 1 magazine for that weapon(60% chance)					_containerFilled:AddItem(huntermagTable[hunterIndex]);					if NCY_ammovar >= 75 then --Another mag (25% chance)						_containerFilled:AddItem(huntermagTable[hunterIndex]);						if NCY_ammovar >= 92 then --2 more mags (8% chance)							_containerFilled:AddItem(huntermagTable[hunterIndex]);							_containerFilled:AddItem(huntermagTable[hunterIndex]);						end					end				end				--Now again for boxed rounds				NCY_ammovar = rnd(100);				if NCY_ammovar >= 70 then --Add 1 box for that weapon(30% chance)					_containerFilled:AddItem(hunterboxTable[hunterIndex]);					if NCY_ammovar >= 93 then --Another mag (7% chance)						_containerFilled:AddItem(hunterboxTable[hunterIndex]);					end				end			elseif weaponType > 90 then --Enthusiast				enthusiastIndex = rnd(#enthusiastweaponsTable);				_containerFilled:AddItem(enthusiastweaponsTable[enthusiastIndex]);				NCY_ammovar = rnd(100);				if NCY_ammovar >= 40 then --Add 1 magazine for that weapon(60% chance)					_containerFilled:AddItem(enthusiastmagTable[enthusiastIndex]);					if NCY_ammovar >= 75 then --Another mag (25% chance)						_containerFilled:AddItem(enthusiastmagTable[enthusiastIndex]);						if NCY_ammovar >= 92 then --2 more mags (8% chance)							_containerFilled:AddItem(enthusiastmagTable[enthusiastIndex]);							_containerFilled:AddItem(enthusiastmagTable[enthusiastIndex]);						end					end				end				--Now again for boxed rounds				NCY_ammovar = rnd(100);				if NCY_ammovar >= 70 then --Add 1 box for that weapon(30% chance)					_containerFilled:AddItem(enthusiastboxTable[enthusiastIndex]);					if NCY_ammovar >= 93 then --Another mag (7% chance)						_containerFilled:AddItem(enthusiastboxTable[enthusiastIndex]);					end				end			end		else			--No firearm, roll for misc ammo (2.0% chance)			if rnd(1000) >= 980 then				allammoIndex = rnd(#allammoTable);				_containerFilled:AddItem(allammoTable[allammoIndex]);			end		end	endendbasicweaponsTable = {	"RKFmod.SWMP22",	"RKFmod.HRModel99",	"RKFmod.RugerMKII",	"RKFmod.WaltherP22",	"RKFmod.SWModel392",	"RKFmod.BrowningHiPower",	"RKFmod.GlockG17",	"RKFmod.TaurusModel82",	"RKFmod.SWModel637",	"RKFmod.Glock31",	"RKFmod.ColtPython",	"RKFmod.TaurusModel608",	"RKFmod.Glock22",	"RKFmod.HiPoint40",	"RKFmod.SIGSauerP226",	"RKFmod.TaurusModel444RagingBull",	"RKFmod.Kimber1911",	"RKFmod.HiPointJHP",	"RKFmod.Ruger1022",	"RKFmod.MarlinModel795",	"RKFmod.SavageMarkIIF",	"RKFmod.MarlinModel336W",	"RKFmod.WeatherbyVanguard",	"RKFmod.WinchesterModel70",	"RKFmod.RemingtonModel770",	"RKFmod.RemingtonMSR",	"RKFmod.IthicaModel37",	"RKFmod.BrowningBPS",	"RKFmod.HRTrackerII",	"RKFmod.StevensModel512",};basicmagTable = {	"RKFmod.SWMP22Mag",	"RKFmod.22rounds",	"RKFmod.RugerMKIIMag",	"RKFmod.WaltherP22Mag",	"RKFmod.SWModel392Mag",	"RKFmod.BrowningHiPowerMag",	"RKFmod.GlockG17Mag",	"RKFmod.38rounds",	"RKFmod.38rounds",	"RKFmod.Glock31Mag",	"RKFmod.357Magnumrounds",	"RKFmod.357Magnumrounds",	"RKFmod.Glock22Mag",	"RKFmod.HiPoint40Mag",	"RKFmod.SIGSauerP226Mag",	"RKFmod.44rounds",	"RKFmod.Kimber1911Mag",	"RKFmod.HiPointJHPMag",	"RKFmod.Ruger1022Mag",	"RKFmod.MarlinModel795Mag",	"RKFmod.SavageMarkIIFMag",	"RKFmod.3030rounds",	"RKFmod.WeatherbyVanguardMag",	"RKFmod.3006rounds",	"RKFmod.308rounds",	"RKFmod.RemingtonMSRMag",	"RKFmod.12grounds",	"RKFmod.12grounds",	"RKFmod.20grounds",	"RKFmod.410grounds",};basicboxTable = {	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf9mm",	"RKFmod.BoxOf9mm",	"RKFmod.BoxOf9mm",	"RKFmod.BoxOf38",	"RKFmod.BoxOf38",	"RKFmod.BoxOf357",	"RKFmod.BoxOf357",	"RKFmod.BoxOf357",	"RKFmod.BoxOf40",	"RKFmod.BoxOf40",	"RKFmod.BoxOf40",	"RKFmod.BoxOf44",	"RKFmod.BoxOf45",	"RKFmod.BoxOf45",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf3030",	"RKFmod.BoxOf3006",	"RKFmod.BoxOf3006",	"RKFmod.BoxOf308",	"RKFmod.BoxOf308",	"RKFmod.BoxOf12g",	"RKFmod.BoxOf12g",	"RKFmod.BoxOf20g",	"RKFmod.BoxOf410g",};hunterweaponsTable = {	"RKFmod.ColtPython",	"RKFmod.TaurusModel444RagingBull",	"RKFmod.Kimber1911",	"RKFmod.Ruger1022ArchangelNomad",	"RKFmod.Ruger1022",	"RKFmod.MarlinModel795",	"RKFmod.SavageMarkIIF",	"RKFmod.BushmasterCarbon15",	"RKFmod.ColtAR15A3",	"RKFmod.MarlinModel336W",	"RKFmod.WeatherbyVanguard",	"RKFmod.WinchesterModel70",	"RKFmod.RemingtonModel770",	"RKFmod.RemingtonMSR",	"RKFmod.NorincoSKS",	"RKFmod.IthicaModel37",	"RKFmod.BrowningBPS",	"RKFmod.HRTrackerII",	"RKFmod.Mossberg505Bantam",	"RKFmod.StevensModel512",};huntermagTable = {	"RKFmod.357Mrounds",	"RKFmod.44rounds",	"RKFmod.45rounds",	"RKFmod.Ruger1022ArchangelNomadMag",	"RKFmod.Ruger1022Mag",	"RKFmod.MarlinModel795Mag",	"RKFmod.SavageMarkIIFMag",	"RKFmod.BushmasterCarbon15Mag",	"RKFmod.ColtAR15A3Mag",	"RKFmod.3030rounds",	"RKFmod.WeatherbyVanguardMag",	"RKFmod.3006rounds",	"RKFmod.308rounds",	"RKFmod.RemingtonMSRMag",	"RKFmod.NorincoSKSMag",	"RKFmod.12grounds",	"RKFmod.12grounds",	"RKFmod.20grounds",	"RKFmod.20grounds",	"RKFmod.410grounds",};hunterboxTable = {	"RKFmod.BoxOf357",	"RKFmod.BoxOf44",	"RKFmod.BoxOf45",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf223",	"RKFmod.BoxOf223",	"RKFmod.3030rounds",	"RKFmod.BoxOf3006",	"RKFmod.BoxOf3006",	"RKFmod.BoxOf308",	"RKFmod.BoxOf308",	"RKFmod.BoxOf762",	"RKFmod.BoxOf12g",	"RKFmod.BoxOf12g",	"RKFmod.BoxOf20g",	"RKFmod.BoxOf20g",	"RKFmod.BoxOf410g",};enthusiastweaponsTable = {	"RKFmod.SWMP22s",	"RKFmod.RugerMKIIs",	"RKFmod.WaltherP22s",	"RKFmod.GlockG17",	"RKFmod.Glock31",	"RKFmod.Glock22",	"RKFmod.HiPoint40",	"RKFmod.SIGSauerP226",	"RKFmod.Kimber1911",	"RKFmod.Ruger1022ArchangelNomad",	"RKFmod.BushmasterCarbon15",	"RKFmod.ColtM4A1",	"RKFmod.SIGSauerM400",	"RKFmod.ColtAR15A3",	"RKFmod.RugerMini14",	"RKFmod.RemingtonMSR",	"RKFmod.HKMP5A5",	"RKFmod.NorincoSKS",	"RKFmod.YugoSKS",	"RKFmod.Mossberg500JIC",	"RKFmod.BrowningBPSSO",};enthusiastmagTable = {	"RKFmod.SWMP22sMag",	"RKFmod.RugerMKIIsMag",	"RKFmod.WaltherP22sMag",	"RKFmod.GlockG17Mag",	"RKFmod.Glock31Mag",	"RKFmod.Glock22Mag",	"RKFmod.HiPoint40Mag",	"RKFmod.SIGSauerP226Mag",	"RKFmod.Kimber1911Mag",	"RKFmod.Ruger1022ArchangelNomadMag",	"RKFmod.BushmasterCarbon15Mag",	"RKFmod.ColtM4A1Mag",	"RKFmod.SIGSauerM400Mag",	"RKFmod.ColtAR15A3Mag",	"RKFmod.RugerMini14Mag",	"RKFmod.RemingtonMSRMag",	"RKFmod.HKMP5A5Mag",	"RKFmod.NorincoSKSMag",	"RKFmod.YugoSKSMag",	"RKFmod.12grounds",	"RKFmod.12grounds",};enthusiastboxTable = {	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf9mm",	"RKFmod.BoxOf38",	"RKFmod.BoxOf40",	"RKFmod.BoxOf40",	"RKFmod.BoxOf40",	"RKFmod.BoxOf45",	"RKFmod.BoxOf22",	"RKFmod.BoxOf223",	"RKFmod.BoxOf223",	"RKFmod.BoxOf223",	"RKFmod.BoxOf223",	"RKFmod.BoxOf223",	"RKFmod.BoxOf308",	"RKFmod.BoxOf9mm",	"RKFmod.BoxOf762",	"RKFmod.BoxOf762",	"RKFmod.BoxOf12g",	"RKFmod.BoxOf12g",};miscitemTable = {	"RKFmod.DigitalWatch",	"RKFmod.DigitalWatch",	"RKFmod.DigitalWatch",	"RKFmod.EtFold",	"RKFmod.s1",	"RKFmod.LEDtorch",	"RKFmod.LEDtorch",	"RKFmod.HPrEmpty",	"RKFmod.MetWB",	"RKFmod.CBoots",	"RKFmod.BDUlower",	"RKFmod.BJacketN",	"RKFmod.BJacket",	"RKFmod.RepKit",	"RKFmod.Cleaning2",	"RKFmod.Cleaning2",	"RKFmod.Cleaning2",	"RKFmod.Cleaning2",	"RKFmod.Cleaning1",	"RKFmod.Cleaning1",	"RKFmod.Cleaning1",	"RKFmod.Cleaning1",};allammoTable = {	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf9mm",	"RKFmod.BoxOf9mm",	"RKFmod.BoxOf9mm",	"RKFmod.BoxOf38",	"RKFmod.BoxOf38",	"RKFmod.BoxOf357",	"RKFmod.BoxOf357",	"RKFmod.BoxOf357",	"RKFmod.BoxOf40",	"RKFmod.BoxOf40",	"RKFmod.BoxOf40",	"RKFmod.BoxOf44",	"RKFmod.BoxOf45",	"RKFmod.BoxOf45",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf3030",	"RKFmod.BoxOf3006",	"RKFmod.BoxOf3006",	"RKFmod.BoxOf308",	"RKFmod.BoxOf308",	"RKFmod.BoxOf12g",	"RKFmod.BoxOf12g",	"RKFmod.BoxOf20g",	"RKFmod.BoxOf410g",	"RKFmod.BoxOf223",	"RKFmod.BoxOf223",	"RKFmod.BoxOf223",	"RKFmod.BoxOf22",	"RKFmod.BoxOf22",	"RKFmod.BoxOf9mm",	"RKFmod.BoxOf9mm",	"RKFmod.BoxOf762",	};--From RoboMat's RMUtility Modfunction rnd(_value)	return ZombRand(_value) + 1;endEvents.OnFillContainer.Add(spawnNCStuff);

 

This was altered by me to work with the KY firearms mod, for personal use. I guess now it's open to all. I will also post the original YAWmod lua if anyone wants to experiment with thatj.

 

NOTE: You will want to get rid of all the...

table.insert(SuburbsDistributions["garagestorage"]["all"].items, "RKFmod.BoxOf22");

...type code if you want to do this, or at least that which is relevant to what you're trying to achieve with these functions.

 

Anyway, thanks should go to NCrawler, wherever he is, as far as I know he was the one to come up with this approach and code for this game.

Link to comment
Share on other sites

  • 1 month later...
  • 4 months later...

Good god that's wonderful! (I really hope this doesn't count as necro-posting, I just really wanna say thanks!).

 

I've made my first dive into PZ modding today, and I now have a "bag of holding" with a working texture, has a weight reduction of 100 and a very large capacity, and now it spawn in the world <3 (Don't judge... those logs are f*ckin' heavy!)

 

So thanks! World spawn was the last thing holding me back!

 

Is this:

--------------------------Fine Tunned Loot Spawn--Thanks to Talksintext------------------------function spawnLoot(_roomName, _containerType, _containerFilled)	if _roomName == "kitchen" and _containerType == "counter" then		if RollPercent(1) then			_containerFilled:AddItem("BagOfHolding.BagOfHolding");		end	endend--------------------------Helper Functions--Thanks to Talksintext------------------------function RollPercent(percentage)	if rnd(1000) > (1000 - ((1000 * percentage) / 100)) then		return true;	else		return false;	endend

enough credit to give where credit is due?

Link to comment
Share on other sites

Good god that's wonderful! (I really hope this doesn't count as necro-posting, I just really wanna say thanks!).

 

I've made my first dive into PZ modding today, and I now have a "bag of holding" with a working texture, has a weight reduction of 100 and a very large capacity, and now it spawn in the world <3 (Don't judge... those logs are f*ckin' heavy!)

 

So thanks! World spawn was the last thing holding me back!

 

Is this:

--------------------------Fine Tunned Loot Spawn--Thanks to Talksintext------------------------function spawnLoot(_roomName, _containerType, _containerFilled)	if _roomName == "kitchen" and _containerType == "counter" then		if RollPercent(1) then			_containerFilled:AddItem("BagOfHolding.BagOfHolding");		end	endend--------------------------Helper Functions--Thanks to Talksintext------------------------function RollPercent(percentage)	if rnd(1000) > (1000 - ((1000 * percentage) / 100)) then		return true;	else		return false;	endend

enough credit to give where credit is due?

 

Yes, as long as you change it to say "Thanks to NCrawler" since the above code fragments are straight out of one of my mods.

 

Edit: oh yeah, you'll also need to credit RoboMat as you are also using his 'rnd' function in the above code.

Edited by NCrawler
Link to comment
Share on other sites

I've made my first dive into PZ modding today, and I now have a "bag of holding" with a working texture, has a weight reduction of 100 and a very large capacity, and now it spawn in the world <3 (Don't judge... those logs are f*ckin' heavy!)

Helpful Tip: Don't ever set it down or put it in a container when it's full. The game looks at the total weight of the bag plus contents when you try and pick it up, which does not include weight reduction. This is also true if you are trying to go straight from "ground" to "equipped on back". So, if you create a bag that holds more than you can possibly carry, you will never be able to pick it up again once it's that heavy and you drop it.

I learned this the hard way when I dropped a larger bag I had created and then had to clear out my inventory and eat a bunch to get a strength buff so I could carry enough to pick the thing up and equip it to empty it.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...