1 | /* |
1 | /* |
2 | * static char *rcsid_player_c = |
2 | * static char *rcsid_player_c = |
3 | * "$Id: player.c,v 1.10 2006/03/24 06:06:23 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 | |
… | |
… | |
149 | continue; |
149 | continue; |
150 | if ( *buf =='%'){ /* send one news */ |
150 | if ( *buf =='%'){ /* send one news */ |
151 | if (size>0) |
151 | if (size>0) |
152 | draw_ext_info_format(NDI_UNIQUE | NDI_GREEN, 0, op, |
152 | draw_ext_info_format(NDI_UNIQUE | NDI_GREEN, 0, op, |
153 | MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, |
153 | MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, |
154 | "!! informations: %s\n%s", |
154 | "INFORMATION: %s\n%s", |
155 | "%s\n%s", |
155 | "%s\n%s", |
156 | subject, news); /*send previously read news*/ |
156 | subject, news); /*send previously read news*/ |
157 | strcpy(subject,buf+1); |
157 | strcpy(subject,buf+1); |
158 | strip_endline(subject); |
158 | strip_endline(subject); |
159 | size=0; |
159 | size=0; |
… | |
… | |
170 | } |
170 | } |
171 | } |
171 | } |
172 | |
172 | |
173 | draw_ext_info_format(NDI_UNIQUE | NDI_GREEN, 0, op, |
173 | draw_ext_info_format(NDI_UNIQUE | NDI_GREEN, 0, op, |
174 | MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, |
174 | MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, |
175 | "!! informations: %s\n%s\n", |
175 | "INFORMATION: %s\n%s\n", |
176 | "%s\n%s", |
176 | "%s\n%s", |
177 | subject, news); |
177 | subject, news); |
178 | close_and_delete(fp, comp); |
178 | close_and_delete(fp, comp); |
179 | } |
179 | } |
180 | |
180 | |
… | |
… | |
228 | } |
228 | } |
229 | |
229 | |
230 | /* Clears basically the entire player structure except |
230 | /* Clears basically the entire player structure except |
231 | * for next and socket. |
231 | * for next and socket. |
232 | */ |
232 | */ |
233 | memset((void*)((char*)p + offsetof(player, maplevel)), 0, |
233 | memset((void*)((char*)p + offsetof(player, ob)), 0, |
234 | sizeof(player) - offsetof(player, maplevel)); |
234 | sizeof(player) - offsetof(player, ob)); |
235 | |
235 | |
236 | /* There are some elements we want initialized to non zero value - |
236 | /* There are some elements we want initialized to non zero value - |
237 | * we deal with that below this point. |
237 | * we deal with that below this point. |
238 | */ |
238 | */ |
239 | p->party=NULL; |
239 | p->party=NULL; |
… | |
… | |
264 | p->gen_sp_armour=10; |
264 | p->gen_sp_armour=10; |
265 | p->last_speed= -1; |
265 | p->last_speed= -1; |
266 | p->shoottype=range_none; |
266 | p->shoottype=range_none; |
267 | p->bowtype=bow_normal; |
267 | p->bowtype=bow_normal; |
268 | p->petmode=pet_normal; |
268 | p->petmode=pet_normal; |
269 | p->listening=9; |
269 | p->listening=10; |
|
|
270 | p->usekeys=containers; |
270 | p->last_weapon_sp= -1; |
271 | p->last_weapon_sp= -1; |
271 | p->peaceful=1; /* default peaceful */ |
272 | p->peaceful=1; /* default peaceful */ |
272 | p->do_los=1; |
273 | p->do_los=1; |
273 | p->explore=0; |
274 | p->explore=0; |
274 | p->no_shout=0; /* default can shout */ |
275 | p->no_shout=0; /* default can shout */ |
… | |
… | |
316 | |
317 | |
317 | int add_player(NewSocket *ns) { |
318 | int add_player(NewSocket *ns) { |
318 | player *p; |
319 | player *p; |
319 | |
320 | |
320 | p=get_player(NULL); |
321 | p=get_player(NULL); |
321 | memcpy(&p->socket, ns, sizeof(NewSocket)); |
322 | p->socket = *ns; |
322 | 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)); |
323 | if(p->socket.faces_sent == NULL) |
324 | if(p->socket.faces_sent == NULL) |
324 | fatal(OUT_OF_MEMORY); |
325 | fatal(OUT_OF_MEMORY); |
325 | 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)); |
326 | /* 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. |
… | |
… | |
488 | |
489 | |
489 | mflags = get_map_flags(m, &m, x, y, &x, &y); |
490 | mflags = get_map_flags(m, &m, x, y, &x, &y); |
490 | 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); |
491 | |
492 | |
492 | /* Space is blocked - try changing direction a little */ |
493 | /* Space is blocked - try changing direction a little */ |
493 | 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)) |
494 | && (m == mon->map && blocked_link(mon, m, x, y)))) { |
495 | && (m == mon->map && blocked_link(mon, m, x, y)))) { |
495 | /* recalculate direction from last good location. Possible |
496 | /* recalculate direction from last good location. Possible |
496 | * we were not traversing ideal location before. |
497 | * we were not traversing ideal location before. |
497 | */ |
498 | */ |
498 | get_rangevector_from_mapcoord(lastmap, lastx, lasty, pl, &rv, 0); |
499 | get_rangevector_from_mapcoord(lastmap, lastx, lasty, pl, &rv, 0); |
… | |
… | |
532 | m = lastmap; |
533 | m = lastmap; |
533 | mflags = get_map_flags(m, &m, x, y, &x, &y); |
534 | mflags = get_map_flags(m, &m, x, y, &x, &y); |
534 | if (mflags & P_OUT_OF_MAP) continue; |
535 | if (mflags & P_OUT_OF_MAP) continue; |
535 | blocked = GET_MAP_MOVE_BLOCK(m, x, y); |
536 | blocked = GET_MAP_MOVE_BLOCK(m, x, y); |
536 | if (OB_TYPE_MOVE_BLOCK(mon, blocked)) continue; |
537 | if (OB_TYPE_MOVE_BLOCK(mon, blocked)) continue; |
|
|
538 | if (mflags & P_BLOCKSVIEW) continue; |
537 | |
539 | |
538 | if (m == mon->map && blocked_link(mon, m, x, y)) break; |
540 | if (m == mon->map && blocked_link(mon, m, x, y)) break; |
539 | } |
541 | } |
540 | /* go through entire loop without finding a valid |
542 | /* go through entire loop without finding a valid |
541 | * sidestep to take - thus, no valid path. |
543 | * sidestep to take - thus, no valid path. |
… | |
… | |
950 | } |
952 | } |
951 | return 0; |
953 | return 0; |
952 | } |
954 | } |
953 | |
955 | |
954 | /* This function takes the key that is passed, and does the |
956 | /* This function takes the key that is passed, and does the |
955 | * 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. |
956 | */ |
961 | */ |
957 | |
962 | |
958 | int key_change_class(object *op, char key) |
963 | int key_change_class(object *op, char key) |
959 | { |
964 | { |
960 | int tmp_loop; |
965 | int tmp_loop; |
961 | |
966 | |
962 | if(key=='q'||key=='Q') { |
967 | if(key=='q'||key=='Q') { |
963 | remove_ob(op); |
968 | remove_ob(op); |
964 | play_again(op); |
969 | play_again(op); |
965 | return 0; |
970 | return 0; |
… | |
… | |
996 | CLEAR_FLAG(op, FLAG_WIZ); |
1001 | CLEAR_FLAG(op, FLAG_WIZ); |
997 | give_initial_items(op,op->randomitems); |
1002 | give_initial_items(op,op->randomitems); |
998 | link_player_skills(op); |
1003 | link_player_skills(op); |
999 | esrv_send_inventory(op, op); |
1004 | esrv_send_inventory(op, op); |
1000 | 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 | } |
1001 | return 0; |
1027 | return 0; |
1002 | } |
1028 | } |
1003 | |
1029 | |
1004 | /* Following actually changes the class - this is the default command |
1030 | /* Following actually changes the race - this is the default command |
1005 | * if we don't match with one of the options above. |
1031 | * if we don't match with one of the options above. |
1006 | */ |
1032 | */ |
1007 | |
1033 | |
1008 | tmp_loop = 0; |
1034 | tmp_loop = 0; |
1009 | while(!tmp_loop) { |
1035 | while(!tmp_loop) { |
… | |
… | |
1024 | insert_ob_in_map (op, op->map, op,0); |
1050 | insert_ob_in_map (op, op->map, op,0); |
1025 | 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); |
1026 | op->contr->title[sizeof(op->contr->title)-1] = '\0'; |
1052 | op->contr->title[sizeof(op->contr->title)-1] = '\0'; |
1027 | add_statbonus(op); |
1053 | add_statbonus(op); |
1028 | 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 |
1029 | } |
1057 | } |
1030 | update_object(op,UP_OBJ_FACE); |
1058 | update_object(op,UP_OBJ_FACE); |
1031 | esrv_update_item(UPD_FACE,op,op); |
1059 | esrv_update_item(UPD_FACE,op,op); |
1032 | fix_player(op); |
1060 | fix_player(op); |
1033 | op->stats.hp=op->stats.maxhp; |
1061 | op->stats.hp=op->stats.maxhp; |
… | |
… | |
2093 | * attack them either. |
2121 | * attack them either. |
2094 | */ |
2122 | */ |
2095 | if ((mon->type==PLAYER || mon->enemy != op) && |
2123 | if ((mon->type==PLAYER || mon->enemy != op) && |
2096 | (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)) && |
2097 | ( |
2125 | ( |
2098 | #ifndef PROHIBIT_PLAYERKILL |
2126 | #ifdef PROHIBIT_PLAYERKILL |
|
|
2127 | (op->contr->peaceful || (mon->type == PLAYER && mon->contr->peaceful)) && |
|
|
2128 | #else |
2099 | op->contr->peaceful && |
2129 | op->contr->peaceful && |
2100 | #endif |
2130 | #endif |
2101 | !on_battleground |
2131 | !on_battleground |
2102 | )) { |
2132 | )) { |
2103 | if (!op->contr->braced) { |
2133 | if (!op->contr->braced) { |
… | |
… | |
2644 | } |
2674 | } |
2645 | |
2675 | |
2646 | /* Lauwenmark: Handle for plugin death event */ |
2676 | /* Lauwenmark: Handle for plugin death event */ |
2647 | 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) |
2648 | return; |
2678 | return; |
|
|
2679 | |
|
|
2680 | command_kill_pets (op, 0); |
2649 | |
2681 | |
2650 | /* Lauwenmark: Handle for the global death event */ |
2682 | /* Lauwenmark: Handle for the global death event */ |
2651 | execute_global_event(EVENT_PLAYER_DEATH, op); |
2683 | execute_global_event(EVENT_PLAYER_DEATH, op); |
2652 | if(op->stats.food<0) { |
2684 | if(op->stats.food<0) { |
2653 | if (op->contr->explore) { |
2685 | if (op->contr->explore) { |