Author Topic: [RESOURCE] Functions That Should Be Default (but Aren't)  (Read 5574 times)

Code: (Extended Defaults.cs) [Select]
/// Returns a tab-delimited string with %item added to %list, if it isn't already.
/// %list: The list of items to add to.
/// %item: The item to add to the list.
function addItemToList(%list, %item)
{
if(hasItemOnList(%list, %item))
return %list;
if(%list $= "") return %item;
return %list TAB %item;
}

/// Returns whether or not a tab-delimited %list contains a given %item.
/// %list: The list of items to check against.
/// %item: The item to check for.
function hasItemOnList(%list, %item)
{
return striPos("\t"@%list@"\t", "\t"@%item@"\t") != -1;
}

/// Returns a tab-delimited string with all instances of %item removed from %list.
/// %list: The list of items to remove from.
/// %item: The item to remove from the list.
function removeItemFromList(%list, %item)
{
%fields = getFieldCount(%list);
for(%i=%fields-1;%i>=0;%i--)
if(getField(%list, %i) $= %item)
%list = removeField(%list, %i);
return %list;
}

These functions all encourage string lists, the usage of which is an extremely bad habit to get into.



Sorry for the long post, but I just went through say, the 25 most readily available folders and dumped arbitrary, useful functions.
I rewrote some of them slightly during the process, so not everything is guaranteed to work. Do point out if that's the case for any of them.

Code: [Select]
// Create a new copy of the object.
function SimObject::clone(%this)
{
  %name = %this.getName();
  %this.setName("CloneBase");

  %clone = new (%this.getClassName())(%name : CloneBase)
  {
    isClone = 1;
  };

  %this.setName(%name);

  if (!isObject(%clone))
  {
    error("ERROR: Failed to clone object");
    return 0;
  }

  %group = %this.getGroup();

  if (isObject(%group))
  {
    %group.add(%clone);
  }

  return %clone;
}

// Check whether or not the method *%name* is available
// from this object's namespace.
function SimObject::hasMethod(%this, %name)
{
  %className = %this.getClassName();

  if (isFunction(%className, %name) || isFunction(%this.getName(), %name))
  {
    return 1;
  }

  if (%className $= "ScriptObject" || %className $= "ScriptGroup")
  {
    return
      isFunction(%this.class, %name) ||
      isFunction(%this.superClass, %name);
  }

  return isFunction(%this.className, %name);
}

// Safely set *%field* to *%value* on the object.
function SimObject::setField(%this, %field, %value)
{
  if (%field !$= "" && %field $= getSafeVariableName(%field))
  {
    eval("%this." @ %field @ "=%value;");
  }
}

// Play the `AudioProfile` *%profile* in 2D to all members of the mini-game.
function MiniGameSO::play2D(%this, %profile)
{
  if (!isObject(%profile))
  {
    return;
  }

  for (%i = 0; %i < %this.numMembers; %i++)
  {
    %this.member[%i].play2D(%profile);
  }
}

// Determine whether any event on the brick is triggered by *%input*.
function FxDTSBrick::hasInputEvent(%this, %input)
{
  for (%i = 0; %i < %this.numEvents; %i++)
  {
    if (%this.eventInput[%i] $= %input)
    {
      return 1;
    }
  }

  return 0;
}

// Determine whether the player would be in a brick if placed at *%position*.
function Player::collidesAt(%this, %position)
{
  %armor = %this.getDataBlock();

  %box = vectorScale(%this.isCrouched() ?
    %armor.crouchBoundingBox : %armor.boundingBox, 0.25);

  initContainerBoxSearch(%position, %box, $TypeMasks::FxBrickObjectType);
  return isObject(containerSearchNext());
}

// Convert *%color*, a RGBA 0.0f-1.0f representation of a color to 0-255.
function floatRGBA(%color)
{
  return
    getWord(%color, 0) / 255 SPC
    getWord(%color, 1) / 255 SPC
    getWord(%color, 2) / 255 SPC
    getWord(%color, 3) / 255;
}

// Convert *%color*, a RGBA 0-255 representation of a color to 0.0f-1.0f.
function integerRGBA(%color)
{
  return
    mFloatLength(getWord(%color, 0) * 255, 0) SPC
    mFloatLength(getWord(%color, 1) * 255, 0) SPC
    mFloatLength(getWord(%color, 2) * 255, 0) SPC
    mFloatLength(getWord(%color, 3) * 255, 0);
}

// Translate *%rgb* from the RGB colorspace into HSL.
function rgbToHsl(%rgb)
{
  %r = getWord(%rgb, 0);
  %g = getWord(%rgb, 1);
  %b = getWord(%rgb, 2);

  %max = getMax3(%r, %g, %b);
  %min = getMin3(%r, %g, %b);

  %lightness = (%max + %min) / 2;

  if (%max == %min)
  {
    return "0 0" SPC %lightness;
  }

  %delta = %max - %min;
  %saturation = %lightness > 0.5 ?
                %delta / (2 - %max - %min) :
                %delta / (%max + %min);

  switch (%max)
  {
    case %r: %hue = (%g - %b) / %delta + (%g < %b ? 6 : 0);
    case %g: %hue = (%b - %r) / %delta + 2;
    case %g: %hue = (%r - %g) / %delta + 4;
  }

  return %hue / 6 SPC %saturation SPC %lightness;
}

// Rotate/offset *%vector* randomly by *%spread* radians.
function vectorSpread(%vector, %spread)
{
  %scalars = getRandomScalar() SPC getRandomScalar() SPC getRandomScalar();
  %scalars = vectorScale(%scalars, %spread);

  return matrixMulVector(matrixCreateFromEuler(%scalars), %vector);
}

// Find the smallest of the 3 values.
function getMin3(%a, %b, %c)
{
  return %a < %b ? (%a < %c ? %a : %c) : (%b < %c ? %b : %c);
}

// Find the biggest of the 3 values.
function getMax3(%a, %b, %c)
{
  return %a > %b ? (%a > %c ? %a : %c) : (%b > %c ? %b : %c);
}

// Return a random floating point value from -1.0f to 1.0f.
function getRandomScalar()
{
  return getRandom() * 2 - 1;
}

// Search for bricks in the way of a given solid line using box searches.
// Returns 1 if an obstruction was found, 0 otherwise.
function hullTrace(%position, %target, %bounds, %limit)
{
  if (%limit $= "")
  {
    %limit = 40;
  }

  %delta = vectorSub(%target, %position);
  %count = vectorLen(%delta) / (vectorLen(%bounds) / 4);

  if (%count > %limit)
  {
    %count = %limit;
  }

  %step = vectorScale(%delta, 1 / %count);

  for (%i = 0; %i < %count; %i++)
  {
    %box = vectorScale(%bounds, 0.25);
    %pos = setWord(%position, 2,
      getWord(%position, 2) + getWord(%box, 2) / 2);

    initContainerBoxSearch(%position, %box, $TypeMasks::FxBrickObjectType);

    if (isObject(containerSearchNext()))
    {
      return 1;
    }

    %position = vectorAdd(%position, %step);
  }

  return 0;
}

// Returns the current time of day (from 0.0f to 1.0f).
function getDayCycleTime()
{
  %time = $Sim::Time / DayCycle.dayLength + DayCycle.dayOffset;
  return %time - mFloor(%time);
}

// Apply the environment settings in *%file*, created by
// `saveEnvironment` or something similar.
function loadEnvironment(%file)
{
  GameModeGuiServer::parseGameModeFile(%file, 1);

  EnvGuiServer::getIdxFromFilenames();
  EnvGuiServer::setSimpleMode();

  if (!$EnvGuiServer::SimpleMode)
  {
    EnvGuiServer::fillAdvancedVarsFromSimple();
    EnvGuiServer::setAdvancedMode();
  }
}

// Change an environment setting without needing a fake client. Implements
// the default functionality - could be written more succintly, but this was
// intended to be as much like the default system as possible.
function setEnvironment(%varName, %value)
{
  if ($EnvGuiServer["::" @ %varName] $= %value)
    return;

  switch$ (%varName)
  {
  case "SimpleMode":
    $EnvGuiServer::SimpleMode = mClamp(%value, 0, 1);
    EnvGuiServer::setSimpleMode();

    if (!$EnvGuiServer::SimpleMode)
    {
      if (!$EnvGuiServer::HasSetAdvancedOnce)
        EnvGuiServer::readAdvancedVarsFromSimple();

      EnvGuiServer::setAdvancedMode();
    }

  case "SkyIdx":
    $EnvGuiServer::SkyIdx = mClamp(%value, 0, $EnvGuiServer::SkyCount);
    setSkyBox($EnvGuiServer::Sky[$EnvGuiServer::SkyIdx]);

  case "WaterIdx":
    $EnvGuiServer::WaterIdx = mClamp(%value, 0, $EnvGuiServer::WaterCount);
    setWater($EnvGuiServer::Water[$EnvGuiServer::WaterIdx]);

  case "GroundIdx":
    $EnvGuiServer::GroundIdx = mClamp(%value, 0, $EnvGuiServer::GroundCount);
    setGround($EnvGuiServer::Ground[$EnvGuiServer::GroundIdx]);

  case "SunFlareTopIdx":
    $EnvGuiServer::SunFlareTopIdx = mClamp(%value, 0, $EnvGuiServer::SunFlareCount);
    %top = $EnvGuiServer::SunFlareTop[$EnvGuiServer::SunFlareTopIdx];
    %bottom = $EnvGuiServer::SunFlareBottom[$EnvGuiServer::SunFlareBottomIdx];
    SunLight.setFlareBitmaps(%top, %bottom);

  case "SunFlareBottomIdx":
    $EnvGuiServer::SunFlareBottomIdx = mClamp(%value, 0, $EnvGuiServer::SunFlareCount);
    %top = $EnvGuiServer::SunFlareTop[$EnvGuiServer::SunFlareTopIdx];
    %bottom = $EnvGuiServer::SunFlareBottom[$EnvGuiServer::SunFlareBottomIdx];
    SunLight.setFlareBitmaps(%top, %bottom);

  case "DayOffset":
    $EnvGuiServer::DayOffset = mClampF(%value, 0, 1);
    DayCycle.setDayOffset($EnvGuiServer::DayOffset);

  case "DayLength":
    $EnvGuiServer::DayLength = mClamp(%value, 0, 86400);
    DayCycle.setDayLength($EnvGuiServer::DayLength);

  case "DayCycleEnabled":
    $EnvGuiServer::DayCycleEnabled = mClamp(%value, 0, 1);
    DayCycle.setEnabled($EnvGuiServer::DayCycleEnabled);

  case "DayCycleIdx":
    $EnvGuiServer::DayCycleIdx = mClamp(%value, 0, $EnvGuiServer::DayCycleCount);
    %dayCycle = $EnvGuiServer::DayCycle[$EnvGuiServer::DayCycleIdx];
    echo("server setting daycycle to " @ %dayCycle);
    loadDayCycle(%dayCycle);

  case "Sunational socialistmuth":
    $EnvGuiServer::Sunational socialistmuth = mClampF(%value, 0, 360);
    Sun.azimuth = $EnvGuiServer::Sunational socialistmuth;
    Sun.sendUpdate();

  case "SunElevation":
    $EnvGuiServer::SunElevation = mClampF(%value, -10, 190);
    Sun.elevation = $EnvGuiServer::SunElevation;
    Sun.sendUpdate();

  case "DirectLightColor":
    $EnvGuiServer::DirectLightColor = getColorF(%value);
    Sun.color = $EnvGuiServer::DirectLightColor;
    Sun.sendUpdate();

  case "AmbientLightColor":
    $EnvGuiServer::AmbientLightColor = getColorF(%value);
    Sun.ambient = $EnvGuiServer::AmbientLightColor;
    Sun.sendUpdate();

  case "ShadowColor":
    $EnvGuiServer::ShadowColor = getColorF(%value);
    Sun.shadowColor = $EnvGuiServer::DirectLightColor;
    Sun.sendUpdate();

  case "SunFlareColor":
    $EnvGuiServer::SunFlareColor = getColorF(%value);
    SunLight.color = $EnvGuiServer::SunFlareColor;
    SunLight.sendUpdate();

  case "SunFlareSize":
    $EnvGuiServer::SunFlareSize = mClampF(%value, 0, 10);
    // Badspot, why not just SunLight.setFlareSize(...);?
    SunLight.flareSize = $EnvGuiServer::SunFlareSize;
    SunLight.sendUpdate();

  case "SunFlareIdx":
    $EnvGuiServer::SunFlareIdx = mClamp(%value, 0, $EnvGuiServer::SunFlareCount);
    // ... what? Why does this exist? There is no "SunFlareIdx" system.
    // Get outta' here.

  case "VisibleDistance":
    $EnvGuiServer::VisibleDistance = mClampF(%value, 0, 1000);
    Sky.visibleDistance = $EnvGuiServer::VisibleDistance;
    Sky.sendUpdate();

  case "FogDistance":
    $EnvGuiServer::FogDistance = mClampF(%value, 0, 1000);
    Sky.fogDistance = $EnvGuiServer::FogDistance;
    Sky.sendUpdate();

  case "FogHeight":
    $EnvGuiServer::FogHeight = mClampF(%value, 0, 1000);
    // Nothing to see here...

  case "FogColor":
    $EnvGuiServer::FogColor = getColorF(%value);
    Sky.fogColor = $EnvGuiServer::FogColor;
    Sky.sendUpdate();

  case "WaterColor":
    $EnvGuiServer::WaterColor = getColorF(%value);

    if (isObject(WaterPlane))
    {
      WaterPlane.color = getColorI($EnvGuiServer::WaterColor);
      WaterPlane.blend = getWord(WaterPlane.color, 3) < 255;
      WaterPlane.sendUpdate();
    }

    updateWaterFog();

  case "WaterHeight":
    $EnvGuiServer::WaterHeight = mClampF(%value, 0, 100);

    if (isObject(WaterPlane))
    {
      %pos = getWords(GroundPlane.getTransform(), 0, 2);
      %pos = vectorAdd(%pos, "0 0" SPC $EnvGuiServer::WaterHeight);

      WaterPlane.setTransform(%pos SPC "0 0 1 0");
      WaterPlane.sendUpdate();

      updateWaterFog();

      if (isObject(WaterZone))
      {
        %pos = vectorSub(%pos, "0 0 99.5");
        %pos = vectorSub(%pos, "500000 -500000 0");
        WaterZone.setTransform(%pos SPC "0 0 1 0");
      }
    }

  case "UnderWaterColor":
    $EnvGuiServer::UnderWaterColor = getColorF(%value);

    if (isObject(WaterZone))
    {
      WaterZone.setWaterColor($EnvGuiServer::UnderWaterColor);
    }

  case "SkyColor":
    $EnvGuiServer::SkyColor = getColorF(%value);
    // Something is off about this one...
    Sky.skyColor = $EnvGuiServer::SkyColor;
    Sky.sendUpdate();

  // Should probably combine this into one
  // case "WaterScrollX" or "WaterScrollY":
  case "WaterScrollX":
    $EnvGuiServer::WaterScrollX = mClampF(%value, -10, 10);
    $EnvGuiServer::WaterScrollY = mClampF($EnvGuiServer::WaterScrollY, -10, 10);

    if (isObject(WaterPlane))
    {
      WaterPlane.scrollSpeed = $EnvGuiServer::WaterScrollX SPC $EnvGuiServer::WaterScrollY;
      WaterPlane.sendUpdate();
    }

    if (isObject(WaterZone))
    {
      %fx = $EnvGuiServer::WaterScrollX * 414;
      %fy = $EnvGuiServer::WaterScrollY * -414;

      WaterZone.appliedForce = %fx SPC %fy SPC 0;
      WaterZone.sendUpdate();
    }

  case "WaterScrollY":
    $EnvGuiServer::WaterScrollY = mClampF(%value, -10, 10);
    $EnvGuiServer::WaterScrollX = mClampF($EnvGuiServer::WaterScrollX, -10, 10);

    if (isObject(WaterPlane))
    {
      WaterPlane.scrollSpeed = $EnvGuiServer::WaterScrollX SPC $EnvGuiServer::WaterScrollY;
      WaterPlane.sendUpdate();
    }

    if (isObject(WaterZone))
    {
      %fx = $EnvGuiServer::WaterScrollX * 414;
      %fy = $EnvGuiServer::WaterScrollY * -414;

      WaterZone.appliedForce = %fx SPC %fy SPC 0;
      WaterZone.sendUpdate();
    }

  case "GroundColor":
    $EnvGuiServer::GroundColor = getColorF(%value);

    if (isObject(GroundPlane))
    {
      GroundPlane.color = getColorI($EnvGuiServer::GroundColor);
      GroundPlane.blend = getWord(GroundPlane.color, 3) < 255;
      GroundPlane.sendUpdate();

      Sky.renderBottomTexture = getWord(GroundPlane.color, 3) <= 0);
      Sky.noRenderBans = Sky.renderBottomTexture;
      Sky.sendUpdate();
    }

  case "GroundScrollX":
    $EnvGuiServer::GroundScrollX = mClampF(%value, -10, 10);
    $EnvGuiServer::GroundScrollY = mClampF($EnvGuiServer::GroundScrollY, -10, 10);

    if (isObject(GroundPlane))
    {
      GroundPlane.scrollSpeed = $EnvGuiServer::GroundScrollX SPC $EnvGuiServer::GroundScrollY;
      GroundPlane.sendUpdate();
    }

  case "GroundScrollY":
    $EnvGuiServer::GroundScrollY = mClampF(%value, -10, 10);
    $EnvGuiServer::GroundScrollX = mClampF($EnvGuiServer::GroundScrollX, -10, 10);

    if (isObject(GroundPlane))
    {
      GroundPlane.scrollSpeed = $EnvGuiServer::GroundScrollX SPC $EnvGuiServer::GroundScrollY;
      GroundPlane.sendUpdate();
    }

  case "VignetteMultiply":
    $EnvGuiServer::VignetteMultiply = mClamp(%value, 0, 1);
    sendVignetteAll();

  case "VignetteColor":
    $EnvGuiServer::VignetteColor = getColorF(%value);
    sendVignetteAll();

  default:
    return 0;
  }

  return 1;
}
« Last Edit: June 14, 2014, 06:10:23 AM by portify »

oh god forget all of these functions are useful
ESPECIALLY the hull search

Ill dump some of my core.cs which I copy paste between all my add-ons. I havent really documented the functions too well, some of them could be seriously optimized, and some of them might be broken.


function brickAngleToTransform(%angleID) {
   switch(%angleID % 4) {
      case 0: return "1 0 0 0";
      case 1: return "0 0 1 90";
      case 2: return "0 0 1 180";
      case 3: return "0 0 -1 90";
   }
}

function printNameToID(%printname) { //Credits to DrenDran from BVSS
   if(%printname $= "" || %printname $= " ")
      return 0;
   %slashPos = strpos(%printname,"/");
   %end = getSubStr(%printname, %slashPos, strlen(%printname)-%slashPos);
   return $printNameTableLetters[%end];
}

function printIDToName(%id) { //Credits to Port, from forums
   %texture = getPrintTexture(%id);

   %path = getSubStr(%texture, 14, strLen(%texture));
   %path = getSubStr(%path, 0, strPos(%path, "/"));
   %path = getSubStr(%path, 0, strPos(%path, "_"));
   
   return %path @ "/" @ fileBase(%texture);
}

function mLerp(%a, %b, %t) {
   return %t * (%b-%a) + %a;
}

function vectorLerp(%init, %end, %t) {
   return vectorAdd(%init, vectorScale(vectorSub(%end, %init), %t));
}

function vectorSlerp(%init, %end, %t) { //Thanks wikipedia! Returns spherical interpolation of two vectors
   %ang = vectorAngleBetween(%init, %end);
   //vecA * (sin((1-t)*a)/sin(a)) + vecB * (sin(t*a)/sin(a))
   return vectorAdd(vectorScale(%init, mSin((1-%t) * %ang) / mSin(%ang)), vectorScale(%end, mSin(%t * %ang) / mSin(%ang)));
}

function vectorAngleBetween(%vec1, %vec2) { //Returns the angle between two vectors in radians
   return mACos(vectorDot(%vec1, %vec2)/(vectorLen(%vec1) * vectorLen(%vec2)));
}

function vectorComponent(%vec1, %vec2) { //Returns the component of vec1 in the direction of vec2
   return vectorDot(%vec1, vectorNormalize(%vec2));
}

function vectorProjection(%vec1, %vec2) { //Returns the vector projection of %vec1 in the direction of %vec2
   return vectorScale(vectorNormalize(%vec2), vectorComponent(%vec1, %vec2));
}

function vectorRejection(%vec1, %vec2) { //Returns the vector rejection of vec1 from vec2
   return vectorSub(%vec1, vectorProjection(%vec1, %vec2));
}

function eulerToVector(%ang) {
   if(getWordCount(%ang) == 2) //Support for giving pitch and yaw, but not roll.
      %ang = getWord(%ang, 0) SPC "0" SPC getWord(%ang, 1);

   %yaw = mDegToRad(getWord(%ang, 2));
   %pitch = mDegToRad(getWord(%ang, 0));
   %x = mSin(%yaw) * mCos(%pitch) * -1;
   %y = mCos(%yaw) * mCos(%pitch);
   %z = mSin(%pitch);
   return %x SPC %y SPC %z;
}

function axisToVector(%ang) {
   return eulerToVector(axisToEuler(%ang));
}

function vectorToEuler(%vec) {
   %vec = vectorNormalize(%vec);
   %yaw   = mRadToDeg(mATan(getWord(%vec, 0) * -1, getWord(%vec, 1)));
   %pitch = mFloatLength(mRadToDeg(mATan(getWord(%vec, 2), vectorLen(getWords(%vec, 0, 1)))), 3);
   return %pitch SPC "0" SPC %yaw;
}

function vectorToAxis(%vec) {
   return eulerToAxis(vectorToEuler(%vec));
}

function vectorRotateVector(%vec1, %vec2) {
   return vectorRotateAxis(%vec1, vectorToAxis(%vec2));
}

function vectorRotateEuler(%vec, %euler) {
   return vectorRotateAxis(%vec, eulerToAxis(%euler));
}

function vectorRotateAxis(%vec, %axis) { //Epic function found online. Credits to Blocki <3. Id also like to thank Zeblote for finding this for me <3
   %u["x"] = getword(%axis,0);
   %u["y"] = getword(%axis,1);
   %u["z"] = getword(%axis,2);

   %angl = getword(%axis,3) * -1;
   %cos = mcos(%angl);
   %sin = msin(%angl);

   %a[1,1] = %cos + (%u["x"] * %u["x"] * (1 - %cos));
   %a[1,2] = (%u["x"] * %u["y"] * (1 - %cos)) - (%u["z"] * %sin);
   %a[1,3] = (%u["x"] * %u["z"] * (1 - %cos)) + (%u["y"] * %sin);

   %a[2,1] = (%u["y"] * %u["x"] * (1 - %cos)) + (%u["z"] * %sin);
   %a[2,2] = %cos + (%u["y"] * %u["y"] * (1 - %cos));
   %a[2,3] = (%u["y"] * %u["z"] * (1 - %cos)) - (%u["x"] * %sin);

   %a[3,1] = (%u["z"] * %u["x"] * (1 - %cos)) - (%u["y"] * %sin);
   %a[3,2] = (%u["z"] * %u["y"] * (1 - %cos)) + (%u["x"] * %sin);
   %a[3,3] = %cos + (%u["z"] * %u["z"] * (1 - %cos));

   %x = getWord(%vec, 0);
   %y = getWord(%vec, 1);
   %z = getWord(%vec, 2);

   %newx = (%a[1,1] * %x) + (%a[1,2] * %y) + (%a[1,3] * %z);
   %newy = (%a[2,1] * %x) + (%a[2,2] * %y) + (%a[2,3] * %z);
   %newz = (%a[3,1] * %x) + (%a[3,2] * %y) + (%a[3,3] * %z);

   %pos = %newx SPC %newy SPC %newz;
   return %pos;
}

