Unlimited Summons

Any questions and discussions about authoring mods are welcome here. Also, feel free to let people know about mod-related resources, to request mods or post mod ideas.

Postby Tiptoe on Thu Mar 16, 2006 2:18 pm

Hi,
In DS1 a very clever chap by the name of 'MercuryPenguin' created a mod called 'UnlimitedSummons' which Removed the one summon per character limit and made the summons have an unlimited duration.

As I like to play solo, I'm desperately trying to recreate this mod for DS2, but as I have no programming experience, I'm not having much luck with it.

This is the original DS1 'UnlimitedSummons' code, as edited by MercuryPenguin:

Code: Select all
//////////////////////////////////////////////////////////////////////////////
//
// File     :  spell_summon.skrit
// Author(s):  Rick Saenz, Eric Tams
//
// Copyright © 2000 Gas Powered Games, Inc.  All rights reserved.
//----------------------------------------------------------------------------
//  $Revision:: $              $Date:$
//----------------------------------------------------------------------------
//
// Summons an actor to guard the caster.
//
//////////////////////////////////////////////////////////////////////////////

property string effect_script$  = ""   doc = "Name of the SiegeFx script that will be providing the visual.";
property string end_script$     = ""   doc = "Name of the SiegeFx script that will be providing the visual when un_summoning.";
property string script_params$  = ""    doc = "Parameters to send to SiegeFx script";
property string template_name$  = ""    doc = "Template name of actor to summon";
property string state_name$     = "summoned"     doc = "Name of effect to use as a generic state and as a screen name.";
property string description$  = ""   doc = "Description of enchantment being applied";
property string caster_description$   = ""   doc = "Description of enchantment being applied to the caster";
property bool   guard_caster$  = true   doc = "Make the summoned creature follow the caster.";
property bool   change_align$  = true   doc = "set summon alignment to be that of the caster.";
property bool   delete_inv$     = true   doc = "delete summons inventory when removed.";



owner = GoSkritComponent;
#include "k_inc_spl_utils"

int starting_pos$;

Goid summoned_goid$;
Goid target$;
Goid caster$;
float summon_duration$;

trigger OnGoPreload$
{
   if( template_name$ != "")
   {
 GoDb.PreloadCloneSource( owner.Go, template_name$ );
   }
}

trigger OnTimer$( 2 )
{
   SetState CleanUp$;
}

event OnGoHandleCcMessage$( eWorldEvent e$, WorldMessage msg$ )
{
   if( ( e$ == WE_KILLED ) && ( summoned_goid$ == msg$.GetSendTo() ) )
   {
 if( summoned_goid$.IsValidMp)
 {
    if ( end_script$ != "" ) {
   SiegeFx.SRunScript( end_script$, summoned_goid$, summoned_goid$, script_params$, owner.Goid, WE_KILLED );
    }  
 }
 this.CreateTimer( 2, .1 );
   }
}

trigger OnGoHandleMessage$( WE_WORLD_STATE_TRANSITION_DONE )
{
   if( summoned_goid$.IsValid )
   {
 if( WorldState.CurrentState == WS_SP_NIS )
 {
    Go Summon$ = summoned_goid$.Go;
    Summon$.Mind.SetMayAttack( false );
    Summon$.Mind.SetMayBeAttacked( false );
    Summon$.Mind.SDoJob( MakeJobReq( JAT_STOP, JQ_ACTION, QP_CLEAR, AO_COMMAND ));
    
    Summon$.Mind.TempGopColl1.clear;
    Summon$.Mind.GetEngagedMeEnemies( Summon$.Mind.TempGopColl1 );
    
    int j$ = 0;
    int jend$ = Summon$.Mind.TempGopColl1.Size();
    
    Go Enemy$;
    
    while( j$ < jend$ )
    {
   Enemy$ = Summon$.Mind.TempGopColl1.Get( j$ );
   if( Enemy$ != NULL )
   {
      Enemy$.Mind.SDoJob( MakeJobReq( JAT_STOP, JQ_ACTION, QP_CLEAR, AO_COMMAND ));
      Enemy$.Mind.ResetSensors();
    
   }
   j$ += 1;  
    }   
 }
 else
 {
    summoned_goid$.Go.Mind.SetMayAttack( true );
    summoned_goid$.Go.Mind.SetMayBeAttacked( true );
 }
   }
}
    
startup state CastBegin$
{
 event OnGoHandleMessage$( eWorldEvent e$, WorldMessage msg$ )
   {
 if( e$ == WE_REQ_CAST )
 {

    ////////////////////
    // Normal Go
    
    caster$ = msg$.GetSendFrom();
    target$ = MakeGoid( msg$.GetData1() );
    
    if( !target$.IsValidMp || !caster$.IsValidMp )
    {
   SetState Abort$;
   return;
    }
    
    //Got rid of state checking... should allow for unlimited summons -MercuryPenguin
    //if( caster$.Go.Actor.HasGenericState( owner.Go.Magic.CasterStateName ) )
    //{
    //   SetState Abort$;
    //   return;
    //}
   
    // Copy the reference to the starting position into SiegeFx persistant storage
    starting_pos$ = SiegeFx.AddVariable( target$.go.placement.position, owner.goid );
    
    // Start the visual effect
    SiegeFx.SRunScript( effect_script$, target$, caster$, script_params$, owner.Goid, WE_REQ_CAST );
 
    summon_duration$ = owner.Go.Magic.EvaluateEffectDuration(caster$.Go, caster$.Go);
    //caster$.Go.Actor.SAddGenericState( owner.Go.Magic.CasterStateName, caster_description$, summon_duration$ + 2.0, caster$, owner.goid, owner.go.magic.GetMagicLevel( caster$.go ) );
 }
 else if ( e$ == WE_SPELL_SYNC_MID )
 {
    ////////////////////
    // Normal Go
    
    SetState SummonGo$;
 }
 else if ( e$ == WE_REQ_ACTIVATE )
 {
    ////////////////////
    // Omni Go
    
    caster$ = msg$.GetSendFrom();
    summoned_goid$ = MakeGoid( msg$.GetData1() );
    
    if( !summoned_goid$.IsValid || !caster$.Isvalid )
    {
   SetState CleanUp$;
   return;
    }
    
    summon_duration$ = owner.Go.Magic.EvaluateEffectDuration(summoned_goid$.Go, caster$.Go);
    if( summoned_goid$.go.hasactor )
    {
   // buff the summoned guy up.
   owner.go.magic.SApplyEnchantments( summoned_goid$, caster$ );
   
   summoned_goid$.Go.Aspect.IsInvincible = false;
   
   // Setup where experience will go from who this actor damages
   summoned_goid$.Go.aspect.SetExperienceBenefactor( caster$ );
   summoned_goid$.Go.aspect.SetExperienceBenefactorSkill( owner.go.magic.skillclass );
   
   // watch out pet, so if he dies we can control a new pet.
   GoDb.StartWatching( owner.Goid, summoned_goid$);
   }
   else
   {
      SetState CleanUp$;
   }
    
    this.CreateTimer( 1, 0 );
 }
   }
   transition -> ControlSummoned$ : OnTimer( 1 );
}

state SummonGo$
{
   ////////////////////
   // Normal Go
   
   event OnEnterState$
   {
 if( Owner.go.Parent != NULL )
 {
    // First create the go
    GoCloneReq cloneReq$ = MakeGoCloneReq( template_name$ );
    cloneReq$.StartingPos = SiegeFx.GetVariable( starting_pos$, owner.goid );
    cloneReq$.SnapToTerrain = true;
    cloneReq$.Fadein = true;
    summoned_goid$ = GoDb.SCloneGo( cloneReq$ );
    
    if( change_align$ && caster$.IsValid )
    {
   summoned_goid$.Go.actor.ssetalignment( caster$.Go.actor.alignment );
   summoned_goid$.Go.SsetPlayer( caster$.Go.PlayerID );
    }
    summoned_goid$.Go.Aspect.IsInvincible = true;
    
    // create Omni version of the spell.
    cloneReq$ = MakeGoCloneReq( Owner.go.Parent.Goid, owner.goid );
    cloneReq$.Omni = true;
    Goid new_spell$ = GoDb.SCloneGo( cloneReq$ );
    
    // send Omni version an Activate to get it started.
    PostWorldMessage( WE_REQ_ACTIVATE, caster$, new_spell$, MakeInt( summoned_goid$ ), 0 );
 }
 // delete normal version of the spell.
 SetState Finished$;
   }
}        


