diff --git a/code/ryzom/common/src/game_share/_backup_service_interface_singleton.cpp b/code/ryzom/common/src/game_share/_backup_service_interface_singleton.cpp index f60fab176..51dfa8c38 100644 --- a/code/ryzom/common/src/game_share/_backup_service_interface_singleton.cpp +++ b/code/ryzom/common/src/game_share/_backup_service_interface_singleton.cpp @@ -49,7 +49,7 @@ NL_INSTANCE_COUNTER_IMPL(CBackupInterfaceSingleton); // method used to update stuff on config file reload / variable change void onSaveShardRootModified( NLMISC::IVariable &var ); // configuration variables - to be setup in cfg files -CVariable SaveShardRoot("variables", "SaveShardRoot", "Root directory of all files saved by any shard", "", 0, true, onSaveShardRootModified, false); +CVariable SaveShardRootGameShare("variables", "SaveShardRoot", "Root directory of all files saved by any shard", "", 0, true, onSaveShardRootModified, false); // stats variables CVariable BSLastAckTime("BSIF", "BSLastAckTime", "The timestamp of the last ack received from backup system", 0, 0, true); @@ -103,15 +103,15 @@ void CBackupInterfaceSingleton::init() _ShardDependentBsi.init("BS"); _ShardDependentBsi.setRemotePath( IService::getInstance()->SaveFilesDirectory.toString() ); - _ShardDependentBsi.setLocalPath( CPath::standardizePath( SaveShardRoot.get() ) + IService::getInstance()->SaveFilesDirectory.toString() ); + _ShardDependentBsi.setLocalPath( CPath::standardizePath( SaveShardRootGameShare.get() ) + IService::getInstance()->SaveFilesDirectory.toString() ); _GlobalBsi.init("BS"); _GlobalBsi.setRemotePath( string() ); - _GlobalBsi.setLocalPath( SaveShardRoot.get() ); + _GlobalBsi.setLocalPath( SaveShardRootGameShare.get() ); // _PDBsi.init("PDBS"); // _PDBsi.setRemotePath( IService::getInstance()->SaveFilesDirectory.toString() ); -// _PDBsi.setLocalPath( CPath::standardizePath( SaveShardRoot.get() ) + IService::getInstance()->SaveFilesDirectory.toString() ); +// _PDBsi.setLocalPath( CPath::standardizePath( SaveShardRootGameShare.get() ) + IService::getInstance()->SaveFilesDirectory.toString() ); IService::getInstance()->setDirectoryChangeCallback( this ); } @@ -357,9 +357,9 @@ void CBackupInterfaceSingleton::onVariableChanged( NLMISC::IVariable &var ) if ( var.getName() == "SaveFilesDirectory" ) { _ShardDependentBsi.setRemotePath( var.toString() ); - _ShardDependentBsi.setLocalPath( CPath::standardizePath( SaveShardRoot.get() ) + var.toString() ); + _ShardDependentBsi.setLocalPath( CPath::standardizePath( SaveShardRootGameShare.get() ) + var.toString() ); // _PDBsi.setRemotePath( var.toString() ); -// _PDBsi.setLocalPath( CPath::standardizePath( SaveShardRoot.get() ) + var.toString() ); +// _PDBsi.setLocalPath( CPath::standardizePath( SaveShardRootGameShare.get() ) + var.toString() ); } else if ( var.getName() == "SaveShardRoot" ) { diff --git a/code/ryzom/server/src/backup_service/backup_file_access.cpp b/code/ryzom/server/src/backup_service/backup_file_access.cpp index 7663424e4..ebb63b926 100644 --- a/code/ryzom/server/src/backup_service/backup_file_access.cpp +++ b/code/ryzom/server/src/backup_service/backup_file_access.cpp @@ -36,7 +36,7 @@ NLMISC::CVariable BSFileSubst("backup", "BSFileSubst", "file read/w NLMISC::CVariable VerboseLog("backup", "VerboseLog", "Activate verbose logging of BS activity", false); NLMISC::CVariable UseTempFile("backup", "UseTempFile", "Flag the use of temporary file for safe write or append operation", true, true); -extern NLMISC::CVariable SaveShardRoot; +extern NLMISC::CVariable SaveShardRootBackupService; bool bsstrincmp(const char* s1, const char* s2, int n) { @@ -48,7 +48,7 @@ bool bsstrincmp(const char* s1, const char* s2, int n) std::string getBackupFileName(const std::string& filename) { - return SaveShardRoot.get() + filename; + return SaveShardRootBackupService.get() + filename; /* // BSFilePrefix and BSFileSubst are deprecated if (BSFilePrefix.get().empty()) return filename; diff --git a/code/ryzom/server/src/backup_service/backup_service.cpp b/code/ryzom/server/src/backup_service/backup_service.cpp index 95c11d07a..61538f3e4 100644 --- a/code/ryzom/server/src/backup_service/backup_service.cpp +++ b/code/ryzom/server/src/backup_service/backup_service.cpp @@ -62,7 +62,7 @@ struct CBackupMsgSaveFileRecv extern CDirectoryRateStat DirStats; -extern NLMISC::CVariable SaveShardRoot; +extern NLMISC::CVariable SaveShardRootBackupService; using namespace NLNET; using namespace NLMISC; @@ -542,7 +542,7 @@ static CMessage getFileClassImp( CMessage& msgin) } } // In case something like getPathContent() has returned full paths, make paths relative to match the requested filenames - fdc.stripFilename(SaveShardRoot.get()); + fdc.stripFilename(SaveShardRootBackupService.get()); // compose the output message CMessage msgout("BS_FILE_CLASS"); diff --git a/code/ryzom/server/src/backup_service/commands.cpp b/code/ryzom/server/src/backup_service/commands.cpp index 7e1b4889e..312643418 100644 --- a/code/ryzom/server/src/backup_service/commands.cpp +++ b/code/ryzom/server/src/backup_service/commands.cpp @@ -30,7 +30,7 @@ using namespace NLNET; CDirectoryRateStat DirStats; -extern CVariable SaveShardRoot; +extern CVariable SaveShardRootBackupService; NLMISC_COMMAND(displayFileStats, "display file read/write stats for the last minute", "") @@ -74,9 +74,9 @@ NLMISC_COMMAND ( dumpCharacterFile, "dump the content of the save file for a cha { // just output the list of available shard id vector shards; - CPath::getPathContent(SaveShardRoot, false, true, false, shards); + CPath::getPathContent(SaveShardRootBackupService, false, true, false, shards); - log.displayNL("Listing %u available shard id in path '%s':", shards.size(), SaveShardRoot.c_str()); + log.displayNL("Listing %u available shard id in path '%s':", shards.size(), SaveShardRootBackupService.c_str()); for (uint i=0; i IncrementalBackupDirectory("backup", "IncrementalBackupDirectory", "Directory to find incremental backuped archives", "", 0, true); -// (SaveShardRoot from game_share/backup_service_interface.cpp is not instanciated because the nothing is used from that file) -extern CVariable SaveShardRoot; +CVariable SaveShardRootBackupService("backup", "SaveShardRoot", "Root directory of all saved data by BS", "/home/nevrax/save_shard", 0, true, cbOnSaveShardRootModified); // (SaveShardRoot from game_share/backup_service_interface.cpp is not instanciated because the nothing is used from that file) CVariable SaveTemplatePath("backup", "SaveTemplatePath", "Directory to find saves (with shard and account replacement strings)", "$shard/characters/account_$userid_$charid$ext", 0, true); CVariable SaveExtList("backup", "SaveExtList", "List of possible extensions for save files (space separated)", "_pdr.bin _pdr.xml .bin", 0, true); @@ -210,7 +209,7 @@ void cbGetSaveList(CMemStream &msgin, TSockId host) explode(str, string("%%"), params, true); string incrementalDir = IncrementalBackupDirectory.get(); - string saveShardRoot = SaveShardRoot.get(); + string saveShardRoot = SaveShardRootBackupService.get(); string templatePath = SaveTemplatePath.get(); string extList = SaveExtList.get(); @@ -293,7 +292,7 @@ void cbRestoreSave(CMemStream &msgin, TSockId host) explode(str, string("%%"), params, true); - string saveShardRoot = SaveShardRoot.get(); + string saveShardRoot = SaveShardRootBackupService.get(); string templatePath = SaveTemplatePath.get(); string shard; @@ -368,7 +367,7 @@ void cbCopyOverSave(CMemStream &msgin, TSockId host) explode(str, string("%%"), params, true); - string saveShardRoot = SaveShardRoot.get(); + string saveShardRoot = SaveShardRootBackupService.get(); string templatePath = SaveTemplatePath.get(); string extList = SaveExtList.get(); diff --git a/code/ryzom/server/src/entities_game_service/creature_manager/creature_manager.cpp b/code/ryzom/server/src/entities_game_service/creature_manager/creature_manager.cpp index 7c0dc7780..9fe263a31 100644 --- a/code/ryzom/server/src/entities_game_service/creature_manager/creature_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/creature_manager/creature_manager.cpp @@ -268,10 +268,6 @@ void CCreatureSetUrlImp::callback(const string &, NLNET::TServiceId sid) uint32 program = c->getBotChatProgram(); if(!(program & (1<setBotChatProgram(program); } diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.h b/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.h index 43818cd24..a4b97f203 100644 --- a/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.h +++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.h @@ -51,7 +51,8 @@ public: void cancelAFK(); CCreature * getInterlocutor(); CModuleParent & getModuleParent(); - void sendSystemMessage( const std::string & msg, const TVectorParamCheck & params = TVectorParamCheck() ); + void sendSystemMessage( const std::string & msg, const TVectorParamCheck & params); + void sendSystemMessage( const std::string & msg); void sendDynamicMessageToChatGroup( const std::string & msg, CChatGroup::TGroupType type, const TVectorParamCheck & params = TVectorParamCheck() ); uint64 getMoney(); void spendMoney(uint64 money); diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp index 6e7eab41c..8844f0484 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp @@ -33,9 +33,13 @@ #include "mission_manager/mission_guild.h" #include "guild_manager/guild_manager.h" #include "guild_manager/guild.h" +#include "building_manager/building_manager.h" +#include "building_manager/building_physical.h" #include "admin.h" #include "creature_manager/creature_manager.h" +#include "world_instances.h" + using namespace NLMISC; using namespace NLNET; @@ -553,3 +557,677 @@ NLMISC_COMMAND(addMission,"Add mission to character"," getInventory(selectedInv); + break; + + default: + // No-op + break; + } + } + return inventoryPtr; +} + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(getEid, "get entitiy id of entity", "") +{ + + GET_ACTIVE_CHARACTER + + log.displayNL("%s", c->getId().toString().c_str()); + + return true; +} + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(getItemList, "get list of named items of character by filter", " [bag sheet quantity_min quantity_max quality_min quality_max extra_infos]") +{ + + GET_ACTIVE_CHARACTER + + std::vector inventories; + + string selected_inv = "*"; + string filter = "*"; + uint32 quantity_min = 0; + uint32 quantity_max = 999; + uint32 quality_min = 0; + uint32 quality_max = 999; + + string extra; + + if (args.size() > 1) + selected_inv = args[1]; + + if (args.size() > 2) + filter = args[2]; + + if (args.size() > 3) + fromString(args[3], quantity_min); + + if (args.size() > 4) + fromString(args[4], quantity_max); + + if (args.size() > 5) + fromString(args[5], quality_min); + + if (args.size() > 6) + fromString(args[6], quality_max); + + if (args.size() > 7) + extra = args[7]; + + string msg; + + if (selected_inv != "*") + { + std::vector invs; + NLMISC::splitString(selected_inv, ",", invs); + for (uint32 i=0; igetInventory(inventories[i]); + if (childSrc != NULL) + { + uint32 k = 0; + log.displayNL("#%s", INVENTORIES::toString(inventories[i]).c_str()); + + for ( uint j = 0; j < childSrc->getSlotCount(); j++ ) + { + CGameItemPtr itemPtr = childSrc->getItem(j); + if (itemPtr != NULL) + { + string sheet = itemPtr->getSheetId().toString(); + if (testWildCard(sheet, filter)) + { + uint32 item_stack = itemPtr->getStackSize(); + uint32 item_quality = itemPtr->quality(); + if (item_stack >= quantity_min && item_stack <= quantity_max + && item_quality >= quality_min && item_quality <= quality_max) + { + string item_stats = toString("%3d|%s|", j, sheet.c_str()); + if (!extra.empty()) + itemPtr->getStats(extra, item_stats); + log.displayNL(item_stats.c_str()); + } + } + } + } + } + } + + return true; +} + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(getNamedItemList, "get list of named items of character by filter", " [bag named quantity_min quantity_max quality_min quality_max extra_infos]") +{ + + GET_ACTIVE_CHARACTER + + std::vector inventories; + + string selected_inv = "*"; + string filter = "*"; + uint32 quantity_min = 0; + uint32 quantity_max = 999; + uint32 quality_min = 0; + uint32 quality_max = 999; + + string extra; + + if (args.size() > 1) + selected_inv = args[1]; + + if (args.size() > 2) + filter = args[2]; + + if (args.size() > 3) + fromString(args[3], quantity_min); + + if (args.size() > 4) + fromString(args[4], quantity_max); + + if (args.size() > 5) + fromString(args[5], quality_min); + + if (args.size() > 6) + fromString(args[6], quality_max); + + if (args.size() > 7) + extra = args[7]; + + string msg; + + if (selected_inv != "*") + { + std::vector invs; + NLMISC::splitString(selected_inv, ",", invs); + for (uint32 i=0; igetInventory(inventories[i]); + if (childSrc != NULL) + { + uint32 k = 0; + log.displayNL("#%s", INVENTORIES::toString(inventories[i]).c_str()); + + for ( uint j = 0; j < childSrc->getSlotCount(); j++ ) + { + CGameItemPtr itemPtr = childSrc->getItem(j); + if (itemPtr != NULL) + { + string phraseId = itemPtr->getPhraseId(); + if (!phraseId.empty() && testWildCard(phraseId, filter)) + { + uint32 item_stack = itemPtr->getStackSize(); + uint32 item_quality = itemPtr->quality(); + if (item_stack >= quantity_min && item_stack <= quantity_max + && item_quality >= quality_min && item_quality <= quality_max) + { + string item_stats = toString("%3d|%s|", j, phraseId.c_str()); + if (!extra.empty()) + itemPtr->getStats(extra, item_stats); + log.displayNL(item_stats.c_str()); + } + } + } + } + } + } + + return true; +} + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(deleteInventoryItems, "Delete items from a characters inventory", " ") +{ + if (args.size () < 5) + { + log.displayNL("ERR: Invalid number of parameters. Parameters: "); + return false; + } + + GET_ACTIVE_CHARACTER + + std::map need_items; + + std::vector sheet_names; + NLMISC::splitString(args[1], ",", sheet_names); + std::vector qualities; + NLMISC::splitString(args[2], ",", qualities); + std::vector quantities; + NLMISC::splitString(args[3], ",", quantities); + + for (uint32 i=0; i < std::min(quantities.size(), std::min(qualities.size(), sheet_names.size())); i++) + { + uint32 quantity = 0; + fromString(quantities[i], quantity); + need_items.insert(make_pair(sheet_names[i]+":"+qualities[i], quantity)); + } + + std::map slots; + std::map::iterator itNeedItems; + + // Save list of slots and quantities to delete + CInventoryPtr inventory = c->getInventory(INVENTORIES::bag); + if (inventory != NULL) + { + for ( uint32 j = 0; j < inventory->getSlotCount(); j++ ) + { + CGameItemPtr itemPtr = inventory->getItem(j); + if (itemPtr != NULL) + { + string sheet = itemPtr->getSheetId().toString(); + uint32 item_quality = itemPtr->quality(); + itNeedItems = need_items.find(sheet+":"+NLMISC::toString("%d", item_quality)); + if (itNeedItems != need_items.end() && (*itNeedItems).second > 0) + { + nlinfo("Found : %s %d", sheet.c_str(), item_quality); + uint32 quantity = std::min((*itNeedItems).second, itemPtr->getStackSize()); + slots.insert(make_pair(j, quantity)); + (*itNeedItems).second -= quantity; + } + } + } + + // Check if all items has been found + for ( itNeedItems = need_items.begin(); itNeedItems != need_items.end(); ++itNeedItems ) + { + if ((*itNeedItems).second != 0) { + nlinfo("Missing : %s", (*itNeedItems).first.c_str()); + log.displayNL("ERR: Not enough items."); + return false; + } + } + + //Delete them + for ( std::map::iterator it = slots.begin(); it != slots.end(); ++it ) + { + nlinfo("Deleting... %d, %d", (*it).first, (*it).second); + inventory->deleteStackItem((*it).first, (*it).second); + } + } + + return true; +} + + + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(getPosition, "get position of entity", "") +{ + + GET_ACTIVE_CHARACTER + + double x = 0, y = 0, z = 0, h = 0; + sint32 cell = 0; + + x = c->getState().X / 1000.; + y = c->getState().Y / 1000.; + z = c->getState().Z / 1000.; + h = c->getState().Heading; + + TDataSetRow dsr = c->getEntityRowId(); + CMirrorPropValueRO srcCell( TheDataset, dsr, DSPropertyCELL ); + cell = srcCell; + + log.displayNL("%.2f|%.2f|%.2f|%.4f|%d", x, y, z, h, cell); + + return true; +} + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(getFame, "get fame of player", " faction") +{ + + if (args.size () < 2) + { + log.displayNL("ERR: invalid arg count"); + return false; + } + + GET_ACTIVE_CHARACTER + + uint32 factionIndex = CStaticFames::getInstance().getFactionIndex(args[1]); + if (factionIndex == CStaticFames::INVALID_FACTION_INDEX) + { + log.displayNL("ERR: invalid fame"); + return false; + } + + sint32 fame = CFameInterface::getInstance().getFameIndexed(c->getId(), factionIndex); + log.displayNL("%d", fame); + + return true; +} + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(getFames, "get fames of player", " faction1,faction2,faction3,...") +{ + + if (args.size () < 2) + { + log.displayNL("ERR: invalid arg count"); + return false; + } + + GET_ACTIVE_CHARACTER + + string sfames; + + std::pair allegiance = c->getAllegiance(); + log.displayNL("%s", PVP_CLAN::toString(allegiance.first).c_str()); + log.displayNL("%s", PVP_CLAN::toString(allegiance.second).c_str()); + log.displayNL("%d", c->getOrganization()); + + std::vector fames; + NLMISC::splitString(args[1], ",", fames); + for (uint32 i=0; igetId(), factionIndex)); + } + + return true; +} + + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(getTarget, "get target of player", "") +{ + + GET_ACTIVE_CHARACTER + + const CEntityId &target = c->getTarget(); + string msg = target.toString()+"|"; + + if (target == CEntityId::Unknown) + { + log.displayNL("0"); + return true; + } + + if (target.getType() == RYZOMID::creature) + msg += "c|"; + else if (target.getType() == RYZOMID::npc) + msg += "n|"; + else if (target.getType() == RYZOMID::player) + msg += "p|"; + else + msg += "0"; + + if (target.getType() == RYZOMID::player) + { + CCharacter * cTarget = dynamic_cast(CEntityBaseManager::getEntityBasePtr(target)); + if (cTarget) { + msg += cTarget->getName().toString()+"|"; + + if (c->getGuildId() != 0 && c->getGuildId() == cTarget->getGuildId()) + msg += "g|"; + else + msg += "0|"; + + if (c->getTeamId() != CTEAM::InvalidTeamId && c->getTeamId() == cTarget->getTeamId()) + msg += "t"; + else + msg += "0"; + } + } + + log.displayNL(msg.c_str()); + + return true; +} + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(getMoney, "get money of player", "") +{ + + GET_ACTIVE_CHARACTER + + string value = toString("%"NL_I64"u", c->getMoney()); + + log.displayNL(value.c_str()); +} + + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(getPvpPoints, "get pvp points of player", "") +{ + + GET_ACTIVE_CHARACTER + + string value = toString("%u", c->getPvpPoint()); + + log.displayNL(value.c_str()); +} + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(getCivCultOrg, "get civ cult and organization of player", "") +{ + + GET_ACTIVE_CHARACTER + + std::pair allegiance = c->getAllegiance(); + + + log.displayNL("%s|%s|%u", PVP_CLAN::toString(allegiance.first).c_str(), PVP_CLAN::toString(allegiance.second).c_str(), c->getOrganization()); +} + + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(accessPowo, "give access to the powo", " player_name number") +{ + GET_ACTIVE_CHARACTER + + IBuildingPhysical * building; + if (args.size () >= 3) + building = CBuildingManager::getInstance()->getBuildingPhysicalsByName("building_instance_ZO_player_11"+args[2]); + else + building = CBuildingManager::getInstance()->getBuildingPhysicalsByName("building_instance_ZO_player_111"); + + + if ( building ) + { + + if (building->getTemplate()->Type == BUILDING_TYPES::Player) + { + + CBuildingPhysicalPlayer * buildingPlayer = dynamic_cast( building ); + + CEntityBase *entityBase = PlayerManager.getCharacterByName(CShardNames::getInstance().makeFullNameFromRelative(c->getHomeMainlandSessionId(), args[2])); + if (buildingPlayer && entityBase) + { + CBuildingManager::getInstance()->removePlayerFromRoom( c ); + uint16 ownerId = buildingPlayer->getOwnerIdx( entityBase->getId() ); + sint32 cell; + buildingPlayer->addUser(c, 0, ownerId, cell); + c->setPowoCell(cell); + CBuildingManager::getInstance()->setRoomLifeTime(cell, TGameCycle(NLMISC::TGameTime(4*60*60) / CTickEventHandler::getGameTimeStep())); + log.displayNL("%d", cell); + } + } else { + log.displayNL("ERR: invalid number"); + return false; + } + } else { + log.displayNL("ERR: invalid number"); + return false; + } + return true; +} + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(slide, "slide to the powo", " x y cell [z] [h]") +{ + + if (args.size () < 4) + { + log.displayNL("ERR: invalid arg count"); + return false; + } + + GET_ACTIVE_CHARACTER + + string value = args[1]; + + sint32 x; + sint32 y; + sint32 cell = c->getPowoCell(); + sint32 z = 0; + float h = 0; + + fromString(args[1], x); + x *= 1000; + fromString(args[2], y); + y *= 1000; + if (args[3] != "*") + fromString(args[3], cell); + + if (args.size() >= 5) + { + fromString(args[4], z); + z *= 1000; + } + + if (args.size() >= 6) + fromString(args[5], h); + + c->teleportCharacter(x,y,z,false,true,h,0xFF,cell); + + return true; +} + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(spawn, "spawn entity", " quantity sheet dispersion orientation groupname x y look cell") +{ + + if (args.size () < 10) + { + log.displayNL("ERR: invalid arg count"); + return false; + } + + GET_ACTIVE_CHARACTER + + + uint32 instanceNumber = 0; + sint32 x = 0; + sint32 y = 0; + sint32 z = c->getZ(); + sint32 cell = 0; + sint32 orientation = 6666; // used to specify a random orientation + + uint32 nbBots; + fromString(args[1], nbBots); + if (nbBots<=0) + { + log.displayNL("ERR: invalid bot count"); + return false; + } + + NLMISC::CSheetId sheetId(args[2]); + if (sheetId == NLMISC::CSheetId::Unknown) + sheetId = args[2] + ".creature"; + if (sheetId == NLMISC::CSheetId::Unknown) + return true; + + double dispersionRadius = 10.; + if (args.size()>3) + { + fromString(args[3], dispersionRadius); + if (dispersionRadius < 0.) { + log.displayNL("ERR: invalid dispersion"); + return false; + } + } + + bool spawnBots = true; + + if (args.size()>4) + { + if (args[4] == "self") + { + orientation = (sint32)(c->getHeading() * 1000.0); + } + else if (args[4] != "random") + { + NLMISC::fromString(args[4], orientation); + orientation = (sint32)((double)orientation / 360.0 * (NLMISC::Pi * 2.0) * 1000.0); + } + } + + string botsName = args[5]; + + float userX; + NLMISC::fromString(args[6], userX); + x = (sint32)(userX * 1000.0); + + float userY; + NLMISC::fromString(args[7], userY); + y = (sint32)(userY * 1000.0); + + string look = args[8]; + NLMISC::fromString(args[9], cell); + + // See if another AI instance has been specified + if (botsName.find("@") != string::npos) + { + string continent = botsName.substr(0, botsName.find('@')); + uint32 nr = CUsedContinent::instance().getInstanceForContinent(continent); + if (nr == ~0) + { + log.displayNL("ERR: invalid continent"); + return false; + } + instanceNumber = nr; + botsName = botsName.substr(botsName.find('@') + 1, botsName.size()); + } + + CEntityId playerId = c->getId(); + + CMessage msgout("EVENT_CREATE_NPC_GROUP"); + uint32 messageVersion = 1; + msgout.serial(messageVersion); + msgout.serial(instanceNumber); + msgout.serial(playerId); + msgout.serial(x); + msgout.serial(y); + msgout.serial(z); + msgout.serial(orientation); + msgout.serial(nbBots); + msgout.serial(sheetId); + msgout.serial(dispersionRadius); + msgout.serial(spawnBots); + msgout.serial(botsName); + msgout.serial(look); + msgout.serial(cell); + CWorldInstances::instance().msgToAIInstance2(instanceNumber, msgout); + + return true; +} \ No newline at end of file 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 bebf64b70..d819db2ee 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 @@ -181,7 +181,7 @@ void CDamageScoreTable::addPlayerDamage(TDataSetRow playerRowId, uint32 damage) void CDamageScoreTable::addCreatureDamage(TDataSetRow creatureRowId, uint32 damage) { nlassert(damage > 0); - + /* CCreatureDamageScore * creatureScore = getCreatureDamageScore(creatureRowId); if (creatureScore == NULL) { @@ -193,6 +193,7 @@ void CDamageScoreTable::addCreatureDamage(TDataSetRow creatureRowId, uint32 dama { creatureScore->TotalDamage += damage; } + */ } //----------------------------------------------------------------------------- @@ -1694,7 +1695,7 @@ bool CDamageScoreManager::playerInFactionPvP(const CCharacter * playerChar, PVP_ CPVPVersusZone * zone = dynamic_cast(const_cast(playerChar->getPVPInterface()).getPVPSession()); if (zone != NULL) { - PVP_CLAN::TPVPClan factionInZone = zone->getCharacterClan(playerChar->getId()); + /*PVP_CLAN::TPVPClan factionInZone = zone->getCharacterClan(playerChar->getId()); if (factionInZone == PVP_CLAN::Neutral) return false; @@ -1705,7 +1706,7 @@ bool CDamageScoreManager::playerInFactionPvP(const CCharacter * playerChar, PVP_ if (withFactionPoints) *withFactionPoints = zone->giveFactionPoints(); - + */ return true; } } diff --git a/code/ryzom/server/src/gpm_service/cell.h b/code/ryzom/server/src/gpm_service/cell.h index 7fbff9023..8cc740a08 100644 --- a/code/ryzom/server/src/gpm_service/cell.h +++ b/code/ryzom/server/src/gpm_service/cell.h @@ -117,12 +117,15 @@ public: /// Gets at maximum MAX_SEEN_ENTITIES entities contained in the cell - CVisionEntry* addEntities(CVisionEntry* fillPtr, CVisionEntry* endPtr, uint32 cellMask, uint32 distance) + CVisionEntry* addEntities(CVisionEntry* fillPtr, CVisionEntry* endPtr, uint32 cellMask, uint32 distance, bool indoor, CWorldEntity *player) { CWorldEntity *ent = _EntitiesList.getHead(); while (ent != NULL && fillPtr < endPtr) { sint32 mask = cellMask & (sint32)(ent->WhoSeesMe); + if (mask && indoor && (float)(player->X()-ent->X())*(float)(player->X()-ent->X()) + (float)(player->Y()-ent->Y())*(float)(player->Y()-ent->Y()) > 15625000000) + mask = 0; + //if (!ent->IsInvisibleToPlayer && mask != 0) if (mask != 0) { @@ -136,12 +139,15 @@ public: return fillPtr; } /// Gets at maximum MAX_SEEN_ENTITIES entities contained in the cell - CVisionEntry* addObjects(CVisionEntry* fillPtr, CVisionEntry* endPtr, uint32 cellMask, uint32 distance) + CVisionEntry* addObjects(CVisionEntry* fillPtr, CVisionEntry* endPtr, uint32 cellMask, uint32 distance, bool indoor, CWorldEntity *player) { CWorldEntity *ent = _ObjectsList.getHead(); while (ent != NULL && fillPtr < endPtr) { sint32 mask = cellMask & (sint32)(ent->WhoSeesMe); + if (mask && indoor && (float)(player->X()-ent->X())*(float)(player->X()-ent->X()) + (float)(player->Y()-ent->Y())*(float)(player->Y()-ent->Y()) > 15625000000) + mask = 0; + //if (!ent->IsInvisibleToPlayer && mask != 0) if (mask != 0) { diff --git a/code/ryzom/server/src/gpm_service/messages.cpp b/code/ryzom/server/src/gpm_service/messages.cpp index d85a93e0e..f0cadcacd 100644 --- a/code/ryzom/server/src/gpm_service/messages.cpp +++ b/code/ryzom/server/src/gpm_service/messages.cpp @@ -493,7 +493,9 @@ void cbEntityTeleportation( CMessage& msgin, const string &serviceName, NLNET::T id.serial( msgin ); TDataSetRow index = CWorldPositionManager::getEntityIndex(id); - BOMB_IF(IsRingShard && !index.isValid(),"Ignoring request to TP entity withe invalid data set row: "< maxSpeed( TheDataset, entity->Index, DSPropertyCURRENT_RUN_SPEED ); float limitSpeedToUse = maxSpeed(); + // Get the proper speed of master + CMirrorPropValueRO maxSpeedMaster( TheDataset, master->Index, DSPropertyCURRENT_RUN_SPEED ); + float mountWalkSpeed = maxSpeedMaster(); if ( entity != master ) { // If the player is on a mount, handle the hunger of the mount - if ( (movVector.x > 0.001) && (movVector.y > 0.001) ) + // if ( (movVector.x > 0.001) && (movVector.y > 0.001) ) { CMirrorPropValueRO walkSpeed( TheDataset, entity->Index, DSPropertyCURRENT_WALK_SPEED ); CSpeedLimit speedLimit( TheDataset, entity->Index ); limitSpeedToUse = speedLimit.getSpeedLimit( walkSpeed, maxSpeed ); + mountWalkSpeed = walkSpeed; } } @@ -2201,18 +2205,20 @@ void CWorldPositionManager::movePlayer(CWorldEntity *entity, sint32 x, sint32 y, // Check player speed // only consider (x,y) motion for speed and position correction - if (master->PlayerInfos != NULL && master->PlayerInfos->CheckSpeed && CheckPlayerSpeed && fabs(movVector.x)+fabs(movVector.y) > maxDist) + if (master->PlayerInfos != NULL /*&& master->PlayerInfos->CheckSpeed && CheckPlayerSpeed && fabs(movVector.x)+fabs(movVector.y) > maxDist*/) { double movNorm = sqr(movVector.x)+sqr(movVector.y); // already done if (entity != master) but here is a rare overspeed case if (movNorm > sqr(maxDist)) { - if (VerboseSpeedAbuse) - { - nlwarning("CWorldPositionManager::movePlayer%s: limited speed (movNorm=%.2f, movMax=%.2f, maxSpeed=%.2f)", entity->Id.toString().c_str(), sqrt(movNorm), maxDist, limitSpeedToUse*0.001*SecuritySpeedFactor); + if (movNorm > sqr(5 * SecuritySpeedFactor * CTickEventHandler::getGameTimeStep() * ticksSinceLastUpdate)) { + movVector *= (maxDist / sqrt(movNorm)); + nlwarning("Player limitSpeed=%2.f, entitySpeed=%.2f, masterSpeed=%.2f", limitSpeedToUse, maxSpeed(), mountWalkSpeed); + } + else + { + nlwarning("Player limitSpeed=%2.f, entitySpeed=%.2f, masterSpeed=%.2f", limitSpeedToUse, maxSpeed(), mountWalkSpeed); } - - movVector *= (maxDist / sqrt(movNorm)); } } @@ -2268,9 +2274,9 @@ void CWorldPositionManager::movePlayer(CWorldEntity *entity, sint32 x, sint32 y, if (diff2d.sqrnorm() > 1.0 ) { correctPos = true; - if (VerboseSpeedAbuse) + if (true/*VerboseSpeedAbuse*/) { - nlwarning("CWorldPositionManager::movePlayer%s: corrected position: real=(%.1f,%.1f) targeted=(%.1f,%.1f)", master->Id.toString().c_str(), finalPos.x, finalPos.y, targetPos.x, targetPos.y); + nlwarning("PlayerAbuse %s real=(%.1f,%.1f) targeted=(%.1f,%.1f)", master->Id.toString().c_str(), finalPos.x, finalPos.y, targetPos.x, targetPos.y); } } diff --git a/code/ryzom/tools/leveldesign/mission_compiler_lib/mission_compiler.cpp b/code/ryzom/tools/leveldesign/mission_compiler_lib/mission_compiler.cpp index 6e11bd83e..fd119e0df 100644 --- a/code/ryzom/tools/leveldesign/mission_compiler_lib/mission_compiler.cpp +++ b/code/ryzom/tools/leveldesign/mission_compiler_lib/mission_compiler.cpp @@ -1580,6 +1580,14 @@ string CMissionData::genPreRequisites() ret += NL; } } + if (!_ReqCharacterAge.empty()) + { + ret += "req_character_age : "+_ReqCharacterAge+NL; + } + if (!_ReqMaxPlayerID.empty()) + { + ret += "req_max_player_id : "+_ReqMaxPlayerID+NL; + } if (!_ReqSeason.empty()) { ret += "req_season : "+_ReqSeason+NL; @@ -2019,6 +2027,10 @@ void CMissionData::parsePrerequisites(NLLIGO::IPrimitive *prim) _ReqGrade = getProperty(prim, "require_guild_grade", true, false); // team size _ReqTeamSize = getProperty(prim, "require_team_size", true, false); + // character minimum age + _ReqCharacterAge = getProperty(prim, "require_character_age", true, false); + // maximum player ID + _ReqMaxPlayerID = getProperty(prim, "require_max_player_id", true, false); // brick vs = getPropertyArray(prim, "require_brick_knowledge", true, false); for (uint i=0; i _ReqBrick; + std::string _ReqCharacterAge; + std::string _ReqMaxPlayerID; std::string _ReqSeason; // bool _ReqEncycloTasksDone; std::string _ReqEncyclo; diff --git a/code/ryzom/tools/leveldesign/mission_compiler_lib/step_content.cpp b/code/ryzom/tools/leveldesign/mission_compiler_lib/step_content.cpp index adcf6c680..cda6790ae 100644 --- a/code/ryzom/tools/leveldesign/mission_compiler_lib/step_content.cpp +++ b/code/ryzom/tools/leveldesign/mission_compiler_lib/step_content.cpp @@ -1844,19 +1844,27 @@ struct TKillRaceInfo TCompilerVarName Quantity; }; +struct TKillPlayerInfo +{ + TCompilerVarName ClanName; + TCompilerVarName MinLevel; + TCompilerVarName MaxLevel; + TCompilerVarName Quantity; +}; class CContentKill : public CContentObjective { - vector _KillFaunas; - vector _KillRaces; - TCompilerVarName _KillGroup; - vector _KillNpcs; - TCompilerVarName _KillNpcByNames; - TCompilerVarName _KillNpcByNamesQuantity; - TCompilerVarName _KillFactionName; - TCompilerVarName _KillFactionQuantity; - vector _PredefVarName; - TCompilerVarName _Place; + vector _KillFaunas; + vector _KillRaces; + TCompilerVarName _KillGroup; + vector _KillNpcs; + TCompilerVarName _KillNpcByNames; + TCompilerVarName _KillNpcByNamesQuantity; + TCompilerVarName _KillFactionName; + TCompilerVarName _KillFactionQuantity; + vector _PredefVarName; + vector _KillPlayers; + TCompilerVarName _Place; void getPredefParam(uint32 &numEntry, CPhrase::TPredefParams &predef) @@ -1924,7 +1932,22 @@ class CContentKill : public CContentObjective predef[0].resize(2); predef[0][0] = _KillFactionName; predef[0][1] = _KillFactionQuantity; - + } + else if(!_KillPlayers.empty()) + { + numEntry = _KillPlayers.size(); + predef.resize(numEntry); + for (uint i=0; i args; + explode(vs[i], string(" "), args, true); + if (args.size() != 4) + { + string err = toString("Invalid player clan infos in '%s', need ", vs[i].c_str()); + throw EParseException(prim, err.c_str()); + } + if (atoi(args[1].c_str()) >= atoi(args[2].c_str())) + { + string err = toString("Invalid player clan infos in '%s', need lower than ", vs[i].c_str()); + throw EParseException(prim, err.c_str()); + } + if (atoi(args[3].c_str()) <= 0) + { + string err = toString("Invalid player clan infos in '%s', need upper than 0", vs[i].c_str()); + throw EParseException(prim, err.c_str()); + } + TKillPlayerInfo kp; + kp.ClanName.initWithText(toString("clan%u", i+1), STRING_MANAGER::clan, md, prim, args[0]); + kp.MinLevel.initWithText(toString("minlvl%u", i+1), STRING_MANAGER::integer, md, prim, args[1]); + kp.MaxLevel.initWithText(toString("maxlvl%u", i+1), STRING_MANAGER::integer, md, prim, args[2]); + kp.Quantity.initWithText(toString("quantity%u", i+1), STRING_MANAGER::integer, md, prim, args[3]); + _KillPlayers.push_back(kp); + } s = md.getProperty(prim, "npc_by_name/quantity", false, false); if (!s.empty()) @@ -2058,6 +2108,12 @@ public: throw EParseException(prim, "Merging of multiple kill mode is forbidden !"); check = true; } + if (!_KillPlayers.empty()) + { + if (check) + throw EParseException(prim, "Merging of multiple kill mode is forbidden !"); + check = true; + } _Place.init("p", STRING_MANAGER::place, md, prim, "place"); @@ -2117,6 +2173,16 @@ public: { ret += "kill_faction : "+_KillFactionName+" "+_KillFactionQuantity; } + else if (!_KillPlayers.empty()) + { + ret += "kill_player : "; + for (uint i=0; i<_KillPlayers.size(); ++i) + { + ret += _KillPlayers[i].ClanName+" "+_KillPlayers[i].MinLevel+" "+_KillPlayers[i].MaxLevel+" "+_KillPlayers[i].Quantity; + if (i < _KillPlayers.size()-1) + {ret += "; ";} + } + } if (!_Place.empty()) ret += " : "+_Place; @@ -2130,6 +2196,30 @@ public: }; REGISTER_STEP_CONTENT(CContentKill, "kill"); + +/* +class CContentKillFamedPlayer : public CContentObjective +{ + vector _Clans; + + virtual void getPredefParam(uint32 &numEntry, CPhrase::TPredefParams &predef) + { + numEntry = _Clans.size(); + predef.resize(numEntry); + for (uint i=0; i