function isBL_IDAdmin(%id) {
   //Check if player is online and is admin
   if(isObject(%client = findClientByBL_ID(%id))) {
      if(%client.isAdmin || %client.isSuperAdmin) //Check super admin now rather than calling the other function for efficiency
         return true;
      else
         return false; //If theyre online and theyre not admin, assume theyre not supposed to be admin
   }

   //Check auto admin list
   %count = getWordCount($Pref::Server::AutoAdminList);
   for(%i=0; %i < %count; %i++) {
      %guy = getWord($Pref::Server::AutoAdminList, %i);
      if(%guy == %id)
         return true;
   }

   return isBL_IDSuperAdmin(%id);
}

function isBL_IDSuperAdmin(%id) {
   //Check if player is online and is super admin
   if(isObject(%client = findClientByBL_ID(%id))) {
      if(%client.isSuperAdmin)
         return true;
      else
         return false;
   }

   //Check auto super admin list
   %count = getWordCount($Pref::Server::AutoSuperAdminList);
   for(%i=0; %i < %count; %i++) {
      %guy = getWord($Pref::Server::AutoSuperAdminList, %i);
      if(%guy == %id)
         return true;
   }

   return isBL_IDHost(%id);
}

function isBL_IDHost(%id) { //Credits to Greek2me for this, on forums.
   return (%client.isLocalConnection() || ($Server::LAN && $Server::Dedicated) || %client.getBLID() $= getNumKeyID());
}


function vectorAddMulti(%a, %b) { //Add up to infinite dimensional vectors
   %lowest = getWordCount(%a) < getWordCount(%b) ? getWordCount(%a) : getWordCount(%b);
   for(%i=0; %i < %lowest; %i++)
      %vec = %vec SPC getWord(%a, %i) + getWord(%b, %i);
   return trim(%vec);
}

function vectorSubMulti(%a, %b) {
   %lowest = getWordCount(%a) < getWordCount(%b) ? getWordCount(%a) : getWordCount(%b);
   for(%i=0; %i < %lowest; %i++)
      %vec = %vec SPC getWord(%a, %i) - getWord(%b, %i);
   return trim(%vec);
}

function vectorScaleMulti(%a, %b) {
   for(%i=0; %i < getWordCount(%a); %i++)
      %vec = %vec SPC getWord(%a, %i) * %b;
   return trim(%vec);
}

function vectorMultiplyMulti(%a, %b) {
   %lowest = getWordCount(%a) < getWordCount(%b) ? getWordCount(%a) : getWordCount(%b);
   for(%i=0; %i < %lowest; %i++)
      %vec = %vec SPC getWord(%a, %i) * getWord(%b, %i);
   return trim(%vec);
}

function vectorDivideMulti(%a, %b) {
   %lowest = getWordCount(%a) < getWordCount(%b) ? getWordCount(%a) : getWordCount(%b);
   for(%i=0; %i < %lowest; %i++)
      %vec = %vec SPC getWord(%a, %i) / getWord(%b, %i);
   return trim(%vec);
}

