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.37 by root, Thu Dec 14 02:37:37 2006 UTC vs.
Revision 1.43 by root, Sat Dec 16 03:08:26 2006 UTC

21 The author can be reached via e-mail to <crossfire@schmorp.de> 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#include <pwd.h> 25#include <pwd.h>
26#ifndef __CEXTRACT__
27# include <sproto.h> 26#include <sproto.h>
28#endif
29#include <sounds.h> 27#include <sounds.h>
30#include <living.h> 28#include <living.h>
31#include <object.h> 29#include <object.h>
32#include <spells.h> 30#include <spells.h>
33#include <skills.h> 31#include <skills.h>
34#include <newclient.h>
35 32
36#ifdef COZY_SERVER 33#ifdef COZY_SERVER
37extern int same_party (partylist *a, partylist *b); 34extern int same_party (partylist *a, partylist *b);
38#endif 35#endif
39 36
206 * the one that is passed. 203 * the one that is passed.
207 */ 204 */
208static player * 205static player *
209get_player (player *p) 206get_player (player *p)
210{ 207{
211 object *op = arch_to_object (get_player_archetype (NULL)); 208 object *op = arch_to_object (get_player_archetype (0));
212 int i; 209 int i;
213
214 if (!p)
215 {
216 p = new player;
217
218 /* This adds the player in the linked list. There is extra
219 * complexity here because we want to add the new player at the
220 * end of the list - there is in fact no compelling reason that
221 * that needs to be done except for things like output of
222 * 'who'.
223 */
224 player *tmp = first_player;
225
226 while (tmp != NULL && tmp->next != NULL)
227 tmp = tmp->next;
228 if (tmp != NULL)
229 tmp->next = p;
230 else
231 first_player = p;
232
233 p->next = NULL;
234 }
235 210
236 /* Clears basically the entire player structure except 211 /* Clears basically the entire player structure except
237 * for next and socket. 212 * for next and socket.
238 */ 213 */
239 p->clear (); 214 p->clear ();
258 op->speed_left = 0.5; 233 op->speed_left = 0.5;
259 op->speed = 1.0; 234 op->speed = 1.0;
260 op->direction = 5; /* So player faces south */ 235 op->direction = 5; /* So player faces south */
261 op->stats.wc = 2; 236 op->stats.wc = 2;
262 op->run_away = 25; /* Then we panick... */ 237 op->run_away = 25; /* Then we panick... */
238
239 {
240 int oldmon = p->socket->monitor_spells; // what a hack
263 p->socket.monitor_spells = 0; /* Needed because esrv_update_spells( ) gets called by roll_stats */ 241 p->socket->monitor_spells = 0; /* Needed because esrv_update_spells( ) gets called by roll_stats */
264
265 roll_stats (op); 242 roll_stats (op);
243 p->socket->monitor_spells = oldmon;
244 }
266 p->state = ST_ROLL_STAT; 245 p->state = ST_ROLL_STAT;
267 clear_los (op); 246 clear_los (op);
268 247
269 p->gen_sp_armour = 10; 248 p->gen_sp_armour = 10;
270 p->last_speed = -1; 249 p->last_speed = -1;
292 for (i = 0; i < NUM_SKILLS; i++) 271 for (i = 0; i < NUM_SKILLS; i++)
293 { 272 {
294 p->last_skill_exp[i] = -1; 273 p->last_skill_exp[i] = -1;
295 p->last_skill_ob[i] = NULL; 274 p->last_skill_ob[i] = NULL;
296 } 275 }
276
297 for (i = 0; i < NROFATTACKS; i++) 277 for (i = 0; i < NROFATTACKS; i++)
298 {
299 p->last_resist[i] = -1; 278 p->last_resist[i] = -1;
300 } 279
301 p->last_stats.exp = -1; 280 p->last_stats.exp = -1;
302 p->last_weight = (uint32) - 1; 281 p->last_weight = (uint32) - 1;
303 282
304 p->socket.update_look = 0; 283 p->socket->update_look = 0;
305 p->socket.look_position = 0; 284 p->socket->look_position = 0;
285
306 return p; 286 return p;
307} 287}
308 288
309/* This loads the first map an puts the player on it. */ 289/* This loads the first map an puts the player on it. */
310static void 290static void
320 * All we can really get in this is some settings like host and display 300 * All we can really get in this is some settings like host and display
321 * mode. 301 * mode.
322 */ 302 */
323 303
324int 304int
325add_player (client_socket * ns) 305add_player (client *ns)
326{ 306{
327 player *p; 307 player *p = new player;
328 308
329 p = get_player (NULL);
330 p->socket = *ns; 309 p->socket = ns;
331 p->socket.faces_sent = (uint8 *) malloc (p->socket.faces_sent_len * sizeof (*p->socket.faces_sent)); 310 ns->pl = p;
332 311
333 if (p->socket.faces_sent == NULL) 312 p->next = first_player;
334 fatal (OUT_OF_MEMORY); 313 first_player = p;
335 314
336 memcpy (p->socket.faces_sent, ns->faces_sent, p->socket.faces_sent_len * sizeof (*p->socket.faces_sent)); 315 p = get_player (p);
337 /* Needed because the socket we just copied over needs to be cleared. 316
338 * Note that this can result in a client reset if there is partial data
339 * on the uncoming socket.
340 */
341 //TODO socket copying is EVIL, do not do this
342 p->socket.inbuf_len = 0;
343 set_first_map (p->ob); 317 set_first_map (p->ob);
344 318
345 CLEAR_FLAG (p->ob, FLAG_FRIENDLY); 319 CLEAR_FLAG (p->ob, FLAG_FRIENDLY);
346 add_friendly_object (p->ob); 320 add_friendly_object (p->ob);
347 send_rules (p->ob); 321 send_rules (p->ob);
715void 689void
716get_name (object *op) 690get_name (object *op)
717{ 691{
718 op->contr->write_buf[0] = '\0'; 692 op->contr->write_buf[0] = '\0';
719 op->contr->state = ST_GET_NAME; 693 op->contr->state = ST_GET_NAME;
720 send_query (&op->contr->socket, 0, "What is your name?\n:"); 694 send_query (op->contr->socket, 0, "What is your name?\n:");
721} 695}
722 696
723void 697void
724get_password (object *op) 698get_password (object *op)
725{ 699{
726 op->contr->write_buf[0] = '\0'; 700 op->contr->write_buf[0] = '\0';
727 op->contr->state = ST_GET_PASSWORD; 701 op->contr->state = ST_GET_PASSWORD;
728 send_query (&op->contr->socket, CS_QUERY_HIDEINPUT, "What is your password?\n:"); 702 send_query (op->contr->socket, CS_QUERY_HIDEINPUT, "What is your password?\n:");
729} 703}
730 704
731void 705void
732play_again (object *op) 706play_again (object *op)
733{ 707{
734 op->contr->state = ST_PLAY_AGAIN; 708 op->contr->state = ST_PLAY_AGAIN;
735 op->chosen_skill = NULL; 709 op->chosen_skill = NULL;
736 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, "Do you want to play again (a/q)?"); 710 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 711 /* a bit of a hack, but there are various places early in th
738 * player creation process that a user can quit (eg, roll 712 * player creation process that a user can quit (eg, roll
739 * stats) that isn't removing the player. Taking a quick 713 * stats) that isn't removing the player. Taking a quick
740 * look, there are many places that call play_again without 714 * look, there are many places that call play_again without
741 * removing the player - it probably makes more sense 715 * removing the player - it probably makes more sense
790confirm_password (object *op) 764confirm_password (object *op)
791{ 765{
792 766
793 op->contr->write_buf[0] = '\0'; 767 op->contr->write_buf[0] = '\0';
794 op->contr->state = ST_CONFIRM_PASSWORD; 768 op->contr->state = ST_CONFIRM_PASSWORD;
795 send_query (&op->contr->socket, CS_QUERY_HIDEINPUT, "Please type your password again.\n:"); 769 send_query (op->contr->socket, CS_QUERY_HIDEINPUT, "Please type your password again.\n:");
796} 770}
797 771
798void 772void
799get_party_password (object *op, partylist *party) 773get_party_password (object *op, partylist *party)
800{ 774{
804 return; 778 return;
805 } 779 }
806 op->contr->write_buf[0] = '\0'; 780 op->contr->write_buf[0] = '\0';
807 op->contr->state = ST_GET_PARTY_PASSWORD; 781 op->contr->state = ST_GET_PARTY_PASSWORD;
808 op->contr->party_to_join = party; 782 op->contr->party_to_join = party;
809 send_query (&op->contr->socket, CS_QUERY_HIDEINPUT, "What is the password?\n:"); 783 send_query (op->contr->socket, CS_QUERY_HIDEINPUT, "What is the password?\n:");
810} 784}
811 785
812 786
813/* This rolls four 1-6 rolls and sums the best 3 of the 4. */ 787/* This rolls four 1-6 rolls and sums the best 3 of the 4. */
814int 788int
911 885
912void 886void
913Roll_Again (object *op) 887Roll_Again (object *op)
914{ 888{
915 esrv_new_player (op->contr, 0); 889 esrv_new_player (op->contr, 0);
916 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, 890 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)? "); 891 "[y] to roll new stats [n] to use stats\n[1-7] [1-7] to swap stats.\nRoll again (y/n/1-7)? ");
918} 892}
919 893
920void 894void
921Swap_Stat (object *op, int Swap_Second) 895Swap_Stat (object *op, int Swap_Second)
988 new_draw_info (NDI_UNIQUE, 0, op, buf); 962 new_draw_info (NDI_UNIQUE, 0, op, buf);
989 } 963 }
990 else 964 else
991 Swap_Stat (op, stat_trans[keynum]); 965 Swap_Stat (op, stat_trans[keynum]);
992 966
993 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, ""); 967 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "");
994 return 1; 968 return 1;
995 } 969 }
996 switch (key) 970 switch (key)
997 { 971 {
998 case 'n': 972 case 'n':
1012 enter_exit (op, NULL); 986 enter_exit (op, NULL);
1013#endif 987#endif
1014 SET_ANIMATION (op, 2); /* So player faces south */ 988 SET_ANIMATION (op, 2); /* So player faces south */
1015 /* Enter exit adds a player otherwise */ 989 /* Enter exit adds a player otherwise */
1016 add_statbonus (op); 990 add_statbonus (op);
1017 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, 991 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"); 992 "Now choose a character.\nPress any key to change outlook.\nPress `d' when you're pleased.\n");
1019 op->contr->state = ST_CHANGE_CLASS; 993 op->contr->state = ST_CHANGE_CLASS;
1020 if (op->msg) 994 if (op->msg)
1021 new_draw_info (NDI_BLUE, 0, op, op->msg); 995 new_draw_info (NDI_BLUE, 0, op, op->msg);
1022 return 0; 996 return 0;
1023 } 997 }
1024 case 'y': 998 case 'y':
1025 case 'Y': 999 case 'Y':
1026 roll_stats (op); 1000 roll_stats (op);
1027 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, ""); 1001 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "");
1028 return 1; 1002 return 1;
1029 1003
1030 case 'q': 1004 case 'q':
1031 case 'Q': 1005 case 'Q':
1032 play_again (op); 1006 play_again (op);
1033 return 1; 1007 return 1;
1034 1008
1035 default: 1009 default:
1036 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, "Yes, No, Quit or 1-6. Roll again?"); 1010 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "Yes, No, Quit or 1-6. Roll again?");
1037 return 0; 1011 return 0;
1038 } 1012 }
1039 return 0; 1013 return 0;
1040} 1014}
1041 1015
1151 op->stats.grace = 0; 1125 op->stats.grace = 0;
1152 1126
1153 if (op->msg) 1127 if (op->msg)
1154 new_draw_info (NDI_BLUE, 0, op, op->msg); 1128 new_draw_info (NDI_BLUE, 0, op, op->msg);
1155 1129
1156 send_query (&op->contr->socket, CS_QUERY_SINGLECHAR, "Press any key for the next race.\nPress `d' to play this race.\n"); 1130 send_query (op->contr->socket, CS_QUERY_SINGLECHAR, "Press any key for the next race.\nPress `d' to play this race.\n");
1157 return 0; 1131 return 0;
1158} 1132}
1159 1133
1160int 1134int
1161key_confirm_quit (object *op, char key) 1135key_confirm_quit (object *op, char key)
1904 SET_ANIMATION (arrow, arrow->direction); 1878 SET_ANIMATION (arrow, arrow->direction);
1905 arrow->stats.sp = arrow->stats.wc; /* save original wc and dam */ 1879 arrow->stats.sp = arrow->stats.wc; /* save original wc and dam */
1906 arrow->stats.hp = arrow->stats.dam; 1880 arrow->stats.hp = arrow->stats.dam;
1907 arrow->stats.grace = arrow->attacktype; 1881 arrow->stats.grace = arrow->attacktype;
1908 if (arrow->slaying != NULL) 1882 if (arrow->slaying != NULL)
1909 arrow->spellarg = strdup_local (arrow->slaying); 1883 arrow->spellarg = strdup (arrow->slaying);
1910 1884
1911 /* Note that this was different for monsters - they got their level 1885 /* Note that this was different for monsters - they got their level
1912 * added to the damage. I think the strength bonus is more proper. 1886 * added to the damage. I think the strength bonus is more proper.
1913 */ 1887 */
1914 1888
2570 2544
2571 /* call this here - we also will call this in do_ericserver, but 2545 /* call this here - we also will call this in do_ericserver, but
2572 * the players time has been increased when doericserver has been 2546 * the players time has been increased when doericserver has been
2573 * called, so we recheck it here. 2547 * called, so we recheck it here.
2574 */ 2548 */
2575 HandleClient (&op->contr->socket, op->contr); 2549 op->contr->socket->handle_command ();
2576 if (op->speed_left < 0) 2550 if (op->speed_left < 0)
2577 return 0; 2551 return 0;
2578 2552
2579 if (op->direction && (op->contr->run_on || op->contr->fire_on)) 2553 if (op->direction && (op->contr->run_on || op->contr->fire_on))
2580 { 2554 {
2589 if (op->speed_left > 0) 2563 if (op->speed_left > 0)
2590 return 1; 2564 return 1;
2591 else 2565 else
2592 return 0; 2566 return 0;
2593 } 2567 }
2568
2594 return 0; 2569 return 0;
2595} 2570}
2596 2571
2597int 2572int
2598save_life (object *op) 2573save_life (object *op)
2599{ 2574{
2600 object *tmp;
2601
2602 if (!QUERY_FLAG (op, FLAG_LIFESAVE)) 2575 if (!QUERY_FLAG (op, FLAG_LIFESAVE))
2603 return 0; 2576 return 0;
2604 2577
2605 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 2578 for (object *tmp = op->inv; tmp; tmp = tmp->below)
2606 if (QUERY_FLAG (tmp, FLAG_APPLIED) && QUERY_FLAG (tmp, FLAG_LIFESAVE)) 2579 if (QUERY_FLAG (tmp, FLAG_APPLIED) && QUERY_FLAG (tmp, FLAG_LIFESAVE))
2607 { 2580 {
2608 play_sound_map (op->map, op->x, op->y, SOUND_OB_EVAPORATE); 2581 play_sound_map (op->map, op->x, op->y, SOUND_OB_EVAPORATE);
2609 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s vibrates violently, then evaporates.", query_name (tmp)); 2582 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s vibrates violently, then evaporates.", query_name (tmp));
2610 2583
2621 op->stats.food = 999; 2594 op->stats.food = 999;
2622 2595
2623 fix_player (op); 2596 fix_player (op);
2624 return 1; 2597 return 1;
2625 } 2598 }
2599
2626 LOG (llevError, "Error: LIFESAVE set without applied object.\n"); 2600 LOG (llevError, "Error: LIFESAVE set without applied object.\n");
2627 CLEAR_FLAG (op, FLAG_LIFESAVE); 2601 CLEAR_FLAG (op, FLAG_LIFESAVE);
2628 enter_player_savebed (op); /* bring him home. */ 2602 enter_player_savebed (op); /* bring him home. */
2629 return 0; 2603 return 0;
2630} 2604}
2653 esrv_del_item (env->contr, op->count); 2627 esrv_del_item (env->contr, op->count);
2654 insert_ob_in_map (op, env->map, NULL, 0); 2628 insert_ob_in_map (op, env->map, NULL, 0);
2655 } 2629 }
2656 else if (op->inv) 2630 else if (op->inv)
2657 remove_unpaid_objects (op->inv, env); 2631 remove_unpaid_objects (op->inv, env);
2632
2658 op = next; 2633 op = next;
2659 } 2634 }
2660} 2635}
2661 2636
2662 2637
2677 strcpy (buf2, " R.I.P.\n\n"); 2652 strcpy (buf2, " R.I.P.\n\n");
2678 if (op->type == PLAYER) 2653 if (op->type == PLAYER)
2679 sprintf (buf, "%s the %s\n", &op->name, op->contr->title); 2654 sprintf (buf, "%s the %s\n", &op->name, op->contr->title);
2680 else 2655 else
2681 sprintf (buf, "%s\n", &op->name); 2656 sprintf (buf, "%s\n", &op->name);
2657
2682 strncat (buf2, " ", 20 - strlen (buf) / 2); 2658 strncat (buf2, " ", 20 - strlen (buf) / 2);
2683 strcat (buf2, buf); 2659 strcat (buf2, buf);
2684 if (op->type == PLAYER) 2660 if (op->type == PLAYER)
2685 sprintf (buf, "who was in level %d when killed\n", op->level); 2661 sprintf (buf, "who was in level %d when killed\n", op->level);
2686 else 2662 else
2687 sprintf (buf, "who was in level %d when died.\n\n", op->level); 2663 sprintf (buf, "who was in level %d when died.\n\n", op->level);
2664
2688 strncat (buf2, " ", 20 - strlen (buf) / 2); 2665 strncat (buf2, " ", 20 - strlen (buf) / 2);
2689 strcat (buf2, buf); 2666 strcat (buf2, buf);
2690 if (op->type == PLAYER) 2667 if (op->type == PLAYER)
2691 { 2668 {
2692 sprintf (buf, "by %s.\n\n", op->contr->killer); 2669 sprintf (buf, "by %s.\n\n", op->contr->killer);
2693 strncat (buf2, " ", 21 - strlen (buf) / 2); 2670 strncat (buf2, " ", 21 - strlen (buf) / 2);
2694 strcat (buf2, buf); 2671 strcat (buf2, buf);
2695 } 2672 }
2673
2696 strftime (buf, MAX_BUF, "%b %d %Y\n", localtime (&now)); 2674 strftime (buf, MAX_BUF, "%b %d %Y\n", localtime (&now));
2697 strncat (buf2, " ", 20 - strlen (buf) / 2); 2675 strncat (buf2, " ", 20 - strlen (buf) / 2);
2698 strcat (buf2, buf); 2676 strcat (buf2, buf);
2677
2699 return buf2; 2678 return buf2;
2700} 2679}
2701 2680
2702 2681
2703 2682
3650 3629
3651 /* only the viewable area the player sees is updated by LOS 3630 /* only the viewable area the player sees is updated by LOS
3652 * code, so we need to restrict ourselves to that range of values 3631 * code, so we need to restrict ourselves to that range of values
3653 * for any meaningful values. 3632 * for any meaningful values.
3654 */ 3633 */
3655 if (FABS (dx) <= (pl->contr->socket.mapx / 2) && 3634 if (FABS (dx) <= (pl->contr->socket->mapx / 2) &&
3656 FABS (dy) <= (pl->contr->socket.mapy / 2) && 3635 FABS (dy) <= (pl->contr->socket->mapy / 2) &&
3657 !pl->contr->blocked_los[dx + (pl->contr->socket.mapx / 2)][dy + (pl->contr->socket.mapy / 2)]) 3636 !pl->contr->blocked_los[dx + (pl->contr->socket->mapx / 2)][dy + (pl->contr->socket->mapy / 2)])
3658 return 1; 3637 return 1;
3659 op = op->more; 3638 op = op->more;
3660 } 3639 }
3661 return 0; 3640 return 0;
3662} 3641}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines