void Client::ResetAA() { SendClearAA(); RefundAA(); memset(&m_pp.aa_array[0], 0, sizeof(AA_Array) * MAX_PP_AA_ARRAY); int i = 0; for(auto &rank_value : aa_ranks) { auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(rank_value.first, rank_value.second.first); auto ability = ability_rank.first; auto rank = ability_rank.second; if(!rank) { continue; } m_pp.aa_array[i].AA = rank_value.first; m_pp.aa_array[i].value = rank_value.second.first; m_pp.aa_array[i].charges = rank_value.second.second; ++i; } for(int i = 0; i < _maxLeaderAA; ++i) m_pp.leader_abilities.ranks[i] = 0; m_pp.group_leadership_points = 0; m_pp.raid_leadership_points = 0; m_pp.group_leadership_exp = 0; m_pp.raid_leadership_exp = 0; database.DeleteCharacterLeadershipAAs(CharacterID()); // undefined for these clients if (GetClientVersionBit() & BIT_TitaniumAndEarlier) Kick(); }
void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm) { bool ReadyToZone = true; int iZoneNameLength = 0; const char* pShortZoneName = nullptr; char* pZoneName = nullptr; pShortZoneName = database.GetZoneName(zoneID); database.GetZoneLongName(pShortZoneName, &pZoneName); SetPortExemption(true); if(!pZoneName) { Message(13, "Invalid zone number specified"); safe_delete_array(pZoneName); return; } iZoneNameLength = strlen(pZoneName); switch(zm) { case EvacToSafeCoords: case ZoneToSafeCoords: x = zone->safe_x(); y = zone->safe_y(); z = zone->safe_z(); SetHeading(heading); break; case GMSummon: zonesummon_x = x_pos = x; zonesummon_y = y_pos = y; zonesummon_z = z_pos = z; SetHeading(heading); zonesummon_id = zoneID; zonesummon_ignorerestrictions = 1; break; case ZoneSolicited: zonesummon_x = x; zonesummon_y = y; zonesummon_z = z; SetHeading(heading); zonesummon_id = zoneID; zonesummon_ignorerestrictions = ignorerestrictions; break; case GateToBindPoint: x = x_pos = m_pp.binds[0].x; y = y_pos = m_pp.binds[0].y; z = z_pos = m_pp.binds[0].z; heading = m_pp.binds[0].heading; break; case ZoneToBindPoint: x = x_pos = m_pp.binds[0].x; y = y_pos = m_pp.binds[0].y; z = z_pos = m_pp.binds[0].z; heading = m_pp.binds[0].heading; zonesummon_ignorerestrictions = 1; LogFile->write(EQEMuLog::Debug, "Player %s has died and will be zoned to bind point in zone: %s at LOC x=%f, y=%f, z=%f, heading=%f", GetName(), pZoneName, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, m_pp.binds[0].heading); break; case SummonPC: zonesummon_x = x_pos = x; zonesummon_y = y_pos = y; zonesummon_z = z_pos = z; SetHeading(heading); break; case Rewind: LogFile->write(EQEMuLog::Debug, "%s has requested a /rewind from %f, %f, %f, to %f, %f, %f in %s", GetName(), x_pos, y_pos, z_pos, rewind_x, rewind_y, rewind_z, zone->GetShortName()); zonesummon_x = x_pos = x; zonesummon_y = y_pos = y; zonesummon_z = z_pos = z; SetHeading(heading); break; default: LogFile->write(EQEMuLog::Error, "Client::ZonePC() received a reguest to perform an unsupported client zone operation."); ReadyToZone = false; break; } if(ReadyToZone) { zone_mode = zm; if(zm == ZoneToBindPoint) { EQApplicationPacket* outapp = new EQApplicationPacket(OP_ZonePlayerToBind, sizeof(ZonePlayerToBind_Struct) + iZoneNameLength); ZonePlayerToBind_Struct* gmg = (ZonePlayerToBind_Struct*) outapp->pBuffer; // If we are SoF and later and are respawning from hover, we want the real zone ID, else zero to use the old hack. // if((GetClientVersionBit() & BIT_SoFAndLater) && (!RuleB(Character, RespawnFromHover) || !IsHoveringForRespawn())) gmg->bind_zone_id = 0; else gmg->bind_zone_id = zoneID; gmg->x = x; gmg->y = y; gmg->z = z; gmg->heading = heading; strcpy(gmg->zone_name, pZoneName); outapp->priority = 6; FastQueuePacket(&outapp); safe_delete(outapp); } else if(zm == ZoneSolicited || zm == ZoneToSafeCoords) { EQApplicationPacket* outapp = new EQApplicationPacket(OP_RequestClientZoneChange, sizeof(RequestClientZoneChange_Struct)); RequestClientZoneChange_Struct* gmg = (RequestClientZoneChange_Struct*) outapp->pBuffer; gmg->zone_id = zoneID; gmg->x = x; gmg->y = y; gmg->z = z; gmg->heading = heading; gmg->instance_id = instance_id; gmg->type = 0x01; //an observed value, not sure of meaning outapp->priority = 6; FastQueuePacket(&outapp); safe_delete(outapp); } else if(zm == EvacToSafeCoords) { EQApplicationPacket* outapp = new EQApplicationPacket(OP_RequestClientZoneChange, sizeof(RequestClientZoneChange_Struct)); RequestClientZoneChange_Struct* gmg = (RequestClientZoneChange_Struct*) outapp->pBuffer; // if we are in the same zone we want to evac to, client will not send OP_ZoneChange back to do an actual // zoning of the client, so we have to send a viable zoneid that the client *could* zone to to make it believe // we are leaving the zone, even though we are not. We have to do this because we are missing the correct op code // and struct that should be used for evac/succor. // 213 is Plane of War // 76 is orignial Plane of Hate // WildcardX 27 January 2008. Tested this for 6.2 and Titanium clients. if(this->GetZoneID() == 1) gmg->zone_id = 2; else if(this->GetZoneID() == 2) gmg->zone_id = 1; else gmg->zone_id = 1; gmg->x = x; gmg->y = y; gmg->z = z; gmg->heading = heading; gmg->instance_id = instance_id; gmg->type = 0x01; // '0x01' was an observed value for the type field, not sure of meaning // we hide the real zoneid we want to evac/succor to here zonesummon_id = zoneID; outapp->priority = 6; FastQueuePacket(&outapp); safe_delete(outapp); } else { if(zoneID == GetZoneID()) { //properly handle proximities entity_list.ProcessMove(this, x_pos, y_pos, z_pos); proximity_x = x_pos; proximity_y = y_pos; proximity_z = z_pos; //send out updates to people in zone. SendPosition(); } EQApplicationPacket* outapp = new EQApplicationPacket(OP_RequestClientZoneChange, sizeof(RequestClientZoneChange_Struct)); RequestClientZoneChange_Struct* gmg = (RequestClientZoneChange_Struct*) outapp->pBuffer; gmg->zone_id = zoneID; gmg->x = x; gmg->y = y; gmg->z = z; gmg->heading = heading; gmg->instance_id = instance_id; gmg->type = 0x01; //an observed value, not sure of meaning outapp->priority = 6; FastQueuePacket(&outapp); safe_delete(outapp); } _log(NET__DEBUG, "Player %s has requested a zoning to LOC x=%f, y=%f, z=%f, heading=%f in zoneid=%i", GetName(), x, y, z, heading, zoneID); //Clear zonesummon variables if we're zoning to our own zone //Client wont generate a zone change packet to the server in this case so //They aren't needed and it keeps behavior on next zone attempt from being undefined. if(zoneID == zone->GetZoneID() && instance_id == zone->GetInstanceID()) { if(zm != EvacToSafeCoords && zm != ZoneToSafeCoords && zm != ZoneToBindPoint) { zonesummon_x = 0; zonesummon_y = 0; zonesummon_z = 0; zonesummon_id = 0; zonesummon_ignorerestrictions = 0; zone_mode = ZoneUnsolicited; } } } safe_delete_array(pZoneName); }