Pawns die upon spawn and another issue

Topics regarding Scripting with Reality Factory
Post Reply
incenseman2003
Posts: 320
Joined: Sat Mar 11, 2006 11:41 pm

Pawns die upon spawn and another issue

Post by incenseman2003 »

I have 2 issues that I find odd to say the least.

1st issue:
I put a robot in a one room level and use the robot.s script to run it. It will run fine if it is standing in one part of the level but if I move it to the other end of the room (for example) it dies upon spawning in. I have created 55 different one room levels and get the same issue in all of them.


2nd issue:
I have my own pawn and I use a modified perfectai.s to run it. If I set the perfectai.s to target the robot pawn group it works perfect. I made a copy of the same perfectai.s renamed it perfectai2.s and set it to target the soldier group and set the group of it to robot. I then put 2 of that pawn in the same level. One is run by the perfectai.s and the other is run by the perfectai2.s. They did target each other and did run toward each other. They did shoot at each other. Here is the issue. The projectiles did not go far enough to hit each pawn but against the robot pawns they did. Then the pawns stop firing and just stand there.


Has anyone else seen these issues, and is there a way to fix them? If so please give some detail on how to fix them.
Patience and tolerance are the keys to the passage of knowledge. Even those that are the most knowledgeable started with many questions.
User avatar
Juutis
Posts: 1511
Joined: Thu Jan 12, 2006 12:46 pm
Location: Finland

Post by Juutis »

2nd issue:
I have my own pawn and I use a modified perfectai.s to run it. If I set the perfectai.s to target the robot pawn group it works perfect. I made a copy of the same perfectai.s renamed it perfectai2.s and set it to target the soldier group and set the group of it to robot. I then put 2 of that pawn in the same level. One is run by the perfectai.s and the other is run by the perfectai2.s. They did target each other and did run toward each other. They did shoot at each other. Here is the issue. The projectiles did not go far enough to hit each pawn but against the robot pawns they did. Then the pawns stop firing and just stand there.
So you first tested with you own actors (pawn models), but the bullets didn't fly far enough and then you tested with both pawns having the robot actor ?
Or did I get something wrong once again? :)

Well anyway, you can make sure the projectiles fly far enough by increasing the 'speed' and 'lifetime' of the projectiles shot by the pawns in weapon.ini.
If that doesn't help, I would think the problem is in the shooting bones and pawns being hit by their own projectiles. Make sure the point where the projectile is launched is outside the pawn's bounding box. Give it some Z offset to move it further away from the pawn.

Then the pawns' dying... that happens with the robot actor, right?
The only explanation I can think of is that the pawns don't have the death animation you have defined in the script. Then they would try to play animation X, but because it is not found, they just end up playing the default animation, which is standing.


And please, do tell me if I got the whole thing all wrong. I hope I helped even a tiny bit... :D


***EDIT***OFFTOPIC***
Woho! My 400th post! :D
Pain is only psychological.
incenseman2003
Posts: 320
Joined: Sat Mar 11, 2006 11:41 pm

Post by incenseman2003 »

I did get the perfectai.s to work for my pawns just the way I need it to. When my pawns fire at the robots that are run by the robot.s the projectiles fly as far as they need to and kill the robots. It is only when I set my pawns up to fight each other that I have the issue that the projectiles dont go far enough and they stop shooting and just stand there after a while. Please understand that they do run to attack each other and they do shoot at each other to start with, then all of a sudden they just quit shooting and stand there.

As for the robots dying when the spawn in. They fall down dead at the second they spawn in. It only happens when they are standing in certain places in the level. If I made a one room level the robot would be fine when it spawns in. If I just move it to the other end of the room, it dies the instant that it spawns into the level. Thats really all there is to the issue. Makes no sense to me that where the robot stands should make a difference. Bare in mind that it just a room, nothing in it, no doors and no windows. Just the robot and me.


Edit 11:42 AM 1/10/2007:
It seems that I did something to the robot.s that caused some random behavior. Im not sure what it is that I did. I just replaced it with a fresh one from the backup of my RF dir. Seems to work fine now.

