void myChickRocket (edict_t *self) { int damage, speed; vec3_t forward, start; if (self->monsterinfo.bonus_flags & BF_UNIQUE_FIRE) { myChickFireball(self); return; } if (!G_EntExists(self->enemy)) return; damage = 50 + 15*self->monsterinfo.level; if ( self->activator && self->activator->client ) { speed = 450 + 30*self->monsterinfo.level; } else { speed = 450; } MonsterAim(self, 1, speed, true, MZ2_CHICK_ROCKET_1, forward, start); monster_fire_rocket (self, start, forward, damage, speed, MZ2_CHICK_ROCKET_1); }
void lightningbolt_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (G_EntExists(other)) T_Damage(other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, self->dmg, 0, MOD_LIGHTNING); G_FreeEdict(self); }
void mybrain_suxor (edict_t *self) { int damage, range, pull; vec3_t start, v, end; trace_t tr; if (!self->enemy) return; if (!self->enemy->inuse) return; self->lastsound = level.framenum; G_EntMidPoint(self->enemy, start); VectorSubtract(start, self->s.origin, v); self->ideal_yaw = vectoyaw(v); M_ChangeYaw (self); range = VectorLength(v); VectorNormalize(v); VectorMA(self->s.origin, 512, v, end); tr = gi.trace(self->s.origin, NULL, NULL, end, self, MASK_SHOT); if (G_EntExists(tr.ent) && (tr.ent == self->enemy)) { damage = BRAIN_INITIAL_TENTACLE_DMG + BRAIN_ADDON_TENTACLE_DMG*self->monsterinfo.level; pull = BRAIN_INITIAL_PULL + BRAIN_ADDON_PULL*self->monsterinfo.level; if (tr.ent->groundentity) pull *= 2; if (range > 64) T_Damage(tr.ent, self, self, v, tr.endpos, tr.plane.normal, 0, pull, 0, MOD_UNKNOWN); else T_Damage(tr.ent, self, self, v, tr.endpos, tr.plane.normal, damage, pull, 0, MOD_UNKNOWN); } }
void GladiatorLightningStorm (edict_t *self) { int damage; if (!G_EntExists(self->enemy)) return; //slvl = self->monsterinfo.level; //if (slvl > 15) // slvl = 15; damage = 200;//50 + 15 * slvl; SpawnLightningStorm(self, self->enemy->s.origin, 128, 5.0, damage); // write a nice effect so everyone knows we've cast a spell gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_TELEPORT_EFFECT); gi.WritePosition (self->enemy->s.origin); gi.multicast (self->enemy->s.origin, MULTICAST_PVS); // entity made a sound, used to alert monsters self->lastsound = level.framenum; gi.sound (self, CHAN_WEAPON, gi.soundindex("spells/eleccast.wav"), 1, ATTN_NORM, 0); }
// botsafe bprintf void safe_bprintf (int printlevel, char *fmt, ...) { int i; char bigbuffer[0x10000]; char bigbuffer2[0x10000]; int len; va_list argptr; edict_t *cl_ent; va_start (argptr,fmt); len = vsprintf (bigbuffer,fmt,argptr); va_end (argptr); if (dedicated->value) { convert_string(bigbuffer, 128, 255, -128, bigbuffer2); // green -> white gi.cprintf(NULL, printlevel, bigbuffer2); } // This is to be compatible with Eraser (ACE) //for (i=0; i<num_players; i++) //{ // Ridah, changed this so CAM works for (i=0 ; i<maxclients->value ; i++) { cl_ent = g_edicts + 1 + i; if (cl_ent->inuse && !cl_ent->bot_client && cl_ent->client->pers.in_game) if (G_EntExists(cl_ent)) gi.cprintf(cl_ent, printlevel, bigbuffer); } }
void boss_spawn_tank (edict_t *ent) { char userinfo[MAX_INFO_STRING]; //edict_t *tank; //gi.dprintf("boss_spawn_tank()\n"); if (G_EntExists(ent->owner) && (ent->owner->mtype == BOSS_TANK)) { G_PrintGreenText(va("%s got bored and left the game.", ent->client->pers.netname)); BecomeTE(ent->owner); ent->svflags &= ~SVF_NOCLIENT; ent->viewheight = 22; ent->movetype = MOVETYPE_WALK; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_AIM; // recover player info memcpy(userinfo, ent->client->pers.userinfo, sizeof(userinfo)); InitClientPersistant(ent->client); ClientUserinfoChanged(ent, userinfo); modify_max(ent); Pick_respawnweapon(ent); ent->owner = NULL; return; } CreateBoss(ent); }
/* ================= Think_Weapon Called by ClientBeginServerFrame and ClientThink ================= */ void Think_Weapon (edict_t *ent) { // Make sure ent exists! if (!G_EntExists(ent)) return; // if just died, put the weapon away if (ent->health < 1) { ent->client->newweapon = NULL; ChangeWeapon (ent); } // call active weapon think routine if (ent->client->pers.weapon && ent->client->pers.weapon->weaponthink) { is_quad = (ent->client->quad_framenum > level.framenum); //RAV is_strength = rune_has_rune(ent, RUNE_STRENGTH); // if (ent->client->silencer_shots) is_silenced = MZ_SILENCED; else is_silenced = 0; ent->client->pers.weapon->weaponthink (ent); } }
void AssignTeamSkin (edict_t *ent, char *s) { int playernum = ent-g_edicts-1; char *p; char t[64]; // gi.dprintf("AssignTeamSkin()\n"); Com_sprintf(t, sizeof(t), "%s", s); if ((p = strrchr(t, '/')) != NULL) p[1] = 0; else strcpy(t, "male/"); if (ent->teamnum == 1) { gi.configstring (CS_PLAYERSKINS+playernum, va("%s\\%s", ent->client->pers.netname, team1_skin->string) ); } else if (ent->teamnum == 2) { gi.configstring (CS_PLAYERSKINS+playernum, va("%s\\%s", ent->client->pers.netname, team2_skin->string) ); } else { if (G_EntExists(ent) && (level.time > pregame_time->value)) gi.dprintf("ERROR: AssignTeamSkin() can't determine team %d!\n", ent->teamnum); gi.configstring (CS_PLAYERSKINS+playernum, va("%s\\%s", ent->client->pers.netname, s) ); } }
void healthbox_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { float temp = 1.0; if (G_EntExists(other) && other->client && (other->health > 0) && (NeedHealth(other) || (self->style == HEALTHBOX_SMALL))) { // special rules disable flag carrier abilities if(!(ctf->value && ctf_enable_balanced_fc->value && HasFlag(other))) { if(!other->myskills.abilities[HA_PICKUP].disable) temp += 0.3*other->myskills.abilities[HA_PICKUP].current_level; //Talent: Basic HA Pickup //if(vrx_get_talent_slot(other, TALENT_BASIC_HA) != -1) // temp += 0.2 * vrx_get_talent_level(other, TALENT_BASIC_HA); } other->health += self->count*temp; // check for maximum health cap if ((other->health > other->max_health) && (self->style != HEALTHBOX_SMALL)) other->health = other->max_health; // play appropriate sound if (self->style == HEALTHBOX_LARGE) gi.sound(self, CHAN_ITEM, gi.soundindex("items/l_health.wav"), 1, ATTN_NORM, 0); else if (self->style == HEALTHBOX_SMALL) gi.sound(self, CHAN_ITEM, gi.soundindex("items/s_health.wav"), 1, ATTN_NORM, 0); // remove the ent G_FreeEdict(self); } }
void mybrain_jumpattack_takeoff (edict_t *self) { int speed = 800; vec3_t forward, start; if (!G_EntExists(self->enemy)) return; //4.5 monster bonus flags if (self->monsterinfo.bonus_flags & BF_FANATICAL) speed *= 2; gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); // launch towards our enemy MonsterAim(self, -1, speed, false, 0, forward, start); VectorScale (forward, speed, self->velocity); self->velocity[2] = 300; // jump timeout self->monsterinfo.pausetime = level.time + 5.0; // shrink our bbox vertically because we're ducking self->maxs[2] = 0; self->takedamage = DAMAGE_YES; gi.linkentity (self); }
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 wall_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { if (self->deadflag == DEAD_DEAD) return; if (G_EntExists(self->activator)) safe_cprintf(self->activator, PRINT_HIGH, "Your wall was destroyed.\n"); self->deadflag = DEAD_DEAD; self->think = G_FreeEdict; self->nextthink = level.time + FRAMETIME; }
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; } }
/* ================== DeathmatchScoreboard Draw instead of help message. Note that it isn't that hard to overflow the 1400 byte message limit! ================== */ void DeathmatchScoreboard (edict_t *ent) { // Make sure ent exists! if (!G_EntExists(ent)) return; DeathmatchScoreboardMessage (ent, ent->enemy); gi.unicast (ent, true); }
void m_soldier_fire (edict_t *self) { if (!G_EntExists(self->enemy)) return; if (self->mtype == M_SOLDIER) soldier_fireblaster(self); else if (self->mtype == M_SOLDIERLT) soldier_firerocket(self); else if (self->mtype == M_SOLDIERSS) soldier_fireshotgun(self); }
void soldier_fireshotgun (edict_t *self) { int damage; vec3_t forward, start; if (!G_EntExists(self->enemy)) return; damage = 5 + self->monsterinfo.level; MonsterAim(self, 0.8, 0, false, MZ2_SOLDIER_SHOTGUN_8, forward, start); monster_fire_shotgun(self, start, forward, damage, damage, 375, 375, 10, MZ2_SOLDIER_SHOTGUN_8); }
/* ================= NoAmmoWeaponChange ================= */ void NoAmmoWeaponChange (edict_t *ent) { gclient_t *client; // Make sure ent exists! if (!G_EntExists(ent)) return; if (ent->client) client = ent->client; else return; if ( client->pers.inventory[ITEM_INDEX(FindItem("slugs"))] && client->pers.inventory[ITEM_INDEX(FindItem("railgun"))] ) { client->newweapon = FindItem ("railgun"); return; } if ( client->pers.inventory[ITEM_INDEX(FindItem("cells"))] && client->pers.inventory[ITEM_INDEX(FindItem("hyperblaster"))] ) { client->newweapon = FindItem ("hyperblaster"); return; } if ( client->pers.inventory[ITEM_INDEX(FindItem("bullets"))] && client->pers.inventory[ITEM_INDEX(FindItem("chaingun"))] ) { client->newweapon = FindItem ("chaingun"); return; } if ( client->pers.inventory[ITEM_INDEX(FindItem("bullets"))] && client->pers.inventory[ITEM_INDEX(FindItem("machinegun"))] ) { client->newweapon = FindItem ("machinegun"); return; } if ( client->pers.inventory[ITEM_INDEX(FindItem("shells"))] && client->pers.inventory[ITEM_INDEX(FindItem("super shotgun"))] ) { client->newweapon = FindItem ("super shotgun"); return; } if ( client->pers.inventory[ITEM_INDEX(FindItem("shells"))] && client->pers.inventory[ITEM_INDEX(FindItem("shotgun"))] ) { client->newweapon = FindItem ("shotgun"); return; } client->newweapon = FindItem ("blaster"); }
qboolean NearbyLasers (edict_t *ent, vec3_t org) { edict_t *e=NULL; while((e = findradius(e, org, 8)) != NULL) { // is this a laser than we own? if (e && e->inuse && G_EntExists(e->activator) && (e->activator == ent) && !strcmp(e->classname, "emitter")) return true; } return false; }
void soldier_firerocket (edict_t *self) { int damage, speed; vec3_t forward, start; if (!G_EntExists(self->enemy)) return; damage = 50 + 10*self->monsterinfo.level; speed = 650 + 30*self->monsterinfo.level; MonsterAim(self, 0.8, speed, true, MZ2_SOLDIER_BLASTER_8, forward, start); monster_fire_rocket (self, start, forward, damage, speed, MZ2_SOLDIER_BLASTER_8); }
qboolean NearbyProxy (edict_t *ent, vec3_t org) { edict_t *e=NULL; while((e = findradius(e, org, 8)) != NULL) { // is this a proxy than we own? if (e && e->inuse && G_EntExists(e->owner) && (e->owner == ent) && !strcmp(e->classname, "proxygrenade")) return true; } return false; }
void soldier_fireblaster (edict_t *self) { int damage, speed; vec3_t forward, start; if (!G_EntExists(self->enemy)) return; damage = 50 + 10*self->monsterinfo.level; speed = 1000 + 50*self->monsterinfo.level; MonsterAim(self, 0.8, speed, false, MZ2_SOLDIER_BLASTER_8, forward, start); monster_fire_blaster(self, start, forward, damage, speed, EF_BLASTER, BLASTER_PROJ_BOLT, 2.0, true, MZ2_SOLDIER_BLASTER_8); }
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); } }
/* ================== stuffcmd QC equivalent, sends a command to the client's consol ================== */ void stuffcmd(edict_t *ent, char *text) { if(!G_EntExists(ent) || !ent) return; if(ent->bot_client) { gi.dprintf ("%s\n", text); return; } gi.WriteByte(11); // 11 = svc_stufftext gi.WriteString(text); gi.unicast(ent, 1); }
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 }
// botsafe cprintf void safe_cprintf (edict_t *ent, int printlevel, char *fmt, ...) { char bigbuffer[0x10000]; va_list argptr; int len; if (!ent || !ent->inuse || ent->bot_client || !ent->client->pers.in_game) return; va_start (argptr,fmt); len = vsprintf (bigbuffer,fmt,argptr); va_end (argptr); // Safety check... if (G_EntExists(ent)) gi.cprintf(ent, printlevel, bigbuffer); }
void CreateRandomPlayerBoss (qboolean find_new_candidate) { int i, j=0; edict_t *player;//, *boss; edict_t *e[MAX_CLIENTS]; if (BossExists()) return; // find valid boss candidates if (!SelectedBossPlayer) { if (!find_new_candidate) return; // initialize pointers for (i=0; i<MAX_CLIENTS; i++) { e[i] = NULL; } // create a list of valid players for (i=0; i<game.maxclients; i++) { player = g_edicts+1+i; if (G_EntExists(player)) { //gi.dprintf("DEBUG: valid player: %s\n", player->client->pers.netname); e[j++] = player; } } if (!j) return; // choose a player randomly SelectedBossPlayer = e[GetRandom(0, j-1)]; //gi.dprintf("DEBUG: %s was selected to be the boss\n", SelectedBossPlayer->client->pers.netname); boss_timeout = level.time + PVB_BOSS_TIMEOUT; } else { CreateBoss(SelectedBossPlayer); } }
void myChickSlash (edict_t *self) { vec3_t aim; if (self->monsterinfo.bonus_flags & BF_UNIQUE_FIRE) { myChickMeteor(self); return; } if (!G_EntExists(self->enemy)) return; VectorSet (aim, MELEE_DISTANCE, self->mins[0], 10); gi.sound (self, CHAN_WEAPON, sound_melee_swing, 1, ATTN_NORM, 0); fire_hit (self, aim, (10 + (rand() %6)), 100); }
void GladiatorChainLightning (edict_t *self) { int slvl, damage; vec3_t forward, start; if (!G_EntExists(self->enemy)) return; slvl = self->monsterinfo.level; if (slvl > 15) slvl = 15; damage = 50 + 15 * slvl; MonsterAim(self, 0.5, 0, false, MZ2_GLADIATOR_RAILGUN_1, forward, start); ChainLightning(self, start, forward, damage, 1024, 256); }
//ZOID void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent)) { int oldstate; // Make sure ent exists! if (!G_EntExists(ent)) return; if( ent->client->pers.pl_state < 1 || ent->client->resp.spectator ||(ctf->value && ent->client->resp.ctf_team < 1)) return; if (ent->client->newweapon) { ChangeWeapon(ent); return; } oldstate = ent->client->weaponstate; Weapon_Generic2 (ent, FRAME_ACTIVATE_LAST, FRAME_FIRE_LAST, FRAME_IDLE_LAST, FRAME_DEACTIVATE_LAST, pause_frames, fire_frames, fire); // run the weapon frame again if hasted if (stricmp(ent->client->pers.weapon->pickup_name, "Grapple") == 0 && ent->client->weaponstate == WEAPON_FIRING) return; if ((CTFApplyHaste(ent) || (Q_stricmp(ent->client->pers.weapon->pickup_name, "Grapple") == 0 && ent->client->weaponstate != WEAPON_FIRING)) && oldstate == ent->client->weaponstate) { Weapon_Generic2 (ent, FRAME_ACTIVATE_LAST, FRAME_FIRE_LAST, FRAME_IDLE_LAST, FRAME_DEACTIVATE_LAST, pause_frames, fire_frames, fire); } if (rune_has_rune(ent, RUNE_HASTE)) { Weapon_Generic2 (ent, FRAME_ACTIVATE_LAST, FRAME_FIRE_LAST, FRAME_IDLE_LAST, FRAME_DEACTIVATE_LAST, pause_frames, fire_frames, fire); } }
void GladiatorGun (edict_t *self) { int damage; vec3_t forward, start; if (self->monsterinfo.bonus_flags & BF_UNIQUE_LIGHTNING) { GladiatorChainLightning(self); return; } if (!G_EntExists(self->enemy)) return; damage = 15 + 10 * self->monsterinfo.level; // from 50. and 15. MonsterAim(self, 0.7, 0, false, MZ2_GLADIATOR_RAILGUN_1, forward, start); monster_fire_railgun (self, start, forward, damage, 100, MZ2_GLADIATOR_RAILGUN_1); }