Jump to content

Making a New class


Recommended Posts

Posted

I have a little question.

because JKA can have only 32 weapons and i need some more slots, and i cannot add more weapons... i was thinking about this:

should possible to add new AI Classes cloning some classes, and changing efx and sound of the weapons if they are shooted by that classes.

how many is difficult to make this thing? there is some restriction to the number of class of AI of Npcs can contain the game?

@@ent

@@eezstreet

@@ensiform

@@DT85

 

 

 

Posted

Who told you it can "only" have 32?

 

Adding new structures (or changing their object size) to clients will cause save game incompatibilities, sadly.  And in SP this field is engine-wide not mod-only.

 

The other option to avoid needing int64_t would be adding an extra STAT_WEAPONS field.  And using some bit storage checks to determine which array is currently being used.

 

Don't know anything about the AI stuff sorry.

Asgarath83 likes this
Posted

instead, adding new class is an extremely solution @@ensiform, that i prefear to avoid. i know that savegame can be compromise but all this editing stuff. :\

 

sure it's a stupid question, but is not a problem i have a 32 bit system  as windows OS for making a 64 bit code values for expanding storying cache of the weapon, @@ent?

i need simply to replace the storing weapon var int_t with a int64_t? :) i making some changes about that in past, if you remember, also with the 64 byt storing of the entities primitive for expand efx capacity. :)

however let me think... well theorically for my project i will need something as 16 new slot weapons :\

Posted

It is independant to OS bitness. Use int64_t.

@ensiform, if he is making new weapons then save games compatibility is out of question - it's definitely won't be compatible anyways. I am sure he knows that.

Posted

It is independant to OS bitness. Use int64_t.

@ensiform, if he is making new weapons then save games compatibility is out of question - it's definitely won't be compatible anyways. I am sure he knows that.

i have already added 3 new weapon to SP game also with NPC support. npc can use it and player can grab by deads npcs. ;)

i have not noticed any trouble with savegame. i now if code is edit all old savegame become unusable but i use ever consolle commnand for loading map and if i load the new save game with consolle they works fine D:

 

checked a new game with t1_fatal map. the savegame system is fine, also if i restart the game and i load savegame while player has selected as weapon the new weapon i added.

Posted

Who told you it can "only" have 32?

 

Adding new structures (or changing their object size) to clients will cause save game incompatibilities, sadly.  And in SP this field is engine-wide not mod-only.

 

The other option to avoid needing int64_t would be adding an extra STAT_WEAPONS field.  And using some bit storage checks to determine which array is currently being used.

 

Don't know anything about the AI stuff sorry.

code game statindex.h

typedef enum {
    STAT_HEALTH,
    STAT_ITEMS,
    STAT_WEAPONS,                    // 16 bit fields
    STAT_ARMOR,                
    STAT_DEAD_YAW,                    // look this direction when dead (FIXME: get rid of?)
    STAT_CLIENTS_READY,                // bit mask of clients wishing to exit the intermission (FIXME: configstring?)
    STAT_MAX_HEALTH                    // health / armor limit, changable by handicap
} statIndex_t;       
 

i need to add a new STAT_WEAPONS field here, with int64_t allocating memory, right? and using that for storage the new weapons up to the 32 value into the enumeration of weapons.h ... mmm, it's very complicated. o.o  i think i need some hints about procedure.

cg_players.cpp

 

bits = cg.snap->ps.stats[ STAT_WEAPONS ];

    // count the number of weapons owned
    count = 0;
    isOnVeh = (G_IsRidingVehicle(cg_entities[0].gent)!=0);
     for ( i = 1 ; i < MAX_PLAYER_WEAPONS ; i++ )
    {
        if ((bits & ( 1 << i ))  &&
            (!isOnVeh || i==WP_NONE || i==WP_SABER || i==WP_BLASTER))
        {
            count++;
        }
    }
Posted

It is independant to OS bitness. Use int64_t.

@ensiform, if he is making new weapons then save games compatibility is out of question - it's definitely won't be compatible anyways. I am sure he knows that.

But is he distributing a new engine or just a mod?  Engine changes is required to make either/any solution work.

 

And you now have to change that ENTIRE stat array to int64_t if you want to go with ent's option.  Plus the MSG_read/write functions also do not support > 32 so more changes required there as well.

 

Level transitions code in engine also blindly assumes the stats array is a regular int when reading/writing to the cvars.

 

There is no EASY solution for this.  The best imo, is to add STAT_WEAPONS2 but then you also have to create some functions for bit setting and bit checking and removing etc and replace all areas where STAT_WEAPONS is used with those functions to use the correct STAT_WEAPONS or STAT_WEAPONS2.  That one place you've shown is not the only location you need to look at unfortunately.  I cannot really help you with this right now sorry.

 

Something like this:

You'd have to use these everywhere pretty much though in place of the equivalent final line in each respective function.  And I'm not sure how that would work for the function you listed yet as it gets a bit more complicated.

qboolean BG_WeaponArrayCheck( const playerState_t *ps, int value )
{
	int choice = STAT_WEAPONS;
	if ( value > 31 )
	{
		choice = STAT_WEAPONS2;
		value -= 32;
	}

	return (ps->stats[choice] & (1 << value)) ? qtrue : qfalse;
}

void BG_WeaponArraySet( playerState_t *ps, int value )
{
	int choice = STAT_WEAPONS;
	if ( value > 31 )
	{
		choice = STAT_WEAPONS2;
		value -= 32;
	}

	ps->stats[choice] |= (1 << value);
}

void BG_WeaponArrayRemove( playerState_t *ps, int value )
{
	int choice = STAT_WEAPONS;
	if ( value > 31 )
	{
		choice = STAT_WEAPONS2;
		value -= 32;
	}

	ps->stats[choice] &= ~(1 << value);
}
Posted

 

But is he distributing a new engine or just a mod?  Engine changes is required to make either/any solution work.

 

And you now have to change that ENTIRE stat array to int64_t if you want to go with ent's option.  Plus the MSG_read/write functions also do not support > 32 so more changes required there as well.

 

Level transitions code in engine also blindly assumes the stats array is a regular int when reading/writing to the cvars.

 

There is no EASY solution for this.  The best imo, is to add STAT_WEAPONS2 but then you also have to create some functions for bit setting and bit checking and removing etc and replace all areas where STAT_WEAPONS is used with those functions to use the correct STAT_WEAPONS or STAT_WEAPONS2.  That one place you've shown is not the only location you need to look at unfortunately.  I cannot really help you with this right now sorry.

 

Something like this:

You'd have to use these everywhere pretty much though in place of the equivalent final line in each respective function.  And I'm not sure how that would work for the function you listed yet as it gets a bit more complicated.

qboolean BG_WeaponArrayCheck( const playerState_t *ps, int value )
{
	int choice = STAT_WEAPONS;
	if ( value > 31 )
	{
		choice = STAT_WEAPONS2;
		value -= 32;
	}

	return (ps->stats[choice] & (1 << value)) ? qtrue : qfalse;
}

void BG_WeaponArraySet( playerState_t *ps, int value )
{
	int choice = STAT_WEAPONS;
	if ( value > 31 )
	{
		choice = STAT_WEAPONS2;
		value -= 32;
	}

	ps->stats[choice] |= (1 << value);
}

void BG_WeaponArrayRemove( playerState_t *ps, int value )
{
	int choice = STAT_WEAPONS;
	if ( value > 31 )
	{
		choice = STAT_WEAPONS2;
		value -= 32;
	}

	ps->stats[choice] &= ~(1 << value);
}

mmmm.... yes is pretty complicated and is really over my actual knowledge and ability of the code.

it's not simple modding, this is like making a serious upgrade of the entire SP engine system array.  :\

i am again a noob for many sense. add new weapons and customize effects or change dmg by classes are little edit to the code. this is a total rewriting. for get more of 32 weapons i need to write and entire new STAT_WEAPON with a 64bit allocating memory cache and i need to use it for all new weapons > 32 value. this require a big amount of work. there is an alternative solution and i am thinking also about this: i need 16 new weapons i making the count, but all of that are "spells" not shooting weapons,. into SP game client force spells are just 16 so there is space for other 16 force power... i was thinking about this: making that not as weapons but as 16 new force powers... but they need to act as a force powers... i am thinking about something programmed like the force_lightning when player not shooting a ray burst of damaging force , but a projectile like a weapon. i think i can get the answer about this think studying the work of @@JediBantha from concussion to force destruction.

Posted

For JKG we didn't use two different STAT_ fields. Instead we kept two separate inventories on the client and server and kept them in sync. The server wasn't even aware of what was in your hotbar. (Technically this could open an exploit where you could get any weapon you wanted without actually buying it, but it wouldn't work properly as you wouldn't have ammo for it)

Each weapon had a base ID and variation ID. Base being weapon type (pistols, carbines, rifles, shotguns, rocket launchers, concussion rifles, grenades, trip mines, deployable explosives, chemical weapons, lightsaber. Probably other categories, these are the only ones I remember) and variation being the specific type (so pistol -> DE-10 Blaster Pistol, concussion rifle -> Stouker Concussion Rifle, etc)

I'm just saying that there's a lot of ways to design the net code. Also consider that you're in singleplayer. There's a lot of stuff you can get away with since this is true. Something like this appeals to me:

class Weapon {
public:
    Weapon(const char* filename) {
        /* Loads the file */
    }
    virtual void Fire (bool bAltFire) = 0;
    virtual void Equip () = 0;
protected:
    int fireTime;
    int primDamage; 
    /* ... */
}

struct gentity_t {
    ...
    std::vector <Weapon*> vOwnedWeapons;
    std::unordered_map <Weapon*, int> umAmmo;
}
There's a lot that can be said about the design of data types here, and even just a cursory glance over my code shows a few improvements that could be made.

 

I guess what I'm trying to say is simple. This is not really an easy fix if you stay inside the mindset of changing the engine to suit your needs. You really ought to dive in and see how everything works.

Asgarath83 likes this
Posted

For JKG we didn't use two different STAT_ fields. Instead we kept two separate inventories on the client and server and kept them in sync. The server wasn't even aware of what was in your hotbar. (Technically this could open an exploit where you could get any weapon you wanted without actually buying it, but it wouldn't work properly as you wouldn't have ammo for it)

Each weapon had a base ID and variation ID. Base being weapon type (pistols, carbines, rifles, shotguns, rocket launchers, concussion rifles, grenades, trip mines, deployable explosives, chemical weapons, lightsaber. Probably other categories, these are the only ones I remember) and variation being the specific type (so pistol -> DE-10 Blaster Pistol, concussion rifle -> Stouker Concussion Rifle, etc)

I'm just saying that there's a lot of ways to design the net code. Also consider that you're in singleplayer. There's a lot of stuff you can get away with since this is true. Something like this appeals to me:

class Weapon {
public:
    Weapon(const char* filename) {
        /* Loads the file */
    }
    virtual void Fire (bool bAltFire) = 0;
    virtual void Equip () = 0;
protected:
    int fireTime;
    int primDamage; 
    /* ... */
}

struct gentity_t {
    ...
    std::vector <Weapon*> vOwnedWeapons;
    std::unordered_map <Weapon*, int> umAmmo;
}
There's a lot that can be said about the design of data types here, and even just a cursory glance over my code shows a few improvements that could be made.

 

I guess what I'm trying to say is simple. This is not really an easy fix if you stay inside the mindset of changing the engine to suit your needs. You really ought to dive in and see how everything works.

 

 

 

Many thanks eez :) you make me a great suggest. now i am little tired so i need to have fresh mind for that. tomorrow i will think better on a solution about this. thanks however. i ended and hosted my tutorial about add a new SP weapon into the code. if you want examinate and test and see for approvation that's will make me very happy :) i hope it's okay as tutorial it's all i done with my new gun and for me it works pretty fine. greetings and have good time :) 

note: english is not my mother language, so sure the staff need to edit a lot for make more understandable. i am sure i had using some wrong word. i am apologize for that. :\ good night ^_^

Posted

Thanks @@eezstreet and @@Asgarath83 -- this thread will be useful when I get to the point of creating a new class for IG-88. :winkthumb:

Eh, not problem D: can you teach also to me how to do it? :) with new class with customize efx of weapon i can temporany solve my dilemma. i need just to know how to make something like_:

 

if CLASS_SHADOW  is using WP_BLASTpER_PISTOL

muzzleeffect -> bryar2/muzzle

altmuzzleeffect-> bryar2/altmuzzle

wallimpacteffect-> bryar2/wall_impact

fleshimpacteffect-> bryar2/flesh_impact.

projectileeffect ->bryar2/shot

primary file MOD-> MOD_SMOKING

altprimary file means of death  -> ,MOD_SMOKING_ALT

the weapon is the same, but when using NPC with this class, weapon making different efx. that's is what i was thinking.

no matter about weapons models., on my mod weapons are converted into spell shooted by hands so models are removed.

 

But i am also thinking about the words of @@eezstreet of SWG, and i have an idea about a coding project. because is VERY FRUSTRATING the JKA limitation about adding weapons and force powers, because every time need to deep hack the code i was thinking about this:

you get the WP_SABER, you know? WP_SABER has SAB files that allow to modder to easy customize every kind of lightsaber or melee weapons!

i was thinking about this: why not make for every default weapon of the game, not as a weapon, but as a weapon class!

example: blaster pistol become the weapon class gun. and there as .GUN files that allow to people to add and customize dozens of guns to his characters. exactly like the saber. same thing with rifle class, disruptor class, bowcaster class, demp2 class, flechette class, concussioin class, rocket class, grenade class, mine class, explosive class, i think this can be encoded as an half way between the SAB file programming and the weapon file format of the vehicles . :) in that mode weapons can be added as external data, exactly as saber and they are pretty customizable! XD should be a wonderful dream.

but for know if is it possible i need really to study how work the code of SAB files and Weapon vehicle files. external data. :\

Posted

Mmmm, @@ensiform

at the end, the better solution is the more easy. what i need to do is simply that:

i have a magical mod.

i removed models of weapons and character shoot by hands, like @@Langerd mod.

i modded weapon for be aligned to the follow elements:

blasterpistol: darkness

jawa: sonic (i separate efx for jawa and bryar pistol weapon by blaster pistol effect)

disruptor: magic bow.

blaster: fire

repeater: water

flechette: earth

demp2: spirit

rocket: comprex air bolt explosion

bowcaster: light balls

concussion: necromancy.

poison (new weapon added for making the noghri stick poison spray available for player without crash)

my mod got some heroes and every hero control an element, so use saber + one of this shooting weapons spells.

they can found some temple with puzzles that completed upgrade their power. each powerr can be upgrated two times, except jawa and concussion rifle.

every upgrade will change efx and sound of the weapon.

example: repeater: after first upgrade, repeater change water atk effect into frost \ ice, the second upgrade upgrade ice to crystal atk.

using DEMP2 droid weakness class code, i making a big array of if else that make all classes resistance or weakness to a certain

elemental weapon.

every AI class of JKA has getting a role as "elemental creature" so BARTENDER i use for ice creature, HAZARDTROOPER for magma creatures, REBORN for vampires, PROTOCOL for creature of light elemental etc. it's all modded like a fantasy rpg.

using @@Serenity937 hints, i changed force power efx and sound so, every class can cast custom efx and sound attack with force drain, force lightning etc.

example:. bartender class force lightning are a snow burst attack, not an electric attack.

that's is already done and working on my mod.

the unique thing i need is just this:

because adding more of 32 weapons is really over of my coding skills, i am thinking about this solution:

for every weapon, 2 elemental class, that using that weapon will shoots custom efx and sound.

example:

repeater:

if weapon is repeater. and if shooting class is CLASS_BARTENDER, repeater not shoot water efx but use muzzle efx , projectile efx, wall impact and flesh impact efx of ice.

if weapon is repater and is shooting by CLASS_GALAKMECH, it shoot crystal.

looking at blaster_rifle.cpp  i found how allow to a class to do more dmg with a weapon.

yesterday i making this.:

if CLASS_GRAN use WP_BLASTER making 1.5x dmg. (fireball upgraded projectiles) if use HAZARD_TROOPER class, making 2x damage (Magma Projectiles)

here my edit on WP_blaster_rifle.cpp about the increased damaged by a shooting class...

 

what i need is simply that: changing efx of a weapons by the class of owner shooter. exaclty as i make with force lightning and drain power with @@Serenity937 . so, without adding new weapons, i can however making different version of the shoot efx of a weapons simply changing the shooting class. into mod external data, for unlock these on player will be sufficient using playermodel command for change the class of the heroes to new class with different elemental efx.

void WP_FireBlasterMissile( gentity_t *ent, vec3_t start, vec3_t dir, qboolean altFire )
//---------------------------------------------------------
{
    int velocity    = BLASTER_VELOCITY;
    int    damage        = altFire ? weaponData[WP_BLASTER].damage : weaponData[WP_BLASTER].damage;

    if ( ent && ent->client && ent->client->NPC_class == CLASS_VEHICLE )
    {
        damage *= 3;
        velocity = ATST_MAIN_VEL + ent->client->ps.speed;
    }
    else if ( ent && ent->client && ent->client->NPC_class == CLASS_CLAW )
    {
        damage *= 1.5; // Elementali del Calore fanno 50% di danno in più!
    }
    else if ( ent && ent->client && ent->client->NPC_class == CLASS_HAZARD_TROOPER )
    {
        damage *= 2; // Elementali del Magma fanno 50% di danno doppio!!
    }
    else
    {
        // If an enemy is shooting at us, lower the velocity so you have a chance to evade
        if ( ent->client && ent->client->ps.clientNum != 0 && ent->client->NPC_class != CLASS_BOBAFETT )
        {
            if ( g_spskill->integer < 2 )
            {        
                velocity *= BLASTER_NPC_VEL_CUT;
            }
            else
            {
                velocity *= BLASTER_NPC_HARD_VEL_CUT;
            }
        }
    }

    WP_TraceSetStart( ent, start, vec3_origin, vec3_origin );//make sure our start point isn't on the other side of a wall

    WP_MissileTargetHint(ent, start, dir);

    gentity_t *missile = CreateMissile( start, dir, velocity, 10000, ent, altFire );

    missile->classname = "blaster_proj";
    missile->s.weapon = WP_BLASTER;

    // Do the damages
    if ( ent->s.number != 0 && ent->client->NPC_class != CLASS_BOBAFETT )
    {
        if ( g_spskill->integer == 0 )
        {
            damage = BLASTER_NPC_DAMAGE_EASY;
        }
        else if ( g_spskill->integer == 1 )
        {
            damage = BLASTER_NPC_DAMAGE_NORMAL;
        }
        else
        {
            damage = BLASTER_NPC_DAMAGE_HARD;
        }
    }

    if ( ent->client->NPC_class == CLASS_GRAN )
    {
        {
            damage *= 1.5;
            
        }
    }
    else if ( ent->client->NPC_class == CLASS_HAZARD_TROOPER )
    {
        {
            damage *= 2;
        }
    }

that's is for damage, now i need to make the same thing for effects, but every time i trying to edit the effect array into FX_blaster.cpp

the game still crashing when blaster is shooting or when is hitting a wall or a npc.

i have already efx files and sounds ready for the new effect, i need just to tell to the code "when blaster is used by these classes, it make different visual efx of projectiles and wall and flesh impact)

Posted

Perhaps use the debugger :P  Or read the other code a bit better?

good point, sure the answer is in the code itself. pity there is no moment into the game when some class change the effect of is weapons, so i have nothing as example for a start point. but i begin to think maybe the answer could be into the forge rage sound effect code that's is played on the caster. it's all a question of cent \, gent\ , self\,  ent client parameters, i need to set in the right mode in the right place of the code. :)

Posted

@@ensiform

 

thanks! yes! i did it!!

CLASS_CLAW with blaster shoot magma bolts!

magma bolt has damage increased!

 

http://postimg.org/image/wrj5zwcj5/

 

 

WP_BLASTER_RIFLE.CPP
 
//---------------------------------------------------------
void WP_FireBlasterMissile( gentity_t *ent, vec3_t start, vec3_t dir, qboolean altFire )
//---------------------------------------------------------
{
    int velocity    = BLASTER_VELOCITY;
    int    damage        = altFire ? weaponData[WP_BLASTER].damage : weaponData[WP_BLASTER].damage;

    if ( ent && ent->client && ent->client->NPC_class == CLASS_VEHICLE )
    {
        damage *= 3;
        velocity = ATST_MAIN_VEL + ent->client->ps.speed;
    }
    else if ( ent && ent->client && ent->client->NPC_class == CLASS_HAZARD_TROOPER )
    {
        damage *= 1.5; // Elementali del Calore fanno 50% di danno in più!
    }
    else if ( ent && ent->client && ent->client->NPC_class == CLASS_CLAW )
    {
        damage *= 2; // Elementali del Magma fanno 50% di danno doppio!!
    }
    else
    {
        // If an enemy is shooting at us, lower the velocity so you have a chance to evade
        if ( ent->client && ent->client->ps.clientNum != 0 && ent->client->NPC_class != CLASS_BOBAFETT )
        {
            if ( g_spskill->integer < 2 )
            {        
                velocity *= BLASTER_NPC_VEL_CUT;
            }
            else
            {
                velocity *= BLASTER_NPC_HARD_VEL_CUT;
            }
        }
    }

    WP_TraceSetStart( ent, start, vec3_origin, vec3_origin );//make sure our start point isn't on the other side of a wall

    WP_MissileTargetHint(ent, start, dir);

    gentity_t *missile = CreateMissile( start, dir, velocity, 10000, ent, altFire );

    missile->classname = "blaster_proj";
    missile->s.weapon = WP_BLASTER;

    // Do the damages
    if ( ent->s.number != 0 && ent->client->NPC_class != CLASS_BOBAFETT )
    {
        if ( g_spskill->integer == 0 )
        {
            damage = BLASTER_NPC_DAMAGE_EASY;
        }
        else if ( g_spskill->integer == 1 )
        {
            damage = BLASTER_NPC_DAMAGE_NORMAL;
        }
        else
        {
            damage = BLASTER_NPC_DAMAGE_HARD;
        }
    }

    if ( ent->client->NPC_class == CLASS_HAZARD_TROOPER )
    {
        {
            damage *= 1.5;
            
        }
    }
    else if ( ent->client->NPC_class == CLASS_CLAW )
    {
        {
            damage *= 2;
        }
    }

//    if ( ent->client )
//    {
//        if ( ent->client->ps.powerups[PW_WEAPON_OVERCHARGE] > 0 && ent->client->ps.powerups[PW_WEAPON_OVERCHARGE] > cg.time )
//        {
//            // in overcharge mode, so doing double damage
//            missile->flags |= FL_OVERCHARGED;
//            damage *= 2;
//        }
//    }

    missile->damage = damage;
    missile->dflags = DAMAGE_DEATH_KNOCKBACK;
    if ( altFire )
    {
        missile->methodOfDeath = MOD_BLASTER_ALT;
    }
    else
    {
        missile->methodOfDeath = MOD_BLASTER;
    }
    missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;

    // we don't want it to bounce forever
    missile->bounceCount = 8;
}

//---------------------------------------------------------
void WP_FireBlaster( gentity_t *ent, qboolean alt_fire )
//---------------------------------------------------------
{
    vec3_t    dir, angs;

    vectoangles( forwardVec, angs );

    if ( ent->client && ent->client->NPC_class == CLASS_VEHICLE )
    {//no inherent aim screw up
    }
    else if ( !(ent->client->ps.forcePowersActive&(1<<FP_SEE))
        || ent->client->ps.forcePowerLevel[FP_SEE] < FORCE_LEVEL_2 )
    {//force sight 2+ gives perfect aim
        //FIXME: maybe force sight level 3 autoaims some?
        if ( alt_fire )
        {
            // add some slop to the alt-fire direction
            angs[PITCH] += crandom() * BLASTER_ALT_SPREAD;
            angs[YAW]    += crandom() * BLASTER_ALT_SPREAD;
        }
        else
        {
            // Troopers use their aim values as well as the gun's inherent inaccuracy
            // so check for all classes of stormtroopers and anyone else that has aim error
            if ( ent->client && ent->NPC &&
                ( ent->client->NPC_class == CLASS_GRAN ||
                ent->client->NPC_class == CLASS_HAZARD_TROOPER ) )
            {
                angs[PITCH] += ( crandom() * (BLASTER_NPC_SPREAD+(6-ent->NPC->currentAim)*0.25f));//was 0.5f
                angs[YAW]    += ( crandom() * (BLASTER_NPC_SPREAD+(6-ent->NPC->currentAim)*0.25f));//was 0.5f
            }
            else
            {
                // add some slop to the main-fire direction
                angs[PITCH] += crandom() * BLASTER_MAIN_SPREAD;
                angs[YAW]    += crandom() * BLASTER_MAIN_SPREAD;
            }
        }
    }

    AngleVectors( angs, dir, NULL, NULL );

    // FIXME: if temp_org does not have clear trace to inside the bbox, don't shoot!
    WP_FireBlasterMissile( ent, muzzle, dir, alt_fire );
}
 
FX_BLASTER.CPP
/*
-------------------------
FX_BlasterProjectileThink
-------------------------
*/
void FX_BlasterProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
    vec3_t forward;
    if (cent->currentState.eFlags & EF_USE_ANGLEDELTA)
    {
        AngleVectors(cent->currentState.angles, forward, 0, 0);
    }
    else
    {
        if ( VectorNormalize2( cent->gent->s.pos.trDelta, forward ) == 0.0f )
        {
            if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
            {
                forward[2] = 1.0f;
            }
        }
    }

    // hack the scale of the forward vector if we were just fired or bounced...this will shorten up the tail for a split second so tails don't clip so harshly
    int dif = cg.time - cent->gent->s.pos.trTime;

    if ( dif < 75 )
    {
        if ( dif < 0 )
        {
            dif = 0;
        }

        float scale = ( dif / 75.0f ) * 0.95f + 0.05f;

        VectorScale( forward, scale, forward );
    }

    if ( cent->gent && cent->gent->owner && cent->gent->owner->s.number > 0 )
    {
        theFxScheduler.PlayEffect( "blaster/NPCshot", cent->lerpOrigin, forward );

        if ( cent->gent->owner->client->NPC_class == CLASS_HAZARD_TROOPER )
        theFxScheduler.PlayEffect( "blaster2/NPCshot", cent->lerpOrigin, forward );
        else if ( cent->gent->owner->client->NPC_class == CLASS_CLAW )
        theFxScheduler.PlayEffect( "blaster3/NPCshot", cent->lerpOrigin, forward );
    }
    else
    {
        theFxScheduler.PlayEffect( cgs.effects.blasterShotEffect, cent->lerpOrigin, forward );

        if ( cent->gent->owner->client->NPC_class == CLASS_HAZARD_TROOPER )
        theFxScheduler.PlayEffect( "blaster2/shot", cent->lerpOrigin, forward );
        else if ( cent->gent->owner->client->NPC_class == CLASS_CLAW )
        theFxScheduler.PlayEffect( "blaster3/shot", cent->lerpOrigin, forward );
    }
}
 

 

Now i need to do this also for wall impact, flesh impact and muzzle flashes efx! :D  and i am okay!

Posted

 

 
if ( cent->gent && cent->gent->owner && cent->gent->owner->s.number > 0 )
    {
        // theFxScheduler.PlayEffect( "blaster/NPCshot", cent->lerpOrigin, forward );

        if ( cent->gent->owner->client->NPC_class == CLASS_HAZARD_TROOPER )
        theFxScheduler.PlayEffect( "blaster2/NPCshot", cent->lerpOrigin, forward );
        else if ( cent->gent->owner->client->NPC_class == CLASS_CLAW )
        theFxScheduler.PlayEffect( "blaster3/NPCshot", cent->lerpOrigin, forward );
        else if ( cent->gent->owner->client->NPC_class != CLASS_CLAW ||
        cent->gent->owner->client->NPC_class != CLASS_HAZARD_TROOPER )
        theFxScheduler.PlayEffect( "blaster/NPCshot", cent->lerpOrigin, forward );
    }
    else
    {
        // theFxScheduler.PlayEffect( cgs.effects.blasterShotEffect, cent->lerpOrigin, forward );

        if ( cent->gent->owner->client->NPC_class == CLASS_HAZARD_TROOPER )
        theFxScheduler.PlayEffect( "blaster2/shot", cent->lerpOrigin, forward );
        else if ( cent->gent->owner->client->NPC_class == CLASS_CLAW )
        theFxScheduler.PlayEffect( "blaster3/shot", cent->lerpOrigin, forward );
        else if ( cent->gent->owner->client->NPC_class != CLASS_CLAW ||
        cent->gent->owner->client->NPC_class != CLASS_HAZARD_TROOPER )
        theFxScheduler.PlayEffect( "blaster/shot", cent->lerpOrigin, forward );

    }
 

Little edit because i see that engine play together efx of blaster and blaster2 or blaster and blaster3 projectiles.

fixed. if blaster is shooted by CLASS_HAZARD_TROOPER do blaster2 efx, if blaster is shooted by CLASS_CLAW do blaster3 efx.

if blaster is shooted by a class different of CLASS_CLAW and CLASS_HAZARDTROOPER, shoot normal blaster projectile.

:)

Posted

@@eezstreet

@@ensiform

@@ent

@@Xycaleth

did it! now blaster rifle shoot 3 different kind of fireball attack efx and sound at second of shooting ai CLASS of NPC. D:

muzzleefx, altmuzzleefx, shoots, wallimpact and fleshimpact. this need a little low of edit and adding switch cases and if \ else expression into  wp_blaster_rifle.cpp FX_blaster.cpp cg_weapons, cg_media.h and cg_local.h

this open a large amount of scenarios. there are 64 Ai NPC classes into SP game and so if i want now a weapon is like 64 weapons XD :P thanks very much for all suggest.

the only tning i need to solve is that when saber deflect fireballs of burning fire and magma they return on the default fireball efx. i think i will disable the saber deflecting function of saber defense. for contest of my mod is not necessary. blocking shoots with blades okay, but no deflecting. i need to study the rocket launcher code for understand how to do it. rockets cannot be deflected by sabers. :)

 

 

.

Posted

Here what i did:

for muzzle flash and damage: (on weapon.dat muzzle flash and altmuzzleflash of blaster now are disabled)

wp_blaster_rifle_cpp

 

// Do the damages
    if ( ent->s.number != 0 && ent->client->NPC_class != CLASS_BOBAFETT )
    {
        if ( g_spskill->integer == 0 )
        {
            damage = BLASTER_NPC_DAMAGE_EASY;
        }
        else if ( g_spskill->integer == 1 )
        {
            damage = BLASTER_NPC_DAMAGE_NORMAL;
        }
        else
        {
            damage = BLASTER_NPC_DAMAGE_HARD;
        }
    }

if ( altFire )
{
    if ( ent->client->NPC_class == CLASS_HAZARD_TROOPER )
    {
        {
            damage *= 1.5;
            G_PlayEffect( G_EffectIndex( "blaster2/altmuzzle_flash" ), ent->client->renderInfo.handRPoint, dir );
        }
    }
    else if ( ent->client->NPC_class == CLASS_CLAW )
    {
        {
            damage *= 2;
            G_PlayEffect( G_EffectIndex( "blaster3/altmuzzle_flash" ), ent->client->renderInfo.handRPoint, dir );

        }
    }
    else if ( ent->client->NPC_class != CLASS_CLAW || ent->client->NPC_class != CLASS_HAZARD_TROOPER )
    {
        {
            damage *= 1;
            G_PlayEffect( G_EffectIndex( "blaster/altmuzzle_flash" ), ent->client->renderInfo.handRPoint, dir );

        }
    }
}
else
{
    if ( ent->client->NPC_class == CLASS_HAZARD_TROOPER )
    {
        {
            damage *= 1.5;
            G_PlayEffect( G_EffectIndex( "blaster2/muzzle_flash" ), ent->client->renderInfo.handRPoint, dir );
        }
    }
    else if ( ent->client->NPC_class == CLASS_CLAW )
    {
        {
            damage *= 2;
            G_PlayEffect( G_EffectIndex( "blaster3/muzzle_flash" ), ent->client->renderInfo.handRPoint, dir );

        }
    }
    else if ( ent->client->NPC_class != CLASS_CLAW || ent->client->NPC_class != CLASS_HAZARD_TROOPER )
    {
        {
            damage *= 1;
            G_PlayEffect( G_EffectIndex( "blaster/muzzle_flash" ), ent->client->renderInfo.handRPoint, dir );

        }
    }
}

for shot efx

FX_blaster_rifle.cpp

 

// hack the scale of the forward vector if we were just fired or bounced...this will shorten up the tail for a split second so tails don't clip so harshly
    int dif = cg.time - cent->gent->s.pos.trTime;

    if ( dif < 75 )
    {
        if ( dif < 0 )
        {
            dif = 0;
        }

        float scale = ( dif / 75.0f ) * 0.95f + 0.05f;

        VectorScale( forward, scale, forward );
    }

    if ( cent->gent && cent->gent->owner && cent->gent->owner->s.number > 0 )
    {
        // theFxScheduler.PlayEffect( "blaster/NPCshot", cent->lerpOrigin, forward );

        if ( cent->gent->owner->client->NPC_class == CLASS_HAZARD_TROOPER )
        theFxScheduler.PlayEffect( "blaster2/NPCshot", cent->lerpOrigin, forward );
        else if ( cent->gent->owner->client->NPC_class == CLASS_CLAW )
        theFxScheduler.PlayEffect( "blaster3/NPCshot", cent->lerpOrigin, forward );
        else if ( cent->gent->owner->client->NPC_class != CLASS_CLAW ||
        cent->gent->owner->client->NPC_class != CLASS_HAZARD_TROOPER )
        theFxScheduler.PlayEffect( "blaster/NPCshot", cent->lerpOrigin, forward );
    }
    else
    {
        // theFxScheduler.PlayEffect( cgs.effects.blasterShotEffect, cent->lerpOrigin, forward );

        if ( cent->gent->owner->client->NPC_class == CLASS_HAZARD_TROOPER )
        theFxScheduler.PlayEffect( "blaster2/shot", cent->lerpOrigin, forward );
        else if ( cent->gent->owner->client->NPC_class == CLASS_CLAW )
        theFxScheduler.PlayEffect( "blaster3/shot", cent->lerpOrigin, forward );
        else if ( cent->gent->owner->client->NPC_class != CLASS_CLAW ||
        cent->gent->owner->client->NPC_class != CLASS_HAZARD_TROOPER )
        theFxScheduler.PlayEffect( "blaster/shot", cent->lerpOrigin, forward );
    }
}

/*
-------------------------
FX_BlasterAltFireThink
-------------------------
*/

for impact and impactbody efx

on FX_blaster_rifle.cpp

 

/*
-------------------------
FX_BlasterWeaponHitWall
-------------------------
*/
void FX_BlasterWeaponHitWall( vec3_t origin, vec3_t normal )
{
        theFxScheduler.PlayEffect( cgs.effects.blasterWallImpactEffect, origin, normal );
}

void FX_WarmHitWall( vec3_t origin, vec3_t normal )
{
    
        theFxScheduler.PlayEffect( cgs.effects.warmWallImpactEffect, origin, normal );
}

void FX_MagmaHitWall( vec3_t origin, vec3_t normal )
{
    
        theFxScheduler.PlayEffect( cgs.effects.magmaWallImpactEffect, origin, normal );
}


/*
-------------------------
FX_BlasterWeaponHitPlayer
-------------------------
*/
void FX_BlasterWeaponHitPlayer( gentity_t *hit, vec3_t origin, vec3_t normal, qboolean humanoid )
{
    //temporary? just testing out the damage skin stuff -rww
    if ( hit && hit->client && hit->ghoul2.size() )
    {
    //    theFxScheduler.PlayEffect( cgs.effects.blasterFleshImpactEffect, origin, normal );
        CG_AddGhoul2Mark(cgs.media.bdecal_burnmark1, flrand(3.5, 4.0), origin, normal, hit->s.number,
        hit->client->ps.origin, hit->client->renderInfo.legsYaw, hit->ghoul2, hit->s.modelScale, Q_irand(10000, 13000));
    }
        
    theFxScheduler.PlayEffect( cgs.effects.blasterFleshImpactEffect, origin, normal );
}

void FX_WarmHitPlayer( gentity_t *hit, vec3_t origin, vec3_t normal, qboolean humanoid )
{
    //temporary? just testing out the damage skin stuff -rww
    if ( hit && hit->client && hit->ghoul2.size() )
    {
    //    theFxScheduler.PlayEffect( cgs.effects.blasterFleshImpactEffect, origin, normal );
        CG_AddGhoul2Mark(cgs.media.bdecal_burnmark1, flrand(3.5, 4.0), origin, normal, hit->s.number,
        hit->client->ps.origin, hit->client->renderInfo.legsYaw, hit->ghoul2, hit->s.modelScale, Q_irand(10000, 13000));
    }
        
    theFxScheduler.PlayEffect( cgs.effects.warmFleshImpactEffect, origin, normal );
}

void FX_MagmaHitPlayer( gentity_t *hit, vec3_t origin, vec3_t normal, qboolean humanoid )
{
    //temporary? just testing out the damage skin stuff -rww
    if ( hit && hit->client && hit->ghoul2.size() )
    {
    //    theFxScheduler.PlayEffect( cgs.effects.blasterFleshImpactEffect, origin, normal );
        CG_AddGhoul2Mark(cgs.media.bdecal_burnmark1, flrand(3.5, 4.0), origin, normal, hit->s.number,
        hit->client->ps.origin, hit->client->renderInfo.legsYaw, hit->ghoul2, hit->s.modelScale, Q_irand(10000, 13000));
    }
        
    theFxScheduler.PlayEffect( cgs.effects.magmaFleshImpactEffect, origin, normal );
}

cg_local.h

 

void FX_BlasterProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_BlasterAltFireThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_BlasterWeaponHitWall( vec3_t origin, vec3_t normal );
void FX_WarmHitWall( vec3_t origin, vec3_t normal );
void FX_MagmaHitWall( vec3_t origin, vec3_t normal );
void FX_BlasterWeaponHitPlayer( gentity_t *hit, vec3_t origin, vec3_t normal, qboolean humanoid );
void FX_WarmHitPlayer( gentity_t *hit, vec3_t origin, vec3_t normal, qboolean humanoid );
void FX_MagmaHitPlayer( gentity_t *hit, vec3_t origin, vec3_t normal, qboolean humanoid );

cg_media.h

 

// WARM
    fxHandle_t    warmShotEffect;
    fxHandle_t    warmOverchargeEffect;
    fxHandle_t    warmWallImpactEffect;
    fxHandle_t    warmFleshImpactEffect;
// MAGMA
    fxHandle_t    magmaShotEffect;
    fxHandle_t    magmaOverchargeEffect;
    fxHandle_t    magmaWallImpactEffect;
    fxHandle_t    magmaFleshImpactEffect;

cg_weapons.cpp

 

case WP_BLASTER:
        cgs.effects.blasterShotEffect            = theFxScheduler.RegisterEffect( "blaster/shot" );
                                                    theFxScheduler.RegisterEffect( "blaster/NPCshot" );
//        cgs.effects.blasterOverchargeEffect        = theFxScheduler.RegisterEffect( "blaster/overcharge" );
        cgs.effects.blasterWallImpactEffect        = theFxScheduler.RegisterEffect( "blaster/wall_impact" );
        cgs.effects.blasterFleshImpactEffect    = theFxScheduler.RegisterEffect( "blaster/flesh_impact" );
        theFxScheduler.RegisterEffect( "blaster/deflect" );
        theFxScheduler.RegisterEffect( "blaster/smoke_bolton" ); // note: this will be called game side
        // WARM EFFECTS
        cgs.effects.warmShotEffect            = theFxScheduler.RegisterEffect( "blaster2/shot" );
                                               theFxScheduler.RegisterEffect( "blaster2/NPCshot" );
//        cgs.effects.blasterOverchargeEffect        = theFxScheduler.RegisterEffect( "blaster/overcharge" );
        cgs.effects.warmWallImpactEffect        = theFxScheduler.RegisterEffect( "blaster2/wall_impact" );
        cgs.effects.warmFleshImpactEffect    = theFxScheduler.RegisterEffect( "blaster2/flesh_impact" );

        // MAGMA EFFECTS
        cgs.effects.magmaShotEffect            = theFxScheduler.RegisterEffect( "blaster3/shot" );
                                               theFxScheduler.RegisterEffect( "blaster3/NPCshot" );
//        cgs.effects.blasterOverchargeEffect        = theFxScheduler.RegisterEffect( "blaster/overcharge" );
        cgs.effects.magmaWallImpactEffect        = theFxScheduler.RegisterEffect( "blaster3/wall_impact" );
        cgs.effects.magmaFleshImpactEffect    = theFxScheduler.RegisterEffect( "blaster3/flesh_impact" );


        break;

 

 

 

/*
=================
CG_MissileHitWall

Caused by an EV_MISSILE_MISS event, or directly by local bullet tracing
=================
*/
void CG_MissileHitWall( centity_t *cent, int weapon, vec3_t origin, vec3_t dir, qboolean altFire )
{
    int parm;

    switch( weapon )
    {
    case WP_BRYAR_PISTOL:
        if ( altFire )
        {
            parm = 0;

            if ( cent->gent )
            {
                parm += cent->gent->count;
            }

            FX_BowAltHitWall( origin, dir, parm );
        }
        else
        {
            FX_BowHitWall( origin, dir );
        }
        break;
    case WP_BLASTER_PISTOL:
        if ( altFire )
        {
            parm = 0;

            if ( cent->gent )
            {
                parm += cent->gent->count;
            }

            FX_BryarAltHitWall( origin, dir, parm );
        }
        else
        {
            FX_BryarHitWall( origin, dir );
        }
        break;
    case WP_JAWA:
        if ( altFire )
        {
            parm = 0;

            if ( cent->gent )
            {
                parm += cent->gent->count;
            }

            FX_HowlerAltHitWall( origin, dir, parm );
        }
        else
        {
            FX_HowlerHitWall( origin, dir );
        }
        break;
        case WP_BLOODGUN:
        if ( altFire )
        {
            parm = 0;

            if ( cent->gent )
            {
                parm += cent->gent->count;
            }

            FX_BloodGunAltHitWall( origin, dir, parm );
        }
        else
        {
            FX_BloodGunHitWall( origin, dir );
        }
        break;

    case WP_BLASTER:
        if ( cent->gent->owner->client )
        {
            switch ( cent->gent->owner->client->NPC_class )
            {
            case CLASS_HAZARD_TROOPER:
            FX_WarmHitWall( origin, dir );
                break;
            case CLASS_CLAW:
            FX_MagmaHitWall( origin, dir );
                break;
            case CLASS_REBORN:
            case CLASS_KYLE:
            case CLASS_ATST:                // technically droid...
            case CLASS_BARTENDER:
            case CLASS_BESPIN_COP:
            case CLASS_COMMANDO:
            case CLASS_DESANN:
            case CLASS_FISH:
            case CLASS_FLIER2:
            case CLASS_GALAK:
            case CLASS_GLIDER:
            case CLASS_GONK:
            case CLASS_GRAN:
            case CLASS_HOWLER:
            case CLASS_RANCOR:
            case CLASS_SAND_CREATURE:
            case CLASS_WAMPA:
            case CLASS_IMPERIAL:
            case CLASS_IMPWORKER:
            case CLASS_INTERROGATOR:
            case CLASS_JAN:
            case CLASS_JEDI:
            case CLASS_LANDO:
            case CLASS_LIZARD:
            case CLASS_LUKE:
            case CLASS_MARK1:
            case CLASS_MARK2:
            case CLASS_GALAKMECH:
            case CLASS_MINEMONSTER:
            case CLASS_MONMOTHA:
            case CLASS_MORGANKATARN:
            case CLASS_MOUSE:
            case CLASS_MURJJ:
            case CLASS_PRISONER:
            case CLASS_PROBE:
            case CLASS_PROTOCOL:
            case CLASS_R2D2:
            case CLASS_R5D2:
            case CLASS_REBEL:
            case CLASS_REELO:
            case CLASS_REMOTE:
            case CLASS_RODIAN:
            case CLASS_SEEKER:
            case CLASS_SENTRY:
            case CLASS_SHADOWTROOPER:
            case CLASS_SABOTEUR:
            case CLASS_STORMTROOPER:
            case CLASS_SWAMP:
            case CLASS_SWAMPTROOPER:
            case CLASS_NOGHRI:
            case CLASS_TAVION:
            case CLASS_ALORA:
            case CLASS_TRANDOSHAN:
            case CLASS_UGNAUGHT:
            case CLASS_JAWA:
            case CLASS_WEEQUAY:
            case CLASS_TUSKEN:
            case CLASS_BOBAFETT:
            case CLASS_ROCKETTROOPER:
            case CLASS_SABER_DROID:
            case CLASS_ASSASSIN_DROID:
            case CLASS_PLAYER:
            case CLASS_VEHICLE:
            FX_BlasterWeaponHitWall( origin, dir );
            break;
        default:
            break;
            }
        }
        //FX_BlasterWeaponHitWall( origin, dir );
        break;

    case WP_BOWCASTER:
        FX_BowcasterHitWall( origin, dir );
        break;
 

 

 

/*
-------------------------
CG_MissileHitPlayer
-------------------------
*/

void CG_MissileHitPlayer( centity_t *cent, int weapon, vec3_t origin, vec3_t dir, qboolean altFire )
{
    gentity_t *other = NULL;
    qboolean    humanoid = qtrue;
    
    if ( cent->gent )
    {
        other = &g_entities[cent->gent->s.otherEntityNum];
        if( other->client )
        {
            class_t    npc_class = other->client->NPC_class;
            // check for all droids, maybe check for certain monsters if they're considered non-humanoid..?        
            if ( npc_class == CLASS_SEEKER || npc_class == CLASS_PROBE || npc_class == CLASS_MOUSE ||
                 npc_class == CLASS_GONK || npc_class == CLASS_R2D2 || npc_class == CLASS_R5D2 ||
                 npc_class == CLASS_PROTOCOL || npc_class == CLASS_MARK1 || npc_class == CLASS_MARK2 ||
                 npc_class == CLASS_INTERROGATOR || npc_class == CLASS_ATST || npc_class == CLASS_SENTRY )
            {
                humanoid = qfalse;
            }
        }
    }

    /*if ( cent->gent )
    {
        other = &g_entities[cent->gent->s.otherEntityNum];
        if( other->client )
        {
            class_t    npc_class = other->client->NPC_class;
            // check for all droids, maybe check for certain monsters if they're considered non-humanoid..?        
            if ( npc_class == CLASS_GRAN )
            {
                switch (weapon )
                (
                  case WP_BLASTER
                  FX_WarmHitPlayer( other, origin, dir, humanoid )
            }
        }
    }*/
        
    switch( weapon )
    {
    case WP_BRYAR_PISTOL:
        if ( altFire )
        {
            FX_BowAltHitPlayer( origin, dir, humanoid );
        }
        else
        {
            FX_BowHitPlayer( origin, dir, humanoid );
        }
        break;
    case WP_BLASTER_PISTOL:
        if ( altFire )
        {
            FX_BryarAltHitPlayer( origin, dir, humanoid );
        }
        else
        {
            FX_BryarHitPlayer( origin, dir, humanoid );
        }
        break;
    case WP_JAWA:
        if ( altFire )
        {
            FX_HowlerAltHitPlayer( origin, dir, humanoid );
        }
        else
        {
            FX_HowlerHitPlayer( origin, dir, humanoid );
        }
        break;
    case WP_BLOODGUN:
        if ( altFire )
        {
            FX_BloodGunAltHitPlayer( origin, dir, humanoid );
        }
        else
        {
            FX_BloodGunHitPlayer( origin, dir, humanoid );
        }
        break;

    case WP_BLASTER:
        //FX_BlasterWeaponHitPlayer( other, origin, dir, humanoid );
        //break;
        if ( cent->gent->owner->client )
        {
            switch ( cent->gent->owner->client->NPC_class )
            {
            case CLASS_HAZARD_TROOPER:
            FX_WarmHitPlayer( other, origin, dir, humanoid );
                break;
            case CLASS_CLAW:
            FX_MagmaHitPlayer( other, origin, dir, humanoid );
                break;
            case CLASS_REBORN:
            case CLASS_KYLE:
            case CLASS_ATST:                // technically droid...
            case CLASS_BARTENDER:
            case CLASS_BESPIN_COP:
            case CLASS_COMMANDO:
            case CLASS_DESANN:
            case CLASS_FISH:
            case CLASS_FLIER2:
            case CLASS_GALAK:
            case CLASS_GLIDER:
            case CLASS_GONK:
            case CLASS_GRAN:
            case CLASS_HOWLER:
            case CLASS_RANCOR:
            case CLASS_SAND_CREATURE:
            case CLASS_WAMPA:
            case CLASS_IMPERIAL:
            case CLASS_IMPWORKER:
            case CLASS_INTERROGATOR:
            case CLASS_JAN:
            case CLASS_JEDI:
            case CLASS_LANDO:
            case CLASS_LIZARD:
            case CLASS_LUKE:
            case CLASS_MARK1:
            case CLASS_MARK2:
            case CLASS_GALAKMECH:
            case CLASS_MINEMONSTER:
            case CLASS_MONMOTHA:
            case CLASS_MORGANKATARN:
            case CLASS_MOUSE:
            case CLASS_MURJJ:
            case CLASS_PRISONER:
            case CLASS_PROBE:
            case CLASS_PROTOCOL:
            case CLASS_R2D2:
            case CLASS_R5D2:
            case CLASS_REBEL:
            case CLASS_REELO:
            case CLASS_REMOTE:
            case CLASS_RODIAN:
            case CLASS_SEEKER:
            case CLASS_SENTRY:
            case CLASS_SHADOWTROOPER:
            case CLASS_SABOTEUR:
            case CLASS_STORMTROOPER:
            case CLASS_SWAMP:
            case CLASS_SWAMPTROOPER:
            case CLASS_NOGHRI:
            case CLASS_TAVION:
            case CLASS_ALORA:
            case CLASS_TRANDOSHAN:
            case CLASS_UGNAUGHT:
            case CLASS_JAWA:
            case CLASS_WEEQUAY:
            case CLASS_TUSKEN:
            case CLASS_BOBAFETT:
            case CLASS_ROCKETTROOPER:
            case CLASS_SABER_DROID:
            case CLASS_ASSASSIN_DROID:
            case CLASS_PLAYER:
            case CLASS_VEHICLE:
            FX_BlasterWeaponHitPlayer( other, origin, dir, humanoid );
            break;
        default:
            break;
            }
        }
        break;
    case WP_BOWCASTER:
        FX_BowcasterHitPlayer( origin, dir, humanoid );
        break;

Now the only thing missing is the issue of deflected projectile by sabers. they turn on blaster default projectiles also for magma and warm projectiles.

 

if there is a possibility to make the same thing also for weaponmodel (so every class can have his custom blaster rifle model) this will open immense possibilities for SP modding because every weapon can got 64 class variances, every new weapon is used by a different class.

the only last problem should be if player catch the weapon, the weaponmodel of player change into weaponmodel of the enemy weapon stolen also class player need to change in that mode. in that case.

well in that case... wellcome SWG gameplay on JKA D:

but that's is over of my mod purpose, i told and i share this edit if someone wanna use this SP code as base for making a huge expansion coding mod for add dozens of weapons  on SP with custom effect without the necessity to create new weapons into the code. basically blaster_rifle become a category for 64 possible blaster_rifle weapons, like @@eezstreet suggest to me.

 

@@Langerd you are making a magical mod, maybe you are interessed on this code if you want some enemy bosses shoot with different efx and dmg by default weapons ;)

Posted

I only have time to skim this topic, but maybe not use a non POD data type (roll your own? Memory management is certainly a trial by fire) as replacement for vector. Problem is that vector is template type. But if you write your own then you won't have to worry about it. Use a macro instead of a template?

I never really intended my post to be taken super literally though. It was mostly just pseudocode and ramblings :s apologies if that wasn't clear.

 

Also please refrain from tagging lots of people in your posts, and/or tagging every post.

 

As for reflecting the missiles, I believe the code is handled somewhere in g_missiles.c (pp).

 

(I will try and hold back the urge to write some overengineered thought on this.)

Asgarath83 likes this
Posted

Okay, sorry for my massive tagging. i wanna simply searching valid suggest by the people, nothing more. :)

it's not a pity temptative of take attemption of others. i am not a child ;)

i am sorry if i take too much seriously your suggest. but your words and the ensiform reply about the reading better the

rest of the code was illuminating because i deeping dive the code syntaxis about if and else and switch case in various part of code and

yersterday i figured how to set the customization of effects that was my target to release.

i share my code edit because i was asking suggest about some technicall error i was doing and because i wanna learning almost a lot of coding, the little sufficient for not be every noious as a mosquito to asking helps every time to the coders for any thing.

also, i share because i think this code about changing efx of weapons by CLASS of user can get big potentially for future mods and i wanna share with peoples that read the thread. maybe will be useful for someone. :)

thanks for suggest about the deflecting of projectile. i will check g_missile.cpp ASAP. :D

Posted

You welcome man. :)

 

Bryar pistol custom class efx ended. now it's a smoking gun XD shadowtrooper can use for shoots little black holes D: 

little weapon, but deadly. lol :D

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...