NPC Special Attacks should all work right: also huge explanation in changelog.txt

This commit is contained in:
KimLS
2013-07-11 13:44:45 -07:00
parent ab2c184b54
commit 239d4afb13
10 changed files with 233 additions and 36 deletions
+47 -30
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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)
-1
View File
@@ -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;
}