mirror of
https://github.com/polserver/polserver
synced 2026-08-13 08:23:08 -04:00
132 lines
3.6 KiB
C++
132 lines
3.6 KiB
C++
/** @file
|
|
*
|
|
* @par History
|
|
* - 2005/12/05 MuadDib: Added check for invul_tag from ssopt. If not 1, don't add tag.
|
|
* - 2009/11/19 Turley: ssopt.core_sends_season & .core_handled_tags - Tomi
|
|
*/
|
|
|
|
#include "sngclick.h"
|
|
|
|
#include <cstdio>
|
|
#include <string>
|
|
|
|
#include "../clib/clib_endian.h"
|
|
#include "../clib/passert.h"
|
|
#include "../plib/uconst.h"
|
|
#include "containr.h"
|
|
#include "mobile/charactr.h"
|
|
#include "network/client.h"
|
|
#include "network/pktin.h"
|
|
#include "ufunc.h"
|
|
#include "ufuncstd.h"
|
|
#include "uobject.h"
|
|
#include "uworld.h"
|
|
|
|
|
|
namespace Pol
|
|
{
|
|
namespace Core
|
|
{
|
|
Items::Item* find_legal_singleclick_item( Mobile::Character* chr, u32 serial )
|
|
{
|
|
Items::Item* item = find_legal_item( chr, serial );
|
|
if ( item )
|
|
return item;
|
|
|
|
// search equipment of nearby mobiles
|
|
Pos2d posL = zone_convert( chr->pos() - Vec2d( RANGE_VISUAL, RANGE_VISUAL ) );
|
|
Pos2d posH = zone_convert( chr->pos() + Vec2d( RANGE_VISUAL, RANGE_VISUAL ) );
|
|
Area2d area( posL, posH, nullptr );
|
|
for ( const auto& p : area )
|
|
{
|
|
for ( const auto& ochr : chr->realm()->getzone( p ).characters )
|
|
{
|
|
Items::Item* _item = ochr->find_wornitem( serial );
|
|
if ( _item != nullptr )
|
|
return _item;
|
|
}
|
|
for ( const auto& ochr : chr->realm()->getzone( p ).npcs )
|
|
{
|
|
Items::Item* _item = ochr->find_wornitem( serial );
|
|
if ( _item != nullptr )
|
|
return _item;
|
|
}
|
|
}
|
|
if ( chr->trade_container() )
|
|
{
|
|
item = chr->trade_container()->find( serial );
|
|
if ( item )
|
|
return item;
|
|
}
|
|
if ( chr->trading_with.get() && chr->trading_with->trade_container() )
|
|
{
|
|
item = chr->trading_with->trade_container()->find( serial );
|
|
if ( item )
|
|
return item;
|
|
}
|
|
|
|
return nullptr;
|
|
} // namespace Core
|
|
|
|
std::string create_nametags( Mobile::Character* chr )
|
|
{
|
|
std::string tags;
|
|
|
|
if ( chr->frozen() && ( settingsManager.ssopt.core_handled_tags & 0x2 ) )
|
|
tags = "[frozen] ";
|
|
if ( chr->paralyzed() && ( settingsManager.ssopt.core_handled_tags & 0x4 ) )
|
|
tags += "[paralyzed] ";
|
|
if ( chr->squelched() && ( settingsManager.ssopt.core_handled_tags & 0x8 ) )
|
|
tags += "[squelched] ";
|
|
if ( chr->deafened() && ( settingsManager.ssopt.core_handled_tags & 0x10 ) )
|
|
tags += "[deafened] ";
|
|
if ( chr->invul() && settingsManager.ssopt.invul_tag == 1 )
|
|
tags += "[invulnerable]";
|
|
|
|
return tags;
|
|
}
|
|
|
|
void singleclick( Network::Client* client, u32 serial )
|
|
{
|
|
passert_always( client != nullptr && client->chr != nullptr );
|
|
|
|
if ( IsCharacter( serial ) )
|
|
{
|
|
Mobile::Character* chr = nullptr;
|
|
if ( serial == client->chr->serial )
|
|
chr = client->chr;
|
|
else
|
|
chr = find_character( serial );
|
|
|
|
if ( chr != nullptr && inrange( client->chr, chr ) &&
|
|
!client->chr->is_concealed_from_me( chr ) )
|
|
{
|
|
if ( chr->has_title_guild() && ( settingsManager.ssopt.core_handled_tags & 0x1 ) )
|
|
send_nametext( client, chr, "[" + chr->title_guild() + "]" );
|
|
send_nametext( client, chr, chr->name() );
|
|
|
|
std::string tags = create_nametags( chr );
|
|
if ( !tags.empty() )
|
|
send_nametext( client, chr, tags );
|
|
}
|
|
}
|
|
else // single clicked on an item
|
|
{
|
|
Items::Item* item = find_legal_singleclick_item( client->chr, serial );
|
|
if ( item )
|
|
{
|
|
send_objdesc( client, item );
|
|
}
|
|
}
|
|
}
|
|
|
|
void handle_singleclick( Network::Client* client, PKTIN_09* msg )
|
|
{
|
|
u32 serial = cfBEu32( msg->serial );
|
|
if ( client && client->chr )
|
|
singleclick( client, serial );
|
|
// TODO: report if someone tries to use singleclick without a connected char (should have been
|
|
// blocked)
|
|
}
|
|
} // namespace Core
|
|
} // namespace Pol
|