Guest User

Untitled

a guest
Sep 22nd, 2019
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.71 KB | None | 0 0
  1. /**
  2.  * Tibia GIMUD Server - a free and open-source MMORPG server emulator
  3.  * Copyright (C) 2017  Alejandro Mujica <alejandrodemujica@gmail.com>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18.  */
  19.  
  20. #include "otpch.h"
  21.  
  22. #include "items.h"
  23. #include "spells.h"
  24. #include "movement.h"
  25. #include "script.h"
  26.  
  27. #include "pugicast.h"
  28.  
  29. extern MoveEvents* g_moveEvents;
  30.  
  31. Items::Items()
  32. {
  33.     items.reserve(6000);
  34.     nameToItems.reserve(6000);
  35. }
  36.  
  37. void Items::clear()
  38. {
  39.     items.clear();
  40.     nameToItems.clear();
  41. }
  42. bool Items::reload()
  43. {
  44.     clear();
  45.     if (!loadItems()) {
  46.         return false;
  47.     }
  48.  
  49.     g_moveEvents->reload();
  50.     return true;
  51. }
  52.  
  53. bool Items::loadItems()
  54. {
  55.     ScriptReader script;
  56.     if (!script.open("data/items/items.srv")) {
  57.         return false;
  58.     }
  59.  
  60.     std::string identifier;
  61.     uint16_t id = 0;
  62.     while (true) {
  63.         script.nextToken();
  64.         if (script.Token == ENDOFFILE) {
  65.             break;
  66.         }
  67.  
  68.         if (script.Token != IDENTIFIER) {
  69.             script.error("Identifier expected");
  70.             return false;
  71.         }
  72.  
  73.         identifier = script.getIdentifier();
  74.         script.readSymbol('=');
  75.  
  76.         if (identifier == "typeid") {
  77.             id = script.readNumber();
  78.             if (id >= items.size()) {
  79.                 items.resize(id + 1);
  80.             }
  81.  
  82.             if (items[id].id) {
  83.                 script.error("item type already defined");
  84.                 return false;
  85.             }
  86.  
  87.             items[id].id = id;
  88.         } else if (identifier == "name") {
  89.             items[id].name = script.readString();
  90.         } else if (identifier == "description") {
  91.             items[id].description = script.readString();
  92.         } else if (identifier == "flags") {
  93.             script.readSymbol('{');
  94.             while (true) {
  95.                 while (true) {
  96.                     script.nextToken();
  97.                     if (script.Token == SPECIAL) {
  98.                         break;
  99.                     }
  100.  
  101.                     identifier = script.getIdentifier();
  102.                    
  103.                     if (identifier == "bank") {
  104.                         items[id].group = ITEM_GROUP_GROUND;
  105.                     } else if (identifier == "clip") {
  106.                         items[id].alwaysOnTop = true;
  107.                         items[id].alwaysOnTopOrder = 1;
  108.                     } else if (identifier == "bottom") {
  109.                         items[id].alwaysOnTop = true;
  110.                         items[id].alwaysOnTopOrder = 2;
  111.                     } else if (identifier == "top") {
  112.                         items[id].alwaysOnTop = true;
  113.                         items[id].alwaysOnTopOrder = 3;
  114.                     } else if (identifier == "container") {
  115.                         items[id].type = ITEM_TYPE_CONTAINER;
  116.                     } else if (identifier == "quiver") {
  117.                         items[id].group = ITEM_GROUP_QUIVER;
  118.                     } else if (identifier == "chest") {
  119.                         items[id].type = ITEM_TYPE_CHEST;
  120.                     } else if (identifier == "cumulative") {
  121.                         items[id].stackable = true;
  122.                     } else if (identifier == "changeuse") {
  123.                         items[id].changeUse = true;
  124.                     } else if (identifier == "forceuse") {
  125.                         items[id].forceUse = true;
  126.                     } else if (identifier == "key") {
  127.                         items[id].type = ITEM_TYPE_KEY;
  128.                         items[id].group = ITEM_GROUP_KEY;
  129.                     } else if (identifier == "door") {
  130.                         items[id].type = ITEM_TYPE_DOOR;
  131.                     } else if (identifier == "bed") {
  132.                         items[id].type = ITEM_TYPE_BED;
  133.                     } else if (identifier == "rune") {
  134.                         items[id].type = ITEM_TYPE_RUNE;
  135.                     } else if (identifier == "depot") {
  136.                         items[id].type = ITEM_TYPE_DEPOT;
  137.                     } else if (identifier == "mailbox") {
  138.                         items[id].type = ITEM_TYPE_MAILBOX;
  139.                     } else if (identifier == "allowdistread") {
  140.                         items[id].allowDistRead = true;
  141.                     } else if (identifier == "text") {
  142.                         items[id].canReadText = true;
  143.                     } else if (identifier == "write") {
  144.                         items[id].canWriteText = true;
  145.                     } else if (identifier == "writeonce") {
  146.                         items[id].canWriteText = true;
  147.                         items[id].writeOnceItemId = id;
  148.                     } else if (identifier == "fluidcontainer") {
  149.                         items[id].group = ITEM_GROUP_FLUID;
  150.                     } else if (identifier == "splash") {
  151.                         items[id].group = ITEM_GROUP_SPLASH;
  152.                     } else if (identifier == "unpass") {
  153.                         items[id].blockSolid = true;
  154.                     } else if (identifier == "unmove") {
  155.                         items[id].moveable = false;
  156.                     } else if (identifier == "unthrow") {
  157.                         items[id].blockProjectile = true;
  158.                     } else if (identifier == "unlay") {
  159.                         items[id].allowPickupable = false;
  160.                     } else if (identifier == "avoid") {
  161.                         items[id].blockPathFind = true;
  162.                     } else if (identifier == "magicfield") {
  163.                         items[id].type = ITEM_TYPE_MAGICFIELD;
  164.                         items[id].group = ITEM_GROUP_MAGICFIELD;
  165.                     } else if (identifier == "take") {
  166.                         items[id].pickupable = true;
  167.                     } else if (identifier == "hang") {
  168.                         items[id].isHangable = true;
  169.                     } else if (identifier == "hooksouth") {
  170.                         items[id].isHorizontal = true;
  171.                     } else if (identifier == "hookeast") {
  172.                         items[id].isVertical = true;
  173.                     } else if (identifier == "rotate") {
  174.                         items[id].rotatable = true;
  175.                     } else if (identifier == "destroy") {
  176.                         items[id].destroy = true;
  177.                     } else if (identifier == "corpse") {
  178.                         items[id].corpse = true;
  179.                     } else if (identifier == "expire") {
  180.                         items[id].stopTime = false;
  181.                     } else if (identifier == "expirestop") {
  182.                         items[id].stopTime = true;
  183.                     } else if (identifier == "weapon") {
  184.                         items[id].group = ITEM_GROUP_WEAPON;
  185.                     } else if (identifier == "shield") {
  186.                         items[id].weaponType = WEAPON_SHIELD;
  187.                     } else if (identifier == "distance") {
  188.                         items[id].weaponType = WEAPON_DISTANCE;
  189.                     } else if (identifier == "wand") {
  190.                         items[id].weaponType = WEAPON_WAND;
  191.                     } else if (identifier == "ammo") {
  192.                         items[id].weaponType = WEAPON_AMMO;
  193.                     } else if (identifier == "armor") {
  194.                         items[id].group = ITEM_GROUP_ARMOR;
  195.                     } else if (identifier == "height") {
  196.                         items[id].hasHeight = true;
  197.                     } else if (identifier == "disguise") {
  198.                         items[id].disguise = true;
  199.                     } else if (identifier == "showdetail") {
  200.                         items[id].showDuration = true;
  201.                     } else if (identifier == "noreplace") {
  202.                         items[id].replaceable = false;
  203.                     } else if (identifier == "collisionevent") {
  204.                         items[id].collisionEvent = true;
  205.                     } else if (identifier == "separationevent") {
  206.                         items[id].separationEvent = true;
  207.                     } else if (identifier == "useevent") {
  208.                         items[id].useEvent = true;
  209.                     } else if (identifier == "distuse") {
  210.                         items[id].distUse = true;
  211.                     } else if (identifier == "multiuse") {
  212.                         items[id].multiUseEvent = true;
  213.                     } else {
  214.                         script.error("Unknown flag");
  215.                         return false;
  216.                     }
  217.                 }
  218.  
  219.                 if (script.getSpecial() == '}') {
  220.                     break;
  221.                 }
  222.  
  223.                 if (script.Token != SPECIAL || script.getSpecial() != ',') {
  224.                     continue;
  225.                 }
  226.             }
  227.         } else if (identifier == "attributes") {
  228.             script.readSymbol('{');
  229.             while (true) {
  230.                 while (true) {
  231.                     script.nextToken();
  232.                     if (script.Token == SPECIAL) {
  233.                         break;
  234.                     }
  235.  
  236.                     identifier = script.getIdentifier();
  237.                     script.readSymbol('=');
  238.  
  239.                     if (identifier == "waypoints") {
  240.                         items[id].speed = script.readNumber();
  241.                     } else if (identifier == "capacity") {
  242.                         items[id].maxItems = script.readNumber();
  243.                     } else if (identifier == "changetarget") {
  244.                         items[id].transformToOnUse = script.readNumber();
  245.                     } else if (identifier == "nutrition") {
  246.                         items[id].nutrition = script.readNumber();
  247.                     } else if (identifier == "maxlength") {
  248.                         items[id].maxTextLen = script.readNumber();
  249.                     } else if (identifier == "fluidsource") {
  250.                         items[id].fluidSource = getFluidType(script.readIdentifier());
  251.                     } else if (identifier == "avoiddamagetypes") {
  252.                         items[id].combatType = getCombatType(script.readIdentifier());
  253.                     } else if (identifier == "damagetype") {
  254.                         items[id].damageType = getCombatType(script.readIdentifier());
  255.                     } else if (identifier == "attackstrength") {
  256.                         items[id].attackStrength = script.readNumber();
  257.                     } else if (identifier == "attackvariation") {
  258.                         items[id].attackVariation = script.readNumber();
  259.                     } else if (identifier == "manaconsumption") {
  260.                         items[id].manaConsumption = script.readNumber();
  261.                     } else if (identifier == "minimumlevel") {
  262.                         items[id].minReqLevel = script.readNumber();
  263.                         items[id].wieldInfo |= WIELDINFO_LEVEL;
  264.                     } else if (identifier == "vocations") {
  265.                         int32_t vocations = script.readNumber();
  266.                         items[id].vocations = vocations;
  267.  
  268.                         std::list<std::string> vocationStringList;
  269.  
  270.                         if (hasBitSet(VOCATION_SORCERER, vocations)) {
  271.                             vocationStringList.push_back("sorcerer");
  272.                         }
  273.  
  274.                         if (hasBitSet(VOCATION_DRUID, vocations)) {
  275.                             vocationStringList.push_back("druid");
  276.                         }
  277.  
  278.                         if (hasBitSet(VOCATION_PALADIN, vocations)) {
  279.                             vocationStringList.push_back("paladin");
  280.                         }
  281.  
  282.                         if (hasBitSet(VOCATION_KNIGHT, vocations)) {
  283.                             vocationStringList.push_back("knight");
  284.                         }
  285.  
  286.                         std::string vocationString;
  287.                         for (const std::string& str : vocationStringList) {
  288.                             if (!vocationString.empty()) {
  289.                                 if (str != vocationStringList.back()) {
  290.                                     vocationString.push_back(',');
  291.                                     vocationString.push_back(' ');
  292.                                 } else {
  293.                                     vocationString += " and ";
  294.                                 }
  295.                             }
  296.  
  297.                             vocationString += str;
  298.                             vocationString.push_back('s');
  299.                         }
  300.  
  301.                         items[id].wieldInfo |= WIELDINFO_VOCREQ;
  302.                         items[id].vocationString = vocationString;
  303.                     } else if (identifier == "weaponspecialeffect") {
  304.                         items[id].weaponSpecialEffect = script.readNumber();
  305.                     } else if (identifier == "beddirection") {
  306.                         items[id].bedPartnerDir = getDirection(script.readIdentifier());
  307.                     } else if (identifier == "bedtarget") {
  308.                         items[id].transformToOnUse = script.readNumber();
  309.                     } else if (identifier == "bedfree") {
  310.                         items[id].transformToFree = script.readNumber();
  311.                     } else if (identifier == "weight") {
  312.                         items[id].weight = script.readNumber();
  313.                     } else if (identifier == "rotatetarget") {
  314.                         items[id].rotateTo = script.readNumber();
  315.                     } else if (identifier == "destroytarget") {
  316.                         items[id].destroyTarget = script.readNumber();
  317.                     } else if (identifier == "slottype") {
  318.                         identifier = asLowerCaseString(script.readIdentifier());
  319.                         if (identifier == "head") {
  320.                             items[id].slotPosition |= SLOTP_HEAD;
  321.                         } else if (identifier == "body") {
  322.                             items[id].slotPosition |= SLOTP_ARMOR;
  323.                         } else if (identifier == "legs") {
  324.                             items[id].slotPosition |= SLOTP_LEGS;
  325.                         } else if (identifier == "feet") {
  326.                             items[id].slotPosition |= SLOTP_FEET;
  327.                         } else if (identifier == "backpack") {
  328.                             items[id].slotPosition |= SLOTP_BACKPACK;
  329.                         } else if (identifier == "twohanded") {
  330.                             items[id].slotPosition |= SLOTP_TWO_HAND;
  331.                         } else if (identifier == "righthand") {
  332.                             items[id].slotPosition &= ~SLOTP_LEFT;
  333.                         } else if (identifier == "lefthand") {
  334.                             items[id].slotPosition &= ~SLOTP_RIGHT;
  335.                         } else if (identifier == "necklace") {
  336.                             items[id].slotPosition |= SLOTP_NECKLACE;
  337.                         } else if (identifier == "ring") {
  338.                             items[id].slotPosition |= SLOTP_RING;
  339.                         } else if (identifier == "ammo") {
  340.                             items[id].slotPosition |= SLOTP_AMMO;
  341.                         } else if (identifier == "hand") {
  342.                             items[id].slotPosition |= SLOTP_HAND;
  343.                         } else {
  344.                             script.error("Unknown slot position");
  345.                             return false;
  346.                         }
  347.                     } else if (identifier == "speedboost") {
  348.                         items[id].getAbilities().speed = script.readNumber();
  349.                     } else if (identifier == "fistboost") {
  350.                         items[id].getAbilities().skills[SKILL_FIST] = script.readNumber();
  351.                     } else if (identifier == "swordboost") {
  352.                         items[id].getAbilities().skills[SKILL_SWORD] = script.readNumber();
  353.                     } else if (identifier == "clubboost") {
  354.                         items[id].getAbilities().skills[SKILL_CLUB] = script.readNumber();
  355.                     } else if (identifier == "axeboost") {
  356.                         items[id].getAbilities().skills[SKILL_AXE] = script.readNumber();
  357.                     } else if (identifier == "shieldboost") {
  358.                         items[id].getAbilities().skills[SKILL_SHIELD] = script.readNumber();
  359.                     } else if (identifier == "distanceboost") {
  360.                         items[id].getAbilities().skills[SKILL_DISTANCE] = script.readNumber();
  361.                     } else if (identifier == "magicboost") {
  362.                         items[id].getAbilities().stats[STAT_MAGICPOINTS] = script.readNumber();
  363.                     } else if (identifier == "percenthp") {
  364.                         items[id].getAbilities().statsPercent[STAT_MAXHITPOINTS] = script.readNumber();
  365.                     } else if (identifier == "percentmp") {
  366.                         items[id].getAbilities().statsPercent[STAT_MAXMANAPOINTS] = script.readNumber();
  367.                     } else if (identifier == "suppressdrunk") {
  368.                         if (script.readNumber()) {
  369.                             items[id].getAbilities().conditionSuppressions |= CONDITION_DRUNK;
  370.                         }
  371.                     } else if (identifier == "invisible") {
  372.                         if (script.readNumber()) {
  373.                             items[id].getAbilities().invisible = true;
  374.                         }
  375.                     } else if (identifier == "manashield") {
  376.                         if (script.readNumber()) {
  377.                             items[id].getAbilities().manaShield = true;
  378.                         }
  379.                     } else if (identifier == "healthticks") {
  380.                         Abilities& abilities = items[id].getAbilities();
  381.                         abilities.regeneration = true;
  382.                         abilities.healthTicks = script.readNumber();
  383.                     } else if (identifier == "healthgain") {
  384.                         Abilities& abilities = items[id].getAbilities();
  385.                         abilities.regeneration = true;
  386.                         abilities.healthGain = script.readNumber();
  387.                     } else if (identifier == "manaticks") {
  388.                         Abilities& abilities = items[id].getAbilities();
  389.                         abilities.regeneration = true;
  390.                         abilities.manaTicks = script.readNumber();
  391.                     } else if (identifier == "managain") {
  392.                         Abilities& abilities = items[id].getAbilities();
  393.                         abilities.regeneration = true;
  394.                         abilities.manaGain = script.readNumber();
  395.                     } else if (identifier == "absorbmagic") {
  396.                         int32_t percent = script.readNumber();
  397.                         items[id].getAbilities().absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += percent;
  398.                         items[id].getAbilities().absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += percent;
  399.                         items[id].getAbilities().absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += percent;
  400.                     } else if (identifier == "absorbenergy") {
  401.                         items[id].getAbilities().absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += script.readNumber();
  402.                     } else if (identifier == "absorbfire") {
  403.                         items[id].getAbilities().absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += script.readNumber();
  404.                     } else if (identifier == "absorbpoison") {
  405.                         items[id].getAbilities().absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += script.readNumber();
  406.                     } else if (identifier == "absorblifedrain") {
  407.                         items[id].getAbilities().absorbPercent[combatTypeToIndex(COMBAT_LIFEDRAIN)] += script.readNumber();
  408.                     } else if (identifier == "absorbmanadrain") {
  409.                         items[id].getAbilities().absorbPercent[combatTypeToIndex(COMBAT_MANADRAIN)] += script.readNumber();
  410.                     } else if (identifier == "absorbphysical") {
  411.                         items[id].getAbilities().absorbPercent[combatTypeToIndex(COMBAT_PHYSICALDAMAGE)] += script.readNumber();
  412.                     } else if (identifier == "absorbhealing") {
  413.                         items[id].getAbilities().absorbPercent[combatTypeToIndex(COMBAT_HEALING)] += script.readNumber();
  414.                     } else if (identifier == "absorbundefined") {
  415.                         items[id].getAbilities().absorbPercent[combatTypeToIndex(COMBAT_UNDEFINEDDAMAGE)] += script.readNumber();
  416.                     } else if (identifier == "absorbfirefield") {
  417.                         items[id].getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += static_cast<int16_t>(script.readNumber());
  418.                     } else if (identifier == "brightness") {
  419.                         items[id].lightLevel = script.readNumber();
  420.                     } else if (identifier == "lightcolor") {
  421.                         items[id].lightColor = script.readNumber();
  422.                     } else if (identifier == "totalexpiretime") {
  423.                         items[id].decayTime = script.readNumber();
  424.                     } else if (identifier == "expiretarget") {
  425.                         items[id].decayTo = script.readNumber();
  426.                     } else if (identifier == "totaluses") {
  427.                         items[id].charges = script.readNumber();
  428.                     } else if (identifier == "weapontype") {
  429.                         identifier = script.readIdentifier();
  430.                         if (identifier == "sword") {
  431.                             items[id].weaponType = WEAPON_SWORD;
  432.                         } else if (identifier == "club") {
  433.                             items[id].weaponType = WEAPON_CLUB;
  434.                         } else if (identifier == "axe") {
  435.                             items[id].weaponType = WEAPON_AXE;
  436.                         } else if (identifier == "shield") {
  437.                             items[id].weaponType = WEAPON_SHIELD;
  438.                         } else if (identifier == "distance") {
  439.                             items[id].weaponType = WEAPON_DISTANCE;
  440.                         } else if (identifier == "wand") {
  441.                             items[id].weaponType = WEAPON_WAND;
  442.                         } else if (identifier == "ammunition") {
  443.                             items[id].weaponType = WEAPON_AMMO;
  444.                         } else {
  445.                             script.error("Unknown weapon type");
  446.                             return false;
  447.                         }
  448.                     } else if (identifier == "attack") {
  449.                         items[id].attack = script.readNumber();
  450.                     } else if (identifier == "defense") {
  451.                         items[id].defense = script.readNumber();
  452.                     } else if (identifier == "range") {
  453.                         items[id].shootRange = static_cast<uint8_t>(script.readNumber());
  454.                     } else if (identifier == "ammotype") {
  455.                         items[id].ammoType = getAmmoType(script.readIdentifier());
  456.                         if (items[id].ammoType == AMMO_NONE) {
  457.                             script.error("Unknown ammo type");
  458.                             return false;
  459.                         }
  460.                     } else if (identifier == "missileeffect") {
  461.                         items[id].shootType = static_cast<ShootType_t>(script.readNumber());
  462.                     } else if (identifier == "fragility") {
  463.                         items[id].fragility = script.readNumber();
  464.                     } else if (identifier == "armorvalue") {
  465.                         items[id].armor = script.readNumber();
  466.                     } else if (identifier == "disguisetarget") {
  467.                         items[id].disguiseId = script.readNumber();
  468.                     } else if (identifier == "equiptarget") {
  469.                         items[id].transformEquipTo = script.readNumber();
  470.                     } else if (identifier == "deequiptarget") {
  471.                         items[id].transformDeEquipTo = script.readNumber();
  472.                     } else {
  473.                         script.error("Unknown attribute");
  474.                         return false;
  475.                     }
  476.                 }
  477.  
  478.                 if (script.getSpecial() == '}') {
  479.                     break;
  480.                 }
  481.  
  482.                 if (script.Token != SPECIAL || script.getSpecial() != ',') {
  483.                     continue;
  484.                 }
  485.             }
  486.         } else if (identifier == "magicfield") {
  487.             script.readSymbol('{');
  488.  
  489.             CombatType_t combatType = COMBAT_NONE;
  490.             ConditionDamage* conditionDamage = nullptr;
  491.  
  492.             int32_t cycles = 0;
  493.             int32_t hit_damage = 0;
  494.  
  495.             while (true) {
  496.                 while (true) {
  497.                     script.nextToken();
  498.                     if (script.Token == SPECIAL) {
  499.                         break;
  500.                     }
  501.  
  502.                     identifier = script.getIdentifier();
  503.                     script.readSymbol('=');
  504.  
  505.                     if (identifier == "type") {
  506.                         identifier = script.readIdentifier();
  507.                         if (identifier == "fire") {
  508.                             conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_FIRE);
  509.                             combatType = COMBAT_FIREDAMAGE;
  510.                             items[id].combatType = combatType;
  511.                             items[id].conditionDamage.reset(conditionDamage);
  512.                         } else if (identifier == "energy") {
  513.                             conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_ENERGY);
  514.                             combatType = COMBAT_ENERGYDAMAGE;
  515.                             items[id].combatType = combatType;
  516.                             items[id].conditionDamage.reset(conditionDamage);
  517.                         } else if (identifier == "poison") {
  518.                             conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_POISON);
  519.                             conditionDamage->setParam(CONDITION_PARAM_DELAYED, true);
  520.                             combatType = COMBAT_EARTHDAMAGE;
  521.                             items[id].combatType = combatType;
  522.                             items[id].conditionDamage.reset(conditionDamage);
  523.                         } else {
  524.                             script.error("unknown magicfield type");
  525.                             return false;
  526.                         }
  527.                     } else if (identifier == "count") {
  528.                         cycles = script.readNumber();
  529.                     } else if (identifier == "damage") {
  530.                         hit_damage = script.readNumber();
  531.                     } else {
  532.                         script.error("unknown identifier");
  533.                         return false;
  534.                     }
  535.                 }
  536.  
  537.                 if (script.getSpecial() == '}') {
  538.                     break;
  539.                 }
  540.  
  541.                 if (script.Token != SPECIAL || script.getSpecial() != ',') {
  542.                     continue;
  543.                 }
  544.             }
  545.  
  546.             int32_t count = 3;
  547.  
  548.             if (combatType == COMBAT_FIREDAMAGE) {
  549.                 cycles /= 10;
  550.                 count = 8;
  551.             } else if (combatType == COMBAT_ENERGYDAMAGE) {
  552.                 cycles /= 20;
  553.                 count = 10;
  554.             }
  555.  
  556.             conditionDamage->setParam(CONDITION_PARAM_CYCLE, cycles);
  557.             conditionDamage->setParam(CONDITION_PARAM_COUNT, count);
  558.             conditionDamage->setParam(CONDITION_PARAM_MAX_COUNT, count);
  559.             conditionDamage->setParam(CONDITION_PARAM_HIT_DAMAGE, hit_damage);
  560.  
  561.             conditionDamage->setParam(CONDITION_PARAM_FIELD, 1);
  562.         }
  563.     }
  564.  
  565.     script.close();
  566.     items.shrink_to_fit();
  567.  
  568.     for (ItemType& type : items) {
  569.         std::string& name = type.name;
  570.         extractArticleAndName(name, type.article, type.name);
  571.         nameToItems.insert({ asLowerCaseString(type.name), type.id });
  572.         if (!name.empty()) {
  573.             if (type.stackable) {
  574.                 type.showCount = true;
  575.                 type.pluralName = pluralizeString(name);
  576.             }
  577.         }
  578.     }
  579.  
  580.     return true;
  581. }
  582.  
  583. ItemType& Items::getItemType(size_t id)
  584. {
  585.     if (id < items.size()) {
  586.         return items[id];
  587.     }
  588.     return items.front();
  589. }
  590.  
  591. const ItemType& Items::getItemType(size_t id) const
  592. {
  593.     if (id < items.size()) {
  594.         return items[id];
  595.     }
  596.     return items.front();
  597. }
  598.  
  599. uint16_t Items::getItemIdByName(const std::string& name)
  600. {
  601.     auto result = nameToItems.find(asLowerCaseString(name));
  602.  
  603.     if (result == nameToItems.end())
  604.         return 0;
  605.  
  606.     return result->second;
  607. }
Add Comment
Please, Sign In to add comment