Merge from master

This commit is contained in:
KimLS
2014-12-20 19:32:00 -08:00
32 changed files with 675 additions and 483 deletions
+17
View File
@@ -2107,6 +2107,18 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
#endif //BOTS
}
if(give_exp && give_exp->IsTempPet() && give_exp->IsPetOwnerClient()) {
if (give_exp->IsNPC() && give_exp->CastToNPC()->GetSwarmOwner()){
Mob* temp_owner = nullptr;
temp_owner = entity_list.GetMobID(give_exp->CastToNPC()->GetSwarmOwner());
if (temp_owner)
give_exp = temp_owner;
}
}
int PlayerCount = 0; // QueryServ Player Counting
Client *give_exp_client = nullptr;
@@ -3937,6 +3949,11 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
return;
}
if (DivineAura()) {
mlog(COMBAT__PROCS, "Procs canceled, Divine Aura is in effect.");
return;
}
if(!weapon_g) {
TrySpellProc(nullptr, (const Item_Struct*)nullptr, on);
return;
+3 -3
View File
@@ -538,9 +538,9 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAu
}
void Client::CalcEdibleBonuses(StatBonuses* newbon) {
#if EQDEBUG >= 11
std::cout<<"Client::CalcEdibleBonuses(StatBonuses* newbon)"<<std::endl;
#endif
//#if EQDEBUG >= 11
// std::cout<<"Client::CalcEdibleBonuses(StatBonuses* newbon)"<<std::endl;
//#endif
// Search player slots for skill=14(food) and skill=15(drink)
uint32 i;
+1 -1
View File
@@ -11276,7 +11276,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
if(!results.Success())
return;
int slotmaterial = Inventory::CalcMaterialFromSlot(setslot);
uint8 slotmaterial = Inventory::CalcMaterialFromSlot(setslot);
c->GetTarget()->CastToBot()->SendWearChange(slotmaterial);
}
else {
+12 -26
View File
@@ -2685,8 +2685,11 @@ void Client::SetMaterial(int16 in_slot, uint32 item_id) {
const Item_Struct* item = database.GetItem(item_id);
if (item && (item->ItemClass==ItemClassCommon))
{
uint32 matslot = Inventory::CalcMaterialFromSlot(in_slot);
m_pp.item_material[matslot] = GetEquipmentMaterial(matslot);
uint8 matslot = Inventory::CalcMaterialFromSlot(in_slot);
if (matslot != _MaterialInvalid)
{
m_pp.item_material[matslot] = GetEquipmentMaterial(matslot);
}
}
}
@@ -3016,31 +3019,14 @@ void Client::SetTint(int16 in_slot, uint32 color) {
// Still need to reconcile bracer01 versus bracer02
void Client::SetTint(int16 in_slot, Color_Struct& color) {
if (in_slot==MainHead)
m_pp.item_tint[MaterialHead].color=color.color;
else if (in_slot==MainArms)
m_pp.item_tint[MaterialArms].color=color.color;
else if (in_slot==MainWrist1)
m_pp.item_tint[MaterialWrist].color=color.color;
/*
// non-live behavior
else if (in_slot==SLOT_BRACER02)
m_pp.item_tint[MaterialWrist].color=color.color;
*/
else if (in_slot==MainHands)
m_pp.item_tint[MaterialHands].color=color.color;
else if (in_slot==MainPrimary)
m_pp.item_tint[MaterialPrimary].color=color.color;
else if (in_slot==MainSecondary)
m_pp.item_tint[MaterialSecondary].color=color.color;
else if (in_slot==MainChest)
m_pp.item_tint[MaterialChest].color=color.color;
else if (in_slot==MainLegs)
m_pp.item_tint[MaterialLegs].color=color.color;
else if (in_slot==MainFeet)
m_pp.item_tint[MaterialFeet].color=color.color;
database.SaveCharacterMaterialColor(this->CharacterID(), in_slot, color.color);
uint8 matslot = Inventory::CalcMaterialFromSlot(in_slot);
if (matslot != _MaterialInvalid)
{
m_pp.item_tint[matslot].color = color.color;
database.SaveCharacterMaterialColor(this->CharacterID(), in_slot, color.color);
}
}
void Client::SetHideMe(bool flag)
+8 -4
View File
@@ -1428,8 +1428,12 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
/* Set item material tint */
for (int i = EmuConstants::MATERIAL_BEGIN; i <= EmuConstants::MATERIAL_END; i++)
if (m_pp.item_tint[i].rgb.use_tint == 1 || m_pp.item_tint[i].rgb.use_tint == 255)
m_pp.item_tint[i].rgb.use_tint = 0xFF;
{
if (m_pp.item_tint[i].rgb.use_tint == 1 || m_pp.item_tint[i].rgb.use_tint == 255)
{
m_pp.item_tint[i].rgb.use_tint = 0xFF;
}
}
if (level){ level = m_pp.level; }
@@ -5745,7 +5749,7 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
}
else
{
std::list<int> pathlist = zone->pathing->FindRoute(Start, End);
std::deque<int> pathlist = zone->pathing->FindRoute(Start, End);
if (pathlist.size() == 0)
{
@@ -5784,7 +5788,7 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
p.z = GetZ();
points.push_back(p);
for (std::list<int>::iterator Iterator = pathlist.begin(); Iterator != pathlist.end(); ++Iterator)
for (auto Iterator = pathlist.begin(); Iterator != pathlist.end(); ++Iterator)
{
if ((*Iterator) == -1) // Teleporter
{
+1 -1
View File
@@ -2664,7 +2664,7 @@ void EntityList::FindPathsToAllNPCs()
while (it != npc_list.end()) {
Map::Vertex Node0 = zone->pathing->GetPathNodeCoordinates(0, false);
Map::Vertex Dest(it->second->GetX(), it->second->GetY(), it->second->GetZ());
std::list<int> Route = zone->pathing->FindRoute(Node0, Dest);
std::deque<int> Route = zone->pathing->FindRoute(Node0, Dest);
if (Route.size() == 0)
printf("Unable to find a route to %s\n", it->second->GetName());
else
+1 -1
View File
@@ -158,7 +158,7 @@ void Mob::CalculateNewFearpoint()
Map::Vertex CurrentPosition(GetX(), GetY(), GetZ());
std::list<int> Route = zone->pathing->FindRoute(CurrentPosition, Loc);
std::deque<int> Route = zone->pathing->FindRoute(CurrentPosition, Loc);
if(Route.size() > 0)
{
+94 -85
View File
@@ -542,6 +542,8 @@ float Mob::_GetMovementSpeed(int mod) const
// http://everquest.allakhazam.com/db/item.html?item=1721;page=1;howmany=50#m10822246245352
if (IsRooted())
return 0.0f;
else if (IsPseudoRooted())
return 0.00001f;
float speed_mod = runspeed;
@@ -2795,10 +2797,17 @@ uint32 Mob::GetEquipmentColor(uint8 material_slot) const
{
const Item_Struct *item;
item = database.GetItem(GetEquipment(material_slot));
if(item != 0)
if (armor_tint[material_slot])
{
return item->Color;
return armor_tint[material_slot];
}
else
{
item = database.GetItem(GetEquipment(material_slot));
if (item != 0)
{
return item->Color;
}
}
return 0;
@@ -5323,98 +5332,98 @@ int32 Mob::GetSpellStat(uint32 spell_id, const char *identifier, uint8 slot)
}
if (slot < 16){
if (id == "classes") {stat = spells[spell_id].classes[slot]; }
else if (id == "dieties") {stat = spells[spell_id].deities[slot];}
if (id == "classes") {return spells[spell_id].classes[slot]; }
else if (id == "dieties") {return spells[spell_id].deities[slot];}
}
if (slot < 12){
if (id == "base") {stat = spells[spell_id].base[slot];}
else if (id == "base2") {stat = spells[spell_id].base2[slot];}
else if (id == "max") {stat = spells[spell_id].max[slot];}
else if (id == "formula") {spells[spell_id].formula[slot];}
else if (id == "effectid") {spells[spell_id].effectid[slot];}
if (id == "base") {return spells[spell_id].base[slot];}
else if (id == "base2") {return spells[spell_id].base2[slot];}
else if (id == "max") {return spells[spell_id].max[slot];}
else if (id == "formula") {return spells[spell_id].formula[slot];}
else if (id == "effectid") {return spells[spell_id].effectid[slot];}
}
if (slot < 4){
if (id == "components") { spells[spell_id].components[slot];}
else if (id == "component_counts") {spells[spell_id].component_counts[slot];}
else if (id == "NoexpendReagent") {spells[spell_id].NoexpendReagent[slot];}
if (id == "components") { return spells[spell_id].components[slot];}
else if (id == "component_counts") { return spells[spell_id].component_counts[slot];}
else if (id == "NoexpendReagent") {return spells[spell_id].NoexpendReagent[slot];}
}
if (id == "range") {stat = static_cast<int32>(spells[spell_id].range); }
else if (id == "aoerange") {stat = static_cast<int32>(spells[spell_id].aoerange);}
else if (id == "pushback") {stat = static_cast<int32>(spells[spell_id].pushback);}
else if (id == "pushup") {stat = static_cast<int32>(spells[spell_id].pushup);}
else if (id == "cast_time") {stat = spells[spell_id].cast_time;}
else if (id == "recovery_time") {stat = spells[spell_id].recovery_time;}
else if (id == "recast_time") {stat = spells[spell_id].recast_time;}
else if (id == "buffdurationformula") {stat = spells[spell_id].buffdurationformula;}
else if (id == "buffduration") {stat = spells[spell_id].buffduration;}
else if (id == "AEDuration") {stat = spells[spell_id].AEDuration;}
else if (id == "mana") {stat = spells[spell_id].mana;}
if (id == "range") {return static_cast<int32>(spells[spell_id].range); }
else if (id == "aoerange") {return static_cast<int32>(spells[spell_id].aoerange);}
else if (id == "pushback") {return static_cast<int32>(spells[spell_id].pushback);}
else if (id == "pushup") {return static_cast<int32>(spells[spell_id].pushup);}
else if (id == "cast_time") {return spells[spell_id].cast_time;}
else if (id == "recovery_time") {return spells[spell_id].recovery_time;}
else if (id == "recast_time") {return spells[spell_id].recast_time;}
else if (id == "buffdurationformula") {return spells[spell_id].buffdurationformula;}
else if (id == "buffduration") {return spells[spell_id].buffduration;}
else if (id == "AEDuration") {return spells[spell_id].AEDuration;}
else if (id == "mana") {return spells[spell_id].mana;}
//else if (id == "LightType") {stat = spells[spell_id].LightType;} - Not implemented
else if (id == "goodEffect") {stat = spells[spell_id].goodEffect;}
else if (id == "Activated") {stat = spells[spell_id].Activated;}
else if (id == "resisttype") {stat = spells[spell_id].resisttype;}
else if (id == "targettype") {stat = spells[spell_id].targettype;}
else if (id == "basedeiff") {stat = spells[spell_id].basediff;}
else if (id == "skill") {stat = spells[spell_id].skill;}
else if (id == "zonetype") {stat = spells[spell_id].zonetype;}
else if (id == "EnvironmentType") {stat = spells[spell_id].EnvironmentType;}
else if (id == "TimeOfDay") {stat = spells[spell_id].TimeOfDay;}
else if (id == "CastingAnim") {stat = spells[spell_id].CastingAnim;}
else if (id == "SpellAffectIndex") {stat = spells[spell_id].SpellAffectIndex; }
else if (id == "disallow_sit") {stat = spells[spell_id].disallow_sit; }
else if (id == "goodEffect") {return spells[spell_id].goodEffect;}
else if (id == "Activated") {return spells[spell_id].Activated;}
else if (id == "resisttype") {return spells[spell_id].resisttype;}
else if (id == "targettype") {return spells[spell_id].targettype;}
else if (id == "basedeiff") {return spells[spell_id].basediff;}
else if (id == "skill") {return spells[spell_id].skill;}
else if (id == "zonetype") {return spells[spell_id].zonetype;}
else if (id == "EnvironmentType") {return spells[spell_id].EnvironmentType;}
else if (id == "TimeOfDay") {return spells[spell_id].TimeOfDay;}
else if (id == "CastingAnim") {return spells[spell_id].CastingAnim;}
else if (id == "SpellAffectIndex") {return spells[spell_id].SpellAffectIndex; }
else if (id == "disallow_sit") {return spells[spell_id].disallow_sit; }
//else if (id == "spellanim") {stat = spells[spell_id].spellanim; } - Not implemented
else if (id == "uninterruptable") {stat = spells[spell_id].uninterruptable; }
else if (id == "ResistDiff") {stat = spells[spell_id].ResistDiff; }
else if (id == "dot_stacking_exemp") {stat = spells[spell_id].dot_stacking_exempt; }
else if (id == "RecourseLink") {stat = spells[spell_id].RecourseLink; }
else if (id == "no_partial_resist") {stat = spells[spell_id].no_partial_resist; }
else if (id == "short_buff_box") {stat = spells[spell_id].short_buff_box; }
else if (id == "descnum") {stat = spells[spell_id].descnum; }
else if (id == "effectdescnum") {stat = spells[spell_id].effectdescnum; }
else if (id == "npc_no_los") {stat = spells[spell_id].npc_no_los; }
else if (id == "reflectable") {stat = spells[spell_id].reflectable; }
else if (id == "bonushate") {stat = spells[spell_id].bonushate; }
else if (id == "EndurCost") {stat = spells[spell_id].EndurCost; }
else if (id == "EndurTimerIndex") {stat = spells[spell_id].EndurTimerIndex; }
else if (id == "IsDisciplineBuf") {stat = spells[spell_id].IsDisciplineBuff; }
else if (id == "HateAdded") {stat = spells[spell_id].HateAdded; }
else if (id == "EndurUpkeep") {stat = spells[spell_id].EndurUpkeep; }
else if (id == "numhitstype") {stat = spells[spell_id].numhitstype; }
else if (id == "numhits") {stat = spells[spell_id].numhits; }
else if (id == "pvpresistbase") {stat = spells[spell_id].pvpresistbase; }
else if (id == "pvpresistcalc") {stat = spells[spell_id].pvpresistcalc; }
else if (id == "pvpresistcap") {stat = spells[spell_id].pvpresistcap; }
else if (id == "spell_category") {stat = spells[spell_id].spell_category; }
else if (id == "can_mgb") {stat = spells[spell_id].can_mgb; }
else if (id == "dispel_flag") {stat = spells[spell_id].dispel_flag; }
else if (id == "MinResist") {stat = spells[spell_id].MinResist; }
else if (id == "MaxResist") {stat = spells[spell_id].MaxResist; }
else if (id == "viral_targets") {stat = spells[spell_id].viral_targets; }
else if (id == "viral_timer") {stat = spells[spell_id].viral_timer; }
else if (id == "NimbusEffect") {stat = spells[spell_id].NimbusEffect; }
else if (id == "directional_start") {stat = static_cast<int32>(spells[spell_id].directional_start); }
else if (id == "directional_end") {stat = static_cast<int32>(spells[spell_id].directional_end); }
else if (id == "not_extendable") {stat = spells[spell_id].not_extendable; }
else if (id == "suspendable") {stat = spells[spell_id].suspendable; }
else if (id == "viral_range") {stat = spells[spell_id].viral_range; }
else if (id == "spellgroup") {stat = spells[spell_id].spellgroup; }
else if (id == "rank") {stat = spells[spell_id].rank; }
else if (id == "powerful_flag") {stat = spells[spell_id].powerful_flag; }
else if (id == "CastRestriction") {stat = spells[spell_id].CastRestriction; }
else if (id == "AllowRest") {stat = spells[spell_id].AllowRest; }
else if (id == "InCombat") {stat = spells[spell_id].InCombat; }
else if (id == "OutofCombat") {stat = spells[spell_id].OutofCombat; }
else if (id == "aemaxtargets") {stat = spells[spell_id].aemaxtargets; }
else if (id == "maxtargets") {stat = spells[spell_id].maxtargets; }
else if (id == "persistdeath") {stat = spells[spell_id].persistdeath; }
else if (id == "min_dist") {stat = static_cast<int32>(spells[spell_id].min_dist); }
else if (id == "min_dist_mod") {stat = static_cast<int32>(spells[spell_id].min_dist_mod); }
else if (id == "max_dist") {stat = static_cast<int32>(spells[spell_id].max_dist); }
else if (id == "min_range") {stat = static_cast<int32>(spells[spell_id].min_range); }
else if (id == "DamageShieldType") {stat = spells[spell_id].DamageShieldType; }
else if (id == "uninterruptable") {return spells[spell_id].uninterruptable; }
else if (id == "ResistDiff") {return spells[spell_id].ResistDiff; }
else if (id == "dot_stacking_exemp") {return spells[spell_id].dot_stacking_exempt; }
else if (id == "RecourseLink") {return spells[spell_id].RecourseLink; }
else if (id == "no_partial_resist") {return spells[spell_id].no_partial_resist; }
else if (id == "short_buff_box") {return spells[spell_id].short_buff_box; }
else if (id == "descnum") {return spells[spell_id].descnum; }
else if (id == "effectdescnum") {return spells[spell_id].effectdescnum; }
else if (id == "npc_no_los") {return spells[spell_id].npc_no_los; }
else if (id == "reflectable") {return spells[spell_id].reflectable; }
else if (id == "bonushate") {return spells[spell_id].bonushate; }
else if (id == "EndurCost") {return spells[spell_id].EndurCost; }
else if (id == "EndurTimerIndex") {return spells[spell_id].EndurTimerIndex; }
else if (id == "IsDisciplineBuf") {return spells[spell_id].IsDisciplineBuff; }
else if (id == "HateAdded") {return spells[spell_id].HateAdded; }
else if (id == "EndurUpkeep") {return spells[spell_id].EndurUpkeep; }
else if (id == "numhitstype") {return spells[spell_id].numhitstype; }
else if (id == "numhits") {return spells[spell_id].numhits; }
else if (id == "pvpresistbase") {return spells[spell_id].pvpresistbase; }
else if (id == "pvpresistcalc") {return spells[spell_id].pvpresistcalc; }
else if (id == "pvpresistcap") {return spells[spell_id].pvpresistcap; }
else if (id == "spell_category") {return spells[spell_id].spell_category; }
else if (id == "can_mgb") {return spells[spell_id].can_mgb; }
else if (id == "dispel_flag") {return spells[spell_id].dispel_flag; }
else if (id == "MinResist") {return spells[spell_id].MinResist; }
else if (id == "MaxResist") {return spells[spell_id].MaxResist; }
else if (id == "viral_targets") {return spells[spell_id].viral_targets; }
else if (id == "viral_timer") {return spells[spell_id].viral_timer; }
else if (id == "NimbusEffect") {return spells[spell_id].NimbusEffect; }
else if (id == "directional_start") {return static_cast<int32>(spells[spell_id].directional_start); }
else if (id == "directional_end") {return static_cast<int32>(spells[spell_id].directional_end); }
else if (id == "not_extendable") {return spells[spell_id].not_extendable; }
else if (id == "suspendable") {return spells[spell_id].suspendable; }
else if (id == "viral_range") {return spells[spell_id].viral_range; }
else if (id == "spellgroup") {return spells[spell_id].spellgroup; }
else if (id == "rank") {return spells[spell_id].rank; }
else if (id == "powerful_flag") {return spells[spell_id].powerful_flag; }
else if (id == "CastRestriction") {return spells[spell_id].CastRestriction; }
else if (id == "AllowRest") {return spells[spell_id].AllowRest; }
else if (id == "InCombat") {return spells[spell_id].InCombat; }
else if (id == "OutofCombat") {return spells[spell_id].OutofCombat; }
else if (id == "aemaxtargets") {return spells[spell_id].aemaxtargets; }
else if (id == "maxtargets") {return spells[spell_id].maxtargets; }
else if (id == "persistdeath") {return spells[spell_id].persistdeath; }
else if (id == "min_dist") {return static_cast<int32>(spells[spell_id].min_dist); }
else if (id == "min_dist_mod") {return static_cast<int32>(spells[spell_id].min_dist_mod); }
else if (id == "max_dist") {return static_cast<int32>(spells[spell_id].max_dist); }
else if (id == "min_range") {return static_cast<int32>(spells[spell_id].min_range); }
else if (id == "DamageShieldType") {return spells[spell_id].DamageShieldType; }
return stat;
}
+1 -1
View File
@@ -1225,7 +1225,7 @@ protected:
Map::Vertex PathingLastPosition;
int PathingLoopCount;
int PathingLastNodeVisited;
std::list<int> Route;
std::deque<int> Route;
LOSType PathingLOSState;
Timer *PathingLOSCheckTimer;
Timer *PathingRouteUpdateTimerShort;
+1 -1
View File
@@ -2751,7 +2751,7 @@ DBnpcspells_Struct* ZoneDatabase::GetNPCSpells(uint32 iDBSpellsID) {
npc_spells_cache[iDBSpellsID]->attack_proc = tmpattack_proc;
npc_spells_cache[iDBSpellsID]->proc_chance = tmpproc_chance;
npc_spells_cache[iDBSpellsID]->range_proc = tmprange_proc;
npc_spells_cache[iDBSpellsID]->rproc_chance = tmpdproc_chance;
npc_spells_cache[iDBSpellsID]->rproc_chance = tmprproc_chance;
npc_spells_cache[iDBSpellsID]->defensive_proc = tmpdefensive_proc;
npc_spells_cache[iDBSpellsID]->dproc_chance = tmpdproc_chance;
npc_spells_cache[iDBSpellsID]->fail_recast = tmppfail_recast;
+2 -1
View File
@@ -476,7 +476,7 @@ void NPC::CheckMinMaxLevel(Mob *them)
if(themlevel < (*cur)->min_level || themlevel > (*cur)->max_level)
{
material = Inventory::CalcMaterialFromSlot((*cur)->equip_slot);
if(material != 0xFF)
if (material != _MaterialInvalid)
SendWearChange(material);
cur = itemlist.erase(cur);
@@ -1942,6 +1942,7 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue)
else if(id == "special_attacks") { NPCSpecialAttacks(val.c_str(), 0, 1); return; }
else if(id == "special_abilities") { ProcessSpecialAbilities(val.c_str()); return; }
else if(id == "attack_speed") { attack_speed = (float)atof(val.c_str()); CalcBonuses(); return; }
else if(id == "attack_delay") { attack_delay = atoi(val.c_str()); CalcBonuses(); return; }
else if(id == "atk") { ATK = atoi(val.c_str()); return; }
else if(id == "accuracy") { accuracy_rating = atoi(val.c_str()); return; }
else if(id == "avoidance") { avoidance_rating = atoi(val.c_str()); return; }
+2
View File
@@ -155,6 +155,7 @@ public:
virtual void RangedAttack(Mob* other);
virtual void ThrowingAttack(Mob* other) { }
int32 GetNumberOfAttacks() const { return attack_count; }
void DoRangedAttackDmg(Mob* other, bool Launch=true, int16 damage_mod=0, int16 chance_mod=0, SkillUseTypes skill=SkillArchery, float speed=4.0f, const char *IDFile = nullptr);
bool DatabaseCastAccepted(int spell_id);
bool IsFactionListAlly(uint32 other_faction);
@@ -259,6 +260,7 @@ public:
uint32 GetMinDMG() const {return min_dmg;}
int16 GetSlowMitigation() const {return slow_mitigation;}
float GetAttackSpeed() const {return attack_speed;}
uint8 GetAttackDelay() const {return attack_delay;}
bool IsAnimal() const { return(bodytype == BT_Animal); }
uint16 GetPetSpellID() const {return pet_spell_id;}
void SetPetSpellID(uint16 amt) {pet_spell_id = amt;}
+20 -22
View File
@@ -205,15 +205,15 @@ Map::Vertex PathManager::GetPathNodeCoordinates(int NodeNumber, bool BestZ)
}
std::list<int> PathManager::FindRoute(int startID, int endID)
std::deque<int> PathManager::FindRoute(int startID, int endID)
{
_log(PATHING__DEBUG, "FindRoute from node %i to %i", startID, endID);
memset(ClosedListFlag, 0, sizeof(int) * Head.PathNodeCount);
std::list<AStarNode> OpenList, ClosedList;
std::deque<AStarNode> OpenList, ClosedList;
std::list<int>Route;
std::deque<int>Route;
AStarNode AStarEntry, CurrentNode;
@@ -251,7 +251,7 @@ std::list<int> PathManager::FindRoute(int startID, int endID)
Route.push_back(endID);
std::list<AStarNode>::iterator RouteIterator;
std::deque<AStarNode>::iterator RouteIterator;
while(CurrentNode.PathNodeID != startID)
{
@@ -300,7 +300,7 @@ std::list<int> PathManager::FindRoute(int startID, int endID)
bool AlreadyInOpenList = false;
std::list<AStarNode>::iterator OpenListIterator, InsertionPoint = OpenList.end();
std::deque<AStarNode>::iterator OpenListIterator, InsertionPoint = OpenList.end();
for(OpenListIterator = OpenList.begin(); OpenListIterator != OpenList.end(); ++OpenListIterator)
{
@@ -350,11 +350,11 @@ bool SortPathNodesByDistance(PathNodeSortStruct n1, PathNodeSortStruct n2)
return n1.Distance < n2.Distance;
}
std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
{
_log(PATHING__DEBUG, "FindRoute(%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f)", Start.x, Start.y, Start.z, End.x, End.y, End.z);
std::list<int> noderoute;
std::deque<int> noderoute;
float CandidateNodeRangeXY = RuleR(Pathing, CandidateNodeRangeXY);
@@ -365,7 +365,7 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
//
int ClosestPathNodeToStart = -1;
std::list<PathNodeSortStruct> SortedByDistance;
std::deque<PathNodeSortStruct> SortedByDistance;
PathNodeSortStruct TempNode;
@@ -382,9 +382,9 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
}
}
SortedByDistance.sort(SortPathNodesByDistance);
std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance);
for(std::list<PathNodeSortStruct>::iterator Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
{
_log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
@@ -420,9 +420,9 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
}
}
SortedByDistance.sort(SortPathNodesByDistance);
std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance);
for(std::list<PathNodeSortStruct>::iterator Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
{
_log(PATHING__DEBUG, "Checking Reachability of Node %i from End Position.", PathNodes[(*Iterator).id].id);
_log(PATHING__DEBUG, " (%8.3f, %8.3f, %8.3f) to (%8.3f, %8.3f, %8.3f)",
@@ -456,7 +456,7 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
{
int CulledNodes = 0;
std::list<int>::iterator First, Second;
std::deque<int>::iterator First, Second;
while((noderoute.size() >= 2) && (CulledNodes < NodesToAttemptToCull))
{
@@ -487,7 +487,7 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
{
int CulledNodes = 0;
std::list<int>::iterator First, Second;
std::deque<int>::iterator First, Second;
while((noderoute.size() >= 2) && (CulledNodes < NodesToAttemptToCull))
{
@@ -611,7 +611,7 @@ void PathManager::MeshTest()
if(j == i)
continue;
std::list<int> Route = FindRoute(PathNodes[i].id, PathNodes[j].id);
std::deque<int> Route = FindRoute(PathNodes[i].id, PathNodes[j].id);
if(Route.size() == 0)
{
@@ -638,7 +638,7 @@ void PathManager::SimpleMeshTest()
for(uint32 j = 1; j < Head.PathNodeCount; ++j)
{
std::list<int> Route = FindRoute(PathNodes[0].id, PathNodes[j].id);
std::deque<int> Route = FindRoute(PathNodes[0].id, PathNodes[j].id);
if(Route.size() == 0)
{
@@ -1103,7 +1103,7 @@ int PathManager::FindNearestPathNode(Map::Vertex Position)
int ClosestPathNodeToStart = -1;
std::list<PathNodeSortStruct> SortedByDistance;
std::deque<PathNodeSortStruct> SortedByDistance;
PathNodeSortStruct TempNode;
@@ -1120,9 +1120,9 @@ int PathManager::FindNearestPathNode(Map::Vertex Position)
}
}
SortedByDistance.sort(SortPathNodesByDistance);
std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance);
for(std::list<PathNodeSortStruct>::iterator Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
{
_log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
@@ -1262,9 +1262,7 @@ void Mob::PrintRoute()
printf("Route is : ");
std::list<int>::iterator Iterator;
for(Iterator = Route.begin(); Iterator !=Route.end(); ++Iterator)
for(auto Iterator = Route.begin(); Iterator !=Route.end(); ++Iterator)
{
printf("%i, ", (*Iterator));
}
+3 -3
View File
@@ -3,7 +3,7 @@
#include "map.h"
#include <list>
#include <deque>
class Client;
class Mob;
@@ -60,8 +60,8 @@ public:
static PathManager *LoadPathFile(const char *ZoneName);
bool loadPaths(FILE *fp);
void PrintPathing();
std::list<int> FindRoute(Map::Vertex Start, Map::Vertex End);
std::list<int> FindRoute(int startID, int endID);
std::deque<int> FindRoute(Map::Vertex Start, Map::Vertex End);
std::deque<int> FindRoute(int startID, int endID);
Map::Vertex GetPathNodeCoordinates(int NodeNumber, bool BestZ = true);
bool CheckLosFN(Map::Vertex a, Map::Vertex b);
+132
View File
@@ -2119,6 +2119,32 @@ XS(XS_NPC_GetAttackSpeed)
XSRETURN(1);
}
XS(XS_NPC_GetAttackDelay); /* prototype to pass -Wmissing-prototypes */
XS(XS_NPC_GetAttackDelay)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: NPC::GetAttackDelay(THIS)");
{
NPC * THIS;
float RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "NPC")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(NPC *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type NPC");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetAttackDelay();
XSprePUSH; PUSHn((double)RETVAL);
}
XSRETURN(1);
}
XS(XS_NPC_GetAccuracyRating); /* prototype to pass -Wmissing-prototypes */
XS(XS_NPC_GetAccuracyRating)
{
@@ -2145,6 +2171,32 @@ XS(XS_NPC_GetAccuracyRating)
XSRETURN(1);
}
XS(XS_NPC_GetAvoidanceRating); /* prototype to pass -Wmissing-prototypes */
XS(XS_NPC_GetAvoidanceRating)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: NPC::GetAvoidanceyRating(THIS)");
{
NPC * THIS;
int32 RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "NPC")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(NPC *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type NPC");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetAvoidanceRating();
XSprePUSH; PUSHu((UV)RETVAL);
}
XSRETURN(1);
}
XS(XS_NPC_GetSpawnKillCount); /* prototype to pass -Wmissing-prototypes */
XS(XS_NPC_GetSpawnKillCount)
{
@@ -2245,6 +2297,81 @@ XS(XS_NPC_GetMerchantProbability) {
XSRETURN(1);
}
XS(XS_NPC_AddMeleeProc);
XS(XS_NPC_AddMeleeProc) {
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: NPC::AddMeleeProc(THIS,spellid,chance)");
{
NPC * THIS;
int spell_id = (int)SvIV(ST(1));
int chance = (int)SvIV(ST(2));
dXSTARG;
if (sv_derived_from(ST(0), "NPC")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(NPC *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type NPC");
if(THIS == NULL)
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
THIS->AddProcToWeapon(spell_id, true, chance);
}
XSRETURN_EMPTY;
}
XS(XS_NPC_AddRangedProc);
XS(XS_NPC_AddRangedProc) {
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: NPC::AddRangedProc(THIS,spellid,chance)");
{
NPC * THIS;
int spell_id = (int)SvIV(ST(1));
int chance = (int)SvIV(ST(2));
dXSTARG;
if (sv_derived_from(ST(0), "NPC")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(NPC *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type NPC");
if(THIS == NULL)
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
THIS->AddDefensiveProc(spell_id,chance);
}
XSRETURN_EMPTY;
}
XS(XS_NPC_AddDefensiveProc);
XS(XS_NPC_AddDefensiveProc) {
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: NPC::AddDefensiveProc(THIS,spellid,chance)");
{
NPC * THIS;
int spell_id = (int)SvIV(ST(1));
int chance = (int)SvIV(ST(2));
dXSTARG;
if (sv_derived_from(ST(0), "NPC")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(NPC *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type NPC");
if(THIS == NULL)
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
THIS->AddProcToWeapon(spell_id, true, chance);
}
XSRETURN_EMPTY;
}
#ifdef __cplusplus
extern "C"
#endif
@@ -2342,11 +2469,16 @@ XS(boot_NPC)
newXSproto(strcpy(buf, "GetSpellFocusHeal"), XS_NPC_GetSpellFocusHeal, file, "$");
newXSproto(strcpy(buf, "GetSlowMitigation"), XS_NPC_GetSlowMitigation, file, "$");
newXSproto(strcpy(buf, "GetAttackSpeed"), XS_NPC_GetAttackSpeed, file, "$");
newXSproto(strcpy(buf, "GetAttackDelay"), XS_NPC_GetAttackDelay, file, "$");
newXSproto(strcpy(buf, "GetAccuracyRating"), XS_NPC_GetAccuracyRating, file, "$");
newXSproto(strcpy(buf, "GetAvoidanceRating"), XS_NPC_GetAvoidanceRating, file, "$");
newXSproto(strcpy(buf, "GetSpawnKillCount"), XS_NPC_GetSpawnKillCount, file, "$");
newXSproto(strcpy(buf, "GetScore"), XS_NPC_GetScore, file, "$");
newXSproto(strcpy(buf, "SetMerchantProbability"), XS_NPC_SetMerchantProbability, file, "$$");
newXSproto(strcpy(buf, "GetMerchantProbability"), XS_NPC_GetMerchantProbability, file, "$");
newXSproto(strcpy(buf, "AddMeleeProc"), XS_NPC_AddMeleeProc, file, "$$$");
newXSproto(strcpy(buf, "AddRangedProc"), XS_NPC_AddRangedProc, file, "$$$");
newXSproto(strcpy(buf, "AddDefensiveProc"), XS_NPC_AddDefensiveProc, file, "$$$");
XSRETURN_YES;
}
+107 -82
View File
@@ -103,6 +103,9 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
if (!who)
return;
if(who->GetInvul() || who->GetSpecialAbility(IMMUNE_MELEE) || who->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE))
return; //-5?
int32 hate = max_damage;
if(hate_override > -1)
hate = hate_override;
@@ -1059,8 +1062,8 @@ bool Mob::TryProjectileAttack(Mob* other, const Item_Struct *item, SkillUseTypes
if(item)
SendItemAnimation(other, item, skillInUse, speed);
else if (IsNPC())
ProjectileAnimation(other, 0,false,speed,0,0,0,CastToNPC()->GetAmmoIDfile(),skillInUse);
//else if (IsNPC())
//ProjectileAnimation(other, 0,false,speed,0,0,0,CastToNPC()->GetAmmoIDfile(),skillInUse);
return true;
}
@@ -1097,12 +1100,19 @@ void Mob::ProjectileAttack()
if (ProjectileAtk[i].hit_increment <= ProjectileAtk[i].increment){
if (target){
if (ProjectileAtk[i].skill == SkillArchery)
DoArcheryAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0,ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_id, nullptr, ProjectileAtk[i].ammo_slot);
else if (ProjectileAtk[i].skill == SkillThrowing)
DoThrowingAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0, ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_slot);
else if (ProjectileAtk[i].skill == SkillConjuration && IsValidSpell(ProjectileAtk[i].wpn_dmg))
SpellOnTarget(ProjectileAtk[i].wpn_dmg, target, false, true, spells[ProjectileAtk[i].wpn_dmg].ResistDiff, true);
if (IsNPC())
CastToNPC()->DoRangedAttackDmg(target, false, ProjectileAtk[i].wpn_dmg,0, static_cast<SkillUseTypes>(ProjectileAtk[i].skill));
else
{
if (ProjectileAtk[i].skill == SkillArchery)
DoArcheryAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0,ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_id, nullptr, ProjectileAtk[i].ammo_slot);
else if (ProjectileAtk[i].skill == SkillThrowing)
DoThrowingAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0, ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_slot);
else if (ProjectileAtk[i].skill == SkillConjuration && IsValidSpell(ProjectileAtk[i].wpn_dmg))
SpellOnTarget(ProjectileAtk[i].wpn_dmg, target, false, true, spells[ProjectileAtk[i].wpn_dmg].ResistDiff, true);
}
}
ProjectileAtk[i].increment = 0;
@@ -1187,14 +1197,8 @@ void NPC::RangedAttack(Mob* other)
attacks = attacks > 0 ? attacks : 1;
for(int i = 0; i < attacks; ++i) {
//if we have SPECATK_RANGED_ATK set then we range attack without weapon or ammo
const Item_Struct* weapon = nullptr;
const Item_Struct* ammo = nullptr;
if(!GetSpecialAbility(SPECATK_RANGED_ATK))
{
//find our bow and ammo return if we can't find them...
return;
}
int sa_min_range = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 4); //Min Range of NPC attack
int sa_max_range = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 1); //Max Range of NPC attack
@@ -1208,16 +1212,11 @@ void NPC::RangedAttack(Mob* other)
if (sa_min_range)
min_range = static_cast<float>(sa_min_range);
mlog(COMBAT__RANGED, "Calculated bow range to be %.1f", max_range);
max_range *= max_range;
if(DistNoRootNoZ(*other) > max_range) {
mlog(COMBAT__RANGED, "Ranged attack out of range...%.2f vs %.2f", DistNoRootNoZ(*other), max_range);
//target is out of range, client does a message
if(DistNoRoot(*other) > max_range)
return;
}
else if(DistNoRootNoZ(*other) < (min_range * min_range))
else if(DistNoRoot(*other) < (min_range * min_range))
return;
if(!other || !IsAttackAllowed(other) ||
IsCasting() ||
@@ -1229,74 +1228,100 @@ void NPC::RangedAttack(Mob* other)
return;
}
SkillUseTypes skillinuse = SkillArchery;
skillinuse = static_cast<SkillUseTypes>(GetRangedSkill());
if(!ammo && !GetAmmoIDfile())
ammo = database.GetItem(8005);
if(ammo)
SendItemAnimation(other, ammo, SkillArchery);
else
ProjectileAnimation(other, 0,false,0,0,0,0,GetAmmoIDfile(),skillinuse);
FaceTarget(other);
if (!other->CheckHitChance(this, skillinuse, MainRange, GetSpecialAbilityParam(SPECATK_RANGED_ATK, 2)))
{
mlog(COMBAT__RANGED, "Ranged attack missed %s.", other->GetName());
other->Damage(this, 0, SPELL_UNKNOWN, skillinuse);
}
else
{
int16 WDmg = GetWeaponDamage(other, weapon);
int16 ADmg = GetWeaponDamage(other, ammo);
int32 TotalDmg = 0;
if(WDmg > 0 || ADmg > 0)
{
mlog(COMBAT__RANGED, "Ranged attack hit %s.", other->GetName());
int32 MaxDmg = max_dmg * RuleR(Combat, ArcheryNPCMultiplier); // should add a field to npc_types
int32 MinDmg = min_dmg * RuleR(Combat, ArcheryNPCMultiplier);
if(RuleB(Combat, UseIntervalAC))
TotalDmg = MaxDmg;
else
TotalDmg = zone->random.Int(MinDmg, MaxDmg);
TotalDmg += TotalDmg * GetSpecialAbilityParam(SPECATK_RANGED_ATK, 3) / 100; //Damage modifier
other->AvoidDamage(this, TotalDmg, false);
other->MeleeMitigation(this, TotalDmg, MinDmg);
if (TotalDmg > 0)
CommonOutgoingHitSuccess(other, TotalDmg, skillinuse);
}
else
TotalDmg = -5;
if (TotalDmg > 0)
other->AddToHateList(this, TotalDmg, 0, false);
else
other->AddToHateList(this, 0, 0, false);
other->Damage(this, TotalDmg, SPELL_UNKNOWN, skillinuse);
if (TotalDmg > 0 && HasSkillProcSuccess() && GetTarget() && !other->HasDied())
TrySkillProc(other, skillinuse, 0, true, MainRange);
}
//try proc on hits and misses
if(other && !other->HasDied())
TrySpellProc(nullptr, (const Item_Struct*)nullptr, other, MainRange);
if (HasSkillProcs() && other && !other->HasDied())
TrySkillProc(other, skillinuse, 0, false, MainRange);
DoRangedAttackDmg(other);
CommonBreakInvisible();
}
}
void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 chance_mod, SkillUseTypes skill, float speed, const char *IDFile) {
if ((other == nullptr ||
(other->HasDied())) ||
HasDied() ||
(!IsAttackAllowed(other)) ||
(other->GetInvul() ||
other->GetSpecialAbility(IMMUNE_MELEE)))
{
return;
}
SkillUseTypes skillInUse = static_cast<SkillUseTypes>(GetRangedSkill());
if (skill != skillInUse)
skillInUse = skill;
if (Launch)
{
const char *ammo = "IT10";
if (IDFile != nullptr)
ammo = IDFile;
else if (GetAmmoIDfile())
ammo = GetAmmoIDfile();
ProjectileAnimation(other, 0,false,speed,0,0,0,ammo,skillInUse);
if (RuleB(Combat, ProjectileDmgOnImpact))
{
TryProjectileAttack(other, nullptr, skillInUse, damage_mod, nullptr, nullptr, 0, speed);
return;
}
}
if (!chance_mod)
chance_mod = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 2);
if (!other->CheckHitChance(this, skillInUse, MainRange, chance_mod))
{
other->Damage(this, 0, SPELL_UNKNOWN, skillInUse);
}
else
{
int32 TotalDmg = 0;
int32 MaxDmg = max_dmg * RuleR(Combat, ArcheryNPCMultiplier); // should add a field to npc_types
int32 MinDmg = min_dmg * RuleR(Combat, ArcheryNPCMultiplier);
if(RuleB(Combat, UseIntervalAC))
TotalDmg = MaxDmg;
else
TotalDmg = zone->random.Int(MinDmg, MaxDmg);
if (!damage_mod)
damage_mod = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 3);//Damage modifier
TotalDmg += TotalDmg * damage_mod / 100;
other->AvoidDamage(this, TotalDmg, false);
other->MeleeMitigation(this, TotalDmg, MinDmg);
if (TotalDmg > 0)
CommonOutgoingHitSuccess(other, TotalDmg, skillInUse);
else
TotalDmg = -5;
if (TotalDmg > 0)
other->AddToHateList(this, TotalDmg, 0, false);
else
other->AddToHateList(this, 0, 0, false);
other->Damage(this, TotalDmg, SPELL_UNKNOWN, skillInUse);
if (TotalDmg > 0 && HasSkillProcSuccess() && !other->HasDied())
TrySkillProc(other, skillInUse, 0, true, MainRange);
}
//try proc on hits and misses
if(other && !other->HasDied())
TrySpellProc(nullptr, (const Item_Struct*)nullptr, other, MainRange);
if (HasSkillProcs() && other && !other->HasDied())
TrySkillProc(other, skillInUse, 0, false, MainRange);
}
uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg) {
uint16 MaxDmg = (((2 * wDmg) * GetDamageTable(SkillThrowing)) / 100);