1 | |
|
|
2 | /* |
|
|
3 | * static char *rcsid_living_c = |
|
|
4 | * "$Id: living.C,v 1.9 2006/09/10 16:00:23 root Exp $"; |
|
|
5 | */ |
|
|
6 | |
|
|
7 | /* |
1 | /* |
8 | CrossFire, A Multiplayer game for X-windows |
2 | CrossFire, A Multiplayer game for X-windows |
9 | |
3 | |
10 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
4 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
11 | Copyright (C) 1992 Frank Tore Johansen |
5 | Copyright (C) 1992 Frank Tore Johansen |
… | |
… | |
251 | void |
245 | void |
252 | set_attr_value (living * stats, int attr, sint8 value) |
246 | set_attr_value (living * stats, int attr, sint8 value) |
253 | { |
247 | { |
254 | switch (attr) |
248 | switch (attr) |
255 | { |
249 | { |
256 | case STR: |
250 | case STR: |
257 | stats->Str = value; |
251 | stats->Str = value; |
258 | break; |
252 | break; |
259 | case DEX: |
253 | case DEX: |
260 | stats->Dex = value; |
254 | stats->Dex = value; |
261 | break; |
255 | break; |
262 | case CON: |
256 | case CON: |
263 | stats->Con = value; |
257 | stats->Con = value; |
264 | break; |
258 | break; |
265 | case WIS: |
259 | case WIS: |
266 | stats->Wis = value; |
260 | stats->Wis = value; |
267 | break; |
261 | break; |
268 | case POW: |
262 | case POW: |
269 | stats->Pow = value; |
263 | stats->Pow = value; |
270 | break; |
264 | break; |
271 | case CHA: |
265 | case CHA: |
272 | stats->Cha = value; |
266 | stats->Cha = value; |
273 | break; |
267 | break; |
274 | case INT: |
268 | case INT: |
275 | stats->Int = value; |
269 | stats->Int = value; |
276 | break; |
270 | break; |
277 | } |
271 | } |
278 | } |
272 | } |
279 | |
273 | |
280 | /* |
274 | /* |
281 | * Like set_attr_value(), but instead the value (which can be negative) |
275 | * Like set_attr_value(), but instead the value (which can be negative) |
… | |
… | |
287 | { |
281 | { |
288 | if (value == 0) |
282 | if (value == 0) |
289 | return; |
283 | return; |
290 | switch (attr) |
284 | switch (attr) |
291 | { |
285 | { |
292 | case STR: |
286 | case STR: |
293 | stats->Str += value; |
287 | stats->Str += value; |
294 | break; |
288 | break; |
295 | case DEX: |
289 | case DEX: |
296 | stats->Dex += value; |
290 | stats->Dex += value; |
297 | break; |
291 | break; |
298 | case CON: |
292 | case CON: |
299 | stats->Con += value; |
293 | stats->Con += value; |
300 | break; |
294 | break; |
301 | case WIS: |
295 | case WIS: |
302 | stats->Wis += value; |
296 | stats->Wis += value; |
303 | break; |
297 | break; |
304 | case POW: |
298 | case POW: |
305 | stats->Pow += value; |
299 | stats->Pow += value; |
306 | break; |
300 | break; |
307 | case CHA: |
301 | case CHA: |
308 | stats->Cha += value; |
302 | stats->Cha += value; |
309 | break; |
303 | break; |
310 | case INT: |
304 | case INT: |
311 | stats->Int += value; |
305 | stats->Int += value; |
312 | break; |
306 | break; |
313 | default: |
307 | default: |
314 | LOG (llevError, "Invalid attribute in change_attr_value: %d\n", attr); |
308 | LOG (llevError, "Invalid attribute in change_attr_value: %d\n", attr); |
315 | } |
309 | } |
316 | } |
310 | } |
317 | |
311 | |
318 | /* |
312 | /* |
319 | * returns the specified stat. See also set_attr_value(). |
313 | * returns the specified stat. See also set_attr_value(). |
… | |
… | |
322 | sint8 |
316 | sint8 |
323 | get_attr_value (const living * stats, int attr) |
317 | get_attr_value (const living * stats, int attr) |
324 | { |
318 | { |
325 | switch (attr) |
319 | switch (attr) |
326 | { |
320 | { |
327 | case STR: |
321 | case STR: |
328 | return (stats->Str); |
322 | return (stats->Str); |
329 | case DEX: |
323 | case DEX: |
330 | return (stats->Dex); |
324 | return (stats->Dex); |
331 | case CON: |
325 | case CON: |
332 | return (stats->Con); |
326 | return (stats->Con); |
333 | case WIS: |
327 | case WIS: |
334 | return (stats->Wis); |
328 | return (stats->Wis); |
335 | case CHA: |
329 | case CHA: |
336 | return (stats->Cha); |
330 | return (stats->Cha); |
337 | case INT: |
331 | case INT: |
338 | return (stats->Int); |
332 | return (stats->Int); |
339 | case POW: |
333 | case POW: |
340 | return (stats->Pow); |
334 | return (stats->Pow); |
341 | } |
335 | } |
342 | return 0; |
336 | return 0; |
343 | } |
337 | } |
344 | |
338 | |
345 | /* |
339 | /* |
… | |
… | |
1103 | added_speed += (float) tmp->stats.exp; |
1097 | added_speed += (float) tmp->stats.exp; |
1104 | } |
1098 | } |
1105 | |
1099 | |
1106 | switch (tmp->type) |
1100 | switch (tmp->type) |
1107 | { |
1101 | { |
1108 | /* skills modifying the character -b.t. */ |
1102 | /* skills modifying the character -b.t. */ |
1109 | /* for all skills and skill granting objects */ |
1103 | /* for all skills and skill granting objects */ |
1110 | case SKILL: |
1104 | case SKILL: |
1111 | if (!QUERY_FLAG (tmp, FLAG_APPLIED)) |
1105 | if (!QUERY_FLAG (tmp, FLAG_APPLIED)) |
1112 | break; |
|
|
1113 | |
|
|
1114 | if (IS_COMBAT_SKILL (tmp->subtype)) |
|
|
1115 | wc_obj = tmp; |
|
|
1116 | |
|
|
1117 | if (op->chosen_skill) |
|
|
1118 | { |
|
|
1119 | LOG (llevDebug, "fix_player, op %s has multiple skills applied\n", &op->name); |
|
|
1120 | } |
|
|
1121 | op->chosen_skill = tmp; |
|
|
1122 | if (tmp->stats.dam > 0) |
|
|
1123 | { /* skill is a 'weapon' */ |
|
|
1124 | if (!QUERY_FLAG (op, FLAG_READY_WEAPON)) |
|
|
1125 | weapon_speed = (int) WEAPON_SPEED (tmp); |
|
|
1126 | if (weapon_speed < 0) |
|
|
1127 | weapon_speed = 0; |
|
|
1128 | weapon_weight = tmp->weight; |
|
|
1129 | op->stats.dam += tmp->stats.dam * (1 + (op->chosen_skill->level / 9)); |
|
|
1130 | if (tmp->magic) |
|
|
1131 | op->stats.dam += tmp->magic; |
|
|
1132 | } |
|
|
1133 | if (tmp->stats.wc) |
|
|
1134 | wc -= (tmp->stats.wc + tmp->magic); |
|
|
1135 | |
|
|
1136 | if (tmp->slaying != NULL) |
|
|
1137 | op->slaying = tmp->slaying; |
|
|
1138 | |
|
|
1139 | if (tmp->stats.ac) |
|
|
1140 | ac -= (tmp->stats.ac + tmp->magic); |
|
|
1141 | if (settings.spell_encumbrance == TRUE && op->type == PLAYER) |
|
|
1142 | op->contr->encumbrance += (int) 3 *tmp->weight / 1000; |
|
|
1143 | |
|
|
1144 | if (op->type == PLAYER) |
|
|
1145 | op->contr->ranges[range_skill] = op; |
|
|
1146 | break; |
1106 | break; |
1147 | |
1107 | |
1148 | case SKILL_TOOL: |
1108 | if (IS_COMBAT_SKILL (tmp->subtype)) |
|
|
1109 | wc_obj = tmp; |
|
|
1110 | |
1149 | if (op->chosen_skill) |
1111 | if (op->chosen_skill) |
1150 | { |
|
|
1151 | LOG (llevDebug, "fix_player, op %s has multiple skills applied\n", &op->name); |
1112 | LOG (llevDebug, "fix_player, op %s has multiple skills applied\n", &op->name); |
1152 | } |
1113 | |
1153 | op->chosen_skill = tmp; |
1114 | op->chosen_skill = tmp; |
1154 | if (op->type == PLAYER) |
1115 | |
1155 | op->contr->ranges[range_skill] = op; |
1116 | if (tmp->stats.dam > 0) |
|
|
1117 | { /* skill is a 'weapon' */ |
|
|
1118 | if (!QUERY_FLAG (op, FLAG_READY_WEAPON)) |
|
|
1119 | weapon_speed = (int) WEAPON_SPEED (tmp); |
|
|
1120 | if (weapon_speed < 0) |
|
|
1121 | weapon_speed = 0; |
|
|
1122 | weapon_weight = tmp->weight; |
|
|
1123 | op->stats.dam += tmp->stats.dam * (1 + (op->chosen_skill->level / 9)); |
|
|
1124 | if (tmp->magic) |
|
|
1125 | op->stats.dam += tmp->magic; |
1156 | break; |
1126 | } |
1157 | |
1127 | |
1158 | case SHIELD: |
|
|
1159 | if (settings.spell_encumbrance == TRUE && op->type == PLAYER) |
|
|
1160 | op->contr->encumbrance += (int) tmp->weight / 2000; |
|
|
1161 | case RING: |
|
|
1162 | case AMULET: |
|
|
1163 | case GIRDLE: |
|
|
1164 | case HELMET: |
|
|
1165 | case BOOTS: |
|
|
1166 | case GLOVES: |
|
|
1167 | case CLOAK: |
|
|
1168 | if (tmp->stats.wc) |
1128 | if (tmp->stats.wc) |
1169 | wc -= (tmp->stats.wc + tmp->magic); |
|
|
1170 | if (tmp->stats.dam) |
|
|
1171 | op->stats.dam += (tmp->stats.dam + tmp->magic); |
|
|
1172 | if (tmp->stats.ac) |
|
|
1173 | ac -= (tmp->stats.ac + tmp->magic); |
|
|
1174 | break; |
|
|
1175 | |
|
|
1176 | case WEAPON: |
|
|
1177 | wc -= (tmp->stats.wc + tmp->magic); |
1129 | wc -= (tmp->stats.wc + tmp->magic); |
1178 | if (tmp->stats.ac && tmp->stats.ac + tmp->magic > 0) |
1130 | |
|
|
1131 | if (tmp->slaying != NULL) |
|
|
1132 | op->slaying = tmp->slaying; |
|
|
1133 | |
|
|
1134 | if (tmp->stats.ac) |
1179 | ac -= tmp->stats.ac + tmp->magic; |
1135 | ac -= (tmp->stats.ac + tmp->magic); |
|
|
1136 | if (settings.spell_encumbrance == TRUE && op->type == PLAYER) |
|
|
1137 | op->contr->encumbrance += (int) 3 *tmp->weight / 1000; |
|
|
1138 | |
|
|
1139 | if (op->type == PLAYER) |
|
|
1140 | op->contr->ranges[range_skill] = op; |
|
|
1141 | break; |
|
|
1142 | |
|
|
1143 | case SKILL_TOOL: |
|
|
1144 | if (op->chosen_skill) |
|
|
1145 | { |
|
|
1146 | LOG (llevDebug, "fix_player, op %s has multiple skills applied\n", &op->name); |
|
|
1147 | } |
|
|
1148 | op->chosen_skill = tmp; |
|
|
1149 | if (op->type == PLAYER) |
|
|
1150 | op->contr->ranges[range_skill] = op; |
|
|
1151 | break; |
|
|
1152 | |
|
|
1153 | case SHIELD: |
|
|
1154 | if (settings.spell_encumbrance == TRUE && op->type == PLAYER) |
|
|
1155 | op->contr->encumbrance += (int) tmp->weight / 2000; |
|
|
1156 | case RING: |
|
|
1157 | case AMULET: |
|
|
1158 | case GIRDLE: |
|
|
1159 | case HELMET: |
|
|
1160 | case BOOTS: |
|
|
1161 | case GLOVES: |
|
|
1162 | case CLOAK: |
|
|
1163 | if (tmp->stats.wc) |
|
|
1164 | wc -= (tmp->stats.wc + tmp->magic); |
|
|
1165 | if (tmp->stats.dam) |
1180 | op->stats.dam += (tmp->stats.dam + tmp->magic); |
1166 | op->stats.dam += (tmp->stats.dam + tmp->magic); |
|
|
1167 | if (tmp->stats.ac) |
|
|
1168 | ac -= (tmp->stats.ac + tmp->magic); |
|
|
1169 | break; |
|
|
1170 | |
|
|
1171 | case WEAPON: |
|
|
1172 | wc -= (tmp->stats.wc + tmp->magic); |
|
|
1173 | if (tmp->stats.ac && tmp->stats.ac + tmp->magic > 0) |
|
|
1174 | ac -= tmp->stats.ac + tmp->magic; |
|
|
1175 | op->stats.dam += (tmp->stats.dam + tmp->magic); |
1181 | weapon_weight = tmp->weight; |
1176 | weapon_weight = tmp->weight; |
1182 | weapon_speed = ((int) WEAPON_SPEED (tmp) * 2 - tmp->magic) / 2; |
1177 | weapon_speed = ((int) WEAPON_SPEED (tmp) * 2 - tmp->magic) / 2; |
1183 | if (weapon_speed < 0) |
1178 | if (weapon_speed < 0) |
1184 | weapon_speed = 0; |
1179 | weapon_speed = 0; |
1185 | op->slaying = tmp->slaying; |
1180 | op->slaying = tmp->slaying; |
1186 | /* If there is desire that two handed weapons should do |
1181 | /* If there is desire that two handed weapons should do |
1187 | * extra strength damage, this is where the code should |
1182 | * extra strength damage, this is where the code should |
1188 | * go. |
1183 | * go. |
1189 | */ |
1184 | */ |
1190 | op->current_weapon = tmp; |
1185 | op->current_weapon = tmp; |
1191 | if (settings.spell_encumbrance == TRUE && op->type == PLAYER) |
1186 | if (settings.spell_encumbrance == TRUE && op->type == PLAYER) |
1192 | op->contr->encumbrance += (int) 3 *tmp->weight / 1000; |
1187 | op->contr->encumbrance += (int) 3 *tmp->weight / 1000; |
1193 | |
1188 | |
1194 | break; |
1189 | break; |
1195 | |
1190 | |
1196 | case ARMOUR: /* Only the best of these three are used: */ |
1191 | case ARMOUR: /* Only the best of these three are used: */ |
1197 | if (settings.spell_encumbrance == TRUE && op->type == PLAYER) |
1192 | if (settings.spell_encumbrance == TRUE && op->type == PLAYER) |
1198 | op->contr->encumbrance += (int) tmp->weight / 1000; |
1193 | op->contr->encumbrance += (int) tmp->weight / 1000; |
1199 | |
1194 | |
1200 | case BRACERS: |
1195 | case BRACERS: |
1201 | case FORCE: |
1196 | case FORCE: |
1202 | if (tmp->stats.wc) |
1197 | if (tmp->stats.wc) |
1203 | { |
1198 | { |
1204 | if (best_wc < tmp->stats.wc + tmp->magic) |
1199 | if (best_wc < tmp->stats.wc + tmp->magic) |
1205 | { |
1200 | { |
1206 | wc += best_wc; |
1201 | wc += best_wc; |
1207 | best_wc = tmp->stats.wc + tmp->magic; |
1202 | best_wc = tmp->stats.wc + tmp->magic; |
1208 | } |
1203 | } |
1209 | else |
1204 | else |
1210 | wc += tmp->stats.wc + tmp->magic; |
1205 | wc += tmp->stats.wc + tmp->magic; |
1211 | } |
1206 | } |
1212 | if (tmp->stats.ac) |
1207 | if (tmp->stats.ac) |
1213 | { |
1208 | { |
1214 | if (best_ac < tmp->stats.ac + tmp->magic) |
1209 | if (best_ac < tmp->stats.ac + tmp->magic) |
1215 | { |
1210 | { |
1216 | ac += best_ac; /* Remove last bonus */ |
1211 | ac += best_ac; /* Remove last bonus */ |
1217 | best_ac = tmp->stats.ac + tmp->magic; |
1212 | best_ac = tmp->stats.ac + tmp->magic; |
1218 | } |
1213 | } |
1219 | else /* To nullify the below effect */ |
1214 | else /* To nullify the below effect */ |
1220 | ac += tmp->stats.ac + tmp->magic; |
1215 | ac += tmp->stats.ac + tmp->magic; |
1221 | } |
1216 | } |
1222 | if (tmp->stats.wc) |
1217 | if (tmp->stats.wc) |
1223 | wc -= (tmp->stats.wc + tmp->magic); |
1218 | wc -= (tmp->stats.wc + tmp->magic); |
1224 | if (tmp->stats.ac) |
1219 | if (tmp->stats.ac) |
1225 | ac -= (tmp->stats.ac + tmp->magic); |
1220 | ac -= (tmp->stats.ac + tmp->magic); |
1226 | if (ARMOUR_SPEED (tmp) && ARMOUR_SPEED (tmp) / 10.0 < max) |
1221 | if (ARMOUR_SPEED (tmp) && ARMOUR_SPEED (tmp) / 10.0 < max) |
1227 | max = ARMOUR_SPEED (tmp) / 10.0; |
1222 | max = ARMOUR_SPEED (tmp) / 10.0; |
1228 | break; |
1223 | break; |
1229 | } /* switch tmp->type */ |
1224 | } /* switch tmp->type */ |
1230 | } /* item is equipped */ |
1225 | } /* item is equipped */ |
1231 | } /* for loop of items */ |
1226 | } /* for loop of items */ |
1232 | |
1227 | |
1233 | /* We've gone through all the objects the player has equipped. For many things, we |
1228 | /* We've gone through all the objects the player has equipped. For many things, we |