Pol  Revision:f37d500
uomod4.cpp
Go to the documentation of this file.
1 
9 /*
10  UEMOD4.CPP
11  Handles moving objects within a realm and from realm to realm.
12 */
13 
14 #include <stddef.h>
15 #include <string>
16 
17 #include "../../bscript/berror.h"
18 #include "../../bscript/bobject.h"
19 #include "../../bscript/impstr.h"
20 #include "../../clib/rawtypes.h"
21 #include "../containr.h"
22 #include "../core.h"
23 #include "../item/item.h"
24 #include "../mobile/charactr.h"
25 #include "../multi/boat.h"
26 #include "../polclass.h"
27 #include "../poltype.h"
28 #include "../realms.h"
29 #include "../realms/realm.h"
30 #include "../reftypes.h"
31 #include "../uconst.h"
32 #include "../ufunc.h"
33 #include "../uobject.h"
34 #include "../uoexhelp.h"
35 #include "../uworld.h"
36 #include "uomod.h"
37 
38 namespace Pol
39 {
40 namespace Module
41 {
42 using namespace Bscript;
43 using namespace Mobile;
44 using namespace Core;
45 using namespace Items;
46 BObjectImp* UOExecutorModule::mf_MoveObjectToLocation( /*object, x, y, z, realm, flags*/ )
47 {
48  UObject* obj;
49  unsigned short x, y;
50  short z;
51  int flags;
52  const String* realm_name;
53 
54  // Initialize variables
55  if ( !( getUObjectParam( exec, 0, obj ) && getParam( 1, x ) && getParam( 2, y ) &&
56  getParam( 3, z, ZCOORD_MIN, ZCOORD_MAX ) && getStringParam( 4, realm_name ) &&
57  getParam( 5, flags ) ) )
58  {
59  return new BError( "Invalid parameter" );
60  }
61  Realms::Realm* realm = find_realm( realm_name->value() );
62  if ( !realm )
63  return new BError( "Realm not found." );
64  else if ( !realm->valid( x, y, z ) )
65  return new BError( "Invalid coordinates for realm." );
66 
67  if ( obj->script_isa( POLCLASS_MOBILE ) )
68  return internal_MoveCharacter( static_cast<Character*>( obj ), x, y, z, flags, realm );
69  else if ( obj->script_isa( POLCLASS_BOAT ) )
70  return internal_MoveBoat( static_cast<Multi::UBoat*>( obj ), x, y, z, flags, realm );
71  else if ( obj->script_isa( POLCLASS_MULTI ) )
72  return new BError( "Can't move multis at this time." );
73  else if ( obj->script_isa( POLCLASS_CONTAINER ) )
74  return internal_MoveContainer( static_cast<UContainer*>( obj ), x, y, z, flags, realm );
75  else if ( obj->script_isa( POLCLASS_ITEM ) )
76  return internal_MoveItem( static_cast<Item*>( obj ), x, y, z, flags, realm );
77  else
78  return new BError( "Can't handle that object type." );
79 }
80 
82  int flags, Realms::Realm* newrealm )
83 {
84  short newz;
85  Multi::UMulti* supporting_multi = NULL;
86  Item* walkon_item = NULL;
87 
88  if ( !( flags & MOVEITEM_FORCELOCATION ) )
89  {
90  if ( newrealm != NULL )
91  {
92  if ( !newrealm->walkheight( x, y, z, &newz, &supporting_multi, &walkon_item, true,
93  chr->movemode ) )
94  return new BError( "Can't go there" );
95  }
96  }
97  Realms::Realm* oldrealm = chr->realm;
98 
99  bool ok;
100  if ( newrealm == NULL || oldrealm == newrealm )
101  { // Realm is staying the same, just changing X Y Z coordinates.
102  ok = move_character_to( chr, x, y, z, flags, NULL );
103  }
104  else
105  { // Realm and X Y Z change.
106 
107  // Notify NPCs in the old realm that the player left the realm.
108  oldrealm->notify_left( *chr );
109 
111  if ( chr->client != NULL )
113  chr->realm = newrealm;
114  chr->realm_changed();
115  ok = move_character_to( chr, x, y, z, flags, oldrealm );
116  }
117 
118  if ( ok )
119  return new BLong( 1 );
120  else
121  return new BError( "Can't go there" );
122 }
123 
125  int flags, Realms::Realm* newrealm )
126 {
127  Realms::Realm* oldrealm = boat->realm;
128  { // local scope for reg/unreg guard
129  Multi::UBoat::BoatMoveGuard registerguard( boat );
130  if ( !boat->navigable( boat->multidef(), x, y, z, newrealm ) )
131  {
132  return new BError( "Position indicated is impassable" );
133  }
134  }
135  if ( newrealm !=
136  boat->realm ) // boat->move_xy removes on xy change so only realm change check is needed
137  {
139  }
140  boat->realm = newrealm;
141 
142  s8 deltaz = static_cast<s8>( z - boat->z );
143  boat->z = (s8)z;
144  boat->adjust_traveller_z( deltaz );
145  boat->realm_changed();
146  bool ok = boat->move_xy( x, y, flags, oldrealm );
147  return new BLong( ok );
148 }
149 
151  zcoord z, int flags, Realms::Realm* newrealm )
152 {
153  Realms::Realm* oldrealm = container->realm;
154 
155  BObjectImp* ok = internal_MoveItem( static_cast<Item*>( container ), x, y, z, flags, newrealm );
156  // Check if container was successfully moved to a new realm and update contents.
157  if ( !ok->isa( BObjectImp::OTError ) )
158  {
159  if ( newrealm != NULL && oldrealm != newrealm )
160  container->for_each_item( setrealm, (void*)newrealm );
161  }
162 
163  return ok;
164 }
165 
167  int flags, Realms::Realm* newrealm )
168 {
169  ItemRef itemref( item ); // dave 1/28/3 prevent item from being destroyed before function ends
170  if ( !( flags & MOVEITEM_IGNOREMOVABLE ) && !item->movable() )
171  {
172  Character* chr = controller_.get();
173  if ( chr == NULL || !chr->can_move( item ) )
174  return new BError( "That is immobile" );
175  }
176  if ( item->inuse() && !is_reserved_to_me( item ) )
177  {
178  return new BError( "That item is being used." );
179  }
180 
181  Realms::Realm* oldrealm = item->realm;
182  item->realm = newrealm;
183  if ( !item->realm->valid( x, y, z ) )
184  { // Should probably have checked this already.
185  item->realm = oldrealm;
186  std::string message = "Location (" + Clib::tostring( x ) + "," + Clib::tostring( y ) + "," +
187  Clib::tostring( z ) + ") is out of bounds";
188  return new BError( message );
189  }
190 
191  Multi::UMulti* multi = NULL;
192  if ( flags & MOVEITEM_FORCELOCATION )
193  {
194  short newz;
195  Item* walkon;
196  item->realm->walkheight( x, y, z, &newz, &multi, &walkon, true, MOVEMODE_LAND );
197  // note that newz is ignored...
198  }
199  else
200  {
201  short newz;
202  Item* walkon;
203  if ( !item->realm->walkheight( x, y, z, &newz, &multi, &walkon, true, MOVEMODE_LAND ) )
204  {
205  item->realm = oldrealm;
206  return new BError( "Invalid location selected" );
207  }
208  z = newz;
209  }
210 
211  if ( item->container != NULL )
212  {
213  // DAVE added this 12/04, call can/onRemove scripts for the old container
214  UObject* oldroot = item->toplevel_owner();
215  UContainer* oldcont = item->container;
216  Character* chr_owner = oldcont->GetCharacterOwner();
217  if ( chr_owner == NULL )
218  if ( controller_.get() != NULL )
219  chr_owner = controller_.get();
220 
221  // dave changed 1/26/3 order of scripts to call. added unequip/test script call
222  if ( !oldcont->check_can_remove_script( chr_owner, item, UContainer::MT_CORE_MOVED ) )
223  {
224  item->realm = oldrealm;
225  return new BError( "Could not remove item from its container." );
226  }
227  else if ( item->orphan() ) // dave added 1/28/3, item might be destroyed in RTC script
228  {
229  return new BError( "Item was destroyed in CanRemove script" );
230  }
231 
232  if ( !item->check_unequiptest_scripts() || !item->check_unequip_script() )
233  {
234  item->realm = oldrealm;
235  return new BError( "Item cannot be unequipped" );
236  }
237  if ( item->orphan() ) // dave added 1/28/3, item might be destroyed in RTC script
238  return new BError( "Item was destroyed in Equip script" );
239 
240  oldcont->on_remove( chr_owner, item, UContainer::MT_CORE_MOVED );
241  if ( item->orphan() ) // dave added 1/28/3, item might be destroyed in RTC script
242  {
243  return new BError( "Item was destroyed in OnRemove script" );
244  }
245 
246  item->set_dirty();
247 
248  item->extricate();
249 
250  // wherever it was, it wasn't in the world/on the ground
251  item->x = oldroot->x;
252  item->y = oldroot->y;
253  // move_item calls MoveItemWorldLocation, so this gets it
254  // in the right place to start with.
255  item->realm = oldrealm;
256  add_item_to_world( item );
257  item->realm = newrealm;
258  }
259 
260  move_item( item, x, y, static_cast<signed char>( z ), oldrealm );
261 
262  if ( multi != NULL )
263  {
264  multi->register_object( item );
265  }
266  return new BLong( 1 );
267 }
268 }
269 }
void on_remove(Mobile::Character *chr, Items::Item *item, MoveType move=MT_PLAYER)
Definition: containr.cpp:744
Bscript::BObjectImp * mf_MoveObjectToLocation()
Definition: uomod4.cpp:46
const std::string & value() const
Definition: impstr.h:67
void send_remove_character_to_nearby(const Character *chr)
Definition: ufunc.cpp:379
void add_item_to_world(Items::Item *item)
Definition: uworld.cpp:31
short zcoord
Definition: poltype.h:21
bool check_unequip_script()
Definition: item.cpp:1064
bool isa(BObjectType type) const
Definition: bobject.h:353
Network::Client * client
Definition: charactr.h:871
virtual UObject * toplevel_owner() POL_OVERRIDE
Definition: item.cpp:252
unsigned short ycoord
Definition: poltype.h:20
bool check_unequiptest_scripts(Mobile::Character *chr)
Definition: item.cpp:1142
const unsigned POLCLASS_BOAT
Definition: polclass.h:24
bool move_character_to(Mobile::Character *chr, unsigned short x, unsigned short y, short z, int flags, Realms::Realm *oldrealm)
Definition: core.cpp:50
const unsigned POLCLASS_MULTI
Definition: polclass.h:23
bool walkheight(unsigned short x, unsigned short y, short oldz, short *newz, Multi::UMulti **pmulti, Items::Item **pwalkon, bool doors_block, Core::MOVEMODE movemode, short *gradual_boost=NULL)
Definition: realmfunc.cpp:340
virtual void register_object(UObject *obj)
Definition: multis.cpp:60
void realm_changed()
Definition: boat.cpp:1116
virtual bool script_isa(unsigned isatype) const
Definition: uoscrobj.cpp:4566
void set_dirty()
Definition: uobject.h:291
static bool navigable(const MultiDef &, unsigned short x, unsigned short y, short z, Realms::Realm *realm)
Definition: boat.cpp:639
const short ZCOORD_MIN
Definition: poltype.h:15
const unsigned POLCLASS_ITEM
Definition: polclass.h:14
std::string tostring(const Bscript::BTokenType &v)
Definition: tokens.cpp:19
bool orphan() const
Definition: baseobject.h:119
const unsigned POLCLASS_CONTAINER
Definition: polclass.h:18
void notify_left(Mobile::Character &wholeft)
Definition: realm.cpp:174
Core::MOVEMODE movemode
Definition: charactr.h:811
Bscript::BObjectImp * internal_MoveContainer(Core::UContainer *container, Core::xcoord x, Core::ycoord y, Core::zcoord z, int flags, Realms::Realm *newrealm)
Definition: uomod4.cpp:150
void setrealm(Item *item, void *arg)
Definition: ufunc.cpp:1571
signed char s8
Definition: rawtypes.h:29
Core::UContainer * container
Definition: item.h:256
const unsigned POLCLASS_MOBILE
Definition: polclass.h:15
void send_remove_object_to_inrange(const UObject *centerObject)
Definition: ufunc.cpp:428
void move_item(Item *item, UFACING facing)
Definition: ufunc.cpp:1601
bool movable() const
Definition: item.h:300
void adjust_traveller_z(s8 delta_z)
Definition: boat.cpp:1098
const int MOVEITEM_FORCELOCATION
Definition: core.h:52
ref_ptr< Items::Item > ItemRef
Definition: reftypes.h:43
void remove_objects_inrange(Network::Client *client)
Definition: movement.cpp:121
Bscript::BObjectImp * internal_MoveItem(Items::Item *item, Core::xcoord x, Core::ycoord y, Core::zcoord z, int flags, Realms::Realm *newrealm)
Definition: uomod4.cpp:166
bool getUObjectParam(Executor &exec, unsigned param, UObject *&objptr)
Definition: uoexhelp.cpp:369
const short ZCOORD_MAX
Definition: poltype.h:16
Realms::Realm * realm
Definition: baseobject.h:56
const int MOVEITEM_IGNOREMOVABLE
Definition: core.h:51
bool check_can_remove_script(Mobile::Character *chr, Items::Item *item, MoveType move=MT_PLAYER)
Definition: containr.cpp:823
Realms::Realm * find_realm(const std::string &name)
Definition: realms.cpp:64
bool can_move(const Items::Item *item) const
Definition: charactr.cpp:1218
bool inuse() const
Definition: item.h:314
const MultiDef & multidef() const
Definition: multis.cpp:69
bool valid(unsigned short x, unsigned short y, short z) const
Definition: realm.cpp:119
Bscript::BObjectImp * internal_MoveCharacter(Mobile::Character *chr, Core::xcoord x, Core::ycoord y, Core::zcoord z, int flags, Realms::Realm *newrealm)
Definition: uomod4.cpp:81
void extricate()
Definition: item.cpp:906
Mobile::Character * GetCharacterOwner()
Definition: item.cpp:1168
bool move_xy(unsigned short x, unsigned short y, int flags, Realms::Realm *oldrealm)
Definition: boat.cpp:1187
Definition: berror.cpp:12
unsigned short xcoord
Definition: poltype.h:19
Bscript::BObjectImp * internal_MoveBoat(Multi::UBoat *boat, Core::xcoord x, Core::ycoord y, Core::zcoord z, int flags, Realms::Realm *newrealm)
Definition: uomod4.cpp:124
virtual void for_each_item(void(*f)(Item *item, void *a), void *arg)
Definition: containr.cpp:634