// deleting the auto pointer deletes what the internal pointer points to... CMclKernelAutoPtr::~CMclKernelAutoPtr() { // no check needed since deleting a NULL // pointer is okay in C++... safe_delete( m_pObjectPtr ); }
//if itemlist is null, just send wear changes void NPC::AddLootDrop(const EQEmu::ItemBase *item2, ItemList* itemlist, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange) { if(item2 == nullptr) return; //make sure we are doing something... if(!itemlist && !wearchange) return; auto item = new ServerLootItem_Struct; #if EQDEBUG>=11 Log.Out(Logs::General, Logs::None, "Adding drop to npc: %s, Item: %i", GetName(), item2->ID); #endif EQApplicationPacket* outapp = nullptr; WearChange_Struct* wc = nullptr; if(wearchange) { outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct)); wc = (WearChange_Struct*)outapp->pBuffer; wc->spawn_id = GetID(); wc->material=0; } item->item_id = item2->ID; item->charges = charges; item->aug_1 = 0; item->aug_2 = 0; item->aug_3 = 0; item->aug_4 = 0; item->aug_5 = 0; item->aug_6 = 0; item->attuned = 0; item->min_level = minlevel; item->max_level = maxlevel; if (equipit) { uint8 eslot = 0xFF; char newid[20]; const EQEmu::ItemBase* compitem = nullptr; bool found = false; // track if we found an empty slot we fit into int32 foundslot = -1; // for multi-slot items // Equip rules are as follows: // If the item has the NoPet flag set it will not be equipped. // An empty slot takes priority. The first empty one that an item can // fit into will be the one picked for the item. // AC is the primary choice for which item gets picked for a slot. // If AC is identical HP is considered next. // If an item can fit into multiple slots we'll pick the last one where // it is an improvement. if (!item2->NoPet) { for (int i = 0; !found && i < EQEmu::legacy::EQUIPMENT_SIZE; i++) { uint32 slots = (1 << i); if (item2->Slots & slots) { if(equipment[i]) { compitem = database.GetItem(equipment[i]); if (item2->AC > compitem->AC || (item2->AC == compitem->AC && item2->HP > compitem->HP)) { // item would be an upgrade // check if we're multi-slot, if yes then we have to keep // looking in case any of the other slots we can fit into are empty. if (item2->Slots != slots) { foundslot = i; } else { equipment[i] = item2->ID; foundslot = i; found = true; } } // end if ac } else { equipment[i] = item2->ID; foundslot = i; found = true; } } // end if (slots) } // end for } // end if NoPet // Possible slot was found but not selected. Pick it now. if (!found && foundslot >= 0) { equipment[foundslot] = item2->ID; found = true; } // @merth: IDFile size has been increased, this needs to change uint16 emat; if(item2->Material <= 0 || item2->Slots & (1 << EQEmu::legacy::SlotPrimary | 1 << EQEmu::legacy::SlotSecondary)) { memset(newid, 0, sizeof(newid)); for(int i=0;i<7;i++){ if (!isalpha(item2->IDFile[i])){ strn0cpy(newid, &item2->IDFile[i],6); i=8; } } emat = atoi(newid); } else { emat = item2->Material; } if (foundslot == EQEmu::legacy::SlotPrimary) { if (item2->Proc.Effect != 0) CastToMob()->AddProcToWeapon(item2->Proc.Effect, true); eslot = EQEmu::textures::TexturePrimary; if (item2->Damage > 0) SendAddPlayerState(PlayerState::PrimaryWeaponEquipped); if (item2->IsType2HWeapon()) SetTwoHanderEquipped(true); } else if (foundslot == EQEmu::legacy::SlotSecondary && (GetOwner() != nullptr || (CanThisClassDualWield() && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) && (item2->IsType1HWeapon() || item2->ItemType == EQEmu::item::ItemTypeShield)) { if (item2->Proc.Effect!=0) CastToMob()->AddProcToWeapon(item2->Proc.Effect, true); eslot = EQEmu::textures::TextureSecondary; if (item2->Damage > 0) SendAddPlayerState(PlayerState::SecondaryWeaponEquipped); } else if (foundslot == EQEmu::legacy::SlotHead) { eslot = EQEmu::textures::TextureHead; } else if (foundslot == EQEmu::legacy::SlotChest) { eslot = EQEmu::textures::TextureChest; } else if (foundslot == EQEmu::legacy::SlotArms) { eslot = EQEmu::textures::TextureArms; } else if (foundslot == EQEmu::legacy::SlotWrist1 || foundslot == EQEmu::legacy::SlotWrist2) { eslot = EQEmu::textures::TextureWrist; } else if (foundslot == EQEmu::legacy::SlotHands) { eslot = EQEmu::textures::TextureHands; } else if (foundslot == EQEmu::legacy::SlotLegs) { eslot = EQEmu::textures::TextureLegs; } else if (foundslot == EQEmu::legacy::SlotFeet) { eslot = EQEmu::textures::TextureFeet; } /* what was this about??? if (((npc->GetRace()==127) && (npc->CastToMob()->GetOwnerID()!=0)) && (item2->Slots==24576) || (item2->Slots==8192) || (item2->Slots==16384)){ npc->d_melee_texture2=atoi(newid); wc->wear_slot_id=8; if (item2->Material >0) wc->material=item2->Material; else wc->material=atoi(newid); npc->AC+=item2->AC; npc->STR+=item2->STR; npc->INT+=item2->INT; } */ //if we found an open slot it goes in... if(eslot != 0xFF) { if(wearchange) { wc->wear_slot_id = eslot; wc->material = emat; } } if (found) { CalcBonuses(); // This is less than ideal for bulk adding of items } item->equip_slot = item2->Slots; } if(itemlist != nullptr) itemlist->push_back(item); else safe_delete(item); if(wearchange && outapp) { entity_list.QueueClients(this, outapp); safe_delete(outapp); } UpdateEquipmentLight(); if (UpdateActiveLight()) SendAppearancePacket(AT_Light, GetActiveLightType()); }
void HGTController::fillDownloadList(bool &usingDiffs) { usingDiffs = false; safe_delete(m_vSuperBlockList); MCFCore::MCF *webMcf = new MCFCore::MCF(); try { webMcf->dlHeaderFromHttp(m_szUrl.c_str()); } catch (gcException &e) { onErrorEvent(e); safe_delete(webMcf); return; } webMcf->sortFileList(); uint64 mcfOffset = m_pHeader->getSize(); size_t fsSize = m_rvFileList.size(); //find the last files offset for (size_t x=0; x< fsSize; x++) { if (!m_rvFileList[x]->isSaved()) continue; if ((m_rvFileList[x]->isComplete() || m_rvFileList[x]->hasStartedDL()) && m_rvFileList[x]->getOffSet() > mcfOffset) { mcfOffset = m_rvFileList[x]->getOffSet() + m_rvFileList[x]->getCurSize(); } } std::deque<Misc::WGTBlock*> vBlockList; std::sort(m_rvFileList.begin(), m_rvFileList.end(), SortByOffset); for (size_t x=0; x<fsSize; x++) { //dont download all ready downloaded items if (m_rvFileList[x]->isComplete()) continue; //skip files that arnt "saved" in the MCF if (!m_rvFileList[x]->isSaved()) continue; uint32 index = webMcf->findFileIndexByHash(m_rvFileList[x]->getHash()); auto webFile = webMcf->getFile(index); uint64 size = m_rvFileList[x]->getCurSize(); bool started = m_rvFileList[x]->hasStartedDL(); if (index == UNKNOWN_ITEM || !webFile || !webFile->isSaved()) { Warning(gcString("File {0} is not in web MCF. Skipping download.\n", m_rvFileList[x]->getName())); if (!started) m_rvFileList[x]->delFlag(MCFCore::MCFFileI::FLAG_SAVE); continue; } if (!started) m_rvFileList[x]->setOffSet(mcfOffset); Misc::WGTBlock* temp = new Misc::WGTBlock; temp->fileOffset = m_rvFileList[x]->getOffSet(); temp->file = m_rvFileList[x]; if (webFile->hasDiff() && HasAllFlags(m_rvFileList[x]->getFlags(), MCFFileI::FLAG_CANUSEDIFF)) { temp->webOffset = webFile->getDiffOffSet(); temp->size = webFile->getDiffSize(); if (!started) mcfOffset += webFile->getSize(); usingDiffs = true; } else { m_rvFileList[x]->delFlag(MCFFileI::FLAG_CANUSEDIFF); temp->webOffset = webFile->getOffSet(); temp->size = size; if (!started) mcfOffset += size; } vBlockList.push_back(temp); m_uiTotal += temp->size; } std::sort(vBlockList.begin(), vBlockList.end(), &WGTBlockSort); while (vBlockList.size() > 0) { Misc::WGTSuperBlock* sb = new Misc::WGTSuperBlock(); sb->offset = vBlockList[0]->webOffset; do { Misc::WGTBlock* block = vBlockList.front(); vBlockList.pop_front(); sb->size += block->size; sb->vBlockList.push_back(block); } while (vBlockList.size() > 0 && vBlockList[0]->webOffset == (sb->offset + sb->size)); m_vSuperBlockList.push_back(sb); } }
bool Group::DelMember(Mob* oldmember,bool ignoresender) { if (oldmember == nullptr) { return false; } for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) { if (members[i] == oldmember) { members[i] = nullptr; membername[i][0] = '\0'; memset(membername[i],0,64); MemberRoles[i] = 0; Log.Out(Logs::Detail, Logs::Group, "DelMember: Removed Member: %s", oldmember->GetCleanName()); break; } } if(GroupCount() < 2) { DisbandGroup(); return true; } // If the leader has quit and we have 2 or more players left in group, we want to first check the zone the old leader was in for a new leader. // If a suitable replacement cannot be found, we need to go out of zone. If checkleader remains true after this method completes, another // loop will be run in DelMemberOOZ. bool checkleader = true; if (strcmp(GetOldLeaderName(),oldmember->GetCleanName()) == 0 && GroupCount() >= 2) { for(uint32 nl = 0; nl < MAX_GROUP_MEMBERS; nl++) { if(members[nl]) { if (members[nl]->IsClient()) { ChangeLeader(members[nl]); checkleader = false; break; } } } } ServerPacket* pack = new ServerPacket(ServerOP_GroupLeave, sizeof(ServerGroupLeave_Struct)); ServerGroupLeave_Struct* gl = (ServerGroupLeave_Struct*)pack->pBuffer; gl->gid = GetID(); gl->zoneid = zone->GetZoneID(); gl->instance_id = zone->GetInstanceID(); strcpy(gl->member_name, oldmember->GetName()); gl->checkleader = checkleader; worldserver.SendPacket(pack); safe_delete(pack); EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); GroupJoin_Struct* gu = (GroupJoin_Struct*)outapp->pBuffer; gu->action = groupActLeave; strcpy(gu->membername, oldmember->GetCleanName()); strcpy(gu->yourname, oldmember->GetCleanName()); for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) { if (members[i] == nullptr) { //if (DEBUG>=5) Log.Out(Logs::Detail, Logs::Group, "Group::DelMember() null member at slot %i", i); continue; } if (members[i] != oldmember) { strcpy(gu->yourname, members[i]->GetCleanName()); if(members[i]->IsClient()) members[i]->CastToClient()->QueuePacket(outapp); } } if (!ignoresender) { strcpy(gu->yourname,oldmember->GetCleanName()); strcpy(gu->membername,oldmember->GetCleanName()); gu->action = groupActLeave; if(oldmember->IsClient()) oldmember->CastToClient()->QueuePacket(outapp); } if(oldmember->IsClient()) { database.SetGroupID(oldmember->GetCleanName(), 0, oldmember->CastToClient()->CharacterID()); } oldmember->SetGrouped(false); disbandcheck = true; safe_delete(outapp); return true; }
bool Database::DBLoadDoors(uint32 iDoorCount, uint32 iMaxDoorID) { cout << "Loading Doors from database..." << endl; char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; MYSQL_RES *result; MYSQL_ROW row; query = new char[256]; strcpy(query, "SELECT MAX(id), Count(*) FROM doors"); if (RunQuery(query, strlen(query), errbuf, &result)) { safe_delete(query); row = mysql_fetch_row(result); if (row && row[0]) { if (atoi(row[0]) > iMaxDoorID) { cout << "Error: Insufficient shared memory to load doors." << endl; cout << "Max(id): " << atoi(row[0]) << ", iMaxDoorID: " << iMaxDoorID << endl; cout << "Fix this by increasing the MMF_MAX_Door_ID define statement" << endl; return false; } if (atoi(row[1]) != iDoorCount) { cout << "Error: Insufficient shared memory to load doors." << endl; cout << "Count(*): " << atoi(row[1]) << ", iDoorCount: " << iDoorCount << endl; return false; } max_door_type = atoi(row[0]); mysql_free_result(result); Door tmpDoor; MakeAnyLenString(&query, "SELECT id,doorid,zone,name,pos_x,pos_y,pos_z,heading,opentype,guild,lockpick,keyitem,triggerdoor,triggertype from doors");//WHERE zone='%s'", zone_name if (RunQuery(query, strlen(query), errbuf, &result)) { safe_delete(query); while((row = mysql_fetch_row(result))) { memset(&tmpDoor, 0, sizeof(Door)); tmpDoor.db_id = atoi(row[0]); tmpDoor.door_id = atoi(row[1]); strn0cpy(tmpDoor.zone_name,row[2],32); strn0cpy(tmpDoor.door_name,row[3],32); tmpDoor.pos_x = (float)atof(row[4]); tmpDoor.pos_y = (float)atof(row[5]); tmpDoor.pos_z = (float)atof(row[6]); tmpDoor.heading = atoi(row[7]); tmpDoor.opentype = atoi(row[8]); tmpDoor.guild_id = atoi(row[9]); tmpDoor.lockpick = atoi(row[10]); tmpDoor.keyitem = atoi(row[11]); tmpDoor.trigger_door = atoi(row[12]); tmpDoor.trigger_type = atoi(row[13]); EMuShareMemDLL.Doors.cbAddDoor(tmpDoor.db_id, &tmpDoor); Sleep(0); } mysql_free_result(result); } else { cerr << "Error in DBLoadDoors query '" << query << "' " << errbuf << endl; delete[] query; return false; } } } return true; }
void Trap::Trigger(Mob* trigger) { Log.Out(Logs::General, Logs::Traps, "Trap %d triggered by %s for the %d time!", trap_id, trigger->GetName(), times_triggered+1); int i = 0; const NPCType* tmp = 0; switch (effect) { case trapTypeDebuff: if(message.empty()) { entity_list.MessageClose(trigger,false,100,CC_Default,"%s triggers a trap!",trigger->GetName()); } else { entity_list.MessageClose(trigger,false,100,CC_Default,"%s",message.c_str()); } if(hiddenTrigger){ hiddenTrigger->SpellFinished(effectvalue, trigger, 10, 0, -1, spells[effectvalue].ResistDiff); } break; case trapTypeAlarm: if (message.empty()) { entity_list.MessageClose(trigger,false,effectvalue,CC_Default,"A loud alarm rings out through the air..."); } else { entity_list.MessageClose(trigger,false,effectvalue,CC_Default,"%s",message.c_str()); } entity_list.SendAlarm(this,trigger,effectvalue2); break; case trapTypeMysticSpawn: if (message.empty()) { entity_list.MessageClose(trigger,false,100,CC_Default,"The air shimmers..."); } else { entity_list.MessageClose(trigger,false,100,CC_Default,"%s",message.c_str()); } for (i = 0; i < effectvalue2; i++) { if ((tmp = database.GetNPCType(effectvalue))) { auto randomOffset = glm::vec4(zone->random.Int(-5, 5),zone->random.Int(-5, 5),zone->random.Int(-5, 5), zone->random.Int(0, 249)); auto spawnPosition = randomOffset + glm::vec4(m_Position, 0.0f); NPC* new_npc = new NPC(tmp, nullptr, spawnPosition, FlyMode3); new_npc->AddLootTable(); entity_list.AddNPC(new_npc); new_npc->AddToHateList(trigger,1); } } break; case trapTypeBanditSpawn: if (message.empty()) { entity_list.MessageClose(trigger,false,100,CC_Default,"A bandit leaps out from behind a tree!"); } else { entity_list.MessageClose(trigger,false,100,CC_Default,"%s",message.c_str()); } for (i = 0; i < effectvalue2; i++) { if ((tmp = database.GetNPCType(effectvalue))) { auto randomOffset = glm::vec4(zone->random.Int(-2, 2), zone->random.Int(-2, 2), zone->random.Int(-2, 2), zone->random.Int(0, 249)); auto spawnPosition = randomOffset + glm::vec4(m_Position, 0.0f); NPC* new_npc = new NPC(tmp, nullptr, spawnPosition, FlyMode3); new_npc->AddLootTable(); entity_list.AddNPC(new_npc); new_npc->AddToHateList(trigger,1); } } break; case trapTypeDamage: if (message.empty()) { entity_list.MessageClose(trigger,false,100,CC_Default,"%s triggers a trap!",trigger->GetName()); } else { entity_list.MessageClose(trigger,false,100,CC_Default,"%s",message.c_str()); } if(trigger->IsClient()) { EQApplicationPacket* outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct)); CombatDamage_Struct* a = (CombatDamage_Struct*)outapp->pBuffer; int dmg = zone->random.Int(effectvalue, effectvalue2); trigger->SetHP(trigger->GetHP() - dmg); a->damage = dmg; a->sequence = (float)zone->random.Int(0, 511); a->source = GetHiddenTrigger()!=nullptr ? GetHiddenTrigger()->GetID() : trigger->GetID(); a->spellid = 0; a->target = trigger->GetID(); a->type = 253; trigger->CastToClient()->QueuePacket(outapp); safe_delete(outapp); } } if(trigger && trigger->IsClient()) { trigger->CastToClient()->trapid = trap_id; charid = trigger->CastToClient()->CharacterID(); } bool update = false; if(despawn_when_triggered) { Log.Out(Logs::General, Logs::Traps, "Trap %d is despawning after being triggered.", trap_id); update = true; } else { reset_timer.Start(5000); } if(triggered_number > 0) ++times_triggered; if(triggered_number > 0 && triggered_number <= times_triggered) { Log.Out(Logs::General, Logs::Traps, "Triggered number for trap %d reached. %d/%d", trap_id, times_triggered, triggered_number); update = true; } if(update) { UpdateTrap(); } }
void Doors::HandleClick(Client* sender, uint8 trigger) { //door debugging info dump 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; md->doorid = door_id; ///////////////////////////////////////////////////////////////// //used_pawn: Locked doors! Rogue friendly too =) //TODO: add check for other lockpick items ////////////////////////////////////////////////////////////////// //TODO: ADVENTURE DOOR if(IsLDoNDoor()) { if(sender) { if(RuleI(Adventure, ItemIDToEnablePorts) != 0) { if(!sender->KeyRingCheck(RuleI(Adventure, ItemIDToEnablePorts))) { if (sender->GetInv().HasItem(RuleI(Adventure, ItemIDToEnablePorts)) == INVALID_INDEX) { sender->Message_StringID(13, DUNGEON_SEALED); safe_delete(outapp); return; } else { sender->KeyRingAdd(RuleI(Adventure, ItemIDToEnablePorts)); } } } if(!sender->GetPendingAdventureDoorClick()) { sender->PendingAdventureDoorClick(); ServerPacket *pack = new ServerPacket(ServerOP_AdventureClickDoor, sizeof(ServerPlayerClickedAdventureDoor_Struct)); ServerPlayerClickedAdventureDoor_Struct *ads = (ServerPlayerClickedAdventureDoor_Struct*)pack->pBuffer; strcpy(ads->player, sender->GetName()); ads->zone_id = zone->GetZoneID(); ads->id = GetDoorDBID(); worldserver.SendPacket(pack); safe_delete(pack); safe_delete(outapp); } return; } } uint32 keyneeded = GetKeyItem(); uint8 keepoffkeyring = GetNoKeyring(); uint32 haskey = 0; uint32 playerkey = 0; const ItemInst *lockpicks = sender->GetInv().GetItem(SlotCursor); haskey = sender->GetInv().HasItem(keyneeded, 1); if (haskey != INVALID_INDEX) { playerkey = keyneeded; } if(GetTriggerType() == 255) { // this object isnt triggered if(trigger == 1) { // this door is only triggered by an object if(!IsDoorOpen() || (opentype == 58)) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } } else { safe_delete(outapp); return; } } // guild doors if(((keyneeded == 0) && (GetLockpick() == 0) && (guild_id == 0)) || (IsDoorOpen() && (opentype == 58)) || ((guild_id > 0) && (guild_id == sender->GuildID()))) { //door not locked if(!IsDoorOpen() || (opentype == 58)) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } } else { // guild doors if((guild_id > 0) && !sender->GetGM()) { std::string tmp; char tmpmsg[240]; // guild doors msgs if(guild_mgr.GetGuildNameByID(guild_id, tmp)) { sprintf(tmpmsg, "Only members of the <%s> guild may enter here", tmp.c_str()); } else { strcpy(tmpmsg, "Door is locked by an unknown guild"); } sender->Message(4, tmpmsg); safe_delete(outapp); return; } // a key is required or the door is locked but can be picked or both sender->Message(4, "This is locked..."); // debug spam - should probably go if(sender->GetGM()) // GM can always open locks - should probably be changed to require a key { sender->Message_StringID(4,DOORS_GM); if(!IsDoorOpen() || (opentype == 58)) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } } else if(playerkey) { // they have something they are trying to open it with if(keyneeded && (keyneeded == playerkey)) { // key required and client is using the right key if(!keepoffkeyring) { sender->KeyRingAdd(playerkey); } sender->Message(4, "You got it open!"); if(!IsDoorOpen() || (opentype == 58)) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } } } else if(lockpicks != nullptr) { if(sender->GetSkill(SkillPickLock)) { if(lockpicks->GetItem()->ItemType == ItemTypeLockPick) { float modskill=sender->GetSkill(SkillPickLock); sender->CheckIncreaseSkill(SkillPickLock, nullptr, 1); Log.Out(Logs::General, Logs::Skills, "Client has lockpicks: skill=%f", modskill); if(GetLockpick() <= modskill) { if(!IsDoorOpen()) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } sender->Message_StringID(4, DOORS_SUCCESSFUL_PICK); } else { sender->Message_StringID(4, DOORS_INSUFFICIENT_SKILL); safe_delete(outapp); return; } } else { sender->Message_StringID(4, DOORS_NO_PICK); safe_delete(outapp); return; } } else { sender->Message_StringID(4, DOORS_CANT_PICK); safe_delete(outapp); return; } } else { // locked door and nothing to open it with // search for key on keyring if(sender->KeyRingCheck(keyneeded)) { playerkey = keyneeded; sender->Message(4, "You got it open!"); // more debug spam if(!IsDoorOpen() || (opentype == 58)) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } } else { sender->Message_StringID(4, DOORS_LOCKED); safe_delete(outapp); return; } } } entity_list.QueueClients(sender, outapp, false); if(!IsDoorOpen() || (opentype == 58)) { close_timer.Start(); SetOpenState(true); } else { close_timer.Disable(); SetOpenState(false); } //everything past this point assumes we opened the door //and met all the reqs for opening //everything to do with closed doors has already been taken care of //we return because we don't want people using teleports on an unlocked door (exploit!) if((md->action == CLOSE_DOOR && invert_state == 0) || (md->action == CLOSE_INVDOOR && invert_state == 1)) { safe_delete(outapp); return; } safe_delete(outapp); if((GetTriggerDoorID() != 0) && (GetTriggerType() == 1)) { Doors* triggerdoor = entity_list.FindDoor(GetTriggerDoorID()); if(triggerdoor && !triggerdoor->triggered) { triggered=true; triggerdoor->HandleClick(sender, 1); } else { triggered=false; } } else if((GetTriggerDoorID() != 0) && (GetTriggerType() != 1)) { Doors* triggerdoor = entity_list.FindDoor(GetTriggerDoorID()); if(triggerdoor && !triggerdoor->triggered) { triggered=true; triggerdoor->HandleClick(sender, 0); } else { triggered=false; } } if(((opentype == 57) || (opentype == 58)) && (strncmp(dest_zone, "NONE", strlen("NONE")) != 0)) { // Teleport door! if (( strncmp(dest_zone,zone_name,strlen(zone_name)) == 0) && (!keyneeded)) { if(!keepoffkeyring) { sender->KeyRingAdd(playerkey); } 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()))) { if(!keepoffkeyring) { sender->KeyRingAdd(playerkey); } if(database.GetZoneID(dest_zone) == zone->GetZoneID()) { 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, 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(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w); } else { sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w); } } } }
void Corpse::SendEndLootErrorPacket(Client* client) { EQApplicationPacket* outapp = new EQApplicationPacket(OP_LootComplete, 0); client->QueuePacket(outapp); safe_delete(outapp); }
bool Corpse::Process() { if (player_corpse_depop) return false; if (corpse_delay_timer.Check()) { for (int i = 0; i < MAX_LOOTERS; i++) allowed_looters[i] = 0; corpse_delay_timer.Disable(); return true; } if (corpse_graveyard_timer.Check()) { if (zone->HasGraveyard()) { Save(); player_corpse_depop = true; database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(), (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; spc->player_corpse_id = corpse_db_id; spc->zone_id = zone->graveyard_zoneid(); worldserver.SendPacket(pack); safe_delete(pack); 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; } corpse_graveyard_timer.Disable(); return false; } /* if(corpse_res_timer.Check()) { can_rez = false; corpse_res_timer.Disable(); } */ /* This is when a corpse hits decay timer and does checks*/ if (corpse_decay_timer.Check()) { /* NPC */ if (IsNPCCorpse()){ corpse_decay_timer.Disable(); return false; } /* Client */ if (!RuleB(Zone, EnableShadowrest)){ Delete(); } else { if (database.BuryCharacterCorpse(corpse_db_id)) { Save(); player_corpse_depop = true; corpse_db_id = 0; Log.Out(Logs::General, Logs::None, "Tagged %s player corpse has buried.", this->GetName()); } else { Log.Out(Logs::General, Logs::Error, "Unable to bury %s player corpse.", this->GetName()); return true; } } corpse_decay_timer.Disable(); return false; } return true; }
void Corpse::LootItem(Client* client, const EQApplicationPacket* app) { /* This gets sent no matter what as a sort of ACK */ client->QueuePacket(app); if (!loot_cooldown_timer.Check()) { SendEndLootErrorPacket(client); //unlock corpse for others if (this->being_looted_by = client->GetID()) { being_looted_by = 0xFFFFFFFF; } return; } /* To prevent item loss for a player using 'Loot All' who doesn't have inventory space for all their items. */ if (RuleB(Character, CheckCursorEmptyWhenLooting) && !client->GetInv().CursorEmpty()) { client->Message(13, "You may not loot an item while you have an item on your cursor."); SendEndLootErrorPacket(client); /* Unlock corpse for others */ if (this->being_looted_by = client->GetID()) { being_looted_by = 0xFFFFFFFF; } return; } LootingItem_Struct* lootitem = (LootingItem_Struct*)app->pBuffer; if (this->being_looted_by != client->GetID()) { client->Message(13, "Error: Corpse::LootItem: BeingLootedBy != client"); SendEndLootErrorPacket(client); return; } if (IsPlayerCorpse() && !CanPlayerLoot(client->CharacterID()) && !become_npc && (char_id != client->CharacterID() && client->Admin() < 150)) { client->Message(13, "Error: This is a player corpse and you dont own it."); SendEndLootErrorPacket(client); return; } if (is_locked && client->Admin() < 100) { SendLootReqErrorPacket(client, 0); client->Message(13, "Error: Corpse locked by GM."); return; } if (IsPlayerCorpse() && (char_id != client->CharacterID()) && CanPlayerLoot(client->CharacterID()) && GetPlayerKillItem() == 0){ client->Message(13, "Error: You cannot loot any more items from this corpse."); SendEndLootErrorPacket(client); being_looted_by = 0xFFFFFFFF; return; } const Item_Struct* item = 0; ItemInst *inst = 0; ServerLootItem_Struct* item_data = nullptr, *bag_item_data[10]; memset(bag_item_data, 0, sizeof(bag_item_data)); if (GetPlayerKillItem() > 1){ item = database.GetItem(GetPlayerKillItem()); } else if (GetPlayerKillItem() == -1 || GetPlayerKillItem() == 1){ item_data = GetItem(lootitem->slot_id - EmuConstants::CORPSE_BEGIN); //dont allow them to loot entire bags of items as pvp reward } else{ item_data = GetItem(lootitem->slot_id - EmuConstants::CORPSE_BEGIN, bag_item_data); } if (GetPlayerKillItem()<=1 && item_data != 0) { item = database.GetItem(item_data->item_id); } if (item != 0) { if (item_data){ inst = database.CreateItem(item, item_data ? item_data->charges : 0, 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); } else { inst = database.CreateItem(item); } } if (client && inst) { if (client->CheckLoreConflict(item)) { client->Message_StringID(0, LOOT_LORE_ERROR); SendEndLootErrorPacket(client); being_looted_by = 0; delete inst; return; } if (inst->IsAugmented()) { for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { ItemInst *itm = inst->GetAugment(i); if (itm) { if (client->CheckLoreConflict(itm->GetItem())) { client->Message_StringID(0, LOOT_LORE_ERROR); SendEndLootErrorPacket(client); being_looted_by = 0; delete inst; return; } } } } char buf[88]; char corpse_name[64]; strcpy(corpse_name, corpse_name); snprintf(buf, 87, "%d %d %s", inst->GetItem()->ID, inst->GetCharges(), EntityList::RemoveNumbers(corpse_name)); buf[87] = '\0'; std::vector<EQEmu::Any> args; args.push_back(inst); args.push_back(this); parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args); parse->EventItem(EVENT_LOOT, client, inst, this, buf, 0); if (!IsPlayerCorpse() && RuleB(Character, EnableDiscoveredItems)) { if (client && !client->GetGM() && !client->IsDiscovered(inst->GetItem()->ID)) client->DiscoverItem(inst->GetItem()->ID); } if (zone->adv_data) { ServerZoneAdventureDataReply_Struct *ad = (ServerZoneAdventureDataReply_Struct*)zone->adv_data; if (ad->type == Adventure_Collect && !IsPlayerCorpse()) { if (ad->data_id == inst->GetItem()->ID) { zone->DoAdventureCountIncrease(); } } } /* First add it to the looter - this will do the bag contents too */ if (lootitem->auto_loot) { if (!client->AutoPutLootInInventory(*inst, true, true, bag_item_data)) client->PutLootInInventory(MainCursor, *inst, bag_item_data); } else { client->PutLootInInventory(MainCursor, *inst, bag_item_data); } /* Update any tasks that have an activity to loot this item */ if (RuleB(TaskSystem, EnableTaskSystem)) client->UpdateTasksForItem(ActivityLoot, item->ID); /* Remove it from Corpse */ if (item_data){ /* 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); } /* Remove Bag Contents */ if (item->ItemClass == ItemClassContainer && (GetPlayerKillItem() != -1 || GetPlayerKillItem() != 1)) { 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); /* Delete Item Instance */ RemoveItem(bag_item_data[i]); } } } if (GetPlayerKillItem() != -1) { SetPlayerKillItemID(0); } /* 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()) { Group *g = client->GetGroup(); if(g != nullptr) { g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str()); } else { Raid *r = client->GetRaid(); if(r != nullptr) { r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str()); } } } } else { SendEndLootErrorPacket(client); safe_delete(inst); return; } if (IsPlayerCorpse()){ client->SendItemLink(inst); } else{ client->SendItemLink(inst, true); } safe_delete(inst); }
void Corpse::Spawn() { EQApplicationPacket* app = new EQApplicationPacket; this->CreateSpawnPacket(app, this); entity_list.QueueClients(this, app); safe_delete(app); }
BaseMCFThread::~BaseMCFThread() { safe_delete(m_pUPThread); }
void Window::OnResourceUnload() { OnUnload(); safe_delete(mLayout); }
virtual void OnShutdown() { safe_delete(mVideoPlayer); }
static void thread_proc(NodeFunction* pFunc, ParseInfo* pinfo, std::vector<Symbol*>* pvecSyms) { // ignore return value Symbol *pRet = task_proc(pFunc, pinfo, pvecSyms); safe_delete(pRet, 0, pinfo); }
void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* app) { // Added 12/08. Started compressing loot struct on live. char tmp[10]; if(player_corpse_depop) { SendLootReqErrorPacket(client, 0); return; } if(IsPlayerCorpse() && corpse_db_id == 0) { // SendLootReqErrorPacket(client, 0); client->Message(13, "Warning: Corpse's dbid = 0! Corpse will not survive zone shutdown!"); std::cout << "Error: PlayerCorpse::MakeLootRequestPackets: dbid = 0!" << std::endl; // return; } if(is_locked && client->Admin() < 100) { SendLootReqErrorPacket(client, 0); client->Message(13, "Error: Corpse locked by GM."); return; } 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; } uint8 Loot_Request_Type = 1; bool loot_coin = false; 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); Loot_Request_Type = 0; } else if (IsPlayerCorpse() && char_id == client->CharacterID()) { Loot_Request_Type = 2; } else if ((IsNPCCorpse() || become_npc) && CanPlayerLoot(client->CharacterID())) { Loot_Request_Type = 2; } else if (GetPlayerKillItem() == -1 && CanPlayerLoot(client->CharacterID())) { /* PVP loot all items, variable cash */ Loot_Request_Type = 3; } else if (GetPlayerKillItem() == 1 && CanPlayerLoot(client->CharacterID())) { /* PVP loot 1 item, variable cash */ Loot_Request_Type = 4; } else if (GetPlayerKillItem() > 1 && CanPlayerLoot(client->CharacterID())) { /* PVP loot 1 set item, variable cash */ Loot_Request_Type = 5; } if (Loot_Request_Type == 1) { if (client->Admin() < 100 || !client->GetGM()) { SendLootReqErrorPacket(client, 2); } } if(Loot_Request_Type >= 2 || (Loot_Request_Type == 1 && client->Admin() >= 100 && client->GetGM())) { this->being_looted_by = client->GetID(); EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct)); moneyOnCorpseStruct* d = (moneyOnCorpseStruct*) outapp->pBuffer; d->response = 1; d->unknown1 = 0x42; 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(!IsPlayerCorpse() && client->IsGrouped() && client->AutoSplitEnabled() && client->GetGroup()) { d->copper = 0; d->silver = 0; d->gold = 0; d->platinum = 0; Group *cgroup = client->GetGroup(); cgroup->SplitMoney(GetCopper(), GetSilver(), GetGold(), GetPlatinum(), client); } else { d->copper = this->GetCopper(); d->silver = this->GetSilver(); d->gold = this->GetGold(); d->platinum = this->GetPlatinum(); client->AddMoneyToPP(GetCopper(), GetSilver(), GetGold(), GetPlatinum(), false); } RemoveCash(); Save(); } auto timestamps = database.GetItemRecastTimestamps(client->CharacterID()); outapp->priority = 6; client->QueuePacket(outapp); safe_delete(outapp); if(Loot_Request_Type == 5) { int pkitem = GetPlayerKillItem(); 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); } else { client->Message(13, "Could not find item number %i to send!!", GetPlayerKillItem()); } client->QueuePacket(app); return; } int i = 0; const Item_Struct* item = 0; ItemList::iterator cur,end; cur = itemlist.begin(); end = itemlist.end(); int corpselootlimit = EQLimits::InventoryMapSize(MapCorpse, client->GetClientVersion()); for(; cur != end; ++cur) { ServerLootItem_Struct* item_data = *cur; item_data->lootslot = 0xFFFF; // Dont display the item if it's in a bag // Added cursor queue slots to corpse item visibility list. Nothing else should be making it to corpse. if(!IsPlayerCorpse() || item_data->equip_slot <= MainCursor || item_data->equip_slot == MainPowerSource || Loot_Request_Type>=3 || (item_data->equip_slot >= 8000 && item_data->equip_slot <= 8999)) { if(i < corpselootlimit) { item = database.GetItem(item_data->item_id); 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); } item_data->lootslot = i; } } i++; } } if(IsPlayerCorpse() && (char_id == client->CharacterID() || client->GetGM())) { if(i > corpselootlimit) { client->Message(15, "*** This corpse contains more items than can be displayed! ***"); client->Message(0, "Remove items and re-loot corpse to access remaining inventory."); client->Message(0, "(%s contains %i additional %s.)", GetName(), (i - corpselootlimit), (i - corpselootlimit) == 1 ? "item" : "items"); } if(IsPlayerCorpse() && i == 0 && itemlist.size() > 0) { // somehow, player corpse contains items, but client doesn't see them... client->Message(13, "This corpse contains items that are inaccessable!"); client->Message(15, "Contact a GM for item replacement, if necessary."); client->Message(15, "BUGGED CORPSE [DBID: %i, Name: %s, Item Count: %i]", GetCorpseDBID(), GetName(), itemlist.size()); cur = itemlist.begin(); end = itemlist.end(); for(; cur != end; ++cur) { ServerLootItem_Struct* item_data = *cur; item = database.GetItem(item_data->item_id); 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); } } } } // Disgrace: Client seems to require that we send the packet back... client->QueuePacket(app); // 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() >= ClientVersion::SoD) { SendLootReqErrorPacket(client, 6); } }
SMTWorker::~SMTWorker() { safe_delete(m_phFhSink); safe_delete(m_BZ2Worker); }
void MCF::dlHeaderFromWeb() { if (m_bStopped) return; if (m_vProviderList.size() == 0) throw gcException(ERR_ZEROFILE); gcException lastE; bool successful = false; OutBuffer out(MCF_HEADERSIZE_V2); MCFCore::Misc::MCFServerCon msc; for (size_t x=0; x<m_vProviderList.size(); x++) { try { msc.disconnect(); msc.connect(m_vProviderList[x]->getUrl(), m_pFileAuth); msc.downloadRange(0, 5, &out); //4 id bytes and 1 version byte if (out.m_uiTotalSize != 5) throw gcException(ERR_BADHEADER, "Did not get any data from mcf server."); const char* data = out.m_szBuffer; if ( !(data[0] == 'L' && data[1] == 'M' && data[2] == 'C' && data[3] == 'F') ) throw gcException(ERR_BADHEADER, "Failed magic check."); size_t headerSize = MCF_HEADERSIZE_V1; if (data[4] == 0x01) headerSize = MCF_HEADERSIZE_V1; else if (data[4] == 0x02) headerSize = MCF_HEADERSIZE_V2; else throw gcException(ERR_BADHEADER, "Bad version number"); out.reset(); msc.downloadRange(0, headerSize, &out); if (out.m_uiTotalSize != headerSize) throw gcException(ERR_BADHEADER, "Did not get correct ammount of data from server."); MCFCore::MCFHeader webHeader((uint8*)out.m_szBuffer); if (!webHeader.isValid()) throw gcException(ERR_BADHEADER, "Mcf header was not valid."); uint32 ths = webHeader.getXmlSize(); out = ths; msc.downloadRange(webHeader.getXmlStart(), webHeader.getXmlSize(), &out); if (out.m_uiTotalSize == 0 || out.m_uiTotalSize != webHeader.getXmlSize()) throw gcException(ERR_WEBDL_FAILED, "Failed to download MCF xml from web (size is ether zero or didnt match header size)"); data = out.m_szBuffer; if (data[0] == 'L' && data[1] == 'M' && data[2] == 'C' && data[3] == 'F') throw gcException(ERR_WEBDL_FAILED, "Server failed 4gb seek."); setHeader(&webHeader); successful = true; break; } catch (gcException &e) { lastE = e; Warning(gcString("Failed to download MCF Header from {1}: {0}\n", e, m_vProviderList[x]->getUrl())); } } if (!successful) throw lastE; uint32 bz2BuffLen = getHeader()->getXmlSize()*25; char* bz2Buff = NULL; if ( isCompressed() ) { bz2Buff = new char[bz2BuffLen]; UTIL::STRING::zeroBuffer(bz2Buff, bz2BuffLen); try { UTIL::BZIP::BZ2DBuff((char*)bz2Buff, &bz2BuffLen, out.m_szBuffer, out.m_uiTotalSize); parseXml(bz2Buff, bz2BuffLen); safe_delete(bz2Buff); } catch (gcException &) { safe_delete(bz2Buff); throw; } } else { parseXml(out.m_szBuffer, out.m_uiTotalSize); } //we remove the complete flag due to the files not existing in the MCF for (size_t x=0; x< m_pFileList.size(); x++) { m_pFileList[x]->delFlag(MCFCore::MCFFileI::FLAG_COMPLETE); } if (m_szFile != "") saveMCF_Header(); }
// Split from the basic MakePet to allow backward compatiblity with existing code while also // making it possible for petpower to be retained without the focus item having to // stay equipped when the character zones. petpower of -1 means that the currently equipped petfocus // of a client is searched for and used instead. void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, const char *petname, float in_size) { // Sanity and early out checking first. if(HasPet() || pettype == nullptr) return; int16 act_power = 0; // The actual pet power we'll use. if (petpower == -1) { if (this->IsClient()) { act_power = CastToClient()->GetFocusEffect(focusPetPower, spell_id);//Client only act_power = CastToClient()->mod_pet_power(act_power, spell_id); } #ifdef BOTS else if (this->IsBot()) act_power = CastToBot()->GetBotFocusEffect(Bot::BotfocusPetPower, spell_id); #endif } else if (petpower > 0) act_power = petpower; // optional rule: classic style variance in pets. Achieve this by // adding a random 0-4 to pet power, since it only comes in increments // of five from focus effects. //lookup our pets table record for this type PetRecord record; if(!database.GetPoweredPetEntry(pettype, act_power, &record)) { Message(13, "Unable to find data for pet %s", pettype); Log.Out(Logs::General, Logs::Error, "Unable to find data for pet %s, check pets table.", pettype); return; } //find the NPC data for the specified NPC type const NPCType *base = database.LoadNPCTypesData(record.npc_type); if(base == nullptr) { Message(13, "Unable to load NPC data for pet %s", pettype); 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; } //we copy the npc_type data because we need to edit it a bit auto npc_type = new NPCType; memcpy(npc_type, base, sizeof(NPCType)); // If pet power is set to -1 in the DB, use stat scaling if ((this->IsClient() #ifdef BOTS || this->IsBot() #endif ) && record.petpower == -1) { float scale_power = (float)act_power / 100.0f; if(scale_power > 0) { npc_type->max_hp *= (1 + scale_power); npc_type->cur_hp = npc_type->max_hp; npc_type->AC *= (1 + scale_power); npc_type->level += 1 + ((int)act_power / 25) > npc_type->level + RuleR(Pets, PetPowerLevelCap) ? RuleR(Pets, PetPowerLevelCap) : 1 + ((int)act_power / 25); // gains an additional level for every 25 pet power npc_type->min_dmg = (npc_type->min_dmg * (1 + (scale_power / 2))); npc_type->max_dmg = (npc_type->max_dmg * (1 + (scale_power / 2))); npc_type->size = npc_type->size * (1 + (scale_power / 2)) > npc_type->size * 3 ? npc_type->size * 3 : npc_type-> size * (1 + (scale_power / 2)); } record.petpower = act_power; } //Live AA - Elemental Durability int16 MaxHP = aabonuses.PetMaxHP + itembonuses.PetMaxHP + spellbonuses.PetMaxHP; if (MaxHP){ npc_type->max_hp += (npc_type->max_hp*MaxHP)/100; npc_type->cur_hp = npc_type->max_hp; } //TODO: think about regen (engaged vs. not engaged) // Pet naming: // 0 - `s pet // 1 - `s familiar // 2 - `s Warder // 3 - Random name if client, `s pet for others // 4 - Keep DB name if (petname != nullptr) { // Name was provided, use it. strn0cpy(npc_type->name, petname, 64); } else if (record.petnaming == 0) { strcpy(npc_type->name, this->GetCleanName()); npc_type->name[25] = '\0'; strcat(npc_type->name, "`s_pet"); } else if (record.petnaming == 1) { strcpy(npc_type->name, this->GetName()); npc_type->name[19] = '\0'; strcat(npc_type->name, "`s_familiar"); } else if (record.petnaming == 2) { strcpy(npc_type->name, this->GetName()); npc_type->name[21] = 0; strcat(npc_type->name, "`s_Warder"); } else if (record.petnaming == 4) { // Keep the DB name } else if (record.petnaming == 3 && IsClient()) { strcpy(npc_type->name, GetRandPetName()); } else { strcpy(npc_type->name, this->GetCleanName()); npc_type->name[25] = '\0'; strcat(npc_type->name, "`s_pet"); } //handle beastlord pet appearance if(record.petnaming == 2) { switch(GetBaseRace()) { case VAHSHIR: npc_type->race = TIGER; npc_type->size *= 0.8f; break; case TROLL: npc_type->race = ALLIGATOR; npc_type->size *= 2.5f; break; case OGRE: npc_type->race = BEAR; npc_type->texture = 3; npc_type->gender = 2; break; case BARBARIAN: npc_type->race = WOLF; npc_type->texture = 2; break; case IKSAR: npc_type->race = WOLF; npc_type->texture = 0; npc_type->gender = 1; npc_type->size *= 2.0f; npc_type->luclinface = 0; break; default: npc_type->race = WOLF; npc_type->texture = 0; } } // handle monster summoning pet appearance if(record.monsterflag) { uint32 monsterid = 0; // 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); if (!results.Success()) { safe_delete(npc_type); return; } 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; // give the summoned pet the attributes of the monster we found const NPCType* monster = database.LoadNPCTypesData(monsterid); if(monster) { npc_type->race = monster->race; npc_type->size = monster->size; npc_type->texture = monster->texture; npc_type->gender = monster->gender; npc_type->luclinface = monster->luclinface; npc_type->helmtexture = monster->helmtexture; npc_type->herosforgemodel = monster->herosforgemodel; } else Log.Out(Logs::General, Logs::Error, "Error loading NPC data for monster summoning pet (NPC ID %d)", monsterid); } //this takes ownership of the npc_type data auto npc = new Pet(npc_type, this, (PetType)record.petcontrol, spell_id, record.petpower); // Now that we have an actual object to interact with, load // the base items for the pet. These are always loaded // so that a rank 1 suspend minion does not kill things // like the special back items some focused pets may receive. uint32 petinv[EQEmu::legacy::EQUIPMENT_SIZE]; memset(petinv, 0, sizeof(petinv)); const EQEmu::ItemBase *item = 0; if (database.GetBasePetItems(record.equipmentset, petinv)) { for (int i = 0; i < EQEmu::legacy::EQUIPMENT_SIZE; i++) if (petinv[i]) { item = database.GetItem(petinv[i]); npc->AddLootDrop(item, &npc->itemlist, 0, 1, 127, true, true); } } npc->UpdateEquipmentLight(); // finally, override size if one was provided if (in_size > 0.0f) npc->size = in_size; entity_list.AddNPC(npc, true, true); SetPetID(npc->GetID()); // We need to handle PetType 5 (petHatelist), add the current target to the hatelist of the pet if (record.petcontrol == petTargetLock) { Mob* target = GetTarget(); if (target){ npc->AddToHateList(target, 1); npc->SetPetTargetLockID(target->GetID()); npc->SetSpecialAbility(IMMUNE_AGGRO, 1); } else npc->Kill(); //On live casts spell 892 Unsummon (Kayen - Too limiting to use that for emu since pet can have more than 20k HP) } }
~OutBuffer() { safe_delete(m_szBuffer); }
bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 CharacterID) { bool InZone = true; // This method should either be passed a Mob*, if the new member is in this zone, or a nullptr Mob* // and the name and CharacterID of the new member, if they are out of zone. // if (!newmember && !NewMemberName) return false; if (GroupCount() >= MAX_GROUP_MEMBERS) //Sanity check for merging groups together. return false; if (!newmember) InZone = false; else { NewMemberName = newmember->GetCleanName(); if (newmember->IsClient()) CharacterID = newmember->CastToClient()->CharacterID(); } uint32 i = 0; // See if they are already in the group // for (i = 0; i < MAX_GROUP_MEMBERS; ++i) if (!strcasecmp(membername[i], NewMemberName)) return false; // Put them in the group for (i = 0; i < MAX_GROUP_MEMBERS; ++i) { if (membername[i][0] == '\0') { if (InZone) members[i] = newmember; break; } } if (i == MAX_GROUP_MEMBERS) return false; strcpy(membername[i], NewMemberName); MemberRoles[i] = 0; int x = 1; //build the template join packet EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); GroupJoin_Struct* gj = (GroupJoin_Struct*)outapp->pBuffer; strcpy(gj->membername, NewMemberName); gj->action = groupActJoin; for (i = 0; i < MAX_GROUP_MEMBERS; i++) { if (members[i] != nullptr && members[i] != newmember) { //fill in group join & send it strcpy(gj->yourname, members[i]->GetCleanName()); if (members[i]->IsClient()) { members[i]->CastToClient()->QueuePacket(outapp); //put new member into existing person's list strcpy(members[i]->CastToClient()->GetPP().groupMembers[this->GroupCount() - 1], NewMemberName); } //put this existing person into the new member's list if (InZone && newmember->IsClient()) { if (IsLeader(members[i])) strcpy(newmember->CastToClient()->GetPP().groupMembers[0], members[i]->GetCleanName()); else { strcpy(newmember->CastToClient()->GetPP().groupMembers[x], members[i]->GetCleanName()); x++; } } } } if (InZone) { //put new member in his own list. newmember->SetGrouped(true); if (newmember->IsClient()) { strcpy(newmember->CastToClient()->GetPP().groupMembers[x], NewMemberName); newmember->CastToClient()->Save(); database.SetGroupID(NewMemberName, GetID(), newmember->CastToClient()->CharacterID()); } } else database.SetGroupID(NewMemberName, GetID(), CharacterID); safe_delete(outapp); return true; }
MOpcodeMesh::~MOpcodeMesh() { safe_delete (mCollisionModel); }
SFTWorker::~SFTWorker() { stop(); safe_delete(m_pBzs); }
///////////////// // Destroy accelerators // void CCoolMenuManager::DestroyAccel() { m_mapIDtoAccel.RemoveAll(); // delete ACCEL entries in map safe_delete(m_pAccel); // delete current accelerators }
PGTaskMgr::~PGTaskMgr() { std::for_each(m_Task.begin(), m_Task.end(), safe_delete()); m_Task.clear(); }
void ZSList::SendZoneStatus(const char* to, sint16 admin, WorldTCPConnection* connection) { LinkedListIterator<ZoneServer*> iterator(list); struct in_addr in; iterator.Reset(); char locked[4]; if (WorldConfig::get()->Locked == true) strcpy(locked, "Yes"); else strcpy(locked, "No"); char* output = 0; int32 outsize = 0, outlen = 0; if (connection->IsConsole()) AppendAnyLenString(&output, &outsize, &outlen, "World Locked: %s\r\n", locked); else AppendAnyLenString(&output, &outsize, &outlen, "World Locked: %s^", locked); if (connection->IsConsole()) AppendAnyLenString(&output, &outsize, &outlen, "Zoneservers online:\r\n"); else AppendAnyLenString(&output, &outsize, &outlen, "Zoneservers online:^"); // connection->SendEmoteMessage(to, 0, 0, 0, "World Locked: %s", locked); // connection->SendEmoteMessage(to, 0, 0, 0, "Zoneservers online:"); int v=0, w=0, x=0, y=0, z=0; char tmpStatic[2] = { 0, 0 }, tmpZone[64]; memset(tmpZone, 0, sizeof(tmpZone)); ZoneServer* zs = 0; while(iterator.MoreElements()) { zs = iterator.GetData(); in.s_addr = zs->GetIP(); if(zs->IsStaticZone()) z++; else if (zs->GetZoneID() != 0) w++; else if(zs->GetZoneID() == 0 && !zs->IsBootingUp()) v++; if (zs->IsStaticZone()) tmpStatic[0] = 'S'; else tmpStatic[0] = ' '; if (admin >= 150) { if (zs->GetZoneID()) snprintf(tmpZone, sizeof(tmpZone), "%s (%i)", zs->GetZoneName(), zs->GetZoneID()); else if (zs->IsBootingUp()) strcpy(tmpZone, "..."); else tmpZone[0] = 0; AppendAnyLenString(&output, &outsize, &outlen, " #%-3i %s %15s:%-5i %2i %s:%i %s", zs->GetID(), tmpStatic, inet_ntoa(in), zs->GetPort(), zs->NumPlayers(), zs->GetCAddress(), zs->GetCPort(), tmpZone); if (outlen >= 3584) { connection->SendEmoteMessageRaw(to, 0, 0, 10, output); safe_delete(output); outsize = 0; outlen = 0; } else { if (connection->IsConsole()) AppendAnyLenString(&output, &outsize, &outlen, "\r\n"); else AppendAnyLenString(&output, &outsize, &outlen, "^"); } x++; } else if (zs->GetZoneID() != 0) { if (zs->GetZoneID()) strcpy(tmpZone, zs->GetZoneName()); else tmpZone[0] = 0; AppendAnyLenString(&output, &outsize, &outlen, " #%i %s %s", zs->GetID(), tmpStatic, tmpZone); if (outlen >= 3584) { connection->SendEmoteMessageRaw(to, 0, 0, 10, output); safe_delete(output); outsize = 0; outlen = 0; } else { if (connection->IsConsole()) AppendAnyLenString(&output, &outsize, &outlen, "\r\n"); else AppendAnyLenString(&output, &outsize, &outlen, "^"); } x++; } y++; iterator.Advance(); } if (connection->IsConsole()) AppendAnyLenString(&output, &outsize, &outlen, "%i servers listed. %i servers online.\r\n", x, y); else AppendAnyLenString(&output, &outsize, &outlen, "%i servers listed. %i servers online.^", x, y); AppendAnyLenString(&output, &outsize, &outlen, "%i zones are static zones, %i zones are booted zones, %i zones available.",z,w,v); // connection->SendEmoteMessage(to, 0, 0, "%i servers listed. %i servers online.", x, y); // connection->SendEmoteMessage(to,0,0,"%i zones are static zones, %i zones are booted zones, %i zones available.",z,w,v); if (output) connection->SendEmoteMessageRaw(to, 0, 0, 10, output); safe_delete(output); }
CIPManager::~CIPManager() { safe_delete(m_pThread); }
MenuSeperator::~MenuSeperator() { safe_delete(m_imgBG); }
HGTController::~HGTController() { safe_delete(m_vSuperBlockList); }
ToolTransInfo::~ToolTransInfo() { safe_delete(m_pTransaction); }