void openTalentMenu(edict_t *ent, int talentID) { talent_t *talent = &ent->myskills.talents.talent[getTalentSlot(ent, talentID)]; int level = talent->upgradeLevel; int lineCount = 7;//12; if (!ShowMenu(ent)) return; clearmenu(ent); addlinetomenu(ent, "Talent", MENU_GREEN_CENTERED); addlinetomenu(ent, GetTalentString(talentID), MENU_WHITE_CENTERED); addlinetomenu(ent, " ", 0); lineCount += writeTalentDescription(ent, talentID); addlinetomenu(ent, " ", 0); //addlinetomenu(ent, "Current", MENU_GREEN_CENTERED); //writeTalentUpgrade(ent, talentID, level); addlinetomenu(ent, " ", 0); if(talent->upgradeLevel < talent->maxLevel) addlinetomenu(ent, "Upgrade this talent.", -1*(talentID+1)); else addlinetomenu(ent, " ", 0); addlinetomenu(ent, "Previous menu.", talentID+1); setmenuhandler(ent, TalentUpgradeMenu_handler); ent->client->menustorage.currentline = lineCount; showmenu(ent); }
//Returns the talent upgrade level matching talentID. //Returns -1 if there is no matching talent. int getTalentLevel(edict_t *ent, int talentID) { int slot = getTalentSlot(ent, talentID); if(slot < 0) return 0;//-1; return ent->myskills.talents.talent[slot].upgradeLevel; }
void TalentUpgradeMenu_handler(edict_t *ent, int option) { //Not upgrading if(option > 0) { OpenTalentUpgradeMenu(ent, getTalentSlot(ent, option-1)+1); } else //upgrading { upgradeTalent(ent, (option * -1)-1); } }
//Upgrades the talent with a matching talentID void upgradeTalent(edict_t *ent, int talentID) { int slot = getTalentSlot(ent, talentID); talent_t *talent; if(slot == -1) return; talent = &ent->myskills.talents.talent[slot]; // check for conflicting talents if (talentID == TALENT_RAPID_ASSEMBLY && getTalentLevel(ent, TALENT_PRECISION_TUNING) > 0) { gi.cprintf(ent, PRINT_HIGH, "Rapid Assembly can't be combined with Precision Tuning.\n"); return; } if (talentID == TALENT_PRECISION_TUNING && getTalentLevel(ent, TALENT_RAPID_ASSEMBLY) > 0) { gi.cprintf(ent, PRINT_HIGH, "Precision Tuning can't be combined with Rapid Assembly.\n"); return; } if (talentID == TALENT_CORPULENCE && getTalentLevel(ent, TALENT_LIFE_TAP) > 0) { gi.cprintf(ent, PRINT_HIGH, "Corpulence can't be combined with Life Tap.\n"); return; } if (talentID == TALENT_LIFE_TAP && getTalentLevel(ent, TALENT_CORPULENCE) > 0) { gi.cprintf(ent, PRINT_HIGH, "Life Tap can't be combined with Corpulence.\n"); return; } if(talent->upgradeLevel == talent->maxLevel) { gi.cprintf(ent, PRINT_HIGH, "You can not upgrade this talent any further.\n"); return; } if(ent->myskills.talents.talentPoints < 1) { gi.cprintf(ent, PRINT_HIGH, "You do not have enough talent points.\n"); return; } //We can upgrade. talent->upgradeLevel++; ent->myskills.talents.talentPoints--; gi.cprintf(ent, PRINT_HIGH, va("%s upgraded to level %d/%d.\n", GetTalentString(talent->id), talent->upgradeLevel, talent->maxLevel)); gi.cprintf(ent, PRINT_HIGH, va("Talent points remaining: %d\n", ent->myskills.talents.talentPoints)); savePlayer(ent); }
//Returns the talent upgrade level matching talentID. //Returns -1 if there is no matching talent. int getTalentLevel(edict_t *ent, int talentID) { int slot = getTalentSlot(ent, talentID); if(slot < 0) { if (!ent->client) // so it's a morphed player? if (ent->owner && ent->owner->inuse && ent->owner->client) { slot = getTalentSlot(ent->owner, talentID); ent = ent->owner; }else if (ent->activator && ent->activator->inuse && ent->activator->client) { slot = getTalentSlot(ent->activator, talentID); ent = ent->activator; } if(slot < 0) // still doesn't exist? k return 0; } //;//-1; return ent->myskills.talents.talent[slot].upgradeLevel; }
//Talent: Frost Nova void Cmd_FrostNova_f (edict_t *ent, float skill_mult, float cost_mult) { int slot = getTalentSlot(ent, TALENT_FROST_NOVA); talent_t *talent; if (slot == -1) return; talent = &ent->myskills.talents.talent[slot]; if(talent->upgradeLevel > 0) { if(talent->delay < level.time) { Cmd_Nova_f(ent, talent->upgradeLevel, skill_mult, cost_mult); talent->delay = level.time + 2.2; // 2 second recharge. } else safe_cprintf(ent, PRINT_HIGH, va("You can't cast another frost nova for %0.1f seconds.\n", talent->delay - level.time)); } else { safe_cprintf(ent, PRINT_HIGH, "You must upgrade frost nova before you can use it.\n"); } }
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_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); }