Aller au contenu

Photo

Triggered effect script: rockfall


  • Veuillez vous connecter pour répondre
8 réponses à ce sujet

#1
rjshae

rjshae
  • Members
  • 4 509 messages
For your use and amusement, I present the following script. I'm sure there are other ways of doing this, but it's here in case anybody wants to skip the labor.

// on_enter_rock_fall
/*
    This is an On Enter script for a custom trigger. It
    simulates debris falling on the entering PC. This is
    suitable for caverns or mines with weakened roofs.
    If the trigger has a local integer named "d6damage",
    up to that many d6 dice of bludgeoning damage is
    applied to any targets in the area of effect. That
    parameter is also used to compute the DCs for the
    saving throws.
*/
// 08jul12 RJH

#include "ginc_effect"

const string HAS_RUN = "has_run_before";
const string D6_DAMAGE = "d6damage";
const string IPOINT_RESREF = "plc_ipoint "; // Deliberate space
const string SPEAKER_TAG = "RockFallIPoint";
const string ROCKSLIDE_SEF = "fx_rockslide.sef";
const string AFTERMATH_SEF = "fx_rockslide_after.sef";
const string CRUMBLE_WAV = "as_cv_bldgcrumb1";
const float IMPACT_DELAY = 1.5f; // Time based on CRUMBLE_WAV

// Cause the IPoint to self-destruct
void CleanupIPoint()
{
    string sTag = GetTag( OBJECT_SELF );
    if ( StringCompare( sTag, SPEAKER_TAG ) == 0 )
        DestroyObject( OBJECT_SELF, 0.1f, FALSE );
}

/*    This routine applies damage to each target in the area,
    whether friend or foe. The number of d6-dice of damage
    is determined by the local "d6damage" variable. A
    Reflex check is made to reduce or avoid any damage at
    DC = 10 + (d6-dice/2). A Strength check is made by
    each target at DC 15 + (d6-dice/2) to see if a half-
    round knockdown effect is applied. 
*/
void DoRockslideDamage()
{
    object oLeader = GetFactionLeader( GetFirstPC() );
    location locSpeaker = GetLocation( OBJECT_SELF );
    effect eImpact = EffectVisualEffect( 354 );
    effect eTrip = EffectKnockdown();
    float fDelay;
    
    int nDamageDice = GetLocalInt( OBJECT_SELF, D6_DAMAGE );
    int nSaveDC = 10 + ( nDamageDice / 2 );
    
    // Cycle through the creatures in the spherical shape
    object oTarget = GetFirstObjectInShape( SHAPE_SPHERE,
        RADIUS_SIZE_HUGE, locSpeaker, TRUE );
    while ( GetIsObjectValid( oTarget ) ) {
        // Use the distance to the target to calculate the delay
        location locTarget = GetLocation( oTarget );
        fDelay = GetDistanceBetweenLocations( locSpeaker, locTarget ) / 20;
        
        // Roll damage
        int nDamage = 0;
        if ( nDamageDice > 0 ) {
            nDamage = d6( nDamageDice );
            nDamage = GetReflexAdjustedDamage( nDamage, oTarget,
                nSaveDC, SAVING_THROW_TYPE_TRAP );
        }
        
        // Apply concussion damage, if any
        if ( nDamage > 0 ) {
            effect eDamage = EffectDamage( nDamage,
                DAMAGE_TYPE_BLUDGEONING );
            DelayCommand( fDelay + 0.1f, ApplyEffectAtLocation(
                DURATION_TYPE_INSTANT, eImpact, locTarget ) );
            DelayCommand( fDelay + 0.2f, ApplyEffectToObject(
                DURATION_TYPE_INSTANT, eDamage, oTarget ) );
        }
        
        // Do an opposed Strength check
        int nSourceStrChk = d20() + 15 + ( nDamageDice / 2 );
        int nTargetStrChk = d20() + GetAbilityScore( oTarget, ABILITY_STRENGTH );
        if ( nSourceStrChk >= nTargetStrChk ) {
            // Apply a knockdown
            DelayCommand( fDelay + 0.2f, ApplyEffectToObject(
                DURATION_TYPE_TEMPORARY, eTrip, oTarget, 3.0f ) );
        }
        
        // Select the next target within the shape
        oTarget = GetNextObjectInShape( SHAPE_SPHERE,
            RADIUS_SIZE_HUGE, locSpeaker, TRUE );
    }
}

// Run a sequence of effects to simulate a rockslide
void DoRockslide( int nDamageDice )
{
    float fDelay = IMPACT_DELAY; // Delay between sound and rockfall
    
    // Store the damage dice on the speaker
    SetLocalInt( OBJECT_SELF, D6_DAMAGE, nDamageDice );
    
    // Set the stage with a crumbling noise
    DelayCommand( 0.1f, PlaySound( CRUMBLE_WAV ) );
    
    // Apply the initial rockslide effect
    location locSpeaker = GetLocation( OBJECT_SELF );
    DelayCommand( fDelay, ApplySEFToLocation(
        ROCKSLIDE_SEF, locSpeaker, 4.0f ) );
    
    // Apply a shudder impact effect
    effect eImpact = EffectVisualEffect( 460 );
    DelayCommand( fDelay + 0.1f, ApplyEffectAtLocation(
        DURATION_TYPE_INSTANT, eImpact, locSpeaker ) );
    
    // Run the damage routine
    DelayCommand( fDelay + 0.6f, DoRockslideDamage() );
    
    // Apply an aftermath effect
    DelayCommand( fDelay + 1.0f, ApplySEFToLocation(
        AFTERMATH_SEF, locSpeaker, 5.0f ) );
    
    // Perform cleanup
    DelayCommand( 30.0f, CleanupIPoint() );
}

void main()
{
    // Check if this has been triggered before
    int bHasRun = GetLocalInt( OBJECT_SELF, HAS_RUN );
    if ( bHasRun )
        return;
    SetLocalInt( OBJECT_SELF, HAS_RUN, TRUE );
    
    // Check if the entering object is valid
    object oTarget = GetEnteringObject();
    if ( ! GetIsObjectValid( oTarget ) )
        return; // Invalid object
    
    // Only continue if the entering object is player controlled
    if ( ! GetIsPC( oTarget ) )
        return;
    
    // This creates an IPoint to run the rockslide
    location locTarget = GetLocation( oTarget );
    object oSpeaker = CreateObject( OBJECT_TYPE_PLACEABLE,
        IPOINT_RESREF, locTarget, FALSE, SPEAKER_TAG );
    if ( GetIsObjectValid( oSpeaker ) ) {
        // Run the rockslide from the IPoint
        SetFirstName( oSpeaker, "Rock fall" );
        int d6damage = GetLocalInt( OBJECT_SELF, D6_DAMAGE );
        AssignCommand( oSpeaker, DoRockslide( d6damage ) );
    }
}

Modifié par rjshae, 22 juillet 2012 - 04:07 .


#2
rjshae

rjshae
  • Members
  • 4 509 messages
There are three different as_cv_bldgcrumb* files, so it should be possible to modify the above to handle all three sound sequences. Different delays would be needed for each.

#3
Alupinu

Alupinu
  • Members
  • 528 messages
Hey rjshae, I might be able to use this. Thanks, I'll check it out. :)

#4
Alupinu

Alupinu
  • Members
  • 528 messages
Ok, I’m probable just being a moron but I can’t get the script to in-flick damage. Looking at the script I believe it’s supposed to do 1d6 of damage 5 out of 6 times. After about 6 tries with a 2ndlv rogue I did not suffer a single point of damage. Do I have this right?
Am I supposed to set some variables or something?

Also it says something about an Ipoint cleaner, how am I suppose to set that up?
Thank you.

#5
Alupinu

Alupinu
  • Members
  • 528 messages
Ok, IC, it creates it’s own Ipoint, very good. Delete the ipoint question.

Still like to know why I can’t get my character to suffer any damage. Does he just keep making his saves?

#6
rjshae

rjshae
  • Members
  • 4 509 messages

Alupinu wrote...

Ok, IC, it creates it’s own Ipoint, very good. Delete the ipoint question.

Still like to know why I can’t get my character to suffer any damage. Does he just keep making his saves?


The trigger needs to have a "d6damage" integer variable set to a non-zero value. Otherwise all it does is perform a knockdown check. It's mentioned in the comments for the DoRockslideDamage routine, but I should probably add a note to the header comments as well. Sorry.

					
					

#7
Alupinu

Alupinu
  • Members
  • 528 messages
NP, my fault for not reading the script more carefully.

Good news is got it to work! Very cool, have a mine area that the script should work perfectly in.

Little suggestion, adding the following line:

FloatingTextStringOnCreature("Cave in!", oLeader);

Kind of lets the player know what just happen so they don’t think they just stepped on a land mine or something. Just a suggestion.

And thanks again for taking the time to make this script for the rest of us, great job.  Posted Image

Modifié par Alupinu, 11 juillet 2012 - 12:27 .


#8
rjshae

rjshae
  • Members
  • 4 509 messages
Good idea! Thank you.

I wish there were an effect that would show rocks tumbling down, but we get what we get, I guess. Somebody might be able to do something with descending rock placables, but that would probably be more work than it's worth.

#9
Alupinu

Alupinu
  • Members
  • 528 messages

rjshae wrote...

Good idea! Thank you.

I wish there were an effect that would show rocks tumbling down, but we get what we get, I guess. Somebody might be able to do something with descending rock placables, but that would probably be more work than it's worth.


LOL, I did think about that, having rock pile spawn in and then destroy a few seconds later. But like you said “ ...be more work than it's worth.”