Merge with develop

This commit is contained in:
kervala 2015-12-29 18:03:21 +01:00
commit 556333ca38
60 changed files with 2054 additions and 326 deletions

View file

@ -669,7 +669,7 @@ static void BuildColoredVersionForOneBitmap(const CBuildInfo &bi, const std::str
// we can save it as RGB to optimize it
if (bi.OptimizeTextures > 0 && depth == 32)
{
uint32 size = srcBitmap.getSize(0);
uint32 size = srcBitmap.getPixels().size();
if (size > 0)
{

View file

@ -239,7 +239,7 @@ public:
CHashCode() {}
enum { bucket_size = 4, min_buckets = 8, };
enum { bucket_size = 4, min_buckets = 8 };
size_t operator () ( const TDataSetRow &index ) const { return index.getHashCode(); }

View file

@ -4176,7 +4176,7 @@ NLMISC_COMMAND(loadMap,"load a complete set of primitive files","<map name>")
// check that the continent is active
CUsedContinent &uc = CUsedContinent::instance();
uint32 in = uc.getInstanceForContinent(continentName);
if (in == INVALID_AI_INSTANCE)
if (in == std::numeric_limits<uint32>::max())
{
log.displayNL("loadMap : while loading map '%s', can't load primitive '%s' coz continent '%s' is not active",
args[0].c_str(),
@ -4216,7 +4216,7 @@ NLMISC_COMMAND(unloadMap,"unload a complete set of primitive files","<map name>"
// check that the continent is active
CUsedContinent &uc = CUsedContinent::instance();
uint32 in = uc.getInstanceForContinent(continentName);
if (in == INVALID_AI_INSTANCE)
if (in == std::numeric_limits<uint32>::max())
{
log.displayNL("unloadMap : while loading map '%s', can't load primitive '%s' coz continent '%s' is not active",
args[0].c_str(),

File diff suppressed because it is too large Load diff

View file

@ -46,11 +46,31 @@ void initCommandsPrivileges(const std::string & fileName);
void initPositionFlags(const std::string & fileName);
void initSalt();
const std::string &getSalt();
void getUCstringFromHash(const std::string & hash, ucstring & finaltext);
std::string getStringFromHash(const std::string &hash);
CAdminCommand * findAdminCommand(const std::string & name);
extern void GET_CHARACTER_Helper(std::string& command, const NLMISC::CEntityId& id, const std::string& adminCommand);
#define GET_ENTITY \
if (args.size() < 1) { nlwarning ("Missing argument number 0 that should be the eid"); return false; } \
CEntityId eid(args[0]); \
if (eid == CEntityId::Unknown) \
return true; \
TLogContext_Character_AdminCommand commandContext(eid); \
CEntityBase *e = CEntityBaseManager::getEntityBasePtr(eid); \
if(e == 0) \
{ \
nlwarning ("Unknown entity '%s'", eid.toString().c_str()); \
return true; \
} \
if(!TheDataset.isAccessible(e->getEntityRowId())) \
{ \
nlwarning ("'%s' is not valid in mirror", eid.toString().c_str()); \
return true; \
}
#define GET_CHARACTER \
if (args.size() < 1) { nlwarning ("Missing argument number 0 that should be the eid"); return false; } \
CEntityId eid(args[0]); \
@ -88,6 +108,29 @@ extern void GET_CHARACTER_Helper(std::string& command, const NLMISC::CEntityId&
} \
end:
#define GET_ACTIVE_CHARACTER \
if (args.size() < 1) { nlwarning ("ERR: Missing argument number 0 that should be the uid"); return false; } \
uint32 uid; \
NLMISC::fromString(args[0], uid); \
CCharacter *c = CPlayerManager::getInstance().getActiveChar(uid); \
if(c == 0) \
{ \
log.displayNL ("ERR: Unknown player '%u' (%s)", uid, args[0].c_str()); \
return false; \
} \
CEntityId eid = c->getId(); \
TLogContext_Character_AdminCommand commandContext(eid); \
if(!c->getEnterFlag()) \
{ \
log.displayNL ("ERR: '%s' is not entered", eid.toString().c_str()); \
return false; \
} \
if(!TheDataset.isAccessible(c->getEntityRowId())) \
{ \
log.displayNL ("ERR: '%s' is not valid in mirror", eid.toString().c_str()); \
return false; \
} \
//#define GET_CHARACTER1 \
// if (args.size() < 2) { nlwarning ("Missing argument number 1 that should be the eid"); return false; } \
// CEntityId eid = CEntityIdTranslator::getInstance()->getByEntity(args[1]); \

View file

@ -57,6 +57,8 @@ public:
inline const CTPDestination* getExit( uint8 idx )const;
/// return the default exit spawn zone
inline uint16 getDefaultExitSpawn() const;
/// return the Cell of roomIdx and ownerId
inline sint32 getRoomCell( uint16 roomIdx, uint16 ownerIdx );
//@}
/// get the cell id of a physical room of this building. Return true if no error.
@ -184,6 +186,8 @@ public:
inline void resetRoomCell( uint16 roomIdx,const NLMISC::CEntityId & userId );
/// get an owner player
inline const NLMISC::CEntityId & getPlayer(uint idx);
/// get the index of a owner player
inline uint16 getOwnerIdx( const NLMISC::CEntityId & userId );
virtual void getClientDescription(uint16 roomIdx, uint16 ownerIndex, CCharacter * user, uint64 & icon, uint32 & textId )const;
virtual void onPlayerDeletion( const NLMISC::CEntityId & userId );

View file

@ -74,6 +74,25 @@ inline bool IBuildingPhysical::removeUser(const TDataSetRow & row)
return false;
}
//----------------------------------------------------------------------------
inline sint32 IBuildingPhysical::getRoomCell( uint16 roomIdx, uint16 ownerIdx )
{
/// simply get the cell matching the parameters
if ( roomIdx >= _Rooms.size() )
{
nlwarning("<BUILDING>Invalid room %u count is %u",roomIdx,_Rooms.size() );
return false;
}
if ( ownerIdx >= _Rooms[roomIdx].Cells.size() )
{
nlwarning("<BUILDING>Invalid owner idx %u count is %u",ownerIdx,_Rooms[roomIdx].Cells.size());
return false;
}
return _Rooms[roomIdx].Cells[ownerIdx];
}
/*****************************************************************************/
// CBuildingPhysicalCommon implementation
/*****************************************************************************/
@ -167,7 +186,7 @@ inline void CBuildingPhysicalPlayer::addPlayer( const NLMISC::CEntityId & userId
{
if ( std::find(_Players.begin(), _Players.end(), userId) != _Players.end() )
{
nlwarning("<BUILDING> trying to add player %s which is already present in the building", userId.toString().c_str());
//nlwarning("<BUILDING> trying to add player %s which is already present in the building", userId.toString().c_str());
return;
}
@ -181,6 +200,30 @@ inline void CBuildingPhysicalPlayer::addPlayer( const NLMISC::CEntityId & userId
}
}
//----------------------------------------------------------------------------
inline uint16 CBuildingPhysicalPlayer::getOwnerIdx( const NLMISC::CEntityId & userId )
{
for ( uint16 i = 0; i < _Players.size(); i++ )
{
if ( _Players[i] == userId )
{
return i;
}
}
_StateCounter++;
_Players.push_back( userId );
// add an instance cell to each room for this player
const uint size = (uint)_Rooms.size();
for ( uint i = 0; i < size; i++ )
{
_Rooms[i].Cells.push_back( 0 );
}
return (uint16)(_Players.size() - 1);
}
//----------------------------------------------------------------------------
inline void CBuildingPhysicalPlayer::resetRoomCell( uint16 roomIdx,const NLMISC::CEntityId & userId )
{

View file

@ -1574,7 +1574,7 @@ inline sint32 CCreature::applyDamageOnArmor( DMGTYPE::EDamageType dmgType, sint3
///\todo localisation for NPCS
if ( dmgType <0 || uint(dmgType) >= /*form->Protections.size()*/DMGTYPE::NBTYPES )
{
nlwarning( "<CCreature getProtection> invalid damage type %d in entity %s", (sint)dmgType, _Id.toString().c_str() );
//nlwarning( "<CCreature getProtection> invalid damage type %d in entity %s", (sint)dmgType, _Id.toString().c_str() );
return damage;
}
else
@ -1654,7 +1654,7 @@ CGameItemPtr CCreature::getNpcItem( const NLMISC::CSheetId &sheet, uint16 qualit
}
}
nlwarning("Failed to create NPC item %s with quality %d for entity %s (%s)", sheet.toString().c_str(), quality, _Id.toString().c_str(), getType().toString().c_str() );
//nlwarning("Failed to create NPC item %s with quality %d for entity %s (%s)", sheet.toString().c_str(), quality, _Id.toString().c_str(), getType().toString().c_str() );
return CGameItemPtr(NULL);
} // getNpcItem //
@ -1814,6 +1814,8 @@ void CCreature::tpWanted( sint32 x, sint32 y, sint32 z , bool useHeading , float
msgout2.serial( z );
msgout2.serial( heading );
msgout2.serial( tick );
msgout2.serial( continent );
msgout2.serial( cell );
sendMessageViaMirror("GPMS", msgout2);
}

View file

@ -3140,7 +3140,8 @@ void CBankAccessor_PLR::TPACK_ANIMAL::TBEAST::init(ICDBStructNode *parent, uint
nlassert(node != NULL);
_DESPAWN = node;
node = parent->getNode( ICDBStructNode::CTextId("NAME"), false );
// WARNING: let the value to true, else it'll corrupt backups
node = parent->getNode( ICDBStructNode::CTextId("NAME"), true );
nlassert(node != NULL);
_NAME = node;

View file

@ -95,7 +95,7 @@ TChanID CDynChatEGS::addChan(const std::string &name, const ucstring &title, boo
{
_DynChat.getChan(chan)->Localized = localized;
_DynChat.getChan(chan)->Title = title;
iosAddChan(chan, noBroadcast, forwardPlayerInputs, unify);
iosAddChan(chan, noBroadcast, forwardPlayerInputs, unify, name);
_ChanNames.add(chan, name);
return chan;
}
@ -108,7 +108,7 @@ TChanID CDynChatEGS::addChan(const std::string &name, const ucstring &title, boo
else if (_DynChat.addChan(_NextChanID, false, false, false))
{
TChanID result = _NextChanID;
iosAddChan(_NextChanID, noBroadcast, forwardPlayerInputs, unify);
iosAddChan(_NextChanID, noBroadcast, forwardPlayerInputs, unify, name);
_DynChat.getChan(_NextChanID)->Localized = localized;
_DynChat.getChan(_NextChanID)->Title = title;
_ChanNames.add(_NextChanID, name);
@ -465,13 +465,16 @@ void CDynChatEGS::onServiceDown(NLNET::TServiceId serviceId)
//============================================================================================================
void CDynChatEGS::iosAddChan(TChanID chan, bool noBroadcast, bool forwardPlayerInputs, bool unify)
void CDynChatEGS::iosAddChan(TChanID chan, bool noBroadcast, bool forwardPlayerInputs, bool unify, const std::string &name)
{
CMessage msg("DYN_CHAT:ADD_CHAN");
msg.serial(chan);
msg.serial(noBroadcast);
msg.serial(forwardPlayerInputs);
msg.serial(unify);
msg.serial(const_cast<std::string&>(name));
nlinfo("ask IOS to create channel: %s - name: '%s'", chan.toString().c_str(), name.c_str());
sendMessageViaMirror( "IOS", msg);
}
@ -542,12 +545,14 @@ void CDynChatEGS::iosResetDynChat()
//============================================================================================================
void CDynChatEGS::iosConnection()
{
nlwarning("IOS connected, add all chan we already have in memory");
iosResetDynChat();
CDynChat::TChanPtrVector chans;
_DynChat.getChans(chans);
for(uint k = 0; k < chans.size(); ++k)
{
iosAddChan(chans[k]->getID(), chans[k]->getDontBroadcastPlayerInputs(), chans[k]->getForwardPlayerIntputToOwnerService(), chans[k]->getUnifiedChannel());
iosAddChan(chans[k]->getID(), chans[k]->getDontBroadcastPlayerInputs(), chans[k]->getForwardPlayerIntputToOwnerService(), chans[k]->getUnifiedChannel(), getChanNameFromID(chans[k]->getID()));
// add each session in the channel
CDynChatSession *currSession = chans[k]->getFirstSession();
while (currSession)

View file

@ -123,7 +123,7 @@ private:
TChanTwinMap _ChanNames;
private:
// ios msg
void iosAddChan(TChanID chan, bool noBroadcast, bool forwardPlayerInputs, bool unify);
void iosAddChan(TChanID chan, bool noBroadcast, bool forwardPlayerInputs, bool unify, const std::string &name);
void iosSetHideBubble(TChanID chan, bool hideBubble);
void iosSetUniversalChannel(TChanID chan, bool universalChannel);
void iosRemoveChan(TChanID chan);

View file

@ -2233,9 +2233,11 @@ NLMISC_COMMAND(create_obj,"create a new object","<type>")
if( args.size() > 0 )
{
CWorldObjectLocation loc;
uint32 type;
uint16 quality = 0;
uint32 hp = 0;
WorldObjectManager.createObject(NLMISC::fromString(args[2].c_str()),loc,quality,hp);
NLMISC::fromString(args[0], type);
WorldObjectManager.createObject(type,loc,quality,hp);
return true;
}
return false;

View file

@ -500,6 +500,9 @@ public:
// Set entity mounted
void setEntityMounted( const TDataSetRow& entityRowId ) { _EntityMounted = entityRowId; }
// Set speed factor
inline void setSpeedVariationModifier( sint32 speed ) { _PhysScores.SpeedVariationModifier = speed; }
// get entity mounted
const TDataSetRow& getEntityMounted() const { return _EntityMounted(); }

View file

@ -3050,6 +3050,31 @@ void cbTeleportPlayer(NLNET::CMessage& msgin, const std::string &serviceName, NL
chr->teleportCharacter(x, y, z, true, true, t);
}
//---------------------------------------------------
// trigger the webig
//---------------------------------------------------
void cbTriggerWebig(NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId)
{
H_AUTO(cbTriggerWebig);
string event;
msgin.serial( event );
uint32 nbPlayers;
msgin.serial( nbPlayers );
nlinfo("ok %s %d", event.c_str(), nbPlayers);
for ( uint i=0; i<nbPlayers; ++i )
{
// Access the source
TDataSetRow player;
msgin.serial( player );
CEntityId playerId = TheDataset.getEntityId(player);
nlinfo("NPC: TRIGGER EVENT KILLED : %s", playerId.toString().c_str());
CCharacter *chr = PlayerManager.getChar(playerId);
if (!chr)
continue;
chr->sendUrl(event, "");
}
}
//---------------------------------------------------
/// Forage source position validation

View file

@ -213,6 +213,9 @@ void cbPlayerUnreachable( NLNET::CMessage& msgin, const std::string &serviceName
// AIS ask to teleport player via script
void cbTeleportPlayer(NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId);
// AIS ask to trigger webig
void cbTriggerWebig(NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId);
#endif //ENTITY_CALLBACKS_H

View file

@ -22,6 +22,8 @@
#include "stdpch.h"
//
#include "resists.h"
#include "player_manager/character.h"
#include "game_item_manager/game_item.h"
//////////////
// USING //

View file

@ -1205,6 +1205,7 @@ CGameItemPtr CGameItem::getItemCopy()
item->_SapLoad = _SapLoad;
item->_LostHPremains = 0.0f;
item->_PhraseId = _PhraseId;
item->_RequiredFaction = _RequiredFaction;
item->computeItemWornState();
log_Item_Create(item->getItemId(), item->getSheetId(), item->getStackSize(), item->quality());
@ -1372,9 +1373,12 @@ void CGameItem::clear()
_HasPrerequisit= false;
_LockedByOwner = false;
_Movable = false;
_UnMovable = false;
_TypeSkillMods.clear();
_PhraseId.clear();
_RequiredFaction.clear();
_CustomText.clear();
}
@ -4325,6 +4329,51 @@ void CGameItem::displayInLog( CLog &log )
}
} // displayInLog //
//-----------------------------------------------
// getStats
//-----------------------------------------------
bool CGameItem::getStats(const std::string &stats, std::string &final )
{
if (stats.size() % 2)
return false;
// cut hash in portion of 4
for (uint i=0; i<stats.size()/2; i++)
{
string part = stats.substr(i*2, 2);
if (part == "Sh")
final += NLMISC::toString("%s|", _SheetId.toString().c_str());
else if (part == "Qt")
final += NLMISC::toString("%u|", _StackSize);
else if (part == "Ql")
final += NLMISC::toString("%u|", quality());
else if (part == "Cl")
final += NLMISC::toString("%u|", (uint)getItemClass());
else if (part == "Se")
final += NLMISC::toString("%.1f|", getStatEnergy());
else if (part == "Hp")
final += NLMISC::toString("%u|", durability());
else if (part == "HP")
final += NLMISC::toString("%u|", maxDurability());
else if (part == "Sl")
final += NLMISC::toString("%u|", sapLoad());
else if (part == "SL")
final += NLMISC::toString("%u|", maxSapLoad());
else if (part == "Cr")
final += NLMISC::toString("%s|", getCreator().toString().c_str());
else if (part == "Fo")
final += NLMISC::toString("%s|", _Form->Name.c_str());
else if (part == "Ct")
final += NLMISC::toString("%s|", getCustomText().toString().c_str());
else if (part == "Bu")
final += NLMISC::toString("%u|", _Form->Bulk);
else if (part == "We")
final += NLMISC::toString("%u|", _Form->Weight);
else
return false;
}
return true;
} // getStats //
//-----------------------------------------------
// getClientEnchantValue

View file

@ -648,6 +648,7 @@ public :
* display item infos
*/
void displayInLog(NLMISC::CLog &log);
bool getStats(const std::string &stats, std::string &final );
/// accessors to the action latency end date
inline NLMISC::TGameCycle getLatencyEndDate(){ return _LatencyEndDate; }
@ -679,9 +680,20 @@ public :
/// set required skill level
inline void setRequiredSkillLevel2( uint16 l ) { _RequiredSkillLevel2 = l; }
bool getLockedByOwner() const { return _LockedByOwner; }
/// get Required Faction
inline const std::string & getRequiredFaction() const { return _RequiredFaction;}
/// set Required Faction
inline void setRequiredFaction(const std::string & str){ _RequiredFaction = str;}
inline bool getLockedByOwner() const { return _LockedByOwner; }
void setLockedByOwner(bool value);
inline bool getMovable() const { return _Movable; }
inline void setMovable(bool value) { _Movable = value; }
inline bool getUnMovable() const { return _UnMovable; }
inline void setUnMovable(bool value) { _UnMovable = value; }
/// get required stat
inline CHARACTERISTICS::TCharacteristics getRequiredCharac() const { return _RequiredCharac; }
/// set required stat
@ -945,6 +957,7 @@ private:
// required skill
bool _UseNewSystemRequirement;
std::string _RequiredFaction;
SKILLS::ESkills _RequiredSkill;
uint16 _RequiredSkillLevel;
SKILLS::ESkills _RequiredSkill2;
@ -958,6 +971,8 @@ private:
ucstring _CustomText;
bool _LockedByOwner;
bool _UnMovable;
bool _Movable;
uint8 _PetIndex;
ucstring _CustomName;
};

View file

@ -81,7 +81,7 @@ bool CExchangeView::putItemInExchange(uint32 bagSlot, uint32 exchangeSlot, uint3
// if it is an exchange between 2 players
// do not permit exchange of non dropable items, but pet animal ticket are NoDrop item but must ne exchangeable
if (_InterlocutorView != NULL && (!form->DropOrSell && form->Family != ITEMFAMILY::PET_ANIMAL_TICKET))
if (!item->getMovable() && _InterlocutorView != NULL && form->Family != ITEMFAMILY::PET_ANIMAL_TICKET && (!form->DropOrSell || item->getUnMovable()))
return false;
// Can't trade items locked by owner

View file

@ -186,7 +186,7 @@ CInventoryBase::TInventoryOpResult CInventoryBase::doInsertItem(CGameItemPtr &it
vector< pair<uint32,uint32> > Modifs;
// If slot provided is NULL directly insert item in it
if (_Items[slotBegin] == NULL)
if (_Items[slotBegin] == NULL && slot != INVENTORIES::INSERT_IN_FIRST_FREE_SLOT)
{
Modifs.push_back(make_pair(slotBegin, itemStackSize));
}

View file

@ -955,9 +955,11 @@ void CGuild::putItem( CCharacter * user, uint32 slot, uint32 quantity, uint16 se
// check if this type of item is legal in the guild inventory
CGameItemPtr item = srcItem;
if ( !item->getStaticForm()->DropOrSell
if (!item->getMovable() && (
!item->getStaticForm()->DropOrSell
|| item->getStaticForm()->Family == ITEMFAMILY::PET_ANIMAL_TICKET
|| user->isAnActiveXpCatalyser(item)
|| item->getUnMovable() )
)
{
CCharacter::sendDynamicSystemMessage( user->getId(),"GUILD_ITEM_CANT_BE_PUT" );

View file

@ -66,6 +66,12 @@ CModuleParent & CGuildCharProxy::getModuleParent()
return _ModuleCore->getModuleParent();
}
//----------------------------------------------------------------------------
void CGuildCharProxy::sendSystemMessage( const std::string & msg)
{
CCharacter::sendDynamicSystemMessage(_ModuleCore->getEntityRowId(), msg);
}
//----------------------------------------------------------------------------
void CGuildCharProxy::sendSystemMessage( const std::string & msg, const TVectorParamCheck & params)
{

View file

@ -574,7 +574,13 @@ void CMissionManager::checkVisitPlaceMissions()
BOMB_IF( ! missionTemplate, NLMISC::toString( "Invalid VisitPlace template %s", CPrimitivesParser::getInstance().aliasToString( stepId.MissionAlias ).c_str() ).c_str(), ++its; continue );
const IMissionStepTemplate *step = missionTemplate->getStep( stepId.StepIndex );
const CMission *missionInstance = character->getMission( stepId.MissionAlias );
BOMB_IF( ! (step && missionInstance), NLMISC::toString( "Invalid Visit Place step or mission %s", CPrimitivesParser::getInstance().aliasToString( stepId.MissionAlias ).c_str() ).c_str(), ++its; continue );
// OLD: BOMB_IF( ! (step && missionInstance), NLMISC::toString( "Invalid Visit Place step or mission %s", CPrimitivesParser::getInstance().aliasToString( stepId.MissionAlias ).c_str() ).c_str(), ++its; continue );
if (! (step && missionInstance))
{
++its;
continue;
}
// Test if the iterated "visit place" steps match the current places with contraints
bool placeProcessed = false;

View file

@ -172,8 +172,27 @@ class CMissionStepTalk : public IMissionStepTemplate
return 0;
}
_User = PlayerManager.getChar(getEntityIdFromRow(user));
uint32 userId = PlayerManager.getPlayerId(_User->getId());
string text = _PhraseId;
if (_User)
{
uint32 userId = PlayerManager.getPlayerId(_User->getId());
text = _User->getCustomMissionText(_PhraseId);
if (text.empty())
return 0;
}
TVectorParamCheck params;
ucstring phrase = ucstring(_PhraseId+"(){["+text+"]}");
NLNET::CMessage msgout("SET_PHRASE");
msgout.serial(_PhraseId);
msgout.serial(phrase);
sendMessageViaMirror("IOS", msgout);
return STRING_MANAGER::sendStringToClient( user, _PhraseId, params );
/* SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal);
params[0].Literal= text;*/
}
CCreature * bot = CreatureManager.getCreature( interlocutor );

View file

@ -104,6 +104,27 @@ uint32 IMissionStepTemplate::sendRpStepText(CCharacter * user,const std::vector<
_User = user;
if (_RoleplayText.substr(0, 6) == "WEBIG_")
{
TVectorParamCheck params;
string name = _RoleplayText;
if (user)
{
uint32 userId = PlayerManager.getPlayerId(user->getId());
string text = user->getCustomMissionText(_RoleplayText);
if (text.empty())
return 0;
name = _RoleplayText+"_"+toString(userId);
ucstring phrase = ucstring(name+"(){["+text+"]}");
NLNET::CMessage msgout("SET_PHRASE");
msgout.serial(name);
msgout.serial(phrase);
sendMessageViaMirror("IOS", msgout);
}
return STRING_MANAGER::sendStringToClient( user->getEntityRowId(), name, params );
}
else
{
if ( !_RoleplayText.empty() )
{
// build the param list
@ -134,7 +155,7 @@ uint32 IMissionStepTemplate::sendRpStepText(CCharacter * user,const std::vector<
}
else
return STRING_MANAGER::sendStringToClient( user->getEntityRowId(),*textPtr,params);
}
}// IMissionStepTemplate::sendRpStepText
@ -152,6 +173,22 @@ uint32 IMissionStepTemplate::sendStepText(CCharacter * user,const std::vector<ui
// If the text is overriden, add the overide parameters
if ( !_OverridenText.empty() )
{
if (_OverridenText.substr(0, 6) == "WEBIG_")
{
string text = _OverridenText;
if (user)
{
uint32 userId = PlayerManager.getPlayerId(user->getId());
text = user->getCustomMissionText(_OverridenText);
if (text.empty())
text = _OverridenText;
}
SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal);
params[0].Literal.fromUtf8(text);
return STRING_MANAGER::sendStringToClient( user->getEntityRowId(), "LITERAL", params );
}
else
{
if ( _AddDefaultParams )
{
@ -171,6 +208,7 @@ uint32 IMissionStepTemplate::sendStepText(CCharacter * user,const std::vector<ui
textPtr = &_OverridenText;
}
}
}
if( !textPtr )
return 0;

View file

@ -2085,15 +2085,6 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
if (!fillPrereqInfos)
return MISSION_DESC::PreReqFail;
/*if (addedPrereqTexts.find("GUILD_BUILDING_BAD_GRADE") == addedPrereqTexts.end())
{
prereqDesc.Description = STRING_MANAGER::sendStringToClient(user->getEntityRowId(), "GUILD_BUILDING_BAD_GRADE", TVectorParamCheck());
prereqDesc.IsMandatory = true;
prereqDesc.Validated = false;
prereqInfos.Prerequisits.push_back(prereqDesc);
addedPrereqTexts.insert("GUILD_BUILDING_BAD_GRADE");
}*/
returnValue = MISSION_DESC::PreReqFail;
logOnFail = false;
}
@ -2449,6 +2440,23 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
uint32 CMissionTemplate::sendTitleText( const TDataSetRow & userRow, const TDataSetRow & giver ) const
{
if (TitleText.substr(0, 6) == "WEBIG_")
{
string text = TitleText;
CCharacter *user = PlayerManager.getChar(getEntityIdFromRow(userRow));
if (user)
{
uint32 userId = PlayerManager.getPlayerId(user->getId());
text = user->getCustomMissionText(TitleText);
if (text.empty())
text = "<Undefined>";
}
SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal);
params[0].Literal.fromUtf8(text);
return STRING_MANAGER::sendStringToClient( userRow, "LITERAL", params );
}
else
{
TVectorParamCheck params(1 + TitleParams.size() );
std::copy( TitleParams.begin(),TitleParams.end(), params.begin() + 1 );
@ -2456,16 +2464,52 @@ uint32 CMissionTemplate::sendTitleText( const TDataSetRow & userRow, const TData
params[0].setEIdAIAlias( getEntityIdFromRow( giver ), CAIAliasTranslator::getInstance()->getAIAlias(getEntityIdFromRow( giver )) );
CMissionParser::solveEntitiesNames(params,userRow,params[0].getEId());
return STRING_MANAGER::sendStringToClient( userRow, TitleText,params );
}
}// CMissionTemplate sendTitleText
uint32 CMissionTemplate::sendAutoText( const TDataSetRow & userRow,const NLMISC::CEntityId & giver) const
{
if (AutoText.substr(0, 6) == "WEBIG_")
{
string text = AutoText;
CCharacter *user = PlayerManager.getChar(getEntityIdFromRow(userRow));
if (user)
{
uint32 userId = PlayerManager.getPlayerId(user->getId());
text = user->getCustomMissionText(AutoText);
if (text.empty())
return 0;
}
SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal);
params[0].Literal.fromUtf8(text);
return STRING_MANAGER::sendStringToClient( userRow, "LITERAL", params );
}
else
{
TVectorParamCheck params = AutoParams;
CMissionParser::solveEntitiesNames(params,userRow,giver);
return STRING_MANAGER::sendStringToClient( userRow, AutoText,params );
}
}// CMissionTemplate::sendAutoText
uint32 CMissionTemplate::sendDescText( const TDataSetRow & userRow, const TDataSetRow & giver, uint32 descIndex) const
{
if (DescText.substr(0, 6) == "WEBIG_")
{
string text = DescText;
CCharacter *user = PlayerManager.getChar(getEntityIdFromRow(userRow));
if (user)
{
uint32 userId = PlayerManager.getPlayerId(user->getId());
text = user->getCustomMissionText(DescText);
if (text.empty())
text = "<Undefined>";
}
SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal);
params[0].Literal.fromUtf8(text);
return STRING_MANAGER::sendStringToClient( userRow, "LITERAL", params );
}
else
{
CEntityId id = getEntityIdFromRow( giver );
@ -2499,6 +2543,7 @@ uint32 CMissionTemplate::sendDescText( const TDataSetRow & userRow, const TDataS
CMissionParser::solveEntitiesNames(params,userRow,id);
return STRING_MANAGER::sendStringToClient( userRow,*txt,params );
}
}// CMissionTemplate sendDetailsText
/*

View file

@ -1510,7 +1510,7 @@ PVP_RELATION::TPVPRelation COutpost::getPVPRelation( CCharacter * user, CEntityB
}
}
return PVP_RELATION::NeutralPVP;
return PVP_RELATION::Neutral;
} // getPVPRelation //

View file

@ -1136,10 +1136,25 @@ bool CCombatPhrase::validate()
if(_MeleeCombat)
{
// check combat float mode
uint32 range;
if (!combatDefender || !combatDefender->getEntity())
return false;
CCharacter *character = PlayerManager.getChar(_Attacker->getEntityRowId());
if (character && !character->meleeCombatIsValid())
CCharacter *cdefender = PlayerManager.getChar(defender->getEntityRowId());
if ( defender->getId().getType() == RYZOMID::player )
{
if (!_TargetTooFarMsg)
if (character && character->hasMoved() && cdefender && cdefender->hasMoved())
range = 10000;
else
range = 3000;
}
else
range = 6000;
if ((character && !character->meleeCombatIsValid()) || ! PHRASE_UTILITIES::testRange(*actingEntity, *defender, range ))
{
if (!_TargetTooFarMsg && (character && !character->meleeCombatIsValid()))
{
PHRASE_UTILITIES::sendSimpleMessage( _Attacker->getEntityRowId(), "BS_TARGET_TOO_FAR_OR");
_TargetTooFarMsg = true;
@ -1488,11 +1503,26 @@ bool CCombatPhrase::update()
if (_MeleeCombat )
{
debugStep = 18;
if (!combatDefender || !combatDefender->getEntity())
return false;
uint32 range;
CCharacter *character = dynamic_cast<CCharacter *> (actor);
if (character && !character->meleeCombatIsValid())
CCharacter *defender = dynamic_cast<CCharacter *> (combatDefender->getEntity());
if ( combatDefender->getEntity()->getId().getType() == RYZOMID::player )
{
if (character && character->hasMoved() && defender && defender->hasMoved() )
range = 10000;
else
range = 3000;
}
else
range = 6000;
if ((character && !character->meleeCombatIsValid()) || !PHRASE_UTILITIES::testRange(*actor, *combatDefender->getEntity(), range))
{
debugStep = 19;
if (!_TargetTooFarMsg && !_Idle)
if (!_TargetTooFarMsg && !_Idle && (character && !character->meleeCombatIsValid()))
{
PHRASE_UTILITIES::sendSimpleMessage( actor->getId(), "BS_TARGET_TOO_FAR_OR");
_TargetTooFarMsg = true;

View file

@ -119,6 +119,11 @@ public:
}
float successFactor = rollSuccessFactor( c, phrase, deltaLvl );
ITEMFAMILY::EItemFamily family = phrase->getCraftedItemStaticForm()->Family;
if( family==ITEMFAMILY::CRAFTING_TOOL || family==ITEMFAMILY::HARVEST_TOOL )
successFactor = 1.0f;
if( successFactor == 0.0f )
{
//Failure
@ -281,7 +286,7 @@ public:
}
else
{
c->wearRightHandItem(phrase->getMps().size()/10);
c->wearRightHandItem((double)phrase->getMps().size()/10);
// report Xp Gain unless used tool is worned
PROGRESSIONPVE::CCharacterProgressionPVE::getInstance()->actionReport( report, true, false );

View file

@ -150,6 +150,10 @@ bool CSLinkEffect::update(CTimerEvent * event, bool)
CCharacter *player = dynamic_cast<CCharacter *> (caster);
if (player)
{
if (player->isDead())
{
endEffect = true;
}
_Focus.init(player->getRightHandItem());
}
}

View file

@ -146,6 +146,7 @@
#include "modules/client_command_forwarder.h"
#include "server_share/log_character_gen.h"
#include "server_share/log_item_gen.h"
#include "server_share/mongo_wrapper.h"
///////////
// USING //
@ -670,6 +671,8 @@ CCharacter::CCharacter(): CEntityBase(false),
_LastTickNpcControlUpdated = CTickEventHandler::getGameCycle();
_LastWebCommandIndex = 0;
_LastUrlIndex = 0;
_CustomMissionsParams.clear();
@ -1533,6 +1536,9 @@ uint32 CCharacter::tickUpdate()
nextUpdate = 8;
}
_SavedPosX = _EntityState.X();
_SavedPosY = _EntityState.Y();
return nextUpdate;
} // tickUpdate //
@ -2401,6 +2407,17 @@ void CCharacter::applyRegenAndClipCurrentValue()
// restore value without weight malus
_PhysScores.SpeedVariationModifier -= _LastAppliedWeightMalus;
// adapt speed of mount without weight malus
if( TheDataset.isAccessible(_EntityMounted()) )
{
TDataSetRow creatureId = _EntityMounted;
CCreature *creature = CreatureManager.getCreature(creatureId);
if (creature)
{
creature->setSpeedVariationModifier(_PhysScores.SpeedVariationModifier);
}
}
// compute new value
_LastAppliedWeightMalus = getWeightMalus();
_PhysScores.SpeedVariationModifier += _LastAppliedWeightMalus;
@ -3705,7 +3722,28 @@ void CCharacter::setTargetBotchatProgramm( CEntityBase * target, const CEntityId
// send the web page url
SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal);
params[0].Literal= c->getWebPage();
string url = c->getWebPage();
// add ? or & with
if ( url.find('?') == string::npos )
url += NLMISC::toString("?urlidx=%d", getUrlIndex());
else
url += NLMISC::toString("&urlidx=%d", getUrlIndex());
setUrlIndex(getUrlIndex()+1);
url += "&player_eid="+getId().toString();
// add cheksum : pnj eid
url += "&teid="+c->getId().toString();
string defaultSalt = toString(getLastConnectedDate());
nlinfo(defaultSalt.c_str());
nlinfo(url.c_str());
string control = "&hmac="+getHMacSHA1((uint8*)&url[0], (uint32)url.size(), (uint8*)&defaultSalt[0], (uint32)defaultSalt.size()).toString();
params[0].Literal= url+control;
text = STRING_MANAGER::sendStringToClient(_EntityRowId, "LITERAL", params );
// _PropertyDatabase.setProp( "TARGET:CONTEXT_MENU:WEB_PAGE_URL" , text );
CBankAccessor_PLR::getTARGET().getCONTEXT_MENU().setWEB_PAGE_URL(_PropertyDatabase, text );
@ -3856,6 +3894,12 @@ void CCharacter::sendBetaTesterStatus()
sendReservedTitleStatus( CHARACTER_TITLE::FBT, p->isBetaTester() );
/*if (!p->isBetaTester() && _Title == CHARACTER_TITLE::FBT)
{
_Title = CHARACTER_TITLE::Refugee;
registerName();
}*/
if (!p->isBetaTester() && _NewTitle == "FBT")
{
_NewTitle = "Refugee";
@ -3874,6 +3918,12 @@ void CCharacter::sendWindermeerStatus()
sendReservedTitleStatus( CHARACTER_TITLE::WIND, p->isWindermeerCommunity() );
/*if ( !p->isWindermeerCommunity() && _Title == CHARACTER_TITLE::WIND)
{
_Title = CHARACTER_TITLE::Refugee;
registerName();
}*/
if ( !p->isWindermeerCommunity() && _NewTitle == "WIND")
{
_NewTitle = "Refugee";
@ -4342,6 +4392,37 @@ void CCharacter::addKnownBrick( const CSheetId& brickId )
}
} //addKnownBrick//
//-----------------------------------------------
// CCharacter::addKnownBrickBonus add a know brick bonus
//-----------------------------------------------
void CCharacter::addKnownBrickBonus( const CSheetId& brickId )
{
// egs_chinfo("<CCharacter::addKnownBrickBonus> adding new known brick idSheet (%s)", brickId.toString().c_str() );
const CStaticBrick* brickForm = CSheets::getSBrickForm( brickId );
if( brickForm )
{
// if the brick is a training brick, then apply charac increase
if ( BRICK_FAMILIES::brickType(brickForm->Family) == BRICK_TYPE::TRAINING)
{
processTrainingBrick(brickForm);
}
// if the brick is a bonus that needs to be taken into account now, do it
switch ( brickForm->Family )
{
case BRICK_FAMILIES::BPBHFEA:
processForageBonusBrick(brickForm);
break;
case BRICK_FAMILIES::BPBGLA:
processMiscBonusBrick(brickForm);
break;
default:;
}
}
} //addKnownBrickBonus//
//-----------------------------------------------
// CCharacter::removeKnownBrick remove a known brick
//-----------------------------------------------
@ -4420,6 +4501,37 @@ void CCharacter::removeKnownBrick( const CSheetId& brickId )
}
} //removeKnownBrick//
//-----------------------------------------------
// CCharacter::removeKnownBrickBonus remove a known brick bonus
//-----------------------------------------------
void CCharacter::removeKnownBrickBonus( const CSheetId& brickId )
{
// egs_chinfo("<CCharacter::removeKnownBrickBonus> removing a known brick idSheet (%s)", brickId.toString().c_str() );
const CStaticBrick* brickForm = CSheets::getSBrickForm( brickId );
if( brickForm )
{
// if the brick is a training brick, then apply charac increase
if ( BRICK_FAMILIES::brickType(brickForm->Family) == BRICK_TYPE::TRAINING)
{
unprocessTrainingBrick(brickForm, true);
}
// if the brick is a bonus that needs to be taken into account now, do it
switch ( brickForm->Family )
{
case BRICK_FAMILIES::BPBHFEA:
unprocessForageBonusBrick(brickForm);
break;
case BRICK_FAMILIES::BPBGLA:
unprocessMiscBonusBrick(brickForm);
break;
default:;
}
}
} //removeKnownBrickBonus//
//-----------------------------------------------
// CCharacter::processTrainingBrick
//-----------------------------------------------
@ -9896,7 +10008,7 @@ void CCharacter::sellItem( INVENTORIES::TInventory inv, uint32 slot, uint32 quan
nlwarning("<CCharacter sellItem> character %s Invalid item sheet %s : the sheet is invalid",_Id.toString().c_str(),sheet.toString().c_str());
return;
}
if ( !itemForm->DropOrSell )
if ( !item->getMovable() && ( !itemForm->DropOrSell || item->getUnMovable() ) )
{
nlwarning("<CCharacter sellItem> character %s try to sell item slot %u sheet %s",
_Id.toString().c_str(),
@ -10924,6 +11036,47 @@ void CCharacter::acceptExchange(uint8 exchangeId)
c->removeExchangeItems(items2, exchangePlayerPets2);
}
if (haveAnyPrivilege() && !c->haveAnyPrivilege())
{
for (uint i = 0; i < items1.size(); ++i)
{
nlinfo ("ADMIN: CSR (%s,%s) exchange %ux%s Q%u with %s",
getId().toString().c_str(),
getName().toString().c_str(),
items1[i]->getStackSize(),
items1[i]->getSheetId().toString().c_str(),
items1[i]->quality(),
c->getName().toString().c_str());
}
if (_ExchangeMoney)
nlinfo ("ADMIN: CSR (%s,%s) give %u dappers to %s",
getId().toString().c_str(),
getName().toString().c_str(),
_ExchangeMoney,
c->getName().toString().c_str());
}
if (c->haveAnyPrivilege() && !haveAnyPrivilege())
{
for (uint i = 0; i < items2.size(); ++i)
{
nlinfo ("ADMIN: CSR (%s,%s) exchange %ux%s Q%u with %s",
c->getId().toString().c_str(),
c->getName().toString().c_str(),
items2[i]->getStackSize(),
items2[i]->getSheetId().toString().c_str(),
items2[i]->quality(),
getName().toString().c_str());
}
if (c->_ExchangeMoney)
nlinfo ("ADMIN: CSR (%s,%s) give %u dappers to %s",
c->getId().toString().c_str(),
c->getName().toString().c_str(),
c->_ExchangeMoney,
getName().toString().c_str());
}
// do the exchange
{
TLogContext_Item_Swap logContext(_Id);
@ -11539,6 +11692,7 @@ void CCharacter::cancelStaticActionInProgress(STATIC_ACT_TYPES::TStaticActTypes
{
setAfkState( false );
// changed : always stop links (so one can only have one link at a time... as casting a new one will cancel the previous one)
if (!isDead())
stopAllLinks();
CPhraseManager::getInstance().cancelTopPhrase(_EntityRowId, true);
@ -13130,6 +13284,66 @@ void CCharacter::setPlaces(const std::vector<const CPlace*> & places)
}
}
//-----------------------------------------------
// isSpawnValid
//-----------------------------------------------
bool CCharacter::isSpawnValid(bool inVillage, bool inOutpost, bool inStable, bool inAtys)
{
if (inVillage)
nlinfo("inVillage");
if (inOutpost)
nlinfo("inOutpost");
if (inStable)
nlinfo("inStable");
if (inAtys)
nlinfo("inAtys");
const uint size = (uint)_Places.size();
for ( uint i = 0; i < size; i++ )
{
CPlace * p = CZoneManager::getInstance().getPlaceFromId( _Places[i] );
if (p)
{
PLACE_TYPE::TPlaceType place_type = p->getPlaceType();
nlinfo("Place type = %s", PLACE_TYPE::toString(p->getPlaceType()).c_str());
if (!inVillage && (place_type == PLACE_TYPE::Village || place_type == PLACE_TYPE::Capital))
{
CCharacter::sendDynamicSystemMessage( _EntityRowId, "NO_ACTION_IN_VILLAGE" );
return false;
}
TAIAlias outpostAlias = getOutpostAlias();
if (!inOutpost && outpostAlias != 0)
{
CSmartPtr<COutpost> outpost = COutpostManager::getInstance().getOutpostFromAlias( outpostAlias );
if( outpost && outpost->getState() != OUTPOSTENUMS::Peace )
{
CCharacter::sendDynamicSystemMessage( _EntityRowId, "NO_ACTION_IN_OUPOST" );
return false;
}
}
if( !inStable && _CurrentStable != 0xFFFF )
{
CCharacter::sendDynamicSystemMessage( _EntityRowId, "NO_ACTION_IN_STABLE" );
return false;
}
TDataSetRow dsr = getEntityRowId();
CMirrorPropValueRO<TYPE_CELL> srcCell( TheDataset, dsr, DSPropertyCELL );
sint32 cell = srcCell;
if (!inAtys && cell >= 0)
{
CCharacter::sendDynamicSystemMessage( _EntityRowId, "NO_ACTION_IN_ATYS" );
return false;
}
}
}
return true;
}
//-----------------------------------------------
// memorize
//-----------------------------------------------
@ -13658,6 +13872,21 @@ uint16 CCharacter::getFirstFreeSlotInKnownPhrase()
} // getFirstFreeSlotInKnownPhrase //
void CCharacter::sendDynamicMessage(const string &phrase, const string &message)
{
TVectorParamCheck messageParams;
ucstring phraseText;
string phraseName = phrase;
phraseText.fromUtf8(message);
ucstring phraseContent = phrase+"(){["+phraseText+"]}";
NLNET::CMessage msgout("SET_PHRASE");
msgout.serial(phraseName);
msgout.serial(phraseContent);
sendMessageViaMirror("IOS", msgout);
PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, phrase, messageParams );
}
void CCharacter::sendUrl(const string &url, const string &salt)
{
string control;
@ -13672,18 +13901,15 @@ void CCharacter::sendUrl(const string &url, const string &salt)
}
nlinfo(url.c_str());
TVectorParamCheck titleParams;
TVectorParamCheck textParams;
uint32 userId = PlayerManager.getPlayerId(getId());
std::string name = "CUSTOM_URL_"+toString(userId);
ucstring phrase = ucstring(name+"(){[WEB : "+url+control+"]}");
NLNET::CMessage msgout("SET_PHRASE");
msgout.serial(name);
msgout.serial(phrase);
sendMessageViaMirror("IOS", msgout);
uint32 userId = PlayerManager.getPlayerId(getId());
SM_STATIC_PARAMS_1(textParams, STRING_MANAGER::literal);
textParams[0].Literal= "WEB : "+url+control;
TVectorParamCheck titleParams;
uint32 titleId = STRING_MANAGER::sendStringToUser(userId, "web_transactions", titleParams);
uint32 textId = STRING_MANAGER::sendStringToUser(userId, name, textParams);
uint32 textId = STRING_MANAGER::sendStringToClient(_EntityRowId, "LITERAL", textParams );
PlayerManager.sendImpulseToClient(getId(), "USER:POPUP", titleId, textId);
}
@ -13695,6 +13921,9 @@ void CCharacter::validateDynamicMissionStep(const string &url)
/// set custom mission param
void CCharacter::setCustomMissionParams(const string &missionName, const string &params)
{
if (params.empty())
_CustomMissionsParams.erase(missionName);
else
_CustomMissionsParams[missionName] = params;
}
@ -13724,6 +13953,21 @@ vector<string> CCharacter::getCustomMissionParams(const string &missionName)
return params;
}
/// get custom mission text
string CCharacter::getCustomMissionText(const string &missionName)
{
if (_CustomMissionsParams.empty())
{
return "";
}
if (!_CustomMissionsParams.empty() && _CustomMissionsParams.find(missionName) != _CustomMissionsParams.end())
{
return _CustomMissionsParams[missionName];
}
return "";
}
// !!! Deprecated !!!
void CCharacter::addWebCommandCheck(const string &url, const string &data, const string &salt)
@ -14063,6 +14307,49 @@ bool CCharacter::pickUpRawMaterial( uint32 indexInTempInv, bool * lastMaterial )
return false; // don't try to quarter an item for looting
}
// Send url for Arcc triggers
vector<string> params = getCustomMissionParams("__LOOT_SHEET__");
if (params.size() >= 2)
{
// check if it's the creature have good sheet
CSheetId creatureSheetId(params[1]);
if (creatureSheetId != CSheetId::Unknown && creatureSheetId == creature->getType())
{
validateDynamicMissionStep(params[0]);
setCustomMissionParams("__LOOT_SHEET__", "");
}
}
// only check first item
if (indexInTempInv == 0)
{
params = getCustomMissionParams("__LOOT_SHEET_WITH_ITEM__");
if (params.size() >= 3)
{
// check if it's the creature have good sheet
CSheetId creatureSheetId(params[1]);
if (creatureSheetId != CSheetId::Unknown && creatureSheetId == creature->getType())
{
// check if player have item in right hand
CGameItemPtr rightHandItem = getRightHandItem();
CSheetId needItem(params[2]);
if (rightHandItem != NULL && rightHandItem->getSheetId() == needItem)
{
validateDynamicMissionStep(params[0]);
setCustomMissionParams("__LOOT_SHEET_WITH_ITEM__", "");
if (params.size() >= 4)
setCustomMissionParams(params[3], "");
}
else if (params.size() >= 4)
{
string message = getCustomMissionText(params[3]);
if (!message.empty())
sendDynamicMessage(params[3], message);
}
}
}
}
// first slots are filled with loot items, quarter items are not in temp inv but only info in DB
uint32 rawMaterialIndex = indexInTempInv - creature->getLootSlotCount();
const CCreatureRawMaterial * mp = creature->getCreatureRawMaterial( rawMaterialIndex );
@ -14285,6 +14572,13 @@ void CCharacter::resetFameDatabase()
{
CFameInterface &fi = CFameInterface::getInstance();
// Check fames and fix bad values
if (!haveAnyPrivilege())
{
CFameManager::getInstance().enforceFameCaps(getId(), getAllegiance());
CFameManager::getInstance().setAndEnforceTribeFameCap(getId(), getAllegiance());
}
for (uint i=0; i<CStaticFames::getInstance().getNbFame(); ++i)
{
// update player fame info
@ -14762,6 +15056,18 @@ TCharConnectionState CCharacter::isFriendCharVisualyOnline(const NLMISC::CEntity
return ccs_offline;
}
if ( PlayerManager.hasBetterCSRGrade(_Id, friendId, true))
{
// better CSR grade return always 'online' status
return ccs_online;
}
if (haveAnyPrivilege())
{
// this character has some privs, so just show status.
return ccs_online;
}
ret = ccs_online;
}
@ -17953,6 +18259,8 @@ void CCharacter::setOutpostAlias( uint32 id )
if( _OutpostAlias != 0 )
{
sendDynamicSystemMessage( _Id, "OUTPOST_NO_MORE_IN_CONFLICT");
if (getCurrentPVPZone() != CAIAliasTranslator::Invalid)
CPVPManager::getInstance()->enterPVPZone( this, getCurrentPVPZone() );
}
// _PropertyDatabase.setProp("CHARACTER_INFO:PVP_OUTPOST:ROUND_LVL_CUR", 0 );
CBankAccessor_PLR::getCHARACTER_INFO().getPVP_OUTPOST().setROUND_LVL_CUR(_PropertyDatabase, 0 );
@ -19063,6 +19371,10 @@ bool CCharacter::setGuildId( uint32 guildId )
_GuildId = guildId;
#ifdef HAVE_MONGO
CMongo::update("users", toString("{'game.cid':%"NL_I64"u}", _Id.getShortId()), toString("{$set:{'game.guildId':%d}}", guildId));
#endif
return true;
}

View file

@ -637,6 +637,12 @@ public:
*/
void setEnterFlag( bool b );
/**
* Get/Set the score permanent modifier
*/
uint32 getScorePermanentModifiers(SCORES::TScores score) const;
void setScorePermanentModifiers(SCORES::TScores score, uint32 value);
/**
* Get the enter flag
* \return true if the player entered the game, false if he left
@ -719,12 +725,18 @@ public:
/// add a known brick
void addKnownBrick( const NLMISC::CSheetId& brickId);
/// add a known brick bonus
void addKnownBrickBonus( const NLMISC::CSheetId& brickId);
/// check if have brick
bool haveBrick( const NLMISC::CSheetId& brickId );
/// remove a known brick
void removeKnownBrick( const NLMISC::CSheetId& brickId );
/// remove a known brick
void removeKnownBrickBonus( const NLMISC::CSheetId& brickId );
/// get known bricks
const std::set<NLMISC::CSheetId> &getKnownBricks() const;
@ -1542,6 +1554,9 @@ public:
/// client (in)validate melee combat
void validateMeleeCombat(bool flag);
/// check is player can spawn npc group in here position
bool isSpawnValid(bool inVillage, bool inOutpost, bool inStable, bool inAtys);
/// memorize a phrase
void memorize(uint8 memorizationSet, uint8 index, uint16 phraseId, const std::vector<NLMISC::CSheetId> &bricks);
@ -1660,6 +1675,9 @@ public:
/// get ammo item
virtual CGameItemPtr getAmmoItem() const;
/// send dynamic message
void sendDynamicMessage(const std::string &phrase, const std::string &message);
/// send custom url
void sendUrl(const std::string &url, const std::string &salt);
@ -1672,6 +1690,9 @@ public:
/// get custom mission params
std::vector<std::string> getCustomMissionParams(const std::string &missionName);
/// get custom mission texts
std::string getCustomMissionText(const std::string &missionName);
/// validate dynamic mission step sending url
void validateDynamicMissionStep(const std::string &url);
@ -3174,6 +3195,11 @@ private:
/// old pos Y
mutable sint32 _OldPosY;
/// old pos X
mutable sint32 _SavedPosX;
/// old pos Y
mutable sint32 _SavedPosY;
/// last X position written in DB
sint32 _LastPosXInDB;
/// last Y position written in DB
@ -3316,6 +3342,9 @@ private:
/// last webcommand index
uint32 _LastWebCommandIndex;
/// last web url index
uint32 _LastUrlIndex;
std::map<std::string, std::string> _CustomMissionsParams;
// for a power/combat event, stores start and end ticks
@ -3716,6 +3745,9 @@ private:
/// keep the Ids of the mission queues in which is this player
std::vector<uint32> _MissionsQueues;
/// keep the validated web commandes
std::set<uint32> _ValideWebCommandIndex;
/// keep here the queue for which this player currently has an enter critical zone proposal
uint32 _EnterCriticalZoneProposalQueueId;
@ -3748,7 +3780,7 @@ private:
public:
uint32 getLastDisconnectionDate();
bool hasMoved();
private:
TAIAlias _SelectedOutpost;
@ -3782,6 +3814,11 @@ public:
void setWebCommandIndex(uint32 index) { _LastWebCommandIndex = index;}
uint32 getWebCommandIndex() const { return _LastWebCommandIndex;}
void validateWebCommandIndex(uint32 index) { _ValideWebCommandIndex.insert(index);}
uint32 isValidWebCommandIndex(uint32 index) { return _ValideWebCommandIndex.find(index) != _ValideWebCommandIndex.end();}
void setUrlIndex(uint32 index) { _LastUrlIndex = index;}
uint32 getUrlIndex() const { return _LastUrlIndex;}
bool getInvisibility() const { return _Invisibility;}
/// Set the invisibility flag, NB : just for persistence, do not change nothing.

View file

@ -63,6 +63,16 @@ inline CHARACTER_TITLE::ECharacterTitle CCharacter::getTitle() const
//------------------------------------------------------------------------------
inline uint32 CCharacter::getScorePermanentModifiers(SCORES::TScores score) const
{
return _ScorePermanentModifiers[score];
}
inline void CCharacter::setScorePermanentModifiers(SCORES::TScores score, uint32 value)
{
_ScorePermanentModifiers[score] = value;
}
inline bool CCharacter::getEnterFlag() const
{
return _Enter;
@ -1047,6 +1057,12 @@ inline TAIAlias CCharacter::getSelectedOutpost() const
return _SelectedOutpost;
}
// return true if character has moved
inline bool CCharacter::hasMoved()
{
return ( _EntityState.X() != _SavedPosX || _EntityState.Y() != _SavedPosY );
}
//------------------------------------------------------------------------------
//inline CCharacter::CCharacterDbReminder* CCharacter::getDataIndexReminder()

View file

@ -819,7 +819,7 @@ void CCharacter::moveItem(INVENTORIES::TInventory srcInvId, uint32 srcSlot, INVE
return;
// cannot move a non dropable item or an active xp catalyser
if ((!srcForm->DropOrSell && !canPutNonDropableItemInInventory(dstInvId)) || isAnActiveXpCatalyser(srcItem))
if (!srcItem->getMovable() && (srcItem->getUnMovable() || (!srcForm->DropOrSell && !canPutNonDropableItemInInventory(dstInvId)) || isAnActiveXpCatalyser(srcItem)))
return;
// You cannot exchange genesis named items
@ -1326,6 +1326,22 @@ bool CCharacter::checkPreRequired(const CGameItemPtr & item, bool equipCheck )
}
}
pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> allegeance = getAllegiance();
bool neutralcult = (allegeance.first == PVP_CLAN::Neutral || allegeance.first == PVP_CLAN::None);
bool neutralciv = (allegeance.second == PVP_CLAN::Neutral || allegeance.second == PVP_CLAN::None);
if (item->getPhraseId().find("foragetool_") != 0 && (
(item->getRequiredFaction() == "kami" && (allegeance.first != PVP_CLAN::Kami || getOrganization() != 0)) ||
(item->getRequiredFaction() == "karavan" && (allegeance.first != PVP_CLAN::Karavan || getOrganization() != 0)) ||
(item->getRequiredFaction() == "marauder" && (!neutralcult || !neutralciv || getOrganization() != 5)) ||
(item->getRequiredFaction() == "neutralcult" && (!neutralcult || getOrganization() != 0)) ||
(item->getRequiredFaction() == "neutralciv" && (!neutralciv || getOrganization() != 0)) ||
(item->getRequiredFaction() == "neutral" && (!neutralcult || !neutralciv || getOrganization() != 0)) ||
(item->getRequiredFaction() == "fyros" && (allegeance.second != PVP_CLAN::Fyros || getOrganization() != 0)) ||
(item->getRequiredFaction() == "matis" && (allegeance.second != PVP_CLAN::Matis || getOrganization() != 0)) ||
(item->getRequiredFaction() == "tryker" && (allegeance.second != PVP_CLAN::Tryker || getOrganization() != 0)) ||
(item->getRequiredFaction() == "zorai" && (allegeance.second != PVP_CLAN::Zorai || getOrganization() != 0))))
requiredRespected = false;
if( requiredRespected == false && equipCheck )
{
PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, "REQUIRED_EQUIP" );
@ -2848,8 +2864,8 @@ void CCharacter::procEnchantment()
rightHandItem->setLatencyEndDate( phrase.getCastingTime() + CTickEventHandler::getGameCycle() );
}
}
else
nlwarning("user %s : no valid image for right weapon", _Id.toString().c_str());
/* else
nlwarning("user %s : no valid image for right weapon", _Id.toString().c_str());*/
}
else
{

View file

@ -21,6 +21,8 @@
/////////////
#include "stdpch.h"
#include "guild_manager/fame_manager.h"
#include "player_manager/character_version_adapter.h"
#include "player_manager/player_manager.h"
#include "player_manager/player.h"
@ -89,8 +91,11 @@ uint32 CCharacterVersionAdapter::currentVersionNumber() const
// 20 : (06/03/2006) give full hp to tools (even in player room and guild inv)
// 21 : (19/04/2006) convert to position stack & store the mainland in db
// 22 : (15/05/2006) reset flag pvp for resolve migration timer pb
// 23 : (05/04/2013) fix post merge marauder plan issue
// 24 : (23/10/2014) fix post merge rite bonus issue
// 25 : (05/03/2015) fix required faction in items on inventory
////////////////////////////////////
return 22;
return 25;
}
@ -122,6 +127,9 @@ void CCharacterVersionAdapter::adaptCharacterFromVersion( CCharacter &character,
case 19: adaptToVersion20(character);
case 20: adaptToVersion21(character);
case 21: adaptToVersion22(character);
case 22: adaptToVersion23(character);
case 23: adaptToVersion24(character);
case 24: adaptToVersion25(character);
default:;
}
}
@ -1009,3 +1017,330 @@ void CCharacterVersionAdapter::adaptToVersion22(CCharacter &character) const
{
character.resetPVPTimers();
}
//---------------------------------------------------
void CCharacterVersionAdapter::adaptToVersion23(CCharacter &character) const
{
nlinfo("Start");
//check if phrase is already known and Fix marauder sbricks + sp craft
uint16 sp = 0;
vector<string> parts;
parts.push_back("b");
parts.push_back("g");
parts.push_back("h");
parts.push_back("p");
parts.push_back("s");
parts.push_back("v");
vector<uint> deletePhrases;
// Check each part
for (uint i = 0; i < parts.size(); i++)
{
CSheetId phraseSId = CSheetId("abcbah"+parts[i]+".sphrase");
CSheetId brickMSid = CSheetId("bcbah"+parts[i]+"_m.sbrick");
CSheetId brickSid = CSheetId("bcbah"+parts[i]+".sbrick");
if (character._BoughtPhrases.find(phraseSId) != character._BoughtPhrases.end())
{
if (character._KnownBricks.find(brickMSid) != character._KnownBricks.end()
&& character._KnownBricks.find(brickSid) == character._KnownBricks.end() )
{
nlinfo("Bugged Char with phrase %s!", parts[i].c_str());
// Remove phrase and brick
character._BoughtPhrases.erase(phraseSId);
character._KnownBricks.erase(brickMSid);
sp += 40;
}
}
}
if (sp > 0)
{
nlinfo("Adding %d SP Craft !", sp);
character._SpType[EGSPD::CSPType::Craft] += sp;
}
}
//---------------------------------------------------
void CCharacterVersionAdapter::adaptToVersion24(CCharacter &character) const
{
// HP
uint32 bonus;
vector<string> bricks;
bricks.push_back("bthp01");
bricks.push_back("bthp04");
bricks.push_back("bthp06");
bricks.push_back("bthp08");
bricks.push_back("bthp12");
bricks.push_back("bthp13");
bricks.push_back("bthp16");
bricks.push_back("bthp17");
bricks.push_back("bthp18");
bricks.push_back("bthp20");
bonus = 0;
for (uint i = 0; i < bricks.size(); i++)
{
CSheetId brickSid = CSheetId(bricks[i]+".sbrick");
if (character._KnownBricks.find(brickSid) != character._KnownBricks.end())
{
bonus += 50;
}
}
if (character.getScorePermanentModifiers(SCORES::hit_points) < bonus)
{
nlinfo("RITE BONUS FIX: Player %s need %d (hp) but have %d !", character.getName().toString().c_str(), bonus, character.getScorePermanentModifiers(SCORES::hit_points));
character.setScorePermanentModifiers(SCORES::hit_points, bonus);
}
// SAP
bricks.clear();
bricks.push_back("btsap03");
bricks.push_back("btsap04");
bricks.push_back("btsap12");
bricks.push_back("btsap16");
bricks.push_back("btsap18");
bonus = 0;
for (uint i = 0; i < bricks.size(); i++)
{
CSheetId brickSid = CSheetId(bricks[i]+".sbrick");
if (character._KnownBricks.find(brickSid) != character._KnownBricks.end())
{
bonus += 50;
}
}
if (character.getScorePermanentModifiers(SCORES::sap) < bonus)
{
nlinfo("RITE BONUS FIX: Player %s need %d (sap) but have %d !", character.getName().toString().c_str(),bonus, character.getScorePermanentModifiers(SCORES::sap));
character.setScorePermanentModifiers(SCORES::sap, bonus);
}
// FOCUS
bricks.clear();
bricks.push_back("btfoc01");
bricks.push_back("btfoc04");
bricks.push_back("btfoc09");
bricks.push_back("btfoc11");
bricks.push_back("btfoc15");
bricks.push_back("btfoc17");
bricks.push_back("btfoc19");
bricks.push_back("btfoc20");
bonus = 0;
for (uint i = 0; i < bricks.size(); i++)
{
CSheetId brickSid = CSheetId(bricks[i]+".sbrick");
if (character._KnownBricks.find(brickSid) != character._KnownBricks.end())
{
bonus += 50;
}
}
if (character.getScorePermanentModifiers(SCORES::focus) < bonus)
{
nlinfo("RITE BONUS FIX: Player %s need %d (focus) but have %d !", character.getName().toString().c_str(),bonus, character.getScorePermanentModifiers(SCORES::focus));
character.setScorePermanentModifiers(SCORES::focus, bonus);
}
// STA
bricks.clear();
bricks.push_back("btsta13");
bricks.push_back("btsta14");
bricks.push_back("btsta15");
bricks.push_back("btsta16");
bricks.push_back("btsta17");
bricks.push_back("btsta20");
bonus = 0;
for (uint i = 0; i < bricks.size(); i++)
{
CSheetId brickSid = CSheetId(bricks[i]+".sbrick");
if (character._KnownBricks.find(brickSid) != character._KnownBricks.end())
{
bonus += 50;
}
}
if (character.getScorePermanentModifiers(SCORES::stamina) < bonus)
{
nlinfo("RITE BONUS FIX: Player %s need %d (stamina) but have %d !", character.getName().toString().c_str(),bonus, character.getScorePermanentModifiers(SCORES::stamina));
character.setScorePermanentModifiers(SCORES::stamina, bonus);
}
}
//---------------------------------------------------
void CCharacterVersionAdapter::adaptToVersion25(CCharacter &character) const
{
const uint sizeInv = INVENTORIES::NUM_INVENTORY;
for ( uint i = 0; i < sizeInv ; ++i )
if (character._Inventory[i] != NULL)
{
CInventoryPtr childSrc = character._Inventory[i];
for ( uint j = 0; j < childSrc->getSlotCount(); j++ )
{
CGameItemPtr item = childSrc->getItem(j);
if (item != NULL)
{
string phraseId = item->getPhraseId();
if ( (phraseId == "shield_ep2_kami50_1") ||
(phraseId == "shield_ep2_kami50_2") ||
(phraseId == "shield_ep2_kami100_1") ||
(phraseId == "shield_ep2_kami100_2") ||
(phraseId == "shield_ep2_kami150_1") ||
(phraseId == "shield_ep2_kami150_2") ||
(phraseId == "shield_ep2_kami200_1") ||
(phraseId == "shield_ep2_kami200_2") ||
(phraseId == "shield_ep2_kami250_1") ||
(phraseId == "shield_ep2_kami250_2") ||
(phraseId == "magic_dress_ep2_kami50_1") ||
(phraseId == "magic_dress_ep2_kami50_2") ||
(phraseId == "magic_dress_ep2_kami100_1") ||
(phraseId == "magic_dress_ep2_kami100_2") ||
(phraseId == "magic_dress_ep2_kami150_1") ||
(phraseId == "magic_dress_ep2_kami150_2") ||
(phraseId == "magic_dress_ep2_kami200_1") ||
(phraseId == "magic_dress_ep2_kami200_2") ||
(phraseId == "magic_dress_ep2_kami250_1") ||
(phraseId == "magic_dress_ep2_kami250_2")/* ||
(phraseId == "foragetool_kami_ep2_50_1") ||
(phraseId == "foragetool_kami_ep2_50_2") ||
(phraseId == "foragetool_kami_ep2_100_1") ||
(phraseId == "foragetool_kami_ep2_100_2") ||
(phraseId == "foragetool_kami_ep2_150_1") ||
(phraseId == "foragetool_kami_ep2_150_2") ||
(phraseId == "foragetool_kami_ep2_200_1") ||
(phraseId == "foragetool_kami_ep2_200_2") ||
(phraseId == "foragetool_kami_ep2_250_1") ||
(phraseId == "foragetool_kami_ep2_250_2")*/)
{
item->setRequiredFaction("kami");
item->addHp(item->durability());
}
/*
if ( (phraseId == "foragetool_tryker_50") ||
(phraseId == "foragetool_tryker_100") ||
(phraseId == "foragetool_tryker_150") ||
(phraseId == "foragetool_tryker_200") ||
(phraseId == "foragetool_tryker_250") ||
(phraseId == "foragetool_tryker_sfx"))
{
item->setRequiredFaction("tryker");
}
if ( (phraseId == "foragetool_zorai_50") ||
(phraseId == "foragetool_zorai_100") ||
(phraseId == "foragetool_zorai_150") ||
(phraseId == "foragetool_zorai_200") ||
(phraseId == "foragetool_zorai_250") ||
(phraseId == "foragetool_zorai_sfx"))
{
item->setRequiredFaction("zorai");
}
*/
if ( (phraseId == "shield_pvp_50") ||
(phraseId == "shield_pvp_100") ||
(phraseId == "shield_pvp_150") ||
(phraseId == "shield_pvp_200") ||
(phraseId == "shield_pvp_250") ||
(phraseId == "magic_dress_pvp_50") ||
(phraseId == "magic_dress_pvp_100") ||
(phraseId == "magic_dress_pvp_150") ||
(phraseId == "magic_dress_pvp_200") ||
(phraseId == "magic_dress_pvp_250"))
{
item->setRequiredFaction("neutralcult");
item->addHp(item->durability());
}
/*
if ( (phraseId == "foragetool_fyros_50") ||
(phraseId == "foragetool_fyros_100") ||
(phraseId == "foragetool_fyros_150") ||
(phraseId == "foragetool_fyros_200") ||
(phraseId == "foragetool_fyros_250") ||
(phraseId == "foragetool_fyros_sfx"))
{
item->setRequiredFaction("fyros");
}
if ( (phraseId == "foragetool_matis_50") ||
(phraseId == "foragetool_matis_100") ||
(phraseId == "foragetool_matis_150") ||
(phraseId == "foragetool_matis_200") ||
(phraseId == "foragetool_matis_250") ||
(phraseId == "foragetool_matis_sfx"))
{
item->setRequiredFaction("matis");
}
*/
if ( (phraseId == "shield_ep2_karavan50_1") ||
(phraseId == "shield_ep2_karavan50_2") ||
(phraseId == "shield_ep2_karavan100_1") ||
(phraseId == "shield_ep2_karavan100_2") ||
(phraseId == "shield_ep2_karavan150_1") ||
(phraseId == "shield_ep2_karavan150_2") ||
(phraseId == "shield_ep2_karavan200_1") ||
(phraseId == "shield_ep2_karavan200_2") ||
(phraseId == "shield_ep2_karavan250_1") ||
(phraseId == "shield_ep2_karavan250_2") ||
(phraseId == "magic_dress_ep2_karavan50_1") ||
(phraseId == "magic_dress_ep2_karavan50_2") ||
(phraseId == "magic_dress_ep2_karavan100_1") ||
(phraseId == "magic_dress_ep2_karavan100_2") ||
(phraseId == "magic_dress_ep2_karavan150_1") ||
(phraseId == "magic_dress_ep2_karavan150_2") ||
(phraseId == "magic_dress_ep2_karavan200_1") ||
(phraseId == "magic_dress_ep2_karavan200_2") ||
(phraseId == "magic_dress_ep2_karavan250_1") ||
(phraseId == "magic_dress_ep2_karavan250_2") ||
(phraseId == "foragetool_karavan_ep2_50_1")/* ||
(phraseId == "foragetool_karavan_ep2_50_2") ||
(phraseId == "foragetool_karavan_ep2_100_1") ||
(phraseId == "foragetool_karavan_ep2_100_2") ||
(phraseId == "foragetool_karavan_ep2_150_1") ||
(phraseId == "foragetool_karavan_ep2_150_2") ||
(phraseId == "foragetool_karavan_ep2_200_1") ||
(phraseId == "foragetool_karavan_ep2_200_2") ||
(phraseId == "foragetool_karavan_ep2_250_1") ||
(phraseId == "foragetool_karavan_ep2_250_2")*/)
{
item->setRequiredFaction("karavan");
item->addHp(item->durability());
}
if ( (phraseId == "shield_mar_50") ||
(phraseId == "shield_mar_100") ||
(phraseId == "shield_mar_150") ||
(phraseId == "shield_mar_200") ||
(phraseId == "shield_mar_250") ||
(phraseId == "magic_dress_mar_50") ||
(phraseId == "magic_dress_mar_100") ||
(phraseId == "magic_dress_mar_150") ||
(phraseId == "magic_dress_mar_200") ||
(phraseId == "magic_dress_mar_250"))
{
item->setRequiredFaction("marauder");
item->addHp(item->durability());
}
}
}
}
character.unequipCharacter( INVENTORIES::handling, INVENTORIES::left );
}

View file

@ -83,6 +83,9 @@ private:
void adaptToVersion20(CCharacter &character) const;
void adaptToVersion21(CCharacter &character) const;
void adaptToVersion22(CCharacter &character) const;
void adaptToVersion23(CCharacter &character) const;
void adaptToVersion24(CCharacter &character) const;
void adaptToVersion25(CCharacter &character) const;
private:
/// unique instance
static CCharacterVersionAdapter* _Instance;

View file

@ -62,7 +62,7 @@ class CDBStringUpdater : public NLMISC::CSingleton<CDBStringUpdater>
// hasher for the identifier
struct THashDBStringLeaf
{
enum { bucket_size = 4, min_buckets = 8, };
enum { bucket_size = 4, min_buckets = 8 };
size_t operator()(const TBDStringLeaf &stringLeaf) const
{
return ((size_t)stringLeaf.ClientDB>>4) ^ ((size_t)stringLeaf.Node>>4);

View file

@ -507,6 +507,7 @@ static void prepareCharacterPositionForStore ( COfflineEntityState & state, cons
STRUCT_VECT(_Pact)\
STRUCT_VECT(_KnownPhrases)\
STRUCT_MAP(TAIAlias, TMissionHistory, _MissionHistories)\
PROP_MAP(string, string, _CustomMissionsParams)\
LSTRUCT(_WelcomeMissionDesc, if (_WelcomeMissionDesc.isValid()))\
STRUCT_ARRAY(_PlayerPets,_PlayerPets.size())\
\
@ -1339,6 +1340,7 @@ private:
PROP2(_Recommended, uint32, _Recommended, _Recommended=val)\
PROP2(_CreatorId, CEntityId, _CreatorId, _CreatorId=val)\
PROP2(_PhraseId, string, _PhraseId, _PhraseId=val)\
PROP2(_RequiredFaction, string, _RequiredFaction, _RequiredFaction=val)\
LSTRUCT2(_CraftParameters, if (_CraftParameters != NULL), _CraftParameters->store(pdr), _CraftParameters = new CItemCraftParameters; _CraftParameters->apply(pdr))\
LPROP2(_SlotImage, uint16, if (0), 0xffff, slotImage=val)\
LPROP2(_SapLoad, uint32, if (_SapLoad!=0), _SapLoad, _SapLoad=val)\
@ -1357,6 +1359,9 @@ private:
STRUCT_VECT(_TypeSkillMods)\
LPROP_VECT(CSheetId, _Enchantment, VECT_LOGIC(_Enchantment) if (_Enchantment[i]!=CSheetId::Unknown))\
PROP2(_CustomText, ucstring, _CustomText, _CustomText=val)\
PROP2(_CustomName, ucstring, _CustomName, _CustomName=val)\
PROP(bool, _Movable)\
PROP(bool, _UnMovable)\
PROP(bool, _LockedByOwner)\
//#pragma message( PERSISTENT_GENERATION_MESSAGE )

View file

@ -460,6 +460,7 @@ void CPlayerManager::addClientCallback()
{ "SET_PLAYER_SEASON", cbSetPlayerSeason }, // from DSS
{ "TELEPORT_PLAYER", cbTeleportPlayer }, // from AIS
{ "TRIGGER_WEBIG", cbTriggerWebig }, // from AIS
{ "SET_CHAR_AIINSTANCE", cbSetCharacterAIInstance},

View file

@ -50,7 +50,7 @@ extern CGenericXmlMsgHeaderManager GenericMsgManager;
struct CServiceIdHash
{
enum { bucket_size = 4, min_buckets = 8, };
enum { bucket_size = 4, min_buckets = 8 };
size_t operator () ( const NLNET::TServiceId &sid ) const { return sid.get(); }
bool operator()(const NLNET::TServiceId &left, const NLNET::TServiceId &right) const { return left < right; }
};

View file

@ -43,7 +43,7 @@ public:
struct CUint32Hash
{
enum { bucket_size = 4, min_buckets = 8, };
enum { bucket_size = 4, min_buckets = 8 };
size_t operator () (const uint32 &i) const { return i; }
bool operator()(const uint32 left, const uint32 right) const { return left < right; }
};

View file

@ -54,6 +54,12 @@ public:
return _Data->Building;
}
/// set the destination where the room physically is
void setBuilding(CBuildingPhysicalPlayer * building)
{
_Data->Building = building;
}
/// init the room. Should be called when a user buys it
void init(CCharacter * owner, CBuildingPhysicalPlayer * building);

View file

@ -1203,7 +1203,7 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
CCharacter * winnerChar = PlayerManager.getChar(players[k]);
BOMB_IF(winnerChar == NULL, "invalid winner!", continue);
PVP_CLAN::TPVPClan winnerFaction = PVP_CLAN::None;
PVP_CLAN::TPVPClan winnerFaction = PVP_CLAN::Neutral;
bool winnerGainFactionPoints = true;
if (!canPlayerWinPoints(winnerChar, victimChar))
@ -1247,7 +1247,7 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
fameFactor--;
}
clamp(fameFactor, 0, 3);
nlinfo("points = %d * %d", fpPerPlayer, fameFactor);
//nlinfo("points = %d * %d", fpPerPlayer, fameFactor);
// player gains faction points
changePlayerPvpPoints(winnerChar, sint32(fpPerPlayer) * fameFactor);

View file

@ -570,6 +570,10 @@ void CPVPManager::enterPVPZone( CCharacter * user, TAIAlias pvpZoneAlias )
if( zone->getPVPZoneType() != PVP_ZONE_TYPE::OutpostZone )
{
// Remove OP pvp interface
user->setOutpostAlias(0);
user->stopOutpostLeavingTimer();
// add user to entering PVP zone users
NLMISC::TGameCycle endDate = CTickEventHandler::getGameCycle() + PVPZoneEnterBufferTime;
CPVPZonePendingUser pendingUser;

View file

@ -213,12 +213,17 @@ std::vector<TChanID> CPVPManager2::getCharacterChannels(CCharacter * user)
// Add lang channel, should be first.
if (!user->getLangChannel().empty())
{
TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find(user->getLangChannel());
std::vector<std::string> langChannels;
NLMISC::splitString(user->getLangChannel(), " ", langChannels);
for ( uint i = 0; i < langChannels.size(); i++ )
{
TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find(langChannels[i]);
if (it != _ExtraFactionChannel.end())
{
result.push_back((*it).second);
}
}
}
else
{
TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find("en");
@ -713,10 +718,15 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn
_Instance->_PVPOutpostAllyReminder = false;
_Instance->_PVPOutpostEnemyReminder = false;
PVP_RELATION::TPVPRelation relationTmp = PVP_RELATION::Neutral;
CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if( pTarget )
{
if (curative && pTarget == actor)
{
return PVP_RELATION::Ally;
}
// Full PVP is ennemy of everybody
if (pTarget->getFullPVP() || actor->getFullPVP())
{
@ -731,8 +741,8 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn
IPVP * pvpSession = pTarget->getPVPInterface().getPVPSession();
if( pvpSession )
{
relation = pvpSession->getPVPRelation( actor, target );
if( relation == PVP_RELATION::Ennemy )
relationTmp = pvpSession->getPVPRelation( actor, target );
if( relationTmp == PVP_RELATION::Ennemy )
{
pvpSession = actor->getPVPInterface().getPVPSession();
if( pvpSession )
@ -754,11 +764,15 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn
}
}
}
else if ( relationTmp != PVP_RELATION::Ally )
{
relationTmp = PVP_RELATION::NeutralPVP;
}
relation = relationTmp;
}
////////////////////////////////////////////////////////
}
PVP_RELATION::TPVPRelation relationTmp = PVP_RELATION::Neutral;
uint i;
for( i=0; i<_PVPInterface.size(); ++i )
{
@ -970,7 +984,7 @@ bool CPVPManager2::canApplyAreaEffect(CCharacter* actor, CEntityBase * areaTarge
// set faction flag
if( offensive && _PVPFactionEnemyReminder )
{
if(pTarget)
if(pTarget && pTarget->getId() != actor->getId())
{
actor->setPVPRecentActionFlag();
TeamManager.pvpAttackOccursInTeam( actor, pTarget );

View file

@ -33,20 +33,18 @@ void CRangeSelector::buildDisc( CEntityBase * actor, sint32 x, sint32 y,float ra
for (uint32 i=0;i<_Entities.size();++i)
BOMB_IF(_Entities[i]==&*it,"BUG: We just tried to insert the same entity into a disk entity list more than once!",continue);
if( c != 0 )
{
CEntityBase * areaTarget = &(*it);
if( c != 0)
if( c != NULL)
{
// Do not add the entity if a PVP rule excludes it from being selected
if( ! CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, offensiveAction, ignoreMainTarget ) )
continue;
// Do not add invisible entity for player
if( !R2_VISION::isEntityVisibleToPlayers(areaTarget->getWhoSeesMe()))
continue;
// Do not add invulnerable entities, they are GM and use a slot for nothing
if( areaTarget && areaTarget->invulnerableMode() )
continue;
// Do not add the entity if a PVP rule excludes it from being selected
if( ! CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, offensiveAction, ignoreMainTarget ) )
continue;
}
else
{
@ -57,7 +55,6 @@ void CRangeSelector::buildDisc( CEntityBase * actor, sint32 x, sint32 y,float ra
if( areaTarget && areaTarget->invulnerableMode() )
continue;
}
}
_Entities.push_back(&*it);
_Distances.push_back( it.getDistance() );
@ -154,15 +151,16 @@ void CRangeSelector::buildCone(CEntityBase* source , CEntityBase* target,float h
CEntityBase * areaTarget = &(*it);
if( c != 0 )
{
// Do not add the entity if a PVP rule excludes it from being selected
if( ! CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, offensiveAction, ignoreMainTarget ) )
continue;
// Do not add invisible entity for player
if( !R2_VISION::isEntityVisibleToPlayers(areaTarget->getWhoSeesMe()))
continue;
// Do not add invulnerable entities, they are GM and use a slot for nothing
if( areaTarget && areaTarget->invulnerableMode() )
continue;
// Do not add the entity if a PVP rule excludes it from being selected
if( ! CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, offensiveAction, ignoreMainTarget ) )
continue;
}
else
{
@ -210,15 +208,17 @@ void CRangeSelector::buildChain( CEntityBase* actor, CEntityBase* target, float
CEntityBase * areaTarget = &(*it);
if( c != 0 )
{
// Do not add the entity if a PVP rule excludes it from being selected
if( ! CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, (nature == ACTNATURE::FIGHT || nature == ACTNATURE::OFFENSIVE_MAGIC), ignoreMainTarget ) )
continue;
// Do not add invisible entity for player
if( !R2_VISION::isEntityVisibleToPlayers(areaTarget->getWhoSeesMe()))
continue;
// Do not add invulnerable entities, they are GM and use a slot for nothing
if( areaTarget && areaTarget->invulnerableMode() )
continue;
// Do not add the entity if a PVP rule excludes it from being selected
if( ! CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, (nature == ACTNATURE::FIGHT || nature == ACTNATURE::OFFENSIVE_MAGIC), ignoreMainTarget ) )
continue;
}
else
{
@ -250,15 +250,18 @@ void CRangeSelector::buildChain( CEntityBase* actor, CEntityBase* target, float
CEntityBase * areaTarget = &(*it);
if( c != 0 )
{
// Do not add the entity if a PVP rule excludes it from being selected
if( CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, (nature == ACTNATURE::FIGHT || nature == ACTNATURE::OFFENSIVE_MAGIC), ignoreMainTarget ) )
continue;
// Do not add invisible entity player
if( !R2_VISION::isEntityVisibleToPlayers(areaTarget->getWhoSeesMe()))
continue;
// Do not add invulnerable entities, they are GM and use a slot for nothing
if( areaTarget && areaTarget->invulnerableMode() )
continue;
// Do not add the entity if a PVP rule excludes it from being selected
if( CPVPManager2::getInstance()->canApplyAreaEffect( c, areaTarget, (nature == ACTNATURE::FIGHT || nature == ACTNATURE::OFFENSIVE_MAGIC), ignoreMainTarget ) )
continue;
}
else
{

View file

@ -1375,7 +1375,7 @@ uint32 CShopTypeManager::computeBasePrice( const CSheetId& sheet, uint16 level,
const CStaticBrick * brick = CSheets::getSBrickForm( itemForm->CraftPlan );
if( !brick )
{
nlwarning("<CShopTypeManager> Can't find craft plan sheet '%s' in item form '%s'", itemForm->CraftPlan.toString().c_str(), sheet.toString().c_str() );
//nlwarning("<CShopTypeManager> Can't find craft plan sheet '%s' in item form '%s'", itemForm->CraftPlan.toString().c_str(), sheet.toString().c_str() );
return 0;
}
const CFaber* faber = brick->Faber;

View file

@ -342,16 +342,14 @@ bool CPlace::build(const NLLIGO::CPrimZone * zone,uint16 id, bool reportAutorise
_GooPath = false;
_GooActive = false;
// get place_type of re-spawn point
PLACE_TYPE::TPlaceType placeType;
if( zone->getPropertyByName("place_type", val) )
{
placeType = PLACE_TYPE::fromString(val);
if( placeType == PLACE_TYPE::Undefined )
placeType = PLACE_TYPE::Place;
_PlaceType = PLACE_TYPE::fromString(val);
if( _PlaceType == PLACE_TYPE::Undefined )
_PlaceType = PLACE_TYPE::Place;
}
else
placeType = PLACE_TYPE::Place;
_PlaceType = PLACE_TYPE::Place;
// get children respawn points
bool ret = true;
@ -377,7 +375,7 @@ bool CPlace::build(const NLLIGO::CPrimZone * zone,uint16 id, bool reportAutorise
spawn->getType() == RESPAWN_POINT::NEWBIELAND ||
spawn->getType() == RESPAWN_POINT::RESPAWNABLE )
{
(const_cast<CTpSpawnZone *>(spawn))->setPlaceType(placeType);
(const_cast<CTpSpawnZone *>(spawn))->setPlaceType(_PlaceType);
_RespawnPoints.push_back( idx );
}
}

View file

@ -155,6 +155,7 @@ public:
bool isGooActive() const { return _GooActive; }
bool isMainPlace() const { return _MainPlace; }
TAIAlias getAlias()const{ return _Alias; }
PLACE_TYPE::TPlaceType getPlaceType() const { return _PlaceType; }
const std::vector<uint16> & getRespawnPoints() const { return _RespawnPoints; }
@ -178,6 +179,8 @@ private:
std::vector<uint16> _RespawnPoints;
/// persistant alias
TAIAlias _Alias;
/// place type: capital, village etc
PLACE_TYPE::TPlaceType _PlaceType;
};
/**

View file

@ -357,6 +357,7 @@ public:
Entity = entity;
CheckSpeed = true;
Indoor = false;
EnableVisionProcessing = true;
}
@ -415,6 +416,7 @@ public:
bool EnableVisionProcessing;
bool CheckSpeed;
bool Indoor;
/// Who I can see flag field
uint32 WhoICanSee;

View file

@ -1473,7 +1473,7 @@ void CWorldPositionManager::computeVision()
break;
cell->setVisionUpdateCycle(CTickEventHandler::getGameCycle());
H_TIME(ComputeCellVision, computeCellVision(cell, cellVisionArray, numEntities););
H_TIME(ComputeCellVision, computeCellVision(cell, cellVisionArray, numEntities, player->Entity););
CPlayerInfos *plv;
for (plv=cell->getPlayersList(); plv!=NULL; plv=plv->Next)
@ -1632,7 +1632,7 @@ TPlayerList::iterator CWorldPositionManager::prioritizeVisionState(TPlayerList::
/****************************************************************\
computeCellVision()
\****************************************************************/
void CWorldPositionManager::computeCellVision( CCell *cell, CVisionEntry* entitiesSeenFromCell, uint &numEntities)
void CWorldPositionManager::computeCellVision( CCell *cell, CVisionEntry* entitiesSeenFromCell, uint &numEntities, CWorldEntity *player)
{
STOP_IF(IsRingShard,"Illegal use of CWorldPositionManager on ring shard");
CVisionEntry* fillPtr; // entities pointer fill buffer
@ -1656,7 +1656,7 @@ void CWorldPositionManager::computeCellVision( CCell *cell, CVisionEntry* entiti
// First adds objects
fillPtr = entitiesSeenFromCell;
endPtr = entitiesSeenFromCell+MAX_SEEN_OBJECTS;
fillPtr = cell->addObjects(fillPtr, endPtr, centerCellMask, 0);
fillPtr = cell->addObjects(fillPtr, endPtr, centerCellMask, 0, cell->isIndoor(), player);
// if the cell has vision on other cells
if (!cell->isIndoor())
@ -1706,7 +1706,7 @@ void CWorldPositionManager::computeCellVision( CCell *cell, CVisionEntry* entiti
// then adds entities
endPtr = entitiesSeenFromCell+MAX_SEEN_ENTITIES;
fillPtr = cell->addEntities(fillPtr, endPtr, centerCellMask, 0);
fillPtr = cell->addEntities(fillPtr, endPtr, centerCellMask, 0, cell->isIndoor(), player);
// if the cell has vision on other cells
if (!cell->isIndoor())
@ -1778,6 +1778,8 @@ void CWorldPositionManager::setCellVisionToEntity( CWorldEntity *entity, CVision
if (!infos->EnableVisionProcessing)
return;
infos->Indoor = entity->CellPtr != NULL && entity->CellPtr->isIndoor();
// update the player vision, new entities in vision are stored in inVision, old ones in outVision
static CPlayerVisionDelta visionDelta;
H_TIME(ComputePlayerDeltaVision, computePlayerDeltaVision( infos, cellVisionArray, numEntities, visionDelta ););
@ -1983,16 +1985,14 @@ void CWorldPositionManager::computePlayerDeltaVision( CPlayerInfos *infos, CVisi
if (e->TempVisionState)
{
addToEntitiesIn(infos, e, visionDelta);
e->TempVisionState = false;
}
cellVision[i].Entity->TempVisionState = false;
}
// reset vision state for entities that were not checked (not enough slots)
for (; i<numEntities; ++i)
cellVision[i].Entity->TempVisionState = false;
// *** Prevent from splitting vision of controller/controlled entity.
// Ex: mounted mounts must not be visible if their rider is not visible.
// It might waste some free slot space but this way we are sure the players won't have invisible riders.

View file

@ -999,7 +999,7 @@ private:
* compute Cell Vision,
* \param CCell the cell to compute vision on
*/
static void computeCellVision( CCell *cell, CVisionEntry* entitiesSeenFromCell, uint &numEntities);
static void computeCellVision( CCell *cell, CVisionEntry* entitiesSeenFromCell, uint &numEntities, CWorldEntity *player);
/**
* Update vision for this player

View file

@ -97,6 +97,8 @@ void CChatManager::onServiceDown(const std::string &serviceShortName)
case CChatGroup::universe:
case CChatGroup::say:
case CChatGroup::shout:
case CChatGroup::player:
case CChatGroup::nbChatMode:
continue;
case CChatGroup::team:
case CChatGroup::guild:

View file

@ -45,6 +45,9 @@ extern CGenericXmlMsgHeaderManager GenericXmlMsgHeaderMngr;
extern CVariable<bool> VerboseChatManagement;
typedef NLMISC::CTwinMap<TChanID, string> TChanTwinMap;
extern TChanTwinMap _ChanNames;
//-----------------------------------------------
// cbImpulsionReadyString :
@ -1584,15 +1587,26 @@ void cbDynChatAddChan(CMessage& msgin, const string &serviceName, TServiceId ser
bool noBroadcast;
bool forwardInput;
bool unify;
string name;
msgin.serial(chanID);
msgin.serial(noBroadcast);
msgin.serial(forwardInput);
msgin.serial(unify);
nlinfo("cbDynChatAddChan: add channel");
msgin.serial(name);
nlinfo("cbDynChatAddChan: add channel : %s", name.c_str());
bool res = IOS->getChatManager().getDynChat().addChan(chanID, noBroadcast, forwardInput, unify);
if (!res) nlwarning("Couldn't add chan %s", chanID.toString().c_str());
else nlinfo("cbDynChatAddChan: add channel %s",chanID.toString().c_str());
if (!res)
nlwarning("Couldn't add chan %s", chanID.toString().c_str());
else
{
if (_ChanNames.getA(name) == NULL && _ChanNames.getB(chanID) == NULL)
_ChanNames.add(chanID, name);
else
nlwarning("Couldn't add chan %s. already added! %p %p", chanID.toString().c_str(), _ChanNames.getA(name), _ChanNames.getB(chanID));
nlinfo("cbDynChatAddChan: add channel %s",chanID.toString().c_str());
}
}
//-----------------------------------------------
@ -1802,7 +1816,23 @@ void cbDynChatSetHideBubble(CMessage& msgin, const string &serviceName, TService
chan->HideBubble = hideBubble;
}
void cbDynChatSetUniversalChannel(CMessage& msgin, const string &serviceName, TServiceId serviceId)
{
TChanID chanID;
bool universalChannel;
msgin.serial(chanID);
msgin.serial(universalChannel);
CChatManager &cm = IOS->getChatManager();
CDynChatChan *chan = cm.getDynChat().getChan(chanID);
if (!chan)
{
nlwarning("Unknown chan");
return;
}
chan->UniversalChannel = universalChannel;
}
void cbDynChatServiceChat(CMessage& msgin, const string &serviceName, TServiceId serviceId)
{
@ -2072,6 +2102,7 @@ TUnifiedCallbackItem CbIOSArray[]=
{ "DYN_CHAT:SERVICE_CHAT", cbDynChatServiceChat }, // a service send a chat message in the channel without sender id
{ "DYN_CHAT:SERVICE_TELL", cbDynChatServiceTell }, // a service send a chat message to a specific client in the channel without sender id
{ "DYN_CHAT:SET_HIDE_BUBBLE", cbDynChatSetHideBubble }, // a service send a chat message to a specific client in the channel without sender id
{ "DYN_CHAT:SET_UNIVERSAL_CHANNEL", cbDynChatSetUniversalChannel },
//received from DSS
{ "REQUEST_DSR", cbRequestDsr},
// { "ADD_DM", cbAddDM }, // A character enter a ring session that he own

View file

@ -246,6 +246,60 @@ void CStringManager::clearCache(NLMISC::CLog *log)
// load the values using the george sheet
void CStringManager::TSheetInfo::readGeorges (const NLMISC::CSmartPtr<NLGEORGES::UForm> &form, const NLMISC::CSheetId &sheetId)
{
if (form)
{
SheetName = sheetId.toString();
std::string ext = NLMISC::CSheetId::fileExtensionFromType(sheetId.getSheetType());
SheetName = SheetName.substr(0, SheetName.find(ext));
// remove ending '.'
if (!SheetName.empty() && *SheetName.rbegin() == '.')
SheetName.resize(SheetName.size()-1);
std::string gender;
if (sheetId.getSheetType() == NLMISC::CSheetId::typeFromFileExtension("creature"))
{
form->getRootNode ().getValueByName (gender, "Basics.Gender");
sint genderId;
NLMISC::fromString(gender, genderId);
Gender = GSGENDER::EGender(genderId);
form->getRootNode ().getValueByName (Race, "Basics.Race");
// form->getRootNode ().getValueByName (DisplayName, "Basics.First Name");
// std::string s;
// form->getRootNode ().getValueByName (s, "Basics.CharacterName");
// if (!DisplayName.empty())
// DisplayName+=' ';
// DisplayName+=s;
form->getRootNode ().getValueByName (Profile, "Basics.Profile");
form->getRootNode ().getValueByName (ChatProfile, "Basics.ChatProfile");
}
else if (sheetId.getSheetType() == NLMISC::CSheetId::typeFromFileExtension("race_stats"))
{
form->getRootNode ().getValueByName (Race, "Race");
}
/* else if (sheetId.getType() == NLMISC::CSheetId::typeFromFileExtension("sitem"))
{
// read any item specific data
}
*/ else
{
nlwarning("CStringManager::TEntityInfo : Do not know the type of the sheet '%s'.", sheetId.toString().c_str());
return;
}
}
}
const CStringManager::CEntityWords &CStringManager::getEntityWords(TLanguages lang, STRING_MANAGER::TParamType type) const
{
nlassert(lang < NB_LANGUAGES);

View file

@ -106,7 +106,7 @@ uint32 CUsedContinent::getInstanceForContinent(const std::string &continentName)
if (it != _Continents.end())
return it->ContinentInstance;
else
return INVALID_AI_INSTANCE;
return std::numeric_limits<uint32>::max();
}
uint32 CUsedContinent::getInstanceForContinent(CONTINENT::TContinent continentEnum) const
@ -116,7 +116,7 @@ uint32 CUsedContinent::getInstanceForContinent(CONTINENT::TContinent continentEn
if (it != _Continents.end())
return it->ContinentInstance;
else
return INVALID_AI_INSTANCE;
return std::numeric_limits<uint32>::max();
}
const std::string &CUsedContinent::getContinentForInstance(uint32 instanceNumber) const

View file

@ -21,7 +21,6 @@
#include "nel/misc/types_nl.h"
#include "nel/net/service.h"
#include "game_share/continent.h"
#include "game_share/misc_const.h"
#include <algorithm>

View file

@ -564,6 +564,7 @@ namespace ENTITYLOC
void charConnected(NLNET::IModuleProxy *sender, const NLMISC::CEntityId &charEId, uint32 lastDisconnectionDate)
{
TCharId charId = (TCharId)charEId.getShortId();
uint32 dynamicId = charEId.getDynamicId();
nldebug("ENTLOC : charConnected : character %u connected from '%s'", charId, sender->getModuleName().c_str());
@ -577,10 +578,10 @@ namespace ENTITYLOC
TShardId shardId = locIt->second;
_charConnected(sender, charId, lastDisconnectionDate, shardId);
_charConnected(sender, charId, lastDisconnectionDate, shardId, dynamicId);
}
void _charConnected(NLNET::IModuleProxy *sender, uint32 charId, uint32 lastDisconnectionDate, uint32 shardId)
void _charConnected(NLNET::IModuleProxy *sender, uint32 charId, uint32 lastDisconnectionDate, uint32 shardId, uint32 dynamicId)
{
uint32 lastConnectionDate = CTime::getSecondsSince1970();
@ -608,6 +609,7 @@ namespace ENTITYLOC
// update the last played date
character->setLastPlayedDate(lastConnectionDate);
character->setRRPAM(dynamicId);
character->update(_RingDB);
}
@ -792,7 +794,7 @@ namespace ENTITYLOC
// return true;
// }
_charConnected(NULL, charId, CTime::getSecondsSince1970()-10, shardId);
_charConnected(NULL, charId, CTime::getSecondsSince1970()-10, shardId, 0);
return true;
}

View file

@ -29,7 +29,8 @@ class IStep;
int main(int argc, char *argv[])
{
new NLMISC::CApplicationContext;
CSmartPtr<NLMISC::CApplicationContext> appContext(new NLMISC::CApplicationContext());
CPath::addSearchPath("L:\\primitives\\", true, false);
bool test = false;
@ -95,7 +96,12 @@ int main(int argc, char *argv[])
::fwrite(script.data(), script.size(), 1, fp);
::fclose(fp);
system((string("\"C:\\Program Files\\Beyond Compare 2\\bc2.exe\" ")+string(tmp)+"/compiled_mission.script test_compilateur.script").c_str());
// TODO: set diff program in .cfg
std::string compareApp = "";
sint error = system(compareApp+(string(" ")+string(tmp)+"/compiled_mission.script test_compilateur.script").c_str());
if (error)
nlwarning("'%s' failed with error code %d", "", error);
}
catch(const EParseException &e)
{
@ -265,6 +271,8 @@ int main(int argc, char *argv[])
}
CPrimitiveContext::instance().CurrentLigoConfig = NULL;
return 0;
}