/*

		vector_attach.X = StringToFloat( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells_main', 'debug_pos_x' ) );
		vector_attach.Y = StringToFloat( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells_main', 'debug_pos_y' ) );
		vector_attach.Z = StringToFloat( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells_main', 'debug_pos_z' ) );
		
		rotation.Roll += StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_rot_roll' ) );
		rotation.Pitch += StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_rot_pitch' ) );
		rotation.Yaw += StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_rot_yaw' ) );
		
		main_effect = (CEntity)theGame.CreateEntity( (CEntityTemplate)LoadResource( parent.templatename ,true ), position );
		main_effect.CreateAttachment( thePlayer, 'r_weapon', vector_attach, rotation );
		
		main_effect.PlayEffect('fire_gnosis_cone_sword');
		main_effect.BreakAttachment();










										/*
										lenght = 0.9;
										
										rotation.Roll += StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells_main', 'debug_rot_roll' ) );
										rotation.Pitch += StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells_main', 'debug_rot_pitch' ) );
										rotation.Yaw += StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells_main', 'debug_rot_yaw' ) );
										*/


			/*
			if( !thePlayer.GetInventory().IsItemHeld(xid) )
			{
				xbow.SetHideInGame(false);
				xbow.SetHideInGame(true);
			}
			else
			{
				xbow.SetHideInGame(false);
			}
			*/
			
			steelcomp.SetVisible(false); 
			silvercomp.SetVisible(false); 
			
			if ( thePlayer.GetInventory().IsItemHeld(steelid) || thePlayer.GetInventory().IsItemHeld(silverid) )
			{
				effect_sword.PlayEffectSingle('electricity');
			}
			else
			{
				effect_sword.StopAllEffects();
			}
			
			
						//if( !thePlayer.GetInventory().IsItemHeld(steelid) )
						//{
						//	//swordsteel.SetHideInGame(false);
						//	//swordsteel.SetHideInGame(true);
						//}
						//else
						//{
						//	steelcomp.SetVisible(true); 
						//	//swordsteel.SetHideInGame(false);
						//}
			
						//if( !thePlayer.GetInventory().IsItemHeld(silverid) )
						//{
						//	//swordsilver.SetHideInGame(false);
						//	//swordsilver.SetHideInGame(true);
						//}
						//else
						//{
						//	silvercomp.SetVisible(true); 
						//	//swordsilver.SetHideInGame(false);
						//}
		}










	private entry function cast_spells_winter_tornado_init()
	{
		var movementAdjustor 		: CMovementAdjustor;
		var ticket 					: SMovementAdjustmentRequestTicket;
		var targetNode 				: CNode;
		
		if ( parent.spell_name == 'winter_souls_tornado' )
		{
			parent.templatename = "dlc\magicspellsrev\data\entities\wintersouls_tornado_init.w2ent";
			position = thePlayer.GetWorldPosition() + thePlayer.GetWorldForward()*6;
			main_effect = (CEntity)theGame.CreateEntity( (CEntityTemplate)LoadResource( parent.templatename ,true ), TraceFloor( position ), thePlayer.GetWorldRotation() );
			main_effect.StopAllEffectsAfter(2.8);
			main_effect.DestroyAfter(4);
			main_effect.AddTag('spells_rimrgand_mouth');
			
			starttime = EngineTimeToFloat( theGame.GetEngineTime() );
			
			cast_mouth = true;
			
			//while ( ( EngineTimeToFloat( theGame.GetEngineTime() ) - starttime ) < 2.7 )
			while ( true && cast_mouth )
			{
				//theGame.witcherLog.AddMessage("CASTING" );
				Sleep( theTimer.timeDelta );
				
				movementAdjustor = thePlayer.GetMovingAgentComponent().GetMovementAdjustor();
				ticket = movementAdjustor.CreateNewRequest( 'Spells_Rimrgand_tornado' );
				//targetNode = theGame.GetNodeByTag( 'spells_rimrgand_mouth' );
				//movementAdjustor.RotateTowards( ticket, targetNode );
				movementAdjustor.MaxRotationAdjustmentSpeed( ticket, 500 );
				movementAdjustor.MaxLocationAdjustmentSpeed( ticket, 500 );
				movementAdjustor.RotateTo( ticket, VecHeading( theCamera.GetCameraDirection() ) );
				
				theGame.GetEntityByTag( 'spells_rimrgand_mouth' ).TeleportWithRotation( TraceFloor( thePlayer.GetWorldPosition() + thePlayer.GetWorldForward()*6 ),thePlayer.GetWorldRotation()  );
			}
			
		}
	}





				vector_attach.X = StringToFloat( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells_main', 'debug_pos_x' ) );
				vector_attach.Y = StringToFloat( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells_main', 'debug_pos_y' ) );
				vector_attach.Z = StringToFloat( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells_main', 'debug_pos_z' ) );






		OK, so the principle is:
		1. Every class in the game can have states added to them, even if they're not declared as statemachine 
		(you get a warning during script compile if you try to add a state to a non-statemachine, but this is only visible if there's also a compilation error)
		2. In my case, the class I want to modify is a statemachine, so no issue.
		3. States are the only class code (that I know of) that can be specified outside the main class;  
		the format as you probably know is:  state StateName in ClassName [extends ParentStateName].  This can be specified anywhere, including in a new local script
		4. You can then switch that state with ClassName.GotoState('StateName');
		5. The reason to do all this is that, because the state is 'in' the class, it can access protected variables on the class. 
		 Not private of course, but by doing this you've expanded your access to protected + public variables/functions.
		So in my own example:  the stash inventory is contained on the W3HorseManager, defined in horseManager.ws.  
		This is stored in W3PlayerWitcher, and can be accessed externally with  GetWitcherPlayer().GetHorseManager(), and this is what the vanilla stash code does.

		Now, the actual W3HorseManager class is stored on W3PlayerWitcher in an EntityHandle, defined as protected saved    var horseManagerHandle            : EntityHandle;

		So, by injecting a new state into W3PlayerWitcher, I can spawn a new subclass of W3HorseManager, 
		and update horseManagerHandle on W3PlayerWitcher to point to my new version of W3HorseManager.

		And in that new subclass, I can do my custom stuff.
		In order to trigger all that, I just do: GetWitcherPlayer().GotoState('SMinject')
		Then once I've done what I need to in my new state SMinject, I call parent.GotoState(prevState); 
		to immediately W3PlayerWitcher back to whatever state it was in before (usually 'Exploration')






	
if ( !thePlayer.HasBuff( EET_Blizzard ) )
{
	if ( VecDistance( thePlayer.GetWorldPosition(), this.GetWorldPosition() ) <= 2.7 )
	{
		theGame.SetTimeScale(0.5, theGame.GetTimescaleSource(ETS_CFM_On), theGame.GetTimescalePriority(ETS_CFM_On) );
		theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_CFM_On) );
		theGame.SetTimeScale(0.5, theGame.GetTimescaleSource(ETS_CFM_On), theGame.GetTimescalePriority(ETS_CFM_On) );
	}
	else 
	{
		theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_CFM_On) );
	}
}
theGame.witcherLog.AddMessage("GetTimescaleSource: " + NameToString(theGame.GetTimescaleSource(7)));	
theGame.witcherLog.AddMessage("GetTimescalePriority: " + (string)theGame.GetTimescalePriority(7));	


