Pol  Revision:cb584c9
umap.cpp
Go to the documentation of this file.
1 
10 #include "umap.h"
11 
12 #include <stdio.h>
13 #include <string>
14 
15 #include "../bscript/berror.h"
16 #include "../bscript/bobject.h"
17 #include "../bscript/bstruct.h"
18 #include "../bscript/executor.h"
19 #include "../bscript/objmethods.h"
20 #include "../clib/cfgelem.h"
21 #include "../clib/clib_endian.h"
22 #include "../clib/streamsaver.h"
23 #include "item/itemdesc.h"
24 #include "network/client.h"
25 #include "network/packethelper.h"
26 #include "network/packets.h"
27 #include "pktboth.h"
28 #include "realms/realm.h"
29 #include "ufunc.h"
30 #include "uobject.h"
31 
32 namespace Pol
33 {
34 namespace Core
35 {
36 Map::Map( const Items::MapDesc& mapdesc )
37  : Item( mapdesc, UOBJ_CLASS::CLASS_ITEM ),
38  gumpwidth( 0 ),
39  gumpheight( 0 ),
40  editable( mapdesc.editable ),
41  plotting( false ),
42  pin_points( 0 ),
43  xwest( 0 ),
44  xeast( 0 ),
45  ynorth( 0 ),
46  ysouth( 0 ),
47  facetid( 0 )
48 {
49 }
50 
52 
54 {
56 
57  sw() << "\txwest\t" << xwest << pf_endl;
58  sw() << "\tynorth\t" << ynorth << pf_endl;
59  sw() << "\txeast\t" << xeast << pf_endl;
60  sw() << "\tysouth\t" << ysouth << pf_endl;
61  sw() << "\tgumpwidth\t" << gumpwidth << pf_endl;
62  sw() << "\tgumpheight\t" << gumpheight << pf_endl;
63  sw() << "\tfacetid\t" << facetid << pf_endl;
64 
65  sw() << "\teditable\t" << editable << pf_endl;
66 
67  printPinPoints( sw );
68 
69  sw() << pf_endl;
70 }
71 
73 {
74  PinPoints::const_iterator itr;
75  int i = 0;
76  sw() << "\tNumPins " << pin_points.size() << pf_endl;
77 
78  for ( itr = pin_points.begin(); itr != pin_points.end(); ++itr, ++i )
79  {
80  sw() << "\tPin" << i << " " << itr->x << "," << itr->y << pf_endl;
81  }
82 }
83 
85 {
86  base::readProperties( elem );
87 
88  xwest = elem.remove_ushort( "xwest", 0 );
89  ynorth = elem.remove_ushort( "ynorth", 0 );
90  xeast = elem.remove_ushort( "xeast", 0 );
91  ysouth = elem.remove_ushort( "ysouth", 0 );
92  gumpwidth = elem.remove_ushort( "gumpwidth", 0 );
93  gumpheight = elem.remove_ushort( "gumpheight", 0 );
94  facetid = elem.remove_ushort( "facetid", 0 );
95  editable = elem.remove_bool( "editable", 0 );
96 
97  unsigned short numpins = elem.remove_ushort( "NumPins", 0 );
98  std::string pinval;
99  char search_string[6];
100  int i, px, py;
101  struct PinPoint pp;
102 
103  for ( i = 0; i < numpins; i++ )
104  {
105  sprintf( search_string, "Pin%i", i );
106  pinval = elem.remove_string( search_string );
107  sscanf( pinval.c_str(), "%i,%i", &px, &py );
108 
109  pp.x = static_cast<unsigned short>( px );
110  pp.y = static_cast<unsigned short>( py );
111 
112  pin_points.push_back( pp );
113  }
114 }
115 
117 {
118  if ( gumpwidth && gumpheight )
119  {
120  if ( client->ClientType & Network::CLIENTTYPE_70130 )
121  {
123  msgF5->Write<u32>( serial_ext );
124  msgF5->Write<u8>( 0x13u );
125  msgF5->Write<u8>( 0x9du );
126  msgF5->WriteFlipped<u16>( xwest );
127  msgF5->WriteFlipped<u16>( ynorth );
128  msgF5->WriteFlipped<u16>( xeast );
129  msgF5->WriteFlipped<u16>( ysouth );
130  msgF5->WriteFlipped<u16>( gumpwidth );
131  msgF5->WriteFlipped<u16>( gumpheight );
132  msgF5->WriteFlipped<u16>( facetid );
133  msgF5.Send( client );
134  }
135  else
136  {
138  msg90->Write<u32>( serial_ext );
139  msg90->Write<u8>( 0x13u );
140  msg90->Write<u8>( 0x9du );
141  msg90->WriteFlipped<u16>( xwest );
142  msg90->WriteFlipped<u16>( ynorth );
143  msg90->WriteFlipped<u16>( xeast );
144  msg90->WriteFlipped<u16>( ysouth );
145  msg90->WriteFlipped<u16>( gumpwidth );
146  msg90->WriteFlipped<u16>( gumpheight );
147  msg90.Send( client );
148  }
149 
151  msg56->Write<u32>( serial_ext );
152  msg56->Write<u8>( PKTBI_56::TYPE_REMOVE_ALL );
153  msg56->offset += 5; // u8 pinidx,u16 pinx,piny
154  msg56.Send( client );
155 
156  // need to send each point to the client
157 
158  if ( !pin_points.empty() )
159  {
160  msg56->offset = 5; // msgtype+serial_ext
161  msg56->Write<u8>( PKTBI_56::TYPE_ADD );
162  // u8 pinidx still 0
163 
164  for ( pin_points_itr itr = pin_points.begin(), end = pin_points.end(); itr != end; ++itr )
165  {
166  msg56->offset = 7; // msgtype+serial_ext+type,pinidx
167  msg56->WriteFlipped<u16>( worldXtoGumpX( itr->x ) );
168  msg56->WriteFlipped<u16>( worldYtoGumpY( itr->y ) );
169  msg56.Send( client );
170  }
171  }
172  }
173 }
174 
176 {
177  using namespace Bscript;
178  BObjectImp* imp = base::script_method_id( id, ex );
179  if ( imp != nullptr )
180  return imp;
181 
182  switch ( id )
183  {
184  case MTH_GETPINS:
185  {
186  std::unique_ptr<ObjArray> arr( new ObjArray );
187  for ( PinPoints::iterator itr = pin_points.begin(); itr != pin_points.end(); ++itr )
188  {
189  std::unique_ptr<BStruct> struc( new BStruct );
190  struc->addMember( "x", new BLong( itr->x ) );
191  struc->addMember( "y", new BLong( itr->y ) );
192 
193  arr->addElement( struc.release() );
194  }
195  return arr.release();
196  }
197 
198  case MTH_INSERTPIN:
199  {
200  int idx;
201  unsigned short px, py;
202  if ( ex.getParam( 0, idx, static_cast<int>( pin_points.size() ) ) && ex.getParam( 1, px ) &&
203  ex.getParam( 2, py ) )
204  {
205  struct PinPoint pp;
206  pin_points_itr itr;
207 
208  if ( !realm->valid( px, py, 0 ) )
209  return new BError( "Invalid Coordinates for Realm" );
210  pp.x = px;
211  pp.y = py;
212 
213  itr = pin_points.begin();
214  itr += idx;
215 
216  set_dirty();
217  pin_points.insert( itr, pp );
218 
219  return new BLong( 1 );
220  }
221  else
222  {
223  return new BError( "Invalid parameter type" );
224  }
225  }
226 
227  case MTH_APPENDPIN:
228  {
229  unsigned short px, py;
230  if ( ex.getParam( 0, px ) && ex.getParam( 1, py ) )
231  {
232  struct PinPoint pp;
233  if ( !realm->valid( px, py, 0 ) )
234  return new BError( "Invalid Coordinates for Realm" );
235  pp.x = px;
236  pp.y = py;
237  set_dirty();
238  pin_points.push_back( pp );
239  return new BLong( 1 );
240  }
241  else
242  {
243  return new BError( "Invalid parameter type" );
244  }
245  }
246 
247  case MTH_ERASEPIN:
248  {
249  int idx;
250  if ( ex.getParam( 0, idx, static_cast<int>( pin_points.size() - 1 ) ) )
251  {
252  pin_points_itr itr;
253 
254  itr = pin_points.begin();
255  itr += idx;
256 
257  set_dirty();
258  pin_points.erase( itr );
259  return new BLong( 1 );
260  }
261  else
262  {
263  return new BError( "Index Out of Range" );
264  }
265  }
266 
267  default:
268  return nullptr;
269  }
270 }
271 
272 
274 {
275  Bscript::BObjectImp* imp = base::script_method( methodname, ex );
276  if ( imp != nullptr )
277  return imp;
278 
279  Bscript::ObjMethod* objmethod = Bscript::getKnownObjMethod( methodname );
280  if ( objmethod != nullptr )
281  return this->script_method_id( objmethod->id, ex );
282  else
283  return nullptr;
284 }
285 
287 {
288  u16 newx, newy;
289  newx = cfBEu16( msg->pinx );
290  newy = cfBEu16( msg->piny );
291 
292  if ( ( ( newx + get_xwest() ) > get_xeast() ) || ( ( newy + get_ynorth() ) > get_ysouth() ) )
293  return false;
294  else
295  return true;
296 }
297 
299 {
300  float world_xtiles_per_pixel = (float)( get_xeast() - get_xwest() ) / (float)gumpwidth;
301  u16 ret = ( u16 )( get_xwest() + ( world_xtiles_per_pixel * gumpx ) );
302  return ret;
303 }
304 
306 {
307  float world_ytiles_per_pixel = (float)( get_ysouth() - get_ynorth() ) / (float)gumpheight;
308  u16 ret = ( u16 )( get_ynorth() + ( world_ytiles_per_pixel * gumpy ) );
309  return ret;
310 }
311 
313 {
314  float world_xtiles_per_pixel = (float)( get_xeast() - get_xwest() ) / (float)gumpwidth;
315  u16 ret = ( u16 )( ( worldx - get_xwest() ) / world_xtiles_per_pixel );
316  return ret;
317 }
318 
320 {
321  float world_ytiles_per_pixel = (float)( get_ysouth() - get_ynorth() ) / (float)gumpheight;
322  u16 ret = ( u16 )( ( worldy - get_ynorth() ) / world_ytiles_per_pixel );
323  return ret;
324 }
325 
326 // dave 12-20
328 {
329  Map* map = static_cast<Map*>( base::clone() );
330 
331  map->gumpwidth = gumpwidth;
332  map->gumpheight = gumpheight;
333  map->editable = editable;
334  map->plotting = plotting;
335  map->pin_points = pin_points;
336  map->xwest = xwest;
337  map->xeast = xeast;
338  map->ynorth = ynorth;
339  map->ysouth = ysouth;
340  map->facetid = facetid;
341  return map;
342 }
343 
344 size_t Map::estimatedSize() const
345 {
346  return base::estimatedSize() + sizeof( u16 ) /*gumpwidth*/
347  + sizeof( u16 ) /*gumpheight*/
348  + sizeof( bool ) /*editable*/
349  + sizeof( bool ) /*plotting*/
350  + sizeof( u16 ) /*xwest*/
351  + sizeof( u16 ) /*xeast*/
352  + sizeof( u16 ) /*ynorth*/
353  + sizeof( u16 ) /*ysouth*/
354  + sizeof( u16 ) /*facetid*/
355  + 3 * sizeof( PinPoint* ) + pin_points.capacity() * sizeof( PinPoint );
356 }
357 
359 {
360  // FIXME you really need to check that the item is in fact a map.
361  // Can cause crash if someone is messing with their packets to script
362  // pin movement on a non-map item.
363  Map* my_map = (Map*)find_legal_item( client->chr, cfBEu32( msg->serial ) );
364  if ( my_map == nullptr )
365  return;
366  if ( my_map->editable == false )
367  return;
368 
369  static struct PinPoint pp;
371 
372  switch ( msg->type )
373  {
375  {
376  // hmm msg->plotstate never seems to be 1 when type is 6
377  my_map->plotting = my_map->plotting ? 0 : 1;
379  msg56->Write<u32>( msg->serial );
380  msg56->Write<u8>( PKTBI_56::TYPE_TOGGLE_RESPONSE );
381  msg56->Write<u8>( my_map->plotting ? 1u : 0u );
382  msg56->Write<u16>( msg->pinx );
383  msg56->Write<u16>( msg->piny );
384  msg56.Send( client );
385  break;
386  }
387 
388  case PKTBI_56::TYPE_ADD:
389  if ( !( my_map->plotting ) )
390  return;
391  if ( !my_map->msgCoordsInBounds( msg ) )
392  return;
393 
394  pp.x = my_map->gumpXtoWorldX( cfBEu16( msg->pinx ) );
395  pp.y = my_map->gumpYtoWorldY( cfBEu16( msg->piny ) );
396  my_map->pin_points.push_back( pp );
397  break;
398 
400  if ( !( my_map->plotting ) )
401  return;
402  if ( msg->pinidx >= my_map->pin_points.size() ) // pinidx out of range
403  return;
404  if ( !my_map->msgCoordsInBounds( msg ) )
405  return;
406 
407  itr = my_map->pin_points.begin();
408  itr += msg->pinidx;
409 
410  pp.x = my_map->gumpXtoWorldX( cfBEu16( msg->pinx ) );
411  pp.y = my_map->gumpYtoWorldY( cfBEu16( msg->piny ) );
412 
413  my_map->pin_points.insert( itr, pp );
414  break;
415 
417  if ( !( my_map->plotting ) )
418  return;
419  if ( msg->pinidx >= my_map->pin_points.size() ) // pinidx out of range
420  return;
421  if ( !my_map->msgCoordsInBounds( msg ) )
422  return;
423 
424  itr = my_map->pin_points.begin();
425  itr += msg->pinidx;
426 
427  itr->x = my_map->gumpXtoWorldX( cfBEu16( msg->pinx ) );
428  itr->y = my_map->gumpYtoWorldY( cfBEu16( msg->piny ) );
429 
430  break;
431 
433  if ( !( my_map->plotting ) )
434  return;
435  if ( msg->pinidx >= my_map->pin_points.size() ) // pinidx out of range
436  return;
437 
438  itr = my_map->pin_points.begin();
439  itr += msg->pinidx;
440 
441  my_map->pin_points.erase( itr );
442 
443  break;
444 
446  if ( !( my_map->plotting ) )
447  return;
448 
449  my_map->pin_points.clear();
450 
451  break;
452  }
453 }
454 }
455 }
unsigned char u8
Definition: rawtypes.h:25
std::string remove_string(const char *propname)
Definition: cfgfile.cpp:381
virtual Bscript::BObjectImp * script_method_id(const int id, Bscript::Executor &ex) POL_OVERRIDE
Definition: uoscrobj.cpp:1325
virtual Items::Item * clone() const POL_OVERRIDE
Definition: umap.cpp:327
unsigned short y
Definition: umap.h:54
PinPoints pin_points
Definition: umap.h:67
u16 ynorth
Definition: umap.h:109
u16 ysouth
Definition: umap.h:110
#define cfBEu32(x)
Definition: clib_endian.h:43
virtual void printProperties(Clib::StreamWriter &sw) const POL_OVERRIDE
Definition: item.cpp:337
void handle_map_pin(Network::Client *client, PKTBI_56 *msg)
Definition: umap.cpp:358
Item * find_legal_item(const Character *chr, u32 serial, bool *additlegal, bool *isRemoteContainer)
Definition: ufunc.cpp:958
virtual Bscript::BObjectImp * script_method_id(const int id, Bscript::Executor &ex) POL_OVERRIDE
Definition: umap.cpp:175
void printPinPoints(Clib::StreamWriter &sw) const
Definition: umap.cpp:72
ObjMethod * getKnownObjMethod(const char *token)
Definition: parser.cpp:666
virtual Item * clone() const
Definition: item.cpp:56
bool plotting
Definition: umap.h:65
Mobile::Character * chr
Definition: client.h:182
u16 gumpheight
Definition: umap.h:63
void set_dirty()
Definition: uobject.h:291
virtual void readProperties(Clib::ConfigElem &elem) POL_OVERRIDE
Definition: item.cpp:434
unsigned short u16
Definition: rawtypes.h:26
unsigned int u32
Definition: rawtypes.h:27
bool editable
Definition: umap.h:64
bool msgCoordsInBounds(PKTBI_56 *msg)
Definition: umap.cpp:286
virtual Bscript::BObjectImp * script_method(const char *methodname, Bscript::Executor &ex) POL_OVERRIDE
Definition: uoscrobj.cpp:1577
u16 worldXtoGumpX(u16 worldx)
Definition: umap.cpp:312
void Send(Client *client, int len=-1) const
Definition: packethelper.h:69
u16 get_xwest()
Definition: umap.h:70
virtual void printProperties(Clib::StreamWriter &sw) const POL_OVERRIDE
Definition: umap.cpp:53
virtual size_t estimatedSize() const POL_OVERRIDE
Definition: umap.cpp:344
Map(const Items::MapDesc &mapdesc)
Definition: umap.cpp:36
u16 get_ysouth()
Definition: umap.h:73
u16 get_ynorth()
Definition: umap.h:72
#define cfBEu16(x)
Definition: clib_endian.h:44
u16 xwest
Definition: umap.h:107
virtual void builtin_on_use(Network::Client *client) POL_OVERRIDE
Definition: umap.cpp:116
PinPoints::iterator pin_points_itr
Definition: umap.h:68
virtual void readProperties(Clib::ConfigElem &elem) POL_OVERRIDE
Definition: umap.cpp:84
u16 gumpXtoWorldX(u16 gumpx)
Definition: umap.cpp:298
virtual size_t estimatedSize() const POL_OVERRIDE
Definition: item00.cpp:58
u16 gumpYtoWorldY(u16 gumpy)
Definition: umap.cpp:305
Realms::Realm * realm
Definition: baseobject.h:56
u16 xeast
Definition: umap.h:108
unsigned short remove_ushort(const char *propname)
Definition: cfgfile.cpp:318
virtual ~Map()
Definition: umap.cpp:51
u16 worldYtoGumpY(u16 worldy)
Definition: umap.cpp:319
u16 gumpwidth
Definition: umap.h:62
bool valid(unsigned short x, unsigned short y, short z) const
Definition: realm.cpp:119
unsigned short x
Definition: umap.h:53
#define pf_endl
Definition: proplist.cpp:25
Definition: berror.cpp:12
bool remove_bool(const char *propname)
Definition: cfgfile.cpp:426
virtual Bscript::BObjectImp * script_method(const char *methodname, Bscript::Executor &ex) POL_OVERRIDE
Definition: umap.cpp:273
bool getParam(unsigned param, int &value)
Definition: executor.cpp:363
u16 get_xeast()
Definition: umap.h:71
u16 facetid
Definition: umap.h:111