1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
|
|
4 | * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2002 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 2002 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * |
8 | * |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
9 | * Deliantra is free software: you can redistribute it and/or modify it under |
9 | * the terms of the Affero GNU General Public License as published by the |
10 | * the terms of the Affero GNU General Public License as published by the |
… | |
… | |
260 | *from = STACK_FROM_TOP; |
261 | *from = STACK_FROM_TOP; |
261 | return dm_stack_peek (pl); |
262 | return dm_stack_peek (pl); |
262 | } |
263 | } |
263 | |
264 | |
264 | /** |
265 | /** |
265 | * Actually hides specified player (obviously a DM). |
|
|
266 | * If 'silent_dm' is non zero, other players are informed of DM entering/leaving, |
|
|
267 | * else they just think someone left/entered. |
|
|
268 | */ |
|
|
269 | static void |
|
|
270 | do_wizard_hide (object *op, int silent_dm) |
|
|
271 | { |
|
|
272 | if (op->contr->hidden) |
|
|
273 | { |
|
|
274 | op->contr->hidden = 0; |
|
|
275 | op->invisible = 1; |
|
|
276 | new_draw_info (NDI_UNIQUE, 0, op, "You are no longer hidden from other players"); |
|
|
277 | op->map->players++; |
|
|
278 | new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, "%s has entered the game.", &op->name); |
|
|
279 | |
|
|
280 | if (!silent_dm) |
|
|
281 | new_draw_info (NDI_UNIQUE | NDI_ALL | NDI_LT_GREEN, 1, NULL, "The Dungeon Master has arrived!"); |
|
|
282 | } |
|
|
283 | else |
|
|
284 | { |
|
|
285 | op->contr->hidden = 1; |
|
|
286 | new_draw_info (NDI_UNIQUE, 0, op, "Other players will no longer see you."); |
|
|
287 | op->map->players--; |
|
|
288 | |
|
|
289 | if (!silent_dm) |
|
|
290 | new_draw_info (NDI_UNIQUE | NDI_ALL | NDI_LT_GREEN, 1, NULL, "The Dungeon Master is gone.."); |
|
|
291 | |
|
|
292 | new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, "%s leaves the game.", &op->name); |
|
|
293 | new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, "%s left the game.", &op->name); |
|
|
294 | } |
|
|
295 | } |
|
|
296 | |
|
|
297 | int |
|
|
298 | command_hide (object *op, char *params) |
|
|
299 | { |
|
|
300 | do_wizard_hide (op, 0); |
|
|
301 | return 1; |
|
|
302 | } |
|
|
303 | |
|
|
304 | /** |
|
|
305 | * This finds and returns the object which matches the name or |
266 | * This finds and returns the object which matches the name or |
306 | * object nubmer (specified via num #whatever). |
267 | * object nubmer (specified via num #whatever). |
307 | */ |
268 | */ |
308 | static object * |
269 | static object * |
309 | find_object_both (char *params) |
270 | find_object_both (char *params) |
… | |
… | |
462 | { |
423 | { |
463 | new_draw_info (NDI_UNIQUE, 0, op, "Can not find a free spot to place summoned player."); |
424 | new_draw_info (NDI_UNIQUE, 0, op, "Can not find a free spot to place summoned player."); |
464 | return 1; |
425 | return 1; |
465 | } |
426 | } |
466 | |
427 | |
467 | nx += freearr_x [i]; |
428 | nx += DIRX (i); |
468 | ny += freearr_y [i]; |
429 | ny += DIRY (i); |
469 | |
430 | |
470 | if (!xy_normalise (m, nx, ny)) |
431 | if (!xy_normalise (m, nx, ny)) |
471 | { |
432 | { |
472 | new_draw_info (NDI_UNIQUE, 0, op, "Can not find a free spot to place summoned player."); |
433 | new_draw_info (NDI_UNIQUE, 0, op, "Can not find a free spot to place summoned player."); |
473 | return 1; |
434 | return 1; |
… | |
… | |
981 | * This adds exp to a player. We now allow adding to a specific skill. |
942 | * This adds exp to a player. We now allow adding to a specific skill. |
982 | */ |
943 | */ |
983 | int |
944 | int |
984 | command_addexp (object *op, char *params) |
945 | command_addexp (object *op, char *params) |
985 | { |
946 | { |
986 | char buf[MAX_BUF], skill[MAX_BUF]; |
947 | char buf[1024], skill[1024]; |
987 | int q; |
948 | int q; |
988 | long long i; // use sint64 and finally provide format specifiers for sint64 etc. via configure |
949 | sint64 i; |
989 | object *skillob = NULL; |
950 | object *skillob = NULL; |
990 | |
951 | |
991 | skill[0] = '\0'; |
952 | skill[0] = '\0'; |
992 | if ((params == NULL) || (strlen (params) > MAX_BUF) || ((q = sscanf (params, "%s %lld %[^\n]", buf, &i, skill)) < 2)) |
953 | if ((params == NULL) || (strlen (params) > MAX_BUF) || ((q = sscanf (params, "%1023s %" SCNd64 " %1023[^\n]", buf, &i, skill)) < 2)) |
993 | { |
954 | { |
994 | new_draw_info (NDI_UNIQUE, 0, op, "Usage: addexp <who> <how much> [<skill>]."); |
955 | new_draw_info (NDI_UNIQUE, 0, op, "Usage: addexp <who> <how much> [<skill>]."); |
995 | return 1; |
956 | return 1; |
996 | } |
957 | } |
997 | |
958 | |
… | |
… | |
1068 | } |
1029 | } |
1069 | |
1030 | |
1070 | int |
1031 | int |
1071 | command_abil (object *op, char *params) |
1032 | command_abil (object *op, char *params) |
1072 | { |
1033 | { |
1073 | char thing[20], thing2[20]; |
1034 | char thing[80], thing2[80]; |
1074 | int iii; |
1035 | int iii; |
1075 | char buf[MAX_BUF]; |
1036 | char buf[MAX_BUF]; |
1076 | |
1037 | |
1077 | iii = 0; |
1038 | iii = 0; |
1078 | thing[0] = '\0'; |
1039 | thing[0] = '\0'; |
1079 | thing2[0] = '\0'; |
1040 | thing2[0] = '\0'; |
1080 | if (params == NULL || !sscanf (params, "%s %s %d", thing, thing2, &iii) || thing == NULL) |
1041 | if (!params || 3 != sscanf (params, "%79s %79s %d", thing, thing2, &iii)) |
1081 | { |
1042 | { |
1082 | new_draw_info (NDI_UNIQUE, 0, op, "Who?"); |
1043 | new_draw_info (NDI_UNIQUE, 0, op, "Who?"); |
1083 | return 1; |
1044 | return 1; |
1084 | } |
1045 | } |
1085 | |
1046 | |
1086 | if (thing2 == NULL) |
1047 | if (!*thing2) |
1087 | { |
1048 | { |
1088 | new_draw_info (NDI_UNIQUE, 0, op, "You can't change that."); |
1049 | new_draw_info (NDI_UNIQUE, 0, op, "You can't change that."); |
1089 | return 1; |
1050 | return 1; |
1090 | } |
1051 | } |
1091 | |
1052 | |
… | |
… | |
1117 | new_draw_info (NDI_UNIQUE, 0, op, "No such player."); |
1078 | new_draw_info (NDI_UNIQUE, 0, op, "No such player."); |
1118 | return 1; |
1079 | return 1; |
1119 | } |
1080 | } |
1120 | |
1081 | |
1121 | int |
1082 | int |
1122 | command_nowiz (object *op, char *params) |
|
|
1123 | { /* 'nodm' is alias */ |
|
|
1124 | op->clr_flag (FLAG_WIZ); |
|
|
1125 | op->clr_flag (FLAG_WIZPASS); |
|
|
1126 | op->clr_flag (FLAG_WIZCAST); |
|
|
1127 | op->clr_flag (FLAG_WIZLOOK); |
|
|
1128 | op->contr->do_los = 1; |
|
|
1129 | |
|
|
1130 | if (op->contr->hidden) |
|
|
1131 | { |
|
|
1132 | new_draw_info (NDI_UNIQUE, 0, op, "You are no longer hidden from other players"); |
|
|
1133 | op->map->players++; |
|
|
1134 | new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, "%s has entered the game.", &op->name); |
|
|
1135 | op->contr->hidden = 0; |
|
|
1136 | op->invisible = 1; |
|
|
1137 | } |
|
|
1138 | else |
|
|
1139 | new_draw_info (NDI_UNIQUE | NDI_ALL | NDI_LT_GREEN, 1, NULL, "The Dungeon Master is gone.."); |
|
|
1140 | |
|
|
1141 | return 1; |
|
|
1142 | } |
|
|
1143 | |
|
|
1144 | /** |
|
|
1145 | * object *op is trying to become dm. |
|
|
1146 | * pl_name is name supplied by player. Restrictive DM will make it harder |
|
|
1147 | * for socket users to become DM - in that case, it will check for the players |
|
|
1148 | * character name. |
|
|
1149 | */ |
|
|
1150 | static int |
|
|
1151 | checkdm (object *op, const char *pl_name, const char *pl_passwd, const char *pl_host) |
|
|
1152 | { |
|
|
1153 | FILE *dmfile; |
|
|
1154 | char buf[MAX_BUF]; |
|
|
1155 | char line_buf[160], name[160], passwd[160], host[160]; |
|
|
1156 | |
|
|
1157 | #ifdef RESTRICTIVE_DM |
|
|
1158 | *pl_name = op->name ? op->name : "*"; |
|
|
1159 | #endif |
|
|
1160 | |
|
|
1161 | sprintf (buf, "%s/%s", settings.confdir, DMFILE); |
|
|
1162 | if ((dmfile = fopen (buf, "r")) == NULL) |
|
|
1163 | { |
|
|
1164 | LOG (llevDebug, "Could not find DM file.\n"); |
|
|
1165 | return 0; |
|
|
1166 | } |
|
|
1167 | |
|
|
1168 | while (fgets (line_buf, 160, dmfile) != NULL) |
|
|
1169 | { |
|
|
1170 | if (line_buf[0] == '#') |
|
|
1171 | continue; |
|
|
1172 | if (sscanf (line_buf, "%[^:]:%[^:]:%s\n", name, passwd, host) != 3) |
|
|
1173 | { |
|
|
1174 | LOG (llevError, "Warning - malformed dm file entry: %s\n", line_buf); |
|
|
1175 | } |
|
|
1176 | else if ((!strcmp (name, "*") || (pl_name && !strcmp (pl_name, name))) |
|
|
1177 | && (!strcmp (passwd, "*") || !strcmp (passwd, pl_passwd)) && (!strcmp (host, "*") || !strcmp (host, pl_host))) |
|
|
1178 | { |
|
|
1179 | fclose (dmfile); |
|
|
1180 | return (1); |
|
|
1181 | } |
|
|
1182 | } |
|
|
1183 | fclose (dmfile); |
|
|
1184 | return (0); |
|
|
1185 | } |
|
|
1186 | |
|
|
1187 | static int |
|
|
1188 | do_wizard_dm (object *op, char *params, int silent) |
|
|
1189 | { |
|
|
1190 | if (!op->contr) |
|
|
1191 | return 0; |
|
|
1192 | |
|
|
1193 | if (op->flag [FLAG_WIZ]) |
|
|
1194 | { |
|
|
1195 | new_draw_info (NDI_UNIQUE, 0, op, "You are already the Dungeon Master!"); |
|
|
1196 | return 0; |
|
|
1197 | } |
|
|
1198 | |
|
|
1199 | if (checkdm (op, op->name, (params ? params : "*"), op->contr->ns->host)) |
|
|
1200 | { |
|
|
1201 | op->set_flag (FLAG_WIZ); |
|
|
1202 | op->set_flag (FLAG_WIZPASS); |
|
|
1203 | op->set_flag (FLAG_WIZCAST); |
|
|
1204 | op->set_flag (FLAG_WIZLOOK); |
|
|
1205 | op->contr->do_los = 1; |
|
|
1206 | |
|
|
1207 | new_draw_info (NDI_UNIQUE, 0, op, "Ok, you are the Dungeon Master!"); |
|
|
1208 | op->contr->write_buf[0] = '\0'; |
|
|
1209 | |
|
|
1210 | if (!silent) |
|
|
1211 | new_draw_info (NDI_UNIQUE | NDI_ALL | NDI_LT_GREEN, 1, NULL, "The Dungeon Master has arrived!"); |
|
|
1212 | |
|
|
1213 | return 1; |
|
|
1214 | } |
|
|
1215 | else |
|
|
1216 | { |
|
|
1217 | new_draw_info (NDI_UNIQUE, 0, op, "Sorry Pal, I don't think so."); |
|
|
1218 | op->contr->write_buf[0] = '\0'; |
|
|
1219 | return 0; |
|
|
1220 | } |
|
|
1221 | } |
|
|
1222 | |
|
|
1223 | /* |
|
|
1224 | * Actual command to perhaps become dm. Changed aroun a bit in version 0.92.2 |
|
|
1225 | * - allow people on sockets to become dm, and allow better dm file |
|
|
1226 | */ |
|
|
1227 | int |
|
|
1228 | command_dm (object *op, char *params) |
|
|
1229 | { |
|
|
1230 | if (!op->contr) |
|
|
1231 | return 0; |
|
|
1232 | |
|
|
1233 | do_wizard_dm (op, params, 0); |
|
|
1234 | |
|
|
1235 | return 1; |
|
|
1236 | } |
|
|
1237 | |
|
|
1238 | int |
|
|
1239 | command_invisible (object *op, char *params) |
1083 | command_invisible (object *op, char *params) |
1240 | { |
1084 | { |
1241 | if (op) |
1085 | if (op) |
1242 | { |
1086 | { |
1243 | op->invisible += 100; |
1087 | op->invisible += TIME2TICK (60); |
1244 | update_object (op, UP_OBJ_CHANGE); |
1088 | update_object (op, UP_OBJ_CHANGE); |
1245 | new_draw_info (NDI_UNIQUE, 0, op, "You turn invisible."); |
1089 | new_draw_info (NDI_UNIQUE, 0, op, "You turn invisible."); |
1246 | } |
1090 | } |
1247 | |
1091 | |
1248 | return 0; |
1092 | return 0; |
… | |
… | |
1353 | new_draw_info_format (NDI_UNIQUE, 0, op, "You do not know the spell %s.", params); |
1197 | new_draw_info_format (NDI_UNIQUE, 0, op, "You do not know the spell %s.", params); |
1354 | return 0; |
1198 | return 0; |
1355 | } |
1199 | } |
1356 | |
1200 | |
1357 | do_forget_spell (op, spell->name); |
1201 | do_forget_spell (op, spell->name); |
1358 | return 1; |
|
|
1359 | } |
|
|
1360 | |
|
|
1361 | /** |
|
|
1362 | * A players wants to become DM and hide. |
|
|
1363 | * Let's see if that's authorized. |
|
|
1364 | * Make sure to not tell anything to anyone. |
|
|
1365 | */ |
|
|
1366 | int |
|
|
1367 | command_dmhide (object *op, char *params) |
|
|
1368 | { |
|
|
1369 | if (!do_wizard_dm (op, params, 1)) |
|
|
1370 | return 0; |
|
|
1371 | |
|
|
1372 | do_wizard_hide (op, 1); |
|
|
1373 | |
|
|
1374 | return 1; |
1202 | return 1; |
1375 | } |
1203 | } |
1376 | |
1204 | |
1377 | /** |
1205 | /** |
1378 | * Pop the stack top. |
1206 | * Pop the stack top. |