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.20 by root, Tue Sep 12 17:54:41 2006 UTC vs.
Revision 1.51 by root, Thu Dec 21 06:12:37 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 strncpy (p->title, op->arch->clone.name, sizeof (p->title) - 1); 269 assign (p->title, op->arch->clone.name);
285 p->title[sizeof (p->title) - 1] = '\0';
286 op->race = op->arch->clone.race; 270 op->race = op->arch->clone.race;
287 271
288 CLEAR_FLAG (op, FLAG_READY_SKILL); 272 CLEAR_FLAG (op, FLAG_READY_SKILL);
289 273
290 /* we need to clear these to -1 and not zero - otherwise, 274 /* we need to clear these to -1 and not zero - otherwise,
295 for (i = 0; i < NUM_SKILLS; i++) 279 for (i = 0; i < NUM_SKILLS; i++)
296 { 280 {
297 p->last_skill_exp[i] = -1; 281 p->last_skill_exp[i] = -1;
298 p->last_skill_ob[i] = NULL; 282 p->last_skill_ob[i] = NULL;
299 } 283 }
284
300 for (i = 0; i < NROFATTACKS; i++) 285 for (i = 0; i < NROFATTACKS; i++)
301 {
302 p->last_resist[i] = -1; 286 p->last_resist[i] = -1;
303 } 287
304 p->last_stats.exp = -1; 288 p->last_stats.exp = -1;
305 p->last_weight = (uint32) - 1; 289 p->last_weight = (uint32) - 1;
306 290
307 p->socket.update_look = 0; 291 p->socket->update_look = 0;
308 p->socket.look_position = 0; 292 p->socket->look_position = 0;
293
309 return p; 294 return p;
310} 295}
311 296
312/* This loads the first map an puts the player on it. */ 297/* This loads the first map an puts the player on it. */
313static void 298static void
314set_first_map (object *op) 299set_first_map (object *op)
315{ 300{
316 strcpy (op->contr->maplevel, first_map_path); 301 strcpy (op->contr->maplevel, first_map_path);
317 op->x = -1; 302 op->x = -1;
318 op->y = -1; 303 op->y = -1;
319 enter_exit (op, NULL); 304 enter_exit (op, 0);
320} 305}
321 306
322/* Tries to add player on the connection passwd in ns. 307/* Tries to add player on the connection passwd in ns.
323 * 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
324 * mode. 309 * mode.
325 */ 310 */
326 311
327int 312int
328add_player (NewSocket * ns) 313add_player (client *ns)
329{ 314{
330 player *p; 315 player *p = new player;
331 316
332 p = get_player (NULL);
333 p->socket = *ns; 317 p->socket = ns;
334 p->socket.faces_sent = (uint8 *) malloc (p->socket.faces_sent_len * sizeof (*p->socket.faces_sent)); 318 ns->pl = p;
335 if (p->socket.faces_sent == NULL) 319
336 fatal (OUT_OF_MEMORY); 320 p->next = first_player;
337 memcpy (p->socket.faces_sent, ns->faces_sent, p->socket.faces_sent_len * sizeof (*p->socket.faces_sent)); 321 first_player = p;
338 /* Needed because the socket we just copied over needs to be cleared. 322
339 * Note that this can result in a client reset if there is partial data 323 p = get_player (p);
340 * on the uncoming socket. 324
341 */
342 p->socket.inbuf.len = 0;
343 set_first_map (p->ob); 325 set_first_map (p->ob);
344 326
345 CLEAR_FLAG (p->ob, FLAG_FRIENDLY); 327 CLEAR_FLAG (p->ob, FLAG_FRIENDLY);
346 add_friendly_object (p->ob); 328 add_friendly_object (p->ob);
347 send_rules (p->ob); 329 send_rules (p->ob);
348 send_news (p->ob); 330 send_news (p->ob);
349 display_motd (p->ob); 331 display_motd (p->ob);
332
350 get_name (p->ob); 333 get_name (p->ob);
334
351 return 0; 335 return 0;
352} 336}
353 337
354/* 338/*
355 * get_player_archetype() return next player archetype from archetype 339 * get_player_archetype() return next player archetype from archetype
365 { 349 {
366 if (at == NULL || at->next == NULL) 350 if (at == NULL || at->next == NULL)
367 at = first_archetype; 351 at = first_archetype;
368 else 352 else
369 at = at->next; 353 at = at->next;
354
370 if (at->clone.type == PLAYER) 355 if (at->clone.type == PLAYER)
371 return at; 356 return at;
357
372 if (at == start) 358 if (at == start)
373 { 359 {
374 LOG (llevError, "No Player archetypes\n"); 360 LOG (llevError, "No Player archetypes\n");
375 exit (-1); 361 exit (-1);
376 } 362 }
377 } 363 }
378} 364}
379
380 365
381object * 366object *
382get_nearest_player (object *mon) 367get_nearest_player (object *mon)
383{ 368{
384 object *op = NULL; 369 object *op = NULL;
490path_to_player (object *mon, object *pl, unsigned mindiff) 475path_to_player (object *mon, object *pl, unsigned mindiff)
491{ 476{
492 rv_vector rv; 477 rv_vector rv;
493 sint16 x, y; 478 sint16 x, y;
494 int lastx, lasty, dir, i, diff, firstdir = 0, lastdir, max = MAX_SPACES, mflags, blocked; 479 int lastx, lasty, dir, i, diff, firstdir = 0, lastdir, max = MAX_SPACES, mflags, blocked;
495 mapstruct *m, *lastmap; 480 maptile *m, *lastmap;
496 481
497 get_rangevector (mon, pl, &rv, 0); 482 get_rangevector (mon, pl, &rv, 0);
498 483
499 if (rv.distance < mindiff) 484 if (rv.distance < mindiff)
500 return 0; 485 return 0;
644 (op->type == ARMOUR || op->type == BOOTS || 629 (op->type == ARMOUR || op->type == BOOTS ||
645 op->type == CLOAK || op->type == HELMET || 630 op->type == CLOAK || op->type == HELMET ||
646 op->type == SHIELD || op->type == GLOVES || 631 op->type == SHIELD || op->type == GLOVES ||
647 op->type == BRACERS || op->type == GIRDLE)) || (!QUERY_FLAG (pl, FLAG_USE_WEAPON) && op->type == WEAPON)) 632 op->type == BRACERS || op->type == GIRDLE)) || (!QUERY_FLAG (pl, FLAG_USE_WEAPON) && op->type == WEAPON))
648 { 633 {
649 remove_ob (op); 634 op->destroy ();
650 free_object (op);
651 continue; 635 continue;
652 } 636 }
653 } 637 }
654 638
655 /* This really needs to be better - we should really give 639 /* This really needs to be better - we should really give
666 if (tmp->type == op->type && tmp->name == op->name) 650 if (tmp->type == op->type && tmp->name == op->name)
667 break; 651 break;
668 652
669 if (tmp) 653 if (tmp)
670 { 654 {
671 remove_ob (op); 655 op->destroy ();
672 free_object (op);
673 LOG (llevError, "give_initial_items: Removing duplicate object %s\n", &tmp->name); 656 LOG (llevError, "give_initial_items: Removing duplicate object %s\n", &tmp->name);
674 continue; 657 continue;
675 } 658 }
659
676 if (op->nrof > 1) 660 if (op->nrof > 1)
677 op->nrof = 1; 661 op->nrof = 1;
678 } 662 }
679 663
680 if (op->type == SPELLBOOK && op->inv) 664 if (op->type == SPELLBOOK && op->inv)
692 CLEAR_FLAG (op, FLAG_CURSED); 676 CLEAR_FLAG (op, FLAG_CURSED);
693 CLEAR_FLAG (op, FLAG_DAMNED); 677 CLEAR_FLAG (op, FLAG_DAMNED);
694 } 678 }
695 if (op->type == SPELL) 679 if (op->type == SPELL)
696 { 680 {
697 remove_ob (op); 681 op->destroy ();
698 free_object (op);
699 continue; 682 continue;
700 } 683 }
701 else if (op->type == SKILL) 684 else if (op->type == SKILL)
702 { 685 {
703 SET_FLAG (op, FLAG_CAN_USE_SKILL); 686 SET_FLAG (op, FLAG_CAN_USE_SKILL);
716void 699void
717get_name (object *op) 700get_name (object *op)
718{ 701{
719 op->contr->write_buf[0] = '\0'; 702 op->contr->write_buf[0] = '\0';
720 op->contr->state = ST_GET_NAME; 703 op->contr->state = ST_GET_NAME;
721 send_query (&op->contr->socket, 0, "What is your name?\n:"); 704 send_query (op->contr->socket, 0, "What is your name?\n:");
722} 705}
723 706
724void 707void
725get_password (object *op) 708get_password (object *op)
726{ 709{
727 op->contr->write_buf[0] = '\0'; 710 op->contr->write_buf[0] = '\0';
728 op->contr->state = ST_GET_PASSWORD; 711 op->contr->state = ST_GET_PASSWORD;
729 send_query (&op->contr->socket, CS_QUERY_HIDEINPUT, "What is your password?\n:"); 712 send_query (op->contr->socket, CS_QUERY_HIDEINPUT, "What is your password?\n:");
730} 713}
731 714
732void 715void
733play_again (object *op) 716play_again (object *op)
734{ 717{
735 op->contr->state = ST_PLAY_AGAIN; 718 op->contr->state = ST_PLAY_AGAIN;
736 op->chosen_skill = NULL; 719 op->chosen_skill = NULL;
737 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, "Do you want to play again (a/q)?"); 720 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "Do you want to play again (a/q)?");
738 /* a bit of a hack, but there are various places early in th 721 /* a bit of a hack, but there are various places early in th
739 * player creation process that a user can quit (eg, roll 722 * player creation process that a user can quit (eg, roll
740 * stats) that isn't removing the player. Taking a quick 723 * stats) that isn't removing the player. Taking a quick
741 * look, there are many places that call play_again without 724 * look, there are many places that call play_again without
742 * removing the player - it probably makes more sense 725 * removing the player - it probably makes more sense
743 * to leave it to play_again to remove the object in all 726 * to leave it to play_again to remove the object in all
744 * cases. 727 * cases.
745 */ 728 */
746 if (!QUERY_FLAG (op, FLAG_REMOVED)) 729 if (!QUERY_FLAG (op, FLAG_REMOVED))
747 remove_ob (op); 730 op->remove ();
731
748 /* Need to set this to null - otherwise, it could point to garbage, 732 /* Need to set this to null - otherwise, it could point to garbage,
749 * and draw() doesn't check to see if the player is removed, only if 733 * and draw() doesn't check to see if the player is removed, only if
750 * the map is null or not swapped out. 734 * the map is null or not swapped out.
751 */ 735 */
752 op->map = NULL; 736 op->map = NULL;
766 player *pl = op->contr; 750 player *pl = op->contr;
767 shstr name = op->name; 751 shstr name = op->name;
768 752
769 op->contr = 0; 753 op->contr = 0;
770 op->type = 0; 754 op->type = 0;
771 op->free (1); 755 op->destroy (1);
772 pl = get_player (pl); 756 pl = get_player (pl);
773 op = pl->ob; 757 op = pl->ob;
774 add_friendly_object (op); 758 add_friendly_object (op);
775 op->contr->password[0] = '~'; 759 op->contr->password[0] = '~';
776 op->name = op->name_pl = 0; 760 op->name = op->name_pl = 0;
791confirm_password (object *op) 775confirm_password (object *op)
792{ 776{
793 777
794 op->contr->write_buf[0] = '\0'; 778 op->contr->write_buf[0] = '\0';
795 op->contr->state = ST_CONFIRM_PASSWORD; 779 op->contr->state = ST_CONFIRM_PASSWORD;
796 send_query (&op->contr->socket, CS_QUERY_HIDEINPUT, "Please type your password again.\n:"); 780 send_query (op->contr->socket, CS_QUERY_HIDEINPUT, "Please type your password again.\n:");
797} 781}
798 782
799void 783void
800get_party_password (object *op, partylist *party) 784get_party_password (object *op, partylist *party)
801{ 785{
805 return; 789 return;
806 } 790 }
807 op->contr->write_buf[0] = '\0'; 791 op->contr->write_buf[0] = '\0';
808 op->contr->state = ST_GET_PARTY_PASSWORD; 792 op->contr->state = ST_GET_PARTY_PASSWORD;
809 op->contr->party_to_join = party; 793 op->contr->party_to_join = party;
810 send_query (&op->contr->socket, CS_QUERY_HIDEINPUT, "What is the password?\n:"); 794 send_query (op->contr->socket, CS_QUERY_HIDEINPUT, "What is the password?\n:");
811} 795}
812 796
813 797
814/* This rolls four 1-6 rolls and sums the best 3 of the 4. */ 798/* This rolls four 1-6 rolls and sums the best 3 of the 4. */
815int 799int
912 896
913void 897void
914Roll_Again (object *op) 898Roll_Again (object *op)
915{ 899{
916 esrv_new_player (op->contr, 0); 900 esrv_new_player (op->contr, 0);
917 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, 901 send_query (op->contr->socket, CS_QUERY_SINGLECHAR,
918 "[y] to roll new stats [n] to use stats\n[1-7] [1-7] to swap stats.\nRoll again (y/n/1-7)? "); 902 "[y] to roll new stats [n] to use stats\n[1-7] [1-7] to swap stats.\nRoll again (y/n/1-7)? ");
919} 903}
920 904
921void 905void
922Swap_Stat (object *op, int Swap_Second) 906Swap_Stat (object *op, int Swap_Second)
989 new_draw_info (NDI_UNIQUE, 0, op, buf); 973 new_draw_info (NDI_UNIQUE, 0, op, buf);
990 } 974 }
991 else 975 else
992 Swap_Stat (op, stat_trans[keynum]); 976 Swap_Stat (op, stat_trans[keynum]);
993 977
994 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, ""); 978 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "");
995 return 1; 979 return 1;
996 } 980 }
997 switch (key) 981 switch (key)
998 { 982 {
999 case 'n': 983 case 'n':
1013 enter_exit (op, NULL); 997 enter_exit (op, NULL);
1014#endif 998#endif
1015 SET_ANIMATION (op, 2); /* So player faces south */ 999 SET_ANIMATION (op, 2); /* So player faces south */
1016 /* Enter exit adds a player otherwise */ 1000 /* Enter exit adds a player otherwise */
1017 add_statbonus (op); 1001 add_statbonus (op);
1018 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, 1002 send_query (op->contr->socket, CS_QUERY_SINGLECHAR,
1019 "Now choose a character.\nPress any key to change outlook.\nPress `d' when you're pleased.\n"); 1003 "Now choose a character.\nPress any key to change outlook.\nPress `d' when you're pleased.\n");
1020 op->contr->state = ST_CHANGE_CLASS; 1004 op->contr->state = ST_CHANGE_CLASS;
1021 if (op->msg) 1005 if (op->msg)
1022 new_draw_info (NDI_BLUE, 0, op, op->msg); 1006 new_draw_info (NDI_BLUE, 0, op, op->msg);
1023 return 0; 1007 return 0;
1024 } 1008 }
1025 case 'y': 1009 case 'y':
1026 case 'Y': 1010 case 'Y':
1027 roll_stats (op); 1011 roll_stats (op);
1028 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, ""); 1012 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "");
1029 return 1; 1013 return 1;
1030 1014
1031 case 'q': 1015 case 'q':
1032 case 'Q': 1016 case 'Q':
1033 play_again (op); 1017 play_again (op);
1034 return 1; 1018 return 1;
1035 1019
1036 default: 1020 default:
1037 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, "Yes, No, Quit or 1-6. Roll again?"); 1021 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "Yes, No, Quit or 1-6. Roll again?");
1038 return 0; 1022 return 0;
1039 } 1023 }
1040 return 0; 1024 return 0;
1041} 1025}
1042 1026
1052{ 1036{
1053 int tmp_loop; 1037 int tmp_loop;
1054 1038
1055 if (key == 'q' || key == 'Q') 1039 if (key == 'q' || key == 'Q')
1056 { 1040 {
1057 remove_ob (op); 1041 op->remove ();
1058 play_again (op); 1042 play_again (op);
1059 return 0; 1043 return 0;
1060 } 1044 }
1061 if (key == 'd' || key == 'D') 1045 if (key == 'd' || key == 'D')
1062 { 1046 {
1063 char buf[MAX_BUF]; 1047 char buf[MAX_BUF];
1064 1048
1065 /* this must before then initial items are given */ 1049 /* this must before then initial items are given */
1066 esrv_new_player (op->contr, op->weight + op->carrying); 1050 esrv_new_player (op->contr, op->weight + op->carrying);
1051
1067 create_treasure (find_treasurelist ("starting_wealth"), op, 0, 0, 0); 1052 treasurelist *tl = find_treasurelist ("starting_wealth");
1053 if (tl)
1054 create_treasure (tl, op, 0, 0, 0);
1068 1055
1069 INVOKE_PLAYER (BIRTH, op->contr); 1056 INVOKE_PLAYER (BIRTH, op->contr);
1070 INVOKE_PLAYER (LOGIN, op->contr); 1057 INVOKE_PLAYER (LOGIN, op->contr);
1071 1058
1072 op->contr->state = ST_PLAYING; 1059 op->contr->state = ST_PLAYING;
1097 { 1084 {
1098 object *tmp; 1085 object *tmp;
1099 char mapname[MAX_BUF]; 1086 char mapname[MAX_BUF];
1100 1087
1101 snprintf (mapname, MAX_BUF - 1, "%s/%s", first_map_ext_path, &op->arch->name); 1088 snprintf (mapname, MAX_BUF - 1, "%s/%s", first_map_ext_path, &op->arch->name);
1102 tmp = get_object (); 1089 tmp = object::create ();
1103 EXIT_PATH (tmp) = mapname; 1090 EXIT_PATH (tmp) = mapname;
1104 EXIT_X (tmp) = op->x; 1091 EXIT_X (tmp) = op->x;
1105 EXIT_Y (tmp) = op->y; 1092 EXIT_Y (tmp) = op->y;
1106 enter_exit (op, tmp); /* we don't really care if it succeeded; 1093 enter_exit (op, tmp); /* we don't really care if it succeeded;
1107 * if the map isn't there, then stay on the 1094 * if the map isn't there, then stay on the
1108 * default initial map */ 1095 * default initial map */
1109 free_object (tmp); 1096 tmp->destroy ();
1110 } 1097 }
1111 else 1098 else
1112 {
1113 LOG (llevDebug, "first_map_ext_path not set\n"); 1099 LOG (llevDebug, "first_map_ext_path not set\n");
1114 } 1100
1115 return 0; 1101 return 0;
1116 } 1102 }
1117 1103
1118 /* Following actually changes the race - this is the default command 1104 /* Following actually changes the race - this is the default command
1119 * if we don't match with one of the options above. 1105 * if we don't match with one of the options above.
1124 { 1110 {
1125 shstr name = op->name; 1111 shstr name = op->name;
1126 int x = op->x, y = op->y; 1112 int x = op->x, y = op->y;
1127 1113
1128 remove_statbonus (op); 1114 remove_statbonus (op);
1129 remove_ob (op); 1115 op->remove ();
1130 op->arch = get_player_archetype (op->arch); 1116 op->arch = get_player_archetype (op->arch);
1131 copy_object (&op->arch->clone, op); 1117 op->arch->clone.copy_to (op);
1132 op->instantiate (); 1118 op->instantiate ();
1133 op->stats = op->contr->orig_stats; 1119 op->stats = op->contr->orig_stats;
1134 op->name = op->name_pl = name; 1120 op->name = op->name_pl = name;
1135 op->x = x; 1121 op->x = x;
1136 op->y = y; 1122 op->y = y;
1137 SET_ANIMATION (op, 2); /* So player faces south */ 1123 SET_ANIMATION (op, 2); /* So player faces south */
1138 insert_ob_in_map (op, op->map, op, 0); 1124 insert_ob_in_map (op, op->map, op, 0);
1139 strncpy (op->contr->title, op->arch->clone.name, sizeof (op->contr->title) - 1); 1125 assign (op->contr->title, op->arch->clone.name);
1140 op->contr->title[sizeof (op->contr->title) - 1] = '\0';
1141 add_statbonus (op); 1126 add_statbonus (op);
1142 tmp_loop = allowed_class (op); 1127 tmp_loop = allowed_class (op);
1143 } 1128 }
1144 1129
1145 update_object (op, UP_OBJ_FACE); 1130 update_object (op, UP_OBJ_FACE);
1146 esrv_update_item (UPD_FACE, op, op); 1131 esrv_update_item (UPD_FACE, op, op);
1147 fix_player (op); 1132 fix_player (op);
1148 op->stats.hp = op->stats.maxhp; 1133 op->stats.hp = op->stats.maxhp;
1149 op->stats.sp = op->stats.maxsp; 1134 op->stats.sp = op->stats.maxsp;
1150 op->stats.grace = 0; 1135 op->stats.grace = 0;
1136
1151 if (op->msg) 1137 if (op->msg)
1152 new_draw_info (NDI_BLUE, 0, op, op->msg); 1138 new_draw_info (NDI_BLUE, 0, op, op->msg);
1139
1153 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, "Press any key for the next race.\nPress `d' to play this race.\n"); 1140 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; 1141 return 0;
1155} 1142}
1156 1143
1157int 1144int
1158key_confirm_quit (object *op, char key) 1145key_confirm_quit (object *op, char key)
1180 if (settings.set_title == TRUE) 1167 if (settings.set_title == TRUE)
1181 op->contr->own_title[0] = '\0'; 1168 op->contr->own_title[0] = '\0';
1182 1169
1183 if (!QUERY_FLAG (op, FLAG_WAS_WIZ)) 1170 if (!QUERY_FLAG (op, FLAG_WAS_WIZ))
1184 { 1171 {
1185 mapstruct *mp, *next; 1172 maptile *mp, *next;
1186 1173
1187 /* We need to hunt for any per player unique maps in memory and 1174 /* 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, 1175 * 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 1176 * so that players named 'Ab' won't match against players 'Abe' pathname
1190 */ 1177 */
1238 { 1225 {
1239 op->enemy = NULL; 1226 op->enemy = NULL;
1240 CLEAR_FLAG (op, FLAG_SCARED); 1227 CLEAR_FLAG (op, FLAG_SCARED);
1241 return; 1228 return;
1242 } 1229 }
1230
1243 get_rangevector (op, op->enemy, &rv, 0); 1231 get_rangevector (op, op->enemy, &rv, 0);
1244 1232
1245 dir = absdir (4 + rv.direction); 1233 dir = absdir (4 + rv.direction);
1246 for (diff = 0; diff < 3; diff++) 1234 for (diff = 0; diff < 3; diff++)
1247 { 1235 {
1248 int m = 1 - (RANDOM () & 2); 1236 int m = 1 - (RANDOM () & 2);
1249 1237
1250 if (move_ob (op, absdir (dir + diff * m), op) || (diff == 0 && move_ob (op, absdir (dir - diff * m), op))) 1238 if (move_ob (op, absdir (dir + diff * m), op) || (diff == 0 && move_ob (op, absdir (dir - diff * m), op)))
1251 {
1252 return; 1239 return;
1253 }
1254 } 1240 }
1241
1255 /* Cornered, get rid of scared */ 1242 /* Cornered, get rid of scared */
1256 CLEAR_FLAG (op, FLAG_SCARED); 1243 CLEAR_FLAG (op, FLAG_SCARED);
1257 op->enemy = NULL; 1244 op->enemy = NULL;
1258} 1245}
1259 1246
1264 */ 1251 */
1265int 1252int
1266check_pick (object *op) 1253check_pick (object *op)
1267{ 1254{
1268 object *tmp, *next; 1255 object *tmp, *next;
1269 tag_t next_tag = 0, op_tag;
1270 int stop = 0; 1256 int stop = 0;
1271 int j, k, wvratio; 1257 int j, k, wvratio;
1272 char putstring[128], tmpstr[16]; 1258 char putstring[128], tmpstr[16];
1273 1259
1274
1275 /* if you're flying, you cna't pick up anything */ 1260 /* if you're flying, you cna't pick up anything */
1276 if (op->move_type & MOVE_FLYING) 1261 if (op->move_type & MOVE_FLYING)
1277 return 1; 1262 return 1;
1278 1263
1279 op_tag = op->count;
1280
1281 next = op->below; 1264 next = op->below;
1282 if (next)
1283 next_tag = next->count;
1284 1265
1285 /* loop while there are items on the floor that are not marked as 1266 /* loop while there are items on the floor that are not marked as
1286 * destroyed */ 1267 * destroyed */
1287 while (next && !was_destroyed (next, next_tag)) 1268 while (next && !next->destroyed ())
1288 { 1269 {
1289 tmp = next; 1270 tmp = next;
1290 next = tmp->below; 1271 next = tmp->below;
1291 if (next)
1292 next_tag = next->count;
1293 1272
1294 if (was_destroyed (op, op_tag)) 1273 if (op->destroyed ())
1295 return 0; 1274 return 0;
1296 1275
1297 if (!can_pick (op, tmp)) 1276 if (!can_pick (op, tmp))
1298 continue; 1277 continue;
1299 1278
1431 /* question: don't pick up known-poisonous stuff? */ 1410 /* question: don't pick up known-poisonous stuff? */
1432 if (op->contr->mode & PU_FOOD) 1411 if (op->contr->mode & PU_FOOD)
1433 if (tmp->type == FOOD) 1412 if (tmp->type == FOOD)
1434 { 1413 {
1435 pick_up (op, tmp); 1414 pick_up (op, tmp);
1436 if (0)
1437 fprintf (stderr, "FOOD\n");
1438 continue; 1415 continue;
1439 } 1416 }
1417
1440 if (op->contr->mode & PU_DRINK) 1418 if (op->contr->mode & PU_DRINK)
1441 if (tmp->type == DRINK || (tmp->type == POISON && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED))) 1419 if (tmp->type == DRINK || (tmp->type == POISON && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED)))
1442 { 1420 {
1443 pick_up (op, tmp); 1421 pick_up (op, tmp);
1444 if (0)
1445 fprintf (stderr, "DRINK\n");
1446 continue; 1422 continue;
1447 } 1423 }
1448 1424
1449 if (op->contr->mode & PU_POTION) 1425 if (op->contr->mode & PU_POTION)
1450 if (tmp->type == POTION) 1426 if (tmp->type == POTION)
1451 { 1427 {
1452 pick_up (op, tmp); 1428 pick_up (op, tmp);
1453 if (0)
1454 fprintf (stderr, "POTION\n");
1455 continue; 1429 continue;
1456 } 1430 }
1457 1431
1458 /* spellbooks, skillscrolls and normal books/scrolls */ 1432 /* spellbooks, skillscrolls and normal books/scrolls */
1459 if (op->contr->mode & PU_SPELLBOOK) 1433 if (op->contr->mode & PU_SPELLBOOK)
1460 if (tmp->type == SPELLBOOK) 1434 if (tmp->type == SPELLBOOK)
1461 { 1435 {
1462 pick_up (op, tmp); 1436 pick_up (op, tmp);
1463 if (0)
1464 fprintf (stderr, "SPELLBOOK\n");
1465 continue; 1437 continue;
1466 } 1438 }
1439
1467 if (op->contr->mode & PU_SKILLSCROLL) 1440 if (op->contr->mode & PU_SKILLSCROLL)
1468 if (tmp->type == SKILLSCROLL) 1441 if (tmp->type == SKILLSCROLL)
1469 { 1442 {
1470 pick_up (op, tmp); 1443 pick_up (op, tmp);
1471 if (0)
1472 fprintf (stderr, "SKILLSCROLL\n");
1473 continue; 1444 continue;
1474 } 1445 }
1446
1475 if (op->contr->mode & PU_READABLES) 1447 if (op->contr->mode & PU_READABLES)
1476 if (tmp->type == BOOK || tmp->type == SCROLL) 1448 if (tmp->type == BOOK || tmp->type == SCROLL)
1477 { 1449 {
1478 pick_up (op, tmp); 1450 pick_up (op, tmp);
1479 if (0)
1480 fprintf (stderr, "READABLES\n");
1481 continue; 1451 continue;
1482 } 1452 }
1483 1453
1484 /* wands/staves/rods/horns */ 1454 /* wands/staves/rods/horns */
1485 if (op->contr->mode & PU_MAGIC_DEVICE) 1455 if (op->contr->mode & PU_MAGIC_DEVICE)
1486 if (tmp->type == WAND || tmp->type == ROD || tmp->type == HORN) 1456 if (tmp->type == WAND || tmp->type == ROD || tmp->type == HORN)
1487 { 1457 {
1488 pick_up (op, tmp); 1458 pick_up (op, tmp);
1489 if (0)
1490 fprintf (stderr, "MAGIC_DEVICE\n");
1491 continue; 1459 continue;
1492 } 1460 }
1493 1461
1494 /* pick up all magical items */ 1462 /* pick up all magical items */
1495 if (op->contr->mode & PU_MAGICAL) 1463 if (op->contr->mode & PU_MAGICAL)
1496 if (QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED)) 1464 if (QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED))
1497 { 1465 {
1498 pick_up (op, tmp); 1466 pick_up (op, tmp);
1499 if (0)
1500 fprintf (stderr, "MAGICAL\n");
1501 continue; 1467 continue;
1502 } 1468 }
1503 1469
1504 if (op->contr->mode & PU_VALUABLES) 1470 if (op->contr->mode & PU_VALUABLES)
1505 { 1471 {
1506 if (tmp->type == MONEY || tmp->type == GEM) 1472 if (tmp->type == MONEY || tmp->type == GEM)
1507 { 1473 {
1508 pick_up (op, tmp); 1474 pick_up (op, tmp);
1509 if (0)
1510 fprintf (stderr, "MONEY/GEM\n");
1511 continue; 1475 continue;
1512 } 1476 }
1513 } 1477 }
1514 1478
1515 /* rings & amulets - talismans seems to be typed AMULET */ 1479 /* rings & amulets - talismans seems to be typed AMULET */
1516 if (op->contr->mode & PU_JEWELS) 1480 if (op->contr->mode & PU_JEWELS)
1517 if (tmp->type == RING || tmp->type == AMULET) 1481 if (tmp->type == RING || tmp->type == AMULET)
1518 { 1482 {
1519 pick_up (op, tmp); 1483 pick_up (op, tmp);
1484 continue;
1520 if (0) 1485 }
1521 fprintf (stderr, "JEWELS\n"); 1486
1487 /* we don't forget dragon food */
1488 if (op->contr->mode & PU_FLESH)
1489 if (tmp->type == FLESH)
1490 {
1491 pick_up (op, tmp);
1522 continue; 1492 continue;
1523 } 1493 }
1524 1494
1525 /* bows and arrows. Bows are good for selling! */ 1495 /* bows and arrows. Bows are good for selling! */
1526 if (op->contr->mode & PU_BOW) 1496 if (op->contr->mode & PU_BOW)
1527 if (tmp->type == BOW) 1497 if (tmp->type == BOW)
1528 { 1498 {
1529 pick_up (op, tmp); 1499 pick_up (op, tmp);
1530 if (0)
1531 fprintf (stderr, "BOW\n");
1532 continue; 1500 continue;
1533 } 1501 }
1502
1534 if (op->contr->mode & PU_ARROW) 1503 if (op->contr->mode & PU_ARROW)
1535 if (tmp->type == ARROW) 1504 if (tmp->type == ARROW)
1536 { 1505 {
1537 pick_up (op, tmp); 1506 pick_up (op, tmp);
1538 if (0)
1539 fprintf (stderr, "ARROW\n");
1540 continue; 1507 continue;
1541 } 1508 }
1542 1509
1543 /* all kinds of armor etc. */ 1510 /* all kinds of armor etc. */
1544 if (op->contr->mode & PU_ARMOUR) 1511 if (op->contr->mode & PU_ARMOUR)
1545 if (tmp->type == ARMOUR) 1512 if (tmp->type == ARMOUR)
1546 { 1513 {
1547 pick_up (op, tmp); 1514 pick_up (op, tmp);
1548 if (0)
1549 fprintf (stderr, "ARMOUR\n");
1550 continue; 1515 continue;
1551 } 1516 }
1517
1552 if (op->contr->mode & PU_HELMET) 1518 if (op->contr->mode & PU_HELMET)
1553 if (tmp->type == HELMET) 1519 if (tmp->type == HELMET)
1554 { 1520 {
1555 pick_up (op, tmp); 1521 pick_up (op, tmp);
1556 if (0)
1557 fprintf (stderr, "HELMET\n");
1558 continue; 1522 continue;
1559 } 1523 }
1524
1560 if (op->contr->mode & PU_SHIELD) 1525 if (op->contr->mode & PU_SHIELD)
1561 if (tmp->type == SHIELD) 1526 if (tmp->type == SHIELD)
1562 { 1527 {
1563 pick_up (op, tmp); 1528 pick_up (op, tmp);
1564 if (0)
1565 fprintf (stderr, "SHIELD\n");
1566 continue; 1529 continue;
1567 } 1530 }
1531
1568 if (op->contr->mode & PU_BOOTS) 1532 if (op->contr->mode & PU_BOOTS)
1569 if (tmp->type == BOOTS) 1533 if (tmp->type == BOOTS)
1570 { 1534 {
1571 pick_up (op, tmp); 1535 pick_up (op, tmp);
1572 if (0)
1573 fprintf (stderr, "BOOTS\n");
1574 continue; 1536 continue;
1575 } 1537 }
1538
1576 if (op->contr->mode & PU_GLOVES) 1539 if (op->contr->mode & PU_GLOVES)
1577 if (tmp->type == GLOVES) 1540 if (tmp->type == GLOVES)
1578 { 1541 {
1579 pick_up (op, tmp); 1542 pick_up (op, tmp);
1580 if (0)
1581 fprintf (stderr, "GLOVES\n");
1582 continue; 1543 continue;
1583 } 1544 }
1545
1584 if (op->contr->mode & PU_CLOAK) 1546 if (op->contr->mode & PU_CLOAK)
1585 if (tmp->type == CLOAK) 1547 if (tmp->type == CLOAK)
1586 { 1548 {
1587 pick_up (op, tmp); 1549 pick_up (op, tmp);
1588 if (0)
1589 fprintf (stderr, "GLOVES\n");
1590 continue; 1550 continue;
1591 } 1551 }
1592 1552
1593 /* hoping to catch throwing daggers here */ 1553 /* hoping to catch throwing daggers here */
1594 if (op->contr->mode & PU_MISSILEWEAPON) 1554 if (op->contr->mode & PU_MISSILEWEAPON)
1595 if (tmp->type == WEAPON && QUERY_FLAG (tmp, FLAG_IS_THROWN)) 1555 if (tmp->type == WEAPON && QUERY_FLAG (tmp, FLAG_IS_THROWN))
1596 { 1556 {
1597 pick_up (op, tmp); 1557 pick_up (op, tmp);
1598 if (0)
1599 fprintf (stderr, "MISSILEWEAPON\n");
1600 continue; 1558 continue;
1601 } 1559 }
1602 1560
1603 /* careful: chairs and tables are weapons! */ 1561 /* careful: chairs and tables are weapons! */
1604 if (op->contr->mode & PU_ALLWEAPON) 1562 if (op->contr->mode & PU_ALLWEAPON)
1607 { 1565 {
1608 if (strstr (tmp->name, "table") == NULL && strstr (tmp->arch->name, "table") == NULL && 1566 if (strstr (tmp->name, "table") == NULL && strstr (tmp->arch->name, "table") == NULL &&
1609 strstr (tmp->name, "chair") && strstr (tmp->arch->name, "chair") == NULL) 1567 strstr (tmp->name, "chair") && strstr (tmp->arch->name, "chair") == NULL)
1610 { 1568 {
1611 pick_up (op, tmp); 1569 pick_up (op, tmp);
1612 if (0)
1613 fprintf (stderr, "WEAPON\n");
1614 continue; 1570 continue;
1615 } 1571 }
1616 } 1572 }
1573
1617 if (tmp->type == WEAPON && tmp->name == NULL) 1574 if (tmp->type == WEAPON && tmp->name == NULL)
1618 { 1575 {
1619 if (strstr (tmp->arch->name, "table") == NULL && strstr (tmp->arch->name, "chair") == NULL) 1576 if (strstr (tmp->arch->name, "table") == NULL && strstr (tmp->arch->name, "chair") == NULL)
1620 { 1577 {
1621 pick_up (op, tmp); 1578 pick_up (op, tmp);
1622 if (0)
1623 fprintf (stderr, "WEAPON\n");
1624 continue; 1579 continue;
1625 } 1580 }
1626 } 1581 }
1627 } 1582 }
1628 1583
1629 /* misc stuff that's useful */ 1584 /* misc stuff that's useful */
1630 if (op->contr->mode & PU_KEY) 1585 if (op->contr->mode & PU_KEY)
1631 if (tmp->type == KEY || tmp->type == SPECIAL_KEY) 1586 if (tmp->type == KEY || tmp->type == SPECIAL_KEY)
1632 { 1587 {
1633 pick_up (op, tmp); 1588 pick_up (op, tmp);
1634 if (0)
1635 fprintf (stderr, "KEY\n");
1636 continue; 1589 continue;
1637 } 1590 }
1638 1591
1639 /* any of the last 4 bits set means we use the ratio for value 1592 /* any of the last 4 bits set means we use the ratio for value
1640 * pickups */ 1593 * pickups */
1662 continue; 1615 continue;
1663 } 1616 }
1664 } 1617 }
1665 } /* the new pickup model */ 1618 } /* the new pickup model */
1666 } 1619 }
1620
1667 return !stop; 1621 return !stop;
1668} 1622}
1669 1623
1670/* 1624/*
1671 * Find an arrow in the inventory and after that 1625 * Find an arrow in the inventory and after that
1770 1724
1771object * 1725object *
1772pick_arrow_target (object *op, const char *type, int dir) 1726pick_arrow_target (object *op, const char *type, int dir)
1773{ 1727{
1774 object *tmp = NULL; 1728 object *tmp = NULL;
1775 mapstruct *m; 1729 maptile *m;
1776 int i, mflags, found, number; 1730 int i, mflags, found, number;
1777 sint16 x, y; 1731 sint16 x, y;
1778 1732
1779 if (op->map == NULL) 1733 if (op->map == NULL)
1780 return find_arrow (op, type); 1734 return find_arrow (op, type);
1840 */ 1794 */
1841int 1795int
1842fire_bow (object *op, object *part, object *arrow, int dir, int wc_mod, sint16 sx, sint16 sy) 1796fire_bow (object *op, object *part, object *arrow, int dir, int wc_mod, sint16 sx, sint16 sy)
1843{ 1797{
1844 object *left, *bow; 1798 object *left, *bow;
1845 tag_t left_tag, tag;
1846 int bowspeed, mflags; 1799 int bowspeed, mflags;
1847 mapstruct *m; 1800 maptile *m;
1848 1801
1849 if (!dir) 1802 if (!dir)
1850 { 1803 {
1851 new_draw_info (NDI_UNIQUE, 0, op, "You can't shoot yourself!"); 1804 new_draw_info (NDI_UNIQUE, 0, op, "You can't shoot yourself!");
1852 return 0; 1805 return 0;
1853 } 1806 }
1807
1854 if (op->type == PLAYER) 1808 if (op->type == PLAYER)
1855 bow = op->contr->ranges[range_bow]; 1809 bow = op->contr->ranges[range_bow];
1856 else 1810 else
1857 { 1811 {
1858 for (bow = op->inv; bow; bow = bow->below) 1812 for (bow = op->inv; bow; bow = bow->below)
1866 { 1820 {
1867 LOG (llevError, "Range: bow without activated bow (%s).\n", &op->name); 1821 LOG (llevError, "Range: bow without activated bow (%s).\n", &op->name);
1868 return 0; 1822 return 0;
1869 } 1823 }
1870 } 1824 }
1825
1871 if (!bow->race || !bow->skill) 1826 if (!bow->race || !bow->skill)
1872 { 1827 {
1873 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is broken.", &bow->name); 1828 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is broken.", &bow->name);
1874 return 0; 1829 return 0;
1875 } 1830 }
1877 bowspeed = bow->stats.sp + dex_bonus[op->stats.Dex]; 1832 bowspeed = bow->stats.sp + dex_bonus[op->stats.Dex];
1878 1833
1879 /* penalize ROF for bestarrow */ 1834 /* penalize ROF for bestarrow */
1880 if (op->type == PLAYER && op->contr->bowtype == bow_bestarrow) 1835 if (op->type == PLAYER && op->contr->bowtype == bow_bestarrow)
1881 bowspeed -= dex_bonus[op->stats.Dex] + 5; 1836 bowspeed -= dex_bonus[op->stats.Dex] + 5;
1837
1882 if (bowspeed < 1) 1838 if (bowspeed < 1)
1883 bowspeed = 1; 1839 bowspeed = 1;
1884 1840
1885 if (arrow == NULL) 1841 if (arrow == NULL)
1886 { 1842 {
1892 else 1848 else
1893 CLEAR_FLAG (op, FLAG_READY_BOW); 1849 CLEAR_FLAG (op, FLAG_READY_BOW);
1894 return 0; 1850 return 0;
1895 } 1851 }
1896 } 1852 }
1853
1897 mflags = get_map_flags (op->map, &m, sx, sy, &sx, &sy); 1854 mflags = get_map_flags (op->map, &m, sx, sy, &sx, &sy);
1898 if (mflags & P_OUT_OF_MAP) 1855 if (mflags & P_OUT_OF_MAP)
1899 {
1900 return 0; 1856 return 0;
1901 } 1857
1902 if (GET_MAP_MOVE_BLOCK (m, sx, sy) == MOVE_FLY_LOW) 1858 if (GET_MAP_MOVE_BLOCK (m, sx, sy) == MOVE_FLY_LOW)
1903 { 1859 {
1904 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); 1860 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way.");
1905 return 0; 1861 return 0;
1906 } 1862 }
1907 1863
1908 /* this should not happen, but sometimes does */ 1864 /* this should not happen, but sometimes does */
1909 if (arrow->nrof == 0) 1865 if (arrow->nrof == 0)
1910 { 1866 {
1911 remove_ob (arrow); 1867 arrow->destroy ();
1912 free_object (arrow);
1913 return 0; 1868 return 0;
1914 } 1869 }
1915 1870
1916 left = arrow; /* these are arrows left to the player */ 1871 left = arrow; /* these are arrows left to the player */
1917 left_tag = left->count;
1918 arrow = get_split_ob (arrow, 1); 1872 arrow = get_split_ob (arrow, 1);
1919 if (arrow == NULL) 1873 if (!arrow)
1920 { 1874 {
1921 new_draw_info_format (NDI_UNIQUE, 0, op, "You have no %s left.", &bow->race); 1875 new_draw_info_format (NDI_UNIQUE, 0, op, "You have no %s left.", &bow->race);
1922 return 0; 1876 return 0;
1923 } 1877 }
1924 set_owner (arrow, op); 1878
1879 arrow->set_owner (op);
1925 arrow->skill = bow->skill; 1880 arrow->skill = bow->skill;
1926 1881
1927 arrow->direction = dir; 1882 arrow->direction = dir;
1928 arrow->x = sx; 1883 arrow->x = sx;
1929 arrow->y = sy; 1884 arrow->y = sy;
1937 SET_ANIMATION (arrow, arrow->direction); 1892 SET_ANIMATION (arrow, arrow->direction);
1938 arrow->stats.sp = arrow->stats.wc; /* save original wc and dam */ 1893 arrow->stats.sp = arrow->stats.wc; /* save original wc and dam */
1939 arrow->stats.hp = arrow->stats.dam; 1894 arrow->stats.hp = arrow->stats.dam;
1940 arrow->stats.grace = arrow->attacktype; 1895 arrow->stats.grace = arrow->attacktype;
1941 if (arrow->slaying != NULL) 1896 if (arrow->slaying != NULL)
1942 arrow->spellarg = strdup_local (arrow->slaying); 1897 arrow->spellarg = strdup (arrow->slaying);
1943 1898
1944 /* Note that this was different for monsters - they got their level 1899 /* Note that this was different for monsters - they got their level
1945 * added to the damage. I think the strength bonus is more proper. 1900 * added to the damage. I think the strength bonus is more proper.
1946 */ 1901 */
1947 1902
1965 arrow->level = op->chosen_skill ? op->chosen_skill->level : op->level; 1920 arrow->level = op->chosen_skill ? op->chosen_skill->level : op->level;
1966 } 1921 }
1967 else 1922 else
1968 { 1923 {
1969 arrow->stats.wc = op->stats.wc - bow->magic - arrow->magic - arrow->stats.wc + wc_mod; 1924 arrow->stats.wc = op->stats.wc - bow->magic - arrow->magic - arrow->stats.wc + wc_mod;
1970
1971 arrow->level = op->level; 1925 arrow->level = op->level;
1972 } 1926 }
1927
1973 if (arrow->attacktype == AT_PHYSICAL) 1928 if (arrow->attacktype == AT_PHYSICAL)
1974 arrow->attacktype |= bow->attacktype; 1929 arrow->attacktype |= bow->attacktype;
1930
1975 if (bow->slaying != NULL) 1931 if (bow->slaying)
1976 arrow->slaying = bow->slaying; 1932 arrow->slaying = bow->slaying;
1977 1933
1978 arrow->map = m; 1934 arrow->map = m;
1979 arrow->move_type = MOVE_FLY_LOW; 1935 arrow->move_type = MOVE_FLY_LOW;
1980 arrow->move_on = MOVE_FLY_LOW | MOVE_WALK; 1936 arrow->move_on = MOVE_FLY_LOW | MOVE_WALK;
1981 1937
1982 play_sound_map (op->map, op->x, op->y, SOUND_FIRE_ARROW); 1938 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); 1939 insert_ob_in_map (arrow, m, op, 0);
1985 1940
1986 if (!was_destroyed (arrow, tag)) 1941 if (!arrow->destroyed ())
1987 move_arrow (arrow); 1942 move_arrow (arrow);
1988 1943
1989 if (op->type == PLAYER) 1944 if (op->type == PLAYER)
1990 { 1945 {
1991 if (was_destroyed (left, left_tag)) 1946 if (left->destroyed ())
1992 esrv_del_item (op->contr, left_tag); 1947 esrv_del_item (op->contr, left->count);
1993 else 1948 else
1994 esrv_send_item (op, left); 1949 esrv_send_item (op, left);
1995 } 1950 }
1951
1996 return 1; 1952 return 1;
1997} 1953}
1998 1954
1999/* Special fire code for players - this takes into 1955/* Special fire code for players - this takes into
2000 * account the special fire modes players can have 1956 * account the special fire modes players can have
2096 CLEAR_FLAG (item, FLAG_ANIMATE); 2052 CLEAR_FLAG (item, FLAG_ANIMATE);
2097 item->face = item->arch->clone.face; 2053 item->face = item->arch->clone.face;
2098 item->speed = 0; 2054 item->speed = 0;
2099 update_ob_speed (item); 2055 update_ob_speed (item);
2100 } 2056 }
2101 if ((tmp = is_player_inv (item))) 2057 if ((tmp = item->in_player ()))
2102 esrv_update_item (UPD_ANIM, tmp, item); 2058 esrv_update_item (UPD_ANIM, tmp, item);
2103 } 2059 }
2104 } 2060 }
2105 else if (item->type == ROD || item->type == HORN) 2061 else if (item->type == ROD || item->type == HORN)
2106 { 2062 {
2136 case range_misc: 2092 case range_misc:
2137 fire_misc_object (op, dir); 2093 fire_misc_object (op, dir);
2138 return; 2094 return;
2139 2095
2140 case range_golem: /* Control summoned monsters from scrolls */ 2096 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) 2097 if (QUERY_FLAG (op->contr->ranges[range_golem], FLAG_REMOVED))
2142 { 2098 {
2143 op->contr->ranges[range_golem] = NULL; 2099 op->contr->ranges[range_golem] = 0;
2144 op->contr->shoottype = range_none; 2100 op->contr->shoottype = range_none;
2145 op->contr->golem_count = 0;
2146 } 2101 }
2147 else 2102 else
2148 control_golem (op->contr->ranges[range_golem], dir); 2103 control_golem (op->contr->ranges[range_golem], dir);
2149 return; 2104 return;
2150 2105
2257 * 0 otherwise 2212 * 0 otherwise
2258 */ 2213 */
2259static int 2214static int
2260player_attack_door (object *op, object *door) 2215player_attack_door (object *op, object *door)
2261{ 2216{
2262
2263 /* If its a door, try to find a use a key. If we do destroy the door, 2217 /* If its a door, try to find a use a key. If we do destroy the door,
2264 * might as well return immediately as there is nothing more to do - 2218 * might as well return immediately as there is nothing more to do -
2265 * otherwise, we fall through to the rest of the code. 2219 * otherwise, we fall through to the rest of the code.
2266 */ 2220 */
2267 object *key = find_key (op, op, door); 2221 object *key = find_key (op, op, door);
2305 * It should keep the code cleaner. 2259 * It should keep the code cleaner.
2306 * When this is called, the players direction has been updated 2260 * When this is called, the players direction has been updated
2307 * (taking into account confusion.) The player is also actually 2261 * (taking into account confusion.) The player is also actually
2308 * going to try and move (not fire weapons). 2262 * going to try and move (not fire weapons).
2309 */ 2263 */
2310
2311void 2264void
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, 0, 0);
2323 2276
2324 /* If braced, or can't move to the square, and it is not out of the 2277 /* If braced, or can't move to the square, and it is not out of the
2325 * map, attack it. Note order of if statement is important - don't 2278 * map, attack it. Note order of if statement is important - don't
2326 * want to be calling move_ob if braced, because move_ob will move the 2279 * want to be calling move_ob if braced, because move_ob will move the
2327 * player. This is a pretty nasty hack, because if we could 2280 * player. This is a pretty nasty hack, because if we could
2339 return; /* Don't think this should happen */ 2292 return; /* Don't think this should happen */
2340 } 2293 }
2341 else 2294 else
2342 m = op->map; 2295 m = op->map;
2343 2296
2344 if ((tmp = get_map_ob (m, nx, ny)) == NULL) 2297 if ((tmp = GET_MAP_OB (m, nx, ny)) == NULL)
2345 { 2298 {
2346 /* LOG(llevError,"player_move_attack: get_map_ob returns NULL, but player can not more there.\n"); */ 2299 /* LOG(llevError,"player_move_attack: GET_MAP_OB returns NULL, but player can not move there.\n"); */
2347 return; 2300 return;
2348 } 2301 }
2349 2302
2350 mon = NULL; 2303 mon = 0;
2351 /* Go through all the objects, and find ones of interest. Only stop if 2304 /* Go through all the objects, and find ones of interest. Only stop if
2352 * we find a monster - that is something we know we want to attack. 2305 * we find a monster - that is something we know we want to attack.
2353 * if its a door or barrel (can roll) see if there may be monsters 2306 * if its a door or barrel (can roll) see if there may be monsters
2354 * on the space 2307 * on the space
2355 */ 2308 */
2356 while (tmp != NULL) 2309 while (tmp)
2357 { 2310 {
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) /* This happens anytime the player tries to move */
2374 return; /* into a wall */ 2330 return; /* into a wall */
2375 2331
2376 if (mon->head != NULL) 2332 if (mon->head)
2377 mon = mon->head; 2333 mon = mon->head;
2378 2334
2379 if ((mon->type == DOOR && mon->stats.hp >= 0) || (mon->type == LOCKED_DOOR)) 2335 if ((mon->type == DOOR && mon->stats.hp >= 0) || (mon->type == LOCKED_DOOR))
2380 if (player_attack_door (op, mon)) 2336 if (player_attack_door (op, mon))
2381 return; 2337 return;
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)
2418 * attack them either. 2374 * attack them either.
2419 */ 2375 */
2420 if ((mon->type == PLAYER || mon->enemy != op) && 2376 if ((mon->type == PLAYER || mon->enemy != op) &&
2421 (mon->type == PLAYER || QUERY_FLAG (mon, FLAG_UNAGGRESSIVE) || QUERY_FLAG (mon, FLAG_FRIENDLY)) && ( 2377 (mon->type == PLAYER || QUERY_FLAG (mon, FLAG_UNAGGRESSIVE) || QUERY_FLAG (mon, FLAG_FRIENDLY)) && (
2422#ifdef PROHIBIT_PLAYERKILL 2378#ifdef PROHIBIT_PLAYERKILL
2423 (op->contr->peaceful 2379 (op->contr->peaceful
2424 || (mon->type == PLAYER 2380 || (mon->type == PLAYER
2425 && mon->contr-> 2381 && mon->contr->
2426 peaceful)) && 2382 peaceful)) &&
2427#else 2383#else
2428 op->contr->peaceful && 2384 op->contr->peaceful &&
2429#endif 2385#endif
2430 !on_battleground)) 2386 !on_battleground))
2431 { 2387 {
2432 if (!op->contr->braced) 2388 if (!op->contr->braced)
2433 { 2389 {
2434 play_sound_map (op->map, op->x, op->y, SOUND_PUSH_PLAYER); 2390 play_sound_map (op->map, op->x, op->y, SOUND_PUSH_PLAYER);
2435 (void) push_ob (mon, dir, op); 2391 (void) push_ob (mon, dir, op);
2436 } 2392 }
2437 else 2393 else
2438 {
2439 new_draw_info (0, 0, op, "You withhold your attack"); 2394 new_draw_info (0, 0, op, "You withhold your attack");
2440 } 2395
2441 if (op->contr->tmp_invis || op->hide) 2396 if (op->contr->tmp_invis || op->hide)
2442 make_visible (op); 2397 make_visible (op);
2443 } 2398 }
2444 2399
2445 /* If the object is a boulder or other rollable object, then 2400 /* If the object is a boulder or other rollable object, then
2473 op->speed_left += op->speed / op->contr->weapon_sp; 2428 op->speed_left += op->speed / op->contr->weapon_sp;
2474 2429
2475 op->contr->has_hit = 1; /* The last action was to hit, so use weapon_sp */ 2430 op->contr->has_hit = 1; /* The last action was to hit, so use weapon_sp */
2476 } 2431 }
2477 2432
2478 skill_attack (mon, op, 0, NULL, NULL); 2433 skill_attack (mon, op, 0, 0, 0);
2479 2434
2480 /* If attacking another player, that player gets automatic 2435 /* If attacking another player, that player gets automatic
2481 * hitback, and doesn't loose luck either. 2436 * hitback, and doesn't loose luck either.
2482 * Disable hitback on the battleground or if the target is 2437 * Disable hitback on the battleground or if the target is
2483 * the wiz. 2438 * the wiz.
2485 if (mon->type == PLAYER && mon->stats.hp >= 0 && !mon->contr->has_hit && !on_battleground && !QUERY_FLAG (mon, FLAG_WIZ)) 2440 if (mon->type == PLAYER && mon->stats.hp >= 0 && !mon->contr->has_hit && !on_battleground && !QUERY_FLAG (mon, FLAG_WIZ))
2486 { 2441 {
2487 short luck = mon->stats.luck; 2442 short luck = mon->stats.luck;
2488 2443
2489 mon->contr->has_hit = 1; 2444 mon->contr->has_hit = 1;
2490 skill_attack (op, mon, 0, NULL, NULL); 2445 skill_attack (op, mon, 0, 0, 0);
2491 mon->stats.luck = luck; 2446 mon->stats.luck = luck;
2492 } 2447 }
2448
2493 if (action_makes_visible (op)) 2449 if (action_makes_visible (op))
2494 make_visible (op); 2450 make_visible (op);
2495 } 2451 }
2496 } /* if player should attack something */ 2452 } /* if player should attack something */
2497} 2453}
2532 2488
2533 /* Add special check for newcs players and fire on - this way, the 2489 /* Add special check for newcs players and fire on - this way, the
2534 * server can handle repeat firing. 2490 * server can handle repeat firing.
2535 */ 2491 */
2536 if (op->contr->fire_on || (op->contr->run_on && pick != 0)) 2492 if (op->contr->fire_on || (op->contr->run_on && pick != 0))
2537 {
2538 op->direction = dir; 2493 op->direction = dir;
2539 }
2540 else 2494 else
2541 {
2542 op->direction = 0; 2495 op->direction = 0;
2543 } 2496
2544 /* Update how the player looks. Use the facing, so direction may 2497 /* Update how the player looks. Use the facing, so direction may
2545 * get reset to zero. This allows for full animation capabilities 2498 * get reset to zero. This allows for full animation capabilities
2546 * for players. 2499 * for players.
2547 */ 2500 */
2548 animate_object (op, op->facing); 2501 animate_object (op, op->facing);
2593 /* I've been seeing crashes where the golem has been destroyed, but 2546 /* 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 2547 * 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 2548 * 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. 2549 * put this in a a workaround to clean up the golem pointer.
2597 */ 2550 */
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))) 2551 if (op->contr->ranges[range_golem] && QUERY_FLAG (op->contr->ranges[range_golem], FLAG_REMOVED))
2600 {
2601 op->contr->ranges[range_golem] = NULL; 2552 op->contr->ranges[range_golem] = 0;
2602 op->contr->golem_count = 0;
2603 }
2604 2553
2605 /* call this here - we also will call this in do_ericserver, but 2554 /* call this here - we also will call this in do_ericserver, but
2606 * the players time has been increased when doericserver has been 2555 * the players time has been increased when doericserver has been
2607 * called, so we recheck it here. 2556 * called, so we recheck it here.
2608 */ 2557 */
2609 HandleClient (&op->contr->socket, op->contr); 2558 //TODO: better than handling 8 commands, use some more intelligent rate-limiting
2559 for (int rep = 8; --rep && op->contr->socket->handle_command (); )
2560 ;
2561
2610 if (op->speed_left < 0) 2562 if (op->speed_left < 0)
2611 return 0; 2563 return 0;
2612 2564
2613 if (op->direction && (op->contr->run_on || op->contr->fire_on)) 2565 if (op->direction && (op->contr->run_on || op->contr->fire_on))
2614 { 2566 {
2623 if (op->speed_left > 0) 2575 if (op->speed_left > 0)
2624 return 1; 2576 return 1;
2625 else 2577 else
2626 return 0; 2578 return 0;
2627 } 2579 }
2580
2628 return 0; 2581 return 0;
2629} 2582}
2630 2583
2631int 2584int
2632save_life (object *op) 2585save_life (object *op)
2633{ 2586{
2634 object *tmp;
2635
2636 if (!QUERY_FLAG (op, FLAG_LIFESAVE)) 2587 if (!QUERY_FLAG (op, FLAG_LIFESAVE))
2637 return 0; 2588 return 0;
2638 2589
2639 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 2590 for (object *tmp = op->inv; tmp; tmp = tmp->below)
2640 if (QUERY_FLAG (tmp, FLAG_APPLIED) && QUERY_FLAG (tmp, FLAG_LIFESAVE)) 2591 if (QUERY_FLAG (tmp, FLAG_APPLIED) && QUERY_FLAG (tmp, FLAG_LIFESAVE))
2641 { 2592 {
2642 play_sound_map (op->map, op->x, op->y, SOUND_OB_EVAPORATE); 2593 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)); 2594 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s vibrates violently, then evaporates.", query_name (tmp));
2595
2644 if (op->contr) 2596 if (op->contr)
2645 esrv_del_item (op->contr, tmp->count); 2597 esrv_del_item (op->contr, tmp->count);
2646 remove_ob (tmp); 2598
2647 free_object (tmp); 2599 tmp->destroy ();
2648 CLEAR_FLAG (op, FLAG_LIFESAVE); 2600 CLEAR_FLAG (op, FLAG_LIFESAVE);
2601
2649 if (op->stats.hp < 0) 2602 if (op->stats.hp < 0)
2650 op->stats.hp = op->stats.maxhp; 2603 op->stats.hp = op->stats.maxhp;
2604
2651 if (op->stats.food < 0) 2605 if (op->stats.food < 0)
2652 op->stats.food = 999; 2606 op->stats.food = 999;
2607
2653 fix_player (op); 2608 fix_player (op);
2654 return 1; 2609 return 1;
2655 } 2610 }
2611
2656 LOG (llevError, "Error: LIFESAVE set without applied object.\n"); 2612 LOG (llevError, "Error: LIFESAVE set without applied object.\n");
2657 CLEAR_FLAG (op, FLAG_LIFESAVE); 2613 CLEAR_FLAG (op, FLAG_LIFESAVE);
2658 enter_player_savebed (op); /* bring him home. */ 2614 enter_player_savebed (op); /* bring him home. */
2659 return 0; 2615 return 0;
2660} 2616}
2674 next = op->below; /* Make sure we have a good value, in case 2630 next = op->below; /* Make sure we have a good value, in case
2675 * we remove object 'op' 2631 * we remove object 'op'
2676 */ 2632 */
2677 if (QUERY_FLAG (op, FLAG_UNPAID)) 2633 if (QUERY_FLAG (op, FLAG_UNPAID))
2678 { 2634 {
2679 remove_ob (op); 2635 op->remove ();
2680 op->x = env->x; 2636 op->x = env->x;
2681 op->y = env->y; 2637 op->y = env->y;
2682 if (env->type == PLAYER) 2638 if (env->type == PLAYER)
2683 esrv_del_item (env->contr, op->count); 2639 esrv_del_item (env->contr, op->count);
2684 insert_ob_in_map (op, env->map, NULL, 0); 2640 insert_ob_in_map (op, env->map, NULL, 0);
2685 } 2641 }
2686 else if (op->inv) 2642 else if (op->inv)
2687 remove_unpaid_objects (op->inv, env); 2643 remove_unpaid_objects (op->inv, env);
2644
2688 op = next; 2645 op = next;
2689 } 2646 }
2690} 2647}
2691 2648
2692 2649
2707 strcpy (buf2, " R.I.P.\n\n"); 2664 strcpy (buf2, " R.I.P.\n\n");
2708 if (op->type == PLAYER) 2665 if (op->type == PLAYER)
2709 sprintf (buf, "%s the %s\n", &op->name, op->contr->title); 2666 sprintf (buf, "%s the %s\n", &op->name, op->contr->title);
2710 else 2667 else
2711 sprintf (buf, "%s\n", &op->name); 2668 sprintf (buf, "%s\n", &op->name);
2669
2712 strncat (buf2, " ", 20 - strlen (buf) / 2); 2670 strncat (buf2, " ", 20 - strlen (buf) / 2);
2713 strcat (buf2, buf); 2671 strcat (buf2, buf);
2714 if (op->type == PLAYER) 2672 if (op->type == PLAYER)
2715 sprintf (buf, "who was in level %d when killed\n", op->level); 2673 sprintf (buf, "who was in level %d when killed\n", op->level);
2716 else 2674 else
2717 sprintf (buf, "who was in level %d when died.\n\n", op->level); 2675 sprintf (buf, "who was in level %d when died.\n\n", op->level);
2676
2718 strncat (buf2, " ", 20 - strlen (buf) / 2); 2677 strncat (buf2, " ", 20 - strlen (buf) / 2);
2719 strcat (buf2, buf); 2678 strcat (buf2, buf);
2720 if (op->type == PLAYER) 2679 if (op->type == PLAYER)
2721 { 2680 {
2722 sprintf (buf, "by %s.\n\n", op->contr->killer); 2681 sprintf (buf, "by %s.\n\n", op->contr->killer);
2723 strncat (buf2, " ", 21 - strlen (buf) / 2); 2682 strncat (buf2, " ", 21 - strlen (buf) / 2);
2724 strcat (buf2, buf); 2683 strcat (buf2, buf);
2725 } 2684 }
2685
2726 strftime (buf, MAX_BUF, "%b %d %Y\n", localtime (&now)); 2686 strftime (buf, MAX_BUF, "%b %d %Y\n", localtime (&now));
2727 strncat (buf2, " ", 20 - strlen (buf) / 2); 2687 strncat (buf2, " ", 20 - strlen (buf) / 2);
2728 strcat (buf2, buf); 2688 strcat (buf2, buf);
2689
2729 return buf2; 2690 return buf2;
2730} 2691}
2731 2692
2732 2693
2733 2694
2952{ 2913{
2953 char buf[MAX_BUF]; 2914 char buf[MAX_BUF];
2954 int x, y; 2915 int x, y;
2955 2916
2956 //int i; 2917 //int i;
2957 mapstruct *map; /* this is for resurrection */ 2918 maptile *map; /* this is for resurrection */
2958 2919
2959 /* int z; 2920 /* int z;
2960 int num_stats_lose; 2921 int num_stats_lose;
2961 int lost_a_stat; 2922 int lost_a_stat;
2962 int lose_this_stat; 2923 int lose_this_stat;
2977 { 2938 {
2978 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "You have been defeated in combat!"); 2939 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..."); 2940 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "Local medics have saved your life...");
2980 2941
2981 /* restore player */ 2942 /* restore player */
2982 at = find_archetype ("poisoning"); 2943 at = archetype::find ("poisoning");
2983 tmp = present_arch_in_ob (at, op); 2944 tmp = present_arch_in_ob (at, op);
2984 if (tmp) 2945 if (tmp)
2985 { 2946 {
2986 remove_ob (tmp); 2947 tmp->destroy ();
2987 free_object (tmp);
2988 new_draw_info (NDI_UNIQUE, 0, op, "Your body feels cleansed"); 2948 new_draw_info (NDI_UNIQUE, 0, op, "Your body feels cleansed");
2989 } 2949 }
2990 2950
2991 at = find_archetype ("confusion"); 2951 at = archetype::find ("confusion");
2992 tmp = present_arch_in_ob (at, op); 2952 tmp = present_arch_in_ob (at, op);
2993 if (tmp) 2953 if (tmp)
2994 { 2954 {
2995 remove_ob (tmp); 2955 tmp->destroy ();
2996 free_object (tmp);
2997 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); 2956 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer");
2998 } 2957 }
2999 2958
3000 cure_disease (op, 0); /* remove any disease */ 2959 cure_disease (op, 0); /* remove any disease */
3001 op->stats.hp = op->stats.maxhp; 2960 op->stats.hp = op->stats.maxhp;
3002 if (op->stats.food <= 0) 2961 if (op->stats.food <= 0)
3003 op->stats.food = 999; 2962 op->stats.food = 999;
3004 2963
3005 /* create a bodypart-trophy to make the winner happy */ 2964 /* create a bodypart-trophy to make the winner happy */
3006 tmp = arch_to_object (find_archetype ("finger")); 2965 tmp = arch_to_object (archetype::find ("finger"));
3007 if (tmp != NULL) 2966 if (tmp != NULL)
3008 { 2967 {
3009 sprintf (buf, "%s's finger", &op->name); 2968 sprintf (buf, "%s's finger", &op->name);
3010 tmp->name = buf; 2969 tmp->name = buf;
3011 sprintf (buf, " This finger has been cut off %s\n" 2970 sprintf (buf, " This finger has been cut off %s\n"
3108 lost_a_stat = 1; 3067 lost_a_stat = 1;
3109 } 3068 }
3110 else 3069 else
3111 { 3070 {
3112 /* deplete a stat */ 3071 /* deplete a stat */
3113 archetype *deparch = find_archetype ("depletion"); 3072 archetype *deparch = archetype::find ("depletion");
3114 object *dep; 3073 object *dep;
3115 3074
3116 dep = present_arch_in_ob (deparch, op); 3075 dep = present_arch_in_ob (deparch, op);
3117 if (!dep) 3076 if (!dep)
3118 { 3077 {
3178 /* determine_god() seems to not work sometimes... why is this? 3137 /* determine_god() seems to not work sometimes... why is this?
3179 Should I be using something else? GD */ 3138 Should I be using something else? GD */
3180 const char *god = determine_god (op); 3139 const char *god = determine_god (op);
3181 3140
3182 if (god && (strcmp (god, "none"))) 3141 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); 3142 new_draw_info_format (NDI_UNIQUE, 0, op, "For a brief moment you feel the holy presence of %s protecting" " you.", god);
3184 else 3143 else
3185 new_draw_info (NDI_UNIQUE, 0, op, "For a brief moment you" " feel a holy presence protecting you."); 3144 new_draw_info (NDI_UNIQUE, 0, op, "For a brief moment you feel a holy presence protecting you.");
3186 } 3145 }
3146#else
3147 new_draw_info (NDI_UNIQUE, 0, op, "For a brief moment you" " feel a holy presence protecting you from losing yourself completely.");
3187#endif 3148#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 3149
3190 /* Put a gravestone up where the character 'almost' died. List the 3150 /* Put a gravestone up where the character 'almost' died. List the
3191 * exp loss on the stone. 3151 * exp loss on the stone.
3192 */ 3152 */
3193 tmp = arch_to_object (find_archetype ("gravestone")); 3153 tmp = arch_to_object (archetype::find ("gravestone"));
3194 sprintf (buf, "%s's gravestone", &op->name); 3154 sprintf (buf, "%s's gravestone", &op->name);
3195 tmp->name = buf; 3155 tmp->name = buf;
3196 sprintf (buf, "%s's gravestones", &op->name); 3156 sprintf (buf, "%s's gravestones", &op->name);
3197 tmp->name_pl = buf; 3157 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); 3158 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; 3159 tmp->msg = buf;
3200 tmp->x = op->x, tmp->y = op->y; 3160 tmp->x = op->x, tmp->y = op->y;
3201 insert_ob_in_map (tmp, op->map, NULL, 0); 3161 insert_ob_in_map (tmp, op->map, NULL, 0);
3202 3162
3203 /**************************************/ 3163 /**************************************/
3204 /* */ 3164 /* */
3205 /* Subtract the experience points, */ 3165 /* Subtract the experience points, */
3206 /* if we died cause of food, give us */ 3166 /* if we died cause of food, give us */
3207 /* food, and reset HP's... */ 3167 /* food, and reset HP's... */
3208 /* */ 3168 /* */
3209
3210 /**************************************/ 3169 /**************************************/
3211 3170
3212 /* remove any poisoning and confusion the character may be suffering. */ 3171 /* remove any poisoning and confusion the character may be suffering. */
3213 /* restore player */ 3172 /* restore player */
3214 at = find_archetype ("poisoning"); 3173 at = archetype::find ("poisoning");
3174 tmp = present_arch_in_ob (at, op);
3175
3176 if (tmp)
3177 {
3178 tmp->destroy ();
3179 new_draw_info (NDI_UNIQUE, 0, op, "Your body feels cleansed");
3180 }
3181
3182 at = archetype::find ("confusion");
3215 tmp = present_arch_in_ob (at, op); 3183 tmp = present_arch_in_ob (at, op);
3216 if (tmp) 3184 if (tmp)
3217 { 3185 {
3218 remove_ob (tmp); 3186 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"); 3187 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer");
3230 } 3188 }
3189
3231 cure_disease (op, 0); /* remove any disease */ 3190 cure_disease (op, 0); /* remove any disease */
3232 3191
3233 /*add_exp(op, (op->stats.exp * -0.20)); */ 3192 /*add_exp(op, (op->stats.exp * -0.20)); */
3234 apply_death_exp_penalty (op); 3193 apply_death_exp_penalty (op);
3235 if (op->stats.food < 100) 3194 if (op->stats.food < 100)
3245 */ 3204 */
3246 3205
3247 if (is_in_shop (op)) 3206 if (is_in_shop (op))
3248 remove_unpaid_objects (op->inv, op); 3207 remove_unpaid_objects (op->inv, op);
3249 3208
3250 /****************************************/ 3209 /****************************************/
3251 /* */ 3210 /* */
3252 /* Move player to his current respawn- */ 3211 /* Move player to his current respawn- */
3253 /* position (usually last savebed) */ 3212 /* position (usually last savebed) */
3254 /* */ 3213 /* */
3255
3256 /****************************************/ 3214 /****************************************/
3257 3215
3258 enter_player_savebed (op); 3216 enter_player_savebed (op);
3259 3217
3260 /* Save the player before inserting the force to reduce 3218 /* Save the player before inserting the force to reduce
3261 * chance of abuse. 3219 * chance of abuse.
3267 * at his savebed location, and that can have long lasting 3225 * at his savebed location, and that can have long lasting
3268 * spell effects. So first see if there is a spell effect 3226 * spell effects. So first see if there is a spell effect
3269 * on the space that might harm the player. 3227 * on the space that might harm the player.
3270 */ 3228 */
3271 will_kill_again = 0; 3229 will_kill_again = 0;
3272 for (tmp = get_map_ob (op->map, op->x, op->y); tmp; tmp = tmp->above) 3230 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above)
3273 {
3274 if (tmp->type == SPELL_EFFECT) 3231 if (tmp->type == SPELL_EFFECT)
3275 will_kill_again |= tmp->attacktype; 3232 will_kill_again |= tmp->attacktype;
3276 } 3233
3277 if (will_kill_again) 3234 if (will_kill_again)
3278 { 3235 {
3279 object *force; 3236 object *force;
3280 int at; 3237 int at;
3281 3238
3283 /* 50 ticks should be enough time for the spell to abate */ 3240 /* 50 ticks should be enough time for the spell to abate */
3284 force->speed = 0.1; 3241 force->speed = 0.1;
3285 force->speed_left = -5.0; 3242 force->speed_left = -5.0;
3286 SET_FLAG (force, FLAG_APPLIED); 3243 SET_FLAG (force, FLAG_APPLIED);
3287 for (at = 0; at < NROFATTACKS; at++) 3244 for (at = 0; at < NROFATTACKS; at++)
3288 {
3289 if (will_kill_again & (1 << at)) 3245 if (will_kill_again & (1 << at))
3290 force->resist[at] = 100; 3246 force->resist[at] = 100;
3291 } 3247
3292 insert_ob_in_ob (force, op); 3248 insert_ob_in_ob (force, op);
3293 fix_player (op); 3249 fix_player (op);
3294 3250
3295 } 3251 }
3296 3252
3306 op->contr->party = NULL; 3262 op->contr->party = NULL;
3307 if (settings.set_title == TRUE) 3263 if (settings.set_title == TRUE)
3308 op->contr->own_title[0] = '\0'; 3264 op->contr->own_title[0] = '\0';
3309 new_draw_info (NDI_UNIQUE | NDI_ALL, 0, NULL, buf); 3265 new_draw_info (NDI_UNIQUE | NDI_ALL, 0, NULL, buf);
3310 check_score (op); 3266 check_score (op);
3267
3311 if (op->contr->ranges[range_golem] != NULL) 3268 if (op->contr->ranges[range_golem])
3312 { 3269 {
3313 remove_friendly_object (op->contr->ranges[range_golem]); 3270 remove_friendly_object (op->contr->ranges[range_golem]);
3314 remove_ob (op->contr->ranges[range_golem]); 3271 op->contr->ranges[range_golem]->destroy ();
3315 free_object (op->contr->ranges[range_golem]);
3316 op->contr->ranges[range_golem] = NULL; 3272 op->contr->ranges[range_golem] = 0;
3317 op->contr->golem_count = 0;
3318 } 3273 }
3274
3319 loot_object (op); /* Remove some of the items for good */ 3275 loot_object (op); /* Remove some of the items for good */
3320 remove_ob (op); 3276 op->remove ();
3321 op->direction = 0; 3277 op->direction = 0;
3322 3278
3323 if (!QUERY_FLAG (op, FLAG_WAS_WIZ) && op->stats.exp) 3279 if (!QUERY_FLAG (op, FLAG_WAS_WIZ) && op->stats.exp)
3324 { 3280 {
3325 delete_character (op->name, 0); 3281 delete_character (op->name, 0);
3350 } 3306 }
3351 3307
3352 play_again (op); 3308 play_again (op);
3353 3309
3354 /* peterm: added to create a corpse at deathsite. */ 3310 /* peterm: added to create a corpse at deathsite. */
3355 tmp = arch_to_object (find_archetype ("corpse_pl")); 3311 tmp = arch_to_object (archetype::find ("corpse_pl"));
3356 sprintf (buf, "%s", &op->name); 3312 sprintf (buf, "%s", &op->name);
3357 tmp->name = tmp->name_pl = buf; 3313 tmp->name = tmp->name_pl = buf;
3358 tmp->level = op->level; 3314 tmp->level = op->level;
3359 tmp->x = x; 3315 tmp->x = x;
3360 tmp->y = y; 3316 tmp->y = y;
3376 } 3332 }
3377 3333
3378 for (tmp = op->inv; tmp != NULL; tmp = next) 3334 for (tmp = op->inv; tmp != NULL; tmp = next)
3379 { 3335 {
3380 next = tmp->below; 3336 next = tmp->below;
3381 if (tmp->type == EXPERIENCE || tmp->invisible) 3337 if (tmp->invisible)
3382 continue; 3338 continue;
3383 remove_ob (tmp); 3339 tmp->remove ();
3384 tmp->x = op->x, tmp->y = op->y; 3340 tmp->x = op->x, tmp->y = op->y;
3385 if (tmp->type == CONTAINER) 3341 if (tmp->type == CONTAINER)
3386 { /* empty container to ground */ 3342 { /* empty container to ground */
3387 loot_object (tmp); 3343 loot_object (tmp);
3388 } 3344 }
3389 if (!QUERY_FLAG (tmp, FLAG_UNIQUE) && (QUERY_FLAG (tmp, FLAG_STARTEQUIP) || QUERY_FLAG (tmp, FLAG_NO_DROP) || !(RANDOM () % 3))) 3345 if (!QUERY_FLAG (tmp, FLAG_UNIQUE) && (QUERY_FLAG (tmp, FLAG_STARTEQUIP) || QUERY_FLAG (tmp, FLAG_NO_DROP) || !(RANDOM () % 3)))
3390 { 3346 {
3391 if (tmp->nrof > 1) 3347 if (tmp->nrof > 1)
3392 { 3348 {
3393 tmp2 = get_split_ob (tmp, 1 + RANDOM () % (tmp->nrof - 1)); 3349 tmp2 = get_split_ob (tmp, 1 + RANDOM () % (tmp->nrof - 1));
3394 free_object (tmp2); 3350 tmp2->destroy ();
3395 insert_ob_in_map (tmp, op->map, NULL, 0); 3351 insert_ob_in_map (tmp, op->map, NULL, 0);
3396 } 3352 }
3397 else 3353 else
3398 free_object (tmp); 3354 tmp->destroy ();
3399 } 3355 }
3400 else 3356 else
3401 insert_ob_in_map (tmp, op->map, NULL, 0); 3357 insert_ob_in_map (tmp, op->map, NULL, 0);
3402 } 3358 }
3403} 3359}
3468 if (op->type == PLAYER) 3424 if (op->type == PLAYER)
3469 new_draw_info_format (NDI_UNIQUE, 0, op, "You cast %s.", &spob->name); 3425 new_draw_info_format (NDI_UNIQUE, 0, op, "You cast %s.", &spob->name);
3470 3426
3471 cast_spell (op, throw_ob, dir, spob, NULL); 3427 cast_spell (op, throw_ob, dir, spob, NULL);
3472 3428
3473 if (!QUERY_FLAG (throw_ob, FLAG_REMOVED)) 3429 throw_ob->destroy ();
3474 remove_ob (throw_ob);
3475 free_object (throw_ob);
3476} 3430}
3477 3431
3478void 3432void
3479make_visible (object *op) 3433make_visible (object *op)
3480{ 3434{
3494 object *tmp = NULL; 3448 object *tmp = NULL;
3495 3449
3496 if (QUERY_FLAG (&op->arch->clone, FLAG_UNDEAD)) 3450 if (QUERY_FLAG (&op->arch->clone, FLAG_UNDEAD))
3497 return 1; 3451 return 1;
3498 3452
3499 if (op->type == PLAYER)
3500 for (tmp = op->inv; tmp; tmp = tmp->below)
3501 if (tmp->type == EXPERIENCE && tmp->stats.Wis)
3502 if (QUERY_FLAG (tmp, FLAG_UNDEAD))
3503 return 1;
3504 return 0; 3453 return 0;
3505} 3454}
3506 3455
3507/* look at the surrounding terrain to determine 3456/* look at the surrounding terrain to determine
3508 * the hideability of this object. Positive levels 3457 * the hideability of this object. Positive levels
3596int 3545int
3597stand_near_hostile (object *who) 3546stand_near_hostile (object *who)
3598{ 3547{
3599 object *tmp = NULL; 3548 object *tmp = NULL;
3600 int i, friendly = 0, player = 0, mflags; 3549 int i, friendly = 0, player = 0, mflags;
3601 mapstruct *m; 3550 maptile *m;
3602 sint16 x, y; 3551 sint16 x, y;
3603 3552
3604 if (!who) 3553 if (!who)
3605 return 0; 3554 return 0;
3606 3555
3623 if (mflags & P_OUT_OF_MAP) 3572 if (mflags & P_OUT_OF_MAP)
3624 continue; 3573 continue;
3625 if (OB_TYPE_MOVE_BLOCK (who, GET_MAP_MOVE_BLOCK (m, x, y))) 3574 if (OB_TYPE_MOVE_BLOCK (who, GET_MAP_MOVE_BLOCK (m, x, y)))
3626 continue; 3575 continue;
3627 3576
3628 for (tmp = get_map_ob (m, x, y); tmp; tmp = tmp->above) 3577 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above)
3629 { 3578 {
3630 if ((player ||friendly) &&QUERY_FLAG (tmp, FLAG_MONSTER) && !QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE)) 3579 if ((player ||friendly) &&QUERY_FLAG (tmp, FLAG_MONSTER) && !QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE))
3631 return 1; 3580 return 1;
3632 else if (tmp->type == PLAYER) 3581 else if (tmp->type == PLAYER)
3633 { 3582 {
3687 3636
3688 /* only the viewable area the player sees is updated by LOS 3637 /* only the viewable area the player sees is updated by LOS
3689 * code, so we need to restrict ourselves to that range of values 3638 * code, so we need to restrict ourselves to that range of values
3690 * for any meaningful values. 3639 * for any meaningful values.
3691 */ 3640 */
3692 if (FABS (dx) <= (pl->contr->socket.mapx / 2) && 3641 if (FABS (dx) <= (pl->contr->socket->mapx / 2) &&
3693 FABS (dy) <= (pl->contr->socket.mapy / 2) && 3642 FABS (dy) <= (pl->contr->socket->mapy / 2) &&
3694 !pl->contr->blocked_los[dx + (pl->contr->socket.mapx / 2)][dy + (pl->contr->socket.mapy / 2)]) 3643 !pl->contr->blocked_los[dx + (pl->contr->socket->mapx / 2)][dy + (pl->contr->socket->mapy / 2)])
3695 return 1; 3644 return 1;
3696 op = op->more; 3645 op = op->more;
3697 } 3646 }
3698 return 0; 3647 return 0;
3699} 3648}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines