diff --git a/ryzom/server/src/entities_game_service/egs_sheets/egs_static_brick.cpp b/ryzom/server/src/entities_game_service/egs_sheets/egs_static_brick.cpp index a287a8721..fade8142d 100644 --- a/ryzom/server/src/entities_game_service/egs_sheets/egs_static_brick.cpp +++ b/ryzom/server/src/entities_game_service/egs_sheets/egs_static_brick.cpp @@ -1702,6 +1702,15 @@ void addParam(const std::string ¶mStr, std::vector &Par // $*STRUCT CSBrickParamConsumeItem TBrickParam::TA_CONSUME Params.push_back(new CSBrickParamConsumeItem(tail)); break; + + case TBrickParam::JEWEL_ATTRS: + // $*STRUCT CSBrickParamJewelAttrs TBrickParam::JEWEL_ATTRS + // $*-s std::string Attribute // attribute name + // $*-s std::string Value // attribute value + // $*-i uint32 Charge // initial charge of sapload + // $*-i uint32 Modifier // onus on attribute + Params.push_back(new CSBrickParamJewelAttrs(tail)); + break; } } // addParam // diff --git a/ryzom/server/src/entities_game_service/egs_sheets/egs_static_brick.cpp.h b/ryzom/server/src/entities_game_service/egs_sheets/egs_static_brick.cpp.h index 2a2946bcf..2f06d7982 100644 --- a/ryzom/server/src/entities_game_service/egs_sheets/egs_static_brick.cpp.h +++ b/ryzom/server/src/entities_game_service/egs_sheets/egs_static_brick.cpp.h @@ -168,6 +168,7 @@ public: TA_MOUNT, TA_UNMOUNT, TA_CONSUME, + JEWEL_ATTRS, NUM_VALUES, BAD_VALUE= NUM_VALUES }; @@ -347,6 +348,7 @@ public: if (copyOfStr=="ta_mount") {_Value=TA_MOUNT; return *this;} if (copyOfStr=="ta_unmount") {_Value=TA_UNMOUNT; return *this;} if (copyOfStr=="ta_consume") {_Value=TA_CONSUME; return *this;} + if (copyOfStr=="jewel_attrs") {_Value=JEWEL_ATTRS; return *this;} _Value=BAD_VALUE; return *this; @@ -5174,6 +5176,58 @@ struct CSBrickParamCharacUpgrade : public TBrickParam::IId } }; +struct CSBrickParamJewelAttrs : public TBrickParam::IId +{ + // attribute name + std::string Attribute; + // attribute value + std::string Value; + // initial charge of sapload + uint32 Charge; + // bonus on attribute + uint32 Modifier; + // required Faction + std::string RequiredFaction; + + CSBrickParamJewelAttrs(): + Attribute(), + Value(), + Charge(), + Modifier(), + RequiredFaction() + + { + _Id = TBrickParam::JEWEL_ATTRS; + } + + CSBrickParamJewelAttrs(const std::string&str) + { + *this=CSBrickParamJewelAttrs(); + *this=str; + } + + const CSBrickParamJewelAttrs& operator=(const std::string& input) + { + std::vector args; + convertInput(args, input); + + if (args.size() < 4) + return *this; + + ParsedOk=true; + Attribute=args[0].c_str(); + Value=args[1].c_str(); + NLMISC::fromString(args[2], Charge); + NLMISC::fromString(args[3], Modifier); + if (args.size() > 4) + RequiredFaction = args[4].c_str(); + else + RequiredFaction = ""; + + return *this; + } +}; + struct CSBrickParamScoreUpgrade : public TBrickParam::IId { diff --git a/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp b/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp index eccc881e7..f502b354a 100644 --- a/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp +++ b/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp @@ -711,6 +711,7 @@ void finalizeClientReady( uint32 userId, uint32 index ) if (c->invulnerableMode()) c->setBonusMalusName("invulnerability", c->addEffectInDB(CSheetId("invulnerability.sbrick"), true)); + c->updateJewelsTags(false); c->setFinalized(true); diff --git a/ryzom/server/src/entities_game_service/game_item_manager/player_inv_equip.cpp b/ryzom/server/src/entities_game_service/game_item_manager/player_inv_equip.cpp index f83a5eacc..9d9638919 100644 --- a/ryzom/server/src/entities_game_service/game_item_manager/player_inv_equip.cpp +++ b/ryzom/server/src/entities_game_service/game_item_manager/player_inv_equip.cpp @@ -22,6 +22,9 @@ #include "player_manager/character.h" #include "egs_sheets/egs_sheets.h" +using namespace NLMISC; +using namespace std; + extern NLMISC::CVariable MaxPlayerBulk; ///////////////////////////////////////////////////////////// @@ -118,6 +121,9 @@ void CEquipInvView::onItemChanged(uint32 slot, INVENTORIES::TItemChangeFlags cha } } } + + // Update tags + getCharacter()->updateJewelsTags(false); } // **************************************************************************** diff --git a/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp b/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp index b5797331c..891ec373c 100644 --- a/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp +++ b/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp @@ -1013,6 +1013,40 @@ NLMISC_COMMAND(deleteInventoryItems, "Delete items from a characters inventory", return true; } +//---------------------------------------------------------------------------- +NLMISC_COMMAND(enchantItem, "enchantItem", " ,[ ...]") +{ + if (args.size () < 3) + { + log.displayNL("ERR: Invalid number of parameters. Parameters: "); + return false; + } + + GET_ACTIVE_CHARACTER + + string selected_slot = args[1]; + + std::vector sheet_names; + NLMISC::splitString(args[2], ",", sheet_names); + + std::vector sheets; + for (uint32 i=0; igetItem(INVENTORIES::equipment, SLOT_EQUIPMENT::stringToSlotEquipment(selected_slot)); + if (itemPtr != NULL) + { + itemPtr->applyEnchantment(sheets); + log.displayNL("OK"); + return true; + } + log.displayNL("KO"); + return true; +} + + //---------------------------------------------------------------------------- diff --git a/ryzom/server/src/entities_game_service/player_manager/character.cpp b/ryzom/server/src/entities_game_service/player_manager/character.cpp index 349b9e1a3..0fef6abce 100644 --- a/ryzom/server/src/entities_game_service/player_manager/character.cpp +++ b/ryzom/server/src/entities_game_service/player_manager/character.cpp @@ -1621,11 +1621,9 @@ uint32 CCharacter::tickUpdate() if (_LastTickNpcStopped && CTickEventHandler::getGameCycle() > _LastTickNpcStopped) { - nlinfo("ULU: CTickEventHandler::getGameCycle() > _LastTickNpcStopped"); TDataSetRow stoppedNpc = getStoppedNpc(); if (TheDataset.isAccessible(stoppedNpc)) { - nlinfo("ULU: stop bot"); CharacterBotChatBeginEnd.BotChatEnd.push_back(getEntityRowId()); CharacterBotChatBeginEnd.BotChatEnd.push_back(stoppedNpc); } @@ -11705,6 +11703,74 @@ void CCharacter::setDontTranslate(const string &langs) _DontTranslate = langs; } + +//----------------------------------------------------------------------------- +CSBrickParamJewelAttrs *CCharacter::getJewelAttrs(const string &attribute, SLOT_EQUIPMENT::TSlotEquipment slot) +{ + + CInventoryPtr inv = getInventory(INVENTORIES::equipment); + if (inv) + { + if (slot == SLOT_EQUIPMENT::UNDEFINED) + { + for( uint8 s = 0; s < SLOT_EQUIPMENT::NB_SLOT_EQUIPMENT; ++s ) + { + const CGameItemPtr item = inv->getItem(s); + if (item != NULL) + { + vector< CSheetId > enchant = item->getEnchantment(); + for (uint i = 0; i < enchant.size(); i++) + { + const CStaticBrick * brick = CSheets::getSBrickForm(enchant[i]); + if (brick && brick->Family == BRICK_FAMILIES::BSGMC) + { + if (brick->Params.size() > 0) + { + const TBrickParam::IId* param = brick->Params[0]; + CSBrickParamJewelAttrs *sbrickParam = (CSBrickParamJewelAttrs*)param; + if (param->id() == TBrickParam::JEWEL_ATTRS && sbrickParam->Attribute == attribute) + { + if (checkRequiredFaction(sbrickParam->RequiredFaction)) { + return sbrickParam; + } + } + } + } + } + } + } + } + else + { + const CGameItemPtr item = inv->getItem(slot); + if (item != NULL) + { + vector< CSheetId > enchant = item->getEnchantment(); + for (uint i = 0; i < enchant.size(); i++) + { + const CStaticBrick * brick = CSheets::getSBrickForm(enchant[i]); + if (brick && brick->Family == BRICK_FAMILIES::BSGMC) + { + if (brick->Params.size() > 0) + { + const TBrickParam::IId* param = brick->Params[0]; + CSBrickParamJewelAttrs *sbrickParam = (CSBrickParamJewelAttrs*)param; + if (param->id() == TBrickParam::JEWEL_ATTRS && sbrickParam->Attribute == attribute) + { + if (checkRequiredFaction(sbrickParam->RequiredFaction)) { + return sbrickParam; + } + } + } + } + } + } + } + } + + return NULL; +} + //----------------------------------------------------------------------------- void CCharacter::setOrganization(uint32 org) { @@ -11718,6 +11784,8 @@ void CCharacter::setOrganization(uint32 org) CBankAccessor_PLR::getUSER().getRRPS_LEVELS(2).setVALUE(_PropertyDatabase, _OrganizationStatus); CBankAccessor_PLR::getUSER().getRRPS_LEVELS(3).setVALUE(_PropertyDatabase, _OrganizationPoints); CPVPManager2::getInstance()->updateFactionChannel(this); + + updateJewelsTags(false); } //----------------------------------------------------------------------------- @@ -20092,6 +20160,7 @@ bool CCharacter::setDeclaredCult(PVP_CLAN::TPVPClan newClan) updatePVPClanVP(); // update ring database IShardUnifierEvent::getInstance()->onUpdateCharAllegiance(_Id, _DeclaredCult, _DeclaredCiv); + updateJewelsTags(false); return true; } @@ -20152,6 +20221,7 @@ bool CCharacter::setDeclaredCiv(PVP_CLAN::TPVPClan newClan) updatePVPClanVP(); // update ring database IShardUnifierEvent::getInstance()->onUpdateCharAllegiance(_Id, _DeclaredCult, _DeclaredCiv); + updateJewelsTags(false); return true; } @@ -21123,6 +21193,37 @@ void CCharacter::updateParry(ITEMFAMILY::EItemFamily family, SKILLS::ESkills ski _PropertyDatabase, checkedCast(_CurrentParryLevel)); } +//---------------------------------------------------------------------------- +void CCharacter::updateJewelsTags(bool remove) +{ + if (!getEnterFlag()) + return; + + string tagA = getTagA(); + string tagB = getTagB(); + + setTagA(""); + setTagB(""); + + if (remove) + return; + + CSBrickParamJewelAttrs *sbrickParam = getJewelAttrs("tag", SLOT_EQUIPMENT::HEADDRESS); + if (sbrickParam) + { + setTagA(sbrickParam->Value); + } + + sbrickParam = getJewelAttrs("tag", SLOT_EQUIPMENT::NECKLACE); + if (sbrickParam) + { + setTagB(sbrickParam->Value); + } + + if (getTagA() != tagA || getTagB() != tagB) + registerName(); +} + //---------------------------------------------------------------------------- void CCharacter::updateMagicProtectionAndResistance() { @@ -22547,7 +22648,6 @@ void CCharacter::setStoppedNpc(const TDataSetRow &npc) void CCharacter::setStoppedNpcTick() { - nlinfo("ULU: setStopNpcTick in 60s"); _LastTickNpcStopped = CTickEventHandler::getGameCycle() + 10*60; } diff --git a/ryzom/server/src/entities_game_service/player_manager/character.h b/ryzom/server/src/entities_game_service/player_manager/character.h index fdc7e4a63..b66c932a3 100644 --- a/ryzom/server/src/entities_game_service/player_manager/character.h +++ b/ryzom/server/src/entities_game_service/player_manager/character.h @@ -2422,6 +2422,9 @@ public: /// update parry skill and level void updateParry(ITEMFAMILY::EItemFamily family, SKILLS::ESkills skill); + // Jewel enchants used for Tags + void updateJewelsTags(bool remove); + // Jewel equipment or skill or region are changed, recompute protection and resistances void updateMagicProtectionAndResistance(); @@ -2582,6 +2585,8 @@ public: std::string getFullTitle() const; + bool checkRequiredFaction(std::string faction) const; + std::string getTagA() const; void setTagA(const std::string &tag); @@ -2597,6 +2602,8 @@ public: std::string getDontTranslate() const; void setDontTranslate(const std::string &langs); + CSBrickParamJewelAttrs *getJewelAttrs(const std::string &attribute, SLOT_EQUIPMENT::TSlotEquipment slot); + uint32 getOrganization() const; uint32 getOrganizationStatus() const; uint32 getLastTpTick() const; diff --git a/ryzom/server/src/entities_game_service/player_manager/character_inlines.h b/ryzom/server/src/entities_game_service/player_manager/character_inlines.h index 1b2261da8..43e7a8f0e 100644 --- a/ryzom/server/src/entities_game_service/player_manager/character_inlines.h +++ b/ryzom/server/src/entities_game_service/player_manager/character_inlines.h @@ -1013,6 +1013,28 @@ inline std::string CCharacter::getFullTitle() const return _NewTitle; } +inline bool CCharacter::checkRequiredFaction(std::string faction) const +{ + if (faction == "") + return true; + + std::pair allegeance = getAllegiance(); + bool neutralcult = (allegeance.first == PVP_CLAN::Neutral || allegeance.first == PVP_CLAN::None); + bool neutralciv = (allegeance.second == PVP_CLAN::Neutral || allegeance.second == PVP_CLAN::None); + + return ((faction == "kami" && allegeance.first == PVP_CLAN::Kami && getOrganization() == 0) || + (faction == "karavan" && allegeance.first == PVP_CLAN::Karavan && getOrganization() == 0) || + (faction == "marauder" && neutralcult && neutralciv && getOrganization() == 5) || + (faction == "ranger" && neutralcult && neutralciv && getOrganization() == 7) || + (faction == "neutralcult" && neutralcult && getOrganization() == 0) || + (faction == "neutralciv" && neutralciv && getOrganization() == 0) || + (faction == "neutral" && neutralcult && neutralciv && getOrganization() == 0) || + (faction == "fyros" && allegeance.second == PVP_CLAN::Fyros && getOrganization() == 0) || + (faction == "matis" && allegeance.second == PVP_CLAN::Matis && getOrganization() == 0) || + (faction == "tryker" && allegeance.second == PVP_CLAN::Tryker && getOrganization() == 0) || + (faction == "zorai" && allegeance.second == PVP_CLAN::Zorai && getOrganization() == 0)); +} + //------------------------------------------------------------------------------ inline uint32 CCharacter::getOrganization() const