ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/player.C
(Generate patch)

Comparing deliantra/server/server/player.C (file contents):
Revision 1.21 by root, Tue Sep 12 19:20:08 2006 UTC vs.
Revision 1.48 by root, Tue Dec 19 05:41:22 2006 UTC

16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 20
21 The author can be reached via e-mail to crossfire-devel@real-time.com 21 The author can be reached via e-mail to <crossfire@schmorp.de>
22*/ 22*/
23 23
24#include <global.h> 24#include <global.h>
25#ifndef WIN32 /* ---win32 remove headers */
26# include <pwd.h> 25#include <pwd.h>
27#endif
28#ifndef __CEXTRACT__
29# include <sproto.h> 26#include <sproto.h>
30#endif
31#include <sounds.h> 27#include <sounds.h>
32#include <living.h> 28#include <living.h>
33#include <object.h> 29#include <object.h>
34#include <spells.h> 30#include <spells.h>
35#include <skills.h> 31#include <skills.h>
36#include <newclient.h>
37 32
38#ifdef COZY_SERVER 33#ifdef COZY_SERVER
39extern int same_party (partylist *a, partylist *b); 34extern int same_party (partylist *a, partylist *b);
40#endif 35#endif
41 36
87 int comp; 82 int comp;
88 int size; 83 int size;
89 84
90 sprintf (buf, "%s/%s", settings.confdir, settings.motd); 85 sprintf (buf, "%s/%s", settings.confdir, settings.motd);
91 if ((fp = open_and_uncompress (buf, 0, &comp)) == NULL) 86 if ((fp = open_and_uncompress (buf, 0, &comp)) == NULL)
92 {
93 return; 87 return;
94 } 88
95 motd[0] = '\0'; 89 motd[0] = '\0';
96 size = 0; 90 size = 0;
91
97 while (fgets (buf, MAX_BUF, fp) != NULL) 92 while (fgets (buf, MAX_BUF, fp) != NULL)
98 { 93 {
99 if (*buf == '#') 94 if (*buf == '#')
100 continue; 95 continue;
96
101 strncat (motd + size, buf, HUGE_BUF - size); 97 strncat (motd + size, buf, HUGE_BUF - size);
102 size += strlen (buf); 98 size += strlen (buf);
103 } 99 }
100
104 draw_ext_info (NDI_UNIQUE | NDI_GREEN, 0, op, MSG_TYPE_MOTD, MSG_SUBTYPE_NONE, motd, NULL); 101 draw_ext_info (NDI_UNIQUE | NDI_GREEN, 0, op, MSG_TYPE_MOTD, MSG_SUBTYPE_NONE, motd, NULL);
105 close_and_delete (fp, comp); 102 close_and_delete (fp, comp);
106} 103}
107 104
108void 105void
114 int comp; 111 int comp;
115 int size; 112 int size;
116 113
117 sprintf (buf, "%s/%s", settings.confdir, settings.rules); 114 sprintf (buf, "%s/%s", settings.confdir, settings.rules);
118 if ((fp = open_and_uncompress (buf, 0, &comp)) == NULL) 115 if ((fp = open_and_uncompress (buf, 0, &comp)) == NULL)
119 {
120 return; 116 return;
121 } 117
122 rules[0] = '\0'; 118 rules[0] = '\0';
123 size = 0; 119 size = 0;
120
124 while (fgets (buf, MAX_BUF, fp) != NULL) 121 while (fgets (buf, MAX_BUF, fp) != NULL)
125 { 122 {
126 if (*buf == '#') 123 if (*buf == '#')
127 continue; 124 continue;
125
128 if (size + strlen (buf) >= HUGE_BUF) 126 if (size + strlen (buf) >= HUGE_BUF)
129 { 127 {
130 LOG (llevDebug, "Warning, rules size is > %d bytes.\n", HUGE_BUF); 128 LOG (llevDebug, "Warning, rules size is > %d bytes.\n", HUGE_BUF);
131 break; 129 break;
132 } 130 }
131
133 strncat (rules + size, buf, HUGE_BUF - size); 132 strncat (rules + size, buf, HUGE_BUF - size);
134 size += strlen (buf); 133 size += strlen (buf);
135 } 134 }
135
136 draw_ext_info (NDI_UNIQUE | NDI_GREEN, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_RULES, rules, NULL); 136 draw_ext_info (NDI_UNIQUE | NDI_GREEN, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_RULES, rules, NULL);
137 close_and_delete (fp, comp); 137 close_and_delete (fp, comp);
138} 138}
139 139
140void 140void
148 int size; 148 int size;
149 149
150 sprintf (buf, "%s/%s", settings.confdir, settings.news); 150 sprintf (buf, "%s/%s", settings.confdir, settings.news);
151 if ((fp = open_and_uncompress (buf, 0, &comp)) == NULL) 151 if ((fp = open_and_uncompress (buf, 0, &comp)) == NULL)
152 return; 152 return;
153
153 news[0] = '\0'; 154 news[0] = '\0';
154 subject[0] = '\0'; 155 subject[0] = '\0';
155 size = 0; 156 size = 0;
157
156 while (fgets (buf, MAX_BUF, fp) != NULL) 158 while (fgets (buf, MAX_BUF, fp) != NULL)
157 { 159 {
158 if (*buf == '#') 160 if (*buf == '#')
159 continue; 161 continue;
162
160 if (*buf == '%') 163 if (*buf == '%')
161 { /* send one news */ 164 { /* send one news */
162 if (size > 0) 165 if (size > 0)
163 draw_ext_info_format (NDI_UNIQUE | NDI_GREEN, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, "INFORMATION: %s\n%s", "%s\n%s", subject, news); /*send previously read news */ 166 draw_ext_info_format (NDI_UNIQUE | NDI_GREEN, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, "INFORMATION: %s\n%s", "%s\n%s", subject, news); /*send previously read news */
164 strcpy (subject, buf + 1); 167 strcpy (subject, buf + 1);
191 return 0; 194 return 0;
192 195
193 for (; *cp != '\0'; cp++) 196 for (; *cp != '\0'; cp++)
194 if (!((*cp >= 'a' && *cp <= 'z') || (*cp >= 'A' && *cp <= 'Z')) && *cp != '-' && *cp != '_') 197 if (!((*cp >= 'a' && *cp <= 'z') || (*cp >= 'A' && *cp <= 'Z')) && *cp != '-' && *cp != '_')
195 return 0; 198 return 0;
199
196 return 1; 200 return 1;
197} 201}
198 202
199/* This no longer sets the player map. Also, it now updates 203/* This no longer sets the player map. Also, it now updates
200 * all the pointers so the caller doesn't need to do that. 204 * all the pointers so the caller doesn't need to do that.
208 * the one that is passed. 212 * the one that is passed.
209 */ 213 */
210static player * 214static player *
211get_player (player *p) 215get_player (player *p)
212{ 216{
213 object *op = arch_to_object (get_player_archetype (NULL)); 217 object *op = arch_to_object (get_player_archetype (0));
214 int i; 218 int i;
215
216 if (!p)
217 {
218 p = new player;
219
220 /* This adds the player in the linked list. There is extra
221 * complexity here because we want to add the new player at the
222 * end of the list - there is in fact no compelling reason that
223 * that needs to be done except for things like output of
224 * 'who'.
225 */
226 player *tmp = first_player;
227
228 while (tmp != NULL && tmp->next != NULL)
229 tmp = tmp->next;
230 if (tmp != NULL)
231 tmp->next = p;
232 else
233 first_player = p;
234
235 p->next = NULL;
236 }
237 219
238 /* Clears basically the entire player structure except 220 /* Clears basically the entire player structure except
239 * for next and socket. 221 * for next and socket.
240 */ 222 */
241 p->clear (); 223 p->clear ();
260 op->speed_left = 0.5; 242 op->speed_left = 0.5;
261 op->speed = 1.0; 243 op->speed = 1.0;
262 op->direction = 5; /* So player faces south */ 244 op->direction = 5; /* So player faces south */
263 op->stats.wc = 2; 245 op->stats.wc = 2;
264 op->run_away = 25; /* Then we panick... */ 246 op->run_away = 25; /* Then we panick... */
247
248 {
249 int oldmon = p->socket->monitor_spells; // what a hack
265 p->socket.monitor_spells = 0; /* Needed because esrv_update_spells( ) gets called by roll_stats */ 250 p->socket->monitor_spells = 0; /* Needed because esrv_update_spells( ) gets called by roll_stats */
266
267 roll_stats (op); 251 roll_stats (op);
252 p->socket->monitor_spells = oldmon;
253 }
268 p->state = ST_ROLL_STAT; 254 p->state = ST_ROLL_STAT;
269 clear_los (op); 255 clear_los (op);
270 256
271 p->gen_sp_armour = 10; 257 p->gen_sp_armour = 10;
272 p->last_speed = -1; 258 p->last_speed = -1;
277 p->usekeys = containers; 263 p->usekeys = containers;
278 p->last_weapon_sp = -1; 264 p->last_weapon_sp = -1;
279 p->peaceful = 1; /* default peaceful */ 265 p->peaceful = 1; /* default peaceful */
280 p->do_los = 1; 266 p->do_los = 1;
281 p->explore = 0; 267 p->explore = 0;
282 p->no_shout = 0; /* default can shout */
283 268
284 assign (p->title, op->arch->clone.name); 269 assign (p->title, op->arch->clone.name);
285 op->race = op->arch->clone.race; 270 op->race = op->arch->clone.race;
286 271
287 CLEAR_FLAG (op, FLAG_READY_SKILL); 272 CLEAR_FLAG (op, FLAG_READY_SKILL);
294 for (i = 0; i < NUM_SKILLS; i++) 279 for (i = 0; i < NUM_SKILLS; i++)
295 { 280 {
296 p->last_skill_exp[i] = -1; 281 p->last_skill_exp[i] = -1;
297 p->last_skill_ob[i] = NULL; 282 p->last_skill_ob[i] = NULL;
298 } 283 }
284
299 for (i = 0; i < NROFATTACKS; i++) 285 for (i = 0; i < NROFATTACKS; i++)
300 {
301 p->last_resist[i] = -1; 286 p->last_resist[i] = -1;
302 } 287
303 p->last_stats.exp = -1; 288 p->last_stats.exp = -1;
304 p->last_weight = (uint32) - 1; 289 p->last_weight = (uint32) - 1;
305 290
306 p->socket.update_look = 0; 291 p->socket->update_look = 0;
307 p->socket.look_position = 0; 292 p->socket->look_position = 0;
293
308 return p; 294 return p;
309} 295}
310 296
311/* This loads the first map an puts the player on it. */ 297/* This loads the first map an puts the player on it. */
312static void 298static void
313set_first_map (object *op) 299set_first_map (object *op)
314{ 300{
315 strcpy (op->contr->maplevel, first_map_path); 301 strcpy (op->contr->maplevel, first_map_path);
316 op->x = -1; 302 op->x = -1;
317 op->y = -1; 303 op->y = -1;
318 enter_exit (op, NULL); 304 enter_exit (op, 0);
319} 305}
320 306
321/* Tries to add player on the connection passwd in ns. 307/* Tries to add player on the connection passwd in ns.
322 * All we can really get in this is some settings like host and display 308 * All we can really get in this is some settings like host and display
323 * mode. 309 * mode.
324 */ 310 */
325 311
326int 312int
327add_player (NewSocket * ns) 313add_player (client *ns)
328{ 314{
329 player *p; 315 player *p = new player;
330 316
331 p = get_player (NULL);
332 p->socket = *ns; 317 p->socket = ns;
333 p->socket.faces_sent = (uint8 *) malloc (p->socket.faces_sent_len * sizeof (*p->socket.faces_sent)); 318 ns->pl = p;
334 if (p->socket.faces_sent == NULL) 319
335 fatal (OUT_OF_MEMORY); 320 p->next = first_player;
336 memcpy (p->socket.faces_sent, ns->faces_sent, p->socket.faces_sent_len * sizeof (*p->socket.faces_sent)); 321 first_player = p;
337 /* Needed because the socket we just copied over needs to be cleared. 322
338 * Note that this can result in a client reset if there is partial data 323 p = get_player (p);
339 * on the uncoming socket. 324
340 */
341 p->socket.inbuf.len = 0;
342 set_first_map (p->ob); 325 set_first_map (p->ob);
343 326
344 CLEAR_FLAG (p->ob, FLAG_FRIENDLY); 327 CLEAR_FLAG (p->ob, FLAG_FRIENDLY);
345 add_friendly_object (p->ob); 328 add_friendly_object (p->ob);
346 send_rules (p->ob); 329 send_rules (p->ob);
347 send_news (p->ob); 330 send_news (p->ob);
348 display_motd (p->ob); 331 display_motd (p->ob);
349 get_name (p->ob); 332 get_name (p->ob);
333
350 return 0; 334 return 0;
351} 335}
352 336
353/* 337/*
354 * get_player_archetype() return next player archetype from archetype 338 * get_player_archetype() return next player archetype from archetype
364 { 348 {
365 if (at == NULL || at->next == NULL) 349 if (at == NULL || at->next == NULL)
366 at = first_archetype; 350 at = first_archetype;
367 else 351 else
368 at = at->next; 352 at = at->next;
353
369 if (at->clone.type == PLAYER) 354 if (at->clone.type == PLAYER)
370 return at; 355 return at;
356
371 if (at == start) 357 if (at == start)
372 { 358 {
373 LOG (llevError, "No Player archetypes\n"); 359 LOG (llevError, "No Player archetypes\n");
374 exit (-1); 360 exit (-1);
375 } 361 }
376 } 362 }
377} 363}
378
379 364
380object * 365object *
381get_nearest_player (object *mon) 366get_nearest_player (object *mon)
382{ 367{
383 object *op = NULL; 368 object *op = NULL;
489path_to_player (object *mon, object *pl, unsigned mindiff) 474path_to_player (object *mon, object *pl, unsigned mindiff)
490{ 475{
491 rv_vector rv; 476 rv_vector rv;
492 sint16 x, y; 477 sint16 x, y;
493 int lastx, lasty, dir, i, diff, firstdir = 0, lastdir, max = MAX_SPACES, mflags, blocked; 478 int lastx, lasty, dir, i, diff, firstdir = 0, lastdir, max = MAX_SPACES, mflags, blocked;
494 mapstruct *m, *lastmap; 479 maptile *m, *lastmap;
495 480
496 get_rangevector (mon, pl, &rv, 0); 481 get_rangevector (mon, pl, &rv, 0);
497 482
498 if (rv.distance < mindiff) 483 if (rv.distance < mindiff)
499 return 0; 484 return 0;
643 (op->type == ARMOUR || op->type == BOOTS || 628 (op->type == ARMOUR || op->type == BOOTS ||
644 op->type == CLOAK || op->type == HELMET || 629 op->type == CLOAK || op->type == HELMET ||
645 op->type == SHIELD || op->type == GLOVES || 630 op->type == SHIELD || op->type == GLOVES ||
646 op->type == BRACERS || op->type == GIRDLE)) || (!QUERY_FLAG (pl, FLAG_USE_WEAPON) && op->type == WEAPON)) 631 op->type == BRACERS || op->type == GIRDLE)) || (!QUERY_FLAG (pl, FLAG_USE_WEAPON) && op->type == WEAPON))
647 { 632 {
648 remove_ob (op); 633 op->destroy ();
649 free_object (op);
650 continue; 634 continue;
651 } 635 }
652 } 636 }
653 637
654 /* This really needs to be better - we should really give 638 /* This really needs to be better - we should really give
665 if (tmp->type == op->type && tmp->name == op->name) 649 if (tmp->type == op->type && tmp->name == op->name)
666 break; 650 break;
667 651
668 if (tmp) 652 if (tmp)
669 { 653 {
670 remove_ob (op); 654 op->destroy ();
671 free_object (op);
672 LOG (llevError, "give_initial_items: Removing duplicate object %s\n", &tmp->name); 655 LOG (llevError, "give_initial_items: Removing duplicate object %s\n", &tmp->name);
673 continue; 656 continue;
674 } 657 }
658
675 if (op->nrof > 1) 659 if (op->nrof > 1)
676 op->nrof = 1; 660 op->nrof = 1;
677 } 661 }
678 662
679 if (op->type == SPELLBOOK && op->inv) 663 if (op->type == SPELLBOOK && op->inv)
691 CLEAR_FLAG (op, FLAG_CURSED); 675 CLEAR_FLAG (op, FLAG_CURSED);
692 CLEAR_FLAG (op, FLAG_DAMNED); 676 CLEAR_FLAG (op, FLAG_DAMNED);
693 } 677 }
694 if (op->type == SPELL) 678 if (op->type == SPELL)
695 { 679 {
696 remove_ob (op); 680 op->destroy ();
697 free_object (op);
698 continue; 681 continue;
699 } 682 }
700 else if (op->type == SKILL) 683 else if (op->type == SKILL)
701 { 684 {
702 SET_FLAG (op, FLAG_CAN_USE_SKILL); 685 SET_FLAG (op, FLAG_CAN_USE_SKILL);
715void 698void
716get_name (object *op) 699get_name (object *op)
717{ 700{
718 op->contr->write_buf[0] = '\0'; 701 op->contr->write_buf[0] = '\0';
719 op->contr->state = ST_GET_NAME; 702 op->contr->state = ST_GET_NAME;
720 send_query (&op->contr->socket, 0, "What is your name?\n:"); 703 send_query (op->contr->socket, 0, "What is your name?\n:");
721} 704}
722 705
723void 706void
724get_password (object *op) 707get_password (object *op)
725{ 708{
726 op->contr->write_buf[0] = '\0'; 709 op->contr->write_buf[0] = '\0';
727 op->contr->state = ST_GET_PASSWORD; 710 op->contr->state = ST_GET_PASSWORD;
728 send_query (&op->contr->socket, CS_QUERY_HIDEINPUT, "What is your password?\n:"); 711 send_query (op->contr->socket, CS_QUERY_HIDEINPUT, "What is your password?\n:");
729} 712}
730 713
731void 714void
732play_again (object *op) 715play_again (object *op)
733{ 716{
734 op->contr->state = ST_PLAY_AGAIN; 717 op->contr->state = ST_PLAY_AGAIN;
735 op->chosen_skill = NULL; 718 op->chosen_skill = NULL;
736 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, "Do you want to play again (a/q)?"); 719 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "Do you want to play again (a/q)?");
737 /* a bit of a hack, but there are various places early in th 720 /* a bit of a hack, but there are various places early in th
738 * player creation process that a user can quit (eg, roll 721 * player creation process that a user can quit (eg, roll
739 * stats) that isn't removing the player. Taking a quick 722 * stats) that isn't removing the player. Taking a quick
740 * look, there are many places that call play_again without 723 * look, there are many places that call play_again without
741 * removing the player - it probably makes more sense 724 * removing the player - it probably makes more sense
742 * to leave it to play_again to remove the object in all 725 * to leave it to play_again to remove the object in all
743 * cases. 726 * cases.
744 */ 727 */
745 if (!QUERY_FLAG (op, FLAG_REMOVED)) 728 if (!QUERY_FLAG (op, FLAG_REMOVED))
746 remove_ob (op); 729 op->remove ();
747 /* Need to set this to null - otherwise, it could point to garbage, 730 /* Need to set this to null - otherwise, it could point to garbage,
748 * and draw() doesn't check to see if the player is removed, only if 731 * and draw() doesn't check to see if the player is removed, only if
749 * the map is null or not swapped out. 732 * the map is null or not swapped out.
750 */ 733 */
751 op->map = NULL; 734 op->map = NULL;
765 player *pl = op->contr; 748 player *pl = op->contr;
766 shstr name = op->name; 749 shstr name = op->name;
767 750
768 op->contr = 0; 751 op->contr = 0;
769 op->type = 0; 752 op->type = 0;
770 op->free (1); 753 op->destroy (1);
771 pl = get_player (pl); 754 pl = get_player (pl);
772 op = pl->ob; 755 op = pl->ob;
773 add_friendly_object (op); 756 add_friendly_object (op);
774 op->contr->password[0] = '~'; 757 op->contr->password[0] = '~';
775 op->name = op->name_pl = 0; 758 op->name = op->name_pl = 0;
790confirm_password (object *op) 773confirm_password (object *op)
791{ 774{
792 775
793 op->contr->write_buf[0] = '\0'; 776 op->contr->write_buf[0] = '\0';
794 op->contr->state = ST_CONFIRM_PASSWORD; 777 op->contr->state = ST_CONFIRM_PASSWORD;
795 send_query (&op->contr->socket, CS_QUERY_HIDEINPUT, "Please type your password again.\n:"); 778 send_query (op->contr->socket, CS_QUERY_HIDEINPUT, "Please type your password again.\n:");
796} 779}
797 780
798void 781void
799get_party_password (object *op, partylist *party) 782get_party_password (object *op, partylist *party)
800{ 783{
804 return; 787 return;
805 } 788 }
806 op->contr->write_buf[0] = '\0'; 789 op->contr->write_buf[0] = '\0';
807 op->contr->state = ST_GET_PARTY_PASSWORD; 790 op->contr->state = ST_GET_PARTY_PASSWORD;
808 op->contr->party_to_join = party; 791 op->contr->party_to_join = party;
809 send_query (&op->contr->socket, CS_QUERY_HIDEINPUT, "What is the password?\n:"); 792 send_query (op->contr->socket, CS_QUERY_HIDEINPUT, "What is the password?\n:");
810} 793}
811 794
812 795
813/* This rolls four 1-6 rolls and sums the best 3 of the 4. */ 796/* This rolls four 1-6 rolls and sums the best 3 of the 4. */
814int 797int
911 894
912void 895void
913Roll_Again (object *op) 896Roll_Again (object *op)
914{ 897{
915 esrv_new_player (op->contr, 0); 898 esrv_new_player (op->contr, 0);
916 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, 899 send_query (op->contr->socket, CS_QUERY_SINGLECHAR,
917 "[y] to roll new stats [n] to use stats\n[1-7] [1-7] to swap stats.\nRoll again (y/n/1-7)? "); 900 "[y] to roll new stats [n] to use stats\n[1-7] [1-7] to swap stats.\nRoll again (y/n/1-7)? ");
918} 901}
919 902
920void 903void
921Swap_Stat (object *op, int Swap_Second) 904Swap_Stat (object *op, int Swap_Second)
988 new_draw_info (NDI_UNIQUE, 0, op, buf); 971 new_draw_info (NDI_UNIQUE, 0, op, buf);
989 } 972 }
990 else 973 else
991 Swap_Stat (op, stat_trans[keynum]); 974 Swap_Stat (op, stat_trans[keynum]);
992 975
993 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, ""); 976 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "");
994 return 1; 977 return 1;
995 } 978 }
996 switch (key) 979 switch (key)
997 { 980 {
998 case 'n': 981 case 'n':
1012 enter_exit (op, NULL); 995 enter_exit (op, NULL);
1013#endif 996#endif
1014 SET_ANIMATION (op, 2); /* So player faces south */ 997 SET_ANIMATION (op, 2); /* So player faces south */
1015 /* Enter exit adds a player otherwise */ 998 /* Enter exit adds a player otherwise */
1016 add_statbonus (op); 999 add_statbonus (op);
1017 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, 1000 send_query (op->contr->socket, CS_QUERY_SINGLECHAR,
1018 "Now choose a character.\nPress any key to change outlook.\nPress `d' when you're pleased.\n"); 1001 "Now choose a character.\nPress any key to change outlook.\nPress `d' when you're pleased.\n");
1019 op->contr->state = ST_CHANGE_CLASS; 1002 op->contr->state = ST_CHANGE_CLASS;
1020 if (op->msg) 1003 if (op->msg)
1021 new_draw_info (NDI_BLUE, 0, op, op->msg); 1004 new_draw_info (NDI_BLUE, 0, op, op->msg);
1022 return 0; 1005 return 0;
1023 } 1006 }
1024 case 'y': 1007 case 'y':
1025 case 'Y': 1008 case 'Y':
1026 roll_stats (op); 1009 roll_stats (op);
1027 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, ""); 1010 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "");
1028 return 1; 1011 return 1;
1029 1012
1030 case 'q': 1013 case 'q':
1031 case 'Q': 1014 case 'Q':
1032 play_again (op); 1015 play_again (op);
1033 return 1; 1016 return 1;
1034 1017
1035 default: 1018 default:
1036 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, "Yes, No, Quit or 1-6. Roll again?"); 1019 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "Yes, No, Quit or 1-6. Roll again?");
1037 return 0; 1020 return 0;
1038 } 1021 }
1039 return 0; 1022 return 0;
1040} 1023}
1041 1024
1051{ 1034{
1052 int tmp_loop; 1035 int tmp_loop;
1053 1036
1054 if (key == 'q' || key == 'Q') 1037 if (key == 'q' || key == 'Q')
1055 { 1038 {
1056 remove_ob (op); 1039 op->remove ();
1057 play_again (op); 1040 play_again (op);
1058 return 0; 1041 return 0;
1059 } 1042 }
1060 if (key == 'd' || key == 'D') 1043 if (key == 'd' || key == 'D')
1061 { 1044 {
1062 char buf[MAX_BUF]; 1045 char buf[MAX_BUF];
1063 1046
1064 /* this must before then initial items are given */ 1047 /* this must before then initial items are given */
1065 esrv_new_player (op->contr, op->weight + op->carrying); 1048 esrv_new_player (op->contr, op->weight + op->carrying);
1049
1066 create_treasure (find_treasurelist ("starting_wealth"), op, 0, 0, 0); 1050 treasurelist *tl = find_treasurelist ("starting_wealth");
1051 if (tl)
1052 create_treasure (tl, op, 0, 0, 0);
1067 1053
1068 INVOKE_PLAYER (BIRTH, op->contr); 1054 INVOKE_PLAYER (BIRTH, op->contr);
1069 INVOKE_PLAYER (LOGIN, op->contr); 1055 INVOKE_PLAYER (LOGIN, op->contr);
1070 1056
1071 op->contr->state = ST_PLAYING; 1057 op->contr->state = ST_PLAYING;
1096 { 1082 {
1097 object *tmp; 1083 object *tmp;
1098 char mapname[MAX_BUF]; 1084 char mapname[MAX_BUF];
1099 1085
1100 snprintf (mapname, MAX_BUF - 1, "%s/%s", first_map_ext_path, &op->arch->name); 1086 snprintf (mapname, MAX_BUF - 1, "%s/%s", first_map_ext_path, &op->arch->name);
1101 tmp = get_object (); 1087 tmp = object::create ();
1102 EXIT_PATH (tmp) = mapname; 1088 EXIT_PATH (tmp) = mapname;
1103 EXIT_X (tmp) = op->x; 1089 EXIT_X (tmp) = op->x;
1104 EXIT_Y (tmp) = op->y; 1090 EXIT_Y (tmp) = op->y;
1105 enter_exit (op, tmp); /* we don't really care if it succeeded; 1091 enter_exit (op, tmp); /* we don't really care if it succeeded;
1106 * if the map isn't there, then stay on the 1092 * if the map isn't there, then stay on the
1107 * default initial map */ 1093 * default initial map */
1108 free_object (tmp); 1094 tmp->destroy ();
1109 } 1095 }
1110 else 1096 else
1111 {
1112 LOG (llevDebug, "first_map_ext_path not set\n"); 1097 LOG (llevDebug, "first_map_ext_path not set\n");
1113 } 1098
1114 return 0; 1099 return 0;
1115 } 1100 }
1116 1101
1117 /* Following actually changes the race - this is the default command 1102 /* Following actually changes the race - this is the default command
1118 * if we don't match with one of the options above. 1103 * if we don't match with one of the options above.
1123 { 1108 {
1124 shstr name = op->name; 1109 shstr name = op->name;
1125 int x = op->x, y = op->y; 1110 int x = op->x, y = op->y;
1126 1111
1127 remove_statbonus (op); 1112 remove_statbonus (op);
1128 remove_ob (op); 1113 op->remove ();
1129 op->arch = get_player_archetype (op->arch); 1114 op->arch = get_player_archetype (op->arch);
1130 copy_object (&op->arch->clone, op); 1115 op->arch->clone.copy_to (op);
1131 op->instantiate (); 1116 op->instantiate ();
1132 op->stats = op->contr->orig_stats; 1117 op->stats = op->contr->orig_stats;
1133 op->name = op->name_pl = name; 1118 op->name = op->name_pl = name;
1134 op->x = x; 1119 op->x = x;
1135 op->y = y; 1120 op->y = y;
1148 op->stats.grace = 0; 1133 op->stats.grace = 0;
1149 1134
1150 if (op->msg) 1135 if (op->msg)
1151 new_draw_info (NDI_BLUE, 0, op, op->msg); 1136 new_draw_info (NDI_BLUE, 0, op, op->msg);
1152 1137
1153 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, "Press any key for the next race.\nPress `d' to play this race.\n"); 1138 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "Press any key for the next race.\nPress `d' to play this race.\n");
1154 return 0; 1139 return 0;
1155} 1140}
1156 1141
1157int 1142int
1158key_confirm_quit (object *op, char key) 1143key_confirm_quit (object *op, char key)
1180 if (settings.set_title == TRUE) 1165 if (settings.set_title == TRUE)
1181 op->contr->own_title[0] = '\0'; 1166 op->contr->own_title[0] = '\0';
1182 1167
1183 if (!QUERY_FLAG (op, FLAG_WAS_WIZ)) 1168 if (!QUERY_FLAG (op, FLAG_WAS_WIZ))
1184 { 1169 {
1185 mapstruct *mp, *next; 1170 maptile *mp, *next;
1186 1171
1187 /* We need to hunt for any per player unique maps in memory and 1172 /* We need to hunt for any per player unique maps in memory and
1188 * get rid of them. The trailing slash in the path is intentional, 1173 * get rid of them. The trailing slash in the path is intentional,
1189 * so that players named 'Ab' won't match against players 'Abe' pathname 1174 * so that players named 'Ab' won't match against players 'Abe' pathname
1190 */ 1175 */
1264 */ 1249 */
1265int 1250int
1266check_pick (object *op) 1251check_pick (object *op)
1267{ 1252{
1268 object *tmp, *next; 1253 object *tmp, *next;
1269 tag_t next_tag = 0, op_tag;
1270 int stop = 0; 1254 int stop = 0;
1271 int j, k, wvratio; 1255 int j, k, wvratio;
1272 char putstring[128], tmpstr[16]; 1256 char putstring[128], tmpstr[16];
1273 1257
1274
1275 /* if you're flying, you cna't pick up anything */ 1258 /* if you're flying, you cna't pick up anything */
1276 if (op->move_type & MOVE_FLYING) 1259 if (op->move_type & MOVE_FLYING)
1277 return 1; 1260 return 1;
1278 1261
1279 op_tag = op->count;
1280
1281 next = op->below; 1262 next = op->below;
1282 if (next)
1283 next_tag = next->count;
1284 1263
1285 /* loop while there are items on the floor that are not marked as 1264 /* loop while there are items on the floor that are not marked as
1286 * destroyed */ 1265 * destroyed */
1287 while (next && !was_destroyed (next, next_tag)) 1266 while (next && !next->destroyed ())
1288 { 1267 {
1289 tmp = next; 1268 tmp = next;
1290 next = tmp->below; 1269 next = tmp->below;
1291 if (next)
1292 next_tag = next->count;
1293 1270
1294 if (was_destroyed (op, op_tag)) 1271 if (op->destroyed ())
1295 return 0; 1272 return 0;
1296 1273
1297 if (!can_pick (op, tmp)) 1274 if (!can_pick (op, tmp))
1298 continue; 1275 continue;
1299 1276
1431 /* question: don't pick up known-poisonous stuff? */ 1408 /* question: don't pick up known-poisonous stuff? */
1432 if (op->contr->mode & PU_FOOD) 1409 if (op->contr->mode & PU_FOOD)
1433 if (tmp->type == FOOD) 1410 if (tmp->type == FOOD)
1434 { 1411 {
1435 pick_up (op, tmp); 1412 pick_up (op, tmp);
1436 if (0)
1437 fprintf (stderr, "FOOD\n");
1438 continue; 1413 continue;
1439 } 1414 }
1415
1440 if (op->contr->mode & PU_DRINK) 1416 if (op->contr->mode & PU_DRINK)
1441 if (tmp->type == DRINK || (tmp->type == POISON && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED))) 1417 if (tmp->type == DRINK || (tmp->type == POISON && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED)))
1442 { 1418 {
1443 pick_up (op, tmp); 1419 pick_up (op, tmp);
1444 if (0)
1445 fprintf (stderr, "DRINK\n");
1446 continue; 1420 continue;
1447 } 1421 }
1448 1422
1449 if (op->contr->mode & PU_POTION) 1423 if (op->contr->mode & PU_POTION)
1450 if (tmp->type == POTION) 1424 if (tmp->type == POTION)
1451 { 1425 {
1452 pick_up (op, tmp); 1426 pick_up (op, tmp);
1453 if (0)
1454 fprintf (stderr, "POTION\n");
1455 continue; 1427 continue;
1456 } 1428 }
1457 1429
1458 /* spellbooks, skillscrolls and normal books/scrolls */ 1430 /* spellbooks, skillscrolls and normal books/scrolls */
1459 if (op->contr->mode & PU_SPELLBOOK) 1431 if (op->contr->mode & PU_SPELLBOOK)
1460 if (tmp->type == SPELLBOOK) 1432 if (tmp->type == SPELLBOOK)
1461 { 1433 {
1462 pick_up (op, tmp); 1434 pick_up (op, tmp);
1463 if (0)
1464 fprintf (stderr, "SPELLBOOK\n");
1465 continue; 1435 continue;
1466 } 1436 }
1437
1467 if (op->contr->mode & PU_SKILLSCROLL) 1438 if (op->contr->mode & PU_SKILLSCROLL)
1468 if (tmp->type == SKILLSCROLL) 1439 if (tmp->type == SKILLSCROLL)
1469 { 1440 {
1470 pick_up (op, tmp); 1441 pick_up (op, tmp);
1471 if (0)
1472 fprintf (stderr, "SKILLSCROLL\n");
1473 continue; 1442 continue;
1474 } 1443 }
1444
1475 if (op->contr->mode & PU_READABLES) 1445 if (op->contr->mode & PU_READABLES)
1476 if (tmp->type == BOOK || tmp->type == SCROLL) 1446 if (tmp->type == BOOK || tmp->type == SCROLL)
1477 { 1447 {
1478 pick_up (op, tmp); 1448 pick_up (op, tmp);
1479 if (0)
1480 fprintf (stderr, "READABLES\n");
1481 continue; 1449 continue;
1482 } 1450 }
1483 1451
1484 /* wands/staves/rods/horns */ 1452 /* wands/staves/rods/horns */
1485 if (op->contr->mode & PU_MAGIC_DEVICE) 1453 if (op->contr->mode & PU_MAGIC_DEVICE)
1486 if (tmp->type == WAND || tmp->type == ROD || tmp->type == HORN) 1454 if (tmp->type == WAND || tmp->type == ROD || tmp->type == HORN)
1487 { 1455 {
1488 pick_up (op, tmp); 1456 pick_up (op, tmp);
1489 if (0)
1490 fprintf (stderr, "MAGIC_DEVICE\n");
1491 continue; 1457 continue;
1492 } 1458 }
1493 1459
1494 /* pick up all magical items */ 1460 /* pick up all magical items */
1495 if (op->contr->mode & PU_MAGICAL) 1461 if (op->contr->mode & PU_MAGICAL)
1496 if (QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED)) 1462 if (QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED))
1497 { 1463 {
1498 pick_up (op, tmp); 1464 pick_up (op, tmp);
1499 if (0)
1500 fprintf (stderr, "MAGICAL\n");
1501 continue; 1465 continue;
1502 } 1466 }
1503 1467
1504 if (op->contr->mode & PU_VALUABLES) 1468 if (op->contr->mode & PU_VALUABLES)
1505 { 1469 {
1506 if (tmp->type == MONEY || tmp->type == GEM) 1470 if (tmp->type == MONEY || tmp->type == GEM)
1507 { 1471 {
1508 pick_up (op, tmp); 1472 pick_up (op, tmp);
1509 if (0)
1510 fprintf (stderr, "MONEY/GEM\n");
1511 continue; 1473 continue;
1512 } 1474 }
1513 } 1475 }
1514 1476
1515 /* rings & amulets - talismans seems to be typed AMULET */ 1477 /* rings & amulets - talismans seems to be typed AMULET */
1516 if (op->contr->mode & PU_JEWELS) 1478 if (op->contr->mode & PU_JEWELS)
1517 if (tmp->type == RING || tmp->type == AMULET) 1479 if (tmp->type == RING || tmp->type == AMULET)
1518 { 1480 {
1519 pick_up (op, tmp); 1481 pick_up (op, tmp);
1482 continue;
1520 if (0) 1483 }
1521 fprintf (stderr, "JEWELS\n"); 1484
1485 /* we don't forget dragon food */
1486 if (op->contr->mode & PU_FLESH)
1487 if (tmp->type == FLESH)
1488 {
1489 pick_up (op, tmp);
1522 continue; 1490 continue;
1523 } 1491 }
1524 1492
1525 /* bows and arrows. Bows are good for selling! */ 1493 /* bows and arrows. Bows are good for selling! */
1526 if (op->contr->mode & PU_BOW) 1494 if (op->contr->mode & PU_BOW)
1527 if (tmp->type == BOW) 1495 if (tmp->type == BOW)
1528 { 1496 {
1529 pick_up (op, tmp); 1497 pick_up (op, tmp);
1530 if (0)
1531 fprintf (stderr, "BOW\n");
1532 continue; 1498 continue;
1533 } 1499 }
1500
1534 if (op->contr->mode & PU_ARROW) 1501 if (op->contr->mode & PU_ARROW)
1535 if (tmp->type == ARROW) 1502 if (tmp->type == ARROW)
1536 { 1503 {
1537 pick_up (op, tmp); 1504 pick_up (op, tmp);
1538 if (0)
1539 fprintf (stderr, "ARROW\n");
1540 continue; 1505 continue;
1541 } 1506 }
1542 1507
1543 /* all kinds of armor etc. */ 1508 /* all kinds of armor etc. */
1544 if (op->contr->mode & PU_ARMOUR) 1509 if (op->contr->mode & PU_ARMOUR)
1545 if (tmp->type == ARMOUR) 1510 if (tmp->type == ARMOUR)
1546 { 1511 {
1547 pick_up (op, tmp); 1512 pick_up (op, tmp);
1548 if (0)
1549 fprintf (stderr, "ARMOUR\n");
1550 continue; 1513 continue;
1551 } 1514 }
1515
1552 if (op->contr->mode & PU_HELMET) 1516 if (op->contr->mode & PU_HELMET)
1553 if (tmp->type == HELMET) 1517 if (tmp->type == HELMET)
1554 { 1518 {
1555 pick_up (op, tmp); 1519 pick_up (op, tmp);
1556 if (0)
1557 fprintf (stderr, "HELMET\n");
1558 continue; 1520 continue;
1559 } 1521 }
1522
1560 if (op->contr->mode & PU_SHIELD) 1523 if (op->contr->mode & PU_SHIELD)
1561 if (tmp->type == SHIELD) 1524 if (tmp->type == SHIELD)
1562 { 1525 {
1563 pick_up (op, tmp); 1526 pick_up (op, tmp);
1564 if (0)
1565 fprintf (stderr, "SHIELD\n");
1566 continue; 1527 continue;
1567 } 1528 }
1529
1568 if (op->contr->mode & PU_BOOTS) 1530 if (op->contr->mode & PU_BOOTS)
1569 if (tmp->type == BOOTS) 1531 if (tmp->type == BOOTS)
1570 { 1532 {
1571 pick_up (op, tmp); 1533 pick_up (op, tmp);
1572 if (0)
1573 fprintf (stderr, "BOOTS\n");
1574 continue; 1534 continue;
1575 } 1535 }
1536
1576 if (op->contr->mode & PU_GLOVES) 1537 if (op->contr->mode & PU_GLOVES)
1577 if (tmp->type == GLOVES) 1538 if (tmp->type == GLOVES)
1578 { 1539 {
1579 pick_up (op, tmp); 1540 pick_up (op, tmp);
1580 if (0)
1581 fprintf (stderr, "GLOVES\n");
1582 continue; 1541 continue;
1583 } 1542 }
1543
1584 if (op->contr->mode & PU_CLOAK) 1544 if (op->contr->mode & PU_CLOAK)
1585 if (tmp->type == CLOAK) 1545 if (tmp->type == CLOAK)
1586 { 1546 {
1587 pick_up (op, tmp); 1547 pick_up (op, tmp);
1588 if (0)
1589 fprintf (stderr, "GLOVES\n");
1590 continue; 1548 continue;
1591 } 1549 }
1592 1550
1593 /* hoping to catch throwing daggers here */ 1551 /* hoping to catch throwing daggers here */
1594 if (op->contr->mode & PU_MISSILEWEAPON) 1552 if (op->contr->mode & PU_MISSILEWEAPON)
1595 if (tmp->type == WEAPON && QUERY_FLAG (tmp, FLAG_IS_THROWN)) 1553 if (tmp->type == WEAPON && QUERY_FLAG (tmp, FLAG_IS_THROWN))
1596 { 1554 {
1597 pick_up (op, tmp); 1555 pick_up (op, tmp);
1598 if (0)
1599 fprintf (stderr, "MISSILEWEAPON\n");
1600 continue; 1556 continue;
1601 } 1557 }
1602 1558
1603 /* careful: chairs and tables are weapons! */ 1559 /* careful: chairs and tables are weapons! */
1604 if (op->contr->mode & PU_ALLWEAPON) 1560 if (op->contr->mode & PU_ALLWEAPON)
1607 { 1563 {
1608 if (strstr (tmp->name, "table") == NULL && strstr (tmp->arch->name, "table") == NULL && 1564 if (strstr (tmp->name, "table") == NULL && strstr (tmp->arch->name, "table") == NULL &&
1609 strstr (tmp->name, "chair") && strstr (tmp->arch->name, "chair") == NULL) 1565 strstr (tmp->name, "chair") && strstr (tmp->arch->name, "chair") == NULL)
1610 { 1566 {
1611 pick_up (op, tmp); 1567 pick_up (op, tmp);
1612 if (0)
1613 fprintf (stderr, "WEAPON\n");
1614 continue; 1568 continue;
1615 } 1569 }
1616 } 1570 }
1571
1617 if (tmp->type == WEAPON && tmp->name == NULL) 1572 if (tmp->type == WEAPON && tmp->name == NULL)
1618 { 1573 {
1619 if (strstr (tmp->arch->name, "table") == NULL && strstr (tmp->arch->name, "chair") == NULL) 1574 if (strstr (tmp->arch->name, "table") == NULL && strstr (tmp->arch->name, "chair") == NULL)
1620 { 1575 {
1621 pick_up (op, tmp); 1576 pick_up (op, tmp);
1622 if (0)
1623 fprintf (stderr, "WEAPON\n");
1624 continue; 1577 continue;
1625 } 1578 }
1626 } 1579 }
1627 } 1580 }
1628 1581
1629 /* misc stuff that's useful */ 1582 /* misc stuff that's useful */
1630 if (op->contr->mode & PU_KEY) 1583 if (op->contr->mode & PU_KEY)
1631 if (tmp->type == KEY || tmp->type == SPECIAL_KEY) 1584 if (tmp->type == KEY || tmp->type == SPECIAL_KEY)
1632 { 1585 {
1633 pick_up (op, tmp); 1586 pick_up (op, tmp);
1634 if (0)
1635 fprintf (stderr, "KEY\n");
1636 continue; 1587 continue;
1637 } 1588 }
1638 1589
1639 /* any of the last 4 bits set means we use the ratio for value 1590 /* any of the last 4 bits set means we use the ratio for value
1640 * pickups */ 1591 * pickups */
1662 continue; 1613 continue;
1663 } 1614 }
1664 } 1615 }
1665 } /* the new pickup model */ 1616 } /* the new pickup model */
1666 } 1617 }
1618
1667 return !stop; 1619 return !stop;
1668} 1620}
1669 1621
1670/* 1622/*
1671 * Find an arrow in the inventory and after that 1623 * Find an arrow in the inventory and after that
1770 1722
1771object * 1723object *
1772pick_arrow_target (object *op, const char *type, int dir) 1724pick_arrow_target (object *op, const char *type, int dir)
1773{ 1725{
1774 object *tmp = NULL; 1726 object *tmp = NULL;
1775 mapstruct *m; 1727 maptile *m;
1776 int i, mflags, found, number; 1728 int i, mflags, found, number;
1777 sint16 x, y; 1729 sint16 x, y;
1778 1730
1779 if (op->map == NULL) 1731 if (op->map == NULL)
1780 return find_arrow (op, type); 1732 return find_arrow (op, type);
1840 */ 1792 */
1841int 1793int
1842fire_bow (object *op, object *part, object *arrow, int dir, int wc_mod, sint16 sx, sint16 sy) 1794fire_bow (object *op, object *part, object *arrow, int dir, int wc_mod, sint16 sx, sint16 sy)
1843{ 1795{
1844 object *left, *bow; 1796 object *left, *bow;
1845 tag_t left_tag, tag;
1846 int bowspeed, mflags; 1797 int bowspeed, mflags;
1847 mapstruct *m; 1798 maptile *m;
1848 1799
1849 if (!dir) 1800 if (!dir)
1850 { 1801 {
1851 new_draw_info (NDI_UNIQUE, 0, op, "You can't shoot yourself!"); 1802 new_draw_info (NDI_UNIQUE, 0, op, "You can't shoot yourself!");
1852 return 0; 1803 return 0;
1853 } 1804 }
1805
1854 if (op->type == PLAYER) 1806 if (op->type == PLAYER)
1855 bow = op->contr->ranges[range_bow]; 1807 bow = op->contr->ranges[range_bow];
1856 else 1808 else
1857 { 1809 {
1858 for (bow = op->inv; bow; bow = bow->below) 1810 for (bow = op->inv; bow; bow = bow->below)
1866 { 1818 {
1867 LOG (llevError, "Range: bow without activated bow (%s).\n", &op->name); 1819 LOG (llevError, "Range: bow without activated bow (%s).\n", &op->name);
1868 return 0; 1820 return 0;
1869 } 1821 }
1870 } 1822 }
1823
1871 if (!bow->race || !bow->skill) 1824 if (!bow->race || !bow->skill)
1872 { 1825 {
1873 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is broken.", &bow->name); 1826 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is broken.", &bow->name);
1874 return 0; 1827 return 0;
1875 } 1828 }
1877 bowspeed = bow->stats.sp + dex_bonus[op->stats.Dex]; 1830 bowspeed = bow->stats.sp + dex_bonus[op->stats.Dex];
1878 1831
1879 /* penalize ROF for bestarrow */ 1832 /* penalize ROF for bestarrow */
1880 if (op->type == PLAYER && op->contr->bowtype == bow_bestarrow) 1833 if (op->type == PLAYER && op->contr->bowtype == bow_bestarrow)
1881 bowspeed -= dex_bonus[op->stats.Dex] + 5; 1834 bowspeed -= dex_bonus[op->stats.Dex] + 5;
1835
1882 if (bowspeed < 1) 1836 if (bowspeed < 1)
1883 bowspeed = 1; 1837 bowspeed = 1;
1884 1838
1885 if (arrow == NULL) 1839 if (arrow == NULL)
1886 { 1840 {
1892 else 1846 else
1893 CLEAR_FLAG (op, FLAG_READY_BOW); 1847 CLEAR_FLAG (op, FLAG_READY_BOW);
1894 return 0; 1848 return 0;
1895 } 1849 }
1896 } 1850 }
1851
1897 mflags = get_map_flags (op->map, &m, sx, sy, &sx, &sy); 1852 mflags = get_map_flags (op->map, &m, sx, sy, &sx, &sy);
1898 if (mflags & P_OUT_OF_MAP) 1853 if (mflags & P_OUT_OF_MAP)
1899 {
1900 return 0; 1854 return 0;
1901 } 1855
1902 if (GET_MAP_MOVE_BLOCK (m, sx, sy) == MOVE_FLY_LOW) 1856 if (GET_MAP_MOVE_BLOCK (m, sx, sy) == MOVE_FLY_LOW)
1903 { 1857 {
1904 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); 1858 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way.");
1905 return 0; 1859 return 0;
1906 } 1860 }
1907 1861
1908 /* this should not happen, but sometimes does */ 1862 /* this should not happen, but sometimes does */
1909 if (arrow->nrof == 0) 1863 if (arrow->nrof == 0)
1910 { 1864 {
1911 remove_ob (arrow); 1865 arrow->destroy ();
1912 free_object (arrow);
1913 return 0; 1866 return 0;
1914 } 1867 }
1915 1868
1916 left = arrow; /* these are arrows left to the player */ 1869 left = arrow; /* these are arrows left to the player */
1917 left_tag = left->count;
1918 arrow = get_split_ob (arrow, 1); 1870 arrow = get_split_ob (arrow, 1);
1919 if (arrow == NULL) 1871 if (!arrow)
1920 { 1872 {
1921 new_draw_info_format (NDI_UNIQUE, 0, op, "You have no %s left.", &bow->race); 1873 new_draw_info_format (NDI_UNIQUE, 0, op, "You have no %s left.", &bow->race);
1922 return 0; 1874 return 0;
1923 } 1875 }
1924 set_owner (arrow, op); 1876
1877 arrow->set_owner (op);
1925 arrow->skill = bow->skill; 1878 arrow->skill = bow->skill;
1926 1879
1927 arrow->direction = dir; 1880 arrow->direction = dir;
1928 arrow->x = sx; 1881 arrow->x = sx;
1929 arrow->y = sy; 1882 arrow->y = sy;
1937 SET_ANIMATION (arrow, arrow->direction); 1890 SET_ANIMATION (arrow, arrow->direction);
1938 arrow->stats.sp = arrow->stats.wc; /* save original wc and dam */ 1891 arrow->stats.sp = arrow->stats.wc; /* save original wc and dam */
1939 arrow->stats.hp = arrow->stats.dam; 1892 arrow->stats.hp = arrow->stats.dam;
1940 arrow->stats.grace = arrow->attacktype; 1893 arrow->stats.grace = arrow->attacktype;
1941 if (arrow->slaying != NULL) 1894 if (arrow->slaying != NULL)
1942 arrow->spellarg = strdup_local (arrow->slaying); 1895 arrow->spellarg = strdup (arrow->slaying);
1943 1896
1944 /* Note that this was different for monsters - they got their level 1897 /* Note that this was different for monsters - they got their level
1945 * added to the damage. I think the strength bonus is more proper. 1898 * added to the damage. I think the strength bonus is more proper.
1946 */ 1899 */
1947 1900
1965 arrow->level = op->chosen_skill ? op->chosen_skill->level : op->level; 1918 arrow->level = op->chosen_skill ? op->chosen_skill->level : op->level;
1966 } 1919 }
1967 else 1920 else
1968 { 1921 {
1969 arrow->stats.wc = op->stats.wc - bow->magic - arrow->magic - arrow->stats.wc + wc_mod; 1922 arrow->stats.wc = op->stats.wc - bow->magic - arrow->magic - arrow->stats.wc + wc_mod;
1970
1971 arrow->level = op->level; 1923 arrow->level = op->level;
1972 } 1924 }
1925
1973 if (arrow->attacktype == AT_PHYSICAL) 1926 if (arrow->attacktype == AT_PHYSICAL)
1974 arrow->attacktype |= bow->attacktype; 1927 arrow->attacktype |= bow->attacktype;
1928
1975 if (bow->slaying != NULL) 1929 if (bow->slaying)
1976 arrow->slaying = bow->slaying; 1930 arrow->slaying = bow->slaying;
1977 1931
1978 arrow->map = m; 1932 arrow->map = m;
1979 arrow->move_type = MOVE_FLY_LOW; 1933 arrow->move_type = MOVE_FLY_LOW;
1980 arrow->move_on = MOVE_FLY_LOW | MOVE_WALK; 1934 arrow->move_on = MOVE_FLY_LOW | MOVE_WALK;
1981 1935
1982 play_sound_map (op->map, op->x, op->y, SOUND_FIRE_ARROW); 1936 play_sound_map (op->map, op->x, op->y, SOUND_FIRE_ARROW);
1983 tag = arrow->count;
1984 insert_ob_in_map (arrow, m, op, 0); 1937 insert_ob_in_map (arrow, m, op, 0);
1985 1938
1986 if (!was_destroyed (arrow, tag)) 1939 if (!arrow->destroyed ())
1987 move_arrow (arrow); 1940 move_arrow (arrow);
1988 1941
1989 if (op->type == PLAYER) 1942 if (op->type == PLAYER)
1990 { 1943 {
1991 if (was_destroyed (left, left_tag)) 1944 if (left->destroyed ())
1992 esrv_del_item (op->contr, left_tag); 1945 esrv_del_item (op->contr, left->count);
1993 else 1946 else
1994 esrv_send_item (op, left); 1947 esrv_send_item (op, left);
1995 } 1948 }
1949
1996 return 1; 1950 return 1;
1997} 1951}
1998 1952
1999/* Special fire code for players - this takes into 1953/* Special fire code for players - this takes into
2000 * account the special fire modes players can have 1954 * account the special fire modes players can have
2136 case range_misc: 2090 case range_misc:
2137 fire_misc_object (op, dir); 2091 fire_misc_object (op, dir);
2138 return; 2092 return;
2139 2093
2140 case range_golem: /* Control summoned monsters from scrolls */ 2094 case range_golem: /* Control summoned monsters from scrolls */
2141 if (op->contr->ranges[range_golem] == NULL || op->contr->golem_count != op->contr->ranges[range_golem]->count) 2095 if (QUERY_FLAG (op->contr->ranges[range_golem], FLAG_REMOVED))
2142 { 2096 {
2143 op->contr->ranges[range_golem] = NULL; 2097 op->contr->ranges[range_golem] = 0;
2144 op->contr->shoottype = range_none; 2098 op->contr->shoottype = range_none;
2145 op->contr->golem_count = 0;
2146 } 2099 }
2147 else 2100 else
2148 control_golem (op->contr->ranges[range_golem], dir); 2101 control_golem (op->contr->ranges[range_golem], dir);
2149 return; 2102 return;
2150 2103
2312move_player_attack (object *op, int dir) 2265move_player_attack (object *op, int dir)
2313{ 2266{
2314 object *tmp, *mon; 2267 object *tmp, *mon;
2315 sint16 nx, ny; 2268 sint16 nx, ny;
2316 int on_battleground; 2269 int on_battleground;
2317 mapstruct *m; 2270 maptile *m;
2318 2271
2319 nx = freearr_x[dir] + op->x; 2272 nx = freearr_x[dir] + op->x;
2320 ny = freearr_y[dir] + op->y; 2273 ny = freearr_y[dir] + op->y;
2321 2274
2322 on_battleground = op_on_battleground (op, NULL, NULL); 2275 on_battleground = op_on_battleground (op, NULL, NULL);
2358 if (tmp == op) 2311 if (tmp == op)
2359 { 2312 {
2360 tmp = tmp->above; 2313 tmp = tmp->above;
2361 continue; 2314 continue;
2362 } 2315 }
2316
2363 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 2317 if (QUERY_FLAG (tmp, FLAG_ALIVE))
2364 { 2318 {
2365 mon = tmp; 2319 mon = tmp;
2366 break; 2320 break;
2367 } 2321 }
2322
2368 if (tmp->type == LOCKED_DOOR || QUERY_FLAG (tmp, FLAG_CAN_ROLL)) 2323 if (tmp->type == LOCKED_DOOR || QUERY_FLAG (tmp, FLAG_CAN_ROLL))
2369 mon = tmp; 2324 mon = tmp;
2325
2370 tmp = tmp->above; 2326 tmp = tmp->above;
2371 } 2327 }
2372 2328
2373 if (mon == NULL) /* This happens anytime the player tries to move */ 2329 if (mon == NULL) /* This happens anytime the player tries to move */
2374 return; /* into a wall */ 2330 return; /* into a wall */
2393 * player owns it and it is either friendly or unagressive. 2349 * player owns it and it is either friendly or unagressive.
2394 */ 2350 */
2395 if ((op->type == PLAYER) 2351 if ((op->type == PLAYER)
2396#if COZY_SERVER 2352#if COZY_SERVER
2397 && 2353 &&
2398 ((get_owner (mon) && get_owner (mon)->contr 2354 ((mon->owner && mon->owner->contr
2399 && same_party (get_owner (mon)->contr->party, op->contr->party)) || get_owner (mon) == op) 2355 && same_party (mon->owner->contr->party, op->contr->party)) || mon->owner == op)
2400#else 2356#else
2401 && get_owner (mon) == op 2357 && mon->owner == op
2402#endif 2358#endif
2403 && (QUERY_FLAG (mon, FLAG_UNAGGRESSIVE) || QUERY_FLAG (mon, FLAG_FRIENDLY))) 2359 && (QUERY_FLAG (mon, FLAG_UNAGGRESSIVE) || QUERY_FLAG (mon, FLAG_FRIENDLY)))
2404 { 2360 {
2405 /* If we're braced, we don't want to switch places with it */ 2361 /* If we're braced, we don't want to switch places with it */
2406 if (op->contr->braced) 2362 if (op->contr->braced)
2593 /* I've been seeing crashes where the golem has been destroyed, but 2549 /* I've been seeing crashes where the golem has been destroyed, but
2594 * the player object still points to the defunct golem. The code that 2550 * the player object still points to the defunct golem. The code that
2595 * destroys the golem looks correct, and it doesn't always happen, so 2551 * destroys the golem looks correct, and it doesn't always happen, so
2596 * put this in a a workaround to clean up the golem pointer. 2552 * put this in a a workaround to clean up the golem pointer.
2597 */ 2553 */
2598 if (op->contr->ranges[range_golem] &&
2599 ((op->contr->golem_count != op->contr->ranges[range_golem]->count) || QUERY_FLAG (op->contr->ranges[range_golem], FLAG_REMOVED))) 2554 if (op->contr->ranges[range_golem] && QUERY_FLAG (op->contr->ranges[range_golem], FLAG_REMOVED))
2600 {
2601 op->contr->ranges[range_golem] = NULL; 2555 op->contr->ranges[range_golem] = 0;
2602 op->contr->golem_count = 0;
2603 }
2604 2556
2605 /* call this here - we also will call this in do_ericserver, but 2557 /* call this here - we also will call this in do_ericserver, but
2606 * the players time has been increased when doericserver has been 2558 * the players time has been increased when doericserver has been
2607 * called, so we recheck it here. 2559 * called, so we recheck it here.
2608 */ 2560 */
2609 HandleClient (&op->contr->socket, op->contr); 2561 //TODO: better than handling 8 commands, use some more intelligent rate-limiting
2562 for (int rep = 8; --rep && op->contr->socket->handle_command (); )
2563 ;
2564
2610 if (op->speed_left < 0) 2565 if (op->speed_left < 0)
2611 return 0; 2566 return 0;
2612 2567
2613 if (op->direction && (op->contr->run_on || op->contr->fire_on)) 2568 if (op->direction && (op->contr->run_on || op->contr->fire_on))
2614 { 2569 {
2623 if (op->speed_left > 0) 2578 if (op->speed_left > 0)
2624 return 1; 2579 return 1;
2625 else 2580 else
2626 return 0; 2581 return 0;
2627 } 2582 }
2583
2628 return 0; 2584 return 0;
2629} 2585}
2630 2586
2631int 2587int
2632save_life (object *op) 2588save_life (object *op)
2633{ 2589{
2634 object *tmp;
2635
2636 if (!QUERY_FLAG (op, FLAG_LIFESAVE)) 2590 if (!QUERY_FLAG (op, FLAG_LIFESAVE))
2637 return 0; 2591 return 0;
2638 2592
2639 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 2593 for (object *tmp = op->inv; tmp; tmp = tmp->below)
2640 if (QUERY_FLAG (tmp, FLAG_APPLIED) && QUERY_FLAG (tmp, FLAG_LIFESAVE)) 2594 if (QUERY_FLAG (tmp, FLAG_APPLIED) && QUERY_FLAG (tmp, FLAG_LIFESAVE))
2641 { 2595 {
2642 play_sound_map (op->map, op->x, op->y, SOUND_OB_EVAPORATE); 2596 play_sound_map (op->map, op->x, op->y, SOUND_OB_EVAPORATE);
2643 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s vibrates violently, then evaporates.", query_name (tmp)); 2597 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s vibrates violently, then evaporates.", query_name (tmp));
2598
2644 if (op->contr) 2599 if (op->contr)
2645 esrv_del_item (op->contr, tmp->count); 2600 esrv_del_item (op->contr, tmp->count);
2646 remove_ob (tmp); 2601
2647 free_object (tmp); 2602 tmp->destroy ();
2648 CLEAR_FLAG (op, FLAG_LIFESAVE); 2603 CLEAR_FLAG (op, FLAG_LIFESAVE);
2604
2649 if (op->stats.hp < 0) 2605 if (op->stats.hp < 0)
2650 op->stats.hp = op->stats.maxhp; 2606 op->stats.hp = op->stats.maxhp;
2607
2651 if (op->stats.food < 0) 2608 if (op->stats.food < 0)
2652 op->stats.food = 999; 2609 op->stats.food = 999;
2610
2653 fix_player (op); 2611 fix_player (op);
2654 return 1; 2612 return 1;
2655 } 2613 }
2614
2656 LOG (llevError, "Error: LIFESAVE set without applied object.\n"); 2615 LOG (llevError, "Error: LIFESAVE set without applied object.\n");
2657 CLEAR_FLAG (op, FLAG_LIFESAVE); 2616 CLEAR_FLAG (op, FLAG_LIFESAVE);
2658 enter_player_savebed (op); /* bring him home. */ 2617 enter_player_savebed (op); /* bring him home. */
2659 return 0; 2618 return 0;
2660} 2619}
2674 next = op->below; /* Make sure we have a good value, in case 2633 next = op->below; /* Make sure we have a good value, in case
2675 * we remove object 'op' 2634 * we remove object 'op'
2676 */ 2635 */
2677 if (QUERY_FLAG (op, FLAG_UNPAID)) 2636 if (QUERY_FLAG (op, FLAG_UNPAID))
2678 { 2637 {
2679 remove_ob (op); 2638 op->remove ();
2680 op->x = env->x; 2639 op->x = env->x;
2681 op->y = env->y; 2640 op->y = env->y;
2682 if (env->type == PLAYER) 2641 if (env->type == PLAYER)
2683 esrv_del_item (env->contr, op->count); 2642 esrv_del_item (env->contr, op->count);
2684 insert_ob_in_map (op, env->map, NULL, 0); 2643 insert_ob_in_map (op, env->map, NULL, 0);
2685 } 2644 }
2686 else if (op->inv) 2645 else if (op->inv)
2687 remove_unpaid_objects (op->inv, env); 2646 remove_unpaid_objects (op->inv, env);
2647
2688 op = next; 2648 op = next;
2689 } 2649 }
2690} 2650}
2691 2651
2692 2652
2707 strcpy (buf2, " R.I.P.\n\n"); 2667 strcpy (buf2, " R.I.P.\n\n");
2708 if (op->type == PLAYER) 2668 if (op->type == PLAYER)
2709 sprintf (buf, "%s the %s\n", &op->name, op->contr->title); 2669 sprintf (buf, "%s the %s\n", &op->name, op->contr->title);
2710 else 2670 else
2711 sprintf (buf, "%s\n", &op->name); 2671 sprintf (buf, "%s\n", &op->name);
2672
2712 strncat (buf2, " ", 20 - strlen (buf) / 2); 2673 strncat (buf2, " ", 20 - strlen (buf) / 2);
2713 strcat (buf2, buf); 2674 strcat (buf2, buf);
2714 if (op->type == PLAYER) 2675 if (op->type == PLAYER)
2715 sprintf (buf, "who was in level %d when killed\n", op->level); 2676 sprintf (buf, "who was in level %d when killed\n", op->level);
2716 else 2677 else
2717 sprintf (buf, "who was in level %d when died.\n\n", op->level); 2678 sprintf (buf, "who was in level %d when died.\n\n", op->level);
2679
2718 strncat (buf2, " ", 20 - strlen (buf) / 2); 2680 strncat (buf2, " ", 20 - strlen (buf) / 2);
2719 strcat (buf2, buf); 2681 strcat (buf2, buf);
2720 if (op->type == PLAYER) 2682 if (op->type == PLAYER)
2721 { 2683 {
2722 sprintf (buf, "by %s.\n\n", op->contr->killer); 2684 sprintf (buf, "by %s.\n\n", op->contr->killer);
2723 strncat (buf2, " ", 21 - strlen (buf) / 2); 2685 strncat (buf2, " ", 21 - strlen (buf) / 2);
2724 strcat (buf2, buf); 2686 strcat (buf2, buf);
2725 } 2687 }
2688
2726 strftime (buf, MAX_BUF, "%b %d %Y\n", localtime (&now)); 2689 strftime (buf, MAX_BUF, "%b %d %Y\n", localtime (&now));
2727 strncat (buf2, " ", 20 - strlen (buf) / 2); 2690 strncat (buf2, " ", 20 - strlen (buf) / 2);
2728 strcat (buf2, buf); 2691 strcat (buf2, buf);
2692
2729 return buf2; 2693 return buf2;
2730} 2694}
2731 2695
2732 2696
2733 2697
2952{ 2916{
2953 char buf[MAX_BUF]; 2917 char buf[MAX_BUF];
2954 int x, y; 2918 int x, y;
2955 2919
2956 //int i; 2920 //int i;
2957 mapstruct *map; /* this is for resurrection */ 2921 maptile *map; /* this is for resurrection */
2958 2922
2959 /* int z; 2923 /* int z;
2960 int num_stats_lose; 2924 int num_stats_lose;
2961 int lost_a_stat; 2925 int lost_a_stat;
2962 int lose_this_stat; 2926 int lose_this_stat;
2977 { 2941 {
2978 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "You have been defeated in combat!"); 2942 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "You have been defeated in combat!");
2979 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "Local medics have saved your life..."); 2943 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "Local medics have saved your life...");
2980 2944
2981 /* restore player */ 2945 /* restore player */
2982 at = find_archetype ("poisoning"); 2946 at = archetype::find ("poisoning");
2983 tmp = present_arch_in_ob (at, op); 2947 tmp = present_arch_in_ob (at, op);
2984 if (tmp) 2948 if (tmp)
2985 { 2949 {
2986 remove_ob (tmp); 2950 tmp->destroy ();
2987 free_object (tmp);
2988 new_draw_info (NDI_UNIQUE, 0, op, "Your body feels cleansed"); 2951 new_draw_info (NDI_UNIQUE, 0, op, "Your body feels cleansed");
2989 } 2952 }
2990 2953
2991 at = find_archetype ("confusion"); 2954 at = archetype::find ("confusion");
2992 tmp = present_arch_in_ob (at, op); 2955 tmp = present_arch_in_ob (at, op);
2993 if (tmp) 2956 if (tmp)
2994 { 2957 {
2995 remove_ob (tmp); 2958 tmp->destroy ();
2996 free_object (tmp);
2997 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); 2959 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer");
2998 } 2960 }
2999 2961
3000 cure_disease (op, 0); /* remove any disease */ 2962 cure_disease (op, 0); /* remove any disease */
3001 op->stats.hp = op->stats.maxhp; 2963 op->stats.hp = op->stats.maxhp;
3002 if (op->stats.food <= 0) 2964 if (op->stats.food <= 0)
3003 op->stats.food = 999; 2965 op->stats.food = 999;
3004 2966
3005 /* create a bodypart-trophy to make the winner happy */ 2967 /* create a bodypart-trophy to make the winner happy */
3006 tmp = arch_to_object (find_archetype ("finger")); 2968 tmp = arch_to_object (archetype::find ("finger"));
3007 if (tmp != NULL) 2969 if (tmp != NULL)
3008 { 2970 {
3009 sprintf (buf, "%s's finger", &op->name); 2971 sprintf (buf, "%s's finger", &op->name);
3010 tmp->name = buf; 2972 tmp->name = buf;
3011 sprintf (buf, " This finger has been cut off %s\n" 2973 sprintf (buf, " This finger has been cut off %s\n"
3108 lost_a_stat = 1; 3070 lost_a_stat = 1;
3109 } 3071 }
3110 else 3072 else
3111 { 3073 {
3112 /* deplete a stat */ 3074 /* deplete a stat */
3113 archetype *deparch = find_archetype ("depletion"); 3075 archetype *deparch = archetype::find ("depletion");
3114 object *dep; 3076 object *dep;
3115 3077
3116 dep = present_arch_in_ob (deparch, op); 3078 dep = present_arch_in_ob (deparch, op);
3117 if (!dep) 3079 if (!dep)
3118 { 3080 {
3178 /* determine_god() seems to not work sometimes... why is this? 3140 /* determine_god() seems to not work sometimes... why is this?
3179 Should I be using something else? GD */ 3141 Should I be using something else? GD */
3180 const char *god = determine_god (op); 3142 const char *god = determine_god (op);
3181 3143
3182 if (god && (strcmp (god, "none"))) 3144 if (god && (strcmp (god, "none")))
3183 new_draw_info_format (NDI_UNIQUE, 0, op, "For a brief " "moment you feel the holy presence of %s protecting" " you.", god); 3145 new_draw_info_format (NDI_UNIQUE, 0, op, "For a brief moment you feel the holy presence of %s protecting" " you.", god);
3184 else 3146 else
3185 new_draw_info (NDI_UNIQUE, 0, op, "For a brief moment you" " feel a holy presence protecting you."); 3147 new_draw_info (NDI_UNIQUE, 0, op, "For a brief moment you feel a holy presence protecting you.");
3186 } 3148 }
3149#else
3150 new_draw_info (NDI_UNIQUE, 0, op, "For a brief moment you" " feel a holy presence protecting you from losing yourself completely.");
3187#endif 3151#endif
3188 new_draw_info (NDI_UNIQUE, 0, op, "For a brief moment you" " feel a holy presence protecting you from losing yourself completely.");
3189 3152
3190 /* Put a gravestone up where the character 'almost' died. List the 3153 /* Put a gravestone up where the character 'almost' died. List the
3191 * exp loss on the stone. 3154 * exp loss on the stone.
3192 */ 3155 */
3193 tmp = arch_to_object (find_archetype ("gravestone")); 3156 tmp = arch_to_object (archetype::find ("gravestone"));
3194 sprintf (buf, "%s's gravestone", &op->name); 3157 sprintf (buf, "%s's gravestone", &op->name);
3195 tmp->name = buf; 3158 tmp->name = buf;
3196 sprintf (buf, "%s's gravestones", &op->name); 3159 sprintf (buf, "%s's gravestones", &op->name);
3197 tmp->name_pl = buf; 3160 tmp->name_pl = buf;
3198 sprintf (buf, "RIP\nHere rests the hero %s the %s,\n" "who was killed\n" "by %s.\n", &op->name, op->contr->title, op->contr->killer); 3161 sprintf (buf, "RIP\nHere rests the hero %s the %s,\n" "who was killed\n" "by %s.\n", &op->name, op->contr->title, op->contr->killer);
3199 tmp->msg = buf; 3162 tmp->msg = buf;
3200 tmp->x = op->x, tmp->y = op->y; 3163 tmp->x = op->x, tmp->y = op->y;
3201 insert_ob_in_map (tmp, op->map, NULL, 0); 3164 insert_ob_in_map (tmp, op->map, NULL, 0);
3202 3165
3203 /**************************************/ 3166 /**************************************/
3204 /* */ 3167 /* */
3205 /* Subtract the experience points, */ 3168 /* Subtract the experience points, */
3206 /* if we died cause of food, give us */ 3169 /* if we died cause of food, give us */
3207 /* food, and reset HP's... */ 3170 /* food, and reset HP's... */
3208 /* */ 3171 /* */
3209
3210 /**************************************/ 3172 /**************************************/
3211 3173
3212 /* remove any poisoning and confusion the character may be suffering. */ 3174 /* remove any poisoning and confusion the character may be suffering. */
3213 /* restore player */ 3175 /* restore player */
3214 at = find_archetype ("poisoning"); 3176 at = archetype::find ("poisoning");
3177 tmp = present_arch_in_ob (at, op);
3178
3179 if (tmp)
3180 {
3181 tmp->destroy ();
3182 new_draw_info (NDI_UNIQUE, 0, op, "Your body feels cleansed");
3183 }
3184
3185 at = archetype::find ("confusion");
3215 tmp = present_arch_in_ob (at, op); 3186 tmp = present_arch_in_ob (at, op);
3216 if (tmp) 3187 if (tmp)
3217 { 3188 {
3218 remove_ob (tmp); 3189 tmp->destroy ();
3219 free_object (tmp);
3220 new_draw_info (NDI_UNIQUE, 0, op, "Your body feels cleansed");
3221 }
3222
3223 at = find_archetype ("confusion");
3224 tmp = present_arch_in_ob (at, op);
3225 if (tmp)
3226 {
3227 remove_ob (tmp);
3228 free_object (tmp);
3229 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); 3190 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer");
3230 } 3191 }
3192
3231 cure_disease (op, 0); /* remove any disease */ 3193 cure_disease (op, 0); /* remove any disease */
3232 3194
3233 /*add_exp(op, (op->stats.exp * -0.20)); */ 3195 /*add_exp(op, (op->stats.exp * -0.20)); */
3234 apply_death_exp_penalty (op); 3196 apply_death_exp_penalty (op);
3235 if (op->stats.food < 100) 3197 if (op->stats.food < 100)
3245 */ 3207 */
3246 3208
3247 if (is_in_shop (op)) 3209 if (is_in_shop (op))
3248 remove_unpaid_objects (op->inv, op); 3210 remove_unpaid_objects (op->inv, op);
3249 3211
3250 /****************************************/ 3212 /****************************************/
3251 /* */ 3213 /* */
3252 /* Move player to his current respawn- */ 3214 /* Move player to his current respawn- */
3253 /* position (usually last savebed) */ 3215 /* position (usually last savebed) */
3254 /* */ 3216 /* */
3255
3256 /****************************************/ 3217 /****************************************/
3257 3218
3258 enter_player_savebed (op); 3219 enter_player_savebed (op);
3259 3220
3260 /* Save the player before inserting the force to reduce 3221 /* Save the player before inserting the force to reduce
3261 * chance of abuse. 3222 * chance of abuse.
3268 * spell effects. So first see if there is a spell effect 3229 * spell effects. So first see if there is a spell effect
3269 * on the space that might harm the player. 3230 * on the space that might harm the player.
3270 */ 3231 */
3271 will_kill_again = 0; 3232 will_kill_again = 0;
3272 for (tmp = get_map_ob (op->map, op->x, op->y); tmp; tmp = tmp->above) 3233 for (tmp = get_map_ob (op->map, op->x, op->y); tmp; tmp = tmp->above)
3273 {
3274 if (tmp->type == SPELL_EFFECT) 3234 if (tmp->type == SPELL_EFFECT)
3275 will_kill_again |= tmp->attacktype; 3235 will_kill_again |= tmp->attacktype;
3276 } 3236
3277 if (will_kill_again) 3237 if (will_kill_again)
3278 { 3238 {
3279 object *force; 3239 object *force;
3280 int at; 3240 int at;
3281 3241
3283 /* 50 ticks should be enough time for the spell to abate */ 3243 /* 50 ticks should be enough time for the spell to abate */
3284 force->speed = 0.1; 3244 force->speed = 0.1;
3285 force->speed_left = -5.0; 3245 force->speed_left = -5.0;
3286 SET_FLAG (force, FLAG_APPLIED); 3246 SET_FLAG (force, FLAG_APPLIED);
3287 for (at = 0; at < NROFATTACKS; at++) 3247 for (at = 0; at < NROFATTACKS; at++)
3288 {
3289 if (will_kill_again & (1 << at)) 3248 if (will_kill_again & (1 << at))
3290 force->resist[at] = 100; 3249 force->resist[at] = 100;
3291 } 3250
3292 insert_ob_in_ob (force, op); 3251 insert_ob_in_ob (force, op);
3293 fix_player (op); 3252 fix_player (op);
3294 3253
3295 } 3254 }
3296 3255
3306 op->contr->party = NULL; 3265 op->contr->party = NULL;
3307 if (settings.set_title == TRUE) 3266 if (settings.set_title == TRUE)
3308 op->contr->own_title[0] = '\0'; 3267 op->contr->own_title[0] = '\0';
3309 new_draw_info (NDI_UNIQUE | NDI_ALL, 0, NULL, buf); 3268 new_draw_info (NDI_UNIQUE | NDI_ALL, 0, NULL, buf);
3310 check_score (op); 3269 check_score (op);
3270
3311 if (op->contr->ranges[range_golem] != NULL) 3271 if (op->contr->ranges[range_golem])
3312 { 3272 {
3313 remove_friendly_object (op->contr->ranges[range_golem]); 3273 remove_friendly_object (op->contr->ranges[range_golem]);
3314 remove_ob (op->contr->ranges[range_golem]); 3274 op->contr->ranges[range_golem]->destroy ();
3315 free_object (op->contr->ranges[range_golem]);
3316 op->contr->ranges[range_golem] = NULL; 3275 op->contr->ranges[range_golem] = 0;
3317 op->contr->golem_count = 0;
3318 } 3276 }
3277
3319 loot_object (op); /* Remove some of the items for good */ 3278 loot_object (op); /* Remove some of the items for good */
3320 remove_ob (op); 3279 op->remove ();
3321 op->direction = 0; 3280 op->direction = 0;
3322 3281
3323 if (!QUERY_FLAG (op, FLAG_WAS_WIZ) && op->stats.exp) 3282 if (!QUERY_FLAG (op, FLAG_WAS_WIZ) && op->stats.exp)
3324 { 3283 {
3325 delete_character (op->name, 0); 3284 delete_character (op->name, 0);
3350 } 3309 }
3351 3310
3352 play_again (op); 3311 play_again (op);
3353 3312
3354 /* peterm: added to create a corpse at deathsite. */ 3313 /* peterm: added to create a corpse at deathsite. */
3355 tmp = arch_to_object (find_archetype ("corpse_pl")); 3314 tmp = arch_to_object (archetype::find ("corpse_pl"));
3356 sprintf (buf, "%s", &op->name); 3315 sprintf (buf, "%s", &op->name);
3357 tmp->name = tmp->name_pl = buf; 3316 tmp->name = tmp->name_pl = buf;
3358 tmp->level = op->level; 3317 tmp->level = op->level;
3359 tmp->x = x; 3318 tmp->x = x;
3360 tmp->y = y; 3319 tmp->y = y;
3378 for (tmp = op->inv; tmp != NULL; tmp = next) 3337 for (tmp = op->inv; tmp != NULL; tmp = next)
3379 { 3338 {
3380 next = tmp->below; 3339 next = tmp->below;
3381 if (tmp->type == EXPERIENCE || tmp->invisible) 3340 if (tmp->type == EXPERIENCE || tmp->invisible)
3382 continue; 3341 continue;
3383 remove_ob (tmp); 3342 tmp->remove ();
3384 tmp->x = op->x, tmp->y = op->y; 3343 tmp->x = op->x, tmp->y = op->y;
3385 if (tmp->type == CONTAINER) 3344 if (tmp->type == CONTAINER)
3386 { /* empty container to ground */ 3345 { /* empty container to ground */
3387 loot_object (tmp); 3346 loot_object (tmp);
3388 } 3347 }
3389 if (!QUERY_FLAG (tmp, FLAG_UNIQUE) && (QUERY_FLAG (tmp, FLAG_STARTEQUIP) || QUERY_FLAG (tmp, FLAG_NO_DROP) || !(RANDOM () % 3))) 3348 if (!QUERY_FLAG (tmp, FLAG_UNIQUE) && (QUERY_FLAG (tmp, FLAG_STARTEQUIP) || QUERY_FLAG (tmp, FLAG_NO_DROP) || !(RANDOM () % 3)))
3390 { 3349 {
3391 if (tmp->nrof > 1) 3350 if (tmp->nrof > 1)
3392 { 3351 {
3393 tmp2 = get_split_ob (tmp, 1 + RANDOM () % (tmp->nrof - 1)); 3352 tmp2 = get_split_ob (tmp, 1 + RANDOM () % (tmp->nrof - 1));
3394 free_object (tmp2); 3353 tmp2->destroy ();
3395 insert_ob_in_map (tmp, op->map, NULL, 0); 3354 insert_ob_in_map (tmp, op->map, NULL, 0);
3396 } 3355 }
3397 else 3356 else
3398 free_object (tmp); 3357 tmp->destroy ();
3399 } 3358 }
3400 else 3359 else
3401 insert_ob_in_map (tmp, op->map, NULL, 0); 3360 insert_ob_in_map (tmp, op->map, NULL, 0);
3402 } 3361 }
3403} 3362}
3468 if (op->type == PLAYER) 3427 if (op->type == PLAYER)
3469 new_draw_info_format (NDI_UNIQUE, 0, op, "You cast %s.", &spob->name); 3428 new_draw_info_format (NDI_UNIQUE, 0, op, "You cast %s.", &spob->name);
3470 3429
3471 cast_spell (op, throw_ob, dir, spob, NULL); 3430 cast_spell (op, throw_ob, dir, spob, NULL);
3472 3431
3473 if (!QUERY_FLAG (throw_ob, FLAG_REMOVED)) 3432 throw_ob->destroy ();
3474 remove_ob (throw_ob);
3475 free_object (throw_ob);
3476} 3433}
3477 3434
3478void 3435void
3479make_visible (object *op) 3436make_visible (object *op)
3480{ 3437{
3596int 3553int
3597stand_near_hostile (object *who) 3554stand_near_hostile (object *who)
3598{ 3555{
3599 object *tmp = NULL; 3556 object *tmp = NULL;
3600 int i, friendly = 0, player = 0, mflags; 3557 int i, friendly = 0, player = 0, mflags;
3601 mapstruct *m; 3558 maptile *m;
3602 sint16 x, y; 3559 sint16 x, y;
3603 3560
3604 if (!who) 3561 if (!who)
3605 return 0; 3562 return 0;
3606 3563
3687 3644
3688 /* only the viewable area the player sees is updated by LOS 3645 /* only the viewable area the player sees is updated by LOS
3689 * code, so we need to restrict ourselves to that range of values 3646 * code, so we need to restrict ourselves to that range of values
3690 * for any meaningful values. 3647 * for any meaningful values.
3691 */ 3648 */
3692 if (FABS (dx) <= (pl->contr->socket.mapx / 2) && 3649 if (FABS (dx) <= (pl->contr->socket->mapx / 2) &&
3693 FABS (dy) <= (pl->contr->socket.mapy / 2) && 3650 FABS (dy) <= (pl->contr->socket->mapy / 2) &&
3694 !pl->contr->blocked_los[dx + (pl->contr->socket.mapx / 2)][dy + (pl->contr->socket.mapy / 2)]) 3651 !pl->contr->blocked_los[dx + (pl->contr->socket->mapx / 2)][dy + (pl->contr->socket->mapy / 2)])
3695 return 1; 3652 return 1;
3696 op = op->more; 3653 op = op->more;
3697 } 3654 }
3698 return 0; 3655 return 0;
3699} 3656}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines