1 | /* |
1 | /* |
2 | * static char *rcsid_player_c = |
2 | * static char *rcsid_player_c = |
3 | * "$Id: player.C,v 1.6 2006/08/26 23:36:34 root Exp $"; |
3 | * "$Id: player.C,v 1.10 2006/08/29 07:54:38 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 | |
… | |
… | |
202 | static player* get_player(player *p) { |
202 | static player* get_player(player *p) { |
203 | object *op=arch_to_object(get_player_archetype(NULL)); |
203 | object *op=arch_to_object(get_player_archetype(NULL)); |
204 | int i; |
204 | int i; |
205 | |
205 | |
206 | if (!p) { |
206 | if (!p) { |
207 | player *tmp; |
|
|
208 | |
|
|
209 | p = (player *) malloc(sizeof(player)); |
207 | p = (player *) malloc(sizeof(player)); |
210 | if(p==NULL) |
208 | if(p==NULL) |
211 | fatal(OUT_OF_MEMORY); |
209 | fatal(OUT_OF_MEMORY); |
212 | |
210 | |
213 | /* This adds the player in the linked list. There is extra |
211 | /* This adds the player in the linked list. There is extra |
214 | * complexity here because we want to add the new player at the |
212 | * complexity here because we want to add the new player at the |
215 | * end of the list - there is in fact no compelling reason that |
213 | * end of the list - there is in fact no compelling reason that |
216 | * that needs to be done except for things like output of |
214 | * that needs to be done except for things like output of |
217 | * 'who'. |
215 | * 'who'. |
218 | */ |
216 | */ |
219 | tmp=first_player; |
217 | player *tmp = first_player; |
220 | while(tmp!=NULL&&tmp->next!=NULL) |
218 | while(tmp!=NULL&&tmp->next!=NULL) |
221 | tmp=tmp->next; |
219 | tmp=tmp->next; |
222 | if(tmp!=NULL) |
220 | if(tmp!=NULL) |
223 | tmp->next=p; |
221 | tmp->next=p; |
224 | else |
222 | else |
… | |
… | |
229 | |
227 | |
230 | /* Clears basically the entire player structure except |
228 | /* Clears basically the entire player structure except |
231 | * for next and socket. |
229 | * for next and socket. |
232 | */ |
230 | */ |
233 | memset (static_cast<player_memset *>(p), 0, sizeof (player_memset)); |
231 | memset (static_cast<player_memset *>(p), 0, sizeof (player_memset)); |
|
|
232 | p->attachable_init (); //HACK |
234 | |
233 | |
235 | /* There are some elements we want initialized to non zero value - |
234 | /* There are some elements we want initialized to non zero value - |
236 | * we deal with that below this point. |
235 | * we deal with that below this point. |
237 | */ |
236 | */ |
238 | p->party=NULL; |
237 | p->party=NULL; |
… | |
… | |
2017 | * going to try and move (not fire weapons). |
2016 | * going to try and move (not fire weapons). |
2018 | */ |
2017 | */ |
2019 | |
2018 | |
2020 | void move_player_attack(object *op, int dir) |
2019 | void move_player_attack(object *op, int dir) |
2021 | { |
2020 | { |
2022 | object *tmp, *mon, *tpl; |
2021 | object *tmp, *mon; |
2023 | sint16 nx, ny; |
2022 | sint16 nx, ny; |
2024 | int on_battleground; |
2023 | int on_battleground; |
2025 | mapstruct *m; |
2024 | mapstruct *m; |
2026 | |
2025 | |
2027 | if (op->contr->transport) tpl = op->contr->transport; |
|
|
2028 | else tpl = op; |
|
|
2029 | nx=freearr_x[dir]+tpl->x; |
2026 | nx=freearr_x[dir]+op->x; |
2030 | ny=freearr_y[dir]+tpl->y; |
2027 | ny=freearr_y[dir]+op->y; |
2031 | |
2028 | |
2032 | on_battleground = op_on_battleground(tpl, NULL, NULL); |
2029 | on_battleground = op_on_battleground(op, NULL, NULL); |
2033 | |
2030 | |
2034 | /* If braced, or can't move to the square, and it is not out of the |
2031 | /* If braced, or can't move to the square, and it is not out of the |
2035 | * map, attack it. Note order of if statement is important - don't |
2032 | * map, attack it. Note order of if statement is important - don't |
2036 | * want to be calling move_ob if braced, because move_ob will move the |
2033 | * want to be calling move_ob if braced, because move_ob will move the |
2037 | * player. This is a pretty nasty hack, because if we could |
2034 | * player. This is a pretty nasty hack, because if we could |
2038 | * move to some space, it then means that if we are braced, we should |
2035 | * move to some space, it then means that if we are braced, we should |
2039 | * do nothing at all. As it is, if we are braced, we go through |
2036 | * do nothing at all. As it is, if we are braced, we go through |
2040 | * quite a bit of processing. However, it probably is less than what |
2037 | * quite a bit of processing. However, it probably is less than what |
2041 | * move_ob uses. |
2038 | * move_ob uses. |
2042 | */ |
2039 | */ |
2043 | if ((op->contr->braced || !move_ob(tpl,dir,tpl)) && !out_of_map(tpl->map,nx,ny)) { |
2040 | if ((op->contr->braced || !move_ob(op,dir,op)) && !out_of_map(op->map,nx,ny)) { |
2044 | if (OUT_OF_REAL_MAP(tpl->map, nx, ny)) { |
2041 | if (OUT_OF_REAL_MAP(op->map, nx, ny)) { |
2045 | m = get_map_from_coord(tpl->map, &nx, &ny); |
2042 | m = get_map_from_coord(op->map, &nx, &ny); |
2046 | if (!m) return; /* Don't think this should happen */ |
2043 | if (!m) return; /* Don't think this should happen */ |
2047 | } |
2044 | } |
2048 | else m =tpl->map; |
2045 | else m =op->map; |
2049 | |
2046 | |
2050 | if ((tmp=get_map_ob(m,nx,ny))==NULL) { |
2047 | if ((tmp=get_map_ob(m,nx,ny))==NULL) { |
2051 | /* LOG(llevError,"player_move_attack: get_map_ob returns NULL, but player can not more there.\n");*/ |
2048 | /* LOG(llevError,"player_move_attack: get_map_ob returns NULL, but player can not more there.\n");*/ |
2052 | return; |
2049 | return; |
2053 | } |
2050 | } |
… | |
… | |
2106 | #endif |
2103 | #endif |
2107 | && (QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY))) |
2104 | && (QUERY_FLAG(mon,FLAG_UNAGGRESSIVE) || QUERY_FLAG(mon, FLAG_FRIENDLY))) |
2108 | { |
2105 | { |
2109 | /* If we're braced, we don't want to switch places with it */ |
2106 | /* If we're braced, we don't want to switch places with it */ |
2110 | if (op->contr->braced) return; |
2107 | if (op->contr->braced) return; |
2111 | play_sound_map(tpl->map, tpl->x, tpl->y, SOUND_PUSH_PLAYER); |
2108 | play_sound_map(op->map, op->x, op->y, SOUND_PUSH_PLAYER); |
2112 | (void) push_ob(mon,dir,op); |
2109 | (void) push_ob(mon,dir,op); |
2113 | if(op->contr->tmp_invis||op->hide) make_visible(op); |
2110 | if(op->contr->tmp_invis||op->hide) make_visible(op); |
2114 | return; |
2111 | return; |
2115 | } |
2112 | } |
2116 | |
2113 | |
… | |
… | |
2128 | op->contr->peaceful && |
2125 | op->contr->peaceful && |
2129 | #endif |
2126 | #endif |
2130 | !on_battleground |
2127 | !on_battleground |
2131 | )) { |
2128 | )) { |
2132 | if (!op->contr->braced) { |
2129 | if (!op->contr->braced) { |
2133 | play_sound_map(tpl->map, tpl->x, tpl->y, SOUND_PUSH_PLAYER); |
2130 | play_sound_map(op->map, op->x, op->y, SOUND_PUSH_PLAYER); |
2134 | (void) push_ob(mon,dir,op); |
2131 | (void) push_ob(mon,dir,op); |
2135 | } else { |
2132 | } else { |
2136 | new_draw_info(0, 0,op,"You withhold your attack"); |
2133 | new_draw_info(0, 0,op,"You withhold your attack"); |
2137 | } |
2134 | } |
2138 | if(op->contr->tmp_invis||op->hide) make_visible(op); |
2135 | if(op->contr->tmp_invis||op->hide) make_visible(op); |
… | |
… | |
2187 | } /* if player should attack something */ |
2184 | } /* if player should attack something */ |
2188 | } |
2185 | } |
2189 | |
2186 | |
2190 | int move_player(object *op,int dir) { |
2187 | int move_player(object *op,int dir) { |
2191 | int pick; |
2188 | int pick; |
2192 | object *transport = op->contr->transport; |
|
|
2193 | |
2189 | |
2194 | if(!transport && (op->map == NULL || op->map->in_memory != MAP_IN_MEMORY)) |
2190 | if(op->map == NULL || op->map->in_memory != MAP_IN_MEMORY) |
2195 | return 0; |
2191 | return 0; |
2196 | |
2192 | |
2197 | /* Sanity check: make sure dir is valid */ |
2193 | /* Sanity check: make sure dir is valid */ |
2198 | if ( ( dir < 0 ) || ( dir >= 9 ) ) { |
2194 | if ( ( dir < 0 ) || ( dir >= 9 ) ) { |
2199 | LOG( llevError, "move_player: invalid direction %d\n", dir); |
2195 | LOG( llevError, "move_player: invalid direction %d\n", dir); |
… | |
… | |
2204 | if(QUERY_FLAG(op,FLAG_CONFUSED) && dir) |
2200 | if(QUERY_FLAG(op,FLAG_CONFUSED) && dir) |
2205 | dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2); |
2201 | dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2); |
2206 | |
2202 | |
2207 | op->facing = dir; |
2203 | op->facing = dir; |
2208 | |
2204 | |
2209 | if(!transport && op->hide) do_hidden_move(op); |
2205 | if(op->hide) do_hidden_move(op); |
2210 | |
2206 | |
2211 | if (transport) { |
2207 | if (INVOKE_PLAYER (MOVE, op->contr, ARG_INT (dir))) |
2212 | /* transport->contr is set up for the person in charge of the boat. |
2208 | /*nop*/; |
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 | } |
|
|
2233 | |
|
|
2234 | if(op->contr->fire_on) { |
2209 | else if (op->contr->fire_on) |
2235 | fire(op,dir); |
2210 | fire (op, dir); |
2236 | } |
2211 | else |
|
|
2212 | { |
2237 | else move_player_attack(op,dir); |
2213 | move_player_attack (op, dir); |
2238 | |
|
|
2239 | pick = check_pick(op); |
2214 | pick = check_pick(op); |
2240 | |
2215 | } |
2241 | |
2216 | |
2242 | /* Add special check for newcs players and fire on - this way, the |
2217 | /* Add special check for newcs players and fire on - this way, the |
2243 | * server can handle repeat firing. |
2218 | * server can handle repeat firing. |
2244 | */ |
2219 | */ |
2245 | if (op->contr->fire_on || (op->contr->run_on && pick!=0)) { |
2220 | if (op->contr->fire_on || (op->contr->run_on && pick!=0)) { |
… | |
… | |
2249 | } |
2224 | } |
2250 | /* Update how the player looks. Use the facing, so direction may |
2225 | /* Update how the player looks. Use the facing, so direction may |
2251 | * get reset to zero. This allows for full animation capabilities |
2226 | * get reset to zero. This allows for full animation capabilities |
2252 | * for players. |
2227 | * for players. |
2253 | */ |
2228 | */ |
2254 | if (!transport) animate_object(op, op->facing); |
2229 | animate_object(op, op->facing); |
2255 | return 0; |
2230 | return 0; |
2256 | } |
2231 | } |
2257 | |
2232 | |
2258 | /* This is similar to handle_player, below, but is only used by the |
2233 | /* This is similar to handle_player, below, but is only used by the |
2259 | * new client/server stuff. |
2234 | * new client/server stuff. |