Pol  Revision:f37d500
privupdater.h
Go to the documentation of this file.
1 #ifndef PRIVUPDATER_H
2 #define PRIVUPDATER_H
3 
4 #ifndef __CHARACTR_H
5 #include "charactr.h"
6 #endif
7 
8 #ifndef H_NPC_H
9 // At some point, npc.h should be removed.
10 // The only dependence is to send leftarea/enteredarea events.
11 #include "npc.h"
12 #endif
13 
14 #include "../../clib/passert.h"
15 #include "../ufunc.h"
16 #include "../uworld.h"
17 
18 namespace Pol
19 {
20 namespace Mobile
21 {
22 // This class deal with the side effects of activating/revoking privileges
23 // it can be used as a watcher by instanciating or directly via the statics
25 {
26 public:
27  PrivUpdater( Character* chr, PRIV_FLAGS flag );
28  ~PrivUpdater();
29 
30 private:
33  bool oldvalue_;
34 
35 public:
36  static void on_change_see_hidden( Character* chr, bool enable );
37  static void on_change_see_ghosts( Character* chr, bool enable );
38  static void on_change_see_invis_items( Character* chr, bool enable );
39  static void on_change_invul( Character* chr, bool enable );
40 
41 private:
42  static bool is_active_or_npc( Character* chr );
43 
44  // Helper functions for the loops
45  static void enable_see_hidden( Character* in_range_chr, Character* chr );
46  static void disable_see_hidden( Character* in_range_chr, Character* chr );
47 
48  static void enable_see_ghosts( Character* in_range_chr, Character* chr );
49  static void disable_see_ghosts( Character* in_range_chr, Character* chr );
50 
51  static void enable_see_invis_items( Items::Item* in_range_item, Character* chr );
52  static void disable_see_invis_items( Items::Item* in_range_item, Character* chr );
53 
54  static void enable_invul( Character* in_range_chr, Character* chr );
55  static void disable_invul( Character* in_range_chr, Character* chr,
57 };
58 
59 
61  : chr_( chr ),
62  flag_( flag ),
63  oldvalue_( chr_ != nullptr ? chr_->cached_settings.get( flag_ ) : false )
64 {
65 }
66 
68 {
69  if ( chr_ == nullptr )
70  return;
71  bool newvalue = chr_->cached_settings.get( flag_ );
72  if ( oldvalue_ == newvalue )
73  return;
74  switch ( flag_ )
75  {
76  case PRIV_FLAGS::INVUL:
77  on_change_invul( chr_, newvalue );
78  break;
80  on_change_see_ghosts( chr_, newvalue );
81  break;
83  on_change_see_hidden( chr_, newvalue );
84  break;
86  on_change_see_invis_items( chr_, newvalue );
87  break;
88  default:
89  passert_always( 0 );
90  break;
91  }
92 }
93 
95 {
96  if ( !is_active_or_npc( chr ) )
97  return; // don't do useless work
98 
99  if ( enable )
100  {
102  chr, [&]( Character* zonechr ) { enable_see_hidden( zonechr, chr ); } );
103  }
104  else
105  {
107  chr, [&]( Character* zonechr ) { disable_see_hidden( zonechr, chr ); } );
108  }
109 }
110 
112 {
113  if ( !is_active_or_npc( chr ) )
114  return; // don't do useless work
115 
116  if ( enable )
117  {
119  chr, [&]( Character* zonechr ) { enable_see_ghosts( zonechr, chr ); } );
120  }
121  else
122  {
124  chr, [&]( Character* zonechr ) { disable_see_ghosts( zonechr, chr ); } );
125  }
126 }
127 
129 {
130  // NPCs don't care about invisible items, so we only need to check for active clients.
131  if ( chr == NULL || !chr->has_active_client() )
132  return;
133 
134  if ( enable )
135  {
137  chr, [&]( Items::Item* zoneitem ) { enable_see_invis_items( zoneitem, chr ); } );
138  }
139  else
140  {
142  chr, [&]( Items::Item* zoneitem ) { disable_see_invis_items( zoneitem, chr ); } );
143  }
144 }
145 
146 void PrivUpdater::on_change_invul( Character* chr, bool enable )
147 {
148  if ( !is_active_or_npc( chr ) )
149  return; // don't do useless work
150 
151  if ( enable )
152  {
154  chr, [&]( Character* zonechr ) { enable_invul( zonechr, chr ); } );
155  }
156  else
157  {
159  Network::HealthBarStatusUpdate::Color::YELLOW, false );
161  chr, [&]( Character* zonechr ) { disable_invul( zonechr, chr, msg ); } );
162  }
163 }
164 
166 {
167  return chr != NULL && ( chr->has_active_client() || chr->isa( Core::UOBJ_CLASS::CLASS_NPC ) );
168 }
169 
171 {
172  if ( in_range_chr->hidden() && in_range_chr != chr )
173  {
174  if ( chr->client )
175  send_owncreate( chr->client, in_range_chr );
176  else if ( chr->isa( Core::UOBJ_CLASS::CLASS_NPC ) )
177  {
178  NPC* npc = static_cast<NPC*>( chr );
180  npc->send_event( new Module::SourcedEvent( Core::EVID_ENTEREDAREA, in_range_chr ) );
181  }
182  }
183 }
184 
186 {
187  if ( in_range_chr->hidden() && in_range_chr != chr )
188  {
189  if ( chr->client )
190  send_remove_character( chr->client, in_range_chr );
191  else if ( chr->isa( Core::UOBJ_CLASS::CLASS_NPC ) )
192  {
193  NPC* npc = static_cast<NPC*>( chr );
195  npc->send_event( new Module::SourcedEvent( Core::EVID_LEFTAREA, in_range_chr ) );
196  }
197  }
198 }
199 
201 {
202  if ( in_range_chr->dead() && in_range_chr != chr )
203  {
204  if ( chr->client )
205  send_owncreate( chr->client, in_range_chr );
206  else if ( chr->isa( Core::UOBJ_CLASS::CLASS_NPC ) )
207  {
208  NPC* npc = static_cast<NPC*>( chr );
210  npc->send_event( new Module::SourcedEvent( Core::EVID_ENTEREDAREA, in_range_chr ) );
211  }
212  }
213 }
214 
216 {
217  if ( in_range_chr->dead() && in_range_chr != chr )
218  {
219  if ( chr->client )
220  send_remove_character( chr->client, in_range_chr );
221  else if ( chr->isa( Core::UOBJ_CLASS::CLASS_NPC ) )
222  {
223  NPC* npc = static_cast<NPC*>( chr );
225  npc->send_event( new Module::SourcedEvent( Core::EVID_LEFTAREA, in_range_chr ) );
226  }
227  }
228 }
229 
231 {
232  if ( in_range_item->invisible() )
233  {
234  send_item( chr->client, in_range_item );
235  }
236 }
237 
239 {
240  if ( in_range_item->invisible() )
241  {
242  send_remove_object( chr->client, in_range_item );
243  }
244 }
245 
246 void PrivUpdater::enable_invul( Character* in_range_chr, Character* chr )
247 {
248  if ( in_range_chr != chr )
249  {
250  if ( in_range_chr->is_visible_to_me( chr ) )
251  {
252  send_owncreate( in_range_chr->client, chr );
253  }
254  }
255  else
256  {
257  // If it's the same, it can't be a NPC and must be active because of the OnlinePlayerFilter,
258  // so it tells itself.
259  send_move( chr->client, chr );
260  }
261 }
262 
265 {
266  if ( in_range_chr != chr )
267  {
268  if ( in_range_chr->is_visible_to_me( chr ) )
269  {
270  send_owncreate( in_range_chr->client, chr );
271 
272  // Needs to update the healthbar, because send_owncreate only sends if invul() == true.
273  msg.Send( in_range_chr->client );
274  }
275  }
276  else
277  {
278  send_move( chr->client,
279  chr ); // tells itself if player (same justification as in enable_invul)
280 
281  // Needs to update the healthbar to the player as well
282  msg.Send( chr->client );
283  }
284 }
285 }
286 }
287 
288 #endif
bool can_accept_event(Core::EVENTID eventid)
Definition: npc.cpp:879
static void enable_see_invis_items(Items::Item *in_range_item, Character *chr)
Definition: privupdater.h:230
bool send_event(Bscript::BObjectImp *event)
Definition: npc.cpp:889
static void disable_invul(Character *in_range_chr, Character *chr, Network::HealthBarStatusUpdate &msg)
Definition: privupdater.h:263
static bool is_active_or_npc(Character *chr)
Definition: privupdater.h:165
Network::Client * client
Definition: charactr.h:871
bool is_visible_to_me(const Character *chr) const
Definition: charactr.cpp:2658
bool has_active_client() const
Definition: charactr.cpp:448
bool get(ENUM flag) const
Definition: uobject.h:108
virtual void Send(Client *client) POL_OVERRIDE
Definition: packetdefs.cpp:856
void send_remove_character(Client *client, const Character *chr)
Definition: ufunc.cpp:355
void send_move(Client *client, const Character *chr)
Definition: ufunc.cpp:174
static void on_change_see_ghosts(Character *chr, bool enable)
Definition: privupdater.h:111
static void on_change_invul(Character *chr, bool enable)
Definition: privupdater.h:146
void send_remove_object(Client *client, const UObject *object)
Definition: ufunc.cpp:420
PrivUpdater(Character *chr, PRIV_FLAGS flag)
Definition: privupdater.h:60
static void on_change_see_invis_items(Character *chr, bool enable)
Definition: privupdater.h:128
static void enable_see_hidden(Character *in_range_chr, Character *chr)
Definition: privupdater.h:170
Core::AttributeFlags< PRIV_FLAGS > cached_settings
Definition: charactr.h:895
static void disable_see_invis_items(Items::Item *in_range_item, Character *chr)
Definition: privupdater.h:238
static void InVisualRange(const UObject *obj, F &&f)
Definition: uworld.h:245
static void disable_see_ghosts(Character *in_range_chr, Character *chr)
Definition: privupdater.h:215
void send_item(Client *client, const Item *item)
Definition: ufunc.cpp:676
static void disable_see_hidden(Character *in_range_chr, Character *chr)
Definition: privupdater.h:185
bool invisible() const
Definition: item.h:324
static void on_change_see_hidden(Character *chr, bool enable)
Definition: privupdater.h:94
bool isa(UOBJ_CLASS uobj_class) const
Definition: baseobject.h:99
#define passert_always(exp)
Definition: passert.h:80
static void enable_see_ghosts(Character *in_range_chr, Character *chr)
Definition: privupdater.h:200
void send_owncreate(Client *client, const Character *chr)
Definition: ufunc.cpp:206
static void enable_invul(Character *in_range_chr, Character *chr)
Definition: privupdater.h:246
Definition: berror.cpp:12
bool dead() const
Definition: charactr.h:931
bool hidden() const
Definition: charactr.h:941