// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . ///////////// // INCLUDE // ///////////// #include "stdpch.h" // First include for pre-compiled headers. // Georges #include "nel/georges/u_form_elm.h" // Client. #include "item_sheet.h" #include "game_share/characteristics.h" #include "game_share/scores.h" #include "game_share/skills.h" #include "game_share/people.h" #include "game_share/protection_type.h" #include "nel/misc/i18n.h" /////////// // USING // /////////// using namespace std; using namespace NLMISC; using namespace NLGEORGES; // *************************************************************************** // Easy Macro to translate .typ enum #define TRANSLATE_ENUM( _Var_, _unknown_, _func_, _key_) \ _Var_ = _unknown_; \ if( !item.getValueByName(val, _key_)) \ debug( toString("Key '%s' not found.", _key_) ); \ else if( (_Var_ = _func_(val)) == _unknown_ ) \ debug(#_Var_ " Unknown: " + val); // Same but no error if the result of enum is _unknown_ #define TRANSLATE_ENUM_NODB( _Var_, _unknown_, _func_, _key_) \ _Var_ = _unknown_; \ if( !item.getValueByName(val, _key_)) \ debug( toString("Key '%s' not found.", _key_) ); \ else \ _Var_ = _func_(val); // Easy macro to translate value from georges #define TRANSLATE_VAL( _Var_, _key_ ) \ if(!item.getValueByName(_Var_, _key_)) \ debug( toString("Key '%s' not found.", _key_) ); \ // *************************************************************************** //----------------------------------------------- // CItemSheet : // Constructor. //----------------------------------------------- CItemSheet::CItemSheet() { IdShape = 0; IdShapeFemale = 0; MapVariant = 0; ItemType = ITEM_TYPE::UNDEFINED; Family = ITEMFAMILY::UNDEFINED; SlotBF= 0; IdIconBack = 0; IdIconMain = 0; IdIconOver = 0; IdIconOver2 = 0; IdIconText = 0; IdAnimSet = 0; Color = 0; HasFx = false; DropOrSell = false; IsItemNoRent = false; Stackable = 0; IsConsumable = false; IdEffect1 = 0; IdEffect2 = 0; IdEffect3 = 0; IdEffect4 = 0; Type = CEntitySheet::ITEM; Bulk= 0.f; EquipTime= 0; NeverHideWhenEquiped = false; RequiredCharac = CHARACTERISTICS::Unknown; RequiredCharacLevel = 0; RequiredSkill = SKILLS::unknown; RequiredSkillLevel = 0; IconColor= NLMISC::CRGBA::White; IconBackColor= NLMISC::CRGBA::White; IconOverColor= NLMISC::CRGBA::White; IconOver2Color= NLMISC::CRGBA::White; ItemOrigin = ITEM_ORIGIN::UNKNOWN; Cosmetic.VPValue = 0; Cosmetic.Gender = GSGENDER::unknown; Armor.ArmorType = ARMORTYPE::UNKNOWN; MeleeWeapon.WeaponType = WEAPONTYPE::UNKNOWN; MeleeWeapon.Skill = SKILLS::unknown; MeleeWeapon.DamageType = DMGTYPE::UNDEFINED; MeleeWeapon.MeleeRange = 0; RangeWeapon.WeaponType = WEAPONTYPE::UNKNOWN; RangeWeapon.RangeWeaponType = RANGE_WEAPON_TYPE::Unknown; RangeWeapon.Skill = SKILLS::unknown; Ammo.Skill = SKILLS::unknown; Ammo.DamageType = DMGTYPE::UNDEFINED; Ammo.Magazine = 0; Mp.Ecosystem = ECOSYSTEM::unknown; Mp.MpCategory = MP_CATEGORY::Undefined; Mp.HarvestSkill = SKILLS::unknown; Mp.Family = RM_FAMILY::Unknown; Mp.UsedAsCraftRequirement = false; Mp.MpColor = 0; Mp.StatEnergy = 0; Mp.ItemPartBF = 0; Shield.ShieldType = SHIELDTYPE::NONE; Tool.Skill = SKILLS::unknown; Tool.CraftingToolType = TOOL_TYPE::Unknown; Tool.CommandRange = 0; Tool.MaxDonkey = 0; GuildOption.MoneyCost = 0; GuildOption.XPCost = 0; Pet.Slot = 0; Teleport.Type = TELEPORT_TYPES::NONE; }// CItemSheet // //----------------------------------------------- // build : // Build the sheet from an external script. //----------------------------------------------- void CItemSheet::build(const NLGEORGES::UFormElm &item) { // Load the name. string Shape; if(!item.getValueByName(Shape, "3d.shape")) debug("key '3d.shape' not found."); IdShape = ClientSheetsStrings.add(Shape); // Load the name. string ShapeFemale; if(!item.getValueByName(ShapeFemale, "3d.shape_female")) debug("key '3d.shape_female' not found."); IdShapeFemale = ClientSheetsStrings.add(ShapeFemale); // Get the icon associated. string IconMain; if(!item.getValueByName (IconMain, "3d.icon")) debug("key '3d.icon' not found."); IconMain = strlwr (IconMain); IdIconMain = ClientSheetsStrings.add(IconMain); // Get the icon associated. string IconBack; if(!item.getValueByName (IconBack, "3d.icon background")) debug("key '3d.icon background' not found."); IconBack = strlwr (IconBack); IdIconBack = ClientSheetsStrings.add(IconBack); // Get the icon associated. string IconOver; if(!item.getValueByName (IconOver, "3d.icon overlay")) debug("key '3d.icon overlay' not found."); IconOver = strlwr (IconOver); IdIconOver = ClientSheetsStrings.add(IconOver); // Get the icon associated. string IconOver2; if(!item.getValueByName (IconOver2, "3d.icon overlay2")) debug("key '3d.icon overlay2' not found."); IconOver2 = strlwr (IconOver2); IdIconOver2 = ClientSheetsStrings.add(IconOver2); // Get Special modulate colors item.getValueByName (IconColor, "3d.IconColor" ); item.getValueByName (IconBackColor, "3d.IconBackColor"); item.getValueByName (IconOverColor, "3d.IconOverColor"); item.getValueByName (IconOver2Color, "3d.IconOver2Color"); // Get the icon text associated. string IconText; if(!item.getValueByName (IconText, "3d.text overlay")) debug("key '3d.text overlay' not found."); IconText = strlwr (IconText); IdIconText = ClientSheetsStrings.add(IconText); // See if this item can be hiden when equiped if(!item.getValueByName (NeverHideWhenEquiped, "3d.never hide when equiped")) debug("key '3d.never hide when equiped."); // Load the different slot in wicth the item can be equipped. const UFormElm *pElt = 0; // check uint32 is OK! nlassert( SLOTTYPE::NB_SLOT_TYPE <= 32 ); SlotBF= 0; if(item.getNodeByName(&pElt, "basics.EquipmentInfo.EquipmentSlots") && pElt) { // Get all slots. uint size; if(pElt->getArraySize(size)) { for(uint i = 0; i < size; ++i) { string slotName; if(pElt->getArrayValue(slotName, i)) { // Check name. if(slotName.empty()) debug(toString("The slot name %d is Empty.", i)); // Push the possible slots for the item in the list. SlotBF|= SINT64_CONSTANT(1)<< (SLOTTYPE::stringToSlotType(NLMISC::strupr(slotName))); } } } else debug("The element 'basics.Equipment Slot' is not an array."); } else debug("Cannot create the element from the name 'basics.Equipment Slot'."); // Get the Item Family. string family; if(!item.getValueByName(family, "basics.family")) { debug("Key 'basics.family' not found."); Family = ITEMFAMILY::UNDEFINED; } else { Family = (ITEMFAMILY::EItemFamily) ITEMFAMILY::stringToItemFamily(NLMISC::strupr( family) ); if(Family == ITEMFAMILY::UNDEFINED) debug("Item Family Undefined."); } // Get the Item Type. string itemtype; if(!item.getValueByName(itemtype, "basics.ItemType")) { debug("Key 'basics.ItemType' not found."); ItemType = ITEM_TYPE::UNDEFINED; } else { ItemType = (ITEM_TYPE::TItemType) ITEM_TYPE::stringToItemType(NLMISC::strupr(itemtype) ); if (ItemType == ITEM_TYPE::UNDEFINED) debug("Item Type Undefined."); } // Get the DropOrSell property if(!item.getValueByName (DropOrSell, "basics.Drop or Sell")) debug("key 'basics.Drop or Sell' not found."); // Get the IsItemNoRent property if(!item.getValueByName (IsItemNoRent, "basics.No Rent")) debug("key 'basics.No Rent' not found."); // Get the stackable property if(!item.getValueByName (Stackable, "basics.stackable")) debug("key 'basics.stackable' not found."); // Get the Consumable property if(!item.getValueByName (IsConsumable, "basics.Consumable")) debug("key 'basics.Consumable' not found."); // Get the texture variante. if(!item.getValueByName(MapVariant, "3d.map_variant")) debug("Key '3d.map_variant' not found."); // Load the name. string AnimSet; if(!item.getValueByName(AnimSet, "3d.anim_set")) debug("key '3d.anim_set' not found."); // Force the CASE in UPPER to not be CASE SENSITIVE. else NLMISC::strlwr(AnimSet); IdAnimSet = ClientSheetsStrings.add(AnimSet); // Get the Trail Shape if(!item.getValueByName(Color, "3d.color")) debug("key '3d.color' not found."); // Get the Fx flag if(!item.getValueByName(HasFx, "3d.has_fx")) debug("key '3d.has_fx' not found."); // Get special Effect1 string Effect1; if(!item.getValueByName(Effect1, "Effects.Effect1")) debug("key 'Effects.Effect1' not found."); Effect1 = strlwr(Effect1); IdEffect1 = ClientSheetsStrings.add(Effect1); // Get special Effect2 string Effect2; if(!item.getValueByName(Effect2, "Effects.Effect2")) debug("key 'Effects.Effect2' not found."); Effect2 = strlwr(Effect2); IdEffect2 = ClientSheetsStrings.add(Effect2); // Get special Effect3 string Effect3; if(!item.getValueByName(Effect3, "Effects.Effect3")) debug("key 'Effects.Effect3' not found."); Effect3 = strlwr(Effect3); IdEffect3 = ClientSheetsStrings.add(Effect3); // Get special Effect4 string Effect4; if(!item.getValueByName(Effect4, "Effects.Effect4")) debug("key 'Effects.Effect4' not found."); Effect4 = strlwr(Effect4); IdEffect4 = ClientSheetsStrings.add(Effect4); // Get its bulk TRANSLATE_VAL( Bulk, "basics.Bulk" ); // Get its equip time TRANSLATE_VAL( EquipTime, "basics.Time to Equip In Ticks" ); // build fx part FX.build(item, "3d.fx."); // **** Build Help Infos string val; TRANSLATE_ENUM( RequiredCharac, CHARACTERISTICS::Unknown, CHARACTERISTICS::toCharacteristic, "basics.RequiredCharac"); TRANSLATE_VAL( RequiredCharacLevel, "basics.MinRequiredCharacLevel"); TRANSLATE_ENUM( RequiredSkill, SKILLS::unknown, SKILLS::toSkill, "basics.RequiredSkill"); TRANSLATE_VAL( RequiredSkillLevel, "basics.MinRequiredSkillLevel"); // item Origin TRANSLATE_ENUM ( ItemOrigin, ITEM_ORIGIN::UNKNOWN, ITEM_ORIGIN::stringToEnum, "basics.origin"); /// item craft plan TRANSLATE_VAL( val, "basics.CraftPlan" ); if (!val.empty()) CraftPlan = CSheetId(val); // Special according to Family; switch(Family) { // COSMETIC case ITEMFAMILY::COSMETIC : { string sheetName = Id.toString(); string::size_type pos = sheetName.find('.',0); if (pos == string::npos) nlwarning(" Can't load the VPValue from sheet name in sheet %s", Id.toString().c_str() ); else { sint i = (sint)pos - 1; for(; i >= 0; i-- ) { if ( !isdigit( sheetName[i] ) ) break; } if ( i >= -1 ) { string val = sheetName.substr( i + 1, pos - i - 1); NLMISC::fromString( val, Cosmetic.VPValue ); } } if ( sheetName.find( "hof" ) != string::npos ) Cosmetic.Gender = GSGENDER::female; else Cosmetic.Gender = GSGENDER::male; } break; // ARMOR case ITEMFAMILY::ARMOR : { // ArmorType TRANSLATE_ENUM ( Armor.ArmorType, ARMORTYPE::UNKNOWN, ARMORTYPE::toArmorType, "armor.Armor category" ); } break; // MELEE_WEAPON case ITEMFAMILY::MELEE_WEAPON : { // WeaponType TRANSLATE_ENUM ( MeleeWeapon.WeaponType, WEAPONTYPE::UNKNOWN, WEAPONTYPE::stringToWeaponType, "melee weapon.category" ); // Skill TRANSLATE_ENUM ( MeleeWeapon.Skill, SKILLS::unknown, SKILLS::toSkill, "melee weapon.skill" ); // DamageType TRANSLATE_ENUM ( MeleeWeapon.DamageType, DMGTYPE::UNDEFINED, DMGTYPE::stringToDamageType, "melee weapon.damage type" ); // DamageType TRANSLATE_VAL ( MeleeWeapon.MeleeRange, "melee weapon.melee range" ); } break; // RANGE_WEAPON case ITEMFAMILY::RANGE_WEAPON : { // WeaponType TRANSLATE_ENUM ( RangeWeapon.WeaponType, WEAPONTYPE::UNKNOWN, WEAPONTYPE::stringToWeaponType, "range weapon.category" ); // Range weapon type TRANSLATE_ENUM ( RangeWeapon.RangeWeaponType, RANGE_WEAPON_TYPE::Generic, RANGE_WEAPON_TYPE::stringToRangeWeaponType, "range weapon.RangeWeaponType" ); // Skill TRANSLATE_ENUM ( RangeWeapon.Skill, SKILLS::unknown, SKILLS::toSkill, "range weapon.skill" ); } break; // AMMO case ITEMFAMILY::AMMO : { // Skill TRANSLATE_ENUM ( Ammo.Skill, SKILLS::unknown, SKILLS::toSkill, "ammo.weapon type" ); // DamageType TRANSLATE_ENUM ( Ammo.DamageType, DMGTYPE::UNDEFINED, DMGTYPE::stringToDamageType, "ammo.damage type" ); // Magazine TRANSLATE_VAL( Ammo.Magazine, "ammo.magazine" ); } break; // RAW_MATERIAL case ITEMFAMILY::RAW_MATERIAL : { // Ecosystem TRANSLATE_ENUM( Mp.Ecosystem, ECOSYSTEM::unknown, ECOSYSTEM::stringToEcosystem, "mp.Ecosystem" ); // MpCategory TRANSLATE_ENUM( Mp.MpCategory, MP_CATEGORY::Undefined, MP_CATEGORY::stringToMPCategory, "mp.Category" ); // Skill TRANSLATE_ENUM( Mp.HarvestSkill, SKILLS::unknown, SKILLS::toSkill, "mp.HarvestSkill" ); // MP Family TRANSLATE_VAL( Mp.Family, "mp.Family" ); // Faber Item Part uint i; char keyTmp[256]; // ensure that if you modify RM_FABER_TYPE, you have to rebuild the item sheets. nlctassert(RM_FABER_TYPE::NUM_FABER_TYPE == 26); // ensure that the bitfields are enough (nb: unknown can be stored) nlctassert(ITEM_ORIGIN::NUM_ITEM_ORIGIN < 256); // ensure that the bitfield for item part buildable for this MP is possible nlctassert(RM_FABER_TYPE::NUM_FABER_TYPE <= 32); // reset Mp.ItemPartBF= 0; MpItemParts.clear(); // check if ok for each for(i=0;i ok if(DropOrSell) return true; // still can give any item to bot chat return botChatGift; } // *************************************************************************** void CItemSheet::getItemPartListAsText(ucstring &ipList) const { bool all= true; for(uint i=0;i