--- deliantra/server/common/loader.C 2007/01/19 18:06:51 1.50 +++ deliantra/server/common/loader.C 2007/02/10 01:52:25 1.57 @@ -26,65 +26,22 @@ sub/add_weight will transcend the environment updating the carrying variable. */ - #include #include #include -// future resource loader base class -struct loader_base -{ - const char *filename; - virtual const char *type () const = 0; - - virtual archetype *get_arch (const char *name); - virtual void put_arch (archetype *arch); - - virtual object *get_object (const char *name); - virtual void put_object (object *op); - - virtual player *get_player (); - virtual void put_player (player *pl); - - virtual region *get_region (const char *name); - virtual void put_region (region *region); - - virtual facetile *get_face (const char *name); - virtual void put_face (facetile *face); - - virtual treasurelist *get_treasure (const char *name, bool one = false); - virtual void put_treasure (treasurelist *treasure); - - virtual animation *get_animation (const char *name); - virtual void put_animation (animation *anim); -}; +///////////////////////////////////////////////////////////////////////////// -// future generic resource loader -// handles generic stuff valid in most files, such as -// animations, treasures, faces and so on -struct loader_generic : loader_base +loader_base::~loader_base () { - const char *type () const = 0; - - region *get_region (); - void put_region (region *region); - - facetile *get_face (const char *name); - void put_face (facetile *face); - - treasurelist *get_treasure (const char *name, bool one = false); - void put_treasure (treasurelist *treasure); - - animation *get_animation (const char *name); - void put_animation (animation *anim); -}; +} // the base class warns about and skips everything archetype * loader_base::get_arch (const char *name) { - LOG (llevError, "%s: found archetype definition '%s', which is not allowed in files of type %s.\n", - filename, name, type ()); + LOG (llevError, "%s: found archetype definition '%s', which is not allowed in files of this type.\n", + filename, name); return new archetype; } @@ -92,8 +49,8 @@ object * loader_base::get_object (const char *name) { - LOG (llevError, "%s: found object definition '%s', which is not allowed in files of type %s.\n", - filename, name, type ()); + LOG (llevError, "%s: found object definition '%s', which is not allowed in files of this type.\n", + filename, name); return object::create (); } @@ -101,8 +58,8 @@ player * loader_base::get_player () { - LOG (llevError, "%s: found player definition, which is not allowed in files of type %s.\n", - filename, type ()); + LOG (llevError, "%s: found player definition, which is not allowed in files of this type.\n", + filename); return player::create (); } @@ -110,8 +67,8 @@ region * loader_base::get_region (const char *name) { - LOG (llevError, "%s: found region definition '%s', which is not allowed in files of type %s.\n", - filename, name, type ()); + LOG (llevError, "%s: found region definition '%s', which is not allowed in files of this type.\n", + filename, name); return new region; } @@ -119,8 +76,8 @@ facetile * loader_base::get_face (const char *name) { - LOG (llevError, "%s: found face definition '%s', which is not allowed in files of type %s.\n", - filename, name, type ()); + LOG (llevError, "%s: found face definition '%s', which is not allowed in files of this type.\n", + filename, name); return new facetile; } @@ -128,8 +85,8 @@ treasurelist * loader_base::get_treasure (const char *name, bool one) { - LOG (llevError, "%s: found treasure definition '%s', which is not allowed in files of type %s.\n", - filename, name, type ()); + LOG (llevError, "%s: found treasure definition '%s', which is not allowed in files of this type.\n", + filename, name); return new treasurelist;//D } @@ -137,8 +94,8 @@ animation * loader_base::get_animation (const char *name) { - LOG (llevError, "%s: found animation definition '%s', which is not allowed in files of type %s.\n", - filename, name, type ()); + LOG (llevError, "%s: found animation definition '%s', which is not allowed in files of this type.\n", + filename, name); return new animation; } @@ -185,6 +142,54 @@ delete anim; } +///////////////////////////////////////////////////////////////////////////// + +bool loader_base::parse (object_thawer &thawer) +{ + for (;;) + { + keyword kw = thawer.get_kv (); + + switch (kw) + { + case KW_region: + { + region *rgn = get_region (thawer.get_str ()); + + if (!parse_region (thawer, rgn)) + { + delete rgn; + return false; + } + + put_region (rgn); + } + break; + + case KW_EOF: + return true; + + default: + if (!thawer.parse_error (kw, "resource file")) + return false; + } + } +} + +bool loader_base::load (const char *filename) +{ + this->filename = filename; + + object_thawer fp (filename); + + if (!fp) + return false; + + return parse (fp); +} + +///////////////////////////////////////////////////////////////////////////// + /* Maps the MOVE_* values to names */ static const char *const move_name[] = { "walk", "fly_low", "fly_high", "swim", "boat", NULL }; @@ -418,8 +423,6 @@ static void check_loaded_object (object *op) { - int ip; - /* We do some specialised handling to handle legacy cases of name_pl. * If the object doesn't have a name_pl, we just use the object name - * this isn't perfect (things won't be properly pluralised), but works to @@ -430,7 +433,7 @@ * information (appear as just 'hearts' and not 'goblins heart') */ if (op->arch && op->name != op->arch->clone.name && op->name_pl == op->arch->clone.name_pl) - op->name_pl = NULL; + op->name_pl = 0; if (!op->name_pl) op->name_pl = op->name; @@ -443,6 +446,7 @@ else set_materialname (op, 5, NULL); } + /* only do these when program is first run - a bit * excessive to do this at every run - most of this is * really just to catch any errors - program will still run, but @@ -451,25 +455,22 @@ if ((op->type == WEAPON || op->type == BOW) && arch_init) { if (!op->skill) - { - LOG (llevError, "Weapon %s lacks a skill.\n", op->debug_desc ()); - } + LOG (llevError, "Weapon %s lacks a skill.\n", op->debug_desc ()); else if ((!strcmp (op->skill, "one handed weapons") && op->body_info[1] != -1) || (!strcmp (op->skill, "two handed weapons") && op->body_info[1] != -2)) - { - LOG (llevError, "weapon %s arm usage does not match skill: %d, %s\n", op->debug_desc (), op->body_info[1], &op->skill); - } + LOG (llevError, "weapon %s arm usage does not match skill: %d, %s\n", op->debug_desc (), op->body_info[1], &op->skill); } /* We changed last_heal to gen_sp_armour, which is what it * really does for many objects. Need to catch any in maps * that may have an old value. */ - if ((op->type == WEAPON) || - (op->type == ARMOUR) || (op->type == HELMET) || - (op->type == SHIELD) || (op->type == RING) || - (op->type == BOOTS) || (op->type == GLOVES) || - (op->type == AMULET) || (op->type == GIRDLE) || (op->type == BRACERS) || (op->type == CLOAK)) + if (op->type == WEAPON + || op->type == ARMOUR || op->type == HELMET + || op->type == SHIELD || op->type == RING + || op->type == BOOTS || op->type == GLOVES + || op->type == AMULET || op->type == GIRDLE + || op->type == BRACERS || op->type == CLOAK) { if (op->last_heal) { @@ -478,16 +479,17 @@ op->last_heal = 0; } - ip = calc_item_power (op, 0); + int ip = calc_item_power (op, 0); + /* Legacy objects from before item power was in the game */ if (!op->item_power && ip) { if (ip > 3) - { - LOG (llevDebug, "Object %s had no item power, using %d\n", op->debug_desc (), ip); - } + LOG (llevDebug, "Object %s had no item power, using %d\n", op->debug_desc (), ip); + op->item_power = ip; } + /* Check for possibly bogus values. Has to meet both these criteria - * something that has item_power 1 is probably just fine if our calculated * value is 1 or 2 - these values are small enough that hard to be precise. @@ -495,32 +497,26 @@ * but not the second one. */ if (ip > 2 * op->item_power && ip > (op->item_power + 3)) - { - LOG (llevDebug, "Object %s seems to have too low item power? %d > %d\n", op->debug_desc (), ip, op->item_power); - } - + LOG (llevDebug, "Object %s seems to have too low item power? %d > %d\n", op->debug_desc (), ip, op->item_power); } + /* Old spellcasting object - need to load in the appropiate object */ if ((op->type == ROD || op->type == WAND || op->type == SCROLL || op->type == HORN || op->type == FIREWALL || /* POTIONS and ALTARS don't always cast spells, but if they do, update them */ ((op->type == POTION || op->type == ALTAR) && op->stats.sp)) && !op->inv && !arch_init) { - object *tmp; - /* Fireall is bizarre in that spell type was stored in dam. Rest are 'normal' * in that spell was stored in sp. */ - tmp = get_archetype (spell_mapping[op->type == FIREWALL ? op->stats.dam : op->stats.sp]); + object *tmp = get_archetype (spell_mapping[op->type == FIREWALL ? op->stats.dam : op->stats.sp]); insert_ob_in_ob (tmp, op); op->randomitems = NULL; /* So another spell isn't created for this object */ } - /* spellbooks & runes use slaying. But not to arch name, but to spell name */ + /* spellbooks & runes use slaying. But not to arch name, but to spell name */ if ((op->type == SPELLBOOK || op->type == RUNE) && op->slaying && !op->inv && !arch_init) { - object *tmp; - - tmp = get_archetype_by_object_name (op->slaying); + object *tmp = get_archetype_by_object_name (op->slaying); insert_ob_in_ob (tmp, op); op->randomitems = NULL; /* So another spell isn't created for this object */ /* without this, value is all screwed up */ @@ -566,9 +562,7 @@ op->stats.maxhp = 0; } else - { - op->move_type = MOVE_WALK; - } + op->move_type = MOVE_WALK; } } @@ -715,6 +709,7 @@ { tmp = object::create (); /* record the name of the broken object */ + //TODO: but do not log??? tmp->name = str; } @@ -782,17 +777,13 @@ case KW_animation: { - const char *str = thawer.get_str (); + CLEAR_FLAG (op, FLAG_ANIMATE); + op->animation_id = 0; - if (!str) - { - op->animation_id = 0; - CLEAR_FLAG (op, FLAG_ANIMATE); - } - else if ((op->animation_id = find_animation (str))) + const char *str = thawer.get_str (); + if (str && (op->animation_id = find_animation (str))) SET_FLAG (op, FLAG_ANIMATE); } - break; case KW_last_heal: thawer.get (op->last_heal); break; @@ -867,7 +858,7 @@ case KW_magic: thawer.get (op->magic); break; case KW_state: thawer.get (op->state); break; case KW_move_slow_penalty: thawer.get (op->move_slow_penalty); break; - case KW_material: thawer.get (op->material); break; + case KW_material: thawer.get (op->materials); break; //TODO: nuke case KW_materialname: thawer.get (op->materialname); break; /* These are the new values */ @@ -1139,6 +1130,8 @@ case KW_randomitems: op->randomitems = find_treasurelist (thawer.get_str ()); + //if (!op->randomitems) + // LOG (llevError, "%s uses unknown randomitems '%s'.\n", op->debug_desc (), thawer.get_str ()); break; case KW_msg: @@ -1191,7 +1184,8 @@ break; default: - LOG (llevError, "UNSUPPORTED KEYWORD IN MAP: \"%s\", bug in normaliser. skipping.\n", keyword_str[kw]); + if (!thawer.parse_error (kw, "object", op->name)) + return false; break; } } @@ -1535,7 +1529,7 @@ CMP_OUT (path_attuned); CMP_OUT (path_repelled); CMP_OUT (path_denied); - CMP_OUT (material); + CMP_OUT2 (material, materials);//TODO: nuke CMP_OUT (materialname); CMP_OUT (value); CMP_OUT (carrying);