May 22 – Omni update

Today I mostly cleaned up some bugs and fixed some technical debt ahead of my next short project.  Kyren and I have been cleaning up the Item interfaces and streamlining and defining a better, smaller internal API to deal with Items.  Today, I removed explicit functions for fuel and removed the critical item flag (which was kind of a hack and we’ve solved the problem of losing your pickaxe).  I moved direct access to all parameters into protected.  And then I move instanceValue (which checks parameter and then config for a key) to public from protected.  I also exposed instanceValue to Lua and unexposed parameter.

There’s still some mess in Item, like a list of augments and such which should be parameter values.  But I think I’ll leave that to my next rampage through this area.

The second half of my day was mainly spent on a negative money bug that metadept brought to my attention regarding money underflow.  After examining the code I realized that the money could easily overflow as well.  So I spent most of the rest of the day creating a completely bullet proof no overflow signed/unsigned integer multiplication method, which surprisingly wasn’t something that was already in the language or documented somewhere.  I’ve copied it here for posterity.

template <typename Int>
typename std::enable_if<std::is_integral<Int>::value, Int>::type noOverflowMult(Int a, Int b) {
  if (!a || !b)
    return 0;

  if (b == std::numeric_limits<Int>::min()) {
    if (a > 0) {
      return b;
    } else {
      return std::numeric_limits<Int>::max();
    }
  }

  if (a == std::numeric_limits<Int>::min()) {
    if (b > 0) {
      return a;
    } else {
      return std::numeric_limits<Int>::max();
    }
  }

  Int maxInt;
  if ((a < 0) != (b < 0)) {
    maxInt = std::numeric_limits<Int>::min();
  } else {
    maxInt = std::numeric_limits<Int>::max();
  }

  if (abs(maxInt / a) < abs(b))
    return maxInt;

  return a*b;
}

Which has been tested as working against every possible pair of uint16_t and int16_t.

I also put in a “normal” maxMoney limit, and set it to 9,999,999 pixels, this is super subject to change of course, considering I just pressed 9 for a while.

I also removed our custom range function that actually had broken behavior (on every number of the form -n + .5 it rounded the wrong direction).  It was there because MSVC didn’t have it at the time, but again, we’re probably not going to target that platform.

I also created the beginnings of a math test suite to make sure our custom math functions work properly.