JediBantha Posted January 12, 2018 Share Posted January 12, 2018 I must have tried at least a dozen times now, and the game keeps crashing whenever I mind-trick an NPC ForceTelepathy_ConfuseEnts void ForceTelepathy_ConfuseEnts(gentity_t* ent, vec3_t dir) { trace_t tr; gentity_t *self = &g_entities[0]; gentity_t *traceEnt; qboolean targetLive = qfalse; traceEnt = &g_entities[tr.entityNum]; if (traceEnt->NPC && traceEnt->NPC->scriptFlags & SCF_NO_FORCE) { return; } if (traceEnt && traceEnt->client) { switch (traceEnt->client->NPC_class) { case CLASS_GALAKMECH: case CLASS_ATST: case CLASS_PROBE: case CLASS_GONK: case CLASS_R2D2: case CLASS_R5D2: case CLASS_MARK1: case CLASS_MARK2: case CLASS_MOUSE: case CLASS_SEEKER: case CLASS_REMOTE: case CLASS_PROTOCOL: case CLASS_ASSASSIN_DROID: case CLASS_SABER_DROID: case CLASS_BOBAFETT: break; case CLASS_RANCOR: if (!(traceEnt->spawnflags & 1)) { targetLive = qtrue; } break; default: targetLive = qtrue; break; } } if (targetLive && traceEnt->NPC && traceEnt->health > 0) { team_t saveTeam; switch (traceEnt->client->NPC_class) { case CLASS_KYLE: case CLASS_LUKE: case CLASS_DESANN: NPC_Jedi_PlayConfusionSound(traceEnt); break; case CLASS_TAVION: if (!Q_stricmp("tavion", traceEnt->NPC_type)) { if (traceEnt->enemy) { G_ClearEnemy(traceEnt); } traceEnt->NPC->confusionTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]];//confused for about 10 seconds if (traceEnt->ghoul2.size() && traceEnt->headBolt != -1) {//FIXME: what if already playing effect? G_PlayEffect(G_EffectIndex("force/confusion"), traceEnt->playerModel, traceEnt->headBolt, traceEnt->s.number, traceEnt->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } NPC_PlayConfusionSound(traceEnt); } else { NPC_Jedi_PlayConfusionSound(traceEnt); } break; case CLASS_ALORA: if (traceEnt->client && traceEnt->health > 0 && traceEnt->NPC && (traceEnt->NPC->aiFlags&NPCAI_BOSS_CHARACTER)) { if (traceEnt->enemy) { NPC_Jedi_PlayConfusionSound(traceEnt); } } else { if (traceEnt->enemy) { G_ClearEnemy(traceEnt); } traceEnt->NPC->confusionTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]];//confused for about 10 seconds if (traceEnt->ghoul2.size() && traceEnt->headBolt != -1) {//FIXME: what if already playing effect? G_PlayEffect(G_EffectIndex("force/confusion"), traceEnt->playerModel, traceEnt->headBolt, traceEnt->s.number, traceEnt->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } NPC_PlayConfusionSound(traceEnt); } break; case CLASS_REBORN: case CLASS_SHADOWTROOPER: case CLASS_JEDI: if (traceEnt->enemy) { G_ClearEnemy(traceEnt); } traceEnt->NPC->confusionTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]];//confused for about 10 seconds if (traceEnt->ghoul2.size() && traceEnt->headBolt != -1) {//FIXME: what if already playing effect? G_PlayEffect(G_EffectIndex("force/confusion"), traceEnt->playerModel, traceEnt->headBolt, traceEnt->s.number, traceEnt->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } NPC_PlayConfusionSound(traceEnt); break; default: if (traceEnt->enemy) { G_ClearEnemy(traceEnt); } if (traceEnt->NPC) { //traceEnt->NPC->tempBehavior = BS_FOLLOW_LEADER; traceEnt->client->leader = self; } //FIXME: maybe pick an enemy right here? //FIXME: does nothing to TEAM_FREE and TEAM_NEUTRALs!!! saveTeam = traceEnt->client->enemyTeam; traceEnt->client->enemyTeam = traceEnt->client->playerTeam; traceEnt->client->playerTeam = saveTeam; //FIXME: need a *charmed* timer on this...? Or do TEAM_PLAYERS assume that "confusion" means they should switch to team_enemy when done? traceEnt->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]]; if (traceEnt->ghoul2.size() && traceEnt->headBolt != -1) {//FIXME: what if already playing effect? G_PlayEffect(G_EffectIndex("force/confusion"), traceEnt->playerModel, traceEnt->headBolt, traceEnt->s.number, traceEnt->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } break; } } } ForceTelepathyRadius void ForceTelepathyRadius( gentity_t *self) { trace_t tr; gentity_t *traceEnt; int numEnts; gentity_t* radiusEnts[128]; float radius; vec3_t mins, maxs; vec3_t dir; float dist; switch (self->client->ps.forcePowerLevel[FP_TELEPATHY]) { case FORCE_LEVEL_5: radius = 256; break; case FORCE_LEVEL_4: default: radius = 128; break; } traceEnt = &g_entities[tr.entityNum]; for (int i = 0; i < 3; i++) { mins[i] = traceEnt->currentOrigin[i] - radius; maxs[i] = traceEnt->currentOrigin[i] + radius; } numEnts = gi.EntitiesInBox(mins, maxs, radiusEnts, 128); for (int entIndex = 0; entIndex<numEnts; entIndex++) { // Only Clients //-------------- if (!radiusEnts[entIndex] || !radiusEnts[entIndex]->client) { continue; } // Do The Vector Distance Test //----------------------------- VectorSubtract(radiusEnts[entIndex]->currentOrigin, traceEnt->currentOrigin, dir); dist = VectorNormalize(dir); if (dist < radius) { ForceTelepathy_ConfuseEnts(radiusEnts[entIndex], dir); } } } Any help at this point would be greatly appreciated. Link to comment
Solution Asgarath83 Posted January 17, 2018 Solution Share Posted January 17, 2018 I must have tried at least a dozen times now, and the game keeps crashing whenever I mind-trick an NPC ForceTelepathy_ConfuseEnts void ForceTelepathy_ConfuseEnts(gentity_t* ent, vec3_t dir) { trace_t tr; gentity_t *self = &g_entities[0]; gentity_t *traceEnt; qboolean targetLive = qfalse; traceEnt = &g_entities[tr.entityNum]; if (traceEnt->NPC && traceEnt->NPC->scriptFlags & SCF_NO_FORCE) { return; } if (traceEnt && traceEnt->client) { switch (traceEnt->client->NPC_class) { case CLASS_GALAKMECH: case CLASS_ATST: case CLASS_PROBE: case CLASS_GONK: case CLASS_R2D2: case CLASS_R5D2: case CLASS_MARK1: case CLASS_MARK2: case CLASS_MOUSE: case CLASS_SEEKER: case CLASS_REMOTE: case CLASS_PROTOCOL: case CLASS_ASSASSIN_DROID: case CLASS_SABER_DROID: case CLASS_BOBAFETT: break; case CLASS_RANCOR: if (!(traceEnt->spawnflags & 1)) { targetLive = qtrue; } break; default: targetLive = qtrue; break; } } if (targetLive && traceEnt->NPC && traceEnt->health > 0) { team_t saveTeam; switch (traceEnt->client->NPC_class) { case CLASS_KYLE: case CLASS_LUKE: case CLASS_DESANN: NPC_Jedi_PlayConfusionSound(traceEnt); break; case CLASS_TAVION: if (!Q_stricmp("tavion", traceEnt->NPC_type)) { if (traceEnt->enemy) { G_ClearEnemy(traceEnt); } traceEnt->NPC->confusionTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]];//confused for about 10 seconds if (traceEnt->ghoul2.size() && traceEnt->headBolt != -1) {//FIXME: what if already playing effect? G_PlayEffect(G_EffectIndex("force/confusion"), traceEnt->playerModel, traceEnt->headBolt, traceEnt->s.number, traceEnt->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } NPC_PlayConfusionSound(traceEnt); } else { NPC_Jedi_PlayConfusionSound(traceEnt); } break; case CLASS_ALORA: if (traceEnt->client && traceEnt->health > 0 && traceEnt->NPC && (traceEnt->NPC->aiFlags&NPCAI_BOSS_CHARACTER)) { if (traceEnt->enemy) { NPC_Jedi_PlayConfusionSound(traceEnt); } } else { if (traceEnt->enemy) { G_ClearEnemy(traceEnt); } traceEnt->NPC->confusionTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]];//confused for about 10 seconds if (traceEnt->ghoul2.size() && traceEnt->headBolt != -1) {//FIXME: what if already playing effect? G_PlayEffect(G_EffectIndex("force/confusion"), traceEnt->playerModel, traceEnt->headBolt, traceEnt->s.number, traceEnt->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } NPC_PlayConfusionSound(traceEnt); } break; case CLASS_REBORN: case CLASS_SHADOWTROOPER: case CLASS_JEDI: if (traceEnt->enemy) { G_ClearEnemy(traceEnt); } traceEnt->NPC->confusionTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]];//confused for about 10 seconds if (traceEnt->ghoul2.size() && traceEnt->headBolt != -1) {//FIXME: what if already playing effect? G_PlayEffect(G_EffectIndex("force/confusion"), traceEnt->playerModel, traceEnt->headBolt, traceEnt->s.number, traceEnt->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } NPC_PlayConfusionSound(traceEnt); break; default: if (traceEnt->enemy) { G_ClearEnemy(traceEnt); } if (traceEnt->NPC) { //traceEnt->NPC->tempBehavior = BS_FOLLOW_LEADER; traceEnt->client->leader = self; } //FIXME: maybe pick an enemy right here? //FIXME: does nothing to TEAM_FREE and TEAM_NEUTRALs!!! saveTeam = traceEnt->client->enemyTeam; traceEnt->client->enemyTeam = traceEnt->client->playerTeam; traceEnt->client->playerTeam = saveTeam; //FIXME: need a *charmed* timer on this...? Or do TEAM_PLAYERS assume that "confusion" means they should switch to team_enemy when done? traceEnt->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]]; if (traceEnt->ghoul2.size() && traceEnt->headBolt != -1) {//FIXME: what if already playing effect? G_PlayEffect(G_EffectIndex("force/confusion"), traceEnt->playerModel, traceEnt->headBolt, traceEnt->s.number, traceEnt->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } break; } } } ForceTelepathyRadius void ForceTelepathyRadius( gentity_t *self) { trace_t tr; gentity_t *traceEnt; int numEnts; gentity_t* radiusEnts[128]; float radius; vec3_t mins, maxs; vec3_t dir; float dist; switch (self->client->ps.forcePowerLevel[FP_TELEPATHY]) { case FORCE_LEVEL_5: radius = 256; break; case FORCE_LEVEL_4: default: radius = 128; break; } traceEnt = &g_entities[tr.entityNum]; for (int i = 0; i < 3; i++) { mins[i] = traceEnt->currentOrigin[i] - radius; maxs[i] = traceEnt->currentOrigin[i] + radius; } numEnts = gi.EntitiesInBox(mins, maxs, radiusEnts, 128); for (int entIndex = 0; entIndex<numEnts; entIndex++) { // Only Clients //-------------- if (!radiusEnts[entIndex] || !radiusEnts[entIndex]->client) { continue; } // Do The Vector Distance Test //----------------------------- VectorSubtract(radiusEnts[entIndex]->currentOrigin, traceEnt->currentOrigin, dir); dist = VectorNormalize(dir); if (dist < radius) { ForceTelepathy_ConfuseEnts(radiusEnts[entIndex], dir); } } } Any help at this point would be greatly appreciated.years ago I created a radius stunning attack for certain classes with kain mind reaver AOE attack. you need to work about force repulse code of JAE for your mindtrickradius force power. put knockback value and dmg to zero and set mindtrick confusiontime on push_list[x] entities hitted by the shockwave that aren't jedi \ sith classes and do not use saber as weapon Link to comment
JediBantha Posted January 21, 2018 Author Share Posted January 21, 2018 @@Asgarath83 Thanks man, I finally got it working: Mind Trick Radius: void ForceTelepathy(gentity_t *self) { trace_t tr; vec3_t end, forward; gentity_t *traceEnt; qboolean targetLive = qfalse; switch (self->client->ps.forcePowerLevel[FP_TELEPATHY]) { case FORCE_LEVEL_6: forcePowerNeeded[FP_TELEPATHY] = 1; break; case FORCE_LEVEL_5: case FORCE_LEVEL_4: forcePowerNeeded[FP_TELEPATHY] = 5; break; case FORCE_LEVEL_3: case FORCE_LEVEL_2: forcePowerNeeded[FP_TELEPATHY] = 20; break; case FORCE_LEVEL_1: default: forcePowerNeeded[FP_TELEPATHY] = 35; break; } if (WP_CheckBreakControl(self)) { return; } if (self->health <= 0) { return; } //FIXME: if mind trick 3 and aiming at an enemy need more force power if (!WP_ForcePowerUsable(self, FP_TELEPATHY, 0)) { return; } if (self->client->ps.weaponTime >= 800) {//just did one! return; } if (self->client->ps.saberLockTime > level.time) {//FIXME: can this be a way to break out? return; } if (self->client->ps.forceBreachLockoutTime > level.time) { return; } AngleVectors(self->client->ps.viewangles, forward, NULL, NULL); VectorNormalize(forward); VectorMA(self->client->renderInfo.eyePoint, 2048, forward, end); //Cause a distraction if enemy is not fighting gi.trace(&tr, self->client->renderInfo.eyePoint, vec3_origin, vec3_origin, end, self->s.number, MASK_OPAQUE | CONTENTS_BODY, (EG2_Collision)0, 0); if (tr.entityNum == ENTITYNUM_NONE || tr.fraction == 1.0 || tr.allsolid || tr.startsolid) { return; } traceEnt = &g_entities[tr.entityNum]; if (traceEnt->NPC && traceEnt->NPC->scriptFlags & SCF_NO_FORCE) { return; } if (traceEnt && traceEnt->client) { switch (traceEnt->client->NPC_class) { case CLASS_GALAKMECH://cant grip him, he's in armor case CLASS_ATST://much too big to grip! //no droids either case CLASS_PROBE: case CLASS_GONK: case CLASS_R2D2: case CLASS_R5D2: case CLASS_MARK1: case CLASS_MARK2: case CLASS_MOUSE: case CLASS_SEEKER: case CLASS_REMOTE: case CLASS_PROTOCOL: case CLASS_ASSASSIN_DROID: case CLASS_SABER_DROID: case CLASS_BOBAFETT: case CLASS_RAGNOS: case CLASS_GHOST: break; case CLASS_RANCOR: if (!(traceEnt->spawnflags & 1)) { targetLive = qtrue; } break; default: targetLive = qtrue; break; } } if (targetLive && traceEnt->NPC && traceEnt->health > 0) {//hit an organic non-player if (G_ActivateBehavior(traceEnt, BSET_MINDTRICK)) {//activated a script on him //FIXME: do the visual sparkles effect on their heads, still? WP_ForcePowerStart(self, FP_TELEPATHY, 0); } else if (traceEnt->client->playerTeam != self->client->playerTeam) {//an enemy team_t saveTeam; int override = 0; switch (self->client->ps.forcePowerLevel[FP_TELEPATHY]) { case FORCE_LEVEL_6: override = 5; break; case FORCE_LEVEL_5: override = 35; break; case FORCE_LEVEL_4: default: override = 50; break; } if ((traceEnt->NPC->scriptFlags&SCF_NO_MIND_TRICK)) { if (traceEnt->client->NPC_class == CLASS_GALAKMECH) { G_AddVoiceEvent(traceEnt, Q_irand(EV_CONFUSE1, EV_CONFUSE3), Q_irand(3000, 5000)); } } else if (self->client->ps.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_3) {//control them, even jedi if (self->client->ps.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_5) { G_SetViewEntity(self, traceEnt); traceEnt->NPC->controlledTime = level.time + 30000; } else { gentity_t* radiusEnts[128]; vec3_t center, mins, maxs, dir, ent_org, size, v; float radius, dist; int e, numListedEntities, i; switch (self->client->ps.forcePowerLevel[FP_TELEPATHY]) { case FORCE_LEVEL_5: radius = 256; break; case FORCE_LEVEL_4: default: radius = 128; break; } VectorCopy(traceEnt->currentOrigin, center); for (i = 0; i < 3; i++) { mins[i] = traceEnt->currentOrigin[i] - radius; maxs[i] = traceEnt->currentOrigin[i] + radius; } numListedEntities = gi.EntitiesInBox(mins, maxs, radiusEnts, MAX_GENTITIES); for (e = 0; e < numListedEntities; e++) { if (!radiusEnts[e]) continue; if (radiusEnts[e] == self) continue; if (!radiusEnts[e]->inuse) continue; if (radiusEnts[e]->health <= 0) continue; for (i = 0; i < 3; i++) { if (center[i] < radiusEnts[e]->absmin[i]) { v[i] = radiusEnts[e]->absmin[i] - center[i]; } else if (center[i] > radiusEnts[e]->absmax[i]) { v[i] = center[i] - radiusEnts[e]->absmax[i]; } else { v[i] = 0; } } VectorSubtract(radiusEnts[e]->absmax, radiusEnts[e]->absmin, size); VectorMA(radiusEnts[e]->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); //must be close enough dist = VectorLength(v); if (dist >= radius) { continue; } //in PVS? if (!radiusEnts[e]->bmodel && !gi.inPVS(ent_org, traceEnt->client->renderInfo.headPoint)) {//must be in PVS continue; } //Now check and see if we can actually hit it gi.trace(&tr, traceEnt->client->renderInfo.headPoint, vec3_origin, vec3_origin, ent_org, traceEnt->s.number, MASK_SHOT, (EG2_Collision)0, 0); if (tr.fraction < 1.0f && tr.entityNum != radiusEnts[e]->s.number) {//must have clear LOS continue; } if (radiusEnts[e] && radiusEnts[e]->client) { switch (radiusEnts[e]->client->NPC_class) { case CLASS_GALAKMECH: case CLASS_ATST: case CLASS_PROBE: case CLASS_GONK: case CLASS_R2D2: case CLASS_R5D2: case CLASS_MARK1: case CLASS_MARK2: case CLASS_MOUSE: case CLASS_SEEKER: case CLASS_REMOTE: case CLASS_PROTOCOL: case CLASS_ASSASSIN_DROID: case CLASS_SABER_DROID: case CLASS_BOBAFETT: case CLASS_RAGNOS: case CLASS_GHOST: break; case CLASS_RANCOR: if (!(radiusEnts[e]->spawnflags & 1)) { targetLive = qtrue; } break; case CLASS_LUKE: case CLASS_KYLE: case CLASS_DESANN: //Nothing break; case CLASS_TAVION: if (Q_stricmp("tavion", radiusEnts[e]->NPC_type)) {//Nothing } else { if (radiusEnts[e]->NPC && (radiusEnts[e]->NPC->aiFlags&NPCAI_BOSS_CHARACTER)) {//Nothing } else { if (radiusEnts[e]->enemy) { G_ClearEnemy(radiusEnts[e]); } if (self->client->ps.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_4) {//Requires level 5 to convert them if (radiusEnts[e]->NPC) { radiusEnts[e]->client->leader = self; } saveTeam = radiusEnts[e]->client->enemyTeam; radiusEnts[e]->client->enemyTeam = radiusEnts[e]->client->playerTeam; radiusEnts[e]->client->playerTeam = saveTeam; radiusEnts[e]->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]]; } if (radiusEnts[e]->ghoul2.size() && radiusEnts[e]->headBolt != -1) { G_PlayEffect(G_EffectIndex("force/confusion"), radiusEnts[e]->playerModel, radiusEnts[e]->headBolt, radiusEnts[e]->s.number, radiusEnts[e]->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } } } break; case CLASS_ALORA: if (radiusEnts[e]->NPC && (radiusEnts[e]->NPC->aiFlags&NPCAI_BOSS_CHARACTER)) {//Nothing } else { if (radiusEnts[e]->enemy) { G_ClearEnemy(radiusEnts[e]); } if (self->client->ps.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_4) {//Requires level 5 to convert them if (radiusEnts[e]->NPC) { radiusEnts[e]->client->leader = self; } saveTeam = radiusEnts[e]->client->enemyTeam; radiusEnts[e]->client->enemyTeam = radiusEnts[e]->client->playerTeam; radiusEnts[e]->client->playerTeam = saveTeam; radiusEnts[e]->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]]; } if (radiusEnts[e]->ghoul2.size() && radiusEnts[e]->headBolt != -1) { G_PlayEffect(G_EffectIndex("force/confusion"), radiusEnts[e]->playerModel, radiusEnts[e]->headBolt, radiusEnts[e]->s.number, radiusEnts[e]->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } } break; case CLASS_JEDI: case CLASS_REBORN: case CLASS_SHADOWTROOPER: if (radiusEnts[e]->enemy) { G_ClearEnemy(radiusEnts[e]); } if (self->client->ps.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_4) {//Requires level 5 to convert them if (radiusEnts[e]->NPC) { radiusEnts[e]->client->leader = self; } saveTeam = radiusEnts[e]->client->enemyTeam; radiusEnts[e]->client->enemyTeam = radiusEnts[e]->client->playerTeam; radiusEnts[e]->client->playerTeam = saveTeam; radiusEnts[e]->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]]; } if (radiusEnts[e]->ghoul2.size() && radiusEnts[e]->headBolt != -1) { G_PlayEffect(G_EffectIndex("force/confusion"), radiusEnts[e]->playerModel, radiusEnts[e]->headBolt, radiusEnts[e]->s.number, radiusEnts[e]->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } break; default: if (radiusEnts[e]->enemy) { G_ClearEnemy(radiusEnts[e]); } if (radiusEnts[e]->NPC) { radiusEnts[e]->client->leader = self; } saveTeam = radiusEnts[e]->client->enemyTeam; radiusEnts[e]->client->enemyTeam = radiusEnts[e]->client->playerTeam; radiusEnts[e]->client->playerTeam = saveTeam; radiusEnts[e]->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]]; if (radiusEnts[e]->ghoul2.size() && radiusEnts[e]->headBolt != -1) { G_PlayEffect(G_EffectIndex("force/confusion"), radiusEnts[e]->playerModel, radiusEnts[e]->headBolt, radiusEnts[e]->s.number, radiusEnts[e]->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } break; } } } } } else if (traceEnt->s.weapon != WP_SABER && traceEnt->client->NPC_class != CLASS_REBORN) {//haha! Jedi aren't easily confused! if (self->client->ps.forcePowerLevel[FP_TELEPATHY] == FORCE_LEVEL_3 && traceEnt->s.weapon != WP_NONE //don't charm people who aren't capable of fighting... like ugnaughts and droids, just confuse them && traceEnt->client->NPC_class != CLASS_TUSKEN//don't charm them, just confuse them && traceEnt->client->NPC_class != CLASS_NOGHRI//don't charm them, just confuse them && !Pilot_AnyVehiclesRegistered() //also, don't charm guys when bikes are near ) {//turn them to our side //if mind trick 3 and aiming at an enemy need more force power if (self->client->ps.forcePower < override) { return; } if (traceEnt->enemy) { G_ClearEnemy(traceEnt); } if (traceEnt->NPC) { //traceEnt->NPC->tempBehavior = BS_FOLLOW_LEADER; traceEnt->client->leader = self; } //FIXME: maybe pick an enemy right here? //FIXME: does nothing to TEAM_FREE and TEAM_NEUTRALs!!! saveTeam = traceEnt->client->enemyTeam; traceEnt->client->enemyTeam = traceEnt->client->playerTeam; traceEnt->client->playerTeam = saveTeam; //FIXME: need a *charmed* timer on this...? Or do TEAM_PLAYERS assume that "confusion" means they should switch to team_enemy when done? traceEnt->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]]; if (traceEnt->ghoul2.size() && traceEnt->headBolt != -1) {//FIXME: what if already playing effect? G_PlayEffect(G_EffectIndex("force/confusion"), traceEnt->playerModel, traceEnt->headBolt, traceEnt->s.number, traceEnt->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } } else {//just confuse them //somehow confuse them? Set don't fire to true for a while? Drop their aggression? Maybe just take their enemy away and don't let them pick one up for a while unless shot? traceEnt->NPC->confusionTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]];//confused for about 10 seconds if (traceEnt->ghoul2.size() && traceEnt->headBolt != -1) {//FIXME: what if already playing effect? G_PlayEffect(G_EffectIndex("force/confusion"), traceEnt->playerModel, traceEnt->headBolt, traceEnt->s.number, traceEnt->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } NPC_PlayConfusionSound(traceEnt); if (traceEnt->enemy) { G_ClearEnemy(traceEnt); } } } else { NPC_Jedi_PlayConfusionSound(traceEnt); } WP_ForcePowerStart(self, FP_TELEPATHY, override); } else if (traceEnt->client->playerTeam == self->client->playerTeam) {//an ally //maybe just have him look at you? Respond? Take your enemy? if (traceEnt->client->ps.pm_type < PM_DEAD && traceEnt->NPC != NULL && !(traceEnt->NPC->scriptFlags&SCF_NO_RESPONSE)) { NPC_UseResponse(traceEnt, self, qfalse); WP_ForcePowerStart(self, FP_TELEPATHY, 1); } }//NOTE: no effect on TEAM_NEUTRAL? vec3_t eyeDir; AngleVectors(traceEnt->client->renderInfo.eyeAngles, eyeDir, NULL, NULL); VectorNormalize(eyeDir); G_PlayEffect("force/force_touch", traceEnt->client->renderInfo.eyePoint, eyeDir); //make sure this plays and that you cannot press fire for about 1 second after this //FIXME: BOTH_FORCEMINDTRICK or BOTH_FORCEDISTRACT NPC_SetAnim(self, SETANIM_TORSO, BOTH_MINDTRICK1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_RESTART | SETANIM_FLAG_HOLD); //FIXME: build-up or delay this until in proper part of anim } else { if (self->client->ps.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_1 && tr.fraction * 2048 > 64) {//don't create a diversion less than 64 from you of if at power level 1 //use distraction anim instead G_PlayEffect(G_EffectIndex("force/force_touch"), tr.endpos, tr.plane.normal); //FIXME: these events don't seem to always be picked up...? AddSoundEvent(self, tr.endpos, 512, AEL_SUSPICIOUS, qtrue, qtrue); AddSightEvent(self, tr.endpos, 512, AEL_SUSPICIOUS, 50); WP_ForcePowerStart(self, FP_TELEPATHY, 0); } NPC_SetAnim(self, SETANIM_TORSO, BOTH_MINDTRICK2, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_RESTART | SETANIM_FLAG_HOLD); } self->client->ps.saberMove = self->client->ps.saberBounceMove = LS_READY;//don't finish whatever saber anim you may have been in self->client->ps.saberBlocked = BLOCKED_NONE; self->client->ps.weaponTime = 1000; if (self->client->ps.forcePowersActive&(1 << FP_SPEED)) { self->client->ps.weaponTime = floor(self->client->ps.weaponTime * g_timescale->value); } } Feel free to use this in any other projects you might be working on. Asgarath83 likes this Link to comment
Asgarath83 Posted January 21, 2018 Share Posted January 21, 2018 @@Asgarath83 Thanks man, I finally got it working: Mind Trick Radius: void ForceTelepathy(gentity_t *self) { trace_t tr; vec3_t end, forward; gentity_t *traceEnt; qboolean targetLive = qfalse; switch (self->client->ps.forcePowerLevel[FP_TELEPATHY]) { case FORCE_LEVEL_6: forcePowerNeeded[FP_TELEPATHY] = 1; break; case FORCE_LEVEL_5: case FORCE_LEVEL_4: forcePowerNeeded[FP_TELEPATHY] = 5; break; case FORCE_LEVEL_3: case FORCE_LEVEL_2: forcePowerNeeded[FP_TELEPATHY] = 20; break; case FORCE_LEVEL_1: default: forcePowerNeeded[FP_TELEPATHY] = 35; break; } if (WP_CheckBreakControl(self)) { return; } if (self->health <= 0) { return; } //FIXME: if mind trick 3 and aiming at an enemy need more force power if (!WP_ForcePowerUsable(self, FP_TELEPATHY, 0)) { return; } if (self->client->ps.weaponTime >= 800) {//just did one! return; } if (self->client->ps.saberLockTime > level.time) {//FIXME: can this be a way to break out? return; } if (self->client->ps.forceBreachLockoutTime > level.time) { return; } AngleVectors(self->client->ps.viewangles, forward, NULL, NULL); VectorNormalize(forward); VectorMA(self->client->renderInfo.eyePoint, 2048, forward, end); //Cause a distraction if enemy is not fighting gi.trace(&tr, self->client->renderInfo.eyePoint, vec3_origin, vec3_origin, end, self->s.number, MASK_OPAQUE | CONTENTS_BODY, (EG2_Collision)0, 0); if (tr.entityNum == ENTITYNUM_NONE || tr.fraction == 1.0 || tr.allsolid || tr.startsolid) { return; } traceEnt = &g_entities[tr.entityNum]; if (traceEnt->NPC && traceEnt->NPC->scriptFlags & SCF_NO_FORCE) { return; } if (traceEnt && traceEnt->client) { switch (traceEnt->client->NPC_class) { case CLASS_GALAKMECH://cant grip him, he's in armor case CLASS_ATST://much too big to grip! //no droids either case CLASS_PROBE: case CLASS_GONK: case CLASS_R2D2: case CLASS_R5D2: case CLASS_MARK1: case CLASS_MARK2: case CLASS_MOUSE: case CLASS_SEEKER: case CLASS_REMOTE: case CLASS_PROTOCOL: case CLASS_ASSASSIN_DROID: case CLASS_SABER_DROID: case CLASS_BOBAFETT: case CLASS_RAGNOS: case CLASS_GHOST: break; case CLASS_RANCOR: if (!(traceEnt->spawnflags & 1)) { targetLive = qtrue; } break; default: targetLive = qtrue; break; } } if (targetLive && traceEnt->NPC && traceEnt->health > 0) {//hit an organic non-player if (G_ActivateBehavior(traceEnt, BSET_MINDTRICK)) {//activated a script on him //FIXME: do the visual sparkles effect on their heads, still? WP_ForcePowerStart(self, FP_TELEPATHY, 0); } else if (traceEnt->client->playerTeam != self->client->playerTeam) {//an enemy team_t saveTeam; int override = 0; switch (self->client->ps.forcePowerLevel[FP_TELEPATHY]) { case FORCE_LEVEL_6: override = 5; break; case FORCE_LEVEL_5: override = 35; break; case FORCE_LEVEL_4: default: override = 50; break; } if ((traceEnt->NPC->scriptFlags&SCF_NO_MIND_TRICK)) { if (traceEnt->client->NPC_class == CLASS_GALAKMECH) { G_AddVoiceEvent(traceEnt, Q_irand(EV_CONFUSE1, EV_CONFUSE3), Q_irand(3000, 5000)); } } else if (self->client->ps.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_3) {//control them, even jedi if (self->client->ps.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_5) { G_SetViewEntity(self, traceEnt); traceEnt->NPC->controlledTime = level.time + 30000; } else { gentity_t* radiusEnts[128]; vec3_t center, mins, maxs, dir, ent_org, size, v; float radius, dist; int e, numListedEntities, i; switch (self->client->ps.forcePowerLevel[FP_TELEPATHY]) { case FORCE_LEVEL_5: radius = 256; break; case FORCE_LEVEL_4: default: radius = 128; break; } VectorCopy(traceEnt->currentOrigin, center); for (i = 0; i < 3; i++) { mins[i] = traceEnt->currentOrigin[i] - radius; maxs[i] = traceEnt->currentOrigin[i] + radius; } numListedEntities = gi.EntitiesInBox(mins, maxs, radiusEnts, MAX_GENTITIES); for (e = 0; e < numListedEntities; e++) { if (!radiusEnts[e]) continue; if (radiusEnts[e] == self) continue; if (!radiusEnts[e]->inuse) continue; if (radiusEnts[e]->health <= 0) continue; for (i = 0; i < 3; i++) { if (center[i] < radiusEnts[e]->absmin[i]) { v[i] = radiusEnts[e]->absmin[i] - center[i]; } else if (center[i] > radiusEnts[e]->absmax[i]) { v[i] = center[i] - radiusEnts[e]->absmax[i]; } else { v[i] = 0; } } VectorSubtract(radiusEnts[e]->absmax, radiusEnts[e]->absmin, size); VectorMA(radiusEnts[e]->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); //must be close enough dist = VectorLength(v); if (dist >= radius) { continue; } //in PVS? if (!radiusEnts[e]->bmodel && !gi.inPVS(ent_org, traceEnt->client->renderInfo.headPoint)) {//must be in PVS continue; } //Now check and see if we can actually hit it gi.trace(&tr, traceEnt->client->renderInfo.headPoint, vec3_origin, vec3_origin, ent_org, traceEnt->s.number, MASK_SHOT, (EG2_Collision)0, 0); if (tr.fraction < 1.0f && tr.entityNum != radiusEnts[e]->s.number) {//must have clear LOS continue; } if (radiusEnts[e] && radiusEnts[e]->client) { switch (radiusEnts[e]->client->NPC_class) { case CLASS_GALAKMECH: case CLASS_ATST: case CLASS_PROBE: case CLASS_GONK: case CLASS_R2D2: case CLASS_R5D2: case CLASS_MARK1: case CLASS_MARK2: case CLASS_MOUSE: case CLASS_SEEKER: case CLASS_REMOTE: case CLASS_PROTOCOL: case CLASS_ASSASSIN_DROID: case CLASS_SABER_DROID: case CLASS_BOBAFETT: case CLASS_RAGNOS: case CLASS_GHOST: break; case CLASS_RANCOR: if (!(radiusEnts[e]->spawnflags & 1)) { targetLive = qtrue; } break; case CLASS_LUKE: case CLASS_KYLE: case CLASS_DESANN: //Nothing break; case CLASS_TAVION: if (Q_stricmp("tavion", radiusEnts[e]->NPC_type)) {//Nothing } else { if (radiusEnts[e]->NPC && (radiusEnts[e]->NPC->aiFlags&NPCAI_BOSS_CHARACTER)) {//Nothing } else { if (radiusEnts[e]->enemy) { G_ClearEnemy(radiusEnts[e]); } if (self->client->ps.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_4) {//Requires level 5 to convert them if (radiusEnts[e]->NPC) { radiusEnts[e]->client->leader = self; } saveTeam = radiusEnts[e]->client->enemyTeam; radiusEnts[e]->client->enemyTeam = radiusEnts[e]->client->playerTeam; radiusEnts[e]->client->playerTeam = saveTeam; radiusEnts[e]->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]]; } if (radiusEnts[e]->ghoul2.size() && radiusEnts[e]->headBolt != -1) { G_PlayEffect(G_EffectIndex("force/confusion"), radiusEnts[e]->playerModel, radiusEnts[e]->headBolt, radiusEnts[e]->s.number, radiusEnts[e]->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } } } break; case CLASS_ALORA: if (radiusEnts[e]->NPC && (radiusEnts[e]->NPC->aiFlags&NPCAI_BOSS_CHARACTER)) {//Nothing } else { if (radiusEnts[e]->enemy) { G_ClearEnemy(radiusEnts[e]); } if (self->client->ps.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_4) {//Requires level 5 to convert them if (radiusEnts[e]->NPC) { radiusEnts[e]->client->leader = self; } saveTeam = radiusEnts[e]->client->enemyTeam; radiusEnts[e]->client->enemyTeam = radiusEnts[e]->client->playerTeam; radiusEnts[e]->client->playerTeam = saveTeam; radiusEnts[e]->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]]; } if (radiusEnts[e]->ghoul2.size() && radiusEnts[e]->headBolt != -1) { G_PlayEffect(G_EffectIndex("force/confusion"), radiusEnts[e]->playerModel, radiusEnts[e]->headBolt, radiusEnts[e]->s.number, radiusEnts[e]->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } } break; case CLASS_JEDI: case CLASS_REBORN: case CLASS_SHADOWTROOPER: if (radiusEnts[e]->enemy) { G_ClearEnemy(radiusEnts[e]); } if (self->client->ps.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_4) {//Requires level 5 to convert them if (radiusEnts[e]->NPC) { radiusEnts[e]->client->leader = self; } saveTeam = radiusEnts[e]->client->enemyTeam; radiusEnts[e]->client->enemyTeam = radiusEnts[e]->client->playerTeam; radiusEnts[e]->client->playerTeam = saveTeam; radiusEnts[e]->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]]; } if (radiusEnts[e]->ghoul2.size() && radiusEnts[e]->headBolt != -1) { G_PlayEffect(G_EffectIndex("force/confusion"), radiusEnts[e]->playerModel, radiusEnts[e]->headBolt, radiusEnts[e]->s.number, radiusEnts[e]->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } break; default: if (radiusEnts[e]->enemy) { G_ClearEnemy(radiusEnts[e]); } if (radiusEnts[e]->NPC) { radiusEnts[e]->client->leader = self; } saveTeam = radiusEnts[e]->client->enemyTeam; radiusEnts[e]->client->enemyTeam = radiusEnts[e]->client->playerTeam; radiusEnts[e]->client->playerTeam = saveTeam; radiusEnts[e]->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]]; if (radiusEnts[e]->ghoul2.size() && radiusEnts[e]->headBolt != -1) { G_PlayEffect(G_EffectIndex("force/confusion"), radiusEnts[e]->playerModel, radiusEnts[e]->headBolt, radiusEnts[e]->s.number, radiusEnts[e]->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } break; } } } } } else if (traceEnt->s.weapon != WP_SABER && traceEnt->client->NPC_class != CLASS_REBORN) {//haha! Jedi aren't easily confused! if (self->client->ps.forcePowerLevel[FP_TELEPATHY] == FORCE_LEVEL_3 && traceEnt->s.weapon != WP_NONE //don't charm people who aren't capable of fighting... like ugnaughts and droids, just confuse them && traceEnt->client->NPC_class != CLASS_TUSKEN//don't charm them, just confuse them && traceEnt->client->NPC_class != CLASS_NOGHRI//don't charm them, just confuse them && !Pilot_AnyVehiclesRegistered() //also, don't charm guys when bikes are near ) {//turn them to our side //if mind trick 3 and aiming at an enemy need more force power if (self->client->ps.forcePower < override) { return; } if (traceEnt->enemy) { G_ClearEnemy(traceEnt); } if (traceEnt->NPC) { //traceEnt->NPC->tempBehavior = BS_FOLLOW_LEADER; traceEnt->client->leader = self; } //FIXME: maybe pick an enemy right here? //FIXME: does nothing to TEAM_FREE and TEAM_NEUTRALs!!! saveTeam = traceEnt->client->enemyTeam; traceEnt->client->enemyTeam = traceEnt->client->playerTeam; traceEnt->client->playerTeam = saveTeam; //FIXME: need a *charmed* timer on this...? Or do TEAM_PLAYERS assume that "confusion" means they should switch to team_enemy when done? traceEnt->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]]; if (traceEnt->ghoul2.size() && traceEnt->headBolt != -1) {//FIXME: what if already playing effect? G_PlayEffect(G_EffectIndex("force/confusion"), traceEnt->playerModel, traceEnt->headBolt, traceEnt->s.number, traceEnt->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } } else {//just confuse them //somehow confuse them? Set don't fire to true for a while? Drop their aggression? Maybe just take their enemy away and don't let them pick one up for a while unless shot? traceEnt->NPC->confusionTime = level.time + mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]];//confused for about 10 seconds if (traceEnt->ghoul2.size() && traceEnt->headBolt != -1) {//FIXME: what if already playing effect? G_PlayEffect(G_EffectIndex("force/confusion"), traceEnt->playerModel, traceEnt->headBolt, traceEnt->s.number, traceEnt->currentOrigin, mindTrickTime[self->client->ps.forcePowerLevel[FP_TELEPATHY]], qtrue); } NPC_PlayConfusionSound(traceEnt); if (traceEnt->enemy) { G_ClearEnemy(traceEnt); } } } else { NPC_Jedi_PlayConfusionSound(traceEnt); } WP_ForcePowerStart(self, FP_TELEPATHY, override); } else if (traceEnt->client->playerTeam == self->client->playerTeam) {//an ally //maybe just have him look at you? Respond? Take your enemy? if (traceEnt->client->ps.pm_type < PM_DEAD && traceEnt->NPC != NULL && !(traceEnt->NPC->scriptFlags&SCF_NO_RESPONSE)) { NPC_UseResponse(traceEnt, self, qfalse); WP_ForcePowerStart(self, FP_TELEPATHY, 1); } }//NOTE: no effect on TEAM_NEUTRAL? vec3_t eyeDir; AngleVectors(traceEnt->client->renderInfo.eyeAngles, eyeDir, NULL, NULL); VectorNormalize(eyeDir); G_PlayEffect("force/force_touch", traceEnt->client->renderInfo.eyePoint, eyeDir); //make sure this plays and that you cannot press fire for about 1 second after this //FIXME: BOTH_FORCEMINDTRICK or BOTH_FORCEDISTRACT NPC_SetAnim(self, SETANIM_TORSO, BOTH_MINDTRICK1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_RESTART | SETANIM_FLAG_HOLD); //FIXME: build-up or delay this until in proper part of anim } else { if (self->client->ps.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_1 && tr.fraction * 2048 > 64) {//don't create a diversion less than 64 from you of if at power level 1 //use distraction anim instead G_PlayEffect(G_EffectIndex("force/force_touch"), tr.endpos, tr.plane.normal); //FIXME: these events don't seem to always be picked up...? AddSoundEvent(self, tr.endpos, 512, AEL_SUSPICIOUS, qtrue, qtrue); AddSightEvent(self, tr.endpos, 512, AEL_SUSPICIOUS, 50); WP_ForcePowerStart(self, FP_TELEPATHY, 0); } NPC_SetAnim(self, SETANIM_TORSO, BOTH_MINDTRICK2, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_RESTART | SETANIM_FLAG_HOLD); } self->client->ps.saberMove = self->client->ps.saberBounceMove = LS_READY;//don't finish whatever saber anim you may have been in self->client->ps.saberBlocked = BLOCKED_NONE; self->client->ps.weaponTime = 1000; if (self->client->ps.forcePowersActive&(1 << FP_SPEED)) { self->client->ps.weaponTime = floor(self->client->ps.weaponTime * g_timescale->value); } } Feel free to use this in any other projects you might be working on.Nice works! you create thje same things i did in past, but in a more efficient coding way. is more short as code, and more easy to understand and apply. my code was little... confuse (so stun also coder not only NPCs ) Remember that you can also create a AOE attack that push enemy...or pull enemy, or poison enemies, or freeze foes... depend all of with kind of alteration you infuse.mmm i think the howler scream code can be an help for the affection of enemy hitted by a shockwave force power. Link to comment
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now