RF crashes everytime i kill my pawn!!! pls help!!!

Topics regarding Scripting with Reality Factory
Post Reply
User avatar
psYco
Posts: 782
Joined: Wed Mar 15, 2006 10:55 am
Location: England

RF crashes everytime i kill my pawn!!! pls help!!!

Post by psYco »

hi, may all you ppl that can help pls help,

i have added a pawn into my level, but there's one problem, it runs fine until you kill it....

when you kill it RF crashes and exits... (RF0.75)

here is my pawn's script

Code: Select all

	 //   Male Zombie

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

	// define the type of monster this will be

	ATTACKTYPE		[melee]		// type of attack - melee or missile
	PATROL			[false]		// false - ambush or true - patrol

	// idling and turning

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

	// when in pain

	PAIN				[jab]	        	// pain animations
	PAIN1				[jab]
	PAINPERCENT			[75]    		// percentage of time pain is shown
	PAINSOUND			[bosses\holmespain1.wav]// sounds played when in pain
	PAINSOUND1			[bosses\holmespain2.wav]
	PAINSOUND2			[bosses\holmespain3.wav]
	PAINSOUND3			[bosses\holmespain4.wav]

	// when dying

	DIE				[die_backwards]	// dying animations
	DIE1				[die_backwards]
	DIE2				[die_backwards]
	DIE3				[die_backwards]
	DIEHOLD			        [300]		// time corpse still appears
	DIEFADE				[300]		// fadeout time of corpse
	DIESOUND			[bosses\holmesdie.wav]	// sounds played when dying
	DIESOUND1			[bosses\holmesdie.wav]
	DIESOUND2			[bosses\holmesdie.wav]
	DIESOUND3			[bosses\holmesdie.wav]

	// when running to attack

	RUN				[walk]		// running animation
	RUNSPEED			[150]		// average run speed
	RUNSOUNDDELAY			[2]		// delay between making sounds when running to attack
	RUNSOUND			[bosses\holmeswalk.wav]	// sound played while running to attack

	// when walking while patroling

	WALK				[walk]		// walking animation
	WALKSPEED			[75]		// average walking speed

	// the melee attack mode

	MELEEATTACK			[ref_shoot_kick_blend1.wav]	// melee attacking animations
	MELEEATTACK1			[ref_shoot_kick_blend1.wav]
	MELEEATTACK2			[ref_shoot_kick_blend1.wav]
	MELEESOUND			[bosses\holmesmelee.wav]	// sounds played when melee attacking
	MELEESOUND1			[bosses\holmesmelee.wav]
	MELEESOUND2			[bosses\holmesmelee.wav]
	MELEERANGE			[90]		// max distance to start melee attack
	MINMELEEDAMAGE			[20]		// minimum amount of damage per melee attack
	MAXMELEEDAMAGE			[33]		// maximum amount of damage per melee attack
	MELEEDELAY			[15]		// number of seconds between melee damages
	MELEEDAMAGESOUND		[bosses\holmesmeleedamage.wav]	// sound played when damage is done

	// search for enemy

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

	// obstacle avoidance forces for jumping

	FORCEUP				[30]		// obstacle avoidance jump speed
	FORCEFORWARD			[30]		// obstacle avoidance forward speed
	FORCESIDE			[30]		// 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(true);
		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);
		SetFOV(FOV);					// 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");
		AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0);	// go to alert when triggered 
                AddTriggerOrder("GoLowCheck", INTERACTTRIGGER, 0);	// go to interactmode when triggered 
		RotateToPoint(STAND, YAWSPEED, false, ""); // go to point if any specified
		MoveToPoint(WALK, WALKSPEED*SCALE, "");
		if(PATROL = false)
		{
			NewOrder("Idle");
		}
		else
		{
			NewOrder("Patrol");
		}
	} ]

	// 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[ ()
	{
                // need to monitor if the player is within distance and if so, detect the usekey being pressed
		PlayAnimation(STAND, true, "");
                PlayerDistOrder(BOXSIZE,"GoLowCheck");

		if(random(1,10)>6)
		{
			if(random(1,10)>5)
			{
				Rotate(TURNL, 102, 0, 90, 0, "");
				PlayAnimation(STAND, true, "");
				Rotate(TURNR, 108, 0, -90, 0, "");
			}
			else
			{
				Rotate(TURNR, 108, 0, -90, 0, "");
				PlayAnimation(STAND, true, "");
				Rotate(TURNL, 102, 0, 90, 0, "");
			}
		}
		RestartOrder();
	} ]	

        GoLowCheck[()
        {
        // Switch to low level
        LowLevel("CheckIn");
        }]
        
        CheckIn[()
        {
        // Check if keynumber 22 is pressed. Key 22 is, O
                if(self.key_pressed=22)
                {
                // OK, key is pressed. get in
                self.think="GetIn";
                return 0;
                }
                if(self.player_range>BOXSIZE)
                {
                // Player no longer near pawn. Go to High Level Idle.
                HighLevel("Idle");
                return 0;
                }
        }]
        
        GetIn[()
        {
        // Set Think Time to run every frame.
        self.ThinkTime=0;
        //SetEventState(DRIVINGTRIG,true);
        self.think="InteractPlayer";
        }]
	// walk the beat from point to point

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

	// show pain at idle then trigger to alert

	IdlePain[ ()
	{
		switch(random(1,4)) // chose between 4 animations
		{
			case 1
			{
				PlayAnimation(PAIN, true, PAINSOUND);
			}
			case 2
			{
				PlayAnimation(PAIN1, true, PAINSOUND1);
			}
			case 3
			{
				PlayAnimation(PAIN2, true, PAINSOUND2);
			}
			case 4
			{
				PlayAnimation(PAIN3, true, "PAINSOUND3");
			}
		}
		SetEventState(ALERTTRIGGER, true);	// set trigger to go to alert
		Return();
	} ]	

	// start shifting from idle to alert

	IdleToAlert[ ()
	{
		FindTargetOrder(ALERTSIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);	// increase viewing distance
		AddPainOrder("AlertPain", PAINPERCENT);			// show pain
		AddTimerOrder(1, 10, "AlertToIdle");			// go to idle after 10 secs
		SetEventState(ALERTTRIGGER, false);		// turn off alert trigger
		NewOrder("Alert");
	} ]

	// look around at alert looking for enemy

	Alert[ ()
	{
		if(random(1,10)>5)
		{
			Rotate(TURNL, 102, 0, 90, 0, "");
			Rotate(TURNL, 102, 0, 90, 0, "");
			Rotate(TURNL, 102, 0, 90, 0, "");
			Rotate(TURNL, 102, 0, 90, 0, "");
		}
		else
		{
			Rotate(TURNR, 108, 0, -90, 0, "");
			Rotate(TURNR, 108, 0, -90, 0, "");
			Rotate(TURNR, 108, 0, -90, 0, "");
			Rotate(TURNR, 108, 0, -90, 0, "");
		}
		RestartOrder();
	} ]	

	// show pain at alert

	AlertPain[ ()
	{
		switch(random(1,4)) // play one of 4 animations
		{
			case 1
			{
				PlayAnimation(PAIN, true, PAINSOUND);
			}
			case 2
			{
				PlayAnimation(PAIN1, true, PAINSOUND1);
			}
			case 3
			{
				PlayAnimation(PAIN2, true, PAINSOUND2);
			}
			case 4
			{
				PlayAnimation(PAIN3, true, PAINSOUND3);
			}
		}
		Return();
	} ]	

	// timed out at alert

	AlertToIdle[ ()
	{
		FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);	// decrease viewing distance
		AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0);	// go to alert when triggered
		AddPainOrder("IdlePain", 100);				// show pain 
		if(PATROL = false)
		{
			NewOrder("Idle");
		}
		else
		{
			RotateToPoint(STAND, YAWSPEED, false, "");
			MoveToPoint(WALK, WALKSPEED*SCALE, "");
			NewOrder("Patrol");
		}
	} ]

	// found a target to attack

	FoundTarget[ ()
	{
		DelTimerOrder(1);	// get rid of alert timer
		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
		AddPainOrder("IdlePain", 100);				// show pain and trigger alert
		AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0);	// go to alert when triggered
		if(PATROL = false)
		{
			NewOrder("Idle");
		}
		else
		{
			RotateToPoint(STAND, YAWSPEED, false, "");
			MoveToPoint(WALK, WALKSPEED*SCALE, "");
			NewOrder("Patrol");
		}
	} ]

	// you died

	Death[ ()
	{
		DelTimerOrder(1);	// remove alert timer
		AddPainOrder("IdlePain", 0);	// remove pain order
		FindTargetOrder(0, "FoundTarget", DAMAGEATTRIBUTE);	// remove target finding
		DelTriggerOrder("IdleToAlert");	// remove alert trigger
		SetNoCollision();	// remove bounding box so there are no collisions with corpse
		switch(random(1,4)) // chose between 4 death animations
		{
			case 1
			{
				AnimateStop(DIE, DIEHOLD, DIESOUND);
			}
			case 2
			{
				AnimateStop(DIE1, DIEHOLD, DIESOUND1);
			}
			case 3
			{
				AnimateStop(DIE2, DIEHOLD, DIESOUND2);
			}
			case 4
			{
				AnimateStop(DIE, DIEHOLD, DIESOUND3);
			}
		}
		if(DIEHOLD >= 0)
		{
			FadeOut(DIEFADE, 0); // fade out corpse
			Remove(true);	// remove actor
		}
	} ]

	// Low level attack routines

	// Start of run to attack

	monster_run_start[ ()
	{
		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.1;
		if(self.health<=0)
		{
			HighLevel("Death"); // 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)
		{
			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(PAINSOUND);
			}
			case 2
			{
				Animate(PAIN1);
				PlaySound(PAINSOUND1);
			}
			case 3
			{
				Animate(PAIN2);
				PlaySound(PAINSOUND2);
			}
			case 4
			{
				Animate(PAIN3);
				PlaySound(PAINSOUND3);
			}
		}
		SetHoldAtEnd(true);	// set to stop at animation end
		self.ThinkTime = 0.1;
		self.think = "monster_run_pain";
	} ]

	// wait for animation to stop

	monster_run_pain[ ()
	{
		self.ThinkTime = 0.1;
		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.1;
		if(lost_time<time)
		{
			HighLevel("LostTarget"); // timed out while looking
			return 0;
		}
		if(self.health<=0)
		{
			HighLevel("Death"); // died
			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)
		{
			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(PAINSOUND);
			}
			case 2
			{
				Animate(PAIN1);
				PlaySound(PAINSOUND1);
			}
			case 3
			{
				Animate(PAIN2);
				PlaySound(PAINSOUND2);
			}
			case 4
			{
				Animate(PAIN3);
				PlaySound(PAINSOUND3);
			}
		}
		SetHoldAtEnd(true);	// set to stop at end
		self.ThinkTime = 0.1;
		self.think = "monster_lost_pain";
	} ]

	// wait till animation is done

	monster_lost_pain[ ()
	{
		self.ThinkTime = 0.1;
		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;
		}
	} ]

	// 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
				missile_sound = MISSILESOUND;
			}
			case 2
			{
				Animate(MISSILEATTACK1);
				fire_delay = time + FIREDELAY1; // set firing delay
				missile_sound = MISSILESOUND1;
			}
			case 3
			{
				Animate(MISSILEATTACK2);
				fire_delay = time + FIREDELAY2; // set firing delay
				missile_sound = MISSILESOUND2;
			}
		}
		SetHoldAtEnd(true);
		self.ThinkTime = 0;
		self.think = "monster_missile";
		UpdateTarget();					// update target location
		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.1;
		if(self.health<=0)
		{
			SetHoldAtEnd(false);
			HighLevel("Death"); // dead
			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(enemy_range>MISSILERANGE)
		{
			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.1);
			ai_face();	// face enemy while attacking
		}

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

		// wait until animation is done before attacking again
		// hold animation at end until attack delay is over

		if(self.animate_at_end = true)
		{
			if(attack_delay < time)
			{
				self.think = "monster_missile_start"; // go back to missile attack
				SetHoldAtEnd(false);
				self.ThinkTime = 0.1;
			}
		} 
	} ]

	// start of showing pain

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

	// wait until animation is done

	monster_missile_pain[ ()
	{
		self.ThinkTime = 0.1;
		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);
				PlaySound(MELEESOUND);
			}
			case 2
			{
				Animate(MELEEATTACK1);
				PlaySound(MELEESOUND1);
			}
			case 3
			{
				Animate(MELEEATTACK2);
				PlaySound(MELEESOUND2);
			}
		}
		SetHoldAtEnd(true);	// set to stop at end
		self.ThinkTime = 0;
		self.think = "monster_melee";
	} ]

	// melee attack

	monster_melee[ ()
	{
		self.ThinkTime = 0.1;
		if(self.health<=0)
		{
			SetHoldAtEnd(false);
			HighLevel("Death"); // you died
			return 0;
		}
		if((self.in_pain = true) and (random(1,100)<PAINPERCENT))
		{
			SetHoldAtEnd(false);
			self.think = "monster_melee_pain_start"; // in pain
			return 0;
		}
		exist = EnemyExist(DAMAGEATTRIBUTE); // see if target is around
		if(exist < 2)
		{
			SetHoldAtEnd(false);
			HighLevel("LostTarget"); // enemy is dead and gone
			return 0;
		}
		if(exist = 2)
		{
			SetHoldAtEnd(false);
			HighLevel("DeadTarget"); // enemy is dead but body remains
			return 0;
		}
		if(enemy_vis = false)
		{
			SetHoldAtEnd(false);
			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(false);
			switch(random(1,3)) // play one of 3 melee animations
			{
				case 1
				{
					Animate(MELEEATTACK);
					PlaySound(MELEESOUND);
				}
				case 2
				{
					Animate(MELEEATTACK1);
					PlaySound(MELEESOUND1);
				}	
				case 3
				{
					Animate(MELEEATTACK2);
					PlaySound(MELEESOUND2);
				}
			}
			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
			PlaySound(MELEEDAMAGESOUND);
		}
	} ]

	// start of showing pain

	monster_melee_pain_start[ ()
	{
		switch(random(1,4)) // play one of 4 pain animations
		{
			case 1
			{
				Animate(PAIN);
				PlaySound(PAINSOUND);
			}
			case 2
			{
				Animate(PAIN1);
				PlaySound(PAINSOUND1);
			}
			case 3
			{
				Animate(PAIN2);
				PlaySound(PAINSOUND2);
			}
			case 4
			{
				Animate(PAIN3);
				PlaySound(PAINSOUND3);
			}
		}
		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;
			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();
			return 0;
		}
		if (attack_state = AS_MISSILE) // do missile attack
		{
			ai_run_missile();
			return 0;
		}
		if (CheckAnyAttack()) // check if you can start the actual attack
		{
			return 0;
		}
		if(RUNSPEED > 0)
		{
			walk_movetogoal(dist); // else move toward the enemy
		}
	} ]

	// 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;
	} ]

	// check if ready to do actual attacking

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

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

}

please help!!! :cry:

all help will be APPRECIATED :lol:

thanks in advance
User avatar
QuestOfDreams
Site Admin
Posts: 1520
Joined: Sun Jul 03, 2005 11:12 pm
Location: Austria
Contact:

Post by QuestOfDreams »

there's one problem, it runs fine until you kill it....
Well, if it happens when the pawn gets killed, the problem might be in the death function
Comment out all commands in that function and see if it still crashes. If it works fine, start to uncomment the function line by line and find out which line is causing the crash. Compare the command in question with the docs and see if you've set the parameters correctly.
If you're sure that you're using it correctly and it still crashes, post again.
User avatar
bernie
RF Moderator
Posts: 1249
Joined: Tue Nov 15, 2005 10:07 am
Location: Ireland

Post by bernie »

Same thing happens to me too.
Just comment out these two lines in the death routine
FadeOut(DIEFADE, 0); // fade out corpse
Remove(true); // remove actor
and all will be fine except you are left with bodies littering the place.
According to my console, FadeOut() and Remove() routines aren't recognised by the engine.
User avatar
bernie
RF Moderator
Posts: 1249
Joined: Tue Nov 15, 2005 10:07 am
Location: Ireland

Post by bernie »

@QOD:

Using RF 0.75

Same thing happens with perfectai.s
lines read:
Death[ ()
{
SetNoCollision(); // remove bounding box so there are no collisions with corpse
FadeOut(10,0);
Remove(true); // remove actor
return 0;
}]

Fred Death:
Scripts\perfectai.s: Death: 2 - Method FadeOut not Found*

After commenting out line 2 I then get:

Fred Death:
Scripts\perfectai.s: Death: 2 - Method Remove not Found*

I don't seem to be able to remove Pawns at death at all. Just able to make no collision and walk through the bodies.

Possible bug in RF75 ?? I never noticed this until mentioned in this thread.
Feel free to move this post to bugs if necessary.
Jay
RF Dev Team
Posts: 1232
Joined: Fri Jul 08, 2005 1:56 pm
Location: Germany

Post by Jay »

@bernie:

I suppose you used Remove() and FadeOut() in LowLevel mode. They are High Level functions that cannot be called in low level, while SetNoCollision() is a two-sided-function(i.e. it can be used in both low and high level)


Be sure you enter the Death function as high level mode. (HighLevel("Death"); or NewOrder("Death");)


It could happen that your pawn dies in low level and you just forgot to call HighLevel("Death") because you used self.think="Death"; instead. This is not the same.

I hope this helps.
Everyone can see the difficult, but only the wise can see the simple.
-----
User avatar
bernie
RF Moderator
Posts: 1249
Joined: Tue Nov 15, 2005 10:07 am
Location: Ireland

Post by bernie »

Yes you are right Jay. perfectai calls the Death routine with self.think
:oops: I changed this to HighLevel("Death") and all is well. Thanks a million for pointing that out. This High Low level bit is very confusing. However, lesson learned. Apart from me feeling an absolute ejit no harm done.
User avatar
psYco
Posts: 782
Joined: Wed Mar 15, 2006 10:55 am
Location: England

Resolved part of the problem, but need more help

Post by psYco »

i finally got my pawns to die without crashing the engine, i simply changed this line of code:

Code: Select all

if(DIEHOLD >= 5)
		{
			FadeOut(DIEFADE, 0); // fade out corpse
			Remove(true);	// remove actor
		}
and my
"DIEHOLD is = 3
BUT........

the engine still crashes when i kill them when they aren't alert, i.e. while IDLEing. (REFER to the script on top of the page)

pls can someone help me b'coz this is a serious issue, i don't want to crash the engine everytime i kill and unalerted ZOMBIE!!!!!!

thanx 2 kind souls who can help :wink:
shadow
Posts: 81
Joined: Mon Jul 25, 2005 5:37 am

Post by shadow »

Are you sure the the problem is during Idle when they die?

Since FOV is set at 360, your pawn will see the player before the player can shoot the pawn!

So... the pawn will immediately go to Alert (not stay at Idle) when the player is seen, right?

When did this problem occur with this script?
Did the die problem occur after you made some changes?
Or has it been a problem since you first started using the script?

Hope this helps a little.
shadow
Posts: 81
Joined: Mon Jul 25, 2005 5:37 am

Post by shadow »

Well I spent some time with your script and there are a quite a few errors in it but most of them are not deal breakers.

So here are a few things I found...

1 - why do you have this in Spawn order...
AddTriggerOrder("GoLowCheck", INTERACTTRIGGER, 0); // go to interactmode when triggered

this actually isn't used any where.???


2 - In monster_melee_pain_start you have ...
case 3
{
Animate(PAIN2);
PlaySound(PAINSOUND2);
}
case 4
{
Animate(PAIN3);
PlaySound(PAINSOUND3);
}

PAIN2 and 3 are never defined in your script?


3 - in your monster_melee you have...
if(exist = 2)
{
SetHoldAtEnd(false);
HighLevel("DeadTarget"); // enemy is dead but body remains
return 0;
}
There is no highlevel order Deadtarget"???


4 - in your Idle order you have...
PlayerDistOrder(BOXSIZE,"GoLowCheck");

Do you know why this is even there?

NOTE: going back and forth repeatedly between high and low level is not a good idea in scripts.



So I'm not sure where you got this script from, it seems it was originally used for something else.

That being said I made a small box level with this and used the virgil.act instead.
It worked for me except some of the errors noted above.

Also note your defined times for
DIEHOLD     [300] // time corpse still appears
DIEFADE     [300] // fadeout time of corpse

I believe these are in seconds.

If you can, get hold of Pickles RF book.
It has a great section on scripting.

Good luck
User avatar
psYco
Posts: 782
Joined: Wed Mar 15, 2006 10:55 am
Location: England

So SORRY

Post by psYco »

i found the error in my script :oops: , this is the line of code that was incorrect,
IdlePain[ ()
{
switch(random(1,4)) // chose between 4 animations
{
case 1
{
PlayAnimation(PAIN, true, PAINSOUND);
}
case 2
{
PlayAnimation(PAIN1, true, PAINSOUND1);
}
case 3
{
PlayAnimation(PAIN2, true, PAINSOUND2);
}
case 4
{
PlayAnimation(PAIN3, true, "PAINSOUND3");
}
}
PAINSOUND3 shouldn't have quotations around them, sorry about all the fuss, but thanx 2 those wo did try and help...

but....

if there is anyone out there who can make blood effects in the scripting, help will be very much appreciated, just look at the next post. :wink:

thanks ALL
Post Reply