Torque 2D/Reference/Strategy/StrategyActions/actionscs2

From TDN

Back {{Template:ContentBlockoutB|

The contents of "actions.cs"

// --------------------------------------------------------------------
// Soldier::attack()
//
// This is the attack action attached to our Soldier class,
// this function will trigger the needed attack steps and then calls
// the follow action (since the attacker needs to follow)
// --------------------------------------------------------------------
function Soldier::attack(%this, %obj)
{
   // reset all of our actions
   %this.action("resetAllActions");

   // set the proper bool and target values
   %this.attacking = true;
   %this.attackTarget = %obj;
   
   // call the follow action passing the target (to be followed)
   %this.action("follow", %obj);
}

// --------------------------------------------------------------------
// Soldier::follow()
//
// This is the follow action, you specify the object to be followed and
// then the following function is triggered
// --------------------------------------------------------------------
function Soldier::follow(%this, %obj)
{
   // store the object and the bool
   %this.followObj = %obj;
   %this.following = true;
   
   // call the following function
   %this.following();   
}

// --------------------------------------------------------------------
// Soldier::following()
//
// This is the following event, this is the meat of the following system
// this will keep triggering while following, this will also handle
// a large portion of the attack triggering system
// --------------------------------------------------------------------
function Soldier::following(%this)
{
   // check if we are actually following
   if(%this.following)
   {
      // first we grab the follow object's positon, then our position
      // we then get the vectorBetween us and our follow object, next we normalize
      // this vector so we can proceed and scale it up by the specified distance,
      // after that we add our scaled vector to our follow object's position
      // this creates a tailing distance vs. following on the exact location
      // of the object
      %objPos = %this.followObj.getPosition();
      %pos = %this.getPosition();
      %vecBetween = t2dVectorSub(%pos, %objPos);
      %vecNorm = t2dVectorNormalise(%vecBetween);
      %scaled = t2dVectorScale(%vecNorm, %this.followDistance);
      %result = t2dVectorAdd(%scaled, %objPos);
      
         // we calculate the distance between the objects, then subtract our follow distance
      %distToObject = t2dVectorLength(%vecBetween);
      %dist = %distToObject - %this.followDistance;
      
      // if we are following an object and -Not- attack it we do this adjustment and 
      // comparisson to add a slight slow down to ease up to our ally we're following
      if(%dist >= %this.speed || %this.attacking)
      {
         %speed = %this.speed;
      } else
      {
         %div = %this.speed;
         %speed = %this.speed  - (%div - %dist);
      }
      
         // Check if we are attacking and the object we're attackign isn't dead
      if(%this.attacking && !%this.attackTarget.dead)
      {
         // we compare the sceneTime minus last attack time to the attackDelay... this
         // gives us a nice delay in attacking
         if(($strategyScene.getSceneTime() - %this.lastAttackTime) > %this.attackDelay || %this.lastAttackTime $= "")
         {
            // grab the enemies position and distance to them
            %enemyPos = %this.attackTarget.getPosition();
            %distToEnemy = t2dVectorLength(t2dVectorSub(%pos, %enemyPos));

            // check our attack range
            if(%distToEnemy <= %this.attackRange)
            {
               // if within attacking range, attack the target
               %this.action("attackTarget");
            }
         }
      }
      
      // lets move to our resulitng position
      %this.action("moveToLoc", %result);
      // schedule our following function to be called again
      %this.followSchedule = %this.schedule(500, "following");   
   }
}

// --------------------------------------------------------------------
// Soldier::attackTarget()
//
// This is the action attached to the Soldier that will actually perform 
// the attacking sequence.  This action is only called if a target is
// within range and is to be attacked, so we call damage on the target
// and store the time for the delayed attack system
// --------------------------------------------------------------------
function Soldier::attackTarget(%this)
{
   // store the scene time when we attacked for our attack delay
   %this.lastAttackTime = $strategyScene.getSceneTime();
 
   // call the damage action on the target using the power
   // of the attacking unit
   %this.attackTarget.action("damage", %this.attackPower);
}

// --------------------------------------------------------------------
// Entity::damage()
//
// This is the action attached to all of our entities that performs
// the actual hitpoint reduction calculation and subtraction
// --------------------------------------------------------------------
function Entity::damage(%this, %ammount)
{
   // first check to see if this object is already dead
   if(%this.dead)
   {
      return;
   }

   // lets call our blood effect
   playBloodEffect(%this.getPosition());
 
   // subtract the hit points based on the ammount passed (usually the
   // attacking unit's power)
   %this.hitPoints -= %ammount;
   
   // if our object reaches 0 or less hitpoints then we want to do a 
   // few things to ensure it is dead
   if(%this.hitPoints <= 0)
   {
      // first we will call a reset to all actions, to prevent our object
      // from continually performing any actions
      %this.action("resetAllActions");

      // set the hitpooints to zero
      %this.hitPoints = 0;

      // toggle the object's dead to true
      %this.dead = true;

      // turn our label invisible
      %this.labelGui.setVisible(false);

      // disable our label object
      %this.labelObj.setEnabled(false);

      // disable our object
      %this.setEnabled(false);  
   }
   
   // call the update of our hit points display
   %this.action("updateHitPointsDisplay");
}

// --------------------------------------------------------------------
// Entity::updateHitPointsDisplay()
//
// This is the action that updates the visual bitmap hit points bar and
// the border bar on the unit
// --------------------------------------------------------------------
function Entity::updateHitPointsDisplay(%this)
{
   // first we grab the position and then we 
   // divide it up into X and Y variables, then we
   // grab the extent and divide it into width and height
   %pos = %this.hitPointsBorderBar.getPosition();
   %posX = getWord(%pos, 0);
   %posY = getWord(%pos, 1);
   %extent = %this.hitPointsBorderBar.getExtent();
   %extentWidth = getWord(%extent, 0);
   %extentHeight = getWord(%extent, 1);
		
   // here we use the hitpoints max to set the hitPoints border bar extent 
   %extentWidth = mFloor(%this.hitPointsMax/%this.hitPointBarScaleFactor);	

   // we dynamically size the GUI bitmap bar by using the resize() command
   %this.hitPointsBorderBar.resize(%posX, %posY, %extentWidth, %extentHeight);

   // first we grab the position and then we 
   // divide it up into X and Y variables, then we
   // grab the extent and divide it into width and height		 
   %pos = %this.hitPointsBar.getPosition();
   %posX = getWord(%pos, 0);
   %posY = getWord(%pos, 1);
   %extent = %this.hitPointsBar.getExtent();
   %extentWidth = getWord(%extent, 0);
   %extentHeight = getWord(%extent, 1);
		
   // here we use the hitpoints to set the hitPoints bar extent 
   %extentWidth = mFloor(%this.hitPoints/%this.hitPointBarScaleFactor);	

   // we dynamically size the GUI bitmap bar by using the resize() command
   %this.hitPointsBar.resize(%posX, %posY, %extentWidth, %extentHeight); 
}

// --------------------------------------------------------------------
// Soldier::resetAllActions()
//
// This action will reset all actions, we basically put calls to the stop
// actions here that are specific to the class
// --------------------------------------------------------------------
function Soldier::resetAllActions(%this)
{
   // stop the attacking action
   %this.action("stopAttacking");
}

// --------------------------------------------------------------------
// Soldier::stopAttacking()
//
// This action will stop the attacking process properly
// --------------------------------------------------------------------
function Soldier::stopAttacking(%this)
{
   // first we toggle attacking to false, we reset the attackTarget to
   // nothing, set the lastAttackTime to nothing, and then call the
   // stopFollowing action
   %this.attacking = false;
   %this.attackTarget = "";
   %this.lastAttackTime = "";
   %this.action("stopFollowing");
}

// --------------------------------------------------------------------
// Soldier::stopFollowing()
//
// This action will stop the following process properly
// --------------------------------------------------------------------
function Soldier::stopFollowing(%this)
{
   // reset the followObj and the following bool
   %this.followObj = "";
   %this.following = false;
}

// --------------------------------------------------------------------
// playBloodEffect()
//
// Used to play the blood spurt/spray particle effect
// --------------------------------------------------------------------
function playBloodEffect(%pos)
{
   // store the effect object
   %eff = new t2dParticleEffect() { sceneGraph = $strategyScene; };
   // load th effect file
   %eff.loadEffect("Strategy/data/particles/bloodspurt.eff");
   // set the effect for the first layer
   %eff.setLayer(0);
   // set the effect to be destroyed on completion
   %eff.setEffectLifeMode("KILL", 1.0);
   // set the efects position with the position passed
   %eff.setPosition(%pos);
   // play the effect
   %eff.playEffect(); 
}

// --------------------------------------------------------------------
// Worker::mineGold()
//
// This action will start the Worker mining gold
// --------------------------------------------------------------------
function Worker::mineGold(%this, %mine)
{
   // first we check to see of the mine's .type is
   // in fact a goldMine
   if(%mine.class !$= "GoldMine")
   {
      // we have encountered an invalid mine
      error("not a valid gold mine");
      return;      
   }
   
   // store the mine on the object and set mining to true
   %this.mineTarget = %mine;
   %this.mining = true;
   
   // now we call our next action, goToMine
   %this.action("goToMine");
}

// --------------------------------------------------------------------
// Worker::goToMine()
//
// This action will send our Worker to the mine
// --------------------------------------------------------------------
function Worker::goToMine(%this)
{
   // first we check if we have a mining target
   // if we don't, we set mining to false and exit
   if(%this.mineTarget $= "")
   {
      error("no valid mine selected to mine");
      %this.mining = false;
      return;      
   }
   
   // grab the mine stored on the object
   %mine = %this.mineTarget;
   
   // toggle headingToMine to true
   %this.headingToMine = true;

   // send our Worker to the mine, the last true is to 
   // enable the callback
   %this.moveTo(%mine.getPosition(), %this.speed, true, true);   
}

// --------------------------------------------------------------------
// t2dSceneObject::onPositionTarget()
//
// This is the generic callback by TGB when an object has reached
// it's destination
// --------------------------------------------------------------------
function t2dSceneObject::onPositionTarget(%this)
{
      %this.onReachDestination(%this);
}

// --------------------------------------------------------------------
// Soldier::onReachDestination()
//
// This is called when a Soldier has reached its destination
// --------------------------------------------------------------------
function Soldier::onReachDestination(%this)
{

}

// --------------------------------------------------------------------
// Worker::onReachDestination()
//
// This is called when a worker has reached its destination on a
// moveTo call that has the callback option set to true
// --------------------------------------------------------------------
function Worker::onReachDestination(%this)
{
   // here is the check if the worker is mining
   if(%this.mining)
   {
      // check if we're heading home, if so then we have returned
      // from mining... if we aren't heading home then we have reached
      // the mine and must start mining
      if(%this.headingHome)
      {
         %this.headingHome = false;
         %this.action("returnedFromMining");   
      } else if(%this.headingToMine)
      {
         %this.headingToMine = false;
         %this.action("startMining");         
      }
   }   
}

// --------------------------------------------------------------------
// Worker::startMining()
//
// This is the action to get the Worker to start mining
// --------------------------------------------------------------------
function Worker::startMining(%this)
{
   // grab the miningDelay
   %delay = %this.miningDelay;
   
   // schedule the completion of the mining process
   %this.miningSchedule = %this.schedule(%delay, "action", "finishMining");
}

// --------------------------------------------------------------------
// Worker::finishMining()
//
// This is the action that is called when the Worker has finished
// it's mining process, we then store gold on the object and tell
// it to return home
// --------------------------------------------------------------------
function Worker::finishMining(%this)
{
   // store that our object is carrying gold
   %this.carrying = "gold";
   // store the mining ammount of gold on it
   %this.carryingAmmount = %this.goldMiningAmmount;
   // time to send it home
   %this.action("returnHome");      
}

// --------------------------------------------------------------------
// Worker::returnHome()
//
// This action sends our object back home
// --------------------------------------------------------------------
function Worker::returnHome(%this)
{
   // toggle that it is heading home
   %this.headingHome = true; 
   // grab the object's base
   %home = %this.team.base;
   // tell it to moveTo home and trigger a callback
   %this.moveTo(%home.getPosition(), %this.speed, true, true);            
}

// --------------------------------------------------------------------
// Worker::returnedFromMining()
//
// This is called when our object has reached it's destination
// and headingHome is toggled to true
// --------------------------------------------------------------------
function Worker::returnedFromMining(%this)
{
   // We check if it is carrying gold
   if(%this.carrying $= "gold")
   {
      // lets deposit the gold into it's base and reset what it is carrying
      %this.team.base.depositGold(%this.team.base, %this.carryingAmmount);
      %this.carrying = "";
      %this.carryingAmmount = 0;

      // we end by sending our object back to mine
      %this.action("goToMine");      
   }
}

// --------------------------------------------------------------------
// Worker::stopMining()
//
// This will tell our worker to cease all mining activities and
// resets the proper values
// --------------------------------------------------------------------
function Worker::stopMining(%this)
{
   // we reset all the values needed
   %this.mining = false;
   %this.carrying = false;
   %this.carryingAmmount = 0;
   %this.headingHome = false;
   %this.headingToMine = false;

   // here we check if a mining event is pending, if so we cancel it
   if(isEventPending(%this.miningSchedule))
      cancel(%this.miningSchedule);   
}

// --------------------------------------------------------------------
// Worker::resetAllActions()
//
// This will reset all of our actions
// --------------------------------------------------------------------
function Worker::resetAllActions(%this)
{
   // stop mining
   %this.action("stopMining");  
}
}}
<b>[[Torque_2D/GenreTutorials/StrategyActions#Gold_mining_script_file_references|Back]]</b>