I do still have the issue as follows:
I have 2 of my own pawns in a single room level.
One is run by the perfectai.s and is set up to attack the robot group and is set to be in the soldier group.
The other is run by a copy of perfectai.s called perfectai2.s and it is setup to a attack the soldier group and is set to be in the robot group.
When the 2 pawns see each other they run to attack each other.
They shoot 2 or 3 shots and the stop and just stand there.
They are both still alive.

If the pawn is run by perfectai.s and will attack a robot pawn until it dies then they should do the same to each other. Right?

Also when my pawn is shot by the robots exactly 3 times the game crashes and there is no errors in the RealityFactory.log. I have confirmed that all of the animations and sounds that I gave the pawn are properly placed and I dentified in the script.

I would have posted the script for whoever wants to look at it but this forum said "The Extension s is not allowed" and "The Extension txt is not allowed". So I pasted the whole thing here.

---------------------------------
{
// Perfect AI
// by Peter Coleman
// monster will fire missiles or melee if close enough
// Changes to ai-run and Check-Any-Attack


SCALE [1] // scale of actor
GROUP [soldier] // name of monster group
BOXWIDTH [25] // width and depth of bounding box
HOSTILEPLAYER [false] // hostile to player
HOSTILEDIFFERENT [false] // hostile to different Pawn group
HOSTILESAME [false] // hostile to same Pawn group
HEALTHATTRIBUTE [health] // name of health attribute
HEALTH [100] // initial amount of health
SIGHTDIST [2000] // max distance monster can see at idle
ALERTSIGHTDIST [1500] // max distance monster can see when alert
FOV [360] // field of view in degrees
ATTACKFOV [360] // attacking field of view
YAWSPEED [360] // speed of rotation in deg/sec
DAMAGEATTRIBUTE [enemy_health] // attribute damaged by attack
ALERTTRIGGER [AlertG] // name of alert trigger

// define the type of monster this will be

ATTACKTYPE [missile] // type of attack - melee or missile
PATROL [true] // false - ambush or true - patrol
PC [0] // make any visible point the next point

// idling and turning

STAND [idle] // idle animation
TURNL [idle] // turn left animation
TURNR [idle] // turn right animation

// when in pain

PAIN [pain_head] // pain animations
PAIN1 [pain_stomach]
PAIN2 [pain_head]
PAIN3 [pain_stomach]
PAINPERCENT [50] // percentage of time pain is shown
PAINSOUND [injury.wav] // sounds played when in pain
PAINSOUND1 [injury1.wav]
PAINSOUND2 [injury1.wav]
PAINSOUND3 [injury1.wav]

// when dying

DIE [die_backwards] // dying animations
DIE1 [die_spin]
DIE2 [die_backwards]
DIE3 [die_spin]
DIEHOLD [5] // time corpse still appears
DIEFADE [5] // fadeout time of corpse
DIESOUND [die1.wav] // sounds played when dying
DIESOUND1 [die1.wav]
DIESOUND2 [die1.wav]
DIESOUND3 [die1.wav]

// when running to attack

RUN [run] // running animation
RUNSPEED [200] // average run speed
RUNSOUNDDELAY [2] // delay between making sounds when running to attack
RUNSOUND [espark.wav] // sound played while running to attack

// when walking while patroling

WALK [walk] // walking animation
WALKSPEED [100] // average walking speed
WALKSOUND [espark.wav] // walking sound

// the projectile attack mode

MISSILEATTACK [idle] // missile attacking animations
MISSILEATTACK1 [idle]
MISSILEATTACK2 [idle]
SHOOTUP [idle]
SHOOTDOWN [idle]
FIREDELAY [0.3] // delay after animation starts before

projectile launch
FIREDELAY1 [0.3]
FIREDELAY2 [0.3]
MISSILESOUND [weapon\deagle.wav] // sounds played when shooting
MISSILESOUND1 [weapon\deagle.wav]
MISSILESOUND2 [weapon\deagle.wav]
MISSILERANGE [900] // max distance to start missile attack
PROJECTILE [10mm_shell] // projectile name
FIREBONE [Bip01 R Finger1] // projectile launch bone
OFFSETX [0] // launch offsets
OFFSETY [0]
OFFSETZ [0]
ATTACKDELAY [0.3] // time between shots
SKILL [5] // skill level 1 to 10

// the melee attack mode

MELEEATTACK [ref_shoot_kick_blend1] // melee attacking animations
MELEEATTACK1 [punches]
MELEEATTACK2 [jab]
MELEESOUND [injury.wav] // sounds played when melee attacking
MELEESOUND1 [injury.wav]
MELEESOUND2 [injury.wav]
MELEERANGE [55] // max distance to start melee attack
//MAXMELEERANGE [100] // max distance for melee mode
MINMELEEDAMAGE [25] // minimum amount of damage per melee attack
MAXMELEEDAMAGE [25] // maximum amount of damage per melee attack
MELEEDELAY [1] // number of seconds between melee damages
MELEEDAMAGESOUND [injury.wav] // sound played when damage is done

// search for enemy

LOSTTIME [10] // time to search for enemy before giving up
POINTRADIUS [20] // radius from point when considered there

// obstacle avoidance forces for jumping

FORCEUP [15] // obstacle avoidance jump speed
FORCEFORWARD [20] // obstacle avoidance forward speed
FORCESIDE [20] // obstacle avoidance sideways speed

// local variables - do not change


RUNFUNC [monster_run_start] // monster run to attack function
MISSILEFUNC [monster_missile_start] // monster missile function
MELEEFUNC [monster_melee_start] // monster melee function
LOSTFUNC [monster_lost_target_start] // monster lost target function

AS_NONE [0]
AS_MELEE [1]
AS_MISSILE [2]
AS_STRAIGHT [3]
attack_delay [0]
melee_time [0]
lost_time [0]
back_up [false]
back_time [0]
left_time [0]
back_flag [false]
fire_delay [0]
skill_time [0]
attack_state [0]
run_sound_time [0]
missile_sound [NULL]

// spawn pawn and do setup work

Spawn[ ()
{
Console(false);
Scale(SCALE); // scale the actor
if(BOXWIDTH > 0)
{
BoxWidth(BOXWIDTH*SCALE); // set bounding box width/depth
}
AttributeOrder(HEALTHATTRIBUTE, HEALTH, "Death"); // give monster health
HostilePlayer(HOSTILEPLAYER); // set who monster is hostile to
HostileSame(HOSTILESAME);
HostileDifferent(HOSTILEDIFFERENT);
//TargetGroup("robot");
//HostileDifferent(true);
SetFOV(360,"Bip01 Head"); // set field of

view
SetGroup(GROUP); //

assign a group to belong to
FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // seen a target to chase
AddPainOrder("IdlePain", 100); // show pain

and trigger alert
AvoidOrder("Avoidance"); //

avoid obstacles
AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0); // go to alert when triggered
SetWeapon("Mp5k2"); // give the

monster a big gun
RotateToPoint(STAND, YAWSPEED, false, ""); // go to point if any specified
MoveToPoint(WALK, WALKSPEED*SCALE, WALKSOUND);
if(PATROL = true)
{
NewOrder("Patrol");
}
else
{
NewOrder("Idle");
}
} ]

