void printDmgList (edict_t *self) { int i; float percent; dmglist_t *slot; for (i=0; i < MAX_CLIENTS; i++) { slot = &self->monsterinfo.dmglist[i]; if (self->monsterinfo.dmglist[i].player) { percent = 100*(slot->damage/GetTotalBossDamage(self)); if (self->client) gi.dprintf("(%s) slot %d: %s, %.0f damage (%.1f%c)\n", self->client->pers.netname, i, slot->player->client->pers.netname, slot->damage, percent, '%'); else if (self->mtype) gi.dprintf("(%s) slot %d: %s, %.0f damage (%.1f%c)\n", V_GetMonsterName(self), i, slot->player->client->pers.netname, slot->damage, percent, '%'); else gi.dprintf("(%s) slot %d: %s, %.0f damage (%.1f%c)\n", self->classname, i, slot->player->client->pers.netname, slot->damage, percent, '%'); } } }
void CurseMessage (edict_t *caster, edict_t *target, int type, float duration, qboolean isCurse) { char *curseName = GetCurseName(type); char *typeName; if (isCurse) typeName = "cursed"; else typeName = "blessed"; //Notify the target if ((target->client) && !(target->svflags & SVF_MONSTER)) { gi.cprintf(target, PRINT_HIGH, "**You have been %s with %s for %0.1f second(s)**\n", typeName, curseName, duration); if (caster && caster->client) gi.cprintf(caster, PRINT_HIGH, "%s %s with %s for %0.1f second(s)\n", typeName, target->myskills.player_name, curseName, duration); } else if (target->mtype) { if (PM_MonsterHasPilot(target)) { gi.cprintf(target->activator, PRINT_HIGH, "**You have been %s with %s for %0.1f second(s)**\n", typeName, curseName, duration); if (caster && caster->client) gi.cprintf(caster, PRINT_HIGH, "%s %s with %s for %0.1f second(s)\n", typeName, target->activator->client->pers.netname, curseName, duration); return; } if (caster && caster->client) gi.cprintf(caster, PRINT_HIGH, "%s %s with %s for %0.1f second(s)\n", typeName, V_GetMonsterName(target), curseName, duration); } else if (caster && caster->client) gi.cprintf(caster, PRINT_HIGH, "%s %s with %s for %0.1f second(s)\n", typeName, target->classname, curseName, duration); }
void minisentry_think (edict_t *self) { float modifier, temp; que_t *slot=NULL; if (!self->owner || !self->owner->inuse) { minisentry_remove(self); return; } else if (self->removetime > 0) { qboolean converted=false; if (self->flags & FL_CONVERTED) converted = true; if (level.time > self->removetime) { // if we were converted, try to convert back to previous owner if (converted && self->prev_owner && self->prev_owner->inuse) { if (!ConvertOwner(self->prev_owner, self, 0, false)) { minisentry_remove(self); return; } } else { minisentry_remove(self); return; } } // warn the converted monster's current owner else if (converted && self->creator && self->creator->inuse && self->creator->client && (level.time > self->removetime-5) && !(level.framenum%10)) safe_cprintf(self->creator, PRINT_HIGH, "%s conversion will expire in %.0f seconds\n", V_GetMonsterName(self), self->removetime-level.time); } // sentry is stunned if (self->holdtime > level.time) { M_SetEffects(self); self->nextthink = level.time + FRAMETIME; return; } // toggle sentry spotlight if (level.daytime && self->flashlight) FL_make(self); else if (!level.daytime && !self->flashlight) FL_make(self); // is the sentry slowed by holy freeze? temp = self->yaw_speed; slot = que_findtype(self->curses, slot, AURA_HOLYFREEZE); if (slot) { modifier = 1 / (1 + 0.1 * slot->ent->owner->myskills.abilities[HOLY_FREEZE].current_level); if (modifier < 0.25) modifier = 0.25; self->yaw_speed *= modifier; } // chill effect slows sentry rotation speed if(self->chill_time > level.time) self->yaw_speed *= 1 / (1 + CHILL_DEFAULT_BASE + CHILL_DEFAULT_ADDON * self->chill_level); if (!self->enemy) { minisentry_regenerate(self); if (minisentry_findtarget(self)) minisentry_attack(self); else minisentry_idle(self); } else { if (G_ValidTarget(self, self->enemy, true) && (entdist(self, self->enemy)<=SENTRY_ATTACK_RANGE)) { minisentry_attack(self); } else { self->enemy = NULL; if (minisentry_findtarget(self)) { minisentry_attack(self); } else { minisentry_idle(self); VectorCopy(self->move_angles, self->s.angles); } } } self->yaw_speed = temp; // restore original yaw speed M_SetEffects(self); self->nextthink = level.time + FRAMETIME; }
void PlayerID_SetStats (edict_t *player, edict_t *target, qboolean chasecam) { int health, armor=0, ammo=0, lvl=0; float dist; char name[24], buf[100]; int team_status=0; dist = entdist(player, target); health = target->health; team_status = OnSameTeam(player, target); if (target->client) { sprintf(name, target->client->pers.netname); armor = target->client->pers.inventory[body_armor_index]; ammo = target->client->pers.inventory[target->client->ammo_index]; lvl = target->myskills.level; } else { name[0] = 0; // name if (PM_MonsterHasPilot(target)) strcat(name, target->owner->client->pers.netname); else if (target->mtype) strcat(name, V_GetMonsterName(target)); else strcat(name, target->classname); // armor if (target->monsterinfo.power_armor_type) armor = target->monsterinfo.power_armor_power; // ammo if (target->mtype && (target->mtype == M_SENTRY || target->mtype == M_AUTOCANNON)) ammo = target->light_level; // level if (target->monsterinfo.level > 0) lvl = target->monsterinfo.level; } // initialize the string by terminating it, required by strcat() buf[0] = 0; if (chasecam) strcat(buf, va("Chasing ")); // build the string strcat(buf, va("%s ", name)); if (team_status > 1) V_SetColorText(buf); strcat(buf, va("(%d) ", lvl)); if (!chasecam) { // newbies get a very basic free ID if (player->myskills.abilities[ID].current_level < 1) { if (M_IgnoreInferiorTarget(target, player) && !team_status) strcat(buf, "is ignoring you"); } else { strcat(buf, va("@ %.0f", dist)); strcat(buf, va(": %dh", health)); if (armor) strcat(buf, va("/%da", armor)); if (ammo) strcat(buf, va("/%d", ammo)); } } // set stat to the configstring's index // this is the index to the string we just made player->client->ps.stats[STAT_CHASE] = CS_GENERAL + 1; gi.WriteByte (13);//svc_configstring gi.WriteShort (CS_GENERAL + 1); gi.WriteString (buf);// put the string in the configstring list gi.unicast (player, false);// announce to this player only }
void Cmd_Deflect_f(edict_t *ent) { float duration; edict_t *target = ent; // default target is self if (!V_CanUseAbilities(ent, DEFLECT, DEFLECT_COST, true)) return; duration = DEFLECT_INITIAL_DURATION + DEFLECT_ADDON_DURATION * ent->myskills.abilities[DEFLECT].current_level; // bless the tank instead of the noclipped player if (PM_PlayerHasMonster(ent)) target = target->owner; //Blessing self? if (Q_strcasecmp(gi.argv(1), "self") == 0) { if (!curse_add(target, ent, DEFLECT, 0, duration)) { gi.cprintf(ent, PRINT_HIGH, "Unable to bless self.\n"); return; } //target = ent; } else { target = curse_Attack(ent, DEFLECT, 512.0, duration, false); } if (target != NULL) { que_t *slot = NULL; //Finish casting the spell ent->client->ability_delay = level.time + DEFLECT_DELAY; ent->client->pers.inventory[power_cube_index] -= DEFLECT_COST; // ent->myskills.abilities[DEFLECT].delay = level.time + duration + DEFLECT_DELAY; //Change the curse think to the deflect think slot = que_findtype(target->curses, NULL, DEFLECT); if (slot) { slot->ent->think = deflect_think; slot->ent->nextthink = level.time + FRAMETIME; slot->ent->random = DEFLECT_INITIAL_PROJECTILE_CHANCE+DEFLECT_ADDON_HITSCAN_CHANCE*ent->myskills.abilities[DEFLECT].current_level; if (slot->ent->random > DEFLECT_MAX_PROJECTILE_CHANCE) slot->ent->random = DEFLECT_MAX_PROJECTILE_CHANCE; } //Notify the target if (target == ent) { gi.cprintf(target, PRINT_HIGH, "You have been blessed with deflect for %0.1f seconds!\n", duration); } else if ((target->client) && !(target->svflags & SVF_MONSTER)) { gi.cprintf(target, PRINT_HIGH, "You have been blessed with deflect for %0.1f seconds!\n\n", duration); gi.cprintf(ent, PRINT_HIGH, "Blessed %s with deflect for %0.1f seconds.\n", target->myskills.player_name, duration); } else { gi.cprintf(ent, PRINT_HIGH, "Blessed %s with deflect for %0.1f seconds.\n", V_GetMonsterName(target), duration); } //Play the spell sound! gi.sound(target, CHAN_ITEM, gi.soundindex("curses/prayer.wav"), 1, ATTN_NORM, 0); } }