mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-22 07:28:32 +00:00
Merge remote-tracking branch 'remotes/origin/master' into web_interface
Conflicts: CMakeLists.txt common/logtypes.h common/shareddb.cpp world/net.cpp zone/client_logs.cpp zone/corpse.cpp zone/mob.cpp zone/net.cpp
This commit is contained in:
+4
-4
@@ -9,14 +9,13 @@ SET(zone_sources
|
||||
bot.cpp
|
||||
botspellsai.cpp
|
||||
client.cpp
|
||||
client_logs.cpp
|
||||
client_mods.cpp
|
||||
client_packet.cpp
|
||||
client_process.cpp
|
||||
command.cpp
|
||||
corpse.cpp
|
||||
doors.cpp
|
||||
effects.cpp
|
||||
effects.cpp
|
||||
embparser.cpp
|
||||
embparser_api.cpp
|
||||
embperl.cpp
|
||||
@@ -92,6 +91,7 @@ SET(zone_sources
|
||||
perlpacket.cpp
|
||||
petitions.cpp
|
||||
pets.cpp
|
||||
position.cpp
|
||||
qglobals.cpp
|
||||
queryserv.cpp
|
||||
questmgr.cpp
|
||||
@@ -112,13 +112,13 @@ SET(zone_sources
|
||||
trading.cpp
|
||||
trap.cpp
|
||||
tribute.cpp
|
||||
tune.cpp
|
||||
water_map.cpp
|
||||
water_map_v1.cpp
|
||||
water_map_v2.cpp
|
||||
waypoints.cpp
|
||||
worldserver.cpp
|
||||
zone.cpp
|
||||
zone_logsys.cpp
|
||||
zone_config.cpp
|
||||
zonedb.cpp
|
||||
zoning.cpp
|
||||
@@ -131,7 +131,6 @@ SET(zone_headers
|
||||
bot.h
|
||||
bot_structs.h
|
||||
client.h
|
||||
client_logs.h
|
||||
client_packet.h
|
||||
command.h
|
||||
common.h
|
||||
@@ -184,6 +183,7 @@ SET(zone_headers
|
||||
perlpacket.h
|
||||
petitions.h
|
||||
pets.h
|
||||
position.h
|
||||
qglobals.h
|
||||
quest_interface.h
|
||||
queryserv.h
|
||||
|
||||
+114
-125
@@ -17,7 +17,8 @@ Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
|
||||
*/
|
||||
|
||||
#include "../common/classes.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/races.h"
|
||||
#include "../common/spdat.h"
|
||||
@@ -268,10 +269,10 @@ void Client::ActivateAA(aaID activate){
|
||||
}
|
||||
// Check if AA is expendable
|
||||
if (aas_send[activate - activate_val]->special_category == 7) {
|
||||
|
||||
|
||||
// Add the AA cost to the extended profile to track overall total
|
||||
m_epp.expended_aa += aas_send[activate]->cost;
|
||||
|
||||
|
||||
SetAA(activate, 0);
|
||||
|
||||
SaveAA(); /* Save Character AA */
|
||||
@@ -444,7 +445,7 @@ void Client::HandleAAAction(aaID activate) {
|
||||
break;
|
||||
|
||||
default:
|
||||
LogFile->write(EQEMuLog::Error, "Unknown AA nonspell action type %d", caa->action);
|
||||
Log.Out(Logs::General, Logs::Error, "Unknown AA nonspell action type %d", caa->action);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -500,7 +501,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
||||
PetRecord record;
|
||||
if(!database.GetPetEntry(spells[spell_id].teleport_zone, &record))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Unknown swarm pet spell id: %d, check pets table", spell_id);
|
||||
Log.Out(Logs::General, Logs::Error, "Unknown swarm pet spell id: %d, check pets table", spell_id);
|
||||
Message(13, "Unable to find data for pet %s", spells[spell_id].teleport_zone);
|
||||
return;
|
||||
}
|
||||
@@ -527,7 +528,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
||||
const NPCType *npc_type = database.GetNPCType(pet.npc_id);
|
||||
if(npc_type == nullptr) {
|
||||
//log write
|
||||
LogFile->write(EQEMuLog::Error, "Unknown npc type for swarm pet spell id: %d", spell_id);
|
||||
Log.Out(Logs::General, Logs::Error, "Unknown npc type for swarm pet spell id: %d", spell_id);
|
||||
Message(0,"Unable to find pet!");
|
||||
return;
|
||||
}
|
||||
@@ -546,12 +547,12 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
||||
if(summon_count > MAX_SWARM_PETS)
|
||||
summon_count = MAX_SWARM_PETS;
|
||||
|
||||
static const float swarm_pet_x[MAX_SWARM_PETS] = { 5, -5, 5, -5,
|
||||
10, -10, 10, -10,
|
||||
8, -8, 8, -8 };
|
||||
static const float swarm_pet_y[MAX_SWARM_PETS] = { 5, 5, -5, -5,
|
||||
10, 10, -10, -10,
|
||||
8, 8, -8, -8 };
|
||||
static const glm::vec2 swarmPetLocations[MAX_SWARM_PETS] = {
|
||||
glm::vec2(5, 5), glm::vec2(-5, 5), glm::vec2(5, -5), glm::vec2(-5, -5),
|
||||
glm::vec2(10, 10), glm::vec2(-10, 10), glm::vec2(10, -10), glm::vec2(-10, -10),
|
||||
glm::vec2(8, 8), glm::vec2(-8, 8), glm::vec2(8, -8), glm::vec2(-8, -8)
|
||||
};
|
||||
|
||||
while(summon_count > 0) {
|
||||
int pet_duration = pet.duration;
|
||||
if(duration_override > 0)
|
||||
@@ -568,8 +569,8 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
||||
NPC* npca = new NPC(
|
||||
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
|
||||
0,
|
||||
GetX()+swarm_pet_x[summon_count], GetY()+swarm_pet_y[summon_count],
|
||||
GetZ(), GetHeading(), FlyMode3);
|
||||
GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f),
|
||||
FlyMode3);
|
||||
|
||||
if (followme)
|
||||
npca->SetFollowID(GetID());
|
||||
@@ -624,7 +625,7 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
|
||||
const NPCType *npc_type = database.GetNPCType(typesid);
|
||||
if(npc_type == nullptr) {
|
||||
//log write
|
||||
LogFile->write(EQEMuLog::Error, "Unknown npc type for swarm pet type id: %d", typesid);
|
||||
Log.Out(Logs::General, Logs::Error, "Unknown npc type for swarm pet type id: %d", typesid);
|
||||
Message(0,"Unable to find pet!");
|
||||
return;
|
||||
}
|
||||
@@ -643,12 +644,11 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
|
||||
if(summon_count > MAX_SWARM_PETS)
|
||||
summon_count = MAX_SWARM_PETS;
|
||||
|
||||
static const float swarm_pet_x[MAX_SWARM_PETS] = { 5, -5, 5, -5,
|
||||
10, -10, 10, -10,
|
||||
8, -8, 8, -8 };
|
||||
static const float swarm_pet_y[MAX_SWARM_PETS] = { 5, 5, -5, -5,
|
||||
10, 10, -10, -10,
|
||||
8, 8, -8, -8 };
|
||||
static const glm::vec2 swarmPetLocations[MAX_SWARM_PETS] = {
|
||||
glm::vec2(5, 5), glm::vec2(-5, 5), glm::vec2(5, -5), glm::vec2(-5, -5),
|
||||
glm::vec2(10, 10), glm::vec2(-10, 10), glm::vec2(10, -10), glm::vec2(-10, -10),
|
||||
glm::vec2(8, 8), glm::vec2(-8, 8), glm::vec2(8, -8), glm::vec2(-8, -8)
|
||||
};;
|
||||
|
||||
while(summon_count > 0) {
|
||||
int pet_duration = pet.duration;
|
||||
@@ -666,8 +666,8 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
|
||||
NPC* npca = new NPC(
|
||||
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
|
||||
0,
|
||||
GetX()+swarm_pet_x[summon_count], GetY()+swarm_pet_y[summon_count],
|
||||
GetZ(), GetHeading(), FlyMode3);
|
||||
GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f),
|
||||
FlyMode3);
|
||||
|
||||
if (followme)
|
||||
npca->SetFollowID(GetID());
|
||||
@@ -853,7 +853,7 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration)
|
||||
make_npc->d_melee_texture1 = 0;
|
||||
make_npc->d_melee_texture2 = 0;
|
||||
|
||||
NPC* npca = new NPC(make_npc, 0, GetX(), GetY(), GetZ(), GetHeading(), FlyMode3);
|
||||
NPC* npca = new NPC(make_npc, 0, GetPosition(), FlyMode3);
|
||||
|
||||
if(!npca->GetSwarmInfo()){
|
||||
AA_SwarmPetInfo* nSI = new AA_SwarmPetInfo;
|
||||
@@ -950,7 +950,7 @@ void Client::SendAAStats() {
|
||||
|
||||
void Client::BuyAA(AA_Action* action)
|
||||
{
|
||||
mlog(AA__MESSAGE, "Starting to buy AA %d", action->ability);
|
||||
Log.Out(Logs::Detail, Logs::AA, "Starting to buy AA %d", action->ability);
|
||||
|
||||
//find the AA information from the database
|
||||
SendAA_Struct* aa2 = zone->FindAA(action->ability);
|
||||
@@ -962,7 +962,7 @@ void Client::BuyAA(AA_Action* action)
|
||||
a = action->ability - i;
|
||||
if(a <= 0)
|
||||
break;
|
||||
mlog(AA__MESSAGE, "Could not find AA %d, trying potential parent %d", action->ability, a);
|
||||
Log.Out(Logs::Detail, Logs::AA, "Could not find AA %d, trying potential parent %d", action->ability, a);
|
||||
aa2 = zone->FindAA(a);
|
||||
if(aa2 != nullptr)
|
||||
break;
|
||||
@@ -979,7 +979,7 @@ void Client::BuyAA(AA_Action* action)
|
||||
|
||||
uint32 cur_level = GetAA(aa2->id);
|
||||
if((aa2->id + cur_level) != action->ability) { //got invalid AA
|
||||
mlog(AA__ERROR, "Unable to find or match AA %d (found %d + lvl %d)", action->ability, aa2->id, cur_level);
|
||||
Log.Out(Logs::Detail, Logs::AA, "Unable to find or match AA %d (found %d + lvl %d)", action->ability, aa2->id, cur_level);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1010,14 +1010,14 @@ void Client::BuyAA(AA_Action* action)
|
||||
if (m_pp.aapoints >= real_cost && cur_level < aa2->max_level) {
|
||||
SetAA(aa2->id, cur_level + 1);
|
||||
|
||||
mlog(AA__MESSAGE, "Set AA %d to level %d", aa2->id, cur_level + 1);
|
||||
Log.Out(Logs::Detail, Logs::AA, "Set AA %d to level %d", aa2->id, cur_level + 1);
|
||||
|
||||
m_pp.aapoints -= real_cost;
|
||||
|
||||
/* Do Player Profile rank calculations and set player profile */
|
||||
SaveAA();
|
||||
/* Save to Database to avoid having to write the whole AA array to the profile, only write changes*/
|
||||
// database.SaveCharacterAA(this->CharacterID(), aa2->id, (cur_level + 1));
|
||||
// database.SaveCharacterAA(this->CharacterID(), aa2->id, (cur_level + 1));
|
||||
|
||||
if ((RuleB(AA, Stacking) && (GetClientVersionBit() >= 4) && (aa2->hotkey_sid == 4294967295u))
|
||||
&& ((aa2->max_level == (cur_level + 1)) && aa2->sof_next_id)){
|
||||
@@ -1038,7 +1038,7 @@ void Client::BuyAA(AA_Action* action)
|
||||
if (cur_level < 1){
|
||||
Message(15, "You have gained the ability \"%s\" at a cost of %d ability %s.", aa2->name, real_cost, (real_cost>1) ? "points" : "point");
|
||||
|
||||
/* QS: Player_Log_AA_Purchases */
|
||||
/* QS: Player_Log_AA_Purchases */
|
||||
if (RuleB(QueryServ, PlayerLogAAPurchases)){
|
||||
std::string event_desc = StringFormat("Initial AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc);
|
||||
@@ -1428,10 +1428,10 @@ SendAA_Struct* Zone::FindAA(uint32 id) {
|
||||
}
|
||||
|
||||
void Zone::LoadAAs() {
|
||||
LogFile->write(EQEMuLog::Status, "Loading AA information...");
|
||||
Log.Out(Logs::General, Logs::Status, "Loading AA information...");
|
||||
totalAAs = database.CountAAs();
|
||||
if(totalAAs == 0) {
|
||||
LogFile->write(EQEMuLog::Error, "Failed to load AAs!");
|
||||
Log.Out(Logs::General, Logs::Error, "Failed to load AAs!");
|
||||
aas = nullptr;
|
||||
return;
|
||||
}
|
||||
@@ -1446,11 +1446,11 @@ void Zone::LoadAAs() {
|
||||
}
|
||||
|
||||
//load AA Effects into aa_effects
|
||||
LogFile->write(EQEMuLog::Status, "Loading AA Effects...");
|
||||
Log.Out(Logs::General, Logs::Status, "Loading AA Effects...");
|
||||
if (database.LoadAAEffects2())
|
||||
LogFile->write(EQEMuLog::Status, "Loaded %d AA Effects.", aa_effects.size());
|
||||
Log.Out(Logs::General, Logs::Status, "Loaded %d AA Effects.", aa_effects.size());
|
||||
else
|
||||
LogFile->write(EQEMuLog::Error, "Failed to load AA Effects!");
|
||||
Log.Out(Logs::General, Logs::Error, "Failed to load AA Effects!");
|
||||
}
|
||||
|
||||
bool ZoneDatabase::LoadAAEffects2() {
|
||||
@@ -1459,26 +1459,24 @@ bool ZoneDatabase::LoadAAEffects2() {
|
||||
const std::string query = "SELECT aaid, slot, effectid, base1, base2 FROM aa_effects ORDER BY aaid ASC, slot ASC";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadAAEffects2 query: '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!results.RowCount()) { //no results
|
||||
LogFile->write(EQEMuLog::Error, "Error loading AA Effects, none found in the database.");
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||
int aaid = atoi(row[0]);
|
||||
int slot = atoi(row[1]);
|
||||
int effectid = atoi(row[2]);
|
||||
int base1 = atoi(row[3]);
|
||||
int base2 = atoi(row[4]);
|
||||
aa_effects[aaid][slot].skill_id = effectid;
|
||||
aa_effects[aaid][slot].base1 = base1;
|
||||
aa_effects[aaid][slot].base2 = base2;
|
||||
aa_effects[aaid][slot].slot = slot; //not really needed, but we'll populate it just in case
|
||||
}
|
||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||
int aaid = atoi(row[0]);
|
||||
int slot = atoi(row[1]);
|
||||
int effectid = atoi(row[2]);
|
||||
int base1 = atoi(row[3]);
|
||||
int base2 = atoi(row[4]);
|
||||
aa_effects[aaid][slot].skill_id = effectid;
|
||||
aa_effects[aaid][slot].base1 = base1;
|
||||
aa_effects[aaid][slot].base2 = base2;
|
||||
aa_effects[aaid][slot].slot = slot; //not really needed, but we'll populate it just in case
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1797,34 +1795,33 @@ bool ZoneDatabase::LoadAAEffects() {
|
||||
memset(AA_Actions, 0, sizeof(AA_Actions)); //I hope the compiler is smart about this size...
|
||||
|
||||
const std::string query = "SELECT aaid, rank, reuse_time, spell_id, target, "
|
||||
"nonspell_action, nonspell_mana, nonspell_duration, "
|
||||
"redux_aa, redux_rate, redux_aa2, redux_rate2 FROM aa_actions";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadAAEffects query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
"nonspell_action, nonspell_mana, nonspell_duration, "
|
||||
"redux_aa, redux_rate, redux_aa2, redux_rate2 FROM aa_actions";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
|
||||
int aaid = atoi(row[0]);
|
||||
int rank = atoi(row[1]);
|
||||
if(aaid < 0 || aaid >= aaHighestID || rank < 0 || rank >= MAX_AA_ACTION_RANKS)
|
||||
continue;
|
||||
AA_DBAction *caction = &AA_Actions[aaid][rank];
|
||||
int aaid = atoi(row[0]);
|
||||
int rank = atoi(row[1]);
|
||||
if(aaid < 0 || aaid >= aaHighestID || rank < 0 || rank >= MAX_AA_ACTION_RANKS)
|
||||
continue;
|
||||
AA_DBAction *caction = &AA_Actions[aaid][rank];
|
||||
|
||||
caction->reuse_time = atoi(row[2]);
|
||||
caction->spell_id = atoi(row[3]);
|
||||
caction->target = (aaTargetType) atoi(row[4]);
|
||||
caction->action = (aaNonspellAction) atoi(row[5]);
|
||||
caction->mana_cost = atoi(row[6]);
|
||||
caction->duration = atoi(row[7]);
|
||||
caction->redux_aa = (aaID) atoi(row[8]);
|
||||
caction->redux_rate = atoi(row[9]);
|
||||
caction->redux_aa2 = (aaID) atoi(row[10]);
|
||||
caction->redux_rate2 = atoi(row[11]);
|
||||
caction->reuse_time = atoi(row[2]);
|
||||
caction->spell_id = atoi(row[3]);
|
||||
caction->target = (aaTargetType) atoi(row[4]);
|
||||
caction->action = (aaNonspellAction) atoi(row[5]);
|
||||
caction->mana_cost = atoi(row[6]);
|
||||
caction->duration = atoi(row[7]);
|
||||
caction->redux_aa = (aaID) atoi(row[8]);
|
||||
caction->redux_rate = atoi(row[9]);
|
||||
caction->redux_aa2 = (aaID) atoi(row[10]);
|
||||
caction->redux_rate2 = atoi(row[11]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1840,14 +1837,13 @@ uint8 ZoneDatabase::GetTotalAALevels(uint32 skill_id) {
|
||||
std::string query = StringFormat("SELECT count(slot) FROM aa_effects WHERE aaid = %i", skill_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetTotalAALevels '%s: %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (results.RowCount() != 1)
|
||||
return 0;
|
||||
if (results.RowCount() != 1)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
auto row = results.begin();
|
||||
|
||||
return atoi(row[0]);
|
||||
}
|
||||
@@ -1894,14 +1890,13 @@ uint32 ZoneDatabase::CountAAs(){
|
||||
const std::string query = "SELECT count(title_sid) FROM altadv_vars";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::CountAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (results.RowCount() != 1)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
auto row = results.begin();
|
||||
|
||||
return atoi(row[0]);;
|
||||
}
|
||||
@@ -1911,14 +1906,13 @@ uint32 ZoneDatabase::CountAAEffects() {
|
||||
const std::string query = "SELECT count(id) FROM aa_effects";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::CountAALevels query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (results.RowCount() != 1)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
auto row = results.begin();
|
||||
|
||||
return atoi(row[0]);
|
||||
}
|
||||
@@ -1944,63 +1938,58 @@ void ZoneDatabase::LoadAAs(SendAA_Struct **load){
|
||||
load[index]->seq = index+1;
|
||||
}
|
||||
} else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
AARequiredLevelAndCost.clear();
|
||||
query = "SELECT skill_id, level, cost from aa_required_level_cost order by skill_id";
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
AALevelCost_Struct aalcs;
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
aalcs.Level = atoi(row[1]);
|
||||
aalcs.Cost = atoi(row[2]);
|
||||
AARequiredLevelAndCost[atoi(row[0])] = aalcs;
|
||||
}
|
||||
query = "SELECT skill_id, level, cost from aa_required_level_cost order by skill_id";
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AALevelCost_Struct aalcs;
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
aalcs.Level = atoi(row[1]);
|
||||
aalcs.Cost = atoi(row[2]);
|
||||
AARequiredLevelAndCost[atoi(row[0])] = aalcs;
|
||||
}
|
||||
}
|
||||
|
||||
SendAA_Struct* ZoneDatabase::GetAASkillVars(uint32 skill_id)
|
||||
{
|
||||
std::string query = "SET @row = 0"; //initialize "row" variable in database for next query
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetAASkillVars '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
query = StringFormat("SELECT a.cost, a.max_level, a.hotkey_sid, a.hotkey_sid2, a.title_sid, a.desc_sid, a.type, "
|
||||
"COALESCE(" //So we can return 0 if it's null.
|
||||
"(" // this is our derived table that has the row #
|
||||
// that we can SELECT from, because the client is stupid.
|
||||
"SELECT p.prereq_index_num "
|
||||
"FROM (SELECT a2.skill_id, @row := @row + 1 AS prereq_index_num "
|
||||
query = StringFormat("SELECT a.cost, a.max_level, a.hotkey_sid, a.hotkey_sid2, a.title_sid, a.desc_sid, a.type, "
|
||||
"COALESCE(" //So we can return 0 if it's null.
|
||||
"(" // this is our derived table that has the row #
|
||||
// that we can SELECT from, because the client is stupid.
|
||||
"SELECT p.prereq_index_num "
|
||||
"FROM (SELECT a2.skill_id, @row := @row + 1 AS prereq_index_num "
|
||||
"FROM altadv_vars a2) AS p "
|
||||
"WHERE p.skill_id = a.prereq_skill), 0) "
|
||||
"AS prereq_skill_index, a.prereq_minpoints, a.spell_type, a.spell_refresh, a.classes, "
|
||||
"a.berserker, a.spellid, a.class_type, a.name, a.cost_inc, a.aa_expansion, a.special_category, "
|
||||
"a.sof_type, a.sof_cost_inc, a.sof_max_level, a.sof_next_skill, "
|
||||
"a.clientver, " // Client Version 0 = None, 1 = All, 2 = Titanium/6.2, 4 = SoF 5 = SOD 6 = UF
|
||||
"a.account_time_required, a.sof_current_level, a.sof_next_id, a.level_inc "
|
||||
"FROM altadv_vars a WHERE skill_id=%i", skill_id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetAASkillVars '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
"WHERE p.skill_id = a.prereq_skill), 0) "
|
||||
"AS prereq_skill_index, a.prereq_minpoints, a.spell_type, a.spell_refresh, a.classes, "
|
||||
"a.berserker, a.spellid, a.class_type, a.name, a.cost_inc, a.aa_expansion, a.special_category, "
|
||||
"a.sof_type, a.sof_cost_inc, a.sof_max_level, a.sof_next_skill, "
|
||||
"a.clientver, " // Client Version 0 = None, 1 = All, 2 = Titanium/6.2, 4 = SoF 5 = SOD 6 = UF
|
||||
"a.account_time_required, a.sof_current_level, a.sof_next_id, a.level_inc "
|
||||
"FROM altadv_vars a WHERE skill_id=%i", skill_id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (results.RowCount() != 1)
|
||||
return nullptr;
|
||||
if (results.RowCount() != 1)
|
||||
return nullptr;
|
||||
|
||||
int total_abilities = GetTotalAALevels(skill_id); //eventually we'll want to use zone->GetTotalAALevels(skill_id) since it should save queries to the DB
|
||||
int total_abilities = GetTotalAALevels(skill_id); //eventually we'll want to use zone->GetTotalAALevels(skill_id) since it should save queries to the DB
|
||||
int totalsize = total_abilities * sizeof(AA_Ability) + sizeof(SendAA_Struct);
|
||||
|
||||
SendAA_Struct* sendaa = nullptr;
|
||||
uchar* buffer;
|
||||
SendAA_Struct* sendaa = nullptr;
|
||||
uchar* buffer;
|
||||
|
||||
buffer = new uchar[totalsize];
|
||||
memset(buffer,0,totalsize);
|
||||
@@ -2011,7 +2000,7 @@ SendAA_Struct* ZoneDatabase::GetAASkillVars(uint32 skill_id)
|
||||
//ATOI IS NOT UNSIGNED LONG-SAFE!!!
|
||||
|
||||
sendaa->cost = atoul(row[0]);
|
||||
sendaa->cost2 = sendaa->cost;
|
||||
sendaa->cost2 = sendaa->cost;
|
||||
sendaa->max_level = atoul(row[1]);
|
||||
sendaa->hotkey_sid = atoul(row[2]);
|
||||
sendaa->id = skill_id;
|
||||
|
||||
+35
-36
@@ -16,7 +16,8 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/faction.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/spdat.h"
|
||||
@@ -88,7 +89,7 @@ void EntityList::DescribeAggro(Client *towho, NPC *from_who, float d, bool verbo
|
||||
if (mob->IsClient()) //also ensures that mob != around
|
||||
continue;
|
||||
|
||||
if (mob->DistNoRoot(*from_who) > d2)
|
||||
if (DistanceSquared(mob->GetPosition(), from_who->GetPosition()) > d2)
|
||||
continue;
|
||||
|
||||
if (engaged) {
|
||||
@@ -150,7 +151,8 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) {
|
||||
return;
|
||||
}
|
||||
|
||||
float dist2 = mob->DistNoRoot(*this);
|
||||
float dist2 = DistanceSquared(mob->GetPosition(), m_Position);
|
||||
|
||||
float iAggroRange2 = iAggroRange*iAggroRange;
|
||||
if( dist2 > iAggroRange2 ) {
|
||||
towho->Message(0, "...%s is out of range. %.3f > %.3f ", mob->GetName(),
|
||||
@@ -295,7 +297,7 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
float dist2 = mob->DistNoRoot(*this);
|
||||
float dist2 = DistanceSquared(mob->GetPosition(), m_Position);
|
||||
float iAggroRange2 = iAggroRange*iAggroRange;
|
||||
|
||||
if( dist2 > iAggroRange2 ) {
|
||||
@@ -341,22 +343,18 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
{
|
||||
//FatherNiwtit: make sure we can see them. last since it is very expensive
|
||||
if(CheckLosFN(mob)) {
|
||||
|
||||
// Aggro
|
||||
#if EQDEBUG>=6
|
||||
LogFile->write(EQEMuLog::Debug, "Check aggro for %s target %s.", GetName(), mob->GetName());
|
||||
#endif
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Check aggro for %s target %s.", GetName(), mob->GetName());
|
||||
return( mod_will_aggro(mob, this) );
|
||||
}
|
||||
}
|
||||
#if EQDEBUG >= 6
|
||||
printf("Is In zone?:%d\n", mob->InZone());
|
||||
printf("Dist^2: %f\n", dist2);
|
||||
printf("Range^2: %f\n", iAggroRange2);
|
||||
printf("Faction: %d\n", fv);
|
||||
printf("Int: %d\n", GetINT());
|
||||
printf("Con: %d\n", GetLevelCon(mob->GetLevel()));
|
||||
#endif
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Is In zone?:%d\n", mob->InZone());
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Dist^2: %f\n", dist2);
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Range^2: %f\n", iAggroRange2);
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Faction: %d\n", fv);
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Int: %d\n", GetINT());
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Con: %d\n", GetLevelCon(mob->GetLevel()));
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
@@ -413,7 +411,7 @@ int EntityList::GetHatedCount(Mob *attacker, Mob *exclude)
|
||||
|
||||
AggroRange *= AggroRange;
|
||||
|
||||
if (mob->DistNoRoot(*attacker) > AggroRange)
|
||||
if (DistanceSquared(mob->GetPosition(), attacker->GetPosition()) > AggroRange)
|
||||
continue;
|
||||
|
||||
Count++;
|
||||
@@ -443,7 +441,7 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
||||
// && !mob->IsCorpse()
|
||||
// && mob->IsAIControlled()
|
||||
&& mob->GetPrimaryFaction() != 0
|
||||
&& mob->DistNoRoot(*sender) <= r
|
||||
&& DistanceSquared(mob->GetPosition(), sender->GetPosition()) <= r
|
||||
&& !mob->IsEngaged()
|
||||
&& ((!mob->IsPet()) || (mob->IsPet() && mob->GetOwner() && !mob->GetOwner()->IsClient()))
|
||||
// If we're a pet we don't react to any calls for help if our owner is a client
|
||||
@@ -469,8 +467,10 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
||||
//Father Nitwit: make sure we can see them.
|
||||
if(mob->CheckLosFN(sender)) {
|
||||
#if (EQDEBUG>=5)
|
||||
LogFile->write(EQEMuLog::Debug, "AIYellForHelp(\"%s\",\"%s\") %s attacking %s Dist %f Z %f",
|
||||
sender->GetName(), attacker->GetName(), mob->GetName(), attacker->GetName(), mob->DistNoRoot(*sender), fabs(sender->GetZ()+mob->GetZ()));
|
||||
Log.Out(Logs::General, Logs::None, "AIYellForHelp(\"%s\",\"%s\") %s attacking %s Dist %f Z %f",
|
||||
sender->GetName(), attacker->GetName(), mob->GetName(),
|
||||
attacker->GetName(), DistanceSquared(mob->GetPosition(),
|
||||
sender->GetPosition()), fabs(sender->GetZ()+mob->GetZ()));
|
||||
#endif
|
||||
mob->AddToHateList(attacker, 1, 0, false);
|
||||
}
|
||||
@@ -481,7 +481,7 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
||||
}
|
||||
|
||||
/*
|
||||
solar: returns false if attack should not be allowed
|
||||
returns false if attack should not be allowed
|
||||
I try to list every type of conflict that's possible here, so it's easy
|
||||
to see how the decision is made. Yea, it could be condensed and made
|
||||
faster, but I'm doing it this way to make it readable and easy to modify
|
||||
@@ -550,7 +550,7 @@ bool Mob::IsAttackAllowed(Mob *target, bool isSpellAttack)
|
||||
}
|
||||
}
|
||||
|
||||
// solar: the format here is a matrix of mob type vs mob type.
|
||||
// the format here is a matrix of mob type vs mob type.
|
||||
// redundant ones are omitted and the reverse is tried if it falls through.
|
||||
|
||||
// first figure out if we're pets. we always look at the master's flags.
|
||||
@@ -696,12 +696,12 @@ type', in which case, the answer is yes.
|
||||
}
|
||||
while( reverse++ == 0 );
|
||||
|
||||
LogFile->write(EQEMuLog::Debug, "Mob::IsAttackAllowed: don't have a rule for this - %s vs %s\n", this->GetName(), target->GetName());
|
||||
Log.Out(Logs::General, Logs::None, "Mob::IsAttackAllowed: don't have a rule for this - %s vs %s\n", this->GetName(), target->GetName());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// solar: this is to check if non detrimental things are allowed to be done
|
||||
// this is to check if non detrimental things are allowed to be done
|
||||
// to the target. clients cannot affect npcs and vice versa, and clients
|
||||
// cannot affect other clients that are not of the same pvp flag as them.
|
||||
// also goes for their pets
|
||||
@@ -717,7 +717,7 @@ bool Mob::IsBeneficialAllowed(Mob *target)
|
||||
if (target->GetAllowBeneficial())
|
||||
return true;
|
||||
|
||||
// solar: see IsAttackAllowed for notes
|
||||
// see IsAttackAllowed for notes
|
||||
|
||||
// first figure out if we're pets. we always look at the master's flags.
|
||||
// no need to compare pets to anything
|
||||
@@ -836,7 +836,7 @@ bool Mob::IsBeneficialAllowed(Mob *target)
|
||||
}
|
||||
while( reverse++ == 0 );
|
||||
|
||||
LogFile->write(EQEMuLog::Debug, "Mob::IsBeneficialAllowed: don't have a rule for this - %s to %s\n", this->GetName(), target->GetName());
|
||||
Log.Out(Logs::General, Logs::None, "Mob::IsBeneficialAllowed: don't have a rule for this - %s to %s\n", this->GetName(), target->GetName());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -877,7 +877,7 @@ bool Mob::CombatRange(Mob* other)
|
||||
if (size_mod > 10000)
|
||||
size_mod = size_mod / 7;
|
||||
|
||||
float _DistNoRoot = DistNoRoot(*other);
|
||||
float _DistNoRoot = DistanceSquared(m_Position, other->GetPosition());
|
||||
|
||||
if (GetSpecialAbility(NPC_CHASE_DISTANCE)){
|
||||
|
||||
@@ -934,8 +934,8 @@ bool Mob::CheckLosFN(float posX, float posY, float posZ, float mobSize) {
|
||||
#endif
|
||||
}
|
||||
|
||||
Map::Vertex myloc;
|
||||
Map::Vertex oloc;
|
||||
glm::vec3 myloc;
|
||||
glm::vec3 oloc;
|
||||
|
||||
#define LOS_DEFAULT_HEIGHT 6.0f
|
||||
|
||||
@@ -948,7 +948,7 @@ bool Mob::CheckLosFN(float posX, float posY, float posZ, float mobSize) {
|
||||
oloc.z = posZ + (mobSize==0.0?LOS_DEFAULT_HEIGHT:mobSize)/2 * SEE_POSITION;
|
||||
|
||||
#if LOSDEBUG>=5
|
||||
LogFile->write(EQEMuLog::Debug, "LOS from (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f) sizes: (%.2f, %.2f)", myloc.x, myloc.y, myloc.z, oloc.x, oloc.y, oloc.z, GetSize(), mobSize);
|
||||
Log.Out(Logs::General, Logs::None, "LOS from (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f) sizes: (%.2f, %.2f)", myloc.x, myloc.y, myloc.z, oloc.x, oloc.y, oloc.z, GetSize(), mobSize);
|
||||
#endif
|
||||
return zone->zonemap->CheckLoS(myloc, oloc);
|
||||
}
|
||||
@@ -1233,7 +1233,7 @@ void Mob::ClearFeignMemory() {
|
||||
AIfeignremember_timer->Disable();
|
||||
}
|
||||
|
||||
bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) {
|
||||
bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) {
|
||||
|
||||
/*
|
||||
Charm formula is correct based on over 50 hours of personal live parsing - Kayen
|
||||
@@ -1260,9 +1260,9 @@ bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) {
|
||||
return true;
|
||||
|
||||
if (RuleB(Spells, CharismaCharmDuration))
|
||||
resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster,0,0,true,true);
|
||||
resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster,false,0,true,true);
|
||||
else
|
||||
resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, 0,0, false, true);
|
||||
resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, false,0, false, true);
|
||||
|
||||
//2: The mob makes a resistance check against the charm
|
||||
if (resist_check == 100)
|
||||
@@ -1286,8 +1286,7 @@ bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) {
|
||||
{
|
||||
// Assume this is a harmony/pacify spell
|
||||
// If 'Lull' spell resists, do a second resist check with a charisma modifier AND regular resist checks. If resists agian you gain aggro.
|
||||
resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, true);
|
||||
|
||||
resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, false,0,true);
|
||||
if (resist_check == 100)
|
||||
return true;
|
||||
}
|
||||
|
||||
+126
-129
@@ -16,11 +16,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if EQDEBUG >= 5
|
||||
//#define ATTACK_DEBUG 20
|
||||
#endif
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eq_constants.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/rulesys.h"
|
||||
@@ -61,9 +57,9 @@ bool Mob::AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* w
|
||||
int type = 0;
|
||||
if (weapon && weapon->IsType(ItemClassCommon)) {
|
||||
const Item_Struct* item = weapon->GetItem();
|
||||
#if EQDEBUG >= 11
|
||||
LogFile->write(EQEMuLog::Debug, "Weapon skill:%i", item->ItemType);
|
||||
#endif
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Attack, "Weapon skill : %i", item->ItemType);
|
||||
|
||||
switch (item->ItemType)
|
||||
{
|
||||
case ItemType1HSlash: // 1H Slashing
|
||||
@@ -192,10 +188,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
||||
if(attacker->IsNPC() && !attacker->IsPet())
|
||||
chancetohit += RuleR(Combat, NPCBonusHitChance);
|
||||
|
||||
#if ATTACK_DEBUG>=11
|
||||
LogFile->write(EQEMuLog::Debug, "CheckHitChance(%s) attacked by %s", defender->GetName(), attacker->GetName());
|
||||
#endif
|
||||
mlog(COMBAT__TOHIT,"CheckHitChance(%s) attacked by %s", defender->GetName(), attacker->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Attack, "CheckHitChance(%s) attacked by %s", defender->GetName(), attacker->GetName());
|
||||
|
||||
bool pvpmode = false;
|
||||
if(IsClient() && other->IsClient())
|
||||
@@ -216,7 +209,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
||||
|
||||
//Calculate the level difference
|
||||
|
||||
mlog(COMBAT__TOHIT, "Chance to hit before level diff calc %.2f", chancetohit);
|
||||
Log.Out(Logs::Detail, Logs::Attack, "Chance to hit before level diff calc %.2f", chancetohit);
|
||||
|
||||
double level_difference = attacker_level - defender_level;
|
||||
double range = defender->GetLevel();
|
||||
@@ -244,32 +237,32 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
||||
chancetohit += (RuleR(Combat,HitBonusPerLevel) * level_difference);
|
||||
}
|
||||
|
||||
mlog(COMBAT__TOHIT, "Chance to hit after level diff calc %.2f", chancetohit);
|
||||
Log.Out(Logs::Detail, Logs::Attack, "Chance to hit after level diff calc %.2f", chancetohit);
|
||||
|
||||
chancetohit -= ((float)defender->GetAGI() * RuleR(Combat, AgiHitFactor));
|
||||
|
||||
mlog(COMBAT__TOHIT, "Chance to hit after agil calc %.2f", chancetohit);
|
||||
Log.Out(Logs::Detail, Logs::Attack, "Chance to hit after Agility calc %.2f", chancetohit);
|
||||
|
||||
if(attacker->IsClient())
|
||||
{
|
||||
chancetohit -= (RuleR(Combat,WeaponSkillFalloff) * (attacker->CastToClient()->MaxSkill(skillinuse) - attacker->GetSkill(skillinuse)));
|
||||
mlog(COMBAT__TOHIT, "Chance to hit after weapon falloff calc (attack) %.2f", chancetohit);
|
||||
Log.Out(Logs::Detail, Logs::Attack, "Chance to hit after agil calc %.2f", "Chance to hit after weapon falloff calc (attack) %.2f", chancetohit);
|
||||
}
|
||||
|
||||
if(defender->IsClient())
|
||||
{
|
||||
chancetohit += (RuleR(Combat,WeaponSkillFalloff) * (defender->CastToClient()->MaxSkill(SkillDefense) - defender->GetSkill(SkillDefense)));
|
||||
mlog(COMBAT__TOHIT, "Chance to hit after weapon falloff calc (defense) %.2f", chancetohit);
|
||||
Log.Out(Logs::Detail, Logs::Attack, "Chance to hit after weapon falloff calc (defense) %.2f", chancetohit);
|
||||
}
|
||||
|
||||
//I dont think this is 100% correct, but at least it does something...
|
||||
if(attacker->spellbonuses.MeleeSkillCheckSkill == skillinuse || attacker->spellbonuses.MeleeSkillCheckSkill == 255) {
|
||||
chancetohit += attacker->spellbonuses.MeleeSkillCheck;
|
||||
mlog(COMBAT__TOHIT, "Applied spell melee skill bonus %d, yeilding %.2f", attacker->spellbonuses.MeleeSkillCheck, chancetohit);
|
||||
Log.Out(Logs::Detail, Logs::Attack, "Applied spell melee skill bonus %d, yeilding %.2f", attacker->spellbonuses.MeleeSkillCheck, chancetohit);
|
||||
}
|
||||
if(attacker->itembonuses.MeleeSkillCheckSkill == skillinuse || attacker->itembonuses.MeleeSkillCheckSkill == 255) {
|
||||
chancetohit += attacker->itembonuses.MeleeSkillCheck;
|
||||
mlog(COMBAT__TOHIT, "Applied item melee skill bonus %d, yeilding %.2f", attacker->spellbonuses.MeleeSkillCheck, chancetohit);
|
||||
Log.Out(Logs::Detail, Logs::Attack, "Applied item melee skill bonus %d, yeilding %.2f", attacker->spellbonuses.MeleeSkillCheck, chancetohit);
|
||||
}
|
||||
|
||||
//Avoidance Bonuses on defender decreases baseline hit chance by percent.
|
||||
@@ -316,7 +309,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
||||
|
||||
//Calculate final chance to hit
|
||||
chancetohit += ((chancetohit * (hitBonus - avoidanceBonus)) / 100.0f);
|
||||
mlog(COMBAT__TOHIT, "Chance to hit %.2f after accuracy calc %.2f and avoidance calc %.2f", chancetohit, hitBonus, avoidanceBonus);
|
||||
Log.Out(Logs::Detail, Logs::Attack, "Chance to hit %.2f after accuracy calc %.2f and avoidance calc %.2f", chancetohit, hitBonus, avoidanceBonus);
|
||||
|
||||
chancetohit = mod_hit_chance(chancetohit, skillinuse, attacker);
|
||||
|
||||
@@ -334,9 +327,9 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
||||
//I dont know the best way to handle a garunteed hit discipline being used
|
||||
//agains a garunteed riposte (for example) discipline... for now, garunteed hit wins
|
||||
|
||||
#if EQDEBUG>=11
|
||||
LogFile->write(EQEMuLog::Debug, "3 FINAL calculated chance to hit is: %5.2f", chancetohit);
|
||||
#endif
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Attack, "3 FINAL calculated chance to hit is: %5.2f", chancetohit);
|
||||
|
||||
|
||||
//
|
||||
// Did we hit?
|
||||
@@ -344,14 +337,14 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
||||
|
||||
float tohit_roll = zone->random.Real(0, 100);
|
||||
|
||||
mlog(COMBAT__TOHIT, "Final hit chance: %.2f%%. Hit roll %.2f", chancetohit, tohit_roll);
|
||||
Log.Out(Logs::Detail, Logs::Attack, "Final hit chance: %.2f%%. Hit roll %.2f", chancetohit, tohit_roll);
|
||||
|
||||
return(tohit_roll <= chancetohit);
|
||||
}
|
||||
|
||||
bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
||||
{
|
||||
/* solar: called when a mob is attacked, does the checks to see if it's a hit
|
||||
/* called when a mob is attacked, does the checks to see if it's a hit
|
||||
* and does other mitigation checks. 'this' is the mob being attacked.
|
||||
*
|
||||
* special return values:
|
||||
@@ -378,7 +371,7 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
||||
/////////////////////////////////////////////////////////
|
||||
if (IsEnraged() && other->InFrontMob(this, other->GetX(), other->GetY())) {
|
||||
damage = -3;
|
||||
mlog(COMBAT__DAMAGE, "I am enraged, riposting frontal attack.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "I am enraged, riposting frontal attack.");
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
@@ -525,7 +518,7 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
||||
}
|
||||
}
|
||||
|
||||
mlog(COMBAT__DAMAGE, "Final damage after all avoidances: %d", damage);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Final damage after all avoidances: %d", damage);
|
||||
|
||||
if (damage < 0)
|
||||
return true;
|
||||
@@ -698,9 +691,9 @@ void Mob::MeleeMitigation(Mob *attacker, int32 &damage, int32 minhit, ExtraAttac
|
||||
damage -= (myac * zone->random.Int(0, acrandom) / 10000);
|
||||
}
|
||||
if (damage<1) damage=1;
|
||||
mlog(COMBAT__DAMAGE, "AC Damage Reduction: fail chance %d%%. Failed. Reduction %.3f%%, random %d. Resulting damage %d.", acfail, acreduction, acrandom, damage);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "AC Damage Reduction: fail chance %d%%. Failed. Reduction %.3f%%, random %d. Resulting damage %d.", acfail, acreduction, acrandom, damage);
|
||||
} else {
|
||||
mlog(COMBAT__DAMAGE, "AC Damage Reduction: fail chance %d%%. Did not fail.", acfail);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "AC Damage Reduction: fail chance %d%%. Did not fail.", acfail);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1136,14 +1129,14 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
{
|
||||
if (!other) {
|
||||
SetTarget(nullptr);
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Client::Attack() for evaluation!");
|
||||
Log.Out(Logs::General, Logs::Error, "A null Mob object was passed to Client::Attack() for evaluation!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!GetTarget())
|
||||
SetTarget(other);
|
||||
|
||||
mlog(COMBAT__ATTACKS, "Attacking %s with hand %d %s", other?other->GetName():"(nullptr)", Hand, bRiposte?"(this is a riposte)":"");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attacking %s with hand %d %s", other?other->GetName():"(nullptr)", Hand, bRiposte?"(this is a riposte)":"");
|
||||
|
||||
//SetAttackTimer();
|
||||
if (
|
||||
@@ -1153,12 +1146,12 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
|| (GetHP() < 0)
|
||||
|| (!IsAttackAllowed(other))
|
||||
) {
|
||||
mlog(COMBAT__ATTACKS, "Attack canceled, invalid circumstances.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attack canceled, invalid circumstances.");
|
||||
return false; // Only bards can attack while casting
|
||||
}
|
||||
|
||||
if(DivineAura() && !GetGM()) {//cant attack while invulnerable unless your a gm
|
||||
mlog(COMBAT__ATTACKS, "Attack canceled, Divine Aura is in effect.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attack canceled, Divine Aura is in effect.");
|
||||
Message_StringID(MT_DefaultText, DIVINE_AURA_NO_ATK); //You can't attack while invulnerable!
|
||||
return false;
|
||||
}
|
||||
@@ -1178,19 +1171,19 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
|
||||
if(weapon != nullptr) {
|
||||
if (!weapon->IsWeapon()) {
|
||||
mlog(COMBAT__ATTACKS, "Attack canceled, Item %s (%d) is not a weapon.", weapon->GetItem()->Name, weapon->GetID());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attack canceled, Item %s (%d) is not a weapon.", weapon->GetItem()->Name, weapon->GetID());
|
||||
return(false);
|
||||
}
|
||||
mlog(COMBAT__ATTACKS, "Attacking with weapon: %s (%d)", weapon->GetItem()->Name, weapon->GetID());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attacking with weapon: %s (%d)", weapon->GetItem()->Name, weapon->GetID());
|
||||
} else {
|
||||
mlog(COMBAT__ATTACKS, "Attacking without a weapon.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attacking without a weapon.");
|
||||
}
|
||||
|
||||
// calculate attack_skill and skillinuse depending on hand and weapon
|
||||
// also send Packet to near clients
|
||||
SkillUseTypes skillinuse;
|
||||
AttackAnimation(skillinuse, Hand, weapon);
|
||||
mlog(COMBAT__ATTACKS, "Attacking with %s in slot %d using skill %d", weapon?weapon->GetItem()->Name:"Fist", Hand, skillinuse);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attacking with %s in slot %d using skill %d", weapon?weapon->GetItem()->Name:"Fist", Hand, skillinuse);
|
||||
|
||||
/// Now figure out damage
|
||||
int damage = 0;
|
||||
@@ -1208,7 +1201,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
if(IsBerserk() && GetClass() == BERSERKER){
|
||||
int bonus = 3 + GetLevel()/10; //unverified
|
||||
weapon_damage = weapon_damage * (100+bonus) / 100;
|
||||
mlog(COMBAT__DAMAGE, "Berserker damage bonus increases DMG to %d", weapon_damage);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Berserker damage bonus increases DMG to %d", weapon_damage);
|
||||
}
|
||||
|
||||
//try a finishing blow.. if successful end the attack
|
||||
@@ -1276,7 +1269,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
|
||||
damage = mod_client_damage(damage, skillinuse, Hand, weapon, other);
|
||||
|
||||
mlog(COMBAT__DAMAGE, "Damage calculated to %d (min %d, max %d, str %d, skill %d, DMG %d, lv %d)",
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Damage calculated to %d (min %d, max %d, str %d, skill %d, DMG %d, lv %d)",
|
||||
damage, min_hit, max_hit, GetSTR(), GetSkill(skillinuse), weapon_damage, mylevel);
|
||||
|
||||
int hit_chance_bonus = 0;
|
||||
@@ -1291,7 +1284,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
|
||||
//check to see if we hit..
|
||||
if(!other->CheckHitChance(this, skillinuse, Hand, hit_chance_bonus)) {
|
||||
mlog(COMBAT__ATTACKS, "Attack missed. Damage set to 0.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attack missed. Damage set to 0.");
|
||||
damage = 0;
|
||||
} else { //we hit, try to avoid it
|
||||
other->AvoidDamage(this, damage);
|
||||
@@ -1299,7 +1292,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
if(damage > 0)
|
||||
CommonOutgoingHitSuccess(other, damage, skillinuse);
|
||||
|
||||
mlog(COMBAT__DAMAGE, "Final damage after all reductions: %d", damage);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Final damage after all reductions: %d", damage);
|
||||
}
|
||||
|
||||
//riposte
|
||||
@@ -1386,7 +1379,7 @@ void Client::Damage(Mob* other, int32 damage, uint16 spell_id, SkillUseTypes att
|
||||
if(spell_id==0)
|
||||
spell_id = SPELL_UNKNOWN;
|
||||
|
||||
// cut all PVP spell damage to 2/3 -solar
|
||||
// cut all PVP spell damage to 2/3
|
||||
// Blasting ourselfs is considered PvP
|
||||
//Don't do PvP mitigation if the caster is damaging himself
|
||||
if(other && other->IsClient() && (other != this) && damage > 0) {
|
||||
@@ -1438,7 +1431,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
||||
}
|
||||
|
||||
int exploss = 0;
|
||||
mlog(COMBAT__HITS, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killerMob ? killerMob->GetName() : "Unknown", damage, spell, attack_skill);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killerMob ? killerMob->GetName() : "Unknown", damage, spell, attack_skill);
|
||||
|
||||
/*
|
||||
#1: Send death packet to everyone
|
||||
@@ -1592,10 +1585,12 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
||||
|
||||
//this generates a lot of 'updates' to the client that the client does not need
|
||||
BuffFadeNonPersistDeath();
|
||||
if((GetClientVersionBit() & BIT_SoFAndLater) && RuleB(Character, RespawnFromHover))
|
||||
UnmemSpellAll(true);
|
||||
else
|
||||
UnmemSpellAll(false);
|
||||
if (RuleB(Character, UnmemSpellsOnDeath)) {
|
||||
if((GetClientVersionBit() & BIT_SoFAndLater) && RuleB(Character, RespawnFromHover))
|
||||
UnmemSpellAll(true);
|
||||
else
|
||||
UnmemSpellAll(false);
|
||||
}
|
||||
|
||||
if((RuleB(Character, LeaveCorpses) && GetLevel() >= RuleI(Character, DeathItemLossLevel)) || RuleB(Character, LeaveNakedCorpses))
|
||||
{
|
||||
@@ -1700,7 +1695,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
|
||||
if (!other) {
|
||||
SetTarget(nullptr);
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to NPC::Attack() for evaluation!");
|
||||
Log.Out(Logs::General, Logs::Error, "A null Mob object was passed to NPC::Attack() for evaluation!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1718,7 +1713,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
if (other->IsClient())
|
||||
other->CastToClient()->RemoveXTarget(this, false);
|
||||
RemoveFromHateList(other);
|
||||
mlog(COMBAT__ATTACKS, "I am not allowed to attack %s", other->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "I am not allowed to attack %s", other->GetName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1745,10 +1740,10 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
//We dont factor much from the weapon into the attack.
|
||||
//Just the skill type so it doesn't look silly using punching animations and stuff while wielding weapons
|
||||
if(weapon) {
|
||||
mlog(COMBAT__ATTACKS, "Attacking with weapon: %s (%d) (too bad im not using it for much)", weapon->Name, weapon->ID);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attacking with weapon: %s (%d) (too bad im not using it for much)", weapon->Name, weapon->ID);
|
||||
|
||||
if(Hand == MainSecondary && weapon->ItemType == ItemTypeShield){
|
||||
mlog(COMBAT__ATTACKS, "Attack with shield canceled.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attack with shield canceled.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1837,11 +1832,11 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
|
||||
//check if we're hitting above our max or below it.
|
||||
if((min_dmg+eleBane) != 0 && damage < (min_dmg+eleBane)) {
|
||||
mlog(COMBAT__DAMAGE, "Damage (%d) is below min (%d). Setting to min.", damage, (min_dmg+eleBane));
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Damage (%d) is below min (%d). Setting to min.", damage, (min_dmg+eleBane));
|
||||
damage = (min_dmg+eleBane);
|
||||
}
|
||||
if((max_dmg+eleBane) != 0 && damage > (max_dmg+eleBane)) {
|
||||
mlog(COMBAT__DAMAGE, "Damage (%d) is above max (%d). Setting to max.", damage, (max_dmg+eleBane));
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Damage (%d) is above max (%d). Setting to max.", damage, (max_dmg+eleBane));
|
||||
damage = (max_dmg+eleBane);
|
||||
}
|
||||
|
||||
@@ -1854,7 +1849,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
}
|
||||
|
||||
if(other->IsClient() && other->CastToClient()->IsSitting()) {
|
||||
mlog(COMBAT__DAMAGE, "Client %s is sitting. Hitting for max damage (%d).", other->GetName(), (max_dmg+eleBane));
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Client %s is sitting. Hitting for max damage (%d).", other->GetName(), (max_dmg+eleBane));
|
||||
damage = (max_dmg+eleBane);
|
||||
damage += (itembonuses.HeroicSTR / 10) + (damage * other->GetSkillDmgTaken(skillinuse) / 100) + GetSkillDmgAmt(skillinuse);
|
||||
|
||||
@@ -1865,7 +1860,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
hate += opts->hate_flat;
|
||||
}
|
||||
|
||||
mlog(COMBAT__HITS, "Generating hate %d towards %s", hate, GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Generating hate %d towards %s", hate, GetName());
|
||||
// now add done damage to the hate list
|
||||
other->AddToHateList(this, hate);
|
||||
|
||||
@@ -1889,7 +1884,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
if(damage > 0) {
|
||||
CommonOutgoingHitSuccess(other, damage, skillinuse);
|
||||
}
|
||||
mlog(COMBAT__HITS, "Generating hate %d towards %s", hate, GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Generating hate %d towards %s", hate, GetName());
|
||||
// now add done damage to the hate list
|
||||
if(damage > 0)
|
||||
other->AddToHateList(this, hate);
|
||||
@@ -1898,7 +1893,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
}
|
||||
}
|
||||
|
||||
mlog(COMBAT__DAMAGE, "Final damage against %s: %d", other->GetName(), damage);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Final damage against %s: %d", other->GetName(), damage);
|
||||
|
||||
if(other->IsClient() && IsPet() && GetOwner()->IsClient()) {
|
||||
//pets do half damage to clients in pvp
|
||||
@@ -1910,7 +1905,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
|
||||
//cant riposte a riposte
|
||||
if (bRiposte && damage == -3) {
|
||||
mlog(COMBAT__DAMAGE, "Riposte of riposte canceled.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Riposte of riposte canceled.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1962,7 +1957,7 @@ void NPC::Damage(Mob* other, int32 damage, uint16 spell_id, SkillUseTypes attack
|
||||
//handle EVENT_ATTACK. Resets after we have not been attacked for 12 seconds
|
||||
if(attacked_timer.Check())
|
||||
{
|
||||
mlog(COMBAT__HITS, "Triggering EVENT_ATTACK due to attack by %s", other->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Triggering EVENT_ATTACK due to attack by %s", other->GetName());
|
||||
parse->EventNPC(EVENT_ATTACK, this, other, "", 0);
|
||||
}
|
||||
attacked_timer.Start(CombatEventTimer_expire);
|
||||
@@ -1999,7 +1994,7 @@ void NPC::Damage(Mob* other, int32 damage, uint16 spell_id, SkillUseTypes attack
|
||||
}
|
||||
|
||||
bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack_skill) {
|
||||
mlog(COMBAT__HITS, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killerMob->GetName(), damage, spell, attack_skill);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killerMob->GetName(), damage, spell, attack_skill);
|
||||
|
||||
bool MadeCorpse = false;
|
||||
uint16 OrigEntID = this->GetID();
|
||||
@@ -2039,9 +2034,7 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
if (IsEngaged())
|
||||
{
|
||||
zone->DelAggroMob();
|
||||
#if EQDEBUG >= 11
|
||||
LogFile->write(EQEMuLog::Debug,"NPC::Death() Mobs currently Aggro %i", zone->MobsAggroCount());
|
||||
#endif
|
||||
Log.Out(Logs::Detail, Logs::Attack, "%s Mobs currently Aggro %i", __FUNCTION__, zone->MobsAggroCount());
|
||||
}
|
||||
SetHP(0);
|
||||
SetPet(0);
|
||||
@@ -2486,7 +2479,7 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
|
||||
}
|
||||
|
||||
if(IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
||||
if(!zone->watermap->InLiquid(other->GetX(), other->GetY(), other->GetZ())) {
|
||||
if(!zone->watermap->InLiquid(glm::vec3(other->GetPosition()))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2569,7 +2562,7 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
|
||||
}
|
||||
}
|
||||
|
||||
// solar: this is called from Damage() when 'this' is attacked by 'other.
|
||||
// this is called from Damage() when 'this' is attacked by 'other.
|
||||
// 'this' is the one being attacked
|
||||
// 'other' is the attacker
|
||||
// a damage shield causes damage (or healing) to whoever attacks the wearer
|
||||
@@ -2604,7 +2597,7 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) {
|
||||
if(DS == 0 && rev_ds == 0)
|
||||
return;
|
||||
|
||||
mlog(COMBAT__HITS, "Applying Damage Shield of value %d to %s", DS, attacker->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Applying Damage Shield of value %d to %s", DS, attacker->GetName());
|
||||
|
||||
//invert DS... spells yield negative values for a true damage shield
|
||||
if(DS < 0) {
|
||||
@@ -2649,7 +2642,7 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) {
|
||||
rev_ds_spell_id = spellbonuses.ReverseDamageShieldSpellID;
|
||||
|
||||
if(rev_ds < 0) {
|
||||
mlog(COMBAT__HITS, "Applying Reverse Damage Shield of value %d to %s", rev_ds, attacker->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Applying Reverse Damage Shield of value %d to %s", rev_ds, attacker->GetName());
|
||||
attacker->Damage(this, -rev_ds, rev_ds_spell_id, SkillAbjuration/*hackish*/, false); //"this" (us) will get the hate, etc. not sure how this works on Live, but it'll works for now, and tanks will love us for this
|
||||
//do we need to send a damage packet here also?
|
||||
}
|
||||
@@ -3161,7 +3154,7 @@ int32 Mob::ReduceDamage(int32 damage)
|
||||
int damage_to_reduce = damage * spellbonuses.MeleeThresholdGuard[0] / 100;
|
||||
if(damage_to_reduce >= buffs[slot].melee_rune)
|
||||
{
|
||||
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MeleeThresholdGuard %d damage negated, %d"
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Mob::ReduceDamage SE_MeleeThresholdGuard %d damage negated, %d"
|
||||
" damage remaining, fading buff.", damage_to_reduce, buffs[slot].melee_rune);
|
||||
damage -= buffs[slot].melee_rune;
|
||||
if(!TryFadeEffect(slot))
|
||||
@@ -3169,7 +3162,7 @@ int32 Mob::ReduceDamage(int32 damage)
|
||||
}
|
||||
else
|
||||
{
|
||||
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MeleeThresholdGuard %d damage negated, %d"
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Mob::ReduceDamage SE_MeleeThresholdGuard %d damage negated, %d"
|
||||
" damage remaining.", damage_to_reduce, buffs[slot].melee_rune);
|
||||
buffs[slot].melee_rune = (buffs[slot].melee_rune - damage_to_reduce);
|
||||
damage -= damage_to_reduce;
|
||||
@@ -3188,7 +3181,7 @@ int32 Mob::ReduceDamage(int32 damage)
|
||||
|
||||
if(spellbonuses.MitigateMeleeRune[3] && (damage_to_reduce >= buffs[slot].melee_rune))
|
||||
{
|
||||
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
|
||||
" damage remaining, fading buff.", damage_to_reduce, buffs[slot].melee_rune);
|
||||
damage -= buffs[slot].melee_rune;
|
||||
if(!TryFadeEffect(slot))
|
||||
@@ -3196,7 +3189,7 @@ int32 Mob::ReduceDamage(int32 damage)
|
||||
}
|
||||
else
|
||||
{
|
||||
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
|
||||
" damage remaining.", damage_to_reduce, buffs[slot].melee_rune);
|
||||
|
||||
if (spellbonuses.MitigateMeleeRune[3])
|
||||
@@ -3314,7 +3307,7 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
|
||||
|
||||
if(spellbonuses.MitigateSpellRune[3] && (damage_to_reduce >= buffs[slot].magic_rune))
|
||||
{
|
||||
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateSpellDamage %d damage negated, %d"
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Mob::ReduceDamage SE_MitigateSpellDamage %d damage negated, %d"
|
||||
" damage remaining, fading buff.", damage_to_reduce, buffs[slot].magic_rune);
|
||||
damage -= buffs[slot].magic_rune;
|
||||
if(!TryFadeEffect(slot))
|
||||
@@ -3322,7 +3315,7 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
|
||||
}
|
||||
else
|
||||
{
|
||||
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
|
||||
" damage remaining.", damage_to_reduce, buffs[slot].magic_rune);
|
||||
|
||||
if (spellbonuses.MitigateSpellRune[3])
|
||||
@@ -3363,7 +3356,7 @@ int32 Mob::ReduceAllDamage(int32 damage)
|
||||
}
|
||||
}
|
||||
|
||||
CheckNumHitsRemaining(NUMHIT_IncomingDamage);
|
||||
CheckNumHitsRemaining(NumHit::IncomingDamage);
|
||||
|
||||
return(damage);
|
||||
}
|
||||
@@ -3461,11 +3454,11 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
// This method is called with skill_used=ABJURE for Damage Shield damage.
|
||||
bool FromDamageShield = (skill_used == SkillAbjuration);
|
||||
|
||||
mlog(COMBAT__HITS, "Applying damage %d done by %s with skill %d and spell %d, avoidable? %s, is %sa buff tic in slot %d",
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Applying damage %d done by %s with skill %d and spell %d, avoidable? %s, is %sa buff tic in slot %d",
|
||||
damage, attacker?attacker->GetName():"NOBODY", skill_used, spell_id, avoidable?"yes":"no", iBuffTic?"":"not ", buffslot);
|
||||
|
||||
if (GetInvul() || DivineAura()) {
|
||||
mlog(COMBAT__DAMAGE, "Avoiding %d damage due to invulnerability.", damage);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Avoiding %d damage due to invulnerability.", damage);
|
||||
damage = -5;
|
||||
}
|
||||
|
||||
@@ -3479,10 +3472,10 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
}
|
||||
|
||||
if (spell_id == SPELL_UNKNOWN && skill_used) {
|
||||
CheckNumHitsRemaining(NUMHIT_IncomingHitAttempts);
|
||||
CheckNumHitsRemaining(NumHit::IncomingHitAttempts);
|
||||
|
||||
if (attacker)
|
||||
attacker->CheckNumHitsRemaining(NUMHIT_OutgoingHitAttempts);
|
||||
attacker->CheckNumHitsRemaining(NumHit::OutgoingHitAttempts);
|
||||
}
|
||||
|
||||
if(attacker){
|
||||
@@ -3517,7 +3510,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
int healed = damage;
|
||||
|
||||
healed = attacker->GetActSpellHealing(spell_id, healed);
|
||||
mlog(COMBAT__DAMAGE, "Applying lifetap heal of %d to %s", healed, attacker->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Applying lifetap heal of %d to %s", healed, attacker->GetName());
|
||||
attacker->HealDamage(healed);
|
||||
|
||||
//we used to do a message to the client, but its gone now.
|
||||
@@ -3530,7 +3523,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
if (pet && !pet->IsFamiliar() && !pet->GetSpecialAbility(IMMUNE_AGGRO) && !pet->IsEngaged() && attacker && attacker != this && !attacker->IsCorpse())
|
||||
{
|
||||
if (!pet->IsHeld()) {
|
||||
mlog(PETS__AGGRO, "Sending pet %s into battle due to attack.", pet->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Sending pet %s into battle due to attack.", pet->GetName());
|
||||
pet->AddToHateList(attacker, 1);
|
||||
pet->SetTarget(attacker);
|
||||
Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName());
|
||||
@@ -3540,7 +3533,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
//see if any runes want to reduce this damage
|
||||
if(spell_id == SPELL_UNKNOWN) {
|
||||
damage = ReduceDamage(damage);
|
||||
mlog(COMBAT__HITS, "Melee Damage reduced to %d", damage);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Melee Damage reduced to %d", damage);
|
||||
damage = ReduceAllDamage(damage);
|
||||
TryTriggerThreshHold(damage, SE_TriggerMeleeThreshold, attacker);
|
||||
} else {
|
||||
@@ -3559,7 +3552,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
}
|
||||
|
||||
if (skill_used)
|
||||
CheckNumHitsRemaining(NUMHIT_IncomingHitSuccess);
|
||||
CheckNumHitsRemaining(NumHit::IncomingHitSuccess);
|
||||
|
||||
if(IsClient() && CastToClient()->sneaking){
|
||||
CastToClient()->sneaking = false;
|
||||
@@ -3597,7 +3590,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
|
||||
//fade mez if we are mezzed
|
||||
if (IsMezzed() && attacker) {
|
||||
mlog(COMBAT__HITS, "Breaking mez due to attack.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Breaking mez due to attack.");
|
||||
entity_list.MessageClose_StringID(this, true, 100, MT_WornOff,
|
||||
HAS_BEEN_AWAKENED, GetCleanName(), attacker->GetCleanName());
|
||||
BuffFadeByEffect(SE_Mez);
|
||||
@@ -3640,7 +3633,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
int stun_resist = itembonuses.StunResist + spellbonuses.StunResist;
|
||||
int frontal_stun_resist = itembonuses.FrontalStunResist + spellbonuses.FrontalStunResist;
|
||||
|
||||
mlog(COMBAT__HITS, "Stun passed, checking resists. Was %d chance.", stun_chance);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Stun passed, checking resists. Was %d chance.", stun_chance);
|
||||
if (IsClient()) {
|
||||
stun_resist += aabonuses.StunResist;
|
||||
frontal_stun_resist += aabonuses.FrontalStunResist;
|
||||
@@ -3650,20 +3643,20 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
if (((GetBaseRace() == OGRE && IsClient()) ||
|
||||
(frontal_stun_resist && zone->random.Roll(frontal_stun_resist))) &&
|
||||
!attacker->BehindMob(this, attacker->GetX(), attacker->GetY())) {
|
||||
mlog(COMBAT__HITS, "Frontal stun resisted. %d chance.", frontal_stun_resist);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Frontal stun resisted. %d chance.", frontal_stun_resist);
|
||||
} else {
|
||||
// Normal stun resist check.
|
||||
if (stun_resist && zone->random.Roll(stun_resist)) {
|
||||
if (IsClient())
|
||||
Message_StringID(MT_Stun, SHAKE_OFF_STUN);
|
||||
mlog(COMBAT__HITS, "Stun Resisted. %d chance.", stun_resist);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Stun Resisted. %d chance.", stun_resist);
|
||||
} else {
|
||||
mlog(COMBAT__HITS, "Stunned. %d resist chance.", stun_resist);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Stunned. %d resist chance.", stun_resist);
|
||||
Stun(zone->random.Int(0, 2) * 1000); // 0-2 seconds
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mlog(COMBAT__HITS, "Stun failed. %d chance.", stun_chance);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Stun failed. %d chance.", stun_chance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3677,7 +3670,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
//increment chances of interrupting
|
||||
if(IsCasting()) { //shouldnt interrupt on regular spell damage
|
||||
attacked_count++;
|
||||
mlog(COMBAT__HITS, "Melee attack while casting. Attack count %d", attacked_count);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Melee attack while casting. Attack count %d", attacked_count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3883,7 +3876,7 @@ float Mob::GetProcChances(float ProcBonus, uint16 hand)
|
||||
ProcChance += ProcChance * ProcBonus / 100.0f;
|
||||
}
|
||||
|
||||
mlog(COMBAT__PROCS, "Proc chance %.2f (%.2f from bonuses)", ProcChance, ProcBonus);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Proc chance %.2f (%.2f from bonuses)", ProcChance, ProcBonus);
|
||||
return ProcChance;
|
||||
}
|
||||
|
||||
@@ -3902,7 +3895,7 @@ float Mob::GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 h
|
||||
ProcBonus += static_cast<float>(myagi) * RuleR(Combat, DefProcPerMinAgiContrib) / 100.0f;
|
||||
ProcChance = ProcChance + (ProcChance * ProcBonus);
|
||||
|
||||
mlog(COMBAT__PROCS, "Defensive Proc chance %.2f (%.2f from bonuses)", ProcChance, ProcBonus);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Defensive Proc chance %.2f (%.2f from bonuses)", ProcChance, ProcBonus);
|
||||
return ProcChance;
|
||||
}
|
||||
|
||||
@@ -3911,7 +3904,7 @@ void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
|
||||
|
||||
if (!on) {
|
||||
SetTarget(nullptr);
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Mob::TryDefensiveProc for evaluation!");
|
||||
Log.Out(Logs::General, Logs::Error, "A null Mob object was passed to Mob::TryDefensiveProc for evaluation!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3932,7 +3925,8 @@ void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
|
||||
float chance = ProcChance * (static_cast<float>(DefensiveProcs[i].chance)/100.0f);
|
||||
if (zone->random.Roll(chance)) {
|
||||
ExecWeaponProc(nullptr, DefensiveProcs[i].spellID, on);
|
||||
CheckNumHitsRemaining(NUMHIT_DefensiveSpellProcs,0,DefensiveProcs[i].base_spellID);
|
||||
CheckNumHitsRemaining(NumHit::DefensiveSpellProcs, 0,
|
||||
DefensiveProcs[i].base_spellID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3942,17 +3936,17 @@ void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
|
||||
void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
|
||||
if(!on) {
|
||||
SetTarget(nullptr);
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Mob::TryWeaponProc for evaluation!");
|
||||
Log.Out(Logs::General, Logs::Error, "A null Mob object was passed to Mob::TryWeaponProc for evaluation!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsAttackAllowed(on)) {
|
||||
mlog(COMBAT__PROCS, "Preventing procing off of unattackable things.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Preventing procing off of unattackable things.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DivineAura()) {
|
||||
mlog(COMBAT__PROCS, "Procs canceled, Divine Aura is in effect.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Procs canceled, Divine Aura is in effect.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3999,7 +3993,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on
|
||||
static_cast<float>(weapon->ProcRate)) / 100.0f;
|
||||
if (zone->random.Roll(WPC)) { // 255 dex = 0.084 chance of proc. No idea what this number should be really.
|
||||
if (weapon->Proc.Level > ourlevel) {
|
||||
mlog(COMBAT__PROCS,
|
||||
Log.Out(Logs::Detail, Logs::Combat,
|
||||
"Tried to proc (%s), but our level (%d) is lower than required (%d)",
|
||||
weapon->Name, ourlevel, weapon->Proc.Level);
|
||||
if (IsPet()) {
|
||||
@@ -4010,7 +4004,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on
|
||||
Message_StringID(13, PROC_TOOLOW);
|
||||
}
|
||||
} else {
|
||||
mlog(COMBAT__PROCS,
|
||||
Log.Out(Logs::Detail, Logs::Combat,
|
||||
"Attacking weapon (%s) successfully procing spell %d (%.2f percent chance)",
|
||||
weapon->Name, weapon->Proc.Effect, WPC * 100);
|
||||
ExecWeaponProc(inst, weapon->Proc.Effect, on);
|
||||
@@ -4089,12 +4083,12 @@ void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on,
|
||||
// Perma procs (AAs)
|
||||
if (PermaProcs[i].spellID != SPELL_UNKNOWN) {
|
||||
if (zone->random.Roll(PermaProcs[i].chance)) { // TODO: Do these get spell bonus?
|
||||
mlog(COMBAT__PROCS,
|
||||
Log.Out(Logs::Detail, Logs::Combat,
|
||||
"Permanent proc %d procing spell %d (%d percent chance)",
|
||||
i, PermaProcs[i].spellID, PermaProcs[i].chance);
|
||||
ExecWeaponProc(nullptr, PermaProcs[i].spellID, on);
|
||||
} else {
|
||||
mlog(COMBAT__PROCS,
|
||||
Log.Out(Logs::Detail, Logs::Combat,
|
||||
"Permanent proc %d failed to proc %d (%d percent chance)",
|
||||
i, PermaProcs[i].spellID, PermaProcs[i].chance);
|
||||
}
|
||||
@@ -4104,13 +4098,14 @@ void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on,
|
||||
if (SpellProcs[i].spellID != SPELL_UNKNOWN) {
|
||||
float chance = ProcChance * (static_cast<float>(SpellProcs[i].chance) / 100.0f);
|
||||
if (zone->random.Roll(chance)) {
|
||||
mlog(COMBAT__PROCS,
|
||||
Log.Out(Logs::Detail, Logs::Combat,
|
||||
"Spell proc %d procing spell %d (%.2f percent chance)",
|
||||
i, SpellProcs[i].spellID, chance);
|
||||
ExecWeaponProc(nullptr, SpellProcs[i].spellID, on);
|
||||
CheckNumHitsRemaining(NUMHIT_OffensiveSpellProcs, 0, SpellProcs[i].base_spellID);
|
||||
CheckNumHitsRemaining(NumHit::OffensiveSpellProcs, 0,
|
||||
SpellProcs[i].base_spellID);
|
||||
} else {
|
||||
mlog(COMBAT__PROCS,
|
||||
Log.Out(Logs::Detail, Logs::Combat,
|
||||
"Spell proc %d failed to proc %d (%.2f percent chance)",
|
||||
i, SpellProcs[i].spellID, chance);
|
||||
}
|
||||
@@ -4120,13 +4115,14 @@ void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on,
|
||||
if (RangedProcs[i].spellID != SPELL_UNKNOWN) {
|
||||
float chance = ProcChance * (static_cast<float>(RangedProcs[i].chance) / 100.0f);
|
||||
if (zone->random.Roll(chance)) {
|
||||
mlog(COMBAT__PROCS,
|
||||
Log.Out(Logs::Detail, Logs::Combat,
|
||||
"Ranged proc %d procing spell %d (%.2f percent chance)",
|
||||
i, RangedProcs[i].spellID, chance);
|
||||
ExecWeaponProc(nullptr, RangedProcs[i].spellID, on);
|
||||
CheckNumHitsRemaining(NUMHIT_OffensiveSpellProcs, 0, RangedProcs[i].base_spellID);
|
||||
CheckNumHitsRemaining(NumHit::OffensiveSpellProcs, 0,
|
||||
RangedProcs[i].base_spellID);
|
||||
} else {
|
||||
mlog(COMBAT__PROCS,
|
||||
Log.Out(Logs::Detail, Logs::Combat,
|
||||
"Ranged proc %d failed to proc %d (%.2f percent chance)",
|
||||
i, RangedProcs[i].spellID, chance);
|
||||
}
|
||||
@@ -4376,7 +4372,7 @@ bool Mob::TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse)
|
||||
}
|
||||
|
||||
void Mob::DoRiposte(Mob* defender) {
|
||||
mlog(COMBAT__ATTACKS, "Preforming a riposte");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a riposte");
|
||||
|
||||
if (!defender)
|
||||
return;
|
||||
@@ -4394,7 +4390,7 @@ void Mob::DoRiposte(Mob* defender) {
|
||||
|
||||
//Live AA - Double Riposte
|
||||
if(DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||
mlog(COMBAT__ATTACKS, "Preforming a double riposed (%d percent chance)", DoubleRipChance);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a double riposed (%d percent chance)", DoubleRipChance);
|
||||
defender->Attack(this, MainPrimary, true);
|
||||
if (HasDied()) return;
|
||||
}
|
||||
@@ -4405,7 +4401,7 @@ void Mob::DoRiposte(Mob* defender) {
|
||||
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[1];
|
||||
|
||||
if(DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||
mlog(COMBAT__ATTACKS, "Preforming a return SPECIAL ATTACK (%d percent chance)", DoubleRipChance);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a return SPECIAL ATTACK (%d percent chance)", DoubleRipChance);
|
||||
|
||||
if (defender->GetClass() == MONK)
|
||||
defender->MonkSpecialAttack(this, defender->aabonuses.GiveDoubleRiposte[2]);
|
||||
@@ -4422,7 +4418,7 @@ void Mob::ApplyMeleeDamageBonus(uint16 skill, int32 &damage){
|
||||
int dmgbonusmod = 0;
|
||||
dmgbonusmod += (100*(itembonuses.STR + spellbonuses.STR))/3;
|
||||
dmgbonusmod += (100*(spellbonuses.ATK + itembonuses.ATK))/5;
|
||||
mlog(COMBAT__DAMAGE, "Damage bonus: %d percent from ATK and STR bonuses.", (dmgbonusmod/100));
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Damage bonus: %d percent from ATK and STR bonuses.", (dmgbonusmod/100));
|
||||
damage += (damage*dmgbonusmod/10000);
|
||||
}
|
||||
}
|
||||
@@ -4491,7 +4487,7 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
|
||||
|
||||
if (!on) {
|
||||
SetTarget(nullptr);
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Mob::TrySkillProc for evaluation!");
|
||||
Log.Out(Logs::General, Logs::Error, "A null Mob object was passed to Mob::TrySkillProc for evaluation!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4541,7 +4537,8 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
|
||||
float final_chance = chance * (ProcMod / 100.0f);
|
||||
if (zone->random.Roll(final_chance)) {
|
||||
ExecWeaponProc(nullptr, proc_spell_id, on);
|
||||
CheckNumHitsRemaining(NUMHIT_OffensiveSpellProcs,0, base_spell_id);
|
||||
CheckNumHitsRemaining(NumHit::OffensiveSpellProcs, 0,
|
||||
base_spell_id);
|
||||
CanProc = false;
|
||||
break;
|
||||
}
|
||||
@@ -4716,13 +4713,13 @@ bool Mob::TryRootFadeByDamage(int buffslot, Mob* attacker) {
|
||||
|
||||
if (!TryFadeEffect(spellbonuses.Root[1])) {
|
||||
BuffFadeBySlot(spellbonuses.Root[1]);
|
||||
mlog(COMBAT__HITS, "Spell broke root! BreakChance percent chance");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Spell broke root! BreakChance percent chance");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mlog(COMBAT__HITS, "Spell did not break root. BreakChance percent chance");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Spell did not break root. BreakChance percent chance");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4787,26 +4784,26 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, int32 &damage, SkillUseTypes s
|
||||
ApplyMeleeDamageBonus(skillInUse, damage);
|
||||
damage += (damage * defender->GetSkillDmgTaken(skillInUse) / 100) + (GetSkillDmgAmt(skillInUse) + defender->GetFcDamageAmtIncoming(this, 0, true, skillInUse));
|
||||
TryCriticalHit(defender, skillInUse, damage);
|
||||
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
|
||||
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
||||
}
|
||||
|
||||
void Mob::CommonBreakInvisible()
|
||||
{
|
||||
//break invis when you attack
|
||||
if(invisible) {
|
||||
mlog(COMBAT__ATTACKS, "Removing invisibility due to melee attack.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Removing invisibility due to melee attack.");
|
||||
BuffFadeByEffect(SE_Invisibility);
|
||||
BuffFadeByEffect(SE_Invisibility2);
|
||||
invisible = false;
|
||||
}
|
||||
if(invisible_undead) {
|
||||
mlog(COMBAT__ATTACKS, "Removing invisibility vs. undead due to melee attack.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Removing invisibility vs. undead due to melee attack.");
|
||||
BuffFadeByEffect(SE_InvisVsUndead);
|
||||
BuffFadeByEffect(SE_InvisVsUndead2);
|
||||
invisible_undead = false;
|
||||
}
|
||||
if(invisible_animals){
|
||||
mlog(COMBAT__ATTACKS, "Removing invisibility vs. animals due to melee attack.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Removing invisibility vs. animals due to melee attack.");
|
||||
BuffFadeByEffect(SE_InvisVsAnimals);
|
||||
invisible_animals = false;
|
||||
}
|
||||
@@ -4835,20 +4832,20 @@ void Mob::CommonBreakInvisible()
|
||||
|
||||
/* Dev quotes:
|
||||
* Old formula
|
||||
* Final delay = (Original Delay / (haste mod *.01f)) + ((Hundred Hands / 100) * Original Delay)
|
||||
* Final delay = (Original Delay / (haste mod *.01f)) + ((Hundred Hands / 100) * Original Delay)
|
||||
* New formula
|
||||
* Final delay = (Original Delay / (haste mod *.01f)) + ((Hundred Hands / 1000) * (Original Delay / (haste mod *.01f))
|
||||
* Base Delay 20 25 30 37
|
||||
* Haste 2.25 2.25 2.25 2.25
|
||||
* HHE (old) -17 -17 -17 -17
|
||||
* Final Delay 5.488888889 6.861111111 8.233333333 10.15444444
|
||||
* Final delay = (Original Delay / (haste mod *.01f)) + ((Hundred Hands / 1000) * (Original Delay / (haste mod *.01f))
|
||||
* Base Delay 20 25 30 37
|
||||
* Haste 2.25 2.25 2.25 2.25
|
||||
* HHE (old) -17 -17 -17 -17
|
||||
* Final Delay 5.488888889 6.861111111 8.233333333 10.15444444
|
||||
*
|
||||
* Base Delay 20 25 30 37
|
||||
* Haste 2.25 2.25 2.25 2.25
|
||||
* HHE (new) -383 -383 -383 -383
|
||||
* Final Delay 5.484444444 6.855555556 8.226666667 10.14622222
|
||||
* Base Delay 20 25 30 37
|
||||
* Haste 2.25 2.25 2.25 2.25
|
||||
* HHE (new) -383 -383 -383 -383
|
||||
* Final Delay 5.484444444 6.855555556 8.226666667 10.14622222
|
||||
*
|
||||
* Difference -0.004444444 -0.005555556 -0.006666667 -0.008222222
|
||||
* Difference -0.004444444 -0.005555556 -0.006666667 -0.008222222
|
||||
*
|
||||
* These times are in 10th of a second
|
||||
*/
|
||||
|
||||
+5
-18
@@ -18,7 +18,7 @@
|
||||
|
||||
/*
|
||||
|
||||
solar: Beacon class, extends Mob. Used for AE rain spells to have a mob
|
||||
Beacon class, extends Mob. Used for AE rain spells to have a mob
|
||||
target to center around.
|
||||
|
||||
*/
|
||||
@@ -35,7 +35,7 @@ class Zone;
|
||||
#include "../common/races.h"
|
||||
#include "beacon.h"
|
||||
#include "entity.h"
|
||||
#include "mob.h"
|
||||
#include "mob.h"
|
||||
|
||||
|
||||
#ifdef BOTS
|
||||
@@ -48,12 +48,12 @@ class Zone;
|
||||
extern EntityList entity_list;
|
||||
extern Zone* zone;
|
||||
|
||||
// solar: if lifetime is 0 this is a permanent beacon.. not sure if that'll be
|
||||
// if lifetime is 0 this is a permanent beacon.. not sure if that'll be
|
||||
// useful for anything
|
||||
Beacon::Beacon(Mob *at_mob, int lifetime)
|
||||
:Mob
|
||||
(
|
||||
nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, at_mob->GetPosition(), 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
),
|
||||
remove_timer(lifetime),
|
||||
@@ -67,26 +67,13 @@ Beacon::Beacon(Mob *at_mob, int lifetime)
|
||||
spell_iterations = 0;
|
||||
caster_id = 0;
|
||||
|
||||
// copy location
|
||||
x_pos = at_mob->GetX();
|
||||
y_pos = at_mob->GetY();
|
||||
z_pos = at_mob->GetZ();
|
||||
heading = at_mob->GetHeading();
|
||||
|
||||
if(lifetime)
|
||||
{
|
||||
remove_timer.Start();
|
||||
}
|
||||
#ifdef SOLAR
|
||||
entity_list.Message(0, 0, "Beacon being created at %0.2f %0.2f %0.2f heading %0.2f lifetime %d", GetX(), GetY(), GetZ(), GetHeading(), lifetime);
|
||||
#endif
|
||||
}
|
||||
|
||||
Beacon::~Beacon()
|
||||
{
|
||||
#ifdef SOLAR
|
||||
entity_list.Message(0, 0, "Beacon %d being removed at %0.2f %0.2f %0.2f heading %0.2f", GetID(), GetX(), GetY(), GetZ(), GetHeading());
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool Beacon::Process()
|
||||
|
||||
+9
-13
@@ -16,7 +16,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "../common/classes.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/item.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/skills.h"
|
||||
@@ -77,9 +77,9 @@ void Client::CalcBonuses()
|
||||
|
||||
CalcSpellBonuses(&spellbonuses);
|
||||
|
||||
_log(AA__BONUSES, "Calculating AA Bonuses for %s.", this->GetCleanName());
|
||||
Log.Out(Logs::Detail, Logs::AA, "Calculating AA Bonuses for %s.", this->GetCleanName());
|
||||
CalcAABonuses(&aabonuses); //we're not quite ready for this
|
||||
_log(AA__BONUSES, "Finished calculating AA Bonuses for %s.", this->GetCleanName());
|
||||
Log.Out(Logs::Detail, Logs::AA, "Finished calculating AA Bonuses for %s.", this->GetCleanName());
|
||||
|
||||
RecalcWeight();
|
||||
|
||||
@@ -155,7 +155,7 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
|
||||
}
|
||||
|
||||
//Power Source Slot
|
||||
if (GetClientVersion() >= EQClientSoF)
|
||||
if (GetClientVersion() >= ClientVersion::SoF)
|
||||
{
|
||||
const ItemInst* inst = m_inv[MainPowerSource];
|
||||
if(inst)
|
||||
@@ -538,11 +538,7 @@ 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
|
||||
// Search player slots for skill=14(food) and skill=15(drink)
|
||||
uint32 i;
|
||||
uint32 i;
|
||||
|
||||
bool food = false;
|
||||
bool drink = false;
|
||||
@@ -638,7 +634,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
||||
if (effect == SE_Blank || (effect == SE_CHA && base1 == 0) || effect == SE_StackingCommand_Block || effect == SE_StackingCommand_Overwrite)
|
||||
continue;
|
||||
|
||||
_log(AA__BONUSES, "Applying Effect %d from AA %u in slot %d (base1: %d, base2: %d) on %s", effect, aaid, slot, base1, base2, this->GetCleanName());
|
||||
Log.Out(Logs::Detail, Logs::AA, "Applying Effect %d from AA %u in slot %d (base1: %d, base2: %d) on %s", effect, aaid, slot, base1, base2, this->GetCleanName());
|
||||
|
||||
uint8 focus = IsFocusEffect(0, 0, true,effect);
|
||||
if (focus)
|
||||
@@ -2980,7 +2976,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
//Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
|
||||
if (IsAISpellEffect) {
|
||||
|
||||
//Non-Focused Effect to modify incomming spell damage by resist type.
|
||||
//Non-Focused Effect to modify incoming spell damage by resist type.
|
||||
case SE_FcSpellVulnerability:
|
||||
ModVulnerability(base2, effect_value);
|
||||
break;
|
||||
@@ -3086,7 +3082,7 @@ void Client::CalcItemScale() {
|
||||
changed = true;
|
||||
|
||||
//Power Source Slot
|
||||
if (GetClientVersion() >= EQClientSoF)
|
||||
if (GetClientVersion() >= ClientVersion::SoF)
|
||||
{
|
||||
if(CalcItemScale(MainPowerSource, MainPowerSource))
|
||||
changed = true;
|
||||
@@ -3180,7 +3176,7 @@ void Client::DoItemEnterZone() {
|
||||
changed = true;
|
||||
|
||||
//Power Source Slot
|
||||
if (GetClientVersion() >= EQClientSoF)
|
||||
if (GetClientVersion() >= ClientVersion::SoF)
|
||||
{
|
||||
if(DoItemEnterZone(MainPowerSource, MainPowerSource))
|
||||
changed = true;
|
||||
|
||||
+142
-132
@@ -9,7 +9,7 @@
|
||||
extern volatile bool ZoneLoaded;
|
||||
|
||||
// This constructor is used during the bot create command
|
||||
Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, 0, 0, 0, 0, 0, 0, false), rest_timer(1) {
|
||||
Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm::vec4(), 0, false), rest_timer(1) {
|
||||
if(botOwner) {
|
||||
this->SetBotOwner(botOwner);
|
||||
this->_botOwnerCharacterID = botOwner->CharacterID();
|
||||
@@ -96,10 +96,12 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, 0, 0, 0, 0,
|
||||
}
|
||||
|
||||
strcpy(this->name, this->GetCleanName());
|
||||
|
||||
active_light = spell_light = equip_light = innate_light = NOT_USED;
|
||||
}
|
||||
|
||||
// This constructor is used when the bot is loaded out of the database
|
||||
Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType npcTypeData) : NPC(&npcTypeData, 0, 0, 0, 0, 0, 0, false), rest_timer(1) {
|
||||
Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType npcTypeData) : NPC(&npcTypeData, nullptr, glm::vec4(), 0, false), rest_timer(1) {
|
||||
this->_botOwnerCharacterID = botOwnerCharacterID;
|
||||
|
||||
if(this->_botOwnerCharacterID > 0) {
|
||||
@@ -211,6 +213,8 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
|
||||
if(cur_mana > max_mana)
|
||||
cur_mana = max_mana;
|
||||
cur_end = max_end;
|
||||
|
||||
active_light = spell_light = equip_light = innate_light = NOT_USED;
|
||||
}
|
||||
|
||||
Bot::~Bot() {
|
||||
@@ -380,6 +384,8 @@ NPCType Bot::FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::str
|
||||
BotNPCType.mana_regen = 1;
|
||||
BotNPCType.maxlevel = botLevel;
|
||||
|
||||
BotNPCType.light = NOT_USED; // due to the way that bots are coded..this is sent post-spawn
|
||||
|
||||
return BotNPCType;
|
||||
}
|
||||
|
||||
@@ -1225,7 +1231,7 @@ int32 Bot::acmod()
|
||||
return (65 + ((agility-300) / 21));
|
||||
}
|
||||
#if EQDEBUG >= 11
|
||||
LogFile->write(EQEMuLog::Error, "Error in Bot::acmod(): Agility: %i, Level: %i",agility,level);
|
||||
Log.Out(Logs::General, Logs::Error, "Error in Bot::acmod(): Agility: %i, Level: %i",agility,level);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -1375,7 +1381,7 @@ int32 Bot::GenerateBaseHitPoints()
|
||||
uint32 Post255;
|
||||
uint32 NormalSTA = GetSTA();
|
||||
|
||||
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= EQClientSoD && RuleB(Character, SoDClientUseSoDHPManaEnd))
|
||||
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd))
|
||||
{
|
||||
float SoDPost255;
|
||||
|
||||
@@ -1462,7 +1468,7 @@ void Bot::LoadAAs() {
|
||||
auto results = database.QueryDatabase(query);
|
||||
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Bot::LoadAAs()");
|
||||
Log.Out(Logs::General, Logs::Error, "Error in Bot::LoadAAs()");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1564,7 +1570,7 @@ void Bot::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
||||
if (effect == SE_Blank || (effect == SE_CHA && base1 == 0) || effect == SE_StackingCommand_Block || effect == SE_StackingCommand_Overwrite)
|
||||
continue;
|
||||
|
||||
_log(AA__BONUSES, "Applying Effect %d from AA %u in slot %d (base1: %d, base2: %d) on %s", effect, aaid, slot, base1, base2, this->GetCleanName());
|
||||
Log.Out(Logs::Detail, Logs::AA, "Applying Effect %d from AA %u in slot %d (base1: %d, base2: %d) on %s", effect, aaid, slot, base1, base2, this->GetCleanName());
|
||||
|
||||
uint8 focus = IsFocusEffect(0, 0, true,effect);
|
||||
if (focus)
|
||||
@@ -2774,7 +2780,7 @@ void Bot::LoadStance() {
|
||||
std::string query = StringFormat("SELECT StanceID FROM botstances WHERE BotID = %u;", GetBotID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success() || results.RowCount() == 0) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Bot::LoadStance()");
|
||||
Log.Out(Logs::General, Logs::Error, "Error in Bot::LoadStance()");
|
||||
SetDefaultBotStance();
|
||||
return;
|
||||
}
|
||||
@@ -2792,7 +2798,7 @@ void Bot::SaveStance() {
|
||||
"VALUES(%u, %u);", GetBotID(), GetBotStance());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error in Bot::SaveStance()");
|
||||
Log.Out(Logs::General, Logs::Error, "Error in Bot::SaveStance()");
|
||||
|
||||
}
|
||||
|
||||
@@ -2807,7 +2813,7 @@ void Bot::LoadTimers() {
|
||||
GetBotID(), DisciplineReuseStart-1, DisciplineReuseStart-1, GetClass(), GetLevel());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Bot::LoadTimers()");
|
||||
Log.Out(Logs::General, Logs::Error, "Error in Bot::LoadTimers()");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2847,7 +2853,7 @@ void Bot::SaveTimers() {
|
||||
}
|
||||
|
||||
if(hadError)
|
||||
LogFile->write(EQEMuLog::Error, "Error in Bot::SaveTimers()");
|
||||
Log.Out(Logs::General, Logs::Error, "Error in Bot::SaveTimers()");
|
||||
|
||||
}
|
||||
|
||||
@@ -2979,7 +2985,7 @@ void Bot::BotRangedAttack(Mob* other) {
|
||||
//make sure the attack and ranged timers are up
|
||||
//if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow
|
||||
if((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check())) {
|
||||
mlog(COMBAT__RANGED, "Bot Archery attack canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Bot Archery attack canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||
Message(0, "Error: Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||
return;
|
||||
}
|
||||
@@ -2997,7 +3003,7 @@ void Bot::BotRangedAttack(Mob* other) {
|
||||
if(!RangeWeapon || !Ammo)
|
||||
return;
|
||||
|
||||
mlog(COMBAT__RANGED, "Shooting %s with bow %s (%d) and arrow %s (%d)", other->GetCleanName(), RangeWeapon->Name, RangeWeapon->ID, Ammo->Name, Ammo->ID);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Shooting %s with bow %s (%d) and arrow %s (%d)", other->GetCleanName(), RangeWeapon->Name, RangeWeapon->ID, Ammo->Name, Ammo->ID);
|
||||
|
||||
if(!IsAttackAllowed(other) ||
|
||||
IsCasting() ||
|
||||
@@ -3015,19 +3021,19 @@ void Bot::BotRangedAttack(Mob* other) {
|
||||
|
||||
//break invis when you attack
|
||||
if(invisible) {
|
||||
mlog(COMBAT__ATTACKS, "Removing invisibility due to melee attack.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Removing invisibility due to melee attack.");
|
||||
BuffFadeByEffect(SE_Invisibility);
|
||||
BuffFadeByEffect(SE_Invisibility2);
|
||||
invisible = false;
|
||||
}
|
||||
if(invisible_undead) {
|
||||
mlog(COMBAT__ATTACKS, "Removing invisibility vs. undead due to melee attack.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Removing invisibility vs. undead due to melee attack.");
|
||||
BuffFadeByEffect(SE_InvisVsUndead);
|
||||
BuffFadeByEffect(SE_InvisVsUndead2);
|
||||
invisible_undead = false;
|
||||
}
|
||||
if(invisible_animals){
|
||||
mlog(COMBAT__ATTACKS, "Removing invisibility vs. animals due to melee attack.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Removing invisibility vs. animals due to melee attack.");
|
||||
BuffFadeByEffect(SE_InvisVsAnimals);
|
||||
invisible_animals = false;
|
||||
}
|
||||
@@ -3184,7 +3190,7 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
||||
return;
|
||||
|
||||
if (damage > 0)
|
||||
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
|
||||
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
||||
|
||||
if((skillinuse == SkillDragonPunch) && GetAA(aaDragonPunch) && zone->random.Int(0, 99) < 25){
|
||||
SpellFinished(904, other, 10, 0, -1, spells[904].ResistDiff);
|
||||
@@ -3354,7 +3360,7 @@ void Bot::AI_Process() {
|
||||
if(GetHasBeenSummoned()) {
|
||||
if(IsBotCaster() || IsBotArcher()) {
|
||||
if (AImovement_timer->Check()) {
|
||||
if(!GetTarget() || (IsBotCaster() && !IsBotCasterCombatRange(GetTarget())) || (IsBotArcher() && IsArcheryRange(GetTarget())) || (DistNoRootNoZ(GetPreSummonX(), GetPreSummonY()) < 10)) {
|
||||
if(!GetTarget() || (IsBotCaster() && !IsBotCasterCombatRange(GetTarget())) || (IsBotArcher() && IsArcheryRange(GetTarget())) || (DistanceSquaredNoZ(static_cast<glm::vec3>(m_Position), m_PreSummonLocation) < 10)) {
|
||||
if(GetTarget())
|
||||
FaceTarget(GetTarget());
|
||||
SetHasBeenSummoned(false);
|
||||
@@ -3362,9 +3368,9 @@ void Bot::AI_Process() {
|
||||
else if(!IsRooted()) {
|
||||
if(GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this)
|
||||
{
|
||||
mlog(AI__WAYPOINTS, "Returning to location prior to being summoned.");
|
||||
CalculateNewPosition2(GetPreSummonX(), GetPreSummonY(), GetPreSummonZ(), GetRunspeed());
|
||||
SetHeading(CalculateHeadingToTarget(GetPreSummonX(), GetPreSummonY()));
|
||||
Log.Out(Logs::Detail, Logs::AI, "Returning to location prior to being summoned.");
|
||||
CalculateNewPosition2(m_PreSummonLocation.x, m_PreSummonLocation.y, m_PreSummonLocation.z, GetRunspeed());
|
||||
SetHeading(CalculateHeadingToTarget(m_PreSummonLocation.x, m_PreSummonLocation.y));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -3505,7 +3511,7 @@ void Bot::AI_Process() {
|
||||
if(IsBotCasterCombatRange(GetTarget()))
|
||||
atCombatRange = true;
|
||||
}
|
||||
else if(DistNoRoot(*GetTarget()) <= meleeDistance) {
|
||||
else if(DistanceSquared(m_Position, GetTarget()->GetPosition()) <= meleeDistance) {
|
||||
atCombatRange = true;
|
||||
}
|
||||
|
||||
@@ -3533,7 +3539,7 @@ void Bot::AI_Process() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(!IsMoving() && GetClass() != ROGUE && (DistNoRootNoZ(*GetTarget()) < GetTarget()->GetSize())) {
|
||||
else if(!IsMoving() && GetClass() != ROGUE && (DistanceSquaredNoZ(m_Position, GetTarget()->GetPosition()) < GetTarget()->GetSize())) {
|
||||
// If we are not a rogue trying to backstab, let's try to adjust our melee range so we don't appear to be bunched up
|
||||
float newX = 0;
|
||||
float newY = 0;
|
||||
@@ -3689,7 +3695,7 @@ void Bot::AI_Process() {
|
||||
|
||||
if (AImovement_timer->Check()) {
|
||||
if(!IsRooted()) {
|
||||
mlog(AI__WAYPOINTS, "Pursuing %s while engaged.", GetTarget()->GetCleanName());
|
||||
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", GetTarget()->GetCleanName());
|
||||
CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetRunspeed());
|
||||
return;
|
||||
}
|
||||
@@ -3732,7 +3738,7 @@ void Bot::AI_Process() {
|
||||
Mob* follow = entity_list.GetMob(GetFollowID());
|
||||
|
||||
if(follow) {
|
||||
float dist = DistNoRoot(*follow);
|
||||
float dist = DistanceSquared(m_Position, follow->GetPosition());
|
||||
float speed = follow->GetRunspeed();
|
||||
|
||||
if(dist < GetFollowDistance() + 1000)
|
||||
@@ -3865,7 +3871,7 @@ void Bot::PetAIProcess() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(botPet->DistNoRootNoZ(*botPet->GetTarget()) < botPet->GetTarget()->GetSize()) {
|
||||
else if(DistanceSquaredNoZ(botPet->GetPosition(), botPet->GetTarget()->GetPosition()) < botPet->GetTarget()->GetSize()) {
|
||||
// Let's try to adjust our melee range so we don't appear to be bunched up
|
||||
bool isBehindMob = false;
|
||||
bool moveBehindMob = false;
|
||||
@@ -3972,7 +3978,7 @@ void Bot::PetAIProcess() {
|
||||
{
|
||||
botPet->SetRunAnimSpeed(0);
|
||||
if(!botPet->IsRooted()) {
|
||||
mlog(AI__WAYPOINTS, "Pursuing %s while engaged.", botPet->GetTarget()->GetCleanName());
|
||||
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", botPet->GetTarget()->GetCleanName());
|
||||
botPet->CalculateNewPosition2(botPet->GetTarget()->GetX(), botPet->GetTarget()->GetY(), botPet->GetTarget()->GetZ(), botPet->GetOwner()->GetRunspeed());
|
||||
return;
|
||||
}
|
||||
@@ -4003,7 +4009,7 @@ void Bot::PetAIProcess() {
|
||||
switch(pStandingPetOrder) {
|
||||
case SPO_Follow:
|
||||
{
|
||||
float dist = botPet->DistNoRoot(*botPet->GetTarget());
|
||||
float dist = DistanceSquared(botPet->GetPosition(), botPet->GetTarget()->GetPosition());
|
||||
botPet->SetRunAnimSpeed(0);
|
||||
if(dist > 184) {
|
||||
botPet->CalculateNewPosition2(botPet->GetTarget()->GetX(), botPet->GetTarget()->GetY(), botPet->GetTarget()->GetZ(), botPet->GetTarget()->GetRunspeed());
|
||||
@@ -4105,9 +4111,9 @@ void Bot::Spawn(Client* botCharacterOwner, std::string* errorMessage) {
|
||||
this->GetBotOwner()->CastToClient()->Message(13, "%s save failed!", this->GetCleanName());
|
||||
|
||||
// Spawn the bot at the bow owner's loc
|
||||
this->x_pos = botCharacterOwner->GetX();
|
||||
this->y_pos = botCharacterOwner->GetY();
|
||||
this->z_pos = botCharacterOwner->GetZ();
|
||||
this->m_Position.x = botCharacterOwner->GetX();
|
||||
this->m_Position.y = botCharacterOwner->GetY();
|
||||
this->m_Position.z = botCharacterOwner->GetZ();
|
||||
|
||||
// Make the bot look at the bot owner
|
||||
FaceTarget(botCharacterOwner);
|
||||
@@ -4115,6 +4121,9 @@ void Bot::Spawn(Client* botCharacterOwner, std::string* errorMessage) {
|
||||
// Level the bot to the same level as the bot owner
|
||||
//this->SetLevel(botCharacterOwner->GetLevel());
|
||||
|
||||
UpdateEquipLightValue();
|
||||
UpdateActiveLightValue();
|
||||
|
||||
entity_list.AddBot(this, true, true);
|
||||
|
||||
// Load pet
|
||||
@@ -4178,6 +4187,7 @@ void Bot::RemoveBotItemBySlot(uint32 slotID, std::string *errorMessage) {
|
||||
*errorMessage = std::string(results.ErrorMessage());
|
||||
|
||||
m_inv.DeleteItem(slotID);
|
||||
UpdateEquipLightValue();
|
||||
}
|
||||
|
||||
// Retrieves all the inventory records from the database for this bot.
|
||||
@@ -4211,7 +4221,7 @@ void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) {
|
||||
|
||||
ItemInst* inst = database.CreateItem(item_id, charges, aug[0], aug[1], aug[2], aug[3], aug[4]);
|
||||
if (!inst) {
|
||||
LogFile->write(EQEMuLog::Error, "Warning: botid %i has an invalid item_id %i in inventory slot %i", this->GetBotID(), item_id, slot_id);
|
||||
Log.Out(Logs::General, Logs::Error, "Warning: botid %i has an invalid item_id %i in inventory slot %i", this->GetBotID(), item_id, slot_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -4235,10 +4245,11 @@ void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) {
|
||||
|
||||
// Save ptr to item in inventory
|
||||
if (put_slot_id == INVALID_INDEX)
|
||||
LogFile->write(EQEMuLog::Error, "Warning: Invalid slot_id for item in inventory: botid=%i, item_id=%i, slot_id=%i",this->GetBotID(), item_id, slot_id);
|
||||
Log.Out(Logs::General, Logs::Error, "Warning: Invalid slot_id for item in inventory: botid=%i, item_id=%i, slot_id=%i",this->GetBotID(), item_id, slot_id);
|
||||
|
||||
}
|
||||
|
||||
UpdateEquipLightValue();
|
||||
}
|
||||
|
||||
// Returns the inventory record for this bot from the database for the specified equipment slot.
|
||||
@@ -4364,6 +4375,9 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
||||
ns->spawn.size = 0;
|
||||
ns->spawn.NPC = 0; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||
|
||||
UpdateActiveLightValue();
|
||||
ns->spawn.light = active_light;
|
||||
|
||||
ns->spawn.helm = helmtexture; //0xFF;
|
||||
ns->spawn.equip_chest2 = texture; //0xFF;
|
||||
|
||||
@@ -5073,6 +5087,10 @@ void Bot::BotAddEquipItem(int slot, uint32 id) {
|
||||
equipment[slot] = id; // npc has more than just material slots. Valid material should mean valid inventory index
|
||||
SendWearChange(materialFromSlot);
|
||||
}
|
||||
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5087,6 +5105,10 @@ void Bot::BotRemoveEquipItem(int slot) {
|
||||
if(materialFromSlot == MaterialChest)
|
||||
SendWearChange(MaterialArms);
|
||||
}
|
||||
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5959,7 +5981,7 @@ void Bot::Damage(Mob *from, int32 damage, uint16 spell_id, SkillUseTypes attack_
|
||||
|
||||
//handle EVENT_ATTACK. Resets after we have not been attacked for 12 seconds
|
||||
if(attacked_timer.Check()) {
|
||||
mlog(COMBAT__HITS, "Triggering EVENT_ATTACK due to attack by %s", from->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Triggering EVENT_ATTACK due to attack by %s", from->GetName());
|
||||
parse->EventNPC(EVENT_ATTACK, this, from, "", 0);
|
||||
}
|
||||
|
||||
@@ -5972,7 +5994,7 @@ void Bot::Damage(Mob *from, int32 damage, uint16 spell_id, SkillUseTypes attack_
|
||||
// if spell is lifetap add hp to the caster
|
||||
if (spell_id != SPELL_UNKNOWN && IsLifetapSpell(spell_id)) {
|
||||
int healed = GetActSpellHealing(spell_id, damage);
|
||||
mlog(COMBAT__DAMAGE, "Applying lifetap heal of %d to %s", healed, GetCleanName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Applying lifetap heal of %d to %s", healed, GetCleanName());
|
||||
HealDamage(healed);
|
||||
entity_list.MessageClose(this, true, 300, MT_Spells, "%s beams a smile at %s", GetCleanName(), from->GetCleanName() );
|
||||
}
|
||||
@@ -6017,14 +6039,14 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
{
|
||||
if (!other) {
|
||||
SetTarget(nullptr);
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Bot::Attack for evaluation!");
|
||||
Log.Out(Logs::General, Logs::Error, "A null Mob object was passed to Bot::Attack for evaluation!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!GetTarget() || GetTarget() != other)
|
||||
SetTarget(other);
|
||||
|
||||
mlog(COMBAT__ATTACKS, "Attacking %s with hand %d %s", other?other->GetCleanName():"(nullptr)", Hand, FromRiposte?"(this is a riposte)":"");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attacking %s with hand %d %s", other?other->GetCleanName():"(nullptr)", Hand, FromRiposte?"(this is a riposte)":"");
|
||||
|
||||
if ((IsCasting() && (GetClass() != BARD) && !IsFromSpell) ||
|
||||
other == nullptr ||
|
||||
@@ -6036,13 +6058,13 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
entity_list.MessageClose(this, 1, 200, 10, "%s says, '%s is not a legal target master.'", this->GetCleanName(), this->GetTarget()->GetCleanName());
|
||||
if(other) {
|
||||
RemoveFromHateList(other);
|
||||
mlog(COMBAT__ATTACKS, "I am not allowed to attack %s", other->GetCleanName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "I am not allowed to attack %s", other->GetCleanName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(DivineAura()) {//cant attack while invulnerable
|
||||
mlog(COMBAT__ATTACKS, "Attack canceled, Divine Aura is in effect.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attack canceled, Divine Aura is in effect.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6068,19 +6090,19 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
|
||||
if(weapon != nullptr) {
|
||||
if (!weapon->IsWeapon()) {
|
||||
mlog(COMBAT__ATTACKS, "Attack canceled, Item %s (%d) is not a weapon.", weapon->GetItem()->Name, weapon->GetID());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attack canceled, Item %s (%d) is not a weapon.", weapon->GetItem()->Name, weapon->GetID());
|
||||
return(false);
|
||||
}
|
||||
mlog(COMBAT__ATTACKS, "Attacking with weapon: %s (%d)", weapon->GetItem()->Name, weapon->GetID());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attacking with weapon: %s (%d)", weapon->GetItem()->Name, weapon->GetID());
|
||||
} else {
|
||||
mlog(COMBAT__ATTACKS, "Attacking without a weapon.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attacking without a weapon.");
|
||||
}
|
||||
|
||||
// calculate attack_skill and skillinuse depending on hand and weapon
|
||||
// also send Packet to near clients
|
||||
SkillUseTypes skillinuse;
|
||||
AttackAnimation(skillinuse, Hand, weapon);
|
||||
mlog(COMBAT__ATTACKS, "Attacking with %s in slot %d using skill %d", weapon?weapon->GetItem()->Name:"Fist", Hand, skillinuse);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attacking with %s in slot %d using skill %d", weapon?weapon->GetItem()->Name:"Fist", Hand, skillinuse);
|
||||
|
||||
/// Now figure out damage
|
||||
int damage = 0;
|
||||
@@ -6098,7 +6120,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
if(berserk && (GetClass() == BERSERKER)){
|
||||
int bonus = 3 + GetLevel()/10; //unverified
|
||||
weapon_damage = weapon_damage * (100+bonus) / 100;
|
||||
mlog(COMBAT__DAMAGE, "Berserker damage bonus increases DMG to %d", weapon_damage);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Berserker damage bonus increases DMG to %d", weapon_damage);
|
||||
}
|
||||
|
||||
//try a finishing blow.. if successful end the attack
|
||||
@@ -6163,7 +6185,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
else
|
||||
damage = zone->random.Int(min_hit, max_hit);
|
||||
|
||||
mlog(COMBAT__DAMAGE, "Damage calculated to %d (min %d, max %d, str %d, skill %d, DMG %d, lv %d)",
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Damage calculated to %d (min %d, max %d, str %d, skill %d, DMG %d, lv %d)",
|
||||
damage, min_hit, max_hit, GetSTR(), GetSkill(skillinuse), weapon_damage, GetLevel());
|
||||
|
||||
if(opts) {
|
||||
@@ -6175,7 +6197,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
|
||||
//check to see if we hit..
|
||||
if(!other->CheckHitChance(other, skillinuse, Hand)) {
|
||||
mlog(COMBAT__ATTACKS, "Attack missed. Damage set to 0.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Attack missed. Damage set to 0.");
|
||||
damage = 0;
|
||||
other->AddToHateList(this, 0);
|
||||
} else { //we hit, try to avoid it
|
||||
@@ -6185,13 +6207,13 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
ApplyMeleeDamageBonus(skillinuse, damage);
|
||||
damage += (itembonuses.HeroicSTR / 10) + (damage * other->GetSkillDmgTaken(skillinuse) / 100) + GetSkillDmgAmt(skillinuse);
|
||||
TryCriticalHit(other, skillinuse, damage, opts);
|
||||
mlog(COMBAT__HITS, "Generating hate %d towards %s", hate, GetCleanName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Generating hate %d towards %s", hate, GetCleanName());
|
||||
// now add done damage to the hate list
|
||||
//other->AddToHateList(this, hate);
|
||||
}
|
||||
else
|
||||
other->AddToHateList(this, 0);
|
||||
mlog(COMBAT__DAMAGE, "Final damage after all reductions: %d", damage);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Final damage after all reductions: %d", damage);
|
||||
}
|
||||
|
||||
//riposte
|
||||
@@ -6249,23 +6271,23 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
MeleeLifeTap(damage);
|
||||
|
||||
if (damage > 0)
|
||||
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
|
||||
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
||||
|
||||
//break invis when you attack
|
||||
if(invisible) {
|
||||
mlog(COMBAT__ATTACKS, "Removing invisibility due to melee attack.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Removing invisibility due to melee attack.");
|
||||
BuffFadeByEffect(SE_Invisibility);
|
||||
BuffFadeByEffect(SE_Invisibility2);
|
||||
invisible = false;
|
||||
}
|
||||
if(invisible_undead) {
|
||||
mlog(COMBAT__ATTACKS, "Removing invisibility vs. undead due to melee attack.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Removing invisibility vs. undead due to melee attack.");
|
||||
BuffFadeByEffect(SE_InvisVsUndead);
|
||||
BuffFadeByEffect(SE_InvisVsUndead2);
|
||||
invisible_undead = false;
|
||||
}
|
||||
if(invisible_animals){
|
||||
mlog(COMBAT__ATTACKS, "Removing invisibility vs. animals due to melee attack.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Removing invisibility vs. animals due to melee attack.");
|
||||
BuffFadeByEffect(SE_InvisVsAnimals);
|
||||
invisible_animals = false;
|
||||
}
|
||||
@@ -7028,7 +7050,7 @@ int32 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
LogFile->write(EQEMuLog::Normal, "CalcFocusEffect: unknown limit spelltype %d", focus_spell.base[i]);
|
||||
Log.Out(Logs::General, Logs::Normal, "CalcFocusEffect: unknown limit spelltype %d", focus_spell.base[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -7332,12 +7354,10 @@ int32 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
|
||||
|
||||
break;
|
||||
}
|
||||
#if EQDEBUG >= 6
|
||||
//this spits up a lot of garbage when calculating spell focuses
|
||||
//since they have all kinds of extra effects on them.
|
||||
default:
|
||||
LogFile->write(EQEMuLog::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
|
||||
#endif
|
||||
Log.Out(Logs::General, Logs::Spells, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
|
||||
}
|
||||
}
|
||||
//Check for spell skill limits.
|
||||
@@ -7380,13 +7400,13 @@ float Bot::GetProcChances(float ProcBonus, uint16 hand) {
|
||||
ProcChance += ProcChance*ProcBonus / 100.0f;
|
||||
}
|
||||
|
||||
mlog(COMBAT__PROCS, "Proc chance %.2f (%.2f from bonuses)", ProcChance, ProcBonus);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Proc chance %.2f (%.2f from bonuses)", ProcChance, ProcBonus);
|
||||
return ProcChance;
|
||||
}
|
||||
|
||||
bool Bot::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
||||
{
|
||||
/* solar: called when a mob is attacked, does the checks to see if it's a hit
|
||||
/* called when a mob is attacked, does the checks to see if it's a hit
|
||||
* and does other mitigation checks. 'this' is the mob being attacked.
|
||||
*
|
||||
* special return values:
|
||||
@@ -7416,7 +7436,7 @@ bool Bot::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
||||
/////////////////////////////////////////////////////////
|
||||
if (IsEnraged() && !other->BehindMob(this, other->GetX(), other->GetY())) {
|
||||
damage = -3;
|
||||
mlog(COMBAT__DAMAGE, "I am enraged, riposting frontal attack.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "I am enraged, riposting frontal attack.");
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
@@ -7558,7 +7578,7 @@ bool Bot::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
||||
}
|
||||
}
|
||||
|
||||
mlog(COMBAT__DAMAGE, "Final damage after all avoidances: %d", damage);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Final damage after all avoidances: %d", damage);
|
||||
|
||||
if (damage < 0)
|
||||
return true;
|
||||
@@ -7611,14 +7631,14 @@ bool Bot::TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse)
|
||||
uint16 levelreq = aabonuses.FinishingBlowLvl[0];
|
||||
|
||||
if(defender->GetLevel() <= levelreq && (chance >= zone->random.Int(0, 1000))){
|
||||
mlog(COMBAT__ATTACKS, "Landed a finishing blow: levelreq at %d, other level %d", levelreq , defender->GetLevel());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Landed a finishing blow: levelreq at %d, other level %d", levelreq , defender->GetLevel());
|
||||
entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, FINISHING_BLOW, GetName());
|
||||
defender->Damage(this, damage, SPELL_UNKNOWN, skillinuse);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mlog(COMBAT__ATTACKS, "FAILED a finishing blow: levelreq at %d, other level %d", levelreq , defender->GetLevel());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "FAILED a finishing blow: levelreq at %d, other level %d", levelreq , defender->GetLevel());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -7626,7 +7646,7 @@ bool Bot::TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse)
|
||||
}
|
||||
|
||||
void Bot::DoRiposte(Mob* defender) {
|
||||
mlog(COMBAT__ATTACKS, "Preforming a riposte");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a riposte");
|
||||
|
||||
if (!defender)
|
||||
return;
|
||||
@@ -7639,7 +7659,7 @@ void Bot::DoRiposte(Mob* defender) {
|
||||
defender->GetItemBonuses().GiveDoubleRiposte[0];
|
||||
|
||||
if(DoubleRipChance && (DoubleRipChance >= zone->random.Int(0, 100))) {
|
||||
mlog(COMBAT__ATTACKS, "Preforming a double riposte (%d percent chance)", DoubleRipChance);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a double riposte (%d percent chance)", DoubleRipChance);
|
||||
|
||||
defender->Attack(this, MainPrimary, true);
|
||||
}
|
||||
@@ -7707,7 +7727,7 @@ void Bot::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
|
||||
if (HasDied()) return;
|
||||
|
||||
if (max_damage > 0)
|
||||
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
|
||||
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
||||
|
||||
//[AA Dragon Punch] value[0] = 100 for 25%, chance value[1] = skill
|
||||
if(aabonuses.SpecialAttackKBProc[0] && aabonuses.SpecialAttackKBProc[1] == skill){
|
||||
@@ -7761,7 +7781,7 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) {
|
||||
|
||||
if (bIsBehind || bCanFrontalBS){ // Bot is behind other OR can do Frontal Backstab
|
||||
|
||||
// solar - chance to assassinate
|
||||
// chance to assassinate
|
||||
int chance = 10 + (GetDEX()/10) + (itembonuses.HeroicDEX/10); //18.5% chance at 85 dex 40% chance at 300 dex
|
||||
if(
|
||||
level >= 60 && // bot is 60 or higher
|
||||
@@ -8209,7 +8229,7 @@ bool Bot::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) {
|
||||
float AttackerChance = 0.20f + ((float)(rangerLevel - 51) * 0.005f);
|
||||
float DefenderChance = (float)zone->random.Real(0.00f, 1.00f);
|
||||
if(AttackerChance > DefenderChance) {
|
||||
mlog(COMBAT__ATTACKS, "Landed a headshot: Attacker chance was %f and Defender chance was %f.", AttackerChance, DefenderChance);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Landed a headshot: Attacker chance was %f and Defender chance was %f.", AttackerChance, DefenderChance);
|
||||
// WildcardX: At the time I wrote this, there wasnt a string id for something like HEADSHOT_BLOW
|
||||
//entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, FINISHING_BLOW, GetName());
|
||||
entity_list.MessageClose(this, false, 200, MT_CritMelee, "%s has scored a leathal HEADSHOT!", GetName());
|
||||
@@ -8217,7 +8237,7 @@ bool Bot::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) {
|
||||
Result = true;
|
||||
}
|
||||
else {
|
||||
mlog(COMBAT__ATTACKS, "FAILED a headshot: Attacker chance was %f and Defender chance was %f.", AttackerChance, DefenderChance);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "FAILED a headshot: Attacker chance was %f and Defender chance was %f.", AttackerChance, DefenderChance);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8386,6 +8406,8 @@ void Bot::EquipBot(std::string* errorMessage) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateEquipLightValue();
|
||||
}
|
||||
|
||||
//// This method is meant to be called by zone or client methods to clean up objects when a client camps, goes LD, zones out or something like that.
|
||||
@@ -8420,7 +8442,7 @@ void Bot::ProcessBotOwnerRefDelete(Mob* botOwner) {
|
||||
std::list<Bot*> BotList = entity_list.GetBotsByBotOwnerCharacterID(botOwner->CastToClient()->CharacterID());
|
||||
|
||||
if(!BotList.empty()) {
|
||||
for(std::list<Bot*>::iterator botListItr = BotList.begin(); botListItr != BotList.end(); botListItr++) {
|
||||
for(std::list<Bot*>::iterator botListItr = BotList.begin(); botListItr != BotList.end(); ++botListItr) {
|
||||
Bot* tempBot = *botListItr;
|
||||
|
||||
if(tempBot) {
|
||||
@@ -8443,11 +8465,11 @@ void Bot::ProcessGuildInvite(Client* guildOfficer, Bot* botToGuild) {
|
||||
return;
|
||||
}
|
||||
|
||||
// mlog(GUILDS__ACTIONS, "Inviting %s (%d) into guild %s (%d)", botToGuild->GetName(), botToGuild->GetBotID(), guild_mgr.GetGuildName(client->GuildID()), client->GuildID());
|
||||
// Log.Out(Logs::Detail, Logs::Guilds, "Inviting %s (%d) into guild %s (%d)", botToGuild->GetName(), botToGuild->GetBotID(), guild_mgr.GetGuildName(client->GuildID()), client->GuildID());
|
||||
|
||||
SetBotGuildMembership(botToGuild->GetBotID(), guildOfficer->GuildID(), GUILD_MEMBER);
|
||||
|
||||
//_log(GUILDS__REFRESH, "Sending char refresh for BOT %s from guild %d to world", botToGuild->GetName(), guildOfficer->GuildID();
|
||||
//Log.LogDebugType(Logs::Detail, Logs::Guilds, "Sending char refresh for BOT %s from guild %d to world", botToGuild->GetName(), guildOfficer->GuildID();
|
||||
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_GuildCharRefresh, sizeof(ServerGuildCharRefresh_Struct));
|
||||
ServerGuildCharRefresh_Struct *s = (ServerGuildCharRefresh_Struct *) pack->pBuffer;
|
||||
@@ -8550,7 +8572,7 @@ int32 Bot::CalcMaxMana() {
|
||||
}
|
||||
default:
|
||||
{
|
||||
LogFile->write(EQEMuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
|
||||
Log.Out(Logs::General, Logs::None, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
|
||||
max_mana = 0;
|
||||
break;
|
||||
}
|
||||
@@ -9076,9 +9098,9 @@ void Bot::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
|
||||
bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot, int16 *resist_adjust) {
|
||||
bool Result = false;
|
||||
|
||||
if(zone && !zone->IsSpellBlocked(spell_id, GetX(), GetY(), GetZ())) {
|
||||
if(zone && !zone->IsSpellBlocked(spell_id, glm::vec3(GetPosition()))) {
|
||||
|
||||
mlog(SPELLS__CASTING, "CastSpell called for spell %s (%d) on entity %d, slot %d, time %d, mana %d, from item slot %d",
|
||||
Log.Out(Logs::Detail, Logs::Spells, "CastSpell called for spell %s (%d) on entity %d, slot %d, time %d, mana %d, from item slot %d",
|
||||
spells[spell_id].name, spell_id, target_id, slot, cast_time, mana_cost, (item_slot==0xFFFFFFFF)?999:item_slot);
|
||||
|
||||
if(casting_spell_id == spell_id)
|
||||
@@ -9086,7 +9108,7 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_t
|
||||
|
||||
if(GetClass() != BARD) {
|
||||
if(!IsValidSpell(spell_id) || casting_spell_id || delaytimer || spellend_timer.Enabled() || IsStunned() || IsFeared() || IsMezzed() || (IsSilenced() && !IsDiscipline(spell_id)) || (IsAmnesiad() && IsDiscipline(spell_id))) {
|
||||
mlog(SPELLS__CASTING_ERR, "Spell casting canceled: not able to cast now. Valid? %d, casting %d, waiting? %d, spellend? %d, stunned? %d, feared? %d, mezed? %d, silenced? %d",
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Spell casting canceled: not able to cast now. Valid? %d, casting %d, waiting? %d, spellend? %d, stunned? %d, feared? %d, mezed? %d, silenced? %d",
|
||||
IsValidSpell(spell_id), casting_spell_id, delaytimer, spellend_timer.Enabled(), IsStunned(), IsFeared(), IsMezzed(), IsSilenced() );
|
||||
if(IsSilenced() && !IsDiscipline(spell_id))
|
||||
Message_StringID(13, SILENCED_STRING);
|
||||
@@ -9107,7 +9129,7 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_t
|
||||
|
||||
//cannot cast under deivne aura
|
||||
if(DivineAura()) {
|
||||
mlog(SPELLS__CASTING_ERR, "Spell casting canceled: cannot cast while Divine Aura is in effect.");
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Spell casting canceled: cannot cast while Divine Aura is in effect.");
|
||||
InterruptSpell(173, 0x121, false);
|
||||
return(false);
|
||||
}
|
||||
@@ -9121,7 +9143,7 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_t
|
||||
InterruptSpell(fizzle_msg, 0x121, spell_id);
|
||||
|
||||
uint32 use_mana = ((spells[spell_id].mana) / 4);
|
||||
mlog(SPELLS__CASTING_ERR, "Spell casting canceled: fizzled. %d mana has been consumed", use_mana);
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Spell casting canceled: fizzled. %d mana has been consumed", use_mana);
|
||||
|
||||
// fizzle 1/4 the mana away
|
||||
SetMana(GetMana() - use_mana);
|
||||
@@ -9129,7 +9151,7 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_t
|
||||
}
|
||||
|
||||
if (HasActiveSong()) {
|
||||
mlog(SPELLS__BARDS, "Casting a new spell/song while singing a song. Killing old song %d.", bardsong);
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Casting a new spell/song while singing a song. Killing old song %d.", bardsong);
|
||||
//Note: this does NOT tell the client
|
||||
//_StopSong();
|
||||
bardsong = 0;
|
||||
@@ -9258,7 +9280,7 @@ bool Bot::IsImmuneToSpell(uint16 spell_id, Mob *caster) {
|
||||
if(caster->IsBot()) {
|
||||
if(spells[spell_id].targettype == ST_Undead) {
|
||||
if((GetBodyType() != BT_SummonedUndead) && (GetBodyType() != BT_Undead) && (GetBodyType() != BT_Vampire)) {
|
||||
mlog(SPELLS__RESISTS, "Bot's target is not an undead.");
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Bot's target is not an undead.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -9268,13 +9290,13 @@ bool Bot::IsImmuneToSpell(uint16 spell_id, Mob *caster) {
|
||||
&& (GetBodyType() != BT_Summoned2)
|
||||
&& (GetBodyType() != BT_Summoned3)
|
||||
) {
|
||||
mlog(SPELLS__RESISTS, "Bot's target is not a summoned creature.");
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Bot's target is not a summoned creature.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mlog(SPELLS__RESISTS, "No bot immunities to spell %d found.", spell_id);
|
||||
Log.Out(Logs::Detail, Logs::Spells, "No bot immunities to spell %d found.", spell_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9332,7 +9354,7 @@ int32 Bot::GenerateBaseManaPoints()
|
||||
{
|
||||
case 'I':
|
||||
WisInt = INT;
|
||||
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= EQClientSoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if(WisInt > 100) {
|
||||
ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100);
|
||||
if(WisInt > 201) {
|
||||
@@ -9375,7 +9397,7 @@ int32 Bot::GenerateBaseManaPoints()
|
||||
|
||||
case 'W':
|
||||
WisInt = WIS;
|
||||
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= EQClientSoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if(WisInt > 100) {
|
||||
ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100);
|
||||
if(WisInt > 201) {
|
||||
@@ -9614,7 +9636,7 @@ int32 Bot::GetMaxStat() {
|
||||
if (level < 61) {
|
||||
base = 255;
|
||||
}
|
||||
else if (GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= EQClientSoF) {
|
||||
else if (GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= ClientVersion::SoF) {
|
||||
base = 255 + 5 * (level - 60);
|
||||
}
|
||||
else if (level < 71) {
|
||||
@@ -10234,7 +10256,7 @@ int32 Bot::CalcBaseEndurance()
|
||||
int32 sta_end = 0;
|
||||
int Stats = 0;
|
||||
|
||||
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= EQClientSoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
int HeroicStats = 0;
|
||||
|
||||
Stats = ((GetSTR() + GetSTA() + GetDEX() + GetAGI()) / 4);
|
||||
@@ -10387,7 +10409,7 @@ bool Bot::IsArcheryRange(Mob *target) {
|
||||
|
||||
range *= range;
|
||||
|
||||
float targetDistance = DistNoRootNoZ(*target);
|
||||
float targetDistance = DistanceSquaredNoZ(m_Position, target->GetPosition());
|
||||
|
||||
float minRuleDistance = RuleI(Combat, MinRangedAttackDist) * RuleI(Combat, MinRangedAttackDist);
|
||||
|
||||
@@ -10411,7 +10433,7 @@ bool Bot::IsBotCasterCombatRange(Mob *target) {
|
||||
// half the max so the bot doesn't always stop at max range to allow combat movement
|
||||
range *= .5;
|
||||
|
||||
float targetDistance = DistNoRootNoZ(*target);
|
||||
float targetDistance = DistanceSquaredNoZ(m_Position, target->GetPosition());
|
||||
|
||||
if(targetDistance > range)
|
||||
result = false;
|
||||
@@ -10663,12 +10685,12 @@ void Bot::BotGroupSummon(Group* group, Client* client) {
|
||||
if(botMember->GetBotOwnerCharacterID() == client->CharacterID()) {
|
||||
botMember->SetTarget(botMember->GetBotOwner());
|
||||
botMember->WipeHateList();
|
||||
botMember->Warp(botMember->GetBotOwner()->GetX(), botMember->GetBotOwner()->GetY(), botMember->GetBotOwner()->GetZ());
|
||||
botMember->Warp(glm::vec3(botMember->GetBotOwner()->GetPosition()));
|
||||
|
||||
if(botMember->HasPet() && botMember->GetPet()) {
|
||||
botMember->GetPet()->SetTarget(botMember);
|
||||
botMember->GetPet()->WipeHateList();
|
||||
botMember->GetPet()->Warp(botMember->GetBotOwner()->GetX(), botMember->GetBotOwner()->GetY(), botMember->GetBotOwner()->GetZ());
|
||||
botMember->GetPet()->Warp(glm::vec3(botMember->GetBotOwner()->GetPosition()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11677,7 +11699,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
||||
else
|
||||
{
|
||||
b->SetTarget(c->CastToMob());
|
||||
b->Warp(c->GetX(), c->GetY(), c->GetZ());
|
||||
b->Warp(glm::vec3(c->GetPosition()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11707,7 +11729,6 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
||||
std::string item_link;
|
||||
Client::TextLink linker;
|
||||
linker.SetLinkType(linker.linkItemInst);
|
||||
linker.SetClientVersion(c->GetClientVersion());
|
||||
|
||||
for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) {
|
||||
if((i == MainSecondary) && is2Hweapon) {
|
||||
@@ -15457,7 +15478,7 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
||||
// according to Rogean, Live NPCs will just cast through walls/floors, no problem..
|
||||
//
|
||||
// This check was put in to address an idle-mob CPU issue
|
||||
_log(AI__ERROR, "Error: detrimental spells requested from AICheckCloseBeneficialSpells!!");
|
||||
Log.Out(Logs::General, Logs::Error, "Error: detrimental spells requested from AICheckCloseBeneficialSpells!!");
|
||||
return(false);
|
||||
}
|
||||
|
||||
@@ -15742,47 +15763,38 @@ std::list<Bot*> EntityList::GetBotsByBotOwnerCharacterID(uint32 botOwnerCharacte
|
||||
|
||||
void EntityList::BotPickLock(Bot* rogue)
|
||||
{
|
||||
auto it = door_list.begin();
|
||||
for (auto it = door_list.begin(); it != door_list.end(); ++it) {
|
||||
Doors *cdoor = it->second;
|
||||
if(cdoor && !cdoor->IsDoorOpen()) {
|
||||
float zdiff = rogue->GetZ() - cdoor->GetZ();
|
||||
if(zdiff < 0)
|
||||
zdiff = 0 - zdiff;
|
||||
float curdist = 0;
|
||||
float tmp = rogue->GetX() - cdoor->GetX();
|
||||
curdist += (tmp * tmp);
|
||||
tmp = rogue->GetY() - cdoor->GetY();
|
||||
curdist += (tmp * tmp);
|
||||
if((zdiff < 10) && (curdist <= 130)) {
|
||||
// All rogue items with lock pick bonuses are hands or primary
|
||||
const ItemInst* item1 = rogue->GetBotItem(MainHands);
|
||||
const ItemInst* item2 = rogue->GetBotItem(MainPrimary);
|
||||
if(!cdoor || cdoor->IsDoorOpen())
|
||||
continue;
|
||||
|
||||
float bonus1 = 0.0f;
|
||||
float bonus2 = 0.0f;
|
||||
float skill = rogue->GetSkill(SkillPickLock);
|
||||
auto diff = rogue->GetPosition() - cdoor->GetPosition();
|
||||
|
||||
if(item1) { // Hand slot item
|
||||
if(item1->GetItem()->SkillModType == SkillPickLock) {
|
||||
bonus1 = skill * (((float)item1->GetItem()->SkillModValue) / 100.0f);
|
||||
}
|
||||
}
|
||||
float curdist = diff.x * diff.x + diff.y * diff.y;
|
||||
|
||||
if(item2) { // Primary slot item
|
||||
if(item2->GetItem()->SkillModType == SkillPickLock) {
|
||||
bonus2 = skill * (((float)item2->GetItem()->SkillModValue) / 100.0f);
|
||||
}
|
||||
}
|
||||
if((diff.z * diff.z >= 10) || (curdist > 130))
|
||||
continue;
|
||||
|
||||
if((skill+bonus1+bonus2) >= cdoor->GetLockpick()) {
|
||||
cdoor->ForceOpen(rogue);
|
||||
}
|
||||
else {
|
||||
rogue->Say("I am not skilled enough for this lock.");
|
||||
}
|
||||
}
|
||||
}
|
||||
// All rogue items with lock pick bonuses are hands or primary
|
||||
const ItemInst* item1 = rogue->GetBotItem(MainHands);
|
||||
const ItemInst* item2 = rogue->GetBotItem(MainPrimary);
|
||||
|
||||
float bonus1 = 0.0f;
|
||||
float bonus2 = 0.0f;
|
||||
float skill = rogue->GetSkill(SkillPickLock);
|
||||
|
||||
if(item1) // Hand slot item
|
||||
if(item1->GetItem()->SkillModType == SkillPickLock)
|
||||
bonus1 = skill * (((float)item1->GetItem()->SkillModValue) / 100.0f);
|
||||
|
||||
if(item2) // Primary slot item
|
||||
if(item2->GetItem()->SkillModType == SkillPickLock)
|
||||
bonus2 = skill * (((float)item2->GetItem()->SkillModValue) / 100.0f);
|
||||
|
||||
if((skill+bonus1+bonus2) >= cdoor->GetLockpick())
|
||||
cdoor->ForceOpen(rogue);
|
||||
else
|
||||
rogue->Say("I am not skilled enough for this lock.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15820,7 +15832,7 @@ void EntityList::ShowSpawnWindow(Client* client, int Distance, bool NamedOnly) {
|
||||
|
||||
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
|
||||
curMob = it->second;
|
||||
if (curMob && curMob->DistNoZ(*client)<=Distance) {
|
||||
if (curMob && DistanceNoZ(curMob->GetPosition(), client->GetPosition()) <= Distance) {
|
||||
if(curMob->IsTrackable()) {
|
||||
Mob* cur_entity = curMob;
|
||||
int Extras = (cur_entity->IsBot() || cur_entity->IsPet() || cur_entity->IsFamiliar() || cur_entity->IsClient());
|
||||
@@ -16169,11 +16181,9 @@ bool Bot::HasOrMayGetAggro() {
|
||||
|
||||
void Bot::SetHasBeenSummoned(bool wasSummoned) {
|
||||
_hasBeenSummoned = wasSummoned;
|
||||
if(!wasSummoned) {
|
||||
_preSummonX = 0;
|
||||
_preSummonY = 0;
|
||||
_preSummonZ = 0;
|
||||
}
|
||||
if(!wasSummoned)
|
||||
m_PreSummonLocation = glm::vec3();
|
||||
|
||||
}
|
||||
|
||||
void Bot::SetDefaultBotStance() {
|
||||
|
||||
+5
-10
@@ -12,7 +12,7 @@
|
||||
#include "zonedb.h"
|
||||
#include "string_ids.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "guild_mgr.h"
|
||||
#include "worldserver.h"
|
||||
|
||||
@@ -332,6 +332,7 @@ public:
|
||||
void EquipBot(std::string* errorMessage);
|
||||
bool CheckLoreConflict(const Item_Struct* item);
|
||||
uint32 GetEquipmentColor(uint8 material_slot) const;
|
||||
virtual void UpdateEquipLightValue() { equip_light = m_inv.FindHighestLightValue(); }
|
||||
|
||||
// Static Class Methods
|
||||
static void SaveBotGroup(Group* botGroup, std::string botGroupName, std::string* errorMessage);
|
||||
@@ -448,9 +449,7 @@ public:
|
||||
uint32 GetAA(uint32 aa_id);
|
||||
void ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon);
|
||||
bool GetHasBeenSummoned() { return _hasBeenSummoned; }
|
||||
float GetPreSummonX() { return _preSummonX; }
|
||||
float GetPreSummonY() { return _preSummonY; }
|
||||
float GetPreSummonZ() { return _preSummonZ; }
|
||||
const glm::vec3 GetPreSummonLocation() const { return m_PreSummonLocation; }
|
||||
bool GetGroupMessagesOn() { return _groupMessagesOn; }
|
||||
bool GetInHealRotation() { return _isInHealRotation; }
|
||||
bool GetHealRotationActive() { return (GetInHealRotation() && _isHealRotationActive); }
|
||||
@@ -535,9 +534,7 @@ public:
|
||||
void SetSpellRecastTimer(int timer_index, int32 recast_delay);
|
||||
void SetDisciplineRecastTimer(int timer_index, int32 recast_delay);
|
||||
void SetHasBeenSummoned(bool s);
|
||||
void SetPreSummonX(float x) { _preSummonX = x; }
|
||||
void SetPreSummonY(float y) { _preSummonY = y; }
|
||||
void SetPreSummonZ(float z) { _preSummonZ = z; }
|
||||
void SetPreSummonLocation(const glm::vec3& location) { m_PreSummonLocation = location; }
|
||||
void SetGroupMessagesOn(bool groupMessagesOn) { _groupMessagesOn = groupMessagesOn; }
|
||||
void SetInHealRotation( bool inRotation ) { _isInHealRotation = inRotation; }
|
||||
void SetHealRotationActive( bool isActive ) { _isHealRotationActive = isActive; }
|
||||
@@ -604,9 +601,7 @@ private:
|
||||
int32 end_regen;
|
||||
uint32 timers[MaxTimer];
|
||||
bool _hasBeenSummoned;
|
||||
float _preSummonX;
|
||||
float _preSummonY;
|
||||
float _preSummonZ;
|
||||
glm::vec3 m_PreSummonLocation;
|
||||
uint8 _spellCastingChances[MaxStances][MaxSpellTypes];
|
||||
bool _groupMessagesOn;
|
||||
bool _isInHealRotation;
|
||||
|
||||
@@ -898,7 +898,7 @@ bool Bot::AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain
|
||||
if (AIspells[i].type & SpellType_Escape) {
|
||||
dist2 = 0;
|
||||
} else
|
||||
dist2 = DistNoRoot(*tar);
|
||||
dist2 = DistanceSquared(m_Position, tar->GetPosition());
|
||||
|
||||
if (((((spells[AIspells[i].spellid].targettype==ST_GroupTeleport && AIspells[i].type==2)
|
||||
|| spells[AIspells[i].spellid].targettype==ST_AECaster
|
||||
@@ -950,7 +950,7 @@ bool Bot::AI_PursueCastCheck() {
|
||||
|
||||
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
|
||||
|
||||
mlog(AI__SPELLS, "Bot Engaged (pursuing) autocast check triggered. Trying to cast offensive spells.");
|
||||
Log.Out(Logs::Detail, Logs::AI, "Bot Engaged (pursuing) autocast check triggered. Trying to cast offensive spells.");
|
||||
|
||||
if(!AICastSpell(GetTarget(), 100, SpellType_Snare)) {
|
||||
if(!AICastSpell(GetTarget(), 100, SpellType_Lifetap)) {
|
||||
@@ -1055,7 +1055,7 @@ bool Bot::AI_EngagedCastCheck() {
|
||||
BotStanceType botStance = GetBotStance();
|
||||
bool mayGetAggro = HasOrMayGetAggro();
|
||||
|
||||
mlog(AI__SPELLS, "Engaged autocast check triggered (BOTS). Trying to cast healing spells then maybe offensive spells.");
|
||||
Log.Out(Logs::Detail, Logs::AI, "Engaged autocast check triggered (BOTS). Trying to cast healing spells then maybe offensive spells.");
|
||||
|
||||
if(botClass == CLERIC) {
|
||||
if(!AICastSpell(GetTarget(), GetChanceToCastBySpellType(SpellType_Escape), SpellType_Escape)) {
|
||||
@@ -1755,7 +1755,7 @@ Mob* Bot::GetFirstIncomingMobToMez(Bot* botCaster, BotSpell botSpell) {
|
||||
for(std::list<NPC*>::iterator itr = npc_list.begin(); itr != npc_list.end(); ++itr) {
|
||||
NPC* npc = *itr;
|
||||
|
||||
if(npc->DistNoRootNoZ(*botCaster) <= botCaster->GetActSpellRange(botSpell.SpellId, spells[botSpell.SpellId].range)) {
|
||||
if(DistanceSquaredNoZ(npc->GetPosition(), botCaster->GetPosition()) <= botCaster->GetActSpellRange(botSpell.SpellId, spells[botSpell.SpellId].range)) {
|
||||
if(!npc->IsMezzed()) {
|
||||
if(botCaster->HasGroup()) {
|
||||
Group* g = botCaster->GetGroup();
|
||||
|
||||
+530
-521
File diff suppressed because it is too large
Load Diff
+35
-32
@@ -64,6 +64,7 @@ struct Item_Struct;
|
||||
#include <float.h>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
|
||||
#define CLIENT_TIMEOUT 90000
|
||||
@@ -201,7 +202,7 @@ struct ClientReward
|
||||
|
||||
class ClientFactory {
|
||||
public:
|
||||
Client *MakeClient(EQStream* ieqs);
|
||||
Client *MakeClient(std::shared_ptr<EQStream> ieqs);
|
||||
};
|
||||
|
||||
class Client : public Mob
|
||||
@@ -398,10 +399,10 @@ public:
|
||||
|
||||
inline const char* GetLastName() const { return lastname; }
|
||||
|
||||
inline float ProximityX() const { return(proximity_x); }
|
||||
inline float ProximityY() const { return(proximity_y); }
|
||||
inline float ProximityZ() const { return(proximity_z); }
|
||||
inline void ClearAllProximities() { entity_list.ProcessMove(this, FLT_MAX, FLT_MAX, FLT_MAX); proximity_x = FLT_MAX; proximity_y = FLT_MAX; proximity_z = FLT_MAX; }
|
||||
inline float ProximityX() const { return m_Proximity.x; }
|
||||
inline float ProximityY() const { return m_Proximity.y; }
|
||||
inline float ProximityZ() const { return m_Proximity.z; }
|
||||
inline void ClearAllProximities() { entity_list.ProcessMove(this, glm::vec3(FLT_MAX, FLT_MAX, FLT_MAX)); m_Proximity = glm::vec3(FLT_MAX,FLT_MAX,FLT_MAX); }
|
||||
|
||||
/*
|
||||
Begin client modifiers
|
||||
@@ -428,6 +429,7 @@ public:
|
||||
inline virtual int32 GetPR() const { return PR; }
|
||||
inline virtual int32 GetCR() const { return CR; }
|
||||
inline virtual int32 GetCorrup() const { return Corrup; }
|
||||
inline virtual int32 GetPhR() const { return PhR; }
|
||||
|
||||
int32 GetMaxStat() const;
|
||||
int32 GetMaxResist() const;
|
||||
@@ -452,6 +454,7 @@ public:
|
||||
inline uint8 GetBaseAGI() const { return m_pp.AGI; }
|
||||
inline uint8 GetBaseWIS() const { return m_pp.WIS; }
|
||||
inline uint8 GetBaseCorrup() const { return 15; } // Same for all
|
||||
inline uint8 GetBasePhR() const { return 0; } // Guessing at 0 as base
|
||||
|
||||
inline virtual int32 GetHeroicSTR() const { return itembonuses.HeroicSTR; }
|
||||
inline virtual int32 GetHeroicSTA() const { return itembonuses.HeroicSTA; }
|
||||
@@ -466,6 +469,7 @@ public:
|
||||
inline virtual int32 GetHeroicPR() const { return itembonuses.HeroicPR; }
|
||||
inline virtual int32 GetHeroicCR() const { return itembonuses.HeroicCR; }
|
||||
inline virtual int32 GetHeroicCorrup() const { return itembonuses.HeroicCorrup; }
|
||||
inline virtual int32 GetHeroicPhR() const { return 0; } // Heroic PhR not implemented yet
|
||||
// Mod2
|
||||
inline virtual int32 GetShielding() const { return itembonuses.MeleeMitigation; }
|
||||
inline virtual int32 GetSpellShield() const { return itembonuses.SpellShield; }
|
||||
@@ -577,7 +581,7 @@ public:
|
||||
void GoToBind(uint8 bindnum = 0);
|
||||
void GoToSafeCoords(uint16 zone_id, uint16 instance_id);
|
||||
void Gate();
|
||||
void SetBindPoint(int to_zone = -1, int to_instance = 0, float new_x = 0.0f, float new_y = 0.0f, float new_z = 0.0f);
|
||||
void SetBindPoint(int to_zone = -1, int to_instance = 0, const glm::vec3& location = glm::vec3());
|
||||
void SetStartZone(uint32 zoneid, float x = 0.0f, float y =0.0f, float z = 0.0f);
|
||||
uint32 GetStartZone(void);
|
||||
void MovePC(const char* zonename, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
|
||||
@@ -603,8 +607,9 @@ public:
|
||||
int32 GetCharacterFactionLevel(int32 faction_id);
|
||||
int32 GetModCharacterFactionLevel(int32 faction_id);
|
||||
void MerchantRejectMessage(Mob *merchant, int primaryfaction);
|
||||
void SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 totalvalue, uint8 temp);
|
||||
void SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_before_hit, int32 totalvalue, uint8 temp, int32 this_faction_min, int32 this_faction_max);
|
||||
|
||||
void UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp, int32 this_faction_min, int32 this_faction_max);
|
||||
void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity);
|
||||
void SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp);
|
||||
int32 GetRawItemAC();
|
||||
@@ -725,6 +730,7 @@ public:
|
||||
#endif
|
||||
uint32 GetEquipment(uint8 material_slot) const; // returns item id
|
||||
uint32 GetEquipmentColor(uint8 material_slot) const;
|
||||
virtual void UpdateEquipLightValue() { equip_light = m_inv.FindHighestLightValue(); }
|
||||
|
||||
inline bool AutoSplitEnabled() { return m_pp.autosplit != 0; }
|
||||
|
||||
@@ -832,20 +838,19 @@ public:
|
||||
void SetProxyItemID(uint32 proxyItemID) { m_ProxyItemID = proxyItemID; } // mainly for saylinks..but, not limited to
|
||||
void SetProxyText(const char* proxyText) { m_ProxyText = proxyText; } // overrides standard text use
|
||||
void SetTaskUse() { m_TaskUse = true; }
|
||||
void SetClientVersion(EQClientVersion clientVersion) { m_ClientVersion = EQLimits::ValidateClientVersion(clientVersion); }
|
||||
|
||||
std::string GenerateLink();
|
||||
bool LinkError() { return m_Error; }
|
||||
|
||||
const char* GetLink(); // contains full format: '/12x' '<LinkBody>' '<LinkText>' '/12x'
|
||||
const char* GetLinkBody(); // contains format: '<LinkBody>'
|
||||
const char* GetLinkText(); // contains format: '<LinkText>'
|
||||
std::string GetLinkString();
|
||||
std::string GetLinkBodyString();
|
||||
std::string GetLinkTextString();
|
||||
std::string GetLink() { return m_Link; } // contains full string format: '/12x' '<LinkBody>' '<LinkText>' '/12x'
|
||||
std::string GetLinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
|
||||
std::string GetLinkText() { return m_LinkText; } // contains string format: '<LinkText>'
|
||||
|
||||
void Reset();
|
||||
|
||||
static bool DegenerateLinkBody(TextLinkBody_Struct& textLinkBodyStruct, const std::string& textLinkBody);
|
||||
static bool GenerateLinkBody(std::string& textLinkBody, const TextLinkBody_Struct& textLinkBodyStruct);
|
||||
|
||||
private:
|
||||
void generate_body();
|
||||
void generate_text();
|
||||
@@ -857,10 +862,10 @@ public:
|
||||
uint32 m_ProxyItemID;
|
||||
const char* m_ProxyText;
|
||||
bool m_TaskUse;
|
||||
TextLinkBody_Struct m_LinkBodyStruct;
|
||||
std::string m_Link;
|
||||
std::string m_LinkBody;
|
||||
std::string m_LinkText;
|
||||
EQClientVersion m_ClientVersion;
|
||||
bool m_Error;
|
||||
};
|
||||
|
||||
@@ -912,8 +917,6 @@ public:
|
||||
void SendZoneFlagInfo(Client *to) const;
|
||||
void LoadZoneFlags();
|
||||
|
||||
void ChangeSQLLog(const char *file);
|
||||
void LogSQL(const char *fmt, ...);
|
||||
bool CanFish();
|
||||
void GoFish();
|
||||
void ForageItem(bool guarantee = false);
|
||||
@@ -1017,8 +1020,9 @@ public:
|
||||
inline int ActiveTasksInSet(int TaskSet) { return (taskstate ? taskstate->ActiveTasksInSet(TaskSet) :0); }
|
||||
inline int CompletedTasksInSet(int TaskSet) { return (taskstate ? taskstate->CompletedTasksInSet(TaskSet) :0); }
|
||||
|
||||
inline const EQClientVersion GetClientVersion() const { return ClientVersion; }
|
||||
inline const ClientVersion GetClientVersion() const { return m_ClientVersion; }
|
||||
inline const uint32 GetClientVersionBit() const { return ClientVersionBit; }
|
||||
inline void SetClientVersion(ClientVersion in) { m_ClientVersion = in; }
|
||||
|
||||
/** Adventure Stuff **/
|
||||
void SendAdventureError(const char *error);
|
||||
@@ -1076,7 +1080,7 @@ public:
|
||||
void DoItemEnterZone();
|
||||
bool DoItemEnterZone(uint32 slot_x, uint32 slot_y); // behavior change: 'slot_y' is now [RANGE]_END and not [RANGE]_END + 1
|
||||
void SummonAndRezzAllCorpses();
|
||||
void SummonAllCorpses(float dest_x, float dest_y, float dest_z, float dest_heading);
|
||||
void SummonAllCorpses(const glm::vec4& position);
|
||||
void DepopAllCorpses();
|
||||
void DepopPlayerCorpse(uint32 dbid);
|
||||
void BuryPlayerCorpses();
|
||||
@@ -1095,7 +1099,7 @@ public:
|
||||
QGlobalCache *GetQGlobals() { return qGlobals; }
|
||||
QGlobalCache *CreateQGlobals() { qGlobals = new QGlobalCache(); return qGlobals; }
|
||||
void GuildBankAck();
|
||||
void GuildBankDepositAck(bool Fail);
|
||||
void GuildBankDepositAck(bool Fail, int8 action);
|
||||
inline bool IsGuildBanker() { return GuildBanker; }
|
||||
void ClearGuildBank();
|
||||
void SendGroupCreatePacket();
|
||||
@@ -1135,7 +1139,7 @@ public:
|
||||
void HandleLFGuildResponse(ServerPacket *pack);
|
||||
void SendLFGuildStatus();
|
||||
void SendGuildLFGuildStatus();
|
||||
inline bool XTargettingAvailable() const { return ((ClientVersionBit & BIT_UnderfootAndLater) && RuleB(Character, EnableXTargetting)); }
|
||||
inline bool XTargettingAvailable() const { return ((ClientVersionBit & BIT_UFAndLater) && RuleB(Character, EnableXTargetting)); }
|
||||
inline uint8 GetMaxXTargets() const { return MaxXTargets; }
|
||||
void SetMaxXTargets(uint8 NewMax);
|
||||
bool IsXTarget(const Mob *m) const;
|
||||
@@ -1245,6 +1249,10 @@ public:
|
||||
|
||||
bool InterrogateInventory(Client* requester, bool log, bool silent, bool allowtrip, bool& error, bool autolog = true);
|
||||
|
||||
//Command #Tune functions
|
||||
virtual int32 Tune_GetMeleeMitDmg(Mob* GM, Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||
int32 GetMeleeDamage(Mob* other, bool GetMinDamage = false);
|
||||
|
||||
protected:
|
||||
friend class Mob;
|
||||
void CalcItemBonuses(StatBonuses* newbon);
|
||||
@@ -1261,11 +1269,10 @@ protected:
|
||||
|
||||
Mob* bind_sight_target;
|
||||
|
||||
Map::Vertex aa_los_me;
|
||||
Map::Vertex aa_los_them;
|
||||
glm::vec4 m_AutoAttackPosition;
|
||||
glm::vec3 m_AutoAttackTargetLocation;
|
||||
Mob *aa_los_them_mob;
|
||||
bool los_status;
|
||||
float aa_los_me_heading;
|
||||
bool los_status_facing;
|
||||
QGlobalCache *qGlobals;
|
||||
|
||||
@@ -1418,9 +1425,8 @@ private:
|
||||
void DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instance_id, float dest_x, float dest_y, float dest_z, float dest_h, int8 ignore_r);
|
||||
void ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm);
|
||||
void ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
|
||||
float zonesummon_x;
|
||||
float zonesummon_y;
|
||||
float zonesummon_z;
|
||||
|
||||
glm::vec3 m_ZoneSummonLocation;
|
||||
uint16 zonesummon_id;
|
||||
uint8 zonesummon_ignorerestrictions;
|
||||
ZoneMode zone_mode;
|
||||
@@ -1459,10 +1465,7 @@ private:
|
||||
Timer RespawnFromHoverTimer;
|
||||
Timer merc_timer;
|
||||
|
||||
float proximity_x;
|
||||
float proximity_y;
|
||||
float proximity_z;
|
||||
|
||||
glm::vec3 m_Proximity;
|
||||
|
||||
void BulkSendInventoryItems();
|
||||
|
||||
@@ -1505,7 +1508,7 @@ private:
|
||||
Timer *GlobalChatLimiterTimer; //60 seconds
|
||||
uint32 AttemptedMessages;
|
||||
|
||||
EQClientVersion ClientVersion;
|
||||
ClientVersion m_ClientVersion;
|
||||
uint32 ClientVersionBit;
|
||||
|
||||
int XPRate;
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "../common/debug.h"
|
||||
#include "../common/features.h"
|
||||
|
||||
#ifdef CLIENT_LOGS
|
||||
#include "client_logs.h"
|
||||
#include "client.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
ClientLogs client_logs;
|
||||
|
||||
char ClientLogs::_buffer[MAX_CLIENT_LOG_MESSAGE_LENGTH+1];
|
||||
|
||||
void ClientLogs::subscribe(EQEMuLog::LogIDs id, Client *c) {
|
||||
if(id >= EQEMuLog::MaxLogID)
|
||||
return;
|
||||
if(c == nullptr)
|
||||
return;
|
||||
|
||||
std::vector<Client *>::iterator cur,end;
|
||||
cur = entries[id].begin();
|
||||
end = entries[id].end();
|
||||
for(; cur != end; ++cur) {
|
||||
if(*cur == c) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
entries[id].push_back(c);
|
||||
}
|
||||
|
||||
void ClientLogs::unsubscribe(EQEMuLog::LogIDs id, Client *c) {
|
||||
if(id >= EQEMuLog::MaxLogID)
|
||||
return;
|
||||
if(c == nullptr)
|
||||
return;
|
||||
|
||||
std::vector<Client *>::iterator cur,end;
|
||||
cur = entries[id].begin();
|
||||
end = entries[id].end();
|
||||
for(; cur != end; ++cur) {
|
||||
if(*cur == c) {
|
||||
entries[id].erase(cur);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientLogs::subscribeAll(Client *c) {
|
||||
if(c == nullptr)
|
||||
return;
|
||||
int r;
|
||||
for(r = EQEMuLog::Status; r < EQEMuLog::MaxLogID; r++) {
|
||||
subscribe((EQEMuLog::LogIDs)r, c);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientLogs::unsubscribeAll(Client *c) {
|
||||
if(c == nullptr)
|
||||
return;
|
||||
int r;
|
||||
for(r = EQEMuLog::Status; r < EQEMuLog::MaxLogID; r++) {
|
||||
unsubscribe((EQEMuLog::LogIDs)r, c);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientLogs::clear() {
|
||||
int r;
|
||||
for(r = EQEMuLog::Status; r < EQEMuLog::MaxLogID; r++) {
|
||||
entries[r].clear();
|
||||
}
|
||||
}
|
||||
|
||||
void ClientLogs::msg(EQEMuLog::LogIDs id, const char *buf) {
|
||||
if(id >= EQEMuLog::MaxLogID)
|
||||
return;
|
||||
std::vector<Client *>::iterator cur,end;
|
||||
cur = entries[id].begin();
|
||||
end = entries[id].end();
|
||||
for(; cur != end; ++cur) {
|
||||
if(!(*cur)->InZone())
|
||||
continue;
|
||||
|
||||
(*cur)->Message(CLIENT_LOG_CHANNEL, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientLogs::EQEmuIO_buf(EQEMuLog::LogIDs id, const char *buf, uint8 size, uint32 count) {
|
||||
if(size != 1)
|
||||
return; //cannot print multibyte data
|
||||
if(buf[0] == '\n' || buf[0] == '\r')
|
||||
return; //skip new lines...
|
||||
if(count > MAX_CLIENT_LOG_MESSAGE_LENGTH)
|
||||
count = MAX_CLIENT_LOG_MESSAGE_LENGTH;
|
||||
memcpy(_buffer, buf, count);
|
||||
_buffer[count] = '\0';
|
||||
client_logs.msg(id, _buffer);
|
||||
}
|
||||
|
||||
void ClientLogs::EQEmuIO_fmt(EQEMuLog::LogIDs id, const char *fmt, va_list ap) {
|
||||
if(fmt[0] == '\n' || fmt[0] == '\r')
|
||||
return; //skip new lines...
|
||||
vsnprintf(_buffer, MAX_CLIENT_LOG_MESSAGE_LENGTH, fmt, ap);
|
||||
_buffer[MAX_CLIENT_LOG_MESSAGE_LENGTH] = '\0';
|
||||
client_logs.msg(id, _buffer);
|
||||
}
|
||||
|
||||
void ClientLogs::EQEmuIO_pva(EQEMuLog::LogIDs id, const char *prefix, const char *fmt, va_list ap) {
|
||||
if(fmt[0] == '\n' || fmt[0] == '\r')
|
||||
return; //skip new lines...
|
||||
char *buf = _buffer;
|
||||
int plen = snprintf(buf, MAX_CLIENT_LOG_MESSAGE_LENGTH, "%s", prefix);
|
||||
buf += plen;
|
||||
vsnprintf(buf, MAX_CLIENT_LOG_MESSAGE_LENGTH-plen, fmt, ap);
|
||||
_buffer[MAX_CLIENT_LOG_MESSAGE_LENGTH] = '\0';
|
||||
client_logs.msg(id, _buffer);
|
||||
}
|
||||
|
||||
#endif //CLIENT_LOGS
|
||||
|
||||
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef CLIENT_LOGS_H
|
||||
#define CLIENT_LOGS_H
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/features.h"
|
||||
|
||||
#ifdef CLIENT_LOGS
|
||||
|
||||
#define CLIENT_LOG_CHANNEL MT_Chat10Echo
|
||||
|
||||
//trim messages to this length before sending to any clients
|
||||
#define MAX_CLIENT_LOG_MESSAGE_LENGTH 512
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Client;
|
||||
|
||||
class ClientLogs {
|
||||
public:
|
||||
static void EQEmuIO_buf(EQEMuLog::LogIDs id, const char *buf, uint8 size, uint32 count);
|
||||
static void EQEmuIO_fmt(EQEMuLog::LogIDs id, const char *fmt, va_list ap);
|
||||
static void EQEmuIO_pva(EQEMuLog::LogIDs id, const char *prefix, const char *fmt, va_list ap);
|
||||
|
||||
void subscribe(EQEMuLog::LogIDs id, Client *c);
|
||||
void unsubscribe(EQEMuLog::LogIDs id, Client *c);
|
||||
void subscribeAll(Client *c);
|
||||
void unsubscribeAll(Client *c);
|
||||
void clear(); //unsubscribes everybody
|
||||
|
||||
void msg(EQEMuLog::LogIDs id, const char *buf);
|
||||
|
||||
protected:
|
||||
|
||||
std::vector<Client *> entries[EQEMuLog::MaxLogID];
|
||||
|
||||
static char _buffer[MAX_CLIENT_LOG_MESSAGE_LENGTH+1];
|
||||
};
|
||||
|
||||
extern ClientLogs client_logs;
|
||||
|
||||
#endif //CLIENT_LOGS
|
||||
#endif
|
||||
|
||||
+1093
-937
File diff suppressed because it is too large
Load Diff
+582
-533
File diff suppressed because it is too large
Load Diff
+57
-67
@@ -18,7 +18,9 @@
|
||||
client_process.cpp:
|
||||
Handles client login sequence and packets sent from client to zone
|
||||
*/
|
||||
#include "../common/debug.h"
|
||||
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/global_define.h"
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <zlib.h>
|
||||
@@ -124,7 +126,7 @@ bool Client::Process() {
|
||||
HandleRespawnFromHover(0);
|
||||
}
|
||||
|
||||
if(IsTracking() && (GetClientVersion() >= EQClientSoD) && TrackingTimer.Check())
|
||||
if(IsTracking() && (GetClientVersion() >= ClientVersion::SoD) && TrackingTimer.Check())
|
||||
DoTracking();
|
||||
|
||||
if(hpupdate_timer.Check())
|
||||
@@ -174,7 +176,7 @@ bool Client::Process() {
|
||||
GetMerc()->Save();
|
||||
GetMerc()->Depop();
|
||||
}
|
||||
|
||||
|
||||
Raid *myraid = entity_list.GetRaidByClient(this);
|
||||
if (myraid)
|
||||
{
|
||||
@@ -231,10 +233,7 @@ bool Client::Process() {
|
||||
|
||||
if(GetMercInfo().MercTemplateID != 0 && GetMercInfo().IsSuspended)
|
||||
{
|
||||
if(p_timers.Expired(&database, pTimerMercSuspend, false))
|
||||
{
|
||||
CheckMercSuspendTimer();
|
||||
}
|
||||
CheckMercSuspendTimer();
|
||||
}
|
||||
|
||||
if(IsAIControlled())
|
||||
@@ -340,41 +339,31 @@ bool Client::Process() {
|
||||
if(aa_los_them_mob)
|
||||
{
|
||||
if(auto_attack_target != aa_los_them_mob ||
|
||||
aa_los_me.x != GetX() ||
|
||||
aa_los_me.y != GetY() ||
|
||||
aa_los_me.z != GetZ() ||
|
||||
aa_los_them.x != aa_los_them_mob->GetX() ||
|
||||
aa_los_them.y != aa_los_them_mob->GetY() ||
|
||||
aa_los_them.z != aa_los_them_mob->GetZ())
|
||||
m_AutoAttackPosition.x != GetX() ||
|
||||
m_AutoAttackPosition.y != GetY() ||
|
||||
m_AutoAttackPosition.z != GetZ() ||
|
||||
m_AutoAttackTargetLocation.x != aa_los_them_mob->GetX() ||
|
||||
m_AutoAttackTargetLocation.y != aa_los_them_mob->GetY() ||
|
||||
m_AutoAttackTargetLocation.z != aa_los_them_mob->GetZ())
|
||||
{
|
||||
aa_los_them_mob = auto_attack_target;
|
||||
aa_los_me.x = GetX();
|
||||
aa_los_me.y = GetY();
|
||||
aa_los_me.z = GetZ();
|
||||
aa_los_them.x = aa_los_them_mob->GetX();
|
||||
aa_los_them.y = aa_los_them_mob->GetY();
|
||||
aa_los_them.z = aa_los_them_mob->GetZ();
|
||||
m_AutoAttackPosition = GetPosition();
|
||||
m_AutoAttackTargetLocation = glm::vec3(aa_los_them_mob->GetPosition());
|
||||
los_status = CheckLosFN(auto_attack_target);
|
||||
aa_los_me_heading = GetHeading();
|
||||
los_status_facing = IsFacingMob(aa_los_them_mob);
|
||||
}
|
||||
// If only our heading changes, we can skip the CheckLosFN call
|
||||
// but above we still need to update los_status_facing
|
||||
if (aa_los_me_heading != GetHeading()) {
|
||||
aa_los_me_heading = GetHeading();
|
||||
if (m_AutoAttackPosition.w != GetHeading()) {
|
||||
m_AutoAttackPosition.w = GetHeading();
|
||||
los_status_facing = IsFacingMob(aa_los_them_mob);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aa_los_them_mob = auto_attack_target;
|
||||
aa_los_me.x = GetX();
|
||||
aa_los_me.y = GetY();
|
||||
aa_los_me.z = GetZ();
|
||||
aa_los_me_heading = GetHeading();
|
||||
aa_los_them.x = aa_los_them_mob->GetX();
|
||||
aa_los_them.y = aa_los_them_mob->GetY();
|
||||
aa_los_them.z = aa_los_them_mob->GetZ();
|
||||
m_AutoAttackPosition = GetPosition();
|
||||
m_AutoAttackTargetLocation = glm::vec3(aa_los_them_mob->GetPosition());
|
||||
los_status = CheckLosFN(auto_attack_target);
|
||||
los_status_facing = IsFacingMob(aa_los_them_mob);
|
||||
}
|
||||
@@ -529,9 +518,7 @@ bool Client::Process() {
|
||||
else
|
||||
{
|
||||
animation = 0;
|
||||
delta_x = 0;
|
||||
delta_y = 0;
|
||||
delta_z = 0;
|
||||
m_Delta = glm::vec4(0.0f, 0.0f, 0.0f, m_Delta.w);
|
||||
SendPosUpdate(2);
|
||||
}
|
||||
}
|
||||
@@ -668,7 +655,7 @@ bool Client::Process() {
|
||||
|
||||
if (client_state != CLIENT_LINKDEAD && !eqs->CheckState(ESTABLISHED)) {
|
||||
OnDisconnect(true);
|
||||
std::cout << "Client linkdead: " << name << std::endl;
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Client linkdead: %s", name);
|
||||
|
||||
if (GetGM()) {
|
||||
if (GetMerc())
|
||||
@@ -785,32 +772,32 @@ void Client::OnDisconnect(bool hard_disconnect) {
|
||||
if (MyRaid)
|
||||
MyRaid->MemberZoned(this);
|
||||
|
||||
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
|
||||
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
|
||||
|
||||
/* QS: PlayerLogConnectDisconnect */
|
||||
if (RuleB(QueryServ, PlayerLogConnectDisconnect)){
|
||||
std::string event_desc = StringFormat("Disconnect :: in zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_Connect_State, this->CharacterID(), event_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Mob *Other = trade->With();
|
||||
Mob *Other = trade->With();
|
||||
if(Other)
|
||||
{
|
||||
mlog(TRADING__CLIENT, "Client disconnected during a trade. Returning their items.");
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client disconnected during a trade. Returning their items.");
|
||||
FinishTrade(this);
|
||||
|
||||
if(Other->IsClient())
|
||||
Other->CastToClient()->FinishTrade(Other);
|
||||
|
||||
/* Reset both sides of the trade */
|
||||
trade->Reset();
|
||||
trade->Reset();
|
||||
Other->trade->Reset();
|
||||
}
|
||||
|
||||
database.SetFirstLogon(CharacterID(), 0); //We change firstlogon status regardless of if a player logs out to zone or not, because we only want to trigger it on their first login from world.
|
||||
|
||||
/* Remove ourself from all proximities */
|
||||
/* Remove ourself from all proximities */
|
||||
ClearAllProximities();
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LogoutReply);
|
||||
@@ -834,7 +821,7 @@ void Client::BulkSendInventoryItems() {
|
||||
if(inst) {
|
||||
bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false;
|
||||
int16 free_slot_id = m_inv.FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size, is_arrow);
|
||||
mlog(INVENTORY__ERROR, "Incomplete Trade Transaction: Moving %s from slot %i to %i", inst->GetItem()->Name, slot_id, free_slot_id);
|
||||
Log.Out(Logs::Detail, Logs::Inventory, "Incomplete Trade Transaction: Moving %s from slot %i to %i", inst->GetItem()->Name, slot_id, free_slot_id);
|
||||
PutItemInInventory(free_slot_id, *inst, false);
|
||||
database.SaveInventory(character_id, nullptr, slot_id);
|
||||
safe_delete(inst);
|
||||
@@ -883,7 +870,7 @@ void Client::BulkSendInventoryItems() {
|
||||
}
|
||||
|
||||
// Power Source
|
||||
if(GetClientVersion() >= EQClientSoF) {
|
||||
if(GetClientVersion() >= ClientVersion::SoF) {
|
||||
const ItemInst* inst = m_inv[MainPowerSource];
|
||||
if(inst) {
|
||||
std::string packet = inst->Serialize(MainPowerSource);
|
||||
@@ -973,6 +960,9 @@ void Client::BulkSendInventoryItems()
|
||||
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||
const Item_Struct* handyitem = nullptr;
|
||||
uint32 numItemSlots = 80; //The max number of items passed in the transaction.
|
||||
if (ClientVersionBit & BIT_RoFAndLater) { // RoF+ can send 200 items
|
||||
numItemSlots = 200;
|
||||
}
|
||||
const Item_Struct *item;
|
||||
std::list<MerchantList> merlist = zone->merchanttable[merchant_id];
|
||||
std::list<MerchantList>::const_iterator itr;
|
||||
@@ -1035,7 +1025,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||
// Account for merchant lists with gaps.
|
||||
if (ml.slot >= i) {
|
||||
if (ml.slot > i)
|
||||
LogFile->write(EQEMuLog::Debug, "(WARNING) Merchantlist contains gap at slot %d. Merchant: %d, NPC: %d", i, merchant_id, npcid);
|
||||
Log.Out(Logs::General, Logs::None, "(WARNING) Merchantlist contains gap at slot %d. Merchant: %d, NPC: %d", i, merchant_id, npcid);
|
||||
i = ml.slot + 1;
|
||||
}
|
||||
}
|
||||
@@ -1127,7 +1117,7 @@ uint8 Client::WithCustomer(uint16 NewCustomer){
|
||||
Client* c = entity_list.GetClientByID(CustomerID);
|
||||
|
||||
if(!c) {
|
||||
_log(TRADING__CLIENT, "Previous customer has gone away.");
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Previous customer has gone away.");
|
||||
CustomerID = NewCustomer;
|
||||
return 1;
|
||||
}
|
||||
@@ -1139,7 +1129,7 @@ void Client::OPRezzAnswer(uint32 Action, uint32 SpellID, uint16 ZoneID, uint16 I
|
||||
{
|
||||
if(PendingRezzXP < 0) {
|
||||
// pendingrezexp is set to -1 if we are not expecting an OP_RezzAnswer
|
||||
_log(SPELLS__REZ, "Unexpected OP_RezzAnswer. Ignoring it.");
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Unexpected OP_RezzAnswer. Ignoring it.");
|
||||
Message(13, "You have already been resurrected.\n");
|
||||
return;
|
||||
}
|
||||
@@ -1149,7 +1139,7 @@ void Client::OPRezzAnswer(uint32 Action, uint32 SpellID, uint16 ZoneID, uint16 I
|
||||
// Mark the corpse as rezzed in the database, just in case the corpse has buried, or the zone the
|
||||
// corpse is in has shutdown since the rez spell was cast.
|
||||
database.MarkCorpseAsRezzed(PendingRezzDBID);
|
||||
_log(SPELLS__REZ, "Player %s got a %i Rezz, spellid %i in zone%i, instance id %i",
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Player %s got a %i Rezz, spellid %i in zone%i, instance id %i",
|
||||
this->name, (uint16)spells[SpellID].base[0],
|
||||
SpellID, ZoneID, InstanceID);
|
||||
|
||||
@@ -1199,7 +1189,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app)
|
||||
{
|
||||
if(app->size != sizeof(MemorizeSpell_Struct))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error,"Wrong size on OP_MemorizeSpell. Got: %i, Expected: %i", app->size, sizeof(MemorizeSpell_Struct));
|
||||
Log.Out(Logs::General, Logs::Error, "Wrong size on OP_MemorizeSpell. Got: %i, Expected: %i", app->size, sizeof(MemorizeSpell_Struct));
|
||||
DumpPacket(app);
|
||||
return;
|
||||
}
|
||||
@@ -1555,7 +1545,7 @@ void Client::OPMoveCoin(const EQApplicationPacket* app)
|
||||
if (from_bucket == &m_pp.platinum_shared)
|
||||
amount_to_add = 0 - amount_to_take;
|
||||
|
||||
database.SetSharedPlatinum(AccountID(),amount_to_add);
|
||||
database.SetSharedPlatinum(AccountID(),amount_to_add);
|
||||
}
|
||||
}
|
||||
else{
|
||||
@@ -1613,7 +1603,7 @@ void Client::OPGMTraining(const EQApplicationPacket *app)
|
||||
return;
|
||||
|
||||
//you have to be somewhat close to a trainer to be properly using them
|
||||
if(DistNoRoot(*pTrainer) > USE_NPC_RANGE2)
|
||||
if(DistanceSquared(m_Position,pTrainer->GetPosition()) > USE_NPC_RANGE2)
|
||||
return;
|
||||
|
||||
// if this for-loop acts up again (crashes linux), try enabling the before and after #pragmas
|
||||
@@ -1661,7 +1651,7 @@ void Client::OPGMEndTraining(const EQApplicationPacket *app)
|
||||
return;
|
||||
|
||||
//you have to be somewhat close to a trainer to be properly using them
|
||||
if(DistNoRoot(*pTrainer) > USE_NPC_RANGE2)
|
||||
if(DistanceSquared(m_Position, pTrainer->GetPosition()) > USE_NPC_RANGE2)
|
||||
return;
|
||||
|
||||
// goodbye message
|
||||
@@ -1690,7 +1680,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
||||
return;
|
||||
|
||||
//you have to be somewhat close to a trainer to be properly using them
|
||||
if(DistNoRoot(*pTrainer) > USE_NPC_RANGE2)
|
||||
if(DistanceSquared(m_Position, pTrainer->GetPosition()) > USE_NPC_RANGE2)
|
||||
return;
|
||||
|
||||
if (gmskill->skillbank == 0x01)
|
||||
@@ -1721,12 +1711,12 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
||||
SkillUseTypes skill = (SkillUseTypes) gmskill->skill_id;
|
||||
|
||||
if(!CanHaveSkill(skill)) {
|
||||
mlog(CLIENT__ERROR, "Tried to train skill %d, which is not allowed.", skill);
|
||||
Log.Out(Logs::Detail, Logs::Skills, "Tried to train skill %d, which is not allowed.", skill);
|
||||
return;
|
||||
}
|
||||
|
||||
if(MaxSkill(skill) == 0) {
|
||||
mlog(CLIENT__ERROR, "Tried to train skill %d, but training is not allowed at this level.", skill);
|
||||
Log.Out(Logs::Detail, Logs::Skills, "Tried to train skill %d, but training is not allowed at this level.", skill);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1741,7 +1731,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
SetSkill(skill, t_level);
|
||||
} else {
|
||||
} else {
|
||||
switch(skill) {
|
||||
case SkillBrewing:
|
||||
case SkillMakePoison:
|
||||
@@ -1804,7 +1794,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
||||
}
|
||||
}
|
||||
|
||||
if(GetClientVersion() >= EQClientSoF) {
|
||||
if(GetClientVersion() >= ClientVersion::SoF) {
|
||||
// The following packet decreases the skill points left in the Training Window and
|
||||
// produces the 'You have increased your skill / learned the basics of' message.
|
||||
//
|
||||
@@ -1943,7 +1933,7 @@ void Client::DoEnduranceUpkeep() {
|
||||
|
||||
int upkeep_sum = 0;
|
||||
int cost_redux = spellbonuses.EnduranceReduction + itembonuses.EnduranceReduction + aabonuses.EnduranceReduction;
|
||||
|
||||
|
||||
bool has_effect = false;
|
||||
uint32 buffs_i;
|
||||
uint32 buff_count = GetMaxTotalSlots();
|
||||
@@ -2120,7 +2110,7 @@ void Client::HandleRespawnFromHover(uint32 Option)
|
||||
{
|
||||
if (PendingRezzXP < 0 || PendingRezzSpellID == 0)
|
||||
{
|
||||
_log(SPELLS__REZ, "Unexpected Rezz from hover request.");
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Unexpected Rezz from hover request.");
|
||||
return;
|
||||
}
|
||||
SetHP(GetMaxHP() / 5);
|
||||
@@ -2129,9 +2119,9 @@ void Client::HandleRespawnFromHover(uint32 Option)
|
||||
|
||||
if (corpse)
|
||||
{
|
||||
x_pos = corpse->GetX();
|
||||
y_pos = corpse->GetY();
|
||||
z_pos = corpse->GetZ();
|
||||
m_Position.x = corpse->GetX();
|
||||
m_Position.y = corpse->GetY();
|
||||
m_Position.z = corpse->GetZ();
|
||||
}
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ZonePlayerToBind, sizeof(ZonePlayerToBind_Struct) + 10);
|
||||
@@ -2153,10 +2143,10 @@ void Client::HandleRespawnFromHover(uint32 Option)
|
||||
|
||||
if (corpse && corpse->IsCorpse())
|
||||
{
|
||||
_log(SPELLS__REZ, "Hover Rez in zone %s for corpse %s",
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Hover Rez in zone %s for corpse %s",
|
||||
zone->GetShortName(), PendingRezzCorpseName.c_str());
|
||||
|
||||
_log(SPELLS__REZ, "Found corpse. Marking corpse as rezzed.");
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Found corpse. Marking corpse as rezzed.");
|
||||
|
||||
corpse->IsRezzed(true);
|
||||
corpse->CompleteResurrection();
|
||||
@@ -2184,10 +2174,10 @@ void Client::HandleRespawnFromHover(uint32 Option)
|
||||
SetMana(GetMaxMana());
|
||||
SetEndurance(GetMaxEndurance());
|
||||
|
||||
x_pos = chosen->x;
|
||||
y_pos = chosen->y;
|
||||
z_pos = chosen->z;
|
||||
heading = chosen->heading;
|
||||
m_Position.x = chosen->x;
|
||||
m_Position.y = chosen->y;
|
||||
m_Position.z = chosen->z;
|
||||
m_Position.w = chosen->heading;
|
||||
|
||||
ClearHover();
|
||||
entity_list.RefreshClientXTargets(this);
|
||||
@@ -2197,7 +2187,7 @@ void Client::HandleRespawnFromHover(uint32 Option)
|
||||
//After they've respawned into the same zone, trigger EVENT_RESPAWN
|
||||
parse->EventPlayer(EVENT_RESPAWN, this, static_cast<std::string>(itoa(Option)), is_rez ? 1 : 0);
|
||||
|
||||
//Pop Rez option from the respawn options list;
|
||||
//Pop Rez option from the respawn options list;
|
||||
//easiest way to make sure it stays at the end and
|
||||
//doesn't disrupt adding/removing scripted options
|
||||
respawn_options.pop_back();
|
||||
@@ -2244,7 +2234,7 @@ void Client::ClearHover()
|
||||
entity_list.QueueClients(this, outapp, false);
|
||||
safe_delete(outapp);
|
||||
|
||||
if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UnderfootAndLater)
|
||||
if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UFAndLater)
|
||||
{
|
||||
EQApplicationPacket *outapp = MakeBuffsPacket(false);
|
||||
CastToClient()->FastQueuePacket(&outapp);
|
||||
|
||||
+2285
-2316
File diff suppressed because it is too large
Load Diff
+5
-6
@@ -87,7 +87,6 @@ void command_chat(Client *c, const Seperator *sep);
|
||||
void command_showpetspell(Client *c, const Seperator *sep);
|
||||
void command_ipc(Client *c, const Seperator *sep);
|
||||
void command_npcloot(Client *c, const Seperator *sep);
|
||||
void command_log(Client *c, const Seperator *sep);
|
||||
void command_gm(Client *c, const Seperator *sep);
|
||||
void command_summon(Client *c, const Seperator *sep);
|
||||
void command_zone(Client *c, const Seperator *sep);
|
||||
@@ -259,9 +258,6 @@ void command_undye(Client *c, const Seperator *sep);
|
||||
void command_undyeme(Client *c, const Seperator *sep);
|
||||
void command_hp(Client *c, const Seperator *sep);
|
||||
void command_ginfo(Client *c, const Seperator *sep);
|
||||
void command_logs(Client *c, const Seperator *sep);
|
||||
void command_nologs(Client *c, const Seperator *sep);
|
||||
void command_logsql(Client *c, const Seperator *sep);
|
||||
void command_qglobal(Client *c, const Seperator *sep);
|
||||
void command_path(Client *c, const Seperator *sep);
|
||||
void command_ginfo(Client *c, const Seperator *sep);
|
||||
@@ -272,7 +268,6 @@ void command_aggrozone(Client *c, const Seperator *sep);
|
||||
void command_reloadstatic(Client *c, const Seperator *sep);
|
||||
void command_flags(Client *c, const Seperator *sep);
|
||||
void command_flagedit(Client *c, const Seperator *sep);
|
||||
void command_mlog(Client *c, const Seperator *sep);
|
||||
void command_serverrules(Client *c, const Seperator *sep);
|
||||
void command_acceptrules(Client *c, const Seperator *sep);
|
||||
void command_guildcreate(Client *c, const Seperator *sep);
|
||||
@@ -326,7 +321,11 @@ void command_npctype_cache(Client *c, const Seperator *sep);
|
||||
void command_merchantopenshop(Client *c, const Seperator *sep);
|
||||
void command_merchantcloseshop(Client *c, const Seperator *sep);
|
||||
void command_shownumhits(Client *c, const Seperator *sep);
|
||||
|
||||
void command_tune(Client *c, const Seperator *sep);
|
||||
void command_logtest(Client *c, const Seperator *sep);
|
||||
void command_mysqltest(Client *c, const Seperator *sep);
|
||||
void command_logs(Client *c, const Seperator *sep);
|
||||
|
||||
#ifdef EQPROFILE
|
||||
void command_profiledump(Client *c, const Seperator *sep);
|
||||
void command_profilereset(Client *c, const Seperator *sep);
|
||||
|
||||
+15
-17
@@ -7,7 +7,7 @@
|
||||
#define HIGHEST_RESIST 9 //Max resist type value
|
||||
#define MAX_SPELL_PROJECTILE 10 //Max amount of spell projectiles that can be active by a single mob.
|
||||
|
||||
/* solar: macros for IsAttackAllowed, IsBeneficialAllowed */
|
||||
/* macros for IsAttackAllowed, IsBeneficialAllowed */
|
||||
#define _CLIENT(x) (x && x->IsClient() && !x->CastToClient()->IsBecomeNPC())
|
||||
#define _NPC(x) (x && x->IsNPC() && !x->CastToMob()->GetOwnerID())
|
||||
#define _BECOMENPC(x) (x && x->IsClient() && x->CastToClient()->IsBecomeNPC())
|
||||
@@ -158,18 +158,18 @@ enum TradeState {
|
||||
TradeCompleting
|
||||
};
|
||||
|
||||
enum { //Numhits type
|
||||
NUMHIT_IncomingHitAttempts = 1, //Attempted incoming melee attacks (hit or miss) on YOU.
|
||||
NUMHIT_OutgoingHitAttempts = 2, //Attempted outgoing melee attacks (hit or miss) on YOUR TARGET.
|
||||
NUMHIT_IncomingSpells = 3, //Incoming detrimental spells
|
||||
NUMHIT_OutgoingSpells = 4, //Outgoing deterimental spells
|
||||
NUMHIT_OutgoingHitSuccess = 5, //Successful outgoing melee attack HIT on YOUR TARGET.
|
||||
NUMHIT_IncomingHitSuccess = 6, //Successful incoming melee attack HIT on YOU.
|
||||
NUMHIT_MatchingSpells = 7, //Any casted spell matching/triggering a focus effect.
|
||||
NUMHIT_IncomingDamage = 8, //Successful incoming spell or melee dmg attack on YOU
|
||||
NUMHIT_ReflectSpell = 9, //Incoming Reflected spells.
|
||||
NUMHIT_DefensiveSpellProcs = 10, //Defensive buff procs
|
||||
NUMHIT_OffensiveSpellProcs = 11 //Offensive buff procs
|
||||
enum class NumHit { // Numhits type
|
||||
IncomingHitAttempts = 1, // Attempted incoming melee attacks (hit or miss) on YOU.
|
||||
OutgoingHitAttempts = 2, // Attempted outgoing melee attacks (hit or miss) on YOUR TARGET.
|
||||
IncomingSpells = 3, // Incoming detrimental spells
|
||||
OutgoingSpells = 4, // Outgoing detrimental spells
|
||||
OutgoingHitSuccess = 5, // Successful outgoing melee attack HIT on YOUR TARGET.
|
||||
IncomingHitSuccess = 6, // Successful incoming melee attack HIT on YOU.
|
||||
MatchingSpells = 7, // Any casted spell matching/triggering a focus effect.
|
||||
IncomingDamage = 8, // Successful incoming spell or melee dmg attack on YOU
|
||||
ReflectSpell = 9, // Incoming Reflected spells.
|
||||
DefensiveSpellProcs = 10, // Defensive buff procs
|
||||
OffensiveSpellProcs = 11 // Offensive buff procs
|
||||
};
|
||||
|
||||
//this is our internal representation of the BUFF struct, can put whatever we want in it
|
||||
@@ -560,10 +560,8 @@ public:
|
||||
// Audit trade
|
||||
void LogTrade();
|
||||
|
||||
// Debug only method
|
||||
#if (EQDEBUG >= 9)
|
||||
void DumpTrade();
|
||||
#endif
|
||||
void DumpTrade();
|
||||
|
||||
|
||||
public:
|
||||
// Object state
|
||||
|
||||
+227
-259
@@ -28,7 +28,8 @@ Child of the Mob class.
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/string_util.h"
|
||||
|
||||
@@ -71,13 +72,13 @@ void Corpse::SendLootReqErrorPacket(Client* client, uint8 response) {
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, float in_x, float in_y, float in_z, float in_heading, std::string time_of_death, bool rezzed, bool was_at_graveyard){
|
||||
Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const glm::vec4& position, std::string time_of_death, bool rezzed, bool was_at_graveyard) {
|
||||
uint32 item_count = database.GetCharacterCorpseItemCount(in_dbid);
|
||||
char *buffer = new char[sizeof(PlayerCorpse_Struct) + (item_count * sizeof(player_lootitem::ServerLootItem_Struct))];
|
||||
PlayerCorpse_Struct *pcs = (PlayerCorpse_Struct*)buffer;
|
||||
database.LoadCharacterCorpseData(in_dbid, pcs);
|
||||
|
||||
/* Load Items */
|
||||
/* Load Items */
|
||||
ItemList itemlist;
|
||||
ServerLootItem_Struct* tmp = 0;
|
||||
for (unsigned int i = 0; i < pcs->itemcount; i++) {
|
||||
@@ -96,10 +97,7 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
|
||||
pcs->silver, // uint32 in_silver
|
||||
pcs->gold, // uint32 in_gold
|
||||
pcs->plat, // uint32 in_plat
|
||||
in_x, // float in_x
|
||||
in_y, // float in_y
|
||||
in_z, // float in_z
|
||||
in_heading, // float in_heading
|
||||
position,
|
||||
pcs->size, // float in_size
|
||||
pcs->gender, // uint8 in_gender
|
||||
pcs->race, // uint16 in_race
|
||||
@@ -111,9 +109,9 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
|
||||
pcs->exp, // uint32 in_rezexp
|
||||
was_at_graveyard // bool wasAtGraveyard
|
||||
);
|
||||
if (pcs->locked){
|
||||
|
||||
if (pcs->locked)
|
||||
pc->Lock();
|
||||
}
|
||||
|
||||
/* Load Item Tints */
|
||||
pc->item_tint[0].color = pcs->item_tint[0].color;
|
||||
@@ -124,7 +122,7 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
|
||||
pc->item_tint[5].color = pcs->item_tint[5].color;
|
||||
pc->item_tint[6].color = pcs->item_tint[6].color;
|
||||
pc->item_tint[7].color = pcs->item_tint[7].color;
|
||||
pc->item_tint[8].color = pcs->item_tint[8].color;
|
||||
pc->item_tint[8].color = pcs->item_tint[8].color;
|
||||
|
||||
/* Load Physical Appearance */
|
||||
pc->haircolor = pcs->haircolor;
|
||||
@@ -140,63 +138,22 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
|
||||
pc->IsRezzed(rezzed);
|
||||
pc->become_npc = false;
|
||||
|
||||
pc->spell_light = pc->innate_light = NOT_USED;
|
||||
pc->UpdateEquipLightValue();
|
||||
//pc->UpdateActiveLightValue();
|
||||
|
||||
safe_delete_array(pcs);
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime)
|
||||
: Mob("Unnamed_Corpse", // const char* in_name,
|
||||
"", // const char* in_lastname,
|
||||
0, // int32 in_cur_hp,
|
||||
0, // int32 in_max_hp,
|
||||
in_npc->GetGender(), // uint8 in_gender,
|
||||
in_npc->GetRace(), // uint16 in_race,
|
||||
in_npc->GetClass(), // uint8 in_class,
|
||||
BT_Humanoid, // bodyType in_bodytype,
|
||||
in_npc->GetDeity(), // uint8 in_deity,
|
||||
in_npc->GetLevel(), // uint8 in_level,
|
||||
in_npc->GetNPCTypeID(), // uint32 in_npctype_id,
|
||||
in_npc->GetSize(), // float in_size,
|
||||
0, // float in_runspeed,
|
||||
in_npc->GetHeading(), // float in_heading,
|
||||
in_npc->GetX(), // float in_x_pos,
|
||||
in_npc->GetY(), // float in_y_pos,
|
||||
in_npc->GetZ(), // float in_z_pos,
|
||||
0, // uint8 in_light,
|
||||
in_npc->GetTexture(), // uint8 in_texture,
|
||||
in_npc->GetHelmTexture(), // uint8 in_helmtexture,
|
||||
0, // uint16 in_ac,
|
||||
0, // uint16 in_atk,
|
||||
0, // uint16 in_str,
|
||||
0, // uint16 in_sta,
|
||||
0, // uint16 in_dex,
|
||||
0, // uint16 in_agi,
|
||||
0, // uint16 in_int,
|
||||
0, // uint16 in_wis,
|
||||
0, // uint16 in_cha,
|
||||
0, // uint8 in_haircolor,
|
||||
0, // uint8 in_beardcolor,
|
||||
0, // uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye?
|
||||
0, // uint8 in_eyecolor2,
|
||||
0, // uint8 in_hairstyle,
|
||||
0, // uint8 in_luclinface,
|
||||
0, // uint8 in_beard,
|
||||
0, // uint32 in_drakkin_heritage,
|
||||
0, // uint32 in_drakkin_tattoo,
|
||||
0, // uint32 in_drakkin_details,
|
||||
0, // uint32 in_armor_tint[_MaterialCount],
|
||||
0xff, // uint8 in_aa_title,
|
||||
0, // uint8 in_see_invis, // see through invis/ivu
|
||||
0, // uint8 in_see_invis_undead,
|
||||
0, // uint8 in_see_hide,
|
||||
0, // uint8 in_see_improved_hide,
|
||||
0, // int32 in_hp_regen,
|
||||
0, // int32 in_mana_regen,
|
||||
0, // uint8 in_qglobal,
|
||||
0, // uint8 in_maxlevel,
|
||||
0 // uint32 in_scalerate
|
||||
),
|
||||
// vesuvias - appearence fix
|
||||
: Mob("Unnamed_Corpse","",0,0,in_npc->GetGender(),in_npc->GetRace(),in_npc->GetClass(),BT_Humanoid,//bodytype added
|
||||
in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0,
|
||||
in_npc->GetPosition(), in_npc->GetInnateLightValue(), in_npc->GetTexture(),in_npc->GetHelmTexture(),
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0xff,0,0,0,0,0,0,0,0,0),
|
||||
corpse_decay_timer(in_decaytime),
|
||||
corpse_rez_timer(0),
|
||||
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
|
||||
@@ -225,7 +182,7 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
|
||||
player_corpse_depop = false;
|
||||
strcpy(corpse_name, in_npc->GetName());
|
||||
strcpy(name, in_npc->GetName());
|
||||
|
||||
|
||||
for(int count = 0; count < 100; count++) {
|
||||
if ((level >= npcCorpseDecayTimes[count].minlvl) && (level <= npcCorpseDecayTimes[count].maxlvl)) {
|
||||
corpse_decay_timer.SetTimer(npcCorpseDecayTimes[count].seconds*1000);
|
||||
@@ -236,6 +193,7 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
|
||||
corpse_decay_timer.SetTimer(RuleI(NPC,EmptyNPCCorpseDecayTimeMS)+1000);
|
||||
}
|
||||
|
||||
|
||||
if(in_npc->HasPrivateCorpse()) {
|
||||
corpse_delay_timer.SetTimer(corpse_decay_timer.GetRemainingTime() + 1000);
|
||||
}
|
||||
@@ -244,6 +202,10 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
|
||||
allowed_looters[i] = 0;
|
||||
}
|
||||
this->rez_experience = 0;
|
||||
|
||||
UpdateEquipLightValue();
|
||||
spell_light = NOT_USED;
|
||||
UpdateActiveLightValue();
|
||||
}
|
||||
|
||||
Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
@@ -260,11 +222,8 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
0, // uint32 in_npctype_id,
|
||||
client->GetSize(), // float in_size,
|
||||
0, // float in_runspeed,
|
||||
client->GetHeading(), // float in_heading,
|
||||
client->GetX(), // float in_x_pos,
|
||||
client->GetY(), // float in_y_pos,
|
||||
client->GetZ(), // float in_z_pos,
|
||||
0, // uint8 in_light,
|
||||
client->GetPosition(),
|
||||
0, // uint8 in_light, - verified for client innate_light value
|
||||
client->GetTexture(), // uint8 in_texture,
|
||||
client->GetHelmTexture(), // uint8 in_helmtexture,
|
||||
0, // uint16 in_ac,
|
||||
@@ -297,15 +256,15 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
0, // uint8 in_qglobal,
|
||||
0, // uint8 in_maxlevel,
|
||||
0 // uint32 in_scalerate
|
||||
),
|
||||
),
|
||||
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
|
||||
corpse_rez_timer(RuleI(Character, CorpseResTimeMS)),
|
||||
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
|
||||
corpse_graveyard_timer(RuleI(Zone, GraveyardTimeMS)),
|
||||
loot_cooldown_timer(10)
|
||||
loot_cooldown_timer(10)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
PlayerProfile_Struct *pp = &client->GetPP();
|
||||
ItemInst *item;
|
||||
|
||||
@@ -335,7 +294,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
platinum = 0;
|
||||
|
||||
strcpy(corpse_name, pp->name);
|
||||
strcpy(name, pp->name);
|
||||
strcpy(name, pp->name);
|
||||
|
||||
/* become_npc was not being initialized which led to some pretty funky things with newly created corpses */
|
||||
become_npc = false;
|
||||
@@ -343,13 +302,13 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
SetPlayerKillItemID(0);
|
||||
|
||||
/* Check Rule to see if we can leave corpses */
|
||||
if(!RuleB(Character, LeaveNakedCorpses) ||
|
||||
RuleB(Character, LeaveCorpses) &&
|
||||
if(!RuleB(Character, LeaveNakedCorpses) ||
|
||||
RuleB(Character, LeaveCorpses) &&
|
||||
GetLevel() >= RuleI(Character, DeathItemLossLevel)) {
|
||||
// cash
|
||||
// Let's not move the cash when 'RespawnFromHover = true' && 'client->GetClientVersion() < EQClientSoF' since the client doesn't.
|
||||
// (change to first client that supports 'death hover' mode, if not SoF.)
|
||||
if (!RuleB(Character, RespawnFromHover) || client->GetClientVersion() < EQClientSoF) {
|
||||
if (!RuleB(Character, RespawnFromHover) || client->GetClientVersion() < ClientVersion::SoF) {
|
||||
SetCash(pp->copper, pp->silver, pp->gold, pp->platinum);
|
||||
pp->copper = 0;
|
||||
pp->silver = 0;
|
||||
@@ -360,48 +319,30 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
// get their tints
|
||||
memcpy(item_tint, &client->GetPP().item_tint, sizeof(item_tint));
|
||||
|
||||
// solar: TODO soulbound items need not be added to corpse, but they need
|
||||
// TODO soulbound items need not be added to corpse, but they need
|
||||
// to go into the regular slots on the player, out of bags
|
||||
|
||||
// worn + inventory + cursor
|
||||
std::list<uint32> removed_list;
|
||||
bool cursor = false;
|
||||
for(i = MAIN_BEGIN; i < EmuConstants::MAP_POSSESSIONS_SIZE; i++) {
|
||||
if(i == MainAmmo && client->GetClientVersion() >= EQClientSoF) {
|
||||
|
||||
for(i = MAIN_BEGIN; i < EmuConstants::MAP_POSSESSIONS_SIZE; ++i) {
|
||||
if(i == MainAmmo && client->GetClientVersion() >= ClientVersion::SoF) {
|
||||
item = client->GetInv().GetItem(MainPowerSource);
|
||||
if((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) {
|
||||
std::list<uint32> slot_list = MoveItemToCorpse(client, item, MainPowerSource);
|
||||
removed_list.merge(slot_list);
|
||||
if (item != nullptr) {
|
||||
if (!client->IsBecomeNPC() || (client->IsBecomeNPC() && !item->GetItem()->NoRent))
|
||||
MoveItemToCorpse(client, item, MainPowerSource, removed_list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
item = client->GetInv().GetItem(i);
|
||||
if((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) {
|
||||
std::list<uint32> slot_list = MoveItemToCorpse(client, item, i);
|
||||
removed_list.merge(slot_list);
|
||||
}
|
||||
}
|
||||
if (item == nullptr) { continue; }
|
||||
|
||||
// cursor queue // (change to first client that supports 'death hover' mode, if not SoF.)
|
||||
if (!RuleB(Character, RespawnFromHover) || client->GetClientVersion() < EQClientSoF) {
|
||||
|
||||
// bumped starting assignment to 8001 because any in-memory 'slot 8000' item was moved above as 'slot 30'
|
||||
// this was mainly for client profile state reflection..should match db player inventory entries now.
|
||||
|
||||
iter_queue it;
|
||||
for (it = client->GetInv().cursor_begin(), i = 8001; it != client->GetInv().cursor_end(); ++it, i++) {
|
||||
item = *it;
|
||||
if ((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) {
|
||||
std::list<uint32> slot_list = MoveItemToCorpse(client, item, i);
|
||||
removed_list.merge(slot_list);
|
||||
cursor = true;
|
||||
}
|
||||
}
|
||||
if(!client->IsBecomeNPC() || (client->IsBecomeNPC() && !item->GetItem()->NoRent))
|
||||
MoveItemToCorpse(client, item, i, removed_list);
|
||||
}
|
||||
|
||||
database.TransactionBegin();
|
||||
if (removed_list.size() != 0) {
|
||||
|
||||
// I have an untested process that avoids this snarl up when all possessions inventory is removed..but this isn't broke -U
|
||||
if (!removed_list.empty()) {
|
||||
std::stringstream ss("");
|
||||
ss << "DELETE FROM inventory WHERE charid=" << client->CharacterID();
|
||||
ss << " AND (";
|
||||
@@ -421,111 +362,127 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
database.QueryDatabase(ss.str().c_str());
|
||||
}
|
||||
|
||||
if (cursor) { // all cursor items should be on corpse (client < SoF or RespawnFromHover = false)
|
||||
while (!client->GetInv().CursorEmpty())
|
||||
client->DeleteItemInInventory(MainCursor, 0, false, false);
|
||||
}
|
||||
else { // only visible cursor made it to corpse (client >= Sof and RespawnFromHover = true)
|
||||
std::list<ItemInst*>::const_iterator start = client->GetInv().cursor_begin();
|
||||
std::list<ItemInst*>::const_iterator finish = client->GetInv().cursor_end();
|
||||
database.SaveCursor(client->CharacterID(), start, finish);
|
||||
}
|
||||
auto start = client->GetInv().cursor_begin();
|
||||
auto finish = client->GetInv().cursor_end();
|
||||
database.SaveCursor(client->CharacterID(), start, finish);
|
||||
|
||||
client->CalcBonuses(); // will only affect offline profile viewing of dead characters..unneeded overhead
|
||||
client->CalcBonuses();
|
||||
client->Save();
|
||||
|
||||
IsRezzed(false);
|
||||
Save();
|
||||
|
||||
database.TransactionCommit();
|
||||
|
||||
UpdateEquipLightValue();
|
||||
spell_light = NOT_USED;
|
||||
UpdateActiveLightValue();
|
||||
|
||||
return;
|
||||
} //end "not leaving naked corpses"
|
||||
|
||||
UpdateEquipLightValue();
|
||||
spell_light = NOT_USED;
|
||||
UpdateActiveLightValue();
|
||||
|
||||
IsRezzed(false);
|
||||
Save();
|
||||
}
|
||||
|
||||
std::list<uint32> Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16 equipslot)
|
||||
void Corpse::MoveItemToCorpse(Client *client, ItemInst *inst, int16 equipSlot, std::list<uint32> &removedList)
|
||||
{
|
||||
int bagindex;
|
||||
int16 interior_slot;
|
||||
ItemInst *interior_item;
|
||||
std::list<uint32> returnlist;
|
||||
AddItem(
|
||||
inst->GetItem()->ID,
|
||||
inst->GetCharges(),
|
||||
equipSlot,
|
||||
inst->GetAugmentItemID(0),
|
||||
inst->GetAugmentItemID(1),
|
||||
inst->GetAugmentItemID(2),
|
||||
inst->GetAugmentItemID(3),
|
||||
inst->GetAugmentItemID(4),
|
||||
inst->GetAugmentItemID(5),
|
||||
inst->IsAttuned()
|
||||
);
|
||||
removedList.push_back(equipSlot);
|
||||
|
||||
AddItem(item->GetItem()->ID, item->GetCharges(), equipslot, item->GetAugmentItemID(0), item->GetAugmentItemID(1), item->GetAugmentItemID(2), item->GetAugmentItemID(3), item->GetAugmentItemID(4), item->GetAugmentItemID(5), item->IsAttuned());
|
||||
returnlist.push_back(equipslot);
|
||||
while (true) {
|
||||
if (!inst->IsType(ItemClassContainer)) { break; }
|
||||
if (equipSlot < EmuConstants::GENERAL_BEGIN || equipSlot > MainCursor) { break; }
|
||||
|
||||
// Qualified bag slot iterations. processing bag slots that don't exist is probably not a good idea.
|
||||
if (item->IsType(ItemClassContainer) && ((equipslot >= EmuConstants::GENERAL_BEGIN && equipslot <= MainCursor))) {
|
||||
for (bagindex = SUB_BEGIN; bagindex <= EmuConstants::ITEM_CONTAINER_SIZE; bagindex++) {
|
||||
// For empty bags in cursor queue, slot was previously being resolved as SLOT_INVALID (-1)
|
||||
interior_slot = Inventory::CalcSlotId(equipslot, bagindex);
|
||||
interior_item = client->GetInv().GetItem(interior_slot);
|
||||
for (auto sub_index = SUB_BEGIN; sub_index < EmuConstants::ITEM_CONTAINER_SIZE; ++sub_index) {
|
||||
int16 real_bag_slot = Inventory::CalcSlotId(equipSlot, sub_index);
|
||||
auto bag_inst = client->GetInv().GetItem(real_bag_slot);
|
||||
if (bag_inst == nullptr) { continue; }
|
||||
|
||||
if (interior_item) {
|
||||
AddItem(interior_item->GetItem()->ID, interior_item->GetCharges(), interior_slot, interior_item->GetAugmentItemID(0), interior_item->GetAugmentItemID(1), interior_item->GetAugmentItemID(2), interior_item->GetAugmentItemID(3), interior_item->GetAugmentItemID(4), interior_item->GetAugmentItemID(5), item->IsAttuned());
|
||||
returnlist.push_back(Inventory::CalcSlotId(equipslot, bagindex));
|
||||
client->DeleteItemInInventory(interior_slot, 0, true, false);
|
||||
}
|
||||
AddItem(
|
||||
bag_inst->GetItem()->ID,
|
||||
bag_inst->GetCharges(),
|
||||
real_bag_slot,
|
||||
bag_inst->GetAugmentItemID(0),
|
||||
bag_inst->GetAugmentItemID(1),
|
||||
bag_inst->GetAugmentItemID(2),
|
||||
bag_inst->GetAugmentItemID(3),
|
||||
bag_inst->GetAugmentItemID(4),
|
||||
bag_inst->GetAugmentItemID(5),
|
||||
bag_inst->IsAttuned()
|
||||
);
|
||||
removedList.push_back(real_bag_slot);
|
||||
client->DeleteItemInInventory(real_bag_slot, 0, true, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
client->DeleteItemInInventory(equipslot, 0, true, false);
|
||||
return returnlist;
|
||||
client->DeleteItemInInventory(equipSlot, 0, true, false);
|
||||
}
|
||||
|
||||
/* Called from Database Load */
|
||||
|
||||
Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, float in_x, float in_y, float in_z, float in_heading, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture,uint32 in_rezexp, bool wasAtGraveyard)
|
||||
: Mob("Unnamed_Corpse", // const char* in_name,
|
||||
"", // const char* in_lastname,
|
||||
0, // int32 in_cur_hp,
|
||||
0, // int32 in_max_hp,
|
||||
in_gender, // uint8 in_gender,
|
||||
in_race, // uint16 in_race,
|
||||
in_class, // uint8 in_class,
|
||||
BT_Humanoid, // bodyType in_bodytype,
|
||||
in_deity, // uint8 in_deity,
|
||||
in_level, // uint8 in_level,
|
||||
0, // uint32 in_npctype_id,
|
||||
in_size, // float in_size,
|
||||
0, // float in_runspeed,
|
||||
in_heading, // float in_heading,
|
||||
in_x, // float in_x_pos,
|
||||
in_y, // float in_y_pos,
|
||||
in_z, // float in_z_pos,
|
||||
0, // uint8 in_light,
|
||||
in_texture, // uint8 in_texture,
|
||||
in_helmtexture, // uint8 in_helmtexture,
|
||||
0, // uint16 in_ac,
|
||||
0, // uint16 in_atk,
|
||||
0, // uint16 in_str,
|
||||
0, // uint16 in_sta,
|
||||
0, // uint16 in_dex,
|
||||
0, // uint16 in_agi,
|
||||
0, // uint16 in_int,
|
||||
0, // uint16 in_wis,
|
||||
0, // uint16 in_cha,
|
||||
0, // uint8 in_haircolor,
|
||||
0, // uint8 in_beardcolor,
|
||||
0, // uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye?
|
||||
0, // uint8 in_eyecolor2,
|
||||
0, // uint8 in_hairstyle,
|
||||
0, // uint8 in_luclinface,
|
||||
0, // uint8 in_beard,
|
||||
0, // uint32 in_drakkin_heritage,
|
||||
0, // uint32 in_drakkin_tattoo,
|
||||
0, // uint32 in_drakkin_details,
|
||||
0, // uint32 in_armor_tint[_MaterialCount],
|
||||
0xff, // uint8 in_aa_title,
|
||||
0, // uint8 in_see_invis, // see through invis/ivu
|
||||
0, // uint8 in_see_invis_undead,
|
||||
0, // uint8 in_see_hide,
|
||||
0, // uint8 in_see_improved_hide,
|
||||
0, // int32 in_hp_regen,
|
||||
0, // int32 in_mana_regen,
|
||||
0, // uint8 in_qglobal,
|
||||
0, // uint8 in_maxlevel,
|
||||
0), // uint32 in_scalerate
|
||||
// To be called from LoadFromDBData
|
||||
Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, const glm::vec4& position, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture,uint32 in_rezexp, bool wasAtGraveyard)
|
||||
: Mob("Unnamed_Corpse",
|
||||
"",
|
||||
0,
|
||||
0,
|
||||
in_gender,
|
||||
in_race,
|
||||
in_class,
|
||||
BT_Humanoid,
|
||||
in_deity,
|
||||
in_level,
|
||||
0,
|
||||
in_size,
|
||||
0,
|
||||
position,
|
||||
0, // verified for client innate_light value
|
||||
in_texture,
|
||||
in_helmtexture,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0xff,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0),
|
||||
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
|
||||
corpse_rez_timer(RuleI(Character, CorpseResTimeMS)),
|
||||
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
|
||||
@@ -535,9 +492,8 @@ Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemLi
|
||||
|
||||
LoadPlayerCorpseDecayTime(in_dbid);
|
||||
|
||||
if (!zone->HasGraveyard() || wasAtGraveyard){
|
||||
if (!zone->HasGraveyard() || wasAtGraveyard)
|
||||
corpse_graveyard_timer.Disable();
|
||||
}
|
||||
|
||||
memset(item_tint, 0, sizeof(item_tint));
|
||||
|
||||
@@ -565,6 +521,10 @@ Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemLi
|
||||
allowed_looters[i] = 0;
|
||||
}
|
||||
SetPlayerKillItemID(0);
|
||||
|
||||
UpdateEquipLightValue();
|
||||
spell_light = NOT_USED;
|
||||
UpdateActiveLightValue();
|
||||
}
|
||||
|
||||
Corpse::~Corpse() {
|
||||
@@ -640,18 +600,18 @@ bool Corpse::Save() {
|
||||
ItemList::iterator cur, end;
|
||||
cur = itemlist.begin();
|
||||
end = itemlist.end();
|
||||
for (; cur != end; ++cur) {
|
||||
for (; cur != end; ++cur) {
|
||||
ServerLootItem_Struct* item = *cur;
|
||||
memcpy((char*)&dbpc->items[x++], (char*)item, sizeof(ServerLootItem_Struct));
|
||||
}
|
||||
|
||||
/* Create New Corpse*/
|
||||
if (corpse_db_id == 0) {
|
||||
corpse_db_id = database.SaveCharacterCorpse(char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading);
|
||||
corpse_db_id = database.SaveCharacterCorpse(char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, m_Position);
|
||||
}
|
||||
/* Update Corpse Data */
|
||||
else{
|
||||
corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading, IsRezzed());
|
||||
corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, m_Position, IsRezzed());
|
||||
}
|
||||
|
||||
safe_delete_array(dbpc);
|
||||
@@ -661,16 +621,15 @@ bool Corpse::Save() {
|
||||
|
||||
void Corpse::Delete() {
|
||||
if (IsPlayerCorpse() && corpse_db_id != 0)
|
||||
database.DeleteCharacterCorpse(corpse_db_id);
|
||||
|
||||
database.DeleteCharacterCorpse(corpse_db_id);
|
||||
|
||||
corpse_db_id = 0;
|
||||
player_corpse_depop = true;
|
||||
}
|
||||
|
||||
void Corpse::Bury() {
|
||||
if (IsPlayerCorpse() && corpse_db_id != 0){
|
||||
if (IsPlayerCorpse() && corpse_db_id != 0)
|
||||
database.BuryCharacterCorpse(corpse_db_id);
|
||||
}
|
||||
corpse_db_id = 0;
|
||||
player_corpse_depop = true;
|
||||
}
|
||||
@@ -702,7 +661,7 @@ void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, ui
|
||||
is_corpse_changed = true;
|
||||
|
||||
ServerLootItem_Struct* item = new ServerLootItem_Struct;
|
||||
|
||||
|
||||
memset(item, 0, sizeof(ServerLootItem_Struct));
|
||||
item->item_id = itemnum;
|
||||
item->charges = charges;
|
||||
@@ -715,6 +674,8 @@ void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, ui
|
||||
item->aug_6=aug6;
|
||||
item->attuned=attuned;
|
||||
itemlist.push_back(item);
|
||||
|
||||
UpdateEquipLightValue();
|
||||
}
|
||||
|
||||
ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data) {
|
||||
@@ -776,25 +737,25 @@ void Corpse::RemoveItem(uint16 lootslot) {
|
||||
}
|
||||
}
|
||||
|
||||
void Corpse::RemoveItem(ServerLootItem_Struct* item_data){
|
||||
uint8 material;
|
||||
ItemList::iterator cur,end;
|
||||
cur = itemlist.begin();
|
||||
end = itemlist.end();
|
||||
for(; cur != end; ++cur) {
|
||||
ServerLootItem_Struct* sitem = *cur;
|
||||
if (sitem == item_data) {
|
||||
is_corpse_changed = true;
|
||||
itemlist.erase(cur);
|
||||
void Corpse::RemoveItem(ServerLootItem_Struct* item_data)
|
||||
{
|
||||
for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
|
||||
auto sitem = *iter;
|
||||
if (sitem != item_data) { continue; }
|
||||
|
||||
material = Inventory::CalcMaterialFromSlot(sitem->equip_slot);
|
||||
if(material != _MaterialInvalid)
|
||||
SendWearChange(material);
|
||||
is_corpse_changed = true;
|
||||
itemlist.erase(iter);
|
||||
|
||||
safe_delete(sitem);
|
||||
uint8 material = Inventory::CalcMaterialFromSlot(sitem->equip_slot); // autos to unsigned char
|
||||
if (material != _MaterialInvalid)
|
||||
SendWearChange(material);
|
||||
|
||||
return;
|
||||
}
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
|
||||
safe_delete(sitem);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -818,18 +779,16 @@ bool Corpse::IsEmpty() const {
|
||||
if (copper != 0 || silver != 0 || gold != 0 || platinum != 0)
|
||||
return false;
|
||||
|
||||
return(itemlist.size() == 0);
|
||||
return itemlist.empty();
|
||||
}
|
||||
|
||||
bool Corpse::Process() {
|
||||
if (player_corpse_depop){
|
||||
if (player_corpse_depop)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (corpse_delay_timer.Check()) {
|
||||
for (int i = 0; i < MAX_LOOTERS; i++){
|
||||
for (int i = 0; i < MAX_LOOTERS; i++)
|
||||
allowed_looters[i] = 0;
|
||||
}
|
||||
corpse_delay_timer.Disable();
|
||||
return true;
|
||||
}
|
||||
@@ -839,8 +798,7 @@ bool Corpse::Process() {
|
||||
Save();
|
||||
player_corpse_depop = true;
|
||||
database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(),
|
||||
(zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->graveyard_x(),
|
||||
zone->graveyard_y(), zone->graveyard_z(), zone->graveyard_heading());
|
||||
(zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->GetGraveyardPoint());
|
||||
corpse_graveyard_timer.Disable();
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct));
|
||||
SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer;
|
||||
@@ -848,7 +806,7 @@ bool Corpse::Process() {
|
||||
spc->zone_id = zone->graveyard_zoneid();
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
LogFile->write(EQEMuLog::Debug, "Moved %s player corpse to the designated graveyard in zone %s.", this->GetName(), database.GetZoneName(zone->graveyard_zoneid()));
|
||||
Log.Out(Logs::General, Logs::None, "Moved %s player corpse to the designated graveyard in zone %s.", this->GetName(), database.GetZoneName(zone->graveyard_zoneid()));
|
||||
corpse_db_id = 0;
|
||||
}
|
||||
|
||||
@@ -878,10 +836,10 @@ bool Corpse::Process() {
|
||||
Save();
|
||||
player_corpse_depop = true;
|
||||
corpse_db_id = 0;
|
||||
LogFile->write(EQEMuLog::Debug, "Tagged %s player corpse has burried.", this->GetName());
|
||||
Log.Out(Logs::General, Logs::None, "Tagged %s player corpse has burried.", this->GetName());
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to bury %s player corpse.", this->GetName());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to bury %s player corpse.", this->GetName());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -906,15 +864,11 @@ bool Corpse::CanPlayerLoot(int charid) {
|
||||
looters++;
|
||||
}
|
||||
|
||||
if (allowed_looters[i] == charid){
|
||||
if (allowed_looters[i] == charid)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/* If we have no looters, obviously client can loot */
|
||||
if (looters == 0){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return looters == 0;
|
||||
}
|
||||
|
||||
void Corpse::AllowPlayerLoot(Mob *them, uint8 slot) {
|
||||
@@ -947,21 +901,20 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
return;
|
||||
}
|
||||
|
||||
if(being_looted_by == 0) {
|
||||
being_looted_by = 0xFFFFFFFF;
|
||||
}
|
||||
if(being_looted_by == 0)
|
||||
being_looted_by = 0xFFFFFFFF;
|
||||
|
||||
if(this->being_looted_by != 0xFFFFFFFF) {
|
||||
// lets double check....
|
||||
Entity* looter = entity_list.GetID(this->being_looted_by);
|
||||
if(looter == 0) {
|
||||
this->being_looted_by = 0xFFFFFFFF;
|
||||
}
|
||||
if(looter == 0)
|
||||
this->being_looted_by = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
uint8 Loot_Request_Type = 1;
|
||||
bool loot_coin = false;
|
||||
if(database.GetVariable("LootCoin", tmp, 9)) { loot_coin = (atoi(tmp) == 1); }
|
||||
if(database.GetVariable("LootCoin", tmp, 9))
|
||||
loot_coin = (atoi(tmp) == 1);
|
||||
|
||||
if (this->being_looted_by != 0xFFFFFFFF && this->being_looted_by != client->GetID()) {
|
||||
SendLootReqErrorPacket(client, 0);
|
||||
@@ -999,7 +952,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
d->unknown2 = 0xef;
|
||||
|
||||
/* Dont take the coin off if it's a gm peeking at the corpse */
|
||||
if(Loot_Request_Type == 2 || (Loot_Request_Type >= 3 && loot_coin)) {
|
||||
if(Loot_Request_Type == 2 || (Loot_Request_Type >= 3 && loot_coin)) {
|
||||
if(!IsPlayerCorpse() && client->IsGrouped() && client->AutoSplitEnabled() && client->GetGroup()) {
|
||||
d->copper = 0;
|
||||
d->silver = 0;
|
||||
@@ -1017,9 +970,10 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
}
|
||||
|
||||
RemoveCash();
|
||||
Save();
|
||||
Save();
|
||||
}
|
||||
|
||||
auto timestamps = database.GetItemRecastTimestamps(client->CharacterID());
|
||||
outapp->priority = 6;
|
||||
client->QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
@@ -1028,6 +982,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
const Item_Struct* item = database.GetItem(pkitem);
|
||||
ItemInst* inst = database.CreateItem(item, item->MaxCharges);
|
||||
if(inst) {
|
||||
if (item->RecastDelay)
|
||||
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||
client->SendItemPacket(EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
|
||||
safe_delete(inst);
|
||||
}
|
||||
@@ -1059,6 +1015,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
if(client && item) {
|
||||
ItemInst* inst = database.CreateItem(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
|
||||
if(inst) {
|
||||
if (item->RecastDelay)
|
||||
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||
// MainGeneral1 is the corpse inventory start offset for Ti(EMu) - CORPSE_END = MainGeneral1 + MainCursor
|
||||
client->SendItemPacket(i + EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
|
||||
safe_delete(inst);
|
||||
@@ -1089,7 +1047,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
for(; cur != end; ++cur) {
|
||||
ServerLootItem_Struct* item_data = *cur;
|
||||
item = database.GetItem(item_data->item_id);
|
||||
LogFile->write(EQEMuLog::Debug, "Corpse Looting: %s was not sent to client loot window (corpse_dbid: %i, charname: %s(%s))", item->Name, GetCorpseDBID(), client->GetName(), client->GetGM() ? "GM" : "Owner");
|
||||
Log.Out(Logs::General, Logs::None, "Corpse Looting: %s was not sent to client loot window (corpse_dbid: %i, charname: %s(%s))", item->Name, GetCorpseDBID(), client->GetName(), client->GetGM() ? "GM" : "Owner");
|
||||
client->Message(0, "Inaccessable Corpse Item: %s", item->Name);
|
||||
}
|
||||
}
|
||||
@@ -1101,7 +1059,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
|
||||
// This is required for the 'Loot All' feature to work for SoD clients. I expect it is to tell the client that the
|
||||
// server has now sent all the items on the corpse.
|
||||
if(client->GetClientVersion() >= EQClientSoD) { SendLootReqErrorPacket(client, 6); }
|
||||
if(client->GetClientVersion() >= ClientVersion::SoD) { SendLootReqErrorPacket(client, 6); }
|
||||
}
|
||||
|
||||
void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
@@ -1246,7 +1204,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
/* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */
|
||||
database.DeleteItemOffCharacterCorpse(this->corpse_db_id, item_data->equip_slot, item_data->item_id);
|
||||
/* Delete Item Instance */
|
||||
RemoveItem(item_data->lootslot);
|
||||
RemoveItem(item_data->lootslot);
|
||||
}
|
||||
|
||||
/* Remove Bag Contents */
|
||||
@@ -1254,9 +1212,9 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
for (int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) {
|
||||
if (bag_item_data[i]) {
|
||||
/* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */
|
||||
database.DeleteItemOffCharacterCorpse(this->corpse_db_id, bag_item_data[i]->equip_slot, bag_item_data[i]->item_id);
|
||||
database.DeleteItemOffCharacterCorpse(this->corpse_db_id, bag_item_data[i]->equip_slot, bag_item_data[i]->item_id);
|
||||
/* Delete Item Instance */
|
||||
RemoveItem(bag_item_data[i]);
|
||||
RemoveItem(bag_item_data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1265,23 +1223,16 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
SetPlayerKillItemID(0);
|
||||
}
|
||||
|
||||
/* Send message with item link to groups and such */
|
||||
Client::TextLink linker;
|
||||
linker.SetLinkType(linker.linkItemInst);
|
||||
linker.SetItemInst(inst);
|
||||
linker.SetClientVersion(client->GetClientVersion());
|
||||
/* Send message with item link to groups and such */
|
||||
Client::TextLink linker;
|
||||
linker.SetLinkType(linker.linkItemInst);
|
||||
linker.SetItemInst(inst);
|
||||
|
||||
auto item_link = linker.GenerateLink();
|
||||
|
||||
client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, item_link.c_str());
|
||||
|
||||
if(!IsPlayerCorpse()) {
|
||||
// When sending to multiple/unknown client types, we set for the highest client..
|
||||
// ..which is processed when 'EQClientUnknown,' or default value, is selected.
|
||||
// This should help with any current issues..or it may create more! O.o
|
||||
linker.SetClientVersion(EQClientUnknown);
|
||||
item_link = linker.GenerateLink();
|
||||
|
||||
if (!IsPlayerCorpse()) {
|
||||
Group *g = client->GetGroup();
|
||||
if(g != nullptr) {
|
||||
g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
|
||||
@@ -1333,9 +1284,12 @@ void Corpse::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
||||
ns->spawn.NPC = 3;
|
||||
else
|
||||
ns->spawn.NPC = 2;
|
||||
|
||||
UpdateActiveLightValue();
|
||||
ns->spawn.light = active_light;
|
||||
}
|
||||
|
||||
void Corpse::QueryLoot(Client* to) {
|
||||
void Corpse::QueryLoot(Client* to) {
|
||||
int x = 0, y = 0; // x = visible items, y = total items
|
||||
to->Message(0, "Coin: %ip, %ig, %is, %ic", platinum, gold, silver, copper);
|
||||
|
||||
@@ -1395,7 +1349,7 @@ bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) {
|
||||
client->Message(13, "That corpse is locked by a GM.");
|
||||
return false;
|
||||
}
|
||||
if (!CheckDistance || (DistNoRootNoZ(*client) <= dist2)) {
|
||||
if (!CheckDistance || (DistanceSquaredNoZ(m_Position, client->GetPosition()) <= dist2)) {
|
||||
GMMove(client->GetX(), client->GetY(), client->GetZ());
|
||||
is_corpse_changed = true;
|
||||
}
|
||||
@@ -1410,7 +1364,7 @@ bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) {
|
||||
std::list<std::string>::iterator itr;
|
||||
for(itr = client->consent_list.begin(); itr != client->consent_list.end(); ++itr) {
|
||||
if(strcmp(this->GetOwnerName(), itr->c_str()) == 0) {
|
||||
if (!CheckDistance || (DistNoRootNoZ(*client) <= dist2)) {
|
||||
if (!CheckDistance || (DistanceSquaredNoZ(m_Position, client->GetPosition()) <= dist2)) {
|
||||
GMMove(client->GetX(), client->GetY(), client->GetZ());
|
||||
is_corpse_changed = true;
|
||||
}
|
||||
@@ -1479,6 +1433,20 @@ uint32 Corpse::GetEquipmentColor(uint8 material_slot) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Corpse::UpdateEquipLightValue()
|
||||
{
|
||||
equip_light = NOT_USED;
|
||||
|
||||
for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
|
||||
if (((*iter)->equip_slot < EmuConstants::EQUIPMENT_BEGIN || (*iter)->equip_slot > EmuConstants::GENERAL_END) && (*iter)->equip_slot != MainPowerSource) { continue; }
|
||||
auto item = database.GetItem((*iter)->item_id);
|
||||
if (item == nullptr) { continue; }
|
||||
if (item->ItemType != ItemTypeMisc && item->ItemType != ItemTypeLight) { continue; }
|
||||
if (item->Light & 0xF0) { continue; }
|
||||
if (item->Light > equip_light) { equip_light = item->Light; }
|
||||
}
|
||||
}
|
||||
|
||||
void Corpse::AddLooter(Mob* who) {
|
||||
for (int i = 0; i < MAX_LOOTERS; i++) {
|
||||
if (allowed_looters[i] == 0) {
|
||||
|
||||
+17
-18
@@ -37,22 +37,19 @@ class Corpse : public Mob {
|
||||
public:
|
||||
|
||||
static void SendEndLootErrorPacket(Client* client);
|
||||
static void SendLootReqErrorPacket(Client* client, uint8 response = 2);
|
||||
|
||||
static void SendLootReqErrorPacket(Client* client, uint8 response = 2);
|
||||
|
||||
Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime = 600000);
|
||||
Corpse(Client* client, int32 in_rezexp);
|
||||
Corpse(uint32 in_corpseid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, float in_x, float in_y, float in_z, float in_heading, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture, uint32 in_rezexp, bool wasAtGraveyard = false);
|
||||
|
||||
~Corpse();
|
||||
static Corpse* LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, float in_x, float in_y, float in_z, float in_heading, std::string time_of_death, bool rezzed, bool was_at_graveyard);
|
||||
Corpse(uint32 in_corpseid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, const glm::vec4& position, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture, uint32 in_rezexp, bool wasAtGraveyard = false);
|
||||
|
||||
~Corpse();
|
||||
static Corpse* LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const glm::vec4& position, std::string time_of_death, bool rezzed, bool was_at_graveyard);
|
||||
|
||||
/* Corpse: General */
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; }
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) { return; }
|
||||
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false,
|
||||
bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) {
|
||||
return false;
|
||||
}
|
||||
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; }
|
||||
virtual bool HasRaid() { return false; }
|
||||
virtual bool HasGroup() { return false; }
|
||||
virtual Raid* GetRaid() { return 0; }
|
||||
@@ -73,7 +70,7 @@ class Corpse : public Mob {
|
||||
uint32 GetDecayTime() { if (!corpse_decay_timer.Enabled()) return 0xFFFFFFFF; else return corpse_decay_timer.GetRemainingTime(); }
|
||||
uint32 GetRezTime() { if (!corpse_rez_timer.Enabled()) return 0; else return corpse_rez_timer.GetRemainingTime(); }
|
||||
void SetDecayTimer(uint32 decay_time);
|
||||
|
||||
|
||||
void Delete();
|
||||
void Bury();
|
||||
void CalcCorpseName();
|
||||
@@ -81,9 +78,9 @@ class Corpse : public Mob {
|
||||
|
||||
/* Corpse: Items */
|
||||
uint32 GetWornItem(int16 equipSlot) const;
|
||||
ServerLootItem_Struct* GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data = 0);
|
||||
ServerLootItem_Struct* GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data = 0);
|
||||
void SetPlayerKillItemID(int32 pk_item_id) { player_kill_item = pk_item_id; }
|
||||
int32 GetPlayerKillItem() { return player_kill_item; }
|
||||
int32 GetPlayerKillItem() { return player_kill_item; }
|
||||
void RemoveItem(uint16 lootslot);
|
||||
void RemoveItem(ServerLootItem_Struct* item_data);
|
||||
void AddItem(uint32 itemnum, uint16 charges, int16 slot = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
|
||||
@@ -123,13 +120,15 @@ class Corpse : public Mob {
|
||||
bool Summon(Client* client, bool spell, bool CheckDistance);
|
||||
void Spawn();
|
||||
|
||||
char corpse_name[64];
|
||||
char corpse_name[64];
|
||||
uint32 GetEquipment(uint8 material_slot) const;
|
||||
uint32 GetEquipmentColor(uint8 material_slot) const;
|
||||
inline int GetRezExp() { return rez_experience; }
|
||||
inline int GetRezExp() { return rez_experience; }
|
||||
|
||||
virtual void UpdateEquipLightValue();
|
||||
|
||||
protected:
|
||||
std::list<uint32> MoveItemToCorpse(Client *client, ItemInst *item, int16 equipslot);
|
||||
void MoveItemToCorpse(Client *client, ItemInst *inst, int16 equipSlot, std::list<uint32> &removedList);
|
||||
|
||||
private:
|
||||
bool is_player_corpse; /* Determines if Player Corpse or not */
|
||||
@@ -139,7 +138,7 @@ private:
|
||||
uint32 corpse_db_id; /* Corpse Database ID (Player Corpse) */
|
||||
uint32 char_id; /* Character ID */
|
||||
ItemList itemlist; /* Internal Item list used for corpses */
|
||||
uint32 copper;
|
||||
uint32 copper;
|
||||
uint32 silver;
|
||||
uint32 gold;
|
||||
uint32 platinum;
|
||||
@@ -152,7 +151,7 @@ private:
|
||||
int allowed_looters[MAX_LOOTERS]; /* People allowed to loot the corpse, character id */
|
||||
Timer corpse_decay_timer; /* The amount of time in millseconds in which a corpse will take to decay (Depop/Poof) */
|
||||
Timer corpse_rez_timer; /* The amount of time in millseconds in which a corpse can be rezzed */
|
||||
Timer corpse_delay_timer;
|
||||
Timer corpse_delay_timer;
|
||||
Timer corpse_graveyard_timer;
|
||||
Timer loot_cooldown_timer; /* Delay between loot actions on the corpse entity */
|
||||
Color_Struct item_tint[9];
|
||||
|
||||
+32
-66
@@ -16,7 +16,8 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/string_util.h"
|
||||
|
||||
#include "client.h"
|
||||
@@ -39,17 +40,15 @@
|
||||
extern EntityList entity_list;
|
||||
extern WorldServer worldserver;
|
||||
|
||||
Doors::Doors(const Door* door)
|
||||
: close_timer(5000)
|
||||
Doors::Doors(const Door* door) :
|
||||
close_timer(5000),
|
||||
m_Position(door->pos_x, door->pos_y, door->pos_z, door->heading),
|
||||
m_Destination(door->dest_x, door->dest_y, door->dest_z, door->dest_heading)
|
||||
{
|
||||
db_id = door->db_id;
|
||||
door_id = door->door_id;
|
||||
strn0cpy(zone_name,door->zone_name,32);
|
||||
strn0cpy(door_name,door->door_name,32);
|
||||
pos_x = door->pos_x;
|
||||
pos_y = door->pos_y;
|
||||
pos_z = door->pos_z;
|
||||
heading = door->heading;
|
||||
incline = door->incline;
|
||||
opentype = door->opentype;
|
||||
guild_id = door->guild_id;
|
||||
@@ -66,28 +65,22 @@ Doors::Doors(const Door* door)
|
||||
|
||||
close_timer.Disable();
|
||||
|
||||
strn0cpy(dest_zone,door->dest_zone,32);
|
||||
strn0cpy(dest_zone,door->dest_zone,16);
|
||||
dest_instance_id = door->dest_instance_id;
|
||||
dest_x = door->dest_x;
|
||||
dest_y = door->dest_y;
|
||||
dest_z = door->dest_z;
|
||||
dest_heading = door->dest_heading;
|
||||
|
||||
is_ldon_door = door->is_ldon_door;
|
||||
client_version_mask = door->client_version_mask;
|
||||
}
|
||||
|
||||
Doors::Doors(const char *dmodel, float dx, float dy, float dz, float dheading, uint8 dopentype, uint16 dsize)
|
||||
: close_timer(5000)
|
||||
Doors::Doors(const char *dmodel, const glm::vec4& position, uint8 dopentype, uint16 dsize) :
|
||||
close_timer(5000),
|
||||
m_Position(position),
|
||||
m_Destination(glm::vec4())
|
||||
{
|
||||
db_id = database.GetDoorsCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion());
|
||||
door_id = database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion());
|
||||
strn0cpy(zone_name,zone->GetShortName(),32);
|
||||
strn0cpy(door_name,dmodel,32);
|
||||
pos_x = dx;
|
||||
pos_y = dy;
|
||||
pos_z = dz;
|
||||
heading = dheading;
|
||||
incline = 0;
|
||||
opentype = dopentype;
|
||||
guild_id = 0;
|
||||
@@ -106,10 +99,6 @@ Doors::Doors(const char *dmodel, float dx, float dy, float dz, float dheading, u
|
||||
|
||||
strn0cpy(dest_zone,"NONE",32);
|
||||
dest_instance_id = 0;
|
||||
dest_x = 0;
|
||||
dest_y = 0;
|
||||
dest_z = 0;
|
||||
dest_heading = 0;
|
||||
|
||||
is_ldon_door = 0;
|
||||
client_version_mask = 4294967295u;
|
||||
@@ -144,9 +133,9 @@ bool Doors::Process()
|
||||
void Doors::HandleClick(Client* sender, uint8 trigger)
|
||||
{
|
||||
//door debugging info dump
|
||||
_log(DOORS__INFO, "%s clicked door %s (dbid %d, eqid %d) at (%.4f,%.4f,%.4f @%.4f)", sender->GetName(), door_name, db_id, door_id, pos_x, pos_y, pos_z, heading);
|
||||
_log(DOORS__INFO, " incline %d, opentype %d, lockpick %d, key %d, nokeyring %d, trigger %d type %d, param %d", incline, opentype, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param);
|
||||
_log(DOORS__INFO, " size %d, invert %d, dest: %s (%.4f,%.4f,%.4f @%.4f)", size, invert_state, dest_zone, dest_x, dest_y, dest_z, dest_heading);
|
||||
Log.Out(Logs::Detail, Logs::Doors, "%s clicked door %s (dbid %d, eqid %d) at %s", sender->GetName(), door_name, db_id, door_id, to_string(m_Position).c_str());
|
||||
Log.Out(Logs::Detail, Logs::Doors, " incline %d, opentype %d, lockpick %d, key %d, nokeyring %d, trigger %d type %d, param %d", incline, opentype, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param);
|
||||
Log.Out(Logs::Detail, Logs::Doors, " size %d, invert %d, dest: %s %s", size, invert_state, dest_zone, to_string(m_Destination).c_str());
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer;
|
||||
@@ -301,9 +290,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
|
||||
float modskill=sender->GetSkill(SkillPickLock);
|
||||
sender->CheckIncreaseSkill(SkillPickLock, nullptr, 1);
|
||||
|
||||
#if EQDEBUG>=5
|
||||
LogFile->write(EQEMuLog::Debug, "Client has lockpicks: skill=%f", modskill);
|
||||
#endif
|
||||
Log.Out(Logs::General, Logs::Skills, "Client has lockpicks: skill=%f", modskill);
|
||||
|
||||
if(GetLockpick() <= modskill)
|
||||
{
|
||||
@@ -422,7 +409,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
|
||||
{
|
||||
sender->KeyRingAdd(playerkey);
|
||||
}
|
||||
sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading);
|
||||
sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w);
|
||||
}
|
||||
else if (( !IsDoorOpen() || opentype == 58 ) && (keyneeded && ((keyneeded == playerkey) || sender->GetGM())))
|
||||
{
|
||||
@@ -432,22 +419,22 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
|
||||
}
|
||||
if(database.GetZoneID(dest_zone) == zone->GetZoneID())
|
||||
{
|
||||
sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading);
|
||||
sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w);
|
||||
}
|
||||
else
|
||||
{
|
||||
sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, dest_x, dest_y, dest_z, dest_heading);
|
||||
sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w);
|
||||
}
|
||||
}
|
||||
if (( !IsDoorOpen() || opentype == 58 ) && (!keyneeded))
|
||||
{
|
||||
if(database.GetZoneID(dest_zone) == zone->GetZoneID())
|
||||
{
|
||||
sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading);
|
||||
sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w);
|
||||
}
|
||||
else
|
||||
{
|
||||
sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, dest_x, dest_y, dest_z, dest_heading);
|
||||
sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -559,15 +546,15 @@ void Doors::ToggleState(Mob *sender)
|
||||
}
|
||||
|
||||
void Doors::DumpDoor(){
|
||||
LogFile->write(EQEMuLog::Debug,
|
||||
"db_id:%i door_id:%i zone_name:%s door_name:%s pos_x:%f pos_y:%f pos_z:%f heading:%f",
|
||||
db_id, door_id, zone_name, door_name, pos_x, pos_y, pos_z, heading);
|
||||
LogFile->write(EQEMuLog::Debug,
|
||||
Log.Out(Logs::General, Logs::None,
|
||||
"db_id:%i door_id:%i zone_name:%s door_name:%s %s",
|
||||
db_id, door_id, zone_name, door_name, to_string(m_Position).c_str());
|
||||
Log.Out(Logs::General, Logs::None,
|
||||
"opentype:%i guild_id:%i lockpick:%i keyitem:%i nokeyring:%i trigger_door:%i trigger_type:%i door_param:%i open:%s",
|
||||
opentype, guild_id, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param, (isopen) ? "open":"closed");
|
||||
LogFile->write(EQEMuLog::Debug,
|
||||
"dest_zone:%s dest_x:%f dest_y:%f dest_z:%f dest_heading:%f",
|
||||
dest_zone, dest_x, dest_y, dest_z, dest_heading);
|
||||
Log.Out(Logs::General, Logs::None,
|
||||
"dest_zone:%s destination:%s ",
|
||||
dest_zone, to_string(m_Destination).c_str());
|
||||
}
|
||||
|
||||
int32 ZoneDatabase::GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version) {
|
||||
@@ -577,7 +564,6 @@ int32 ZoneDatabase::GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 v
|
||||
zone_name, version);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
std::cerr << "Error in GetDoorsCount query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -604,7 +590,6 @@ int32 ZoneDatabase::GetDoorsCountPlusOne(const char *zone_name, int16 version) {
|
||||
"WHERE zone = '%s' AND version = %u", zone_name, version);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
std::cerr << "Error in GetDoorsCountPlusOne query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -628,7 +613,6 @@ int32 ZoneDatabase::GetDoorsDBCountPlusOne(const char *zone_name, int16 version)
|
||||
zone_name, version);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
std::cerr << "Error in GetDoorsCountPlusOne query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -644,7 +628,7 @@ int32 ZoneDatabase::GetDoorsDBCountPlusOne(const char *zone_name, int16 version)
|
||||
}
|
||||
|
||||
bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version) {
|
||||
LogFile->write(EQEMuLog::Status, "Loading Doors from database...");
|
||||
Log.Out(Logs::General, Logs::Status, "Loading Doors from database...");
|
||||
|
||||
|
||||
// Door tmpDoor;
|
||||
@@ -656,7 +640,6 @@ bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name
|
||||
"ORDER BY doorid asc", zone_name, version);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()){
|
||||
std::cerr << "Error in DBLoadDoors query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -709,30 +692,13 @@ bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name
|
||||
void Doors::SetLocation(float x, float y, float z)
|
||||
{
|
||||
entity_list.DespawnAllDoors();
|
||||
pos_x = x;
|
||||
pos_y = y;
|
||||
pos_z = z;
|
||||
m_Position = glm::vec4(x, y, z, m_Position.w);
|
||||
entity_list.RespawnAllDoors();
|
||||
}
|
||||
|
||||
void Doors::SetX(float in) {
|
||||
void Doors::SetPosition(const glm::vec4& position) {
|
||||
entity_list.DespawnAllDoors();
|
||||
pos_x = in;
|
||||
entity_list.RespawnAllDoors();
|
||||
}
|
||||
void Doors::SetY(float in) {
|
||||
entity_list.DespawnAllDoors();
|
||||
pos_y = in;
|
||||
entity_list.RespawnAllDoors();
|
||||
}
|
||||
void Doors::SetZ(float in) {
|
||||
entity_list.DespawnAllDoors();
|
||||
pos_z = in;
|
||||
entity_list.RespawnAllDoors();
|
||||
}
|
||||
void Doors::SetHeading(float in) {
|
||||
entity_list.DespawnAllDoors();
|
||||
heading = in;
|
||||
m_Position = position;
|
||||
entity_list.RespawnAllDoors();
|
||||
}
|
||||
|
||||
@@ -767,6 +733,6 @@ void Doors::CreateDatabaseEntry()
|
||||
{
|
||||
return;
|
||||
}
|
||||
database.InsertDoor(GetDoorDBID(), GetDoorID(), GetDoorName(), GetX(), GetY(), GetZ(), GetHeading(), GetOpenType(), GetGuildID(), GetLockpick(), GetKeyItem(), GetDoorParam(), GetInvertState(), GetIncline(), GetSize());
|
||||
database.InsertDoor(GetDoorDBID(), GetDoorID(), GetDoorName(), m_Position, GetOpenType(), GetGuildID(), GetLockpick(), GetKeyItem(), GetDoorParam(), GetInvertState(), GetIncline(), GetSize());
|
||||
}
|
||||
|
||||
|
||||
+7
-22
@@ -17,7 +17,7 @@ class Doors : public Entity
|
||||
{
|
||||
public:
|
||||
Doors(const Door* door);
|
||||
Doors(const char *dmodel, float dx, float dy, float dz, float dheading, uint8 dopentype = 58, uint16 dsize = 100);
|
||||
Doors(const char *dmodel, const glm::vec4& position, uint8 dopentype = 58, uint16 dsize = 100);
|
||||
~Doors();
|
||||
bool IsDoor() const { return true; }
|
||||
void HandleClick(Client* sender, uint8 trigger);
|
||||
@@ -29,10 +29,7 @@ public:
|
||||
char* GetDoorName() { return door_name; }
|
||||
uint32 GetDoorParam() { return door_param; }
|
||||
int GetInvertState() { return invert_state; }
|
||||
float GetX() { return pos_x; }
|
||||
float GetY() { return pos_y; }
|
||||
float GetZ() { return pos_z; }
|
||||
float GetHeading() { return heading; }
|
||||
const glm::vec4& GetPosition() const{ return m_Position; }
|
||||
int GetIncline() { return incline; }
|
||||
bool triggered;
|
||||
void SetOpenState(bool st) { isopen = st; }
|
||||
@@ -54,10 +51,7 @@ public:
|
||||
void SetEntityID(uint32 entity) { entity_id = entity; }
|
||||
|
||||
void DumpDoor();
|
||||
float GetDestX() { return dest_x; }
|
||||
float GetDestY() { return dest_y; }
|
||||
float GetDestZ() { return dest_z; }
|
||||
float GetDestHeading() { return dest_heading; }
|
||||
const glm::vec4 GetDestination() const { return m_Destination; }
|
||||
|
||||
uint8 IsLDoNDoor() { return is_ldon_door; }
|
||||
uint32 GetClientVersionMask() { return client_version_mask; }
|
||||
@@ -67,14 +61,11 @@ public:
|
||||
void ForceClose(Mob *sender, bool alt_mode=false);
|
||||
void ToggleState(Mob *sender);
|
||||
|
||||
void SetX(float in);
|
||||
void SetY(float in);
|
||||
void SetZ(float in);
|
||||
void SetHeading(float in);
|
||||
void SetPosition(const glm::vec4& position);
|
||||
void SetLocation(float x, float y, float z);
|
||||
void SetIncline(int in);
|
||||
void SetDoorName(const char* name);
|
||||
void SetOpenType(uint8 in);
|
||||
void SetLocation(float x, float y, float z);
|
||||
void SetSize(uint16 size);
|
||||
void CreateDatabaseEntry();
|
||||
|
||||
@@ -84,10 +75,7 @@ private:
|
||||
uint8 door_id;
|
||||
char zone_name[32];
|
||||
char door_name[32];
|
||||
float pos_x;
|
||||
float pos_y;
|
||||
float pos_z;
|
||||
float heading;
|
||||
glm::vec4 m_Position;
|
||||
int incline;
|
||||
uint8 opentype;
|
||||
uint32 guild_id;
|
||||
@@ -106,10 +94,7 @@ private:
|
||||
|
||||
char dest_zone[16];
|
||||
int dest_instance_id;
|
||||
float dest_x;
|
||||
float dest_y;
|
||||
float dest_z;
|
||||
float dest_heading;
|
||||
glm::vec4 m_Destination;
|
||||
|
||||
uint8 is_ldon_door;
|
||||
uint32 client_version_mask;
|
||||
|
||||
+14
-12
@@ -16,7 +16,8 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/spdat.h"
|
||||
|
||||
#include "client.h"
|
||||
@@ -26,6 +27,7 @@
|
||||
#include "string_ids.h"
|
||||
#include "worldserver.h"
|
||||
#include "zonedb.h"
|
||||
#include "position.h"
|
||||
|
||||
float Mob::GetActSpellRange(uint16 spell_id, float range, bool IsBard)
|
||||
{
|
||||
@@ -460,7 +462,7 @@ bool Client::TrainDiscipline(uint32 itemid) {
|
||||
const Item_Struct *item = database.GetItem(itemid);
|
||||
if(item == nullptr) {
|
||||
Message(13, "Unable to find the tome you turned in!");
|
||||
LogFile->write(EQEMuLog::Error, "Unable to find turned in tome id %lu\n", (unsigned long)itemid);
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to find turned in tome id %lu\n", (unsigned long)itemid);
|
||||
return(false);
|
||||
}
|
||||
|
||||
@@ -673,7 +675,7 @@ void EntityList::AETaunt(Client* taunter, float range)
|
||||
zdiff *= -1;
|
||||
if (zdiff < 10
|
||||
&& taunter->IsAttackAllowed(them)
|
||||
&& taunter->DistNoRootNoZ(*them) <= range) {
|
||||
&& DistanceSquaredNoZ(taunter->GetPosition(), them->GetPosition()) <= range) {
|
||||
if (taunter->CheckLosFN(them)) {
|
||||
taunter->Taunt(them, true);
|
||||
}
|
||||
@@ -682,7 +684,7 @@ void EntityList::AETaunt(Client* taunter, float range)
|
||||
}
|
||||
}
|
||||
|
||||
// solar: causes caster to hit every mob within dist range of center with
|
||||
// causes caster to hit every mob within dist range of center with
|
||||
// spell_id.
|
||||
// NPC spells will only affect other NPCs with compatible faction
|
||||
void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust)
|
||||
@@ -720,10 +722,10 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
||||
continue;
|
||||
|
||||
if (spells[spell_id].targettype == ST_Ring) {
|
||||
dist_targ = curmob->DistNoRoot(caster->GetTargetRingX(), caster->GetTargetRingY(), caster->GetTargetRingZ());
|
||||
dist_targ = DistanceSquared(static_cast<glm::vec3>(curmob->GetPosition()), caster->GetTargetRingLocation());
|
||||
}
|
||||
else if (center) {
|
||||
dist_targ = center->DistNoRoot(*curmob);
|
||||
dist_targ = DistanceSquared(curmob->GetPosition(), center->GetPosition());
|
||||
}
|
||||
|
||||
if (dist_targ > dist2) //make sure they are in range
|
||||
@@ -747,9 +749,9 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
||||
if (bad) {
|
||||
if (!caster->IsAttackAllowed(curmob, true))
|
||||
continue;
|
||||
if (center && !center->CheckLosFN(curmob))
|
||||
if (center && !spells[spell_id].npc_no_los && !center->CheckLosFN(curmob))
|
||||
continue;
|
||||
if (!center && !caster->CheckLosFN(caster->GetTargetRingX(), caster->GetTargetRingY(), caster->GetTargetRingZ(), curmob->GetSize()))
|
||||
if (!center && !spells[spell_id].npc_no_los && !caster->CheckLosFN(caster->GetTargetRingX(), caster->GetTargetRingY(), caster->GetTargetRingZ(), curmob->GetSize()))
|
||||
continue;
|
||||
} else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
|
||||
// This does not check faction for beneficial AE buffs..only agro and attackable.
|
||||
@@ -795,7 +797,7 @@ void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool a
|
||||
continue;
|
||||
if (curmob == caster && !affect_caster) //watch for caster too
|
||||
continue;
|
||||
if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
|
||||
if (DistanceSquared(center->GetPosition(), curmob->GetPosition()) > dist2) //make sure they are in range
|
||||
continue;
|
||||
|
||||
//Only npcs mgb should hit are client pets...
|
||||
@@ -818,7 +820,7 @@ void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool a
|
||||
}
|
||||
}
|
||||
|
||||
// solar: causes caster to hit every mob within dist range of center with
|
||||
// causes caster to hit every mob within dist range of center with
|
||||
// a bard pulse of spell_id.
|
||||
// NPC spells will only affect other NPCs with compatible faction
|
||||
void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
|
||||
@@ -837,7 +839,7 @@ void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool aff
|
||||
continue;
|
||||
if (curmob == caster && !affect_caster) //watch for caster too
|
||||
continue;
|
||||
if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
|
||||
if (DistanceSquared(center->GetPosition(), curmob->GetPosition()) > dist2) //make sure they are in range
|
||||
continue;
|
||||
if (isnpc && curmob->IsNPC()) { //check npc->npc casting
|
||||
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
|
||||
@@ -887,7 +889,7 @@ void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool I
|
||||
&& curmob != attacker //this is not needed unless NPCs can use this
|
||||
&&(attacker->IsAttackAllowed(curmob))
|
||||
&& curmob->GetRace() != 216 && curmob->GetRace() != 472 /* dont attack horses */
|
||||
&& (curmob->DistNoRoot(*attacker) <= dist2)
|
||||
&& (DistanceSquared(curmob->GetPosition(), attacker->GetPosition()) <= dist2)
|
||||
) {
|
||||
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
||||
hit++;
|
||||
|
||||
+11
-3
@@ -18,7 +18,7 @@
|
||||
|
||||
#ifdef EMBPERL
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/seperator.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/string_util.h"
|
||||
@@ -65,6 +65,7 @@ const char *QuestEventSubroutines[_LargestEventID] = {
|
||||
"EVENT_AGGRO_SAY",
|
||||
"EVENT_PLAYER_PICKUP",
|
||||
"EVENT_POPUPRESPONSE",
|
||||
"EVENT_ENVIRONMENTAL_DAMAGE",
|
||||
"EVENT_PROXIMITY_SAY",
|
||||
"EVENT_CAST",
|
||||
"EVENT_CAST_BEGIN",
|
||||
@@ -140,7 +141,7 @@ void PerlembParser::ReloadQuests() {
|
||||
perl = nullptr;
|
||||
}
|
||||
|
||||
LogFile->write(EQEMuLog::Status, "Error re-initializing perlembed: %s", e.what());
|
||||
Log.Out(Logs::General, Logs::Status, "Error re-initializing perlembed: %s", e.what());
|
||||
throw e.what();
|
||||
}
|
||||
|
||||
@@ -1143,7 +1144,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
ItemInst *inst = EQEmu::any_cast<ItemInst*>(extra_pointers->at(i));
|
||||
|
||||
std::string var_name = "item";
|
||||
var_name += std::to_string(static_cast<long long>(i + 1));
|
||||
var_name += std::to_string(i + 1);
|
||||
|
||||
if(inst) {
|
||||
ExportVar(package_name.c_str(), var_name.c_str(), inst->GetItem()->ID);
|
||||
@@ -1290,6 +1291,13 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
ExportVar(package_name.c_str(), "popupid", data);
|
||||
break;
|
||||
}
|
||||
case EVENT_ENVIRONMENTAL_DAMAGE:{
|
||||
Seperator sep(data);
|
||||
ExportVar(package_name.c_str(), "env_damage", sep.arg[0]);
|
||||
ExportVar(package_name.c_str(), "env_damage_type", sep.arg[1]);
|
||||
ExportVar(package_name.c_str(), "env_final_damage", sep.arg[2]);
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_PROXIMITY_SAY: {
|
||||
ExportVar(package_name.c_str(), "data", objid);
|
||||
|
||||
+60
-40
@@ -21,8 +21,9 @@
|
||||
#ifdef EMBPERL
|
||||
#ifdef EMBPERL_XS
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
|
||||
#include "embparser.h"
|
||||
#include "embxs.h"
|
||||
@@ -32,7 +33,7 @@
|
||||
#include "zone.h"
|
||||
|
||||
extern Zone* zone;
|
||||
extern QueryServ* QServ;
|
||||
extern QueryServ* QServ;
|
||||
|
||||
/*
|
||||
|
||||
@@ -219,11 +220,9 @@ XS(XS__spawn)
|
||||
int npc_type = (int)SvIV(ST(0));
|
||||
int grid = (int)SvIV(ST(1));
|
||||
int unused = (int)SvIV(ST(2));
|
||||
float x = (float)SvNV(ST(3));
|
||||
float y = (float)SvNV(ST(4));
|
||||
float z = (float)SvNV(ST(5));
|
||||
auto position = glm::vec4((float)SvNV(ST(3)), (float)SvNV(ST(4)), (float)SvNV(ST(5)), 0.0f);
|
||||
|
||||
Mob *r = quest_manager.spawn2(npc_type, grid, unused, x, y, z, 0);
|
||||
Mob *r = quest_manager.spawn2(npc_type, grid, unused, position);
|
||||
RETVAL = (r != nullptr) ? r->GetID() : 0;
|
||||
XSprePUSH; PUSHu((UV)RETVAL);
|
||||
|
||||
@@ -243,12 +242,9 @@ XS(XS__spawn2)
|
||||
int npc_type = (int)SvIV(ST(0));
|
||||
int grid = (int)SvIV(ST(1));
|
||||
int unused = (int)SvIV(ST(2));
|
||||
float x = (float)SvNV(ST(3));
|
||||
float y = (float)SvNV(ST(4));
|
||||
float z = (float)SvNV(ST(5));
|
||||
float heading = (float)SvNV(ST(6));
|
||||
auto position = glm::vec4((float)SvNV(ST(3)), (float)SvNV(ST(4)), (float)SvNV(ST(5)), (float)SvNV(ST(6)));
|
||||
|
||||
Mob *r = quest_manager.spawn2(npc_type, grid, unused, x, y, z, heading);
|
||||
Mob *r = quest_manager.spawn2(npc_type, grid, unused, position);
|
||||
RETVAL = (r != nullptr) ? r->GetID() : 0;
|
||||
XSprePUSH; PUSHu((UV)RETVAL);
|
||||
|
||||
@@ -275,7 +271,7 @@ XS(XS__unique_spawn)
|
||||
if(items == 7)
|
||||
heading = (float)SvNV(ST(6));
|
||||
|
||||
Mob *r = quest_manager.unique_spawn(npc_type, grid, unused, x, y, z, heading);
|
||||
Mob *r = quest_manager.unique_spawn(npc_type, grid, unused, glm::vec4(x, y, z, heading));
|
||||
RETVAL = (r != nullptr) ? r->GetID() : 0;
|
||||
|
||||
XSprePUSH; PUSHu((UV)RETVAL);
|
||||
@@ -1175,7 +1171,7 @@ XS(XS__createguild)
|
||||
Perl_croak(aTHX_ "Usage: createguild(guild_name, leader)");
|
||||
|
||||
char * guild_name = (char *)SvPV_nolen(ST(0));
|
||||
char * leader = (char *)SvPV_nolen(ST(1));
|
||||
char * leader = (char *)SvPV_nolen(ST(1));
|
||||
|
||||
quest_manager.CreateGuild(guild_name, leader);
|
||||
|
||||
@@ -1322,11 +1318,9 @@ XS(XS__rebind)
|
||||
Perl_croak(aTHX_ "Usage: rebind(zoneid, x, y, z)");
|
||||
|
||||
int zoneid = (int)SvIV(ST(0));
|
||||
float x = (float)SvNV(ST(1));
|
||||
float y = (float)SvNV(ST(2));
|
||||
float z = (float)SvNV(ST(3));
|
||||
auto location = glm::vec3((float)SvNV(ST(1)),(float)SvNV(ST(2)),(float)SvNV(ST(3)));
|
||||
|
||||
quest_manager.rebind(zoneid, x, y, z);
|
||||
quest_manager.rebind(zoneid, location);
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -1395,7 +1389,7 @@ XS(XS__moveto)
|
||||
else
|
||||
saveguard = false;
|
||||
|
||||
quest_manager.moveto(x, y, z, h, saveguard);
|
||||
quest_manager.moveto(glm::vec4(x, y, z, h), saveguard);
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -1750,12 +1744,9 @@ XS(XS__summonburriedplayercorpse)
|
||||
|
||||
bool RETVAL;
|
||||
uint32 char_id = (int)SvIV(ST(0));
|
||||
float dest_x = (float)SvIV(ST(1));
|
||||
float dest_y = (float)SvIV(ST(2));
|
||||
float dest_z = (float)SvIV(ST(3));
|
||||
float dest_heading = (float)SvIV(ST(4));
|
||||
auto position = glm::vec4((float)SvIV(ST(1)), (float)SvIV(ST(2)), (float)SvIV(ST(3)),(float)SvIV(ST(4)));
|
||||
|
||||
RETVAL = quest_manager.summonburriedplayercorpse(char_id, dest_x, dest_y, dest_z, dest_heading);
|
||||
RETVAL = quest_manager.summonburriedplayercorpse(char_id, position);
|
||||
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
@@ -1771,12 +1762,9 @@ XS(XS__summonallplayercorpses)
|
||||
|
||||
bool RETVAL;
|
||||
uint32 char_id = (int)SvIV(ST(0));
|
||||
float dest_x = (float)SvIV(ST(1));
|
||||
float dest_y = (float)SvIV(ST(2));
|
||||
float dest_z = (float)SvIV(ST(3));
|
||||
float dest_heading = (float)SvIV(ST(4));
|
||||
auto position = glm::vec4((float)SvIV(ST(1)),(float)SvIV(ST(2)),(float)SvIV(ST(3)),(float)SvIV(ST(4)));
|
||||
|
||||
RETVAL = quest_manager.summonallplayercorpses(char_id, dest_x, dest_y, dest_z, dest_heading);
|
||||
RETVAL = quest_manager.summonallplayercorpses(char_id, position);
|
||||
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
@@ -2673,10 +2661,10 @@ XS(XS__CreateGroundObject)
|
||||
uint16 id = 0;
|
||||
|
||||
if(items == 5)
|
||||
id = quest_manager.CreateGroundObject(itemid, x, y, z, heading);
|
||||
id = quest_manager.CreateGroundObject(itemid, glm::vec4(x, y, z, heading));
|
||||
else{
|
||||
uint32 decay_time = (uint32)SvIV(ST(5));
|
||||
id = quest_manager.CreateGroundObject(itemid, x, y, z, heading, decay_time);
|
||||
id = quest_manager.CreateGroundObject(itemid, glm::vec4(x, y, z, heading), decay_time);
|
||||
}
|
||||
|
||||
XSRETURN_IV(id);
|
||||
@@ -2704,7 +2692,7 @@ XS(XS__CreateGroundObjectFromModel)
|
||||
if (items > 6)
|
||||
decay_time = (uint32)SvIV(ST(6));
|
||||
|
||||
id = quest_manager.CreateGroundObjectFromModel(modelname, x, y, z, heading, type, decay_time);
|
||||
id = quest_manager.CreateGroundObjectFromModel(modelname, glm::vec4(x, y, z, heading), type, decay_time);
|
||||
XSRETURN_IV(id);
|
||||
}
|
||||
|
||||
@@ -2979,12 +2967,12 @@ XS(XS__MovePCInstance)
|
||||
|
||||
if (items == 4)
|
||||
{
|
||||
quest_manager.MovePCInstance(zoneid, instanceid, x, y, z, 0.0f);
|
||||
quest_manager.MovePCInstance(zoneid, instanceid, glm::vec4(x, y, z, 0.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
float heading = (float)SvNV(ST(5));
|
||||
quest_manager.MovePCInstance(zoneid, instanceid, x, y, z, heading);
|
||||
quest_manager.MovePCInstance(zoneid, instanceid, glm::vec4(x, y, z, heading));
|
||||
}
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
@@ -3294,7 +3282,7 @@ XS(XS__GetZoneID)
|
||||
|
||||
char *zone = (char *)SvPV_nolen(ST(0));
|
||||
int32 id = quest_manager.GetZoneID(zone);
|
||||
|
||||
|
||||
XSRETURN_IV(id);
|
||||
}
|
||||
|
||||
@@ -3307,7 +3295,7 @@ XS(XS__GetZoneLongName)
|
||||
dXSTARG;
|
||||
char *zone = (char *)SvPV_nolen(ST(0));
|
||||
Const_char* RETVAL = quest_manager.GetZoneLongName(zone);
|
||||
|
||||
|
||||
sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
|
||||
XSRETURN(1);
|
||||
}
|
||||
@@ -3437,7 +3425,7 @@ XS(XS__clear_npctype_cache)
|
||||
int32 npctype_id = (int32)SvIV(ST(0));
|
||||
quest_manager.ClearNPCTypeCache(npctype_id);
|
||||
}
|
||||
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
@@ -3460,11 +3448,11 @@ XS(XS__qs_player_event);
|
||||
XS(XS__qs_player_event)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2){
|
||||
if (items != 2){
|
||||
Perl_croak(aTHX_ "Usage: qs_player_event(char_id, event_desc)");
|
||||
}
|
||||
else{
|
||||
int char_id = (int)SvIV(ST(0));
|
||||
int char_id = (int)SvIV(ST(0));
|
||||
std::string event_desc = (std::string)SvPV_nolen(ST(1));
|
||||
QServ->PlayerLogEvent(Player_Log_Quest, char_id, event_desc);
|
||||
}
|
||||
@@ -3499,13 +3487,44 @@ XS(XS__crosszonesignalnpcbynpctypeid)
|
||||
|
||||
if (items == 2) {
|
||||
uint32 npctype_id = (uint32)SvIV(ST(0));
|
||||
uint32 data = (uint32)SvIV(ST(1));
|
||||
uint32 data = (uint32)SvIV(ST(1));
|
||||
quest_manager.CrossZoneSignalNPCByNPCTypeID(npctype_id, data);
|
||||
}
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__debug);
|
||||
XS(XS__debug)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1 && items != 2){
|
||||
Perl_croak(aTHX_ "Usage: debug(message, [debug_level])");
|
||||
}
|
||||
else{
|
||||
std::string log_message = (std::string)SvPV_nolen(ST(0));
|
||||
uint8 debug_level = 1;
|
||||
|
||||
if (items == 2)
|
||||
debug_level = (uint8)SvIV(ST(1));
|
||||
|
||||
if (debug_level > Logs::Detail)
|
||||
return;
|
||||
|
||||
if (debug_level == Logs::General){
|
||||
Log.Out(Logs::General, Logs::QuestDebug, log_message);
|
||||
}
|
||||
else if (debug_level == Logs::Moderate){
|
||||
Log.Out(Logs::Moderate, Logs::QuestDebug, log_message);
|
||||
}
|
||||
else if (debug_level == Logs::Detail){
|
||||
Log.Out(Logs::Detail, Logs::QuestDebug, log_message);
|
||||
}
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This is the callback perl will look for to setup the
|
||||
quest package's XSUBs
|
||||
@@ -3519,7 +3538,7 @@ EXTERN_C XS(boot_quest)
|
||||
file[255] = '\0';
|
||||
|
||||
if(items != 1)
|
||||
LogFile->write(EQEMuLog::Error, "boot_quest does not take any arguments.");
|
||||
Log.Out(Logs::General, Logs::Error, "boot_quest does not take any arguments.");
|
||||
|
||||
char buf[128]; //shouldent have any function names longer than this.
|
||||
|
||||
@@ -3592,6 +3611,7 @@ EXTERN_C XS(boot_quest)
|
||||
newXS(strcpy(buf, "crosszonesignalclientbycharid"), XS__crosszonesignalclientbycharid, file);
|
||||
newXS(strcpy(buf, "crosszonesignalclientbyname"), XS__crosszonesignalclientbyname, file);
|
||||
newXS(strcpy(buf, "crosszonesignalnpcbynpctypeid"), XS__crosszonesignalnpcbynpctypeid, file);
|
||||
newXS(strcpy(buf, "debug"), XS__debug, file);
|
||||
newXS(strcpy(buf, "delglobal"), XS__delglobal, file);
|
||||
newXS(strcpy(buf, "depop"), XS__depop, file);
|
||||
newXS(strcpy(buf, "depop_withtimer"), XS__depop_withtimer, file);
|
||||
|
||||
+7
-6
@@ -10,7 +10,8 @@ Eglin
|
||||
|
||||
#ifdef EMBPERL
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <vector>
|
||||
@@ -139,12 +140,12 @@ void Embperl::DoInit() {
|
||||
catch(const char *err)
|
||||
{
|
||||
//remember... lasterr() is no good if we crap out here, in construction
|
||||
LogFile->write(EQEMuLog::Quest, "perl error: %s", err);
|
||||
Log.Out(Logs::General, Logs::Quests, "perl error: %s", err);
|
||||
throw "failed to install eval_file hook";
|
||||
}
|
||||
|
||||
#ifdef EMBPERL_IO_CAPTURE
|
||||
LogFile->write(EQEMuLog::Quest, "Tying perl output to eqemu logs");
|
||||
Log.Out(Logs::General, Logs::Quests, "Tying perl output to eqemu logs");
|
||||
//make a tieable class to capture IO and pass it into EQEMuLog
|
||||
eval_pv(
|
||||
"package EQEmuIO; "
|
||||
@@ -169,14 +170,14 @@ void Embperl::DoInit() {
|
||||
,FALSE
|
||||
);
|
||||
|
||||
LogFile->write(EQEMuLog::Quest, "Loading perlemb plugins.");
|
||||
Log.Out(Logs::General, Logs::Quests, "Loading perlemb plugins.");
|
||||
try
|
||||
{
|
||||
eval_pv("main::eval_file('plugin', 'plugin.pl');", FALSE);
|
||||
}
|
||||
catch(const char *err)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Quest, "Warning - plugin.pl: %s", err);
|
||||
Log.Out(Logs::General, Logs::Quests, "Warning - plugin.pl: %s", err);
|
||||
}
|
||||
try
|
||||
{
|
||||
@@ -194,7 +195,7 @@ void Embperl::DoInit() {
|
||||
}
|
||||
catch(const char *err)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Quest, "Perl warning: %s", err);
|
||||
Log.Out(Logs::General, Logs::Quests, "Perl warning: %s", err);
|
||||
}
|
||||
#endif //EMBPERL_PLUGIN
|
||||
in_use = false;
|
||||
|
||||
+8
-4
@@ -17,7 +17,8 @@
|
||||
*/
|
||||
#ifdef EMBPERL
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "masterentity.h"
|
||||
#include "command.h"
|
||||
|
||||
@@ -63,7 +64,7 @@ EXTERN_C XS(boot_qc)
|
||||
file[255] = '\0';
|
||||
|
||||
if(items != 1)
|
||||
LogFile->write(EQEMuLog::Error, "boot_qc does not take any arguments.");
|
||||
Log.Out(Logs::General, Logs::Error, "boot_qc does not take any arguments.");
|
||||
|
||||
char buf[128]; //shouldent have any function names longer than this.
|
||||
|
||||
@@ -91,12 +92,15 @@ XS(XS_EQEmuIO_PRINT)
|
||||
char *str = SvPV_nolen(ST(r));
|
||||
char *cur = str;
|
||||
|
||||
/* Strip newlines from log message 'str' */
|
||||
*std::remove(str, str + strlen(str), '\n') = '\0';
|
||||
|
||||
int i;
|
||||
int pos = 0;
|
||||
int len = 0;
|
||||
for(i = 0; *cur != '\0'; i++, cur++) {
|
||||
if(*cur == '\n') {
|
||||
LogFile->writebuf(EQEMuLog::Quest, str + pos, 1, len);
|
||||
Log.Out(Logs::General, Logs::Quests, str);
|
||||
len = 0;
|
||||
pos = i+1;
|
||||
} else {
|
||||
@@ -104,7 +108,7 @@ XS(XS_EQEmuIO_PRINT)
|
||||
}
|
||||
}
|
||||
if(len > 0) {
|
||||
LogFile->writebuf(EQEMuLog::Quest, str + pos, 1, len);
|
||||
Log.Out(Logs::General, Logs::Quests, str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+162
-237
@@ -15,7 +15,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
@@ -71,23 +71,22 @@ Entity::Entity()
|
||||
|
||||
Entity::~Entity()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
Client *Entity::CastToClient()
|
||||
{
|
||||
if (this == 0x00) {
|
||||
std::cout << "CastToClient error (nullptr)" << std::endl;
|
||||
DebugBreak();
|
||||
Log.Out(Logs::General, Logs::Error, "CastToClient error (nullptr)");
|
||||
return 0;
|
||||
}
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsClient()) {
|
||||
std::cout << "CastToClient error (not client?)" << std::endl;
|
||||
DebugBreak();
|
||||
Log.Out(Logs::General, Logs::Error, "CastToClient error (not client)");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return static_cast<Client *>(this);
|
||||
}
|
||||
|
||||
@@ -95,8 +94,7 @@ NPC *Entity::CastToNPC()
|
||||
{
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsNPC()) {
|
||||
std::cout << "CastToNPC error" << std::endl;
|
||||
DebugBreak();
|
||||
Log.Out(Logs::General, Logs::Error, "CastToNPC error (Not NPC)");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -108,7 +106,6 @@ Mob *Entity::CastToMob()
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsMob()) {
|
||||
std::cout << "CastToMob error" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -120,7 +117,6 @@ Merc *Entity::CastToMerc()
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsMerc()) {
|
||||
std::cout << "CastToMerc error" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -132,7 +128,6 @@ Trap *Entity::CastToTrap()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!IsTrap()) {
|
||||
//std::cout << "CastToTrap error" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -144,7 +139,6 @@ Corpse *Entity::CastToCorpse()
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsCorpse()) {
|
||||
std::cout << "CastToCorpse error" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -156,7 +150,6 @@ Object *Entity::CastToObject()
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsObject()) {
|
||||
std::cout << "CastToObject error" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -167,7 +160,6 @@ Object *Entity::CastToObject()
|
||||
#ifdef _EQDEBUG
|
||||
if(!IsGroup()) {
|
||||
std::cout << "CastToGroup error" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -188,13 +180,11 @@ const Client *Entity::CastToClient() const
|
||||
{
|
||||
if (this == 0x00) {
|
||||
std::cout << "CastToClient error (nullptr)" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsClient()) {
|
||||
std::cout << "CastToClient error (not client?)" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -206,7 +196,6 @@ const NPC *Entity::CastToNPC() const
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsNPC()) {
|
||||
std::cout << "CastToNPC error" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -218,7 +207,6 @@ const Mob *Entity::CastToMob() const
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsMob()) {
|
||||
std::cout << "CastToMob error" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -230,7 +218,6 @@ const Merc *Entity::CastToMerc() const
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsMerc()) {
|
||||
std::cout << "CastToMerc error" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -241,7 +228,6 @@ const Trap *Entity::CastToTrap() const
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!IsTrap()) {
|
||||
//std::cout << "CastToTrap error" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -253,7 +239,6 @@ const Corpse *Entity::CastToCorpse() const
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsCorpse()) {
|
||||
std::cout << "CastToCorpse error" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -265,7 +250,6 @@ const Object *Entity::CastToObject() const
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsObject()) {
|
||||
std::cout << "CastToObject error" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -288,7 +272,6 @@ Bot *Entity::CastToBot()
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsBot()) {
|
||||
std::cout << "CastToBot error" << std::endl;
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -374,7 +357,7 @@ void EntityList::CheckGroupList (const char *fname, const int fline)
|
||||
{
|
||||
if (*it == nullptr)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "nullptr group, %s:%i", fname, fline);
|
||||
Log.Out(Logs::General, Logs::Error, "nullptr group, %s:%i", fname, fline);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -389,11 +372,8 @@ void EntityList::GroupProcess()
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = group_list.begin();
|
||||
while (it != group_list.end()) {
|
||||
(*it)->Process();
|
||||
++it;
|
||||
}
|
||||
for (auto &group : group_list)
|
||||
group->Process();
|
||||
|
||||
#if EQDEBUG >= 5
|
||||
CheckGroupList (__FILE__, __LINE__);
|
||||
@@ -402,11 +382,8 @@ void EntityList::GroupProcess()
|
||||
|
||||
void EntityList::QueueToGroupsForNPCHealthAA(Mob *sender, const EQApplicationPacket *app)
|
||||
{
|
||||
auto it = group_list.begin();
|
||||
while (it != group_list.end()) {
|
||||
(*it)->QueueHPPacketsForNPCHealthAA(sender, app);
|
||||
++it;
|
||||
}
|
||||
for (auto &group : group_list)
|
||||
group->QueueHPPacketsForNPCHealthAA(sender, app);
|
||||
}
|
||||
|
||||
void EntityList::RaidProcess()
|
||||
@@ -419,11 +396,8 @@ void EntityList::RaidProcess()
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = raid_list.begin();
|
||||
while (it != raid_list.end()) {
|
||||
(*it)->Process();
|
||||
++it;
|
||||
}
|
||||
for (auto &raid : raid_list)
|
||||
raid->Process();
|
||||
}
|
||||
|
||||
void EntityList::DoorProcess()
|
||||
@@ -496,14 +470,14 @@ void EntityList::MobProcess()
|
||||
while (it != mob_list.end()) {
|
||||
uint16 id = it->first;
|
||||
Mob *mob = it->second;
|
||||
|
||||
|
||||
size_t sz = mob_list.size();
|
||||
bool p_val = mob->Process();
|
||||
size_t a_sz = mob_list.size();
|
||||
|
||||
|
||||
if(a_sz > sz) {
|
||||
//increased size can potentially screw with iterators so reset it to current value
|
||||
//if buckets are re-orderered we may skip a process here and there but since
|
||||
//if buckets are re-orderered we may skip a process here and there but since
|
||||
//process happens so often it shouldn't matter much
|
||||
it = mob_list.find(id);
|
||||
++it;
|
||||
@@ -527,17 +501,17 @@ void EntityList::MobProcess()
|
||||
#ifdef _WINDOWS
|
||||
struct in_addr in;
|
||||
in.s_addr = mob->CastToClient()->GetIP();
|
||||
std::cout << "Dropping client: Process=false, ip=" << inet_ntoa(in) << ", port=" << mob->CastToClient()->GetPort() << std::endl;
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Dropping client: Process=false, ip=%s port=%u", inet_ntoa(in), mob->CastToClient()->GetPort());
|
||||
#endif
|
||||
zone->StartShutdownTimer();
|
||||
Group *g = GetGroupByMob(mob);
|
||||
if(g) {
|
||||
LogFile->write(EQEMuLog::Error, "About to delete a client still in a group.");
|
||||
Log.Out(Logs::General, Logs::Error, "About to delete a client still in a group.");
|
||||
g->DelMember(mob);
|
||||
}
|
||||
Raid *r = entity_list.GetRaidByClient(mob->CastToClient());
|
||||
if(r) {
|
||||
LogFile->write(EQEMuLog::Error, "About to delete a client still in a raid.");
|
||||
Log.Out(Logs::General, Logs::Error, "About to delete a client still in a raid.");
|
||||
r->MemberZoned(mob->CastToClient());
|
||||
}
|
||||
entity_list.RemoveClient(id);
|
||||
@@ -569,7 +543,7 @@ void EntityList::AddGroup(Group *group)
|
||||
|
||||
uint32 gid = worldserver.NextGroupID();
|
||||
if (gid == 0) {
|
||||
LogFile->write(EQEMuLog::Error,
|
||||
Log.Out(Logs::General, Logs::Error,
|
||||
"Unable to get new group ID from world server. group is going to be broken.");
|
||||
return;
|
||||
}
|
||||
@@ -598,7 +572,7 @@ void EntityList::AddRaid(Raid *raid)
|
||||
|
||||
uint32 gid = worldserver.NextGroupID();
|
||||
if (gid == 0) {
|
||||
LogFile->write(EQEMuLog::Error,
|
||||
Log.Out(Logs::General, Logs::Error,
|
||||
"Unable to get new group ID from world server. group is going to be broken.");
|
||||
return;
|
||||
}
|
||||
@@ -665,7 +639,7 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
|
||||
} else {
|
||||
NewSpawn_Struct *ns = new NewSpawn_Struct;
|
||||
memset(ns, 0, sizeof(NewSpawn_Struct));
|
||||
npc->FillSpawnStruct(ns, 0); // Not working on player newspawns, so it's safe to use a ForWho of 0
|
||||
npc->FillSpawnStruct(ns, nullptr); // Not working on player newspawns, so it's safe to use a ForWho of 0
|
||||
AddToSpawnQueue(npc->GetID(), &ns);
|
||||
safe_delete(ns);
|
||||
}
|
||||
@@ -872,10 +846,11 @@ bool EntityList::MakeDoorSpawnPacket(EQApplicationPacket *app, Client *client)
|
||||
strlen(door->GetDoorName()) > 3) {
|
||||
memset(&nd, 0, sizeof(nd));
|
||||
memcpy(nd.name, door->GetDoorName(), 32);
|
||||
nd.xPos = door->GetX();
|
||||
nd.yPos = door->GetY();
|
||||
nd.zPos = door->GetZ();
|
||||
nd.heading = door->GetHeading();
|
||||
auto position = door->GetPosition();
|
||||
nd.xPos = position.x;
|
||||
nd.yPos = position.y;
|
||||
nd.zPos = position.z;
|
||||
nd.heading = position.w;
|
||||
nd.incline = door->GetIncline();
|
||||
nd.size = door->GetSize();
|
||||
nd.doorId = door->GetDoorID();
|
||||
@@ -1144,7 +1119,7 @@ void EntityList::ChannelMessage(Mob *from, uint8 chan_num, uint8 language,
|
||||
filter = FilterAuctions;
|
||||
//
|
||||
// Only say is limited in range
|
||||
if (chan_num != 8 || client->Dist(*from) < 200)
|
||||
if (chan_num != 8 || Distance(client->GetPosition(), from->GetPosition()) < 200)
|
||||
if (filter == FilterNone || client->GetFilter(filter) != FilterHide)
|
||||
client->ChannelMessageSend(from->GetName(), 0, chan_num, language, lang_skill, buffer);
|
||||
++it;
|
||||
@@ -1467,7 +1442,7 @@ void EntityList::QueueCloseClients(Mob *sender, const EQApplicationPacket *app,
|
||||
|| (filter2 == FilterShowGroupOnly && (sender == ent ||
|
||||
(ent->GetGroup() && ent->GetGroup()->IsGroupMember(sender))))
|
||||
|| (filter2 == FilterShowSelfOnly && ent == sender))
|
||||
&& (ent->DistNoRoot(*sender) <= dist2)) {
|
||||
&& (DistanceSquared(ent->GetPosition(), sender->GetPosition()) <= dist2)) {
|
||||
ent->QueuePacket(app, ackreq, Client::CLIENT_CONNECTED);
|
||||
}
|
||||
}
|
||||
@@ -1577,16 +1552,14 @@ Client *EntityList::GetClientByWID(uint32 iWID)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Client *EntityList::GetRandomClient(float x, float y, float z, float Distance, Client *ExcludeClient)
|
||||
Client *EntityList::GetRandomClient(const glm::vec3& location, float Distance, Client *ExcludeClient)
|
||||
{
|
||||
std::vector<Client *> ClientsInRange;
|
||||
|
||||
auto it = client_list.begin();
|
||||
while (it != client_list.end()) {
|
||||
if ((it->second != ExcludeClient) && (it->second->DistNoRoot(x, y, z) <= Distance))
|
||||
|
||||
for (auto it = client_list.begin();it != client_list.end(); ++it)
|
||||
if ((it->second != ExcludeClient) && (DistanceSquared(static_cast<glm::vec3>(it->second->GetPosition()), location) <= Distance))
|
||||
ClientsInRange.push_back(it->second);
|
||||
++it;
|
||||
}
|
||||
|
||||
if (ClientsInRange.empty())
|
||||
return nullptr;
|
||||
@@ -1611,7 +1584,7 @@ Corpse *EntityList::GetCorpseByOwnerWithinRange(Client *client, Mob *center, int
|
||||
auto it = corpse_list.begin();
|
||||
while (it != corpse_list.end()) {
|
||||
if (it->second->IsPlayerCorpse())
|
||||
if (center->DistNoRootNoZ(*it->second) < range &&
|
||||
if (DistanceSquaredNoZ(center->GetPosition(), it->second->GetPosition()) < range &&
|
||||
strcasecmp(it->second->GetOwnerName(), client->GetName()) == 0)
|
||||
return it->second;
|
||||
++it;
|
||||
@@ -1948,7 +1921,7 @@ void EntityList::MessageClose_StringID(Mob *sender, bool skipsender, float dist,
|
||||
|
||||
for (auto it = client_list.begin(); it != client_list.end(); ++it) {
|
||||
c = it->second;
|
||||
if(c && c->DistNoRoot(*sender) <= dist2 && (!skipsender || c != sender))
|
||||
if(c && DistanceSquared(c->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || c != sender))
|
||||
c->Message_StringID(type, string_id, message1, message2, message3, message4, message5, message6, message7, message8, message9);
|
||||
}
|
||||
}
|
||||
@@ -1964,7 +1937,7 @@ void EntityList::FilteredMessageClose_StringID(Mob *sender, bool skipsender,
|
||||
|
||||
for (auto it = client_list.begin(); it != client_list.end(); ++it) {
|
||||
c = it->second;
|
||||
if (c && c->DistNoRoot(*sender) <= dist2 && (!skipsender || c != sender))
|
||||
if (c && DistanceSquared(c->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || c != sender))
|
||||
c->FilteredMessage_StringID(sender, type, filter, string_id,
|
||||
message1, message2, message3, message4, message5,
|
||||
message6, message7, message8, message9);
|
||||
@@ -2012,7 +1985,7 @@ void EntityList::MessageClose(Mob* sender, bool skipsender, float dist, uint32 t
|
||||
|
||||
auto it = client_list.begin();
|
||||
while (it != client_list.end()) {
|
||||
if (it->second->DistNoRoot(*sender) <= dist2 && (!skipsender || it->second != sender))
|
||||
if (DistanceSquared(it->second->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || it->second != sender))
|
||||
it->second->Message(type, buffer);
|
||||
++it;
|
||||
}
|
||||
@@ -2050,8 +2023,9 @@ void EntityList::RemoveAllMercs()
|
||||
void EntityList::RemoveAllGroups()
|
||||
{
|
||||
while (group_list.size()) {
|
||||
safe_delete(group_list.front());
|
||||
auto group = group_list.front();
|
||||
group_list.pop_front();
|
||||
delete group;
|
||||
}
|
||||
#if EQDEBUG >= 5
|
||||
CheckGroupList (__FILE__, __LINE__);
|
||||
@@ -2061,8 +2035,9 @@ void EntityList::RemoveAllGroups()
|
||||
void EntityList::RemoveAllRaids()
|
||||
{
|
||||
while (raid_list.size()) {
|
||||
safe_delete(raid_list.front());
|
||||
auto raid = raid_list.front();
|
||||
raid_list.pop_front();
|
||||
delete raid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2266,44 +2241,30 @@ bool EntityList::RemoveCorpse(uint16 delete_id)
|
||||
|
||||
bool EntityList::RemoveGroup(uint32 delete_id)
|
||||
{
|
||||
std::list<Group *>::iterator iterator;
|
||||
|
||||
iterator = group_list.begin();
|
||||
|
||||
while(iterator != group_list.end())
|
||||
{
|
||||
if((*iterator)->GetID() == delete_id) {
|
||||
safe_delete(*iterator);
|
||||
group_list.remove(*iterator);
|
||||
auto it = std::find_if(group_list.begin(), group_list.end(),
|
||||
[delete_id](const Group *a) { return a->GetID() == delete_id; });
|
||||
if (it == group_list.end()) {
|
||||
#if EQDEBUG >= 5
|
||||
CheckGroupList (__FILE__, __LINE__);
|
||||
CheckGroupList (__FILE__, __LINE__);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
++iterator;
|
||||
return false;
|
||||
}
|
||||
#if EQDEBUG >= 5
|
||||
CheckGroupList (__FILE__, __LINE__);
|
||||
#endif
|
||||
return false;
|
||||
auto group = *it;
|
||||
group_list.erase(it);
|
||||
delete group;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EntityList::RemoveRaid(uint32 delete_id)
|
||||
{
|
||||
std::list<Raid *>::iterator iterator;
|
||||
|
||||
iterator = raid_list.begin();
|
||||
|
||||
while(iterator != raid_list.end())
|
||||
{
|
||||
if((*iterator)->GetID() == delete_id) {
|
||||
safe_delete(*iterator);
|
||||
raid_list.remove(*iterator);
|
||||
return true;
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
return false;
|
||||
auto it = std::find_if(raid_list.begin(), raid_list.end(),
|
||||
[delete_id](const Raid *a) { return a->GetID() == delete_id; });
|
||||
if (it == raid_list.end())
|
||||
return false;
|
||||
auto raid = *it;
|
||||
raid_list.erase(it);
|
||||
delete raid;
|
||||
return true;
|
||||
}
|
||||
|
||||
void EntityList::Clear()
|
||||
@@ -2510,7 +2471,7 @@ void EntityList::SendPositionUpdates(Client *client, uint32 cLastUpdate,
|
||||
//bool Grouped = client->HasGroup() && mob->IsClient() && (client->GetGroup() == mob->CastToClient()->GetGroup());
|
||||
|
||||
//if (range == 0 || (iterator.GetData() == alwayssend) || Grouped || (mob->DistNoRootNoZ(*client) <= range)) {
|
||||
if (range == 0 || (it->second == alwayssend) || mob->IsClient() || (mob->DistNoRoot(*client) <= range)) {
|
||||
if (range == 0 || (it->second == alwayssend) || mob->IsClient() || (DistanceSquared(mob->GetPosition(), client->GetPosition()) <= range)) {
|
||||
mob->MakeSpawnUpdate(ppu);
|
||||
}
|
||||
if(mob && mob->IsClient() && mob->GetID()>0) {
|
||||
@@ -2558,7 +2519,7 @@ char *EntityList::MakeNameUnique(char *name)
|
||||
return name;
|
||||
}
|
||||
}
|
||||
LogFile->write(EQEMuLog::Error, "Fatal error in EntityList::MakeNameUnique: Unable to find unique name for '%s'", name);
|
||||
Log.Out(Logs::General, Logs::Error, "Fatal error in EntityList::MakeNameUnique: Unable to find unique name for '%s'", name);
|
||||
char tmp[64] = "!";
|
||||
strn0cpy(&tmp[1], name, sizeof(tmp) - 1);
|
||||
strcpy(name, tmp);
|
||||
@@ -2669,8 +2630,8 @@ void EntityList::FindPathsToAllNPCs()
|
||||
|
||||
auto it = npc_list.begin();
|
||||
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());
|
||||
glm::vec3 Node0 = zone->pathing->GetPathNodeCoordinates(0, false);
|
||||
glm::vec3 Dest(it->second->GetX(), it->second->GetY(), it->second->GetZ());
|
||||
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());
|
||||
@@ -2992,7 +2953,7 @@ bool EntityList::MakeTrackPacket(Client *client)
|
||||
it->second->IsInvisible(client))
|
||||
continue;
|
||||
|
||||
MobDistance = it->second->DistNoZ(*client);
|
||||
MobDistance = DistanceNoZ(it->second->GetPosition(), client->GetPosition());
|
||||
if (MobDistance > distance)
|
||||
continue;
|
||||
|
||||
@@ -3041,7 +3002,8 @@ void EntityList::MessageGroup(Mob *sender, bool skipclose, uint32 type, const ch
|
||||
|
||||
auto it = client_list.begin();
|
||||
while (it != client_list.end()) {
|
||||
if (it->second != sender && (it->second->Dist(*sender) <= dist2 || it->second->GetGroup() == sender->CastToClient()->GetGroup())) {
|
||||
if (it->second != sender &&
|
||||
(Distance(it->second->GetPosition(), sender->GetPosition()) <= dist2 || it->second->GetGroup() == sender->CastToClient()->GetGroup())) {
|
||||
it->second->Message(type, buffer);
|
||||
}
|
||||
++it;
|
||||
@@ -3114,54 +3076,42 @@ void EntityList::AddHealAggro(Mob *target, Mob *caster, uint16 thedam)
|
||||
|
||||
void EntityList::OpenDoorsNear(NPC *who)
|
||||
{
|
||||
auto it = door_list.begin();
|
||||
while (it != door_list.end()) {
|
||||
|
||||
for (auto it = door_list.begin();it != door_list.end(); ++it) {
|
||||
Doors *cdoor = it->second;
|
||||
if (cdoor && !cdoor->IsDoorOpen()) {
|
||||
float zdiff = who->GetZ() - cdoor->GetZ();
|
||||
if (zdiff < 0)
|
||||
zdiff = 0 - zdiff;
|
||||
float curdist = 0;
|
||||
float tmp = who->GetX() - cdoor->GetX();
|
||||
curdist += tmp * tmp;
|
||||
tmp = who->GetY() - cdoor->GetY();
|
||||
curdist += tmp * tmp;
|
||||
if (zdiff < 10 && curdist <= 100)
|
||||
cdoor->NPCOpen(who);
|
||||
}
|
||||
++it;
|
||||
if (!cdoor || cdoor->IsDoorOpen())
|
||||
continue;
|
||||
|
||||
auto diff = who->GetPosition() - cdoor->GetPosition();
|
||||
|
||||
float curdist = diff.x * diff.x + diff.y * diff.y;
|
||||
|
||||
if (diff.z * diff.z < 10 && curdist <= 100)
|
||||
cdoor->NPCOpen(who);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::SendAlarm(Trap *trap, Mob *currenttarget, uint8 kos)
|
||||
{
|
||||
float val2 = trap->effectvalue * trap->effectvalue;
|
||||
float preSquareDistance = trap->effectvalue * trap->effectvalue;
|
||||
|
||||
auto it = npc_list.begin();
|
||||
while (it != npc_list.end()) {
|
||||
for (auto it = npc_list.begin();it != npc_list.end(); ++it) {
|
||||
NPC *cur = it->second;
|
||||
float curdist = 0;
|
||||
float tmp = cur->GetX() - trap->x;
|
||||
curdist += tmp*tmp;
|
||||
tmp = cur->GetY() - trap->y;
|
||||
curdist += tmp*tmp;
|
||||
tmp = cur->GetZ() - trap->z;
|
||||
curdist += tmp*tmp;
|
||||
if (!cur->GetOwner() &&
|
||||
/*!cur->CastToMob()->dead && */
|
||||
!cur->IsEngaged() &&
|
||||
curdist <= val2 )
|
||||
{
|
||||
if (kos) {
|
||||
uint8 factioncon = currenttarget->GetReverseFactionCon(cur);
|
||||
if (factioncon == FACTION_THREATENLY || factioncon == FACTION_SCOWLS) {
|
||||
cur->AddToHateList(currenttarget,1);
|
||||
}
|
||||
} else {
|
||||
|
||||
auto diff = glm::vec3(cur->GetPosition()) - trap->m_Position;
|
||||
float curdist = diff.x * diff.x + diff.y * diff.y + diff.z * diff.z;
|
||||
|
||||
if (cur->GetOwner() || cur->IsEngaged() || curdist > preSquareDistance )
|
||||
continue;
|
||||
|
||||
if (kos) {
|
||||
uint8 factioncon = currenttarget->GetReverseFactionCon(cur);
|
||||
if (factioncon == FACTION_THREATENLY || factioncon == FACTION_SCOWLS) {
|
||||
cur->AddToHateList(currenttarget,1);
|
||||
}
|
||||
}
|
||||
++it;
|
||||
else
|
||||
cur->AddToHateList(currenttarget,1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3171,21 +3121,18 @@ void EntityList::AddProximity(NPC *proximity_for)
|
||||
|
||||
proximity_list.push_back(proximity_for);
|
||||
|
||||
proximity_for->proximity = new NPCProximity;
|
||||
proximity_for->proximity = new NPCProximity; // deleted in NPC::~NPC
|
||||
}
|
||||
|
||||
bool EntityList::RemoveProximity(uint16 delete_npc_id)
|
||||
{
|
||||
auto iter = proximity_list.begin();
|
||||
auto it = std::find_if(proximity_list.begin(), proximity_list.end(),
|
||||
[delete_npc_id](const NPC *a) { return a->GetID() == delete_npc_id; });
|
||||
if (it == proximity_list.end())
|
||||
return false;
|
||||
|
||||
while (iter != proximity_list.end()) {
|
||||
if ((*iter)->GetID() == delete_npc_id) {
|
||||
proximity_list.erase(iter);
|
||||
return true;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
return false;
|
||||
proximity_list.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
void EntityList::RemoveAllLocalities()
|
||||
@@ -3201,7 +3148,7 @@ struct quest_proximity_event {
|
||||
int area_type;
|
||||
};
|
||||
|
||||
void EntityList::ProcessMove(Client *c, float x, float y, float z)
|
||||
void EntityList::ProcessMove(Client *c, const glm::vec3& location)
|
||||
{
|
||||
float last_x = c->ProximityX();
|
||||
float last_y = c->ProximityY();
|
||||
@@ -3223,9 +3170,9 @@ void EntityList::ProcessMove(Client *c, float x, float y, float z)
|
||||
last_z < l->min_z || last_z > l->max_z) {
|
||||
old_in = false;
|
||||
}
|
||||
if (x < l->min_x || x > l->max_x ||
|
||||
y < l->min_y || y > l->max_y ||
|
||||
z < l->min_z || z > l->max_z) {
|
||||
if (location.x < l->min_x || location.x > l->max_x ||
|
||||
location.y < l->min_y || location.y > l->max_y ||
|
||||
location.z < l->min_z || location.z > l->max_z) {
|
||||
new_in = false;
|
||||
}
|
||||
|
||||
@@ -3258,9 +3205,9 @@ void EntityList::ProcessMove(Client *c, float x, float y, float z)
|
||||
old_in = false;
|
||||
}
|
||||
|
||||
if (x < a.min_x || x > a.max_x ||
|
||||
y < a.min_y || y > a.max_y ||
|
||||
z < a.min_z || z > a.max_z ) {
|
||||
if (location.x < a.min_x || location.x > a.max_x ||
|
||||
location.y < a.min_y || location.y > a.max_y ||
|
||||
location.z < a.min_z || location.z > a.max_z ) {
|
||||
new_in = false;
|
||||
}
|
||||
|
||||
@@ -3388,14 +3335,12 @@ void EntityList::AddArea(int id, int type, float min_x, float max_x, float min_y
|
||||
|
||||
void EntityList::RemoveArea(int id)
|
||||
{
|
||||
auto iter = area_list.begin();
|
||||
while(iter != area_list.end()) {
|
||||
if((*iter).id == id) {
|
||||
area_list.erase(iter);
|
||||
return;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
auto it = std::find_if(area_list.begin(), area_list.end(),
|
||||
[id](const Area &a) { return a.id == id; });
|
||||
if (it == area_list.end())
|
||||
return;
|
||||
|
||||
area_list.erase(it);
|
||||
}
|
||||
|
||||
void EntityList::ClearAreas()
|
||||
@@ -3451,7 +3396,7 @@ void EntityList::ReloadAllClientsTaskState(int TaskID)
|
||||
// If we have been passed a TaskID, only reload the client state if they have
|
||||
// that Task active.
|
||||
if ((!TaskID) || (TaskID && client->IsTaskActive(TaskID))) {
|
||||
_log(TASKS__CLIENTLOAD, "Reloading Task State For Client %s", client->GetName());
|
||||
Log.Out(Logs::General, Logs::Tasks, "[CLIENTLOAD] Reloading Task State For Client %s", client->GetName());
|
||||
client->RemoveClientTaskState();
|
||||
client->LoadClientTaskState();
|
||||
taskmanager->SendActiveTasksToClient(client);
|
||||
@@ -3592,35 +3537,6 @@ bool EntityList::LimitCheckName(const char *npc_name)
|
||||
return true;
|
||||
}
|
||||
|
||||
void EntityList::RadialSetLogging(Mob *around, bool enabled, bool clients,
|
||||
bool non_clients, float range)
|
||||
{
|
||||
float range2 = range * range;
|
||||
|
||||
auto it = mob_list.begin();
|
||||
while (it != mob_list.end()) {
|
||||
Mob *mob = it->second;
|
||||
|
||||
++it;
|
||||
|
||||
if (mob->IsClient()) {
|
||||
if (!clients)
|
||||
continue;
|
||||
} else {
|
||||
if (!non_clients)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (around->DistNoRoot(*mob) > range2)
|
||||
continue;
|
||||
|
||||
if (enabled)
|
||||
mob->EnableLogging();
|
||||
else
|
||||
mob->DisableLogging();
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::UpdateHoTT(Mob *target)
|
||||
{
|
||||
auto it = client_list.begin();
|
||||
@@ -3665,7 +3581,7 @@ int16 EntityList::CountTempPets(Mob *owner)
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
|
||||
owner->SetTempPetCount(count);
|
||||
|
||||
return count;
|
||||
@@ -3695,9 +3611,9 @@ bool Entity::CheckCoordLosNoZLeaps(float cur_x, float cur_y, float cur_z,
|
||||
if (zone->zonemap == nullptr)
|
||||
return true;
|
||||
|
||||
Map::Vertex myloc;
|
||||
Map::Vertex oloc;
|
||||
Map::Vertex hit;
|
||||
glm::vec3 myloc;
|
||||
glm::vec3 oloc;
|
||||
glm::vec3 hit;
|
||||
|
||||
myloc.x = cur_x;
|
||||
myloc.y = cur_y;
|
||||
@@ -3731,7 +3647,7 @@ void EntityList::QuestJournalledSayClose(Mob *sender, Client *QuestInitiator,
|
||||
// Use the old method for all other nearby clients
|
||||
for (auto it = client_list.begin(); it != client_list.end(); ++it) {
|
||||
c = it->second;
|
||||
if(c && (c != QuestInitiator) && c->DistNoRoot(*sender) <= dist2)
|
||||
if(c && (c != QuestInitiator) && DistanceSquared(c->GetPosition(), sender->GetPosition()) <= dist2)
|
||||
c->Message_StringID(10, GENERIC_SAY, mobname, message);
|
||||
}
|
||||
}
|
||||
@@ -3856,51 +3772,54 @@ void EntityList::GroupMessage(uint32 gid, const char *from, const char *message)
|
||||
}
|
||||
}
|
||||
|
||||
uint16 EntityList::CreateGroundObject(uint32 itemid, float x, float y, float z,
|
||||
float heading, uint32 decay_time)
|
||||
uint16 EntityList::CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time)
|
||||
{
|
||||
const Item_Struct *is = database.GetItem(itemid);
|
||||
if (is) {
|
||||
ItemInst *i = new ItemInst(is, is->MaxCharges);
|
||||
if (i) {
|
||||
Object *object = new Object(i, x, y, z, heading,decay_time);
|
||||
entity_list.AddObject(object, true);
|
||||
if (!is)
|
||||
return 0;
|
||||
|
||||
safe_delete(i);
|
||||
if (object)
|
||||
return object->GetID();
|
||||
}
|
||||
return 0; // fell through itemstruct
|
||||
}
|
||||
return 0; // fell through everything, this is bad/incomplete from perl
|
||||
ItemInst *i = new ItemInst(is, is->MaxCharges);
|
||||
if (!i)
|
||||
return 0;
|
||||
|
||||
Object *object = new Object(i, position.x, position.y, position.z, position.w,decay_time);
|
||||
entity_list.AddObject(object, true);
|
||||
|
||||
safe_delete(i);
|
||||
if (!object)
|
||||
return 0;
|
||||
|
||||
return object->GetID();
|
||||
}
|
||||
|
||||
uint16 EntityList::CreateGroundObjectFromModel(const char *model, float x,
|
||||
float y, float z, float heading, uint8 type, uint32 decay_time)
|
||||
uint16 EntityList::CreateGroundObjectFromModel(const char *model, const glm::vec4& position, uint8 type, uint32 decay_time)
|
||||
{
|
||||
if (model) {
|
||||
Object *object = new Object(model, x, y, z, heading, type);
|
||||
entity_list.AddObject(object, true);
|
||||
if (!model)
|
||||
return 0;
|
||||
|
||||
if (object)
|
||||
return object->GetID();
|
||||
}
|
||||
return 0; // fell through everything, this is bad/incomplete from perl
|
||||
Object *object = new Object(model, position.x, position.y, position.z, position.w, type);
|
||||
entity_list.AddObject(object, true);
|
||||
|
||||
if (!object)
|
||||
return 0;
|
||||
|
||||
return object->GetID();
|
||||
}
|
||||
|
||||
uint16 EntityList::CreateDoor(const char *model, float x, float y, float z,
|
||||
float heading, uint8 opentype, uint16 size)
|
||||
uint16 EntityList::CreateDoor(const char *model, const glm::vec4& position, uint8 opentype, uint16 size)
|
||||
{
|
||||
if (model) {
|
||||
Doors *door = new Doors(model, x, y, z, heading, opentype, size);
|
||||
RemoveAllDoors();
|
||||
zone->LoadZoneDoors(zone->GetShortName(), zone->GetInstanceVersion());
|
||||
entity_list.AddDoor(door);
|
||||
entity_list.RespawnAllDoors();
|
||||
if (!model)
|
||||
return 0; // fell through everything, this is bad/incomplete from perl
|
||||
|
||||
Doors *door = new Doors(model, position, opentype, size);
|
||||
RemoveAllDoors();
|
||||
zone->LoadZoneDoors(zone->GetShortName(), zone->GetInstanceVersion());
|
||||
entity_list.AddDoor(door);
|
||||
entity_list.RespawnAllDoors();
|
||||
|
||||
if (door)
|
||||
return door->GetEntityID();
|
||||
|
||||
if (door)
|
||||
return door->GetEntityID();
|
||||
}
|
||||
return 0; // fell through everything, this is bad/incomplete from perl
|
||||
}
|
||||
|
||||
@@ -3930,7 +3849,7 @@ Mob *EntityList::GetTargetForMez(Mob *caster)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (caster->DistNoRoot(*d) > 22250) { //only pick targets within 150 range
|
||||
if (DistanceSquared(caster->GetPosition(), d->GetPosition()) > 22250) { //only pick targets within 150 range
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
@@ -4440,7 +4359,7 @@ void EntityList::UpdateFindableNPCState(NPC *n, bool Remove)
|
||||
auto it = client_list.begin();
|
||||
while (it != client_list.end()) {
|
||||
Client *c = it->second;
|
||||
if (c && (c->GetClientVersion() >= EQClientSoD))
|
||||
if (c && (c->GetClientVersion() >= ClientVersion::SoD))
|
||||
c->QueuePacket(outapp);
|
||||
|
||||
++it;
|
||||
@@ -4558,7 +4477,6 @@ void EntityList::AddLootToNPCS(uint32 item_id, uint32 count)
|
||||
void EntityList::CameraEffect(uint32 duration, uint32 intensity)
|
||||
{
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_CameraEffect, sizeof(Camera_Struct));
|
||||
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
|
||||
Camera_Struct* cs = (Camera_Struct*) outapp->pBuffer;
|
||||
cs->duration = duration; // Duration in milliseconds
|
||||
cs->intensity = ((intensity * 6710886) + 1023410176); // Intensity ranges from 1023410176 to 1090519040, so simplify it from 0 to 10.
|
||||
@@ -4723,3 +4641,10 @@ Mob *EntityList::GetTargetForVirus(Mob *spreader, int range)
|
||||
return TargetsInRange[zone->random.Int(0, TargetsInRange.size() - 1)];
|
||||
}
|
||||
|
||||
void EntityList::StopMobAI()
|
||||
{
|
||||
for (auto &mob : mob_list) {
|
||||
mob.second->AI_Stop();
|
||||
mob.second->AI_ShutDown();
|
||||
}
|
||||
}
|
||||
|
||||
+9
-8
@@ -27,6 +27,7 @@
|
||||
#include "../common/bodytypes.h"
|
||||
#include "../common/eq_constants.h"
|
||||
|
||||
#include "position.h"
|
||||
#include "zonedump.h"
|
||||
|
||||
class Beacon;
|
||||
@@ -57,7 +58,7 @@ class Bot;
|
||||
class BotRaids;
|
||||
#endif
|
||||
|
||||
extern EntityList entity_list;
|
||||
extern EntityList entity_list;
|
||||
|
||||
class Entity
|
||||
{
|
||||
@@ -154,7 +155,7 @@ public:
|
||||
Client *GetClientByCharID(uint32 iCharID);
|
||||
Client *GetClientByWID(uint32 iWID);
|
||||
Client *GetClient(uint32 ip, uint16 port);
|
||||
Client *GetRandomClient(float x, float y, float z, float Distance, Client *ExcludeClient = nullptr);
|
||||
Client *GetRandomClient(const glm::vec3& location, float Distance, Client *ExcludeClient = nullptr);
|
||||
Group *GetGroupByMob(Mob* mob);
|
||||
Group *GetGroupByClient(Client* client);
|
||||
Group *GetGroupByID(uint32 id);
|
||||
@@ -202,7 +203,7 @@ public:
|
||||
void MobProcess();
|
||||
void TrapProcess();
|
||||
void BeaconProcess();
|
||||
void ProcessMove(Client *c, float x, float y, float z);
|
||||
void ProcessMove(Client *c, const glm::vec3& location);
|
||||
void ProcessMove(NPC *n, float x, float y, float z);
|
||||
void AddArea(int id, int type, float min_x, float max_x, float min_y, float max_y, float min_z, float max_z);
|
||||
void RemoveArea(int id);
|
||||
@@ -268,6 +269,8 @@ public:
|
||||
Entity *GetEntityMob(const char *name);
|
||||
Entity *GetEntityCorpse(const char *name);
|
||||
|
||||
void StopMobAI();
|
||||
|
||||
void DescribeAggro(Client *towho, NPC *from_who, float dist, bool verbose);
|
||||
|
||||
void Message(uint32 to_guilddbid, uint32 type, const char* message, ...);
|
||||
@@ -318,8 +321,6 @@ public:
|
||||
void MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);
|
||||
void AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);
|
||||
|
||||
void RadialSetLogging(Mob *around, bool enabled, bool clients, bool non_clients, float range = 0);
|
||||
|
||||
//trap stuff
|
||||
Mob* GetTrapTrigger(Trap* trap);
|
||||
void SendAlarm(Trap* trap, Mob* currenttarget, uint8 kos);
|
||||
@@ -391,9 +392,9 @@ public:
|
||||
void SaveAllClientsTaskState();
|
||||
void ReloadAllClientsTaskState(int TaskID=0);
|
||||
|
||||
uint16 CreateGroundObject(uint32 itemid, float x, float y, float z, float heading, uint32 decay_time = 300000);
|
||||
uint16 CreateGroundObjectFromModel(const char *model, float x, float y, float z, float heading, uint8 type = 0x00, uint32 decay_time = 0);
|
||||
uint16 CreateDoor(const char *model, float x, float y, float z, float heading, uint8 type = 0, uint16 size = 100);
|
||||
uint16 CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time = 300000);
|
||||
uint16 CreateGroundObjectFromModel(const char *model, const glm::vec4& position, uint8 type = 0x00, uint32 decay_time = 0);
|
||||
uint16 CreateDoor(const char *model, const glm::vec4& position, uint8 type = 0, uint16 size = 100);
|
||||
void ZoneWho(Client *c, Who_All_Struct* Who);
|
||||
void UnMarkNPC(uint16 ID);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ typedef enum {
|
||||
EVENT_AGGRO_SAY,
|
||||
EVENT_PLAYER_PICKUP,
|
||||
EVENT_POPUP_RESPONSE,
|
||||
EVENT_ENVIRONMENTAL_DAMAGE,
|
||||
EVENT_PROXIMITY_SAY,
|
||||
EVENT_CAST,
|
||||
EVENT_CAST_BEGIN,
|
||||
|
||||
+6
-7
@@ -16,7 +16,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/features.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/string_util.h"
|
||||
@@ -240,7 +240,7 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||
}
|
||||
|
||||
void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
_log(CLIENT__EXP, "Attempting to Set Exp for %s (XP: %u, AAXP: %u, Rez: %s)", this->GetCleanName(), set_exp, set_aaxp, isrezzexp ? "true" : "false");
|
||||
Log.Out(Logs::Detail, Logs::None, "Attempting to Set Exp for %s (XP: %u, AAXP: %u, Rez: %s)", this->GetCleanName(), set_exp, set_aaxp, isrezzexp ? "true" : "false");
|
||||
//max_AAXP = GetEXPForLevel(52) - GetEXPForLevel(51); //GetEXPForLevel() doesn't depend on class/race, just level, so it shouldn't change between Clients
|
||||
max_AAXP = RuleI(AA, ExpPerPoint); //this may be redundant since we're doing this in Client::FinishConnState2()
|
||||
if (max_AAXP == 0 || GetEXPForLevel(GetLevel()) == 0xFFFFFFFF) {
|
||||
@@ -308,7 +308,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
|
||||
//figure out how many AA points we get from the exp were setting
|
||||
m_pp.aapoints = set_aaxp / max_AAXP;
|
||||
_log(CLIENT__EXP, "Calculating additional AA Points from AAXP for %s: %u / %u = %.1f points", this->GetCleanName(), set_aaxp, max_AAXP, (float)set_aaxp / (float)max_AAXP);
|
||||
Log.Out(Logs::Detail, Logs::None, "Calculating additional AA Points from AAXP for %s: %u / %u = %.1f points", this->GetCleanName(), set_aaxp, max_AAXP, (float)set_aaxp / (float)max_AAXP);
|
||||
|
||||
//get remainder exp points, set in PP below
|
||||
set_aaxp = set_aaxp - (max_AAXP * m_pp.aapoints);
|
||||
@@ -430,7 +430,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
void Client::SetLevel(uint8 set_level, bool command)
|
||||
{
|
||||
if (GetEXPForLevel(set_level) == 0xFFFFFFFF) {
|
||||
LogFile->write(EQEMuLog::Error,"Client::SetLevel() GetEXPForLevel(%i) = 0xFFFFFFFF", set_level);
|
||||
Log.Out(Logs::General, Logs::Error, "Client::SetLevel() GetEXPForLevel(%i) = 0xFFFFFFFF", set_level);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -488,7 +488,7 @@ void Client::SetLevel(uint8 set_level, bool command)
|
||||
safe_delete(outapp);
|
||||
this->SendAppearancePacket(AT_WhoLevel, set_level); // who level change
|
||||
|
||||
LogFile->write(EQEMuLog::Normal,"Setting Level for %s to %i", GetName(), set_level);
|
||||
Log.Out(Logs::General, Logs::Normal, "Setting Level for %s to %i", GetName(), set_level);
|
||||
|
||||
CalcBonuses();
|
||||
|
||||
@@ -506,8 +506,7 @@ void Client::SetLevel(uint8 set_level, bool command)
|
||||
SetMana(CalcMaxMana());
|
||||
UpdateWho();
|
||||
|
||||
if(GetMerc())
|
||||
UpdateMercLevel();
|
||||
UpdateMercLevel();
|
||||
|
||||
Save();
|
||||
}
|
||||
|
||||
+6
-14
@@ -152,26 +152,24 @@ void Mob::CalculateNewFearpoint()
|
||||
{
|
||||
int Node = zone->pathing->GetRandomPathNode();
|
||||
|
||||
Map::Vertex Loc = zone->pathing->GetPathNodeCoordinates(Node);
|
||||
glm::vec3 Loc = zone->pathing->GetPathNodeCoordinates(Node);
|
||||
|
||||
++Loc.z;
|
||||
|
||||
Map::Vertex CurrentPosition(GetX(), GetY(), GetZ());
|
||||
glm::vec3 CurrentPosition(GetX(), GetY(), GetZ());
|
||||
|
||||
std::deque<int> Route = zone->pathing->FindRoute(CurrentPosition, Loc);
|
||||
|
||||
if(Route.size() > 0)
|
||||
{
|
||||
fear_walkto_x = Loc.x;
|
||||
fear_walkto_y = Loc.y;
|
||||
fear_walkto_z = Loc.z;
|
||||
m_FearWalkTarget = glm::vec3(Loc.x, Loc.y, Loc.z);
|
||||
curfp = true;
|
||||
|
||||
mlog(PATHING__DEBUG, "Feared to node %i (%8.3f, %8.3f, %8.3f)", Node, Loc.x, Loc.y, Loc.z);
|
||||
Log.Out(Logs::Detail, Logs::None, "Feared to node %i (%8.3f, %8.3f, %8.3f)", Node, Loc.x, Loc.y, Loc.z);
|
||||
return;
|
||||
}
|
||||
|
||||
mlog(PATHING__DEBUG, "No path found to selected node. Falling through to old fear point selection.");
|
||||
Log.Out(Logs::Detail, Logs::None, "No path found to selected node. Falling through to old fear point selection.");
|
||||
}
|
||||
|
||||
int loop = 0;
|
||||
@@ -194,14 +192,8 @@ void Mob::CalculateNewFearpoint()
|
||||
}
|
||||
}
|
||||
if (curfp)
|
||||
{
|
||||
fear_walkto_x = ranx;
|
||||
fear_walkto_y = rany;
|
||||
fear_walkto_z = ranz;
|
||||
}
|
||||
m_FearWalkTarget = glm::vec3(ranx, rany, ranz);
|
||||
else //Break fear
|
||||
{
|
||||
BuffFadeByEffect(SE_Fear);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-17
@@ -16,7 +16,8 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/string_util.h"
|
||||
@@ -58,7 +59,6 @@ uint32 ZoneDatabase::GetZoneForage(uint32 ZoneID, uint8 skill) {
|
||||
"LIMIT %i", ZoneID, skill, FORAGE_ITEM_LIMIT);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Forage query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ uint32 ZoneDatabase::GetZoneForage(uint32 ZoneID, uint8 skill) {
|
||||
|
||||
item[index] = atoi(row[0]);
|
||||
chance[index] = atoi(row[1]) + chancepool;
|
||||
LogFile->write(EQEMuLog::Error, "Possible Forage: %d with a %d chance", item[index], chance[index]);
|
||||
Log.Out(Logs::General, Logs::Error, "Possible Forage: %d with a %d chance", item[index], chance[index]);
|
||||
chancepool = chance[index];
|
||||
}
|
||||
|
||||
@@ -114,7 +114,6 @@ uint32 ZoneDatabase::GetZoneFishing(uint32 ZoneID, uint8 skill, uint32 &npc_id,
|
||||
ZoneID, skill);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
std::cerr << "Error in Fishing query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -174,7 +173,8 @@ bool Client::CanFish() {
|
||||
}
|
||||
|
||||
if(zone->zonemap != nullptr && zone->watermap != nullptr && RuleB(Watermap, CheckForWaterWhenFishing)) {
|
||||
float RodX, RodY, RodZ;
|
||||
|
||||
glm::vec3 rodPosition;
|
||||
// Tweak Rod and LineLength if required
|
||||
const float RodLength = RuleR(Watermap, FishingRodLength);
|
||||
const float LineLength = RuleR(Watermap, FishingLineLength);
|
||||
@@ -183,25 +183,25 @@ bool Client::CanFish() {
|
||||
HeadingDegrees = (int) ((GetHeading()*360)/256);
|
||||
HeadingDegrees = HeadingDegrees % 360;
|
||||
|
||||
RodX = x_pos + RodLength * sin(HeadingDegrees * M_PI/180.0f);
|
||||
RodY = y_pos + RodLength * cos(HeadingDegrees * M_PI/180.0f);
|
||||
rodPosition.x = m_Position.x + RodLength * sin(HeadingDegrees * M_PI/180.0f);
|
||||
rodPosition.y = m_Position.y + RodLength * cos(HeadingDegrees * M_PI/180.0f);
|
||||
|
||||
// Do BestZ to find where the line hanging from the rod intersects the water (if it is water).
|
||||
// and go 1 unit into the water.
|
||||
Map::Vertex dest;
|
||||
dest.x = RodX;
|
||||
dest.y = RodY;
|
||||
dest.z = z_pos+10;
|
||||
glm::vec3 dest;
|
||||
dest.x = rodPosition.x;
|
||||
dest.y = rodPosition.y;
|
||||
dest.z = m_Position.z+10;
|
||||
|
||||
RodZ = zone->zonemap->FindBestZ(dest, nullptr) + 4;
|
||||
bool in_lava = zone->watermap->InLava(RodX, RodY, RodZ);
|
||||
bool in_water = zone->watermap->InWater(RodX, RodY, RodZ) || zone->watermap->InVWater(RodX, RodY, RodZ);
|
||||
rodPosition.z = zone->zonemap->FindBestZ(dest, nullptr) + 4;
|
||||
bool in_lava = zone->watermap->InLava(rodPosition);
|
||||
bool in_water = zone->watermap->InWater(rodPosition) || zone->watermap->InVWater(rodPosition);
|
||||
//Message(0, "Rod is at %4.3f, %4.3f, %4.3f, InWater says %d, InLava says %d", RodX, RodY, RodZ, in_water, in_lava);
|
||||
if (in_lava) {
|
||||
Message_StringID(MT_Skills, FISHING_LAVA); //Trying to catch a fire elemental or something?
|
||||
return false;
|
||||
}
|
||||
if((!in_water) || (z_pos-RodZ)>LineLength) { //Didn't hit the water OR the water is too far below us
|
||||
if((!in_water) || (m_Position.z-rodPosition.z)>LineLength) { //Didn't hit the water OR the water is too far below us
|
||||
Message_StringID(MT_Skills, FISHING_LAND); //Trying to catch land sharks perhaps?
|
||||
return false;
|
||||
}
|
||||
@@ -272,7 +272,9 @@ void Client::GoFish()
|
||||
if(npc_chance < zone->random.Int(0, 99)) {
|
||||
const NPCType* tmp = database.GetNPCType(npc_id);
|
||||
if(tmp != nullptr) {
|
||||
NPC* npc = new NPC(tmp, nullptr, GetX()+3, GetY(), GetZ(), GetHeading(), FlyMode3);
|
||||
auto positionNPC = GetPosition();
|
||||
positionNPC.x = positionNPC.x + 3;
|
||||
NPC* npc = new NPC(tmp, nullptr, positionNPC, FlyMode3);
|
||||
npc->AddLootTable();
|
||||
|
||||
npc->AddToHateList(this, 1, 0, false); //no help yelling
|
||||
@@ -388,7 +390,7 @@ void Client::ForageItem(bool guarantee) {
|
||||
const Item_Struct* food_item = database.GetItem(foragedfood);
|
||||
|
||||
if(!food_item) {
|
||||
LogFile->write(EQEMuLog::Error, "nullptr returned from database.GetItem in ClientForageItem");
|
||||
Log.Out(Logs::General, Logs::Error, "nullptr returned from database.GetItem in ClientForageItem");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+86
-103
@@ -15,7 +15,8 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "masterentity.h"
|
||||
#include "npc_ai.h"
|
||||
#include "../common/packet_functions.h"
|
||||
@@ -26,23 +27,16 @@
|
||||
extern EntityList entity_list;
|
||||
extern WorldServer worldserver;
|
||||
|
||||
//
|
||||
// Xorlac: This will need proper synchronization to make it work correctly.
|
||||
// Also, should investigate client ack for packet to ensure proper synch.
|
||||
//
|
||||
|
||||
/*
|
||||
|
||||
note about how groups work:
|
||||
A group contains 2 list, a list of pointers to members and a
|
||||
list of member names. All members of a group should have their
|
||||
name in the membername array, wether they are in the zone or not.
|
||||
name in the membername array, whether they are in the zone or not.
|
||||
Only members in this zone will have non-null pointers in the
|
||||
members array.
|
||||
|
||||
*/
|
||||
|
||||
//create a group which should allready exist in the database
|
||||
//create a group which should already exist in the database
|
||||
Group::Group(uint32 gid)
|
||||
: GroupIDConsumer(gid)
|
||||
{
|
||||
@@ -112,8 +106,7 @@ Group::~Group()
|
||||
}
|
||||
}
|
||||
|
||||
//Cofruben:Split money used in OP_Split.
|
||||
//Rewritten by Father Nitwit
|
||||
//Split money used in OP_Split (/split and /autosplit).
|
||||
void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter) {
|
||||
//avoid unneeded work
|
||||
if(copper == 0 && silver == 0 && gold == 0 && platinum == 0)
|
||||
@@ -197,7 +190,7 @@ void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinu
|
||||
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
if (members[i] != nullptr && members[i]->IsClient()) { // If Group Member is Client
|
||||
Client *c = members[i]->CastToClient();
|
||||
Client *c = members[i]->CastToClient();
|
||||
//I could not get MoneyOnCorpse to work, so we use this
|
||||
c->AddMoneyToPP(cpsplit, spsplit, gpsplit, ppsplit, true);
|
||||
c->Message(2, msg.c_str());
|
||||
@@ -239,7 +232,6 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
|
||||
if(owner)
|
||||
{
|
||||
CharacterID = owner->CastToClient()->CharacterID();
|
||||
NewMemberName = newmember->GetName();
|
||||
}
|
||||
ismerc = true;
|
||||
}
|
||||
@@ -290,14 +282,7 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
|
||||
if (members[i] != nullptr && members[i] != newmember)
|
||||
{
|
||||
//fill in group join & send it
|
||||
if(members[i]->IsMerc())
|
||||
{
|
||||
strcpy(gj->yourname, members[i]->GetName());
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(gj->yourname, members[i]->GetCleanName());
|
||||
}
|
||||
strcpy(gj->yourname, members[i]->GetCleanName());
|
||||
if(members[i]->IsClient())
|
||||
{
|
||||
members[i]->CastToClient()->QueuePacket(outapp);
|
||||
@@ -344,7 +329,7 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
|
||||
Client* owner = newmember->CastToMerc()->GetMercOwner();
|
||||
if(owner)
|
||||
{
|
||||
database.SetGroupID(newmember->GetName(), GetID(), owner->CharacterID(), true);
|
||||
database.SetGroupID(NewMemberName, GetID(), owner->CharacterID(), true);
|
||||
}
|
||||
}
|
||||
#ifdef BOTS
|
||||
@@ -368,7 +353,6 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
|
||||
void Group::AddMember(const char *NewMemberName)
|
||||
{
|
||||
// This method should be called when both the new member and the group leader are in a different zone to this one.
|
||||
//
|
||||
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i)
|
||||
if(!strcasecmp(membername[i], NewMemberName))
|
||||
{
|
||||
@@ -395,9 +379,8 @@ void Group::QueuePacket(const EQApplicationPacket *app, bool ack_req)
|
||||
members[i]->CastToClient()->QueuePacket(app, ack_req);
|
||||
}
|
||||
|
||||
// solar: sends the rest of the group's hps to member. this is useful when
|
||||
// someone first joins a group, but otherwise there shouldn't be a need to
|
||||
// call it
|
||||
// Sends the rest of the group's hps to member. this is useful when someone
|
||||
// first joins a group, but otherwise there shouldn't be a need to call it
|
||||
void Group::SendHPPacketsTo(Mob *member)
|
||||
{
|
||||
if(member && member->IsClient())
|
||||
@@ -411,7 +394,7 @@ void Group::SendHPPacketsTo(Mob *member)
|
||||
{
|
||||
members[i]->CreateHPPacket(&hpapp);
|
||||
member->CastToClient()->QueuePacket(&hpapp, false);
|
||||
if(member->CastToClient()->GetClientVersion() >= EQClientSoD)
|
||||
if(member->CastToClient()->GetClientVersion() >= ClientVersion::SoD)
|
||||
{
|
||||
outapp.SetOpcode(OP_MobManaUpdate);
|
||||
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;
|
||||
@@ -442,7 +425,7 @@ void Group::SendHPPacketsFrom(Mob *member)
|
||||
if(members[i] && members[i] != member && members[i]->IsClient())
|
||||
{
|
||||
members[i]->CastToClient()->QueuePacket(&hp_app);
|
||||
if(members[i]->CastToClient()->GetClientVersion() >= EQClientSoD)
|
||||
if(members[i]->CastToClient()->GetClientVersion() >= ClientVersion::SoD)
|
||||
{
|
||||
outapp.SetOpcode(OP_MobManaUpdate);
|
||||
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;
|
||||
@@ -459,9 +442,11 @@ void Group::SendHPPacketsFrom(Mob *member)
|
||||
}
|
||||
|
||||
//updates a group member's client pointer when they zone in
|
||||
//if the group was in the zone allready
|
||||
//if the group was in the zone already
|
||||
bool Group::UpdatePlayer(Mob* update){
|
||||
|
||||
bool updateSuccess = false;
|
||||
|
||||
VerifyGroup();
|
||||
|
||||
uint32 i=0;
|
||||
@@ -483,11 +468,12 @@ bool Group::UpdatePlayer(Mob* update){
|
||||
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++)
|
||||
{
|
||||
if (!strcasecmp(membername[i],update->GetName()))
|
||||
if (!strcasecmp(membername[i],update->GetCleanName()))
|
||||
{
|
||||
members[i] = update;
|
||||
members[i]->SetGrouped(true);
|
||||
return true;
|
||||
updateSuccess = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,7 +481,7 @@ bool Group::UpdatePlayer(Mob* update){
|
||||
if (update->IsClient() && !mentoree && mentoree_name.length() && !mentoree_name.compare(update->GetName()))
|
||||
mentoree = update->CastToClient();
|
||||
|
||||
return false;
|
||||
return updateSuccess;
|
||||
}
|
||||
|
||||
|
||||
@@ -520,6 +506,7 @@ void Group::MemberZoned(Mob* removemob) {
|
||||
}
|
||||
#endif //BOTS
|
||||
}
|
||||
|
||||
if(removemob->IsClient() && HasRole(removemob, RoleAssist))
|
||||
SetGroupAssistTarget(0);
|
||||
|
||||
@@ -551,7 +538,7 @@ void Group::SendGroupJoinOOZ(Mob* NewMember) {
|
||||
gj->gid = GetID();
|
||||
gj->zoneid = zone->GetZoneID();
|
||||
gj->instance_id = zone->GetInstanceID();
|
||||
strcpy(gj->member_name, NewMember->GetName());
|
||||
strcpy(gj->member_name, NewMember->GetCleanName());
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
@@ -578,7 +565,7 @@ bool Group::DelMemberOOZ(const char *Name) {
|
||||
if(GroupCount() < 3)
|
||||
{
|
||||
UnDelegateMarkNPC(NPCMarkerName.c_str());
|
||||
if(GetLeader() && GetLeader()->IsClient() && GetLeader()->CastToClient()->GetClientVersion() < EQClientSoD) {
|
||||
if(GetLeader() && GetLeader()->IsClient() && GetLeader()->CastToClient()->GetClientVersion() < ClientVersion::SoD) {
|
||||
UnDelegateMainAssist(MainAssistName.c_str());
|
||||
}
|
||||
ClearAllNPCMarks();
|
||||
@@ -592,7 +579,7 @@ bool Group::DelMemberOOZ(const char *Name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Group::DelMember(Mob* oldmember,bool ignoresender)
|
||||
bool Group::DelMember(Mob* oldmember, bool ignoresender)
|
||||
{
|
||||
if (oldmember == nullptr)
|
||||
{
|
||||
@@ -651,7 +638,7 @@ bool Group::DelMember(Mob* oldmember,bool ignoresender)
|
||||
gl->gid = GetID();
|
||||
gl->zoneid = zone->GetZoneID();
|
||||
gl->instance_id = zone->GetInstanceID();
|
||||
strcpy(gl->member_name, oldmember->GetName());
|
||||
strcpy(gl->member_name, oldmember->GetCleanName());
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
@@ -689,6 +676,8 @@ bool Group::DelMember(Mob* oldmember,bool ignoresender)
|
||||
if(oldmember->IsClient())
|
||||
oldmember->CastToClient()->QueuePacket(outapp);
|
||||
}
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
if(oldmember->IsClient())
|
||||
{
|
||||
@@ -700,31 +689,29 @@ bool Group::DelMember(Mob* oldmember,bool ignoresender)
|
||||
Client* owner = oldmember->CastToMerc()->GetMercOwner();
|
||||
if(owner)
|
||||
{
|
||||
database.SetGroupID(oldmember->GetName(), 0, owner->CharacterID(), true);
|
||||
database.SetGroupID(oldmember->GetCleanName(), 0, owner->CharacterID(), true);
|
||||
}
|
||||
}
|
||||
|
||||
oldmember->SetGrouped(false);
|
||||
disbandcheck = true;
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
if(HasRole(oldmember, RoleTank))
|
||||
{
|
||||
SetGroupTankTarget(0);
|
||||
UnDelegateMainTank(oldmember->GetName());
|
||||
UnDelegateMainTank(oldmember->GetCleanName());
|
||||
}
|
||||
|
||||
if(HasRole(oldmember, RoleAssist))
|
||||
{
|
||||
SetGroupAssistTarget(0);
|
||||
UnDelegateMainAssist(oldmember->GetName());
|
||||
UnDelegateMainAssist(oldmember->GetCleanName());
|
||||
}
|
||||
|
||||
if(HasRole(oldmember, RolePuller))
|
||||
{
|
||||
SetGroupPullerTarget(0);
|
||||
UnDelegatePuller(oldmember->GetName());
|
||||
UnDelegatePuller(oldmember->GetCleanName());
|
||||
}
|
||||
|
||||
if (oldmember->GetName() == mentoree_name)
|
||||
@@ -736,7 +723,7 @@ bool Group::DelMember(Mob* oldmember,bool ignoresender)
|
||||
if(GroupCount() < 3)
|
||||
{
|
||||
UnDelegateMarkNPC(NPCMarkerName.c_str());
|
||||
if(GetLeader() && GetLeader()->IsClient() && GetLeader()->CastToClient()->GetClientVersion() < EQClientSoD) {
|
||||
if(GetLeader() && GetLeader()->IsClient() && GetLeader()->CastToClient()->GetClientVersion() < ClientVersion::SoD) {
|
||||
UnDelegateMainAssist(MainAssistName.c_str());
|
||||
}
|
||||
ClearAllNPCMarks();
|
||||
@@ -772,7 +759,7 @@ void Group::CastGroupSpell(Mob* caster, uint16 spell_id) {
|
||||
}
|
||||
else if(members[z] != nullptr)
|
||||
{
|
||||
distance = caster->DistNoRoot(*members[z]);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[z]->GetPosition());
|
||||
if(distance <= range2 && distance >= min_range2) {
|
||||
members[z]->CalcSpellPowerDistanceMod(spell_id, distance);
|
||||
caster->SpellOnTarget(spell_id, members[z]);
|
||||
@@ -781,7 +768,7 @@ void Group::CastGroupSpell(Mob* caster, uint16 spell_id) {
|
||||
caster->SpellOnTarget(spell_id, members[z]->GetPet());
|
||||
#endif
|
||||
} else
|
||||
_log(SPELLS__CASTING, "Group spell: %s is out of range %f at distance %f from %s", members[z]->GetName(), range, distance, caster->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Group spell: %s is out of range %f at distance %f from %s", members[z]->GetName(), range, distance, caster->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -812,7 +799,7 @@ void Group::GroupBardPulse(Mob* caster, uint16 spell_id) {
|
||||
}
|
||||
else if(members[z] != nullptr)
|
||||
{
|
||||
distance = caster->DistNoRoot(*members[z]);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[z]->GetPosition());
|
||||
if(distance <= range2) {
|
||||
members[z]->BardPulse(spell_id, caster);
|
||||
#ifdef GROUP_BUFF_PETS
|
||||
@@ -820,7 +807,7 @@ void Group::GroupBardPulse(Mob* caster, uint16 spell_id) {
|
||||
members[z]->GetPet()->BardPulse(spell_id, caster);
|
||||
#endif
|
||||
} else
|
||||
_log(SPELLS__BARDS, "Group bard pulse: %s is out of range %f at distance %f from %s", members[z]->GetName(), range, distance, caster->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Group bard pulse: %s is out of range %f at distance %f from %s", members[z]->GetName(), range, distance, caster->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -864,7 +851,7 @@ void Group::GroupMessage(Mob* sender, uint8 language, uint8 lang_skill, const ch
|
||||
gcm->zoneid = zone->GetZoneID();
|
||||
gcm->groupid = GetID();
|
||||
gcm->instanceid = zone->GetInstanceID();
|
||||
strcpy(gcm->from, sender->GetName());
|
||||
strcpy(gcm->from, sender->GetCleanName());
|
||||
strcpy(gcm->message, message);
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
@@ -906,8 +893,8 @@ void Group::DisbandGroup() {
|
||||
Leader = members[i]->CastToClient();
|
||||
}
|
||||
|
||||
strcpy(gu->yourname, members[i]->GetName());
|
||||
database.SetGroupID(members[i]->GetName(), 0, members[i]->CastToClient()->CharacterID(), false);
|
||||
strcpy(gu->yourname, members[i]->GetCleanName());
|
||||
database.SetGroupID(members[i]->GetCleanName(), 0, members[i]->CastToClient()->CharacterID(), false);
|
||||
members[i]->CastToClient()->QueuePacket(outapp);
|
||||
SendMarkedNPCsToMember(members[i]->CastToClient(), true);
|
||||
}
|
||||
@@ -917,7 +904,7 @@ void Group::DisbandGroup() {
|
||||
Client* owner = members[i]->CastToMerc()->GetMercOwner();
|
||||
if(owner)
|
||||
{
|
||||
database.SetGroupID(members[i]->GetName(), 0, owner->CharacterID(), true);
|
||||
database.SetGroupID(members[i]->GetCleanName(), 0, owner->CharacterID(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -936,12 +923,13 @@ void Group::DisbandGroup() {
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
entity_list.RemoveGroup(GetID());
|
||||
if(GetID() != 0)
|
||||
{
|
||||
database.ClearGroup(GetID());
|
||||
}
|
||||
|
||||
entity_list.RemoveGroup(GetID());
|
||||
|
||||
if(Leader && (Leader->IsLFP()))
|
||||
{
|
||||
Leader->UpdateLFP();
|
||||
@@ -981,7 +969,7 @@ void Group::SendUpdate(uint32 type, Mob* member)
|
||||
|
||||
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i)
|
||||
if (members[i] != nullptr && members[i] != member)
|
||||
strcpy(gu->membername[x++], members[i]->GetName());
|
||||
strcpy(gu->membername[x++], members[i]->GetCleanName());
|
||||
|
||||
member->CastToClient()->QueuePacket(outapp);
|
||||
|
||||
@@ -998,24 +986,21 @@ void Group::SendLeadershipAAUpdate()
|
||||
// aware of it until they are next in the same zone as the leader.
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
|
||||
|
||||
GroupJoin_Struct* gu = (GroupJoin_Struct*)outapp->pBuffer;
|
||||
|
||||
gu->action = groupActAAUpdate;
|
||||
|
||||
uint32 i = 0;
|
||||
|
||||
gu->leader_aas = LeaderAbilities;
|
||||
|
||||
gu->NPCMarkerID = GetNPCMarkerID();
|
||||
|
||||
uint32 i = 0;
|
||||
for (i = 0;i < MAX_GROUP_MEMBERS; ++i)
|
||||
{
|
||||
if(members[i] && members[i]->IsClient())
|
||||
{
|
||||
strcpy(gu->yourname, members[i]->GetName());
|
||||
strcpy(gu->membername, members[i]->GetName());
|
||||
members[i]->CastToClient()->QueuePacket(outapp);
|
||||
}
|
||||
}
|
||||
|
||||
safe_delete(outapp);
|
||||
}
|
||||
@@ -1037,8 +1022,8 @@ uint8 Group::GroupCount() {
|
||||
|
||||
uint32 Group::GetHighestLevel()
|
||||
{
|
||||
uint32 level = 1;
|
||||
uint32 i;
|
||||
uint32 level = 1;
|
||||
uint32 i;
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++)
|
||||
{
|
||||
if (members[i])
|
||||
@@ -1049,10 +1034,11 @@ uint32 i;
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
uint32 Group::GetLowestLevel()
|
||||
{
|
||||
uint32 level = 255;
|
||||
uint32 i;
|
||||
uint32 level = 255;
|
||||
uint32 i;
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++)
|
||||
{
|
||||
if (members[i])
|
||||
@@ -1083,7 +1069,7 @@ bool Group::LearnMembers() {
|
||||
return false;
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
LogFile->write(EQEMuLog::Error, "Error getting group members for group %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Error getting group members for group %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1112,18 +1098,16 @@ void Group::VerifyGroup() {
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
if (membername[i][0] == '\0') {
|
||||
#if EQDEBUG >= 7
|
||||
LogFile->write(EQEMuLog::Debug, "Group %lu: Verify %d: Empty.\n", (unsigned long)GetID(), i);
|
||||
Log.Out(Logs::General, Logs::None, "Group %lu: Verify %d: Empty.\n", (unsigned long)GetID(), i);
|
||||
#endif
|
||||
members[i] = nullptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
//it should be safe to use GetClientByName, but Group is trying
|
||||
//to be generic, so we'll go for general Mob
|
||||
Mob *them = entity_list.GetMob(membername[i]);
|
||||
if(them == nullptr && members[i] != nullptr) { //they arnt here anymore....
|
||||
if(them == nullptr && members[i] != nullptr) { //they aren't in zone
|
||||
#if EQDEBUG >= 6
|
||||
LogFile->write(EQEMuLog::Debug, "Member of group %lu named '%s' has disappeared!!", (unsigned long)GetID(), membername[i]);
|
||||
Log.Out(Logs::General, Logs::None, "Member of group %lu named '%s' has disappeared!!", (unsigned long)GetID(), membername[i]);
|
||||
#endif
|
||||
membername[i][0] = '\0';
|
||||
members[i] = nullptr;
|
||||
@@ -1132,18 +1116,17 @@ LogFile->write(EQEMuLog::Debug, "Group %lu: Verify %d: Empty.\n", (unsigned long
|
||||
|
||||
if(them != nullptr && members[i] != them) { //our pointer is out of date... not so good.
|
||||
#if EQDEBUG >= 5
|
||||
LogFile->write(EQEMuLog::Debug, "Member of group %lu named '%s' had an out of date pointer!!", (unsigned long)GetID(), membername[i]);
|
||||
Log.Out(Logs::General, Logs::None, "Member of group %lu named '%s' had an out of date pointer!!", (unsigned long)GetID(), membername[i]);
|
||||
#endif
|
||||
members[i] = them;
|
||||
continue;
|
||||
}
|
||||
#if EQDEBUG >= 8
|
||||
LogFile->write(EQEMuLog::Debug, "Member of group %lu named '%s' is valid.", (unsigned long)GetID(), membername[i]);
|
||||
Log.Out(Logs::General, Logs::None, "Member of group %lu named '%s' is valid.", (unsigned long)GetID(), membername[i]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Group::GroupMessage_StringID(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9, uint32 distance) {
|
||||
uint32 i;
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
@@ -1152,13 +1135,14 @@ void Group::GroupMessage_StringID(Mob* sender, uint32 type, uint32 string_id, co
|
||||
|
||||
if(members[i] == sender)
|
||||
continue;
|
||||
|
||||
if(!members[i]->IsClient())
|
||||
continue;
|
||||
|
||||
members[i]->Message_StringID(type, string_id, message, message2, message3, message4, message5, message6, message7, message8, message9, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Client::LeaveGroup() {
|
||||
Group *g = GetGroup();
|
||||
|
||||
@@ -1166,7 +1150,7 @@ void Client::LeaveGroup() {
|
||||
{
|
||||
int32 MemberCount = g->GroupCount();
|
||||
// Account for both client and merc leaving the group
|
||||
if (GetMerc() && GetMerc()->HasGroup() && GetMerc()->GetGroup() == g)
|
||||
if (GetMerc() && g == GetMerc()->GetGroup())
|
||||
{
|
||||
MemberCount -= 1;
|
||||
}
|
||||
@@ -1178,7 +1162,7 @@ void Client::LeaveGroup() {
|
||||
else
|
||||
{
|
||||
g->DelMember(this);
|
||||
if (GetMerc() && GetMerc()->HasGroup() && GetMerc()->GetGroup() == g)
|
||||
if (GetMerc() != nullptr && g == GetMerc()->GetGroup() )
|
||||
{
|
||||
GetMerc()->RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup());
|
||||
}
|
||||
@@ -1187,10 +1171,10 @@ void Client::LeaveGroup() {
|
||||
else
|
||||
{
|
||||
//force things a little
|
||||
database.SetGroupID(GetName(), 0, CharacterID(), false);
|
||||
database.SetGroupID(GetCleanName(), 0, CharacterID(), false);
|
||||
if (GetMerc())
|
||||
{
|
||||
database.SetGroupID(GetMerc()->GetName(), 0, CharacterID(), true);
|
||||
database.SetGroupID(GetMerc()->GetCleanName(), 0, CharacterID(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1214,7 +1198,7 @@ void Group::HealGroup(uint32 heal_amt, Mob* caster, float range)
|
||||
for(; gi < MAX_GROUP_MEMBERS; gi++)
|
||||
{
|
||||
if(members[gi]){
|
||||
distance = caster->DistNoRoot(*members[gi]);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[gi]->GetPosition());
|
||||
if(distance <= range2){
|
||||
numMem += 1;
|
||||
}
|
||||
@@ -1225,7 +1209,7 @@ void Group::HealGroup(uint32 heal_amt, Mob* caster, float range)
|
||||
for(gi = 0; gi < MAX_GROUP_MEMBERS; gi++)
|
||||
{
|
||||
if(members[gi]){
|
||||
distance = caster->DistNoRoot(*members[gi]);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[gi]->GetPosition());
|
||||
if(distance <= range2){
|
||||
members[gi]->HealDamage(heal_amt, caster);
|
||||
members[gi]->SendHPUpdate();
|
||||
@@ -1252,7 +1236,7 @@ void Group::BalanceHP(int32 penalty, float range, Mob* caster, int32 limit)
|
||||
for(; gi < MAX_GROUP_MEMBERS; gi++)
|
||||
{
|
||||
if(members[gi]){
|
||||
distance = caster->DistNoRoot(*members[gi]);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[gi]->GetPosition());
|
||||
if(distance <= range2){
|
||||
|
||||
dmgtaken_tmp = members[gi]->GetMaxHP() - members[gi]->GetHP();
|
||||
@@ -1270,7 +1254,7 @@ void Group::BalanceHP(int32 penalty, float range, Mob* caster, int32 limit)
|
||||
for(gi = 0; gi < MAX_GROUP_MEMBERS; gi++)
|
||||
{
|
||||
if(members[gi]){
|
||||
distance = caster->DistNoRoot(*members[gi]);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[gi]->GetPosition());
|
||||
if(distance <= range2){
|
||||
if((members[gi]->GetMaxHP() - dmgtaken) < 1){ //this way the ability will never kill someone
|
||||
members[gi]->SetHP(1); //but it will come darn close
|
||||
@@ -1301,7 +1285,7 @@ void Group::BalanceMana(int32 penalty, float range, Mob* caster, int32 limit)
|
||||
for(; gi < MAX_GROUP_MEMBERS; gi++)
|
||||
{
|
||||
if(members[gi] && (members[gi]->GetMaxMana() > 0)){
|
||||
distance = caster->DistNoRoot(*members[gi]);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[gi]->GetPosition());
|
||||
if(distance <= range2){
|
||||
|
||||
manataken_tmp = members[gi]->GetMaxMana() - members[gi]->GetMana();
|
||||
@@ -1323,7 +1307,7 @@ void Group::BalanceMana(int32 penalty, float range, Mob* caster, int32 limit)
|
||||
for(gi = 0; gi < MAX_GROUP_MEMBERS; gi++)
|
||||
{
|
||||
if(members[gi]){
|
||||
distance = caster->DistNoRoot(*members[gi]);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[gi]->GetPosition());
|
||||
if(distance <= range2){
|
||||
if((members[gi]->GetMaxMana() - manataken) < 1){
|
||||
members[gi]->SetMana(1);
|
||||
@@ -1363,7 +1347,7 @@ void Group::MarkNPC(Mob* Target, int Number)
|
||||
// Send a packet to all group members in this zone causing the client to prefix the Target mob's name
|
||||
// with the specified Number.
|
||||
//
|
||||
if(!Target || Target->IsClient())
|
||||
if(!Target || Target->IsClient() || Target->IsMerc())
|
||||
return;
|
||||
|
||||
if((Number < 1) || (Number > MAX_MARKED_NPCS))
|
||||
@@ -1473,7 +1457,7 @@ void Group::DelegateMainTank(const char *NewMainTankName, uint8 toggle)
|
||||
MainTankName.c_str(), GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to set group main tank: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to set group main tank: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1519,7 +1503,7 @@ void Group::DelegateMainAssist(const char *NewMainAssistName, uint8 toggle)
|
||||
MainAssistName.c_str(), GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to set group main assist: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to set group main assist: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1566,7 +1550,7 @@ void Group::DelegatePuller(const char *NewPullerName, uint8 toggle)
|
||||
PullerName.c_str(), GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to set group main puller: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to set group main puller: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
@@ -1584,7 +1568,7 @@ void Group::NotifyMainTank(Client *c, uint8 toggle)
|
||||
if(!MainTankName.size())
|
||||
return;
|
||||
|
||||
if(c->GetClientVersion() < EQClientSoD)
|
||||
if(c->GetClientVersion() < ClientVersion::SoD)
|
||||
{
|
||||
if(toggle)
|
||||
c->Message(0, "%s is now Main Tank.", MainTankName.c_str());
|
||||
@@ -1624,7 +1608,7 @@ void Group::NotifyMainAssist(Client *c, uint8 toggle)
|
||||
if(!MainAssistName.size())
|
||||
return;
|
||||
|
||||
if(c->GetClientVersion() < EQClientSoD)
|
||||
if(c->GetClientVersion() < ClientVersion::SoD)
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_DelegateAbility, sizeof(DelegateAbility_Struct));
|
||||
|
||||
@@ -1679,7 +1663,7 @@ void Group::NotifyPuller(Client *c, uint8 toggle)
|
||||
if(!PullerName.size())
|
||||
return;
|
||||
|
||||
if(c->GetClientVersion() < EQClientSoD)
|
||||
if(c->GetClientVersion() < ClientVersion::SoD)
|
||||
{
|
||||
if(toggle)
|
||||
c->Message(0, "%s is now Puller.", PullerName.c_str());
|
||||
@@ -1717,7 +1701,7 @@ void Group::UnDelegateMainTank(const char *OldMainTankName, uint8 toggle)
|
||||
std::string query = StringFormat("UPDATE group_leaders SET maintank = '' WHERE gid = %i LIMIT 1", GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to clear group main tank: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to clear group main tank: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
if(!toggle) {
|
||||
for(uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||
@@ -1766,7 +1750,7 @@ void Group::UnDelegateMainAssist(const char *OldMainAssistName, uint8 toggle)
|
||||
std::string query = StringFormat("UPDATE group_leaders SET assist = '' WHERE gid = %i LIMIT 1", GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to clear group main assist: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to clear group main assist: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
if(!toggle)
|
||||
{
|
||||
@@ -1794,7 +1778,7 @@ void Group::UnDelegatePuller(const char *OldPullerName, uint8 toggle)
|
||||
std::string query = StringFormat("UPDATE group_leaders SET puller = '' WHERE gid = %i LIMIT 1", GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to clear group main puller: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to clear group main puller: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
if(!toggle) {
|
||||
for(uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||
@@ -1877,7 +1861,7 @@ void Group::SetGroupMentor(int percent, char *name)
|
||||
mentoree_name.c_str(), mentor_percent, GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to set group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to set group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Group::ClearGroupMentor()
|
||||
@@ -1888,7 +1872,7 @@ void Group::ClearGroupMentor()
|
||||
std::string query = StringFormat("UPDATE group_leaders SET mentoree = '', mentor_percent = 0 WHERE gid = %i LIMIT 1", GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to clear group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to clear group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Group::NotifyAssistTarget(Client *c)
|
||||
@@ -1958,7 +1942,7 @@ void Group::DelegateMarkNPC(const char *NewNPCMarkerName)
|
||||
NewNPCMarkerName, GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to set group mark npc: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to set group mark npc: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Group::NotifyMarkNPC(Client *c)
|
||||
@@ -2039,7 +2023,7 @@ void Group::UnDelegateMarkNPC(const char *OldNPCMarkerName)
|
||||
std::string query = StringFormat("UPDATE group_leaders SET marknpc = '' WHERE gid = %i LIMIT 1", GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to clear group marknpc: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to clear group marknpc: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
@@ -2056,7 +2040,7 @@ void Group::SaveGroupLeaderAA()
|
||||
safe_delete_array(queryBuffer);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
@@ -2166,7 +2150,6 @@ int8 Group::GetNumberNeedingHealedInGroup(int8 hpr, bool includePets) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return needHealed;
|
||||
}
|
||||
|
||||
@@ -2228,7 +2211,7 @@ void Group::ChangeLeader(Mob* newleader)
|
||||
// this changes the current group leader, notifies other members, and updates leadship AA
|
||||
|
||||
// if the new leader is invalid, do nothing
|
||||
if (!newleader)
|
||||
if (!newleader || !newleader->IsClient())
|
||||
return;
|
||||
|
||||
Mob* oldleader = GetLeader();
|
||||
@@ -2246,7 +2229,7 @@ void Group::ChangeLeader(Mob* newleader)
|
||||
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
if (members[i] && members[i]->IsClient())
|
||||
{
|
||||
if(members[i]->CastToClient()->GetClientVersion() >= EQClientSoD)
|
||||
if(members[i]->CastToClient()->GetClientVersion() >= ClientVersion::SoD)
|
||||
members[i]->CastToClient()->SendGroupLeaderChangePacket(newleader->GetName());
|
||||
|
||||
members[i]->CastToClient()->QueuePacket(outapp);
|
||||
|
||||
+12
-18
@@ -56,15 +56,14 @@ void Client::SendGuildMOTD(bool GetGuildMOTDReply) {
|
||||
|
||||
}
|
||||
|
||||
mlog(GUILDS__OUT_PACKETS, "Sending OP_GuildMOTD of length %d", outapp->size);
|
||||
mpkt(GUILDS__OUT_PACKET_TRACE, outapp);
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending OP_GuildMOTD of length %d", outapp->size);
|
||||
|
||||
FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
void Client::SendGuildURL()
|
||||
{
|
||||
if(GetClientVersion() < EQClientSoF)
|
||||
if(GetClientVersion() < ClientVersion::SoF)
|
||||
return;
|
||||
|
||||
if(IsInAGuild())
|
||||
@@ -85,7 +84,7 @@ void Client::SendGuildURL()
|
||||
|
||||
void Client::SendGuildChannel()
|
||||
{
|
||||
if(GetClientVersion() < EQClientSoF)
|
||||
if(GetClientVersion() < ClientVersion::SoF)
|
||||
return;
|
||||
|
||||
if(IsInAGuild())
|
||||
@@ -107,7 +106,7 @@ void Client::SendGuildChannel()
|
||||
|
||||
void Client::SendGuildRanks()
|
||||
{
|
||||
if(GetClientVersion() < EQClientRoF)
|
||||
if(GetClientVersion() < ClientVersion::RoF)
|
||||
return;
|
||||
|
||||
int permissions = 30 + 1; //Static number of permissions in all EQ clients as of May 2014
|
||||
@@ -145,12 +144,12 @@ void Client::SendGuildSpawnAppearance() {
|
||||
if (!IsInAGuild()) {
|
||||
// clear guildtag
|
||||
SendAppearancePacket(AT_GuildID, GUILD_NONE);
|
||||
mlog(GUILDS__OUT_PACKETS, "Sending spawn appearance for no guild tag.");
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending spawn appearance for no guild tag.");
|
||||
} else {
|
||||
uint8 rank = guild_mgr.GetDisplayedRank(GuildID(), GuildRank(), CharacterID());
|
||||
mlog(GUILDS__OUT_PACKETS, "Sending spawn appearance for guild %d at rank %d", GuildID(), rank);
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending spawn appearance for guild %d at rank %d", GuildID(), rank);
|
||||
SendAppearancePacket(AT_GuildID, GuildID());
|
||||
if(GetClientVersion() >= EQClientRoF)
|
||||
if(GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
switch (rank) {
|
||||
case 0: { rank = 5; break; } // GUILD_MEMBER 0
|
||||
@@ -172,12 +171,11 @@ void Client::SendGuildList() {
|
||||
//ask the guild manager to build us a nice guild list packet
|
||||
outapp->pBuffer = guild_mgr.MakeGuildList(/*GetName()*/"", outapp->size);
|
||||
if(outapp->pBuffer == nullptr) {
|
||||
mlog(GUILDS__ERROR, "Unable to make guild list!");
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Unable to make guild list!");
|
||||
return;
|
||||
}
|
||||
|
||||
mlog(GUILDS__OUT_PACKETS, "Sending OP_ZoneGuildList of length %d", outapp->size);
|
||||
// mpkt(GUILDS__OUT_PACKET_TRACE, outapp);
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending OP_ZoneGuildList of length %d", outapp->size);
|
||||
|
||||
FastQueuePacket(&outapp);
|
||||
}
|
||||
@@ -194,8 +192,7 @@ void Client::SendGuildMembers() {
|
||||
outapp->pBuffer = data;
|
||||
data = nullptr;
|
||||
|
||||
mlog(GUILDS__OUT_PACKETS, "Sending OP_GuildMemberList of length %d", outapp->size);
|
||||
mpkt(GUILDS__OUT_PACKET_TRACE, outapp);
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending OP_GuildMemberList of length %d", outapp->size);
|
||||
|
||||
FastQueuePacket(&outapp);
|
||||
|
||||
@@ -226,7 +223,7 @@ void Client::RefreshGuildInfo()
|
||||
|
||||
CharGuildInfo info;
|
||||
if(!guild_mgr.GetCharInfo(CharacterID(), info)) {
|
||||
mlog(GUILDS__ERROR, "Unable to obtain guild char info for %s (%d)", GetName(), CharacterID());
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Unable to obtain guild char info for %s (%d)", GetName(), CharacterID());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -338,8 +335,7 @@ void Client::SendGuildJoin(GuildJoin_Struct* gj){
|
||||
outgj->rank = gj->rank;
|
||||
outgj->zoneid = gj->zoneid;
|
||||
|
||||
mlog(GUILDS__OUT_PACKETS, "Sending OP_GuildManageAdd for join of length %d", outapp->size);
|
||||
mpkt(GUILDS__OUT_PACKET_TRACE, outapp);
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending OP_GuildManageAdd for join of length %d", outapp->size);
|
||||
|
||||
FastQueuePacket(&outapp);
|
||||
|
||||
@@ -413,7 +409,6 @@ bool ZoneDatabase::CheckGuildDoor(uint8 doorid, uint16 guild_id, const char* zon
|
||||
doorid-128, zone);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in CheckGuildDoor query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -433,7 +428,6 @@ bool ZoneDatabase::SetGuildDoor(uint8 doorid,uint16 guild_id, const char* zone)
|
||||
guild_id, doorid, zone);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in SetGuildDoor query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+18
-25
@@ -32,7 +32,7 @@ extern WorldServer worldserver;
|
||||
extern volatile bool ZoneLoaded;
|
||||
|
||||
void ZoneGuildManager::SendGuildRefresh(uint32 guild_id, bool name, bool motd, bool rank, bool relation) {
|
||||
_log(GUILDS__REFRESH, "Sending guild refresh for %d to world, changes: name=%d, motd=%d, rank=d, relation=%d", guild_id, name, motd, rank, relation);
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending guild refresh for %d to world, changes: name=%d, motd=%d, rank=d, relation=%d", guild_id, name, motd, rank, relation);
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_RefreshGuild, sizeof(ServerGuildRefresh_Struct));
|
||||
ServerGuildRefresh_Struct *s = (ServerGuildRefresh_Struct *) pack->pBuffer;
|
||||
s->guild_id = guild_id;
|
||||
@@ -46,7 +46,7 @@ void ZoneGuildManager::SendGuildRefresh(uint32 guild_id, bool name, bool motd, b
|
||||
|
||||
void ZoneGuildManager::SendCharRefresh(uint32 old_guild_id, uint32 guild_id, uint32 charid) {
|
||||
if(guild_id == 0) {
|
||||
_log(GUILDS__REFRESH, "Guild lookup for char %d when sending char refresh.", charid);
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Guild lookup for char %d when sending char refresh.", charid);
|
||||
|
||||
CharGuildInfo gci;
|
||||
if(!GetCharInfo(charid, gci)) {
|
||||
@@ -56,7 +56,7 @@ void ZoneGuildManager::SendCharRefresh(uint32 old_guild_id, uint32 guild_id, uin
|
||||
}
|
||||
}
|
||||
|
||||
_log(GUILDS__REFRESH, "Sending char refresh for %d from guild %d to world", charid, guild_id);
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending char refresh for %d from guild %d to world", charid, guild_id);
|
||||
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_GuildCharRefresh, sizeof(ServerGuildCharRefresh_Struct));
|
||||
ServerGuildCharRefresh_Struct *s = (ServerGuildCharRefresh_Struct *) pack->pBuffer;
|
||||
@@ -89,7 +89,7 @@ void ZoneGuildManager::SendRankUpdate(uint32 CharID)
|
||||
}
|
||||
|
||||
void ZoneGuildManager::SendGuildDelete(uint32 guild_id) {
|
||||
_log(GUILDS__REFRESH, "Sending guild delete for guild %d to world", guild_id);
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending guild delete for guild %d to world", guild_id);
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_DeleteGuild, sizeof(ServerGuildID_Struct));
|
||||
ServerGuildID_Struct *s = (ServerGuildID_Struct *) pack->pBuffer;
|
||||
s->guild_id = guild_id;
|
||||
@@ -261,12 +261,12 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
switch(pack->opcode) {
|
||||
case ServerOP_RefreshGuild: {
|
||||
if(pack->size != sizeof(ServerGuildRefresh_Struct)) {
|
||||
_log(GUILDS__ERROR, "Received ServerOP_RefreshGuild of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildRefresh_Struct));
|
||||
Log.Out(Logs::General, Logs::Error, "Received ServerOP_RefreshGuild of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildRefresh_Struct));
|
||||
return;
|
||||
}
|
||||
ServerGuildRefresh_Struct *s = (ServerGuildRefresh_Struct *) pack->pBuffer;
|
||||
|
||||
_log(GUILDS__REFRESH, "Received guild refresh from world for %d, changes: name=%d, motd=%d, rank=%d, relation=%d", s->guild_id, s->name_change, s->motd_change, s->rank_change, s->relation_change);
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Received guild refresh from world for %d, changes: name=%d, motd=%d, rank=%d, relation=%d", s->guild_id, s->name_change, s->motd_change, s->rank_change, s->relation_change);
|
||||
|
||||
//reload all the guild details from the database.
|
||||
RefreshGuild(s->guild_id);
|
||||
@@ -295,12 +295,12 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
|
||||
case ServerOP_GuildCharRefresh: {
|
||||
if(pack->size != sizeof(ServerGuildCharRefresh_Struct)) {
|
||||
_log(GUILDS__ERROR, "Received ServerOP_RefreshGuild of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildCharRefresh_Struct));
|
||||
Log.Out(Logs::General, Logs::Error, "Received ServerOP_RefreshGuild of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildCharRefresh_Struct));
|
||||
return;
|
||||
}
|
||||
ServerGuildCharRefresh_Struct *s = (ServerGuildCharRefresh_Struct *) pack->pBuffer;
|
||||
|
||||
_log(GUILDS__REFRESH, "Received guild member refresh from world for char %d from guild %d", s->char_id, s->guild_id);
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Received guild member refresh from world for char %d from guild %d", s->char_id, s->guild_id);
|
||||
|
||||
Client *c = entity_list.GetClientByCharID(s->char_id);
|
||||
|
||||
@@ -322,7 +322,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
else if(c != nullptr && s->guild_id != GUILD_NONE) {
|
||||
//char is in zone, and has changed into a new guild, send MOTD.
|
||||
c->SendGuildMOTD();
|
||||
if(c->GetClientVersion() >= EQClientRoF)
|
||||
if(c->GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
c->SendGuildRanks();
|
||||
}
|
||||
@@ -338,7 +338,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
{
|
||||
if(pack->size != sizeof(ServerGuildRankUpdate_Struct))
|
||||
{
|
||||
_log(GUILDS__ERROR, "Received ServerOP_RankUpdate of incorrect size %d, expected %d",
|
||||
Log.Out(Logs::General, Logs::Error, "Received ServerOP_RankUpdate of incorrect size %d, expected %d",
|
||||
pack->size, sizeof(ServerGuildRankUpdate_Struct));
|
||||
|
||||
return;
|
||||
@@ -364,12 +364,12 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
|
||||
case ServerOP_DeleteGuild: {
|
||||
if(pack->size != sizeof(ServerGuildID_Struct)) {
|
||||
_log(GUILDS__ERROR, "Received ServerOP_DeleteGuild of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildID_Struct));
|
||||
Log.Out(Logs::General, Logs::Error, "Received ServerOP_DeleteGuild of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildID_Struct));
|
||||
return;
|
||||
}
|
||||
ServerGuildID_Struct *s = (ServerGuildID_Struct *) pack->pBuffer;
|
||||
|
||||
_log(GUILDS__REFRESH, "Received guild delete from world for guild %d", s->guild_id);
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Received guild delete from world for guild %d", s->guild_id);
|
||||
|
||||
//clear all the guild tags.
|
||||
entity_list.RefreshAllGuildInfo(s->guild_id);
|
||||
@@ -417,10 +417,10 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
|
||||
if (!c || !c->IsInAGuild())
|
||||
{
|
||||
_log(GUILDS__ERROR,"Invalid Client or not in guild. ID=%i", FromID);
|
||||
Log.Out(Logs::Detail, Logs::Guilds,"Invalid Client or not in guild. ID=%i", FromID);
|
||||
break;
|
||||
}
|
||||
_log(GUILDS__IN_PACKETS,"Processing ServerOP_OnlineGuildMembersResponse");
|
||||
Log.Out(Logs::Detail, Logs::Guilds,"Processing ServerOP_OnlineGuildMembersResponse");
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildMemberUpdate, sizeof(GuildMemberUpdate_Struct));
|
||||
GuildMemberUpdate_Struct *gmus = (GuildMemberUpdate_Struct*)outapp->pBuffer;
|
||||
char Name[64];
|
||||
@@ -433,7 +433,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
VARSTRUCT_DECODE_STRING(Name, Buffer);
|
||||
strn0cpy(gmus->MemberName, Name, sizeof(gmus->MemberName));
|
||||
gmus->ZoneID = VARSTRUCT_DECODE_TYPE(uint32, Buffer);
|
||||
_log(GUILDS__OUT_PACKETS,"Sending OP_GuildMemberUpdate to %i. Name=%s ZoneID=%i",FromID,Name,gmus->ZoneID);
|
||||
Log.Out(Logs::Detail, Logs::Guilds,"Sending OP_GuildMemberUpdate to %i. Name=%s ZoneID=%i",FromID,Name,gmus->ZoneID);
|
||||
c->QueuePacket(outapp);
|
||||
}
|
||||
safe_delete(outapp);
|
||||
@@ -603,7 +603,6 @@ bool GuildBankManager::Load(uint32 guildID)
|
||||
"FROM `guild_bank` WHERE `guildid` = %i", guildID);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
_log(GUILDS__BANK_ERROR, "Error Loading guild bank: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -684,7 +683,7 @@ void GuildBankManager::SendGuildBank(Client *c)
|
||||
|
||||
if(Iterator == Banks.end())
|
||||
{
|
||||
_log(GUILDS__BANK_ERROR, "Unable to find guild bank for guild ID %i", c->GuildID());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to find guild bank for guild ID %i", c->GuildID());
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -800,7 +799,7 @@ bool GuildBankManager::AddItem(uint32 GuildID, uint8 Area, uint32 ItemID, int32
|
||||
|
||||
if(Iterator == Banks.end())
|
||||
{
|
||||
_log(GUILDS__BANK_ERROR, "Unable to find guild bank for guild ID %i", GuildID);
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to find guild bank for guild ID %i", GuildID);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -846,7 +845,7 @@ bool GuildBankManager::AddItem(uint32 GuildID, uint8 Area, uint32 ItemID, int32
|
||||
|
||||
if(Slot < 0)
|
||||
{
|
||||
_log(GUILDS__BANK_ERROR, "No space to add item to the guild bank.");
|
||||
Log.Out(Logs::General, Logs::Error, "No space to add item to the guild bank.");
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -857,7 +856,6 @@ bool GuildBankManager::AddItem(uint32 GuildID, uint8 Area, uint32 ItemID, int32
|
||||
GuildID, Area, Slot, ItemID, QtyOrCharges, Donator, Permissions, WhoFor);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
_log(GUILDS__BANK_ERROR, "Insert Error: %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -922,7 +920,6 @@ int GuildBankManager::Promote(uint32 guildID, int slotID)
|
||||
"LIMIT 1", mainSlot, guildID, slotID);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
_log(GUILDS__BANK_ERROR, "error promoting item: %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -974,7 +971,6 @@ void GuildBankManager::SetPermissions(uint32 guildID, uint16 slotID, uint32 perm
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success())
|
||||
{
|
||||
_log(GUILDS__BANK_ERROR, "error changing permissions: %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1124,7 +1120,6 @@ bool GuildBankManager::DeleteItem(uint32 guildID, uint16 area, uint16 slotID, ui
|
||||
guildID, area, slotID);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
_log(GUILDS__BANK_ERROR, "Delete item failed. %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1136,7 +1131,6 @@ bool GuildBankManager::DeleteItem(uint32 guildID, uint16 area, uint16 slotID, ui
|
||||
BankArea[slotID].Quantity - quantity, guildID, area, slotID);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
_log(GUILDS__BANK_ERROR, "Update item failed. %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1299,7 +1293,6 @@ void GuildBankManager::UpdateItemQuantity(uint32 guildID, uint16 area, uint16 sl
|
||||
quantity, guildID, area, slotID);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
_log(GUILDS__BANK_ERROR, "Update item quantity failed. %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -158,7 +158,7 @@ Mob* HateList::GetClosestEntOnHateList(Mob *hater) {
|
||||
|
||||
auto iterator = list.begin();
|
||||
while (iterator != list.end()) {
|
||||
this_distance = (*iterator)->entity_on_hatelist->DistNoRootNoZ(*hater);
|
||||
this_distance = DistanceSquaredNoZ((*iterator)->entity_on_hatelist->GetPosition(), hater->GetPosition());
|
||||
if ((*iterator)->entity_on_hatelist != nullptr && this_distance <= close_distance) {
|
||||
close_distance = this_distance;
|
||||
close_entity = (*iterator)->entity_on_hatelist;
|
||||
@@ -308,8 +308,9 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center)
|
||||
continue;
|
||||
}
|
||||
|
||||
auto hateEntryPosition = glm::vec3(cur->entity_on_hatelist->GetX(), cur->entity_on_hatelist->GetY(), cur->entity_on_hatelist->GetZ());
|
||||
if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
||||
if (!zone->watermap->InLiquid(cur->entity_on_hatelist->GetX(), cur->entity_on_hatelist->GetY(), cur->entity_on_hatelist->GetZ())) {
|
||||
if (!zone->watermap->InLiquid(hateEntryPosition)) {
|
||||
skipped_count++;
|
||||
++iterator;
|
||||
continue;
|
||||
@@ -434,7 +435,7 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center)
|
||||
{
|
||||
struct_HateList *cur = (*iterator);
|
||||
if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
||||
if (!zone->watermap->InLiquid(cur->entity_on_hatelist->GetX(), cur->entity_on_hatelist->GetY(), cur->entity_on_hatelist->GetZ())) {
|
||||
if(!zone->watermap->InLiquid(glm::vec3(cur->entity_on_hatelist->GetPosition()))) {
|
||||
skipped_count++;
|
||||
++iterator;
|
||||
continue;
|
||||
@@ -591,7 +592,7 @@ void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_cent
|
||||
struct_HateList *h = (*iterator);
|
||||
if (range > 0)
|
||||
{
|
||||
dist_targ = center->DistNoRoot(*h->entity_on_hatelist);
|
||||
dist_targ = DistanceSquared(center->GetPosition(), h->entity_on_hatelist->GetPosition());
|
||||
if (dist_targ <= range && dist_targ >= min_range2)
|
||||
{
|
||||
id_list.push_back(h->entity_on_hatelist->GetID());
|
||||
|
||||
+7
-7
@@ -16,7 +16,8 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/string_util.h"
|
||||
|
||||
@@ -28,8 +29,8 @@
|
||||
std::map<uint16, const NPCType *> Horse::horse_types;
|
||||
LinkedList<NPCType *> horses_auto_delete;
|
||||
|
||||
Horse::Horse(Client *_owner, uint16 spell_id, float x, float y, float z, float heading)
|
||||
: NPC(GetHorseType(spell_id), nullptr, x, y, z, heading, FlyMode3)
|
||||
Horse::Horse(Client *_owner, uint16 spell_id, const glm::vec4& position)
|
||||
: NPC(GetHorseType(spell_id), nullptr, position, FlyMode3)
|
||||
{
|
||||
//give the horse its proper name.
|
||||
strn0cpy(name, _owner->GetCleanName(), 55);
|
||||
@@ -72,12 +73,11 @@ const NPCType *Horse::BuildHorseType(uint16 spell_id) {
|
||||
std::string query = StringFormat("SELECT race, gender, texture, mountspeed FROM horses WHERE filename = '%s'", fileName);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Mount query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (results.RowCount() != 1) {
|
||||
LogFile->write(EQEMuLog::Error, "No Database entry for mount: %s, check the horses table", fileName);
|
||||
Log.Out(Logs::General, Logs::Error, "No Database entry for mount: %s, check the horses table", fileName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -120,13 +120,13 @@ void Client::SummonHorse(uint16 spell_id) {
|
||||
return;
|
||||
}
|
||||
if(!Horse::IsHorseSpell(spell_id)) {
|
||||
LogFile->write(EQEMuLog::Error, "%s tried to summon an unknown horse, spell id %d", GetName(), spell_id);
|
||||
Log.Out(Logs::General, Logs::Error, "%s tried to summon an unknown horse, spell id %d", GetName(), spell_id);
|
||||
return;
|
||||
}
|
||||
|
||||
// No Horse, lets get them one.
|
||||
|
||||
Horse* horse = new Horse(this, spell_id, GetX(), GetY(), GetZ(), GetHeading());
|
||||
Horse* horse = new Horse(this, spell_id, GetPosition());
|
||||
|
||||
//we want to manage the spawn packet ourself.
|
||||
//another reason is we dont want quests executing on it.
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ struct NewSpawn_Struct;
|
||||
|
||||
class Horse : public NPC {
|
||||
public:
|
||||
Horse(Client *owner, uint16 spell_id, float x, float y, float z, float heading);
|
||||
Horse(Client *owner, uint16 spell_id, const glm::vec4& position);
|
||||
|
||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
|
||||
|
||||
+410
-403
File diff suppressed because it is too large
Load Diff
+12
-3
@@ -16,7 +16,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/loottable.h"
|
||||
#include "../common/misc_functions.h"
|
||||
|
||||
@@ -145,7 +145,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
drop_chance = zone->random.Real(0.0, 100.0);
|
||||
|
||||
#if EQDEBUG>=11
|
||||
LogFile->write(EQEMuLog::Debug, "Drop chance for npc: %s, this chance:%f, drop roll:%f", npc->GetName(), thischance, drop_chance);
|
||||
Log.Out(Logs::General, Logs::None, "Drop chance for npc: %s, this chance:%f, drop roll:%f", npc->GetName(), thischance, drop_chance);
|
||||
#endif
|
||||
if (thischance == 100.0 || drop_chance < thischance)
|
||||
{
|
||||
@@ -174,6 +174,11 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
}
|
||||
}
|
||||
} // We either ran out of items or reached our limit.
|
||||
|
||||
npc->UpdateEquipLightValue();
|
||||
// no wearchange associated with this function..so, this should not be needed
|
||||
//if (npc->UpdateActiveLightValue())
|
||||
// npc->SendAppearancePacket(AT_Light, npc->GetActiveLightValue());
|
||||
}
|
||||
|
||||
//if itemlist is null, just send wear changes
|
||||
@@ -187,7 +192,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
|
||||
ServerLootItem_Struct* item = new ServerLootItem_Struct;
|
||||
#if EQDEBUG>=11
|
||||
LogFile->write(EQEMuLog::Debug, "Adding drop to npc: %s, Item: %i", GetName(), item2->ID);
|
||||
Log.Out(Logs::General, Logs::None, "Adding drop to npc: %s, Item: %i", GetName(), item2->ID);
|
||||
#endif
|
||||
|
||||
EQApplicationPacket* outapp = nullptr;
|
||||
@@ -359,6 +364,10 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
entity_list.QueueClients(this, outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
}
|
||||
|
||||
void NPC::AddItem(const Item_Struct* item, uint16 charges, bool equipitem) {
|
||||
|
||||
+7
-7
@@ -242,17 +242,17 @@ void Lua_Client::SetBindPoint(int to_zone, int to_instance) {
|
||||
|
||||
void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetBindPoint(to_zone, to_instance, new_x);
|
||||
self->SetBindPoint(to_zone, to_instance, glm::vec3(new_x,0.0f,0.0f));
|
||||
}
|
||||
|
||||
void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetBindPoint(to_zone, to_instance, new_x, new_y);
|
||||
self->SetBindPoint(to_zone, to_instance, glm::vec3(new_x, new_y, 0.0f));
|
||||
}
|
||||
|
||||
void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y, float new_z) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetBindPoint(to_zone, to_instance, new_x, new_y, new_z);
|
||||
self->SetBindPoint(to_zone, to_instance, glm::vec3(new_x, new_y, new_z));
|
||||
}
|
||||
|
||||
float Lua_Client::GetBindX() {
|
||||
@@ -700,13 +700,13 @@ void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug
|
||||
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5);
|
||||
}
|
||||
|
||||
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
bool attuned) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned);
|
||||
}
|
||||
|
||||
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
bool attuned, int to_slot) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned, to_slot);
|
||||
@@ -834,7 +834,7 @@ void Lua_Client::SetAATitle(const char *title) {
|
||||
|
||||
int Lua_Client::GetClientVersion() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetClientVersion();
|
||||
return static_cast<unsigned int>(self->GetClientVersion());
|
||||
}
|
||||
|
||||
uint32 Lua_Client::GetClientVersionBit() {
|
||||
@@ -1396,7 +1396,7 @@ luabind::scope lua_register_client() {
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32))&Lua_Client::SummonItem)
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32))&Lua_Client::SummonItem)
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool))&Lua_Client::SummonItem)
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool,int))&Lua_Client::SummonItem)
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool,int))&Lua_Client::SummonItem)
|
||||
.def("SetStats", (void(Lua_Client::*)(int,int))&Lua_Client::SetStats)
|
||||
.def("IncStats", (void(Lua_Client::*)(int,int))&Lua_Client::IncStats)
|
||||
.def("DropItem", (void(Lua_Client::*)(int))&Lua_Client::DropItem)
|
||||
|
||||
+16
-8
@@ -20,42 +20,50 @@ const char *Lua_Door::GetDoorName() {
|
||||
|
||||
float Lua_Door::GetX() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetX();
|
||||
return self->GetPosition().x;
|
||||
}
|
||||
|
||||
float Lua_Door::GetY() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetY();
|
||||
return self->GetPosition().y;
|
||||
}
|
||||
|
||||
float Lua_Door::GetZ() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetZ();
|
||||
return self->GetPosition().z;
|
||||
}
|
||||
|
||||
float Lua_Door::GetHeading() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetHeading();
|
||||
return self->GetPosition().w;
|
||||
}
|
||||
|
||||
void Lua_Door::SetX(float x) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetX(x);
|
||||
auto position = self->GetPosition();
|
||||
position.x = x;
|
||||
self->SetPosition(position);
|
||||
}
|
||||
|
||||
void Lua_Door::SetY(float y) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetY(y);
|
||||
auto position = self->GetPosition();
|
||||
position.y = y;
|
||||
self->SetPosition(position);
|
||||
}
|
||||
|
||||
void Lua_Door::SetZ(float z) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetZ(z);
|
||||
auto position = self->GetPosition();
|
||||
position.z = z;
|
||||
self->SetPosition(position);
|
||||
}
|
||||
|
||||
void Lua_Door::SetHeading(float h) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetHeading(h);
|
||||
auto position = self->GetPosition();
|
||||
position.w = h;
|
||||
self->SetPosition(position);
|
||||
}
|
||||
|
||||
void Lua_Door::SetLocation(float x, float y, float z) {
|
||||
|
||||
@@ -298,12 +298,12 @@ void Lua_EntityList::MessageGroup(Lua_Mob who, bool skip_close, uint32 type, con
|
||||
|
||||
Lua_Client Lua_EntityList::GetRandomClient(float x, float y, float z, float dist) {
|
||||
Lua_Safe_Call_Class(Lua_Client);
|
||||
return self->GetRandomClient(x, y, z, dist);
|
||||
return self->GetRandomClient(glm::vec3(x, y, z), dist);
|
||||
}
|
||||
|
||||
Lua_Client Lua_EntityList::GetRandomClient(float x, float y, float z, float dist, Lua_Client exclude) {
|
||||
Lua_Safe_Call_Class(Lua_Client);
|
||||
return self->GetRandomClient(x, y, z, dist, exclude);
|
||||
return self->GetRandomClient(glm::vec3(x, y, z), dist, exclude);
|
||||
}
|
||||
|
||||
Lua_Mob_List Lua_EntityList::GetMobList() {
|
||||
|
||||
+46
-30
@@ -17,6 +17,7 @@
|
||||
#include "questmgr.h"
|
||||
#include "qglobals.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
|
||||
struct Events { };
|
||||
struct Factions { };
|
||||
@@ -124,7 +125,7 @@ void register_event(std::string package_name, std::string name, int evt, luabind
|
||||
e.encounter_name = name;
|
||||
e.lua_reference = func;
|
||||
e.event_id = static_cast<QuestEventID>(evt);
|
||||
|
||||
|
||||
auto liter = lua_encounter_events_registered.find(package_name);
|
||||
if(liter == lua_encounter_events_registered.end()) {
|
||||
std::list<lua_registered_event> elist;
|
||||
@@ -200,8 +201,8 @@ void unregister_player_event(int evt) {
|
||||
|
||||
void register_item_event(std::string name, int evt, int item_id, luabind::adl::object func) {
|
||||
std::string package_name = "item_";
|
||||
package_name += std::to_string(static_cast<long long>(item_id));
|
||||
|
||||
package_name += std::to_string(item_id);
|
||||
|
||||
if(luabind::type(func) == LUA_TFUNCTION) {
|
||||
register_event(package_name, name, evt, func);
|
||||
}
|
||||
@@ -214,7 +215,7 @@ void register_item_event(int evt, int item_id, luabind::adl::object func) {
|
||||
|
||||
void unregister_item_event(std::string name, int evt, int item_id) {
|
||||
std::string package_name = "item_";
|
||||
package_name += std::to_string(static_cast<long long>(item_id));
|
||||
package_name += std::to_string(item_id);
|
||||
|
||||
unregister_event(package_name, name, evt);
|
||||
}
|
||||
@@ -251,13 +252,13 @@ void unregister_spell_event(int evt, int spell_id) {
|
||||
}
|
||||
|
||||
Lua_Mob lua_spawn2(int npc_type, int grid, int unused, double x, double y, double z, double heading) {
|
||||
return Lua_Mob(quest_manager.spawn2(npc_type, grid, unused,
|
||||
static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(heading)));
|
||||
auto position = glm::vec4(x, y, z, heading);
|
||||
return Lua_Mob(quest_manager.spawn2(npc_type, grid, unused, position));
|
||||
}
|
||||
|
||||
Lua_Mob lua_unique_spawn(int npc_type, int grid, int unused, double x, double y, double z, double heading = 0.0) {
|
||||
return Lua_Mob(quest_manager.unique_spawn(npc_type, grid, unused,
|
||||
static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(heading)));
|
||||
auto position = glm::vec4(x, y, z, heading);
|
||||
return Lua_Mob(quest_manager.unique_spawn(npc_type, grid, unused, position));
|
||||
}
|
||||
|
||||
Lua_Mob lua_spawn_from_spawn2(uint32 spawn2_id) {
|
||||
@@ -421,15 +422,15 @@ void lua_pause(int duration) {
|
||||
}
|
||||
|
||||
void lua_move_to(float x, float y, float z) {
|
||||
quest_manager.moveto(x, y, z, 0, false);
|
||||
quest_manager.moveto(glm::vec4(x, y, z, 0.0f), false);
|
||||
}
|
||||
|
||||
void lua_move_to(float x, float y, float z, float h) {
|
||||
quest_manager.moveto(x, y, z, h, false);
|
||||
quest_manager.moveto(glm::vec4(x, y, z, h), false);
|
||||
}
|
||||
|
||||
void lua_move_to(float x, float y, float z, float h, bool save_guard_spot) {
|
||||
quest_manager.moveto(x, y, z, h, save_guard_spot);
|
||||
quest_manager.moveto(glm::vec4(x, y, z, h), save_guard_spot);
|
||||
}
|
||||
|
||||
void lua_path_resume() {
|
||||
@@ -485,11 +486,11 @@ void lua_toggle_spawn_event(int event_id, bool enable, bool strict, bool reset)
|
||||
}
|
||||
|
||||
void lua_summon_burried_player_corpse(uint32 char_id, float x, float y, float z, float h) {
|
||||
quest_manager.summonburriedplayercorpse(char_id, x, y, z, h);
|
||||
quest_manager.summonburriedplayercorpse(char_id, glm::vec4(x, y, z, h));
|
||||
}
|
||||
|
||||
void lua_summon_all_player_corpses(uint32 char_id, float x, float y, float z, float h) {
|
||||
quest_manager.summonallplayercorpses(char_id, x, y, z, h);
|
||||
quest_manager.summonallplayercorpses(char_id, glm::vec4(x, y, z, h));
|
||||
}
|
||||
|
||||
int lua_get_player_burried_corpse_count(uint32 char_id) {
|
||||
@@ -685,23 +686,23 @@ int lua_get_level(int type) {
|
||||
}
|
||||
|
||||
void lua_create_ground_object(uint32 item_id, float x, float y, float z, float h) {
|
||||
quest_manager.CreateGroundObject(item_id, x, y, z, h);
|
||||
quest_manager.CreateGroundObject(item_id, glm::vec4(x, y, z, h));
|
||||
}
|
||||
|
||||
void lua_create_ground_object(uint32 item_id, float x, float y, float z, float h, uint32 decay_time) {
|
||||
quest_manager.CreateGroundObject(item_id, x, y, z, h, decay_time);
|
||||
quest_manager.CreateGroundObject(item_id, glm::vec4(x, y, z, h), decay_time);
|
||||
}
|
||||
|
||||
void lua_create_ground_object_from_model(const char *model, float x, float y, float z, float h) {
|
||||
quest_manager.CreateGroundObjectFromModel(model, x, y, z, h);
|
||||
quest_manager.CreateGroundObjectFromModel(model, glm::vec4(x, y, z, h));
|
||||
}
|
||||
|
||||
void lua_create_ground_object_from_model(const char *model, float x, float y, float z, float h, int type) {
|
||||
quest_manager.CreateGroundObjectFromModel(model, x, y, z, h, type);
|
||||
quest_manager.CreateGroundObjectFromModel(model, glm::vec4(x, y, z, h), type);
|
||||
}
|
||||
|
||||
void lua_create_ground_object_from_model(const char *model, float x, float y, float z, float h, int type, uint32 decay_time) {
|
||||
quest_manager.CreateGroundObjectFromModel(model, x, y, z, h, type, decay_time);
|
||||
quest_manager.CreateGroundObjectFromModel(model, glm::vec4(x, y, z, h), type, decay_time);
|
||||
}
|
||||
|
||||
void lua_create_door(const char *model, float x, float y, float z, float h, int open_type, int size) {
|
||||
@@ -1036,7 +1037,7 @@ void lua_add_spawn_point(luabind::adl::object table) {
|
||||
int condition_min_value = 0;
|
||||
bool enabled = true;
|
||||
int animation = 0;
|
||||
|
||||
|
||||
auto cur = table["spawn2_id"];
|
||||
if(luabind::type(cur) != LUA_TNIL) {
|
||||
try {
|
||||
@@ -1221,7 +1222,6 @@ std::string lua_get_encounter() {
|
||||
return quest_manager.GetEncounter();
|
||||
}
|
||||
|
||||
|
||||
void lua_map_opcodes() {
|
||||
MapOpcodes();
|
||||
}
|
||||
@@ -1249,6 +1249,17 @@ double lua_clock() {
|
||||
return static_cast<double>(t) / 1000.0;
|
||||
}
|
||||
|
||||
void lua_debug(std::string message) {
|
||||
Log.Out(Logs::General, Logs::QuestDebug, message);
|
||||
}
|
||||
|
||||
void lua_debug(std::string message, int level) {
|
||||
if (level < Logs::General || level > Logs::Detail)
|
||||
return;
|
||||
|
||||
Log.Out(static_cast<Logs::DebugLevel>(level), Logs::QuestDebug, message);
|
||||
}
|
||||
|
||||
#define LuaCreateNPCParse(name, c_type, default_value) do { \
|
||||
cur = table[#name]; \
|
||||
if(luabind::type(cur) != LUA_TNIL) { \
|
||||
@@ -1284,7 +1295,7 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
|
||||
if(luabind::type(table) != LUA_TTABLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
NPCType* npc_type = new NPCType;
|
||||
memset(npc_type, 0, sizeof(NPCType));
|
||||
|
||||
@@ -1356,7 +1367,7 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
|
||||
LuaCreateNPCParseString(special_abilities, 512, "");
|
||||
LuaCreateNPCParse(d_melee_texture1, uint16, 0);
|
||||
LuaCreateNPCParse(d_melee_texture2, uint16, 0);
|
||||
LuaCreateNPCParseString(ammo_idfile, 32, "");
|
||||
LuaCreateNPCParseString(ammo_idfile, 30, "");
|
||||
LuaCreateNPCParse(prim_melee_type, uint8, 0);
|
||||
LuaCreateNPCParse(sec_melee_type, uint8, 0);
|
||||
LuaCreateNPCParse(ranged_type, uint8, 0);
|
||||
@@ -1391,7 +1402,7 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
|
||||
LuaCreateNPCParse(raid_target, bool, false);
|
||||
LuaCreateNPCParse(probability, uint8, 0);
|
||||
|
||||
NPC* npc = new NPC(npc_type, nullptr, x, y, z, heading, FlyMode3);
|
||||
NPC* npc = new NPC(npc_type, nullptr, glm::vec4(x, y, z, heading), FlyMode3);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
entity_list.AddNPC(npc);
|
||||
}
|
||||
@@ -1582,7 +1593,9 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("disable_recipe", &lua_disable_recipe),
|
||||
luabind::def("clear_npctype_cache", &lua_clear_npctype_cache),
|
||||
luabind::def("clock", &lua_clock),
|
||||
luabind::def("create_npc", &lua_create_npc)
|
||||
luabind::def("create_npc", &lua_create_npc),
|
||||
luabind::def("debug", (void(*)(std::string))&lua_debug),
|
||||
luabind::def("debug", (void(*)(std::string, int))&lua_debug)
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1612,6 +1625,7 @@ luabind::scope lua_register_events() {
|
||||
luabind::value("cast_on", static_cast<int>(EVENT_CAST_ON)),
|
||||
luabind::value("task_accepted", static_cast<int>(EVENT_TASK_ACCEPTED)),
|
||||
luabind::value("task_stage_complete", static_cast<int>(EVENT_TASK_STAGE_COMPLETE)),
|
||||
luabind::value("environmental_damage", static_cast<int>(EVENT_ENVIRONMENTAL_DAMAGE)),
|
||||
luabind::value("task_update", static_cast<int>(EVENT_TASK_UPDATE)),
|
||||
luabind::value("task_complete", static_cast<int>(EVENT_TASK_COMPLETE)),
|
||||
luabind::value("task_fail", static_cast<int>(EVENT_TASK_FAIL)),
|
||||
@@ -1758,12 +1772,14 @@ luabind::scope lua_register_client_version() {
|
||||
return luabind::class_<ClientVersions>("ClientVersion")
|
||||
.enum_("constants")
|
||||
[
|
||||
luabind::value("Unknown", static_cast<int>(EQClientUnknown)),
|
||||
luabind::value("Titanium", static_cast<int>(EQClientTitanium)),
|
||||
luabind::value("SoF", static_cast<int>(EQClientSoF)),
|
||||
luabind::value("SoD", static_cast<int>(EQClientSoD)),
|
||||
luabind::value("Underfoot", static_cast<int>(EQClientUnderfoot)),
|
||||
luabind::value("RoF", static_cast<int>(EQClientRoF))
|
||||
luabind::value("Unknown", static_cast<int>(ClientVersion::Unknown)),
|
||||
luabind::value("Titanium", static_cast<int>(ClientVersion::Titanium)),
|
||||
luabind::value("SoF", static_cast<int>(ClientVersion::SoF)),
|
||||
luabind::value("SoD", static_cast<int>(ClientVersion::SoD)),
|
||||
luabind::value("Underfoot", static_cast<int>(ClientVersion::UF)), // deprecated
|
||||
luabind::value("UF", static_cast<int>(ClientVersion::UF)),
|
||||
luabind::value("RoF", static_cast<int>(ClientVersion::RoF)),
|
||||
luabind::value("RoF2", static_cast<int>(ClientVersion::RoF2))
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
+22
-16
@@ -576,6 +576,11 @@ int Lua_Mob::GetCorruption() {
|
||||
return self->GetCorrup();
|
||||
}
|
||||
|
||||
int Lua_Mob::GetPhR() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetPhR();
|
||||
}
|
||||
|
||||
int Lua_Mob::GetMaxSTR() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMaxSTR();
|
||||
@@ -626,7 +631,7 @@ double Lua_Mob::ResistSpell(int resist_type, int spell_id, Lua_Mob caster, bool
|
||||
return self->ResistSpell(resist_type, spell_id, caster, use_resist_override, resist_override);
|
||||
}
|
||||
|
||||
double Lua_Mob::ResistSpell(int resist_type, int spell_id, Lua_Mob caster, bool use_resist_override, int resist_override,
|
||||
double Lua_Mob::ResistSpell(int resist_type, int spell_id, Lua_Mob caster, bool use_resist_override, int resist_override,
|
||||
bool charisma_check) {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->ResistSpell(resist_type, spell_id, caster, use_resist_override, resist_override, charisma_check);
|
||||
@@ -669,22 +674,22 @@ double Lua_Mob::GetHeading() {
|
||||
|
||||
double Lua_Mob::GetWaypointX() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetCWPX();
|
||||
return self->GetCurrentWayPoint().x;
|
||||
}
|
||||
|
||||
double Lua_Mob::GetWaypointY() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetCWPY();
|
||||
return self->GetCurrentWayPoint().y;
|
||||
}
|
||||
|
||||
double Lua_Mob::GetWaypointZ() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetCWPZ();
|
||||
return self->GetCurrentWayPoint().z;
|
||||
}
|
||||
|
||||
double Lua_Mob::GetWaypointH() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetCWPH();
|
||||
return self->GetCurrentWayPoint().w;
|
||||
}
|
||||
|
||||
double Lua_Mob::GetWaypointPause() {
|
||||
@@ -772,19 +777,19 @@ bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, in
|
||||
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot));
|
||||
}
|
||||
|
||||
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer,
|
||||
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer,
|
||||
int timer_duration) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
|
||||
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
|
||||
static_cast<uint32>(timer), static_cast<uint32>(timer_duration));
|
||||
}
|
||||
|
||||
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer,
|
||||
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer,
|
||||
int timer_duration, int resist_adjust) {
|
||||
Lua_Safe_Call_Bool();
|
||||
int16 res = resist_adjust;
|
||||
|
||||
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
|
||||
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
|
||||
static_cast<uint32>(timer), static_cast<uint32>(timer_duration), 0, &res);
|
||||
}
|
||||
|
||||
@@ -836,7 +841,7 @@ Lua_Mob Lua_Mob::GetOwner() {
|
||||
Lua_HateList Lua_Mob::GetHateList() {
|
||||
Lua_Safe_Call_Class(Lua_HateList);
|
||||
Lua_HateList ret;
|
||||
|
||||
|
||||
auto h_list = self->GetHateList();
|
||||
auto iter = h_list.begin();
|
||||
while(iter != h_list.end()) {
|
||||
@@ -1217,7 +1222,7 @@ bool Lua_Mob::EntityVariableExists(const char *name) {
|
||||
|
||||
void Lua_Mob::Signal(uint32 id) {
|
||||
Lua_Safe_Call_Void();
|
||||
|
||||
|
||||
if(self->IsClient()) {
|
||||
self->CastToClient()->Signal(id);
|
||||
} else if(self->IsNPC()) {
|
||||
@@ -1250,7 +1255,7 @@ void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, in
|
||||
self->DoSpecialAttackDamage(other, static_cast<SkillUseTypes>(skill), max_damage, min_damage, hate_override, reuse_time);
|
||||
}
|
||||
|
||||
void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override, int reuse_time,
|
||||
void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override, int reuse_time,
|
||||
bool hit_chance) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->DoSpecialAttackDamage(other, static_cast<SkillUseTypes>(skill), max_damage, min_damage, hate_override, reuse_time, hit_chance);
|
||||
@@ -1281,7 +1286,7 @@ void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_
|
||||
self->DoThrowingAttackDmg(other, range_weapon, item, weapon_damage, chance_mod);
|
||||
}
|
||||
|
||||
void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_Item item, int weapon_damage, int chance_mod,
|
||||
void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_Item item, int weapon_damage, int chance_mod,
|
||||
int focus) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->DoThrowingAttackDmg(other, range_weapon, item, weapon_damage, chance_mod, focus);
|
||||
@@ -1332,7 +1337,7 @@ void Lua_Mob::DoArcheryAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_I
|
||||
self->DoArcheryAttackDmg(other, range_weapon, ammo, weapon_damage, chance_mod);
|
||||
}
|
||||
|
||||
void Lua_Mob::DoArcheryAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_ItemInst ammo, int weapon_damage, int chance_mod,
|
||||
void Lua_Mob::DoArcheryAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_ItemInst ammo, int weapon_damage, int chance_mod,
|
||||
int focus) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->DoArcheryAttackDmg(other, range_weapon, ammo, weapon_damage, chance_mod, focus);
|
||||
@@ -1390,7 +1395,7 @@ void Lua_Mob::ProjectileAnimation(Lua_Mob to, int item_id, bool is_arrow, double
|
||||
|
||||
void Lua_Mob::ProjectileAnimation(Lua_Mob to, int item_id, bool is_arrow, double speed, double angle, double tilt, double arc) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->ProjectileAnimation(to, item_id, is_arrow, static_cast<float>(speed), static_cast<float>(angle), static_cast<float>(tilt),
|
||||
self->ProjectileAnimation(to, item_id, is_arrow, static_cast<float>(speed), static_cast<float>(angle), static_cast<float>(tilt),
|
||||
static_cast<float>(arc));
|
||||
}
|
||||
|
||||
@@ -1630,7 +1635,7 @@ void Lua_Mob::SendSpellEffect(uint32 effect_id, uint32 duration, uint32 finish_d
|
||||
self->SendSpellEffect(effect_id, duration, finish_delay, zone_wide, unk020, perm_effect);
|
||||
}
|
||||
|
||||
void Lua_Mob::SendSpellEffect(uint32 effect_id, uint32 duration, uint32 finish_delay, bool zone_wide, uint32 unk020, bool perm_effect,
|
||||
void Lua_Mob::SendSpellEffect(uint32 effect_id, uint32 duration, uint32 finish_delay, bool zone_wide, uint32 unk020, bool perm_effect,
|
||||
Lua_Client c) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SendSpellEffect(effect_id, duration, finish_delay, zone_wide, unk020, perm_effect, c);
|
||||
@@ -1962,6 +1967,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("GetPR", &Lua_Mob::GetPR)
|
||||
.def("GetCR", &Lua_Mob::GetCR)
|
||||
.def("GetCorruption", &Lua_Mob::GetCorruption)
|
||||
.def("GetPhR", &Lua_Mob::GetPhR)
|
||||
.def("GetMaxSTR", &Lua_Mob::GetMaxSTR)
|
||||
.def("GetMaxSTA", &Lua_Mob::GetMaxSTA)
|
||||
.def("GetMaxDEX", &Lua_Mob::GetMaxDEX)
|
||||
|
||||
@@ -128,6 +128,7 @@ public:
|
||||
int GetPR();
|
||||
int GetCR();
|
||||
int GetCorruption();
|
||||
int GetPhR();
|
||||
int GetMaxSTR();
|
||||
int GetMaxSTA();
|
||||
int GetMaxDEX();
|
||||
|
||||
+9
-8
@@ -269,7 +269,8 @@ void Lua_NPC::PauseWandering(int pause_time) {
|
||||
|
||||
void Lua_NPC::MoveTo(float x, float y, float z, float h, bool save) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->MoveTo(x, y, z, h, save);
|
||||
auto position = glm::vec4(x, y, z, h);
|
||||
self->MoveTo(position, save);
|
||||
}
|
||||
|
||||
void Lua_NPC::NextGuardPosition() {
|
||||
@@ -314,37 +315,37 @@ int Lua_NPC::GetSpawnPointID() {
|
||||
|
||||
float Lua_NPC::GetSpawnPointX() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetSpawnPointX();
|
||||
return self->GetSpawnPoint().x;
|
||||
}
|
||||
|
||||
float Lua_NPC::GetSpawnPointY() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetSpawnPointY();
|
||||
return self->GetSpawnPoint().y;
|
||||
}
|
||||
|
||||
float Lua_NPC::GetSpawnPointZ() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetSpawnPointZ();
|
||||
return self->GetSpawnPoint().z;
|
||||
}
|
||||
|
||||
float Lua_NPC::GetSpawnPointH() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetSpawnPointH();
|
||||
return self->GetSpawnPoint().w;
|
||||
}
|
||||
|
||||
float Lua_NPC::GetGuardPointX() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetGuardPointX();
|
||||
return self->GetGuardPoint().x;
|
||||
}
|
||||
|
||||
float Lua_NPC::GetGuardPointY() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetGuardPointY();
|
||||
return self->GetGuardPoint().y;
|
||||
}
|
||||
|
||||
float Lua_NPC::GetGuardPointZ() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetGuardPointZ();
|
||||
return self->GetGuardPoint().z;
|
||||
}
|
||||
|
||||
void Lua_NPC::SetPrimSkill(int skill_id) {
|
||||
|
||||
+19
-17
@@ -67,6 +67,7 @@ const char *LuaEvents[_LargestEventID] = {
|
||||
"event_aggro_say",
|
||||
"event_player_pickup",
|
||||
"event_popup_response",
|
||||
"event_environmental_damage",
|
||||
"event_proximity_say",
|
||||
"event_cast",
|
||||
"event_cast_begin",
|
||||
@@ -164,6 +165,7 @@ LuaParser::LuaParser() {
|
||||
NPCArgumentDispatch[EVENT_LEAVE_AREA] = handle_npc_area;
|
||||
|
||||
PlayerArgumentDispatch[EVENT_SAY] = handle_player_say;
|
||||
PlayerArgumentDispatch[EVENT_ENVIRONMENTAL_DAMAGE] = handle_player_environmental_damage;
|
||||
PlayerArgumentDispatch[EVENT_DEATH] = handle_player_death;
|
||||
PlayerArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_player_death;
|
||||
PlayerArgumentDispatch[EVENT_TIMER] = handle_player_timer;
|
||||
@@ -235,7 +237,7 @@ int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string package_name = "npc_" + std::to_string(static_cast<long long>(npc->GetNPCTypeID()));
|
||||
std::string package_name = "npc_" + std::to_string(npc->GetNPCTypeID());
|
||||
return _EventNPC(package_name, evt, npc, init, data, extra_data, extra_pointers);
|
||||
}
|
||||
|
||||
@@ -425,7 +427,7 @@ int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *
|
||||
}
|
||||
|
||||
std::string package_name = "item_";
|
||||
package_name += std::to_string(static_cast<long long>(item->GetID()));
|
||||
package_name += std::to_string(item->GetID());
|
||||
return _EventItem(package_name, evt, client, item, mob, data, extra_data, extra_pointers);
|
||||
}
|
||||
|
||||
@@ -499,12 +501,12 @@ int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spe
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string package_name = "spell_" + std::to_string(static_cast<long long>(spell_id));
|
||||
std::string package_name = "spell_" + std::to_string(spell_id);
|
||||
|
||||
if(!SpellHasQuestSub(spell_id, evt)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return _EventSpell(package_name, evt, npc, client, spell_id, extra_data, extra_pointers);
|
||||
}
|
||||
|
||||
@@ -646,7 +648,7 @@ bool LuaParser::HasQuestSub(uint32 npc_id, QuestEventID evt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string package_name = "npc_" + std::to_string(static_cast<long long>(npc_id));
|
||||
std::string package_name = "npc_" + std::to_string(npc_id);
|
||||
|
||||
const char *subname = LuaEvents[evt];
|
||||
return HasFunction(subname, package_name);
|
||||
@@ -688,7 +690,7 @@ bool LuaParser::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string package_name = "spell_" + std::to_string(static_cast<long long>(spell_id));
|
||||
std::string package_name = "spell_" + std::to_string(spell_id);
|
||||
|
||||
const char *subname = LuaEvents[evt];
|
||||
return HasFunction(subname, package_name);
|
||||
@@ -704,7 +706,7 @@ bool LuaParser::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) {
|
||||
}
|
||||
|
||||
std::string package_name = "item_";
|
||||
package_name += std::to_string(static_cast<long long>(itm->GetID()));
|
||||
package_name += std::to_string(itm->GetID());
|
||||
|
||||
const char *subname = LuaEvents[evt];
|
||||
return HasFunction(subname, package_name);
|
||||
@@ -723,7 +725,7 @@ bool LuaParser::EncounterHasQuestSub(std::string encounter_name, QuestEventID ev
|
||||
}
|
||||
|
||||
void LuaParser::LoadNPCScript(std::string filename, int npc_id) {
|
||||
std::string package_name = "npc_" + std::to_string(static_cast<long long>(npc_id));
|
||||
std::string package_name = "npc_" + std::to_string(npc_id);
|
||||
|
||||
LoadScript(filename, package_name);
|
||||
}
|
||||
@@ -744,13 +746,13 @@ void LuaParser::LoadItemScript(std::string filename, ItemInst *item) {
|
||||
if (item == nullptr)
|
||||
return;
|
||||
std::string package_name = "item_";
|
||||
package_name += std::to_string(static_cast<long long>(item->GetID()));
|
||||
package_name += std::to_string(item->GetID());
|
||||
|
||||
LoadScript(filename, package_name);
|
||||
}
|
||||
|
||||
void LuaParser::LoadSpellScript(std::string filename, uint32 spell_id) {
|
||||
std::string package_name = "spell_" + std::to_string(static_cast<long long>(spell_id));
|
||||
std::string package_name = "spell_" + std::to_string(spell_id);
|
||||
|
||||
LoadScript(filename, package_name);
|
||||
}
|
||||
@@ -1011,8 +1013,8 @@ int LuaParser::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::stri
|
||||
if(!npc)
|
||||
return 0;
|
||||
|
||||
std::string package_name = "npc_" + std::to_string(static_cast<long long>(npc->GetNPCTypeID()));
|
||||
int ret = 0;
|
||||
std::string package_name = "npc_" + std::to_string(npc->GetNPCTypeID());
|
||||
int ret = 0;
|
||||
|
||||
auto iter = lua_encounter_events_registered.find(package_name);
|
||||
if(iter != lua_encounter_events_registered.end()) {
|
||||
@@ -1085,11 +1087,11 @@ int LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *ite
|
||||
|
||||
if(!item)
|
||||
return 0;
|
||||
|
||||
|
||||
std::string package_name = "item_";
|
||||
package_name += std::to_string(static_cast<long long>(item->GetID()));
|
||||
int ret = 0;
|
||||
|
||||
package_name += std::to_string(item->GetID());
|
||||
int ret = 0;
|
||||
|
||||
auto iter = lua_encounter_events_registered.find(package_name);
|
||||
if(iter != lua_encounter_events_registered.end()) {
|
||||
auto riter = iter->second.begin();
|
||||
@@ -1129,7 +1131,7 @@ int LuaParser::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, ui
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string package_name = "spell_" + std::to_string(static_cast<long long>(spell_id));
|
||||
std::string package_name = "spell_" + std::to_string(spell_id);
|
||||
|
||||
int ret = 0;
|
||||
auto iter = lua_encounter_events_registered.find(package_name);
|
||||
|
||||
@@ -56,7 +56,7 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *
|
||||
if(extra_pointers) {
|
||||
size_t sz = extra_pointers->size();
|
||||
for(size_t i = 0; i < sz; ++i) {
|
||||
std::string prefix = "item" + std::to_string(static_cast<long long>(i + 1));
|
||||
std::string prefix = "item" + std::to_string(i + 1);
|
||||
ItemInst *inst = EQEmu::any_cast<ItemInst*>(extra_pointers->at(i));
|
||||
|
||||
Lua_ItemInst l_inst = inst;
|
||||
@@ -246,6 +246,19 @@ void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std:
|
||||
lua_setfield(L, -2, "language");
|
||||
}
|
||||
|
||||
void handle_player_environmental_damage(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers){
|
||||
Seperator sep(data.c_str());
|
||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
||||
lua_setfield(L, -2, "env_damage");
|
||||
|
||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
||||
lua_setfield(L, -2, "env_damage_type");
|
||||
|
||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
||||
lua_setfield(L, -2, "env_final_damage");
|
||||
}
|
||||
|
||||
void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers) {
|
||||
Seperator sep(data.c_str());
|
||||
|
||||
@@ -44,6 +44,8 @@ void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, s
|
||||
//Player
|
||||
void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
void handle_player_environmental_damage(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||
|
||||
+41
-41
@@ -1,4 +1,4 @@
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/misc_functions.h"
|
||||
|
||||
#include "map.h"
|
||||
@@ -62,17 +62,17 @@ Map::~Map() {
|
||||
}
|
||||
}
|
||||
|
||||
float Map::FindBestZ(Vertex &start, Vertex *result) const {
|
||||
float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result) const {
|
||||
if (!imp)
|
||||
return false;
|
||||
|
||||
Vertex tmp;
|
||||
glm::vec3 tmp;
|
||||
if(!result)
|
||||
result = &tmp;
|
||||
|
||||
start.z += RuleI(Map, FindBestZHeightAdjust);
|
||||
Vertex from(start.x, start.y, start.z);
|
||||
Vertex to(start.x, start.y, BEST_Z_INVALID);
|
||||
glm::vec3 from(start.x, start.y, start.z);
|
||||
glm::vec3 to(start.x, start.y, BEST_Z_INVALID);
|
||||
float hit_distance;
|
||||
bool hit = false;
|
||||
|
||||
@@ -93,19 +93,19 @@ float Map::FindBestZ(Vertex &start, Vertex *result) const {
|
||||
return BEST_Z_INVALID;
|
||||
}
|
||||
|
||||
bool Map::LineIntersectsZone(Vertex start, Vertex end, float step, Vertex *result) const {
|
||||
bool Map::LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const {
|
||||
if(!imp)
|
||||
return false;
|
||||
return imp->rm->raycast((const RmReal*)&start, (const RmReal*)&end, (RmReal*)result, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool Map::LineIntersectsZoneNoZLeaps(Vertex start, Vertex end, float step_mag, Vertex *result) const {
|
||||
bool Map::LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const {
|
||||
if (!imp)
|
||||
return false;
|
||||
|
||||
float z = BEST_Z_INVALID;
|
||||
Vertex step;
|
||||
Vertex cur;
|
||||
glm::vec3 step;
|
||||
glm::vec3 cur;
|
||||
cur.x = start.x;
|
||||
cur.y = start.y;
|
||||
cur.z = start.z;
|
||||
@@ -139,11 +139,11 @@ bool Map::LineIntersectsZoneNoZLeaps(Vertex start, Vertex end, float step_mag, V
|
||||
while(cur.x != end.x || cur.y != end.y || cur.z != end.z)
|
||||
{
|
||||
steps++;
|
||||
Vertex me;
|
||||
glm::vec3 me;
|
||||
me.x = cur.x;
|
||||
me.y = cur.y;
|
||||
me.z = cur.z;
|
||||
Vertex hit;
|
||||
glm::vec3 hit;
|
||||
|
||||
float best_z = FindBestZ(me, &hit);
|
||||
float diff = best_z - z;
|
||||
@@ -184,7 +184,7 @@ bool Map::LineIntersectsZoneNoZLeaps(Vertex start, Vertex end, float step_mag, V
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Map::CheckLoS(Vertex myloc, Vertex oloc) const {
|
||||
bool Map::CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const {
|
||||
if(!imp)
|
||||
return false;
|
||||
|
||||
@@ -250,22 +250,22 @@ bool Map::LoadV1(FILE *f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<Vertex> verts;
|
||||
std::vector<glm::vec3> verts;
|
||||
std::vector<uint32> indices;
|
||||
for(uint32 i = 0; i < face_count; ++i) {
|
||||
Vertex a;
|
||||
Vertex b;
|
||||
Vertex c;
|
||||
glm::vec3 a;
|
||||
glm::vec3 b;
|
||||
glm::vec3 c;
|
||||
float normals[4];
|
||||
if(fread(&a, sizeof(Vertex), 1, f) != 1) {
|
||||
if(fread(&a, sizeof(glm::vec3), 1, f) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fread(&b, sizeof(Vertex), 1, f) != 1) {
|
||||
if(fread(&b, sizeof(glm::vec3), 1, f) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fread(&c, sizeof(Vertex), 1, f) != 1) {
|
||||
if(fread(&c, sizeof(glm::vec3), 1, f) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ struct ModelEntry
|
||||
uint32 v1, v2, v3;
|
||||
uint8 vis;
|
||||
};
|
||||
std::vector<Map::Vertex> verts;
|
||||
std::vector<glm::vec3> verts;
|
||||
std::vector<Poly> polys;
|
||||
};
|
||||
|
||||
@@ -376,7 +376,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
units_per_vertex = *(float*)buf;
|
||||
buf += sizeof(float);
|
||||
|
||||
std::vector<Vertex> verts;
|
||||
std::vector<glm::vec3> verts;
|
||||
std::vector<uint32> indices;
|
||||
|
||||
for (uint32 i = 0; i < vert_count; ++i) {
|
||||
@@ -393,7 +393,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
z = *(float*)buf;
|
||||
buf += sizeof(float);
|
||||
|
||||
Vertex vert(x, y, z);
|
||||
glm::vec3 vert(x, y, z);
|
||||
verts.push_back(vert);
|
||||
}
|
||||
|
||||
@@ -413,9 +413,9 @@ bool Map::LoadV2(FILE *f) {
|
||||
buf += sizeof(uint32);
|
||||
}
|
||||
|
||||
std::map<std::string, std::shared_ptr<ModelEntry>> models;
|
||||
std::map<std::string, std::unique_ptr<ModelEntry>> models;
|
||||
for (uint32 i = 0; i < model_count; ++i) {
|
||||
std::shared_ptr<ModelEntry> me(new ModelEntry);
|
||||
std::unique_ptr<ModelEntry> me(new ModelEntry);
|
||||
std::string name = buf;
|
||||
buf += name.length() + 1;
|
||||
|
||||
@@ -434,7 +434,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
float z = *(float*)buf;
|
||||
buf += sizeof(float);
|
||||
|
||||
me->verts[j] = Vertex(x, y, z);
|
||||
me->verts[j] = glm::vec3(x, y, z);
|
||||
}
|
||||
|
||||
me->polys.resize(poly_count);
|
||||
@@ -456,7 +456,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
me->polys[j] = p;
|
||||
}
|
||||
|
||||
models[name] = me;
|
||||
models[name] = std::move(me);
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < plac_count; ++i) {
|
||||
@@ -487,7 +487,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
if (models.count(name) == 0)
|
||||
continue;
|
||||
|
||||
auto model = models[name];
|
||||
auto &model = models[name];
|
||||
auto &mod_polys = model->polys;
|
||||
auto &mod_verts = model->verts;
|
||||
for (uint32 j = 0; j < mod_polys.size(); ++j) {
|
||||
@@ -596,7 +596,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
|
||||
for (size_t k = 0; k < model->polys.size(); ++k) {
|
||||
auto &poly = model->polys[k];
|
||||
Vertex v1, v2, v3;
|
||||
glm::vec3 v1, v2, v3;
|
||||
|
||||
v1 = model->verts[poly.v1];
|
||||
v2 = model->verts[poly.v2];
|
||||
@@ -618,7 +618,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
RotateVertex(v2, 0, y_rot * 3.14159f / 180.0f, 0);
|
||||
RotateVertex(v3, 0, y_rot * 3.14159f / 180.0f, 0);
|
||||
|
||||
Vertex correction(p_x, p_y, p_z);
|
||||
glm::vec3 correction(p_x, p_y, p_z);
|
||||
|
||||
RotateVertex(correction, x_rot * 3.14159f / 180.0f, 0, 0);
|
||||
|
||||
@@ -724,10 +724,10 @@ bool Map::LoadV2(FILE *f) {
|
||||
float QuadVertex4Z = QuadVertex1Z;
|
||||
|
||||
uint32 current_vert = (uint32)verts.size() + 3;
|
||||
verts.push_back(Vertex(QuadVertex1X, QuadVertex1Y, QuadVertex1Z));
|
||||
verts.push_back(Vertex(QuadVertex2X, QuadVertex2Y, QuadVertex2Z));
|
||||
verts.push_back(Vertex(QuadVertex3X, QuadVertex3Y, QuadVertex3Z));
|
||||
verts.push_back(Vertex(QuadVertex4X, QuadVertex4Y, QuadVertex4Z));
|
||||
verts.push_back(glm::vec3(QuadVertex1X, QuadVertex1Y, QuadVertex1Z));
|
||||
verts.push_back(glm::vec3(QuadVertex2X, QuadVertex2Y, QuadVertex2Z));
|
||||
verts.push_back(glm::vec3(QuadVertex3X, QuadVertex3Y, QuadVertex3Z));
|
||||
verts.push_back(glm::vec3(QuadVertex4X, QuadVertex4Y, QuadVertex4Z));
|
||||
|
||||
indices.push_back(current_vert);
|
||||
indices.push_back(current_vert - 2);
|
||||
@@ -790,7 +790,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
}
|
||||
else {
|
||||
i1 = (uint32)verts.size();
|
||||
verts.push_back(Vertex(QuadVertex1X, QuadVertex1Y, QuadVertex1Z));
|
||||
verts.push_back(glm::vec3(QuadVertex1X, QuadVertex1Y, QuadVertex1Z));
|
||||
cur_verts[std::make_tuple(QuadVertex1X, QuadVertex1Y, QuadVertex1Z)] = i1;
|
||||
}
|
||||
|
||||
@@ -801,7 +801,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
}
|
||||
else {
|
||||
i2 = (uint32)verts.size();
|
||||
verts.push_back(Vertex(QuadVertex2X, QuadVertex2Y, QuadVertex2Z));
|
||||
verts.push_back(glm::vec3(QuadVertex2X, QuadVertex2Y, QuadVertex2Z));
|
||||
cur_verts[std::make_tuple(QuadVertex2X, QuadVertex2Y, QuadVertex2Z)] = i2;
|
||||
}
|
||||
|
||||
@@ -812,7 +812,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
}
|
||||
else {
|
||||
i3 = (uint32)verts.size();
|
||||
verts.push_back(Vertex(QuadVertex3X, QuadVertex3Y, QuadVertex3Z));
|
||||
verts.push_back(glm::vec3(QuadVertex3X, QuadVertex3Y, QuadVertex3Z));
|
||||
cur_verts[std::make_tuple(QuadVertex3X, QuadVertex3Y, QuadVertex3Z)] = i3;
|
||||
}
|
||||
|
||||
@@ -823,7 +823,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
}
|
||||
else {
|
||||
i4 = (uint32)verts.size();
|
||||
verts.push_back(Vertex(QuadVertex4X, QuadVertex4Y, QuadVertex4Z));
|
||||
verts.push_back(glm::vec3(QuadVertex4X, QuadVertex4Y, QuadVertex4Z));
|
||||
cur_verts[std::make_tuple(QuadVertex4X, QuadVertex4Y, QuadVertex4Z)] = i4;
|
||||
}
|
||||
|
||||
@@ -859,8 +859,8 @@ bool Map::LoadV2(FILE *f) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Map::RotateVertex(Vertex &v, float rx, float ry, float rz) {
|
||||
Vertex nv = v;
|
||||
void Map::RotateVertex(glm::vec3 &v, float rx, float ry, float rz) {
|
||||
glm::vec3 nv = v;
|
||||
|
||||
nv.y = (cos(rx) * v.y) - (sin(rx) * v.z);
|
||||
nv.z = (sin(rx) * v.y) + (cos(rx) * v.z);
|
||||
@@ -878,13 +878,13 @@ void Map::RotateVertex(Vertex &v, float rx, float ry, float rz) {
|
||||
v = nv;
|
||||
}
|
||||
|
||||
void Map::ScaleVertex(Vertex &v, float sx, float sy, float sz) {
|
||||
void Map::ScaleVertex(glm::vec3 &v, float sx, float sy, float sz) {
|
||||
v.x = v.x * sx;
|
||||
v.y = v.y * sy;
|
||||
v.z = v.z * sz;
|
||||
}
|
||||
|
||||
void Map::TranslateVertex(Vertex &v, float tx, float ty, float tz) {
|
||||
void Map::TranslateVertex(glm::vec3 &v, float tx, float ty, float tz) {
|
||||
v.x = v.x + tx;
|
||||
v.y = v.y + ty;
|
||||
v.z = v.z + tz;
|
||||
|
||||
+10
-26
@@ -22,6 +22,7 @@
|
||||
#ifndef ZONE_MAP_H
|
||||
#define ZONE_MAP_H
|
||||
|
||||
#include "position.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define BEST_Z_INVALID -99999
|
||||
@@ -29,39 +30,22 @@
|
||||
class Map
|
||||
{
|
||||
public:
|
||||
#pragma pack(1)
|
||||
struct Vertex
|
||||
{
|
||||
Vertex() : x(0.0f), y(0.0f), z(0.0f) { }
|
||||
Vertex(float _x, float _y, float _z) : x(_x), y(_y), z(_z) { }
|
||||
~Vertex() { }
|
||||
bool operator==(const Vertex &v) const
|
||||
{
|
||||
return((v.x == x) && (v.y == y) && (v.z == z));
|
||||
}
|
||||
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
Map();
|
||||
~Map();
|
||||
|
||||
float FindBestZ(Vertex &start, Vertex *result) const;
|
||||
bool LineIntersectsZone(Vertex start, Vertex end, float step, Vertex *result) const;
|
||||
bool LineIntersectsZoneNoZLeaps(Vertex start, Vertex end, float step_mag, Vertex *result) const;
|
||||
bool CheckLoS(Vertex myloc, Vertex oloc) const;
|
||||
|
||||
float FindBestZ(glm::vec3 &start, glm::vec3 *result) const;
|
||||
bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const;
|
||||
bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const;
|
||||
bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const;
|
||||
bool Load(std::string filename);
|
||||
static Map *LoadMapFile(std::string file);
|
||||
private:
|
||||
void RotateVertex(Vertex &v, float rx, float ry, float rz);
|
||||
void ScaleVertex(Vertex &v, float sx, float sy, float sz);
|
||||
void TranslateVertex(Vertex &v, float tx, float ty, float tz);
|
||||
void RotateVertex(glm::vec3 &v, float rx, float ry, float rz);
|
||||
void ScaleVertex(glm::vec3 &v, float sx, float sy, float sz);
|
||||
void TranslateVertex(glm::vec3 &v, float tx, float ty, float tz);
|
||||
bool LoadV1(FILE *f);
|
||||
bool LoadV2(FILE *f);
|
||||
|
||||
|
||||
struct impl;
|
||||
impl *imp;
|
||||
};
|
||||
|
||||
+2868
-2302
File diff suppressed because it is too large
Load Diff
+342
-213
File diff suppressed because it is too large
Load Diff
+4
-2
@@ -13,7 +13,6 @@ struct MercTemplate;
|
||||
struct NPCType;
|
||||
struct NewSpawn_Struct;
|
||||
|
||||
#define MERC_DEBUG 0
|
||||
#define MAXMERCS 1
|
||||
#define TANK 1
|
||||
#define HEALER 2
|
||||
@@ -138,8 +137,9 @@ public:
|
||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
static Merc* LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, bool updateFromDB = false);
|
||||
void UpdateMercInfo(Client *c);
|
||||
void UpdateMercStats(Client *c);
|
||||
void UpdateMercStats(Client *c, bool setmax = false);
|
||||
void UpdateMercAppearance();
|
||||
virtual void UpdateEquipLightValue();
|
||||
void AddItem(uint8 slot, uint32 item_id);
|
||||
static const char *GetRandomName();
|
||||
bool Spawn(Client *owner);
|
||||
@@ -189,6 +189,7 @@ public:
|
||||
bool TryHide();
|
||||
|
||||
// stat functions
|
||||
virtual void ScaleStats(int scalepercent, bool setmax = false);
|
||||
virtual void CalcBonuses();
|
||||
int32 GetEndurance() const {return cur_end;} //This gets our current endurance
|
||||
inline virtual int32 GetAC() const { return AC; }
|
||||
@@ -347,6 +348,7 @@ private:
|
||||
|
||||
// Private "base stats" Members
|
||||
int32 base_mana;
|
||||
int32 base_end;
|
||||
int32 _baseAC;
|
||||
uint32 _baseSTR;
|
||||
uint32 _baseSTA;
|
||||
|
||||
+114
-177
@@ -49,11 +49,7 @@ Mob::Mob(const char* in_name,
|
||||
uint32 in_npctype_id,
|
||||
float in_size,
|
||||
float in_runspeed,
|
||||
float in_heading,
|
||||
float in_x_pos,
|
||||
float in_y_pos,
|
||||
float in_z_pos,
|
||||
|
||||
const glm::vec4& position,
|
||||
uint8 in_light,
|
||||
uint8 in_texture,
|
||||
uint8 in_helmtexture,
|
||||
@@ -102,29 +98,21 @@ Mob::Mob(const char* in_name,
|
||||
bardsong_timer(6000),
|
||||
gravity_timer(1000),
|
||||
viral_timer(0),
|
||||
flee_timer(FLEE_CHECK_TIMER)
|
||||
|
||||
m_FearWalkTarget(-999999.0f,-999999.0f,-999999.0f),
|
||||
m_TargetLocation(glm::vec3()),
|
||||
m_TargetV(glm::vec3()),
|
||||
flee_timer(FLEE_CHECK_TIMER),
|
||||
m_Position(position)
|
||||
{
|
||||
targeted = 0;
|
||||
tar_ndx=0;
|
||||
tar_vector=0;
|
||||
tar_vx=0;
|
||||
tar_vy=0;
|
||||
tar_vz=0;
|
||||
tarx=0;
|
||||
tary=0;
|
||||
tarz=0;
|
||||
fear_walkto_x = -999999;
|
||||
fear_walkto_y = -999999;
|
||||
fear_walkto_z = -999999;
|
||||
curfp = false;
|
||||
|
||||
AI_Init();
|
||||
SetMoving(false);
|
||||
moved=false;
|
||||
rewind_x = 0; //Stored x_pos for /rewind
|
||||
rewind_y = 0; //Stored y_pos for /rewind
|
||||
rewind_z = 0; //Stored z_pos for /rewind
|
||||
m_RewindLocation = glm::vec3();
|
||||
move_tic_count = 0;
|
||||
|
||||
_egnode = nullptr;
|
||||
@@ -161,11 +149,9 @@ Mob::Mob(const char* in_name,
|
||||
if (runspeed < 0 || runspeed > 20)
|
||||
runspeed = 1.25f;
|
||||
|
||||
heading = in_heading;
|
||||
x_pos = in_x_pos;
|
||||
y_pos = in_y_pos;
|
||||
z_pos = in_z_pos;
|
||||
light = in_light;
|
||||
active_light = innate_light = in_light;
|
||||
spell_light = equip_light = NOT_USED;
|
||||
|
||||
texture = in_texture;
|
||||
helmtexture = in_helmtexture;
|
||||
haircolor = in_haircolor;
|
||||
@@ -259,10 +245,7 @@ Mob::Mob(const char* in_name,
|
||||
}
|
||||
}
|
||||
|
||||
delta_heading = 0;
|
||||
delta_x = 0;
|
||||
delta_y = 0;
|
||||
delta_z = 0;
|
||||
m_Delta = glm::vec4();
|
||||
animation = 0;
|
||||
|
||||
logging_enabled = false;
|
||||
@@ -335,17 +318,12 @@ Mob::Mob(const char* in_name,
|
||||
wandertype=0;
|
||||
pausetype=0;
|
||||
cur_wp = 0;
|
||||
cur_wp_x = 0;
|
||||
cur_wp_y = 0;
|
||||
cur_wp_z = 0;
|
||||
m_CurrentWayPoint = glm::vec4();
|
||||
cur_wp_pause = 0;
|
||||
patrol=0;
|
||||
follow=0;
|
||||
follow_dist = 100; // Default Distance for Follow
|
||||
flee_mode = false;
|
||||
fear_walkto_x = -999999;
|
||||
fear_walkto_y = -999999;
|
||||
fear_walkto_z = -999999;
|
||||
curfp = false;
|
||||
flee_timer.Start();
|
||||
|
||||
@@ -387,9 +365,7 @@ Mob::Mob(const char* in_name,
|
||||
nimbus_effect3 = 0;
|
||||
m_targetable = true;
|
||||
|
||||
targetring_x = 0.0f;
|
||||
targetring_y = 0.0f;
|
||||
targetring_z = 0.0f;
|
||||
m_TargetRing = glm::vec3();
|
||||
|
||||
flymode = FlyMode3;
|
||||
// Pathing
|
||||
@@ -908,10 +884,10 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName));
|
||||
}
|
||||
|
||||
ns->spawn.heading = FloatToEQ19(heading);
|
||||
ns->spawn.x = FloatToEQ19(x_pos);//((int32)x_pos)<<3;
|
||||
ns->spawn.y = FloatToEQ19(y_pos);//((int32)y_pos)<<3;
|
||||
ns->spawn.z = FloatToEQ19(z_pos);//((int32)z_pos)<<3;
|
||||
ns->spawn.heading = FloatToEQ19(m_Position.w);
|
||||
ns->spawn.x = FloatToEQ19(m_Position.x);//((int32)x_pos)<<3;
|
||||
ns->spawn.y = FloatToEQ19(m_Position.y);//((int32)y_pos)<<3;
|
||||
ns->spawn.z = FloatToEQ19(m_Position.z);//((int32)z_pos)<<3;
|
||||
ns->spawn.spawnId = GetID();
|
||||
ns->spawn.curHp = static_cast<uint8>(GetHPRatio());
|
||||
ns->spawn.max_hp = 100; //this field needs a better name
|
||||
@@ -924,7 +900,10 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
ns->spawn.deity = deity;
|
||||
ns->spawn.animation = 0;
|
||||
ns->spawn.findable = findable?1:0;
|
||||
ns->spawn.light = light;
|
||||
|
||||
UpdateActiveLightValue();
|
||||
ns->spawn.light = active_light;
|
||||
|
||||
ns->spawn.showhelm = (helmtexture && helmtexture != 0xFF) ? 1 : 0;
|
||||
|
||||
ns->spawn.invis = (invisible || hidden) ? 1 : 0; // TODO: load this before spawning players
|
||||
@@ -966,13 +945,9 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
// 3 - Mobs in water do not sink. A value of 3 in this field appears to be the default setting for all mobs
|
||||
// (in water or not) according to 6.2 era packet collects.
|
||||
if(IsClient())
|
||||
{
|
||||
ns->spawn.flymode = FindType(SE_Levitate) ? 2 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ns->spawn.flymode = flymode;
|
||||
}
|
||||
|
||||
ns->spawn.lastName[0] = '\0';
|
||||
|
||||
@@ -1240,13 +1215,13 @@ void Mob::SendPosUpdate(uint8 iSendToSelf) {
|
||||
void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu){
|
||||
memset(spu,0xff,sizeof(PlayerPositionUpdateServer_Struct));
|
||||
spu->spawn_id = GetID();
|
||||
spu->x_pos = FloatToEQ19(x_pos);
|
||||
spu->y_pos = FloatToEQ19(y_pos);
|
||||
spu->z_pos = FloatToEQ19(z_pos);
|
||||
spu->x_pos = FloatToEQ19(m_Position.x);
|
||||
spu->y_pos = FloatToEQ19(m_Position.y);
|
||||
spu->z_pos = FloatToEQ19(m_Position.z);
|
||||
spu->delta_x = NewFloatToEQ13(0);
|
||||
spu->delta_y = NewFloatToEQ13(0);
|
||||
spu->delta_z = NewFloatToEQ13(0);
|
||||
spu->heading = FloatToEQ19(heading);
|
||||
spu->heading = FloatToEQ19(m_Position.w);
|
||||
spu->animation = 0;
|
||||
spu->delta_heading = NewFloatToEQ13(0);
|
||||
spu->padding0002 =0;
|
||||
@@ -1271,13 +1246,13 @@ void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu){
|
||||
// this is for SendPosUpdate()
|
||||
void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) {
|
||||
spu->spawn_id = GetID();
|
||||
spu->x_pos = FloatToEQ19(x_pos);
|
||||
spu->y_pos = FloatToEQ19(y_pos);
|
||||
spu->z_pos = FloatToEQ19(z_pos);
|
||||
spu->delta_x = NewFloatToEQ13(delta_x);
|
||||
spu->delta_y = NewFloatToEQ13(delta_y);
|
||||
spu->delta_z = NewFloatToEQ13(delta_z);
|
||||
spu->heading = FloatToEQ19(heading);
|
||||
spu->x_pos = FloatToEQ19(m_Position.x);
|
||||
spu->y_pos = FloatToEQ19(m_Position.y);
|
||||
spu->z_pos = FloatToEQ19(m_Position.z);
|
||||
spu->delta_x = NewFloatToEQ13(m_Delta.x);
|
||||
spu->delta_y = NewFloatToEQ13(m_Delta.y);
|
||||
spu->delta_z = NewFloatToEQ13(m_Delta.z);
|
||||
spu->heading = FloatToEQ19(m_Position.w);
|
||||
spu->padding0002 =0;
|
||||
spu->padding0006 =7;
|
||||
spu->padding0014 =0x7f;
|
||||
@@ -1286,7 +1261,7 @@ void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) {
|
||||
spu->animation = animation;
|
||||
else
|
||||
spu->animation = pRunAnimSpeed;
|
||||
spu->delta_heading = NewFloatToEQ13(static_cast<float>(delta_heading));
|
||||
spu->delta_heading = NewFloatToEQ13(m_Delta.w);
|
||||
}
|
||||
|
||||
void Mob::ShowStats(Client* client)
|
||||
@@ -1308,7 +1283,7 @@ void Mob::ShowStats(Client* client)
|
||||
client->Message(0, " Mana: %i Max Mana: %i", GetMana(), GetMaxMana());
|
||||
client->Message(0, " Total ATK: %i Worn/Spell ATK (Cap %i): %i", GetATK(), RuleI(Character, ItemATKCap), GetATKBonus());
|
||||
client->Message(0, " STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetSTR(), GetSTA(), GetDEX(), GetAGI(), GetINT(), GetWIS(), GetCHA());
|
||||
client->Message(0, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup());
|
||||
client->Message(0, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i PhR: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup(), GetPhR());
|
||||
client->Message(0, " Race: %i BaseRace: %i Texture: %i HelmTexture: %i Gender: %i BaseGender: %i", GetRace(), GetBaseRace(), GetTexture(), GetHelmTexture(), GetGender(), GetBaseGender());
|
||||
if (client->Admin() >= 100)
|
||||
client->Message(0, " EntityID: %i PetID: %i OwnerID: %i AIControlled: %i Targetted: %i", GetID(), GetPetID(), GetOwnerID(), IsAIControlled(), targeted);
|
||||
@@ -1402,11 +1377,11 @@ void Mob::GMMove(float x, float y, float z, float heading, bool SendUpdate) {
|
||||
entity_list.ProcessMove(CastToNPC(), x, y, z);
|
||||
}
|
||||
|
||||
x_pos = x;
|
||||
y_pos = y;
|
||||
z_pos = z;
|
||||
if (heading != 0.01)
|
||||
this->heading = heading;
|
||||
m_Position.x = x;
|
||||
m_Position.y = y;
|
||||
m_Position.z = z;
|
||||
if (m_Position.w != 0.01)
|
||||
this->m_Position.w = heading;
|
||||
if(IsNPC())
|
||||
CastToNPC()->SaveGuardSpot(true);
|
||||
if(SendUpdate)
|
||||
@@ -1570,7 +1545,6 @@ void Mob::SendIllusionPacket(uint16 in_race, uint8 in_gender, uint8 in_texture,
|
||||
}
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Illusion, sizeof(Illusion_Struct));
|
||||
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
|
||||
Illusion_Struct* is = (Illusion_Struct*) outapp->pBuffer;
|
||||
is->spawnid = GetID();
|
||||
strcpy(is->charname, GetCleanName());
|
||||
@@ -1592,7 +1566,7 @@ void Mob::SendIllusionPacket(uint16 in_race, uint8 in_gender, uint8 in_texture,
|
||||
|
||||
entity_list.QueueClients(this, outapp);
|
||||
safe_delete(outapp);
|
||||
mlog(CLIENT__SPELLS, "Illusion: Race = %i, Gender = %i, Texture = %i, HelmTexture = %i, HairColor = %i, BeardColor = %i, EyeColor1 = %i, EyeColor2 = %i, HairStyle = %i, Face = %i, DrakkinHeritage = %i, DrakkinTattoo = %i, DrakkinDetails = %i, Size = %f",
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Illusion: Race = %i, Gender = %i, Texture = %i, HelmTexture = %i, HairColor = %i, BeardColor = %i, EyeColor1 = %i, EyeColor2 = %i, HairStyle = %i, Face = %i, DrakkinHeritage = %i, DrakkinTattoo = %i, DrakkinDetails = %i, Size = %f",
|
||||
race, gender, texture, helmtexture, haircolor, beardcolor, eyecolor1, eyecolor2, hairstyle, luclinface, drakkin_heritage, drakkin_tattoo, drakkin_details, size);
|
||||
}
|
||||
|
||||
@@ -1811,7 +1785,6 @@ bool Mob::IsPlayerRace(uint16 in_race) {
|
||||
|
||||
|
||||
uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) {
|
||||
//std::cout << "Gender in: " << (int)in_gender << std::endl; // undefined cout [CODEBUG]
|
||||
if (Mob::IsPlayerRace(in_race) || in_race == 15 || in_race == 50 || in_race == 57 || in_race == 70 || in_race == 98 || in_race == 118) {
|
||||
if (in_gender >= 2) {
|
||||
// Male default for PC Races
|
||||
@@ -1936,7 +1909,6 @@ void Mob::SendTargetable(bool on, Client *specific_target) {
|
||||
void Mob::QuestReward(Client *c, uint32 silver, uint32 gold, uint32 platinum) {
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Sound, sizeof(QuestReward_Struct));
|
||||
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
|
||||
QuestReward_Struct* qr = (QuestReward_Struct*) outapp->pBuffer;
|
||||
|
||||
qr->from_mob = GetID(); // Entity ID for the from mob name
|
||||
@@ -1956,7 +1928,6 @@ void Mob::CameraEffect(uint32 duration, uint32 intensity, Client *c, bool global
|
||||
if(global == true)
|
||||
{
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_CameraShake, sizeof(ServerCameraShake_Struct));
|
||||
memset(pack->pBuffer, 0, sizeof(pack->pBuffer));
|
||||
ServerCameraShake_Struct* scss = (ServerCameraShake_Struct*) pack->pBuffer;
|
||||
scss->duration = duration;
|
||||
scss->intensity = intensity;
|
||||
@@ -1966,7 +1937,6 @@ void Mob::CameraEffect(uint32 duration, uint32 intensity, Client *c, bool global
|
||||
}
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_CameraEffect, sizeof(Camera_Struct));
|
||||
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
|
||||
Camera_Struct* cs = (Camera_Struct*) outapp->pBuffer;
|
||||
cs->duration = duration; // Duration in milliseconds
|
||||
cs->intensity = ((intensity * 6710886) + 1023410176); // Intensity ranges from 1023410176 to 1090519040, so simplify it from 0 to 10.
|
||||
@@ -1982,7 +1952,6 @@ void Mob::CameraEffect(uint32 duration, uint32 intensity, Client *c, bool global
|
||||
void Mob::SendSpellEffect(uint32 effectid, uint32 duration, uint32 finish_delay, bool zone_wide, uint32 unk020, bool perm_effect, Client *c) {
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpellEffect, sizeof(SpellEffect_Struct));
|
||||
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
|
||||
SpellEffect_Struct* se = (SpellEffect_Struct*) outapp->pBuffer;
|
||||
se->EffectID = effectid; // ID of the Particle Effect
|
||||
se->EntityID = GetID();
|
||||
@@ -2034,7 +2003,6 @@ void Mob::TempName(const char *newname)
|
||||
|
||||
// Send the new name to all clients
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MobRename, sizeof(MobRename_Struct));
|
||||
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
|
||||
MobRename_Struct* mr = (MobRename_Struct*) outapp->pBuffer;
|
||||
strn0cpy(mr->old_name, old_name, 64);
|
||||
strn0cpy(mr->old_name_again, old_name, 64);
|
||||
@@ -2077,6 +2045,39 @@ void Mob::SetAppearance(EmuAppearance app, bool iIgnoreSelf) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Mob::UpdateActiveLightValue()
|
||||
{
|
||||
/* This is old information...
|
||||
0 - "None"
|
||||
1 - "Candle"
|
||||
2 - "Torch"
|
||||
3 - "Tiny Glowing Skull"
|
||||
4 - "Small Lantern"
|
||||
5 - "Stein of Moggok"
|
||||
6 - "Large Lantern"
|
||||
7 - "Flameless Lantern"
|
||||
8 - "Globe of Stars"
|
||||
9 - "Light Globe"
|
||||
10 - "Lightstone"
|
||||
11 - "Greater Lightstone"
|
||||
12 - "Fire Beatle Eye"
|
||||
13 - "Coldlight"
|
||||
14 - "Unknown"
|
||||
15 - "Unknown"
|
||||
*/
|
||||
|
||||
uint8 old_light = (active_light & 0x0F);
|
||||
active_light = (innate_light & 0x0F);
|
||||
|
||||
if (equip_light > active_light) { active_light = equip_light; } // limiter in property handler
|
||||
if (spell_light > active_light) { active_light = spell_light; } // limiter in property handler
|
||||
|
||||
if (active_light != old_light)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Mob::ChangeSize(float in_size = 0, bool bNoRestriction) {
|
||||
// Size Code
|
||||
if (!bNoRestriction)
|
||||
@@ -2319,59 +2320,7 @@ bool Mob::CanThisClassBlock(void) const
|
||||
return(CastToClient()->HasSkill(SkillBlock));
|
||||
}
|
||||
}
|
||||
|
||||
float Mob::Dist(const Mob &other) const {
|
||||
float xDiff = other.x_pos - x_pos;
|
||||
float yDiff = other.y_pos - y_pos;
|
||||
float zDiff = other.z_pos - z_pos;
|
||||
|
||||
return sqrtf( (xDiff * xDiff)
|
||||
+ (yDiff * yDiff)
|
||||
+ (zDiff * zDiff) );
|
||||
}
|
||||
|
||||
float Mob::DistNoZ(const Mob &other) const {
|
||||
float xDiff = other.x_pos - x_pos;
|
||||
float yDiff = other.y_pos - y_pos;
|
||||
|
||||
return sqrtf( (xDiff * xDiff)
|
||||
+ (yDiff * yDiff) );
|
||||
}
|
||||
|
||||
float Mob::DistNoRoot(const Mob &other) const {
|
||||
float xDiff = other.x_pos - x_pos;
|
||||
float yDiff = other.y_pos - y_pos;
|
||||
float zDiff = other.z_pos - z_pos;
|
||||
|
||||
return ( (xDiff * xDiff)
|
||||
+ (yDiff * yDiff)
|
||||
+ (zDiff * zDiff) );
|
||||
}
|
||||
|
||||
float Mob::DistNoRoot(float x, float y, float z) const {
|
||||
float xDiff = x - x_pos;
|
||||
float yDiff = y - y_pos;
|
||||
float zDiff = z - z_pos;
|
||||
|
||||
return ( (xDiff * xDiff)
|
||||
+ (yDiff * yDiff)
|
||||
+ (zDiff * zDiff) );
|
||||
}
|
||||
|
||||
float Mob::DistNoRootNoZ(float x, float y) const {
|
||||
float xDiff = x - x_pos;
|
||||
float yDiff = y - y_pos;
|
||||
|
||||
return ( (xDiff * xDiff) + (yDiff * yDiff) );
|
||||
}
|
||||
|
||||
float Mob::DistNoRootNoZ(const Mob &other) const {
|
||||
float xDiff = other.x_pos - x_pos;
|
||||
float yDiff = other.y_pos - y_pos;
|
||||
|
||||
return ( (xDiff * xDiff) + (yDiff * yDiff) );
|
||||
}
|
||||
|
||||
/*
|
||||
float Mob::GetReciprocalHeading(Mob* target) {
|
||||
float Result = 0;
|
||||
|
||||
@@ -2388,7 +2337,7 @@ float Mob::GetReciprocalHeading(Mob* target) {
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
*/
|
||||
bool Mob::PlotPositionAroundTarget(Mob* target, float &x_dest, float &y_dest, float &z_dest, bool lookForAftArc) {
|
||||
bool Result = false;
|
||||
|
||||
@@ -2396,7 +2345,7 @@ bool Mob::PlotPositionAroundTarget(Mob* target, float &x_dest, float &y_dest, fl
|
||||
float look_heading = 0;
|
||||
|
||||
if(lookForAftArc)
|
||||
look_heading = GetReciprocalHeading(target);
|
||||
look_heading = GetReciprocalHeading(target->GetPosition());
|
||||
else
|
||||
look_heading = target->GetHeading();
|
||||
|
||||
@@ -2512,20 +2461,18 @@ bool Mob::HateSummon() {
|
||||
entity_list.MessageClose(this, true, 500, MT_Say, "%s says,'You will not evade me, %s!' ", GetCleanName(), target->GetCleanName() );
|
||||
|
||||
if (target->IsClient()) {
|
||||
target->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x_pos, y_pos, z_pos, target->GetHeading(), 0, SummonPC);
|
||||
target->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Position.x, m_Position.y, m_Position.z, target->GetHeading(), 0, SummonPC);
|
||||
}
|
||||
else {
|
||||
#ifdef BOTS
|
||||
if(target && target->IsBot()) {
|
||||
// set pre summoning info to return to (to get out of melee range for caster)
|
||||
target->CastToBot()->SetHasBeenSummoned(true);
|
||||
target->CastToBot()->SetPreSummonX(target->GetX());
|
||||
target->CastToBot()->SetPreSummonY(target->GetY());
|
||||
target->CastToBot()->SetPreSummonZ(target->GetZ());
|
||||
target->CastToBot()->SetPreSummonLocation(glm::vec3(target->GetPosition()));
|
||||
|
||||
}
|
||||
#endif //BOTS
|
||||
target->GMMove(x_pos, y_pos, z_pos, target->GetHeading());
|
||||
target->GMMove(m_Position.x, m_Position.y, m_Position.z, target->GetHeading());
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2703,7 +2650,7 @@ int32 Mob::GetEquipmentMaterial(uint8 material_slot) const
|
||||
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||
const Item_Struct *item;
|
||||
item = database.GetItem(GetEquipment(material_slot));
|
||||
|
||||
|
||||
if (item != 0)
|
||||
{
|
||||
// For primary and secondary we need the model, not the material
|
||||
@@ -2814,14 +2761,10 @@ uint32 Mob::GetEquipmentColor(uint8 material_slot) const
|
||||
{
|
||||
return armor_tint[material_slot];
|
||||
}
|
||||
else
|
||||
{
|
||||
item = database.GetItem(GetEquipment(material_slot));
|
||||
if (item != 0)
|
||||
{
|
||||
return item->Color;
|
||||
}
|
||||
}
|
||||
|
||||
item = database.GetItem(GetEquipment(material_slot));
|
||||
if (item != 0)
|
||||
return item->Color;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2865,7 +2808,7 @@ void Mob::Say(const char *format, ...)
|
||||
}
|
||||
|
||||
//
|
||||
// solar: this is like the above, but the first parameter is a string id
|
||||
// this is like the above, but the first parameter is a string id
|
||||
//
|
||||
void Mob::Say_StringID(uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9)
|
||||
{
|
||||
@@ -2943,20 +2886,16 @@ void Mob::SetNextIncHPEvent( int inchpevent )
|
||||
nextinchpevent = inchpevent;
|
||||
}
|
||||
//warp for quest function,from sandy
|
||||
void Mob::Warp( float x, float y, float z )
|
||||
void Mob::Warp(const glm::vec3& location)
|
||||
{
|
||||
if(IsNPC()) {
|
||||
entity_list.ProcessMove(CastToNPC(), x, y, z);
|
||||
}
|
||||
if(IsNPC())
|
||||
entity_list.ProcessMove(CastToNPC(), location.x, location.y, location.z);
|
||||
|
||||
x_pos = x;
|
||||
y_pos = y;
|
||||
z_pos = z;
|
||||
m_Position = glm::vec4(location, m_Position.w);
|
||||
|
||||
Mob* target = GetTarget();
|
||||
if (target) {
|
||||
if (target)
|
||||
FaceTarget( target );
|
||||
}
|
||||
|
||||
SendPosition();
|
||||
}
|
||||
@@ -2994,7 +2933,6 @@ int16 Mob::GetResist(uint8 type) const
|
||||
|
||||
uint32 Mob::GetLevelHP(uint8 tlevel)
|
||||
{
|
||||
//std::cout<<"Tlevel: "<<(int)tlevel<<std::endl; // cout undefined [CODEBUG]
|
||||
int multiplier = 0;
|
||||
if (tlevel < 10)
|
||||
{
|
||||
@@ -3042,7 +2980,7 @@ int32 Mob::GetActSpellCasttime(uint16 spell_id, int32 casttime) {
|
||||
}
|
||||
|
||||
casttime = (casttime*(100 - cast_reducer)/100);
|
||||
return(casttime);
|
||||
return casttime;
|
||||
}
|
||||
|
||||
void Mob::ExecWeaponProc(const ItemInst *inst, uint16 spell_id, Mob *on) {
|
||||
@@ -3059,7 +2997,7 @@ void Mob::ExecWeaponProc(const ItemInst *inst, uint16 spell_id, Mob *on) {
|
||||
if(!IsValidSpell(spell_id)) { // Check for a valid spell otherwise it will crash through the function
|
||||
if(IsClient()){
|
||||
Message(0, "Invalid spell proc %u", spell_id);
|
||||
mlog(CLIENT__SPELLS, "Player %s, Weapon Procced invalid spell %u", this->GetName(), spell_id);
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Player %s, Weapon Procced invalid spell %u", this->GetName(), spell_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3077,7 +3015,8 @@ void Mob::ExecWeaponProc(const ItemInst *inst, uint16 spell_id, Mob *on) {
|
||||
bool twinproc = false;
|
||||
int32 twinproc_chance = 0;
|
||||
|
||||
twinproc_chance = GetFocusEffect(focusTwincast, spell_id);
|
||||
if(IsClient())
|
||||
twinproc_chance = CastToClient()->GetFocusEffect(focusTwincast, spell_id);
|
||||
|
||||
if(twinproc_chance && zone->random.Roll(twinproc_chance))
|
||||
twinproc = true;
|
||||
@@ -3168,11 +3107,11 @@ float Mob::FindGroundZ(float new_x, float new_y, float z_offset)
|
||||
float ret = -999999;
|
||||
if (zone->zonemap != nullptr)
|
||||
{
|
||||
Map::Vertex me;
|
||||
glm::vec3 me;
|
||||
me.x = new_x;
|
||||
me.y = new_y;
|
||||
me.z = z_pos+z_offset;
|
||||
Map::Vertex hit;
|
||||
me.z = m_Position.z + z_offset;
|
||||
glm::vec3 hit;
|
||||
float best_z = zone->zonemap->FindBestZ(me, &hit);
|
||||
if (best_z != -999999)
|
||||
{
|
||||
@@ -3188,11 +3127,11 @@ float Mob::GetGroundZ(float new_x, float new_y, float z_offset)
|
||||
float ret = -999999;
|
||||
if (zone->zonemap != 0)
|
||||
{
|
||||
Map::Vertex me;
|
||||
glm::vec3 me;
|
||||
me.x = new_x;
|
||||
me.y = new_y;
|
||||
me.z = z_pos+z_offset;
|
||||
Map::Vertex hit;
|
||||
me.z = m_Position.z+z_offset;
|
||||
glm::vec3 hit;
|
||||
float best_z = zone->zonemap->FindBestZ(me, &hit);
|
||||
if (best_z != -999999)
|
||||
{
|
||||
@@ -3241,8 +3180,8 @@ int Mob::GetSnaredAmount()
|
||||
{
|
||||
int val = CalcSpellEffectValue_formula(spells[buffs[i].spellid].formula[j], spells[buffs[i].spellid].base[j], spells[buffs[i].spellid].max[j], buffs[i].casterlevel, buffs[i].spellid);
|
||||
//int effect = CalcSpellEffectValue(buffs[i].spellid, spells[buffs[i].spellid].effectid[j], buffs[i].casterlevel);
|
||||
if (val < 0 && abs(val) > worst_snare)
|
||||
worst_snare = abs(val);
|
||||
if (val < 0 && std::abs(val) > worst_snare)
|
||||
worst_snare = std::abs(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3286,11 +3225,8 @@ void Mob::TriggerDefensiveProcs(const ItemInst* weapon, Mob *on, uint16 hand, in
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::SetDeltas(float dx, float dy, float dz, float dh) {
|
||||
delta_x = dx;
|
||||
delta_y = dy;
|
||||
delta_z = dz;
|
||||
delta_heading = static_cast<int>(dh);
|
||||
void Mob::SetDelta(const glm::vec4& delta) {
|
||||
m_Delta = delta;
|
||||
}
|
||||
|
||||
void Mob::SetEntityVariable(const char *id, const char *m_var)
|
||||
@@ -3399,7 +3335,7 @@ void Mob::TriggerOnCast(uint32 focus_spell, uint32 spell_id, bool aa_trigger)
|
||||
|
||||
if(IsValidSpell(trigger_spell_id) && GetTarget()){
|
||||
SpellFinished(trigger_spell_id, GetTarget(),10, 0, -1, spells[trigger_spell_id].ResistDiff);
|
||||
CheckNumHitsRemaining(NUMHIT_MatchingSpells,-1, focus_spell);
|
||||
CheckNumHitsRemaining(NumHit::MatchingSpells, -1, focus_spell);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3631,7 +3567,7 @@ int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
|
||||
value += tmp_focus;
|
||||
|
||||
if (tmp_buffslot >= 0)
|
||||
CheckNumHitsRemaining(NUMHIT_MatchingSpells, tmp_buffslot);
|
||||
CheckNumHitsRemaining(NumHit::MatchingSpells, tmp_buffslot);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -3736,7 +3672,7 @@ void Mob::TrySympatheticProc(Mob *target, uint32 spell_id)
|
||||
SpellFinished(focus_trigger, target, 10, 0, -1, spells[focus_trigger].ResistDiff);
|
||||
}
|
||||
|
||||
CheckNumHitsRemaining(NUMHIT_MatchingSpells, -1, focus_spell);
|
||||
CheckNumHitsRemaining(NumHit::MatchingSpells, -1, focus_spell);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4552,7 +4488,7 @@ void Mob::MeleeLifeTap(int32 damage) {
|
||||
if(lifetap_amt && damage > 0){
|
||||
|
||||
lifetap_amt = damage * lifetap_amt / 100;
|
||||
mlog(COMBAT__DAMAGE, "Melee lifetap healing for %d damage.", damage);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Melee lifetap healing for %d damage.", damage);
|
||||
|
||||
if (lifetap_amt > 0)
|
||||
HealDamage(lifetap_amt); //Heal self for modified damage amount.
|
||||
@@ -4611,7 +4547,8 @@ void Mob::DoGravityEffect()
|
||||
if(value > 0)
|
||||
away = 1;
|
||||
|
||||
amount = fabs(value) / (100.0f); // to bring the values in line, arbitarily picked
|
||||
amount = std::abs(value) /
|
||||
(100.0f); // to bring the values in line, arbitarily picked
|
||||
|
||||
x_vector = cur_x - caster_x;
|
||||
y_vector = cur_y - caster_y;
|
||||
@@ -4630,7 +4567,7 @@ void Mob::DoGravityEffect()
|
||||
}
|
||||
}
|
||||
|
||||
if((fabs(my_x - cur_x) > 0.01) || (fabs(my_y - cur_y) > 0.01)) {
|
||||
if ((std::abs(my_x - cur_x) > 0.01) || (std::abs(my_y - cur_y) > 0.01)) {
|
||||
float new_ground = GetGroundZ(cur_x, cur_y);
|
||||
// If we cant get LoS on our new spot then keep checking up to 5 units up.
|
||||
if(!CheckLosFN(cur_x, cur_y, new_ground, GetSize())) {
|
||||
@@ -5290,7 +5227,7 @@ bool Mob::IsFacingMob(Mob *other)
|
||||
if (angle < 40.0 && heading > 472.0)
|
||||
angle = heading;
|
||||
|
||||
if (fabs(angle - heading) <= 80.0)
|
||||
if (std::abs(angle - heading) <= 80.0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -5304,8 +5241,8 @@ float Mob::HeadingAngleToMob(Mob *other)
|
||||
float this_x = GetX();
|
||||
float this_y = GetY();
|
||||
|
||||
float y_diff = fabs(this_y - mob_y);
|
||||
float x_diff = fabs(this_x - mob_x);
|
||||
float y_diff = std::abs(this_y - mob_y);
|
||||
float x_diff = std::abs(this_x - mob_x);
|
||||
if (y_diff < 0.0000009999999974752427)
|
||||
y_diff = 0.0000009999999974752427;
|
||||
|
||||
|
||||
+88
-99
@@ -22,8 +22,10 @@
|
||||
#include "entity.h"
|
||||
#include "hate_list.h"
|
||||
#include "pathing.h"
|
||||
#include "position.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
char* strn0cpy(char* dest, const char* source, uint32 size);
|
||||
|
||||
@@ -77,10 +79,7 @@ public:
|
||||
uint32 in_npctype_id,
|
||||
float in_size,
|
||||
float in_runspeed,
|
||||
float in_heading,
|
||||
float in_x_pos,
|
||||
float in_y_pos,
|
||||
float in_z_pos,
|
||||
const glm::vec4& position,
|
||||
uint8 in_light,
|
||||
uint8 in_texture,
|
||||
uint8 in_helmtexture,
|
||||
@@ -124,7 +123,7 @@ public:
|
||||
|
||||
//Attack
|
||||
virtual void RogueBackstab(Mob* other, bool min_damage = false, int ReuseTime = 10);
|
||||
virtual void RogueAssassinate(Mob* other); // solar
|
||||
virtual void RogueAssassinate(Mob* other);
|
||||
float MobAngle(Mob *other = 0, float ourx = 0.0f, float oury = 0.0f) const;
|
||||
// greater than 90 is behind
|
||||
inline bool BehindMob(Mob *other = 0, float ourx = 0.0f, float oury = 0.0f) const
|
||||
@@ -183,7 +182,7 @@ public:
|
||||
bool IsInvisible(Mob* other = 0) const;
|
||||
void SetInvisible(uint8 state);
|
||||
bool AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* weapon);
|
||||
|
||||
|
||||
//Song
|
||||
bool UseBardSpellLogic(uint16 spell_id = 0xffff, int slot = -1);
|
||||
bool ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, uint16 slot);
|
||||
@@ -282,7 +281,7 @@ public:
|
||||
int16 GetBuffSlotFromType(uint16 type);
|
||||
uint16 GetSpellIDFromSlot(uint8 slot);
|
||||
int CountDispellableBuffs();
|
||||
void CheckNumHitsRemaining(uint8 type, int32 buff_slot=-1, uint16 spell_id=SPELL_UNKNOWN);
|
||||
void CheckNumHitsRemaining(NumHit type, int32 buff_slot = -1, uint16 spell_id = SPELL_UNKNOWN);
|
||||
bool HasNumhits() const { return has_numhits; }
|
||||
inline void Numhits(bool val) { has_numhits = val; }
|
||||
bool HasMGB() const { return has_MGB; }
|
||||
@@ -296,9 +295,10 @@ public:
|
||||
inline virtual uint32 GetNimbusEffect2() const { return nimbus_effect2; }
|
||||
inline virtual uint32 GetNimbusEffect3() const { return nimbus_effect3; }
|
||||
void RemoveNimbusEffect(int effectid);
|
||||
inline float GetTargetRingX() const { return targetring_x; }
|
||||
inline float GetTargetRingY() const { return targetring_y; }
|
||||
inline float GetTargetRingZ() const { return targetring_z; }
|
||||
inline const glm::vec3& GetTargetRingLocation() const { return m_TargetRing; }
|
||||
inline float GetTargetRingX() const { return m_TargetRing.x; }
|
||||
inline float GetTargetRingY() const { return m_TargetRing.y; }
|
||||
inline float GetTargetRingZ() const { return m_TargetRing.z; }
|
||||
inline bool HasEndurUpkeep() const { return endur_upkeep; }
|
||||
inline void SetEndurUpkeep(bool val) { endur_upkeep = val; }
|
||||
|
||||
@@ -371,7 +371,7 @@ public:
|
||||
inline virtual int32 GetPR() const { return PR + itembonuses.PR + spellbonuses.PR; }
|
||||
inline virtual int32 GetCR() const { return CR + itembonuses.CR + spellbonuses.CR; }
|
||||
inline virtual int32 GetCorrup() const { return Corrup + itembonuses.Corrup + spellbonuses.Corrup; }
|
||||
inline virtual int32 GetPhR() const { return PhR; }
|
||||
inline virtual int32 GetPhR() const { return PhR; } // PhR bonuses not implemented yet
|
||||
inline StatBonuses GetItemBonuses() const { return itembonuses; }
|
||||
inline StatBonuses GetSpellBonuses() const { return spellbonuses; }
|
||||
inline StatBonuses GetAABonuses() const { return aabonuses; }
|
||||
@@ -400,18 +400,19 @@ public:
|
||||
((static_cast<float>(cur_mana) / max_mana) * 100); }
|
||||
virtual int32 CalcMaxMana();
|
||||
uint32 GetNPCTypeID() const { return npctype_id; }
|
||||
inline const float GetX() const { return x_pos; }
|
||||
inline const float GetY() const { return y_pos; }
|
||||
inline const float GetZ() const { return z_pos; }
|
||||
inline const float GetHeading() const { return heading; }
|
||||
inline const glm::vec4& GetPosition() const { return m_Position; }
|
||||
inline const float GetX() const { return m_Position.x; }
|
||||
inline const float GetY() const { return m_Position.y; }
|
||||
inline const float GetZ() const { return m_Position.z; }
|
||||
inline const float GetHeading() const { return m_Position.w; }
|
||||
inline const float GetSize() const { return size; }
|
||||
inline const float GetBaseSize() const { return base_size; }
|
||||
inline const float GetTarX() const { return tarx; }
|
||||
inline const float GetTarY() const { return tary; }
|
||||
inline const float GetTarZ() const { return tarz; }
|
||||
inline const float GetTarVX() const { return tar_vx; }
|
||||
inline const float GetTarVY() const { return tar_vy; }
|
||||
inline const float GetTarVZ() const { return tar_vz; }
|
||||
inline const float GetTarX() const { return m_TargetLocation.x; }
|
||||
inline const float GetTarY() const { return m_TargetLocation.y; }
|
||||
inline const float GetTarZ() const { return m_TargetLocation.z; }
|
||||
inline const float GetTarVX() const { return m_TargetV.x; }
|
||||
inline const float GetTarVY() const { return m_TargetV.y; }
|
||||
inline const float GetTarVZ() const { return m_TargetV.z; }
|
||||
inline const float GetTarVector() const { return tar_vector; }
|
||||
inline const uint8 GetTarNDX() const { return tar_ndx; }
|
||||
bool IsBoat() const;
|
||||
@@ -426,9 +427,9 @@ public:
|
||||
virtual inline int32 GetPrimaryFaction() const { return 0; }
|
||||
|
||||
//Movement
|
||||
void Warp( float x, float y, float z );
|
||||
void Warp(const glm::vec3& location);
|
||||
inline bool IsMoving() const { return moving; }
|
||||
virtual void SetMoving(bool move) { moving = move; delta_x = 0; delta_y = 0; delta_z = 0; delta_heading = 0; }
|
||||
virtual void SetMoving(bool move) { moving = move; m_Delta = glm::vec4(); }
|
||||
virtual void GoToBind(uint8 bindnum = 0) { }
|
||||
virtual void Gate();
|
||||
float GetWalkspeed() const { return(_GetMovementSpeed(-47)); }
|
||||
@@ -438,15 +439,15 @@ public:
|
||||
bool IsRunning() const { return m_is_running; }
|
||||
void SetRunning(bool val) { m_is_running = val; }
|
||||
virtual void GMMove(float x, float y, float z, float heading = 0.01, bool SendUpdate = true);
|
||||
void SetDeltas(float delta_x, float delta_y, float delta_z, float delta_h);
|
||||
void SetDelta(const glm::vec4& delta);
|
||||
void SetTargetDestSteps(uint8 target_steps) { tar_ndx = target_steps; }
|
||||
void SendPosUpdate(uint8 iSendToSelf = 0);
|
||||
void MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct* spu);
|
||||
void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu);
|
||||
void SendPosition();
|
||||
void SetFlyMode(uint8 flymode);
|
||||
inline void Teleport(Map::Vertex NewPosition) { x_pos = NewPosition.x; y_pos = NewPosition.y;
|
||||
z_pos = NewPosition.z; };
|
||||
inline void Teleport(glm::vec3 NewPosition) { m_Position.x = NewPosition.x; m_Position.y = NewPosition.y;
|
||||
m_Position.z = NewPosition.z; };
|
||||
|
||||
//AI
|
||||
static uint32 GetLevelCon(uint8 mylevel, uint8 iOtherLevel);
|
||||
@@ -467,8 +468,8 @@ public:
|
||||
bool IsEngaged() { return(!hate_list.IsHateListEmpty()); }
|
||||
bool HateSummon();
|
||||
void FaceTarget(Mob* MobToFace = 0);
|
||||
void SetHeading(float iHeading) { if(heading != iHeading) { pLastChange = Timer::GetCurrentTime();
|
||||
heading = iHeading; } }
|
||||
void SetHeading(float iHeading) { if(m_Position.w != iHeading) { pLastChange = Timer::GetCurrentTime();
|
||||
m_Position.w = iHeading; } }
|
||||
void WipeHateList();
|
||||
void AddFeignMemory(Client* attacker);
|
||||
void RemoveFromFeignMemory(Client* attacker);
|
||||
@@ -511,13 +512,6 @@ public:
|
||||
void ShowStats(Client* client);
|
||||
void ShowBuffs(Client* client);
|
||||
void ShowBuffList(Client* client);
|
||||
float Dist(const Mob &) const;
|
||||
float DistNoZ(const Mob &) const;
|
||||
float DistNoRoot(const Mob &) const;
|
||||
float DistNoRoot(float x, float y, float z) const;
|
||||
float DistNoRootNoZ(float x, float y) const;
|
||||
float DistNoRootNoZ(const Mob &) const;
|
||||
static float GetReciprocalHeading(Mob* target);
|
||||
bool PlotPositionAroundTarget(Mob* target, float &x_dest, float &y_dest, float &z_dest,
|
||||
bool lookForAftArc = true);
|
||||
|
||||
@@ -535,12 +529,6 @@ public:
|
||||
bool HasProcs() const;
|
||||
bool IsCombatProc(uint16 spell_id);
|
||||
|
||||
//Logging
|
||||
bool IsLoggingEnabled() const { return(logging_enabled); }
|
||||
void EnableLogging() { logging_enabled = true; }
|
||||
void DisableLogging() { logging_enabled = false; }
|
||||
|
||||
|
||||
//More stuff to sort:
|
||||
virtual bool IsRaidTarget() const { return false; };
|
||||
virtual bool IsAttackAllowed(Mob *target, bool isSpellAttack = false);
|
||||
@@ -575,10 +563,10 @@ public:
|
||||
|
||||
int16 CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, bool best_focus=false);
|
||||
uint8 IsFocusEffect(uint16 spellid, int effect_index, bool AA=false,uint32 aa_effect=0);
|
||||
void SendIllusionPacket(uint16 in_race, uint8 in_gender = 0xFF, uint8 in_texture = 0xFF, uint8 in_helmtexture = 0xFF,
|
||||
uint8 in_haircolor = 0xFF, uint8 in_beardcolor = 0xFF, uint8 in_eyecolor1 = 0xFF, uint8 in_eyecolor2 = 0xFF,
|
||||
uint8 in_hairstyle = 0xFF, uint8 in_luclinface = 0xFF, uint8 in_beard = 0xFF, uint8 in_aa_title = 0xFF,
|
||||
uint32 in_drakkin_heritage = 0xFFFFFFFF, uint32 in_drakkin_tattoo = 0xFFFFFFFF,
|
||||
void SendIllusionPacket(uint16 in_race, uint8 in_gender = 0xFF, uint8 in_texture = 0xFF, uint8 in_helmtexture = 0xFF,
|
||||
uint8 in_haircolor = 0xFF, uint8 in_beardcolor = 0xFF, uint8 in_eyecolor1 = 0xFF, uint8 in_eyecolor2 = 0xFF,
|
||||
uint8 in_hairstyle = 0xFF, uint8 in_luclinface = 0xFF, uint8 in_beard = 0xFF, uint8 in_aa_title = 0xFF,
|
||||
uint32 in_drakkin_heritage = 0xFFFFFFFF, uint32 in_drakkin_tattoo = 0xFFFFFFFF,
|
||||
uint32 in_drakkin_details = 0xFFFFFFFF, float in_size = -1.0f);
|
||||
bool RandomizeFeatures(bool send_illusion = true, bool set_variables = true);
|
||||
virtual void Stun(int duration);
|
||||
@@ -590,7 +578,7 @@ public:
|
||||
void WakeTheDead(uint16 spell_id, Mob *target, uint32 duration);
|
||||
void Spin();
|
||||
void Kill();
|
||||
bool PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id);
|
||||
bool PassCharismaCheck(Mob* caster, uint16 spell_id);
|
||||
bool TryDeathSave();
|
||||
bool TryDivineSave();
|
||||
void DoBuffWearOffEffect(uint32 index);
|
||||
@@ -627,7 +615,7 @@ public:
|
||||
bool CanBlockSpell() const { return(spellbonuses.BlockNextSpell); }
|
||||
bool DoHPToManaCovert(uint16 mana_cost = 0);
|
||||
int32 ApplySpellEffectiveness(Mob* caster, int16 spell_id, int32 value, bool IsBard = false);
|
||||
int8 GetDecayEffectValue(uint16 spell_id, uint16 spelleffect);
|
||||
int8 GetDecayEffectValue(uint16 spell_id, uint16 spelleffect);
|
||||
int32 GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_spell_dmg);
|
||||
void MeleeLifeTap(int32 damage);
|
||||
bool PassCastRestriction(bool UseCastRestriction = true, int16 value = 0, bool IsDamage = true);
|
||||
@@ -664,6 +652,15 @@ public:
|
||||
bool IsDestructibleObject() { return destructibleobject; }
|
||||
void SetDestructibleObject(bool in) { destructibleobject = in; }
|
||||
|
||||
inline uint8 GetInnateLightValue() { return innate_light; }
|
||||
inline uint8 GetEquipLightValue() { return equip_light; }
|
||||
inline uint8 GetSpellLightValue() { return spell_light; }
|
||||
virtual void UpdateEquipLightValue() { equip_light = NOT_USED; }
|
||||
inline void SetSpellLightValue(uint8 light_value) { spell_light = (light_value & 0x0F); }
|
||||
|
||||
inline uint8 GetActiveLightValue() { return active_light; }
|
||||
bool UpdateActiveLightValue(); // returns true if change, false if no change
|
||||
|
||||
Mob* GetPet();
|
||||
void SetPet(Mob* newpet);
|
||||
virtual Mob* GetOwner();
|
||||
@@ -688,9 +685,9 @@ public:
|
||||
inline int16 GetTempPetCount() const { return count_TempPet; }
|
||||
inline void SetTempPetCount(int16 i) { count_TempPet = i; }
|
||||
bool HasPetAffinity() { if (aabonuses.GivePetGroupTarget || itembonuses.GivePetGroupTarget || spellbonuses.GivePetGroupTarget) return true; return false; }
|
||||
inline bool IsPetOwnerClient() const { return pet_owner_client; }
|
||||
inline bool IsPetOwnerClient() const { return pet_owner_client; }
|
||||
inline void SetPetOwnerClient(bool value) { pet_owner_client = value; }
|
||||
inline bool IsTempPet() const { return _IsTempPet; }
|
||||
inline bool IsTempPet() const { return _IsTempPet; }
|
||||
inline void SetTempPet(bool value) { _IsTempPet = value; }
|
||||
|
||||
inline const bodyType GetBodyType() const { return bodytype; }
|
||||
@@ -821,10 +818,10 @@ public:
|
||||
void SetDontCureMeBefore(uint32 time) { pDontCureMeBefore = time; }
|
||||
|
||||
// calculate interruption of spell via movement of mob
|
||||
void SaveSpellLoc() {spell_x = x_pos; spell_y = y_pos; spell_z = z_pos; }
|
||||
inline float GetSpellX() const {return spell_x;}
|
||||
inline float GetSpellY() const {return spell_y;}
|
||||
inline float GetSpellZ() const {return spell_z;}
|
||||
void SaveSpellLoc() { m_SpellLocation = glm::vec3(m_Position); }
|
||||
inline float GetSpellX() const {return m_SpellLocation.x;}
|
||||
inline float GetSpellY() const {return m_SpellLocation.y;}
|
||||
inline float GetSpellZ() const {return m_SpellLocation.z;}
|
||||
inline bool IsGrouped() const { return isgrouped; }
|
||||
void SetGrouped(bool v);
|
||||
inline bool IsRaidGrouped() const { return israidgrouped; }
|
||||
@@ -875,19 +872,16 @@ public:
|
||||
|
||||
Shielders_Struct shielder[MAX_SHIELDERS];
|
||||
Trade* trade;
|
||||
|
||||
inline float GetCWPX() const { return(cur_wp_x); }
|
||||
inline float GetCWPY() const { return(cur_wp_y); }
|
||||
inline float GetCWPZ() const { return(cur_wp_z); }
|
||||
inline float GetCWPH() const { return(cur_wp_heading); }
|
||||
|
||||
inline glm::vec4 GetCurrentWayPoint() const { return m_CurrentWayPoint; }
|
||||
inline float GetCWPP() const { return(static_cast<float>(cur_wp_pause)); }
|
||||
inline int GetCWP() const { return(cur_wp); }
|
||||
void SetCurrentWP(uint16 waypoint) { cur_wp = waypoint; }
|
||||
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther) { return FACTION_INDIFFERENT; }
|
||||
|
||||
inline bool IsTrackable() const { return(trackable); }
|
||||
Timer* GetAIThinkTimer() { return AIthink_timer; }
|
||||
Timer* GetAIMovementTimer() { return AImovement_timer; }
|
||||
Timer* GetAIThinkTimer() { return AIthink_timer.get(); }
|
||||
Timer* GetAIMovementTimer() { return AImovement_timer.get(); }
|
||||
Timer GetAttackTimer() { return attack_timer; }
|
||||
Timer GetAttackDWTimer() { return attack_dw_timer; }
|
||||
inline bool IsFindable() { return findable; }
|
||||
@@ -930,6 +924,16 @@ public:
|
||||
void mod_spell_cast(uint16 spell_id, Mob* spelltar, bool reflect, bool use_resist_adjust, int16 resist_adjust, bool isproc);
|
||||
bool mod_will_aggro(Mob *attacker, Mob *on);
|
||||
|
||||
//Command #Tune functions
|
||||
int32 Tune_MeleeMitigation(Mob* GM, Mob *attacker, int32 damage, int32 minhit, ExtraAttackOptions *opts = nullptr, int Msg =0, int ac_override=0, int atk_override=0, int add_ac=0, int add_atk = 0);
|
||||
virtual int32 Tune_GetMeleeMitDmg(Mob* GM, Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||
uint32 Tune_GetMeanDamage(Mob* GM, Mob *attacker, int32 damage, int32 minhit, ExtraAttackOptions *opts = nullptr, int Msg = 0,int ac_override=0, int atk_override=0, int add_ac=0, int add_atk = 0);
|
||||
void Tune_FindATKByPctMitigation(Mob* defender, Mob *attacker, float pct_mitigation, int interval = 50, int max_loop = 100, int ac_override=0,int Msg =0);
|
||||
void Tune_FindACByPctMitigation(Mob* defender, Mob *attacker, float pct_mitigation, int interval = 50, int max_loop = 100, int atk_override=0,int Msg =0);
|
||||
float Tune_CheckHitChance(Mob* defender, Mob* attacker, SkillUseTypes skillinuse, int Hand, int16 chance_mod, int Msg = 1,int acc_override=0, int avoid_override=0, int add_acc=0, int add_avoid = 0);
|
||||
void Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int avoid_override, int Msg = 0);
|
||||
void Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int acc_override, int Msg = 0);
|
||||
|
||||
protected:
|
||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
|
||||
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
||||
@@ -1013,10 +1017,7 @@ protected:
|
||||
uint8 level;
|
||||
uint8 orig_level;
|
||||
uint32 npctype_id;
|
||||
float x_pos;
|
||||
float y_pos;
|
||||
float z_pos;
|
||||
float heading;
|
||||
glm::vec4 m_Position;
|
||||
uint16 animation;
|
||||
float base_size;
|
||||
float size;
|
||||
@@ -1049,7 +1050,7 @@ protected:
|
||||
virtual int16 GetFocusEffect(focusType type, uint16 spell_id) { return 0; }
|
||||
void CalculateNewFearpoint();
|
||||
float FindGroundZ(float new_x, float new_y, float z_offset=0.0);
|
||||
Map::Vertex UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange, bool &NodeReached);
|
||||
glm::vec3 UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange, bool &NodeReached);
|
||||
void PrintRoute();
|
||||
|
||||
virtual float GetSympatheticProcChances(uint16 spell_id, int16 ProcRateMod, int32 ItemProcRate = 0);
|
||||
@@ -1065,19 +1066,18 @@ protected:
|
||||
char clean_name[64];
|
||||
char lastname[64];
|
||||
|
||||
int32 delta_heading;
|
||||
float delta_x;
|
||||
float delta_y;
|
||||
float delta_z;
|
||||
glm::vec4 m_Delta;
|
||||
|
||||
uint8 light;
|
||||
uint8 innate_light; // defined by db field `npc_types`.`light` - where appropriate
|
||||
uint8 equip_light; // highest value of equipped/carried light-producing items
|
||||
uint8 spell_light; // set value of any light-producing spell (can be modded to mimic equip_light behavior)
|
||||
uint8 active_light; // highest value of all light sources
|
||||
|
||||
float fixedZ;
|
||||
EmuAppearance _appearance;
|
||||
uint8 pRunAnimSpeed;
|
||||
bool m_is_running;
|
||||
|
||||
|
||||
Timer attack_timer;
|
||||
Timer attack_dw_timer;
|
||||
Timer ranged_timer;
|
||||
@@ -1090,7 +1090,7 @@ protected:
|
||||
//spell casting vars
|
||||
Timer spellend_timer;
|
||||
uint16 casting_spell_id;
|
||||
float spell_x, spell_y, spell_z;
|
||||
glm::vec3 m_SpellLocation;
|
||||
int attacked_count;
|
||||
bool delaytimer;
|
||||
uint16 casting_spell_targetid;
|
||||
@@ -1109,9 +1109,8 @@ protected:
|
||||
bool ActiveProjectileATK;
|
||||
tProjatk ProjectileAtk[MAX_SPELL_PROJECTILE];
|
||||
|
||||
float rewind_x;
|
||||
float rewind_y;
|
||||
float rewind_z;
|
||||
glm::vec3 m_RewindLocation;
|
||||
|
||||
Timer rewind_timer;
|
||||
|
||||
// Currently 3 max nimbus particle effects at a time
|
||||
@@ -1172,14 +1171,14 @@ protected:
|
||||
uint32 maxLastFightingDelayMoving;
|
||||
float pAggroRange;
|
||||
float pAssistRange;
|
||||
Timer* AIthink_timer;
|
||||
Timer* AImovement_timer;
|
||||
Timer* AItarget_check_timer;
|
||||
std::unique_ptr<Timer> AIthink_timer;
|
||||
std::unique_ptr<Timer> AImovement_timer;
|
||||
std::unique_ptr<Timer> AItarget_check_timer;
|
||||
bool movetimercompleted;
|
||||
bool permarooted;
|
||||
Timer* AIscanarea_timer;
|
||||
Timer* AIwalking_timer;
|
||||
Timer* AIfeignremember_timer;
|
||||
std::unique_ptr<Timer> AIscanarea_timer;
|
||||
std::unique_ptr<Timer> AIwalking_timer;
|
||||
std::unique_ptr<Timer> AIfeignremember_timer;
|
||||
uint32 pLastFightingDelayMoving;
|
||||
HateList hate_list;
|
||||
std::set<uint32> feign_memory_list;
|
||||
@@ -1207,22 +1206,18 @@ protected:
|
||||
int pausetype;
|
||||
|
||||
int cur_wp;
|
||||
float cur_wp_x;
|
||||
float cur_wp_y;
|
||||
float cur_wp_z;
|
||||
glm::vec4 m_CurrentWayPoint;
|
||||
int cur_wp_pause;
|
||||
float cur_wp_heading;
|
||||
|
||||
|
||||
int patrol;
|
||||
float fear_walkto_x;
|
||||
float fear_walkto_y;
|
||||
float fear_walkto_z;
|
||||
glm::vec3 m_FearWalkTarget;
|
||||
bool curfp;
|
||||
|
||||
// Pathing
|
||||
//
|
||||
Map::Vertex PathingDestination;
|
||||
Map::Vertex PathingLastPosition;
|
||||
glm::vec3 PathingDestination;
|
||||
glm::vec3 PathingLastPosition;
|
||||
int PathingLoopCount;
|
||||
int PathingLastNodeVisited;
|
||||
std::deque<int> Route;
|
||||
@@ -1251,19 +1246,13 @@ protected:
|
||||
bool pet_owner_client; //Flags regular and pets as belonging to a client
|
||||
|
||||
EGNode *_egnode; //the EG node we are in
|
||||
float tarx;
|
||||
float tary;
|
||||
float tarz;
|
||||
glm::vec3 m_TargetLocation;
|
||||
uint8 tar_ndx;
|
||||
float tar_vector;
|
||||
float tar_vx;
|
||||
float tar_vy;
|
||||
float tar_vz;
|
||||
glm::vec3 m_TargetV;
|
||||
float test_vector;
|
||||
|
||||
float targetring_x;
|
||||
float targetring_y;
|
||||
float targetring_z;
|
||||
glm::vec3 m_TargetRing;
|
||||
|
||||
uint32 m_spellHitsLeft[38]; // Used to track which spells will have their numhits incremented when spell finishes casting, 38 Buffslots
|
||||
int flymode;
|
||||
|
||||
+118
-120
@@ -16,7 +16,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/features.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/string_util.h"
|
||||
@@ -45,7 +45,6 @@ extern Zone *zone;
|
||||
#else
|
||||
#define MobAI_DEBUG_Spells -1
|
||||
#endif
|
||||
#define ABS(x) ((x)<0?-(x):(x))
|
||||
|
||||
//NOTE: do NOT pass in beneficial and detrimental spell types into the same call here!
|
||||
bool NPC::AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes) {
|
||||
@@ -69,7 +68,7 @@ bool NPC::AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes) {
|
||||
dist2 = 0; //DistNoRoot(*this); //WTF was up with this...
|
||||
}
|
||||
else
|
||||
dist2 = DistNoRoot(*tar);
|
||||
dist2 = DistanceSquared(m_Position, tar->GetPosition());
|
||||
|
||||
bool checked_los = false; //we do not check LOS until we are absolutely sure we need to, and we only do it once.
|
||||
|
||||
@@ -357,7 +356,7 @@ bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float
|
||||
// according to Rogean, Live NPCs will just cast through walls/floors, no problem..
|
||||
//
|
||||
// This check was put in to address an idle-mob CPU issue
|
||||
_log(AI__ERROR, "Error: detrimental spells requested from AICheckCloseBeneficialSpells!!");
|
||||
Log.Out(Logs::General, Logs::Error, "Error: detrimental spells requested from AICheckCloseBeneficialSpells!!");
|
||||
return(false);
|
||||
}
|
||||
|
||||
@@ -403,7 +402,7 @@ bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float
|
||||
if (t1 > iRange
|
||||
|| t2 > iRange
|
||||
|| t3 > iRange
|
||||
|| mob->DistNoRoot(*caster) > iRange2
|
||||
|| DistanceSquared(mob->GetPosition(), caster->GetPosition()) > iRange2
|
||||
//this call should seem backwards:
|
||||
|| !mob->CheckLosFN(caster)
|
||||
|| mob->GetReverseFactionCon(caster) >= FACTION_KINDLY
|
||||
@@ -425,14 +424,15 @@ bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float
|
||||
return false;
|
||||
}
|
||||
|
||||
void Mob::AI_Init() {
|
||||
void Mob::AI_Init()
|
||||
{
|
||||
pAIControlled = false;
|
||||
AIthink_timer = 0;
|
||||
AIwalking_timer = 0;
|
||||
AImovement_timer = 0;
|
||||
AItarget_check_timer = 0;
|
||||
AIfeignremember_timer = nullptr;
|
||||
AIscanarea_timer = 0;
|
||||
AIthink_timer.reset(nullptr);
|
||||
AIwalking_timer.reset(nullptr);
|
||||
AImovement_timer.reset(nullptr);
|
||||
AItarget_check_timer.reset(nullptr);
|
||||
AIfeignremember_timer.reset(nullptr);
|
||||
AIscanarea_timer.reset(nullptr);
|
||||
minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin);
|
||||
maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax);
|
||||
|
||||
@@ -444,10 +444,9 @@ void Mob::AI_Init() {
|
||||
pDontCureMeBefore = 0;
|
||||
}
|
||||
|
||||
void NPC::AI_Init() {
|
||||
Mob::AI_Init();
|
||||
|
||||
AIautocastspell_timer = 0;
|
||||
void NPC::AI_Init()
|
||||
{
|
||||
AIautocastspell_timer.reset(nullptr);
|
||||
casting_spell_AIindex = static_cast<uint8>(AIspells.size());
|
||||
|
||||
roambox_max_x = 0;
|
||||
@@ -461,8 +460,8 @@ void NPC::AI_Init() {
|
||||
roambox_delay = 2500;
|
||||
}
|
||||
|
||||
void Client::AI_Init() {
|
||||
Mob::AI_Init();
|
||||
void Client::AI_Init()
|
||||
{
|
||||
minLastFightingDelayMoving = CLIENT_LD_TIMEOUT;
|
||||
maxLastFightingDelayMoving = CLIENT_LD_TIMEOUT;
|
||||
}
|
||||
@@ -477,13 +476,13 @@ void Mob::AI_Start(uint32 iMoveDelay) {
|
||||
pLastFightingDelayMoving = 0;
|
||||
|
||||
pAIControlled = true;
|
||||
AIthink_timer = new Timer(AIthink_duration);
|
||||
AIthink_timer = std::unique_ptr<Timer>(new Timer(AIthink_duration));
|
||||
AIthink_timer->Trigger();
|
||||
AIwalking_timer = new Timer(0);
|
||||
AImovement_timer = new Timer(AImovement_duration);
|
||||
AItarget_check_timer = new Timer(AItarget_check_duration);
|
||||
AIfeignremember_timer = new Timer(AIfeignremember_delay);
|
||||
AIscanarea_timer = new Timer(AIscanarea_delay);
|
||||
AIwalking_timer = std::unique_ptr<Timer>(new Timer(0));
|
||||
AImovement_timer = std::unique_ptr<Timer>(new Timer(AImovement_duration));
|
||||
AItarget_check_timer = std::unique_ptr<Timer>(new Timer(AItarget_check_duration));
|
||||
AIfeignremember_timer = std::unique_ptr<Timer>(new Timer(AIfeignremember_delay));
|
||||
AIscanarea_timer = std::unique_ptr<Timer>(new Timer(AIscanarea_delay));
|
||||
#ifdef REVERSE_AGGRO
|
||||
if(IsNPC() && !CastToNPC()->WillAggroNPCs())
|
||||
AIscanarea_timer->Disable();
|
||||
@@ -495,10 +494,7 @@ void Mob::AI_Start(uint32 iMoveDelay) {
|
||||
pAssistRange = 70;
|
||||
hate_list.WipeHateList();
|
||||
|
||||
delta_heading = 0;
|
||||
delta_x = 0;
|
||||
delta_y = 0;
|
||||
delta_z = 0;
|
||||
m_Delta = glm::vec4();
|
||||
pRunAnimSpeed = 0;
|
||||
pLastChange = Timer::GetCurrentTime();
|
||||
}
|
||||
@@ -522,10 +518,10 @@ void NPC::AI_Start(uint32 iMoveDelay) {
|
||||
return;
|
||||
|
||||
if (AIspells.size() == 0) {
|
||||
AIautocastspell_timer = new Timer(1000);
|
||||
AIautocastspell_timer = std::unique_ptr<Timer>(new Timer(1000));
|
||||
AIautocastspell_timer->Disable();
|
||||
} else {
|
||||
AIautocastspell_timer = new Timer(750);
|
||||
AIautocastspell_timer = std::unique_ptr<Timer>(new Timer(750));
|
||||
AIautocastspell_timer->Start(RandomTimer(0, 15000), false);
|
||||
}
|
||||
|
||||
@@ -546,19 +542,19 @@ void Mob::AI_Stop() {
|
||||
|
||||
pAIControlled = false;
|
||||
|
||||
safe_delete(AIthink_timer);
|
||||
safe_delete(AIwalking_timer);
|
||||
safe_delete(AImovement_timer);
|
||||
safe_delete(AItarget_check_timer);
|
||||
safe_delete(AIscanarea_timer);
|
||||
safe_delete(AIfeignremember_timer);
|
||||
AIthink_timer.reset(nullptr);
|
||||
AIwalking_timer.reset(nullptr);
|
||||
AImovement_timer.reset(nullptr);
|
||||
AItarget_check_timer.reset(nullptr);
|
||||
AIscanarea_timer.reset(nullptr);
|
||||
AIfeignremember_timer.reset(nullptr);
|
||||
|
||||
hate_list.WipeHateList();
|
||||
}
|
||||
|
||||
void NPC::AI_Stop() {
|
||||
Waypoints.clear();
|
||||
safe_delete(AIautocastspell_timer);
|
||||
AIautocastspell_timer.reset(nullptr);
|
||||
}
|
||||
|
||||
void Client::AI_Stop() {
|
||||
@@ -627,7 +623,7 @@ void Client::AI_SpellCast()
|
||||
if(!targ)
|
||||
return;
|
||||
|
||||
float dist = DistNoRootNoZ(*targ);
|
||||
float dist = DistanceSquaredNoZ(m_Position, targ->GetPosition());
|
||||
|
||||
std::vector<uint32> valid_spells;
|
||||
std::vector<uint32> slots;
|
||||
@@ -789,17 +785,18 @@ void Client::AI_Process()
|
||||
if(AImovement_timer->Check()) {
|
||||
animation = GetRunspeed() * 21;
|
||||
// Check if we have reached the last fear point
|
||||
if((ABS(GetX()-fear_walkto_x) < 0.1) && (ABS(GetY()-fear_walkto_y) <0.1)) {
|
||||
if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) &&
|
||||
(std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) {
|
||||
// Calculate a new point to run to
|
||||
CalculateNewFearpoint();
|
||||
}
|
||||
if(!RuleB(Pathing, Fear) || !zone->pathing)
|
||||
CalculateNewPosition2(fear_walkto_x, fear_walkto_y, fear_walkto_z, GetFearSpeed(), true);
|
||||
CalculateNewPosition2(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, GetFearSpeed(), true);
|
||||
else
|
||||
{
|
||||
bool WaypointChanged, NodeReached;
|
||||
|
||||
Map::Vertex Goal = UpdatePath(fear_walkto_x, fear_walkto_y, fear_walkto_z,
|
||||
glm::vec3 Goal = UpdatePath(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z,
|
||||
GetFearSpeed(), WaypointChanged, NodeReached);
|
||||
|
||||
if(WaypointChanged)
|
||||
@@ -955,7 +952,7 @@ void Client::AI_Process()
|
||||
else
|
||||
{
|
||||
bool WaypointChanged, NodeReached;
|
||||
Map::Vertex Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(),
|
||||
glm::vec3 Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(),
|
||||
GetRunspeed(), WaypointChanged, NodeReached);
|
||||
|
||||
if(WaypointChanged)
|
||||
@@ -1002,7 +999,7 @@ void Client::AI_Process()
|
||||
if(owner == nullptr)
|
||||
return;
|
||||
|
||||
float dist = DistNoRoot(*owner);
|
||||
float dist = DistanceSquared(m_Position, owner->GetPosition());
|
||||
if (dist >= 100)
|
||||
{
|
||||
float speed = dist >= 225 ? GetRunspeed() : GetWalkspeed();
|
||||
@@ -1057,17 +1054,18 @@ void Mob::AI_Process() {
|
||||
} else {
|
||||
if(AImovement_timer->Check()) {
|
||||
// Check if we have reached the last fear point
|
||||
if((ABS(GetX()-fear_walkto_x) < 0.1) && (ABS(GetY()-fear_walkto_y) <0.1)) {
|
||||
if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) &&
|
||||
(std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) {
|
||||
// Calculate a new point to run to
|
||||
CalculateNewFearpoint();
|
||||
}
|
||||
if(!RuleB(Pathing, Fear) || !zone->pathing)
|
||||
CalculateNewPosition2(fear_walkto_x, fear_walkto_y, fear_walkto_z, GetFearSpeed(), true);
|
||||
CalculateNewPosition2(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, GetFearSpeed(), true);
|
||||
else
|
||||
{
|
||||
bool WaypointChanged, NodeReached;
|
||||
|
||||
Map::Vertex Goal = UpdatePath(fear_walkto_x, fear_walkto_y, fear_walkto_z,
|
||||
glm::vec3 Goal = UpdatePath(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z,
|
||||
GetFearSpeed(), WaypointChanged, NodeReached);
|
||||
|
||||
if(WaypointChanged)
|
||||
@@ -1129,19 +1127,20 @@ void Mob::AI_Process() {
|
||||
if(DivineAura())
|
||||
return;
|
||||
|
||||
auto npcSpawnPoint = CastToNPC()->GetSpawnPoint();
|
||||
if(GetSpecialAbility(TETHER)) {
|
||||
float tether_range = static_cast<float>(GetSpecialAbilityParam(TETHER, 0));
|
||||
tether_range = tether_range > 0.0f ? tether_range * tether_range : pAggroRange * pAggroRange;
|
||||
|
||||
if(DistNoRootNoZ(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY()) > tether_range) {
|
||||
GMMove(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY(), CastToNPC()->GetSpawnPointZ(), CastToNPC()->GetSpawnPointH());
|
||||
if(DistanceSquaredNoZ(m_Position, npcSpawnPoint) > tether_range) {
|
||||
GMMove(npcSpawnPoint.x, npcSpawnPoint.y, npcSpawnPoint.z, npcSpawnPoint.w);
|
||||
}
|
||||
} else if(GetSpecialAbility(LEASH)) {
|
||||
float leash_range = static_cast<float>(GetSpecialAbilityParam(LEASH, 0));
|
||||
leash_range = leash_range > 0.0f ? leash_range * leash_range : pAggroRange * pAggroRange;
|
||||
|
||||
if(DistNoRootNoZ(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY()) > leash_range) {
|
||||
GMMove(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY(), CastToNPC()->GetSpawnPointZ(), CastToNPC()->GetSpawnPointH());
|
||||
if(DistanceSquaredNoZ(m_Position, npcSpawnPoint) > leash_range) {
|
||||
GMMove(npcSpawnPoint.x, npcSpawnPoint.y, npcSpawnPoint.z, npcSpawnPoint.w);
|
||||
SetHP(GetMaxHP());
|
||||
BuffFadeAll();
|
||||
WipeHateList();
|
||||
@@ -1375,7 +1374,8 @@ void Mob::AI_Process() {
|
||||
//we cannot reach our target...
|
||||
//underwater stuff only works with water maps in the zone!
|
||||
if(IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
||||
if(!zone->watermap->InLiquid(target->GetX(), target->GetY(), target->GetZ())) {
|
||||
auto targetPosition = glm::vec3(target->GetX(), target->GetY(), target->GetZ());
|
||||
if(!zone->watermap->InLiquid(targetPosition)) {
|
||||
Mob *tar = hate_list.GetEntWithMostHateOnList(this);
|
||||
if(tar == target) {
|
||||
WipeHateList();
|
||||
@@ -1406,14 +1406,14 @@ void Mob::AI_Process() {
|
||||
else if (AImovement_timer->Check())
|
||||
{
|
||||
if(!IsRooted()) {
|
||||
mlog(AI__WAYPOINTS, "Pursuing %s while engaged.", target->GetName());
|
||||
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", target->GetName());
|
||||
if(!RuleB(Pathing, Aggro) || !zone->pathing)
|
||||
CalculateNewPosition2(target->GetX(), target->GetY(), target->GetZ(), GetRunspeed());
|
||||
else
|
||||
{
|
||||
bool WaypointChanged, NodeReached;
|
||||
|
||||
Map::Vertex Goal = UpdatePath(target->GetX(), target->GetY(), target->GetZ(),
|
||||
glm::vec3 Goal = UpdatePath(target->GetX(), target->GetY(), target->GetZ(),
|
||||
GetRunspeed(), WaypointChanged, NodeReached);
|
||||
|
||||
if(WaypointChanged)
|
||||
@@ -1495,7 +1495,7 @@ void Mob::AI_Process() {
|
||||
//if(owner->IsClient())
|
||||
// printf("Pet start pos: (%f, %f, %f)\n", GetX(), GetY(), GetZ());
|
||||
|
||||
float dist = DistNoRoot(*owner);
|
||||
float dist = DistanceSquared(m_Position, owner->GetPosition());
|
||||
if (dist >= 400)
|
||||
{
|
||||
float speed = GetWalkspeed();
|
||||
@@ -1550,7 +1550,7 @@ void Mob::AI_Process() {
|
||||
if (!follow) SetFollowID(0);
|
||||
else
|
||||
{
|
||||
float dist2 = DistNoRoot(*follow);
|
||||
float dist2 = DistanceSquared(m_Position, follow->GetPosition());
|
||||
int followdist = GetFollowDistance();
|
||||
|
||||
if (dist2 >= followdist) // Default follow distance is 100
|
||||
@@ -1641,7 +1641,7 @@ void NPC::AI_DoMovement() {
|
||||
roambox_movingto_y = zone->random.Real(roambox_min_y+1,roambox_max_y-1);
|
||||
}
|
||||
|
||||
mlog(AI__WAYPOINTS, "Roam Box: d=%.3f (%.3f->%.3f,%.3f->%.3f): Go To (%.3f,%.3f)",
|
||||
Log.Out(Logs::Detail, Logs::AI, "Roam Box: d=%.3f (%.3f->%.3f,%.3f->%.3f): Go To (%.3f,%.3f)",
|
||||
roambox_distance, roambox_min_x, roambox_max_x, roambox_min_y, roambox_max_y, roambox_movingto_x, roambox_movingto_y);
|
||||
if (!CalculateNewPosition2(roambox_movingto_x, roambox_movingto_y, GetZ(), walksp, true))
|
||||
{
|
||||
@@ -1694,11 +1694,11 @@ void NPC::AI_DoMovement() {
|
||||
else {
|
||||
movetimercompleted=false;
|
||||
|
||||
mlog(QUESTS__PATHING, "We are departing waypoint %d.", cur_wp);
|
||||
Log.Out(Logs::Detail, Logs::Pathing, "We are departing waypoint %d.", cur_wp);
|
||||
|
||||
//if we were under quest control (with no grid), we are done now..
|
||||
if(cur_wp == -2) {
|
||||
mlog(QUESTS__PATHING, "Non-grid quest mob has reached its quest ordered waypoint. Leaving pathing mode.");
|
||||
Log.Out(Logs::Detail, Logs::Pathing, "Non-grid quest mob has reached its quest ordered waypoint. Leaving pathing mode.");
|
||||
roamer = false;
|
||||
cur_wp = 0;
|
||||
}
|
||||
@@ -1727,15 +1727,15 @@ void NPC::AI_DoMovement() {
|
||||
} // endif (movetimercompleted==true)
|
||||
else if (!(AIwalking_timer->Enabled()))
|
||||
{ // currently moving
|
||||
if (cur_wp_x == GetX() && cur_wp_y == GetY())
|
||||
if (m_CurrentWayPoint.x == GetX() && m_CurrentWayPoint.y == GetY())
|
||||
{ // are we there yet? then stop
|
||||
mlog(AI__WAYPOINTS, "We have reached waypoint %d (%.3f,%.3f,%.3f) on grid %d", cur_wp, GetX(), GetY(), GetZ(), GetGrid());
|
||||
Log.Out(Logs::Detail, Logs::AI, "We have reached waypoint %d (%.3f,%.3f,%.3f) on grid %d", cur_wp, GetX(), GetY(), GetZ(), GetGrid());
|
||||
SetWaypointPause();
|
||||
if(GetAppearance() != eaStanding)
|
||||
SetAppearance(eaStanding, false);
|
||||
SetMoving(false);
|
||||
if (cur_wp_heading >= 0.0) {
|
||||
SetHeading(cur_wp_heading);
|
||||
if (m_CurrentWayPoint.w >= 0.0) {
|
||||
SetHeading(m_CurrentWayPoint.w);
|
||||
}
|
||||
SendPosition();
|
||||
|
||||
@@ -1751,12 +1751,12 @@ void NPC::AI_DoMovement() {
|
||||
else
|
||||
{ // not at waypoint yet, so keep moving
|
||||
if(!RuleB(Pathing, AggroReturnToGrid) || !zone->pathing || (DistractedFromGrid == 0))
|
||||
CalculateNewPosition2(cur_wp_x, cur_wp_y, cur_wp_z, walksp, true);
|
||||
CalculateNewPosition2(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, true);
|
||||
else
|
||||
{
|
||||
bool WaypointChanged;
|
||||
bool NodeReached;
|
||||
Map::Vertex Goal = UpdatePath(cur_wp_x, cur_wp_y, cur_wp_z, walksp, WaypointChanged, NodeReached);
|
||||
glm::vec3 Goal = UpdatePath(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, WaypointChanged, NodeReached);
|
||||
if(WaypointChanged)
|
||||
tar_ndx = 20;
|
||||
|
||||
@@ -1775,7 +1775,7 @@ void NPC::AI_DoMovement() {
|
||||
if (movetimercompleted==true)
|
||||
{ // time to pause has ended
|
||||
SetGrid( 0 - GetGrid()); // revert to AI control
|
||||
mlog(QUESTS__PATHING, "Quest pathing is finished. Resuming on grid %d", GetGrid());
|
||||
Log.Out(Logs::Detail, Logs::Pathing, "Quest pathing is finished. Resuming on grid %d", GetGrid());
|
||||
|
||||
if(GetAppearance() != eaStanding)
|
||||
SetAppearance(eaStanding, false);
|
||||
@@ -1789,13 +1789,13 @@ void NPC::AI_DoMovement() {
|
||||
{
|
||||
bool CP2Moved;
|
||||
if(!RuleB(Pathing, Guard) || !zone->pathing)
|
||||
CP2Moved = CalculateNewPosition2(guard_x, guard_y, guard_z, walksp);
|
||||
CP2Moved = CalculateNewPosition2(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, walksp);
|
||||
else
|
||||
{
|
||||
if(!((x_pos == guard_x) && (y_pos == guard_y) && (z_pos == guard_z)))
|
||||
if(!((m_Position.x == m_GuardPoint.x) && (m_Position.y == m_GuardPoint.y) && (m_Position.z == m_GuardPoint.z)))
|
||||
{
|
||||
bool WaypointChanged, NodeReached;
|
||||
Map::Vertex Goal = UpdatePath(guard_x, guard_y, guard_z, walksp, WaypointChanged, NodeReached);
|
||||
glm::vec3 Goal = UpdatePath(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, walksp, WaypointChanged, NodeReached);
|
||||
if(WaypointChanged)
|
||||
tar_ndx = 20;
|
||||
|
||||
@@ -1811,13 +1811,13 @@ void NPC::AI_DoMovement() {
|
||||
if (!CP2Moved)
|
||||
{
|
||||
if(moved) {
|
||||
mlog(AI__WAYPOINTS, "Reached guard point (%.3f,%.3f,%.3f)", guard_x, guard_y, guard_z);
|
||||
Log.Out(Logs::Detail, Logs::AI, "Reached guard point (%.3f,%.3f,%.3f)", m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z);
|
||||
ClearFeignMemory();
|
||||
moved=false;
|
||||
SetMoving(false);
|
||||
if (GetTarget() == nullptr || DistNoRoot(*GetTarget()) >= 5*5 )
|
||||
if (GetTarget() == nullptr || DistanceSquared(m_Position, GetTarget()->GetPosition()) >= 5*5 )
|
||||
{
|
||||
SetHeading(guard_heading);
|
||||
SetHeading(m_GuardPoint.w);
|
||||
} else {
|
||||
FaceTarget(GetTarget());
|
||||
}
|
||||
@@ -1954,7 +1954,7 @@ bool NPC::AI_EngagedCastCheck() {
|
||||
if (AIautocastspell_timer->Check(false)) {
|
||||
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
|
||||
|
||||
mlog(AI__SPELLS, "Engaged autocast check triggered. Trying to cast healing spells then maybe offensive spells.");
|
||||
Log.Out(Logs::Detail, Logs::AI, "Engaged autocast check triggered. Trying to cast healing spells then maybe offensive spells.");
|
||||
|
||||
// try casting a heal or gate
|
||||
if (!AICastSpell(this, AISpellVar.engaged_beneficial_self_chance, SpellType_Heal | SpellType_Escape | SpellType_InCombatBuff)) {
|
||||
@@ -1977,7 +1977,7 @@ bool NPC::AI_PursueCastCheck() {
|
||||
if (AIautocastspell_timer->Check(false)) {
|
||||
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
|
||||
|
||||
mlog(AI__SPELLS, "Engaged (pursuing) autocast check triggered. Trying to cast offensive spells.");
|
||||
Log.Out(Logs::Detail, Logs::AI, "Engaged (pursuing) autocast check triggered. Trying to cast offensive spells.");
|
||||
if(!AICastSpell(GetTarget(), AISpellVar.pursue_detrimental_chance, SpellType_Root | SpellType_Nuke | SpellType_Lifetap | SpellType_Snare | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Slow | SpellType_Debuff)) {
|
||||
//no spell cast, try again soon.
|
||||
AIautocastspell_timer->Start(RandomTimer(AISpellVar.pursue_no_sp_recast_min, AISpellVar.pursue_no_sp_recast_max), false);
|
||||
@@ -2677,7 +2677,7 @@ DBnpcspells_Struct* ZoneDatabase::GetNPCSpells(uint32 iDBSpellsID) {
|
||||
npc_spells_cache = new DBnpcspells_Struct*[npc_spells_maxid+1];
|
||||
npc_spells_loadtried = new bool[npc_spells_maxid+1];
|
||||
for (uint32 i=0; i<=npc_spells_maxid; i++) {
|
||||
npc_spells_cache[i] = 0;
|
||||
npc_spells_cache[i] = nullptr;
|
||||
npc_spells_loadtried[i] = false;
|
||||
}
|
||||
}
|
||||
@@ -2700,7 +2700,6 @@ DBnpcspells_Struct* ZoneDatabase::GetNPCSpells(uint32 iDBSpellsID) {
|
||||
"idle_b_chance FROM npc_spells WHERE id=%d", iDBSpellsID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
std::cerr << "Error in AddNPCSpells query1 '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -2736,7 +2735,6 @@ DBnpcspells_Struct* ZoneDatabase::GetNPCSpells(uint32 iDBSpellsID) {
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
std::cerr << "Error in AddNPCSpells query1 '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -2793,7 +2791,6 @@ uint32 ZoneDatabase::GetMaxNPCSpellsID() {
|
||||
std::string query = "SELECT max(id) from npc_spells";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
std::cerr << "Error in GetMaxNPCSpellsID query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2808,16 +2805,17 @@ uint32 ZoneDatabase::GetMaxNPCSpellsID() {
|
||||
return atoi(row[0]);
|
||||
}
|
||||
|
||||
DBnpcspellseffects_Struct* ZoneDatabase::GetNPCSpellsEffects(uint32 iDBSpellsEffectsID) {
|
||||
DBnpcspellseffects_Struct *ZoneDatabase::GetNPCSpellsEffects(uint32 iDBSpellsEffectsID)
|
||||
{
|
||||
if (iDBSpellsEffectsID == 0)
|
||||
return nullptr;
|
||||
|
||||
if (!npc_spellseffects_cache) {
|
||||
npc_spellseffects_maxid = GetMaxNPCSpellsEffectsID();
|
||||
npc_spellseffects_cache = new DBnpcspellseffects_Struct*[npc_spellseffects_maxid+1];
|
||||
npc_spellseffects_loadtried = new bool[npc_spellseffects_maxid+1];
|
||||
for (uint32 i=0; i<=npc_spellseffects_maxid; i++) {
|
||||
npc_spellseffects_cache[i] = 0;
|
||||
npc_spellseffects_cache = new DBnpcspellseffects_Struct *[npc_spellseffects_maxid + 1];
|
||||
npc_spellseffects_loadtried = new bool[npc_spellseffects_maxid + 1];
|
||||
for (uint32 i = 0; i <= npc_spellseffects_maxid; i++) {
|
||||
npc_spellseffects_cache[i] = nullptr;
|
||||
npc_spellseffects_loadtried[i] = false;
|
||||
}
|
||||
}
|
||||
@@ -2825,54 +2823,55 @@ DBnpcspellseffects_Struct* ZoneDatabase::GetNPCSpellsEffects(uint32 iDBSpellsEff
|
||||
if (iDBSpellsEffectsID > npc_spellseffects_maxid)
|
||||
return nullptr;
|
||||
|
||||
if (npc_spellseffects_cache[iDBSpellsEffectsID]) // it's in the cache, easy =)
|
||||
if (npc_spellseffects_cache[iDBSpellsEffectsID]) // it's in the cache, easy =)
|
||||
return npc_spellseffects_cache[iDBSpellsEffectsID];
|
||||
|
||||
if (npc_spellseffects_loadtried[iDBSpellsEffectsID])
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
|
||||
npc_spellseffects_loadtried[iDBSpellsEffectsID] = true;
|
||||
npc_spellseffects_loadtried[iDBSpellsEffectsID] = true;
|
||||
|
||||
std::string query = StringFormat("SELECT id, parent_list FROM npc_spells_effects WHERE id=%d", iDBSpellsEffectsID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
std::cerr << "Error in AddNPCSpells query1 '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
std::string query =
|
||||
StringFormat("SELECT id, parent_list FROM npc_spells_effects WHERE id=%d", iDBSpellsEffectsID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (results.RowCount() != 1)
|
||||
return nullptr;
|
||||
if (results.RowCount() != 1)
|
||||
return nullptr;
|
||||
|
||||
auto row = results.begin();
|
||||
uint32 tmpparent_list = atoi(row[1]);
|
||||
auto row = results.begin();
|
||||
uint32 tmpparent_list = atoi(row[1]);
|
||||
|
||||
query = StringFormat("SELECT spell_effect_id, minlevel, "
|
||||
"maxlevel,se_base, se_limit, se_max "
|
||||
"FROM npc_spells_effects_entries "
|
||||
"WHERE npc_spells_effects_id = %d ORDER BY minlevel", iDBSpellsEffectsID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return nullptr;
|
||||
query = StringFormat("SELECT spell_effect_id, minlevel, "
|
||||
"maxlevel,se_base, se_limit, se_max "
|
||||
"FROM npc_spells_effects_entries "
|
||||
"WHERE npc_spells_effects_id = %d ORDER BY minlevel",
|
||||
iDBSpellsEffectsID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return nullptr;
|
||||
|
||||
uint32 tmpSize = sizeof(DBnpcspellseffects_Struct) + (sizeof(DBnpcspellseffects_entries_Struct) * results.RowCount());
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID] = (DBnpcspellseffects_Struct*) new uchar[tmpSize];
|
||||
memset(npc_spellseffects_cache[iDBSpellsEffectsID], 0, tmpSize);
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->parent_list = tmpparent_list;
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->numentries = results.RowCount();
|
||||
uint32 tmpSize =
|
||||
sizeof(DBnpcspellseffects_Struct) + (sizeof(DBnpcspellseffects_entries_Struct) * results.RowCount());
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID] = (DBnpcspellseffects_Struct *)new uchar[tmpSize];
|
||||
memset(npc_spellseffects_cache[iDBSpellsEffectsID], 0, tmpSize);
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->parent_list = tmpparent_list;
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->numentries = results.RowCount();
|
||||
|
||||
int entryIndex = 0;
|
||||
for (row = results.begin(); row != results.end(); ++row, ++entryIndex)
|
||||
{
|
||||
int spell_effect_id = atoi(row[0]);
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->entries[entryIndex].spelleffectid = spell_effect_id;
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->entries[entryIndex].minlevel = atoi(row[1]);
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->entries[entryIndex].maxlevel = atoi(row[2]);
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->entries[entryIndex].base = atoi(row[3]);
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->entries[entryIndex].limit = atoi(row[4]);
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->entries[entryIndex].max = atoi(row[5]);
|
||||
}
|
||||
int entryIndex = 0;
|
||||
for (row = results.begin(); row != results.end(); ++row, ++entryIndex) {
|
||||
int spell_effect_id = atoi(row[0]);
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->entries[entryIndex].spelleffectid = spell_effect_id;
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->entries[entryIndex].minlevel = atoi(row[1]);
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->entries[entryIndex].maxlevel = atoi(row[2]);
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->entries[entryIndex].base = atoi(row[3]);
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->entries[entryIndex].limit = atoi(row[4]);
|
||||
npc_spellseffects_cache[iDBSpellsEffectsID]->entries[entryIndex].max = atoi(row[5]);
|
||||
}
|
||||
|
||||
return npc_spellseffects_cache[iDBSpellsEffectsID];
|
||||
return npc_spellseffects_cache[iDBSpellsEffectsID];
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::GetMaxNPCSpellsEffectsID() {
|
||||
@@ -2880,7 +2879,6 @@ uint32 ZoneDatabase::GetMaxNPCSpellsEffectsID() {
|
||||
std::string query = "SELECT max(id) FROM npc_spells_effects";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
std::cerr << "Error in GetMaxNPCSpellsEffectsID query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+83
-105
@@ -17,8 +17,9 @@
|
||||
*/
|
||||
|
||||
#define DONT_SHARED_OPCODES
|
||||
#define PLATFORM_ZONE 1
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/features.h"
|
||||
#include "../common/queue.h"
|
||||
#include "../common/timer.h"
|
||||
@@ -27,7 +28,7 @@
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/mutex.h"
|
||||
#include "../common/version.h"
|
||||
#include "../common/eqemu_error.h"
|
||||
|
||||
#include "../common/packet_dump_file.h"
|
||||
#include "../common/opcodemgr.h"
|
||||
#include "../common/guilds.h"
|
||||
@@ -42,6 +43,8 @@
|
||||
#include "../common/memory_mapped_file.h"
|
||||
#include "../common/eqemu_exception.h"
|
||||
#include "../common/spdat.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
|
||||
|
||||
#include "zone_config.h"
|
||||
#include "masterentity.h"
|
||||
@@ -57,7 +60,7 @@
|
||||
#include "quest_parser_collection.h"
|
||||
#include "embparser.h"
|
||||
#include "lua_parser.h"
|
||||
#include "client_logs.h"
|
||||
|
||||
#include "questmgr.h"
|
||||
#include "remote_call.h"
|
||||
#include "remote_call_subscribe.h"
|
||||
@@ -70,6 +73,7 @@
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <ctime>
|
||||
|
||||
#ifdef _CRTDBG_MAP_ALLOC
|
||||
#undef new
|
||||
@@ -101,6 +105,7 @@ TitleManager title_manager;
|
||||
QueryServ *QServ = 0;
|
||||
TaskManager *taskmanager = 0;
|
||||
QuestParserCollection *parse = 0;
|
||||
EQEmuLogSys Log;
|
||||
|
||||
const SPDat_Spell_Struct* spells;
|
||||
void LoadSpells(EQEmu::MemoryMappedFile **mmf);
|
||||
@@ -111,6 +116,7 @@ extern void MapOpcodes();
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
RegisterExecutablePlatform(ExePlatformZone);
|
||||
Log.LoadLogSettingsDefaults();
|
||||
set_exception_handler();
|
||||
register_remote_call_handlers();
|
||||
|
||||
@@ -144,144 +150,144 @@ int main(int argc, char** argv) {
|
||||
worldserver.SetLauncherName("NONE");
|
||||
}
|
||||
|
||||
_log(ZONE__INIT, "Loading server configuration..");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading server configuration..");
|
||||
if (!ZoneConfig::LoadConfig()) {
|
||||
_log(ZONE__INIT_ERR, "Loading server configuration failed.");
|
||||
Log.Out(Logs::General, Logs::Error, "Loading server configuration failed.");
|
||||
return 1;
|
||||
}
|
||||
const ZoneConfig *Config=ZoneConfig::get();
|
||||
|
||||
if(!load_log_settings(Config->LogSettingsFile.c_str()))
|
||||
_log(ZONE__INIT, "Warning: Unable to read %s", Config->LogSettingsFile.c_str());
|
||||
else
|
||||
_log(ZONE__INIT, "Log settings loaded from %s", Config->LogSettingsFile.c_str());
|
||||
const ZoneConfig *Config = ZoneConfig::get();
|
||||
|
||||
worldserver.SetPassword(Config->SharedKey.c_str());
|
||||
|
||||
_log(ZONE__INIT, "Connecting to MySQL...");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Connecting to MySQL...");
|
||||
if (!database.Connect(
|
||||
Config->DatabaseHost.c_str(),
|
||||
Config->DatabaseUsername.c_str(),
|
||||
Config->DatabasePassword.c_str(),
|
||||
Config->DatabaseDB.c_str(),
|
||||
Config->DatabasePort)) {
|
||||
_log(ZONE__INIT_ERR, "Cannot continue without a database connection.");
|
||||
Log.Out(Logs::General, Logs::Error, "Cannot continue without a database connection.");
|
||||
return 1;
|
||||
}
|
||||
guild_mgr.SetDatabase(&database);
|
||||
|
||||
/* Register Log System and Settings */
|
||||
Log.OnLogHookCallBackZone(&Zone::GMSayHookCallBackProcess);
|
||||
database.LoadLogSettings(Log.log_settings);
|
||||
Log.StartFileLogs();
|
||||
|
||||
/* Guilds */
|
||||
guild_mgr.SetDatabase(&database);
|
||||
GuildBanks = nullptr;
|
||||
|
||||
#ifdef _EQDEBUG
|
||||
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||
#endif
|
||||
|
||||
_log(ZONE__INIT, "CURRENT_VERSION: %s", CURRENT_VERSION);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "CURRENT_VERSION: %s", CURRENT_VERSION);
|
||||
|
||||
/*
|
||||
* Setup nice signal handlers
|
||||
*/
|
||||
if (signal(SIGINT, CatchSignal) == SIG_ERR) {
|
||||
_log(ZONE__INIT_ERR, "Could not set signal handler");
|
||||
Log.Out(Logs::General, Logs::Error, "Could not set signal handler");
|
||||
return 1;
|
||||
}
|
||||
if (signal(SIGTERM, CatchSignal) == SIG_ERR) {
|
||||
_log(ZONE__INIT_ERR, "Could not set signal handler");
|
||||
Log.Out(Logs::General, Logs::Error, "Could not set signal handler");
|
||||
return 1;
|
||||
}
|
||||
#ifndef WIN32
|
||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
|
||||
_log(ZONE__INIT_ERR, "Could not set signal handler");
|
||||
Log.Out(Logs::General, Logs::Error, "Could not set signal handler");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *log_ini_file = "./log.ini";
|
||||
if(!load_log_settings(log_ini_file))
|
||||
_log(ZONE__INIT, "Warning: Unable to read %s", log_ini_file);
|
||||
else
|
||||
_log(ZONE__INIT, "Log settings loaded from %s", log_ini_file);
|
||||
|
||||
_log(ZONE__INIT, "Mapping Incoming Opcodes");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Mapping Incoming Opcodes");
|
||||
MapOpcodes();
|
||||
_log(ZONE__INIT, "Loading Variables");
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading Variables");
|
||||
database.LoadVariables();
|
||||
_log(ZONE__INIT, "Loading zone names");
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading zone names");
|
||||
database.LoadZoneNames();
|
||||
_log(ZONE__INIT, "Loading items");
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading items");
|
||||
if (!database.LoadItems()) {
|
||||
_log(ZONE__INIT_ERR, "Loading items FAILED!");
|
||||
_log(ZONE__INIT, "Failed. But ignoring error and going on...");
|
||||
Log.Out(Logs::General, Logs::Error, "Loading items FAILED!");
|
||||
Log.Out(Logs::General, Logs::Error, "Failed. But ignoring error and going on...");
|
||||
}
|
||||
|
||||
_log(ZONE__INIT, "Loading npc faction lists");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading npc faction lists");
|
||||
if (!database.LoadNPCFactionLists()) {
|
||||
_log(ZONE__INIT_ERR, "Loading npcs faction lists FAILED!");
|
||||
CheckEQEMuErrorAndPause();
|
||||
Log.Out(Logs::General, Logs::Error, "Loading npcs faction lists FAILED!");
|
||||
return 1;
|
||||
}
|
||||
_log(ZONE__INIT, "Loading loot tables");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading loot tables");
|
||||
if (!database.LoadLoot()) {
|
||||
_log(ZONE__INIT_ERR, "Loading loot FAILED!");
|
||||
CheckEQEMuErrorAndPause();
|
||||
Log.Out(Logs::General, Logs::Error, "Loading loot FAILED!");
|
||||
return 1;
|
||||
}
|
||||
_log(ZONE__INIT, "Loading skill caps");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading skill caps");
|
||||
if (!database.LoadSkillCaps()) {
|
||||
_log(ZONE__INIT_ERR, "Loading skill caps FAILED!");
|
||||
CheckEQEMuErrorAndPause();
|
||||
Log.Out(Logs::General, Logs::Error, "Loading skill caps FAILED!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
_log(ZONE__INIT, "Loading spells");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading spells");
|
||||
EQEmu::MemoryMappedFile *mmf = nullptr;
|
||||
LoadSpells(&mmf);
|
||||
|
||||
_log(ZONE__INIT, "Loading base data");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading base data");
|
||||
if (!database.LoadBaseData()) {
|
||||
_log(ZONE__INIT_ERR, "Loading base data FAILED!");
|
||||
CheckEQEMuErrorAndPause();
|
||||
Log.Out(Logs::General, Logs::Error, "Loading base data FAILED!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
_log(ZONE__INIT, "Loading guilds");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading guilds");
|
||||
guild_mgr.LoadGuilds();
|
||||
_log(ZONE__INIT, "Loading factions");
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading factions");
|
||||
database.LoadFactionData();
|
||||
_log(ZONE__INIT, "Loading titles");
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading titles");
|
||||
title_manager.LoadTitles();
|
||||
_log(ZONE__INIT, "Loading AA effects");
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading AA effects");
|
||||
database.LoadAAEffects();
|
||||
_log(ZONE__INIT, "Loading tributes");
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading tributes");
|
||||
database.LoadTributes();
|
||||
_log(ZONE__INIT, "Loading corpse timers");
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading corpse timers");
|
||||
database.GetDecayTimes(npcCorpseDecayTimes);
|
||||
_log(ZONE__INIT, "Loading commands");
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading commands");
|
||||
int retval=command_init();
|
||||
if(retval<0)
|
||||
_log(ZONE__INIT_ERR, "Command loading FAILED");
|
||||
Log.Out(Logs::General, Logs::Error, "Command loading FAILED");
|
||||
else
|
||||
_log(ZONE__INIT, "%d commands loaded", retval);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "%d commands loaded", retval);
|
||||
|
||||
//rules:
|
||||
{
|
||||
char tmp[64];
|
||||
if (database.GetVariable("RuleSet", tmp, sizeof(tmp)-1)) {
|
||||
_log(ZONE__INIT, "Loading rule set '%s'", tmp);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading rule set '%s'", tmp);
|
||||
if(!RuleManager::Instance()->LoadRules(&database, tmp)) {
|
||||
_log(ZONE__INIT_ERR, "Failed to load ruleset '%s', falling back to defaults.", tmp);
|
||||
Log.Out(Logs::General, Logs::Error, "Failed to load ruleset '%s', falling back to defaults.", tmp);
|
||||
}
|
||||
} else {
|
||||
if(!RuleManager::Instance()->LoadRules(&database, "default")) {
|
||||
_log(ZONE__INIT, "No rule set configured, using default rules");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "No rule set configured, using default rules");
|
||||
} else {
|
||||
_log(ZONE__INIT, "Loaded default rule set 'default'", tmp);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loaded default rule set 'default'", tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(RuleB(TaskSystem, EnableTaskSystem)) {
|
||||
_log(ZONE__INIT, "Loading Tasks");
|
||||
Log.Out(Logs::General, Logs::Tasks, "[INIT] Loading Tasks");
|
||||
taskmanager = new TaskManager;
|
||||
taskmanager->LoadTasks();
|
||||
}
|
||||
@@ -298,17 +304,11 @@ int main(int argc, char** argv) {
|
||||
#endif
|
||||
|
||||
//now we have our parser, load the quests
|
||||
_log(ZONE__INIT, "Loading quests");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading quests");
|
||||
parse->ReloadQuests();
|
||||
|
||||
|
||||
#ifdef CLIENT_LOGS
|
||||
LogFile->SetAllCallbacks(ClientLogs::EQEmuIO_buf);
|
||||
LogFile->SetAllCallbacks(ClientLogs::EQEmuIO_fmt);
|
||||
LogFile->SetAllCallbacks(ClientLogs::EQEmuIO_pva);
|
||||
#endif
|
||||
if (!worldserver.Connect()) {
|
||||
_log(ZONE__INIT_ERR, "worldserver.Connect() FAILED!");
|
||||
Log.Out(Logs::General, Logs::Error, "Worldserver Connection Failed :: worldserver.Connect()");
|
||||
}
|
||||
|
||||
Timer InterserverTimer(INTERSERVER_TIMER); // does MySQL pings and auto-reconnect
|
||||
@@ -320,9 +320,9 @@ int main(int argc, char** argv) {
|
||||
#endif
|
||||
#endif
|
||||
if (!strlen(zone_name) || !strcmp(zone_name,".")) {
|
||||
_log(ZONE__INIT, "Entering sleep mode");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Entering sleep mode");
|
||||
} else if (!Zone::Bootup(database.GetZoneID(zone_name), 0, true)) { //todo: go above and fix this to allow cmd line instance
|
||||
_log(ZONE__INIT_ERR, "Zone bootup FAILED!");
|
||||
Log.Out(Logs::General, Logs::Error, "Zone Bootup failed :: Zone::Bootup");
|
||||
zone = 0;
|
||||
}
|
||||
|
||||
@@ -331,13 +331,13 @@ int main(int argc, char** argv) {
|
||||
RegisterAllPatches(stream_identifier);
|
||||
|
||||
#ifndef WIN32
|
||||
_log(COMMON__THREADS, "Main thread running with thread id %d", pthread_self());
|
||||
Log.Out(Logs::Detail, Logs::None, "Main thread running with thread id %d", pthread_self());
|
||||
#endif
|
||||
|
||||
Timer quest_timers(100);
|
||||
UpdateWindowTitle();
|
||||
bool worldwasconnected = worldserver.Connected();
|
||||
EQStream* eqss;
|
||||
std::shared_ptr<EQStream> eqss;
|
||||
EQStreamInterface *eqsi;
|
||||
uint8 IDLEZONEUPDATE = 200;
|
||||
uint8 ZONEUPDATE = 10;
|
||||
@@ -349,13 +349,12 @@ int main(int argc, char** argv) {
|
||||
//Advance the timer to our current point in time
|
||||
Timer::SetCurrentTime();
|
||||
|
||||
//process stuff from world
|
||||
worldserver.Process();
|
||||
|
||||
if (!eqsf.IsOpen() && Config->ZonePort!=0) {
|
||||
_log(ZONE__INIT, "Starting EQ Network server on port %d",Config->ZonePort);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d",Config->ZonePort);
|
||||
if (!eqsf.Open(Config->ZonePort)) {
|
||||
_log(ZONE__INIT_ERR, "Failed to open port %d",Config->ZonePort);
|
||||
Log.Out(Logs::General, Logs::Error, "Failed to open port %d",Config->ZonePort);
|
||||
ZoneConfig::SetZonePort(0);
|
||||
worldserver.Disconnect();
|
||||
worldwasconnected = false;
|
||||
@@ -369,7 +368,7 @@ int main(int argc, char** argv) {
|
||||
//structures and opcodes for that patch.
|
||||
struct in_addr in;
|
||||
in.s_addr = eqss->GetRemoteIP();
|
||||
_log(WORLD__CLIENT, "New connection from %s:%d", inet_ntoa(in),ntohs(eqss->GetRemotePort()));
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "New connection from %s:%d", inet_ntoa(in),ntohs(eqss->GetRemotePort()));
|
||||
stream_identifier.AddStream(eqss); //takes the stream
|
||||
}
|
||||
|
||||
@@ -381,7 +380,7 @@ int main(int argc, char** argv) {
|
||||
//now that we know what patch they are running, start up their client object
|
||||
struct in_addr in;
|
||||
in.s_addr = eqsi->GetRemoteIP();
|
||||
_log(WORLD__CLIENT, "New client from %s:%d", inet_ntoa(in), ntohs(eqsi->GetRemotePort()));
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "New client from %s:%d", inet_ntoa(in), ntohs(eqsi->GetRemotePort()));
|
||||
Client* client = new Client(eqsi);
|
||||
entity_list.AddClient(client);
|
||||
}
|
||||
@@ -426,10 +425,8 @@ int main(int argc, char** argv) {
|
||||
if(net.raid_timer.Enabled() && net.raid_timer.Check())
|
||||
entity_list.RaidProcess();
|
||||
|
||||
entity_list.Process();
|
||||
|
||||
entity_list.MobProcess();
|
||||
|
||||
entity_list.Process();
|
||||
entity_list.MobProcess();
|
||||
entity_list.BeaconProcess();
|
||||
|
||||
if (zone) {
|
||||
@@ -455,25 +452,6 @@ int main(int argc, char** argv) {
|
||||
worldserver.AsyncConnect();
|
||||
}
|
||||
|
||||
#if defined(_EQDEBUG) && defined(DEBUG_PC)
|
||||
QueryPerformanceCounter(&tmp3);
|
||||
mainloop_time += tmp3.QuadPart - tmp2.QuadPart;
|
||||
if (!--tmp0) {
|
||||
tmp0 = 200;
|
||||
printf("Elapsed Tics : %9.0f (%1.4f sec)\n", (double)mainloop_time, ((double)mainloop_time/tmp.QuadPart));
|
||||
printf("NPCAI Tics : %9.0f (%1.2f%%)\n", (double)npcai_time, ((double)npcai_time/mainloop_time)*100);
|
||||
printf("FindSpell Tics: %9.0f (%1.2f%%)\n", (double)findspell_time, ((double)findspell_time/mainloop_time)*100);
|
||||
printf("AtkAllowd Tics: %9.0f (%1.2f%%)\n", (double)IsAttackAllowed_time, ((double)IsAttackAllowed_time/mainloop_time)*100);
|
||||
printf("ClientPro Tics: %9.0f (%1.2f%%)\n", (double)clientprocess_time, ((double)clientprocess_time/mainloop_time)*100);
|
||||
printf("ClientAtk Tics: %9.0f (%1.2f%%)\n", (double)clientattack_time, ((double)clientattack_time/mainloop_time)*100);
|
||||
mainloop_time = 0;
|
||||
npcai_time = 0;
|
||||
findspell_time = 0;
|
||||
IsAttackAllowed_time = 0;
|
||||
clientprocess_time = 0;
|
||||
clientattack_time = 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef EQPROFILE
|
||||
#ifdef PROFILE_DUMP_TIME
|
||||
if(profile_dump_timer.Check()) {
|
||||
@@ -481,7 +459,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
} //end extra profiler block
|
||||
} //end extra profiler block
|
||||
Sleep(ZoneTimerResolution);
|
||||
}
|
||||
|
||||
@@ -508,14 +486,14 @@ int main(int argc, char** argv) {
|
||||
safe_delete(taskmanager);
|
||||
command_deinit();
|
||||
safe_delete(parse);
|
||||
CheckEQEMuErrorAndPause();
|
||||
_log(ZONE__INIT, "Proper zone shutdown complete.");
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Proper zone shutdown complete.");
|
||||
Log.CloseFileLogs();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CatchSignal(int sig_num) {
|
||||
#ifdef _WINDOWS
|
||||
_log(ZONE__INIT, "Recieved signal: %i", sig_num);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Recieved signal: %i", sig_num);
|
||||
#endif
|
||||
RunLoops = false;
|
||||
}
|
||||
@@ -524,9 +502,9 @@ void Shutdown()
|
||||
{
|
||||
Zone::Shutdown(true);
|
||||
RunLoops = false;
|
||||
worldserver.Disconnect();
|
||||
// safe_delete(worldserver);
|
||||
_log(ZONE__INIT, "Shutting down...");
|
||||
worldserver.Disconnect();
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Shutting down...");
|
||||
Log.CloseFileLogs();
|
||||
}
|
||||
|
||||
uint32 NetConnection::GetIP()
|
||||
@@ -615,7 +593,7 @@ void LoadSpells(EQEmu::MemoryMappedFile **mmf) {
|
||||
spells = reinterpret_cast<SPDat_Spell_Struct*>((*mmf)->Get());
|
||||
mutex.Unlock();
|
||||
} catch(std::exception &ex) {
|
||||
LogFile->write(EQEMuLog::Error, "Error loading spells: %s", ex.what());
|
||||
Log.Out(Logs::General, Logs::Error, "Error loading spells: %s", ex.what());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+216
-249
@@ -18,17 +18,17 @@
|
||||
|
||||
#include "../common/bodytypes.h"
|
||||
#include "../common/classes.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/seperator.h"
|
||||
#include "../common/spdat.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/clientversions.h"
|
||||
#include "../common/features.h"
|
||||
#include "../common/item.h"
|
||||
#include "../common/item_struct.h"
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/features.h"
|
||||
#include "../common/item.h"
|
||||
#include "../common/item_struct.h"
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/servertalk.h"
|
||||
|
||||
#include "aa.h"
|
||||
@@ -56,7 +56,7 @@ extern Zone* zone;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern EntityList entity_list;
|
||||
|
||||
NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float heading, int iflymode, bool IsCorpse)
|
||||
NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int iflymode, bool IsCorpse)
|
||||
: Mob(d->name,
|
||||
d->lastname,
|
||||
d->max_hp,
|
||||
@@ -70,11 +70,8 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
|
||||
d->npc_id,
|
||||
d->size,
|
||||
d->runspeed,
|
||||
heading,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
d->light,
|
||||
position,
|
||||
d->light, // innate_light
|
||||
d->texture,
|
||||
d->helmtexture,
|
||||
d->AC,
|
||||
@@ -115,7 +112,10 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
|
||||
qglobal_purge_timer(30000),
|
||||
sendhpupdate_timer(1000),
|
||||
enraged_timer(1000),
|
||||
taunt_timer(TauntReuseTime * 1000)
|
||||
taunt_timer(TauntReuseTime * 1000),
|
||||
m_SpawnPoint(position),
|
||||
m_GuardPoint(-1,-1,-1,0),
|
||||
m_GuardPointSaved(0,0,0,0)
|
||||
{
|
||||
//What is the point of this, since the names get mangled..
|
||||
Mob* mob = entity_list.GetMob(name);
|
||||
@@ -205,14 +205,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
|
||||
MerchantType = d->merchanttype;
|
||||
merchant_open = GetClass() == MERCHANT;
|
||||
adventure_template_id = d->adventure_template;
|
||||
org_x = x;
|
||||
org_y = y;
|
||||
org_z = z;
|
||||
flymode = iflymode;
|
||||
guard_x = -1; //just some value we might be able to recongize as "unset"
|
||||
guard_y = -1;
|
||||
guard_z = -1;
|
||||
guard_heading = 0;
|
||||
guard_anim = eaStanding;
|
||||
roambox_distance = 0;
|
||||
roambox_max_x = -2;
|
||||
@@ -223,7 +216,6 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
|
||||
roambox_movingto_y = -2;
|
||||
roambox_min_delay = 1000;
|
||||
roambox_delay = 1000;
|
||||
org_heading = heading;
|
||||
p_depop = false;
|
||||
loottable_id = d->loottable_id;
|
||||
|
||||
@@ -258,8 +250,8 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
|
||||
|
||||
npc_aggro = d->npc_aggro;
|
||||
|
||||
if(!IsMerc())
|
||||
AI_Start();
|
||||
AI_Init();
|
||||
AI_Start();
|
||||
|
||||
d_melee_texture1 = d->d_melee_texture1;
|
||||
d_melee_texture2 = d->d_melee_texture2;
|
||||
@@ -356,14 +348,13 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
|
||||
reface_timer = new Timer(15000);
|
||||
reface_timer->Disable();
|
||||
qGlobals = nullptr;
|
||||
guard_x_saved = 0;
|
||||
guard_y_saved = 0;
|
||||
guard_z_saved = 0;
|
||||
guard_heading_saved = 0;
|
||||
SetEmoteID(d->emoteid);
|
||||
InitializeBuffSlots();
|
||||
CalcBonuses();
|
||||
raid_target = d->raid_target;
|
||||
|
||||
active_light = d->light;
|
||||
spell_light = equip_light = NOT_USED;
|
||||
}
|
||||
|
||||
NPC::~NPC()
|
||||
@@ -448,14 +439,19 @@ void NPC::RemoveItem(uint32 item_id, uint16 quantity, uint16 slot) {
|
||||
ServerLootItem_Struct* item = *cur;
|
||||
if (item->item_id == item_id && slot <= 0 && quantity <= 0) {
|
||||
itemlist.erase(cur);
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue()) { SendAppearancePacket(AT_Light, GetActiveLightValue()); }
|
||||
return;
|
||||
}
|
||||
else if (item->item_id == item_id && item->equip_slot == slot && quantity >= 1) {
|
||||
//std::cout<<"NPC::RemoveItem"<<" equipSlot:"<<iterator.GetData()->equipSlot<<" quantity:"<< quantity<<std::endl; // iterator undefined [CODEBUG]
|
||||
if (item->charges <= quantity)
|
||||
if (item->charges <= quantity) {
|
||||
itemlist.erase(cur);
|
||||
else
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue()) { SendAppearancePacket(AT_Light, GetActiveLightValue()); }
|
||||
}
|
||||
else {
|
||||
item->charges -= quantity;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -487,6 +483,9 @@ void NPC::CheckMinMaxLevel(Mob *them)
|
||||
++cur;
|
||||
}
|
||||
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
}
|
||||
|
||||
void NPC::ClearItemList() {
|
||||
@@ -498,6 +497,10 @@ void NPC::ClearItemList() {
|
||||
safe_delete(item);
|
||||
}
|
||||
itemlist.clear();
|
||||
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
}
|
||||
|
||||
void NPC::QueryLoot(Client* to)
|
||||
@@ -508,14 +511,13 @@ void NPC::QueryLoot(Client* to)
|
||||
for(ItemList::iterator cur = itemlist.begin(); cur != itemlist.end(); ++cur, ++x) {
|
||||
const Item_Struct* item = database.GetItem((*cur)->item_id);
|
||||
if (item == nullptr) {
|
||||
LogFile->write(EQEMuLog::Error, "Database error, invalid item");
|
||||
Log.Out(Logs::General, Logs::Error, "Database error, invalid item");
|
||||
continue;
|
||||
}
|
||||
|
||||
Client::TextLink linker;
|
||||
linker.SetLinkType(linker.linkItemData);
|
||||
linker.SetItemData(item);
|
||||
linker.SetClientVersion(to->GetClientVersion());
|
||||
|
||||
auto item_link = linker.GenerateLink();
|
||||
|
||||
@@ -675,8 +677,8 @@ bool NPC::Process()
|
||||
DoGravityEffect();
|
||||
}
|
||||
|
||||
if(reface_timer->Check() && !IsEngaged() && (guard_x == GetX() && guard_y == GetY() && guard_z == GetZ())) {
|
||||
SetHeading(guard_heading);
|
||||
if(reface_timer->Check() && !IsEngaged() && (m_GuardPoint.x == GetX() && m_GuardPoint.y == GetY() && m_GuardPoint.z == GetZ())) {
|
||||
SetHeading(m_GuardPoint.w);
|
||||
SendPosition();
|
||||
reface_timer->Disable();
|
||||
}
|
||||
@@ -716,6 +718,27 @@ uint32 NPC::CountLoot() {
|
||||
return(itemlist.size());
|
||||
}
|
||||
|
||||
void NPC::UpdateEquipLightValue()
|
||||
{
|
||||
equip_light = NOT_USED;
|
||||
|
||||
for (int index = MAIN_BEGIN; index < EmuConstants::EQUIPMENT_SIZE; ++index) {
|
||||
if (equipment[index] == NOT_USED) { continue; }
|
||||
auto item = database.GetItem(equipment[index]);
|
||||
if (item == nullptr) { continue; }
|
||||
if (item->Light & 0xF0) { continue; }
|
||||
if (item->Light > equip_light) { equip_light = item->Light; }
|
||||
}
|
||||
|
||||
for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
|
||||
auto item = database.GetItem((*iter)->item_id);
|
||||
if (item == nullptr) { continue; }
|
||||
if (item->ItemType != ItemTypeMisc && item->ItemType != ItemTypeLight) { continue; }
|
||||
if (item->Light & 0xF0) { continue; }
|
||||
if (item->Light > equip_light) { equip_light = item->Light; }
|
||||
}
|
||||
}
|
||||
|
||||
void NPC::Depop(bool StartSpawnTimer) {
|
||||
uint16 emoteid = this->GetEmoteID();
|
||||
if(emoteid != 0)
|
||||
@@ -781,7 +804,7 @@ bool NPC::DatabaseCastAccepted(int spell_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NPC* NPC::SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z, float in_heading, Client* client) {
|
||||
NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client) {
|
||||
if(spawncommand == 0 || spawncommand[0] == 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -920,7 +943,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z,
|
||||
npc_type->npc_id = 0;
|
||||
npc_type->loottable_id = 0;
|
||||
npc_type->texture = atoi(sep.arg[3]);
|
||||
npc_type->light = 0;
|
||||
npc_type->light = 0; // spawncommand needs update
|
||||
npc_type->runspeed = 1.25;
|
||||
npc_type->d_melee_texture1 = atoi(sep.arg[7]);
|
||||
npc_type->d_melee_texture2 = atoi(sep.arg[8]);
|
||||
@@ -940,7 +963,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z,
|
||||
npc_type->prim_melee_type = 28;
|
||||
npc_type->sec_melee_type = 28;
|
||||
|
||||
NPC* npc = new NPC(npc_type, 0, in_x, in_y, in_z, in_heading/8, FlyMode3);
|
||||
NPC* npc = new NPC(npc_type, nullptr, position, FlyMode3);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
|
||||
entity_list.AddNPC(npc);
|
||||
@@ -964,325 +987,267 @@ NPC* NPC::SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z,
|
||||
}
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,Client *client, NPC* spawn, uint32 extra) {
|
||||
uint32 ZoneDatabase::CreateNewNPCCommand(const char *zone, uint32 zone_version, Client *client, NPC *spawn,
|
||||
uint32 extra)
|
||||
{
|
||||
uint32 npc_type_id = 0;
|
||||
|
||||
uint32 npc_type_id = 0;
|
||||
|
||||
if (extra && client && client->GetZoneID())
|
||||
{
|
||||
if (extra && client && client->GetZoneID()) {
|
||||
// Set an npc_type ID within the standard range for the current zone if possible (zone_id * 1000)
|
||||
int starting_npc_id = client->GetZoneID() * 1000;
|
||||
|
||||
std::string query = StringFormat("SELECT MAX(id) FROM npc_types WHERE id >= %i AND id < %i",
|
||||
starting_npc_id, starting_npc_id + 1000);
|
||||
auto results = QueryDatabase(query);
|
||||
starting_npc_id, starting_npc_id + 1000);
|
||||
auto results = QueryDatabase(query);
|
||||
if (results.Success()) {
|
||||
if (results.RowCount() != 0)
|
||||
{
|
||||
auto row = results.begin();
|
||||
npc_type_id = atoi(row[0]) + 1;
|
||||
// Prevent the npc_type id from exceeding the range for this zone
|
||||
if (npc_type_id >= (starting_npc_id + 1000))
|
||||
npc_type_id = 0;
|
||||
}
|
||||
else // No npc_type IDs set in this range yet
|
||||
npc_type_id = starting_npc_id;
|
||||
}
|
||||
}
|
||||
if (results.RowCount() != 0) {
|
||||
auto row = results.begin();
|
||||
npc_type_id = atoi(row[0]) + 1;
|
||||
// Prevent the npc_type id from exceeding the range for this zone
|
||||
if (npc_type_id >= (starting_npc_id + 1000))
|
||||
npc_type_id = 0;
|
||||
} else // No npc_type IDs set in this range yet
|
||||
npc_type_id = starting_npc_id;
|
||||
}
|
||||
}
|
||||
|
||||
char tmpstr[64];
|
||||
EntityList::RemoveNumbers(strn0cpy(tmpstr, spawn->GetName(), sizeof(tmpstr)));
|
||||
std::string query;
|
||||
if (npc_type_id)
|
||||
{
|
||||
query = StringFormat("INSERT INTO npc_types (id, name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(%i, \"%s\" , %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
npc_type_id, tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (npc_type_id) {
|
||||
query = StringFormat("INSERT INTO npc_types (id, name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(%i, \"%s\" , %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
npc_type_id, tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
npc_type_id = results.LastInsertedID();
|
||||
} else {
|
||||
query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(),
|
||||
spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(),
|
||||
spawn->GetLoottableID(), spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
npc_type_id = results.LastInsertedID();
|
||||
}
|
||||
else
|
||||
{
|
||||
query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
npc_type_id = results.LastInsertedID();
|
||||
}
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("INSERT INTO spawngroup (id, name) VALUES(%i, '%s-%s')", 0, zone, spawn->GetName());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
uint32 spawngroupid = results.LastInsertedID();
|
||||
uint32 spawngroupid = results.LastInsertedID();
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), 1200,
|
||||
spawn->GetHeading(), spawngroupid);
|
||||
results = QueryDatabase(query);
|
||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), 1200, spawn->GetHeading(),
|
||||
spawngroupid);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)",
|
||||
spawngroupid, npc_type_id, 100);
|
||||
results = QueryDatabase(query);
|
||||
query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)", spawngroupid,
|
||||
npc_type_id, 100);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 respawnTime) {
|
||||
uint32 last_insert_id = 0;
|
||||
uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char *zone, uint32 zone_version, Client *client, NPC *spawn,
|
||||
uint32 respawnTime)
|
||||
{
|
||||
uint32 last_insert_id = 0;
|
||||
|
||||
std::string query = StringFormat("INSERT INTO spawngroup (name) VALUES('%s%s%i')",
|
||||
zone, spawn->GetName(), Timer::GetCurrentTime());
|
||||
auto results = QueryDatabase(query);
|
||||
std::string query = StringFormat("INSERT INTO spawngroup (name) VALUES('%s%s%i')", zone, spawn->GetName(),
|
||||
Timer::GetCurrentTime());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
last_insert_id = results.LastInsertedID();
|
||||
last_insert_id = results.LastInsertedID();
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
uint32 respawntime = 0;
|
||||
uint32 spawnid = 0;
|
||||
if (respawnTime)
|
||||
respawntime = respawnTime;
|
||||
else if (spawn->respawn2 && spawn->respawn2->RespawnTimer() != 0)
|
||||
respawntime = spawn->respawn2->RespawnTimer();
|
||||
else
|
||||
respawntime = 1200;
|
||||
|
||||
uint32 respawntime = 0;
|
||||
uint32 spawnid = 0;
|
||||
if (respawnTime)
|
||||
respawntime = respawnTime;
|
||||
else if(spawn->respawn2 && spawn->respawn2->RespawnTimer() != 0)
|
||||
respawntime = spawn->respawn2->RespawnTimer();
|
||||
else
|
||||
respawntime = 1200;
|
||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), respawntime,
|
||||
spawn->GetHeading(), last_insert_id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return 0;
|
||||
}
|
||||
spawnid = results.LastInsertedID();
|
||||
|
||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), respawntime,
|
||||
spawn->GetHeading(), last_insert_id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
spawnid = results.LastInsertedID();
|
||||
query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)", last_insert_id,
|
||||
spawn->GetNPCTypeID(), 100);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)",
|
||||
last_insert_id, spawn->GetNPCTypeID(), 100);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
return spawnid;
|
||||
return spawnid;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::UpdateNPCTypeAppearance(Client *client, NPC* spawn) {
|
||||
|
||||
std::string query = StringFormat("UPDATE npc_types SET name = \"%s\", level = %i, race = %i, class = %i, "
|
||||
"hp = %i, gender = %i, texture = %i, helmtexture = %i, size = %i, "
|
||||
"loottable_id = %i, merchant_id = %i, face = %i, WHERE id = %i",
|
||||
spawn->GetName(), spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, spawn->GetNPCTypeID());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success() && client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
return results.Success() == true? 1: 0;
|
||||
uint32 ZoneDatabase::UpdateNPCTypeAppearance(Client *client, NPC *spawn)
|
||||
{
|
||||
std::string query =
|
||||
StringFormat("UPDATE npc_types SET name = \"%s\", level = %i, race = %i, class = %i, "
|
||||
"hp = %i, gender = %i, texture = %i, helmtexture = %i, size = %i, "
|
||||
"loottable_id = %i, merchant_id = %i, face = %i, WHERE id = %i",
|
||||
spawn->GetName(), spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(),
|
||||
spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(),
|
||||
spawn->GetLoottableID(), spawn->MerchantType, spawn->GetNPCTypeID());
|
||||
auto results = QueryDatabase(query);
|
||||
return results.Success() == true ? 1 : 0;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::DeleteSpawnLeaveInNPCTypeTable(const char* zone, Client *client, NPC* spawn) {
|
||||
uint32 ZoneDatabase::DeleteSpawnLeaveInNPCTypeTable(const char *zone, Client *client, NPC *spawn)
|
||||
{
|
||||
uint32 id = 0;
|
||||
uint32 spawngroupID = 0;
|
||||
|
||||
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE "
|
||||
"zone='%s' AND spawngroupID=%i", zone, spawn->GetSp2());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
"zone='%s' AND spawngroupID=%i",
|
||||
zone, spawn->GetSp2());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
if (row[0])
|
||||
id = atoi(row[0]);
|
||||
id = atoi(row[0]);
|
||||
|
||||
if (row[1])
|
||||
spawngroupID = atoi(row[1]);
|
||||
spawngroupID = atoi(row[1]);
|
||||
|
||||
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
||||
results = QueryDatabase(query);
|
||||
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::DeleteSpawnRemoveFromNPCTypeTable(const char* zone, uint32 zone_version, Client *client, NPC* spawn) {
|
||||
|
||||
uint32 ZoneDatabase::DeleteSpawnRemoveFromNPCTypeTable(const char *zone, uint32 zone_version, Client *client,
|
||||
NPC *spawn)
|
||||
{
|
||||
uint32 id = 0;
|
||||
uint32 spawngroupID = 0;
|
||||
|
||||
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE zone = '%s' "
|
||||
"AND version = %u AND spawngroupID = %i",
|
||||
zone, zone_version, spawn->GetSp2());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
"AND version = %u AND spawngroupID = %i",
|
||||
zone, zone_version, spawn->GetSp2());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
if (row[0])
|
||||
id = atoi(row[0]);
|
||||
id = atoi(row[0]);
|
||||
|
||||
if (row[1])
|
||||
spawngroupID = atoi(row[1]);
|
||||
spawngroupID = atoi(row[1]);
|
||||
|
||||
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID);
|
||||
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID);
|
||||
query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("DELETE FROM npc_types WHERE id = '%i'", spawn->GetNPCTypeID());
|
||||
query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
query = StringFormat("DELETE FROM npc_types WHERE id = '%i'", spawn->GetNPCTypeID());
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::AddSpawnFromSpawnGroup(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID) {
|
||||
|
||||
uint32 ZoneDatabase::AddSpawnFromSpawnGroup(const char *zone, uint32 zone_version, Client *client, NPC *spawn,
|
||||
uint32 spawnGroupID)
|
||||
{
|
||||
uint32 last_insert_id = 0;
|
||||
std::string query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, client->GetX(), client->GetY(), client->GetZ(),
|
||||
120, client->GetHeading(), spawnGroupID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
std::string query =
|
||||
StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, client->GetX(), client->GetY(), client->GetZ(), 120, client->GetHeading(),
|
||||
spawnGroupID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::AddNPCTypes(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID) {
|
||||
|
||||
uint32 npc_type_id;
|
||||
uint32 ZoneDatabase::AddNPCTypes(const char *zone, uint32 zone_version, Client *client, NPC *spawn, uint32 spawnGroupID)
|
||||
{
|
||||
uint32 npc_type_id;
|
||||
char numberlessName[64];
|
||||
|
||||
EntityList::RemoveNumbers(strn0cpy(numberlessName, spawn->GetName(), sizeof(numberlessName)));
|
||||
std::string query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
numberlessName, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
std::string query =
|
||||
StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
numberlessName, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(),
|
||||
spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(),
|
||||
spawn->GetLoottableID(), spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
npc_type_id = results.LastInsertedID();
|
||||
npc_type_id = results.LastInsertedID();
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
if(client)
|
||||
client->Message(0, "%s npc_type ID %i created successfully!", numberlessName, npc_type_id);
|
||||
if (client)
|
||||
client->Message(0, "%s npc_type ID %i created successfully!", numberlessName, npc_type_id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1673,7 +1638,7 @@ void Mob::NPCSpecialAttacks(const char* parse, int permtag, bool reset, bool rem
|
||||
{
|
||||
if(database.SetSpecialAttkFlag(this->GetNPCTypeID(), orig_parse))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Normal, "NPCTypeID: %i flagged to '%s' for Special Attacks.\n",this->GetNPCTypeID(),orig_parse);
|
||||
Log.Out(Logs::General, Logs::Normal, "NPCTypeID: %i flagged to '%s' for Special Attacks.\n",this->GetNPCTypeID(),orig_parse);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1845,6 +1810,8 @@ void NPC::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
Mob::FillSpawnStruct(ns, ForWho);
|
||||
PetOnSpawn(ns);
|
||||
ns->spawn.is_npc = 1;
|
||||
UpdateActiveLightValue();
|
||||
ns->spawn.light = GetActiveLightValue();
|
||||
}
|
||||
|
||||
void NPC::PetOnSpawn(NewSpawn_Struct* ns)
|
||||
@@ -2434,7 +2401,7 @@ void NPC::DepopSwarmPets()
|
||||
Mob* owner = entity_list.GetMobID(GetSwarmInfo()->owner_id);
|
||||
if (owner)
|
||||
owner->SetTempPetCount(owner->GetTempPetCount() - 1);
|
||||
|
||||
|
||||
Depop();
|
||||
return;
|
||||
}
|
||||
|
||||
+23
-28
@@ -64,10 +64,10 @@ struct AISpells_Struct {
|
||||
};
|
||||
|
||||
struct AISpellsEffects_Struct {
|
||||
uint16 spelleffectid;
|
||||
int32 base;
|
||||
int32 limit;
|
||||
int32 max;
|
||||
uint16 spelleffectid;
|
||||
int32 base;
|
||||
int32 limit;
|
||||
int32 max;
|
||||
};
|
||||
|
||||
struct AISpellsVar_Struct {
|
||||
@@ -83,7 +83,7 @@ struct AISpellsVar_Struct {
|
||||
uint32 idle_no_sp_recast_min;
|
||||
uint32 idle_no_sp_recast_max;
|
||||
uint8 idle_beneficial_chance;
|
||||
};
|
||||
};
|
||||
|
||||
class AA_SwarmPetInfo;
|
||||
class Client;
|
||||
@@ -95,10 +95,10 @@ struct Item_Struct;
|
||||
class NPC : public Mob
|
||||
{
|
||||
public:
|
||||
static NPC* SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z, float in_heading = 0, Client* client = 0);
|
||||
static NPC* SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client = nullptr);
|
||||
static int8 GetAILevel(bool iForceReRead = false);
|
||||
|
||||
NPC(const NPCType* data, Spawn2* respawn, float x, float y, float z, float heading, int iflymode, bool IsCorpse = false);
|
||||
NPC(const NPCType* data, Spawn2* respawn, const glm::vec4& position, int iflymode, bool IsCorpse = false);
|
||||
|
||||
virtual ~NPC();
|
||||
|
||||
@@ -162,7 +162,7 @@ public:
|
||||
FACTION_VALUE CheckNPCFactionAlly(int32 other_faction);
|
||||
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther);
|
||||
|
||||
void GoToBind(uint8 bindnum = 0) { GMMove(org_x, org_y, org_z, org_heading); }
|
||||
void GoToBind(uint8 bindnum = 0) { GMMove(m_SpawnPoint.x, m_SpawnPoint.y, m_SpawnPoint.z, m_SpawnPoint.w); }
|
||||
void Gate();
|
||||
|
||||
void GetPetState(SpellBuff_Struct *buffs, uint32 *items, char *name);
|
||||
@@ -187,6 +187,7 @@ public:
|
||||
void QueryLoot(Client* to);
|
||||
uint32 CountLoot();
|
||||
inline uint32 GetLoottableID() const { return loottable_id; }
|
||||
virtual void UpdateEquipLightValue();
|
||||
|
||||
inline uint32 GetCopper() const { return copper; }
|
||||
inline uint32 GetSilver() const { return silver; }
|
||||
@@ -210,14 +211,8 @@ public:
|
||||
uint32 GetSp2() const { return spawn_group; }
|
||||
uint32 GetSpawnPointID() const;
|
||||
|
||||
float GetSpawnPointX() const { return org_x; }
|
||||
float GetSpawnPointY() const { return org_y; }
|
||||
float GetSpawnPointZ() const { return org_z; }
|
||||
float GetSpawnPointH() const { return org_heading; }
|
||||
float GetGuardPointX() const { return guard_x; }
|
||||
float GetGuardPointY() const { return guard_y; }
|
||||
float GetGuardPointZ() const { return guard_z; }
|
||||
float GetGuardPointH() const { return guard_heading; }
|
||||
glm::vec4 const GetSpawnPoint() const { return m_SpawnPoint; }
|
||||
glm::vec4 const GetGuardPoint() const { return m_GuardPoint; }
|
||||
EmuAppearance GetGuardPointAnim() const { return guard_anim; }
|
||||
void SaveGuardPointAnim(EmuAppearance anim) { guard_anim = anim; }
|
||||
|
||||
@@ -254,7 +249,7 @@ public:
|
||||
|
||||
void SetNPCFactionID(int32 in) { npc_faction_id = in; database.GetFactionIdsForNPC(npc_faction_id, &faction_list, &primary_faction); }
|
||||
|
||||
float org_x, org_y, org_z, org_heading;
|
||||
glm::vec4 m_SpawnPoint;
|
||||
|
||||
uint32 GetMaxDMG() const {return max_dmg;}
|
||||
uint32 GetMinDMG() const {return min_dmg;}
|
||||
@@ -266,6 +261,7 @@ public:
|
||||
void SetPetSpellID(uint16 amt) {pet_spell_id = amt;}
|
||||
uint32 GetMaxDamage(uint8 tlevel);
|
||||
void SetTaunting(bool tog) {taunting = tog;}
|
||||
bool IsTaunting() const { return taunting; }
|
||||
void PickPocket(Client* thief);
|
||||
void StartSwarmTimer(uint32 duration) { swarm_timer.Start(duration); }
|
||||
void AddLootDrop(const Item_Struct*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false);
|
||||
@@ -287,15 +283,15 @@ public:
|
||||
void StopWandering();
|
||||
void ResumeWandering();
|
||||
void PauseWandering(int pausetime);
|
||||
void MoveTo(float mtx, float mty, float mtz, float mth, bool saveguardspot);
|
||||
void GetClosestWaypoint(std::list<wplist> &wp_list, int count, float m_x, float m_y, float m_z);
|
||||
void MoveTo(const glm::vec4& position, bool saveguardspot);
|
||||
void GetClosestWaypoint(std::list<wplist> &wp_list, int count, const glm::vec3& location);
|
||||
|
||||
uint32 GetEquipment(uint8 material_slot) const; // returns item id
|
||||
int32 GetEquipmentMaterial(uint8 material_slot) const;
|
||||
|
||||
void NextGuardPosition();
|
||||
void SaveGuardSpot(bool iClearGuardSpot = false);
|
||||
inline bool IsGuarding() const { return(guard_heading != 0); }
|
||||
inline bool IsGuarding() const { return(m_GuardPoint.w != 0); }
|
||||
void SaveGuardSpotCharm();
|
||||
void RestoreGuardSpotCharm();
|
||||
void AI_SetRoambox(float iDist, float iRoamDist, uint32 iDelay = 2500, uint32 iMinDelay = 2500);
|
||||
@@ -386,7 +382,7 @@ public:
|
||||
|
||||
inline void SetHealScale(float amt) { healscale = amt; }
|
||||
inline float GetHealScale() { return healscale; }
|
||||
|
||||
|
||||
inline void SetSpellFocusDMG(int32 NewSpellFocusDMG) {SpellFocusDMG = NewSpellFocusDMG;}
|
||||
inline int32 GetSpellFocusDMG() const { return SpellFocusDMG;}
|
||||
|
||||
@@ -407,7 +403,7 @@ public:
|
||||
void SetHeroForgeModel(uint32 model) { herosforgemodel = model; }
|
||||
|
||||
bool IsRaidTarget() const { return raid_target; };
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
const NPCType* NPCTypedata;
|
||||
@@ -440,7 +436,7 @@ protected:
|
||||
|
||||
uint32 npc_spells_id;
|
||||
uint8 casting_spell_AIindex;
|
||||
Timer* AIautocastspell_timer;
|
||||
std::unique_ptr<Timer> AIautocastspell_timer;
|
||||
uint32* pDontCastBefore_casting_spell;
|
||||
std::vector<AISpells_Struct> AIspells;
|
||||
bool HasAISpell;
|
||||
@@ -448,8 +444,7 @@ protected:
|
||||
virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0);
|
||||
AISpellsVar_Struct AISpellVar;
|
||||
int16 GetFocusEffect(focusType type, uint16 spell_id);
|
||||
|
||||
|
||||
|
||||
uint32 npc_spells_effects_id;
|
||||
std::vector<AISpellsEffects_Struct> AIspellsEffects;
|
||||
bool HasAISpellEffects;
|
||||
@@ -479,8 +474,8 @@ protected:
|
||||
void _ClearWaypints();
|
||||
int max_wp;
|
||||
int save_wp;
|
||||
float guard_x, guard_y, guard_z, guard_heading;
|
||||
float guard_x_saved, guard_y_saved, guard_z_saved, guard_heading_saved;
|
||||
glm::vec4 m_GuardPoint;
|
||||
glm::vec4 m_GuardPointSaved;
|
||||
EmuAppearance guard_anim;
|
||||
float roambox_max_x;
|
||||
float roambox_max_y;
|
||||
@@ -518,7 +513,7 @@ protected:
|
||||
//mercenary stuff
|
||||
std::list<MercType> mercTypeList;
|
||||
std::list<MercData> mercDataList;
|
||||
|
||||
|
||||
bool raid_target;
|
||||
uint8 probability;
|
||||
|
||||
|
||||
+14
-11
@@ -16,7 +16,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/string_util.h"
|
||||
|
||||
#include "client.h"
|
||||
@@ -86,7 +86,6 @@ Object::Object(const ItemInst* inst, char* name,float max_x,float min_x,float ma
|
||||
// Set as much struct data as we can
|
||||
memset(&m_data, 0, sizeof(Object_Struct));
|
||||
m_data.heading = heading;
|
||||
//printf("Spawning object %s at %f,%f,%f\n",name,m_data.x,m_data.y,m_data.z);
|
||||
m_data.z = z;
|
||||
m_data.zone_id = zone->GetZoneID();
|
||||
respawn_timer.Disable();
|
||||
@@ -118,7 +117,7 @@ Object::Object(Client* client, const ItemInst* inst)
|
||||
m_data.heading = client->GetHeading();
|
||||
m_data.x = client->GetX();
|
||||
m_data.y = client->GetY();
|
||||
if (client->GetClientVersion() >= EQClientRoF2)
|
||||
if (client->GetClientVersion() >= ClientVersion::RoF2)
|
||||
{
|
||||
// RoF2 places items at player's Z, which is 0.625 of their height.
|
||||
m_data.z = client->GetZ() - (client->GetSize() * 0.625f);
|
||||
@@ -336,7 +335,7 @@ const ItemInst* Object::GetItem(uint8 index) {
|
||||
void Object::PutItem(uint8 index, const ItemInst* inst)
|
||||
{
|
||||
if (index > 9) {
|
||||
LogFile->write(EQEMuLog::Error, "Object::PutItem: Invalid index specified (%i)", index);
|
||||
Log.Out(Logs::General, Logs::Error, "Object::PutItem: Invalid index specified (%i)", index);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -468,16 +467,21 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
||||
if (m_inst && sender) {
|
||||
// if there is a lore conflict, delete the offending item from the server inventory
|
||||
// the client updates itself and takes care of sending "duplicate lore item" messages
|
||||
if(sender->CheckLoreConflict(m_inst->GetItem())) {
|
||||
int16 loreslot = sender->GetInv().HasItem(m_inst->GetItem()->ID, 0, invWhereBank);
|
||||
auto item = m_inst->GetItem();
|
||||
if(sender->CheckLoreConflict(item)) {
|
||||
int16 loreslot = sender->GetInv().HasItem(item->ID, 0, invWhereBank);
|
||||
if (loreslot != INVALID_INDEX) // if the duplicate is in the bank, delete it.
|
||||
sender->DeleteItemInInventory(loreslot);
|
||||
else
|
||||
cursordelete = true; // otherwise, we delete the new one
|
||||
}
|
||||
|
||||
if (item->RecastDelay)
|
||||
m_inst->SetRecastTimestamp(
|
||||
database.GetItemRecastTimestamp(sender->CharacterID(), item->RecastType));
|
||||
|
||||
char buf[10];
|
||||
snprintf(buf, 9, "%u", m_inst->GetItem()->ID);
|
||||
snprintf(buf, 9, "%u", item->ID);
|
||||
buf[9] = '\0';
|
||||
std::vector<EQEmu::Any> args;
|
||||
args.push_back(m_inst);
|
||||
@@ -598,7 +602,7 @@ uint32 ZoneDatabase::AddObject(uint32 type, uint32 icon, const Object_Struct& ob
|
||||
safe_delete_array(object_name);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to insert object: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to insert object: %s", results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -635,7 +639,7 @@ void ZoneDatabase::UpdateObject(uint32 id, uint32 type, uint32 icon, const Objec
|
||||
safe_delete_array(object_name);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to update object: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to update object: %s", results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -654,7 +658,6 @@ Ground_Spawns* ZoneDatabase::LoadGroundSpawns(uint32 zone_id, int16 version, Gro
|
||||
"LIMIT 50", zone_id, version);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
std::cerr << "Error in LoadGroundSpawns query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||
return gs;
|
||||
}
|
||||
|
||||
@@ -680,7 +683,7 @@ void ZoneDatabase::DeleteObject(uint32 id)
|
||||
std::string query = StringFormat("DELETE FROM object WHERE id = %i", id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to delete object: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to delete object: %s", results.ErrorMessage().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1589,22 +1589,18 @@ Message(0, "Disc packet id=%d, %x,%x,%x", disc_in->disc_id, disc_in->unknown3[0]
|
||||
#endif
|
||||
// Npc
|
||||
if (caster->IsAttackAllowed(mob) && spells[spell_id].targettype != ST_AEBard) {
|
||||
//printf("NPC Spell casted on %s\n", mob->GetName());
|
||||
caster->SpellOnTarget(spell_id, mob);
|
||||
}
|
||||
else if (mob->IsAIControlled() && spells[spell_id].targettype == ST_AEBard) {
|
||||
//printf("NPC mgb/aebard spell casted on %s\n", mob->GetName());
|
||||
caster->SpellOnTarget(spell_id, mob);
|
||||
}
|
||||
else {
|
||||
//printf("NPC AE, fall thru. spell_id:%i, Target type:%x\n", spell_id, spells[spell_id].targettype);
|
||||
}
|
||||
}
|
||||
#ifdef IPC
|
||||
else if(caster->IsNPC() && caster->CastToNPC()->IsInteractive()) {
|
||||
// Interactive npc
|
||||
if (caster->IsAttackAllowed(mob) && spells[spell_id].targettype != ST_AEBard && spells[spell_id].targettype != ST_GroupTeleport) {
|
||||
//printf("IPC Spell casted on %s\n", mob->GetName());
|
||||
caster->SpellOnTarget(spell_id, mob);
|
||||
}
|
||||
else if (!mob->IsAIControlled() && (spells[spell_id].targettype == ST_AEBard||group) && mob->CastToClient()->GetPVP() == caster->CastToClient()->GetPVP()) {
|
||||
@@ -1612,18 +1608,15 @@ Message(0, "Disc packet id=%d, %x,%x,%x", disc_in->disc_id, disc_in->unknown3[0]
|
||||
iterator.Advance();
|
||||
continue;
|
||||
}
|
||||
//printf("IPC mgb/aebard spell casted on %s\n", mob->GetName());
|
||||
caster->SpellOnTarget(spell_id, mob);
|
||||
}
|
||||
else {
|
||||
//printf("NPC AE, fall thru. spell_id:%i, Target type:%x\n", spell_id, spells[spell_id].targettype);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (caster->IsClient() && !(caster->CastToClient()->IsBecomeNPC())) {
|
||||
// Client
|
||||
if (caster->IsAttackAllowed(mob) && spells[spell_id].targettype != ST_AEBard){
|
||||
//printf("Client Spell casted on %s\n", mob->GetName());
|
||||
caster->SpellOnTarget(spell_id, mob);
|
||||
}
|
||||
else if(spells[spell_id].targettype == ST_GroupTeleport && mob->IsClient() && mob->isgrouped && caster->isgrouped && entity_list.GetGroupByMob(caster))
|
||||
@@ -1805,7 +1798,6 @@ void ZoneDatabase::AddLootDropToNPC(uint32 lootdrop_id, ItemList* itemlist) {
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("Adding item2: %i",item->item_id);
|
||||
//cout << "Adding item to Mob" << endl;
|
||||
ServerLootItem_Struct* item = new ServerLootItem_Struct;
|
||||
item->item_id = dbitem->ItemNumber;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "oriented_bounding_box.h"
|
||||
#include <gtc/matrix_transform.hpp>
|
||||
#include <gtx/transform.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
glm::mat4 CreateRotateMatrix(float rx, float ry, float rz) {
|
||||
glm::mat4 rot_x(1.0f);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#ifndef EQEMU_ORIENTED_BOUNDNG_BOX_H
|
||||
#define EQEMU_ORIENTED_BOUNDNG_BOX_H
|
||||
|
||||
#include <glm.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
class OrientedBoundingBox
|
||||
{
|
||||
|
||||
+155
-155
@@ -1,4 +1,4 @@
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "doors.h"
|
||||
@@ -17,11 +17,10 @@
|
||||
#endif
|
||||
|
||||
//#define PATHDEBUG
|
||||
#define ABS(x) ((x)<0?-(x):(x))
|
||||
|
||||
extern Zone *zone;
|
||||
|
||||
float VertexDistance(Map::Vertex a, Map::Vertex b)
|
||||
float VectorDistance(glm::vec3 a, glm::vec3 b)
|
||||
{
|
||||
float xdist = a.x - b.x;
|
||||
float ydist = a.y - b.y;
|
||||
@@ -29,7 +28,7 @@ float VertexDistance(Map::Vertex a, Map::Vertex b)
|
||||
return sqrtf(xdist * xdist + ydist * ydist + zdist * zdist);
|
||||
}
|
||||
|
||||
float VertexDistanceNoRoot(Map::Vertex a, Map::Vertex b)
|
||||
float VectorDistanceNoRoot(glm::vec3 a, glm::vec3 b)
|
||||
{
|
||||
float xdist = a.x - b.x;
|
||||
float ydist = a.y - b.y;
|
||||
@@ -61,19 +60,19 @@ PathManager* PathManager::LoadPathFile(const char* ZoneName)
|
||||
|
||||
if(Ret->loadPaths(PathFile))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Status, "Path File %s loaded.", ZonePathFileName);
|
||||
Log.Out(Logs::General, Logs::Status, "Path File %s loaded.", ZonePathFileName);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Path File %s failed to load.", ZonePathFileName);
|
||||
Log.Out(Logs::General, Logs::Error, "Path File %s failed to load.", ZonePathFileName);
|
||||
safe_delete(Ret);
|
||||
}
|
||||
fclose(PathFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Path File %s not found.", ZonePathFileName);
|
||||
Log.Out(Logs::General, Logs::Error, "Path File %s not found.", ZonePathFileName);
|
||||
}
|
||||
|
||||
return Ret;
|
||||
@@ -103,18 +102,18 @@ bool PathManager::loadPaths(FILE *PathFile)
|
||||
|
||||
if(strncmp(Magic, "EQEMUPATH", 9))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Bad Magic String in .path file.");
|
||||
Log.Out(Logs::General, Logs::Error, "Bad Magic String in .path file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
fread(&Head, sizeof(Head), 1, PathFile);
|
||||
|
||||
LogFile->write(EQEMuLog::Status, "Path File Header: Version %ld, PathNodes %ld",
|
||||
Log.Out(Logs::General, Logs::Status, "Path File Header: Version %ld, PathNodes %ld",
|
||||
(long)Head.version, (long)Head.PathNodeCount);
|
||||
|
||||
if(Head.version != 2)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Unsupported path file version.");
|
||||
Log.Out(Logs::General, Logs::Error, "Unsupported path file version.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -138,7 +137,7 @@ bool PathManager::loadPaths(FILE *PathFile)
|
||||
{
|
||||
if(PathNodes[i].Neighbours[j].id > MaxNodeID)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Path Node %i, Neighbour %i (%i) out of range.", i, j, PathNodes[i].Neighbours[j].id);
|
||||
Log.Out(Logs::General, Logs::Error, "Path Node %i, Neighbour %i (%i) out of range.", i, j, PathNodes[i].Neighbours[j].id);
|
||||
|
||||
PathFileValid = false;
|
||||
}
|
||||
@@ -187,9 +186,9 @@ void PathManager::PrintPathing()
|
||||
}
|
||||
}
|
||||
|
||||
Map::Vertex PathManager::GetPathNodeCoordinates(int NodeNumber, bool BestZ)
|
||||
glm::vec3 PathManager::GetPathNodeCoordinates(int NodeNumber, bool BestZ)
|
||||
{
|
||||
Map::Vertex Result;
|
||||
glm::vec3 Result;
|
||||
|
||||
if(NodeNumber < Head.PathNodeCount)
|
||||
{
|
||||
@@ -206,10 +205,10 @@ Map::Vertex PathManager::GetPathNodeCoordinates(int NodeNumber, bool BestZ)
|
||||
}
|
||||
|
||||
std::deque<int> PathManager::FindRoute(int startID, int endID)
|
||||
{
|
||||
_log(PATHING__DEBUG, "FindRoute from node %i to %i", startID, endID);
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::None, "FindRoute from node %i to %i", startID, endID);
|
||||
|
||||
memset(ClosedListFlag, 0, sizeof(int) * Head.PathNodeCount);
|
||||
memset(ClosedListFlag, 0, sizeof(int) * Head.PathNodeCount);
|
||||
|
||||
std::deque<AStarNode> OpenList, ClosedList;
|
||||
|
||||
@@ -283,7 +282,7 @@ std::deque<int> PathManager::FindRoute(int startID, int endID)
|
||||
AStarEntry.Teleport = PathNodes[CurrentNode.PathNodeID].Neighbours[i].Teleport;
|
||||
|
||||
// HCost is the estimated cost to get from this node to the end.
|
||||
AStarEntry.HCost = VertexDistance(PathNodes[PathNodes[CurrentNode.PathNodeID].Neighbours[i].id].v,
|
||||
AStarEntry.HCost = VectorDistance(PathNodes[PathNodes[CurrentNode.PathNodeID].Neighbours[i].id].v,
|
||||
PathNodes[endID].v);
|
||||
|
||||
AStarEntry.GCost = CurrentNode.GCost + PathNodes[CurrentNode.PathNodeID].Neighbours[i].distance;
|
||||
@@ -330,14 +329,14 @@ std::deque<int> PathManager::FindRoute(int startID, int endID)
|
||||
}
|
||||
|
||||
}
|
||||
_log(PATHING__DEBUG, "Unable to find a route.");
|
||||
Log.Out(Logs::Detail, Logs::None, "Unable to find a route.");
|
||||
return Route;
|
||||
|
||||
}
|
||||
|
||||
bool CheckLOSBetweenPoints(Map::Vertex start, Map::Vertex end) {
|
||||
bool CheckLOSBetweenPoints(glm::vec3 start, glm::vec3 end) {
|
||||
|
||||
Map::Vertex hit;
|
||||
glm::vec3 hit;
|
||||
|
||||
if((zone->zonemap) && (zone->zonemap->LineIntersectsZone(start, end, 1, &hit)))
|
||||
return false;
|
||||
@@ -350,9 +349,9 @@ auto path_compare = [](const PathNodeSortStruct& a, const PathNodeSortStruct& b)
|
||||
return a.Distance < b.Distance;
|
||||
};
|
||||
|
||||
std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
||||
std::deque<int> PathManager::FindRoute(glm::vec3 Start, glm::vec3 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);
|
||||
Log.Out(Logs::Detail, Logs::None, "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::deque<int> noderoute;
|
||||
|
||||
@@ -371,12 +370,11 @@ std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
||||
|
||||
for(uint32 i = 0 ; i < Head.PathNodeCount; ++i)
|
||||
{
|
||||
if((ABS(Start.x - PathNodes[i].v.x) <= CandidateNodeRangeXY) &&
|
||||
(ABS(Start.y - PathNodes[i].v.y) <= CandidateNodeRangeXY) &&
|
||||
(ABS(Start.z - PathNodes[i].v.z) <= CandidateNodeRangeZ))
|
||||
{
|
||||
if ((std::abs(Start.x - PathNodes[i].v.x) <= CandidateNodeRangeXY) &&
|
||||
(std::abs(Start.y - PathNodes[i].v.y) <= CandidateNodeRangeXY) &&
|
||||
(std::abs(Start.z - PathNodes[i].v.z) <= CandidateNodeRangeZ)) {
|
||||
TempNode.id = i;
|
||||
TempNode.Distance = VertexDistanceNoRoot(Start, PathNodes[i].v);
|
||||
TempNode.Distance = VectorDistanceNoRoot(Start, PathNodes[i].v);
|
||||
SortedByDistance.push_back(TempNode);
|
||||
|
||||
}
|
||||
@@ -386,7 +384,7 @@ std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
||||
|
||||
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
|
||||
{
|
||||
_log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
|
||||
Log.Out(Logs::Detail, Logs::None, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
|
||||
|
||||
if(!zone->zonemap->LineIntersectsZone(Start, PathNodes[(*Iterator).id].v, 1.0f, nullptr))
|
||||
{
|
||||
@@ -396,11 +394,11 @@ std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
||||
}
|
||||
|
||||
if(ClosestPathNodeToStart <0 ) {
|
||||
_log(PATHING__DEBUG, "No LOS to any starting Path Node within range.");
|
||||
Log.Out(Logs::Detail, Logs::None, "No LOS to any starting Path Node within range.");
|
||||
return noderoute;
|
||||
}
|
||||
|
||||
_log(PATHING__DEBUG, "Closest Path Node To Start: %2d", ClosestPathNodeToStart);
|
||||
Log.Out(Logs::Detail, Logs::None, "Closest Path Node To Start: %2d", ClosestPathNodeToStart);
|
||||
|
||||
// Find the nearest PathNode the end point has LOS to
|
||||
|
||||
@@ -410,12 +408,11 @@ std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
||||
|
||||
for(uint32 i = 0 ; i < Head.PathNodeCount; ++i)
|
||||
{
|
||||
if((ABS(End.x - PathNodes[i].v.x) <= CandidateNodeRangeXY) &&
|
||||
(ABS(End.y - PathNodes[i].v.y) <= CandidateNodeRangeXY) &&
|
||||
(ABS(End.z - PathNodes[i].v.z) <= CandidateNodeRangeZ))
|
||||
{
|
||||
if ((std::abs(End.x - PathNodes[i].v.x) <= CandidateNodeRangeXY) &&
|
||||
(std::abs(End.y - PathNodes[i].v.y) <= CandidateNodeRangeXY) &&
|
||||
(std::abs(End.z - PathNodes[i].v.z) <= CandidateNodeRangeZ)) {
|
||||
TempNode.id = i;
|
||||
TempNode.Distance = VertexDistanceNoRoot(End, PathNodes[i].v);
|
||||
TempNode.Distance = VectorDistanceNoRoot(End, PathNodes[i].v);
|
||||
SortedByDistance.push_back(TempNode);
|
||||
}
|
||||
}
|
||||
@@ -424,8 +421,8 @@ std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
||||
|
||||
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)",
|
||||
Log.Out(Logs::Detail, Logs::None, "Checking Reachability of Node %i from End Position.", PathNodes[(*Iterator).id].id);
|
||||
Log.Out(Logs::Detail, Logs::None, " (%8.3f, %8.3f, %8.3f) to (%8.3f, %8.3f, %8.3f)",
|
||||
End.x, End.y, End.z,
|
||||
PathNodes[(*Iterator).id].v.x, PathNodes[(*Iterator).id].v.y, PathNodes[(*Iterator).id].v.z);
|
||||
|
||||
@@ -437,11 +434,11 @@ std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
||||
}
|
||||
|
||||
if(ClosestPathNodeToEnd < 0) {
|
||||
_log(PATHING__DEBUG, "No LOS to any end Path Node within range.");
|
||||
Log.Out(Logs::Detail, Logs::None, "No LOS to any end Path Node within range.");
|
||||
return noderoute;
|
||||
}
|
||||
|
||||
_log(PATHING__DEBUG, "Closest Path Node To End: %2d", ClosestPathNodeToEnd);
|
||||
Log.Out(Logs::Detail, Logs::None, "Closest Path Node To End: %2d", ClosestPathNodeToEnd);
|
||||
|
||||
if(ClosestPathNodeToStart == ClosestPathNodeToEnd)
|
||||
{
|
||||
@@ -587,8 +584,8 @@ void PathManager::SpawnPathNodes()
|
||||
npc_type->CHA = 150;
|
||||
|
||||
npc_type->findable = 1;
|
||||
|
||||
NPC* npc = new NPC(npc_type, 0, PathNodes[i].v.x, PathNodes[i].v.y, PathNodes[i].v.z, 0, FlyMode1);
|
||||
auto position = glm::vec4(PathNodes[i].v.x, PathNodes[i].v.y, PathNodes[i].v.z, 0.0f);
|
||||
NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
|
||||
entity_list.AddNPC(npc, true, true);
|
||||
@@ -652,19 +649,19 @@ void PathManager::SimpleMeshTest()
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChanged, bool &NodeReached)
|
||||
glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChanged, bool &NodeReached)
|
||||
{
|
||||
WaypointChanged = false;
|
||||
|
||||
NodeReached = false;
|
||||
|
||||
Map::Vertex NodeLoc;
|
||||
glm::vec3 NodeLoc;
|
||||
|
||||
Map::Vertex From(GetX(), GetY(), GetZ());
|
||||
glm::vec3 From(GetX(), GetY(), GetZ());
|
||||
|
||||
Map::Vertex HeadPosition(From.x, From.y, From.z + (GetSize() < 6.0 ? 6 : GetSize()) * HEAD_POSITION);
|
||||
glm::vec3 HeadPosition(From.x, From.y, From.z + (GetSize() < 6.0 ? 6 : GetSize()) * HEAD_POSITION);
|
||||
|
||||
Map::Vertex To(ToX, ToY, ToZ);
|
||||
glm::vec3 To(ToX, ToY, ToZ);
|
||||
|
||||
bool SameDestination = (To == PathingDestination);
|
||||
|
||||
@@ -673,7 +670,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
if(To == From)
|
||||
return To;
|
||||
|
||||
mlog(PATHING__DEBUG, "UpdatePath. From(%8.3f, %8.3f, %8.3f) To(%8.3f, %8.3f, %8.3f)", From.x, From.y, From.z, To.x, To.y, To.z);
|
||||
Log.Out(Logs::Detail, Logs::None, "UpdatePath. From(%8.3f, %8.3f, %8.3f) To(%8.3f, %8.3f, %8.3f)", From.x, From.y, From.z, To.x, To.y, To.z);
|
||||
|
||||
if(From == PathingLastPosition)
|
||||
{
|
||||
@@ -681,7 +678,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
|
||||
if((PathingLoopCount > 5) && !IsRooted())
|
||||
{
|
||||
mlog(PATHING__DEBUG, "appears to be stuck. Teleporting them to next position.", GetName());
|
||||
Log.Out(Logs::Detail, Logs::None, "appears to be stuck. Teleporting them to next position.", GetName());
|
||||
|
||||
if(Route.size() == 0)
|
||||
{
|
||||
@@ -721,7 +718,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
// If we are already pathing, and the destination is the same as before ...
|
||||
if(SameDestination)
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Still pathing to the same destination.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Still pathing to the same destination.");
|
||||
|
||||
// Get the coordinates of the first path node we are going to.
|
||||
NextNode = Route.front();
|
||||
@@ -732,7 +729,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
// We have reached the path node.
|
||||
if(NodeLoc == From)
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Arrived at node %i", NextNode);
|
||||
Log.Out(Logs::Detail, Logs::None, " Arrived at node %i", NextNode);
|
||||
|
||||
NodeReached = true;
|
||||
|
||||
@@ -746,37 +743,36 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
// target, and we may run past the target if we don't check LOS at this point.
|
||||
int RouteSize = Route.size();
|
||||
|
||||
mlog(PATHING__DEBUG, "Route size is %i", RouteSize);
|
||||
Log.Out(Logs::Detail, Logs::None, "Route size is %i", RouteSize);
|
||||
|
||||
if((RouteSize == 2)
|
||||
|| ((PathingTraversedNodes >= RuleI(Pathing, MinNodesTraversedForLOSCheck))
|
||||
&& (RouteSize <= RuleI(Pathing, MinNodesLeftForLOSCheck))
|
||||
&& PathingLOSCheckTimer->Check()))
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Checking distance to target.");
|
||||
float Distance = VertexDistanceNoRoot(From, To);
|
||||
Log.Out(Logs::Detail, Logs::None, " Checking distance to target.");
|
||||
float Distance = VectorDistanceNoRoot(From, To);
|
||||
|
||||
mlog(PATHING__DEBUG, " Distance between From and To (NoRoot) is %8.3f", Distance);
|
||||
Log.Out(Logs::Detail, Logs::None, " Distance between From and To (NoRoot) is %8.3f", Distance);
|
||||
|
||||
if((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort))
|
||||
&& (ABS(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold)))
|
||||
{
|
||||
if ((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort)) &&
|
||||
(std::abs(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold))) {
|
||||
if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr))
|
||||
PathingLOSState = HaveLOS;
|
||||
else
|
||||
PathingLOSState = NoLOS;
|
||||
mlog(PATHING__DEBUG, " LOS stats is %s", (PathingLOSState == HaveLOS) ? "HaveLOS" : "NoLOS");
|
||||
Log.Out(Logs::Detail, Logs::None, "NoLOS");
|
||||
|
||||
if((PathingLOSState == HaveLOS) && zone->pathing->NoHazards(From, To))
|
||||
{
|
||||
mlog(PATHING__DEBUG, " No hazards. Running directly to target.");
|
||||
Log.Out(Logs::Detail, Logs::None, " No hazards. Running directly to target.");
|
||||
Route.clear();
|
||||
|
||||
return To;
|
||||
}
|
||||
else
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Continuing on node path.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Continuing on node path.");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -802,7 +798,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
|
||||
if(Route.size() == 0)
|
||||
{
|
||||
mlog(PATHING__DEBUG, "Missing node after teleport.");
|
||||
Log.Out(Logs::Detail, Logs::None, "Missing node after teleport.");
|
||||
return To;
|
||||
}
|
||||
|
||||
@@ -812,7 +808,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
|
||||
Teleport(NodeLoc);
|
||||
|
||||
mlog(PATHING__DEBUG, " TELEPORTED to %8.3f, %8.3f, %8.3f\n", NodeLoc.x, NodeLoc.y, NodeLoc.z);
|
||||
Log.Out(Logs::Detail, Logs::None, " TELEPORTED to %8.3f, %8.3f, %8.3f\n", NodeLoc.x, NodeLoc.y, NodeLoc.z);
|
||||
|
||||
Route.pop_front();
|
||||
|
||||
@@ -823,7 +819,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
}
|
||||
zone->pathing->OpenDoors(PathingLastNodeVisited, NextNode, this);
|
||||
|
||||
mlog(PATHING__DEBUG, " Now moving to node %i", NextNode);
|
||||
Log.Out(Logs::Detail, Logs::None, " Now moving to node %i", NextNode);
|
||||
|
||||
return zone->pathing->GetPathNodeCoordinates(NextNode);
|
||||
}
|
||||
@@ -831,7 +827,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
{
|
||||
// we have run all the nodes, all that is left is the direct path from the last node
|
||||
// to the destination
|
||||
mlog(PATHING__DEBUG, " Reached end of node path, running direct to target.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Reached end of node path, running direct to target.");
|
||||
|
||||
return To;
|
||||
}
|
||||
@@ -845,31 +841,30 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
&& (RouteSize <= RuleI(Pathing, MinNodesLeftForLOSCheck))
|
||||
&& PathingLOSCheckTimer->Check())
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Checking distance to target.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Checking distance to target.");
|
||||
|
||||
float Distance = VertexDistanceNoRoot(From, To);
|
||||
float Distance = VectorDistanceNoRoot(From, To);
|
||||
|
||||
mlog(PATHING__DEBUG, " Distance between From and To (NoRoot) is %8.3f", Distance);
|
||||
Log.Out(Logs::Detail, Logs::None, " Distance between From and To (NoRoot) is %8.3f", Distance);
|
||||
|
||||
if((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort))
|
||||
&& (ABS(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold)))
|
||||
{
|
||||
if ((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort)) &&
|
||||
(std::abs(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold))) {
|
||||
if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr))
|
||||
PathingLOSState = HaveLOS;
|
||||
else
|
||||
PathingLOSState = NoLOS;
|
||||
mlog(PATHING__DEBUG, " LOS stats is %s", (PathingLOSState == HaveLOS) ? "HaveLOS" : "NoLOS");
|
||||
Log.Out(Logs::Detail, Logs::None, "NoLOS");
|
||||
|
||||
if((PathingLOSState == HaveLOS) && zone->pathing->NoHazards(From, To))
|
||||
{
|
||||
mlog(PATHING__DEBUG, " No hazards. Running directly to target.");
|
||||
Log.Out(Logs::Detail, Logs::None, " No hazards. Running directly to target.");
|
||||
Route.clear();
|
||||
|
||||
return To;
|
||||
}
|
||||
else
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Continuing on node path.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Continuing on node path.");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -881,34 +876,33 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
{
|
||||
// We get here if we were already pathing, but our destination has now changed.
|
||||
//
|
||||
mlog(PATHING__DEBUG, " Target has changed position.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Target has changed position.");
|
||||
// Update our record of where we are going to.
|
||||
PathingDestination = To;
|
||||
// Check if we now have LOS etc to the new destination.
|
||||
if(PathingLOSCheckTimer->Check())
|
||||
{
|
||||
float Distance = VertexDistanceNoRoot(From, To);
|
||||
float Distance = VectorDistanceNoRoot(From, To);
|
||||
|
||||
if((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort))
|
||||
&& (ABS(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold)))
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Checking for short LOS at distance %8.3f.", Distance);
|
||||
if ((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort)) &&
|
||||
(std::abs(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold))) {
|
||||
Log.Out(Logs::Detail, Logs::None, " Checking for short LOS at distance %8.3f.", Distance);
|
||||
if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr))
|
||||
PathingLOSState = HaveLOS;
|
||||
else
|
||||
PathingLOSState = NoLOS;
|
||||
|
||||
mlog(PATHING__DEBUG, " LOS stats is %s", (PathingLOSState == HaveLOS) ? "HaveLOS" : "NoLOS");
|
||||
Log.Out(Logs::Detail, Logs::None, "NoLOS");
|
||||
|
||||
if((PathingLOSState == HaveLOS) && zone->pathing->NoHazards(From, To))
|
||||
{
|
||||
mlog(PATHING__DEBUG, " No hazards. Running directly to target.");
|
||||
Log.Out(Logs::Detail, Logs::None, " No hazards. Running directly to target.");
|
||||
Route.clear();
|
||||
return To;
|
||||
}
|
||||
else
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Continuing on node path.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Continuing on node path.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -919,19 +913,19 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
{
|
||||
if(!PathingRouteUpdateTimerShort->Check())
|
||||
{
|
||||
mlog(PATHING__DEBUG, "Short route update timer not yet expired.");
|
||||
Log.Out(Logs::Detail, Logs::None, "Short route update timer not yet expired.");
|
||||
return zone->pathing->GetPathNodeCoordinates(Route.front());
|
||||
}
|
||||
mlog(PATHING__DEBUG, "Short route update timer expired.");
|
||||
Log.Out(Logs::Detail, Logs::None, "Short route update timer expired.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!PathingRouteUpdateTimerLong->Check())
|
||||
{
|
||||
mlog(PATHING__DEBUG, "Long route update timer not yet expired.");
|
||||
Log.Out(Logs::Detail, Logs::None, "Long route update timer not yet expired.");
|
||||
return zone->pathing->GetPathNodeCoordinates(Route.front());
|
||||
}
|
||||
mlog(PATHING__DEBUG, "Long route update timer expired.");
|
||||
Log.Out(Logs::Detail, Logs::None, "Long route update timer expired.");
|
||||
}
|
||||
|
||||
// We are already pathing, destination changed, no LOS. Find the nearest node to our destination.
|
||||
@@ -940,7 +934,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
// Destination unreachable via pathing, return direct route.
|
||||
if(DestinationPathNode == -1)
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Unable to find path node for new destination. Running straight to target.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Unable to find path node for new destination. Running straight to target.");
|
||||
Route.clear();
|
||||
return To;
|
||||
}
|
||||
@@ -948,7 +942,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
// one, we will carry on on our path.
|
||||
if(DestinationPathNode == Route.back())
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Same destination Node (%i). Continue with current path.", DestinationPathNode);
|
||||
Log.Out(Logs::Detail, Logs::None, " Same destination Node (%i). Continue with current path.", DestinationPathNode);
|
||||
|
||||
NodeLoc = zone->pathing->GetPathNodeCoordinates(Route.front());
|
||||
|
||||
@@ -956,7 +950,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
// Check if we have reached a path node.
|
||||
if(NodeLoc == From)
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Arrived at node %i, moving to next one.\n", Route.front());
|
||||
Log.Out(Logs::Detail, Logs::None, " Arrived at node %i, moving to next one.\n", Route.front());
|
||||
|
||||
NodeReached = true;
|
||||
|
||||
@@ -979,7 +973,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
|
||||
if(Route.size() == 0)
|
||||
{
|
||||
mlog(PATHING__DEBUG, "Missing node after teleport.");
|
||||
Log.Out(Logs::Detail, Logs::None, "Missing node after teleport.");
|
||||
return To;
|
||||
}
|
||||
|
||||
@@ -989,7 +983,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
|
||||
Teleport(NodeLoc);
|
||||
|
||||
mlog(PATHING__DEBUG, " TELEPORTED to %8.3f, %8.3f, %8.3f\n", NodeLoc.x, NodeLoc.y, NodeLoc.z);
|
||||
Log.Out(Logs::Detail, Logs::None, " TELEPORTED to %8.3f, %8.3f, %8.3f\n", NodeLoc.x, NodeLoc.y, NodeLoc.z);
|
||||
|
||||
Route.pop_front();
|
||||
|
||||
@@ -999,7 +993,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
NextNode = Route.front();
|
||||
}
|
||||
// Return the coords of our next path node on the route.
|
||||
mlog(PATHING__DEBUG, " Now moving to node %i", NextNode);
|
||||
Log.Out(Logs::Detail, Logs::None, " Now moving to node %i", NextNode);
|
||||
|
||||
zone->pathing->OpenDoors(PathingLastNodeVisited, NextNode, this);
|
||||
|
||||
@@ -1007,7 +1001,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
}
|
||||
else
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Reached end of path grid. Running direct to target.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Reached end of path grid. Running direct to target.");
|
||||
return To;
|
||||
}
|
||||
}
|
||||
@@ -1015,7 +1009,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
}
|
||||
else
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Target moved. End node is different. Clearing route.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Target moved. End node is different. Clearing route.");
|
||||
|
||||
Route.clear();
|
||||
// We will now fall through to get a new route.
|
||||
@@ -1025,11 +1019,11 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
|
||||
|
||||
}
|
||||
mlog(PATHING__DEBUG, " Our route list is empty.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Our route list is empty.");
|
||||
|
||||
if((SameDestination) && !PathingLOSCheckTimer->Check())
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Destination same as before, LOS check timer not reached. Returning To.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Destination same as before, LOS check timer not reached. Returning To.");
|
||||
return To;
|
||||
}
|
||||
|
||||
@@ -1039,27 +1033,26 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
|
||||
WaypointChanged = true;
|
||||
|
||||
float Distance = VertexDistanceNoRoot(From, To);
|
||||
float Distance = VectorDistanceNoRoot(From, To);
|
||||
|
||||
if((Distance <= RuleR(Pathing, MinDistanceForLOSCheckLong))
|
||||
&& (ABS(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold)))
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Checking for long LOS at distance %8.3f.", Distance);
|
||||
if ((Distance <= RuleR(Pathing, MinDistanceForLOSCheckLong)) &&
|
||||
(std::abs(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold))) {
|
||||
Log.Out(Logs::Detail, Logs::None, " Checking for long LOS at distance %8.3f.", Distance);
|
||||
|
||||
if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr))
|
||||
PathingLOSState = HaveLOS;
|
||||
else
|
||||
PathingLOSState = NoLOS;
|
||||
|
||||
mlog(PATHING__DEBUG, " LOS stats is %s", (PathingLOSState == HaveLOS) ? "HaveLOS" : "NoLOS");
|
||||
Log.Out(Logs::Detail, Logs::None, "NoLOS");
|
||||
|
||||
if((PathingLOSState == HaveLOS) && zone->pathing->NoHazards(From, To))
|
||||
{
|
||||
mlog(PATHING__DEBUG, "Target is reachable. Running directly there.");
|
||||
Log.Out(Logs::Detail, Logs::None, "Target is reachable. Running directly there.");
|
||||
return To;
|
||||
}
|
||||
}
|
||||
mlog(PATHING__DEBUG, " Calculating new route to target.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Calculating new route to target.");
|
||||
|
||||
Route = zone->pathing->FindRoute(From, To);
|
||||
|
||||
@@ -1067,14 +1060,14 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
|
||||
if(Route.size() == 0)
|
||||
{
|
||||
mlog(PATHING__DEBUG, " No route available, running direct.");
|
||||
Log.Out(Logs::Detail, Logs::None, " No route available, running direct.");
|
||||
|
||||
return To;
|
||||
}
|
||||
|
||||
if(SameDestination && (Route.front() == PathingLastNodeVisited))
|
||||
{
|
||||
mlog(PATHING__DEBUG, " Probable loop detected. Same destination and Route.front() == PathingLastNodeVisited.");
|
||||
Log.Out(Logs::Detail, Logs::None, " Probable loop detected. Same destination and Route.front() == PathingLastNodeVisited.");
|
||||
|
||||
Route.clear();
|
||||
|
||||
@@ -1082,7 +1075,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
}
|
||||
NodeLoc = zone->pathing->GetPathNodeCoordinates(Route.front());
|
||||
|
||||
mlog(PATHING__DEBUG, " New route determined, heading for node %i", Route.front());
|
||||
Log.Out(Logs::Detail, Logs::None, " New route determined, heading for node %i", Route.front());
|
||||
|
||||
PathingLoopCount = 0;
|
||||
|
||||
@@ -1090,7 +1083,7 @@ Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &
|
||||
|
||||
}
|
||||
|
||||
int PathManager::FindNearestPathNode(Map::Vertex Position)
|
||||
int PathManager::FindNearestPathNode(glm::vec3 Position)
|
||||
{
|
||||
|
||||
// Find the nearest PathNode we have LOS to.
|
||||
@@ -1109,12 +1102,11 @@ int PathManager::FindNearestPathNode(Map::Vertex Position)
|
||||
|
||||
for(uint32 i = 0 ; i < Head.PathNodeCount; ++i)
|
||||
{
|
||||
if((ABS(Position.x - PathNodes[i].v.x) <= CandidateNodeRangeXY) &&
|
||||
(ABS(Position.y - PathNodes[i].v.y) <= CandidateNodeRangeXY) &&
|
||||
(ABS(Position.z - PathNodes[i].v.z) <= CandidateNodeRangeZ))
|
||||
{
|
||||
if ((std::abs(Position.x - PathNodes[i].v.x) <= CandidateNodeRangeXY) &&
|
||||
(std::abs(Position.y - PathNodes[i].v.y) <= CandidateNodeRangeXY) &&
|
||||
(std::abs(Position.z - PathNodes[i].v.z) <= CandidateNodeRangeZ)) {
|
||||
TempNode.id = i;
|
||||
TempNode.Distance = VertexDistanceNoRoot(Position, PathNodes[i].v);
|
||||
TempNode.Distance = VectorDistanceNoRoot(Position, PathNodes[i].v);
|
||||
SortedByDistance.push_back(TempNode);
|
||||
|
||||
}
|
||||
@@ -1124,7 +1116,7 @@ int PathManager::FindNearestPathNode(Map::Vertex Position)
|
||||
|
||||
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
|
||||
{
|
||||
_log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
|
||||
Log.Out(Logs::Detail, Logs::None, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
|
||||
|
||||
if(!zone->zonemap->LineIntersectsZone(Position, PathNodes[(*Iterator).id].v, 1.0f, nullptr))
|
||||
{
|
||||
@@ -1134,40 +1126,39 @@ int PathManager::FindNearestPathNode(Map::Vertex Position)
|
||||
}
|
||||
|
||||
if(ClosestPathNodeToStart <0 ) {
|
||||
_log(PATHING__DEBUG, "No LOS to any starting Path Node within range.");
|
||||
Log.Out(Logs::Detail, Logs::None, "No LOS to any starting Path Node within range.");
|
||||
return -1;
|
||||
}
|
||||
return ClosestPathNodeToStart;
|
||||
}
|
||||
|
||||
bool PathManager::NoHazards(Map::Vertex From, Map::Vertex To)
|
||||
bool PathManager::NoHazards(glm::vec3 From, glm::vec3 To)
|
||||
{
|
||||
// Test the Z coordinate at the mid point.
|
||||
//
|
||||
Map::Vertex MidPoint((From.x + To.x) / 2, (From.y + To.y) / 2, From.z);
|
||||
glm::vec3 MidPoint((From.x + To.x) / 2, (From.y + To.y) / 2, From.z);
|
||||
|
||||
float NewZ = zone->zonemap->FindBestZ(MidPoint, nullptr);
|
||||
|
||||
if(ABS(NewZ - From.z) > RuleR(Pathing, ZDiffThreshold))
|
||||
{
|
||||
_log(PATHING__DEBUG, " HAZARD DETECTED moving from %8.3f, %8.3f, %8.3f to %8.3f, %8.3f, %8.3f. Z Change is %8.3f",
|
||||
if (std::abs(NewZ - From.z) > RuleR(Pathing, ZDiffThreshold)) {
|
||||
Log.Out(Logs::Detail, Logs::None, " HAZARD DETECTED moving from %8.3f, %8.3f, %8.3f to %8.3f, %8.3f, %8.3f. Z Change is %8.3f",
|
||||
From.x, From.y, From.z, MidPoint.x, MidPoint.y, MidPoint.z, NewZ - From.z);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_log(PATHING__DEBUG, "No HAZARD DETECTED moving from %8.3f, %8.3f, %8.3f to %8.3f, %8.3f, %8.3f. Z Change is %8.3f",
|
||||
Log.Out(Logs::Detail, Logs::None, "No HAZARD DETECTED moving from %8.3f, %8.3f, %8.3f to %8.3f, %8.3f, %8.3f. Z Change is %8.3f",
|
||||
From.x, From.y, From.z, MidPoint.x, MidPoint.y, MidPoint.z, NewZ - From.z);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PathManager::NoHazardsAccurate(Map::Vertex From, Map::Vertex To)
|
||||
bool PathManager::NoHazardsAccurate(glm::vec3 From, glm::vec3 To)
|
||||
{
|
||||
float stepx, stepy, stepz, curx, cury, curz;
|
||||
Map::Vertex cur = From;
|
||||
glm::vec3 cur = From;
|
||||
float last_z = From.z;
|
||||
float step_size = 1.0;
|
||||
|
||||
@@ -1185,11 +1176,10 @@ bool PathManager::NoHazardsAccurate(Map::Vertex From, Map::Vertex To)
|
||||
stepy = (stepy / factor)*step_size;
|
||||
stepz = (stepz / factor)*step_size;
|
||||
|
||||
Map::Vertex TestPoint(curx, cury, curz);
|
||||
glm::vec3 TestPoint(curx, cury, curz);
|
||||
float NewZ = zone->zonemap->FindBestZ(TestPoint, nullptr);
|
||||
if (ABS(NewZ - last_z) > 5.0f)
|
||||
{
|
||||
_log(PATHING__DEBUG, " HAZARD DETECTED moving from %8.3f, %8.3f, %8.3f to %8.3f, %8.3f, %8.3f. Best Z %8.3f, Z Change is %8.3f",
|
||||
if (std::abs(NewZ - last_z) > 5.0f) {
|
||||
Log.Out(Logs::Detail, Logs::None, " HAZARD DETECTED moving from %8.3f, %8.3f, %8.3f to %8.3f, %8.3f, %8.3f. Best Z %8.3f, Z Change is %8.3f",
|
||||
From.x, From.y, From.z, TestPoint.x, TestPoint.y, TestPoint.z, NewZ, NewZ - From.z);
|
||||
return false;
|
||||
}
|
||||
@@ -1197,16 +1187,18 @@ bool PathManager::NoHazardsAccurate(Map::Vertex From, Map::Vertex To)
|
||||
|
||||
if (zone->watermap)
|
||||
{
|
||||
if (zone->watermap->InLiquid(From.x, From.y, From.z) || zone->watermap->InLiquid(To.x, To.y, To.z))
|
||||
auto from = glm::vec3(From.x, From.y, From.z);
|
||||
auto to = glm::vec3(To.x, To.y, To.z);
|
||||
if (zone->watermap->InLiquid(from) || zone->watermap->InLiquid(to))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (zone->watermap->InLiquid(TestPoint.x, TestPoint.y, NewZ))
|
||||
auto testPointNewZ = glm::vec3(TestPoint.x, TestPoint.y, NewZ);
|
||||
if (zone->watermap->InLiquid(testPointNewZ))
|
||||
{
|
||||
Map::Vertex TestPointWater(TestPoint.x, TestPoint.y, NewZ - 0.5f);
|
||||
Map::Vertex TestPointWaterDest = TestPointWater;
|
||||
Map::Vertex hit;
|
||||
glm::vec3 TestPointWater(TestPoint.x, TestPoint.y, NewZ - 0.5f);
|
||||
glm::vec3 TestPointWaterDest = TestPointWater;
|
||||
glm::vec3 hit;
|
||||
TestPointWaterDest.z -= 500;
|
||||
float best_z2 = -999990;
|
||||
if (zone->zonemap->LineIntersectsZone(TestPointWater, TestPointWaterDest, 1.0f, &hit))
|
||||
@@ -1215,30 +1207,33 @@ bool PathManager::NoHazardsAccurate(Map::Vertex From, Map::Vertex To)
|
||||
}
|
||||
if (best_z2 == -999990)
|
||||
{
|
||||
_log(PATHING__DEBUG, " HAZARD DETECTED, really deep water/lava!");
|
||||
Log.Out(Logs::Detail, Logs::None, " HAZARD DETECTED, really deep water/lava!");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ABS(NewZ - best_z2) > RuleR(Pathing, ZDiffThreshold))
|
||||
{
|
||||
_log(PATHING__DEBUG, " HAZARD DETECTED, water is fairly deep at %8.3f units deep", ABS(NewZ - best_z2));
|
||||
if (std::abs(NewZ - best_z2) > RuleR(Pathing, ZDiffThreshold)) {
|
||||
Log.Out(Logs::Detail, Logs::None,
|
||||
" HAZARD DETECTED, water is fairly deep at %8.3f units deep",
|
||||
std::abs(NewZ - best_z2));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_log(PATHING__DEBUG, " HAZARD NOT DETECTED, water is shallow at %8.3f units deep", ABS(NewZ - best_z2));
|
||||
Log.Out(Logs::Detail, Logs::None,
|
||||
" HAZARD NOT DETECTED, water is shallow at %8.3f units deep",
|
||||
std::abs(NewZ - best_z2));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log(PATHING__DEBUG, "Hazard point not in water or lava!");
|
||||
Log.Out(Logs::Detail, Logs::None, "Hazard point not in water or lava!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log(PATHING__DEBUG, "No water map loaded for hazards!");
|
||||
Log.Out(Logs::Detail, Logs::None, "No water map loaded for hazards!");
|
||||
}
|
||||
|
||||
curx += stepx;
|
||||
@@ -1249,9 +1244,12 @@ bool PathManager::NoHazardsAccurate(Map::Vertex From, Map::Vertex To)
|
||||
cur.y = cury;
|
||||
cur.z = curz;
|
||||
|
||||
if (ABS(curx - To.x) < step_size) cur.x = To.x;
|
||||
if (ABS(cury - To.y) < step_size) cur.y = To.y;
|
||||
if (ABS(curz - To.z) < step_size) cur.z = To.z;
|
||||
if (std::abs(curx - To.x) < step_size)
|
||||
cur.x = To.x;
|
||||
if (std::abs(cury - To.y) < step_size)
|
||||
cur.y = To.y;
|
||||
if (std::abs(curz - To.z) < step_size)
|
||||
cur.z = To.z;
|
||||
|
||||
} while (cur.x != To.x || cur.y != To.y || cur.z != To.z);
|
||||
return true;
|
||||
@@ -1290,7 +1288,7 @@ void PathManager::OpenDoors(int Node1, int Node2, Mob *ForWho)
|
||||
|
||||
if(d && !d->IsDoorOpen() )
|
||||
{
|
||||
_log(PATHING__DEBUG, "Opening door %i for %s", PathNodes[Node1].Neighbours[i].DoorID, ForWho->GetName());
|
||||
Log.Out(Logs::Detail, Logs::None, "Opening door %i for %s", PathNodes[Node1].Neighbours[i].DoorID, ForWho->GetName());
|
||||
|
||||
d->ForceOpen(ForWho);
|
||||
}
|
||||
@@ -1574,7 +1572,8 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
|
||||
npc_type->CHA = 150;
|
||||
npc_type->findable = 1;
|
||||
|
||||
NPC* npc = new NPC(npc_type, 0, new_node.v.x, new_node.v.y, new_node.v.z, 0, FlyMode1);
|
||||
auto position = glm::vec4(new_node.v.x, new_node.v.y, new_node.v.z, 0.0f);
|
||||
NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
entity_list.AddNPC(npc, true, true);
|
||||
|
||||
@@ -1634,7 +1633,8 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
|
||||
npc_type->CHA = 150;
|
||||
npc_type->findable = 1;
|
||||
|
||||
NPC* npc = new NPC(npc_type, 0, new_node.v.x, new_node.v.y, new_node.v.z, 0, FlyMode1);
|
||||
auto position = glm::vec4(new_node.v.x, new_node.v.y, new_node.v.z, 0.0f);
|
||||
NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
entity_list.AddNPC(npc, true, true);
|
||||
|
||||
@@ -1793,7 +1793,7 @@ void PathManager::ConnectNodeToNode(int32 Node1, int32 Node2, int32 teleport, in
|
||||
a->Neighbours[a_i].id = b->id;
|
||||
a->Neighbours[a_i].DoorID = doorid;
|
||||
a->Neighbours[a_i].Teleport = teleport;
|
||||
a->Neighbours[a_i].distance = VertexDistance(a->v, b->v);
|
||||
a->Neighbours[a_i].distance = VectorDistance(a->v, b->v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1808,7 +1808,7 @@ void PathManager::ConnectNodeToNode(int32 Node1, int32 Node2, int32 teleport, in
|
||||
b->Neighbours[b_i].id = a->id;
|
||||
b->Neighbours[b_i].DoorID = doorid;
|
||||
b->Neighbours[b_i].Teleport = teleport;
|
||||
b->Neighbours[b_i].distance = VertexDistance(a->v, b->v);
|
||||
b->Neighbours[b_i].distance = VectorDistance(a->v, b->v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1878,7 +1878,7 @@ void PathManager::ConnectNode(int32 Node1, int32 Node2, int32 teleport, int32 do
|
||||
a->Neighbours[a_i].id = b->id;
|
||||
a->Neighbours[a_i].DoorID = doorid;
|
||||
a->Neighbours[a_i].Teleport = teleport;
|
||||
a->Neighbours[a_i].distance = VertexDistance(a->v, b->v);
|
||||
a->Neighbours[a_i].distance = VectorDistance(a->v, b->v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1994,7 +1994,7 @@ void PathManager::MoveNode(Client *c)
|
||||
|
||||
if(zone->zonemap)
|
||||
{
|
||||
Map::Vertex loc(c->GetX(), c->GetY(), c->GetZ());
|
||||
glm::vec3 loc(c->GetX(), c->GetY(), c->GetZ());
|
||||
Node->bestz = zone->zonemap->FindBestZ(loc, nullptr);
|
||||
}
|
||||
else
|
||||
@@ -2065,14 +2065,14 @@ bool PathManager::NodesConnected(PathNode *a, PathNode *b)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PathManager::CheckLosFN(Map::Vertex a, Map::Vertex b)
|
||||
bool PathManager::CheckLosFN(glm::vec3 a, glm::vec3 b)
|
||||
{
|
||||
if(zone->zonemap)
|
||||
{
|
||||
Map::Vertex hit;
|
||||
glm::vec3 hit;
|
||||
|
||||
Map::Vertex myloc;
|
||||
Map::Vertex oloc;
|
||||
glm::vec3 myloc;
|
||||
glm::vec3 oloc;
|
||||
|
||||
myloc.x = a.x;
|
||||
myloc.y = a.y;
|
||||
@@ -2115,7 +2115,7 @@ void PathManager::ProcessNodesAndSave(std::string filename)
|
||||
|
||||
if(!NodesConnected(&PathNodes[x], &PathNodes[y]))
|
||||
{
|
||||
if(VertexDistance(PathNodes[x].v, PathNodes[y].v) <= 200)
|
||||
if(VectorDistance(PathNodes[x].v, PathNodes[y].v) <= 200)
|
||||
{
|
||||
if(CheckLosFN(PathNodes[x].v, PathNodes[y].v))
|
||||
{
|
||||
|
||||
+7
-7
@@ -30,7 +30,7 @@ struct NeighbourNode {
|
||||
|
||||
struct PathNode {
|
||||
uint16 id;
|
||||
Map::Vertex v;
|
||||
glm::vec3 v;
|
||||
float bestz;
|
||||
NeighbourNode Neighbours[PATHNODENEIGHBOURS];
|
||||
};
|
||||
@@ -60,17 +60,17 @@ public:
|
||||
static PathManager *LoadPathFile(const char *ZoneName);
|
||||
bool loadPaths(FILE *fp);
|
||||
void PrintPathing();
|
||||
std::deque<int> FindRoute(Map::Vertex Start, Map::Vertex End);
|
||||
std::deque<int> FindRoute(glm::vec3 Start, glm::vec3 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);
|
||||
glm::vec3 GetPathNodeCoordinates(int NodeNumber, bool BestZ = true);
|
||||
bool CheckLosFN(glm::vec3 a, glm::vec3 b);
|
||||
void SpawnPathNodes();
|
||||
void MeshTest();
|
||||
void SimpleMeshTest();
|
||||
int FindNearestPathNode(Map::Vertex Position);
|
||||
bool NoHazards(Map::Vertex From, Map::Vertex To);
|
||||
bool NoHazardsAccurate(Map::Vertex From, Map::Vertex To);
|
||||
int FindNearestPathNode(glm::vec3 Position);
|
||||
bool NoHazards(glm::vec3 From, glm::vec3 To);
|
||||
bool NoHazardsAccurate(glm::vec3 From, glm::vec3 To);
|
||||
void OpenDoors(int Node1, int Node2, Mob* ForWho);
|
||||
|
||||
PathNode* FindPathNodeByCoordinates(float x, float y, float z);
|
||||
|
||||
+18
-18
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "../common/features.h"
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "embperl.h"
|
||||
|
||||
#ifdef seed
|
||||
@@ -1072,7 +1072,7 @@ XS(XS_Client_SetBindPoint)
|
||||
new_z = (float)SvNV(ST(5));
|
||||
}
|
||||
|
||||
THIS->SetBindPoint(to_zone, to_instance, new_x, new_y, new_z);
|
||||
THIS->SetBindPoint(to_zone, to_instance, glm::vec3(new_x, new_y, new_z));
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -1271,15 +1271,15 @@ XS(XS_Client_MovePC)
|
||||
}
|
||||
else {
|
||||
if (THIS->IsMerc())
|
||||
_log(CLIENT__ERROR, "Perl(XS_Client_MovePC) attempted to process a type Merc reference");
|
||||
Log.Out(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Merc reference");
|
||||
else if (THIS->IsNPC())
|
||||
_log(CLIENT__ERROR, "Perl(XS_Client_MovePC) attempted to process a type NPC reference");
|
||||
Log.Out(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type NPC reference");
|
||||
#ifdef BOTS
|
||||
else if (THIS->IsBot())
|
||||
_log(CLIENT__ERROR, "Perl(XS_Client_MovePC) attempted to process a type Bot reference");
|
||||
#endif
|
||||
Log.Out(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Bot reference");
|
||||
#endif
|
||||
else
|
||||
_log(CLIENT__ERROR, "Perl(XS_Client_MovePC) attempted to process an Unknown type reference");
|
||||
Log.Out(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process an Unknown type reference");
|
||||
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
}
|
||||
@@ -1317,17 +1317,17 @@ XS(XS_Client_MovePCInstance)
|
||||
}
|
||||
else {
|
||||
if (THIS->IsMerc())
|
||||
_log(CLIENT__ERROR, "Perl(XS_Client_MovePCInstance) attempted to process a type Merc reference");
|
||||
Log.Out(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Merc reference");
|
||||
else if (THIS->IsNPC())
|
||||
_log(CLIENT__ERROR, "Perl(XS_Client_MovePCInstance) attempted to process a type NPC reference");
|
||||
Log.Out(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type NPC reference");
|
||||
#ifdef BOTS
|
||||
else if (THIS->IsBot())
|
||||
_log(CLIENT__ERROR, "Perl(XS_Client_MovePCInstance) attempted to process a type Bot reference");
|
||||
Log.Out(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Bot reference");
|
||||
#endif
|
||||
else
|
||||
_log(CLIENT__ERROR, "Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference");
|
||||
Log.Out(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference");
|
||||
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
}
|
||||
@@ -3899,7 +3899,7 @@ XS(XS_Client_GetClientVersion)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetClientVersion();
|
||||
RETVAL = static_cast<unsigned int>(THIS->GetClientVersion());
|
||||
XSprePUSH; PUSHu((UV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -5094,7 +5094,7 @@ XS(XS_Client_GetTaskActivityDoneCount)
|
||||
Perl_croak(aTHX_ "Usage: Client::GetTaskActivityDoneCount(THIS, TaskID, ActivityID)");
|
||||
{
|
||||
Client * THIS;
|
||||
int RETVAL;
|
||||
int RETVAL;
|
||||
int TaskID = (int)SvIV(ST(1));
|
||||
int ActivityID = (int)SvIV(ST(2));
|
||||
dXSTARG;
|
||||
@@ -5108,7 +5108,7 @@ XS(XS_Client_GetTaskActivityDoneCount)
|
||||
if (THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
|
||||
|
||||
RETVAL = THIS->GetTaskActivityDoneCountFromTaskID(TaskID, ActivityID);
|
||||
XSprePUSH; PUSHi((IV)RETVAL);
|
||||
}
|
||||
@@ -5952,7 +5952,7 @@ XS(XS_Client_SilentMessage)
|
||||
{
|
||||
Client * THIS;
|
||||
dXSTARG;
|
||||
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
@@ -5963,7 +5963,7 @@ XS(XS_Client_SilentMessage)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
if(THIS->GetTarget() != NULL){
|
||||
if(THIS->GetTarget()->IsNPC()){
|
||||
if (THIS->DistNoRootNoZ(*THIS->GetTarget()) <= 200) {
|
||||
if (DistanceSquaredNoZ(THIS->GetPosition(), THIS->GetTarget()->GetPosition()) <= 200) {
|
||||
if(THIS->GetTarget()->CastToNPC()->IsMoving() && !THIS->GetTarget()->CastToNPC()->IsOnHatelist(THIS->GetTarget()))
|
||||
THIS->GetTarget()->CastToNPC()->PauseWandering(RuleI(NPC, SayPauseTimeInSec));
|
||||
THIS->ChannelMessageReceived(8, 0, 100, SvPV_nolen(ST(1)));
|
||||
@@ -6351,7 +6351,7 @@ XS(boot_Client)
|
||||
newXSproto(strcpy(buf, "SendMarqueeMessage"), XS_Client_SendMarqueeMessage, file, "$$$$$$$");
|
||||
newXSproto(strcpy(buf, "SendColoredText"), XS_Client_SendColoredText, file, "$$$");
|
||||
newXSproto(strcpy(buf, "SendSpellAnim"), XS_Client_SendSpellAnim, file, "$$$");
|
||||
|
||||
|
||||
XSRETURN_YES;
|
||||
}
|
||||
|
||||
|
||||
+20
-13
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "../common/features.h"
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "embperl.h"
|
||||
|
||||
#ifdef seed
|
||||
@@ -138,7 +138,7 @@ XS(XS_Doors_GetX)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetX();
|
||||
RETVAL = THIS->GetPosition().x;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -164,7 +164,7 @@ XS(XS_Doors_GetY)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetY();
|
||||
RETVAL = THIS->GetPosition().y;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -190,7 +190,7 @@ XS(XS_Doors_GetZ)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetZ();
|
||||
RETVAL = THIS->GetPosition().z;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -216,7 +216,7 @@ XS(XS_Doors_GetHeading)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetHeading();
|
||||
RETVAL = THIS->GetPosition().w;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -556,7 +556,7 @@ XS(XS_Doors_SetX)
|
||||
Perl_croak(aTHX_ "Usage: Doors::SetX(THIS, XPos)");
|
||||
{
|
||||
Doors * THIS;
|
||||
float pos = (float)SvNV(ST(1));
|
||||
float x = (float)SvNV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "Doors")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
@@ -566,8 +566,9 @@ XS(XS_Doors_SetX)
|
||||
Perl_croak(aTHX_ "THIS is not of type Doors");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->SetX(pos);
|
||||
auto position = THIS->GetPosition();
|
||||
position.x = x;
|
||||
THIS->SetPosition(position);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -580,7 +581,7 @@ XS(XS_Doors_SetY)
|
||||
Perl_croak(aTHX_ "Usage: Doors::SetY(THIS, YPos)");
|
||||
{
|
||||
Doors * THIS;
|
||||
float pos = (float)SvNV(ST(1));
|
||||
float y = (float)SvNV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "Doors")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
@@ -591,7 +592,9 @@ XS(XS_Doors_SetY)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->SetY(pos);
|
||||
auto position = THIS->GetPosition();
|
||||
position.y = y;
|
||||
THIS->SetPosition(position);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -604,7 +607,7 @@ XS(XS_Doors_SetZ)
|
||||
Perl_croak(aTHX_ "Usage: Doors::SetZ(THIS, ZPos)");
|
||||
{
|
||||
Doors * THIS;
|
||||
float pos = (float)SvNV(ST(1));
|
||||
float z = (float)SvNV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "Doors")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
@@ -615,7 +618,9 @@ XS(XS_Doors_SetZ)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->SetZ(pos);
|
||||
auto position = THIS->GetPosition();
|
||||
position.z = z;
|
||||
THIS->SetPosition(position);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -639,7 +644,9 @@ XS(XS_Doors_SetHeading)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->SetHeading(heading);
|
||||
auto position = THIS->GetPosition();
|
||||
position.w = heading;
|
||||
THIS->SetPosition(position);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "../common/features.h"
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include <list>
|
||||
#include "embperl.h"
|
||||
|
||||
@@ -1875,7 +1875,7 @@ XS(XS_EntityList_GetRandomClient)
|
||||
c = INT2PTR(Client *,tmp);
|
||||
}
|
||||
}
|
||||
RETVAL = entity_list.GetRandomClient(x, y, z, d * d, c);
|
||||
RETVAL = entity_list.GetRandomClient(glm::vec3(x, y, z), d * d, c);
|
||||
ST(0) = sv_newmortal();
|
||||
sv_setref_pv(ST(0), "Client", (void*)RETVAL);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "../common/features.h"
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "embperl.h"
|
||||
|
||||
#ifdef seed
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "../common/features.h"
|
||||
#include "client.h"
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "embperl.h"
|
||||
|
||||
#ifdef seed
|
||||
|
||||
+36
-12
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "../common/features.h"
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "embperl.h"
|
||||
|
||||
#ifdef seed
|
||||
@@ -1615,7 +1615,7 @@ XS(XS_Mob_TypesTempPet)
|
||||
else
|
||||
Perl_croak(aTHX_ "target is not of type Mob");
|
||||
|
||||
|
||||
|
||||
if (items < 7)
|
||||
sticktarg = false;
|
||||
else {
|
||||
@@ -2933,6 +2933,32 @@ XS(XS_Mob_GetCorruption)
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_GetPhR); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_GetPhR)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: Mob::GetPhR(THIS)");
|
||||
{
|
||||
Mob * THIS;
|
||||
int32 RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "Mob")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Mob *, tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||
if (THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetPhR();
|
||||
XSprePUSH; PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_GetMaxSTR); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_GetMaxSTR)
|
||||
{
|
||||
@@ -3525,7 +3551,7 @@ XS(XS_Mob_GetWaypointX)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetCWPX();
|
||||
RETVAL = THIS->GetCurrentWayPoint().x;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -3551,7 +3577,7 @@ XS(XS_Mob_GetWaypointY)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetCWPY();
|
||||
RETVAL = THIS->GetCurrentWayPoint().y;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -3577,7 +3603,7 @@ XS(XS_Mob_GetWaypointZ)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetCWPZ();
|
||||
RETVAL = THIS->GetCurrentWayPoint().z;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -3603,7 +3629,7 @@ XS(XS_Mob_GetWaypointH)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetCWPH();
|
||||
RETVAL = THIS->GetCurrentWayPoint().w;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -7636,10 +7662,7 @@ XS(XS_Mob_SetDeltas)
|
||||
Perl_croak(aTHX_ "Usage: Mob::SetDeltas(THIS, delta_x, delta_y, delta_z, delta_h)");
|
||||
{
|
||||
Mob * THIS;
|
||||
float delta_x = (float)SvNV(ST(1));
|
||||
float delta_y = (float)SvNV(ST(2));
|
||||
float delta_z = (float)SvNV(ST(3));
|
||||
float delta_h = (float)SvNV(ST(4));
|
||||
auto delta = glm::vec4((float)SvNV(ST(1)), (float)SvNV(ST(2)), (float)SvNV(ST(3)), (float)SvNV(ST(4)));
|
||||
|
||||
if (sv_derived_from(ST(0), "Mob")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
@@ -7650,7 +7673,7 @@ XS(XS_Mob_SetDeltas)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->SetDeltas(delta_x, delta_y, delta_z, delta_h);
|
||||
THIS->SetDelta(delta);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -8462,7 +8485,8 @@ XS(boot_Mob)
|
||||
newXSproto(strcpy(buf, "GetDR"), XS_Mob_GetDR, file, "$");
|
||||
newXSproto(strcpy(buf, "GetPR"), XS_Mob_GetPR, file, "$");
|
||||
newXSproto(strcpy(buf, "GetCR"), XS_Mob_GetCR, file, "$");
|
||||
newXSproto(strcpy(buf, "GetCorruption"), XS_Mob_GetCR, file, "$");
|
||||
newXSproto(strcpy(buf, "GetCorruption"), XS_Mob_GetCorruption, file, "$");
|
||||
newXSproto(strcpy(buf, "GetPhR"), XS_Mob_GetPhR, file, "$");
|
||||
newXSproto(strcpy(buf, "GetMaxSTR"), XS_Mob_GetMaxSTR, file, "$");
|
||||
newXSproto(strcpy(buf, "GetMaxSTA"), XS_Mob_GetMaxSTA, file, "$");
|
||||
newXSproto(strcpy(buf, "GetMaxDEX"), XS_Mob_GetMaxDEX, file, "$");
|
||||
|
||||
+10
-9
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "../common/features.h"
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "embperl.h"
|
||||
|
||||
#ifdef seed
|
||||
@@ -1345,7 +1345,8 @@ XS(XS_NPC_MoveTo)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->MoveTo(mtx, mty, mtz, mth, saveguard);
|
||||
auto position = glm::vec4(mtx, mty, mtz, mth);
|
||||
THIS->MoveTo(position, saveguard);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -1545,7 +1546,7 @@ XS(XS_NPC_GetSpawnPointX)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
|
||||
RETVAL = THIS->GetSpawnPointX();
|
||||
RETVAL = THIS->GetSpawnPoint().x;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -1572,7 +1573,7 @@ XS(XS_NPC_GetSpawnPointY)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
|
||||
RETVAL = THIS->GetSpawnPointY();
|
||||
RETVAL = THIS->GetSpawnPoint().y;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -1599,7 +1600,7 @@ XS(XS_NPC_GetSpawnPointZ)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
|
||||
RETVAL = THIS->GetSpawnPointZ();
|
||||
RETVAL = THIS->GetSpawnPoint().z;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -1626,7 +1627,7 @@ XS(XS_NPC_GetSpawnPointH)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
|
||||
RETVAL = THIS->GetSpawnPointH();
|
||||
RETVAL = THIS->GetSpawnPoint().w;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -1653,7 +1654,7 @@ XS(XS_NPC_GetGuardPointX)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
|
||||
RETVAL = THIS->GetGuardPointX();
|
||||
RETVAL = THIS->GetGuardPoint().x;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -1680,7 +1681,7 @@ XS(XS_NPC_GetGuardPointY)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
|
||||
RETVAL = THIS->GetGuardPointY();
|
||||
RETVAL = THIS->GetGuardPoint().y;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -1707,7 +1708,7 @@ XS(XS_NPC_GetGuardPointZ)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
|
||||
RETVAL = THIS->GetGuardPointZ();
|
||||
RETVAL = THIS->GetGuardPoint().z;
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "../common/features.h"
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "embperl.h"
|
||||
|
||||
#ifdef seed
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
|
||||
#include "../common/features.h"
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/types.h"
|
||||
#include "embperl.h"
|
||||
|
||||
#ifdef seed
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "../common/features.h"
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "embperl.h"
|
||||
|
||||
#ifdef seed
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "../common/features.h"
|
||||
#include "client.h"
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "embperl.h"
|
||||
|
||||
#ifdef seed
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "../common/features.h"
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "embperl.h"
|
||||
|
||||
#ifdef seed
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include <stdlib.h>
|
||||
#include "perlpacket.h"
|
||||
#include "client.h"
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../common/emu_opcodes.h"
|
||||
|
||||
class Client;
|
||||
|
||||
+3
-10
@@ -15,7 +15,8 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include <string.h>
|
||||
#ifdef _WINDOWS
|
||||
#include <process.h>
|
||||
@@ -211,9 +212,6 @@ void ZoneDatabase::DeletePetitionFromDB(Petition* wpet) {
|
||||
|
||||
std::string query = StringFormat("DELETE FROM petitions WHERE petid = %i", wpet->GetID());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error in DeletePetitionFromDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
void ZoneDatabase::UpdatePetitionToDB(Petition* wpet) {
|
||||
@@ -225,9 +223,6 @@ void ZoneDatabase::UpdatePetitionToDB(Petition* wpet) {
|
||||
wpet->GetCheckouts(), wpet->GetUnavails(),
|
||||
wpet->CheckedOut() ? 1: 0, wpet->GetID());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error in UpdatePetitionToDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
void ZoneDatabase::InsertPetitionToDB(Petition* wpet)
|
||||
@@ -253,12 +248,11 @@ void ZoneDatabase::InsertPetitionToDB(Petition* wpet)
|
||||
safe_delete_array(petitiontext);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in InsertPetitionToDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
#if EQDEBUG >= 5
|
||||
LogFile->write(EQEMuLog::Debug, "New petition created");
|
||||
Log.Out(Logs::General, Logs::None, "New petition created");
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -272,7 +266,6 @@ void ZoneDatabase::RefreshPetitionsFromDB()
|
||||
"FROM petitions ORDER BY petid";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in RefreshPetitionsFromDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+68
-68
@@ -16,7 +16,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/spdat.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/types.h"
|
||||
@@ -243,7 +243,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
||||
PetRecord record;
|
||||
if(!database.GetPoweredPetEntry(pettype, act_power, &record)) {
|
||||
Message(13, "Unable to find data for pet %s", pettype);
|
||||
LogFile->write(EQEMuLog::Error, "Unable to find data for pet %s, check pets table.", pettype);
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to find data for pet %s, check pets table.", pettype);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
||||
const NPCType *base = database.GetNPCType(record.npc_type);
|
||||
if(base == nullptr) {
|
||||
Message(13, "Unable to load NPC data for pet %s", pettype);
|
||||
LogFile->write(EQEMuLog::Error, "Unable to load NPC data for pet %s (NPC ID %d), check pets and npc_types tables.", pettype, record.npc_type);
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to load NPC data for pet %s (NPC ID %d), check pets and npc_types tables.", pettype, record.npc_type);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -361,28 +361,27 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
||||
|
||||
// get a random npc id from the spawngroups assigned to this zone
|
||||
auto query = StringFormat("SELECT npcID "
|
||||
"FROM (spawnentry INNER JOIN spawn2 ON spawn2.spawngroupID = spawnentry.spawngroupID) "
|
||||
"INNER JOIN npc_types ON npc_types.id = spawnentry.npcID "
|
||||
"WHERE spawn2.zone = '%s' AND npc_types.bodytype NOT IN (11, 33, 66, 67) "
|
||||
"AND npc_types.race NOT IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 44, "
|
||||
"55, 67, 71, 72, 73, 77, 78, 81, 90, 92, 93, 94, 106, 112, 114, 127, 128, "
|
||||
"130, 139, 141, 183, 236, 237, 238, 239, 254, 266, 329, 330, 378, 379, "
|
||||
"380, 381, 382, 383, 404, 522) "
|
||||
"ORDER BY RAND() LIMIT 1", zone->GetShortName());
|
||||
auto results = database.QueryDatabase(query);
|
||||
"FROM (spawnentry INNER JOIN spawn2 ON spawn2.spawngroupID = spawnentry.spawngroupID) "
|
||||
"INNER JOIN npc_types ON npc_types.id = spawnentry.npcID "
|
||||
"WHERE spawn2.zone = '%s' AND npc_types.bodytype NOT IN (11, 33, 66, 67) "
|
||||
"AND npc_types.race NOT IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 44, "
|
||||
"55, 67, 71, 72, 73, 77, 78, 81, 90, 92, 93, 94, 106, 112, 114, 127, 128, "
|
||||
"130, 139, 141, 183, 236, 237, 238, 239, 254, 266, 329, 330, 378, 379, "
|
||||
"380, 381, 382, 383, 404, 522) "
|
||||
"ORDER BY RAND() LIMIT 1", zone->GetShortName());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
// if the database query failed
|
||||
LogFile->write(EQEMuLog::Error, "Error querying database for monster summoning pet in zone %s (%s)", zone->GetShortName(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (results.RowCount() != 0) {
|
||||
auto row = results.begin();
|
||||
monsterid = atoi(row[0]);
|
||||
}
|
||||
if (results.RowCount() != 0) {
|
||||
auto row = results.begin();
|
||||
monsterid = atoi(row[0]);
|
||||
}
|
||||
|
||||
// since we don't have any monsters, just make it look like an earth pet for now
|
||||
if (monsterid == 0)
|
||||
monsterid = 567;
|
||||
// since we don't have any monsters, just make it look like an earth pet for now
|
||||
if (monsterid == 0)
|
||||
monsterid = 567;
|
||||
|
||||
// give the summoned pet the attributes of the monster we found
|
||||
const NPCType* monster = database.GetNPCType(monsterid);
|
||||
@@ -395,7 +394,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
||||
npc_type->helmtexture = monster->helmtexture;
|
||||
npc_type->herosforgemodel = monster->herosforgemodel;
|
||||
} else
|
||||
LogFile->write(EQEMuLog::Error, "Error loading NPC data for monster summoning pet (NPC ID %d)", monsterid);
|
||||
Log.Out(Logs::General, Logs::Error, "Error loading NPC data for monster summoning pet (NPC ID %d)", monsterid);
|
||||
|
||||
}
|
||||
|
||||
@@ -418,6 +417,8 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
||||
}
|
||||
}
|
||||
|
||||
npc->UpdateEquipLightValue();
|
||||
|
||||
// finally, override size if one was provided
|
||||
if (in_size > 0.0f)
|
||||
npc->size = in_size;
|
||||
@@ -430,7 +431,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
||||
into walls or objects (+10), this sometimes creates the "ghost" effect. I changed to +2 (as close as I
|
||||
could get while it still looked good). I also noticed this can happen if an NPC is spawned on the same spot of another or in a related bad spot.*/
|
||||
Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 power)
|
||||
: NPC(type_data, 0, owner->GetX()+2, owner->GetY()+2, owner->GetZ(), owner->GetHeading(), FlyMode3)
|
||||
: NPC(type_data, 0, owner->GetPosition() + glm::vec4(2.0f, 2.0f, 0.0f, 0.0f), FlyMode3)
|
||||
{
|
||||
GiveNPCTypeData(type_data);
|
||||
typeofpet = type;
|
||||
@@ -438,6 +439,8 @@ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 po
|
||||
SetOwnerID(owner->GetID());
|
||||
SetPetSpellID(spell_id);
|
||||
taunting = true;
|
||||
|
||||
// Class should use npc constructor to set light properties
|
||||
}
|
||||
|
||||
bool ZoneDatabase::GetPetEntry(const char *pet_type, PetRecord *into) {
|
||||
@@ -449,31 +452,31 @@ bool ZoneDatabase::GetPoweredPetEntry(const char *pet_type, int16 petpower, PetR
|
||||
|
||||
if (petpower <= 0)
|
||||
query = StringFormat("SELECT npcID, temp, petpower, petcontrol, petnaming, monsterflag, equipmentset "
|
||||
"FROM pets WHERE type='%s' AND petpower<=0", pet_type);
|
||||
"FROM pets WHERE type='%s' AND petpower<=0", pet_type);
|
||||
else
|
||||
query = StringFormat("SELECT npcID, temp, petpower, petcontrol, petnaming, monsterflag, equipmentset "
|
||||
"FROM pets WHERE type='%s' AND petpower<=%d ORDER BY petpower DESC LIMIT 1",
|
||||
pet_type, petpower);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetPoweredPetEntry query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
"FROM pets WHERE type='%s' AND petpower<=%d ORDER BY petpower DESC LIMIT 1",
|
||||
pet_type, petpower);
|
||||
|
||||
if (results.RowCount() != 1)
|
||||
return false;
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
if (results.RowCount() != 1)
|
||||
return false;
|
||||
|
||||
into->npc_type = atoi(row[0]);
|
||||
into->temporary = atoi(row[1]);
|
||||
into->petpower = atoi(row[2]);
|
||||
into->petcontrol = atoi(row[3]);
|
||||
into->petnaming = atoi(row[4]);
|
||||
into->monsterflag = atoi(row[5]);
|
||||
into->equipmentset = atoi(row[6]);
|
||||
auto row = results.begin();
|
||||
|
||||
return true;
|
||||
into->npc_type = atoi(row[0]);
|
||||
into->temporary = atoi(row[1]);
|
||||
into->petpower = atoi(row[2]);
|
||||
into->petcontrol = atoi(row[3]);
|
||||
into->petnaming = atoi(row[4]);
|
||||
into->monsterflag = atoi(row[5]);
|
||||
into->equipmentset = atoi(row[6]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Mob* Mob::GetPet() {
|
||||
@@ -653,41 +656,38 @@ bool ZoneDatabase::GetBasePetItems(int32 equipmentset, uint32 *items) {
|
||||
// all of the result rows. Check if we have something in the slot
|
||||
// already. If no, add the item id to the equipment array.
|
||||
while (curset >= 0 && depth < 5) {
|
||||
std::string query = StringFormat("SELECT nested_set FROM pets_equipmentset WHERE set_id = '%s'", curset);
|
||||
std::string query = StringFormat("SELECT nested_set FROM pets_equipmentset WHERE set_id = '%s'", curset);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (results.RowCount() != 1) {
|
||||
// invalid set reference, it doesn't exist
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems equipment set '%d' does not exist", curset);
|
||||
return false;
|
||||
}
|
||||
if (results.RowCount() != 1) {
|
||||
// invalid set reference, it doesn't exist
|
||||
Log.Out(Logs::General, Logs::Error, "Error in GetBasePetItems equipment set '%d' does not exist", curset);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
nextset = atoi(row[0]);
|
||||
auto row = results.begin();
|
||||
nextset = atoi(row[0]);
|
||||
|
||||
query = StringFormat("SELECT slot, item_id FROM pets_equipmentset_entries WHERE set_id='%s'", curset);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
else {
|
||||
for (row = results.begin(); row != results.end(); ++row)
|
||||
{
|
||||
slot = atoi(row[0]);
|
||||
query = StringFormat("SELECT slot, item_id FROM pets_equipmentset_entries WHERE set_id='%s'", curset);
|
||||
results = QueryDatabase(query);
|
||||
if (results.Success()) {
|
||||
for (row = results.begin(); row != results.end(); ++row)
|
||||
{
|
||||
slot = atoi(row[0]);
|
||||
|
||||
if (slot >= EmuConstants::EQUIPMENT_SIZE)
|
||||
continue;
|
||||
if (slot >= EmuConstants::EQUIPMENT_SIZE)
|
||||
continue;
|
||||
|
||||
if (items[slot] == 0)
|
||||
items[slot] = atoi(row[1]);
|
||||
}
|
||||
}
|
||||
if (items[slot] == 0)
|
||||
items[slot] = atoi(row[1]);
|
||||
}
|
||||
}
|
||||
|
||||
curset = nextset;
|
||||
depth++;
|
||||
curset = nextset;
|
||||
depth++;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+31
-20
@@ -1,26 +1,37 @@
|
||||
#ifndef PETS_H
|
||||
#define PETS_H
|
||||
|
||||
#define PET_BACKOFF 1
|
||||
#define PET_GETLOST 2
|
||||
#define PET_HEALTHREPORT 4
|
||||
#define PET_GUARDHERE 5
|
||||
#define PET_GUARDME 6
|
||||
#define PET_ATTACK 7
|
||||
#define PET_FOLLOWME 8
|
||||
#define PET_SITDOWN 9
|
||||
#define PET_STANDUP 10
|
||||
#define PET_TAUNT 11
|
||||
#define PET_HOLD 12
|
||||
#define PET_NOTAUNT 14
|
||||
#define PET_LEADER 16
|
||||
#define PET_SLUMBER 17
|
||||
#define PET_NOCAST 18
|
||||
#define PET_FOCUS 19
|
||||
#define PET_FOCUS_ON 25
|
||||
#define PET_FOCUS_OFF 26
|
||||
#define PET_HOLD_ON 27
|
||||
#define PET_HOLD_OFF 28
|
||||
// Defines based on the RoF2 Client
|
||||
#define PET_HEALTHREPORT 0 // 0x00 - /pet health or Pet Window
|
||||
#define PET_LEADER 1 // 0x01 - /pet leader or Pet Window
|
||||
#define PET_ATTACK 2 // 0x02 - /pet attack or Pet Window
|
||||
#define PET_QATTACK 3 // 0x03 - /pet qattack or Pet Window
|
||||
#define PET_FOLLOWME 4 // 0x04 - /pet follow or Pet Window
|
||||
#define PET_GUARDHERE 5 // 0x05 - /pet guard or Pet Window
|
||||
#define PET_SIT 6 // 0x06 - /pet sit or Pet Window
|
||||
#define PET_SITDOWN 7 // 0x07 - /pet sit on
|
||||
#define PET_STANDUP 8 // 0x08 - /pet sit off
|
||||
#define PET_STOP 9 // 0x09 - /pet stop or Pet Window - Not implemented
|
||||
#define PET_STOP_ON 10 // 0x0a - /pet stop on - Not implemented
|
||||
#define PET_STOP_OFF 11 // 0x0b - /pet stop off - Not implemented
|
||||
#define PET_TAUNT 12 // 0x0c - /pet taunt or Pet Window
|
||||
#define PET_TAUNT_ON 13 // 0x0d - /pet taunt on
|
||||
#define PET_TAUNT_OFF 14 // 0x0e - /pet taunt off
|
||||
#define PET_HOLD 15 // 0x0f - /pet hold or Pet Window
|
||||
#define PET_HOLD_ON 16 // 0x10 - /pet hold on
|
||||
#define PET_HOLD_OFF 17 // 0x11 - /pet hold off
|
||||
#define PET_SLUMBER 18 // 0x12 - What activates this? - define guessed
|
||||
#define PET_SLUMBER_ON 19 // 0x13 - What activates this? - define guessed
|
||||
#define PET_SLUMBER_OFF 20 // 0x14 - What activates this? - define guessed
|
||||
#define PET_SPELLHOLD 21 // 0x15 - /pet no cast or /pet spellhold or Pet Window
|
||||
#define PET_SPELLHOLD_ON 22 // 0x16 - /pet spellhold on
|
||||
#define PET_SPELLHOLD_OFF 23 // 0x17 - /pet spellhold off
|
||||
#define PET_FOCUS 24 // 0x18 - /pet focus or Pet Window
|
||||
#define PET_FOCUS_ON 25 // 0x19 - /pet focus on
|
||||
#define PET_FOCUS_OFF 26 // 0x1a - /pet focus off
|
||||
#define PET_BACKOFF 28 // 0x1c - /pet back off
|
||||
#define PET_GETLOST 29 // 0x1d - /pet get lost
|
||||
#define PET_GUARDME 30 // 0x1e - Same as /pet follow, but different message in older clients - define not from client
|
||||
|
||||
class Mob;
|
||||
struct NPCType;
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
#include "position.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include "../common/string_util.h"
|
||||
|
||||
std::string to_string(const glm::vec4 &position) {
|
||||
return StringFormat("(%.3f, %.3f, %.3f, %.3f)", position.x,position.y,position.z,position.w);
|
||||
}
|
||||
|
||||
std::string to_string(const glm::vec3 &position){
|
||||
return StringFormat("(%.3f, %.3f, %.3f)", position.x,position.y,position.z);
|
||||
}
|
||||
|
||||
std::string to_string(const glm::vec2 &position){
|
||||
return StringFormat("(%.3f, %.3f)", position.x,position.y);
|
||||
}
|
||||
|
||||
bool IsOrigin(const glm::vec2 &position) {
|
||||
return glm::dot(position, position) == 0;
|
||||
}
|
||||
|
||||
bool IsOrigin(const glm::vec3 &position) {
|
||||
return glm::dot(position, position) == 0;
|
||||
}
|
||||
|
||||
bool IsOrigin(const glm::vec4 &position) {
|
||||
return IsOrigin(glm::vec3(position));
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the non square root'ed distance between the two points within the XY plane.
|
||||
*/
|
||||
float DistanceSquared(const glm::vec2& point1, const glm::vec2& point2) {
|
||||
auto diff = point1 - point2;
|
||||
return glm::dot(diff, diff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the distance between the two points on the XY plane.
|
||||
*/
|
||||
float Distance(const glm::vec2& point1, const glm::vec2& point2) {
|
||||
return std::sqrt(DistanceSquared(point1, point2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the non square root'ed distance between the two points.
|
||||
*/
|
||||
float DistanceSquared(const glm::vec3& point1, const glm::vec3& point2) {
|
||||
auto diff = point1 - point2;
|
||||
return glm::dot(diff, diff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the non square root'ed distance between the two points.
|
||||
*/
|
||||
float DistanceSquared(const glm::vec4& point1, const glm::vec4& point2) {
|
||||
return DistanceSquared(static_cast<glm::vec3>(point1), static_cast<glm::vec3>(point2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the distance between the two points.
|
||||
*/
|
||||
float Distance(const glm::vec3& point1, const glm::vec3& point2) {
|
||||
return std::sqrt(DistanceSquared(point1, point2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the distance between the two points.
|
||||
*/
|
||||
float Distance(const glm::vec4& point1, const glm::vec4& point2) {
|
||||
return Distance(static_cast<glm::vec3>(point1), static_cast<glm::vec3>(point2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the distance between the two points within the XY plane.
|
||||
*/
|
||||
float DistanceNoZ(const glm::vec3& point1, const glm::vec3& point2) {
|
||||
return Distance(static_cast<glm::vec2>(point1),static_cast<glm::vec2>(point2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the distance between the two points within the XY plane.
|
||||
*/
|
||||
float DistanceNoZ(const glm::vec4& point1, const glm::vec4& point2) {
|
||||
return Distance(static_cast<glm::vec2>(point1),static_cast<glm::vec2>(point2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the non square root'ed distance between the two points within the XY plane.
|
||||
*/
|
||||
float DistanceSquaredNoZ(const glm::vec3& point1, const glm::vec3& point2) {
|
||||
return DistanceSquared(static_cast<glm::vec2>(point1),static_cast<glm::vec2>(point2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the non square root'ed distance between the two points within the XY plane.
|
||||
*/
|
||||
float DistanceSquaredNoZ(const glm::vec4& point1, const glm::vec4& point2) {
|
||||
return DistanceSquared(static_cast<glm::vec2>(point1),static_cast<glm::vec2>(point2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if 'position' is within (inclusive) the axis aligned
|
||||
* box (3 dimensional) formed from the points minimum and maximum.
|
||||
*/
|
||||
bool IsWithinAxisAlignedBox(const glm::vec3 &position, const glm::vec3 &minimum, const glm::vec3 &maximum) {
|
||||
auto actualMinimum = glm::vec3(std::min(minimum.x, maximum.x), std::min(minimum.y, maximum.y),std::min(minimum.z, maximum.z));
|
||||
auto actualMaximum = glm::vec3(std::max(minimum.x, maximum.x), std::max(minimum.y, maximum.y),std::max(minimum.z, maximum.z));
|
||||
|
||||
bool xcheck = position.x >= actualMinimum.x && position.x <= actualMaximum.x;
|
||||
bool ycheck = position.y >= actualMinimum.y && position.y <= actualMaximum.y;
|
||||
bool zcheck = position.z >= actualMinimum.z && position.z <= actualMaximum.z;
|
||||
|
||||
return xcheck && ycheck && zcheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if 'position' is within (inclusive) the axis aligned
|
||||
* box (2 dimensional) formed from the points minimum and maximum.
|
||||
*/
|
||||
bool IsWithinAxisAlignedBox(const glm::vec2 &position, const glm::vec2 &minimum, const glm::vec2 &maximum) {
|
||||
auto actualMinimum = glm::vec2(std::min(minimum.x, maximum.x), std::min(minimum.y, maximum.y));
|
||||
auto actualMaximum = glm::vec2(std::max(minimum.x, maximum.x), std::max(minimum.y, maximum.y));
|
||||
|
||||
bool xcheck = position.x >= actualMinimum.x && position.x <= actualMaximum.x;
|
||||
bool ycheck = position.y >= actualMinimum.y && position.y <= actualMaximum.y;
|
||||
|
||||
return xcheck && ycheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the heading directly 180 degrees from the
|
||||
* current heading.
|
||||
* Takes the EQfloat from the glm::vec4 and returns
|
||||
* an EQFloat.
|
||||
*/
|
||||
float GetReciprocalHeading(const glm::vec4& point1) {
|
||||
return GetReciprocalHeading(point1.w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the heading directly 180 degrees from the
|
||||
* current heading.
|
||||
* Takes an EQfloat and returns an EQFloat.
|
||||
*/
|
||||
float GetReciprocalHeading(const float heading)
|
||||
{
|
||||
float result = 0;
|
||||
|
||||
// Convert to radians
|
||||
float h = (heading / 256.0f) * 6.283184f;
|
||||
|
||||
// Calculate the reciprocal heading in radians
|
||||
result = h + 3.141592f;
|
||||
|
||||
// Convert back to eq heading from radians
|
||||
result = (result / 6.283184f) * 256.0f;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef POSITION_H
|
||||
#define POSITION_H
|
||||
|
||||
#include <string>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
#include <glm/geometric.hpp>
|
||||
|
||||
std::string to_string(const glm::vec4 &position);
|
||||
std::string to_string(const glm::vec3 &position);
|
||||
std::string to_string(const glm::vec2 &position);
|
||||
|
||||
bool IsWithinAxisAlignedBox(const glm::vec3 &position, const glm::vec3 &minimum, const glm::vec3 &maximum);
|
||||
bool IsWithinAxisAlignedBox(const glm::vec2 &position, const glm::vec2 &minimum, const glm::vec2 &maximum);
|
||||
|
||||
bool IsOrigin(const glm::vec2 &position);
|
||||
bool IsOrigin(const glm::vec3 &position);
|
||||
bool IsOrigin(const glm::vec4 &position);
|
||||
|
||||
float DistanceSquared(const glm::vec2& point1, const glm::vec2& point2);
|
||||
float Distance(const glm::vec2& point1, const glm::vec2& point2);
|
||||
float DistanceSquared(const glm::vec3& point1, const glm::vec3& point2);
|
||||
float Distance(const glm::vec3& point1, const glm::vec3& point2);
|
||||
float DistanceNoZ(const glm::vec3& point1, const glm::vec3& point2);
|
||||
float DistanceSquaredNoZ(const glm::vec3& point1, const glm::vec3& point2);
|
||||
|
||||
float DistanceSquared(const glm::vec4& point1, const glm::vec4& point2);
|
||||
float Distance(const glm::vec4& point1, const glm::vec4& point2);
|
||||
float DistanceNoZ(const glm::vec4& point1, const glm::vec4& point2);
|
||||
float DistanceSquaredNoZ(const glm::vec4& point1, const glm::vec4& point2);
|
||||
|
||||
float GetReciprocalHeading(const glm::vec4& point1);
|
||||
float GetReciprocalHeading(const float heading);
|
||||
|
||||
#endif
|
||||
+1
-1
@@ -16,7 +16,7 @@ Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "queryserv.h"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/features.h"
|
||||
|
||||
@@ -206,11 +206,11 @@ bool QuestParserCollection::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) {
|
||||
std::string item_script;
|
||||
if(itm->GetItem()->ScriptFileID != 0) {
|
||||
item_script = "script_";
|
||||
item_script += std::to_string(static_cast<long long>(itm->GetItem()->ScriptFileID));
|
||||
item_script += std::to_string(itm->GetItem()->ScriptFileID);
|
||||
} else if(strlen(itm->GetItem()->CharmFile) > 0) {
|
||||
item_script = itm->GetItem()->CharmFile;
|
||||
} else {
|
||||
item_script = std::to_string(static_cast<long long>(itm->GetID()));
|
||||
item_script = std::to_string(itm->GetID());
|
||||
}
|
||||
|
||||
uint32 item_id = itm->GetID();
|
||||
@@ -358,11 +358,11 @@ int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst
|
||||
std::string item_script;
|
||||
if(item->GetItem()->ScriptFileID != 0) {
|
||||
item_script = "script_";
|
||||
item_script += std::to_string(static_cast<long long>(item->GetItem()->ScriptFileID));
|
||||
item_script += std::to_string(item->GetItem()->ScriptFileID);
|
||||
} else if(strlen(item->GetItem()->CharmFile) > 0) {
|
||||
item_script = item->GetItem()->CharmFile;
|
||||
} else {
|
||||
item_script = std::to_string(static_cast<long long>(item->GetID()));
|
||||
item_script = std::to_string(item->GetID());
|
||||
}
|
||||
|
||||
uint32 item_id = item->GetID();
|
||||
|
||||
+60
-70
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "../common/classes.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/skills.h"
|
||||
#include "../common/spdat.h"
|
||||
@@ -154,7 +154,7 @@ void QuestManager::echo(int colour, const char *str) {
|
||||
void QuestManager::say(const char *str) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (!owner) {
|
||||
LogFile->write(EQEMuLog::Quest, "QuestManager::say called with nullptr owner. Probably syntax error in quest file.");
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::say called with nullptr owner. Probably syntax error in quest file.");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -170,7 +170,7 @@ void QuestManager::say(const char *str) {
|
||||
void QuestManager::say(const char *str, uint8 language) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (!owner) {
|
||||
LogFile->write(EQEMuLog::Quest, "QuestManager::say called with nullptr owner. Probably syntax error in quest file.");
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::say called with nullptr owner. Probably syntax error in quest file.");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -201,11 +201,11 @@ void QuestManager::write(const char *file, const char *str) {
|
||||
fclose (pFile);
|
||||
}
|
||||
|
||||
Mob* QuestManager::spawn2(int npc_type, int grid, int unused, float x, float y, float z, float heading) {
|
||||
Mob* QuestManager::spawn2(int npc_type, int grid, int unused, const glm::vec4& position) {
|
||||
const NPCType* tmp = 0;
|
||||
if (tmp = database.GetNPCType(npc_type))
|
||||
{
|
||||
NPC* npc = new NPC(tmp, 0, x, y, z, heading, FlyMode3);
|
||||
NPC* npc = new NPC(tmp, nullptr, position, FlyMode3);
|
||||
npc->AddLootTable();
|
||||
entity_list.AddNPC(npc,true,true);
|
||||
if(grid > 0)
|
||||
@@ -218,7 +218,7 @@ Mob* QuestManager::spawn2(int npc_type, int grid, int unused, float x, float y,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, float x, float y, float z, float heading) {
|
||||
Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, const glm::vec4& position) {
|
||||
Mob *other = entity_list.GetMobByNpcTypeID(npc_type);
|
||||
if(other != nullptr) {
|
||||
return other;
|
||||
@@ -227,7 +227,7 @@ Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, float x, flo
|
||||
const NPCType* tmp = 0;
|
||||
if (tmp = database.GetNPCType(npc_type))
|
||||
{
|
||||
NPC* npc = new NPC(tmp, 0, x, y, z, heading, FlyMode3);
|
||||
NPC* npc = new NPC(tmp, nullptr, position, FlyMode3);
|
||||
npc->AddLootTable();
|
||||
entity_list.AddNPC(npc,true,true);
|
||||
if(grid > 0)
|
||||
@@ -300,8 +300,8 @@ Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id)
|
||||
database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0);
|
||||
found_spawn->SetCurrentNPCID(npcid);
|
||||
|
||||
NPC* npc = new NPC(tmp, found_spawn, found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(),
|
||||
found_spawn->GetHeading(), FlyMode3);
|
||||
auto position = glm::vec4(found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(), found_spawn->GetHeading());
|
||||
NPC* npc = new NPC(tmp, found_spawn, position, FlyMode3);
|
||||
|
||||
found_spawn->SetNPCPointer(npc);
|
||||
npc->AddLootTable();
|
||||
@@ -548,7 +548,7 @@ void QuestManager::stopalltimers(Mob *mob) {
|
||||
void QuestManager::emote(const char *str) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (!owner) {
|
||||
LogFile->write(EQEMuLog::Quest, "QuestManager::emote called with nullptr owner. Probably syntax error in quest file.");
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::emote called with nullptr owner. Probably syntax error in quest file.");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -559,7 +559,7 @@ void QuestManager::emote(const char *str) {
|
||||
void QuestManager::shout(const char *str) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (!owner) {
|
||||
LogFile->write(EQEMuLog::Quest, "QuestManager::shout called with nullptr owner. Probably syntax error in quest file.");
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::shout called with nullptr owner. Probably syntax error in quest file.");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -570,7 +570,7 @@ void QuestManager::shout(const char *str) {
|
||||
void QuestManager::shout2(const char *str) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (!owner) {
|
||||
LogFile->write(EQEMuLog::Quest, "QuestManager::shout2 called with nullptr owner. Probably syntax error in quest file.");
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::shout2 called with nullptr owner. Probably syntax error in quest file.");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -589,7 +589,7 @@ void QuestManager::gmsay(const char *str, uint32 color, bool send_to_world, uint
|
||||
void QuestManager::depop(int npc_type) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (!owner || !owner->IsNPC()) {
|
||||
LogFile->write(EQEMuLog::Quest, "QuestManager::depop called with nullptr owner or non-NPC owner. Probably syntax error in quest file.");
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::depop called with nullptr owner or non-NPC owner. Probably syntax error in quest file.");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -619,7 +619,7 @@ void QuestManager::depop(int npc_type) {
|
||||
void QuestManager::depop_withtimer(int npc_type) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (!owner || !owner->IsNPC()) {
|
||||
LogFile->write(EQEMuLog::Quest, "QuestManager::depop_withtimer called with nullptr owner or non-NPC owner. Probably syntax error in quest file.");
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::depop_withtimer called with nullptr owner or non-NPC owner. Probably syntax error in quest file.");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -646,7 +646,7 @@ void QuestManager::depopall(int npc_type) {
|
||||
entity_list.DepopAll(npc_type);
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Quest, "QuestManager::depopall called with nullptr owner, non-NPC owner, or invalid NPC Type ID. Probably syntax error in quest file.");
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::depopall called with nullptr owner, non-NPC owner, or invalid NPC Type ID. Probably syntax error in quest file.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -655,7 +655,7 @@ void QuestManager::depopzone(bool StartSpawnTimer) {
|
||||
zone->Depop(StartSpawnTimer);
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Quest, "QuestManager::depopzone called with nullptr zone. Probably syntax error in quest file.");
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::depopzone called with nullptr zone. Probably syntax error in quest file.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -664,7 +664,7 @@ void QuestManager::repopzone() {
|
||||
zone->Repop();
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Quest, "QuestManager::repopzone called with nullptr zone. Probably syntax error in quest file.");
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::repopzone called with nullptr zone. Probably syntax error in quest file.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -923,7 +923,7 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) {
|
||||
spells[curspell].skill != 52 &&
|
||||
( !RuleB(Spells, UseCHAScribeHack) || spells[curspell].effectid[EFFECT_COUNT - 1] != 10 )
|
||||
)
|
||||
{
|
||||
{
|
||||
if(IsDiscipline(curspell)){
|
||||
//we may want to come up with a function like Client::GetNextAvailableSpellBookSlot() to help speed this up a little
|
||||
for(uint32 r = 0; r < MAX_PP_DISCIPLINES; r++) {
|
||||
@@ -937,12 +937,12 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) {
|
||||
SpellGlobalCheckResult = initiator->SpellGlobalCheck(curspell, Char_ID);
|
||||
if (SpellGlobalCheckResult) {
|
||||
initiator->GetPP().disciplines.values[r] = curspell;
|
||||
database.SaveCharacterDisc(Char_ID, r, curspell);
|
||||
database.SaveCharacterDisc(Char_ID, r, curspell);
|
||||
initiator->SendDisciplineUpdate();
|
||||
initiator->Message(0, "You have learned a new discipline!");
|
||||
count++; //success counter
|
||||
}
|
||||
break; //continue the 1st loop
|
||||
break; //continue the 1st loop
|
||||
}
|
||||
else {
|
||||
initiator->GetPP().disciplines.values[r] = curspell;
|
||||
@@ -1234,7 +1234,6 @@ void QuestManager::itemlink(int item_id) {
|
||||
Client::TextLink linker;
|
||||
linker.SetLinkType(linker.linkItemData);
|
||||
linker.SetItemData(item);
|
||||
linker.SetClientVersion(initiator->GetClientVersion());
|
||||
|
||||
auto item_link = linker.GenerateLink();
|
||||
|
||||
@@ -1487,10 +1486,10 @@ void QuestManager::ding() {
|
||||
|
||||
}
|
||||
|
||||
void QuestManager::rebind(int zoneid, float x, float y, float z) {
|
||||
void QuestManager::rebind(int zoneid, const glm::vec3& location) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if(initiator && initiator->IsClient()) {
|
||||
initiator->SetBindPoint(zoneid, x, y, z);
|
||||
initiator->SetBindPoint(zoneid, 0, location);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1518,12 +1517,12 @@ void QuestManager::pause(int duration) {
|
||||
owner->CastToNPC()->PauseWandering(duration);
|
||||
}
|
||||
|
||||
void QuestManager::moveto(float x, float y, float z, float h, bool saveguardspot) {
|
||||
void QuestManager::moveto(const glm::vec4& position, bool saveguardspot) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (!owner || !owner->IsNPC())
|
||||
return;
|
||||
|
||||
owner->CastToNPC()->MoveTo(x, y, z, h, saveguardspot);
|
||||
owner->CastToNPC()->MoveTo(position, saveguardspot);
|
||||
}
|
||||
|
||||
void QuestManager::resume() {
|
||||
@@ -1564,26 +1563,20 @@ void QuestManager::setnextinchpevent(int at) {
|
||||
owner->SetNextIncHPEvent(at);
|
||||
}
|
||||
|
||||
void QuestManager::respawn(int npc_type, int grid) {
|
||||
void QuestManager::respawn(int npcTypeID, int grid) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (!owner || !owner->IsNPC())
|
||||
return;
|
||||
float x,y,z,h;
|
||||
|
||||
x = owner->GetX();
|
||||
y = owner->GetY();
|
||||
z = owner->GetZ();
|
||||
h = owner->GetHeading();
|
||||
|
||||
running_quest e = quests_running_.top();
|
||||
e.depop_npc = true;
|
||||
quests_running_.pop();
|
||||
quests_running_.push(e);
|
||||
|
||||
const NPCType* tmp = 0;
|
||||
if ((tmp = database.GetNPCType(npc_type)))
|
||||
const NPCType* npcType = nullptr;
|
||||
if ((npcType = database.GetNPCType(npcTypeID)))
|
||||
{
|
||||
owner = new NPC(tmp, 0, x, y, z, h, FlyMode3);
|
||||
owner = new NPC(npcType, nullptr, owner->GetPosition(), FlyMode3);
|
||||
owner->CastToNPC()->AddLootTable();
|
||||
entity_list.AddNPC(owner->CastToNPC(),true,true);
|
||||
if(grid > 0)
|
||||
@@ -1653,7 +1646,7 @@ void QuestManager::showgrid(int grid) {
|
||||
"ORDER BY `number`", grid, zone->GetZoneID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Quest, "Error loading grid %d for showgrid(): %s", grid, results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Quests, "Error loading grid %d for showgrid(): %s", grid, results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1705,27 +1698,28 @@ void QuestManager::sethp(int hpperc) {
|
||||
owner->Damage(owner, newhp, SPELL_UNKNOWN, SkillHandtoHand, false, 0, false);
|
||||
}
|
||||
|
||||
bool QuestManager::summonburriedplayercorpse(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading) {
|
||||
bool QuestManager::summonburriedplayercorpse(uint32 char_id, const glm::vec4& position) {
|
||||
bool Result = false;
|
||||
|
||||
if(char_id > 0) {
|
||||
Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(char_id, zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading);
|
||||
if(PlayerCorpse) {
|
||||
Result = true;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
if(char_id <= 0)
|
||||
return false;
|
||||
|
||||
Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(char_id, zone->GetZoneID(), zone->GetInstanceID(), position);
|
||||
if(!PlayerCorpse)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QuestManager::summonallplayercorpses(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading) {
|
||||
bool Result = false;
|
||||
bool QuestManager::summonallplayercorpses(uint32 char_id, const glm::vec4& position) {
|
||||
|
||||
if(char_id > 0) {
|
||||
Client* c = entity_list.GetClientByCharID(char_id);
|
||||
c->SummonAllCorpses(dest_x, dest_y, dest_z, dest_heading);
|
||||
Result = true;
|
||||
}
|
||||
return Result;
|
||||
if(char_id <= 0)
|
||||
return false;
|
||||
|
||||
Client* c = entity_list.GetClientByCharID(char_id);
|
||||
c->SummonAllCorpses(position);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 QuestManager::getplayerburriedcorpsecount(uint32 char_id) {
|
||||
@@ -2075,7 +2069,7 @@ bool QuestManager::istaskenabled(int taskid) {
|
||||
|
||||
void QuestManager::tasksetselector(int tasksetid) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
_log(TASKS__UPDATE, "TaskSetSelector called for task set %i", tasksetid);
|
||||
Log.Out(Logs::General, Logs::Tasks, "[UPDATE] TaskSetSelector called for task set %i", tasksetid);
|
||||
if(RuleB(TaskSystem, EnableTaskSystem) && initiator && owner && taskmanager)
|
||||
initiator->TaskSetSelector(owner, tasksetid);
|
||||
}
|
||||
@@ -2313,17 +2307,17 @@ int QuestManager::getlevel(uint8 type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 QuestManager::CreateGroundObject(uint32 itemid, float x, float y, float z, float heading, uint32 decay_time)
|
||||
uint16 QuestManager::CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time)
|
||||
{
|
||||
uint16 entid = 0; //safety check
|
||||
entid = entity_list.CreateGroundObject(itemid, x, y, z, heading, decay_time);
|
||||
entid = entity_list.CreateGroundObject(itemid, position, decay_time);
|
||||
return entid;
|
||||
}
|
||||
|
||||
uint16 QuestManager::CreateGroundObjectFromModel(const char *model, float x, float y, float z, float heading, uint8 type, uint32 decay_time)
|
||||
uint16 QuestManager::CreateGroundObjectFromModel(const char *model, const glm::vec4& position, uint8 type, uint32 decay_time)
|
||||
{
|
||||
uint16 entid = 0; //safety check
|
||||
entid = entity_list.CreateGroundObjectFromModel(model, x, y, z, heading, type, decay_time);
|
||||
entid = entity_list.CreateGroundObjectFromModel(model, position, type, decay_time);
|
||||
return entid;
|
||||
}
|
||||
|
||||
@@ -2474,8 +2468,6 @@ const char* QuestManager::varlink(char* perltext, int item_id) {
|
||||
Client::TextLink linker;
|
||||
linker.SetLinkType(linker.linkItemData);
|
||||
linker.SetItemData(item);
|
||||
if (initiator)
|
||||
linker.SetClientVersion(initiator->GetClientVersion());
|
||||
|
||||
auto item_link = linker.GenerateLink();
|
||||
strcpy(perltext, item_link.c_str()); // link length is currently ranged from 1 to 250 in TextLink::GenerateLink()
|
||||
@@ -2590,12 +2582,12 @@ void QuestManager::RemoveAllFromInstance(uint16 instance_id)
|
||||
}
|
||||
}
|
||||
|
||||
void QuestManager::MovePCInstance(int zone_id, int instance_id, float x, float y, float z, float heading)
|
||||
void QuestManager::MovePCInstance(int zone_id, int instance_id, const glm::vec4& position)
|
||||
{
|
||||
QuestManagerCurrentQuestVars();
|
||||
if(initiator)
|
||||
{
|
||||
initiator->MovePC(zone_id, instance_id, x, y, z, heading);
|
||||
initiator->MovePC(zone_id, instance_id, position.x, position.y, position.z, position.w);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2644,7 +2636,7 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
|
||||
std::string insert_query = StringFormat("INSERT INTO `saylink` (`phrase`) VALUES ('%s')", escaped_string);
|
||||
results = database.QueryDatabase(insert_query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str());
|
||||
} else {
|
||||
results = database.QueryDatabase(query);
|
||||
if (results.Success()) {
|
||||
@@ -2652,7 +2644,7 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
|
||||
for(auto row = results.begin(); row != results.end(); ++row)
|
||||
sayid = atoi(row[0]);
|
||||
} else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2668,8 +2660,6 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
|
||||
Client::TextLink linker;
|
||||
linker.SetProxyItemID(sayid);
|
||||
linker.SetProxyText(LinkName);
|
||||
if (initiator)
|
||||
linker.SetClientVersion(initiator->GetClientVersion());
|
||||
|
||||
auto say_link = linker.GenerateLink();
|
||||
strcpy(Phrase, say_link.c_str()); // link length is currently ranged from 1 to 250 in TextLink::GenerateLink()
|
||||
@@ -2814,7 +2804,7 @@ void QuestManager::voicetell(const char *str, int macronum, int racenum, int gen
|
||||
safe_delete(outapp);
|
||||
}
|
||||
else
|
||||
LogFile->write(EQEMuLog::Quest, "QuestManager::voicetell from %s. Client %s not found.", owner->GetName(), str);
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::voicetell from %s. Client %s not found.", owner->GetName(), str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2846,7 +2836,7 @@ void QuestManager::SendMail(const char *to, const char *from, const char *subjec
|
||||
uint16 QuestManager::CreateDoor(const char* model, float x, float y, float z, float heading, uint8 opentype, uint16 size)
|
||||
{
|
||||
uint16 entid = 0; //safety check
|
||||
entid = entity_list.CreateDoor(model, x, y, z, heading, opentype, size);
|
||||
entid = entity_list.CreateDoor(model, glm::vec4(x, y, z, heading), opentype, size);
|
||||
return entid;
|
||||
}
|
||||
|
||||
@@ -2889,7 +2879,7 @@ void QuestManager::CrossZoneSignalPlayerByName(const char *CharName, uint32 data
|
||||
CZSC->data = data;
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
}
|
||||
|
||||
void QuestManager::CrossZoneMessagePlayerByName(uint32 Type, const char *CharName, const char *Message){
|
||||
uint32 message_len = strlen(CharName) + 1;
|
||||
@@ -2899,7 +2889,7 @@ void QuestManager::CrossZoneMessagePlayerByName(uint32 Type, const char *CharNam
|
||||
CZSC->Type = Type;
|
||||
strn0cpy(CZSC->CharName, CharName, 64);
|
||||
strn0cpy(CZSC->Message, Message, 512);
|
||||
worldserver.SendPacket(pack);
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
@@ -2909,7 +2899,7 @@ void QuestManager::CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, cons
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_CZSetEntityVariableByNPCTypeID, sizeof(CZSetEntVarByNPCTypeID_Struct) + message_len + message_len2);
|
||||
CZSetEntVarByNPCTypeID_Struct* CZSNBYNID = (CZSetEntVarByNPCTypeID_Struct*)pack->pBuffer;
|
||||
CZSNBYNID->npctype_id = npctype_id;
|
||||
strn0cpy(CZSNBYNID->id, id, 256);
|
||||
strn0cpy(CZSNBYNID->id, id, 256);
|
||||
strn0cpy(CZSNBYNID->m_var, m_var, 256);
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
+10
-10
@@ -57,8 +57,8 @@ public:
|
||||
void me(const char *str);
|
||||
void summonitem(uint32 itemid, int16 charges = -1);
|
||||
void write(const char *file, const char *str);
|
||||
Mob* spawn2(int npc_type, int grid, int unused, float x, float y, float z, float heading);
|
||||
Mob* unique_spawn(int npc_type, int grid, int unused, float x, float y, float z, float heading = 0);
|
||||
Mob* spawn2(int npc_type, int grid, int unused, const glm::vec4& position);
|
||||
Mob* unique_spawn(int npc_type, int grid, int unused, const glm::vec4& position);
|
||||
Mob* spawn_from_spawn2(uint32 spawn2_id);
|
||||
void enable_spawn2(uint32 spawn2_id);
|
||||
void disable_spawn2(uint32 spawn2_id);
|
||||
@@ -132,11 +132,11 @@ public:
|
||||
void targlobal(const char *varname, const char *value, const char *duration, int npcid, int charid, int zoneid);
|
||||
void delglobal(const char *varname);
|
||||
void ding();
|
||||
void rebind(int zoneid, float x, float y, float z);
|
||||
void rebind(int zoneid, const glm::vec3& location);
|
||||
void start(int wp);
|
||||
void stop();
|
||||
void pause(int duration);
|
||||
void moveto(float x, float y, float z, float h, bool saveguardspot);
|
||||
void moveto(const glm::vec4& position, bool saveguardspot);
|
||||
void resume();
|
||||
void addldonpoints(int32 points, uint32 theme);
|
||||
void addldonwin(int32 wins, uint32 theme);
|
||||
@@ -157,8 +157,8 @@ public:
|
||||
void set_zone_flag(int zone_id);
|
||||
void clear_zone_flag(int zone_id);
|
||||
void sethp(int hpperc);
|
||||
bool summonburriedplayercorpse(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading);
|
||||
bool summonallplayercorpses(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading);
|
||||
bool summonburriedplayercorpse(uint32 char_id, const glm::vec4& position);
|
||||
bool summonallplayercorpses(uint32 char_id, const glm::vec4& position);
|
||||
uint32 getplayerburriedcorpsecount(uint32 char_id);
|
||||
bool buryplayercorpse(uint32 char_id);
|
||||
void forcedooropen(uint32 doorid, bool altmode);
|
||||
@@ -208,8 +208,8 @@ public:
|
||||
void enabletitle(int titleset);
|
||||
bool checktitle(int titlecheck);
|
||||
void removetitle(int titlecheck);
|
||||
uint16 CreateGroundObject(uint32 itemid, float x, float y, float z, float heading, uint32 decay_time = 300000);
|
||||
uint16 CreateGroundObjectFromModel(const char* model, float x, float y, float z, float heading, uint8 type = 0x00, uint32 decay_time = 0);
|
||||
uint16 CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time = 300000);
|
||||
uint16 CreateGroundObjectFromModel(const char* model, const glm::vec4& position, uint8 type = 0x00, uint32 decay_time = 0);
|
||||
void ModifyNPCStat(const char *identifier, const char *newValue);
|
||||
void UpdateSpawnTimer(uint32 id, uint32 newTime);
|
||||
void MerchantSetItem(uint32 NPCid, uint32 itemid, uint32 quantity = 0);
|
||||
@@ -224,7 +224,7 @@ public:
|
||||
//void RemoveGroupFromInstance(uint16 instance_id); //potentially useful but not implmented at this time.
|
||||
//void RemoveRaidFromInstance(uint16 instance_id); //potentially useful but not implmented at this time.
|
||||
void RemoveAllFromInstance(uint16 instance_id);
|
||||
void MovePCInstance(int zone_id, int instance_id, float x, float y, float z, float heading);
|
||||
void MovePCInstance(int zone_id, int instance_id, const glm::vec4& position);
|
||||
void FlagInstanceByGroupLeader(uint32 zone, int16 version);
|
||||
void FlagInstanceByRaidLeader(uint32 zone, int16 version);
|
||||
const char* varlink(char* perltext, int item_id);
|
||||
@@ -241,7 +241,7 @@ public:
|
||||
uint16 CreateDoor( const char* model, float x, float y, float z, float heading, uint8 opentype, uint16 size);
|
||||
int32 GetZoneID(const char *zone);
|
||||
const char *GetZoneLongName(const char *zone);
|
||||
void CrossZoneSignalPlayerByCharID(int charid, uint32 data);
|
||||
void CrossZoneSignalPlayerByCharID(int charid, uint32 data);
|
||||
void CrossZoneSignalNPCByNPCTypeID(uint32 npctype_id, uint32 data);
|
||||
void CrossZoneSignalPlayerByName(const char *CharName, uint32 data);
|
||||
void CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, const char *id, const char *m_var);
|
||||
|
||||
+21
-21
@@ -99,7 +99,7 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo
|
||||
auto results = database.QueryDatabase(query);
|
||||
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error inserting into raid members: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Error inserting into raid members: %s", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
LearnMembers();
|
||||
@@ -233,12 +233,12 @@ void Raid::SetRaidLeader(const char *wasLead, const char *name)
|
||||
std::string query = StringFormat("UPDATE raid_members SET israidleader = 0 WHERE name = '%s'", wasLead);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Set Raid Leader error: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Set Raid Leader error: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
query = StringFormat("UPDATE raid_members SET israidleader = 1 WHERE name = '%s'", name);
|
||||
results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Set Raid Leader error: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Set Raid Leader error: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
strn0cpy(leadername, name, 64);
|
||||
|
||||
@@ -271,7 +271,7 @@ void Raid::SaveGroupLeaderAA(uint32 gid)
|
||||
safe_delete_array(queryBuffer);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Raid::SaveRaidLeaderAA()
|
||||
@@ -285,7 +285,7 @@ void Raid::SaveRaidLeaderAA()
|
||||
safe_delete_array(queryBuffer);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Raid::UpdateGroupAAs(uint32 gid)
|
||||
@@ -489,7 +489,7 @@ void Raid::CastGroupSpell(Mob* caster, uint16 spellid, uint32 gid)
|
||||
else if(members[x].member != nullptr)
|
||||
{
|
||||
if(members[x].GroupNumber == gid){
|
||||
distance = caster->DistNoRoot(*members[x].member);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[x].member->GetPosition());
|
||||
if(distance <= range2){
|
||||
caster->SpellOnTarget(spellid, members[x].member);
|
||||
#ifdef GROUP_BUFF_PETS
|
||||
@@ -498,7 +498,7 @@ void Raid::CastGroupSpell(Mob* caster, uint16 spellid, uint32 gid)
|
||||
#endif
|
||||
}
|
||||
else{
|
||||
_log(SPELLS__CASTING, "Raid spell: %s is out of range %f at distance %f from %s", members[x].member->GetName(), range, distance, caster->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Raid spell: %s is out of range %f at distance %f from %s", members[x].member->GetName(), range, distance, caster->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -537,7 +537,7 @@ void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, float range)
|
||||
if(members[gi].member){
|
||||
if(members[gi].GroupNumber == gid)
|
||||
{
|
||||
distance = caster->DistNoRoot(*members[gi].member);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[gi].member->GetPosition());
|
||||
if(distance <= range2){
|
||||
numMem += 1;
|
||||
}
|
||||
@@ -551,7 +551,7 @@ void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, float range)
|
||||
if(members[gi].member){
|
||||
if(members[gi].GroupNumber == gid)
|
||||
{
|
||||
distance = caster->DistNoRoot(*members[gi].member);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[gi].member->GetPosition());
|
||||
if(distance <= range2){
|
||||
members[gi].member->SetHP(members[gi].member->GetHP() + heal_amt);
|
||||
members[gi].member->SendHPUpdate();
|
||||
@@ -581,7 +581,7 @@ void Raid::BalanceHP(int32 penalty, uint32 gid, float range, Mob* caster, int32
|
||||
if(members[gi].member){
|
||||
if(members[gi].GroupNumber == gid)
|
||||
{
|
||||
distance = caster->DistNoRoot(*members[gi].member);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[gi].member->GetPosition());
|
||||
if(distance <= range2){
|
||||
|
||||
dmgtaken_tmp = members[gi].member->GetMaxHP() - members[gi].member->GetHP();
|
||||
@@ -602,7 +602,7 @@ void Raid::BalanceHP(int32 penalty, uint32 gid, float range, Mob* caster, int32
|
||||
if(members[gi].member){
|
||||
if(members[gi].GroupNumber == gid)
|
||||
{
|
||||
distance = caster->DistNoRoot(*members[gi].member);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[gi].member->GetPosition());
|
||||
if(distance <= range2){
|
||||
if((members[gi].member->GetMaxHP() - dmgtaken) < 1){//this way the ability will never kill someone
|
||||
members[gi].member->SetHP(1); //but it will come darn close
|
||||
@@ -637,7 +637,7 @@ void Raid::BalanceMana(int32 penalty, uint32 gid, float range, Mob* caster, int3
|
||||
if(members[gi].GroupNumber == gid)
|
||||
{
|
||||
if (members[gi].member->GetMaxMana() > 0) {
|
||||
distance = caster->DistNoRoot(*members[gi].member);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[gi].member->GetPosition());
|
||||
if(distance <= range2){
|
||||
|
||||
manataken_tmp = members[gi].member->GetMaxMana() - members[gi].member->GetMana();
|
||||
@@ -660,7 +660,7 @@ void Raid::BalanceMana(int32 penalty, uint32 gid, float range, Mob* caster, int3
|
||||
if(members[gi].member){
|
||||
if(members[gi].GroupNumber == gid)
|
||||
{
|
||||
distance = caster->DistNoRoot(*members[gi].member);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[gi].member->GetPosition());
|
||||
if(distance <= range2){
|
||||
if((members[gi].member->GetMaxMana() - manataken) < 1){
|
||||
members[gi].member->SetMana(1);
|
||||
@@ -791,7 +791,7 @@ void Raid::GroupBardPulse(Mob* caster, uint16 spellid, uint32 gid){
|
||||
else if(members[z].member != nullptr)
|
||||
{
|
||||
if(members[z].GroupNumber == gid){
|
||||
distance = caster->DistNoRoot(*members[z].member);
|
||||
distance = DistanceSquared(caster->GetPosition(), members[z].member->GetPosition());
|
||||
if(distance <= range2) {
|
||||
members[z].member->BardPulse(spellid, caster);
|
||||
#ifdef GROUP_BUFF_PETS
|
||||
@@ -799,7 +799,7 @@ void Raid::GroupBardPulse(Mob* caster, uint16 spellid, uint32 gid){
|
||||
members[z].member->GetPet()->BardPulse(spellid, caster);
|
||||
#endif
|
||||
} else
|
||||
_log(SPELLS__BARDS, "Group bard pulse: %s is out of range %f at distance %f from %s", members[z].member->GetName(), range, distance, caster->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Group bard pulse: %s is out of range %f at distance %f from %s", members[z].member->GetName(), range, distance, caster->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1407,7 +1407,7 @@ void Raid::GetRaidDetails()
|
||||
return;
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
LogFile->write(EQEMuLog::Error, "Error getting raid details for raid %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Error getting raid details for raid %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1439,7 +1439,7 @@ bool Raid::LearnMembers()
|
||||
return false;
|
||||
|
||||
if(results.RowCount() == 0) {
|
||||
LogFile->write(EQEMuLog::Error, "Error getting raid members for raid %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Error getting raid members for raid %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
|
||||
disbandCheck = true;
|
||||
return false;
|
||||
}
|
||||
@@ -1529,7 +1529,7 @@ void Raid::SendHPPacketsTo(Client *c)
|
||||
{
|
||||
members[x].member->CreateHPPacket(&hpapp);
|
||||
c->QueuePacket(&hpapp, false);
|
||||
if(c->GetClientVersion() >= EQClientSoD)
|
||||
if(c->GetClientVersion() >= ClientVersion::SoD)
|
||||
{
|
||||
outapp.SetOpcode(OP_MobManaUpdate);
|
||||
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;
|
||||
@@ -1565,7 +1565,7 @@ void Raid::SendHPPacketsFrom(Mob *m)
|
||||
if(!m->IsClient() || ((members[x].member != m->CastToClient()) && (members[x].GroupNumber == gid)))
|
||||
{
|
||||
members[x].member->QueuePacket(&hpapp, false);
|
||||
if(members[x].member->GetClientVersion() >= EQClientSoD)
|
||||
if(members[x].member->GetClientVersion() >= ClientVersion::SoD)
|
||||
{
|
||||
outapp.SetOpcode(OP_MobManaUpdate);
|
||||
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;
|
||||
@@ -1643,7 +1643,7 @@ void Raid::SetGroupMentor(uint32 group_id, int percent, char *name)
|
||||
name, percent, group_id, GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to set raid group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to set raid group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Raid::ClearGroupMentor(uint32 group_id)
|
||||
@@ -1658,7 +1658,7 @@ void Raid::ClearGroupMentor(uint32 group_id)
|
||||
group_id, GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to clear raid group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to clear raid group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
// there isn't a nice place to add this in another function, unlike groups
|
||||
|
||||
+72
-87
@@ -16,7 +16,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/string_util.h"
|
||||
|
||||
#include "client.h"
|
||||
@@ -153,13 +153,13 @@ bool Spawn2::Process() {
|
||||
if (timer.Check()) {
|
||||
timer.Disable();
|
||||
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Timer has triggered", spawn2_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Timer has triggered", spawn2_id);
|
||||
|
||||
//first check our spawn condition, if this isnt active
|
||||
//then we reset the timer and try again next time.
|
||||
if(condition_id != SC_AlwaysEnabled
|
||||
&& !zone->spawn_conditions.Check(condition_id, condition_min_value)) {
|
||||
_log(SPAWNS__CONDITIONS, "Spawn2 %d: spawning prevented by spawn condition %d", spawn2_id, condition_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: spawning prevented by spawn condition %d", spawn2_id, condition_id);
|
||||
Reset();
|
||||
return(true);
|
||||
}
|
||||
@@ -170,14 +170,14 @@ bool Spawn2::Process() {
|
||||
}
|
||||
|
||||
if (sg == nullptr) {
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Unable to locate spawn group %d. Disabling.", spawn2_id, spawngroup_id_);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Unable to locate spawn group %d. Disabling.", spawn2_id, spawngroup_id_);
|
||||
return false;
|
||||
}
|
||||
|
||||
//have the spawn group pick an NPC for us
|
||||
uint32 npcid = sg->GetNPCType();
|
||||
if (npcid == 0) {
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Spawn group %d did not yeild an NPC! not spawning.", spawn2_id, spawngroup_id_);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d did not yeild an NPC! not spawning.", spawn2_id, spawngroup_id_);
|
||||
Reset(); //try again later (why?)
|
||||
return(true);
|
||||
}
|
||||
@@ -185,7 +185,7 @@ bool Spawn2::Process() {
|
||||
//try to find our NPC type.
|
||||
const NPCType* tmp = database.GetNPCType(npcid);
|
||||
if (tmp == nullptr) {
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Spawn group %d yeilded an invalid NPC type %d", spawn2_id, spawngroup_id_, npcid);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d yeilded an invalid NPC type %d", spawn2_id, spawngroup_id_, npcid);
|
||||
Reset(); //try again later
|
||||
return(true);
|
||||
}
|
||||
@@ -194,7 +194,7 @@ bool Spawn2::Process() {
|
||||
{
|
||||
if(!entity_list.LimitCheckName(tmp->name))
|
||||
{
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Spawn group %d yeilded NPC type %d, which is unique and one already exists.", spawn2_id, spawngroup_id_, npcid);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d yeilded NPC type %d, which is unique and one already exists.", spawn2_id, spawngroup_id_, npcid);
|
||||
timer.Start(5000); //try again in five seconds.
|
||||
return(true);
|
||||
}
|
||||
@@ -202,7 +202,7 @@ bool Spawn2::Process() {
|
||||
|
||||
if(tmp->spawn_limit > 0) {
|
||||
if(!entity_list.LimitCheckType(npcid, tmp->spawn_limit)) {
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Spawn group %d yeilded NPC type %d, which is over its spawn limit (%d)", spawn2_id, spawngroup_id_, npcid, tmp->spawn_limit);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d yeilded NPC type %d, which is over its spawn limit (%d)", spawn2_id, spawngroup_id_, npcid, tmp->spawn_limit);
|
||||
timer.Start(5000); //try again in five seconds.
|
||||
return(true);
|
||||
}
|
||||
@@ -218,7 +218,7 @@ bool Spawn2::Process() {
|
||||
database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0);
|
||||
|
||||
currentnpcid = npcid;
|
||||
NPC* npc = new NPC(tmp, this, x, y, z, heading, FlyMode3);
|
||||
NPC* npc = new NPC(tmp, this, glm::vec4(x, y, z, heading), FlyMode3);
|
||||
|
||||
npc->mod_prespawn(this);
|
||||
|
||||
@@ -233,10 +233,10 @@ bool Spawn2::Process() {
|
||||
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);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Group %d spawned %s (%d) at (%.3f, %.3f, %.3f).", spawn2_id, spawngroup_id_, npc->GetName(), npcid, x, y, z);
|
||||
LoadGrid();
|
||||
} else {
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Group %d spawned %s (%d) at (%.3f, %.3f, %.3f). Grid loading delayed.", spawn2_id, spawngroup_id_, tmp->name, npcid, x, y, z);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Group %d spawned %s (%d) at (%.3f, %.3f, %.3f). Grid loading delayed.", spawn2_id, spawngroup_id_, tmp->name, npcid, x, y, z);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -261,7 +261,7 @@ void Spawn2::LoadGrid() {
|
||||
//dont set an NPC's grid until its loaded for them.
|
||||
npcthis->SetGrid(grid_);
|
||||
npcthis->AssignWaypoints(grid_);
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Loading grid %d for %s", spawn2_id, grid_, npcthis->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Loading grid %d for %s", spawn2_id, grid_, npcthis->GetName());
|
||||
}
|
||||
|
||||
|
||||
@@ -272,21 +272,21 @@ void Spawn2::LoadGrid() {
|
||||
void Spawn2::Reset() {
|
||||
timer.Start(resetTimer());
|
||||
npcthis = nullptr;
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Spawn reset, repop in %d ms", spawn2_id, timer.GetRemainingTime());
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn reset, repop in %d ms", spawn2_id, timer.GetRemainingTime());
|
||||
}
|
||||
|
||||
void Spawn2::Depop() {
|
||||
timer.Disable();
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Spawn reset, repop disabled", spawn2_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn reset, repop disabled", spawn2_id);
|
||||
npcthis = nullptr;
|
||||
}
|
||||
|
||||
void Spawn2::Repop(uint32 delay) {
|
||||
if (delay == 0) {
|
||||
timer.Trigger();
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Spawn reset, repop immediately.", spawn2_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn reset, repop immediately.", spawn2_id);
|
||||
} else {
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Spawn reset for repop, repop in %d ms", spawn2_id, delay);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn reset for repop, repop in %d ms", spawn2_id, delay);
|
||||
timer.Start(delay);
|
||||
}
|
||||
npcthis = nullptr;
|
||||
@@ -328,7 +328,7 @@ void Spawn2::ForceDespawn()
|
||||
cur = despawnTimer(dtimer);
|
||||
}
|
||||
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Spawn group %d set despawn timer to %d ms.", spawn2_id, spawngroup_id_, cur);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d set despawn timer to %d ms.", spawn2_id, spawngroup_id_, cur);
|
||||
timer.Start(cur);
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ void Spawn2::DeathReset(bool realdeath)
|
||||
if(spawn2_id)
|
||||
{
|
||||
database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), (cur/1000));
|
||||
_log(SPAWNS__MAIN, "Spawn2 %d: Spawn reset by death, repop in %d ms", spawn2_id, timer.GetRemainingTime());
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn reset by death, repop in %d ms", spawn2_id, timer.GetRemainingTime());
|
||||
//store it to database too
|
||||
}
|
||||
}
|
||||
@@ -364,7 +364,6 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spa
|
||||
zone_name, version);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in PopulateZoneLists query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -392,12 +391,10 @@ Spawn2* ZoneDatabase::LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2
|
||||
"WHERE id = %i", spawn2id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (results.RowCount() != 1) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -414,17 +411,16 @@ Spawn2* ZoneDatabase::LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2
|
||||
return newSpawn;
|
||||
}
|
||||
|
||||
bool ZoneDatabase::CreateSpawn2(Client *client, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value)
|
||||
bool ZoneDatabase::CreateSpawn2(Client *client, uint32 spawngroup, const char* zone, const glm::vec4& position, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value)
|
||||
{
|
||||
|
||||
std::string query = StringFormat("INSERT INTO spawn2 (spawngroupID, zone, x, y, z, heading, "
|
||||
"respawntime, variance, _condition, cond_value) "
|
||||
"VALUES (%i, '%s', %f, %f, %f, %f, %i, %i, %u, %i)",
|
||||
spawngroup, zone, x, y, z, heading,
|
||||
spawngroup, zone, position.x, position.y, position.z, position.w,
|
||||
respawn, variance, condition, cond_value);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in CreateSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -432,7 +428,6 @@ bool ZoneDatabase::CreateSpawn2(Client *client, uint32 spawngroup, const char* z
|
||||
return false;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -466,12 +461,12 @@ void Spawn2::SpawnConditionChanged(const SpawnCondition &c, int16 old_value) {
|
||||
if(GetSpawnCondition() != c.condition_id)
|
||||
return;
|
||||
|
||||
_log(SPAWNS__CONDITIONS, "Spawn2 %d: Notified that our spawn condition %d has changed from %d to %d. Our min value is %d.", spawn2_id, c.condition_id, old_value, c.value, condition_min_value);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Notified that our spawn condition %d has changed from %d to %d. Our min value is %d.", spawn2_id, c.condition_id, old_value, c.value, condition_min_value);
|
||||
|
||||
bool old_state = (old_value >= condition_min_value);
|
||||
bool new_state = (c.value >= condition_min_value);
|
||||
if(old_state == new_state) {
|
||||
_log(SPAWNS__CONDITIONS, "Spawn2 %d: Our threshold for this condition was not crossed. Doing nothing.", spawn2_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Our threshold for this condition was not crossed. Doing nothing.", spawn2_id);
|
||||
return; //no change
|
||||
}
|
||||
|
||||
@@ -479,50 +474,50 @@ void Spawn2::SpawnConditionChanged(const SpawnCondition &c, int16 old_value) {
|
||||
switch(c.on_change) {
|
||||
case SpawnCondition::DoNothing:
|
||||
//that was easy.
|
||||
_log(SPAWNS__CONDITIONS, "Spawn2 %d: Our condition is now %s. Taking no action on existing spawn.", spawn2_id, new_state?"enabled":"disabled");
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Our condition is now %s. Taking no action on existing spawn.", spawn2_id, new_state?"enabled":"disabled");
|
||||
break;
|
||||
case SpawnCondition::DoDepop:
|
||||
_log(SPAWNS__CONDITIONS, "Spawn2 %d: Our condition is now %s. Depoping our mob.", spawn2_id, new_state?"enabled":"disabled");
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Our condition is now %s. Depoping our mob.", spawn2_id, new_state?"enabled":"disabled");
|
||||
if(npcthis != nullptr)
|
||||
npcthis->Depop(false); //remove the current mob
|
||||
Reset(); //reset our spawn timer
|
||||
break;
|
||||
case SpawnCondition::DoRepop:
|
||||
_log(SPAWNS__CONDITIONS, "Spawn2 %d: Our condition is now %s. Forcing a repop.", spawn2_id, new_state?"enabled":"disabled");
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Our condition is now %s. Forcing a repop.", spawn2_id, new_state?"enabled":"disabled");
|
||||
if(npcthis != nullptr)
|
||||
npcthis->Depop(false); //remove the current mob
|
||||
Repop(); //repop
|
||||
break;
|
||||
case SpawnCondition::DoRepopIfReady:
|
||||
_log(SPAWNS__CONDITIONS, "Spawn2 %d: Our condition is now %s. Forcing a repop if repsawn timer is expired.", spawn2_id, new_state?"enabled":"disabled");
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Our condition is now %s. Forcing a repop if repsawn timer is expired.", spawn2_id, new_state?"enabled":"disabled");
|
||||
if(npcthis != nullptr) {
|
||||
_log(SPAWNS__CONDITIONS, "Spawn2 %d: Our npcthis is currently not null. The zone thinks it is %s. Forcing a depop.", spawn2_id, npcthis->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Our npcthis is currently not null. The zone thinks it is %s. Forcing a depop.", spawn2_id, npcthis->GetName());
|
||||
npcthis->Depop(false); //remove the current mob
|
||||
npcthis = nullptr;
|
||||
}
|
||||
if(new_state) { // only get repawn timer remaining when the SpawnCondition is enabled.
|
||||
timer_remaining = database.GetSpawnTimeLeft(spawn2_id,zone->GetInstanceID());
|
||||
_log(SPAWNS__CONDITIONS,"Spawn2 %d: Our condition is now %s. The respawn timer_remaining is %d. Forcing a repop if it is <= 0.", spawn2_id, new_state?"enabled":"disabled", timer_remaining);
|
||||
Log.Out(Logs::Detail, Logs::Spawns,"Spawn2 %d: Our condition is now %s. The respawn timer_remaining is %d. Forcing a repop if it is <= 0.", spawn2_id, new_state?"enabled":"disabled", timer_remaining);
|
||||
if(timer_remaining <= 0)
|
||||
Repop();
|
||||
} else {
|
||||
_log(SPAWNS__CONDITIONS,"Spawn2 %d: Our condition is now %s. Not checking respawn timer.", spawn2_id, new_state?"enabled":"disabled");
|
||||
Log.Out(Logs::Detail, Logs::Spawns,"Spawn2 %d: Our condition is now %s. Not checking respawn timer.", spawn2_id, new_state?"enabled":"disabled");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(c.on_change < SpawnCondition::DoSignalMin) {
|
||||
_log(SPAWNS__CONDITIONS, "Spawn2 %d: Our condition is now %s. Invalid on-change action %d.", spawn2_id, new_state?"enabled":"disabled", c.on_change);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Our condition is now %s. Invalid on-change action %d.", spawn2_id, new_state?"enabled":"disabled", c.on_change);
|
||||
return; //unknown onchange action
|
||||
}
|
||||
int signal_id = c.on_change - SpawnCondition::DoSignalMin;
|
||||
_log(SPAWNS__CONDITIONS, "Spawn2 %d: Our condition is now %s. Signaling our mob with %d.", spawn2_id, new_state?"enabled":"disabled", signal_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Our condition is now %s. Signaling our mob with %d.", spawn2_id, new_state?"enabled":"disabled", signal_id);
|
||||
if(npcthis != nullptr)
|
||||
npcthis->SignalNPC(signal_id);
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::SpawnConditionChanged(const SpawnCondition &c, int16 old_value) {
|
||||
_log(SPAWNS__CONDITIONS, "Zone notified that spawn condition %d has changed from %d to %d. Notifying all spawn points.", c.condition_id, old_value, c.value);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Zone notified that spawn condition %d has changed from %d to %d. Notifying all spawn points.", c.condition_id, old_value, c.value);
|
||||
|
||||
LinkedListIterator<Spawn2*> iterator(spawn2_list);
|
||||
|
||||
@@ -592,7 +587,7 @@ void SpawnConditionManager::Process() {
|
||||
EQTime::AddMinutes(cevent.period, &cevent.next);
|
||||
std::string t;
|
||||
EQTime::ToString(&cevent.next, t);
|
||||
_log(SPAWNS__CONDITIONS, "Event %d: Will trigger again in %d EQ minutes at %s.", cevent.id, cevent.period, t.c_str());
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Event %d: Will trigger again in %d EQ minutes at %s.", cevent.id, cevent.period, t.c_str());
|
||||
//save the next event time in the DB
|
||||
UpdateDBEvent(cevent);
|
||||
//find the next closest event timer.
|
||||
@@ -611,7 +606,7 @@ void SpawnConditionManager::ExecEvent(SpawnEvent &event, bool send_update) {
|
||||
std::map<uint16, SpawnCondition>::iterator condi;
|
||||
condi = spawn_conditions.find(event.condition_id);
|
||||
if(condi == spawn_conditions.end()) {
|
||||
_log(SPAWNS__CONDITIONS, "Event %d: Unable to find condition %d to execute on.", event.id, event.condition_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Event %d: Unable to find condition %d to execute on.", event.id, event.condition_id);
|
||||
return; //unable to find the spawn condition to operate on
|
||||
}
|
||||
|
||||
@@ -619,7 +614,7 @@ void SpawnConditionManager::ExecEvent(SpawnEvent &event, bool send_update) {
|
||||
zone->zone_time.getEQTimeOfDay(&tod);
|
||||
if(event.strict && (event.next.hour != tod.hour || event.next.day != tod.day || event.next.month != tod.month || event.next.year != tod.year))
|
||||
{
|
||||
_log(SPAWNS__CONDITIONS, "Event %d: Unable to execute. Condition is strict, and event time has already passed.", event.id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Event %d: Unable to execute. Condition is strict, and event time has already passed.", event.id);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -631,26 +626,26 @@ void SpawnConditionManager::ExecEvent(SpawnEvent &event, bool send_update) {
|
||||
switch(event.action) {
|
||||
case SpawnEvent::ActionSet:
|
||||
new_value = event.argument;
|
||||
_log(SPAWNS__CONDITIONS, "Event %d: Executing. Setting condition %d to %d.", event.id, event.condition_id, event.argument);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Event %d: Executing. Setting condition %d to %d.", event.id, event.condition_id, event.argument);
|
||||
break;
|
||||
case SpawnEvent::ActionAdd:
|
||||
new_value += event.argument;
|
||||
_log(SPAWNS__CONDITIONS, "Event %d: Executing. Adding %d to condition %d, yeilding %d.", event.id, event.argument, event.condition_id, new_value);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Event %d: Executing. Adding %d to condition %d, yeilding %d.", event.id, event.argument, event.condition_id, new_value);
|
||||
break;
|
||||
case SpawnEvent::ActionSubtract:
|
||||
new_value -= event.argument;
|
||||
_log(SPAWNS__CONDITIONS, "Event %d: Executing. Subtracting %d from condition %d, yeilding %d.", event.id, event.argument, event.condition_id, new_value);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Event %d: Executing. Subtracting %d from condition %d, yeilding %d.", event.id, event.argument, event.condition_id, new_value);
|
||||
break;
|
||||
case SpawnEvent::ActionMultiply:
|
||||
new_value *= event.argument;
|
||||
_log(SPAWNS__CONDITIONS, "Event %d: Executing. Multiplying condition %d by %d, yeilding %d.", event.id, event.condition_id, event.argument, new_value);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Event %d: Executing. Multiplying condition %d by %d, yeilding %d.", event.id, event.condition_id, event.argument, new_value);
|
||||
break;
|
||||
case SpawnEvent::ActionDivide:
|
||||
new_value /= event.argument;
|
||||
_log(SPAWNS__CONDITIONS, "Event %d: Executing. Dividing condition %d by %d, yeilding %d.", event.id, event.condition_id, event.argument, new_value);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Event %d: Executing. Dividing condition %d by %d, yeilding %d.", event.id, event.condition_id, event.argument, new_value);
|
||||
break;
|
||||
default:
|
||||
_log(SPAWNS__CONDITIONS, "Event %d: Invalid event action type %d", event.id, event.action);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Event %d: Invalid event action type %d", event.id, event.action);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -672,10 +667,7 @@ void SpawnConditionManager::UpdateDBEvent(SpawnEvent &event) {
|
||||
event.next.day, event.next.month,
|
||||
event.next.year, event.enabled? 1: 0,
|
||||
event.strict? 1: 0, event.id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to update spawn event '%s': %s\n", query.c_str(), results.ErrorMessage().c_str());
|
||||
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
|
||||
void SpawnConditionManager::UpdateDBCondition(const char* zone_name, uint32 instance_id, uint16 cond_id, int16 value) {
|
||||
@@ -684,10 +676,7 @@ void SpawnConditionManager::UpdateDBCondition(const char* zone_name, uint32 inst
|
||||
"(id, value, zone, instance_id) "
|
||||
"VALUES( %u, %u, '%s', %u)",
|
||||
cond_id, value, zone_name, instance_id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to update spawn condition '%s': %s\n", query.c_str(), results.ErrorMessage().c_str());
|
||||
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
|
||||
bool SpawnConditionManager::LoadDBEvent(uint32 event_id, SpawnEvent &event, std::string &zone_name) {
|
||||
@@ -699,7 +688,6 @@ bool SpawnConditionManager::LoadDBEvent(uint32 event_id, SpawnEvent &event, std:
|
||||
"FROM spawn_events WHERE id = %d", event_id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadDBEvent query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -727,7 +715,7 @@ bool SpawnConditionManager::LoadDBEvent(uint32 event_id, SpawnEvent &event, std:
|
||||
std::string timeAsString;
|
||||
EQTime::ToString(&event.next, timeAsString);
|
||||
|
||||
_log(SPAWNS__CONDITIONS, "(LoadDBEvent) Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d, strict %d. Will trigger at %s", event.enabled? "enabled": "disabled", event.id, event.condition_id, event.period, event.action, event.argument, event.strict, timeAsString.c_str());
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "(LoadDBEvent) Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d, strict %d. Will trigger at %s", event.enabled? "enabled": "disabled", event.id, event.condition_id, event.period, event.action, event.argument, event.strict, timeAsString.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -742,7 +730,6 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
|
||||
"WHERE zone = '%s'", zone_name);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -755,7 +742,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
|
||||
cond.on_change = (SpawnCondition::OnChange) atoi(row[1]);
|
||||
spawn_conditions[cond.condition_id] = cond;
|
||||
|
||||
_log(SPAWNS__CONDITIONS, "Loaded spawn condition %d with value %d and on_change %d", cond.condition_id, cond.value, cond.on_change);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Loaded spawn condition %d with value %d and on_change %d", cond.condition_id, cond.value, cond.on_change);
|
||||
}
|
||||
|
||||
//load values
|
||||
@@ -764,7 +751,6 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
|
||||
zone_name, instance_id);
|
||||
results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
spawn_conditions.clear();
|
||||
return false;
|
||||
}
|
||||
@@ -782,7 +768,6 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
|
||||
"FROM spawn_events WHERE zone = '%s'", zone_name);
|
||||
results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions events query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -794,7 +779,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
|
||||
event.period = atoi(row[2]);
|
||||
|
||||
if(event.period == 0) {
|
||||
LogFile->write(EQEMuLog::Error, "Refusing to load spawn event #%d because it has a period of 0\n", event.id);
|
||||
Log.Out(Logs::General, Logs::Error, "Refusing to load spawn event #%d because it has a period of 0\n", event.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -811,7 +796,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
|
||||
|
||||
spawn_events.push_back(event);
|
||||
|
||||
_log(SPAWNS__CONDITIONS, "(LoadSpawnConditions) Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d, strict %d", event.enabled? "enabled": "disabled", event.id, event.condition_id, event.period, event.action, event.argument, event.strict);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "(LoadSpawnConditions) Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d, strict %d", event.enabled? "enabled": "disabled", event.id, event.condition_id, event.period, event.action, event.argument, event.strict);
|
||||
}
|
||||
|
||||
//now we need to catch up on events that happened while we were away
|
||||
@@ -846,7 +831,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
|
||||
|
||||
//watch for special case of all 0s, which means to reset next to now
|
||||
if(cevent.next.year == 0 && cevent.next.month == 0 && cevent.next.day == 0 && cevent.next.hour == 0 && cevent.next.minute == 0) {
|
||||
_log(SPAWNS__CONDITIONS, "Initial next trigger time set for spawn event %d", cevent.id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Initial next trigger time set for spawn event %d", cevent.id);
|
||||
memcpy(&cevent.next, &tod, sizeof(cevent.next));
|
||||
//add one period
|
||||
EQTime::AddMinutes(cevent.period, &cevent.next);
|
||||
@@ -857,7 +842,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
|
||||
|
||||
bool ran = false;
|
||||
while(EQTime::IsTimeBefore(&tod, &cevent.next)) {
|
||||
_log(SPAWNS__CONDITIONS, "Catch up triggering on event %d", cevent.id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Catch up triggering on event %d", cevent.id);
|
||||
//this event has been triggered.
|
||||
//execute the event
|
||||
if(!cevent.strict || StrictCheck)
|
||||
@@ -900,9 +885,9 @@ void SpawnConditionManager::FindNearestEvent() {
|
||||
}
|
||||
}
|
||||
if(next_id == -1)
|
||||
_log(SPAWNS__CONDITIONS, "No spawn events enabled. Disabling next event.");
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "No spawn events enabled. Disabling next event.");
|
||||
else
|
||||
_log(SPAWNS__CONDITIONS, "Next event determined to be event %d", next_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Next event determined to be event %d", next_id);
|
||||
}
|
||||
|
||||
void SpawnConditionManager::SetCondition(const char *zone_short, uint32 instance_id, uint16 condition_id, int16 new_value, bool world_update)
|
||||
@@ -914,14 +899,14 @@ void SpawnConditionManager::SetCondition(const char *zone_short, uint32 instance
|
||||
std::map<uint16, SpawnCondition>::iterator condi;
|
||||
condi = spawn_conditions.find(condition_id);
|
||||
if(condi == spawn_conditions.end()) {
|
||||
_log(SPAWNS__CONDITIONS, "Condition update received from world for %d, but we do not have that conditon.", condition_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Condition update received from world for %d, but we do not have that conditon.", condition_id);
|
||||
return; //unable to find the spawn condition
|
||||
}
|
||||
|
||||
SpawnCondition &cond = condi->second;
|
||||
|
||||
if(cond.value == new_value) {
|
||||
_log(SPAWNS__CONDITIONS, "Condition update received from world for %d with value %d, which is what we already have.", condition_id, new_value);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Condition update received from world for %d with value %d, which is what we already have.", condition_id, new_value);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -930,7 +915,7 @@ void SpawnConditionManager::SetCondition(const char *zone_short, uint32 instance
|
||||
//set our local value
|
||||
cond.value = new_value;
|
||||
|
||||
_log(SPAWNS__CONDITIONS, "Condition update received from world for %d with value %d", condition_id, new_value);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Condition update received from world for %d with value %d", condition_id, new_value);
|
||||
|
||||
//now we have to test each spawn point to see if it changed.
|
||||
zone->SpawnConditionChanged(cond, old_value);
|
||||
@@ -941,14 +926,14 @@ void SpawnConditionManager::SetCondition(const char *zone_short, uint32 instance
|
||||
std::map<uint16, SpawnCondition>::iterator condi;
|
||||
condi = spawn_conditions.find(condition_id);
|
||||
if(condi == spawn_conditions.end()) {
|
||||
_log(SPAWNS__CONDITIONS, "Local Condition update requested for %d, but we do not have that conditon.", condition_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Local Condition update requested for %d, but we do not have that conditon.", condition_id);
|
||||
return; //unable to find the spawn condition
|
||||
}
|
||||
|
||||
SpawnCondition &cond = condi->second;
|
||||
|
||||
if(cond.value == new_value) {
|
||||
_log(SPAWNS__CONDITIONS, "Local Condition update requested for %d with value %d, which is what we already have.", condition_id, new_value);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Local Condition update requested for %d with value %d, which is what we already have.", condition_id, new_value);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -959,7 +944,7 @@ void SpawnConditionManager::SetCondition(const char *zone_short, uint32 instance
|
||||
//save it in the DB too
|
||||
UpdateDBCondition(zone_short, instance_id, condition_id, new_value);
|
||||
|
||||
_log(SPAWNS__CONDITIONS, "Local Condition update requested for %d with value %d", condition_id, new_value);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Local Condition update requested for %d with value %d", condition_id, new_value);
|
||||
|
||||
//now we have to test each spawn point to see if it changed.
|
||||
zone->SpawnConditionChanged(cond, old_value);
|
||||
@@ -969,7 +954,7 @@ void SpawnConditionManager::SetCondition(const char *zone_short, uint32 instance
|
||||
//this is a remote spawn condition, update the DB and send
|
||||
//an update packet to the zone if its up
|
||||
|
||||
_log(SPAWNS__CONDITIONS, "Remote spawn condition %d set to %d. Updating DB and notifying world.", condition_id, new_value);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Remote spawn condition %d set to %d. Updating DB and notifying world.", condition_id, new_value);
|
||||
|
||||
UpdateDBCondition(zone_short, instance_id, condition_id, new_value);
|
||||
|
||||
@@ -989,7 +974,7 @@ void SpawnConditionManager::SetCondition(const char *zone_short, uint32 instance
|
||||
void SpawnConditionManager::ReloadEvent(uint32 event_id) {
|
||||
std::string zone_short_name;
|
||||
|
||||
_log(SPAWNS__CONDITIONS, "Requested to reload event %d from the database.", event_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Requested to reload event %d from the database.", event_id);
|
||||
|
||||
//first look for the event in our local event list
|
||||
std::vector<SpawnEvent>::iterator cur,end;
|
||||
@@ -1002,7 +987,7 @@ void SpawnConditionManager::ReloadEvent(uint32 event_id) {
|
||||
//load the event into the old event slot
|
||||
if(!LoadDBEvent(event_id, cevent, zone_short_name)) {
|
||||
//unable to find the event in the database...
|
||||
_log(SPAWNS__CONDITIONS, "Failed to reload event %d from the database.", event_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Failed to reload event %d from the database.", event_id);
|
||||
return;
|
||||
}
|
||||
//sync up our nearest event
|
||||
@@ -1015,7 +1000,7 @@ void SpawnConditionManager::ReloadEvent(uint32 event_id) {
|
||||
SpawnEvent e;
|
||||
if(!LoadDBEvent(event_id, e, zone_short_name)) {
|
||||
//unable to find the event in the database...
|
||||
_log(SPAWNS__CONDITIONS, "Failed to reload event %d from the database.", event_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Failed to reload event %d from the database.", event_id);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1032,7 +1017,7 @@ void SpawnConditionManager::ReloadEvent(uint32 event_id) {
|
||||
|
||||
void SpawnConditionManager::ToggleEvent(uint32 event_id, bool enabled, bool strict, bool reset_base) {
|
||||
|
||||
_log(SPAWNS__CONDITIONS, "Request to %s spawn event %d %sresetting trigger time", enabled?"enable":"disable", event_id, reset_base?"":"without ");
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Request to %s spawn event %d %sresetting trigger time", enabled?"enable":"disable", event_id, reset_base?"":"without ");
|
||||
|
||||
//first look for the event in our local event list
|
||||
std::vector<SpawnEvent>::iterator cur,end;
|
||||
@@ -1047,13 +1032,13 @@ void SpawnConditionManager::ToggleEvent(uint32 event_id, bool enabled, bool stri
|
||||
cevent.enabled = enabled;
|
||||
cevent.strict = strict;
|
||||
if(reset_base) {
|
||||
_log(SPAWNS__CONDITIONS, "Spawn event %d located in this zone. State set. Trigger time reset (period %d).", event_id, cevent.period);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn event %d located in this zone. State set. Trigger time reset (period %d).", event_id, cevent.period);
|
||||
//start with the time now
|
||||
zone->zone_time.getEQTimeOfDay(&cevent.next);
|
||||
//advance the next time by our period
|
||||
EQTime::AddMinutes(cevent.period, &cevent.next);
|
||||
} else {
|
||||
_log(SPAWNS__CONDITIONS, "Spawn event %d located in this zone. State changed.", event_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn event %d located in this zone. State changed.", event_id);
|
||||
}
|
||||
|
||||
//save the event in the DB
|
||||
@@ -1062,7 +1047,7 @@ void SpawnConditionManager::ToggleEvent(uint32 event_id, bool enabled, bool stri
|
||||
//sync up our nearest event
|
||||
FindNearestEvent();
|
||||
} else {
|
||||
_log(SPAWNS__CONDITIONS, "Spawn event %d located in this zone but no change was needed.", event_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn event %d located in this zone but no change was needed.", event_id);
|
||||
}
|
||||
//even if we dont change anything, we still found it
|
||||
return;
|
||||
@@ -1081,24 +1066,24 @@ void SpawnConditionManager::ToggleEvent(uint32 event_id, bool enabled, bool stri
|
||||
SpawnEvent e;
|
||||
std::string zone_short_name;
|
||||
if(!LoadDBEvent(event_id, e, zone_short_name)) {
|
||||
_log(SPAWNS__CONDITIONS, "Unable to find spawn event %d in the database.", event_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Unable to find spawn event %d in the database.", event_id);
|
||||
//unable to find the event in the database...
|
||||
return;
|
||||
}
|
||||
if(e.enabled == enabled && !reset_base) {
|
||||
_log(SPAWNS__CONDITIONS, "Spawn event %d is not located in this zone but no change was needed.", event_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn event %d is not located in this zone but no change was needed.", event_id);
|
||||
return; //no changes.
|
||||
}
|
||||
|
||||
e.enabled = enabled;
|
||||
if(reset_base) {
|
||||
_log(SPAWNS__CONDITIONS, "Spawn event %d is in zone %s. State set. Trigger time reset (period %d). Notifying world.", event_id, zone_short_name.c_str(), e.period);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn event %d is in zone %s. State set. Trigger time reset (period %d). Notifying world.", event_id, zone_short_name.c_str(), e.period);
|
||||
//start with the time now
|
||||
zone->zone_time.getEQTimeOfDay(&e.next);
|
||||
//advance the next time by our period
|
||||
EQTime::AddMinutes(e.period, &e.next);
|
||||
} else {
|
||||
_log(SPAWNS__CONDITIONS, "Spawn event %d is in zone %s. State changed. Notifying world.", event_id, zone_short_name.c_str(), e.period);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn event %d is in zone %s. State changed. Notifying world.", event_id, zone_short_name.c_str(), e.period);
|
||||
}
|
||||
//save the event in the DB
|
||||
UpdateDBEvent(e);
|
||||
@@ -1123,7 +1108,7 @@ int16 SpawnConditionManager::GetCondition(const char *zone_short, uint32 instanc
|
||||
condi = spawn_conditions.find(condition_id);
|
||||
if(condi == spawn_conditions.end())
|
||||
{
|
||||
_log(SPAWNS__CONDITIONS, "Unable to find local condition %d in Get request.", condition_id);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Unable to find local condition %d in Get request.", condition_id);
|
||||
return(0); //unable to find the spawn condition
|
||||
}
|
||||
|
||||
@@ -1138,12 +1123,12 @@ int16 SpawnConditionManager::GetCondition(const char *zone_short, uint32 instanc
|
||||
zone_short, instance_id, condition_id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
_log(SPAWNS__CONDITIONS, "Unable to query remote condition %d from zone %s in Get request.", condition_id, zone_short);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Unable to query remote condition %d from zone %s in Get request.", condition_id, zone_short);
|
||||
return 0; //dunno a better thing to do...
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
_log(SPAWNS__CONDITIONS, "Unable to load remote condition %d from zone %s in Get request.", condition_id, zone_short);
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Unable to load remote condition %d from zone %s in Get request.", condition_id, zone_short);
|
||||
return 0; //dunno a better thing to do...
|
||||
}
|
||||
|
||||
|
||||
+5
-8
@@ -16,7 +16,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/types.h"
|
||||
|
||||
@@ -51,7 +51,7 @@ SpawnGroup::SpawnGroup( uint32 in_id, char* name, int in_group_spawn_limit, floa
|
||||
|
||||
uint32 SpawnGroup::GetNPCType() {
|
||||
#if EQDEBUG >= 10
|
||||
LogFile->write(EQEMuLog::Debug, "SpawnGroup[%08x]::GetNPCType()", (uint32) this);
|
||||
Log.Out(Logs::General, Logs::None, "SpawnGroup[%08x]::GetNPCType()", (uint32) this);
|
||||
#endif
|
||||
int npcType = 0;
|
||||
int totalchance = 0;
|
||||
@@ -149,7 +149,6 @@ bool ZoneDatabase::LoadSpawnGroups(const char* zone_name, uint16 version, SpawnG
|
||||
"AND spawn2.version = %u and zone = '%s'", version, zone_name);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
_log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query '%s' ", query.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -168,7 +167,7 @@ bool ZoneDatabase::LoadSpawnGroups(const char* zone_name, uint16 version, SpawnG
|
||||
"AND zone = '%s'", zone_name);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
_log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query '%'", query.c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Error2 in PopulateZoneLists query '%'", query.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -177,7 +176,6 @@ bool ZoneDatabase::LoadSpawnGroups(const char* zone_name, uint16 version, SpawnG
|
||||
SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
||||
|
||||
if (!sg) {
|
||||
_log(ZONE__SPAWNS, "Error in LoadSpawnGroups %s ", query.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -197,7 +195,7 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_g
|
||||
"FROM spawngroup WHERE spawngroup.ID = '%i'", spawngroupid);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
_log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query %s", query.c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Error2 in PopulateZoneLists query %s", query.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -212,7 +210,7 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_g
|
||||
"ORDER BY chance", spawngroupid);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
_log(ZONE__SPAWNS, "Error3 in PopulateZoneLists query '%s'", query.c_str());
|
||||
Log.Out(Logs::General, Logs::Error, "Error3 in PopulateZoneLists query '%s'", query.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -220,7 +218,6 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_g
|
||||
SpawnEntry* newSpawnEntry = new SpawnEntry( atoi(row[1]), atoi(row[2]), row[3]?atoi(row[3]):0);
|
||||
SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
||||
if (!sg) {
|
||||
_log(ZONE__SPAWNS, "Error in SpawngroupID: %s ", row[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
+45
-39
@@ -464,7 +464,7 @@ int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
mlog(CLIENT__ERROR, "Invalid special attack type %d attempted", unchecked_type);
|
||||
Log.Out(Logs::Detail, Logs::Attack, "Invalid special attack type %d attempted", unchecked_type);
|
||||
return(1000); /* nice long delay for them, the caller depends on this! */
|
||||
}
|
||||
|
||||
@@ -663,7 +663,7 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
|
||||
DoAnim(animPiercing);
|
||||
}
|
||||
|
||||
// solar - assassinate [Kayen: No longer used for regular assassinate 6-29-14]
|
||||
// assassinate [No longer used for regular assassinate 6-29-14]
|
||||
void Mob::RogueAssassinate(Mob* other)
|
||||
{
|
||||
//can you dodge, parry, etc.. an assassinate??
|
||||
@@ -683,7 +683,7 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
||||
//make sure the attack and ranged timers are up
|
||||
//if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow
|
||||
if(!CanDoubleAttack && ((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check()))) {
|
||||
mlog(COMBAT__RANGED, "Throwing attack canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Throwing attack canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||
// The server and client timers are not exact matches currently, so this would spam too often if enabled
|
||||
//Message(0, "Error: Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||
return;
|
||||
@@ -695,12 +695,12 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
||||
const ItemInst* Ammo = m_inv[MainAmmo];
|
||||
|
||||
if (!RangeWeapon || !RangeWeapon->IsType(ItemClassCommon)) {
|
||||
mlog(COMBAT__RANGED, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(MainRange), MainRange);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(MainRange), MainRange);
|
||||
Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have no bow!", GetItemIDAt(MainRange));
|
||||
return;
|
||||
}
|
||||
if (!Ammo || !Ammo->IsType(ItemClassCommon)) {
|
||||
mlog(COMBAT__RANGED, "Ranged attack canceled. Missing or invalid ammo item (%d) in slot %d", GetItemIDAt(MainAmmo), MainAmmo);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack canceled. Missing or invalid ammo item (%d) in slot %d", GetItemIDAt(MainAmmo), MainAmmo);
|
||||
Message(0, "Error: Ammo: GetItem(%i)==0, you have no ammo!", GetItemIDAt(MainAmmo));
|
||||
return;
|
||||
}
|
||||
@@ -709,17 +709,17 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
||||
const Item_Struct* AmmoItem = Ammo->GetItem();
|
||||
|
||||
if(RangeItem->ItemType != ItemTypeBow) {
|
||||
mlog(COMBAT__RANGED, "Ranged attack canceled. Ranged item is not a bow. type %d.", RangeItem->ItemType);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack canceled. Ranged item is not a bow. type %d.", RangeItem->ItemType);
|
||||
Message(0, "Error: Rangeweapon: Item %d is not a bow.", RangeWeapon->GetID());
|
||||
return;
|
||||
}
|
||||
if(AmmoItem->ItemType != ItemTypeArrow) {
|
||||
mlog(COMBAT__RANGED, "Ranged attack canceled. Ammo item is not an arrow. type %d.", AmmoItem->ItemType);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack canceled. Ammo item is not an arrow. type %d.", AmmoItem->ItemType);
|
||||
Message(0, "Error: Ammo: type %d != %d, you have the wrong type of ammo!", AmmoItem->ItemType, ItemTypeArrow);
|
||||
return;
|
||||
}
|
||||
|
||||
mlog(COMBAT__RANGED, "Shooting %s with bow %s (%d) and arrow %s (%d)", other->GetName(), RangeItem->Name, RangeItem->ID, AmmoItem->Name, AmmoItem->ID);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Shooting %s with bow %s (%d) and arrow %s (%d)", other->GetName(), RangeItem->Name, RangeItem->ID, AmmoItem->Name, AmmoItem->ID);
|
||||
|
||||
//look for ammo in inventory if we only have 1 left...
|
||||
if(Ammo->GetCharges() == 1) {
|
||||
@@ -746,7 +746,7 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
||||
Ammo = baginst;
|
||||
ammo_slot = m_inv.CalcSlotId(r, i);
|
||||
found = true;
|
||||
mlog(COMBAT__RANGED, "Using ammo from quiver stack at slot %d. %d in stack.", ammo_slot, Ammo->GetCharges());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Using ammo from quiver stack at slot %d. %d in stack.", ammo_slot, Ammo->GetCharges());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -761,17 +761,17 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
||||
if (aslot != INVALID_INDEX) {
|
||||
ammo_slot = aslot;
|
||||
Ammo = m_inv[aslot];
|
||||
mlog(COMBAT__RANGED, "Using ammo from inventory stack at slot %d. %d in stack.", ammo_slot, Ammo->GetCharges());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Using ammo from inventory stack at slot %d. %d in stack.", ammo_slot, Ammo->GetCharges());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float range = RangeItem->Range + AmmoItem->Range + GetRangeDistTargetSizeMod(GetTarget());
|
||||
mlog(COMBAT__RANGED, "Calculated bow range to be %.1f", range);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Calculated bow range to be %.1f", range);
|
||||
range *= range;
|
||||
float dist = DistNoRoot(*other);
|
||||
float dist = DistanceSquared(m_Position, other->GetPosition());
|
||||
if(dist > range) {
|
||||
mlog(COMBAT__RANGED, "Ranged attack out of range... client should catch this. (%f > %f).\n", dist, range);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack out of range... client should catch this. (%f > %f).\n", dist, range);
|
||||
Message_StringID(13,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase.
|
||||
return;
|
||||
}
|
||||
@@ -799,9 +799,9 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
||||
|
||||
if (!ChanceAvoidConsume || (ChanceAvoidConsume < 100 && zone->random.Int(0,99) > ChanceAvoidConsume)){
|
||||
DeleteItemInInventory(ammo_slot, 1, true);
|
||||
mlog(COMBAT__RANGED, "Consumed one arrow from slot %d", ammo_slot);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Consumed one arrow from slot %d", ammo_slot);
|
||||
} else {
|
||||
mlog(COMBAT__RANGED, "Endless Quiver prevented ammo consumption.");
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Endless Quiver prevented ammo consumption.");
|
||||
}
|
||||
|
||||
CheckIncreaseSkill(SkillArchery, GetTarget(), -15);
|
||||
@@ -857,7 +857,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
if (IsClient()){
|
||||
|
||||
_RangeWeapon = CastToClient()->m_inv[MainRange];
|
||||
if (_RangeWeapon && !_RangeWeapon->GetItem() && _RangeWeapon->GetItem()->ID == range_id)
|
||||
if (_RangeWeapon && _RangeWeapon->GetItem() && _RangeWeapon->GetItem()->ID == range_id)
|
||||
RangeWeapon = _RangeWeapon;
|
||||
|
||||
_Ammo = CastToClient()->m_inv[AmmoSlot];
|
||||
@@ -873,7 +873,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
SendItemAnimation(other, AmmoItem, SkillArchery);
|
||||
|
||||
if (ProjectileMiss || (!ProjectileImpact && !other->CheckHitChance(this, SkillArchery, MainPrimary, chance_mod))) {
|
||||
mlog(COMBAT__RANGED, "Ranged attack missed %s.", other->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack missed %s.", other->GetName());
|
||||
|
||||
if (LaunchProjectile){
|
||||
TryProjectileAttack(other, AmmoItem, SkillArchery, 0, RangeWeapon, Ammo, AmmoSlot, speed);
|
||||
@@ -882,7 +882,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
else
|
||||
other->Damage(this, 0, SPELL_UNKNOWN, SkillArchery);
|
||||
} else {
|
||||
mlog(COMBAT__RANGED, "Ranged attack hit %s.", other->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack hit %s.", other->GetName());
|
||||
|
||||
bool HeadShot = false;
|
||||
uint32 HeadShot_Dmg = TryHeadShot(other, SkillArchery);
|
||||
@@ -923,7 +923,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
|
||||
MaxDmg += MaxDmg*bonusArcheryDamageModifier / 100;
|
||||
|
||||
mlog(COMBAT__RANGED, "Bow DMG %d, Arrow DMG %d, Max Damage %d.", WDmg, ADmg, MaxDmg);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Bow DMG %d, Arrow DMG %d, Max Damage %d.", WDmg, ADmg, MaxDmg);
|
||||
|
||||
bool dobonus = false;
|
||||
if(GetClass() == RANGER && GetLevel() > 50){
|
||||
@@ -944,7 +944,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
hate *= 2;
|
||||
MaxDmg = mod_archery_bonus_damage(MaxDmg, RangeWeapon);
|
||||
|
||||
mlog(COMBAT__RANGED, "Ranger. Double damage success roll, doubling damage to %d", MaxDmg);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranger. Double damage success roll, doubling damage to %d", MaxDmg);
|
||||
Message_StringID(MT_CritMelee, BOW_DOUBLE_DAMAGE);
|
||||
}
|
||||
}
|
||||
@@ -996,10 +996,10 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
}
|
||||
|
||||
if (LaunchProjectile)
|
||||
return;//Shouldn't reach this point, but just in case.
|
||||
return;//Shouldn't reach this point durring initial launch phase, but just in case.
|
||||
|
||||
//Weapon Proc
|
||||
if(!RangeWeapon && other && !other->HasDied())
|
||||
if(RangeWeapon && other && !other->HasDied())
|
||||
TryWeaponProc(RangeWeapon, other, MainRange);
|
||||
|
||||
//Ammo Proc
|
||||
@@ -1101,8 +1101,14 @@ void Mob::ProjectileAttack()
|
||||
|
||||
if (target){
|
||||
|
||||
if (IsNPC())
|
||||
CastToNPC()->DoRangedAttackDmg(target, false, ProjectileAtk[i].wpn_dmg,0, static_cast<SkillUseTypes>(ProjectileAtk[i].skill));
|
||||
if (IsNPC()){
|
||||
if (ProjectileAtk[i].skill == SkillConjuration){
|
||||
if (IsValidSpell(ProjectileAtk[i].wpn_dmg))
|
||||
SpellOnTarget(ProjectileAtk[i].wpn_dmg, target, false, true, spells[ProjectileAtk[i].wpn_dmg].ResistDiff, true);
|
||||
}
|
||||
else
|
||||
CastToNPC()->DoRangedAttackDmg(target, false, ProjectileAtk[i].wpn_dmg,0, static_cast<SkillUseTypes>(ProjectileAtk[i].skill));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
@@ -1186,7 +1192,7 @@ void NPC::RangedAttack(Mob* other)
|
||||
//make sure the attack and ranged timers are up
|
||||
//if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow
|
||||
if((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check())){
|
||||
mlog(COMBAT__RANGED, "Archery canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Archery canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1213,9 +1219,9 @@ void NPC::RangedAttack(Mob* other)
|
||||
min_range = static_cast<float>(sa_min_range);
|
||||
|
||||
max_range *= max_range;
|
||||
if(DistNoRoot(*other) > max_range)
|
||||
if(DistanceSquared(m_Position, other->GetPosition()) > max_range)
|
||||
return;
|
||||
else if(DistNoRoot(*other) < (min_range * min_range))
|
||||
else if(DistanceSquared(m_Position, other->GetPosition()) < (min_range * min_range))
|
||||
return;
|
||||
|
||||
if(!other || !IsAttackAllowed(other) ||
|
||||
@@ -1355,7 +1361,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
|
||||
//make sure the attack and ranged timers are up
|
||||
//if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow
|
||||
if((!CanDoubleAttack && (attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check()))) {
|
||||
mlog(COMBAT__RANGED, "Throwing attack canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Throwing attack canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||
// The server and client timers are not exact matches currently, so this would spam too often if enabled
|
||||
//Message(0, "Error: Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||
return;
|
||||
@@ -1365,19 +1371,19 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
|
||||
const ItemInst* RangeWeapon = m_inv[MainRange];
|
||||
|
||||
if (!RangeWeapon || !RangeWeapon->IsType(ItemClassCommon)) {
|
||||
mlog(COMBAT__RANGED, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(MainRange), MainRange);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(MainRange), MainRange);
|
||||
Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have nothing to throw!", GetItemIDAt(MainRange));
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct* item = RangeWeapon->GetItem();
|
||||
if(item->ItemType != ItemTypeLargeThrowing && item->ItemType != ItemTypeSmallThrowing) {
|
||||
mlog(COMBAT__RANGED, "Ranged attack canceled. Ranged item %d is not a throwing weapon. type %d.", item->ItemType);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack canceled. Ranged item %d is not a throwing weapon. type %d.", item->ItemType);
|
||||
Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have nothing useful to throw!", GetItemIDAt(MainRange));
|
||||
return;
|
||||
}
|
||||
|
||||
mlog(COMBAT__RANGED, "Throwing %s (%d) at %s", item->Name, item->ID, other->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Throwing %s (%d) at %s", item->Name, item->ID, other->GetName());
|
||||
|
||||
if(RangeWeapon->GetCharges() == 1) {
|
||||
//first check ammo
|
||||
@@ -1386,7 +1392,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
|
||||
//more in the ammo slot, use it
|
||||
RangeWeapon = AmmoItem;
|
||||
ammo_slot = MainAmmo;
|
||||
mlog(COMBAT__RANGED, "Using ammo from ammo slot, stack at slot %d. %d in stack.", ammo_slot, RangeWeapon->GetCharges());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Using ammo from ammo slot, stack at slot %d. %d in stack.", ammo_slot, RangeWeapon->GetCharges());
|
||||
} else {
|
||||
//look through our inventory for more
|
||||
int32 aslot = m_inv.HasItem(item->ID, 1, invWherePersonal);
|
||||
@@ -1394,17 +1400,17 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
|
||||
//the item wont change, but the instance does, not that it matters
|
||||
ammo_slot = aslot;
|
||||
RangeWeapon = m_inv[aslot];
|
||||
mlog(COMBAT__RANGED, "Using ammo from inventory slot, stack at slot %d. %d in stack.", ammo_slot, RangeWeapon->GetCharges());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Using ammo from inventory slot, stack at slot %d. %d in stack.", ammo_slot, RangeWeapon->GetCharges());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float range = item->Range + GetRangeDistTargetSizeMod(other);
|
||||
mlog(COMBAT__RANGED, "Calculated bow range to be %.1f", range);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Calculated bow range to be %.1f", range);
|
||||
range *= range;
|
||||
float dist = DistNoRoot(*other);
|
||||
float dist = DistanceSquared(m_Position, other->GetPosition());
|
||||
if(dist > range) {
|
||||
mlog(COMBAT__RANGED, "Throwing attack out of range... client should catch this. (%f > %f).\n", dist, range);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Throwing attack out of range... client should catch this. (%f > %f).\n", dist, range);
|
||||
Message_StringID(13,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase.
|
||||
return;
|
||||
}
|
||||
@@ -1483,7 +1489,7 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
SendItemAnimation(other, AmmoItem, SkillThrowing);
|
||||
|
||||
if (ProjectileMiss || (!ProjectileImpact && !other->CheckHitChance(this, SkillThrowing, MainPrimary, chance_mod))){
|
||||
mlog(COMBAT__RANGED, "Ranged attack missed %s.", other->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack missed %s.", other->GetName());
|
||||
if (LaunchProjectile){
|
||||
TryProjectileAttack(other, AmmoItem, SkillThrowing, 0, RangeWeapon, nullptr, AmmoSlot, speed);
|
||||
return;
|
||||
@@ -1491,7 +1497,7 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
else
|
||||
other->Damage(this, 0, SPELL_UNKNOWN, SkillThrowing);
|
||||
} else {
|
||||
mlog(COMBAT__RANGED, "Throwing attack hit %s.", other->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Throwing attack hit %s.", other->GetName());
|
||||
|
||||
int16 WDmg = 0;
|
||||
|
||||
@@ -1527,7 +1533,7 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, ASSASSINATES, GetName());
|
||||
}
|
||||
|
||||
mlog(COMBAT__RANGED, "Item DMG %d. Max Damage %d. Hit for damage %d", WDmg, MaxDmg, TotalDmg);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Item DMG %d. Max Damage %d. Hit for damage %d", WDmg, MaxDmg, TotalDmg);
|
||||
if (!Assassinate_Dmg)
|
||||
other->AvoidDamage(this, TotalDmg, false); //CanRiposte=false - Can not riposte throw attacks.
|
||||
|
||||
|
||||
+49
-47
@@ -16,9 +16,10 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/bodytypes.h"
|
||||
#include "../common/classes.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/item.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/skills.h"
|
||||
@@ -133,7 +134,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
if (spells[spell_id].EndurUpkeep > 0)
|
||||
SetEndurUpkeep(true);
|
||||
|
||||
if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UnderfootAndLater)
|
||||
if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UFAndLater)
|
||||
{
|
||||
EQApplicationPacket *outapp = MakeBuffsPacket(false);
|
||||
CastToClient()->FastQueuePacket(&outapp);
|
||||
@@ -368,8 +369,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
snprintf(effect_desc, _EDLEN, "Current Mana: %+i", effect_value);
|
||||
#endif
|
||||
SetMana(GetMana() + effect_value);
|
||||
caster->SetMana(caster->GetMana() + abs(effect_value));
|
||||
|
||||
caster->SetMana(caster->GetMana() + std::abs(effect_value));
|
||||
|
||||
if (effect_value < 0)
|
||||
TryTriggerOnValueAmount(false, true);
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
@@ -475,7 +476,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
|
||||
if(!target_zone) {
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
LogFile->write(EQEMuLog::Debug, "Succor/Evacuation Spell In Same Zone.");
|
||||
Log.Out(Logs::General, Logs::None, "Succor/Evacuation Spell In Same Zone.");
|
||||
#endif
|
||||
if(IsClient())
|
||||
CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x, y, z, heading, 0, EvacToSafeCoords);
|
||||
@@ -484,7 +485,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
}
|
||||
else {
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
LogFile->write(EQEMuLog::Debug, "Succor/Evacuation Spell To Another Zone.");
|
||||
Log.Out(Logs::General, Logs::None, "Succor/Evacuation Spell To Another Zone.");
|
||||
#endif
|
||||
if(IsClient())
|
||||
CastToClient()->MovePC(target_zone, x, y, z, heading);
|
||||
@@ -710,7 +711,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
stun_resist += aabonuses.StunResist;
|
||||
|
||||
if (stun_resist <= 0 || zone->random.Int(0,99) >= stun_resist) {
|
||||
mlog(COMBAT__HITS, "Stunned. We had %d percent resist chance.", stun_resist);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Stunned. We had %d percent resist chance.", stun_resist);
|
||||
|
||||
if (caster->IsClient())
|
||||
effect_value += effect_value*caster->GetFocusEffect(focusFcStunTimeMod, spell_id)/100;
|
||||
@@ -720,7 +721,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
if (IsClient())
|
||||
Message_StringID(MT_Stun, SHAKE_OFF_STUN);
|
||||
|
||||
mlog(COMBAT__HITS, "Stun Resisted. We had %d percent resist chance.", stun_resist);
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Stun Resisted. We had %d percent resist chance.", stun_resist);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1648,7 +1649,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
if (IsCorpse() && CastToCorpse()->IsPlayerCorpse()) {
|
||||
|
||||
if(caster)
|
||||
mlog(SPELLS__REZ, " corpse being rezzed using spell %i by %s",
|
||||
Log.Out(Logs::Detail, Logs::Spells, " corpse being rezzed using spell %i by %s",
|
||||
spell_id, caster->GetName());
|
||||
|
||||
CastToCorpse()->CastRezz(spell_id, caster);
|
||||
@@ -1771,7 +1772,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
}
|
||||
else {
|
||||
Message_StringID(4, TARGET_NOT_FOUND);
|
||||
LogFile->write(EQEMuLog::Error, "%s attempted to cast spell id %u with spell effect SE_SummonCorpse, but could not cast target into a Client object.", GetCleanName(), spell_id);
|
||||
Log.Out(Logs::General, Logs::Error, "%s attempted to cast spell id %u with spell effect SE_SummonCorpse, but could not cast target into a Client object.", GetCleanName(), spell_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3064,7 +3065,7 @@ int Mob::CalcSpellEffectValue(uint16 spell_id, int effect_id, int caster_level,
|
||||
int mod = caster->GetInstrumentMod(spell_id);
|
||||
mod = ApplySpellEffectiveness(caster, spell_id, mod, true);
|
||||
effect_value = effect_value * mod / 10;
|
||||
mlog(SPELLS__BARDS, "Effect value %d altered with bard modifier of %d to yeild %d", oval, mod, effect_value);
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Effect value %d altered with bard modifier of %d to yeild %d", oval, mod, effect_value);
|
||||
}
|
||||
|
||||
effect_value = mod_effect_value(effect_value, spell_id, spells[spell_id].effectid[effect_id], caster);
|
||||
@@ -3126,7 +3127,7 @@ snare has both of them negative, yet their range should work the same:
|
||||
updownsign = 1;
|
||||
}
|
||||
|
||||
mlog(SPELLS__EFFECT_VALUES, "CSEV: spell %d, formula %d, base %d, max %d, lvl %d. Up/Down %d",
|
||||
Log.Out(Logs::Detail, Logs::Spells, "CSEV: spell %d, formula %d, base %d, max %d, lvl %d. Up/Down %d",
|
||||
spell_id, formula, base, max, caster_level, updownsign);
|
||||
|
||||
switch(formula)
|
||||
@@ -3210,7 +3211,7 @@ snare has both of them negative, yet their range should work the same:
|
||||
break;
|
||||
}
|
||||
case 123: // added 2/6/04
|
||||
result = zone->random.Int(ubase, abs(max));
|
||||
result = zone->random.Int(ubase, std::abs(max));
|
||||
break;
|
||||
|
||||
case 124: // check sign
|
||||
@@ -3325,7 +3326,7 @@ snare has both of them negative, yet their range should work the same:
|
||||
result = ubase * (caster_level * (formula - 2000) + 1);
|
||||
}
|
||||
else
|
||||
LogFile->write(EQEMuLog::Debug, "Unknown spell effect value forumula %d", formula);
|
||||
Log.Out(Logs::General, Logs::None, "Unknown spell effect value forumula %d", formula);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3350,7 +3351,7 @@ snare has both of them negative, yet their range should work the same:
|
||||
if (base < 0 && result > 0)
|
||||
result *= -1;
|
||||
|
||||
mlog(SPELLS__EFFECT_VALUES, "Result: %d (orig %d), cap %d %s", result, oresult, max, (base < 0 && result > 0)?"Inverted due to negative base":"");
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Result: %d (orig %d), cap %d %s", result, oresult, max, (base < 0 && result > 0)?"Inverted due to negative base":"");
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -3382,18 +3383,18 @@ void Mob::BuffProcess()
|
||||
IsMezSpell(buffs[buffs_i].spellid) ||
|
||||
IsBlindSpell(buffs[buffs_i].spellid))
|
||||
{
|
||||
mlog(SPELLS__BUFFS, "Buff %d in slot %d has expired. Fading.", buffs[buffs_i].spellid, buffs_i);
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Buff %d in slot %d has expired. Fading.", buffs[buffs_i].spellid, buffs_i);
|
||||
BuffFadeBySlot(buffs_i);
|
||||
}
|
||||
}
|
||||
else if (buffs[buffs_i].ticsremaining < 0)
|
||||
{
|
||||
mlog(SPELLS__BUFFS, "Buff %d in slot %d has expired. Fading.", buffs[buffs_i].spellid, buffs_i);
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Buff %d in slot %d has expired. Fading.", buffs[buffs_i].spellid, buffs_i);
|
||||
BuffFadeBySlot(buffs_i);
|
||||
}
|
||||
else
|
||||
{
|
||||
mlog(SPELLS__BUFFS, "Buff %d in slot %d has %d tics remaining.", buffs[buffs_i].spellid, buffs_i, buffs[buffs_i].ticsremaining);
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Buff %d in slot %d has %d tics remaining.", buffs[buffs_i].spellid, buffs_i, buffs[buffs_i].ticsremaining);
|
||||
}
|
||||
}
|
||||
else if(IsClient() && !(CastToClient()->GetClientVersionBit() & BIT_SoFAndLater))
|
||||
@@ -3408,7 +3409,7 @@ void Mob::BuffProcess()
|
||||
{
|
||||
CastToClient()->SendBuffDurationPacket(buffs[buffs_i]);
|
||||
// Hack to get UF to play nicer, RoF seems fine without it
|
||||
if (CastToClient()->GetClientVersion() == EQClientUnderfoot && buffs[buffs_i].numhits > 0)
|
||||
if (CastToClient()->GetClientVersion() == ClientVersion::UF && buffs[buffs_i].numhits > 0)
|
||||
CastToClient()->SendBuffNumHitPacket(buffs[buffs_i], buffs_i);
|
||||
buffs[buffs_i].UpdateClient = false;
|
||||
}
|
||||
@@ -3471,14 +3472,16 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
|
||||
{
|
||||
effect_value = CalcSpellEffectValue(spell_id, i, caster_level, caster, ticsremaining);
|
||||
//Handle client cast DOTs here.
|
||||
if (caster && effect_value < 0 && IsDetrimentalSpell(spell_id)){
|
||||
if (caster && effect_value < 0){
|
||||
|
||||
if (caster->IsClient()){
|
||||
if (!caster->CastToClient()->GetFeigned())
|
||||
if (IsDetrimentalSpell(spell_id)){
|
||||
if (caster->IsClient()){
|
||||
if (!caster->CastToClient()->GetFeigned())
|
||||
AddToHateList(caster, -effect_value);
|
||||
}
|
||||
else if (!IsClient()) //Allow NPC's to generate hate if casted on other NPC's.
|
||||
AddToHateList(caster, -effect_value);
|
||||
}
|
||||
else if (!IsClient()) //Allow NPC's to generate hate if casted on other NPC's.
|
||||
AddToHateList(caster, -effect_value);
|
||||
|
||||
effect_value = caster->GetActDoTDamage(spell_id, effect_value, this);
|
||||
|
||||
@@ -3583,7 +3586,7 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
|
||||
}
|
||||
|
||||
case SE_Charm: {
|
||||
if (!caster || !PassCharismaCheck(caster, this, spell_id)) {
|
||||
if (!caster || !PassCharismaCheck(caster, spell_id)) {
|
||||
BuffFadeByEffect(SE_Charm);
|
||||
}
|
||||
|
||||
@@ -3758,7 +3761,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
||||
if (IsClient() && !CastToClient()->IsDead())
|
||||
CastToClient()->MakeBuffFadePacket(buffs[slot].spellid, slot);
|
||||
|
||||
mlog(SPELLS__BUFFS, "Fading buff %d from slot %d", buffs[slot].spellid, slot);
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Fading buff %d from slot %d", buffs[slot].spellid, slot);
|
||||
|
||||
if(spells[buffs[slot].spellid].viral_targets > 0) {
|
||||
bool last_virus = true;
|
||||
@@ -4172,7 +4175,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UnderfootAndLater)
|
||||
if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UFAndLater)
|
||||
{
|
||||
EQApplicationPacket *outapp = MakeBuffsPacket(false);
|
||||
CastToClient()->FastQueuePacket(&outapp);
|
||||
@@ -4816,7 +4819,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
LogFile->write(EQEMuLog::Normal, "CalcFocusEffect: unknown limit spelltype %d", focus_spell.base[i]);
|
||||
Log.Out(Logs::General, Logs::Normal, "CalcFocusEffect: unknown limit spelltype %d", focus_spell.base[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -5155,7 +5158,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
||||
//this spits up a lot of garbage when calculating spell focuses
|
||||
//since they have all kinds of extra effects on them.
|
||||
default:
|
||||
LogFile->write(EQEMuLog::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
|
||||
Log.Out(Logs::General, Logs::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -5643,7 +5646,7 @@ int16 NPC::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
return realTotal + realTotal2;
|
||||
}
|
||||
|
||||
void Mob::CheckNumHitsRemaining(uint8 type, int32 buff_slot, uint16 spell_id)
|
||||
void Mob::CheckNumHitsRemaining(NumHit type, int32 buff_slot, uint16 spell_id)
|
||||
{
|
||||
/*
|
||||
Field 175 = numhits type
|
||||
@@ -5670,7 +5673,7 @@ void Mob::CheckNumHitsRemaining(uint8 type, int32 buff_slot, uint16 spell_id)
|
||||
if (IsValidSpell(spell_id)) {
|
||||
for (int d = 0; d < buff_max; d++) {
|
||||
if (buffs[d].spellid == spell_id && buffs[d].numhits > 0 &&
|
||||
spells[buffs[d].spellid].numhitstype == type) {
|
||||
spells[buffs[d].spellid].numhitstype == static_cast<int>(type)) {
|
||||
if (--buffs[d].numhits == 0) {
|
||||
CastOnNumHitFade(buffs[d].spellid);
|
||||
if (!TryFadeEffect(d))
|
||||
@@ -5680,7 +5683,7 @@ void Mob::CheckNumHitsRemaining(uint8 type, int32 buff_slot, uint16 spell_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (type == NUMHIT_MatchingSpells) {
|
||||
} else if (type == NumHit::MatchingSpells) {
|
||||
if (buff_slot >= 0) {
|
||||
if (--buffs[buff_slot].numhits == 0) {
|
||||
CastOnNumHitFade(buffs[buff_slot].spellid);
|
||||
@@ -5709,7 +5712,7 @@ void Mob::CheckNumHitsRemaining(uint8 type, int32 buff_slot, uint16 spell_id)
|
||||
} else {
|
||||
for (int d = 0; d < buff_max; d++) {
|
||||
if (IsValidSpell(buffs[d].spellid) && buffs[d].numhits > 0 &&
|
||||
spells[buffs[d].spellid].numhitstype == type) {
|
||||
spells[buffs[d].spellid].numhitstype == static_cast<int>(type)) {
|
||||
if (--buffs[d].numhits == 0) {
|
||||
CastOnNumHitFade(buffs[d].spellid);
|
||||
if (!TryFadeEffect(d))
|
||||
@@ -5973,7 +5976,7 @@ int32 Mob::GetFcDamageAmtIncoming(Mob *caster, uint32 spell_id, bool use_skill,
|
||||
}
|
||||
if ((!limit_exists) || (limit_exists && skill_found)){
|
||||
dmg += temp_dmg;
|
||||
CheckNumHitsRemaining(NUMHIT_MatchingSpells,i);
|
||||
CheckNumHitsRemaining(NumHit::MatchingSpells, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5981,7 +5984,7 @@ int32 Mob::GetFcDamageAmtIncoming(Mob *caster, uint32 spell_id, bool use_skill,
|
||||
int32 focus = caster->CalcFocusEffect(focusFcDamageAmtIncoming, buffs[i].spellid, spell_id);
|
||||
if(focus){
|
||||
dmg += focus;
|
||||
CheckNumHitsRemaining(NUMHIT_MatchingSpells,i);
|
||||
CheckNumHitsRemaining(NumHit::MatchingSpells, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6033,7 +6036,7 @@ int32 Mob::GetFocusIncoming(focusType type, int effect, Mob *caster, uint32 spel
|
||||
value = tmp_focus;
|
||||
|
||||
if (tmp_buffslot >= 0)
|
||||
CheckNumHitsRemaining(NUMHIT_MatchingSpells, tmp_buffslot);
|
||||
CheckNumHitsRemaining(NumHit::MatchingSpells, tmp_buffslot);
|
||||
}
|
||||
|
||||
|
||||
@@ -6568,33 +6571,32 @@ bool Mob::TrySpellProjectile(Mob* spell_target, uint16 spell_id, float speed){
|
||||
|
||||
DoAnim(anim, 0, true, IsClient() ? FilterPCSpells : FilterNPCSpells); //Override the default projectile animation.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::ResourceTap(int32 damage, uint16 spellid){
|
||||
void Mob::ResourceTap(int32 damage, uint16 spellid)
|
||||
{
|
||||
//'this' = caster
|
||||
if (!IsValidSpell(spellid))
|
||||
return;
|
||||
|
||||
for (int i = 0; i <= EFFECT_COUNT; i++)
|
||||
{
|
||||
if (spells[spellid].effectid[i] == SE_ResourceTap){
|
||||
|
||||
damage += (damage * spells[spellid].base[i])/100;
|
||||
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||
if (spells[spellid].effectid[i] == SE_ResourceTap) {
|
||||
damage += (damage * spells[spellid].base[i]) / 100;
|
||||
|
||||
if (spells[spellid].max[i] && (damage > spells[spellid].max[i]))
|
||||
damage = spells[spellid].max[i];
|
||||
|
||||
if (spells[spellid].base2[i] == 0){ //HP Tap
|
||||
if (spells[spellid].base2[i] == 0) { // HP Tap
|
||||
if (damage > 0)
|
||||
HealDamage(damage);
|
||||
else
|
||||
Damage(this, -damage,0, SkillEvocation,false);
|
||||
Damage(this, -damage, 0, SkillEvocation, false);
|
||||
}
|
||||
|
||||
if (spells[spellid].base2[i] == 1) //Mana Tap
|
||||
if (spells[spellid].base2[i] == 1) // Mana Tap
|
||||
SetMana(GetMana() + damage);
|
||||
|
||||
if (spells[spellid].base2[i] == 2 && IsClient()) //Endurance Tap
|
||||
if (spells[spellid].base2[i] == 2 && IsClient()) // Endurance Tap
|
||||
CastToClient()->SetEndurance(CastToClient()->GetEndurance() + damage);
|
||||
}
|
||||
}
|
||||
|
||||
+261
-239
File diff suppressed because it is too large
Load Diff
+132
-153
File diff suppressed because it is too large
Load Diff
+2
-9
@@ -40,7 +40,6 @@ bool TitleManager::LoadTitles()
|
||||
"`status`, `item_id`, `prefix`, `suffix`, `title_set` FROM titles";
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to load titles: %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -263,7 +262,6 @@ void TitleManager::CreateNewPlayerTitle(Client *client, const char *title)
|
||||
safe_delete_array(escTitle);
|
||||
results = database.QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error adding title: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -296,7 +294,6 @@ void TitleManager::CreateNewPlayerSuffix(Client *client, const char *suffix)
|
||||
safe_delete_array(escSuffix);
|
||||
results = database.QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error adding title suffix: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -351,7 +348,7 @@ void Client::EnableTitle(int titleSet) {
|
||||
CharacterID(), titleSet);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error in EnableTitle query for titleset %i and charid %i", titleSet, CharacterID());
|
||||
Log.Out(Logs::General, Logs::Error, "Error in EnableTitle query for titleset %i and charid %i", titleSet, CharacterID());
|
||||
|
||||
}
|
||||
|
||||
@@ -362,7 +359,6 @@ bool Client::CheckTitle(int titleSet) {
|
||||
titleSet, CharacterID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in CheckTitle query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -380,9 +376,6 @@ void Client::RemoveTitle(int titleSet) {
|
||||
std::string query = StringFormat("DELETE FROM player_titlesets "
|
||||
"WHERE `title_set` = %i AND `char_id` = %i",
|
||||
titleSet, CharacterID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error in RemoveTitle query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user