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.35 by root, Thu Dec 14 00:01:35 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 (NewSocket * 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
1061 { 1035 {
1062 char buf[MAX_BUF]; 1036 char buf[MAX_BUF];
1063 1037
1064 /* this must before then initial items are given */ 1038 /* this must before then initial items are given */
1065 esrv_new_player (op->contr, op->weight + op->carrying); 1039 esrv_new_player (op->contr, op->weight + op->carrying);
1040
1066 create_treasure (find_treasurelist ("starting_wealth"), op, 0, 0, 0); 1041 treasurelist *tl = find_treasurelist ("starting_wealth");
1042 if (tl)
1043 create_treasure (tl, op, 0, 0, 0);
1067 1044
1068 INVOKE_PLAYER (BIRTH, op->contr); 1045 INVOKE_PLAYER (BIRTH, op->contr);
1069 INVOKE_PLAYER (LOGIN, op->contr); 1046 INVOKE_PLAYER (LOGIN, op->contr);
1070 1047
1071 op->contr->state = ST_PLAYING; 1048 op->contr->state = ST_PLAYING;
1148 op->stats.grace = 0; 1125 op->stats.grace = 0;
1149 1126
1150 if (op->msg) 1127 if (op->msg)
1151 new_draw_info (NDI_BLUE, 0, op, op->msg); 1128 new_draw_info (NDI_BLUE, 0, op, op->msg);
1152 1129
1153 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");
1154 return 0; 1131 return 0;
1155} 1132}
1156 1133
1157int 1134int
1158key_confirm_quit (object *op, char key) 1135key_confirm_quit (object *op, char key)
1901 SET_ANIMATION (arrow, arrow->direction); 1878 SET_ANIMATION (arrow, arrow->direction);
1902 arrow->stats.sp = arrow->stats.wc; /* save original wc and dam */ 1879 arrow->stats.sp = arrow->stats.wc; /* save original wc and dam */
1903 arrow->stats.hp = arrow->stats.dam; 1880 arrow->stats.hp = arrow->stats.dam;
1904 arrow->stats.grace = arrow->attacktype; 1881 arrow->stats.grace = arrow->attacktype;
1905 if (arrow->slaying != NULL) 1882 if (arrow->slaying != NULL)
1906 arrow->spellarg = strdup_local (arrow->slaying); 1883 arrow->spellarg = strdup (arrow->slaying);
1907 1884
1908 /* Note that this was different for monsters - they got their level 1885 /* Note that this was different for monsters - they got their level
1909 * 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.
1910 */ 1887 */
1911 1888
2567 2544
2568 /* 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
2569 * the players time has been increased when doericserver has been 2546 * the players time has been increased when doericserver has been
2570 * called, so we recheck it here. 2547 * called, so we recheck it here.
2571 */ 2548 */
2572 HandleClient (&op->contr->socket, op->contr); 2549 op->contr->socket->handle_command ();
2573 if (op->speed_left < 0) 2550 if (op->speed_left < 0)
2574 return 0; 2551 return 0;
2575 2552
2576 if (op->direction && (op->contr->run_on || op->contr->fire_on)) 2553 if (op->direction && (op->contr->run_on || op->contr->fire_on))
2577 { 2554 {
2586 if (op->speed_left > 0) 2563 if (op->speed_left > 0)
2587 return 1; 2564 return 1;
2588 else 2565 else
2589 return 0; 2566 return 0;
2590 } 2567 }
2568
2591 return 0; 2569 return 0;
2592} 2570}
2593 2571
2594int 2572int
2595save_life (object *op) 2573save_life (object *op)
2596{ 2574{
2597 object *tmp;
2598
2599 if (!QUERY_FLAG (op, FLAG_LIFESAVE)) 2575 if (!QUERY_FLAG (op, FLAG_LIFESAVE))
2600 return 0; 2576 return 0;
2601 2577
2602 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 2578 for (object *tmp = op->inv; tmp; tmp = tmp->below)
2603 if (QUERY_FLAG (tmp, FLAG_APPLIED) && QUERY_FLAG (tmp, FLAG_LIFESAVE)) 2579 if (QUERY_FLAG (tmp, FLAG_APPLIED) && QUERY_FLAG (tmp, FLAG_LIFESAVE))
2604 { 2580 {
2605 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);
2606 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));
2607 2583
2618 op->stats.food = 999; 2594 op->stats.food = 999;
2619 2595
2620 fix_player (op); 2596 fix_player (op);
2621 return 1; 2597 return 1;
2622 } 2598 }
2599
2623 LOG (llevError, "Error: LIFESAVE set without applied object.\n"); 2600 LOG (llevError, "Error: LIFESAVE set without applied object.\n");
2624 CLEAR_FLAG (op, FLAG_LIFESAVE); 2601 CLEAR_FLAG (op, FLAG_LIFESAVE);
2625 enter_player_savebed (op); /* bring him home. */ 2602 enter_player_savebed (op); /* bring him home. */
2626 return 0; 2603 return 0;
2627} 2604}
2650 esrv_del_item (env->contr, op->count); 2627 esrv_del_item (env->contr, op->count);
2651 insert_ob_in_map (op, env->map, NULL, 0); 2628 insert_ob_in_map (op, env->map, NULL, 0);
2652 } 2629 }
2653 else if (op->inv) 2630 else if (op->inv)
2654 remove_unpaid_objects (op->inv, env); 2631 remove_unpaid_objects (op->inv, env);
2632
2655 op = next; 2633 op = next;
2656 } 2634 }
2657} 2635}
2658 2636
2659 2637
2674 strcpy (buf2, " R.I.P.\n\n"); 2652 strcpy (buf2, " R.I.P.\n\n");
2675 if (op->type == PLAYER) 2653 if (op->type == PLAYER)
2676 sprintf (buf, "%s the %s\n", &op->name, op->contr->title); 2654 sprintf (buf, "%s the %s\n", &op->name, op->contr->title);
2677 else 2655 else
2678 sprintf (buf, "%s\n", &op->name); 2656 sprintf (buf, "%s\n", &op->name);
2657
2679 strncat (buf2, " ", 20 - strlen (buf) / 2); 2658 strncat (buf2, " ", 20 - strlen (buf) / 2);
2680 strcat (buf2, buf); 2659 strcat (buf2, buf);
2681 if (op->type == PLAYER) 2660 if (op->type == PLAYER)
2682 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);
2683 else 2662 else
2684 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
2685 strncat (buf2, " ", 20 - strlen (buf) / 2); 2665 strncat (buf2, " ", 20 - strlen (buf) / 2);
2686 strcat (buf2, buf); 2666 strcat (buf2, buf);
2687 if (op->type == PLAYER) 2667 if (op->type == PLAYER)
2688 { 2668 {
2689 sprintf (buf, "by %s.\n\n", op->contr->killer); 2669 sprintf (buf, "by %s.\n\n", op->contr->killer);
2690 strncat (buf2, " ", 21 - strlen (buf) / 2); 2670 strncat (buf2, " ", 21 - strlen (buf) / 2);
2691 strcat (buf2, buf); 2671 strcat (buf2, buf);
2692 } 2672 }
2673
2693 strftime (buf, MAX_BUF, "%b %d %Y\n", localtime (&now)); 2674 strftime (buf, MAX_BUF, "%b %d %Y\n", localtime (&now));
2694 strncat (buf2, " ", 20 - strlen (buf) / 2); 2675 strncat (buf2, " ", 20 - strlen (buf) / 2);
2695 strcat (buf2, buf); 2676 strcat (buf2, buf);
2677
2696 return buf2; 2678 return buf2;
2697} 2679}
2698 2680
2699 2681
2700 2682
3647 3629
3648 /* only the viewable area the player sees is updated by LOS 3630 /* only the viewable area the player sees is updated by LOS
3649 * 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
3650 * for any meaningful values. 3632 * for any meaningful values.
3651 */ 3633 */
3652 if (FABS (dx) <= (pl->contr->socket.mapx / 2) && 3634 if (FABS (dx) <= (pl->contr->socket->mapx / 2) &&
3653 FABS (dy) <= (pl->contr->socket.mapy / 2) && 3635 FABS (dy) <= (pl->contr->socket->mapy / 2) &&
3654 !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)])
3655 return 1; 3637 return 1;
3656 op = op->more; 3638 op = op->more;
3657 } 3639 }
3658 return 0; 3640 return 0;
3659} 3641}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines