Thoughts on wearables

Just 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.)


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


Great


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

Support

Forums