function vectorLenMulti(%a) {
   %wordCount = getWordCount(%a);
   for(%i=0; %i < %wordCount; %i++)
      %len += mPow(getWord(%a, %i), 2);
   return mPow(%len, 0.5);
}

function vectorDistMulti(%a, %b) {
   return vectorLenMulti(vectorSubMulti(%a, %b));
}

function VectorNormalizeMulti(%a) {
   return vectorScaleMulti(%a, 1/vectorLenMulti(%a)); //Lazy method
}

function vectorFloatLength(%vec, %float) {
   return mFloatLength(getWord(%vec, 0), %float) SPC mFloatLength(getWord(%vec, 1), %float) SPC mFloatLength(getWord(%vec, 2), %float);
}

function getClosestPaintColor(%rgba) {
   %prevdist = 100000;
   %colorMatch = 0;
   for(%i = 0; %i < 64; %i++) {
      %color = getColorIDTable(%i);
      if(vectorDist(%rgba,getWords(%color,0,2)) < %prevdist && getWord(%rgba,3) - getWord(%color,3) < 0.3 && getWord(%rgba,3) - getWord(%color,3) > -0.3) {
         %prevdist = vectorDist(%rgba,%color);
         %colormatch = %i;
      }
   }
   return %colormatch;
}

function mMod(%num, %a) { //Supports decimals unlike %
   return ((%num / %a) - mFloor(%num / %a)) * %a;
}

function mFloorTo(%num, %a) { //Rounds down %num to the nearest %a
   return mFloor(%num / %a) * %a;
}

function mCeilTo(%num, %a) {
   return mCeil(%num / %a) * %a;
}

function mRound(%num) {
   return mFloatLength(%num, 0);
}

function mRoundTo(%num, %a) {
   return mRound(%num / %a) * %a;
}

function mIntLength(%num, %a) {
   %num = mRound(%num);

   if(%a >= 0) {
      while(strLen(%num) < %a)
         %num = 0 @ %num;
      while(strLen(%num) > %a) {
         %num = getSubStr(%num, 0, strLen(%num)-1);
         %add0s++;
      }

      for(%i=1; %i <= %add0s; %i++)
         %num = %num @ 0;
      return %num;
   }
}

function mInterpolate(%num, %mina, %maxa, %minb, %maxb) { //Similar to mLerp, but does a reverse lerp with the first 3 parameters
   return (%num-%mina) / (%maxa-%mina) * (%maxb-%minb) + %minb;
}



//Credits to Trader for these off the forums.
function eulerToAxis(%euler) {
   %euler = VectorScale(%euler,$pi / 180);
   %matrix = MatrixCreateFromEuler(%euler);
   return getWords(%matrix,3,6);
}

