Jump to content

Saber defense level 4?


Recommended Posts

I've noticed alot of mods have made some big changes to saber mechanics, but all i've wanted for awhile now is the same level of saber blocking chance as Jedi Outcast had for Academy singleplayer. Outcast SP saber combat was so much more fun due to saber blocking simply being a bit better. Having had alot of actual fast paced saber clashing when keeping the right distance during a fight as opposed to just hitting or getting hit (with saber realism on 2 for both games). Also properly deflecting gunfire consistently at the right angle made the game so much more satisfying and fun..anyways i'm just looking for a small mod that changes this without a "total conversion" of the whole combat system for singleplayer if possible.

Link to comment

Here's a tutorial for SP force powers i found looking for info (you probably have already seen this but just in case), i don't know the first thing about coding unfortunately. http://jkhub.org/tutorials/article/204-how-to-make-a-new-force-power-single-player/  this part here "SET_SABER_DEFENSE,//## %t="FORCE_LEVELS" # Change force power level" in one of the sections near the top of the tutorial looks like it might be it, though i have no idea if anything else would need to be changed in addition. Glad to see someone else is interested in this who can get into the coding though =)

Link to comment

Hello! I am the author of related tutorial. :)

Maybe i have something that can interess to you.

in my mod i deactivated the saber defense reflection of projectiles. saber defense can only parry, but not deflecte.

so diving the code casually i founded months ago the part of code related to saber deflecting projectiles. that's because there is a little bug in my code on deflection and because i not know how to fix, i disable the deflecting (also about my mod is fantasy style and swords that deflects magical spheres was very weirds. XD )

for your luckys now i am working about some AOE force power like repulse for reproduce the Glyph spells of Soul Reaver

(my mod is about Legacy of Kain ) yesterday i make the Sonic Glyph and the other day i changed force repulse code into Force Glyph. 

However...

oh, i FOUNDED!

yes, i found also my edit for disable deflections of projectiles.

@FlemoidusMaximus WRONG, man! is not into wp_saber.cpp what you are looking! check the g_missile.cpp code. it contain the answer . many code is about the saber deflections. :)


 

 
void G_MissileReflectEffect( gentity_t *ent, vec3_t org, vec3_t dir )
{
    //FIXME: have an EV_BOUNCE_MISSILE event that checks the s.weapon and does the appropriate effect
    switch( ent->s.weapon )
    {
    case WP_BOWCASTER:
        G_PlayEffect( "bowcaster/deflect", ent->currentOrigin, dir );
        break;
    case WP_BLASTER:
    case WP_BRYAR_PISTOL:
    case WP_BLASTER_PISTOL:
    default:
        G_PlayEffect( "blaster/deflect", ent->currentOrigin, dir );
        break;
    }
}

//-------------------------------------------------------------------------
static void G_MissileStick( gentity_t *missile, gentity_t *other, trace_t *tr )
{
    if ( other->NPC || !Q_stricmp( other->classname, "misc_model_breakable" ))
    {
        // we bounce off of NPC's and misc model breakables because sticking to them requires too much effort
        vec3_t velocity;

        int hitTime = level.previousTime + ( level.time - level.previousTime ) * tr->fraction;

        EvaluateTrajectoryDelta( &missile->s.pos, hitTime, velocity );

        float dot = DotProduct( velocity, tr->plane.normal );
        G_SetOrigin( missile, tr->endpos );
        VectorMA( velocity, -1.6f * dot, tr->plane.normal, missile->s.pos.trDelta );
        VectorMA( missile->s.pos.trDelta, 10, tr->plane.normal, missile->s.pos.trDelta );
        missile->s.pos.trTime = level.time - 10; // move a bit on the first frame

        // check for stop
        if ( tr->entityNum >= 0 && tr->entityNum < ENTITYNUM_WORLD &&
                tr->plane.normal[2] > 0.7 && missile->s.pos.trDelta[2] < 40 ) //this can happen even on very slightly sloped walls, so changed it from > 0 to > 0.7
        {
            missile->nextthink = level.time + 100;
        }
        else
        {
            // fall till we hit the ground
            missile->s.pos.trType = TR_GRAVITY;
        }

        return; // don't stick yet
    }

    if ( missile->e_TouchFunc != touchF_NULL )
    {
        GEntity_TouchFunc( missile, other, tr );
    }

    G_AddEvent( missile, EV_MISSILE_STICK, 0 );

    if ( other->s.eType == ET_MOVER || other->e_DieFunc == dieF_funcBBrushDie || other->e_DieFunc == dieF_funcGlassDie)
    {
        // movers and breakable brushes need extra info...so sticky missiles can ride lifts and blow up when the thing they are attached to goes away.
        missile->s.groundEntityNum = tr->entityNum;
    }
}

