18 #include "../bscript/bobject.h" 19 #include "../bscript/impstr.h" 20 #include "../clib/clib_endian.h" 21 #include "../clib/logfacility.h" 22 #include "../clib/random.h" 23 #include "../clib/rawtypes.h" 24 #include "../plib/systemstate.h" 48 char firstchar,
u8 type,
u16 color,
u16 font )
53 if ( textbuflen == 1 )
60 if ( textcol < 2 || textcol > 1001 )
66 if ( textbuf[0] ==
'.' || textbuf[0] ==
'=' )
69 send_sysmessage( client, std::string(
"Unknown command: " ) + textbuf );
73 if ( firstchar ==
'~' )
90 u16 textlen =
static_cast<u16>( textbuflen + 1 );
98 talkmsg->Write<
u8>( type );
99 talkmsg->WriteFlipped<
u16>( textcol );
100 talkmsg->WriteFlipped<
u16>( font );
101 talkmsg->Write( chr->
name().c_str(), 30 );
102 talkmsg->Write( textbuf, textlen );
103 u16 len = talkmsg->offset;
105 talkmsg->WriteFlipped<
u16>( len );
106 talkmsg.
Send( client, len );
111 memcpy( &ghostmsg->buffer, &talkmsg->buffer,
sizeof ghostmsg->buffer );
112 ghostmsg->offset = 44;
113 char* t = &ghostmsg->buffer[ghostmsg->offset];
114 while ( ghostmsg->offset < len )
116 if ( !isspace( *t ) )
137 Network::Client* client2 = other_chr->client;
138 if ( client == client2 )
140 if ( !other_chr->is_visible_to_me( chr ) )
142 if ( other_chr->deafened() )
145 if ( !chr->dead() || other_chr->dead() || other_chr->can_hearghosts() ||
146 chr->can_be_heard_as_ghost() )
148 talkmsg.Send( client2, len );
152 ghostmsg.Send( client2, len );
160 Mobile::NPC* npc = static_cast<Mobile::NPC*>( otherchr );
161 npc->on_pc_spoke( chr, textbuf, type );
168 Mobile::NPC* npc = static_cast<Mobile::NPC*>( otherchr );
169 npc->on_ghost_pc_spoke( chr, textbuf, type );
193 for ( i = 0, textbuflen = 0; i < intextlen; i++ )
195 char ch = mymsg->
text[i];
203 textbuf[textbuflen++] = ch;
206 textbuf[textbuflen++] = 0;
217 if ( textcol < 2 || textcol > 1001 )
233 wstring wtmp( L
"Unknown command: " );
235 for (
size_t i = 0; i < wtextlen; i++ )
236 wtmp += static_cast<wchar_t>(
cfBEu16( wtext[i] ) );
262 talkmsg->offset += 2;
265 talkmsg->Write<
u8>( msgin->
type );
266 talkmsg->WriteFlipped<
u16>( textcol );
267 talkmsg->WriteFlipped<
u16>( msgin->
font );
268 talkmsg->Write( msgin->
lang, 4 );
269 talkmsg->Write( chr->
name().c_str(), 30 );
270 talkmsg->Write( &wtext[0], static_cast<u16>( wtextlen ),
false );
271 u16 len = talkmsg->offset;
273 talkmsg->WriteFlipped<
u16>( len );
276 if ( msgin->
type == 0x0d )
278 auto thisguild = chr->guild();
284 if ( !client2->
ready )
286 if ( thisguild->guildid() == client2->
chr->
guildid() )
287 talkmsg.
Send( client2, len );
291 else if ( msgin->
type == 0x0e )
293 auto thisguild = chr->guild();
299 if ( !client2->
ready )
301 auto otherguild = client2->
chr->guild();
302 if ( otherguild !=
nullptr )
304 if ( thisguild->guildid() == otherguild->guildid() ||
305 ( thisguild->hasAlly( otherguild ) ) )
306 talkmsg.
Send( client2, len );
313 talkmsg.
Send( client, len );
316 memcpy( &ghostmsg->buffer, &talkmsg->buffer,
sizeof ghostmsg->buffer );
318 ghostmsg->offset = 48;
319 u16* t = ( (
u16*)&ghostmsg->buffer[ghostmsg->offset] );
320 while ( ghostmsg->offset < len - 2 )
322 wchar_t wch = ( *t );
323 if ( !iswspace( wch ) )
331 ghostmsg->offset += 2;
344 Network::Client* client2 = otherchr->client;
345 if ( client == client2 )
347 if ( !otherchr->is_visible_to_me( chr ) )
349 if ( otherchr->deafened() )
352 if ( !chr->dead() || otherchr->dead() || otherchr->can_hearghosts() ||
353 chr->can_be_heard_as_ghost() )
355 talkmsg.Send( client2, len );
359 ghostmsg.Send( client2, len );
367 Mobile::NPC* npc = static_cast<Mobile::NPC*>( otherchr );
368 npc->on_pc_spoke( chr, ntext, msgin->type, wtext, msgin->lang, speechtokens );
375 Mobile::NPC* npc = static_cast<Mobile::NPC*>( otherchr );
376 npc->on_ghost_pc_spoke( chr, ntext, msgin->type, wtext, msgin->lang, speechtokens );
380 msgin->
lang, static_cast<int>( wtextlen ), speechtokens );
386 int thenibble = theindex * 3;
387 int thebyte = thenibble / 2;
389 theresult =
cfBEu16( *( (
u16*)( thearray + thebyte ) ) ) & 0x0FFF;
391 theresult =
cfBEu16( *( (
u16*)( thearray + thebyte ) ) ) >> 4;
399 if ( ( bytemsg[i] & 0x80 ) == 0 )
401 unicodeChar = bytemsg[i];
405 if ( ( bytemsg[i] & 0xE0 ) == 0xC0 )
408 if ( ( bytemsg[i + 1] & 0xC0 ) == 0x80 )
410 result = ( ( bytemsg[i] & 0x1F ) << 6 ) | ( bytemsg[i + 1] & 0x3F );
411 unicodeChar = result;
415 else if ( ( bytemsg[i] & 0xF0 ) == 0xE0 )
418 if ( ( ( bytemsg[i + 1] & 0xC0 ) == 0x80 ) && ( ( bytemsg[i + 2] & 0xC0 ) == 0x80 ) )
420 result = ( ( bytemsg[i] & 0x0F ) << 12 ) | ( ( bytemsg[i + 1] & 0x3F ) < 6 ) |
421 ( bytemsg[i + 2] & 0x3F );
422 unicodeChar = result;
441 std::unique_ptr<Bscript::ObjArray> speechtokens(
nullptr );
452 if ( msgin->
type & 0xc0 )
455 wtextoffset = ( ( ( ( numtokens + 1 ) * 3 ) / 2 ) + ( ( numtokens + 1 ) % 2 ) );
456 bytemsg = ( ( (
u8*)themsg ) + wtextoffset );
466 tempbuf[j++] =
cfBEu16( unicodeChar );
486 for ( i = 0; i < intextlen; i++ )
493 wtextbuf[wtextbuflen++] =
ctBEu16( wc );
494 ntextbuf[ntextbuflen++] = wcout.narrow( (
wchar_t)wc,
'?' );
496 wtextbuf[wtextbuflen++] = (
u16)0;
497 ntextbuf[ntextbuflen++] = 0;
499 if ( msgin->
type & 0xc0 )
502 if ( speechtokens.get() == nullptr )
504 for (
u16 j = 0; j < numtokens; j++ )
507 speechtokens->addElement( atoken );
515 msgin->
type &= ( ~0xC0 );
519 speechtokens.release() );
unsigned int guildid() const
bool process_command(Network::Client *client, const char *text, const u16 *wtext, const char *lang)
ExportedFunction * speechmul_hook
bool call(Bscript::BObjectImp *p0)
bool process_tildecommand(Network::Client *client, const char *textbuf)
unsigned short whisper_range
unsigned short yell_range
void sayto_listening_points(Mobile::Character *speaker, const char *p_text, int, u8 texttype, const u16 *p_wtext, const char *p_lang, int p_wtextlen, Bscript::ObjArray *speechtokens)
static void InRange(u16 x, u16 y, const Realms::Realm *realm, unsigned range, F &&f)
void handle_processed_speech(Network::Client *client, char *textbuf, int textbuflen, char firstchar, u8 type, u16 color, u16 font)
char text[SPEECH_MAX_LEN+1]
bool core_sends_guildmsgs
u16 Get12BitNumber(u8 *thearray, u16 theindex)
NetworkManager networkManager
void UnicodeSpeechHandler(Network::Client *client, PKTIN_AD *msgin)
void Send(Client *client, int len=-1) const
unsigned short speech_range
bool can_be_heard_as_ghost() const
SettingsManager settingsManager
int GetNextUTF8(u8 *bytemsg, int i, u16 &unicodeChar)
void SpeechHandler(Network::Client *client, PKTIN_03 *mymsg)
void SendUnicodeSpeech(Network::Client *client, PKTIN_AD *msgin, u16 *wtext, size_t wtextlen, char *ntext, size_t ntextlen, Bscript::ObjArray *speechtokens)
u16 last_textcolor() const
virtual std::string name() const
Bscript::BObjectImp * make_mobileref(Mobile::Character *chr)
void send_sysmessage(Network::Client *client, const char *text, unsigned short font, unsigned short color)