bool TalkAction::configureEvent(xmlNodePtr p) { std::string str; int intValue; if(readXMLString(p, "words", str)){ commandString = str; } else{ std::cout << "Error: [TalkAction::configureEvent] No words for TalkAction or Spell." << std::endl; return false; } if(readXMLString(p, "filter", str)){ if(str == "quotation") { filterType = TALKACTION_MATCH_QUOTATION; } else if(str == "first word") { filterType = TALKACTION_MATCH_FIRST_WORD; } } if(readXMLInteger(p, "case-sensitive", intValue) || readXMLInteger(p, "sensitive", intValue)){ caseSensitive = (intValue != 0); } if(readXMLInteger(p, "access", intValue)){ accessLevel = intValue; } return true; }
bool WeaponWand::configureEvent(xmlNodePtr p) { if(!Weapon::configureEvent(p)) return false; int32_t intValue; std::string strValue; if(readXMLInteger(p, "min", intValue)) minChange = intValue; if(readXMLInteger(p, "max", intValue)) maxChange = intValue; if(readXMLString(p, "type", strValue)) { std::string tmpStrValue = asLowerCaseString(strValue); if(tmpStrValue == "earth") params.combatType = COMBAT_EARTHDAMAGE; else if(tmpStrValue == "ice") params.combatType = COMBAT_ICEDAMAGE; else if(tmpStrValue == "energy") params.combatType = COMBAT_ENERGYDAMAGE; else if(tmpStrValue == "fire") params.combatType = COMBAT_FIREDAMAGE; else if(tmpStrValue == "death") params.combatType = COMBAT_DEATHDAMAGE; else if(tmpStrValue == "holy") params.combatType = COMBAT_HOLYDAMAGE; else std::cout << "[Warning - WeaponWand::configureEvent] Type \"" << strValue << "\" does not exist." << std::endl; } return true; }
bool EffectEvent::configureRaidEvent(xmlNodePtr eventNode) { if(!RaidEvent::configureRaidEvent(eventNode)) return false; int32_t intValue; std::string strValue; if(!readXMLInteger(eventNode, "id", intValue)) { if(!readXMLString(eventNode, "name", strValue)) { std::clog << "[Error - EffectEvent::configureRaidEvent] id (or name) tag missing for effect event." << std::endl; return false; } else m_effect = getMagicEffect(strValue); } else m_effect = (MagicEffect_t)intValue; if(!readXMLString(eventNode, "pos", strValue)) { if(!readXMLInteger(eventNode, "x", intValue)) { std::clog << "[Error - EffectEvent::configureRaidEvent] x tag missing for effect event." << std::endl; return false; } m_position.x = intValue; if(!readXMLInteger(eventNode, "y", intValue)) { std::clog << "[Error - EffectEvent::configureRaidEvent] y tag missing for effect event." << std::endl; return false; } m_position.y = intValue; if(!readXMLInteger(eventNode, "z", intValue)) { std::clog << "[Error - EffectEvent::configureRaidEvent] z tag missing for effect event." << std::endl; return false; } m_position.z = intValue; } else { IntegerVec posList = vectorAtoi(explodeString(strValue, ";")); if(posList.size() < 3) { std::clog << "[Error - EffectEvent::configureRaidEvent] Malformed pos tag for effect event." << std::endl; return false; } m_position = Position(posList[0], posList[1], posList[2]); } return true; }
bool Actions::loadFromXml(const std::string &_datadir) { this->loaded = false; Action *action = NULL; datadir = _datadir; std::string filename = datadir + "actions/actions.xml"; std::transform(filename.begin(), filename.end(), filename.begin(), tolower); xmlDocPtr doc = xmlParseFile(filename.c_str()); if (doc){ this->loaded=true; xmlNodePtr root, p; root = xmlDocGetRootElement(doc); if (xmlStrcmp(root->name,(const xmlChar*) "actions")){ xmlFreeDoc(doc); return false; } p = root->children; while (p) { const char* str = (char*)p->name; if (strcmp(str, "action") == 0){ int itemid,uniqueid,actionid; if(readXMLInteger(p,"itemid",itemid)){ action = loadAction(p); useItemMap[itemid] = action; action = NULL; } else if(readXMLInteger(p,"uniqueid",uniqueid)){ action = loadAction(p); uniqueItemMap[uniqueid] = action; action = NULL; } else if(readXMLInteger(p,"actionid",actionid)){ action = loadAction(p); actionItemMap[actionid] = action; action = NULL; } else{ std::cout << "missing action id." << std::endl; } } p = p->next; } xmlFreeDoc(doc); } return this->loaded; }
bool SingleSpawnEvent::configureRaidEvent(xmlNodePtr eventNode) { if(!RaidEvent::configureRaidEvent(eventNode)) return false; std::string strValue; if(!readXMLString(eventNode, "name", strValue)) { std::clog << "[Error - SingleSpawnEvent::configureRaidEvent] name tag missing for singlespawn event." << std::endl; return false; } m_monsterName = strValue; if(!readXMLString(eventNode, "pos", strValue)) { int32_t intValue; if(!readXMLInteger(eventNode, "x", intValue)) { std::clog << "[Error - SingleSpawnEvent::configureRaidEvent] x tag missing for singlespawn event." << std::endl; return false; } m_position.x = intValue; if(!readXMLInteger(eventNode, "y", intValue)) { std::clog << "[Error - SingleSpawnEvent::configureRaidEvent] y tag missing for singlespawn event." << std::endl; return false; } m_position.y = intValue; if(!readXMLInteger(eventNode, "z", intValue)) { std::clog << "[Error - SingleSpawnEvent::configureRaidEvent] z tag missing for singlespawn event." << std::endl; return false; } m_position.z = intValue; } else { IntegerVec posList = vectorAtoi(explodeString(strValue, ";")); if(posList.size() < 3) { std::clog << "[Error - SingleSpawnEvent::configureRaidEvent] Malformed pos tag for singlespawn event." << std::endl; return false; } m_position = Position(posList[0], posList[1], posList[2]); } return true; }
bool Groups::parseGroupNode(xmlNodePtr p) { if(xmlStrcmp(p->name, (const xmlChar*)"group")) return false; int32_t intValue; if(!readXMLInteger(p, "id", intValue)) { std::cout << "[Warning - Groups::parseGroupNode] Missing group id." << std::endl; return false; } std::string strValue; int64_t int64Value; Group* group = new Group(intValue); if(readXMLString(p, "name", strValue)) { group->setFullName(strValue); group->setName(asLowerCaseString(strValue)); } if(readXMLInteger64(p, "flags", int64Value)) group->setFlags(int64Value); if(readXMLInteger64(p, "customFlags", int64Value)) group->setCustomFlags(int64Value); if(readXMLInteger(p, "access", intValue)) group->setAccess(intValue); if(readXMLInteger(p, "ghostAccess", intValue)) group->setGhostAccess(intValue); else group->setGhostAccess(group->getAccess()); if(readXMLInteger(p, "violationReasons", intValue)) group->setViolationReasons(intValue); if(readXMLInteger(p, "nameViolationFlags", intValue)) group->setNameViolationFlags(intValue); if(readXMLInteger(p, "statementViolationFlags", intValue)) group->setStatementViolationFlags(intValue); if(readXMLInteger(p, "depotLimit", intValue)) group->setDepotLimit(intValue); if(readXMLInteger(p, "maxVips", intValue)) group->setMaxVips(intValue); if(readXMLInteger(p, "outfit", intValue)) group->setOutfit(intValue); groupsMap[group->getId()] = group; return true; }
bool Item::loadItem(xmlNodePtr node, Container* parent) { if(!xmlStrcmp(node->name, (const xmlChar*)"item")) return false; int32_t intValue; std::string strValue; Item* item = NULL; if(readXMLInteger(node, "id", intValue)) item = Item::CreateItem(intValue); if(!item) return false; if(readXMLString(node, "attributes", strValue)) { StringVec v, attr = explodeString(strValue, ";"); for(StringVec::iterator it = attr.begin(); it != attr.end(); ++it) { v = explodeString((*it), ","); if(v.size() < 2) continue; if(atoi(v[1].c_str()) || v[1] == "0") item->setAttribute(v[0].c_str(), atoi(v[1].c_str())); else item->setAttribute(v[0].c_str(), v[1]); } } //compatibility if(readXMLInteger(node, "subtype", intValue) || readXMLInteger(node, "subType", intValue)) item->setSubType(intValue); if(readXMLInteger(node, "actionId", intValue) || readXMLInteger(node, "actionid", intValue) || readXMLInteger(node, "aid", intValue)) item->setActionId(intValue); if(readXMLInteger(node, "uniqueId", intValue) || readXMLInteger(node, "uniqueid", intValue) || readXMLInteger(node, "uid", intValue)) item->setUniqueId(intValue); if(readXMLString(node, "text", strValue)) item->setText(strValue); if(item->getContainer()) loadContainer(node, item->getContainer()); if(parent) parent->addItem(item); return true; }
bool Item::loadItem(xmlNodePtr node, Container* parent) { if (xmlStrcmp(node->name, (const xmlChar*)"item") == 0) { int32_t intValue; std::string strValue; Item* item = NULL; if (readXMLInteger(node, "id", intValue)) { item = Item::CreateItem(intValue); } if (!item) { return false; } //optional if (readXMLInteger(node, "subtype", intValue)) { item->setSubType(intValue); } if (readXMLInteger(node, "actionid", intValue)) { item->setActionId(intValue); } if (readXMLString(node, "text", strValue)) { item->setText(strValue); } if (item->getContainer()) { loadContainer(node, item->getContainer()); } if (parent) { parent->addItem(item); } return true; } return false; }
bool Outfits::parseOutfitNode(xmlNodePtr p) { if(xmlStrcmp(p->name, (const xmlChar*)"outfit")) return false; int32_t intValue; if(!readXMLInteger(p, "id", intValue)) { LOGe("[Outfits::parseOutfitNode] Missing outfit id, skipping"); return false; } Outfit newOutfit; newOutfit.outfitId = intValue; std::string name, strValue; if(readXMLString(p, "default", strValue)) newOutfit.isDefault = booleanString(strValue); if(!readXMLString(p, "name", strValue)) { std::stringstream ss; ss << "Outfit #" << newOutfit.outfitId; ss >> name; }
bool Action::configureEvent(xmlNodePtr p) { int32_t intValue; if(readXMLInteger(p, "allowfaruse", intValue)) { if(intValue != 0) setAllowFarUse(true); } if(readXMLInteger(p, "blockwalls", intValue)) { if(intValue == 0) setCheckLineOfSight(false); } return true; }
Item* ProtocolAdmin::createMail(const std::string& xmlData, std::string& name, uint32_t& depotId) { xmlDocPtr doc = xmlParseMemory(xmlData.c_str(), strlen(xmlData.c_str())); if(!doc){ return NULL; } xmlNodePtr root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name,(const xmlChar*)"mail") != 0){ return NULL; } int32_t itemId = ITEM_PARCEL; int32_t intValue; std::string strValue; if(readXMLString(root, "to", strValue)){ name = strValue; } if(readXMLString(root, "town", strValue)){ if(!Mailbox::getDepotId(strValue, depotId)){ return NULL; } } else{ //use the players default town if(!IOPlayer::instance()->getDefaultTown(name, depotId)){ return NULL; } } if(readXMLInteger(root, "id", intValue)){ itemId = intValue; } Item* mailItem = Item::CreateItem(itemId); mailItem->setParent(VirtualCylinder::virtualCylinder); if(Container* mailContainer = mailItem->getContainer()){ xmlNodePtr node = root->children; while(node){ if(node->type != XML_ELEMENT_NODE){ node = node->next; continue; } if(!Item::loadItem(node, mailContainer)){ delete mailContainer; return NULL; } node = node->next; } } return mailItem; }
bool WeaponDistance::configureEvent(xmlNodePtr p) { if (!Weapon::configureEvent(p)) { return false; } const ItemType& it = Item::items[id]; //default values if (it.ammoType != AMMO_NONE) { //hit chance on two-handed weapons is limited to 90% maxHitChance = 90; } else { //one-handed is set to 75% maxHitChance = 75; } if (it.hitChance != 0) { hitChance = it.hitChance; } if (it.maxHitChance != -1) { maxHitChance = it.maxHitChance; } if (it.breakChance != -1) { breakChance = it.breakChance; } if (it.ammoAction != AMMOACTION_NONE) { ammoAction = it.ammoAction; } int32_t intValue; if (readXMLInteger(p, "hitChance", intValue)) { std::cout << "Warning: hitChance is not longer used in weapons.xml." << std::endl; } if (readXMLInteger(p, "breakChance", intValue)) { std::cout << "Warning: breakChance is not longer used in weapons.xml." << std::endl; } return true; }
bool SingleSpawnEvent::configureRaidEvent(xmlNodePtr eventNode) { if(!RaidEvent::configureRaidEvent(eventNode)){ return false; } std::string strValue; int intValue; if(readXMLString(eventNode, "name", strValue)){ m_monsterName = strValue; } else{ std::cout << "[Error] Raid: name tag missing for singlespawn event." << std::endl; return false; } if(readXMLInteger(eventNode, "x", intValue)){ m_position.x = intValue; } else{ std::cout << "[Error] Raid: x tag missing for singlespawn event." << std::endl; return false; } if(readXMLInteger(eventNode, "y", intValue)){ m_position.y = intValue; } else{ std::cout << "[Error] Raid: y tag missing for singlespawn event." << std::endl; return false; } if(readXMLInteger(eventNode, "z", intValue)){ m_position.z = intValue; } else{ std::cout << "[Error] Raid: z tag missing for singlespawn event." << std::endl; return false; } return true; }
bool RaidEvent::configureRaidEvent(xmlNodePtr eventNode) { std::string strValue; if(readXMLString(eventNode, "ref", strValue)) m_ref = booleanString(strValue); int32_t intValue; if(readXMLInteger(eventNode, "delay", intValue)) m_delay = std::max((int32_t)m_delay, intValue); return true; }
bool Item::unserialize(xmlNodePtr nodeItem) { int intValue; std::string strValue; if(readXMLInteger(nodeItem, "id", intValue)){ id = intValue; } else{ return false; } if(readXMLInteger(nodeItem, "count", intValue)){ setSubType(intValue); } if(readXMLString(nodeItem, "special_description", strValue)){ setSpecialDescription(strValue); } if(readXMLString(nodeItem, "text", strValue)){ setText(strValue); } if(readXMLInteger(nodeItem, "written_date", intValue)){ setWrittenDate(intValue); } if(readXMLString(nodeItem, "writer", strValue)){ setWriter(strValue); } if(readXMLInteger(nodeItem, "actionId", intValue)){ setActionId(intValue); } if(readXMLInteger(nodeItem, "uniqueId", intValue)){ setUniqueId(intValue); } if(readXMLInteger(nodeItem, "duration", intValue)){ setDuration(intValue); } if(readXMLInteger(nodeItem, "decayState", intValue)){ ItemDecayState_t decayState = (ItemDecayState_t)intValue; if(decayState != DECAYING_FALSE){ setDecaying(DECAYING_PENDING); } } return true; }
bool RaidEvent::configureRaidEvent(xmlNodePtr eventNode) { int intValue; if(readXMLInteger(eventNode, "delay", intValue)){ m_delay = intValue; if(m_delay < RAID_MINTICKS){ m_delay = RAID_MINTICKS; } return true; } else{ std::cout << "[Error] Raid: delay tag missing." << std::endl; return false; } }
Item* Admin::createMail(const std::string xmlData, std::string& name) { xmlDocPtr doc = xmlParseMemory(xmlData.c_str(), xmlData.length()); if(!doc) return NULL; xmlNodePtr root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name,(const xmlChar*)"mail")) return NULL; int32_t intValue; std::string strValue; int32_t itemId = ITEM_PARCEL; if(readXMLString(root, "to", strValue)) name = strValue; if(readXMLInteger(root, "id", intValue)) itemId = intValue; Item* mailItem = Item::CreateItem(itemId); mailItem->setParent(VirtualCylinder::virtualCylinder); if(Container* mailContainer = mailItem->getContainer()) { xmlNodePtr node = root->children; while(node) { if(node->type != XML_ELEMENT_NODE) { node = node->next; continue; } if(!Item::loadItem(node, mailContainer)) { delete mailContainer; return NULL; } node = node->next; } } return mailItem; }
bool Vocations::loadFromXml() { std::string filename = "data/XML/vocations.xml"; xmlDocPtr doc = xmlParseFile(filename.c_str()); if (doc) { xmlNodePtr root, p; root = xmlDocGetRootElement(doc); if (xmlStrcmp(root->name, (const xmlChar*)"vocations") != 0) { xmlFreeDoc(doc); return false; } p = root->children; while (p) { std::string str; int32_t intVal; if (xmlStrcmp(p->name, (const xmlChar*)"vocation") == 0) { Vocation* voc = new Vocation(); uint32_t voc_id; xmlNodePtr configNode; if (readXMLInteger(p, "id", intVal)) { float floatVal; voc_id = intVal; if (readXMLString(p, "name", str)) { voc->name = str; } if (readXMLInteger(p, "clientid", intVal)) { voc->clientId = intVal; } if (readXMLString(p, "description", str)) { voc->description = str; } if (readXMLInteger(p, "gaincap", intVal)) { voc->gainCap = intVal; } if (readXMLInteger(p, "gainhp", intVal)) { voc->gainHP = intVal; } if (readXMLInteger(p, "gainmana", intVal)) { voc->gainMana = intVal; } if (readXMLInteger(p, "gainhpticks", intVal)) { voc->gainHealthTicks = intVal; } if (readXMLInteger(p, "gainhpamount", intVal)) { voc->gainHealthAmount = intVal; } if (readXMLInteger(p, "gainmanaticks", intVal)) { voc->gainManaTicks = intVal; } if (readXMLInteger(p, "gainmanaamount", intVal)) { voc->gainManaAmount = intVal; } if (readXMLFloat(p, "manamultiplier", floatVal)) { voc->manaMultiplier = floatVal; } if (readXMLInteger(p, "attackspeed", intVal)) { voc->attackSpeed = intVal; } if (readXMLInteger(p, "basespeed", intVal)) { voc->baseSpeed = intVal; } if (readXMLInteger(p, "soulmax", intVal)) { voc->soulMax = intVal; } if (readXMLInteger(p, "gainsoulticks", intVal)) { voc->gainSoulTicks = intVal; } if (readXMLInteger(p, "fromvoc", intVal)) { voc->fromVocation = intVal; } configNode = p->children; while (configNode) { if (xmlStrcmp(configNode->name, (const xmlChar*)"skill") == 0) { uint32_t skill_id; if (readXMLInteger(configNode, "id", intVal)) { skill_id = intVal; if (skill_id > SKILL_LAST) { std::cout << "No valid skill id. " << skill_id << std::endl; } else { if (readXMLFloat(configNode, "multiplier", floatVal)) { voc->skillMultipliers[skill_id] = floatVal; } } } else { std::cout << "Missing skill id." << std::endl; } } else if (xmlStrcmp(configNode->name, (const xmlChar*)"formula") == 0) { if (readXMLFloat(configNode, "meleeDamage", floatVal)) { voc->meleeDamageMultipler = floatVal; } if (readXMLFloat(configNode, "distDamage", floatVal)) { voc->distDamageMultipler = floatVal; } if (readXMLFloat(configNode, "defense", floatVal)) { voc->defenseMultipler = floatVal; } if (readXMLFloat(configNode, "armor", floatVal)) { voc->armorMultipler = floatVal; } } configNode = configNode->next; } vocationsMap[voc_id] = voc; } else { std::cout << "Missing vocation id." << std::endl; } } p = p->next; } xmlFreeDoc(doc); } return true; }
bool MoveEvent::configureEvent(xmlNodePtr p) { std::string str; int intValue; if(readXMLString(p, "event", str)){ if(asLowerCaseString(str) == "stepin"){ m_eventType = MOVE_EVENT_STEP_IN; } else if(asLowerCaseString(str) == "stepout"){ m_eventType = MOVE_EVENT_STEP_OUT; } else if(asLowerCaseString(str) == "equip"){ m_eventType = MOVE_EVENT_EQUIP; } else if(asLowerCaseString(str) == "deequip"){ m_eventType = MOVE_EVENT_DEEQUIP; } else if(asLowerCaseString(str) == "additem"){ m_eventType = MOVE_EVENT_ADD_ITEM; } else if(asLowerCaseString(str) == "removeitem"){ m_eventType = MOVE_EVENT_REMOVE_ITEM; } else{ std::cout << "Error: [MoveEvent::configureMoveEvent] No valid event name " << str << std::endl; return false; } if(m_eventType == MOVE_EVENT_EQUIP || m_eventType == MOVE_EVENT_DEEQUIP){ if(readXMLString(p, "slot", str)){ if(asLowerCaseString(str) == "head"){ slot = SLOT_HEAD; } else if(asLowerCaseString(str) == "necklace"){ slot = SLOT_NECKLACE; } else if(asLowerCaseString(str) == "backpack"){ slot = SLOT_BACKPACK; } else if(asLowerCaseString(str) == "armor"){ slot = SLOT_ARMOR; } else if(asLowerCaseString(str) == "right-hand"){ slot = SLOT_RIGHT; } else if(asLowerCaseString(str) == "left-hand"){ slot = SLOT_LEFT; } else if(asLowerCaseString(str) == "legs"){ slot = SLOT_LEGS; } else if(asLowerCaseString(str) == "feet"){ slot = SLOT_FEET; } else if(asLowerCaseString(str) == "ring"){ slot = SLOT_RING; } else if(asLowerCaseString(str) == "ammo"){ slot = SLOT_AMMO; } else{ std::cout << "Warning: [MoveEvent::configureMoveEvent] " << "Unknown slot type " << str << std::endl; } } wieldInfo = 0; if(readXMLInteger(p, "lvl", intValue) || readXMLInteger(p, "level", intValue)){ reqLevel = intValue; if(reqLevel > 0){ wieldInfo |= WIELDINFO_LEVEL; } } if(readXMLInteger(p, "maglv", intValue) || readXMLInteger(p, "maglevel", intValue)){ reqMagLevel = intValue; if(reqMagLevel > 0){ wieldInfo |= WIELDINFO_MAGLV; } } if(readXMLInteger(p, "prem", intValue) || readXMLInteger(p, "premium", intValue)){ premium = (intValue != 0); if(premium){ wieldInfo |= WIELDINFO_PREMIUM; } } //Gather vocation information typedef std::list<std::string> STRING_LIST; STRING_LIST vocStringList; xmlNodePtr vocationNode = p->children; while(vocationNode){ if(xmlStrcmp(vocationNode->name,(const xmlChar*)"vocation") == 0){ if(readXMLString(vocationNode, "name", str)){ int32_t vocationId = g_vocations.getVocationId(str); if(vocationId != -1){ vocEquipMap[vocationId] = true; intValue = 1; readXMLInteger(vocationNode, "showInDescription", intValue); if(intValue != 0){ toLowerCaseString(str); vocStringList.push_back(str); } } } } vocationNode = vocationNode->next; } if(!vocStringList.empty()){ for(STRING_LIST::iterator it = vocStringList.begin(); it != vocStringList.end(); ++it){ if(*it != vocStringList.front()){ if(*it != vocStringList.back()){ vocationString += ", "; } else{ vocationString += " and "; } } vocationString += *it; vocationString += "s"; } wieldInfo |= WIELDINFO_VOCREQ; } } } else{ std::cout << "Error: [MoveEvent::configureMoveEvent] No event found." << std::endl; return false; } return true; }
bool MoveEvents::registerEvent(Event* event, xmlNodePtr p) { MoveEvent* moveEvent = dynamic_cast<MoveEvent*>(event); if(!moveEvent) return false; bool success = true; int id; std::string str; MoveEvent_t eventType = moveEvent->getEventType(); if(eventType == MOVE_EVENT_ADD_ITEM || eventType == MOVE_EVENT_REMOVE_ITEM){ if(readXMLInteger(p,"tileitem",id) && id == 1){ switch(eventType){ case MOVE_EVENT_ADD_ITEM: moveEvent->setEventType(MOVE_EVENT_ADD_ITEM_ITEMTILE); break; case MOVE_EVENT_REMOVE_ITEM: moveEvent->setEventType(MOVE_EVENT_REMOVE_ITEM_ITEMTILE); break; default: break; } } } if(readXMLInteger(p,"itemid",id)){ if(moveEvent->getEventType() == MOVE_EVENT_EQUIP){ ItemType& it = Item::items.getItemType(id); it.wieldInfo = moveEvent->getWieldInfo(); it.minReqLevel = moveEvent->getReqLevel(); it.minReqMagicLevel = moveEvent->getReqMagLv(); it.vocationString = moveEvent->getVocationString(); } addEvent(moveEvent, id, m_itemIdMap); } else if(readXMLInteger(p,"uniqueid",id)){ addEvent(moveEvent, id, m_uniqueIdMap); } else if(readXMLInteger(p,"actionid",id)){ addEvent(moveEvent, id, m_actionIdMap); } else if(readXMLString(p,"pos",str)){ std::vector<std::string> posList = explodeString(str, ";"); if(posList.size() < 3){ success = false; } else{ Position pos; pos.x = atoi(posList[0].c_str()); pos.y = atoi(posList[1].c_str()); pos.z = atoi(posList[2].c_str()); addEvent(moveEvent, pos, m_positionMap); } } else{ success = false; } return success; }
bool Vocations::parseVocationNode(xmlNodePtr p) { std::string strValue; int32_t intValue; float floatValue; if(xmlStrcmp(p->name, (const xmlChar*)"vocation")) return false; if(!readXMLInteger(p, "id", intValue)) { std::cout << "[Error - Vocations::parseVocationNode] Missing vocation id." << std::endl; return false; } Vocation* voc = new Vocation(intValue); if(readXMLString(p, "name", strValue)) voc->setName(strValue); if(readXMLString(p, "description", strValue)) voc->setDescription(strValue); if(readXMLString(p, "needpremium", strValue)) voc->setNeedPremium(booleanString(strValue)); if(readXMLInteger(p, "gaincap", intValue) || readXMLInteger(p, "gaincapacity", intValue)) voc->setGainCap(intValue); if(readXMLInteger(p, "gainhp", intValue) || readXMLInteger(p, "gainhealth", intValue)) voc->setGain(GAIN_HEALTH, intValue); if(readXMLInteger(p, "gainmana", intValue)) voc->setGain(GAIN_MANA, intValue); if(readXMLInteger(p, "gainhpticks", intValue) || readXMLInteger(p, "gainhealthticks", intValue)) voc->setGainTicks(GAIN_HEALTH, intValue); if(readXMLInteger(p, "gainhpamount", intValue) || readXMLInteger(p, "gainhealthamount", intValue)) voc->setGainAmount(GAIN_HEALTH, intValue); if(readXMLInteger(p, "gainmanaticks", intValue)) voc->setGainTicks(GAIN_MANA, intValue); if(readXMLInteger(p, "gainmanaamount", intValue)) voc->setGainAmount(GAIN_MANA, intValue); if(readXMLFloat(p, "manamultiplier", floatValue)) voc->setMultiplier(MULTIPLIER_MANA, floatValue); if(readXMLInteger(p, "attackspeed", intValue)) voc->setAttackSpeed(intValue); if(readXMLInteger(p, "basespeed", intValue)) voc->setBaseSpeed(intValue); if(readXMLInteger(p, "soulmax", intValue)) voc->setGain(GAIN_SOUL, intValue); if(readXMLInteger(p, "gainsoulamount", intValue)) voc->setGainAmount(GAIN_SOUL, intValue); if(readXMLInteger(p, "gainsoulticks", intValue)) voc->setGainTicks(GAIN_SOUL, intValue); if(readXMLString(p, "attackable", strValue)) voc->setAttackable(booleanString(strValue)); if(readXMLInteger(p, "fromvoc", intValue) || readXMLInteger(p, "fromvocation", intValue)) voc->setFromVocation(intValue); if(readXMLInteger(p, "lessloss", intValue)) voc->setLessLoss(intValue); xmlNodePtr configNode = p->children; while(configNode) { if(!xmlStrcmp(configNode->name, (const xmlChar*)"skill")) { if(readXMLFloat(configNode, "fist", floatValue)) voc->setSkillMultiplier(SKILL_FIST, floatValue); if(readXMLInteger(configNode, "fistBase", intValue)) voc->setSkillBase(SKILL_FIST, intValue); if(readXMLFloat(configNode, "club", floatValue)) voc->setSkillMultiplier(SKILL_CLUB, floatValue); if(readXMLInteger(configNode, "clubBase", intValue)) voc->setSkillBase(SKILL_CLUB, intValue); if(readXMLFloat(configNode, "axe", floatValue)) voc->setSkillMultiplier(SKILL_AXE, floatValue); if(readXMLInteger(configNode, "axeBase", intValue)) voc->setSkillBase(SKILL_AXE, intValue); if(readXMLFloat(configNode, "sword", floatValue)) voc->setSkillMultiplier(SKILL_SWORD, floatValue); if(readXMLInteger(configNode, "swordBase", intValue)) voc->setSkillBase(SKILL_SWORD, intValue); if(readXMLFloat(configNode, "distance", floatValue) || readXMLFloat(configNode, "dist", floatValue)) voc->setSkillMultiplier(SKILL_DIST, floatValue); if(readXMLInteger(configNode, "distanceBase", intValue) || readXMLInteger(configNode, "distBase", intValue)) voc->setSkillBase(SKILL_DIST, intValue); if(readXMLFloat(configNode, "shielding", floatValue) || readXMLFloat(configNode, "shield", floatValue)) voc->setSkillMultiplier(SKILL_SHIELD, floatValue); if(readXMLInteger(configNode, "shieldingBase", intValue) || readXMLInteger(configNode, "shieldBase", intValue)) voc->setSkillBase(SKILL_SHIELD, intValue); if(readXMLFloat(configNode, "fishing", floatValue) || readXMLFloat(configNode, "fish", floatValue)) voc->setSkillMultiplier(SKILL_FISH, floatValue); if(readXMLInteger(configNode, "fishingBase", intValue) || readXMLInteger(configNode, "fishBase", intValue)) voc->setSkillBase(SKILL_FISH, intValue); if(readXMLFloat(configNode, "experience", floatValue) || readXMLFloat(configNode, "exp", floatValue)) voc->setSkillMultiplier(SKILL__LEVEL, floatValue); if(readXMLInteger(configNode, "id", intValue)) { skills_t skill = (skills_t)intValue; if(intValue < SKILL_FIRST || intValue >= SKILL__LAST) { std::cout << "[Error - Vocations::parseVocationNode] No valid skill id (" << intValue << ")." << std::endl; continue; } if(readXMLInteger(configNode, "base", intValue)) voc->setSkillBase(skill, intValue); if(readXMLFloat(configNode, "multiplier", floatValue)) voc->setSkillMultiplier(skill, floatValue); } } else if(!xmlStrcmp(configNode->name, (const xmlChar*)"formula")) { if(readXMLFloat(configNode, "meleeDamage", floatValue)) voc->setMultiplier(MULTIPLIER_MELEE, floatValue); if(readXMLFloat(configNode, "distDamage", floatValue) || readXMLFloat(configNode, "distanceDamage", floatValue)) voc->setMultiplier(MULTIPLIER_DISTANCE, floatValue); if(readXMLFloat(configNode, "wandDamage", floatValue) || readXMLFloat(configNode, "rodDamage", floatValue)) voc->setMultiplier(MULTIPLIER_WAND, floatValue); if(readXMLFloat(configNode, "magDamage", floatValue) || readXMLFloat(configNode, "magicDamage", floatValue)) voc->setMultiplier(MULTIPLIER_MAGIC, floatValue); if(readXMLFloat(configNode, "magHealingDamage", floatValue) || readXMLFloat(configNode, "magicHealingDamage", floatValue)) voc->setMultiplier(MULTIPLIER_MAGICHEALING, floatValue); if(readXMLFloat(configNode, "defense", floatValue)) voc->setMultiplier(MULTIPLIER_DEFENSE, floatValue); if(readXMLFloat(configNode, "magDefense", floatValue) || readXMLFloat(configNode, "magicDefense", floatValue)) voc->setMultiplier(MULTIPLIER_MAGICDEFENSE, floatValue); if(readXMLFloat(configNode, "armor", floatValue)) voc->setMultiplier(MULTIPLIER_ARMOR, floatValue); } else if(!xmlStrcmp(configNode->name, (const xmlChar*)"absorb")) { if(readXMLInteger(configNode, "percentAll", intValue)) { for(uint32_t i = COMBAT_FIRST; i <= COMBAT_LAST; i++) voc->increaseAbsorbPercent((CombatType_t)i, intValue); } else if(readXMLInteger(configNode, "percentElements", intValue)) { voc->increaseAbsorbPercent(COMBAT_ENERGYDAMAGE, intValue); voc->increaseAbsorbPercent(COMBAT_FIREDAMAGE, intValue); voc->increaseAbsorbPercent(COMBAT_EARTHDAMAGE, intValue); voc->increaseAbsorbPercent(COMBAT_ICEDAMAGE, intValue); } else if(readXMLInteger(configNode, "percentMagic", intValue)) { voc->increaseAbsorbPercent(COMBAT_ENERGYDAMAGE, intValue); voc->increaseAbsorbPercent(COMBAT_FIREDAMAGE, intValue); voc->increaseAbsorbPercent(COMBAT_EARTHDAMAGE, intValue); voc->increaseAbsorbPercent(COMBAT_ICEDAMAGE, intValue); voc->increaseAbsorbPercent(COMBAT_HOLYDAMAGE, intValue); voc->increaseAbsorbPercent(COMBAT_DEATHDAMAGE, intValue); } else if(readXMLInteger(configNode, "percentEnergy", intValue)) voc->increaseAbsorbPercent(COMBAT_ENERGYDAMAGE, intValue); else if(readXMLInteger(configNode, "percentFire", intValue)) voc->increaseAbsorbPercent(COMBAT_FIREDAMAGE, intValue); else if(readXMLInteger(configNode, "percentPoison", intValue) || readXMLInteger(configNode, "percentEarth", intValue)) voc->increaseAbsorbPercent(COMBAT_EARTHDAMAGE, intValue); else if(readXMLInteger(configNode, "percentIce", intValue)) voc->increaseAbsorbPercent(COMBAT_ICEDAMAGE, intValue); else if(readXMLInteger(configNode, "percentHoly", intValue)) voc->increaseAbsorbPercent(COMBAT_HOLYDAMAGE, intValue); else if(readXMLInteger(configNode, "percentDeath", intValue)) voc->increaseAbsorbPercent(COMBAT_DEATHDAMAGE, intValue); else if(readXMLInteger(configNode, "percentLifeDrain", intValue)) voc->increaseAbsorbPercent(COMBAT_LIFEDRAIN, intValue); else if(readXMLInteger(configNode, "percentManaDrain", intValue)) voc->increaseAbsorbPercent(COMBAT_MANADRAIN, intValue); else if(readXMLInteger(configNode, "percentDrown", intValue)) voc->increaseAbsorbPercent(COMBAT_DROWNDAMAGE, intValue); else if(readXMLInteger(configNode, "percentPhysical", intValue)) voc->increaseAbsorbPercent(COMBAT_PHYSICALDAMAGE, intValue); else if(readXMLInteger(configNode, "percentHealing", intValue)) voc->increaseAbsorbPercent(COMBAT_HEALING, intValue); else if(readXMLInteger(configNode, "percentUndefined", intValue)) voc->increaseAbsorbPercent(COMBAT_UNDEFINEDDAMAGE, intValue); } configNode = configNode->next; } vocationsMap[voc->getId()] = voc; return true; }
bool AdminProtocolConfig::loadXMLConfig() { xmlDocPtr doc = xmlParseFile("data/XML/admin.xml"); if (!doc) { return false; } xmlNodePtr root, p, q; root = xmlDocGetRootElement(doc); if (!xmlStrEqual(root->name, (const xmlChar*)"otadmin")) { xmlFreeDoc(doc); return false; } int enabled; if (readXMLInteger(root, "enabled", enabled)) { m_enabled = enabled != 0; } int value; p = root->children; while (p) { if (xmlStrEqual(p->name, (const xmlChar*)"security")) { if (readXMLInteger(p, "onlylocalhost", value)) { m_onlyLocalHost = value != 0; } if (readXMLInteger(p, "maxconnections", value) && value > 0) { m_maxConnections = value; } if (readXMLInteger(p, "loginrequired", value)) { m_requireLogin = value != 0; } std::string password; if (readXMLString(p, "loginpassword", password)) { m_password = password; } else if (m_requireLogin) { std::cout << "Security warning: require login but use default password." << std::endl; } } else if (xmlStrEqual(p->name, (const xmlChar*)"encryption")) { if (readXMLInteger(p, "required", value)) { m_requireEncryption = value != 0; } q = p->children; while (q) { if (xmlStrEqual(q->name, (const xmlChar*)"key")) { std::string str; if (readXMLString(q, "type", str)) { if (asLowerCaseString(str) == "rsa1024xtea") { if (readXMLString(q, "file", str)) { m_key_RSA1024XTEA = new RSA(); if (!m_key_RSA1024XTEA->setKey("data/XML/" + str)) { delete m_key_RSA1024XTEA; m_key_RSA1024XTEA = NULL; std::cout << "Can not load key from data/XML/" << str << std::endl; } } else { std::cout << "Missing file for RSA1024XTEA key." << std::endl; } } else { std::cout << str << " is not a valid key type." << std::endl; } } } q = q->next; } } p = p->next; } xmlFreeDoc(doc); return true; }
bool Spawns::loadFromXml(const std::string& _filename) { if (isLoaded()) { return true; } filename = _filename; xmlDocPtr doc = xmlParseFile(filename.c_str()); if (doc) { xmlNodePtr root, spawnNode; root = xmlDocGetRootElement(doc); if (xmlStrcmp(root->name, (const xmlChar*)"spawns") != 0) { xmlFreeDoc(doc); return false; } int32_t intValue; std::string strValue; spawnNode = root->children; while (spawnNode) { if (xmlStrcmp(spawnNode->name, (const xmlChar*)"spawn") == 0) { Position centerPos; int32_t radius = -1; if (readXMLInteger(spawnNode, "centerx", intValue)) { centerPos.x = intValue; } else { xmlFreeDoc(doc); return false; } if (readXMLInteger(spawnNode, "centery", intValue)) { centerPos.y = intValue; } else { xmlFreeDoc(doc); return false; } if (readXMLInteger(spawnNode, "centerz", intValue)) { centerPos.z = intValue; } else { xmlFreeDoc(doc); return false; } if (readXMLInteger(spawnNode, "radius", intValue)) { radius = intValue; } else { xmlFreeDoc(doc); return false; } Spawn* spawn = new Spawn(centerPos, radius); spawnList.push_back(spawn); xmlNodePtr tmpNode = spawnNode->children; while (tmpNode) { if (xmlStrcmp(tmpNode->name, (const xmlChar*)"monster") == 0) { std::string name = ""; Position pos = centerPos; Direction dir = NORTH; uint32_t interval = 0; if (readXMLString(tmpNode, "name", strValue)) { name = strValue; } else { tmpNode = tmpNode->next; continue; } if (readXMLInteger(tmpNode, "direction", intValue)) { switch (intValue) { case 0: dir = NORTH; break; case 1: dir = EAST; break; case 2: dir = SOUTH; break; case 3: dir = WEST; break; } } if (readXMLInteger(tmpNode, "x", intValue)) { pos.x += intValue; } else { tmpNode = tmpNode->next; continue; } if (readXMLInteger(tmpNode, "y", intValue)) { pos.y += intValue; } else { tmpNode = tmpNode->next; continue; } if (readXMLInteger(tmpNode, "spawntime", intValue) || readXMLInteger(tmpNode, "interval", intValue)) { interval = intValue * 1000; } else { tmpNode = tmpNode->next; continue; } if (interval > MINSPAWN_INTERVAL) { spawn->addMonster(name, pos, dir, interval); } else { std::cout << "[Warning] Spawns::loadFromXml " << name << " " << pos << " spawntime can not be less than " << MINSPAWN_INTERVAL / 1000 << " seconds." << std::endl; } } else if (xmlStrcmp(tmpNode->name, (const xmlChar*)"npc") == 0) { Direction direction = NORTH; std::string name = ""; Position placePos = centerPos; if (readXMLString(tmpNode, "name", strValue)) { name = strValue; } else { tmpNode = tmpNode->next; continue; } if (readXMLInteger(tmpNode, "direction", intValue)) { switch (intValue) { case 0: direction = NORTH; break; case 1: direction = EAST; break; case 2: direction = SOUTH; break; case 3: direction = WEST; break; } } if (readXMLInteger(tmpNode, "x", intValue)) { placePos.x += intValue; } else { tmpNode = tmpNode->next; continue; } if (readXMLInteger(tmpNode, "y", intValue)) { placePos.y += intValue; } else { tmpNode = tmpNode->next; continue; } Npc* npc = Npc::createNpc(name); if (!npc) { tmpNode = tmpNode->next; continue; } npc->setDirection(direction); npc->setMasterPos(placePos, radius); npcList.push_back(npc); } tmpNode = tmpNode->next; } } spawnNode = spawnNode->next; } xmlFreeDoc(doc); loaded = true; return true; } return false; }
bool Quests::parseQuestNode(xmlNodePtr p, bool checkDuplicate) { if(xmlStrcmp(p->name, (const xmlChar*)"quest")) return false; int32_t intValue; std::string strValue; uint32_t id = m_lastId; if(readXMLInteger(p, "id", intValue) && id > 0) { id = intValue; if(id > m_lastId) m_lastId = id; } std::string name; if(readXMLString(p, "name", strValue)) name = strValue; uint32_t startStorageId = 0; if(readXMLInteger(p, "startstorageid", intValue) || readXMLInteger(p, "storageId", intValue)) startStorageId = intValue; int32_t startStorageValue = 0; if(readXMLInteger(p, "startstoragevalue", intValue) || readXMLInteger(p, "storageValue", intValue)) startStorageValue = intValue; Quest* quest = new Quest(name, id, startStorageId, startStorageValue); if(!quest) return false; for(xmlNodePtr missionNode = p->children; missionNode; missionNode = missionNode->next) { if(xmlStrcmp(missionNode->name, (const xmlChar*)"mission")) continue; std::string missionName, missionState; if(readXMLString(missionNode, "name", strValue)) missionName = strValue; if(readXMLString(missionNode, "state", strValue) || readXMLString(missionNode, "description", strValue)) missionState = strValue; uint32_t storageId = 0; if(readXMLInteger(missionNode, "storageid", intValue) || readXMLInteger(missionNode, "storageId", intValue)) storageId = intValue; int32_t startValue = 0, endValue = 0; if(readXMLInteger(missionNode, "startvalue", intValue) || readXMLInteger(missionNode, "startValue", intValue)) startValue = intValue; if(readXMLInteger(missionNode, "endvalue", intValue) || readXMLInteger(missionNode, "endValue", intValue)) endValue = intValue; if(Mission* mission = new Mission(missionName, missionState, storageId, startValue, endValue)) { if(missionState.empty()) { // parse sub-states only if main is not set for(xmlNodePtr stateNode = missionNode->children; stateNode; stateNode = stateNode->next) { if(xmlStrcmp(stateNode->name, (const xmlChar*)"missionstate")) continue; uint32_t missionId; if(!readXMLInteger(stateNode, "id", intValue)) { std::clog << "[Warning - Quests::parseQuestNode] Missing missionId for mission state" << std::endl; continue; } missionId = intValue; std::string description; if(readXMLString(stateNode, "description", strValue)) description = strValue; mission->newState(missionId, description); } } quest->newMission(mission); } } if(checkDuplicate) { for(QuestList::iterator it = quests.begin(); it != quests.end(); ++it) { if((*it)->getName() == name) delete *it; } } m_lastId++; quests.push_back(quest); return true; }
bool Outfits::loadFromXml(const std::string& datadir) { m_datadir = datadir; std::string filename = datadir + "outfits.xml"; xmlDocPtr doc = xmlParseFile(filename.c_str()); if (doc) { xmlNodePtr root, p; root = xmlDocGetRootElement(doc); if (xmlStrcmp(root->name, (const xmlChar*)"outfits") != 0) { xmlFreeDoc(doc); std::cout << "Warning: outfits.xml not found, using defaults." << std::endl; return true; } p = root->children; while (p) { if (xmlStrcmp(p->name, (const xmlChar*)"outfit") == 0) { int32_t intValue; std::string strValue; if (readXMLInteger(p, "id", intValue)) { Outfit outfit; outfit.outfitId = intValue; outfit.isDefault = true; if (readXMLInteger(p, "premium", intValue)) { outfit.isPremium = (intValue == 1); } if (readXMLInteger(p, "default", intValue)) { outfit.isDefault = (intValue == 1); } xmlNodePtr pchild = p->children; while (pchild) { if (xmlStrcmp(pchild->name, (const xmlChar*)"list") == 0) { if (readXMLInteger(pchild, "looktype", intValue)) { outfit.lookType = intValue; } else { std::cout << "Missing looktype for an outfit." << std::endl; pchild = pchild->next; continue; } if (readXMLInteger(pchild, "addons", intValue)) { outfit.addons = intValue; } if (readXMLString(pchild, "name", strValue)) { outfit.name = strValue; } if (readXMLString(pchild, "type", strValue)) { PlayerSex_t playersex = PLAYERSEX_LAST; if (asLowerCaseString(strValue) == "female") { playersex = PLAYERSEX_FEMALE; } else if (asLowerCaseString(strValue) == "male") { playersex = PLAYERSEX_MALE; } else if (asLowerCaseString(strValue) == "femalegm") { playersex = PLAYERSEX_FEMALE_GAMEMASTER; } else if (asLowerCaseString(strValue) == "malegm") { playersex = PLAYERSEX_MALE_GAMEMASTER; } else if (asLowerCaseString(strValue) == "femalecm") { playersex = PLAYERSEX_FEMALE_MANAGER; } else if (asLowerCaseString(strValue) == "malecm") { playersex = PLAYERSEX_MALE_MANAGER; } else if (asLowerCaseString(strValue) == "femalegod") { playersex = PLAYERSEX_FEMALE_GOD; } else if (asLowerCaseString(strValue) == "malegod") { playersex = PLAYERSEX_MALE_GOD; } else { std::cout << "Invalid player sex " << strValue << " for an outfit." << std::endl; pchild = pchild->next; continue; } allOutfits.push_back(outfit); outfitMaps[playersex][outfit.outfitId] = outfit; } else { std::cout << "Missing playersex for an outfit." << std::endl; pchild = pchild->next; continue; } } pchild = pchild->next; } } else { std::cout << "Missing outfit id." << std::endl; } } p = p->next; } xmlFreeDoc(doc); } return true; }
void TilesetCategory::loadBrush(xmlNodePtr node, wxArrayString& warnings) { std::string strVal; std::string brush_name; int intVal = 0; readXMLValue(node, "after", brush_name); if(readXMLValue(node, "afteritem", intVal)) { ItemType& it = item_db[intVal]; if(it.id != 0)// Verify that we have a valid item { brush_name = (it.raw_brush? it.raw_brush->getName() : ""); } } if(xmlStrcmp(node->name,(const xmlChar*)"brush") == 0) { if(readXMLString(node, "name", strVal)) { Brush* brush = tileset.brushes.getBrush(strVal); if(brush) { std::vector<Brush*>::iterator insert_here = brushlist.end(); if(brush_name.size()) { for(std::vector<Brush*>::iterator iter = brushlist.begin(); iter != brushlist.end(); ++iter) { if((*iter)->getName() == brush_name) { insert_here = ++iter; break; } } } brush->flagAsVisible(); brushlist.insert(insert_here, brush); } else { warnings.push_back(wxT("Brush \"") + wxstr(strVal) + wxT("\" doesn't exist.")); } } } else if(xmlStrcmp(node->name,(const xmlChar*)"item") == 0) { int fromid = 0, toid = 0; if(!readXMLInteger(node, "id", fromid)) { if(!readXMLInteger(node, "fromid", fromid)) { warnings.push_back(wxT("Couldn't read raw ids.")); } readXMLInteger(node, "toid", toid); } toid = std::max(toid, fromid); std::vector<Brush*>::iterator insert_here = brushlist.end(); if(brush_name.size()) { for(std::vector<Brush*>::iterator iter = brushlist.begin(); iter != brushlist.end(); ++iter) { if((*iter)->getName() == brush_name) { insert_here = ++iter; break; } } } std::vector<Brush*> temp_vec; for(int id = fromid; id <= toid; ++id) { ItemType& it = item_db[id]; if(it.id == 0) // Verify that we have a valid item { warnings.push_back(wxT("Unknown item id #") + i2ws(id) + wxT(".")); } else { RAWBrush* brush; if(it.raw_brush) { brush = it.raw_brush; } else { brush = it.raw_brush = newd RAWBrush(it.id); it.has_raw = true; tileset.brushes.addBrush(brush); // This will take care of cleaning up afterwards } if(it.doodad_brush == NULL && !isTrivial()) { it.doodad_brush = brush; } brush->flagAsVisible(); temp_vec.push_back(brush); } } brushlist.insert(insert_here, temp_vec.begin(), temp_vec.end()); } }
bool Monsters::loadMonster(const std::string& file, const std::string& monsterName, bool reloading/* = false*/) { if(getIdByName(monsterName) && !reloading) { std::clog << "[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(file.c_str()); if(!doc) { std::clog << "[Warning - Monsters::loadMonster] Cannot load monster (" << monsterName << ") file (" << file << ")." << std::endl; std::clog << getLastXMLError() << std::endl; return false; } monsterLoad = true; xmlNodePtr root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name,(const xmlChar*)"monster")) { std::clog << "[Error - Monsters::loadMonster] Malformed monster (" << monsterName << ") file (" << file << ")." << std::endl; xmlFreeDoc(doc); return false; } int32_t intValue; std::string strValue; if(readXMLString(root, "name", strValue)) mType->name = strValue; else monsterLoad = false; if(readXMLString(root, "nameDescription", strValue)) mType->nameDescription = strValue; else { mType->nameDescription = "a " + mType->name; toLowerCaseString(mType->nameDescription); } if(readXMLString(root, "race", strValue)) { std::string tmpStrValue = asLowerCaseString(strValue); if(tmpStrValue == "venom") mType->race = RACE_VENOM; else if(tmpStrValue == "blood") mType->race = RACE_BLOOD; else if(tmpStrValue == "undead") mType->race = RACE_UNDEAD; else if(tmpStrValue == "fire") mType->race = RACE_FIRE; else if(tmpStrValue == "energy") mType->race = RACE_ENERGY; else { int32_t race = atoi(strValue.c_str()); if(race < RACE_VENOM || race > RACE_ENERGY) { SHOW_XML_WARNING("Unknown race type " << strValue); } else mType->race = (RaceType_t)race; } } if(readXMLInteger(root, "experience", intValue)) mType->experience = intValue; if(readXMLInteger(root, "speed", intValue)) mType->baseSpeed = intValue; if(readXMLInteger(root, "manacost", intValue)) mType->manaCost = intValue; if(readXMLString(root, "skull", strValue)) mType->skull = getSkulls(strValue); if(readXMLString(root, "shield", strValue)) mType->partyShield = getShields(strValue); if(readXMLString(root, "emblem", strValue)) mType->guildEmblem = getEmblems(strValue); for(xmlNodePtr p = root->children; p; p = p->next) { if(p->type != XML_ELEMENT_NODE) continue; if(!xmlStrcmp(p->name, (const xmlChar*)"health")) { if(!readXMLInteger(p, "max", intValue)) { SHOW_XML_ERROR("Missing health.max"); monsterLoad = false; break; } mType->healthMax = intValue; if(!readXMLInteger(p, "now", intValue)) mType->health = mType->healthMax; else mType->health = intValue; } else if(!xmlStrcmp(p->name, (const xmlChar*)"flags")) { for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"flag")) { 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 = getSkulls(strValue); if(readXMLString(tmpNode, "shield", strValue)) mType->partyShield = getShields(strValue); if(readXMLString(tmpNode, "emblem", strValue)) mType->guildEmblem = getEmblems(strValue); } } //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")) { for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { 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"); } } } else if(!xmlStrcmp(p->name, (const xmlChar*)"defenses")) { if(readXMLInteger(p, "defense", intValue)) mType->defense = intValue; if(readXMLInteger(p, "armor", intValue)) mType->armor = intValue; for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { 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"); } } } else if(!xmlStrcmp(p->name, (const xmlChar*)"immunities")) { for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { 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; } } } 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"); for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { 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); } } } else if(!xmlStrcmp(p->name, (const xmlChar*)"loot")) { for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { if(tmpNode->type != XML_ELEMENT_NODE) continue; LootBlock rootBlock; if(loadLoot(tmpNode, rootBlock)) mType->lootItems.push_back(rootBlock); else SHOW_XML_WARNING("Cant load loot"); } } else if(!xmlStrcmp(p->name, (const xmlChar*)"elements")) { for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { 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; } } } else if(!xmlStrcmp(p->name, (const xmlChar*)"summons")) { if(readXMLInteger(p, "maxSummons", intValue) || readXMLInteger(p, "max", intValue)) mType->maxSummons = intValue; for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { 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"); } } } else if(!xmlStrcmp(p->name, (const xmlChar*)"script")) { for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { 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"); } } } else SHOW_XML_WARNING("Unknown attribute type - " << p->name); } xmlFreeDoc(doc); if(!monsterLoad) { if(new_mType) delete mType; return false; } static uint32_t id = 0; if(new_mType) { monsterNames[asLowerCaseString(monsterName)] = ++id; monsters[id] = mType; } return true; }
bool Monsters::deserializeSpell(xmlNodePtr node, spellBlock_t& sb, const std::string& description) { sb.range = sb.minCombatValue = sb.maxCombatValue = 0; sb.combatSpell = sb.isMelee = false; sb.chance = 100; sb.speed = 2000; std::string name, scriptName; bool isScripted = false; if(readXMLString(node, "script", scriptName)) isScripted = true; else if(!readXMLString(node, "name", name)) return false; int32_t intValue; std::string strValue; if(readXMLInteger(node, "speed", intValue) || readXMLInteger(node, "interval", intValue)) sb.speed = std::max(1, intValue); if(readXMLInteger(node, "chance", intValue)) { if(intValue < 0 || intValue > 100) intValue = 100; sb.chance = intValue; } if(readXMLInteger(node, "range", intValue)) { if(intValue < 0) intValue = 0; if(intValue > Map::maxViewportX * 2) intValue = Map::maxViewportX * 2; sb.range = intValue; } if(readXMLInteger(node, "min", intValue)) sb.minCombatValue = intValue; if(readXMLInteger(node, "max", intValue)) sb.maxCombatValue = intValue; //normalize values if(std::abs(sb.minCombatValue) > std::abs(sb.maxCombatValue)) std::swap(sb.minCombatValue, sb.maxCombatValue); if((sb.spell = g_spells->getSpellByName(name))) return true; CombatSpell* combatSpell = NULL; bool needTarget = false, needDirection = false; if(isScripted) { if(readXMLString(node, "direction", strValue)) needDirection = booleanString(strValue); if(readXMLString(node, "target", strValue)) needTarget = booleanString(strValue); combatSpell = new CombatSpell(NULL, needTarget, needDirection); if(!combatSpell->loadScript(getFilePath(FILE_TYPE_OTHER, g_spells->getScriptBaseName() + "/scripts/" + scriptName), true)) { delete combatSpell; return false; } if(!combatSpell->loadScriptCombat()) { delete combatSpell; return false; } combatSpell->getCombat()->setPlayerCombatValues(FORMULA_VALUE, sb.minCombatValue, 0, sb.maxCombatValue, 0, 0, 0, 0, 0, 0, 0); } else { Combat* combat = new Combat; sb.combatSpell = true; if(readXMLInteger(node, "length", intValue)) { int32_t length = intValue; if(length > 0) { int32_t spread = 3; //need direction spell if(readXMLInteger(node, "spread", intValue)) spread = std::max(0, intValue); CombatArea* area = new CombatArea(); area->setupArea(length, spread); combat->setArea(area); needDirection = true; } } if(readXMLInteger(node, "radius", intValue)) { int32_t radius = intValue; //target spell if(readXMLInteger(node, "target", intValue)) needTarget = (intValue != 0); CombatArea* area = new CombatArea(); area->setupArea(radius); combat->setArea(area); } std::string tmpName = asLowerCaseString(name); if(tmpName == "melee" || tmpName == "distance") { int32_t attack = 0, skill = 0; if(readXMLInteger(node, "attack", attack) && readXMLInteger(node, "skill", skill)) { sb.minCombatValue = 0; sb.maxCombatValue = -Weapons::getMaxMeleeDamage(skill, attack); } uint32_t tickInterval = 2000; ConditionType_t conditionType = CONDITION_NONE; if(readXMLInteger(node, "physical", intValue)) conditionType = CONDITION_PHYSICAL; else if(readXMLInteger(node, "fire", intValue)) { conditionType = CONDITION_FIRE; tickInterval = 9000; } else if(readXMLInteger(node, "energy", intValue)) { conditionType = CONDITION_ENERGY; tickInterval = 10000; } else if(readXMLInteger(node, "earth", intValue)) { conditionType = CONDITION_POISON; tickInterval = 5000; } else if(readXMLInteger(node, "freeze", intValue)) { conditionType = CONDITION_FREEZING; tickInterval = 8000; } else if(readXMLInteger(node, "dazzle", intValue)) { conditionType = CONDITION_DAZZLED; tickInterval = 10000; } else if(readXMLInteger(node, "curse", intValue)) { conditionType = CONDITION_CURSED; tickInterval = 4000; } else if(readXMLInteger(node, "drown", intValue)) { conditionType = CONDITION_DROWN; tickInterval = 5000; } else if(readXMLInteger(node, "poison", intValue)) { conditionType = CONDITION_POISON; tickInterval = 5000; } uint32_t damage = std::abs(intValue); if(readXMLInteger(node, "tick", intValue) && intValue > 0) tickInterval = intValue; if(conditionType != CONDITION_NONE) { Condition* condition = getDamageCondition(conditionType, damage, damage, 0, tickInterval); if(condition) combat->setCondition(condition); } sb.isMelee = true; sb.range = 1; combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_PHYSICALDAMAGE); combat->setParam(COMBATPARAM_BLOCKEDBYSHIELD, 1); combat->setParam(COMBATPARAM_BLOCKEDBYARMOR, 1); } else if(tmpName == "physical") { combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_PHYSICALDAMAGE); combat->setParam(COMBATPARAM_BLOCKEDBYARMOR, 1); } else if(tmpName == "drown") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_DROWNDAMAGE); else if(tmpName == "fire") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_FIREDAMAGE); else if(tmpName == "energy") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_ENERGYDAMAGE); else if(tmpName == "poison" || tmpName == "earth") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_EARTHDAMAGE); else if(tmpName == "ice") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_ICEDAMAGE); else if(tmpName == "holy") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_HOLYDAMAGE); else if(tmpName == "death") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_DEATHDAMAGE); else if(tmpName == "lifedrain") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_LIFEDRAIN); else if(tmpName == "manadrain") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_MANADRAIN); else if(tmpName == "healing") { bool aggressive = false; if(readXMLInteger(node, "self", intValue)) aggressive = intValue; combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_HEALING); combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive); } else if(tmpName == "undefined") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_UNDEFINEDDAMAGE); else if(tmpName == "speed") { int32_t speedChange = 0, duration = 10000; if(readXMLInteger(node, "duration", intValue)) duration = intValue; enum Aggressive { NO, YES, AUTO } aggressive = AUTO; if(readXMLInteger(node, "self", intValue)) aggressive = (Aggressive)intValue; if(readXMLInteger(node, "speedchange", intValue)) speedChange = std::max(-1000, intValue); //cant be slower than 100% std::vector<Outfit_t> outfits; for(xmlNodePtr tmpNode = node->children; tmpNode; tmpNode = tmpNode->next) { if(xmlStrcmp(tmpNode->name,(const xmlChar*)"outfit")) continue; if(readXMLInteger(tmpNode, "type", intValue)) { Outfit_t outfit; outfit.lookType = intValue; if(readXMLInteger(tmpNode, "head", intValue)) outfit.lookHead = intValue; if(readXMLInteger(tmpNode, "body", intValue)) outfit.lookBody = intValue; if(readXMLInteger(tmpNode, "legs", intValue)) outfit.lookLegs = intValue; if(readXMLInteger(tmpNode, "feet", intValue)) outfit.lookFeet = intValue; if(readXMLInteger(tmpNode, "addons", intValue)) outfit.lookAddons = intValue; outfits.push_back(outfit); } if(readXMLInteger(tmpNode, "typeex", intValue) || readXMLInteger(tmpNode, "item", intValue)) { Outfit_t outfit; outfit.lookTypeEx = intValue; outfits.push_back(outfit); } if(readXMLString(tmpNode, "monster", strValue)) { if(MonsterType* mType = g_monsters.getMonsterType(strValue)) outfits.push_back(mType->outfit); } } ConditionType_t conditionType = CONDITION_PARALYZE; if(speedChange > 0) { conditionType = CONDITION_HASTE; if(aggressive == AUTO) aggressive = NO; } else if(aggressive == AUTO) aggressive = YES; if(ConditionSpeed* condition = dynamic_cast<ConditionSpeed*>(Condition::createCondition( CONDITIONID_COMBAT, conditionType, duration))) { condition->setFormulaVars((speedChange / 1000.), 0, (speedChange / 1000.), 0); if(!outfits.empty()) condition->setOutfits(outfits); combat->setCondition(condition); combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive); } } else if(tmpName == "outfit") { std::vector<Outfit_t> outfits; for(xmlNodePtr tmpNode = node->children; tmpNode; tmpNode = tmpNode->next) { if(xmlStrcmp(tmpNode->name,(const xmlChar*)"outfit")) continue; if(readXMLInteger(tmpNode, "type", intValue)) { Outfit_t outfit; outfit.lookType = intValue; if(readXMLInteger(tmpNode, "head", intValue)) outfit.lookHead = intValue; if(readXMLInteger(tmpNode, "body", intValue)) outfit.lookBody = intValue; if(readXMLInteger(tmpNode, "legs", intValue)) outfit.lookLegs = intValue; if(readXMLInteger(tmpNode, "feet", intValue)) outfit.lookFeet = intValue; if(readXMLInteger(tmpNode, "addons", intValue)) outfit.lookAddons = intValue; outfits.push_back(outfit); } if(readXMLInteger(tmpNode, "typeex", intValue) || readXMLInteger(tmpNode, "item", intValue)) { Outfit_t outfit; outfit.lookTypeEx = intValue; outfits.push_back(outfit); } if(readXMLString(tmpNode, "monster", strValue)) { if(MonsterType* mType = g_monsters.getMonsterType(strValue)) outfits.push_back(mType->outfit); } } if(outfits.empty()) { if(readXMLInteger(node, "type", intValue)) { Outfit_t outfit; outfit.lookType = intValue; if(readXMLInteger(node, "head", intValue)) outfit.lookHead = intValue; if(readXMLInteger(node, "body", intValue)) outfit.lookBody = intValue; if(readXMLInteger(node, "legs", intValue)) outfit.lookLegs = intValue; if(readXMLInteger(node, "feet", intValue)) outfit.lookFeet = intValue; if(readXMLInteger(node, "addons", intValue)) outfit.lookAddons = intValue; outfits.push_back(outfit); } if(readXMLInteger(node, "typeex", intValue) || readXMLInteger(node, "item", intValue)) { Outfit_t outfit; outfit.lookTypeEx = intValue; outfits.push_back(outfit); } if(readXMLString(node, "monster", strValue)) { if(MonsterType* mType = g_monsters.getMonsterType(strValue)) outfits.push_back(mType->outfit); } } if(!outfits.empty()) { int32_t duration = 10000; if(readXMLInteger(node, "duration", intValue)) duration = intValue; bool aggressive = false; if(readXMLInteger(node, "self", intValue)) aggressive = intValue; if(ConditionOutfit* condition = dynamic_cast<ConditionOutfit*>(Condition::createCondition( CONDITIONID_COMBAT, CONDITION_OUTFIT, duration))) { condition->setOutfits(outfits); combat->setCondition(condition); combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive); } } } else if(tmpName == "invisible") { int32_t duration = 10000; if(readXMLInteger(node, "duration", intValue)) duration = intValue; bool aggressive = false; if(readXMLInteger(node, "self", intValue)) aggressive = intValue; if(Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration)) { combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive); combat->setCondition(condition); } } else if(tmpName == "drunk") { int32_t duration = 10000; if(readXMLInteger(node, "duration", intValue)) duration = intValue; if(Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration)) combat->setCondition(condition); } else if(tmpName == "skills" || tmpName == "attributes") { uint32_t duration = 10000, subId = 0; if(readXMLInteger(node, "duration", intValue)) duration = intValue; if(readXMLInteger(node, "subid", intValue)) subId = intValue; intValue = 0; ConditionParam_t param = CONDITIONPARAM_BUFF; //to know was it loaded if(readXMLInteger(node, "melee", intValue)) param = CONDITIONPARAM_SKILL_MELEE; else if(readXMLInteger(node, "fist", intValue)) param = CONDITIONPARAM_SKILL_FIST; else if(readXMLInteger(node, "club", intValue)) param = CONDITIONPARAM_SKILL_CLUB; else if(readXMLInteger(node, "axe", intValue)) param = CONDITIONPARAM_SKILL_AXE; else if(readXMLInteger(node, "sword", intValue)) param = CONDITIONPARAM_SKILL_SWORD; else if(readXMLInteger(node, "distance", intValue) || readXMLInteger(node, "dist", intValue)) param = CONDITIONPARAM_SKILL_DISTANCE; else if(readXMLInteger(node, "shielding", intValue) || readXMLInteger(node, "shield", intValue)) param = CONDITIONPARAM_SKILL_SHIELD; else if(readXMLInteger(node, "fishing", intValue) || readXMLInteger(node, "fish", intValue)) param = CONDITIONPARAM_SKILL_FISHING; else if(readXMLInteger(node, "meleePercent", intValue)) param = CONDITIONPARAM_SKILL_MELEEPERCENT; else if(readXMLInteger(node, "fistPercent", intValue)) param = CONDITIONPARAM_SKILL_FISTPERCENT; else if(readXMLInteger(node, "clubPercent", intValue)) param = CONDITIONPARAM_SKILL_CLUBPERCENT; else if(readXMLInteger(node, "axePercent", intValue)) param = CONDITIONPARAM_SKILL_AXEPERCENT; else if(readXMLInteger(node, "swordPercent", intValue)) param = CONDITIONPARAM_SKILL_SWORDPERCENT; else if(readXMLInteger(node, "distancePercent", intValue) || readXMLInteger(node, "distPercent", intValue)) param = CONDITIONPARAM_SKILL_DISTANCEPERCENT; else if(readXMLInteger(node, "shieldingPercent", intValue) || readXMLInteger(node, "shieldPercent", intValue)) param = CONDITIONPARAM_SKILL_SHIELDPERCENT; else if(readXMLInteger(node, "fishingPercent", intValue) || readXMLInteger(node, "fishPercent", intValue)) param = CONDITIONPARAM_SKILL_FISHINGPERCENT; else if(readXMLInteger(node, "maxhealth", intValue)) param = CONDITIONPARAM_STAT_MAXHEALTHPERCENT; else if(readXMLInteger(node, "maxmana", intValue)) param = CONDITIONPARAM_STAT_MAXMANAPERCENT; else if(readXMLInteger(node, "soul", intValue)) param = CONDITIONPARAM_STAT_SOULPERCENT; else if(readXMLInteger(node, "magiclevel", intValue) || readXMLInteger(node, "maglevel", intValue)) param = CONDITIONPARAM_STAT_MAGICLEVELPERCENT; else if(readXMLInteger(node, "maxhealthPercent", intValue)) param = CONDITIONPARAM_STAT_MAXHEALTHPERCENT; else if(readXMLInteger(node, "maxmanaPercent", intValue)) param = CONDITIONPARAM_STAT_MAXMANAPERCENT; else if(readXMLInteger(node, "soulPercent", intValue)) param = CONDITIONPARAM_STAT_SOULPERCENT; else if(readXMLInteger(node, "magiclevelPercent", intValue) || readXMLInteger(node, "maglevelPercent", intValue)) param = CONDITIONPARAM_STAT_MAGICLEVELPERCENT; if(param != CONDITIONPARAM_BUFF) { if(ConditionAttributes* condition = dynamic_cast<ConditionAttributes*>(Condition::createCondition( CONDITIONID_COMBAT, CONDITION_ATTRIBUTES, duration, false, subId))) { condition->setParam(param, intValue); combat->setCondition(condition); } } } else if(tmpName == "firefield") combat->setParam(COMBATPARAM_CREATEITEM, 1492); else if(tmpName == "poisonfield") combat->setParam(COMBATPARAM_CREATEITEM, 1496); else if(tmpName == "energyfield") combat->setParam(COMBATPARAM_CREATEITEM, 1495); else if(tmpName == "firecondition" || tmpName == "energycondition" || tmpName == "drowncondition" || tmpName == "poisoncondition" || tmpName == "earthcondition" || tmpName == "freezecondition" || tmpName == "cursecondition" || tmpName == "dazzlecondition") { ConditionType_t conditionType = CONDITION_NONE; uint32_t tickInterval = 2000; if(tmpName == "physicalcondition") conditionType = CONDITION_PHYSICAL; else if(tmpName == "firecondition") { conditionType = CONDITION_FIRE; tickInterval = 9000; } else if(tmpName == "energycondition") { conditionType = CONDITION_ENERGY; tickInterval = 10000; } else if(tmpName == "earthcondition") { conditionType = CONDITION_POISON; tickInterval = 5000; } else if(tmpName == "freezecondition") { conditionType = CONDITION_FREEZING; tickInterval = 8000; } else if(tmpName == "cursecondition") { conditionType = CONDITION_CURSED; tickInterval = 4000; } else if(tmpName == "dazzlecondition") { conditionType = CONDITION_DAZZLED; tickInterval = 10000; } else if(tmpName == "drowncondition") { conditionType = CONDITION_DROWN; tickInterval = 5000; } else if(tmpName == "poisoncondition") { conditionType = CONDITION_POISON; tickInterval = 5000; } if(readXMLInteger(node, "tick", intValue) && intValue > 0) tickInterval = intValue; int32_t startDamage = 0, minDamage = std::abs(sb.minCombatValue), maxDamage = std::abs(sb.maxCombatValue); if(readXMLInteger(node, "start", intValue)) startDamage = std::max(std::abs(intValue), minDamage); if(Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, startDamage, tickInterval)) combat->setCondition(condition); } else if(tmpName == "strength") { //TODO: monster extra strength } else if(tmpName == "effect") {/*show some effect and bye bye!*/} else { delete combat; std::clog << "[Error - Monsters::deserializeSpell] " << description << " - Unknown spell name: " << name << std::endl; return false; } combat->setPlayerCombatValues(FORMULA_VALUE, sb.minCombatValue, 0, sb.maxCombatValue, 0, 0, 0, 0, 0, 0, 0); combatSpell = new CombatSpell(combat, needTarget, needDirection); for(xmlNodePtr attributeNode = node->children; attributeNode; attributeNode = attributeNode->next) { if(!xmlStrcmp(attributeNode->name, (const xmlChar*)"attribute")) { if(readXMLString(attributeNode, "key", strValue)) { std::string tmpStrValue = asLowerCaseString(strValue); if(tmpStrValue == "shooteffect") { if(readXMLString(attributeNode, "value", strValue)) { ShootEffect_t shoot = getShootType(strValue); if(shoot != SHOOT_EFFECT_UNKNOWN) combat->setParam(COMBATPARAM_DISTANCEEFFECT, shoot); else std::clog << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown shootEffect: " << strValue << std::endl; } } else if(tmpStrValue == "areaeffect") { if(readXMLString(attributeNode, "value", strValue)) { MagicEffect_t effect = getMagicEffect(strValue); if(effect != MAGIC_EFFECT_UNKNOWN) combat->setParam(COMBATPARAM_EFFECT, effect); else std::clog << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown areaEffect: " << strValue << std::endl; } } else std::clog << "[Warning - Monsters::deserializeSpells] Effect type \"" << strValue << "\" does not exist." << std::endl; } } } } sb.spell = combatSpell; return true; }
bool Monsters::loadLoot(xmlNodePtr node, LootBlock& lootBlock) { std::string strValue; if(readXMLString(node, "id", strValue) || readXMLString(node, "ids", strValue)) { IntegerVec idsVec; parseIntegerVec(strValue, idsVec); for(IntegerVec::iterator it = idsVec.begin(); it != idsVec.end(); ++it) { lootBlock.ids.push_back(*it); if(Item::items[(*it)].isContainer()) loadChildLoot(node, lootBlock); } } else if(readXMLString(node, "name", strValue) || readXMLString(node, "names", strValue)) { StringVec names = explodeString(strValue, ";"); for(StringVec::iterator it = names.begin(); it != names.end(); ++it) { uint16_t tmp = Item::items.getItemIdByName(strValue); if(!tmp) continue; lootBlock.ids.push_back(tmp); if(Item::items[tmp].isContainer()) loadChildLoot(node, lootBlock); } } if(lootBlock.ids.empty()) return false; int32_t intValue; if(readXMLInteger(node, "count", intValue) || readXMLInteger(node, "countmax", intValue)) lootBlock.count = intValue; else lootBlock.count = 1; if(readXMLInteger(node, "chance", intValue) || readXMLInteger(node, "chance1", intValue)) lootBlock.chance = std::min(MAX_LOOTCHANCE, intValue); else lootBlock.chance = MAX_LOOTCHANCE; if(readXMLInteger(node, "subtype", intValue) || readXMLInteger(node, "subType", intValue)) lootBlock.subType = intValue; if(readXMLInteger(node, "actionId", intValue) || readXMLInteger(node, "actionid", intValue) || readXMLInteger(node, "aid", intValue)) lootBlock.actionId = intValue; if(readXMLInteger(node, "uniqueId", intValue) || readXMLInteger(node, "uniqueid", intValue) || readXMLInteger(node, "uid", intValue)) lootBlock.uniqueId = intValue; if(readXMLString(node, "text", strValue)) lootBlock.text = strValue; return true; }
bool AreaSpawnEvent::configureRaidEvent(xmlNodePtr eventNode) { if(!RaidEvent::configureRaidEvent(eventNode)) return false; std::string strValue; int32_t intValue; if(readXMLInteger(eventNode, "radius", intValue)) { int32_t radius = intValue; Position centerPos; if(readXMLInteger(eventNode, "centerx", intValue)) centerPos.x = intValue; else { std::cout << "[Error] Raid: centerx tag missing for areaspawn event." << std::endl; return false; } if(readXMLInteger(eventNode, "centery", intValue)) centerPos.y = intValue; else { std::cout << "[Error] Raid: centery tag missing for areaspawn event." << std::endl; return false; } if(readXMLInteger(eventNode, "centerz", intValue)) centerPos.z = intValue; else { std::cout << "[Error] Raid: centerz tag missing for areaspawn event." << std::endl; return false; } m_fromPos.x = centerPos.x - radius; m_fromPos.y = centerPos.y - radius; m_fromPos.z = centerPos.z; m_toPos.x = centerPos.x + radius; m_toPos.y = centerPos.y + radius; m_toPos.z = centerPos.z; } else { if(readXMLInteger(eventNode, "fromx", intValue)) m_fromPos.x = intValue; else { std::cout << "[Error] Raid: fromx tag missing for areaspawn event." << std::endl; return false; } if(readXMLInteger(eventNode, "fromy", intValue)) m_fromPos.y = intValue; else { std::cout << "[Error] Raid: fromy tag missing for areaspawn event." << std::endl; return false; } if(readXMLInteger(eventNode, "fromz", intValue)) m_fromPos.z = intValue; else { std::cout << "[Error] Raid: fromz tag missing for areaspawn event." << std::endl; return false; } if(readXMLInteger(eventNode, "tox", intValue)) m_toPos.x = intValue; else { std::cout << "[Error] Raid: tox tag missing for areaspawn event." << std::endl; return false; } if(readXMLInteger(eventNode, "toy", intValue)) m_toPos.y = intValue; else { std::cout << "[Error] Raid: toy tag missing for areaspawn event." << std::endl; return false; } if(readXMLInteger(eventNode, "toz", intValue)) m_toPos.z = intValue; else { std::cout << "[Error] Raid: toz tag missing for areaspawn event." << std::endl; return false; } } xmlNodePtr monsterNode = eventNode->children; while(monsterNode) { if(xmlStrcmp(monsterNode->name, (const xmlChar*)"monster") == 0) { std::string name; int32_t minAmount = 0; int32_t maxAmount = 0; if(readXMLString(monsterNode, "name", strValue)) name = strValue; else { std::cout << "[Error] Raid: name tag missing for monster node." << std::endl; return false; } if(readXMLInteger(monsterNode, "minamount", intValue)) minAmount = intValue; if(readXMLInteger(monsterNode, "maxamount", intValue)) maxAmount = intValue; if(maxAmount == 0 && minAmount == 0) { if(readXMLInteger(monsterNode, "amount", intValue)) { maxAmount = intValue; minAmount = intValue; } else { std::cout << "[Error] Raid: amount tag missing for monster node." << std::endl; return false; } } addMonster(name, minAmount, maxAmount); } monsterNode = monsterNode->next; } return true; }