SIEGE UNIVERSITY 2

Siege University II Tutorials
Modding FAQ
095: Upgrading DSII
100: The Basics of Siege Editor
201: Compass Map Radar
202: Conversations
203: Journal
204: Quest Indicator Icons
205: Start Positions
206: Teleporters
207: Town Portal Restrictions
208: Weapon Effects
209: Flick
210: Tuning Grids
211: Setting Up Good Map Lighting
212: Setting Up Simple Node Fading
215: Building Data Tables

Siege University I Tutorials
200: Concepts and Terminology
201: Templates
203: Triggers
204: Moods
205: Fades
206: Elevators
211: Naming Key
213: Dungeon Siege Resource System
301: Introduction to Dungeon Siege Architecture

Third Party Tutorials
A Simple Mod Part One - Armor Textures
A Simple Mod Part Two - A New Armor
Beginners Guide to Stitching Regions
How to Open and Create Tanks
Making Chants Work in a New Map
Ornaments
Understanding the NKK

Useful Links
Siegetheday.org
Dungeon Siege Outpost
Dungeon Raider
Kdawg.org - List of useful Links
MCarp DS Nodes
Dungeon Siege 2 at Gamefront
Broken World at Gamefront

Overview


Ok so here is the scoop when it comes to effects on weapons:

The effect system in DSII is radically different from the system in DS1.

Due to its constraints we are required to make sure that each of the effects are safe for streaming and/or multiplayer.

With this in mind weapon effects are attached in the form of an enchantment called "alter_generic"

By placing a magic block with enchantments in our weapon template, we can use an enchantment to attach effects to weapons.

Inside the enchantment block we use the special properties called "custom_effect" and "custom_effect_skrit" which allows us to run a skrit function- in this case containing the effect for our weapon.

By assigning the function "weapon_enchant.skrit" to the custom_effect_skrit property, we are able to attach effects to the weapon and it's ammo, as well as run an effect when the weapon hits an enemy. This is done by assigning a flickFX script to the corresponding property of the weapon_enchant component.

Lets take a look at a magic block so you can better visualize what we are describing here:

1       [magic]

2       {

3               [enchantments]

4               {

5                       [*]

6                       {

7                               alteration            = alter_generic;

8                               value                 = 1;

9                               duration              = #infinite;

10                              is_permanent          = true;

11                              is_single_instance    = false;

12                              custom_effect         = "lyssasbow";

13                              custom_effect_skrit   = world\global\enchantments\weapon_enchant.skrit

14                              ?bow_ffx              = ffx_wpn_lyssasbow

15                              &projectile_ffx       = ffx_spell_fire_arrow

16                              &hit_ffx              = ffx_spell_fire_sword_hit;

17                      }

18              }

19      }

 

DS2 uses flick effects as the means to connect effects to objects. In the case of weapons they are assigned to properties with in the weapon_enchant.skrit. In the example above, the effects are being attached to a bow. When attaching effects to a different class of weapon, you will want to override different properties of weapon_enchant.skrit. For example, a sword will not need a flickFX assigned to bow_ffx or projectile_ffx- you will want to assign a flickFX to weapon_ffx instead.

As you can see we have created a magic block with an enchantment block.
Lines 13-16 show how we are declaring the custom effect. In line 14 we are adding the flickFX that will give the bow it's effect, and on line 15 we are assigning the flickFX that will give the projectile it's effect. In line 16 we are assigning the flick that will be displayed on the hit.

Lines 13-16 are in reality a single line ( ending with ';' on line 16 ) where property information is passed by using the tokens '?' and '&' in to the weapon_enchant skrit. You should not worry about the reasons for this but rather make sure that you include them when you make your weapon with an effect.

Now lets look at the flick function:

1       [ffx_spell_fire_arrow]

2       {

3               thread main

4               {

5                       RunEffect "efct_spell_fire_arrow", wait;

6               }

7       }

 

The effect calls a single effect "efct_spell_fire_arrow" ( line 5 ), and because the way weapon_enchant calls projecile_ffx ( ffx_spell_fire_arrow in our case ) the effect that is requested to run will be attached to the arrow of the weapon.

Now lets look at part of the effect skrit itself:

1       [efct_spell_fire_arrow]

