diff --git a/ryzom/server/src/entities_game_service/outpost_manager/outpost.cpp b/ryzom/server/src/entities_game_service/outpost_manager/outpost.cpp index 20f3c64ce..4f3847434 100644 --- a/ryzom/server/src/entities_game_service/outpost_manager/outpost.cpp +++ b/ryzom/server/src/entities_game_service/outpost_manager/outpost.cpp @@ -76,6 +76,8 @@ static uint32 const hours = 60*minutes; static uint32 const days = 24*hours; CVariable OutpostFightRoundCount("egs","OutpostFightRoundCount","number of rounds in an outpost fight", 24, 0, true); +CVariable OutpostInTestFightRoundCount("egs","OutpostInTestFightRoundCount","number of rounds in an outpost (in test) fight", 11, 0, true); +CVariable OutpostInTestFightSquadCount("egs", "OutpostInTestFightSquadCount", "Coef for squad count per round", 1.2f, 0, true ); CVariable OutpostFightRoundTime("egs","OutpostFightRoundTime","time of a round in an outpost fight, in seconds", 5*minutes, 0, true); CVariable OutpostLevelDecrementTime("egs","OutpostLevelDecrementTime","time to decrement an outpost level in seconds (in peace time)", 2*days, 0, true); CVariable OutpostEditingConcurrencyCheckDelay("egs", "OutpostEditingConcurrencyCheckDelay", "delay in ticks used to check if 2 actions for editing an outpost are concurrent", 50, 0, true ); @@ -203,14 +205,14 @@ void COutpost::fillOutpostDB() CBankAccessor_OUTPOST::getOUTPOST_SELECTED().setSTATE_END_DATE(_DbGroup, STATE_END_DATE); //setClientDBProp("OUTPOST_SELECTED:STATE_END_DATE", STATE_END_DATE); CBankAccessor_OUTPOST::getOUTPOST_SELECTED().setDISPLAY_CRASH(_DbGroup, _CrashHappened); // setClientDBProp("OUTPOST_SELECTED:DISPLAY_CRASH", DISPLAY_CRASH); CBankAccessor_OUTPOST::getOUTPOST_SELECTED().setWARCOST(_DbGroup, WARCOST); // setClientDBProp("OUTPOST_SELECTED:WARCOST", WARCOST); - + CBankAccessor_OUTPOST::getOUTPOST_SELECTED().setROUND_LVL_THRESHOLD(_DbGroup, ROUND_LVL_THRESHOLD); // setClientDBProp("OUTPOST_SELECTED:ROUND_LVL_THRESHOLD", ROUND_LVL_THRESHOLD); CBankAccessor_OUTPOST::getOUTPOST_SELECTED().setROUND_LVL_MAX_ATT(_DbGroup, ROUND_LVL_MAX_ATT); // setClientDBProp("OUTPOST_SELECTED:ROUND_LVL_MAX_ATT", ROUND_LVL_MAX_ATT); CBankAccessor_OUTPOST::getOUTPOST_SELECTED().setROUND_LVL_MAX_DEF(_DbGroup, ROUND_LVL_MAX_DEF); // setClientDBProp("OUTPOST_SELECTED:ROUND_LVL_MAX_DEF", ROUND_LVL_MAX_DEF); CBankAccessor_OUTPOST::getOUTPOST_SELECTED().setROUND_LVL_CUR(_DbGroup, ROUND_LVL_CUR); // setClientDBProp("OUTPOST_SELECTED:ROUND_LVL_CUR", ROUND_LVL_CUR); CBankAccessor_OUTPOST::getOUTPOST_SELECTED().setROUND_ID_CUR(_DbGroup, ROUND_ID_CUR); // setClientDBProp("OUTPOST_SELECTED:ROUND_ID_CUR", ROUND_ID_CUR); CBankAccessor_OUTPOST::getOUTPOST_SELECTED().setROUND_ID_MAX(_DbGroup, ROUND_ID_MAX); // setClientDBProp("OUTPOST_SELECTED:ROUND_ID_MAX", ROUND_ID_MAX); - + CBankAccessor_OUTPOST::getOUTPOST_SELECTED().setTIME_RANGE_DEF_WANTED(_DbGroup, TIME_RANGE_DEF_WANTED); // setClientDBProp("OUTPOST_SELECTED:TIME_RANGE_DEF_WANTED", TIME_RANGE_DEF_WANTED); CBankAccessor_OUTPOST::getOUTPOST_SELECTED().setTIME_RANGE_DEF(_DbGroup, TIME_RANGE_DEF); // setClientDBProp("OUTPOST_SELECTED:TIME_RANGE_DEF", TIME_RANGE_DEF); CBankAccessor_OUTPOST::getOUTPOST_SELECTED().setTIME_RANGE_ATT(_DbGroup, TIME_RANGE_ATT); // setClientDBProp("OUTPOST_SELECTED:TIME_RANGE_ATT", TIME_RANGE_ATT); @@ -245,7 +247,7 @@ void COutpost::fillCharacterOutpostDB( CCharacter * user ) bool COutpost::build(const NLLIGO::IPrimitive* prim,const std::string &filename,const std::string &dynSystem, CONTINENT::TContinent continent) { _Alias = 0; - + _State = OUTPOSTENUMS::Peace; _OwnerGuildId = 0; _AttackerGuildId = 0; @@ -264,7 +266,7 @@ bool COutpost::build(const NLLIGO::IPrimitive* prim,const std::string &filename, // parse identifier nlverify( prim->getPropertyByName("name",_Name) ); - + nlverify( prim->getPropertyByName("disable_outpost", value) ); if (value == "true") { @@ -284,7 +286,7 @@ bool COutpost::build(const NLLIGO::IPrimitive* prim,const std::string &filename, string deathPenaltyFactor; nlverify( prim->getPropertyByName("death_penalty_factor", deathPenaltyFactor) ); _DeathPenaltyFactor = (float)atof( deathPenaltyFactor.c_str() ); - + // get the sheet and check it nlverify( prim->getPropertyByName("outpost_sheet", value ) ); _Sheet = CSheetId( value+".outpost" ); @@ -293,7 +295,7 @@ bool COutpost::build(const NLLIGO::IPrimitive* prim,const std::string &filename, OUTPOST_WRN("PRIM_ERROR : invalid sheet '%s' (the sheet is not in sheet_id.bin)", value.c_str()); ret = false; } - + _Form = CSheets::getOutpostForm(_Sheet); if ( _Form == NULL ) { @@ -305,7 +307,7 @@ bool COutpost::build(const NLLIGO::IPrimitive* prim,const std::string &filename, { OUTPOST_WRN("PRIM_ERROR : the outposts %s and %s have the same sheet %s", getName().c_str(), otherOutpost->getName().c_str(), _Sheet.toString().c_str() ); } - + // get the PVP type nlverify( prim->getPropertyByName("PVP_Type", value ) ); _PVPType = OUTPOSTENUMS::toPVPType( value ); @@ -314,7 +316,7 @@ bool COutpost::build(const NLLIGO::IPrimitive* prim,const std::string &filename, OUTPOST_WRN("PRIM_ERROR : invalid PVP type '%s' (the sheet exists but contained errors)", value.c_str()); ret = false; } - + // build the outpost PVP zone const NLLIGO::CPrimZone * zone = dynamic_cast ( prim ); nlassert( zone ); @@ -393,7 +395,7 @@ bool COutpost::build(const NLLIGO::IPrimitive* prim,const std::string &filename, OUTPOST_WRN( "PRIM_ERROR : found no valid default squads in %s", _Name.c_str() ); ret = false; } - + // get buyable squads nlverify ( prim->getPropertyByName("buyable_squads",params) && params ); for (size_t i = 0; i < params->size(); ++i) @@ -424,7 +426,7 @@ bool COutpost::build(const NLLIGO::IPrimitive* prim,const std::string &filename, // tribe nlverifyex ( prim->getPropertyByName("owner_tribe",value) && (!value.empty()), ("Missing owner tribe in outpost '%s' in %s", _Name.c_str(), filename.c_str()) ); string tribeName = value; - + // get tribe squads nlverify ( prim->getPropertyByName("tribe_squads",params) && params ); if (!params->empty()) @@ -487,7 +489,7 @@ bool COutpost::build(const NLLIGO::IPrimitive* prim,const std::string &filename, } } - + OUTPOST_DBG( "Outpost %s has %u default squads (free), %u buyable squads, %u(A)/%u(B) tribe squads, %u default buildings", _Name.c_str(), _DefaultSquads.size(), @@ -496,9 +498,9 @@ bool COutpost::build(const NLLIGO::IPrimitive* prim,const std::string &filename, _TribeSquadsB.size(), _Buildings.size() ); - + // spawn zones - for ( uint i = 0; i < prim->getNumChildren(); ++i ) + for ( uint i = 0; i < prim->getNumChildren(); ++i ) { const NLLIGO::IPrimitive* outpostChildNode = NULL; std::string className; @@ -596,7 +598,7 @@ void COutpost::initNewOutpost() _NextAttackSquadsB.resize(OUTPOSTENUMS::OUTPOST_NB_SQUAD_SLOTS); _NextDefenseSquadsA.resize(OUTPOSTENUMS::OUTPOST_NB_SQUAD_SLOTS); _NextDefenseSquadsB.resize(OUTPOSTENUMS::OUTPOST_NB_SQUAD_SLOTS); - + // tribes own new outposts _OwnerGuildId = 0; @@ -651,7 +653,7 @@ bool COutpost::isBelongingToAGuild() const //---------------------------------------------------------------------------- uint32 COutpost::getAIInstanceNumber() const { - return CUsedContinent::instance().getInstanceForContinent( _Continent ); + return CUsedContinent::instance().getInstanceForContinent( _Continent ); } //---------------------------------------------------------------------------- @@ -673,19 +675,19 @@ NLNET::TServiceId COutpost::getAISId() const } //---------------------------------------------------------------------------- -// Sets the guild and resend data to AIS. +// Sets the guild and resend data to AIS. // The case when _OwnerGuildId==ownerGuild only resends data (see resendDynamicDataToAIS()). void COutpost::setOwnerGuild( EGSPD::TGuildId ownerGuild ) { // clear the attacker if the new owner was the attacker if (ownerGuild != 0 && ownerGuild == _AttackerGuildId) setAttackerGuild(0); - + EGSPD::TGuildId oldOwnerGuildId = _OwnerGuildId; - + _OwnerGuildId = ownerGuild; OUTPOST_DBG( "Outpost %s is now owned by 0x%x", _Name.c_str(), _OwnerGuildId ); - + if (ownerGuild != oldOwnerGuildId) { CGuild* oldOwner = CGuildManager::getInstance()->getGuildFromId(oldOwnerGuildId); @@ -708,7 +710,7 @@ void COutpost::setOwnerGuild( EGSPD::TGuildId ownerGuild ) // register new owner owner->addOwnedOutpost(_Alias); } - + // Send to AIS CSetOutpostOwner ownerParams; ownerParams.Outpost = getAlias(); @@ -717,7 +719,7 @@ void COutpost::setOwnerGuild( EGSPD::TGuildId ownerGuild ) } //---------------------------------------------------------------------------- -// Sets the guild and resend data to AIS. +// Sets the guild and resend data to AIS. // The case when _Owner==attackerGuild only resends data (see resendDynamicDataToAIS()). void COutpost::setAttackerGuild( EGSPD::TGuildId attackerGuild ) { @@ -746,7 +748,7 @@ void COutpost::setAttackerGuild( EGSPD::TGuildId attackerGuild ) // register new challenger attacker->addChallengedOutpost(_Alias); } - + // Send to AIS CSetOutpostAttacker attackerParams; attackerParams.Outpost = getAlias(); @@ -762,7 +764,7 @@ void COutpost::setState(OUTPOSTENUMS::TOutpostState state) switch( state ) { case OUTPOSTENUMS::Peace : - { + { clearBanishment(); } break; @@ -773,7 +775,7 @@ void COutpost::setState(OUTPOSTENUMS::TOutpostState state) } break; case OUTPOSTENUMS::DefenseRound : - { + { broadcastMessage(OwnerGuild, DefenseRounds); broadcastMessage(AttackerGuild, DefenseRounds); } @@ -790,7 +792,7 @@ void COutpost::setState(OUTPOSTENUMS::TOutpostState state) OUTPOST_DBG( "Outpost %s: [%s] -> [%s]", _Name.c_str(), OUTPOSTENUMS::toString( _State ).c_str(), OUTPOSTENUMS::toString( state ).c_str() ); _State = state; - + // Send to AIS COutpostSetStateMsg params; params.Outpost = getAlias(); @@ -856,7 +858,7 @@ COutpost::TChallengeOutpostErrors COutpost::challengeOutpost( CGuild *attackerGu eventTriggered(OUTPOSTENUMS::Challenged); } - log_Outpost_Challenge(_Name, + log_Outpost_Challenge(_Name, this->_OwnerGuildId ? CGuildManager::getInstance()->getGuildFromId(this->_OwnerGuildId)->getName().toUtf8() : "TRIBES_OWNED", attackerGuild->getName().toUtf8()); @@ -1049,7 +1051,7 @@ void COutpost::aieventSquadDied(uint32 groupId) { if (!it->isNull() && (*it)->getGroupId()==groupId) { - ++_FightData._KilledSquads; + ++_FightData._KilledSquads; (*it)->died(); askGuildDBUpdate(COutpostGuildDBUpdater::SQUAD_SPAWNED); return; @@ -1060,7 +1062,7 @@ void COutpost::aieventSquadDied(uint32 groupId) { if (!it->isNull() && (*it)->getGroupId()==groupId) { - ++_FightData._KilledSquads; + ++_FightData._KilledSquads; (*it)->died(); askGuildDBUpdate(COutpostGuildDBUpdater::SQUAD_SPAWNED); return; @@ -1081,7 +1083,7 @@ void COutpost::aieventSquadLeaderDied(uint32 groupId) if (!it->isNull() && (*it)->getGroupId()==groupId) { -// ++_FightData._KilledSquads; +// ++_FightData._KilledSquads; (*it)->leaderDied(); askGuildDBUpdate(COutpostGuildDBUpdater::SQUAD_SPAWNED); return; @@ -1092,7 +1094,7 @@ void COutpost::aieventSquadLeaderDied(uint32 groupId) { if (!it->isNull() && (*it)->getGroupId()==groupId) { -// ++_FightData._KilledSquads; +// ++_FightData._KilledSquads; (*it)->leaderDied(); askGuildDBUpdate(COutpostGuildDBUpdater::SQUAD_SPAWNED); return; @@ -1105,7 +1107,7 @@ void COutpost::aieventSquadLeaderDied(uint32 groupId) void COutpost::aisUp() { OUTPOST_DBG( "Outpost %s: resending dynamic data to AIS", _Name.c_str() ); - + nlassert(!_AISUp); _AISUp = true; @@ -1113,7 +1115,7 @@ void COutpost::aisUp() setAttackerGuild( _AttackerGuildId ); setState( _State ); - + // vector::iterator it, itEnd; // itEnd = _CurrentSquadsA.end(); // for (it=_CurrentSquadsA.begin(); it!=itEnd; ++it) @@ -1123,7 +1125,7 @@ void COutpost::aisUp() // for (it=_CurrentSquadsB.begin(); it!=itEnd; ++it) // if (!it->isNull()) // (*it)->AISUp(); - + eventTriggered(OUTPOSTENUMS::EventAisUp); // buildings @@ -1135,10 +1137,10 @@ void COutpost::aisUp() void COutpost::aisDown() { OUTPOST_DBG( "Outpost %s: resetting dynamic data of AIS", _Name.c_str() ); - + nlassert(_AISUp); _AISUp = false; - + vector::iterator it, itEnd; itEnd = _CurrentSquadsA.end(); for (it=_CurrentSquadsA.begin(); it!=itEnd; ++it) @@ -1154,9 +1156,9 @@ void COutpost::aisDown() (*it)->AISDown(); (*it) = NULL; } - + eventTriggered(OUTPOSTENUMS::EventAisDown); - + _CurrentSquadsA.clear(); _CurrentSquadsB.clear(); @@ -1199,10 +1201,10 @@ void COutpost::updateOutpost(uint32 currentTime) nlerror("Undefined state in outpost"); } } - + // Child updates // Squads - + for (vector::iterator its=_CurrentSquadsA.begin(); its!=_CurrentSquadsA.end(); ++its) { if (!its->isNull() && !(*its)->updateSquad(currentTime) ) @@ -1459,7 +1461,7 @@ PVP_RELATION::TPVPRelation COutpost::getPVPRelation( CCharacter * user, CEntityB { H_AUTO(COutpost_getPVPRelation); BOMB_IF( ! (user && target), "ErrorCUHTT", return PVP_RELATION::Unknown ); - + if( IsRingShard ) return PVP_RELATION::Neutral; @@ -1471,7 +1473,7 @@ PVP_RELATION::TPVPRelation COutpost::getPVPRelation( CCharacter * user, CEntityB { return PVP_RELATION::Neutral; } - + CCharacter * pTarget = dynamic_cast(target); if (pTarget == 0) return PVP_RELATION::Unknown; @@ -1553,7 +1555,7 @@ bool COutpost::isPlayerBanishedForDefense( CEntityId& id ) const } return false; } - + } //---------------------------------------------------------------------------- @@ -1575,7 +1577,7 @@ bool COutpost::isGuildBanishedForDefense( uint32 guildId ) const return true; else return false; - + } //----------------------------------------------------------------------------- @@ -1657,13 +1659,13 @@ void COutpost::banishGuildForDefense( uint32 guildId ) OUTPOST_WRN(" guild id 0 is not a valid guild id"); return; } - + set::const_iterator it = _DefenseBanishedGuilds.find( guildId ); if( it != _DefenseBanishedGuilds.end() ) return; else _DefenseBanishedGuilds.insert( guildId ); - + // each members of guild are removed from outpost conflict CGuild * guild = CGuildManager::getInstance()->getGuildFromId( guildId ); if( guild ) @@ -1865,7 +1867,7 @@ bool COutpost::convertSpawnZoneIndex(uint32 spawnZoneIndex, TAIAlias & spawnZone { if (spawnZoneIndex >= _SpawnZones.size()) return false; - + spawnZoneAlias = _SpawnZones[spawnZoneIndex].alias(); return true; } @@ -1889,7 +1891,7 @@ void COutpost::setNextAttackSquadA(uint32 index, COutpostSquadData const& nextSq nlassert(index < OUTPOSTENUMS::OUTPOST_NB_SQUAD_SLOTS); nlassert(nextSquad.getSquadDescriptor().sheet()!=CSheetId::Unknown); _NextAttackSquadsA[index] = nextSquad; -} +} //---------------------------------------------------------------------------- void COutpost::setNextAttackSquadB(uint32 index, COutpostSquadData const& nextSquad) @@ -1898,21 +1900,21 @@ void COutpost::setNextAttackSquadB(uint32 index, COutpostSquadData const& nextSq nlassert(index < OUTPOSTENUMS::OUTPOST_NB_SQUAD_SLOTS); nlassert(nextSquad.getSquadDescriptor().sheet()!=CSheetId::Unknown); _NextAttackSquadsB[index] = nextSquad; -} +} //---------------------------------------------------------------------------- void COutpost::setNextDefenseSquadA(uint32 index, COutpostSquadData const& nextSquad) { nlassert(index < _NextDefenseSquadsA.size()); _NextDefenseSquadsA[index] = nextSquad; -} +} //---------------------------------------------------------------------------- void COutpost::setNextDefenseSquadB(uint32 index, COutpostSquadData const& nextSquad) { nlassert(index < _NextDefenseSquadsA.size()); _NextDefenseSquadsB[index] = nextSquad; -} +} //---------------------------------------------------------------------------- bool COutpost::createSquad(COutpostSquadPtr& squad, COutpostSquadData const& squadData, CGuildCharProxy* leader, CGuild* originGuild, OUTPOSTENUMS::TPVPSide side) @@ -2320,10 +2322,10 @@ void COutpost::actionChangeOwner() { EGSPD::TGuildId newOwner = _AttackerGuildId; EGSPD::TGuildId newAttacker = _OwnerGuildId; - + setOwnerGuild(newOwner); setAttackerGuild(newAttacker); - + std::swap(_NextAttackSquadsA, _NextDefenseSquadsA); std::swap(_NextAttackSquadsB, _NextDefenseSquadsB); std::swap(_OwnerExpenseLimit, _AttackerExpenseLimit); @@ -2393,6 +2395,11 @@ void COutpost::actionPayBackMoneySpent() //---------------------------------------------------------------------------- uint32 COutpost::computeRoundCount() const { + ///// Nexus test : only 11 rounds + if (getName().substr(0, 14) == "outpost_nexus_") + return OutpostInTestFightRoundCount.get(); + ////// + return std::min(OutpostFightRoundCount.get(), OUTPOSTENUMS::OUTPOST_MAX_SQUAD_SPAWNED); } @@ -2423,13 +2430,24 @@ uint32 COutpost::computeSpawnDelay(uint32 roundLevel) const //---------------------------------------------------------------------------- uint32 COutpost::computeSquadCountA(uint32 roundLevel) const { - return (uint32)ceil((float)(roundLevel+1)/2.f); + + ///// Nexus test : Number of squad increase faster + if (getName().substr(0, 14) == "outpost_nexus_") + return (uint32)ceil((float)(roundLevel+1)/OutpostInTestFightSquadCount.get()); + ////// + + return (uint32)ceil((float)(roundLevel+1)/1.5f); } //---------------------------------------------------------------------------- uint32 COutpost::computeSquadCountB(uint32 roundLevel) const { - return (uint32)floor((float)(roundLevel+1)/2.f); + ///// Nexus test : Number of squad increase faster + if (getName().substr(0, 14) == "outpost_nexus_") + return (uint32)floor((float)(roundLevel+1)/OutpostInTestFightSquadCount.get()); + ////// + + return (uint32)floor((float)(roundLevel+1)/1.5f); } //---------------------------------------------------------------------------- @@ -3153,7 +3171,7 @@ std::string COutpost::toString() const #define PERSISTENT_DATA\ PROP2(VERSION, uint32, COutpostVersionAdapter::getInstance()->currentVersionNumber(), version = val)\ \ - /*PROP2(_PVPType, string, OUTPOSTENUMS::toString( _PVPType );, _PVPType = OUTPOSTENUMS::toPVPType( val ); )*/\ + PROP2(_PVPType, string, OUTPOSTENUMS::toString( _PVPType );, _PVPType = OUTPOSTENUMS::toPVPType( val ); )\ PROP2(_State, string, OUTPOSTENUMS::toString( _State );, _State = OUTPOSTENUMS::toOutpostState( val ); )\ PROP2(_OwnerGuildId, uint32, _OwnerGuildId & ((1<<20)-1), _OwnerGuildId = val != 0 ? ((val & ((1<<20)-1)) | (IService::getInstance()->getShardId()<<20)) : 0)\ PROP2(_AttackerGuildId, uint32, _AttackerGuildId & ((1<<20)-1), _AttackerGuildId = val != 0 ? ((val & ((1<<20)-1)) | (IService::getInstance()->getShardId()<<20)) : 0)\ diff --git a/ryzom/server/src/entities_game_service/outpost_manager/outpost.h b/ryzom/server/src/entities_game_service/outpost_manager/outpost.h index f08cf4fe2..3a92e7da4 100644 --- a/ryzom/server/src/entities_game_service/outpost_manager/outpost.h +++ b/ryzom/server/src/entities_game_service/outpost_manager/outpost.h @@ -31,7 +31,7 @@ #include "database_outpost.h" /** - * All classes in this file : + * All classes in this file : * \author Nicolas Brigand * \author Olivier Cado * \author Sebastien Guignot @@ -63,10 +63,10 @@ class COutpost NLMISC_COMMAND_FRIEND(outpostSetFightData); public: - + /// outposts are persistent and stored through PDR DECLARE_PERSISTENCE_METHODS - + public: enum TChallengeOutpostErrors { NoError = 0, @@ -82,7 +82,7 @@ public: TooManyGuildOutposts, UnknownError, }; - + enum TEditingAccessType { EditSquads, @@ -91,14 +91,14 @@ public: NbEditingAccessType }; - + enum TBroadcastAudience { OwnerGuild, AttackerGuild, OwnerFighters, AttackerFighters, - + NbBroadcastAudience }; enum TBroadcastMessage @@ -115,16 +115,16 @@ public: AttackRounds, DefenseRounds, WarDeclared, - + NbBroadcastMessage }; - + public: COutpost(); - + /// build an outpost from a primitive bool build(const NLLIGO::IPrimitive* prim,const std::string &filename,const std::string &dynSystem, CONTINENT::TContinent continent); - + /// return true if this building was awaited to be built bool onBuildingSpawned(CCreature *pBuilding); @@ -153,7 +153,7 @@ public: /// get challenge cost (price to attack this outpost) uint32 getChallengeCost() const; - + /// get a random spawn zone of the outpost TAIAlias getRandomSpawnZone() const; //@} @@ -168,18 +168,18 @@ public: EGSPD::TGuildId getOwnerGuild() const { return _OwnerGuildId; } /// return the id of the guild attacking the outpost (opponent), or 0 in peace time EGSPD::TGuildId getAttackerGuild() const { return _AttackerGuildId; } - + /// challenges the outpost (war declaration). attackerGuild must be non-null. TChallengeOutpostErrors challengeOutpost(CGuild* attackerGuild, bool simulate = false); - + /// if the attacking guild want to stop the attack (or counter attack) void giveupAttack(); /// if the attacking guild want to stop the attack (or counter attack) void giveupOwnership(); - + void ownerGuildVanished(); void attackerGuildVanished(); - + /// set a squad in the given slot bool setSquad(OUTPOSTENUMS::TPVPSide side, uint32 squadSlot, uint32 shopSquadIndex); /// set the spawn zone of a squad @@ -199,7 +199,7 @@ public: /// get a one line description string (for debug) std::string toString() const; //@} - + /// PVP zone management (IPVPZone implementation) //@{ virtual bool leavePVP(CCharacter * user, IPVP::TEndType type); @@ -207,12 +207,12 @@ public: virtual bool isCharacterInConflict(CCharacter *user) const; virtual PVP_RELATION::TPVPRelation getPVPRelation( CCharacter * user, CEntityBase * target ) const; //@} - + /// get PVP mode to send to the client (IPVP implementation) //@{ virtual PVP_MODE::TPVPMode getPVPMode() const { return PVP_MODE::PvpZoneOutpost; } //@} - + /// Init //@{ /// called on outposts that have never been saved before @@ -220,12 +220,12 @@ public: /// register outpost in its owner/attacker guilds if any void registerOutpostInGuilds(); //@} - + /// @name Manager used methods //@{ /// return the AI instance number of the continent of the outpost uint32 getAIInstanceNumber() const; - + /// send dynamic data to the corresponding AIS, when restarting EGS or /// AIS. aisUp() and aisDown() must be called alternatively (not two /// aisUp() between two aisDown()). @@ -234,11 +234,11 @@ public: void aisDown(); bool isAISUp() const { return _AISUp; } - + /// update the outpost state depending on the elapsing time /// \param currentTime : seconds since 1970 void updateOutpost(uint32 currentTime); - + /// simulate a timer end void simulateTimer0End(uint32 endTime = 1); /// simulate a timer end @@ -246,7 +246,7 @@ public: /// simulate a timer end void simulateTimer2End(uint32 endTime = 1); //@} - + /// @name AIS events //@{ /// called when a squad was created @@ -260,12 +260,12 @@ public: /// called when a squad leader died void aieventSquadLeaderDied(uint32 groupId); //@} - + /// @name Squad used methods //@{ /// return the AIS Id corresponding to the instance of the continent of the outpost, or 0 (with a nlwarning) if not found (AIS not online...) NLNET::TServiceId getAISId() const; - + /// send a message to the AIS hosting the outpost template void sendOutpostMessage(const std::string& msgName, T& paramStruct) @@ -279,7 +279,7 @@ public: } } //@} - + /// @name AIS interface //@{ /// initialize default squads @@ -289,7 +289,7 @@ public: //@} - /// Banishment management + /// Banishment management bool isPlayerBanishedForAttack( NLMISC::CEntityId& id ) const; bool isPlayerBanishedForDefense( NLMISC::CEntityId& id ) const; bool isGuildBanishedForAttack( uint32 guildId ) const; @@ -303,7 +303,7 @@ public: void unBanishGuildForAttack( uint32 guildId ); void unBanishGuildForDefense( uint32 guildId ); void clearBanishment(); - + /// Time void timeSetAttackHour(uint32 val); void timeSetDefenseHour(uint32 val); @@ -314,7 +314,7 @@ public: static std::string getErrorString(TChallengeOutpostErrors error); - + private: /// an event affecting outpost state occured @@ -322,7 +322,7 @@ private: /// an event affecting outpost state occured and has not been handled /// WARNING: it should only be called from eventTriggered void eventException(OUTPOSTENUMS::TOutpostEvent event, void* eventParams); - + // State machine parameters uint32 computeRoundCount() const; uint32 computeRoundTime() const; @@ -348,7 +348,7 @@ private: uint32 computeTimeRangeLengthForClient() const; uint32 computeTribeOutpostLevel() const; uint32 computeGuildMinimumOutpostLevel() const; - + public: static uint32 s_computeEstimatedAttackTimeForClient(uint32 hour); private: @@ -395,7 +395,7 @@ private: uint32 _MaxAttackLevel; uint32 _MaxDefenseLevel; } _FightData; - + private: /// called before storing a pdr save record void preStore() const; @@ -409,9 +409,9 @@ private: void setNextAttackSquadB(uint32 index, COutpostSquadData const& squadData); void setNextDefenseSquadA(uint32 index, COutpostSquadData const& squadData); void setNextDefenseSquadB(uint32 index, COutpostSquadData const& squadData); - + bool createSquad(COutpostSquadPtr& squad, COutpostSquadData const& squadData, CGuildCharProxy* leader, CGuild* originGuild, OUTPOSTENUMS::TPVPSide side); - + public: //for commands /// changes the state of the outpost void setState(OUTPOSTENUMS::TOutpostState state); @@ -451,7 +451,7 @@ private: void broadcastMessageMsg(std::vector const& audience, std::string const& message, TVectorParamCheck const& params=TVectorParamCheck()) const; void broadcastMessagePopup(std::vector const& audience, std::string const& message, TVectorParamCheck const& params=TVectorParamCheck(), TVectorParamCheck const& paramsTitle=TVectorParamCheck()) const; void broadcastMessage(TBroadcastAudience audience, TBroadcastMessage message) const; - + private: /// @name Static data read from primitive //@{ @@ -463,7 +463,7 @@ private: NLMISC::CSheetId _Sheet; /// continent of the outpost CONTINENT::TContinent _Continent; - + /// current buildings std::vector< COutpostBuilding > _Buildings; @@ -477,14 +477,14 @@ private: std::vector _BuyableSquads; /// spawn zones of the outpost std::vector _SpawnZones; - + /// PVP type allowed in the outpost OUTPOSTENUMS::TPVPType _PVPType; - + /// outpost sheet const CStaticOutpost* _Form; //@} - + /// @name Dynamic persistent data //@{ /// current state of the outpost @@ -527,7 +527,7 @@ private: /// tells if last outpost challenge ended in a server crash bool _CrashHappened; - + /// Timings /// /// Challenge starts at _ChallengeHour on day D (or _ChallengeTime since 1970) @@ -543,7 +543,7 @@ private: uint32 _DefenseHour; ///< Hour in the day, starting at UTC midnight, from 0 to 23 //@} //@} - + /// \name Temporary data //@{ /// next state of the outpost @@ -574,7 +574,7 @@ private: std::set _DefenseBanishedPlayers; std::set _AttackBanishedPlayers; - + /// @name CDB stuff //@{ public: @@ -591,7 +591,7 @@ private: private: /// CDB group for outpost state -// CCDBGroup _DbGroup; +// CCDBGroup _DbGroup; CBankAccessor_OUTPOST _DbGroup; bool _NeedOutpostDBUpdate; @@ -611,6 +611,8 @@ public: void setRealChallengeTime(uint32 t) { _RealChallengeTime = t; } void setChallengeTime(uint32 t) { _ChallengeTime = t; } void setChallengeHour(uint32 t) { _ChallengeHour = t; } + void setPvpType(OUTPOSTENUMS::TPVPType type) { _PVPType = type; } + OUTPOSTENUMS::TPVPType getPvpType() { return _PVPType; } }; diff --git a/ryzom/server/src/entities_game_service/outpost_manager/outpost_commands.cpp b/ryzom/server/src/entities_game_service/outpost_manager/outpost_commands.cpp index 0270eb9e6..b88929cdf 100644 --- a/ryzom/server/src/entities_game_service/outpost_manager/outpost_commands.cpp +++ b/ryzom/server/src/entities_game_service/outpost_manager/outpost_commands.cpp @@ -80,9 +80,9 @@ CSmartPtr getOutpostFromString(const std::string & outpostString, CLog //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- -NLMISC_COMMAND(outpostChallengeByGuild, "Challenges an outpost", " ") +NLMISC_COMMAND(outpostChallengeByGuild, "Challenges an outpost", " ") { - if (args.size()!=2) + if (args.size() < 2) return false; CSmartPtr outpost = getOutpostFromString(args[0], log); @@ -92,11 +92,20 @@ NLMISC_COMMAND(outpostChallengeByGuild, "Challenges an outpost", " < CGuild * guild = CGuildManager::getInstance()->getGuildByName( args[1] ); if ( guild == NULL ) { - log.displayNL("Invalid guild '%s'", args[1].c_str()); + log.displayNL("ERR: Invalid guild '%s'", args[1].c_str()); return true; } - outpost->challengeOutpost( guild ); + string error = COutpost::getErrorString(outpost->challengeOutpost( guild )); + if (error == "OUTPOST_ERROR_NONE") + { + if (args.size() > 2) + outpost->setPvpType(OUTPOSTENUMS::toPVPType(args[2])); + log.displayNL("OK"); + } + else + log.displayNL("ERR: %s", error.c_str()); + return true; } @@ -125,7 +134,7 @@ NLMISC_COMMAND(outpostSimulateTimer0End, "", " [ endTime += CTime::getSecondsSince1970(); } if (endTime==0) endTime = 1; - + outpost->simulateTimer0End(endTime); return true; } @@ -148,7 +157,7 @@ NLMISC_COMMAND(outpostSimulateTimer1End, "", " [ endTime += CTime::getSecondsSince1970(); } if (endTime==0) endTime = 1; - + outpost->simulateTimer1End(endTime); return true; } @@ -158,7 +167,7 @@ NLMISC_COMMAND(outpostSimulateTimer2End, "", " [ { if (args.size()<1) return false; - + CSmartPtr outpost = getOutpostFromString(args[0], log); if (outpost == NULL) return true; @@ -171,7 +180,7 @@ NLMISC_COMMAND(outpostSimulateTimer2End, "", " [ endTime += CTime::getSecondsSince1970(); } if (endTime==0) endTime = 1; - + outpost->simulateTimer2End(endTime); return true; } @@ -289,7 +298,7 @@ NLMISC_COMMAND(outpostAccelerateConstruction, "set all current construction to a NLMISC::fromString(args[0], nNbSecondLeft); COutpostManager::getInstance().setConstructionTime(nNbSecondLeft); - + return true; } @@ -297,9 +306,9 @@ NLMISC_COMMAND(outpostAccelerateConstruction, "set all current construction to a NLMISC_COMMAND(outpostPlayerOutpostInfos, "get the outpost infos of a player", "") { if (args.size() != 1) return false; - + GET_CHARACTER - + string str; uint32 outpostAlias = c->getOutpostAlias(); OUTPOSTENUMS::TPVPSide side = c->getOutpostSide(); @@ -313,7 +322,7 @@ NLMISC_COMMAND(outpostPlayerOutpostInfos, "get the outpost infos of a player", " { str = "no outpost"; } - + log.displayNL("Player %s outpost : %s", c->getId().toString().c_str(), str.c_str()); return true; } @@ -343,7 +352,7 @@ NLMISC_COMMAND(outpostGiveupOutpost, "Giveup an outpost, letting its ownership t { if (args.size()!=2) return false; - + GET_CHARACTER CGuildMemberModule * module; @@ -353,7 +362,7 @@ NLMISC_COMMAND(outpostGiveupOutpost, "Giveup an outpost, letting its ownership t CSmartPtr outpost = getOutpostFromString(args[1], log); if (outpost == NULL) return true; - + module->giveupOutpost(outpost->getSheet()); return true; } @@ -363,7 +372,7 @@ NLMISC_COMMAND(outpostDisplayGuildOutposts, "Display the outposts owned or being { if ( args.size() < 1 ) return false; - + GET_CHARACTER CGuild * guild = CGuildManager::getInstance()->getGuildFromId( c->getGuildId() ); @@ -426,9 +435,9 @@ NLMISC_COMMAND(outpostForceOpenGuildInventory, "", "" ) { if ( args.size() < 1 ) return false; - + GET_CHARACTER - + PlayerManager.sendImpulseToClient(eid, "GUILD:OPEN_INVENTORY"); return true; @@ -439,11 +448,11 @@ NLMISC_COMMAND(outpostForceCloseGuildInventory, "", "" ) { if ( args.size() < 1 ) return false; - + GET_CHARACTER - + PlayerManager.sendImpulseToClient(eid, "GUILD:CLOSE_INVENTORY"); - + return true; } @@ -451,9 +460,9 @@ NLMISC_COMMAND(outpostForceCloseGuildInventory, "", "" ) NLMISC_COMMAND(outpostSetPlayerPvpSide, "changes the outpost infos of a player", " [ attacker|defender]") { if (args.size() != 3 && args.size() != 1) return false; - + GET_CHARACTER - + if (args.size()==3) { CSmartPtr outpost = getOutpostFromString(args[1], log); @@ -470,7 +479,7 @@ NLMISC_COMMAND(outpostSetPlayerPvpSide, "changes the outpost infos of a player", log.displayNL("Invalid side specified"); return false; } - + c->setOutpostAlias(outpost->getAlias()); c->setOutpostSide(side); OUTPOST_INF("Player %s outpost side set to %s %s", c->getId().toString().c_str(), CPrimitivesParser::aliasToString(outpost->getAlias()).c_str(), side?"attacker":"defender"); @@ -481,7 +490,7 @@ NLMISC_COMMAND(outpostSetPlayerPvpSide, "changes the outpost infos of a player", OUTPOSTENUMS::TPVPSide side = c->getOutpostSide(); log.displayNL("Player %s outpost side set to %s %s", c->getId().toString().c_str(), CPrimitivesParser::aliasToString(outpostAlias).c_str(), OUTPOSTENUMS::toString(side).c_str()); } - + return true; } @@ -489,13 +498,13 @@ NLMISC_COMMAND(outpostSetPlayerPvpSide, "changes the outpost infos of a player", NLMISC_COMMAND(outpostSetOutpostToPlayer, "set the player's guild as the owner of the outpost", " ") { if (args.size() != 2) return false; - + GET_CHARACTER - + CSmartPtr outpost = getOutpostFromString(args[1], log); if (outpost == NULL) return true; - + CGuild * guild = CGuildManager::getInstance()->getGuildFromId( c->getGuildId() ); if (guild != NULL) { @@ -517,7 +526,7 @@ NLMISC_COMMAND(outpostSetOutpostOwner, "set the owner of the outpost", " 3) return false; - + CSmartPtr outpost = getOutpostFromString(args[0], log); if (outpost == NULL) return true; @@ -565,7 +574,7 @@ NLMISC_COMMAND(outpostSetOutpostOwner, "set the owner of the outpost", " ") { if (args.size() != 2) return false; - + GET_CHARACTER // remove previously selected outpost if any @@ -588,7 +597,7 @@ NLMISC_COMMAND(outpostSelectOutpost, "select an outpost to show it info", "") { if (args.size() != 1) return false; - + GET_CHARACTER TAIAlias outpostAlias = c->getSelectedOutpost(); @@ -603,7 +612,7 @@ NLMISC_COMMAND(outpostUnselectOutpost, "unselect an outpost", "") NLMISC_COMMAND(outpostSetAttackDefenseHour, "Set attack and defense time of an outpost", " ") { if (args.size() != 3) return false; - + // select the wanted outpost CSmartPtr outpost = getOutpostFromString(args[0], log); if (outpost == NULL) @@ -636,7 +645,7 @@ NLMISC_COMMAND(outpostSetAttackDefenseHour, "Set attack and defense time of an o NLMISC_COMMAND(outpostSetAttackDefenseDate, "Set attack and defense date of an outpost", " ") { if (args.size() != 2) return false; - + // select the wanted outpost CSmartPtr outpost = getOutpostFromString(args[0], log); if (outpost == NULL) @@ -656,12 +665,12 @@ NLMISC_COMMAND(outpostSetAttackDefenseDate, "Set attack and defense date of an o NLMISC_COMMAND(outpostSetState, "Set outpost state (Peace/WarDeclaration/AttackBefore/AttackRound/AttackAfter/DefenseBefore/DefenseRound/DefenseAfter)", " ") { if (args.size() != 2) return false; - + // select the wanted outpost CSmartPtr outpost = getOutpostFromString(args[0], log); if (outpost == NULL) return false; - + OUTPOSTENUMS::TOutpostState state = OUTPOSTENUMS::toOutpostState(args[1]); if(state == OUTPOSTENUMS::UnknownOutpostState) { @@ -677,7 +686,7 @@ NLMISC_COMMAND(outpostSetState, "Set outpost state (Peace/WarDeclaration/AttackB NLMISC_COMMAND(setMemberEntryDate, "Set guild member entry date", " ") { if (args.size() != 2) return false; - + GET_CHARACTER uint32 cycleEntryDate; @@ -732,11 +741,11 @@ NLMISC_COMMAND(outpostUnbanPlayer, "Unban player for an outpost", " NLMISC_COMMAND(outpostUnbanGuild, "Unban guild for an outpost", " []") { if( args.size() < 2 || args.size() > 3 ) return false; - + CSmartPtr outpost = getOutpostFromString(args[0], log); if (outpost == NULL) return false; - + CGuild * guild = CGuildManager::getInstance()->getGuildByName(args[1]); if (guild == NULL) { @@ -764,13 +773,13 @@ NLMISC_COMMAND(outpostUnbanGuild, "Unban guild for an outpost", " []") { if( args.size() < 2 || args.size() > 3 ) return false; - + CEntityId eid(args[1]); - + CSmartPtr outpost = getOutpostFromString(args[0], log); if (outpost == NULL) return false; - + if(args.size() == 2 || args[2] == string("all") ) { outpost->banishPlayerForDefense(eid); @@ -791,18 +800,18 @@ NLMISC_COMMAND(outpostBanPlayer, "Ban player for an outpost", " []") { if( args.size() < 2 || args.size() > 3 ) return false; - + CSmartPtr outpost = getOutpostFromString(args[0], log); if (outpost == NULL) return false; - + CGuild * guild = CGuildManager::getInstance()->getGuildByName(args[1]); if (guild == NULL) { log.displayNL("unknown guild : '%s'", args[1].c_str()); return true; } - + if(args.size() == 2 || args[2] == string("all") ) { outpost->banishGuildForDefense(guild->getId()); diff --git a/ryzom/server/src/entities_game_service/outpost_manager/outpost_manager.cpp b/ryzom/server/src/entities_game_service/outpost_manager/outpost_manager.cpp index efe71fbd0..89d1e0533 100644 --- a/ryzom/server/src/entities_game_service/outpost_manager/outpost_manager.cpp +++ b/ryzom/server/src/entities_game_service/outpost_manager/outpost_manager.cpp @@ -49,7 +49,9 @@ using namespace NLNET; //COutpostManager* COutpostManager::_Instance = NULL; extern NLMISC::CVariable UseBS; + CVariable LoadOutposts("egs", "LoadOutposts", "If false outposts won't be loaded", true, 0, true ); +CVariable OutpostInTestTeleportOutNeutrals("egs", "OutpostInTestTeleportOutNeutrals", "If true, teleport out of OP zone the neutrals", false, 0, true ); CFileDisplayer OutpostDisplayer("outposts.log"); CLog OutpostDbgLog(CLog::LOG_DEBUG), OutpostInfLog(CLog::LOG_INFO), OutpostWrnLog(CLog::LOG_WARNING), OutpostErrLog(CLog::LOG_ERROR); @@ -174,7 +176,7 @@ void COutpostManager::loadOutpostPrimitives() for ( first = primsList.begin(), last = primsList.end(); first != last; ++first ) { // get the squad_template nodes - for ( uint i = 0; i < first->Primitive.RootNode->getNumChildren(); ++i ) + for ( uint i = 0; i < first->Primitive.RootNode->getNumChildren(); ++i ) { const NLLIGO::IPrimitive* stNode = NULL; if ( first->Primitive.RootNode->getChild( stNode, i ) && stNode != NULL ) @@ -185,9 +187,9 @@ void COutpostManager::loadOutpostPrimitives() string path = first->FileName; CSquadTemplate squadTemplate; squadTemplate.SquadName = readProperty( stNode, "name", parentClass, path, false, true ); - + // get the squad_template variants - for ( uint j = 0; j < stNode->getNumChildren(); ++j ) + for ( uint j = 0; j < stNode->getNumChildren(); ++j ) { const NLLIGO::IPrimitive* stvNode = NULL; if ( stNode->getChild( stvNode, j ) && stvNode != NULL ) @@ -246,14 +248,14 @@ void COutpostManager::loadOutpostPrimitives() } } OUTPOST_DBG("Squad templates loaded."); - + OUTPOST_DBG("Loading outposts..."); // *** Outposts (must be done after squad templates) *** // get the primitive list and parse each primitive for ( first = primsList.begin(), last = primsList.end(); first != last; ++first ) { // get the dynamic_system nodes - for ( uint i = 0; i < first->Primitive.RootNode->getNumChildren(); ++i ) + for ( uint i = 0; i < first->Primitive.RootNode->getNumChildren(); ++i ) { const NLLIGO::IPrimitive* dynSystemNode = NULL; if ( first->Primitive.RootNode->getChild( dynSystemNode,i ) && dynSystemNode != NULL ) @@ -267,12 +269,12 @@ void COutpostManager::loadOutpostPrimitives() CONTINENT::TContinent continent = CONTINENT::toContinent( value ); if ( continent == CONTINENT::UNKNOWN ) { - OUTPOST_WRN("Invalid continent '%s' in dynamic system '%s' of primitive file '%s'", + OUTPOST_WRN("Invalid continent '%s' in dynamic system '%s' of primitive file '%s'", value.c_str(), dynSystemName.c_str(), first->FileName.c_str() ); break; } // parse all the outpost within this dynamic system. - for ( uint j = 0; j < dynSystemNode->getNumChildren(); ++j ) + for ( uint j = 0; j < dynSystemNode->getNumChildren(); ++j ) { const NLLIGO::IPrimitive* outpostNode = NULL; if ( dynSystemNode->getChild( outpostNode,j ) && outpostNode != NULL ) @@ -302,7 +304,7 @@ void COutpostManager::loadOutpostPrimitives() _OutpostsByAlias.insert( make_pair( outpost->getAlias(), outpost ) ); _OutpostsBySheet.insert( make_pair( outpost->getSheet(), outpost ) ); OUTPOST_INF("Outpost '%s' was successfully parsed", outpost->getName().c_str()); - + // nb : short id starts at 1, 0 is used for invalid _OutpostAliasToShortId.insert( make_pair( outpost->getAlias(), (uint16)_Outposts.size()) ); } @@ -315,7 +317,7 @@ void COutpostManager::loadOutpostPrimitives() } } OUTPOST_DBG("Outposts loaded."); - + OUTPOST_DBG("Clearing squad templates..."); // No more need of squad templates _SquadTemplates.clear(); @@ -392,7 +394,7 @@ void COutpostManager::loadOutpostSaveFiles() string path = /*Bsi.getLocalPath() +*/ string("outposts"); // create the saved file directory, if needed // CFile::createDirectory(path); - + // get all the outpost files TOupostFileClassCallback *ccb = new TOupostFileClassCallback; OutpostFiles.clear(); @@ -437,7 +439,7 @@ void COutpostManager::loadOutpostSaveFiles() // } // } OUTPOST_DBG("Outpost save files applied."); - + OUTPOST_DBG("Initializing unsaved outposts..."); // Init new outpost that have never been saved uint nbNewOutposts = 0; @@ -653,7 +655,7 @@ void COutpostManager::onAIInstanceReadyOrDown( uint32 instanceNumber, bool start void COutpostManager::tickUpdate() { H_AUTO(COutpostManager_tickUpdate); - + // do nothing until outpost save files are loaded if (!_OutpostSaveFilesLoaded) return; @@ -665,10 +667,10 @@ void COutpostManager::tickUpdate() // update outposts { H_AUTO(COutpostManagerUPDATE); - + if (OutpostUpdatePeriod.get() == 0) OutpostUpdatePeriod.set(1); - + if (OutpostUpdatePeriod.get() == 1) { // update every outposts each tick @@ -677,7 +679,7 @@ void COutpostManager::tickUpdate() { _Outposts[i]->updateOutpost(currentTime); } - + if (_OutpostUpdateCursor != 0) _OutpostUpdateCursor = 0; } @@ -686,16 +688,16 @@ void COutpostManager::tickUpdate() uint32 nbOutpost = (uint32)_Outposts.size(); uint32 nbOutpostPerTick = (uint32)floor(double(nbOutpost) / double(OutpostUpdatePeriod.get())); nbOutpostPerTick = std::max(uint32(1), nbOutpostPerTick); // The strict minimum is a single outpost update per tick - + uint32 beginIndex = _OutpostUpdateCursor; nlassert(beginIndex < _Outposts.size()); - + // move the cursor and roll it in valid outpost indexes range _OutpostUpdateCursor += nbOutpostPerTick; uint32 endIndex = _OutpostUpdateCursor; if (_OutpostUpdateCursor >= nbOutpost) _OutpostUpdateCursor -= nbOutpost; - + if (beginIndex != endIndex) { // update a range of outposts each tick @@ -716,10 +718,10 @@ void COutpostManager::tickUpdate() } } } - + // do outpost guild database updates doOutpostGuildDBUpdates(); - + // save 1 outpost if ( ( CTickEventHandler::getGameCycle() % OutpostSavingPeriod ) == 0 ) { @@ -790,7 +792,7 @@ void COutpostManager::saveOutpost(NLMISC::CSmartPtr outpost) } else { - H_AUTO(COutpostSerialBin); + H_AUTO(COutpostSerialBin); uint32 bufSize= pdr.totalDataSize(); vector buffer; buffer.resize(bufSize); @@ -856,13 +858,13 @@ uint16 COutpostManager::getOutpostShortId( TAIAlias alias ) TAIAlias COutpostManager::getOutpostAliasFromShortId( uint16 shortId ) { TAIAlias alias = 0; - + map::iterator it = _OutpostShortIdToAlias.find( shortId ); if( it != _OutpostShortIdToAlias.end() ) { alias = (*it).second; } - + return alias; } @@ -915,20 +917,31 @@ TAIAlias COutpostManager::getOutpostFromUserPosition( CCharacter *user ) const for (uint i = 0; i < _Outposts.size(); i++) { COutpost * outpost = _Outposts[i]; - if( outpost->contains(vect, false) ) + CVector nearPos; + float distance; + if( outpost->contains(vect, distance, nearPos) ) { - // Maybe we should check here that user is owner of the outpost - // if( outpost->isCharacterInConflict(user) ) - // { - return outpost->getAlias(); - // } - // else - // { - // OUTPOST_DBG(" user not in conflict"); - // } + if (OutpostInTestTeleportOutNeutrals.get()) + { + OUTPOSTENUMS::TOutpostState state = outpost->getState(); + bool outpostInFire = state == OUTPOSTENUMS::AttackBefore || state == OUTPOSTENUMS::AttackRound || state == OUTPOSTENUMS::DefenseBefore || state == OUTPOSTENUMS::DefenseRound; + if (outpost->getName().substr(0, 14) == "outpost_nexus_" && outpostInFire) + { + nlinfo("DISTANCE TO OUTPOST = %f", distance); + if (distance > 20.f && user->getOutpostSide() == OUTPOSTENUMS::UnknownPVPSide) + { + CVector outPos = user->getOutOutpostPos(); + user->teleportCharacter(outPos.x*1000.f, outPos.y*1000.f); + return CAIAliasTranslator::Invalid; + } + } + } + + return outpost->getAlias(); } } + user->setOutOutpostPos(vect.x, vect.y); return CAIAliasTranslator::Invalid; } @@ -936,9 +949,9 @@ TAIAlias COutpostManager::getOutpostFromUserPosition( CCharacter *user ) const void COutpostManager::enterOutpostZone(CCharacter* user) { H_AUTO(COutpostManager_enterPVPZone); - + nlassert(user); - + COutpost* outpost = getOutpostFromAlias(user->getCurrentOutpostZone()); if (outpost && outpost->getOwnerGuild()==user->getGuildId()) PlayerManager.sendImpulseToClient(user->getId(), "GUILD:OPEN_INVENTORY"); @@ -948,9 +961,9 @@ void COutpostManager::enterOutpostZone(CCharacter* user) void COutpostManager::leaveOutpostZone(CCharacter* user) { H_AUTO(COutpostManager_leavePVPZone); - + nlassert(user); - + // COutpost* outpost = getOutpostFromAlias(user->getCurrentOutpostZone()); // if (outpost && outpost->getOwnerGuild()==user->getGuildId()) PlayerManager.sendImpulseToClient(user->getId(), "GUILD:CLOSE_INVENTORY"); diff --git a/ryzom/server/src/entities_game_service/outpost_manager/outpost_manager.h b/ryzom/server/src/entities_game_service/outpost_manager/outpost_manager.h index ab39d5bbc..7139194da 100644 --- a/ryzom/server/src/entities_game_service/outpost_manager/outpost_manager.h +++ b/ryzom/server/src/entities_game_service/outpost_manager/outpost_manager.h @@ -32,7 +32,7 @@ extern NLMISC::CLog OutpostDbgLog, OutpostInfLog, OutpostWrnLog, OutpostErrLog; #ifdef RY_OUTPOST_TEMP_LOG -#define OUTPOST_DBG nldebug +#define OUTPOST_DBG nlinfo //#define OUTPOST_INF nlinfo #define OUTPOST_INF nldebug #define OUTPOST_WRN nlwarning diff --git a/ryzom/server/src/entities_game_service/player_manager/character.cpp b/ryzom/server/src/entities_game_service/player_manager/character.cpp index f914c54f8..ce0b428e2 100644 --- a/ryzom/server/src/entities_game_service/player_manager/character.cpp +++ b/ryzom/server/src/entities_game_service/player_manager/character.cpp @@ -20918,6 +20918,9 @@ void CCharacter::outpostOpenChooseSideDialog(TAIAlias outpostId) return; } + uint8 type = (uint8)outpost->getPvpType(); + + bms.serial(type); bms.serial(outpostInFire); bms.serial(playerGuildInConflict); bms.serial(playerGuildIsAttacker); @@ -21039,10 +21042,20 @@ void CCharacter::outpostSideChosen(bool neutral, OUTPOSTENUMS::TPVPSide side) // his guild doesn't participate in outpost conflict but player don't made a choice when op is under attack => random if (neutral && outpostInFire) { - if (uint32(RandomGenerator.rand(1)) == 0) - setOutpostSide(OUTPOSTENUMS::OutpostOwner); + + if (outpost->getName().substr(0, 14) == "outpost_nexus_") + { + nlinfo("Player are neutral in %s in fire : ", outpost->getName().c_str()); + //setOutpostSide(OUTPOSTENUMS::UnknownPVPSide); + + } else - setOutpostSide(OUTPOSTENUMS::OutpostAttacker); + { + if (uint32(RandomGenerator.rand(1)) == 0) + setOutpostSide(OUTPOSTENUMS::OutpostOwner); + else + setOutpostSide(OUTPOSTENUMS::OutpostAttacker); + } } else // his guild doesn't participate in outpost conflict so he can choose the side he wants @@ -23191,6 +23204,15 @@ void CCharacter::setBuildingExitPos(sint32 x, sint32 y, sint32 cell) _BuildingExitPos.z = cell; } +//------------------------------------------------------------------------------ + +void CCharacter::setOutOutpostPos(sint32 x, sint32 y) +{ + _OutOutpostPos.x = x; + _OutOutpostPos.y = y; +} + + //------------------------------------------------------------------------------ diff --git a/ryzom/server/src/entities_game_service/player_manager/character.h b/ryzom/server/src/entities_game_service/player_manager/character.h index f5453b77f..15ec85122 100644 --- a/ryzom/server/src/entities_game_service/player_manager/character.h +++ b/ryzom/server/src/entities_game_service/player_manager/character.h @@ -2370,6 +2370,12 @@ public: /// get building exit pos NLMISC::CVector getBuildingExitPos() const; + /// set last outside outpost position + void setOutOutpostPos(sint32 x, sint32 y); + + /// get last outside outpost position + NLMISC::CVector getOutOutpostPos() const; + /// set building exit zone void setBuildingExitZone(uint16 zoneIdx); @@ -3798,6 +3804,7 @@ private: uint16 _BuildingExitZone; NLMISC::CVector _BuildingExitPos; + NLMISC::CVector _OutOutpostPos; // used for force respawn player who are in a mainland in town of this mainland bool _RespawnMainLandInTown; diff --git a/ryzom/server/src/entities_game_service/player_manager/character_inlines.h b/ryzom/server/src/entities_game_service/player_manager/character_inlines.h index 5f82b6ea5..ae602492e 100644 --- a/ryzom/server/src/entities_game_service/player_manager/character_inlines.h +++ b/ryzom/server/src/entities_game_service/player_manager/character_inlines.h @@ -808,6 +808,14 @@ inline NLMISC::CVector CCharacter::getBuildingExitPos() const return _BuildingExitPos; } +//------------------------------------------------------------------------------ + +inline NLMISC::CVector CCharacter::getOutOutpostPos() const +{ + return _OutOutpostPos; +} + + //------------------------------------------------------------------------------ diff --git a/ryzom/server/src/entities_game_service/pvp_manager/pvp_zone.cpp b/ryzom/server/src/entities_game_service/pvp_manager/pvp_zone.cpp index 0abee8114..fd84c44ef 100644 --- a/ryzom/server/src/entities_game_service/pvp_manager/pvp_zone.cpp +++ b/ryzom/server/src/entities_game_service/pvp_manager/pvp_zone.cpp @@ -162,7 +162,7 @@ NLMISC::CSmartPtr IPVPZone::build(const NLLIGO::CPrimZone * zone) PRIM_VERIFY( CPrimitivesParser::getAlias(zone, pvpZone->_Alias) ); PRIM_ASSERT( pvpZone->_Alias != CAIAliasTranslator::Invalid ); - + // get the bounding box float minX = zone->VPoints[0].x; float minY = zone->VPoints[0].y; @@ -206,7 +206,7 @@ NLMISC::CSmartPtr IPVPZone::buildOutpostZone(const NLLIGO::CPrimZone * PRIM_VERIFY( CPrimitivesParser::getAlias(zone, pvpZone->_Alias) ); PRIM_ASSERT( pvpZone->_Alias != CAIAliasTranslator::Invalid ); - + // get the bounding box float minX = zone->VPoints[0].x; float minY = zone->VPoints[0].y; @@ -295,12 +295,28 @@ void IPVPZone::dumpZone(NLMISC::CLog * log, bool dumpUsers) const } } +//---------------------------------------------------------------------------- +bool IPVPZone::contains(const NLMISC::CVector & v, float &distance, NLMISC::CVector &nearPos) const +{ + + if ( !CPrimZone::contains(v, VPoints, distance, nearPos, false)) + return false; + + return true; +} + + //---------------------------------------------------------------------------- bool IPVPZone::contains(const NLMISC::CVector & v, bool excludeSafeZones) const { + + CVector nearPos; + float distance; + CPrimZone::contains (v, VPoints, distance, nearPos, true); + if ( !CPrimZone::contains(v) ) return false; - + // safe zones are excluded from the PVP zone if (excludeSafeZones) { @@ -310,7 +326,7 @@ bool IPVPZone::contains(const NLMISC::CVector & v, bool excludeSafeZones) const return false; } } - + return true; } @@ -546,7 +562,7 @@ void CPVPVersusZone::addPlayer(CCharacter * user) // ask player to choose his clan //user->openPVPVersusDialog(); - + // set player clan depending on it's fames setPlayerClan( user ); } @@ -627,7 +643,7 @@ PVP_CLAN::TPVPClan CPVPVersusZone::getPlayerClan(CCharacter * user, PVP_CLAN::TP // get fame of player in each clan const sint32 fame1 = CFameInterface::getInstance().getFameIndexed( user->getId(), PVP_CLAN::getFactionIndex(clan1), false, true ); sint32 fame2 = CFameInterface::getInstance().getFameIndexed( user->getId(), PVP_CLAN::getFactionIndex(clan2), false, true ); - + // find his clan PVP_CLAN::TPVPClan clan = determinatePlayerClan( user, clan1, fame1, clan2, fame2 ); @@ -637,12 +653,12 @@ PVP_CLAN::TPVPClan CPVPVersusZone::getPlayerClan(CCharacter * user, PVP_CLAN::TP //---------------------------------------------------------------------------- bool CPVPVersusZone::isOverridedByARunningEvent( CCharacter * user ) { - + bool event = CGameEventManager::getInstance().isGameEventRunning(); PVP_CLAN::TPVPClan eventClan1 = PVP_CLAN::fromString( CGameEventManager::getInstance().getFaction1() ); PVP_CLAN::TPVPClan eventClan2 = PVP_CLAN::fromString( CGameEventManager::getInstance().getFaction2() ); bool zoneOnly = CGameEventManager::getInstance().isFactionChanelInZoneOnly(); - + if( event && eventClan1==_Clan1 && eventClan2==_Clan2 && !zoneOnly ) { if( user->isChannelAdded() ) @@ -708,7 +724,7 @@ bool CPVPVersusZone::setPlayerClan(CCharacter * user/*, PVP_CLAN::TPVPClan clan* if (clan != PVP_CLAN::Neutral) { const PVP_CLAN::TPVPClan rivalClan = (clan == _Clan1) ? _Clan2 : _Clan1; - + // if player is not neutral anymore, clear his aggressors _AggressedNeutralUsers.erase( user->getEntityRowId() ); @@ -768,15 +784,15 @@ PVP_CLAN::TPVPClan CPVPVersusZone::determinatePlayerClan( CCharacter *user, PVP_ void CPVPVersusZone::setPlayerClanInMirror(CCharacter * user, PVP_CLAN::TPVPClan clan) const { BOMB_IF( clan >= PVP_CLAN::NbClans, "invalid clan!", return ); - + if (!user) return; - + const TDataSetRow & rowId = user->getEntityRowId(); - + if ( !TheDataset.isAccessible(rowId) ) return; - + CMirrorPropValue propPvpClan( TheDataset, rowId, DSPropertyPVP_CLAN ); propPvpClan = (uint8) clan; user->updateGuildFlag(); @@ -790,7 +806,7 @@ PVP_CLAN::TPVPClan CPVPVersusZone::getCharacterClan( const NLMISC::CEntityId& ch { return (*it).second; } - return PVP_CLAN::Neutral; + return PVP_CLAN::Neutral; } //---------------------------------------------------------------------------- @@ -811,7 +827,7 @@ bool CPVPVersusZone::leavePVP(CCharacter * user, IPVP::TEndType type) if( user->haveAnyPrivilege() == false ) { if( ! isOverridedByARunningEvent( user ) ) - { + { if( (*it).second == _Clan1 ) { CGameEventManager::getInstance().removeCharacterToChannelFactionEvent( user, 1 ); @@ -823,7 +839,7 @@ bool CPVPVersusZone::leavePVP(CCharacter * user, IPVP::TEndType type) } } } - + _UsersClan.erase( it ); // update mirror @@ -893,7 +909,7 @@ void CPVPVersusZone::userHurtsTarget(CCharacter * user, CCharacter * target) // Update neutral bot chat programme target->setTargetBotchatProgramm( user, user->getId() ); } - + #ifdef PVP_DEBUG map::const_iterator userClanIt = _UsersClan.find( user->getId() ); BOMB_IF( userClanIt == _UsersClan.end(), "PVP: player must have a clan!", return ); @@ -921,7 +937,7 @@ PVP_RELATION::TPVPRelation CPVPVersusZone::getPVPRelation( CCharacter * user, CE map::const_iterator userClanIt = _UsersClan.find( user->getId() ); BOMB_IF( userClanIt == _UsersClan.end(), "PVP: player must have a clan!", return PVP_RELATION::Neutral ); - + // check that target is in the same zone than user (discards bots) if ( _Users.find( target->getEntityRowId() ) != _Users.end() ) { @@ -930,7 +946,7 @@ PVP_RELATION::TPVPRelation CPVPVersusZone::getPVPRelation( CCharacter * user, CE const PVP_CLAN::TPVPClan userClan = (*userClanIt).second; const PVP_CLAN::TPVPClan targetClan = (*targetClanIt).second; - + if (userClan == PVP_CLAN::Neutral) { // neutral players can only attack their aggressors @@ -1182,7 +1198,7 @@ PVP_RELATION::TPVPRelation CPVPGuildZone::getPVPRelation( CCharacter * user, CEn return PVP_RELATION::NeutralPVP; } - // if target is in same zone then he's an ennemy or ally + // if target is in same zone then he's an ennemy or ally if ( _Users.find( target->getEntityRowId() ) != _Users.end() ) { // In Same Team or League => Ally @@ -1190,8 +1206,8 @@ PVP_RELATION::TPVPRelation CPVPGuildZone::getPVPRelation( CCharacter * user, CEn { return PVP_RELATION::Ally; } - - // in same Guild and not in Leagues => Ally + + // in same Guild and not in Leagues => Ally if (inSameGuild( user, pTarget ) && user->getLeagueId() == DYN_CHAT_INVALID_CHAN && pTarget->getLeagueId() == DYN_CHAT_INVALID_CHAN) { return PVP_RELATION::Ally; @@ -1204,7 +1220,7 @@ PVP_RELATION::TPVPRelation CPVPGuildZone::getPVPRelation( CCharacter * user, CEn return PVP_RELATION::NeutralPVP; } - + /* //---------------------------------------------------------------------------- bool CPVPGuildZone::canUserHurtTarget(CCharacter * user, CEntityBase * target) const diff --git a/ryzom/server/src/entities_game_service/pvp_manager/pvp_zone.h b/ryzom/server/src/entities_game_service/pvp_manager/pvp_zone.h index 132c02d95..bfee81a75 100644 --- a/ryzom/server/src/entities_game_service/pvp_manager/pvp_zone.h +++ b/ryzom/server/src/entities_game_service/pvp_manager/pvp_zone.h @@ -99,7 +99,7 @@ public: /// get zone type PVP_ZONE_TYPE::TPVPZoneType getPVPZoneType() const { return _PVPZoneType; } - /** + /** * Return true if a character killed by 'killer' must use deathPenaltyFactor(). * Precondition: kill not null. * By default, it's true only when killed by a player character. @@ -111,6 +111,7 @@ public: /// returns true if the PVP zone contains the given position bool contains(const NLMISC::CVector & v, bool excludeSafeZones = true) const; + bool contains(const NLMISC::CVector & v, float &distance, NLMISC::CVector &nearPos) const; bool contains(CCharacter* user, bool excludeSafeZones = true) const; /** @@ -216,13 +217,13 @@ public: /// return pvp relation between the two players PVP_RELATION::TPVPRelation getPVPRelation( CCharacter * user, CEntityBase * target ) const; - + private: bool isOverridedByARunningEvent( CCharacter * user ); bool setPlayerClan(CCharacter * user/*, PVP_CLAN::TPVPClan clan*/); - + static PVP_CLAN::TPVPClan determinatePlayerClan( CCharacter *user, PVP_CLAN::TPVPClan clan1, sint32 fame1, PVP_CLAN::TPVPClan clan2, sint32 fame2 ); void setPlayerClanInMirror(CCharacter * user, PVP_CLAN::TPVPClan clan) const; @@ -269,7 +270,7 @@ public: /// return pvp relation between the two players PVP_RELATION::TPVPRelation getPVPRelation( CCharacter * user, CEntityBase * target ) const; - + private: bool leavePVP(CCharacter * user, IPVP::TEndType type); @@ -295,8 +296,8 @@ private: class CPVPOutpostZone : public IPVPZone { public: - - /** + + /** * Return true if a character killed by 'killer' must use deathPenaltyFactor(). * Precondition: kill not null. * For outpost zones, it's true whether the killer is a player character or a bot.