// avoid objects when doing a MoveToPoint

Avoidance[ ()
{
if(random(1,10)<3) // backup and move sideways sometimes
{
MoveBackward(WALK, WALKSPEED*SCALE, (WALKSPEED/2)*SCALE, "");
MoveRight(WALK, WALKSPEED*SCALE, (WALKSPEED/2)*SCALE, "");
}
else
{
Jump(RUN, FORCEUP*SCALE, true, "");
if(random(1,10)<6)
{
Move("", FORCEFORWARD*SCALE, (FORCEFORWARD/2)*SCALE, 0, 90, 0, "");
}
else
{
Move("", FORCEFORWARD*SCALE, (FORCEFORWARD/2)*SCALE, 0, -90, 0, "");
}
}
Return();
} ]

// idle in place waiting for something to happen

Idle[ ()
{
PlayAnimation(STAND, true, "");
RestartOrder();
} ]

// walk the beat from point to point

Patrol[ ()
{
NextPoint();
RotateMoveToPoint(WALK, YAWSPEED, WALKSPEED*SCALE, false, WALKSOUND);
MoveToPoint(WALK, WALKSPEED*SCALE, WALKSOUND);
RestartOrder();
} ]

// show pain at idle then trigger to alert

IdlePain[ ()
{

NewOrder("FoundTarget");
} ]