function axisToEuler(%axis) {
   %angleOver2 = getWord(%axis,3) * 0.5;
   %angleOver2 = -%angleOver2;
   %sinThetaOver2 = mSin(%angleOver2);
   %cosThetaOver2 = mCos(%angleOver2);
   %q0 = %cosThetaOver2;
   %q1 = getWord(%axis,0) * %sinThetaOver2;
   %q2 = getWord(%axis,1) * %sinThetaOver2;
   %q3 = getWord(%axis,2) * %sinThetaOver2;
   %q0q0 = %q0 * %q0;
   %q1q2 = %q1 * %q2;
   %q0q3 = %q0 * %q3;
   %q1q3 = %q1 * %q3;
   %q0q2 = %q0 * %q2;
   %q2q2 = %q2 * %q2;
   %q2q3 = %q2 * %q3;
   %q0q1 = %q0 * %q1;
   %q3q3 = %q3 * %q3;
   %m13 = 2.0 * (%q1q3 - %q0q2);
   %m21 = 2.0 * (%q1q2 - %q0q3);
   %m22 = 2.0 * %q0q0 - 1.0 + 2.0 * %q2q2;
   %m23 = 2.0 * (%q2q3 + %q0q1);
   %m33 = 2.0 * %q0q0 - 1.0 + 2.0 * %q3q3;
   return mRadToDeg(mAsin(%m23)) SPC mRadToDeg(mAtan(-%m13, %m33)) SPC mRadToDeg(mAtan(-%m21, %m22));
}
« Last Edit: June 14, 2014, 01:26:16 PM by boodals 2 »

These functions all encourage string lists, the usage of which is an extremely bad habit to get into.
Why is this a bad habit?

Code: [Select]
// Safely set *%field* to *%value* on the object.
function SimObject::setField(%this, %field, %value)
{
  if (%field !$= "" && %field $= getSafeVariableName(%field))
  {
    eval("%this." @ %field @ "=%value;");
  }
}
This isn't actually safe, I advise against using this

Why is this a bad habit?
Because string lists are the slowest things ever. You're literally better off using an array of global variables.

This isn't actually safe, I advise against using this

Well only in the regard that getSafeVariableName doesn't cover all cases. Validating the string as an identifier would be better.

Well only in the regard that getSafeVariableName doesn't cover all cases. Validating the string as an identifier would be better.
Correct. But still, not completely safe.

Boodals, look carefully at that isBL_IDHost function.

Here's another couple: http://forum.blockland.us/index.php?topic=237487.0
« Last Edit: June 14, 2014, 10:59:58 AM by Greek2me »

Boodals, look carefully at that isBL_IDHost function.

Oh wow derp.

I guess that's never been called, else I would have noticed it..

Code: [Select]
function advancedFindClientByName(%name)
{
if(%name $= "")
{
return false;
}

%matchCount = 0;
%numOfClients = clientGroup.getCount();

for(%count = 0; %count < %numOfClients; %count++)
{
%target = clientGroup.getObject(%count);

if(getSubStr(%target.name, 0, strLen(%name)) $= %name)
{
%matchedClient = %target;
%matchedCount++;
}

if(%name $= %matchedClient.name)
{
return(%matchedClient);
}
}

if(!(%matchedClient.name $= ""))
{
if(%matchedCount == 1)
{
return(%matchedClient);
}
}

return false;
}


I made an advanced FindClient function, I was having a lot of problems with when people had similar names.

alxPause(), alxPauseAll()

alxPause(), alxPauseAll()

Thank you for providing such a perfect example of what this thread ISN'T for.


Also, I'll add the functions posted up to now once I get back from this birthday party.

getRandomF

"Returns a value (not integer) between X and Y"

The "f" means nothing really. It could have meant "field" and it gets a random integer within the field delimited by the arguments. Value also in no way implies float. Value can describe a string too, does that mean I should assume you meant it returns a random string between X and Y? Don't even try to argue that you clarified in the metadata that the function returned a float value, because you straight didn't.

I made an advanced FindClient function, I was having a lot of problems with when people had similar names.

So it just returns the first client whose name starts with %name? "return(stuff);" should be "return stuff;" as well.

So it just returns the first client whose name starts with %name? "return(stuff);" should be "return stuff;" as well.


It would only return the client in the for loop if the name you searched for completely matched the client's name. Then after the for loop it checks to see if there was only one matched client. If there was only one it returns that client, otherwise it doesn't return anything.