Wearables Library (need technical help)

Anonynn
Error running script: Error compiling expression 'item.worn = true': CompareElement: Operation 'Equal' is not defined for types 'Object' and 'Boolean'


This error is popping up and I've tested it a lot. It seems that as long as the player doesn't do anything and immediately try to equip the clothes it is fine (though if they take them off and do something and then try to requip the error returns), but if they do ANYTHING else first...that error pops up.

Now I've checked the clothing booleans in the game and they are set to false when the game starts ---- so I'm not sure what is going on with this...

TM123
I reproduced the error by making a wearable object then setting it to "cannot be worn."
This leaves in the "wear_slots" attribute which the "DoWear" function checks for as a way to test for wearability,
but removes the "worn" attribute. When the "worn" attribute is missing, "item.worn = true" will give that error.

So I would check your inventory (specifically ScopeReachableInventory) for an item with a "wear_slots" attribute, but no "worn" attribute - probably something set to "cannot be worn."

Change all the "item.worn = true" in the DoWear and DoRemove functions to "GetBoolean(item, "worn")"
The "GetBoolean" would return false if the attribute "worn" doesn't exist instead of causing an error.

Anonynn
TM123 wrote:I reproduced the error by making a wearable object then setting it to "cannot be worn."
This leaves in the "wear_slots" attribute which the "DoWear" function checks for as a way to test for wearability,
but removes the "worn" attribute. When the "worn" attribute is missing, "item.worn = true" will give that error.

So I would check your inventory (specifically ScopeReachableInventory) for an item with a "wear_slots" attribute, but no "worn" attribute - probably something set to "cannot be worn."

And/or stick a "if(HasAttribute(item,"worn"))" into the DoWear and DoRemove function just before the "if(item.worn = true)"


This seems to have worked. We may want to release a new version of the wearables library with these changes so that this isn't an issue anymore. Thank you very much for the help!

TM123
Note that I changed the fix to use the GetBoolean function -- a little easier than adding even more curly braces.

HegemonKhan
Thank you TM123 for helping neonayon with Chase's and Pixie's libraries, as I forgot to do it, and also am too busy getting ready for school, to have troubleshooted this issue for neonayon (it'd take me a long time to re-learn Chase's and Pixie's libraries and then find the issue~problem), as I barely understand this level of coding of Chase's and Pixie's (and all the other good coders' codes, lol).

Anonynn
Alright. Well, after implementing the Journal thing. The boolean error started happening again. Here is the coding for the DoWear and DoRemove ....same problem as last time. It seemed like it was fixed but if the player does anything else before the clothing the boolean pops up again.

DoWear
if (not HasAttribute(object,"worn")) {
msg (DynamicTemplate("WearUnsuccessful", object))
}
else if (object.parent = player and object.worn = true) {
msg (DynamicTemplate("AlreadyWearing", object))
}
else if (not ListContains(ScopeInventory(), object)) {
msg (DynamicTemplate("WearUnsuccessful", object))
}
else {
isLayerProblem = false
conflictedItem = null
if (HasAttribute(object,"wear_slots")) {
foreach (item, ScopeReachableInventory()) {
if (HasAttribute(item,"wear_slots")) {
if (HasAttribute(item,"worn")) {
}
if (item.worn = true) {
foreach (itemSlot, item.wear_slots) {
if (ListContains(object.wear_slots,itemSlot)) {
if (object.wear_layer < item.wear_layer) {
conflictedItem = item
isLayerProblem = true
}
else if (object.wear_layer = item.wear_layer) {
conflictedItem = item
}
}
}
}
}
}
}
if (conflictedItem = null) {
object.worn = True
object.original_drop = object.drop
object.original_alias = object.alias
object.drop = false
object.display = GetDisplayName(object)
object.alias = GetDisplayAlias(object) + " (worn)"
if (object.wearmsg = null) {
msg (DynamicTemplate("WearSuccessful",object))
}
else {
msg (object.wearmsg)
}
// do after
if (HasScript(object, "onafterwear")) {
do (object, "onafterwear")
}
else if (HasString(object, "onafterwear")) {
msg (object.onafterwear)
}
}
else if (isLayerProblem = true) {
msg (DynamicTemplate("CannotWearOver",conflictedItem))
}
else {
msg (DynamicTemplate("CannotWearWith",conflictedItem))
}
}



