-
Posts
237 -
Joined
-
Last visited
Content Type
Profiles
News Articles
Tutorials
Forums
Downloads
Everything posted by JediBantha
-
Ep. 1, because of the game that followed... There was just so much in that game that could've been in the movie.
-
I don't think it had anything at all to do with the type of computer you use, but rather a bad "kyle.npc" file in one of the mods you had; You can search the pk3 files by using WinRar, and looking in the "ext_data/npcs" directory for the file I mentioned earlier.
-
I may have mis-worded the description of my problem when I said 'marked' ...
-
Stasis would probably also require pieces of both the "ForceLightningShoot" and "ForceTelepathy" codes, (Lightning's radius damage, and MindTrick's distract effect, where you only hit a floor/wall with Mind Trick) for a more coordinated use of the power's freeze effect at levels 3 and above. As for Destruction... From what I gathered from switching labels around in it's missile code, I know that it has alot to do with the line "VectorCopy( muzzle, start );" . The problem I have now is whether I should edit either "muzzle" or "start", or just add a specific label to make it actually fire straight at all times, and not mark a surface with Saber swings.
-
From Concussion to Destruction (Help)
JediBantha replied to JediBantha's topic in Coding and Scripts
Here's what I'm trying to do: I took the code for wp_concussion's primary fire and just pasted it into wp_saber as ForceDestruction, and I've never done a weapon-force conversion before. So, take WP_ATST_MAIN for example; When you type "give weapon_atst_main" in the console, you're able to fire the weapon no problem, but it has no weapon MODEL, as it was designed for the AT-ST model itself. How would I convert that into a Force power without it randomly spewing shots all over the map, instead of firing precisely in the direction that I'm facing, and without having to use Mouse1 to "mark" the target? -
From Concussion to Destruction (Help)
JediBantha replied to JediBantha's topic in Coding and Scripts
Well, basically what I'm doing is trying to fire a sort of "Concussion" round from the player's left hand, as you would do with level 2 Force Lightning. Problem is, when I try to "fire" it off, I get the following results: (In-Game results) #1: Never plays the FX for the thrown projectile (Invisible shot) #2: Never fires in the direction I'm facing #3: Never plays the FX for the explosion, just the damage and the radius (Compiler results) 2>..\..\..\code\game\wp_saber.cpp(13615): warning C4101: 'forward' : unreferenced local variable2>..\..\..\code\game\wp_saber.cpp(13615): warning C4101: 'end' : unreferenced local variable2>..\..\..\code\game\wp_saber.cpp(13704): warning C4101: 'forward' : unreferenced local variable2>..\..\..\code\game\wp_saber.cpp(13704): warning C4101: 'end' : unreferenced local variable2>..\..\..\code\game\wp_saber.cpp(13703): warning C4101: 'start' : unreferenced local variable As for what everyone else wants... I'm not worried about it; They can take the final build of the code and change it about as they please. -
From Concussion to Destruction (Help)
JediBantha replied to JediBantha's topic in Coding and Scripts
Well I don't exactly know how to do it myself, seeing as this is from wp_concussion instead of wp_saber; It tends to give me error messages whenever I just paste the Conc Rilfe's code into wp_saber, as it's a weapon code. [EDIT]: @@eezstreet : Pay attention at 2:45 -
From Concussion to Destruction (Help)
JediBantha replied to JediBantha's topic in Coding and Scripts
void ForceDestruction( gentity_t *ent ) {//a fast rocket-like projectile vec3_t start; vec3_t end, forward; trace_t tr; gentity_t *traceEnt; traceEnt = &g_entities[tr.entityNum]; int damage = forceDestructionDamage[ent->client->ps.forcePowerLevel[FP_DESTRUCTION]]; int radius = forceDestructionRadius[ent->client->ps.forcePowerLevel[FP_DESTRUCTION]]; float vel = 2300; VectorCopy( ent->client->renderInfo.handLPoint, start ); WP_TraceSetStart( ent, start, vec3_origin, vec3_origin );//make sure our start point isn't on the other side of a wall gentity_t *missile = CreateMissile( start, forwardVec, vel, 10000, ent, qfalse ); missile->classname = "destruct_proj"; missile->mass = 10; // Make it easier to hit things VectorSet( missile->maxs, ROCKET_SIZE, ROCKET_SIZE, ROCKET_SIZE ); VectorScale( missile->maxs, -1, missile->mins ); missile->damage = damage; missile->dflags = DAMAGE_EXTRA_KNOCKBACK; missile->methodOfDeath = MOD_FORCE_DESTRUCTION; missile->splashMethodOfDeath = MOD_FORCE_DESTRUCTION; missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER; missile->splashDamage = damage = floor((float)damage * 0.5f); missile->splashRadius = radius; // we don't want it to ever bounce missile->bounceCount = 0; int modPowerLevel = -1; if (traceEnt->client) { modPowerLevel = WP_AbsorbConversion(traceEnt, traceEnt->client->ps.forcePowerLevel[FP_ABSORB], ent, FP_DESTRUCTION, ent->client->ps.forcePowerLevel[FP_DESTRUCTION], 1); } if (modPowerLevel != -1) { if ( !modPowerLevel ) { damage = 0; } else if ( modPowerLevel == 1 ) { damage = floor((float)damage/4.0f); } else if ( modPowerLevel == 2 ) { damage = floor((float)damage/2.0f); } else if ( modPowerLevel == 3 ) { damage = floor((float)damage/1.0f); } else if ( modPowerLevel == 4 ) { damage = floor((float)damage/0.5f); } else if ( modPowerLevel == 5 ) { damage = floor((float)damage/0.25f); } else if ( modPowerLevel == 6 ) { damage = floor((float)damage/0.12f); } else if ( modPowerLevel == 7 ) { damage = floor((float)damage/0.06f); } else if ( modPowerLevel == 8 ) { damage = floor((float)damage/0.03f); } else if ( modPowerLevel > 8 ) { damage = floor((float)damage/0.01f); } } } void ForceDestructionShoot( gentity_t *self ) {//a fast rocket-like projectile vec3_t start; vec3_t end, forward; trace_t tr; gentity_t *traceEnt; traceEnt = &g_entities[tr.entityNum]; if ( self->client->ps.forcePowerLevel[FP_DESTRUCTION] <= FORCE_LEVEL_2 && self->client->ps.forcePower < 80 || self->client->ps.forcePowerLevel[FP_DESTRUCTION] > FORCE_LEVEL_2 && self->client->ps.forcePower < 40 || !WP_ForcePowerUsable( self, FP_DESTRUCTION, 0 ) ) { return; } if ( self->client->ps.forcePowerLevel[FP_DESTRUCTION] <= FORCE_LEVEL_2 ) { WP_ForcePowerStart( self, FP_DESTRUCTION, 80 ); NPC_SetAnim( self, SETANIM_TORSO, BOTH_FORCEPUSH, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_RESTART|SETANIM_FLAG_HOLD ); G_SoundOnEnt( self, CHAN_BODY, "sound/weapons/force/forcedestruct_01.wav" ); ForceDestruction( self ); } if ( self->client->ps.forcePowerLevel[FP_DESTRUCTION] > FORCE_LEVEL_2 ) { WP_ForcePowerStart( self, FP_DESTRUCTION, 40 ); NPC_SetAnim( self, SETANIM_TORSO, BOTH_FORCEPUSH, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_RESTART|SETANIM_FLAG_HOLD ); G_SoundOnEnt( self, CHAN_BODY, "sound/weapons/force/forcedestruct_01.wav" ); ForceDestruction( self ); } if (self->client->ps.forcePowersActive & (1 << FP_PROTECT) ) { WP_ForcePowerStop( self, FP_PROTECT ); } if (self->client->ps.forcePowersActive & (1 << FP_ABSORB) ) { WP_ForcePowerStop( self, FP_ABSORB ); } self->client->ps.weaponTime = 1000; } This is all I have so far. I probably won't be able to finish this due to my looking for a career at the moment. BTW @@eezstreet , there's nothing in the tutorial that helps me translate the concussion rifle to an actual Force power. I've scrolled through it once or twice before starting on this. -
In the SWBF2 campaign, it said they stopped using clones altogether after raiding the cloning labs on Kamino, so that's probably why.
-
"Die, rebel!"
-
Need a character to base my new Force powers on if I'm going to make them... So yeah, which character would best fit as an endgame boss in the timeline Jedi Academy is set in, or after?
-
Using Force Destruction in Jedi Knight: Dark Forces 2 was like making a grenade out of thin air, and then throwing it. Also, the method you described would only affect objects that the Lightsaber touches when you attack, which would only be effective as a "Saber Sling" from The Force Unleashed.
-
@ A combination of the three would be so much win...
-
At the moment, I'm working on Destruction. Problem is, I have no idea at all how to translate "wp_concussion.cpp" into "wp_saber.cpp" . As of right now, the only time it "does" work, is when I click Mouse1 in a certain spot on the map, and npcs will indeed try to push it back, but it's like the Disruptor Rifle's firing function: Once you fire, there's no stopping it. Even when it "explodes" on a surface, it never plays the missile's FX, or the explosion's FX either; It just damages whatever is within the blast radius of the spot I clicked on.
-
From Concussion to Destruction (Help)
JediBantha replied to JediBantha's topic in Coding and Scripts
I can't seem to make it fire in the direction that I'm facing, or make it play it's actual missile FX, instead of the FX for the flechette rifle's main rounds. -
I'm having second thoughts about Stasis... Feel like I should put in Valor instead, but I dunno.
-
ShroomDuck been doin' Shrooms on a Shroom, Shroomin' on Rainbow Road. (insert .gif)
-
From Concussion to Destruction (Help)
JediBantha replied to JediBantha's topic in Coding and Scripts
This is SP, just so you know... At the moment, I'm having trouble with making it actually fire off a projectile. -
Like the topic suggests, I'm trying to convert the Concussion Rifle into Force Destruction. For those of you that haven't played Dark Forces 2, Force Destruction is your own Force-fueled grenade, courtesy of the Dark Side. static void WP_FireConcussionAlt( gentity_t *ent ) {//a rail-gun-like beam int damage = weaponData[WP_CONCUSSION].altDamage, skip, traces = DISRUPTOR_ALT_TRACES; qboolean render_impact = qtrue; vec3_t start, end; vec3_t muzzle2, spot, dir; trace_t tr; gentity_t *traceEnt, *tent; float dist, shotDist, shotRange = 8192; qboolean hitDodged = qfalse; if (ent->s.number >= MAX_CLIENTS) { vec3_t angles; vectoangles(forwardVec, angles); angles[PITCH] += ( crandom() * (CONC_NPC_SPREAD+(6-ent->NPC->currentAim)*0.25f));//was 0.5f angles[YAW] += ( crandom() * (CONC_NPC_SPREAD+(6-ent->NPC->currentAim)*0.25f));//was 0.5f AngleVectors(angles, forwardVec, vrightVec, up); } //Shove us backwards for half a second VectorMA( ent->client->ps.velocity, -200, forwardVec, ent->client->ps.velocity ); ent->client->ps.groundEntityNum = ENTITYNUM_NONE; if ( (ent->client->ps.pm_flags&PMF_DUCKED) ) {//hunkered down ent->client->ps.pm_time = 100; } else { ent->client->ps.pm_time = 250; } ent->client->ps.pm_flags |= PMF_TIME_KNOCKBACK|PMF_TIME_NOFRICTION; //FIXME: only if on ground? So no "rocket jump"? Or: (see next FIXME) //FIXME: instead, set a forced ucmd backmove instead of this sliding VectorCopy( muzzle, muzzle2 ); // making a backup copy // The trace start will originate at the eye so we can ensure that it hits the crosshair. if ( ent->NPC ) { switch ( g_spskill->integer ) { case 0: damage = CONC_ALT_NPC_DAMAGE_EASY; break; case 1: damage = CONC_ALT_NPC_DAMAGE_MEDIUM; break; case 2: default: damage = CONC_ALT_NPC_DAMAGE_HARD; break; } } VectorCopy( muzzle, start ); WP_TraceSetStart( ent, start, vec3_origin, vec3_origin ); skip = ent->s.number; // if ( ent->client && ent->client->ps.powerups[PW_WEAPON_OVERCHARGE] > 0 && ent->client->ps.powerups[PW_WEAPON_OVERCHARGE] > cg.time ) // { // // in overcharge mode, so doing double damage // damage *= 2; // } //Make it a little easier to hit guys at long range vec3_t shot_mins, shot_maxs; VectorSet( shot_mins, -1, -1, -1 ); VectorSet( shot_maxs, 1, 1, 1 ); for ( int i = 0; i < traces; i++ ) { VectorMA( start, shotRange, forwardVec, end ); //NOTE: if you want to be able to hit guys in emplaced guns, use "G2_COLLIDE, 10" instead of "G2_RETURNONHIT, 0" //alternately, if you end up hitting an emplaced_gun that has a sitter, just redo this one trace with the "G2_COLLIDE, 10" to see if we it the sitter //gi.trace( &tr, start, NULL, NULL, end, skip, MASK_SHOT, G2_COLLIDE, 10 );//G2_RETURNONHIT, 0 ); gi.trace( &tr, start, shot_mins, shot_maxs, end, skip, MASK_SHOT, G2_COLLIDE, 10 );//G2_RETURNONHIT, 0 ); if ( tr.surfaceFlags & SURF_NOIMPACT ) { render_impact = qfalse; } if ( tr.entityNum == ent->s.number ) { // should never happen, but basically we don't want to consider a hit to ourselves? // Get ready for an attempt to trace through another person VectorCopy( tr.endpos, muzzle2 ); VectorCopy( tr.endpos, start ); skip = tr.entityNum; #ifdef _DEBUG gi.Printf( "BAD! Concussion gun shot somehow traced back and hit the owner!\n" ); #endif continue; } // always render a shot beam, doing this the old way because I don't much feel like overriding the effect. //NOTE: let's just draw one beam at the end //tent = G_TempEntity( tr.endpos, EV_CONC_ALT_SHOT ); //tent->svFlags |= SVF_BROADCAST; //VectorCopy( muzzle2, tent->s.origin2 ); if ( tr.fraction >= 1.0f ) { // draw the beam but don't do anything else break; } traceEnt = &g_entities[tr.entityNum]; if ( traceEnt //&& traceEnt->NPC && ( traceEnt->s.weapon == WP_SABER || (traceEnt->client && (traceEnt->client->NPC_class == CLASS_BOBAFETT||traceEnt->client->NPC_class == CLASS_REBORN) ) ) ) {//FIXME: need a more reliable way to know we hit a jedi? hitDodged = Jedi_DodgeEvasion( traceEnt, ent, &tr, HL_NONE ); //acts like we didn't even hit him } if ( !hitDodged ) { if ( render_impact ) { if (( tr.entityNum < ENTITYNUM_WORLD && traceEnt->takedamage ) || !Q_stricmp( traceEnt->classname, "misc_model_breakable" ) || traceEnt->s.eType == ET_MOVER ) { // Create a simple impact type mark that doesn't last long in the world G_PlayEffect( G_EffectIndex( "concussion/alt_hit" ), tr.endpos, tr.plane.normal ); if ( traceEnt->client && LogAccuracyHit( traceEnt, ent )) {//NOTE: hitting multiple ents can still get you over 100% accuracy ent->client->ps.persistant[PERS_ACCURACY_HITS]++; } int hitLoc = G_GetHitLocFromTrace( &tr, MOD_CONC_ALT ); qboolean noKnockBack = (traceEnt->flags&FL_NO_KNOCKBACK);//will be set if they die, I want to know if it was on *before* they died if ( traceEnt && traceEnt->client && traceEnt->client->NPC_class == CLASS_GALAKMECH ) {//hehe G_Damage( traceEnt, ent, ent, forwardVec, tr.endpos, 10, DAMAGE_NO_KNOCKBACK|DAMAGE_NO_HIT_LOC, MOD_CONC_ALT, hitLoc ); break; } G_Damage( traceEnt, ent, ent, forwardVec, tr.endpos, damage, DAMAGE_NO_KNOCKBACK|DAMAGE_NO_HIT_LOC, MOD_CONC_ALT, hitLoc ); //do knockback and knockdown manually if ( traceEnt->client ) {//only if we hit a client vec3_t pushDir; VectorCopy( forwardVec, pushDir ); if ( pushDir[2] < 0.2f ) { pushDir[2] = 0.2f; }//hmm, re-normalize? nah... //if ( traceEnt->NPC || Q_irand(0,g_spskill->integer+1) ) { if ( !noKnockBack ) {//knock-backable G_Throw( traceEnt, pushDir, 200 ); if ( traceEnt->client->NPC_class == CLASS_ROCKETTROOPER ) { traceEnt->client->ps.pm_time = Q_irand( 1500, 3000 ); } } if ( traceEnt->health > 0 ) {//alive if ( G_HasKnockdownAnims( traceEnt ) ) {//knock-downable G_Knockdown( traceEnt, ent, pushDir, 400, qtrue ); } } } } if ( traceEnt->s.eType == ET_MOVER ) {//stop the traces on any mover break; } } else { // we only make this mark on things that can't break or move tent = G_TempEntity( tr.endpos, EV_CONC_ALT_MISS ); tent->svFlags |= SVF_BROADCAST; VectorCopy( tr.plane.normal, tent->pos1 ); break; // hit solid, but doesn't take damage, so stop the shot...we _could_ allow it to shoot through walls, might be cool? } } else // not rendering impact, must be a skybox or other similar thing? { break; // don't try anymore traces } } // Get ready for an attempt to trace through another person VectorCopy( tr.endpos, muzzle2 ); VectorCopy( tr.endpos, start ); skip = tr.entityNum; hitDodged = qfalse; } //just draw one beam all the way to the end tent = G_TempEntity( tr.endpos, EV_CONC_ALT_SHOT ); tent->svFlags |= SVF_BROADCAST; VectorCopy( muzzle, tent->s.origin2 ); // now go along the trail and make sight events VectorSubtract( tr.endpos, muzzle, dir ); shotDist = VectorNormalize( dir ); //FIXME: if shoot *really* close to someone, the alert could be way out of their FOV for ( dist = 0; dist < shotDist; dist += 64 ) { //FIXME: on a really long shot, this could make a LOT of alerts in one frame... VectorMA( muzzle, dist, dir, spot ); AddSightEvent( ent, spot, 256, AEL_DISCOVERED, 50 ); //FIXME: creates *way* too many effects, make it one effect somehow? G_PlayEffect( G_EffectIndex( "concussion/alt_ring" ), spot, forwardVec ); } //FIXME: spawn a temp ent that continuously spawns sight alerts here? And 1 sound alert to draw their attention? VectorMA( start, shotDist-4, forwardVec, spot ); AddSightEvent( ent, spot, 256, AEL_DISCOVERED, 50 ); G_PlayEffect( G_EffectIndex( "concussion/altmuzzle_flash" ), muzzle, forwardVec ); } static void WP_FireConcussion( gentity_t *ent ) {//a fast rocket-like projectile vec3_t start; int damage = weaponData[WP_CONCUSSION].damage; float vel = CONC_VELOCITY; if (ent->s.number >= MAX_CLIENTS) { vec3_t angles; vectoangles(forwardVec, angles); angles[PITCH] += ( crandom() * (CONC_NPC_SPREAD+(6-ent->NPC->currentAim)*0.25f));//was 0.5f angles[YAW] += ( crandom() * (CONC_NPC_SPREAD+(6-ent->NPC->currentAim)*0.25f));//was 0.5f AngleVectors(angles, forwardVec, vrightVec, up); } //hold us still for a bit ent->client->ps.pm_time = 300; ent->client->ps.pm_flags |= PMF_TIME_KNOCKBACK; //add viewkick if ( ent->s.number < MAX_CLIENTS//player only && !cg.renderingThirdPerson )//gives an advantage to being in 3rd person, but would look silly otherwise {//kick the view back cg.kick_angles[PITCH] = Q_flrand( -10, -15 ); cg.kick_time = level.time; } VectorCopy( muzzle, start ); WP_TraceSetStart( ent, start, vec3_origin, vec3_origin );//make sure our start point isn't on the other side of a wall gentity_t *missile = CreateMissile( start, forwardVec, vel, 10000, ent, qfalse ); missile->classname = "conc_proj"; missile->s.weapon = WP_CONCUSSION; missile->mass = 10; // Do the damages if ( ent->s.number != 0 ) { if ( g_spskill->integer == 0 ) { damage = CONC_NPC_DAMAGE_EASY; } else if ( g_spskill->integer == 1 ) { damage = CONC_NPC_DAMAGE_NORMAL; } else { damage = CONC_NPC_DAMAGE_HARD; } } // Make it easier to hit things VectorSet( missile->maxs, ROCKET_SIZE, ROCKET_SIZE, ROCKET_SIZE ); VectorScale( missile->maxs, -1, missile->mins ); missile->damage = damage; missile->dflags = DAMAGE_EXTRA_KNOCKBACK; missile->methodOfDeath = MOD_CONC; missile->splashMethodOfDeath = MOD_CONC; missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER; missile->splashDamage = weaponData[WP_CONCUSSION].splashDamage; missile->splashRadius = weaponData[WP_CONCUSSION].splashRadius; // we don't want it to ever bounce missile->bounceCount = 0; } void WP_Concussion( gentity_t *ent, qboolean alt_fire ) { if(alt_fire) { WP_FireConcussionAlt(ent); } else { WP_FireConcussion(ent); } }My question is (as stated above), how would I convert this into a Force power?
-
- 18 comments
-
- NPC Support
- Bot Support
-
(and 5 more)
Tagged with:
-
Now that I've finished with my cores, I want to move onto light/dark powers, but have no idea how to actually make them work. (EDIT): I will update this as I progress. Deadly Sight (Solved): void ForceDeadlySightInit( gentity_t *self ) { trace_t tr; vec3_t end, forward; gentity_t *traceEnt; if ( self->health <= 0 ) { return; } if ( !self->s.number && cg.zoomMode ) {//can't force lightning when zoomed in return; } AngleVectors( self->client->ps.viewangles, forward, NULL, NULL ); VectorNormalize( forward ); //FIXME: if lightning hits water, do water-only-flagged radius damage from that point if ( self->client->ps.forcePowerLevel[FP_DEADLYSIGHT] > FORCE_LEVEL_0 ) {//arc vec3_t center, mins, maxs, dir, ent_org, size, v; float radius = 800, dot, dist; gentity_t *entityList[MAX_GENTITIES]; int e, numListedEntities, i; VectorCopy( self->currentOrigin, center ); for ( i = 0 ; i < 3 ; i++ ) { mins[i] = center[i] - radius; maxs[i] = center[i] + radius; } numListedEntities = gi.EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); for ( e = 0 ; e < numListedEntities ; e++ ) { traceEnt = entityList[e]; if ( !traceEnt ) continue; if ( traceEnt == self ) continue; if ( !traceEnt->inuse ) continue; if ( !traceEnt->takedamage ) continue; if ( traceEnt->health <= 0 )//no torturing corpses continue; if ( !traceEnt->client ) continue; if (self->enemy != traceEnt//not my enemy && OnSameTeam(self, traceEnt))//on my team continue; //this is all to see if we need to start a saber attack, if it's in flight, this doesn't matter // find the distance from the edge of the bounding box for ( i = 0 ; i < 3 ; i++ ) { if ( center[i] < traceEnt->absmin[i] ) { v[i] = traceEnt->absmin[i] - center[i]; } else if ( center[i] > traceEnt->absmax[i] ) { v[i] = center[i] - traceEnt->absmax[i]; } else { v[i] = 0; } } VectorSubtract( traceEnt->absmax, traceEnt->absmin, size ); VectorMA( traceEnt->absmin, 0.5, size, ent_org ); //see if they're in front of me //must be within the forward cone VectorSubtract( ent_org, center, dir ); VectorNormalize( dir ); if ( (dot = DotProduct( dir, forward )) < 0.5 ) continue; //must be close enough dist = VectorLength( v ); if ( dist >= radius ) { continue; } //in PVS? if ( !traceEnt->bmodel && !gi.inPVS( ent_org, self->client->renderInfo.eyePoint ) ) {//must be in PVS continue; } //Now check and see if we can actually hit it gi.trace( &tr, self->client->renderInfo.eyePoint, vec3_origin, vec3_origin, ent_org, self->s.number, MASK_SHOT, (EG2_Collision)0, 0 ); if ( tr.fraction < 1.0f && tr.entityNum != traceEnt->s.number ) {//must have clear LOS continue; } // ok, we are within the radius, add us to the incoming list //FIXME: maybe add up the ents and do more damage the less ents there are // as if we're spreading out the damage? ForceDeadlySightDamage( self, traceEnt, dir, dist, dot, ent_org ); } } else {//trace-line int ignore = self->s.number; int traces = 0; vec3_t start; VectorCopy( self->client->renderInfo.eyePoint, start ); VectorMA( self->client->renderInfo.eyePoint, 2048, forward, end ); traceEnt = &g_entities[tr.entityNum]; ForceDeadlySightDamage( self, traceEnt, forward, 0, 0, tr.endpos ); } } void ForceDeadlySightDamage( gentity_t *self, gentity_t *traceEnt, vec3_t dir, float dist, float dot, vec3_t impactPoint ) { if( traceEnt->NPC && traceEnt->NPC->scriptFlags & SCF_NO_FORCE ) { return; } if ( traceEnt && traceEnt->takedamage ) { if ( !traceEnt->client || traceEnt->client->playerTeam != self->client->playerTeam || self->enemy == traceEnt || traceEnt->enemy == self ) {//an enemy or object int dmg; int dflags = (DAMAGE_NO_ARMOR|DAMAGE_NO_KNOCKBACK|DAMAGE_NO_HIT_LOC); //FIXME: check for client using FP_ABSORB if ( self->client->ps.forcePowerLevel[FP_DEADLYSIGHT] == FORCE_LEVEL_1 ) {//more damage if closer and more in front if ( dist > 100 ) { dmg = 0; } if ( dot < 0.9f ) { dmg = 0; } else { dmg = 1; } if (self->client->ps.forcePowersActive & (1 << FP_RAGE) ) { dmg *= 2; } } if ( self->client->ps.forcePowerLevel[FP_DEADLYSIGHT] == FORCE_LEVEL_2 ) {//more damage if closer and more in front if ( dist > 200 ) { dmg = 0; } if ( dot < 0.7f ) { dmg = 0; } else { dmg = 1; } if ( self->client->NPC_class == CLASS_REBORN && self->client->ps.weapon == WP_NONE ) {//Cultist: looks fancy, but does less damage } else { if ( dist < 100 ) { dmg += 1; } if ( dot > 0.9f ) { dmg += 1; } } if (self->client->ps.forcePowersActive & (1 << FP_RAGE) ) { dmg *= 2; } } if ( self->client->ps.forcePowerLevel[FP_DEADLYSIGHT] == FORCE_LEVEL_3 ) {//more damage if closer and more in front if ( dist > 400 ) { dmg = 0; } if ( dot < 0.5f ) { dmg = 0; } else { dmg = 1; } if ( self->client->NPC_class == CLASS_REBORN && self->client->ps.weapon == WP_NONE ) {//Cultist: looks fancy, but does less damage } else { if ( dist < 200 ) { dmg += 1; if ( dist < 100 ) { dmg += 1; } } if ( dot > 0.7f ) { dmg += 1; if ( dot > 0.9f ) { dmg += 1; } } } if (self->client->ps.forcePowersActive & (1 << FP_RAGE) ) { dmg *= 2; } } if ( self->client->ps.forcePowerLevel[FP_DEADLYSIGHT] == FORCE_LEVEL_4 ) {//more damage if closer and more in front if ( dist > 800 ) { dmg = 0; } if ( dot < 0.3f ) { dmg = 0; } else { dmg = 1; } if ( self->client->NPC_class == CLASS_REBORN && self->client->ps.weapon == WP_NONE ) {//Cultist: looks fancy, but does less damage } else { if ( dist < 400 ) { dmg += 1; if ( dist < 200 ) { dmg += 1; if ( dist < 100 ) { dmg += 1; } } } if ( dot > 0.5f ) { dmg += 1; if ( dot > 0.7f ) { dmg += 1; if ( dot > 0.9f ) { dmg += 1; } } } } if (self->client->ps.forcePowersActive & (1 << FP_RAGE) ) { dmg *= 2; } } if ( self->client->ps.forcePowerLevel[FP_DEADLYSIGHT] == FORCE_LEVEL_5 ) {//more damage if closer and more in front if ( dist > 800 ) { dmg = 0; } else { dmg = 2; } if ( self->client->NPC_class == CLASS_REBORN && self->client->ps.weapon == WP_NONE ) {//Cultist: looks fancy, but does less damage } else { if ( dist < 800 ) { dmg += 1; if ( dist < 400 ) { dmg += 1; if ( dist < 200 ) { dmg += 1; if ( dist < 100 ) { dmg += 1; } } } } if ( dot > 0.3f ) { dmg += 1; if ( dot > 0.5f ) { dmg += 1; if ( dot > 0.7f ) { dmg += 1; if ( dot > 0.9f ) { dmg += 1; } } } } } if (self->client->ps.forcePowersActive & (1 << FP_RAGE) ) { dmg *= 2; } } else { dmg = Q_irand( 1, 3 );//*self->client->ps.forcePowerLevel[FP_DEADLYSIGHT]; } if ( traceEnt->client && traceEnt->health > 0 && traceEnt->NPC && (traceEnt->NPC->aiFlags&NPCAI_BOSS_CHARACTER) ) {//Luke, Desann Tavion and Kyle can shield themselves from the attack //FIXME: shield effect or something? //FIXME: don't interrupt big anims with this! Jedi_PlayDeflectSound( traceEnt ); dmg = 0; } else if ( traceEnt->s.weapon == WP_SABER ) {//saber can block lightning if ( traceEnt->client //a client && !traceEnt->client->ps.saberInFlight//saber in hand && ( traceEnt->client->ps.saberMove == LS_READY || PM_SaberInParry( traceEnt->client->ps.saberMove ) || PM_SaberInReturn( traceEnt->client->ps.saberMove ) )//not attacking with saber && InFOV( self->currentOrigin, traceEnt->currentOrigin, traceEnt->client->ps.viewangles, 20, 35 ) //I'm in front of them && !PM_InKnockDown( &traceEnt->client->ps ) //they're not in a knockdown && !PM_SuperBreakLoseAnim( traceEnt->client->ps.torsoAnim ) && !PM_SuperBreakWinAnim( traceEnt->client->ps.torsoAnim ) && !PM_SaberInSpecialAttack( traceEnt->client->ps.torsoAnim ) && !PM_InSpecialJump( traceEnt->client->ps.torsoAnim ) && (!traceEnt->s.number||(traceEnt->NPC&&traceEnt->NPC->rank>=RANK_LT_COMM)) )//the player or a tough jedi/reborn { if ( Q_irand( 0, traceEnt->client->ps.forcePowerLevel[FP_SABER_DEFENSE]*3 ) > 0 )//more of a chance of defending if saber defense is high { dmg = 0; } if ( (traceEnt->client->ps.forcePowersActive&(1<<FP_ABSORB)) && traceEnt->client->ps.forcePowerLevel[FP_ABSORB] > FORCE_LEVEL_2 ) {//no parry, just absorb } } else if ( Q_irand( 0, 1 ) ) {//jedi less likely to be damaged dmg = 0; } else { dmg = 1; } } if ( traceEnt && traceEnt->client && traceEnt->client->ps.powerups[PW_GALAK_SHIELD] ) { //has shield up dmg = 0; } int modPowerLevel = -1; if (traceEnt->client) { modPowerLevel = WP_AbsorbConversion(traceEnt, traceEnt->client->ps.forcePowerLevel[FP_ABSORB], self, FP_DEADLYSIGHT, self->client->ps.forcePowerLevel[FP_DEADLYSIGHT], 1); } if (modPowerLevel != -1) { if ( !modPowerLevel ) { dmg = 0; } else if ( modPowerLevel == 1 ) { dmg = floor((float)dmg/4.0f); } else if ( modPowerLevel == 2 ) { dmg = floor((float)dmg/2.0f); } else if ( modPowerLevel == 3 ) { dmg = floor((float)dmg/1.0f); } else if ( modPowerLevel == 4 ) { dmg = floor((float)dmg/0.5f); } else if ( modPowerLevel == 5 ) { dmg = floor((float)dmg/0.25f); } else if ( modPowerLevel > 5 ) { dmg = floor((float)dmg/0.12f); } } //FIXME: if ForceDrain, sap force power and add health to self, use different sound & effects if ( dmg ) { G_Damage( traceEnt, self, self, dir, impactPoint, dmg, dflags, MOD_FORCE_DEADLYSIGHT ); } } } } void ForceDeadlySight( gentity_t *self ) { if ( self->health <= 0 ) { return; } if (self->client->ps.forceAllowDeactivateTime < level.time && (self->client->ps.forcePowersActive & (1 << FP_DEADLYSIGHT)) ) { WP_ForcePowerStop( self, FP_DEADLYSIGHT ); return; } if ( !WP_ForcePowerUsable( self, FP_DEADLYSIGHT, 0 ) ) { return; } if (self->client->ps.forcePowersActive & (1 << FP_PROTECT) ) { WP_ForcePowerStop( self, FP_PROTECT ); } if (self->client->ps.forcePowersActive & (1 << FP_ABSORB) ) { WP_ForcePowerStop( self, FP_ABSORB ); } if (self->client->ps.forcePowersActive & (1 << FP_SEE) ) { WP_ForcePowerStop( self, FP_SEE ); } if ( self->client->ps.forcePowerLevel[FP_DEADLYSIGHT] < FORCE_LEVEL_3 )//optional { forcePowerNeeded[FP_DEADLYSIGHT] = 50; } if ( self->client->ps.forcePowerLevel[FP_DEADLYSIGHT] >= FORCE_LEVEL_3 ] )//optional { forcePowerNeeded[FP_DEADLYSIGHT] = 25; } WP_DebounceForceDeactivateTime( self ); WP_ForcePowerStart( self, FP_DEADLYSIGHT, 0 ); G_SoundOnEnt( self, CHAN_ITEM, "sound/weapons/force/dsight.wav" ); }</code> Under void WP_ForcePowerStart( gentity_t *self, forcePowers_t forcePower, int overrideAmt ): <code>case FP_DEADLYSIGHT: switch ( self->client->ps.forcePowerLevel[FP_DEADLYSIGHT] ) { case FORCE_LEVEL_5: duration = 25000; break; case FORCE_LEVEL_4: duration = 20000; break; case FORCE_LEVEL_3: duration = 15000; break; case FORCE_LEVEL_2: duration = 10000; break; case FORCE_LEVEL_1: default: duration = 5000; break; } self->client->ps.forcePowersActive |= ( 1 << forcePower ); G_SoundOnEnt( self, CHAN_ITEM, "sound/weapons/force/dsight.wav" ); self->s.loopSound = G_SoundIndex( "sound/weapons/force/dsightloop.wav" ); break;</code> Under void WP_ForcePowerStop( gentity_t *self, forcePowers_t forcePower ): <code>case FP_DEADLYSIGHT: self->s.loopSound = 0; break; Under void WP_CheckForcedPowers( gentity_t *self, usercmd_t *ucmd ): case FP_DEADLYSIGHT: ForceDeadlySight( self ); break; bg_pmove.cpp: extern void ForceDeadlySight( gentity_t *self ); Under void PM_CheckForceUseButton( gentity_t *ent, usercmd_t *ucmd ): case FP_DEADLYSIGHT: ForceDeadlySight( ent ); break; cg_main.cpp: int showPowers[MAX_SHOWPOWERS] = { FP_ABSORB, FP_HEAL, FP_PROTECT, FP_TELEPATHY, FP_SPEED, FP_PUSH, FP_PULL, FP_SEE, FP_DRAIN, FP_LIGHTNING, FP_RAGE, FP_GRIP, FP_DEADLYSIGHT, }; const char *showPowersName[MAX_SHOWPOWERS] = { "SP_INGAME_ABSORB2", "SP_INGAME_HEAL2", "SP_INGAME_PROTECT2", "SP_INGAME_MINDTRICK2", "SP_INGAME_SPEED2", "SP_INGAME_PUSH2", "SP_INGAME_PULL2", "SP_INGAME_SEEING2", "SP_INGAME_DRAIN2", "SP_INGAME_LIGHTNING2", "SP_INGAME_DARK_RAGE2", "SP_INGAME_GRIP2", "SP_INGAME_DEADLYSIGHT2", }; // Keep these with groups light side, core, and dark side int showDataPadPowers[MAX_DPSHOWPOWERS] = { // Light side FP_ABSORB, FP_HEAL, FP_PROTECT, FP_TELEPATHY, // Core Powers FP_LEVITATION, FP_SPEED, FP_PUSH, FP_PULL, FP_SABERTHROW, FP_SABER_DEFENSE, FP_SABER_OFFENSE, FP_SEE, //Dark Side FP_DRAIN, FP_LIGHTNING, FP_RAGE, FP_GRIP, FP_DEADLYSIGHT, }; Under CG_Init( int serverCommandSequence ) {: const char *force_icon_files[NUM_FORCE_POWERS] = {//icons matching enums forcePowers_t "gfx/mp/f_icon_lt_heal", //FP_HEAL, "gfx/mp/f_icon_levitation", //FP_LEVITATION, "gfx/mp/f_icon_speed", //FP_SPEED, "gfx/mp/f_icon_push", //FP_PUSH, "gfx/mp/f_icon_pull", //FP_PULL, "gfx/mp/f_icon_lt_telepathy", //FP_TELEPATHY, "gfx/mp/f_icon_dk_grip", //FP_GRIP, "gfx/mp/f_icon_dk_l1", //FP_LIGHTNING, "gfx/mp/f_icon_saber_throw", //FP_SABERTHROW "gfx/mp/f_icon_saber_defend", //FP_SABERDEFEND, "gfx/mp/f_icon_saber_attack", //FP_SABERATTACK, "gfx/mp/f_icon_dk_rage", //FP_RAGE, "gfx/mp/f_icon_lt_protect", //FP_PROTECT, "gfx/mp/f_icon_lt_absorb", //FP_ABSORB, "gfx/mp/f_icon_dk_drain", //FP_DRAIN, "gfx/mp/f_icon_sight", //FP_SEE, "gfx/mp/f_icon_dk_dsight", //FP_DEADLYSIGHT, }; q_shared.h: typedef enum { FP_FIRST = 0,//marker FP_HEAL = 0,//instant FP_LEVITATION,//hold/duration FP_SPEED,//duration FP_PUSH,//hold/duration FP_PULL,//hold/duration FP_TELEPATHY,//instant FP_GRIP,//hold/duration FP_LIGHTNING,//hold/duration FP_SABERTHROW, FP_SABER_DEFENSE, FP_SABER_OFFENSE, //new Jedi Academy powers FP_RAGE,//duration - speed, invincibility and extra damage for short period, drains your health and leaves you weak and slow afterwards. FP_PROTECT,//duration - protect against physical/energy (level 1 stops blaster/energy bolts, level 2 stops projectiles, level 3 protects against explosions) FP_ABSORB,//duration - protect against dark force powers (grip, lightning, drain - maybe push/pull, too?) FP_DRAIN,//hold/duration - drain force power for health FP_SEE,//duration - detect/see hidden enemies FP_DEADLYSIGHT, NUM_FORCE_POWERS } forcePowers_t; Destruction: I have no idea whatsoever how to code this into SP. Blind: I want to use the code for Mind Trick, except make it to where it hits multiple people and doesn't deactivate when you attack someone. Stasis: Like Grip, except I want it to hit multiple enemies at level 3.
-
Out of all the things I could learn, I'd say modeling since that's my weak point.
-
Force Grip (New Grip) and Force Choke (Old Grip)
JediBantha replied to JediBantha's topic in Coding and Scripts
I suppose you could grip multiple people if you hold down the "Use" button before gripping, like TFU1. EDIT: Btw, it's different from the SP Grip; different lines of coding. -
Force Grip (New Grip) and Force Choke (Old Grip)
JediBantha replied to JediBantha's topic in Coding and Scripts
What about the SP version of grip? -
Force Grip (New Grip) and Force Choke (Old Grip)
JediBantha replied to JediBantha's topic in Coding and Scripts
'Kay, now how do I make it so Grip can now lift objects?