// start shifting from idle to alert

IdleToAlert[ ()
{
NewOrder("FoundTarget");
} ]

// look around at alert looking for enemy

Alert[ ()
{
NewOrder("FoundTarget");
} ]

// show pain at alert

AlertPain[ ()
{
NewOrder("FoundTarget");
} ]

// timed out at alert

AlertToIdle[ ()
{
NewOrder("FoundTarget");
} ]

// found a target to attack

FoundTarget[ ()
{
SetFOV(360,"Bip01 Head"); // set field of view
LowLevel(RUNFUNC); // attack functions are low level
} ]

// lost target while attacking so go back to idle again

LostTarget[ ()
{
FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // seen a target to chase
FindPointOrder("Patrol"); // do point

stuff
if(PATROL = true)
{
NewOrder("Patrol");
}
else
{
NewOrder("Idle");
}
} ]

// you died

Death[ ()
{
//SetNoCollision(); // remove bounding box so there are no collisions with corpse
Remove = false; // remove actor
RemoveWeapon = false; // remove the current weapon actor.
return 0;
}]

// Low level attack routines

// Start of run to attack

monster_run_start[ ()
{
//TargetPlayer();
UpdateEnemyVis(true); //always aware of player position
UpdateTarget();
Animate(RUN); // play run animation
self.ThinkTime = 0; // start thinking on next frame
self.think = "monster_run"; // go to run attack routine
self.ideal_yaw = enemy_yaw; // set direction to run
self.yaw_speed = YAWSPEED; // set rotation speed
back_up = false; // initialize obstacle avoidance
attack_state = AS_NONE; // not attacking yet
melee_time = time;
run_sound_time = time;
} ]

// run to enemy to attack

monster_run[ ()
{
self.ThinkTime = 0;
if(self.health<=0)
{
self.think = "death_biz"; // dead
return 0;
}
if((self.in_pain = true) and (random(1,100)<PAINPERCENT))
{
self.think = "monster_run_pain_start"; // in pain
return 0;
}
if(EnemyExist(DAMAGEATTRIBUTE) < 3)
{ SetHoldAtEnd(true);
HighLevel("LostTarget"); // enemy is gone or dead
return 0;
}
if(enemy_vis = false)
{
self.think = LOSTFUNC; // lost sight of enemy
lost_time = time + LOSTTIME;
return 0;
}
if(run_sound_time < time)
{
if(random(1,10)>7)
{
run_sound_time = time + RUNSOUNDDELAY;
PlaySound(RUNSOUND);
}
}
ai_run(random((RUNSPEED-2)*SCALE,(RUNSPEED+2)*SCALE)); // run toward enemy
} ]

// start of pain while running

monster_run_pain_start[ ()
{
switch(random(1,4)) // play one of 4 pain animations
{
case 1
{
Animate(PAIN);
PlaySound("injury.wav", 500);
}
case 2
{
Animate(PAIN1);
PlaySound("injury.wav", 500);
}
case 3
{
Animate(PAIN2);
PlaySound("injury.wav", 500);
}
case 4
{
Animate(PAIN3);
PlaySound("injury.wav", 500);
}
}
SetHoldAtEnd(true); // set to stop at animation end
self.ThinkTime = 0;
self.think = "monster_run_pain";
} ]

// wait for animation to stop

monster_run_pain[ ()
{
self.ThinkTime = 0;
if(self.animate_at_end = true) // wait for end of animation
{
self.think = "monster_run_start"; // start running again
SetHoldAtEnd(false); // remove animation stop
self.ThinkTime = 0;
}
} ]

// start of lost sight of enemy routine

monster_lost_target_start[ ()
{
Animate(RUN); // play run animation
self.ThinkTime = 0; // start thinking on next frame
self.think = "monster_lost_target";
run_sound_time = time + RUNSOUNDDELAY;
} ]

// go to last known location of enemy

