int32 NPC::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) { //Quest scale all NPC spell damage via $npc->SetSpellFocusDMG(value) //DoT Damage - Mob::DoBuffTic [spell_effects.cpp] / Direct Damage Mob::SpellEffect [spell_effects.cpp] int32 dmg = value; if (target) { value += dmg*target->GetVulnerability(this, spell_id, 0)/100; if (spells[spell_id].buffduration == 0) value -= target->GetFcDamageAmtIncoming(this, spell_id); else value -= target->GetFcDamageAmtIncoming(this, spell_id)/spells[spell_id].buffduration; } value += dmg*SpellFocusDMG/100; if (AI_HasSpellsEffects()){ int16 chance = 0; int ratio = 0; if (spells[spell_id].buffduration == 0) { chance += spellbonuses.CriticalSpellChance + spellbonuses.FrenziedDevastation; if (chance && MakeRandomInt(1,100) <= chance){ ratio += spellbonuses.SpellCritDmgIncrease + spellbonuses.SpellCritDmgIncNoStack; value += (value*ratio)/100; entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits, OTHER_CRIT_BLAST, GetCleanName(), itoa(-value)); } } else { chance += spellbonuses.CriticalDoTChance; if (chance && MakeRandomInt(1,100) <= chance){ ratio += spellbonuses.DotCritDmgIncrease; value += (value*ratio)/100; } } } return value; }
void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration) { Corpse *CorpseToUse = nullptr; CorpseToUse = entity_list.GetClosestCorpse(this, nullptr); if(!CorpseToUse) return; //assuming we have pets in our table; we take the first pet as a base type. const NPCType *base_type = database.LoadNPCTypesData(500); auto make_npc = new NPCType; memcpy(make_npc, base_type, sizeof(NPCType)); //combat stats make_npc->AC = ((GetLevel() * 7) + 550); make_npc->ATK = GetLevel(); make_npc->max_dmg = (GetLevel() * 4) + 2; make_npc->min_dmg = 1; //base stats make_npc->current_hp = (GetLevel() * 55); make_npc->max_hp = (GetLevel() * 55); make_npc->STR = 85 + (GetLevel() * 3); make_npc->STA = 85 + (GetLevel() * 3); make_npc->DEX = 85 + (GetLevel() * 3); make_npc->AGI = 85 + (GetLevel() * 3); make_npc->INT = 85 + (GetLevel() * 3); make_npc->WIS = 85 + (GetLevel() * 3); make_npc->CHA = 85 + (GetLevel() * 3); make_npc->MR = 25; make_npc->FR = 25; make_npc->CR = 25; make_npc->DR = 25; make_npc->PR = 25; //level class and gender make_npc->level = GetLevel(); make_npc->class_ = CorpseToUse->class_; make_npc->race = CorpseToUse->race; make_npc->gender = CorpseToUse->gender; make_npc->loottable_id = 0; //name char NewName[64]; sprintf(NewName, "%s`s Animated Corpse", GetCleanName()); strcpy(make_npc->name, NewName); //appearance make_npc->beard = CorpseToUse->beard; make_npc->beardcolor = CorpseToUse->beardcolor; make_npc->eyecolor1 = CorpseToUse->eyecolor1; make_npc->eyecolor2 = CorpseToUse->eyecolor2; make_npc->haircolor = CorpseToUse->haircolor; make_npc->hairstyle = CorpseToUse->hairstyle; make_npc->helmtexture = CorpseToUse->helmtexture; make_npc->luclinface = CorpseToUse->luclinface; make_npc->size = CorpseToUse->size; make_npc->texture = CorpseToUse->texture; //cast stuff.. based off of PEQ's if you want to change //it you'll have to mod this code, but most likely //most people will be using PEQ style for the first //part of their spell list; can't think of any smooth //way to do this //some basic combat mods here too since it's convienent switch(CorpseToUse->class_) { case CLERIC: make_npc->npc_spells_id = 1; break; case WIZARD: make_npc->npc_spells_id = 2; break; case NECROMANCER: make_npc->npc_spells_id = 3; break; case MAGICIAN: make_npc->npc_spells_id = 4; break; case ENCHANTER: make_npc->npc_spells_id = 5; break; case SHAMAN: make_npc->npc_spells_id = 6; break; case DRUID: make_npc->npc_spells_id = 7; break; case PALADIN: //SPECATK_TRIPLE strcpy(make_npc->special_abilities, "6,1"); make_npc->current_hp = make_npc->current_hp * 150 / 100; make_npc->max_hp = make_npc->max_hp * 150 / 100; make_npc->npc_spells_id = 8; break; case SHADOWKNIGHT: strcpy(make_npc->special_abilities, "6,1"); make_npc->current_hp = make_npc->current_hp * 150 / 100; make_npc->max_hp = make_npc->max_hp * 150 / 100; make_npc->npc_spells_id = 9; break; case RANGER: strcpy(make_npc->special_abilities, "7,1"); make_npc->current_hp = make_npc->current_hp * 135 / 100; make_npc->max_hp = make_npc->max_hp * 135 / 100; make_npc->npc_spells_id = 10; break; case BARD: strcpy(make_npc->special_abilities, "6,1"); make_npc->current_hp = make_npc->current_hp * 110 / 100; make_npc->max_hp = make_npc->max_hp * 110 / 100; make_npc->npc_spells_id = 11; break; case BEASTLORD: strcpy(make_npc->special_abilities, "7,1"); make_npc->current_hp = make_npc->current_hp * 110 / 100; make_npc->max_hp = make_npc->max_hp * 110 / 100; make_npc->npc_spells_id = 12; break; case ROGUE: strcpy(make_npc->special_abilities, "7,1"); make_npc->max_dmg = make_npc->max_dmg * 150 /100; make_npc->current_hp = make_npc->current_hp * 110 / 100; make_npc->max_hp = make_npc->max_hp * 110 / 100; break; case MONK: strcpy(make_npc->special_abilities, "7,1"); make_npc->max_dmg = make_npc->max_dmg * 150 /100; make_npc->current_hp = make_npc->current_hp * 135 / 100; make_npc->max_hp = make_npc->max_hp * 135 / 100; break; case WARRIOR: case BERSERKER: strcpy(make_npc->special_abilities, "7,1"); make_npc->max_dmg = make_npc->max_dmg * 150 /100; make_npc->current_hp = make_npc->current_hp * 175 / 100; make_npc->max_hp = make_npc->max_hp * 175 / 100; break; default: make_npc->npc_spells_id = 0; break; } make_npc->loottable_id = 0; make_npc->merchanttype = 0; make_npc->d_melee_texture1 = 0; make_npc->d_melee_texture2 = 0; auto npca = new NPC(make_npc, 0, GetPosition(), GravityBehavior::Water); if(!npca->GetSwarmInfo()){ auto nSI = new SwarmPet; npca->SetSwarmInfo(nSI); npca->GetSwarmInfo()->duration = new Timer(duration*1000); } else{ npca->GetSwarmInfo()->duration->Start(duration*1000); } npca->StartSwarmTimer(duration * 1000); npca->GetSwarmInfo()->owner_id = GetID(); //give the pet somebody to "love" if(target != nullptr){ npca->AddToHateList(target, 100000); npca->GetSwarmInfo()->target = target->GetID(); } //gear stuff, need to make sure there's //no situation where this stuff can be duped for (int x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invslot::EQUIPMENT_END; x++) { uint32 sitem = 0; sitem = CorpseToUse->GetWornItem(x); if(sitem){ const EQEmu::ItemData * itm = database.GetItem(sitem); npca->AddLootDrop(itm, &npca->itemlist, 1, 1, 255, true, true); } } //we allocated a new NPC type object, give the NPC ownership of that memory if(make_npc != nullptr) npca->GiveNPCTypeData(make_npc); entity_list.AddNPC(npca, true, true); //the target of these swarm pets will take offense to being cast on... if(target != nullptr) target->AddToHateList(this, 1, 0); }
int32 NPC::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) { //Scale all NPC spell healing via SetSpellFocusHeal(value) value += value*SpellFocusHeal/100; if (target) { value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id); value += value*target->GetHealRate(spell_id, this)/100; } //Allow for critical heal chance if NPC is loading spell effect bonuses. if (AI_HasSpellsEffects()){ if(spells[spell_id].buffduration < 1) { if(spellbonuses.CriticalHealChance && (MakeRandomInt(0,99) < spellbonuses.CriticalHealChance)) { value = value*2; entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits, OTHER_CRIT_HEAL, GetCleanName(), itoa(value)); } } else if(spellbonuses.CriticalHealOverTime && (MakeRandomInt(0,99) < spellbonuses.CriticalHealOverTime)) { value = value*2; } } return value; }
void NPC::Gate() { entity_list.MessageClose_StringID(this, true, 200, MT_Spells, GATES, GetCleanName()); Mob::Gate(); }