Esempio n. 1
0
void Doors::NPCOpen(NPC* sender, bool alt_mode)
{
	if(sender) {
		if(GetTriggerType() == 255 || (GetTriggerDoorID() > 0 && IsDoorOpen()) || GetLockpick() != 0 || GetKeyItem() != 0 || opentype == 59 || opentype == 58 || !sender->IsNPC()) { // this object isnt triggered or door is locked - NPCs should not open locked doors!
			return;
		}

		EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
		MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer;
		md->doorid = door_id;
		md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
		entity_list.QueueCloseClients(sender,outapp,false,200);
		safe_delete(outapp);


		if(!alt_mode) { // original function
			if(!isopen) {
				close_timer.Start();
				isopen=true;
			}
			else {
				close_timer.Disable();
				isopen=false;
			}
		}
		else { // alternative function
			close_timer.Start();
			isopen=true;
		}
	}
}
Esempio n. 2
0
void Doors::ToggleState(Mob *sender)
{
	if(GetTriggerDoorID() > 0 || GetLockpick() != 0 || GetKeyItem() != 0 || opentype == 58 || opentype == 40) { // borrowed some NPCOpen criteria
		return;
	}

	EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
	MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer;
	md->doorid = door_id;

	if(!isopen) {
		md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
		isopen=true;
	}
	else
	{
		md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
		isopen=false;
	}

	entity_list.QueueClients(sender,outapp,false);
	safe_delete(outapp);
}
Esempio n. 3
0
void Doors::CreateDatabaseEntry()
{
	if (database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()) - 1 >= 255) {
		return;
	}

	/**
	 * Persist
	 */
	database.InsertDoor(
		GetDoorDBID(),
		GetDoorID(),
		GetDoorName(),
		m_Position,
		GetOpenType(),
		static_cast<uint16>(GetGuildID()),
		GetLockpick(),
		GetKeyItem(),
		static_cast<uint8>(GetDoorParam()),
		static_cast<uint8>(GetInvertState()),
		GetIncline(),
		GetSize()
	);
}
Esempio n. 4
0
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);
			}
		}
	}
}
Esempio n. 5
0
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
				);
			}
		}
	}
}
Esempio n. 6
0
void Doors::CreateDatabaseEntry()
{
	if(database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()) - 1 >= 255)
	{
		return;
	}
	database.InsertDoor(GetDoorDBID(), GetDoorID(), GetDoorName(), GetX(), GetY(), GetZ(), GetHeading(), GetOpenType(), GetGuildID(), GetLockpick(), GetKeyItem(), GetDoorParam(), GetInvertState(), GetIncline(), GetSize());
}
Esempio n. 7
0
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);
			}
		}
	}
}