polserver/pol-core/pol/ufunc2.cpp
turleypol c588c51a33
Expansion helper classes for central handling of features (#756)
* use uoexpansion enums for A9, B9 flags
added TOL to uoexpansion
currently unsure where this will end

simplified account initialisation, added errorcheck

* Expansion classes for server and account
fixed flags

* use of AccountExpansion,ServerExpansion
extended tests
splitted unittest file
added missing test for Min/MaxAttackRange

* more micro performance for world saving
use all 4 cores in CI builds
fix compiler flag warning on windows

* save test for weight_multiplier

* enable gothic,rustictiles when using HSA expansion

* removed ancient unused files

* addressed comments
renamed ServerExpansion to ServerFeatures
added method for expansion name

* got rid of client UOExpansionFlag which is the same as the accout
expansion

* updated core-changes and docs

* updated generated ssopt

* test for tooltips
changed method names
removed/clarified comments

* npc hitchance was never saved
added missing npc save tests

* hitchance bug exists also for items...
added missing test for movemode
2025-02-05 19:02:25 +01:00

129 lines
3.8 KiB
C++

/** @file
*
* @par History
* - 2009/07/23 MuadDib: updates for new Enum::Packet Out ID
* - 2009/09/06 Turley: Changed Version checks to bitfield client->ClientType
* - 2009/10/12 Turley: whisper/yell/say-range ssopt definition
*/
#include "../clib/rawtypes.h"
#include "containr.h"
#include "item/item.h"
#include "menu.h"
#include "mobile/charactr.h"
#include "network/client.h"
#include "network/packethelper.h"
#include "network/packets.h"
#include "tooltips.h"
#include "ufunc.h"
namespace Pol
{
namespace Core
{
using namespace Network;
bool send_menu( Client* client, Menu* menu )
{
// build up the message so it gets sent as a unit.
if ( menu->menuitems_.size() > 255 )
return false;
PktHelper::PacketOut<PktOut_7C> msg;
msg->offset += 2;
msg->offset += 4; // used_item_serial
msg->WriteFlipped<u16>( menu->menu_id );
std::string convertedText = Clib::strUtf8ToCp1252( menu->title );
size_t stringlen = convertedText.length();
if ( stringlen > 80 )
stringlen = 80;
msg->Write<u8>( stringlen ); // NOTE null-term not included!
msg->Write( convertedText.c_str(), static_cast<u16>( stringlen ), false );
msg->Write<u8>( menu->menuitems_.size() );
for ( unsigned idx = 0; idx < menu->menuitems_.size(); idx++ )
{
if ( msg->offset + 85 > static_cast<u16>( sizeof msg->buffer ) )
{
return false;
}
MenuItem* mi = &menu->menuitems_[idx];
msg->WriteFlipped<u16>( mi->graphic_ );
msg->WriteFlipped<u16>( mi->color_ );
convertedText = Clib::strUtf8ToCp1252( mi->title );
stringlen = convertedText.length();
if ( stringlen > 80 )
stringlen = 80;
msg->Write<u8>( stringlen ); // NOTE null-term not included!
msg->Write( convertedText.c_str(), static_cast<u16>( stringlen ), false );
}
u16 len = msg->offset;
msg->offset = 1;
msg->WriteFlipped<u16>( len );
msg.Send( client, len );
return true;
}
void send_open_gump( Client* client, const UContainer& cont )
{
PktHelper::PacketOut<PktOut_24> msg;
msg->Write<u32>( cont.serial_ext );
msg->WriteFlipped<u16>( cont.gump() );
if ( client->ClientType & CLIENTTYPE_7090 )
msg->WriteFlipped<u16>( 0x7Du );
msg.Send( client );
}
// dave changed 11/9/3, don't send invis items to those who can't see invis
void send_container_contents( Client* client, const UContainer& cont )
{
PktHelper::PacketOut<PktOut_3C> msg;
msg->offset += 4; // msglen+count
u16 count = 0;
for ( UContainer::const_iterator itr = cont.begin(), itrend = cont.end(); itr != itrend; ++itr )
{
const Items::Item* item = *itr;
if ( !item->invisible() || client->chr->can_seeinvisitems() )
{
msg->Write<u32>( item->serial_ext );
msg->WriteFlipped<u16>( item->graphic );
msg->offset++; // unk6
msg->WriteFlipped<u16>( item->get_senditem_amount() );
msg->WriteFlipped<u16>( item->x() );
msg->WriteFlipped<u16>( item->y() );
if ( client->ClientType & CLIENTTYPE_6017 )
msg->Write<u8>( item->slot_index() );
msg->Write<u32>( cont.serial_ext );
msg->WriteFlipped<u16>( item->color ); // color
++count;
}
else
{
send_remove_object(
client, item ); // TODO: Doesn't this send a list of invisible items on the corpse?
}
}
u16 len = msg->offset;
msg->offset = 1;
msg->WriteFlipped<u16>( len );
msg->WriteFlipped<u16>( count );
msg.Send( client, len );
if ( client->acctSupports( Plib::ExpansionVersion::AOS ) )
{
// 07/11/09 Turley: moved to bottom first the client needs to know the item then we can send
// revision
for ( UContainer::const_iterator itr = cont.begin(), itrend = cont.end(); itr != itrend; ++itr )
{
const Items::Item* item = *itr;
if ( !item->invisible() || client->chr->can_seeinvisitems() )
{
send_object_cache( client, item );
}
}
}
}
} // namespace Core
} // namespace Pol