monster_lost_target[ ()
{
self.ThinkTime = 0;
if(lost_time<time)
{
HighLevel("LostTarget"); // timed out while looking
return 0;
}
self.ThinkTime = 0;
if(self.health<=0)
{
self.think = "death_biz"; // dead
return 0;
}
if((self.in_pain = true) and (random(1,100)<PAINPERCENT))
{
self.think = "monster_lost_pain_start"; // in pain
return 0;
}
if(EnemyExist(DAMAGEATTRIBUTE) < 3)
{
HighLevel("LostTarget"); // enemy died or was removed
return 0;
}
if(enemy_vis = true)
{
PlaySound("espark.wav", 500);
self.think = "monster_run_start"; // seen again so run to attack
self.ThinkTime = 0;
return 0;
}
if(run_sound_time < time)
{
if(random(1,10)>7)
{
run_sound_time = time + RUNSOUNDDELAY;
PlaySound(RUNSOUND);
}
}
if((enemy_range>POINTRADIUS) and (RUNSPEED > 0)) // get close to last known location
{
walk_movetogoal(random((RUNSPEED-2)*SCALE,(RUNSPEED+2)*SCALE));
}
else
{
HighLevel("LostTarget"); // can't find at last known location
return 0;
}
} ]

// start of showing pain while searching

monster_lost_pain_start[ ()
{
switch(random(1,4)) // play one of 4 pain animations
{
case 1
{
Animate(PAIN);
PlaySound("injury.wav", 500);
}
case 2
{
Animate(PAIN1);
PlaySound("injury.wav", 500);
}
case 3
{
Animate(PAIN2);
PlaySound("injury.wav", 500);
}
case 4
{
Animate(PAIN3);
PlaySound("injury.wav", 500);
}
}
SetHoldAtEnd(true); // set to stop at end
self.ThinkTime = 0;
self.think = "monster_lost_pain";
} ]

// wait till animation is done

monster_lost_pain[ ()
{
self.ThinkTime = 0;
if(self.animate_at_end = true) // animation done
{
self.think = "monster_lost_target_start"; // go back to finding target
SetHoldAtEnd(false); // remove stop at end
self.ThinkTime = 0;
}
} ]

CheckForPoints[()
{
self.ThinkTime=0; // Process every frame
if(self.point_vis)
{
// point is visible - go to high level for nav and targetting
HighLevel("LostTarget");
return 0;
}
else
{
// Point not visible - cycle points
PC=PC+1; // Increment point counter variable
if(PC > 110)
{
// Point count has exceeded max - set to 0. (Max 110)
PC=1;
}
NextPoint();
}
}]

// start of missile attack

monster_missile_start[ ()
{
switch(random(1,3)) // play one of 3 missile animations
{
case 1
{
Animate(MISSILEATTACK);
fire_delay = time + FIREDELAY; // set firing delay
PlaySound("weapon\deagle.wav", 500);
}
case 2
{
Animate(MISSILEATTACK1);
fire_delay = time + FIREDELAY1; // set firing delay
PlaySound("weapon\deagle.wav", 500);
}
case 3
{
Animate(MISSILEATTACK2);
fire_delay = time + FIREDELAY2; // set firing delay
PlaySound("weapon\deagle.wav", 500);
}
}
//TargetPlayer();
UpdateEnemyVis(true); //always aware of player position
UpdateTarget();
self.ideal_yaw = enemy_yaw; // set direction to run
SetHoldAtEnd(true);
self.ThinkTime = 0.3;
self.think = "monster_missile";
skill_time = time + (SKILL*0.1); // calculate next update time
attack_delay = time + ATTACKDELAY; // delay until next shot
} ]

// attack target with projectile

monster_missile[ ()
{
self.ThinkTime = 0.3;
if(self.health<=0)
{
self.think = "death_biz";
return 0;
}
if((self.in_pain = true) and (random(1,100)<PAINPERCENT))
{
self.think = "monster_missile_pain_start"; // in pain
SetHoldAtEnd(false);
return 0;
}
exist = EnemyExist(DAMAGEATTRIBUTE);
if(exist < 2)
{
SetHoldAtEnd(false);
HighLevel("LostTarget"); // enemy is dead and gone
return 0;
}
if(exist = 2)
{
SetHoldAtEnd(false);
HighLevel("LostTarget"); // enemy is dead but body remains
return 0;
}
if(enemy_vis = false)
{
self.think = LOSTFUNC; // lost sight of enemy
lost_time = time + LOSTTIME;
SetHoldAtEnd(false);
return 0;
}
if(self.player_Y>self.current_Y)
{
Animate(SHOOTUP);
FireProjectile(PROJECTILE, FIREBONE, OFFSETX, OFFSETY, OFFSETZ, DAMAGEATTRIBUTE);
PlaySound("weapon\deagle.wav", 500);
SetHoldAtEnd(false);
self.ThinkTime = 0.3;
}
if(self.player_Y<self.current_Y)
{
Animate(SHOOTDOWN);
FireProjectile(PROJECTILE, FIREBONE, OFFSETX, OFFSETY, OFFSETZ, DAMAGEATTRIBUTE);
PlaySound("weapon\deagle.wav", 500);
SetHoldAtEnd(false);
self.ThinkTime = 0.3;
}
if(enemy_range>MISSILERANGE)
{
Animate(MISSILEATTACK);
FireProjectile(PROJECTILE, FIREBONE, OFFSETX, OFFSETY, OFFSETZ, DAMAGEATTRIBUTE);
fire_delay = time + FIREDELAY; // set firing delay
PlaySound("weapon\deagle.wav", 500);
self.think = RUNFUNC; // too far away so run toward
SetHoldAtEnd(false);
return 0;
}
if(skill_time<time) // update according to skill level
{
UpdateTarget(); // update target location
skill_time = time + (SKILL*0);
ai_face(); // face enemy while attacking
}

if(fire_delay<time) // delay after animation starts before firing
{
FireProjectile(PROJECTILE, FIREBONE, OFFSETX, OFFSETY, OFFSETZ, DAMAGEATTRIBUTE);
fire_delay = time + 1000; // set delay well ahead so it is

ignored
PlaySound("weapon\deagle.wav", 500);
}
if(self.animate_at_end = true)
{
if(attack_delay < time)
{
//self.think = RUNFUNC; // no
self.think = "monster_missile_start";
SetHoldAtEnd(false);
self.ThinkTime = 0;
}
}
} ]

death_biz[ ()
{
Animate(DIE);
PlaySound("die1.wav", 500);
SetHoldAtEnd(true); // set to stop at end
self.ThinkTime = 0.1;
self.think = "Death";
return 0;
} ]

// start of showing pain

monster_missile_pain_start[ ()
{
switch(random(1,4)) // play one of 4 pain animations
{
case 1
{
Animate(PAIN);
PlaySound("injury1.wav", 500);
}
case 2
{
Animate(PAIN1);
PlaySound("injury1.wav", 500);
}
case 3
{
Animate(PAIN2);
PlaySound("injury1.wav", 500);
}
case 4
{
Animate(PAIN3);
PlaySound("injury1.wav", 500);
}
}
SetHoldAtEnd(true); // set to stop at end
self.ThinkTime = 0;
self.think = "monster_missile_pain";
} ]

// wait until animation is done

monster_missile_pain[ ()
{
self.ThinkTime = 0;
if(self.animate_at_end = true) // animation is done
{
self.think = "monster_missile_start"; // go back to missile attack
SetHoldAtEnd(false);
self.ThinkTime = 0;
}
} ]

// start of melee attack

monster_melee_start[ ()
{
switch(random(1,3)) // play one of 3 melee animations
{
case 1
{
Animate(MELEEATTACK);
}
case 2
{
Animate(MELEEATTACK1);
}
case 3
{
Animate(MELEEATTACK2);
}
}
SetHoldAtEnd(true); // set to stop at end
self.ThinkTime = 0.1;
self.think = "monster_melee";
} ]

// melee attack