state ControlSummoned$
{
   ////////////////////
   // Omni Go
   
   trigger OnGoHandleMessage$( WE_SPELL_EXPIRATION_TIMER_RESET )
   {
 if( summoned_goid$.IsValidMp)
 {
    if ( end_script$ != "" ) {
   SiegeFx.SRunScript( end_script$, summoned_goid$, summoned_goid$, script_params$, owner.Goid, WE_DAMAGED );
    }  
 }
 this.CreateTimer( 2, .1 );
   }
   
   //trigger OnTimer$ ( 1 )  // yoink goes the timer... - MercuryPenguin
   //{
   //   if( summoned_goid$.IsValidMp)
   //   {
   //  if ( end_script$ != "" ) {
   //     SiegeFx.SRunScript( end_script$, summoned_goid$, summoned_goid$, script_params$, owner.Goid, WE_DAMAGED );
   //  }  
   //   }
   //   this.CreateTimer( 2, .1 );
   //}
   trigger OnTimer$ ( 3 )
   {
 this.CreateTimer( 3, 5 );
 if( summoned_goid$.isvalid && caster$.IsValid() )
 {
    if( summoned_goid$.Go.Mind.UnderstandsJob( JAT_GUARD ) )
    {
   if( summoned_goid$.Go.Mind.CanOperateOn( owner.go.parent ) )
   {
      Job action$ = summoned_goid$.Go.Mind.GetFrontJob( JQ_ACTION );
   
      if( action$ != NULL )
      {
     if( action$.JobAbstractType != JAT_FIDGET )
     {
        return;
     }
      }
      summoned_goid$.go.Mind.SDoJob( MakeJobReq( JAT_GUARD, JQ_ACTION, QP_FRONT, AO_COMMAND, owner.go.parent.Goid ) );
   }
    }
 }
   }

   event OnEnterState$
   {
 if( !summoned_goid$.isvalid )
 {
    SetState CleanUp$;
    return;
 }
 
 if(guard_caster$)
 {
    JobReq req$;
    if( summoned_goid$.Go.Mind.UnderstandsJob( JAT_GUARD ) )
    {
   if( summoned_goid$.Go.Mind.CanOperateOn( owner.go.parent ) )
   {
      req$ = MakeJobReq( JAT_GUARD, JQ_ACTION, QP_FRONT, AO_COMMAND, owner.go.parent.Goid );
      summoned_goid$.go.Mind.SDoJob( req$ );
   }
    }
 }
 
 if( caster$.IsValid() )
 {
    summoned_goid$.Go.Actor.SAddGenericState( state_name$, description$, summon_duration$, caster$, owner.goid, owner.go.magic.GetMagicLevel( caster$.go ) );
    caster$.Go.Actor.SRemoveGenericState( owner.Go.Magic.CasterStateName );   
    //caster$.Go.Actor.SAddGenericState( owner.Go.Magic.CasterStateName, caster_description$, summon_duration$, caster$, owner.goid, owner.go.magic.GetMagicLevel( caster$.go ) );
    
    // we want to be able to see the dude's health
    summoned_goid$.Go.Actor.SSetCanShowHealth( true );  

    // Make him have the same membership as the caster
    summoned_goid$.Go.Common.SCopyMembership( caster$ );
 }

 this.CreateTimer( 1, summon_duration$ );
 if(guard_caster$)
 {
    this.CreateTimer( 3, 5 );
 }
   }
}

state CleanUp$
{
   ////////////////////
   // Omni Go
   
   transition -> FinishedOmni$: OnTimer( 1 );
   
   event OnEnterState$
   {
 if( caster$.IsValid )
 {
    caster$.Go.Actor.SRemoveGenericState( owner.Go.Magic.CasterStateName );   
 }
   
 if( summoned_goid$.isvalid)
 {     
    GoDb.StopWatching( owner.Goid, summoned_goid$);
    
    if( delete_inv$ )
    {
   GoDb.SMarkGoAndChildrenForDeletion( summoned_goid$, true, true );
    }
    else
    {
   GoDb.SMarkForDeletion( summoned_goid$, true, true );
    }
 }
 this.CreateTimer( 1, 0 );
   }
}
   
state Finished$
{
   ////////////////////
   // Normal Go
   
   event OnEnterState$
   {
 PostWorldMessage( WE_REQ_DELETE, owner.Goid, owner.Goid, 1 );
   }
}

state FinishedOmni$
{
   ////////////////////
   // Omni Go
   
   event OnEnterState$
   {
 // Get rid of any temporary storage
 SiegeFx.ClearVariables( owner.goid );
   
 PostWorldMessage( WE_REQ_DELETE, owner.Goid, owner.Goid, 1 );
   }
}

state Abort$
{
   ////////////////////
   // Normal Go
   
   event OnEnterState$
   {
 // Refund the players mana
 Rules.ChangeMana( caster$, owner.go.getmagic.manacost );

 // Get rid of any temporary storage
 SiegeFx.ClearVariables( owner.goid );

 PostWorldMessage( WE_REQ_DELETE, owner.Goid, owner.Goid, 1 );
   }
}


//////////////////////////////////////////////////////////////////////////////
//
// File     :  spell_return_summoned.skrit
// Author(s):  Eric Tams
//
// Copyright © 2000 Gas Powered Games, Inc.  All rights reserved.
//----------------------------------------------------------------------------
//  $Revision:: $              $Date:$
//----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////

// This skrit will tell summoned creatures to go away.

owner = GoSkritComponent;

property string state_name$     = "summoned"     doc = "Name of effect to use as a generic state and as a screen name.";
property float   health_per_level$   = 22.0       doc = "The caster may return any actor with health less his level times this value.";

Goid  target$;
Goid  caster$;
Goid   old_spell$;

startup state CastBegin$
{
 event OnGoHandleMessage$( eWorldEvent e$, WorldMessage msg$ )
   {
 if( e$ == WE_REQ_CAST )
 {
    target$ = MakeGoid( msg$.GetData1() );
    caster$ = msg$.GetSendFrom();

    if( !target$.IsValid || !caster$.IsValid )
    {
   SetState Finished$;
   return;
    }
    
    // Check to see if the enchantment has already been cast on this go
    //if( !target$.Go.Actor.HasGenericState( state_name$ ) )
    //{   
    //   SetState Abort$;
    //   return;
    //}   
    
    if( target$.Go.Aspect.MaxLife > ( health_per_level$ * caster$.Go.Actor.GetSkillLevel( owner.Go.Magic.SkillClass ) ) )
    {
   SetState Abort$;
   return;
    }

    old_spell$ = target$.Go.Actor.GetGenericStateSpellGoid ( state_name$ );
 }
   }
   transition
   {
 -> Finished$:   OnGoHandleMessage( WE_SPELL_SYNC_MID ) =
 {
    SendWorldMessage( WE_SPELL_EXPIRATION_TIMER_RESET, owner.Goid, old_spell$ );
 }
   }
   
}  

state Abort$
{
   event OnEnterState$
   {
 // Refund the players mana
 Rules.ChangeMana( caster$, owner.go.getmagic.manacost );

 SetState( Finished$ );
   }
}

state Finished$
{
   event OnEnterState$
   {
 // Delete this skrit
 PostWorldMessage( WE_REQ_DELETE, owner.Goid, owner.Goid, 10 );
   }
}



This is my attempt to edit the DS2 summon code (GPG seems to have made a few changes to it since DS1) All I did was try to change the parts that MercuryPenguin changed in the code above:

Code: Select all
//////////////////////////////////////////////////////////////////////////////
//
// File     :  spell_summon.skrit
// Author(s):  Rick Saenz, Eric Tams, Elijah Emerson
//
// Copyright © 2000 Gas Powered Games, Inc.  All rights reserved.
//----------------------------------------------------------------------------
//  $Revision:: $              $Date:$
//----------------------------------------------------------------------------
//
// Summons an actor to guard the caster.
//
//////////////////////////////////////////////////////////////////////////////

property bool   _server_only$  = true;

property string template_name$  = ""        doc = "Template name of actor to summon";
property string state_name$     = "summoned"     doc = "Name of effect to use as a generic state and as a screen name.";
property string description$  = ""       doc = "Description of enchantment being applied";
property string caster_description$   = ""       doc = "Description of enchantment being applied to the caster";
property bool   guard_caster$  = true       doc = "Make the summoned creature follow the caster.";
property bool   change_align$  = true       doc = "set summon alignment to be that of the caster.";
property bool   delete_inv$     = true       doc = "delete summons inventory when removed.";
property float   spawn_delay$  = 2.0       doc = "delays the spawn of the summoned creature";
property float   spawn_offset_x$  = 0.0       doc = "x component of spawn location offset vector";
property float   spawn_offset_y$  = 0.0       doc = "y component of spawn location offset vector";
property float   spawn_offset_z$  = 0.0       doc = "z component of spawn location offset vector";



owner = GoSkritComponent;
#include "k_inc_spl_utils"
#include "k_inc_damage_utils"

my SiegePos starting_pos$;

Goid summoned_goid$;
Goid target$;
Goid caster$;
float summon_duration$;
bool m_bIsOmniSpell$ = false;

trigger OnGoPreload$
{
   if( template_name$ != "")
   {
 GoDb.PreloadCloneSource( owner.Go, template_name$ );
   }
}

trigger OnTimer$( 2 )
{
   report.reportf("summon","summon[0x%08x]: cleanup spell_summon OnTimer$( 2 )\n", owner.Goid );
   SetState CleanUp$;
}

trigger OnGoHandleMessage$( WE_DESTRUCTED )
{
   report.reportf("summon","summon[0x%08x]: got WE_DESTRUCTED.\n", owner.Goid );
   SetState CleanUp$;
}

trigger OnGoHandleCCMessage$( WE_KILLED )
{
   report.reportf("summon","summon[0x%08x]: caster or summoned creature died! .. cleaning up summon omni spell.\n", owner.Goid );
   SetState CleanUp$;
}

