31 #include "../../bscript/berror.h" 32 #include "../../clib/cfgelem.h" 33 #include "../../clib/fileutil.h" 34 #include "../../clib/logfacility.h" 35 #include "../../clib/passert.h" 36 #include "../../clib/random.h" 37 #include "../../clib/refptr.h" 38 #include "../../clib/streamsaver.h" 39 #include "../baseobject.h" 41 #include "../fnsearch.h" 42 #include "../globals/state.h" 43 #include "../globals/uvars.h" 44 #include "../item/armor.h" 45 #include "../item/weapon.h" 46 #include "../listenpt.h" 47 #include "../mdelta.h" 48 #include "../module/npcmod.h" 49 #include "../module/osmod.h" 50 #include "../module/uomod.h" 51 #include "../multi/multi.h" 52 #include "../npctmpl.h" 53 #include "../scrdef.h" 54 #include "../scrsched.h" 55 #include "../scrstore.h" 57 #include "../uobjcnt.h" 58 #include "../uobject.h" 59 #include "../uoexec.h" 60 #include "../uoscrobj.h" 61 #include "../uworld.h" 86 run_speed( dexterity() ),
130 if ( multi !=
nullptr )
159 if ( newdist > curdist )
182 u8 tmp_facing = ( fdir + 1 ) & 0x7;
188 bool walk1 =
realm->
walkheight(
this, tmp_newx, tmp_newy,
z, &newz, &supporting_multi,
189 &walkon_item, ¤t_boost );
191 tmp_facing = ( fdir - 1 ) & 0x7;
195 if ( !walk1 && !
realm->
walkheight(
this, tmp_newx, tmp_newy,
z, &newz, &supporting_multi,
196 &walkon_item, ¤t_boost ) )
202 return realm->
walkheight(
this, newx, newy,
z, &newz, &supporting_multi, &walkon_item,
216 unsigned short wx, wy;
224 if ( chr->x == newx && chr->y == newy && chr->z >=
z - 10 && chr->z <=
z + 10 )
234 if ( chr->x == newx && chr->y == newy && chr->z >=
z - 10 && chr->z <=
z + 10 )
240 NPC* npc =
static_cast<NPC*
>( chr );
282 if ( !
script.get().empty() )
285 if (
master_.get() != nullptr )
288 if ( has_speech_color() )
289 sw() <<
"\tSpeechColor\t" << speech_color() <<
pf_endl;
291 if ( has_speech_font() )
292 sw() <<
"\tSpeechFont\t" << speech_font() <<
pf_endl;
300 if ( has_orig_fire_resist() )
301 sw() <<
"\tFireResist\t" << orig_fire_resist() <<
pf_endl;
302 if ( has_orig_cold_resist() )
303 sw() <<
"\tColdResist\t" << orig_cold_resist() <<
pf_endl;
304 if ( has_orig_energy_resist() )
305 sw() <<
"\tEnergyResist\t" << orig_energy_resist() <<
pf_endl;
306 if ( has_orig_poison_resist() )
307 sw() <<
"\tPoisonResist\t" << orig_poison_resist() <<
pf_endl;
308 if ( has_orig_physical_resist() )
309 sw() <<
"\tPhysicalResist\t" << orig_physical_resist() <<
pf_endl;
311 if ( has_orig_fire_damage() )
312 sw() <<
"\tFireDamage\t" << orig_fire_damage() <<
pf_endl;
313 if ( has_orig_cold_damage() )
314 sw() <<
"\tColdDamage\t" << orig_cold_damage() <<
pf_endl;
315 if ( has_orig_energy_damage() )
316 sw() <<
"\tEnergyDamage\t" << orig_energy_damage() <<
pf_endl;
317 if ( has_orig_poison_damage() )
318 sw() <<
"\tPoisonDamage\t" << orig_poison_damage() <<
pf_endl;
319 if ( has_orig_physical_damage() )
320 sw() <<
"\tPhysicalDamage\t" << orig_physical_damage() <<
pf_endl;
328 sw() <<
"# template: " <<
template_.name <<
pf_endl;
342 if ( wpn ==
nullptr )
344 if ( wpn !=
nullptr )
349 if ( sld ==
nullptr )
351 if ( sld !=
nullptr )
365 if (
getprop(
"template", tmp ) )
372 unsigned int master_serial;
373 if ( elem.
remove_prop(
"MASTER", &master_serial ) )
376 if ( chr !=
nullptr )
381 if ( !
script.get().empty() )
398 auto diceValue = [](
const std::string& dicestr,
int* value ) ->
bool {
401 if ( !dice.
load( dicestr.c_str(), &errmsg ) )
402 *value = atoi( dicestr.c_str() );
404 *value = dice.
roll();
408 return v.
addToValue( static_cast<s16>( value ) );
414 if ( elem.
remove_prop(
"AR", &tmp ) && diceValue( tmp, &value ) )
415 npc_ar_ = static_cast<u16>( value );
419 if ( elem.
remove_prop(
"FIRERESIST", &tmp ) && diceValue( tmp, &value ) )
421 fire_resist( apply( fire_resist(), value ) );
422 orig_fire_resist( static_cast<s16>( value ) );
424 if ( has_fire_resist() )
425 fire_resist( refresh( fire_resist() ) );
426 if ( elem.
remove_prop(
"COLDRESIST", &tmp ) && diceValue( tmp, &value ) )
428 cold_resist( apply( cold_resist(), value ) );
429 orig_cold_resist( static_cast<s16>( value ) );
431 if ( has_cold_resist() )
432 cold_resist( refresh( cold_resist() ) );
433 if ( elem.
remove_prop(
"ENERGYRESIST", &tmp ) && diceValue( tmp, &value ) )
435 energy_resist( apply( energy_resist(), value ) );
436 orig_energy_resist( static_cast<s16>( value ) );
438 if ( has_energy_resist() )
439 energy_resist( refresh( energy_resist() ) );
440 if ( elem.
remove_prop(
"POISONRESIST", &tmp ) && diceValue( tmp, &value ) )
442 poison_resist( apply( poison_resist(), value ) );
443 orig_poison_resist( static_cast<s16>( value ) );
445 if ( has_poison_resist() )
446 poison_resist( refresh( poison_resist() ) );
447 if ( elem.
remove_prop(
"PHYSICALRESIST", &tmp ) && diceValue( tmp, &value ) )
449 physical_resist( apply( physical_resist(), value ) );
450 orig_physical_resist( static_cast<s16>( value ) );
452 if ( has_physical_resist() )
453 physical_resist( refresh( physical_resist() ) );
455 if ( elem.
remove_prop(
"FIREDAMAGE", &tmp ) && diceValue( tmp, &value ) )
457 fire_damage( apply( fire_damage(), value ) );
458 orig_fire_damage( static_cast<s16>( value ) );
460 if ( has_fire_damage() )
461 fire_damage( refresh( fire_damage() ) );
462 if ( elem.
remove_prop(
"COLDDAMAGE", &tmp ) && diceValue( tmp, &value ) )
464 cold_damage( apply( cold_damage(), value ) );
465 orig_cold_damage( static_cast<s16>( value ) );
467 if ( has_cold_damage() )
468 cold_damage( refresh( cold_damage() ) );
469 if ( elem.
remove_prop(
"ENERGYDAMAGE", &tmp ) && diceValue( tmp, &value ) )
471 energy_damage( apply( energy_damage(), value ) );
472 orig_energy_damage( static_cast<s16>( value ) );
474 if ( has_energy_damage() )
475 energy_damage( refresh( energy_damage() ) );
476 if ( elem.
remove_prop(
"POISONDAMAGE", &tmp ) && diceValue( tmp, &value ) )
478 poison_damage( apply( poison_damage(), value ) );
479 orig_poison_damage( static_cast<s16>( value ) );
481 if ( has_poison_damage() )
482 poison_damage( refresh( poison_damage() ) );
483 if ( elem.
remove_prop(
"PHYSICALDAMAGE", &tmp ) && diceValue( tmp, &value ) )
485 physical_damage( apply( physical_damage(), value ) );
486 orig_physical_damage( static_cast<s16>( value ) );
488 if ( has_physical_damage() )
489 physical_damage( refresh( physical_damage() ) );
502 if (
getprop(
"template", tmp ) )
513 std::string diestring;
520 for (
unsigned i = 0; i < pAttr->aliases.size(); ++i )
522 if ( elem.
remove_prop( pAttr->aliases[i].c_str(), &diestring ) )
524 if ( !dice.
load( diestring.c_str(), &errmsg ) )
526 elem.
throw_error(
"Error reading Attribute " + pAttr->name +
": " + errmsg );
532 av.
base( static_cast<unsigned short>( base ) );
564 if ( !
script.get().empty() )
602 if ( prog.
get() == nullptr )
604 ERROR_PRINT <<
"Unable to read script " << sd.name() <<
" for NPC " <<
name() <<
"(0x" 605 << fmt::hexu(
serial ) <<
")\n";
606 throw std::runtime_error(
"Error loading NPCs" );
616 <<
"(0x" << fmt::hexu(
serial ) <<
")\n";
617 throw std::runtime_error(
"Error loading NPCs" );
628 return (
master_.get() == chr );
696 const u16* wspeech,
const char lang[4],
804 bool signaled =
false;
917 return new Bscript::BError(
"That NPC doesn't have a control script" );
922 bool send_damage_packet )
945 int blocked =
npc_ar_ + ar_mod();
948 int absorbed = blocked / 2;
953 INFO_PRINT << absorbed <<
" hits absorbed by NPC armor.\n";
976 return template_.intrinsic_weapon;
1006 if ( has_fire_resist() || has_orig_fire_resist() )
1007 fire_resist( fire_resist().resetModAsValue().addToValue( orig_fire_resist() ) );
1008 if ( has_cold_resist() || has_orig_cold_resist() )
1009 cold_resist( cold_resist().resetModAsValue().addToValue( orig_cold_resist() ) );
1010 if ( has_energy_resist() || has_orig_energy_resist() )
1011 energy_resist( energy_resist().resetModAsValue().addToValue( orig_energy_resist() ) );
1012 if ( has_poison_resist() || has_orig_poison_resist() )
1013 poison_resist( poison_resist().resetModAsValue().addToValue( orig_poison_resist() ) );
1014 if ( has_physical_resist() || has_orig_physical_resist() )
1015 physical_resist( physical_resist().resetModAsValue().addToValue( orig_physical_resist() ) );
1017 if ( has_fire_damage() || has_orig_fire_damage() )
1018 fire_damage( fire_damage().resetModAsValue().addToValue( orig_fire_damage() ) );
1019 if ( has_cold_damage() || has_orig_cold_damage() )
1020 cold_damage( cold_damage().resetModAsValue().addToValue( orig_cold_damage() ) );
1021 if ( has_energy_damage() || has_orig_energy_damage() )
1022 energy_damage( energy_damage().resetModAsValue().addToValue( orig_energy_damage() ) );
1023 if ( has_poison_damage() || has_orig_poison_damage() )
1024 poison_damage( poison_damage().resetModAsValue().addToValue( orig_poison_damage() ) );
1025 if ( has_physical_damage() || has_orig_physical_damage() )
1026 physical_damage( physical_damage().resetModAsValue().addToValue( orig_physical_damage() ) );
1032 +
sizeof(
unsigned short )
1034 +
sizeof(
unsigned short )
boost_utils::script_name_flystring script
bool can_accept_event(Core::EVENTID eventid)
ref_ptr< Bscript::EScriptProgram > find_script2(const ScriptDef &script, bool complain_if_not_found, bool cache_script)
const Plib::Package * pkg
virtual size_t estimatedSize() const POL_OVERRIDE
bool in_debugger_holdlist() const
std::string remove_string(const char *propname)
void send_remove_character_to_nearby(const Character *chr)
void set_vitals_to_maximum()
bool send_event(Bscript::BObjectImp *event)
unsigned short roll(void) const
void resetEquipablePropertiesNPC()
void setprop(const std::string &propname, const std::string &propvalue)
Character * master() const
virtual u16 get_damaged_sound() const POL_OVERRIDE
std::string templatename() const
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=nullptr)
virtual void inform_enteredarea(Character *whoentered) POL_OVERRIDE
void addModule(ExecutorModule *module)
const Core::NpcTemplate & template_
ValueModPack & addToValue(const ValueModPack &other)
virtual void printDebugProperties(Clib::StreamWriter &sw) const POL_OVERRIDE
bool signal_event(Bscript::BObjectImp *eventimp)
unsigned int remove_ulong(const char *propname)
bool is_visible_to_me(const Character *chr) const
ref_ptr< Core::WornItemsContainer > wornitems
unsigned short speech_size
void calc_vital_stuff(bool i_mod=true, bool v_mod=true)
bool get(ENUM flag) const
virtual void get_hitscript_params(double damage, Items::UArmor **parmor, unsigned short *rawdamage)
unsigned short calc_thru_damage(double damage, unsigned short ar)
virtual void apply_raw_damage_hundredths(unsigned int damage, Character *source, bool userepsys=true, bool send_damage_packet=false) POL_OVERRIDE
const unsigned short DEFAULT_TEXT_COLOR
virtual void printOn(Clib::StreamWriter &sw) const POL_OVERRIDE
virtual double armor_absorb_damage(double damage)
virtual Items::UWeapon * intrinsic_weapon() POL_OVERRIDE
virtual void inform_engaged(Character *engaged) POL_OVERRIDE
std::vector< Items::UArmor * > armor_
virtual void readProperties(Clib::ConfigElem &elem) POL_OVERRIDE
const unsigned short DEFAULT_TEXT_FONT
void loadEquipablePropertiesNPC(Clib::ConfigElem &elem)
const NpcTemplate & find_npc_template(const Clib::ConfigElem &elem)
bool can_freemove() const
virtual const char * classname() const POL_OVERRIDE
virtual void printSelfOn(Clib::StreamWriter &sw) const POL_OVERRIDE
ZoneCharacters characters
const char * rest() const
virtual void destroy() POL_OVERRIDE
void zone_convert_clip(int x, int y, const Realms::Realm *realm, unsigned short *wx, unsigned short *wy)
void readNpcProperties(Clib::ConfigElem &elem)
bool getprop(const std::string &propname, std::string &propvalue) const
POL_NORETURN void throw_error(const std::string &errmsg) const
Multi::UMulti * system_find_multi(u32 serial)
void readCommonProperties(Clib::ConfigElem &elem)
virtual void inform_imoved(Character *chr) POL_OVERRIDE
AttributeFlags< OBJ_FLAGS > flags_
UOExecutor * create_script_executor()
virtual void inform_criminal(Character *thecriminal) POL_OVERRIDE
bool npc_path_blocked(Core::UFACING dir) const
virtual double armor_absorb_damage(double damage) POL_OVERRIDE
boost_utils::npctemplate_name_flystring template_name
virtual void get_hitscript_params(double damage, Items::UArmor **parmor, unsigned short *rawdamage) POL_OVERRIDE
const AttributeValue & attribute(unsigned attrid) const
virtual bool can_be_renamed_by(const Character *chr) const POL_OVERRIDE
Core::CharacterRef master_
UArmor * create_intrinsic_shield_from_npctemplate(Clib::ConfigElem &elem, const Plib::Package *pkg)
Creates a new intrinic shield for an NPC template and returns it.
virtual void readProperties(Clib::ConfigElem &elem) POL_OVERRIDE
bool setProgram(EScriptProgram *prog)
bool could_move(Core::UFACING dir) const
ref_ptr< Mobile::Character > CharacterRef
void readNewNpcAttributes(Clib::ConfigElem &elem)
bool use_adjustments() const
void ClrCharacterWorldPosition(Mobile::Character *chr, Realms::WorldChangeReason reason)
Bscript::BObjectImp * send_event_script(Bscript::BObjectImp *event)
const char * TextTypeToString(u8 texttype)
SettingsManager settingsManager
Core::AttributeFlags< MOB_FLAGS > mob_flags_
virtual void destroy() POL_OVERRIDE
StateManager stateManager
Mobile::Character * system_find_mobile(u32 serial)
virtual void on_death(Items::Item *corpse) POL_OVERRIDE
void on_pc_spoke(Character *src_chr, const char *speech, u8 texttype)
boost::flyweight< std::string, boost::flyweights::tag< script_name_tag >, FLYWEIGHT_HASH_FACTORY > script_name_flystring
bool remove_prop(const char *propname, std::string *value)
const unsigned ATTRIBUTE_MAX_BASE
NPC(u32 objtype, const Clib::ConfigElem &elem)
virtual void printProperties(Clib::StreamWriter &sw) const POL_OVERRIDE
virtual void inform_leftarea(Character *wholeft) POL_OVERRIDE
void on_ghost_pc_spoke(Character *src_chr, const char *speech, u8 texttype)
unsigned short pol_distance(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2)
Items::UWeapon * intrinsic_weapon
bool anchor_allows_move(Core::UFACING dir) const
unsigned short remove_ushort(const char *propname)
virtual void printDebugProperties(Clib::StreamWriter &sw) const POL_OVERRIDE
virtual void inform_moved(Character *moved) POL_OVERRIDE
virtual void apply_raw_damage_hundredths(unsigned int damage, Character *source, bool userepsys=true, bool send_damage_packet=false)
void change(ENUM flag, bool value)
UWeapon * create_intrinsic_weapon_from_npctemplate(Clib::ConfigElem &elem, const Plib::Package *pkg)
Creates a new intrinic weapon for an NPC template and returns it.
virtual void refresh_ar()
bool no_drop_exception() const
void schedule_executor(UOExecutor *ex)
virtual void refresh_ar() POL_OVERRIDE
bool FileExists(const char *filename)
virtual void inform_disengaged(Character *disengaged) POL_OVERRIDE
Items::UWeapon * wrestling_weapon
bool load(const char *dice, std::string *errormsg)
bool inrangex(const Character *c1, const Character *c2, int maxdist)
void start_script(const char *filename, Bscript::BObjectImp *param0, Bscript::BObjectImp *param1)
virtual std::string name() const
virtual u16 get_damaged_sound() const
virtual void unregister_object(UObject *obj)
bool remove_bool(const char *propname)
virtual size_t estimatedSize() const POL_OVERRIDE
void readPropertiesForNewNPC(Clib::ConfigElem &elem)
unsigned short damaged_sound
virtual void printProperties(Clib::StreamWriter &sw) const POL_OVERRIDE
boost::flyweight< std::string, boost::flyweights::tag< npctemplate_name_tag >, FLYWEIGHT_HASH_FACTORY > npctemplate_name_flystring
Mobile::Character * attached_npc_
Equipment * find_intrinsic_equipment(const std::string &name, u8 layer)
Looks up for an existing intrinsic equipment and return it or nullptr if not found.
Module::OSExecutorModule * os_module
static Attribute * FindAttribute(const std::string &str)