var entss : array<CGameplayEntity>; var yrden : W3YrdenEntity;

FindGameplayEntitiesInSphere( entss, thePlayer.GetWorldPosition(), 5, 99 ); 

for( i = 0; i < entss.Size(); i += 1 )
{
	yrden = (W3YrdenEntity)entss[i];
	
	if( yrden )
	{
		theGame.witcherLog.AddMessage("YRDEN");
	}
}


		timer function playeraction( deltaTime : float , id : int)
		{
					sett.blendIn = 1.0f;
					sett.blendOut = 1.0f;
				thePlayer.GetRootAnimatedComponent().PlaySlotAnimationAsync( 'man_mage_sand_cage_01', 'PLAYER_ACTION_SLOT', sett );
		}

					thePlayer.SetBehaviorVariable( 'playerExplorationAction', (float)(int)1);
					if ( thePlayer.RaiseEvent('playerActionStart') )
					{ AddTimer('playeraction',0.0); }



		if ( GetNPC() == thePlayer )
		{
			theGame.witcherLog.AddMessage( "OnGameplayEvent " + (string)eventName );
		}





	if ( FactsQuerySum("testing_traps") <=0 )
	{
		theGame.witcherLog.AddMessage("DAMAGE = " + (string)damage_value );
		theGame.witcherLog.AddMessage("VICTIMS = " + (string)victims.Size() );
		theGame.witcherLog.AddMessage("DAMAGE % = " + (string)( 0.01+( spellpower_final* 0.4 ) ) );
		FactsAdd("testing_traps",,1);
	}

				AddTimer( timerName, period, repeats,scatter,group,saveable,overrideExisting) : int;
				
				
			for( i = 0; i < hitCollisionsGroups.Size(); i += 1 )
			{
				theGame.witcherLog.AddMessage("COLL   !!    " + (string)hitCollisionsGroups[i] );
			}



		rotation.Roll += StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_rot_roll' ) );
		rotation.Pitch += StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_rot_pitch' ) );
		rotation.Yaw += StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_rot_yaw' ) );
		
		position.X += StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_pos_x' ) );
		position.Y += StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_pos_y' ) );
		position.Z += StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_pos_z' ) );












				blackball = (W3BlackFireball)theGame.CreateEntity( (CEntityTemplate)LoadResource( "dlc\magicspellsrev\data\entities\black_fire_projectile.w2ent",true ), pos );
				blackball.Init(NULL);
				blackball.PlayEffect( 'venom' );
				blackball.ShootProjectileAtPosition(0, 8, thePlayer.playerAiming.GetThrowPosition() );
				blackball.DestroyAfter(7);
				
				fxEntity = (CEntity)theGame.CreateEntity( (CEntityTemplate)LoadResource( "dlc\magicspellsrev\data\entities\fire_gnosis.w2ent" ,true ), pos );
				fxEntity.PlayEffect('fire_gnosis_cone');
				fxEntity.PlayEffect('fire_gnosis_cone');
				fxEntity.CreateAttachment(blackball,, 
				Vector( 
				StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_pos_x' ) ), 
				StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_pos_y' ) ), 
				StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_pos_z' ) ) 
				),	
				EulerAngles(
				StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_rot_roll' ) ), 
				StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_rot_pitch' ) ),	
				StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_rot_yaw' ) ) 
				) );





	event OnProjectileInit()
	{
				fxEntity = (CEntity)theGame.CreateEntity( (CEntityTemplate)LoadResource( "dlc\magicspellsrev\data\entities\fire_gnosis.w2ent" ,true ), GetWorldPosition() );
				fxEntity.PlayEffect('fire_gnosis_cone');
				fxEntity.CreateAttachment(this,, 
				Vector( 
				StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_pos_x' ) ), 
				StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_pos_y' ) ), 
				StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_pos_z' ) ) 
				),	
				EulerAngles(
				StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_rot_roll' ) ), 
				StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_rot_pitch' ) ),	
				StringToInt( theGame.GetInGameConfigWrapper().GetVarValue( 'magic_spells', 'debug_rot_yaw' ) ) 
				) );
		comp = (CEffectDummyComponent)this.GetComponentByClassName('CEffectDummyComponent');		
		
		init_pos = comp.GetWorldPosition();
		
		AddTimer('Sampling', 0.05, true);
		Sampling(0.f);
	}
	
	timer function Sampling ( dt : float, optional id : int)
	{
		var newPosition : Vector;
		var zDiff : float;
		var newPosition2 : Vector;
		
		newPosition = comp.GetLocalPosition();
		
		newPosition2 = comp.GetWorldPosition();
		
		if ( ( newPosition2.Z - init_pos.Z ) >0 )
		{
			newPosition.Z += ( newPosition2.Z - init_pos.Z ) ;
			comp.SetPosition( newPosition );
		}
		
		if ( doTrace ( comp, zDiff) )
		{
			//if ( zDiff >0 )
			//{
				newPosition.Z += zDiff + 1;
				comp.SetPosition( newPosition );
				Loop();
			//}
		}
	}
	
	private function Loop()
	{
		//PlayEffect(effectName);
	}
	
	private function doTrace( comp: CComponent, out outZdiff : float ) : bool
	{
		var currPosition,outPosition, outNormal, tempPosition1, tempPosition2 : Vector;
		
		currPosition = comp.GetWorldPosition();
		
		tempPosition1 = currPosition;
		tempPosition1.Z -= 5;
		
		tempPosition2 = currPosition;
		tempPosition2.Z += 2;
		
		if ( theGame.GetWorld().StaticTrace( tempPosition2, tempPosition1, outPosition, outNormal ) )
		{
			if ( ( currPosition.Z - init_pos.Z ) >0 )
			{
				outZdiff = outPosition.Z - currPosition.Z;
				//theGame.witcherLog.AddMessage("outZdiff  " + (string)( currPosition.Z - init_pos.Z ) );
				return true;
			}
			else
			{
				return false;
			}
		}
		
		return false;
	}


   
					//sett.blendIn = 1.0f;
					//sett.blendOut = 1.0f;
					//thePlayer.GetRootAnimatedComponent().PlaySlotAnimationAsync( 'man_mage_lightning_01', 'PLAYER_SLOT', sett );


















	timer function fire_gnosis_stream( deltaTime : float , id : int)
	{
		var main_effect					  					: CEntity;
		
		templatename = "dlc\magicspellsrev\data\entities\black_fire_amulet.w2ent";
		
		main_effect = (CEntity)theGame.CreateEntity( (CEntityTemplate)LoadResource( templatename ,true ), thePlayer.GetWorldPosition() );
		main_effect.PlayEffect('black_fire_stream');
		main_effect.CreateAttachment( thePlayer, 'l_weapon');
		main_effect.AddTag('spells_alt_stream');
		
		AddTimer( 'deal_damage_stream_gnosis', 0.01, true );
		
		spellpower_final = get_spellpower_spells( false, S_Magic_2);
		
		stamina_cost = CalculateAttributeValue( GetWitcherPlayer().GetSkillAttributeValue( signskill, 'stamina_cost_per_sec', false, true ) * 0.5 );
		stamina_cost += stamina_cost * get_stamina_cost_mult_streams(); 
		
		stamina_delay = CalculateAttributeValue( GetWitcherPlayer().GetSkillAttributeValue( signskill, 'stamina_delay', false, true ) );
		stamina_delay += stamina_delay * get_stamina_delay_mult(); 
	}
	timer function deal_damage_stream_gnosis( deltaTime : float , id : int)
	{
		var damage_action_stream				: W3DamageAction;
		var victims 							: array<CActor>;
		var victim								: CActor;
		var damage 								: float;
		var channelDmg 							: SAbilityAttributeValue;
		var i									: int;
		var castDir								: Vector;
		var targetPosition						: Vector;
		var position							: Vector;
		var slotMatrix 							: Matrix;
		var effectentity						: CEntity;
		var coll, normal 						: Vector;
		var lastpos 							: Vector;

		if (  thePlayer.GetStatPercents( BCS_Stamina ) > 0.01f && thePlayer.GetBehaviorVariable	( 'IsCastingSign' ) == 1 )
		{
			thePlayer.CalcEntitySlotMatrix('l_weapon', slotMatrix);
			position = MatrixGetTranslation(slotMatrix);
			
			castDir 		= MatrixGetAxisX( thePlayer.GetBoneWorldMatrixByIndex( thePlayer.GetBoneIndex( 'l_weapon' ) ) );
			targetPosition  = position + ( 6 * castDir );
			
			hand_aim_position = position;
			hand_aim_direction = castDir;
		
			victims = thePlayer.GetNPCsAndPlayersInCone( 6, VecHeading( castDir ), 25, 20, , FLAG_Attitude_Hostile + FLAG_OnlyAliveActors);
			for (i=0; i<victims.Size(); i+=1)			
			{
				victim = victims[i];
				
				channelDmg = thePlayer.GetSkillAttributeValue(S_Magic_s02, 'channeling_damage', false, true);
				channelDmg += thePlayer.GetSkillAttributeValue(S_Magic_s02, 'channeling_damage', false, false) * thePlayer.GetSkillLevel(S_Magic_s02); 	// delete for vanilla
				damage = channelDmg.valueAdditive + channelDmg.valueMultiplicative * victim.GetMaxHealth();
				damage += damage * spellpower_final * get_spellpower_mult();
				damage += damage * get_streams_increase();
				damage += damage * get_overall_mult();
				damage *= 1.75;																									// delete for vanilla
				damage *= deltaTime;
			
				damage_action_stream = new W3DamageAction in this;
				if(	!victim.IsHuman() && !victim.IsAnimal()	)
					{	damage += damage * get_monsters_mult();	}
				
				damage_action_stream.Initialize(thePlayer,victim,this,thePlayer.GetName()+"_sign",EHRT_None,CPS_SpellPower,false, false, true, false );
				damage_action_stream.AddDamage( theGame.params.DAMAGE_NAME_FIRE, sp_fire_dmg_mod() * damage );
				damage_action_stream.AddEffectInfo(EET_SpellsSlowDownAverage, MaxF( 3, MinF( 8, spellpower_final * 3 ) ) );
				if( RandF()<0.05 ) { damage_action_stream.AddEffectInfo( EET_Burning, 1 ); }
				
				damage_action_stream.SetIsDoTDamage( deltaTime );
					
				damage_action_stream.SetHitEffect('');
				damage_action_stream.SetHitEffect('', true );
				damage_action_stream.SetHitEffect('', false, true);
				damage_action_stream.SetHitEffect('', true, true);
				
				theGame.damageMgr.ProcessAction( damage_action_stream );
				delete damage_action_stream;
			}
			
			if( theGame.GetWorld().SweepTest( position + castDir, targetPosition, 0.3, coll, normal, collisions_stream ) )
			{
				lastpos = coll;
				theGame.GetEntityByTag( 'spells_stream_collision' ).PlayEffectSingle('collision_fx');
			}
			else
			{
				theGame.GetEntityByTag( 'spells_stream_collision' ).StopAllEffects();
			}
			
			if ( !theGame.GetEntityByTag( 'spells_stream_collision' ) )
			{
				effectentity = theGame.CreateEntity( (CEntityTemplate)LoadResource("dlc\magicspellsrev\data\entities\black_fire_stream_collision.w2ent",true), targetPosition, thePlayer.GetWorldRotation() );
				effectentity.AddTag('spells_stream_collision');
			}
			else
			{
				theGame.GetEntityByTag( 'spells_stream_collision' ).Teleport(lastpos);
			}
			
			GetWitcherPlayer().DrainStamina( ESAT_FixedValue, stamina_cost * deltaTime, stamina_delay ); 
		}
		else
		{
			thePlayer.SoundEvent("gui_no_stamina");
			AddTimer( 'interrupt_stream', 0 );
		}
	}
	timer function interrupt_stream( deltaTime : float , id : int)
	{
		var i								: int;
		var ents_destroy					: array< CEntity >;
		var ent_destr 	 	   				: CEntity;
		
		thePlayer.SetBehaviorVariable	( 'alternateSignCast', 0 );
		thePlayer.SetBehaviorVariable	( 'IsCastingSign', 0 );
		alternate = false;
		thePlayer.PopState();
		
		RemoveTimer('deal_damage_stream_gnosis');
		
		theGame.GetEntityByTag( 'spells_stream_collision' ).StopAllEffects();
		theGame.GetEntityByTag( 'spells_stream_collision' ).DestroyAfter(2);
		theGame.GetEntityByTag( 'spells_stream_collision' ).RemoveTag( 'spells_stream_collision' );
		
		theGame.GetEntitiesByTag('spells_alt_stream',ents_destroy);
		for( i=0; i<ents_destroy.Size(); i+=1 )
		{
			ent_destr = ents_destroy[i];
			ent_destr.StopAllEffects();
			ent_destr.DestroyAfter(3);
		} 	
	}




				checkHeading = VecHeading( actor.GetWorldPosition() - thePlayer.GetWorldPosition() );
				playerToHeadingDist = AngleDistance( GetHeading(), checkHeading );
				
				theGame.witcherLog.AddMessage("playerToHeadingDist  " + playerToHeadingDist );
				theGame.witcherLog.AddMessage("playerToHeadingDist ABS  " + AbsF( playerToHeadingDist ) );





*/