trigger OnGoHandleMessage$( WE_WORLD_STATE_TRANSITION_DONE )
{
   if( summoned_goid$.IsValid )
   {
 if( IsInNISMode() )
 {
    report.reportf("summon","summon[0x%08x]: Handling WorldEvent [WE_WORLD_STATE_TRANSITION_DONE]\n", owner.Goid );
    Go Summon$ = summoned_goid$.Go;
    Summon$.Mind.SSetMayAttack( false );
    Summon$.Mind.SSetMayBeAttacked( false );
    Summon$.Mind.SDoJob( MakeJobReq( JAT_STOP, JQ_ACTION, QP_CLEAR, AO_COMMAND ));
    
    Summon$.Mind.TempGopColl1.clear;
    Summon$.Mind.GetEngagedMeEnemies( Summon$.Mind.TempGopColl1 );
    
    int j$ = 0;
    int jend$ = Summon$.Mind.TempGopColl1.Size();
    
    Go Enemy$;
    
    while( j$ < jend$ )
    {
   Enemy$ = Summon$.Mind.TempGopColl1.Get( j$ );
   if( Enemy$ != NULL )
   {
      Enemy$.Mind.SDoJob( MakeJobReq( JAT_STOP, JQ_ACTION, QP_CLEAR, AO_COMMAND ));
      Enemy$.Mind.ResetSensors();
    
   }
   j$ += 1;  
    }   
 }
 else
 {
    summoned_goid$.Go.Mind.SSetMayAttack( true );
    summoned_goid$.Go.Mind.SSetMayBeAttacked( true );
 }
   }
}
    
startup state CastBegin$
{
 event OnGoHandleMessage$( eWorldEvent e$, WorldMessage msg$ )
   {
 if( e$ == WE_REQ_CAST )
 {
    report.reportf("summon","summon[0x%08x]: CastBegin entered.\n", owner.Goid );

    ////////////////////
    // Normal Go
    
    caster$ = msg$.GetSendFrom();
    target$ = MakeGoid( msg$.GetData1() );
    
    if( !caster$.Go.HasAspect() || IsDead( Caster$.Go.Aspect.LifeState ) )
    {
   // caster is dead.. so we will not cast the spell
   report.reportf("summon","summon[0x%08x]: caster is dead.. so we will not cast the spell.\n", owner.Goid );
   GoDb.SMarkForDeletion( owner.goid );
   return;
    }

    if( !target$.Go.HasPlacement() )
    {
   report.errorf("spell_summon[0x%08x]: is trying to target go[%s] but it doesn't have a placement component!!!???\n"
        "How can you target something that doesn't have a position?\n", target$.Go.GetTemplateName() );
   GoDb.SMarkForDeletion( owner.goid );
   return;
    }

    if( !target$.IsValidMp || !caster$.IsValidMp )
    {
   report.reportf("summon","summon[0x%08x]: (!target$.IsValidMp || !caster$.IsValidMp).. "
         "so we will not cast the spell.\n", owner.Goid );
   SetState Abort$;
   return;
    }
    
    //if( caster$.Go.Actor.HasGenericState( owner.Go.Magic.CasterStateName ) )
    //{
    //   report.reportf("summon","summon[0x%08x]: caster$.Go.Actor.HasGenericState( owner.Go.Magic.CasterStateName ).. "
    //         "so we will not cast the spell.\n", owner.Goid );
    //   SetState Abort$;
    //   return;
    //}
    
    // Copy the reference to the starting position into SiegeFx persistant storage
    starting_pos$ = target$.go.placement.position;
    starting_pos$.pos.x = starting_pos$.pos.x + spawn_offset_x$;
    starting_pos$.pos.y = starting_pos$.pos.y + spawn_offset_y$;
    starting_pos$.pos.z = starting_pos$.pos.z + spawn_offset_z$;
    
    summon_duration$ = owner.Go.Magic.EvaluateEffectDuration(caster$.Go, caster$.Go);
    //caster$.Go.Actor.SAddGenericState( owner.Go.Magic.CasterStateName, caster_description$, summon_duration$ + 2.0,
    //           caster$, owner.goid, owner.go.magic.GetMagicLevel( caster$.go ) );
 
    SetState SummonGo$;
 }
 else if ( e$ == WE_REQ_ACTIVATE )
 {
    ////////////////////
    // Omni Go

    report.reportf("summon","summon[0x%08x]: omni - got WE_REQ_ACTIVATE!, spell_summon created.\n", owner.Goid );
    
    m_bIsOmniSpell$ = true;
    caster$ = msg$.GetSendFrom();
    summoned_goid$ = MakeGoid( msg$.GetData1() );
    
    if( !summoned_goid$.IsValid || !caster$.Isvalid )
    {
   report.reportf("summon","summon[0x%08x]: omni - (!summoned_goid$.IsValid || "
         "!caster$.Isvalid) so we will cleanup.\n", owner.Goid );
   SetState CleanUp$;
   return;
    }
    
    summon_duration$ = owner.Go.Magic.EvaluateEffectDuration(summoned_goid$.Go, caster$.Go);
    if( summoned_goid$.go.hasactor )
    {
   report.reportf("summon","summon[0x%08x]: omni - start watching summoned[0x%08x] and caster[0x%08x].\n",
      owner.Goid, summoned_goid$, caster$ );

   // buff the summoned guy up.
   owner.go.magic.SApplyEnchantments( owner.Go.Magic.StateName, caster$, summoned_goid$ );
   
   summoned_goid$.Go.Aspect.SSetIsInvincible( false );
   
   // Setup where experience will go from who this actor damages
   summoned_goid$.Go.aspect.SetExperienceBenefactor( caster$ );
   summoned_goid$.Go.aspect.SetExperienceBenefactorSkill( owner.go.magic.skillclass );
   
   // watch summoned, so if he dies we can control a new pet.
   GoDb.StartWatching( owner.Goid, summoned_goid$ );
   
   // watch the caster, because if he dies we need to kill the summoned creature
   GoDb.StartWatching( owner.Goid, caster$ );
   }
   else
   {
   report.reportf("summon","summon[0x%08x]: summoned_goid$.go.hasactor\n", owner.Goid );
      SetState CleanUp$;
   }
    
    SetState ControlSummoned$;
 }
   }   
}

