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.4 by root, Thu Feb 9 02:11:26 2006 UTC vs.
Revision 1.13 by pippijn, Fri Apr 21 14:40:31 2006 UTC

1/* 1/*
2 * static char *rcsid_player_c = 2 * static char *rcsid_player_c =
3 * "$Id: player.c,v 1.4 2006/02/09 02:11:26 root Exp $"; 3 * "$Id: player.c,v 1.13 2006/04/21 14:40:31 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
77 } 77 }
78 } 78 }
79 return found; 79 return found;
80 } 80 }
81 81
82void display_motd(object *op) { 82void display_motd(const object *op) {
83 char buf[MAX_BUF]; 83 char buf[MAX_BUF];
84 char motd[HUGE_BUF]; 84 char motd[HUGE_BUF];
85 FILE *fp; 85 FILE *fp;
86 int comp; 86 int comp;
87 int size; 87 int size;
100 } 100 }
101 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);
102 close_and_delete(fp, comp); 102 close_and_delete(fp, comp);
103} 103}
104 104
105void send_rules(object *op) { 105void send_rules(const object *op) {
106 char buf[MAX_BUF]; 106 char buf[MAX_BUF];
107 char rules[HUGE_BUF]; 107 char rules[HUGE_BUF];
108 FILE *fp; 108 FILE *fp;
109 int comp; 109 int comp;
110 int size; 110 int size;
128 } 128 }
129 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);
130 close_and_delete(fp, comp); 130 close_and_delete(fp, comp);
131} 131}
132 132
133void send_news(object *op) { 133void send_news(const object *op) {
134 char buf[MAX_BUF]; 134 char buf[MAX_BUF];
135 char news[HUGE_BUF]; 135 char news[HUGE_BUF];
136 char subject[MAX_BUF]; 136 char subject[MAX_BUF];
137 FILE *fp; 137 FILE *fp;
138 int comp; 138 int comp;
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;
253 op->speed_left=0.5; 253 op->speed_left=0.5;
254 op->speed=1.0; 254 op->speed=1.0;
255 op->direction=5; /* So player faces south */ 255 op->direction=5; /* So player faces south */
256 op->stats.wc=2; 256 op->stats.wc=2;
257 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 */
258 259
259 roll_stats(op); 260 roll_stats(op);
260 p->state=ST_ROLL_STAT; 261 p->state=ST_ROLL_STAT;
261 clear_los(op); 262 clear_los(op);
262 263
638 if(op->type==SPELL) { 639 if(op->type==SPELL) {
639 remove_ob(op); 640 remove_ob(op);
640 free_object(op); 641 free_object(op);
641 continue; 642 continue;
642 } 643 }
643 if(op->type==SKILL) { 644 else if(op->type==SKILL) {
644 SET_FLAG(op, FLAG_CAN_USE_SKILL); 645 SET_FLAG(op, FLAG_CAN_USE_SKILL);
645 op->stats.exp = 0; 646 op->stats.exp = 0;
646 op->level = 1; 647 op->level = 1;
647 } 648 }
649 /* lock all 'normal items by default */
650 else SET_FLAG(op, FLAG_INV_LOCKED);
648 } /* for loop of objects in player inv */ 651 } /* for loop of objects in player inv */
649 652
650 /* Need to set up the skill pointers */ 653 /* Need to set up the skill pointers */
651 link_player_skills(pl); 654 link_player_skills(pl);
652} 655}
947 } 950 }
948 return 0; 951 return 0;
949} 952}
950 953
951/* This function takes the key that is passed, and does the 954/* This function takes the key that is passed, and does the
952 * appropriate action with it (change class, or other things. 955 * appropriate action with it (change race, or other things).
956 * The function name is for historical reasons - now we have
957 * separate race and class; this actually changes the RACE,
958 * not the class.
953 */ 959 */
954 960
955int key_change_class(object *op, char key) 961int key_change_class(object *op, char key)
956{ 962{
957 int tmp_loop; 963 int tmp_loop;
958 964
959 if(key=='q'||key=='Q') { 965 if(key=='q'||key=='Q') {
960 remove_ob(op); 966 remove_ob(op);
961 play_again(op); 967 play_again(op);
962 return 0; 968 return 0;
993 CLEAR_FLAG(op, FLAG_WIZ); 999 CLEAR_FLAG(op, FLAG_WIZ);
994 give_initial_items(op,op->randomitems); 1000 give_initial_items(op,op->randomitems);
995 link_player_skills(op); 1001 link_player_skills(op);
996 esrv_send_inventory(op, op); 1002 esrv_send_inventory(op, op);
997 fix_player(op); 1003 fix_player(op);
1004
1005 /* This moves the player to a different start map, if there
1006 * is one for this race
1007 */
1008 if(*first_map_ext_path) {
1009 object *tmp;
1010 mapstruct *oldmap = op->map;
1011 char mapname[MAX_BUF];
1012 snprintf(mapname, MAX_BUF-1, "%s/%s",
1013 first_map_ext_path, op->arch->name);
1014 printf("%s\n", mapname);
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 }
998 return 0; 1026 return 0;
999 } 1027 }
1000 1028
1001 /* Following actually changes the class - this is the default command 1029 /* Following actually changes the race - this is the default command
1002 * if we don't match with one of the options above. 1030 * if we don't match with one of the options above.
1003 */ 1031 */
1004 1032
1005 tmp_loop = 0; 1033 tmp_loop = 0;
1006 while(!tmp_loop) { 1034 while(!tmp_loop) {
1987 * going to try and move (not fire weapons). 2015 * going to try and move (not fire weapons).
1988 */ 2016 */
1989 2017
1990void move_player_attack(object *op, int dir) 2018void move_player_attack(object *op, int dir)
1991{ 2019{
1992 object *tmp, *mon; 2020 object *tmp, *mon, *tpl;
1993 sint16 nx=freearr_x[dir]+op->x,ny=freearr_y[dir]+op->y; 2021 sint16 nx, ny;
1994 int on_battleground; 2022 int on_battleground;
1995 mapstruct *m; 2023 mapstruct *m;
1996 2024
2025 if (op->contr->transport) tpl = op->contr->transport;
2026 else tpl = op;
2027 nx=freearr_x[dir]+tpl->x;
2028 ny=freearr_y[dir]+tpl->y;
2029
1997 on_battleground = op_on_battleground(op, NULL, NULL); 2030 on_battleground = op_on_battleground(tpl, NULL, NULL);
1998 2031
1999 /* If braced, or can't move to the square, and it is not out of the 2032 /* If braced, or can't move to the square, and it is not out of the
2000 * map, attack it. Note order of if statement is important - don't 2033 * map, attack it. Note order of if statement is important - don't
2001 * want to be calling move_ob if braced, because move_ob will move the 2034 * want to be calling move_ob if braced, because move_ob will move the
2002 * player. This is a pretty nasty hack, because if we could 2035 * player. This is a pretty nasty hack, because if we could
2003 * move to some space, it then means that if we are braced, we should 2036 * move to some space, it then means that if we are braced, we should
2004 * do nothing at all. As it is, if we are braced, we go through 2037 * do nothing at all. As it is, if we are braced, we go through
2005 * quite a bit of processing. However, it probably is less than what 2038 * quite a bit of processing. However, it probably is less than what
2006 * move_ob uses. 2039 * move_ob uses.
2007 */ 2040 */
2008 if ((op->contr->braced || !move_ob(op,dir,op)) && !out_of_map(op->map,nx,ny)) { 2041 if ((op->contr->braced || !move_ob(tpl,dir,tpl)) && !out_of_map(tpl->map,nx,ny)) {
2009 if (OUT_OF_REAL_MAP(op->map, nx, ny)) { 2042 if (OUT_OF_REAL_MAP(tpl->map, nx, ny)) {
2010 m = get_map_from_coord(op->map, &nx, &ny); 2043 m = get_map_from_coord(tpl->map, &nx, &ny);
2011 if (!m) return; /* Don't think this should happen */ 2044 if (!m) return; /* Don't think this should happen */
2012 } 2045 }
2013 else m =op->map; 2046 else m =tpl->map;
2014 2047
2015 if ((tmp=get_map_ob(m,nx,ny))==NULL) { 2048 if ((tmp=get_map_ob(m,nx,ny))==NULL) {
2016 /* LOG(llevError,"player_move_attack: get_map_ob returns NULL, but player can not more there.\n");*/ 2049 /* LOG(llevError,"player_move_attack: get_map_ob returns NULL, but player can not more there.\n");*/
2017 return; 2050 return;
2018 } 2051 }
2071#endif 2104#endif
2072 && (QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY))) 2105 && (QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY)))
2073 { 2106 {
2074 /* 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 */
2075 if (op->contr->braced) return; 2108 if (op->contr->braced) return;
2076 play_sound_map(op->map, op->x, op->y, SOUND_PUSH_PLAYER); 2109 play_sound_map(tpl->map, tpl->x, tpl->y, SOUND_PUSH_PLAYER);
2077 (void) push_ob(mon,dir,op); 2110 (void) push_ob(mon,dir,op);
2078 if(op->contr->tmp_invis||op->hide) make_visible(op); 2111 if(op->contr->tmp_invis||op->hide) make_visible(op);
2079 return; 2112 return;
2080 } 2113 }
2081 2114
2084 * 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
2085 * attack them either. 2118 * attack them either.
2086 */ 2119 */
2087 if ((mon->type==PLAYER || mon->enemy != op) && 2120 if ((mon->type==PLAYER || mon->enemy != op) &&
2088 (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)) &&
2089 (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 )) {
2090 if (!op->contr->braced) { 2130 if (!op->contr->braced) {
2091 play_sound_map(op->map, op->x, op->y, SOUND_PUSH_PLAYER); 2131 play_sound_map(tpl->map, tpl->x, tpl->y, SOUND_PUSH_PLAYER);
2092 (void) push_ob(mon,dir,op); 2132 (void) push_ob(mon,dir,op);
2093 } else { 2133 } else {
2094 new_draw_info(0, 0,op,"You withhold your attack"); 2134 new_draw_info(0, 0,op,"You withhold your attack");
2095 } 2135 }
2096 if(op->contr->tmp_invis||op->hide) make_visible(op); 2136 if(op->contr->tmp_invis||op->hide) make_visible(op);
2145 } /* if player should attack something */ 2185 } /* if player should attack something */
2146} 2186}
2147 2187
2148int move_player(object *op,int dir) { 2188int move_player(object *op,int dir) {
2149 int pick; 2189 int pick;
2190 object *transport = op->contr->transport;
2150 2191
2151 if(op->map == NULL || op->map->in_memory != MAP_IN_MEMORY) 2192 if(!transport && (op->map == NULL || op->map->in_memory != MAP_IN_MEMORY))
2152 return 0; 2193 return 0;
2153 2194
2154 /* Sanity check: make sure dir is valid */ 2195 /* Sanity check: make sure dir is valid */
2155 if ( ( dir < 0 ) || ( dir >= 9 ) ) { 2196 if ( ( dir < 0 ) || ( dir >= 9 ) ) {
2156 LOG( llevError, "move_player: invalid direction %d\n", dir); 2197 LOG( llevError, "move_player: invalid direction %d\n", dir);
2161 if(QUERY_FLAG(op,FLAG_CONFUSED) && dir) 2202 if(QUERY_FLAG(op,FLAG_CONFUSED) && dir)
2162 dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2); 2203 dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2);
2163 2204
2164 op->facing = dir; 2205 op->facing = dir;
2165 2206
2166 if(op->hide) do_hidden_move(op); 2207 if(!transport && op->hide) do_hidden_move(op);
2208
2209 if (transport) {
2210 /* transport->contr is set up for the person in charge of the boat.
2211 * if that isn't this person, he can't steer it, etc
2212 */
2213 if (transport->contr != op->contr) return 0;
2214
2215 /* Transport can't move. But update dir so it at least
2216 * will point in the same direction if player is running.
2217 */
2218 if (transport->speed_left < 0.0) {
2219 transport->direction = dir;
2220 op->direction = dir;
2221 return 0;
2222 }
2223 /* Remove transport speed. Give player just a little speed -
2224 * enough so that they will get an action again quickly.
2225 *
2226 */
2227 transport->speed_left -= 1.0;
2228 if (op->speed_left < 0.0) op->speed_left = -0.01;
2229
2230 }
2167 2231
2168 if(op->contr->fire_on) { 2232 if(op->contr->fire_on) {
2169 fire(op,dir); 2233 fire(op,dir);
2170 } 2234 }
2171 else move_player_attack(op,dir); 2235 else move_player_attack(op,dir);
2183 } 2247 }
2184 /* Update how the player looks. Use the facing, so direction may 2248 /* Update how the player looks. Use the facing, so direction may
2185 * get reset to zero. This allows for full animation capabilities 2249 * get reset to zero. This allows for full animation capabilities
2186 * for players. 2250 * for players.
2187 */ 2251 */
2188 animate_object(op, op->facing); 2252 if (!transport) animate_object(op, op->facing);
2189 return 0; 2253 return 0;
2190} 2254}
2191 2255
2192/* This is similar to handle_player, below, but is only used by the 2256/* This is similar to handle_player, below, but is only used by the
2193 * new client/server stuff. 2257 * new client/server stuff.
2198 */ 2262 */
2199int handle_newcs_player(object *op) 2263int handle_newcs_player(object *op)
2200{ 2264{
2201 if (op->contr->hidden) { 2265 if (op->contr->hidden) {
2202 op->invisible = 1000; 2266 op->invisible = 1000;
2203 /* the socket code flasehs the player visible/invisible 2267 /* the socket code flashes the player visible/invisible
2204 * depending on the value if invisible, so we need to 2268 * depending on the value of invisible, so we need to
2205 * alternate it here for it to work correctly. 2269 * alternate it here for it to work correctly.
2206 */ 2270 */
2207 if (pticks & 2) op->invisible--; 2271 if (pticks & 2) op->invisible--;
2208 } 2272 }
2209 else if(op->invisible&&!(QUERY_FLAG(op,FLAG_MAKE_INVIS))) { 2273 else if(op->invisible&&!(QUERY_FLAG(op,FLAG_MAKE_INVIS))) {
2664 num_stats_lose = 1; 2728 num_stats_lose = 1;
2665 } 2729 }
2666 lost_a_stat = 0; 2730 lost_a_stat = 0;
2667 2731
2668 for (z=0; z<num_stats_lose; z++) { 2732 for (z=0; z<num_stats_lose; z++) {
2733 i = RANDOM() % NUM_STATS;
2734
2669 if (settings.stat_loss_on_death) { 2735 if (settings.stat_loss_on_death) {
2670 /* Pick a random stat and take a point off it. Tell the player 2736 /* Pick a random stat and take a point off it. Tell the player
2671 * what he lost. 2737 * what he lost.
2672 */ 2738 */
2673 i = RANDOM() % 7;
2674 change_attr_value(&(op->stats), i,-1); 2739 change_attr_value(&(op->stats), i,-1);
2675 check_stat_bounds(&(op->stats)); 2740 check_stat_bounds(&(op->stats));
2676 change_attr_value(&(op->contr->orig_stats), i,-1); 2741 change_attr_value(&(op->contr->orig_stats), i,-1);
2677 check_stat_bounds(&(op->contr->orig_stats)); 2742 check_stat_bounds(&(op->contr->orig_stats));
2678 new_draw_info(NDI_UNIQUE, 0,op, lose_msg[i]); 2743 new_draw_info(NDI_UNIQUE, 0,op, lose_msg[i]);
2680 } else { 2745 } else {
2681 /* deplete a stat */ 2746 /* deplete a stat */
2682 archetype *deparch=find_archetype("depletion"); 2747 archetype *deparch=find_archetype("depletion");
2683 object *dep; 2748 object *dep;
2684 2749
2685 i = RANDOM() % 7;
2686 dep = present_arch_in_ob(deparch,op); 2750 dep = present_arch_in_ob(deparch,op);
2687 if(!dep) { 2751 if(!dep) {
2688 dep = arch_to_object(deparch); 2752 dep = arch_to_object(deparch);
2689 insert_ob_in_ob(dep, op); 2753 insert_ob_in_ob(dep, op);
2690 } 2754 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines