Page 1 of 2

Item Placement Randomizer script

Posted: Sat Nov 24, 2012 2:04 am
by Diarmuid
Hi there, I posted this yesterday directly in the Useful Scripts thread, but then realized it would be better to post it here for discussion/critique before, (deleted it there). If you think it deserves to be put with the others go ahead, I didn't want to presume.

So: Easy Item Placement Randomizer

I just coded this for my dungeon and thought it could be useful to others. Simply placed in a script entity in your dungeon, this script spreads out randomly a list of items to a list of alcoves when the dungeon is initialized. (Works with monsters & containers too).

I tried to code the script so that it's very easy to put in lists of items and destinations for those with lesser scripting skills. In the example below, the armor of valor set is spread between 5 alcoves, and a lucky ogre gets one too! ;)

The commented line prints what went where, for debug purposes.

Code: Select all

function distributeItems()
	local targetIndex = 0
	local itemsTable = {
		"boots_valor",
		"cuirass_valor",
		"gauntlets_valor",
		"greaves_valor",
		"helmet_valor",
		"shield_valor",
		}
	local alcovesTable = {
		temple_alcove_1,
		temple_alcove_2,
		temple_alcove_3,
		temple_alcove_4,
		temple_alcove_5,
		ogre_1,
		}
	for i, v in ipairs(itemsTable) do
		targetIndex = math.random(# alcovesTable)
		alcovesTable[targetIndex]:addItem(spawn(v))
		--print(v," went to ",alcovesTable[targetIndex].id)
		table.remove(alcovesTable,targetIndex)
	end
end

distributeItems()

Re: Item Placement Randomizer script

Posted: Sat Nov 24, 2012 2:15 am
by Komag
I thought it was fine there, but go ahead and wait a few days and see if there are any improvements to be made

Re: Item Placement Randomizer script

Posted: Sat Nov 24, 2012 2:33 am
by Diarmuid
Oh alright, I'm still new to the forum so I'm trying to see what are the best practices... If you wish you can just move it back.

Re: Item Placement Randomizer script

Posted: Sat Nov 24, 2012 3:02 am
by msyblade
Anyone know if I can use the _ shortcuts with a script like this? Meaning if I put in "temple_alcove_", will it distribute to all temple_alcoves?nevermind, prolly be just as easy to try it and see what I can do.

Re: Item Placement Randomizer script

Posted: Sat Nov 24, 2012 3:25 am
by Komag
I'm not sure how you would set that up, but something like that ought to work I would think

Re: Item Placement Randomizer script

Posted: Sat Nov 24, 2012 3:40 am
by msyblade
K i'm getting the functionality of it. You cannot use shorcuts, must list each item/object completely. However you can decide what loot is going on an entire floor, list it in the script,and list your alcoves on that floor. doesnt matter if it's 2 items and 14 alcoves, it still puts one of each item in a random 2 of the alcoves. (Wasnt sure if I'd get 7 of each, or 4 in one alcove etc. ). Thanx Diarmuid!

Re: Item Placement Randomizer script

Posted: Sat Nov 24, 2012 3:43 am
by Komag
Ah, I see, that's different than I thought but still quite useful and cool. 8-)

Re: Item Placement Randomizer script

Posted: Sat Nov 24, 2012 3:44 am
by Grimwold
You could use sub() to check for a partial match and iterate over all temple_alcoves in a level... but you'd either have to have at least as many
things in the itemList as you have alcoves, or accept duplicates.

Code: Select all

for i in allEntities(level) do
  if i.id:sub(1,14) == "temple_alcove_" then
  -- ADD ITEM TO ALCOVE
 end
end

Re: Item Placement Randomizer script

Posted: Sat Nov 24, 2012 4:56 am
by msyblade
I'm so gonna check that out grim, thank you! What I'm looking at is making 8 of these. One starting weapons, one advanced weapons, one starter armor, one light/heavy armors, one starting mage, one advanced mage, one starting rogue, one advanced. Then Ill name tag the alcoves i want, something simple, like swa1 (starting weapons alcove 1). Hoping it allows me to randomize equipment ,then work on balance issues for it and such. Sure, sometimes the party might get 3 leather greaves on the first level, and no helm, but it would be a dynamic world and increase replayability. Dont think it will be too much work if i can use the shortcut.

Re: Item Placement Randomizer script

Posted: Sat Nov 24, 2012 5:04 am
by Diarmuid
It's fixed below, but right now, you must (ideally) have an equal number of items and destinations. Less items than destinations works as well as msyblade said, leaving some empty (could be fun, especially if you want, let's say, give a key to 1 out of 10 skeletons). More items than destinations crashed.

The way it works, for each item, it picks a random destination and sends it there, then REMOVES the destination from the table so nothing gets sent there again. So after each item, the alcoveTable gets smaller until it's empty.

Here's an updated version which doesn't crash if there's too much items to store. Also, I've now changed the function to accept external table arguments, so you have to define tables before calling the function. This has the advantage of not destroying the original table if you want to call multiple times the function to put different sets of Items to same destinations. You can now autopopulate the alcoveTable automatically before calling the function with something like Grimwold said. Ex:

Code: Select all

alcovesTable = {}
for i in allEntities(level) do
  if i.id:sub(1,14) == "temple_alcove_" then
    table.insert(alcovesTable,i)
 end
end
or

Code: Select all

alcovesTable = {}
for i in allEntities(level) do
  if i.id:sub(1,5) == "ogre_" then
    table.insert(alcovesTable,i)
 end
end
Here's the script for the function:

Code: Select all

function distributeItems(iTable,dTable)
	local targetIndex = 0
	for i, v in ipairs(iTable) do
		if # dTable > 0 then
			targetIndex = math.random(# dTable)
			dTable[targetIndex]:addItem(spawn(v))
			--print(v," went to ",dTable[targetIndex].id)
			table.remove(dTable,targetIndex)
		end
	end
end
And here is an example initialization and call :

Code: Select all

local itemsTable = {
      "boots_valor",
      "cuirass_valor",
      "gauntlets_valor",
      "greaves_valor",
      "helmet_valor",
      "shield_valor",
 }

 local alcovesTable = {
      temple_alcove_1,
      temple_alcove_2,
      temple_alcove_3,
      temple_alcove_4,
      temple_alcove_5,
      ogre_1,
}
		
distributeItems(itemsTable,alcovesTable)