/*
================
G_ReflectMissile

  Reflect the missile roughly back at it's owner
================
*/
extern gentity_t *Jedi_FindEnemyInCone( gentity_t *self, gentity_t *fallback, float minDot );
void G_ReflectMissile( gentity_t *ent, gentity_t *missile, vec3_t forward )
{
    vec3_t    bounce_dir;
    int        i;
    float    speed;
    qboolean reflected = qfalse;
    gentity_t    *owner = ent;

    if ( ent->owner )
    {
        owner = ent->owner;
    }

    //save the original speed
    speed = VectorNormalize( missile->s.pos.trDelta );

    if ( ent && owner && owner->client && !owner->client->ps.saberInFlight &&
        (owner->client->ps.forcePowerLevel[FP_SABER_DEFENSE] > FORCE_LEVEL_2 || (owner->client->ps.forcePowerLevel[FP_SABER_DEFENSE]>FORCE_LEVEL_1&&!Q_irand( 0, 3 )) ) )
    {//if high enough defense skill and saber in-hand (100% at level 3, 25% at level 2, 0% at level 1), reflections are perfectly deflected toward an enemy
        gentity_t *enemy;
        if ( owner->enemy && Q_irand( 0, 3 ) )
        {//toward current enemy 75% of the time
            enemy = owner->enemy;
        }
        else
        {//find another enemy
            enemy = Jedi_FindEnemyInCone( owner, owner->enemy, 0.3f );
        }
        if ( enemy )
        {
            vec3_t    bullseye;
            CalcEntitySpot( enemy, SPOT_HEAD, bullseye );
            bullseye[0] += Q_irand( -4, 4 );
            bullseye[1] += Q_irand( -4, 4 );
            bullseye[2] += Q_irand( -16, 4 );
            VectorSubtract( bullseye, missile->currentOrigin, bounce_dir );
            VectorNormalize( bounce_dir );
            if ( !PM_SaberInParry( owner->client->ps.saberMove )
                && !PM_SaberInReflect( owner->client->ps.saberMove )
                && !PM_SaberInIdle( owner->client->ps.saberMove ) )
            {//a bit more wild
                if ( PM_SaberInAttack( owner->client->ps.saberMove )
                    || PM_SaberInTransitionAny( owner->client->ps.saberMove )
                    || PM_SaberInSpecialAttack( owner->client->ps.torsoAnim ) )
                {//moderately more wild
                    for ( i = 0; i < 3; i++ )
                    {
                        bounce_dir[i] += Q_flrand( -0.2f, 0.2f );
                    }
                }
                else
                {//mildly more wild
                    for ( i = 0; i < 3; i++ )
                    {
                        bounce_dir[i] += Q_flrand( -0.1f, 0.1f );
                    }
                }
            }
            VectorNormalize( bounce_dir );
            reflected = qtrue;
        }
    }
    if ( !reflected )
    {
        if ( missile->owner && missile->s.weapon != WP_SABER )
        {//bounce back at them if you can
            VectorSubtract( missile->owner->currentOrigin, missile->currentOrigin, bounce_dir );
            VectorNormalize( bounce_dir );
        }
        else
        {
            vec3_t missile_dir;

            VectorSubtract( ent->currentOrigin, missile->currentOrigin, missile_dir );
            VectorCopy( missile->s.pos.trDelta, bounce_dir );
            VectorScale( bounce_dir, DotProduct( forward, missile_dir ), bounce_dir );
            VectorNormalize( bounce_dir );
        }
        if ( owner->s.weapon == WP_SABER && owner->client )
        {//saber
            if ( owner->client->ps.saberInFlight )
            {//reflecting off a thrown saber is totally wild
                for ( i = 0; i < 3; i++ )
                {
                    bounce_dir[i] += Q_flrand( -0.8f, 0.8f );
                }
            }
            else if ( owner->client->ps.forcePowerLevel[FP_SABER_DEFENSE] <= FORCE_LEVEL_1 )
            {// at level 1
                for ( i = 0; i < 3; i++ )
                {
                    bounce_dir[i] += Q_flrand( -0.4f, 0.4f );
                }
            }
            else
            {// at level 2
                for ( i = 0; i < 3; i++ )
                {
                    bounce_dir[i] += Q_flrand( -0.2f, 0.2f );
                }
            }
            if ( !PM_SaberInParry( owner->client->ps.saberMove )
                && !PM_SaberInReflect( owner->client->ps.saberMove )
                && !PM_SaberInIdle( owner->client->ps.saberMove ) )
            {//a bit more wild
                if ( PM_SaberInAttack( owner->client->ps.saberMove )
                    || PM_SaberInTransitionAny( owner->client->ps.saberMove )
                    || PM_SaberInSpecialAttack( owner->client->ps.torsoAnim ) )
                {//really wild
                    for ( i = 0; i < 3; i++ )
                    {
                        bounce_dir[i] += Q_flrand( -0.3f, 0.3f );
                    }
                }
                else
                {//mildly more wild
                    for ( i = 0; i < 3; i++ )
                    {
                        bounce_dir[i] += Q_flrand( -0.1f, 0.1f );
                    }
                }
            }
        }
        else
        {//some other kind of reflection
            for ( i = 0; i < 3; i++ )
            {
                bounce_dir[i] += Q_flrand( -0.2f, 0.2f );
            }
        }
    }
    VectorNormalize( bounce_dir );
    VectorScale( bounce_dir, speed, missile->s.pos.trDelta );
#ifdef _DEBUG
        assert( !Q_isnan(missile->s.pos.trDelta[0])&&!Q_isnan(missile->s.pos.trDelta[1])&&!Q_isnan(missile->s.pos.trDelta[2]));
#endif// _DEBUG
    missile->s.pos.trTime = level.time - 10;        // move a bit on the very first frame
    VectorCopy( missile->currentOrigin, missile->s.pos.trBase );
    if ( missile->s.weapon != WP_SABER )
    {//you are mine, now!
        if ( !missile->lastEnemy )
        {//remember who originally shot this missile
            missile->lastEnemy = missile->owner;
        }
        missile->owner = owner;
    }
    if ( missile->s.weapon == WP_ROCKET_LAUNCHER )
    {//stop homing
        missile->e_ThinkFunc = thinkF_NULL;
    }
}
 
Just a taste of reflection code. :) I suggest you also to check all code voices related to FP_SABER_DEFENSE and all the function this power calls. sure you will find the amount of reflection skill related to every force power levels. :)
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...