It contains just the code to control communications, lifepoints and the rules for attacking.
Current implemented attacks (kindof hardcoded for now):
- proximitystrike (hits nearest object closer than 2m)
- farstrike (hits nearest object, up to really far, does less damage than proximitystrike, instantaneous)
It could probably be broken up in a couple of modules or more, so look out for future versions.
There are some hardcoded constants at the top for now.
Antipersonnel: whether attacks AGENTS or SCRIPTED
ModeWornOnPlayer: whether this is an avatarattachment. If yes, it will do death animations when you die.
I guess this is public domain but Id prefer to see derivatives posted if possible; you only have to kill the channel number to protect your system's privacy. Remember that if you derive from this and post it back, it's more likely to get into future updated versions!!!
You need a driver module for this by the way. Example driver module (robot AI) to be posted in next thread.
Future versions will include increased attack types (eg projectiles and spells) and increased attack diversity.
This code includes examples of:
- argument multiplexing/demultiplexing
- LinkMessages
- Sensors
Channel number has been changed to protect the innocent.
CODE
integer Channel = 1;
integer LifePoints = 100;
integer AntiPersonnel = FALSE;
key Playerid;
string PlayerName;
integer DeadOn = FALSE;
integer ModeWornOnPlayer = TRUE;
float LastAttack = 0;
integer ChannelListener;
float DeathTime = 10.0;
string AttackType;
float CoolDown = 0.5;
TellPlayer( string Message )
{
llWhisper(0,PlayerName + ", " + Message );
}
TellOwner( string Message )
{
// llInstantMessage( Playerid, Message );
}
Init()
{
if( ModeWornOnPlayer )
{
Playerid = llGetOwner();
llRequestPermissions(Playerid,
PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS);
}
else
{
Playerid = llGetKey();
}
PlayerName = llKey2Name( Playerid );
llSetText( "Life: " + (string)LifePoints, <4,0,0>,1.0);
llSetStatus( STATUS_PHYSICS, TRUE );
}
ReduceLife( integer PointsToRemove, key Attackerid )
{
// TellPlayer( "You were " + AttackType + " for " + (string)Power + " points of damage");
LifePoints = LifePoints - PointsToRemove;
//llSay(0, AttackType );
// llSay(0, PlayerName + " " + AttackType + " for " + (string)Power + " by " + llKey2Name(Attackerid) );
// TellPlayer( "Life remaing: " + (string)LifePoints);
if(LifePoints <= 0 )
{
// llListenRemove( ChannelListener );
llSetText( "-- Dead --", <4,0,0>,1.0);
TellPlayer( "You are dead. Please wait...");
llShout( Channel, "KILLED" +"-=-" + (string)llFrand(1000.0) + "-=-" + (string)Attackerid + "-=-" + (string)Playerid );
//TellPlayer( "LOADING. PLEASE WAIT...");
//llShout(0, "Player " + PlayerName + " has been mercilessly slaughtered!" );
if( ModeWornOnPlayer )
{
llStartAnimation( "dead" );
llMoveToTarget( llGetPos(), 0.2 );
}
DeadOn = TRUE;
llSleep(DeathTime);
DeadOn = FALSE;
if( ModeWornOnPlayer )
{
//llMoveToTarget( llGetPos() + <0,0,20>, 0.2);
// llSleep(DeathTime);
llStopAnimation("dead");
llStopMoveToTarget();
}
// TellPlayer( "Ressurection completed" );
// llShout( Channel, "RESURRECTED-=-" + (string)llFrand(1000.0) +"-=-" + (string)Playerid +"-=-" ) ;
//llShout(0, "Player " + PlayerName + " has re-entered the arena" );
LifePoints = 100;
ChannelListener = llListen( Channel, "","","");
llSetText( "Life: " + (string)LifePoints, <4,0,0>,1.0);
}
else
{
llSetText( "Life: " + (string)LifePoints, <4,0,0>,1.0);
// llSay(0, PlayerName + " Life: " + (string)LifePoints);
}
}
default
{
state_entry()
{
llListen( Channel, "","","" );
Init();
}
on_rez( integer param )
{
Init();
}
link_message( integer sender_num, integer num, string message, key sender_id )
{
list Arguments;
Arguments = llParseString2List( message, ["-=-"],[] );
string Command;
Command = llList2String( Arguments, 0 );
if( !DeadOn )
{
if( LastAttack < llGetTimeOfDay() - CoolDown )
{
LastAttack = llGetTimeOfDay();
if( Command == "PROXIMITYSTRIKE" )
{
AttackType = "SWORDSTRIKE";
}
else if( Command == "REPULSE" )
{
AttackType = "REPULSE";
}
else if( Command == "FARSTRIKE" )
{
// llSay( 0, "Farstriking...");
vector TargetPos;
// TargetPos = (vector)llList2String( Arguments, 1 );
AttackType = "FARSTRIKE";
}
if( AntiPersonnel )
{
llSensor("","",AGENT,20.0,PI);
}
else
{
llSensor("","",SCRIPTED,20.0,PI);
}
}
}
}
listen( integer channel, string name, key id, string message )
{
list Arguments;
Arguments = llParseString2List( message, ["-=-"],[] );
string Command;
Command = llList2String( Arguments, 0 );
if( Command == "ATTACK" )
{
key Targetid;
integer Power;
string AttackType;
string Attackerid;
Attackerid = (key)llList2String(Arguments,1);
Targetid = (key)llList2String(Arguments,2);
Power = (integer)llList2String(Arguments,4);
AttackType = llList2String(Arguments,3);
//TellOwner("Target id = " + (string)Targetid );
if( Playerid == Targetid )
{
ReduceLife( (integer)Power, Attackerid );
}
}
else if( Command == "FARSTRIKE" )
{
vector AttackPos;
integer Power;
key AttackerId;
AttackerId = (key) llList2String(Arguments,1);
AttackPos = (vector)llList2String( Arguments, 2 );
Power = (integer)llList2String(Arguments,3);
// llSay( 0,"Attackpos = " + (string)AttackPos );
vector DifferenceFromAttack;
DifferenceFromAttack = llGetPos() - AttackPos;
float DistanceFromAttack;
DistanceFromAttack = llVecMag( DifferenceFromAttack );
// llSay( 0, (string)DistanceFromAttack );
if( DistanceFromAttack < 0.5 )
{
ReduceLife( (integer)Power, AttackerId );
}
}
}
sensor(integer num_detected)
{
integer TargetFound = FALSE;
key Targetid;
string TargetName;
TargetFound = FALSE;
integer i;
i = 0;
while( TargetFound == FALSE && i < num_detected )
{
//llSay( 0,"CandidateTarget:" + llDetectedName(i) );
//if( llDetectedName(i) == "Orc21" )
//{
TargetFound = TRUE;
Targetid = llDetectedKey(i);
TargetName = llDetectedName(i);
//}
i++;
}
if( TargetFound )
{
if( AttackType == "SWORDSTRIKE" )
{
// llSay(0, "Attacking a " + TargetName );
integer Damage;
Damage = (integer)llFrand( 20.0 ) + 5;
llShout( Channel, "ATTACK" + "-=-" + (string)Playerid + "-=-" + (string)Targetid + "-=-struck-=-" + (string)Damage);
// llPlaySound( "swordhit", 1.0);
}
else if( AttackType == "FARSTRIKE" )
{
// llSay(0, "Farstriking a " + TargetName );
integer Damage;
Damage = (integer)llFrand( 8.0 );
llShout( Channel, "FARSTRIKE" + "-=-" + (string)Playerid + "-=-" + (string)llDetectedPos(0) + "-=-" + (string)Damage);
// llPlaySound( "swordhit", 1.0);
}
else if( AttackType == "REPULSE" )
{
llSay(0, "Pushing " + TargetName );
llPushObject(Targetid, <50,0,0>, ZERO_VECTOR, TRUE);
}
}
// else
// {
// llSay(0,"Nothing found...");
// }
//else
//{
//}
}
}