View Single Post
  #3  
Old 06-13-2012, 03:25 AM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

This patch incorporates both the 'inverted' door fix and the 'opentype 40' door fix. (patched, compiled, verified)

(If you applied my previous inverted door patch, make sure you apply this to the revision file and not the patched file. If you don't
know how to revert, just delete your doors.cpp and then svn update to get it back to revision.)


doors.cpp.patch
Code:
Index: doors.cpp
===================================================================
--- doors.cpp	(revision 2145)
+++ doors.cpp	(working copy)
@@ -31,6 +31,8 @@
 
 #define OPEN_DOOR 0x02
 #define CLOSE_DOOR 0x03
+#define OPEN_INVDOOR 0x03  // U: Added inverted
+#define CLOSE_INVDOOR 0x02 // action definitions
 
 extern EntityList entity_list;
 extern WorldServer worldserver;
@@ -120,7 +122,22 @@
 {
     if(close_timer.Enabled() && close_timer.Check() && IsDoorOpen())
     {
-	triggered=false;
+		// U: Added zone broadcast 'close door' action to satisfy opentype 40 close requirement.  Otherwise, all clients (tested)
+		// will spam the server with 'click' events until it is reset.  This method ensures a 'close' action is broadcast to each
+		// client in zone regardless of who originated the request.  If the close_timer is ever disabled in code without allowing
+		// Process() to handle a broadcast, and the procedure also issues a md->action = 'open door' command, then it should be
+		// written to account for having to deal with this repeating 'bounce' issue. (i.e., Doors::ForceOpen())
+		if (opentype == 40)
+		{
+			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 ? CLOSE_DOOR : CLOSE_INVDOOR;
+			entity_list.QueueClients(0, outapp);
+			safe_delete(outapp);
+		}
+		
+		triggered=false;
         close_timer.Disable();
         SetOpenState(false);
     }
@@ -143,6 +160,15 @@
 	//TODO: add check for other lockpick items
 	//////////////////////////////////////////////////////////////////
 
+	// U: I left in my test code in case someone needs to work on trigger doors in the database. It can be removed from
+	// revision if it's not warranted to be here. All test code is suffixed with: '// U: Test code'
+
+	//sender->Message(4, "door:%i->doortype (dty:%i) [start]", door_id, GetOpenType()); // U: Test code
+	//sender->Message(4, "door:%i->doorstate (ds:%s | ti:%s)", door_id, IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
+	//sender->Message(4, "door:%i->trigger (tid:%i | ts:%s | tty:%i)", door_id, trigger, triggered ? "T" : "F", GetTriggerType()); // U: Test code
+	//sender->Message(4, "door:%i->triggerdoor (tdid:%i)", door_id, GetTriggerDoorID()); // U: Test code
+	//sender->Message(4, "door:%i->client (xp:%f | yp:%f | zp:%f)", door_id, sender->GetX(), sender->GetY(), sender->GetZ()); // U: Test code
+
 	//TODO: ADVENTURE DOOR
 	if(IsLDoNDoor())
 	{
@@ -200,11 +226,13 @@
 		{ // this door is only triggered by an object
 			if(!IsDoorOpen() || (opentype == 58))
 			{
-				md->action = OPEN_DOOR;
+				md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
+				//sender->Message(4, "door:%i->%s(ds:%s | ti:%s) [objtrgd]", door_id, invert_state == 0 ? "open" : "invopen", IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
 			}
 			else
 			{
-				md->action = CLOSE_DOOR;
+				md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
+				//sender->Message(4, "door:%i->%s(ds:%s | ti:%s) [objtrgd]", door_id, invert_state == 0 ? "close" : "invclose", IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
 			}
 		}
 		else
@@ -221,11 +249,13 @@
 	{	//door not locked
 		if(!IsDoorOpen() || (opentype == 58))
 		{
-			md->action = OPEN_DOOR;
+			md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
+			//sender->Message(4, "door:%i->%s(ds:%s | ti:%s) [unlckd]", door_id, invert_state == 0 ? "open" : "invopen", IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
 		}
 		else
 		{
-			md->action = CLOSE_DOOR;
+			md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
+			//sender->Message(4, "door:%i->%s(ds:%s | ti:%s) [unlckd]", door_id, invert_state == 0 ? "close" : "invclose", IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
 		}
 	}
 	else
@@ -243,6 +273,8 @@
 				strcpy(tmpmsg, "Door is locked by an unknown guild");
 			}
 			sender->Message(4, tmpmsg);
+			// safe_delete(outapp);
+			// U: Does this need to be added? All other 'fail' returns seem to have one - not tested (deletable message)
 			return;
 		}
 		// a key is required or the door is locked but can be picked or both
@@ -252,11 +284,13 @@
 			sender->Message_StringID(4,DOORS_GM);
 			if(!IsDoorOpen() || (opentype == 58))
 			{
-				md->action = OPEN_DOOR;
+				md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
+				//sender->Message(4, "door:%i->%s(ds:%s | ti:%s) [gmkey]", door_id, invert_state == 0 ? "open" : "invopen", IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
 			}
 			else
 			{
-				md->action = CLOSE_DOOR;
+				md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
+				//sender->Message(4, "door:%i->%s(ds:%s | ti:%s) [gmkey]", door_id, invert_state == 0 ? "close" : "invclose", IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
 			}
 		}
 		else if(playerkey)
@@ -270,11 +304,13 @@
 				sender->Message(4, "You got it open!");
 				if(!IsDoorOpen() || (opentype == 58))
 				{
-					md->action = OPEN_DOOR;
+					md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
+					//sender->Message(4, "door:%i->%s(ds:%s | ti:%s) [keyitem]", door_id, invert_state == 0 ? "open" : "invopen", IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
 				}
 				else
 				{
-					md->action = CLOSE_DOOR;
+					md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
+					//sender->Message(4, "door:%i->%s(ds:%s | ti:%s) [keyitem]", door_id, invert_state == 0 ? "close" : "invclose", IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
 				}
 			}
 		}
@@ -295,11 +331,13 @@
 					{
 						if(!IsDoorOpen())
 						{
-							md->action = OPEN_DOOR;
+							md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
+							//sender->Message(4, "door:%i->%s(ds:%s | ti:%s) [picklock]", door_id, invert_state == 0 ? "open" : "invopen", IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
 						}
 						else
 						{
-							md->action = CLOSE_DOOR;
+							md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
+							//sender->Message(4, "door:%i->%s(ds:%s | ti:%s) [picklock]", door_id, invert_state == 0 ? "close" : "invclose", IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
 						}
 						sender->Message_StringID(4, DOORS_SUCCESSFUL_PICK);
 					}
@@ -333,11 +371,13 @@
 				sender->Message(4, "You got it open!"); // more debug spam
 				if(!IsDoorOpen() || (opentype == 58))
 				{ 
-					md->action = OPEN_DOOR; 
+					md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
+					//sender->Message(4, "door:%i->%s(ds:%s | ti:%s) [keyring]", door_id, invert_state == 0 ? "open" : "invopen", IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
 				} 
 				else
 				{ 
-					md->action = CLOSE_DOOR; 
+					md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
+					//sender->Message(4, "door:%i->%s(ds:%s | ti:%s) [keyring]", door_id, invert_state == 0 ? "close" : "invclose", IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
 				} 
 			}
 			else 
@@ -361,11 +401,14 @@
 		SetOpenState(false);
 	}
 
+	//sender->Message(4, "door:%i->timer(ds:%s | ti:%s) [end]", door_id, IsDoorOpen() ? "O" : "C", close_timer.Enabled() ? "E" : "D"); // U: Test code
+	//sender->Message(4, "---end of call---"); // U: Test code
+
 	//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)
+	if((md->action == CLOSE_DOOR && invert_state == 0) || (md->action == CLOSE_INVDOOR && invert_state == 1))
 	{
 		safe_delete(outapp);
 		return;
@@ -439,9 +482,14 @@
 	}
 }
 
+// U: I am looking into a proper fix for 'NPCOpen,' 'ForceOpen' and 'ForceClose.'  I have not incorporated the opentype 40
+// fix into the current code to avoid introducing erratic scripting behavior, but I did correct the 'md->action =' and
+// changed 'ForceClose' to the untested suggestion that Trev gave last summer.
+
 void Doors::NPCOpen(NPC* sender)
 {
 	if(sender) {
+		// U: NPC's should probably not be allowed to open type 40 doors either.  Just ForceOpen the actual door. 
 		if(GetTriggerType() == 255 || GetTriggerDoorID() > 0 || 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;
 		}
@@ -449,7 +497,7 @@
 		EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
 		MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer;
 		md->doorid = door_id;
-		md->action = OPEN_DOOR;
+		md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
 		entity_list.QueueCloseClients(sender,outapp,false,200);
 		safe_delete(outapp);
 
@@ -469,7 +517,7 @@
     EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
 	MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer;
 	md->doorid = door_id;
-	md->action = OPEN_DOOR;
+	md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
 	entity_list.QueueClients(sender,outapp,false);
 	safe_delete(outapp);
 
@@ -488,15 +536,11 @@
     EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
 	MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer;
 	md->doorid = door_id;
-	md->action = OPEN_DOOR;
+	md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
 	entity_list.QueueClients(sender,outapp,false);
 	safe_delete(outapp);
 
-    if(!isopen) {
-        close_timer.Start();
-        isopen=true;
-    }
-    else {
+    if(isopen) {
         close_timer.Disable();
         isopen=false;
     }

This patch should fix door-state logic issues, but not any scripted or database value problems.


U
__________________
Uleat of Bertoxxulous

Compilin' Dirty
Reply With Quote