monster_melee[ ()
{
self.ThinkTime = 0;
if(self.health<=0)
{
PlaySound("die1.wav", 500);
self.think = "death_biz"; // in pain
return 0;
}
if((self.in_pain = true) and (random(1,100)<PAINPERCENT))
{
SetHoldAtEnd(false);
self.think = "monster_melee_pain_start"; // in pain
return 0.1;
}
exist = EnemyExist(DAMAGEATTRIBUTE); // see if target is around
if(exist < 2)
{
SetHoldAtEnd(true);
HighLevel("LostTarget"); // enemy is dead and gone
return 0;
}
if(exist = 0)
{
SetHoldAtEnd(true);
HighLevel("DeadTarget"); // enemy is dead but body remains
return 0;
}
if(enemy_vis = false)
{
SetHoldAtEnd(true);
self.think = LOSTFUNC; // lost sight of enemy
lost_time = time + LOSTTIME;
return 0;
}
if(enemy_range>(MELEERANGE*SCALE))
{
SetHoldAtEnd(false);
self.think = RUNFUNC; // too far away so run toward
return 0;
}
ai_face(); // face enemy while attacking
if(self.animate_at_end = true) // animation is done
{
SetHoldAtEnd(true);
switch(random(1,3)) // play one of 3 melee animations
{
case 1
{
Animate(MELEEATTACK);
}
case 2
{
Animate(MELEEATTACK1);
}
case 3
{
Animate(MELEEATTACK2);
}
}
SetHoldAtEnd(true); // set to stop at end
}
if(time>melee_time) // if time then damage
{
damage = random(MINMELEEDAMAGE, MAXMELEEDAMAGE); // get damage amount
Damage(damage, DAMAGEATTRIBUTE); // damage target
melee_time = time + MELEEDELAY; // reset time until

next damage
}
} ]

// start of showing pain

monster_melee_pain_start[ ()
{
switch(random(1,4)) // play one of 4 pain animations
{
case 1
{
Animate(PAIN);
PlaySound("injury.wav", 500);
}
case 2
{
Animate(PAIN1);
PlaySound("injury.wav", 500);
}
case 3
{
Animate(PAIN2);
PlaySound("injury.wav", 500);
}
case 4
{
Animate(PAIN3);
PlaySound("injury.wav", 500);
}
}
SetHoldAtEnd(true); // set to stop at end
self.ThinkTime = 0.1;
self.think = "monster_melee_pain";
} ]

// wait until animation is done

monster_melee_pain[ ()
{
self.ThinkTime = 0.1;
if(self.animate_at_end = true) // animation is done
{
self.think = "monster_melee_start"; // go back to melee attack
SetHoldAtEnd(false);
self.ThinkTime = 0.1;
melee_time = time + MELEEDELAY; // reset attack deley
}
} ]

// basic AI routines

// run toward enemy and see if you are ready to attack

ai_run[ (dist)
{
if (attack_state = AS_MELEE) // do melee attack
{
ai_run_melee();
}
if (attack_state = AS_MISSILE) // do missile attack
{
ai_run_missile();
}

attack_state = AS_NONE;

if (CheckAnyAttack()) // check if you can start the actual attack
{
return 0;
}
if(RUNSPEED > 0)
{
walk_movetogoal(dist); // else move toward the enemy
}
} ]

// check if ready to do actual attacking

CheckAnyAttack[ ()
{
if(enemy_range<MELEERANGE)
{
if(enemy_range<(MELEERANGE*SCALE)) // inside melee range
{
attack_state = AS_MELEE; // do a melee attack
return true;
}
return false;
}

if(enemy_range<MISSILERANGE)
{
if(attack_delay>time)
{
return false;
}
if(enemy_range<MISSILERANGE)
{
attack_state = AS_MISSILE; // do a missile attack
return true;
}
}
return false;
} ]

// missile attack setup

ai_run_missile[ ()
{
ai_face();
if(FacingIdeal()) // got close enough
{
self.think = MISSILEFUNC; // start missile attack
attack_state = AS_STRAIGHT;
UpdateTarget();
skill_time = time + (SKILL*0.1);
}
} ]

// melee attack setup

ai_run_melee[ ()
{
ai_face(); // turn to face target
if(FacingIdeal()) // got close enough
{
self.think = MELEEFUNC; // start melee attack
self.attack_state = AS_STRAIGHT;
}
} ]

// face enemy

ai_face[ ()
{
self.ideal_yaw = enemy_yaw;
ChangeYaw(); // rotate to face enemy
} ]