state SummonGo$
{
   ////////////////////
   // Normal Go
   
   // delay spawn time to 2 seconds, which is the duration of the summon effect
   event OnEnterState$
   {
 //Add some extra time to allow the enchantment to launch the end effect.
 this.CreateTimer( 2, spawn_delay$+0.1 );
   }

   trigger OnTimer$( 2 )
   {
 if( Owner.go.Parent != NULL )
 {
    report.reportf("summon","summon[0x%08x]: SummonGo$ - Attempting Summon!\n", owner.Goid );
    
    // First create the go
    my GoCloneReq cloneReq$;
    cloneReq$.Init( template_name$ );
    cloneReq$.StartingPos = starting_pos$;
    cloneReq$.SnapToTerrain = true;
    cloneReq$.Fadein = true;
    summoned_goid$ = GoDb.SCloneGo( cloneReq$ );
    summoned_goid$.Go.Actor.SSetSummonCaster( caster$ );
    
    if( change_align$ && caster$.IsValid )
    {
   summoned_goid$.Go.actor.SSetAlignment( caster$.Go.actor.alignment );
   summoned_goid$.Go.SSetPlayer( caster$.Go.PlayerID );
    }

    summoned_goid$.Go.Aspect.IsInvincible = true;
    //FFXID creatureFlickFxId$ = WorldFXMgr.SCreateFlickFX( "ffx_spell_summon_creatureFX", summoned_goid$, caster$, summoned_goid$, true );
    
    // create Omni version of the spell.
    my GoCloneReq cloneReqSpell$;
    cloneReqSpell$.Init( Owner.go.Parent.Goid, owner.goid );
    cloneReqSpell$.Omni = true;
    Goid new_spell$ = GoDb.SCloneGo( cloneReqSpell$ );
    
    // send Omni version an Activate to get it started.
    SPostWorldMessage( WE_REQ_ACTIVATE, caster$, new_spell$, MakeInt( summoned_goid$ ), 0 );
 }
 // delete normal version of the spell.
 SetState Finished$;
   }
}        


state ControlSummoned$
{
   ////////////////////
   // Omni Go
   trigger OnGoHandleMessage$( WE_SPELL_EXPIRATION_TIMER_RESET )
   {
 this.CreateTimer( 2, .1 );
   }
   //trigger OnTimer$ ( 1 )
   //{
   //   this.CreateTimer( 2, .1 );
   //}
   trigger OnTimer$ ( 3 )
   {
 this.CreateTimer( 3, 5 );
 if( summoned_goid$.isvalid && caster$.IsValid() )
 {
    // If the summon is dead then lets clean up
    if( IsDead( summoned_goid$.go.Aspect.LifeState ) )
    {
   this.CreateTimer( 2, .1 );
   return;
    }
    
    GoMind summonedMind$ = summoned_goid$.Go.Mind;
    if( summonedMind$.GetMovementOrders != MO_HOLD &&
   summonedMind$.UnderstandsJob( JAT_GUARD ) &&
   summonedMind$.FrontActionJat != JAT_GUARD &&
   summonedMind$.CanOperateOn( owner.go.parent ) &&
   summoned_goid$.Go.IsInActiveWorldFrustum &&
   owner.go.parent.IsInActiveWorldFrustum )
    {
   Job action$ = summonedMind$.GetFrontJob( JQ_ACTION );
    
   if( action$ != NULL )
   {
      if( action$.JobAbstractType != JAT_FIDGET )
      {
     return;
      }
   }
   report.reportf("summon","summon[0x%08x]: omni - ControlSummon$ - Making sure summoned creature guards!\n", owner.Goid );
   
   summoned_goid$.go.Mind.RSGuard( owner.go.parent.Goid, QP_BACK, AO_COMMAND );
    }
 }
   }
   trigger OnTimer$ ( 4 )
   {
 if ( !Math.IsEqual( summoned_goid$.Go.Aspect.GetMaxLife(), 0.0 ) &&
   !Math.IsEqual( summoned_goid$.Go.Aspect.GetMaxLife(), 1.0 ) )
 {     
    summoned_goid$.Go.Aspect.SSetCurrentLife( summoned_goid$.Go.Aspect.GetMaxLife() );
 }
 else
 {     
    this.CreateTimer( 4, 0.01 );
 }
   }

   event OnEnterState$
   {
 if( !summoned_goid$.isvalid )
 {
    report.reportf("summon","summon[0x%08x]: omni - ControlSummoned$ - Cleaning up because summoned goid is invalid!\n", owner.Goid );
    SetState CleanUp$;
    return;
 }
 
 // report
 report.reportf("summon","summon[0x%08x]: omni - ControlSummoned$ - guard[%d] caster[0x%08x:%s]\n",
    owner.Goid, guard_caster$, owner.go.parent.Goid, owner.go.parent.TemplateName );
 
 if( caster$.IsValid() )
 {
    // Set caster's summoned goid
    caster$.Go.Actor.SSetSummoned( summoned_goid$ );  

    // Add the summoned state to the caster
    summoned_goid$.Go.Actor.SAddGenericState( state_name$, description$, summon_duration$, caster$, owner.goid, owner.go.magic.GetMagicLevel( caster$.go ) );
    caster$.Go.Actor.SRemoveGenericState( owner.Go.Magic.CasterStateName );   
    //caster$.Go.Actor.SAddGenericState( owner.Go.Magic.CasterStateName, caster_description$, summon_duration$, caster$, owner.goid, owner.go.magic.GetMagicLevel( caster$.go ) );

    // we want to be able to see the dude's health
    summoned_goid$.Go.Actor.SSetCanShowHealth( true );  

    // Make him have the same membership as the caster
    summoned_goid$.Go.Common.SCopyMembership( caster$ );

    // give the summoned creature a guard job ( if we are suppose to )
    if( guard_caster$ &&
   summoned_goid$.Go.IsInActiveWorldFrustum &&
   owner.go.parent.IsInActiveWorldFrustum )
    {
   // report
   report.reportf("summon","summon[0x%08x]: omni - ControlSummoned$ - Asking summoned creature[0x%08x:%s] "
         "to guard the caster[0x%08x:%s]!\n",
         owner.Goid, summoned_goid$, summoned_goid$.Go.TemplateName,
         owner.go.parent.Goid, owner.go.parent.TemplateName );
   
   summoned_goid$.go.Mind.RSGuard( owner.go.parent.Goid, QP_BACK, AO_COMMAND );
    }   

    this.CreateTimer( 4, 0.01 );
 }

 // Setup kill summon duration
 this.CreateTimer( 1, summon_duration$ );
 
 // If we should guard the caster lets ensure thats the case with a guard heartbeat
 if( guard_caster$ )
 {
    this.CreateTimer( 3, 5 );
 }
   }
}

state CleanUp$
{
   ////////////////////
   // Omni Go
   
   transition -> FinishedOmni$: OnTimer( 1 );
   
   event OnEnterState$
   {
 // If this spell is not omni then go straight to the finished state
 if( !m_bIsOmniSpell$ )
 {
    SetState Finished$;
    return;
 }
 
 if( caster$.IsValid && !caster$.Go.IsMarkedForDeletion() )
 {
    caster$.Go.Actor.SRemoveGenericState( owner.Go.Magic.CasterStateName );   
    
    #only( game ) [[
   UIPartyManager.SRemoveCharacterAsGuarded( summoned_goid$, caster$ );
    ]]
    
    Goid invalid$;
    caster$.Go.Actor.SSetSummoned( invalid$ );
 }
 
 if( summoned_goid$.isvalid && !summoned_goid$.Go.IsMarkedForDeletion() )
 {   
    summoned_goid$.Go.Actor.SRemoveGenericState( state_name$ );
    
    report.reportf("summon","summon[0x%08x]: omni - stop watching pet and caster.\n", owner.Goid );
    
    if( GoDb.IsBeingWatchedBy( owner.Goid, summoned_goid$ ) )
    {
   GoDb.StopWatching( owner.Goid, summoned_goid$);
    }
    
    if( GoDb.IsBeingWatchedBy( owner.Goid, caster$ ) )
    {
   GoDb.StopWatching( owner.Goid, caster$);
    }
    
    if( delete_inv$ )
    {
   GoDb.SMarkGoAndChildrenForDeletion( summoned_goid$, true, true );
    }
    else
    {
   GoDb.SMarkForDeletion( summoned_goid$, true, true );
    }
 }

 this.CreateTimer( 1, 0 );
   }
}

state Finished$
{
   ////////////////////
   // Normal Go
   
   event OnEnterState$
   {
 this.CreateTimer( 1, 6 );
   }

   trigger OnTimer$( 1 )
   {
 report.reportf("spell", "spell_summon[0x%08x]: Posting normal go WE_REQ_DELETE\n", owner.Goid );
 PostWorldMessage( WE_REQ_DELETE, owner.Goid, owner.Goid, 1 );
   }
}

state FinishedOmni$
{
   ////////////////////
   // Omni Go
   
   event OnEnterState$
   {
   //   this.CreateTimer( 1, 6 );
   //}
   //
   ////event OnEnterState$
   //trigger OnTimer$( 1 )
   //{
 report.reportf("spell", "spell_summon[0x%08x]: Posting omni go WE_REQ_DELETE\n", owner.Goid );
 PostWorldMessage( WE_REQ_DELETE, owner.Goid, owner.Goid, 1 );
   }
}

state Abort$
{
   ////////////////////
   // Normal Go
   
   event OnEnterState$
   {
 // Refund the players mana
 Rules.ChangeMana( caster$, owner.go.getmagic.manacost );
 report.reportf("spell", "spell_summon[0x%08x]: Posting normal go WE_REQ_DELETE\n", owner.Goid );
 PostWorldMessage( WE_REQ_DELETE, owner.Goid, owner.Goid, 1 );
   }
}


Sadly, this code isn't working. And I'm really hoping that somebody who understands this stuff can help me out here. What have I done wrong? What other changes do I need to make to get this to work?

Thanks Very much.
Tiptoe
Lurker
 
Posts: 2
Joined: Thu Mar 16, 2006 1:56 pm

Postby Lone Knight on Fri Mar 17, 2006 2:28 am

Woah! I'll tell TAS to see this.
Unknown wrote:It remains to be seen if DS can rise back from its ashes and dissociates from DS2 and GPG.

Dungeon Siege Forever
User avatar
Lone Knight
Centurion
Centurion
 
Posts: 604
Joined: Tue Jul 20, 2004 9:07 pm
Location: Castle Mare, Andor

Postby Tiptoe on Sat Mar 18, 2006 4:08 pm

At last!!! I've got it working. It's taken me two days to figure it out, but *touch wood* I seem to have done the trick. Happy times for me :smilewinkgrin:.

Cheers
Tiptoe
Lurker
 
Posts: 2
Joined: Thu Mar 16, 2006 1:56 pm

Postby Beason on Wed Mar 29, 2006 5:50 am

you should post it on a mod site so other can enjoy the fruits of your labor (specifically me :)).
Last edited by Beason on Wed Mar 29, 2006 5:50 am, edited 1 time in total.
Beason
Lurker who Speaks
 
Posts: 9
Joined: Wed Mar 22, 2006 6:29 am

Postby smfairlie on Wed Mar 29, 2006 3:17 pm

Beason wrote: you should post it on a mod site so other can enjoy the fruits of your labor (specifically me :)).

BUt this is a mod sight, isn't it? and he did post it in mod development, so where's your problem?
User avatar
smfairlie
Legionnaire
Legionnaire
 
Posts: 119
Joined: Thu Feb 23, 2006 9:53 pm
Location: Steamboat Springs, Colorado, USA

Postby Lone Knight on Wed Mar 29, 2006 11:28 pm

He meant as a download.
Unknown wrote:It remains to be seen if DS can rise back from its ashes and dissociates from DS2 and GPG.

Dungeon Siege Forever
User avatar
Lone Knight
Centurion
Centurion
 
Posts: 604
Joined: Tue Jul 20, 2004 9:07 pm
Location: Castle Mare, Andor

Postby smfairlie on Sat Apr 01, 2006 5:36 am

Lone Knight wrote: He meant as a download.

oh.. Sorry Lone Knight. :bawl:
User avatar
smfairlie
Legionnaire
Legionnaire
 
Posts: 119
Joined: Thu Feb 23, 2006 9:53 pm
Location: Steamboat Springs, Colorado, USA


Return to Mod Development