Set up for Randomized Loot in dungeon or monster drops
Set up for Randomized Loot in dungeon or monster drops
I was wondering if any of u lua whiz's could whip together some general useful global functions for us "illiterate" modders. I would love for the community (me)to have instant access to randomizers for regular loot all of us can put in our dungeons to increase replayability. Something along the lines of seven categories,
1. Regular weapons : machete to cutlass's
2. Elite weapons : dismantler, Nex, etc. things you shouldnt have access to early on.
3. Regular armor : Leather thru chain everything
4. Elite Armor : Chitin,Valor etc...
5. Accessories : Bracers, magic headwear
6. Rogue weapons : Shuriken, throwing axes
7. Sheilds : duh.
This list is probably shortsighted in the moment, but if someone could throw these together in an hour or two (Think I could do it, but it would take 4 days and wouldn't work when I was done, So I'd end up here, asking you to help me). I think it will improve so many creations we release over the next few months. We just place the Global functions, and script whichever object we want to spawn "this category of object" on the fly, whala. Dynamic playthroughs (What if DM had THAT). hit this thread if this tickles your fancy or are knowledgeable enough to pull it off without actually removing hair strands from your cranium.(Okay, I MAY be using the term "all the modders" as a direct substitute for "I would love this", but lets not go clouding the issue with logic.
1. Regular weapons : machete to cutlass's
2. Elite weapons : dismantler, Nex, etc. things you shouldnt have access to early on.
3. Regular armor : Leather thru chain everything
4. Elite Armor : Chitin,Valor etc...
5. Accessories : Bracers, magic headwear
6. Rogue weapons : Shuriken, throwing axes
7. Sheilds : duh.
This list is probably shortsighted in the moment, but if someone could throw these together in an hour or two (Think I could do it, but it would take 4 days and wouldn't work when I was done, So I'd end up here, asking you to help me). I think it will improve so many creations we release over the next few months. We just place the Global functions, and script whichever object we want to spawn "this category of object" on the fly, whala. Dynamic playthroughs (What if DM had THAT). hit this thread if this tickles your fancy or are knowledgeable enough to pull it off without actually removing hair strands from your cranium.(Okay, I MAY be using the term "all the modders" as a direct substitute for "I would love this", but lets not go clouding the issue with logic.
Currently conspiring with many modders on the "Legends of the Northern Realms"project.
"You have been captured by a psychopathic diety who needs a new plaything to torture."
Hotel Hades
"You have been captured by a psychopathic diety who needs a new plaything to torture."
Hotel Hades
Re: Substantial job for a good scripter.
Here you go, slightly edited from my Mordor dungeon:
Run this code as such:
scriptEntityName.randomLoot(object) <- with object being any world object with coordinates that determines the place where the loot will be placed (I've used spawners, although you can use anything really).
Explanation of all_loot table: the first entry is the thing being spawned, and the second is the likelihood of that item spawning. So what it does is it iterates through each item, and if it makes the cut, it's added to a second list (spawned_loot). From this list, one item is randomly picked and spawned. Therefore there's always a slight chance no item makes the list (unless you have somethng =100). If you want it to always spawn one of the things in the list, simply make them all =100 and they'll have an equally large chance of spawning.
For your individual maces, rogue gears etc, just make several copies of the function and change the all_loot table accordingly! Enjoy.
-Wolfrug
Code: Select all
function randomLoot(object)
local all_loot =
{
cave_nettle=75,
blooddrop_blossom=75,
grim_cap=75,
milkreed=75,
slime_bell=75,
tar_bead=75,
}
local spawned_loot = {}
for i,v in pairs(all_loot) do
if (math.random (1,100) <= v) then table.insert(spawned_loot,i)
end
end
-- print (spawned_loot[1], #spawned_loot)
local newitem=nil
if (#spawned_loot>0) then
local randomnr = math.random (1,#spawned_loot)
for i=1,#spawned_loot do
if (randomnr==i) then newitem=spawn(spawned_loot[i], object.level, object.x, object.y, math.random (0,3))
end
end
end
end
return newitem
end
scriptEntityName.randomLoot(object) <- with object being any world object with coordinates that determines the place where the loot will be placed (I've used spawners, although you can use anything really).
Explanation of all_loot table: the first entry is the thing being spawned, and the second is the likelihood of that item spawning. So what it does is it iterates through each item, and if it makes the cut, it's added to a second list (spawned_loot). From this list, one item is randomly picked and spawned. Therefore there's always a slight chance no item makes the list (unless you have somethng =100). If you want it to always spawn one of the things in the list, simply make them all =100 and they'll have an equally large chance of spawning.
For your individual maces, rogue gears etc, just make several copies of the function and change the all_loot table accordingly! Enjoy.
-Wolfrug
Try my Mordor: Depths of Dejenol LoG-ification. Feedback much appreciated!
Re: Substantial job for a good scripter.
Hi, that sounded like a nice feature so I made a quick implementation of it. It was no biggie because I already had categorized item lists.
random_loot script entity
It's not perfect yet but a good start. There should be level categories for items too, because now any weapon could added to snail. But of course you can remove items which you don't want to be spawned from the itemsList .
random_loot script entity
Code: Select all
itemsList = {
weapon = { "torch","torch_everburning","machete","long_sword","cutlass","nex_sword","dismantler","cudgel","knoffer","warhammer","flail","ogre_hammer","icefall_hammer","hand_axe","battle_axe","great_axe","ancient_axe","knife","dagger","fist_dagger","assassin_dagger","legionary_spear","venom_edge","venom_edge_empty","lightning_blade","lightning_blade_empty","lightning_rod","lightning_rod_empty","fire_blade","fire_blade_empty","power_weapon"},
shield = {"legionary_shield","round_shield","heavy_shield","shield_elements","shield_valor"},
accessory = {"frostbite_necklace","bone_amulet","fire_torc","spirit_mirror_pendant","gear_necklace","hardstone_bracelet","bracelet_tirin","brace_fortitude","huntsman_cloak","tattered_cloak","scaled_cloak","diviner_cloak","serpent_bracer","pit_gauntlets","nomad_mittens","leather_gloves"},
bomb = {"fire_bomb","shock_bomb","frost_bomb","poison_bomb"},
food = {"snail_slice","herder_cap","pitroot_bread","rotten_pitroot_bread","rat_shank","boiled_beetle","baked_maggot","ice_lizard_steak","mole_jerky","blueberry_pie"},
missileweapon = { "sling","short_bow","crossbow","longbow","arrow","fire_arrow","cold_arrow","poison_arrow","shock_arrow","quarrel","fire_quarrel","cold_quarrel","poison_quarrel","shock_quarrel"},
tome = {"tome_health","tome_wisdom","tome_fire"},
armor = { "hide_vest","leather_brigandine","leather_greaves","leather_cap","leather_boots","ring_mail","ring_greaves","ring_gauntlets","ring_boots","legionary_helmet","iron_basinet","chitin_mail","chitin_greaves","chitin_boots","chitin_mask","plate_cuirass","plate_greaves","full_helmet","plate_gauntlets","plate_boots","cuirass_valor","greaves_valor","helmet_valor","gauntlets_valor","boots_valor"},
cloth = { "peasant_breeches","peasant_tunic","peasant_cap","loincloth","leather_pants","doublet","silk_hose","flarefeather_cap","conjurers_hat","circlet_war","lurker_pants","lurker_vest","lurker_hood","lurker_boots","sandals","pointy_shoes","nomad_boots"},
herb = {"grim_cap","tar_bead","cave_nettle","slime_bell","blooddrop_blossom","milkreed"},
machinepart = { "machine_part_north","machine_part_east","machine_part_south","machine_part_west","machine_junk1","machine_junk2","machine_junk3","machine_junk4","machine_junk5","machine_junk6"},
potion = { "flask","water_flask","potion_healing","potion_energy","potion_poison","potion_cure_poison","potion_cure_disease","potion_rage","potion_speed"},
staff = {"whitewood_wand","magic_orb","shaman_staff","zhandul_orb"},
treasure = {"golden_chalice","golden_figure","golden_goromorg","golden_dragon","golden_crown","golden_orb","ancient_apparatus"},
container = {"sack","wooden_box","mortar"},
key = {"iron_key","brass_key","gold_key","round_key","ornate_key","gear_key","prison_key"},
miscitem = { "skull","blue_gem","green_gem","red_gem","compass","remains_of_toorum"},
scroll = { "scroll","note","scroll_light","scroll_darkness","scroll_fireburst","scroll_shock","scroll_fireball","scroll_frostbolt","scroll_ice_shards","scroll_poison_bolt","scroll_poison_cloud","scroll_lightning_bolt","scroll_enchant_fire_arrow","scroll_fire_shield","scroll_frost_shield","scroll_poison_shield","scroll_shock_shield","scroll_invisibility"},
throwingweapon = { "rock","throwing_knife","shuriken","throwing_axe"},
consumable = {"snail_slice","herder_cap","pitroot_bread","rotten_pitroot_bread","rat_shank","boiled_beetle","baked_maggot","ice_lizard_steak","mole_jerky","blueberry_pie",
"grim_cap","water_flask","potion_healing","potion_energy","potion_poison","potion_cure_poison","potion_cure_disease","potion_rage","potion_speed"
}
}
function addRandomLoot(monster,itemCategories,amountMin,amountMax)
amountMin = amountMin or 1
amountMax = amountMax or 1
local amount = math.random(amountMin,amountMax)
for i=1,amount do
local category = itemCategories[math.random(#itemCategories)]
local itemName = getRamdomItemName(category)
monster:addItem(spawn(itemName))
--print(itemName)
end
end
function getRamdomItemName(category)
return itemsList[category][math.random(#itemsList[category])]
end
Code: Select all
random_loot.addRandomLoot(snail_1,{'weapon','potion'})
- LoG Framework 2http://sites.google.com/site/jkoslog2 Define hooks in runtime by entity.name or entity.id + multiple hooks support.
- cloneObject viewtopic.php?f=22&t=8450
- cloneObject viewtopic.php?f=22&t=8450
Re: Substantial job for a good scripter.
I can see this as being quite a handy development! I think I prefer specific placement, but random loot has its place
Finished Dungeons - complete mods to play
Re: Substantial job for a good scripter.
Here's some stuff I've fiddled with:
Here's an example script:
The format of a loot table category entry is {category = "category name", {"item name", tier, bias}}.
The bias is a value between 0 and 1 that represents how likely that item is to be accepted if it is chosen by the mighty Random Roll.
That should cover most of it. I haven't tested or optimized it really thoroughly, but I hope it will be useful to someone.
Code: Select all
function getDefaultLootTable()
local loot = {}
loot[#loot + 1] = {category = "sword", {"machete", 1, 1.0}, {"long_sword", 1, 1.0}, {"cutlass", 2, 1.0}, {"nex_sword", 3, 1.0}, {"dismantler", 3, 1.0}}
loot[#loot + 1] = {category = "mace", {"cudgel", 1, 1.0}, {"knoffer", 1, 1.0}, {"warhammer", 2, 1.0}, {"flail", 2, 1.0}, {"ogre_hammer", 3, 1.0}, {"icefall_hammer", 3, 1.0}}
loot[#loot + 1] = {category = "axe", {"hand_axe", 1, 1.0}, {"battle_axe", 1, 1.0}, {"great_axe", 2, 1.0}, {"ancient_axe", 3, 1.0}}
loot[#loot + 1] = {category = "dagger", {"knife", 1, 1.0}, {"dagger", 1, 1.0}, {"fist_dagger", 2, 1.0}, {"assassin_dagger", 3, 1.0}}
return loot
end
function makeLootTableFromList(...)
-- this doesn't work for now
local loot = {{category = "simple"}}
for i = 1,arg.n*3,3 do
loot[1] = {arg[i], arg[i + 1], arg[i + 2]}
print(loot[1])
end
return loot
end
function pickItemName(caller, options)
local doDebug = false
local loot = options[1] or getDefaultLootTable()
local category = options[2]
local minTier = options[3]
local maxTier = options[4] or minTier
if type(category) == "string" then
category = {category}
end
if type(category) ~= "table" then
if doDebug then
print(self.id .. ": category type " .. type(category) .. " is not supported")
end
return nil
end
local count = 0
for i = 1,#loot do
for j = 1,#category do
if loot[i].category == category[j] then
count = count + 1
end
end
end
if count == 0 then
print(self.id .. ": loot table does not have any of the supplied categories")
return nil
elseif #category ~= count then
if doDebug then
print(self.id .. ": loot table does not have " .. #loot - count .. " of the supplied categories")
end
end
local runaway = 0
repeat
local done = false
local r1 = math.random(1, #loot)
local r2 = math.random(1, #loot[r1])
if loot[r1][r2][2] >= minTier and loot[r1][r2][2] <= maxTier then
if math.random() <= loot[r1][r2][3] then
item = loot[r1][r2][1]
done = true
break
elseif doDebug then
print(self.id .. ": ignoring " .. loot[r1][r2][1] .. "; its chance (" .. loot[r1][r2][3] .. ") did not satisfy random roll")
end
elseif doDebug then
print(self.id .. ": ignoring " .. loot[r1][r2][1] .. "; its tier (" .. loot[r1][r2][2] .. ") is not " .. minTier .. " - " .. maxTier)
end
runaway = runaway + 1
if runaway == 1000000 then
print(self.id .. ": item selector caused runaway")
for i = 1,#loot do
print(loot[i].category)
end
return nil
end
until done
return item
end
function spawnItemOnFloor(caller, options, level, x, y, facing, id)
local item = pickItemName(caller, options)
if item then
return spawn(item, level, x, y, facing, id)
end
end
function spawnItemOnMonster(caller, options, monster, id)
local item = spawnItemInLimbo(caller, options, id)
if item then
if monster then
monster:addItem(item)
return item
else
print(self.id .. ": tried to add item to inexistent entity")
return
end
end
end
function spawnItemInAlcove(caller, options, alcove, id)
return spawnItemOnMonster(caller, options, alcove, id)
end
function spawnItemInLimbo(caller, options, id)
return spawnItemOnFloor(caller, options, nil, nil, nil, nil, id)
end
Code: Select all
function trigger()
-- spawns a random sword, mace, axe or dagger from tiers 1-3.
loot_generator:spawnItemInAlcove({nil, {"sword", "mace", "axe", "dagger"}, 1, 3}, example_alcove)
-- works, but you get a warning if debug is on since the default loot table doesn't have a category called "giblets".
loot_generator:spawnItemInAlcove({nil, {"sword", "mace", "axe", "giblets"}, 1, 3}, example_alcove)
-- doesn't work, the generator needs at least one valid category to work with.
loot_generator:spawnItemInAlcove({nil, {"giblets"}, 1, 3}, example_alcove)
-- you may supply a string if there's only one category.
loot_generator:spawnItemInAlcove({nil, "sword", 1, 3}, example_alcove)
-- let's put a tier 1 axe in the square to the east of this script entity and give it the id "Fred".
if not findEntity("Fred") then
loot_generator:spawnItemOnFloor({nil, "axe", 1}, self.level, self.x + 1, self.y, self.facing, "Fred")
end
-- this monster needs a mace to go clubbing. Get it? HAHAHAHAaaa! *commits suicide*
loot_generator:spawnItemOnMonster({nil, "mace", 1, 3}, example_monster)
-- spawns an item but doesn't put actually put it anywhere. Don't forget to get the return value if you do this.
local my_item = loot_generator:spawnItemInLimbo({nil, {"sword", "mace", "axe", "dagger"}, 1, 3})
-- let's try a custom loot table (that alcove is getting pretty full by now, by the way).
-- this will always return a food item (biased towards a baked maggot) since the junk items are tier 1 and we want a tier 2 item.
-- the rotten pitroot bread won't be included either since it is tier 3.
loot_generator:spawnItemInAlcove({{{category = "junk", {"skull", 1, 1}, {"rock", 1, 1}}, {category = "food", {"baked_maggot", 2, 1}, {"boiled_beetle", 2, 0.25}, {"rotten_pitroot_bread", 3, 1}}}, {"skull", "food"}, 2}, example_alcove)
end
The bias is a value between 0 and 1 that represents how likely that item is to be accepted if it is chosen by the mighty Random Roll.
That should cover most of it. I haven't tested or optimized it really thoroughly, but I hope it will be useful to someone.
Re: Set up for Randomized Loot in dungeon or monster drops
added to Editing Superthread
Finished Dungeons - complete mods to play
Re: Set up for Randomized Loot in dungeon or monster drops
thanks a lot. those scripts are very helpful.
this is by the way exactly what i am trying to do with my "armory mod". it will turn all item generation inside the game into a nethack like random generation.
this is by the way exactly what i am trying to do with my "armory mod". it will turn all item generation inside the game into a nethack like random generation.
--
Fhizban's Asset Repository - the place where you find all my LoG contributions:
viewtopic.php?f=14&t=3904
Fhizban's Asset Repository - the place where you find all my LoG contributions:
viewtopic.php?f=14&t=3904
Re: Set up for Randomized Loot in dungeon or monster drops
It would be pretty cool if the treasure generation would take dungeon level into account as well so you don't get plate drops and Dismantlers early on.
Re: Set up for Randomized Loot in dungeon or monster drops
@Ixnatifual my script will! Im taking into consideration the current dungeon level as well as the total party level. still working on the balancing though...
--
Fhizban's Asset Repository - the place where you find all my LoG contributions:
viewtopic.php?f=14&t=3904
Fhizban's Asset Repository - the place where you find all my LoG contributions:
viewtopic.php?f=14&t=3904