1 | /* |
1 | /* |
2 | * static char *rcsid_player_c = |
2 | * static char *rcsid_player_c = |
3 | * "$Id: player.C,v 1.13 2006/09/01 14:12:04 pippijn Exp $"; |
3 | * "$Id: player.C,v 1.14 2006/09/03 00:18:42 root Exp $"; |
4 | */ |
4 | */ |
5 | |
5 | |
6 | /* |
6 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
7 | CrossFire, A Multiplayer game for X-windows |
8 | |
8 | |
… | |
… | |
202 | static player* get_player(player *p) { |
202 | static player* get_player(player *p) { |
203 | object *op=arch_to_object(get_player_archetype(NULL)); |
203 | object *op=arch_to_object(get_player_archetype(NULL)); |
204 | int i; |
204 | int i; |
205 | |
205 | |
206 | if (!p) { |
206 | if (!p) { |
207 | p = (player *) malloc(sizeof(player)); |
207 | p = new player; |
208 | if(p==NULL) |
|
|
209 | fatal(OUT_OF_MEMORY); |
|
|
210 | |
208 | |
211 | /* This adds the player in the linked list. There is extra |
209 | /* This adds the player in the linked list. There is extra |
212 | * complexity here because we want to add the new player at the |
210 | * complexity here because we want to add the new player at the |
213 | * end of the list - there is in fact no compelling reason that |
211 | * end of the list - there is in fact no compelling reason that |
214 | * that needs to be done except for things like output of |
212 | * that needs to be done except for things like output of |
… | |
… | |
234 | /* There are some elements we want initialized to non zero value - |
232 | /* There are some elements we want initialized to non zero value - |
235 | * we deal with that below this point. |
233 | * we deal with that below this point. |
236 | */ |
234 | */ |
237 | p->party=NULL; |
235 | p->party=NULL; |
238 | p->outputs_sync=16; /* Every 2 seconds */ |
236 | p->outputs_sync=16; /* Every 2 seconds */ |
239 | p->outputs_count=1; /* Keeps present behaviour */ |
237 | p->outputs_count=8; /* Keeps present behaviour */ |
240 | p->unapply = unapply_nochoice; |
238 | p->unapply = unapply_nochoice; |
241 | p->Swap_First = -1; |
239 | p->Swap_First = -1; |
242 | |
240 | |
243 | #ifdef AUTOSAVE |
241 | #ifdef AUTOSAVE |
244 | p->last_save_tick = 9999999; |
242 | p->last_save_tick = 9999999; |
… | |
… | |
272 | p->explore=0; |
270 | p->explore=0; |
273 | p->no_shout=0; /* default can shout */ |
271 | p->no_shout=0; /* default can shout */ |
274 | |
272 | |
275 | strncpy(p->title, op->arch->clone.name, sizeof(p->title)-1); |
273 | strncpy(p->title, op->arch->clone.name, sizeof(p->title)-1); |
276 | p->title[sizeof(p->title)-1] = '\0'; |
274 | p->title[sizeof(p->title)-1] = '\0'; |
277 | op->race = add_string (op->arch->clone.race); |
275 | op->race = op->arch->clone.race; |
278 | |
276 | |
279 | CLEAR_FLAG(op,FLAG_READY_SKILL); |
277 | CLEAR_FLAG(op,FLAG_READY_SKILL); |
280 | |
278 | |
281 | /* we need to clear these to -1 and not zero - otherwise, |
279 | /* we need to clear these to -1 and not zero - otherwise, |
282 | * if a player quits and starts a new character, we wont |
280 | * if a player quits and starts a new character, we wont |
… | |
… | |
409 | lastdist=rv.distance; |
407 | lastdist=rv.distance; |
410 | } |
408 | } |
411 | } |
409 | } |
412 | } |
410 | } |
413 | #if 0 |
411 | #if 0 |
414 | LOG(llevDebug,"get_nearest_player() finds player: %s\n",op?op->name:"(null)"); |
412 | LOG(llevDebug,"get_nearest_player() finds player: %s\n",op?&op->name:"(null)"); |
415 | #endif |
413 | #endif |
416 | return op; |
414 | return op; |
417 | } |
415 | } |
418 | |
416 | |
419 | /* I believe this can safely go to 2, 3 is questionable, 4 will likely |
417 | /* I believe this can safely go to 2, 3 is questionable, 4 will likely |
… | |
… | |
615 | |
613 | |
616 | if (tmp) { |
614 | if (tmp) { |
617 | remove_ob(op); |
615 | remove_ob(op); |
618 | free_object(op); |
616 | free_object(op); |
619 | LOG(llevError,"give_initial_items: Removing duplicate object %s\n", |
617 | LOG(llevError,"give_initial_items: Removing duplicate object %s\n", |
620 | tmp->name); |
618 | &tmp->name); |
621 | continue; |
619 | continue; |
622 | } |
620 | } |
623 | if (op->nrof > 1) op->nrof = 1; |
621 | if (op->nrof > 1) op->nrof = 1; |
624 | } |
622 | } |
625 | |
623 | |
… | |
… | |
696 | leave(op->contr,0); /* ericserver will draw the message */ |
694 | leave(op->contr,0); /* ericserver will draw the message */ |
697 | return 2; |
695 | return 2; |
698 | } |
696 | } |
699 | else if(key=='a'||key=='A') { |
697 | else if(key=='a'||key=='A') { |
700 | player *pl = op->contr; |
698 | player *pl = op->contr; |
701 | const char *name = op->name; |
699 | shstr name = op->name; |
702 | |
700 | |
703 | add_refcount(name); |
|
|
704 | remove_friendly_object(op); |
701 | remove_friendly_object(op); |
705 | free_object(op); |
702 | free_object(op); |
706 | pl = get_player(pl); |
703 | pl = get_player(pl); |
707 | op = pl->ob; |
704 | op = pl->ob; |
708 | add_friendly_object(op); |
705 | add_friendly_object(op); |
709 | op->contr->password[0]='~'; |
706 | op->contr->password[0]='~'; |
710 | FREE_AND_CLEAR_STR(op->name); |
707 | op->name = op->name_pl = 0; |
711 | FREE_AND_CLEAR_STR(op->name_pl); |
|
|
712 | |
|
|
713 | /* Lets put a space in here */ |
708 | /* Lets put a space in here */ |
714 | new_draw_info(NDI_UNIQUE, 0, op, "\n"); |
709 | new_draw_info(NDI_UNIQUE, 0, op, "\n"); |
715 | get_name(op); |
710 | get_name(op); |
716 | op->name = name; /* Alrady added a refcount above */ |
711 | op->name = op->name_pl = name; |
717 | op->name_pl = add_string(name); |
|
|
718 | set_first_map(op); |
712 | set_first_map(op); |
719 | } else { |
713 | } else { |
720 | /* user pressed something else so just ask again... */ |
714 | /* user pressed something else so just ask again... */ |
721 | play_again(op); |
715 | play_again(op); |
722 | } |
716 | } |
… | |
… | |
730 | send_query(&op->contr->socket, CS_QUERY_HIDEINPUT, "Please type your password again.\n:"); |
724 | send_query(&op->contr->socket, CS_QUERY_HIDEINPUT, "Please type your password again.\n:"); |
731 | } |
725 | } |
732 | |
726 | |
733 | void get_party_password(object *op, partylist *party) { |
727 | void get_party_password(object *op, partylist *party) { |
734 | if (party == NULL) { |
728 | if (party == NULL) { |
735 | LOG(llevError, "get_party_password(): tried to make player %s join a NULL party", op->name); |
729 | LOG(llevError, "get_party_password(): tried to make player %s join a NULL party", &op->name); |
736 | return; |
730 | return; |
737 | } |
731 | } |
738 | op->contr->write_buf[0]='\0'; |
732 | op->contr->write_buf[0]='\0'; |
739 | op->contr->state=ST_GET_PARTY_PASSWORD; |
733 | op->contr->state=ST_GET_PARTY_PASSWORD; |
740 | op->contr->party_to_join = party; |
734 | op->contr->party_to_join = party; |
… | |
… | |
977 | INVOKE_PLAYER (BIRTH, op->contr); |
971 | INVOKE_PLAYER (BIRTH, op->contr); |
978 | INVOKE_PLAYER (LOGIN, op->contr); |
972 | INVOKE_PLAYER (LOGIN, op->contr); |
979 | |
973 | |
980 | op->contr->state=ST_PLAYING; |
974 | op->contr->state=ST_PLAYING; |
981 | |
975 | |
982 | if (op->msg) { |
976 | if (op->msg) |
983 | free_string(op->msg); |
|
|
984 | op->msg=NULL; |
977 | op->msg=NULL; |
985 | } |
|
|
986 | |
978 | |
987 | /* We create this now because some of the unique maps will need it |
979 | /* We create this now because some of the unique maps will need it |
988 | * to save here. |
980 | * to save here. |
989 | */ |
981 | */ |
990 | sprintf(buf,"%s/%s/%s",settings.localdir,settings.playerdir,op->name); |
982 | sprintf(buf,"%s/%s/%s",settings.localdir,settings.playerdir,&op->name); |
991 | make_path_to_file(buf); |
983 | make_path_to_file(buf); |
992 | |
984 | |
993 | #ifdef AUTOSAVE |
985 | #ifdef AUTOSAVE |
994 | op->contr->last_save_tick = pticks; |
986 | op->contr->last_save_tick = pticks; |
995 | #endif |
987 | #endif |
… | |
… | |
1006 | if(*first_map_ext_path) { |
998 | if(*first_map_ext_path) { |
1007 | object *tmp; |
999 | object *tmp; |
1008 | mapstruct *oldmap = op->map; |
1000 | mapstruct *oldmap = op->map; |
1009 | char mapname[MAX_BUF]; |
1001 | char mapname[MAX_BUF]; |
1010 | snprintf(mapname, MAX_BUF-1, "%s/%s", |
1002 | snprintf(mapname, MAX_BUF-1, "%s/%s", |
1011 | first_map_ext_path, op->arch->name); |
1003 | first_map_ext_path, &op->arch->name); |
1012 | tmp=get_object(); |
1004 | tmp=get_object(); |
1013 | EXIT_PATH(tmp) = add_string(mapname); |
1005 | EXIT_PATH(tmp) = mapname; |
1014 | EXIT_X(tmp) = op->x; |
1006 | EXIT_X(tmp) = op->x; |
1015 | EXIT_Y(tmp) = op->y; |
1007 | EXIT_Y(tmp) = op->y; |
1016 | enter_exit(op,tmp); /* we don't really care if it succeeded; |
1008 | enter_exit(op,tmp); /* we don't really care if it succeeded; |
1017 | * if the map isn't there, then stay on the |
1009 | * if the map isn't there, then stay on the |
1018 | * default initial map */ |
1010 | * default initial map */ |
… | |
… | |
1027 | * if we don't match with one of the options above. |
1019 | * if we don't match with one of the options above. |
1028 | */ |
1020 | */ |
1029 | |
1021 | |
1030 | tmp_loop = 0; |
1022 | tmp_loop = 0; |
1031 | while(!tmp_loop) { |
1023 | while(!tmp_loop) { |
1032 | const char *name = add_string (op->name); |
1024 | shstr name = op->name; |
1033 | int x = op->x, y = op->y; |
1025 | int x = op->x, y = op->y; |
1034 | remove_statbonus(op); |
1026 | remove_statbonus(op); |
1035 | remove_ob (op); |
1027 | remove_ob (op); |
1036 | op->arch = get_player_archetype(op->arch); |
1028 | op->arch = get_player_archetype(op->arch); |
1037 | copy_object (&op->arch->clone, op); |
1029 | copy_object (&op->arch->clone, op); |
1038 | op->instantiate (); |
1030 | op->instantiate (); |
1039 | op->stats = op->contr->orig_stats; |
1031 | op->stats = op->contr->orig_stats; |
1040 | free_string (op->name); |
|
|
1041 | op->name = name; |
1032 | op->name = op->name_pl = name; |
1042 | free_string(op->name_pl); |
|
|
1043 | op->name_pl = add_string(name); |
|
|
1044 | op->x = x; |
1033 | op->x = x; |
1045 | op->y = y; |
1034 | op->y = y; |
1046 | SET_ANIMATION(op, 2); /* So player faces south */ |
1035 | SET_ANIMATION(op, 2); /* So player faces south */ |
1047 | insert_ob_in_map (op, op->map, op,0); |
1036 | insert_ob_in_map (op, op->map, op,0); |
1048 | strncpy(op->contr->title, op->arch->clone.name, sizeof(op->contr->title)-1); |
1037 | strncpy(op->contr->title, op->arch->clone.name, sizeof(op->contr->title)-1); |
… | |
… | |
1077 | |
1066 | |
1078 | terminate_all_pets(op); |
1067 | terminate_all_pets(op); |
1079 | leave_map(op); |
1068 | leave_map(op); |
1080 | op->direction=0; |
1069 | op->direction=0; |
1081 | new_draw_info_format(NDI_UNIQUE | NDI_ALL, 5, NULL, |
1070 | new_draw_info_format(NDI_UNIQUE | NDI_ALL, 5, NULL, |
1082 | "%s quits the game.",op->name); |
1071 | "%s quits the game.", &op->name); |
1083 | |
1072 | |
1084 | strcpy(op->contr->killer,"quit"); |
1073 | strcpy(op->contr->killer,"quit"); |
1085 | check_score(op); |
1074 | check_score(op); |
1086 | op->contr->party=NULL; |
1075 | op->contr->party=NULL; |
1087 | if (settings.set_title == TRUE) |
1076 | if (settings.set_title == TRUE) |
… | |
… | |
1092 | |
1081 | |
1093 | /* We need to hunt for any per player unique maps in memory and |
1082 | /* We need to hunt for any per player unique maps in memory and |
1094 | * get rid of them. The trailing slash in the path is intentional, |
1083 | * get rid of them. The trailing slash in the path is intentional, |
1095 | * so that players named 'Ab' won't match against players 'Abe' pathname |
1084 | * so that players named 'Ab' won't match against players 'Abe' pathname |
1096 | */ |
1085 | */ |
1097 | sprintf(buf,"%s/%s/%s/", settings.localdir, settings.playerdir, op->name); |
1086 | sprintf(buf,"%s/%s/%s/", settings.localdir, settings.playerdir, &op->name); |
1098 | for (mp=first_map; mp!=NULL; mp=next) { |
1087 | for (mp=first_map; mp!=NULL; mp=next) { |
1099 | next = mp->next; |
1088 | next = mp->next; |
1100 | if (!strncmp(mp->path, buf, strlen(buf))) |
1089 | if (!strncmp(mp->path, buf, strlen(buf))) |
1101 | delete_map(mp); |
1090 | delete_map(mp); |
1102 | } |
1091 | } |
… | |
… | |
1237 | if(op->contr->mode & PU_DEBUG) |
1226 | if(op->contr->mode & PU_DEBUG) |
1238 | { |
1227 | { |
1239 | /* some debugging code to figure out item information */ |
1228 | /* some debugging code to figure out item information */ |
1240 | if(tmp->name!=NULL) |
1229 | if(tmp->name!=NULL) |
1241 | sprintf(putstring,"item name: %s item type: %d weight/value: %d", |
1230 | sprintf(putstring,"item name: %s item type: %d weight/value: %d", |
1242 | tmp->name, tmp->type, |
1231 | &tmp->name, tmp->type, |
1243 | (int)(query_cost(tmp, op, F_TRUE)*100 / (tmp->weight * MAX(tmp->nrof,1)))); |
1232 | (int)(query_cost(tmp, op, F_TRUE)*100 / (tmp->weight * MAX(tmp->nrof,1)))); |
1244 | else |
1233 | else |
1245 | sprintf(putstring,"item name: %s item type: %d weight/value: %d", |
1234 | sprintf(putstring,"item name: %s item type: %d weight/value: %d", |
1246 | tmp->arch->name, tmp->type, |
1235 | &tmp->arch->name, tmp->type, |
1247 | (int)(query_cost(tmp, op, F_TRUE)*100 / (tmp->weight * MAX(tmp->nrof,1)))); |
1236 | (int)(query_cost(tmp, op, F_TRUE)*100 / (tmp->weight * MAX(tmp->nrof,1)))); |
1248 | new_draw_info(NDI_UNIQUE, 0,op,putstring); |
1237 | new_draw_info(NDI_UNIQUE, 0,op,putstring); |
1249 | |
1238 | |
1250 | sprintf(putstring,"...flags: "); |
1239 | sprintf(putstring,"...flags: "); |
1251 | for(k=0;k<4;k++) |
1240 | for(k=0;k<4;k++) |
… | |
… | |
1611 | */ |
1600 | */ |
1612 | if(bow->type==BOW) |
1601 | if(bow->type==BOW) |
1613 | break; |
1602 | break; |
1614 | |
1603 | |
1615 | if (!bow) { |
1604 | if (!bow) { |
1616 | LOG (llevError, "Range: bow without activated bow (%s).\n", op->name); |
1605 | LOG (llevError, "Range: bow without activated bow (%s).\n", &op->name); |
1617 | return 0; |
1606 | return 0; |
1618 | } |
1607 | } |
1619 | } |
1608 | } |
1620 | if( !bow->race || !bow->skill) { |
1609 | if( !bow->race || !bow->skill) { |
1621 | new_draw_info_format(NDI_UNIQUE, 0, op, "Your %s is broken.", bow->name); |
1610 | new_draw_info_format(NDI_UNIQUE, 0, op, "Your %s is broken.", &bow->name); |
1622 | return 0; |
1611 | return 0; |
1623 | } |
1612 | } |
1624 | |
1613 | |
1625 | bowspeed = bow->stats.sp + dex_bonus[op->stats.Dex]; |
1614 | bowspeed = bow->stats.sp + dex_bonus[op->stats.Dex]; |
1626 | |
1615 | |
… | |
… | |
1632 | |
1621 | |
1633 | if (arrow == NULL) { |
1622 | if (arrow == NULL) { |
1634 | if ((arrow=find_arrow(op, bow->race)) == NULL) { |
1623 | if ((arrow=find_arrow(op, bow->race)) == NULL) { |
1635 | if (op->type == PLAYER) |
1624 | if (op->type == PLAYER) |
1636 | new_draw_info_format(NDI_UNIQUE, 0, op, |
1625 | new_draw_info_format(NDI_UNIQUE, 0, op, |
1637 | "You have no %s left.", bow->race); |
1626 | "You have no %s left.", &bow->race); |
1638 | /* FLAG_READY_BOW will get reset if the monsters picks up some arrows */ |
1627 | /* FLAG_READY_BOW will get reset if the monsters picks up some arrows */ |
1639 | else |
1628 | else |
1640 | CLEAR_FLAG(op, FLAG_READY_BOW); |
1629 | CLEAR_FLAG(op, FLAG_READY_BOW); |
1641 | return 0; |
1630 | return 0; |
1642 | } |
1631 | } |
… | |
… | |
1659 | |
1648 | |
1660 | left = arrow; /* these are arrows left to the player */ |
1649 | left = arrow; /* these are arrows left to the player */ |
1661 | left_tag = left->count; |
1650 | left_tag = left->count; |
1662 | arrow = get_split_ob(arrow, 1); |
1651 | arrow = get_split_ob(arrow, 1); |
1663 | if (arrow == NULL) { |
1652 | if (arrow == NULL) { |
1664 | new_draw_info_format(NDI_UNIQUE, 0, op, "You have no %s left.", |
1653 | new_draw_info_format(NDI_UNIQUE, 0, op, "You have no %s left.", &bow->race); |
1665 | bow->race); |
|
|
1666 | return 0; |
1654 | return 0; |
1667 | } |
1655 | } |
1668 | set_owner(arrow, op); |
1656 | set_owner(arrow, op); |
1669 | if (arrow->skill) free_string(arrow->skill); |
|
|
1670 | arrow->skill = add_refcount(bow->skill); |
1657 | arrow->skill = bow->skill; |
1671 | |
1658 | |
1672 | arrow->direction=dir; |
1659 | arrow->direction=dir; |
1673 | arrow->x = sx; |
1660 | arrow->x = sx; |
1674 | arrow->y = sy; |
1661 | arrow->y = sy; |
1675 | |
1662 | |
… | |
… | |
1718 | arrow->level = op->level; |
1705 | arrow->level = op->level; |
1719 | } |
1706 | } |
1720 | if (arrow->attacktype == AT_PHYSICAL) |
1707 | if (arrow->attacktype == AT_PHYSICAL) |
1721 | arrow->attacktype |= bow->attacktype; |
1708 | arrow->attacktype |= bow->attacktype; |
1722 | if (bow->slaying != NULL) |
1709 | if (bow->slaying != NULL) |
1723 | arrow->slaying = add_string(bow->slaying); |
1710 | arrow->slaying = bow->slaying; |
1724 | |
1711 | |
1725 | arrow->map = m; |
1712 | arrow->map = m; |
1726 | arrow->move_type = MOVE_FLY_LOW; |
1713 | arrow->move_type = MOVE_FLY_LOW; |
1727 | arrow->move_on = MOVE_FLY_LOW | MOVE_WALK; |
1714 | arrow->move_on = MOVE_FLY_LOW | MOVE_WALK; |
1728 | |
1715 | |
… | |
… | |
1791 | return; |
1778 | return; |
1792 | } |
1779 | } |
1793 | |
1780 | |
1794 | item = op->contr->ranges[range_misc]; |
1781 | item = op->contr->ranges[range_misc]; |
1795 | if (!item->inv) { |
1782 | if (!item->inv) { |
1796 | LOG(llevError,"Object %s lacks a spell\n", item->name); |
1783 | LOG(llevError,"Object %s lacks a spell\n", &item->name); |
1797 | return; |
1784 | return; |
1798 | } |
1785 | } |
1799 | if (item->type == WAND) { |
1786 | if (item->type == WAND) { |
1800 | if(item->stats.food<=0) { |
1787 | if(item->stats.food<=0) { |
1801 | play_sound_player_only(op->contr, SOUND_WAND_POOF,0,0); |
1788 | play_sound_player_only(op->contr, SOUND_WAND_POOF,0,0); |
… | |
… | |
2366 | char buf[MAX_BUF]; |
2353 | char buf[MAX_BUF]; |
2367 | time_t now = time (NULL); |
2354 | time_t now = time (NULL); |
2368 | |
2355 | |
2369 | strcpy (buf2, " R.I.P.\n\n"); |
2356 | strcpy (buf2, " R.I.P.\n\n"); |
2370 | if (op->type == PLAYER) |
2357 | if (op->type == PLAYER) |
2371 | sprintf (buf, "%s the %s\n", op->name, op->contr->title); |
2358 | sprintf (buf, "%s the %s\n", &op->name, op->contr->title); |
2372 | else |
2359 | else |
2373 | sprintf (buf, "%s\n", op->name); |
2360 | sprintf (buf, "%s\n", &op->name); |
2374 | strncat (buf2, " ", 20 - strlen (buf) / 2); |
2361 | strncat (buf2, " ", 20 - strlen (buf) / 2); |
2375 | strcat (buf2, buf); |
2362 | strcat (buf2, buf); |
2376 | if (op->type == PLAYER) |
2363 | if (op->type == PLAYER) |
2377 | sprintf (buf, "who was in level %d when killed\n", op->level); |
2364 | sprintf (buf, "who was in level %d when killed\n", op->level); |
2378 | else |
2365 | else |
… | |
… | |
2624 | |
2611 | |
2625 | /* create a bodypart-trophy to make the winner happy */ |
2612 | /* create a bodypart-trophy to make the winner happy */ |
2626 | tmp=arch_to_object(find_archetype("finger")); |
2613 | tmp=arch_to_object(find_archetype("finger")); |
2627 | if (tmp != NULL) |
2614 | if (tmp != NULL) |
2628 | { |
2615 | { |
2629 | sprintf(buf,"%s's finger",op->name); |
2616 | sprintf(buf,"%s's finger", &op->name); |
2630 | tmp->name = add_string(buf); |
2617 | tmp->name = buf; |
2631 | sprintf(buf," This finger has been cut off %s\n" |
2618 | sprintf(buf," This finger has been cut off %s\n" |
2632 | " the %s, when he was defeated at\n level %d by %s.\n", |
2619 | " the %s, when he was defeated at\n level %d by %s.\n", |
2633 | op->name, op->contr->title, (int)(op->level), |
2620 | &op->name, op->contr->title, (int)(op->level), |
2634 | op->contr->killer); |
2621 | op->contr->killer); |
2635 | tmp->msg=add_string(buf); |
2622 | tmp->msg=buf; |
2636 | tmp->value=0, tmp->material=0, tmp->type=0; |
2623 | tmp->value=0, tmp->material=0, tmp->type=0; |
2637 | tmp->materialname = NULL; |
2624 | tmp->materialname = NULL; |
2638 | tmp->x = op->x, tmp->y = op->y; |
2625 | tmp->x = op->x, tmp->y = op->y; |
2639 | insert_ob_in_map(tmp,op->map,op,0); |
2626 | insert_ob_in_map(tmp,op->map,op,0); |
2640 | } |
2627 | } |
… | |
… | |
2654 | new_draw_info(NDI_UNIQUE, 0,op,"You would have starved, but you are"); |
2641 | new_draw_info(NDI_UNIQUE, 0,op,"You would have starved, but you are"); |
2655 | new_draw_info(NDI_UNIQUE, 0,op,"in explore mode, so..."); |
2642 | new_draw_info(NDI_UNIQUE, 0,op,"in explore mode, so..."); |
2656 | op->stats.food=999; |
2643 | op->stats.food=999; |
2657 | return; |
2644 | return; |
2658 | } |
2645 | } |
2659 | sprintf(buf,"%s starved to death.",op->name); |
2646 | sprintf(buf,"%s starved to death.",&op->name); |
2660 | strcpy(op->contr->killer,"starvation"); |
2647 | strcpy(op->contr->killer,"starvation"); |
2661 | } |
2648 | } |
2662 | else { |
2649 | else { |
2663 | if (op->contr->explore) { |
2650 | if (op->contr->explore) { |
2664 | new_draw_info(NDI_UNIQUE, 0,op,"You would have died, but you are"); |
2651 | new_draw_info(NDI_UNIQUE, 0,op,"You would have died, but you are"); |
2665 | new_draw_info(NDI_UNIQUE, 0,op,"in explore mode, so..."); |
2652 | new_draw_info(NDI_UNIQUE, 0,op,"in explore mode, so..."); |
2666 | op->stats.hp=op->stats.maxhp; |
2653 | op->stats.hp=op->stats.maxhp; |
2667 | return; |
2654 | return; |
2668 | } |
2655 | } |
2669 | sprintf(buf,"%s died.",op->name); |
2656 | sprintf(buf,"%s died.", &op->name); |
2670 | } |
2657 | } |
2671 | play_sound_player_only(op->contr, SOUND_PLAYER_DIES,0,0); |
2658 | play_sound_player_only(op->contr, SOUND_PLAYER_DIES,0,0); |
2672 | |
2659 | |
2673 | /* save the map location for corpse, gravestone*/ |
2660 | /* save the map location for corpse, gravestone*/ |
2674 | x=op->x;y=op->y;map=op->map; |
2661 | x=op->x;y=op->y;map=op->map; |
… | |
… | |
2791 | |
2778 | |
2792 | /* Put a gravestone up where the character 'almost' died. List the |
2779 | /* Put a gravestone up where the character 'almost' died. List the |
2793 | * exp loss on the stone. |
2780 | * exp loss on the stone. |
2794 | */ |
2781 | */ |
2795 | tmp=arch_to_object(find_archetype("gravestone")); |
2782 | tmp=arch_to_object(find_archetype("gravestone")); |
2796 | sprintf(buf,"%s's gravestone",op->name); |
2783 | sprintf(buf,"%s's gravestone",&op->name); tmp->name = buf; |
2797 | FREE_AND_COPY(tmp->name, buf); |
|
|
2798 | sprintf(buf,"%s's gravestones",op->name); |
2784 | sprintf(buf,"%s's gravestones",&op->name); tmp->name_pl = buf; |
2799 | FREE_AND_COPY(tmp->name_pl, buf); |
|
|
2800 | sprintf(buf,"RIP\nHere rests the hero %s the %s,\n" |
2785 | sprintf(buf,"RIP\nHere rests the hero %s the %s,\n" |
2801 | "who was killed\n" |
2786 | "who was killed\n" |
2802 | "by %s.\n", |
2787 | "by %s.\n", |
2803 | op->name, op->contr->title, |
2788 | &op->name, op->contr->title, |
2804 | op->contr->killer); |
2789 | op->contr->killer); |
2805 | tmp->msg = add_string(buf); |
2790 | tmp->msg = buf; |
2806 | tmp->x=op->x,tmp->y=op->y; |
2791 | tmp->x=op->x,tmp->y=op->y; |
2807 | insert_ob_in_map (tmp, op->map, NULL,0); |
2792 | insert_ob_in_map (tmp, op->map, NULL,0); |
2808 | |
2793 | |
2809 | /**************************************/ |
2794 | /**************************************/ |
2810 | /* */ |
2795 | /* */ |
… | |
… | |
2950 | } |
2935 | } |
2951 | play_again(op); |
2936 | play_again(op); |
2952 | |
2937 | |
2953 | /* peterm: added to create a corpse at deathsite. */ |
2938 | /* peterm: added to create a corpse at deathsite. */ |
2954 | tmp=arch_to_object(find_archetype("corpse_pl")); |
2939 | tmp=arch_to_object(find_archetype("corpse_pl")); |
2955 | sprintf(buf,"%s", op->name); |
2940 | sprintf(buf,"%s", &op->name); |
2956 | FREE_AND_COPY(tmp->name, buf); |
2941 | tmp->name = tmp->name_pl = buf; |
2957 | FREE_AND_COPY(tmp->name_pl, buf); |
|
|
2958 | tmp->level=op->level; |
2942 | tmp->level=op->level; |
2959 | tmp->x=x;tmp->y=y; |
2943 | tmp->x=x;tmp->y=y; |
2960 | if (tmp->msg) |
|
|
2961 | free_string(tmp->msg); |
|
|
2962 | tmp->msg = add_string (gravestone_text(op)); |
2944 | tmp->msg = gravestone_text(op); |
2963 | SET_FLAG (tmp, FLAG_UNIQUE); |
2945 | SET_FLAG (tmp, FLAG_UNIQUE); |
2964 | insert_ob_in_map (tmp, map, NULL,0); |
2946 | insert_ob_in_map (tmp, map, NULL,0); |
2965 | } |
2947 | } |
2966 | } |
2948 | } |
2967 | |
2949 | |
… | |
… | |
3006 | int old = pl->ob->carrying, sum = sum_weight(pl->ob); |
2988 | int old = pl->ob->carrying, sum = sum_weight(pl->ob); |
3007 | if(old == sum) |
2989 | if(old == sum) |
3008 | continue; |
2990 | continue; |
3009 | fix_player(pl->ob); |
2991 | fix_player(pl->ob); |
3010 | LOG(llevDebug,"Fixed inventory in %s (%d -> %d)\n", |
2992 | LOG(llevDebug,"Fixed inventory in %s (%d -> %d)\n", |
3011 | pl->ob->name, old, sum); |
2993 | &pl->ob->name, old, sum); |
3012 | } |
2994 | } |
3013 | } |
2995 | } |
3014 | |
2996 | |
3015 | void fix_luck(void) { |
2997 | void fix_luck(void) { |
3016 | player *pl; |
2998 | player *pl; |
… | |
… | |
3034 | |
3016 | |
3035 | /* casting POTION 'dusts' is really a use_magic_item skill */ |
3017 | /* casting POTION 'dusts' is really a use_magic_item skill */ |
3036 | if (op->type == PLAYER && throw_ob->type == POTION && !skop) |
3018 | if (op->type == PLAYER && throw_ob->type == POTION && !skop) |
3037 | { |
3019 | { |
3038 | LOG (llevError, "Player %s lacks critical skill use_magic_item!\n", |
3020 | LOG (llevError, "Player %s lacks critical skill use_magic_item!\n", |
3039 | op->name); |
3021 | &op->name); |
3040 | return; |
3022 | return; |
3041 | } |
3023 | } |
3042 | |
3024 | |
3043 | spob = throw_ob->inv; |
3025 | spob = throw_ob->inv; |
3044 | |
3026 | |
… | |
… | |
3046 | // not pass NULL to cast_spell (which did indeed check itself, but |
3028 | // not pass NULL to cast_spell (which did indeed check itself, but |
3047 | // errors should be reported as early as possible IMHO) |
3029 | // errors should be reported as early as possible IMHO) |
3048 | if (!spob) |
3030 | if (!spob) |
3049 | { |
3031 | { |
3050 | LOG (llevError, "cast_dust: thrown object %s (by %s) had no spell in it!", |
3032 | LOG (llevError, "cast_dust: thrown object %s (by %s) had no spell in it!", |
3051 | throw_ob->name, op->name); |
3033 | &throw_ob->name, &op->name); |
3052 | return; |
3034 | return; |
3053 | } |
3035 | } |
3054 | |
3036 | |
3055 | if (op->type == PLAYER) |
3037 | if (op->type == PLAYER) |
3056 | new_draw_info_format (NDI_UNIQUE, 0, op, "You cast %s.", spob->name); |
3038 | new_draw_info_format (NDI_UNIQUE, 0, op, "You cast %s.", &spob->name); |
3057 | |
3039 | |
3058 | cast_spell (op, throw_ob, dir, spob, NULL); |
3040 | cast_spell (op, throw_ob, dir, spob, NULL); |
3059 | |
3041 | |
3060 | if (!QUERY_FLAG (throw_ob, FLAG_REMOVED)) |
3042 | if (!QUERY_FLAG (throw_ob, FLAG_REMOVED)) |
3061 | remove_ob (throw_ob); |
3043 | remove_ob (throw_ob); |
… | |
… | |
3065 | void make_visible (object *op) { |
3047 | void make_visible (object *op) { |
3066 | op->hide = 0; |
3048 | op->hide = 0; |
3067 | op->invisible = 0; |
3049 | op->invisible = 0; |
3068 | if(op->type==PLAYER) { |
3050 | if(op->type==PLAYER) { |
3069 | op->contr->tmp_invis = 0; |
3051 | op->contr->tmp_invis = 0; |
3070 | if (op->contr->invis_race) FREE_AND_CLEAR_STR(op->contr->invis_race); |
3052 | op->contr->invis_race = 0; |
3071 | } |
3053 | } |
3072 | update_object(op,UP_OBJ_FACE); |
3054 | update_object(op,UP_OBJ_FACE); |
3073 | } |
3055 | } |
3074 | |
3056 | |
3075 | int is_true_undead(object *op) { |
3057 | int is_true_undead(object *op) { |
… | |
… | |
3354 | |
3336 | |
3355 | if (item->type == SPELL) { |
3337 | if (item->type == SPELL) { |
3356 | if (check_spell_known (who, item->name)) |
3338 | if (check_spell_known (who, item->name)) |
3357 | return; |
3339 | return; |
3358 | |
3340 | |
3359 | new_draw_info_format(NDI_UNIQUE|NDI_BLUE, 0, who, "You gained the ability of %s", item->name); |
3341 | new_draw_info_format(NDI_UNIQUE|NDI_BLUE, 0, who, "You gained the ability of %s", &item->name); |
3360 | do_learn_spell (who, item, 0); |
3342 | do_learn_spell (who, item, 0); |
3361 | return; |
3343 | return; |
3362 | } |
3344 | } |
3363 | |
3345 | |
3364 | /* grant direct spell */ |
3346 | /* grant direct spell */ |
3365 | if (item->type == SPELLBOOK) { |
3347 | if (item->type == SPELLBOOK) { |
3366 | if (!item->inv) { |
3348 | if (!item->inv) { |
3367 | LOG(llevDebug,"dragon_ability_gain: Broken spellbook %s\n", |
3349 | LOG(llevDebug,"dragon_ability_gain: Broken spellbook %s\n", &item->name); |
3368 | item->name); |
|
|
3369 | return; |
3350 | return; |
3370 | } |
3351 | } |
3371 | if (check_spell_known (who, item->inv->name)) |
3352 | if (check_spell_known (who, item->inv->name)) |
3372 | return; |
3353 | return; |
3373 | if (item->invisible) { |
3354 | if (item->invisible) { |
3374 | new_draw_info_format(NDI_UNIQUE|NDI_BLUE, 0, who, "You gained the ability of %s", item->inv->name); |
3355 | new_draw_info_format(NDI_UNIQUE|NDI_BLUE, 0, who, "You gained the ability of %s", &item->inv->name); |
3375 | do_learn_spell (who, item->inv, 0); |
3356 | do_learn_spell (who, item->inv, 0); |
3376 | return; |
3357 | return; |
3377 | } |
3358 | } |
3378 | } |
3359 | } |
3379 | else if (item->type == SKILL_TOOL && item->invisible) { |
3360 | else if (item->type == SKILL_TOOL && item->invisible) { |