Inventory Worn Problem! Argh! [SOLVED]

Anonynn
Hm. So I created an awesome way to condense "Clothing" in my game's inventory (the same way I condensed the container items). I move them into a player daughter object called "Worn Clothing" once they are "worn". After wearing, shirt.parent = Worn Clothing. It seems to work perfectly, except for one itty bitty little problem :3 The player cannot 'remove' the clothing once it's put into this daughter storage item.

I'm using Chase's Wear Library.

Any ideas why they can't be removed? Do I need to specify in the "wearable tab", after removing shirt.parent=player? Because I tried that and it didn't work.

The Pixie
When the player types REMOVE SHIRT, Quest looks for an item matching SHIRT. But it only looks in the player inventory and the current room, and not in the Worn Clothing room. I tried to do just this when we were looking at a second inventory in the other thread, and abandoned it because I hit the same problem.

Thinking about it again, a solution might be to change the ScopeInventory function, so it includes your new room. The code would look like this:
result = NewObjectList()
foreach (obj, GetAllChildObjects(game.pov)) {
if (ContainsVisible(game.pov, obj)) {
list add (result, obj)
}
}
foreach (obj, GetAllChildObjects(Worn Clothing)) {
list add (result, obj)
}
return (result)

I am not exactly sure what you already have set up, so no guarantee!

HegemonKhan
this would be a global change, with it searching through all of the containers' sub-items/objects/containers (indirect children) in her inventory, which probably will be fine if she limits her 'ScopeInventory()' usage just for this purpose.

otherwise, it might be better to implement this into her/Chase's custom 'wear' (or whatever Verb/Commands), so it will just do this functionality then upon its use, leaving the 'ScopeInventory()' to work as it originally did/does (to just get the direct children, not all of the indirect children).

another option is to change the code so it'll only do it (search the indirect children) for a specific container object, her 'storage' object, and not every container object in her inventory.

The Pixie
Yes, this will be a global change, so needs careful thought.

The problem is you need Quest to include that other room when it is matching items in a command. You would have to change REMOVE to use "remove #text#", and then do the pattern matching yourself. TAKE <object1> FROM <object2> would be the same, and possibly others. It is doable, but a lot more work, and more scope for going wrong.

I am assuming this room, Worn Clothing, will not be used for anything except worn clothing, including backpacks, so it should be safe to include everything in there, including sub-items.

Anonynn
Actually, "Worn Clothing" is just an openable/closable object, not a room. I attached an object to the player.object called "Worn Clothing" and had it become a parent to clothing being worn by the player. The "Worn Clothing" object is inside the player inventory. :) Does that make it better or help any?

HegemonKhan
I should post the coding work I did on this long ago (which I never done even though mentioning about it in sora's stackable library)... I'll have it posted up on the weekend, so you can take a look at it.

---------

just been looking over it (luckily I was able to find it, lol)...

it's really simple... I'll have something up on the weekend...

what I ended up doing was to make custom Verbs to handle storage specifically, that way I'm not messing with any other functionality (you can still 'take' and 'drop' like normal, wear/equip/remove/unequip like normal, and etc):

'store' Verb (transfers/moves items from inventory or where-ever location, into the correct storage sub-container inside of the inventory storage container): so for example, you could 'take' the Object (moves the object from the room or an Object in the room, to your inventory, aka the 'player' Object), and then 'store' it (moves the object from the inventory, aka 'player' Object, to the storage sub-container object inside of the storage container object inside of the inventory/'player'_object. Or, you could just 'store' the object (moving it from the room or object inside of the room, that it is in, to the storage sub-container object inside of the storage container object inside of the inventory/'player'_object directly. By having a 'store' Verb, you can still do/use 'take' putting stuff into your inventory, or you can 'store' putting the object into a subcontainer inside of a container inside of the inventory, or you can do both: take and then store (maybe at the time, you just wanted to take the object, having it in your inventory, as you thought you'd be using that item soon, but after not using it for awhile, you decide to store it, waiting for when you finall discover or get to its use).

'destore' Verb (transfers/moves items from the storage sub-containers into the inventory: you could then use the default 'drop' Verb normally, to move/transfer from the inventory to the room you're in). the same stuff about store applies here for destore: you can 'destore' (moving/"dropping" the item into your inventory), or you can do the normal 'drop' (moving "dropping" the item into the room that you're in as usual/normally).

-------

I literally just did a very simple long if/switch chain for the 'store' Verb, conceptual example only (not actual code) for idea of it:

(I'll post the actual code over the weekend, this is just to "tidy over" until then)

// I forgot what the built-in code for the openable/closeable container type (Object Type/Inherited Attribute), is... meh, so just pretend the 'storage' objects are openable/closeable containers... (initially starting as being closed obviously, as that's the point of this design, to NOT clutter up the inventory: you click on them to open them up seeing all their sub-items/objects, as you want to, and click again to hide them, keeping your inventory not cluttered, just like with folder organization), ??? : <inherit name="closed_container" />, <inherit name="openable_conainer" />, <inherit name="container" />

<object name="player">
<object name="storage_object">
<attr name="alias" type="string">storage</attr>
<object name="spell_storage_object">
<object name="fire_spell_storage_object">
</object>
<object name="water_spell_storage_object">
</object>
</object>
<object name="equipment_storage_object">
<object name="weapon_equipment_storage_object">
<object name="sword_weapon_equipment_storage_object"
</object>
<object name="axe_weapon_equipment_storage_object"
</object>
</object>
<object name="armor_equipment_storage_object">
<object name="headwear_armor_equipment_storage_object"
</object>
<object name="footwear_armor_equipment_storage_object"
</object>
</object>
</object>
<object name="item_storage">
<object name="healing/curative">
</object>
<object name="battle">
</object>
<object name="quest">
</object>
</object>
</object>
</object>

// and here's the "pseudo-scripting", *conceptual only*, for my custom 'store' Verb:

if (item.object_type = "spell") {
if (item.spell_type = "fire") {
item.parent = fire_spell_storage_object
} else if (item.spell_type = "water") {
item.parent = water_spell_storage_object
}
} else if (item.object_type = "equipment") {
if (item.equipment_type = "weapon") {
if (item.weapon_type = "sword") {
item.parent = sword_weapon_equipment_storage_object
} else if (item.weapon_type = "axe") {
item.parent = axe_weapon_equipment_storage_object
}
} else if (item.equipment_type = "armor") {
if (item.armor_type = "headwear") {
item.parent = headwear_armor_equipment_storage_object
} else if (item.armor_type = "footwear") {
item.parent = footwear_armor_equipment_storage_object
}
}
} else if (item.object_type = "item") {
if (item.item_type = "healing/curative") {
} else if (item.item_type = "battle") {
} else if (item.item_type = "quest/mission/non-useable/plot-story") {
}
}


-------

the issue again, is applying/implementing this design with Chase's Wearables design and/or your own game's design

The Pixie
Anonynn wrote:Actually, "Worn Clothing" is just an openable/closable object, not a room. I attached an object to the player.object called "Worn Clothing" and had it become a parent to clothing being worn by the player. The "Worn Clothing" object is inside the player inventory. :) Does that make it better or help any?

Okay, I misunderstood. Is the issue just that the container is closed?

Anonynn

Okay, I misunderstood. Is the issue just that the container is closed?



Nope! It happens when the container's open as well. So for example...

Inventory
itemname
itemname
shirt
Worn Clothing (closed)

wear shirt . You wear the shirt :D

Inventory
itemname
itemname
Worn Clothing (closed)

Inventory
itemname
itemname
Worn Clothing (open)
shirt (worn)

Remove shirt.

You can't remove it.
<----- this is the problem.

Inventory
itemname
itemname
Worn Clothing (closed)

Remove shirt. I can't see that ((which is fine, the issue is removing it when you can see it))



Does that make it more clear? x_X

HegemonKhan
can you post your code for 'remove' Verb/Command, as this should be a quick fix to get it working...

as all you need for the Verb is this:

blah_object.parent = player // if you want to move it out of where-ever (so it should work if it's in your 'worn clothing' container Object), as it doesn't even care where the Object is, it just sets it to being inside/contained_within the specified Object, and into the 'player' Object (your "inventory"), otherwise, change 'player' to where-ever you want it to be removed to.

------

the only reason I could possible see how it might not be removeable... is if you were to have an Object Type that prevents it from being dropped, and applied that to both your 'worn clothing' storage object and your 'shirt' object too, but even then I'm not sure if setting that built-in 'dropable' Boolean to false would prevent direct code of moving the object, such as using the 'parent' Object Attribute or 'MoveObject()' Script, but if the built-in/default 'remove' Verb's internal coding does/would check the Attribute, then it wouldn't thus do the drop. So, I'm confused... which is why I'd like to see your 'remove' Verb's code...

-----

if the 'remove' Verb/Command is Chase's altered code... then it should still be easy to fix/get working... just adding in the 'blah_object.parent=player', but that still wouldn't explain why 'remove' Verb/Command wouldn't work in the first place... unless Chase used his own code lines on how to do its removal... meh... I'm confused why its not working... lol

Anonynn
I don't know either. I already tried this on the "after removing" part of the wearables code ------> shirt.parent = player But it didn't help to remove the clothing inside the container. If it were that easy to solve I wouldn't have bothered everyone xD ! Maybe I should try shirt.parent = game or something like that.

the only reason I could possible see how it might not be removeable... is if you were to have an Object Type that prevents it from being dropped, and applied that to both your 'worn clothing' storage object and your 'shirt' object too, but even then I'm not sure if setting that built-in 'dropable' Boolean to false would prevent direct code of moving the object, such as using the 'parent' Object Attribute or 'MoveObject()' Script, but if the built-in/default 'remove' Verb's internal coding does/would check the Attribute, then it wouldn't thus do the drop. So, I'm confused... which is why I'd like to see your 'remove' Verb's code...



Nope, I already checked to see if things are droppable. They have to be removed first, then dropped. And all the appropriate check's are in place. The only thing that has been added is the "Worn Clothing" openable/closable container to which the items are set in. That cannot be dropped, maybe it's feeding that to the rest of the daughter objects inside?

Here's the remove code.

if (not object.parent = player or not GetBoolean(object, "worn") or not GetBoolean(object, "removeable")) {
if (object.removemsg = null) {
msg (DynamicTemplate("RemoveUnsuccessful",object))
}
else {
msg (object.removemsg)
}
}
else {
conflictedItem = null
// check if we are wearing anything over it
if (HasAttribute(object,"wear_slots")) {
foreach (item, ScopeReachableInventory()) {
if (HasAttribute(item,"wear_slots")) {
if (GetBoolean(item, "worn")) {
foreach (itemSlot, item.wear_slots) {
if (ListContains(object.wear_slots,itemSlot)) {
if (object.wear_layer < item.wear_layer) {
conflictedItem = item
}
}
}
}
}
}
}
if (conflictedItem = null) {
if (object.removemsg = null) {
msg (DynamicTemplate("RemoveSuccessful",object))
}
else {
msg (object.removemsg)
}
object.worn = false
object.drop = object.original_drop
object.alias = object.original_alias
object.original_drop = null
object.original_alias = null
object.display = null
// do after
if (HasScript(object, "onafterremove")) {
do (object, "onafterremove")
}
else if (HasString(object, "onafterremove")) {
msg (object.onafterremove)
}
}
else {
msg (DynamicTemplate("RemoveFirst", conflictedItem))
}
}


This is the modified "DoRemove"

HegemonKhan
HK edit:

ignore this post, Pixie found the actual culprit

(well... at least it was an interesting/creative idea of a possible cause by me... lol)

----------

you know what... are you using the 'door-like openable/close-able' container_type Object Type (or whatever it is called, meh), as maybe that just doesn't work, make sure you have it as a container_type as in 'openable_container' or 'closed_container'... whatever they're called...

as if you make an Object just be an openable/closeable "door-like" Object (via Object Type/Type/Inherited Attribute), than it is NOT an Object that has been given any scripting or Attributes to handle it being a container of other Objects, and thus this indeed could be the culprit of your remove is not working, as you made the Object, a NON-container, when it may very well need to be a container (have all the needed built-in scripting/Attributes for take/drop/wear/remove/lock/unlock/etc etc etc container features).

let me actually open up quest... (or just look at the quest doc online... that's actually faster... lol) ... one sec

------

I am getting optimistic (with fingers crossed though - HK never is confident enough to be optimistic and HK's history proves it, lol), that this may indeed be the culprit (if you're indeed using the 'door' openable container_type, and not one of the actual container_types...

here they are in the doc (too lazy to start up quest and look at it through the GUI~Editor drop down options, lol):

http://docs.textadventures.co.uk/quest/ ... bject.html (scroll down to the very bottom)

http://docs.textadventures.co.uk/quest/ ... nable.html (as can be seen, this is for door Objects, opening and closing, but not able to actually contain/hold any Objects)

http://docs.textadventures.co.uk/quest/ ... ainer.html (I think this is the most base case)

(and I think these below are the actual container types):
http://docs.textadventures.co.uk/quest/ ... _base.html (this is the base of these actual container types)
http://docs.textadventures.co.uk/quest/ ... losed.html
http://docs.textadventures.co.uk/quest/ ... mited.html
http://docs.textadventures.co.uk/quest/ ... _open.html
http://docs.textadventures.co.uk/quest/ ... rface.html

-------------

container_lockable seems to be completely separate, requiring that you also must inherit (container_limited/container_open/container_closed), obviously, in order to able able to apply the lock/unlock scripting with the open/close scripting from the container_limited/container_open/container_close. The 'Surface' type isn't included, as it is an 'always open' container.

-----------

my guess at the inheritance heirarchy:

.............openable (doors, NON-containers)
.........../
container.....................container_open (container, starts in opened state, can change between opened and closed states)
...........\................../
............container_base - container_closed (container, starts in closed state, can change between opened and closed states)
....................\.........\
.....................\.........container_limited (container, has 'maxobject/volume' Attributes, for handling/limiting/specifying quantity of child objects)
......................\
.......................surface (container, always is in an opened state - can't be in a closed state)


----------------------------

so, have your 'clothes worn' storage object (and any of its child-sub storage objects) be:

container_closed and container_limited (the container_limited would only be added too for the most child storage objects, holding the actual stored objects)

AND THUS NOT BE:

openable, nor surface, too

The Pixie
The problem is the very first line of the code you posted:
if (not object.parent = player or not GetBoolean(object, "worn") or not GetBoolean(object, "removeable")) 

It is testing if the item is a direct child of the player (i.e., shirt.parent = player). You need to check if it is Worn Clothing. in fact a better way might be to test if its parent's parent is player:
if (not object.parent.parent = player or not GetBoolean(object, "worn") or not GetBoolean(object, "removeable")) 

HegemonKhan
you may have to do different scripting for dynamic child layers... is there a built-in function for getting the 'root parent' for a (any) child object ???

-------

good catch on finding the actual culprit Pixie (HK says "doh!" to himself)

The Pixie
The best way would be to use ListParents(object), which returns a list of objects, and then test if the list contains the player object. The root parent would be the room the player is in, by the way.

Anonynn

if (not object.parent.parent = player or not GetBoolean(object, "worn") or not GetBoolean(object, "removeable"))



Yay! Stuff can be removed now. Thank you so much! But what would be the opposite code to return the unworn items to the player inventory :) ?

For example:
After Wearing
plain_bra.parent = Worn Clothing

After Removing
plain_bra.parent = Player?

The Pixie
Yes, but it is player, not Player. The case is important

HegemonKhan
yep, the 'inventory' IS the 'player' Player Object

blah_Object.parent = player // (or whatever you changed its name to, as Pixie said, upper/lower case matters)
// is putting something into the "inventory" = is putting something into the 'player' Player Object
// "inventory" = 'player' Player Object

Anonynn
Great! That worked! Thank you both so much for all of your help with that, I really, really appreciate it! :D :D :D!

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums