mirror of
https://github.com/UOX3DevTeam/UOX3
synced 2026-08-13 12:27:04 -04:00
Added dummy context restore function to additional scripts Updated 'go command to support specifying location to teleport to by name, mapped to locations from locations.dfn (Thanks Dragon Slayer!) Updated Smart Turn script for furniture (js/server/misc/furniture_smartturn.js) with more optimized code (Humility) Fixed latitude/longitude output of GetMapCoordinates helper function (js/server/data/map_coordinates.js), and updated scripts that relied on it Fixed an issue where trying to craft fletching tools would produce hatchets instead (js/skill/craft/fletching.js) Updated js/item/bankcheck.js to display value of checks using onTooltip JS Event, or onNameRequest JS Event if tooltips are disabled Fixed a couple of DFN formatting issues (thanks, punt) Fixed an issue where blank deeds (and bank checks) would be pileable if dropped on the same container (dfndata/items/tools/inscription.dfn) Added dedicated [bankcheck] DFN item (dfndata/items/misc/money.dfn) Updated Banker AI script (js/npc/ai/banker.js) to use dedicated [bankcheck] item instead of blank deeds as base for bank checks, and to have banker NPCs pause and turn towards player when talked to Fixed an issue with script for Healing/Veterinary (js/skill/healing.js) which incorrectly used Anatomy as supplementary skill for Veterinary instead of Animal Lore, and which checked dex of wrong character when calculating healing slips Added two missing tile flags to tileflag enum that threw order of such flags added with HS expansion out of order (thanks, punt) Fixed an issue with travel-commands in GM menu which handled travelling between facets incorrectly Added region spawners for dungeons, towns and overworld in Ilshenar facet Enabled Trammel and Ilshenar facet decorations/spawns by default in admin welcome script (js/server/misc/admin_welcome.js) Reworked portions of admin welcome gump to display optional "addon" decorations per facet, which might be client/era-specific (js/server/misc/admin_welcome.js) Added new NPCs to dfndata/npc/femalehuman.dfn: f_executioner, f_chaosdragoon, f_chaosdragoonelite, f_gypsybanker Added new NPCs to dfndata/npc/femalevendors.dfn: f_gypsymaiden, f_gypsyanimaltrainer, f_gypsyfortuneteller, f_vagabond, f_ironworker Added new NPCs to dfndata/npc/malehuman.dfn: m_executioner, m_chaosdragoon, m_chaosdragoonelite, m_gypsybanker Added new NPCs to dfndata/npc/malevendors.dfn: m_gypsyanimaltrainer, m_vagabond, m_ironworker Added new NPC to dfndata/npc/miscmonsters.dfn: darkwisp Added new NPC to dfndata/npc/undead.dfn: ancientlich Added new Item DFNs for "camps" that when spawned will create a camp with specific decorations ([ilsh_orc_camp], [ilsh_healer_camp], [ilsh_mage_camp], [ilsh_banker_camp]) Added scripts for camps (js/item/camps/ilsh_banker_camp.js, js/item/camps/ilsh_healer_camp.js, js/item/camps/ilsh_mage_camp.js, js/item/camps/ilsh_orc_camp.js) Added new colorlist to dfndata/colors/colors.dfn: [RANDOMCOLOR 33] (Bright Primary Colors) Fixed an issue with gargish cloth chest DFN which prevented LBR version from working properly (dfndata/items/gear/armor/gargish_armor/gargish_cloth.dfn) Added a bunch of new NPCLISTS in various npclist DFN files to support regional spawns in Ilshenar Added missing BACKPACK tag to [golem] NPC DFN (dfndata/npc/clockwork.dfn) Fixed misspelled section header for Fire Elemental NPC - from firele to fireele (dfndata/npc/elementals.dfn) Murderous brigand NPCs are no longer willing to teach players skills (dfndata/npc/femalehuman.dfn, dfndata/npc/malehuman.dfn) Corrected coordinates of Rock Dungeon region (dfndata/regions/regions.dfn) Added regions for Sea Market (Felucca/Trammel), Blackthorn Dungeon (Felucca/Trammel) and Lakeshire (Ilshenar) (dfndata/regions/regions.dfn) Fixed an issue with 'radditem and 'raddspawner GM commands which would not correctly set the Z of the added item/spawner to match target location (js/commands/custom/repeatingcmds.js) Added two new repeating commands (js/commands/custom/repeatingcmds.js): 'rmovable # // Repeats bringing up targeting cursor to set movable property on multiple objects 'rnodecay // Repeats bringing up targeting cursor to set decayable property to false on multiple objects Added new areacommand (js/commands/targeting/areacommand.js): 'areacommand name [string] // Sets name of all objects within targeted area to [string] Updated 'decorate command script to better handle flags passed in via admin welcome script for things like facet addons (js/commands/decorate.js) Updated fire breath script (js/npc/special/fire_breath.js) to get fire breath info per NPC based on their sectionID rather than their base body ID Updated facet ruleset script (js/server/misc/facetRuleset.js) with an override for GMs trying to snoop players even in places where snooping is disallowed Updated facet ruleset script (js/server/misc/facetRuleset.js) to allow damage that's not coming from a player/NPC source even in Trammel/Ilshenar Added teleport locations for entering/leaving Blackthorn Dungeon in Felucca/Trammel (js/teleport.scp) Updated 'remove and 'rremove commands to release any targeted objects from potential multis they are locked in to properly update lockdown count (js/commands/targeting/remove.js, js/commands/custom/repeatingcmds.js) Updated felucca/ilshenar world templates with decorations (js/jsdata/worldtemplates/felucca_*/ilshenar_*) Added world templates with decorations for Trammel (js/jsdata/worldtemplates/trammel_*) Added DFN entry for Power Generators, and spawn entries for these in Ilshenar (dfndata/item/puzzles/puzzles.dfn, dfndata/spawn/ilshenar/spawn_ilshenar_world_general.dfn) Added script for Power Generators, which initializes random puzzles on creation and rewards player with diamonds/arcane gems/shadow iron ore when solved, or lightning when failing to solve (js/item/power_generator.js) Added support for overriding newbie-state of items added to players via dfndata/newbie/newbie.dfn. Supported syntax: PACKITEM=sectionID[, amount[, newbieFlag]] // To use newbieFlag with PACKITEM, amount must also be specified. Flag can be 0/1 EQUIPITEM=sectionID[, itemHue[, newbieFlag] // To use newbieFlag with EQUIPITEM, itemHue must also be specified. Flag can be 0/1 Casting the Earthquake spell will no longer affect the caster, or cause them to become criminal when cast out of town with no impacted targets Fixed a bug where caster would remain frozen after finishing casting targetless spells like Earthquake Fixed a bug where caster would remain frozen if spellcast was cancelled half-ways through by picking up or equipping an item Fixed a bug where caster would remain frozen if spellcast was interrupted by losing concentration from taking melee damage in combat Fixed a bug where a paralyzed player would remain frozen even if taking magic or poison damage, which releases them from paralyzis Fixed a bug where target of Paralyze spell would not visually be shown as frozen in target's client Fixed a bug where a caster frozen while casting a spell could become unfrozen mid-cast because of incoming magic damage Address overflow issue in MultiMul.cpp (punt) Address various cast issues (punt) Corrected jscript project, to not include two files that where for stand alone programs (and resulted in main being added twice in the library (and once was incorrect all ready). (punt) Replaced RoundNumber with std::round (punt) The original physical appearance of characters targeted by 'make admin/gm/cns is now kept track of, and restored upon being targeted by 'make player Fixed an issue where the .HasSpell JS Method was off by 1 when looking for specific spells in player's spellbook, due to 0-based array indexing in code vs 1-based indexing for Spells in DFNs
312 lines
9.1 KiB
C++
312 lines
9.1 KiB
C++
#ifndef __UOXMAP_CLASSES_H__
|
|
#define __UOXMAP_CLASSES_H__
|
|
|
|
#include <cstdint>
|
|
#include <sstream>
|
|
#include <array>
|
|
#include <bitset>
|
|
#include <algorithm>
|
|
|
|
#include "power.h"
|
|
#include "MultiMul.hpp"
|
|
#include "osunique.hpp"
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
enum TileFlags
|
|
{
|
|
// Flag: Also known as:
|
|
TF_FLOORLEVEL = 0, // "Background"
|
|
TF_HOLDABLE, // "Weapon"
|
|
TF_TRANSPARENT, // "SignGuildBanner"
|
|
TF_TRANSLUCENT, // "WebDirtBlood"
|
|
TF_WALL, // "WallVertTile"
|
|
TF_DAMAGING,
|
|
TF_BLOCKING, // "Impassable"
|
|
TF_WET, // "LiquidWet"
|
|
TF_UNKNOWN1, // "Ignored"
|
|
TF_SURFACE, // "Standable"
|
|
TF_CLIMBABLE, // "Bridge"
|
|
TF_STACKABLE, // "Generic"
|
|
TF_WINDOW, // "WindowArchDoor"
|
|
TF_NOSHOOT, // "CannotShootThru"
|
|
TF_DISPLAYA, // "Prefix A"
|
|
TF_DISPLAYAN, // "Prefix An"
|
|
TF_DESCRIPTION, // "Internal"
|
|
TF_FOLIAGE, // "FadeWithTrans"
|
|
TF_PARTIALHUE,
|
|
TF_UNKNOWN2,
|
|
TF_MAP,
|
|
TF_CONTAINER,
|
|
TF_WEARABLE, // "Equipable"
|
|
TF_LIGHT, // "LightSource"
|
|
TF_ANIMATED,
|
|
TF_NODIAGONAL, // "HoverOver" in SA clients and later, to determine if tiles can be moved on by flying gargoyles
|
|
TF_UNKNOWN3, // "NoDiagonal" in SA clients and later?
|
|
TF_ARMOR, // "WholeBodyItem"
|
|
TF_ROOF, // "WallRoofWeap"
|
|
TF_DOOR,
|
|
TF_STAIRBACK, // "ClimbableBit1"
|
|
TF_STAIRRIGHT, // "ClimbableBit2"
|
|
|
|
// Following flags were added in HS expansion? Purpose unknown
|
|
TF_ALPHABLEND, // Blend Alphas, tile blending
|
|
TF_USENEWART, // Uses new art style?
|
|
TF_ARTUSED, // Is art being used?
|
|
TF_BIT36, // Unknown/Unused
|
|
TF_NOSHADOW, // Disallow shadow on this tile, lightsource? lava?
|
|
TF_PIXELBLEED, // Let pixels bleed in to other tiles? Is this Disabling Texture Clamp?
|
|
TF_PLAYANIMONCE, // Play tile animation once.
|
|
TF_BIT40, // Unknown/Unused
|
|
TF_MULTIMOVABLE, // Movable multi? Cool ships and vehicles etc?
|
|
TF_COUNT
|
|
};
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
// Pre declare tileinfo so we can make it a friend of CBaseTile, CTile, and CLand
|
|
class TileInfo;
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
// Frankly, these chould/should have been structures, There really isn't a reason to make the
|
|
// data private, and then expose everything with accessors. Just adds a lot of verbage,
|
|
// that can clutter when maintaining. Oh well, we stay compatable for now.
|
|
class CBaseTile
|
|
{
|
|
friend TileInfo;
|
|
protected:
|
|
std::bitset<64> flags; // We are going to use a 64 bit value here, so specify 64 bit.
|
|
// This one day may be changed to a vector of bools, but for now
|
|
std::string name;
|
|
|
|
public:
|
|
CBaseTile()
|
|
{
|
|
flags.reset();
|
|
}
|
|
virtual ~CBaseTile() = default;
|
|
// This doesnt seem to be used, but I wonder about DFN overloads?
|
|
//
|
|
/*
|
|
auto Flag( UI08 part ) const -> std::uint8_t
|
|
{
|
|
auto mFlags = static_cast<std::uint32_t>( flags.to_ulong() );
|
|
auto retVal = std::uint8_t( 0 );
|
|
switch( part )
|
|
{
|
|
case 0: retVal = static_cast<std::uint8_t>( mFlags >> 24 ); break;
|
|
case 1: retVal = static_cast<std::uint8_t>( mFlags >> 16 ); break;
|
|
case 2: retVal = static_cast<std::uint8_t>( mFlags >> 8 ); break;
|
|
case 3: retVal = static_cast<std::uint8_t>( mFlags % 256 ); break;
|
|
}
|
|
return retVal;
|
|
}
|
|
*/
|
|
auto Name() const -> const std::string& { return name; }
|
|
auto Name( const std::string &value ) -> void { name = value; }
|
|
|
|
auto FlagsNum() const -> std::uint32_t { return static_cast<std::uint32_t>( flags.to_ulong() ); }
|
|
auto Flags() const -> std::bitset<64> { return flags; }
|
|
void Flags( std::bitset<64> newVal ) { flags = newVal; }
|
|
|
|
bool CheckFlag( TileFlags toCheck ) const
|
|
{
|
|
if( toCheck >= TF_COUNT )
|
|
{
|
|
return false;
|
|
}
|
|
return flags.test( toCheck );
|
|
}
|
|
void SetFlag( TileFlags toSet, bool newVal )
|
|
{
|
|
if( toSet >= TF_COUNT )
|
|
{
|
|
return;
|
|
}
|
|
flags.set( toSet, newVal );
|
|
}
|
|
};
|
|
//o------------------------------------------------------------------------------------------------o
|
|
class CTile : public CBaseTile
|
|
{
|
|
private:
|
|
friend TileInfo;
|
|
std::uint8_t weight;
|
|
std::int8_t layer;
|
|
std::uint16_t unknown1;
|
|
std::uint8_t unknown2;
|
|
std::uint8_t quantity;
|
|
std::uint16_t animation;
|
|
std::uint8_t unknown3;
|
|
std::uint8_t hue;
|
|
std::uint8_t unknown4;
|
|
std::uint8_t unknown5;
|
|
std::int8_t height;
|
|
public:
|
|
CTile() :CBaseTile(), weight( 0 ), layer( 0 ), unknown1( 0 ), unknown2( 0 ), quantity( 0 ), animation( 0 ), unknown3( 0 ), hue( 0 ), unknown4( 0 ), unknown5( 0 ), height( 0 )
|
|
{
|
|
}
|
|
~CTile() = default;
|
|
auto Unknown1() const -> std::uint16_t { return unknown1; }
|
|
auto Unknown2() const -> std::uint8_t { return unknown2; }
|
|
auto Unknown3() const -> std::uint8_t { return unknown3; }
|
|
auto Unknown4() const -> std::uint8_t { return unknown4; }
|
|
auto Unknown5() const -> std::uint8_t { return unknown5; }
|
|
auto Hue() const -> std::uint8_t { return hue; }
|
|
auto Quantity() const -> std::uint8_t { return quantity; }
|
|
auto Animation() const -> std::uint16_t { return animation; }
|
|
auto Weight() const -> std::uint8_t { return weight; }
|
|
auto Layer() const -> std::int8_t { return layer; }
|
|
auto Height() const -> std::int8_t { return height; }
|
|
auto ClimbHeight( bool trueHeight = false ) const -> std::int8_t
|
|
{
|
|
if( CheckFlag( TF_CLIMBABLE ) && !trueHeight )
|
|
{
|
|
return height / 2;
|
|
}
|
|
return height;
|
|
}
|
|
void Unknown1( std::uint16_t newVal ) { unknown1 = newVal; }
|
|
void Unknown2( std::uint8_t newVal ) { unknown2 = newVal; }
|
|
void Unknown3( std::uint8_t newVal ) { unknown3 = newVal; }
|
|
void Unknown4( std::uint8_t newVal ) { unknown4 = newVal; }
|
|
void Unknown5( std::uint8_t newVal ) { unknown5 = newVal; }
|
|
void Animation( std::uint16_t newVal ) { animation = newVal; }
|
|
void Weight( std::uint8_t newVal ) { weight = newVal; }
|
|
void Layer( std::int8_t newVal ) { layer = newVal; }
|
|
void Height( std::int8_t newVal ) { height = newVal; }
|
|
void Hue( std::uint8_t newVal ) { hue = newVal; }
|
|
void Quantity( std::uint8_t newVal ) { quantity = newVal; }
|
|
};
|
|
//o------------------------------------------------------------------------------------------------o
|
|
class CLand : public CBaseTile
|
|
{
|
|
friend TileInfo;
|
|
private:
|
|
std::uint16_t textureId;
|
|
// List of road tiles, or road-related tiles, on which houses cannot be placed
|
|
constexpr static
|
|
std::array<std::uint16_t, 18> roadIds
|
|
{
|
|
0x0009, 0x0015, // furrows
|
|
0x0071, 0x0078, // dirt
|
|
0x00E8, 0x00EB, // dirt
|
|
0x0150, 0x015C, // furrows
|
|
0x0442, 0x0479, // sand stone
|
|
0x0501, 0x0510, // sand stone
|
|
0x07AE, 0x07B1, // dirt
|
|
0x3FF4, 0x3FF4, // dirt
|
|
0x3FF8, 0x3FFB // dirt
|
|
};
|
|
|
|
public:
|
|
CLand() :CBaseTile(), textureId( 0 )
|
|
{
|
|
}
|
|
~CLand() = default;
|
|
auto TextureId() const -> std::uint16_t { return textureId; }
|
|
auto TextureId( std::uint16_t newVal ) -> void { textureId = newVal; }
|
|
auto IsRoadId() const -> bool
|
|
{
|
|
auto rValue = false;
|
|
for( size_t j = 0; j < roadIds.size(); j += 2 )
|
|
{
|
|
if( textureId >= roadIds[j] && textureId <= roadIds[j + 1] )
|
|
{
|
|
rValue = true;
|
|
break;
|
|
}
|
|
}
|
|
return rValue;
|
|
}
|
|
};
|
|
|
|
|
|
enum TileType_t { terrain, art, dyn };
|
|
|
|
// A structure that holds tile information. Type, id, information, altitude (if in a map), hue (if a static tile)
|
|
|
|
struct Tile_st
|
|
{
|
|
TileType_t type;
|
|
std::uint16_t tileId; // for instance, this should be a tileid_t , that would make sense!
|
|
std::int8_t altitude;
|
|
std::uint16_t staticHue;
|
|
union
|
|
{
|
|
const CTile *artInfo;
|
|
const CLand *terrainInfo;
|
|
};
|
|
constexpr static std::array<std::uint16_t, 11> terrainVoids
|
|
{
|
|
430, 431, 432,
|
|
433, 434, 475,
|
|
580, 610, 611,
|
|
612, 613
|
|
};
|
|
auto CheckFlag( TileFlags toCheck ) const -> bool
|
|
{
|
|
if( type != TileType_t::terrain )
|
|
{
|
|
return artInfo->CheckFlag( toCheck );
|
|
}
|
|
return terrainInfo->CheckFlag( toCheck );
|
|
}
|
|
Tile_st( TileType_t type = TileType_t::terrain ) :type( type ), tileId( 0 ), altitude( 0 ), staticHue( 0 ), artInfo( nullptr ) {}
|
|
auto isVoid() const -> bool
|
|
{
|
|
auto rValue = false;
|
|
if( type == TileType_t::terrain )
|
|
{
|
|
auto iter = std::find_if( terrainVoids.begin(), terrainVoids.end(), [this]( const std::uint16_t &value )
|
|
{
|
|
return tileId == value;
|
|
});
|
|
rValue = iter != terrainVoids.end();
|
|
}
|
|
return rValue;
|
|
}
|
|
auto IsMountain() const -> bool
|
|
{
|
|
auto rValue = false;
|
|
if( type != TileType_t::terrain )
|
|
{
|
|
rValue = (( tileId >= 431 ) && ( tileId <= 432 )) || (( tileId >= 467 ) && ( tileId <= 474 )) ||
|
|
(( tileId >= 543 ) && ( tileId <= 560 )) || (( tileId >= 1754 ) && ( tileId <= 1757 )) ||
|
|
(( tileId >= 1787 ) && ( tileId <= 1789 )) || (( tileId >= 1821 ) && ( tileId <= 1824 )) ||
|
|
(( tileId >= 1851 ) && ( tileId <= 1854 )) || (( tileId >= 1881 ) && ( tileId <= 1884 ));
|
|
}
|
|
return rValue;
|
|
}
|
|
auto top() -> std::int16_t
|
|
{
|
|
auto value = static_cast<int16_t>( altitude );
|
|
if( type != TileType_t::terrain )
|
|
{
|
|
auto temp = artInfo->Height();
|
|
temp = ( temp & 0x8 ? ( temp & 0xF ) >> 1 : temp & 0xF );
|
|
|
|
value += temp;
|
|
}
|
|
return value;
|
|
}
|
|
auto height() -> std::uint8_t
|
|
{
|
|
if( type != TileType_t::terrain )
|
|
{
|
|
return artInfo->Height();
|
|
}
|
|
return 0;
|
|
}
|
|
auto name() const -> std::string
|
|
{
|
|
if( type != TileType_t::terrain )
|
|
{
|
|
return artInfo->Name();
|
|
}
|
|
return terrainInfo->Name();
|
|
}
|
|
};
|
|
#endif
|
|
|