Extended Wearables Library

Chase
I saw the Clothing Library. looked it over and found it sorely inadequate. I am a programmer by trade so I figured I could write something better.

So here it is. It isn't perfect, and could still use some minor tweaking.

What it does
Allows items to be worn in a intuitive way.
Allowed you to prevent removal once worn (cursed objects)
Allows Wear slots/location (Mutually Exclusive worn items)
Event System for after wear/removal of the item
Disallowed obvious things, such as you cannot drop something you're wearing.
Layered Clothing Support. Meaning you cannot pull your socks off before removing you're shoes.
Support items with or without aliases.

Version History

v2.3
=Fixed a significant bug where you could not wear something if a non-wearable item was in your inventory.

v2.2
=Fixed an issue where the custom remove message doesn't play if the item cannot be removed.

v2.1
=Fixed an issue of an error being thrown when trying to wear something that is not wearable. It never occurred to me someone would try to wear like.. I dunno, a briefcase.

v2.0
+Rewrite
+Added wear layer support
-Known: Not compatible with v1.0 (shouldn't be a big issue)

v1.4
=Fixed an issue with wearing multiple blank items (should make it quicker too)
=Fixed the issue with wearing items without aliases
=Was some minor code cleanup, should most other issues that cropped up in v1.03

v1.3
+Added configurable wear/remove messages
-Removed redundant events

v1.2
+Added Event Handlers
+Fixed drop bug

v1.1
+Fixed a small typo, should work now.

v1.0
=Initial Release


This was written for my game "The Festival" due out sometime in the next millenium.

Pertex
Nice work!
In my opinion it's possible to copy the name into alias if alias is empty.
It would be great, if you could add equipment to your lib. So an object "can be worn" , "can be equiped" and "can't be worn/equiped". And you can wear an object and equip an object in the same slot.

If you do not add wear slots to objects which can be worn you will get a bug if you put on two or more objects. So you should add <wear_slots type="list"></wear_slots> to the type.

Chase
That adds a list with one element of length 0 to the visual UI, may also cause a bug with one zero length entry being equal to the other zero length entry (meaning only one could be worn like that at a time). But the engine might be smarter then that (But I certainly hope not, as I like my dumb languages, thanks :D).

I think I know a better way around the issue however, I can just check to see if it has a list, if not don't even try and compare. Thanks for the feedback, i'll write up a 1.04.

Chase
Updated

ASLX's limitations want to make me pull my hair out, but I got over that to bring you a bugfixed version.

v1.04
=Fixed an issue with wearing multiple blank items
=Fixed the issue with wearing items without aliases

Which just leaves layering, I am considering doing something like the following.

Each wearable has a wear layer, a numeric value from 0 to some really large number.

You would be able to wear anything with a higher layer over anything with a lower layer. It would be very annoying (for both me and game builders) to check multiple layers on different slots against each other, so I am considering just having a single slot_layer value, which will determine what layer it is on.

By default everything would be layer 0. No, better yet, by default layer 2. See what I did there?

I'll play around with the layering system and see if I can get a nice working version of this layering system.

Chase
I am in the middle of rewriting it to be more like the internal libraries. It long since grew to big for the basic clothing library template. Also resolving a number of previous issues during the rewrite.

Chase
New version, version 2. Almost entirely rewritten, some of the templates might need a little tweaking. Also the level of customization isn't where I want it to be but it works for what I expect people would want from a clothing library.

v2.0
+Rewrite
+Added wear layer support
-Known: Not compatible with v1.0 (shouldn't be a big issue)

Find latest version in First Post.

Chase
So any input on version 2?

Good? Bad? Ugly?

Suggestions on templates and the like?

sgreig
I haven't had a chance to play around with it yet, but I'm intending to use it with a little project I'm working on at the moment so I'll report back once I've had a chance.

Pertex
It's great, I added it to the wiki some time ago. I just used it as a template for my siton-library :D
And there is a bug in it. If you try to wear an object, which is not wearable, you get an error.

Chase
Ah, whoops, i'll see about fixing that (didn't think to try that, why would anyone try wearing something unwearable ;))

Edit: FIXED
Edit: REFIXED! I am 90% sure this time. :)


On a side not I suppose I should mention that while originally based on Pixie's clothing library, it is far removed from that now. I rewrote it to more closely match the internal libraries (that is what I did in v2).

The only thing really left over from Pixie's library is (part of) the check if already being worn logic and the basic arrangement of the library (that is templates are first, then the command/verb, etc).

Chase
Well there are two types of 'sitting' as I see it.

There is sitting on, and sitting in.

Sitting on allows you pretty much the same access as standing up, might limit/allow a few things in the room selectively. Where as sitting in is pretty much a new room altogether.

Sitting in, is like a car, or a arcade racing machine, etc.

Things you sit on is anything else really. A chair, a stool, or a etc.

I would provide an auto-stand option for things you can sit on in the game options. So if you move north, you can either automatically stand up and move north, or tell them they need to stand up first.

Since most 'sitting on' is just so that you can. Few things require you to sit on something. Among these are like getting a hair cut, perhaps playing a carnival game (though most are stand based), or during an interview.

Most things that require you to sit in, 100% require you to 'sit in' them. A roller-coasters, a car, etc.

Makes me want to make such a library myself.

Jsimmons
Does this wearbles file fix the bug that I keep having with the one I downloaded when it came to picking up items that are not wearable?

What would happen is that I would be wearing an object, and then I'd try to pick up an object that wasnt wearable, and It would bring up an error message. I could carry the non-wearable object and pick up what my character was wearing, but its not practical to shed all clothing and wearable items in the inventory just to pick up one item. I can solve the issue by making the item wearable, but I dont actually want it to be wearable, so does this file fix that bug?

Pertex
Try it with this version. I just removed a bug in it

Chase
I don't seem to have this problem in my tests, can you tell me a bit more about it. The changes made to the above script shouldn't really change much of anything.

I can pick up items not wearable while wearing things. Honestly the library doesn't even touch that code in any way, so it (in theory) shouldn't conflict. However there might be some special interactions going on. So please let me know.


OTHER NEWS:
Updated to actually play the custom remove message if the item is unremovable and someone tries to take it off. (It only played the default message before)

Pertex
In your lib you check all items in the inventory
foreach(item, ScopeReachableInventory()) {
if(item.worn = true and HasAttribute(item,"wear_slots")) {

item.worn = true throws an error if there is an item without the worn attribute. So I check this attribute first
foreach(item, ScopeReachableInventory()) {
if (HasAttribute(item,"worn")and HasAttribute(item,"wear_slots")){
if(item.worn = true) {

jaynabonne
You could also do this:

if(GetBoolean(item, "worn") = true and HasAttribute(item,"wear_slots")) {


as GetBoolean just returns false if the attribute doesn't exist.

Or even:

if(GetBoolean(item, "worn") and HasAttribute(item,"wear_slots")) {


(Is the "= true" part actually necessary for a boolean value? "if (((x = true) = true) = true)" ad infinitum )

Chase
jaynabonne wrote:Is the "= true" part actually necessary for a boolean value? "if (((x = true) = true) = true)" ad infinitum

I think it might in this, I am not entirely sure, but it is better to be safe I figured when working with an unknown language.


Edit: I have been able to reproduce the bug, working to fix it now, thanks for the report!

Edit Again: Fixed, updating to v2.3 in OP. I gotta say, this scripting language drives me a little batty sometimes heh.

Jsimmons
The new library fixed the bug, which proved extremely helpful in continuing my game. Thanks for looking into it.

Chase
Yup, sorry about not testing that in the first place. Send me a link once your done, I am interested in seeing the finished product.

Mostly since I haven't seen any finished game using my library yet (possibly for good reason ;)

Chase
Here is a general how it works.

On Wearing an item

If the item is not wearable, print an error message telling the player off. Then exit the function.
If the item is already worn, print an error message telling the player off. Then exit the function.

For every item in the inventory,
check if the item is wearable,
if so, check if it is on an equal or higher layer to what we are trying to wear,
if so, check if any of its wear locations match the item we are trying to wear,
if so, then print an error message telling the player off and exit the function.
(if not continue to next item)

If there are no conflicts with anything else the player is wearing then,
print a message telling the player the item is now worn,
update the inventory title of the item to show its worn,
run any scripts on the item in question.

On Removing an item

If the item is not wearable, print an error message telling the player off. Then exit the function.
If the item is not worn, print an error message telling the player off. Then exit the function.
If the item is cursed, print an error message telling the player off. Then exit the function.

For every item in the inventory,
check if the item is worn,
if so, check if it is on a higher layer to what we are trying to remove,
if so, check if any of its wear locations match the item we are trying to remove,
if so, then print an error message telling the player off and exit the function.
(if not continue to next item)

If there are no conflicts with anything else the player is wearing then,
print a message telling the player the item has been removed,
update the inventory title of the item back to its original title,
run any scripts on the item in question.

m4u
Hi, how can i make the thing being worn from the beggining (by default), so the player starts wearing a clock for example?

HegemonKhan
Hopefully this will do it, lol:

"player" -> Objects (Tab) -> Add -> (your equipment object, such as for example: wooden_sword or cloak)

"wooden_sword" -> Attributes (Tab) -> Add ->

Name: worn
Type: boolean
Value: true

also, you'd need to set the other (Chase's library's) attributes' values too for your objects ("wooden_sword or cloak or whatever"):

(whatever the attributes are actually called, lol)

wear_layer // what number (integer) is it?
wear_slots // what label (string) is it? (for examples: for a wooden_sword: right_arm, for a cloak: back, for a helmet: head)
etc

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

actually, this probably won't work, as the scripts that create the "wooden_sword (worn)" in your display are activated via the "wear" and "remove" commands~verbs~functions, so just setting the "wooden_sword.worn", won't be enough. you'd need to add some kind of coding to activate the same scripts that are activated in the "wear" and "remove" commands~verbs~functions.

maybe we could do (add) this script for your Game Object's "start" script:

http://quest5.net/wiki/Do

Do (wooden_sword, "wear")

along with setting, "wooden_sword.worn", too as I shown above at top of this post.

m4u
Thank you, with the DoWear function was enough!

Entropic Pen
And I thought my combat system was complicated... but I can see the potential of this library in "Welcome to Dream Valley" and FUTURE projects. The key word being "potential", and not "sweet mother of Super Mario I gotta have this in my game!"

rfrijhoff
It seems that the wearable library only works with 'player', but not with other created actors (player or not). If i'm doing something wrong, please tell me, otherwise can and will you fix this problem?

HegemonKhan
I haven't taken a hard look at this yet, so this might be incorrect, but I think that it is because:

the "equipping" utilizes the "displayment", which is the "statusattributes" and its pane during game play, which only works for Player Objects (such as the default: "player" Player Object).

So... you'd just have to have your Object be a Player Object (and to actually see it during the game, you'd have to control of that Player Object) for Chase's "equipping" coding to work.

To have a NON-Player Object have "equipping" features, it is a lot more simplistic, as you just have that Object be "equipped" with the gear, or not.

Now, if you want to have "AI intelligence" to be able to equip and unequip... that'd take some skill with coding, lol.

Also, I'm sure you (or someone) can craft coding that doesn't use the "statusattribute" for the "equipping", which is what would let you do "equipping" on any Object, and not just a Player Object, like Chase's coding only allows for.

---------

HK Edit:

in looking at Chase's code, my hunch was right, the code is only crafted to work with Player Objects, due to what I mentioned above, and also because of this part of Chase's coding as well: it searches through the "Player_Object_Scope.inventory", which is also only for Player Objects (unless you alter the core coding ~ though this would take a lot of coding skill to do it and get it to work).

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

P.S.

this is only generalizations on my part, so ask, if you need help on specifics with "equipping", and I'll see if I can help you, or if not me, than hopefully others will help you, hehe.

The Pixie
rfrijhoff wrote:It seems that the wearable library only works with 'player', but not with other created actors (player or not). If i'm doing something wrong, please tell me, otherwise can and will you fix this problem?

It was written for an earlier version of Quest that used "player" for the player, rather than "game.pov". You should be able to update your copy of the library just by doing a search-and-replace with those two terms (though I would recommend checking each one individually to see if it is appropriate to replace it).

Chase
Ah sorry, if you want to give a rundown of what exactly is wrong I will see about updating the library to your satisfaction.

As far as I can tell, the desired additional features are:

[list=1]
[*]Allow objects to be worn initially.[/*:m]
[*]Allow non-player actors to wear things.[/*:m][/list:o]

It has been awhile since I played with Quest, so either one of these may be more difficult then the other.

m4u
For some reason opening the wearables.aslx with the notepad shows the code scrambled over the screen, any other program to open it?

HegemonKhan
a really useful free program~software:

http://notepad-plus-plus.org/

(I think the site can be changed to a few other languages, in the upper left corner)

(once you got the software~program and opened~started it up, in the menu bar at the top, select "Language", and choose "XML")

it's great for code writing, reading, and troubleshooting, as it uses color coding and have a lot of very useful features that I've yet to learn about and use still myself, lol.

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

the default computer built-in "notepad" does mess up the tabing and of spaces quite a bit, you could also try the other default software: "wordpad", if you don't want to get the "notepad++" (but you should, it's really awesome, especially for being free)

Silver
Does this make wearable objects scriptable. Such as if player is wearing object Y then.. ?

HegemonKhan
yes:

DoEquip:

if (HasScript(object, "onafterwear")) {
do(object, "onafterwear")
} else if(HasString(object, "onafterwear")) {
msg(object.onafterwear)
}

DoRemove:

if (HasScript(object, "onafterremove")) {
do(object, "onafterremove")
} else if(HasString(object, "onafterremove")) {
msg(object.onafterremove)
}

Tags for being able to use the Editor:

<control>
<mustinherit>wearable</mustinherit>
<selfcaption>After wearing the object</selfcaption>
<controltype>multi</controltype>
<attribute>onafterwear</attribute>
<types>null=None; string=Text; script=Run script</types>
<editors>string=textbox</editors>
<expand/>
</control>

<control>
<mustinherit>wearable</mustinherit>
<selfcaption>After removing the object</selfcaption>
<controltype>multi</controltype>
<attribute>onafterremove</attribute>
<types>null=None; string=Text; script=Run script</types>
<editors>string=textbox</editors>
<expand/>
</control>


though, you'll have to choose~make the script that you want to be run, of course.

Silver
I'll give it a whirl. Although I suspect you may have to talk me through that process. :mrgreen:

HegemonKhan
it's just like the default "room descriptions" setup in the GUI~Editor:

player.fire_protection = false

onenterroom -> run as script ->

add a script -> if... -> variables -> set a variable or attribute -> player.fire_protection=true
-> then, add a script -> print a message [MESSAGE] -> Thanks to your protective gear, you don't lose 500 HP in the volcanic cave.
else, add a script -> if... -> variables -> set a variable or attribute -> player.fire_protection=false
-> then, add a script -> variables -> set a variable or attribute -> player.hp = player.hp - 500
-> add a script -> output -> print a message [MESSAGE] -> The volcanic cave is too hot without protective gear, you lose 500 HP.

but with Chase's Wearables library added, you got tabs now in the GUI~Editor with~for the wearing of equipment:

afteronwear -> run as script ->

add a script -> variables -> set a variable or attribute -> player.fire_protection = true

afteronremove -> run as script ->

add a script -> variables -> set a variable or attribute -> player.fire_protection = false

Silver
I see. As i don't understand code when people post up bits of code i assume i have to somehow implement that code into the game somehow although now I think you were offering an explanation in code which I wouldn't understand as I don't understand code... :mrgreen:

I guess i need to understand code.

HegemonKhan
1. do you know how to add the library to your game? (if no, tell us in post, and we'll help you with it)
2. if yes, then in the GUI~Editor (no coding knowledge required nor used), for your Objects, you'll now have a "wearables" Tab.
3. choose the "run as script" under the "after_on_wear" and also under the "after_on_remove".
4. then select your scripts to add for what you want to be done.

"dragon_scale_mail" (Object) -> Wearables (Tab) -> afteronwear -> run as script -> add a script (and etc scripts)
"dragon_scale_mail" (Object) -> Wearables (Tab) -> afteronremove -> run as script -> add a script (and etc scripts)

---------

yes. in my previous post, that scripting (but it was mostly shown to be done with the GUI~Editor, so you can follow along) was just an example only, but here's what it says and does conceptually:

upon wearing the equipment object (let's say, a "flame_shield"), change the player's boolean attribute called "fire_protection" from its original set up as "player.fire_protection=false" to its new set up as "player.fire_protection=true"

and upon removal of the equipment object (let's say, a flame_shield"), change the player's boolean attribute called "fire_protection" from its current set up as "player.fire_protection=true" back to its original set up as "player.fire_protection=false"

as for the "volcanic cave" room's scripting:

if you (player) are fire protected (player.fire_protection=true), then message script "Thanks to your protective gear, no fire damage is done to you".

if you (player) are not fire protected (player.fire_protection=false), then damage (lower) the player's hp by 500 (player.hp = player.hp - 500) and also message script "Due to not having protective gear, you've been damaged by 500 HPs"

Silver
Yes was able to add the library to my game. Okay I'll try and make my question clearer.

As an example, say you need to wear a disguise in order to achieve something. In my game there's going to be a locked door and something that reads an ID card. However, the player looks nothing like the photo on the ID card and until he does he can't progress past the door. So I would need a script along the lines of

If player is wearing object a, object b and object c then door unlocks

Else print << Warning, ID and face mismatch >>

However, the wearables tab doesn't appear to cover that depth. My question was are wearable objects now an option in the script editor (rather than just basic scripts in the wearable tab)?

HegemonKhan
ah okay, you need help with the scripting.

yes, you've got to do the scripting yourself, and this request is a bit more complex than you realize, it's going to require a bit of scripting in different places.

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

all you want to do with the Objects' wearables tab, is to:

1. "can be worn?", choose: wearable = can be worn

2. leave "removeable" checked (on~able to remove), don't change it (don't uncheck the box)

3. leave the "wear_layer" at "2" (as you're probably not going to work with multiple layers~levels of clothing~equipment)

4. leave "wear slots" blank! (as you're probably not going to have different body locations for what you're wearing)

5. type in what you want for the message of wearing the object, or leave it blank to do its default message

6. type in what you want for the message of removing the object, or leave it blank to do its default message

(HK edit: removed #7~"onafterwear" and #8~"onafterremove", as this was a mistake on my part, leave them blank)

-----------

and now for your "ID card reader" Object's "scan" Verb:

Add a script -> scripts -> if... -> [expression] (or whatever option that achieves this to the right, lol ~ I don't know the editor that well) -> type this in (example objects "mask", "wig", and "contact_lenses" used): mask.worn=true and wig.worn=true and contact_lenses.worn=true

-> then -> add a script -> objects -> unlock (door)

else -> add a script -> print a message -> [MESSAGE] -> Hey kid, do you think I'm an idiot, you don't look anything like the picture on this stolen or fake ID card of yours, you're not getting into the bar and you're going to jail for theft or fraud too!

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

"door" Object:

requires it's own scripting to unlock the exit (now that the door is unlocked, you can open the door, which unlocks the exit, and moves the player into the other connected room of the exit)

Silver
Hey, thanks for the help. Once I've implemented and tested it I'll get back to you on whether I've got it working or not. :shock:

But now I know it can be done I can at least start building the puzzle.

HegemonKhan
err... my mistake, don't do #7 and #8, leave these blank ~ don't touch them, as the wearable library's added Verbs "wear" and "remove" already sets "this.worn=true" and "this.worn=false" for you.

I edited my previous post, so look at it again.

Silver
Thanks for the clarification. My only query would be when you say leave the "wear_layer" at "2" I think if all objects are set at 2 they can't be worn simultaneously?

So I would need to set each object at different layers even if they're all worn on the head?

HegemonKhan
no, they should be okay if they're all the same number, be it 2 or another number, as the script only checks if you also give them a body location slot too.

as can be seen (just showing the "DoWear", as don't need to show "DoRemove" as well):

DoWear:

if(HasAttribute(object,"wear_slots")) {
-> foreach(item, ScopeReachableInventory()) {
->-> if(HasAttribute(item,"wear_slots")) {
->->-> 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
->->->->->-> }

----------

HK Edit:

actually, I'm not sure... lol

so, maybe I'm wrong, if I am, then giving each object a different "wear slot" string (ie: "body", "head", "arm", "leg", "red", "blue", etc lol) would be what you want to do, if you need to do something, as this causes no conflicts with the "wearable" Objects.

Chase
Last I recall, it does indeed only matter if you have something in the slots. Otherwise layer doesn't matter. I did this so that you could as complicated or as simple of wearable items as you wanted.

Though it isn't perfect, I mean in theory you could wear a pair of socks over another pair of socks.

Silver
Okay I've found, purely by accident, a bug in this library. I accidentally input the wrong command asking the game to remove an item of clothing I wasn't wearing and it returned an error. So I tried with a few other random objects and all returned the same error. Which was:

Error running script: Error compiling expression 'not object.parent = player or not object.worn or not object.removeable': NotElement: Operation not defined for type 'Object'



Surely this should default to some message like "You're not wearing it"?

Grainger
Hi...
I've just found this in the documentation:

in Quest 5.3 the object 'player' is replaced with 'game.pov' so if you are working with Q 5.3 or higher replace 'player' with 'game.pov'



Are there any plans to enhance the library so that also others (e.g. a wizard) can wear stuff like, say, a hat? If I figure out how to do it, would it help if I offer the changes here?

Thanks!

Grainger
Hmmm... while I'm at it: is there a way to expand "wearables" to have special attributes, such as armor points or some such? I'd like to add up all the armor points eventually :-)
Originally, I had thought I could make a new object type "armor" that derives from "wearable", but that seems to be stretching Quest a bit...

Silver
There's currently an error in its present state as I explained in the post above. If you ask to remove an item you're not wearing it prints an ugly game error instead of simply saying 'you're not wearing *object*'.

Silver
Grainger wrote:Hmmm... while I'm at it: is there a way to expand "wearables" to have special attributes, such as armor points or some such? I'd like to add up all the armor points eventually :-)
Originally, I had thought I could make a new object type "armor" that derives from "wearable", but that seems to be stretching Quest a bit...


This is already handled by adding attributes to objects. It isn't a massive leap to to add an If script for the object being worn or not to take effect. I'm not a coder so can't really help. There's already health and combat systems if you search about.

HegemonKhan
I would create your own library with modifications, unless chase himself wants to expand his~her library. The reason is that not everyone may want to use a library with whatever such modifications, as those modifications wouldn't be for their games, that's why a base~general functionality library is better, than a specialized'ly modified one for just a single person's game in mind.

you can have Object Types within Object Types, that's not a problem for quest, so long as you do it all correctly.

an uber simple example...

<type name="equipment_object_type">
// equip, unequip, etc functionality code lines
</type>

<type name="two_handed_object_type">
<attr name="equipment_slots" type="simplestringlist">left_hand;right_hand</attr>
</type>

<type name="sword_object_type">
<inherit name="equipment_object_type" />
<attr name="physical_damage" type="int">50</attr>
<attr name="attack_rating" type="int">25</attr>
</type>

<object name="claymore_sword_1">
<inherit name="sword_object_type" />
<inherit name="two_handed_object_type" />
<alias>claymore</alias>
</object>

Grainger
First of all, thanks for the super-quick feedback!
HegemonKhan wrote:... you can have Object Types within Object Types, that's not a problem for quest, so long as you do it all correctly. ...

an uber simple example...

I'll see what I can make out of this.

Grainger
Silver wrote:There's currently an error in its present state as I explained in the post above. If you ask to remove an item you're not wearing it prints an ugly game error instead of simply saying 'you're not wearing *object*'.


Hi Silver,
I'm not entirely sure (I didn't reproduce the problem before), but I believe the modification I've made to the library (replace player with game.pov in lines 85 and 143) has fixed that. At least, I get the flow below now. Note that I didn't wear boots. Is that what you meant?

It was actually much easier than I had thought. Beginners' luck I guess :wink:
Hope this helps,
Grainger


> take boots
You pick them up.

> remove boots
You can't remove them.

Silver
I discovered the error by making a mistake with my input when testing my game. So for example say I'm wearing a hat. But I'm thinking about the mirror I've just looked in. Instead of typing 'remove hat' I typed in 'remove mirror'. I expected the game to print 'you're not wearing it' or similar but it just printed an error saying player wasn't the parent of object mirror or similar. So your example may not reproduce the problem (I haven't tried it yet, but I will) because the player IS the parent even though the object isn't being worn.

Grainger
Silver wrote:... So your example may not reproduce the problem (I haven't tried it yet, but I will) because the player IS the parent even though the object isn't being worn. ...


I don't know why, but it seems to work anyways:

> drop boots
You drop them.

> remove boots
You can't remove them.

That's more or less what I'd expect.
Not sure it's my fix or just a different version of the library.

Silver
I'll give it a try today.

Silver
Can this be edited in game or do I have to edit the wearables.aslx and then import it in again? I'm worried it'll mess with work previously done with it.

The Pixie
I would edit the wearables.aslx file. it will not need to be imported again (assuming you edit a copy that is already in your game folder). If your player is the player object it should be fine (game.pov was introduced to allow the player to change to other objects).

Do a search for "player", and change every occurrence to "game.pov" (no quotes).

Try it and see what happens,

Silver
Okay, some major confusion going on here. I haven't got the wearables.aslx in my game folder... but the elements from it are still there such as being able to make an object wearable. I've downloaded the wearables.aslx file from the opening post anyway but the game won't open it, stating Failed to load game due to the following errors: * File must begin with an ASL element.

So am I getting the problem because the file isn't in my game directory? If not I don't appear to be able to open the file to edit it but another bizarre thing is I can open the other file - wearablestest.aslx which I'm sure was the one I had problems with initially. Agghhh.

The Pixie
It is a library file, so you cannot open it witrh Quest. Use a text editor like Notepad. The wearablestest.aslx file is a game, not a library, so can be opened with Quest.

As to where the library file is...

To incorporate a library in your game, expand advanced at the bottom on the left, go to libraries, click Add and navigate to the library file. Quest will add a line to your game code to include the library (see below, it will be one of the first few lines), and will also copy the file to your game's folder.
<include ref="wearables.aslx" />

An alternative is to type the line into the code yourself (perhaps as below), and if you do that you can include the path to the folder the library is in.
<include ref="..\lib\wearables.aslx" />

A further alternative is to copy all the code across from wearables.aslx to your game. In that case the functions will be in the game code. I am guessing you wold remember doing that though.

Silver
Oh, ok, I'll try all that.

Silver
Ok tried that and it hasn't fixed anything.

Grainger wrote:

I don't know why, but it seems to work anyways:

> drop boots
You drop them.

> remove boots
You can't remove them.

That's more or less what I'd expect.
Not sure it's my fix or just a different version of the library.


But have you made the boots a wearable object? If that's the case that's not what I'm talking about. I'm talking about the player trying to remove something that they are neither carrying and isn't wearable. In fact they can't even pick it up. But they may try to 'remove' it in a different sense. But instead of the game saying "You're not wearing it" or similar, it says:

Error running script: Error compiling expression 'not object.parent = game.pov or not object.worn or not object.removeable': NotElement: Operation not defined for type 'Object'

Which is a bug. I'm now thinking it might just be easier to set it up using commands as it's not imperative that the wearables library handles this in my game. I just happened to be testing it out when I started writing this so kept it in.

Silver
Unless I've done it wrong of course. I just changed the code and dragged the file into my game directory.I haven't physically imported it into the game again.

Grainger
Silver wrote:Ok tried that and it hasn't fixed anything.
... I'm talking about the player trying to remove something that they are neither carrying and isn't wearable. In fact they can't even pick it up. But they may try to 'remove' it in a different sense. But instead of the game saying "You're not wearing it" or similar, it says:

Error running script: Error compiling expression 'not object.parent = game.pov or not object.worn or not object.removeable': NotElement: Operation not defined for type 'Object'

Which is a bug. I'm now thinking it might just be easier to set it up using commands as it's not imperative that the wearables library handles this in my game. I just happened to be testing it out when I started writing this so kept it in.


OK, now I understand. Sorry for causing you so much effort. By changing the file location, you may have to import the library again, but with all I understand about Quest scripting, my suggestiosn won't fix that behaviour.

Silver
Right, I've got some serious fixing to be done. Anyone know how I remove a library from the game? Please say it can be done! It's not simply a case of removing the library from the directory as the code still persists. I could search for the code I guess. Will it exist as one convenient block in the game code?

Grainger
Silver wrote:Anyone know how I remove a library from the game? Please say it can be done!


In Quest 5.5.1, I see two ways:
1) Open Objects -> Advanced -> Included Libraries.
It looks like the "objects" tab of a room: A pane with a few buttons on top and a list of all included libraries inside. Select the library you want to remove and click the "Delete"-button above the pane.

2) Close Quest, open the aslx file of the game in a text editor like notepad. What you see should start a bit like:

<!--Saved by Quest 5.5.5328.26617-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<include ref="wearables.aslx" />
<include ref="LiftLib5-4.aslx" />
<game name="...">

Remove the line corresponding to the library you want to remove, re-open the file in Quest and continue as you always did.

Admittedly, I haven't tried either.

Silver
This was answered on the other thread I started, but cheers for the response! Would be great if someone could fix this. I've altered my game to not need it now but I did have a puzzle planned around it in mind for a game that's on the back burner at the moment.

The Pixie
I had a look at the Wearables library. The problem is in the first line of the DoRemove function, which assumes two attributes exist. If you change it to this, it should work properly:

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


Or download this file:


Silver
I've had a reply from the author who said although he's busy he'll take a look. Cheers for looking into it. I'll give it a try at some point today.

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

for some reason I'm getting this error --- only in the starting area. I checked all the attributes of the items and the worn is all "false" so I don't know what the hell to do with this ...

Anonynn
So I have another question.

I'm not sure how to go about writing this but if the player doesn't meet certain parameters of wearing a piece of clothing. How would I write that? Let's say they are too overweight....I have this, for example.

if (player.weight>="obese" ) {
msg ("<br/>You simply cannot fit into this at the moment.<br/>")
}

What would I put for let's say if the player was wearing the piece of clothing or attempted to?

Remove "worn" status...and just have them keep it in their inventory.

The Pixie
You need to compare numbers not strings, as you have a greater than in there, so:

if (player.weight_as_int >= 10) {

What I would do is change the command in the library to check for size, and have two new attributes on each garment, one naming the attribute, "weight" in this case, the other the maximum value, 10. It might go like this:

handled = false
if (HasString(garment, "size_attribute") and HasInt(garment, "size_value")) {
if (GetInt(player, garment.size_attribute + "_as_int") >= garment.size_value) {
msg ("<br/>You simply cannot fit into this at the moment.<br/>")
handled = true
}
}
if (not handled) {
msg("You put it on")
garment.worn = true
}

I have not looked in the wearables library, you will need to adapt that code to fit the existing code (for example, changing garment to whatever it is called in the library).

You will also need to check the effect on clothing when the player changes size...

Anonynn

You need to compare numbers not strings, as you have a greater than in there, so:

if (player.weight_as_int >= 10) {

What I would do is change the command in the library to check for size, and have two new attributes on each garment, one naming the attribute, "weight" in this case, the other the maximum value, 10. It might go like this:

handled = false
if (HasString(garment, "size_attribute") and HasInt(garment, "size_value")) {
if (GetInt(player, garment.size_attribute + "_as_int") >= garment.size_value) {
msg ("<br/>You simply cannot fit into this at the moment.<br/>")
handled = true
}
}
if (not handled) {
msg("You put it on")
garment.worn = true
}

I have not looked in the wearables library, you will need to adapt that code to fit the existing code (for example, changing garment to whatever it is called in the library).

You will also need to check the effect on clothing when the player changes size...



I wonder if there is a more simple way.

Like...

if (player.weight_as_int >= 10) {
remove garment
msg ("<br/>You a are too big for this right now!<br/>")
add to inventory (I'm not sure if "remove" would remove it from the inventory)
}

What do you think of that? Because the chase library has a section "wearables tab" and a script section for after wearing, and after removing. So it should be easy enough to just force the player to "take off" that article of clothing if he/she doesn't meet the parameters, right?

Anonynn
Any ideas on this? Or am I completely wrong x)


Also, it seems that you can wear items from the same wear slots and that shouldn't be able to happen!

HegemonKhan
the 'player's inventory' is an Objectlist Attribute called 'inventory':

(as code scripting, it looks like this, I think):

player.inventory = split ("object1, object2, etc", ";")

and I think it's hidden (not shown, as it's dealt with by the engine's code, internally) in the GUI~Editor, but it should be something like this:

<object name="player">
<attr name="inventory" type="simpleobjectlist">object1;object2;object3</attr>
// or (if I remember the vertical format~syntax correctly, lol):
<attr name="inventory" type="objectlist">
<value>object1</value>
<value>object2</value>
<value>etc etc</value>
</attr>
</object>


to add~remove items from a list~dictionary:

http://docs.textadventures.co.uk/quest/ ... t_add.html
http://docs.textadventures.co.uk/quest/ ... emove.html
http://docs.textadventures.co.uk/quest/ ... y_add.html
http://docs.textadventures.co.uk/quest/ ... emove.html

so, for your inventory (various actions~scripts you can do):

list add (player.inventory, fists)
list remove (player.inventory, fists)
list add (player.inventory, knife)
list remove (player.inventory, knife)
list add (player.inventory, machete)
list remove (player.inventory, machete)
list add (player.inventory, fire_spellbook)
list remove (player.inventory, fire_spellbook)
list add (player.inventory, shirt)
list remove (player.inventory, shirt)

and whatever you other items~equipment, and all other game items in your game (as this is your inventory, what objects are held inside of the 'player' Player Object), I forgot their names, rickety_machete, and a knife?

errr...

actually I think it's ScopeInventory()...

http://docs.textadventures.co.uk/quest/ ... ntory.html

so just replace the 'player.inventory' with 'ScopeInventory()', see below:

list add (ScopeInventory(), fists)
list remove (ScopeInventory(), fists)
list add (ScopeInventory(), knife)
list remove (ScopeInventory(), knife)
list add (ScopeInventory(), machete)
list remove (ScopeInventory(), machete)
list add (ScopeInventory(), fire_spellbook)
list remove (ScopeInventory(), fire_spellbook)
list add (ScopeInventory(), shirt)
list remove (ScopeInventory(), shirt)

Anonynn
So, for example...

list add (ScopeInventory(), fists)
list remove (ScopeInventory(), fists)
list add (ScopeInventory(), knife)
list remove (ScopeInventory(), knife)
list add (ScopeInventory(), machete)
list remove (ScopeInventory(), machete)
list add (ScopeInventory(), fire_spellbook)
list remove (ScopeInventory(), fire_spellbook)
list add (ScopeInventory(), shirt)
list remove (ScopeInventory(), shirt)



if (player.weight>="obese") {
List remove (ScopeInventory(), plain_black_shirt)
msg ("You're too big to wear this!")
}
// And that will remove the "worn" status?

The Pixie
HegemonKhan wrote:the 'player's inventory' is an Objectlist Attribute called 'inventory':

(as code scripting, it looks like this, I think):

player.inventory = split ("object1, object2, etc", ";") ...

Doing that would make player.inventory a string list, and as you are splitting on a semi-colon, it would have one long string!

I do not think there is an inventory attribute at all. Item in the inventory are all those where the "parent" attribute is equal to player.


To move an item to the inventory:
object1.parent = player

To check if an item is in the inventory:
if (object1.parent = player) {

To list items in the inventory:
objectlist = GetDirectChildren(player)

HegemonKhan
I corrected it further down my post, as seen here a copy of it:

errr...

actually I think it's ScopeInventory()...

http://docs.textadventures.co.uk/quest/ ... ntory.html

so just replace the 'player.inventory' with 'ScopeInventory()', see below:

list add (ScopeInventory(), fists)
list remove (ScopeInventory(), fists)
list add (ScopeInventory(), knife)
list remove (ScopeInventory(), knife)
list add (ScopeInventory(), machete)
list remove (ScopeInventory(), machete)
list add (ScopeInventory(), fire_spellbook)
list remove (ScopeInventory(), fire_spellbook)
list add (ScopeInventory(), shirt)
list remove (ScopeInventory(), shirt)

----------

though I didn't inform neonayon specifically~explicitly that this also means that my 'player.inventory' was wrong, that it doesn't work.

---------

@ neonayon:

you're using a capitol L in your: List add~remove(list_name, item_name)

I think it must be a lowercase L (I could be wrong though): list add~remove(list_name, item_name)

Anonynn
Alright, so I tried...and the first few times had a couple of errors, but I fixed them all and finished with this code.

if (player.weight_as_int>=1) {
list remove (ScopeInventory(), plain_black_shirt)
msg ("You're too big to wear this!")
plain_black_shirt.worn = false
}



But in game it doesn't remove the "worn status" but hilariously does this instead!

> wear Plain Black Shirt (worn) (worn)
You put it on.
You're too big to wear this!

> wear Plain Black Shirt (worn) (worn) (worn)
You put it on.
You're too big to wear this!

> wear Plain Black Shirt (worn) (worn) (worn) (worn)
You put it on.
You're too big to wear this!

> wear Plain Black Shirt (worn) (worn) (worn) (worn) (worn)
You put it on.
You're too big to wear this!

Ideally, if the player doesn't meet a parameter of "weight" for example, I just want the game to auto-remove the clothing.

Anonynn
Does that make sense?

Anonynn
bumperz :)

The Pixie
The problem with the code is that it is testing for size too late. You need the alias update and the putting-on message inside the if block.

Anonynn
So I fixed one problem...multiple pieces of the same clothing being able to be worn. That is no longer an issue!

But I'm still having issues with the parameters.

The problem with the code is that it is testing for size too late. You need the alias update and the putting-on message inside the if block.



The problem is on the "Wearables Library" is that the only place I can put code is in the "Wearables Tab", in the "After Wearing" space, because you can change it to a script. The script I have now is...

if (player.weight_as_int>=1) {
list remove (ScopeInventory(), plain_black_shirt)
plain_black_shirt.worn = false
msg ("You're too big to wear this!")
}



So if this has to be put in "Before Worn" space, I'm not sure where that would be. Any suggestions? :D

sez
Nice. I've put it into my game. Should work well with things like rings and lockets too.

Anonynn
Any suggestions :D?

Anonynn
So I fixed one problem...multiple pieces of the same clothing being able to be worn. That is no longer an issue!

But I'm still having issues with the parameters.

The problem with the code is that it is testing for size too late. You need the alias update and the putting-on message inside the if block.



The problem is on the "Wearables Library" is that the only place I can put code is in the "Wearables Tab", in the "After Wearing" space, because you can change it to a script. The script I have now is...

if (player.weight_as_int>=1) {
list remove (ScopeInventory(), plain_black_shirt)
plain_black_shirt.worn = false
msg ("You're too big to wear this!")
}



So if this has to be put in "Before Worn" space, I'm not sure where that would be. Any suggestions? :D


UPDATE:

So aside from this problem, there is another with the player being able to click "wear" and then the word (worn) appearing next to the item as many times as it is clicked. For example...

Plain Black Shirt (worn) (worn) (worn) (worn) (worn)

The Pixie
I guess the problem is that the item is not actually getting its "worn" attribute set to true because something is failing between changing the alias and setting the flag. You may have to look inside the library file to find where that is. There is probable a "wear" script in there you can search for, or maybe a line like this:
this.alias = this.alias + " (worn)"

Anonynn

I guess the problem is that the item is not actually getting its "worn" attribute set to true because something is failing between changing the alias and setting the flag. You may have to look inside the library file to find where that is. There is probable a "wear" script in there you can search for, or maybe a line like this:
this.alias = this.alias + " (worn)"



I figured out the problem. It was just happening on one item. The plain black shirt because of:

if (player.weight_as_int>=1) {
list remove (ScopeInventory(), plain_black_shirt)
plain_black_shirt.worn = false
msg ("You're too big to wear this!")
}

coding still on there. So I still have just the one problem xD

The problem with the code is that it is testing for size too late. You need the alias update and the putting-on message inside the if block.



The problem is on the "Wearables Library" is that the only place I can put code is in the "Wearables Tab", in the "After Wearing" space, because you can change it to a script. The script I have now is...

if (player.weight_as_int>=1) {
list remove (ScopeInventory(), plain_black_shirt)
plain_black_shirt.worn = false
msg ("You're too big to wear this!")
}



So if this has to be put in "Before Worn" space, I'm not sure where that would be. Any suggestions? :D


The Pixie
The easiest way (though probably not the best) would be to add a line that removes the " (worn)" bit.

if (player.weight_as_int>=1) {
list remove (ScopeInventory(), plain_black_shirt)
plain_black_shirt.worn = false
msg ("You're too big to wear this!")
plain_black_shirt.alias = Replace(plain_black_shirt.alias, " (worn)", "")
}

I am assuming it does have an alias, but I guess the Wearables library requires that?

Anonynn
So that worked to remove the word "worn"

but:

if (player.weight_as_int>=1) {
list remove (ScopeInventory(), plain_black_shirt)
plain_black_shirt.worn = false
msg ("You're too big to wear this!")
plain_black_shirt.alias = Replace(plain_black_shirt.alias, " (worn)", "")
}

doesn't allow you to remove the item, and then be able to drop it. So it can't be dropped or removed now! Almost there. I think it's because we have this...

{if plain_black_shirt.worn:You can't drop it.{once: You have to "<i>Remove</i>" it before you can drop it.}} {if plain_black_shirt.worn:You carelessly toss the black shirt away.}

on the "drop verb"

HegemonKhan
in general (this won't really help, as I'd need to look at Chase's programming, to adapt this conceptual design to it ~~~ actually, this is generally chase's design, but obviously somthing got messed up at some point as you're trying to use Chase's library in your game), you need this design:

Wear:

if (able to wear and NOT already wearing) { // if you don' have the 'NOT already wearing', then you'll get the: hat (worn) (worn) (worn) ...
-> hat.worn = true
-> hat.old_alias = hat.alias // hat.old_alias <==== hat.alias <==== hat // if you don't do this, then you'll get the: hat (worn) (worn) (worn) ...
-> hat.alias = GetDisplayAlias (hat) + " (worn)"
// output in inventory: hat (worn)
} else if (ALREADY wearing) {
-> msg ("You're already wearing it, silly!")
} else {
-> msg ("You can't wear that!")
}

Remove:

if (able to remove):
-> hat.worn = false
-> hat.alias = hat.old_alias // if you don't do this, then you'll get the: hat (worn) (worn) (worn) ...
// output in inventory: hat

HegemonKhan
@ Pixie:

here's Chase's Wearables Library (from the first page, first post, of this very thread, lol):

<library>
<!--
Chase's Wearables Library v2.3
Based on: Pixie's Clothing Library (originally)

You may edit this library however you please.

I decided to include a UI, since not having a UI kinda bugged me.

v1.01
-Fixed a typo

v1.02
+Added Event Handlers
+Fixed drop bug

v1.03
+Added configurable wear/remove messages
-Removed redundant events

v1.04
=Fixed an issue with wearing multiple blank items
=Fixed the issue with wearing items without aliases

v2.0
=Rewritten to better support base systems, may have broken older usages
+Added wear layer support

v2.1
=Fixed an issue of an error being thrown when trying to wear something that is not wearable.

v2.2
=Fixed an issue where the custom remove message doesn't play if the item cannot be removed.

v2.3
=Fixed a significant bug where you could not wear something if a non-wearable item was in your inventory.

Chase
chasesan@gmail.com
-->

<dynamictemplate name="WearSuccessful">"You put " + object.article + " on."</dynamictemplate>
<dynamictemplate name="WearUnsuccessful">"You can't wear " + object.article + "."</dynamictemplate>
<dynamictemplate name="AlreadyWearing">"You are already wearing " + object.article + "."</dynamictemplate>
<dynamictemplate name="CannotWearOver">"You cannot wear that over " + object.display + "."</dynamictemplate>
<dynamictemplate name="CannotWearWith">"You cannot wear that while wearing " + object.display + "."</dynamictemplate>

<dynamictemplate name="RemoveSuccessful">"You take " + object.article + " off."</dynamictemplate>
<dynamictemplate name="RemoveUnsuccessful">"You can't remove " + object.article + "."</dynamictemplate>
<dynamictemplate name="RemoveFirst">"You can't remove that while wearing "+object.display+"."</dynamictemplate>

<template name="Wear">Wear</template>
<verbtemplate name="wear">wear</verbtemplate>
<verbtemplate name="wear">put on</verbtemplate>

<template name="Remove">Remove</template>
<verbtemplate name="remove">remove</verbtemplate>
<verbtemplate name="remove">take off</verbtemplate>

<command name="wear" template="wear">
<multiple>
return (ScopeInventory())
</multiple>
<script>
foreach (obj, object) {
DoWear(obj)
}
</script>
</command>

<command name="remove" template="remove">
<multiple>
return (ScopeInventory())
</multiple>
<script>
foreach (obj, object) {
DoRemove(obj)
}
</script>
</command>

<function name="DoWear" parameters="object"><![CDATA[
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(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))
}

}
]]></function>

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

<type name="wearable">
<worn type="boolean">false</worn>
<removeable type="boolean">true</removeable>
<wear_layer type="int">2</wear_layer>
<inventoryverbs type="listextend">[Wear];[Remove]</inventoryverbs>
</type>
<!-- Interface -->
<tab>
<parent>_ObjectEditor</parent>
<caption>Wearable</caption>
<mustnotinherit>editor_room; defaultplayer</mustnotinherit>

<control>
<controltype>title</controltype>
<caption>Wearable</caption>
</control>

<control>
<controltype>dropdowntypes</controltype>
<caption>Can be worn?</caption>
<types>*=Cannot be worn; wearable=Can be worn</types>
<width>150</width>
</control>

<control>
<mustinherit>wearable</mustinherit>
<controltype>checkbox</controltype>
<attribute>removeable</attribute>
<caption>Removeable?</caption>
</control>

<control>
<mustinherit>wearable</mustinherit>
<controltype>number</controltype>
<caption>Wear Layer</caption>
<attribute>wear_layer</attribute>
</control>

<control>
<mustinherit>wearable</mustinherit>
<caption>Wear Slot</caption>
<controltype>list</controltype>
<attribute>wear_slots</attribute>
<editprompt>Please enter the name for the wear location</editprompt>
</control>

<control>
<mustinherit>wearable</mustinherit>
<controltype>label</controltype>
<caption>If two objects have the same wear location, they will not be able to be worn at a same time. Any number items without wear locations can be worn.</caption>
<advanced/>
</control>

<!-- snip -->

<control>
<mustinherit>wearable</mustinherit>
<controltype>textbox</controltype>
<attribute>wearmsg</attribute>
<caption>Message to print when wearing (leave blank for default)</caption>
<nullable/>
</control>

<control>
<mustinherit>wearable</mustinherit>
<controltype>textbox</controltype>
<attribute>removemsg</attribute>
<caption>Message to print when removing or trying to remove (leave blank for default)</caption>
<nullable/>
</control>

<!-- Event Handlers from here down none/text/scripts -->

<control>
<mustinherit>wearable</mustinherit>
<controltype>title</controltype>
<caption>After Wearing</caption>
</control>

<control>
<mustinherit>wearable</mustinherit>
<selfcaption>After wearing the object</selfcaption>
<controltype>multi</controltype>
<attribute>onafterwear</attribute>
<types>null=None; string=Text; script=Run script</types>
<editors>string=textbox</editors>
<expand/>
</control>

<control>
<mustinherit>wearable</mustinherit>
<controltype>title</controltype>
<caption>After Removing</caption>
</control>

<control>
<mustinherit>wearable</mustinherit>
<selfcaption>After removing the object</selfcaption>
<controltype>multi</controltype>
<attribute>onafterremove</attribute>
<types>null=None; string=Text; script=Run script</types>
<editors>string=textbox</editors>
<expand/>
</control>

</tab>
</library>


you should be able to pretty quickly get it, as Chase has most of the meat of the code quite concisely within two Verbs~Commands: ~ "DoWear" and "DoRemove", whereas (it took me a long time to somewhat get it way back when I was trying to study this anyways, laughs). The important parts in regards to the 'hat (worn) (worn) (worn) (worn)' problem that neonayon has, is near the bottom of these two Functions, see below:

'DoWear' Function:

			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))
}


'DoRemove' Function:

			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))
}


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

the bigger problem is between neonayon's usage of it, in figuring out what's going wrong for her in trying to use it for her game, and~or possibly her using any of my erroneous code that has messed up her game even worse from working as it should with Chase's Library, my apologies neonayon and Pixie for any code trouble I've caused with neonayon trying to get this fixed up.

Anonynn

the bigger problem is between neonayon's usage of it, in figuring out what's going wrong for her in trying to use it for her game, and~or possibly her using any of my erroneous code that has messed up her game even worse from working as it should with Chase's Library, my apologies neonayon and Pixie for any code trouble I've caused with neonayon trying to get this fixed up.



Actually, I'm not using the code any differently :) Least I don't think so. I know I brought up a situation a while back where Chase's Library needed fixin' 'cause he/she left a small bug in the mix that let people drop clothes they were wearing or something like that. But that's been resolved. All I need is to figure out how to create an 'argument' ^_~ in the script that let's the game know to remove clothes if the player meets a certain criteria. Sort of like an auto-remove if script.

And HK some of what you suggested made it into the script, Pix and I are working on (like 95% Pix)!

if (player.weight_as_int>=1) {
list remove (ScopeInventory(), plain_black_shirt)
plain_black_shirt.worn = false
msg ("You're too big to wear this!")
plain_black_shirt.alias = Replace(plain_black_shirt.alias, " (worn)", "")
}

doesn't allow you to remove the item, and then be able to drop it. So it can't be dropped or removed now! Almost there. I think it's because we have this...

{if plain_black_shirt.worn:You can't drop it.{once: You have to "<i>Remove</i>" it before you can drop it.}} {if plain_black_shirt.worn:You carelessly toss the black shirt away.}

on the "drop verb"



this is the only problem now, and you're the one that suggested the Scope Inventory thing and the list remove. I think that code there has a little bit of you, Pix and me in it lol.

The Pixie
I suggest a new approach. It is not a simple system, but is probably the simplest you will find.

In the wearables library file, look for this:
  <function name="DoWear" parameters="object"><![CDATA[
if(not HasAttribute(object,"worn")) {
msg (DynamicTemplate("WearUnsuccessful", object))

Replace it with this, which will check if the garment is of a suitable size:
  <function name="DoWear" parameters="object"><![CDATA[
player.toobigforitem = false
if (HasScript(object, "testplayersize")) {
do(object, "testplayersize")
}
if (player.toobigforitem) {
if (HasString(object, "toobigtowearmsg")) {
msg (object.toobigtowearmsg)
}
else {
msg("You try to put on the " + GetDisplayName(object) + " but it just won't fit!")
}
} else if(not HasAttribute(object,"worn")) {
msg (DynamicTemplate("WearUnsuccessful", object))

Also add this new function:
	<function name="SizeCheck"><![CDATA[
foreach (object, ScopeInventory()) {
if (HasScript(object, "testplayersize")) {
player.toobigforitem = false
do (object, "testplayersize")
if (player.toobigforitem) {
if (HasString(object, "grewtoobigmsg")) {
msg (object.grewtoobigmsg)
}
else {
msg ("The " + Replace(object.alias, " (worn)", "") + " you are wearing is too small for you! It rips to shreds.")
}
destroy (object.name)
}
}
}
]]></function>

Now for any garment you want to check the size of, add a script called "testplayersize", and in that script, set player.toobigforitem to true if the player is too fat or whatever. So a script might look like this:
if (player.buttsize_as_int > 5) {
player.toobigforitem = true
}

The thing about adding a script to each garment is that you can choose whether it is the buttsize or the bustsize or whether having a tail or wings or anything at all. Here is an example of checkng three things:
if (player.buttsize_as_int > 5) {
player.toobigforitem = true
}
if (player.bustsize_as_int > 9) {
player.toobigforitem = true
}
if (player.has_a_tail) {
player.toobigforitem = true
}

For each garment you can add a string attribute called "grewtoobigmsg" to describe the player growing to be too big for the garment and "toobigtowearmsg" for when the player tries to put it on but is too big for it, but there are defaults, so it is optional.#

Lastly, when the player grows bigger or gets a tail or whatever, called the SizeCheck function.

HegemonKhan
@neonayon:

if I ever get back to being able to work on quest, I'm going to be needing your help for making my own RPG game, as a lot of this stuff that you're trying to get developed, I'll need it for my game, laughs. Keep up the progress Neonayon, and thanks for helping her, Pixie, as it helps everyone too, hehe!

Anonynn
Not a problem HK! I'll do my best to help you out however I can, it's the least that I owe to everyone here on the forums! I wish I could help Pixie out too with something but I'm too dumb at the moment. Maybe one day!

As for the thing, Pix! I'll give it a shot and see how it works. Thank you so much!!

foreach (object, ScopeInventory()) {
if (HasScript(object, "testplayersize")) {
player.toobigforitem = false
do (object, "testplayersize")
if (player.toobigforitem) {
if (HasString(object, "grewtoobigmsg")) {
msg (object.grewtoobigmsg)
}
else {
msg ("The " + Replace(object.alias, " (worn)", "") + " you are wearing is too small for you! It rips to shreds.")
}
destroy (object.name)
}
}
}



You were missing a } underneath this line <i>do (object, "testplayersize")</i> In case anyone else wanted to use this! ^_^

But other than that, the entire script seems to be running. I just need to test it!

It becomes this.

foreach (object, ScopeInventory()) {
if (HasScript(object, "testplayersize")) {
player.toobigforitem = false
do (object, "testplayersize")
}
if (player.toobigforitem) {
if (HasString(object, "grewtoobigmsg")) {
msg (object.grewtoobigmsg)
}
else {
msg ("The " + Replace(object.alias, " (worn)", "") + " you are wearing is too small for you! It rips to shreds.")
}
destroy (object.name)
}
}

Anonynn
A couple problems are happening...

Now for any garment you want to check the size of, add a script called "testplayersize", and in that script, set player.toobigforitem to true if the player is too fat or whatever. So a script might look like this:

if (player.buttsize_as_int > 5) {
player.toobigforitem
}



Maybe I wasn't sure what you said but I went to the attribute of the plain_black_shirt, made testplayersize and then made it a script...

if (player.buttsize_as_int > 1) {
player.toobigforitem
}

but this error happened.

Error running script: Function not found: 'player.toobigforitem'

Here is the Function "SizeCheck"

foreach (object, ScopeInventory()) {
if (HasScript(object, "testplayersize")) {
player.toobigforitem = false
do (object, "testplayersize")
}
if (player.toobigforitem) {
if (HasString(object, "grewtoobigmsg")) {
msg (object.grewtoobigmsg)
}
else {
msg ("The " + Replace(object.alias, " (worn)", "") + " you are wearing is too small for you! It rips to shreds.")
}
destroy (object.name)
}
}


Not sure if it helps but here is the "DoWear" code after the new code was put into place.

player.toobigforitem = false
if (HasScript(object, "testplayersize")) {
do (object, "testplayersize")
}
if (player.toobigforitem) {
if (HasString(object, "toobigtowearmsg")) {
msg (object.toobigtowearmsg)
}
else if ("You try to put on the " + GetDisplayName(object) + " but it just won't fit!") {
}
}
else if (not HasAttribute(object,"worn")) {
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

The Pixie
Neonayon wrote:A couple problems are happening...

Now for any garment you want to check the size of, add a script called "testplayersize", and in that script, set player.toobigforitem to true if the player is too fat or whatever. So a script might look like this:

if (player.buttsize_as_int > 5) {
player.toobigforitem
}



Maybe I wasn't sure what you said but I went to the attribute of the plain_black_shirt, made testplayersize and then made it a script...

if (player.buttsize_as_int > 1) {
player.toobigforitem
}

but this error happened.

Error running script: Function not found: 'player.toobigforitem'


My mistake. It should be this:

if (player.buttsize_as_int > 1) {
player.toobigforitem = true
}

You said a couple of errors; was there something else?

I will edit my post with these corrections.

The Pixie
Neonayon wrote:

foreach (object, ScopeInventory()) {
if (HasScript(object, "testplayersize")) {
player.toobigforitem = false
do (object, "testplayersize")
if (player.toobigforitem) {
if (HasString(object, "grewtoobigmsg")) {
msg (object.grewtoobigmsg)
}
else {
msg ("The " + Replace(object.alias, " (worn)", "") + " you are wearing is too small for you! It rips to shreds.")
}
destroy (object.name)
}
}
}



You were missing a } underneath this line <i>do (object, "testplayersize")</i> In case anyone else wanted to use this! ^_^

But other than that, the entire script seems to be running. I just need to test it!

It becomes this.

foreach (object, ScopeInventory()) {
if (HasScript(object, "testplayersize")) {
player.toobigforitem = false
do (object, "testplayersize")
}
if (player.toobigforitem) {
if (HasString(object, "grewtoobigmsg")) {
msg (object.grewtoobigmsg)
}
else {
msg ("The " + Replace(object.alias, " (worn)", "") + " you are wearing is too small for you! It rips to shreds.")
}
destroy (object.name)
}
}


I am going to disagree with this one. The two functions I tested fairly well before posting, and they worked okay. The way you have arranged it, if the current item has no script, but the previous item i the list was too small, the current one will be treated as being too small too.

Anonynn

I am going to disagree with this one. The two functions I tested fairly well before posting, and they worked okay. The way you have arranged it, if the current item has no script, but the previous item i the list was too small, the current one will be treated as being too small too.



Aww, I thought I caught a mistake and was useful! I should have known! You're right though, the code works perfectly.

You said a couple of errors; was there something else?



So far so good! The errors were happening on the other version of the game that I had sent with that Quest haywire email. But since I redid it everything is working like a charm (as far as I know, I haven't fully tested anything yet). Thank you so much, Pixie. Hopefully, if this ever comes up again it'll help those other people too!

Anonynn
So I have a question.

I have a shirt item that is a wear slot 3 (torso)

and an outfit that is a wear slot 11 (torso, legs, feet, head).

This is stated. "If two objects have the same wear location, they will be able to be worn at the same time. Any number items without wear location can be worn."

But I think there is a loop-hole here. The wear slot 3 works between two shirts and doesn't allow you to wear them both, and wear slot four between two pants works the same --- they all do actually, but when the outfit is involved...I think because the other "wear slots" are empty (legs, shoes, and head), it allows the item to be worn. Anyway to fix this? I want that if ANY of the wear slots is occupied, that the outfits cannot be worn.

Pykrete
So I've run into a pretty massive problem here; as part of my current project, you can switch characters, and are expected to do so often. I'd figured that the wearables library would just adapt to this, but unfortunately it will only work correctly if your player object is the initial 'player'. As it is now, I can equip clothing on the other characters, but if I try to remove said clothing it will activate the verb but then print nothing... no error message, nada, zip. This leaves characters with clothes just stuck to them, and multiple clothing sets (it's an RPG) is something pretty integral to the game.

So, does anyone have any idea how to go about modifying the library to support multiple player characters? After opening it up, i'm seeing a lot of lines that reference the object.parent = player as a requirement... wondering if removing those lines or perhaps modifying them from player to game.pov instead might fix the issue.

But ultimately, i'm out of my depth here. If anyone else knows where to begin with this, that'd be great.

EdIt: My gosh, that feels like dodging a bullet! Fingers crossed and knock on wood, but I seem to have fixed it by doing just that. In DoRemove, in the first line (if (not object.parent = player or not object.worn or not object.removeable)), I have replaced player with game.pov. It now looks like this -
if (not object.parent = game.pov or not object.worn or not object.removeable)

This has immediately fixed my issue, and now all different playable characters are able to equip and remove clothing and gear as needed. Quite the relief, let me tell you! I will update further if this causes any side effects, though I can't see why it would. You may wish to update the library with this change, unless I've missed something and this is causing serious side effects.

Anonynn
Yeah! Good job!!

When you have something locked to the "player" then game will only recognize things connected to THAT object. But switching it to "game" as you did allows multiple objects to be considered. It works the same way with equipping and unequipping items :)

HegemonKhan
@ Pykrete:

http://blog.textadventures.co.uk/2012/0 ... quest-5-3/
^^^^^
http://blog.textadventures.co.uk/2012/1 ... available/ (scroll way down to find the 'changeable pov' info)
^^^^^^
http://docs.textadventures.co.uk/quest/ ... notes.html
^^^^^^^
path

------

http://docs.textadventures.co.uk/quest/ ... bject.html (about changing the pov)
http://docs.textadventures.co.uk/quest/ ... gepov.html
http://docs.textadventures.co.uk/quest/ ... bject.html (scroll down to the 'pov_X' Attributes)

-----

the 'game' Game Object's special 'pov' Object Attribute (the Attribute's value is the Object that you want to currently control) references the Object (whichever/whoever) that you're currently controlling.

-----

this is good and bad. If you use 'player.Attribute_name', this references just the default 'player' Player Object. However, say you created these additional Player Objects, 'HK' and 'Pykrete', then you can use 'game.pov.Attribute_name' which will reference whichever of these 3 Player Objects, you're currently controlling. However, the caution is when you need to keep your Player Objects (such as their game stats/Attributes) separate. If you only want certain actions/scripts/changed_attributes, to occur with a specific Player Object, then you must reference THAT Player Object ( 'player.Attribute_name', or 'HK.Attribute_name', or 'Pykrete.Attribute_name' ), if you want, need, or don't mind, stuff happening to any of them, then use the 'pov' reference (game.pov.Attribute_name).

for examples:

let's say I want all of my Player Objects to use the same 'leveling' formula/equation (they all level up the same), thus I'd want to use 'game.pov', shown below

<function name="leveling_function">
if (game.pov.experience >= game.pov.level * 100 + 100) {
game.pov.experience = game.pov.experience - (game.pov.level * 100 + 100)
game.pov.level = game.pov.level + 1
leveling_function
}
</function>


the code above will work regardless of whether I'm controlling the 'player' Player Object, the 'HK' Player Object, or the 'Pykrete' Player Object.

however, if we were to use, say specifcally the 'player', then what will happen if you're controlling the 'Pykrete' Player Object when you get enough experience to level up?

<function name="leveling_function">
if (player.experience >= player.level * 100 + 100) {
player.experience = player.experience - (player.level * 100 + 100)
player.level = player.level + 1
leveling_function
}
</function>


Answer: 'Pykrete' Player Object will NOT have a level up... but your 'player' Player Object will have a level up instead...

----------

let's say we have a quest in the game, that involves giving an item to only a specific Player Object in order to be able to beat the game, well if you were to use 'game.pov' in that item giving script, then it would give that item to whichever Player Object you're controlling, which is what you do NOT want, as you won't be able to complete the game, if you're controlling the wrong character, when you fire off that item giving script.

---------

also, a big issue, that always happens, as it's not well documented nor made well-known, Player Objects have TWO locations for their 2 different 'look' descriptions. One 'look' description (I think under the 'setup' Tab) is for when that Player Object is NOT being controlled by you (acting like a npc) and it's other 'look' description (I believe under the 'Player' Tab) is for when it IS being controlled by you (you try looking at yourself). We have many new people who're baffled at why they don't see their 'look' description, because of this.

Pykrete
Thank you, but I think I have that all covered already. This problem really is one of the only things I'm using POV for, everything else is making a check to see which character is being used and then updating them and them only. It's a little long-winded, but it ensures that I'm in control.

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

Support

Forums