XIDPawn
Class JohanssonController

source: C:\XIII\XIDPawn\Classes\JohanssonController.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Controller
         |
         +--Engine.AIController
            |
            +--XIDPawn.JohanssonController
Direct Known Subclasses:None

class JohanssonController
extends Engine.AIController

//============================================================================= // JOhanssonController. //=============================================================================
Variables
 AllianceInfoEx AlliancesEx[8]
 bool CHARGE_LES_LOGS
           Pour voir mes logs
 int CompteurFonceSurXIII
           en H2H
 int CompteurTirSurXIIIDeLoin
           en H2H
 XIIIGameInfo GI
 Johansson Johan
 vector LastPosition
           position de deplacement
 SafePoint LastSafepoint
 int NbCoupsDonnes
           en H2H
 int NbFiolesRestantes
           position de deplacement
 int NumeroTimbre
           position de deplacement
 SafePoint OldSafepoint
 array PathNodeJohanList
 Pawn PeeredEnemy
 PathNode PointDeVUe
 float TempsEntreChaqueFioles
           position de deplacement
 float TempsEntreChaqueScalpels
           position de deplacement
 float TimeToLastFiole
           position de deplacement
 float TimeToLastPiquouse
           position de deplacement
 vector V_Pos
           position de deplacement
 int ValeurArmeXIII
           en H2H
 XIIIPlayerPawn XIII
 bool bChambreXIII
           Pour voir mes logs
 bool bFirstTrigger
           Pour voir mes logs
 bool bFonceSurXIII
           Pour voir mes logs
 bool bInStrafeMode
           Pour voir mes logs
 bool bPlanqueSurSafePoint
           Pour voir mes logs
 bool bPointIsBehindMe
           Pour voir mes logs
 bool bStrafe
           Pour voir mes logs
 bool bTestArmeXIII
           Pour voir mes logs
 bool bTestSiXIIILoin
           Pour voir mes logs
 bool bTestSiXIIIProche
           Pour voir mes logs
 bool bTestTimeToLastPiquouse
           Pour voir mes logs
 bool bTestXIIIDelogeable
           Pour voir mes logs
 bool bTire
           Pour voir mes logs
 bool bTirsurXIIIdeLoin
           Pour voir mes logs
 int iCompteur
           compteur utilise dans les boucle sur routecache
 rotator rl
 rotator temp_rotator

States
end, VaChercherFioles, VaChercherScalpels, fuite, Piquouse, AttaqueH2H, AttaqueADistance, intro, init, Mort

Function Summary
 rotator AdjustAim(Ammunition FiredAmmunition, vector projStart, int aimerror)
     
// ----------------------------------------------------------------------
// Adjust Aim
// ----------------------------------------------------------------------
 void DamageAttitudeTo(Pawn Other, float Damage)
 int EvalueArmeXIII()
 PathNode FindBestLineOfFire()
     
// ----------------------------------------------------------------------
// FindBestLineOfFire()
//
 bool FindBestPathToward(Actor desired, bool bClearPaths)
     
// ----------------------------------------------------------------------
// FindBestPathToward()
//
// assumes the desired destination is not directly reachable.
// It tries to set Destination to the location of the
// best waypoint, and returns true if successful
 PathNode FindNewPosition(bool bDerrierePerso)
     
// ----------------------------------------------------------------------
// FindNewPositionBehind()
//
 void Firexiii()
     
// ----------------------------------------------------------------------
// Firexiii
// ----------------------------------------------------------------------
 void HalteAuFeu()
     
// ----------------------------------------------------------------------
// HalteAuFeu
// ----------------------------------------------------------------------
 bool LineOfFire(optional vector)
     
// ----------------------------------------------------------------------
// LineOfFire()
//permet de savoir si je peut tirer sur XIII (pour eviter de tirer dans les murs)
 void NotifyFiring()
     
// ----------------------------------------------------------------------
// NotifyFiring
// ----------------------------------------------------------------------
 bool TestDirection(vector dir, out vector)
 void XIIIBePoisoned()
 bool XIIIDelogeable()


State end Function Summary


State VaChercherFioles Function Summary
 void EndState()
 void BeginState()
 void TakeFiole()


State VaChercherScalpels Function Summary
 void EndState()
 void BeginState()
 void TakeScalpels()


State fuite Function Summary
 void EndState()
 void BeginState()
 SafePoint ChercheSafePoint()
 void DamageAttitudeTo(Pawn Other, float Damage)


State Piquouse Function Summary
 void EndState()
 void BeginState()
 void XIIIBePoisoned()
 bool StrafeDestination()


State AttaqueH2H Function Summary
 void EndState()
 void BeginState()
 bool StrafeDestination()


State AttaqueADistance Function Summary
 void EndState()
 void BeginState()
 bool NeedRecalage()
 bool StrafeDestination()
 void TakeScalpels()


State intro Function Summary


State init Function Summary
 void EndState()
 void BeginState()
 void InitPathNodeJohanList()


State Mort Function Summary
 void Endstate()
 void BeginState()
 void Trigger(Actor Other, Pawn EventInstigator)
 void DamageAttitudeTo(Pawn Other, float Damage)
 bool NearWall(float walldist)



Source Code


00001	//=============================================================================
00002	// JOhanssonController.
00003	//=============================================================================
00004	class JohanssonController extends AIController;
00005	
00006	//Structures
00007	struct AllianceInfoEx  {
00008		var Name  AllianceName;
00009		var float AllianceLevel;
00010		var bool  bPermanent;
00011	};
00012	
00013	var AllianceInfoEx  AlliancesEx[8];
00014	var XiiiPlayerPawn XIII;
00015	var Johansson Johan;
00016	var pathnode PointDeVUe;
00017	var SafePoint LastSafepoint;
00018	var SafePoint OldSafepoint;
00019	var XIIIGameInfo GI;
00020	var array<PathNode> PathNodeJohanList;
00021	var pawn PeeredEnemy;
00022	
00023	var rotator temp_rotator;
00024	var rotator rl;
00025	
00026	var vector LastPosition; //position de deplacement
00027	var vector V_Pos;
00028	
00029	var float TempsEntreChaqueScalpels;
00030	var float TempsEntreChaqueFioles;
00031	var float TimeToLastPiquouse;
00032	var float TimeToLastFiole;
00033	
00034	var int NumeroTimbre;
00035	var int NbFiolesRestantes;
00036	var int iCompteur; //compteur utilise dans les boucle sur routecache
00037	var int NbCoupsDonnes; //en H2H
00038	var int ValeurArmeXIII;
00039	var int CompteurFonceSurXIII;
00040	var int CompteurTirSurXIIIDeLoin;
00041	
00042	var bool CHARGE_LES_LOGS; // Pour voir mes logs
00043	var bool bTire;
00044	var bool bTestSiXIIIProche;
00045	var bool bTestSiXIIILoin;
00046	var bool bTestTimeToLastPiquouse;
00047	var bool bTestXIIIDelogeable;
00048	var bool bTestArmeXIII;
00049	var bool bPointIsBehindMe;
00050	var bool bStrafe;
00051	var bool bPlanqueSurSafePoint;
00052	var bool bInStrafeMode;
00053	var bool bFonceSurXIII;
00054	var bool bTirsurXIIIdeLoin;
00055	var bool bChambreXIII;
00056	var bool bFirstTrigger;
00057	
00058	// ****************************************  Fonctions Systemes **************
00059	
00060	// ----------------------------------------------------------------------
00061	// FindBestPathToward()
00062	//
00063	// assumes the desired destination is not directly reachable.
00064	// It tries to set Destination to the location of the
00065	// best waypoint, and returns true if successful
00066	function bool FindBestPathToward(actor desired, bool bClearPaths)
00067	{
00068	    local Actor path;
00069	    local bool success;
00070	    local vector Desti;
00071	
00072	    desti=desired.location;
00073	    MoveTarget=none;   //pas de test sur movetarget!=none donc je le place ici
00074	    path = FindPathTo(desti,true);
00075	    success = (path != None);
00076	    if (success)
00077	    {
00078	        MoveTarget = path;
00079	        Destination = path.Location;
00080	    }
00081	
00082	    return success;
00083	}
00084	
00085	// ----------------------------------------------------------------------
00086	// FindBestLineOfFire()
00087	//
00088	function pathnode FindBestLineOfFire()
00089	{
00090	    local PathNOde bestpath;
00091	    local float distance;
00092	    local int i;
00093	
00094	    for (i=0;i<PathNodeJohanList.Length;i++)
00095	    {
00096			distance=VSize(PathNodeJohanList[i].location-pawn.location);
00097	        if (/*distance<400 && */distance>50 && LineOfFire(PathNodeJohanList[i].location-pawn.location))
00098	        {
00099	            if (bestpath!=none)
00100	            {
00101					if (Vsize(bestpath.location-pawn.location)>Vsize(PathNodeJohanList[i].location- pawn.location))
00102					{
00103						bestpath=PathNodeJohanList[i];
00104					}
00105	            }
00106	            else
00107					bestpath=PathNodeJohanList[i];
00108	        }
00109	    }
00110	    return bestpath;
00111	}
00112	
00113	
00114	// ----------------------------------------------------------------------
00115	// FindNewPositionBehind()
00116	//
00117	function pathnode FindNewPosition(bool bDerrierePerso)
00118	{
00119	    local Actor path;
00120	    local vector Desti;
00121	    local int i;
00122	
00123	    for (i=0;i<PathNodeJohanList.Length;i++)
00124	    {
00125	        if ((((!bDerrierePerso && (normal(PathNodeJohanList[i].location-pawn.location) dot vector(pawn.rotation))>0) || (bDerrierePerso && (normal(PathNodeJohanList[i].location-pawn.location) dot vector(pawn.rotation))<0))) && VSize(PathNodeJohanList[i].location-pawn.location)<200 && Fasttrace(PathNodeJohanList[i].location,pawn.location-vect(0,0,30)))
00126	        {
00127	            return PathNodeJohanList[i];
00128	        }
00129	    }
00130	    return none;
00131	}
00132	
00133	
00134	//------------------------------------------------
00135	// TRIGGER: Fonction Trigger declenchee par detectionvolume ou trigger alarme
00136	//------------------------------------------------
00137	event Trigger( actor Other, pawn EventInstigator)
00138	{
00139		if (!bFirstTrigger)
00140		{
00141			bFirstTrigger=true;
00142			gotostate('intro');
00143		}
00144		else
00145			gotostate('intro','go');
00146	}
00147	event bool NotifyBump(actor Other)
00148	{
00149	    return false;
00150	}
00151	function DamageAttitudeTo(pawn Other, float Damage)
00152	{
00153		Johan.PlaySndPNJOno(pnjono'Onomatopees.hPNJHurt',Johan.CodeMesh,Johan.NumeroTimbre);
00154	}
00155	event SeePlayer (pawn seenplayer)
00156	{
00157	}
00158	event SeeMonster(pawn seenplayer)
00159	{
00160	}
00161	event Timer()
00162	{
00163	}
00164	event timer3()
00165	{
00166		if (bFonceSurXIII)
00167		{
00168			if (CompteurFonceSurXIII>10)
00169				bFonceSurXIII=false;
00170			else
00171				CompteurFonceSurXIII++;
00172		}
00173		if (bTirsurXIIIdeLoin)
00174		{
00175			if (CompteurTirSurXIIIdeLoin>5)
00176				bTirsurXIIIdeLoin=false;
00177			else
00178				CompteurTirSurXIIIdeLoin++;
00179		}
00180	
00181		if (bTestTimeToLastPiquouse)  //piquouse toutes les 5s
00182		{
00183			if ((level.timeseconds-TimeToLastPiquouse)>10 && Vsize(xiii.location-pawn.location)<450)
00184			{
00185				gotostate('piquouse');
00186				return;
00187			}
00188		}
00189	
00190		if (bTestXIIIDelogeable)
00191		{
00192			if (XIIIDelogeable())
00193			{
00194				gotostate('vachercherfioles');
00195				return;
00196			}
00197		}
00198		if (bTestSiXIIIProche)
00199		{
00200			if (bTirsurXIIIdeLoin)
00201				return;
00202			if (Vsize(xiii.location-pawn.location)<350)
00203			{
00204				gotostate('attaqueH2H');
00205				return;
00206			}
00207			else if (frand()<0.1)
00208			{
00209				CompteurFonceSurXIII=0;
00210				bFonceSurXIII=true;
00211			}
00212		}
00213		else if (bTestSiXIIILoin)
00214		{
00215			if (bFonceSurXIII)
00216				return;
00217			if (Vsize(xiii.location-pawn.location)>550)
00218			{
00219				gotostate('attaqueadistance');
00220				return;
00221			}
00222		}
00223	}
00224	event HearNoise(float Loudness, Actor NoiseMaker)
00225	{
00226	}
00227	
00228	
00229	event Tick(float DeltaTime)
00230	{
00231		local int valeurarmeactuelle;
00232	
00233		super.tick(DeltaTime);
00234	
00235		if (bTestArmeXIII)
00236		{
00237			valeurarmeactuelle=EvalueArmeXIII();
00238			if (valeurarmeactuelle!=ValeurArmeXIII)
00239			{
00240				ValeurArmeXIII=valeurarmeactuelle;
00241				if (valeurarmeactuelle==2)
00242				{
00243					if (rand(3)<1)
00244					{
00245						HalteAufeu();
00246						gotostate('fuite');
00247					}
00248				}
00249				else if (valeurarmeactuelle==0)
00250					gotostate('attaqueH2H');
00251			}
00252		}
00253	}
00254	
00255	// ----------------------------------------------------------------------
00256	// Firexiii
00257	// ----------------------------------------------------------------------
00258	function Firexiii()
00259	{
00260		if (!bTire)
00261		{
00262	        if (!xiii.bisdead)
00263	        {
00264				Focus=xiii;
00265				bTire = true;
00266				timer();
00267	        }
00268	        else
00269	        {
00270				gotostate('end');
00271	        }
00272		}
00273	}
00274	
00275	// ----------------------------------------------------------------------
00276	// HalteAuFeu
00277	// ----------------------------------------------------------------------
00278	function HalteAuFeu()
00279	{
00280	    bTire = false;
00281	    settimer(0,false);
00282	}
00283	
00284	// ----------------------------------------------------------------------
00285	// NotifyFiring
00286	// ----------------------------------------------------------------------
00287	function NotifyFiring()
00288	{
00289	}
00290	
00291	// ----------------------------------------------------------------------
00292	// Adjust Aim
00293	// ----------------------------------------------------------------------
00294	function rotator AdjustAim(Ammunition FiredAmmunition, vector projStart, int aimerror)
00295	{
00296		local vector DirectionTir;
00297	
00298	    if (Johan.arme=='scalpelH2H' || Johan.arme=='piquouse')
00299	    {
00300		DirectionTir=xiii.location; /*+xiii.velocity*(0.6+0.4*Frand())*(Vsize(xiii.location-pawn.location)/0.05);
00301		DirectionTir+=vect(0,0,28);  */
00302	    }
00303	    else if (Johan.arme=='scalpels')
00304	    {
00305			DirectionTir=xiii.location+xiii.velocity*(0.6+0.4*Frand())*(Vsize(xiii.location-pawn.location)/class'Prock03_Scalpels'.default.speed);
00306			DirectionTir+=vect(0,0,28);
00307	    }
00308	    else if (Johan.arme=='fiole')
00309		{
00310			DirectionTir=xiii.location+xiii.velocity*(0.6+0.4*Frand())*(Vsize(xiii.location-pawn.location)/class'Prock03_Fioles'.default.speed);
00311			DirectionTir+=vect(0,0,28);
00312		}
00313		return rotator(DirectionTir-projStart);
00314	}
00315	
00316	
00317	// Fin fonctions systemes -------------------------------------------------------
00318	//--------------------------------------------------------------------------------
00319	
00320	
00321	// ----------------------------------------------------------------------
00322	// LineOfFire()
00323	//permet de savoir si je peut tirer sur XIII (pour eviter de tirer dans les murs)
00324	function bool LineOfFire(optional vector Offset)
00325	{
00326		local vector X,Y,Z;
00327		local vector StartTrace;
00328		local vector Depart;
00329		local actor hitactor;
00330		local vector hitlocation,hitnormal;
00331	
00332		GetAxes(rotation, X,Y,Z);  //choppe axes controller
00333		StartTrace = Johan.GetScalpelStart(X,Y,Z)+16*X;
00334		if (offset!=vect(0,0,0))
00335		{
00336			StartTrace+=offset;
00337		}
00338		HitActor=Trace(HitLocation, HitNormal, xiii.location+vect(0,0,28), StartTrace, true, vect(0,0,0));
00339		if (HitActor == None || HitActor == xiii || (Johan.arme=='fiole' && HitActor.isa('Breakablemover')))
00340			return true;
00341		return false;
00342	}
00343	
00344	
00345	function bool XIIIDelogeable()
00346	{
00347		local int i;
00348	
00349		if (NbFiolesRestantes<=0 && Johan.NbFioles>0)
00350			return false;
00351		for (i=0;i<8;i++)
00352		{
00353			if (Johan.PtsDePlanque[i] != none && Johan.PtsDePlanque[i].bActive)
00354				return true;
00355		}
00356		return false;
00357	}
00358	
00359	function int EvalueArmeXIII()
00360	{
00361		if (xiii.weapon.InventoryGroup==0 || xiii.weapon.isinstate('reloading') || !xiii.weapon.hasammo()) //au point ou reload
00362			return 0;
00363		else if (xiii.weapon.InventoryGroup<=2) //beretta  ou tknife
00364			return 1;
00365		else
00366			return 2;    //magum ou pompe
00367	}
00368	
00369	function bool TestDirection(vector dir, out vector pick)
00370	{
00371		local vector HitLocation, HitNormal, dist;
00372		local actor HitActor;
00373		local float minDist;
00374	
00375		minDist = 100;
00376		pick = dir * (minDist + 250* FRand());
00377		HitActor = Trace(HitLocation, HitNormal, Pawn.Location + pick + 1.5 * Pawn.CollisionRadius * dir , Pawn.Location, false);
00378		if (HitActor != None)
00379		{
00380			pick = HitLocation + (HitNormal - dir) * 2 * Pawn.CollisionRadius;
00381			if ( !FastTrace(pick, Pawn.Location) )
00382				return false;
00383		}
00384		else
00385			pick = Pawn.Location + pick;
00386	
00387		dist = pick - Pawn.Location;
00388		if (Pawn.Physics == PHYS_Walking)
00389			dist.Z = 0;
00390		return (VSize(dist) > minDist);
00391	}
00392	
00393	function XIIIBePoisoned()
00394	{
00395	}
00396	
00397	State Mort
00398	{
00399	    ignores seeplayer,seemonster,hearnoise,notifybump;
00400	
00401	    function bool NearWall(float walldist)
00402	    {
00403	        return false;
00404	    }
00405	    event Tick(float DeltaTime)
00406	    {
00407	    }
00408	    singular function DamageAttitudeTo(pawn Other, float Damage)
00409	    {
00410	    }
00411	    function Trigger(actor Other, pawn EventInstigator)
00412	    {
00413	    }
00414	    function BeginState()
00415	    {
00416	        if (CHARGE_LES_LOGS) log(pawn@"dead man"@self);
00417	        HalteAuFeu();
00418	        settimer(0,false);
00419	        settimer2(0,false);
00420			  XIIIBaseHud(XIIIPlayerController(XIII.Controller).MyHud).AddBossBar(none);
00421			  Johan.VisuelScalpel.destroy();
00422			  Johan.VisuelPiquouse.destroy();
00423			  Johan.VisuelFiole.destroy();
00424			  //johan.releaseanimcontrol();
00425			  pawn.RefreshDisplaying();
00426	    }
00427	    function Endstate()
00428	    {
00429	    }
00430	begin:
00431	
00432	Dead:
00433	}
00434	
00435	// ----------------------------------------------------------------------
00436	// INIT
00437	//
00438	// ----------------------------------------------------------------------
00439	auto state init
00440	{
00441		ignores SeePlayer,hearNoise,seemonster;
00442	    event Tick (float delta)
00443	    {
00444	    }
00445	    function InitPathNodeJohanList()
00446		{
00447			local Pathnode PathNodeJ;
00448	
00449			foreach allactors(class'Pathnode', PathNodeJ,'JohanssonPath')
00450			{
00451				PathNodeJohanList.Length = PathNodeJohanList.Length + 1;
00452				PathNodeJohanList[PathNodeJohanList.Length - 1] = PathNodeJ;
00453			}
00454		}
00455	    singular event bool NotifyBump(actor Other)
00456	    {
00457			return false;
00458	    }
00459	    function BeginState()
00460	    {
00461	    }
00462	    function EndState()
00463	    {
00464	    }
00465	
00466	begin:
00467	    //CHARGE_LES_LOGS=true;
00468	start:
00469	    sleep(0.5);
00470		GI=XIIIGameInfo(level.game);
00471		XIII=XIIIPlayerPawn(xiiigameinfo(level.game).mapinfo.XIIIpawn);
00472	    if (XIII==none)
00473			goto('start');
00474	    pawn.rotationrate.yaw=43000;
00475		pawn.rotationrate.roll=0;
00476		pawn.rotationrate.pitch=0;
00477	    bRotateToDesired = false;
00478	    Johan= Johansson(Pawn);
00479		pawn.AnimBlendParams(johan.FIRINGCHANNEL+1,0,0,0,'X');
00480		pawn.EnableChannelNotify(johan.FiringChannel+1, 1);
00481	    //conversions
00482	    johan.PeripheralVision=cos(johan.PeripheralVision*0.00873);
00483	    johan.alertness=0;
00484	    pawn.bCanJump=false;
00485	    temp_rotator=johan.rotation;
00486	    Pawn.SetPhysics(PHYS_Walking);
00487	    johan.setrotation(temp_rotator);
00488	    InitPathNodeJohanList();
00489	initinventaire:
00490	    JOhan.InitializeInventory();
00491	    Johan.InitScalpelAttach();
00492	    Johan.InitPiquouseAttach();
00493	    Johan.InitFioleAttach();
00494	    Johan.ScalpelDansLaMain(false);
00495	    Johan.PiquouseDansLaMain(false);
00496	    Johan.FioleDansLaMain(false);
00497	    JOhan.arme='Scalpels';
00498	    For(iCompteur=0;iCompteur<3;iCompteur++) //init nb de fioles
00499	    {
00500	        if (Johan.Fioles[iCompteur] !=none)
00501	        {
00502	            NbFiolesRestantes++;
00503	        }
00504	    }
00505	    focalpoint=johan.location+vector(temp_rotator);
00506	    focus =none;
00507	    pawn.bCanPickupInventory=false;
00508	    bPreparingMove=false;
00509	    bAdvancedTactics=false;
00510	    NumeroTimbre=1;
00511	    disable('seeplayer');
00512	    disable('seemonster');
00513	    disable('hearnoise');
00514	    sightcounter=0;
00515	    if (Johan.GenEffects!=none)
00516	    {
00517			Johan.GenEffects.xiii=xiii;
00518			Johan.GenEffects.instigator=instigator;
00519			Johan.GenEffects.PC=XIIIGameInfo(Level.Game).MapInfo.XIIIController;
00520	    }
00521	initperceptions:
00522	    TimeToLastPiquouse=3;
00523	    TimeToLastFiole=3;
00524	    //gotostate('intro');
00525	    stop;
00526	}
00527	
00528	// ----------------------------------------------------------------------
00529	// Intro
00530	//
00531	// ----------------------------------------------------------------------
00532	state intro
00533	{
00534	    event Tick (float delta)
00535	    {
00536			super.tick(Delta);
00537	    }
00538		event timer2()
00539		{
00540				LOCAL Rotator rl;
00541				LOCAL int n;
00542	
00543				if (PeeredEnemy!=none )
00544				{
00545					rl=rotator(PeeredEnemy.Location-pawn.Location)-pawn.Rotation;
00546	
00547					n=rl.Yaw;//-16384;
00548					n=((n+32768)&65535)-32768;
00549	
00550					//if ((15000>n) /*&& (n>-15000)*/)
00551					//{
00552						pawn.HeadYaw = pawn.HeadYaw*0.6+0.4*n;
00553						rl.Yaw=0;
00554						rl.Pitch=0;
00555						rl.Roll=pawn.HeadYaw;
00556						pawn.SetBoneRotation('X HEAD',rl,,0.75);
00557					/*}
00558					else
00559					{
00560						pawn.HeadYaw = pawn.HeadYaw*0.7;
00561						rl.Yaw=0;
00562						rl.Pitch=0;
00563						rl.Roll= pawn.HeadYaw;
00564						pawn.SetBoneRotation('X HEAD',rl,,0.75);
00565					}     */
00566				}
00567				else
00568				{
00569					if ( pawn.HeadYaw!=0 )
00570					{
00571						pawn.HeadYaw = pawn.HeadYaw*0.8;
00572						if (pawn.HeadYaw > 100 )
00573						{
00574							rl.Yaw=0;
00575							rl.Pitch=0;
00576							rl.Roll= pawn.HeadYaw;
00577							pawn.SetBoneRotation('X HEAD',rl,,0.75);
00578						}
00579						else
00580						{
00581							pawn.HeadYaw=0;
00582							rl.Yaw=0;
00583							rl.Pitch=0;
00584							rl.Roll= 0;
00585							settimer2(0,false);
00586							pawn.SetBoneRotation('X HEAD',rl,,0.0);
00587						}
00588					}
00589				}
00590		}
00591	
00592	begin:
00593		Johan.ScalpelDansLaMain(false);
00594	   johan.TakeAnimControl(false);
00595		pawn.loopanim('gardienbricole',,,johan.FIRINGCHANNEL+1);
00596		stop;
00597	go:
00598		Johan.playAnim('takescalpel',0.5,0.4,johan.FIRINGCHANNEL+1);
00599		sleep(1.5);
00600		pawn.PlayAnim('wait',1,0.4,johan.FIRINGCHANNEL+1);
00601	 	PeeredEnemy=xiii;
00602		settimer2(0.05,true);
00603		timer2();
00604		pawn.rotationrate.yaw=50000;
00605		moveto(50*(normal(xiii.location-pawn.location)-0.5*vector(pawn.rotation))+pawn.location,xiii,0.1);
00606		settimer2(0,false);
00607		PeeredEnemy=none;
00608		pawn.HeadYaw=0;
00609		rl.Yaw=0;
00610		rl.Pitch=0;
00611		rl.Roll= 0;
00612		pawn.SetBoneRotation('X HEAD',rl,,0.0);
00613		pawn.rotationrate.yaw=43000;
00614	//	pawn.bSpineControl=false;
00615		sleep(2);
00616		pawn.PlayAnim('dialogue4JOH',0.5,0.4,johan.FIRINGCHANNEL+1);
00617		sleep(4.5);
00618		pawn.loopAnim('marche',1,0.3,johan.FIRINGCHANNEL+1);
00619	  // johan.releaseanimcontrol();
00620		moveto(200*normal(xiii.location-pawn.location)+pawn.location,xiii,0.4);
00621	  // johan.TakeAnimControl(false);
00622		pawn.PlayAnim('degaine2',1,0.3,johan.FIRINGCHANNEL+1);
00623		sleep(1.7);
00624		Johan.NbScalpels=10;
00625		Johan.ScalpelDansLaMain(true);
00626		pawn.playAnim('provoc',1,0.4,johan.FIRINGCHANNEL+1);
00627		sleep(4);
00628		johan.releaseanimcontrol();
00629		settimer3(0.5,true);
00630		XIIIBaseHud(XIIIPlayerController(XIII.Controller).MyHud).AddBossBar(pawn);
00631		gotostate('attaqueadistance');
00632	
00633	//gotostate('attaqueH2H');
00634	}
00635	
00636	
00637	// ----------------------------------------------------------------------
00638	// ATTAQUE A DISTANCE
00639	//
00640	// ----------------------------------------------------------------------
00641	State AttaqueADistance  //attaque au scalpel   א distance
00642	{
00643		ignores hearnoise;
00644	
00645		event timer2()
00646		{
00647			if (!bInStrafeMode)
00648			{
00649				bInStrafeMode=true;
00650				settimer2(3,false);
00651			}
00652			else
00653			{
00654				bInStrafeMode=false;
00655				settimer2(8,false);
00656			}
00657		}
00658	
00659		event ReceiveWarning(pawn shooter, float projspeed,vector firedir)
00660		{
00661			// AI controlled creatures may duck if not falling
00662			if (xiii.bisdead || ValeurArmeXIII==0 || bStrafe || (bInStrafeMode && frand()<0.5))
00663				return;
00664	//|| btire
00665			if (!XIIIWeapon(xiii.weapon).AmmoType.bInstantHit)
00666			{
00667				if (CHARGE_LES_LOGS) log(pawn$"evite projectile");
00668				if (pawn.biscrouched)
00669					pawn.shouldcrouch(false);
00670				gotostate('AttaqueADistance','strafe');
00671			}
00672			else
00673			{
00674				if (rand(500)>5*ValeurArmeXIII)
00675						return;
00676	            if (CHARGE_LES_LOGS) log(pawn$"je suis vise");
00677	            if (pawn.biscrouched && frand()<0.3)
00678	            {
00679					pawn.shouldcrouch(false);
00680					gotostate('AttaqueADistance','strafe');
00681	            }
00682	            else
00683					gotostate('AttaqueADistance','strafe');
00684			}
00685	    }
00686		event Timer()
00687		{
00688			if (bTire)
00689			{
00690				if (xiii.bisdead)
00691				{
00692					gotostate('end');
00693					return;
00694				}
00695				if (Johan.arme=='scalpels')
00696				{
00697					if (Johan.bWeaponReady) Johan.ScalpelsFire();
00698					settimer(TempsEntreChaqueScalpels,false); // pour tester si reste muns
00699				}
00700				else
00701				{
00702					if (Johan.bWeaponReady) Johan.FioleFire();
00703					settimer(TempsEntreChaqueFioles,false); // pour tester si reste muns
00704				}
00705	
00706			}
00707		}
00708	    Function TakeScalpels()
00709	    {
00710	        if (CHARGE_LES_LOGS) log("takescalpels *******************");
00711	        focalpoint=pawn.location+1000*vector(Johan.pointscalpel.rotation);
00712	        Johan.PlayTakeScalpels();
00713	        Johan.NbScalpels=10;
00714	        Johan.ScalpelDansLaMain(true);
00715	    }
00716	    function bool StrafeDestination()
00717	    {
00718			local vector pick, pickdir;
00719	        local bool success;
00720	
00721	        pickdir=(xiii.location-pawn.location) cross vect(0,0,1);
00722	        pickdir.Z = 0;
00723	        pickdir=normal(pickdir);
00724	        if (Frand()>0.5)
00725				pickdir *= -1;
00726	
00727	        success = TestDirection(pickdir, pick);
00728	        if (!success)
00729	        {
00730				success = TestDirection(-1*pickdir, pick);
00731				if (!success)
00732					return false;
00733	        }
00734	        Destination = pick;
00735	        return success;
00736		}
00737	    function bool NeedRecalage()
00738	    {
00739			local float distance;
00740	
00741			movetarget=none;
00742			distance=vsize(xiii.location-pawn.location);
00743	
00744			if (distance<(Johan.DistanceAttaque-(100+50*frand())))
00745			{
00746				destination=pawn.location+(Johan.distanceAttaque-distance)*normal(pawn.location-xiii.location);
00747				if (Fasttrace(destination,pawn.location-vect(0,0,30)))
00748				{
00749					if (CHARGE_LES_LOGS) log("recalage arriere");
00750					bPointIsBehindMe=true;
00751					return true;
00752				}
00753				else
00754				{
00755					movetarget=FindNewPosition(true);
00756					if (movetarget!=none)
00757					{
00758						if (CHARGE_LES_LOGS)log("recalage arriere sur point");
00759						destination=movetarget.location;
00760						bPointIsBehindMe=true;
00761						return true;
00762					}
00763				}
00764			}
00765			else if (distance>(Johan.distanceAttaque+(100+50*frand())))
00766			{
00767				destination=pawn.location+(distance-Johan.distanceAttaque)*normal(xiii.location-pawn.location);
00768				if (Fasttrace(destination,pawn.location-vect(0,0,30))/* && LineOfFire(destination-pawn.location)*/)
00769				{
00770					if (CHARGE_LES_LOGS)log("recalage avant");
00771					return true;
00772				}
00773				else
00774				{
00775					movetarget=FindNewPosition(false);
00776					if (movetarget!=none)
00777					{
00778						destination=movetarget.location;
00779						if (CHARGE_LES_LOGS)log("recalage avant sur point");
00780						return true;
00781					}
00782				}
00783			}
00784	    }
00785	
00786	    function BeginState()
00787	    {
00788			//updates
00789			if (Johan.NbFioles<=0) bTestSiXIIIProche=true;
00790			if (Johan.NbFioles<=0) bTestTimeToLastPiquouse=true;
00791			if (Johan.NbFioles<=0) bTestXIIIDelogeable=true;
00792			if (Johan.NbFioles<=0) bTestArmeXIII=true;
00793			bStrafe=false;
00794			bInStrafeMode=false;
00795			settimer2(4,false);
00796	    }
00797	    function EndState()
00798	    {
00799			if (pawn.biscrouched)
00800				pawn.shouldcrouch(false);
00801			bTestSiXIIIProche=false;
00802			bTestTimeToLastPiquouse=false;
00803			bTestXIIIDelogeable=false;
00804			bTestArmeXIII=false;
00805			HalteAufeu();
00806			settimer2(0,false);
00807	    }
00808	
00809	
00810	begin:
00811	    if (CHARGE_LES_LOGS) log(pawn@"Etat Atatque a distance"@Johan.NbScalpels);
00812		//pawn.velocity=vect(0,0,0);
00813		//pawn.acceleration=vect(0,0,0);
00814		if (xiii.bisdead)
00815		{
00816	        gotostate('end');
00817		}
00818		if (Johan.NbScalpels<=1 && Johan.NbFioles<=0)
00819		{
00820			if (pawn.biscrouched)
00821	            pawn.shouldcrouch(false);
00822			gotostate('VaChercherScalpels');
00823		}
00824		focus=xiii;
00825		finishrotation();
00826	attaque:
00827		if (xiii.bisdead)
00828		{
00829	        gotostate('end');
00830		}
00831		if (Johan.NbScalpels<=1 && Johan.NbFioles<=0)
00832		{
00833			if (pawn.biscrouched)
00834	            pawn.shouldcrouch(false);
00835			gotostate('VaChercherScalpels');
00836		}
00837		else if (!LineOfFIre())
00838		{
00839			HalteAuFeu();
00840			if (pawn.biscrouched)
00841				pawn.shouldcrouch(false);
00842			goto('cherchelignedevue');
00843		}
00844	
00845	TirSurPlace:
00846		//if (CHARGE_LES_LOGS) log("TirSurPlace");
00847		if (Johan.NbFioles>0)
00848		{
00849			if (Johan.arme!='fiole')
00850			{
00851				if (!Johan.bWeaponReady)
00852				{
00853					sleep(0.5);
00854					goto('TirSurPlace');
00855				}
00856				Johan.arme='fiole';
00857				Johan.ScalpelDansLaMain(false);
00858				Johan.FioleDansLaMain(true);
00859			}
00860		}
00861		else if (Johan.arme!='scalpels')
00862		{
00863			if (!Johan.bWeaponReady)
00864			{
00865				sleep(0.5);
00866				goto('TirSurPlace');
00867			}
00868			Johan.arme='scalpels';
00869			bTestSiXIIIProche=true;
00870			bTestTimeToLastPiquouse=true;
00871			bTestXIIIDelogeable=true;
00872			bTestArmeXIII=true;
00873			Johan.ScalpelDansLaMain(true);
00874			Johan.FioleDansLaMain(false);
00875		}
00876		Johan.PiquouseDansLaMain(false);
00877		bPointIsBehindMe=false;
00878		if (!pawn.biscrouched && NeedRecalage() && (Johan.NbScalpels>1 || Johan.NbFioles>0))
00879		{
00880			HalteAuFeu();
00881			if (bPointIsBehindMe)
00882				MoveTo(Destination,xiii,0.6);
00883			else
00884				MoveTo(Destination,xiii);
00885		}
00886		Firexiii();
00887		sleep(0.5);
00888		goto('attaque');
00889	ChercheLignedevue:
00890		if (CHARGE_LES_LOGS) log("ChercheLignedevue");
00891	    HalteAuFeu();
00892	    If (!pawn.biscrouched && LineOfFIre(vect(0,0,-29)))
00893	    {
00894			pawn.shouldcrouch(true);
00895			sleep(0.5);
00896			goto('attaque');
00897	    }
00898	    else if (pawn.biscrouched)
00899	    {
00900	        pawn.shouldcrouch(false);
00901	    }
00902	    PointDeVue=FindBestLineOfFire();
00903	    if (PointDeVue==none)   //trouve pas de point donc tente le starfe
00904	    {
00905			log("PAS DE POINT DE VUE !!!!!!!!!!!!!!!!!!*");
00906			goto('strafe');
00907	    }
00908		//log("point de vue "@Pointdevue);
00909	    if (actorreachable(PointDeVue))
00910	    {
00911			focalpoint=PointDeVue.location;
00912			MoveToward(PointDeVue,none,0.8);
00913	    }
00914	    else if (FindBestPathToward(PointDeVue,true))
00915	    {
00916	        for (iCompteur=0;iCompteur<16;iCompteur++)
00917	        {
00918				if (routecache[iCompteur]==none)
00919					break;
00920				focus=none;
00921				focalpoint=1000*(routecache[iCompteur].location-pawn.location)+pawn.location;
00922				MoveToward(routecache[iCompteur],none,0.8);
00923	        }
00924	    }
00925	    else
00926	    {
00927			log("N'ARRIVE PAS ATTEINDRE point de ligne de vue"@PointDeVUe);
00928			gotostate('attaqueH2H');
00929	    }
00930	    goto('attaque');
00931	Strafe:
00932		if (CHARGE_LES_LOGS) log("strafe");
00933	    If (StrafeDestination())
00934	    {
00935			bStrafe=true;
00936			//HalteAuFeu();
00937	        MoveTo(Destination,xiii,0.8);
00938			bStrafe=false;
00939	    }
00940	    goto('attaque');
00941	}
00942	
00943	
00944	// ----------------------------------------------------------------------
00945	//ATTAQUEH2H
00946	//
00947	// ----------------------------------------------------------------------
00948	State AttaqueH2H  //attaque au scalpel en H2H
00949	{
00950		ignores hearnoise;
00951	
00952		event Tick(float DeltaTime)
00953		{
00954			local float distanceaxiii;
00955	
00956			super.tick(DeltaTime);
00957	
00958			if (btire)
00959				return;
00960	
00961			if (Johan.NbCoupsDansVide>3)
00962			{
00963				gotostate('attaqueadistance');
00964				return;
00965			}
00966			distanceaxiii=vsize(XIII.location-pawn.location);
00967			if (distanceaxiii<95)
00968			{
00969				fireXIII();
00970				gotostate('attaqueh2h','TapeSurPlace');
00971				return;
00972			}
00973			if (!bStrafe && vsize(XIII.location-LastPosition)>60 && distanceaxiii>100)  //a bouge
00974			{
00975				gotostate('attaqueH2H','VaVersXIII');
00976				return;
00977			}
00978	
00979		}
00980		event timer2()
00981		{
00982			CompteurTirSurXIIIDeLoin=0;
00983			bTirSurXIIIDeLoin=true;
00984		   gotostate('attaqueadistance');
00985		}
00986		event ReceiveWarning(pawn shooter, float projspeed,vector firedir)
00987		{
00988			// AI controlled creatures may duck if not falling
00989			if (xiii.bisdead /*|| btire */|| ValeurArmeXIII==0 || bStrafe || frand()<0.4)
00990				return;
00991	
00992			if (!XIIIWeapon(xiii.weapon).AmmoType.bInstantHit)
00993			{
00994				if (CHARGE_LES_LOGS) log(pawn$"evite projectile");
00995				if (pawn.biscrouched)
00996					pawn.shouldcrouch(false);
00997				gotostate('AttaqueH2H','strafe');
00998			}
00999			else
01000			{
01001				if (rand(200)>5*ValeurArmeXIII)
01002						return;
01003	            if (CHARGE_LES_LOGS) log(pawn$"je suis vise");
01004				gotostate('AttaqueH2H','strafe');
01005			}
01006	    }
01007	
01008		event Timer()    //ATTENTION le scalepl H2H ne tir qu'une fois
01009		{
01010			if (bTire && Johan.bWeaponReady)
01011			{
01012	
01013				if (xiii.bisdead)
01014				{
01015					gotostate('end');
01016					return;
01017				}
01018				NbCoupsDonnes++;
01019				Johan.ScalpelH2HFire();
01020			}
01021		}
01022		function bool StrafeDestination()
01023	    {
01024			local vector pick, pickdir;
01025	        local bool success;
01026			local vector DirectionXIII;
01027	
01028			DirectionXIII=xiii.location-pawn.location;
01029	
01030			if (Frand()>0.5)
01031				pickdir=(DirectionXIII) cross vect(0,0,1);
01032			else
01033				pickdir=(DirectionXIII) cross vect(0,0,-1);
01034			pickdir+=DirectionXIII;
01035	        pickdir.Z = 0;
01036	        pickdir=normal(pickdir);
01037	
01038	
01039	        success = TestDirection(pickdir, pick);
01040	        if (!success)
01041	        {
01042				success = TestDirection(-1*pickdir, pick);
01043				if (!success)
01044					return false;
01045	        }
01046	        Destination = pick;
01047	        return success;
01048		}
01049	    singular event bool NotifyBump(actor Other)  //je touche je tape
01050	    {
01051			if (other==xiii)
01052			{
01053				fireXIII();
01054				gotostate('attaqueh2h','TapeSurPlace');
01055			}
01056			return false;
01057	    }
01058	    function BeginState()
01059	    {
01060			disable('tick');
01061			if (CHARGE_LES_LOGS) log(pawn@"Etat Atatque H2H");
01062			//updates
01063			bTestSiXIIILoin=true;
01064			bTestTimeToLastPiquouse=true;
01065			bTestXIIIDelogeable=true;
01066			bTestArmeXIII=true;
01067	      settimer2(6,false);
01068			bStrafe=false;
01069			if (Johan.arme=='fiole')
01070			{
01071				Johan.ScalpelDansLaMain(true);
01072				Johan.FioleDansLaMain(false);
01073			}
01074	    }
01075	    function EndState()
01076	    {
01077			bTestSiXIIILoin=false;
01078			bTestTimeToLastPiquouse=false;
01079			bTestXIIIDelogeable=false;
01080			bTestArmeXIII=false;
01081			HalteAufeu();
01082			settimer2(0,false);
01083	    }
01084	begin:
01085		//pawn.velocity=vect(0,0,0);
01086		//pawn.acceleration=vect(0,0,0);
01087		if (!Johan.bWeaponReady)
01088		{
01089			sleep(0.5);
01090			goto('begin');
01091		}
01092		Johan.arme='scalpelH2H';
01093		Johan.NbCoupsDansVide=0;
01094		if (xiii.bisdead)
01095		{
01096	        gotostate('end');
01097		}
01098		Johan.PiquouseDansLaMain(false);
01099		enable('tick');
01100	VaVersXIII:
01101	//log("vaversxiii");
01102	    LastPosition=XIII.location;
01103	    if (actorreachable(xiii))
01104	    {
01105			// focalpoint=XIII.location;
01106			// focus=xiii;
01107			V_Pos=XIII.location-pawn.location;
01108			V_Pos=Vsize(V_Pos)*normal(V_Pos+0.7*xiii.velocity)+pawn.location;
01109			MoveTo(V_Pos,xiii);
01110	    }
01111	    else if (FindBestPathToward(XIII,true))
01112	    {
01113	        for (iCompteur=0;iCompteur<16;iCompteur++)
01114	        {
01115				if (routecache[iCompteur]==none)
01116					break;
01117				focus=none;
01118				focalpoint=1000*(routecache[iCompteur].location-pawn.location)+pawn.location;
01119				MoveToward(routecache[iCompteur],none);
01120	        }
01121	    }
01122	    else
01123	    {
01124			log("N'ARRIVE PAS ATTEINDRE XIII POUR LES SCALPETISER");
01125			CompteurTirSurXIIIDeLoin=0;
01126			bTirSurXIIIDeLoin=true;
01127			gotostate('attaqueadistance');
01128	    }
01129			if (Vsize(pawn.location-xiii.location)>91)
01130			{
01131				goto('VaVersXIII');
01132			}
01133			else
01134				fireXIII();
01135	TapeSurPlace:
01136			pawn.velocity=vect(0,0,0);
01137			pawn.acceleration=vect(0,0,0);
01138			sleep(0.75);
01139			if (!Johan.bxiiipoisoned && Vsize(pawn.location-xiii.location)>90)
01140			{
01141				goto('VaVersXIII');
01142			}
01143			stop;
01144	Strafe:
01145		if (CHARGE_LES_LOGS) log("strafe");
01146	    If (StrafeDestination())
01147	    {
01148			bStrafe=true;
01149			//HalteAuFeu();
01150			MoveTo(Destination,xiii,0.7);
01151			bStrafe=false;
01152	    }
01153	    goto('vaversxiii');
01154	}
01155	
01156	
01157	// ----------------------------------------------------------------------
01158	// Piquouse
01159	//
01160	// ----------------------------------------------------------------------
01161	State Piquouse //attaque au scalpel en H2H
01162	{
01163		ignores hearnoise;
01164	
01165		event Tick(float DeltaTime)
01166		{
01167			local float distanceaxiii;
01168	
01169			super.tick(DeltaTime);
01170	
01171			if (bTire || Johan.bxiiipoisoned || bChambreXIII)
01172				return;
01173	
01174			if (Johan.NbCoupsDansVide>2)
01175			{
01176				gotostate('attaqueadistance');
01177				return;
01178			}
01179			distanceaxiii=vsize(XIII.location-pawn.location);
01180			if (distanceaxiii<95)
01181			{
01182				fireXIII();
01183				gotostate('piquouse','TapeSurPlace');
01184				return;
01185			}
01186			if (!bstrafe && vsize(XIII.location-LastPosition)>60 && distanceaxiii>85)
01187				gotostate('piquouse','VaVersXIII');
01188		}
01189	
01190		event ReceiveWarning(pawn shooter, float projspeed,vector firedir)
01191		{
01192			// AI controlled creatures may duck if not falling
01193			if (xiii.bisdead || btire || ValeurArmeXIII==0 || bStrafe || frand()<0.4)
01194				return;
01195	
01196			if (!XIIIWeapon(xiii.weapon).AmmoType.bInstantHit)
01197			{
01198				if (CHARGE_LES_LOGS) log(pawn$"evite projectile");
01199				if (pawn.biscrouched)
01200					pawn.shouldcrouch(false);
01201				gotostate('piquouse','strafe');
01202			}
01203			else
01204			{
01205				if (rand(500)>5*ValeurArmeXIII)
01206						return;
01207	            if (CHARGE_LES_LOGS) log(pawn$"je suis vise");
01208				gotostate('piquouse','strafe');
01209			}
01210	    }
01211		function bool StrafeDestination()
01212	    {
01213			local vector pick, pickdir;
01214	        local bool success;
01215			local vector DirectionXIII;
01216	
01217			DirectionXIII=xiii.location-pawn.location;
01218	
01219			if (Frand()>0.5)
01220				pickdir=(DirectionXIII) cross vect(0,0,1);
01221			else
01222				pickdir=(DirectionXIII) cross vect(0,0,-1);
01223			pickdir+=DirectionXIII;
01224	        pickdir.Z = 0;
01225	        pickdir=normal(pickdir);
01226	
01227	
01228	        success = TestDirection(pickdir, pick);
01229	        if (!success)
01230	        {
01231				success = TestDirection(-1*pickdir, pick);
01232				if (!success)
01233					return false;
01234	        }
01235	        Destination = pick;
01236	        return success;
01237		}
01238		event Timer()    //ATTENTION le scalepl H2H ne tir qu'une fois
01239		{
01240			if (bTire && Johan.bWeaponReady)
01241			{
01242				if (xiii.bisdead)
01243				{
01244					gotostate('end');
01245					return;
01246				}
01247				NbCoupsDonnes++;
01248				Johan.PiquouseFire();
01249			}
01250		}
01251		function XIIIBePoisoned()
01252		{
01253			gotostate('piquouse','ChambrerXIII');
01254		}
01255	    function BeginState()
01256	    {
01257			disable('tick');
01258			if (CHARGE_LES_LOGS) log(pawn@"Piquouse     ששששששששששששששששששששששששששששששש");
01259			//updates
01260			bTestSiXIIILoin=true;
01261			Johan.PiquouseDansLaMain(true);
01262			Johan.NbCoupsDansVide=0;
01263	    }
01264	    function EndState()
01265	    {
01266			bTestSiXIIILoin=false;
01267			TimeToLastPiquouse=level.timeseconds;
01268			HalteAufeu();
01269			bChambreXIII=false;
01270			Johan.PiquouseDansLaMain(false);
01271	    }
01272	
01273	begin:
01274		pawn.velocity=vect(0,0,0);
01275		pawn.acceleration=vect(0,0,0);
01276		if (!Johan.bWeaponReady)
01277		{
01278			sleep(0.5);
01279			goto('begin');
01280		}
01281		Johan.arme='piquouse';
01282	  	  if (xiii.bisdead)
01283			{
01284				gotostate('end');
01285			}
01286		 enable('tick');
01287	VaVersXIII:
01288	//log("vaversxiii"@btire@Johan.bxiiipoisoned@bChambreXIII);
01289			LastPosition=XIII.location;
01290			if (actorreachable(xiii))
01291			{
01292				// focalpoint=XIII.location;
01293				// focus=xiii;
01294				V_Pos=XIII.location-pawn.location;
01295				V_Pos=Vsize(V_Pos)*normal(V_Pos+0.7*xiii.velocity)+pawn.location;
01296				MoveTo(V_Pos,xiii);
01297			}
01298			else if (FindBestPathToward(XIII,true))
01299			{
01300				for (iCompteur=0;iCompteur<16;iCompteur++)
01301				{
01302					if (routecache[iCompteur]==none)
01303						break;
01304					focus=none;
01305					focalpoint=1000*(routecache[iCompteur].location-pawn.location)+pawn.location;
01306					MoveToward(routecache[iCompteur],none);
01307				}
01308			}
01309			else
01310			{
01311				log("N'ARRIVE PAS ATTEINDRE XIII POUR LE Piquouser");
01312				CompteurTirSurXIIIDeLoin=0;
01313				bTirSurXIIIDeLoin=true;
01314				gotostate('attaqueadistance');
01315			}
01316			if (Vsize(pawn.location-xiii.location)>90)
01317			{
01318				goto('VaVersXIII');
01319			}
01320			else
01321				fireXIII();
01322	TapeSurPlace:
01323	//log("tape sur place");
01324			pawn.velocity=vect(0,0,0);
01325			pawn.acceleration=vect(0,0,0);
01326			sleep(0.75);
01327			if (!Johan.bxiiipoisoned && Vsize(pawn.location-xiii.location)>90)
01328			{
01329				goto('VaVersXIII');
01330			}
01331			stop;
01332	Strafe:
01333		if (CHARGE_LES_LOGS) log("strafe");
01334	    If (StrafeDestination())
01335	    {
01336			bStrafe=true;
01337			//HalteAuFeu();
01338			MoveTo(Destination,xiii,0.7);
01339			bStrafe=false;
01340	    }
01341	    goto('vaversxiii');
01342	ChambrerXIII:
01343	//log("vchanmber xii");
01344			if (CHARGE_LES_LOGS) log("je chambre");
01345			bChambreXIII=true;
01346			HalteAuFeu();
01347	//[******] faire joli trace
01348			if (fasttrace(pawn.location-200*vector(pawn.rotation)))
01349			{
01350					Moveto(pawn.location-200*vector(pawn.rotation),XIII,3); //fait 2 pas en arriere.
01351					if (vsize(xiii.location-pawn.location)> 180)
01352					{
01353						Johan.PlayProvoc();
01354						sleep(1.44);
01355						Johan.ReleaseAnimControl();
01356					}
01357			}
01358		gotostate('attaqueH2H');
01359	}
01360	
01361	
01362	// ----------------------------------------------------------------------
01363	// Fuite
01364	//
01365	// ----------------------------------------------------------------------
01366	state fuite
01367	{
01368		ignores hearnoise;
01369	
01370		event timer2()
01371		{
01372			gotostate('attaqueadistance');
01373		}
01374	    event ReceiveWarning(pawn shooter, float projspeed,vector firedir) //sert a savoir si bien cache
01375	    {
01376			if (xiii.bisdead || btire || !bPlanqueSurSafePoint || !xiii.weapon.hasammo())
01377				return;
01378			//log("je ne suis pas bien cache cassos");
01379			gotostate('attaqueadistance');
01380	    }
01381	    singular function DamageAttitudeTo(pawn Other, float Damage) //sert a savoir si bien cache
01382	    {
01383			Johan.PlaySndPNJOno(pnjono'Onomatopees.hPNJHurt',Johan.CodeMesh,Johan.NumeroTimbre);
01384			if (xiii.bisdead || !bPlanqueSurSafePoint)
01385				return;
01386			//log("je ne suis pas bien cache cassos");
01387			gotostate('attaqueadistance');
01388	    }
01389	    function SafePoint ChercheSafePoint()  //cherche safepoint le plus pres et pas visible par l'xiii
01390	    {
01391			local vector xiiiPos;
01392			local SafePoint Safe;
01393			local SafePoint BestSafe;
01394			local bool bPasdNMI;
01395			local bool bFirstInPlace;
01396			local bool bAngleDeVUe;
01397			local int i;
01398	
01399			if (xiii.bisdead)
01400				return none;
01401			For(i=0;i<GI.SafePointList.Length;i++)
01402			{
01403				safe=safepoint(GI.SafePointList[i]);
01404				bFirstInPlace= 0.05+Vsize(Safe.location -pawn.location)/pawn.groundspeed<Vsize(Safe.location - xiii.location)/xiii.groundspeed;
01405				if (Safe.baccroupi)
01406					bAngleDeVUe=FastTrace(Safe.location+vect(0,0,8.4),xiii.location + xiii.eyeposition());
01407				else
01408					bAngleDeVUe=FastTrace(Safe.location+xiii.eyeposition(),xiii.location + xiii.eyeposition());
01409				if (OldSafePoint!=safe && !Safe.bAlreadyTargeted && VSize(safe.location-pawn.location)<1000 && (bPasdNMI || !bAngleDeVUe) &&  bFirstInPlace)
01410				{
01411					if (bestsafe!=none)
01412					{
01413	                    if (Vsize(bestsafe.location-pawn.location)>Vsize(safe.location- pawn.location))
01414	                    {
01415							bestsafe=safe;
01416	                    }
01417					}
01418					else
01419	                    bestsafe=Safe;
01420				}
01421	        }
01422	        return bestsafe;
01423	    }
01424	    function BeginState()
01425	    {
01426			//updates
01427			bTestSiXIIIProche=true;
01428			bTestXIIIDelogeable=true;
01429	    }
01430	    function EndState()
01431	    {
01432			if (pawn.biscrouched)
01433				pawn.shouldcrouch(false);
01434			bTestSiXIIIProche=false;
01435			bTestXIIIDelogeable=false;
01436			bPlanqueSurSafePoint=false;
01437			HalteAuFeu();
01438			settimer2(0,false);
01439	    }
01440	Begin:
01441		if (CHARGE_LES_LOGS) log(pawn$" Fuite");
01442		if (xiii.bisdead)
01443		{
01444	        gotostate('end');
01445		}
01446	ChercheSafepoint:
01447		pawn.shouldcrouch(false);
01448	    LastSafepoint=ChercheSafePoint();
01449	    If (LastSafePoint==none)
01450	    {
01451			if (CHARGE_LES_LOGS)  LOG("TROUUUUUVE PAS SAFEPOINT");
01452			if (Vsize(pawn.location-xiii.location)<150)
01453				gotostate('attaqueH2H');
01454			else
01455				gotostate('attaqueADistance');
01456	    }
01457	VaVersSafePoint:
01458		if (ActorReachable(LastSafePoint))
01459		{
01460			MoveToward(LastSafePoint,LastSafePoint,0.8);
01461		}
01462		else if (FindBestPathToward(LastSafePoint,true))
01463		{
01464			for (iCompteur=0;iCompteur<16;iCompteur++)
01465			{
01466				if (routecache[iCompteur]==none)
01467					break;
01468				focus=none;
01469				focalpoint=1000*(routecache[iCompteur].location-pawn.location)+pawn.location;
01470				MoveToward(routecache[iCompteur],none,0.8);
01471			}
01472		}
01473		else
01474		{
01475			log("N'ARRIVE PAS ATTEINDRE LE SAFE POINT"$LastSafePoint);
01476			gotostate('attaqueadistance');
01477		}
01478		OldSafePoint=lastsafepoint;
01479		FocalPoint = XIII.location;
01480		if (lastsafepoint.baccroupi)
01481			pawn.shouldcrouch(true);
01482		focus=xiii;
01483		finishrotation();
01484		bPlanqueSurSafePoint=true;
01485		settimer2(5+5*frand(),false);
01486	SurSafePoint:
01487		log("je suis arrive au safepoint");
01488		if (!LineOfFire())
01489		{
01490			sleep(0.5);
01491			goto('Sursafepoint');
01492		}
01493		else
01494		{
01495			gotostate('attaqueadistance');
01496		}
01497	}
01498	
01499	
01500	// ----------------------------------------------------------------------
01501	// VaChercherScalpels
01502	//
01503	// ----------------------------------------------------------------------
01504	State VaChercherScalpels
01505	{
01506		ignores hearnoise;
01507	
01508		Function TakeScalpels()
01509	    {
01510	        if (CHARGE_LES_LOGS) log("takescalpels *******************");
01511	        focalpoint=pawn.location+1000*vector(Johan.pointscalpel.rotation);
01512	        Johan.PlayTakeScalpels();
01513	        Johan.NbScalpels=10;
01514	    }
01515	    function BeginState()
01516	    {
01517			//updates
01518			if (CHARGE_LES_LOGS) log("VaChercherScalpels");
01519			bTestSiXIIIProche=true;
01520			Johan.PiquouseDansLaMain(false);
01521	    }
01522	    function EndState()
01523	    {
01524			bTestSiXIIIProche=false;
01525			johan.releaseanimcontrol();
01526	    }
01527	
01528	begin:
01529	    HalteAuFeu();
01530	    if (pawn.biscrouched)
01531			pawn.shouldcrouch(false);
01532	    if (Actorreachable(Johan.PointScalpel))
01533	    {
01534			focalpoint=Johan.PointScalpel.location;
01535			MoveToward(Johan.PointScalpel,none);
01536	    }
01537	    else if (FindBestPathToward(Johan.PointScalpel,true))
01538	    {
01539	        for (iCompteur=0;iCompteur<16;iCompteur++)
01540	        {
01541				if (routecache[iCompteur]==none)
01542					break;
01543				focus=none;
01544				focalpoint=1000*(routecache[iCompteur].location-pawn.location)+pawn.location;
01545				MoveToward(routecache[iCompteur],none);
01546	        }
01547	    }
01548	    else
01549	    {
01550			log("N'ARRIVE PAS ATTEINDRE SCALPELS"$Johan.PointScalpel);
01551			 gotostate('piquouse');
01552	    }
01553	    sleep(0.04);
01554	    TakeScalpels();
01555	    finishrotation();
01556	    sleep(0.47);
01557	    Johan.ScalpelDansLaMain(true);
01558		sleep(0.4);
01559	    gotostate('attaqueadistance');
01560	}
01561	
01562	// ----------------------------------------------------------------------
01563	// VaChercherFioles
01564	//
01565	// ----------------------------------------------------------------------
01566	State VaChercherFioles
01567	{
01568	    ignores hearnoise;
01569	
01570		event Timer()
01571		{
01572		}
01573	    Function TakeFiole()
01574	    {
01575	        local int i;
01576	
01577	        if (CHARGE_LES_LOGS)  log("takes fiole *******************");
01578	        focalpoint=pawn.location+1000*vector(Johan.pointfiole.rotation);
01579	        Johan.ScalpelDansLaMain(false);
01580	        Johan.PlayTakeFiole();
01581	    }
01582	
01583		function BeginState()
01584	    {
01585			Johan.PiquouseDansLaMain(false);
01586			//updates
01587			bTestSiXIIIProche=true;
01588	    }
01589	    function EndState()
01590	    {
01591			bTestSiXIIIProche=false;
01592			johan.releaseanimcontrol();
01593	    }
01594	
01595	begin:
01596	    if (CHARGE_LES_LOGS) log(pawn@"Etat VaChercherFioles");
01597		//pawn.velocity=vect(0,0,0);
01598		//pawn.acceleration=vect(0,0,0);
01599		if (xiii.bisdead)
01600		{
01601	        gotostate('end');
01602		}
01603	VaChercherFiole:
01604	    HalteAuFeu();
01605	    if (ActorReachable(Johan.PointFiole))
01606	    {
01607			focalpoint=Johan.PointFiole.location;
01608			MoveToward(Johan.PointFiole,none);
01609	    }
01610	    else if (FindBestPathToward(Johan.PointFiole,true))
01611	    {
01612	        for (iCompteur=0;iCompteur<16;iCompteur++)
01613	        {
01614				if (routecache[iCompteur]==none)
01615					break;
01616				focus=none;
01617				focalpoint=1000*(routecache[iCompteur].location-pawn.location)+pawn.location;
01618				MoveToward(routecache[iCompteur],none);
01619	        }
01620	    }
01621	    else
01622	    {
01623			log("N'ARRIVE PAS ATTEINDRE LE POINT FIOLE"@Johan.PointFiole);
01624			gotostate('attaqueadistance');
01625	    }
01626	    sleep(0.04);
01627	    TakeFiole();
01628	    finishrotation();
01629	    //sleep(0.9);
01630			sleep(0.4);
01631	    Johan.Fioles[NbFiolesRestantes-1].SetDrawType(DT_none);      //vire une fioledeco
01632		Johan.FioleDansLaMain(true);
01633	    NbFiolesRestantes--;
01634		Johan.NbFioles=3;
01635		sleep(0.3);
01636	//	sleep(0.6);
01637		gotostate('attaqueadistance');
01638	}
01639	
01640	// ----------------------------------------------------------------------
01641	// THE END
01642	//
01643	// ----------------------------------------------------------------------
01644	state end
01645	{
01646	    ignores hearnoise;
01647	    event Tick(float DeltaTime)
01648	    {
01649	    }
01650	begin:
01651	    if (CHARGE_LES_LOGS) log(pawn@"END C'EST LA FIN POUR CE BATARD");
01652		XIIIBaseHud(XIIIPlayerController(XIII.Controller).MyHud).AddBossBar(none);
01653	}
01654	
01655	
01656	
01657	defaultproperties
01658	{
01659	     TempsEntreChaqueScalpels=1.000000
01660	     TempsEntreChaqueFioles=2.500000
01661	}

End Source Code