FANDOM


ActionCruise is an action Similar to ActionRandomWalk, but it keeps the creature moving. If the focus object argument is given, it will be used to constrain the wanderings of the creature to with the specified distance (2nd argument) of the focus object.

Notes Edit

Best used in the heartbeat.
This script was created to allow me to put a number of predators (think sharks) in an area that continually move around looking for victims. It works quite well when the focus is given (I use the POST waypoint for the creature and adjust the distance to the size of the area they are in).

  • If you don't use a focus, the creatures will tend to get stuck on the sides of the map a little. The script usually gets them off the wall in 2 or 3 heartbeats, but it doesn't look as good.
  • The creatures will also stop on trees/rocks/whatever and tend to take one or two heartbeats to move off.

The Script Edit

// Tibrogargan's ActionCruise Script
// October 2002
int TB_CRUISE_BIAS_ANGLE = 20;
string TB_CRUISE_ADJUST = "tb.cruise.adjust";
string TB_CRUISE_LOCATION = "tb.cruise.location";
string TB_CRUISE_BIAS = "tb.cruise.bias";
// ActionCruise is an action Similar to ActionRandomWalk, but it keeps
// the creature moving.  If the focus object argument is given, it will
// be used to constrain the wanderings of the creature to with the
// specified distance (2nd argument) of the focus object
void ActionCruise(object focus=OBJECT_INVALID, float fMaxDist = 40.0f)
{
    int bias = 1;
    float fDistToFocus;
    location loc;
    location locFocus;
    float facing = GetFacing(OBJECT_SELF);
    location locSelf = GetLocation(OBJECT_SELF);
    int nAngleAdjust = GetLocalInt(OBJECT_SELF, TB_CRUISE_ADJUST);
    float fDist = 25.0f; // this distance should be far enough so that the
                         // creature will not stop between heartbeats, giving
                         // a smooth transition
    // First, check to see if we're stuck on something
    if (locSelf == GetLocalLocation(OBJECT_SELF, TB_CRUISE_LOCATION))
    {
        nAngleAdjust += 30; // the longer we're stuck, the more we should
                            // vary the angle we check for new locations
        SetLocalInt(OBJECT_SELF, TB_CRUISE_ADJUST, nAngleAdjust);
    }
    else
    {
        // we're not stuck anymore, zero the adjustment angle
        DeleteLocalInt(OBJECT_SELF, TB_CRUISE_ADJUST);
    }
    // remember where we are for next time
    SetLocalLocation(OBJECT_SELF, TB_CRUISE_LOCATION, locSelf);
    // get our bias.  If it doesn't exist, calculate it
    // The bias causes the creature to tend to walk in circles, either
    // left or right.  (They are very large circles, so the bias isn't
    // pronounced)
    if (0 == (bias = GetLocalInt(OBJECT_SELF, TB_CRUISE_BIAS)))
    {
        bias = (Random(2) * 2) - 1;
        SetLocalInt(OBJECT_SELF, TB_CRUISE_BIAS, bias);
    }
    // if you don't clear all actions, the old moves get stuck in the queue
    // and make the creature try to complete them if it ever gets to the end
    // of the current move - this leads to bizarre changes in direction
    ClearAllActions();
    // if there's a valid focus, work out relevant factors
    if (GetIsObjectValid(focus))
    {
        locFocus = GetLocation(focus);
        fDistToFocus = GetDistanceBetweenLocations(locFocus, locSelf);
    }
    do
    {
        // calculate a new facing.  Normally it will be within 45 degrees of
        // the current facing, offset by the bias.  If we're stuck, or too
        // far away from the focus, the potential angle grows
        int nAngle = 90 + nAngleAdjust + (bias * TB_CRUISE_BIAS_ANGLE) - 45;
        // if we let the angle go over 360, we could be making a stuck creature
        // stay stuck longer by increasing the chance they get a facing that is
        // relatively forward
        if (nAngle > 360)
        {
            nAngle = 360;
        }
        float fNewFacing = IntToFloat((FloatToInt(facing) + Random(nAngle)) % 360);
        // only reason this is done is because the docs say facings are between
        // 0 and 360.  It seems to work fine if using angles < 0 or > 360
        if (fNewFacing < 0.0f)
        {
            fNewFacing += 360.0;
        }
        // generate the new location to move to
        loc = Location(GetArea(OBJECT_SELF),
                       GetPosition(OBJECT_SELF) +
                            Vector(cos(fNewFacing) * fDist,
                                   sin(fNewFacing) * fDist,
                                   0.0f),
                       fNewFacing);
        // add to the adjustment angle
        nAngleAdjust += 30;
        // we can stop looking for a new location if
    } while (GetIsObjectValid(focus) && // there's no focus
             ((fDistToFocus > fMaxDist) && // we're too far from the focus and
              // the new location is closer to the focus than we are now
             (GetDistanceBetweenLocations(locFocus, loc) > fDistToFocus)));
    ActionMoveToLocation(loc);
}

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.