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.1 by root, Fri Feb 3 07:14:35 2006 UTC vs.
Revision 1.20 by root, Tue Jun 6 02:45:28 2006 UTC

1/* 1/*
2 * static char *rcsid_player_c = 2 * static char *rcsid_player_c =
3 * "$Id: player.c,v 1.1 2006/02/03 07:14:35 root Exp $"; 3 * "$Id: player.c,v 1.20 2006/06/06 02:45:28 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
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
44extern int same_party (partylist *a, partylist *b);
45#endif
46
43player *find_player(const char *plname) 47player *find_player(const char *plname)
44{ 48{
45 player *pl; 49 player *pl;
46 for(pl=first_player;pl!=NULL;pl=pl->next) 50 for(pl=first_player;pl!=NULL;pl=pl->next)
47 { 51 {
73 } 77 }
74 } 78 }
75 return found; 79 return found;
76 } 80 }
77 81
78void display_motd(object *op) { 82void display_motd(const object *op) {
79 char buf[MAX_BUF]; 83 char buf[MAX_BUF];
80 char motd[HUGE_BUF]; 84 char motd[HUGE_BUF];
81 FILE *fp; 85 FILE *fp;
82 int comp; 86 int comp;
83 int size; 87 int size;
96 } 100 }
97 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);
98 close_and_delete(fp, comp); 102 close_and_delete(fp, comp);
99} 103}
100 104
101void send_rules(object *op) { 105void send_rules(const object *op) {
102 char buf[MAX_BUF]; 106 char buf[MAX_BUF];
103 char rules[HUGE_BUF]; 107 char rules[HUGE_BUF];
104 FILE *fp; 108 FILE *fp;
105 int comp; 109 int comp;
106 int size; 110 int size;
124 } 128 }
125 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);
126 close_and_delete(fp, comp); 130 close_and_delete(fp, comp);
127} 131}
128 132
129void send_news(object *op) { 133void send_news(const object *op) {
130 char buf[MAX_BUF]; 134 char buf[MAX_BUF];
131 char news[HUGE_BUF]; 135 char news[HUGE_BUF];
132 char subject[MAX_BUF]; 136 char subject[MAX_BUF];
133 FILE *fp; 137 FILE *fp;
134 int comp; 138 int comp;
145 continue; 149 continue;
146 if ( *buf =='%'){ /* send one news */ 150 if ( *buf =='%'){ /* send one news */
147 if (size>0) 151 if (size>0)
148 draw_ext_info_format(NDI_UNIQUE | NDI_GREEN, 0, op, 152 draw_ext_info_format(NDI_UNIQUE | NDI_GREEN, 0, op,
149 MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, 153 MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS,
150 "!! informations: %s\n%s", 154 "INFORMATION: %s\n%s",
151 "%s\n%s", 155 "%s\n%s",
152 subject, news); /*send previously read news*/ 156 subject, news); /*send previously read news*/
153 strcpy(subject,buf+1); 157 strcpy(subject,buf+1);
154 strip_endline(subject); 158 strip_endline(subject);
155 size=0; 159 size=0;
166 } 170 }
167 } 171 }
168 172
169 draw_ext_info_format(NDI_UNIQUE | NDI_GREEN, 0, op, 173 draw_ext_info_format(NDI_UNIQUE | NDI_GREEN, 0, op,
170 MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, 174 MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS,
171 "!! informations: %s\n%s\n", 175 "INFORMATION: %s\n%s\n",
172 "%s\n%s", 176 "%s\n%s",
173 subject, news); 177 subject, news);
174 close_and_delete(fp, comp); 178 close_and_delete(fp, comp);
175} 179}
176 180
224 } 228 }
225 229
226 /* Clears basically the entire player structure except 230 /* Clears basically the entire player structure except
227 * for next and socket. 231 * for next and socket.
228 */ 232 */
229 memset((void*)((char*)p + offsetof(player, maplevel)), 0, 233 memset((void*)((char*)p + offsetof(player, ob)), 0,
230 sizeof(player) - offsetof(player, maplevel)); 234 sizeof(player) - offsetof(player, ob));
231 235
232 /* There are some elements we want initialized to non zero value - 236 /* There are some elements we want initialized to non zero value -
233 * we deal with that below this point. 237 * we deal with that below this point.
234 */ 238 */
235 p->party=NULL; 239 p->party=NULL;
249 op->speed_left=0.5; 253 op->speed_left=0.5;
250 op->speed=1.0; 254 op->speed=1.0;
251 op->direction=5; /* So player faces south */ 255 op->direction=5; /* So player faces south */
252 op->stats.wc=2; 256 op->stats.wc=2;
253 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 */
254 259
255 roll_stats(op); 260 roll_stats(op);
256 p->state=ST_ROLL_STAT; 261 p->state=ST_ROLL_STAT;
257 clear_los(op); 262 clear_los(op);
258 263
259 p->gen_sp_armour=10; 264 p->gen_sp_armour=10;
260 p->last_speed= -1; 265 p->last_speed= -1;
261 p->shoottype=range_none; 266 p->shoottype=range_none;
262 p->bowtype=bow_normal; 267 p->bowtype=bow_normal;
263 p->petmode=pet_normal; 268 p->petmode=pet_normal;
264 p->listening=9; 269 p->listening=10;
270 p->usekeys=containers;
265 p->last_weapon_sp= -1; 271 p->last_weapon_sp= -1;
266 p->peaceful=1; /* default peaceful */ 272 p->peaceful=1; /* default peaceful */
267 p->do_los=1; 273 p->do_los=1;
268 p->explore=0; 274 p->explore=0;
269 p->no_shout=0; /* default can shout */ 275 p->no_shout=0; /* default can shout */
311 317
312int add_player(NewSocket *ns) { 318int add_player(NewSocket *ns) {
313 player *p; 319 player *p;
314 320
315 p=get_player(NULL); 321 p=get_player(NULL);
316 memcpy(&p->socket, ns, sizeof(NewSocket)); 322 p->socket = *ns;
317 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));
318 if(p->socket.faces_sent == NULL) 324 if(p->socket.faces_sent == NULL)
319 fatal(OUT_OF_MEMORY); 325 fatal(OUT_OF_MEMORY);
320 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));
321 /* 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.
396 op=ol->ob; 402 op=ol->ob;
397 lastdist=rv.distance; 403 lastdist=rv.distance;
398 } 404 }
399 } 405 }
400 for (pl=first_player; pl != NULL; pl=pl->next) { 406 for (pl=first_player; pl != NULL; pl=pl->next) {
401 if (on_same_map(mon, pl->ob)&& can_detect_enemy(mon, pl->ob,&rv)) { 407 if (can_detect_enemy(mon, pl->ob,&rv)) {
402 408
403 if(lastdist>rv.distance) { 409 if(lastdist>rv.distance) {
404 op=pl->ob; 410 op=pl->ob;
405 lastdist=rv.distance; 411 lastdist=rv.distance;
406 } 412 }
634 if(op->type==SPELL) { 640 if(op->type==SPELL) {
635 remove_ob(op); 641 remove_ob(op);
636 free_object(op); 642 free_object(op);
637 continue; 643 continue;
638 } 644 }
639 if(op->type==SKILL) { 645 else if(op->type==SKILL) {
640 SET_FLAG(op, FLAG_CAN_USE_SKILL); 646 SET_FLAG(op, FLAG_CAN_USE_SKILL);
641 op->stats.exp = 0; 647 op->stats.exp = 0;
642 op->level = 1; 648 op->level = 1;
643 } 649 }
650 /* lock all 'normal items by default */
651 else SET_FLAG(op, FLAG_INV_LOCKED);
644 } /* for loop of objects in player inv */ 652 } /* for loop of objects in player inv */
645 653
646 /* Need to set up the skill pointers */ 654 /* Need to set up the skill pointers */
647 link_player_skills(pl); 655 link_player_skills(pl);
648} 656}
943 } 951 }
944 return 0; 952 return 0;
945} 953}
946 954
947/* This function takes the key that is passed, and does the 955/* This function takes the key that is passed, and does the
948 * appropriate action with it (change class, or other things. 956 * appropriate action with it (change race, or other things).
957 * The function name is for historical reasons - now we have
958 * separate race and class; this actually changes the RACE,
959 * not the class.
949 */ 960 */
950 961
951int key_change_class(object *op, char key) 962int key_change_class(object *op, char key)
952{ 963{
953 int tmp_loop; 964 int tmp_loop;
954 965
955 if(key=='q'||key=='Q') { 966 if(key=='q'||key=='Q') {
956 remove_ob(op); 967 remove_ob(op);
957 play_again(op); 968 play_again(op);
958 return 0; 969 return 0;
989 CLEAR_FLAG(op, FLAG_WIZ); 1000 CLEAR_FLAG(op, FLAG_WIZ);
990 give_initial_items(op,op->randomitems); 1001 give_initial_items(op,op->randomitems);
991 link_player_skills(op); 1002 link_player_skills(op);
992 esrv_send_inventory(op, op); 1003 esrv_send_inventory(op, op);
993 fix_player(op); 1004 fix_player(op);
1005
1006 /* This moves the player to a different start map, if there
1007 * is one for this race
1008 */
1009 if(*first_map_ext_path) {
1010 object *tmp;
1011 mapstruct *oldmap = op->map;
1012 char mapname[MAX_BUF];
1013 snprintf(mapname, MAX_BUF-1, "%s/%s",
1014 first_map_ext_path, op->arch->name);
1015 tmp=get_object();
1016 EXIT_PATH(tmp) = add_string(mapname);
1017 EXIT_X(tmp) = op->x;
1018 EXIT_Y(tmp) = op->y;
1019 enter_exit(op,tmp); /* we don't really care if it succeeded;
1020 * if the map isn't there, then stay on the
1021 * default initial map */
1022 free_object(tmp);
1023 } else {
1024 LOG(llevDebug,"first_map_ext_path not set\n");
1025 }
994 return 0; 1026 return 0;
995 } 1027 }
996 1028
997 /* Following actually changes the class - this is the default command 1029 /* Following actually changes the race - this is the default command
998 * if we don't match with one of the options above. 1030 * if we don't match with one of the options above.
999 */ 1031 */
1000 1032
1001 tmp_loop = 0; 1033 tmp_loop = 0;
1002 while(!tmp_loop) { 1034 while(!tmp_loop) {
1017 insert_ob_in_map (op, op->map, op,0); 1049 insert_ob_in_map (op, op->map, op,0);
1018 strncpy(op->contr->title, op->arch->clone.name, sizeof(op->contr->title)-1); 1050 strncpy(op->contr->title, op->arch->clone.name, sizeof(op->contr->title)-1);
1019 op->contr->title[sizeof(op->contr->title)-1] = '\0'; 1051 op->contr->title[sizeof(op->contr->title)-1] = '\0';
1020 add_statbonus(op); 1052 add_statbonus(op);
1021 tmp_loop=allowed_class(op); 1053 tmp_loop=allowed_class(op);
1054
1055 if (!strncmp (op->msg, "Edit me", 7)) tmp_loop = 0; // pippijn fucked it up //D//TODO
1022 } 1056 }
1023 update_object(op,UP_OBJ_FACE); 1057 update_object(op,UP_OBJ_FACE);
1024 esrv_update_item(UPD_FACE,op,op); 1058 esrv_update_item(UPD_FACE,op,op);
1025 fix_player(op); 1059 fix_player(op);
1026 op->stats.hp=op->stats.maxhp; 1060 op->stats.hp=op->stats.maxhp;
1983 * going to try and move (not fire weapons). 2017 * going to try and move (not fire weapons).
1984 */ 2018 */
1985 2019
1986void move_player_attack(object *op, int dir) 2020void move_player_attack(object *op, int dir)
1987{ 2021{
1988 object *tmp, *mon; 2022 object *tmp, *mon, *tpl;
1989 sint16 nx=freearr_x[dir]+op->x,ny=freearr_y[dir]+op->y; 2023 sint16 nx, ny;
1990 int on_battleground; 2024 int on_battleground;
1991 mapstruct *m; 2025 mapstruct *m;
1992 2026
2027 if (op->contr->transport) tpl = op->contr->transport;
2028 else tpl = op;
2029 nx=freearr_x[dir]+tpl->x;
2030 ny=freearr_y[dir]+tpl->y;
2031
1993 on_battleground = op_on_battleground(op, NULL, NULL); 2032 on_battleground = op_on_battleground(tpl, NULL, NULL);
1994 2033
1995 /* If braced, or can't move to the square, and it is not out of the 2034 /* If braced, or can't move to the square, and it is not out of the
1996 * map, attack it. Note order of if statement is important - don't 2035 * map, attack it. Note order of if statement is important - don't
1997 * want to be calling move_ob if braced, because move_ob will move the 2036 * want to be calling move_ob if braced, because move_ob will move the
1998 * player. This is a pretty nasty hack, because if we could 2037 * player. This is a pretty nasty hack, because if we could
1999 * move to some space, it then means that if we are braced, we should 2038 * move to some space, it then means that if we are braced, we should
2000 * do nothing at all. As it is, if we are braced, we go through 2039 * do nothing at all. As it is, if we are braced, we go through
2001 * quite a bit of processing. However, it probably is less than what 2040 * quite a bit of processing. However, it probably is less than what
2002 * move_ob uses. 2041 * move_ob uses.
2003 */ 2042 */
2004 if ((op->contr->braced || !move_ob(op,dir,op)) && !out_of_map(op->map,nx,ny)) { 2043 if ((op->contr->braced || !move_ob(tpl,dir,tpl)) && !out_of_map(tpl->map,nx,ny)) {
2005 if (OUT_OF_REAL_MAP(op->map, nx, ny)) { 2044 if (OUT_OF_REAL_MAP(tpl->map, nx, ny)) {
2006 m = get_map_from_coord(op->map, &nx, &ny); 2045 m = get_map_from_coord(tpl->map, &nx, &ny);
2007 if (!m) return; /* Don't think this should happen */ 2046 if (!m) return; /* Don't think this should happen */
2008 } 2047 }
2009 else m =op->map; 2048 else m =tpl->map;
2010 2049
2011 if ((tmp=get_map_ob(m,nx,ny))==NULL) { 2050 if ((tmp=get_map_ob(m,nx,ny))==NULL) {
2012 /* LOG(llevError,"player_move_attack: get_map_ob returns NULL, but player can not more there.\n");*/ 2051 /* LOG(llevError,"player_move_attack: get_map_ob returns NULL, but player can not more there.\n");*/
2013 return; 2052 return;
2014 } 2053 }
2052 2091
2053 /* If the creature is a pet, push it even if the player is not 2092 /* If the creature is a pet, push it even if the player is not
2054 * peaceful. Our assumption is the creature is a pet if the 2093 * peaceful. Our assumption is the creature is a pet if the
2055 * player owns it and it is either friendly or unagressive. 2094 * player owns it and it is either friendly or unagressive.
2056 */ 2095 */
2057 if ((op->type==PLAYER) && get_owner(mon)==op && 2096 if ((op->type==PLAYER)
2097#if COZY_SERVER
2098 &&
2099 (
2100 (get_owner(mon) && get_owner(mon)->contr
2101 && same_party (get_owner(mon)->contr->party, op->contr->party))
2102 || get_owner(mon) == op
2103 )
2104#else
2105 && get_owner(mon)==op
2106#endif
2058 (QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY))) 2107 && (QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY)))
2059 { 2108 {
2060 /* If we're braced, we don't want to switch places with it */ 2109 /* If we're braced, we don't want to switch places with it */
2061 if (op->contr->braced) return; 2110 if (op->contr->braced) return;
2062 play_sound_map(op->map, op->x, op->y, SOUND_PUSH_PLAYER); 2111 play_sound_map(tpl->map, tpl->x, tpl->y, SOUND_PUSH_PLAYER);
2063 (void) push_ob(mon,dir,op); 2112 (void) push_ob(mon,dir,op);
2064 if(op->contr->tmp_invis||op->hide) make_visible(op); 2113 if(op->contr->tmp_invis||op->hide) make_visible(op);
2065 return; 2114 return;
2066 } 2115 }
2067 2116
2070 * someone, but put it inside this loop so that you won't 2119 * someone, but put it inside this loop so that you won't
2071 * attack them either. 2120 * attack them either.
2072 */ 2121 */
2073 if ((mon->type==PLAYER || mon->enemy != op) && 2122 if ((mon->type==PLAYER || mon->enemy != op) &&
2074 (mon->type==PLAYER || QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY)) && 2123 (mon->type==PLAYER || QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY)) &&
2075 (op->contr->peaceful && !on_battleground)) { 2124 (
2125#ifdef PROHIBIT_PLAYERKILL
2126 (op->contr->peaceful || (mon->type == PLAYER && mon->contr->peaceful)) &&
2127#else
2128 op->contr->peaceful &&
2129#endif
2130 !on_battleground
2131 )) {
2076 if (!op->contr->braced) { 2132 if (!op->contr->braced) {
2077 play_sound_map(op->map, op->x, op->y, SOUND_PUSH_PLAYER); 2133 play_sound_map(tpl->map, tpl->x, tpl->y, SOUND_PUSH_PLAYER);
2078 (void) push_ob(mon,dir,op); 2134 (void) push_ob(mon,dir,op);
2079 } else { 2135 } else {
2080 new_draw_info(0, 0,op,"You withhold your attack"); 2136 new_draw_info(0, 0,op,"You withhold your attack");
2081 } 2137 }
2082 if(op->contr->tmp_invis||op->hide) make_visible(op); 2138 if(op->contr->tmp_invis||op->hide) make_visible(op);
2131 } /* if player should attack something */ 2187 } /* if player should attack something */
2132} 2188}
2133 2189
2134int move_player(object *op,int dir) { 2190int move_player(object *op,int dir) {
2135 int pick; 2191 int pick;
2192 object *transport = op->contr->transport;
2136 2193
2137 if(op->map == NULL || op->map->in_memory != MAP_IN_MEMORY) 2194 if(!transport && (op->map == NULL || op->map->in_memory != MAP_IN_MEMORY))
2138 return 0; 2195 return 0;
2139 2196
2140 /* Sanity check: make sure dir is valid */ 2197 /* Sanity check: make sure dir is valid */
2141 if ( ( dir < 0 ) || ( dir >= 9 ) ) { 2198 if ( ( dir < 0 ) || ( dir >= 9 ) ) {
2142 LOG( llevError, "move_player: invalid direction %d\n", dir); 2199 LOG( llevError, "move_player: invalid direction %d\n", dir);
2147 if(QUERY_FLAG(op,FLAG_CONFUSED) && dir) 2204 if(QUERY_FLAG(op,FLAG_CONFUSED) && dir)
2148 dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2); 2205 dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2);
2149 2206
2150 op->facing = dir; 2207 op->facing = dir;
2151 2208
2152 if(op->hide) do_hidden_move(op); 2209 if(!transport && op->hide) do_hidden_move(op);
2210
2211 if (transport) {
2212 /* transport->contr is set up for the person in charge of the boat.
2213 * if that isn't this person, he can't steer it, etc
2214 */
2215 if (transport->contr != op->contr) return 0;
2216
2217 /* Transport can't move. But update dir so it at least
2218 * will point in the same direction if player is running.
2219 */
2220 if (transport->speed_left < 0.0) {
2221 transport->direction = dir;
2222 op->direction = dir;
2223 return 0;
2224 }
2225 /* Remove transport speed. Give player just a little speed -
2226 * enough so that they will get an action again quickly.
2227 *
2228 */
2229 transport->speed_left -= 1.0;
2230 if (op->speed_left < 0.0) op->speed_left = -0.01;
2231
2232 }
2153 2233
2154 if(op->contr->fire_on) { 2234 if(op->contr->fire_on) {
2155 fire(op,dir); 2235 fire(op,dir);
2156 } 2236 }
2157 else move_player_attack(op,dir); 2237 else move_player_attack(op,dir);
2169 } 2249 }
2170 /* Update how the player looks. Use the facing, so direction may 2250 /* Update how the player looks. Use the facing, so direction may
2171 * get reset to zero. This allows for full animation capabilities 2251 * get reset to zero. This allows for full animation capabilities
2172 * for players. 2252 * for players.
2173 */ 2253 */
2174 animate_object(op, op->facing); 2254 if (!transport) animate_object(op, op->facing);
2175 return 0; 2255 return 0;
2176} 2256}
2177 2257
2178/* This is similar to handle_player, below, but is only used by the 2258/* This is similar to handle_player, below, but is only used by the
2179 * new client/server stuff. 2259 * new client/server stuff.
2184 */ 2264 */
2185int handle_newcs_player(object *op) 2265int handle_newcs_player(object *op)
2186{ 2266{
2187 if (op->contr->hidden) { 2267 if (op->contr->hidden) {
2188 op->invisible = 1000; 2268 op->invisible = 1000;
2189 /* the socket code flasehs the player visible/invisible 2269 /* the socket code flashes the player visible/invisible
2190 * depending on the value if invisible, so we need to 2270 * depending on the value of invisible, so we need to
2191 * alternate it here for it to work correctly. 2271 * alternate it here for it to work correctly.
2192 */ 2272 */
2193 if (pticks & 2) op->invisible--; 2273 if (pticks & 2) op->invisible--;
2194 } 2274 }
2195 else if(op->invisible&&!(QUERY_FLAG(op,FLAG_MAKE_INVIS))) { 2275 else if(op->invisible&&!(QUERY_FLAG(op,FLAG_MAKE_INVIS))) {
2463 } 2543 }
2464 } 2544 }
2465 2545
2466 /* Digestion */ 2546 /* Digestion */
2467 if(--op->last_eat<0) { 2547 if(--op->last_eat<0) {
2548#ifdef COZY_SERVER
2549 int dg = op->contr->digestion>=0 && op->contr->digestion<2 ? 2 : op->contr->digestion;
2550 int bonus=dg>0?dg:0,
2551 penalty=dg<0?-dg:0;
2552#else
2468 int bonus=op->contr->digestion>0?op->contr->digestion:0, 2553 int bonus=op->contr->digestion>0?op->contr->digestion:0,
2469 penalty=op->contr->digestion<0?-op->contr->digestion:0; 2554 penalty=op->contr->digestion<0?-op->contr->digestion:0;
2555#endif
2556
2470 if(op->contr->gen_hp > 0) 2557 if(op->contr->gen_hp > 0)
2471 op->last_eat=25*(1+bonus)/(op->contr->gen_hp+penalty+1); 2558 op->last_eat=25*(1+bonus)/(op->contr->gen_hp+penalty+1);
2472 else 2559 else
2473 op->last_eat=25*(1+bonus)/(penalty +1); 2560 op->last_eat=25*(1+bonus)/(penalty +1);
2474 /* dms do not consume food */ 2561 /* dms do not consume food */
2587 2674
2588 /* Lauwenmark: Handle for plugin death event */ 2675 /* Lauwenmark: Handle for plugin death event */
2589 if (execute_event(op, EVENT_DEATH,NULL,NULL,NULL,SCRIPT_FIX_ALL) != 0) 2676 if (execute_event(op, EVENT_DEATH,NULL,NULL,NULL,SCRIPT_FIX_ALL) != 0)
2590 return; 2677 return;
2591 2678
2679 command_kill_pets (op, 0);
2680
2592 /* Lauwenmark: Handle for the global death event */ 2681 /* Lauwenmark: Handle for the global death event */
2593 execute_global_event(EVENT_PLAYER_DEATH, op); 2682 execute_global_event(EVENT_PLAYER_DEATH, op);
2594 if(op->stats.food<0) { 2683 if(op->stats.food<0) {
2595 if (op->contr->explore) { 2684 if (op->contr->explore) {
2596 new_draw_info(NDI_UNIQUE, 0,op,"You would have starved, but you are"); 2685 new_draw_info(NDI_UNIQUE, 0,op,"You would have starved, but you are");
2624 2713
2625 /* Basically two ways to go - remove a stat permanently, or just 2714 /* Basically two ways to go - remove a stat permanently, or just
2626 * make it depletion. This bunch of code deals with that aspect 2715 * make it depletion. This bunch of code deals with that aspect
2627 * of death. 2716 * of death.
2628 */ 2717 */
2629 2718#ifndef COZY_SERVER
2630 if (settings.balanced_stat_loss) { 2719 if (settings.balanced_stat_loss) {
2631 /* If stat loss is permanent, lose one stat only. */ 2720 /* If stat loss is permanent, lose one stat only. */
2632 /* Lower level chars don't lose as many stats because they suffer 2721 /* Lower level chars don't lose as many stats because they suffer
2633 more if they do. */ 2722 more if they do. */
2634 /* Higher level characters can afford things such as potions of 2723 /* Higher level characters can afford things such as potions of
2643 num_stats_lose = 1; 2732 num_stats_lose = 1;
2644 } 2733 }
2645 lost_a_stat = 0; 2734 lost_a_stat = 0;
2646 2735
2647 for (z=0; z<num_stats_lose; z++) { 2736 for (z=0; z<num_stats_lose; z++) {
2737 i = RANDOM() % NUM_STATS;
2738
2648 if (settings.stat_loss_on_death) { 2739 if (settings.stat_loss_on_death) {
2649 /* Pick a random stat and take a point off it. Tell the player 2740 /* Pick a random stat and take a point off it. Tell the player
2650 * what he lost. 2741 * what he lost.
2651 */ 2742 */
2652 i = RANDOM() % 7;
2653 change_attr_value(&(op->stats), i,-1); 2743 change_attr_value(&(op->stats), i,-1);
2654 check_stat_bounds(&(op->stats)); 2744 check_stat_bounds(&(op->stats));
2655 change_attr_value(&(op->contr->orig_stats), i,-1); 2745 change_attr_value(&(op->contr->orig_stats), i,-1);
2656 check_stat_bounds(&(op->contr->orig_stats)); 2746 check_stat_bounds(&(op->contr->orig_stats));
2657 new_draw_info(NDI_UNIQUE, 0,op, lose_msg[i]); 2747 new_draw_info(NDI_UNIQUE, 0,op, lose_msg[i]);
2659 } else { 2749 } else {
2660 /* deplete a stat */ 2750 /* deplete a stat */
2661 archetype *deparch=find_archetype("depletion"); 2751 archetype *deparch=find_archetype("depletion");
2662 object *dep; 2752 object *dep;
2663 2753
2664 i = RANDOM() % 7;
2665 dep = present_arch_in_ob(deparch,op); 2754 dep = present_arch_in_ob(deparch,op);
2666 if(!dep) { 2755 if(!dep) {
2667 dep = arch_to_object(deparch); 2756 dep = arch_to_object(deparch);
2668 insert_ob_in_ob(dep, op); 2757 insert_ob_in_ob(dep, op);
2669 } 2758 }
2725 " you.", god); 2814 " you.", god);
2726 else 2815 else
2727 new_draw_info(NDI_UNIQUE, 0, op, "For a brief moment you" 2816 new_draw_info(NDI_UNIQUE, 0, op, "For a brief moment you"
2728 " feel a holy presence protecting you."); 2817 " feel a holy presence protecting you.");
2729 } 2818 }
2819#endif
2820 new_draw_info(NDI_UNIQUE, 0, op, "For a brief moment you"
2821 " feel a holy presence protecting you from losing yourself completely.");
2730 2822
2731 /* Put a gravestone up where the character 'almost' died. List the 2823 /* Put a gravestone up where the character 'almost' died. List the
2732 * exp loss on the stone. 2824 * exp loss on the stone.
2733 */ 2825 */
2734 tmp=arch_to_object(find_archetype("gravestone")); 2826 tmp=arch_to_object(find_archetype("gravestone"));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines