Game Development Community

Tit for Tat AI or Total Warfare

by Dreamer · in RTS Starter Kit · 11/10/2005 (3:02 am) · 4 replies

After creating the scripted AI earlier, I decided to make it do something.
In the interests of creating something useful I decided to have AI players yell for help when attacked, and have thier comrades come running into battle.
That wasn't as useful as I had hoped so, I extended this to create Total Warfare, in this mod everyone yells for help. It's most interesting if you spawn the same number of units for both player and AI.
Here ya go.
At the bottom of server/scripts/core/game.cs add the following.
//--------------------------------------------------------------
//Misc. Game AI functions 
//--------------------------------------------------------------

//Shout for help!
function AIShoutForHelp(%shouter,%target,%AI){
     //%searchMasks = -1;
     %searchMasks = $TypeMasks::PlayerObjectType;
    %radius = 5000;
     InitContainerRadiusSearch(%shouter.getPosition(), %radius, %searchMasks);
    while ((%NewObject = containerSearchNext()) != 0){
	%id = %NewObject.getId();
	if(%id.getTeam() == %shouter.getTeam() && %id.isBuilding != 1 && !isObject(%id.getAimObject())){
		AISetToAttack(%id,%target);
		echo(%id@" says help is on the way!");
	}
   }
   //%id.dump();	
}

//Setup AI for Attack
function AISetToAttack(%obj,%sourceObject){
	%obj.stopAll();
	%obj.setAimObject(%sourceObject);
	%obj.getDatablock().onAttack(%obj,%sourceObject);
}

Now in server/scripts/avatars/player.cs find the RTSUnitData::damage function and add this.
if(!isObject(%obj.getAimObject()){
	AISetToAttack(%obj,%sourceObject);
}
AIShoutForHelp(%obj,%sourceObject,%obj.isAI);  //This line could start a war!

In the same file replace the RTSUnitData::onDamage function and replace it with this one.
function RTSUnitData::onDamage(%this, %obj, %delta){
   if(%obj.isAI !=1){
   	messageClient(%obj.client, 'MsgUnitAttacked', "", getWords(%obj.getPosition(), 0, 2));
   }
}

Finally open bots.cs, rifleman.cs and shocker.cs and replace the %target.applyDamage line with this one.
%target.damage(%attacker,0,%damage,"MELEE");

Thats it! Enjoy your mutually assured destruction!

#1
01/25/2006 (5:39 am)
LOL this is really cool Dreamer, thanks!
#2
04/11/2006 (10:17 pm)
Hmmm... I tried to get this code working, but without success.

From what I can tell, the RTSUnitData::damage function doesn't ever seem to get called. This is with or without your code.

Without that function call the AIShoutForHelp function never gets called, and therefore never calls for help. Any ideas on what I might be doing wrong?

-Nick
#3
01/31/2010 (3:48 pm)
Hah - it works, too good ... when I tell one of my units to attack another, everything including nearby buildings "move" to pounce on the unit.

I added a isBuilding=true to all the datablocks for the buildings, but still happening.

Its a good start though ... that if statement above is missing a ")" which the compiler is happy to point out.
#4
01/31/2010 (6:29 pm)
the call to getClientIndex() returns "-1" for some reason .... so play spawns in as team 0 and AI as team (-1) ... I hard coded it to (1) for now and seems to work ok.