void wormhole_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (!other || !other->inuse) return; // point to monster's pilot if (PM_MonsterHasPilot(other)) other = other->activator; if ((other == self->creator) || IsAlly(self->creator, other)) { float time; // can't enter wormhole with the flag if (HasFlag(other)) return; // can't enter wormhole while being hurt if (other->lasthurt + DAMAGE_ESCAPE_DELAY > level.time) return; // can't enter wormhole while cursed (this includes healing, bless) if (que_typeexists(other->curses, -1)) return; // can't stay in wormhole long if we're warring if (SPREE_WAR == true && SPREE_DUDE == other) time = 10.0; else time = BLACKHOLE_EXIT_TIME; // reset railgun sniper frames other->client->refire_frames = 0; VortexRemovePlayerSummonables(other); V_RestoreMorphed(other, 50); // un-morph other->flags |= FL_WORMHOLE; other->movetype = MOVETYPE_NOCLIP; other->svflags |= SVF_NOCLIENT; other->client->wormhole_time = level.time + BLACKHOLE_EXIT_TIME; // must exit wormhole by this time self->nextthink = level.time + FRAMETIME; // close immediately } }
void Cmd_PlayerToParasite_f (edict_t *ent) { int para_cubecost = PARASITE_INIT_COST; if (debuginfo->value) gi.dprintf("DEBUG: %s just called Cmd_PlayerToParasite_f()\n", ent->client->pers.netname); // try to switch back if (ent->mtype || PM_PlayerHasMonster(ent)) { // don't let a player-tank unmorph if they are cocooned if (ent->owner && ent->owner->inuse && ent->owner->movetype == MOVETYPE_NONE) return; if (que_typeexists(ent->curses, 0)) { gi.cprintf(ent, PRINT_HIGH, "You can't morph while cursed!\n"); return; } V_RestoreMorphed(ent, 0); return; } //Talent: Morphing if(getTalentSlot(ent, TALENT_MORPHING) != -1) para_cubecost *= 1.0 - 0.25 * getTalentLevel(ent, TALENT_MORPHING); // if (!G_CanUseAbilities(ent, ent->myskills.abilities[BLOOD_SUCKER].current_level, para_cubecost)) // return; if (!V_CanUseAbilities(ent, BLOOD_SUCKER, para_cubecost, true)) return; if (HasFlag(ent)) { gi.cprintf(ent, PRINT_HIGH, "Can't morph while carrying flag!\n"); return; } V_ModifyMorphedHealth(ent, M_MYPARASITE, true); ent->wait = level.time + 0.5;// can't attack immediately ent->client->pers.inventory[power_cube_index] -= para_cubecost; ent->client->ability_delay = level.time + PARASITE_DELAY; ent->mtype = M_MYPARASITE; ent->s.modelindex = gi.modelindex ("models/monsters/parasite/tris.md2"); ent->s.modelindex2 = 0; ent->s.skinnum = 0; // decloak ent->svflags &= ~SVF_NOCLIENT; ent->client->cloaking = false; ent->client->cloakable = 0; ent->maxs[2] = 8; ent->viewheight = 0; ent->client->refire_frames = 0; // reset charged weapon ent->client->weapon_mode = 0; // reset weapon mode lasersight_off(ent); gi.sound (ent, CHAN_WEAPON, gi.soundindex("spells/morph.wav") , 1, ATTN_NORM, 0); }
void Cmd_PlayerToMedic_f (edict_t *ent) { vec3_t boxmin, boxmax; trace_t tr; int cost = MEDIC_INIT_COST; //Talent: More Ammo int talentLevel = getTalentLevel(ent, TALENT_MORE_AMMO); if (debuginfo->value) gi.dprintf("DEBUG: %s just called Cmd_PlayerToMedic_f()\n", ent->client->pers.netname); // try to switch back if (ent->mtype || PM_PlayerHasMonster(ent)) { // don't let a player-tank unmorph if they are cocooned if (ent->owner && ent->owner->inuse && ent->owner->movetype == MOVETYPE_NONE) return; if (que_typeexists(ent->curses, 0)) { safe_cprintf(ent, PRINT_HIGH, "You can't morph while cursed!\n"); return; } V_RestoreMorphed(ent, 0); return; } //Talent: Morphing if(getTalentSlot(ent, TALENT_MORPHING) != -1) cost *= 1.0 - 0.25 * getTalentLevel(ent, TALENT_MORPHING); // if (!G_CanUseAbilities(ent, ent->myskills.abilities[MEDIC].current_level, cost)) // return; if (!V_CanUseAbilities(ent, MEDIC, cost, true)) return; if (HasFlag(ent)) { safe_cprintf(ent, PRINT_HIGH, "Can't morph while carrying flag!\n"); return; } // make sure don't get stuck in a wall VectorSet (boxmin, -24, -24, -24); VectorSet (boxmax, 24, 24, 32); tr = gi.trace(ent->s.origin, boxmin, boxmax, ent->s.origin, ent, MASK_SHOT); if (tr.fraction<1) { safe_cprintf(ent, PRINT_HIGH, "Not enough room to morph!\n"); return; } V_ModifyMorphedHealth(ent, MORPH_MEDIC, true); VectorCopy(boxmin, ent->mins); VectorCopy(boxmax, ent->maxs); ent->monsterinfo.attack_finished = level.time + 0.5;// can't attack immediately ent->client->pers.inventory[power_cube_index] -= cost; ent->client->ability_delay = level.time + MEDIC_DELAY; ent->mtype = MORPH_MEDIC; ent->s.modelindex = gi.modelindex ("models/monsters/medic/tris.md2"); ent->s.modelindex2 = 0; if (!ent->myskills.administrator) ent->s.skinnum = 0; else ent->s.skinnum = 2; // commander // set maximum hyperblaster ammo ent->myskills.abilities[MEDIC].max_ammo = MEDIC_HB_INITIAL_AMMO+MEDIC_HB_ADDON_AMMO *ent->myskills.abilities[MEDIC].current_level; // Talent: More Ammo // increases ammo 10% per talent level if(talentLevel > 0) ent->myskills.abilities[MEDIC].max_ammo *= 1.0 + 0.1*talentLevel; // give them some starting ammo ent->myskills.abilities[MEDIC].ammo = MEDIC_HB_START_AMMO; ent->client->refire_frames = 0; // reset charged weapon ent->client->weapon_mode = 0; // reset weapon mode lasersight_off(ent); gi.sound (ent, CHAN_WEAPON, gi.soundindex("spells/morph.wav") , 1, ATTN_NORM, 0); }
void Cmd_PlayerToBerserk_f (edict_t *ent) { int cost = BERSERK_COST; if (debuginfo->value) gi.dprintf("DEBUG: %s just called Cmd_PlayerToBerserk_f()\n", ent->client->pers.netname); // try to switch back if (ent->mtype || PM_PlayerHasMonster(ent)) { // don't let a player-tank unmorph if they are cocooned if (ent->owner && ent->owner->inuse && ent->owner->movetype == MOVETYPE_NONE) return; if (que_typeexists(ent->curses, 0)) { safe_cprintf(ent, PRINT_HIGH, "You can't morph while cursed!\n"); return; } V_RestoreMorphed(ent, 0); return; } //Talent: Morphing if (vrx_get_talent_slot(ent, TALENT_MORPHING) != -1) cost *= 1.0 - 0.25 * vrx_get_talent_level(ent, TALENT_MORPHING); if (!V_CanUseAbilities(ent, BERSERK, cost, true)) return; if (HasFlag(ent) && !hw->value) { safe_cprintf(ent, PRINT_HIGH, "Can't morph while carrying flag!\n"); return; } V_ModifyMorphedHealth(ent, MORPH_BERSERK, true); ent->monsterinfo.attack_finished = level.time + 0.5;// can't attack immediately ent->client->pers.inventory[power_cube_index] -= cost; ent->client->ability_delay = level.time + BERSERK_DELAY; ent->mtype = MORPH_BERSERK; ent->s.modelindex = gi.modelindex ("models/monsters/berserk/tris.md2"); ent->s.modelindex2 = 0; ent->s.skinnum = 0; // undo crouching / ducked state // try asking their client to get up stuffcmd(ent, "-movedown\n"); // if their client ignores the command, force them up if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) { ent->client->ps.pmove.pm_flags &= ~PMF_DUCKED; ent->viewheight = 22; ent->maxs[2] += 28; } ent->client->refire_frames = 0; // reset charged weapon ent->client->weapon_mode = 0; // reset weapon mode ent->client->pers.weapon = NULL; ent->client->ps.gunindex = 0; lasersight_off(ent); gi.sound(ent, CHAN_WEAPON, gi.soundindex("abilities/morph.wav"), 1, ATTN_NORM, 0); }