diff --git a/code/nel/tools/3d/panoply_maker/panoply_maker.cpp b/code/nel/tools/3d/panoply_maker/panoply_maker.cpp index 80aabfaba..e3770ec67 100644 --- a/code/nel/tools/3d/panoply_maker/panoply_maker.cpp +++ b/code/nel/tools/3d/panoply_maker/panoply_maker.cpp @@ -669,7 +669,7 @@ static void BuildColoredVersionForOneBitmap(const CBuildInfo &bi, const std::str // we can save it as RGB to optimize it if (bi.OptimizeTextures > 0 && depth == 32) { - uint32 size = srcBitmap.getSize(0); + uint32 size = srcBitmap.getPixels().size(); if (size > 0) { diff --git a/code/ryzom/common/src/game_share/base_types.h b/code/ryzom/common/src/game_share/base_types.h index b1b0dc1e5..1440c0974 100644 --- a/code/ryzom/common/src/game_share/base_types.h +++ b/code/ryzom/common/src/game_share/base_types.h @@ -239,7 +239,7 @@ public: CHashCode() {} - enum { bucket_size = 4, min_buckets = 8, }; + enum { bucket_size = 4, min_buckets = 8 }; size_t operator () ( const TDataSetRow &index ) const { return index.getHashCode(); } diff --git a/code/ryzom/server/src/ai_share/primitive_parser.cpp b/code/ryzom/server/src/ai_share/primitive_parser.cpp index dd52b4d7a..7b5a6a18e 100644 --- a/code/ryzom/server/src/ai_share/primitive_parser.cpp +++ b/code/ryzom/server/src/ai_share/primitive_parser.cpp @@ -4176,7 +4176,7 @@ NLMISC_COMMAND(loadMap,"load a complete set of primitive files","") // check that the continent is active CUsedContinent &uc = CUsedContinent::instance(); uint32 in = uc.getInstanceForContinent(continentName); - if (in == INVALID_AI_INSTANCE) + if (in == std::numeric_limits::max()) { log.displayNL("loadMap : while loading map '%s', can't load primitive '%s' coz continent '%s' is not active", args[0].c_str(), @@ -4216,7 +4216,7 @@ NLMISC_COMMAND(unloadMap,"unload a complete set of primitive files","" // check that the continent is active CUsedContinent &uc = CUsedContinent::instance(); uint32 in = uc.getInstanceForContinent(continentName); - if (in == INVALID_AI_INSTANCE) + if (in == std::numeric_limits::max()) { log.displayNL("unloadMap : while loading map '%s', can't load primitive '%s' coz continent '%s' is not active", args[0].c_str(), diff --git a/code/ryzom/server/src/entities_game_service/admin.cpp b/code/ryzom/server/src/entities_game_service/admin.cpp index 302adf245..e92657c3e 100644 --- a/code/ryzom/server/src/entities_game_service/admin.cpp +++ b/code/ryzom/server/src/entities_game_service/admin.cpp @@ -37,6 +37,7 @@ #include "nel/misc/eid_translator.h" #include "nel/misc/algo.h" #include "nel/misc/sstring.h" +#include "nel/misc/i18n.h" #include "nel/net/admin.h" #include "nel/net/service.h" @@ -61,6 +62,7 @@ #include "player_manager/player.h" #include "player_manager/character.h" #include "player_manager/character_encyclopedia.h" +#include "player_manager/player_room.h" #include "creature_manager/creature_manager.h" #include "phrase_manager/phrase_manager.h" #include "mission_manager/mission_manager.h" @@ -420,7 +422,7 @@ bool getAIInstanceFromGroupName(string& groupName, uint32& instanceNumber) { string continent = groupName.substr(0, groupName.find('@')); uint32 nr = CUsedContinent::instance().getInstanceForContinent(continent); - if (nr == INVALID_AI_INSTANCE) + if (nr == std::numeric_limits::max()) { return false; } @@ -705,6 +707,38 @@ void initSalt() } } +string getStringFromHash(const string &hash) +{ + ucstring finaltext; + getUCstringFromHash(hash, finaltext); + + return finaltext.toUtf8(); +} + +void getUCstringFromHash(const string &hash, ucstring &finaltext) +{ + string fullhash = hash; + // fill hash with space to be a *2 + if (hash.size() % 2) + { + fullhash += " "; + } + + // cut hash in portion of 4 + for (uint i=0; iaddOfflineCommandWithoutApply( command ); } -#define GET_ENTITY \ - if (args.size() < 1) { nlwarning ("Missing argument number 0 that should be the eid"); return false; } \ - CEntityId eid(args[0]); \ - if (eid == CEntityId::Unknown) \ - return true; \ - TLogContext_Character_AdminCommand commandContext(eid); \ - CEntityBase *e = CEntityBaseManager::getEntityBasePtr(eid); \ - if(e == 0) \ - { \ - nlwarning ("Unknown entity '%s'", eid.toString().c_str()); \ - return true; \ - } \ - if(!TheDataset.isAccessible(e->getEntityRowId())) \ - { \ - nlwarning ("'%s' is not valid in mirror", eid.toString().c_str()); \ - return true; \ - } - #define TRY_GET_CHARACTER \ if (args.size() < 1) { nlwarning ("Missing argument number 0 that should be the eid"); return false; } \ CEntityId eid(args[0]); \ @@ -1142,7 +1158,7 @@ ENTITY_VARIABLE (Priv, "User privilege") ENTITY_GET_CHARACTER CPlayer *p = PlayerManager.getPlayer(PlayerManager.getPlayerId(c->getId())); - if (p == 0) + if (p == NULL) { nlwarning ("Can't find player with UserId %d for checking privilege, assume no priv", PlayerManager.getPlayerId(c->getId())); return; @@ -1227,6 +1243,17 @@ ENTITY_VARIABLE(Position, "Position of a player (in meter) ,[, z *= 1000; } } + else if ( value.find('@') != string::npos ) + { + x = e->getState().X(); + y = e->getState().Y(); + z = e->getState().Z(); + explode (value, string("@"), res); + if (res.size() == 1) + { + fromString(res[0], cell); + } + } else { if ( value.find(".creature") != string::npos ) @@ -1274,7 +1301,7 @@ ENTITY_VARIABLE(Position, "Position of a player (in meter) ,[, return; } CEntityBase *entityBase = PlayerManager.getCharacterByName (CShardNames::getInstance().makeFullNameFromRelative(c->getHomeMainlandSessionId(), value)); - if (entityBase == 0) + if (entityBase == NULL) { // try to find the bot name vector aliases; @@ -1299,7 +1326,7 @@ ENTITY_VARIABLE(Position, "Position of a player (in meter) ,[, } } - if (entityBase != 0) + if (entityBase != NULL) { x = entityBase->getState().X + sint32 (cos (entityBase->getState ().Heading) * 2000); y = entityBase->getState().Y + sint32 (sin (entityBase->getState ().Heading) * 2000); @@ -1462,7 +1489,7 @@ NLMISC_COMMAND (createItemInBag, "Create an item and put it in the player bag", } const CStaticItem *form = CSheets::getForm (sheet); - if (form == 0) + if (form == NULL) { log.displayNL ("sheetId '%s' is not found", sheetName.c_str()); return false; @@ -1546,7 +1573,7 @@ NLMISC_COMMAND (createItemInTmpInv, "Create an item and put it in the player tem } const CStaticItem *form = CSheets::getForm (sheet); - if (form == 0) + if (form == NULL) { log.displayNL ("sheetId '%s' is not found", sheetName.c_str()); return false; @@ -1613,7 +1640,7 @@ NLMISC_COMMAND (createItemInInv, "Create items and put them in the given invento } const CStaticItem *form = CSheets::getForm (sheet); - if (form == 0) + if (form == NULL) { log.displayNL ("sheetId '%s' is not found", sheetName.c_str()); return false; @@ -3047,12 +3074,12 @@ void cbClientAdmin (NLNET::CMessage& msgin, const std::string &serviceName, NLNE CSString cmdName, arg; msgin.serial (cmdName, arg); - nlinfo("ADMIN: Executing admin command: eid=%s onTarget=%s cmdName=%s arg=%s",eid.toString().c_str(),onTarget?"true":"false",cmdName.quote().c_str(),arg.quote().c_str()); + //nlinfo("ADMIN: Executing admin command: eid=%s onTarget=%s cmdName=%s arg=%s",eid.toString().c_str(),onTarget?"true":"false",cmdName.quote().c_str(),arg.quote().c_str()); TLogContext_Command_ExecCtx logContext(eid); // find the character CCharacter *c = PlayerManager.getChar( eid ); - if (c == 0) + if (c == NULL) { nlwarning ("ADMIN: Unknown player %s", eid.toString().c_str()); chatToPlayer (eid, "Unknown player"); @@ -3150,14 +3177,12 @@ void cbClientAdmin (NLNET::CMessage& msgin, const std::string &serviceName, NLNE TLogContext_Character_BuyRolemasterPhrase characterCtx(onTarget ? c->getTarget() : eid); std::string csName = CEntityIdTranslator::getInstance()->getByEntity(eid).toString(); - NLMISC::CSString cs_res = CSString(res); - cs_res = cs_res.replace("#player", eid.toString().c_str()); + strFindReplace(res, "#player", eid.toString().c_str()); if (c->getTarget() != CEntityId::Unknown) { - cs_res = cs_res.replace("#target", c->getTarget().toString().c_str()); - cs_res = cs_res.replace("#gtarget", string("#"+c->getTarget().toString()).c_str()); + strFindReplace(res, "#target", c->getTarget().toString().c_str()); + strFindReplace(res, "#gtarget", string("#"+c->getTarget().toString()).c_str()); } - res = (string)cs_res; nlinfo ("ADMIN: Player (%s,%s) will execute client admin command '%s' on target %s", eid.toString().c_str(), csName.c_str(), res.c_str(), targetName.c_str()); audit(cmd, res, eid, csName, targetName); @@ -3200,7 +3225,7 @@ void cbClientAdminOffline (NLNET::CMessage& msgin, const std::string &serviceNam // find the character CCharacter *c = PlayerManager.getChar( eid ); - if (c == 0) + if (c == NULL) { nlwarning ("ADMIN: Unknown player %s", eid.toString().c_str()); chatToPlayer (eid, "Unknown player"); @@ -3673,7 +3698,7 @@ NLMISC_COMMAND( killMob, "kill a mob ( /a killMob )", "" ) TRY_GET_CHARACTER CCreature * creature = CreatureManager.getCreature( c->getTarget() ); - if( creature == 0 ) + if (creature == NULL) { nlwarning ("Unknown creature '%s'", c->getTarget().toString().c_str() ); return false; @@ -3705,7 +3730,7 @@ NLMISC_COMMAND( dssTarget, "target a mob and send information to dss( /b dssTarg TRY_GET_CHARACTER CCreature * creature = CreatureManager.getCreature( c->getTarget() ); - if( creature == 0 ) + if (creature == NULL) { nlwarning ("Unknown creature '%s'", c->getTarget().toString().c_str() ); return false; @@ -4558,7 +4583,7 @@ NLMISC_COMMAND (connectUserChannel, "Connect to user channels", " ") +NLMISC_COMMAND (connectLangChannel, "Connect to lang channel", " ") { if ((args.size() < 2) || (args.size() > 3)) return false; @@ -4570,17 +4595,26 @@ NLMISC_COMMAND (connectLangChannel, "Connect to lang channel", " string lang = args[1]; if (lang != "en" && lang != "fr" && lang != "de" && lang != "ru" && lang != "es") return false; - + bool leave = false; + if (args.size() > 2) + leave = args[2] == "1"; TChanID channel = inst->getFactionDynChannel(lang); if (channel != DYN_CHAT_INVALID_CHAN) { - if (!c->getLangChannel().empty()) { - TChanID current_channel = inst->getFactionDynChannel(c->getLangChannel()); - inst->removeFactionChannelForCharacter(current_channel, c); + string current_channels = c->getLangChannel(); + if (leave) + { + strFindReplace(current_channels, lang+" ", ""); + strFindReplace(current_channels, " "+lang, ""); + inst->removeFactionChannelForCharacter(channel, c); + c->setLangChannel(current_channels); + } + else if (current_channels.find(lang) == string::npos) + { + inst->addFactionChannelToCharacter(channel, c, true); + c->setLangChannel(current_channels + " "+lang); } - inst->addFactionChannelToCharacter(channel, c, true); - c->setLangChannel(lang); return true; } @@ -4683,7 +4717,7 @@ CInventoryPtr getInv(CCharacter *c, const string &inv) return inventoryPtr; } -NLMISC_COMMAND (webExecCommand, "Execute a web command", " [] [] []") +NLMISC_COMMAND (webExecCommand, "Execute a web command", " [] [] []") { if (args.size() < 5) @@ -4709,7 +4743,14 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " = 8 && args[7] == "1") send_url = true; - c->setAfkState(false); + bool save_index = false; + if (args.size() >= 8 && args[7] == "2") + { + send_url = true; + save_index = true; + } + + c->setAfkState(false); string web_app_url = args[1]; string index = args[2]; @@ -4724,7 +4765,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getWebCommandIndex(); - if (iindex <= saved_index) + if (iindex <= saved_index && command != "is_valid_index") { // Index of command must be higher than last used index to prevent re-use of commands if (send_url) @@ -4741,10 +4782,12 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getLastConnectedDate()) + index + command + c->getId().toString(); + string checksumRowId = web_app_url + toString(c->getLastConnectedDate()) + index + command + toString(c->getEntityRowId().getIndex()); + string realhmacEid = getHMacSHA1((uint8*)&checksumEid[0], checksumEid.size(), (uint8*)&salt[0], salt.size()).toString(); string realhmacRowId = getHMacSHA1((uint8*)&checksumRowId[0], checksumRowId.size(), (uint8*)&salt[0], salt.size()).toString(); - if (realhmacEid != hmac && realhmacRowId != hmac) + if (realhmacEid != hmac && realhmacRowId != hmac && command != "is_valid_index") { if (send_url) c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=bad_auth", getSalt()); @@ -4776,6 +4819,21 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getByEntity(c->getId()).toString(); + nlinfo("(%s ,%s) %s[%s]%d", c->getId().toString().c_str(), pName.c_str(), web_app_url.c_str(), command.c_str(), iindex); + + if (command == "is_valid_index") + { + if (!c->isValidWebCommandIndex(iindex)) { + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=unvalid_index", getSalt()); + } + else + { + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=finished&desc=valid_index", getSalt()); + } + return true; + } + std::vector command_args; if (new_separator) NLMISC::splitString(command, "|", command_args); @@ -4785,7 +4843,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " = 5) selected_inv = command_args[4]; CInventoryPtr inventory = getInv(c, selected_inv); @@ -4817,20 +4875,28 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " = 6) + selected_inv = command_args[5]; + + uint32 numberEqualItem = 0; uint32 numberItem = 0; - for( uint32 i = 0; i < inventory->getSlotCount(); ++ i) + for ( uint32 i = 0; i < inventory->getSlotCount(); ++ i) { const CGameItemPtr itemPtr = inventory->getItem(i); if ( itemPtr != NULL ) { - if ( (itemPtr->getSheetId() == sheetId) && (itemPtr->quality() == quality) ) + if ( (itemPtr->getSheetId() == sheetId) ) { - numberItem += itemPtr->getStackSize(); + if (itemPtr->quality() == quality) + numberEqualItem += itemPtr->getStackSize(); + if (itemPtr->quality() >= quality) + numberItem += itemPtr->getStackSize(); } } } - if (numberItem < quantity) + if ( (is_min_quality && numberItem < quantity) || (!is_min_quality && numberEqualItem < quantity) ) { if (send_url) c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=no_items", getSalt()); @@ -4838,16 +4904,26 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getSlotCount(); ++ i) + numberEqualItem = quantity; + for(uint32 i = 0; i < inventory->getSlotCount(); ++i) { const CGameItemPtr itemPtr = inventory->getItem(i); if ( itemPtr != NULL ) { - if ( (itemPtr->getSheetId() == sheetId) && (itemPtr->quality() == quality) ) + if ( (itemPtr->getSheetId() == sheetId) ) { - numberItem -= inventory->deleteStackItem(i, quantity); - if(numberItem == 0) - break; + if (is_min_quality && itemPtr->quality() >= quality) + { + numberEqualItem -= inventory->deleteStackItem(i, quantity); + if(numberEqualItem == 0) + break; + } + else if (!is_min_quality && itemPtr->quality() == quality) + { + numberItem -= inventory->deleteStackItem(i, quantity); + if(numberItem == 0) + break; + } } } } @@ -4857,7 +4933,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getInventory(inventory); + for( uint32 i = 0; i < selected_inv->getSlotCount(); ++ i ) + { + const CGameItemPtr itemPtr = selected_inv->getItem(i); + if( itemPtr != NULL ) + { + if( itemPtr->getSheetId() == sheetId && itemPtr->quality() == quality ) + { + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=allready_have_item", getSalt()); + return false; + } + } + } + } + new_item = c->createItem(quality, quantity, sheetId); } + if (new_item == NULL) + return true; + if (!c->addItemToInventory(inventory, new_item)) { new_item.deleteItem(); @@ -4919,18 +5015,31 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " setCustomName(customValue); - } + ucstring customValue; - if (command_args.size() == 7 && command_args[6] != "*") - { - customValue.fromUtf8(command_args[6]); - new_item->setCustomText(customValue); + if (command_args.size() >= 6 && command_args[5] != "*") + { + customValue.fromUtf8(command_args[5]); + new_item->setCustomName(customValue); + } + + if (command_args.size() >= 7 && command_args[6] != "*") + { + customValue.fromUtf8(command_args[6]); + new_item->setCustomText(customValue); + } + + if (command_args.size() >= 8) + { + new_item->setMovable(command_args[7] == "1"); + } + + if (command_args.size() >= 9) + { + new_item->setUnMovable(command_args[8] == "1"); + } } } //************************************************* @@ -5000,7 +5109,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " %d", fame, value); } + if (command_args.size() == 4 || (command_args.size () == 5 && command_args[4] != "0")) + { + // Make sure fame values are properly capped. + CFameManager::getInstance().enforceFameCaps(c->getId(), c->getAllegiance()); + + // set tribe fame threshold and clamp fame if necessary + CFameManager::getInstance().setAndEnforceTribeFameCap(c->getId(), c->getAllegiance()); + } } //************************************************* @@ -5033,24 +5150,63 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getTarget(); - if (target == CEntityId::Unknown) - { - if (send_url) - c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=no_target", getSalt()); - return false; - } + + if (command_args.size () < 2) return false; - if (command_args[1] == "sheet") + if (command_args[1] == "leaguemate") { - if (target.getType() == RYZOMID::player) + if (target == CEntityId::Unknown || target.getType() != RYZOMID::player) { if (send_url) c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=bad_type", getSalt()); return false; } + CCharacter * targetTarget = dynamic_cast(CEntityBaseManager::getEntityBasePtr(target)); + if (targetTarget->getLeagueId() == DYN_CHAT_INVALID_CHAN || c->getLeagueId() != targetTarget->getLeagueId()) + { + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=bad_league", getSalt()); + return false; + } + } + else if (command_args[1] == "guildmate") + { + if (target == CEntityId::Unknown || target.getType() != RYZOMID::player) + { + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=bad_type", getSalt()); + return false; + } + CCharacter * targetTarget = dynamic_cast(CEntityBaseManager::getEntityBasePtr(target)); + if (targetTarget->getGuildId() == 0 || c->getGuildId() != targetTarget->getGuildId()) + { + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=bad_guild", getSalt()); + return false; + } + } + else if (command_args[1] == "teammate") + { + if (target == CEntityId::Unknown || target.getType() != RYZOMID::player) + { + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=bad_type", getSalt()); + return false; + } + CCharacter * targetTarget = dynamic_cast(CEntityBaseManager::getEntityBasePtr(target)); + if (targetTarget->getTeamId() == CTEAM::InvalidTeamId || c->getTeamId() != targetTarget->getTeamId()) + { + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=bad_team", getSalt()); + return false; + } + } + + if (command_args.size () < 3) return false; + + if (command_args[1] == "sheet") + { CSheetId creatureSheetId(command_args[2]); CCreature *creature = CreatureManager.getCreature(target); @@ -5063,7 +5219,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=bad_type", getSalt()); @@ -5090,7 +5246,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=bad_type", getSalt()); @@ -5148,7 +5304,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getSlotCount(); ++ i) { @@ -5188,16 +5348,33 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getSheetId() == sheetId) && (itemPtr->quality() == quality) ) { if (!crafted || itemPtr->getCreator() == c->getId()) - numberItem += itemPtr->getStackSize(); + { + if (needCustomName.empty() || itemPtr->getCustomName() == needCustomName) + { + numberItem += itemPtr->getStackSize(); + } + } } } } if (numberItem < quantity) { - if (send_url) - c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=no_items", getSalt()); - return false; + if (command_args[0] == "check_item") + { + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=no_items", getSalt()); + return false; + } + } + else + { + if (command_args[0] == "check_no_item") + { + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=have_items", getSalt()); + return false; + } } } @@ -5248,6 +5425,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getInstanceNumber(); sint32 x = c->getX(); sint32 y = c->getY(); + sint32 z = c->getZ(); sint32 orientation = 6666; // used to specify a random orientation uint32 nbBots; @@ -5298,22 +5476,50 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " 8) + { + if (command_args[8] != "*") { + NLMISC::fromString(command_args[7], z); } } std::string look; - if (command_args.size() > 8) + if (command_args.size() > 9) { - look = command_args[8]; - if (look.find(".creature") == string::npos) - look += ".creature"; + if (command_args[9] != "*") + { + look = command_args[9]; + if (look.find(".creature") == string::npos) + look += ".creature"; + } + } + + //[[inVillage=0/1][inOutpost=0/1][inStable=0/1][InAtys=0/1]] + std::string validation; + if (command_args.size() > 10) + { + validation = command_args[10]; + if (validation.length() == 4) + { + bool inVillage = validation[0] == '1'; + bool inOutpost = validation[1] == '1'; + bool inStable = validation[2] == '1'; + bool inAtys = validation[3] == '1'; + + if (!c->isSpawnValid(inVillage, inOutpost, inStable, inAtys)) + return false; + } + } // See if another AI instance has been specified @@ -5322,6 +5528,10 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getEntityRowId(); + CMirrorPropValueRO srcCell( TheDataset, dsr, DSPropertyCELL ); + sint32 cell = srcCell; + CEntityId playerId = c->getId(); CMessage msgout("EVENT_CREATE_NPC_GROUP"); @@ -5331,6 +5541,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " ForwardToservice.empty()) + { + // we need to forward the command to another service + if (IClientCommandForwader::getInstance()) + { + IClientCommandForwader::getInstance()->sendCommand(cmd->ForwardToservice, "renamePlayer", c->getId(), false, CEntityId::Unknown, arg); + } + } + } + //************************************************* //***************** set_tag //************************************************* @@ -5610,15 +5860,40 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getPvPRecentActionFlag() == false || c->getPVPFlag() == false); - if (command_args.size () > 3 && command_args[3] == "1" && !pvpValid) + + // Checks : PvP Flag, PvP Tag, Sitting, Water, Mount, Fear, Sleep, Invu, Stun + if (command_args.size () > 3) { - CCharacter::sendDynamicSystemMessage(c->getEntityRowId(), "PVP_TP_FORBIDEN"); - return true; + bool pvpFlagValid = (c->getPvPRecentActionFlag() == false || c->getPVPFlag() == false); + if (command_args[3][0] == '1' && !pvpFlagValid) { + CCharacter::sendDynamicSystemMessage(c->getEntityRowId(), "PVP_TP_FORBIDEN"); + return true; + } + + bool pvpTagValid = c->getPVPFlag() == false; + if (command_args[3].length() > 1 && command_args[3][1] == '1' && !pvpTagValid) + { + CCharacter::sendDynamicSystemMessage(c->getEntityRowId(), "PVP_TP_FORBIDEN"); + return true; + } + + if (command_args[3].length() > 2) + { + CBypassCheckFlags bypassCheckFlags; + bypassCheckFlags.setFlag(CHECK_FLAG_TYPE::WhileSitting, command_args[3].length() > 2 && command_args[3][2] == '1'); + bypassCheckFlags.setFlag(CHECK_FLAG_TYPE::InWater, command_args[3].length() > 3 && command_args[3][3] == '1'); + bypassCheckFlags.setFlag(CHECK_FLAG_TYPE::OnMount, command_args[3].length() > 4 && command_args[3][4] == '1'); + bypassCheckFlags.setFlag(CHECK_FLAG_TYPE::Fear, command_args[3].length() > 5 && command_args[3][5] == '1'); + bypassCheckFlags.setFlag(CHECK_FLAG_TYPE::Sleep, command_args[3].length() > 6 && command_args[3][6] == '1'); + bypassCheckFlags.setFlag(CHECK_FLAG_TYPE::Invulnerability, command_args[3].length() > 7 && command_args[3][7] == '1'); + bypassCheckFlags.setFlag(CHECK_FLAG_TYPE::Stun, command_args[3].length() > 8 && command_args[3][8] == '1'); + + if (!c->canEntityUseAction(bypassCheckFlags, true)) + return true; + } } string value = command_args[1]; @@ -5735,7 +6010,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " 2 && command_args[2] == "1") allowPetTp = true; if (allowPetTp) @@ -5751,6 +6026,14 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " applyRespawnEffects(); } + // Use same Cell + if (command_args.size () > 4 && command_args[4] == "1") + { + TDataSetRow dsr = c->getEntityRowId(); + CMirrorPropValueRO mirrorCell( TheDataset, dsr, DSPropertyCELL ); + cell = mirrorCell; + } + c->teleportCharacter(x,y,z,allowPetTp,true,h,0xFF,cell); if ( cont ) @@ -5759,6 +6042,77 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " res; + sint32 x = c->getState().X(); + sint32 y = c->getState().Y(); + sint32 z = c->getState().Z(); + float h = c->getState().Heading(); + sint32 cell; + if ( value.find(',') != string::npos ) // Position x,y,z,a + { + explode (value, string(","), res); + if (res.size() >= 2) + { + fromString(res[0], x); + x *= 1000; + fromString(res[1], y); + y *= 1000; + } + if (res.size() >= 3) + { + fromString(res[2], z); + z *= 1000; + } + if (res.size() >= 4) + fromString(res[3], h); + } + + bool allowPetTp = false; + if (command_args.size() > 4 && command_args[4] == "1") + allowPetTp = true; + + if (allowPetTp) + c->allowNearPetTp(); + else + c->forbidNearPetTp(); + + IBuildingPhysical * building = CBuildingManager::getInstance()->getBuildingPhysicalsByName(command_args[2]); + if ( building ) + { + + if (building->getTemplate()->Type == BUILDING_TYPES::Player) + { + + /*TDataSetRow dsr = c->getEntityRowId(); + CMirrorPropValueRO srcCell( TheDataset, dsr, DSPropertyCELL ); + sint32 cell = srcCell;*/ + + /*if (cell >= 0) + {*/ + CBuildingPhysicalPlayer * buildingPlayer = dynamic_cast( building ); + + CEntityBase *entityBase = PlayerManager.getCharacterByName(CShardNames::getInstance().makeFullNameFromRelative(c->getHomeMainlandSessionId(), command_args[3])); + if (buildingPlayer && entityBase) + { + CBuildingManager::getInstance()->removePlayerFromRoom( c ); + uint16 ownerId = buildingPlayer->getOwnerIdx( entityBase->getId() ); + buildingPlayer->addUser(c, 0, ownerId, cell); + c->teleportCharacter(x,y,z,allowPetTp,true,h,0xFF,cell); + } + //} + } + } + } + //************************************************* //***************** rename_animal //************************************************* @@ -5794,6 +6148,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " buyBuilding(c->getId(), building->getAlias()); } } + else if (action == "set_player_room" && command_args.size () == 3) + { + CBuildingPhysicalPlayer * building = dynamic_cast(CBuildingManager::getInstance()->getBuildingPhysicalsByName(command_args[2])); + if ( building ) + { + c->getRoomInterface().setBuilding(building); + building->addPlayer(c->getId()); + } + } + else if (action == "get_access_room" && command_args.size () == 3) + { + + CCharacter *owner = PlayerManager.getCharacterByName(CShardNames::getInstance().makeFullNameFromRelative(c->getHomeMainlandSessionId(), command_args[2])); + if (owner) + owner->addRoomAccessToPlayer(c->getId()); + } } //************************************************* @@ -5891,6 +6262,50 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " isDead()) { + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=not_dead", getSalt()); + return true; + } + } + else if (action == "alive") + { + if (c->isDead()) { + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=not_alive", getSalt()); + return true; + } + } + else if (action == "tag") + { + if (!c->getPVPFlag()) { + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=not_tag", getSalt()); + return true; + } + } + else if (action == "flag") + { + if (!c->getPvPRecentActionFlag()) { + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=not_flag", getSalt()); + return true; + } + } + } + //************************************************* //***************** Money //************************************************* @@ -6135,6 +6550,79 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getHomeMainlandSessionId(), player)); + destPlayer = dynamic_cast(CEntityBaseManager::getEntityBasePtr(entityBase->getId())); + } else { + const CEntityId &target = c->getTarget(); + destPlayer = dynamic_cast(CEntityBaseManager::getEntityBasePtr(target)); + } + if (destPlayer) + destPlayer->sendUrl(app+" "+params, ""); + } + + + //************************************************* + //***************** dt_bot + // /a webExecCommand debug 1 dt_bot!bejc hmac 0 + //************************************************* + +/* else if (command_args[0] == "dt_bot") + { + + if (command_args.size() != 2) + return false; + + string botname = command_args[1]; // bot_name + vector aliases; + + CAIAliasTranslator::getInstance()->getNPCAliasesFromName( botname, aliases ); + if ( aliases.empty() ) + { + nldebug ("Bot not found '%s'", botname.c_str()); + return true; + } + + TAIAlias alias = aliases[0]; + + const CEntityId & botId = CAIAliasTranslator::getInstance()->getEntityId (alias); + if ( botId != CEntityId::Unknown ) + { + nlinfo("Openning window trad..."); + c->setDirectTradeNpc(botId); + if ( !c->startDirectBotChat( BOTCHATTYPE::TradeItemFlag ) ) + { + nlinfo("failed !"); + return true; + } + c->resetRawMaterialItemPartFilter(); + c->resetItemTypeFilter(); + c->refreshTradeList(); + nlinfo("done!"); + } + else + { + nlwarning ("'%s' has no eId. Is it Spawned???", botname.c_str()); + return true; + } + + }*/ + //************************************************* //***************** missions //************************************************* @@ -6219,6 +6707,15 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " = 4) + { + uint32 nbString = (uint32)command_args.size(); + string text = getStringFromHash(command_args[3]); + + for (uint32 i=4; isetCustomMissionParams(command_args[2], text); + } else if (action == "set_params" && command_args.size() == 4) { c->setCustomMissionParams(command_args[2], web_app_url+","+command_args[3]); @@ -6247,10 +6744,21 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=finished", getSalt()); } } + else + { + if (save_index) + { + c->validateWebCommandIndex(iindex); + } + if (send_url) + c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=finished", getSalt()); + } } else { c->setWebCommandIndex(iindex); + if (save_index) + c->validateWebCommandIndex(iindex); if (send_url) c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=finished", getSalt()); } @@ -6507,7 +7015,7 @@ NLMISC_COMMAND(roomInvite, "send a room invite to a player character", " getHomeMainlandSessionId(), args[1])); - if(target == 0 || target->getEnterFlag() == false ) + if(target == NULL || target->getEnterFlag() == false ) { CCharacter::sendDynamicSystemMessage( user->getId(), "TEAM_INVITED_CHARACTER_MUST_BE_ONLINE" ); return true; @@ -6552,7 +7060,7 @@ NLMISC_COMMAND(roomKick, "kick player from room", " ") } CCharacter * target = PlayerManager.getCharacterByName(CShardNames::getInstance().makeFullNameFromRelative(user->getHomeMainlandSessionId(), args[1])); - if(target == 0 || target->getEnterFlag() == false ) + if(target == NULL || target->getEnterFlag() == false ) { CCharacter::sendDynamicSystemMessage( user->getId(), "TEAM_KICKED_CHARACTER_MUST_BE_ONLINE" ); return true; @@ -7493,7 +8001,7 @@ NLMISC_COMMAND(setOrganizationStatus, "set the organization status of a player", } //---------------------------------------------------------------------------- -NLMISC_COMMAND(eventCreateNpcGroup, "create an event npc group", " [ [ [ [ [ []]]]]]") +NLMISC_COMMAND(eventCreateNpcGroup, "create an event npc group", " [] [] [] [] [] [] [client_sheet] [inVIllage?inOutpost?inStable?inAtys?]") { if (args.size () < 3) return false; GET_CHARACTER @@ -7501,6 +8009,7 @@ NLMISC_COMMAND(eventCreateNpcGroup, "create an event npc group", " < uint32 instanceNumber = c->getInstanceNumber(); sint32 x = c->getX(); sint32 y = c->getY(); + sint32 z = c->getZ(); sint32 orientation = 6666; // used to specify a random orientation uint32 nbBots; @@ -7555,23 +8064,32 @@ NLMISC_COMMAND(eventCreateNpcGroup, "create an event npc group", " < if (args.size() > 8) { - if (args[7] != "*") { + if (args[7] != "*") + { float userX; NLMISC::fromString(args[7], userX); - x = (sint32)(userX * 1000); + x = (sint32)(userX * 1000.0); } - if (args[8] != "*") { + if (args[8] != "*") + { float userY; NLMISC::fromString(args[8], userY); - y = (sint32)(userY * 1000); + y = (sint32)(userY * 1000.0); + } + } + + if (args.size() > 9) + { + if (args[9] != "*") { + NLMISC::fromString(args[9], z); } } std::string look; - if (args.size() > 9) + if (args.size() > 10) { - look = args[9]; + look = args[10]; if (look.find(".creature") == string::npos) look += ".creature"; } @@ -7582,6 +8100,10 @@ NLMISC_COMMAND(eventCreateNpcGroup, "create an event npc group", " < return true; } + TDataSetRow dsr = c->getEntityRowId(); + CMirrorPropValueRO srcCell( TheDataset, dsr, DSPropertyCELL ); + sint32 cell = srcCell; + CEntityId playerId = c->getId(); CMessage msgout("EVENT_CREATE_NPC_GROUP"); @@ -7591,6 +8113,7 @@ NLMISC_COMMAND(eventCreateNpcGroup, "create an event npc group", " < msgout.serial(playerId); msgout.serial(x); msgout.serial(y); + msgout.serial(z); msgout.serial(orientation); msgout.serial(nbBots); msgout.serial(sheetId); @@ -7598,6 +8121,7 @@ NLMISC_COMMAND(eventCreateNpcGroup, "create an event npc group", " < msgout.serial(spawnBots); msgout.serial(botsName); msgout.serial(look); + msgout.serial(cell); CWorldInstances::instance().msgToAIInstance2(instanceNumber, msgout); return true; @@ -7655,8 +8179,15 @@ NLMISC_COMMAND(eScript, "executes a script on an event npc group", " { string arg = args[i]+";"; + size_t pos = 0; + while((pos = arg.find(" &", pos)) != string::npos) + { + arg.replace(pos, 6, " "); + pos ++; + } + // Replace "(eid:)" with player Entity ID string - size_t pos = arg.find("(eid:"); + pos = arg.find("(eid:"); while (pos != string::npos) { string s = arg.substr(pos, arg.find(")\"", pos) - pos + 1); @@ -7708,7 +8239,7 @@ NLMISC_COMMAND(eventSetBotScale, "changes the scale of a bot (in % up to 255)", NLMISC::fromString(args[1], scale); if (scale>255) scale = 0; - CMirrorPropValue< SAltLookProp2, CPropLocationPacked<2> > visualPropertyB( TheDataset, row, DSPropertyVPB ); + CMirrorPropValue< SAltLookProp2, CPropLocationPacked<2> > visualPropertyB( TheDataset, row, DSPropertyVPB ); SET_STRUCT_MEMBER( visualPropertyB, PropertySubData.Scale, scale ); return true; @@ -8087,7 +8618,7 @@ NLMISC_COMMAND(displayPositionStack, "Display the position stack of a character if (eid == CEntityId::Unknown) return true; CCharacter *c = PlayerManager.getChar(eid); - if(c == 0) + if (c == NULL) { log.displayNL( "Character not found" ); return true; @@ -8219,7 +8750,7 @@ NLMISC_COMMAND(farTPSubst, "Substitute a position in the stack (no immediate far if (eid == CEntityId::Unknown) return true; CCharacter *c = PlayerManager.getChar(eid); - if(c == 0) + if (c == NULL) { log.displayNL( "Character not found" ); return true; @@ -8289,7 +8820,7 @@ NLMISC_COMMAND(teamInvite, "send a team invite to a player character", " getHomeMainlandSessionId(), args[1])); - if(invitedCharacter == 0 || invitedCharacter->getEnterFlag() == false ) + if (invitedCharacter == NULL || invitedCharacter->getEnterFlag() == false ) { CCharacter::sendDynamicSystemMessage( user->getId(),"TEAM_INVITED_CHARACTER_MUST_BE_ONLINE" ); return true; @@ -8331,7 +8862,7 @@ NLMISC_COMMAND(leagueInvite, "send a League invite to a player character", "getHomeMainlandSessionId(), args[1])); - if(invitedCharacter == 0 || invitedCharacter->getEnterFlag() == false ) + if (invitedCharacter == NULL || invitedCharacter->getEnterFlag() == false ) { CCharacter::sendDynamicSystemMessage( user->getId(),"TEAM_INVITED_CHARACTER_MUST_BE_ONLINE" ); return true; @@ -8373,7 +8904,7 @@ NLMISC_COMMAND(leagueKick, "kick a player character from league", " getHomeMainlandSessionId(), args[1])); - if(invitedCharacter == 0 || invitedCharacter->getEnterFlag() == false ) + if (invitedCharacter == NULL || invitedCharacter->getEnterFlag() == false ) { CCharacter::sendDynamicSystemMessage( user->getId(),"TEAM_INVITED_CHARACTER_MUST_BE_ONLINE" ); return true; @@ -8488,12 +9019,6 @@ NLMISC_COMMAND(eventSetBotURL, "changes the url of a bot", " []") uint32 program = creature->getBotChatProgram(); if(!(program & (1<setBotChatProgram(program); diff --git a/code/ryzom/server/src/entities_game_service/admin.h b/code/ryzom/server/src/entities_game_service/admin.h index 5a00850aa..337824459 100644 --- a/code/ryzom/server/src/entities_game_service/admin.h +++ b/code/ryzom/server/src/entities_game_service/admin.h @@ -46,11 +46,31 @@ void initCommandsPrivileges(const std::string & fileName); void initPositionFlags(const std::string & fileName); void initSalt(); const std::string &getSalt(); +void getUCstringFromHash(const std::string & hash, ucstring & finaltext); +std::string getStringFromHash(const std::string &hash); CAdminCommand * findAdminCommand(const std::string & name); extern void GET_CHARACTER_Helper(std::string& command, const NLMISC::CEntityId& id, const std::string& adminCommand); +#define GET_ENTITY \ + if (args.size() < 1) { nlwarning ("Missing argument number 0 that should be the eid"); return false; } \ + CEntityId eid(args[0]); \ + if (eid == CEntityId::Unknown) \ + return true; \ + TLogContext_Character_AdminCommand commandContext(eid); \ + CEntityBase *e = CEntityBaseManager::getEntityBasePtr(eid); \ + if(e == 0) \ + { \ + nlwarning ("Unknown entity '%s'", eid.toString().c_str()); \ + return true; \ + } \ + if(!TheDataset.isAccessible(e->getEntityRowId())) \ + { \ + nlwarning ("'%s' is not valid in mirror", eid.toString().c_str()); \ + return true; \ + } + #define GET_CHARACTER \ if (args.size() < 1) { nlwarning ("Missing argument number 0 that should be the eid"); return false; } \ CEntityId eid(args[0]); \ @@ -88,6 +108,29 @@ extern void GET_CHARACTER_Helper(std::string& command, const NLMISC::CEntityId& } \ end: +#define GET_ACTIVE_CHARACTER \ + if (args.size() < 1) { nlwarning ("ERR: Missing argument number 0 that should be the uid"); return false; } \ + uint32 uid; \ + NLMISC::fromString(args[0], uid); \ + CCharacter *c = CPlayerManager::getInstance().getActiveChar(uid); \ + if(c == 0) \ + { \ + log.displayNL ("ERR: Unknown player '%u' (%s)", uid, args[0].c_str()); \ + return false; \ + } \ + CEntityId eid = c->getId(); \ + TLogContext_Character_AdminCommand commandContext(eid); \ + if(!c->getEnterFlag()) \ + { \ + log.displayNL ("ERR: '%s' is not entered", eid.toString().c_str()); \ + return false; \ + } \ + if(!TheDataset.isAccessible(c->getEntityRowId())) \ + { \ + log.displayNL ("ERR: '%s' is not valid in mirror", eid.toString().c_str()); \ + return false; \ + } \ + //#define GET_CHARACTER1 \ // if (args.size() < 2) { nlwarning ("Missing argument number 1 that should be the eid"); return false; } \ // CEntityId eid = CEntityIdTranslator::getInstance()->getByEntity(args[1]); \ diff --git a/code/ryzom/server/src/entities_game_service/building_manager/building_physical.h b/code/ryzom/server/src/entities_game_service/building_manager/building_physical.h index c80506a2f..87eac37dd 100644 --- a/code/ryzom/server/src/entities_game_service/building_manager/building_physical.h +++ b/code/ryzom/server/src/entities_game_service/building_manager/building_physical.h @@ -57,6 +57,8 @@ public: inline const CTPDestination* getExit( uint8 idx )const; /// return the default exit spawn zone inline uint16 getDefaultExitSpawn() const; + /// return the Cell of roomIdx and ownerId + inline sint32 getRoomCell( uint16 roomIdx, uint16 ownerIdx ); //@} /// get the cell id of a physical room of this building. Return true if no error. @@ -184,6 +186,8 @@ public: inline void resetRoomCell( uint16 roomIdx,const NLMISC::CEntityId & userId ); /// get an owner player inline const NLMISC::CEntityId & getPlayer(uint idx); + /// get the index of a owner player + inline uint16 getOwnerIdx( const NLMISC::CEntityId & userId ); virtual void getClientDescription(uint16 roomIdx, uint16 ownerIndex, CCharacter * user, uint64 & icon, uint32 & textId )const; virtual void onPlayerDeletion( const NLMISC::CEntityId & userId ); diff --git a/code/ryzom/server/src/entities_game_service/building_manager/building_physical_inline.h b/code/ryzom/server/src/entities_game_service/building_manager/building_physical_inline.h index 533702b65..bff6849fb 100644 --- a/code/ryzom/server/src/entities_game_service/building_manager/building_physical_inline.h +++ b/code/ryzom/server/src/entities_game_service/building_manager/building_physical_inline.h @@ -74,6 +74,25 @@ inline bool IBuildingPhysical::removeUser(const TDataSetRow & row) return false; } +//---------------------------------------------------------------------------- +inline sint32 IBuildingPhysical::getRoomCell( uint16 roomIdx, uint16 ownerIdx ) +{ + /// simply get the cell matching the parameters + if ( roomIdx >= _Rooms.size() ) + { + nlwarning("Invalid room %u count is %u",roomIdx,_Rooms.size() ); + return false; + } + if ( ownerIdx >= _Rooms[roomIdx].Cells.size() ) + { + nlwarning("Invalid owner idx %u count is %u",ownerIdx,_Rooms[roomIdx].Cells.size()); + return false; + } + + return _Rooms[roomIdx].Cells[ownerIdx]; +} + + /*****************************************************************************/ // CBuildingPhysicalCommon implementation /*****************************************************************************/ @@ -167,7 +186,7 @@ inline void CBuildingPhysicalPlayer::addPlayer( const NLMISC::CEntityId & userId { if ( std::find(_Players.begin(), _Players.end(), userId) != _Players.end() ) { - nlwarning(" trying to add player %s which is already present in the building", userId.toString().c_str()); + //nlwarning(" trying to add player %s which is already present in the building", userId.toString().c_str()); return; } @@ -181,6 +200,30 @@ inline void CBuildingPhysicalPlayer::addPlayer( const NLMISC::CEntityId & userId } } +//---------------------------------------------------------------------------- +inline uint16 CBuildingPhysicalPlayer::getOwnerIdx( const NLMISC::CEntityId & userId ) +{ + for ( uint16 i = 0; i < _Players.size(); i++ ) + { + if ( _Players[i] == userId ) + { + return i; + } + } + + _StateCounter++; + _Players.push_back( userId ); + // add an instance cell to each room for this player + const uint size = (uint)_Rooms.size(); + for ( uint i = 0; i < size; i++ ) + { + _Rooms[i].Cells.push_back( 0 ); + } + + return (uint16)(_Players.size() - 1); +} + + //---------------------------------------------------------------------------- inline void CBuildingPhysicalPlayer::resetRoomCell( uint16 roomIdx,const NLMISC::CEntityId & userId ) { diff --git a/code/ryzom/server/src/entities_game_service/creature_manager/creature.cpp b/code/ryzom/server/src/entities_game_service/creature_manager/creature.cpp index fbda3f415..5a0f8873a 100644 --- a/code/ryzom/server/src/entities_game_service/creature_manager/creature.cpp +++ b/code/ryzom/server/src/entities_game_service/creature_manager/creature.cpp @@ -1574,7 +1574,7 @@ inline sint32 CCreature::applyDamageOnArmor( DMGTYPE::EDamageType dmgType, sint3 ///\todo localisation for NPCS if ( dmgType <0 || uint(dmgType) >= /*form->Protections.size()*/DMGTYPE::NBTYPES ) { - nlwarning( " invalid damage type %d in entity %s", (sint)dmgType, _Id.toString().c_str() ); + //nlwarning( " invalid damage type %d in entity %s", (sint)dmgType, _Id.toString().c_str() ); return damage; } else @@ -1654,7 +1654,7 @@ CGameItemPtr CCreature::getNpcItem( const NLMISC::CSheetId &sheet, uint16 qualit } } - nlwarning("Failed to create NPC item %s with quality %d for entity %s (%s)", sheet.toString().c_str(), quality, _Id.toString().c_str(), getType().toString().c_str() ); + //nlwarning("Failed to create NPC item %s with quality %d for entity %s (%s)", sheet.toString().c_str(), quality, _Id.toString().c_str(), getType().toString().c_str() ); return CGameItemPtr(NULL); } // getNpcItem // @@ -1814,6 +1814,8 @@ void CCreature::tpWanted( sint32 x, sint32 y, sint32 z , bool useHeading , float msgout2.serial( z ); msgout2.serial( heading ); msgout2.serial( tick ); + msgout2.serial( continent ); + msgout2.serial( cell ); sendMessageViaMirror("GPMS", msgout2); } diff --git a/code/ryzom/server/src/entities_game_service/database_plr.cpp b/code/ryzom/server/src/entities_game_service/database_plr.cpp index 4b5fa84fd..01c848d3b 100644 --- a/code/ryzom/server/src/entities_game_service/database_plr.cpp +++ b/code/ryzom/server/src/entities_game_service/database_plr.cpp @@ -3140,7 +3140,8 @@ void CBankAccessor_PLR::TPACK_ANIMAL::TBEAST::init(ICDBStructNode *parent, uint nlassert(node != NULL); _DESPAWN = node; - node = parent->getNode( ICDBStructNode::CTextId("NAME"), false ); + // WARNING: let the value to true, else it'll corrupt backups + node = parent->getNode( ICDBStructNode::CTextId("NAME"), true ); nlassert(node != NULL); _NAME = node; diff --git a/code/ryzom/server/src/entities_game_service/dyn_chat_egs.cpp b/code/ryzom/server/src/entities_game_service/dyn_chat_egs.cpp index 98ec86a75..9ab7013f4 100644 --- a/code/ryzom/server/src/entities_game_service/dyn_chat_egs.cpp +++ b/code/ryzom/server/src/entities_game_service/dyn_chat_egs.cpp @@ -95,7 +95,7 @@ TChanID CDynChatEGS::addChan(const std::string &name, const ucstring &title, boo { _DynChat.getChan(chan)->Localized = localized; _DynChat.getChan(chan)->Title = title; - iosAddChan(chan, noBroadcast, forwardPlayerInputs, unify); + iosAddChan(chan, noBroadcast, forwardPlayerInputs, unify, name); _ChanNames.add(chan, name); return chan; } @@ -108,7 +108,7 @@ TChanID CDynChatEGS::addChan(const std::string &name, const ucstring &title, boo else if (_DynChat.addChan(_NextChanID, false, false, false)) { TChanID result = _NextChanID; - iosAddChan(_NextChanID, noBroadcast, forwardPlayerInputs, unify); + iosAddChan(_NextChanID, noBroadcast, forwardPlayerInputs, unify, name); _DynChat.getChan(_NextChanID)->Localized = localized; _DynChat.getChan(_NextChanID)->Title = title; _ChanNames.add(_NextChanID, name); @@ -465,13 +465,16 @@ void CDynChatEGS::onServiceDown(NLNET::TServiceId serviceId) //============================================================================================================ -void CDynChatEGS::iosAddChan(TChanID chan, bool noBroadcast, bool forwardPlayerInputs, bool unify) +void CDynChatEGS::iosAddChan(TChanID chan, bool noBroadcast, bool forwardPlayerInputs, bool unify, const std::string &name) { CMessage msg("DYN_CHAT:ADD_CHAN"); msg.serial(chan); msg.serial(noBroadcast); msg.serial(forwardPlayerInputs); msg.serial(unify); + msg.serial(const_cast(name)); + + nlinfo("ask IOS to create channel: %s - name: '%s'", chan.toString().c_str(), name.c_str()); sendMessageViaMirror( "IOS", msg); } @@ -542,12 +545,14 @@ void CDynChatEGS::iosResetDynChat() //============================================================================================================ void CDynChatEGS::iosConnection() { + nlwarning("IOS connected, add all chan we already have in memory"); + iosResetDynChat(); CDynChat::TChanPtrVector chans; _DynChat.getChans(chans); for(uint k = 0; k < chans.size(); ++k) { - iosAddChan(chans[k]->getID(), chans[k]->getDontBroadcastPlayerInputs(), chans[k]->getForwardPlayerIntputToOwnerService(), chans[k]->getUnifiedChannel()); + iosAddChan(chans[k]->getID(), chans[k]->getDontBroadcastPlayerInputs(), chans[k]->getForwardPlayerIntputToOwnerService(), chans[k]->getUnifiedChannel(), getChanNameFromID(chans[k]->getID())); // add each session in the channel CDynChatSession *currSession = chans[k]->getFirstSession(); while (currSession) diff --git a/code/ryzom/server/src/entities_game_service/dyn_chat_egs.h b/code/ryzom/server/src/entities_game_service/dyn_chat_egs.h index fb1ad9313..a0886dc40 100644 --- a/code/ryzom/server/src/entities_game_service/dyn_chat_egs.h +++ b/code/ryzom/server/src/entities_game_service/dyn_chat_egs.h @@ -123,7 +123,7 @@ private: TChanTwinMap _ChanNames; private: // ios msg - void iosAddChan(TChanID chan, bool noBroadcast, bool forwardPlayerInputs, bool unify); + void iosAddChan(TChanID chan, bool noBroadcast, bool forwardPlayerInputs, bool unify, const std::string &name); void iosSetHideBubble(TChanID chan, bool hideBubble); void iosSetUniversalChannel(TChanID chan, bool universalChannel); void iosRemoveChan(TChanID chan); diff --git a/code/ryzom/server/src/entities_game_service/entities_game_service.cpp b/code/ryzom/server/src/entities_game_service/entities_game_service.cpp index fa0985692..752e3db6e 100644 --- a/code/ryzom/server/src/entities_game_service/entities_game_service.cpp +++ b/code/ryzom/server/src/entities_game_service/entities_game_service.cpp @@ -2233,9 +2233,11 @@ NLMISC_COMMAND(create_obj,"create a new object","") if( args.size() > 0 ) { CWorldObjectLocation loc; + uint32 type; uint16 quality = 0; uint32 hp = 0; - WorldObjectManager.createObject(NLMISC::fromString(args[2].c_str()),loc,quality,hp); + NLMISC::fromString(args[0], type); + WorldObjectManager.createObject(type,loc,quality,hp); return true; } return false; diff --git a/code/ryzom/server/src/entities_game_service/entity_manager/entity_base.h b/code/ryzom/server/src/entities_game_service/entity_manager/entity_base.h index 99ebae0dc..40503f16c 100644 --- a/code/ryzom/server/src/entities_game_service/entity_manager/entity_base.h +++ b/code/ryzom/server/src/entities_game_service/entity_manager/entity_base.h @@ -500,6 +500,9 @@ public: // Set entity mounted void setEntityMounted( const TDataSetRow& entityRowId ) { _EntityMounted = entityRowId; } + // Set speed factor + inline void setSpeedVariationModifier( sint32 speed ) { _PhysScores.SpeedVariationModifier = speed; } + // get entity mounted const TDataSetRow& getEntityMounted() const { return _EntityMounted(); } diff --git a/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp b/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp index d969a4405..d6ddde501 100644 --- a/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp +++ b/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp @@ -3050,6 +3050,31 @@ void cbTeleportPlayer(NLNET::CMessage& msgin, const std::string &serviceName, NL chr->teleportCharacter(x, y, z, true, true, t); } +//--------------------------------------------------- +// trigger the webig +//--------------------------------------------------- +void cbTriggerWebig(NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId) +{ + H_AUTO(cbTriggerWebig); + string event; + msgin.serial( event ); + uint32 nbPlayers; + msgin.serial( nbPlayers ); + nlinfo("ok %s %d", event.c_str(), nbPlayers); + for ( uint i=0; isendUrl(event, ""); + } +} + //--------------------------------------------------- /// Forage source position validation diff --git a/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.h b/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.h index 96963772b..b4ba5323b 100644 --- a/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.h +++ b/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.h @@ -213,6 +213,9 @@ void cbPlayerUnreachable( NLNET::CMessage& msgin, const std::string &serviceName // AIS ask to teleport player via script void cbTeleportPlayer(NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId); +// AIS ask to trigger webig +void cbTriggerWebig(NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId); + #endif //ENTITY_CALLBACKS_H diff --git a/code/ryzom/server/src/entities_game_service/entity_structure/resists.cpp b/code/ryzom/server/src/entities_game_service/entity_structure/resists.cpp index b8f195857..89322cc9f 100644 --- a/code/ryzom/server/src/entities_game_service/entity_structure/resists.cpp +++ b/code/ryzom/server/src/entities_game_service/entity_structure/resists.cpp @@ -22,6 +22,8 @@ #include "stdpch.h" // #include "resists.h" +#include "player_manager/character.h" +#include "game_item_manager/game_item.h" ////////////// // USING // diff --git a/code/ryzom/server/src/entities_game_service/game_item_manager/game_item.cpp b/code/ryzom/server/src/entities_game_service/game_item_manager/game_item.cpp index e36a4382e..80518f463 100644 --- a/code/ryzom/server/src/entities_game_service/game_item_manager/game_item.cpp +++ b/code/ryzom/server/src/entities_game_service/game_item_manager/game_item.cpp @@ -1205,6 +1205,7 @@ CGameItemPtr CGameItem::getItemCopy() item->_SapLoad = _SapLoad; item->_LostHPremains = 0.0f; item->_PhraseId = _PhraseId; + item->_RequiredFaction = _RequiredFaction; item->computeItemWornState(); log_Item_Create(item->getItemId(), item->getSheetId(), item->getStackSize(), item->quality()); @@ -1372,9 +1373,12 @@ void CGameItem::clear() _HasPrerequisit= false; _LockedByOwner = false; + _Movable = false; + _UnMovable = false; _TypeSkillMods.clear(); _PhraseId.clear(); + _RequiredFaction.clear(); _CustomText.clear(); } @@ -4325,6 +4329,51 @@ void CGameItem::displayInLog( CLog &log ) } } // displayInLog // +//----------------------------------------------- +// getStats +//----------------------------------------------- +bool CGameItem::getStats(const std::string &stats, std::string &final ) +{ + if (stats.size() % 2) + return false; + + // cut hash in portion of 4 + for (uint i=0; iName.c_str()); + else if (part == "Ct") + final += NLMISC::toString("%s|", getCustomText().toString().c_str()); + else if (part == "Bu") + final += NLMISC::toString("%u|", _Form->Bulk); + else if (part == "We") + final += NLMISC::toString("%u|", _Form->Weight); + else + return false; + } + return true; +} // getStats // //----------------------------------------------- // getClientEnchantValue diff --git a/code/ryzom/server/src/entities_game_service/game_item_manager/game_item.h b/code/ryzom/server/src/entities_game_service/game_item_manager/game_item.h index 87c21f7c0..635fbf74c 100644 --- a/code/ryzom/server/src/entities_game_service/game_item_manager/game_item.h +++ b/code/ryzom/server/src/entities_game_service/game_item_manager/game_item.h @@ -648,6 +648,7 @@ public : * display item infos */ void displayInLog(NLMISC::CLog &log); + bool getStats(const std::string &stats, std::string &final ); /// accessors to the action latency end date inline NLMISC::TGameCycle getLatencyEndDate(){ return _LatencyEndDate; } @@ -679,9 +680,20 @@ public : /// set required skill level inline void setRequiredSkillLevel2( uint16 l ) { _RequiredSkillLevel2 = l; } - bool getLockedByOwner() const { return _LockedByOwner; } + /// get Required Faction + inline const std::string & getRequiredFaction() const { return _RequiredFaction;} + /// set Required Faction + inline void setRequiredFaction(const std::string & str){ _RequiredFaction = str;} + + inline bool getLockedByOwner() const { return _LockedByOwner; } void setLockedByOwner(bool value); + inline bool getMovable() const { return _Movable; } + inline void setMovable(bool value) { _Movable = value; } + + inline bool getUnMovable() const { return _UnMovable; } + inline void setUnMovable(bool value) { _UnMovable = value; } + /// get required stat inline CHARACTERISTICS::TCharacteristics getRequiredCharac() const { return _RequiredCharac; } /// set required stat @@ -945,6 +957,7 @@ private: // required skill bool _UseNewSystemRequirement; + std::string _RequiredFaction; SKILLS::ESkills _RequiredSkill; uint16 _RequiredSkillLevel; SKILLS::ESkills _RequiredSkill2; @@ -958,6 +971,8 @@ private: ucstring _CustomText; bool _LockedByOwner; + bool _UnMovable; + bool _Movable; uint8 _PetIndex; ucstring _CustomName; }; diff --git a/code/ryzom/server/src/entities_game_service/game_item_manager/player_inv_xchg.cpp b/code/ryzom/server/src/entities_game_service/game_item_manager/player_inv_xchg.cpp index 79d2b40c1..c5de9318f 100644 --- a/code/ryzom/server/src/entities_game_service/game_item_manager/player_inv_xchg.cpp +++ b/code/ryzom/server/src/entities_game_service/game_item_manager/player_inv_xchg.cpp @@ -81,7 +81,7 @@ bool CExchangeView::putItemInExchange(uint32 bagSlot, uint32 exchangeSlot, uint3 // if it is an exchange between 2 players // do not permit exchange of non dropable items, but pet animal ticket are NoDrop item but must ne exchangeable - if (_InterlocutorView != NULL && (!form->DropOrSell && form->Family != ITEMFAMILY::PET_ANIMAL_TICKET)) + if (!item->getMovable() && _InterlocutorView != NULL && form->Family != ITEMFAMILY::PET_ANIMAL_TICKET && (!form->DropOrSell || item->getUnMovable())) return false; // Can't trade items locked by owner diff --git a/code/ryzom/server/src/entities_game_service/game_item_manager/player_inventory.cpp b/code/ryzom/server/src/entities_game_service/game_item_manager/player_inventory.cpp index b3ec0ee06..dcb7e5a49 100644 --- a/code/ryzom/server/src/entities_game_service/game_item_manager/player_inventory.cpp +++ b/code/ryzom/server/src/entities_game_service/game_item_manager/player_inventory.cpp @@ -186,7 +186,7 @@ CInventoryBase::TInventoryOpResult CInventoryBase::doInsertItem(CGameItemPtr &it vector< pair > Modifs; // If slot provided is NULL directly insert item in it - if (_Items[slotBegin] == NULL) + if (_Items[slotBegin] == NULL && slot != INVENTORIES::INSERT_IN_FIRST_FREE_SLOT) { Modifs.push_back(make_pair(slotBegin, itemStackSize)); } diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp b/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp index b7277bc11..b7a5bc4a5 100644 --- a/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp +++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp @@ -955,9 +955,11 @@ void CGuild::putItem( CCharacter * user, uint32 slot, uint32 quantity, uint16 se // check if this type of item is legal in the guild inventory CGameItemPtr item = srcItem; - if ( !item->getStaticForm()->DropOrSell - || item->getStaticForm()->Family == ITEMFAMILY::PET_ANIMAL_TICKET - || user->isAnActiveXpCatalyser(item) + if (!item->getMovable() && ( + !item->getStaticForm()->DropOrSell + || item->getStaticForm()->Family == ITEMFAMILY::PET_ANIMAL_TICKET + || user->isAnActiveXpCatalyser(item) + || item->getUnMovable() ) ) { CCharacter::sendDynamicSystemMessage( user->getId(),"GUILD_ITEM_CANT_BE_PUT" ); diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.cpp b/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.cpp index a587f68da..418685623 100644 --- a/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.cpp +++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.cpp @@ -66,6 +66,12 @@ CModuleParent & CGuildCharProxy::getModuleParent() return _ModuleCore->getModuleParent(); } +//---------------------------------------------------------------------------- +void CGuildCharProxy::sendSystemMessage( const std::string & msg) +{ + CCharacter::sendDynamicSystemMessage(_ModuleCore->getEntityRowId(), msg); +} + //---------------------------------------------------------------------------- void CGuildCharProxy::sendSystemMessage( const std::string & msg, const TVectorParamCheck & params) { diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_manager.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_manager.cpp index fc2a0a445..9b9c2db29 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_manager.cpp @@ -574,7 +574,13 @@ void CMissionManager::checkVisitPlaceMissions() BOMB_IF( ! missionTemplate, NLMISC::toString( "Invalid VisitPlace template %s", CPrimitivesParser::getInstance().aliasToString( stepId.MissionAlias ).c_str() ).c_str(), ++its; continue ); const IMissionStepTemplate *step = missionTemplate->getStep( stepId.StepIndex ); const CMission *missionInstance = character->getMission( stepId.MissionAlias ); - BOMB_IF( ! (step && missionInstance), NLMISC::toString( "Invalid Visit Place step or mission %s", CPrimitivesParser::getInstance().aliasToString( stepId.MissionAlias ).c_str() ).c_str(), ++its; continue ); + + // OLD: BOMB_IF( ! (step && missionInstance), NLMISC::toString( "Invalid Visit Place step or mission %s", CPrimitivesParser::getInstance().aliasToString( stepId.MissionAlias ).c_str() ).c_str(), ++its; continue ); + if (! (step && missionInstance)) + { + ++its; + continue; + } // Test if the iterated "visit place" steps match the current places with contraints bool placeProcessed = false; diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_talk.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_talk.cpp index 7647e7906..ff20126ac 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_talk.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_talk.cpp @@ -172,8 +172,27 @@ class CMissionStepTalk : public IMissionStepTemplate return 0; } + _User = PlayerManager.getChar(getEntityIdFromRow(user)); + uint32 userId = PlayerManager.getPlayerId(_User->getId()); + string text = _PhraseId; + if (_User) + { + uint32 userId = PlayerManager.getPlayerId(_User->getId()); + text = _User->getCustomMissionText(_PhraseId); + if (text.empty()) + return 0; + } TVectorParamCheck params; + ucstring phrase = ucstring(_PhraseId+"(){["+text+"]}"); + NLNET::CMessage msgout("SET_PHRASE"); + msgout.serial(_PhraseId); + msgout.serial(phrase); + sendMessageViaMirror("IOS", msgout); + return STRING_MANAGER::sendStringToClient( user, _PhraseId, params ); + +/* SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal); + params[0].Literal= text;*/ } CCreature * bot = CreatureManager.getCreature( interlocutor ); diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_template.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_template.cpp index 1caefb340..a042da852 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_template.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_template.cpp @@ -104,37 +104,58 @@ uint32 IMissionStepTemplate::sendRpStepText(CCharacter * user,const std::vector< _User = user; - if ( !_RoleplayText.empty() ) + if (_RoleplayText.substr(0, 6) == "WEBIG_") { - // build the param list - getTextParams(nbSteps,(const std::string *&)textPtr,params,stepStates); - - params.reserve(params.size() + _AdditionalParams.size()); - params.insert(params.end(), _AdditionalParams.begin(), _AdditionalParams.end()); - if ( textPtr && !textPtr->empty() && (*textPtr)[textPtr->size()-1] == '_' ) + TVectorParamCheck params; + string name = _RoleplayText; + if (user) { - buffer = _RoleplayText + "_"; - textPtr = &buffer; + uint32 userId = PlayerManager.getPlayerId(user->getId()); + string text = user->getCustomMissionText(_RoleplayText); + if (text.empty()) + return 0; + name = _RoleplayText+"_"+toString(userId); + ucstring phrase = ucstring(name+"(){["+text+"]}"); + NLNET::CMessage msgout("SET_PHRASE"); + msgout.serial(name); + msgout.serial(phrase); + sendMessageViaMirror("IOS", msgout); } - else - textPtr = &_RoleplayText; - } - - if( !textPtr ) - return 0; - - // solve dynamic names - CMissionParser::solveEntitiesNames(params,user->getEntityRowId(),giver); - - // if the text was generated, compute its suffix - if ( !textPtr->empty() && (*textPtr)[textPtr->size()-1] == '_' ) - { - std::string text = NLMISC::toString( "%s%u", textPtr->c_str(),nbSteps ); - return STRING_MANAGER::sendStringToClient( user->getEntityRowId(),text,params); + return STRING_MANAGER::sendStringToClient( user->getEntityRowId(), name, params ); } else - return STRING_MANAGER::sendStringToClient( user->getEntityRowId(),*textPtr,params); + { + if ( !_RoleplayText.empty() ) + { + // build the param list + getTextParams(nbSteps,(const std::string *&)textPtr,params,stepStates); + params.reserve(params.size() + _AdditionalParams.size()); + params.insert(params.end(), _AdditionalParams.begin(), _AdditionalParams.end()); + if ( textPtr && !textPtr->empty() && (*textPtr)[textPtr->size()-1] == '_' ) + { + buffer = _RoleplayText + "_"; + textPtr = &buffer; + } + else + textPtr = &_RoleplayText; + } + + if( !textPtr ) + return 0; + + // solve dynamic names + CMissionParser::solveEntitiesNames(params,user->getEntityRowId(),giver); + + // if the text was generated, compute its suffix + if ( !textPtr->empty() && (*textPtr)[textPtr->size()-1] == '_' ) + { + std::string text = NLMISC::toString( "%s%u", textPtr->c_str(),nbSteps ); + return STRING_MANAGER::sendStringToClient( user->getEntityRowId(),text,params); + } + else + return STRING_MANAGER::sendStringToClient( user->getEntityRowId(),*textPtr,params); + } }// IMissionStepTemplate::sendRpStepText @@ -153,22 +174,39 @@ uint32 IMissionStepTemplate::sendStepText(CCharacter * user,const std::vectorempty() && (*textPtr)[textPtr->size()-1] == '_' ) + string text = _OverridenText; + if (user) { - buffer = _OverridenText + "_"; - textPtr = &buffer; + uint32 userId = PlayerManager.getPlayerId(user->getId()); + text = user->getCustomMissionText(_OverridenText); + if (text.empty()) + text = _OverridenText; } - else - textPtr = &_OverridenText; + SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal); + params[0].Literal.fromUtf8(text); + return STRING_MANAGER::sendStringToClient( user->getEntityRowId(), "LITERAL", params ); } else { - params = _AdditionalParams; - textPtr = &_OverridenText; + if ( _AddDefaultParams ) + { + params.reserve(params.size() + _AdditionalParams.size()); + params.insert(params.end(), _AdditionalParams.begin(), _AdditionalParams.end()); + if ( textPtr && !textPtr->empty() && (*textPtr)[textPtr->size()-1] == '_' ) + { + buffer = _OverridenText + "_"; + textPtr = &buffer; + } + else + textPtr = &_OverridenText; + } + else + { + params = _AdditionalParams; + textPtr = &_OverridenText; + } } } diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp index a7b114588..ffcbc1e61 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp @@ -2085,15 +2085,6 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos if (!fillPrereqInfos) return MISSION_DESC::PreReqFail; - /*if (addedPrereqTexts.find("GUILD_BUILDING_BAD_GRADE") == addedPrereqTexts.end()) - { - prereqDesc.Description = STRING_MANAGER::sendStringToClient(user->getEntityRowId(), "GUILD_BUILDING_BAD_GRADE", TVectorParamCheck()); - prereqDesc.IsMandatory = true; - prereqDesc.Validated = false; - prereqInfos.Prerequisits.push_back(prereqDesc); - addedPrereqTexts.insert("GUILD_BUILDING_BAD_GRADE"); - }*/ - returnValue = MISSION_DESC::PreReqFail; logOnFail = false; } @@ -2450,55 +2441,109 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos uint32 CMissionTemplate::sendTitleText( const TDataSetRow & userRow, const TDataSetRow & giver ) const { - TVectorParamCheck params(1 + TitleParams.size() ); - std::copy( TitleParams.begin(),TitleParams.end(), params.begin() + 1 ); - params[0].Type = STRING_MANAGER::bot; - params[0].setEIdAIAlias( getEntityIdFromRow( giver ), CAIAliasTranslator::getInstance()->getAIAlias(getEntityIdFromRow( giver )) ); - CMissionParser::solveEntitiesNames(params,userRow,params[0].getEId()); - return STRING_MANAGER::sendStringToClient( userRow, TitleText,params ); + if (TitleText.substr(0, 6) == "WEBIG_") + { + string text = TitleText; + CCharacter *user = PlayerManager.getChar(getEntityIdFromRow(userRow)); + if (user) + { + uint32 userId = PlayerManager.getPlayerId(user->getId()); + text = user->getCustomMissionText(TitleText); + if (text.empty()) + text = ""; + } + SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal); + params[0].Literal.fromUtf8(text); + return STRING_MANAGER::sendStringToClient( userRow, "LITERAL", params ); + } + else + { + TVectorParamCheck params(1 + TitleParams.size() ); + std::copy( TitleParams.begin(),TitleParams.end(), params.begin() + 1 ); + params[0].Type = STRING_MANAGER::bot; + params[0].setEIdAIAlias( getEntityIdFromRow( giver ), CAIAliasTranslator::getInstance()->getAIAlias(getEntityIdFromRow( giver )) ); + CMissionParser::solveEntitiesNames(params,userRow,params[0].getEId()); + return STRING_MANAGER::sendStringToClient( userRow, TitleText,params ); + } }// CMissionTemplate sendTitleText uint32 CMissionTemplate::sendAutoText( const TDataSetRow & userRow,const NLMISC::CEntityId & giver) const { - TVectorParamCheck params = AutoParams; - CMissionParser::solveEntitiesNames(params,userRow,giver); - return STRING_MANAGER::sendStringToClient( userRow, AutoText,params ); + if (AutoText.substr(0, 6) == "WEBIG_") + { + string text = AutoText; + CCharacter *user = PlayerManager.getChar(getEntityIdFromRow(userRow)); + if (user) + { + uint32 userId = PlayerManager.getPlayerId(user->getId()); + text = user->getCustomMissionText(AutoText); + if (text.empty()) + return 0; + } + SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal); + params[0].Literal.fromUtf8(text); + return STRING_MANAGER::sendStringToClient( userRow, "LITERAL", params ); + } + else + { + TVectorParamCheck params = AutoParams; + CMissionParser::solveEntitiesNames(params,userRow,giver); + return STRING_MANAGER::sendStringToClient( userRow, AutoText,params ); + } }// CMissionTemplate::sendAutoText uint32 CMissionTemplate::sendDescText( const TDataSetRow & userRow, const TDataSetRow & giver, uint32 descIndex) const { - CEntityId id = getEntityIdFromRow( giver ); - - TVectorParamCheck params; - const TVectorParamCheck* addParams = NULL; - const string * txt = NULL; - if ( descIndex == 0xFFFFFFFF ) + if (DescText.substr(0, 6) == "WEBIG_") { - txt = &DescText; - addParams = &DescParams; + string text = DescText; + CCharacter *user = PlayerManager.getChar(getEntityIdFromRow(userRow)); + if (user) + { + uint32 userId = PlayerManager.getPlayerId(user->getId()); + text = user->getCustomMissionText(DescText); + if (text.empty()) + text = ""; + } + SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal); + params[0].Literal.fromUtf8(text); + return STRING_MANAGER::sendStringToClient( userRow, "LITERAL", params ); } else { - if ( descIndex >= OverloadedDescs.size() ) + CEntityId id = getEntityIdFromRow( giver ); + + TVectorParamCheck params; + const TVectorParamCheck* addParams = NULL; + const string * txt = NULL; + if ( descIndex == 0xFFFFFFFF ) { - nlwarning(" Invalid descIndex %u, size is %u",descIndex,OverloadedDescs.size() ); txt = &DescText; addParams = &DescParams; } else { - txt = &(OverloadedDescs[descIndex].Text); - addParams = &(OverloadedDescs[descIndex].Params); + if ( descIndex >= OverloadedDescs.size() ) + { + nlwarning(" Invalid descIndex %u, size is %u",descIndex,OverloadedDescs.size() ); + txt = &DescText; + addParams = &DescParams; + } + else + { + txt = &(OverloadedDescs[descIndex].Text); + addParams = &(OverloadedDescs[descIndex].Params); + } } + params.reserve(1 + (*addParams).size() ); + params.push_back(STRING_MANAGER::TParam(STRING_MANAGER::entity)); + params.back().setEIdAIAlias(id, CAIAliasTranslator::getInstance()->getAIAlias(id)); + params.insert(params.end(), (*addParams).begin(), (*addParams).end()); + + + CMissionParser::solveEntitiesNames(params,userRow,id); + return STRING_MANAGER::sendStringToClient( userRow,*txt,params ); } - params.reserve(1 + (*addParams).size() ); - params.push_back(STRING_MANAGER::TParam(STRING_MANAGER::entity)); - params.back().setEIdAIAlias(id, CAIAliasTranslator::getInstance()->getAIAlias(id)); - params.insert(params.end(), (*addParams).begin(), (*addParams).end()); - - - CMissionParser::solveEntitiesNames(params,userRow,id); - return STRING_MANAGER::sendStringToClient( userRow,*txt,params ); }// CMissionTemplate sendDetailsText /* diff --git a/code/ryzom/server/src/entities_game_service/outpost_manager/outpost.cpp b/code/ryzom/server/src/entities_game_service/outpost_manager/outpost.cpp index 36e19db6e..32c21a4c7 100644 --- a/code/ryzom/server/src/entities_game_service/outpost_manager/outpost.cpp +++ b/code/ryzom/server/src/entities_game_service/outpost_manager/outpost.cpp @@ -1510,7 +1510,7 @@ PVP_RELATION::TPVPRelation COutpost::getPVPRelation( CCharacter * user, CEntityB } } - return PVP_RELATION::NeutralPVP; + return PVP_RELATION::Neutral; } // getPVPRelation // diff --git a/code/ryzom/server/src/entities_game_service/phrase_manager/combat_phrase.cpp b/code/ryzom/server/src/entities_game_service/phrase_manager/combat_phrase.cpp index 71c40d394..0e34f243f 100644 --- a/code/ryzom/server/src/entities_game_service/phrase_manager/combat_phrase.cpp +++ b/code/ryzom/server/src/entities_game_service/phrase_manager/combat_phrase.cpp @@ -1136,10 +1136,25 @@ bool CCombatPhrase::validate() if(_MeleeCombat) { // check combat float mode + uint32 range; + if (!combatDefender || !combatDefender->getEntity()) + return false; + CCharacter *character = PlayerManager.getChar(_Attacker->getEntityRowId()); - if (character && !character->meleeCombatIsValid()) + CCharacter *cdefender = PlayerManager.getChar(defender->getEntityRowId()); + if ( defender->getId().getType() == RYZOMID::player ) { - if (!_TargetTooFarMsg) + if (character && character->hasMoved() && cdefender && cdefender->hasMoved()) + range = 10000; + else + range = 3000; + } + else + range = 6000; + + if ((character && !character->meleeCombatIsValid()) || ! PHRASE_UTILITIES::testRange(*actingEntity, *defender, range )) + { + if (!_TargetTooFarMsg && (character && !character->meleeCombatIsValid())) { PHRASE_UTILITIES::sendSimpleMessage( _Attacker->getEntityRowId(), "BS_TARGET_TOO_FAR_OR"); _TargetTooFarMsg = true; @@ -1488,11 +1503,26 @@ bool CCombatPhrase::update() if (_MeleeCombat ) { debugStep = 18; + if (!combatDefender || !combatDefender->getEntity()) + return false; + uint32 range; + CCharacter *character = dynamic_cast (actor); - if (character && !character->meleeCombatIsValid()) + CCharacter *defender = dynamic_cast (combatDefender->getEntity()); + if ( combatDefender->getEntity()->getId().getType() == RYZOMID::player ) + { + if (character && character->hasMoved() && defender && defender->hasMoved() ) + range = 10000; + else + range = 3000; + } + else + range = 6000; + + if ((character && !character->meleeCombatIsValid()) || !PHRASE_UTILITIES::testRange(*actor, *combatDefender->getEntity(), range)) { debugStep = 19; - if (!_TargetTooFarMsg && !_Idle) + if (!_TargetTooFarMsg && !_Idle && (character && !character->meleeCombatIsValid())) { PHRASE_UTILITIES::sendSimpleMessage( actor->getId(), "BS_TARGET_TOO_FAR_OR"); _TargetTooFarMsg = true; diff --git a/code/ryzom/server/src/entities_game_service/phrase_manager/faber_action.cpp b/code/ryzom/server/src/entities_game_service/phrase_manager/faber_action.cpp index c49a45429..2e3b9da5e 100644 --- a/code/ryzom/server/src/entities_game_service/phrase_manager/faber_action.cpp +++ b/code/ryzom/server/src/entities_game_service/phrase_manager/faber_action.cpp @@ -119,6 +119,11 @@ public: } float successFactor = rollSuccessFactor( c, phrase, deltaLvl ); + + ITEMFAMILY::EItemFamily family = phrase->getCraftedItemStaticForm()->Family; + if( family==ITEMFAMILY::CRAFTING_TOOL || family==ITEMFAMILY::HARVEST_TOOL ) + successFactor = 1.0f; + if( successFactor == 0.0f ) { //Failure @@ -281,7 +286,7 @@ public: } else { - c->wearRightHandItem(phrase->getMps().size()/10); + c->wearRightHandItem((double)phrase->getMps().size()/10); // report Xp Gain unless used tool is worned PROGRESSIONPVE::CCharacterProgressionPVE::getInstance()->actionReport( report, true, false ); diff --git a/code/ryzom/server/src/entities_game_service/phrase_manager/s_link_effect.cpp b/code/ryzom/server/src/entities_game_service/phrase_manager/s_link_effect.cpp index 200c9747d..7020797f2 100644 --- a/code/ryzom/server/src/entities_game_service/phrase_manager/s_link_effect.cpp +++ b/code/ryzom/server/src/entities_game_service/phrase_manager/s_link_effect.cpp @@ -150,6 +150,10 @@ bool CSLinkEffect::update(CTimerEvent * event, bool) CCharacter *player = dynamic_cast (caster); if (player) { + if (player->isDead()) + { + endEffect = true; + } _Focus.init(player->getRightHandItem()); } } diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character.cpp b/code/ryzom/server/src/entities_game_service/player_manager/character.cpp index 3107ba75c..5234407c8 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/character.cpp @@ -146,6 +146,7 @@ #include "modules/client_command_forwarder.h" #include "server_share/log_character_gen.h" #include "server_share/log_item_gen.h" +#include "server_share/mongo_wrapper.h" /////////// // USING // @@ -670,6 +671,8 @@ CCharacter::CCharacter(): CEntityBase(false), _LastTickNpcControlUpdated = CTickEventHandler::getGameCycle(); _LastWebCommandIndex = 0; + _LastUrlIndex = 0; + _CustomMissionsParams.clear(); @@ -1533,6 +1536,9 @@ uint32 CCharacter::tickUpdate() nextUpdate = 8; } + _SavedPosX = _EntityState.X(); + _SavedPosY = _EntityState.Y(); + return nextUpdate; } // tickUpdate // @@ -2401,6 +2407,17 @@ void CCharacter::applyRegenAndClipCurrentValue() // restore value without weight malus _PhysScores.SpeedVariationModifier -= _LastAppliedWeightMalus; + // adapt speed of mount without weight malus + if( TheDataset.isAccessible(_EntityMounted()) ) + { + TDataSetRow creatureId = _EntityMounted; + CCreature *creature = CreatureManager.getCreature(creatureId); + if (creature) + { + creature->setSpeedVariationModifier(_PhysScores.SpeedVariationModifier); + } + } + // compute new value _LastAppliedWeightMalus = getWeightMalus(); _PhysScores.SpeedVariationModifier += _LastAppliedWeightMalus; @@ -3705,7 +3722,28 @@ void CCharacter::setTargetBotchatProgramm( CEntityBase * target, const CEntityId // send the web page url SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal); - params[0].Literal= c->getWebPage(); + string url = c->getWebPage(); + + // add ? or & with + if ( url.find('?') == string::npos ) + url += NLMISC::toString("?urlidx=%d", getUrlIndex()); + else + url += NLMISC::toString("&urlidx=%d", getUrlIndex()); + + setUrlIndex(getUrlIndex()+1); + + url += "&player_eid="+getId().toString(); + + // add cheksum : pnj eid + url += "&teid="+c->getId().toString(); + + string defaultSalt = toString(getLastConnectedDate()); + nlinfo(defaultSalt.c_str()); + nlinfo(url.c_str()); + string control = "&hmac="+getHMacSHA1((uint8*)&url[0], (uint32)url.size(), (uint8*)&defaultSalt[0], (uint32)defaultSalt.size()).toString(); + + params[0].Literal= url+control; + text = STRING_MANAGER::sendStringToClient(_EntityRowId, "LITERAL", params ); // _PropertyDatabase.setProp( "TARGET:CONTEXT_MENU:WEB_PAGE_URL" , text ); CBankAccessor_PLR::getTARGET().getCONTEXT_MENU().setWEB_PAGE_URL(_PropertyDatabase, text ); @@ -3856,6 +3894,12 @@ void CCharacter::sendBetaTesterStatus() sendReservedTitleStatus( CHARACTER_TITLE::FBT, p->isBetaTester() ); + /*if (!p->isBetaTester() && _Title == CHARACTER_TITLE::FBT) + { + _Title = CHARACTER_TITLE::Refugee; + registerName(); + }*/ + if (!p->isBetaTester() && _NewTitle == "FBT") { _NewTitle = "Refugee"; @@ -3874,6 +3918,12 @@ void CCharacter::sendWindermeerStatus() sendReservedTitleStatus( CHARACTER_TITLE::WIND, p->isWindermeerCommunity() ); + /*if ( !p->isWindermeerCommunity() && _Title == CHARACTER_TITLE::WIND) + { + _Title = CHARACTER_TITLE::Refugee; + registerName(); + }*/ + if ( !p->isWindermeerCommunity() && _NewTitle == "WIND") { _NewTitle = "Refugee"; @@ -4342,6 +4392,37 @@ void CCharacter::addKnownBrick( const CSheetId& brickId ) } } //addKnownBrick// +//----------------------------------------------- +// CCharacter::addKnownBrickBonus add a know brick bonus +//----------------------------------------------- +void CCharacter::addKnownBrickBonus( const CSheetId& brickId ) +{ +// egs_chinfo(" adding new known brick idSheet (%s)", brickId.toString().c_str() ); + const CStaticBrick* brickForm = CSheets::getSBrickForm( brickId ); + if( brickForm ) + { + + // if the brick is a training brick, then apply charac increase + if ( BRICK_FAMILIES::brickType(brickForm->Family) == BRICK_TYPE::TRAINING) + { + processTrainingBrick(brickForm); + } + + // if the brick is a bonus that needs to be taken into account now, do it + switch ( brickForm->Family ) + { + case BRICK_FAMILIES::BPBHFEA: + processForageBonusBrick(brickForm); + break; + case BRICK_FAMILIES::BPBGLA: + processMiscBonusBrick(brickForm); + break; + default:; + } + } + +} //addKnownBrickBonus// + //----------------------------------------------- // CCharacter::removeKnownBrick remove a known brick //----------------------------------------------- @@ -4420,6 +4501,37 @@ void CCharacter::removeKnownBrick( const CSheetId& brickId ) } } //removeKnownBrick// +//----------------------------------------------- +// CCharacter::removeKnownBrickBonus remove a known brick bonus +//----------------------------------------------- +void CCharacter::removeKnownBrickBonus( const CSheetId& brickId ) +{ +// egs_chinfo(" removing a known brick idSheet (%s)", brickId.toString().c_str() ); + const CStaticBrick* brickForm = CSheets::getSBrickForm( brickId ); + if( brickForm ) + { + + // if the brick is a training brick, then apply charac increase + if ( BRICK_FAMILIES::brickType(brickForm->Family) == BRICK_TYPE::TRAINING) + { + unprocessTrainingBrick(brickForm, true); + } + + // if the brick is a bonus that needs to be taken into account now, do it + switch ( brickForm->Family ) + { + case BRICK_FAMILIES::BPBHFEA: + unprocessForageBonusBrick(brickForm); + break; + case BRICK_FAMILIES::BPBGLA: + unprocessMiscBonusBrick(brickForm); + break; + default:; + } + } + +} //removeKnownBrickBonus// + //----------------------------------------------- // CCharacter::processTrainingBrick //----------------------------------------------- @@ -9896,7 +10008,7 @@ void CCharacter::sellItem( INVENTORIES::TInventory inv, uint32 slot, uint32 quan nlwarning(" character %s Invalid item sheet %s : the sheet is invalid",_Id.toString().c_str(),sheet.toString().c_str()); return; } - if ( !itemForm->DropOrSell ) + if ( !item->getMovable() && ( !itemForm->DropOrSell || item->getUnMovable() ) ) { nlwarning(" character %s try to sell item slot %u sheet %s", _Id.toString().c_str(), @@ -10924,6 +11036,47 @@ void CCharacter::acceptExchange(uint8 exchangeId) c->removeExchangeItems(items2, exchangePlayerPets2); } + if (haveAnyPrivilege() && !c->haveAnyPrivilege()) + { + for (uint i = 0; i < items1.size(); ++i) + { + nlinfo ("ADMIN: CSR (%s,%s) exchange %ux%s Q%u with %s", + getId().toString().c_str(), + getName().toString().c_str(), + items1[i]->getStackSize(), + items1[i]->getSheetId().toString().c_str(), + items1[i]->quality(), + c->getName().toString().c_str()); + } + if (_ExchangeMoney) + nlinfo ("ADMIN: CSR (%s,%s) give %u dappers to %s", + getId().toString().c_str(), + getName().toString().c_str(), + _ExchangeMoney, + c->getName().toString().c_str()); + } + + if (c->haveAnyPrivilege() && !haveAnyPrivilege()) + { + for (uint i = 0; i < items2.size(); ++i) + { + nlinfo ("ADMIN: CSR (%s,%s) exchange %ux%s Q%u with %s", + c->getId().toString().c_str(), + c->getName().toString().c_str(), + items2[i]->getStackSize(), + items2[i]->getSheetId().toString().c_str(), + items2[i]->quality(), + getName().toString().c_str()); + } + if (c->_ExchangeMoney) + nlinfo ("ADMIN: CSR (%s,%s) give %u dappers to %s", + c->getId().toString().c_str(), + c->getName().toString().c_str(), + c->_ExchangeMoney, + getName().toString().c_str()); + } + + // do the exchange { TLogContext_Item_Swap logContext(_Id); @@ -11539,7 +11692,8 @@ void CCharacter::cancelStaticActionInProgress(STATIC_ACT_TYPES::TStaticActTypes { setAfkState( false ); // changed : always stop links (so one can only have one link at a time... as casting a new one will cancel the previous one) - stopAllLinks(); + if (!isDead()) + stopAllLinks(); CPhraseManager::getInstance().cancelTopPhrase(_EntityRowId, true); @@ -13130,6 +13284,66 @@ void CCharacter::setPlaces(const std::vector & places) } } +//----------------------------------------------- +// isSpawnValid +//----------------------------------------------- +bool CCharacter::isSpawnValid(bool inVillage, bool inOutpost, bool inStable, bool inAtys) +{ + if (inVillage) + nlinfo("inVillage"); + if (inOutpost) + nlinfo("inOutpost"); + if (inStable) + nlinfo("inStable"); + if (inAtys) + nlinfo("inAtys"); + + const uint size = (uint)_Places.size(); + for ( uint i = 0; i < size; i++ ) + { + CPlace * p = CZoneManager::getInstance().getPlaceFromId( _Places[i] ); + if (p) + { + PLACE_TYPE::TPlaceType place_type = p->getPlaceType(); + nlinfo("Place type = %s", PLACE_TYPE::toString(p->getPlaceType()).c_str()); + if (!inVillage && (place_type == PLACE_TYPE::Village || place_type == PLACE_TYPE::Capital)) + { + CCharacter::sendDynamicSystemMessage( _EntityRowId, "NO_ACTION_IN_VILLAGE" ); + return false; + } + + TAIAlias outpostAlias = getOutpostAlias(); + if (!inOutpost && outpostAlias != 0) + { + CSmartPtr outpost = COutpostManager::getInstance().getOutpostFromAlias( outpostAlias ); + if( outpost && outpost->getState() != OUTPOSTENUMS::Peace ) + { + CCharacter::sendDynamicSystemMessage( _EntityRowId, "NO_ACTION_IN_OUPOST" ); + return false; + } + } + + if( !inStable && _CurrentStable != 0xFFFF ) + { + CCharacter::sendDynamicSystemMessage( _EntityRowId, "NO_ACTION_IN_STABLE" ); + return false; + } + + TDataSetRow dsr = getEntityRowId(); + CMirrorPropValueRO srcCell( TheDataset, dsr, DSPropertyCELL ); + sint32 cell = srcCell; + + if (!inAtys && cell >= 0) + { + CCharacter::sendDynamicSystemMessage( _EntityRowId, "NO_ACTION_IN_ATYS" ); + return false; + } + } + } + + return true; +} + //----------------------------------------------- // memorize //----------------------------------------------- @@ -13658,6 +13872,21 @@ uint16 CCharacter::getFirstFreeSlotInKnownPhrase() } // getFirstFreeSlotInKnownPhrase // +void CCharacter::sendDynamicMessage(const string &phrase, const string &message) +{ + TVectorParamCheck messageParams; + ucstring phraseText; + string phraseName = phrase; + phraseText.fromUtf8(message); + ucstring phraseContent = phrase+"(){["+phraseText+"]}"; + NLNET::CMessage msgout("SET_PHRASE"); + msgout.serial(phraseName); + msgout.serial(phraseContent); + sendMessageViaMirror("IOS", msgout); + PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, phrase, messageParams ); +} + + void CCharacter::sendUrl(const string &url, const string &salt) { string control; @@ -13672,18 +13901,15 @@ void CCharacter::sendUrl(const string &url, const string &salt) } nlinfo(url.c_str()); - TVectorParamCheck titleParams; - TVectorParamCheck textParams; + uint32 userId = PlayerManager.getPlayerId(getId()); - std::string name = "CUSTOM_URL_"+toString(userId); - ucstring phrase = ucstring(name+"(){[WEB : "+url+control+"]}"); - NLNET::CMessage msgout("SET_PHRASE"); - msgout.serial(name); - msgout.serial(phrase); - sendMessageViaMirror("IOS", msgout); + SM_STATIC_PARAMS_1(textParams, STRING_MANAGER::literal); + textParams[0].Literal= "WEB : "+url+control; + + TVectorParamCheck titleParams; uint32 titleId = STRING_MANAGER::sendStringToUser(userId, "web_transactions", titleParams); - uint32 textId = STRING_MANAGER::sendStringToUser(userId, name, textParams); + uint32 textId = STRING_MANAGER::sendStringToClient(_EntityRowId, "LITERAL", textParams ); PlayerManager.sendImpulseToClient(getId(), "USER:POPUP", titleId, textId); } @@ -13695,7 +13921,10 @@ void CCharacter::validateDynamicMissionStep(const string &url) /// set custom mission param void CCharacter::setCustomMissionParams(const string &missionName, const string ¶ms) { - _CustomMissionsParams[missionName] = params; + if (params.empty()) + _CustomMissionsParams.erase(missionName); + else + _CustomMissionsParams[missionName] = params; } /// add custom mission param @@ -13724,6 +13953,21 @@ vector CCharacter::getCustomMissionParams(const string &missionName) return params; } +/// get custom mission text +string CCharacter::getCustomMissionText(const string &missionName) +{ + if (_CustomMissionsParams.empty()) + { + return ""; + } + + if (!_CustomMissionsParams.empty() && _CustomMissionsParams.find(missionName) != _CustomMissionsParams.end()) + { + return _CustomMissionsParams[missionName]; + } + return ""; +} + // !!! Deprecated !!! void CCharacter::addWebCommandCheck(const string &url, const string &data, const string &salt) @@ -14063,6 +14307,49 @@ bool CCharacter::pickUpRawMaterial( uint32 indexInTempInv, bool * lastMaterial ) return false; // don't try to quarter an item for looting } + // Send url for Arcc triggers + + vector params = getCustomMissionParams("__LOOT_SHEET__"); + if (params.size() >= 2) + { + // check if it's the creature have good sheet + CSheetId creatureSheetId(params[1]); + if (creatureSheetId != CSheetId::Unknown && creatureSheetId == creature->getType()) + { + validateDynamicMissionStep(params[0]); + setCustomMissionParams("__LOOT_SHEET__", ""); + } + } + // only check first item + if (indexInTempInv == 0) + { + + params = getCustomMissionParams("__LOOT_SHEET_WITH_ITEM__"); + if (params.size() >= 3) + { + // check if it's the creature have good sheet + CSheetId creatureSheetId(params[1]); + if (creatureSheetId != CSheetId::Unknown && creatureSheetId == creature->getType()) + { + // check if player have item in right hand + CGameItemPtr rightHandItem = getRightHandItem(); + CSheetId needItem(params[2]); + if (rightHandItem != NULL && rightHandItem->getSheetId() == needItem) + { + validateDynamicMissionStep(params[0]); + setCustomMissionParams("__LOOT_SHEET_WITH_ITEM__", ""); + if (params.size() >= 4) + setCustomMissionParams(params[3], ""); + } + else if (params.size() >= 4) + { + string message = getCustomMissionText(params[3]); + if (!message.empty()) + sendDynamicMessage(params[3], message); + } + } + } + } // first slots are filled with loot items, quarter items are not in temp inv but only info in DB uint32 rawMaterialIndex = indexInTempInv - creature->getLootSlotCount(); const CCreatureRawMaterial * mp = creature->getCreatureRawMaterial( rawMaterialIndex ); @@ -14285,6 +14572,13 @@ void CCharacter::resetFameDatabase() { CFameInterface &fi = CFameInterface::getInstance(); + // Check fames and fix bad values + if (!haveAnyPrivilege()) + { + CFameManager::getInstance().enforceFameCaps(getId(), getAllegiance()); + CFameManager::getInstance().setAndEnforceTribeFameCap(getId(), getAllegiance()); + } + for (uint i=0; ienterPVPZone( this, getCurrentPVPZone() ); } // _PropertyDatabase.setProp("CHARACTER_INFO:PVP_OUTPOST:ROUND_LVL_CUR", 0 ); CBankAccessor_PLR::getCHARACTER_INFO().getPVP_OUTPOST().setROUND_LVL_CUR(_PropertyDatabase, 0 ); @@ -19063,6 +19371,10 @@ bool CCharacter::setGuildId( uint32 guildId ) _GuildId = guildId; +#ifdef HAVE_MONGO + CMongo::update("users", toString("{'game.cid':%"NL_I64"u}", _Id.getShortId()), toString("{$set:{'game.guildId':%d}}", guildId)); +#endif + return true; } diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character.h b/code/ryzom/server/src/entities_game_service/player_manager/character.h index de6d3f110..b0067a5e0 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/character.h @@ -637,6 +637,12 @@ public: */ void setEnterFlag( bool b ); + /** + * Get/Set the score permanent modifier + */ + uint32 getScorePermanentModifiers(SCORES::TScores score) const; + void setScorePermanentModifiers(SCORES::TScores score, uint32 value); + /** * Get the enter flag * \return true if the player entered the game, false if he left @@ -717,7 +723,10 @@ public: void updateTarget(); /// add a known brick - void addKnownBrick( const NLMISC::CSheetId& brickId ); + void addKnownBrick( const NLMISC::CSheetId& brickId); + + /// add a known brick bonus + void addKnownBrickBonus( const NLMISC::CSheetId& brickId); /// check if have brick bool haveBrick( const NLMISC::CSheetId& brickId ); @@ -725,6 +734,9 @@ public: /// remove a known brick void removeKnownBrick( const NLMISC::CSheetId& brickId ); + /// remove a known brick + void removeKnownBrickBonus( const NLMISC::CSheetId& brickId ); + /// get known bricks const std::set &getKnownBricks() const; @@ -1542,6 +1554,9 @@ public: /// client (in)validate melee combat void validateMeleeCombat(bool flag); + /// check is player can spawn npc group in here position + bool isSpawnValid(bool inVillage, bool inOutpost, bool inStable, bool inAtys); + /// memorize a phrase void memorize(uint8 memorizationSet, uint8 index, uint16 phraseId, const std::vector &bricks); @@ -1660,6 +1675,9 @@ public: /// get ammo item virtual CGameItemPtr getAmmoItem() const; + /// send dynamic message + void sendDynamicMessage(const std::string &phrase, const std::string &message); + /// send custom url void sendUrl(const std::string &url, const std::string &salt); @@ -1672,6 +1690,9 @@ public: /// get custom mission params std::vector getCustomMissionParams(const std::string &missionName); + /// get custom mission texts + std::string getCustomMissionText(const std::string &missionName); + /// validate dynamic mission step sending url void validateDynamicMissionStep(const std::string &url); @@ -3174,6 +3195,11 @@ private: /// old pos Y mutable sint32 _OldPosY; + /// old pos X + mutable sint32 _SavedPosX; + /// old pos Y + mutable sint32 _SavedPosY; + /// last X position written in DB sint32 _LastPosXInDB; /// last Y position written in DB @@ -3316,6 +3342,9 @@ private: /// last webcommand index uint32 _LastWebCommandIndex; + /// last web url index + uint32 _LastUrlIndex; + std::map _CustomMissionsParams; // for a power/combat event, stores start and end ticks @@ -3716,6 +3745,9 @@ private: /// keep the Ids of the mission queues in which is this player std::vector _MissionsQueues; + /// keep the validated web commandes + std::set _ValideWebCommandIndex; + /// keep here the queue for which this player currently has an enter critical zone proposal uint32 _EnterCriticalZoneProposalQueueId; @@ -3748,7 +3780,7 @@ private: public: uint32 getLastDisconnectionDate(); - + bool hasMoved(); private: TAIAlias _SelectedOutpost; @@ -3782,6 +3814,11 @@ public: void setWebCommandIndex(uint32 index) { _LastWebCommandIndex = index;} uint32 getWebCommandIndex() const { return _LastWebCommandIndex;} + void validateWebCommandIndex(uint32 index) { _ValideWebCommandIndex.insert(index);} + uint32 isValidWebCommandIndex(uint32 index) { return _ValideWebCommandIndex.find(index) != _ValideWebCommandIndex.end();} + + void setUrlIndex(uint32 index) { _LastUrlIndex = index;} + uint32 getUrlIndex() const { return _LastUrlIndex;} bool getInvisibility() const { return _Invisibility;} /// Set the invisibility flag, NB : just for persistence, do not change nothing. diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character_inlines.h b/code/ryzom/server/src/entities_game_service/player_manager/character_inlines.h index d0bfe3358..eb45824a1 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character_inlines.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/character_inlines.h @@ -63,6 +63,16 @@ inline CHARACTER_TITLE::ECharacterTitle CCharacter::getTitle() const //------------------------------------------------------------------------------ +inline uint32 CCharacter::getScorePermanentModifiers(SCORES::TScores score) const +{ + return _ScorePermanentModifiers[score]; +} + +inline void CCharacter::setScorePermanentModifiers(SCORES::TScores score, uint32 value) +{ + _ScorePermanentModifiers[score] = value; +} + inline bool CCharacter::getEnterFlag() const { return _Enter; @@ -1047,6 +1057,12 @@ inline TAIAlias CCharacter::getSelectedOutpost() const return _SelectedOutpost; } +// return true if character has moved +inline bool CCharacter::hasMoved() +{ + return ( _EntityState.X() != _SavedPosX || _EntityState.Y() != _SavedPosY ); +} + //------------------------------------------------------------------------------ //inline CCharacter::CCharacterDbReminder* CCharacter::getDataIndexReminder() diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character_inventory_manipulation.cpp b/code/ryzom/server/src/entities_game_service/player_manager/character_inventory_manipulation.cpp index 139cf1b4e..954037b56 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character_inventory_manipulation.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/character_inventory_manipulation.cpp @@ -819,7 +819,7 @@ void CCharacter::moveItem(INVENTORIES::TInventory srcInvId, uint32 srcSlot, INVE return; // cannot move a non dropable item or an active xp catalyser - if ((!srcForm->DropOrSell && !canPutNonDropableItemInInventory(dstInvId)) || isAnActiveXpCatalyser(srcItem)) + if (!srcItem->getMovable() && (srcItem->getUnMovable() || (!srcForm->DropOrSell && !canPutNonDropableItemInInventory(dstInvId)) || isAnActiveXpCatalyser(srcItem))) return; // You cannot exchange genesis named items @@ -1326,6 +1326,22 @@ bool CCharacter::checkPreRequired(const CGameItemPtr & item, bool equipCheck ) } } + 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); + if (item->getPhraseId().find("foragetool_") != 0 && ( + (item->getRequiredFaction() == "kami" && (allegeance.first != PVP_CLAN::Kami || getOrganization() != 0)) || + (item->getRequiredFaction() == "karavan" && (allegeance.first != PVP_CLAN::Karavan || getOrganization() != 0)) || + (item->getRequiredFaction() == "marauder" && (!neutralcult || !neutralciv || getOrganization() != 5)) || + (item->getRequiredFaction() == "neutralcult" && (!neutralcult || getOrganization() != 0)) || + (item->getRequiredFaction() == "neutralciv" && (!neutralciv || getOrganization() != 0)) || + (item->getRequiredFaction() == "neutral" && (!neutralcult || !neutralciv || getOrganization() != 0)) || + (item->getRequiredFaction() == "fyros" && (allegeance.second != PVP_CLAN::Fyros || getOrganization() != 0)) || + (item->getRequiredFaction() == "matis" && (allegeance.second != PVP_CLAN::Matis || getOrganization() != 0)) || + (item->getRequiredFaction() == "tryker" && (allegeance.second != PVP_CLAN::Tryker || getOrganization() != 0)) || + (item->getRequiredFaction() == "zorai" && (allegeance.second != PVP_CLAN::Zorai || getOrganization() != 0)))) + requiredRespected = false; + if( requiredRespected == false && equipCheck ) { PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, "REQUIRED_EQUIP" ); @@ -2848,8 +2864,8 @@ void CCharacter::procEnchantment() rightHandItem->setLatencyEndDate( phrase.getCastingTime() + CTickEventHandler::getGameCycle() ); } } - else - nlwarning("user %s : no valid image for right weapon", _Id.toString().c_str()); + /* else + nlwarning("user %s : no valid image for right weapon", _Id.toString().c_str());*/ } else { diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character_version_adapter.cpp b/code/ryzom/server/src/entities_game_service/player_manager/character_version_adapter.cpp index adc281dda..a497e225e 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character_version_adapter.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/character_version_adapter.cpp @@ -21,6 +21,8 @@ ///////////// #include "stdpch.h" +#include "guild_manager/fame_manager.h" + #include "player_manager/character_version_adapter.h" #include "player_manager/player_manager.h" #include "player_manager/player.h" @@ -89,8 +91,11 @@ uint32 CCharacterVersionAdapter::currentVersionNumber() const // 20 : (06/03/2006) give full hp to tools (even in player room and guild inv) // 21 : (19/04/2006) convert to position stack & store the mainland in db // 22 : (15/05/2006) reset flag pvp for resolve migration timer pb + // 23 : (05/04/2013) fix post merge marauder plan issue + // 24 : (23/10/2014) fix post merge rite bonus issue + // 25 : (05/03/2015) fix required faction in items on inventory //////////////////////////////////// - return 22; + return 25; } @@ -102,7 +107,7 @@ void CCharacterVersionAdapter::adaptCharacterFromVersion( CCharacter &character, { case 0: adaptToVersion1(character); case 1: adaptToVersion2(character); - case 2: adaptToVersion3(character); + case 2: adaptToVersion3(character); case 3: adaptToVersion4(character); case 4: adaptToVersion5(character); case 5: adaptToVersion6(character); @@ -122,6 +127,9 @@ void CCharacterVersionAdapter::adaptCharacterFromVersion( CCharacter &character, case 19: adaptToVersion20(character); case 20: adaptToVersion21(character); case 21: adaptToVersion22(character); + case 22: adaptToVersion23(character); + case 23: adaptToVersion24(character); + case 24: adaptToVersion25(character); default:; } } @@ -1009,3 +1017,330 @@ void CCharacterVersionAdapter::adaptToVersion22(CCharacter &character) const { character.resetPVPTimers(); } + + +//--------------------------------------------------- +void CCharacterVersionAdapter::adaptToVersion23(CCharacter &character) const +{ + nlinfo("Start"); + //check if phrase is already known and Fix marauder sbricks + sp craft + uint16 sp = 0; + vector parts; + parts.push_back("b"); + parts.push_back("g"); + parts.push_back("h"); + parts.push_back("p"); + parts.push_back("s"); + parts.push_back("v"); + vector deletePhrases; + // Check each part + for (uint i = 0; i < parts.size(); i++) + { + CSheetId phraseSId = CSheetId("abcbah"+parts[i]+".sphrase"); + CSheetId brickMSid = CSheetId("bcbah"+parts[i]+"_m.sbrick"); + CSheetId brickSid = CSheetId("bcbah"+parts[i]+".sbrick"); + + if (character._BoughtPhrases.find(phraseSId) != character._BoughtPhrases.end()) + { + if (character._KnownBricks.find(brickMSid) != character._KnownBricks.end() + && character._KnownBricks.find(brickSid) == character._KnownBricks.end() ) + { + nlinfo("Bugged Char with phrase %s!", parts[i].c_str()); + // Remove phrase and brick + character._BoughtPhrases.erase(phraseSId); + character._KnownBricks.erase(brickMSid); + sp += 40; + } + } + } + + if (sp > 0) + { + nlinfo("Adding %d SP Craft !", sp); + character._SpType[EGSPD::CSPType::Craft] += sp; + } + +} + +//--------------------------------------------------- +void CCharacterVersionAdapter::adaptToVersion24(CCharacter &character) const +{ + // HP + uint32 bonus; + vector bricks; + bricks.push_back("bthp01"); + bricks.push_back("bthp04"); + bricks.push_back("bthp06"); + bricks.push_back("bthp08"); + bricks.push_back("bthp12"); + bricks.push_back("bthp13"); + bricks.push_back("bthp16"); + bricks.push_back("bthp17"); + bricks.push_back("bthp18"); + bricks.push_back("bthp20"); + + bonus = 0; + for (uint i = 0; i < bricks.size(); i++) + { + CSheetId brickSid = CSheetId(bricks[i]+".sbrick"); + if (character._KnownBricks.find(brickSid) != character._KnownBricks.end()) + { + bonus += 50; + } + } + + if (character.getScorePermanentModifiers(SCORES::hit_points) < bonus) + { + nlinfo("RITE BONUS FIX: Player %s need %d (hp) but have %d !", character.getName().toString().c_str(), bonus, character.getScorePermanentModifiers(SCORES::hit_points)); + character.setScorePermanentModifiers(SCORES::hit_points, bonus); + } + + // SAP + bricks.clear(); + bricks.push_back("btsap03"); + bricks.push_back("btsap04"); + bricks.push_back("btsap12"); + bricks.push_back("btsap16"); + bricks.push_back("btsap18"); + + bonus = 0; + for (uint i = 0; i < bricks.size(); i++) + { + CSheetId brickSid = CSheetId(bricks[i]+".sbrick"); + if (character._KnownBricks.find(brickSid) != character._KnownBricks.end()) + { + bonus += 50; + } + } + + if (character.getScorePermanentModifiers(SCORES::sap) < bonus) + { + nlinfo("RITE BONUS FIX: Player %s need %d (sap) but have %d !", character.getName().toString().c_str(),bonus, character.getScorePermanentModifiers(SCORES::sap)); + character.setScorePermanentModifiers(SCORES::sap, bonus); + } + + // FOCUS + bricks.clear(); + bricks.push_back("btfoc01"); + bricks.push_back("btfoc04"); + bricks.push_back("btfoc09"); + bricks.push_back("btfoc11"); + bricks.push_back("btfoc15"); + bricks.push_back("btfoc17"); + bricks.push_back("btfoc19"); + bricks.push_back("btfoc20"); + + bonus = 0; + for (uint i = 0; i < bricks.size(); i++) + { + CSheetId brickSid = CSheetId(bricks[i]+".sbrick"); + if (character._KnownBricks.find(brickSid) != character._KnownBricks.end()) + { + bonus += 50; + } + } + + if (character.getScorePermanentModifiers(SCORES::focus) < bonus) + { + nlinfo("RITE BONUS FIX: Player %s need %d (focus) but have %d !", character.getName().toString().c_str(),bonus, character.getScorePermanentModifiers(SCORES::focus)); + character.setScorePermanentModifiers(SCORES::focus, bonus); + } + + // STA + bricks.clear(); + bricks.push_back("btsta13"); + bricks.push_back("btsta14"); + bricks.push_back("btsta15"); + bricks.push_back("btsta16"); + bricks.push_back("btsta17"); + bricks.push_back("btsta20"); + + bonus = 0; + for (uint i = 0; i < bricks.size(); i++) + { + CSheetId brickSid = CSheetId(bricks[i]+".sbrick"); + if (character._KnownBricks.find(brickSid) != character._KnownBricks.end()) + { + bonus += 50; + } + } + + if (character.getScorePermanentModifiers(SCORES::stamina) < bonus) + { + nlinfo("RITE BONUS FIX: Player %s need %d (stamina) but have %d !", character.getName().toString().c_str(),bonus, character.getScorePermanentModifiers(SCORES::stamina)); + character.setScorePermanentModifiers(SCORES::stamina, bonus); + } +} + + +//--------------------------------------------------- +void CCharacterVersionAdapter::adaptToVersion25(CCharacter &character) const +{ + + const uint sizeInv = INVENTORIES::NUM_INVENTORY; + for ( uint i = 0; i < sizeInv ; ++i ) + if (character._Inventory[i] != NULL) + { + CInventoryPtr childSrc = character._Inventory[i]; + for ( uint j = 0; j < childSrc->getSlotCount(); j++ ) + { + CGameItemPtr item = childSrc->getItem(j); + if (item != NULL) + { + string phraseId = item->getPhraseId(); + + if ( (phraseId == "shield_ep2_kami50_1") || + (phraseId == "shield_ep2_kami50_2") || + (phraseId == "shield_ep2_kami100_1") || + (phraseId == "shield_ep2_kami100_2") || + (phraseId == "shield_ep2_kami150_1") || + (phraseId == "shield_ep2_kami150_2") || + (phraseId == "shield_ep2_kami200_1") || + (phraseId == "shield_ep2_kami200_2") || + (phraseId == "shield_ep2_kami250_1") || + (phraseId == "shield_ep2_kami250_2") || + (phraseId == "magic_dress_ep2_kami50_1") || + (phraseId == "magic_dress_ep2_kami50_2") || + (phraseId == "magic_dress_ep2_kami100_1") || + (phraseId == "magic_dress_ep2_kami100_2") || + (phraseId == "magic_dress_ep2_kami150_1") || + (phraseId == "magic_dress_ep2_kami150_2") || + (phraseId == "magic_dress_ep2_kami200_1") || + (phraseId == "magic_dress_ep2_kami200_2") || + (phraseId == "magic_dress_ep2_kami250_1") || + (phraseId == "magic_dress_ep2_kami250_2")/* || + (phraseId == "foragetool_kami_ep2_50_1") || + (phraseId == "foragetool_kami_ep2_50_2") || + (phraseId == "foragetool_kami_ep2_100_1") || + (phraseId == "foragetool_kami_ep2_100_2") || + (phraseId == "foragetool_kami_ep2_150_1") || + (phraseId == "foragetool_kami_ep2_150_2") || + (phraseId == "foragetool_kami_ep2_200_1") || + (phraseId == "foragetool_kami_ep2_200_2") || + (phraseId == "foragetool_kami_ep2_250_1") || + (phraseId == "foragetool_kami_ep2_250_2")*/) + { + item->setRequiredFaction("kami"); + item->addHp(item->durability()); + + } + +/* + if ( (phraseId == "foragetool_tryker_50") || + (phraseId == "foragetool_tryker_100") || + (phraseId == "foragetool_tryker_150") || + (phraseId == "foragetool_tryker_200") || + (phraseId == "foragetool_tryker_250") || + (phraseId == "foragetool_tryker_sfx")) + { + item->setRequiredFaction("tryker"); + } + + + if ( (phraseId == "foragetool_zorai_50") || + (phraseId == "foragetool_zorai_100") || + (phraseId == "foragetool_zorai_150") || + (phraseId == "foragetool_zorai_200") || + (phraseId == "foragetool_zorai_250") || + (phraseId == "foragetool_zorai_sfx")) + { + item->setRequiredFaction("zorai"); + } +*/ + + if ( (phraseId == "shield_pvp_50") || + (phraseId == "shield_pvp_100") || + (phraseId == "shield_pvp_150") || + (phraseId == "shield_pvp_200") || + (phraseId == "shield_pvp_250") || + (phraseId == "magic_dress_pvp_50") || + (phraseId == "magic_dress_pvp_100") || + (phraseId == "magic_dress_pvp_150") || + (phraseId == "magic_dress_pvp_200") || + (phraseId == "magic_dress_pvp_250")) + { + item->setRequiredFaction("neutralcult"); + item->addHp(item->durability()); + + } + +/* + if ( (phraseId == "foragetool_fyros_50") || + (phraseId == "foragetool_fyros_100") || + (phraseId == "foragetool_fyros_150") || + (phraseId == "foragetool_fyros_200") || + (phraseId == "foragetool_fyros_250") || + (phraseId == "foragetool_fyros_sfx")) + { + item->setRequiredFaction("fyros"); + } + + + if ( (phraseId == "foragetool_matis_50") || + (phraseId == "foragetool_matis_100") || + (phraseId == "foragetool_matis_150") || + (phraseId == "foragetool_matis_200") || + (phraseId == "foragetool_matis_250") || + (phraseId == "foragetool_matis_sfx")) + { + item->setRequiredFaction("matis"); + } +*/ + + if ( (phraseId == "shield_ep2_karavan50_1") || + (phraseId == "shield_ep2_karavan50_2") || + (phraseId == "shield_ep2_karavan100_1") || + (phraseId == "shield_ep2_karavan100_2") || + (phraseId == "shield_ep2_karavan150_1") || + (phraseId == "shield_ep2_karavan150_2") || + (phraseId == "shield_ep2_karavan200_1") || + (phraseId == "shield_ep2_karavan200_2") || + (phraseId == "shield_ep2_karavan250_1") || + (phraseId == "shield_ep2_karavan250_2") || + (phraseId == "magic_dress_ep2_karavan50_1") || + (phraseId == "magic_dress_ep2_karavan50_2") || + (phraseId == "magic_dress_ep2_karavan100_1") || + (phraseId == "magic_dress_ep2_karavan100_2") || + (phraseId == "magic_dress_ep2_karavan150_1") || + (phraseId == "magic_dress_ep2_karavan150_2") || + (phraseId == "magic_dress_ep2_karavan200_1") || + (phraseId == "magic_dress_ep2_karavan200_2") || + (phraseId == "magic_dress_ep2_karavan250_1") || + (phraseId == "magic_dress_ep2_karavan250_2") || + (phraseId == "foragetool_karavan_ep2_50_1")/* || + (phraseId == "foragetool_karavan_ep2_50_2") || + (phraseId == "foragetool_karavan_ep2_100_1") || + (phraseId == "foragetool_karavan_ep2_100_2") || + (phraseId == "foragetool_karavan_ep2_150_1") || + (phraseId == "foragetool_karavan_ep2_150_2") || + (phraseId == "foragetool_karavan_ep2_200_1") || + (phraseId == "foragetool_karavan_ep2_200_2") || + (phraseId == "foragetool_karavan_ep2_250_1") || + (phraseId == "foragetool_karavan_ep2_250_2")*/) + { + item->setRequiredFaction("karavan"); + item->addHp(item->durability()); + + } + + + if ( (phraseId == "shield_mar_50") || + (phraseId == "shield_mar_100") || + (phraseId == "shield_mar_150") || + (phraseId == "shield_mar_200") || + (phraseId == "shield_mar_250") || + (phraseId == "magic_dress_mar_50") || + (phraseId == "magic_dress_mar_100") || + (phraseId == "magic_dress_mar_150") || + (phraseId == "magic_dress_mar_200") || + (phraseId == "magic_dress_mar_250")) + { + item->setRequiredFaction("marauder"); + item->addHp(item->durability()); + } + } + } + } + + character.unequipCharacter( INVENTORIES::handling, INVENTORIES::left ); +} diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character_version_adapter.h b/code/ryzom/server/src/entities_game_service/player_manager/character_version_adapter.h index 3d3917a85..f151321c6 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character_version_adapter.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/character_version_adapter.h @@ -83,6 +83,9 @@ private: void adaptToVersion20(CCharacter &character) const; void adaptToVersion21(CCharacter &character) const; void adaptToVersion22(CCharacter &character) const; + void adaptToVersion23(CCharacter &character) const; + void adaptToVersion24(CCharacter &character) const; + void adaptToVersion25(CCharacter &character) const; private: /// unique instance static CCharacterVersionAdapter* _Instance; diff --git a/code/ryzom/server/src/entities_game_service/player_manager/db_string_updater.h b/code/ryzom/server/src/entities_game_service/player_manager/db_string_updater.h index e9296b0ef..43c047857 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/db_string_updater.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/db_string_updater.h @@ -62,7 +62,7 @@ class CDBStringUpdater : public NLMISC::CSingleton // hasher for the identifier struct THashDBStringLeaf { - enum { bucket_size = 4, min_buckets = 8, }; + enum { bucket_size = 4, min_buckets = 8 }; size_t operator()(const TBDStringLeaf &stringLeaf) const { return ((size_t)stringLeaf.ClientDB>>4) ^ ((size_t)stringLeaf.Node>>4); diff --git a/code/ryzom/server/src/entities_game_service/player_manager/persistent_player_data.cpp b/code/ryzom/server/src/entities_game_service/player_manager/persistent_player_data.cpp index e777f3067..576819fcc 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/persistent_player_data.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/persistent_player_data.cpp @@ -507,6 +507,7 @@ static void prepareCharacterPositionForStore ( COfflineEntityState & state, cons STRUCT_VECT(_Pact)\ STRUCT_VECT(_KnownPhrases)\ STRUCT_MAP(TAIAlias, TMissionHistory, _MissionHistories)\ + PROP_MAP(string, string, _CustomMissionsParams)\ LSTRUCT(_WelcomeMissionDesc, if (_WelcomeMissionDesc.isValid()))\ STRUCT_ARRAY(_PlayerPets,_PlayerPets.size())\ \ @@ -1339,6 +1340,7 @@ private: PROP2(_Recommended, uint32, _Recommended, _Recommended=val)\ PROP2(_CreatorId, CEntityId, _CreatorId, _CreatorId=val)\ PROP2(_PhraseId, string, _PhraseId, _PhraseId=val)\ + PROP2(_RequiredFaction, string, _RequiredFaction, _RequiredFaction=val)\ LSTRUCT2(_CraftParameters, if (_CraftParameters != NULL), _CraftParameters->store(pdr), _CraftParameters = new CItemCraftParameters; _CraftParameters->apply(pdr))\ LPROP2(_SlotImage, uint16, if (0), 0xffff, slotImage=val)\ LPROP2(_SapLoad, uint32, if (_SapLoad!=0), _SapLoad, _SapLoad=val)\ @@ -1357,6 +1359,9 @@ private: STRUCT_VECT(_TypeSkillMods)\ LPROP_VECT(CSheetId, _Enchantment, VECT_LOGIC(_Enchantment) if (_Enchantment[i]!=CSheetId::Unknown))\ PROP2(_CustomText, ucstring, _CustomText, _CustomText=val)\ + PROP2(_CustomName, ucstring, _CustomName, _CustomName=val)\ + PROP(bool, _Movable)\ + PROP(bool, _UnMovable)\ PROP(bool, _LockedByOwner)\ //#pragma message( PERSISTENT_GENERATION_MESSAGE ) diff --git a/code/ryzom/server/src/entities_game_service/player_manager/player_manager.cpp b/code/ryzom/server/src/entities_game_service/player_manager/player_manager.cpp index d02da2948..ab1d65971 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/player_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/player_manager.cpp @@ -460,6 +460,7 @@ void CPlayerManager::addClientCallback() { "SET_PLAYER_SEASON", cbSetPlayerSeason }, // from DSS { "TELEPORT_PLAYER", cbTeleportPlayer }, // from AIS + { "TRIGGER_WEBIG", cbTriggerWebig }, // from AIS { "SET_CHAR_AIINSTANCE", cbSetCharacterAIInstance}, diff --git a/code/ryzom/server/src/entities_game_service/player_manager/player_manager.h b/code/ryzom/server/src/entities_game_service/player_manager/player_manager.h index 5e68af4d2..95ceda197 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/player_manager.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/player_manager.h @@ -50,7 +50,7 @@ extern CGenericXmlMsgHeaderManager GenericMsgManager; struct CServiceIdHash { - enum { bucket_size = 4, min_buckets = 8, }; + enum { bucket_size = 4, min_buckets = 8 }; size_t operator () ( const NLNET::TServiceId &sid ) const { return sid.get(); } bool operator()(const NLNET::TServiceId &left, const NLNET::TServiceId &right) const { return left < right; } }; diff --git a/code/ryzom/server/src/entities_game_service/player_manager/player_manager_interface.h b/code/ryzom/server/src/entities_game_service/player_manager/player_manager_interface.h index 2ebf3d50e..ebaa6e66a 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/player_manager_interface.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/player_manager_interface.h @@ -43,7 +43,7 @@ public: struct CUint32Hash { - enum { bucket_size = 4, min_buckets = 8, }; + enum { bucket_size = 4, min_buckets = 8 }; size_t operator () (const uint32 &i) const { return i; } bool operator()(const uint32 left, const uint32 right) const { return left < right; } }; diff --git a/code/ryzom/server/src/entities_game_service/player_manager/player_room.h b/code/ryzom/server/src/entities_game_service/player_manager/player_room.h index 20475fc1f..4d3bd5181 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/player_room.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/player_room.h @@ -54,6 +54,12 @@ public: return _Data->Building; } + /// set the destination where the room physically is + void setBuilding(CBuildingPhysicalPlayer * building) + { + _Data->Building = building; + } + /// init the room. Should be called when a user buys it void init(CCharacter * owner, CBuildingPhysicalPlayer * building); diff --git a/code/ryzom/server/src/entities_game_service/progression/progression_pvp.cpp b/code/ryzom/server/src/entities_game_service/progression/progression_pvp.cpp index 698148710..bebf64b70 100644 --- a/code/ryzom/server/src/entities_game_service/progression/progression_pvp.cpp +++ b/code/ryzom/server/src/entities_game_service/progression/progression_pvp.cpp @@ -1203,7 +1203,7 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter CCharacter * winnerChar = PlayerManager.getChar(players[k]); BOMB_IF(winnerChar == NULL, "invalid winner!", continue); - PVP_CLAN::TPVPClan winnerFaction = PVP_CLAN::None; + PVP_CLAN::TPVPClan winnerFaction = PVP_CLAN::Neutral; bool winnerGainFactionPoints = true; if (!canPlayerWinPoints(winnerChar, victimChar)) @@ -1247,7 +1247,7 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter fameFactor--; } clamp(fameFactor, 0, 3); - nlinfo("points = %d * %d", fpPerPlayer, fameFactor); + //nlinfo("points = %d * %d", fpPerPlayer, fameFactor); // player gains faction points changePlayerPvpPoints(winnerChar, sint32(fpPerPlayer) * fameFactor); diff --git a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager.cpp b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager.cpp index 35cead2b5..7f0ce4ed3 100644 --- a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager.cpp @@ -570,6 +570,10 @@ void CPVPManager::enterPVPZone( CCharacter * user, TAIAlias pvpZoneAlias ) if( zone->getPVPZoneType() != PVP_ZONE_TYPE::OutpostZone ) { + // Remove OP pvp interface + user->setOutpostAlias(0); + user->stopOutpostLeavingTimer(); + // add user to entering PVP zone users NLMISC::TGameCycle endDate = CTickEventHandler::getGameCycle() + PVPZoneEnterBufferTime; CPVPZonePendingUser pendingUser; diff --git a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp index 7f42a671c..0eb5b3c5b 100644 --- a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp +++ b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp @@ -213,10 +213,15 @@ std::vector CPVPManager2::getCharacterChannels(CCharacter * user) // Add lang channel, should be first. if (!user->getLangChannel().empty()) { - TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find(user->getLangChannel()); - if (it != _ExtraFactionChannel.end()) + std::vector langChannels; + NLMISC::splitString(user->getLangChannel(), " ", langChannels); + for ( uint i = 0; i < langChannels.size(); i++ ) { - result.push_back((*it).second); + TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find(langChannels[i]); + if (it != _ExtraFactionChannel.end()) + { + result.push_back((*it).second); + } } } else @@ -713,10 +718,15 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn _Instance->_PVPOutpostAllyReminder = false; _Instance->_PVPOutpostEnemyReminder = false; + PVP_RELATION::TPVPRelation relationTmp = PVP_RELATION::Neutral; CCharacter * pTarget = dynamic_cast(target); if( pTarget ) { + if (curative && pTarget == actor) + { + return PVP_RELATION::Ally; + } // Full PVP is ennemy of everybody if (pTarget->getFullPVP() || actor->getFullPVP()) { @@ -731,8 +741,8 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn IPVP * pvpSession = pTarget->getPVPInterface().getPVPSession(); if( pvpSession ) { - relation = pvpSession->getPVPRelation( actor, target ); - if( relation == PVP_RELATION::Ennemy ) + relationTmp = pvpSession->getPVPRelation( actor, target ); + if( relationTmp == PVP_RELATION::Ennemy ) { pvpSession = actor->getPVPInterface().getPVPSession(); if( pvpSession ) @@ -753,12 +763,16 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn } } } + } + else if ( relationTmp != PVP_RELATION::Ally ) + { + relationTmp = PVP_RELATION::NeutralPVP; } + relation = relationTmp; } //////////////////////////////////////////////////////// } - PVP_RELATION::TPVPRelation relationTmp = PVP_RELATION::Neutral; uint i; for( i=0; i<_PVPInterface.size(); ++i ) { @@ -970,7 +984,7 @@ bool CPVPManager2::canApplyAreaEffect(CCharacter* actor, CEntityBase * areaTarge // set faction flag if( offensive && _PVPFactionEnemyReminder ) { - if(pTarget) + if(pTarget && pTarget->getId() != actor->getId()) { actor->setPVPRecentActionFlag(); TeamManager.pvpAttackOccursInTeam( actor, pTarget ); diff --git a/code/ryzom/server/src/entities_game_service/range_selector.cpp b/code/ryzom/server/src/entities_game_service/range_selector.cpp index f53c9172b..169e83be5 100644 --- a/code/ryzom/server/src/entities_game_service/range_selector.cpp +++ b/code/ryzom/server/src/entities_game_service/range_selector.cpp @@ -33,30 +33,27 @@ void CRangeSelector::buildDisc( CEntityBase * actor, sint32 x, sint32 y,float ra for (uint32 i=0;i<_Entities.size();++i) BOMB_IF(_Entities[i]==&*it,"BUG: We just tried to insert the same entity into a disk entity list more than once!",continue); - if( c != 0 ) + CEntityBase * areaTarget = &(*it); + if( c != NULL) { - CEntityBase * areaTarget = &(*it); - if( c != 0) - { - // Do not add the entity if a PVP rule excludes it from being selected - if( ! CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, offensiveAction, ignoreMainTarget ) ) - continue; - // Do not add invisible entity for player - if( !R2_VISION::isEntityVisibleToPlayers(areaTarget->getWhoSeesMe())) - continue; - // Do not add invulnerable entities, they are GM and use a slot for nothing - if( areaTarget && areaTarget->invulnerableMode() ) - continue; - } - else - { - // Do not add invisible entity for creature - if( !R2_VISION::isEntityVisibleToMobs(areaTarget->getWhoSeesMe())) - continue; - // Do not add invulnerable entities, they are GM and use a slot for nothing - if( areaTarget && areaTarget->invulnerableMode() ) - continue; - } + // Do not add invisible entity for player + if( !R2_VISION::isEntityVisibleToPlayers(areaTarget->getWhoSeesMe())) + continue; + // Do not add invulnerable entities, they are GM and use a slot for nothing + if( areaTarget && areaTarget->invulnerableMode() ) + continue; + // Do not add the entity if a PVP rule excludes it from being selected + if( ! CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, offensiveAction, ignoreMainTarget ) ) + continue; + } + else + { + // Do not add invisible entity for creature + if( !R2_VISION::isEntityVisibleToMobs(areaTarget->getWhoSeesMe())) + continue; + // Do not add invulnerable entities, they are GM and use a slot for nothing + if( areaTarget && areaTarget->invulnerableMode() ) + continue; } _Entities.push_back(&*it); @@ -154,15 +151,16 @@ void CRangeSelector::buildCone(CEntityBase* source , CEntityBase* target,float h CEntityBase * areaTarget = &(*it); if( c != 0 ) { - // Do not add the entity if a PVP rule excludes it from being selected - if( ! CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, offensiveAction, ignoreMainTarget ) ) - continue; // Do not add invisible entity for player if( !R2_VISION::isEntityVisibleToPlayers(areaTarget->getWhoSeesMe())) continue; // Do not add invulnerable entities, they are GM and use a slot for nothing if( areaTarget && areaTarget->invulnerableMode() ) continue; + // Do not add the entity if a PVP rule excludes it from being selected + if( ! CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, offensiveAction, ignoreMainTarget ) ) + continue; + } else { @@ -210,15 +208,17 @@ void CRangeSelector::buildChain( CEntityBase* actor, CEntityBase* target, float CEntityBase * areaTarget = &(*it); if( c != 0 ) { - // Do not add the entity if a PVP rule excludes it from being selected - if( ! CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, (nature == ACTNATURE::FIGHT || nature == ACTNATURE::OFFENSIVE_MAGIC), ignoreMainTarget ) ) - continue; // Do not add invisible entity for player if( !R2_VISION::isEntityVisibleToPlayers(areaTarget->getWhoSeesMe())) continue; // Do not add invulnerable entities, they are GM and use a slot for nothing if( areaTarget && areaTarget->invulnerableMode() ) continue; + + // Do not add the entity if a PVP rule excludes it from being selected + if( ! CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, (nature == ACTNATURE::FIGHT || nature == ACTNATURE::OFFENSIVE_MAGIC), ignoreMainTarget ) ) + continue; + } else { @@ -250,15 +250,18 @@ void CRangeSelector::buildChain( CEntityBase* actor, CEntityBase* target, float CEntityBase * areaTarget = &(*it); if( c != 0 ) { - // Do not add the entity if a PVP rule excludes it from being selected - if( CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, (nature == ACTNATURE::FIGHT || nature == ACTNATURE::OFFENSIVE_MAGIC), ignoreMainTarget ) ) - continue; // Do not add invisible entity player if( !R2_VISION::isEntityVisibleToPlayers(areaTarget->getWhoSeesMe())) continue; // Do not add invulnerable entities, they are GM and use a slot for nothing if( areaTarget && areaTarget->invulnerableMode() ) continue; + + // Do not add the entity if a PVP rule excludes it from being selected + if( CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, (nature == ACTNATURE::FIGHT || nature == ACTNATURE::OFFENSIVE_MAGIC), ignoreMainTarget ) ) + continue; + + } else { diff --git a/code/ryzom/server/src/entities_game_service/shop_type/shop_type_manager.cpp b/code/ryzom/server/src/entities_game_service/shop_type/shop_type_manager.cpp index 6b1aa0d9d..eb831f2cf 100644 --- a/code/ryzom/server/src/entities_game_service/shop_type/shop_type_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/shop_type/shop_type_manager.cpp @@ -1375,7 +1375,7 @@ uint32 CShopTypeManager::computeBasePrice( const CSheetId& sheet, uint16 level, const CStaticBrick * brick = CSheets::getSBrickForm( itemForm->CraftPlan ); if( !brick ) { - nlwarning(" Can't find craft plan sheet '%s' in item form '%s'", itemForm->CraftPlan.toString().c_str(), sheet.toString().c_str() ); + //nlwarning(" Can't find craft plan sheet '%s' in item form '%s'", itemForm->CraftPlan.toString().c_str(), sheet.toString().c_str() ); return 0; } const CFaber* faber = brick->Faber; diff --git a/code/ryzom/server/src/entities_game_service/zone_manager.cpp b/code/ryzom/server/src/entities_game_service/zone_manager.cpp index f55222dca..400a00586 100644 --- a/code/ryzom/server/src/entities_game_service/zone_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/zone_manager.cpp @@ -342,16 +342,14 @@ bool CPlace::build(const NLLIGO::CPrimZone * zone,uint16 id, bool reportAutorise _GooPath = false; _GooActive = false; - // get place_type of re-spawn point - PLACE_TYPE::TPlaceType placeType; if( zone->getPropertyByName("place_type", val) ) { - placeType = PLACE_TYPE::fromString(val); - if( placeType == PLACE_TYPE::Undefined ) - placeType = PLACE_TYPE::Place; + _PlaceType = PLACE_TYPE::fromString(val); + if( _PlaceType == PLACE_TYPE::Undefined ) + _PlaceType = PLACE_TYPE::Place; } else - placeType = PLACE_TYPE::Place; + _PlaceType = PLACE_TYPE::Place; // get children respawn points bool ret = true; @@ -377,7 +375,7 @@ bool CPlace::build(const NLLIGO::CPrimZone * zone,uint16 id, bool reportAutorise spawn->getType() == RESPAWN_POINT::NEWBIELAND || spawn->getType() == RESPAWN_POINT::RESPAWNABLE ) { - (const_cast(spawn))->setPlaceType(placeType); + (const_cast(spawn))->setPlaceType(_PlaceType); _RespawnPoints.push_back( idx ); } } diff --git a/code/ryzom/server/src/entities_game_service/zone_manager.h b/code/ryzom/server/src/entities_game_service/zone_manager.h index 67e3d5a97..8390f2387 100644 --- a/code/ryzom/server/src/entities_game_service/zone_manager.h +++ b/code/ryzom/server/src/entities_game_service/zone_manager.h @@ -155,6 +155,7 @@ public: bool isGooActive() const { return _GooActive; } bool isMainPlace() const { return _MainPlace; } TAIAlias getAlias()const{ return _Alias; } + PLACE_TYPE::TPlaceType getPlaceType() const { return _PlaceType; } const std::vector & getRespawnPoints() const { return _RespawnPoints; } @@ -178,6 +179,8 @@ private: std::vector _RespawnPoints; /// persistant alias TAIAlias _Alias; + /// place type: capital, village etc + PLACE_TYPE::TPlaceType _PlaceType; }; /** diff --git a/code/ryzom/server/src/gpm_service/world_entity.h b/code/ryzom/server/src/gpm_service/world_entity.h index 65b0db955..e22e2359c 100644 --- a/code/ryzom/server/src/gpm_service/world_entity.h +++ b/code/ryzom/server/src/gpm_service/world_entity.h @@ -357,6 +357,7 @@ public: Entity = entity; CheckSpeed = true; + Indoor = false; EnableVisionProcessing = true; } @@ -415,6 +416,7 @@ public: bool EnableVisionProcessing; bool CheckSpeed; + bool Indoor; /// Who I can see flag field uint32 WhoICanSee; diff --git a/code/ryzom/server/src/gpm_service/world_position_manager.cpp b/code/ryzom/server/src/gpm_service/world_position_manager.cpp index 9674541fc..f17882cd5 100644 --- a/code/ryzom/server/src/gpm_service/world_position_manager.cpp +++ b/code/ryzom/server/src/gpm_service/world_position_manager.cpp @@ -1473,7 +1473,7 @@ void CWorldPositionManager::computeVision() break; cell->setVisionUpdateCycle(CTickEventHandler::getGameCycle()); - H_TIME(ComputeCellVision, computeCellVision(cell, cellVisionArray, numEntities);); + H_TIME(ComputeCellVision, computeCellVision(cell, cellVisionArray, numEntities, player->Entity);); CPlayerInfos *plv; for (plv=cell->getPlayersList(); plv!=NULL; plv=plv->Next) @@ -1632,7 +1632,7 @@ TPlayerList::iterator CWorldPositionManager::prioritizeVisionState(TPlayerList:: /****************************************************************\ computeCellVision() \****************************************************************/ -void CWorldPositionManager::computeCellVision( CCell *cell, CVisionEntry* entitiesSeenFromCell, uint &numEntities) +void CWorldPositionManager::computeCellVision( CCell *cell, CVisionEntry* entitiesSeenFromCell, uint &numEntities, CWorldEntity *player) { STOP_IF(IsRingShard,"Illegal use of CWorldPositionManager on ring shard"); CVisionEntry* fillPtr; // entities pointer fill buffer @@ -1656,7 +1656,7 @@ void CWorldPositionManager::computeCellVision( CCell *cell, CVisionEntry* entiti // First adds objects fillPtr = entitiesSeenFromCell; endPtr = entitiesSeenFromCell+MAX_SEEN_OBJECTS; - fillPtr = cell->addObjects(fillPtr, endPtr, centerCellMask, 0); + fillPtr = cell->addObjects(fillPtr, endPtr, centerCellMask, 0, cell->isIndoor(), player); // if the cell has vision on other cells if (!cell->isIndoor()) @@ -1706,7 +1706,7 @@ void CWorldPositionManager::computeCellVision( CCell *cell, CVisionEntry* entiti // then adds entities endPtr = entitiesSeenFromCell+MAX_SEEN_ENTITIES; - fillPtr = cell->addEntities(fillPtr, endPtr, centerCellMask, 0); + fillPtr = cell->addEntities(fillPtr, endPtr, centerCellMask, 0, cell->isIndoor(), player); // if the cell has vision on other cells if (!cell->isIndoor()) @@ -1778,6 +1778,8 @@ void CWorldPositionManager::setCellVisionToEntity( CWorldEntity *entity, CVision if (!infos->EnableVisionProcessing) return; + infos->Indoor = entity->CellPtr != NULL && entity->CellPtr->isIndoor(); + // update the player vision, new entities in vision are stored in inVision, old ones in outVision static CPlayerVisionDelta visionDelta; H_TIME(ComputePlayerDeltaVision, computePlayerDeltaVision( infos, cellVisionArray, numEntities, visionDelta );); @@ -1983,16 +1985,14 @@ void CWorldPositionManager::computePlayerDeltaVision( CPlayerInfos *infos, CVisi if (e->TempVisionState) { addToEntitiesIn(infos, e, visionDelta); + e->TempVisionState = false; } - - cellVision[i].Entity->TempVisionState = false; } // reset vision state for entities that were not checked (not enough slots) for (; iTempVisionState = false; - // *** Prevent from splitting vision of controller/controlled entity. // Ex: mounted mounts must not be visible if their rider is not visible. // It might waste some free slot space but this way we are sure the players won't have invisible riders. diff --git a/code/ryzom/server/src/gpm_service/world_position_manager.h b/code/ryzom/server/src/gpm_service/world_position_manager.h index 31030a582..a85b4cd51 100644 --- a/code/ryzom/server/src/gpm_service/world_position_manager.h +++ b/code/ryzom/server/src/gpm_service/world_position_manager.h @@ -999,7 +999,7 @@ private: * compute Cell Vision, * \param CCell the cell to compute vision on */ - static void computeCellVision( CCell *cell, CVisionEntry* entitiesSeenFromCell, uint &numEntities); + static void computeCellVision( CCell *cell, CVisionEntry* entitiesSeenFromCell, uint &numEntities, CWorldEntity *player); /** * Update vision for this player diff --git a/code/ryzom/server/src/input_output_service/chat_manager.cpp b/code/ryzom/server/src/input_output_service/chat_manager.cpp index aedfa063f..e6dc5c254 100644 --- a/code/ryzom/server/src/input_output_service/chat_manager.cpp +++ b/code/ryzom/server/src/input_output_service/chat_manager.cpp @@ -97,6 +97,8 @@ void CChatManager::onServiceDown(const std::string &serviceShortName) case CChatGroup::universe: case CChatGroup::say: case CChatGroup::shout: + case CChatGroup::player: + case CChatGroup::nbChatMode: continue; case CChatGroup::team: case CChatGroup::guild: @@ -130,7 +132,7 @@ void CChatManager::onServiceDown(const std::string &serviceShortName) /* * Reset ChatLog management */ -void CChatManager::resetChatLog() +void CChatManager::resetChatLog() { std::string logPath = (LogChatDirectory.get().empty() ? Bsi.getLocalPath() : LogChatDirectory.get()); _Displayer.setParam(CPath::standardizePath(logPath) + "chat.log"); @@ -181,7 +183,7 @@ void CChatManager::addClient( const TDataSetRow& id ) } else { - nlwarning("CChatManager::addClient : the client %s:%x is already in the manager !", + nlwarning("CChatManager::addClient : the client %s:%x is already in the manager !", TheDataset.getEntityId(id).toString().c_str(), id.getIndex()); } diff --git a/code/ryzom/server/src/input_output_service/messages.cpp b/code/ryzom/server/src/input_output_service/messages.cpp index 4af959590..3387cfecf 100644 --- a/code/ryzom/server/src/input_output_service/messages.cpp +++ b/code/ryzom/server/src/input_output_service/messages.cpp @@ -45,6 +45,9 @@ extern CGenericXmlMsgHeaderManager GenericXmlMsgHeaderMngr; extern CVariable VerboseChatManagement; +typedef NLMISC::CTwinMap TChanTwinMap; +extern TChanTwinMap _ChanNames; + //----------------------------------------------- // cbImpulsionReadyString : @@ -1584,15 +1587,26 @@ void cbDynChatAddChan(CMessage& msgin, const string &serviceName, TServiceId ser bool noBroadcast; bool forwardInput; bool unify; + string name; msgin.serial(chanID); msgin.serial(noBroadcast); msgin.serial(forwardInput); msgin.serial(unify); - nlinfo("cbDynChatAddChan: add channel"); + msgin.serial(name); + + nlinfo("cbDynChatAddChan: add channel : %s", name.c_str()); bool res = IOS->getChatManager().getDynChat().addChan(chanID, noBroadcast, forwardInput, unify); - if (!res) nlwarning("Couldn't add chan %s", chanID.toString().c_str()); - else nlinfo("cbDynChatAddChan: add channel %s",chanID.toString().c_str()); + if (!res) + nlwarning("Couldn't add chan %s", chanID.toString().c_str()); + else + { + if (_ChanNames.getA(name) == NULL && _ChanNames.getB(chanID) == NULL) + _ChanNames.add(chanID, name); + else + nlwarning("Couldn't add chan %s. already added! %p %p", chanID.toString().c_str(), _ChanNames.getA(name), _ChanNames.getB(chanID)); + nlinfo("cbDynChatAddChan: add channel %s",chanID.toString().c_str()); + } } //----------------------------------------------- @@ -1802,7 +1816,23 @@ void cbDynChatSetHideBubble(CMessage& msgin, const string &serviceName, TService chan->HideBubble = hideBubble; } - +void cbDynChatSetUniversalChannel(CMessage& msgin, const string &serviceName, TServiceId serviceId) +{ + TChanID chanID; + bool universalChannel; + + msgin.serial(chanID); + msgin.serial(universalChannel); + + CChatManager &cm = IOS->getChatManager(); + CDynChatChan *chan = cm.getDynChat().getChan(chanID); + if (!chan) + { + nlwarning("Unknown chan"); + return; + } + chan->UniversalChannel = universalChannel; +} void cbDynChatServiceChat(CMessage& msgin, const string &serviceName, TServiceId serviceId) { @@ -2072,6 +2102,7 @@ TUnifiedCallbackItem CbIOSArray[]= { "DYN_CHAT:SERVICE_CHAT", cbDynChatServiceChat }, // a service send a chat message in the channel without sender id { "DYN_CHAT:SERVICE_TELL", cbDynChatServiceTell }, // a service send a chat message to a specific client in the channel without sender id { "DYN_CHAT:SET_HIDE_BUBBLE", cbDynChatSetHideBubble }, // a service send a chat message to a specific client in the channel without sender id + { "DYN_CHAT:SET_UNIVERSAL_CHANNEL", cbDynChatSetUniversalChannel }, //received from DSS { "REQUEST_DSR", cbRequestDsr}, // { "ADD_DM", cbAddDM }, // A character enter a ring session that he own diff --git a/code/ryzom/server/src/input_output_service/string_manager.cpp b/code/ryzom/server/src/input_output_service/string_manager.cpp index 1e1215594..56a351fea 100644 --- a/code/ryzom/server/src/input_output_service/string_manager.cpp +++ b/code/ryzom/server/src/input_output_service/string_manager.cpp @@ -246,6 +246,60 @@ void CStringManager::clearCache(NLMISC::CLog *log) +// load the values using the george sheet +void CStringManager::TSheetInfo::readGeorges (const NLMISC::CSmartPtr &form, const NLMISC::CSheetId &sheetId) +{ + if (form) + { + SheetName = sheetId.toString(); + + std::string ext = NLMISC::CSheetId::fileExtensionFromType(sheetId.getSheetType()); + + SheetName = SheetName.substr(0, SheetName.find(ext)); + // remove ending '.' + if (!SheetName.empty() && *SheetName.rbegin() == '.') + SheetName.resize(SheetName.size()-1); + + std::string gender; + + if (sheetId.getSheetType() == NLMISC::CSheetId::typeFromFileExtension("creature")) + { + form->getRootNode ().getValueByName (gender, "Basics.Gender"); + sint genderId; + NLMISC::fromString(gender, genderId); + Gender = GSGENDER::EGender(genderId); + + form->getRootNode ().getValueByName (Race, "Basics.Race"); + +// form->getRootNode ().getValueByName (DisplayName, "Basics.First Name"); +// std::string s; +// form->getRootNode ().getValueByName (s, "Basics.CharacterName"); +// if (!DisplayName.empty()) +// DisplayName+=' '; +// DisplayName+=s; + + form->getRootNode ().getValueByName (Profile, "Basics.Profile"); + form->getRootNode ().getValueByName (ChatProfile, "Basics.ChatProfile"); + } + else if (sheetId.getSheetType() == NLMISC::CSheetId::typeFromFileExtension("race_stats")) + { + form->getRootNode ().getValueByName (Race, "Race"); + } +/* else if (sheetId.getType() == NLMISC::CSheetId::typeFromFileExtension("sitem")) + { + // read any item specific data + } +*/ else + { + nlwarning("CStringManager::TEntityInfo : Do not know the type of the sheet '%s'.", sheetId.toString().c_str()); + return; + } + } +} + + + + const CStringManager::CEntityWords &CStringManager::getEntityWords(TLanguages lang, STRING_MANAGER::TParamType type) const { nlassert(lang < NB_LANGUAGES); diff --git a/code/ryzom/server/src/server_share/used_continent.cpp b/code/ryzom/server/src/server_share/used_continent.cpp index 9d2b48f0d..8a396a41c 100644 --- a/code/ryzom/server/src/server_share/used_continent.cpp +++ b/code/ryzom/server/src/server_share/used_continent.cpp @@ -106,7 +106,7 @@ uint32 CUsedContinent::getInstanceForContinent(const std::string &continentName) if (it != _Continents.end()) return it->ContinentInstance; else - return INVALID_AI_INSTANCE; + return std::numeric_limits::max(); } uint32 CUsedContinent::getInstanceForContinent(CONTINENT::TContinent continentEnum) const @@ -116,7 +116,7 @@ uint32 CUsedContinent::getInstanceForContinent(CONTINENT::TContinent continentEn if (it != _Continents.end()) return it->ContinentInstance; else - return INVALID_AI_INSTANCE; + return std::numeric_limits::max(); } const std::string &CUsedContinent::getContinentForInstance(uint32 instanceNumber) const diff --git a/code/ryzom/server/src/server_share/used_continent.h b/code/ryzom/server/src/server_share/used_continent.h index 412c133e3..85f002e40 100644 --- a/code/ryzom/server/src/server_share/used_continent.h +++ b/code/ryzom/server/src/server_share/used_continent.h @@ -21,7 +21,6 @@ #include "nel/misc/types_nl.h" #include "nel/net/service.h" #include "game_share/continent.h" -#include "game_share/misc_const.h" #include diff --git a/code/ryzom/server/src/shard_unifier_service/chat_unifier.cpp b/code/ryzom/server/src/shard_unifier_service/chat_unifier.cpp index 519f5f125..e4c52f4a2 100644 --- a/code/ryzom/server/src/shard_unifier_service/chat_unifier.cpp +++ b/code/ryzom/server/src/shard_unifier_service/chat_unifier.cpp @@ -204,7 +204,7 @@ namespace CHATUNI { // no entity locator, can't forward messages cucSender.recvFarTellFail(this, senderCharId, destName, TFailInfo::fi_no_entity_locator); -nldebug("sendFarTell : no entity locator"); + nldebug("sendFarTell : no entity locator"); return; } uint32 hostShardId = el->getShardIdForChar(destName); @@ -213,7 +213,7 @@ nldebug("sendFarTell : no entity locator"); { // the character is not online cucSender.recvFarTellFail(this, senderCharId, destName, TFailInfo::fi_char_offline); -nldebug("sendFarTell : no valid host shard id for addressee '%s'", destName.toUtf8().c_str()); + nldebug("sendFarTell : no valid host shard id for addressee '%s'", destName.toUtf8().c_str()); return; } diff --git a/code/ryzom/server/src/shard_unifier_service/entity_locator.cpp b/code/ryzom/server/src/shard_unifier_service/entity_locator.cpp index 562f6d41e..4b37b88b5 100644 --- a/code/ryzom/server/src/shard_unifier_service/entity_locator.cpp +++ b/code/ryzom/server/src/shard_unifier_service/entity_locator.cpp @@ -564,6 +564,7 @@ namespace ENTITYLOC void charConnected(NLNET::IModuleProxy *sender, const NLMISC::CEntityId &charEId, uint32 lastDisconnectionDate) { TCharId charId = (TCharId)charEId.getShortId(); + uint32 dynamicId = charEId.getDynamicId(); nldebug("ENTLOC : charConnected : character %u connected from '%s'", charId, sender->getModuleName().c_str()); @@ -577,10 +578,10 @@ namespace ENTITYLOC TShardId shardId = locIt->second; - _charConnected(sender, charId, lastDisconnectionDate, shardId); + _charConnected(sender, charId, lastDisconnectionDate, shardId, dynamicId); } - void _charConnected(NLNET::IModuleProxy *sender, uint32 charId, uint32 lastDisconnectionDate, uint32 shardId) + void _charConnected(NLNET::IModuleProxy *sender, uint32 charId, uint32 lastDisconnectionDate, uint32 shardId, uint32 dynamicId) { uint32 lastConnectionDate = CTime::getSecondsSince1970(); @@ -608,6 +609,7 @@ namespace ENTITYLOC // update the last played date character->setLastPlayedDate(lastConnectionDate); + character->setRRPAM(dynamicId); character->update(_RingDB); } @@ -792,7 +794,7 @@ namespace ENTITYLOC // return true; // } - _charConnected(NULL, charId, CTime::getSecondsSince1970()-10, shardId); + _charConnected(NULL, charId, CTime::getSecondsSince1970()-10, shardId, 0); return true; } diff --git a/code/ryzom/tools/leveldesign/mission_compiler_lib/main.cpp b/code/ryzom/tools/leveldesign/mission_compiler_lib/main.cpp index 88d04883a..71cb054b9 100644 --- a/code/ryzom/tools/leveldesign/mission_compiler_lib/main.cpp +++ b/code/ryzom/tools/leveldesign/mission_compiler_lib/main.cpp @@ -29,7 +29,8 @@ class IStep; int main(int argc, char *argv[]) { - new NLMISC::CApplicationContext; + CSmartPtr appContext(new NLMISC::CApplicationContext()); + CPath::addSearchPath("L:\\primitives\\", true, false); bool test = false; @@ -95,7 +96,12 @@ int main(int argc, char *argv[]) ::fwrite(script.data(), script.size(), 1, fp); ::fclose(fp); - system((string("\"C:\\Program Files\\Beyond Compare 2\\bc2.exe\" ")+string(tmp)+"/compiled_mission.script test_compilateur.script").c_str()); + // TODO: set diff program in .cfg + std::string compareApp = ""; + sint error = system(compareApp+(string(" ")+string(tmp)+"/compiled_mission.script test_compilateur.script").c_str()); + + if (error) + nlwarning("'%s' failed with error code %d", "", error); } catch(const EParseException &e) { @@ -265,6 +271,8 @@ int main(int argc, char *argv[]) } CPrimitiveContext::instance().CurrentLigoConfig = NULL; + + return 0; }