and

DoRemove
if (not object.parent = player or not object.worn or not 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 (HasAttribute(item,"worn")) {
}
if (item.worn = true) {
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))
}
}


What a pain! But at least if we can isolate this problem then other people will be able to use the library again.

TM123
You have the curly braces in the wrong place. I hate curly braces. I think I'm curly brace dyslexic.
I went over my changes using "getboolean" and discovered another problem, also involving the boolean attributes that don't exist. So here's the functions with "getbooleans" added that should solve the problems.

DoWear:
	<function name="DoWear" parameters="object"><![CDATA[
if(not HasAttribute(object,"worn")) {
msg (DynamicTemplate("WearUnsuccessful", object))
} else if (object.parent = player and GetBoolean(object, "worn")) {
msg (DynamicTemplate("AlreadyWearing", object))
} else if (not ListContains(ScopeInventory(), object)) {
msg (DynamicTemplate("WearUnsuccessful", object))
} else {
isLayerProblem = false
conflictedItem = null

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
isLayerProblem = true
} else if(object.wear_layer = item.wear_layer) {
conflictedItem = item
}
}
}
}
}
}
}

if(conflictedItem = null) {
object.worn = True
object.original_drop = object.drop
object.original_alias = object.alias
object.drop = false

object.display = GetDisplayName(object)
object.alias = GetDisplayAlias(object) + " (worn)"

if(object.wearmsg = null) {
msg (DynamicTemplate("WearSuccessful",object))
} else {
msg(object.wearmsg)
}

//do after
if (HasScript(object, "onafterwear")) {
do(object, "onafterwear")
} else if(HasString(object, "onafterwear")) {
msg(object.onafterwear)
}
} else if(isLayerProblem = true) {
msg(DynamicTemplate("CannotWearOver",conflictedItem))
} else {
msg(DynamicTemplate("CannotWearWith",conflictedItem))
}

}
]]></function>


DoRemove:
	<function name="DoRemove" parameters="object"><![CDATA[
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))
}
}
]]></function>

Anonynn
I'll check to see if this works! Thanks again TMI. You sort of...just came out of nowhere lol but you're incredibly helpful!

Anonynn
Alright, so there appears to be ONE more issue with the clothing. The boolean that was happening before seems forever fixed, but I'm having another very minor problem!

It seems that if a PC is wearing the item of clothing...and they try to drop it (while wearing it), the game prints the drop message, even though the item is still worn on the player.

Is there a way to add a check like "you have to remove it first?" before the drop message is displayed? Or am I wishing against fate!?

TM123
Neonayon wrote:It seems that if a PC is wearing the item of clothing...and they try to drop it (while wearing it), the game prints the drop message, even though the item is still worn on the player.


Hmm. It has code to handle dropping, and it is working for me. I'll look it over.

TM123
Is this for all items or some?
Does the PC start the game wearing these items?

You mean it is like this:
> inv
You are carrying a pants.
> wear pants
You put it on.
> inv
You are carrying a pants (worn).
> drop pants
You drop it.
> inv
You are carrying a pants (worn).
> look
You are in a room. --- (you don't see any pants)

The DoWear sets the worn object's .drop attribute to false, and doesn't mess around with anything else having to do with dropping. If .drop = false then you can't drop it. If DoWear makes a mistake and .drop = true then you can drop it.
The core library handles that. I would guess the false drop message is coming from a script.
Could you post the code for one of the clothing objects?

Anonynn

Is this for all items or some?
Does the PC start the game wearing these items?

You mean it is like this:
> inv
You are carrying a pants.
> wear pants
You put it on.
> inv
You are carrying a pants (worn).
> drop pants
You drop it.
> inv
You are carrying a pants (worn).
> look
You are in a room. --- (you don't see any pants)

The DoWear sets the worn object's .drop attribute to false, and doesn't mess around with anything else having to do with dropping. If .drop = false then you can't drop it. If DoWear makes a mistake and .drop = true then you can drop it.
The core library handles that. I would guess the false drop message is coming from a script.
Could you post the code for one of the clothing objects?



Yeah, of course. Here is the code.

          <object name="cute_headband">
<inherit name="editor_object" />
<inherit name="wearable" />
<alias>Cute Headband</alias>
<look><![CDATA[<br/>A cute black headband with a shimmering silk strip down the center. ]]></look>
<usedefaultprefix type="boolean">false</usedefaultprefix>
<alt type="stringlist">
<value>cute headband</value>
<value>head band</value>
<value>black headband</value>
<value>cute black headband</value>
</alt>
<take />
<volume type="int">1</volume>
<takemsg>You take the headband in hand. </takemsg>
<dropmsg><![CDATA[{once:(You have to "<i>Remove</i>" it before you can drop it)} You drop the headband. ]]></dropmsg>
<attr name="wear_layer" type="int">9</attr>
<inventoryverbs type="stringlist">
<value>Look at</value>
<value>Drop</value>
<value>Wear</value>
<value>Remove</value>
</inventoryverbs>
</object>


I use the default take and drop messages from the game, not the "wearables" drop and remove customizable scripts. Does that matter?

TM123
Here's the problem, in the inventory custom drop message:

<dropmsg><![CDATA[{once:(You have to "<i>Remove</i>" it before you can drop it)} You drop the headband. ]]></dropmsg>


You need some more logic in there.

<dropmsg><![CDATA[{if cute_headband.worn:You can't drop it.{once: You have to "<i>Remove</i>" it before you can drop it.}} {if not cute_headband.worn:You drop the headband.}]]></dropmsg>


If it is worn, it will give this message the first time:
You can't drop it. You have to "Remove" it before you can drop it.
After the first time:
You can't drop it.
If it is not worn:
You drop the headband.

Anonynn
Oh, great! That worked like a charm. Appreciate you looking into this for me! I hope it helps some other people using this library as well!

Anonynn
I had another question. Is there a way to do a "wear" check --- meaning that if the character approach an NPC and are carrying the clothes but not wearing them, that the NPC will be all freaked out? Just wondering!


I was also wondering if the "text processor" could recognize the same thing like in the descriptions of the clothing. Wearing and not wearing.

Oh, and is there a way for the clothing item to have a check on "body parts" like if the player is too "large" to wear something the item cannot be worn,

For example...

{if player.weight<4: You are too large to wear this.}

Anonynn
So anyone have any idea?

The Pixie
You can check if a specific item is worn with the "worn" Boolean attribute. To check if the player is naked, check all held items.
naked = true
foreach(o, ScopeInventory ()) {
if (GetBoolean(o, "worn")) {
naked = false
}
}
if (naked) {
msg("He freaks out, what with you being naked.")
}

Of course, if the player is just wearing a pair of heels, the character will not be freaked out... I guess you could also check the "wear_slots" attribute too.
naked = true
foreach(o, ScopeInventory ()) {
if (GetBoolean(o, "worn")) {
if (o.wear_slots = "chest" or o.wear_slots = "groin") {
naked = false
}
}
}
if (naked) {
msg("He freaks out, what with you being naked.")
}

For text processor, if you are describing one specific item, again you can use the "worn" attribute, but it cannot handle anything more complicated.
The bowtie{if bowtie.worn: that you are wearing} is black.

Anonynn
Thanks Pix!

So just to be clear...

[quote]naked = true
foreach(o, ScopeInventory ()) {
if (GetBoolean(o, "worn")) {
if (o.wear_slots = "chest" or o.wear_slots = "groin") {
naked = false
}
}
}
if (naked) {
msg("He freaks out, what with you being naked.")
}[/quote]


^--- what is the "o" in o.wear_slots? This will likely be the one I'll be using for most events if the player is indeed nekkid, haha.

Also, thank you for sending that revised version of the game. I haven't been able to look at it yet because I have two exams practically back-to-back so I've been studying my booty off. Ugh! But I'll get back to you on it asap!

The Pixie
Neonayon wrote:^--- what is the "o" in o.wear_slots? This will likely be the one I'll be using for most events if the player is indeed nekkid, haha.

The code uses foreach to test each object in a list (which comes from ScopeInventory). Inside the loop, o is the current list entry. Say the player has a hat and a teapot, the first time through the list o is the hat, the second time o is the teapot. You can use any name for the variable, I use o to stand for object.

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

Support

Forums