Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- $botstate_Wait = 0;
- $botstate_Moving = 1;
- $botstate_fire = 2;
- $botstate_ceacefire = 3;
- $botstate_PathToNearest = 4;
- $botstate_Wander = 5;
- $botstate_Confused = 6;
- $botStateDuration[$botstate_Wait] = 500;
- $botStateDuration[$botstate_fire] = 32;
- $botStateDuration[$botstate_ceacefire] = 32;
- $botStateDuration[$botstate_PathToNearest] = 32;
- $botStateDuration[$botstate_Wander] = 128;
- $botStateDuration[$botstate_Confused] = 128;
- $botStateDuration[$botstate_Moving] = 128;
- $showBotStates = false;
- function AIPlayer::customAiSpawn(%spawn, %datablock)
- {
- if (!isObject(%datablock)) %datablock = DemoPlayer;
- // Create the demo player object
- %player = new AiPlayer()
- {
- dataBlock = %datablock;
- position = %spawn.getTransform();
- isBot = true;
- repathTolerance = %datablock.repathTolerance;
- searchTolerance = %datablock.searchTolerance;
- hieghtPreference = %datablock.hieghtPreference;
- mMoveTolerance = 0.25;
- MoveStuckTolerance = %datablock.maxForwardSpeed * 0.9;
- moveStuckTestDelay = %datablock.stuckTimeWait;
- team = 2;
- deployed = true;
- AttackRadius = %datablock.fireTolerance;
- mutter = %datablock.mutter;
- mutterCount = %datablock.mutterCount;
- mutterTime = 0;
- mutterFreq = %datablock.mutterFreq;
- mutterProb = %datablock.mutterProb;
- haterix = %datablock.haterix;
- };
- //%player.playAudio(1, %datablock.ambientAudio);
- MissionCleanup.add(%player);
- //are we stuck?
- %player.stuck = 0;
- %obj.irritated = false;
- //give the Ai a rifle
- %player.mountImage(%datablock.weapon, 0);
- if (%datablock.dualWeapons)
- %player.mountImage(%datablock.altWeapon, 1);
- //pause a moment to let behind the scene stuff work out
- %player.schedule(1000, "aiStartUp");
- %player.skin = addTaggedString(%datablock.getBotSkin());
- %player.setSkinName(%player.skin);
- WalkaboutIgnore(%player,false);
- return %player;
- }
- function AIPlayer::Muttering(%this)
- {
- if (%this.mutterTime == 0) %this.mutterTime = $Sim::Time;
- if (($Sim::Time - %this.mutterTime)> %this.mutterFreq)
- {
- if (getrandom() < (%this.mutterProb))
- {
- %trackNum = getrandom(5);
- if (%this.irritated) %trackNum +=5;
- %track = %this.mutter @ %trackNum;
- %this.playAudio(0, %track);
- }
- %this.mutterTime = $Sim::Time;
- }
- }
- function AIPlayer::aiStartUp(%this)
- {
- if(!isObject(%this)||(%this.getState() $="Dead")) return;
- //here the Ai is going to decide what to do when it spawns
- //tool up with some bullets
- %this.setInventory("aiAmmo", 65535);
- %this.setInventory("aiAmmoClip", 65535);
- %this.manager = $SAI;
- %this.manager.addBot(%this);
- %this.enemy = -1;
- %this.canfire = true;
- %this.setstate($botstate_PathToNearest);
- %this.playThread( 1,"gears");
- }
- //reactive callbacks
- function AIData::onReachDestination(%this,%obj)
- {
- if(!isObject(%obj)||(%obj.getState() $="Dead")) return;
- }
- function AIData::onPathFailed(%this,%obj)
- {
- //error("AIData::onPathFailed - "@%obj);
- //if (isObject(%obj.enemy)) %obj.setMoveDestination(%obj.enemy.getWorldBoxCenter());
- %obj.setstate($botstate_Wander);
- %obj.enemy = -1;
- }
- function AIData::onPathSuccess(%this,%obj)
- {
- //error("AIData::onPathSuccess - "@%obj);
- %obj.setstate($botstate_Moving);
- }
- function AIData::onMoveStuck(%this,%obj)
- {
- if(!isObject(%obj)||(%obj.getState() $="Dead")) return;
- //echo( %obj @ " onMoveStuck");
- %obj.setstate($botstate_Wander);
- %obj.clearAim();
- %offset = (getRandom()-0.5)*4 SPC (getRandom()-0.5)*4 SPC 0;
- %pos = vectorAdd(%obj.getposition(), %offset);
- %obj.setMoveDestination(%pos);
- }
- function AIData::onTargetInRange(%this,%obj)
- {
- if (!isObject(%obj.enemy))
- {
- %obj.setstate($botstate_PathToNearest);
- return;
- }
- //we're close. stop moving.
- %obj.targInRange = true;
- %targ = %obj.enemy;
- %targPos = %targ.getPosition();
- %objPos = %obj.getPosition();
- if (%obj.checkInLos(%obj.enemy))
- %obj.aimAt(%obj.enemy);
- }
- function AIData::onTargetInFiringRange(%this,%obj)
- {
- if (!isObject(%obj.enemy))
- {
- %obj.setstate($botstate_PathToNearest);
- return;
- }
- %targ = %obj.enemy;
- %targPos = %targ.getPosition();
- %objPos = %obj.getPosition();
- if (%obj.checkInLos(%obj.enemy))
- %obj.aimAt(%obj.enemy);
- }
- function AIData::onTargetEnterLOS(%this,%obj)
- {
- if (!isObject(%obj.enemy))
- {
- %obj.setstate($botstate_PathToNearest);
- return;
- }
- %dist = %obj.getTargetDistance(%obj.enemy);
- if (%dist < %this.fireTolerance)
- %obj.setstate($botstate_fire);
- }
- function AIData::onTargetExitLOS(%this,%obj)
- {
- %obj.clearAim();
- %offset = (getRandom()-0.5)*4 SPC (getRandom()-0.5)*4 SPC 0;
- %pos = vectorAdd(%obj.getposition(), %offset);
- %obj.setMoveDestination(%pos);
- %obj.setstate($botstate_Wander);
- }
- function AIData::onDamage(%this, %obj, %delta)
- {
- if(!isObject(%obj)) return;
- %obj.setstate($botstate_PathToNearest);
- if(%obj.getstate() $="Dead")
- {
- //take finger off trigger
- %obj.setImageTrigger(0, 0);
- $curKills++;
- updateKillScore();
- tryUnlock();
- }
- %obj.clearAim();
- %obj.enemy = -1;
- %percentTrauma = %delta/%this.maxDamage;
- %centerpoint = %obj.getWorldBoxCenter();
- %normal[0] = "0.0 0.0 1.0";
- %abNormal[0] = "2.0 2.0 0.0";
- %normal[1] = "0.0 1.0 0.0";
- %abNormal[1] = "2.0 0.0 2.0";
- %normal[2] = "1.0 0.0 0.0";
- %abNormal[2] = "0.0 2.0 2.0";
- %normal[3] = "0.0 0.0 -1.0";
- %abNormal[3] = "2.0 2.0 0.0";
- %normal[4] = "0.0 -1.0 0.0";
- %abNormal[4] = "2.0 0.0 2.0";
- %normal[5] = "-1.0 0.0 0.0";
- %abNormal[5] = "0.0 2.0 2.0";
- %clientCount = ClientGroup.getCount();
- for (%i=0;%i<6;%i++)
- {
- %normalScaled = VectorScale(%normal[%i],-2);
- %targetPoint = VectorAdd(%centerpoint,%normalScaled);
- %mask = $TypeMasks::StaticObjectType | $TypeMasks::TerrainObjectType;
- %hitObject = ContainerRayCast(%centerpoint, %targetPoint, %mask, %obj);
- if (%hitObject)
- {
- %splatterPoint = getWords(%hitObject,1,3);
- %splatterNorm = getWords(%hitObject,4,6);
- %splatterVary = getRandom()*getword(%abNormal[%i],0)-getword(%abNormal[%i],0)/2 SPC getRandom()*getword(%abNormal[%i],1)-getword(%abNormal[%i],1)/2 SPC getRandom()*getword(%abNormal[%i],2)-getword(%abNormal[%i],2)/2;
- %Decalposition = VectorAdd(%splatterPoint, %splatterVary);
- for (%clientIndex = 0; %clientIndex < %clientCount; %clientIndex++)
- {
- %client = ClientGroup.getObject(%clientIndex);
- %ghostIndex = %client.getGhostID(%obj);
- commandToClient(%client,'Spatter', %Decalposition, %splatterNorm, %percentTrauma);
- }
- }
- }
- %obj.damagemark+=%delta;
- // If the pain is excessive, let's hear about it.
- if ((%obj.damagemark > (%this.maxDamage/3))||(%delta > 10))
- {
- %obj.irritated = true;
- %obj.damagemark = 0;
- %obj.playPain();
- }
- }
- function AIData::onDisabled(%this, %obj, %state)
- {
- if(isObject(%obj.effectron)) %obj.effectron.interrupt();
- if (isObject(%obj.elementalEffect)) %obj.elementalEffect.interrupt();
- %obj.manager.removeBot(%obj);
- %obj.stop();
- Parent::onDisabled(%this, %obj, %state);
- }
- //planning
- function AIPlayer::aiDecide(%this)
- {
- if(!isObject(%this)||(%this.getState() $="Dead")) return;
- if (%this.isFalling) return;
- %this.Muttering();
- if(!isObject(%this.enemy))
- {
- %this.enemy = -1;
- %this.setstate($botstate_PathToNearest);
- }
- if (%this.confused) %this.setstate($botstate_Confused);
- if (%this.nextCommandTime>$Sim::Time) return;
- switch(%this.botstate)
- {
- case $botstate_Moving:
- if( VectorLen(%this.getVelocity()) > 0.1 )
- {
- NavmeshUpdateAll(%this,true);
- %this.moving = true;
- return;
- }
- else
- {
- %this.moving = false;
- %this.setstate($botstate_PathToNearest);
- }
- case $botstate_Confused:
- %this.randomPath();
- case $botstate_fire:
- %this.aiShoot();
- case $botstate_Wander:
- %this.randomPath();
- case $botstate_PathToNearest:
- %this.PathToNearest();
- default:
- %this.setstate($botstate_Wander);
- }
- }
- function AIPlayer::setstate(%this,%state)
- {
- if (!%this.inState(%state)) %this.nextCommandTime = $Sim::Time + $botStateDuration[%state]/1000;
- %this.laststate = %this.botstate;
- %this.botstate = %state;
- if ($showBotStates) %this.setShapeName(%state);
- }
- function AIPlayer::inState(%this,%state)
- {
- if (%this.botstate == %state) return true;
- return false;
- }
- function AIPlayer::hateBias(%this,%enemy)
- {
- %hate = 1;
- %DB = %enemy.getDataBlock();
- if (isObject(%this.haterix))
- {
- %hateEntry = %this.haterix.getIndexFromKey(%DB.classname);
- if (%hateEntry == -1) error("No hate entry for:" SPC %DB.classname);
- %hate = %this.haterix.getValue(%hateEntry);
- if (%hate == -1) error("No hate value for:" SPC %DB.classname);
- }
- else
- {
- error("I bring you love! (No haterix found)");
- }
- if (%this.damageTaken[%enemy])
- {
- %hate += %this.damageTaken[%enemy]*10;
- }
- if ( %DB.isMethod( "getHateMod" )) %hatemod = %DB.call("getHateMod");
- if (%hatemod)
- %hate *= %hatemod;
- %hate = ((101-%hate)/100);
- return %hate;
- }
- function AIPlayer::losBias(%this,%enemy)
- {
- %bias = 1;
- //can we see them?
- if(%this.checkInLos(%enemy))
- %bias = %bias / (%this.getdatablock().losPreference+1);
- return %bias;
- }
- function AIPlayer::FoVBias(%this,%enemy,%fov)
- {
- %bias = 1;
- //can we see them?
- if(%this.checkInFoV(%enemy,%fov))
- %bias = %bias / (%this.getdatablock().losPreference+1);
- return %bias;
- }
- function AIPlayer::getNearestTarget(%this)
- {
- if(!isObject(%this)||(%this.getState() $="Dead")) return false;
- %index = -1;
- %enemyID = -1;
- %tempDist = 0;
- %dist = %this.searchTolerance;
- %ourPos = %this.getWorldBoxCenter();
- for(%i = 0; %i < %this.manager.targetList.count(); %i++)
- {
- //get the ID from the array
- %enemy = %this.manager.targetList.getKey(%i);
- if((%enemy != %this)&&(isObject(%enemy))&&(%enemy.deployed))
- {
- %enemyPos = %enemy.getWorldBoxCenter();
- %tempDist = VectorDist(%enemyPos, %ourPos);
- %actualdist = %tempDist;
- //keep your friends close, and your enemies 'closer'
- %hatebias = %this.hateBias(%enemy);
- %tempDist = %tempDist * %hatebias;
- %fovCheck = %this.FoVBias(%enemy,90);
- %tempDist = %tempDist * %fovCheck;
- //if (%fovCheck != 1)
- //%tempDist = %tempDist * %this.losBias(%enemy);
- if ((%tempDist < %dist)&&(%actualdist<%this.searchTolerance))
- {
- //echo(%this @ " finds closer enemy " @ %enemy @ " than previous " @ %enemyID);
- %dist = %tempDist;
- %index = %i;
- %enemyID = %enemy;
- }
- }
- }
- if (!isObject(%enemy)) %enemyID = -1;
- //if (%enemyID == -1) error("no target found!");
- return %enemyID;//return the closest enemy or else return -1;
- }
- function AIPlayer::getROF(%this)
- {
- if (%this.getDatablock().rof)
- %Rof = (1000/%this.getDatablock().rof);
- else
- %Rof = 1000;
- return %Rof;
- }
- //actions
- function AIPlayer::aiShoot(%this)
- {
- if(!isObject(%this)||(%this.getState() $="Dead")) return;
- if(!isObject(%this.enemy)||(%this.enemy.getDamageState() !$="Enabled")||(!%this.enemy.deployed))
- {
- %this.setstate($botstate_PathToNearest);
- return;
- }
- %RoF = %this.getROF();
- if (%this.controled)
- %Rof = %Rof * %this.controler.getDatablock().getTriggerHappyMul();
- if(%this.canfire)
- {
- if (!%this.getDatablock().movefire)
- {
- %this.stop();
- %this.moving = false;
- }
- %this.setImageTrigger(0, true);
- if (%this.getDatablock().dualWeapons)
- {
- %this.schedule(%Rof/2,"setImageTrigger", 1, true);
- }
- %this.lockOutWeapon(true, %Rof);
- }
- %this.setstate($botstate_PathToNearest);
- }
- function AIPlayer::aiStopShoot(%this)
- {
- if(!isObject(%this)||(%this.getState() $="Dead")) return;
- }
- function AIPlayer::lockOutWeapon(%this,%flag,%duration)
- {
- cancel(%this.lockoutTime);
- %this.canfire = !%flag;
- if(%flag)
- {
- %this.setImageTrigger(0, false);
- if (%this.getDatablock().dualWeapons)
- %this.setImageTrigger(1, false);
- %this.lockoutTime = %this.schedule(%duration,"lockOutWeapon",false,%duration);
- }
- }
- function AIPlayer::PathToNearest(%this)
- {
- if(!isObject(%this)||(%this.getState() $="Dead")) return false;
- %enemy = %this.getNearestTarget();
- if ((%this.enemy == %enemy)&&(%this.moving)) return true;
- %this.stop();
- %this.enemy = %enemy;
- %this.followObject(%this.enemy, %this.repathTolerance);
- %this.moving = false;
- return true;
- }
- function AIPlayer::randomPath(%this)
- {
- if(!isObject(%this)||(%this.getState() $="Dead")) return;
- %this.currentNode = 0;
- %this.targetNode = 0;
- %start = %this.getPosition();
- //get a random goal, count available up
- %count = %this.manager.targetList.count();
- %index = getRandom(0, %count-1);
- %enemy = %this.manager.targetList.getKey(%index);
- %this.stop();
- %this.enemy = %enemy;
- %this.followObject(%this.enemy, %this.repathTolerance);
- }
- function AIPlayer::randomPoint(%this, %duration)
- {
- if(!isObject(%this)||(%this.getState() $="Dead")) return;
- %this.stop();
- %this.enemy = -1;
- %offset = (getRandom()-0.5)*10 SPC (getRandom()-0.5)*10 SPC 0;
- %pos = vectorAdd(%this.getposition(), %offset);
- %this.setMoveDestination(%pos);
- %this.nextCommandTime = $Sim::Time + %duration;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement