1 | /* |
1 | /* |
2 | * CrossFire, A Multiplayer game for X-windows |
2 | * CrossFire, A Multiplayer game |
3 | * |
3 | * |
4 | * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team |
4 | * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team |
5 | * Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
5 | * Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
6 | * Copyright (C) 1992 Frank Tore Johansen |
6 | * Copyright (C) 1992 Frank Tore Johansen |
7 | * |
7 | * |
… | |
… | |
293 | */ |
293 | */ |
294 | if ((op->type == WEAPON || op->type == BOW) && loading_arch) |
294 | if ((op->type == WEAPON || op->type == BOW) && loading_arch) |
295 | { |
295 | { |
296 | if (!op->skill) |
296 | if (!op->skill) |
297 | LOG (llevError, "Weapon %s lacks a skill.\n", op->debug_desc ()); |
297 | LOG (llevError, "Weapon %s lacks a skill.\n", op->debug_desc ()); |
298 | else if ((!strcmp (op->skill, "one handed weapons") && op->body_info[1] != -1) || |
298 | else if ((!strcmp (op->skill, "one handed weapons") && op->slot[1].info != -1) || |
299 | (!strcmp (op->skill, "two handed weapons") && op->body_info[1] != -2)) |
299 | (!strcmp (op->skill, "two handed weapons") && op->slot[1].info != -2)) |
300 | LOG (llevError, "weapon %s arm usage does not match skill: %d, %s\n", op->debug_desc (), op->body_info[1], &op->skill); |
300 | LOG (llevError, "weapon %s arm usage does not match skill: %d, %s\n", op->debug_desc (), op->slot[1].info, &op->skill); |
301 | } |
301 | } |
302 | |
302 | |
303 | /* We changed last_heal to gen_sp_armour, which is what it |
303 | /* We changed last_heal to gen_sp_armour, which is what it |
304 | * really does for many objects. Need to catch any in maps |
304 | * really does for many objects. Need to catch any in maps |
305 | * that may have an old value. |
305 | * that may have an old value. |
… | |
… | |
418 | { "flying" , MOVE_FLY_LOW | MOVE_FLY_HIGH }, |
418 | { "flying" , MOVE_FLY_LOW | MOVE_FLY_HIGH }, |
419 | { "fly_low" , MOVE_FLY_LOW }, |
419 | { "fly_low" , MOVE_FLY_LOW }, |
420 | { "fly_high", MOVE_FLY_HIGH }, |
420 | { "fly_high", MOVE_FLY_HIGH }, |
421 | { "swim" , MOVE_SWIM }, |
421 | { "swim" , MOVE_SWIM }, |
422 | { "boat" , MOVE_BOAT }, |
422 | { "boat" , MOVE_BOAT }, |
|
|
423 | { "ship" , MOVE_SHIP }, |
423 | { "all" , MOVE_ALL }, |
424 | { "all" , MOVE_ALL }, |
424 | }; |
425 | }; |
425 | |
426 | |
426 | if (!str) |
427 | if (!str) |
427 | { |
428 | { |
… | |
… | |
473 | CLEAR_FLAG (op, flag) \ |
474 | CLEAR_FLAG (op, flag) \ |
474 | |
475 | |
475 | bool |
476 | bool |
476 | object::parse_kv (object_thawer &f) |
477 | object::parse_kv (object_thawer &f) |
477 | { |
478 | { |
478 | assert (f.kw == KW_object || f.kw == KW_arch); |
|
|
479 | |
|
|
480 | if (f.kw == KW_object) |
|
|
481 | f.get (name); // preset name from object name |
|
|
482 | |
|
|
483 | f.next (); |
|
|
484 | |
|
|
485 | object *op_inv = inv; |
479 | object *op_inv = inv; |
486 | |
480 | |
487 | for (;;) |
481 | for (;;) |
488 | { |
482 | { |
489 | switch (f.kw) |
483 | switch (f.kw) |
… | |
… | |
839 | case KW_no_steal: GET_FLAG (this, FLAG_NO_STEAL); break; |
833 | case KW_no_steal: GET_FLAG (this, FLAG_NO_STEAL); break; |
840 | case KW_one_hit: GET_FLAG (this, FLAG_ONE_HIT); break; |
834 | case KW_one_hit: GET_FLAG (this, FLAG_ONE_HIT); break; |
841 | case KW_berserk: GET_FLAG (this, FLAG_BERSERK); break; |
835 | case KW_berserk: GET_FLAG (this, FLAG_BERSERK); break; |
842 | case KW_is_buildable: GET_FLAG (this, FLAG_IS_BUILDABLE); break; |
836 | case KW_is_buildable: GET_FLAG (this, FLAG_IS_BUILDABLE); break; |
843 | case KW_destroy_on_death: GET_FLAG (this, FLAG_DESTROY_ON_DEATH); break; |
837 | case KW_destroy_on_death: GET_FLAG (this, FLAG_DESTROY_ON_DEATH); break; |
|
|
838 | case KW_treasure_env: GET_FLAG (this, FLAG_TREASURE_ENV); break; |
|
|
839 | case KW_precious: GET_FLAG (this, FLAG_PRECIOUS); break; |
844 | |
840 | |
845 | case KW_armour: f.get (resist[ATNR_PHYSICAL]); break; |
841 | case KW_armour: f.get (resist[ATNR_PHYSICAL]); break; |
846 | case KW_resist_physical: f.get (resist[ATNR_PHYSICAL]); break; |
842 | case KW_resist_physical: f.get (resist[ATNR_PHYSICAL]); break; |
847 | case KW_resist_magic: f.get (resist[ATNR_MAGIC]); break; |
843 | case KW_resist_magic: f.get (resist[ATNR_MAGIC]); break; |
848 | case KW_resist_fire: f.get (resist[ATNR_FIRE]); break; |
844 | case KW_resist_fire: f.get (resist[ATNR_FIRE]); break; |
… | |
… | |
894 | case KW_dam_modifier: f.get (dam_modifier); break; |
890 | case KW_dam_modifier: f.get (dam_modifier); break; |
895 | case KW_duration_modifier: f.get (duration_modifier); break; |
891 | case KW_duration_modifier: f.get (duration_modifier); break; |
896 | |
892 | |
897 | //TODO: mechanism to ensure that KW_xxx is consecutive needed from include/preprocess |
893 | //TODO: mechanism to ensure that KW_xxx is consecutive needed from include/preprocess |
898 | //TODO: parse from other include files |
894 | //TODO: parse from other include files |
899 | case KW_body_range: f.get (body_info[0]); break; |
895 | case KW_body_range: slot[ 0].info = f.get_sint32 (); break; |
900 | case KW_body_arm: f.get (body_info[1]); break; |
896 | case KW_body_arm: slot[ 1].info = f.get_sint32 (); break; |
901 | case KW_body_torso: f.get (body_info[2]); break; |
897 | case KW_body_torso: slot[ 2].info = f.get_sint32 (); break; |
902 | case KW_body_head: f.get (body_info[3]); break; |
898 | case KW_body_head: slot[ 3].info = f.get_sint32 (); break; |
903 | case KW_body_neck: f.get (body_info[4]); break; |
899 | case KW_body_neck: slot[ 4].info = f.get_sint32 (); break; |
904 | case KW_body_skill: f.get (body_info[5]); break; |
900 | case KW_body_skill: slot[ 5].info = f.get_sint32 (); break; |
905 | case KW_body_finger: f.get (body_info[6]); break; |
901 | case KW_body_finger: slot[ 6].info = f.get_sint32 (); break; |
906 | case KW_body_shoulder: f.get (body_info[7]); break; |
902 | case KW_body_shoulder: slot[ 7].info = f.get_sint32 (); break; |
907 | case KW_body_foot: f.get (body_info[8]); break; |
903 | case KW_body_foot: slot[ 8].info = f.get_sint32 (); break; |
908 | case KW_body_hand: f.get (body_info[9]); break; |
904 | case KW_body_hand: slot[ 9].info = f.get_sint32 (); break; |
909 | case KW_body_wrist: f.get (body_info[10]); break; |
905 | case KW_body_wrist: slot[10].info = f.get_sint32 (); break; |
910 | case KW_body_waist: f.get (body_info[11]); break; |
906 | case KW_body_waist: slot[11].info = f.get_sint32 (); break; |
911 | case KW_can_apply: |
907 | case KW_can_apply: |
912 | break; |
908 | break; |
913 | |
909 | |
914 | case KW_connected: |
910 | case KW_connected: |
915 | add_button_link (this, map, f.get_sint32 ()); |
911 | add_button_link (this, map, f.get_sint32 ()); |
… | |
… | |
924 | : treasurelist::find (f.get_str ()); |
920 | : treasurelist::find (f.get_str ()); |
925 | |
921 | |
926 | if (!randomitems) |
922 | if (!randomitems) |
927 | LOG (llevError, "%s uses unknown randomitems '%s'.\n", debug_desc (), f.get_str ()); |
923 | LOG (llevError, "%s uses unknown randomitems '%s'.\n", debug_desc (), f.get_str ()); |
928 | } |
924 | } |
|
|
925 | else |
|
|
926 | randomitems = 0; |
929 | break; |
927 | break; |
930 | |
928 | |
931 | case KW_msg: |
929 | case KW_msg: |
932 | f.get_ml (KW_endmsg, msg); |
930 | f.get_ml (KW_endmsg, msg); |
933 | //TODO: allow longer messages |
931 | //TODO: allow longer messages |
… | |
… | |
989 | LOG (llevError, "object refering to nonexistant archetype '%s'.\n", f.get_str ()); |
987 | LOG (llevError, "object refering to nonexistant archetype '%s'.\n", f.get_str ()); |
990 | arch = archetype::find ("earthwall"); |
988 | arch = archetype::find ("earthwall"); |
991 | } |
989 | } |
992 | |
990 | |
993 | assert (arch); //D maybe use exception handling of sorts? |
991 | assert (arch); //D maybe use exception handling of sorts? |
|
|
992 | |
|
|
993 | f.next (); |
994 | |
994 | |
995 | object *op = object::create (); |
995 | object *op = object::create (); |
996 | |
996 | |
997 | op->map = map; |
997 | op->map = map; |
998 | arch->clone.copy_to (op); |
998 | arch->clone.copy_to (op); |
… | |
… | |
1017 | int |
1017 | int |
1018 | set_variable (object *op, char *buf) |
1018 | set_variable (object *op, char *buf) |
1019 | { |
1019 | { |
1020 | object_thawer f (buf, (AV *)0); |
1020 | object_thawer f (buf, (AV *)0); |
1021 | |
1021 | |
1022 | f.kw = KW_arch; // special hack so that parse_kv skips |
1022 | f.next (); |
1023 | return op->parse_kv (f); |
1023 | return op->parse_kv (f); |
1024 | } |
1024 | } |
1025 | |
1025 | |
1026 | /* This returns a string of the integer movement type */ |
1026 | /* This returns a string of the integer movement type */ |
1027 | #if 0 |
1027 | #if 0 |
… | |
… | |
1108 | KW_monster, |
1108 | KW_monster, |
1109 | KW_friendly, |
1109 | KW_friendly, |
1110 | KW_generator, |
1110 | KW_generator, |
1111 | KW_is_thrown, |
1111 | KW_is_thrown, |
1112 | KW_auto_apply, |
1112 | KW_auto_apply, |
1113 | KW_NULL, // was KW_treasure |
1113 | KW_treasure_env, |
1114 | KW_player_sold, |
1114 | KW_player_sold, |
1115 | /* 20 */ |
1115 | /* 20 */ |
1116 | KW_see_invisible, |
1116 | KW_see_invisible, |
1117 | KW_can_roll, |
1117 | KW_can_roll, |
1118 | KW_overlay_floor, |
1118 | KW_overlay_floor, |
… | |
… | |
1179 | KW_can_use_skill, |
1179 | KW_can_use_skill, |
1180 | KW_been_applied, |
1180 | KW_been_applied, |
1181 | /* 80 */ |
1181 | /* 80 */ |
1182 | KW_has_ready_scroll, |
1182 | KW_has_ready_scroll, |
1183 | KW_can_use_rod, |
1183 | KW_can_use_rod, |
1184 | KW_NULL, |
1184 | KW_precious, |
1185 | KW_can_use_horn, |
1185 | KW_can_use_horn, |
1186 | KW_make_invisible, |
1186 | KW_make_invisible, |
1187 | KW_inv_locked, |
1187 | KW_inv_locked, |
1188 | KW_is_wooded, |
1188 | KW_is_wooded, |
1189 | KW_is_hilly, |
1189 | KW_is_hilly, |
… | |
… | |
1365 | if (flag_names [i] && op->flag [i] != tmp->flag [i]) |
1365 | if (flag_names [i] && op->flag [i] != tmp->flag [i]) |
1366 | f.put (flag_names [i], op->flag [i] ? "1" : "0"); |
1366 | f.put (flag_names [i], op->flag [i] ? "1" : "0"); |
1367 | |
1367 | |
1368 | /* Save body locations */ |
1368 | /* Save body locations */ |
1369 | for (i = 0; i < NUM_BODY_LOCATIONS; i++) |
1369 | for (i = 0; i < NUM_BODY_LOCATIONS; i++) |
1370 | if (op->body_info[i] != tmp->body_info[i]) |
1370 | if (op->slot[i].info != tmp->slot[i].info) |
1371 | f.put (body_locations[i].save_name, op->body_info[i]); |
1371 | f.put (body_locations[i].save_name, op->slot[i].info); |
1372 | } |
1372 | } |
1373 | |
1373 | |
1374 | /* |
1374 | /* |
1375 | * Dumps all variables in an object to a file. |
1375 | * Dumps all variables in an object to a file. |
1376 | * If bit 0 of flag is set, unpaid objects will be saved. As of now, |
1376 | * If bit 0 of flag is set, unpaid objects will be saved. As of now, |
… | |
… | |
1399 | return true; |
1399 | return true; |
1400 | } |
1400 | } |
1401 | |
1401 | |
1402 | ///////////////////////////////////////////////////////////////////////////// |
1402 | ///////////////////////////////////////////////////////////////////////////// |
1403 | |
1403 | |
|
|
1404 | // generic resource file load, |
|
|
1405 | // currently supports: region, treasures, archetypes |
1404 | bool load_resource_file (const char *filename) |
1406 | bool load_resource_file (const char *filename) |
1405 | { |
1407 | { |
1406 | object_thawer f (filename); |
1408 | object_thawer f (filename); |
|
|
1409 | |
|
|
1410 | bool success = false; |
|
|
1411 | bool seen_arch = false; |
1407 | |
1412 | |
1408 | f.next (); |
1413 | f.next (); |
1409 | |
1414 | |
1410 | for (;;) |
1415 | for (;;) |
1411 | { |
1416 | { |
1412 | switch (f.kw) |
1417 | switch (f.kw) |
1413 | { |
1418 | { |
1414 | case KW_region: |
1419 | case KW_region: |
1415 | if (!region::read (f)) |
1420 | if (!region::read (f)) |
1416 | return false; |
1421 | goto finish; |
|
|
1422 | break; |
|
|
1423 | |
|
|
1424 | case KW_treasure: |
|
|
1425 | case KW_treasureone: |
|
|
1426 | if (!treasurelist::read (f)) |
|
|
1427 | goto finish; |
|
|
1428 | break; |
|
|
1429 | |
|
|
1430 | case KW_object: |
|
|
1431 | seen_arch = true; |
|
|
1432 | if (!archetype::read (f)) |
|
|
1433 | goto finish; |
1417 | break; |
1434 | break; |
1418 | |
1435 | |
1419 | case KW_EOF: |
1436 | case KW_EOF: |
1420 | return true; |
1437 | success = true; |
|
|
1438 | goto finish; |
1421 | |
1439 | |
1422 | default: |
1440 | default: |
1423 | if (!f.parse_error ("resource file")) |
1441 | if (!f.parse_error ("resource file")) |
1424 | return false; |
1442 | goto finish; |
|
|
1443 | |
|
|
1444 | f.next (); |
|
|
1445 | break; |
1425 | } |
1446 | } |
1426 | |
|
|
1427 | f.next (); |
|
|
1428 | } |
1447 | } |
|
|
1448 | |
|
|
1449 | finish: |
|
|
1450 | if (seen_arch) |
|
|
1451 | init_archetype_pointers (); |
|
|
1452 | |
|
|
1453 | return success; |
1429 | } |
1454 | } |
1430 | |
1455 | |