Procházet zdrojové kódy

Added support for viewpointvalue command (#3754)

Additionally added a script command to update the player's camera.
Added a new atcommand camerainfo for this, which is limited to admins.

Credits to @4144 for finding /setcamera
Lemongrass3110 před 6 roky
rodič
revize
4944491228

+ 1 - 0
conf/atcommand_athena.conf

@@ -64,6 +64,7 @@ aliases: {
 	clonestat: ["stclone"]
 	reloadnpcfile: ["reloadnpc"]
 	changedress: ["nocosplay"]
+	camerainfo: ["viewpointvalue", "setcamera"]
 }
 
 /* Commands help file */

+ 1 - 0
conf/help.txt

@@ -325,3 +325,4 @@ reload: "Params: <type>\n" "Reload a database or configuration file.\n"
 langtype: "Params: <language>\n" "Changes your language setting."
 limitedsale: "Opens the limited sale window."
 changedress: "Removes all character costumes."
+camerainfo: "Shows or updates the client's camera settings."

+ 3 - 1
conf/msg_conf/map_msg.conf

@@ -855,7 +855,9 @@
 // Private Airship
 792: The private airship system is disabled.
 
-//793-899 free
+793: Usage @camerainfo range rotation latitude
+
+//794-899 free
 
 //------------------------------------
 // More atcommands message

+ 1 - 0
doc/packet_struct_notation.txt

@@ -59,6 +59,7 @@ values.
  B = 1 byte (byte)
  W = 2 bytes (word)
  L = 4 bytes (long, dword)
+ F = 4 bytes (float)
  Q = 8 bytes (quad)
 
  nB = n bytes

+ 22 - 0
doc/script_commands.txt

@@ -7659,6 +7659,28 @@ and attempt to execute a source-defined command.
 The three .@atcmd_***** variables will NOT be set when invoking script-bound atcommands
 in this way.
 
+---------------------------------------
+
+*camerainfo <range>,<rotation>,<latitude>{,<char id>};
+
+This command will update the client's camera information with the given values where
+the client can be the attached character or the player given by the char id parameter.
+Note: This requires 2016-05-25aRagexeRE or newer.
+
+The values given will be divided by 100 and transmitted as floating-point number.
+
+	range		The zoomfactor of the camera.
+				Default: 230000 (230.0) when fully zoomed in
+				Maximum: 400000 (400.0) when fully zoomed out
+
+	rotation	The rotation of the camera.
+				Default: 0 (0.0) when no rotation is applied
+				Maximum: 360000 (360.0°) when fully rotated
+
+	latitude	The angle of the camera.
+				Default: -50000 (-50.0)
+				Maximum: -75000 (-75.0)
+
 ---------------------------------------
 \\
 6,1.- Unit-related commands

+ 2 - 0
src/common/socket.hpp

@@ -32,6 +32,8 @@
 #define WFIFOW(fd,pos) (*(uint16*)WFIFOP(fd,pos))
 #define RFIFOL(fd,pos) (*(uint32*)RFIFOP(fd,pos))
 #define WFIFOL(fd,pos) (*(uint32*)WFIFOP(fd,pos))
+#define RFIFOF(fd,pos) (*(float*)RFIFOP(fd,pos))
+#define WFIFOF(fd,pos) (*(float*)WFIFOP(fd,pos))
 #define RFIFOQ(fd,pos) (*(uint64*)RFIFOP(fd,pos))
 #define WFIFOQ(fd,pos) (*(uint64*)WFIFOP(fd,pos))
 #define RFIFOSPACE(fd) (session[fd]->max_rdata - session[fd]->rdata_size)

+ 27 - 0
src/map/atcommand.cpp

@@ -10002,6 +10002,32 @@ ACMD_FUNC(limitedsale){
 	return 0;
 }
 
+/**
+ * Displays camera information from the client.
+ * Usage: @camerainfo or client command /viewpointvalue or /setcamera on supported clients
+ */
+ACMD_FUNC(camerainfo){
+	nullpo_retr(-1, sd);
+
+	if( message == nullptr || message[0] == '\0' ){
+		clif_camerainfo( sd, true );
+		return 0;
+	}
+
+	float range = 0;
+	float rotation = 0;
+	float latitude = 0;
+
+	if( sscanf( message, "%f %f %f", &range, &rotation, &latitude ) < 3 ){
+		clif_displaymessage( fd, msg_txt( sd, 793 ) ); // Usage @camerainfo range rotation latitude
+		return -1;
+	}
+
+	clif_camerainfo( sd, false, range, rotation, latitude );
+
+	return 0;
+}
+
 #include "../custom/atcommand.inc"
 
 /**
@@ -10301,6 +10327,7 @@ void atcommand_basecommands(void) {
 		ACMD_DEF(agitend3),
 		ACMD_DEFR(limitedsale, ATCMD_NOCONSOLE|ATCMD_NOAUTOTRADE),
 		ACMD_DEFR(changedress, ATCMD_NOCONSOLE|ATCMD_NOAUTOTRADE),
+		ACMD_DEFR(camerainfo, ATCMD_NOCONSOLE|ATCMD_NOAUTOTRADE),
 	};
 	AtCommandInfo* atcommand;
 	int i;

+ 33 - 0
src/map/clif.cpp

@@ -20565,6 +20565,39 @@ void clif_guild_storage_log( struct map_session_data* sd, std::vector<struct gui
 #endif
 }
 
+/// Activates the client camera info or updates the client camera with the given values.
+/// 0A78 <type>.B <range>.F <rotation>.F <latitude>.F
+void clif_camerainfo( struct map_session_data* sd, bool show, float range, float rotation, float latitude ){
+#if PACKETVER >= 20160525
+	int fd = sd->fd;
+
+	WFIFOHEAD(fd, packet_len(0xa78));
+	WFIFOW(fd, 0) = 0xa78;
+	WFIFOB(fd, 2) = show;
+	WFIFOF(fd, 3) = range;
+	WFIFOF(fd, 7) = rotation;
+	WFIFOF(fd, 11) = latitude;
+	WFIFOSET(fd, packet_len(0xa78));
+#endif
+}
+
+/// Activates or deactives the client camera info or updates the camera settings.
+/// This packet is triggered by /viewpointvalue or /setcamera
+/// 0A77 <type>.B <range>.F <rotation>.F <latitude>.F
+void clif_parse_camerainfo( int fd, struct map_session_data* sd ){
+	char command[CHAT_SIZE_MAX];
+
+	// /viewpointvalue
+	if( RFIFOB( fd, 2 ) == 1 ){
+		safesnprintf( command, sizeof( command ), "%ccamerainfo", atcommand_symbol );
+	// /setcamera
+	}else{
+		safesnprintf( command, sizeof( command ), "%ccamerainfo %03.03f %03.03f %03.03f", atcommand_symbol, RFIFOF( fd, 3 ), RFIFOF( fd, 7 ), RFIFOF( fd, 11 ) );
+	}
+
+	is_atcommand( fd, sd, command, 1 );
+}
+
 /*==========================================
  * Main client packet processing function
  *------------------------------------------*/

+ 2 - 0
src/map/clif.hpp

@@ -1101,4 +1101,6 @@ void clif_weight_limit( struct map_session_data* sd );
 
 void clif_guild_storage_log( struct map_session_data* sd, std::vector<struct guild_log_entry>& log, enum e_guild_storage_log result );
 
+void clif_camerainfo( struct map_session_data* sd, bool show, float range = 0.0f, float rotation = 0.0f, float latitude = 0.0f );
+
 #endif /* CLIF_HPP */

+ 6 - 0
src/map/clif_packetdb.hpp

@@ -2317,6 +2317,12 @@
 	parseable_packet(0x0A6E,-1,clif_parse_Mail_send,2,4,28,52,60,62,64,68); // CZ_REQ_WRITE_MAIL2
 #endif
 
+// 2016-05-25aRagexeRE
+#if PACKETVER >= 20160525
+	parseable_packet(0x0A77,15,clif_parse_camerainfo,0);
+	packet(0x0A78, 15);
+#endif
+
 // 2016-06-01aRagexe
 #if PACKETVER >= 20160601
 	packet(0x0A7D,-1);

+ 18 - 0
src/map/script.cpp

@@ -24043,6 +24043,23 @@ BUILDIN_FUNC(is_party_leader)
 	return SCRIPT_CMD_SUCCESS;
 }
 
+BUILDIN_FUNC( camerainfo ){
+#if PACKETVER < 20160525
+	ShowError("buildin_camerainfo: This command requires PACKETVER 2016-05-25 or newer.\n");
+	return SCRIPT_CMD_FAILURE;
+#else
+	struct map_session_data* sd;
+
+	if( !script_charid2sd( 5, sd ) ){
+		return SCRIPT_CMD_FAILURE;
+	}
+
+	clif_camerainfo( sd, false, script_getnum( st, 2 ) / 100.0f, script_getnum( st, 3 ) / 100.0f, script_getnum( st, 4 ) / 100.0f );
+
+	return SCRIPT_CMD_SUCCESS;
+#endif
+}
+
 #include "../custom/script.inc"
 
 // declarations that were supposed to be exported from npc_chat.c
@@ -24705,6 +24722,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(identifyall,"??"),
 	BUILDIN_DEF(is_guild_leader,"?"),
 	BUILDIN_DEF(is_party_leader,"?"),
+	BUILDIN_DEF(camerainfo,"iii?"),
 #include "../custom/script_def.inc"
 
 	{NULL,NULL,NULL},