Scandum 6 лет назад
Родитель
Сommit
7ea23cc707
25 измененных файлов с 402 добавлено и 530 удалено
  1. 1 1
      NEWS
  2. 1 1
      README
  3. 3 10
      TODO
  4. 14 0
      mods/igr.mods
  5. 1 1
      src/buffer.c
  6. 28 19
      src/class.c
  7. 1 1
      src/daemon.c
  8. 54 24
      src/data.c
  9. 2 6
      src/draw.c
  10. 52 15
      src/help.c
  11. 41 56
      src/log.c
  12. 68 20
      src/mapper.c
  13. 6 6
      src/misc.c
  14. 0 1
      src/parse.c
  15. 15 9
      src/screen.c
  16. 88 80
      src/substitute.c
  17. 2 2
      src/tables.c
  18. 9 7
      src/telopt_client.c
  19. 6 1
      src/text.c
  20. 3 1
      src/tintin.h
  21. 1 1
      src/update.c
  22. 3 263
      src/utf8.c
  23. 2 2
      src/utils.c
  24. 1 1
      src/variable.c
  25. 0 2
      src/vt102.c

+ 1 - 1
NEWS

@@ -1,7 +1,7 @@
 Due to continuous improvements old tintin scripts aren't always compatible
 Due to continuous improvements old tintin scripts aren't always compatible
 with new versions. This document tries to list most compatibility conflicts.
 with new versions. This document tries to list most compatibility conflicts.
 
 
-TinTin++ 2.01.93
+TinTin++ 2.02.00
 ----------------
 ----------------
 
 
 01) #format <var> %C needs to be changed to #screen get cols <var>
 01) #format <var> %C needs to be changed to #screen get cols <var>

+ 1 - 1
README

@@ -33,5 +33,5 @@ COPYRIGHT
 
 
 WEBSITE
 WEBSITE
 
 
-  https://tintin.sourceforge.io
+  https://tintin.mudhalla.net
 
 

+ 3 - 10
TODO

@@ -1,17 +1,8 @@
 * BUGS
 * BUGS
 
 
-
 * STUFF THAT IS PROBABLY GONNA GET DONE
 * STUFF THAT IS PROBABLY GONNA GET DONE
 
 
-  - #map exit <exit> dir is not updating the room grid.
-
-  - html log improvements
-  
-  - ascii draw mode for #screen fill DEFAULT
-
-  - #info unicode <character>
-
-  - pancake mode to display rooms at all levels and annotations
+  - provide the coordinate of the X on the vtmap.
 
 
   - screen move, negative arg handling.
   - screen move, negative arg handling.
 
 
@@ -23,6 +14,8 @@
   - #map legend support for unicode graphics.
   - #map legend support for unicode graphics.
   - add step count for #map list and rename distance to weight
   - add step count for #map list and rename distance to weight
   - multi-line room symbols
   - multi-line room symbols
+  - pancake mode to display rooms at all levels and annotations
+  - there might be a terrain density bug
 
 
   - #math idea: 4 === 2+2 === 8-4
   - #math idea: 4 === 2+2 === 8-4
   - #math true/false handling?
   - #math true/false handling?

+ 14 - 0
mods/igr.mods

@@ -1,3 +1,17 @@
+Jan 2020        2.02.01
+------------------------------------------------------------------------------
+
+data.c          Added CWD field to #info system to get the current working
+                directory.
+
+data.c          Added the option to use #var var[\+1] to set and retrieve a
+                literal +1 instead of referencing the first index. This
+                behaves like the verbatim mode and the backslash is only
+                valid at the start of the line.
+
+data.c          Added #info unicode <character> option to display
+                information about the provided character.
+
 Nov 2019        2.02.00
 Nov 2019        2.02.00
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 

+ 1 - 1
src/buffer.c

@@ -97,7 +97,7 @@ void check_buffer(struct session *ses)
 	{
 	{
 		buffer = ses->scroll->buffer[index];
 		buffer = ses->scroll->buffer[index];
 
 
-		if (buffer->height == 1 && buffer->width < wrap - 1)
+		if (buffer->width < wrap)
 		{
 		{
 			buffer->height = buffer->lines;
 			buffer->height = buffer->lines;
 		}
 		}

+ 28 - 19
src/class.c

@@ -140,35 +140,44 @@ DO_CLASS(class_clear)
 
 
 DO_CLASS(class_close)
 DO_CLASS(class_close)
 {
 {
-	if (atoi(node->arg3) == 0)
+	node = search_node_list(ses->list[LIST_CLASS], arg1);
+
+	if (node == NULL)
 	{
 	{
-		show_message(ses, LIST_CLASS, "#CLASS {%s} IS ALREADY CLOSED.", arg1);
+		show_message(ses, LIST_CLASS, "#CLASS {%s} NO LONGER EXIST.", arg1);
 	}
 	}
 	else
 	else
 	{
 	{
-		show_message(ses, LIST_CLASS, "#CLASS {%s} HAS BEEN CLOSED.", arg1);
-
-		update_node_list(ses->list[LIST_CLASS], arg1, "", "0","");
-
-		if (!strcmp(ses->group, arg1))
+		if (atoi(node->arg3) == 0)
 		{
 		{
-			check_all_events(ses, SUB_ARG, 0, 1, "CLASS DEACTIVATED", ses->group);
-			check_all_events(ses, SUB_ARG, 1, 1, "CLASS DEACTIVATED %s", ses->group, ses->group);
+			show_message(ses, LIST_CLASS, "#CLASS {%s} IS ALREADY CLOSED.", arg1);
+		}
+		else
+		{
+			show_message(ses, LIST_CLASS, "#CLASS {%s} HAS BEEN CLOSED.", arg1);
 
 
-			node = ses->list[LIST_CLASS]->list[0];
+			update_node_list(ses->list[LIST_CLASS], arg1, "", "0","");
 
 
-			if (atoi(node->arg3))
+			if (!strcmp(ses->group, arg1))
 			{
 			{
-				RESTRING(ses->group, node->arg1);
+				check_all_events(ses, SUB_ARG, 0, 1, "CLASS DEACTIVATED", ses->group);
+				check_all_events(ses, SUB_ARG, 1, 1, "CLASS DEACTIVATED %s", ses->group, ses->group);
 
 
-				show_message(ses, LIST_CLASS, "#CLASS {%s} HAS BEEN ACTIVATED.", node->arg1);
+				node = ses->list[LIST_CLASS]->list[0];
 
 
-				check_all_events(ses, SUB_ARG, 0, 1, "CLASS ACTIVATED", node->arg1);
-				check_all_events(ses, SUB_ARG, 1, 1, "CLASS ACTIVATED %s", arg1, arg1);
-			}
-			else
-			{
-				RESTRING(ses->group, "");
+				if (atoi(node->arg3))
+				{
+					RESTRING(ses->group, node->arg1);
+
+					show_message(ses, LIST_CLASS, "#CLASS {%s} HAS BEEN ACTIVATED.", node->arg1);
+
+					check_all_events(ses, SUB_ARG, 0, 1, "CLASS ACTIVATED", node->arg1);
+					check_all_events(ses, SUB_ARG, 1, 1, "CLASS ACTIVATED %s", arg1, arg1);
+				}
+				else
+				{
+					RESTRING(ses->group, "");
+				}
 			}
 			}
 		}
 		}
 	}
 	}

+ 1 - 1
src/daemon.c

@@ -649,7 +649,7 @@ void reset_daemon()
 {
 {
 	if (gtd->detach_sock > 0)
 	if (gtd->detach_sock > 0)
 	{
 	{
-		print_stdout("removing(%s)\n", gtd->detach_file);
+//		print_stdout("removing(%s)\n", gtd->detach_file);
 
 
 		remove(gtd->detach_file);
 		remove(gtd->detach_file);
 	}
 	}

+ 54 - 24
src/data.c

@@ -134,7 +134,14 @@ struct listnode *insert_node_list(struct listroot *root, char *arg1, char *arg2,
 		strcpy(arg3, "5");
 		strcpy(arg3, "5");
 	}
 	}
 
 
-	node->arg1 = str_dup(arg1);
+	if (HAS_BIT(root->flags, LIST_FLAG_NEST) && *arg1 == '\\')
+	{
+		node->arg1 = str_dup(arg1+1);
+	}
+	else
+	{
+		node->arg1 = str_dup(arg1);
+	}
 	node->arg2 = str_dup(arg2);
 	node->arg2 = str_dup(arg2);
 	node->arg3 = str_dup(arg3);
 	node->arg3 = str_dup(arg3);
 	node->arg4 = str_dup(arg4);
 	node->arg4 = str_dup(arg4);
@@ -392,33 +399,37 @@ int bsearch_alpha_list(struct listroot *root, char *text, int seek)
 
 
 	push_call("bsearch_alpha_list(%p,%p,%d)",root,text,seek);
 	push_call("bsearch_alpha_list(%p,%p,%d)",root,text,seek);
 
 
-	bot = 0;
-	top = root->used - 1;
-	val = top;
+	if (seek == 0 && HAS_BIT(root->flags, LIST_FLAG_NEST))
+	{
+		switch (*text)
+		{
+			case '+':
+			case '-':
+				toi = get_number(root->ses, text);
 
 
-//	toi = get_number(root->ses, text);
+				if (toi > 0 && toi <= root->used)
+				{
+					pop_call();
+					return toi - 1;
+				}
 
 
-	if (seek == 0 && (*text == '+' || *text == '-') && is_math(root->ses, text) && HAS_BIT(root->flags, LIST_FLAG_NEST))
-	{
-		toi = get_number(root->ses, text);
+				if (toi < 0 && toi + root->used >= 0)
+				{
+					pop_call();
+					return root->used + toi;
+				}
+				break;
 
 
-		if (toi > 0 && toi <= root->used)
-		{
-			pop_call();
-			return toi - 1;
-		}
-		if (toi < 0 && toi + root->used >= 0)
-		{
-			pop_call();
-			return root->used + toi;
-		}
-		else
-		{
-			pop_call();
-			return -1;
+			case '\\':
+				text++;
+				break;
 		}
 		}
 	}
 	}
 
 
+	bot = 0;
+	top = root->used - 1;
+	val = top;
+
 	toi = is_number(text) ? tintoi(text) : 0;
 	toi = is_number(text) ? tintoi(text) : 0;
 
 
 	while (bot <= top)
 	while (bot <= top)
@@ -1122,13 +1133,17 @@ DO_COMMAND(do_info)
 			}
 			}
 			else if (is_abbrev(arg1, "SYSTEM"))
 			else if (is_abbrev(arg1, "SYSTEM"))
 			{
 			{
+				char cwd[PATH_MAX];
+
+				getcwd(cwd, PATH_MAX);
+
 				if (is_abbrev(arg2, "SAVE"))
 				if (is_abbrev(arg2, "SAVE"))
 				{
 				{
 					sprintf(name, "info[SYSTEM]");
 					sprintf(name, "info[SYSTEM]");
 
 
 					set_nest_node_ses(ses, name, "{CLIENT_NAME}{%s}{CLIENT_VERSION}{%s}", CLIENT_NAME, CLIENT_VERSION);
 					set_nest_node_ses(ses, name, "{CLIENT_NAME}{%s}{CLIENT_VERSION}{%s}", CLIENT_NAME, CLIENT_VERSION);
-					add_nest_node_ses(ses, name, "{CLIENT}{{NAME}{%s}{VERSION}{%s}}", CLIENT_NAME, CLIENT_VERSION);
-					add_nest_node_ses(ses, name, "{EXEC}{%s}{HOME}{%s}{LANG}{%s}{OS}{%s}{TERM}{%s}", gtd->exec, gtd->home, gtd->lang, gtd->os, gtd->term);
+//					add_nest_node_ses(ses, name, "{CLIENT}{{NAME}{%s}{VERSION}{%s}}", CLIENT_NAME, CLIENT_VERSION);
+					add_nest_node_ses(ses, name, "{CWD}{%s}{EXEC}{%s}{HOME}{%s}{LANG}{%s}{OS}{%s}{TERM}{%s}", cwd, gtd->exec, gtd->home, gtd->lang, gtd->os, gtd->term);
 					add_nest_node_ses(ses, name, "{DETACH_FILE}{%s}{ATTACH_FILE}{%s}", gtd->detach_port > 0 ? gtd->detach_file : "", gtd->attach_sock > 0 ? gtd->attach_file : "");
 					add_nest_node_ses(ses, name, "{DETACH_FILE}{%s}{ATTACH_FILE}{%s}", gtd->detach_port > 0 ? gtd->detach_file : "", gtd->attach_sock > 0 ? gtd->attach_file : "");
 
 
 					show_message(ses, LIST_COMMAND, "#INFO: DATA WRITTEN TO {info[SYSTEM]}");
 					show_message(ses, LIST_COMMAND, "#INFO: DATA WRITTEN TO {info[SYSTEM]}");
@@ -1137,6 +1152,7 @@ DO_COMMAND(do_info)
 				{
 				{
 					tintin_printf2(ses, "#INFO SYSTEM: CLIENT_NAME    = %s", CLIENT_NAME);
 					tintin_printf2(ses, "#INFO SYSTEM: CLIENT_NAME    = %s", CLIENT_NAME);
 					tintin_printf2(ses, "#INFO SYSTEM: CLIENT_VERSION = %s", CLIENT_VERSION);
 					tintin_printf2(ses, "#INFO SYSTEM: CLIENT_VERSION = %s", CLIENT_VERSION);
+					tintin_printf2(ses, "#INFO SYSTEM: CWD            = %s", cwd);
 					tintin_printf2(ses, "#INFO SYSTEM: EXEC           = %s", gtd->exec);
 					tintin_printf2(ses, "#INFO SYSTEM: EXEC           = %s", gtd->exec);
 					tintin_printf2(ses, "#INFO SYSTEM: HOME           = %s", gtd->home);
 					tintin_printf2(ses, "#INFO SYSTEM: HOME           = %s", gtd->home);
 					tintin_printf2(ses, "#INFO SYSTEM: LANG           = %s", gtd->lang);
 					tintin_printf2(ses, "#INFO SYSTEM: LANG           = %s", gtd->lang);
@@ -1148,6 +1164,20 @@ DO_COMMAND(do_info)
 					tintin_printf2(ses, "#INFO SYSTEM: ATTACH_FILE    = %s", gtd->attach_sock ? gtd->attach_file : "");
 					tintin_printf2(ses, "#INFO SYSTEM: ATTACH_FILE    = %s", gtd->attach_sock ? gtd->attach_file : "");
 				}
 				}
 			}
 			}
+			else if (is_abbrev(arg1, "UNICODE"))
+			{
+				int size, width, index;
+
+				size = get_utf8_size(arg2);
+				get_utf8_width(arg2, &width);
+				get_utf8_index(arg2, &index);
+
+				tintin_printf2(ses, "#INFO UNICODE: %s:  is_utf8_head  = %d (%s)", arg2, is_utf8_head(arg2), is_utf8_head(arg2) ? "true" : "false");
+				tintin_printf2(ses, "#INFO UNICODE: %s: get_utf8_size  = %d", arg2, size);
+				tintin_printf2(ses, "#INFO UNICODE: %s: get_utf8_width = %d", arg2, width);
+				tintin_printf2(ses, "#INFO UNICODE: %s: get_utf8_index = %d (decimal)", arg2, index);
+				tintin_printf2(ses, "#INFO UNICODE: %s: get_utf8_index = %x (hexadecimal)", arg2, index);
+			}
 			else
 			else
 			{
 			{
 				show_error(ses, LIST_COMMAND, "#INFO {%s} - NO MATCH FOUND.", arg1);
 				show_error(ses, LIST_COMMAND, "#INFO {%s} - NO MATCH FOUND.", arg1);

+ 2 - 6
src/draw.c

@@ -1017,7 +1017,7 @@ DO_DRAW(draw_rain)
 {
 {
 	char code[BUFFER_SIZE], arg3[BUFFER_SIZE], arg4[BUFFER_SIZE], *rain[400];
 	char code[BUFFER_SIZE], arg3[BUFFER_SIZE], arg4[BUFFER_SIZE], *rain[400];
 	struct listnode *node;
 	struct listnode *node;
-	int skp, row, col, len, rand, cnt, size, max, utfs[400];
+	int row, col, len, rand, cnt, size, max, utfs[400];
 	long double density, fade;
 	long double density, fade;
 
 
 	strcpy(code, arg2);
 	strcpy(code, arg2);
@@ -1207,8 +1207,6 @@ DO_DRAW(draw_rain)
 		}
 		}
 		else if (node->root->list[col]->val16[0] > 1)
 		else if (node->root->list[col]->val16[0] > 1)
 		{
 		{
-			skp = 1;
-
 			while (row < len)
 			while (row < len)
 			{
 			{
 				if (node->root->list[col]->arg2[row] == ' ')
 				if (node->root->list[col]->arg2[row] == ' ')
@@ -1237,20 +1235,18 @@ DO_DRAW(draw_rain)
 					sprintf(arg2, "%s%.*s", fuzzy_color_code(ses, code), size, &node->root->list[col]->arg2[row]);
 					sprintf(arg2, "%s%.*s", fuzzy_color_code(ses, code), size, &node->root->list[col]->arg2[row]);
 					substitute(ses, arg2, arg3, SUB_COL);
 					substitute(ses, arg2, arg3, SUB_COL);
 					print_stdout("%s", arg3);
 					print_stdout("%s", arg3);
-					skp = 0;
 				}
 				}
 				else
 				else
 				{
 				{
 					sprintf(arg2, "%s%.*s", dim_color_code(ses, code, node->root->list[col]->val16[0] - cnt), size, &node->root->list[col]->arg2[row]);
 					sprintf(arg2, "%s%.*s", dim_color_code(ses, code, node->root->list[col]->val16[0] - cnt), size, &node->root->list[col]->arg2[row]);
 					substitute(ses, arg2, arg3, SUB_COL);
 					substitute(ses, arg2, arg3, SUB_COL);
 					print_stdout("%s", arg3);
 					print_stdout("%s", arg3);
-					skp = 0;
 				}
 				}
 
 
 				row += size;
 				row += size;
 			}
 			}
 
 
-			if (skp)
+			if (node->root->list[col]->val16[0] - cnt > 16)
 			{
 			{
 				node->root->list[col]->val16[0] = 0;
 				node->root->list[col]->val16[0] = 0;
 				node->root->list[col]->val16[1] = 0;
 				node->root->list[col]->val16[1] = 0;

+ 52 - 15
src/help.c

@@ -577,15 +577,38 @@ struct help_type help_table[] =
 	{
 	{
 		"CHAT",
 		"CHAT",
 
 
-		"<178>Command<278>: #chat <178>{<278>option<178>} {<278>argument<178>}<278>\n"
-		"\n"
-		"         #chat {init}       {port}             Initilizes a chat port.\n"
-		"         #chat {name}       {name}             Sets your chat name.\n"
-		"         #chat {message}    {buddy|all} {text} Sends a chat message\n"
-		"\n"
-		"         #chat {accept}     {buddy} {boost}    Accept a file transfer\n"
-		"         #chat {call}       {address} {port}   Connect to a buddy\n"
-		"         #chat {cancel}     {buddy}            Cancel a file transfer\n"
+		"<178>Command<278>: #chat <178>{<278>option<178>} {<278>argument<178>}\n"
+		"<278>\n"
+		"         The #chat command is used to create peer to peer connections to other\n"
+		"         clients, typically for the purpose of chatting and sending files.\n"
+		"         This is a decentralized chat system, meaning you have to exchange ip\n"
+		"         addresses and port numbers with other users in order to connect to\n"
+		"         them.\n"
+		"\n"
+		"         <178>#chat {init} {port}\n"
+		"         <278>  #chat initialize launches your chat server. The port number is\n"
+		"           optional, and by default 4050 is used as your port. After using\n"
+		"           this command other people can connect to your chat server using\n"
+		"           your ip address and port number, and in turn you can connect to\n"
+		"           other people.\n"
+		"         <178>#chat {name} {name}\n"
+		"         <278>  By default your name is set to TinTin, but most servers will\n"
+		"           reject you if there is already someone with the name TinTin\n"
+		"           connected, so one of the first things you'd want to do is\n"
+		"           change your chat name. Your name can include color codes. Some\n"
+		"           names aren't accepted by tt++ chat servers, like the name 'all'\n"
+		"           and names longer than 20 characters.\n"
+		"         <178>#chat {message} {buddy|all} {text}\n"
+		"         <278>  This is the main command used for communication. If you use\n"
+		"           #chat message all, the message is marked as public and send to\n"
+		"           everyone you are connected to.\n"
+		"         <178>#chat {accept} {buddy} {boost}\n"
+		"         <278>  Accept a file transfer from a buddy. The boost is optional and\n"
+		"           must be a value between 1 and 1000.\n"
+		"         <178>#chat {call}       {address} {port}\n"
+		"         <278>  #chat call is used to connect to another chat server. If you\n"
+		"           omit the port argument the default port (4050) is used.\n"
+		"         <178>#chat {cancel}     {buddy}            Cancel a file transfer\n"
 		"         #chat {color}      {color names}      Set the default color\n"
 		"         #chat {color}      {color names}      Set the default color\n"
 		"         #chat {decline}    {buddy}            Decline a file transfer\n"
 		"         #chat {decline}    {buddy}            Decline a file transfer\n"
 		"         #chat {dnd}                           Decline new connections\n"
 		"         #chat {dnd}                           Decline new connections\n"
@@ -609,15 +632,22 @@ struct help_type help_table[] =
 		"         #chat {sendfile}   {buddy} {filename} Start a file transfer\n"
 		"         #chat {sendfile}   {buddy} {filename} Start a file transfer\n"
 		"         #chat {serve}      {buddy}            Forward all public chat messages\n"
 		"         #chat {serve}      {buddy}            Forward all public chat messages\n"
 		"         #chat {uninitialize}                  Uninitialize the chat port.\n"
 		"         #chat {uninitialize}                  Uninitialize the chat port.\n"
-		"         #chat {who}                           Show all connections\n"
-		"         #chat {zap}        {buddy}            Close a connection\n",
+		"         <178>#chat {who}                           Show all connections\n"
+		"         <278>  #chat who shows all people you are connected to. The first\n"
+		"           column shows a reference number for the connection, which can be\n"
+		"           used instead of the connection's name when sending someone a message\n"
+		"           The second column shows the connection's name. The third column\n"
+		"           shows flags set for the connection, (P)rivate, (I)gnore, (S)erve,\n"
+		"           (F)orward to user, and (f)orward from user. The next columns show\n"
+		"           ip, port, and client name.\n"
+		"         <178>#chat {zap}        {buddy}            Close a connection\n",
 		
 		
 		"port"
 		"port"
 	},
 	},
 	{
 	{
 		"CLASS",
 		"CLASS",
 
 
-		"<178>Command<278>: #class <178>{<278>name<178>} {<278>open<178>|<278>close<178>|<278>list<178>|<278>read<178>|<278>size<178>|<278>write<178>|<278>kill<178>} {<278>arg<178>}<278>\n"
+		"<178>Command<278>: #class <178>{<278>name<178>} {<278>optionkill<178>} {<278>arg<178>}<278>\n"
 		"\n"
 		"\n"
 		"         <178>#class {<name>} {open}\n"
 		"         <178>#class {<name>} {open}\n"
 		"         <278>  Open a class, closing a previously opened class. All triggers\n"
 		"         <278>  Open a class, closing a previously opened class. All triggers\n"
@@ -790,8 +820,11 @@ struct help_type help_table[] =
 		"\n"
 		"\n"
 		"         The cursor command's primarly goal is adding customizable input editing\n"
 		"         The cursor command's primarly goal is adding customizable input editing\n"
 		"         with macros. Subsequently many cursor commands only work properly when\n"
 		"         with macros. Subsequently many cursor commands only work properly when\n"
-		"         used within a macro or event.\n",
-		
+		"         used within a macro or event.\n"
+		"\n"
+		"         <178>#cursor tab <list;scrollback> <backward|forward>\n"
+		"         <278>  Tab through the given option(s) going forward or backward.\n"
+		,
 		"alias history keypad macro speedwalk tab"
 		"alias history keypad macro speedwalk tab"
 	},
 	},
 	{
 	{
@@ -1697,7 +1730,8 @@ struct help_type help_table[] =
 		"         #info mccp will show information about data compression.\n"
 		"         #info mccp will show information about data compression.\n"
 		"         #info stack will show the low level debugging stack.\n"
 		"         #info stack will show the low level debugging stack.\n"
 		"         #info session will show some session information.\n"
 		"         #info session will show some session information.\n"
-		"         #info system will show some system information.\n",
+		"         #info system will show some system information.\n"
+		"         #info unicode will show information on the provided character.\n",
 
 
 		"class debug ignore kill message"
 		"class debug ignore kill message"
 	},
 	},
@@ -2199,6 +2233,9 @@ struct help_type help_table[] =
 		"         <178>#map terrain <name> <symbol> [FADEIN|FADEOUT]\n"
 		"         <178>#map terrain <name> <symbol> [FADEIN|FADEOUT]\n"
 		"         <278>  Determine symbol spread density, omit for the default.\n"
 		"         <278>  Determine symbol spread density, omit for the default.\n"
 		"\n"
 		"\n"
+		"         <178>#map terrain <name> <symbol> [DOUBLE]\n"
+		"         <278>  You're using two characters for the symbol.\n"
+		"\n"
 		"         <178>#map travel <direction> <delay>\n"
 		"         <178>#map travel <direction> <delay>\n"
 		"         <278>  Follows the direction until a dead end or an intersection is\n"
 		"         <278>  Follows the direction until a dead end or an intersection is\n"
 		"         <278>  found. Use braces around the direction if you use the delay,\n"
 		"         <278>  found. Use braces around the direction if you use the delay,\n"

+ 41 - 56
src/log.c

@@ -166,29 +166,18 @@ void write_html_header(struct session *ses, FILE *fp)
 		"<head>\n"
 		"<head>\n"
 		"<meta http-equiv='content-type' content='text/html; charset=%s'>\n"
 		"<meta http-equiv='content-type' content='text/html; charset=%s'>\n"
 		"<meta name='viewport' content='width=device-width, initial-scale=1.0'>\n"
 		"<meta name='viewport' content='width=device-width, initial-scale=1.0'>\n"
-		"<meta name='description' content='Generated by TinTin++ "CLIENT_VERSION" - http://tintin.sourceforge.net'>\n"
 		"<style type='text/css'>\n"
 		"<style type='text/css'>\n"
-		"body {font-family:Consolas;font-size:12pt;}\n"
-		"a {text-decoration:none;}\n"
-		"a:link {color:#06b;}\n"
-		"a:visited {color:#6b0;}\n"
-		"a:hover {text-decoration:underline;}\n"
-		"a:active {color:#b06;}\n"
-		".d30{ color: #000; } .l30{ color: #555; } .b40{ background-color: #000; } .b50{ background-color: #555 }\n"
-		".d31{ color: #B00; } .l31{ color: #F55; } .b41{ background-color: #B00; } .b51{ background-color: #F55 }\n"
-		".d32{ color: #0B0; } .l32{ color: #5F5; } .b42{ background-color: #0B0; } .b52{ background-color: #5F5 }\n"
-		".d33{ color: #BB0; } .l33{ color: #FF5; } .b43{ background-color: #BB0; } .b53{ background-color: #FF5 }\n"
-		".d34{ color: #00B; } .l34{ color: #55F; } .b44{ background-color: #00B; } .b54{ background-color: #55F }\n"
-		".d35{ color: #B0B; } .l35{ color: #F5F; } .b45{ background-color: #B0B; } .b55{ background-color: #F5F }\n"
-		".d36{ color: #0BB; } .l36{ color: #5FF; } .b46{ background-color: #0BB; } .b56{ background-color: #5FF }\n"
-		".d37{ color: #BBB; } .l37{ color: #FFF; } .b47{ background-color: #BBB; } .b57{ background-color: #FFF }\n"
-		".d38{ color: #FFF; } .l38{ color: #FFF; } .b48{ background-color: #000; } .b58{ background-color: #000 }\n"
-		".d39{ color: #FFF; } .l39{ color: #FFF; } .b49{ background-color: #000; } .b59{ background-color: #000 }\n"
+		"body {font-family:Consolas;font-size:12pt}\n"
+		"a {text-decoration:none}\n"
+		"a:link {color:#06b}\n"
+		"a:visited {color:#6b0}\n"
+		"a:hover {text-decoration:underline}\n"
+		"a:active {color:#b06}\n"
 		"</style>\n"
 		"</style>\n"
 		"<body bgcolor='#000000'>\n"
 		"<body bgcolor='#000000'>\n"
 		"</head>\n"
 		"</head>\n"
 		"<pre>\n"
 		"<pre>\n"
-		"<span class='b49'><span class='d39'>\n",
+		"<span style='background-color:#000'><span style='color:#FFF'>\n",
 		HAS_BIT(gtd->ses->charset, CHARSET_FLAG_UTF8) ? "utf-8" : 
 		HAS_BIT(gtd->ses->charset, CHARSET_FLAG_UTF8) ? "utf-8" : 
 			HAS_BIT(ses->charset, CHARSET_FLAG_BIG5) ? "big5" : 
 			HAS_BIT(ses->charset, CHARSET_FLAG_BIG5) ? "big5" : 
 				HAS_BIT(ses->charset, CHARSET_FLAG_GBK1) ? "gb18030" : "iso-8859-1");
 				HAS_BIT(ses->charset, CHARSET_FLAG_GBK1) ? "gb18030" : "iso-8859-1");
@@ -200,7 +189,9 @@ void write_html_header(struct session *ses, FILE *fp)
 void vt102_to_html(struct session *ses, char *txt, char *out)
 void vt102_to_html(struct session *ses, char *txt, char *out)
 {
 {
 	char tmp[BUFFER_SIZE], *pti, *pto;
 	char tmp[BUFFER_SIZE], *pti, *pto;
-	char xtc[] = { '0', '6', '8', 'B', 'D', 'F' };
+	char xtc[6]  = { '0', '6', '8', 'B', 'D', 'F' };
+	char *ans[16] = { "000", "A00", "0A0", "AA0", "00A", "A0A", "0AA", "AAA", "555", "F55", "5F5", "FF5", "55F", "F5F", "5FF", "FFF" };
+
 	int vtc, fgc, bgc, cnt;
 	int vtc, fgc, bgc, cnt;
 	int rgb[6] = { 0, 0, 0, 0, 0, 0 };
 	int rgb[6] = { 0, 0, 0, 0, 0, 0 };
 
 
@@ -292,8 +283,8 @@ void vt102_to_html(struct session *ses, char *txt, char *out)
 							{
 							{
 								case 0:
 								case 0:
 									vtc = 0;
 									vtc = 0;
-									fgc = 39;
-									bgc = 49;
+									fgc = 7;
+									bgc = 0;
 									break;
 									break;
 								case 1:
 								case 1:
 									SET_BIT(vtc, COL_BLD);
 									SET_BIT(vtc, COL_BLD);
@@ -339,13 +330,16 @@ void vt102_to_html(struct session *ses, char *txt, char *out)
 									DEL_BIT(vtc, COL_REV);
 									DEL_BIT(vtc, COL_REV);
 									break;
 									break;
 								case 38:
 								case 38:
+								case 39:
 									SET_BIT(vtc, COL_XTF_5|COL_TCF_2);
 									SET_BIT(vtc, COL_XTF_5|COL_TCF_2);
-									fgc = 38;
+									fgc = 7;
 									break;
 									break;
 								case 48:
 								case 48:
+								case 49:
 									SET_BIT(vtc, COL_XTB_5|COL_TCB_2);
 									SET_BIT(vtc, COL_XTB_5|COL_TCB_2);
-									bgc = 48;
+									bgc = 0;
 									break;
 									break;
+
 								default:
 								default:
 									switch (atoi(tmp) / 10)
 									switch (atoi(tmp) / 10)
 									{
 									{
@@ -360,22 +354,21 @@ void vt102_to_html(struct session *ses, char *txt, char *out)
 									}
 									}
 									if (atoi(tmp) / 10 == 4)
 									if (atoi(tmp) / 10 == 4)
 									{
 									{
-										bgc = atoi(tmp);
+										bgc = atoi(tmp) % 10;
 									}
 									}
-									if (atoi(tmp) / 10 == 10)
+									else if (atoi(tmp) / 10 == 10)
 									{
 									{
-										bgc = atoi(tmp) - 50;
+										bgc = atoi(tmp) % 10;
 									}
 									}
-
-									if (atoi(tmp) / 10 == 3)
+									else if (atoi(tmp) / 10 == 3)
 									{
 									{
-										fgc = atoi(tmp);
+										fgc = atoi(tmp) % 10;
 									}
 									}
-									if (atoi(tmp) / 10 == 9)
+									else if (atoi(tmp) / 10 == 9)
 									{
 									{
 										SET_BIT(vtc, COL_BLD);
 										SET_BIT(vtc, COL_BLD);
 
 
-										fgc = atoi(tmp) - 60;
+										fgc = atoi(tmp) % 10;
 									}
 									}
 									break;
 									break;
 							}
 							}
@@ -391,8 +384,8 @@ void vt102_to_html(struct session *ses, char *txt, char *out)
 				if (!HAS_BIT(vtc, COL_REV) && HAS_BIT(ses->vtc, COL_REV))
 				if (!HAS_BIT(vtc, COL_REV) && HAS_BIT(ses->vtc, COL_REV))
 				{
 				{
 					cnt = fgc;
 					cnt = fgc;
-					fgc = ses->fgc = bgc - 10;
-					bgc = ses->bgc = cnt + 10;
+					fgc = ses->fgc = bgc;
+					bgc = ses->bgc = cnt;
 				}
 				}
 
 
 				if (bgc != ses->bgc || fgc != ses->fgc || vtc != ses->vtc)
 				if (bgc != ses->bgc || fgc != ses->fgc || vtc != ses->vtc)
@@ -404,66 +397,58 @@ void vt102_to_html(struct session *ses, char *txt, char *out)
 					{
 					{
 						if (HAS_BIT(vtc, COL_XTB))
 						if (HAS_BIT(vtc, COL_XTB))
 						{
 						{
-							if (bgc < 8)
+							if (bgc < 16)
 							{
 							{
-								sprintf(pto, "</span><span class='b%d'>", 40+bgc);
-							}
-							else if (bgc < 16)
-							{
-								sprintf(pto, "</span><span class='b%d'>", 50+bgc-8);
+								sprintf(pto, "</span><span style='background-color: #%s'>", ans[bgc]);
 							}
 							}
 							else if (bgc < 232)
 							else if (bgc < 232)
 							{
 							{
-								sprintf(pto, "</span><span style='background-color: #%c%c%c;'>", xtc[(bgc-16) / 36], xtc[(bgc-16) % 36 / 6], xtc[(bgc-16) % 6]);
+								sprintf(pto, "</span><span style='background-color: #%c%c%c'>", xtc[(bgc-16) / 36], xtc[(bgc-16) % 36 / 6], xtc[(bgc-16) % 6]);
 							}
 							}
 							else
 							else
 							{
 							{
-								sprintf(pto, "</span><span style='background-color: rgb(%d,%d,%d);'>", (bgc-232) * 10 + 8, (bgc-232) * 10 + 8,(bgc-232) * 10 + 8);
+								sprintf(pto, "</span><span style='background-color: rgb(%d,%d,%d)'>", (bgc-232) * 10 + 8, (bgc-232) * 10 + 8, (bgc-232) * 10 + 8);
 							}
 							}
 						}
 						}
 						else if (HAS_BIT(vtc, COL_TCB))
 						else if (HAS_BIT(vtc, COL_TCB))
 						{
 						{
-							sprintf(pto, "</span><span style='background-color: rgb(%d,%d,%d);'>", rgb[3], rgb[4], rgb[5]);
+							sprintf(pto, "</span><span style='background-color:#%02x%02x%02x'>", rgb[3], rgb[4], rgb[5]);
 						}
 						}
 						else
 						else
 						{
 						{
-							sprintf(pto, "</span><span class='b%d'>", bgc);
+							sprintf(pto, "</span><span style='background-color:#%s'>", ans[bgc]);
 						}
 						}
 						pto += strlen(pto);
 						pto += strlen(pto);
 					}
 					}
 
 
 					if (HAS_BIT(vtc, COL_XTF))
 					if (HAS_BIT(vtc, COL_XTF))
 					{
 					{
-						if (fgc < 8)
-						{
-							sprintf(pto, "<span class='d%d'>", 30+fgc);
-						}
-						else if (fgc < 16)
+						if (fgc < 16)
 						{
 						{
-							sprintf(pto, "<span class='l%d'>", 30+fgc-8);
+							sprintf(pto, "</span><span style='color:#%s'>", ans[fgc]);
 						}
 						}
 						else if (fgc < 232)
 						else if (fgc < 232)
 						{
 						{
-							sprintf(pto, "<span style='color: #%c%c%c;'>", xtc[(fgc-16) / 36], xtc[(fgc-16) % 36 / 6], xtc[(fgc-16) % 6]);
+							sprintf(pto, "<span style='color:#%c%c%c'>", xtc[(fgc-16) / 36], xtc[(fgc-16) % 36 / 6], xtc[(fgc-16) % 6]);
 						}
 						}
 						else
 						else
 						{
 						{
-							sprintf(pto, "<span style='color: rgb(%d,%d,%d);'>", (fgc-232) * 10 + 8, (fgc-232) * 10 + 8,(fgc-232) * 10 + 8);
+							sprintf(pto, "<span style='color:rgb(%d,%d,%d)'>", (fgc-232) * 10 + 8, (fgc-232) * 10 + 8,(fgc-232) * 10 + 8);
 						}
 						}
 					}
 					}
 					else if (HAS_BIT(vtc, COL_TCF))
 					else if (HAS_BIT(vtc, COL_TCF))
 					{
 					{
-						sprintf(pto, "<span style='color: rgb(%d,%d,%d);'>", fgc / 256 / 256, fgc / 256 % 256, fgc % 256);
+						sprintf(pto, "<span style='color:#%02x%02x%02x'>", rgb[0], rgb[1], rgb[2]);
 					}
 					}
 					else
 					else
 					{
 					{
 						if (HAS_BIT(vtc, COL_BLD))
 						if (HAS_BIT(vtc, COL_BLD))
 						{
 						{
-							sprintf(pto, "<span class='l%d'>", fgc);
+							sprintf(pto, "<span style='color:#%s'>", ans[fgc+8]);
 						}
 						}
 						else
 						else
 						{
 						{
-							sprintf(pto, "<span class='d%d'>", fgc);
+							sprintf(pto, "<span style='color:#%s'>", ans[fgc]);
 						}
 						}
 					}
 					}
 					pto += strlen(pto);
 					pto += strlen(pto);
@@ -472,8 +457,8 @@ void vt102_to_html(struct session *ses, char *txt, char *out)
 				if (HAS_BIT(vtc, COL_REV) && !HAS_BIT(ses->vtc, COL_REV))
 				if (HAS_BIT(vtc, COL_REV) && !HAS_BIT(ses->vtc, COL_REV))
 				{
 				{
 					cnt = fgc;
 					cnt = fgc;
-					fgc = ses->fgc = bgc - 10;
-					bgc = ses->bgc = cnt + 10;
+					fgc = ses->fgc = bgc;
+					bgc = ses->bgc = cnt;
 				}
 				}
 
 
 				ses->vtc = vtc;
 				ses->vtc = vtc;

+ 68 - 20
src/mapper.c

@@ -282,7 +282,7 @@ int delete_map(struct session *ses)
 
 
 struct room_data *create_room(struct session *ses, char *format, ...)
 struct room_data *create_room(struct session *ses, char *format, ...)
 {
 {
-	char *arg, buf[BUFFER_SIZE];
+	char *arg, buf[BUFFER_SIZE], arg1[BUFFER_SIZE];
 	struct room_data *newroom;
 	struct room_data *newroom;
 	va_list args;
 	va_list args;
 
 
@@ -292,9 +292,9 @@ struct room_data *create_room(struct session *ses, char *format, ...)
 
 
 	newroom = (struct room_data *) calloc(1, sizeof(struct room_data));
 	newroom = (struct room_data *) calloc(1, sizeof(struct room_data));
 
 
-	arg = buf;
+	arg = get_arg_in_braces(ses, buf, arg1, GET_ONE);
 
 
-	arg = get_arg_in_braces(ses, arg, buf, GET_ONE); newroom->vnum    = atoi(buf);
+	newroom->vnum = atoi(arg1);
 
 
 	if (HAS_BIT(ses->map->flags, MAP_FLAG_SYNC) && ses->map->room_list[newroom->vnum] != NULL)
 	if (HAS_BIT(ses->map->flags, MAP_FLAG_SYNC) && ses->map->room_list[newroom->vnum] != NULL)
 	{
 	{
@@ -305,17 +305,17 @@ struct room_data *create_room(struct session *ses, char *format, ...)
 		return ses->map->room_list[vnum];
 		return ses->map->room_list[vnum];
 	}
 	}
 
 
-	arg = get_arg_in_braces(ses, arg, buf, GET_ONE); newroom->flags   = atoi(buf);
-	arg = get_arg_in_braces(ses, arg, buf, GET_ONE); newroom->color   = strdup(buf);
-	arg = get_arg_in_braces(ses, arg, buf, GET_ONE); newroom->name    = strdup(buf);
-	arg = get_arg_in_braces(ses, arg, buf, GET_ONE); newroom->symbol  = strdup(buf);
-	arg = get_arg_in_braces(ses, arg, buf, GET_ONE); newroom->desc    = strdup(buf);
-	arg = get_arg_in_braces(ses, arg, buf, GET_ONE); newroom->area    = strdup(buf);
-	arg = get_arg_in_braces(ses, arg, buf, GET_ONE); newroom->note    = strdup(buf);
-	arg = get_arg_in_braces(ses, arg, buf, GET_ONE); newroom->terrain = strdup(buf);
-	arg = get_arg_in_braces(ses, arg, buf, GET_ONE); newroom->data    = strdup(buf);
-	arg = get_arg_in_braces(ses, arg, buf, GET_ONE); newroom->weight  = atof(buf);
-	arg = get_arg_in_braces(ses, arg, buf, GET_ONE); newroom->id      = strdup(buf);
+	arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); newroom->flags   = atoi(arg1);
+	arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); newroom->color   = strdup(arg1);
+	arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); newroom->name    = strdup(arg1);
+	arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); newroom->symbol  = strdup(arg1);
+	arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); newroom->desc    = strdup(arg1);
+	arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); newroom->area    = strdup(arg1);
+	arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); newroom->note    = strdup(arg1);
+	arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); newroom->terrain = strdup(arg1);
+	arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); newroom->data    = strdup(arg1);
+	arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); newroom->weight  = atof(arg1);
+	arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); newroom->id      = strdup(arg1);
 
 
 	if (HAS_BIT(newroom->flags, ROOM_FLAG_AVOID))
 	if (HAS_BIT(newroom->flags, ROOM_FLAG_AVOID))
 	{
 	{
@@ -1668,7 +1668,7 @@ char *draw_terrain_symbol(struct session *ses, struct room_data *room, int line,
 		{
 		{
 			case 12:
 			case 12:
 			case 14:
 			case 14:
-				if (room_grid[EXIT_GRID_0] && room_grid[EXIT_GRID_N] && room_grid[EXIT_GRID_0]->terrain_index != -1 && room_grid[EXIT_GRID_0]->terrain_index != room_grid[EXIT_GRID_N]->terrain_index)
+				if (room_grid[EXIT_GRID_0] && room_grid[EXIT_GRID_N] && room_grid[EXIT_GRID_0]->terrain_index != -1 && room_grid[EXIT_GRID_N]->terrain_index != -1 && room_grid[EXIT_GRID_0]->terrain_index != room_grid[EXIT_GRID_N]->terrain_index)
 				{
 				{
 					if (!HAS_BIT(ses->list[LIST_TERRAIN]->list[room_grid[EXIT_GRID_N]->terrain_index]->room->terrain_flags, TERRAIN_FLAG_DOUBLE))
 					if (!HAS_BIT(ses->list[LIST_TERRAIN]->list[room_grid[EXIT_GRID_N]->terrain_index]->room->terrain_flags, TERRAIN_FLAG_DOUBLE))
 					{
 					{
@@ -2392,7 +2392,6 @@ char *draw_room(struct session *ses, struct room_data *room, int line, int x, in
 			}
 			}
 			else
 			else
 			{
 			{
-				
 				sprintf(room_left,  "%s%s", room_color, ses->map->legend[LEGEND_UNICODE_GRAPHICS + UNICODE_DIR_RL]);
 				sprintf(room_left,  "%s%s", room_color, ses->map->legend[LEGEND_UNICODE_GRAPHICS + UNICODE_DIR_RL]);
 				sprintf(room_right, "%s%s", room_color, ses->map->legend[LEGEND_UNICODE_GRAPHICS + UNICODE_DIR_RR]);
 				sprintf(room_right, "%s%s", room_color, ses->map->legend[LEGEND_UNICODE_GRAPHICS + UNICODE_DIR_RR]);
 			}
 			}
@@ -6605,7 +6604,7 @@ DO_MAP(map_list)
 
 
 DO_MAP(map_map)
 DO_MAP(map_map)
 {
 {
-	char arg3[BUFFER_SIZE], arg4[BUFFER_SIZE];
+	char arg3[BUFFER_SIZE], arg4[BUFFER_SIZE], tmp[BUFFER_SIZE];
 	FILE *logfile = NULL;
 	FILE *logfile = NULL;
 	int x, y, line, row;
 	int x, y, line, row;
 
 
@@ -6713,7 +6712,7 @@ DO_MAP(map_map)
 	else if (HAS_BIT(ses->map->flags, MAP_FLAG_UNICODEGRAPHICS))
 	else if (HAS_BIT(ses->map->flags, MAP_FLAG_UNICODEGRAPHICS))
 	{
 	{
 		map_grid_y = 2 + (map_grid_y + 1) / 2;
 		map_grid_y = 2 + (map_grid_y + 1) / 2;
-		map_grid_x = 2 + (map_grid_x + 3) / 5;
+		map_grid_x = 2 + (map_grid_x + 4) / 5;
 	}
 	}
 	else if (HAS_BIT(ses->map->flags, MAP_FLAG_BLOCKGRAPHICS))
 	else if (HAS_BIT(ses->map->flags, MAP_FLAG_BLOCKGRAPHICS))
 	{
 	{
@@ -6785,7 +6784,53 @@ DO_MAP(map_map)
 			}
 			}
 		}
 		}
 	}
 	}
-	else if (HAS_BIT(ses->map->flags, MAP_FLAG_UNICODEGRAPHICS) || HAS_BIT(ses->map->flags, MAP_FLAG_BLOCKGRAPHICS))
+	else if (HAS_BIT(ses->map->flags, MAP_FLAG_UNICODEGRAPHICS))
+	{
+		for (y = map_grid_y - 2 ; y >= 1 ; y--)
+		{
+			for (line = 1 ; line <= 2 ; line++)
+			{
+				str_cpy(&gtd->buf, ses->map->color[MAP_COLOR_BACK]);
+
+				for (x = 1 ; x < map_grid_x - 1 ; x++)
+				{
+					if (x == map_grid_x - 2)
+					{
+						strcpy(tmp, draw_room(ses, ses->map->grid_rooms[x + map_grid_x * y], line, x, y));
+
+						str_cat_printf(&gtd->buf, "%.*s", string_str_raw_len(ses, tmp, 0, 2), tmp);
+					}
+					else
+					{
+						str_cat(&gtd->buf, draw_room(ses, ses->map->grid_rooms[x + map_grid_x * y], line, x, y));
+					}
+//					str_cat(&gtd->buf, draw_room(ses, ses->map->grid_rooms[x + map_grid_x * y], line, x, y));
+				}
+
+				str_clone(&gtd->out, gtd->buf);
+
+				substitute(ses, gtd->buf, gtd->out, SUB_COL|SUB_CMP|SUB_LIT);
+
+				if (logfile)
+				{
+					fprintf(logfile, "%s\n", gtd->out);
+				}
+				else if (*arg3 == 'L')
+				{
+					cat_sprintf(arg1, "{%02d}{%s\e[0m}", ++row, gtd->out);
+				}
+				else if (*arg3 == 'V' || *arg3 == 'D')
+				{
+					cat_sprintf(arg1, "%s\e[0m\n", gtd->out);
+				}
+				else
+				{
+					tintin_puts2(ses, gtd->out);
+				}
+			}
+		}
+	}
+	else if (HAS_BIT(ses->map->flags, MAP_FLAG_BLOCKGRAPHICS))
 	{
 	{
 		for (y = map_grid_y - 2 ; y >= 1 ; y--)
 		for (y = map_grid_y - 2 ; y >= 1 ; y--)
 		{
 		{
@@ -7718,7 +7763,10 @@ DO_MAP(map_terrain)
 				strcat(buf1, "DOUBLE ");
 				strcat(buf1, "DOUBLE ");
 			}
 			}
 
 
-			buf1[strlen(buf1) - 1] = 0;
+			if (*buf1)
+			{
+				buf1[strlen(buf1) - 1] = 0;
+			}
 		}
 		}
 
 
 		node = update_node_list(root, arg1, arg2, buf1, "");
 		node = update_node_list(root, arg1, arg2, buf1, "");

+ 6 - 6
src/misc.c

@@ -37,11 +37,8 @@ DO_COMMAND(do_bell)
 	if (*arg1 == 0)
 	if (*arg1 == 0)
 	{
 	{
 		print_stdout("\007");
 		print_stdout("\007");
-
-		return ses;
 	}
 	}
-
-	if (is_abbrev(arg1, "FLASH"))
+	else if (is_abbrev(arg1, "FLASH"))
 	{
 	{
 		if (is_abbrev(arg2, "ON"))
 		if (is_abbrev(arg2, "ON"))
 		{
 		{
@@ -105,6 +102,7 @@ DO_COMMAND(do_bell)
 	{
 	{
 		show_error(ses, LIST_COMMAND, "#SYNTAX: #BELL {FLASH|FOCUS|MARGIN|RING|VOLUME} {ARGUMENT}");
 		show_error(ses, LIST_COMMAND, "#SYNTAX: #BELL {FLASH|FOCUS|MARGIN|RING|VOLUME} {ARGUMENT}");
 	}
 	}
+
 	return ses;
 	return ses;
 }
 }
 
 
@@ -267,13 +265,15 @@ DO_COMMAND(do_test)
 	{
 	{
 		sprintf(arg2, "%d", (arg[0] - '0') * (arg[0] - '0'));
 		sprintf(arg2, "%d", (arg[0] - '0') * (arg[0] - '0'));
 
 
-		if (isxdigit(arg[1]) && isxdigit(arg[2]) && isxdigit(arg[3]))
+		if ((isxdigit(arg[1]) && isxdigit(arg[2]) && isxdigit(arg[3])) || (arg[1] == '?' && arg[2] == '?' && arg[3] == '?'))
 		{
 		{
 			sprintf(arg3, "<f%c%c%c>", arg[1], arg[2], arg[3]);
 			sprintf(arg3, "<f%c%c%c>", arg[1], arg[2], arg[3]);
 
 
 			if (isdigit(arg[4]) && isdigit(arg[5]))
 			if (isdigit(arg[4]) && isdigit(arg[5]))
 			{
 			{
-				sprintf(arg4, "%d %d %s", (arg[4] - '0') * (arg[4] - '0') / 10, (arg[5] - '0') * (arg[5] - '0'), &arg[6]);
+				sprintf(arg4, "%f %d %s", (arg[4] - '0') * (arg[4] - '0') / 10.0, (arg[5] - '0') * (arg[5] - '0'), &arg[6]);
+
+				tintin_printf2(ses, "debug: %s", arg4);
 			}
 			}
 		}
 		}
 	}
 	}

+ 0 - 1
src/parse.c

@@ -545,7 +545,6 @@ char *get_arg_in_braces(struct session *ses, char *string, char *result, int fla
 
 
 	while (*pti)
 	while (*pti)
 	{
 	{
-		
 		if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
 		if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
 		{
 		{
 			*pto++ = *pti++;
 			*pto++ = *pti++;

+ 15 - 9
src/screen.c

@@ -467,17 +467,17 @@ DO_SCREEN(screen_move)
 		return;
 		return;
 	}
 	}
 
 
-	height = (int) get_number(ses, arg2);
-	width  = (int) get_number(ses, arg1);
+	height = (int) get_number(ses, arg1);
+	width  = (int) get_number(ses, arg2);
 
 
 	if (height < 0)
 	if (height < 0)
 	{
 	{
-		strcpy(arg2, "0");
+		sprintf(arg1, "%d", 1 + gtd->screen->desk_height - gtd->screen->tot_height + height);
 	}
 	}
 
 
 	if (width < 0)
 	if (width < 0)
 	{
 	{
-		strcpy(arg1, "0");
+		sprintf(arg2, "%d", 1 + gtd->screen->desk_width - gtd->screen->tot_width + width);
 	}
 	}
 
 
 	screen_csit(ses, "3", arg2, arg1); // reverse x,y to row,col
 	screen_csit(ses, "3", arg2, arg1); // reverse x,y to row,col
@@ -859,6 +859,8 @@ void csit_handler(int ind, int var1, int var2)
 			break;
 			break;
 
 
 		case 4:
 		case 4:
+			gtd->screen->tot_height = UMAX(0, var1);
+			gtd->screen->tot_width  = UMAX(0, var2);
 			check_all_events(NULL, SUB_ARG, 0, 2, "SCREEN DIMENSIONS", ntos(var1), ntos(var2));
 			check_all_events(NULL, SUB_ARG, 0, 2, "SCREEN DIMENSIONS", ntos(var1), ntos(var2));
 			break;
 			break;
 
 
@@ -1014,8 +1016,8 @@ DO_SCREEN(screen_info)
 
 
 	for (lvl = 0 ; lvl < gtd->screen->sav_lev ; lvl++)
 	for (lvl = 0 ; lvl < gtd->screen->sav_lev ; lvl++)
 	{
 	{
-	tintin_printf2(ses, "gtd->screen->sav_row[%2d]: %4d", lvl, gtd->screen->sav_row[lvl]);
-	tintin_printf2(ses, "gtd->screen->sav_col[%2d]: %4d", lvl, gtd->screen->sav_col[lvl]);
+		tintin_printf2(ses, "gtd->screen->sav_row[%2d]: %4d", lvl, gtd->screen->sav_row[lvl]);
+		tintin_printf2(ses, "gtd->screen->sav_col[%2d]: %4d", lvl, gtd->screen->sav_col[lvl]);
 	}
 	}
 
 
 	tintin_printf2(ses, "");
 	tintin_printf2(ses, "");
@@ -1023,9 +1025,9 @@ DO_SCREEN(screen_info)
 	tintin_printf2(ses, "gtd->screen->rows:        %4d", gtd->screen->rows);
 	tintin_printf2(ses, "gtd->screen->rows:        %4d", gtd->screen->rows);
 	tintin_printf2(ses, "gtd->screen->cols:        %4d", gtd->screen->cols);
 	tintin_printf2(ses, "gtd->screen->cols:        %4d", gtd->screen->cols);
 	tintin_printf2(ses, "gtd->screen->height:      %4d", gtd->screen->height);
 	tintin_printf2(ses, "gtd->screen->height:      %4d", gtd->screen->height);
-	tintin_printf2(ses, "gtd->screen->pix_cows:    %4d", gtd->screen->width);
-
-	return;
+	tintin_printf2(ses, "gtd->screen->width:       %4d", gtd->screen->width);
+	tintin_printf2(ses, "gtd->screen->tot_height:  %4d", gtd->screen->tot_height);
+	tintin_printf2(ses, "gtd->screen->tot_width:   %4d", gtd->screen->tot_width);
 
 
 	tintin_printf2(ses, "");
 	tintin_printf2(ses, "");
 
 
@@ -1037,6 +1039,10 @@ DO_SCREEN(screen_info)
 
 
 	tintin_printf2(ses, "");
 	tintin_printf2(ses, "");
 
 
+	tintin_printf2(ses, "gtd->screen->desk_rows:   %4d", gtd->screen->desk_rows);
+	tintin_printf2(ses, "gtd->screen->desk_cols:   %4d", gtd->screen->desk_cols);
+	tintin_printf2(ses, "gtd->screen->desk_height: %4d", gtd->screen->desk_height);
+	tintin_printf2(ses, "gtd->screen->desk_width:  %4d", gtd->screen->desk_width);
 
 
 	if (!HAS_BIT(ses->flags, SES_FLAG_READMUD) && IS_SPLIT(ses))
 	if (!HAS_BIT(ses->flags, SES_FLAG_READMUD) && IS_SPLIT(ses))
 	{
 	{

+ 88 - 80
src/substitute.c

@@ -27,6 +27,7 @@
 
 
 // color subs
 // color subs
 
 
+
 char *c256to16_fg[256] =
 char *c256to16_fg[256] =
 {
 {
 	"\e[22;30m", "\e[22;31m", "\e[22;32m", "\e[22;33m", "\e[22;34m", "\e[22;35m", "\e[22;36m", "\e[22;37m",
 	"\e[22;30m", "\e[22;31m", "\e[22;32m", "\e[22;33m", "\e[22;34m", "\e[22;35m", "\e[22;36m", "\e[22;37m",
@@ -1556,106 +1557,113 @@ int substitute(struct session *ses, char *string, char *result, int flags)
 					{
 					{
 						pti += strlen(old);
 						pti += strlen(old);
 					}
 					}
-					else if (isdigit(pti[1]) && isdigit(pti[2]) && isdigit(pti[3]) && pti[4] == '>')
+					else if (pti[1] && pti[2] && pti[3] && pti[4] == '>')
 					{
 					{
-						if (pti[1] != '8' || pti[2] != '8' || pti[3] != '8')
+						if (isdigit(pti[1]) && isdigit(pti[2]) && isdigit(pti[3]))
 						{
 						{
-							*pto++ = ASCII_ESC;
-							*pto++ = '[';
-
-							switch (pti[1])
+							if (pti[1] != '8' || pti[2] != '8' || pti[3] != '8')
 							{
 							{
-								case '2':
-									*pto++ = '2';
-									*pto++ = '2';
-									*pto++ = ';';
-									break;
-								case '8':
-									break;
-								default:
-									*pto++ = pti[1];
-									*pto++ = ';';
+								*pto++ = ASCII_ESC;
+								*pto++ = '[';
+
+								switch (pti[1])
+								{
+									case '2':
+										*pto++ = '2';
+										*pto++ = '2';
+										*pto++ = ';';
+										break;
+									case '8':
+										break;
+									default:
+										*pto++ = pti[1];
+										*pto++ = ';';
+								}
+								switch (pti[2])
+								{
+									case '8':
+										break;
+									default:
+										*pto++ = '3';
+										*pto++ = pti[2];
+										*pto++ = ';';
+										break;
+								}
+								switch (pti[3])
+								{
+									case '8':
+										break;
+									default:
+										*pto++ = '4';
+										*pto++ = pti[3];
+										*pto++ = ';';
+										break;
+								}
+								pto--;
+								*pto++ = 'm';
 							}
 							}
-							switch (pti[2])
+							pti += sprintf(old, "<%c%c%c>", pti[1], pti[2], pti[3]);
+						}
+						else if (pti[1] >= 'a' && pti[1] <= 'f' && pti[2] >= 'a' && pti[2] <= 'f' && pti[3] >= 'a' && pti[3] <= 'f' && pti[4] == '>')
+						{
+							cnt = 16 + (pti[1] - 'a') * 36 + (pti[2] - 'a') * 6 + (pti[3] - 'a');
+							
+							if (ses->color >= 256)
 							{
 							{
-								case '8':
-									break;
-								default:
-									*pto++ = '3';
-									*pto++ = pti[2];
-									*pto++ = ';';
-									break;
+								pto += sprintf(pto, "\e[38;5;%dm", cnt);
 							}
 							}
-							switch (pti[3])
+							else if (ses->color == 16)
 							{
 							{
-								case '8':
-									break;
-								default:
-									*pto++ = '4';
-									*pto++ = pti[3];
-									*pto++ = ';';
-									break;
+								pto += sprintf(pto, "%s", c256to16_fg[cnt]);
 							}
 							}
-							pto--;
-							*pto++ = 'm';
-						}
-						pti += sprintf(old, "<%c%c%c>", pti[1], pti[2], pti[3]);
-					}
-					else if (pti[1] >= 'a' && pti[1] <= 'f' && pti[2] >= 'a' && pti[2] <= 'f' && pti[3] >= 'a' && pti[3] <= 'f' && pti[4] == '>')
-					{
-						cnt = 16 + (pti[1] - 'a') * 36 + (pti[2] - 'a') * 6 + (pti[3] - 'a');
-
-						if (ses->color >= 256)
-						{
-							pto += sprintf(pto, "\e[38;5;%dm", cnt);
+							pti += sprintf(old, "<%c%c%c>", pti[1], pti[2], pti[3]);
 						}
 						}
-						else if (ses->color == 16)
+						else if (pti[1] >= 'A' && pti[1] <= 'F' && pti[2] >= 'A' && pti[2] <= 'F' && pti[3] >= 'A' && pti[3] <= 'F' && pti[4] == '>')
 						{
 						{
-							pto += sprintf(pto, "%s", c256to16_fg[cnt]);
-						}
-						pti += sprintf(old, "<%c%c%c>", pti[1], pti[2], pti[3]);
-					}
-					else if (pti[1] >= 'A' && pti[1] <= 'F' && pti[2] >= 'A' && pti[2] <= 'F' && pti[3] >= 'A' && pti[3] <= 'F' && pti[4] == '>')
-					{
-						cnt = 16 + (pti[1] - 'A') * 36 + (pti[2] - 'A') * 6 + (pti[3] - 'A');
+							cnt = 16 + (pti[1] - 'A') * 36 + (pti[2] - 'A') * 6 + (pti[3] - 'A');
 
 
-						if (ses->color >= 256)
-						{
-							pto += sprintf(pto, "\e[48;5;%dm", cnt);
+							if (ses->color >= 256)
+							{
+								pto += sprintf(pto, "\e[48;5;%dm", cnt);
+							}
+							else if (ses->color == 16)
+							{
+								pto += sprintf(pto, "%s", c256to16_bg[cnt]);
+							}
+							pti += sprintf(old, "<%c%c%c>", pti[1], pti[2], pti[3]);
 						}
 						}
-						else if (ses->color == 16)
+						else if (pti[1] == 'g' && isdigit((int) pti[2]) && isdigit((int) pti[3]) && pti[4] == '>')
 						{
 						{
-							pto += sprintf(pto, "%s", c256to16_bg[cnt]);
-						}
-						pti += sprintf(old, "<%c%c%c>", pti[1], pti[2], pti[3]);
-					}
-					else if (pti[1] == 'g' && isdigit((int) pti[2]) && isdigit((int) pti[3]) && pti[4] == '>')
-					{
-						cnt = 232 + (pti[2] - '0') * 10 + (pti[3] - '0');
+							cnt = 232 + (pti[2] - '0') * 10 + (pti[3] - '0');
 
 
-						if (ses->color >= 256)
-						{
-							pto += sprintf(pto, "\e[38;5;%dm", cnt);
+							if (ses->color >= 256)
+							{
+								pto += sprintf(pto, "\e[38;5;%dm", cnt);
+							}
+							else if (ses->color == 16)
+							{
+								pto += sprintf(pto, "%s", c256to16_fg[cnt]);
+							}
+							pti += sprintf(old, "<g%c%c>", pti[2], pti[3]);
 						}
 						}
-						else if (ses->color == 16)
+						else if (pti[1] == 'G' && isdigit((int) pti[2]) && isdigit((int) pti[3]) && pti[4] == '>')
 						{
 						{
-							pto += sprintf(pto, "%s", c256to16_fg[cnt]);
-						}
-						pti += sprintf(old, "<g%c%c>", pti[2], pti[3]);
-					}
-					else if (pti[1] == 'G' && isdigit((int) pti[2]) && isdigit((int) pti[3]) && pti[4] == '>')
-					{
-						cnt = 232 + (pti[2] - '0') * 10 + (pti[3] - '0');
+							cnt = 232 + (pti[2] - '0') * 10 + (pti[3] - '0');
 
 
-						if (ses->color >= 256)
-						{
-							pto += sprintf(pto, "\e[48;5;%dm", cnt);
+							if (ses->color >= 256)
+							{
+								pto += sprintf(pto, "\e[48;5;%dm", cnt);
+							}
+							else if (ses->color == 16)
+							{
+								pto += sprintf(pto, "%s", c256to16_bg[cnt]);
+							}
+							pti += sprintf(old, "<G%c%c>", pti[2], pti[3]);
 						}
 						}
-						else if (ses->color == 16)
+						else
 						{
 						{
-							pto += sprintf(pto, "%s", c256to16_bg[cnt]);
+							*pto++ = *pti++;
 						}
 						}
-						pti += sprintf(old, "<G%c%c>", pti[2], pti[3]);
 					}
 					}
 					else if (toupper((int) pti[1]) == 'F' && isxdigit(pti[2]) && isxdigit(pti[3]) && isxdigit(pti[4]) && pti[5] == '>')
 					else if (toupper((int) pti[1]) == 'F' && isxdigit(pti[2]) && isxdigit(pti[3]) && isxdigit(pti[4]) && pti[5] == '>')
 					{
 					{

+ 2 - 2
src/tables.c

@@ -699,9 +699,9 @@ struct map_type map_table[] =
 	{     "TRAVEL",           map_travel,          MAP_FLAG_VTMAP, 2, "Save explored path to #path and run it" },
 	{     "TRAVEL",           map_travel,          MAP_FLAG_VTMAP, 2, "Save explored path to #path and run it" },
 	{     "UNDO",             map_undo,            MAP_FLAG_VTMAP, 2, "Undo last map action"                 },
 	{     "UNDO",             map_undo,            MAP_FLAG_VTMAP, 2, "Undo last map action"                 },
 	{     "UNINSERT",         map_uninsert,        MAP_FLAG_VTMAP, 2, "Uninsert room in given direction"     },
 	{     "UNINSERT",         map_uninsert,        MAP_FLAG_VTMAP, 2, "Uninsert room in given direction"     },
-	{     "UNLANDMARK",       map_unlandmark,      0,              1, "Remove a landmark"                    },
+	{     "UNLANDMARK",       map_unlandmark,      MAP_FLAG_VTMAP, 1, "Remove a landmark"                    },
 	{     "UNLINK",           map_unlink,          MAP_FLAG_VTMAP, 2, "Remove given exit"                    },
 	{     "UNLINK",           map_unlink,          MAP_FLAG_VTMAP, 2, "Remove given exit"                    },
-	{     "UNTERRAIN",        map_unterrain,       0,              1, "Remove a terrain type"                },
+	{     "UNTERRAIN",        map_unterrain,       MAP_FLAG_VTMAP, 1, "Remove a terrain type"                },
 	{     "UPDATE",           map_update,          0,              0, "Mark vt map for an auto update"       },
 	{     "UPDATE",           map_update,          0,              0, "Mark vt map for an auto update"       },
 	{     "VNUM",             map_vnum,            MAP_FLAG_VTMAP, 2, "Change the room vnum to given vnum"   },
 	{     "VNUM",             map_vnum,            MAP_FLAG_VTMAP, 2, "Change the room vnum to given vnum"   },
 	{     "WRITE",            map_write,           0,              1, "Save the map to given file"           },
 	{     "WRITE",            map_write,           0,              1, "Save the map to given file"           },

+ 9 - 7
src/telopt_client.c

@@ -439,12 +439,6 @@ int client_translate_telopts(struct session *ses, unsigned char *src, int cplen)
 					cplen--;
 					cplen--;
 					continue;
 					continue;
 
 
-				case ASCII_ENQ:
-					check_all_events(ses, SUB_ARG, 0, 1, "VT100 ENQ", gtd->term); // obsolete, but we'll handle it for now.
-					cpsrc++;
-					cplen--;
-					continue;
-
 				case ASCII_CR:
 				case ASCII_CR:
 					if (cplen > 1 && cpsrc[1] == ASCII_LF)
 					if (cplen > 1 && cpsrc[1] == ASCII_LF)
 					{
 					{
@@ -469,9 +463,17 @@ int client_translate_telopts(struct session *ses, unsigned char *src, int cplen)
 						cpsrc++;
 						cpsrc++;
 						cplen--;
 						cplen--;
 					}
 					}
-
 					continue;
 					continue;
 
 
+				case ASCII_ENQ:
+					if (check_all_events(ses, SUB_ARG, 0, 1, "CATCH VT100 ENQ", gtd->term))
+					{
+						cpsrc++;
+						cplen--;
+						continue;
+					}
+					break;
+
 				default:
 				default:
 					if (cpsrc[0] == ASCII_ESC)
 					if (cpsrc[0] == ASCII_ESC)
 					{
 					{

+ 6 - 1
src/text.c

@@ -108,7 +108,12 @@ void print_stdout(char *format, ...)
 	}
 	}
 	else
 	else
 	{
 	{
-		write(STDIN_FILENO, buffer, len);
+		SET_BIT(gtd->flags, TINTIN_FLAG_FLUSH);
+
+		printf("%s", buffer);
+
+//		fwrite(buffer, len, 1, stdout);
+//		write(STDIN_FILENO, buffer, len); slooow
 	}
 	}
 	free(buffer);
 	free(buffer);
 }
 }

+ 3 - 1
src/tintin.h

@@ -172,7 +172,7 @@
 #define LIST_SIZE                        2
 #define LIST_SIZE                        2
 
 
 #define CLIENT_NAME              "TinTin++"
 #define CLIENT_NAME              "TinTin++"
-#define CLIENT_VERSION           "2.02.00 "
+#define CLIENT_VERSION           "2.02.01 "
 
 
 #define XT_E                            0x27
 #define XT_E                            0x27
 #define XT_C                            0x5B
 #define XT_C                            0x5B
@@ -1305,6 +1305,8 @@ struct screen_data
 	int                     cols;
 	int                     cols;
 	int                     height;
 	int                     height;
 	int                     width;
 	int                     width;
+	int                     tot_height;
+	int                     tot_width;
 	int                     pos_height;
 	int                     pos_height;
 	int                     pos_width;
 	int                     pos_width;
 	int                     minimized;
 	int                     minimized;

+ 1 - 1
src/update.c

@@ -576,7 +576,7 @@ void update_daemon(void)
 
 
 					winch_handler(0);
 					winch_handler(0);
 
 
-					show_message(gtd->ses, LIST_COMMAND, "#DAEMON UPDATE: UNATTACHING {%s} DUE TO READ ERROR.", gtd->attach_file);
+					show_message(gtd->ses, LIST_COMMAND, "#DAEMON UPDATE: UNATTACHING {%s}.", gtd->attach_file);
 				}
 				}
 				else
 				else
 				{
 				{

Разница между файлами не показана из-за своего большого размера
+ 3 - 263
src/utf8.c


+ 2 - 2
src/utils.c

@@ -363,10 +363,10 @@ char *capitalize(char *str)
 
 
 char *ntos(long long number)
 char *ntos(long long number)
 {
 {
-	static char outbuf[100][NUMBER_SIZE];
+	static char outbuf[10][NUMBER_SIZE];
 	static int cnt;
 	static int cnt;
 
 
-	cnt = (cnt + 1) % 100;
+	cnt = (cnt + 1) % 10;
 
 
 	sprintf(outbuf[cnt], "%lld", number);
 	sprintf(outbuf[cnt], "%lld", number);
 
 

+ 1 - 1
src/variable.c

@@ -142,7 +142,7 @@ DO_COMMAND(do_local)
 
 
 		arg = sub_arg_in_braces(ses, arg, str, GET_ALL, SUB_VAR|SUB_FUN);
 		arg = sub_arg_in_braces(ses, arg, str, GET_ALL, SUB_VAR|SUB_FUN);
 
 
-		node = set_nest_node_ses(ses, arg1, "%s", str);
+		node = set_nest_node(root, arg1, "%s", str);
 
 
 		while (*arg)
 		while (*arg)
 		{
 		{

+ 0 - 2
src/vt102.c

@@ -191,7 +191,6 @@ int skip_vt102_codes(char *str)
 
 
 	switch (str[0])
 	switch (str[0])
 	{
 	{
-		case   5:   /* ENQ */
 		case   7:   /* BEL */
 		case   7:   /* BEL */
 		case   8:   /* BS  */
 		case   8:   /* BS  */
 	//	case   9:      HT
 	//	case   9:      HT
@@ -403,7 +402,6 @@ int skip_vt102_codes_non_graph(char *str)
 
 
 	switch (str[skip])
 	switch (str[skip])
 	{
 	{
-		case   5:   /* ENQ */
 		case   7:   /* BEL */
 		case   7:   /* BEL */
 	/*	case   8: *//* BS  */
 	/*	case   8: *//* BS  */
 	/*	case   9: *//* HT  */
 	/*	case   9: *//* HT  */

Некоторые файлы не были показаны из-за большого количества измененных файлов