Merge branch 'master' into web_interface

This commit is contained in:
KimLS
2014-08-11 13:51:11 -07:00
22 changed files with 1213 additions and 47 deletions
+5
View File
@@ -249,6 +249,7 @@
#define CORPSEDRAG_BEGIN 4064 //You begin to drag %1.
#define CORPSEDRAG_STOPALL 4065 //You stop dragging the corpses.
#define CORPSEDRAG_STOP 4066 //You stop dragging the corpse.
#define TARGET_TOO_CLOSE 4602 //You are too close to your target. Get farther away.
#define WHOALL_NO_RESULTS 5029 //There are no players in EverQuest that match those who filters.
#define PETITION_NO_DELETE 5053 //You do not have a petition in the queue.
#define PETITION_DELETED 5054 //Your petition was successfully deleted.
@@ -316,6 +317,10 @@
#define PET_NOT_FOCUSING 9263 //No longer focusing on one target, Master.
#define PET_NOT_CASTING 9264 //Not casting spells, Master.
#define PET_CASTING 9291 //Casting spells normally, Master.
#define NO_CAST_IN_COMBAT 9190 //You can not cast this spell while in combat.
#define NO_CAST_OUT_OF_COMBAT 9191 //You can not cast this spell while out of combat.
#define NO_ABILITY_IN_COMBAT 9192 //You can not use this ability while in combat.
#define NO_ABILITY_OUT_OF_COMBAT 9194 //You can not use this ability while out of combat.
#define AE_RAMPAGE 11015 //%1 goes on a WILD RAMPAGE!
#define FACE_ACCEPTED 12028 //Facial features accepted.
#define SPELL_LEVEL_TO_LOW 12048 //You will have to achieve level %1 before you can scribe the %2.
+1 -1
View File
@@ -311,7 +311,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
hitBonus += (attacker->CastToNPC()->GetAccuracyRating() / 10.0f); //Modifier from database
if(skillinuse == SkillArchery)
hitBonus -= hitBonus*(RuleR(Combat, ArcheryHitPenalty)*100.0f);
hitBonus -= hitBonus*RuleR(Combat, ArcheryHitPenalty);
//Calculate final chance to hit
chancetohit += ((chancetohit * (hitBonus - avoidanceBonus)) / 100.0f);
+9 -1
View File
@@ -740,6 +740,8 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
float dist = caster->GetAOERange(spell_id);
float dist2 = dist * dist;
float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range;
float dist_targ = 0;
bool bad = IsDetrimentalSpell(spell_id);
bool isnpc = caster->IsNPC();
@@ -755,7 +757,11 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
continue;
if (curmob == caster && !affect_caster) //watch for caster too
continue;
if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
dist_targ = center->DistNoRoot(*curmob);
if (dist_targ > dist2) //make sure they are in range
continue;
if (dist_targ < min_range2) //make sure they are in range
continue;
if (isnpc && curmob->IsNPC()) { //check npc->npc casting
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
@@ -786,6 +792,8 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
continue;
}
curmob->CalcSpellPowerDistanceMod(spell_id, dist_targ);
//if we get here... cast the spell.
if (IsTargetableAESpell(spell_id) && bad) {
if (iCounter < MAX_TARGETS_ALLOWED) {
+5 -5
View File
@@ -4552,7 +4552,7 @@ Mob *EntityList::GetClosestMobByBodyType(Mob *sender, bodyType BodyType)
return ClosestMob;
}
void EntityList::GetTargetsForConeArea(Mob *start, uint32 radius, uint32 height, std::list<Mob*> &m_list)
void EntityList::GetTargetsForConeArea(Mob *start, float min_radius, float radius, float height, std::list<Mob*> &m_list)
{
auto it = mob_list.begin();
while (it != mob_list.end()) {
@@ -4561,15 +4561,15 @@ void EntityList::GetTargetsForConeArea(Mob *start, uint32 radius, uint32 height,
++it;
continue;
}
int32 x_diff = ptr->GetX() - start->GetX();
int32 y_diff = ptr->GetY() - start->GetY();
int32 z_diff = ptr->GetZ() - start->GetZ();
float x_diff = ptr->GetX() - start->GetX();
float y_diff = ptr->GetY() - start->GetY();
float z_diff = ptr->GetZ() - start->GetZ();
x_diff *= x_diff;
y_diff *= y_diff;
z_diff *= z_diff;
if ((x_diff + y_diff) <= (radius * radius))
if ((x_diff + y_diff) <= (radius * radius) && (x_diff + y_diff) >= (min_radius * min_radius))
if(z_diff <= (height * height))
m_list.push_back(ptr);
+1 -1
View File
@@ -406,7 +406,7 @@ public:
void GetObjectList(std::list<Object*> &o_list);
void GetDoorsList(std::list<Doors*> &d_list);
void GetSpawnList(std::list<Spawn2*> &d_list);
void GetTargetsForConeArea(Mob *start, uint32 radius, uint32 height, std::list<Mob*> &m_list);
void GetTargetsForConeArea(Mob *start, float min_radius, float radius, float height, std::list<Mob*> &m_list);
void DepopAll(int NPCTypeID, bool StartSpawnTimer = true);
+3 -1
View File
@@ -658,6 +658,7 @@ void Group::CastGroupSpell(Mob* caster, uint16 spell_id) {
range = caster->GetAOERange(spell_id);
float range2 = range*range;
float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range;
// caster->SpellOnTarget(spell_id, caster);
@@ -673,7 +674,8 @@ void Group::CastGroupSpell(Mob* caster, uint16 spell_id) {
else if(members[z] != nullptr)
{
distance = caster->DistNoRoot(*members[z]);
if(distance <= range2) {
if(distance <= range2 && distance >= min_range2) {
members[z]->CalcSpellPowerDistanceMod(spell_id, distance);
caster->SpellOnTarget(spell_id, members[z]);
#ifdef GROUP_BUFF_PETS
if(members[z]->GetPet() && members[z]->HasPetAffinity() && !members[z]->GetPet()->IsCharmed())
+6 -1
View File
@@ -567,20 +567,25 @@ void HateList::SpellCast(Mob *caster, uint32 spell_id, float range)
//So keep a list of entity ids and look up after
std::list<uint32> id_list;
range = range * range;
float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range;
float dist_targ = 0;
auto iterator = list.begin();
while (iterator != list.end())
{
tHateEntry *h = (*iterator);
if(range > 0)
{
if(caster->DistNoRoot(*h->ent) <= range)
dist_targ = caster->DistNoRoot(*h->ent);
if(dist_targ <= range && dist_targ >= min_range2)
{
id_list.push_back(h->ent->GetID());
h->ent->CalcSpellPowerDistanceMod(spell_id, dist_targ);
}
}
else
{
id_list.push_back(h->ent->GetID());
h->ent->CalcSpellPowerDistanceMod(spell_id, 0, caster);
}
++iterator;
}
+1
View File
@@ -184,6 +184,7 @@ Mob::Mob(const char* in_name,
has_numhits = false;
has_MGB = false;
has_ProjectIllusion = false;
SpellPowerDistanceMod = 0;
if(in_aa_title>0)
aa_title = in_aa_title;
+4
View File
@@ -615,6 +615,9 @@ public:
bool ImprovedTaunt();
bool TryRootFadeByDamage(int buffslot, Mob* attacker);
int16 GetSlowMitigation() const {return slow_mitigation;}
void CalcSpellPowerDistanceMod(uint16 spell_id, float range, Mob* caster = nullptr);
inline int16 GetSpellPowerDistanceMod() const { return SpellPowerDistanceMod; };
inline void SetSpellPowerDistanceMod(int16 value) { SpellPowerDistanceMod = value; };
void ModSkillDmgTaken(SkillUseTypes skill_num, int value);
int16 GetModSkillDmgTaken(const SkillUseTypes skill_num);
@@ -1114,6 +1117,7 @@ protected:
bool has_numhits;
bool has_MGB;
bool has_ProjectIllusion;
int16 SpellPowerDistanceMod;
// Bind wound
Timer bindwound_timer;
+28 -2
View File
@@ -186,6 +186,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
buffs[buffslot].numhits = numhit;
}
if (!IsPowerDistModSpell(spell_id))
SetSpellPowerDistanceMod(0);
// iterate through the effects in the spell
for (i = 0; i < EFFECT_COUNT; i++)
{
@@ -198,6 +201,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if(spell_id == SPELL_LAY_ON_HANDS && caster && caster->GetAA(aaImprovedLayOnHands))
effect_value = GetMaxHP();
if (GetSpellPowerDistanceMod())
effect_value = effect_value*(GetSpellPowerDistanceMod()/100);
#ifdef SPELL_EFFECT_SPAM
effect_desc[0] = 0;
#endif
@@ -2705,7 +2711,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if (buffslot >= 0)
break;
if(IsCasting() && MakeRandomInt(0, 100) <= spells[spell_id].base[i])
if(!spells[spell_id].uninterruptable && IsCasting() && MakeRandomInt(0, 100) <= spells[spell_id].base[i])
InterruptSpell();
break;
@@ -6444,4 +6450,24 @@ bool Mob::CheckSpellCategory(uint16 spell_id, int category_id, int effect_id){
return false;
}
void Mob::CalcSpellPowerDistanceMod(uint16 spell_id, float range, Mob* caster)
{
if (IsPowerDistModSpell(spell_id)){
float distance = 0;
if (caster && !range)
distance = caster->CalculateDistance(GetX(), GetY(), GetZ());
else
distance = sqrt(range);
float dm_range = spells[spell_id].max_dist - spells[spell_id].min_dist;
float dm_mod_interval = spells[spell_id].max_dist_mod - spells[spell_id].min_dist_mod;
float dist_from_min = distance - spells[spell_id].min_dist;
float mod = spells[spell_id].min_dist_mod + (dist_from_min * (dm_mod_interval/dm_range));
mod *= 100.0f;
SetSpellPowerDistanceMod(static_cast<int>(mod));
}
}
+84 -9
View File
@@ -1034,7 +1034,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot,
mlog(SPELLS__CASTING, "Checking Interruption: spell x: %f spell y: %f cur x: %f cur y: %f channelchance %f channeling skill %d\n", GetSpellX(), GetSpellY(), GetX(), GetY(), channelchance, GetSkill(SkillChanneling));
if(MakeRandomFloat(0, 100) > channelchance) {
if(!spells[spell_id].uninterruptable && MakeRandomFloat(0, 100) > channelchance) {
mlog(SPELLS__CASTING_ERR, "Casting of %d canceled: interrupted.", spell_id);
InterruptSpell();
return;
@@ -1384,6 +1384,52 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
return false;
}
//Must be out of combat. (If Beneficial checks casters combat state, Deterimental checks targets)
if (!spells[spell_id].InCombat && spells[spell_id].OutofCombat){
if (IsDetrimentalSpell(spell_id)) {
if ( (spell_target->IsNPC() && spell_target->IsEngaged()) ||
(spell_target->IsClient() && spell_target->CastToClient()->GetAggroCount())){
Message_StringID(13,SPELL_NO_EFFECT); //Unsure correct string
return false;
}
}
else if (IsBeneficialSpell(spell_id)) {
if ( (IsNPC() && IsEngaged()) ||
(IsClient() && CastToClient()->GetAggroCount())){
if (IsDiscipline(spell_id))
Message_StringID(13,NO_ABILITY_IN_COMBAT);
else
Message_StringID(13,NO_CAST_IN_COMBAT);
return false;
}
}
}
//Must be in combat. (If Beneficial checks casters combat state, Deterimental checks targets)
else if (spells[spell_id].InCombat && !spells[spell_id].OutofCombat){
if (IsDetrimentalSpell(spell_id)) {
if ( (spell_target->IsNPC() && !spell_target->IsEngaged()) ||
(spell_target->IsClient() && !spell_target->CastToClient()->GetAggroCount())){
Message_StringID(13,SPELL_NO_EFFECT); //Unsure correct string
return false;
}
}
else if (IsBeneficialSpell(spell_id)) {
if ( (IsNPC() && !IsEngaged()) ||
(IsClient() && !CastToClient()->GetAggroCount())){
if (IsDiscipline(spell_id))
Message_StringID(13,NO_ABILITY_OUT_OF_COMBAT);
else
Message_StringID(13,NO_CAST_OUT_OF_COMBAT);
return false;
}
}
}
switch (targetType)
{
// single target spells
@@ -1734,6 +1780,24 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
break;
}
case ST_PetMaster:
{
Mob *owner = nullptr;
if (IsPet())
owner = GetOwner();
else if ((IsNPC() && CastToNPC()->GetSwarmOwner()))
owner = entity_list.GetMobID(CastToNPC()->GetSwarmOwner());
if (!owner)
return false;
spell_target = owner;
CastAction = SingleTarget;
break;
}
default:
{
mlog(SPELLS__CASTING_ERR, "I dont know Target Type: %d Spell: (%d) %s", spells[spell_id].targettype, spell_id, spells[spell_id].name);
@@ -1863,12 +1927,21 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
//casting a spell on somebody but ourself, make sure they are in range
float dist2 = DistNoRoot(*spell_target);
float range2 = range * range;
float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range;
if(dist2 > range2) {
//target is out of range.
mlog(SPELLS__CASTING, "Spell %d: Spell target is out of range (squared: %f > %f)", spell_id, dist2, range2);
Message_StringID(13, TARGET_OUT_OF_RANGE);
return(false);
}
else if (dist2 < min_range2){
//target is too close range.
mlog(SPELLS__CASTING, "Spell %d: Spell target is too close (squared: %f < %f)", spell_id, dist2, min_range2);
Message_StringID(13, TARGET_TOO_CLOSE);
return(false);
}
spell_target->CalcSpellPowerDistanceMod(spell_id, dist2);
}
//
@@ -2052,7 +2125,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
std::list<Mob*> targets_in_range;
std::list<Mob*>::iterator iter;
entity_list.GetTargetsForConeArea(this, spells[spell_id].aoerange, spells[spell_id].aoerange / 2, targets_in_range);
entity_list.GetTargetsForConeArea(this, spells[spell_id].min_range, spells[spell_id].aoerange, spells[spell_id].aoerange / 2, targets_in_range);
iter = targets_in_range.begin();
while(iter != targets_in_range.end())
{
@@ -2068,16 +2141,20 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
if((heading_to_target >= angle_start && heading_to_target <= 360.0f) ||
(heading_to_target >= 0.0f && heading_to_target <= angle_end))
{
if(CheckLosFN(spell_target))
if(CheckLosFN((*iter)) || spells[spell_id].npc_no_los){
(*iter)->CalcSpellPowerDistanceMod(spell_id, 0, this);
SpellOnTarget(spell_id, spell_target, false, true, resist_adjust);
}
}
}
else
{
if(heading_to_target >= angle_start && heading_to_target <= angle_end)
{
if(CheckLosFN((*iter)))
if(CheckLosFN((*iter)) || spells[spell_id].npc_no_los){
(*iter)->CalcSpellPowerDistanceMod(spell_id, 0, this);
SpellOnTarget(spell_id, (*iter), false, true, resist_adjust);
}
}
}
++iter;
@@ -4625,12 +4702,10 @@ void Mob::Stun(int duration)
if(stunned && stunned_timer.GetRemainingTime() > uint32(duration))
return;
if(casting_spell_id) {
int persistent_casting = spellbonuses.PersistantCasting + itembonuses.PersistantCasting;
if(IsClient())
persistent_casting += aabonuses.PersistantCasting;
if(IsValidSpell(casting_spell_id) && !spells[casting_spell_id].uninterruptable) {
int persistent_casting = spellbonuses.PersistantCasting + itembonuses.PersistantCasting + aabonuses.PersistantCasting;
if(MakeRandomInt(1,99) > persistent_casting)
if(MakeRandomInt(0,99) > persistent_casting)
InterruptSpell();
}