Pol  Revision:cb584c9
dblclick.cpp
Go to the documentation of this file.
1 
17 #include <cstring>
18 #include <string>
19 
20 #include "../bscript/eprog.h"
21 #include "../clib/clib_endian.h"
22 #include "../clib/rawtypes.h"
23 #include "../clib/refptr.h"
24 #include "../plib/systemstate.h"
25 #include "containr.h"
26 #include "eventid.h"
27 #include "gameclck.h"
28 #include "item/item.h"
29 #include "item/itemdesc.h"
30 #include "mobile/charactr.h"
31 #include "mobile/npc.h"
32 #include "network/client.h"
33 #include "network/packethelper.h"
34 #include "network/packets.h"
35 #include "objtype.h"
36 #include "pktdef.h"
37 #include "pktin.h"
38 #include "realms/realm.h"
39 #include "scrdef.h"
40 #include "scrsched.h"
41 #include "scrstore.h"
42 #include "ufunc.h"
43 #include "uobject.h"
44 #include "uoscrobj.h"
45 
46 namespace Pol
47 {
48 namespace Core
49 {
51 {
53  msg->Write<u32>( chr->serial_ext );
54 
55  if ( ( !settingsManager.ssopt.privacy_paperdoll ) || ( client->chr == chr ) )
56  {
57  std::string name = ( !chr->has_title_prefix() ? "" : chr->title_prefix() + " " ) + chr->name() +
58  ( !chr->has_title_suffix() ? "" : " " + chr->title_suffix() );
59  if ( chr->has_title_race() )
60  name += " (" + chr->title_race() + ")";
61  msg->Write( name.c_str(), 60 );
62  }
63  else
64  msg->Write( chr->name().c_str(), 60 );
65 
66 
67  // MuadDib changed to reflect true status for 0x20 packet. 1/4/2007
68  // Paperdoll Appears different type Status byte than other walk/update
69  // packets. Using poison/hidden here will break peace/war button.
70  u8 flag1 = chr->warmode() ? 1 : 0;
71  if ( client->UOExpansionFlag & Network::AOS && client->chr->serial_ext == chr->serial_ext )
72  flag1 |= CHAR_FLAG1_CANALTER;
73  msg->Write<u8>( flag1 );
74 
75  msg.Send( client );
76 }
77 
78 void doubleclick( Network::Client* client, PKTIN_06* msg )
79 {
80  u32 serial = cfBEu32( msg->serial );
81  u32 paperdoll_macro_flag = serial & 0x80000000Lu;
82  serial &= ~0x80000000Lu; // keypress versus doubleclick switch?
83 
84  // the find_character would find this, but most of the time it's your own paperdoll.
85  // this is special-cased for two reasons:
86  // 1) it's commonly done
87  // 2) ghosts can doubleclick ONLY their paperdoll.
88  if ( serial == client->chr->serial )
89  {
90  if ( !paperdoll_macro_flag )
91  {
92  ScriptDef sd;
93  sd.quickconfig( "scripts/misc/dblclickself.ecl" );
94  if ( sd.exists() )
95  {
97  prog = find_script2( sd, false, Plib::systemstate.config.cache_interactive_scripts );
98  if ( prog.get() != nullptr && client->chr->start_script( prog.get(), false ) )
99  {
100  return;
101  }
102  }
103  }
104  send_paperdoll( client, client->chr );
105  return;
106  }
107 
108  if ( client->chr->dblclick_wait() > read_gameclock() )
109  {
110  private_say_above( client->chr, client->chr, "You must wait to use something again." );
111  return;
112  }
113  else
114  client->chr->dblclick_wait( read_gameclock() + settingsManager.ssopt.dblclick_wait );
115 
116  if ( IsCharacter( serial ) )
117  {
118  if ( client->chr->dead() )
119  return;
120  Mobile::Character* chr = find_character( serial );
121  if ( !chr )
122  return;
123 
124  if ( chr->isa( UOBJ_CLASS::CLASS_NPC ) )
125  {
126  Mobile::NPC* npc = static_cast<Mobile::NPC*>( chr );
127  if ( npc->can_accept_event( EVID_DOUBLECLICKED ) )
128  {
129  npc->send_event( new Module::SourcedEvent( EVID_DOUBLECLICKED, client->chr ) );
130  return;
131  }
132  }
133 
134  bool script_ran = false;
135  ScriptDef sd;
136  sd.quickconfig( "scripts/misc/dblclickother.ecl" );
137  if ( sd.exists() )
138  {
140  prog = find_script2( sd, false, Plib::systemstate.config.cache_interactive_scripts );
141  if ( prog.get() != nullptr )
142  script_ran =
143  client->chr->start_script( prog.get(), false, new Module::ECharacterRefObjImp( chr ) );
144  }
145  if ( !script_ran && inrange( client->chr, chr ) )
146  {
147  // MuadDib Changed from a large if || || || to switch case. 1/4/2007
148  switch ( chr->graphic )
149  {
150  case UOBJ_HUMAN_MALE:
151  case UOBJ_HUMAN_FEMALE:
154  case UOBJ_ELF_MALE:
155  case UOBJ_ELF_FEMALE:
156  case UOBJ_ELF_MALE_GHOST:
158  case UOBJ_GARGOYLE_MALE:
162  case UOBJ_GAMEMASTER:
163  case 0x3de:
164  case 0x3df:
165  case 0x3e2:
166  send_paperdoll( client, chr );
167  break;
168  }
169  }
170  return;
171  }
172  else // doubleclicked an item
173  {
174  // next, search worn items, items in the backpack, and items in the world.
175  Items::Item* item = find_legal_item( client->chr, serial );
176 
177  // next, check people's backpacks. (don't recurse down)
178  // (not done yet)
179 
180  if ( item != nullptr )
181  {
182  const Items::ItemDesc& id = item->itemdesc();
183 
184  if ( !id.ghosts_can_use && client->chr->dead() )
185  {
186  private_say_above( client->chr, client->chr, "I am dead and cannot do that." );
187  return;
188  }
189  if ( !id.can_use_while_frozen && client->chr->frozen() )
190  {
191  private_say_above( client->chr, client->chr, "I am frozen and cannot do that." );
192  return;
193  }
194  if ( !id.can_use_while_paralyzed && client->chr->paralyzed() )
195  {
196  private_say_above( client->chr, client->chr, "I am paralyzed and cannot do that." );
197  return;
198  }
199 
200  unsigned short dst = pol_distance( client->chr, item );
201  if ( dst > id.doubleclick_range && !client->chr->can_dblclickany() )
202  {
203  private_say_above( client->chr, item, "That is too far away." );
204  return;
205  }
206  UObject* obj = item->toplevel_owner();
207  obj = obj->self_as_owner();
208  if ( id.use_requires_los && !client->chr->realm->has_los( *client->chr, *obj ) ) // DAVE
209  // 11/24
210  {
211  private_say_above( client->chr, item, "I can't see that." );
212  return;
213  }
214 
215  ScriptDef sd;
216  sd.quickconfig( "scripts/misc/dblclickitem.ecl" );
217  if ( sd.exists() )
218  {
220  prog = find_script2( sd, false, Plib::systemstate.config.cache_interactive_scripts );
221  if ( prog.get() != nullptr )
222  client->chr->start_script( prog.get(), false, new Module::EItemRefObjImp( item ) );
223  }
224 
225  item->double_click( client );
226  return;
227  }
228 
229  // allow looking into containers being traded
230  if ( client->chr->is_trading() )
231  {
232  UContainer* cont = client->chr->trade_container()->find_container( serial );
233  if ( cont != nullptr )
234  {
235  cont->builtin_on_use( client );
236  if ( !cont->locked() )
237  {
238  if ( client->chr->trading_with->client != nullptr )
239  cont->builtin_on_use( client->chr->trading_with->client );
240  }
241  return;
242  }
243  }
244  }
245 }
246 }
247 }
unsigned char u8
Definition: rawtypes.h:25
#define UOBJ_GARGOYLE_FEMALE
Definition: objtype.h:136
bool can_accept_event(Core::EVENTID eventid)
Definition: npc.cpp:877
#define UOBJ_GARGOYLE_MALE
Definition: objtype.h:135
UContainer * find_container(u32 serial) const
Definition: containr.cpp:575
ref_ptr< Bscript::EScriptProgram > find_script2(const ScriptDef &script, bool complain_if_not_found, bool cache_script)
Definition: scrstore.cpp:83
void quickconfig(const Plib::Package *pkg, const std::string &name_ecl)
Definition: scrdef.cpp:112
bool send_event(Bscript::BObjectImp *event)
Definition: npc.cpp:887
bool can_dblclickany() const
Definition: charactr.h:1036
SystemState systemstate
Definition: systemstate.cpp:12
virtual UObject * toplevel_owner() POL_OVERRIDE
Definition: item.cpp:252
#define cfBEu32(x)
Definition: clib_endian.h:43
#define UOBJ_ELF_FEMALE
Definition: objtype.h:131
T * get() const
Definition: refptr.h:176
void send_paperdoll(Network::Client *client, Mobile::Character *chr)
Definition: dblclick.cpp:50
bool inrange(const UObject *c1, unsigned short x, unsigned short y)
Definition: ufunc.cpp:454
virtual void builtin_on_use(Network::Client *client) POL_OVERRIDE
Definition: containr.cpp:690
bool frozen() const
Definition: charactr.h:969
Item * find_legal_item(const Character *chr, u32 serial, bool *additlegal, bool *isRemoteContainer)
Definition: ufunc.cpp:958
Mobile::Character * chr
Definition: client.h:182
bool private_say_above(Character *chr, const UObject *obj, const char *text, unsigned short font, unsigned short color, unsigned int journal_print)
Definition: ufunc.cpp:1328
#define UOBJ_GARGOYLE_FEMALE_GHOST
Definition: objtype.h:138
unsigned int u32
Definition: rawtypes.h:27
#define UOBJ_HUMAN_MALE
Definition: objtype.h:125
Core::UContainer * trade_container()
Definition: charactr.cpp:4142
const u16 AOS
Definition: client.h:75
bool exists() const
Definition: scrdef.cpp:126
bool warmode() const
Definition: charactr.cpp:3067
#define UOBJ_GARGOYLE_MALE_GHOST
Definition: objtype.h:137
virtual UObject * self_as_owner()
Definition: uobject.cpp:224
bool locked() const
Definition: lockable.h:65
void Send(Client *client, int len=-1) const
Definition: packethelper.h:69
Core::CharacterRef trading_with
Definition: charactr.h:857
#define UOBJ_HUMAN_MALE_GHOST
Definition: objtype.h:127
virtual void double_click(Network::Client *client)
Definition: item.cpp:510
bool has_los(const Core::ULWObject &att, const Core::ULWObject &tgt) const
Definition: realmlos.cpp:146
bool is_trading() const
Definition: charactr.cpp:4117
bool paralyzed() const
Definition: charactr.h:974
void doubleclick(Network::Client *client, PKTIN_06 *msg)
Definition: dblclick.cpp:78
unsigned int dblclick_wait
Definition: ssopt.h:43
#define UOBJ_HUMAN_FEMALE_GHOST
Definition: objtype.h:128
gameclock_t read_gameclock()
Reads the current value of the game clock.
Definition: gameclck.cpp:57
Mobile::Character * find_character(u32 serial)
Definition: fnsearch.cpp:60
#define UOBJ_ELF_MALE_GHOST
Definition: objtype.h:132
SettingsManager settingsManager
Definition: settings.cpp:14
#define UOBJ_HUMAN_FEMALE
Definition: objtype.h:126
bool IsCharacter(u32 serial)
Definition: uobject.h:311
#define UOBJ_GAMEMASTER
Definition: objtype.h:200
unsigned short pol_distance(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2)
Definition: ufunc.cpp:481
Realms::Realm * realm
Definition: baseobject.h:56
std::string name
Definition: osmod.cpp:943
#define UOBJ_ELF_MALE
Definition: objtype.h:130
bool isa(UOBJ_CLASS uobj_class) const
Definition: baseobject.h:99
bool start_script(Bscript::EScriptProgram *prog, bool start_attached, Bscript::BObjectImp *param2=nullptr, Bscript::BObjectImp *param3=nullptr, Bscript::BObjectImp *param4=nullptr)
Definition: chrituse.cpp:30
const ItemDesc & itemdesc() const
Definition: item.cpp:127
virtual std::string name() const
Definition: uobject.cpp:196
bool privacy_paperdoll
Definition: ssopt.h:62
#define UOBJ_ELF_FEMALE_GHOST
Definition: objtype.h:133
Definition: berror.cpp:12
bool dead() const
Definition: charactr.h:931
const u8 CHAR_FLAG1_CANALTER
Definition: pktdef.h:103