Thoughts on wearables
mrangel
25 Aug 2018, 22:19Just been looking at the wearables code, and it seems a bit clunky. It would be easy for a naive user to change the 'worn' flag directly, not realising that they need to use functions to ensure that any bonuses from a garment are applied correctly.
Wouldn't it be neater to have something like:
<function name="SetBonuses" parameters="garment, wearflag">
// This function provided for backwards compatibility
// in case any scripts call it manually. In most cases it will do nothing,
// but the existing wearables library advises users to call it, so it's better to replace it
// with a do-nothing function rather than break any libraries that call it
// Small piece of code so that this function will behave sanely if called for some reason on a non-garment
if (not DoesInherit (garment, "wearable")) {
if (HasString (garment, "bonusatts")) {
ApplyBonuses (game.pov, garment.bonusatts, not wearflag)
}
}
</function>
<function name="ApplyBonuses" parameters="character, bonuses, remove">
foreach (att, Split(bonuses, ";")) {
bonus = 1
plusarray = Split(att, "+")
minusarray = Split(att, "-")
if (ListCount(plusarray) = 2) {
att = StringListitem(plusarray, 0)
if (not IsInt(StringListitem(plusarray, 1))) error ("Bonus attribute not properly formatted: " + att)
bonus = ToInt(StringListitem(plusarray, 1))
}
if (ListCount(minusarray) = 2) {
att = StringListitem(minusarray, 0)
if (not IsInt(StringListitem(minusarray, 1))) error ("Negative bonus attribute not properly formatted: " + att)
bonus = -ToInt(StringListitem(minusarray, 1))
}
if (remove) {
bonus = -bonus
}
bonus = ClothingBonusMultiplier() * bonus
n = GetInt(character, att) + bonus
set (character, att, n)
}
</function>
<type name="wearable">
<changedworn type="script">
if (HasString (this, "bonusatts")) {
ApplyBonuses (this.parent, this.bonusatts, this.worn)
}
_SetGarmentAlias (this)
</changedworn>
<changedbonusatts type="script">
if (GetBoolean (this, "worn")) {
if (TypeOf (oldvalue) = "string") {
ApplyBonuses (this.parent, oldvalue, false)
}
if (TypeOf (this, "bonusatts") = "string") {
ApplyBonuses (this.parent, this.bonusatts, true)
}
}
</changedbonusatts>
<changedparent type="script">
if (GetBoolean (this, "worn") and HasString (this, "bonusatts")) {
if (TypeOf(oldvalue) = "object") {
ApplyBonuses (oldvalue, this.bonusatts, false)
}
if (TypeOf(this, "parent") = "object") {
ApplyBonuses (this.parent, this.bonusatts, true)
}
}
this.worn = false
</changedparent>
</type>
(this would make garments work more easily when worn by NPCs. Wearing / removing / multistate changes would work elegantly; as would any other script that changes a garment's bonuses while the player is wearing it. The only thing that wouldn't be accounted for is a script calling destroy()
on a garment, which I think we can't check for.)
mrangel
26 Aug 2018, 19:25(Also, I think a lot of the functionality from WearGarment
and RemoveGarment
could be moved into the changedworn
script; which guards against a naïve user changing the worn
attribute rather than calling the functions. Not sure if that's essential, though)
ahmed11
27 Aug 2018, 09:13Great