mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-05 11:26:35 +00:00
NPC Special Attacks should all work right: also huge explanation in changelog.txt
This commit is contained in:
+47
-30
@@ -1095,15 +1095,23 @@ void Mob::AI_Process() {
|
||||
if(DivineAura())
|
||||
return;
|
||||
|
||||
if(GetSpecialAbility(TETHER) || GetSpecialAbility(LEASH)) {
|
||||
if(DistNoRootNoZ(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY()) > pAggroRange*pAggroRange) {
|
||||
if(GetSpecialAbility(TETHER)) {
|
||||
float aggro_range = static_cast<float>(GetSpecialAbilityParam(TETHER, 0));
|
||||
aggro_range = aggro_range > 0.0f ? aggro_range : pAggroRange * pAggroRange;
|
||||
|
||||
if(DistNoRootNoZ(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY()) > aggro_range) {
|
||||
GMMove(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY(), CastToNPC()->GetSpawnPointZ(), CastToNPC()->GetSpawnPointH());
|
||||
if(GetSpecialAbility(LEASH)) {
|
||||
SetHP(GetMaxHP());
|
||||
BuffFadeAll();
|
||||
WipeHateList();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if(GetSpecialAbility(LEASH)) {
|
||||
float aggro_range = static_cast<float>(GetSpecialAbilityParam(LEASH, 0));
|
||||
aggro_range = aggro_range > 0.0f ? aggro_range : pAggroRange * pAggroRange;
|
||||
|
||||
if(DistNoRootNoZ(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY()) > aggro_range) {
|
||||
GMMove(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY(), CastToNPC()->GetSpawnPointZ(), CastToNPC()->GetSpawnPointH());
|
||||
SetHP(GetMaxHP());
|
||||
BuffFadeAll();
|
||||
WipeHateList();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1180,32 +1188,32 @@ void Mob::AI_Process() {
|
||||
flurry_chance = flurry_chance > 0 ? flurry_chance : RuleI(Combat, NPCFlurryChance);
|
||||
|
||||
ExtraAttackOptions opts;
|
||||
int cur = GetSpecialAbilityParam(SPECATK_FLURRY, 1);
|
||||
int cur = GetSpecialAbilityParam(SPECATK_FLURRY, 2);
|
||||
if(cur > 0) {
|
||||
opts.damage_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 2);
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 3);
|
||||
if(cur > 0) {
|
||||
opts.damage_flat = cur;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 3);
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 4);
|
||||
if(cur > 0) {
|
||||
opts.armor_pen_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 4);
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 5);
|
||||
if(cur > 0) {
|
||||
opts.armor_pen_flat = cur;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 5);
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 6);
|
||||
if(cur > 0) {
|
||||
opts.crit_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 6);
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 7);
|
||||
if(cur > 0) {
|
||||
opts.crit_flat = cur;
|
||||
}
|
||||
@@ -1232,32 +1240,32 @@ void Mob::AI_Process() {
|
||||
rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
|
||||
if(MakeRandomInt(0, 99) < rampage_chance) {
|
||||
ExtraAttackOptions opts;
|
||||
int cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 1);
|
||||
int cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 2);
|
||||
if(cur > 0) {
|
||||
opts.damage_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 2);
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 3);
|
||||
if(cur > 0) {
|
||||
opts.damage_flat = cur;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 3);
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 4);
|
||||
if(cur > 0) {
|
||||
opts.armor_pen_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 4);
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 5);
|
||||
if(cur > 0) {
|
||||
opts.armor_pen_flat = cur;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 5);
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 6);
|
||||
if(cur > 0) {
|
||||
opts.crit_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 6);
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 7);
|
||||
if(cur > 0) {
|
||||
opts.crit_flat = cur;
|
||||
}
|
||||
@@ -1271,32 +1279,32 @@ void Mob::AI_Process() {
|
||||
rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
|
||||
if(MakeRandomInt(0, 99) < rampage_chance) {
|
||||
ExtraAttackOptions opts;
|
||||
int cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 1);
|
||||
int cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 2);
|
||||
if(cur > 0) {
|
||||
opts.damage_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 2);
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 3);
|
||||
if(cur > 0) {
|
||||
opts.damage_flat = cur;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 3);
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 4);
|
||||
if(cur > 0) {
|
||||
opts.armor_pen_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 4);
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 5);
|
||||
if(cur > 0) {
|
||||
opts.armor_pen_flat = cur;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 5);
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 6);
|
||||
if(cur > 0) {
|
||||
opts.crit_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 6);
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 7);
|
||||
if(cur > 0) {
|
||||
opts.crit_flat = cur;
|
||||
}
|
||||
@@ -2008,7 +2016,10 @@ bool Mob::Flurry(ExtraAttackOptions *opts)
|
||||
} else {
|
||||
entity_list.MessageClose_StringID(this, true, 200, MT_PetFlurry, NPC_FLURRY, GetCleanName(), target->GetCleanName());
|
||||
}
|
||||
for (int i = 0; i < RuleI(Combat, MaxFlurryHits); i++)
|
||||
|
||||
int num_attacks = GetSpecialAbilityParam(SPECATK_FLURRY, 1);
|
||||
num_attacks = num_attacks > 0 ? num_attacks : RuleI(Combat, MaxFlurryHits);
|
||||
for (int i = 0; i < num_attacks; i++)
|
||||
Attack(target, 13, false, false, false, opts);
|
||||
}
|
||||
return true;
|
||||
@@ -2045,9 +2056,12 @@ bool Mob::Rampage(ExtraAttackOptions *opts)
|
||||
} else {
|
||||
entity_list.MessageClose_StringID(this, true, 200, MT_PetFlurry, NPC_RAMPAGE, GetCleanName());
|
||||
}
|
||||
|
||||
int rampage_targets = GetSpecialAbilityParam(SPECATK_RAMPAGE, 1);
|
||||
rampage_targets = rampage_targets > 0 ? rampage_targets : RuleI(Combat, MaxRampageTargets);
|
||||
for (int i = 0; i < RampageArray.size(); i++)
|
||||
{
|
||||
if(index_hit >= RuleI(Combat, MaxRampageTargets))
|
||||
if(index_hit >= rampage_targets)
|
||||
break;
|
||||
// range is important
|
||||
Mob *m_target = entity_list.GetMob(RampageArray[i].c_str());
|
||||
@@ -2063,7 +2077,7 @@ bool Mob::Rampage(ExtraAttackOptions *opts)
|
||||
}
|
||||
}
|
||||
|
||||
if(index_hit < RuleI(Combat, MaxRampageTargets)) {
|
||||
if(index_hit < rampage_targets) {
|
||||
Attack(GetTarget(), 13, false, false, false, opts);
|
||||
}
|
||||
return true;
|
||||
@@ -2077,7 +2091,10 @@ void Mob::AreaRampage(ExtraAttackOptions *opts)
|
||||
} else {
|
||||
entity_list.MessageClose_StringID(this, true, 200, MT_PetFlurry, AE_RAMPAGE, GetCleanName());
|
||||
}
|
||||
index_hit = hate_list.AreaRampage(this, GetTarget(), opts);
|
||||
|
||||
int rampage_targets = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 1);
|
||||
rampage_targets = rampage_targets > 0 ? rampage_targets : 1;
|
||||
index_hit = hate_list.AreaRampage(this, GetTarget(), rampage_targets, opts);
|
||||
|
||||
if(index_hit == 0) {
|
||||
Attack(GetTarget(), 13, false, false, false, opts);
|
||||
|
||||
+4
-2
@@ -473,7 +473,7 @@ void HateList::PrintToClient(Client *c)
|
||||
}
|
||||
}
|
||||
|
||||
int HateList::AreaRampage(Mob *caster, Mob *target, ExtraAttackOptions *opts)
|
||||
int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts)
|
||||
{
|
||||
if(!target || !caster)
|
||||
return 0;
|
||||
@@ -501,7 +501,9 @@ int HateList::AreaRampage(Mob *caster, Mob *target, ExtraAttackOptions *opts)
|
||||
Mob *cur = entity_list.GetMobID((*iter));
|
||||
if(cur)
|
||||
{
|
||||
caster->Attack(cur, 13, false, false, false, opts);
|
||||
for(int i = 0; i < count; ++i) {
|
||||
caster->Attack(cur, 13, false, false, false, opts);
|
||||
}
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public:
|
||||
//Gets the target with the most hate regardless of things like frenzy etc.
|
||||
Mob* GetMostHate();
|
||||
|
||||
int AreaRampage(Mob *caster, Mob *target, ExtraAttackOptions *opts);
|
||||
int AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts);
|
||||
|
||||
void SpellCast(Mob *caster, uint32 spell_id, float range);
|
||||
|
||||
|
||||
+1
-1
@@ -151,7 +151,7 @@ static const struct luaL_Reg bit_funcs[] = {
|
||||
*/
|
||||
#define BAD_SAR (bsar(-8, 2) != (SBits)-2)
|
||||
|
||||
LUALIB_API int luaopen_bit(lua_State *L)
|
||||
int luaopen_bit(lua_State *L)
|
||||
{
|
||||
UBits b;
|
||||
lua_pushnumber(L, (lua_Number)1437217655L);
|
||||
|
||||
+26
-1
@@ -5,6 +5,7 @@
|
||||
#include <luabind/object.hpp>
|
||||
|
||||
#include "doors.h"
|
||||
#include "lua_mob.h"
|
||||
#include "lua_door.h"
|
||||
|
||||
void Lua_Door::SetDoorName(const char *name) {
|
||||
@@ -137,6 +138,26 @@ void Lua_Door::CreateDatabaseEntry() {
|
||||
self->CreateDatabaseEntry();
|
||||
}
|
||||
|
||||
void Lua_Door::ForceOpen(Lua_Mob sender) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->ForceOpen(sender);
|
||||
}
|
||||
|
||||
void Lua_Door::ForceOpen(Lua_Mob sender, bool alt_mode) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->ForceOpen(sender, alt_mode);
|
||||
}
|
||||
|
||||
void Lua_Door::ForceClose(Lua_Mob sender) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->ForceClose(sender);
|
||||
}
|
||||
|
||||
void Lua_Door::ForceClose(Lua_Mob sender, bool alt_mode) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->ForceClose(sender, alt_mode);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_door() {
|
||||
return luabind::class_<Lua_Door, Lua_Entity>("Door")
|
||||
.def(luabind::constructor<>())
|
||||
@@ -167,7 +188,11 @@ luabind::scope lua_register_door() {
|
||||
.def("GetKeyItem", (uint32(Lua_Door::*)(void))&Lua_Door::GetKeyItem)
|
||||
.def("SetNoKeyring", (void(Lua_Door::*)(int))&Lua_Door::SetNoKeyring)
|
||||
.def("GetNoKeyring", (int(Lua_Door::*)(void))&Lua_Door::GetNoKeyring)
|
||||
.def("CreateDatabaseEntry", (void(Lua_Door::*)(void))&Lua_Door::CreateDatabaseEntry);
|
||||
.def("CreateDatabaseEntry", (void(Lua_Door::*)(void))&Lua_Door::CreateDatabaseEntry)
|
||||
.def("ForceOpen", (void(Lua_Door::*)(Lua_Mob))&Lua_Door::ForceOpen)
|
||||
.def("ForceOpen", (void(Lua_Door::*)(Lua_Mob,bool))&Lua_Door::ForceOpen)
|
||||
.def("ForceClose", (void(Lua_Door::*)(Lua_Mob))&Lua_Door::ForceClose)
|
||||
.def("ForceClose", (void(Lua_Door::*)(Lua_Mob,bool))&Lua_Door::ForceClose);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "lua_entity.h"
|
||||
|
||||
class Doors;
|
||||
class Lua_Mob;
|
||||
|
||||
namespace luabind {
|
||||
struct scope;
|
||||
@@ -55,6 +56,10 @@ public:
|
||||
void SetNoKeyring(int type);
|
||||
int GetNoKeyring();
|
||||
void CreateDatabaseEntry();
|
||||
void ForceOpen(Lua_Mob sender);
|
||||
void ForceOpen(Lua_Mob sender, bool alt_mode);
|
||||
void ForceClose(Lua_Mob sender);
|
||||
void ForceClose(Lua_Mob sender, bool alt_mode);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1820,6 +1820,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int,bool))&Lua_Mob::Attack)
|
||||
.def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int,bool,bool))&Lua_Mob::Attack)
|
||||
.def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int,bool,bool,bool))&Lua_Mob::Attack)
|
||||
.def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int,bool,bool,bool,luabind::object))&Lua_Mob::Attack)
|
||||
.def("Damage", (void(Lua_Mob::*)(Lua_Mob,int,int,int))&Lua_Mob::Damage)
|
||||
.def("Damage", (void(Lua_Mob::*)(Lua_Mob,int,int,int,bool))&Lua_Mob::Damage)
|
||||
.def("Damage", (void(Lua_Mob::*)(Lua_Mob,int,int,int,bool,int))&Lua_Mob::Damage)
|
||||
|
||||
@@ -2338,7 +2338,6 @@ bool Mob::HateSummon() {
|
||||
|
||||
int summon_level = GetSpecialAbility(SPECATK_SUMMON);
|
||||
if(summon_level == 1 || summon_level == 2) {
|
||||
//Summon things always
|
||||
if(!GetTarget() || (mob_owner && mob_owner->IsClient() && !CheckLosFN(GetTarget()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user