Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
Granamir wrote:Thank you very much, i think i got it. (btw is _ a variable?)
_ is a variable identifier, yes. It's conventional to use _ for a variable that you don't actually plan on using, and in most cases you don't plan on using the numeric index of the item.
Granamir wrote:Ok now that i'm starting to figure my code i got another question (if u don't mind): is there a way to put my code in defineObject{} so that it make automatically calculations for items in surface when i make mother object rotate (with an in game function)? A hook or something that calls my function when object is drawed, updated, moved, refreshed, or whatever?
LightComponent and CameraComponent have onUpdate hooks, you could also use a TimerComponent with an interval close to 0.
While i'm working on code i'm thinking if there is a better way to let item rotate around an external pivot, so i thought a way could be to remove and add again items in surface since items get position and orientation of surface when added.
Code side point of view would be easier, i guess, but what about machine work? worse or better? anyone knows what is best, calculate position and orientation of every item or just remove and add them again?
minmay wrote:The only way to remove an item from a surface with the scripting interface is to destroy the item or the surface so...
One can easily move an item from one surface to another via script. This allows for moving items to an off-map surface for storage, or if one wants to simulate a drop onto the floor; one simply spawns a surface at floor level and puts the item in that surface, with a connector to a function that destroys the surface once empty.
*We should request a champion:dropItem() function the next time Petri offers a Glögg session; dropMouseItem() would be useful too.
minmay wrote:The only way to remove an item from a surface with the scripting interface is to destroy the item or the surface so...
One can easily move an item from one surface to another via script.
No you can't. You can easily add an item to multiple surfaces at once via script; SurfaceComponent:addItem() does NOT remove the item from any surfaces it's already in. If the player saves and loads while an item is in more than one surface, either the item's entire object gets duplicated, or a crash occurs and you have a permanently unusable save file. Neither of these outcomes is desirable.
minmay wrote:The only way to remove an item from a surface with the scripting interface is to destroy the item or the surface so...
One can easily move an item from one surface to another via script.
No you can't. You can easily add an item to multiple surfaces at once via script; SurfaceComponent:addItem() does NOT remove the item from any surfaces it's already in. If the player saves and loads while an item is in more than one surface, either the item's entire object gets duplicated, or a crash occurs and you have a permanently unusable save file. Neither of these outcomes is desirable.
Try it.
(This does happen with champion inventory though; and you can crash the game if you manage to get the item on to the mouse when it's moved ~when they try to drop it.)
If it goes to an off screen alcove then they cannot ever grab it. The script can disable clickable before the move. If it doesn't have a clickable component, they can't pick it up.
YOU try it. Your video shows exactly the behaviour I'm describing! The items are referenced by both surfaces at once. Obviously there's still only one object at the time so you'll only see one model, I'm not sure what your video is even trying to prove. Try saving and loading in that example you made, if you don't get duplicates or crashes I'd be very surprised.
Isaac wrote:Some time ago, I wrote a dropItem() function that could drop a single item or even empty the party's entire inventory onto the ground.
Yes, this works fine, because there is a Champion:removeItem() method to get rid of the item reference. There is no SurfaceComponent:removeItem() method or equivalent, as far as I know; the only methods I know of getting rid of a surface's item reference are the player picking up the item with the mouse (scripting interface can't do this) or destroying the SurfaceComponent or ItemComponent entirely.
*And after having done that, and it being so convincing [looking], I thought I'd test it a bit more. Turns out no errors come of it, but it does indeed leave the object reference in both. I changed the timer setup to repeat indefinitely, and lo... it kept adding the items to the other alcove again, and again. So while it doesn't crash the game, it does multiply the number of objects present... So I changed the script to replace the alcove after the transfer operation.
Now it visually looks and behaves the same, but the objects no longer exist in the first alcove; and do exist in the second one; which could be off-map.
Even before, the player was not able to pick up any 'removed' items, so it doesn't seem to matter for limited [special case] use.
Tried a bit me too.
Didn't tested save problems btw i noticed a very bad slowdown using this method, i guess for all objects references. So maybe it would work replacing alcove after each operation but, again i guess, would be more memory expensive than translating and rotating every single object.