Procyon Updates #3
Fix #367 - Put additional protection to rest of player_quests calls, using read/write locks now also Fix #363 - Added rule R_Loot, SkipLootGrayMob, default is on "1". Set to "0" to allow chests and 'non body' or 'non quest' drops from gray mobs Fix #362 - Removed charge based items when charges depleted Fix #255 - Added World Time LUA Functions int16 = GetWorldTimeYear() sint32 = GetWorldTimeMonth() sint32 = GetWorldTimeHour() sint32 = GetWorldTimeMinute() SetWorldTime(int16 years, sint32 months, sint32 hours, sint32 minutes) SendTimeUpdate() - Additionally fixed camping and logging back in immediately, there was a 30 second delay. That is no longer the case. - Fixed effective level updating on level changes, this prevents the unexpected purple inventory and mentor level display
This commit is contained in:
parent
c1f748c7d6
commit
f169cb6d6e
17 changed files with 357 additions and 129 deletions
|
@ -2094,13 +2094,20 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
|
|||
Item* item = player->item_list.GetItemFromIndex(item_index);
|
||||
if(!item)
|
||||
LogWrite(PLAYER__WARNING, 0, "Command", "%s: Item %s (%i) was used, however after the item looks to be removed.", client->GetPlayer()->GetName(), itemName.c_str(), item_id);
|
||||
else if(!item->generic_info.display_charges && item->generic_info.max_charges == 1)
|
||||
else if(!item->generic_info.display_charges && item->generic_info.max_charges == 1) {
|
||||
client->Message(CHANNEL_NARRATIVE, "%s is out of charges. It has been removed.", item->name.c_str());
|
||||
client->RemoveItem(item, 1); // end of a set of charges OR an item that uses a stack count of actual item quantity
|
||||
}
|
||||
else
|
||||
{
|
||||
item->details.count--; // charges
|
||||
item->save_needed = true;
|
||||
client->QueuePacket(item->serialize(client->GetVersion(), false, client->GetPlayer()));
|
||||
|
||||
if(!item->details.count) {
|
||||
client->Message(CHANNEL_NARRATIVE, "%s is out of charges. It has been removed.", item->name.c_str());
|
||||
client->RemoveItem(item, 1); // end of a set of charges OR an item that uses a stack count of actual item quantity
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2779,7 +2786,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
|
|||
{
|
||||
Entity* ent = (Entity*)spawn;
|
||||
ent->SetLootCoins(0);
|
||||
ent->ClearLootList();
|
||||
ent->ClearLoot();
|
||||
spawn->GetZone()->AddLoot((NPC*)spawn);
|
||||
client->Message(CHANNEL_COLOR_YELLOW, "Spawn %u active loot purged and reloaded.", spawn->GetDatabaseID());
|
||||
}
|
||||
|
@ -3295,6 +3302,8 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
|
|||
}
|
||||
case COMMAND_SETTIME:{
|
||||
if(sep && sep->arg[0]){
|
||||
|
||||
world.MWorldTime.writelock(__FUNCTION__, __LINE__);
|
||||
sscanf (sep->arg[0], "%d:%d", &world.GetWorldTimeStruct()->hour, &world.GetWorldTimeStruct()->minute);
|
||||
if(sep->arg[1] && sep->IsNumber(1))
|
||||
world.GetWorldTimeStruct()->month = atoi(sep->arg[1]) - 1; //zero based indexes
|
||||
|
@ -3302,6 +3311,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
|
|||
world.GetWorldTimeStruct()->day = atoi(sep->arg[2]) - 1; //zero based indexes
|
||||
if(sep->arg[3] && sep->IsNumber(3))
|
||||
world.GetWorldTimeStruct()->year = atoi(sep->arg[3]);
|
||||
world.MWorldTime.releasewritelock(__FUNCTION__, __LINE__);
|
||||
client->GetCurrentZone()->SendTimeUpdateToAllClients();
|
||||
}
|
||||
else{
|
||||
|
|
|
@ -884,7 +884,6 @@ void LoginServer::SendInfo() {
|
|||
#ifdef _DEBUG
|
||||
lsi->servertype = 4;
|
||||
#endif
|
||||
int8 tmppass[16];
|
||||
string passwdSha512 = sha512(net.GetWorldPassword());
|
||||
memcpy(lsi->password, (char*)passwdSha512.c_str(), passwdSha512.length());
|
||||
strcpy(lsi->address, net.GetWorldAddress());
|
||||
|
@ -965,6 +964,7 @@ int32 LoginServer::DetermineCharacterLoginRequest ( UsertoWorldRequest_Struct* u
|
|||
if(status < 100 && zone_list.ClientConnected(utwr->lsaccountid))
|
||||
status = -9;
|
||||
if(status < 0){
|
||||
LogWrite(WORLD__ERROR, 0, "World", "Login Rejected based on PLAY_ERROR (UserStatus) (MinStatus: %i), UserStatus: %i, CharID: %i",loginserver.minLockedStatus,status,utwr->char_id );
|
||||
switch(status){
|
||||
case -10:
|
||||
utwrs->response = PLAY_ERROR_CHAR_NOT_LOADED;
|
||||
|
|
|
@ -417,7 +417,7 @@ int EQ2Emu_lua_SpawnSet(lua_State* state) {
|
|||
|
||||
int8 num_args = (int8)lua_interface->GetNumberOfArgs(state);
|
||||
int8 index = 0;
|
||||
|
||||
|
||||
if(num_args >= 5)
|
||||
{
|
||||
temporary_flag = lua_interface->GetBooleanValue(state, 5); // this used to be false, but no one bothered to set it temporary, we don't need to update the DB
|
||||
|
@ -12319,6 +12319,9 @@ int EQ2Emu_lua_SetRailID(lua_State* state) {
|
|||
}
|
||||
|
||||
int EQ2Emu_lua_IsZoneLoading(lua_State* state) {
|
||||
if (!lua_interface)
|
||||
return 0;
|
||||
|
||||
ZoneServer* zone = lua_interface->GetZone(state);
|
||||
lua_interface->ResetFunctionStack(state);
|
||||
|
||||
|
@ -12329,6 +12332,9 @@ int EQ2Emu_lua_IsZoneLoading(lua_State* state) {
|
|||
return 0;
|
||||
}
|
||||
int EQ2Emu_lua_IsRunning(lua_State* state) {
|
||||
if (!lua_interface)
|
||||
return 0;
|
||||
|
||||
Spawn* spawn = lua_interface->GetSpawn(state);
|
||||
lua_interface->ResetFunctionStack(state);
|
||||
|
||||
|
@ -12359,4 +12365,88 @@ int EQ2Emu_lua_GetZoneLockoutTimer(lua_State* state) {
|
|||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int EQ2Emu_lua_SetWorldTime(lua_State* state) {
|
||||
if (!lua_interface)
|
||||
return 0;
|
||||
|
||||
int16 newYear = lua_interface->GetInt16Value(state, 1);
|
||||
sint32 newMonth = lua_interface->GetInt16Value(state, 2);
|
||||
int16 newHour = lua_interface->GetInt16Value(state, 3);
|
||||
int16 newMinute = lua_interface->GetInt16Value(state, 4);
|
||||
|
||||
lua_interface->ResetFunctionStack(state);
|
||||
|
||||
world.MWorldTime.writelock(__FUNCTION__, __LINE__);
|
||||
world.GetWorldTimeStruct()->year = newYear;
|
||||
world.GetWorldTimeStruct()->month = newMonth;
|
||||
world.GetWorldTimeStruct()->hour = newHour;
|
||||
world.GetWorldTimeStruct()->minute = newMinute;
|
||||
world.MWorldTime.releasewritelock(__FUNCTION__, __LINE__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EQ2Emu_lua_GetWorldTimeYear(lua_State* state) {
|
||||
if (!lua_interface)
|
||||
return 0;
|
||||
|
||||
lua_interface->ResetFunctionStack(state);
|
||||
|
||||
world.MWorldTime.readlock(__FUNCTION__, __LINE__);
|
||||
lua_interface->SetInt32Value(state, world.GetWorldTimeStruct()->year);
|
||||
world.MWorldTime.releasereadlock(__FUNCTION__, __LINE__);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EQ2Emu_lua_GetWorldTimeMonth(lua_State* state) {
|
||||
if (!lua_interface)
|
||||
return 0;
|
||||
|
||||
lua_interface->ResetFunctionStack(state);
|
||||
|
||||
world.MWorldTime.readlock(__FUNCTION__, __LINE__);
|
||||
lua_interface->SetSInt32Value(state, world.GetWorldTimeStruct()->month);
|
||||
world.MWorldTime.releasereadlock(__FUNCTION__, __LINE__);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EQ2Emu_lua_GetWorldTimeHour(lua_State* state) {
|
||||
if (!lua_interface)
|
||||
return 0;
|
||||
|
||||
lua_interface->ResetFunctionStack(state);
|
||||
|
||||
world.MWorldTime.readlock(__FUNCTION__, __LINE__);
|
||||
lua_interface->SetSInt32Value(state, world.GetWorldTimeStruct()->hour);
|
||||
world.MWorldTime.releasereadlock(__FUNCTION__, __LINE__);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EQ2Emu_lua_GetWorldTimeMinute(lua_State* state) {
|
||||
if (!lua_interface)
|
||||
return 0;
|
||||
|
||||
lua_interface->ResetFunctionStack(state);
|
||||
|
||||
world.MWorldTime.readlock(__FUNCTION__, __LINE__);
|
||||
lua_interface->SetSInt32Value(state, world.GetWorldTimeStruct()->minute);
|
||||
world.MWorldTime.releasereadlock(__FUNCTION__, __LINE__);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EQ2Emu_lua_SendTimeUpdate(lua_State* state) {
|
||||
if (!lua_interface)
|
||||
return 0;
|
||||
|
||||
lua_interface->ResetFunctionStack(state);
|
||||
|
||||
world.SendTimeUpdate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -595,4 +595,11 @@ int EQ2Emu_lua_IsZoneLoading(lua_State* state);
|
|||
int EQ2Emu_lua_IsRunning(lua_State* state);
|
||||
|
||||
int EQ2Emu_lua_GetZoneLockoutTimer(lua_State* state);
|
||||
|
||||
int EQ2Emu_lua_SetWorldTime(lua_State* state);
|
||||
int EQ2Emu_lua_GetWorldTimeYear(lua_State* state);
|
||||
int EQ2Emu_lua_GetWorldTimeMonth(lua_State* state);
|
||||
int EQ2Emu_lua_GetWorldTimeHour(lua_State* state);
|
||||
int EQ2Emu_lua_GetWorldTimeMinute(lua_State* state);
|
||||
int EQ2Emu_lua_SendTimeUpdate(lua_State* state);
|
||||
#endif
|
|
@ -1424,6 +1424,13 @@ void LuaInterface::RegisterFunctions(lua_State* state) {
|
|||
lua_register(state, "IsRunning", EQ2Emu_lua_IsRunning);
|
||||
|
||||
lua_register(state, "GetZoneLockoutTimer", EQ2Emu_lua_GetZoneLockoutTimer);
|
||||
|
||||
lua_register(state, "SetWorldTime", EQ2Emu_lua_SetWorldTime);
|
||||
lua_register(state, "GetWorldTimeYear", EQ2Emu_lua_GetWorldTimeYear);
|
||||
lua_register(state, "GetWorldTimeMonth", EQ2Emu_lua_GetWorldTimeMonth);
|
||||
lua_register(state, "GetWorldTimeHour", EQ2Emu_lua_GetWorldTimeHour);
|
||||
lua_register(state, "GetWorldTimeMinute", EQ2Emu_lua_GetWorldTimeMinute);
|
||||
lua_register(state, "SendTimeUpdate", EQ2Emu_lua_SendTimeUpdate);
|
||||
}
|
||||
|
||||
void LuaInterface::LogError(const char* error, ...) {
|
||||
|
|
|
@ -224,7 +224,7 @@ EQ2Packet* Player::Move(float x, float y, float z, int16 version, float heading)
|
|||
}
|
||||
|
||||
void Player::DestroyQuests(){
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.writelock(__FUNCTION__, __LINE__);
|
||||
map<int32, Quest*>::iterator itr;
|
||||
for(itr = completed_quests.begin(); itr != completed_quests.end(); itr++){
|
||||
safe_delete(itr->second);
|
||||
|
@ -238,7 +238,7 @@ void Player::DestroyQuests(){
|
|||
safe_delete(itr->second);
|
||||
}
|
||||
pending_quests.clear();
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasewritelock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
PlayerInfo* Player::GetPlayerInfo(){
|
||||
|
@ -3870,6 +3870,10 @@ float Player::CalculateXP(Spawn* victim){
|
|||
}
|
||||
|
||||
switch(GetArrowColor(victim->GetLevel())){
|
||||
case ARROW_COLOR_GRAY:
|
||||
LogWrite(PLAYER__DEBUG, 5, "XP", "Gray Arrow = No XP");
|
||||
return 0.0f;
|
||||
break;
|
||||
case ARROW_COLOR_GREEN:
|
||||
multiplier = 3.25;
|
||||
LogWrite(PLAYER__DEBUG, 5, "XP", "Green Arrow Multiplier = %.2f", multiplier);
|
||||
|
@ -4256,19 +4260,19 @@ void Player::RemoveSpawn(Spawn* spawn)
|
|||
vector<int32> Player::GetQuestIDs(){
|
||||
vector<int32> ret;
|
||||
map<int32, Quest*>::iterator itr;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
for(itr = player_quests.begin(); itr != player_quests.end(); itr++){
|
||||
if(itr->second)
|
||||
ret.push_back(itr->second->GetQuestID());
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vector<Quest*>* Player::CheckQuestsItemUpdate(Item* item){
|
||||
vector<Quest*>* quest_updates = 0;
|
||||
map<int32, Quest*>::iterator itr;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
for(itr = player_quests.begin(); itr != player_quests.end(); itr++){
|
||||
if(itr->second && itr->second->CheckQuestItemUpdate(item->details.item_id, item->details.count)){
|
||||
if(!quest_updates)
|
||||
|
@ -4276,14 +4280,14 @@ vector<Quest*>* Player::CheckQuestsItemUpdate(Item* item){
|
|||
quest_updates->push_back(itr->second);
|
||||
}
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return quest_updates;
|
||||
}
|
||||
|
||||
void Player::CheckQuestsCraftUpdate(Item* item, int32 qty){
|
||||
map<int32, Quest*>::iterator itr;
|
||||
vector<Quest*>* update_list = new vector<Quest*>;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
for(itr = player_quests.begin(); itr != player_quests.end(); itr++){
|
||||
if(itr->second){
|
||||
if(item && qty > 0){
|
||||
|
@ -4293,7 +4297,7 @@ void Player::CheckQuestsCraftUpdate(Item* item, int32 qty){
|
|||
}
|
||||
}
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
if(update_list && update_list->size() > 0){
|
||||
Client* client = GetZone()->GetClientBySpawn(this);
|
||||
if(client){
|
||||
|
@ -4310,7 +4314,7 @@ void Player::CheckQuestsCraftUpdate(Item* item, int32 qty){
|
|||
void Player::CheckQuestsHarvestUpdate(Item* item, int32 qty){
|
||||
map<int32, Quest*>::iterator itr;
|
||||
vector<Quest*>* update_list = new vector<Quest*>;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
for(itr = player_quests.begin(); itr != player_quests.end(); itr++){
|
||||
if(itr->second){
|
||||
if(item && qty > 0){
|
||||
|
@ -4320,7 +4324,7 @@ void Player::CheckQuestsHarvestUpdate(Item* item, int32 qty){
|
|||
}
|
||||
}
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
if(update_list && update_list->size() > 0){
|
||||
Client* client = GetZone()->GetClientBySpawn(this);
|
||||
if(client){
|
||||
|
@ -4337,7 +4341,7 @@ void Player::CheckQuestsHarvestUpdate(Item* item, int32 qty){
|
|||
vector<Quest*>* Player::CheckQuestsSpellUpdate(Spell* spell) {
|
||||
vector<Quest*>* quest_updates = 0;
|
||||
map<int32, Quest*>::iterator itr;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
for (itr = player_quests.begin(); itr != player_quests.end(); itr++){
|
||||
if (itr->second && itr->second->CheckQuestSpellUpdate(spell)) {
|
||||
if (!quest_updates)
|
||||
|
@ -4345,7 +4349,7 @@ vector<Quest*>* Player::CheckQuestsSpellUpdate(Spell* spell) {
|
|||
quest_updates->push_back(itr->second);
|
||||
}
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return quest_updates;
|
||||
}
|
||||
|
||||
|
@ -4358,7 +4362,7 @@ PacketStruct* Player::GetQuestJournalPacket(bool all_quests, int16 version, int3
|
|||
map<int32, Quest*> total_quests = player_quests;
|
||||
if(all_quests && completed_quests.size() > 0)
|
||||
total_quests.insert(completed_quests.begin(), completed_quests.end());
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
if(total_quests.size() > 0){
|
||||
map<string, int16> quest_types;
|
||||
map<int32, Quest*>::iterator itr;
|
||||
|
@ -4470,7 +4474,7 @@ PacketStruct* Player::GetQuestJournalPacket(bool all_quests, int16 version, int3
|
|||
//packet->setDataByName("unknown4", 0);
|
||||
packet->setDataByName("visible_quest_id", current_quest_id);
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
packet->setDataByName("player_crc", crc);
|
||||
packet->setDataByName("player_name", GetName());
|
||||
packet->setDataByName("used_quests", total_quests_num - total_completed_quests);
|
||||
|
@ -4577,51 +4581,51 @@ PacketStruct* Player::GetQuestJournalPacket(Quest* quest, int16 version, int32 c
|
|||
|
||||
Quest* Player::SetStepComplete(int32 id, int32 step){
|
||||
Quest* ret = 0;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
if(player_quests.count(id) > 0){
|
||||
if(player_quests[id]->SetStepComplete(step))
|
||||
ret = player_quests[id];
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Quest* Player::AddStepProgress(int32 quest_id, int32 step, int32 progress) {
|
||||
Quest* ret = 0;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
if (player_quests.count(quest_id) > 0) {
|
||||
if (player_quests[quest_id]->AddStepProgress(step, progress))
|
||||
ret = player_quests[quest_id];
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32 Player::GetStepProgress(int32 quest_id, int32 step_id) {
|
||||
int32 ret = 0;
|
||||
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
if (player_quests.count(quest_id) > 0)
|
||||
ret = player_quests[quest_id]->GetStepProgress(step_id);
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Player::RemoveQuest(int32 id, bool delete_quest){
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.writelock(__FUNCTION__, __LINE__);
|
||||
if(delete_quest){
|
||||
safe_delete(player_quests[id]);
|
||||
}
|
||||
player_quests.erase(id);
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasewritelock(__FUNCTION__, __LINE__);
|
||||
SendQuestRequiredSpawns(id);
|
||||
}
|
||||
|
||||
vector<Quest*>* Player::CheckQuestsLocationUpdate(){
|
||||
vector<Quest*>* quest_updates = 0;
|
||||
map<int32, Quest*>::iterator itr;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
for(itr = player_quests.begin(); itr != player_quests.end(); itr++){
|
||||
if(itr->second && itr->second->CheckQuestLocationUpdate(GetX(), GetY(), GetZ(), (GetZone() ? GetZone()->GetZoneID() : 0))){
|
||||
if(!quest_updates)
|
||||
|
@ -4629,14 +4633,14 @@ vector<Quest*>* Player::CheckQuestsLocationUpdate(){
|
|||
quest_updates->push_back(itr->second);
|
||||
}
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return quest_updates;
|
||||
}
|
||||
|
||||
vector<Quest*>* Player::CheckQuestsFailures(){
|
||||
vector<Quest*>* quest_failures = 0;
|
||||
map<int32, Quest*>::iterator itr;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
for(itr = player_quests.begin(); itr != player_quests.end(); itr++){
|
||||
if(itr->second && itr->second->GetQuestFailures()->size() > 0){
|
||||
if(!quest_failures)
|
||||
|
@ -4644,14 +4648,14 @@ vector<Quest*>* Player::CheckQuestsFailures(){
|
|||
quest_failures->push_back(itr->second);
|
||||
}
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return quest_failures;
|
||||
}
|
||||
|
||||
vector<Quest*>* Player::CheckQuestsKillUpdate(Spawn* spawn, bool update){
|
||||
vector<Quest*>* quest_updates = 0;
|
||||
map<int32, Quest*>::iterator itr;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
for(itr = player_quests.begin(); itr != player_quests.end(); itr++){
|
||||
if(itr->second && itr->second->CheckQuestKillUpdate(spawn, update)){
|
||||
if(!quest_updates)
|
||||
|
@ -4659,14 +4663,14 @@ vector<Quest*>* Player::CheckQuestsKillUpdate(Spawn* spawn, bool update){
|
|||
quest_updates->push_back(itr->second);
|
||||
}
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return quest_updates;
|
||||
}
|
||||
|
||||
vector<Quest*>* Player::CheckQuestsChatUpdate(Spawn* spawn){
|
||||
vector<Quest*>* quest_updates = 0;
|
||||
map<int32, Quest*>::iterator itr;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
for(itr = player_quests.begin(); itr != player_quests.end(); itr++){
|
||||
if(itr->second && itr->second->CheckQuestChatUpdate(spawn->GetDatabaseID())){
|
||||
if(!quest_updates)
|
||||
|
@ -4674,54 +4678,46 @@ vector<Quest*>* Player::CheckQuestsChatUpdate(Spawn* spawn){
|
|||
quest_updates->push_back(itr->second);
|
||||
}
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return quest_updates;
|
||||
}
|
||||
|
||||
int16 Player::GetTaskGroupStep(int32 quest_id){
|
||||
Quest* quest = 0;
|
||||
int16 step = 0;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
if(player_quests.count(quest_id) > 0){
|
||||
quest = player_quests[quest_id];
|
||||
step = quest->GetTaskGroupStep();
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return step;
|
||||
}
|
||||
|
||||
bool Player::GetQuestStepComplete(int32 quest_id, int32 step_id){
|
||||
bool ret = false;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
if(player_quests.count(quest_id) > 0){
|
||||
Quest* quest = player_quests[quest_id];
|
||||
if ( quest != NULL )
|
||||
ret = quest->GetQuestStepCompleted(step_id);
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int16 Player::GetQuestStep(int32 quest_id){
|
||||
Quest* quest = 0;
|
||||
int16 step = 0;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
if(player_quests.count(quest_id) > 0){
|
||||
quest = player_quests[quest_id];
|
||||
step = quest->GetQuestStep();
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return step;
|
||||
}
|
||||
|
||||
void Player::LockQuests(){
|
||||
MPlayerQuests.lock();
|
||||
}
|
||||
|
||||
void Player::UnlockQuests(){
|
||||
MPlayerQuests.unlock();
|
||||
}
|
||||
|
||||
map<int32, Quest*>* Player::GetPlayerQuests(){
|
||||
return &player_quests;
|
||||
}
|
||||
|
@ -4777,19 +4773,19 @@ int8 Player::CheckQuestFlag(Spawn* spawn){
|
|||
vector<int32>* quests = spawn->GetProvidedQuests();
|
||||
Quest* quest = 0;
|
||||
for(int32 i=0;i<quests->size();i++){
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
if(player_quests.count(quests->at(i)) > 0){
|
||||
if(player_quests[quests->at(i)]->GetCompleted() && player_quests[quests->at(i)]->GetQuestReturnNPC() == spawn->GetDatabaseID()){
|
||||
ret = 2;
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
if (CanReceiveQuest(quests->at(i))){
|
||||
MPlayerQuests.lock();
|
||||
master_quest_list.LockQuests();
|
||||
quest = master_quest_list.GetQuest(quests->at(i), false);
|
||||
MPlayerQuests.unlock();
|
||||
master_quest_list.UnlockQuests();
|
||||
if(quest){
|
||||
int8 color = quest->GetFeatherColor();
|
||||
// purple
|
||||
|
@ -4810,12 +4806,12 @@ int8 Player::CheckQuestFlag(Spawn* spawn){
|
|||
}
|
||||
}
|
||||
map<int32, Quest*>::iterator itr;
|
||||
MPlayerQuests.lock();
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
for(itr = player_quests.begin(); itr != player_quests.end(); itr++){
|
||||
if(itr->second->CheckQuestChatUpdate(spawn->GetDatabaseID(), false))
|
||||
ret = 2;
|
||||
}
|
||||
MPlayerQuests.unlock();
|
||||
MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
if(ret > 0)
|
||||
current_quest_flagged[spawn] = true;
|
||||
return ret;
|
||||
|
@ -4824,9 +4820,9 @@ int8 Player::CheckQuestFlag(Spawn* spawn){
|
|||
bool Player::CanReceiveQuest(int32 quest_id){
|
||||
bool passed = true;
|
||||
int32 x;
|
||||
MPlayerQuests.lock();
|
||||
master_quest_list.LockQuests();
|
||||
Quest* quest = master_quest_list.GetQuest(quest_id, false);
|
||||
MPlayerQuests.unlock();
|
||||
master_quest_list.UnlockQuests();
|
||||
if (!quest)
|
||||
passed = false;
|
||||
//check if quest is already completed, and not repeatable
|
||||
|
@ -6770,4 +6766,13 @@ void Player::SetMentorStats(int32 effective_level, int32 target_char_id)
|
|||
}
|
||||
}
|
||||
GetEquipmentList()->SendEquippedItems(this);
|
||||
}
|
||||
|
||||
void Player::SetLevel(int16 level, bool setUpdateFlags) {
|
||||
if(!GetGroupMemberInfo() || GetGroupMemberInfo()->mentor_target_char_id == 0) {
|
||||
GetInfoStruct()->set_effective_level(level);
|
||||
}
|
||||
SetInfo(&appearance.level, level, setUpdateFlags);
|
||||
SetXP(0);
|
||||
SetNeededXP();
|
||||
}
|
|
@ -583,11 +583,7 @@ public:
|
|||
void ClearRemovedSpawn(Spawn* spawn);
|
||||
bool ShouldSendSpawn(Spawn* spawn);
|
||||
Client* client = 0;
|
||||
void SetLevel(int16 level, bool setUpdateFlags = true) {
|
||||
SetInfo(&appearance.level, level, setUpdateFlags);
|
||||
SetXP(0);
|
||||
SetNeededXP();
|
||||
}
|
||||
void SetLevel(int16 level, bool setUpdateFlags = true);
|
||||
|
||||
Spawn* GetSpawnWithPlayerID(int32 id){
|
||||
Spawn* spawn = 0;
|
||||
|
@ -666,8 +662,6 @@ public:
|
|||
map<int32, Quest*> player_quests;
|
||||
map<int32, Quest*>* GetPlayerQuests();
|
||||
map<int32, Quest*>* GetCompletedPlayerQuests();
|
||||
void LockQuests();
|
||||
void UnlockQuests();
|
||||
void SetFactionValue(int32 faction_id, sint32 value){
|
||||
factions.SetFactionValue(faction_id, value);
|
||||
}
|
||||
|
@ -995,6 +989,8 @@ public:
|
|||
{
|
||||
reset_mentorship = true;
|
||||
}
|
||||
|
||||
Mutex MPlayerQuests;
|
||||
private:
|
||||
bool reset_mentorship;
|
||||
bool range_attack;
|
||||
|
@ -1009,7 +1005,6 @@ private:
|
|||
map<int32, map<int32, bool> > pending_loot_items;
|
||||
Mutex MSpellsBook;
|
||||
Mutex MRecipeBook;
|
||||
Mutex MPlayerQuests;
|
||||
map<Spawn*, bool> current_quest_flagged;
|
||||
PlayerFaction factions;
|
||||
map<int32, Quest*> completed_quests;
|
||||
|
|
|
@ -324,6 +324,7 @@ void RuleManager::Init()
|
|||
RULE_INIT(R_Loot, AllowChestUnlockByDropTime, "1"); // when set to 1 we will start a countdown timer to allow anyone to loot once ChestUnlockedTimeDrop elapsed
|
||||
RULE_INIT(R_Loot, ChestUnlockedTimeTrap, "600"); // time in seconds, 10 minutes by default
|
||||
RULE_INIT(R_Loot, AllowChestUnlockByTrapTime, "1"); // when set to 1 we will allow unlocking the chest to all players after the trap is triggered (or chest is open) and period ChestUnlockedTimeTrap elapsed
|
||||
RULE_INIT(R_Loot, SkipLootGrayMob, "1");
|
||||
|
||||
RULE_INIT(R_Spells, NoInterruptBaseChance, "50");
|
||||
RULE_INIT(R_Spells, EnableFizzleSpells, "1"); // enables/disables the 'fizzling' of spells based on can_fizzle in the spells table. This also enables increasing specialized skills for classes based on spells/abilities.
|
||||
|
@ -340,6 +341,7 @@ void RuleManager::Init()
|
|||
RULE_INIT(R_Expansion, GlobalHolidayFlag, "0");
|
||||
|
||||
RULE_INIT(R_World, DatabaseVersion, "0");
|
||||
|
||||
#undef RULE_INIT
|
||||
}
|
||||
|
||||
|
|
|
@ -195,7 +195,9 @@ enum RuleType {
|
|||
GlobalExpansionFlag,
|
||||
GlobalHolidayFlag,
|
||||
|
||||
DatabaseVersion
|
||||
DatabaseVersion,
|
||||
|
||||
SkipLootGrayMob
|
||||
};
|
||||
|
||||
class Rule {
|
||||
|
|
|
@ -910,6 +910,24 @@ public:
|
|||
|
||||
MLootItems.unlock();
|
||||
}
|
||||
|
||||
void ClearNonBodyLoot() {
|
||||
|
||||
MLootItems.lock();
|
||||
vector<Item*>::iterator itr;
|
||||
for (itr = loot_items.begin(); itr != loot_items.end();) {
|
||||
Item* itm = *itr;
|
||||
if(!itm->IsBodyDrop())
|
||||
{
|
||||
itr = loot_items.erase(itr);
|
||||
safe_delete(itm);
|
||||
}
|
||||
else
|
||||
itr++;
|
||||
}
|
||||
MLootItems.unlock();
|
||||
}
|
||||
|
||||
int32 GetLootCoins() {
|
||||
return loot_coins;
|
||||
}
|
||||
|
@ -919,15 +937,6 @@ public:
|
|||
void AddLootCoins(int32 coins) {
|
||||
loot_coins += coins;
|
||||
}
|
||||
|
||||
void ClearLootList() {
|
||||
vector<Item*>::iterator itr;
|
||||
for (itr = loot_items.begin(); itr != loot_items.end(); itr++)
|
||||
safe_delete(*itr);
|
||||
|
||||
loot_items.clear();
|
||||
}
|
||||
|
||||
Spawn* GetTarget();
|
||||
void SetTarget(Spawn* spawn);
|
||||
Spawn* GetLastAttacker();
|
||||
|
|
|
@ -226,6 +226,7 @@ void World::init(){
|
|||
|
||||
|
||||
PacketStruct* World::GetWorldTime(int16 version){
|
||||
MWorldTime.readlock(__FUNCTION__, __LINE__);
|
||||
PacketStruct* packet = configReader.getStruct("WS_GameWorldTime", version);
|
||||
if(packet){
|
||||
packet->setDataByName("year", world_time.year);
|
||||
|
@ -237,6 +238,7 @@ PacketStruct* World::GetWorldTime(int16 version){
|
|||
packet->setDataByName("unix_time", Timer::GetUnixTimeStamp());
|
||||
packet->setDataByName("unknown2", 1);
|
||||
}
|
||||
MWorldTime.releasereadlock(__FUNCTION__, __LINE__);
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
@ -263,10 +265,21 @@ void World::Process(){
|
|||
if(last_checked_time > Timer::GetCurrentTime2())
|
||||
return;
|
||||
last_checked_time = Timer::GetCurrentTime2() + 1000;
|
||||
|
||||
if(save_time_timer.Check())
|
||||
{
|
||||
MWorldTime.readlock(__FUNCTION__, __LINE__);
|
||||
database.SaveWorldTime(&world_time);
|
||||
MWorldTime.releasereadlock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
if(time_tick_timer.Check())
|
||||
{
|
||||
MWorldTime.writelock(__FUNCTION__, __LINE__);
|
||||
WorldTimeTick();
|
||||
MWorldTime.releasewritelock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
if(vitality_timer.Check())
|
||||
UpdateVitality();
|
||||
if (player_stats_timer.Check())
|
||||
|
@ -350,7 +363,23 @@ void ZoneList::UpdateVitality(float amount)
|
|||
MZoneList.releasereadlock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
void ZoneList::SendTimeUpdate()
|
||||
{
|
||||
list<ZoneServer*>::iterator zone_iter;
|
||||
ZoneServer* tmp = 0;
|
||||
MZoneList.readlock(__FUNCTION__, __LINE__);
|
||||
|
||||
for(zone_iter=zlist.begin(); zone_iter!=zlist.end(); zone_iter++)
|
||||
{
|
||||
tmp = *zone_iter;
|
||||
if(tmp && !tmp->isZoneShuttingDown())
|
||||
tmp->WorldTimeUpdateTrigger();
|
||||
}
|
||||
|
||||
MZoneList.releasereadlock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// should already be ran inside MWorldTime
|
||||
void World::WorldTimeTick(){
|
||||
world_time.minute++;
|
||||
//I know it looks complicated, but the nested ifs are to avoid checking all of them every 3 seconds
|
||||
|
@ -661,7 +690,7 @@ bool ZoneList::ClientConnected(int32 account_id){
|
|||
map<string, Client*>::iterator itr;
|
||||
MClientList.lock();
|
||||
for(itr=client_map.begin(); itr != client_map.end(); itr++){
|
||||
if(itr->second && itr->second->GetAccountID() == account_id && (itr->second->GetPlayer()->GetActivityStatus() & ACTIVITY_STATUS_LINKDEAD) == 0){
|
||||
if(itr->second && itr->second->GetAccountID() == account_id && itr->second->getConnection() && itr->second->getConnection()->GetState() != CLOSING && itr->second->getConnection()->GetState() != CLOSED && (itr->second->GetPlayer()->GetActivityStatus() & ACTIVITY_STATUS_LINKDEAD) == 0){
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
@ -2542,4 +2571,9 @@ Map* World::GetMap(std::string zoneFile, int32 client_version)
|
|||
|
||||
MWorldMaps.releasereadlock();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void World::SendTimeUpdate()
|
||||
{
|
||||
zone_list.SendTimeUpdate();
|
||||
}
|
|
@ -490,6 +490,8 @@ class ZoneList {
|
|||
void ReloadSpawns();
|
||||
|
||||
void WatchdogHeartbeat();
|
||||
|
||||
void SendTimeUpdate();
|
||||
private:
|
||||
Mutex MClientList;
|
||||
Mutex MZoneList;
|
||||
|
@ -633,6 +635,13 @@ public:
|
|||
|
||||
void LoadMaps(std::string zoneFile);
|
||||
Map* GetMap(std::string zoneFile, int32 client_version);
|
||||
|
||||
void SendTimeUpdate();
|
||||
// just in case we roll over a time as to not send bad times to clients (days before hours, hours before minutes as examples)
|
||||
Mutex MWorldTime;
|
||||
|
||||
|
||||
|
||||
static sint64 newValue;
|
||||
private:
|
||||
int32 suppressed_warning = 0;
|
||||
|
|
|
@ -2513,7 +2513,7 @@ void WorldDatabase::SaveCharacterQuests(Client* client){
|
|||
Query query;
|
||||
map<int32, Quest*>::iterator itr;
|
||||
master_quest_list.LockQuests(); //prevent reloading until we are done
|
||||
client->GetPlayer()->LockQuests(); //prevent all quest modifications until we are done
|
||||
client->GetPlayer()->MPlayerQuests.writelock(__FUNCTION__, __LINE__); //prevent all quest modifications until we are done
|
||||
map<int32, Quest*>* quests = client->GetPlayer()->GetPlayerQuests();
|
||||
for(itr = quests->begin(); itr != quests->end(); itr++){
|
||||
if(client->GetCurrentQuestID() == itr->first){
|
||||
|
@ -2540,7 +2540,7 @@ void WorldDatabase::SaveCharacterQuests(Client* client){
|
|||
itr->second->SetSaveNeeded(false);
|
||||
}
|
||||
}
|
||||
client->GetPlayer()->UnlockQuests();
|
||||
client->GetPlayer()->MPlayerQuests.releasewritelock(__FUNCTION__, __LINE__);
|
||||
master_quest_list.UnlockQuests();
|
||||
|
||||
}
|
||||
|
|
|
@ -149,7 +149,6 @@ Client::Client(EQStream* ieqs) : pos_update(125), quest_pos_timer(2000), lua_deb
|
|||
connected_to_zone = false;
|
||||
connected = false;
|
||||
camp_timer = 0;
|
||||
disconnect_timer = 0;
|
||||
client_zoning = false;
|
||||
player_pos_changed = false;
|
||||
++numclients;
|
||||
|
@ -209,6 +208,28 @@ Client::Client(EQStream* ieqs) : pos_update(125), quest_pos_timer(2000), lua_deb
|
|||
}
|
||||
|
||||
Client::~Client() {
|
||||
RemoveClientFromZone();
|
||||
|
||||
//let the stream factory know were done with this stream
|
||||
if (eqs) {
|
||||
eqs->Close();
|
||||
try {
|
||||
eqs->ReleaseFromUse();
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
eqs = NULL;
|
||||
|
||||
//safe_delete(autobootup_timeout);
|
||||
|
||||
safe_delete(CLE_keepalive_timer);
|
||||
safe_delete(connect);
|
||||
--numclients;
|
||||
UpdateWindowTitle(0);
|
||||
}
|
||||
|
||||
|
||||
void Client::RemoveClientFromZone() {
|
||||
if (current_zone && player) {
|
||||
if (player->GetGroupMemberInfo())
|
||||
{
|
||||
|
@ -225,29 +246,7 @@ Client::~Client() {
|
|||
if (player)
|
||||
zone_list.RemoveClientFromMap(player->GetName(), this);
|
||||
|
||||
//let the stream factory know were done with this stream
|
||||
if (eqs) {
|
||||
eqs->Close();
|
||||
try {
|
||||
eqs->ReleaseFromUse();
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
eqs = NULL;
|
||||
|
||||
//safe_delete(autobootup_timeout);
|
||||
|
||||
safe_delete(disconnect_timer);
|
||||
safe_delete(camp_timer);
|
||||
safe_delete(CLE_keepalive_timer);
|
||||
safe_delete(connect);
|
||||
--numclients;
|
||||
|
||||
MDeletePlayer.writelock(__FUNCTION__, __LINE__);
|
||||
if (player && !player->GetPendingDeletion())
|
||||
safe_delete(player);
|
||||
MDeletePlayer.releasewritelock(__FUNCTION__, __LINE__);
|
||||
|
||||
safe_delete(search_items);
|
||||
safe_delete(current_rez.expire_timer);
|
||||
safe_delete(pending_last_name);
|
||||
|
@ -259,9 +258,14 @@ Client::~Client() {
|
|||
delete tmp;
|
||||
SetTempPlacementSpawn(nullptr);
|
||||
}
|
||||
UpdateWindowTitle(0);
|
||||
|
||||
MDeletePlayer.writelock(__FUNCTION__, __LINE__);
|
||||
if (player && !player->GetPendingDeletion())
|
||||
safe_delete(player);
|
||||
MDeletePlayer.releasewritelock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
|
||||
void Client::QueuePacket(EQ2Packet* app, bool attemptedCombine) {
|
||||
if (eqs) {
|
||||
if (!eqs->CheckActive()) {
|
||||
|
@ -383,6 +387,7 @@ void Client::SendLoginInfo() {
|
|||
|
||||
map<int32, Quest*>::iterator itr;
|
||||
Quest* quest = 0;
|
||||
GetPlayer()->MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
for (itr = player->player_quests.begin(); itr != player->player_quests.end(); itr++) {
|
||||
quest = itr->second;
|
||||
if (quest->IsTracked()) {
|
||||
|
@ -392,6 +397,7 @@ void Client::SendLoginInfo() {
|
|||
QueuePacket(itr->second->QuestJournalReply(version, GetNameCRC(), player));
|
||||
}
|
||||
}
|
||||
GetPlayer()->MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
|
||||
// SendAchievementsList();
|
||||
|
||||
|
@ -1214,6 +1220,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
|
|||
if (packet && packet->LoadPacketData(app->pBuffer, app->size)) {
|
||||
int32 quest_id = packet->getType_int32_ByName("quest_id");
|
||||
bool hidden = packet->getType_int8_ByName("visible") == 1 ? false : true;
|
||||
GetPlayer()->MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
map<int32, Quest*>* player_quests = player->GetPlayerQuests();
|
||||
if (player_quests) {
|
||||
if (player_quests->count(quest_id) > 0)
|
||||
|
@ -1223,6 +1230,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
|
|||
}
|
||||
else
|
||||
LogWrite(CCLIENT__ERROR, 0, "Client", "OP_QuestJournalSetVisibleMsg error: Unable to get player(%s) quests", player->GetName());
|
||||
GetPlayer()->MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
|
||||
safe_delete(packet);
|
||||
}
|
||||
|
@ -2238,10 +2246,12 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
|
|||
continue;
|
||||
LogWrite(CCLIENT__DEBUG, 5, "Client", "quest_id = %u", id);
|
||||
bool tracked = packet->getType_int8_ByName("quest_tracked_0", i) == 1 ? true : false;
|
||||
GetPlayer()->MPlayerQuests.writelock(__FUNCTION__, __LINE__);
|
||||
if (player->player_quests.count(id) > 0) {
|
||||
player->player_quests[id]->SetTracked(tracked);
|
||||
player->player_quests[id]->SetSaveNeeded(true);
|
||||
}
|
||||
GetPlayer()->MPlayerQuests.releasewritelock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
safe_delete(packet);
|
||||
|
@ -3022,7 +3032,7 @@ bool Client::Process(bool zone_process) {
|
|||
if(GetPlayer()->GetRegionMap())
|
||||
GetPlayer()->GetRegionMap()->TicRegionsNearSpawn(this->GetPlayer(), regionDebugMessaging ? this : nullptr);
|
||||
|
||||
if(player_pos_changed && IsReadyForUpdates() && ( !disconnect_timer || !disconnect_timer->Enabled())) {
|
||||
if(player_pos_changed && IsReadyForUpdates()) {
|
||||
//GetPlayer()->CalculateLocation();
|
||||
client_list.CheckPlayersInvisStatus(this);
|
||||
GetCurrentZone()->SendPlayerPositionChanges(GetPlayer());
|
||||
|
@ -3045,13 +3055,6 @@ bool Client::Process(bool zone_process) {
|
|||
lua_interface->UpdateDebugClients(this);
|
||||
if (quest_pos_timer.Check())
|
||||
CheckPlayerQuestsLocationUpdate();
|
||||
if (camp_timer && camp_timer->Check() && getConnection()) {
|
||||
ResetSendMail();
|
||||
getConnection()->SendDisconnect(false);
|
||||
safe_delete(camp_timer);
|
||||
disconnect_timer = new Timer(2000);
|
||||
disconnect_timer->Start();
|
||||
}
|
||||
if (player->GetSkills()->HasSkillUpdates()) {
|
||||
vector<Skill*>* skills = player->GetSkills()->GetSkillUpdates();
|
||||
if (skills) {
|
||||
|
@ -3066,10 +3069,6 @@ bool Client::Process(bool zone_process) {
|
|||
safe_delete(skills);
|
||||
}
|
||||
}
|
||||
if (disconnect_timer && disconnect_timer->Check()) {
|
||||
safe_delete(disconnect_timer);
|
||||
ret = false;
|
||||
}
|
||||
m_resurrect.writelock(__FUNCTION__, __LINE__);
|
||||
if (current_rez.should_delete || (current_rez.expire_timer && current_rez.expire_timer->Check(false))) {
|
||||
safe_delete(current_rez.expire_timer);
|
||||
|
@ -3096,6 +3095,7 @@ bool Client::Process(bool zone_process) {
|
|||
MQuestTimers.writelock(__FUNCTION__, __LINE__);
|
||||
if (quest_timers.size() > 0) {
|
||||
vector<int32>::iterator itr;
|
||||
GetPlayer()->MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
map<int32, Quest*>* player_quests = player->GetPlayerQuests();
|
||||
for (itr = quest_timers.begin(); itr != quest_timers.end(); itr++) {
|
||||
if (player_quests->count(*itr) > 0 && player_quests->at(*itr)->GetStepTimer() != 0) {
|
||||
|
@ -3106,10 +3106,11 @@ bool Client::Process(bool zone_process) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
quest_timers.erase(itr);
|
||||
itr = quest_timers.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
GetPlayer()->MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
MQuestTimers.releasewritelock(__FUNCTION__, __LINE__);
|
||||
|
||||
|
@ -3119,6 +3120,14 @@ bool Client::Process(bool zone_process) {
|
|||
if (player->ControlFlagsChanged())
|
||||
player->SendControlFlagUpdates(this);
|
||||
|
||||
if (camp_timer && camp_timer->Check()) {
|
||||
ResetSendMail();
|
||||
if(getConnection())
|
||||
getConnection()->SendDisconnect(false);
|
||||
safe_delete(camp_timer);
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if (!eqs || (eqs && !eqs->CheckActive()))
|
||||
ret = false;
|
||||
|
||||
|
@ -4338,11 +4347,6 @@ void Client::ChangeLevel(int16 old_level, int16 new_level) {
|
|||
}
|
||||
|
||||
if (player->GetLevel() != new_level) {
|
||||
if(!player->GetGroupMemberInfo() || !player->GetGroupMemberInfo()->mentor_target_char_id)
|
||||
{
|
||||
player->GetInfoStruct()->set_effective_level(new_level);
|
||||
}
|
||||
|
||||
player->SetLevel(new_level);
|
||||
if (player->GetGroupMemberInfo()) {
|
||||
player->UpdateGroupMemberInfo();
|
||||
|
@ -5454,13 +5458,15 @@ void Client::AddPendingQuest(Quest* quest, bool forced) {
|
|||
}
|
||||
|
||||
Quest* Client::GetActiveQuest(int32 quest_id) {
|
||||
Quest* quest = 0;
|
||||
GetPlayer()->MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
if (player->player_quests.count(quest_id) > 0) {
|
||||
LogWrite(CCLIENT__DEBUG, 0, "Client", "Found %u active quests for char_id: %u", player->player_quests.count(quest_id), player->GetCharacterID());
|
||||
|
||||
return player->player_quests[quest_id];
|
||||
quest = player->player_quests[quest_id];
|
||||
}
|
||||
|
||||
return 0;
|
||||
GetPlayer()->MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
|
||||
|
||||
return quest;
|
||||
}
|
||||
|
||||
void Client::AcceptQuest(int32 id) {
|
||||
|
@ -5515,6 +5521,7 @@ void Client::SetPlayerQuest(Quest* quest, map<int32, int32>* progress) {
|
|||
}
|
||||
|
||||
void Client::AddPlayerQuest(Quest* quest, bool call_accepted, bool send_packets) {
|
||||
GetPlayer()->MPlayerQuests.writelock(__FUNCTION__, __LINE__);
|
||||
if (player->player_quests.count(quest->GetQuestID()) > 0) {
|
||||
if (player->player_quests[quest->GetQuestID()]->GetQuestFlags() > 0)
|
||||
quest->SetQuestFlags(player->player_quests[quest->GetQuestID()]->GetQuestFlags());
|
||||
|
@ -5522,6 +5529,8 @@ void Client::AddPlayerQuest(Quest* quest, bool call_accepted, bool send_packets)
|
|||
RemovePlayerQuest(quest->GetQuestID(), false, false);
|
||||
}
|
||||
player->player_quests[quest->GetQuestID()] = quest;
|
||||
GetPlayer()->MPlayerQuests.releasewritelock(__FUNCTION__, __LINE__);
|
||||
|
||||
quest->SetPlayer(player);
|
||||
current_quest_id = quest->GetQuestID();
|
||||
if (send_packets && quest->GetQuestGiver() > 0)
|
||||
|
@ -5550,13 +5559,17 @@ void Client::AddPlayerQuest(Quest* quest, bool call_accepted, bool send_packets)
|
|||
void Client::RemovePlayerQuest(int32 id, bool send_update, bool delete_quest) {
|
||||
if (current_quest_id == id)
|
||||
current_quest_id = 0;
|
||||
GetPlayer()->MPlayerQuests.writelock(__FUNCTION__, __LINE__);
|
||||
if (player->player_quests.count(id) > 0) {
|
||||
if (delete_quest) {
|
||||
player->player_quests[id]->SetDeleted(true);
|
||||
database.DeleteCharacterQuest(id, GetCharacterID(), player->GetCompletedPlayerQuests()->count(id) > 0);
|
||||
}
|
||||
if (send_update && player->player_quests[id]->GetQuestGiver() > 0)
|
||||
GetCurrentZone()->SendSpawnChangesByDBID(player->player_quests[id]->GetQuestGiver(), this, false, true);
|
||||
int32 quest_giver = player->player_quests[id]->GetQuestGiver();
|
||||
GetPlayer()->MPlayerQuests.releasewritelock(__FUNCTION__, __LINE__);
|
||||
|
||||
if (send_update && quest_giver > 0)
|
||||
GetCurrentZone()->SendSpawnChangesByDBID(quest_giver, this, false, true);
|
||||
if (send_update) {
|
||||
LogWrite(CCLIENT__DEBUG, 0, "Client", "Send Quest Journal...");
|
||||
SendQuestJournal(false, 0, true);
|
||||
|
@ -5568,6 +5581,10 @@ void Client::RemovePlayerQuest(int32 id, bool send_update, bool delete_quest) {
|
|||
GetCurrentZone()->SendAllSpawnsForVisChange(this);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if we don't have any quests to count then release the write lock
|
||||
GetPlayer()->MPlayerQuests.releasewritelock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -146,6 +146,7 @@ public:
|
|||
Client(EQStream* ieqs);
|
||||
~Client();
|
||||
|
||||
void RemoveClientFromZone();
|
||||
bool Process(bool zone_process = false);
|
||||
void Disconnect(bool send_disconnect = true);
|
||||
void SetConnected(bool val){ connected = val; }
|
||||
|
@ -546,7 +547,6 @@ private:
|
|||
Timer* CLE_keepalive_timer;
|
||||
Timer* connect;
|
||||
Timer* camp_timer;
|
||||
Timer* disconnect_timer;
|
||||
bool connected;
|
||||
bool ready_for_spawns;
|
||||
bool ready_for_updates;
|
||||
|
|
|
@ -1414,9 +1414,10 @@ bool ZoneServer::Process()
|
|||
|
||||
if(lua_interface)
|
||||
lua_interface->Process();
|
||||
|
||||
world.MWorldTime.readlock(__FUNCTION__, __LINE__);
|
||||
int hour = world.GetWorldTimeStruct()->hour;
|
||||
int minute = world.GetWorldTimeStruct()->minute;
|
||||
world.MWorldTime.releasereadlock(__FUNCTION__, __LINE__);
|
||||
|
||||
if (!isDusk && (hour >= 19 || hour < 8)) {//((hour > dusk_hour || hour < dawn_hour) || ((dusk_hour == hour && minute >= dusk_minute) || (hour == dawn_hour && minute < dawn_minute)))) {
|
||||
isDusk = true;
|
||||
|
@ -2350,6 +2351,31 @@ void ZoneServer::ProcessSpawnLocations()
|
|||
}
|
||||
|
||||
void ZoneServer::AddLoot(NPC* npc, Spawn* killer){
|
||||
// this function is ran twice, first on spawn of mob, then at death of mob (gray mob check and no_drop_quest_completed_id check)
|
||||
|
||||
// first we see if the skipping of gray mobs loot is enabled, then we move all non body drops
|
||||
if(killer)
|
||||
{
|
||||
int8 skip_loot_gray_mob_flag = rule_manager.GetGlobalRule(R_Loot, SkipLootGrayMob)->GetInt8();
|
||||
if(skip_loot_gray_mob_flag) {
|
||||
Player* player = 0;
|
||||
if(killer->IsPlayer())
|
||||
player = (Player*)killer;
|
||||
else if(killer->IsPet()) {
|
||||
Spawn* owner = ((Entity*)killer)->GetOwner();
|
||||
if(owner->IsPlayer())
|
||||
player = (Player*)owner;
|
||||
}
|
||||
if(player) {
|
||||
int8 difficulty = player->GetArrowColor(npc->GetLevel());
|
||||
if(difficulty == ARROW_COLOR_GRAY) {
|
||||
npc->ClearNonBodyLoot();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for starting loot of Spawn and death of Spawn loot (no_drop_quest_completed_id)
|
||||
vector<int32> loot_tables = GetSpawnLootList(npc->GetDatabaseID(), GetZoneID(), npc->GetLevel(), race_types_list.GetRaceType(npc->GetModelType()), npc);
|
||||
if(loot_tables.size() > 0){
|
||||
vector<LootDrop*>* loot_drops = 0;
|
||||
|
@ -4135,7 +4161,20 @@ void ZoneServer::SendCalculatedXP(Player* player, Spawn* victim){
|
|||
group->MGroupMembers.readlock(__FUNCTION__, __LINE__);
|
||||
deque<GroupMemberInfo*>* members = group->GetMembers();
|
||||
deque<GroupMemberInfo*>::iterator itr;
|
||||
bool skipGrayMob = false;
|
||||
|
||||
for (itr = members->begin(); itr != members->end(); itr++) {
|
||||
GroupMemberInfo* gmi = *itr;
|
||||
if (gmi->client) {
|
||||
Player* group_member = gmi->client->GetPlayer();
|
||||
if(group_member && group_member->GetArrowColor(victim->GetLevel()) == ARROW_COLOR_GRAY) {
|
||||
skipGrayMob = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (itr = members->begin(); !skipGrayMob && itr != members->end(); itr++) {
|
||||
GroupMemberInfo* gmi = *itr;
|
||||
if (gmi->client) {
|
||||
Player* group_member = gmi->client->GetPlayer();
|
||||
|
|
|
@ -679,6 +679,8 @@ public:
|
|||
void QueueDefaultCommand(int32 spawn_id, std::string command, float distance);
|
||||
void ProcessQueuedStateCommands();
|
||||
void UpdateClientSpawnMap(Player* player, Client* client);
|
||||
|
||||
void WorldTimeUpdateTrigger() { sync_game_time_timer.Trigger(); }
|
||||
private:
|
||||
#ifndef WIN32
|
||||
pthread_t ZoneThread;
|
||||
|
|
Loading…
Add table
Reference in a new issue