Page 2 of 2

Re: anything other than a wall to prevent player throwing st

Posted: Mon Nov 26, 2012 6:45 pm
by Komag
For scroll images, you can do it case by case like so:

in items.lua:

Code: Select all

	defineObject{
		name = "note_map1",
		class = "Item",
		uiName = "Note",
		model = "assets/models/items/note.fbx",
		gfxIndex = 114,
		scroll = true,
		weight = 0.1,
	}

	defineObject{
		name = "note_map2",
		class = "Item",
		uiName = "Note",
		model = "assets/models/items/note.fbx",
		gfxIndex = 114,
		scroll = true,
		weight = 0.1,
	}
in the script in the dungeon:

Code: Select all

     if wasHoldingName == "note_map1" then
        getMouseItem():setScrollImage("assets/textures/gui/scroll_images/treasure_map_slime.tga")
       elseif wasHoldingName == "note_map2" then
        getMouseItem():setScrollImage("assets/textures/gui/scroll_images/treasure_map_vault.tga")
     end

Re: anything other than a wall to prevent player throwing st

Posted: Mon Nov 26, 2012 7:35 pm
by Komag
Xanathar wrote: As a difference from Komag script: I don't keep the id saved - if you need to save and restore it for any reason it must be added (in theory I prefer not to, and I never had the need, but I understand other mods may rely on the ids being preserved).
I actually don't need the IDs either, and found it problematic to try ever rely on it. If I wanted to restore special ids, I would need some way to either:
1 - check whether it had just a number id (assigned by the game) or a string id and only attempt to restore the id if it was a string (number IDs crash), or
2 - check the id against a table of items with ids that I want to preserve, and only if one of those attempt to restore the id.

By the way, is "c * 100 + i" enough room? What if a player had, say, 10 boxes all full with 10 items each! Just for super reliability, might want to change to "c * 1000 + i"

Re: anything other than a wall to prevent player throwing st

Posted: Mon Nov 26, 2012 8:53 pm
by Komag
After banging my head on the keyboard for a couple hours and stretching my brain further than I have in a while, I've come up with a modified version of the script (which includes all the debug text I like), which works GREAT! 8-)

Code: Select all

wasHolding = 0
wasHoldingStored = { }

function mouseSave()
  print("running mouseSave")
  if getMouseItem() ~= nil then
     print("found an item in mouse, called "..getMouseItem().name)
     wasHolding = 1
     wasHoldingStored[1] = saveItem(getMouseItem())
     setMouseItem(nil)
  end
end

function saveItem(item)
   local itemTable = { }
   itemTable.name = item.name
   itemTable.stackSize = item:getStackSize()
    print("mouse item stack size "..itemTable.stackSize)
   itemTable.fuel = item:getFuel()
    print("mouse item fuel "..itemTable.fuel)
   itemTable.charges = item:getCharges()
    print("mouse item charges "..itemTable.charges)
   itemTable.scrollText = item:getScrollText()
    if itemTable.scrollText ~= nil then
       print(""..itemTable.scrollText)
    end
   
   local idx = 0
   for subItem in item:containedItems() do
      if (idx == 0) then
         itemTable.subItems = { }
      end
      
      itemTable.subItems[idx] = saveItem(subItem)
      idx = idx + 1
   end
   
   return itemTable
end

function mouseRestore()
  if wasHolding == 1 then
     setMouseItem(loadItem(wasHoldingStored[1]))
     wasHoldingStored = { }
     wasHolding = 0
  end
end

function loadItem(itemTable)
   local spitem = nil
   spitem = spawn(itemTable.name)

   if itemTable.stackSize > 0 then
      spitem:setStackSize(itemTable.stackSize)
      print("restoring stack size...")
   end

   if itemTable.charges > 0 then
      spitem:setCharges(itemTable.charges)
      print("restoring charges...")
   end

   if itemTable.scrollText ~= nil then
      spitem:setScrollText(itemTable.scrollText)
      print("restoring text...")
   end

   spitem:setFuel(itemTable.fuel)
   print("restoring fuel, if any...")

   if itemTable.name == "note_map1"  then
        spitem:setScrollImage("assets/textures/gui/scroll_images/treasure_map_slime.tga")
       elseif itemTable.name == "note_map2" then
        spitem:setScrollImage("assets/textures/gui/scroll_images/treasure_map_vault.tga")
   end

   if (itemTable.subItems ~= nil) then
      for _, subTable in pairs(itemTable.subItems) do
         local subItem = loadItem(subTable)
         spitem:addItem(subItem, false)
      end
   end
   
   return spitem
end
It even allows me to have on the mouse a box filled with various items with various properties, one of which can be a mortar with 6 more items inside of it! and it all works beautifully, all charges, fuel, text, images (for the two special cases), stack, everything fully restored on all the items! Amazing!!! :o :shock: :mrgreen:

I tried to test a variety of situations and items, and everything is good so far. I haven't tested all those situations/items in game mode with save games yet :?

Re: anything other than a wall to prevent player throwing st

Posted: Mon Nov 26, 2012 11:13 pm
by Komag
... and the final bit about what this whole thread was for is now in place, working perfectly!

Edsploration - I didn't end up using most of what you came up with, but the socket objects themselves (the x and y, not the moving ones) and the overall concept were absolutely invaluable. I adjusted how it works and tied it in to my mouseSave and mouseRestore functions. For the sockets, I simply have them run mouseSave and activate a timer which 0.01s runs mouseRestore. Those mouse functions delete the object before it even leaves your hands, and restores it, so there is no thrown/dropped noise. I also increased the target size middle number, and placed the sockets so that you can still place items right down on the square you occupy but not in the square ahead.

Code: Select all

defineObject{
   name = "no_throw_alcove_x",
   class = "Alcove",
   anchorPos = vec(0, 2, 1.5), -- the parts are all close to 0.5 in, so this should be "behind" them
   targetPos = vec(0, 2, 1.5),
   targetSize = vec(0, 3, 5),
   placement = "wall",
   onInsertItem = function(self, item)
      noThrowScript.noThrow()
	  return false
   end,
   editorIcon = 92,
}

defineObject{
   name = "no_throw_alcove_y",
   class = "Alcove",
   anchorPos = vec(0, 2, 1.5), -- the parts are all close to 0.5 in, so this should be "behind" them
   targetPos = vec(0, 2, 1.5),
   targetSize = vec(5, 3, 0),
   placement = "wall",
   onInsertItem = function(self, item)
      noThrowScript.noThrow()
	  return false
   end,
   editorIcon = 92,
}
and in the script it's just:

Code: Select all

function noThrow()
  mouseItemScript.mouseSave()
  noThrowTimer:activate()
end

function throwRestore()
  mouseItemScript.mouseRestore()
end
with the noThrowTimer set to 0.01s and connected to trigger throwRestore() (and deactivate itself)

I know I could have put those things in the object definition, but I really like to keep my hook links to the absolute minimum, and then handle everything inside the editor.

I absolutely could not have done this without you guys, thanks a ton! :mrgreen:
THANK YOU Edsploration for the script and concept, and
THANK YOU Xanathar for the item properties saving script

Re: anything other than a wall to prevent player throwing st

Posted: Tue Nov 27, 2012 12:36 am
by Darklord
Well done guys, looks like some great team work here. :)

Daniel.