edict_t *NextNearestTotem(edict_t *ent, int totemType, edict_t *lastTotem, qboolean allied) { edict_t *ed, *owner, *closestEnt = NULL; float closestDistance = -1.0; float lastTotemDistance = 0.0; if (lastTotem) lastTotemDistance = V_EntDistance(ent, lastTotem); for (ed = g_edicts ; ed < &g_edicts[globals.num_edicts]; ed++) { float thisDistance; //skip all ents that are not totems, and skip the last "closest" totem. if(ed->mtype != totemType || ed == lastTotem) continue; // air totems can be configured to protect only their owner if (PM_PlayerHasMonster(ed->activator)) owner = ed->activator->owner; else owner = ed->activator; if (ed->mtype == TOTEM_AIR && ed->style && ent != owner) continue; //skip any totems that are "not on my team" or are "not my enemy" if(allied && !OnSameTeam(ent, ed)) continue; else if(!allied && OnSameTeam(ent, ed)) continue; thisDistance = V_EntDistance(ent, ed); //Totem must be in range and must be in "line of sight". //Using visible1() so forcewall, etc.. can block it. if(thisDistance > TOTEM_MAX_RANGE || !visible1(ed, ent)) continue; //The closest totem found must be farther away than the last one found. if(lastTotem != NULL && thisDistance < lastTotemDistance) continue; //This is a valid totem, but is it the closest one? if(thisDistance < closestDistance || closestDistance == -1.0) { closestDistance = thisDistance; closestEnt = ed; } } //This should be the next closest totem to the target, and should be null if there isn't one. return closestEnt; }
gentity_t *EnemyCapturingFlag ( gentity_t *self, int flag_entitynum ) {// Should return an enemy that is trying to capture the same flag as us... gentity_t *flag = &g_entities[flag_entitynum]; int client = 0; for (client = 0; client < MAX_GENTITIES; client++) { gentity_t *ent = &g_entities[client]; if (!ent) continue; if (!ent->client) continue; if (ent->health <= 0) continue; if (ent->s.eType != ET_NPC && ent->s.eType != ET_PLAYER) continue; if (ent->client->ps.stats[STAT_CAPTURE_ENTITYNUM] != flag_entitynum) continue; if (OnSameTeam(ent, self)) continue; // OK, we found an enemy trying to capture this flag! Return it! return ent; } return NULL; }
static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, const char *message ) { if ( !other || !other->inuse || !other->client ) return; if ( other->client->pers.connected != CON_CONNECTED ) return; if ( mode == SAY_TEAM && !OnSameTeam( ent, other ) ) return; //QTZTODO: specmute /* // no chatting to players in tournaments if ( (level.gametype == GT_DUEL || level.gametype == GT_POWERDUEL) && other->client->sess.sessionTeam == TEAM_FREE && ent->client->sess.sessionTeam != TEAM_FREE ) { //Hmm, maybe some option to do so if allowed? Or at least in developer mode... return; } */ trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, other ), va( "%s %i \"%c%c%s\"", mode == SAY_TEAM ? "tchat" : "chat", ent->s.number, Q_COLOR_ESCAPE, color, message)); }
void forcewall_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { V_Touch(self, other, plane, surf); // let teammates pass thru if (/*(other != self->activator) &&*/ G_EntIsAlive(other)) { if (OnSameTeam(self->activator, other) && (other->movetype == MOVETYPE_STEP || other->movetype == MOVETYPE_WALK)) { //gi.dprintf("%s touching %d \n",other->classname, other->movetype); self->solid = SOLID_NOT; self->wait = level.time + 0.2; // small buffer so monsters can get thru } else if (level.time > self->random) { // dont allow solid force wall to trap people if (level.framenum == self->count-900) { G_FreeEdict(self); return; } forcewall_knockback(self, other); // knock them back gi.sound(other, CHAN_ITEM, gi.soundindex("world/force2.wav"), 1, ATTN_NORM, 0); self->random = level.time + 0.5; // dont spam the sound } } }
void mymedic_attack(edict_t *self) { float dist, r; if (!self->enemy) return; if (!self->enemy->inuse) return; dist = entdist(self, self->enemy); r = random(); if ((self->monsterinfo.aiflags & AI_MEDIC) && ((self->enemy->health < 1 || OnSameTeam(self, self->enemy)))) { if (dist <= 256) self->monsterinfo.currentmove = &mymedic_move_attackCable; return; } if (dist <= 256) { if (r <= 0.2) self->monsterinfo.currentmove = &mymedic_move_attackHyperBlaster; else self->monsterinfo.currentmove = &mymedic_move_attackBlaster; } else { if (r <= 0.3) self->monsterinfo.currentmove = &mymedic_move_attackBlaster; else self->monsterinfo.currentmove = &mymedic_move_attackHyperBlaster; } }
static void G_VoiceTo(Gentity *ent, Gentity *other, int mode, const char *id, qbool voiceonly) { int color; char *cmd; if(!other) return; if(!other->inuse) return; if(!other->client) return; if(mode == SAY_TEAM && !OnSameTeam(ent, other)) return; /* no chatting to players in tournements */ if(g_gametype.integer == GT_TOURNAMENT) return; if(mode == SAY_TEAM){ color = COLOR_CYAN; cmd = "vtchat"; }else if(mode == SAY_TELL){ color = COLOR_MAGENTA; cmd = "vtell"; }else{ color = COLOR_GREEN; cmd = "vchat"; } trap_SendServerCommand(other-g_entities, va("%s %d %d %d %s", cmd, voiceonly, ent->s.number, color, id)); }
qboolean G_CurseValidTarget (edict_t *self, edict_t *target, qboolean vis, qboolean isCurse) { if (!G_EntIsAlive(target)) return false; // don't target players with invulnerability if (target->client && (target->client->invincible_framenum > level.framenum)) return false; // don't target spawning players if (target->client && (target->client->respawn_time > level.time)) return false; // don't target players in chat-protect if (!ptr->value && target->client && (target->flags & FL_CHATPROTECT)) return false; // don't target spawning world monsters if (target->activator && !target->activator->client && (target->svflags & SVF_MONSTER) && (target->deadflag != DEAD_DEAD) && (target->nextthink-level.time > 2*FRAMETIME)) return false; // don't target cloaked players if (target->client && target->svflags & SVF_NOCLIENT) return false; if (vis && !visible(self, target)) return false; if(que_typeexists(target->curses, CURSE_FROZEN)) return false; if (isCurse && (target->flags & FL_GODMODE || OnSameTeam(self, target))) return false; if (target == self) return false; return true; }
/* ================== Cmd_Say_f ================== */ void Cmd_Say_f (edict_t *ent, qboolean team, qboolean arg0) { int j; edict_t *other; char *p; char text[2048]; if (gi.argc () < 2 && !arg0) return; if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS))) team = false; if (team) Com_sprintf (text, sizeof(text), "(%s): ", ent->client->pers.netname); else Com_sprintf (text, sizeof(text), "%s: ", ent->client->pers.netname); if (arg0) { strcat (text, gi.argv(0)); strcat (text, " "); strcat (text, gi.args()); } else { p = gi.args(); if (*p == '"') { p++; p[strlen(p)-1] = 0; } strcat(text, p); } // don't let text be too long for malicious reasons if (strlen(text) > 150) text[150] = 0; strcat(text, "\n"); if (dedicated->value) gi.cprintf(NULL, PRINT_CHAT, "%s", text); for (j = 1; j <= game.maxclients; j++) { other = &g_edicts[j]; if (!other->inuse) continue; if (!other->client) continue; if (team) { if (!OnSameTeam(ent, other)) continue; } gi.cprintf(other, PRINT_CHAT, "%s", text); } }
static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, const char *name, const char *message ) { if (!other) { return; } if (!other->inuse) { return; } if (!other->client) { return; } if ( other->client->pers.connected != CON_CONNECTED ) { return; } if ( mode == SAY_TEAM && !OnSameTeam(ent, other) ) { return; } // no chatting to players in tournements if ( (g_gametype.integer == GT_TOURNAMENT ) && other->client->sess.sessionTeam == TEAM_FREE && ent->client->sess.sessionTeam != TEAM_FREE ) { return; } trap_SendServerCommand( other-g_entities, va("%s \"%s%c%c%s\"", mode == SAY_TEAM ? "tchat" : "chat", name, Q_COLOR_ESCAPE, color, message)); }
/* =============== LogAccuracyHit =============== */ qboolean LogAccuracyHit( gentity_t *target, gentity_t *attacker ) { if( !target->takedamage ) { return qfalse; } if ( target == attacker ) { return qfalse; } if( !target->client ) { return qfalse; } if( !attacker->client ) { return qfalse; } if( target->client->ps.stats[STAT_HEALTH] <= 0 ) { return qfalse; } if ( OnSameTeam( target, attacker ) ) { return qfalse; } return qtrue; }
static edict_t * FindEnemy(edict_t * self, int radius) { // loop through all nearby entities, looking for targets edict_t * ent = 0; int nPriority = 0; // 1 grenades, 2 clients, 3 pets int nPotentialPriority = 0; edict_t * enemy = 0; while ((ent = findradius(ent, self->s.origin, 500)) != NULL) { if ((ent->flags & FL_NOTARGET)||(ent->svflags & SVF_NOCLIENT)) continue; if (!ent->inuse || !ent->takedamage || (ent->health <= 0)) continue; if (EntIsMonster(ent)) { if (OnSameTeam(ent, self)) continue; nPotentialPriority = 3; } else if (EntIsClient(ent)) { if (OnSameTeam(ent, self)) continue; nPotentialPriority = 2; } else { // first priority is grenades // modify this if you don't want pets shooting grenades nPotentialPriority = 1; } if (nPriority>nPotentialPriority) continue; if (!visible(self, ent)) continue; // remember this candidate enemy enemy = ent; nPriority = nPotentialPriority; } // return best we found (might be zero) return enemy; }
static qboolean parasite_cantarget (edict_t *self, edict_t *target) { int para_range = PARASITE_ATTACK_RANGE; return (G_EntExists(target) && !que_typeexists(target->curses, CURSE_FROZEN) && !OnSameTeam(self, target) && visible(self, target) && nearfov(self, target, 45, 45) && (entdist(self, target) <= para_range)); }
void GetNearbyTeammates(edict_t *self, char *buf) { unsigned char nearby_teammates[10][16]; int nearby_teammates_num, l; edict_t *ent = NULL; nearby_teammates_num = 0; while ((ent = findradius(ent, self->s.origin, 1500)) != NULL) { if (ent == self || !ent->client || !CanDamage(ent, self) || OnSameTeam(ent, self)) continue; strncpy(nearby_teammates[nearby_teammates_num], ent->client->pers.netname, 15); nearby_teammates[nearby_teammates_num][15] = 0; // in case their name is 15 chars... nearby_teammates_num++; if (nearby_teammates_num >= 10) break; } if (nearby_teammates_num == 0) { strcpy(buf, "nobody"); return; } for (l = 0; l < nearby_teammates_num; l++) { if (l == 0) { strcpy(buf, nearby_teammates[l]); } else { if (nearby_teammates_num == 2) { strcat(buf, " and "); strcat(buf, nearby_teammates[l]); } else { if (l == (nearby_teammates_num - 1)) { strcat(buf, ", and "); strcat(buf, nearby_teammates[l]); } else { strcat(buf, ", "); strcat(buf, nearby_teammates[l]); } } } } }
void supplystation_pain (edict_t *self, edict_t *other, float kick, int damage) { if (G_EntExists(other) && !OnSameTeam(self, other) && (level.time > self->random)) { if (other->client) gi.centerprintf(self->creator, "%s is attacking\nyour station!\n", other->client->pers.netname); else gi.centerprintf(self->creator, "Your station is under\nattack!"); self->random = level.time + 5; } }
//We cannot hurt the ones we love. Unless of course this //function says we can. int PassLovedOneCheck(bot_state_t *bs, gentity_t *ent) { int i; bot_state_t *loved; if (!bs->lovednum) { return 1; } if (g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL) { //There is no love in 1-on-1 return 1; } i = 0; if (!botstates[ent->s.number]) { //not a bot return 1; } if (!bot_attachments.integer) { return 1; } loved = botstates[ent->s.number]; while (i < bs->lovednum) { if (strcmp(level.clients[loved->client].pers.netname, bs->loved[i].name) == 0) { if (!IsTeamplay() && bs->loved[i].level < 2) { //if FFA and level of love is not greater than 1, just don't care return 1; } else if (IsTeamplay() && !OnSameTeam(&g_entities[bs->client], &g_entities[loved->client]) && bs->loved[i].level < 2) { //is teamplay, but not on same team and level < 2 return 1; } else { return 0; } } i++; } return 1; }
void salvation_think (edict_t *self) { int radius; edict_t *other=NULL; que_t *slot=NULL; // check status of owner if (!CheckAuraOwner(self, COST_FOR_SALVATION)) { que_removeent(self->owner->auras, self, true); return; } // use cubes if (!(level.framenum % DEFAULT_AURA_FRAMES)) { int cube_cost = DEFAULT_AURA_COST; self->owner->client->pers.inventory[power_cube_index] -= cube_cost; } que_addent(self->owner->auras, self, DEFAULT_AURA_DURATION); // move aura with owner VectorCopy(self->owner->s.origin,self->s.origin); self->nextthink = level.time + FRAMETIME; if (level.framenum % DEFAULT_AURA_SCAN_FRAMES) return; radius = 256; // scan for targets while ((other = findradius (other, self->s.origin, radius)) != NULL) { slot = NULL; if (other == self->owner) continue; if (!G_EntExists(other)) continue; if (other->health < 1) continue; if (OnSameTeam(self->owner, other) < 2) continue; if (!visible(self->owner, other)) continue; slot = que_findtype(other->auras, slot, AURA_SALVATION); if (slot && (slot->ent->owner != self->owner)) continue; que_addent(other->auras, self, DEFAULT_AURA_DURATION); } }
qboolean G_ShouldEntitiesClip(moveclip_t *clip, int touchNum, gentity_t *touch) { if(clip->passEntityNum < 64 && clip->contentmask & CONTENTS_PLAYERCLIP){ if(g_entities[clip->passEntityNum].client->sess.cs.team == TEAM_FREE){ if(!SV_FFAPlayerCanBlock()){ if(touchNum < 64) { return qfalse; }else if(touch->r.ownerNum -1 < 64 && touch->r.contents & CONTENTS_PLAYERCLIP){ return qfalse; } } }else if(!SV_FriendlyPlayerCanBlock()){ if(touchNum < 64) { if(OnSameTeam( &g_entities[clip->passEntityNum], &g_entities[touchNum])) { return qfalse; } } else if( touch->r.ownerNum && touch->r.ownerNum <= 64 && touch->r.contents & CONTENTS_PLAYERCLIP) { if(OnSameTeam( &g_entities[clip->passEntityNum], &g_entities[touch->r.ownerNum -1])) { return qfalse; } } } } return qtrue; }
static void G_VoiceTo( gentity_t *ent, gentity_t *other, int mode, const char *id, qboolean voiceonly ) { int color; char *cmd; if (!other) { return; } if (!other->inuse) { return; } if (!other->client) { return; } if ( mode == SAY_TEAM && !OnSameTeam(ent, other) ) { return; } // no chatting to players in tournements if ( (g_gametype.integer == GT_TOURNAMENT )) { return; } if (mode == SAY_TEAM) { // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Using renamed color constants: //color = COLOR_CYAN; color = Q_COLOR_CYAN; // <<< FIX cmd = "vtchat"; } else if (mode == SAY_TELL) { // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Using renamed color constants: //color = COLOR_MAGENTA; color = Q_COLOR_MAGENTA; // <<< FIX cmd = "vtell"; } else { // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Using renamed color constants: //color = COLOR_GREEN; color = Q_COLOR_GREEN; // <<< FIX cmd = "vchat"; } trap_SendServerCommand( other-g_entities, va("%s %d %d %d %s", cmd, voiceonly, ent->s.number, color, id)); }
// DetermineViewedTeammate: determine the current player you're viewing (only looks for live teammates) // Modified from SetIDView (which was used from Zoid's CTF) edict_t *DetermineViewedTeammate (edict_t * ent) { vec3_t forward, dir; trace_t tr; edict_t *who, *best; //FIREBLADE, suggested by hal[9k] 3/11/1999 float bd = 0.9f; //FIREBLADE float d; int i; AngleVectors (ent->client->v_angle, forward, NULL, NULL); VectorScale (forward, 8192, forward); VectorAdd (ent->s.origin, forward, forward); PRETRACE (); tr = gi.trace (ent->s.origin, NULL, NULL, forward, ent, MASK_SOLID); POSTTRACE (); if (tr.fraction < 1 && tr.ent && tr.ent->client) { return NULL; } AngleVectors (ent->client->v_angle, forward, NULL, NULL); best = NULL; for (i = 1; i <= maxclients->value; i++) { who = g_edicts + i; if (!who->inuse) continue; VectorSubtract (who->s.origin, ent->s.origin, dir); VectorNormalize (dir); d = DotProduct (forward, dir); if (d > bd && loc_CanSee (ent, who) && who->solid != SOLID_NOT && who->deadflag != DEAD_DEAD && OnSameTeam (who, ent)) { bd = d; best = who; } } if (bd > 0.90) { return best; } return NULL; }
int p_berserk_melee (edict_t *self, vec3_t forward, vec3_t dir, int damage, int knockback, int range, int mod) { vec3_t start, end; trace_t tr; self->lastsound = level.framenum; // damage zone VectorCopy(self->s.origin, start); start[2] += self->viewheight-8; VectorMA(start, range, forward, end); tr = gi.trace(start, NULL, NULL, end, self, MASK_SHOT); // bfg laser effect gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_LASER); gi.WritePosition (start); gi.WritePosition (tr.endpos); //gi.multicast (start, MULTICAST_PHS); gi.unicast(self, true); //safe_cprintf(self, PRINT_HIGH, "Attack\n"); if (G_EntExists(tr.ent)) { if (dir) T_Damage(tr.ent, self, self, dir, tr.endpos, tr.plane.normal, damage, knockback, 0, mod); else T_Damage(tr.ent, self, self, forward, tr.endpos, tr.plane.normal, damage, knockback, 0, mod); // berserk slash attack has a chance to cause bleeding if (!OnSameTeam(self, tr.ent) && (mod == MOD_BERSERK_SLASH) && (random() > 0.5)) { curse_add(tr.ent, self, BLEEDING, self->myskills.abilities[BERSERK].current_level, 10.0); if (tr.ent->client) safe_cprintf(tr.ent, PRINT_HIGH, "You are bleeding!\n"); } return MELEE_HIT_ENT; // hit a damageable ent } if (tr.fraction < 1) return MELEE_HIT_WORLDSPAWN; // hit a wall else return MELEE_HIT_NOTHING; // hit nothing }
qbool LogAccuracyHit(Gentity *target, Gentity *attacker) { if(!target->takedamage) return qfalse; if(target == attacker) return qfalse; if(!target->client) return qfalse; if(!attacker->client) return qfalse; if(target->client->ps.stats[STAT_HEALTH] <= 0) return qfalse; if(OnSameTeam(target, attacker)) return qfalse; return qtrue; }
void proxMineThink(gentity_t *ent) { int i = 0; gentity_t *cl; gentity_t *owner = NULL; if (ent->r.ownerNum < ENTITYNUM_WORLD) { owner = &g_entities[ent->r.ownerNum]; } ent->nextthink = level.time; if (ent->genericValue15 < level.time || !owner || !owner->inuse || !owner->client || owner->client->pers.connected != CON_CONNECTED) { //time to die! ent->think = laserTrapExplode; return; } while (i < MAX_CLIENTS) { //eh, just check for clients, don't care about anyone else... cl = &g_entities[i]; if (cl->inuse && cl->client && cl->client->pers.connected == CON_CONNECTED && owner != cl && cl->client->sess.sessionTeam != TEAM_SPECTATOR && cl->client->tempSpectate < level.time && cl->health > 0) { if (!OnSameTeam(owner, cl) || g_friendlyFire.integer) { //not on the same team, or friendly fire is enabled vec3_t v; VectorSubtract(ent->r.currentOrigin, cl->client->ps.origin, v); if (VectorLength(v) < (ent->splashRadius/2.0f)) { ent->think = laserTrapExplode; return; } } } i++; } }
void laser_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { //gi.dprintf("laser_touch\n"); //gi.dprintf("%s %s %s\n", OnSameTeam(ent, other)?"y":"n", ent->health<ent->max_health?"y":"n", level.framenum>ent->monsterinfo.regen_delay1?"y":"n"); if (G_EntIsAlive(other) && other->client && OnSameTeam(ent, other) // a player on our team && other->client->pers.inventory[power_cube_index] >= 5 // has power cubes && ent->creator->health < 0.5*ent->creator->max_health // only repair below 50% health (to prevent excessive cube use/repair noise) && level.framenum > ent->creator->monsterinfo.regen_delay1) // check delay { ent->creator->health = ent->creator->max_health; other->client->pers.inventory[power_cube_index] -= 5; ent->creator->monsterinfo.regen_delay1 = level.framenum + 20; gi.sound(other, CHAN_VOICE, gi.soundindex("weapons/repair.wav"), 1, ATTN_NORM, 0); gi.cprintf(other, PRINT_HIGH, "Emitter repaired. Maximum output: %d/%d damage.\n", ent->creator->health, ent->creator->max_health); } }
qboolean station_findtarget (edict_t *self) { edict_t *e=NULL; while ((e = findclosestradius(e, self->s.origin, STATION_TARGET_RADIUS)) != NULL) { if (!ValidStationTarget(self, e)) continue; if (!OnSameTeam(self, e)) { gi.centerprintf(self->creator, "%s is using\nyour supply station!\n", e->client->pers.netname); continue; } self->enemy = e; return true; } self->enemy = NULL; return false; }
void mymedic_heal (edict_t *self) { // stop healing our target died, if they are fully healed, or // they have gone out of range while we are standing ground (can't reach them) if (!G_EntIsAlive(self->enemy) || !M_NeedRegen(self->enemy) || ((self->monsterinfo.aiflags & AI_STAND_GROUND) && (entdist(self, self->enemy) > 256))) { self->enemy = NULL; mymedic_stand(self); return; } // continue healing if our target is still in range and // there are no enemies around if (OnSameTeam(self, self->enemy) && (entdist(self, self->enemy) <= 256) && !mymedic_findenemy(self)) self->monsterinfo.currentmove = &mymedic_move_attackCable; else mymedic_run(self); }
/* ================= Cmd_Kill_f ================= */ void Cmd_Kill_f (edict_t * ent) { //FIREBLADE if (ent->solid == SOLID_NOT || ent->deadflag == DEAD_DEAD) return; //FIREBLADE // AQ:TNG - JBravo adding punishkills if (punishkills->value) { if (ent->client->attacker && ent->client->attacker->client && (ent->client->attacker->client != ent->client)) { char deathmsg[64]; Com_sprintf(deathmsg, sizeof(deathmsg), "%s ph34rs %s so much %s committed suicide! :)\n", ent->client->pers.netname, ent->client->attacker->client->pers.netname, ent->client->resp.radio_gender ? "she" : "he"); PrintDeathMessage(deathmsg, ent); if(team_round_going || !OnSameTeam(ent, ent->client->attacker)) { Add_Frag (ent->client->attacker); Subtract_Frag (ent); ent->client->resp.deaths++; } } } // End punishkills if ((level.time - ent->client->respawn_time) < 5) return; ent->flags &= ~FL_GODMODE; ent->health = 0; meansOfDeath = MOD_SUICIDE; player_die (ent, ent, ent, 100000, vec3_origin); // Forget all this... -FB // // don't even bother waiting for death frames // ent->deadflag = DEAD_DEAD; ////FIREBLADE // if (!teamplay->value) ////FIREBLADE // respawn (ent); }
/* =============== LogAccuracyHit =============== */ bool LogAccuracyHit( GameEntity* target, GameEntity* attacker ) { if( !target->takedamage_ ) return false; if ( target == attacker ) return false; if( !target->client_ ) return false; if( !attacker->client_ ) return false; if( target->client_->ps_.stats[STAT_HEALTH] <= 0 ) return false; if ( OnSameTeam( target, attacker ) ) return false; return true; }
void mymedic_dodge (edict_t *self, edict_t *attacker, vec3_t dir, int radius) { if (random() > 0.9) return; if (level.time < self->monsterinfo.dodge_time) return; if (OnSameTeam(self, attacker)) return; if (!self->enemy && G_EntIsAlive(attacker)) self->enemy = attacker; if (!radius) { self->monsterinfo.currentmove = &mymedic_move_duck; self->monsterinfo.dodge_time = level.time + 2.0; } else { mymedic_leap(self); self->monsterinfo.dodge_time = level.time + 3.0; } }
/* ================= G_DropGametypeItems Drops all of the gametype items held by the player ================= */ void G_DropGametypeItems(gentity_t* self, int delayPickup) { // drop all custom gametype items for (int i = 0; i < MAX_GAMETYPE_ITEMS; i++) { // skip this gametype item if the client doenst have it if (!(self->client->ps.stats[STAT_GAMETYPE_ITEMS] & (1 << i))) { continue; } gitem_t *item = BG_FindGametypeItem(i); if (!item) { continue; } float angle = 0; gentity_t *drop = G_DropItem(self, item, angle); drop->count = 1; angle += 45; if (delayPickup) { drop->nextthink = level.time + delayPickup; drop->s.eFlags |= EF_NOPICKUP; drop->think = G_EnableGametypeItemPickup; } // TAke it away from the client just in case self->client->ps.stats[STAT_GAMETYPE_ITEMS] &= ~(1 << i); if (self->enemy && self->enemy->client && !OnSameTeam(self->enemy, self)) { gtCore->onItemDefend(self); } } self->client->ps.stats[STAT_GAMETYPE_ITEMS] = 0; }
void boss_punch (edict_t *self) { int damage; trace_t tr; edict_t *other=NULL; vec3_t v; if (!self->groundentity) return; damage = TANK_PUNCH_INITIAL_DAMAGE+TANK_PUNCH_ADDON_DAMAGE*self->monsterinfo.level; // T_RadiusDamage(self, self, damage, self, TANK_PUNCH_RADIUS, 0); gi.sound (self, CHAN_AUTO, gi.soundindex ("tank/tnkatck5.wav"), 1, ATTN_NORM, 0); while ((other = findradius(other, self->s.origin, 256)) != NULL) { if (other == self) continue; if (!other->inuse) continue; if (!other->takedamage) continue; if (other->solid == SOLID_NOT) continue; if (!other->groundentity) continue; if (OnSameTeam(self, other)) continue; if (!visible(self, other)) continue; VectorSubtract(other->s.origin, self->s.origin, v); VectorNormalize(v); tr = gi.trace(self->s.origin, NULL, NULL, other->s.origin, self, (MASK_PLAYERSOLID | MASK_MONSTERSOLID)); T_Damage (other, self, self, v, other->s.origin, tr.plane.normal, damage, damage, 0, MOD_TANK_PUNCH); other->velocity[2] += damage / 2; } }