// use walkmove to naviagte to enemy

walk_movetogoal[ (dist)
{
if(IsFalling = true)
{
return 0; // don't move while falling
}
if(dist < 0)
{
return 0;
}
if(back_up = false)
{
ai_face(); // turn to face enemy
if(FacingIdeal())
{
if(walkmove(self.current_yaw, dist) = true)
{
return 0; // can move in current direction
}
else
{
if(random(1,10)<3) // backup and move sideways
{
back_up = true;
back_time = time + 0.5;
back_flag = false;
return 0;
}
else
{
ForceUp(FORCEUP*SCALE); // jump up, forward and to side
ForceForward(FORCEFORWARD*SCALE);
if(random(1,10)<6)
{
ForceRight(FORCESIDE*SCALE);
}
else
{
ForceLeft(FORCESIDE*SCALE);
}
}
}
}
}
else
{
if(back_flag = false) // go backward 1/2 sec
{
if(back_time > time)
{
walkmove((self.current_yaw-(180*0.0174532925199433)), dist);
return 0;
}
else
{
back_time = time + 0.5;
back_flag = true;
}
}
if(back_time > time) // go sideways 1/2 sec
{
walkmove((self.current_yaw-(90*0.0174532925199433)), dist);
return 0;
}
back_up = false;
}
} ]

// check if nearly facing enemy

FacingIdeal[ ()
{
selfangle = self.current_yaw/0.0174532925199433; // your direction in degrees
idealangle = self.ideal_yaw/0.0174532925199433; // his direction in degrees
delta = selfangle - idealangle; // difference in directions
if (delta > -20 and delta < 20) // within 20 degrees is close enough
{
return true;
}
return false;
} ]

}


-----------------------------

Im stuck on this one big time.
User avatar
Juutis
Posts: 1511
Joined: Thu Jan 12, 2006 12:46 pm
Location: Finland

Post by Juutis »

Ahh yes, now I remember!
About a year ago I had a similar problem. RF crashed mysteriously every time I killed a pawn leaving nothing to the log. I was using a partially scripted weapon system so actually the pawns were killed by other pawns and then it crashed.
However, I can't remember how I fixed it. :(
But no fear!! I will test your script and try to find out what's wrong as soon as I can! It might be tomorrow, or on the weekend... or a week from now on. But I will test it at some point. :)
Pain is only psychological.
User avatar
LtForce
Posts: 437
Joined: Wed May 03, 2006 11:15 am
Location: Vilnius, Lithuania

Post by LtForce »

I have tha same problem too. I put up about 6 robots in one place and make them attack eachother but only one of them stays alive after spawn and all others just spawn and dies in the first second. I'm using robot.s script
Lithuanians for Georgia!
incenseman2003
Posts: 320
Joined: Sat Mar 11, 2006 11:41 pm

Post by incenseman2003 »

It seems that I have not fixed the issue of the robots dying when they spawn in. I thought that I had but was mistaken. Good to see that it isnt just me having this issue. It didnt happen at first. It all worked great. Then all of a sudden they started doing it. It seems to depend on where on the level the robot is standing. Weird!!
Last edited by incenseman2003 on Sat Jan 13, 2007 1:54 pm, edited 1 time in total.
Patience and tolerance are the keys to the passage of knowledge. Even those that are the most knowledgeable started with many questions.
User avatar
LtForce
Posts: 437
Joined: Wed May 03, 2006 11:15 am
Location: Vilnius, Lithuania

Post by LtForce »

incenseman2003 wrote:It seems that I have not fixed the issue of the robost dying when they spawn in. I thought that I had but was mistaken. Good to see that it isnt just me having this issue. It didnt happen at first. It all worked great. Then all of a sudden they started doing it. It seemd to depend on where on the level the robot is standing. Weird!!
I'm having the same problem - maybe a month ago I didn't have anything to do and I putted robots all over my school and tried killing them. Now I'm trying to put alot of small robots to somekinda cage(I made them 0.3size and gave them a disk launcher). I changed the script so they wouldn't attack a player, but eachother. I put them all in a small cage are but they just die
Lithuanians for Georgia!
Post Reply