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.1.3 by elmex, Wed Mar 15 14:05:37 2006 UTC vs.
Revision 1.19 by pippijn, Fri Jun 2 01:32:36 2006 UTC

1/* 1/*
2 * static char *rcsid_player_c = 2 * static char *rcsid_player_c =
3 * "$Id: player.c,v 1.1.1.3 2006/03/15 14:05:37 elmex Exp $"; 3 * "$Id: player.c,v 1.19 2006/06/02 01:32:36 pippijn 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
37#include <living.h> 37#include <living.h>
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
43#ifdef COZY_SERVER
44extern int same_party (partylist *a, partylist *b);
45#endif
42 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)
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;
260 p->gen_sp_armour=10; 264 p->gen_sp_armour=10;
261 p->last_speed= -1; 265 p->last_speed= -1;
262 p->shoottype=range_none; 266 p->shoottype=range_none;
263 p->bowtype=bow_normal; 267 p->bowtype=bow_normal;
264 p->petmode=pet_normal; 268 p->petmode=pet_normal;
265 p->listening=9; 269 p->listening=10;
270 p->usekeys=containers;
266 p->last_weapon_sp= -1; 271 p->last_weapon_sp= -1;
267 p->peaceful=1; /* default peaceful */ 272 p->peaceful=1; /* default peaceful */
268 p->do_los=1; 273 p->do_los=1;
269 p->explore=0; 274 p->explore=0;
270 p->no_shout=0; /* default can shout */ 275 p->no_shout=0; /* default can shout */
312 317
313int add_player(NewSocket *ns) { 318int add_player(NewSocket *ns) {
314 player *p; 319 player *p;
315 320
316 p=get_player(NULL); 321 p=get_player(NULL);
317 memcpy(&p->socket, ns, sizeof(NewSocket)); 322 p->socket = *ns;
318 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));
319 if(p->socket.faces_sent == NULL) 324 if(p->socket.faces_sent == NULL)
320 fatal(OUT_OF_MEMORY); 325 fatal(OUT_OF_MEMORY);
321 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));
322 /* 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.
397 op=ol->ob; 402 op=ol->ob;
398 lastdist=rv.distance; 403 lastdist=rv.distance;
399 } 404 }
400 } 405 }
401 for (pl=first_player; pl != NULL; pl=pl->next) { 406 for (pl=first_player; pl != NULL; pl=pl->next) {
402 if (on_same_map(mon, pl->ob)&& can_detect_enemy(mon, pl->ob,&rv)) { 407 if (can_detect_enemy(mon, pl->ob,&rv)) {
403 408
404 if(lastdist>rv.distance) { 409 if(lastdist>rv.distance) {
405 op=pl->ob; 410 op=pl->ob;
406 lastdist=rv.distance; 411 lastdist=rv.distance;
407 } 412 }
946 } 951 }
947 return 0; 952 return 0;
948} 953}
949 954
950/* This function takes the key that is passed, and does the 955/* This function takes the key that is passed, and does the
951 * 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.
952 */ 960 */
953 961
954int key_change_class(object *op, char key) 962int key_change_class(object *op, char key)
955{ 963{
956 int tmp_loop; 964 int tmp_loop;
957 965
958 if(key=='q'||key=='Q') { 966 if(key=='q'||key=='Q') {
959 remove_ob(op); 967 remove_ob(op);
960 play_again(op); 968 play_again(op);
961 return 0; 969 return 0;
992 CLEAR_FLAG(op, FLAG_WIZ); 1000 CLEAR_FLAG(op, FLAG_WIZ);
993 give_initial_items(op,op->randomitems); 1001 give_initial_items(op,op->randomitems);
994 link_player_skills(op); 1002 link_player_skills(op);
995 esrv_send_inventory(op, op); 1003 esrv_send_inventory(op, op);
996 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 }
997 return 0; 1026 return 0;
998 } 1027 }
999 1028
1000 /* Following actually changes the class - this is the default command 1029 /* Following actually changes the race - this is the default command
1001 * if we don't match with one of the options above. 1030 * if we don't match with one of the options above.
1002 */ 1031 */
1003 1032
1004 tmp_loop = 0; 1033 tmp_loop = 0;
1005 while(!tmp_loop) { 1034 while(!tmp_loop) {
2060 2089
2061 /* If the creature is a pet, push it even if the player is not 2090 /* If the creature is a pet, push it even if the player is not
2062 * peaceful. Our assumption is the creature is a pet if the 2091 * peaceful. Our assumption is the creature is a pet if the
2063 * player owns it and it is either friendly or unagressive. 2092 * player owns it and it is either friendly or unagressive.
2064 */ 2093 */
2065 if ((op->type==PLAYER) && get_owner(mon)==op && 2094 if ((op->type==PLAYER)
2095#if COZY_SERVER
2096 &&
2097 (
2098 (get_owner(mon) && get_owner(mon)->contr
2099 && same_party (get_owner(mon)->contr->party, op->contr->party))
2100 || get_owner(mon) == op
2101 )
2102#else
2103 && get_owner(mon)==op
2104#endif
2066 (QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY))) 2105 && (QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY)))
2067 { 2106 {
2068 /* If we're braced, we don't want to switch places with it */ 2107 /* If we're braced, we don't want to switch places with it */
2069 if (op->contr->braced) return; 2108 if (op->contr->braced) return;
2070 play_sound_map(tpl->map, tpl->x, tpl->y, SOUND_PUSH_PLAYER); 2109 play_sound_map(tpl->map, tpl->x, tpl->y, SOUND_PUSH_PLAYER);
2071 (void) push_ob(mon,dir,op); 2110 (void) push_ob(mon,dir,op);
2078 * someone, but put it inside this loop so that you won't 2117 * someone, but put it inside this loop so that you won't
2079 * attack them either. 2118 * attack them either.
2080 */ 2119 */
2081 if ((mon->type==PLAYER || mon->enemy != op) && 2120 if ((mon->type==PLAYER || mon->enemy != op) &&
2082 (mon->type==PLAYER || QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY)) && 2121 (mon->type==PLAYER || QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY)) &&
2083 (op->contr->peaceful && !on_battleground)) { 2122 (
2123#ifdef PROHIBIT_PLAYERKILL
2124 (op->contr->peaceful || (mon->type == PLAYER && mon->contr->peaceful)) &&
2125#else
2126 op->contr->peaceful &&
2127#endif
2128 !on_battleground
2129 )) {
2084 if (!op->contr->braced) { 2130 if (!op->contr->braced) {
2085 play_sound_map(tpl->map, tpl->x, tpl->y, SOUND_PUSH_PLAYER); 2131 play_sound_map(tpl->map, tpl->x, tpl->y, SOUND_PUSH_PLAYER);
2086 (void) push_ob(mon,dir,op); 2132 (void) push_ob(mon,dir,op);
2087 } else { 2133 } else {
2088 new_draw_info(0, 0,op,"You withhold your attack"); 2134 new_draw_info(0, 0,op,"You withhold your attack");
2216 */ 2262 */
2217int handle_newcs_player(object *op) 2263int handle_newcs_player(object *op)
2218{ 2264{
2219 if (op->contr->hidden) { 2265 if (op->contr->hidden) {
2220 op->invisible = 1000; 2266 op->invisible = 1000;
2221 /* the socket code flasehs the player visible/invisible 2267 /* the socket code flashes the player visible/invisible
2222 * depending on the value if invisible, so we need to 2268 * depending on the value of invisible, so we need to
2223 * alternate it here for it to work correctly. 2269 * alternate it here for it to work correctly.
2224 */ 2270 */
2225 if (pticks & 2) op->invisible--; 2271 if (pticks & 2) op->invisible--;
2226 } 2272 }
2227 else if(op->invisible&&!(QUERY_FLAG(op,FLAG_MAKE_INVIS))) { 2273 else if(op->invisible&&!(QUERY_FLAG(op,FLAG_MAKE_INVIS))) {
2495 } 2541 }
2496 } 2542 }
2497 2543
2498 /* Digestion */ 2544 /* Digestion */
2499 if(--op->last_eat<0) { 2545 if(--op->last_eat<0) {
2546#ifdef COZY_SERVER
2547 int dg = op->contr->digestion>=0 && op->contr->digestion<2 ? 2 : op->contr->digestion;
2548 int bonus=dg>0?dg:0,
2549 penalty=dg<0?-dg:0;
2550#else
2500 int bonus=op->contr->digestion>0?op->contr->digestion:0, 2551 int bonus=op->contr->digestion>0?op->contr->digestion:0,
2501 penalty=op->contr->digestion<0?-op->contr->digestion:0; 2552 penalty=op->contr->digestion<0?-op->contr->digestion:0;
2553#endif
2554
2502 if(op->contr->gen_hp > 0) 2555 if(op->contr->gen_hp > 0)
2503 op->last_eat=25*(1+bonus)/(op->contr->gen_hp+penalty+1); 2556 op->last_eat=25*(1+bonus)/(op->contr->gen_hp+penalty+1);
2504 else 2557 else
2505 op->last_eat=25*(1+bonus)/(penalty +1); 2558 op->last_eat=25*(1+bonus)/(penalty +1);
2506 /* dms do not consume food */ 2559 /* dms do not consume food */
2619 2672
2620 /* Lauwenmark: Handle for plugin death event */ 2673 /* Lauwenmark: Handle for plugin death event */
2621 if (execute_event(op, EVENT_DEATH,NULL,NULL,NULL,SCRIPT_FIX_ALL) != 0) 2674 if (execute_event(op, EVENT_DEATH,NULL,NULL,NULL,SCRIPT_FIX_ALL) != 0)
2622 return; 2675 return;
2623 2676
2677 command_kill_pets (op, 0);
2678
2624 /* Lauwenmark: Handle for the global death event */ 2679 /* Lauwenmark: Handle for the global death event */
2625 execute_global_event(EVENT_PLAYER_DEATH, op); 2680 execute_global_event(EVENT_PLAYER_DEATH, op);
2626 if(op->stats.food<0) { 2681 if(op->stats.food<0) {
2627 if (op->contr->explore) { 2682 if (op->contr->explore) {
2628 new_draw_info(NDI_UNIQUE, 0,op,"You would have starved, but you are"); 2683 new_draw_info(NDI_UNIQUE, 0,op,"You would have starved, but you are");
2656 2711
2657 /* Basically two ways to go - remove a stat permanently, or just 2712 /* Basically two ways to go - remove a stat permanently, or just
2658 * make it depletion. This bunch of code deals with that aspect 2713 * make it depletion. This bunch of code deals with that aspect
2659 * of death. 2714 * of death.
2660 */ 2715 */
2661 2716#ifndef COZY_SERVER
2662 if (settings.balanced_stat_loss) { 2717 if (settings.balanced_stat_loss) {
2663 /* If stat loss is permanent, lose one stat only. */ 2718 /* If stat loss is permanent, lose one stat only. */
2664 /* Lower level chars don't lose as many stats because they suffer 2719 /* Lower level chars don't lose as many stats because they suffer
2665 more if they do. */ 2720 more if they do. */
2666 /* Higher level characters can afford things such as potions of 2721 /* Higher level characters can afford things such as potions of
2675 num_stats_lose = 1; 2730 num_stats_lose = 1;
2676 } 2731 }
2677 lost_a_stat = 0; 2732 lost_a_stat = 0;
2678 2733
2679 for (z=0; z<num_stats_lose; z++) { 2734 for (z=0; z<num_stats_lose; z++) {
2735 i = RANDOM() % NUM_STATS;
2736
2680 if (settings.stat_loss_on_death) { 2737 if (settings.stat_loss_on_death) {
2681 /* Pick a random stat and take a point off it. Tell the player 2738 /* Pick a random stat and take a point off it. Tell the player
2682 * what he lost. 2739 * what he lost.
2683 */ 2740 */
2684 i = RANDOM() % 7;
2685 change_attr_value(&(op->stats), i,-1); 2741 change_attr_value(&(op->stats), i,-1);
2686 check_stat_bounds(&(op->stats)); 2742 check_stat_bounds(&(op->stats));
2687 change_attr_value(&(op->contr->orig_stats), i,-1); 2743 change_attr_value(&(op->contr->orig_stats), i,-1);
2688 check_stat_bounds(&(op->contr->orig_stats)); 2744 check_stat_bounds(&(op->contr->orig_stats));
2689 new_draw_info(NDI_UNIQUE, 0,op, lose_msg[i]); 2745 new_draw_info(NDI_UNIQUE, 0,op, lose_msg[i]);
2691 } else { 2747 } else {
2692 /* deplete a stat */ 2748 /* deplete a stat */
2693 archetype *deparch=find_archetype("depletion"); 2749 archetype *deparch=find_archetype("depletion");
2694 object *dep; 2750 object *dep;
2695 2751
2696 i = RANDOM() % 7;
2697 dep = present_arch_in_ob(deparch,op); 2752 dep = present_arch_in_ob(deparch,op);
2698 if(!dep) { 2753 if(!dep) {
2699 dep = arch_to_object(deparch); 2754 dep = arch_to_object(deparch);
2700 insert_ob_in_ob(dep, op); 2755 insert_ob_in_ob(dep, op);
2701 } 2756 }
2757 " you.", god); 2812 " you.", god);
2758 else 2813 else
2759 new_draw_info(NDI_UNIQUE, 0, op, "For a brief moment you" 2814 new_draw_info(NDI_UNIQUE, 0, op, "For a brief moment you"
2760 " feel a holy presence protecting you."); 2815 " feel a holy presence protecting you.");
2761 } 2816 }
2817#endif
2818 new_draw_info(NDI_UNIQUE, 0, op, "For a brief moment you"
2819 " feel a holy presence protecting you from losing yourself completely.");
2762 2820
2763 /* Put a gravestone up where the character 'almost' died. List the 2821 /* Put a gravestone up where the character 'almost' died. List the
2764 * exp loss on the stone. 2822 * exp loss on the stone.
2765 */ 2823 */
2766 tmp=arch_to_object(find_archetype("gravestone")); 2824 tmp=arch_to_object(find_archetype("gravestone"));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines