Welcome, guest! Login / Register - Why register?
Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so dont bother with any of their useless mail servers here and just use oauth login instead. Thank the nice Russians for causing that. :)

Paste

Pasted as C++ by Crimm ( 15 years ago )
bool Monsters::loadMonster(const std::string& file, const std::string& monsterName, bool reloading/* = false*/)
{
 if(getIdByName(monsterName) && !reloading)
 {
  std::cout << "[Warning - Monsters::loadMonster] Duplicate registered monster with name: " << monsterName << std::endl;
  return true;
 }

 bool monsterLoad, new_mType = true;
 MonsterType* mType = NULL;
 if(reloading)
 {
  uint32_t id = getIdByName(monsterName);
  if(id != 0)
  {
   mType = getMonsterType(id);
   if(mType != NULL)
   {
    new_mType = false;
    mType->reset();
   }
  }
 }

 if(new_mType)
  mType = new MonsterType();

 xmlDocPtr doc = xmlParseFile&#40;file.c_str(&#41;);
 if(!doc)
 {
  std::cout << "[Warning - Monsters::loadMonster] Cannot load monster (" << monsterName << ") file &#40;" << file << "&#41;." << std::endl;
  std::cout << getLastXMLError() << std::endl;
  return false;
 }

 monsterLoad = true;
 xmlNodePtr p, root = xmlDocGetRootElement(doc);
 if(xmlStrcmp(root->name,(const xmlChar*)"monster"))
 {
  std::cout << "[Error - Monsters::loadMonster] Malformed monster (" << monsterName << ") file &#40;" << file << "&#41;." << std::endl;
  xmlFreeDoc(doc);
  return false;
 }
 




 int32_t intValue;
 std::string strValue;

 if(readXMLInteger(root, "minLevel", intValue))
 mType->minLevel = intValue;

 if(readXMLInteger(root, "maxLevel", intValue))
 mType->maxLevel = intValue;
    int32_t r = random_range(mType->minLevel,mType->maxLevel);
    std::stringstream Msg;
    Msg << r;
    std::string level = Msg.str().c_str();


 
 if(readXMLString(root, "name", strValue))
  mType->name = strValue + " [" + level + "]";
 else
  monsterLoad = false;

 if(readXMLString(root, "nameDescription", strValue))
  mType->nameDescription = strValue;
 else
 {
  mType->nameDescription = "a " + mType->name + " [" + level + "]";;
  toLowerCaseString(mType->nameDescription);
 }

 if(readXMLString(root, "race", strValue))
 {
  std::string tmpStrValue = asLowerCaseString(strValue);
  if(tmpStrValue == "venom" || atoi(strValue.c_str()) == 1)
   mType->race = RACE_VENOM;
  else if(tmpStrValue == "blood" || atoi(strValue.c_str()) == 2)
   mType->race = RACE_BLOOD;
  else if(tmpStrValue == "undead" || atoi(strValue.c_str()) == 3)
   mType->race = RACE_UNDEAD;
  else if(tmpStrValue == "fire" || atoi(strValue.c_str()) == 4)
   mType->race = RACE_FIRE;
  else if(tmpStrValue == "energy" || atoi(strValue.c_str()) == 5)
   mType->race = RACE_ENERGY;
  else
   SHOW_XML_WARNING("Unknown race type " << strValue);
 }

 if(readXMLInteger(root, "experience", intValue))
  mType->experience = intValue + (intValue/10 * r);

 if(readXMLInteger(root, "speed", intValue))
  mType->baseSpeed = intValue;

 if(readXMLInteger(root, "manacost", intValue))
  mType->manaCost = intValue;

 if(readXMLString(root, "skull", strValue))
  mType->skull = getSkull(strValue);

 if(readXMLString(root, "shield", strValue))
  mType->partyShield = getPartyShield(strValue);

 p = root->children;
 while(p && monsterLoad)
 {
  if(p->type != XML_ELEMENT_NODE)
  {
   p = p->next;
   continue;
  }

  if(!xmlStrcmp(p->name, (const xmlChar*)"health"))
  {
   if(readXMLInteger(p, "now", intValue))
    mType->health = intValue + (intValue/10 * r);
   else
   {
    SHOW_XML_ERROR("Missing health.now");
    monsterLoad = false;
   }

   if(readXMLInteger(p, "max", intValue))
    mType->healthMax = intValue + (intValue/10 * r);
   else
   {
    SHOW_XML_ERROR("Missing health.max");
    monsterLoad = false;
   }
  }
  else if(!xmlStrcmp(p->name, (const xmlChar*)"flags"))
  {
   xmlNodePtr tmpNode = p->children;
   while(tmpNode)
   {
    if(xmlStrcmp(tmpNode->name, (const xmlChar*)"flag") == 0)
    {
     if(readXMLString(tmpNode, "summonable", strValue))
      mType->isSummonable = booleanString(strValue);

     if(readXMLString(tmpNode, "attackable", strValue))
      mType->isAttackable = booleanString(strValue);

     if(readXMLString(tmpNode, "hostile", strValue))
      mType->isHostile = booleanString(strValue);

     if(readXMLString(tmpNode, "illusionable", strValue))
      mType->isIllusionable = booleanString(strValue);

     if(readXMLString(tmpNode, "convinceable", strValue))
      mType->isConvinceable = booleanString(strValue);

     if(readXMLString(tmpNode, "pushable", strValue))
      mType->pushable = booleanString(strValue);

     if(readXMLString(tmpNode, "canpushitems", strValue))
      mType->canPushItems = booleanString(strValue);

     if(readXMLString(tmpNode, "canpushcreatures", strValue))
      mType->canPushCreatures = booleanString(strValue);

     if(readXMLString(tmpNode, "hidename", strValue))
      mType->hideName = booleanString(strValue);

     if(readXMLString(tmpNode, "hidehealth", strValue))
      mType->hideHealth = booleanString(strValue);

     if(readXMLInteger(tmpNode, "lootmessage", intValue))
      mType->lootMessage = (LootMessage_t)intValue;

     if(readXMLInteger(tmpNode, "staticattack", intValue))
     {
      if(intValue < 0 || intValue > 100)
      {
       SHOW_XML_WARNING("staticattack lower than 0 or greater than 100");
       intValue = 0;
      }

      mType->staticAttackChance = intValue;
     }

     if(readXMLInteger(tmpNode, "lightlevel", intValue))
      mType->lightLevel = intValue;

     if(readXMLInteger(tmpNode, "lightcolor", intValue))
      mType->lightColor = intValue;

     if(readXMLInteger(tmpNode, "targetdistance", intValue))
     {
      if(intValue > Map::maxViewportX)
       SHOW_XML_WARNING("targetdistance greater than maxViewportX");

      mType->targetDistance = std::max(1, intValue);
     }

     if(readXMLInteger(tmpNode, "runonhealth", intValue))
      mType->runAwayHealth = intValue;

     if(readXMLString(tmpNode, "lureable", strValue))
      mType->isLureable = booleanString(strValue);

     if(readXMLString(tmpNode, "walkable", strValue))
      mType->isWalkable = booleanString(strValue);

     if(readXMLString(tmpNode, "skull", strValue))
      mType->skull = getSkull(strValue);

     if(readXMLString(tmpNode, "shield", strValue))
      mType->partyShield = getPartyShield(strValue);
    }

    tmpNode = tmpNode->next;
   }

   //if a monster can push creatures, it should not be pushable
   if(mType->canPushCreatures && mType->pushable)
    mType->pushable = false;
  }
  else if(!xmlStrcmp(p->name, (const xmlChar*)"targetchange"))
  {
   if(readXMLInteger(p, "speed", intValue) || readXMLInteger(p, "interval", intValue))
    mType->changeTargetSpeed = std::max(1, intValue);
   else
    SHOW_XML_WARNING("Missing targetchange.speed");

   if(readXMLInteger(p, "chance", intValue))
    mType->changeTargetChance = intValue;
   else
    SHOW_XML_WARNING("Missing targetchange.chance");
  }
  else if(!xmlStrcmp(p->name, (const xmlChar*)"strategy"))
  {
   if(readXMLInteger(p, "attack", intValue)) {}
    //mType->attackStrength = intValue;

   if(readXMLInteger(p, "defense", intValue)) {}
    //mType->defenseStrength = intValue;
  }
  else if(!xmlStrcmp(p->name, (const xmlChar*)"look"))
  {
   if(readXMLInteger(p, "type", intValue))
   {
    mType->outfit.lookType = intValue;
    if(readXMLInteger(p, "head", intValue))
     mType->outfit.lookHead = intValue;

    if(readXMLInteger(p, "body", intValue))
     mType->outfit.lookBody = intValue;

    if(readXMLInteger(p, "legs", intValue))
     mType->outfit.lookLegs = intValue;

    if(readXMLInteger(p, "feet", intValue))
     mType->outfit.lookFeet = intValue;

    if(readXMLInteger(p, "addons", intValue))
     mType->outfit.lookAddons = intValue;
   }
   else if(readXMLInteger(p, "typeex", intValue))
    mType->outfit.lookTypeEx = intValue;
   else
    SHOW_XML_WARNING("Missing look type/typeex");

   if(readXMLInteger(p, "corpse", intValue))
    mType->lookCorpse = intValue;

   if(readXMLInteger(p, "corpseUniqueId", intValue) || readXMLInteger(p, "corpseUid", intValue))
    mType->corpseUnique = intValue;

   if(readXMLInteger(p, "corpseActionId", intValue) || readXMLInteger(p, "corpseAid", intValue))
    mType->corpseAction = intValue;
  }
  else if(!xmlStrcmp(p->name, (const xmlChar*)"attacks"))
  {
   xmlNodePtr tmpNode = p->children;
   while(tmpNode)
   {
    if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"attack"))
    {
     spellBlock_t sb;
     if(deserializeSpell(tmpNode, sb, monsterName))
      mType->spellAttackList.push_back(sb);
     else
      SHOW_XML_WARNING("Cant load spell");
    }

    tmpNode = tmpNode->next;
   }
  }
  else if(!xmlStrcmp(p->name, (const xmlChar*)"defenses"))
  {
   if(readXMLInteger(p, "defense", intValue))
    mType->defense = intValue;

   if(readXMLInteger(p, "armor", intValue))
    mType->armor = intValue;

   xmlNodePtr tmpNode = p->children;
   while(tmpNode)
   {
    if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"defense"))
    {
     spellBlock_t sb;
     if(deserializeSpell(tmpNode, sb, monsterName))
      mType->spellDefenseList.push_back(sb);
     else
      SHOW_XML_WARNING("Cant load spell");
    }

    tmpNode = tmpNode->next;
   }
  }
  else if(!xmlStrcmp(p->name, (const xmlChar*)"immunities"))
  {
   xmlNodePtr tmpNode = p->children;
   while(tmpNode)
   {
    if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"immunity"))
    {
     if(readXMLString(tmpNode, "name", strValue))
     {
      std::string tmpStrValue = asLowerCaseString(strValue);
      if(tmpStrValue == "physical")
      {
       mType->damageImmunities |= COMBAT_PHYSICALDAMAGE;
       mType->conditionImmunities |= CONDITION_PHYSICAL;
      }
      else if(tmpStrValue == "energy")
      {
       mType->damageImmunities |= COMBAT_ENERGYDAMAGE;
       mType->conditionImmunities |= CONDITION_ENERGY;
      }
      else if(tmpStrValue == "fire")
      {
       mType->damageImmunities |= COMBAT_FIREDAMAGE;
       mType->conditionImmunities |= CONDITION_FIRE;
      }
      else if(tmpStrValue == "poison" || tmpStrValue == "earth")
      {
       mType->damageImmunities |= COMBAT_EARTHDAMAGE;
       mType->conditionImmunities |= CONDITION_POISON;
      }
      else if(tmpStrValue == "ice")
      {
       mType->damageImmunities |= COMBAT_ICEDAMAGE;
       mType->conditionImmunities |= CONDITION_FREEZING;
      }
      else if(tmpStrValue == "holy")
      {
       mType->damageImmunities |= COMBAT_HOLYDAMAGE;
       mType->conditionImmunities |= CONDITION_DAZZLED;
      }
      else if(tmpStrValue == "death")
      {
       mType->damageImmunities |= COMBAT_DEATHDAMAGE;
       mType->conditionImmunities |= CONDITION_CURSED;
      }
      else if(tmpStrValue == "drown")
      {
       mType->damageImmunities |= COMBAT_DROWNDAMAGE;
       mType->conditionImmunities |= CONDITION_DROWN;
      }
      else if(tmpStrValue == "lifedrain")
       mType->damageImmunities |= COMBAT_LIFEDRAIN;
      else if(tmpStrValue == "manadrain")
       mType->damageImmunities |= COMBAT_MANADRAIN;
      else if(tmpStrValue == "paralyze")
       mType->conditionImmunities |= CONDITION_PARALYZE;
      else if(tmpStrValue == "outfit")
       mType->conditionImmunities |= CONDITION_OUTFIT;
      else if(tmpStrValue == "drunk")
       mType->conditionImmunities |= CONDITION_DRUNK;
      else if(tmpStrValue == "invisible")
       mType->conditionImmunities |= CONDITION_INVISIBLE;
      else
       SHOW_XML_WARNING("Unknown immunity name " << strValue);
     }
     else if(readXMLString(tmpNode, "physical", strValue) && booleanString(strValue))
     {
      mType->damageImmunities |= COMBAT_PHYSICALDAMAGE;
      //mType->conditionImmunities |= CONDITION_PHYSICAL;
     }
     else if(readXMLString(tmpNode, "energy", strValue) && booleanString(strValue))
     {
      mType->damageImmunities |= COMBAT_ENERGYDAMAGE;
      mType->conditionImmunities |= CONDITION_ENERGY;
     }
     else if(readXMLString(tmpNode, "fire", strValue) && booleanString(strValue))
     {
      mType->damageImmunities |= COMBAT_FIREDAMAGE;
      mType->conditionImmunities |= CONDITION_FIRE;
     }
     else if((readXMLString(tmpNode, "poison", strValue) || readXMLString(tmpNode, "earth", strValue))
      && booleanString(strValue))
     {
      mType->damageImmunities |= COMBAT_EARTHDAMAGE;
      mType->conditionImmunities |= CONDITION_POISON;
     }
     else if(readXMLString(tmpNode, "drown", strValue) && booleanString(strValue))
     {
      mType->damageImmunities |= COMBAT_DROWNDAMAGE;
      mType->conditionImmunities |= CONDITION_DROWN;
     }
     else if(readXMLString(tmpNode, "ice", strValue) && booleanString(strValue))
     {
      mType->damageImmunities |= COMBAT_ICEDAMAGE;
      mType->conditionImmunities |= CONDITION_FREEZING;
     }
     else if(readXMLString(tmpNode, "holy", strValue) && booleanString(strValue))
     {
      mType->damageImmunities |= COMBAT_HOLYDAMAGE;
      mType->conditionImmunities |= CONDITION_DAZZLED;
     }
     else if(readXMLString(tmpNode, "death", strValue) && booleanString(strValue))
     {
      mType->damageImmunities |= COMBAT_DEATHDAMAGE;
      mType->conditionImmunities |= CONDITION_CURSED;
     }
     else if(readXMLString(tmpNode, "lifedrain", strValue) && booleanString(strValue))
      mType->damageImmunities |= COMBAT_LIFEDRAIN;
     else if(readXMLString(tmpNode, "manadrain", strValue) && booleanString(strValue))
      mType->damageImmunities |= COMBAT_LIFEDRAIN;
     else if(readXMLString(tmpNode, "paralyze", strValue) && booleanString(strValue))
      mType->conditionImmunities |= CONDITION_PARALYZE;
     else if(readXMLString(tmpNode, "outfit", strValue) && booleanString(strValue))
      mType->conditionImmunities |= CONDITION_OUTFIT;
     else if(readXMLString(tmpNode, "drunk", strValue) && booleanString(strValue))
      mType->conditionImmunities |= CONDITION_DRUNK;
     else if(readXMLString(tmpNode, "invisible", strValue) && booleanString(strValue))
      mType->conditionImmunities |= CONDITION_INVISIBLE;
    }

    tmpNode = tmpNode->next;
   }
  }
  else if(!xmlStrcmp(p->name, (const xmlChar*)"voices"))
  {
   if(readXMLInteger(p, "speed", intValue) || readXMLInteger(p, "interval", intValue))
    mType->yellSpeedTicks = intValue;
   else
    SHOW_XML_WARNING("Missing voices.speed");

   if(readXMLInteger(p, "chance", intValue))
    mType->yellChance = intValue;
   else
    SHOW_XML_WARNING("Missing voices.chance");

   xmlNodePtr tmpNode = p->children;
   while(tmpNode)
   {
    if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"voice"))
    {
     voiceBlock_t vb;
     vb.text = "";
     vb.yellText = false;

     if(readXMLString(tmpNode, "sentence", strValue))
      vb.text = strValue;
     else
      SHOW_XML_WARNING("Missing voice.sentence");

     if(readXMLString(tmpNode, "yell", strValue))
      vb.yellText = booleanString(strValue);

     mType->voiceVector.push_back(vb);
    }

    tmpNode = tmpNode->next;
   }
  }
  else if(!xmlStrcmp(p->name, (const xmlChar*)"loot"))
  {
   xmlNodePtr tmpNode = p->children;
   while(tmpNode)
   {
    if(tmpNode->type != XML_ELEMENT_NODE)
    {
     tmpNode = tmpNode->next;
     continue;
    }

    LootBlock rootBlock;
    if(loadLoot(tmpNode, rootBlock))
     mType->lootItems.push_back(rootBlock);
    else
     SHOW_XML_WARNING("Cant load loot");

    tmpNode = tmpNode->next;
   }
  }
  else if(!xmlStrcmp(p->name, (const xmlChar*)"elements"))
  {
   xmlNodePtr tmpNode = p->children;
   while(tmpNode)
   {
    if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"element"))
    {
     if(readXMLInteger(tmpNode, "firePercent", intValue))
      mType->elementMap[COMBAT_FIREDAMAGE] = intValue;
     else if(readXMLInteger(tmpNode, "energyPercent", intValue))
      mType->elementMap[COMBAT_ENERGYDAMAGE] = intValue;
     else if(readXMLInteger(tmpNode, "icePercent", intValue))
      mType->elementMap[COMBAT_ICEDAMAGE] = intValue;
     else if(readXMLInteger(tmpNode, "poisonPercent", intValue) || readXMLInteger(tmpNode, "earthPercent", intValue))
      mType->elementMap[COMBAT_EARTHDAMAGE] = intValue;
     else if(readXMLInteger(tmpNode, "holyPercent", intValue))
      mType->elementMap[COMBAT_HOLYDAMAGE] = intValue;
     else if(readXMLInteger(tmpNode, "deathPercent", intValue))
      mType->elementMap[COMBAT_DEATHDAMAGE] = intValue;
     else if(readXMLInteger(tmpNode, "drownPercent", intValue))
      mType->elementMap[COMBAT_DROWNDAMAGE] = intValue;
     else if(readXMLInteger(tmpNode, "physicalPercent", intValue))
      mType->elementMap[COMBAT_PHYSICALDAMAGE] = intValue;
     else if(readXMLInteger(tmpNode, "lifeDrainPercent", intValue))
      mType->elementMap[COMBAT_LIFEDRAIN] = intValue;
     else if(readXMLInteger(tmpNode, "manaDrainPercent", intValue))
      mType->elementMap[COMBAT_MANADRAIN] = intValue;
     else if(readXMLInteger(tmpNode, "healingPercent", intValue))
      mType->elementMap[COMBAT_HEALING] = intValue;
     else if(readXMLInteger(tmpNode, "undefinedPercent", intValue))
      mType->elementMap[COMBAT_UNDEFINEDDAMAGE] = intValue;
    }

    tmpNode = tmpNode->next;
   }
  }
  else if(!xmlStrcmp(p->name, (const xmlChar*)"summons"))
  {
   if(readXMLInteger(p, "maxSummons", intValue) || readXMLInteger(p, "max", intValue))
    mType->maxSummons = intValue;

   xmlNodePtr tmpNode = p->children;
   while(tmpNode)
   {
    if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"summon"))
    {
     uint32_t chance = 100, interval = 1000, amount = 1;
     if(readXMLInteger(tmpNode, "speed", intValue) || readXMLInteger(tmpNode, "interval", intValue))
      interval = intValue;

     if(readXMLInteger(tmpNode, "chance", intValue))
      chance = intValue;

     if(readXMLInteger(tmpNode, "amount", intValue) || readXMLInteger(tmpNode, "max", intValue))
      amount = intValue;

     if(readXMLString(tmpNode, "name", strValue))
     {
      summonBlock_t sb;
      sb.name = strValue;
      sb.interval = interval;
      sb.chance = chance;
      sb.amount = amount;

      mType->summonList.push_back(sb);
     }
     else
      SHOW_XML_WARNING("Missing summon.name");
    }

    tmpNode = tmpNode->next;
   }
  }
  else if(!xmlStrcmp(p->name, (const xmlChar*)"script"))
  {
   xmlNodePtr tmpNode = p->children;
   while(tmpNode)
   {
    if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"event"))
    {
     if(readXMLString(tmpNode, "name", strValue))
      mType->scriptList.push_back(strValue);
     else
      SHOW_XML_WARNING("Missing name for script event");
    }

    tmpNode = tmpNode->next;
   }
  }
  else
   SHOW_XML_WARNING("Unknown attribute type - " << p->name);

  p = p->next;
 }

 xmlFreeDoc(doc);
 if(monsterLoad)
 {
  static uint32_t id = 0;
  if(new_mType)
  {
   id++;
   monsterNames[asLowerCaseString(monsterName)] = id;
   monsters[id] = mType;
  }

  return true;
 }

 if(new_mType)
  delete mType;

 return false;
}

 

Revise this Paste

Children: 36812 36813
Your Name: Code Language: