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); } }
void BombPerson (edict_t *target, edict_t *owner, float skill_mult) { edict_t *bomb; gi.sound(target, CHAN_ITEM, gi.soundindex("abilities/meteorlaunch.wav"), 1, ATTN_NORM, 0); if ((target->client) && !(target->svflags & SVF_MONSTER)) safe_cprintf(target, PRINT_HIGH, "SOMEONE SET UP US THE BOMB !!\n"); //target->cursed |= CURSE_BOMBS; bomb=G_Spawn(); bomb->solid = SOLID_NOT; bomb->svflags |= SVF_NOCLIENT; VectorClear(bomb->velocity); VectorClear(bomb->mins); VectorClear(bomb->maxs); bomb->owner = owner; bomb->enemy = target; bomb->delay = level.time + BOMBPERSON_DURATION; bomb->dmg = 50 + 10*owner->myskills.abilities[BOMB_SPELL].current_level*skill_mult; bomb->mtype = CURSE_BOMBS; bomb->nextthink = level.time + 1.0; bomb->think = bombperson_think; VectorCopy(target->s.origin, bomb->s.origin); gi.linkentity(bomb); if (!que_addent(target->curses, bomb, BOMBPERSON_DURATION)) G_FreeEdict(bomb); }
void burn_person (edict_t *target, edict_t *owner, int damage) { edict_t *flame; que_t *slot=NULL; if (level.time < pregame_time->value) return; if (que_typeexists(target->curses, CURSE_FROZEN)) return; // attacker is frozen! if (!G_ValidTarget(owner, target, false)) return; while ((slot = que_findtype(target->curses, slot, CURSE_BURN)) != NULL) { if (slot->time-level.time >= 9) return; // only allow 1 burn per second } flame = G_Spawn(); flame->movetype = MOVETYPE_NOCLIP; flame->solid = SOLID_NOT; VectorClear(flame->mins); VectorClear(flame->maxs); flame->owner = owner; flame->enemy = target; flame->mtype = CURSE_BURN; flame->delay = level.time + 10; flame->nextthink = level.time + FRAMETIME; flame->PlasmaDelay = level.time + FRAMETIME; flame->think = fire_think; flame->classname = "fire"; flame->s.sound = gi.soundindex ("weapons/bfg__l1a.wav"); flame->dmg = damage; VectorCopy(target->s.origin, flame->s.origin); gi.linkentity (flame); if (!que_addent(target->curses, flame, 10)) { G_FreeEdict(flame); return; } gi.sound (target, CHAN_ITEM, gi.soundindex ("misc/needlite.wav"), 1, ATTN_NORM, 0); }
void aura_salvation(edict_t *ent) { edict_t *salvation; salvation = G_Spawn(); salvation->movetype = MOVETYPE_NOCLIP; salvation->svflags |= SVF_NOCLIENT; salvation->solid = SOLID_NOT; VectorClear (salvation->mins); VectorClear (salvation->maxs); salvation->owner = ent; salvation->nextthink = level.time + FRAMETIME; salvation->think = salvation_think; salvation->classname = "Aura"; salvation->mtype = AURA_SALVATION; VectorCopy(ent->s.origin, salvation->s.origin); if (!que_addent(ent->auras, salvation, DEFAULT_AURA_DURATION)) G_FreeEdict(salvation); // too many auras }
void PlagueCloud (edict_t *ent, edict_t *target) { edict_t *plague; plague = G_Spawn(); plague->movetype = MOVETYPE_NOCLIP; plague->svflags |= SVF_NOCLIENT; plague->solid = SOLID_NOT; plague->enemy = target; plague->owner = ent; // plague->dmg = damage; plague->nextthink = level.time + FRAMETIME; plague->think = plague_think; plague->classname = "curse"; plague->mtype = CURSE_PLAGUE; VectorCopy(ent->s.origin, plague->s.origin); // abort if the target has too many curses // if (!AddCurse(ent, target, plague, CURSE_PLAGUE, PLAGUE_DURATION)) if (!que_addent(target->curses, plague, PLAGUE_DURATION)) G_FreeEdict(plague); }
void aura_holyfreeze(edict_t *ent) { edict_t *holyfreeze; holyfreeze = G_Spawn(); holyfreeze->movetype = MOVETYPE_NOCLIP; holyfreeze->svflags |= SVF_NOCLIENT; holyfreeze->solid = SOLID_NOT; VectorClear (holyfreeze->mins); VectorClear (holyfreeze->maxs); holyfreeze->owner = ent; holyfreeze->nextthink = level.time + FRAMETIME; holyfreeze->think = holyfreeze_think; holyfreeze->classname = "Aura"; holyfreeze->mtype = AURA_HOLYFREEZE; VectorCopy(ent->s.origin, holyfreeze->s.origin); if (!que_addent(ent->auras, holyfreeze, DEFAULT_AURA_DURATION)) G_FreeEdict(holyfreeze); // too many auras //que_list(ent->auras); }
void holyfreeze_think (edict_t *self) { int radius; edict_t *target=NULL, *curse=NULL; que_t *slot; // check status of owner if (!CheckAuraOwner(self, DEFAULT_AURA_COST)) { //gi.dprintf("aura removed itself\n"); que_removeent(self->owner->auras, self, true); return; } // owner has an active aura que_addent(self->owner->auras, self, DEFAULT_AURA_DURATION); // use cubes if (!(level.framenum % DEFAULT_AURA_FRAMES)) { int cube_cost = DEFAULT_AURA_COST; self->owner->client->pers.inventory[power_cube_index] -= cube_cost; } // 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; // scan for targets radius = DEFAULT_AURA_MIN_RADIUS+self->owner->myskills.abilities[HOLY_FREEZE].current_level*DEFAULT_AURA_ADDON_RADIUS; if (radius > DEFAULT_AURA_MAX_RADIUS) radius = DEFAULT_AURA_MAX_RADIUS; while ((target = findradius (target, self->s.origin, radius)) != NULL) { slot = NULL; if (target == self->owner) continue; if (!G_ValidTarget(self->owner, target, true)) continue; // FIXME: make this into a loop search if we plan to allow // more than one curse of the same type slot = que_findtype(target->curses, slot, AURA_HOLYFREEZE); if (slot && (slot->ent->owner != self->owner)) { // gi.dprintf("already slowed by someone else\n"); continue; // already slowed by someone else } if (!slot) // aura doesn't exist in que or timed out { if (random() > 0.5) gi.sound(target, CHAN_ITEM, gi.soundindex("spells/blue1.wav"), 1, ATTN_NORM, 0); else gi.sound(target, CHAN_ITEM, gi.soundindex("spells/blue3.wav"), 1, ATTN_NORM, 0); } que_addent(target->curses, self, DEFAULT_AURA_DURATION); } }
qboolean curse_add(edict_t *target, edict_t *caster, int type, int curse_level, float duration) { edict_t *curse; que_t *slot = NULL; //Find out if this curse already exists slot = que_findtype(target->curses, NULL, type); if(slot != NULL) { //If the current curse in effect has a level greater than the caster's curse level //if (slot->ent->owner->myskills.abilities[type].current_level > caster->myskills.abilities[type].current_level) if (slot->ent->monsterinfo.level > curse_level)//4.4 //Can't re-curse this player return false; else { //Refresh the curse with the new level/ent/duration return que_addent(target->curses, slot->ent, duration); } } /* //Talent: Evil curse (improves curse duration) talentLevel = getTalentLevel(caster, TALENT_EVIL_CURSE); if(talentLevel > 0) { //Curses only if(type != BLESS && type != HEALING) duration *= 1.0 + 0.25 * talentLevel; } */ //Create the curse entity curse=G_Spawn(); curse->classname = "curse"; curse->solid = SOLID_NOT; curse->svflags |= SVF_NOCLIENT; curse->monsterinfo.level = curse_level;//4.2 curse->monsterinfo.selected_time = duration;//4.2 VectorClear(curse->velocity); VectorClear(curse->mins); VectorClear(curse->maxs); //Set curse type, target, and caster curse->owner = caster; curse->enemy = target; curse->atype = type; //First think in 1/2 a second curse->nextthink = level.time + FRAMETIME; curse->think = curse_think; //Set origin to target's origin VectorCopy(target->s.origin, curse->s.origin); gi.linkentity(curse); //Try to add the curse to the que if (!que_addent(target->curses, curse, duration)) { G_FreeEdict(curse); return false; } return true; }