Doors::Doors(const char *dmodel, const glm::vec4& position, uint8 dopentype, uint16 dsize) : close_timer(5000), m_Position(position), m_Destination(glm::vec4()) { db_id = database.GetDoorsCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); door_id = database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); strn0cpy(zone_name,zone->GetShortName(),32); strn0cpy(door_name,dmodel,32); incline = 0; opentype = dopentype; guild_id = 0; lockpick = 0; keyitem = 0; nokeyring = 0; altkeyitem = 0; trigger_door = 0; trigger_type = 0; triggered=false; door_param = 0; size = dsize; invert_state = 0; SetOpenState(false); close_timer.Disable(); strn0cpy(dest_zone,"NONE",32); dest_instance_id = 0; client_version_mask = 4294967295u; }
Doors::Doors(const Door *door) : close_timer(5000), m_Position(door->pos_x, door->pos_y, door->pos_z, door->heading), m_Destination(door->dest_x, door->dest_y, door->dest_z, door->dest_heading) { strn0cpy(zone_name, door->zone_name, 32); strn0cpy(door_name, door->door_name, 32); strn0cpy(destination_zone_name, door->dest_zone, 16); this->database_id = door->db_id; this->door_id = door->door_id; this->incline = door->incline; this->open_type = door->opentype; this->guild_id = door->guild_id; this->lockpick = door->lock_pick; this->key_item_id = door->keyitem; this->no_key_ring = door->nokeyring; this->trigger_door = door->trigger_door; this->trigger_type = door->trigger_type; this->triggered = false; this->door_param = door->door_param; this->size = door->size; this->invert_state = door->invert_state; this->destination_instance_id = door->dest_instance_id; this->is_ldon_door = door->is_ldon_door; this->client_version_mask = door->client_version_mask; SetOpenState(false); close_timer.Disable(); disable_timer = (door->disable_timer == 1 ? true : false); }
Doors::Doors(const Door* door) : close_timer(5000), m_Position(door->pos_x, door->pos_y, door->pos_z, door->heading), m_Destination(door->dest_x, door->dest_y, door->dest_z, door->dest_heading) { db_id = door->db_id; door_id = door->door_id; strn0cpy(zone_name,door->zone_name,32); strn0cpy(door_name,door->door_name,32); incline = door->incline; opentype = door->opentype; guild_id = door->guild_id; lockpick = door->lock_pick; keyitem = door->keyitem; nokeyring = door->nokeyring; altkeyitem = door->altkeyitem; trigger_door = door->trigger_door; trigger_type = door->trigger_type; triggered=false; door_param = door->door_param; size = door->size; invert_state = door->invert_state; SetOpenState(false); close_timer.Disable(); strn0cpy(dest_zone,door->dest_zone,16); dest_instance_id = door->dest_instance_id; client_version_mask = door->client_version_mask; }
Doors::Doors(const char *model, const glm::vec4 &position, uint8 open_type, uint16 size) : close_timer(5000), m_Position(position), m_Destination(glm::vec4()){ strn0cpy(zone_name, zone->GetShortName(), 32); strn0cpy(door_name, model, 32); strn0cpy(destination_zone_name, "NONE", 32); this->database_id = (uint32) database.GetDoorsCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); this->door_id = (uint8) database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); this->open_type = open_type; this->size = size; this->incline = 0; this->guild_id = 0; this->lockpick = 0; this->key_item_id = 0; this->no_key_ring = 0; this->trigger_door = 0; this->trigger_type = 0; this->triggered = false; this->door_param = 0; this->invert_state = 0; this->is_ldon_door = 0; this->client_version_mask = 4294967295u; this->disable_timer = 0; this->destination_instance_id = 0; SetOpenState(false); close_timer.Disable(); }
bool Doors::Process() { if (close_timer.Enabled() && close_timer.Check() && IsDoorOpen()) { if (open_type == 40 || GetTriggerType() == 1) { auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); MoveDoor_Struct *md = (MoveDoor_Struct *) outapp->pBuffer; md->doorid = door_id; md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; entity_list.QueueClients(0, outapp); safe_delete(outapp); } triggered = false; close_timer.Disable(); SetOpenState(false); } return true; }
Doors::Doors(const char *dmodel, float dx, float dy, float dz, float dheading, uint8 dopentype, uint16 dsize) : close_timer(5000) { db_id = database.GetDoorsCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); door_id = database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); strn0cpy(zone_name,zone->GetShortName(),32); strn0cpy(door_name,dmodel,32); pos_x = dx; pos_y = dy; pos_z = dz; heading = dheading; incline = 0; opentype = dopentype; guild_id = 0; lockpick = 0; keyitem = 0; nokeyring = 0; trigger_door = 0; trigger_type = 0; triggered=false; door_param = 0; size = dsize; invert_state = 0; SetOpenState(false); close_timer.Disable(); strn0cpy(dest_zone,"NONE",32); dest_instance_id = 0; dest_x = 0; dest_y = 0; dest_z = 0; dest_heading = 0; is_ldon_door = 0; client_version_mask = 4294967295u; }
Doors::Doors(const Door* door) : close_timer(5000) { db_id = door->db_id; door_id = door->door_id; strn0cpy(zone_name,door->zone_name,32); strn0cpy(door_name,door->door_name,32); pos_x = door->pos_x; pos_y = door->pos_y; pos_z = door->pos_z; heading = door->heading; incline = door->incline; opentype = door->opentype; guild_id = door->guild_id; lockpick = door->lockpick; keyitem = door->keyitem; nokeyring = door->nokeyring; trigger_door = door->trigger_door; trigger_type = door->trigger_type; triggered=false; door_param = door->door_param; size = door->size; invert_state = door->invert_state; SetOpenState(false); close_timer.Disable(); strn0cpy(dest_zone,door->dest_zone,32); dest_instance_id = door->dest_instance_id; dest_x = door->dest_x; dest_y = door->dest_y; dest_z = door->dest_z; dest_heading = door->dest_heading; is_ldon_door = door->is_ldon_door; client_version_mask = door->client_version_mask; }
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, keys %d %d, nokeyring %d, trigger %d type %d, param %d", incline, opentype, lockpick, keyitem, altkeyitem, 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 ////////////////////////////////////////////////////////////////// uint32 keyneeded = GetKeyItem(); uint32 altkey = GetAltKeyItem(); uint8 keepoffkeyring = GetNoKeyring(); uint32 haskey = 0; uint32 hasaltkey = 0; uint32 playerkey = 0; const ItemInst *lockpicks = sender->GetInv().GetItem(MainCursor); haskey = sender->GetInv().HasItem(keyneeded, 1, invWhereCursor); hasaltkey = sender->GetInv().HasItem(altkey, 1, invWhereCursor); if(haskey == MainCursor) { playerkey = keyneeded; } else if(hasaltkey == MainCursor) { playerkey = altkey; } 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 && altkey == 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(CC_Blue, tmpmsg); safe_delete(outapp); return; } // a key is required or the door is locked but can be picked or both sender->Message(CC_Blue, "This is locked..."); // debug spam - should probably go if(sender->GetGM()) // GM can always open locks { sender->Message_StringID(CC_Blue,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) || altkey && (altkey == playerkey)) { // key required and client is using the right key if(!keepoffkeyring) { sender->KeyRingAdd(playerkey); } sender->Message(CC_Blue, "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); // Lockpicks will be on the cursor and not equipped, so we need to manually get any skillmod they may have. if(lockpicks->GetItem()->SkillModType == SkillPickLock) { modskill += modskill * (static_cast<float>(lockpicks->GetItem()->SkillModValue)/100.0); } Log.Out(Logs::General, Logs::Skills, "Client has lockpicks: skill=%f", modskill); if(GetLockpick() <= modskill) { if(!IsDoorOpen()) { sender->CheckIncreaseSkill(SkillPickLock, nullptr, zone->skill_difficulty[SkillPickLock].difficulty, 1.0); md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } sender->Message_StringID(CC_Blue, DOORS_SUCCESSFUL_PICK); } else { sender->Message_StringID(CC_Blue, DOORS_INSUFFICIENT_SKILL); safe_delete(outapp); return; } } else { sender->Message_StringID(CC_Blue, DOORS_NO_PICK); safe_delete(outapp); return; } } else { sender->Message_StringID(CC_Blue, DOORS_CANT_PICK); safe_delete(outapp); return; } } else { // locked door and nothing to open it with // search for key on keyring uint32 keyring = 0; if(sender->KeyRingCheck(keyneeded)) keyring = keyneeded; else if(sender->KeyRingCheck(altkey)) keyring = altkey; if(keyring > 0) { playerkey = keyring; sender->Message(CC_Blue, "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(CC_Blue, 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 Doors::HandleClick(Client* sender, uint8 trigger) { Log(Logs::Detail, Logs::Doors, "%s clicked door %s (dbid %d, eqid %d) at %s", sender->GetName(), this->door_name, this->database_id, this->door_id, to_string(m_Position).c_str() ); Log(Logs::Detail, Logs::Doors, "incline %d, open_type %d, lockpick %d, key %d, nokeyring %d, trigger %d type %d, param %d", this->incline, this->open_type, this->lockpick, this->key_item_id, this->no_key_ring, this->trigger_door, this->trigger_type, this->door_param ); Log(Logs::Detail, Logs::Doors, "disable_timer '%s',size %d, invert %d, dest: %s %s", (this->disable_timer ? "true" : "false"), this->size, this->invert_state, this->destination_zone_name, to_string(m_Destination).c_str() ); auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); auto *move_door_packet = (MoveDoor_Struct *) outapp->pBuffer; move_door_packet->doorid = door_id; if (this->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(); auto pack = new ServerPacket( ServerOP_AdventureClickDoor, sizeof(ServerPlayerClickedAdventureDoor_Struct) ); /** * Adventure door */ ServerPlayerClickedAdventureDoor_Struct *adventure_door_click; adventure_door_click = (ServerPlayerClickedAdventureDoor_Struct *) pack->pBuffer; strcpy(adventure_door_click->player, sender->GetName()); adventure_door_click->zone_id = zone->GetZoneID(); adventure_door_click->id = this->GetDoorDBID(); worldserver.SendPacket(pack); safe_delete(pack); } safe_delete(outapp); return; } } uint32 required_key_item = GetKeyItem(); uint8 disable_add_to_key_ring = GetNoKeyring(); uint32 player_has_key = 0; uint32 player_key = 0; const EQEmu::ItemInstance *lock_pick_item = sender->GetInv().GetItem(EQEmu::invslot::slotCursor); player_has_key = static_cast<uint32>(sender->GetInv().HasItem(required_key_item, 1)); if (player_has_key != INVALID_INDEX) { player_key = required_key_item; } /** * Object is not triggered */ if (this->GetTriggerType() == 255) { /** * Door is only triggered by an object */ if (trigger == 1) { if (!this->IsDoorOpen() || (open_type == 58)) { move_door_packet->action = static_cast<uint8>(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); } else { move_door_packet->action = static_cast<uint8>(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } } else { safe_delete(outapp); return; } } /** * Guild Doors * * Door is not locked */ bool is_guild_door = (this->GetGuildID() > 0) && (this->GetGuildID() == sender->GuildID()); bool is_door_not_locked = ((required_key_item == 0) && (this->GetLockpick() == 0) && (this->GetGuildID() == 0)); bool is_door_open_and_open_able = (this->IsDoorOpen() && (open_type == 58)); if (is_door_not_locked || is_door_open_and_open_able || is_guild_door) { if (!this->IsDoorOpen() || (this->GetOpenType() == 58)) { move_door_packet->action = static_cast<uint8>(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); } else { move_door_packet->action = static_cast<uint8>(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } } else { /** * Guild Doors */ if ((this->GetGuildID() > 0) && !sender->GetGM()) { std::string guild_name; char door_message[240]; if (guild_mgr.GetGuildNameByID(guild_id, guild_name)) { sprintf(door_message, "Only members of the <%s> guild may enter here", guild_name.c_str()); } else { strcpy(door_message, "Door is locked by an unknown guild"); } sender->Message(4, door_message); safe_delete(outapp); return; } /** * Key required */ sender->Message(4, "This is locked..."); /** * GM can always open locks */ if (sender->GetGM()) { sender->Message_StringID(4, DOORS_GM); if (!IsDoorOpen() || (open_type == 58)) { move_door_packet->action = static_cast<uint8>(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); } else { move_door_packet->action = static_cast<uint8>(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } } /** * Player has something they are trying to open it with */ else if (player_key) { /** * Key required and client is using the right key */ if (required_key_item && (required_key_item == player_key)) { if (!disable_add_to_key_ring) { sender->KeyRingAdd(player_key); } sender->Message(4, "You got it open!"); if (!IsDoorOpen() || (open_type == 58)) { move_door_packet->action = static_cast<uint8>(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); } else { move_door_packet->action = static_cast<uint8>(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } } } /** * Try Lock pick */ else if (lock_pick_item != nullptr) { if (sender->GetSkill(EQEmu::skills::SkillPickLock)) { if (lock_pick_item->GetItem()->ItemType == EQEmu::item::ItemTypeLockPick) { float player_pick_lock_skill = sender->GetSkill(EQEmu::skills::SkillPickLock); sender->CheckIncreaseSkill(EQEmu::skills::SkillPickLock, nullptr, 1); Log(Logs::General, Logs::Skills, "Client has lockpicks: skill=%f", player_pick_lock_skill); if (GetLockpick() <= player_pick_lock_skill) { if (!IsDoorOpen()) { move_door_packet->action = static_cast<uint8>(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); } else { move_door_packet->action = static_cast<uint8>(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; } } /** * Locked door and nothing to open it with */ else { /** * Search for key on keyring */ if (sender->KeyRingCheck(required_key_item)) { player_key = required_key_item; sender->Message(4, "You got it open!"); // more debug spam if (!IsDoorOpen() || (open_type == 58)) { move_door_packet->action = static_cast<uint8>(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); } else { move_door_packet->action = static_cast<uint8>(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() || (open_type == 58)) { if (!disable_timer) close_timer.Start(); SetOpenState(true); } else { close_timer.Disable(); if (!disable_timer) SetOpenState(false); } /* * Everything past this point assumes we opened the door * and met all the requirements 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 ((move_door_packet->action == CLOSE_DOOR && invert_state == 0) || (move_door_packet->action == CLOSE_INVDOOR && invert_state == 1)) { safe_delete(outapp); return; } safe_delete(outapp); if ((GetTriggerDoorID() != 0) && (GetTriggerType() == 1)) { Doors *trigger_door_entity = entity_list.FindDoor(GetTriggerDoorID()); if (trigger_door_entity && !trigger_door_entity->triggered) { triggered = true; trigger_door_entity->HandleClick(sender, 1); } else { triggered = false; } } else if ((GetTriggerDoorID() != 0) && (GetTriggerType() != 1)) { Doors *trigger_door_entity = entity_list.FindDoor(GetTriggerDoorID()); if (trigger_door_entity && !trigger_door_entity->triggered) { triggered = true; trigger_door_entity->HandleClick(sender, 0); } else { triggered = false; } } /** * Teleport door */ if (((open_type == 57) || (open_type == 58)) && (strncmp(destination_zone_name, "NONE", strlen("NONE")) != 0)) { /** * If click destination is same zone and doesn't require a key */ if ((strncmp(destination_zone_name, zone_name, strlen(zone_name)) == 0) && (!required_key_item)) { if (!disable_add_to_key_ring) { sender->KeyRingAdd(player_key); } sender->MovePC( zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w ); } /** * If requires a key */ else if ( (!IsDoorOpen() || open_type == 58) && (required_key_item && ((required_key_item == player_key) || sender->GetGM())) ) { if (!disable_add_to_key_ring) { sender->KeyRingAdd(player_key); } if (database.GetZoneID(destination_zone_name) == 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(destination_zone_name), static_cast<uint32>(destination_instance_id), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w ); } } if ((!IsDoorOpen() || open_type == 58) && (!required_key_item)) { if (database.GetZoneID(destination_zone_name) == 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(destination_zone_name), static_cast<uint32>(this->destination_instance_id), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w ); } } } }
void Doors::HandleClick(Client* sender, uint8 trigger) { //door debugging info dump _log(DOORS__INFO, "%s clicked door %s (dbid %d, eqid %d) at (%.4f,%.4f,%.4f @%.4f)", sender->GetName(), door_name, db_id, door_id, pos_x, pos_y, pos_z, heading); _log(DOORS__INFO, " incline %d, opentype %d, lockpick %d, key %d, nokeyring %d, trigger %d type %d, param %d", incline, opentype, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param); _log(DOORS__INFO, " size %d, invert %d, dest: %s (%.4f,%.4f,%.4f @%.4f)", size, invert_state, dest_zone, dest_x, dest_y, dest_z, dest_heading); 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)) == SLOT_INVALID) { sender->Message_StringID(13, 5141); 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(SLOT_CURSOR); haskey = sender->GetInv().HasItem(keyneeded, 1); if(haskey != SLOT_INVALID) { 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); // /\ possible missing line..all other 'fail' returns seem to have it 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(PICK_LOCK)) { if(lockpicks->GetItem()->ItemType == ItemTypeLockPick) { float modskill=sender->GetSkill(PICK_LOCK); sender->CheckIncreaseSkill(PICK_LOCK, nullptr, 1); #if EQDEBUG>=5 LogFile->write(EQEMuLog::Debug, "Client has lockpicks: skill=%f", modskill); #endif 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(), dest_x, dest_y, dest_z, dest_heading); } 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(), dest_x, dest_y, dest_z, dest_heading); } else { sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, dest_x, dest_y, dest_z, dest_heading); } } if (( !IsDoorOpen() || opentype == 58 ) && (!keyneeded)) { if(database.GetZoneID(dest_zone) == zone->GetZoneID()) { sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading); } else { sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, dest_x, dest_y, dest_z, dest_heading); } } } }