• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

polserver / polserver / 21108840797

18 Jan 2026 08:35AM UTC coverage: 60.508% (+0.02%) from 60.492%
21108840797

push

github

web-flow
ClangTidy readability-else-after-return (#857)

* trigger tidy

* Automated clang-tidy change: readability-else-after-return

* compile test

* rerun

* Automated clang-tidy change: readability-else-after-return

* trigger..

* Automated clang-tidy change: readability-else-after-return

* manually removed a few

* Automated clang-tidy change: readability-else-after-return

* removed duplicate code

* fix remaining warnings

* fixed scope

---------

Co-authored-by: Clang Tidy <clang-tidy@users.noreply.github.com>

837 of 1874 new or added lines in 151 files covered. (44.66%)

46 existing lines in 25 files now uncovered.

44448 of 73458 relevant lines covered (60.51%)

525066.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

49.24
/pol-core/pol/uoexec.cpp
1
#include "uoexec.h"
2

3
#include <stddef.h>
4

5
#include "../bscript/berror.h"
6
#include "../bscript/bobject.h"
7
#include "../bscript/executor.h"
8
#include "../bscript/fmodule.h"
9
#include "../bscript/impstr.h"
10
#include "../clib/logfacility.h"
11
#include "../clib/stlutil.h"
12
#include "../clib/strutil.h"
13
#include "../plib/systemstate.h"
14
#include "fnsearch.h"
15
#include "globals/network.h"
16
#include "globals/settings.h"
17
#include "globals/uvars.h"
18
#include "guilds.h"
19
#include "guildscrobj.h"
20
#include "item/itemdesc.h"
21
#include "mobile/attribute.h"
22
#include "mobile/charactr.h"
23
#include "module/osmod.h"
24
#include "multi/multi.h"
25
#include "network/client.h"
26
#include "party.h"
27
#include "partyscrobj.h"
28
#include "polclock.h"
29
#include "realms/realm.h"
30
#include "realms/realms.h"
31
#include "uobject.h"
32
#include "uoscrobj.h"
33
#include "vital.h"
34

35

36
namespace Pol::Core
37
{
38
UOExecutor::UOExecutor()
281✔
39
    : Executor(),
40
      os_module( nullptr ),
281✔
41
      keep_alive_( false ),
281✔
42
      instr_cycles( 0 ),
281✔
43
      sleep_cycles( 0 ),
281✔
44
      start_time( poltime() ),
562✔
45
      warn_runaway_on_cycle( Plib::systemstate.config.runaway_script_threshold ),
281✔
46
      runaway_cycles( 0 ),
281✔
47
      eventmask( 0 ),
281✔
48
      area_mask( 0 ),
281✔
49
      area_size( 0 ),
281✔
50
      speech_size( 1 ),
281✔
51
      can_access_offline_mobiles_( false ),
281✔
52
      auxsvc_assume_string( false ),
281✔
53
      survive_attached_disconnect( false ),
281✔
54
      pParent( nullptr ),
281✔
55
      pChild( nullptr )
281✔
56
{
57
  weakptr.set( this );
281✔
58
  os_module = new Module::OSExecutorModule( *this );
281✔
59
  addModule( os_module );
281✔
60
}
281✔
61

62
UOExecutor::~UOExecutor()
479✔
63
{
64
  // note, the os_module isn't deleted here because
65
  // the Executor deletes its ExecutorModules.
66
  if ( ( instr_cycles >= 500 ) && settingsManager.watch.profile_scripts )
281✔
67
  {
68
    int elapsed = static_cast<int>(
69
        poltime() - start_time );  // Doh! A script can't run more than 68 years, for this to work.
×
70
    POLLOG_ERRORLN( "Script {}: {} instr cycles, {} sleep cycles, {} seconds", scriptname(),
×
71
                    instr_cycles, sleep_cycles, elapsed );
×
72
  }
73

74
  pParent = nullptr;
281✔
75
  pChild = nullptr;
281✔
76
  // we need to call base class destructor method here
77
  // the modules need UOExecutor in its own Deconstructor
78
  // once the deconstructor of the baseclass runs its now longer
79
  // a UOExecutor and we run into undefined behaviour
80
  cleanup();
281✔
81
}
479✔
82

83
bool UOExecutor::suspend()
332✔
84
{
85
  // Run to completion scripts can't be suspended
86
  if ( running_to_completion() )
332✔
87
    return false;
×
88

89
  os_module->suspend();
332✔
90
  return true;
332✔
91
}
92

93
bool UOExecutor::revive()
36,935,623✔
94
{
95
  os_module->revive();
36,935,623✔
96
  return true;
36,935,623✔
97
}
98

99
std::string UOExecutor::state()
×
100
{
101
  if ( halt() )
×
102
    return "Debugging";
×
NEW
103
  if ( os_module->blocked() )
×
104
    return "Sleeping";
×
NEW
105
  return "Running";
×
106
}
107

108

109
bool UOExecutor::signal_event( Bscript::BObjectImp* eventimp )
1,686✔
110
{
111
  passert_r( os_module != nullptr, "Object cannot receive events but is receiving them!" );
1,686✔
112
  return os_module->signal_event( eventimp );
1,686✔
113
}
114

115
size_t UOExecutor::sizeEstimate() const
14✔
116
{
117
  return sizeof( UOExecutor ) + base::sizeEstimate();
14✔
118
}
119

120
bool UOExecutor::critical() const
111,230,038✔
121
{
122
  return os_module->critical();
111,230,038✔
123
}
124
void UOExecutor::critical( bool critical )
×
125
{
126
  os_module->critical( critical );
×
127
}
×
128

129
bool UOExecutor::warn_on_runaway() const
24✔
130
{
131
  return os_module->warn_on_runaway();
24✔
132
}
133
void UOExecutor::warn_on_runaway( bool warn_on_runaway )
×
134
{
135
  os_module->warn_on_runaway( warn_on_runaway );
×
136
}
×
137

138
bool UOExecutor::keep_alive() const
556✔
139
{
140
  return keep_alive_;
556✔
141
}
142
void UOExecutor::keep_alive( bool status )
180✔
143
{
144
  keep_alive_ = status;
180✔
145
}
180✔
146

147
unsigned char UOExecutor::priority() const
36,978,654✔
148
{
149
  return os_module->priority();
36,978,654✔
150
}
151
void UOExecutor::priority( unsigned char priority )
14✔
152
{
153
  os_module->priority( priority );
14✔
154
}
14✔
155

156
void UOExecutor::SleepFor( u32 secs )
×
157
{
158
  os_module->SleepFor( secs );
×
159
}
×
160
void UOExecutor::SleepForMs( u32 msecs )
×
161
{
162
  os_module->SleepForMs( msecs );
×
163
}
×
164
unsigned int UOExecutor::pid() const
32✔
165
{
166
  return os_module->pid();
32✔
167
}
168
bool UOExecutor::blocked() const
259,013,467✔
169
{
170
  return os_module->blocked();
259,013,467✔
171
}
172
bool UOExecutor::in_debugger_holdlist() const
108✔
173
{
174
  return os_module->in_debugger_holdlist();
108✔
175
}
176
void UOExecutor::revive_debugged()
9✔
177
{
178
  os_module->revive_debugged();
9✔
179
}
9✔
180

181
Core::polclock_t UOExecutor::sleep_until_clock() const
221,611,754✔
182
{
183
  return os_module->sleep_until_clock();
221,611,754✔
184
}
185

186
void UOExecutor::sleep_until_clock( Core::polclock_t sleep_until_clock )
×
187
{
188
  os_module->sleep_until_clock( sleep_until_clock );
×
189
}
×
190

191
Core::TimeoutHandle UOExecutor::hold_itr() const
×
192
{
193
  return os_module->hold_itr();
×
194
}
195

196
void UOExecutor::hold_itr( Core::TimeoutHandle hold_itr )
36,936,070✔
197
{
198
  os_module->hold_itr( hold_itr );
36,936,070✔
199
}
36,936,070✔
200

201
Core::HoldListType UOExecutor::in_hold_list() const
36,937,067✔
202
{
203
  return os_module->in_hold_list();
36,937,067✔
204
}
205
void UOExecutor::in_hold_list( Core::HoldListType in_hold_list )
36,936,875✔
206
{
207
  return os_module->in_hold_list( in_hold_list );
36,936,875✔
208
}
209

210
Bscript::BObjectImp* UOExecutor::clear_event_queue()
×
211
{
212
  return os_module->clear_event_queue();
×
213
}  // DAVE
214

215
using namespace Bscript;
216
using namespace Module;
217

218
bool UOExecutor::getCharacterOrClientParam( unsigned param, Mobile::Character*& chrptr,
×
219
                                            Network::Client*& clientptr )
220
{
221
  chrptr = nullptr;
×
222
  clientptr = nullptr;
×
223

224
  BObjectImp* imp = getParamImp( param );
×
225
  if ( imp == nullptr )
×
226
  {
227
    setFunctionResult( new BError( "Missing parameter " + Clib::tostring( param ) ) );
×
228
    return false;
×
229
  }
NEW
230
  if ( imp->isa( BObjectImp::OTApplicObj ) )
×
231
  {
232
    BApplicObjBase* aob = Clib::explicit_cast<BApplicObjBase*, BObjectImp*>( imp );
×
233

234
    if ( ( aob != nullptr ) && ( aob->object_type() == &echaracterrefobjimp_type ) )
×
235
    {
236
      ECharacterRefObjImp* chrref_imp =
237
          Clib::explicit_cast<ECharacterRefObjImp*, BApplicObjBase*>( aob );
×
238

239
      chrptr = chrref_imp->value().get();
×
240

241
      if ( chrptr->orphan() )
×
242
      {
243
        setFunctionResult( new BError( "Mobile has been destroyed" ) );
×
244
        return false;
×
245
      }
246

247
      if ( chrptr->logged_in() || chrref_imp->offline_access_ok() || can_access_offline_mobiles_ )
×
248
      {
249
        return true;
×
250
      }
251

NEW
252
      setFunctionResult( new BError( "Mobile is offline" ) );
×
NEW
253
      return false;
×
254
    }
NEW
255
    if ( ( aob != nullptr ) && ( aob->object_type() == &eclientrefobjimp_type ) )
×
256
    {
257
      EClientRefObjImp* clientref_imp =
258
          Clib::explicit_cast<EClientRefObjImp*, BApplicObjBase*>( aob );
×
259

260
      clientptr = clientref_imp->value().exists() ? clientref_imp->value().get_weakptr() : nullptr;
×
261

262
      if ( ( clientptr != nullptr ) && clientptr->isConnected() )
×
263
      {
264
        return true;
×
265
      }
266

NEW
267
      setFunctionResult( new BError( "Client is disconnected" ) );
×
UNCOV
268
      return false;
×
269
    }
270
    // FIXME: log error
NEW
271
    return false;
×
272
  }
NEW
273
  if ( imp->isa( BObjectImp::OTLong ) )
×
274
  {
275
    BLong* pchar_serial = Clib::explicit_cast<BLong*, BObjectImp*>( imp );
×
276

277
    unsigned int serial = pchar_serial->value();
×
278
    if ( IsItem( serial ) || serial == 0 )
×
279
    {
280
      setFunctionResult( new BError( "Serial refers to an Item, or is zero" ) );
×
281
      return false;
×
282
    }
283

284
    chrptr = system_find_mobile( serial );
×
285

286
    if ( chrptr != nullptr )
×
287
    {
288
      if ( chrptr->logged_in() || can_access_offline_mobiles_ )
×
289
      {
290
        return true;
×
291
      }
292

NEW
293
      setFunctionResult( new BError( "Mobile is offline" ) );
×
UNCOV
294
      return false;
×
295
    }
296

NEW
297
    setFunctionResult( new BError( "Mobile does not exist" ) );
×
UNCOV
298
    return false;
×
299
  }
300
  // FIXME: log error
NEW
301
  return false;
×
302
}
303

304
bool UOExecutor::getCharacterParam( unsigned param, Mobile::Character*& chrptr )
616✔
305
{
306
  BObjectImp* imp = getParamImp( param );
616✔
307
  if ( imp == nullptr )
616✔
308
  {
309
    setFunctionResult( new BError( "Missing parameter " + Clib::tostring( param ) ) );
×
310
    return false;
×
311
  }
312
  if ( imp->isa( BObjectImp::OTApplicObj ) )
616✔
313
  {
314
    BApplicObjBase* aob = Clib::explicit_cast<BApplicObjBase*, BObjectImp*>( imp );
609✔
315

316
    if ( ( aob != nullptr ) && ( aob->object_type() == &echaracterrefobjimp_type ) )
609✔
317
    {
318
      ECharacterRefObjImp* chrref_imp =
319
          Clib::explicit_cast<ECharacterRefObjImp*, BApplicObjBase*>( aob );
523✔
320

321
      chrptr = chrref_imp->value().get();
523✔
322

323
      if ( chrptr->orphan() )
523✔
324
      {
325
        setFunctionResult( new BError( "Mobile has been destroyed" ) );
×
326
        return false;
×
327
      }
328

329
      if ( chrptr->logged_in() || chrref_imp->offline_access_ok() || can_access_offline_mobiles_ )
523✔
330
      {
331
        return true;
523✔
332
      }
333

NEW
334
      setFunctionResult( new BError( "Mobile is offline" ) );
×
UNCOV
335
      return false;
×
336
    }
337

338
    // FIXME: log error
339
    return false;
86✔
340
  }
341
  if ( imp->isa( BObjectImp::OTLong ) )
7✔
342
  {
343
    BLong* pchar_serial = Clib::explicit_cast<BLong*, BObjectImp*>( imp );
7✔
344

345
    unsigned int serial = pchar_serial->value();
7✔
346
    if ( IsItem( serial ) || serial == 0 )
7✔
347
    {
348
      setFunctionResult( new BError( "Serial refers to an Item, or is zero" ) );
7✔
349
      return false;
7✔
350
    }
351

352
    chrptr = system_find_mobile( serial );
×
353

354
    if ( chrptr != nullptr )
×
355
    {
356
      if ( chrptr->logged_in() || can_access_offline_mobiles_ )
×
357
      {
358
        return true;
×
359
      }
360

NEW
361
      setFunctionResult( new BError( "Mobile is offline" ) );
×
UNCOV
362
      return false;
×
363
    }
364

NEW
365
    setFunctionResult( new BError( "Mobile does not exist" ) );
×
UNCOV
366
    return false;
×
367
  }
368
  // FIXME: log error
NEW
369
  return false;
×
370
}
371

372
bool UOExecutor::getItemParam( unsigned param, Items::Item*& itemptr )
6,362✔
373
{
374
  BObjectImp* imp = getParamImp( param );
6,362✔
375
  if ( imp == nullptr )
6,362✔
376
  {
377
    return false;
×
378
  }
379
  if ( imp->isa( BObjectImp::OTApplicObj ) )
6,362✔
380
  {
381
    BApplicObjBase* aob = Clib::explicit_cast<BApplicObjBase*, BObjectImp*>( imp );
6,362✔
382

383
    if ( ( aob != nullptr ) && ( aob->object_type() == &eitemrefobjimp_type ) )
6,362✔
384
    {
385
      EItemRefObjImp* itemref_imp = Clib::explicit_cast<EItemRefObjImp*, BApplicObjBase*>( aob );
6,357✔
386

387
      itemptr = itemref_imp->value().get();
6,357✔
388
      return ( !itemptr->orphan() );
6,357✔
389
    }
390

391
    // FIXME: log error
392
    return false;
5✔
393
  }
NEW
394
  if ( imp->isa( BObjectImp::OTLong ) )
×
395
  {
396
    BLong* pitem_serial = Clib::explicit_cast<BLong*, BObjectImp*>( imp );
×
397
    unsigned int serial = pitem_serial->value();
×
398

399
    if ( IsCharacter( serial ) || serial == 0 )
×
400
      return false;
×
401

402
    itemptr = system_find_item( serial );
×
403

404
    return ( itemptr != nullptr );
×
405
  }
406
  // FIXME: log error
NEW
407
  return false;
×
408
}
409

410
bool UOExecutor::getUBoatParam( unsigned param, Multi::UBoat*& boatptr )
70✔
411
{
412
  BObjectImp* imp = getParamImp( param );
70✔
413
  if ( imp == nullptr )
70✔
414
  {
415
    return false;
×
416
  }
417
  if ( imp->isa( BObjectImp::OTApplicObj ) )
70✔
418
  {
419
    BApplicObjBase* aob = Clib::explicit_cast<BApplicObjBase*, BObjectImp*>( imp );
70✔
420

421
    if ( aob->object_type() == &euboatrefobjimp_type )
70✔
422
    {
423
      EUBoatRefObjImp* boatref_imp = Clib::explicit_cast<EUBoatRefObjImp*, BApplicObjBase*>( aob );
70✔
424

425
      boatptr = boatref_imp->value().get();
70✔
426
      return ( !boatptr->orphan() );
70✔
427
    }
NEW
428
    if ( aob->object_type() == &eitemrefobjimp_type )
×
429
    {
430
      EItemRefObjImp* itemref_imp = Clib::explicit_cast<EItemRefObjImp*, BApplicObjBase*>( aob );
×
431

432
      Items::Item* item = itemref_imp->value().get();
×
433
      if ( item->isa( UOBJ_CLASS::CLASS_MULTI ) )
×
434
      {
435
        Multi::UMulti* multi = static_cast<Multi::UMulti*>( item );
×
436
        boatptr = multi->as_boat();
×
437
        if ( boatptr == nullptr )
×
438
          return false;
×
NEW
439
        return ( !boatptr->orphan() );
×
440
      }
UNCOV
441
      return false;
×
442
    }
443
    // FIXME: log error
NEW
444
    return false;
×
445
  }
NEW
446
  if ( imp->isa( BObjectImp::OTLong ) )
×
447
  {
448
    BLong* pitem_serial = Clib::explicit_cast<BLong*, BObjectImp*>( imp );
×
449

450
    Multi::UMulti* multi = system_find_multi( pitem_serial->value() );
×
451
    if ( multi )
×
452
      boatptr = multi->as_boat();
×
453

454
    return ( boatptr != nullptr );
×
455
  }
456
  // FIXME: log error
NEW
457
  return false;
×
458
}
459

460

461
bool UOExecutor::getMultiParam( unsigned param, Multi::UMulti*& multiptr )
34✔
462
{
463
  BObjectImp* imp = getParamImp( param );
34✔
464
  if ( imp == nullptr )
34✔
465
  {
466
    return false;
×
467
  }
468
  if ( imp->isa( BObjectImp::OTApplicObj ) )
34✔
469
  {
470
    BApplicObjBase* aob = Clib::explicit_cast<BApplicObjBase*, BObjectImp*>( imp );
34✔
471

472
    if ( aob->object_type() == &emultirefobjimp_type )
34✔
473
    {
474
      EMultiRefObjImp* multiref_imp = Clib::explicit_cast<EMultiRefObjImp*, BApplicObjBase*>( aob );
13✔
475

476
      multiptr = multiref_imp->value().get();
13✔
477
      return ( !multiptr->orphan() );
13✔
478
    }
479
    if ( aob->object_type() == &euboatrefobjimp_type )
21✔
480
    {
481
      EUBoatRefObjImp* boatref_imp = Clib::explicit_cast<EUBoatRefObjImp*, BApplicObjBase*>( aob );
21✔
482

483
      multiptr = boatref_imp->value().get();
21✔
484
      return ( !multiptr->orphan() );
21✔
485
    }
486

487
    // FIXME: log error
NEW
488
    return false;
×
489
  }
NEW
490
  if ( imp->isa( BObjectImp::OTLong ) )
×
491
  {
492
    BLong* pitem_serial = Clib::explicit_cast<BLong*, BObjectImp*>( imp );
×
493

494
    multiptr = system_find_multi( pitem_serial->value() );
×
495

496
    return ( multiptr != nullptr );
×
497
  }
498
  // FIXME: log error
NEW
499
  return false;
×
500
}
501

502
bool UOExecutor::getUObjectParam( unsigned param, UObject*& objptr )
230✔
503
{
504
  Items::Item* item = nullptr;
230✔
505
  Mobile::Character* chr = nullptr;
230✔
506
  Multi::UMulti* multi = nullptr;
230✔
507

508
  // This function is a kludge because the individual functions will all test for
509
  // a serial independently and may set errors.
510
  // TODO: Refactor this function to test whether the parameter is a BLong in a single place.
511

512
  if ( getCharacterParam( param, chr ) )
230✔
513
  {
514
    objptr = chr;
144✔
515
    return true;
144✔
516
  }
517
  if ( getItemParam( param, item ) )
86✔
518
  {
519
    objptr = item;
81✔
520
    return true;
81✔
521
  }
522
  if ( getMultiParam( param, multi ) )
5✔
523
  {
524
    objptr = multi;
5✔
525
    return true;
5✔
526
  }
527

NEW
528
  return false;
×
529
}
530

531
bool UOExecutor::getObjtypeParam( unsigned param, unsigned int& objtype )
38✔
532
{
533
  BObjectImp* imp = getParamImp( param );
38✔
534
  if ( imp == nullptr )
38✔
535
  {
536
    return false;
×
537
  }
538
  unsigned int objtype_long = 0;
38✔
539

540
  if ( imp->isa( BObjectImp::OTLong ) )
38✔
541
  {
542
    BLong* plong = Clib::explicit_cast<BLong*, BObjectImp*>( imp );
29✔
543
    objtype_long = plong->value();
29✔
544
  }
545
  else if ( imp->isa( BObjectImp::OTString ) )
9✔
546
  {
547
    // this could be an objtypename, or an objtype in string form.  Cope with either.
548
    String* pstring = Clib::explicit_cast<String*, BObjectImp*>( imp );
9✔
549
    const char* ot_str = pstring->data();
9✔
550
    if ( !isdigit( ot_str[0] ) )
9✔
551
    {
552
      objtype = Items::get_objtype_byname( pstring->data() );
9✔
553
      if ( objtype != 0 )
9✔
554
      {
555
        return true;
9✔
556
      }
557

NEW
558
      setFunctionResult( new BError( std::string( "Objtype not defined: " ) + pstring->data() ) );
×
559

NEW
560
      return false;
×
561
    }
562

563
    // a number passed...process below as if passed as a BLong
NEW
564
    objtype_long = strtol( ot_str, nullptr, 0 );
×
565
  }
566
  else
567
  {
568
    DEBUGLOGLN(
×
569
        "Script Error in '{}' PC={}: \n"
570
        "\tCall to function {}:\n"
571
        "\tParameter {}: Expected Long or String, got datatype {}",
572
        scriptname(), PC, current_module_function->name.get(), param,
×
573
        BObjectImp::typestr( imp->type() ) );
×
574
    return false;
×
575
  }
576

577
  if ( ( objtype_long > Plib::systemstate.config.max_tile_id ) &&
29✔
578
       ( objtype_long <= Plib::systemstate.config.max_objtype ) )
2✔
579
  {
580
    objtype = objtype_long;
2✔
581
    if ( Items::has_itemdesc( objtype ) )
2✔
582
    {
583
      return true;
2✔
584
    }
585

NEW
586
    setFunctionResult(
×
NEW
587
        new BError( "Objtype " + Clib::hexint( objtype_long ) + " is not defined." ) );
×
NEW
588
    return false;
×
589
  }
590
  if ( objtype_long <= Plib::systemstate.config.max_tile_id )
27✔
591
  {
592
    objtype = objtype_long;
27✔
593
    return true;
27✔
594
  }
595

NEW
596
  DEBUGLOGLN(
×
597
      "Script Error in '{}' PC={}: \n"
598
      "\tCall to function {}:\n"
599
      "\tParameter {}: Value {} is out of range for an objtype",
NEW
600
      scriptname(), PC, current_module_function->name.get(), param, objtype_long );
×
NEW
601
  setFunctionResult( new BError( "Objtype is out of range ( acceptable: 0 - " +
×
NEW
602
                                 Clib::hexint( Plib::systemstate.config.max_objtype ) + " )" ) );
×
NEW
603
  return false;
×
604
}
605

606
bool UOExecutor::getObjtypeParam( unsigned param, const Items::ItemDesc*& itemdesc_out )
6,200✔
607
{
608
  BObjectImp* imp = getParamImp( param );
6,200✔
609
  if ( imp == nullptr )
6,200✔
610
  {
611
    return false;
×
612
  }
613
  unsigned int objtype_long = 0;
6,200✔
614

615
  if ( imp->isa( BObjectImp::OTLong ) )
6,200✔
616
  {
617
    BLong* plong = Clib::explicit_cast<BLong*, BObjectImp*>( imp );
6,141✔
618
    objtype_long = plong->value();
6,141✔
619
  }
620
  else if ( imp->isa( BObjectImp::OTString ) )
59✔
621
  {
622
    // this could be an objtypename, or an objtype in string form.  Cope with either.
623
    String* pstring = Clib::explicit_cast<String*, BObjectImp*>( imp );
53✔
624
    const char* ot_str = pstring->data();
53✔
625
    if ( !isdigit( ot_str[0] ) )
53✔
626
    {
627
      unsigned int objtype = Items::get_objtype_byname( pstring->data() );
53✔
628
      if ( objtype != 0 )
53✔
629
      {
630
        itemdesc_out = &Items::find_itemdesc( objtype );
52✔
631
        return true;
52✔
632
      }
633

634
      setFunctionResult( new BError( std::string( "Objtype not defined: " ) + pstring->data() ) );
1✔
635

636
      return false;
1✔
637
    }
638

639
    // a number passed...process below as if passed as a BLong
NEW
640
    objtype_long = strtol( ot_str, nullptr, 0 );
×
641
  }
642
  else if ( imp->isa( BObjectImp::OTStruct ) )
6✔
643
  {
644
    BStruct* itemdesc_struct = Clib::explicit_cast<BStruct*, BObjectImp*>( imp );
6✔
645
    try
646
    {
647
      itemdesc_out = Items::CreateItemDescriptor( itemdesc_struct );
6✔
648
      return true;
6✔
649
    }
650
    catch ( std::exception& ex )
×
651
    {
652
      std::string message = std::string( "Unable to create item descriptor: " ) + ex.what();
×
653
      setFunctionResult( new BError( message ) );
×
654
      return false;
×
655
    }
×
656
  }
657
  else
658
  {
659
    DEBUGLOGLN(
×
660
        "Script Error in '{}' PC={}: \n"
661
        "\tCall to function {}:\n"
662
        "\tParameter {}: Expected Long, String, or Struct, got datatype {}",
663
        scriptname(), PC, current_module_function->name.get(), param,
×
664
        BObjectImp::typestr( imp->type() ) );
×
665
    return false;
×
666
  }
667

668
  // we get here if the value passed was an integer - either a BLong, or a String containing a
669
  // number.
670
  if ( ( objtype_long > Plib::systemstate.config.max_tile_id ) &&
6,141✔
671
       ( objtype_long <= Plib::systemstate.config.max_objtype ) )
33✔
672
  {
673
    const Items::ItemDesc* itemdesc = &Items::find_itemdesc( objtype_long );
33✔
674

675
    if ( itemdesc != Core::gamestate.empty_itemdesc.get() )
33✔
676
    {
677
      itemdesc_out = itemdesc;
33✔
678
      return true;
33✔
679
    }
680

NEW
681
    setFunctionResult(
×
NEW
682
        new BError( "Objtype " + Clib::hexint( objtype_long ) + " is not defined." ) );
×
NEW
683
    return false;
×
684
  }
685
  if ( objtype_long <= Plib::systemstate.config.max_tile_id )
6,108✔
686
  {
687
    unsigned int objtype = objtype_long;
6,108✔
688
    itemdesc_out = &Items::find_itemdesc( objtype );
6,108✔
689
    if ( itemdesc_out == Core::gamestate.empty_itemdesc.get() )
6,108✔
690
    {
691
      // return a temporary item descriptor initialized with the objtype and graphic.
692
      itemdesc_out = Core::gamestate.temp_itemdesc.get();
6,067✔
693
      Core::gamestate.temp_itemdesc->objtype = objtype;
6,067✔
694
      Core::gamestate.temp_itemdesc->graphic = static_cast<u16>( objtype );
6,067✔
695
      Core::gamestate.temp_itemdesc->decay_time = settingsManager.ssopt.default_decay_time;
6,067✔
696
      Core::gamestate.temp_itemdesc->doubleclick_range =
6,067✔
697
          settingsManager.ssopt.default_doubleclick_range;
6,067✔
698
    }
699

700
    return true;
6,108✔
701
  }
702

NEW
703
  DEBUGLOGLN(
×
704
      "Script Error in '{}' PC={}: \n"
705
      "\tCall to function {}:\n"
706
      "\tParameter {}: Value {} is out of range for an objtype",
NEW
707
      scriptname(), PC, current_module_function->name.get(), param, objtype_long );
×
NEW
708
  setFunctionResult( new BError( "Objtype is out of range (acceptable: 0-0x20000)" ) );
×
NEW
709
  return false;
×
710
}
711

712
bool UOExecutor::getSkillIdParam( unsigned param, USKILLID& skillid )
×
713
{
714
  BObjectImp* imp = getParamImp( param );
×
715
  if ( imp == nullptr )
×
716
  {
717
    setFunctionResult( new BError( "Missing parameter " + Clib::tostring( param ) ) );
×
718
    return false;
×
719
  }
NEW
720
  if ( imp->isa( BObjectImp::OTLong ) )
×
721
  {
722
    BLong* plong = Clib::explicit_cast<BLong*, BObjectImp*>( imp );
×
723
    int value = plong->value();
×
724
    if ( value >= SKILLID__LOWEST && value <= networkManager.uoclient_general.maxskills )
×
725
    {
726
      skillid = static_cast<USKILLID>( value );
×
727
      return true;
×
728
    }
729

NEW
730
    std::string report = "Parameter " + Clib::tostring( param ) + " value " +
×
NEW
731
                         Clib::tostring( value ) + " out of expected range of [" +
×
NEW
732
                         Clib::tostring( SKILLID__LOWEST ) + ".." +
×
NEW
733
                         Clib::tostring( networkManager.uoclient_general.maxskills ) + "]";
×
NEW
734
    setFunctionResult( new BError( report ) );
×
NEW
735
    return false;
×
736
  }
×
NEW
737
  if ( imp->isa( BObjectImp::OTString ) )
×
738
  {
739
    const Mobile::Attribute* attr;
740
    if ( !getAttributeParam( param, attr ) )
×
741
      return false;
×
742
    if ( attr->skillid != static_cast<USKILLID>( -1 ) )
×
743
    {
744
      skillid = attr->skillid;
×
745
      return true;
×
746
    }
747
    const String* attrname;
748
    getStringParam( param, attrname );  // no error check needed
×
749
    std::string report = "Parameter " + Clib::tostring( param ) + " value " + attrname->value() +
×
750
                         " has no skill id defined";
×
751
    setFunctionResult( new BError( report ) );
×
752
    return false;
×
753
  }
×
754
  std::string report = "Invalid parameter type.  Expected param " + Clib::tostring( param ) +
×
755
                       " as " + BObjectImp::typestr( BObjectImp::OTLong ) + " or " +
×
756
                       BObjectImp::typestr( BObjectImp::OTString ) + ", got " +
×
757
                       BObjectImp::typestr( imp->type() );
×
758
  setFunctionResult( new BError( report ) );
×
759
  return false;
×
760
}
×
761

762

763
bool UOExecutor::getAttributeParam( unsigned param, const Mobile::Attribute*& attr )
279✔
764
{
765
  const String* attrname;
766
  if ( !getStringParam( param, attrname ) )
279✔
767
    return false;
×
768

769
  attr = Mobile::Attribute::FindAttribute( attrname->value() );
279✔
770
  if ( !attr )
279✔
771
  {
772
    setFunctionResult( new BError( "Attribute not defined: " + attrname->value() ) );
×
773
    return false;
×
774
  }
775

776
  return true;
279✔
777
}
778

779

780
bool UOExecutor::getVitalParam( unsigned param, const Vital*& vital )
26✔
781
{
782
  const String* vitalname;
783
  if ( !getStringParam( param, vitalname ) )
26✔
784
    return false;
×
785

786
  vital = FindVital( vitalname->value() );
26✔
787
  if ( !vital )
26✔
788
  {
789
    setFunctionResult( new BError( "Vital not defined: " + vitalname->value() ) );
×
790
    return false;
×
791
  }
792

793
  return true;
26✔
794
}
795

796
bool UOExecutor::getGuildParam( unsigned param, Core::Guild*& guild, Bscript::BError*& err )
×
797
{
798
  BApplicObjBase* aob = nullptr;
×
799
  if ( hasParams( param + 1 ) )
×
800
    aob = getApplicObjParam( param, &guild_type );
×
801

802
  if ( aob == nullptr )
×
803
  {
804
    err = new BError( "Invalid parameter type" );
×
805
    return false;
×
806
  }
807

808
  EGuildRefObjImp* gr = static_cast<EGuildRefObjImp*>( aob );
×
809
  guild = gr->value().get();
×
810
  if ( guild->disbanded() )
×
811
  {
812
    err = new BError( "Guild has disbanded" );
×
813
    return false;
×
814
  }
815
  return true;
×
816
}
817

818
bool UOExecutor::getPartyParam( unsigned param, Core::Party*& party, BError*& err )
×
819
{
820
  BApplicObjBase* aob = nullptr;
×
821
  if ( hasParams( param + 1 ) )
×
822
    aob = getApplicObjParam( param, &party_type );
×
823

824
  if ( aob == nullptr )
×
825
  {
826
    err = new BError( "Invalid parameter type" );
×
827
    return false;
×
828
  }
829

830
  EPartyRefObjImp* pr = static_cast<EPartyRefObjImp*>( aob );
×
831
  party = pr->value().get();
×
832
  if ( Core::system_find_mobile( party->leader() ) == nullptr )
×
833
  {
834
    err = new BError( "Party has no leader" );
×
835
    return false;
×
836
  }
837
  return true;
×
838
}
839

840
bool UOExecutor::getRealmParam( unsigned param, Realms::Realm** realm )
6,447✔
841
{
842
  const Bscript::String* realm_name;
843
  if ( !getStringParam( param, realm_name ) )
6,447✔
844
    return false;
×
845
  *realm = find_realm( realm_name->value() );
6,447✔
846
  if ( !( *realm ) )
6,447✔
847
  {
848
    setFunctionResult( new Bscript::BError( "Realm not found." ) );
×
849
    return false;
×
850
  }
851
  return true;
6,447✔
852
}
853

854
bool UOExecutor::getPos2dParam( unsigned xparam, unsigned yparam, Pos2d* pos,
92✔
855
                                const Realms::Realm* realm )
856
{
857
  u16 x;
858
  u16 y;
859
  if ( getParam( xparam, x ) && getParam( yparam, y ) )
92✔
860
  {
861
    *pos = Pos2d( x, y );
92✔
862
    if ( realm && !realm->valid( *pos ) )
92✔
863
    {
864
      setFunctionResult( new Bscript::BError( "Invalid Coordinates for Realm" ) );
×
865
      return false;
×
866
    }
867
    return true;
92✔
868
  }
869
  return false;
×
870
}
871
bool UOExecutor::getPos3dParam( unsigned xparam, unsigned yparam, unsigned zparam, Pos3d* pos,
19✔
872
                                const Realms::Realm* realm )
873
{
874
  u16 x;
875
  u16 y;
876
  s8 z;
877
  if ( getParam( xparam, x ) && getParam( yparam, y ) && getParam( zparam, z ) )
19✔
878
  {
879
    *pos = Pos3d( x, y, z );
19✔
880
    if ( realm && !realm->valid( *pos ) )
19✔
881
    {
882
      setFunctionResult( new Bscript::BError( "Invalid Coordinates for Realm" ) );
×
883
      return false;
×
884
    }
885
    return true;
19✔
886
  }
887
  return false;
×
888
}
889
bool UOExecutor::getPos4dParam( unsigned xparam, unsigned yparam, unsigned zparam,
6,366✔
890
                                unsigned realmparam, Pos4d* pos )
891
{
892
  u16 x;
893
  u16 y;
894
  s8 z;
895
  Realms::Realm* realm;
896
  if ( getParam( xparam, x ) && getParam( yparam, y ) && getParam( zparam, z ) &&
12,732✔
897
       getRealmParam( realmparam, &realm ) )
6,366✔
898
  {
899
    Pos3d p( x, y, z );
6,366✔
900
    if ( !realm->valid( p ) )
6,366✔
901
    {
902
      setFunctionResult( new Bscript::BError( "Invalid Coordinates for Realm" ) );
1✔
903
      return false;
1✔
904
    }
905
    *pos = Pos4d( p, realm );
6,365✔
906
    return true;
6,365✔
907
  }
908
  return false;
×
909
}
910
}  // namespace Pol::Core
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc