mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +00:00
Better flee runspeed calculation.
Added two new NPC special_abilities, ALWAYS_FLEE and FLEE_PERCENT. Fixed an issue where a NPC could get stuck on a single coord in a rectangular roambox. Added mindelay to spawngroup to allow for greater control of the roambox delay. SQL is required.
This commit is contained in:
parent
ea31a29f8a
commit
1d6bd3cc5e
@ -4,12 +4,19 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
== 02/26/2014 ==
|
||||
Kayen: Implemented SE_FrenziedDevestation - increase critical spell chacnce and 2x mana cost for DD spells
|
||||
Kayen: Fixed SE_SpellProcChance - Now works on spell dervived procs
|
||||
cavedude: Added two new NPC special_abilities. ALWAYS_FLEE, which forces the NPC to always flee ignoring FleeIfNotAlone and FLEE_PERCENT which allows you to change the HP an individual NPC will flee at. If no value is set, the rule is used as normal.
|
||||
cavedude: Fixed an issue where rectangular roamboxes could cause an NPC to get stuck on a single coord.
|
||||
cavedude: Added a new roambox column, mindelay allowing you to have more control over the roambox delay.
|
||||
|
||||
Required SQL: utils/sql/git/required/2014_02_26_roambox_update.sql
|
||||
|
||||
== 02/24/2014 ==
|
||||
cavedude: Better flee runspeed calculation. Added rule Combat:FleeMultiplier to alter this behavior.
|
||||
Sorvani: Updated GetUnusedInstanceID to not recycle instance ID's unless it has reached max (65535)
|
||||
|
||||
== 02/23/2014 ==
|
||||
Secrets: Exported the client object SendTargetCommand to Perl.
|
||||
cavedude: Merchants will now keep better track of charges.
|
||||
|
||||
== 02/20/2014 ==
|
||||
Kayen: Implemented SE_MitigateDotDamage - dot spell mitigation rune with max value
|
||||
|
||||
@ -310,8 +310,8 @@ RULE_INT ( Combat, ClientBaseCritChance, 0 ) //The base crit chance for all clie
|
||||
RULE_BOOL ( Combat, UseIntervalAC, true)
|
||||
RULE_INT ( Combat, PetAttackMagicLevel, 30)
|
||||
RULE_BOOL ( Combat, EnableFearPathing, true)
|
||||
RULE_INT ( Combat, FleeHPRatio, 25)
|
||||
RULE_INT ( Combat, FleeSnareHPRatio, 11) // HP at which snare will halt movement of a fleeing NPC.
|
||||
RULE_REAL ( Combat, FleeMultiplier, 2.0) // Determines how quickly a NPC will slow down while fleeing. Decrease multiplier to slow NPC down quicker.
|
||||
RULE_INT ( Combat, FleeHPRatio, 25) //HP % when a NPC begins to flee.
|
||||
RULE_BOOL ( Combat, FleeIfNotAlone, false) // If false, mobs won't flee if other mobs are in combat with it.
|
||||
RULE_BOOL ( Combat, AdjustProcPerMinute, true)
|
||||
RULE_REAL ( Combat, AvgProcsPerMinute, 2.0)
|
||||
|
||||
2
utils/sql/git/required/2014_02_26_roambox_update.sql
Normal file
2
utils/sql/git/required/2014_02_26_roambox_update.sql
Normal file
@ -0,0 +1,2 @@
|
||||
alter table `spawngroup` add column `mindelay` int(11) not null default 15000 AFTER delay;
|
||||
alter table `spawngroup` change `delay` `delay` int(11) not null default 45000;
|
||||
@ -455,6 +455,7 @@ void NPC::AI_Init() {
|
||||
roambox_distance = 0;
|
||||
roambox_movingto_x = 0;
|
||||
roambox_movingto_y = 0;
|
||||
roambox_min_delay = 2500;
|
||||
roambox_delay = 2500;
|
||||
}
|
||||
|
||||
@ -1590,14 +1591,17 @@ void NPC::AI_DoMovement() {
|
||||
movey *= MakeRandomInt(0, 1) ? 1 : -1;
|
||||
roambox_movingto_x = GetX() + movex;
|
||||
roambox_movingto_y = GetY() + movey;
|
||||
//Try to calculate new coord using distance.
|
||||
if (roambox_movingto_x > roambox_max_x || roambox_movingto_x < roambox_min_x)
|
||||
roambox_movingto_x -= movex * 2;
|
||||
if (roambox_movingto_y > roambox_max_y || roambox_movingto_y < roambox_min_y)
|
||||
roambox_movingto_y -= movey * 2;
|
||||
//New coord is still invalid, ignore distance and just pick a new random coord.
|
||||
//If we're here we may have a roambox where one side is shorter than the specified distance. Commons, Wkarana, etc.
|
||||
if (roambox_movingto_x > roambox_max_x || roambox_movingto_x < roambox_min_x)
|
||||
roambox_movingto_x = roambox_max_x;
|
||||
roambox_movingto_x = MakeRandomFloat(roambox_min_x+1,roambox_max_x-1);
|
||||
if (roambox_movingto_y > roambox_max_y || roambox_movingto_y < roambox_min_y)
|
||||
roambox_movingto_y = roambox_max_y;
|
||||
roambox_movingto_y = MakeRandomFloat(roambox_min_y+1,roambox_max_y-1);
|
||||
}
|
||||
|
||||
mlog(AI__WAYPOINTS, "Roam Box: d=%.3f (%.3f->%.3f,%.3f->%.3f): Go To (%.3f,%.3f)",
|
||||
@ -1605,7 +1609,7 @@ void NPC::AI_DoMovement() {
|
||||
if (!CalculateNewPosition2(roambox_movingto_x, roambox_movingto_y, GetZ(), walksp, true))
|
||||
{
|
||||
roambox_movingto_x = roambox_max_x + 1; // force update
|
||||
pLastFightingDelayMoving = Timer::GetCurrentTime() + RandomTimer(roambox_delay, roambox_delay + 5000);
|
||||
pLastFightingDelayMoving = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay);
|
||||
SetMoving(false);
|
||||
SendPosition(); // makes mobs stop clientside
|
||||
}
|
||||
|
||||
@ -2085,21 +2085,27 @@ void command_ai(Client *c, const Seperator *sep)
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "roambox") == 0) {
|
||||
if (target && target->IsAIControlled() && target->IsNPC()) {
|
||||
if ((sep->argnum == 6 || sep->argnum == 7) && sep->IsNumber(2) && sep->IsNumber(3) && sep->IsNumber(4) && sep->IsNumber(5) && sep->IsNumber(6)) {
|
||||
if ((sep->argnum == 6 || sep->argnum == 7 || sep->argnum == 8) && sep->IsNumber(2) && sep->IsNumber(3) && sep->IsNumber(4) && sep->IsNumber(5) && sep->IsNumber(6)) {
|
||||
uint32 tmp = 2500;
|
||||
uint32 tmp2 = 2500;
|
||||
if (sep->IsNumber(7))
|
||||
tmp = atoi(sep->arg[7]);
|
||||
target->CastToNPC()->AI_SetRoambox(atof(sep->arg[2]), atof(sep->arg[3]), atof(sep->arg[4]), atof(sep->arg[5]), atof(sep->arg[6]), tmp);
|
||||
if (sep->IsNumber(8))
|
||||
tmp2 = atoi(sep->arg[8]);
|
||||
target->CastToNPC()->AI_SetRoambox(atof(sep->arg[2]), atof(sep->arg[3]), atof(sep->arg[4]), atof(sep->arg[5]), atof(sep->arg[6]), tmp, tmp2);
|
||||
}
|
||||
else if ((sep->argnum == 3 || sep->argnum == 4) && sep->IsNumber(2) && sep->IsNumber(3)) {
|
||||
uint32 tmp = 2500;
|
||||
uint32 tmp2 = 2500;
|
||||
if (sep->IsNumber(4))
|
||||
tmp = atoi(sep->arg[4]);
|
||||
target->CastToNPC()->AI_SetRoambox(atof(sep->arg[2]), atof(sep->arg[3]), tmp);
|
||||
if (sep->IsNumber(5))
|
||||
tmp2 = atoi(sep->arg[5]);
|
||||
target->CastToNPC()->AI_SetRoambox(atof(sep->arg[2]), atof(sep->arg[3]), tmp, tmp2);
|
||||
}
|
||||
else {
|
||||
c->Message(0, "Usage: #ai roambox dist max_x min_x max_y min_y [delay]");
|
||||
c->Message(0, "Usage: #ai roambox dist roamdist [delay]");
|
||||
c->Message(0, "Usage: #ai roambox dist max_x min_x max_y min_y [delay] [mindelay]");
|
||||
c->Message(0, "Usage: #ai roambox dist roamdist [delay] [mindelay]");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@ -122,7 +122,10 @@ enum {
|
||||
TETHER = 33,
|
||||
DESTRUCTIBLE_OBJECT = 34,
|
||||
NO_HARM_FROM_CLIENT = 35,
|
||||
MAX_SPECIAL_ATTACK = 36
|
||||
ALWAYS_FLEE = 36,
|
||||
FLEE_PERCENT = 37,
|
||||
MAX_SPECIAL_ATTACK = 38
|
||||
|
||||
};
|
||||
|
||||
typedef enum { //fear states
|
||||
|
||||
@ -53,7 +53,10 @@ void Mob::CheckFlee() {
|
||||
|
||||
//see if were possibly hurt enough
|
||||
float ratio = GetHPRatio();
|
||||
if(ratio >= RuleI(Combat, FleeHPRatio))
|
||||
float fleeratio = GetSpecialAbility(FLEE_PERCENT);
|
||||
fleeratio = fleeratio > 0 ? fleeratio : RuleI(Combat, FleeHPRatio);
|
||||
|
||||
if(ratio >= fleeratio)
|
||||
return;
|
||||
|
||||
//we might be hurt enough, check con now..
|
||||
@ -77,25 +80,24 @@ void Mob::CheckFlee() {
|
||||
switch(con) {
|
||||
//these values are not 100% researched
|
||||
case CON_GREEN:
|
||||
run_ratio = RuleI(Combat, FleeHPRatio);
|
||||
run_ratio = fleeratio;
|
||||
break;
|
||||
case CON_LIGHTBLUE:
|
||||
run_ratio = RuleI(Combat, FleeHPRatio) * 8 / 10;
|
||||
run_ratio = fleeratio * 9 / 10;
|
||||
break;
|
||||
case CON_BLUE:
|
||||
run_ratio = RuleI(Combat, FleeHPRatio) * 6 / 10;
|
||||
run_ratio = fleeratio * 8 / 10;
|
||||
break;
|
||||
default:
|
||||
run_ratio = RuleI(Combat, FleeHPRatio) * 4 / 10;
|
||||
run_ratio = fleeratio * 7 / 10;
|
||||
break;
|
||||
}
|
||||
if(ratio < run_ratio)
|
||||
{
|
||||
if (RuleB(Combat, FleeIfNotAlone) ||
|
||||
(!RuleB(Combat, FleeIfNotAlone) &&
|
||||
(entity_list.GetHatedCount(hate_top, this) == 0)))
|
||||
GetSpecialAbility(ALWAYS_FLEE) ||
|
||||
(!RuleB(Combat, FleeIfNotAlone) && (entity_list.GetHatedCount(hate_top, this) == 0)))
|
||||
StartFleeing();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +112,9 @@ void Mob::ProcessFlee() {
|
||||
}
|
||||
|
||||
//see if we are still dying, if so, do nothing
|
||||
if(GetHPRatio() < (float)RuleI(Combat, FleeHPRatio))
|
||||
float fleeratio = GetSpecialAbility(FLEE_PERCENT);
|
||||
fleeratio = fleeratio > 0 ? fleeratio : RuleI(Combat, FleeHPRatio);
|
||||
if(GetHPRatio() < fleeratio)
|
||||
return;
|
||||
|
||||
//we are not dying anymore... see what we do next
|
||||
@ -128,19 +132,19 @@ void Mob::ProcessFlee() {
|
||||
float Mob::GetFearSpeed() {
|
||||
if(flee_mode) {
|
||||
//we know ratio < FLEE_HP_RATIO
|
||||
float speed = GetRunspeed();
|
||||
float speed = GetBaseRunspeed();
|
||||
float ratio = GetHPRatio();
|
||||
float multiplier = RuleR(Combat, FleeMultiplier);
|
||||
|
||||
// mob's movement will halt with a decent snare at HP specified by rule.
|
||||
if (ratio <= RuleI(Combat, FleeSnareHPRatio) && GetSnaredAmount() > 40) {
|
||||
return 0.0001f;
|
||||
}
|
||||
if(GetSnaredAmount() > 40)
|
||||
multiplier = multiplier / 6.0f;
|
||||
|
||||
if (ratio < FLEE_HP_MINSPEED)
|
||||
ratio = FLEE_HP_MINSPEED;
|
||||
|
||||
speed = speed * 0.5 * ratio / 100;
|
||||
speed = speed * ratio * multiplier / 100;
|
||||
|
||||
//NPC will eventually stop. Snares speeds this up.
|
||||
if(speed < 0.09)
|
||||
speed = 0.0001f;
|
||||
|
||||
return(speed);
|
||||
}
|
||||
return(GetRunspeed());
|
||||
|
||||
@ -2166,7 +2166,9 @@ luabind::scope lua_register_special_abilities() {
|
||||
luabind::value("leash", static_cast<int>(LEASH)),
|
||||
luabind::value("tether", static_cast<int>(TETHER)),
|
||||
luabind::value("destructible_object", static_cast<int>(DESTRUCTIBLE_OBJECT)),
|
||||
luabind::value("no_harm_from_client", static_cast<int>(NO_HARM_FROM_CLIENT))
|
||||
luabind::value("no_harm_from_client", static_cast<int>(NO_HARM_FROM_CLIENT)),
|
||||
luabind::value("always_flee", static_cast<int>(ALWAYS_FLEE)),
|
||||
luabind::value("flee_percent", static_cast<int>(FLEE_PERCENT))
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -297,9 +297,9 @@ void Lua_NPC::AI_SetRoambox(float dist, float max_x, float min_x, float max_y, f
|
||||
self->AI_SetRoambox(dist, max_x, min_x, max_y, min_y);
|
||||
}
|
||||
|
||||
void Lua_NPC::AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y, uint32 delay) {
|
||||
void Lua_NPC::AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y, uint32 delay, uint32 mindelay) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->AI_SetRoambox(dist, max_x, min_x, max_y, min_y, delay);
|
||||
self->AI_SetRoambox(dist, max_x, min_x, max_y, min_y, delay, mindelay);
|
||||
}
|
||||
|
||||
int Lua_NPC::GetNPCSpellsID() {
|
||||
@ -494,7 +494,7 @@ luabind::scope lua_register_npc() {
|
||||
.def("SaveGuardSpot", (void(Lua_NPC::*)(bool))&Lua_NPC::SaveGuardSpot)
|
||||
.def("IsGuarding", (bool(Lua_NPC::*)(void))&Lua_NPC::IsGuarding)
|
||||
.def("AI_SetRoambox", (void(Lua_NPC::*)(float,float,float,float,float))&Lua_NPC::AI_SetRoambox)
|
||||
.def("AI_SetRoambox", (void(Lua_NPC::*)(float,float,float,float,float,uint32))&Lua_NPC::AI_SetRoambox)
|
||||
.def("AI_SetRoambox", (void(Lua_NPC::*)(float,float,float,float,float,uint32,uint32))&Lua_NPC::AI_SetRoambox)
|
||||
.def("GetNPCSpellsID", (int(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsID)
|
||||
.def("GetSpawnPointID", (int(Lua_NPC::*)(void))&Lua_NPC::GetSpawnPointID)
|
||||
.def("GetSpawnPointX", (float(Lua_NPC::*)(void))&Lua_NPC::GetSpawnPointX)
|
||||
|
||||
@ -85,7 +85,7 @@ public:
|
||||
void SaveGuardSpot(bool clear);
|
||||
bool IsGuarding();
|
||||
void AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y);
|
||||
void AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y, uint32 delay);
|
||||
void AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y, uint32 delay, uint32 mindelay);
|
||||
int GetNPCSpellsID();
|
||||
int GetSpawnPointID();
|
||||
float GetSpawnPointX();
|
||||
|
||||
@ -381,6 +381,14 @@ int main(int argc, char** argv) {
|
||||
entity_list.AddClient(client);
|
||||
}
|
||||
|
||||
uint8 IDLEZONETIME = 200;
|
||||
if ( numclients < 1 && temp_timer.GetDuration() != IDLEZONETIME )
|
||||
temp_timer.SetTimer(IDLEZONETIME);
|
||||
else if ( numclients > 0 && temp_timer.GetDuration() == IDLEZONETIME )
|
||||
{
|
||||
temp_timer.SetTimer(10);
|
||||
temp_timer.Trigger();
|
||||
}
|
||||
|
||||
//check for timeouts in other threads
|
||||
timeout_manager.CheckTimeouts();
|
||||
|
||||
16
zone/npc.cpp
16
zone/npc.cpp
@ -216,6 +216,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
|
||||
roambox_min_y = -2;
|
||||
roambox_movingto_x = -2;
|
||||
roambox_movingto_y = -2;
|
||||
roambox_min_delay = 1000;
|
||||
roambox_delay = 1000;
|
||||
org_heading = heading;
|
||||
p_depop = false;
|
||||
@ -1526,6 +1527,12 @@ void Mob::NPCSpecialAttacks(const char* parse, int permtag, bool reset, bool rem
|
||||
case 'i':
|
||||
SetSpecialAbility(IMMUNE_TAUNT, remove ? 0 : 1);
|
||||
break;
|
||||
case 'e':
|
||||
SetSpecialAbility(ALWAYS_FLEE, remove ? 0 : 1);
|
||||
break;
|
||||
case 'h':
|
||||
SetSpecialAbility(FLEE_PERCENT, remove ? 0 : 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -1686,7 +1693,14 @@ bool Mob::HasNPCSpecialAtk(const char* parse) {
|
||||
HasAllAttacks = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if(!GetSpecialAbility(ALWAYS_FLEE))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'h':
|
||||
if(!GetSpecialAbility(FLEE_PERCENT))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
default:
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
|
||||
@ -265,8 +265,8 @@ public:
|
||||
inline bool IsGuarding() const { return(guard_heading != 0); }
|
||||
void SaveGuardSpotCharm();
|
||||
void RestoreGuardSpotCharm();
|
||||
void AI_SetRoambox(float iDist, float iRoamDist, uint32 iDelay = 2500);
|
||||
void AI_SetRoambox(float iDist, float iMaxX, float iMinX, float iMaxY, float iMinY, uint32 iDelay = 2500);
|
||||
void AI_SetRoambox(float iDist, float iRoamDist, uint32 iDelay = 2500, uint32 iMinDelay = 2500);
|
||||
void AI_SetRoambox(float iDist, float iMaxX, float iMinX, float iMaxY, float iMinY, uint32 iDelay = 2500, uint32 iMinDelay = 2500);
|
||||
|
||||
//mercenary stuff
|
||||
void LoadMercTypes();
|
||||
@ -430,6 +430,7 @@ protected:
|
||||
float roambox_movingto_x;
|
||||
float roambox_movingto_y;
|
||||
uint32 roambox_delay;
|
||||
uint32 roambox_min_delay;
|
||||
|
||||
uint16 skills[HIGHEST_SKILL+1];
|
||||
uint32 equipment[MAX_WORN_INVENTORY]; //this is an array of item IDs
|
||||
|
||||
@ -1433,8 +1433,8 @@ XS(XS_NPC_AI_SetRoambox); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_NPC_AI_SetRoambox)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items < 6 || items > 7)
|
||||
Perl_croak(aTHX_ "Usage: NPC::AI_SetRoambox(THIS, iDist, iMaxX, iMinX, iMaxY, iMinY, iDelay= 2500)");
|
||||
if (items < 6 || items > 8)
|
||||
Perl_croak(aTHX_ "Usage: NPC::AI_SetRoambox(THIS, iDist, iMaxX, iMinX, iMaxY, iMinY, iDelay= 2500, iMinDelay= 2500)");
|
||||
{
|
||||
NPC * THIS;
|
||||
float iDist = (float)SvNV(ST(1));
|
||||
@ -1443,6 +1443,7 @@ XS(XS_NPC_AI_SetRoambox)
|
||||
float iMaxY = (float)SvNV(ST(4));
|
||||
float iMinY = (float)SvNV(ST(5));
|
||||
uint32 iDelay;
|
||||
uint32 iMinDelay;
|
||||
|
||||
if (sv_derived_from(ST(0), "NPC")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
@ -1453,13 +1454,20 @@ XS(XS_NPC_AI_SetRoambox)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
if (items < 7)
|
||||
if (items < 7){
|
||||
iMinDelay = 2500;
|
||||
iDelay = 2500;
|
||||
else {
|
||||
}
|
||||
else if (items < 8){
|
||||
iMinDelay = 2500;
|
||||
iDelay = (uint32)SvUV(ST(6));
|
||||
}
|
||||
else {
|
||||
iDelay = (uint32)SvUV(ST(6));
|
||||
iMinDelay = (uint32)SvUV(ST(7));
|
||||
}
|
||||
|
||||
THIS->AI_SetRoambox(iDist, iMaxX, iMinX, iMaxY, iMinY, iDelay);
|
||||
THIS->AI_SetRoambox(iDist, iMaxX, iMinX, iMaxY, iMinY, iDelay, iMinDelay);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@ -2208,7 +2216,7 @@ XS(boot_NPC)
|
||||
newXSproto(strcpy(buf, "NextGuardPosition"), XS_NPC_NextGuardPosition, file, "$");
|
||||
newXSproto(strcpy(buf, "SaveGuardSpot"), XS_NPC_SaveGuardSpot, file, "$;$");
|
||||
newXSproto(strcpy(buf, "IsGuarding"), XS_NPC_IsGuarding, file, "$");
|
||||
newXSproto(strcpy(buf, "AI_SetRoambox"), XS_NPC_AI_SetRoambox, file, "$$$$$$;$");
|
||||
newXSproto(strcpy(buf, "AI_SetRoambox"), XS_NPC_AI_SetRoambox, file, "$$$$$$;$$");
|
||||
newXSproto(strcpy(buf, "GetNPCSpellsID"), XS_NPC_GetNPCSpellsID, file, "$");
|
||||
newXSproto(strcpy(buf, "GetSpawnPointID"), XS_NPC_GetSpawnPointID, file, "$");
|
||||
newXSproto(strcpy(buf, "GetSpawnPointX"), XS_NPC_GetSpawnPointX, file, "$");
|
||||
|
||||
@ -347,8 +347,8 @@ Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id)
|
||||
entity_list.AddNPC(npc);
|
||||
entity_list.LimitAddNPC(npc);
|
||||
|
||||
if(sg->roamdist && sg->roambox[0] && sg->roambox[1] && sg->roambox[2] && sg->roambox[3] && sg->delay)
|
||||
npc->AI_SetRoambox(sg->roamdist,sg->roambox[0],sg->roambox[1],sg->roambox[2],sg->roambox[3],sg->delay);
|
||||
if(sg->roamdist && sg->roambox[0] && sg->roambox[1] && sg->roambox[2] && sg->roambox[3] && sg->delay && sg->min_delay)
|
||||
npc->AI_SetRoambox(sg->roamdist,sg->roambox[0],sg->roambox[1],sg->roambox[2],sg->roambox[3],sg->delay,sg->min_delay);
|
||||
if(zone->InstantGrids())
|
||||
{
|
||||
found_spawn->LoadGrid();
|
||||
|
||||
@ -229,8 +229,8 @@ bool Spawn2::Process() {
|
||||
entity_list.AddNPC(npc);
|
||||
//this limit add must be done after the AddNPC since we need the entity ID.
|
||||
entity_list.LimitAddNPC(npc);
|
||||
if(sg->roamdist && sg->roambox[0] && sg->roambox[1] && sg->roambox[2] && sg->roambox[3] && sg->delay)
|
||||
npc->AI_SetRoambox(sg->roamdist,sg->roambox[0],sg->roambox[1],sg->roambox[2],sg->roambox[3],sg->delay);
|
||||
if(sg->roamdist && sg->roambox[0] && sg->roambox[1] && sg->roambox[2] && sg->roambox[3] && sg->delay && sg->min_delay)
|
||||
npc->AI_SetRoambox(sg->roamdist,sg->roambox[0],sg->roambox[1],sg->roambox[2],sg->roambox[3],sg->delay,sg->min_delay);
|
||||
if(zone->InstantGrids()) {
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Group %d spawned %s (%d) at (%.3f, %.3f, %.3f).", spawn2_id, spawngroup_id_, npc->GetName(), npcid, x, y, z);
|
||||
LoadGrid();
|
||||
|
||||
@ -35,7 +35,7 @@ SpawnEntry::SpawnEntry( uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_lim
|
||||
npc_spawn_limit = in_npc_spawn_limit;
|
||||
}
|
||||
|
||||
SpawnGroup::SpawnGroup( uint32 in_id, char* name, int in_group_spawn_limit, float dist, float maxx, float minx, float maxy, float miny, int delay_in, int despawn_in, uint32 despawn_timer_in ) {
|
||||
SpawnGroup::SpawnGroup( uint32 in_id, char* name, int in_group_spawn_limit, float dist, float maxx, float minx, float maxy, float miny, int delay_in, int despawn_in, uint32 despawn_timer_in, int min_delay_in ) {
|
||||
id = in_id;
|
||||
strn0cpy( name_, name, 120);
|
||||
group_spawn_limit = in_group_spawn_limit;
|
||||
@ -44,6 +44,7 @@ SpawnGroup::SpawnGroup( uint32 in_id, char* name, int in_group_spawn_limit, floa
|
||||
roambox[2]=maxy;
|
||||
roambox[3]=miny;
|
||||
roamdist=dist;
|
||||
min_delay=min_delay_in;
|
||||
delay=delay_in;
|
||||
despawn=despawn_in;
|
||||
despawn_timer=despawn_timer_in;
|
||||
@ -150,11 +151,11 @@ bool ZoneDatabase::LoadSpawnGroups(const char* zone_name, uint16 version, SpawnG
|
||||
|
||||
// CODER new spawn code
|
||||
query = 0;
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT(spawngroupID), spawngroup.name, spawngroup.spawn_limit, spawngroup.dist, spawngroup.max_x, spawngroup.min_x, spawngroup.max_y, spawngroup.min_y, spawngroup.delay, spawngroup.despawn, spawngroup.despawn_timer FROM spawn2,spawngroup WHERE spawn2.spawngroupID=spawngroup.ID and spawn2.version=%u and zone='%s'", version, zone_name), errbuf, &result))
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT(spawngroupID), spawngroup.name, spawngroup.spawn_limit, spawngroup.dist, spawngroup.max_x, spawngroup.min_x, spawngroup.max_y, spawngroup.min_y, spawngroup.delay, spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay FROM spawn2,spawngroup WHERE spawn2.spawngroupID=spawngroup.ID and spawn2.version=%u and zone='%s'", version, zone_name), errbuf, &result))
|
||||
{
|
||||
safe_delete_array(query);
|
||||
while((row = mysql_fetch_row(result))) {
|
||||
SpawnGroup* newSpawnGroup = new SpawnGroup( atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), atoi(row[9]), atoi(row[10]));
|
||||
SpawnGroup* newSpawnGroup = new SpawnGroup( atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), atoi(row[9]), atoi(row[10]), atoi(row[11]));
|
||||
spawn_group_list->AddSpawnGroup(newSpawnGroup);
|
||||
}
|
||||
mysql_free_result(result);
|
||||
@ -205,11 +206,11 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_g
|
||||
|
||||
// CODER new spawn code
|
||||
query = 0;
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT spawngroup.id, spawngroup.name, spawngroup.spawn_limit, spawngroup.dist, spawngroup.max_x, spawngroup.min_x, spawngroup.max_y, spawngroup.min_y, spawngroup.delay, spawngroup.despawn, spawngroup.despawn_timer FROM spawngroup WHERE spawngroup.ID='%i'", spawngroupid), errbuf, &result))
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT spawngroup.id, spawngroup.name, spawngroup.spawn_limit, spawngroup.dist, spawngroup.max_x, spawngroup.min_x, spawngroup.max_y, spawngroup.min_y, spawngroup.delay, spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay FROM spawngroup WHERE spawngroup.ID='%i'", spawngroupid), errbuf, &result))
|
||||
{
|
||||
safe_delete_array(query);
|
||||
while((row = mysql_fetch_row(result))) {
|
||||
SpawnGroup* newSpawnGroup = new SpawnGroup( atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), atoi(row[9]), atoi(row[10]));
|
||||
SpawnGroup* newSpawnGroup = new SpawnGroup( atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), atoi(row[9]), atoi(row[10]), atoi(row[11]));
|
||||
spawn_group_list->AddSpawnGroup(newSpawnGroup);
|
||||
}
|
||||
mysql_free_result(result);
|
||||
|
||||
@ -39,13 +39,14 @@ public:
|
||||
class SpawnGroup
|
||||
{
|
||||
public:
|
||||
SpawnGroup(uint32 in_id, char* name, int in_group_spawn_limit, float dist, float maxx, float minx, float maxy, float miny, int delay_in, int despawn_in, uint32 despawn_timer_in );
|
||||
SpawnGroup(uint32 in_id, char* name, int in_group_spawn_limit, float dist, float maxx, float minx, float maxy, float miny, int delay_in, int despawn_in, uint32 despawn_timer_in, int min_delay_in );
|
||||
~SpawnGroup();
|
||||
uint32 GetNPCType();
|
||||
void AddSpawnEntry( SpawnEntry* newEntry );
|
||||
uint32 id;
|
||||
float roamdist;
|
||||
float roambox[4];
|
||||
int min_delay;
|
||||
int delay;
|
||||
int despawn;
|
||||
uint32 despawn_timer;
|
||||
|
||||
@ -47,11 +47,11 @@ static inline float ABS(float x) {
|
||||
return(x);
|
||||
}
|
||||
|
||||
void NPC::AI_SetRoambox(float iDist, float iRoamDist, uint32 iDelay) {
|
||||
AI_SetRoambox(iDist, GetX()+iRoamDist, GetX()-iRoamDist, GetY()+iRoamDist, GetY()-iRoamDist, iDelay);
|
||||
void NPC::AI_SetRoambox(float iDist, float iRoamDist, uint32 iDelay, uint32 iMinDelay) {
|
||||
AI_SetRoambox(iDist, GetX()+iRoamDist, GetX()-iRoamDist, GetY()+iRoamDist, GetY()-iRoamDist, iDelay, iMinDelay);
|
||||
}
|
||||
|
||||
void NPC::AI_SetRoambox(float iDist, float iMaxX, float iMinX, float iMaxY, float iMinY, uint32 iDelay) {
|
||||
void NPC::AI_SetRoambox(float iDist, float iMaxX, float iMinX, float iMaxY, float iMinY, uint32 iDelay, uint32 iMinDelay) {
|
||||
roambox_distance = iDist;
|
||||
roambox_max_x = iMaxX;
|
||||
roambox_min_x = iMinX;
|
||||
@ -59,6 +59,7 @@ void NPC::AI_SetRoambox(float iDist, float iMaxX, float iMinX, float iMaxY, floa
|
||||
roambox_min_y = iMinY;
|
||||
roambox_movingto_x = roambox_max_x + 1; // this will trigger a recalc
|
||||
roambox_delay = iDelay;
|
||||
roambox_min_delay = iMinDelay;
|
||||
}
|
||||
|
||||
void NPC::DisplayWaypointInfo(Client *c) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user