1 | /* |
1 | /* |
2 | * static char *rcsid_player_c = |
2 | * static char *rcsid_player_c = |
3 | * "$Id: player.c,v 1.3 2006/02/08 04:32:19 root Exp $"; |
3 | * "$Id: player.c,v 1.21 2006/08/11 23:04:50 elmex 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 | |
… | |
… | |
38 | #include <object.h> |
38 | #include <object.h> |
39 | #include <spells.h> |
39 | #include <spells.h> |
40 | #include <skills.h> |
40 | #include <skills.h> |
41 | #include <newclient.h> |
41 | #include <newclient.h> |
42 | |
42 | |
|
|
43 | #ifdef COZY_SERVER |
43 | extern int same_party (partylist *a, partylist *b); |
44 | extern int same_party (partylist *a, partylist *b); |
|
|
45 | #endif |
44 | |
46 | |
45 | player *find_player(const char *plname) |
47 | player *find_player(const char *plname) |
46 | { |
48 | { |
47 | player *pl; |
49 | player *pl; |
48 | for(pl=first_player;pl!=NULL;pl=pl->next) |
50 | for(pl=first_player;pl!=NULL;pl=pl->next) |
… | |
… | |
75 | } |
77 | } |
76 | } |
78 | } |
77 | return found; |
79 | return found; |
78 | } |
80 | } |
79 | |
81 | |
80 | void display_motd(object *op) { |
82 | void display_motd(const object *op) { |
81 | char buf[MAX_BUF]; |
83 | char buf[MAX_BUF]; |
82 | char motd[HUGE_BUF]; |
84 | char motd[HUGE_BUF]; |
83 | FILE *fp; |
85 | FILE *fp; |
84 | int comp; |
86 | int comp; |
85 | int size; |
87 | int size; |
… | |
… | |
98 | } |
100 | } |
99 | 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); |
100 | close_and_delete(fp, comp); |
102 | close_and_delete(fp, comp); |
101 | } |
103 | } |
102 | |
104 | |
103 | void send_rules(object *op) { |
105 | void send_rules(const object *op) { |
104 | char buf[MAX_BUF]; |
106 | char buf[MAX_BUF]; |
105 | char rules[HUGE_BUF]; |
107 | char rules[HUGE_BUF]; |
106 | FILE *fp; |
108 | FILE *fp; |
107 | int comp; |
109 | int comp; |
108 | int size; |
110 | int size; |
… | |
… | |
126 | } |
128 | } |
127 | draw_ext_info(NDI_UNIQUE | NDI_GREEN, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_RULES, rules, NULL); |
129 | draw_ext_info(NDI_UNIQUE | NDI_GREEN, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_RULES, rules, NULL); |
128 | close_and_delete(fp, comp); |
130 | close_and_delete(fp, comp); |
129 | } |
131 | } |
130 | |
132 | |
131 | void send_news(object *op) { |
133 | void send_news(const object *op) { |
132 | char buf[MAX_BUF]; |
134 | char buf[MAX_BUF]; |
133 | char news[HUGE_BUF]; |
135 | char news[HUGE_BUF]; |
134 | char subject[MAX_BUF]; |
136 | char subject[MAX_BUF]; |
135 | FILE *fp; |
137 | FILE *fp; |
136 | int comp; |
138 | int comp; |
… | |
… | |
147 | continue; |
149 | continue; |
148 | if ( *buf =='%'){ /* send one news */ |
150 | if ( *buf =='%'){ /* send one news */ |
149 | if (size>0) |
151 | if (size>0) |
150 | draw_ext_info_format(NDI_UNIQUE | NDI_GREEN, 0, op, |
152 | draw_ext_info_format(NDI_UNIQUE | NDI_GREEN, 0, op, |
151 | MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, |
153 | MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, |
152 | "!! informations: %s\n%s", |
154 | "INFORMATION: %s\n%s", |
153 | "%s\n%s", |
155 | "%s\n%s", |
154 | subject, news); /*send previously read news*/ |
156 | subject, news); /*send previously read news*/ |
155 | strcpy(subject,buf+1); |
157 | strcpy(subject,buf+1); |
156 | strip_endline(subject); |
158 | strip_endline(subject); |
157 | size=0; |
159 | size=0; |
… | |
… | |
168 | } |
170 | } |
169 | } |
171 | } |
170 | |
172 | |
171 | draw_ext_info_format(NDI_UNIQUE | NDI_GREEN, 0, op, |
173 | draw_ext_info_format(NDI_UNIQUE | NDI_GREEN, 0, op, |
172 | MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, |
174 | MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, |
173 | "!! informations: %s\n%s\n", |
175 | "INFORMATION: %s\n%s\n", |
174 | "%s\n%s", |
176 | "%s\n%s", |
175 | subject, news); |
177 | subject, news); |
176 | close_and_delete(fp, comp); |
178 | close_and_delete(fp, comp); |
177 | } |
179 | } |
178 | |
180 | |
… | |
… | |
226 | } |
228 | } |
227 | |
229 | |
228 | /* Clears basically the entire player structure except |
230 | /* Clears basically the entire player structure except |
229 | * for next and socket. |
231 | * for next and socket. |
230 | */ |
232 | */ |
231 | memset((void*)((char*)p + offsetof(player, maplevel)), 0, |
233 | memset((void*)((char*)p + offsetof(player, ob)), 0, |
232 | sizeof(player) - offsetof(player, maplevel)); |
234 | sizeof(player) - offsetof(player, ob)); |
233 | |
235 | |
234 | /* There are some elements we want initialized to non zero value - |
236 | /* There are some elements we want initialized to non zero value - |
235 | * we deal with that below this point. |
237 | * we deal with that below this point. |
236 | */ |
238 | */ |
237 | p->party=NULL; |
239 | p->party=NULL; |
… | |
… | |
251 | op->speed_left=0.5; |
253 | op->speed_left=0.5; |
252 | op->speed=1.0; |
254 | op->speed=1.0; |
253 | op->direction=5; /* So player faces south */ |
255 | op->direction=5; /* So player faces south */ |
254 | op->stats.wc=2; |
256 | op->stats.wc=2; |
255 | op->run_away = 25; /* Then we panick... */ |
257 | op->run_away = 25; /* Then we panick... */ |
|
|
258 | p->socket.monitor_spells = 0; /* Needed because esrv_update_spells( ) gets called by roll_stats */ |
256 | |
259 | |
257 | roll_stats(op); |
260 | roll_stats(op); |
258 | p->state=ST_ROLL_STAT; |
261 | p->state=ST_ROLL_STAT; |
259 | clear_los(op); |
262 | clear_los(op); |
260 | |
263 | |
261 | p->gen_sp_armour=10; |
264 | p->gen_sp_armour=10; |
262 | p->last_speed= -1; |
265 | p->last_speed= -1; |
263 | p->shoottype=range_none; |
266 | p->shoottype=range_none; |
264 | p->bowtype=bow_normal; |
267 | p->bowtype=bow_normal; |
265 | p->petmode=pet_normal; |
268 | p->petmode=pet_normal; |
266 | p->listening=9; |
269 | p->listening=10; |
|
|
270 | p->usekeys=containers; |
267 | p->last_weapon_sp= -1; |
271 | p->last_weapon_sp= -1; |
268 | p->peaceful=1; /* default peaceful */ |
272 | p->peaceful=1; /* default peaceful */ |
269 | p->do_los=1; |
273 | p->do_los=1; |
270 | p->explore=0; |
274 | p->explore=0; |
271 | p->no_shout=0; /* default can shout */ |
275 | p->no_shout=0; /* default can shout */ |
… | |
… | |
313 | |
317 | |
314 | int add_player(NewSocket *ns) { |
318 | int add_player(NewSocket *ns) { |
315 | player *p; |
319 | player *p; |
316 | |
320 | |
317 | p=get_player(NULL); |
321 | p=get_player(NULL); |
318 | memcpy(&p->socket, ns, sizeof(NewSocket)); |
322 | p->socket = *ns; |
319 | p->socket.faces_sent = malloc(p->socket.faces_sent_len*sizeof(*p->socket.faces_sent)); |
323 | p->socket.faces_sent = malloc(p->socket.faces_sent_len*sizeof(*p->socket.faces_sent)); |
320 | if(p->socket.faces_sent == NULL) |
324 | if(p->socket.faces_sent == NULL) |
321 | fatal(OUT_OF_MEMORY); |
325 | fatal(OUT_OF_MEMORY); |
322 | memcpy(p->socket.faces_sent, ns->faces_sent, p->socket.faces_sent_len*sizeof(*p->socket.faces_sent)); |
326 | memcpy(p->socket.faces_sent, ns->faces_sent, p->socket.faces_sent_len*sizeof(*p->socket.faces_sent)); |
323 | /* Needed because the socket we just copied over needs to be cleared. |
327 | /* Needed because the socket we just copied over needs to be cleared. |
… | |
… | |
485 | |
489 | |
486 | mflags = get_map_flags(m, &m, x, y, &x, &y); |
490 | mflags = get_map_flags(m, &m, x, y, &x, &y); |
487 | blocked = (mflags & P_OUT_OF_MAP) ? MOVE_ALL : GET_MAP_MOVE_BLOCK(m, x, y); |
491 | blocked = (mflags & P_OUT_OF_MAP) ? MOVE_ALL : GET_MAP_MOVE_BLOCK(m, x, y); |
488 | |
492 | |
489 | /* Space is blocked - try changing direction a little */ |
493 | /* Space is blocked - try changing direction a little */ |
490 | if ((mflags & P_OUT_OF_MAP) || ((OB_TYPE_MOVE_BLOCK(mon, blocked)) |
494 | if ((mflags & P_OUT_OF_MAP) || ((OB_TYPE_MOVE_BLOCK(mon, blocked) || (mflags&P_BLOCKSVIEW)) |
491 | && (m == mon->map && blocked_link(mon, m, x, y)))) { |
495 | && (m == mon->map && blocked_link(mon, m, x, y)))) { |
492 | /* recalculate direction from last good location. Possible |
496 | /* recalculate direction from last good location. Possible |
493 | * we were not traversing ideal location before. |
497 | * we were not traversing ideal location before. |
494 | */ |
498 | */ |
495 | get_rangevector_from_mapcoord(lastmap, lastx, lasty, pl, &rv, 0); |
499 | get_rangevector_from_mapcoord(lastmap, lastx, lasty, pl, &rv, 0); |
… | |
… | |
529 | m = lastmap; |
533 | m = lastmap; |
530 | mflags = get_map_flags(m, &m, x, y, &x, &y); |
534 | mflags = get_map_flags(m, &m, x, y, &x, &y); |
531 | if (mflags & P_OUT_OF_MAP) continue; |
535 | if (mflags & P_OUT_OF_MAP) continue; |
532 | blocked = GET_MAP_MOVE_BLOCK(m, x, y); |
536 | blocked = GET_MAP_MOVE_BLOCK(m, x, y); |
533 | if (OB_TYPE_MOVE_BLOCK(mon, blocked)) continue; |
537 | if (OB_TYPE_MOVE_BLOCK(mon, blocked)) continue; |
|
|
538 | if (mflags & P_BLOCKSVIEW) continue; |
534 | |
539 | |
535 | if (m == mon->map && blocked_link(mon, m, x, y)) break; |
540 | if (m == mon->map && blocked_link(mon, m, x, y)) break; |
536 | } |
541 | } |
537 | /* go through entire loop without finding a valid |
542 | /* go through entire loop without finding a valid |
538 | * sidestep to take - thus, no valid path. |
543 | * sidestep to take - thus, no valid path. |
… | |
… | |
636 | if(op->type==SPELL) { |
641 | if(op->type==SPELL) { |
637 | remove_ob(op); |
642 | remove_ob(op); |
638 | free_object(op); |
643 | free_object(op); |
639 | continue; |
644 | continue; |
640 | } |
645 | } |
641 | if(op->type==SKILL) { |
646 | else if(op->type==SKILL) { |
642 | SET_FLAG(op, FLAG_CAN_USE_SKILL); |
647 | SET_FLAG(op, FLAG_CAN_USE_SKILL); |
643 | op->stats.exp = 0; |
648 | op->stats.exp = 0; |
644 | op->level = 1; |
649 | op->level = 1; |
645 | } |
650 | } |
|
|
651 | /* lock all 'normal items by default */ |
|
|
652 | else SET_FLAG(op, FLAG_INV_LOCKED); |
646 | } /* for loop of objects in player inv */ |
653 | } /* for loop of objects in player inv */ |
647 | |
654 | |
648 | /* Need to set up the skill pointers */ |
655 | /* Need to set up the skill pointers */ |
649 | link_player_skills(pl); |
656 | link_player_skills(pl); |
650 | } |
657 | } |
… | |
… | |
945 | } |
952 | } |
946 | return 0; |
953 | return 0; |
947 | } |
954 | } |
948 | |
955 | |
949 | /* This function takes the key that is passed, and does the |
956 | /* This function takes the key that is passed, and does the |
950 | * appropriate action with it (change class, or other things. |
957 | * appropriate action with it (change race, or other things). |
|
|
958 | * The function name is for historical reasons - now we have |
|
|
959 | * separate race and class; this actually changes the RACE, |
|
|
960 | * not the class. |
951 | */ |
961 | */ |
952 | |
962 | |
953 | int key_change_class(object *op, char key) |
963 | int key_change_class(object *op, char key) |
954 | { |
964 | { |
955 | int tmp_loop; |
965 | int tmp_loop; |
956 | |
966 | |
957 | if(key=='q'||key=='Q') { |
967 | if(key=='q'||key=='Q') { |
958 | remove_ob(op); |
968 | remove_ob(op); |
959 | play_again(op); |
969 | play_again(op); |
960 | return 0; |
970 | return 0; |
… | |
… | |
991 | CLEAR_FLAG(op, FLAG_WIZ); |
1001 | CLEAR_FLAG(op, FLAG_WIZ); |
992 | give_initial_items(op,op->randomitems); |
1002 | give_initial_items(op,op->randomitems); |
993 | link_player_skills(op); |
1003 | link_player_skills(op); |
994 | esrv_send_inventory(op, op); |
1004 | esrv_send_inventory(op, op); |
995 | fix_player(op); |
1005 | fix_player(op); |
|
|
1006 | |
|
|
1007 | /* This moves the player to a different start map, if there |
|
|
1008 | * is one for this race |
|
|
1009 | */ |
|
|
1010 | if(*first_map_ext_path) { |
|
|
1011 | object *tmp; |
|
|
1012 | mapstruct *oldmap = op->map; |
|
|
1013 | char mapname[MAX_BUF]; |
|
|
1014 | snprintf(mapname, MAX_BUF-1, "%s/%s", |
|
|
1015 | first_map_ext_path, op->arch->name); |
|
|
1016 | tmp=get_object(); |
|
|
1017 | EXIT_PATH(tmp) = add_string(mapname); |
|
|
1018 | EXIT_X(tmp) = op->x; |
|
|
1019 | EXIT_Y(tmp) = op->y; |
|
|
1020 | enter_exit(op,tmp); /* we don't really care if it succeeded; |
|
|
1021 | * if the map isn't there, then stay on the |
|
|
1022 | * default initial map */ |
|
|
1023 | free_object(tmp); |
|
|
1024 | } else { |
|
|
1025 | LOG(llevDebug,"first_map_ext_path not set\n"); |
|
|
1026 | } |
996 | return 0; |
1027 | return 0; |
997 | } |
1028 | } |
998 | |
1029 | |
999 | /* Following actually changes the class - this is the default command |
1030 | /* Following actually changes the race - this is the default command |
1000 | * if we don't match with one of the options above. |
1031 | * if we don't match with one of the options above. |
1001 | */ |
1032 | */ |
1002 | |
1033 | |
1003 | tmp_loop = 0; |
1034 | tmp_loop = 0; |
1004 | while(!tmp_loop) { |
1035 | while(!tmp_loop) { |
… | |
… | |
1019 | insert_ob_in_map (op, op->map, op,0); |
1050 | insert_ob_in_map (op, op->map, op,0); |
1020 | strncpy(op->contr->title, op->arch->clone.name, sizeof(op->contr->title)-1); |
1051 | strncpy(op->contr->title, op->arch->clone.name, sizeof(op->contr->title)-1); |
1021 | op->contr->title[sizeof(op->contr->title)-1] = '\0'; |
1052 | op->contr->title[sizeof(op->contr->title)-1] = '\0'; |
1022 | add_statbonus(op); |
1053 | add_statbonus(op); |
1023 | tmp_loop=allowed_class(op); |
1054 | tmp_loop=allowed_class(op); |
|
|
1055 | |
|
|
1056 | if (!strncmp (op->msg, "Edit me", 7)) tmp_loop = 0; // pippijn fucked it up //D//TODO |
1024 | } |
1057 | } |
1025 | update_object(op,UP_OBJ_FACE); |
1058 | update_object(op,UP_OBJ_FACE); |
1026 | esrv_update_item(UPD_FACE,op,op); |
1059 | esrv_update_item(UPD_FACE,op,op); |
1027 | fix_player(op); |
1060 | fix_player(op); |
1028 | op->stats.hp=op->stats.maxhp; |
1061 | op->stats.hp=op->stats.maxhp; |
… | |
… | |
1985 | * going to try and move (not fire weapons). |
2018 | * going to try and move (not fire weapons). |
1986 | */ |
2019 | */ |
1987 | |
2020 | |
1988 | void move_player_attack(object *op, int dir) |
2021 | void move_player_attack(object *op, int dir) |
1989 | { |
2022 | { |
1990 | object *tmp, *mon; |
2023 | object *tmp, *mon, *tpl; |
1991 | sint16 nx=freearr_x[dir]+op->x,ny=freearr_y[dir]+op->y; |
2024 | sint16 nx, ny; |
1992 | int on_battleground; |
2025 | int on_battleground; |
1993 | mapstruct *m; |
2026 | mapstruct *m; |
1994 | |
2027 | |
|
|
2028 | if (op->contr->transport) tpl = op->contr->transport; |
|
|
2029 | else tpl = op; |
|
|
2030 | nx=freearr_x[dir]+tpl->x; |
|
|
2031 | ny=freearr_y[dir]+tpl->y; |
|
|
2032 | |
1995 | on_battleground = op_on_battleground(op, NULL, NULL); |
2033 | on_battleground = op_on_battleground(tpl, NULL, NULL); |
1996 | |
2034 | |
1997 | /* If braced, or can't move to the square, and it is not out of the |
2035 | /* If braced, or can't move to the square, and it is not out of the |
1998 | * map, attack it. Note order of if statement is important - don't |
2036 | * map, attack it. Note order of if statement is important - don't |
1999 | * want to be calling move_ob if braced, because move_ob will move the |
2037 | * want to be calling move_ob if braced, because move_ob will move the |
2000 | * player. This is a pretty nasty hack, because if we could |
2038 | * player. This is a pretty nasty hack, because if we could |
2001 | * move to some space, it then means that if we are braced, we should |
2039 | * move to some space, it then means that if we are braced, we should |
2002 | * do nothing at all. As it is, if we are braced, we go through |
2040 | * do nothing at all. As it is, if we are braced, we go through |
2003 | * quite a bit of processing. However, it probably is less than what |
2041 | * quite a bit of processing. However, it probably is less than what |
2004 | * move_ob uses. |
2042 | * move_ob uses. |
2005 | */ |
2043 | */ |
2006 | if ((op->contr->braced || !move_ob(op,dir,op)) && !out_of_map(op->map,nx,ny)) { |
2044 | if ((op->contr->braced || !move_ob(tpl,dir,tpl)) && !out_of_map(tpl->map,nx,ny)) { |
2007 | if (OUT_OF_REAL_MAP(op->map, nx, ny)) { |
2045 | if (OUT_OF_REAL_MAP(tpl->map, nx, ny)) { |
2008 | m = get_map_from_coord(op->map, &nx, &ny); |
2046 | m = get_map_from_coord(tpl->map, &nx, &ny); |
2009 | if (!m) return; /* Don't think this should happen */ |
2047 | if (!m) return; /* Don't think this should happen */ |
2010 | } |
2048 | } |
2011 | else m =op->map; |
2049 | else m =tpl->map; |
2012 | |
2050 | |
2013 | if ((tmp=get_map_ob(m,nx,ny))==NULL) { |
2051 | if ((tmp=get_map_ob(m,nx,ny))==NULL) { |
2014 | /* LOG(llevError,"player_move_attack: get_map_ob returns NULL, but player can not more there.\n");*/ |
2052 | /* LOG(llevError,"player_move_attack: get_map_ob returns NULL, but player can not more there.\n");*/ |
2015 | return; |
2053 | return; |
2016 | } |
2054 | } |
… | |
… | |
2055 | /* If the creature is a pet, push it even if the player is not |
2093 | /* If the creature is a pet, push it even if the player is not |
2056 | * peaceful. Our assumption is the creature is a pet if the |
2094 | * peaceful. Our assumption is the creature is a pet if the |
2057 | * player owns it and it is either friendly or unagressive. |
2095 | * player owns it and it is either friendly or unagressive. |
2058 | */ |
2096 | */ |
2059 | if ((op->type==PLAYER) |
2097 | if ((op->type==PLAYER) |
|
|
2098 | #if COZY_SERVER |
2060 | && |
2099 | && |
2061 | ( |
2100 | ( |
2062 | (get_owner(mon) && get_owner(mon)->contr |
2101 | (get_owner(mon) && get_owner(mon)->contr |
2063 | && same_party (get_owner(mon)->contr->party, op->contr->party)) |
2102 | && same_party (get_owner(mon)->contr->party, op->contr->party)) |
2064 | || get_owner(mon) == op |
2103 | || get_owner(mon) == op |
2065 | ) |
2104 | ) |
|
|
2105 | #else |
|
|
2106 | && get_owner(mon)==op |
|
|
2107 | #endif |
2066 | && (QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY))) |
2108 | && (QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY))) |
2067 | { |
2109 | { |
2068 | /* If we're braced, we don't want to switch places with it */ |
2110 | /* If we're braced, we don't want to switch places with it */ |
2069 | if (op->contr->braced) return; |
2111 | if (op->contr->braced) return; |
2070 | play_sound_map(op->map, op->x, op->y, SOUND_PUSH_PLAYER); |
2112 | play_sound_map(tpl->map, tpl->x, tpl->y, SOUND_PUSH_PLAYER); |
2071 | (void) push_ob(mon,dir,op); |
2113 | (void) push_ob(mon,dir,op); |
2072 | if(op->contr->tmp_invis||op->hide) make_visible(op); |
2114 | if(op->contr->tmp_invis||op->hide) make_visible(op); |
2073 | return; |
2115 | return; |
2074 | } |
2116 | } |
2075 | |
2117 | |
… | |
… | |
2078 | * someone, but put it inside this loop so that you won't |
2120 | * someone, but put it inside this loop so that you won't |
2079 | * attack them either. |
2121 | * attack them either. |
2080 | */ |
2122 | */ |
2081 | if ((mon->type==PLAYER || mon->enemy != op) && |
2123 | if ((mon->type==PLAYER || mon->enemy != op) && |
2082 | (mon->type==PLAYER || QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY)) && |
2124 | (mon->type==PLAYER || QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY)) && |
2083 | (op->contr->peaceful && !on_battleground)) { |
2125 | ( |
|
|
2126 | #ifdef PROHIBIT_PLAYERKILL |
|
|
2127 | (op->contr->peaceful || (mon->type == PLAYER && mon->contr->peaceful)) && |
|
|
2128 | #else |
|
|
2129 | op->contr->peaceful && |
|
|
2130 | #endif |
|
|
2131 | !on_battleground |
|
|
2132 | )) { |
2084 | if (!op->contr->braced) { |
2133 | if (!op->contr->braced) { |
2085 | play_sound_map(op->map, op->x, op->y, SOUND_PUSH_PLAYER); |
2134 | play_sound_map(tpl->map, tpl->x, tpl->y, SOUND_PUSH_PLAYER); |
2086 | (void) push_ob(mon,dir,op); |
2135 | (void) push_ob(mon,dir,op); |
2087 | } else { |
2136 | } else { |
2088 | new_draw_info(0, 0,op,"You withhold your attack"); |
2137 | new_draw_info(0, 0,op,"You withhold your attack"); |
2089 | } |
2138 | } |
2090 | if(op->contr->tmp_invis||op->hide) make_visible(op); |
2139 | if(op->contr->tmp_invis||op->hide) make_visible(op); |
… | |
… | |
2139 | } /* if player should attack something */ |
2188 | } /* if player should attack something */ |
2140 | } |
2189 | } |
2141 | |
2190 | |
2142 | int move_player(object *op,int dir) { |
2191 | int move_player(object *op,int dir) { |
2143 | int pick; |
2192 | int pick; |
|
|
2193 | object *transport = op->contr->transport; |
2144 | |
2194 | |
2145 | if(op->map == NULL || op->map->in_memory != MAP_IN_MEMORY) |
2195 | if(!transport && (op->map == NULL || op->map->in_memory != MAP_IN_MEMORY)) |
2146 | return 0; |
2196 | return 0; |
2147 | |
2197 | |
2148 | /* Sanity check: make sure dir is valid */ |
2198 | /* Sanity check: make sure dir is valid */ |
2149 | if ( ( dir < 0 ) || ( dir >= 9 ) ) { |
2199 | if ( ( dir < 0 ) || ( dir >= 9 ) ) { |
2150 | LOG( llevError, "move_player: invalid direction %d\n", dir); |
2200 | LOG( llevError, "move_player: invalid direction %d\n", dir); |
… | |
… | |
2155 | if(QUERY_FLAG(op,FLAG_CONFUSED) && dir) |
2205 | if(QUERY_FLAG(op,FLAG_CONFUSED) && dir) |
2156 | dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2); |
2206 | dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2); |
2157 | |
2207 | |
2158 | op->facing = dir; |
2208 | op->facing = dir; |
2159 | |
2209 | |
2160 | if(op->hide) do_hidden_move(op); |
2210 | if(!transport && op->hide) do_hidden_move(op); |
|
|
2211 | |
|
|
2212 | if (transport) { |
|
|
2213 | /* transport->contr is set up for the person in charge of the boat. |
|
|
2214 | * if that isn't this person, he can't steer it, etc |
|
|
2215 | */ |
|
|
2216 | if (transport->contr != op->contr) return 0; |
|
|
2217 | |
|
|
2218 | /* Transport can't move. But update dir so it at least |
|
|
2219 | * will point in the same direction if player is running. |
|
|
2220 | */ |
|
|
2221 | if (transport->speed_left < 0.0) { |
|
|
2222 | transport->direction = dir; |
|
|
2223 | op->direction = dir; |
|
|
2224 | return 0; |
|
|
2225 | } |
|
|
2226 | /* Remove transport speed. Give player just a little speed - |
|
|
2227 | * enough so that they will get an action again quickly. |
|
|
2228 | * |
|
|
2229 | */ |
|
|
2230 | transport->speed_left -= 1.0; |
|
|
2231 | if (op->speed_left < 0.0) op->speed_left = -0.01; |
|
|
2232 | |
|
|
2233 | } |
2161 | |
2234 | |
2162 | if(op->contr->fire_on) { |
2235 | if(op->contr->fire_on) { |
2163 | fire(op,dir); |
2236 | fire(op,dir); |
2164 | } |
2237 | } |
2165 | else move_player_attack(op,dir); |
2238 | else move_player_attack(op,dir); |
… | |
… | |
2177 | } |
2250 | } |
2178 | /* Update how the player looks. Use the facing, so direction may |
2251 | /* Update how the player looks. Use the facing, so direction may |
2179 | * get reset to zero. This allows for full animation capabilities |
2252 | * get reset to zero. This allows for full animation capabilities |
2180 | * for players. |
2253 | * for players. |
2181 | */ |
2254 | */ |
2182 | animate_object(op, op->facing); |
2255 | if (!transport) animate_object(op, op->facing); |
2183 | return 0; |
2256 | return 0; |
2184 | } |
2257 | } |
2185 | |
2258 | |
2186 | /* This is similar to handle_player, below, but is only used by the |
2259 | /* This is similar to handle_player, below, but is only used by the |
2187 | * new client/server stuff. |
2260 | * new client/server stuff. |
… | |
… | |
2192 | */ |
2265 | */ |
2193 | int handle_newcs_player(object *op) |
2266 | int handle_newcs_player(object *op) |
2194 | { |
2267 | { |
2195 | if (op->contr->hidden) { |
2268 | if (op->contr->hidden) { |
2196 | op->invisible = 1000; |
2269 | op->invisible = 1000; |
2197 | /* the socket code flasehs the player visible/invisible |
2270 | /* the socket code flashes the player visible/invisible |
2198 | * depending on the value if invisible, so we need to |
2271 | * depending on the value of invisible, so we need to |
2199 | * alternate it here for it to work correctly. |
2272 | * alternate it here for it to work correctly. |
2200 | */ |
2273 | */ |
2201 | if (pticks & 2) op->invisible--; |
2274 | if (pticks & 2) op->invisible--; |
2202 | } |
2275 | } |
2203 | else if(op->invisible&&!(QUERY_FLAG(op,FLAG_MAKE_INVIS))) { |
2276 | else if(op->invisible&&!(QUERY_FLAG(op,FLAG_MAKE_INVIS))) { |
… | |
… | |
2471 | } |
2544 | } |
2472 | } |
2545 | } |
2473 | |
2546 | |
2474 | /* Digestion */ |
2547 | /* Digestion */ |
2475 | if(--op->last_eat<0) { |
2548 | if(--op->last_eat<0) { |
|
|
2549 | #ifdef COZY_SERVER |
2476 | int dg = op->contr->digestion>=0 && op->contr->digestion<2 ? 2 : op->contr->digestion; |
2550 | int dg = op->contr->digestion>=0 && op->contr->digestion<2 ? 2 : op->contr->digestion; |
2477 | int bonus=dg>0?dg:0, |
2551 | int bonus=dg>0?dg:0, |
2478 | penalty=dg<0?-dg:0; |
2552 | penalty=dg<0?-dg:0; |
|
|
2553 | #else |
|
|
2554 | int bonus=op->contr->digestion>0?op->contr->digestion:0, |
|
|
2555 | penalty=op->contr->digestion<0?-op->contr->digestion:0; |
|
|
2556 | #endif |
|
|
2557 | |
2479 | if(op->contr->gen_hp > 0) |
2558 | if(op->contr->gen_hp > 0) |
2480 | op->last_eat=25*(1+bonus)/(op->contr->gen_hp+penalty+1); |
2559 | op->last_eat=25*(1+bonus)/(op->contr->gen_hp+penalty+1); |
2481 | else |
2560 | else |
2482 | op->last_eat=25*(1+bonus)/(penalty +1); |
2561 | op->last_eat=25*(1+bonus)/(penalty +1); |
2483 | /* dms do not consume food */ |
2562 | /* dms do not consume food */ |
… | |
… | |
2596 | |
2675 | |
2597 | /* Lauwenmark: Handle for plugin death event */ |
2676 | /* Lauwenmark: Handle for plugin death event */ |
2598 | if (execute_event(op, EVENT_DEATH,NULL,NULL,NULL,SCRIPT_FIX_ALL) != 0) |
2677 | if (execute_event(op, EVENT_DEATH,NULL,NULL,NULL,SCRIPT_FIX_ALL) != 0) |
2599 | return; |
2678 | return; |
2600 | |
2679 | |
|
|
2680 | command_kill_pets (op, 0); |
|
|
2681 | |
2601 | /* Lauwenmark: Handle for the global death event */ |
2682 | /* Lauwenmark: Handle for the global death event */ |
2602 | execute_global_event(EVENT_PLAYER_DEATH, op); |
2683 | execute_global_event(EVENT_PLAYER_DEATH, op); |
2603 | if(op->stats.food<0) { |
2684 | if(op->stats.food<0) { |
2604 | if (op->contr->explore) { |
2685 | if (op->contr->explore) { |
2605 | new_draw_info(NDI_UNIQUE, 0,op,"You would have starved, but you are"); |
2686 | new_draw_info(NDI_UNIQUE, 0,op,"You would have starved, but you are"); |
… | |
… | |
2633 | |
2714 | |
2634 | /* Basically two ways to go - remove a stat permanently, or just |
2715 | /* Basically two ways to go - remove a stat permanently, or just |
2635 | * make it depletion. This bunch of code deals with that aspect |
2716 | * make it depletion. This bunch of code deals with that aspect |
2636 | * of death. |
2717 | * of death. |
2637 | */ |
2718 | */ |
2638 | #if 0 |
2719 | #ifndef COZY_SERVER |
2639 | if (settings.balanced_stat_loss) { |
2720 | if (settings.balanced_stat_loss) { |
2640 | /* If stat loss is permanent, lose one stat only. */ |
2721 | /* If stat loss is permanent, lose one stat only. */ |
2641 | /* Lower level chars don't lose as many stats because they suffer |
2722 | /* Lower level chars don't lose as many stats because they suffer |
2642 | more if they do. */ |
2723 | more if they do. */ |
2643 | /* Higher level characters can afford things such as potions of |
2724 | /* Higher level characters can afford things such as potions of |
… | |
… | |
2652 | num_stats_lose = 1; |
2733 | num_stats_lose = 1; |
2653 | } |
2734 | } |
2654 | lost_a_stat = 0; |
2735 | lost_a_stat = 0; |
2655 | |
2736 | |
2656 | for (z=0; z<num_stats_lose; z++) { |
2737 | for (z=0; z<num_stats_lose; z++) { |
|
|
2738 | i = RANDOM() % NUM_STATS; |
|
|
2739 | |
2657 | if (settings.stat_loss_on_death) { |
2740 | if (settings.stat_loss_on_death) { |
2658 | /* Pick a random stat and take a point off it. Tell the player |
2741 | /* Pick a random stat and take a point off it. Tell the player |
2659 | * what he lost. |
2742 | * what he lost. |
2660 | */ |
2743 | */ |
2661 | i = RANDOM() % 7; |
|
|
2662 | change_attr_value(&(op->stats), i,-1); |
2744 | change_attr_value(&(op->stats), i,-1); |
2663 | check_stat_bounds(&(op->stats)); |
2745 | check_stat_bounds(&(op->stats)); |
2664 | change_attr_value(&(op->contr->orig_stats), i,-1); |
2746 | change_attr_value(&(op->contr->orig_stats), i,-1); |
2665 | check_stat_bounds(&(op->contr->orig_stats)); |
2747 | check_stat_bounds(&(op->contr->orig_stats)); |
2666 | new_draw_info(NDI_UNIQUE, 0,op, lose_msg[i]); |
2748 | new_draw_info(NDI_UNIQUE, 0,op, lose_msg[i]); |
… | |
… | |
2668 | } else { |
2750 | } else { |
2669 | /* deplete a stat */ |
2751 | /* deplete a stat */ |
2670 | archetype *deparch=find_archetype("depletion"); |
2752 | archetype *deparch=find_archetype("depletion"); |
2671 | object *dep; |
2753 | object *dep; |
2672 | |
2754 | |
2673 | i = RANDOM() % 7; |
|
|
2674 | dep = present_arch_in_ob(deparch,op); |
2755 | dep = present_arch_in_ob(deparch,op); |
2675 | if(!dep) { |
2756 | if(!dep) { |
2676 | dep = arch_to_object(deparch); |
2757 | dep = arch_to_object(deparch); |
2677 | insert_ob_in_ob(dep, op); |
2758 | insert_ob_in_ob(dep, op); |
2678 | } |
2759 | } |