Changed: #1135 Merge changes from Ryzom patch 1.10

This commit is contained in:
kervala 2010-10-23 14:29:27 +02:00
parent ee8392a4ab
commit c0c583b316
35 changed files with 1497 additions and 506 deletions

View file

@ -311,6 +311,7 @@ public:
uint32 getChildIndexByAlias(uint32 alias) const;
TChld* getChildByAlias(uint32 alias) const;
TChld* getChildByName(std::string const& name) const;
TChld* getFirstChild() const;
CAliasTreeOwner* getAliasChildByAlias(uint32 alias) const;
CAliasTreeOwner* addAliasChild(CAliasTreeOwner* child);
@ -523,6 +524,19 @@ TChld* CAliasCont<TChld>::getChildByName(std::string const& name) const
return NULL;
}
template <class TChld>
TChld* CAliasCont<TChld>::getFirstChild() const
{
size_t size = this->_Childs.size();
for (size_t i=0; i<size; ++i)
{
TChld* child = this->_Childs[i];
if (child!=NULL)
return child;
}
return NULL;
}
template <class TChld>
CAliasTreeOwner* CAliasCont<TChld>::getAliasChildByAlias(uint32 alias) const
{

View file

@ -1280,18 +1280,30 @@ void setPlayerController_ss_(CStateInstance* entity, CScriptStack& stack)
{
CGroup* grp = NULL;
CSpawnBotNpc* bot = NULL;
if ((bot = dynamic_cast<CSpawnBotNpc*>(CAIEntityPhysicalLocator::getInstance()->getEntity(botId)))
&& (&bot->getPersistent().getGroup())==entity->getGroup())
CAIEntityPhysicalLocator *inst = CAIEntityPhysicalLocator::getInstance();
if (inst)
{
CBotPlayer* player = NULL;
if (playerId!=NLMISC::CEntityId::Unknown
&& (player = dynamic_cast<CBotPlayer*>(CAIEntityPhysicalLocator::getInstance()->getEntity(playerId))))
CAIEntityPhysical *botEntity = inst->getEntity(botId);
if (botEntity)
{
bot->setPlayerController(player);
if ((bot = dynamic_cast<CSpawnBotNpc*>(botEntity))
&& (&bot->getPersistent().getGroup())==entity->getGroup())
{
CBotPlayer* player = NULL;
if (playerId!=NLMISC::CEntityId::Unknown
&& (player = dynamic_cast<CBotPlayer*>(CAIEntityPhysicalLocator::getInstance()->getEntity(playerId))))
{
bot->setPlayerController(player);
}
else
bot->setPlayerController(NULL);
}
}
else
bot->setPlayerController(NULL);
nlwarning("Bot entity not found");
}
else
nlwarning("Instance not found");
}
}
@ -2002,7 +2014,12 @@ static CSpawnBot* getSpawnBotFromGroupByName(CGroupNpc* const group, const std::
CSpawnBot* spawnBot=0;
CAliasCont<CBot> const& bots = group->bots();
CBot* child=bots.getChildByName(botname);
CCont<CBot> & cc_bots = group->bots();
CBot* child;
if (botname == "")
child = bots.getFirstChild();
else
child = bots.getChildByName(botname);
if (!child) { return 0; }
spawnBot = child->getSpawnObj();
@ -2291,6 +2308,37 @@ void emote_css_(CStateInstance* entity, CScriptStack& stack)
NLNET::CUnifiedNetwork::getInstance()->send( "EGS", msgout );
}
void emote_ss_(CStateInstance* entity, CScriptStack& stack)
{
string emoteName = (string)stack.top(); stack.pop();
NLMISC::CEntityId botId = NLMISC::CEntityId((std::string)stack.top());
if (botId == NLMISC::CEntityId::Unknown)
{
return;
}
// Is the emote valid
uint32 emoteId = CAIS::instance().getEmotNumber(emoteName);
if (emoteId == ~0)
{
return;
}
// Get the behaviour Id
MBEHAV::EBehaviour behaviourId = (MBEHAV::EBehaviour)(emoteId + MBEHAV::EMOTE_BEGIN);
// Change the behaviour
NLNET::CMessage msgout("SET_BEHAVIOUR");
msgout.serial(botId);
MBEHAV::CBehaviour bh(behaviourId);
bh.Data = (uint16)(CTimeInterface::gameCycle());
msgout.serial(bh);
NLNET::CUnifiedNetwork::getInstance()->send( "EGS", msgout );
}
//----------------------------------------------------------------------------
/** @page code
@ -2429,6 +2477,7 @@ std::map<std::string, FScrptNativeFunc> nfGetNpcGroupNativeFunctions()
REGISTER_NATIVE_FUNC(functions, talkTo_sc_);
REGISTER_NATIVE_FUNC(functions, facing_cscs_);
REGISTER_NATIVE_FUNC(functions, emote_css_);
REGISTER_NATIVE_FUNC(functions, emote_ss_);
REGISTER_NATIVE_FUNC(functions, npcSay_css_);
REGISTER_NATIVE_FUNC(functions, dssMessage_fsss_);
REGISTER_NATIVE_FUNC(functions, despawnBotByAlias_s_);

View file

@ -30,6 +30,8 @@
#include "nf_helpers.h"
#include "nel/misc/md5.h"
using std::string;
using std::vector;
using namespace NLMISC;
@ -655,6 +657,31 @@ void pow_ff_f(CStateInstance* entity, CScriptStack& stack)
//----------------------------------------------------------------------------
/** @page code
@subsection md5sum_s_s
Returns the md5 sum of a string.
Arguments: s(string) -> s(string)
@param[in] string is a string
@param[out] md5sum is a string
@code
($sum)strlen($str);
@endcode
*/
// none
void md5sum_s_s(CStateInstance* entity, CScriptStack& stack)
{
std::string str = (std::string)stack.top();
std::string value = NLMISC::getMD5((uint8*)&str[0], str.size() ).toString();
nlinfo(value.c_str());
stack.top() = value;
}
//----------------------------------------------------------------------------
/** @page code
@subsection strlen_s_f
Returns the length of a string.
@ -1291,6 +1318,7 @@ std::map<std::string, FScrptNativeFunc> nfGetStaticNativeFunctions()
REGISTER_NATIVE_FUNC(functions, sqrt_f_f);
REGISTER_NATIVE_FUNC(functions, exp_f_f);
REGISTER_NATIVE_FUNC(functions, pow_ff_f);
REGISTER_NATIVE_FUNC(functions, md5sum_s_s);
REGISTER_NATIVE_FUNC(functions, strlen_s_f);
REGISTER_NATIVE_FUNC(functions, substr_sff_s);
REGISTER_NATIVE_FUNC(functions, strtof_s_f);

View file

@ -91,6 +91,7 @@
#include "dyn_chat_egs.h"
#include "pvp_manager/pvp.h"
#include "pvp_manager/pvp_manager_2.h"
#include "player_manager/admin_properties.h"
#include "shop_type/offline_character_command.h"
#include "player_manager/item_service_manager.h"
@ -107,6 +108,10 @@
// Externs
//
// Max number of user channel character can be have
#define NB_MAX_USER_CHANNELS 2
extern CPlayerManager PlayerManager;
extern CCreatureManager CreatureManager;
extern CPlayerService *PS;
@ -158,6 +163,8 @@ AdminCommandsInit[] =
// player character accessible commands
"teamInvite", true,
"guildInvite", true,
"roomInvite", true,
"roomKick", true,
"setGuildMessage", true,
"clearGuildMessage", true,
"dodge", true,
@ -166,6 +173,8 @@ AdminCommandsInit[] =
"resurrected", true,
"validateRespawnPoint", true,
"summonPet", true,
"connectUserChannel", true,
"addPetAnimal", true,
"addSkillPoints", true,
@ -344,12 +353,14 @@ AdminCommandsInit[] =
"eventSetBotName", true,
"eventSetBotScale", true,
"eventSetNpcGroupAggroRange", true,
"eventSetNpcGroupEmote", true,
"eventSetFaunaBotAggroRange", true,
"eventResetFaunaBotAggroRange", true,
"eventSetBotCanAggro", true,
"eventSetItemCustomText", true,
"eventResetItemCustomText", true,
"eventSetBotSheet", true,
// "eventSetBotVPx", true,
"eventSetBotFaction", true,
"eventSetBotFameByKill", true,
"dssTarget", true, //ring stuff
@ -2812,6 +2823,13 @@ void cbClientAdmin (NLNET::CMessage& msgin, const std::string &serviceName, NLNE
return;
}
if (onTarget && !c->haveAnyPrivilege())
{
nlinfo("ADMIN: Player %s doesn't have privilege to execute /b command onTarget '%s' ", eid.toString().c_str(), cmdName.c_str());
chatToPlayer (eid, "You don't have privilege to execute this command");
return;
}
if (!cmd->ForwardToservice.empty())
{
// we need to forward the command to another service
@ -2849,12 +2867,14 @@ void cbClientAdmin (NLNET::CMessage& msgin, const std::string &serviceName, NLNE
{
log_Command_ExecOnTarget(c->getTarget(), cmdName, arg);
res += c->getTarget().toString();
targetEid = c->getTarget();
targetName = NLMISC::toString("(%s,%s)", c->getTarget().toString().c_str(), CEntityIdTranslator::getInstance()->getByEntity(c->getTarget()).toString().c_str());
}
else
{
log_Command_Exec(cmdName, arg);
res += eid.toString();
targetEid = eid;
targetName = string("Himself");
}
res += " ";
@ -2865,7 +2885,11 @@ void cbClientAdmin (NLNET::CMessage& msgin, const std::string &serviceName, NLNE
TLogContext_Item_Command itemCtx(onTarget ? c->getTarget() : eid);
TLogContext_Character_BuyRolemasterPhrase characterCtx(onTarget ? c->getTarget() : eid);
std::string csName = CEntityIdTranslator::getInstance()->getByEntity(eid).toString();
NLMISC::CSString cs_res = CSString(res);
cs_res = cs_res.replace("#player", eid.toString().c_str());
cs_res = cs_res.replace("#target", targetEid.toString().c_str());
res = (string)cs_res;
nlinfo ("ADMIN: Player (%s,%s) will execute client admin command '%s' on target %s", eid.toString().c_str(), csName.c_str(), res.c_str(), targetName.c_str());
CLightMemDisplayer *CmdDisplayer = new CLightMemDisplayer("CmdDisplayer");
@ -2941,6 +2965,13 @@ void cbClientAdminOffline (NLNET::CMessage& msgin, const std::string &serviceNam
return;
}
if (!c->haveAnyPrivilege())
{
nlinfo("ADMIN: Player %s doesn't have privilege to execute /c command '%s' ", eid.toString().c_str(), cmdName.c_str());
chatToPlayer (eid, "You don't have privilege to execute this command");
return;
}
// find the character eid
CEntityId charEid = CEntityIdTranslator::getInstance()->getByEntity(characterName);
if (charEid == CEntityId::Unknown)
@ -4161,22 +4192,80 @@ ENTITY_VARIABLE (Invulnerable, "Invulnerable mode, invulnerability too all")
}
//----------------------------------------------------------------------------
ENTITY_VARIABLE (ShowFactionChannels, "Show faction channels")
NLMISC_COMMAND (ShowFactionChannels, "Show faction channels", "<csr id> <channel> <0|1>")
{
ENTITY_GET_CHARACTER
if (args.size() != 3)
return false;
GET_CHARACTER
if (get)
// PVP_CLAN::TPVPClan channelClan = PVP_CLAN::fromString( args[1] );
bool display = (args[2]=="1" || strlwr(args[2])=="on" || strlwr(args[2])=="true" );
TChanID channel = CPVPManager2::getInstance()->getFactionDynChannel(args[1]);
if (channel == DYN_CHAT_INVALID_CHAN)
{
value = c->showFactionChannelsMode()?"1":"0";
log.displayNL("Invalid Faction name: '%s'", args[1].c_str());
return false;
}
CPVPManager2::getInstance()->addRemoveFactionChannelToUserWithPriviledge(channel, c, display);
nlinfo ("%s %s now in show %s channel mode", eid.toString().c_str(), display?"is":"isn't", channel.toString().c_str());
return true;
}
//----------------------------------------------------------------------------
// If channel not exists create it
NLMISC_COMMAND (connectUserChannel, "Connect to user channels", "<user id> <channel_name> [<pass>]")
{
if ((args.size() < 2) || (args.size() > 3))
return false;
GET_CHARACTER
CPVPManager2 *inst = CPVPManager2::getInstance();
string pass;
string name = NLMISC::toLower(args[1]);
TChanID channel = CPVPManager2::getInstance()->getUserDynChannel(name);
if (args.size() < 3)
pass = name;
else
pass = args[2];
if ( (channel == DYN_CHAT_INVALID_CHAN) && (pass != string("*")) && (pass != string("***")) )
channel = inst->createUserChannel(name, pass);
if (channel != DYN_CHAT_INVALID_CHAN)
{
if (value=="1" || value=="on" || strlwr(value)=="true" )
c->setShowFactionChannelsMode(true);
else if (value=="0" || value=="off" || strlwr(value)=="false" )
c->setShowFactionChannelsMode(false);
nlinfo ("%s %s now in show faction channel mode", entity.toString().c_str(), c->showFactionChannelsMode()?"is":"isn't");
string channelPass = inst->getPassUserChannel(channel);
if ( (channel != DYN_CHAT_INVALID_CHAN) && (pass == string("***")) && (c->havePriv(":DEV:") || c->havePriv(":SGM:") || c->havePriv(":GM:") || c->havePriv(":EM:")))
{
inst->deleteUserChannel(name);
}
else if (channelPass == pass)
{
std::vector<TChanID> userChannels = inst->getCharacterUserChannels(c);
if (userChannels.size() >= NB_MAX_USER_CHANNELS)
{
inst->removeFactionChannelForCharacter(userChannels[0], c, true);
}
inst->addFactionChannelToCharacter(channel, c, true, true);
}
else if (pass == string("*"))
{
inst->removeFactionChannelForCharacter(channel, c, true);
}
else
log.displayNL("You don't have rights to connect to channel %s", name.c_str());
return true;
}
return false;
}
//----------------------------------------------------------------------------
@ -4194,6 +4283,8 @@ ENTITY_VARIABLE (PriviledgePVP, "Priviledge Pvp Mode")
c->setPriviledgePVP(true);
else if (value=="0" || value=="off" || strlwr(value)=="false" )
c->setPriviledgePVP(false);
// c->setPVPRecentActionFlag();
CPVPManager2::getInstance()->setPVPModeInMirror(c);
nlinfo ("%s %s now in pvp mode", entity.toString().c_str(), c->priviledgePVP()?"is":"isn't");
}
}
@ -4382,6 +4473,90 @@ NLMISC_COMMAND(listGuildMembers, "display guild members list", "<csr eid> <guild
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND(roomInvite, "send a room invite to a player character", "<eid> <member name>")
{
if(args.size() != 2 )
return false;
CEntityId eId;
eId.fromString(args[0].c_str());
CCharacter * user = PlayerManager.getChar( eId );
if (!user)
{
log.displayNL("<ROOMINVITE>'%s' is not a valid char. Cant process command",eId.toString().c_str());
return true;
}
if (!user->getEnterFlag())
{
log.displayNL("'%s' is not entered", eId.toString().c_str());
return true;
}
if (!TheDataset.isAccessible(user->getEntityRowId()))
{
log.displayNL("'%s' is not valid in mirror", eId.toString().c_str());
return true;
}
CCharacter * target = PlayerManager.getCharacterByName(CShardNames::getInstance().makeFullNameFromRelative(user->getHomeMainlandSessionId(), args[1]));
if(target == 0 || target->getEnterFlag() == false )
{
CCharacter::sendDynamicSystemMessage( user->getId(), "TEAM_INVITED_CHARACTER_MUST_BE_ONLINE" );
return true;
}
SM_STATIC_PARAMS_1(params, STRING_MANAGER::player);
params[0].setEIdAIAlias( user->getId(), CAIAliasTranslator::getInstance()->getAIAlias(user->getId()) );
CCharacter::sendDynamicSystemMessage(target->getId(), "ROOM_INVITED_BY", params);
params[0].setEIdAIAlias( target->getId(), CAIAliasTranslator::getInstance()->getAIAlias(target->getId()) );
CCharacter::sendDynamicSystemMessage(user->getId(), "ROOM_YOU_INVITE", params);
user->addRoomAccessToPlayer(target->getId());
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND(roomKick, "kick player from room", "<eid> <member name>")
{
if(args.size() != 2 )
return false;
CEntityId eId;
eId.fromString(args[0].c_str());
CCharacter * user = PlayerManager.getChar( eId );
if (!user)
{
log.displayNL("<ROOMKICK>'%s' is not a valid char. Cant process command",eId.toString().c_str());
return true;
}
if (!user->getEnterFlag())
{
log.displayNL("'%s' is not entered", eId.toString().c_str());
return true;
}
if (!TheDataset.isAccessible(user->getEntityRowId()))
{
log.displayNL("'%s' is not valid in mirror", eId.toString().c_str());
return true;
}
CCharacter * target = PlayerManager.getCharacterByName(CShardNames::getInstance().makeFullNameFromRelative(user->getHomeMainlandSessionId(), args[1]));
if(target == 0 || target->getEnterFlag() == false )
{
CCharacter::sendDynamicSystemMessage( user->getId(), "TEAM_KICKED_CHARACTER_MUST_BE_ONLINE" );
return true;
}
user->removeRoomAccesToPlayer(target->getId(), false);
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND(guildInvite, "send a guild invite to a player character", "<eid> <member name>")
{
@ -5280,7 +5455,7 @@ NLMISC_COMMAND(eventCreateNpcGroup, "create an event npc group", "<player eid> <
{
orientation = (sint32)(e->getHeading() * 1000.0);
}
else
else if (args[5] != "random")
{
NLMISC::fromString(args[5], orientation);
orientation = (sint32)((double)orientation / 360.0 * (NLMISC::Pi * 2.0) * 1000.0);
@ -5393,6 +5568,36 @@ NLMISC_COMMAND(eventSetNpcGroupAggroRange, "changes the aggro range of a npc gro
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND(eventSetNpcGroupEmote, "Set emote animation to a npc group", "<bot eid> <emote>")
{
if (args.size() < 2) return false;
GET_ENTITY
CEntityId entityId(args[0]);
uint32 instanceNumber = e->getInstanceNumber();
std::vector<std::string> args2;
args2.push_back(args[0]);
args2.push_back(NLMISC::toString("()emote(\"%s\",\"%s\");", entityId.toString().c_str(), args[1].c_str()));
uint32 nbString = (uint32)args2.size();
CMessage msgout("EVENT_NPC_GROUP_SCRIPT");
uint32 messageVersion = 1;
msgout.serial(messageVersion);
msgout.serial(nbString);
for (uint32 i=0; i<nbString; ++i)
{
string arg = args2[i];
msgout.serial(arg);
}
CWorldInstances::instance().msgToAIInstance2(instanceNumber, msgout);
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND(eventSetFaunaBotAggroRange, "changes the aggro range of a fauna bot", "<bot eid> <not hungry range> [<hungry range> [<hunting range>]]")
{
@ -5495,6 +5700,27 @@ NLMISC_COMMAND(eventSetBotSheet, "Change the sheet of a bot", "<bot eid> <sheet
return true;
}
//----------------------------------------------------------------------------
/*NLMISC_COMMAND(eventSetBotVPx, "Change the VPx of a bot", "<bot eid> <vpx>")
{
if (args.size() < 2) return false;
GET_ENTITY
uint32 instanceNumber = e->getInstanceNumber();
uint32 messageVersion = 3;
string botName = args[0];
string vpx = args[1];
CMessage msgout("EVENT_BOT_VPX");
msgout.serial(messageVersion);
msgout.serial(botName);
msgout.serial(vpx);
CWorldInstances::instance().msgToAIInstance2(instanceNumber, msgout);
return true;
}
*/
//----------------------------------------------------------------------------
extern sint32 clientEventSetItemCustomText(CCharacter* character, INVENTORIES::TInventory inventory, uint32 slot, ucstring const& text);

View file

@ -753,8 +753,13 @@ void CBuildingManager::triggerTeleport(CCharacter * user, uint16 index)
IDestination * dest = entry.Destination;
uint16 ownerIdx = entry.OwnerIndex;
// remove the request
_TriggerRequests.erase( it );
// remove the requests
while ( it != _TriggerRequests.end() )
{
_TriggerRequests.erase( it );
it = _TriggerRequests.find( user->getEntityRowId() );
}
if ( !dest->isUserAllowed(user,ownerIdx) )
{
return;

View file

@ -75,7 +75,7 @@ bool IBuildingPhysical::build( const NLLIGO::IPrimitive* prim, CBuildingParseDat
}
//----------------------------------------------------------------------------
bool IBuildingPhysical::addUser(CCharacter * user,uint16 roomIdx,uint16 ownerIdx, sint32 & cellId)
bool IBuildingPhysical::addUser(CCharacter * user, uint16 roomIdx, uint16 ownerIdx, sint32 & cellId)
{
/// simply get the cell matching the parameters
if ( roomIdx >= _Rooms.size() )
@ -88,6 +88,18 @@ bool IBuildingPhysical::addUser(CCharacter * user,uint16 roomIdx,uint16 ownerIdx
nlwarning("<BUILDING>Invalid owner idx %u count is %u",ownerIdx,_Rooms[roomIdx].Cells.size());
return false;
}
CCharacter *owner;
if (ownerIdx < _Players.size())
{
owner = PlayerManager.getChar(_Players[ownerIdx] );
}
else
{
owner = user;
}
// if the room is not already instanciated, we have to do it
if ( _Rooms[roomIdx].Cells[ownerIdx] == 0 )
{
@ -101,7 +113,7 @@ bool IBuildingPhysical::addUser(CCharacter * user,uint16 roomIdx,uint16 ownerIdx
// init the room
if( !roomInstance->create(this,roomIdx,ownerIdx, _Rooms[roomIdx].Cells[ownerIdx]) )
return false;
roomInstance->addUser(user);
roomInstance->addUser(user, owner);
}
else
{
@ -111,7 +123,7 @@ bool IBuildingPhysical::addUser(CCharacter * user,uint16 roomIdx,uint16 ownerIdx
nlwarning("<BUILDING>%s invalid room cell %d.",user->getId().toString().c_str(),_Rooms[roomIdx].Cells[ownerIdx]);
return false;
}
roomInstance->addUser(user);
roomInstance->addUser(user, owner);
}
user->setBuildingExitZone( _DefaultExitSpawn );
@ -517,7 +529,12 @@ bool CBuildingPhysicalPlayer::isUserAllowed(CCharacter * user, uint16 ownerId, u
{
nlassert(user);
nlassert(ownerId < _Players.size() );
return ( user->getId() == _Players[ownerId] );
CCharacter * owner = PlayerManager.getChar( _Players[ownerId] );
if (owner)
return ( (user->getId() == _Players[ownerId]) || owner->playerHaveRoomAccess(user->getId()) );
else
return false;
}
//----------------------------------------------------------------------------

View file

@ -110,6 +110,9 @@ protected:
/// the players in the building
std::vector<TDataSetRow> _UsersInside;
// list of players
std::vector<NLMISC::CEntityId> _Players;
};
@ -191,7 +194,7 @@ public:
private:
virtual void initRooms();
std::vector<NLMISC::CEntityId> _Players;
};
#include "building_physical_inline.h"

View file

@ -59,7 +59,7 @@ void CRoomInstanceCommon::removeUser( CCharacter* user )
}
//----------------------------------------------------------------------------
void CRoomInstanceCommon::addUser( CCharacter* user )
void CRoomInstanceCommon::addUser( CCharacter* user, CCharacter* owner )
{
BOMB_IF( !user, "<BUILDING> null character!", return );
@ -100,7 +100,7 @@ void CRoomInstanceGuild::removeUser( CCharacter* user )
}
//----------------------------------------------------------------------------
void CRoomInstanceGuild::addUser( CCharacter* user )
void CRoomInstanceGuild::addUser( CCharacter* user, CCharacter* owner )
{
BOMB_IF( !user, "<BUILDING> null character!", return );
@ -141,21 +141,64 @@ void CRoomInstancePlayer::removeUser( CCharacter* user )
return;
}
TVectorParamCheck titleParams;
TVectorParamCheck textParams;
uint32 userId = PlayerManager.getPlayerId( user->getId() );
std::string name = "CLOSE_URL";
//send command to close webig
ucstring phrase = ucstring("CLOSE_URL(){[WEB : app_ryzhome action=quit_room]}");
NLNET::CMessage msgout("SET_PHRASE");
msgout.serial(name);
msgout.serial(phrase);
sendMessageViaMirror("IOS", msgout);
uint32 titleId = STRING_MANAGER::sendStringToUser(userId, "ANSWER_OK", titleParams);
uint32 textId = STRING_MANAGER::sendStringToUser(userId, "CLOSE_URL", textParams);
PlayerManager.sendImpulseToClient(user->getId(), "USER:POPUP", titleId, textId);
--_RefCount;
if ( _RefCount == 0 )
{
playerBuilding->resetRoomCell( _RoomIdx , user->getId() );
playerBuilding->resetRoomCell( _RoomIdx , user->getInRoomOfPlayer());
release();
}
user->setInRoomOfPlayer(CEntityId::Unknown);
}
//----------------------------------------------------------------------------
void CRoomInstancePlayer::addUser( CCharacter* user )
void CRoomInstancePlayer::addUser( CCharacter* user, CCharacter* owner )
{
BOMB_IF( !user, "<BUILDING> null character!", return );
// open room inventory window
PlayerManager.sendImpulseToClient(user->getId(), "ITEM:OPEN_ROOM_INVENTORY");
if (owner)
{
owner->removeRoomAccesToPlayer(user->getId(),false);
user->setInRoomOfPlayer(owner->getId());
}
else
{
// Very rare case
owner = user;
}
// solve bot names for title and text
TVectorParamCheck titleParams;
TVectorParamCheck textParams;
// send the popup message
uint32 userId = PlayerManager.getPlayerId( user->getId() );
std::string name = "RYZHOME_URL";
ucstring phrase = "RYZHOME_URL(){[WEB : app_ryzhome user=" + owner->getName().toString() + "]}";
NLNET::CMessage msgout("SET_PHRASE");
msgout.serial(name);
msgout.serial(phrase);
sendMessageViaMirror("IOS", msgout);
uint32 titleId = STRING_MANAGER::sendStringToUser(userId, "ANSWER_OK", titleParams);
uint32 textId = STRING_MANAGER::sendStringToUser(userId, "RYZHOME_URL", textParams);
PlayerManager.sendImpulseToClient(user->getId(), "USER:POPUP", titleId, textId);
++_RefCount;
}

View file

@ -37,7 +37,7 @@ public:
/// remove a user from the room
virtual void removeUser( CCharacter* user ) = 0;
/// add a user in the room
virtual void addUser( CCharacter* user ) = 0;
virtual void addUser( CCharacter* user, CCharacter* owner ) = 0;
/// create the room from a building
virtual bool create( IBuildingPhysical * building, uint16 roomIdx, uint16 ownerIdx , sint32 cell);
/// return true if the room is valid
@ -79,7 +79,7 @@ public:
private:
virtual void removeUser( CCharacter* user );
virtual void addUser( CCharacter* user );
virtual void addUser( CCharacter* user, CCharacter* owner );
};
/// a guild room
@ -99,7 +99,7 @@ public:
private:
virtual bool create( IBuildingPhysical * building, uint16 roomIdx, uint16 ownerIdx , sint32 cell);
virtual void removeUser( CCharacter* user );
virtual void addUser( CCharacter* user );
virtual void addUser( CCharacter* user, CCharacter* owner );
EGSPD::TGuildId _GuildId;
};
@ -117,7 +117,7 @@ public:
private:
virtual bool create( IBuildingPhysical * building, uint16 roomIdx, uint16 ownerIdx , sint32 cell);
virtual void removeUser( CCharacter* user );
virtual void addUser( CCharacter* user );
virtual void addUser( CCharacter* user, CCharacter* owner );
/// owner player
NLMISC::CEntityId _Player;
};

View file

@ -359,6 +359,10 @@ void CBankAccessor_PLR::TUSER::init(ICDBStructNode *parent)
nlassert(node != NULL);
_DEFAULT_WEIGHT_HANDS = node;
node = parent->getNode( ICDBStructNode::CTextId("IS_INVISIBLE"), false );
nlassert(node != NULL);
_IS_INVISIBLE = node;
node = parent->getNode( ICDBStructNode::CTextId("COUNTER"), false );
nlassert(node != NULL);
_COUNTER = node;

View file

@ -490,6 +490,7 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C
ICDBStructNode *_IS_NEWBIE;
ICDBStructNode *_IS_TRIAL;
ICDBStructNode *_DEFAULT_WEIGHT_HANDS;
ICDBStructNode *_IS_INVISIBLE;
ICDBStructNode *_COUNTER;
TSKILL_POINTS_ _SKILL_POINTS_[4];
TFACTION_POINTS_ _FACTION_POINTS_[6];
@ -975,6 +976,20 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C
{
return _COUNTER;
}
void setIS_INVISIBLE(CCDBSynchronised &dbGroup, bool value, bool forceSending = false)
{
_setProp(dbGroup, _IS_INVISIBLE, value, forceSending);
}
bool getIS_INVISIBLE(const CCDBSynchronised &dbGroup)
{
bool value;
_getProp(dbGroup, _IS_INVISIBLE, value);
return value;
}
TSKILL_POINTS_ &getSKILL_POINTS_(uint32 index)
{
nlassert(index < 4);

View file

@ -197,8 +197,7 @@ bool CDynChatEGS::addSession(TChanID chan, const TDataSetRow &client, bool write
CEntityBase *eb = CEntityBaseManager::getEntityBasePtr(client);
if (!eb)
{
nlwarning("no client %s",client.toString().c_str());
addClient(client);
return false;
}
CDynChatSession *session = _DynChat.addSession(chan, client);
if (!session)

View file

@ -389,6 +389,7 @@ CVariable<float> ForageExplosionDamage( "egs","ForageExplosionDamage", "Max HP h
CVariable<sint32> FameByKill( "egs","FameByKill", "Number of fame point lost for a kill", -5000, true );
CVariable<sint32> PVPFameRequired ("egs","PVPFameRequired", "Minimum of positive or negative fame for PVP", 25, 0, true );
NLMISC::CVariable<NLMISC::TGameCycle>DuelQueryDuration ("egs","DuelQueryDuration", "duration in ticks of a duel requests", 600, 0, true );
NLMISC::CVariable<NLMISC::TGameCycle> PVPZoneEnterBufferTime ("egs","PVPZoneEnterBufferTime", "duration in ticks of the time buffer triggered when someone enters a PVP zone", 300, 0, true );
NLMISC::CVariable<NLMISC::TGameCycle> PVPZoneLeaveBufferTime ("egs","PVPZoneLeaveBufferTime", "duration in ticks of the time buffer triggered when someone leaves a PVP zone", 9000, 0, true );

View file

@ -318,6 +318,7 @@ extern NLMISC::CVariable<float> CristalMoneyFactor;
/// PVP
extern NLMISC::CVariable<bool> AllowPVP;
extern NLMISC::CVariable<sint32> PVPFameRequired;
extern NLMISC::CVariable<NLMISC::TGameCycle> DuelQueryDuration ;
extern NLMISC::CVariable<NLMISC::TGameCycle> PVPZoneEnterBufferTime;
extern NLMISC::CVariable<NLMISC::TGameCycle> PVPZoneLeaveBufferTime;

View file

@ -529,10 +529,6 @@ void cbClientReady( CMessage& msgin, const std::string &serviceName, NLNET::TSer
}
}
c->onConnection();
CPVPManager2::getInstance()->sendFactionWarsToClient( c );
CPVPManager2::getInstance()->addOrRemoveFactionChannel( c );
} // cbClientReady //
@ -681,10 +677,15 @@ void finalizeClientReady( uint32 userId, uint32 index )
}
}
CPVPManager2::getInstance()->updateFactionChannel( c );
CPVPManager2::getInstance()->setPVPModeInMirror( c );
c->updatePVPClanVP();
// for GM player, trigger a 'infos' command to remember their persistent state
if (!PlayerManager.getPlayer(uint32(c->getId().getShortId())>>4)->getUserPriv().empty())
CCommandRegistry::getInstance().execute(toString("infos %s", c->getId().toString().c_str()).c_str(), InfoLog(), true);
c->setFinalized(true);
} // finalizeClientReady //

View file

@ -336,7 +336,7 @@ void CGuildMemberModule::_inviteCharacterInGuild(CGuildCharProxy& invitor, CGuil
{
SM_STATIC_PARAMS_2( params, STRING_MANAGER::player, STRING_MANAGER::faction );
params[0].setEIdAIAlias( target.getId(), CAIAliasTranslator::getInstance()->getAIAlias( target.getId()) );
params[1].Enum = invitedAllegiance.first;
params[1].Enum = PVP_CLAN::getFactionIndex(invitedAllegiance.first);
invitor.sendSystemMessage("GUILD_ICOMPATIBLE_ALLEGIANCE",params);
return;
}
@ -344,7 +344,7 @@ void CGuildMemberModule::_inviteCharacterInGuild(CGuildCharProxy& invitor, CGuil
{
SM_STATIC_PARAMS_2( params, STRING_MANAGER::player, STRING_MANAGER::faction );
params[0].setEIdAIAlias( target.getId(), CAIAliasTranslator::getInstance()->getAIAlias( target.getId()) );
params[1].Enum = invitedAllegiance.second;
params[1].Enum = PVP_CLAN::getFactionIndex(invitedAllegiance.second);
invitor.sendSystemMessage("GUILD_ICOMPATIBLE_ALLEGIANCE",params);
return;
}

View file

@ -174,7 +174,7 @@ bool CMissionStepAIMsg::buildStep( uint32 line, const std::vector< std::string >
MISLOGSYNTAXERROR("<msg name>");
return false;
}
Msg = CMissionParser::getNoBlankString(script[1]);
_Msg = CMissionParser::getNoBlankString(script[1]);
return true;
}
@ -185,8 +185,8 @@ uint CMissionStepAIMsg::processEvent( const TDataSetRow & userRow, const CMissio
if( event.Type == CMissionEvent::AIMsg )
{
CMissionEventAIMsg & eventSpe = (CMissionEventAIMsg &) event;
nlwarning("CMissionStepAIMsg : Message from event = '%s', message of mission = '%s'", eventSpe.Msg.c_str(), Msg.c_str());
if ( eventSpe.Msg == Msg )
nlwarning("CMissionStepAIMsg : Message from event = '%s', message of mission = '%s'", eventSpe.Msg.c_str(), _Msg.c_str());
if ( eventSpe.Msg == _Msg )
{
LOGMISSIONSTEPSUCCESS("wait_msg");
return 1;

View file

@ -56,7 +56,7 @@ class CMissionStepEscort : public IMissionStepTemplate
class CMissionStepAIMsg : public IMissionStepTemplate
{
std::string Msg;
std::string _Msg;
virtual bool buildStep( uint32 line, const std::vector< std::string > & script, CMissionGlobalParsingData & globalData, CMissionSpecificParsingData & missionData );

View file

@ -52,7 +52,11 @@ void CMissionTeam::updateUsersJournalEntry()
void CMissionTeam::clearUsersJournalEntry()
{
CTeam * team = TeamManager.getRealTeam( _TeamId );
nlassert(team);
if ( !team )
{
nlwarning( "<MISSIONS>cant find team ID : %d", _TeamId );
return;
}
for ( list<CEntityId>::const_iterator it = team->getTeamMembers().begin(); it != team->getTeamMembers().end();++it )
{

View file

@ -1555,15 +1555,18 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
logOnFail = false;
}
}
uint k = 0;
for ( ; k < team->getMissions().size(); k++ )
else
{
if ( team->getMissions()[k]->getTemplateId() == templ->Alias )
uint k = 0;
for ( ; k < team->getMissions().size(); k++ )
{
if ( team->getMissions()[k]->getTemplateId() == templ->Alias )
break;
}
if (k != team->getMissions().size())
break;
}
if (k != team->getMissions().size())
break;
}
}
if ( j == Prerequisits.RunningMissions[i].Missions.size() )

View file

@ -395,7 +395,7 @@ void CFaberPhrase::apply()
uint32 nbMpNeedeInPlan = 0;
uint32 neededMp = (uint32)_RootFaberPlan->Faber->NeededMps.size();
for( uint mp = 0; mp < _RootFaberPlan->Faber->NeededMps.size(); ++mp )
for( uint mp = 0; mp < neededMp; ++mp )
{
//for each type of Mp needed
nbMpNeedeInPlan += _RootFaberPlan->Faber->NeededMps[ mp ].Quantity;
@ -411,15 +411,15 @@ void CFaberPhrase::apply()
nbMp = (sint32)_MpsFormula.size();
nbMpNeedeInPlan = 0;
uint32 nbMpForumulaNeedeInPlan = 0;
neededMp = (uint32)_RootFaberPlan->Faber->NeededMpsFormula.size();
for( uint mp = 0; mp < _RootFaberPlan->Faber->NeededMpsFormula.size(); ++mp )
for( uint mp = 0; mp < neededMp; ++mp )
{
//for each type of Mp needed
nbMpNeedeInPlan += _RootFaberPlan->Faber->NeededMpsFormula[ mp ].Quantity;
nbMpForumulaNeedeInPlan += _RootFaberPlan->Faber->NeededMpsFormula[ mp ].Quantity;
}
if( nbMpNeedeInPlan != _MpsFormula.size() )
if( nbMpForumulaNeedeInPlan != _MpsFormula.size() )
{
nlwarning("<CFaberPhrase::apply> Craft plan %s need %d Raw Material Formula and client send %d Raw Material Formula", c->getCraftPlan().toString().c_str(), _RootFaberPlan->Faber->NeededMpsFormula.size(), _MpsFormula.size() );
PHRASE_UTILITIES::sendDynamicSystemMessage(_ActorRowId, "RAW_MATERIAL_MISSING");
@ -454,6 +454,105 @@ void CFaberPhrase::apply()
return;
}
neededMp = _RootFaberPlan->Faber->NeededMps.size();
EGSPD::CPeople::TPeople civRestriction = _RootFaberPlan->CivRestriction;
uint32 usedMp=0;
vector< const CStaticItem * > usedMps = _Mps;
for( uint mp = 0; mp < neededMp; ++mp )
{
nlinfo("MP #%d\n", mp);
//for each type of Mp needed
for( uint k = 0; k < _RootFaberPlan->Faber->NeededMps[ mp ].Quantity; ++k )
{
nlinfo(" usedmps : %d", usedMps.size());
bool found_mp = false;
for(uint u_mp = 0; u_mp < usedMps.size(); ++u_mp)
{
// for each Mp of one type (we have Quantity by type)
uint32 NumMpParameters = (uint32)usedMps[u_mp]->Mp->MpFaberParameters.size();
// for each Faber parameters in Mp
for( uint j = 0; j < NumMpParameters; ++j )
{
// check if Mp Type match with Faber waiting Type
if( _RootFaberPlan->Faber->NeededMps[mp].MpType == usedMps[u_mp]->Mp->MpFaberParameters[j].MpFaberType )
{
found_mp = true;
usedMp++;
break;
}
}
if (found_mp)
{
// Bypass if : Plan is common
if ( civRestriction != EGSPD::CPeople::Common )
{
switch (usedMps[u_mp]->Mp->Ecosystem)
{
// I can't found some thing to do this ugly translation.
case ECOSYSTEM::desert:
if (civRestriction != EGSPD::CPeople::Fyros)
{
nlwarning( "<CFaberPhrase build> bad civilisation mp for plan brick %s", _RootFaberPlan->SheetId.toString().c_str() );
stop();
return;
}
break;
case ECOSYSTEM::forest:
if (civRestriction != EGSPD::CPeople::Matis)
{
nlwarning( "<CFaberPhrase build> bad civilisation mp for plan brick %s", _RootFaberPlan->SheetId.toString().c_str() );
stop();
return;
}
break;
case ECOSYSTEM::lacustre:
if (civRestriction != EGSPD::CPeople::Tryker)
{
nlwarning( "<CFaberPhrase build> bad civilisation mp for plan brick %s", _RootFaberPlan->SheetId.toString().c_str() );
stop();
return;
}
break;
case ECOSYSTEM::jungle:
if (civRestriction != EGSPD::CPeople::Zorai)
{
nlwarning( "<CFaberPhrase build> bad civilisation mp for plan brick %s", _RootFaberPlan->SheetId.toString().c_str() );
stop();
return;
}
break;
}
}
usedMps.erase(usedMps.begin()+u_mp);
break;
}
}
if (!found_mp)
{
nlinfo("NOT FOUND : wanted %d\n", _RootFaberPlan->Faber->NeededMps[ mp ].MpType);
}
}
}
if (!usedMps.empty())
{
nlinfo("final usedmps : %d", usedMps.size());
nlwarning( "<CFaberPhrase build> could not build action for plan brick %s", _RootFaberPlan->SheetId.toString().c_str() );
stop();
return;
}
if (usedMp != nbMpNeedeInPlan)
{
nlwarning( "<CFaberPhrase build> could not build action for plan brick %s", _RootFaberPlan->SheetId.toString().c_str() );
stop();
return;
}
// spend energies
SCharacteristicsAndScores &focus = c->getScores()._PhysicalScores[SCORES::focus];
if ( focus.Current != 0)

View file

@ -364,6 +364,13 @@ CCharacter::CCharacter(): CEntityBase(false),
_NbStaticActiveEffects = 0;
_StaticActionInProgress = false;
_NbUserChannels = 0;
_LoadingFinish = false;
_PVPFlagAlly = 0;
_PVPFlagEnemy = 0;
// init faber plans
// _KnownFaberPlans.resize(64,(uint64)0); //64*64 bits
@ -630,12 +637,13 @@ CCharacter::CCharacter(): CEntityBase(false),
_HaveToUpdatePVPMode = false;
_SessionId = TSessionId(0);
_CurrentSessionId = _SessionId;
_FactionChannelMode = true;
_PvPSafeZoneActive = false;
// For client/server contact list communication
_ContactIdPool= 0;
_inRoomOfPlayer = CEntityId::Unknown;
for(uint i = 0; i < BRICK_FAMILIES::NbFamilies; ++i )
_BrickFamilyBitField[i] = 0;
_InterfacesFlagsBitField = 0;
@ -762,17 +770,77 @@ void CCharacter::initPDStructs()
//-----------------------------------------------
void CCharacter::updatePVPClanVP() const
{
TYPE_PVP_CLAN propPvpClanTemp = 0;
uint32 maxFameCiv = 0;
uint8 civOfMaxFame = 255;
uint32 maxFameCult = 0;
uint8 cultOfMaxFame = 255;
for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++)
{
sint32 fame = CFameInterface::getInstance().getFameIndexed(_Id, fameIdx);
if (fameIdx < 4)
{
if ((uint32)abs(fame) >= maxFameCiv)
{
civOfMaxFame = fameIdx;
maxFameCiv = abs(fame);
}
}
else
{
if ((uint32)abs(fame) >= maxFameCult)
{
cultOfMaxFame = fameIdx - 4;
maxFameCult = abs(fame);
}
}
if (fame >= PVPFameRequired*6000)
{
propPvpClanTemp |= (TYPE_PVP_CLAN(1) << (2*TYPE_PVP_CLAN(fameIdx)));
}
else if (fame <= -PVPFameRequired*6000)
{
propPvpClanTemp |= (TYPE_PVP_CLAN(1) << ((2*TYPE_PVP_CLAN(fameIdx))+1));
}
if (getPvPRecentActionFlag())
{
uint8 flagAlly = (_PVPFlagAlly & (1 << TYPE_PVP_CLAN(fameIdx))) >> TYPE_PVP_CLAN(fameIdx);
uint8 flagEnemy = (_PVPFlagEnemy & (1 << TYPE_PVP_CLAN(fameIdx))) >> TYPE_PVP_CLAN(fameIdx);
propPvpClanTemp |= flagAlly << (2*TYPE_PVP_CLAN(fameIdx));
propPvpClanTemp |= flagEnemy << ((2*TYPE_PVP_CLAN(fameIdx))+1);
}
}
propPvpClanTemp |= TYPE_PVP_CLAN(civOfMaxFame) << (2*TYPE_PVP_CLAN(7));
propPvpClanTemp |= TYPE_PVP_CLAN(cultOfMaxFame) << (2*TYPE_PVP_CLAN(8));
CMirrorPropValue<TYPE_PVP_CLAN> propPvpClan( TheDataset, TheDataset.getDataSetRow(_Id), DSPropertyPVP_CLAN );
if( getAllegiance().first >= PVP_CLAN::BeginCults && getAllegiance().first <= PVP_CLAN::EndCults )
{
propPvpClan = (uint8) getAllegiance().first;
}
else
{
propPvpClan = (uint8) getAllegiance().second;
}
propPvpClan = (uint32)propPvpClanTemp;
}
TYPE_PVP_CLAN CCharacter::getPVPFamesAllies()
{
TYPE_PVP_CLAN propPvpClanTemp = 0;
for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++)
if (CFameInterface::getInstance().getFameIndexed(_Id, fameIdx) >= PVPFameRequired*6000)
propPvpClanTemp |= TYPE_PVP_CLAN(1) << TYPE_PVP_CLAN(fameIdx);
if (getPvPRecentActionFlag())
return propPvpClanTemp | _PVPFlagAlly;
return propPvpClanTemp;
}
TYPE_PVP_CLAN CCharacter::getPVPFamesEnemies()
{
TYPE_PVP_CLAN propPvpClanTemp = 0;
for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++)
if (CFameInterface::getInstance().getFameIndexed(_Id, fameIdx) <= -PVPFameRequired*6000)
propPvpClanTemp |= TYPE_PVP_CLAN(1) << TYPE_PVP_CLAN(fameIdx);
if (getPvPRecentActionFlag())
return propPvpClanTemp | _PVPFlagEnemy;
return propPvpClanTemp;
}
//-----------------------------------------------
@ -1382,7 +1450,8 @@ uint32 CCharacter::tickUpdate()
if (_PVPFlagLastTimeChange + waitTime < CTickEventHandler::getGameCycle())
{
CPVPManager2::getInstance()->setPVPModeInMirror(this);
CPVPManager2::getInstance()->addOrRemoveFactionChannel(this);
CPVPManager2::getInstance()->updateFactionChannel(this);
updatePVPClanVP();
_HaveToUpdatePVPMode = false;
}
}
@ -1393,6 +1462,7 @@ uint32 CCharacter::tickUpdate()
if( propPvpMode.getValue()&PVP_MODE::PvpFactionFlagged )
{
CPVPManager2::getInstance()->setPVPModeInMirror(this);
updatePVPClanVP();
}
}
}
@ -2829,117 +2899,88 @@ void CCharacter::postLoadTreatment()
// if EId translator has been initialized by SU, check contact list
{
H_AUTO(ValidateContactList);
validateContactList();
H_AUTO(ValidateContactList);
validateContactList();
}
{
H_AUTO(UpdateFlagForActiveEffect);
/* update flags for active effects */
if( _ForbidAuraUseEndDate>0 && _ForbidAuraUseStartDate==0 )
{
// thus timer won't look like infinte on client(can happen due to old save file where startDate didn't exist)
_ForbidAuraUseStartDate = CTickEventHandler::getGameCycle();
}
setPowerFlagDates();
setAuraFlagDates();
updateBrickFlagsDBEntry();
_ModifiersInDB.writeInDatabase(_PropertyDatabase);
H_AUTO(UpdateFlagForActiveEffect);
/* update flags for active effects */
if( _ForbidAuraUseEndDate>0 && _ForbidAuraUseStartDate==0 )
{
// thus timer won't look like infinte on client(can happen due to old save file where startDate didn't exist)
_ForbidAuraUseStartDate = CTickEventHandler::getGameCycle();
}
setPowerFlagDates();
setAuraFlagDates();
updateBrickFlagsDBEntry();
_ModifiersInDB.writeInDatabase(_PropertyDatabase);
}
{
H_AUTO(AddCreationBricks);
/* add starting bricks if any modification has been done */
addCreationBricks();
H_AUTO(AddCreationBricks);
/* add starting bricks if any modification has been done */
addCreationBricks();
}
{
H_AUTO(CheckCharacterAndScoresValues);
/* check character and scores are as they are supposed to be according to bricks possessed */
checkCharacAndScoresValues();
H_AUTO(CheckCharacterAndScoresValues);
/* check character and scores are as they are supposed to be according to bricks possessed */
checkCharacAndScoresValues();
}
{
H_AUTO(ComputeBestSkill);
/* compute player best skill */
computeBestSkill();
H_AUTO(ComputeBestSkill);
/* compute player best skill */
computeBestSkill();
}
{
H_AUTO(ComputeSkillUsedForDodge);
/* compute player best skill to use for dodge */
computeSkillUsedForDodge();
H_AUTO(ComputeSkillUsedForDodge);
/* compute player best skill to use for dodge */
computeSkillUsedForDodge();
}
{
H_AUTO(UpdateMagicProtectionAndResistance);
/* compute resists scores*/
updateMagicProtectionAndResistance();
H_AUTO(UpdateMagicProtectionAndResistance);
/* compute resists scores*/
updateMagicProtectionAndResistance();
}
{
H_AUTO(LoadedMissionPostLoad);
/* Call the postLoad methods for the loaded missions */
for ( map<TAIAlias, CMission*>::iterator it = getMissionsBegin(); it != getMissionsEnd(); ++it )
{
BOMB_IF( (*it).second == NULL, "Mission is NULL after load", continue );
(*it).second->onLoad();
}
H_AUTO(LoadedMissionPostLoad);
/* Call the postLoad methods for the loaded missions */
for ( map<TAIAlias, CMission*>::iterator it = getMissionsBegin(); it != getMissionsEnd(); ++it )
{
BOMB_IF( (*it).second == NULL, "Mission is NULL after load", continue );
(*it).second->onLoad();
}
}
/* setup the implicit visual property fields */
SET_STRUCT_MEMBER(_VisualPropertyA,PropertySubData.Sex,getGender());
{
H_AUTO(ComputeForageBonus);
/* compute the forage bonuses */
computeForageBonus();
H_AUTO(ComputeForageBonus);
/* compute the forage bonuses */
computeForageBonus();
}
{
H_AUTO(ComputeMiscBonus);
/* compute misc bonuses */
computeMiscBonus();
H_AUTO(ComputeMiscBonus);
/* compute misc bonuses */
computeMiscBonus();
}
{
H_AUTO(CItemServiceManager);
CItemServiceManager::getInstance()->initPersistentServices(this);
H_AUTO(CItemServiceManager);
CItemServiceManager::getInstance()->initPersistentServices(this);
}
{
H_AUTO(CheckPvPTagValidity);
if( _DeclaredCult == PVP_CLAN::Neutral || _DeclaredCult == PVP_CLAN::None )
{
if( _PVPFlag )
{
// if no cult declared and civ is not in war we remove pvp tag
if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCiv ) == false )
{
_PVPFlag = false;
_PVPFlagLastTimeChange = 0;
_PVPFlagTimeSettedOn = 0;
setPVPFlagDatabase();
_HaveToUpdatePVPMode = true;
}
}
}
H_AUTO(CheckPvPTagValidity);
if( _DeclaredCiv == PVP_CLAN::Neutral || _DeclaredCiv == PVP_CLAN::None )
{
if( _PVPFlag )
{
// if no civ declared and cult is not in war we remove pvp tag
if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCult ) == false )
{
_PVPFlag = false;
_PVPFlagLastTimeChange = 0;
_PVPFlagTimeSettedOn = 0;
setPVPFlagDatabase();
_HaveToUpdatePVPMode = true;
}
}
}
_HaveToUpdatePVPMode = true;
}
}
@ -13666,6 +13707,36 @@ void CCharacter::setFameValuePlayer(uint32 factionIndex, sint32 playerFame, sint
// _PropertyDatabase.setProp( toString("FAME:PLAYER%d:THRESHOLD", fameIndexInDatabase), sint64(float(fameMax)/FameAbsoluteMax*100) );
CBankAccessor_PLR::getFAME().getPLAYER(fameIndexInDatabase).setTHRESHOLD(_PropertyDatabase, checkedCast<sint8>(float(fameMax)/FameAbsoluteMax*100) );
}
bool canPvp = false;
for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++)
{
sint32 fame = CFameInterface::getInstance().getFameIndexed(_Id, fameIdx);
if (fame >= PVPFameRequired*6000) {
canPvp = true;
} else if (fame <= -PVPFameRequired*6000) {
canPvp = true;
}
}
if (_LoadingFinish)
{
if(!canPvp && (_PVPFlag || getPvPRecentActionFlag()) )
{
_PVPFlag = false;
_PVPFlagLastTimeChange = 0;
_PVPFlagTimeSettedOn = 0;
_PVPRecentActionTime = 0;
_HaveToUpdatePVPMode = true;
}
updatePVPClanVP();
setPVPFlagDatabase();
// handle with faction channel
CPVPManager2::getInstance()->updateFactionChannel(this);
}
}
//-----------------------------------------------
@ -14288,6 +14359,63 @@ void CCharacter::syncContactListWithCharNameChanges(const std::vector<NLMISC::CE
sendContactListInit();
}
void CCharacter::setInRoomOfPlayer(const NLMISC::CEntityId &id)
{
_inRoomOfPlayer = id;
}
const NLMISC::CEntityId& CCharacter::getInRoomOfPlayer()
{
return _inRoomOfPlayer;
}
//--------------------------------------------------------------
// CCharacter::havePlayerRoomAccess
//--------------------------------------------------------------
bool CCharacter::playerHaveRoomAccess(const NLMISC::CEntityId &id)
{
const uint size = (uint)_RoomersList.size();
for ( uint i =0 ; i < size ; ++i)
{
if ( _RoomersList[i].getShortId() == id.getShortId())
return true;
}
return false;
}
//--------------------------------------------------------------
// CCharacter::addRoomAccessToPlayer
//--------------------------------------------------------------
void CCharacter::addRoomAccessToPlayer(const NLMISC::CEntityId &id)
{
// if player not found
if (id == CEntityId::Unknown || PlayerManager.getChar(id)==NULL)
{
if ( ! (IShardUnifierEvent::getInstance() && IShardUnifierEvent::getInstance()->isCharacterOnlineAbroad(id)))
{
// player not found => message
PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, "OPERATION_OFFLINE");
return;
}
}
// check not already in list
const uint size = (uint)_RoomersList.size();
for ( uint i =0 ; i < size ; ++i)
{
if ( _RoomersList[i].getShortId() == id.getShortId())
{
return;
}
}
uint32 playerId = PlayerManager.getPlayerId(id);
_RoomersList.push_back(id);
}
//--------------------------------------------------------------
// CCharacter::addPlayerToFriendList()
//--------------------------------------------------------------
@ -14296,9 +14424,12 @@ void CCharacter::addPlayerToFriendList(const NLMISC::CEntityId &id)
// if player not found
if (id == CEntityId::Unknown || PlayerManager.getChar(id)==NULL)
{
// player not found => message
PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, "OPERATION_OFFLINE");
return;
if ( ! (IShardUnifierEvent::getInstance() && IShardUnifierEvent::getInstance()->isCharacterOnlineAbroad(id)))
{
// player not found => message
PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, "OPERATION_OFFLINE");
return;
}
}
// check not already in list
@ -14487,6 +14618,42 @@ void CCharacter::removePlayerFromIgnoreListByIndex(uint16 index)
sendMessageViaMirror ("IOS", msgName);
}
//--------------------------------------------------------------
// CCharacter::removeRoomAccesToPlayer()
//--------------------------------------------------------------
void CCharacter::removeRoomAccesToPlayer(const NLMISC::CEntityId &id, bool kick)
{
if (id == NLMISC::CEntityId::Unknown)
return;
CCharacter *target = PlayerManager.getChar(id);
for ( uint i = 0 ; i < _RoomersList.size() ; ++i)
{
if ( _RoomersList[i].getShortId() == id.getShortId() )
{
_RoomersList.erase(_RoomersList.begin() + i);
return;
}
}
if (kick & (target->getInRoomOfPlayer().getShortId() == getId().getShortId()))
{
target->setInRoomOfPlayer(CEntityId::Unknown);
if (!TheDataset.isAccessible(getEntityRowId()))
return;
const CTpSpawnZone * zone = CZoneManager::getInstance().getTpSpawnZone(target->getBuildingExitZone());
if (zone)
{
sint32 x,y,z;
float heading;
zone->getRandomPoint(x,y,z,heading);
target->tpWanted(x,y,z,true,heading);
}
}
}
//--------------------------------------------------------------
// CCharacter::removePlayerFromFriendListByEntityId()
//--------------------------------------------------------------
@ -16568,7 +16735,21 @@ void CCharacter::setPVPFlag( bool pvpFlag )
if( pvpFlag == true )
{
if( (_DeclaredCult == PVP_CLAN::Neutral || _DeclaredCult == PVP_CLAN::None ) && (_DeclaredCiv == PVP_CLAN::Neutral || _DeclaredCiv == PVP_CLAN::None ) )
// NEW PVP : Check fames
bool havePvpFame = false;
for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++)
{
sint32 fame = CFameInterface::getInstance().getFameIndexed(_Id, fameIdx);
if ((fame >= PVPFameRequired*6000) || (fame <= -PVPFameRequired*6000))
havePvpFame = true;
}
//- if( (_DeclaredCult == PVP_CLAN::Neutral || _DeclaredCult == PVP_CLAN::None ) && (_DeclaredCiv == PVP_CLAN::Neutral || _DeclaredCiv == PVP_CLAN::None ) )
if (!havePvpFame)
{
// character can set it's tag pvp on if he have no allegiance.
SM_STATIC_PARAMS_1(params, STRING_MANAGER::integer);
@ -16578,7 +16759,8 @@ void CCharacter::setPVPFlag( bool pvpFlag )
return;
}
if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCult ) == false &&
// OLD PVP
/* if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCult ) == false &&
CPVPManager2::getInstance()->isFactionInWar( _DeclaredCiv ) == false)
{
// character can set it's tag pvp on if none of his clan is in war
@ -16588,8 +16770,10 @@ void CCharacter::setPVPFlag( bool pvpFlag )
CBankAccessor_PLR::getCHARACTER_INFO().getPVP_FACTION_TAG().setCOUNTER(_PropertyDatabase, uint8(++_PvPDatabaseCounter));
return;
}
*/
}
// if player changed it's decision before timer if finished
if( pvpFlag != _PVPFlag && actualPvpFlag == pvpFlag )
{
@ -16711,12 +16895,28 @@ void CCharacter::setPVPFlagDatabase()
CBankAccessor_PLR::getCHARACTER_INFO().getPVP_FACTION_TAG().setACTIVATION_TIME(_PropertyDatabase, activationTime );
// _PropertyDatabase.setProp("CHARACTER_INFO:PVP_FACTION_TAG:COUNTER", ++_PvPDatabaseCounter );
CBankAccessor_PLR::getCHARACTER_INFO().getPVP_FACTION_TAG().setCOUNTER(_PropertyDatabase, uint8(++_PvPDatabaseCounter) );
CBankAccessor_PLR::getCHARACTER_INFO().getPVP_FACTION_TAG().setFLAG_PVP_TIME_LEFT(_PropertyDatabase, _PVPRecentActionTime + PVPActionTimer );
}
//-----------------------------------------------------------------------------
void CCharacter::setPVPRecentActionFlag()
void CCharacter::setPVPRecentActionFlag(CCharacter *target)
{
if (!getPvPRecentActionFlag())
{
_PVPFlagAlly = 0;
_PVPFlagEnemy = 0;
}
_PVPRecentActionTime = CTickEventHandler::getGameCycle();
if (target != NULL)
{
_PVPFlagAlly |= target->getPVPFamesAllies();
_PVPFlagEnemy |= target->getPVPFamesEnemies();
updatePVPClanVP();
}
// _PropertyDatabase.setProp("CHARACTER_INFO:PVP_FACTION_TAG:FLAG_PVP_TIME_LEFT", _PVPRecentActionTime + PVPActionTimer );
CBankAccessor_PLR::getCHARACTER_INFO().getPVP_FACTION_TAG().setFLAG_PVP_TIME_LEFT(_PropertyDatabase, _PVPRecentActionTime + PVPActionTimer );
@ -16750,7 +16950,7 @@ bool CCharacter::setDeclaredCult(PVP_CLAN::TPVPClan newClan)
CFameManager::getInstance().setAndEnforceTribeFameCap(this->getId(), this->getAllegiance());
// handle with faction channel
CPVPManager2::getInstance()->addOrRemoveFactionChannel(this);
CPVPManager2::getInstance()->updateFactionChannel(this);
// write new allegiance in database
// _PropertyDatabase.setProp("FAME:CULT_ALLEGIANCE", newClan);
@ -16758,21 +16958,22 @@ bool CCharacter::setDeclaredCult(PVP_CLAN::TPVPClan newClan)
_LastCultPointWriteDB = ~0;
if( _DeclaredCult == PVP_CLAN::Neutral || _DeclaredCult == PVP_CLAN::None )
{
if( _PVPFlag )
// if( _DeclaredCult == PVP_CLAN::Neutral || _DeclaredCult == PVP_CLAN::None )
// {
if( _PVPFlag || getPvPRecentActionFlag() )
{
// if no cult declared and civ is not in war we remove pvp tag
if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCiv ) == false )
{
// if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCiv ) == false )
// {
_PVPFlag = false;
_PVPFlagLastTimeChange = 0;
_PVPFlagTimeSettedOn = 0;
_PVPRecentActionTime = 0;
setPVPFlagDatabase();
_HaveToUpdatePVPMode = true;
}
// }
}
}
// }
// Update PvP clan in mirror for faction PvP
updatePVPClanVP();
@ -16811,27 +17012,31 @@ bool CCharacter::setDeclaredCiv(PVP_CLAN::TPVPClan newClan)
// set tribe fame threshold and clamp fame if necessary
CFameManager::getInstance().setAndEnforceTribeFameCap(this->getId(), this->getAllegiance());
// handle with faction channel
CPVPManager2::getInstance()->updateFactionChannel(this);
// write new allegiance in database
// _PropertyDatabase.setProp("FAME:CIV_ALLEGIANCE", newClan);
CBankAccessor_PLR::getFAME().setCIV_ALLEGIANCE(_PropertyDatabase, newClan);
_LastCivPointWriteDB = ~0;
if( _DeclaredCiv == PVP_CLAN::Neutral || _DeclaredCiv == PVP_CLAN::None )
{
if( _PVPFlag )
// if( _DeclaredCiv == PVP_CLAN::Neutral || _DeclaredCiv == PVP_CLAN::None )
// {
if( _PVPFlag || getPvPRecentActionFlag() )
{
// if no civ declared and cult is not in war we remove pvp tag
if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCult ) == false )
{
// if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCult ) == false )
// {
_PVPFlag = false;
_PVPFlagLastTimeChange = 0;
_PVPFlagTimeSettedOn = 0;
_PVPRecentActionTime = 0;
setPVPFlagDatabase();
_HaveToUpdatePVPMode = true;
}
// }
}
}
// }
// Update PvP clan in mirror for faction PvP
updatePVPClanVP();
@ -19505,9 +19710,10 @@ void CCharacter::channelAdded( bool b )
//------------------------------------------------------------------------------
void CCharacter::setShowFactionChannelsMode(bool s)
void CCharacter::setShowFactionChannelsMode(TChanID channel, bool s)
{
_FactionChannelMode = s; CPVPManager2::getInstance()->addRemoveFactionChannelToUserWithPriviledge(this);
_FactionChannelsMode[channel] = s;
CPVPManager2::getInstance()->addRemoveFactionChannelToUserWithPriviledge(channel, this, s);
}

View file

@ -1859,6 +1859,19 @@ public:
void removePlayerFromFriendListByContactId(uint32 contactId);
void removePlayerFromFriendListByEntityId(const NLMISC::CEntityId &id);
void setInRoomOfPlayer(const NLMISC::CEntityId &id);
const NLMISC::CEntityId& getInRoomOfPlayer();
/// get if player have acces to room
bool playerHaveRoomAccess(const NLMISC::CEntityId &id);
/// add room acces to player
void addRoomAccessToPlayer(const NLMISC::CEntityId &id);
/// remove room acces to player
void removeRoomAccesToPlayer(const NLMISC::CEntityId &id, bool kick);
/// remove player from ignore list
void removePlayerFromIgnoreListByContactId(uint32 contactId);
void removePlayerFromIgnoreListByEntityId(const NLMISC::CEntityId &id);
@ -2217,6 +2230,8 @@ public:
void enterPVPZone(uint32 pvpZoneType) const;
/// character enter in versus pvp zone, player must choose a clan
void openPVPVersusDialog() const;
/// get priviledgePvp
bool getPriviledgePVP() const {return _PriviledgePvp;};
/// get character pvp flag
bool getPVPFlag( bool updatePVPModeInMirror = true ) const;
/// change pvp flag
@ -2228,7 +2243,7 @@ public:
/// set database pvp flag
void setPVPFlagDatabase();
/// set PVP recent action flag
void setPVPRecentActionFlag();
void setPVPRecentActionFlag(CCharacter *target = NULL);
/// get PvP recent action flag (true if player involved in PVP action recently)
bool getPvPRecentActionFlag() const;
/// character are killed in PvP situation
@ -2250,6 +2265,10 @@ public:
void setPvPSafeZoneActive();
/// clear pvp zone safe flag
void clearSafeInPvPSafeZone();
/// get pvp fames allies
TYPE_PVP_CLAN getPVPFamesAllies();
/// get pvp fames ennemys
TYPE_PVP_CLAN getPVPFamesEnemies();
/// update the clan in visuale property
void updatePVPClanVP() const;
//@}
@ -2296,13 +2315,17 @@ public:
void channelAdded( bool b );
bool isChannelAdded();
uint8 getNbUserChannels() { return _NbUserChannels; };
void addUserChannel() { _NbUserChannels++; };
void removeUserChannel() { _NbUserChannels--; };
std::vector<SItemSpecialEffect> lookForSpecialItemEffects(ITEM_SPECIAL_EFFECT::TItemSpecialEffect effectType) const;
/// return true if the given item is an xp catalyser which has been activated
bool isAnActiveXpCatalyser( CGameItemPtr item );
void setShowFactionChannelsMode(bool s);
bool showFactionChannelsMode();
void setShowFactionChannelsMode(TChanID channel, bool s);
bool showFactionChannelsMode(TChanID channel) const;
// from offline command
void contactListRefChangeFromCommand(const NLMISC::CEntityId &id, const std::string &operation);
@ -2840,7 +2863,10 @@ public:
bool TestProgression;
bool isShopingListInProgress() const { return _ShoppingList != 0; }
bool isShopingListInProgress() const { return _ShoppingList != 0; };
void setFinalized(bool isFinalized) { _LoadingFinish = isFinalized; };
bool isFinalized() const { return _LoadingFinish; };
//////////////////
// Private members
@ -3193,8 +3219,11 @@ private:
NLMISC::CEntityId EntityId; // Id used for server/storage
uint32 ContactId; // Id used for client/server communication
};
uint32 _ContactIdPool;
uint32 _ContactIdPool;
std::vector<NLMISC::CEntityId> _RoomersList; // Players who have acces to player's room
NLMISC::CEntityId _inRoomOfPlayer;
// friends list
std::vector<CContactId> _FriendsList;
// ignore list
@ -3342,6 +3371,9 @@ private:
NLMISC::TGameCycle _PVPFlagTimeSettedOn;
// time of the last PVP action made (for prevent PVE / PVP exploits)
NLMISC::TGameCycle _PVPRecentActionTime;
// all pvp flags (ally and enemy) when players do a pvp curative action
uint32 _PVPFlagAlly;
uint32 _PVPFlagEnemy;
// character safe if is in pvp safe zone
bool _PvPSafeZoneActive;
// player changed his faction tag, we have to update pvp mode
@ -3362,8 +3394,10 @@ private:
bool _ChannelAdded;
bool _LoadingFinish;
/// if true, enable display of channel faction for users with priviledge
bool _FactionChannelMode;
std::map<TChanID, bool> _FactionChannelsMode;
/// time when user left outpost zone (0 means not valid)
NLMISC::TGameCycle _OutpostLeavingTime;
@ -3574,7 +3608,11 @@ private:
public:
bool getInvisibility() const { return _Invisibility;}
/// Set the invisibility flag, NB : just for persistence, do not change nothing.
void setInvisibility(bool invisible) { _Invisibility = invisible;}
void setInvisibility(bool invisible)
{
_Invisibility = invisible;
CBankAccessor_PLR::getUSER().setIS_INVISIBLE(_PropertyDatabase, _Invisibility);
}
sint8 getAggroableSave() const { return _AggroableSave;}
/// Set the aggroable save flag, NB : just for persistence, do not change nothing.

View file

@ -896,9 +896,13 @@ inline bool CCharacter::isChannelAdded()
//------------------------------------------------------------------------------
inline bool CCharacter::showFactionChannelsMode()
inline bool CCharacter::showFactionChannelsMode(TChanID channel) const
{
return _FactionChannelMode;
std::map<TChanID, bool>::const_iterator it = _FactionChannelsMode.find(channel);
if (it != _FactionChannelsMode.end())
return (*it).second;
else
return false;
}
//------------------------------------------------------------------------------

View file

@ -1102,7 +1102,7 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
return;
// check if victim and final blower are in PvP Faction (by tag or by a pvp versus zone)
if(!CPVPManager2::getInstance()->factionWarOccurs(victimFaction, finalBlowerFaction))
/* if(!CPVPManager2::getInstance()->factionWarOccurs(victimFaction, finalBlowerFaction))
{
CPVPVersusZone * zone = dynamic_cast<CPVPVersusZone *>(const_cast<CPVPInterface &>(victimChar->getPVPInterface()).getPVPSession());
if( zone == 0 )
@ -1110,7 +1110,7 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
PVP_RELATION::TPVPRelation pvpRelation = zone->getPVPRelation(victimChar, const_cast<CCharacter*>(finalBlower));
if( pvpRelation != PVP_RELATION::Ennemy )
return;
}
}*/
// a dead player loses his damage points
clearDamages(victimChar, true);
@ -1684,7 +1684,7 @@ bool CDamageScoreManager::playerInFactionPvP(const CCharacter * playerChar, PVP_
else if( playerChar->getPVPFlag() )
{
pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> allegiance = playerChar->getAllegiance();
if( CPVPManager2::getInstance()->isFactionInWar( allegiance.first ) )
if( (allegiance.first != PVP_CLAN::Neutral) && (allegiance.first != PVP_CLAN::None) )
{
if (faction)
*faction = allegiance.first;
@ -1692,14 +1692,14 @@ bool CDamageScoreManager::playerInFactionPvP(const CCharacter * playerChar, PVP_
*withFactionPoints = true;
return true;
}
if ( CPVPManager2::getInstance()->isFactionInWar( allegiance.second ) )
/*if ( allegiance.second != PVP_CLAN::Neutral)
{
if (faction)
*faction = allegiance.second;
if (withFactionPoints)
*withFactionPoints = true;
return true;
}
}*/
}
return false;
}

View file

@ -35,86 +35,84 @@ CVariable<bool> ResPawnPVPInSameRegionForbiden("egs","ResPawnPVPInSameRegionForb
//----------------------------------------------------------------------------
PVP_RELATION::TPVPRelation CPVPFaction::getPVPRelation( CCharacter * actor, CEntityBase * target, bool curative ) const
{
// init relation reminders
// Init relation reminders
CPVPManager2::getInstance()->setPVPFactionAllyReminder( false );
CPVPManager2::getInstance()->setPVPFactionEnemyReminder( false );
// check actor and target validity
if( actor == 0 || target == 0 )
// Check actor and target validity
if (actor == 0 || target == 0)
{
nlwarning("<CPVPFaction::getPVPRelation> actor: %p target: %p",actor,target);
nlwarning("<CPVPFaction::getPVPRelation> actor: %p target: %p", actor, target);
return PVP_RELATION::Unknown;
}
CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if( pTarget == 0 )
{
if (pTarget == 0)
return PVP_RELATION::Unknown;
}
// if target is not tagged then he's neutral
if( pTarget->getPVPFlag() == false && pTarget->getPvPRecentActionFlag() == false )
{
if (!pTarget->getPVPFlag() && !pTarget->getPvPRecentActionFlag())
return PVP_RELATION::Neutral;
}
if( CPVPManager2::getInstance()->inSafeZone( pTarget->getPosition() ) )
// Check safe zones
if (CPVPManager2::getInstance()->inSafeZone(pTarget->getPosition()))
{
if( pTarget->getSafeInPvPSafeZone() )
{
if (pTarget->getSafeInPvPSafeZone())
return PVP_RELATION::NeutralPVP;
}
}
// get Faction allegiance
pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> actorAllegiance = actor->getAllegiance();
pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> targetAllegiance = pTarget->getAllegiance();
if( CPVPManager2::getInstance()->inSafeZone( actor->getPosition() ) )
if( CPVPManager2::getInstance()->inSafeZone(actor->getPosition()))
{
if( actor->getSafeInPvPSafeZone() )
{
if( actor->getSafeInPvPSafeZone())
return PVP_RELATION::NeutralPVP;
}
}
// Check fames
if( actor->getPVPFlag() || actor->getPvPRecentActionFlag() )
{
// check if he's an enemy (or neutral pvp)
if( actorAllegiance != targetAllegiance )
// In same Team
if ((pTarget->getTeamId() != CTEAM::InvalidTeamId) && (actor->getTeamId() != CTEAM::InvalidTeamId) && (actor->getTeamId() == pTarget->getTeamId()))
{
if( CPVPManager2::getInstance()->factionWarOccurs( actorAllegiance, targetAllegiance ) )
CPVPManager2::getInstance()->setPVPFactionAllyReminder( true );
return PVP_RELATION::Ally;
}
// In same Guild
if ((pTarget->getGuildId() != 0) && (actor->getGuildId() != 0) && (actor->getGuildId() == pTarget->getGuildId()))
{
CPVPManager2::getInstance()->setPVPFactionAllyReminder( true );
return PVP_RELATION::Ally;
}
// check if he's an ennemy
if ((actor->getPVPFamesAllies() & pTarget->getPVPFamesEnemies()) || (actor->getPVPFamesEnemies() & pTarget->getPVPFamesAllies()))
{
// Actor can heal an ennemi if not PvPRecentActionFlaged
if (curative && !pTarget->getPvPRecentActionFlag())
{
if( !curative || (curative && pTarget->getPvPRecentActionFlag()) )
{
CPVPManager2::getInstance()->setPVPFactionEnemyReminder( true );
return PVP_RELATION::Ennemy;
}
else
return PVP_RELATION::Neutral;
return PVP_RELATION::Neutral;
}
else if( actorAllegiance.first != targetAllegiance.first && actorAllegiance.second != actorAllegiance.second )
else
{
if( pTarget->getPvPRecentActionFlag() )
{
// here target is engaged in another faction war
return PVP_RELATION::NeutralPVP;
}
CPVPManager2::getInstance()->setPVPFactionEnemyReminder(true);
return PVP_RELATION::Ennemy;
}
}
// they are ally
CPVPManager2::getInstance()->setPVPFactionAllyReminder( true );
return PVP_RELATION::Ally;
// check if he's an ally
else if ((actor->getPVPFamesAllies() & pTarget->getPVPFamesAllies()) || (actor->getPVPFamesEnemies() & pTarget->getPVPFamesEnemies()))
{
CPVPManager2::getInstance()->setPVPFactionAllyReminder(true);
return PVP_RELATION::Ally;
}
}
else
{
if( pTarget->getPvPRecentActionFlag() )
{
// here target is engaged in a faction war, but player is not tagged
// Check if actor is not PvPFlag and try to heal a PvPRecentActionFlag
if (curative && pTarget->getPvPRecentActionFlag())
return PVP_RELATION::NeutralPVP;
}
}
// default is neutral
return PVP_RELATION::Neutral;
}

View file

@ -66,8 +66,8 @@ CPVPFactionRewardManager::CPVPFactionRewardManager()
//----------------------------------------------------------------------------
void CPVPFactionRewardManager::_BuildTotemBasesRec( const IPrimitive* prim,
std::map<CTotemBase*, set<string> >& neighboursNames,
map<std::string, CTotemBase*>& totemBasesPerName )
std::map<CTotemBase*, set<string> >& neighboursNames,
std::map<std::string, CTotemBase*>& totemBasesPerName )
{
if ( !prim )
return;
@ -441,11 +441,11 @@ bool CPVPFactionRewardManager::destroyTotem( uint16 regionIndex, TDataSetRow kil
// Send message to faction channel
params[2].Int = 1;
TChanID channelId = CPVPManager2::getInstance()->getFactionDynChannel(pTotemBase->getOwnerFaction());
if( channelId != DYN_CHAT_INVALID_CHAN )
{
// TODO TChanID channelId = CPVPManager2::getInstance()->getFactionDynChannel(pTotemBase->getOwnerFaction());
// if( channelId != DYN_CHAT_INVALID_CHAN )
// {
// TODO Send message PVP_SPIRE_DESTROYED to faction channel and enemies factions
}
// }
}
@ -665,11 +665,11 @@ void CPVPFactionRewardManager::tickUpdate()
// Send it in faction channel too
params[2].Int = 1;
TChanID channelId = CPVPManager2::getInstance()->getFactionDynChannel(pTotem->getOwnerFaction());
if( channelId != DYN_CHAT_INVALID_CHAN )
{
//TODO TChanID channelId = CPVPManager2::getInstance()->getFactionDynChannel(pTotem->getOwnerFaction());
//if( channelId != DYN_CHAT_INVALID_CHAN )
//{
// TODO Send message PVP_SPIRE_BUILD_FINISHED to faction channel
}
//}
}
}
}

View file

@ -25,6 +25,7 @@
#include "game_share/utils.h"
#include "game_share/msg_client_server.h"
#include "game_share/fame.h"
#include "pvp_manager/pvp_manager_2.h"
#include "pvp_manager/pvp_manager.h"
@ -70,9 +71,6 @@ void CPVPManager2::init()
IPVPInterface * pvpFaction = new CPVPFaction();
BOMB_IF(pvpFaction == 0, "Can't allocate CPVPFaction", nlstop );
_Instance->_PVPInterface.push_back(pvpFaction);
// add war between kami and karavan faction (must be controled by GM tools later
_Instance->addFactionWar(PVP_CLAN::Kami, PVP_CLAN::Karavan);
// instantiate pvp duel class
IPVPInterface * pvpDuel = new CPVPDuel();
BOMB_IF(pvpDuel == 0, "Can't allocate CPVPDuel", nlstop );
@ -144,146 +142,301 @@ void CPVPManager2::tickUpdate()
}
//----------------------------------------------------------------------------
TChanID CPVPManager2::getFactionDynChannel( PVP_CLAN::TPVPClan faction )
// TODO : Add extra factions
//-------
TChanID CPVPManager2::getFactionDynChannel( const std::string& channelName)
{
TMAPFactionChannel::iterator it = _FactionChannel.find( faction );
if( it != _FactionChannel.end() )
// Search first in extra faction channels
TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find(channelName);
if( it != _ExtraFactionChannel.end() )
{
return (*it).second;
}
return DYN_CHAT_INVALID_CHAN;
}
//----------------------------------------------------------------------------
TChanID CPVPManager2::getCharacterChannel(CCharacter * user)
{
// if( user->getPVPFlag(false) ) // new specs: we not need be tagged for have channel, only allegiance is required.
{
PVP_CLAN::TPVPClan faction = user->getAllegiance().first;
if( faction != PVP_CLAN::Neutral )
{
if( isFactionInWar(faction) )
{
TMAPFactionChannel::iterator it = _FactionChannel.find(faction);
if( it != _FactionChannel.end() )
{
return (*it).second;
}
}
}
}
return DYN_CHAT_INVALID_CHAN;
}
//----------------------------------------------------------------------------
TChanID CPVPManager2::getCharacterRegisteredChannel(CCharacter * user)
{
map< NLMISC::CEntityId, TChanID >::iterator it = _CharacterChannel.find(user->getId());
if( it != _CharacterChannel.end() )
{
return (*it).second;
}
return DYN_CHAT_INVALID_CHAN;
}
//----------------------------------------------------------------------------
void CPVPManager2::addOrRemoveFactionChannel(CCharacter * user, bool b )
{
TChanID channelHave = getCharacterRegisteredChannel(user);
TChanID channelMustHave = getCharacterChannel(user);
if( channelHave != DYN_CHAT_INVALID_CHAN )
{
if( channelHave != channelMustHave)
{
removeFactionChannelForCharacter(user);
}
}
if( channelMustHave != DYN_CHAT_INVALID_CHAN )
{
if(channelMustHave != channelHave )
{
addFactionChannelToCharacter(user);
}
}
if( b )
addRemoveFactionChannelToUserWithPriviledge(user);
}
//----------------------------------------------------------------------------
void CPVPManager2::addFactionChannelToCharacter(CCharacter * user)
{
TChanID channel = getCharacterChannel(user);
if( channel != DYN_CHAT_INVALID_CHAN )
{
DynChatEGS.addSession( channel, user->getEntityRowId(), true);
_CharacterChannel.insert( make_pair(user->getId(), channel) );
}
}
//----------------------------------------------------------------------------
void CPVPManager2::removeFactionChannelForCharacter(CCharacter * user)
{
TChanID channel = getCharacterRegisteredChannel(user);
if( channel != DYN_CHAT_INVALID_CHAN )
{
DynChatEGS.removeSession(channel, user->getEntityRowId());
std::map< NLMISC::CEntityId, TChanID >::iterator it = _CharacterChannel.find(user->getId());
if( it != _CharacterChannel.end() )
{
_CharacterChannel.erase(it);
}
}
}
//----------------------------------------------------------------------------
void CPVPManager2::addRemoveFactionChannelToUserWithPriviledge(CCharacter * user)
{
const CAdminCommand * cmd = findAdminCommand("ShowFactionChannels");
if (!cmd)
{
return;
}
if (!user->havePriv(cmd->Priv))
{
return;
}
if( user->showFactionChannelsMode() )
{
removeFactionChannelForCharacter(user);
bool writeRight = user->havePriv(FactionChannelModeratorWriteRight);
for( uint32 i = PVP_CLAN::BeginClans; i <= PVP_CLAN::EndClans; ++i )
{
if( isFactionInWar((PVP_CLAN::TPVPClan)i) )
{
TMAPFactionChannel::iterator it = _FactionChannel.find((PVP_CLAN::TPVPClan)i);
if( it != _FactionChannel.end() )
{
DynChatEGS.addSession((*it).second, user->getEntityRowId(), writeRight);
}
}
}
}
else
{
for( uint32 i = PVP_CLAN::BeginClans; i <= PVP_CLAN::EndClans; ++i )
PVP_CLAN::TPVPClan channelClan = PVP_CLAN::fromString( channelName );
if( channelClan < PVP_CLAN::BeginClans || channelClan > PVP_CLAN::EndClans )
return DYN_CHAT_INVALID_CHAN;
TMAPFactionChannel::iterator it = _FactionChannel.find( channelClan );
if( it != _FactionChannel.end() )
{
if( isFactionInWar((PVP_CLAN::TPVPClan)i) )
return (*it).second;
}
}
return DYN_CHAT_INVALID_CHAN;
}
TChanID CPVPManager2::getUserDynChannel( const std::string& channelName)
{
// Search in user channels
TMAPExtraFactionChannel::iterator it = _UserChannel.find(channelName);
if( it != _UserChannel.end() )
return (*it).second;
else
return DYN_CHAT_INVALID_CHAN;
}
const std::string & CPVPManager2::getPassUserChannel( TChanID channelId)
{
// Search in user channels
TMAPPassChannel::iterator it = _PassChannels.find(channelId);
if( it != _PassChannels.end() )
return (*it).second;
else
return DYN_CHAT_INVALID_NAME;
}
//----------------------------------------------------------------------------
std::vector<TChanID> CPVPManager2::getCharacterChannels(CCharacter * user)
{
// if( user->getPVPFlag(false) ) // new specs: we not need be tagged for have channel, only allegiance is required.
// {
std::vector<TChanID> result;
result.clear();
PVP_CLAN::TPVPClan faction = user->getAllegiance().first;
if( faction != PVP_CLAN::Neutral )
{
TMAPFactionChannel::iterator it = _FactionChannel.find(faction);
if( it != _FactionChannel.end() )
{
result.push_back((*it).second);
}
}
faction = user->getAllegiance().second;
if( faction != PVP_CLAN::Neutral )
{
TMAPFactionChannel::iterator it = _FactionChannel.find(faction);
if( it != _FactionChannel.end() )
{
result.push_back((*it).second);
}
}
bool matis = CFameInterface::getInstance().getFameIndexed(user->getId(), 0) >= PVPFameRequired*6000;
bool fyros = CFameInterface::getInstance().getFameIndexed(user->getId(), 1) >= PVPFameRequired*6000;
bool tryker = CFameInterface::getInstance().getFameIndexed(user->getId(), 2) >= PVPFameRequired*6000;
bool zorai = CFameInterface::getInstance().getFameIndexed(user->getId(), 3) >= PVPFameRequired*6000;
bool kami = CFameInterface::getInstance().getFameIndexed(user->getId(), 4) >= PVPFameRequired*6000;
bool kara = CFameInterface::getInstance().getFameIndexed(user->getId(), 6) >= PVPFameRequired*6000;
bool amatis = CFameInterface::getInstance().getFameIndexed(user->getId(), 0) <= -PVPFameRequired*6000;
bool afyros = CFameInterface::getInstance().getFameIndexed(user->getId(), 1) <= -PVPFameRequired*6000;
bool atryker = CFameInterface::getInstance().getFameIndexed(user->getId(), 2) <= -PVPFameRequired*6000;
bool azorai = CFameInterface::getInstance().getFameIndexed(user->getId(), 3) <= -PVPFameRequired*6000;
bool akami = CFameInterface::getInstance().getFameIndexed(user->getId(), 4) <= -PVPFameRequired*6000;
bool akara = CFameInterface::getInstance().getFameIndexed(user->getId(), 6) <= -PVPFameRequired*6000;
if (matis && fyros && tryker && zorai)
{
TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find("hominists");
if( it != _ExtraFactionChannel.end() )
{
result.push_back((*it).second);
}
}
if (amatis && afyros && atryker && azorai)
{
TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find("marauders");
if( it != _ExtraFactionChannel.end() )
{
result.push_back((*it).second);
}
}
if (kami && kara)
{
TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find("urasies");
if( it != _ExtraFactionChannel.end() )
{
result.push_back((*it).second);
}
}
if (akami && akara)
{
TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find("agnos");
if( it != _ExtraFactionChannel.end() )
{
result.push_back((*it).second);
}
}
// }
return result;
}
//----------------------------------------------------------------------------
std::vector<TChanID> CPVPManager2::getCharacterRegisteredChannels(CCharacter * user)
{
std::vector<TChanID> result;
result.clear();
TCharacterChannels::iterator it = _CharacterChannels.find(user->getId());
if( it != _CharacterChannels.end() )
return (*it).second; // return a vector<TChanID>
return result;
}
//----------------------------------------------------------------------------
std::vector<TChanID> CPVPManager2::getCharacterUserChannels(CCharacter * user)
{
std::vector<TChanID> result;
result.clear();
TCharacterChannels::iterator it = _CharacterUserChannels.find(user->getId());
if( it != _CharacterUserChannels.end() )
return (*it).second; // return a vector<TChanID>
return result;
}
//----------------------------------------------------------------------------
void CPVPManager2::updateFactionChannel(CCharacter * user, bool b )
{
std::vector<TChanID> channelsHave = getCharacterRegisteredChannels(user);
std::vector<TChanID> channelsMustHave = getCharacterChannels(user);
std::vector<TChanID> userChannelsMustHave = getCharacterUserChannels(user);
// Remove unwanted channels
for (uint i = 0; i < channelsHave.size(); i++)
{
bool have = false;
for (uint j = 0; j < channelsMustHave.size(); j++)
if (channelsHave[i] == channelsMustHave[j])
have = true;
for (uint j = 0; j < userChannelsMustHave.size(); j++)
if (channelsHave[i] == userChannelsMustHave[j])
have = true;
if (!have)
removeFactionChannelForCharacter(channelsHave[i], user);
}
// Add wanted channels
for (uint i = 0; i < channelsMustHave.size(); i++)
{
bool have = false;
for (uint j = 0; j < channelsHave.size(); j++)
if( channelsMustHave[i] == channelsHave[j])
have = true;
if (!have)
addFactionChannelToCharacter(channelsMustHave[i], user);
}
// Add wanted user channels
for (uint i = 0; i < userChannelsMustHave.size(); i++)
{
bool have = false;
for (uint j = 0; j < channelsHave.size(); j++)
if (userChannelsMustHave[i] == channelsHave[j])
have = true;
if (!have)
addFactionChannelToCharacter(userChannelsMustHave[i], user);
}
/*if( b )
addRemoveFactionChannelToUserWithPriviledge(user);
*/
}
//----------------------------------------------------------------------------
void CPVPManager2::addFactionChannelToCharacter(TChanID channel, CCharacter * user, bool writeRight, bool userChannel)
{
if( channel != DYN_CHAT_INVALID_CHAN )
{
if (DynChatEGS.addSession(channel, user->getEntityRowId(), writeRight))
{
std::vector<TChanID> currentChannels = getCharacterRegisteredChannels(user);
currentChannels.push_back(channel);
_CharacterChannels.erase(user->getId());
_CharacterChannels.insert( make_pair(user->getId(), currentChannels) );
if (userChannel)
{
TMAPFactionChannel::iterator it = _FactionChannel.find((PVP_CLAN::TPVPClan)i);
if( it != _FactionChannel.end() )
currentChannels = getCharacterUserChannels(user);
currentChannels.push_back(channel);
_CharacterUserChannels.erase(user->getId());
_CharacterUserChannels.insert( make_pair(user->getId(), currentChannels) );
}
}
}
}
//----------------------------------------------------------------------------
void CPVPManager2::removeFactionChannelForCharacter(TChanID channel, CCharacter * user, bool userChannel)
{
std::vector<TChanID> currentChannels = getCharacterRegisteredChannels(user);
for (uint i = 0; i < currentChannels.size(); i++)
{
if (currentChannels[i] == channel)
{
DynChatEGS.removeSession(channel, user->getEntityRowId());
if (userChannel && (DynChatEGS.getSessionCount(channel) == 0))
{
DynChatEGS.removeChan(channel);
TMAPPassChannel::iterator it = _PassChannels.find(channel);
if (it != _PassChannels.end())
_PassChannels.erase(it);
for (TMAPExtraFactionChannel::iterator it2 = _UserChannel.begin(); it2 != _UserChannel.end(); ++it2)
{
DynChatEGS.removeSession((*it).second, user->getEntityRowId());
if ((*it2).second == channel)
_UserChannel.erase(it2);
}
}
// Update channel list for player
currentChannels.erase(currentChannels.begin() + i);
std::map< NLMISC::CEntityId, std::vector<TChanID> >::iterator it = _CharacterChannels.find(user->getId());
if( it != _CharacterChannels.end() )
{
_CharacterChannels.erase(user->getId());
_CharacterChannels.insert(make_pair(user->getId(), currentChannels));
}
}
}
if (userChannel)
{
currentChannels = getCharacterUserChannels(user);
for (uint i = 0; i < currentChannels.size(); i++)
{
if (currentChannels[i] == channel)
{
// Update channel list for player
currentChannels.erase(currentChannels.begin() + i);
std::map< NLMISC::CEntityId, std::vector<TChanID> >::iterator it = _CharacterUserChannels.find(user->getId());
if( it != _CharacterUserChannels.end() )
{
_CharacterUserChannels.erase(user->getId());
_CharacterUserChannels.insert(make_pair(user->getId(), currentChannels));
}
}
}
addOrRemoveFactionChannel( user, false );
}
}
//----------------------------------------------------------------------------
void CPVPManager2::addRemoveFactionChannelToUserWithPriviledge(TChanID channel, CCharacter * user, bool s)
{
const CAdminCommand * cmd = findAdminCommand("ShowFactionChannels");
if (!cmd)
return;
if (!user->havePriv(cmd->Priv))
return;
if (s)
addFactionChannelToCharacter(channel, user, user->havePriv(FactionChannelModeratorWriteRight));
else
removeFactionChannelForCharacter(channel, user);
}
//----------------------------------------------------------------------------
void CPVPManager2::playerDisconnects(CCharacter * user)
{
@ -293,7 +446,9 @@ void CPVPManager2::playerDisconnects(CCharacter * user)
CPVPManager::getInstance()->playerDisconnects(user);
removeFactionChannelForCharacter(user);
// Remove all channels
removeFactionChannelForCharacter(DYN_CHAT_INVALID_CHAN, user);
_CharacterChannels.erase(user->getId());
}
//----------------------------------------------------------------------------
@ -316,6 +471,12 @@ void CPVPManager2::setPVPModeInMirror( const CCharacter * user ) const
nlassert(user);
uint8 pvpMode = 0;
// Full pvp
if ( user->getPriviledgePVP() )
{
pvpMode |= PVP_MODE::PvpChallenge;
}
// faction
{
if( user->getPVPFlag(false) )
@ -377,9 +538,12 @@ bool CPVPManager2::inSafeZone(const NLMISC::CVector & v) const
return false;
}
//----------------------------------------------------------------------------
// Main method for get Pvp Relation
//----------------------------------------------------------------------------
PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEntityBase * target, bool curative ) const
{
// Default relation
PVP_RELATION::TPVPRelation relation = PVP_RELATION::Neutral;
// init reminders, these help to know if faction pvp recent action flag need to be set
@ -390,13 +554,27 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn
_Instance->_PVPOutpostAllyReminder = false;
_Instance->_PVPOutpostEnemyReminder = false;
/// temp : until new manager is finished we have to check the char pvp session too
CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if( pTarget )
{
// priviledgePVP is Full PVP, only ally of teammates anf guildmates
if (pTarget->priviledgePVP() || actor->priviledgePVP())
{
if ((pTarget->getTeamId() != CTEAM::InvalidTeamId) && (actor->getTeamId() != CTEAM::InvalidTeamId) && (actor->getTeamId() == pTarget->getTeamId()))
return PVP_RELATION::Ally;
if ((pTarget->getGuildId() != 0) && (actor->getGuildId() != 0) && (actor->getGuildId() == pTarget->getGuildId()))
return PVP_RELATION::Ally;
return PVP_RELATION::Ennemy;
}
if( IsRingShard )
return relation; // disable PVP on Ring shards (only if target is a CCharacter, because we must let attack NPCs)
// //////////////////////////////////////////////////////
// temp : until new manager is finished we have to check the char pvp session too
IPVP * pvpSession = pTarget->getPVPInterface().getPVPSession();
if( pvpSession )
{
@ -424,24 +602,28 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn
}
}
}
////////////////////////////////////////////////////////
}
PVP_RELATION::TPVPRelation relationTmp = PVP_RELATION::Neutral;
uint i;
for( i=0; i<_PVPInterface.size(); ++i )
{
// Get relation for this Pvp Interface (faction, zone, outpost, ...)
relationTmp = _PVPInterface[i]->getPVPRelation( actor, target, curative );
if( relationTmp == PVP_RELATION::Unknown )
return PVP_RELATION::Unknown;
// ennemy has the highest priority
// Ennemy has the highest priority
if( relationTmp == PVP_RELATION::Ennemy )
return PVP_RELATION::Ennemy;
// neutral pvp
// Neutral pvp
if( relationTmp == PVP_RELATION::NeutralPVP )
relation = PVP_RELATION::NeutralPVP;
// check if ally (neutralpvp has priority over ally)
// Check if ally (neutralpvp has priority over ally)
if( relationTmp == PVP_RELATION::Ally && relation != PVP_RELATION::NeutralPVP )
relation = PVP_RELATION::Ally;
}
@ -484,19 +666,20 @@ bool CPVPManager2::isCurativeActionValid( CCharacter * actor, CEntityBase * targ
if( actionValid && !checkMode )
{
CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if(pTarget)
actor->clearSafeInPvPSafeZone();
// propagate faction pvp flag
if( pvpRelation == PVP_RELATION::Ally )
{
CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if(pTarget)
actor->clearSafeInPvPSafeZone();
// propagate faction pvp flag
if( _PVPFactionAllyReminder )
{
if( pTarget )
{
if( pTarget->getPvPRecentActionFlag() )
{
actor->setPVPRecentActionFlag();
actor->setPVPRecentActionFlag(pTarget);
TeamManager.pvpHelpOccursInTeam( actor, pTarget );
actor->pvpActionMade();
pTarget->pvpActionMade();
@ -509,6 +692,10 @@ bool CPVPManager2::isCurativeActionValid( CCharacter * actor, CEntityBase * targ
{
actor->refreshOutpostLeavingTimer();
}
// propagate full pvp
if( pTarget->priviledgePVP() )
actor->setPriviledgePVP(true);
}
}
return actionValid;
@ -592,13 +779,13 @@ bool CPVPManager2::canApplyAreaEffect(CCharacter* actor, CEntityBase * areaTarge
switch( pvpRelation )
{
case PVP_RELATION::Ally :
actionValid = !offensive;
actionValid = true;
break;
case PVP_RELATION::Ennemy :
actionValid = offensive;
break;
case PVP_RELATION::Neutral :
actionValid = !offensive;
actionValid = true;
break;
case PVP_RELATION::NeutralPVP :
actionValid = false;
@ -630,7 +817,7 @@ bool CPVPManager2::canApplyAreaEffect(CCharacter* actor, CEntityBase * areaTarge
{
if( pTarget->getPvPRecentActionFlag() )
{
actor->setPVPRecentActionFlag();
actor->setPVPRecentActionFlag(pTarget);
TeamManager.pvpHelpOccursInTeam( actor, pTarget );
}
}
@ -753,40 +940,28 @@ bool CPVPManager2::addFactionWar( PVP_CLAN::TPVPClan clan1, PVP_CLAN::TPVPClan c
/// create the faction chat channel when IOS mirror ready
void CPVPManager2::onIOSMirrorUp()
{
// for each pvp war, create the related char channel
for (uint i=0; i<_FactionWarOccurs.size(); ++i)
// create extra factions channels
createExtraFactionChannel("hominists");
createExtraFactionChannel("urasies");
createExtraFactionChannel("marauders");
createExtraFactionChannel("agnos");
for (uint i = PVP_CLAN::BeginClans; i <= PVP_CLAN::EndClans; i++)
{
PVP_CLAN::TPVPClan clan1 = _FactionWarOccurs[i].Clan1;
PVP_CLAN::TPVPClan clan2 = _FactionWarOccurs[i].Clan2;
// create dynamic channel for faction war if not already exist
createFactionChannel(clan1);
createFactionChannel(clan2);
// send start of faction war to all clients, and add faction channel to character with concerned allegiance
for( CPlayerManager::TMapPlayers::const_iterator it = PlayerManager.getPlayers().begin(); it != PlayerManager.getPlayers().end(); ++it )
//createFactionChannel(PVP_CLAN::getClanFromIndex(i));
createFactionChannel((PVP_CLAN::TPVPClan)i);
}
for( CPlayerManager::TMapPlayers::const_iterator it = PlayerManager.getPlayers().begin(); it != PlayerManager.getPlayers().end(); ++it )
{
CPlayerManager::SCPlayer scPlayer=(*it).second;
if (scPlayer.Player)
{
CPlayerManager::SCPlayer scPlayer=(*it).second;
if (scPlayer.Player)
CCharacter *activePlayer=scPlayer.Player->getActiveCharacter();
if (activePlayer)
{
CCharacter *activePlayer=scPlayer.Player->getActiveCharacter();
if (activePlayer)
{
CMessage msgout( "IMPULSION_ID" );
CEntityId id = activePlayer->getId();
msgout.serial( id );
CBitMemStream bms;
nlverify ( GenericMsgManager.pushNameToStream( "PVP_FACTION:PUSH_FACTION_WAR", bms) );
bms.serialEnum( clan1 );
bms.serialEnum( clan2 );
msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length());
sendMessageViaMirror( NLNET::TServiceId(id.getDynamicId()), msgout );
// add faction channel to character if needed
addFactionChannelToCharacter( activePlayer );
addRemoveFactionChannelToUserWithPriviledge( activePlayer );
}
updateFactionChannel(activePlayer);
}
}
}
@ -796,43 +971,6 @@ void CPVPManager2::onIOSMirrorUp()
//----------------------------------------------------------------------------
bool CPVPManager2::stopFactionWar( PVP_CLAN::TPVPClan clan1, PVP_CLAN::TPVPClan clan2 )
{
vector< PVP_CLAN::CFactionWar >::iterator it;
for( it=_FactionWarOccurs.begin(); it!=_FactionWarOccurs.end(); ++it )
{
if( (*it).inPvPFaction( clan1, clan2 ) )
{
// send end of faction war to all clients, and remove faction channel if needed
for( CPlayerManager::TMapPlayers::const_iterator it2 = PlayerManager.getPlayers().begin(); it2 != PlayerManager.getPlayers().end(); ++it2 )
{
CPlayerManager::SCPlayer scPlayer=(*it2).second;
if (scPlayer.Player)
{
CCharacter *activePlayer=scPlayer.Player->getActiveCharacter();
if (activePlayer)
{
CMessage msgout( "IMPULSION_ID" );
CEntityId id = activePlayer->getId();
msgout.serial( id );
CBitMemStream bms;
nlverify ( GenericMsgManager.pushNameToStream( "PVP_FACTION:POP_FACTION_WAR", bms) );
bms.serialEnum( clan1 );
bms.serialEnum( clan2 );
msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length());
sendMessageViaMirror( NLNET::TServiceId(id.getDynamicId()), msgout );
removeFactionChannelForCharacter(activePlayer);
}
}
}
// erase war
_FactionWarOccurs.erase(it);
removeFactionChannel(clan1);
removeFactionChannel(clan2);
return true;
}
}
return false;
}
@ -842,10 +980,7 @@ void CPVPManager2::createFactionChannel(PVP_CLAN::TPVPClan clan)
TMAPFactionChannel::iterator it = _FactionChannel.find(clan);
if( it == _FactionChannel.end() )
{
ucstring title;
string name = NLMISC::strupr( string("Faction_") + PVP_CLAN::toString(clan) );
// title.fromUtf8(name);
// TChanID factionChannelId = DynChatEGS.addChan(name, title );
TChanID factionChannelId = DynChatEGS.addLocalizedChan(name);
// set historic size of the newly created channel
DynChatEGS.setHistoricSize( factionChannelId, FactionChannelHistoricSize );
@ -854,15 +989,60 @@ void CPVPManager2::createFactionChannel(PVP_CLAN::TPVPClan clan)
}
}
void CPVPManager2::createExtraFactionChannel(const std::string & channelName)
{
TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find(channelName);
if( it == _ExtraFactionChannel.end() )
{
string name = NLMISC::strupr( string("Faction_") + channelName );
TChanID factionChannelId = DynChatEGS.addLocalizedChan(name);
// set historic size of the newly created channel
DynChatEGS.setHistoricSize( factionChannelId, FactionChannelHistoricSize );
_ExtraFactionChannel.insert( make_pair(channelName, factionChannelId) );
}
}
TChanID CPVPManager2::createUserChannel(const std::string & channelName, const std::string & pass)
{
TMAPExtraFactionChannel::iterator it = _UserChannel.find(channelName);
if( it == _UserChannel.end() )
{
string channelTitle;
if (channelName.substr(0, 1) == "#")
channelTitle = channelName.substr(5);
else
channelTitle = channelName;
TChanID factionChannelId = DynChatEGS.addChan(channelName, channelTitle);
DynChatEGS.setHistoricSize( factionChannelId, FactionChannelHistoricSize );
_UserChannel.insert( make_pair(channelName, factionChannelId) );
_PassChannels.insert( make_pair(factionChannelId, pass) );
return factionChannelId;
}
return DYN_CHAT_INVALID_CHAN;
}
void CPVPManager2::deleteUserChannel(const std::string & channelName)
{
TMAPExtraFactionChannel::iterator it = _UserChannel.find(channelName);
if( it != _UserChannel.end() )
{
DynChatEGS.removeChan( (*it).second );
TMAPPassChannel::iterator it2 = _PassChannels.find((*it).second);
if( it2 != _PassChannels.end() )
_PassChannels.erase(it2);
_UserChannel.erase(it);
}
}
//----------------------------------------------------------------------------
void CPVPManager2::removeFactionChannel(PVP_CLAN::TPVPClan clan)
{
for( uint32 i = 0; i < _FactionWarOccurs.size(); ++i )
{
if( _FactionWarOccurs[ i ].Clan1 == clan || _FactionWarOccurs[ i ].Clan2 == clan)
return;
}
TMAPFactionChannel::iterator it = _FactionChannel.find( clan );
if( it != _FactionChannel.end() )
{
@ -874,48 +1054,18 @@ void CPVPManager2::removeFactionChannel(PVP_CLAN::TPVPClan clan)
//----------------------------------------------------------------------------
bool CPVPManager2::factionWarOccurs( PVP_CLAN::TPVPClan clan1, PVP_CLAN::TPVPClan clan2 ) const
{
if( clan1 != PVP_CLAN::Neutral && clan2 != PVP_CLAN::Neutral )
{
uint32 factionWarOccursSize = (uint32)_FactionWarOccurs.size();
for( uint32 i = 0; i < factionWarOccursSize; ++i )
{
if( _FactionWarOccurs[ i ].inPvPFaction( clan1, clan2 ) )
return true;
}
}
return false;
}
//----------------------------------------------------------------------------
bool CPVPManager2::factionWarOccurs( pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> allegiance1, pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> allegiance2 ) const
{
bool warOccurs = false;
if( allegiance1.first != PVP_CLAN::Neutral )
{
if( allegiance2.first != PVP_CLAN::Neutral && allegiance1.first != allegiance2. first )
warOccurs |= factionWarOccurs( allegiance1.first, allegiance2.first );
if( allegiance2.second != PVP_CLAN::Neutral && allegiance1.first != allegiance2.second )
warOccurs |= factionWarOccurs( allegiance1.first, allegiance2.second );
}
if( allegiance1.second != PVP_CLAN::Neutral )
{
if( allegiance2.first != PVP_CLAN::Neutral && allegiance1.second != allegiance2.first )
warOccurs |= factionWarOccurs( allegiance1.second, allegiance2.first );
if( allegiance2.second != PVP_CLAN::Neutral && allegiance1.second != allegiance2.second )
warOccurs |= factionWarOccurs( allegiance1.second, allegiance2.second );
}
return warOccurs;
return false;
}
//----------------------------------------------------------------------------
bool CPVPManager2::isFactionInWar( PVP_CLAN::TPVPClan clan )
{
uint32 factionWarOccursSize = (uint32)_FactionWarOccurs.size();
for( uint32 i = 0; i < factionWarOccursSize; ++i )
{
if( _FactionWarOccurs[ i ].Clan1 == clan || _FactionWarOccurs[ i ].Clan2 == clan )
return true;
}
return false;
}
@ -925,6 +1075,7 @@ bool CPVPManager2::isFactionInWar( PVP_CLAN::TPVPClan clan )
//-----------------------------------------------
void CPVPManager2::sendFactionWarsToClient( CCharacter * user )
{
/** Old Pvp
nlassert(user);
CMessage msgout( "IMPULSION_ID" );
@ -947,6 +1098,7 @@ void CPVPManager2::sendFactionWarsToClient( CCharacter * user )
msgout.serialBufferWithSize( (uint8*)bms.buffer(), bms.length() );
CUnifiedNetwork::getInstance()->send( NLNET::TServiceId(id.getDynamicId()), msgout );
*/
}
@ -1264,7 +1416,8 @@ NLMISC_COMMAND(setFactionWar, "Start/stop current wars between faction", "<Facti
PVP_CLAN::TPVPClan faction1 = PVP_CLAN::fromString( args[ 0 ] );
PVP_CLAN::TPVPClan faction2 = PVP_CLAN::fromString( args[ 1 ] );
uint32 war = (uint32)atoi(args[ 2 ].c_str());
uint32 war;
NLMISC::fromString(args[ 2 ], war);
if( faction1 < PVP_CLAN::BeginClans || faction1 > PVP_CLAN::EndClans )
{

View file

@ -41,6 +41,8 @@ class CPVPManager2
NL_INSTANCE_COUNTER_DECL(CPVPManager2);
public:
typedef std::map< PVP_CLAN::TPVPClan, TChanID > TMAPFactionChannel;
typedef std::map< std::string, TChanID > TMAPExtraFactionChannel;
typedef std::map< TChanID, std::string > TMAPPassChannel;
///\name LOW LEVEL MANAGEMENT
//@{
@ -55,21 +57,27 @@ public:
/// callback called at each tick
void tickUpdate();
/// return dynamic channel TChanID attribued to a faction
TChanID getFactionDynChannel( PVP_CLAN::TPVPClan faction);
TChanID getFactionDynChannel( const std::string& channelName );
/// return dynamic channel TChanID attribued to an user
TChanID getUserDynChannel( const std::string& channelName);
/// return dynamic channel TChanID attribued to a faction
const std::string &getPassUserChannel( TChanID channelId);
/// return dynamic channel TChanID character must have, DYN_CHAT_INVALID_CHAN if he must don't have faction channel
TChanID getCharacterChannel(CCharacter * user);
std::vector<TChanID> getCharacterChannels(CCharacter * user);
/// return dynamic channel TChanId subscribed by character, DYN_CHAT_INVALID_CHAN if character have no faction channel
TChanID getCharacterRegisteredChannel(CCharacter * user);
std::vector<TChanID> getCharacterRegisteredChannels(CCharacter * user);
/// return dynamic user channel TChanId subscribed by character, DYN_CHAT_INVALID_CHAN if character have no user channel
std::vector<TChanID> getCharacterUserChannels(CCharacter * user);
// add faction channel to character if needed
void addFactionChannelToCharacter(CCharacter * user);
void addFactionChannelToCharacter(TChanID channel, CCharacter * user, bool writeRight = true, bool userChannel = false);
// remove faction channel for character
void removeFactionChannelForCharacter(CCharacter * user);
void removeFactionChannelForCharacter(TChanID channel, CCharacter * user, bool userChannel = false);
// add/remove faction channel to this character with privilege
void addRemoveFactionChannelToUserWithPriviledge(CCharacter * user );
void addRemoveFactionChannelToUserWithPriviledge(TChanID channel, CCharacter * user, bool s = true );
/// handle player disconnection
void playerDisconnects(CCharacter * user);
/// handle to add or remove faction channel to player of needed
void addOrRemoveFactionChannel(CCharacter * user, bool b = true );
void updateFactionChannel(CCharacter * user, bool b = true );
/// handle player death
void playerDies(CCharacter * user);
/// handle player teleportation
@ -113,6 +121,12 @@ public:
bool stopFactionWar( PVP_CLAN::TPVPClan clan1, PVP_CLAN::TPVPClan clan2 );
// create a faction channel if not already exist
void createFactionChannel(PVP_CLAN::TPVPClan clan);
// create an extra faction channel if not already exist (for marauders, agnos, urasiens and hominits)
void createExtraFactionChannel(const std::string & channelName);
// create an user channel if not already exist
TChanID createUserChannel(const std::string & channelName, const std::string & pass);
// remove a user channel
void deleteUserChannel(const std::string & channelName);
// remove a fation channel if faction is no more involved in a war
void removeFactionChannel(PVP_CLAN::TPVPClan clan);
// return true if faction war occurs between the 2 factions
@ -165,8 +179,13 @@ private:
TFactionWars _FactionWarOccurs;
/// channel for faction in war
TMAPFactionChannel _FactionChannel;
TMAPExtraFactionChannel _ExtraFactionChannel;
TMAPExtraFactionChannel _UserChannel;
TMAPPassChannel _PassChannels;
/// character registered channel
std::map< NLMISC::CEntityId, TChanID > _CharacterChannel;
typedef std::map< NLMISC::CEntityId, std::vector<TChanID> > TCharacterChannels;
TCharacterChannels _CharacterChannels;
TCharacterChannels _CharacterUserChannels;
/// if a player does an offensive(curative) action on a faction pvp enemy(ally) we must update flag
bool _PVPFactionAllyReminder;
bool _PVPFactionEnemyReminder;

View file

@ -253,6 +253,7 @@ bool CCharacterShoppingList::passThruFilter(TItemTradePtr itemTrade, bool dynnam
case ITEMFAMILY::HARVEST_TOOL:
case ITEMFAMILY::CRAFTING_TOOL:
case ITEMFAMILY::COSMETIC:
case ITEMFAMILY::CONSUMABLE:
if( form->Type != _Character->getItemTypeFilter() )
return false;
break;
@ -269,7 +270,8 @@ bool CCharacterShoppingList::passThruFilter(TItemTradePtr itemTrade, bool dynnam
form->Family != ITEMFAMILY::COSMETIC &&
form->Family != ITEMFAMILY::TELEPORT &&
form->Family != ITEMFAMILY::SERVICE &&
form->Family != ITEMFAMILY::GENERIC_ITEM
form->Family != ITEMFAMILY::GENERIC_ITEM &&
form->Family != ITEMFAMILY::CONSUMABLE
)
{
if( _Character->getMinClassItemFilter() != RM_CLASS_TYPE::Unknown && itemEnergy != ~0u )
@ -387,6 +389,7 @@ uint32 CCharacterShoppingList::getSellPrice( const TItemTradePtr itemTrade, bool
case ITEMFAMILY::SHIELD:
case ITEMFAMILY::JEWELRY:
case ITEMFAMILY::RAW_MATERIAL:
case ITEMFAMILY::CONSUMABLE:
priceFactor *= 4.0f;
break;
case ITEMFAMILY::COSMETIC:

View file

@ -580,6 +580,7 @@ IShopUnit * CShopTypeManager::getDynamicShopUnit( const TItemTradePtr& item, uin
case ITEMFAMILY::JEWELRY:
case ITEMFAMILY::CRYSTALLIZED_SPELL:
case ITEMFAMILY::ITEM_SAP_RECHARGE:
case ITEMFAMILY::CONSUMABLE:
{
uint32 itemType = itemForm->Type;
uint32 itemOrigin = itemForm->Origin;

View file

@ -863,7 +863,12 @@ void CTeam::removeMission( uint idx, TMissionResult result)
result = mr_fail;
}
const CMissionTemplate *tpl = CMissionManager::getInstance()->getTemplate(_Missions[idx]->getTemplateId());
CMissionTemplate *tpl = CMissionManager::getInstance()->getTemplate(_Missions[idx]->getTemplateId());
if ( tpl && !tpl->Tags.NoList )
{
_Missions[idx]->clearUsersJournalEntry();
}
/*Bsi.append( StatPath, NLMISC::toString("[MIT%s] %u %s",
MissionResultStatLogTag[result],
@ -877,7 +882,6 @@ void CTeam::removeMission( uint idx, TMissionResult result)
tpl->getMissionName().c_str());
*/
// EGSPD::missionTeamLog(MissionResultStatLogTag[result], this->_TeamId, tpl->getMissionName());
_Missions[idx]->clearUsersJournalEntry();
CMissionManager::getInstance()->deInstanciateMission(_Missions[idx]);
delete _Missions[idx];
_Missions.erase(_Missions.begin() + idx) ;

View file

@ -90,6 +90,14 @@ void cbSetZoneState( NLNET::CMessage& msgin, const std::string &serviceName, NLN
CZoneManager *pZM = &CZoneManager::getInstance();
// get the places
CPlace *place = pZM->getPlaceFromName(sZoneName);
if (place != NULL)
if (place->isGooPath())
place->setGooActive(nState != 0);
// get the deposit zone (linear search)
const vector<CDeposit*> &rDeps = pZM->getDeposits();
for (uint32 i = 0; i < rDeps.size(); ++i)
@ -267,6 +275,7 @@ bool CPlace::build(const NLLIGO::CPrimPath * path, uint16 id)
_CenterX = sint32 ( ( minX + maxX ) *1000.0f / 2.0f );
_CenterY = sint32 ( ( minY + maxY ) *1000.0f / 2.0f );
_GooPath = true;
_GooActive = true;
_Reported = false;
return true;
@ -331,6 +340,7 @@ bool CPlace::build(const NLLIGO::CPrimZone * zone,uint16 id, bool reportAutorise
_CenterX = sint32 ( ( minX + maxX ) *1000.0f / 2.0f );
_CenterY = sint32 ( ( minY + maxY ) *1000.0f / 2.0f );
_GooPath = false;
_GooActive = false;
// get place_type of re-spawn point
PLACE_TYPE::TPlaceType placeType;

View file

@ -148,9 +148,11 @@ public:
///\return center coords
inline sint32 getCenterX(){ return _CenterX;}
inline sint32 getCenterY(){ return _CenterY;}
inline void setGooActive(bool state) { _GooActive = state; }
bool getReported() const { return _Reported; }
bool isGooPath() const { return _GooPath; }
bool isGooActive() const { return _GooActive; }
bool isMainPlace() const { return _MainPlace; }
TAIAlias getAlias()const{ return _Alias; }
@ -169,6 +171,7 @@ private:
bool _Reported;
/// Flag indicate this place is a goo path
bool _GooPath;
bool _GooActive;
/// true if the place is the main place where a user can be
bool _MainPlace;
/// respawn points validated when a user enters the place

View file

@ -1417,8 +1417,15 @@ void CChatManager::sendChat( CChatGroup::TGroupType senderChatMode, const TDataS
{
if (itCl->second->getId().getType() == RYZOMID::player)
{
if (itCl->second->isInIgnoreList(sender))
bool havePriv = false;
if (charInfos && charInfos->HavePrivilege)
{
havePriv = true;
}
if ( ! havePriv && itCl->second->isInIgnoreList(sender))
{
return;
}
uint32 senderNameIndex;
// if the sender exists
@ -1605,8 +1612,15 @@ void CChatManager::sendChat2Ex( CChatGroup::TGroupType senderChatMode, const TDa
{
if (itCl->second->getId().getType() == RYZOMID::player)
{
if (itCl->second->isInIgnoreList(sender))
bool havePriv = false;
if (charInfos && charInfos->HavePrivilege)
{
havePriv = true;
}
if ( ! havePriv && itCl->second->isInIgnoreList(sender))
{
return;
}
// send the chat phrase to the client
// send the string to FE
@ -1655,6 +1669,7 @@ void CChatManager::sendChatCustomEmote( const TDataSetRow &sender, const TDataSe
TDataSetRow senderFake = TDataSetRow::createFromRawIndex( INVALID_DATASET_ROW );
CCharacterInfos * receiverInfos = IOS->getCharInfos( TheDataset.getEntityId(receiver) );
CCharacterInfos * senderInfos = IOS->getCharInfos( TheDataset.getEntityId(sender) );
if( receiverInfos )
{
TClientInfoCont::iterator itCl = _Clients.find( receiver );
@ -1662,8 +1677,15 @@ void CChatManager::sendChatCustomEmote( const TDataSetRow &sender, const TDataSe
{
if (itCl->second->getId().getType() == RYZOMID::player)
{
if (itCl->second->isInIgnoreList(sender))
bool havePriv = false;
if (senderInfos && senderInfos->HavePrivilege)
{
havePriv = true;
}
if ( ! havePriv && itCl->second->isInIgnoreList(sender))
{
return;
}
// send the string to FE
CMessage msgout( "IMPULS_CH_ID" );
@ -1752,8 +1774,8 @@ void CChatManager::tell2( const TDataSetRow& sender, const TDataSetRow& receiver
return;
}
// check if the sender is not in the ignore list of the receiver
if( !itCl->second->isInIgnoreList(sender) )
// check if the sender is CSR or is not in the ignore list of the receiver
if(senderInfos->HavePrivilege || !itCl->second->isInIgnoreList(sender) )
{
// send the chat phrase to the client
TVectorParamCheck params;
@ -1850,7 +1872,7 @@ void CChatManager::tell( const TDataSetRow& sender, const string& receiverIn, co
}
// check if the sender is not in the ignore list of the receiver
if( !itCl->second->isInIgnoreList(sender) )
if(senderInfos->HavePrivilege || !itCl->second->isInIgnoreList(sender) )
{
// check if user is afk
if ( receiverInfos->DataSetIndex.isValid() && TheDataset.isDataSetRowStillValid( receiverInfos->DataSetIndex ) )
@ -2018,8 +2040,9 @@ void CChatManager::farTell( const NLMISC::CEntityId &senderCharId, const ucstrin
return;
}
// check if the sender is not in the ignore list of the receiver
if( !itCl->second->isInIgnoreList(senderCharId) )
CCharacterInfos * senderInfos = IOS->getCharInfos(senderName);
// check if the sender is CSR is not in the ignore list of the receiver
if((senderInfos && senderInfos->HavePrivilege) || !itCl->second->isInIgnoreList(senderCharId) )
{
// check if user is afk
// if ( receiverInfos->DataSetIndex.isValid() && TheDataset.isDataSetRowStillValid( receiverInfos->DataSetIndex ) )
@ -2311,8 +2334,25 @@ ucstring CChatManager::filterClientInput(ucstring &text)
// any double white skipped
if (text[pos] == '&')
{
// filter out '&' to remove system color code (like '&SYS&' )
result += '.';
// Special case if there is <NEW> or <CHG> at the beginning
bool hasBrackets = false;
if (pos >= 5)
{
hasBrackets = (text[pos-1] == '>') &&
(text[pos-5] == '<');
}
// Filter out '&' at the first non-whitespace position to remove
// system color code (like '&SYS&' )
bool disallowAmpersand = (result.size() == 0) || hasBrackets;
if (disallowAmpersand)
{
result += '.';
}
else
{
// authorized ampersand
result += '&';
}
}
else if (text[pos] == '@' && pos < text.size()-1 && text[pos+1] == '{')
{