2       {

3       skrit=[[

4

5               property Goid   sfx_owner$      doc = "Ammo goid, owner dependent effect, so we die when the ammo dies.";

6               property Goid   sfx_catalyst$   doc = "Weapon Goid.";

7

8               #include "k_inc_weapon_effects"

9

10              startup state Go$

11              {

12                      event OnEnterState$

13                      {

14                              int wpn_target1$ = WorldFXMgr.CreateTarget();

15                              int wpn_target2$ = WorldFXMgr.CreateTarget();

16     

17                              eAttackClass attackclass$ = sfx_catalyst$.Go.Attack.GetAttackClass();       // Weapon Attack Class

18

19                              string template_string$;

20                              StringTool.Assignf( template_string$, "%s:aspect:model", sfx_owner$.Go.GetTemplateName() );

21                              string model_name$ = Contentdb.GetTemplateString( template_string$ );

22                     

23                              if(   StringTool.SameNoCase( model_name$, "m_w_arw_001" ) ||                        // Arrows and bolts

24                                      StringTool.SameNoCase( model_name$, "m_w_csb_ammo-01" ))

25                              {

26                                      WorldFXMgr.AttachTargetToGo( wpn_target1$, sfx_owner$, "ap_tip" );

27                                      WorldFXMgr.AttachTargetToGo( wpn_target2$, sfx_owner$, "ap_grip" );

28

29                                      arrow_fire$( wpn_target1$, wpn_target2$ );

30                              }

                                        .

                                        .

                                        .

                                        .

                                       

In the new effect system everything is connected to targets. Targets are basically points in our game world.
On lines 14 and 15 we are creating targets that will be used to place the effect on our arrow.
Line 21 is getting the model name which will allow use to identify our owner object as an arrow.
Line 26 and 27 will attach the 2 targets we created to the tip and grip of the arrow. We use a defined name of the bones that are part of the mesh of the arrow so that by attaching the effects to those bones effects will be moving with the arrow when the arrow is released.

Line 29 is a function that creates the effect itself. It uses the targets to determine where to render particles.

Arrows are not the only projectile that exist in the game as you know so look at the templates of other weapons so that you can get an idea of what to do with each case.

finally, this is the arrow fire code:

void arrow_fire$( int target$, int target2$ )

{

        my vector v$ = WorldFXMgr.GetTargetVectorToTarget( target$, target2$ );

 

        {

                int effect$ = WorldFXMgr.CreateParticleEffect( target$ );

                WorldFXMgr.SetTargetDependence( effect$, true, true);

                WorldFXMgr.SetEffectTexture( effect$, "b_sfx_fire_anim" );

                WorldFXMgr.SetQuadRendering( effect$, true );

                WorldFXMgr.SetEffectLighting( effect$, false, false );

                WorldFXMgr.AttachSimulation( effect$, "SpawnParticles( 300, 0x01DD0000, 0x01DD0000, 0.07, 0.15 )", 0.0 );

                WorldFXMgr.AttachSimulation( effect$, "PositionInSphere( 0.0, 0.08 )", 0.0 );

                WorldFXMgr.AttachSimulation( effect$, "ScaleChange( 0.2, 0.4, 0.0, 0.0 )", 0.0 );

                WorldFXMgr.AttachSimulationf( effect$, 0.0, 0.0, "ApplyForceAlongTargetVector( %f, %f, %f, 4.5, 0.0, 0.0, 0.0 )", v$.x, v$.y, v$.z );

                WorldFXMgr.AttachSimulation( effect$, "MoveWithVelocity()", 0.0 );

                WorldFXMgr.AttachSimulationf( effect$, 0.0, 0.0, "ColorChange( 0.0, 0.2, %08x, 0.0 )", 0x5AFF8E00 );

                WorldFXMgr.AttachSimulationf( effect$, 0.0, 0.0, "ColorChange( 0.2, 0.4, %08x, 0.0 )", 0xFFDD0000 );

                WorldFXMgr.AttachSimulation( effect$, "AlphaChange( 0.0, 0.1, 0.1, 0.0 )", 0.0 );

                WorldFXMgr.AttachSimulation( effect$, "KillEffectAtZero()", 0.0);

                WorldFXMgr.SetEffectSrcBlend( effect$,  PB_SRCALPHA );      

                WorldFXMgr.SetEffectDestBlend( effect$,  PB_DESTALPHA );

        }

        {

                int effect$ = WorldFXMgr.CreateParticleEffect( target$ );

                WorldFXMgr.SetTargetDependence( effect$, true, true);

                WorldFXMgr.SetEffectTexture( effect$, "b_sfx_fire_02" );

                WorldFXMgr.SetQuadRendering( effect$, true );

                WorldFXMgr.SetEffectLighting( effect$, false, false );

                WorldFXMgr.AttachSimulation( effect$, "SpawnParticles( 150, 0x01DD0000, 0x01DD0000, 0.1, 0.2 )", 0.0 );

                WorldFXMgr.AttachSimulation( effect$, "PositionInSphere( 0.0, 0.08 )", 0.0 );

                WorldFXMgr.AttachSimulation( effect$, "ScaleChange( 0.2, 0.4, 0.0, 0.0 )", 0.0 );

                WorldFXMgr.AttachSimulationf( effect$, 0.0, 0.0, "ApplyForceAlongTargetVector( %f, %f, %f, 5.5, 0.0, 0.0, 0.0 )", v$.x, v$.y, v$.z );

                WorldFXMgr.AttachSimulation( effect$, "MoveWithVelocity()", 0.0 );

                WorldFXMgr.AttachSimulationf( effect$, 0.0, 0.0, "ColorChange( 0.0, 0.2, %08x, 0.0 )", 0x5AFF8E00 );

                WorldFXMgr.AttachSimulationf( effect$, 0.0, 0.0, "ColorChange( 0.2, 0.4, %08x, 0.0 )", 0xFFDD0000 );

                WorldFXMgr.AttachSimulation( effect$, "AlphaChange( 0.0, 0.1, 0.3, 0.0 )", 0.0 );

                WorldFXMgr.AttachSimulation( effect$, "KillEffectAtZero()", 0.0);

                WorldFXMgr.SetEffectSrcBlend( effect$,  PB_SRCALPHA );      

                WorldFXMgr.SetEffectDestBlend( effect$,  PB_DESTALPHA ); 

        }

}

 

I hope this helps you create unique and fun effects for weapons!