bool Raids::parseRaidNode(xmlNodePtr raidNode, bool checkDuplicate, FileType_t pathing) { if(xmlStrcmp(raidNode->name, (const xmlChar*)"raid")) return false; int32_t intValue; std::string strValue; if(!readXMLString(raidNode, "name", strValue)) { std::clog << "[Error - Raids::parseRaidNode] name tag missing for raid." << std::endl; return false; } std::string name = strValue; if(!readXMLInteger(raidNode, "interval2", intValue) || intValue <= 0) { std::clog << "[Error - Raids::parseRaidNode] interval2 tag missing or divided by 0 for raid " << name << std::endl; return false; } uint32_t interval = intValue * 60; std::string file; if(!readXMLString(raidNode, "file", strValue)) { file = name + ".xml"; std::clog << "[Warning - Raids::parseRaidNode] file tag missing for raid " << name << ", using default: " << file << std::endl; } else file = strValue; file = getFilePath(pathing, "raids/" + file); uint64_t margin = 0; if(!readXMLInteger(raidNode, "margin", intValue)) std::clog << "[Warning - Raids::parseRaidNode] margin tag missing for raid " << name << ", using default: " << margin << std::endl; else margin = intValue * 60 * 1000; RefType_t refType = REF_NONE; if(readXMLString(raidNode, "reftype", strValue) || readXMLString(raidNode, "refType", strValue)) { std::string tmpStrValue = asLowerCaseString(strValue); if(tmpStrValue == "single") refType = REF_SINGLE; else if(tmpStrValue == "block") refType = REF_BLOCK; else if(tmpStrValue != "none") std::clog << "[Warning - Raids::parseRaidNode] Unknown reftype \"" << strValue << "\" for raid " << name << std::endl; } bool ref = false; if(readXMLString(raidNode, "ref", strValue)) ref = booleanString(strValue); bool enabled = true; if(readXMLString(raidNode, "enabled", strValue)) enabled = booleanString(strValue); Raid* raid = new Raid(name, interval, margin, refType, ref, enabled); if(!raid || !raid->loadFromXml(file)) { delete raid; std::clog << "[Fatal - Raids::parseRaidNode] failed to load raid " << name << std::endl; return false; } if(checkDuplicate) { for(RaidList::iterator it = raidList.begin(); it != raidList.end(); ++it) { if((*it)->getName() == name) delete *it; } } raidList.push_back(raid); return true; }
bool Commands::loadFromXml() { pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file("data/XML/commands.xml"); if (!result) { std::cout << "[Error - Commands::loadFromXml] Failed to load data/XML/commands.xml: " << result.description() << std::endl; return false; } loaded = true; for (pugi::xml_node commandNode = doc.child("commands").first_child(); commandNode; commandNode = commandNode.next_sibling()) { pugi::xml_attribute cmdAttribute = commandNode.attribute("cmd"); if (!cmdAttribute) { std::cout << "[Warning - Commands::loadFromXml] Missing cmd" << std::endl; continue; } auto it = commandMap.find(cmdAttribute.as_string()); if (it == commandMap.end()) { std::cout << "[Warning - Commands::loadFromXml] Unknown command " << cmdAttribute.as_string() << std::endl; continue; } Command* command = it->second; pugi::xml_attribute groupAttribute = commandNode.attribute("group"); if (groupAttribute) { if (!command->loadedGroupId) { command->groupId = pugi::cast<uint32_t>(groupAttribute.value()); command->loadedGroupId = true; } else { std::cout << "[Notice - Commands::loadFromXml] Duplicate command: " << it->first << std::endl; } } pugi::xml_attribute acctypeAttribute = commandNode.attribute("acctype"); if (acctypeAttribute) { if (!command->loadedAccountType) { command->accountType = (AccountType_t)pugi::cast<uint32_t>(acctypeAttribute.value()); command->loadedAccountType = true; } else { std::cout << "[Notice - Commands::loadFromXml] Duplicate command: " << it->first << std::endl; } } pugi::xml_attribute logAttribute = commandNode.attribute("log"); if (logAttribute) { if (!command->loadedLogging) { command->logged = booleanString(logAttribute.as_string()); command->loadedLogging = true; } else { std::cout << "[Notice - Commands::loadFromXml] Duplicate log tag for: " << it->first << std::endl; } } } for (const auto& it : commandMap) { Command* command = it.second; if (!command->loadedGroupId) { std::cout << "[Warning - Commands::loadFromXml] Missing group id for command " << it.first << std::endl; } if (!command->loadedAccountType) { std::cout << "[Warning - Commands::loadFromXml] Missing acctype level for command " << it.first << std::endl; } if (!command->loadedLogging) { std::cout << "[Warning - Commands::loadFromXml] Missing log command " << it.first << std::endl; } g_game.addCommandTag(it.first.front()); } return loaded; }
void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id) { if (id > 30000 && id < 30100) { id -= 30000; if (id >= items.size()) { items.resize(id + 1); } ItemType& iType = items[id]; iType.id = id; } ItemType& it = getItemType(id); if (it.id == 0) { return; } it.name = itemNode.attribute("name").as_string(); nameToItems.insert({ asLowerCaseString(it.name), id }); pugi::xml_attribute articleAttribute = itemNode.attribute("article"); if (articleAttribute) { it.article = articleAttribute.as_string(); } pugi::xml_attribute pluralAttribute = itemNode.attribute("plural"); if (pluralAttribute) { it.pluralName = pluralAttribute.as_string(); } Abilities& abilities = it.getAbilities(); for (auto attributeNode : itemNode.children()) { pugi::xml_attribute keyAttribute = attributeNode.attribute("key"); if (!keyAttribute) { continue; } pugi::xml_attribute valueAttribute = attributeNode.attribute("value"); if (!valueAttribute) { continue; } std::string tmpStrValue = asLowerCaseString(keyAttribute.as_string()); auto parseAttribute = ItemParseAttributesMap.find(tmpStrValue); if (parseAttribute != ItemParseAttributesMap.end()) { ItemParseAttributes_t parseType = parseAttribute->second; switch (parseType) { case ITEM_PARSE_TYPE: { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); auto it2 = ItemTypesMap.find(tmpStrValue); if (it2 != ItemTypesMap.end()) { it.type = it2->second; if (it.type == ITEM_TYPE_CONTAINER) { it.group = ITEM_GROUP_CONTAINER; } } else { std::cout << "[Warning - Items::parseItemNode] Unknown type: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_DESCRIPTION: { it.description = valueAttribute.as_string(); break; } case ITEM_PARSE_RUNESPELLNAME: { it.runeSpellName = valueAttribute.as_string(); break; } case ITEM_PARSE_WEIGHT: { it.weight = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SHOWCOUNT: { it.showCount = valueAttribute.as_bool(); break; } case ITEM_PARSE_ARMOR: { it.armor = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_DEFENSE: { it.defense = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_EXTRADEF: { it.extraDefense = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_ATTACK: { it.attack = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_ROTATETO: { it.rotateTo = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MOVEABLE: { it.moveable = valueAttribute.as_bool(); break; } case ITEM_PARSE_BLOCKPROJECTILE: { it.blockProjectile = valueAttribute.as_bool(); break; } case ITEM_PARSE_PICKUPABLE: { it.allowPickupable = valueAttribute.as_bool(); break; } case ITEM_PARSE_FORCESERIALIZE: { it.forceSerialize = valueAttribute.as_bool(); break; } case ITEM_PARSE_FLOORCHANGE: { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); auto it2 = TileStatesMap.find(tmpStrValue); if (it2 != TileStatesMap.end()) { it.floorChange = it2->second; } else { std::cout << "[Warning - Items::parseItemNode] Unknown floorChange: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_CORPSETYPE: { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); auto it2 = RaceTypesMap.find(tmpStrValue); if (it2 != RaceTypesMap.end()) { it.corpseType = it2->second; } else { std::cout << "[Warning - Items::parseItemNode] Unknown corpseType: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_CONTAINERSIZE: { it.maxItems = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_FLUIDSOURCE: { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); auto it2 = FluidTypesMap.find(tmpStrValue); if (it2 != FluidTypesMap.end()) { it.fluidSource = it2->second; } else { std::cout << "[Warning - Items::parseItemNode] Unknown fluidSource: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_READABLE: { it.canReadText = valueAttribute.as_bool(); break; } case ITEM_PARSE_WRITEABLE: { it.canWriteText = valueAttribute.as_bool(); it.canReadText = it.canWriteText; break; } case ITEM_PARSE_MAXTEXTLEN: { it.maxTextLen = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_WRITEONCEITEMID: { it.writeOnceItemId = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_WEAPONTYPE: { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); auto it2 = WeaponTypesMap.find(tmpStrValue); if (it2 != WeaponTypesMap.end()) { it.weaponType = it2->second; } else { std::cout << "[Warning - Items::parseItemNode] Unknown weaponType: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_SLOTTYPE: { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "head") { it.slotPosition |= SLOTP_HEAD; } else if (tmpStrValue == "body") { it.slotPosition |= SLOTP_ARMOR; } else if (tmpStrValue == "legs") { it.slotPosition |= SLOTP_LEGS; } else if (tmpStrValue == "feet") { it.slotPosition |= SLOTP_FEET; } else if (tmpStrValue == "backpack") { it.slotPosition |= SLOTP_BACKPACK; } else if (tmpStrValue == "two-handed") { it.slotPosition |= SLOTP_TWO_HAND; } else if (tmpStrValue == "right-hand") { it.slotPosition &= ~SLOTP_LEFT; } else if (tmpStrValue == "left-hand") { it.slotPosition &= ~SLOTP_RIGHT; } else if (tmpStrValue == "necklace") { it.slotPosition |= SLOTP_NECKLACE; } else if (tmpStrValue == "ring") { it.slotPosition |= SLOTP_RING; } else if (tmpStrValue == "ammo") { it.slotPosition |= SLOTP_AMMO; } else if (tmpStrValue == "hand") { it.slotPosition |= SLOTP_HAND; } else { std::cout << "[Warning - Items::parseItemNode] Unknown slotType: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_AMMOTYPE: { it.ammoType = getAmmoType(asLowerCaseString(valueAttribute.as_string())); if (it.ammoType == AMMO_NONE) { std::cout << "[Warning - Items::parseItemNode] Unknown ammoType: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_SHOOTTYPE: { ShootType_t shoot = getShootType(asLowerCaseString(valueAttribute.as_string())); if (shoot != CONST_ANI_NONE) { it.shootType = shoot; } else { std::cout << "[Warning - Items::parseItemNode] Unknown shootType: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_EFFECT: { MagicEffectClasses effect = getMagicEffect(asLowerCaseString(valueAttribute.as_string())); if (effect != CONST_ME_NONE) { it.magicEffect = effect; } else { std::cout << "[Warning - Items::parseItemNode] Unknown effect: " << valueAttribute.as_string() << std::endl; } break; } case ITEM_PARSE_RANGE: { it.shootRange = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_STOPDURATION: { it.stopTime = valueAttribute.as_bool(); break; } case ITEM_PARSE_DECAYTO: { it.decayTo = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_TRANSFORMEQUIPTO: { it.transformEquipTo = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_TRANSFORMDEEQUIPTO: { it.transformDeEquipTo = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_DURATION: { it.decayTime = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SHOWDURATION: { it.showDuration = valueAttribute.as_bool(); break; } case ITEM_PARSE_CHARGES: { it.charges = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SHOWCHARGES: { it.showCharges = valueAttribute.as_bool(); break; } case ITEM_PARSE_SHOWATTRIBUTES: { it.showAttributes = valueAttribute.as_bool(); break; } case ITEM_PARSE_HITCHANCE: { it.hitChance = std::min<int8_t>(100, std::max<int8_t>(-100, pugi::cast<int16_t>(valueAttribute.value()))); break; } case ITEM_PARSE_MAXHITCHANCE: { it.maxHitChance = std::min<uint32_t>(100, pugi::cast<uint32_t>(valueAttribute.value())); break; } case ITEM_PARSE_INVISIBLE: { abilities.invisible = valueAttribute.as_bool(); break; } case ITEM_PARSE_SPEED: { abilities.speed = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_HEALTHGAIN: { abilities.regeneration = true; abilities.healthGain = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_HEALTHTICKS: { abilities.regeneration = true; abilities.healthTicks = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MANAGAIN: { abilities.regeneration = true; abilities.manaGain = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MANATICKS: { abilities.regeneration = true; abilities.manaTicks = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MANASHIELD: { abilities.manaShield = valueAttribute.as_bool(); break; } case ITEM_PARSE_SKILLSWORD: { abilities.skills[SKILL_SWORD] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SKILLAXE: { abilities.skills[SKILL_AXE] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SKILLCLUB: { abilities.skills[SKILL_CLUB] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SKILLDIST: { abilities.skills[SKILL_DISTANCE] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SKILLFISH: { abilities.skills[SKILL_FISHING] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SKILLSHIELD: { abilities.skills[SKILL_SHIELD] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_SKILLFIST: { abilities.skills[SKILL_FIST] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MAXHITPOINTS: { abilities.stats[STAT_MAXHITPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MAXHITPOINTSPERCENT: { abilities.statsPercent[STAT_MAXHITPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MAXMANAPOINTS: { abilities.stats[STAT_MAXMANAPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MAXMANAPOINTSPERCENT: { abilities.statsPercent[STAT_MAXMANAPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MAGICPOINTS: { abilities.stats[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MAGICPOINTSPERCENT: { abilities.statsPercent[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); break; } case ITEM_PARSE_FIELDABSORBPERCENTENERGY: { abilities.fieldAbsorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_FIELDABSORBPERCENTFIRE: { abilities.fieldAbsorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_FIELDABSORBPERCENTPOISON: { abilities.fieldAbsorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTALL: { int16_t value = pugi::cast<int16_t>(valueAttribute.value()); for (auto& i : abilities.absorbPercent) { i += value; } break; } case ITEM_PARSE_ABSORBPERCENTELEMENTS: { int16_t value = pugi::cast<int16_t>(valueAttribute.value()); abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value; break; } case ITEM_PARSE_ABSORBPERCENTMAGIC: { int16_t value = pugi::cast<int16_t>(valueAttribute.value()); abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += value; abilities.absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += value; break; } case ITEM_PARSE_ABSORBPERCENTENERGY: { abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTFIRE: { abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTPOISON: { abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTICE: { abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTHOLY: { abilities.absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTDEATH: { abilities.absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTLIFEDRAIN: { abilities.absorbPercent[combatTypeToIndex(COMBAT_LIFEDRAIN)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTMANADRAIN: { abilities.absorbPercent[combatTypeToIndex(COMBAT_MANADRAIN)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTDROWN: { abilities.absorbPercent[combatTypeToIndex(COMBAT_DROWNDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTPHYSICAL: { abilities.absorbPercent[combatTypeToIndex(COMBAT_PHYSICALDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTHEALING: { abilities.absorbPercent[combatTypeToIndex(COMBAT_HEALING)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ABSORBPERCENTUNDEFINED: { abilities.absorbPercent[combatTypeToIndex(COMBAT_UNDEFINEDDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); break; } case ITEM_PARSE_SUPPRESSDRUNK: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_DRUNK; } break; } case ITEM_PARSE_SUPPRESSENERGY: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_ENERGY; } break; } case ITEM_PARSE_SUPPRESSFIRE: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_FIRE; } break; } case ITEM_PARSE_SUPPRESSPOISON: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_POISON; } break; } case ITEM_PARSE_SUPPRESSDROWN: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_DROWN; } break; } case ITEM_PARSE_SUPPRESSPHYSICAL: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_BLEEDING; } break; } case ITEM_PARSE_SUPPRESSFREEZE: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_FREEZING; } break; } case ITEM_PARSE_SUPPRESSDAZZLE: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_DAZZLED; } break; } case ITEM_PARSE_SUPPRESSCURSE: { if (valueAttribute.as_bool()) { abilities.conditionSuppressions |= CONDITION_CURSED; } break; } case ITEM_PARSE_FIELD: { it.group = ITEM_GROUP_MAGICFIELD; it.type = ITEM_TYPE_MAGICFIELD; CombatType_t combatType = COMBAT_NONE; ConditionDamage* conditionDamage = nullptr; tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "fire") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_FIRE); combatType = COMBAT_FIREDAMAGE; } else if (tmpStrValue == "energy") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_ENERGY); combatType = COMBAT_ENERGYDAMAGE; } else if (tmpStrValue == "poison") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_POISON); combatType = COMBAT_EARTHDAMAGE; } else if (tmpStrValue == "drown") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_DROWN); combatType = COMBAT_DROWNDAMAGE; } else if (tmpStrValue == "physical") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_BLEEDING); combatType = COMBAT_PHYSICALDAMAGE; } else { std::cout << "[Warning - Items::parseItemNode] Unknown field value: " << valueAttribute.as_string() << std::endl; } if (combatType != COMBAT_NONE) { it.combatType = combatType; it.conditionDamage.reset(conditionDamage); for (auto subAttributeNode : attributeNode.children()) { uint32_t ticks = 0; int32_t damage = 0; int32_t start = 0; int32_t count = 1; pugi::xml_attribute subKeyAttribute = subAttributeNode.attribute("key"); if (!subKeyAttribute) { continue; } pugi::xml_attribute subValueAttribute = subAttributeNode.attribute("value"); if (!subValueAttribute) { continue; } tmpStrValue = asLowerCaseString(subKeyAttribute.as_string()); if (tmpStrValue == "ticks") { ticks = pugi::cast<uint32_t>(subValueAttribute.value()); } else if (tmpStrValue == "count") { count = std::max<int32_t>(1, pugi::cast<int32_t>(subValueAttribute.value())); } else if (tmpStrValue == "start") { start = std::max<int32_t>(0, pugi::cast<int32_t>(subValueAttribute.value())); } else if (tmpStrValue == "damage") { damage = -pugi::cast<int32_t>(subValueAttribute.value()); if (start > 0) { std::list<int32_t> damageList; ConditionDamage::generateDamageList(damage, start, damageList); for (int32_t damageValue : damageList) { conditionDamage->addDamage(1, ticks, -damageValue); } start = 0; } else { conditionDamage->addDamage(count, ticks, damage); } } } conditionDamage->setParam(CONDITION_PARAM_FIELD, 1); if (conditionDamage->getTotalDamage() > 0) { conditionDamage->setParam(CONDITION_PARAM_FORCEUPDATE, 1); } } break; } case ITEM_PARSE_REPLACEABLE: { it.replaceable = valueAttribute.as_bool(); break; } case ITEM_PARSE_PARTNERDIRECTION: { it.bedPartnerDir = getDirection(valueAttribute.as_string()); break; } case ITEM_PARSE_LEVELDOOR: { it.levelDoor = pugi::cast<uint32_t>(valueAttribute.value()); break; } case ITEM_PARSE_MALETRANSFORMTO: { uint16_t value = pugi::cast<uint16_t>(valueAttribute.value()); it.transformToOnUse[PLAYERSEX_MALE] = value; ItemType& other = getItemType(value); if (other.transformToFree == 0) { other.transformToFree = it.id; } if (it.transformToOnUse[PLAYERSEX_FEMALE] == 0) { it.transformToOnUse[PLAYERSEX_FEMALE] = value; } break; } case ITEM_PARSE_FEMALETRANSFORMTO: { uint16_t value = pugi::cast<uint16_t>(valueAttribute.value()); it.transformToOnUse[PLAYERSEX_FEMALE] = value; ItemType& other = getItemType(value); if (other.transformToFree == 0) { other.transformToFree = it.id; } if (it.transformToOnUse[PLAYERSEX_MALE] == 0) { it.transformToOnUse[PLAYERSEX_MALE] = value; } break; } case ITEM_PARSE_TRANSFORMTO: { it.transformToFree = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_DESTROYTO: { it.destroyTo = pugi::cast<uint16_t>(valueAttribute.value()); break; } case ITEM_PARSE_ELEMENTICE: { abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value()); abilities.elementType = COMBAT_ICEDAMAGE; break; } case ITEM_PARSE_ELEMENTEARTH: { abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value()); abilities.elementType = COMBAT_EARTHDAMAGE; break; } case ITEM_PARSE_ELEMENTFIRE: { abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value()); abilities.elementType = COMBAT_FIREDAMAGE; break; } case ITEM_PARSE_ELEMENTENERGY: { abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value()); abilities.elementType = COMBAT_ENERGYDAMAGE; break; } case ITEM_PARSE_WALKSTACK: { it.walkStack = valueAttribute.as_bool(); break; } case ITEM_PARSE_BLOCKING: { it.blockSolid = valueAttribute.as_bool(); break; } case ITEM_PARSE_ALLOWDISTREAD: { it.allowDistRead = booleanString(valueAttribute.as_string()); break; } default: { // It should not ever get to here, only if you add a new key to the map and don't configure a case for it. std::cout << "[Warning - Items::parseItemNode] Not configured key value: " << keyAttribute.as_string() << std::endl; break; } } } else { std::cout << "[Warning - Items::parseItemNode] Unknown key value: " << keyAttribute.as_string() << std::endl; } } //check bed items if ((it.transformToFree != 0 || it.transformToOnUse[PLAYERSEX_FEMALE] != 0 || it.transformToOnUse[PLAYERSEX_MALE] != 0) && it.type != ITEM_TYPE_BED) { std::cout << "[Warning - Items::parseItemNode] Item " << it.id << " is not set as a bed-type" << std::endl; } }
bool parseVocationNode(xmlNodePtr vocationNode, VocationMap& vocationMap, StringVec& vocStringVec, std::string& errorStr) { if(xmlStrcmp(vocationNode->name,(const xmlChar*)"vocation")) return true; int32_t vocationId = -1; std::string strValue, tmpStrValue; if(readXMLString(vocationNode, "name", strValue)) { vocationId = Vocations::getInstance()->getVocationId(strValue); if(vocationId != -1) { vocationMap[vocationId] = true; int32_t promotedVocation = Vocations::getInstance()->getPromotedVocation(vocationId); if(promotedVocation != -1) vocationMap[promotedVocation] = true; } else { errorStr = "Wrong vocation name: " + strValue; return false; } } else if(readXMLString(vocationNode, "id", strValue)) { IntegerVec intVector; if(!parseIntegerVec(strValue, intVector)) { errorStr = "Invalid vocation id - '" + strValue + "'"; return false; } size_t size = intVector.size(); for(size_t i = 0; i < size; ++i) { Vocation* vocation = Vocations::getInstance()->getVocation(intVector[i]); if(vocation && vocation->getName() != "") { vocationId = vocation->getId(); strValue = vocation->getName(); vocationMap[vocationId] = true; int32_t promotedVocation = Vocations::getInstance()->getPromotedVocation(vocationId); if(promotedVocation != -1) vocationMap[promotedVocation] = true; } else { std::stringstream ss; ss << "Wrong vocation id: " << intVector[i]; errorStr = ss.str(); return false; } } } if(vocationId != -1 && (!readXMLString(vocationNode, "showInDescription", tmpStrValue) || booleanString(tmpStrValue))) vocStringVec.push_back(asLowerCaseString(strValue)); return true; }
bool Houses::loadFromXml(std::string filename) { xmlDocPtr doc = xmlParseFile(filename.c_str()); if(!doc) { std::cout << "[Warning - Houses::loadFromXml] Cannot load houses file." << std::endl; std::cout << getLastXMLError() << std::endl; return false; } xmlNodePtr houseNode, root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name,(const xmlChar*)"houses")) { std::cout << "[Error - Houses::loadFromXml] Malformed houses file." << std::endl; xmlFreeDoc(doc); return false; } int32_t intValue; std::string strValue; houseNode = root->children; while(houseNode) { if(xmlStrcmp(houseNode->name,(const xmlChar*)"house")) { houseNode = houseNode->next; continue; } int32_t houseId = 0; if(!readXMLInteger(houseNode, "houseid", houseId)) { std::cout << "[Error - Houses::loadFromXml] Could not read houseId" << std::endl; xmlFreeDoc(doc); return false; } House* house = Houses::getInstance()->getHouse(houseId); if(!house) { std::cout << "[Error - Houses::loadFromXml] Unknown house with id: " << houseId << std::endl; xmlFreeDoc(doc); return false; } Position entry(0, 0, 0); if(readXMLInteger(houseNode, "entryx", intValue)) entry.x = intValue; if(readXMLInteger(houseNode, "entryy", intValue)) entry.y = intValue; if(readXMLInteger(houseNode, "entryz", intValue)) entry.z = intValue; house->setEntry(entry); if(!entry.x || !entry.y) { std::cout << "[Warning - Houses::loadFromXml] House entry not set for: "; std::cout << house->getName() << " (" << houseId << ")" << std::endl; } if(readXMLString(houseNode, "name", strValue)) house->setName(strValue); else house->resetSyncFlag(House::HOUSE_SYNC_NAME); if(readXMLInteger(houseNode, "townid", intValue)) house->setTownId(intValue); else house->resetSyncFlag(House::HOUSE_SYNC_TOWN); if(readXMLInteger(houseNode, "size", intValue)) house->setSize(intValue); else house->resetSyncFlag(House::HOUSE_SYNC_SIZE); if(readXMLString(houseNode, "guildhall", strValue)) house->setGuild(booleanString(strValue)); else house->resetSyncFlag(House::HOUSE_SYNC_GUILD); uint32_t rent = 0; if(readXMLInteger(houseNode, "rent", intValue)) rent = intValue; uint32_t price = house->getTilesCount() * g_config.getNumber(ConfigManager::HOUSE_PRICE); if(g_config.getBool(ConfigManager::HOUSE_RENTASPRICE)) { uint32_t tmp = rent; if(!tmp) tmp = price; house->setPrice(tmp); } else house->setPrice(price); if(g_config.getBool(ConfigManager::HOUSE_PRICEASRENT)) house->setRent(price); else house->setRent(rent); house->setOwner(0); houseNode = houseNode->next; } xmlFreeDoc(doc); return true; }
bool ScriptManager::loadFromXml(const std::string& file, bool& enabled) { enabled = false; xmlDocPtr doc = xmlParseFile(getFilePath(FILE_TYPE_MOD, file).c_str()); if(!doc) { std::clog << "[Error - ScriptManager::loadFromXml] Cannot load mod " << file << std::endl; std::clog << getLastXMLError() << std::endl; return false; } int32_t intValue; std::string strValue; xmlNodePtr p, root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name,(const xmlChar*)"mod")) { std::clog << "[Error - ScriptManager::loadFromXml] Malformed mod " << file << std::endl; std::clog << getLastXMLError() << std::endl; xmlFreeDoc(doc); return false; } if(!readXMLString(root, "name", strValue)) strValue = file; ModBlock mod; mod.enabled = true; mod.name = strValue; if(readXMLString(root, "enabled", strValue) && !booleanString(strValue)) mod.enabled = false; mod.file = file; if(readXMLString(root, "author", strValue)) mod.author = strValue; if(readXMLString(root, "version", strValue)) mod.version = strValue; if(readXMLString(root, "contact", strValue)) mod.contact = strValue; bool supported = true; for(p = root->children; p; p = p->next) { if(xmlStrcmp(p->name, (const xmlChar*)"server")) continue; supported = false; for(xmlNodePtr versionNode = p->children; versionNode; versionNode = versionNode->next) { std::string id = SOFTWARE_VERSION; if(readXMLString(versionNode, "id", strValue)) id = asLowerCaseString(strValue); IntegerVec protocol; protocol.push_back(CLIENT_VERSION_MIN); if(readXMLString(versionNode, "protocol", strValue)) protocol = vectorAtoi(explodeString(strValue, "-")); int16_t database = VERSION_DATABASE; if(readXMLInteger(versionNode, "database", intValue)) database = intValue; if(id == asLowerCaseString(SOFTWARE_VERSION) && database >= VERSION_DATABASE && protocol[0] >= CLIENT_VERSION_MIN && (protocol.size() < 2 || protocol[1] <= CLIENT_VERSION_MAX)) { supported = true; break; } } } if(!supported) { std::clog << "[Warning - ScriptManager::loadFromXml] Your server is not supported by mod " << file << std::endl; xmlFreeDoc(doc); return false; } if(mod.enabled) { std::string scriptsPath = getFilePath(FILE_TYPE_MOD, "scripts/"); for(p = root->children; p; p = p->next) { if(!xmlStrcmp(p->name, (const xmlChar*)"quest")) Quests::getInstance()->parseQuestNode(p, modsLoaded); else if(!xmlStrcmp(p->name, (const xmlChar*)"outfit")) Outfits::getInstance()->parseOutfitNode(p); else if(!xmlStrcmp(p->name, (const xmlChar*)"vocation")) Vocations::getInstance()->parseVocationNode(p); //duplicates checking is dangerous, shouldn't be performed until we find some good solution else if(!xmlStrcmp(p->name, (const xmlChar*)"group")) Groups::getInstance()->parseGroupNode(p); //duplicates checking is dangerous, shouldn't be performed until we find some good solution else if(!xmlStrcmp(p->name, (const xmlChar*)"raid")) Raids::getInstance()->parseRaidNode(p, modsLoaded, FILE_TYPE_MOD); //TODO: support mods path else if(!xmlStrcmp(p->name, (const xmlChar*)"spawn")) Spawns::getInstance()->parseSpawnNode(p, modsLoaded); else if(!xmlStrcmp(p->name, (const xmlChar*)"channel")) g_chat.parseChannelNode(p); //TODO: duplicates- channel destructor needs to send closeChannel to users! else if(!xmlStrcmp(p->name, (const xmlChar*)"npc")) g_npcs.parseNpcNode(p, FILE_TYPE_MOD); else if(!xmlStrcmp(p->name, (const xmlChar*)"monster")) { std::string path, name; if((readXMLString(p, "file", path) || readXMLString(p, "path", path)) && readXMLString(p, "name", name)) g_monsters.loadMonster(getFilePath(FILE_TYPE_MOD, "monster/" + path), name, true); } else if(!xmlStrcmp(p->name, (const xmlChar*)"item")) { if(readXMLInteger(p, "id", intValue)) Item::items.parseItemNode(p, intValue); } if(!xmlStrcmp(p->name, (const xmlChar*)"description") || !xmlStrcmp(p->name, (const xmlChar*)"info")) { if(parseXMLContentString(p->children, strValue)) { replaceString(strValue, "\t", ""); mod.description = strValue; } } else if(!xmlStrcmp(p->name, (const xmlChar*)"lib") || !xmlStrcmp(p->name, (const xmlChar*)"config")) { if(!readXMLString(p, "name", strValue)) { if(!xmlStrcmp(p->name, (const xmlChar*)"lib")) strValue = mod.name + "-lib"; else if(!xmlStrcmp(p->name, (const xmlChar*)"config")) strValue = mod.name + "-config"; } else toLowerCaseString(strValue); std::string strLib; if(parseXMLContentString(p->children, strLib)) { LibMap::iterator it = libMap.find(strValue); if(it == libMap.end()) { LibBlock lb; lb.first = file; lb.second = strLib; libMap[strValue] = lb; } else std::clog << "[Warning - ScriptManager::loadFromXml] Duplicated lib in mod " << strValue << ", previously declared in " << it->second.first << std::endl; } } else if(!g_actions->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_talkActions->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_moveEvents->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_creatureEvents->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_globalEvents->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_spells->parseEventNode(p, scriptsPath, modsLoaded)) g_weapons->parseEventNode(p, scriptsPath, modsLoaded); } } } } } } } enabled = mod.enabled; modMap[mod.name] = mod; xmlFreeDoc(doc); return true; }
bool ScriptingManager::loadFromXml(const std::string& file, bool& enabled) { enabled = false; std::string modPath = getFilePath(FILE_TYPE_MOD, file); xmlDocPtr doc = xmlParseFile(modPath.c_str()); if(!doc) { std::cout << "[Error - ScriptingManager::loadFromXml] Cannot load mod " << modPath << std::endl; std::cout << getLastXMLError() << std::endl; return false; } int32_t intValue; std::string strValue; xmlNodePtr p, root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name,(const xmlChar*)"mod")) { std::cout << "[Error - ScriptingManager::loadFromXml] Malformed mod " << modPath << std::endl; std::cout << getLastXMLError() << std::endl; xmlFreeDoc(doc); return false; } if(!readXMLString(root, "name", strValue)) { std::cout << "[Warning - ScriptingManager::loadFromXml] Empty name in mod " << modPath << std::endl; xmlFreeDoc(doc); return false; } ModBlock mod; mod.enabled = false; if(readXMLString(root, "enabled", strValue) && booleanString(strValue)) mod.enabled = true; mod.file = file; mod.name = strValue; if(readXMLString(root, "author", strValue)) mod.author = strValue; if(readXMLString(root, "version", strValue)) mod.version = strValue; if(readXMLString(root, "contact", strValue)) mod.contact = strValue; if(mod.enabled) { std::string scriptsPath = getFilePath(FILE_TYPE_MOD, "scripts/"); p = root->children; while(p) { if(!xmlStrcmp(p->name, (const xmlChar*)"quest")) Quests::getInstance()->parseQuestNode(p, modsLoaded); else if(!xmlStrcmp(p->name, (const xmlChar*)"outfit")) Outfits::getInstance()->parseOutfitNode(p); else if(!xmlStrcmp(p->name, (const xmlChar*)"vocation")) Vocations::getInstance()->parseVocationNode(p); //duplicates checking is dangerous, shouldn't be performed else if(!xmlStrcmp(p->name, (const xmlChar*)"group")) Groups::getInstance()->parseGroupNode(p); //duplicates checking is dangerous, shouldn't be performed else if(!xmlStrcmp(p->name, (const xmlChar*)"raid")) Raids::getInstance()->parseRaidNode(p, modsLoaded, FILE_TYPE_MOD); else if(!xmlStrcmp(p->name, (const xmlChar*)"spawn")) Spawns::getInstance()->parseSpawnNode(p, modsLoaded); else if(!xmlStrcmp(p->name, (const xmlChar*)"channel")) g_chat.parseChannelNode(p); //TODO: duplicates (channel destructor needs sending self close to users) else if(!xmlStrcmp(p->name, (const xmlChar*)"monster")) { std::string file, name; if(readXMLString(p, "file", file) && readXMLString(p, "name", name)) { file = getFilePath(FILE_TYPE_MOD, "monster/" + file); g_monsters.loadMonster(file, name, true); } } else if(!xmlStrcmp(p->name, (const xmlChar*)"item")) { if(readXMLInteger(p, "id", intValue)) Item::items.parseItemNode(p, intValue); //duplicates checking isn't necessary here } if(!xmlStrcmp(p->name, (const xmlChar*)"description") || !xmlStrcmp(p->name, (const xmlChar*)"info")) { if(parseXMLContentString(p->children, strValue)) { replaceString(strValue, "\t", ""); mod.description = strValue; } } else if(!xmlStrcmp(p->name, (const xmlChar*)"lib") || !xmlStrcmp(p->name, (const xmlChar*)"config")) { if(!readXMLString(p, "name", strValue)) { std::cout << "[Warning - ScriptingManager::loadFromXml] Lib without name in mod " << strValue << std::endl; p = p->next; continue; } toLowerCaseString(strValue); std::string strLib; if(parseXMLContentString(p->children, strLib)) { LibMap::iterator it = libMap.find(strValue); if(it == libMap.end()) { LibBlock lb; lb.first = file; lb.second = strLib; libMap[strValue] = lb; } else std::cout << "[Warning - ScriptingManager::loadFromXml] Duplicated lib in mod " << strValue << ", previously declared in " << it->second.first << std::endl; } } else if(!g_actions->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_talkActions->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_moveEvents->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_creatureEvents->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_globalEvents->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_spells->parseEventNode(p, scriptsPath, modsLoaded)) g_weapons->parseEventNode(p, scriptsPath, modsLoaded); } } } } } p = p->next; } } enabled = mod.enabled; modMap[mod.name] = mod; xmlFreeDoc(doc); return true; }
bool ConfigManager::load() { lua_State* L = luaL_newstate(); if (!L) { throw std::runtime_error("Failed to allocate memory"); } if (luaL_dofile(L, "config.lua")) { std::cout << "[Error - ConfigManager::load] " << lua_tostring(L, -1) << std::endl; lua_close(L); return false; } //parse config if (!m_isLoaded) { //info that must be loaded one time (unless we reset the modules involved) m_confBoolean[SERVERSAVE_ENABLED] = booleanString(getGlobalString(L, "serverSaveEnabled", "yes")); m_confBoolean[SAVE_GLOBAL_STORAGE] = booleanString(getGlobalString(L, "saveGlobalStorage", "no")); m_confBoolean[BIND_ONLY_GLOBAL_ADDRESS] = booleanString(getGlobalString(L, "bindOnlyGlobalAddress", "no")); m_confBoolean[OPTIMIZE_DATABASE] = booleanString(getGlobalString(L, "startupDatabaseOptimization", "yes")); m_confString[IP] = getGlobalString(L, "ip", "127.0.0.1"); m_confString[MAP_NAME] = getGlobalString(L, "mapName", "forgotten"); m_confString[MAP_AUTHOR] = getGlobalString(L, "mapAuthor", "Unknown"); m_confString[HOUSE_RENT_PERIOD] = getGlobalString(L, "houseRentPeriod", "monthly"); m_confString[MYSQL_HOST] = getGlobalString(L, "mysqlHost", "localhost"); m_confString[MYSQL_USER] = getGlobalString(L, "mysqlUser", "root"); m_confString[MYSQL_PASS] = getGlobalString(L, "mysqlPass", ""); m_confString[MYSQL_DB] = getGlobalString(L, "mysqlDatabase", "theforgottenserver"); m_confString[PASSWORDTYPE] = getGlobalString(L, "passwordType", "plain"); m_confInteger[SQL_PORT] = getGlobalNumber(L, "mysqlPort", 3306); m_confInteger[PASSWORD_TYPE] = PASSWORD_TYPE_PLAIN; m_confInteger[SERVERSAVE_H] = getGlobalNumber(L, "serverSaveHour", 3); m_confInteger[ADMIN_PORT] = getGlobalNumber(L, "adminProtocolPort", 7171); m_confInteger[GAME_PORT] = getGlobalNumber(L, "gameProtocolPort", 7172); m_confInteger[LOGIN_PORT] = getGlobalNumber(L, "loginProtocolPort", 7171); m_confInteger[STATUS_PORT] = getGlobalNumber(L, "statusProtocolPort", 7171); m_confInteger[MARKET_OFFER_DURATION] = getGlobalNumber(L, "marketOfferDuration", 30 * 24 * 60 * 60); } m_confBoolean[ALLOW_CHANGEOUTFIT] = booleanString(getGlobalString(L, "allowChangeOutfit", "yes")); m_confBoolean[ONE_PLAYER_ON_ACCOUNT] = booleanString(getGlobalString(L, "onePlayerOnlinePerAccount", "yes")); m_confBoolean[CANNOT_ATTACK_SAME_LOOKFEET] = booleanString(getGlobalString(L, "noDamageToSameLookfeet", "no")); m_confBoolean[AIMBOT_HOTKEY_ENABLED] = booleanString(getGlobalString(L, "hotkeyAimbotEnabled", "yes")); m_confBoolean[REMOVE_AMMO] = booleanString(getGlobalString(L, "removeAmmoWhenUsingDistanceWeapon", "yes")); m_confBoolean[REMOVE_RUNE_CHARGES] = booleanString(getGlobalString(L, "removeChargesFromRunes", "yes")); m_confBoolean[REMOVE_WEAPON_CHARGES] = booleanString(getGlobalString(L, "removeChargesFromWeapons", "yes")); m_confBoolean[EXPERIENCE_FROM_PLAYERS] = booleanString(getGlobalString(L, "experienceByKillingPlayers", "no")); m_confBoolean[SHUTDOWN_AT_SERVERSAVE] = booleanString(getGlobalString(L, "shutdownAtServerSave", "no")); m_confBoolean[CLEAN_MAP_AT_SERVERSAVE] = booleanString(getGlobalString(L, "cleanMapAtServerSave", "yes")); m_confBoolean[FREE_PREMIUM] = booleanString(getGlobalString(L, "freePremium", "no")); m_confBoolean[ADMIN_LOGS_ENABLED] = booleanString(getGlobalString(L, "adminLogsEnabled", "no")); m_confBoolean[REPLACE_KICK_ON_LOGIN] = booleanString(getGlobalString(L, "replaceKickOnLogin", "yes")); m_confBoolean[ALLOW_CLONES] = booleanString(getGlobalString(L, "allowClones", "no")); m_confBoolean[MARKET_PREMIUM] = booleanString(getGlobalString(L, "premiumToCreateMarketOffer", "yes")); m_confBoolean[STAMINA_SYSTEM] = booleanString(getGlobalString(L, "staminaSystem", "yes")); m_confString[DEFAULT_PRIORITY] = getGlobalString(L, "defaultPriority", "high"); m_confString[LOGIN_MSG] = getGlobalString(L, "loginMessage", "Welcome to the Forgotten Server!"); m_confString[SERVER_NAME] = getGlobalString(L, "serverName"); m_confString[OWNER_NAME] = getGlobalString(L, "ownerName"); m_confString[OWNER_EMAIL] = getGlobalString(L, "ownerEmail"); m_confString[URL] = getGlobalString(L, "url"); m_confString[LOCATION] = getGlobalString(L, "location"); m_confString[MOTD] = getGlobalString(L, "motd"); m_confString[WORLD_TYPE] = getGlobalString(L, "worldType", "pvp"); m_confInteger[MAX_PLAYERS] = getGlobalNumber(L, "maxPlayers"); m_confInteger[PZ_LOCKED] = getGlobalNumber(L, "pzLocked", 0); m_confInteger[DEFAULT_DESPAWNRANGE] = getGlobalNumber(L, "deSpawnRange", 2); m_confInteger[DEFAULT_DESPAWNRADIUS] = getGlobalNumber(L, "deSpawnRadius", 50); m_confInteger[RATE_EXPERIENCE] = getGlobalNumber(L, "rateExp", 1); m_confInteger[RATE_SKILL] = getGlobalNumber(L, "rateSkill", 1); m_confInteger[RATE_LOOT] = getGlobalNumber(L, "rateLoot", 1); m_confInteger[RATE_MAGIC] = getGlobalNumber(L, "rateMagic", 1); m_confInteger[RATE_SPAWN] = getGlobalNumber(L, "rateSpawn", 1); m_confInteger[HOUSE_PRICE] = getGlobalNumber(L, "housePriceEachSQM", 1000); m_confInteger[KILLS_TO_RED] = getGlobalNumber(L, "killsToRedSkull", 3); m_confInteger[KILLS_TO_BLACK] = getGlobalNumber(L, "killsToBlackSkull", 6); m_confInteger[ACTIONS_DELAY_INTERVAL] = getGlobalNumber(L, "timeBetweenActions", 200); m_confInteger[EX_ACTIONS_DELAY_INTERVAL] = getGlobalNumber(L, "timeBetweenExActions", 1000); m_confInteger[MAX_MESSAGEBUFFER] = getGlobalNumber(L, "maxMessageBuffer", 4); m_confInteger[CRITICAL_HIT_CHANCE] = getGlobalNumber(L, "criticalHitChance", 5); m_confInteger[KICK_AFTER_MINUTES] = getGlobalNumber(L, "kickIdlePlayerAfterMinutes", 15); m_confInteger[PROTECTION_LEVEL] = getGlobalNumber(L, "protectionLevel", 1); m_confInteger[DEATH_LOSE_PERCENT] = getGlobalNumber(L, "deathLosePercent", -1); m_confInteger[STATUSQUERY_TIMEOUT] = getGlobalNumber(L, "statusTimeout", 60000); m_confInteger[FRAG_TIME] = getGlobalNumber(L, "timeToDecreaseFrags", 24 * 60 * 60 * 1000); m_confInteger[WHITE_SKULL_TIME] = getGlobalNumber(L, "whiteSkullTime", 15 * 60 * 1000); m_confInteger[AUTO_SAVE_EACH_MINUTES] = getGlobalNumber(L, "autoSaveEachMinutes", 0); m_confInteger[STAIRHOP_DELAY] = getGlobalNumber(L, "stairJumpExhaustion", 2000); m_confInteger[EXP_FROM_PLAYERS_LEVEL_RANGE] = getGlobalNumber(L, "expFromPlayersLevelRange", 75); m_confInteger[CHECK_EXPIRED_MARKET_OFFERS_EACH_MINUTES] = getGlobalNumber(L, "checkExpiredMarketOffersEachMinutes", 60); m_confInteger[MAX_MARKET_OFFERS_AT_A_TIME_PER_PLAYER] = getGlobalNumber(L, "maxMarketOffersAtATimePerPlayer", 100); m_confInteger[MAX_PACKETS_PER_SECOND] = getGlobalNumber(L, "maxPacketsPerSecond", 40); m_isLoaded = true; lua_close(L); return true; }
void Items::parseItemNode(const pugi::xml_node& itemNode, uint32_t id) { if (id > 30000 && id < 30100) { id -= 30000; if (id >= items.size()) { items.resize(id + 1); } ItemType& iType = items[id]; iType.id = id; } ItemType& it = getItemType(id); if (it.id == 0) { return; } it.name = itemNode.attribute("name").as_string(); pugi::xml_attribute articleAttribute = itemNode.attribute("article"); if (articleAttribute) { it.article = articleAttribute.as_string(); } pugi::xml_attribute pluralAttribute = itemNode.attribute("plural"); if (pluralAttribute) { it.pluralName = pluralAttribute.as_string(); } for (pugi::xml_node attributeNode = itemNode.first_child(); attributeNode; attributeNode = attributeNode.next_sibling()) { pugi::xml_attribute keyAttribute = attributeNode.attribute("key"); if (!keyAttribute) { continue; } pugi::xml_attribute valueAttribute = attributeNode.attribute("value"); if (!valueAttribute) { continue; } std::string tmpStrValue = asLowerCaseString(keyAttribute.as_string()); if (tmpStrValue == "type") { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "key") { it.type = ITEM_TYPE_KEY; } else if (tmpStrValue == "magicfield") { it.type = ITEM_TYPE_MAGICFIELD; } else if (tmpStrValue == "container") { it.group = ITEM_GROUP_CONTAINER; it.type = ITEM_TYPE_CONTAINER; } else if (tmpStrValue == "depot") { it.type = ITEM_TYPE_DEPOT; } else if (tmpStrValue == "mailbox") { it.type = ITEM_TYPE_MAILBOX; } else if (tmpStrValue == "trashholder") { it.type = ITEM_TYPE_TRASHHOLDER; } else if (tmpStrValue == "teleport") { it.type = ITEM_TYPE_TELEPORT; } else if (tmpStrValue == "door") { it.type = ITEM_TYPE_DOOR; } else if (tmpStrValue == "bed") { it.type = ITEM_TYPE_BED; } else if (tmpStrValue == "rune") { it.type = ITEM_TYPE_RUNE; } else { std::cout << "[Warning - Items::parseItemNode] Unknown type: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "description") { it.description = valueAttribute.as_string(); } else if (tmpStrValue == "runespellname") { it.runeSpellName = valueAttribute.as_string(); } else if (tmpStrValue == "weight") { it.weight = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "showcount") { it.showCount = valueAttribute.as_bool(); } else if (tmpStrValue == "armor") { it.armor = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "defense") { it.defense = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "extradef") { it.extraDefense = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "attack") { it.attack = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "rotateto") { it.rotateTo = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "moveable" || tmpStrValue == "movable") { it.moveable = valueAttribute.as_bool(); } else if (tmpStrValue == "blockprojectile") { it.blockProjectile = valueAttribute.as_bool(); } else if (tmpStrValue == "allowpickupable" || tmpStrValue == "pickupable") { it.allowPickupable = valueAttribute.as_bool(); } else if (tmpStrValue == "floorchange") { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "down") { it.floorChangeDown = true; } else if (tmpStrValue == "north") { it.floorChangeNorth = true; } else if (tmpStrValue == "south") { it.floorChangeSouth = true; } else if (tmpStrValue == "southalt" || tmpStrValue == "southex") { it.floorChangeSouthAlt = true; } else if (tmpStrValue == "west") { it.floorChangeWest = true; } else if (tmpStrValue == "east") { it.floorChangeEast = true; } else if (tmpStrValue == "eastalt" || tmpStrValue == "eastex") { it.floorChangeEastAlt = true; } else { std::cout << "[Warning - Items::parseItemNode] Unknown floorChange: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "corpsetype") { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "venom") { it.corpseType = RACE_VENOM; } else if (tmpStrValue == "blood") { it.corpseType = RACE_BLOOD; } else if (tmpStrValue == "undead") { it.corpseType = RACE_UNDEAD; } else if (tmpStrValue == "fire") { it.corpseType = RACE_FIRE; } else if (tmpStrValue == "energy") { it.corpseType = RACE_ENERGY; } else { std::cout << "[Warning - Items::parseItemNode] Unknown corpseType: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "containersize") { it.maxItems = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "fluidsource") { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "water") { it.fluidSource = FLUID_WATER; } else if (tmpStrValue == "blood") { it.fluidSource = FLUID_BLOOD; } else if (tmpStrValue == "beer") { it.fluidSource = FLUID_BEER; } else if (tmpStrValue == "slime") { it.fluidSource = FLUID_SLIME; } else if (tmpStrValue == "lemonade") { it.fluidSource = FLUID_LEMONADE; } else if (tmpStrValue == "milk") { it.fluidSource = FLUID_MILK; } else if (tmpStrValue == "mana") { it.fluidSource = FLUID_MANA; } else if (tmpStrValue == "life") { it.fluidSource = FLUID_LIFE; } else if (tmpStrValue == "oil") { it.fluidSource = FLUID_OIL; } else if (tmpStrValue == "urine") { it.fluidSource = FLUID_URINE; } else if (tmpStrValue == "coconut") { it.fluidSource = FLUID_COCONUTMILK; } else if (tmpStrValue == "wine") { it.fluidSource = FLUID_WINE; } else if (tmpStrValue == "mud") { it.fluidSource = FLUID_MUD; } else if (tmpStrValue == "fruitjuice") { it.fluidSource = FLUID_FRUITJUICE; } else if (tmpStrValue == "lava") { it.fluidSource = FLUID_LAVA; } else if (tmpStrValue == "rum") { it.fluidSource = FLUID_RUM; } else if (tmpStrValue == "swamp") { it.fluidSource = FLUID_SWAMP; } else if (tmpStrValue == "tea") { it.fluidSource = FLUID_TEA; } else if (tmpStrValue == "mead") { it.fluidSource = FLUID_MEAD; } else { std::cout << "[Warning - Items::parseItemNode] Unknown fluidSource: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "readable") { it.canReadText = valueAttribute.as_bool(); } else if (tmpStrValue == "writeable") { it.canWriteText = valueAttribute.as_bool(); it.canReadText = it.canWriteText; } else if (tmpStrValue == "maxtextlen") { it.maxTextLen = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "writeonceitemid") { it.writeOnceItemId = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "weapontype") { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "sword") { it.weaponType = WEAPON_SWORD; } else if (tmpStrValue == "club") { it.weaponType = WEAPON_CLUB; } else if (tmpStrValue == "axe") { it.weaponType = WEAPON_AXE; } else if (tmpStrValue == "shield") { it.weaponType = WEAPON_SHIELD; } else if (tmpStrValue == "distance") { it.weaponType = WEAPON_DISTANCE; } else if (tmpStrValue == "wand") { it.weaponType = WEAPON_WAND; } else if (tmpStrValue == "ammunition") { it.weaponType = WEAPON_AMMO; } else { std::cout << "[Warning - Items::parseItemNode] Unknown weaponType: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "slottype") { tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "head") { it.slotPosition |= SLOTP_HEAD; } else if (tmpStrValue == "body") { it.slotPosition |= SLOTP_ARMOR; } else if (tmpStrValue == "legs") { it.slotPosition |= SLOTP_LEGS; } else if (tmpStrValue == "feet") { it.slotPosition |= SLOTP_FEET; } else if (tmpStrValue == "backpack") { it.slotPosition |= SLOTP_BACKPACK; } else if (tmpStrValue == "two-handed") { it.slotPosition |= SLOTP_TWO_HAND; } else if (tmpStrValue == "right-hand") { it.slotPosition &= ~SLOTP_LEFT; } else if (tmpStrValue == "left-hand") { it.slotPosition &= ~SLOTP_RIGHT; } else if (tmpStrValue == "necklace") { it.slotPosition |= SLOTP_NECKLACE; } else if (tmpStrValue == "ring") { it.slotPosition |= SLOTP_RING; } else if (tmpStrValue == "ammo") { it.slotPosition |= SLOTP_AMMO; } else if (tmpStrValue == "hand") { it.slotPosition |= SLOTP_HAND; } else { std::cout << "[Warning - Items::parseItemNode] Unknown slotType: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "ammotype") { it.ammoType = getAmmoType(valueAttribute.as_string()); if (it.ammoType == AMMO_NONE) { std::cout << "[Warning - Items::parseItemNode] Unknown ammoType: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "shoottype") { ShootType_t shoot = getShootType(valueAttribute.as_string()); if (shoot != CONST_ANI_NONE) { it.shootType = shoot; } else { std::cout << "[Warning - Items::parseItemNode] Unknown shootType: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "effect") { MagicEffectClasses effect = getMagicEffect(valueAttribute.as_string()); if (effect != CONST_ME_NONE) { it.magicEffect = effect; } else { std::cout << "[Warning - Items::parseItemNode] Unknown effect: " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "range") { it.shootRange = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "stopduration") { it.stopTime = valueAttribute.as_bool(); } else if (tmpStrValue == "decayto") { it.decayTo = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "transformequipto") { it.transformEquipTo = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "transformdeequipto") { it.transformDeEquipTo = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "duration") { it.decayTime = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "showduration") { it.showDuration = valueAttribute.as_bool(); } else if (tmpStrValue == "charges") { it.charges = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "showcharges") { it.showCharges = valueAttribute.as_bool(); } else if (tmpStrValue == "showattributes") { it.showAttributes = valueAttribute.as_bool(); } else if (tmpStrValue == "breakchance") { it.breakChance = std::min<uint32_t>(100, pugi::cast<uint32_t>(valueAttribute.value())); } else if (tmpStrValue == "ammoaction") { it.ammoAction = getAmmoAction(valueAttribute.as_string()); if (it.ammoAction == AMMOACTION_NONE) { std::cout << "[Warning - Items::parseItemNode] Unknown ammoAction " << valueAttribute.as_string() << std::endl; } } else if (tmpStrValue == "hitchance") { it.hitChance = std::min<int8_t>(100, std::max<int8_t>(-100, pugi::cast<int16_t>(valueAttribute.value()))); } else if (tmpStrValue == "maxhitchance") { it.maxHitChance = std::min<uint32_t>(100, pugi::cast<uint32_t>(valueAttribute.value())); } else if (tmpStrValue == "invisible") { it.getAbilities()->invisible = valueAttribute.as_bool(); } else if (tmpStrValue == "speed") { it.getAbilities()->speed = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "healthgain") { Abilities* abilities = it.getAbilities(); abilities->regeneration = true; abilities->healthGain = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "healthticks") { Abilities* abilities = it.getAbilities(); abilities->regeneration = true; abilities->healthTicks = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "managain") { Abilities* abilities = it.getAbilities(); abilities->regeneration = true; abilities->manaGain = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "manaticks") { Abilities* abilities = it.getAbilities(); abilities->regeneration = true; abilities->manaTicks = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "manashield") { it.getAbilities()->manaShield = valueAttribute.as_bool(); } else if (tmpStrValue == "skillsword") { it.getAbilities()->skills[SKILL_SWORD] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "skillaxe") { it.getAbilities()->skills[SKILL_AXE] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "skillclub") { it.getAbilities()->skills[SKILL_CLUB] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "skilldist") { it.getAbilities()->skills[SKILL_DISTANCE] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "skillfish") { it.getAbilities()->skills[SKILL_FISHING] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "skillshield") { it.getAbilities()->skills[SKILL_SHIELD] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "skillfist") { it.getAbilities()->skills[SKILL_FIST] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "maxhitpoints") { it.getAbilities()->stats[STAT_MAXHITPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "maxhitpointspercent") { it.getAbilities()->statsPercent[STAT_MAXHITPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "maxmanapoints") { it.getAbilities()->stats[STAT_MAXMANAPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "maxmanapointspercent") { it.getAbilities()->statsPercent[STAT_MAXMANAPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "soulpoints") { it.getAbilities()->stats[STAT_SOULPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "soulpointspercent") { it.getAbilities()->statsPercent[STAT_SOULPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "magicpoints" || tmpStrValue == "magiclevelpoints") { it.getAbilities()->stats[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "magicpointspercent") { it.getAbilities()->statsPercent[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value()); } else if (tmpStrValue == "fieldabsorbpercentenergy") { it.getAbilities()->fieldAbsorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "fieldabsorbpercentfire") { it.getAbilities()->fieldAbsorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "fieldabsorbpercentpoison" || tmpStrValue == "fieldabsorpercentearth") { it.getAbilities()->fieldAbsorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentall" || tmpStrValue == "absorbpercentallelements") { int16_t value = pugi::cast<int16_t>(valueAttribute.value()); Abilities* abilities = it.getAbilities(); for (uint32_t i = COMBAT_FIRST; i <= COMBAT_COUNT; i++) { abilities->absorbPercent[i] += value; } } else if (tmpStrValue == "absorbpercentelements") { int16_t value = pugi::cast<int16_t>(valueAttribute.value()); Abilities* abilities = it.getAbilities(); abilities->absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value; abilities->absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value; abilities->absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value; abilities->absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value; } else if (tmpStrValue == "absorbpercentmagic") { int16_t value = pugi::cast<int16_t>(valueAttribute.value()); Abilities* abilities = it.getAbilities(); abilities->absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value; abilities->absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value; abilities->absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value; abilities->absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value; abilities->absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += value; abilities->absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += value; } else if (tmpStrValue == "absorbpercentenergy") { it.getAbilities()->absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentfire") { it.getAbilities()->absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentpoison" || tmpStrValue == "absorbpercentearth") { it.getAbilities()->absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentice") { it.getAbilities()->absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentholy") { it.getAbilities()->absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentdeath") { it.getAbilities()->absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentlifedrain") { it.getAbilities()->absorbPercent[combatTypeToIndex(COMBAT_LIFEDRAIN)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentmanadrain") { it.getAbilities()->absorbPercent[combatTypeToIndex(COMBAT_MANADRAIN)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentdrown") { it.getAbilities()->absorbPercent[combatTypeToIndex(COMBAT_DROWNDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentphysical") { it.getAbilities()->absorbPercent[combatTypeToIndex(COMBAT_PHYSICALDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercenthealing") { it.getAbilities()->absorbPercent[combatTypeToIndex(COMBAT_HEALING)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "absorbpercentundefined") { it.getAbilities()->absorbPercent[combatTypeToIndex(COMBAT_UNDEFINEDDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value()); } else if (tmpStrValue == "suppressdrunk") { if (valueAttribute.as_bool()) { it.getAbilities()->conditionSuppressions |= CONDITION_DRUNK; } } else if (tmpStrValue == "suppressenergy") { if (valueAttribute.as_bool()) { it.getAbilities()->conditionSuppressions |= CONDITION_ENERGY; } } else if (tmpStrValue == "suppressfire") { if (valueAttribute.as_bool()) { it.getAbilities()->conditionSuppressions |= CONDITION_FIRE; } } else if (tmpStrValue == "suppresspoison") { if (valueAttribute.as_bool()) { it.getAbilities()->conditionSuppressions |= CONDITION_POISON; } } else if (tmpStrValue == "suppressdrown") { if (valueAttribute.as_bool()) { it.getAbilities()->conditionSuppressions |= CONDITION_DROWN; } } else if (tmpStrValue == "suppressphysical") { if (valueAttribute.as_bool()) { it.getAbilities()->conditionSuppressions |= CONDITION_BLEEDING; } } else if (tmpStrValue == "suppressfreeze") { if (valueAttribute.as_bool()) { it.getAbilities()->conditionSuppressions |= CONDITION_FREEZING; } } else if (tmpStrValue == "suppressdazzle") { if (valueAttribute.as_bool()) { it.getAbilities()->conditionSuppressions |= CONDITION_DAZZLED; } } else if (tmpStrValue == "suppresscurse") { if (valueAttribute.as_bool()) { it.getAbilities()->conditionSuppressions |= CONDITION_CURSED; } } else if (tmpStrValue == "field") { it.group = ITEM_GROUP_MAGICFIELD; it.type = ITEM_TYPE_MAGICFIELD; CombatType_t combatType = COMBAT_NONE; ConditionDamage* conditionDamage = nullptr; tmpStrValue = asLowerCaseString(valueAttribute.as_string()); if (tmpStrValue == "fire") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_FIRE); combatType = COMBAT_FIREDAMAGE; } else if (tmpStrValue == "energy") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_ENERGY); combatType = COMBAT_ENERGYDAMAGE; } else if (tmpStrValue == "poison") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_POISON); combatType = COMBAT_EARTHDAMAGE; } else if (tmpStrValue == "drown") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_DROWN); combatType = COMBAT_DROWNDAMAGE; } else if (tmpStrValue == "physical") { conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_BLEEDING); combatType = COMBAT_PHYSICALDAMAGE; } else { std::cout << "[Warning - Items::parseItemNode] Unknown field value: " << valueAttribute.as_string() << std::endl; } if (combatType != COMBAT_NONE) { it.combatType = combatType; it.condition = conditionDamage; uint32_t ticks = 0; int32_t damage = 0; int32_t start = 0; int32_t count = 1; for (pugi::xml_node subAttributeNode = attributeNode.first_child(); subAttributeNode; subAttributeNode = subAttributeNode.next_sibling()) { pugi::xml_attribute subKeyAttribute = subAttributeNode.attribute("key"); if (!subKeyAttribute) { continue; } pugi::xml_attribute subValueAttribute = subAttributeNode.attribute("value"); if (!subValueAttribute) { continue; } tmpStrValue = asLowerCaseString(subKeyAttribute.as_string()); if (tmpStrValue == "ticks") { ticks = pugi::cast<uint32_t>(subValueAttribute.value()); } else if (tmpStrValue == "count") { count = std::max<int32_t>(1, pugi::cast<int32_t>(subValueAttribute.value())); } else if (tmpStrValue == "start") { start = std::max<int32_t>(0, pugi::cast<int32_t>(subValueAttribute.value())); } else if (tmpStrValue == "damage") { damage = -pugi::cast<int32_t>(subValueAttribute.value()); if (start > 0) { std::list<int32_t> damageList; ConditionDamage::generateDamageList(damage, start, damageList); for (int32_t damageValue : damageList) { conditionDamage->addDamage(1, ticks, -damageValue); } start = 0; } else { conditionDamage->addDamage(count, ticks, damage); } } } conditionDamage->setParam(CONDITION_PARAM_FIELD, 1); if (conditionDamage->getTotalDamage() > 0) { conditionDamage->setParam(CONDITION_PARAM_FORCEUPDATE, 1); } } } else if (tmpStrValue == "replaceable") { it.replaceable = valueAttribute.as_bool(); } else if (tmpStrValue == "partnerdirection") { it.bedPartnerDir = getDirection(valueAttribute.as_string()); } else if (tmpStrValue == "leveldoor") { it.levelDoor = pugi::cast<uint32_t>(valueAttribute.value()); } else if (tmpStrValue == "maletransformto" || tmpStrValue == "malesleeper") { uint16_t value = pugi::cast<uint16_t>(valueAttribute.value()); it.transformToOnUse[PLAYERSEX_MALE] = value; ItemType& other = getItemType(value); if (other.transformToFree == 0) { other.transformToFree = it.id; } if (it.transformToOnUse[PLAYERSEX_FEMALE] == 0) { it.transformToOnUse[PLAYERSEX_FEMALE] = value; } } else if (tmpStrValue == "femaletransformto" || tmpStrValue == "femalesleeper") { uint16_t value = pugi::cast<uint16_t>(valueAttribute.value()); it.transformToOnUse[PLAYERSEX_FEMALE] = value; ItemType& other = getItemType(value); if (other.transformToFree == 0) { other.transformToFree = it.id; } if (it.transformToOnUse[PLAYERSEX_MALE] == 0) { it.transformToOnUse[PLAYERSEX_MALE] = value; } } else if (tmpStrValue == "transformto") { it.transformToFree = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "elementice") { Abilities* abilities = it.getAbilities(); abilities->elementDamage = pugi::cast<int16_t>(valueAttribute.value()); abilities->elementType = COMBAT_ICEDAMAGE; } else if (tmpStrValue == "elementearth") { Abilities* abilities = it.getAbilities(); abilities->elementDamage = pugi::cast<int16_t>(valueAttribute.value()); abilities->elementType = COMBAT_EARTHDAMAGE; } else if (tmpStrValue == "elementfire") { Abilities* abilities = it.getAbilities(); abilities->elementDamage = pugi::cast<int16_t>(valueAttribute.value()); abilities->elementType = COMBAT_FIREDAMAGE; } else if (tmpStrValue == "elementenergy") { Abilities* abilities = it.getAbilities(); abilities->elementDamage = pugi::cast<int16_t>(valueAttribute.value()); abilities->elementType = COMBAT_ENERGYDAMAGE; } else if (tmpStrValue == "walkstack") { it.walkStack = valueAttribute.as_bool(); } else if (tmpStrValue == "alwaysontop") { it.alwaysOnTop = booleanString(valueAttribute.as_string()); } else if (tmpStrValue == "toporder") { it.alwaysOnTopOrder = pugi::cast<uint16_t>(valueAttribute.value()); } else if (tmpStrValue == "blocking") { it.blockSolid = valueAttribute.as_bool(); } else if (tmpStrValue == "allowdistread") { it.allowDistRead = booleanString(valueAttribute.as_string()); } else { std::cout << "[Warning - Items::parseItemNode] Unknown key value: " << keyAttribute.as_string() << std::endl; } } //check bed items if ((it.transformToFree != 0 || it.transformToOnUse[PLAYERSEX_FEMALE] != 0 || it.transformToOnUse[PLAYERSEX_MALE] != 0) && it.type != ITEM_TYPE_BED) { std::cout << "[Warning - Items::parseItemNode] Item " << it.id << " is not set as a bed-type" << std::endl; } }
bool ConfigManager::loadFile(const std::string& _filename) { lua_State* L = lua_open(); if(!L) throw std::runtime_error("Failed to allocate memory"); if(luaL_dofile(L, _filename.c_str())) { std::cout << "[Error - ConfigManager::loadFile] With file = " << _filename << ", " << lua_tostring(L, -1) << std::endl; lua_close(L); return false; } //parse config if(!m_isLoaded) //info that must be loaded one time (unless we reset the modules involved) { m_confBoolean[SERVERSAVE_ENABLED] = booleanString(getGlobalString(L, "serverSaveEnabled", "yes")); m_confBoolean[SAVE_GLOBAL_STORAGE] = booleanString(getGlobalString(L, "saveGlobalStorage", "no")); m_confBoolean[INGAME_GUILD_SYSTEM] = booleanString(getGlobalString(L, "ingameGuildSystem", "yes")); m_confBoolean[BIND_ONLY_GLOBAL_ADDRESS] = booleanString(getGlobalString(L, "bindOnlyGlobalAddress", "no")); m_confBoolean[OPTIMIZE_DATABASE] = booleanString(getGlobalString(L, "startupDatabaseOptimization", "yes")); m_confString[CONFIG_FILE] = _filename; m_confString[IP] = getGlobalString(L, "ip", "127.0.0.1"); m_confString[MAP_NAME] = getGlobalString(L, "mapName", "forgotten"); m_confString[MAP_AUTHOR] = getGlobalString(L, "mapAuthor", "Unknown"); m_confString[HOUSE_RENT_PERIOD] = getGlobalString(L, "houseRentPeriod", "monthly"); m_confString[MYSQL_HOST] = getGlobalString(L, "mysqlHost", "localhost"); m_confString[MYSQL_USER] = getGlobalString(L, "mysqlUser", "root"); m_confString[MYSQL_PASS] = getGlobalString(L, "mysqlPass", ""); m_confString[MYSQL_DB] = getGlobalString(L, "mysqlDatabase", "theforgottenserver"); m_confString[SQLITE_DB] = getGlobalString(L, "sqliteDatabase"); m_confString[PASSWORDTYPE] = getGlobalString(L, "passwordType", "plain"); #ifdef MULTI_SQL_DRIVERS m_confString[SQL_TYPE] = getGlobalString(L, "sqlType", "sqlite"); #endif m_confInteger[SQL_PORT] = getGlobalNumber(L, "mysqlPort", 3306); m_confInteger[PASSWORD_TYPE] = PASSWORD_TYPE_PLAIN; m_confInteger[SERVERSAVE_H] = getGlobalNumber(L, "serverSaveHour", 3); m_confInteger[ADMIN_PORT] = getGlobalNumber(L, "adminProtocolPort", 7171); m_confInteger[GAME_PORT] = getGlobalNumber(L, "gameProtocolPort", 7172); m_confInteger[LOGIN_PORT] = getGlobalNumber(L, "loginProtocolPort", 7171); m_confInteger[STATUS_PORT] = getGlobalNumber(L, "statusProtocolPort", 7171); m_confInteger[MARKET_OFFER_DURATION] = getGlobalNumber(L, "marketOfferDuration", 30 * 24 * 60 * 60); } m_confBoolean[FREE_MEMORY_AT_SHUTDOWN] = booleanString(getGlobalString(L, "freeMemoryAtShutdown", "no")); m_confBoolean[ACCOUNT_MANAGER] = booleanString(getGlobalString(L, "accountManager", "yes")); m_confBoolean[ON_OR_OFF_CHARLIST] = booleanString(getGlobalString(L, "displayOnOrOffAtCharlist", "no")); m_confBoolean[ALLOW_CHANGEOUTFIT] = booleanString(getGlobalString(L, "allowChangeOutfit", "yes")); m_confBoolean[ONE_PLAYER_ON_ACCOUNT] = booleanString(getGlobalString(L, "onePlayerOnlinePerAccount", "yes")); m_confBoolean[CANNOT_ATTACK_SAME_LOOKFEET] = booleanString(getGlobalString(L, "noDamageToSameLookfeet", "no")); m_confBoolean[AIMBOT_HOTKEY_ENABLED] = booleanString(getGlobalString(L, "hotkeyAimbotEnabled", "yes")); m_confBoolean[START_CHOOSEVOC] = booleanString(getGlobalString(L, "newPlayerChooseVoc", "no")); m_confBoolean[SHOW_GAMEMASTERS_ONLINE] = booleanString(getGlobalString(L, "displayGamemastersWithOnlineCommand", "no")); m_confBoolean[REMOVE_AMMO] = booleanString(getGlobalString(L, "removeAmmoWhenUsingDistanceWeapon", "yes")); m_confBoolean[REMOVE_RUNE_CHARGES] = booleanString(getGlobalString(L, "removeChargesFromRunes", "yes")); m_confBoolean[REMOVE_WEAPON_CHARGES] = booleanString(getGlobalString(L, "removeChargesFromWeapons", "yes")); m_confBoolean[RANDOMIZE_TILES] = booleanString(getGlobalString(L, "randomizeTiles", "yes")); m_confBoolean[EXPERIENCE_FROM_PLAYERS] = booleanString(getGlobalString(L, "experienceByKillingPlayers", "no")); m_confBoolean[SHUTDOWN_AT_SERVERSAVE] = booleanString(getGlobalString(L, "shutdownAtServerSave", "no")); m_confBoolean[CLEAN_MAP_AT_SERVERSAVE] = booleanString(getGlobalString(L, "cleanMapAtServerSave", "yes")); m_confBoolean[FREE_PREMIUM] = booleanString(getGlobalString(L, "freePremium", "no")); m_confBoolean[ADMIN_LOGS_ENABLED] = booleanString(getGlobalString(L, "adminLogsEnabled", "no")); m_confBoolean[BROADCAST_BANISHMENTS] = booleanString(getGlobalString(L, "broadcastBanishments", "yes")); m_confBoolean[GENERATE_ACCOUNT_NUMBER] = booleanString(getGlobalString(L, "generateAccountNumber", "yes")); m_confBoolean[REPLACE_KICK_ON_LOGIN] = booleanString(getGlobalString(L, "replaceKickOnLogin", "yes")); m_confBoolean[OLD_CONDITION_ACCURACY] = booleanString(getGlobalString(L, "oldConditionAccuracy", "no")); m_confBoolean[ALLOW_CLONES] = booleanString(getGlobalString(L, "allowClones", "no")); m_confBoolean[MARKET_ENABLED] = booleanString(getGlobalString(L, "marketEnabled", "yes")); m_confBoolean[MARKET_PREMIUM] = booleanString(getGlobalString(L, "premiumToCreateMarketOffer", "yes")); m_confBoolean[STAMINA_SYSTEM] = booleanString(getGlobalString(L, "staminaSystem", "yes")); m_confString[DEFAULT_PRIORITY] = getGlobalString(L, "defaultPriority", "high"); m_confString[MAP_STORAGE_TYPE] = getGlobalString(L, "mapStorageType", "relational"); m_confString[LOGIN_MSG] = getGlobalString(L, "loginMessage", "Welcome to the Forgotten Server!"); m_confString[SERVER_NAME] = getGlobalString(L, "serverName"); m_confString[OWNER_NAME] = getGlobalString(L, "ownerName"); m_confString[OWNER_EMAIL] = getGlobalString(L, "ownerEmail"); m_confString[URL] = getGlobalString(L, "url"); m_confString[LOCATION] = getGlobalString(L, "location"); m_confString[MOTD] = getGlobalString(L, "motd"); m_confString[WORLD_TYPE] = getGlobalString(L, "worldType", "pvp"); m_confInteger[LOGIN_TRIES] = getGlobalNumber(L, "loginTries", 3); m_confInteger[RETRY_TIMEOUT] = getGlobalNumber(L, "retryTimeout", 30 * 1000); m_confInteger[LOGIN_TIMEOUT] = getGlobalNumber(L, "loginTimeout", 5 * 1000); m_confInteger[MAX_PLAYERS] = getGlobalNumber(L, "maxPlayers"); m_confInteger[PZ_LOCKED] = getGlobalNumber(L, "pzLocked", 0); m_confInteger[DEFAULT_DESPAWNRANGE] = getGlobalNumber(L, "deSpawnRange", 2); m_confInteger[DEFAULT_DESPAWNRADIUS] = getGlobalNumber(L, "deSpawnRadius", 50); m_confInteger[RATE_EXPERIENCE] = getGlobalNumber(L, "rateExp", 1); m_confInteger[RATE_SKILL] = getGlobalNumber(L, "rateSkill", 1); m_confInteger[RATE_LOOT] = getGlobalNumber(L, "rateLoot", 1); m_confInteger[RATE_MAGIC] = getGlobalNumber(L, "rateMagic", 1); m_confInteger[RATE_SPAWN] = getGlobalNumber(L, "rateSpawn", 1); m_confInteger[SPAWNPOS_X] = getGlobalNumber(L, "newPlayerSpawnPosX", 100); m_confInteger[SPAWNPOS_Y] = getGlobalNumber(L, "newPlayerSpawnPosY", 100); m_confInteger[SPAWNPOS_Z] = getGlobalNumber(L, "newPlayerSpawnPosZ", 7); m_confInteger[SPAWNTOWN_ID] = getGlobalNumber(L, "newPlayerTownId", 1); m_confInteger[START_LEVEL] = getGlobalNumber(L, "newPlayerLevel", 1); m_confInteger[START_MAGICLEVEL] = getGlobalNumber(L, "newPlayerMagicLevel", 0); m_confInteger[HOUSE_PRICE] = getGlobalNumber(L, "housePriceEachSQM", 1000); m_confInteger[KILLS_TO_RED] = getGlobalNumber(L, "killsToRedSkull", 3); m_confInteger[KILLS_TO_BLACK] = getGlobalNumber(L, "killsToBlackSkull", 6); m_confInteger[KILLS_TO_BAN] = getGlobalNumber(L, "killsToBan", 5); m_confInteger[BAN_DAYS] = getGlobalNumber(L, "banDays", 7); m_confInteger[FINAL_BAN_DAYS] = getGlobalNumber(L, "finalBanDays", 30); m_confInteger[ACTIONS_DELAY_INTERVAL] = getGlobalNumber(L, "timeBetweenActions", 200); m_confInteger[EX_ACTIONS_DELAY_INTERVAL] = getGlobalNumber(L, "timeBetweenExActions", 1000); m_confInteger[MAX_MESSAGEBUFFER] = getGlobalNumber(L, "maxMessageBuffer", 4); m_confInteger[CRITICAL_HIT_CHANCE] = getGlobalNumber(L, "criticalHitChance", 5); m_confInteger[KICK_AFTER_MINUTES] = getGlobalNumber(L, "kickIdlePlayerAfterMinutes", 15); m_confInteger[PROTECTION_LEVEL] = getGlobalNumber(L, "protectionLevel", 1); m_confInteger[DEATH_LOSE_PERCENT] = getGlobalNumber(L, "deathLosePercent", -1); m_confInteger[STATUSQUERY_TIMEOUT] = getGlobalNumber(L, "statusTimeout", 5 * 60 * 1000); m_confInteger[FRAG_TIME] = getGlobalNumber(L, "timeToDecreaseFrags", 24 * 60 * 60 * 1000); m_confInteger[WHITE_SKULL_TIME] = getGlobalNumber(L, "whiteSkullTime", 15 * 60 * 1000); m_confInteger[AUTO_SAVE_EACH_MINUTES] = getGlobalNumber(L, "autoSaveEachMinutes", 0); m_confInteger[STAIRHOP_DELAY] = getGlobalNumber(L, "stairJumpExhaustion", 2000); m_confInteger[LEVEL_TO_CREATE_GUILD] = getGlobalNumber(L, "levelToCreateGuild", 8); m_confInteger[MIN_GUILD_NAME] = getGlobalNumber(L, "minGuildNameLength", 4); m_confInteger[MAX_GUILD_NAME] = getGlobalNumber(L, "maxGuildNameLength", 20); m_confInteger[CHECK_EXPIRED_MARKET_OFFERS_EACH_MINUTES] = getGlobalNumber(L, "checkExpiredMarketOffersEachMinutes", 60); m_confInteger[MAX_MARKET_OFFERS_AT_A_TIME_PER_PLAYER] = getGlobalNumber(L, "maxMarketOffersAtATimePerPlayer", 100); m_isLoaded = true; lua_close(L); return true; }
bool Commands::loadFromXml() { std::string filename = "data/XML/commands.xml"; xmlDocPtr doc = xmlParseFile(filename.c_str()); if (doc) { loaded = true; xmlNodePtr root, p; root = xmlDocGetRootElement(doc); if (xmlStrcmp(root->name, (const xmlChar*)"commands")) { std::cout << "[Error - Commands::loadFromXml] Malformed commands file." << std::endl; xmlFreeDoc(doc); return false; } std::string strCmd; p = root->children; while (p) { if (xmlStrcmp(p->name, (const xmlChar*)"command") == 0) { if (readXMLString(p, "cmd", strCmd)) { CommandMap::iterator it = commandMap.find(strCmd); int32_t gId; int32_t aTypeLevel; std::string strValue; if (it != commandMap.end()) { Command* command = it->second; if (readXMLInteger(p, "group", gId)) { if (!command->loadedGroupId) { command->groupId = gId; command->loadedGroupId = true; } else { std::cout << "Duplicated command " << strCmd << std::endl; } } else { std::cout << "missing group tag for " << strCmd << std::endl; } if (readXMLInteger(p, "acctype", aTypeLevel)) { if (!command->loadedAccountType) { command->accountType = (AccountType_t)aTypeLevel; command->loadedAccountType = true; } else { std::cout << "Duplicated command " << strCmd << std::endl; } } else { std::cout << "missing acctype tag for " << strCmd << std::endl; } if (readXMLString(p, "log", strValue)) { if (!command->loadedLogging) { command->logged = booleanString(strValue); command->loadedLogging = true; } else { std::cout << "Duplicated log tag for " << strCmd << std::endl; } } else { std::cout << "Missing log tag for " << strCmd << std::endl; } } else { std::cout << "Unknown command " << strCmd << std::endl; } } else { std::cout << "missing cmd." << std::endl; } } p = p->next; } xmlFreeDoc(doc); } for (CommandMap::iterator it = commandMap.begin(), end = commandMap.end(); it != end; ++it) { Command* command = it->second; if (!command->loadedGroupId) { std::cout << "Warning: Missing group id for command " << it->first << std::endl; } if (!command->loadedAccountType) { std::cout << "Warning: Missing acctype level for command " << it->first << std::endl; } if (!command->loadedLogging) { std::cout << "Warning: Missing log command " << it->first << std::endl; } g_game.addCommandTag(it->first[0]); } return loaded; }