forums | blogs | polls | tutorials | downloads | rules | help

Help with code

Hello. I would like some advice on what to do. I'm making an ability for the tree boss from the second act, but it doesn't work. The idea is this: it fires roots that move back and forth like a boomerang for 20 seconds. I did this, but there is a problem that the direction vector is attached to the boss. That is, when the boss turns and starts walking, the roots begin to move with him. How can this be fixed?
I understand that the problem is in the line

WorldFXMgr.AttachTargetToGo(BaseTarget$, sfx_catalyst$);

But I don’t know what functions are and what they mean.

Code:

[efct_knotted_shambler_line_attack]
{
skrit=[[

	property int    sfx_scriptId$		doc = "ScriptId given at effect script creation time.";
	property Goid	sfx_owner$			doc = "Effect owner goid";
	property Goid	sfx_catalyst$		doc = "Effect catalyst goid";	
	property int    Vector_Change$		doc = "ScriptId given at effect script creation time.";
	property float  Vector_z$		doc = "ScriptId given at effect script creation time.";
	property float  Vector_x$		doc = "ScriptId given at effect script creation time.";
	property int    last_attack$		doc = "ScriptId given at effect script creation time.";

#include "k_inc_effect_utils"
#include "k_inc_flick_utils"
#include "k_inc_mind_utils" 

	startup state Go$
	{
		int LastTarget$;
		int motion_target$;
		start$ at ( 0.0 )
		{
			int BaseTarget$ = WorldFXMgr.CreateTarget();
			WorldFXMgr.AttachTargetToGo(BaseTarget$, sfx_catalyst$);
			LastTarget$ = BaseTarget$;


			// Launch effects
			Vector_Change$ = 1;
			Vector_z$ = 2.5;
			Vector_x$ = 0;
			last_attack$ = 7;

			this.CreateTimer( 3, 0.3 );
			this.CreateTimer( 2, 0.6 );
			this.SetTimerRepeatCount( 3, 66 );	// Repeat count (6 )* 2.5 = distance roots show up (15)
			this.SetTimerRepeatCount( 2, 33 );	// Repeat count (6 )* 2.5 = distance roots show up (1

		}

		trigger OnTimer$( 2 )
		{
			// Create target projectile along target orientation, to detect collisions with actors.
			//{
				my vector v$;
				v$.z = Vector_z$;
				v$.x = Vector_x$;

				motion_target$ = WorldFXMgr.CreateTarget();
				WorldFXMgr.SetTargetPosition( motion_target$, WorldFXMgr.GetTargetPosition( LastTarget$) );

				int SiegeTarget$ = WorldFXMgr.CreateTarget(LastTarget$);
				WorldFXMgr.AddOffsetToTarget(SiegeTarget$, v$);

				my SiegePos mpos$	= WorldFXMgr.GetTargetPosition(motion_target$);
				my SiegePos tpos$	= WorldFXMgr.GetTargetPosition(SiegeTarget$);
				GetSiegeDifference( v$, mpos$, tpos$ );
				Math.Normalize(v$);

				WorldFXMgr.DestroyTarget( SiegeTarget$ );

				string params$;
				StringTool.Assignf( params$, "AccelAlongTargetVector( %f, %f, %f, %f, %f)", v$.x, v$.y, v$.z, 20.0, 20.0);
				WorldFXMgr.AttachTargetSimulation( motion_target$, motion_target$, params$);																										// Width
				int sim$ = WorldFXMgr.AttachTargetSimulation( motion_target$, motion_target$, "MoveWithVelocityColl( false, 1.0, false, false, 0.0, false, false, 0.0, false, true, 0.0, true, false, 4.0, true, false, true )" );
				WorldFXMgr.DetachTargetSimulation( motion_target$, sim$, 0.02 );
			//}
		}

		trigger OnTimer$( 3 )
		{
			Vector_Change$ += 1;
			my vector v$;
			int attacktarger$ = 0;
			if (Vector_Change$ == 6 || Vector_Change$ == 12 || Vector_Change$ == 18 || Vector_Change$ == 24 || Vector_Change$ == 30 || Vector_Change$ == 36 || Vector_Change$ == 42 || Vector_Change$ == 48 || Vector_Change$ == 54  || Vector_Change$ == 60)
			{
				Vector_x$ = 0;
				Vector_z$ = Vector_z$ * (-1);
			}


			v$.z = Vector_z$;
			v$.x = Vector_x$;
			//Math.Normalize(v$);
			int SiegeTarget$ = WorldFXMgr.CreateTarget(LastTarget$);
			WorldFXMgr.AddOffsetToTarget(SiegeTarget$, v$);

			my SiegePos pos$ = WorldFXMgr.getTargetPosition( LastTarget$ );
			my vector orient$ = WorldFXMgr.GetTargetVectorToTarget( SiegeTarget$, LastTarget$);			
			int modeltarget$ = WorldFXMgr.CreateTarget();
			WorldFXMgr.SetTargetPosition(modeltarget$, pos$);
			Math.Normalize(orient$);
			orient$.x = orient$.x * 1.1;
			orient$.z = orient$.z * 1.1;
			WorldFXMgr.SetTargetOffset(modeltarget$, orient$);
			pos$ = WorldFXMgr.GetTargetPosition( SiegeTarget$ );
			int modeltargetoriented$ = WorldFXMgr.CreateTarget();
			WorldFXMgr.SetTargetPosition(modeltargetoriented$, pos$);			
			orient$ = WorldFXMgr.GetTargetVectorToTarget(modeltargetoriented$, LastTarget$);
			//orient$ = WorldFXMgr.GetTargetVectorToTarget( LastTarget$, modeltargetoriented$);
			Math.Normalize(orient$);
			my Quat Vquat$;
			Math.QuatFromDirection(Vquat$, orient$);
			WorldFXMgr.SetTargetOrientation( modeltargetoriented$, Vquat$ );

			LastTarget$ = SiegeTarget$;

			{	// Create Root animation
				//int effect$ = WorldFXMgr.CreateAnimatedModel( SiegeTarget$, "m_i_glb_roots" );
				int effect$ = WorldFXMgr.CreateAnimatedModel( modeltargetoriented$, "m_i_glb_roots" );

				WorldFXMgr.QueueAnimatedModelAnimChore( effect$, "a_i_glb_roots-reveal");
				//WorldFXMgr.SetAnimatedModelRenderOrientOnly( effect$, true );

				WorldFXMgr.FadeAnimatedModel( effect$, 3.0, 0.0, 1.0, 1.0 );
				WorldFXMgr.ScaleAnimatedModel( effect$, Math.RandomFloat(1.5, 2.5), 0 );
			}

			int i$ = 0;
			string params$;

			while ( i$ < 6 ) //6
			{	// Create rock chunks

				int rock_target$ = WorldFXMgr.CreateTimedTarget( 1.5, true );
				WorldFXMgr.SetTargetPosition( rock_target$, WorldFXMgr.GetTargetPosition( SiegeTarget$ ));
				my vector offset$;
				offset$.y = 0.2;
				WorldFXMgr.SetTargetOffset( rock_target$, offset$ );
				float scale$ = Math.RandomFloat( 0.5, 1.5 );

				WorldFXMgr.AttachTargetSimulation( rock_target$, rock_target$, "AccelAlongTargetVector( 0.0, 1.0, 0.0, 3.0, 9.0 )" );
				WorldFXMgr.AttachTargetSimulation( rock_target$, rock_target$, "AccelRingPerpToTargetVector( 0.0, 1.0, 0.0, 1.0, 10.0 )" );
				WorldFXMgr.AttachTargetSimulation( rock_target$, rock_target$, "ApplyGravity( -15.0, 0.0, 0.0, 0.0 )" );
				StringTool.Assignf( params$, "MoveWithVelocityColl( true, 0.4, false, false, 0.0, false, false, 0.0, false, false, 0.0, false, false, %f, false, true )", scale$ );
				WorldFXMgr.AttachTargetSimulation( rock_target$, rock_target$, params$ );

				int rock_effect$ = WorldFXMgr.CreateModelEffect( rock_target$, "m_i_frg_frag-stone-01", 0xFFFFFFFF, 0.0, true );
				WorldFXMgr.SetEffectLighting( rock_effect$, true, true );
				StringTool.Assignf( params$, "ScaleChange( 0.0, 0.1, %f, 0.0 )", scale$ );
				WorldFXMgr.AttachSimulation( rock_effect$, params$, 0.0 );
				WorldFXMgr.AttachSimulation( rock_effect$, "AlphaChange( 0.8, 1.5, 0.0, 0.0 )", 0.0 );
				StringTool.Assignf( params$, "RotateAroundTargetVector( %f, %f, %f, %f, false, 0.0, 0.0, 0.0 )", Math.RandomFloat( -1, 1 ), Math.RandomFloat( -1, 1 ), Math.RandomFloat( -1, 1 ), Math.RandomFloat( 4.0, 10.0 ) );
				WorldFXMgr.AttachSimulation( rock_effect$, params$, 0.0 );
				WorldFXMgr.AttachSimulation( rock_effect$, "KillEffectAtZero()", 0.1 );
				i$ += 1;
			}

			{	// Dust effect
				int effect$ = WorldFXMgr.CreateParticleEffect( SiegeTarget$ );
				WorldFXMgr.SetTargetDependence( effect$, true, false );
				WorldFXMgr.SetEffectTexture( effect$, "b_sfx_mist_02");
				WorldFXMgr.SetQuadRendering( effect$, true );
				WorldFXMgr.AttachSimulation( effect$, "SpawnImmediately( 40, 0x00564532, 0x00564532, 1.0, 2.0 )", 0.0 );
				WorldFXMgr.AttachSimulation( effect$, "PositionInCylinder( 0.2, 3, 0.2, -0.3)", 0.0 );
				WorldFXMgr.AttachSimulation( effect$, "AlphaChange( 0.0, 0.1, 0.2, 0 )", 0.0 );
				WorldFXMgr.AttachSimulation( effect$, "AlphaChange( 1.6, 3.0, 0.0, 0.0 )", 0.0 );
				WorldFXMgr.AttachSimulation( effect$, "ScaleChange( 0.1, 1.0, 4.0, 0.0 )", 0.0 );
				StringTool.Assignf( params$, "ApplyForceRingPerpToTargetVector( 0.0, 1.0, 0.0, %f, 0.0, 0.0, 0.0 )", Math.RandomFloat( 0.3, 1.5) );
				WorldFXMgr.AttachSimulation( effect$, params$, 0.0 );
				WorldFXMgr.AttachSimulation( effect$, "MoveWithVelocity()", 0.0 );
				WorldFXMgr.SetEffectSrcBlend( effect$, /*ePixelBlend srcBlend*/ PB_SRCALPHA );
				WorldFXMgr.AttachSimulation( effect$, "KillEffectAtZero()", 0.0 );
			}


		}

		event OnEffectWorldMessage$( eWorldEvent e$, WorldMessage msg$ )
		{
			goid collision_object$ = msg$.GetSendFrom();

			if( e$ == WE_TARGET_COLLIDED)
			{
				// Send message to owner to cause damage to this guy.
				if ( IsServerLocal )
				{
					PostWorldMessage( WE_USER_TREE_SHOOT_HIT, sfx_owner$, sfx_owner$, MakeInt(collision_object$), 0 );
				}

				{	// Create Root hit animation
					int source_target$ = WorldFXMgr.CreateTarget();
					my SiegePos source_pos$ = WorldFXMgr.GetTargetPosition( motion_target$ );
					AIQuery.GetTerrainPosition( source_pos$, source_pos$ );
					WorldFXMgr.SetTargetPosition( source_target$, source_pos$);

					int destination_target$ = WorldFXMgr.CreateTarget();
					WorldFXMgr.SetTargetToGo( destination_target$, collision_object$ );
					my SiegePos dest_pos$ = WorldFXMgr.GetTargetPosition(destination_target$);

					// Move source closer to victim, so its at least 0.5 units away
					my vector offset$;
					GetSiegeDifference( offset$, source_pos$, dest_pos$ );
					offset$.x = offset$.x * 0.8;
					offset$.y = offset$.y * 0.8;
					offset$.z = offset$.z * 0.8;
					WorldFXMgr.AddOffsetToTarget( source_target$, offset$ );

					// Set orientation
					my vector v$;
					GetSiegeDifference( v$, dest_pos$, source_pos$ );
					Math.Normalize(v$);
					v$.x = -v$.x;
					v$.y = -v$.y;
					v$.z = -v$.z;
					my Quat	orientation$;
					Math.QuatFromDirection(orientation$, v$);
					WorldFXMgr.SetTargetOrientation( source_target$, orientation$);

					// Launch effects
					{	// Hit roots.
						int effect$ = WorldFXMgr.CreateAnimatedModel( source_target$, "m_i_glb_roots-hit" );
						WorldFXMgr.QueueAnimatedModelAnimChore( effect$, "a_i_glb_roots-hit-reveal");
						WorldFXMgr.FadeAnimatedModel( effect$, 2.0, 0.0, 0.3, 1.0 );
						WorldFXMgr.ScaleAnimatedModel( effect$, 0.7, 0 );
					}
					{	// Dust effect
						int effect$ = WorldFXMgr.CreateParticleEffect( source_target$ );
						WorldFXMgr.SetTargetDependence( effect$, true, false );
						WorldFXMgr.SetEffectTexture( effect$, "b_sfx_mist_02");
						WorldFXMgr.SetQuadRendering( effect$, true );
						WorldFXMgr.AttachSimulation( effect$, "SpawnImmediately( 40, 0x00564532, 0x00564532, 1.0, 2.0 )", 0.0 );
						WorldFXMgr.AttachSimulation( effect$, "PositionInCylinder( 0.2, 3, 0.2, -0.3)", 0.0 );
						WorldFXMgr.AttachSimulation( effect$, "AlphaChange( 0.0, 0.1, 0.2, 0 )", 0.0 );
						WorldFXMgr.AttachSimulation( effect$, "AlphaChange( 0.8, 2.0, 0.0, 0.0 )", 0.0 );
						WorldFXMgr.AttachSimulation( effect$, "ScaleChange( 0.1, 1.0, 4.0, 0.0 )", 0.0 );
						WorldFXMgr.AttachSimulation( effect$, "MoveWithVelocity()", 0.0 );
						WorldFXMgr.SetEffectSrcBlend( effect$, /*ePixelBlend srcBlend*/ PB_SRCALPHA );
						WorldFXMgr.AttachSimulation( effect$, "KillEffectAtZero()", 0.0 );
					}
				}
			}
		}

		clean_up$ at ( 25.0 )
		{
			WorldFXMgr.DestroyEffectScript( sfx_scriptId$ );
		}
	}
]];
}

[efct_knotted_shambler_line_charge]
{
skrit=[[

	property int    sfx_scriptId$		doc = "ScriptId given at effect script creation time.";
	property Goid	sfx_owner$			doc = "Effect owner goid";

	startup state Go$
	{
		start$ at ( 0.0 )
		{
		}

		clean_up$ at ( 1.0 )
		{
			WorldFXMgr.DestroyEffectScript( sfx_scriptId$ );
		}
	}
]];
}

Hi, I have no idea about the problem so I can't help.
But maybe you can surround your code with <code>...</code> or the BBCode variant [code]...[/code]? So that the code is formatted somewhat readable...

Also, is your code project on GitHub? This way people can see it more easily and use features such like pull requests

Hi, my friend over on Discord suggests the following: change WorldFXMgr.AttachTargetToGo(BaseTarget$, sfx_catalyst$); to WorldFXMgr.SetTargetPosition(BaseTarget$, sfx_catalyst$.Go.Placement.Position);
(He tries to get an account for siegetheday but this site is old n buggy.)
If it doesn't help, come over to Discord! Wink https://discord.com/channels/373223103985090581/397476722691407874

Honestly I cannot remember syntax details.... Shock

One approach was to create an extra target/point at the position of the caster.

This can happen by creating a dummy object at the place of the caster and from then on attach the effect there.
A combination of WorldFXMgr.CreateTarget() + WorldFXMgr.SetTargetPosition() may work too, some additional parameters may be needed though to get it independent.

Good luck!