2002-04-07 21:27:53 +00:00
|
|
|
#include "uox3.h"
|
2012-11-03 18:11:04 +00:00
|
|
|
#include "regions.h"
|
Housing Revamp and more
Updated JS SysMessage function to accept up to 10 extra, optional arguments, which can be used with dictionary messages that require additional parameters like %s or %i
Added new type of house privilege in cMultiObj.cpp to keep track of friends of the multi - HOUSEPRIV_FRIEND - which is stored during worldsaves as one or more Friend=<player serial> tags in house.wsc
Added new type of house privilege in cMultiObj.cpp to keep track of guests of the multi - HOUSEPRIV_GUEST - which is stored during worldsaves as one or more Guest=<player serial> tags in house.wsc
When items are created for houses upon house placement, a reference to the multi's serial is now stored in the house sign's MORE property to allow easier tracking of which house a particular sign belongs to
Added tracking of new, persistent properties for houses via cMultiObj.cpp/h:
lockdowns, secure containers, vendors, guests, friends, owners, ban location, public status, number of visits, timestamps
Added a multitude of new methods in cMultiObj.cpp/h to assist in improving the functionality of houses
Added new tags for houses in house.dfn (default values applied if tag not specified):
MAXSECURECONTAINERS=4 - Max amount of secure containers allowed in a multi
MAXLOCKDOWNS=256 - Max amount of lockdowns allowed in a multi
MAXVENDORS=10 - Max amount of vendors allowed in a multi
MAXBANS=50 - Max amount of bans in a multi's ban list
MAXFRIENDS=50 - Max amount of friends in a multi's friend list
MAXGUESTS=50 - Max amount of guests in a multi's guest list
MAXOWNERS=8 - Max amount of owners and co-owners in a multi's owner list
MAXTRASHCONTAINERS=1 - Max amount of trash containers allowed in multi
SCRIPT=<scriptID> - Assign a JS script-ID directly to a multi
FRONTDOOR - indicates that a door is the front door of a house. Cannot be locked in public houses!
INTERIORDOOR - indicates that a door is an interior door of a house. Can be locked in public houses.
BANX - Location X offset for multi's ban location, if not used, will try to use SE corner of multi instead
BANY - Location Y offset for multi's ban location, if not used, will try to use SE corner of multi instead
Added JS Event:
onHouseCommand( tSock, multiObj, cmdID ) - For handling spoken house commands via JS scripts attached to multi.
Updated JS Events:
onEntrance() - can now trigger both for multi being entered and/or object entering
onLeaving() - can now trigger both for multi being left and/or object entering
onSpeech() - can now also trigger for items (in addition to chars) with event & script attached, if UOX.INI setting ITEMSDETECTSPEECH is enabled
Added JS Multi methods:
.IsBoat() - Returns whether the item (or multi) is a boat
.IsOwner( playerToCheck ) - Returns whether a player is the owner of a multi
.IsOnOwnerList( playerToCheck ) - Returns whether a player is on the (co-)owner list of a multi
.IsOnFriendList( playerToCheck ) - Returns whether a player is on the friend list of a multi
.IsOnGuestList( playerToCheck ) - Returns whether a player is on the guest list of a multi
.IsOnBanList( playerToCheck ) - Returns whether a player is on the ban list of a multi
.AddToFriendList( playertoAdd ) - Adds player to the friend list of a multi
.RemoveFromFriendList( playertoRemove ) - Removes player from the friend list of a multi
.AddToGuestList( playertoAdd ) - Adds player to the guest list of a multi
.RemoveFromGuestList( playertoRemove ) - Removes player from the guest list of a multi
.ClearOwnerList() - Clears all entries from a multi's (co-)owner list
.ClearFriendList() - Clears all entries from a multi's friend list
.ClearGuestList() - Clears all entries from a multi's guest list
.ClearBanList() - Clears all entries from a multi's ban list
.SecureContainer( itemToSecure ) - Secures a container in a multi
.UnsecureContainer( itemToUnsecure ) - Unsecures a container in a multi
.IsSecureContainer( itemToCheck ) - Checks if specified item is a secure container in a multi
.LockDownItem( itemToLockDown) - Locks down an item in a multi
.ReleaseItem( itemToRelease ) - Releases a locked down item in a multi
.KillKeys() - Deletes ALL keys associated with a multi
.AddTrashCont( itemToAdd ) - Add trash container to multi's list of trash containers
.RemoveTrashCont( itemToRemove ) - Remove trash container from multi's list of trash containers
Added JS Item (Multi only) properties:
.lockdowns - Get the number of lockdowns in a multi
.maxLockdowns - Get/Set the max number of lockdowns allowed in a multi
.secureContainers - Get the number of secure containers in a multi
.maxSecureContainers - Get/Set the max number of secure containers allowed in a multi
.trashContainers - Get the number of trash containers in a multi
.maxTrashContainers - Get/Set the max number of trash containers allowed in a multi
.friends - Get the number of friends in a multi's friend list
.maxFriends - Get/Set the max number of friends allowed in a multi's friend list
.guests - Get the number of guests in a multi's guest list
.maxGuests - Get/Set the max number of guests allowed in a multi's guest list
.owners - Get the number of owners in a multi's owner list
.maxOwners - Get/Set the max number of owners allowed in a multi's owner list
.bans - Get the number of banned players in a multi's ban list
.maxBans - Get/Set the max number of banned players allowed in a multi's ban list
.vendors - Get the number of player vendors in a multi
.maxVendors - Get the max number of player vendors allowed in a multi
.deed - Get the item sectionID for deed used to place multi
.isPublic - Get/Set the private/public state of a multi
.buildTimestamp - Get the timestamp for when the house was originally placed
.tradeTimestamp - Get the timestamp for when the house was last traded to another player
.banX - Get/Set the ban location X offset for the multi
.banY - Get/Set the ban location Y offset for the multi
Added JS Character properties:
.multi = Get/Set the multi object the character is in
.accountNum = Get the account number the character belongs to
.housesOwned = Get a count of houses owned by the character
.housesCoOwned = Get a count of houses co-owned by the character
Updated JS cBaseObject Methods .FirstItem(), .NextItem() and .FinishedItems() to also support iterating through items in multis
Updated JS multi Methods .FirstChar(), .NextChar() and .FinishedChars() to support an additional parameter to specify what kind of characters to loop through:
"default" or no parameter - all characters inside the multi
"owner" - players on multi's owner list
"friend" - players on multi's friend list
"guest" - players on multi's guest list
"banned" - players on multi's ban list
Added new INI tags to a new section of uox.ini called [houses]
DECAYTIMERINHOUSE=3600 // Decay timer in seconds for non-locked down items inside houses
PROTECTPRIVATEHOUSES=1 // Toggles whether private houses will automatically boot unauthorized visitors (1) or not (0)
TRACKHOUSESPERACCOUNT=1 // Toggles whether to track (and restrict) house ownership per account (1) or per character (0)
MAXHOUSESOWNABLE=1 // Specifies the max amount of houses a player can own per account/char, depending on how house ownership is tracked
MAXHOUSESCOOWNABLE=10 // Specifies the max amount of houses a player can co-own per character
CANOWNANDCOOWNHOUSES=1 // Toggles whether players can own and co-own houses at the same time
COOWNHOUSESONSAMEACCOUNT=1 // Toggles whether characters on same account as house owner will be treated as co-owners
Added new INI tags in [settings] section of uox.ini:
ITEMSDETECTSPEECH=0 // If enabled, server will search for nearby items with onSpeech JS event running whenever a character speaks. Disabled by default.
MAXPLAYERPACKITEMS=125 // Defines max item capacity for player (and NPC) backpacks. Defaults to 125.
Moved most of the existing house functionality to JS and expanded upon it to reach feature parity with houses in regular UO around Publish 15/16, with various extras thrown in for good measure and all functionality being customizable:
js/server/house/house.js (15000) - handles detection of house commands and characters entering/leaving houses
js/server/house/houseSign.js (15001) - contains and handles all house-related gumps/menus and what is shown when players interact with house sign
js/server/house/houseCommands.js (15002) - handles functionality of house commands and other functionality such as transfer of ownership, demolishing house, etc.
js/server/house/houseDeed.js (15003) - handles initial rules that allow/disallow placement of additional houses for players
All house-related menus now fully handled through JS
All house commands and other functionality now fully handled through JS
Removed redundant hard-coded house functionality
Implemented Co-owners, friends, guests for houses, with access rules in place for entry, lockdowns, house commands, etc.
Implemented Private and Public houses
Implemented Secure Containers and Trash Barrels
Definable max lockdowns, secure containers, player vendors, bans, friends, guests, owners, trash containers and more - per house type
JS scripts can now be attached directly to houses
Doors in houses can be marked as front doors or interior doors, and will be treated differently with regards to private and public houses
Added new item to dfndata/items/containers/misc.dfn - [trashbarrel]
Added new JS script (js/items/trashbarrel.js) with trash barrel functionality for houses. Trash barrels that are marked as secure containers are only accessible by owners, co-owners and friends of the house. Various options available at top of script.
Updated js/items/axe.js to support chopping up trash barrels and house add-ons in houses owned by the player
Fixed an issue with house doors being left behind after demolishing houses while their doors were open
Fixed an issue where GMs could be banned from player houses
Added Line of Sight checks to speech, to give players some privacy in their own homes
Updated house placement code to more accurately check for other multis, dynamic and static objects when placing houses; now requires free space around each house that cannot be blocked by other houses or items that can block player movement, and disallows placement of houses on roads
Updated house placement code to move characters blocking house placement to SE corner of the house
Updated house placement code to disallow placing houses in guarded regions, or in dungeons
Added new DFN tag for regions to enable/disable player houses in specific regions: HOUSING=0/1
Added new region (247) that covers path to Valley of Eodon in Felucca
Added new region (248) that covers Valley of Eodon in Ter-Mur, with player housing disabled
Added new region (249) that covers entire T2A lands, with player housing disabled
Updated SPACEX and SPACEY values for all houses in dfndata/house/house.dfn to match updated house placement code
Added new JS property to Regions that can be used to determine or change state of player housing in a region: .canPlaceHouse()
Updated rules for usage of dye tubs to dye locked down items; now only house owners or co-owners may dye locked down items
Updated rules for usage of the following locked down items in a house, which are now only usable by house owners and co-owners
Dyes, Guildstone Deeds, Recall Runes (renaming), Rename Deeds, Townstone Deeds, House Deeds, Boat Models, Player Vendor Deeds, Ore, Hair Dye
Updated rules for usage of the following locked down items in a house, which are now only usable by house owners, co-owners and friends:
Keys, Dye Tubs, Magic Scrolls, Fireworks Wands, Magic Wands, Smithing Tools, Mining Tools, Fishing Poles
Updated item lockdown rules to allow locking down (and releasing) items in a container as long as the container is locked down, and to only allow releasing a locked down container if it's empty of locked down items
Updated item lockdown rules to only allow locking down movement-blocking items further than 2 tiles away from doors
Updated rules for releasing items in houses - now the house owner can release any locked down items, co-owners can release items locked down by themselves or by friends, while friends can release only items locked down by themselves
Added some feedback to player about why their attempted house placement failed
Items added by GMs directly into multis will now decay based on the house-specific decay timer instead of the regular one
Fixed an issue that could cause items to almost instantly decay after being released from lockdown in a house
Placing house add-ons now properly takes into account SPACEX and SPACEY values when checking if they can fit in selected area of houses
Re-added SPACEX and SPACEY values for Pentagram and Loom house add-ons
House add-ons can now be converted back into house add-on deeds by chopping them with an axe
Added new item type - IT_HOUSEADDON (201) - used by house add-ons placed in player houses
Fixed a bug where keys would stop working after being added to a keyring, and would turn into blank keys upon release from the keyring
Added visitor count for public player houses, which keeps track of how many visits a public house has received, with each player counted max 1 time every 24 hours
Fixed an issue with FindPlayersInOldVisrange() where it didn't take into account that players could see buildings further away than the standard update range. This could cause players to see ghost images of buildings if they were at the "right" distance when the building was being demolished
Added NODECAY tag to all signs and doors in dfndata/house/house.dfn
Added FRONTDOOR or INTERIORDOOR (as appropriate) to all doors in dfndata/house/house.dfn
Added BANX and BANY to specify ban location for some houses in dfndata/house/house.dfn instead of relying on finding SE corner automatically
Implemented strongboxes (js/server/house/strongbox.js) for co-owners of a house, which can be placed with the house command "i wish to place a strongbox". Max capacity is 25 items
Updated 'REMOVE command to take an optional parameter - itemID. If supplied, the command will remove all items with this itemID from a targeted container
Fixed a bug when checking if dynamic items were blocking valid spawn locations for NPCs, some function arguments were in the wrong order!
Improved code that finds valid spawn locations for items and NPCs spawned via spawn regions. As server gradually builds up lists of valid spawn locations per region over time, it will start using these lists more often, rather than always look for brand new spawn locations.
Fixed a bug with CMulHandler::CheckStaticFlag() that prevented NPCs from spawning inside buildings with no static floors!
Fixed an issue with repeating commands that prevented GMs from being able to cancel them when using the ClassicUO client
Exposed character property .accountNum to JS engine
Extended CDataList class to include a Clear() method for clearing lists
Updated JS File method .Open() to support an optional, third argument - subFolderName - that defines in which sub-folder of UOX3/shared/ to store/look for a file. If no third argument is supplied, UOX3 will default to using the shared folder itself.
Updated JS File method .Length() to return a value of -1 for files that don't exist
Added new code function, exposed to JS engine with same parameters, which simply checks if a given tile ID has a specific flag
bool CheckTileFlag( UI16 itemID, TILEFLAG flagToCheck )
Added JS function used to find the root container of an item (if any)
FindRootContainer( itemSerial )
FindRootContainer( item )
Added new JS function that allows deleting files from UOX3/shared/ folder or subfolders of shared folder. If no subFolderName is provided, looks for file directly in shared folder itself. Restrictions on file- and folder-names apply.
bool DeleteFile( fileName, subFolderName )
Added new JS functions for checking if a specific client or server feature is enabled. See documentation for full list of client/server features.
GetClientFeature( bitNum ) // Returns true if specified client feature is enabled on server
GetServerFeature( bitNum ) // Returns true if specified server feature is enabled on server
Added new JS function for returning the value of almost any server setting from UOX.INI
GetServerSetting( settingNameInDoubleQuotes )
Updated JS function DoesDynamicBlock() with two new parameters - checkOnlyMultis and checkOnlyNonMultis
Updated JS function DoesMapBlock() with two new parameters - checkMultiPlacement and checkForRoad
Fixed an issue where a LoS check would prevent players from accessing containers in their own backpack
Added new functions in findfuncs.cpp to make it easier to find items near another object or location:
findNearbyItems( object, distance )
findNearbyItems( x, y, worldNumber, instanceID, distance )
Added new Item property - maxItems - used by containers to determine their max item capacity
Added new Item property - totalItemCount - used to get total item count in a container (including sub-containers)
Added check for max item capacity when creating new items that are added to a character's backpack - items will be created below character's feet if backpack is full!
Added new DFN tag for items, used by containers to determine item capacity for a given container:
MAXITEMS=# // 125 is the default for all containers if not set
Added new JS Item properties:
.maxItems // gets/sets item capacity for a given container
.totalItemCount // gets total item count in a container, including sub-containers
Updated item tooltips for containers to show accurate total item count, as well as to display max item capacity
Fixed a bug where picking up items from a non-locked down pile of items on the floor inside a multi could cause the remaining pile to be seen as no longer inside the multi, disallowing locking it back down and causing it to decay based on regular decay timer instead of house-specific one
Updated JS command set to allow setting poison-level on items ('set poison #) and hunger-level on characters ('set hunger #)
Fixed an issue with js/item/food.js that prevented poisoned food from poisoning characters when eaten
Fixed an issue with js/skill/poisoning.js that prevented players from poisoning food!
Updated various JS scripts and hardcoded targeting functions to disallow the targeting of locked down resources using skills and tools
Updated JS Method TextMessage() to support three extra, optional parameters. Note that if one optional parameter is included, all preceding optional parameters are also required!
speechTarget - What kind of target is this message intended for?
0 - Only visible for sender and receiver of message
1 - Visible to all players in range
2 - Visible to all NPCs and players in range
3 - Visible to all PCs everywhere + NPCs in range
4 - Visible to all PCs everywhere (broadcast)
5 - Only visible for the receiver of the message
speechTargetSerial - The serial of the receiver of the message, used if speechTarget is 0 or 5
speechFontType - The type of font to display the text in. Defaults to normal.
0 - Bold
1 - Normal with shadow
2 - Bold with shadow
3 - Normal
4 - Gothic
5 - Italic
6 - Small, dark
7 - Colourful
8 - Runic (only works with CAPS)
9 - Small, light
Added timestamp to worldsaves in console, to make it easier to see when a particular world-save was done
Added info about compiler/environment displayed at the top of the UOX3 console during startup
Updated dictionary files with new messages primarily related to housing
2020-11-04 02:00:37 +08:00
|
|
|
#include "townregion.h"
|
2012-11-03 18:11:04 +00:00
|
|
|
#include "cServerDefinitions.h"
|
|
|
|
|
#include "ssection.h"
|
|
|
|
|
#include "scriptc.h"
|
2021-06-01 02:44:56 +08:00
|
|
|
#include <filesystem>
|
2012-11-03 18:11:04 +00:00
|
|
|
|
2022-06-12 14:31:18 -04:00
|
|
|
#include <algorithm>
|
|
|
|
|
#include <array>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
using namespace std::string_literals;
|
2022-06-12 14:31:18 -04:00
|
|
|
|
2021-06-12 07:30:23 -04:00
|
|
|
CMulHandler *Map = nullptr;
|
2012-11-03 18:11:04 +00:00
|
|
|
|
2022-06-14 17:53:00 -04:00
|
|
|
//const UI16 LANDDATA_SIZE = 0x4000; //(512 * 32)
|
2002-04-07 21:27:53 +00:00
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
/*!
|
|
|
|
|
** New rewrite plans, its way confusing having every function in here using 'Height' to mean
|
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms
Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt)
Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri)
Updated SpiderMonkey from v1.6.0 to v1.7.0
Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri)
Added StringUtility file with general common string manipulation functions (punt)
Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt)
Overall code cleanup to remove/replace platform-dependent code (punt)
Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt)
Replaced usage of char in many places with std::string (punt)
Started process of replacing UString usage with functions provided through StringUtility instead (punt)
Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt)
Replaced platform specific time handling by using cross-platform chrono library (punt)
Removed UOX namespace to reduce complexity (punt)
Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt)
Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt)
Removed some platform specific files like uoxlinux.h, which is no longer required (punt)
Removed legacy crash protection code, and removed support for cluox (punt)
Removed legacy "support" for Borland compiler (punt)
Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri)
Removed legacy BUILD folder with outdated compilation instructions (Xuri)
Removed old Changelog file (merged into Changelog.txt) (Xuri)
Fixed a pointer bug for items in multis on world load (punt)
Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt)
Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt)
Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt)
Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt)
Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt)
Added some new commands to js/commands/custom/misc-cmd.js (Xuri)
cont // Targeted item will be made a container, set to nondecay and movable 2
endfight // Targeted character (and character being fought) will stop fighting
getmulti // Get multiObject for targeted item
finditem // Find item at layer X
movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen)
Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri)
Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
|
|
|
** elevation or actual height of a tile. Here's the new renaming plan:
|
|
|
|
|
** Elevation - the z value of the bottom edge of an item
|
|
|
|
|
** Height - the height of the item, it is independant of the elevation, like a person is 6ft tall
|
|
|
|
|
** Top - the z value of the top edge of an item, is always Elevation + Height of item
|
|
|
|
|
*/
|
2002-04-07 21:27:53 +00:00
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//==================================================================================================
|
2022-06-15 11:24:57 -04:00
|
|
|
// CMulHandler
|
2022-10-24 18:39:33 +08:00
|
|
|
//==================================================================================================
|
|
|
|
|
//==================================================================================================
|
2012-11-03 18:11:04 +00:00
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::LoadMapsDFN()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
Instance-support and misc code cleanup
Misc code and documentation cleanup:
Updated and standardized function comment blocks throughout entire codebase
Grouped getters and setters together in pairs and documented them as one
Removed empty and/or non-useful information from comment blocks
Removed unused function from cItem.cpp/h - IncID() - formerly used to change IDs for doors
Added new feature - Instances
Objects (characters, items, multis, spawnregions) can now make use of a 5th parameter to determine their location in the game world. In addition to the traditional X, Y, Z and WORLDNUMBER parameters, a new one has been added - INSTANCEID - that allows objects to exist at the same coordinates in the same world, but in different "dimensions". Code has been updated in multiple places to support this, and a default instanceID of 0 is assumed if nothing else is specified.
Added support for new DFN tag in town regions, spawn regions and locations - INSTANCEID (defaults to 0 if not present)
Added support for another start location parameter after worldNum in UOX.INI representing instanceID (defaults to 0 if not present)
Updated TWEAK menu to include WorldNumber and instanceID
Fixed BaseWeight option in TWEAK menu
Updated CBase_Teleport - now takes an optional 5th parameter instanceID
Updated SE_SpawnNPC now takes an optional 5th parameter - instanceID
Updated SE_FindMulti now takes an optional 5th parameter - instanceID
Updated SE_GetItem now takes an optional 5th parameter - instanceID
Updated SE_FindItem now takes an optional 6th parameter - instanceID
Added new JS property for Items, Characters, Regions: .instanceID
Added JS property for Regions: .members - returns comma-separated list of town member serials
Updated JS scripts making use of the above-mentioned JS Methods/Functions
Updated dictionaries with new tweak menu entry texts
Exposed SpawnRegions to JS engine, and updated JS docs with details:
SpawnRegion JS Functions
IterateOverSpawnRegions()
GetSpawnRegion( spawnRegNum )
GetSpawnRegionCount()
SpawnRegion JS Properties
name
regionNum
itemList
npcList
item
npc
maxItems
maxNpcs
itemCount
npcCount
onlyOutside
prefZ
x1
y1
x2
y2
world
instanceID
minTime
maxTime
call
2020-08-08 13:57:15 +08:00
|
|
|
//| Purpose - Loads maps.dfn to see which map files to actually load into memory later
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::LoadMapsDFN( const std::string &uodir ) -> std::map<int, MapDfnData_st>
|
|
|
|
|
{
|
|
|
|
|
auto entrycount = FileLookup->CountOfEntries( maps_def );
|
|
|
|
|
std::map<int, MapDfnData_st> results;
|
|
|
|
|
auto uopath = std::filesystem::path( uodir );
|
2022-12-04 02:03:43 -05:00
|
|
|
for( auto i = 0; i < static_cast<int>( entrycount ); i++ )
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
|
|
|
|
auto toFind = FileLookup->FindEntry( "MAP "s + std::to_string( i ), maps_def );
|
|
|
|
|
if( toFind == nullptr )
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
auto entry = MapDfnData_st();
|
|
|
|
|
for( const auto &sec :toFind->collection() )
|
|
|
|
|
{
|
|
|
|
|
auto uTag = oldstrutil::upper( sec->tag );
|
|
|
|
|
auto data = oldstrutil::trim( oldstrutil::removeTrailing( sec->data ));
|
|
|
|
|
switch( uTag.data()[0] )
|
|
|
|
|
{
|
|
|
|
|
case 'M':
|
|
|
|
|
if( uTag == "MAP" )
|
|
|
|
|
{
|
|
|
|
|
entry.mapFile = ( uopath / std::filesystem::path( data ));
|
|
|
|
|
}
|
|
|
|
|
else if( uTag == "MAPUOPWRAP" )
|
|
|
|
|
{
|
|
|
|
|
entry.mapUop = ( uopath / std::filesystem::path( data ));
|
|
|
|
|
}
|
|
|
|
|
else if( cwmWorldState->ServerData()->MapDiffsEnabled() )
|
|
|
|
|
{
|
|
|
|
|
if( uTag == "MAPDIFF" )
|
|
|
|
|
{
|
|
|
|
|
entry.mapDiff = ( uopath / std::filesystem::path( data ));
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else if( uTag == "MAPDIFFLIST" )
|
|
|
|
|
{
|
|
|
|
|
entry.mapDiffl = ( uopath / std::filesystem::path( data ));
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'S':
|
|
|
|
|
if( uTag == "STATICS" )
|
|
|
|
|
{
|
|
|
|
|
entry.staMul = ( uopath / std::filesystem::path( data ));
|
|
|
|
|
}
|
|
|
|
|
else if( uTag == "STAIDX" )
|
|
|
|
|
{
|
|
|
|
|
entry.staIdx = ( uopath / std::filesystem::path( data ));
|
|
|
|
|
}
|
|
|
|
|
else if( cwmWorldState->ServerData()->MapDiffsEnabled() )
|
|
|
|
|
{
|
|
|
|
|
if( uTag == "STATICSDIFF" )
|
|
|
|
|
{
|
|
|
|
|
entry.staDiff = ( uopath / std::filesystem::path( data ));
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else if( uTag == "STATICSDIFFLIST" )
|
|
|
|
|
{
|
|
|
|
|
entry.staDiffl = ( uopath / std::filesystem::path( data ));
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else if( uTag == "STATICSDIFFINDEX" )
|
|
|
|
|
{
|
|
|
|
|
entry.staDiffi = ( uopath / std::filesystem::path( data ));
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'X':
|
|
|
|
|
if( uTag == "X" )
|
|
|
|
|
{
|
|
|
|
|
entry.width = std::stoi( data );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'Y':
|
|
|
|
|
if( uTag == "Y" )
|
|
|
|
|
{
|
|
|
|
|
entry.height = std::stoi( data );
|
|
|
|
|
}
|
|
|
|
|
break;
|
2012-11-03 18:11:04 +00:00
|
|
|
}
|
2022-12-04 02:03:43 -05:00
|
|
|
results.insert_or_assign( i, entry );
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return results;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::Load()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Load UO data (tiledata, maps, statics, multis)
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::Load() -> void
|
|
|
|
|
{
|
|
|
|
|
auto uodir = cwmWorldState->ServerData()->Directory( CSDDP_DATA );
|
|
|
|
|
auto mapinfo = LoadMapsDFN( uodir );
|
|
|
|
|
Console.PrintSectionBegin();
|
UOX3 0.99.6-RC6
Removed arbitrary and hidden restrictions on refreshing list of online players shown with 'wholist command
Fixed an issue where player ghosts that get teleported would not see themselves get updated to new location
Fixed a server crash from clients disconnecting while running server in debug mode
Improved how container updates are sent to players; now only sends to clients that have actually opened the container, and who are still within range
Added more information about UO data files being loaded during server startup
Enhanced the GM 'add menu to allow clicking directly on images of items/npcs to add them, and adjusted size of menus to accommodate this
Fixed an issue with fleeing NPCs that could cause them to attempt to flee across time and space, regardless of distance to target/attacker in combat
Added NPC AI that runs away from players if they get too close (even outside combat). Applied to hind, rabbits, squirrels, ferrets and various birds by default:
AI_ANIMAL_SCARED (aitype 12)
Fixed issues with NPCs fleeing forever, or getting stuck in flee/don't flee loop, by introducing max fleeing distance (50 tiles) and cooldown (30 sec) on fleeing
Updated onNameRequest JS Event to include third parameter with origin of name request, so script responses can be tailored appropriately:
onNameRequest( myObj, requestedBy, requestSource )
Potential values for requestSource:
0 - Speech/System Messages
1 - Guild Menus
2 - Stat Window (self)
3 - Stat Window (other)
4 - Tooltip
5 - Paperdoll Journal
6 - Paperdoll
7 - Single Click / All-Names
8 - System
9 - Secure Trade Window
Added Adaptive Performance System (APS) that dynamically adjust how often NPC AI/movement is checked based on overall shard performance. If performance drops below defined threshold, UOX3 gradually slows down checks for NPC AI/movement to prioritize player movement/speech/command responsiveness. If performance climbs back up above threshold, slowdowns are gradually removed. The following UOX.INI options have been added under [system] category to support this system:
APSPERFTHRESHOLD=50 // Performance threshold (measured in simulation cycles/sec) below which the APS kicks in
APSINTERVAL=100 // How often (in milliseconds) the APS checks performance and makes adjustments (if needed) to balance out shard performance
APSDELAYSTEP=50 // How much the delay timer is modified by (in milliseconds) each time APS makes adjustments
APSDELAYMAXCAP=2000 // Max amount of of delay APS can introduce for NPC AI/movement handling when attempting to restore shard performance
Added new JS Methods for Region objects:
.GetOrePrefs( oreType ) // Get ore preference data for ore type found in town region. Returned as an array containing the following data:
orePrefData -> [
oreName, // name of ore
color, // color of ore
minskill, // min skill to mine ore
ingotName, // name of ingot created from ore
makemenu, // makemenu entry for crafting something from ingot
oreChance, // default global chance of finding this ore type
scriptID // script attached to mined ore
],
orePrefChance // Chance of finding this ore type in given town region
.GetOreChance() // Get base chance of finding any ore in town region
Moved Mining skill plus gravedigging feature from hard code to scripts (js/skill/mining.js) to make it easier to maintain and/or customize, and removed hard coded variants
Gravedigging now relies on the ore resource system behind the scenes to restrict how often graves in a given area can be dug up
Fixed some incorrect references to .worldNumber Character property in misc scripts (should be .worldnumber)
Made some "hard-scripted" system messages in misc scripts use dictionary system instead
Added spawn region for banker NPCs in Serpent's Hold (dfndata/spawn/felucca/spawn_town_serpents_hold.dfn, dfndata/spawn/trammel/spawn_town_serpents_hold.dfn)
Fixed region definition of Ocllo to actually cover the entire town (dfndata/regions/regions.dfn)
Added numerous additional locations accessible with 'goplace # command, for key locations in Ilshenar, Malas, Tokuno Islands and Ter Mur (dfndata/location/location.dfn)
Revised travel-menu portion of GM menu (shortcut: 'travel) to include more travel options based on new locations (dfndata/items/travelmenu.dfn and travelmenu.bulk.dfn)
Fixed an issue where NPCs could attempt to attack targets in other worlds/instances
Added new JS Event that triggers for characters who are about to deal damage in combat. Complimentary to onDamage, which triggers for chars receiving damage:
onDamageDeal( dmgDealer, dmgReceiver, damageValue, damageType )
Added new JS Event that can trigger in global script upon creation of new player chars. Note that this will trigger in place of onCreateDFN event for player characters:
onCreatePlayer( pChar )
Added new JS Event that triggers for characters selecting a target with a spell. Complimentary to onSpellTarget, which triggers for targets selected with a spell:
onSpellTargetSelect( caster, target, spellNum )
Updated onCombatStart and onCombatEnd JS Events to also trigger for the other party in combat
Updated onPickup JS Event to include a third parameter - the potential container item was picked up from. Event now also triggers event in scripts attached to said containers:
onPickup( iPickedUp, pChar, iCont )
Added tracking of total playtime per individual character, and per account across all characters, and exposed these properties to JS engine:
.totalPlayTime // Account property, total playtime across all chars
.playTime // Character property, total playtime on given character only
Added new player-accessible command ('playtime) to spit out the playtime of current character/account as a whole (js/commands/playtime.js)
Implemented first version of Young Player System:
Replaced the UNUSED9 account flag with YOUNG, to be used by Young/New Player System
Added new JS Account property that gets/sets whether player account is considered Young:
.isYoung
Added new Char timers:
TIMER_YOUNGHEAL // Restricts how often Young players are healed by NPC healers
TIMER_YOUNGMESSAGE // Restricts how often Young players are warned about dangerous looking monsters in overworld
Updated GM commands 'get and 'set to get/set .isYoung property of player's account (js/commands/targeting/get.js and set.js)
Added new UOX.INI setting to enable/disable Young Player System (enabled by default):
YOUNGPLAYERSYSTEM=1
If Young Player System is enabled, all newly created player accounts are automatically marked with Young flag
Added new script to handle various restrictions and functions related to Young characters (js/player/young_player.js):
Young characters will have [Young] displayed over their head
Young characters will have their Young status checked and verified on every login + every stat/skill gain, to revoke the Young status if any of the following is true:
Account has a total playtime of more than 40 hours
Any character has more than 350 total (base) skill points
Any character has more than 70 skill points in a single skill
Any character has more than 150 total stat points
Any character has more than 80 stat points in a single stat
Young characters can renounce their Young status manually by saying the words "I renounce my young player status"
Young characters get two additional items upon creation:
a new player ticket (can be combined with any other players new player ticket for both players to get a reward)
a sextant (shows Young players directions to nearest moongate/bank regardless of where they are, as long as outdoors)
Young characters cannot target other player characters with hostile spells or skills
Young characters cannot be the target of other player characters' hostile spells or skills
Young characters can only cast beneficial spells upon themselves or other Young characters
Young characters can only be the target of beneficial spells from other Young players
Young players (and their pets/followers) cannot attack or harm any other players (or their pets/followers), nor themselves be attacked or harmed by any other players (or their pets/followers), whether from combat, spells, skills or items
Young players don't lose any of their items on death, and are teleported to the nearest healer upon death with all their items intact
Young players receive a warning upon entering dungeons that monsters there will be hostile
Updated global script (js/server/global.js) to:
Check/Verify Young status of players upon login
Attach young player script on login/creation for players on Young accounts
Give specific items to Young players upon creation
Added new script (js/item/corpse.js) that is assigned to all freshly created corpses. This script handles restrictions related to Young players interactions with corpses, and the interactions of other players with corpses of Young players
Updated JS Method .Carve() to return true/false depending on whether carving a corpse was successful
Updated Healer AI in code to heal nearby injured Young players
Updated Evil AI and Evil Caster AI in code to avoid selecting Young players as targets in combat outside of dungeons
Added a new section to UOX.INI - [young player starting locations] - that can be used to define starting locations for Young players. If only one such location is provided, all players start there. Otherwise, it matches the same starting location setup as the regular one - with one entry per town in Britannia.
Restricted transferring and/or friending of pets (code) and hirelings (hirelings.js) between Young and non-Young players
Restricted Young players from recalling or gating to Felucca facet
Young players can instantly logout from anywhere, at any time
2023-07-01 20:02:40 +08:00
|
|
|
Console << "Loading UO Data..." << myendl << "(If they fail to load, check your DATADIRECTORY path in uox.ini or filenames in maps.dfn)" << myendl;
|
2022-10-24 18:39:33 +08:00
|
|
|
LoadTileData( uodir );
|
|
|
|
|
LoadDFNOverrides();
|
|
|
|
|
LoadMapAndStatics( mapinfo );
|
|
|
|
|
if( uoWorlds.empty() )
|
|
|
|
|
{
|
|
|
|
|
Console.Error( " Fatal Error: No maps found" );
|
|
|
|
|
Console.Error( " Check the settings for DATADIRECTORY in uox.ini" );
|
|
|
|
|
Shutdown( FATAL_UOX3_MAP_NOT_FOUND );
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
LoadMultis( uodir );
|
|
|
|
|
FileLookup->Dispose( maps_def );
|
|
|
|
|
Console.PrintSectionBegin();
|
2012-11-03 18:11:04 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::LoadTileData()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Loads tiledata file into memory
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::LoadTileData( const std::string& uodir ) -> void
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
std::string lName = uodir + "tiledata.mul"s;
|
2012-11-03 18:11:04 +00:00
|
|
|
Console << "\t" << lName << "\t";
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
if( !tileInfo.LoadTiles( lName ))
|
|
|
|
|
{
|
2012-11-03 18:11:04 +00:00
|
|
|
Console.PrintFailed();
|
|
|
|
|
Shutdown( FATAL_UOX3_TILEDATA_NOT_FOUND );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
Console.PrintDone();
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::LoadDFNOverrides()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Override flags/properties for tiles based on DFNDATA/MAPS/tiles.dfn
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::LoadDFNOverrides() -> void
|
|
|
|
|
{
|
|
|
|
|
std::uint16_t entryNum;
|
|
|
|
|
for( auto &mapScp : FileLookup->ScriptListings[maps_def] )
|
|
|
|
|
{
|
|
|
|
|
if( mapScp == nullptr )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
for( const auto &[entryName, toScan]: mapScp->collection() )
|
|
|
|
|
{
|
|
|
|
|
if( toScan == nullptr )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
entryNum = oldstrutil::value<std::uint16_t>( oldstrutil::extractSection( entryName, " ", 1, 1 ));
|
|
|
|
|
auto titlePart = oldstrutil::upper( oldstrutil::extractSection( entryName, " ", 0, 0 ));
|
|
|
|
|
// have we got an entry starting with TILE ?
|
|
|
|
|
if( titlePart == "TILE" && entryNum )
|
|
|
|
|
{
|
UOX3 0.99.6-RC4
Fixed an issue that prevented onBuyFromVendor() and onBoughtFromVendor() JS Events from triggering when attached to NPC shopkeepers
Fixed an issue with help gump that prevented password management section from working as intended (js/server/misc/helpgump.js)
Fixed an issue where UOX3 would fail to load pre-HS multi.mul files
Added chess board to Misc->Games add menu (dfndata/items/ItemMenu.bulk.dfn)
Fixed an issue with 'move (alias for 'telestuff) command that referenced the wrong variable name (js/commands/targeting/tele.js)
When a player is teleported via the GM 'wholist menu, any pets within range are now also brought along for the ride
Consolidated error-reporting for JS Functions, Object Methods and Object Properties to provide more context (scriptID, filename, line number) when something goes wrong
Added some missing shield IDs (0xA649, 0xA64A, 0xA831, 0xA832) to IsShieldType() function
MAXRANGE item property previously only worked for ranged weapons; now it works for melee weapons too, and potentially allows melee weapons with combat range longer than 1 tile
MAXRANGE item property can now be used to define max combat range for melee weapons
Fixed an issue (non-critical) with .PlaceInPack() JS Method that would cause UOX3 to try adding items marked for deletion to refreshQueue and spam console with errors
Added missing AI scripts to summoned Blade Spirits and Energy Vortexes (dfndata/npc/magicsummon.dfn)
Fixed an issue with weight calculation for hireling backpacks (js/npc/ai/hireling.js)
Fixed an issue with the 'fix command, which would in most cases set character's Z to -1 regardless of location, but now adheres to map elevation instead
Fixed an issue with Pack AI (js/npc/ai/pack_ai.js) that prevented pack members from attacking target correctly (thanks Dragon Slayer)
Fixed an issue with DoesMapBlock JS Function that incorrectly checked for 6 function arguments, when it actually requires 8
Fixed an issue with DoesDynamicBlock JS Function that incorrectly checked for 8 function arguments, when it actually requires 9
Fixed an issue with runebook script (js/item/runebook.js) that prevented players from being able to use recall charges without having spellbook with spell in inventory
Fixed issues with placement of tall items on ground/floor, and with stacking of items in houses
Fixed incorrect alias for woodland armor (dfndata/items/gear/armor/other/armor/wood.dfn - thanks Dragon Slayer)
Fixed a critical issue with script context sometimes changing while executing a script, because of events in other scripts being triggered. Affected scripts can be safeguarded against this by the addition of a dummy callback function anywhere in the script: function _restorecontext_() {}
Fixed an issue with non-animal pets not gaining loyalty when being fed (thanks Dragon Slayer)
Added new JS Object Methods for Chars/Items/Multis to fetch list of custom tags associated with object:
.GetTagMap() // Gets list of persistent custom tags associated with object
.GetTempTagMap() // Gets list of temporary custom tags associated with object
Added new JS commands ('GETTAGMAP and 'GETTEMPTAGMAP) that spits out details of custom tags associated with targeted object (js/commands/custom/misc-cmd.js)
Added new JS command ('USEITEM) that acts as a short-cut for double-clicking on targeted item (js/commands/custom/misc-cmd.js)
Updated 'ADD # and 'ADD ITEM # JS commands to support targeting a container directly and adding the new item inside (js/commands/targeting/add.js)
Updated axe script to only perform lumberjacking skill-check when there's still wood available in a given area, and to play appropriate animations for Gargoyle players (js/item/axe.js)
Updated script for gameboards to make generated pieces newbiefied so they won't appear on ground if board decays (js/item/gameboards.js)
Updated script for stablemasters to avoid relying on global variables (js/npc/ai/stablemaster.js)
Updated names of items crafted with runic hammers to include the material name of the hammers used to craft them (js/skill/craft/crafting_complete.js)
Fixed a small issue with Detect Hidden skill that would return the wrong message if players found anyone hiding nearby (js/skill/detecthidden.js)
Fixed an issue that prevented tile overrides in dfndata/maps/tiles.dfn from loading properly
Added entries for a couple of walls with missing no-shoot flags to tile overrides in dfndata/maps/tiles.dfn
Updated JS Method .SoundEffect() to support optional third argument (creatureSoundNum) to play creature-defined sounds from dfndata/creatures/creatures.dfn. New syntax:
.SoundEffect( soundID, allHear[, creatureSoundNum] ) // 0=SOUND_STARTATTACK, 1=SOUND_IDLE, 2=SOUND_ATTACK, 3=SOUND_DEFEND, 4=SOUND_DIE
Added new Character JS Methods:
.SetRandomName( nameListID ) // apply a random name from specified namelist to character
.FindItemSection( sectionID ) // find item in player's backpack with specified sectionID
Added new Socket JS Method:
.OpenContainer() // Opens specified container for socket
2023-05-30 01:47:26 +08:00
|
|
|
if(( entryNum == INVALIDID ) || ( entryNum > tileInfo.SizeArt() ))
|
2022-10-24 18:39:33 +08:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
auto tile = &tileInfo.ArtInfo( entryNum );
|
|
|
|
|
if( tile )
|
|
|
|
|
{
|
|
|
|
|
for( const auto &sec : toScan->collection() )
|
|
|
|
|
{
|
|
|
|
|
auto UTag = oldstrutil::upper( sec->tag );
|
|
|
|
|
auto data = oldstrutil::trim( oldstrutil::removeTrailing( sec->data, "//" ));
|
|
|
|
|
// CTile properties
|
|
|
|
|
if( UTag == "WEIGHT" )
|
|
|
|
|
{
|
|
|
|
|
tile->Weight( static_cast<UI08>( std::stoul( data, nullptr, 0 )));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "HEIGHT" )
|
|
|
|
|
{
|
|
|
|
|
tile->Height( static_cast<SI08>( std::stoi( data, nullptr, 0 )));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "LAYER" )
|
|
|
|
|
{
|
|
|
|
|
tile->Layer( static_cast<SI08>( std::stoi( data, nullptr, 0 )));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "HUE" )
|
|
|
|
|
{
|
|
|
|
|
tile->Hue( static_cast<UI08>( std::stoul( data, nullptr, 0 )));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "QUANTITY" )
|
|
|
|
|
{
|
|
|
|
|
tile->Quantity( static_cast<UI08>( std::stoul( data, nullptr, 0 )));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "ANIMATION" )
|
|
|
|
|
{
|
|
|
|
|
tile->Animation( static_cast<UI16>( std::stoul( data, nullptr, 0 )));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "NAME" )
|
|
|
|
|
{
|
|
|
|
|
tile->Name( data );
|
|
|
|
|
}
|
|
|
|
|
// BaseTile Flag 1
|
|
|
|
|
else if( UTag == "ATFLOORLEVEL" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_FLOORLEVEL, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "HOLDABLE" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_HOLDABLE, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "SIGNGUILDBANNER" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_TRANSPARENT, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "WEBDIRTBLOOD" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_TRANSLUCENT, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "WALLVERTTILE" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_WALL, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "DAMAGING" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_DAMAGING, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "BLOCKING" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_BLOCKING, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "LIQUIDWET" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_WET, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// BaseTile Flag 2
|
|
|
|
|
else if( UTag == "UNKNOWNFLAG1" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_UNKNOWN1, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "STANDABLE" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_SURFACE, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "CLIMBABLE" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_CLIMBABLE, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "STACKABLE" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_STACKABLE, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "WINDOWARCHDOOR" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_WINDOW, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "CANNOTSHOOTTHRU" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_NOSHOOT, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "DISPLAYASA" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_DISPLAYA, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "DISPLAYASAN" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_DISPLAYAN, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// BaseTile Flag 3
|
|
|
|
|
else if( UTag == "DESCRIPTIONTILE" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_DESCRIPTION, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "FADEWITHTRANS" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_FOLIAGE, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "PARTIALHUE" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_PARTIALHUE, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "UNKNOWNFLAG2" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_UNKNOWN2, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "MAP" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_MAP, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "CONTAINER" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_CONTAINER, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "EQUIPABLE" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_WEARABLE, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "LIGHTSOURCE" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_LIGHT, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
// BaseTile Flag 4
|
|
|
|
|
else if( UTag == "ANIMATED" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_ANIMATED, (std::stoi(data, nullptr, 0) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "NODIAGONAL" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_NODIAGONAL, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "UNKNOWNFLAG3" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_UNKNOWN3, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "WHOLEBODYITEM" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_ARMOR, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "WALLROOFWEAP" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_ROOF, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "DOOR" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_DOOR, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "CLIMBABLEBIT1" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_STAIRBACK, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
else if( UTag == "CLIMBABLEBIT2" )
|
|
|
|
|
{
|
|
|
|
|
tile->SetFlag( TF_STAIRRIGHT, ( std::stoi( data, nullptr, 0 ) != 0 ));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if( titlePart == "LAND" && entryNum )
|
|
|
|
|
{ // let's not deal with this just yet
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-11-03 18:11:04 +00:00
|
|
|
}
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::LoadMapAndStatics()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Loads map and statics files into memory
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::LoadMapAndStatics( const std::map<int, MapDfnData_st> &info ) -> void
|
|
|
|
|
{
|
|
|
|
|
for( const auto &[mapNum, dfndata]:info )
|
|
|
|
|
{
|
|
|
|
|
uoWorlds.insert_or_assign( mapNum, UltimaMap( mapNum, dfndata.width, dfndata.height, &tileInfo ));
|
|
|
|
|
auto rValue = false;
|
|
|
|
|
|
UOX3 0.99.6-RC6
Removed arbitrary and hidden restrictions on refreshing list of online players shown with 'wholist command
Fixed an issue where player ghosts that get teleported would not see themselves get updated to new location
Fixed a server crash from clients disconnecting while running server in debug mode
Improved how container updates are sent to players; now only sends to clients that have actually opened the container, and who are still within range
Added more information about UO data files being loaded during server startup
Enhanced the GM 'add menu to allow clicking directly on images of items/npcs to add them, and adjusted size of menus to accommodate this
Fixed an issue with fleeing NPCs that could cause them to attempt to flee across time and space, regardless of distance to target/attacker in combat
Added NPC AI that runs away from players if they get too close (even outside combat). Applied to hind, rabbits, squirrels, ferrets and various birds by default:
AI_ANIMAL_SCARED (aitype 12)
Fixed issues with NPCs fleeing forever, or getting stuck in flee/don't flee loop, by introducing max fleeing distance (50 tiles) and cooldown (30 sec) on fleeing
Updated onNameRequest JS Event to include third parameter with origin of name request, so script responses can be tailored appropriately:
onNameRequest( myObj, requestedBy, requestSource )
Potential values for requestSource:
0 - Speech/System Messages
1 - Guild Menus
2 - Stat Window (self)
3 - Stat Window (other)
4 - Tooltip
5 - Paperdoll Journal
6 - Paperdoll
7 - Single Click / All-Names
8 - System
9 - Secure Trade Window
Added Adaptive Performance System (APS) that dynamically adjust how often NPC AI/movement is checked based on overall shard performance. If performance drops below defined threshold, UOX3 gradually slows down checks for NPC AI/movement to prioritize player movement/speech/command responsiveness. If performance climbs back up above threshold, slowdowns are gradually removed. The following UOX.INI options have been added under [system] category to support this system:
APSPERFTHRESHOLD=50 // Performance threshold (measured in simulation cycles/sec) below which the APS kicks in
APSINTERVAL=100 // How often (in milliseconds) the APS checks performance and makes adjustments (if needed) to balance out shard performance
APSDELAYSTEP=50 // How much the delay timer is modified by (in milliseconds) each time APS makes adjustments
APSDELAYMAXCAP=2000 // Max amount of of delay APS can introduce for NPC AI/movement handling when attempting to restore shard performance
Added new JS Methods for Region objects:
.GetOrePrefs( oreType ) // Get ore preference data for ore type found in town region. Returned as an array containing the following data:
orePrefData -> [
oreName, // name of ore
color, // color of ore
minskill, // min skill to mine ore
ingotName, // name of ingot created from ore
makemenu, // makemenu entry for crafting something from ingot
oreChance, // default global chance of finding this ore type
scriptID // script attached to mined ore
],
orePrefChance // Chance of finding this ore type in given town region
.GetOreChance() // Get base chance of finding any ore in town region
Moved Mining skill plus gravedigging feature from hard code to scripts (js/skill/mining.js) to make it easier to maintain and/or customize, and removed hard coded variants
Gravedigging now relies on the ore resource system behind the scenes to restrict how often graves in a given area can be dug up
Fixed some incorrect references to .worldNumber Character property in misc scripts (should be .worldnumber)
Made some "hard-scripted" system messages in misc scripts use dictionary system instead
Added spawn region for banker NPCs in Serpent's Hold (dfndata/spawn/felucca/spawn_town_serpents_hold.dfn, dfndata/spawn/trammel/spawn_town_serpents_hold.dfn)
Fixed region definition of Ocllo to actually cover the entire town (dfndata/regions/regions.dfn)
Added numerous additional locations accessible with 'goplace # command, for key locations in Ilshenar, Malas, Tokuno Islands and Ter Mur (dfndata/location/location.dfn)
Revised travel-menu portion of GM menu (shortcut: 'travel) to include more travel options based on new locations (dfndata/items/travelmenu.dfn and travelmenu.bulk.dfn)
Fixed an issue where NPCs could attempt to attack targets in other worlds/instances
Added new JS Event that triggers for characters who are about to deal damage in combat. Complimentary to onDamage, which triggers for chars receiving damage:
onDamageDeal( dmgDealer, dmgReceiver, damageValue, damageType )
Added new JS Event that can trigger in global script upon creation of new player chars. Note that this will trigger in place of onCreateDFN event for player characters:
onCreatePlayer( pChar )
Added new JS Event that triggers for characters selecting a target with a spell. Complimentary to onSpellTarget, which triggers for targets selected with a spell:
onSpellTargetSelect( caster, target, spellNum )
Updated onCombatStart and onCombatEnd JS Events to also trigger for the other party in combat
Updated onPickup JS Event to include a third parameter - the potential container item was picked up from. Event now also triggers event in scripts attached to said containers:
onPickup( iPickedUp, pChar, iCont )
Added tracking of total playtime per individual character, and per account across all characters, and exposed these properties to JS engine:
.totalPlayTime // Account property, total playtime across all chars
.playTime // Character property, total playtime on given character only
Added new player-accessible command ('playtime) to spit out the playtime of current character/account as a whole (js/commands/playtime.js)
Implemented first version of Young Player System:
Replaced the UNUSED9 account flag with YOUNG, to be used by Young/New Player System
Added new JS Account property that gets/sets whether player account is considered Young:
.isYoung
Added new Char timers:
TIMER_YOUNGHEAL // Restricts how often Young players are healed by NPC healers
TIMER_YOUNGMESSAGE // Restricts how often Young players are warned about dangerous looking monsters in overworld
Updated GM commands 'get and 'set to get/set .isYoung property of player's account (js/commands/targeting/get.js and set.js)
Added new UOX.INI setting to enable/disable Young Player System (enabled by default):
YOUNGPLAYERSYSTEM=1
If Young Player System is enabled, all newly created player accounts are automatically marked with Young flag
Added new script to handle various restrictions and functions related to Young characters (js/player/young_player.js):
Young characters will have [Young] displayed over their head
Young characters will have their Young status checked and verified on every login + every stat/skill gain, to revoke the Young status if any of the following is true:
Account has a total playtime of more than 40 hours
Any character has more than 350 total (base) skill points
Any character has more than 70 skill points in a single skill
Any character has more than 150 total stat points
Any character has more than 80 stat points in a single stat
Young characters can renounce their Young status manually by saying the words "I renounce my young player status"
Young characters get two additional items upon creation:
a new player ticket (can be combined with any other players new player ticket for both players to get a reward)
a sextant (shows Young players directions to nearest moongate/bank regardless of where they are, as long as outdoors)
Young characters cannot target other player characters with hostile spells or skills
Young characters cannot be the target of other player characters' hostile spells or skills
Young characters can only cast beneficial spells upon themselves or other Young characters
Young characters can only be the target of beneficial spells from other Young players
Young players (and their pets/followers) cannot attack or harm any other players (or their pets/followers), nor themselves be attacked or harmed by any other players (or their pets/followers), whether from combat, spells, skills or items
Young players don't lose any of their items on death, and are teleported to the nearest healer upon death with all their items intact
Young players receive a warning upon entering dungeons that monsters there will be hostile
Updated global script (js/server/global.js) to:
Check/Verify Young status of players upon login
Attach young player script on login/creation for players on Young accounts
Give specific items to Young players upon creation
Added new script (js/item/corpse.js) that is assigned to all freshly created corpses. This script handles restrictions related to Young players interactions with corpses, and the interactions of other players with corpses of Young players
Updated JS Method .Carve() to return true/false depending on whether carving a corpse was successful
Updated Healer AI in code to heal nearby injured Young players
Updated Evil AI and Evil Caster AI in code to avoid selecting Young players as targets in combat outside of dungeons
Added a new section to UOX.INI - [young player starting locations] - that can be used to define starting locations for Young players. If only one such location is provided, all players start there. Otherwise, it matches the same starting location setup as the regular one - with one entry per town in Britannia.
Restricted transferring and/or friending of pets (code) and hirelings (hirelings.js) between Young and non-Young players
Restricted Young players from recalling or gating to Felucca facet
Young players can instantly logout from anywhere, at any time
2023-07-01 20:02:40 +08:00
|
|
|
// Load Terrain/Map data from UOP > MUL
|
2022-10-24 18:39:33 +08:00
|
|
|
if( std::filesystem::exists( dfndata.mapUop ))
|
|
|
|
|
{
|
UOX3 0.99.6-RC6
Removed arbitrary and hidden restrictions on refreshing list of online players shown with 'wholist command
Fixed an issue where player ghosts that get teleported would not see themselves get updated to new location
Fixed a server crash from clients disconnecting while running server in debug mode
Improved how container updates are sent to players; now only sends to clients that have actually opened the container, and who are still within range
Added more information about UO data files being loaded during server startup
Enhanced the GM 'add menu to allow clicking directly on images of items/npcs to add them, and adjusted size of menus to accommodate this
Fixed an issue with fleeing NPCs that could cause them to attempt to flee across time and space, regardless of distance to target/attacker in combat
Added NPC AI that runs away from players if they get too close (even outside combat). Applied to hind, rabbits, squirrels, ferrets and various birds by default:
AI_ANIMAL_SCARED (aitype 12)
Fixed issues with NPCs fleeing forever, or getting stuck in flee/don't flee loop, by introducing max fleeing distance (50 tiles) and cooldown (30 sec) on fleeing
Updated onNameRequest JS Event to include third parameter with origin of name request, so script responses can be tailored appropriately:
onNameRequest( myObj, requestedBy, requestSource )
Potential values for requestSource:
0 - Speech/System Messages
1 - Guild Menus
2 - Stat Window (self)
3 - Stat Window (other)
4 - Tooltip
5 - Paperdoll Journal
6 - Paperdoll
7 - Single Click / All-Names
8 - System
9 - Secure Trade Window
Added Adaptive Performance System (APS) that dynamically adjust how often NPC AI/movement is checked based on overall shard performance. If performance drops below defined threshold, UOX3 gradually slows down checks for NPC AI/movement to prioritize player movement/speech/command responsiveness. If performance climbs back up above threshold, slowdowns are gradually removed. The following UOX.INI options have been added under [system] category to support this system:
APSPERFTHRESHOLD=50 // Performance threshold (measured in simulation cycles/sec) below which the APS kicks in
APSINTERVAL=100 // How often (in milliseconds) the APS checks performance and makes adjustments (if needed) to balance out shard performance
APSDELAYSTEP=50 // How much the delay timer is modified by (in milliseconds) each time APS makes adjustments
APSDELAYMAXCAP=2000 // Max amount of of delay APS can introduce for NPC AI/movement handling when attempting to restore shard performance
Added new JS Methods for Region objects:
.GetOrePrefs( oreType ) // Get ore preference data for ore type found in town region. Returned as an array containing the following data:
orePrefData -> [
oreName, // name of ore
color, // color of ore
minskill, // min skill to mine ore
ingotName, // name of ingot created from ore
makemenu, // makemenu entry for crafting something from ingot
oreChance, // default global chance of finding this ore type
scriptID // script attached to mined ore
],
orePrefChance // Chance of finding this ore type in given town region
.GetOreChance() // Get base chance of finding any ore in town region
Moved Mining skill plus gravedigging feature from hard code to scripts (js/skill/mining.js) to make it easier to maintain and/or customize, and removed hard coded variants
Gravedigging now relies on the ore resource system behind the scenes to restrict how often graves in a given area can be dug up
Fixed some incorrect references to .worldNumber Character property in misc scripts (should be .worldnumber)
Made some "hard-scripted" system messages in misc scripts use dictionary system instead
Added spawn region for banker NPCs in Serpent's Hold (dfndata/spawn/felucca/spawn_town_serpents_hold.dfn, dfndata/spawn/trammel/spawn_town_serpents_hold.dfn)
Fixed region definition of Ocllo to actually cover the entire town (dfndata/regions/regions.dfn)
Added numerous additional locations accessible with 'goplace # command, for key locations in Ilshenar, Malas, Tokuno Islands and Ter Mur (dfndata/location/location.dfn)
Revised travel-menu portion of GM menu (shortcut: 'travel) to include more travel options based on new locations (dfndata/items/travelmenu.dfn and travelmenu.bulk.dfn)
Fixed an issue where NPCs could attempt to attack targets in other worlds/instances
Added new JS Event that triggers for characters who are about to deal damage in combat. Complimentary to onDamage, which triggers for chars receiving damage:
onDamageDeal( dmgDealer, dmgReceiver, damageValue, damageType )
Added new JS Event that can trigger in global script upon creation of new player chars. Note that this will trigger in place of onCreateDFN event for player characters:
onCreatePlayer( pChar )
Added new JS Event that triggers for characters selecting a target with a spell. Complimentary to onSpellTarget, which triggers for targets selected with a spell:
onSpellTargetSelect( caster, target, spellNum )
Updated onCombatStart and onCombatEnd JS Events to also trigger for the other party in combat
Updated onPickup JS Event to include a third parameter - the potential container item was picked up from. Event now also triggers event in scripts attached to said containers:
onPickup( iPickedUp, pChar, iCont )
Added tracking of total playtime per individual character, and per account across all characters, and exposed these properties to JS engine:
.totalPlayTime // Account property, total playtime across all chars
.playTime // Character property, total playtime on given character only
Added new player-accessible command ('playtime) to spit out the playtime of current character/account as a whole (js/commands/playtime.js)
Implemented first version of Young Player System:
Replaced the UNUSED9 account flag with YOUNG, to be used by Young/New Player System
Added new JS Account property that gets/sets whether player account is considered Young:
.isYoung
Added new Char timers:
TIMER_YOUNGHEAL // Restricts how often Young players are healed by NPC healers
TIMER_YOUNGMESSAGE // Restricts how often Young players are warned about dangerous looking monsters in overworld
Updated GM commands 'get and 'set to get/set .isYoung property of player's account (js/commands/targeting/get.js and set.js)
Added new UOX.INI setting to enable/disable Young Player System (enabled by default):
YOUNGPLAYERSYSTEM=1
If Young Player System is enabled, all newly created player accounts are automatically marked with Young flag
Added new script to handle various restrictions and functions related to Young characters (js/player/young_player.js):
Young characters will have [Young] displayed over their head
Young characters will have their Young status checked and verified on every login + every stat/skill gain, to revoke the Young status if any of the following is true:
Account has a total playtime of more than 40 hours
Any character has more than 350 total (base) skill points
Any character has more than 70 skill points in a single skill
Any character has more than 150 total stat points
Any character has more than 80 stat points in a single stat
Young characters can renounce their Young status manually by saying the words "I renounce my young player status"
Young characters get two additional items upon creation:
a new player ticket (can be combined with any other players new player ticket for both players to get a reward)
a sextant (shows Young players directions to nearest moongate/bank regardless of where they are, as long as outdoors)
Young characters cannot target other player characters with hostile spells or skills
Young characters cannot be the target of other player characters' hostile spells or skills
Young characters can only cast beneficial spells upon themselves or other Young characters
Young characters can only be the target of beneficial spells from other Young players
Young players (and their pets/followers) cannot attack or harm any other players (or their pets/followers), nor themselves be attacked or harmed by any other players (or their pets/followers), whether from combat, spells, skills or items
Young players don't lose any of their items on death, and are teleported to the nearest healer upon death with all their items intact
Young players receive a warning upon entering dungeons that monsters there will be hostile
Updated global script (js/server/global.js) to:
Check/Verify Young status of players upon login
Attach young player script on login/creation for players on Young accounts
Give specific items to Young players upon creation
Added new script (js/item/corpse.js) that is assigned to all freshly created corpses. This script handles restrictions related to Young players interactions with corpses, and the interactions of other players with corpses of Young players
Updated JS Method .Carve() to return true/false depending on whether carving a corpse was successful
Updated Healer AI in code to heal nearby injured Young players
Updated Evil AI and Evil Caster AI in code to avoid selecting Young players as targets in combat outside of dungeons
Added a new section to UOX.INI - [young player starting locations] - that can be used to define starting locations for Young players. If only one such location is provided, all players start there. Otherwise, it matches the same starting location setup as the regular one - with one entry per town in Britannia.
Restricted transferring and/or friending of pets (code) and hirelings (hirelings.js) between Young and non-Young players
Restricted Young players from recalling or gating to Felucca facet
Young players can instantly logout from anywhere, at any time
2023-07-01 20:02:40 +08:00
|
|
|
//Console << "\t" << dfndata.mapUop.string() << "(/" << dfndata.mapUop.filename().string() << ")\t\t";
|
|
|
|
|
Console << "\t" << dfndata.mapUop.string() << "\t\t";
|
2022-10-24 18:39:33 +08:00
|
|
|
rValue = uoWorlds[mapNum].LoadUOPTerrainFile( dfndata.mapUop.string() );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
UOX3 0.99.6-RC6
Removed arbitrary and hidden restrictions on refreshing list of online players shown with 'wholist command
Fixed an issue where player ghosts that get teleported would not see themselves get updated to new location
Fixed a server crash from clients disconnecting while running server in debug mode
Improved how container updates are sent to players; now only sends to clients that have actually opened the container, and who are still within range
Added more information about UO data files being loaded during server startup
Enhanced the GM 'add menu to allow clicking directly on images of items/npcs to add them, and adjusted size of menus to accommodate this
Fixed an issue with fleeing NPCs that could cause them to attempt to flee across time and space, regardless of distance to target/attacker in combat
Added NPC AI that runs away from players if they get too close (even outside combat). Applied to hind, rabbits, squirrels, ferrets and various birds by default:
AI_ANIMAL_SCARED (aitype 12)
Fixed issues with NPCs fleeing forever, or getting stuck in flee/don't flee loop, by introducing max fleeing distance (50 tiles) and cooldown (30 sec) on fleeing
Updated onNameRequest JS Event to include third parameter with origin of name request, so script responses can be tailored appropriately:
onNameRequest( myObj, requestedBy, requestSource )
Potential values for requestSource:
0 - Speech/System Messages
1 - Guild Menus
2 - Stat Window (self)
3 - Stat Window (other)
4 - Tooltip
5 - Paperdoll Journal
6 - Paperdoll
7 - Single Click / All-Names
8 - System
9 - Secure Trade Window
Added Adaptive Performance System (APS) that dynamically adjust how often NPC AI/movement is checked based on overall shard performance. If performance drops below defined threshold, UOX3 gradually slows down checks for NPC AI/movement to prioritize player movement/speech/command responsiveness. If performance climbs back up above threshold, slowdowns are gradually removed. The following UOX.INI options have been added under [system] category to support this system:
APSPERFTHRESHOLD=50 // Performance threshold (measured in simulation cycles/sec) below which the APS kicks in
APSINTERVAL=100 // How often (in milliseconds) the APS checks performance and makes adjustments (if needed) to balance out shard performance
APSDELAYSTEP=50 // How much the delay timer is modified by (in milliseconds) each time APS makes adjustments
APSDELAYMAXCAP=2000 // Max amount of of delay APS can introduce for NPC AI/movement handling when attempting to restore shard performance
Added new JS Methods for Region objects:
.GetOrePrefs( oreType ) // Get ore preference data for ore type found in town region. Returned as an array containing the following data:
orePrefData -> [
oreName, // name of ore
color, // color of ore
minskill, // min skill to mine ore
ingotName, // name of ingot created from ore
makemenu, // makemenu entry for crafting something from ingot
oreChance, // default global chance of finding this ore type
scriptID // script attached to mined ore
],
orePrefChance // Chance of finding this ore type in given town region
.GetOreChance() // Get base chance of finding any ore in town region
Moved Mining skill plus gravedigging feature from hard code to scripts (js/skill/mining.js) to make it easier to maintain and/or customize, and removed hard coded variants
Gravedigging now relies on the ore resource system behind the scenes to restrict how often graves in a given area can be dug up
Fixed some incorrect references to .worldNumber Character property in misc scripts (should be .worldnumber)
Made some "hard-scripted" system messages in misc scripts use dictionary system instead
Added spawn region for banker NPCs in Serpent's Hold (dfndata/spawn/felucca/spawn_town_serpents_hold.dfn, dfndata/spawn/trammel/spawn_town_serpents_hold.dfn)
Fixed region definition of Ocllo to actually cover the entire town (dfndata/regions/regions.dfn)
Added numerous additional locations accessible with 'goplace # command, for key locations in Ilshenar, Malas, Tokuno Islands and Ter Mur (dfndata/location/location.dfn)
Revised travel-menu portion of GM menu (shortcut: 'travel) to include more travel options based on new locations (dfndata/items/travelmenu.dfn and travelmenu.bulk.dfn)
Fixed an issue where NPCs could attempt to attack targets in other worlds/instances
Added new JS Event that triggers for characters who are about to deal damage in combat. Complimentary to onDamage, which triggers for chars receiving damage:
onDamageDeal( dmgDealer, dmgReceiver, damageValue, damageType )
Added new JS Event that can trigger in global script upon creation of new player chars. Note that this will trigger in place of onCreateDFN event for player characters:
onCreatePlayer( pChar )
Added new JS Event that triggers for characters selecting a target with a spell. Complimentary to onSpellTarget, which triggers for targets selected with a spell:
onSpellTargetSelect( caster, target, spellNum )
Updated onCombatStart and onCombatEnd JS Events to also trigger for the other party in combat
Updated onPickup JS Event to include a third parameter - the potential container item was picked up from. Event now also triggers event in scripts attached to said containers:
onPickup( iPickedUp, pChar, iCont )
Added tracking of total playtime per individual character, and per account across all characters, and exposed these properties to JS engine:
.totalPlayTime // Account property, total playtime across all chars
.playTime // Character property, total playtime on given character only
Added new player-accessible command ('playtime) to spit out the playtime of current character/account as a whole (js/commands/playtime.js)
Implemented first version of Young Player System:
Replaced the UNUSED9 account flag with YOUNG, to be used by Young/New Player System
Added new JS Account property that gets/sets whether player account is considered Young:
.isYoung
Added new Char timers:
TIMER_YOUNGHEAL // Restricts how often Young players are healed by NPC healers
TIMER_YOUNGMESSAGE // Restricts how often Young players are warned about dangerous looking monsters in overworld
Updated GM commands 'get and 'set to get/set .isYoung property of player's account (js/commands/targeting/get.js and set.js)
Added new UOX.INI setting to enable/disable Young Player System (enabled by default):
YOUNGPLAYERSYSTEM=1
If Young Player System is enabled, all newly created player accounts are automatically marked with Young flag
Added new script to handle various restrictions and functions related to Young characters (js/player/young_player.js):
Young characters will have [Young] displayed over their head
Young characters will have their Young status checked and verified on every login + every stat/skill gain, to revoke the Young status if any of the following is true:
Account has a total playtime of more than 40 hours
Any character has more than 350 total (base) skill points
Any character has more than 70 skill points in a single skill
Any character has more than 150 total stat points
Any character has more than 80 stat points in a single stat
Young characters can renounce their Young status manually by saying the words "I renounce my young player status"
Young characters get two additional items upon creation:
a new player ticket (can be combined with any other players new player ticket for both players to get a reward)
a sextant (shows Young players directions to nearest moongate/bank regardless of where they are, as long as outdoors)
Young characters cannot target other player characters with hostile spells or skills
Young characters cannot be the target of other player characters' hostile spells or skills
Young characters can only cast beneficial spells upon themselves or other Young characters
Young characters can only be the target of beneficial spells from other Young players
Young players (and their pets/followers) cannot attack or harm any other players (or their pets/followers), nor themselves be attacked or harmed by any other players (or their pets/followers), whether from combat, spells, skills or items
Young players don't lose any of their items on death, and are teleported to the nearest healer upon death with all their items intact
Young players receive a warning upon entering dungeons that monsters there will be hostile
Updated global script (js/server/global.js) to:
Check/Verify Young status of players upon login
Attach young player script on login/creation for players on Young accounts
Give specific items to Young players upon creation
Added new script (js/item/corpse.js) that is assigned to all freshly created corpses. This script handles restrictions related to Young players interactions with corpses, and the interactions of other players with corpses of Young players
Updated JS Method .Carve() to return true/false depending on whether carving a corpse was successful
Updated Healer AI in code to heal nearby injured Young players
Updated Evil AI and Evil Caster AI in code to avoid selecting Young players as targets in combat outside of dungeons
Added a new section to UOX.INI - [young player starting locations] - that can be used to define starting locations for Young players. If only one such location is provided, all players start there. Otherwise, it matches the same starting location setup as the regular one - with one entry per town in Britannia.
Restricted transferring and/or friending of pets (code) and hirelings (hirelings.js) between Young and non-Young players
Restricted Young players from recalling or gating to Felucca facet
Young players can instantly logout from anywhere, at any time
2023-07-01 20:02:40 +08:00
|
|
|
//Console << "\t" << dfndata.mapFile.string() << "(/" << dfndata.mapFile.filename().string() << ")\t\t";
|
|
|
|
|
Console << "\t" << dfndata.mapFile.string() << "\t\t";
|
2022-10-24 18:39:33 +08:00
|
|
|
rValue = uoWorlds[mapNum].LoadMulTerrainFile( dfndata.mapFile.string() );
|
|
|
|
|
if( rValue )
|
|
|
|
|
{
|
|
|
|
|
uoWorlds[mapNum].ApplyTerrainDiff( dfndata.mapDiffl.string(), dfndata.mapDiff.string() );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
UOX3 0.99.6-RC6
Removed arbitrary and hidden restrictions on refreshing list of online players shown with 'wholist command
Fixed an issue where player ghosts that get teleported would not see themselves get updated to new location
Fixed a server crash from clients disconnecting while running server in debug mode
Improved how container updates are sent to players; now only sends to clients that have actually opened the container, and who are still within range
Added more information about UO data files being loaded during server startup
Enhanced the GM 'add menu to allow clicking directly on images of items/npcs to add them, and adjusted size of menus to accommodate this
Fixed an issue with fleeing NPCs that could cause them to attempt to flee across time and space, regardless of distance to target/attacker in combat
Added NPC AI that runs away from players if they get too close (even outside combat). Applied to hind, rabbits, squirrels, ferrets and various birds by default:
AI_ANIMAL_SCARED (aitype 12)
Fixed issues with NPCs fleeing forever, or getting stuck in flee/don't flee loop, by introducing max fleeing distance (50 tiles) and cooldown (30 sec) on fleeing
Updated onNameRequest JS Event to include third parameter with origin of name request, so script responses can be tailored appropriately:
onNameRequest( myObj, requestedBy, requestSource )
Potential values for requestSource:
0 - Speech/System Messages
1 - Guild Menus
2 - Stat Window (self)
3 - Stat Window (other)
4 - Tooltip
5 - Paperdoll Journal
6 - Paperdoll
7 - Single Click / All-Names
8 - System
9 - Secure Trade Window
Added Adaptive Performance System (APS) that dynamically adjust how often NPC AI/movement is checked based on overall shard performance. If performance drops below defined threshold, UOX3 gradually slows down checks for NPC AI/movement to prioritize player movement/speech/command responsiveness. If performance climbs back up above threshold, slowdowns are gradually removed. The following UOX.INI options have been added under [system] category to support this system:
APSPERFTHRESHOLD=50 // Performance threshold (measured in simulation cycles/sec) below which the APS kicks in
APSINTERVAL=100 // How often (in milliseconds) the APS checks performance and makes adjustments (if needed) to balance out shard performance
APSDELAYSTEP=50 // How much the delay timer is modified by (in milliseconds) each time APS makes adjustments
APSDELAYMAXCAP=2000 // Max amount of of delay APS can introduce for NPC AI/movement handling when attempting to restore shard performance
Added new JS Methods for Region objects:
.GetOrePrefs( oreType ) // Get ore preference data for ore type found in town region. Returned as an array containing the following data:
orePrefData -> [
oreName, // name of ore
color, // color of ore
minskill, // min skill to mine ore
ingotName, // name of ingot created from ore
makemenu, // makemenu entry for crafting something from ingot
oreChance, // default global chance of finding this ore type
scriptID // script attached to mined ore
],
orePrefChance // Chance of finding this ore type in given town region
.GetOreChance() // Get base chance of finding any ore in town region
Moved Mining skill plus gravedigging feature from hard code to scripts (js/skill/mining.js) to make it easier to maintain and/or customize, and removed hard coded variants
Gravedigging now relies on the ore resource system behind the scenes to restrict how often graves in a given area can be dug up
Fixed some incorrect references to .worldNumber Character property in misc scripts (should be .worldnumber)
Made some "hard-scripted" system messages in misc scripts use dictionary system instead
Added spawn region for banker NPCs in Serpent's Hold (dfndata/spawn/felucca/spawn_town_serpents_hold.dfn, dfndata/spawn/trammel/spawn_town_serpents_hold.dfn)
Fixed region definition of Ocllo to actually cover the entire town (dfndata/regions/regions.dfn)
Added numerous additional locations accessible with 'goplace # command, for key locations in Ilshenar, Malas, Tokuno Islands and Ter Mur (dfndata/location/location.dfn)
Revised travel-menu portion of GM menu (shortcut: 'travel) to include more travel options based on new locations (dfndata/items/travelmenu.dfn and travelmenu.bulk.dfn)
Fixed an issue where NPCs could attempt to attack targets in other worlds/instances
Added new JS Event that triggers for characters who are about to deal damage in combat. Complimentary to onDamage, which triggers for chars receiving damage:
onDamageDeal( dmgDealer, dmgReceiver, damageValue, damageType )
Added new JS Event that can trigger in global script upon creation of new player chars. Note that this will trigger in place of onCreateDFN event for player characters:
onCreatePlayer( pChar )
Added new JS Event that triggers for characters selecting a target with a spell. Complimentary to onSpellTarget, which triggers for targets selected with a spell:
onSpellTargetSelect( caster, target, spellNum )
Updated onCombatStart and onCombatEnd JS Events to also trigger for the other party in combat
Updated onPickup JS Event to include a third parameter - the potential container item was picked up from. Event now also triggers event in scripts attached to said containers:
onPickup( iPickedUp, pChar, iCont )
Added tracking of total playtime per individual character, and per account across all characters, and exposed these properties to JS engine:
.totalPlayTime // Account property, total playtime across all chars
.playTime // Character property, total playtime on given character only
Added new player-accessible command ('playtime) to spit out the playtime of current character/account as a whole (js/commands/playtime.js)
Implemented first version of Young Player System:
Replaced the UNUSED9 account flag with YOUNG, to be used by Young/New Player System
Added new JS Account property that gets/sets whether player account is considered Young:
.isYoung
Added new Char timers:
TIMER_YOUNGHEAL // Restricts how often Young players are healed by NPC healers
TIMER_YOUNGMESSAGE // Restricts how often Young players are warned about dangerous looking monsters in overworld
Updated GM commands 'get and 'set to get/set .isYoung property of player's account (js/commands/targeting/get.js and set.js)
Added new UOX.INI setting to enable/disable Young Player System (enabled by default):
YOUNGPLAYERSYSTEM=1
If Young Player System is enabled, all newly created player accounts are automatically marked with Young flag
Added new script to handle various restrictions and functions related to Young characters (js/player/young_player.js):
Young characters will have [Young] displayed over their head
Young characters will have their Young status checked and verified on every login + every stat/skill gain, to revoke the Young status if any of the following is true:
Account has a total playtime of more than 40 hours
Any character has more than 350 total (base) skill points
Any character has more than 70 skill points in a single skill
Any character has more than 150 total stat points
Any character has more than 80 stat points in a single stat
Young characters can renounce their Young status manually by saying the words "I renounce my young player status"
Young characters get two additional items upon creation:
a new player ticket (can be combined with any other players new player ticket for both players to get a reward)
a sextant (shows Young players directions to nearest moongate/bank regardless of where they are, as long as outdoors)
Young characters cannot target other player characters with hostile spells or skills
Young characters cannot be the target of other player characters' hostile spells or skills
Young characters can only cast beneficial spells upon themselves or other Young characters
Young characters can only be the target of beneficial spells from other Young players
Young players (and their pets/followers) cannot attack or harm any other players (or their pets/followers), nor themselves be attacked or harmed by any other players (or their pets/followers), whether from combat, spells, skills or items
Young players don't lose any of their items on death, and are teleported to the nearest healer upon death with all their items intact
Young players receive a warning upon entering dungeons that monsters there will be hostile
Updated global script (js/server/global.js) to:
Check/Verify Young status of players upon login
Attach young player script on login/creation for players on Young accounts
Give specific items to Young players upon creation
Added new script (js/item/corpse.js) that is assigned to all freshly created corpses. This script handles restrictions related to Young players interactions with corpses, and the interactions of other players with corpses of Young players
Updated JS Method .Carve() to return true/false depending on whether carving a corpse was successful
Updated Healer AI in code to heal nearby injured Young players
Updated Evil AI and Evil Caster AI in code to avoid selecting Young players as targets in combat outside of dungeons
Added a new section to UOX.INI - [young player starting locations] - that can be used to define starting locations for Young players. If only one such location is provided, all players start there. Otherwise, it matches the same starting location setup as the regular one - with one entry per town in Britannia.
Restricted transferring and/or friending of pets (code) and hirelings (hirelings.js) between Young and non-Young players
Restricted Young players from recalling or gating to Felucca facet
Young players can instantly logout from anywhere, at any time
2023-07-01 20:02:40 +08:00
|
|
|
|
|
|
|
|
if( !rValue )
|
|
|
|
|
{
|
|
|
|
|
Console.PrintFailed();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.PrintDone();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Load Art/Statics data
|
2022-10-24 18:39:33 +08:00
|
|
|
if( rValue )
|
|
|
|
|
{
|
UOX3 0.99.6-RC6
Removed arbitrary and hidden restrictions on refreshing list of online players shown with 'wholist command
Fixed an issue where player ghosts that get teleported would not see themselves get updated to new location
Fixed a server crash from clients disconnecting while running server in debug mode
Improved how container updates are sent to players; now only sends to clients that have actually opened the container, and who are still within range
Added more information about UO data files being loaded during server startup
Enhanced the GM 'add menu to allow clicking directly on images of items/npcs to add them, and adjusted size of menus to accommodate this
Fixed an issue with fleeing NPCs that could cause them to attempt to flee across time and space, regardless of distance to target/attacker in combat
Added NPC AI that runs away from players if they get too close (even outside combat). Applied to hind, rabbits, squirrels, ferrets and various birds by default:
AI_ANIMAL_SCARED (aitype 12)
Fixed issues with NPCs fleeing forever, or getting stuck in flee/don't flee loop, by introducing max fleeing distance (50 tiles) and cooldown (30 sec) on fleeing
Updated onNameRequest JS Event to include third parameter with origin of name request, so script responses can be tailored appropriately:
onNameRequest( myObj, requestedBy, requestSource )
Potential values for requestSource:
0 - Speech/System Messages
1 - Guild Menus
2 - Stat Window (self)
3 - Stat Window (other)
4 - Tooltip
5 - Paperdoll Journal
6 - Paperdoll
7 - Single Click / All-Names
8 - System
9 - Secure Trade Window
Added Adaptive Performance System (APS) that dynamically adjust how often NPC AI/movement is checked based on overall shard performance. If performance drops below defined threshold, UOX3 gradually slows down checks for NPC AI/movement to prioritize player movement/speech/command responsiveness. If performance climbs back up above threshold, slowdowns are gradually removed. The following UOX.INI options have been added under [system] category to support this system:
APSPERFTHRESHOLD=50 // Performance threshold (measured in simulation cycles/sec) below which the APS kicks in
APSINTERVAL=100 // How often (in milliseconds) the APS checks performance and makes adjustments (if needed) to balance out shard performance
APSDELAYSTEP=50 // How much the delay timer is modified by (in milliseconds) each time APS makes adjustments
APSDELAYMAXCAP=2000 // Max amount of of delay APS can introduce for NPC AI/movement handling when attempting to restore shard performance
Added new JS Methods for Region objects:
.GetOrePrefs( oreType ) // Get ore preference data for ore type found in town region. Returned as an array containing the following data:
orePrefData -> [
oreName, // name of ore
color, // color of ore
minskill, // min skill to mine ore
ingotName, // name of ingot created from ore
makemenu, // makemenu entry for crafting something from ingot
oreChance, // default global chance of finding this ore type
scriptID // script attached to mined ore
],
orePrefChance // Chance of finding this ore type in given town region
.GetOreChance() // Get base chance of finding any ore in town region
Moved Mining skill plus gravedigging feature from hard code to scripts (js/skill/mining.js) to make it easier to maintain and/or customize, and removed hard coded variants
Gravedigging now relies on the ore resource system behind the scenes to restrict how often graves in a given area can be dug up
Fixed some incorrect references to .worldNumber Character property in misc scripts (should be .worldnumber)
Made some "hard-scripted" system messages in misc scripts use dictionary system instead
Added spawn region for banker NPCs in Serpent's Hold (dfndata/spawn/felucca/spawn_town_serpents_hold.dfn, dfndata/spawn/trammel/spawn_town_serpents_hold.dfn)
Fixed region definition of Ocllo to actually cover the entire town (dfndata/regions/regions.dfn)
Added numerous additional locations accessible with 'goplace # command, for key locations in Ilshenar, Malas, Tokuno Islands and Ter Mur (dfndata/location/location.dfn)
Revised travel-menu portion of GM menu (shortcut: 'travel) to include more travel options based on new locations (dfndata/items/travelmenu.dfn and travelmenu.bulk.dfn)
Fixed an issue where NPCs could attempt to attack targets in other worlds/instances
Added new JS Event that triggers for characters who are about to deal damage in combat. Complimentary to onDamage, which triggers for chars receiving damage:
onDamageDeal( dmgDealer, dmgReceiver, damageValue, damageType )
Added new JS Event that can trigger in global script upon creation of new player chars. Note that this will trigger in place of onCreateDFN event for player characters:
onCreatePlayer( pChar )
Added new JS Event that triggers for characters selecting a target with a spell. Complimentary to onSpellTarget, which triggers for targets selected with a spell:
onSpellTargetSelect( caster, target, spellNum )
Updated onCombatStart and onCombatEnd JS Events to also trigger for the other party in combat
Updated onPickup JS Event to include a third parameter - the potential container item was picked up from. Event now also triggers event in scripts attached to said containers:
onPickup( iPickedUp, pChar, iCont )
Added tracking of total playtime per individual character, and per account across all characters, and exposed these properties to JS engine:
.totalPlayTime // Account property, total playtime across all chars
.playTime // Character property, total playtime on given character only
Added new player-accessible command ('playtime) to spit out the playtime of current character/account as a whole (js/commands/playtime.js)
Implemented first version of Young Player System:
Replaced the UNUSED9 account flag with YOUNG, to be used by Young/New Player System
Added new JS Account property that gets/sets whether player account is considered Young:
.isYoung
Added new Char timers:
TIMER_YOUNGHEAL // Restricts how often Young players are healed by NPC healers
TIMER_YOUNGMESSAGE // Restricts how often Young players are warned about dangerous looking monsters in overworld
Updated GM commands 'get and 'set to get/set .isYoung property of player's account (js/commands/targeting/get.js and set.js)
Added new UOX.INI setting to enable/disable Young Player System (enabled by default):
YOUNGPLAYERSYSTEM=1
If Young Player System is enabled, all newly created player accounts are automatically marked with Young flag
Added new script to handle various restrictions and functions related to Young characters (js/player/young_player.js):
Young characters will have [Young] displayed over their head
Young characters will have their Young status checked and verified on every login + every stat/skill gain, to revoke the Young status if any of the following is true:
Account has a total playtime of more than 40 hours
Any character has more than 350 total (base) skill points
Any character has more than 70 skill points in a single skill
Any character has more than 150 total stat points
Any character has more than 80 stat points in a single stat
Young characters can renounce their Young status manually by saying the words "I renounce my young player status"
Young characters get two additional items upon creation:
a new player ticket (can be combined with any other players new player ticket for both players to get a reward)
a sextant (shows Young players directions to nearest moongate/bank regardless of where they are, as long as outdoors)
Young characters cannot target other player characters with hostile spells or skills
Young characters cannot be the target of other player characters' hostile spells or skills
Young characters can only cast beneficial spells upon themselves or other Young characters
Young characters can only be the target of beneficial spells from other Young players
Young players (and their pets/followers) cannot attack or harm any other players (or their pets/followers), nor themselves be attacked or harmed by any other players (or their pets/followers), whether from combat, spells, skills or items
Young players don't lose any of their items on death, and are teleported to the nearest healer upon death with all their items intact
Young players receive a warning upon entering dungeons that monsters there will be hostile
Updated global script (js/server/global.js) to:
Check/Verify Young status of players upon login
Attach young player script on login/creation for players on Young accounts
Give specific items to Young players upon creation
Added new script (js/item/corpse.js) that is assigned to all freshly created corpses. This script handles restrictions related to Young players interactions with corpses, and the interactions of other players with corpses of Young players
Updated JS Method .Carve() to return true/false depending on whether carving a corpse was successful
Updated Healer AI in code to heal nearby injured Young players
Updated Evil AI and Evil Caster AI in code to avoid selecting Young players as targets in combat outside of dungeons
Added a new section to UOX.INI - [young player starting locations] - that can be used to define starting locations for Young players. If only one such location is provided, all players start there. Otherwise, it matches the same starting location setup as the regular one - with one entry per town in Britannia.
Restricted transferring and/or friending of pets (code) and hirelings (hirelings.js) between Young and non-Young players
Restricted Young players from recalling or gating to Felucca facet
Young players can instantly logout from anywhere, at any time
2023-07-01 20:02:40 +08:00
|
|
|
Console << "\t" << dfndata.staMul.string() << " / " << dfndata.staIdx.filename().string() << "\t\t";
|
2022-10-24 18:39:33 +08:00
|
|
|
rValue = uoWorlds[mapNum].LoadArt( dfndata.staMul.string(), dfndata.staIdx.string() );
|
|
|
|
|
if( rValue )
|
|
|
|
|
{
|
|
|
|
|
uoWorlds[mapNum].ApplyDiff( dfndata.staDiffl.string(), dfndata.staDiffi.string(), dfndata.staDiff.string() );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// this is interesting, we found the terrain, but not the art. Regardless, lets delete it
|
|
|
|
|
auto iter = uoWorlds.find( mapNum );
|
|
|
|
|
if( iter != uoWorlds.end() )
|
|
|
|
|
{
|
|
|
|
|
uoWorlds.erase( iter );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
UOX3 0.99.6-RC6
Removed arbitrary and hidden restrictions on refreshing list of online players shown with 'wholist command
Fixed an issue where player ghosts that get teleported would not see themselves get updated to new location
Fixed a server crash from clients disconnecting while running server in debug mode
Improved how container updates are sent to players; now only sends to clients that have actually opened the container, and who are still within range
Added more information about UO data files being loaded during server startup
Enhanced the GM 'add menu to allow clicking directly on images of items/npcs to add them, and adjusted size of menus to accommodate this
Fixed an issue with fleeing NPCs that could cause them to attempt to flee across time and space, regardless of distance to target/attacker in combat
Added NPC AI that runs away from players if they get too close (even outside combat). Applied to hind, rabbits, squirrels, ferrets and various birds by default:
AI_ANIMAL_SCARED (aitype 12)
Fixed issues with NPCs fleeing forever, or getting stuck in flee/don't flee loop, by introducing max fleeing distance (50 tiles) and cooldown (30 sec) on fleeing
Updated onNameRequest JS Event to include third parameter with origin of name request, so script responses can be tailored appropriately:
onNameRequest( myObj, requestedBy, requestSource )
Potential values for requestSource:
0 - Speech/System Messages
1 - Guild Menus
2 - Stat Window (self)
3 - Stat Window (other)
4 - Tooltip
5 - Paperdoll Journal
6 - Paperdoll
7 - Single Click / All-Names
8 - System
9 - Secure Trade Window
Added Adaptive Performance System (APS) that dynamically adjust how often NPC AI/movement is checked based on overall shard performance. If performance drops below defined threshold, UOX3 gradually slows down checks for NPC AI/movement to prioritize player movement/speech/command responsiveness. If performance climbs back up above threshold, slowdowns are gradually removed. The following UOX.INI options have been added under [system] category to support this system:
APSPERFTHRESHOLD=50 // Performance threshold (measured in simulation cycles/sec) below which the APS kicks in
APSINTERVAL=100 // How often (in milliseconds) the APS checks performance and makes adjustments (if needed) to balance out shard performance
APSDELAYSTEP=50 // How much the delay timer is modified by (in milliseconds) each time APS makes adjustments
APSDELAYMAXCAP=2000 // Max amount of of delay APS can introduce for NPC AI/movement handling when attempting to restore shard performance
Added new JS Methods for Region objects:
.GetOrePrefs( oreType ) // Get ore preference data for ore type found in town region. Returned as an array containing the following data:
orePrefData -> [
oreName, // name of ore
color, // color of ore
minskill, // min skill to mine ore
ingotName, // name of ingot created from ore
makemenu, // makemenu entry for crafting something from ingot
oreChance, // default global chance of finding this ore type
scriptID // script attached to mined ore
],
orePrefChance // Chance of finding this ore type in given town region
.GetOreChance() // Get base chance of finding any ore in town region
Moved Mining skill plus gravedigging feature from hard code to scripts (js/skill/mining.js) to make it easier to maintain and/or customize, and removed hard coded variants
Gravedigging now relies on the ore resource system behind the scenes to restrict how often graves in a given area can be dug up
Fixed some incorrect references to .worldNumber Character property in misc scripts (should be .worldnumber)
Made some "hard-scripted" system messages in misc scripts use dictionary system instead
Added spawn region for banker NPCs in Serpent's Hold (dfndata/spawn/felucca/spawn_town_serpents_hold.dfn, dfndata/spawn/trammel/spawn_town_serpents_hold.dfn)
Fixed region definition of Ocllo to actually cover the entire town (dfndata/regions/regions.dfn)
Added numerous additional locations accessible with 'goplace # command, for key locations in Ilshenar, Malas, Tokuno Islands and Ter Mur (dfndata/location/location.dfn)
Revised travel-menu portion of GM menu (shortcut: 'travel) to include more travel options based on new locations (dfndata/items/travelmenu.dfn and travelmenu.bulk.dfn)
Fixed an issue where NPCs could attempt to attack targets in other worlds/instances
Added new JS Event that triggers for characters who are about to deal damage in combat. Complimentary to onDamage, which triggers for chars receiving damage:
onDamageDeal( dmgDealer, dmgReceiver, damageValue, damageType )
Added new JS Event that can trigger in global script upon creation of new player chars. Note that this will trigger in place of onCreateDFN event for player characters:
onCreatePlayer( pChar )
Added new JS Event that triggers for characters selecting a target with a spell. Complimentary to onSpellTarget, which triggers for targets selected with a spell:
onSpellTargetSelect( caster, target, spellNum )
Updated onCombatStart and onCombatEnd JS Events to also trigger for the other party in combat
Updated onPickup JS Event to include a third parameter - the potential container item was picked up from. Event now also triggers event in scripts attached to said containers:
onPickup( iPickedUp, pChar, iCont )
Added tracking of total playtime per individual character, and per account across all characters, and exposed these properties to JS engine:
.totalPlayTime // Account property, total playtime across all chars
.playTime // Character property, total playtime on given character only
Added new player-accessible command ('playtime) to spit out the playtime of current character/account as a whole (js/commands/playtime.js)
Implemented first version of Young Player System:
Replaced the UNUSED9 account flag with YOUNG, to be used by Young/New Player System
Added new JS Account property that gets/sets whether player account is considered Young:
.isYoung
Added new Char timers:
TIMER_YOUNGHEAL // Restricts how often Young players are healed by NPC healers
TIMER_YOUNGMESSAGE // Restricts how often Young players are warned about dangerous looking monsters in overworld
Updated GM commands 'get and 'set to get/set .isYoung property of player's account (js/commands/targeting/get.js and set.js)
Added new UOX.INI setting to enable/disable Young Player System (enabled by default):
YOUNGPLAYERSYSTEM=1
If Young Player System is enabled, all newly created player accounts are automatically marked with Young flag
Added new script to handle various restrictions and functions related to Young characters (js/player/young_player.js):
Young characters will have [Young] displayed over their head
Young characters will have their Young status checked and verified on every login + every stat/skill gain, to revoke the Young status if any of the following is true:
Account has a total playtime of more than 40 hours
Any character has more than 350 total (base) skill points
Any character has more than 70 skill points in a single skill
Any character has more than 150 total stat points
Any character has more than 80 stat points in a single stat
Young characters can renounce their Young status manually by saying the words "I renounce my young player status"
Young characters get two additional items upon creation:
a new player ticket (can be combined with any other players new player ticket for both players to get a reward)
a sextant (shows Young players directions to nearest moongate/bank regardless of where they are, as long as outdoors)
Young characters cannot target other player characters with hostile spells or skills
Young characters cannot be the target of other player characters' hostile spells or skills
Young characters can only cast beneficial spells upon themselves or other Young characters
Young characters can only be the target of beneficial spells from other Young players
Young players (and their pets/followers) cannot attack or harm any other players (or their pets/followers), nor themselves be attacked or harmed by any other players (or their pets/followers), whether from combat, spells, skills or items
Young players don't lose any of their items on death, and are teleported to the nearest healer upon death with all their items intact
Young players receive a warning upon entering dungeons that monsters there will be hostile
Updated global script (js/server/global.js) to:
Check/Verify Young status of players upon login
Attach young player script on login/creation for players on Young accounts
Give specific items to Young players upon creation
Added new script (js/item/corpse.js) that is assigned to all freshly created corpses. This script handles restrictions related to Young players interactions with corpses, and the interactions of other players with corpses of Young players
Updated JS Method .Carve() to return true/false depending on whether carving a corpse was successful
Updated Healer AI in code to heal nearby injured Young players
Updated Evil AI and Evil Caster AI in code to avoid selecting Young players as targets in combat outside of dungeons
Added a new section to UOX.INI - [young player starting locations] - that can be used to define starting locations for Young players. If only one such location is provided, all players start there. Otherwise, it matches the same starting location setup as the regular one - with one entry per town in Britannia.
Restricted transferring and/or friending of pets (code) and hirelings (hirelings.js) between Young and non-Young players
Restricted Young players from recalling or gating to Felucca facet
Young players can instantly logout from anywhere, at any time
2023-07-01 20:02:40 +08:00
|
|
|
|
|
|
|
|
if( !rValue )
|
|
|
|
|
{
|
|
|
|
|
Console.PrintFailed();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.PrintDone();
|
|
|
|
|
}
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::LoadMultis()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Loads multi files into memory
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::LoadMultis( const std::string& uodir ) -> void
|
|
|
|
|
{
|
|
|
|
|
// now main memory multiItems
|
|
|
|
|
// Odd we do no check?
|
|
|
|
|
if( !multiData.LoadMultiCollection( std::filesystem::path( uodir ), &tileInfo ))
|
|
|
|
|
{
|
|
|
|
|
Console.PrintFailed();
|
|
|
|
|
Shutdown( FATAL_UOX3_MULTI_DATA_NOT_FOUND );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
Console.PrintDone();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::ArtAt()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Try to find and return map tile at specific location in a world
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::ArtAt( std::int16_t x, std::int16_t y, std::uint8_t world ) -> std::vector<Tile_st>&
|
|
|
|
|
{
|
|
|
|
|
static std::vector<Tile_st> empty;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return uoWorlds.at( world ).ArtAt( x, y );
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
return empty;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
2012-11-03 18:11:04 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
//=-----------------------------------------------------------------------------------------------=
|
|
|
|
|
auto CMulHandler::ArtAt( std::int16_t x, std::int16_t y, std::uint8_t world ) const -> const std::vector<Tile_st>&
|
|
|
|
|
{
|
|
|
|
|
static std::vector<Tile_st> empty;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return uoWorlds.at( world ).ArtAt( x, y );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
catch(...)
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
return empty;
|
|
|
|
|
}
|
2021-05-30 03:21:05 +08:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::SizeOfMap()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Return x/y size of specified world
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::SizeOfMap( std::uint8_t worldNumber ) const -> std::pair<int, int>
|
|
|
|
|
{
|
|
|
|
|
return uoWorlds.at( worldNumber ).Size();
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::DiffCountForMap()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Return count of map differences for specified world
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::DiffCountForMap( std::uint8_t worldNumber ) const -> std::pair<int, int>
|
|
|
|
|
{
|
|
|
|
|
return std::make_pair( uoWorlds.at( worldNumber ).DiffArt(), uoWorlds.at( worldNumber ).DiffTerrain() );
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::MultiHeight()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Return the height of a multi item at the given x, y.
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::MultiHeight( CItem *i, std::int16_t x, std::int16_t y, std::int8_t oldZ, std::int8_t maxZ, bool checkHeight ) -> std::int8_t
|
|
|
|
|
{
|
|
|
|
|
UI16 multiId = static_cast<UI16>(i->GetId() - 0x4000);
|
2021-05-28 03:41:43 +08:00
|
|
|
|
2021-05-30 03:21:05 +08:00
|
|
|
SI08 mHeight = ILLEGAL_Z;
|
|
|
|
|
SI08 tmpTop = ILLEGAL_Z;
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
if( !MultiExists( multiId ))
|
|
|
|
|
return mHeight;
|
|
|
|
|
|
2012-11-03 18:11:04 +00:00
|
|
|
const SI16 baseX = i->GetX();
|
|
|
|
|
const SI16 baseY = i->GetY();
|
|
|
|
|
const SI08 baseZ = i->GetZ();
|
2022-10-24 18:39:33 +08:00
|
|
|
for( auto &multi : SeekMulti( multiId ).items )
|
|
|
|
|
{
|
|
|
|
|
if(( checkHeight || multi.flag ) && ( baseX + multi.offsetX ) == x && ( baseY + multi.offsetY ) == y )
|
|
|
|
|
{
|
|
|
|
|
if( checkHeight )
|
|
|
|
|
{
|
2021-05-28 03:41:43 +08:00
|
|
|
// Returns height of highest point of multi
|
2022-10-24 18:39:33 +08:00
|
|
|
tmpTop = static_cast<SI08>( baseZ + multi.altitude );
|
|
|
|
|
if(( tmpTop <= oldZ + maxZ ) && tmpTop > oldZ && tmpTop > mHeight )
|
|
|
|
|
{
|
2021-05-28 03:41:43 +08:00
|
|
|
mHeight = tmpTop;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms
Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt)
Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri)
Updated SpiderMonkey from v1.6.0 to v1.7.0
Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri)
Added StringUtility file with general common string manipulation functions (punt)
Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt)
Overall code cleanup to remove/replace platform-dependent code (punt)
Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt)
Replaced usage of char in many places with std::string (punt)
Started process of replacing UString usage with functions provided through StringUtility instead (punt)
Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt)
Replaced platform specific time handling by using cross-platform chrono library (punt)
Removed UOX namespace to reduce complexity (punt)
Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt)
Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt)
Removed some platform specific files like uoxlinux.h, which is no longer required (punt)
Removed legacy crash protection code, and removed support for cluox (punt)
Removed legacy "support" for Borland compiler (punt)
Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri)
Removed legacy BUILD folder with outdated compilation instructions (Xuri)
Removed old Changelog file (merged into Changelog.txt) (Xuri)
Fixed a pointer bug for items in multis on world load (punt)
Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt)
Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt)
Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt)
Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt)
Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt)
Added some new commands to js/commands/custom/misc-cmd.js (Xuri)
cont // Targeted item will be made a container, set to nondecay and movable 2
endfight // Targeted character (and character being fought) will stop fighting
getmulti // Get multiObject for targeted item
finditem // Find item at layer X
movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen)
Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri)
Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
2022-06-12 19:54:28 -04:00
|
|
|
tmpTop = static_cast<SI08>( baseZ + multi.altitude );
|
2022-10-24 18:39:33 +08:00
|
|
|
if( std::abs( tmpTop - oldZ ) <= maxZ )
|
|
|
|
|
{
|
2023-03-17 16:01:22 +08:00
|
|
|
mHeight = tmpTop + multi.info->ClimbHeight( true );
|
|
|
|
|
if( mHeight == oldZ ) // We found a surface at the suggested height
|
|
|
|
|
break;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms
Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt)
Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri)
Updated SpiderMonkey from v1.6.0 to v1.7.0
Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri)
Added StringUtility file with general common string manipulation functions (punt)
Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt)
Overall code cleanup to remove/replace platform-dependent code (punt)
Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt)
Replaced usage of char in many places with std::string (punt)
Started process of replacing UString usage with functions provided through StringUtility instead (punt)
Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt)
Replaced platform specific time handling by using cross-platform chrono library (punt)
Removed UOX namespace to reduce complexity (punt)
Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt)
Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt)
Removed some platform specific files like uoxlinux.h, which is no longer required (punt)
Removed legacy crash protection code, and removed support for cluox (punt)
Removed legacy "support" for Borland compiler (punt)
Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri)
Removed legacy BUILD folder with outdated compilation instructions (Xuri)
Removed old Changelog file (merged into Changelog.txt) (Xuri)
Fixed a pointer bug for items in multis on world load (punt)
Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt)
Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt)
Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt)
Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt)
Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt)
Added some new commands to js/commands/custom/misc-cmd.js (Xuri)
cont // Targeted item will be made a container, set to nondecay and movable 2
endfight // Targeted character (and character being fought) will stop fighting
getmulti // Get multiObject for targeted item
finditem // Find item at layer X
movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen)
Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri)
Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
|
|
|
}
|
2012-11-03 18:11:04 +00:00
|
|
|
}
|
Exposed various map and statics related functions to JS engine
Updated JS item properties MORE, MOREX, MOREY, MOREZ and SERIAL, and character property SERIAL, to pass values to JS scripts using JS_NewNumberValue() instead of INT_TO_JSVAL if the property value cannot fit inside JSVAL (checked with INT_FITS_IN_JSVAL)
Added support in CResponse.cpp for client trigger word for securing containers in houses - TW_HOUSESECURE
Updated CMulHandler::CheckStaticFlag() to match with statics that cover/extend across the specified Z coordinate, not just ones that have the same base Z level
Updated CMulHandler::DoesMapBlock() to not deem map tiles as blocking if they are more than 16 Z (height of a character) higher than the specified Z coordinate to check
Exposed method for finding corners of a multi to JS engine:
.GetMultiCorner( cornerID ) - Gets coordinates for specified corner of multi (0 = NW, 1 = NE, 2 = SW, 3 = SE)
Exposed various functions related to map, statics and multis to JS engine:
CalcMultiFromSer( serial ) - Find a multi from a provided serial
GetMapElevation( x, y, z, world) - Returns the map elevation at specified coordinates
IsInBuilding( x, y, z, world, instance, checkHeight ) - Returns true if the specified location is inside a static building (underneath static items), or if player is inside a multi. If the checkHeight argument is true, player is only deemed inside a multi if there are multi-items above the player's head. If player is in a courtyard/on a rooftop, they will be deemed to be NOT in the building. checkHeight is not used for the static part of the function.
CheckStaticFlag( x, y, z, world, tileFlagID ) - Checks to see if any statics at given coordinates has specified tile flag
DoesStaticBlock( x, y, z, world, checkWater ) - Checks if statics at/above given location blocks characters
DoesDynamicBlock( x, y, z, world, instance, checkWater, waterWalk ) - Checks if dynamics at/above given location blocks characters
DoesMapBlock( x, y, z, world, checkWater, waterWalk ) - Checks if map tile at/above given location blocks characters
2020-10-05 23:12:34 +08:00
|
|
|
}
|
2022-06-15 11:24:57 -04:00
|
|
|
|
Exposed various map and statics related functions to JS engine
Updated JS item properties MORE, MOREX, MOREY, MOREZ and SERIAL, and character property SERIAL, to pass values to JS scripts using JS_NewNumberValue() instead of INT_TO_JSVAL if the property value cannot fit inside JSVAL (checked with INT_FITS_IN_JSVAL)
Added support in CResponse.cpp for client trigger word for securing containers in houses - TW_HOUSESECURE
Updated CMulHandler::CheckStaticFlag() to match with statics that cover/extend across the specified Z coordinate, not just ones that have the same base Z level
Updated CMulHandler::DoesMapBlock() to not deem map tiles as blocking if they are more than 16 Z (height of a character) higher than the specified Z coordinate to check
Exposed method for finding corners of a multi to JS engine:
.GetMultiCorner( cornerID ) - Gets coordinates for specified corner of multi (0 = NW, 1 = NE, 2 = SW, 3 = SE)
Exposed various functions related to map, statics and multis to JS engine:
CalcMultiFromSer( serial ) - Find a multi from a provided serial
GetMapElevation( x, y, z, world) - Returns the map elevation at specified coordinates
IsInBuilding( x, y, z, world, instance, checkHeight ) - Returns true if the specified location is inside a static building (underneath static items), or if player is inside a multi. If the checkHeight argument is true, player is only deemed inside a multi if there are multi-items above the player's head. If player is in a courtyard/on a rooftop, they will be deemed to be NOT in the building. checkHeight is not used for the static part of the function.
CheckStaticFlag( x, y, z, world, tileFlagID ) - Checks to see if any statics at given coordinates has specified tile flag
DoesStaticBlock( x, y, z, world, checkWater ) - Checks if statics at/above given location blocks characters
DoesDynamicBlock( x, y, z, world, instance, checkWater, waterWalk ) - Checks if dynamics at/above given location blocks characters
DoesMapBlock( x, y, z, world, checkWater, waterWalk ) - Checks if map tile at/above given location blocks characters
2020-10-05 23:12:34 +08:00
|
|
|
return mHeight;
|
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms
Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt)
Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri)
Updated SpiderMonkey from v1.6.0 to v1.7.0
Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri)
Added StringUtility file with general common string manipulation functions (punt)
Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt)
Overall code cleanup to remove/replace platform-dependent code (punt)
Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt)
Replaced usage of char in many places with std::string (punt)
Started process of replacing UString usage with functions provided through StringUtility instead (punt)
Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt)
Replaced platform specific time handling by using cross-platform chrono library (punt)
Removed UOX namespace to reduce complexity (punt)
Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt)
Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt)
Removed some platform specific files like uoxlinux.h, which is no longer required (punt)
Removed legacy crash protection code, and removed support for cluox (punt)
Removed legacy "support" for Borland compiler (punt)
Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri)
Removed legacy BUILD folder with outdated compilation instructions (Xuri)
Removed old Changelog file (merged into Changelog.txt) (Xuri)
Fixed a pointer bug for items in multis on world load (punt)
Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt)
Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt)
Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt)
Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt)
Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt)
Added some new commands to js/commands/custom/misc-cmd.js (Xuri)
cont // Targeted item will be made a container, set to nondecay and movable 2
endfight // Targeted character (and character being fought) will stop fighting
getmulti // Get multiObject for targeted item
finditem // Find item at layer X
movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen)
Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri)
Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
|
|
|
}
|
2002-04-07 21:27:53 +00:00
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::MultiTile()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Returns ID of tile in multi at specified coordinates
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::MultiTile( CItem *i, std::int16_t x, std::int16_t y, std::int8_t oldz, bool checkVisible ) -> std::uint16_t
|
|
|
|
|
{
|
|
|
|
|
auto rValue = std::uint16_t();
|
|
|
|
|
if( !i->CanBeObjType( OT_MULTI ))
|
2012-11-03 18:11:04 +00:00
|
|
|
return 0;
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
UI16 multiId = static_cast<UI16>( i->GetId() - 0x4000 );
|
2022-11-14 21:12:12 -05:00
|
|
|
[[maybe_unused]] SI32 length = 0;
|
2022-11-04 17:12:13 -04:00
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
if( !MultiExists( multiId ))
|
|
|
|
|
{
|
2012-11-03 18:11:04 +00:00
|
|
|
Console << "CMulHandler::MultiTile->Bad length in multi file. Avoiding stall." << myendl;
|
2022-06-15 07:04:28 -04:00
|
|
|
auto map1 = Map->SeekMap( i->GetX(), i->GetY(), i->WorldNumber() );
|
Small update
Fixed an issue with an internal movement check that prevented characters from moving in valid map areas in Felucca/Trammel from X 6144 to X 7168
Fixed an issue where .instanceID property was misspelled in 'xgo GM command script, causing characters to be teleported to an out of bounds area where they would no longer be saved (js/commands/targeting/x.js)
Added some additional error-checking to .Teleport()/.SetLocation() JS Method to prevent script-accidents from sending characters out of bounds.
Updated Poisoning skill to add poison-charges to weapons being poisoned. Charges are consumed when applying poison in combat (js/skill/poisoning.js)
Updated combat code to consume poison-charges if a poisoned weapon is used to poison an opponent
Updated shoplists for Blacksmiths and Weaponsmiths - they now buy/sell longswords (dfndata/items/shoplist.dfn)
Updated MageShopping shoplist for mage vendors - they now buy/sell mass curse scrolls (dfndata/items/shoplist.dfn)
Added new Spawn Region DFN tag that can specify which era or eras of UO (Multiple comma-separated entries supported) a given spawn region is valid for. Spawn region not valid for core shard era will be ignored. Syntax:
ERAS=UO,T2A,UOR,LBR,AOS,SE,ML,SA,HS,TOL
Added new Spawn Region DFN tag that allows using another spawn region as a "parent". All properties of this parent will be inherited except for these, which are ignored: ERAS, NPCLIST, ITEMLIST, NPC and ITEM. Syntax for new tag:
GET=# // Inherit a specified spawn region
Added spawn region for animal trainer vendor in Vesper stable
Added spawn region for fur trader/tanner vendors in The Best Hides of Britain
Added spawn region for spinner vendor in The Lord's Clothier's and The Right Fit shops in Britain
Added spawn region for tanner NPC to Nujel'm Tannery (and fixed leatherworker spawn region for same area)
Added spawn regions for banker NPCs in East Bank of Britain, First Bank of Moonglow, Jhelom Bank and Jeweler, Bank of Skara Brae
Added spawn regions for stables, tailor and blacksmith inside Castle British
Added spawn regions for mage shops, mage guilds and farm houses in Moonglow
Added spawn regions for misc vendors and townfolk in multiple cities
Added spawn regions for Fire Island
Updated spawn regions for Dagger Isle/Ice Island
Added spawn regions for forests and jungles in southern Britannia and on various islands including Bucc's Den, Moonglow, Serpent's Hold, and misc unpopulated islands
Added spawn regions for area east of Skara Brae, around Hedge Maze and south of Britain
Added spawn regions for wandering healers outside every dungeon entrance in Britannia and Lost Lands
Re-integrated ocean spawn regions for ocean creatures (dolphin, walrus, water elemental, sea serpent) from the original community-based spawn file
Added reagent spawns in overworld spawn regions in Britannia/Lost Lands
Added special reagent spawns in swamp areas
Added additional overworld spawn regions in Britannia/Lost Lands
Added spawn regions for Khaldun dungeon that spawn some new and some old NPCs:
Old: Zombies, skeletons, skeletal mages, skeletal knights, ancient liches
New: Cursed (and named) NPCs, shadowfiends, zealots of khaldun (knights/summoners), tentacles of the harrower
Updated size and positions of some existing overworld spawn regions
Fixed incorrect spawn region size for small island south of Trinsic
Added switch/door puzzle functionality in Khaldun dungeon using new switch/door combo script (js/item/dungeons/switch_door_combo.js)
Added "smart objects" in Khaldun dungeon that activate when you come close enough (js/item/dungeons/smart_activate_item.js)
Added teleport locations within Khaldun dungeon (js/teleport.scp)
Added custom AIs to existing NPC spawning in Khaldun dungeon:
Ancient Lich (summons other undead, and can turn into one of them for disguise)
Added DFN entries for new NPCs spawning in Khaldun dungeon, some with custom AIs:
[tentacles_of_the_harrower] -> Tentacles of the Harrower (life steal)
[shadowfiend] -> Shadowfiends (seek out and reveal hidden players)
[zealot_knight]/[zealot_summoner] -> Zealots of Khaldun (turn into undead on death, male/female variants)
[cursed] -> Cursed (male/female variants)
[spectralarmor] -> Spectral Armor
Added DFN entries for new (named) NPCs spawning in Khaldun dungeon:
[lysander_gathenwale] -> Lysander Gathenwale
[grimmoch_drummel] -> Grimmoch Drummel
[morg_bergen] -> Morg Bergen
[tavara_sewel] -> Tavara Sewel
Added new NPC DFN entries:
[leatherworker] -> alias for male/female leatherworker vendors
[mapmaker] -> alias for male/female mapmaker vendors
Added new Race DFN entries:
[RACE 29] -> Cursed (enemies of RACE 30)
[RACE 30] -> Zealots (enemies of RACE 29)
Added new book DFN entries for Khaldun journals of Lysander, Tavara and Grimmoch - available as loot from the respective NPCs (dfndata/misc/books.dfn and dfndata/items/misc/books.dfn)
Added 25% chance for hit-animations and hit-SFX to play for targets in combat, instead of playing every time - can get very spammy
Monsters with actual weapons equipped (like Ophidian Enforcer with Halberd/Bardiche) will now get appropriate combat SFX for hitting with that weapon
Updated Healing skill to base cure/resurrection skill requirements on the calculated skill, rather than base skill (js/skill/healing.js)
Fixed an issue where healing with bandages and dying in the process would not properly reset the healing-related tags and skills used
Updated healing script to show a resurrection confirmation menu for players targeted with bandages for resurrect (js/skill/healing.js)
All skill usage states now reset on death, to prevent cases of players being "busy" while trying to use skills that got stuck due to script bugs.
The 'regspawn GM command now supports a new parameter called "max". Updated command syntax:
'regspawn # // perform a single respawn cycle in a specific spawn region
'regspawn all // perform a single respawn cycle across all spawn regions
'regspawn max // respawn ALL spawn regions to MAX capacity in one go
Added new UOX.INI setting that determines the maximum range at which NPCs can initiate attacks on players/NPCs (the old MAXRANGE=10 setting now instead defines max range at which players can initiate attacks on players/NPCs):
MAXNPCAGGRORANGE=10
Optimized performance by significantly reducing the number of line-of-sight checks performed by characters, especially in combat scenarios, or when evaluating potential targets for NPC AIs. The amount of checks done is also affected by the new ini setting for max aggro range.
Fixed an issue where both NPC and player characters would instantly drop one hunger level (from 6 to 5) upon creation since hungerrate was not initialized until after first hunger-event
Updated character priv property from UI16 to UI32, and added a new flag that determines if fame/karma title is hidden for character:
HIDEFAMEKARMATITLE (0x10000)
NPCs will no longer aggro other NPCs if the Z difference between them is greater or equal to 20 (i.e. they're on different floors), unless both are using ranged weapons and both are in range
Fixed an issue where players could get discounts from shopkeepers even though neither player nor shopkeeper were members of a NPC guild (js/npc/ai/shopkeeper.js)
Fixed an issue where the "premium" a player would get when selling items to a shopkeeper in the same NPC guild as them would be 110% extra on top of the item's value, instead of the intended 10% (js/npc/ai/shopkeeper.js) (Thanks, cobrag0318!)
Added missing tall straw hat to tailoring crafting scripts (Thanks, Dragon Slayer!)
Improved error reporting during compilation of individual scripts being reloaded - will now show more context and line number
onCombatEnd JS Event now also triggers when NPCs ignore their target and/or evade during combat
Updated 'decorate command to support saving/loading custom tags on items for world templates. These are stored after a @ symbol in the world template, each custom tag separated by a | symbol, and with each custom tag saved using this syntax: key$type$value
Updated resource-harvesting scripts to use script-specific global (const) variables, to avoid interference between different scripts (js/server/resource/*)
Added new resource-harvesting scripts and added spawn regions for these in fields on farms all over Britannia/Lost Lands
cabbages (js/server/resource/cabbages.js)
canteloupes (js/server/resource/canteloupes.js)
carrots (js/server/resource/carrots.js)
garlic (js/server/resource/garlic.js)
gourds (js/server/resource/gourds.js)
honeydew melons (js/server/resource/honeydewmelon.js)
onions (js/server/resource/onions.js)
pumpkins (js/server/resource/pumpkins.js)
squashes (js/server/resource/squashes.js)
turnips (js/server/resource/turnips.js)
watermelons (js/server/resource/watermelon.js)
Updated CSpawnRegion::FindItemSpotToSpawn() function in cSpawnRegion.cpp to prevent duplicate spawning of exact same item in exact same location
Updated sectionid of all potion and scroll aliases to match main item, so they'll get correctly picked up by NPC shopkeepers (dfndata/items/magic/potions.dfn and scrolls.dfn)
Specified sectionid for backpacks, so it also gets applied to packs added using the alias [backpack] (dfndata/items/misc/provisions.dfn)
Fixed a code issue that prevented players from selling empty containers to NPC shopkeepers willing to buy such containers
Fixed an issue where field-spells (wall of stone, poison field, etc) would ignore dynamic/static items that should block these
Fixed an issue where field-spells could be cast into houses from the outside by standing next to a wall and targeting self
Fixed a War/Peace-mode desync between client and server by having server always notify client (using war-toggle packet) when the "at war" flag is toggled for player character
Fixed an issue with hiding skill that wouldn't allow player to hide after having acquired self as target in combat (through spellcasting, for instance) (Thanks, Dragon Slayer!)
Fixed an issue where mana/reagents were consumed and skillcheck performed before all spellcast-validations had succeeded, resulting in the occasional loss of reagents/mana when spellcasting was disallowed (code and js/magic/clumsy.js and level1targ.js)
Fixed an issue with lack of criminal-flagging for casting of hostile spells scripted in JS (clumsy, magic arrow, feeblemind) vs blue targets (js/magic/clumsy.js and level1targ.js)
Fixed some issues with Line-of-Sight checking code that returned incorrect results, which amongst other things affected spellcasting in areas with uneven terrain
Fixed some issues with movement code and climbing of ladders, in particular the rope ladder in the 2-story log cabin. Code now sets a "is climbing" flag when character steps onto a rope ladder, and uses that to help resolve some edge cases, and then unsets it when they step off.
Renamed section headers of some map-items in DFNs from "locationname" to "locationnamemap" for clarity (example: "britain" to "britainmap")
Fixed broken "map wrapping" when sailing to edges of map in Felucca or Trammel
Fixed a server crash related to attempts at reading data from invalid map tiles
2025-06-27 08:40:02 +08:00
|
|
|
if( map1.terrainInfo != nullptr && map1.CheckFlag( TF_WET )) // is it water?
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
|
|
|
|
i->SetId( 0x4001 );
|
|
|
|
|
}
|
2012-11-03 18:11:04 +00:00
|
|
|
else
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
|
|
|
|
i->SetId( 0x4064 );
|
|
|
|
|
}
|
2022-11-14 21:12:12 -05:00
|
|
|
length = 0;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
2021-05-30 03:21:05 +08:00
|
|
|
// Loop through each item that makes up the multi
|
|
|
|
|
// If any of those items intersect with area were are checking, return the ID of that tile
|
2022-10-24 18:39:33 +08:00
|
|
|
for( auto &multi : SeekMulti( multiId ).items )
|
|
|
|
|
{
|
|
|
|
|
if( !checkVisible )
|
|
|
|
|
{
|
|
|
|
|
if(( i->GetX() + multi.offsetX == x ) && ( i->GetY() + multi.offsetY == y ))
|
|
|
|
|
{
|
|
|
|
|
rValue = multi.tileId;
|
2022-06-15 11:24:57 -04:00
|
|
|
break;
|
2021-05-30 03:21:05 +08:00
|
|
|
}
|
2012-11-03 18:11:04 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else if( multi.flag > 0 && ( std::abs( i->GetZ() + multi.altitude - oldz ) <= 1 ))
|
|
|
|
|
{
|
|
|
|
|
if(( i->GetX() + multi.offsetX == x ) && ( i->GetY() + multi.offsetY == y ))
|
|
|
|
|
{
|
|
|
|
|
rValue = multi.tileId;
|
2022-06-15 11:24:57 -04:00
|
|
|
break;
|
2021-05-30 03:21:05 +08:00
|
|
|
}
|
2021-05-28 03:41:43 +08:00
|
|
|
}
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
2021-05-28 03:41:43 +08:00
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
return rValue;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::DynTile()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Returns which dynamic tile is present at (x,y) or -1 if no tile exists
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::DynTile( std::int16_t x, std::int16_t y, std::int8_t z, std::uint8_t worldNumber, std::uint16_t instanceId, bool checkOnlyMultis, bool checkOnlyNonMultis ) -> CItem *
|
|
|
|
|
{
|
|
|
|
|
auto rValue = static_cast<CItem*>( nullptr );
|
|
|
|
|
for( auto &cellResponse : MapRegion->PopulateList( x, y, worldNumber ))
|
|
|
|
|
{
|
|
|
|
|
if( cellResponse == nullptr )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
auto regItems = cellResponse->GetItemList();
|
|
|
|
|
for( const auto &item : regItems->collection() )
|
|
|
|
|
{
|
|
|
|
|
if( !ValidateObject( item ) || ( item->GetInstanceId() != instanceId ))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if( !checkOnlyNonMultis )
|
|
|
|
|
{
|
|
|
|
|
if( item->GetId( 1 ) >= 0x40 && ( item->GetObjType() == OT_MULTI || item->CanBeObjType( OT_MULTI )))
|
|
|
|
|
{
|
|
|
|
|
auto multiTileId = MultiTile( item, x, y, z, false );
|
|
|
|
|
if( multiTileId > 0 )
|
|
|
|
|
{
|
|
|
|
|
rValue = item;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if( item->GetMulti() != INVALIDSERIAL || ValidateObject( CalcMultiFromSer( item->GetOwner() )))
|
|
|
|
|
{
|
|
|
|
|
if(( item->GetX() == x ) && ( item->GetY() == y ))
|
|
|
|
|
{
|
|
|
|
|
rValue = item;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if( !checkOnlyMultis && ( item->GetX() == x ) && ( item->GetY() == y ))
|
|
|
|
|
{
|
|
|
|
|
rValue = item;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( rValue )
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return rValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::DoesStaticBlock()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Checks if statics at/above given coordinates blocks movement, etc
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::DoesStaticBlock( std::int16_t x, std::int16_t y, std::int8_t z, std::uint8_t worldNumber, bool checkWater ) -> bool
|
|
|
|
|
{
|
|
|
|
|
auto &artTiles = Map->ArtAt( x, y, worldNumber );
|
|
|
|
|
auto rValue = false;
|
|
|
|
|
for( auto &tile : artTiles )
|
|
|
|
|
{
|
|
|
|
|
auto elev = static_cast<SI08>( tile.altitude + tile.artInfo->ClimbHeight() );
|
|
|
|
|
if( checkWater )
|
|
|
|
|
{
|
Small update
Fixed an issue with an internal movement check that prevented characters from moving in valid map areas in Felucca/Trammel from X 6144 to X 7168
Fixed an issue where .instanceID property was misspelled in 'xgo GM command script, causing characters to be teleported to an out of bounds area where they would no longer be saved (js/commands/targeting/x.js)
Added some additional error-checking to .Teleport()/.SetLocation() JS Method to prevent script-accidents from sending characters out of bounds.
Updated Poisoning skill to add poison-charges to weapons being poisoned. Charges are consumed when applying poison in combat (js/skill/poisoning.js)
Updated combat code to consume poison-charges if a poisoned weapon is used to poison an opponent
Updated shoplists for Blacksmiths and Weaponsmiths - they now buy/sell longswords (dfndata/items/shoplist.dfn)
Updated MageShopping shoplist for mage vendors - they now buy/sell mass curse scrolls (dfndata/items/shoplist.dfn)
Added new Spawn Region DFN tag that can specify which era or eras of UO (Multiple comma-separated entries supported) a given spawn region is valid for. Spawn region not valid for core shard era will be ignored. Syntax:
ERAS=UO,T2A,UOR,LBR,AOS,SE,ML,SA,HS,TOL
Added new Spawn Region DFN tag that allows using another spawn region as a "parent". All properties of this parent will be inherited except for these, which are ignored: ERAS, NPCLIST, ITEMLIST, NPC and ITEM. Syntax for new tag:
GET=# // Inherit a specified spawn region
Added spawn region for animal trainer vendor in Vesper stable
Added spawn region for fur trader/tanner vendors in The Best Hides of Britain
Added spawn region for spinner vendor in The Lord's Clothier's and The Right Fit shops in Britain
Added spawn region for tanner NPC to Nujel'm Tannery (and fixed leatherworker spawn region for same area)
Added spawn regions for banker NPCs in East Bank of Britain, First Bank of Moonglow, Jhelom Bank and Jeweler, Bank of Skara Brae
Added spawn regions for stables, tailor and blacksmith inside Castle British
Added spawn regions for mage shops, mage guilds and farm houses in Moonglow
Added spawn regions for misc vendors and townfolk in multiple cities
Added spawn regions for Fire Island
Updated spawn regions for Dagger Isle/Ice Island
Added spawn regions for forests and jungles in southern Britannia and on various islands including Bucc's Den, Moonglow, Serpent's Hold, and misc unpopulated islands
Added spawn regions for area east of Skara Brae, around Hedge Maze and south of Britain
Added spawn regions for wandering healers outside every dungeon entrance in Britannia and Lost Lands
Re-integrated ocean spawn regions for ocean creatures (dolphin, walrus, water elemental, sea serpent) from the original community-based spawn file
Added reagent spawns in overworld spawn regions in Britannia/Lost Lands
Added special reagent spawns in swamp areas
Added additional overworld spawn regions in Britannia/Lost Lands
Added spawn regions for Khaldun dungeon that spawn some new and some old NPCs:
Old: Zombies, skeletons, skeletal mages, skeletal knights, ancient liches
New: Cursed (and named) NPCs, shadowfiends, zealots of khaldun (knights/summoners), tentacles of the harrower
Updated size and positions of some existing overworld spawn regions
Fixed incorrect spawn region size for small island south of Trinsic
Added switch/door puzzle functionality in Khaldun dungeon using new switch/door combo script (js/item/dungeons/switch_door_combo.js)
Added "smart objects" in Khaldun dungeon that activate when you come close enough (js/item/dungeons/smart_activate_item.js)
Added teleport locations within Khaldun dungeon (js/teleport.scp)
Added custom AIs to existing NPC spawning in Khaldun dungeon:
Ancient Lich (summons other undead, and can turn into one of them for disguise)
Added DFN entries for new NPCs spawning in Khaldun dungeon, some with custom AIs:
[tentacles_of_the_harrower] -> Tentacles of the Harrower (life steal)
[shadowfiend] -> Shadowfiends (seek out and reveal hidden players)
[zealot_knight]/[zealot_summoner] -> Zealots of Khaldun (turn into undead on death, male/female variants)
[cursed] -> Cursed (male/female variants)
[spectralarmor] -> Spectral Armor
Added DFN entries for new (named) NPCs spawning in Khaldun dungeon:
[lysander_gathenwale] -> Lysander Gathenwale
[grimmoch_drummel] -> Grimmoch Drummel
[morg_bergen] -> Morg Bergen
[tavara_sewel] -> Tavara Sewel
Added new NPC DFN entries:
[leatherworker] -> alias for male/female leatherworker vendors
[mapmaker] -> alias for male/female mapmaker vendors
Added new Race DFN entries:
[RACE 29] -> Cursed (enemies of RACE 30)
[RACE 30] -> Zealots (enemies of RACE 29)
Added new book DFN entries for Khaldun journals of Lysander, Tavara and Grimmoch - available as loot from the respective NPCs (dfndata/misc/books.dfn and dfndata/items/misc/books.dfn)
Added 25% chance for hit-animations and hit-SFX to play for targets in combat, instead of playing every time - can get very spammy
Monsters with actual weapons equipped (like Ophidian Enforcer with Halberd/Bardiche) will now get appropriate combat SFX for hitting with that weapon
Updated Healing skill to base cure/resurrection skill requirements on the calculated skill, rather than base skill (js/skill/healing.js)
Fixed an issue where healing with bandages and dying in the process would not properly reset the healing-related tags and skills used
Updated healing script to show a resurrection confirmation menu for players targeted with bandages for resurrect (js/skill/healing.js)
All skill usage states now reset on death, to prevent cases of players being "busy" while trying to use skills that got stuck due to script bugs.
The 'regspawn GM command now supports a new parameter called "max". Updated command syntax:
'regspawn # // perform a single respawn cycle in a specific spawn region
'regspawn all // perform a single respawn cycle across all spawn regions
'regspawn max // respawn ALL spawn regions to MAX capacity in one go
Added new UOX.INI setting that determines the maximum range at which NPCs can initiate attacks on players/NPCs (the old MAXRANGE=10 setting now instead defines max range at which players can initiate attacks on players/NPCs):
MAXNPCAGGRORANGE=10
Optimized performance by significantly reducing the number of line-of-sight checks performed by characters, especially in combat scenarios, or when evaluating potential targets for NPC AIs. The amount of checks done is also affected by the new ini setting for max aggro range.
Fixed an issue where both NPC and player characters would instantly drop one hunger level (from 6 to 5) upon creation since hungerrate was not initialized until after first hunger-event
Updated character priv property from UI16 to UI32, and added a new flag that determines if fame/karma title is hidden for character:
HIDEFAMEKARMATITLE (0x10000)
NPCs will no longer aggro other NPCs if the Z difference between them is greater or equal to 20 (i.e. they're on different floors), unless both are using ranged weapons and both are in range
Fixed an issue where players could get discounts from shopkeepers even though neither player nor shopkeeper were members of a NPC guild (js/npc/ai/shopkeeper.js)
Fixed an issue where the "premium" a player would get when selling items to a shopkeeper in the same NPC guild as them would be 110% extra on top of the item's value, instead of the intended 10% (js/npc/ai/shopkeeper.js) (Thanks, cobrag0318!)
Added missing tall straw hat to tailoring crafting scripts (Thanks, Dragon Slayer!)
Improved error reporting during compilation of individual scripts being reloaded - will now show more context and line number
onCombatEnd JS Event now also triggers when NPCs ignore their target and/or evade during combat
Updated 'decorate command to support saving/loading custom tags on items for world templates. These are stored after a @ symbol in the world template, each custom tag separated by a | symbol, and with each custom tag saved using this syntax: key$type$value
Updated resource-harvesting scripts to use script-specific global (const) variables, to avoid interference between different scripts (js/server/resource/*)
Added new resource-harvesting scripts and added spawn regions for these in fields on farms all over Britannia/Lost Lands
cabbages (js/server/resource/cabbages.js)
canteloupes (js/server/resource/canteloupes.js)
carrots (js/server/resource/carrots.js)
garlic (js/server/resource/garlic.js)
gourds (js/server/resource/gourds.js)
honeydew melons (js/server/resource/honeydewmelon.js)
onions (js/server/resource/onions.js)
pumpkins (js/server/resource/pumpkins.js)
squashes (js/server/resource/squashes.js)
turnips (js/server/resource/turnips.js)
watermelons (js/server/resource/watermelon.js)
Updated CSpawnRegion::FindItemSpotToSpawn() function in cSpawnRegion.cpp to prevent duplicate spawning of exact same item in exact same location
Updated sectionid of all potion and scroll aliases to match main item, so they'll get correctly picked up by NPC shopkeepers (dfndata/items/magic/potions.dfn and scrolls.dfn)
Specified sectionid for backpacks, so it also gets applied to packs added using the alias [backpack] (dfndata/items/misc/provisions.dfn)
Fixed a code issue that prevented players from selling empty containers to NPC shopkeepers willing to buy such containers
Fixed an issue where field-spells (wall of stone, poison field, etc) would ignore dynamic/static items that should block these
Fixed an issue where field-spells could be cast into houses from the outside by standing next to a wall and targeting self
Fixed a War/Peace-mode desync between client and server by having server always notify client (using war-toggle packet) when the "at war" flag is toggled for player character
Fixed an issue with hiding skill that wouldn't allow player to hide after having acquired self as target in combat (through spellcasting, for instance) (Thanks, Dragon Slayer!)
Fixed an issue where mana/reagents were consumed and skillcheck performed before all spellcast-validations had succeeded, resulting in the occasional loss of reagents/mana when spellcasting was disallowed (code and js/magic/clumsy.js and level1targ.js)
Fixed an issue with lack of criminal-flagging for casting of hostile spells scripted in JS (clumsy, magic arrow, feeblemind) vs blue targets (js/magic/clumsy.js and level1targ.js)
Fixed some issues with Line-of-Sight checking code that returned incorrect results, which amongst other things affected spellcasting in areas with uneven terrain
Fixed some issues with movement code and climbing of ladders, in particular the rope ladder in the 2-story log cabin. Code now sets a "is climbing" flag when character steps onto a rope ladder, and uses that to help resolve some edge cases, and then unsets it when they step off.
Renamed section headers of some map-items in DFNs from "locationname" to "locationnamemap" for clarity (example: "britain" to "britainmap")
Fixed broken "map wrapping" when sailing to edges of map in Felucca or Trammel
Fixed a server crash related to attempts at reading data from invalid map tiles
2025-06-27 08:40:02 +08:00
|
|
|
if( elev >= z && tile.altitude <= z && ( tile.CheckFlag( TF_BLOCKING ) || tile.CheckFlag( TF_WET ) || tile.CheckFlag( TF_ROOF )))
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
|
|
|
|
rValue = true;
|
2022-06-15 11:24:57 -04:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
Small update
Fixed an issue with an internal movement check that prevented characters from moving in valid map areas in Felucca/Trammel from X 6144 to X 7168
Fixed an issue where .instanceID property was misspelled in 'xgo GM command script, causing characters to be teleported to an out of bounds area where they would no longer be saved (js/commands/targeting/x.js)
Added some additional error-checking to .Teleport()/.SetLocation() JS Method to prevent script-accidents from sending characters out of bounds.
Updated Poisoning skill to add poison-charges to weapons being poisoned. Charges are consumed when applying poison in combat (js/skill/poisoning.js)
Updated combat code to consume poison-charges if a poisoned weapon is used to poison an opponent
Updated shoplists for Blacksmiths and Weaponsmiths - they now buy/sell longswords (dfndata/items/shoplist.dfn)
Updated MageShopping shoplist for mage vendors - they now buy/sell mass curse scrolls (dfndata/items/shoplist.dfn)
Added new Spawn Region DFN tag that can specify which era or eras of UO (Multiple comma-separated entries supported) a given spawn region is valid for. Spawn region not valid for core shard era will be ignored. Syntax:
ERAS=UO,T2A,UOR,LBR,AOS,SE,ML,SA,HS,TOL
Added new Spawn Region DFN tag that allows using another spawn region as a "parent". All properties of this parent will be inherited except for these, which are ignored: ERAS, NPCLIST, ITEMLIST, NPC and ITEM. Syntax for new tag:
GET=# // Inherit a specified spawn region
Added spawn region for animal trainer vendor in Vesper stable
Added spawn region for fur trader/tanner vendors in The Best Hides of Britain
Added spawn region for spinner vendor in The Lord's Clothier's and The Right Fit shops in Britain
Added spawn region for tanner NPC to Nujel'm Tannery (and fixed leatherworker spawn region for same area)
Added spawn regions for banker NPCs in East Bank of Britain, First Bank of Moonglow, Jhelom Bank and Jeweler, Bank of Skara Brae
Added spawn regions for stables, tailor and blacksmith inside Castle British
Added spawn regions for mage shops, mage guilds and farm houses in Moonglow
Added spawn regions for misc vendors and townfolk in multiple cities
Added spawn regions for Fire Island
Updated spawn regions for Dagger Isle/Ice Island
Added spawn regions for forests and jungles in southern Britannia and on various islands including Bucc's Den, Moonglow, Serpent's Hold, and misc unpopulated islands
Added spawn regions for area east of Skara Brae, around Hedge Maze and south of Britain
Added spawn regions for wandering healers outside every dungeon entrance in Britannia and Lost Lands
Re-integrated ocean spawn regions for ocean creatures (dolphin, walrus, water elemental, sea serpent) from the original community-based spawn file
Added reagent spawns in overworld spawn regions in Britannia/Lost Lands
Added special reagent spawns in swamp areas
Added additional overworld spawn regions in Britannia/Lost Lands
Added spawn regions for Khaldun dungeon that spawn some new and some old NPCs:
Old: Zombies, skeletons, skeletal mages, skeletal knights, ancient liches
New: Cursed (and named) NPCs, shadowfiends, zealots of khaldun (knights/summoners), tentacles of the harrower
Updated size and positions of some existing overworld spawn regions
Fixed incorrect spawn region size for small island south of Trinsic
Added switch/door puzzle functionality in Khaldun dungeon using new switch/door combo script (js/item/dungeons/switch_door_combo.js)
Added "smart objects" in Khaldun dungeon that activate when you come close enough (js/item/dungeons/smart_activate_item.js)
Added teleport locations within Khaldun dungeon (js/teleport.scp)
Added custom AIs to existing NPC spawning in Khaldun dungeon:
Ancient Lich (summons other undead, and can turn into one of them for disguise)
Added DFN entries for new NPCs spawning in Khaldun dungeon, some with custom AIs:
[tentacles_of_the_harrower] -> Tentacles of the Harrower (life steal)
[shadowfiend] -> Shadowfiends (seek out and reveal hidden players)
[zealot_knight]/[zealot_summoner] -> Zealots of Khaldun (turn into undead on death, male/female variants)
[cursed] -> Cursed (male/female variants)
[spectralarmor] -> Spectral Armor
Added DFN entries for new (named) NPCs spawning in Khaldun dungeon:
[lysander_gathenwale] -> Lysander Gathenwale
[grimmoch_drummel] -> Grimmoch Drummel
[morg_bergen] -> Morg Bergen
[tavara_sewel] -> Tavara Sewel
Added new NPC DFN entries:
[leatherworker] -> alias for male/female leatherworker vendors
[mapmaker] -> alias for male/female mapmaker vendors
Added new Race DFN entries:
[RACE 29] -> Cursed (enemies of RACE 30)
[RACE 30] -> Zealots (enemies of RACE 29)
Added new book DFN entries for Khaldun journals of Lysander, Tavara and Grimmoch - available as loot from the respective NPCs (dfndata/misc/books.dfn and dfndata/items/misc/books.dfn)
Added 25% chance for hit-animations and hit-SFX to play for targets in combat, instead of playing every time - can get very spammy
Monsters with actual weapons equipped (like Ophidian Enforcer with Halberd/Bardiche) will now get appropriate combat SFX for hitting with that weapon
Updated Healing skill to base cure/resurrection skill requirements on the calculated skill, rather than base skill (js/skill/healing.js)
Fixed an issue where healing with bandages and dying in the process would not properly reset the healing-related tags and skills used
Updated healing script to show a resurrection confirmation menu for players targeted with bandages for resurrect (js/skill/healing.js)
All skill usage states now reset on death, to prevent cases of players being "busy" while trying to use skills that got stuck due to script bugs.
The 'regspawn GM command now supports a new parameter called "max". Updated command syntax:
'regspawn # // perform a single respawn cycle in a specific spawn region
'regspawn all // perform a single respawn cycle across all spawn regions
'regspawn max // respawn ALL spawn regions to MAX capacity in one go
Added new UOX.INI setting that determines the maximum range at which NPCs can initiate attacks on players/NPCs (the old MAXRANGE=10 setting now instead defines max range at which players can initiate attacks on players/NPCs):
MAXNPCAGGRORANGE=10
Optimized performance by significantly reducing the number of line-of-sight checks performed by characters, especially in combat scenarios, or when evaluating potential targets for NPC AIs. The amount of checks done is also affected by the new ini setting for max aggro range.
Fixed an issue where both NPC and player characters would instantly drop one hunger level (from 6 to 5) upon creation since hungerrate was not initialized until after first hunger-event
Updated character priv property from UI16 to UI32, and added a new flag that determines if fame/karma title is hidden for character:
HIDEFAMEKARMATITLE (0x10000)
NPCs will no longer aggro other NPCs if the Z difference between them is greater or equal to 20 (i.e. they're on different floors), unless both are using ranged weapons and both are in range
Fixed an issue where players could get discounts from shopkeepers even though neither player nor shopkeeper were members of a NPC guild (js/npc/ai/shopkeeper.js)
Fixed an issue where the "premium" a player would get when selling items to a shopkeeper in the same NPC guild as them would be 110% extra on top of the item's value, instead of the intended 10% (js/npc/ai/shopkeeper.js) (Thanks, cobrag0318!)
Added missing tall straw hat to tailoring crafting scripts (Thanks, Dragon Slayer!)
Improved error reporting during compilation of individual scripts being reloaded - will now show more context and line number
onCombatEnd JS Event now also triggers when NPCs ignore their target and/or evade during combat
Updated 'decorate command to support saving/loading custom tags on items for world templates. These are stored after a @ symbol in the world template, each custom tag separated by a | symbol, and with each custom tag saved using this syntax: key$type$value
Updated resource-harvesting scripts to use script-specific global (const) variables, to avoid interference between different scripts (js/server/resource/*)
Added new resource-harvesting scripts and added spawn regions for these in fields on farms all over Britannia/Lost Lands
cabbages (js/server/resource/cabbages.js)
canteloupes (js/server/resource/canteloupes.js)
carrots (js/server/resource/carrots.js)
garlic (js/server/resource/garlic.js)
gourds (js/server/resource/gourds.js)
honeydew melons (js/server/resource/honeydewmelon.js)
onions (js/server/resource/onions.js)
pumpkins (js/server/resource/pumpkins.js)
squashes (js/server/resource/squashes.js)
turnips (js/server/resource/turnips.js)
watermelons (js/server/resource/watermelon.js)
Updated CSpawnRegion::FindItemSpotToSpawn() function in cSpawnRegion.cpp to prevent duplicate spawning of exact same item in exact same location
Updated sectionid of all potion and scroll aliases to match main item, so they'll get correctly picked up by NPC shopkeepers (dfndata/items/magic/potions.dfn and scrolls.dfn)
Specified sectionid for backpacks, so it also gets applied to packs added using the alias [backpack] (dfndata/items/misc/provisions.dfn)
Fixed a code issue that prevented players from selling empty containers to NPC shopkeepers willing to buy such containers
Fixed an issue where field-spells (wall of stone, poison field, etc) would ignore dynamic/static items that should block these
Fixed an issue where field-spells could be cast into houses from the outside by standing next to a wall and targeting self
Fixed a War/Peace-mode desync between client and server by having server always notify client (using war-toggle packet) when the "at war" flag is toggled for player character
Fixed an issue with hiding skill that wouldn't allow player to hide after having acquired self as target in combat (through spellcasting, for instance) (Thanks, Dragon Slayer!)
Fixed an issue where mana/reagents were consumed and skillcheck performed before all spellcast-validations had succeeded, resulting in the occasional loss of reagents/mana when spellcasting was disallowed (code and js/magic/clumsy.js and level1targ.js)
Fixed an issue with lack of criminal-flagging for casting of hostile spells scripted in JS (clumsy, magic arrow, feeblemind) vs blue targets (js/magic/clumsy.js and level1targ.js)
Fixed some issues with Line-of-Sight checking code that returned incorrect results, which amongst other things affected spellcasting in areas with uneven terrain
Fixed some issues with movement code and climbing of ladders, in particular the rope ladder in the 2-story log cabin. Code now sets a "is climbing" flag when character steps onto a rope ladder, and uses that to help resolve some edge cases, and then unsets it when they step off.
Renamed section headers of some map-items in DFNs from "locationname" to "locationnamemap" for clarity (example: "britain" to "britainmap")
Fixed broken "map wrapping" when sailing to edges of map in Felucca or Trammel
Fixed a server crash related to attempts at reading data from invalid map tiles
2025-06-27 08:40:02 +08:00
|
|
|
if( elev >= z && tile.altitude <= z && ( tile.CheckFlag( TF_BLOCKING ) && !tile.CheckFlag( TF_WET ) || tile.CheckFlag( TF_ROOF )))
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
|
|
|
|
rValue = true;
|
2022-06-15 11:24:57 -04:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return rValue;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::DoesDynamicBlock()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Checks if there are any dynamic tiles at given coordinates that block movement
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::DoesDynamicBlock( std::int16_t x, std::int16_t y, std::int8_t z, std::uint8_t worldNumber, std::uint16_t instanceId, bool checkWater, bool waterWalk, bool checkOnlyMultis, bool checkOnlyNonMultis ) -> bool
|
|
|
|
|
{
|
|
|
|
|
auto rValue = false;
|
2022-06-15 11:24:57 -04:00
|
|
|
// get the tile id of any dynamic tiles at this spot
|
2022-10-24 18:39:33 +08:00
|
|
|
auto dtItem = DynTile( x, y, z, worldNumber, instanceId, checkOnlyMultis, checkOnlyNonMultis );
|
|
|
|
|
if( ValidateObject( dtItem ))
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
// Don't allow placing houses on top of immovable, visible dynamic items
|
2022-10-24 18:39:33 +08:00
|
|
|
if( dtItem->GetMovable() == 2 && dtItem->GetVisible() == 0 )
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
// Ignore items that are permanently invisible or visible to GMs only
|
|
|
|
|
if( dtItem->GetVisible() == 1 || dtItem->GetVisible() == 3 )
|
|
|
|
|
return false;
|
|
|
|
|
|
Small update
Fixed an issue with an internal movement check that prevented characters from moving in valid map areas in Felucca/Trammel from X 6144 to X 7168
Fixed an issue where .instanceID property was misspelled in 'xgo GM command script, causing characters to be teleported to an out of bounds area where they would no longer be saved (js/commands/targeting/x.js)
Added some additional error-checking to .Teleport()/.SetLocation() JS Method to prevent script-accidents from sending characters out of bounds.
Updated Poisoning skill to add poison-charges to weapons being poisoned. Charges are consumed when applying poison in combat (js/skill/poisoning.js)
Updated combat code to consume poison-charges if a poisoned weapon is used to poison an opponent
Updated shoplists for Blacksmiths and Weaponsmiths - they now buy/sell longswords (dfndata/items/shoplist.dfn)
Updated MageShopping shoplist for mage vendors - they now buy/sell mass curse scrolls (dfndata/items/shoplist.dfn)
Added new Spawn Region DFN tag that can specify which era or eras of UO (Multiple comma-separated entries supported) a given spawn region is valid for. Spawn region not valid for core shard era will be ignored. Syntax:
ERAS=UO,T2A,UOR,LBR,AOS,SE,ML,SA,HS,TOL
Added new Spawn Region DFN tag that allows using another spawn region as a "parent". All properties of this parent will be inherited except for these, which are ignored: ERAS, NPCLIST, ITEMLIST, NPC and ITEM. Syntax for new tag:
GET=# // Inherit a specified spawn region
Added spawn region for animal trainer vendor in Vesper stable
Added spawn region for fur trader/tanner vendors in The Best Hides of Britain
Added spawn region for spinner vendor in The Lord's Clothier's and The Right Fit shops in Britain
Added spawn region for tanner NPC to Nujel'm Tannery (and fixed leatherworker spawn region for same area)
Added spawn regions for banker NPCs in East Bank of Britain, First Bank of Moonglow, Jhelom Bank and Jeweler, Bank of Skara Brae
Added spawn regions for stables, tailor and blacksmith inside Castle British
Added spawn regions for mage shops, mage guilds and farm houses in Moonglow
Added spawn regions for misc vendors and townfolk in multiple cities
Added spawn regions for Fire Island
Updated spawn regions for Dagger Isle/Ice Island
Added spawn regions for forests and jungles in southern Britannia and on various islands including Bucc's Den, Moonglow, Serpent's Hold, and misc unpopulated islands
Added spawn regions for area east of Skara Brae, around Hedge Maze and south of Britain
Added spawn regions for wandering healers outside every dungeon entrance in Britannia and Lost Lands
Re-integrated ocean spawn regions for ocean creatures (dolphin, walrus, water elemental, sea serpent) from the original community-based spawn file
Added reagent spawns in overworld spawn regions in Britannia/Lost Lands
Added special reagent spawns in swamp areas
Added additional overworld spawn regions in Britannia/Lost Lands
Added spawn regions for Khaldun dungeon that spawn some new and some old NPCs:
Old: Zombies, skeletons, skeletal mages, skeletal knights, ancient liches
New: Cursed (and named) NPCs, shadowfiends, zealots of khaldun (knights/summoners), tentacles of the harrower
Updated size and positions of some existing overworld spawn regions
Fixed incorrect spawn region size for small island south of Trinsic
Added switch/door puzzle functionality in Khaldun dungeon using new switch/door combo script (js/item/dungeons/switch_door_combo.js)
Added "smart objects" in Khaldun dungeon that activate when you come close enough (js/item/dungeons/smart_activate_item.js)
Added teleport locations within Khaldun dungeon (js/teleport.scp)
Added custom AIs to existing NPC spawning in Khaldun dungeon:
Ancient Lich (summons other undead, and can turn into one of them for disguise)
Added DFN entries for new NPCs spawning in Khaldun dungeon, some with custom AIs:
[tentacles_of_the_harrower] -> Tentacles of the Harrower (life steal)
[shadowfiend] -> Shadowfiends (seek out and reveal hidden players)
[zealot_knight]/[zealot_summoner] -> Zealots of Khaldun (turn into undead on death, male/female variants)
[cursed] -> Cursed (male/female variants)
[spectralarmor] -> Spectral Armor
Added DFN entries for new (named) NPCs spawning in Khaldun dungeon:
[lysander_gathenwale] -> Lysander Gathenwale
[grimmoch_drummel] -> Grimmoch Drummel
[morg_bergen] -> Morg Bergen
[tavara_sewel] -> Tavara Sewel
Added new NPC DFN entries:
[leatherworker] -> alias for male/female leatherworker vendors
[mapmaker] -> alias for male/female mapmaker vendors
Added new Race DFN entries:
[RACE 29] -> Cursed (enemies of RACE 30)
[RACE 30] -> Zealots (enemies of RACE 29)
Added new book DFN entries for Khaldun journals of Lysander, Tavara and Grimmoch - available as loot from the respective NPCs (dfndata/misc/books.dfn and dfndata/items/misc/books.dfn)
Added 25% chance for hit-animations and hit-SFX to play for targets in combat, instead of playing every time - can get very spammy
Monsters with actual weapons equipped (like Ophidian Enforcer with Halberd/Bardiche) will now get appropriate combat SFX for hitting with that weapon
Updated Healing skill to base cure/resurrection skill requirements on the calculated skill, rather than base skill (js/skill/healing.js)
Fixed an issue where healing with bandages and dying in the process would not properly reset the healing-related tags and skills used
Updated healing script to show a resurrection confirmation menu for players targeted with bandages for resurrect (js/skill/healing.js)
All skill usage states now reset on death, to prevent cases of players being "busy" while trying to use skills that got stuck due to script bugs.
The 'regspawn GM command now supports a new parameter called "max". Updated command syntax:
'regspawn # // perform a single respawn cycle in a specific spawn region
'regspawn all // perform a single respawn cycle across all spawn regions
'regspawn max // respawn ALL spawn regions to MAX capacity in one go
Added new UOX.INI setting that determines the maximum range at which NPCs can initiate attacks on players/NPCs (the old MAXRANGE=10 setting now instead defines max range at which players can initiate attacks on players/NPCs):
MAXNPCAGGRORANGE=10
Optimized performance by significantly reducing the number of line-of-sight checks performed by characters, especially in combat scenarios, or when evaluating potential targets for NPC AIs. The amount of checks done is also affected by the new ini setting for max aggro range.
Fixed an issue where both NPC and player characters would instantly drop one hunger level (from 6 to 5) upon creation since hungerrate was not initialized until after first hunger-event
Updated character priv property from UI16 to UI32, and added a new flag that determines if fame/karma title is hidden for character:
HIDEFAMEKARMATITLE (0x10000)
NPCs will no longer aggro other NPCs if the Z difference between them is greater or equal to 20 (i.e. they're on different floors), unless both are using ranged weapons and both are in range
Fixed an issue where players could get discounts from shopkeepers even though neither player nor shopkeeper were members of a NPC guild (js/npc/ai/shopkeeper.js)
Fixed an issue where the "premium" a player would get when selling items to a shopkeeper in the same NPC guild as them would be 110% extra on top of the item's value, instead of the intended 10% (js/npc/ai/shopkeeper.js) (Thanks, cobrag0318!)
Added missing tall straw hat to tailoring crafting scripts (Thanks, Dragon Slayer!)
Improved error reporting during compilation of individual scripts being reloaded - will now show more context and line number
onCombatEnd JS Event now also triggers when NPCs ignore their target and/or evade during combat
Updated 'decorate command to support saving/loading custom tags on items for world templates. These are stored after a @ symbol in the world template, each custom tag separated by a | symbol, and with each custom tag saved using this syntax: key$type$value
Updated resource-harvesting scripts to use script-specific global (const) variables, to avoid interference between different scripts (js/server/resource/*)
Added new resource-harvesting scripts and added spawn regions for these in fields on farms all over Britannia/Lost Lands
cabbages (js/server/resource/cabbages.js)
canteloupes (js/server/resource/canteloupes.js)
carrots (js/server/resource/carrots.js)
garlic (js/server/resource/garlic.js)
gourds (js/server/resource/gourds.js)
honeydew melons (js/server/resource/honeydewmelon.js)
onions (js/server/resource/onions.js)
pumpkins (js/server/resource/pumpkins.js)
squashes (js/server/resource/squashes.js)
turnips (js/server/resource/turnips.js)
watermelons (js/server/resource/watermelon.js)
Updated CSpawnRegion::FindItemSpotToSpawn() function in cSpawnRegion.cpp to prevent duplicate spawning of exact same item in exact same location
Updated sectionid of all potion and scroll aliases to match main item, so they'll get correctly picked up by NPC shopkeepers (dfndata/items/magic/potions.dfn and scrolls.dfn)
Specified sectionid for backpacks, so it also gets applied to packs added using the alias [backpack] (dfndata/items/misc/provisions.dfn)
Fixed a code issue that prevented players from selling empty containers to NPC shopkeepers willing to buy such containers
Fixed an issue where field-spells (wall of stone, poison field, etc) would ignore dynamic/static items that should block these
Fixed an issue where field-spells could be cast into houses from the outside by standing next to a wall and targeting self
Fixed a War/Peace-mode desync between client and server by having server always notify client (using war-toggle packet) when the "at war" flag is toggled for player character
Fixed an issue with hiding skill that wouldn't allow player to hide after having acquired self as target in combat (through spellcasting, for instance) (Thanks, Dragon Slayer!)
Fixed an issue where mana/reagents were consumed and skillcheck performed before all spellcast-validations had succeeded, resulting in the occasional loss of reagents/mana when spellcasting was disallowed (code and js/magic/clumsy.js and level1targ.js)
Fixed an issue with lack of criminal-flagging for casting of hostile spells scripted in JS (clumsy, magic arrow, feeblemind) vs blue targets (js/magic/clumsy.js and level1targ.js)
Fixed some issues with Line-of-Sight checking code that returned incorrect results, which amongst other things affected spellcasting in areas with uneven terrain
Fixed some issues with movement code and climbing of ladders, in particular the rope ladder in the 2-story log cabin. Code now sets a "is climbing" flag when character steps onto a rope ladder, and uses that to help resolve some edge cases, and then unsets it when they step off.
Renamed section headers of some map-items in DFNs from "locationname" to "locationnamemap" for clarity (example: "britain" to "britainmap")
Fixed broken "map wrapping" when sailing to edges of map in Felucca or Trammel
Fixed a server crash related to attempts at reading data from invalid map tiles
2025-06-27 08:40:02 +08:00
|
|
|
auto dtItemZ = dtItem->GetZ();
|
2022-10-24 18:39:33 +08:00
|
|
|
rValue = false;
|
|
|
|
|
const UI16 dt = dtItem->GetId();
|
|
|
|
|
if( IsValidTile( dt ) && dt != 0 )
|
|
|
|
|
{
|
|
|
|
|
auto tile = SeekTile( dt );
|
|
|
|
|
if( waterWalk )
|
|
|
|
|
{
|
|
|
|
|
if( !tile.CheckFlag( TF_WET ))
|
|
|
|
|
{
|
|
|
|
|
rValue = true;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
Small update
Fixed an issue with an internal movement check that prevented characters from moving in valid map areas in Felucca/Trammel from X 6144 to X 7168
Fixed an issue where .instanceID property was misspelled in 'xgo GM command script, causing characters to be teleported to an out of bounds area where they would no longer be saved (js/commands/targeting/x.js)
Added some additional error-checking to .Teleport()/.SetLocation() JS Method to prevent script-accidents from sending characters out of bounds.
Updated Poisoning skill to add poison-charges to weapons being poisoned. Charges are consumed when applying poison in combat (js/skill/poisoning.js)
Updated combat code to consume poison-charges if a poisoned weapon is used to poison an opponent
Updated shoplists for Blacksmiths and Weaponsmiths - they now buy/sell longswords (dfndata/items/shoplist.dfn)
Updated MageShopping shoplist for mage vendors - they now buy/sell mass curse scrolls (dfndata/items/shoplist.dfn)
Added new Spawn Region DFN tag that can specify which era or eras of UO (Multiple comma-separated entries supported) a given spawn region is valid for. Spawn region not valid for core shard era will be ignored. Syntax:
ERAS=UO,T2A,UOR,LBR,AOS,SE,ML,SA,HS,TOL
Added new Spawn Region DFN tag that allows using another spawn region as a "parent". All properties of this parent will be inherited except for these, which are ignored: ERAS, NPCLIST, ITEMLIST, NPC and ITEM. Syntax for new tag:
GET=# // Inherit a specified spawn region
Added spawn region for animal trainer vendor in Vesper stable
Added spawn region for fur trader/tanner vendors in The Best Hides of Britain
Added spawn region for spinner vendor in The Lord's Clothier's and The Right Fit shops in Britain
Added spawn region for tanner NPC to Nujel'm Tannery (and fixed leatherworker spawn region for same area)
Added spawn regions for banker NPCs in East Bank of Britain, First Bank of Moonglow, Jhelom Bank and Jeweler, Bank of Skara Brae
Added spawn regions for stables, tailor and blacksmith inside Castle British
Added spawn regions for mage shops, mage guilds and farm houses in Moonglow
Added spawn regions for misc vendors and townfolk in multiple cities
Added spawn regions for Fire Island
Updated spawn regions for Dagger Isle/Ice Island
Added spawn regions for forests and jungles in southern Britannia and on various islands including Bucc's Den, Moonglow, Serpent's Hold, and misc unpopulated islands
Added spawn regions for area east of Skara Brae, around Hedge Maze and south of Britain
Added spawn regions for wandering healers outside every dungeon entrance in Britannia and Lost Lands
Re-integrated ocean spawn regions for ocean creatures (dolphin, walrus, water elemental, sea serpent) from the original community-based spawn file
Added reagent spawns in overworld spawn regions in Britannia/Lost Lands
Added special reagent spawns in swamp areas
Added additional overworld spawn regions in Britannia/Lost Lands
Added spawn regions for Khaldun dungeon that spawn some new and some old NPCs:
Old: Zombies, skeletons, skeletal mages, skeletal knights, ancient liches
New: Cursed (and named) NPCs, shadowfiends, zealots of khaldun (knights/summoners), tentacles of the harrower
Updated size and positions of some existing overworld spawn regions
Fixed incorrect spawn region size for small island south of Trinsic
Added switch/door puzzle functionality in Khaldun dungeon using new switch/door combo script (js/item/dungeons/switch_door_combo.js)
Added "smart objects" in Khaldun dungeon that activate when you come close enough (js/item/dungeons/smart_activate_item.js)
Added teleport locations within Khaldun dungeon (js/teleport.scp)
Added custom AIs to existing NPC spawning in Khaldun dungeon:
Ancient Lich (summons other undead, and can turn into one of them for disguise)
Added DFN entries for new NPCs spawning in Khaldun dungeon, some with custom AIs:
[tentacles_of_the_harrower] -> Tentacles of the Harrower (life steal)
[shadowfiend] -> Shadowfiends (seek out and reveal hidden players)
[zealot_knight]/[zealot_summoner] -> Zealots of Khaldun (turn into undead on death, male/female variants)
[cursed] -> Cursed (male/female variants)
[spectralarmor] -> Spectral Armor
Added DFN entries for new (named) NPCs spawning in Khaldun dungeon:
[lysander_gathenwale] -> Lysander Gathenwale
[grimmoch_drummel] -> Grimmoch Drummel
[morg_bergen] -> Morg Bergen
[tavara_sewel] -> Tavara Sewel
Added new NPC DFN entries:
[leatherworker] -> alias for male/female leatherworker vendors
[mapmaker] -> alias for male/female mapmaker vendors
Added new Race DFN entries:
[RACE 29] -> Cursed (enemies of RACE 30)
[RACE 30] -> Zealots (enemies of RACE 29)
Added new book DFN entries for Khaldun journals of Lysander, Tavara and Grimmoch - available as loot from the respective NPCs (dfndata/misc/books.dfn and dfndata/items/misc/books.dfn)
Added 25% chance for hit-animations and hit-SFX to play for targets in combat, instead of playing every time - can get very spammy
Monsters with actual weapons equipped (like Ophidian Enforcer with Halberd/Bardiche) will now get appropriate combat SFX for hitting with that weapon
Updated Healing skill to base cure/resurrection skill requirements on the calculated skill, rather than base skill (js/skill/healing.js)
Fixed an issue where healing with bandages and dying in the process would not properly reset the healing-related tags and skills used
Updated healing script to show a resurrection confirmation menu for players targeted with bandages for resurrect (js/skill/healing.js)
All skill usage states now reset on death, to prevent cases of players being "busy" while trying to use skills that got stuck due to script bugs.
The 'regspawn GM command now supports a new parameter called "max". Updated command syntax:
'regspawn # // perform a single respawn cycle in a specific spawn region
'regspawn all // perform a single respawn cycle across all spawn regions
'regspawn max // respawn ALL spawn regions to MAX capacity in one go
Added new UOX.INI setting that determines the maximum range at which NPCs can initiate attacks on players/NPCs (the old MAXRANGE=10 setting now instead defines max range at which players can initiate attacks on players/NPCs):
MAXNPCAGGRORANGE=10
Optimized performance by significantly reducing the number of line-of-sight checks performed by characters, especially in combat scenarios, or when evaluating potential targets for NPC AIs. The amount of checks done is also affected by the new ini setting for max aggro range.
Fixed an issue where both NPC and player characters would instantly drop one hunger level (from 6 to 5) upon creation since hungerrate was not initialized until after first hunger-event
Updated character priv property from UI16 to UI32, and added a new flag that determines if fame/karma title is hidden for character:
HIDEFAMEKARMATITLE (0x10000)
NPCs will no longer aggro other NPCs if the Z difference between them is greater or equal to 20 (i.e. they're on different floors), unless both are using ranged weapons and both are in range
Fixed an issue where players could get discounts from shopkeepers even though neither player nor shopkeeper were members of a NPC guild (js/npc/ai/shopkeeper.js)
Fixed an issue where the "premium" a player would get when selling items to a shopkeeper in the same NPC guild as them would be 110% extra on top of the item's value, instead of the intended 10% (js/npc/ai/shopkeeper.js) (Thanks, cobrag0318!)
Added missing tall straw hat to tailoring crafting scripts (Thanks, Dragon Slayer!)
Improved error reporting during compilation of individual scripts being reloaded - will now show more context and line number
onCombatEnd JS Event now also triggers when NPCs ignore their target and/or evade during combat
Updated 'decorate command to support saving/loading custom tags on items for world templates. These are stored after a @ symbol in the world template, each custom tag separated by a | symbol, and with each custom tag saved using this syntax: key$type$value
Updated resource-harvesting scripts to use script-specific global (const) variables, to avoid interference between different scripts (js/server/resource/*)
Added new resource-harvesting scripts and added spawn regions for these in fields on farms all over Britannia/Lost Lands
cabbages (js/server/resource/cabbages.js)
canteloupes (js/server/resource/canteloupes.js)
carrots (js/server/resource/carrots.js)
garlic (js/server/resource/garlic.js)
gourds (js/server/resource/gourds.js)
honeydew melons (js/server/resource/honeydewmelon.js)
onions (js/server/resource/onions.js)
pumpkins (js/server/resource/pumpkins.js)
squashes (js/server/resource/squashes.js)
turnips (js/server/resource/turnips.js)
watermelons (js/server/resource/watermelon.js)
Updated CSpawnRegion::FindItemSpotToSpawn() function in cSpawnRegion.cpp to prevent duplicate spawning of exact same item in exact same location
Updated sectionid of all potion and scroll aliases to match main item, so they'll get correctly picked up by NPC shopkeepers (dfndata/items/magic/potions.dfn and scrolls.dfn)
Specified sectionid for backpacks, so it also gets applied to packs added using the alias [backpack] (dfndata/items/misc/provisions.dfn)
Fixed a code issue that prevented players from selling empty containers to NPC shopkeepers willing to buy such containers
Fixed an issue where field-spells (wall of stone, poison field, etc) would ignore dynamic/static items that should block these
Fixed an issue where field-spells could be cast into houses from the outside by standing next to a wall and targeting self
Fixed a War/Peace-mode desync between client and server by having server always notify client (using war-toggle packet) when the "at war" flag is toggled for player character
Fixed an issue with hiding skill that wouldn't allow player to hide after having acquired self as target in combat (through spellcasting, for instance) (Thanks, Dragon Slayer!)
Fixed an issue where mana/reagents were consumed and skillcheck performed before all spellcast-validations had succeeded, resulting in the occasional loss of reagents/mana when spellcasting was disallowed (code and js/magic/clumsy.js and level1targ.js)
Fixed an issue with lack of criminal-flagging for casting of hostile spells scripted in JS (clumsy, magic arrow, feeblemind) vs blue targets (js/magic/clumsy.js and level1targ.js)
Fixed some issues with Line-of-Sight checking code that returned incorrect results, which amongst other things affected spellcasting in areas with uneven terrain
Fixed some issues with movement code and climbing of ladders, in particular the rope ladder in the 2-story log cabin. Code now sets a "is climbing" flag when character steps onto a rope ladder, and uses that to help resolve some edge cases, and then unsets it when they step off.
Renamed section headers of some map-items in DFNs from "locationname" to "locationnamemap" for clarity (example: "britain" to "britainmap")
Fixed broken "map wrapping" when sailing to edges of map in Felucca or Trammel
Fixed a server crash related to attempts at reading data from invalid map tiles
2025-06-27 08:40:02 +08:00
|
|
|
auto elev = static_cast<SI08>( dtItemZ + tile.ClimbHeight() );
|
|
|
|
|
if( elev >= z && dtItemZ <= z && ( tile.CheckFlag( TF_ROOF ) || tile.CheckFlag( TF_BLOCKING ) || ( checkWater && tile.CheckFlag( TF_WET ))) /*|| !tile.CheckFlag( TF_SURFACE ) */ )
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
|
|
|
|
rValue = true;
|
Various changes
Fixed an issue with JS Function DeleteFile(), which would stop calling script from working if no file was found for deletion. Could break demolishing of houses, amongst other things
Fixed an issue with DoSEErrorMessage() function that prevented JS function error messages from being displayed in UOX3 console if message size was below 512
Fixed a bug that allowed players to place items on the same slot of walls when using a client that doesn't automatically restrict this
When dropping items, UOX3 will now look for a valid surface to drop them on, and move the item to said valid surface if applicable
Fixed an issue with loading of MultiCollections.uop where max boundaries of each multi was not set on load, preventing features that relied on finding corners of building from working (like automatic ban location detection for houses)
Added new function in mapstuff.cpp to check flags on dynamic items, and exposed it as a JS Function with same name and parameters:
CheckDynamicFlag( SI16 x, SI16 y, SI08 oldz, UI08 worldNumber, UI16 instanceID, TileFlags toCheck );
Fixed an issue where items were not always properly added to/removed from map regions when picked up or dropped
Added new helper function in dist.cpp to find 3D distance between two points:
getDist3D( point a, point b )
Added JS Function - DistanceBetween() - to find distance between two sets of coordinates, or two objects:
DistanceBetween( x1, y1, x2, y2 )
DistanceBetween( x1, y1, z1, x2, y2, z2 )
DistanceBetween( sourceObject, targObject )
DistanceBetween( sourceObject, targObject, checkZ )
Added Item JS Method - GetTileName() - to get name of an item directly from tiledata
Added new UOX.INI setting that defines the lower limit for when a purchase will withdraw money from bank instead of backpack:
BANKBUYTHRESHOLD=2000
Split the UOX.INI setting CONSOLELOG into three parts, to enable/disable different forms of logging:
CONSOLELOG=1/0 // Toggles logging of console messages, warnings and errors
NETWORKLOG=1/0 // Toggles logging of network traffic
SPEECHLOG=1/0 // Toggles logging of player/staff speech
2021-06-27 23:23:31 +08:00
|
|
|
}
|
Housing Revamp and more
Updated JS SysMessage function to accept up to 10 extra, optional arguments, which can be used with dictionary messages that require additional parameters like %s or %i
Added new type of house privilege in cMultiObj.cpp to keep track of friends of the multi - HOUSEPRIV_FRIEND - which is stored during worldsaves as one or more Friend=<player serial> tags in house.wsc
Added new type of house privilege in cMultiObj.cpp to keep track of guests of the multi - HOUSEPRIV_GUEST - which is stored during worldsaves as one or more Guest=<player serial> tags in house.wsc
When items are created for houses upon house placement, a reference to the multi's serial is now stored in the house sign's MORE property to allow easier tracking of which house a particular sign belongs to
Added tracking of new, persistent properties for houses via cMultiObj.cpp/h:
lockdowns, secure containers, vendors, guests, friends, owners, ban location, public status, number of visits, timestamps
Added a multitude of new methods in cMultiObj.cpp/h to assist in improving the functionality of houses
Added new tags for houses in house.dfn (default values applied if tag not specified):
MAXSECURECONTAINERS=4 - Max amount of secure containers allowed in a multi
MAXLOCKDOWNS=256 - Max amount of lockdowns allowed in a multi
MAXVENDORS=10 - Max amount of vendors allowed in a multi
MAXBANS=50 - Max amount of bans in a multi's ban list
MAXFRIENDS=50 - Max amount of friends in a multi's friend list
MAXGUESTS=50 - Max amount of guests in a multi's guest list
MAXOWNERS=8 - Max amount of owners and co-owners in a multi's owner list
MAXTRASHCONTAINERS=1 - Max amount of trash containers allowed in multi
SCRIPT=<scriptID> - Assign a JS script-ID directly to a multi
FRONTDOOR - indicates that a door is the front door of a house. Cannot be locked in public houses!
INTERIORDOOR - indicates that a door is an interior door of a house. Can be locked in public houses.
BANX - Location X offset for multi's ban location, if not used, will try to use SE corner of multi instead
BANY - Location Y offset for multi's ban location, if not used, will try to use SE corner of multi instead
Added JS Event:
onHouseCommand( tSock, multiObj, cmdID ) - For handling spoken house commands via JS scripts attached to multi.
Updated JS Events:
onEntrance() - can now trigger both for multi being entered and/or object entering
onLeaving() - can now trigger both for multi being left and/or object entering
onSpeech() - can now also trigger for items (in addition to chars) with event & script attached, if UOX.INI setting ITEMSDETECTSPEECH is enabled
Added JS Multi methods:
.IsBoat() - Returns whether the item (or multi) is a boat
.IsOwner( playerToCheck ) - Returns whether a player is the owner of a multi
.IsOnOwnerList( playerToCheck ) - Returns whether a player is on the (co-)owner list of a multi
.IsOnFriendList( playerToCheck ) - Returns whether a player is on the friend list of a multi
.IsOnGuestList( playerToCheck ) - Returns whether a player is on the guest list of a multi
.IsOnBanList( playerToCheck ) - Returns whether a player is on the ban list of a multi
.AddToFriendList( playertoAdd ) - Adds player to the friend list of a multi
.RemoveFromFriendList( playertoRemove ) - Removes player from the friend list of a multi
.AddToGuestList( playertoAdd ) - Adds player to the guest list of a multi
.RemoveFromGuestList( playertoRemove ) - Removes player from the guest list of a multi
.ClearOwnerList() - Clears all entries from a multi's (co-)owner list
.ClearFriendList() - Clears all entries from a multi's friend list
.ClearGuestList() - Clears all entries from a multi's guest list
.ClearBanList() - Clears all entries from a multi's ban list
.SecureContainer( itemToSecure ) - Secures a container in a multi
.UnsecureContainer( itemToUnsecure ) - Unsecures a container in a multi
.IsSecureContainer( itemToCheck ) - Checks if specified item is a secure container in a multi
.LockDownItem( itemToLockDown) - Locks down an item in a multi
.ReleaseItem( itemToRelease ) - Releases a locked down item in a multi
.KillKeys() - Deletes ALL keys associated with a multi
.AddTrashCont( itemToAdd ) - Add trash container to multi's list of trash containers
.RemoveTrashCont( itemToRemove ) - Remove trash container from multi's list of trash containers
Added JS Item (Multi only) properties:
.lockdowns - Get the number of lockdowns in a multi
.maxLockdowns - Get/Set the max number of lockdowns allowed in a multi
.secureContainers - Get the number of secure containers in a multi
.maxSecureContainers - Get/Set the max number of secure containers allowed in a multi
.trashContainers - Get the number of trash containers in a multi
.maxTrashContainers - Get/Set the max number of trash containers allowed in a multi
.friends - Get the number of friends in a multi's friend list
.maxFriends - Get/Set the max number of friends allowed in a multi's friend list
.guests - Get the number of guests in a multi's guest list
.maxGuests - Get/Set the max number of guests allowed in a multi's guest list
.owners - Get the number of owners in a multi's owner list
.maxOwners - Get/Set the max number of owners allowed in a multi's owner list
.bans - Get the number of banned players in a multi's ban list
.maxBans - Get/Set the max number of banned players allowed in a multi's ban list
.vendors - Get the number of player vendors in a multi
.maxVendors - Get the max number of player vendors allowed in a multi
.deed - Get the item sectionID for deed used to place multi
.isPublic - Get/Set the private/public state of a multi
.buildTimestamp - Get the timestamp for when the house was originally placed
.tradeTimestamp - Get the timestamp for when the house was last traded to another player
.banX - Get/Set the ban location X offset for the multi
.banY - Get/Set the ban location Y offset for the multi
Added JS Character properties:
.multi = Get/Set the multi object the character is in
.accountNum = Get the account number the character belongs to
.housesOwned = Get a count of houses owned by the character
.housesCoOwned = Get a count of houses co-owned by the character
Updated JS cBaseObject Methods .FirstItem(), .NextItem() and .FinishedItems() to also support iterating through items in multis
Updated JS multi Methods .FirstChar(), .NextChar() and .FinishedChars() to support an additional parameter to specify what kind of characters to loop through:
"default" or no parameter - all characters inside the multi
"owner" - players on multi's owner list
"friend" - players on multi's friend list
"guest" - players on multi's guest list
"banned" - players on multi's ban list
Added new INI tags to a new section of uox.ini called [houses]
DECAYTIMERINHOUSE=3600 // Decay timer in seconds for non-locked down items inside houses
PROTECTPRIVATEHOUSES=1 // Toggles whether private houses will automatically boot unauthorized visitors (1) or not (0)
TRACKHOUSESPERACCOUNT=1 // Toggles whether to track (and restrict) house ownership per account (1) or per character (0)
MAXHOUSESOWNABLE=1 // Specifies the max amount of houses a player can own per account/char, depending on how house ownership is tracked
MAXHOUSESCOOWNABLE=10 // Specifies the max amount of houses a player can co-own per character
CANOWNANDCOOWNHOUSES=1 // Toggles whether players can own and co-own houses at the same time
COOWNHOUSESONSAMEACCOUNT=1 // Toggles whether characters on same account as house owner will be treated as co-owners
Added new INI tags in [settings] section of uox.ini:
ITEMSDETECTSPEECH=0 // If enabled, server will search for nearby items with onSpeech JS event running whenever a character speaks. Disabled by default.
MAXPLAYERPACKITEMS=125 // Defines max item capacity for player (and NPC) backpacks. Defaults to 125.
Moved most of the existing house functionality to JS and expanded upon it to reach feature parity with houses in regular UO around Publish 15/16, with various extras thrown in for good measure and all functionality being customizable:
js/server/house/house.js (15000) - handles detection of house commands and characters entering/leaving houses
js/server/house/houseSign.js (15001) - contains and handles all house-related gumps/menus and what is shown when players interact with house sign
js/server/house/houseCommands.js (15002) - handles functionality of house commands and other functionality such as transfer of ownership, demolishing house, etc.
js/server/house/houseDeed.js (15003) - handles initial rules that allow/disallow placement of additional houses for players
All house-related menus now fully handled through JS
All house commands and other functionality now fully handled through JS
Removed redundant hard-coded house functionality
Implemented Co-owners, friends, guests for houses, with access rules in place for entry, lockdowns, house commands, etc.
Implemented Private and Public houses
Implemented Secure Containers and Trash Barrels
Definable max lockdowns, secure containers, player vendors, bans, friends, guests, owners, trash containers and more - per house type
JS scripts can now be attached directly to houses
Doors in houses can be marked as front doors or interior doors, and will be treated differently with regards to private and public houses
Added new item to dfndata/items/containers/misc.dfn - [trashbarrel]
Added new JS script (js/items/trashbarrel.js) with trash barrel functionality for houses. Trash barrels that are marked as secure containers are only accessible by owners, co-owners and friends of the house. Various options available at top of script.
Updated js/items/axe.js to support chopping up trash barrels and house add-ons in houses owned by the player
Fixed an issue with house doors being left behind after demolishing houses while their doors were open
Fixed an issue where GMs could be banned from player houses
Added Line of Sight checks to speech, to give players some privacy in their own homes
Updated house placement code to more accurately check for other multis, dynamic and static objects when placing houses; now requires free space around each house that cannot be blocked by other houses or items that can block player movement, and disallows placement of houses on roads
Updated house placement code to move characters blocking house placement to SE corner of the house
Updated house placement code to disallow placing houses in guarded regions, or in dungeons
Added new DFN tag for regions to enable/disable player houses in specific regions: HOUSING=0/1
Added new region (247) that covers path to Valley of Eodon in Felucca
Added new region (248) that covers Valley of Eodon in Ter-Mur, with player housing disabled
Added new region (249) that covers entire T2A lands, with player housing disabled
Updated SPACEX and SPACEY values for all houses in dfndata/house/house.dfn to match updated house placement code
Added new JS property to Regions that can be used to determine or change state of player housing in a region: .canPlaceHouse()
Updated rules for usage of dye tubs to dye locked down items; now only house owners or co-owners may dye locked down items
Updated rules for usage of the following locked down items in a house, which are now only usable by house owners and co-owners
Dyes, Guildstone Deeds, Recall Runes (renaming), Rename Deeds, Townstone Deeds, House Deeds, Boat Models, Player Vendor Deeds, Ore, Hair Dye
Updated rules for usage of the following locked down items in a house, which are now only usable by house owners, co-owners and friends:
Keys, Dye Tubs, Magic Scrolls, Fireworks Wands, Magic Wands, Smithing Tools, Mining Tools, Fishing Poles
Updated item lockdown rules to allow locking down (and releasing) items in a container as long as the container is locked down, and to only allow releasing a locked down container if it's empty of locked down items
Updated item lockdown rules to only allow locking down movement-blocking items further than 2 tiles away from doors
Updated rules for releasing items in houses - now the house owner can release any locked down items, co-owners can release items locked down by themselves or by friends, while friends can release only items locked down by themselves
Added some feedback to player about why their attempted house placement failed
Items added by GMs directly into multis will now decay based on the house-specific decay timer instead of the regular one
Fixed an issue that could cause items to almost instantly decay after being released from lockdown in a house
Placing house add-ons now properly takes into account SPACEX and SPACEY values when checking if they can fit in selected area of houses
Re-added SPACEX and SPACEY values for Pentagram and Loom house add-ons
House add-ons can now be converted back into house add-on deeds by chopping them with an axe
Added new item type - IT_HOUSEADDON (201) - used by house add-ons placed in player houses
Fixed a bug where keys would stop working after being added to a keyring, and would turn into blank keys upon release from the keyring
Added visitor count for public player houses, which keeps track of how many visits a public house has received, with each player counted max 1 time every 24 hours
Fixed an issue with FindPlayersInOldVisrange() where it didn't take into account that players could see buildings further away than the standard update range. This could cause players to see ghost images of buildings if they were at the "right" distance when the building was being demolished
Added NODECAY tag to all signs and doors in dfndata/house/house.dfn
Added FRONTDOOR or INTERIORDOOR (as appropriate) to all doors in dfndata/house/house.dfn
Added BANX and BANY to specify ban location for some houses in dfndata/house/house.dfn instead of relying on finding SE corner automatically
Implemented strongboxes (js/server/house/strongbox.js) for co-owners of a house, which can be placed with the house command "i wish to place a strongbox". Max capacity is 25 items
Updated 'REMOVE command to take an optional parameter - itemID. If supplied, the command will remove all items with this itemID from a targeted container
Fixed a bug when checking if dynamic items were blocking valid spawn locations for NPCs, some function arguments were in the wrong order!
Improved code that finds valid spawn locations for items and NPCs spawned via spawn regions. As server gradually builds up lists of valid spawn locations per region over time, it will start using these lists more often, rather than always look for brand new spawn locations.
Fixed a bug with CMulHandler::CheckStaticFlag() that prevented NPCs from spawning inside buildings with no static floors!
Fixed an issue with repeating commands that prevented GMs from being able to cancel them when using the ClassicUO client
Exposed character property .accountNum to JS engine
Extended CDataList class to include a Clear() method for clearing lists
Updated JS File method .Open() to support an optional, third argument - subFolderName - that defines in which sub-folder of UOX3/shared/ to store/look for a file. If no third argument is supplied, UOX3 will default to using the shared folder itself.
Updated JS File method .Length() to return a value of -1 for files that don't exist
Added new code function, exposed to JS engine with same parameters, which simply checks if a given tile ID has a specific flag
bool CheckTileFlag( UI16 itemID, TILEFLAG flagToCheck )
Added JS function used to find the root container of an item (if any)
FindRootContainer( itemSerial )
FindRootContainer( item )
Added new JS function that allows deleting files from UOX3/shared/ folder or subfolders of shared folder. If no subFolderName is provided, looks for file directly in shared folder itself. Restrictions on file- and folder-names apply.
bool DeleteFile( fileName, subFolderName )
Added new JS functions for checking if a specific client or server feature is enabled. See documentation for full list of client/server features.
GetClientFeature( bitNum ) // Returns true if specified client feature is enabled on server
GetServerFeature( bitNum ) // Returns true if specified server feature is enabled on server
Added new JS function for returning the value of almost any server setting from UOX.INI
GetServerSetting( settingNameInDoubleQuotes )
Updated JS function DoesDynamicBlock() with two new parameters - checkOnlyMultis and checkOnlyNonMultis
Updated JS function DoesMapBlock() with two new parameters - checkMultiPlacement and checkForRoad
Fixed an issue where a LoS check would prevent players from accessing containers in their own backpack
Added new functions in findfuncs.cpp to make it easier to find items near another object or location:
findNearbyItems( object, distance )
findNearbyItems( x, y, worldNumber, instanceID, distance )
Added new Item property - maxItems - used by containers to determine their max item capacity
Added new Item property - totalItemCount - used to get total item count in a container (including sub-containers)
Added check for max item capacity when creating new items that are added to a character's backpack - items will be created below character's feet if backpack is full!
Added new DFN tag for items, used by containers to determine item capacity for a given container:
MAXITEMS=# // 125 is the default for all containers if not set
Added new JS Item properties:
.maxItems // gets/sets item capacity for a given container
.totalItemCount // gets total item count in a container, including sub-containers
Updated item tooltips for containers to show accurate total item count, as well as to display max item capacity
Fixed a bug where picking up items from a non-locked down pile of items on the floor inside a multi could cause the remaining pile to be seen as no longer inside the multi, disallowing locking it back down and causing it to decay based on regular decay timer instead of house-specific one
Updated JS command set to allow setting poison-level on items ('set poison #) and hunger-level on characters ('set hunger #)
Fixed an issue with js/item/food.js that prevented poisoned food from poisoning characters when eaten
Fixed an issue with js/skill/poisoning.js that prevented players from poisoning food!
Updated various JS scripts and hardcoded targeting functions to disallow the targeting of locked down resources using skills and tools
Updated JS Method TextMessage() to support three extra, optional parameters. Note that if one optional parameter is included, all preceding optional parameters are also required!
speechTarget - What kind of target is this message intended for?
0 - Only visible for sender and receiver of message
1 - Visible to all players in range
2 - Visible to all NPCs and players in range
3 - Visible to all PCs everywhere + NPCs in range
4 - Visible to all PCs everywhere (broadcast)
5 - Only visible for the receiver of the message
speechTargetSerial - The serial of the receiver of the message, used if speechTarget is 0 or 5
speechFontType - The type of font to display the text in. Defaults to normal.
0 - Bold
1 - Normal with shadow
2 - Bold with shadow
3 - Normal
4 - Gothic
5 - Italic
6 - Small, dark
7 - Colourful
8 - Runic (only works with CAPS)
9 - Small, light
Added timestamp to worldsaves in console, to make it easier to see when a particular world-save was done
Added info about compiler/environment displayed at the top of the UOX3 console during startup
Updated dictionary files with new messages primarily related to housing
2020-11-04 02:00:37 +08:00
|
|
|
}
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return rValue;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::DoesMapBlock()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Checks if the map tile at the given coordinates block movement
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::DoesMapBlock( std::int16_t x, std::int16_t y, std::int8_t z, std::uint8_t worldNumber, bool checkWater, bool waterWalk, bool checkMultiPlacement, bool checkForRoad ) -> bool
|
|
|
|
|
{
|
|
|
|
|
if( checkWater || waterWalk )
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
const auto &map = SeekMap( x, y, worldNumber );
|
Small update
Fixed an issue with an internal movement check that prevented characters from moving in valid map areas in Felucca/Trammel from X 6144 to X 7168
Fixed an issue where .instanceID property was misspelled in 'xgo GM command script, causing characters to be teleported to an out of bounds area where they would no longer be saved (js/commands/targeting/x.js)
Added some additional error-checking to .Teleport()/.SetLocation() JS Method to prevent script-accidents from sending characters out of bounds.
Updated Poisoning skill to add poison-charges to weapons being poisoned. Charges are consumed when applying poison in combat (js/skill/poisoning.js)
Updated combat code to consume poison-charges if a poisoned weapon is used to poison an opponent
Updated shoplists for Blacksmiths and Weaponsmiths - they now buy/sell longswords (dfndata/items/shoplist.dfn)
Updated MageShopping shoplist for mage vendors - they now buy/sell mass curse scrolls (dfndata/items/shoplist.dfn)
Added new Spawn Region DFN tag that can specify which era or eras of UO (Multiple comma-separated entries supported) a given spawn region is valid for. Spawn region not valid for core shard era will be ignored. Syntax:
ERAS=UO,T2A,UOR,LBR,AOS,SE,ML,SA,HS,TOL
Added new Spawn Region DFN tag that allows using another spawn region as a "parent". All properties of this parent will be inherited except for these, which are ignored: ERAS, NPCLIST, ITEMLIST, NPC and ITEM. Syntax for new tag:
GET=# // Inherit a specified spawn region
Added spawn region for animal trainer vendor in Vesper stable
Added spawn region for fur trader/tanner vendors in The Best Hides of Britain
Added spawn region for spinner vendor in The Lord's Clothier's and The Right Fit shops in Britain
Added spawn region for tanner NPC to Nujel'm Tannery (and fixed leatherworker spawn region for same area)
Added spawn regions for banker NPCs in East Bank of Britain, First Bank of Moonglow, Jhelom Bank and Jeweler, Bank of Skara Brae
Added spawn regions for stables, tailor and blacksmith inside Castle British
Added spawn regions for mage shops, mage guilds and farm houses in Moonglow
Added spawn regions for misc vendors and townfolk in multiple cities
Added spawn regions for Fire Island
Updated spawn regions for Dagger Isle/Ice Island
Added spawn regions for forests and jungles in southern Britannia and on various islands including Bucc's Den, Moonglow, Serpent's Hold, and misc unpopulated islands
Added spawn regions for area east of Skara Brae, around Hedge Maze and south of Britain
Added spawn regions for wandering healers outside every dungeon entrance in Britannia and Lost Lands
Re-integrated ocean spawn regions for ocean creatures (dolphin, walrus, water elemental, sea serpent) from the original community-based spawn file
Added reagent spawns in overworld spawn regions in Britannia/Lost Lands
Added special reagent spawns in swamp areas
Added additional overworld spawn regions in Britannia/Lost Lands
Added spawn regions for Khaldun dungeon that spawn some new and some old NPCs:
Old: Zombies, skeletons, skeletal mages, skeletal knights, ancient liches
New: Cursed (and named) NPCs, shadowfiends, zealots of khaldun (knights/summoners), tentacles of the harrower
Updated size and positions of some existing overworld spawn regions
Fixed incorrect spawn region size for small island south of Trinsic
Added switch/door puzzle functionality in Khaldun dungeon using new switch/door combo script (js/item/dungeons/switch_door_combo.js)
Added "smart objects" in Khaldun dungeon that activate when you come close enough (js/item/dungeons/smart_activate_item.js)
Added teleport locations within Khaldun dungeon (js/teleport.scp)
Added custom AIs to existing NPC spawning in Khaldun dungeon:
Ancient Lich (summons other undead, and can turn into one of them for disguise)
Added DFN entries for new NPCs spawning in Khaldun dungeon, some with custom AIs:
[tentacles_of_the_harrower] -> Tentacles of the Harrower (life steal)
[shadowfiend] -> Shadowfiends (seek out and reveal hidden players)
[zealot_knight]/[zealot_summoner] -> Zealots of Khaldun (turn into undead on death, male/female variants)
[cursed] -> Cursed (male/female variants)
[spectralarmor] -> Spectral Armor
Added DFN entries for new (named) NPCs spawning in Khaldun dungeon:
[lysander_gathenwale] -> Lysander Gathenwale
[grimmoch_drummel] -> Grimmoch Drummel
[morg_bergen] -> Morg Bergen
[tavara_sewel] -> Tavara Sewel
Added new NPC DFN entries:
[leatherworker] -> alias for male/female leatherworker vendors
[mapmaker] -> alias for male/female mapmaker vendors
Added new Race DFN entries:
[RACE 29] -> Cursed (enemies of RACE 30)
[RACE 30] -> Zealots (enemies of RACE 29)
Added new book DFN entries for Khaldun journals of Lysander, Tavara and Grimmoch - available as loot from the respective NPCs (dfndata/misc/books.dfn and dfndata/items/misc/books.dfn)
Added 25% chance for hit-animations and hit-SFX to play for targets in combat, instead of playing every time - can get very spammy
Monsters with actual weapons equipped (like Ophidian Enforcer with Halberd/Bardiche) will now get appropriate combat SFX for hitting with that weapon
Updated Healing skill to base cure/resurrection skill requirements on the calculated skill, rather than base skill (js/skill/healing.js)
Fixed an issue where healing with bandages and dying in the process would not properly reset the healing-related tags and skills used
Updated healing script to show a resurrection confirmation menu for players targeted with bandages for resurrect (js/skill/healing.js)
All skill usage states now reset on death, to prevent cases of players being "busy" while trying to use skills that got stuck due to script bugs.
The 'regspawn GM command now supports a new parameter called "max". Updated command syntax:
'regspawn # // perform a single respawn cycle in a specific spawn region
'regspawn all // perform a single respawn cycle across all spawn regions
'regspawn max // respawn ALL spawn regions to MAX capacity in one go
Added new UOX.INI setting that determines the maximum range at which NPCs can initiate attacks on players/NPCs (the old MAXRANGE=10 setting now instead defines max range at which players can initiate attacks on players/NPCs):
MAXNPCAGGRORANGE=10
Optimized performance by significantly reducing the number of line-of-sight checks performed by characters, especially in combat scenarios, or when evaluating potential targets for NPC AIs. The amount of checks done is also affected by the new ini setting for max aggro range.
Fixed an issue where both NPC and player characters would instantly drop one hunger level (from 6 to 5) upon creation since hungerrate was not initialized until after first hunger-event
Updated character priv property from UI16 to UI32, and added a new flag that determines if fame/karma title is hidden for character:
HIDEFAMEKARMATITLE (0x10000)
NPCs will no longer aggro other NPCs if the Z difference between them is greater or equal to 20 (i.e. they're on different floors), unless both are using ranged weapons and both are in range
Fixed an issue where players could get discounts from shopkeepers even though neither player nor shopkeeper were members of a NPC guild (js/npc/ai/shopkeeper.js)
Fixed an issue where the "premium" a player would get when selling items to a shopkeeper in the same NPC guild as them would be 110% extra on top of the item's value, instead of the intended 10% (js/npc/ai/shopkeeper.js) (Thanks, cobrag0318!)
Added missing tall straw hat to tailoring crafting scripts (Thanks, Dragon Slayer!)
Improved error reporting during compilation of individual scripts being reloaded - will now show more context and line number
onCombatEnd JS Event now also triggers when NPCs ignore their target and/or evade during combat
Updated 'decorate command to support saving/loading custom tags on items for world templates. These are stored after a @ symbol in the world template, each custom tag separated by a | symbol, and with each custom tag saved using this syntax: key$type$value
Updated resource-harvesting scripts to use script-specific global (const) variables, to avoid interference between different scripts (js/server/resource/*)
Added new resource-harvesting scripts and added spawn regions for these in fields on farms all over Britannia/Lost Lands
cabbages (js/server/resource/cabbages.js)
canteloupes (js/server/resource/canteloupes.js)
carrots (js/server/resource/carrots.js)
garlic (js/server/resource/garlic.js)
gourds (js/server/resource/gourds.js)
honeydew melons (js/server/resource/honeydewmelon.js)
onions (js/server/resource/onions.js)
pumpkins (js/server/resource/pumpkins.js)
squashes (js/server/resource/squashes.js)
turnips (js/server/resource/turnips.js)
watermelons (js/server/resource/watermelon.js)
Updated CSpawnRegion::FindItemSpotToSpawn() function in cSpawnRegion.cpp to prevent duplicate spawning of exact same item in exact same location
Updated sectionid of all potion and scroll aliases to match main item, so they'll get correctly picked up by NPC shopkeepers (dfndata/items/magic/potions.dfn and scrolls.dfn)
Specified sectionid for backpacks, so it also gets applied to packs added using the alias [backpack] (dfndata/items/misc/provisions.dfn)
Fixed a code issue that prevented players from selling empty containers to NPC shopkeepers willing to buy such containers
Fixed an issue where field-spells (wall of stone, poison field, etc) would ignore dynamic/static items that should block these
Fixed an issue where field-spells could be cast into houses from the outside by standing next to a wall and targeting self
Fixed a War/Peace-mode desync between client and server by having server always notify client (using war-toggle packet) when the "at war" flag is toggled for player character
Fixed an issue with hiding skill that wouldn't allow player to hide after having acquired self as target in combat (through spellcasting, for instance) (Thanks, Dragon Slayer!)
Fixed an issue where mana/reagents were consumed and skillcheck performed before all spellcast-validations had succeeded, resulting in the occasional loss of reagents/mana when spellcasting was disallowed (code and js/magic/clumsy.js and level1targ.js)
Fixed an issue with lack of criminal-flagging for casting of hostile spells scripted in JS (clumsy, magic arrow, feeblemind) vs blue targets (js/magic/clumsy.js and level1targ.js)
Fixed some issues with Line-of-Sight checking code that returned incorrect results, which amongst other things affected spellcasting in areas with uneven terrain
Fixed some issues with movement code and climbing of ladders, in particular the rope ladder in the 2-story log cabin. Code now sets a "is climbing" flag when character steps onto a rope ladder, and uses that to help resolve some edge cases, and then unsets it when they step off.
Renamed section headers of some map-items in DFNs from "locationname" to "locationnamemap" for clarity (example: "britain" to "britainmap")
Fixed broken "map wrapping" when sailing to edges of map in Felucca or Trammel
Fixed a server crash related to attempts at reading data from invalid map tiles
2025-06-27 08:40:02 +08:00
|
|
|
if( map.terrainInfo == nullptr )
|
|
|
|
|
return true;
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
if(( checkMultiPlacement && map.altitude == z ) || ( !checkMultiPlacement && map.altitude >= z && map.altitude - z < 16 ))
|
|
|
|
|
{
|
|
|
|
|
if( z == ILLEGAL_Z )
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if( waterWalk )
|
|
|
|
|
{
|
|
|
|
|
if( !map.CheckFlag( TF_WET ))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( map.CheckFlag( TF_WET ) || map.CheckFlag( TF_BLOCKING ))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Check that player is not attempting to place a multi on a road
|
2022-10-24 18:39:33 +08:00
|
|
|
if( checkWater && checkMultiPlacement && checkForRoad )
|
|
|
|
|
{
|
|
|
|
|
if( map.terrainInfo->IsRoadId() )
|
|
|
|
|
{
|
|
|
|
|
return true;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return false;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
Thief Revamp - 0.99.6-RC5
Added script for NPC guildmasters (js/npc/ai/guildmaster.js). Only one NPC guild has been setup in the script so far (more can be easily added) - the Thieves Guild - which if joined grants players the ability to steal from other players and to buy disguise kits
Added two new NPCs, which there will now spawn one of in a random location in each city in Britannia (felucca facet):
m_thief_guildmaster (dfndata/npc/male_human.dfn)
f_thief_guildmaster (dfndata/npc/female_Human.dfn)
Added two new character properties to keep track of which NPC guild a player (or NPC) belongs to. These properties have been exposed as the following Character JS properties:
.npcGuild // ID of NPC guild, as defined in script
.npcGuildJoined // Timestamp for when player joined NPC guild
Added script for Disguise Kits (js/item/disguisekit.js). These allow members of the Thieves Guild to disguise themselves from the prying eyes of other players.
Added two new character properties:
.isDisguised // true/false flag for character being disguised
.origName // used to store character's original name before disguise went into effect
Moved implementation of Stealing skill from code to script (js/skill/stealing.js) and revamped it completely in the process. Changes include:
New features:
Town rare stealing - any item marked as "special stealable" with new item property .stealable can be stolen, even if it's locked down by a GM on the ground, or inside a container
When stealing from item piles, thief can potentially steal the amount of items that makes up the max weight limit for what they can steal, from those piles
Chance to successfully steal is now affected by whether there are any characters (NPCs or Players) that witness the attempt. Depends on distance to character, and direction character is facing
Players now become "permagrey" when successfully stealing from another player, regardless of whether it's witnessed
Players now receive a "stealing" flag when stealing from another player, regardless of whether it's witnessed
Stolen items cannot be removed from thief's backpack for 30 seconds following the theft of the item (AoS core shard era and above)
Optional AoS feature to steal special consumable items from monsters
Updated default stealing rules:
Updated calculations to determine chance of success when stealing
Players cannot steal while engaged in combat
Players are revealed if hidden as soon as they use the stealing skill
Players can no longer steal items in the secure trade window
Players can no longer steal items from NPC shopkeepers
Both hands must be free to steal
Stealing now checks line of sight to target player/object
Only members of Thieves Guild (NPC guild) can now steal from other players, unless they are guild enemies
Players can no longer steal from NPC guards by default
Players can no longer steal from the same NPC monster more than once
Only gold and gems can be stolen from innocent players in dungeon/ll areas of Felucca, if core shard era is set to AoS or higher
Players can no longer steal items held on cursor by other players
Orcish masks now eplode if player steals from orcs while wearing it
If core shard era is set to LBR or lower, player is marked as an aggressor if they steal from another player
Guards can only be called on players that are flagged as criminals within the first 10 seconds of them being flagged
Stealing script options:
Allow stealing entire containers (off by default pre-AoS)
Return stolen items on thief death (off by default)
Temporarily make stolen items immovable in thief's backpack (on by default post-AoS)
Temporarily protect traded items (on by default)
Let dexterity affect chance for successful theft (off by default)
Let light level affect chance for successful theft (off by default)
Allow stealing from NPC Guards (off by default)
Allow stealing special loot from monsters (on by default post-ml)
Moved implementation of Snooping skill from code to script (js/skill/snooping.js), with some changes:
Players cannot snoop pack animals from inside a house, if the animal is outside
The deeper inside main backpack a container sits, the harder it becomes to snoop inside it
Included an optional feature that lets targets of snooping gradually become more aware, increasing the difficulty of succeeding. This awareness fades over time.
Players have a chance to stay hidden while snooping, based on their Hiding skill
Karma is now lowered by snooping regardless of success or failure
Added tracking system for "aggressors" in combat. A player attacking someone (regardless of flag status) will be marked as aggressor to that someone for 2 minutes
Added tracking system for "permagrey" flags - these are stored on a per-target basis, so a player can be flagged visibly as permagrey to multiple other players. Persists until player dies.
Player combat targets and war mode are now cleared on logout
Players will now be unable to hide if within visual distance and in line of sight of their attacker or current target in combat
Server leave-announcement now only happens after the logout timer has expired, instead of the exact moment the player presses the logout button
Fixed an issue that could cause swimming NPCs to swim on land
NPCs now have the ability to temporarily ignore unreachable targets in combat. If attacked by someone they are ignoring, they will enter evade state and try to move away from that someone.
SpawnRegions now support NPCLISTS with weighted entries. Example of an NPCLIST with 75% chance of spawning some kind of orc, and 25% chance of spawning a ratman archer:
[NPCLIST example]
{
75|NPCLIST=allorc
25|ratman
}
Added 3 additional "all purpose" item properties (.more0, .more1 and .more2) and exposed those to JS engine. These work the same as more/morex/morey/morez
Mark spell now stores a 4th property on recall runes - instanceID. This is stored in the rune's .more0 property.
Recall and Gate spells now check the recall rune (or runebook)'s 4th location property - instanceID - to determine where the player ends up
Fixed a server crash related to equipment being automatically unequipped if character is no longer strong enough to have it equipped
Added new JS Function to check if any characters at specified location potentially block movement:
DoesCharacterBlock( x, y, z, worldNum, instanceID ) // returns true if a character exists at given coordinate (within z +/- 4)
2023-06-20 02:21:16 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::DoesCharacterBlock()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Checks if there are any characters at given coordinates that block movement
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::DoesCharacterBlock( UI16 x, UI16 y, SI08 z, UI08 worldNumber, UI16 instanceId ) -> bool
|
|
|
|
|
{
|
|
|
|
|
for( auto &cellResponse : MapRegion->PopulateList( x, y, worldNumber ))
|
|
|
|
|
{
|
|
|
|
|
if( cellResponse == nullptr )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
auto regChars = cellResponse->GetCharList();
|
|
|
|
|
for( const auto &tempChar : regChars->collection() )
|
|
|
|
|
{
|
|
|
|
|
if( !ValidateObject( tempChar ) || ( tempChar->GetInstanceId() != instanceId ))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Is character within the range that normally blocks movement?
|
|
|
|
|
if( tempChar->GetX() == x && tempChar->GetY() == y && tempChar->GetZ() >= z - 2 && tempChar->GetZ() <= z + 2 )
|
|
|
|
|
{
|
|
|
|
|
// Is character a visible NPC, or a non-dead visible player?
|
|
|
|
|
if(( tempChar->IsNpc() && tempChar->GetVisible() == VT_VISIBLE ) || ( !tempChar->IsDead() && tempChar->GetVisible() == VT_VISIBLE ))
|
|
|
|
|
{
|
|
|
|
|
// Character found, potentially blocking
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::CheckStaticFlag()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Checks to see whether any statics at given coordinates has a specific flag
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
UOX3 0.99.6-RC4
Fixed an issue that prevented onBuyFromVendor() and onBoughtFromVendor() JS Events from triggering when attached to NPC shopkeepers
Fixed an issue with help gump that prevented password management section from working as intended (js/server/misc/helpgump.js)
Fixed an issue where UOX3 would fail to load pre-HS multi.mul files
Added chess board to Misc->Games add menu (dfndata/items/ItemMenu.bulk.dfn)
Fixed an issue with 'move (alias for 'telestuff) command that referenced the wrong variable name (js/commands/targeting/tele.js)
When a player is teleported via the GM 'wholist menu, any pets within range are now also brought along for the ride
Consolidated error-reporting for JS Functions, Object Methods and Object Properties to provide more context (scriptID, filename, line number) when something goes wrong
Added some missing shield IDs (0xA649, 0xA64A, 0xA831, 0xA832) to IsShieldType() function
MAXRANGE item property previously only worked for ranged weapons; now it works for melee weapons too, and potentially allows melee weapons with combat range longer than 1 tile
MAXRANGE item property can now be used to define max combat range for melee weapons
Fixed an issue (non-critical) with .PlaceInPack() JS Method that would cause UOX3 to try adding items marked for deletion to refreshQueue and spam console with errors
Added missing AI scripts to summoned Blade Spirits and Energy Vortexes (dfndata/npc/magicsummon.dfn)
Fixed an issue with weight calculation for hireling backpacks (js/npc/ai/hireling.js)
Fixed an issue with the 'fix command, which would in most cases set character's Z to -1 regardless of location, but now adheres to map elevation instead
Fixed an issue with Pack AI (js/npc/ai/pack_ai.js) that prevented pack members from attacking target correctly (thanks Dragon Slayer)
Fixed an issue with DoesMapBlock JS Function that incorrectly checked for 6 function arguments, when it actually requires 8
Fixed an issue with DoesDynamicBlock JS Function that incorrectly checked for 8 function arguments, when it actually requires 9
Fixed an issue with runebook script (js/item/runebook.js) that prevented players from being able to use recall charges without having spellbook with spell in inventory
Fixed issues with placement of tall items on ground/floor, and with stacking of items in houses
Fixed incorrect alias for woodland armor (dfndata/items/gear/armor/other/armor/wood.dfn - thanks Dragon Slayer)
Fixed a critical issue with script context sometimes changing while executing a script, because of events in other scripts being triggered. Affected scripts can be safeguarded against this by the addition of a dummy callback function anywhere in the script: function _restorecontext_() {}
Fixed an issue with non-animal pets not gaining loyalty when being fed (thanks Dragon Slayer)
Added new JS Object Methods for Chars/Items/Multis to fetch list of custom tags associated with object:
.GetTagMap() // Gets list of persistent custom tags associated with object
.GetTempTagMap() // Gets list of temporary custom tags associated with object
Added new JS commands ('GETTAGMAP and 'GETTEMPTAGMAP) that spits out details of custom tags associated with targeted object (js/commands/custom/misc-cmd.js)
Added new JS command ('USEITEM) that acts as a short-cut for double-clicking on targeted item (js/commands/custom/misc-cmd.js)
Updated 'ADD # and 'ADD ITEM # JS commands to support targeting a container directly and adding the new item inside (js/commands/targeting/add.js)
Updated axe script to only perform lumberjacking skill-check when there's still wood available in a given area, and to play appropriate animations for Gargoyle players (js/item/axe.js)
Updated script for gameboards to make generated pieces newbiefied so they won't appear on ground if board decays (js/item/gameboards.js)
Updated script for stablemasters to avoid relying on global variables (js/npc/ai/stablemaster.js)
Updated names of items crafted with runic hammers to include the material name of the hammers used to craft them (js/skill/craft/crafting_complete.js)
Fixed a small issue with Detect Hidden skill that would return the wrong message if players found anyone hiding nearby (js/skill/detecthidden.js)
Fixed an issue that prevented tile overrides in dfndata/maps/tiles.dfn from loading properly
Added entries for a couple of walls with missing no-shoot flags to tile overrides in dfndata/maps/tiles.dfn
Updated JS Method .SoundEffect() to support optional third argument (creatureSoundNum) to play creature-defined sounds from dfndata/creatures/creatures.dfn. New syntax:
.SoundEffect( soundID, allHear[, creatureSoundNum] ) // 0=SOUND_STARTATTACK, 1=SOUND_IDLE, 2=SOUND_ATTACK, 3=SOUND_DEFEND, 4=SOUND_DIE
Added new Character JS Methods:
.SetRandomName( nameListID ) // apply a random name from specified namelist to character
.FindItemSection( sectionID ) // find item in player's backpack with specified sectionID
Added new Socket JS Method:
.OpenContainer() // Opens specified container for socket
2023-05-30 01:47:26 +08:00
|
|
|
auto CMulHandler::CheckStaticFlag( std::int16_t x, std::int16_t y, std::int8_t z, std::uint8_t worldNumber, TileFlags toCheck, UI16 &foundtileID, bool checkSpawnSurface ) -> bool
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
|
|
|
|
auto rValue = checkSpawnSurface;
|
|
|
|
|
for( const auto &tile : Map->ArtAt( x, y, worldNumber ))
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
const SI08 elev = static_cast<SI08>( tile.altitude );
|
2022-10-24 18:39:33 +08:00
|
|
|
const SI08 tileHeight = static_cast<SI08>( tile.artInfo->ClimbHeight() );
|
|
|
|
|
if( checkSpawnSurface )
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
// Special case used when checking for spawn surfaces
|
2022-10-24 18:39:33 +08:00
|
|
|
if(( z >= elev && z <= ( elev + tileHeight )) && !tile.CheckFlag( toCheck ))
|
|
|
|
|
{
|
|
|
|
|
rValue = false;
|
2022-06-15 11:24:57 -04:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
// Generic check exposed to JS
|
2022-10-24 18:39:33 +08:00
|
|
|
if(( z >= elev && z <= ( elev + tileHeight )) && tile.CheckFlag( toCheck ))
|
|
|
|
|
{
|
UOX3 0.99.6-RC4
Fixed an issue that prevented onBuyFromVendor() and onBoughtFromVendor() JS Events from triggering when attached to NPC shopkeepers
Fixed an issue with help gump that prevented password management section from working as intended (js/server/misc/helpgump.js)
Fixed an issue where UOX3 would fail to load pre-HS multi.mul files
Added chess board to Misc->Games add menu (dfndata/items/ItemMenu.bulk.dfn)
Fixed an issue with 'move (alias for 'telestuff) command that referenced the wrong variable name (js/commands/targeting/tele.js)
When a player is teleported via the GM 'wholist menu, any pets within range are now also brought along for the ride
Consolidated error-reporting for JS Functions, Object Methods and Object Properties to provide more context (scriptID, filename, line number) when something goes wrong
Added some missing shield IDs (0xA649, 0xA64A, 0xA831, 0xA832) to IsShieldType() function
MAXRANGE item property previously only worked for ranged weapons; now it works for melee weapons too, and potentially allows melee weapons with combat range longer than 1 tile
MAXRANGE item property can now be used to define max combat range for melee weapons
Fixed an issue (non-critical) with .PlaceInPack() JS Method that would cause UOX3 to try adding items marked for deletion to refreshQueue and spam console with errors
Added missing AI scripts to summoned Blade Spirits and Energy Vortexes (dfndata/npc/magicsummon.dfn)
Fixed an issue with weight calculation for hireling backpacks (js/npc/ai/hireling.js)
Fixed an issue with the 'fix command, which would in most cases set character's Z to -1 regardless of location, but now adheres to map elevation instead
Fixed an issue with Pack AI (js/npc/ai/pack_ai.js) that prevented pack members from attacking target correctly (thanks Dragon Slayer)
Fixed an issue with DoesMapBlock JS Function that incorrectly checked for 6 function arguments, when it actually requires 8
Fixed an issue with DoesDynamicBlock JS Function that incorrectly checked for 8 function arguments, when it actually requires 9
Fixed an issue with runebook script (js/item/runebook.js) that prevented players from being able to use recall charges without having spellbook with spell in inventory
Fixed issues with placement of tall items on ground/floor, and with stacking of items in houses
Fixed incorrect alias for woodland armor (dfndata/items/gear/armor/other/armor/wood.dfn - thanks Dragon Slayer)
Fixed a critical issue with script context sometimes changing while executing a script, because of events in other scripts being triggered. Affected scripts can be safeguarded against this by the addition of a dummy callback function anywhere in the script: function _restorecontext_() {}
Fixed an issue with non-animal pets not gaining loyalty when being fed (thanks Dragon Slayer)
Added new JS Object Methods for Chars/Items/Multis to fetch list of custom tags associated with object:
.GetTagMap() // Gets list of persistent custom tags associated with object
.GetTempTagMap() // Gets list of temporary custom tags associated with object
Added new JS commands ('GETTAGMAP and 'GETTEMPTAGMAP) that spits out details of custom tags associated with targeted object (js/commands/custom/misc-cmd.js)
Added new JS command ('USEITEM) that acts as a short-cut for double-clicking on targeted item (js/commands/custom/misc-cmd.js)
Updated 'ADD # and 'ADD ITEM # JS commands to support targeting a container directly and adding the new item inside (js/commands/targeting/add.js)
Updated axe script to only perform lumberjacking skill-check when there's still wood available in a given area, and to play appropriate animations for Gargoyle players (js/item/axe.js)
Updated script for gameboards to make generated pieces newbiefied so they won't appear on ground if board decays (js/item/gameboards.js)
Updated script for stablemasters to avoid relying on global variables (js/npc/ai/stablemaster.js)
Updated names of items crafted with runic hammers to include the material name of the hammers used to craft them (js/skill/craft/crafting_complete.js)
Fixed a small issue with Detect Hidden skill that would return the wrong message if players found anyone hiding nearby (js/skill/detecthidden.js)
Fixed an issue that prevented tile overrides in dfndata/maps/tiles.dfn from loading properly
Added entries for a couple of walls with missing no-shoot flags to tile overrides in dfndata/maps/tiles.dfn
Updated JS Method .SoundEffect() to support optional third argument (creatureSoundNum) to play creature-defined sounds from dfndata/creatures/creatures.dfn. New syntax:
.SoundEffect( soundID, allHear[, creatureSoundNum] ) // 0=SOUND_STARTATTACK, 1=SOUND_IDLE, 2=SOUND_ATTACK, 3=SOUND_DEFEND, 4=SOUND_DIE
Added new Character JS Methods:
.SetRandomName( nameListID ) // apply a random name from specified namelist to character
.FindItemSection( sectionID ) // find item in player's backpack with specified sectionID
Added new Socket JS Method:
.OpenContainer() // Opens specified container for socket
2023-05-30 01:47:26 +08:00
|
|
|
foundtileID = tile.tileId;
|
2022-10-24 18:39:33 +08:00
|
|
|
rValue = true; // Found static with specified flag
|
2022-06-15 11:24:57 -04:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return rValue;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::CheckDynamicFlag()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Checks to see whether any dynamics at given coordinates has a specific flag
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
UOX3 0.99.6-RC4
Fixed an issue that prevented onBuyFromVendor() and onBoughtFromVendor() JS Events from triggering when attached to NPC shopkeepers
Fixed an issue with help gump that prevented password management section from working as intended (js/server/misc/helpgump.js)
Fixed an issue where UOX3 would fail to load pre-HS multi.mul files
Added chess board to Misc->Games add menu (dfndata/items/ItemMenu.bulk.dfn)
Fixed an issue with 'move (alias for 'telestuff) command that referenced the wrong variable name (js/commands/targeting/tele.js)
When a player is teleported via the GM 'wholist menu, any pets within range are now also brought along for the ride
Consolidated error-reporting for JS Functions, Object Methods and Object Properties to provide more context (scriptID, filename, line number) when something goes wrong
Added some missing shield IDs (0xA649, 0xA64A, 0xA831, 0xA832) to IsShieldType() function
MAXRANGE item property previously only worked for ranged weapons; now it works for melee weapons too, and potentially allows melee weapons with combat range longer than 1 tile
MAXRANGE item property can now be used to define max combat range for melee weapons
Fixed an issue (non-critical) with .PlaceInPack() JS Method that would cause UOX3 to try adding items marked for deletion to refreshQueue and spam console with errors
Added missing AI scripts to summoned Blade Spirits and Energy Vortexes (dfndata/npc/magicsummon.dfn)
Fixed an issue with weight calculation for hireling backpacks (js/npc/ai/hireling.js)
Fixed an issue with the 'fix command, which would in most cases set character's Z to -1 regardless of location, but now adheres to map elevation instead
Fixed an issue with Pack AI (js/npc/ai/pack_ai.js) that prevented pack members from attacking target correctly (thanks Dragon Slayer)
Fixed an issue with DoesMapBlock JS Function that incorrectly checked for 6 function arguments, when it actually requires 8
Fixed an issue with DoesDynamicBlock JS Function that incorrectly checked for 8 function arguments, when it actually requires 9
Fixed an issue with runebook script (js/item/runebook.js) that prevented players from being able to use recall charges without having spellbook with spell in inventory
Fixed issues with placement of tall items on ground/floor, and with stacking of items in houses
Fixed incorrect alias for woodland armor (dfndata/items/gear/armor/other/armor/wood.dfn - thanks Dragon Slayer)
Fixed a critical issue with script context sometimes changing while executing a script, because of events in other scripts being triggered. Affected scripts can be safeguarded against this by the addition of a dummy callback function anywhere in the script: function _restorecontext_() {}
Fixed an issue with non-animal pets not gaining loyalty when being fed (thanks Dragon Slayer)
Added new JS Object Methods for Chars/Items/Multis to fetch list of custom tags associated with object:
.GetTagMap() // Gets list of persistent custom tags associated with object
.GetTempTagMap() // Gets list of temporary custom tags associated with object
Added new JS commands ('GETTAGMAP and 'GETTEMPTAGMAP) that spits out details of custom tags associated with targeted object (js/commands/custom/misc-cmd.js)
Added new JS command ('USEITEM) that acts as a short-cut for double-clicking on targeted item (js/commands/custom/misc-cmd.js)
Updated 'ADD # and 'ADD ITEM # JS commands to support targeting a container directly and adding the new item inside (js/commands/targeting/add.js)
Updated axe script to only perform lumberjacking skill-check when there's still wood available in a given area, and to play appropriate animations for Gargoyle players (js/item/axe.js)
Updated script for gameboards to make generated pieces newbiefied so they won't appear on ground if board decays (js/item/gameboards.js)
Updated script for stablemasters to avoid relying on global variables (js/npc/ai/stablemaster.js)
Updated names of items crafted with runic hammers to include the material name of the hammers used to craft them (js/skill/craft/crafting_complete.js)
Fixed a small issue with Detect Hidden skill that would return the wrong message if players found anyone hiding nearby (js/skill/detecthidden.js)
Fixed an issue that prevented tile overrides in dfndata/maps/tiles.dfn from loading properly
Added entries for a couple of walls with missing no-shoot flags to tile overrides in dfndata/maps/tiles.dfn
Updated JS Method .SoundEffect() to support optional third argument (creatureSoundNum) to play creature-defined sounds from dfndata/creatures/creatures.dfn. New syntax:
.SoundEffect( soundID, allHear[, creatureSoundNum] ) // 0=SOUND_STARTATTACK, 1=SOUND_IDLE, 2=SOUND_ATTACK, 3=SOUND_DEFEND, 4=SOUND_DIE
Added new Character JS Methods:
.SetRandomName( nameListID ) // apply a random name from specified namelist to character
.FindItemSection( sectionID ) // find item in player's backpack with specified sectionID
Added new Socket JS Method:
.OpenContainer() // Opens specified container for socket
2023-05-30 01:47:26 +08:00
|
|
|
auto CMulHandler::CheckDynamicFlag( std::int16_t x, std::int16_t y, std::int8_t z, std::uint8_t worldNumber, std::uint16_t instanceId, TileFlags toCheck, UI16 &foundTileId ) -> bool
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-17 16:01:22 +08:00
|
|
|
// Special case for handling multis that cross over between multiple map regions because of size
|
|
|
|
|
CMultiObj *tempMulti = FindMulti( x, y, z, worldNumber, instanceId );
|
|
|
|
|
if( ValidateObject( tempMulti ) )
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-17 16:01:22 +08:00
|
|
|
// Look for a multi item at specific location
|
|
|
|
|
auto multiId = static_cast<UI16>( tempMulti->GetId() - 0x4000 );
|
|
|
|
|
for( auto &multiItem : SeekMulti( multiId ).items )
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-17 16:01:22 +08:00
|
|
|
if( multiItem.flag > 0 && ( abs( tempMulti->GetZ() + multiItem.altitude - z ) <= 1 ))
|
|
|
|
|
{
|
|
|
|
|
if(( tempMulti->GetX() + multiItem.offsetX == x ) && ( tempMulti->GetY() + multiItem.offsetY == y ))
|
|
|
|
|
{
|
|
|
|
|
if( SeekTile( multiItem.tileId ).CheckFlag( toCheck ))
|
|
|
|
|
{
|
UOX3 0.99.6-RC4
Fixed an issue that prevented onBuyFromVendor() and onBoughtFromVendor() JS Events from triggering when attached to NPC shopkeepers
Fixed an issue with help gump that prevented password management section from working as intended (js/server/misc/helpgump.js)
Fixed an issue where UOX3 would fail to load pre-HS multi.mul files
Added chess board to Misc->Games add menu (dfndata/items/ItemMenu.bulk.dfn)
Fixed an issue with 'move (alias for 'telestuff) command that referenced the wrong variable name (js/commands/targeting/tele.js)
When a player is teleported via the GM 'wholist menu, any pets within range are now also brought along for the ride
Consolidated error-reporting for JS Functions, Object Methods and Object Properties to provide more context (scriptID, filename, line number) when something goes wrong
Added some missing shield IDs (0xA649, 0xA64A, 0xA831, 0xA832) to IsShieldType() function
MAXRANGE item property previously only worked for ranged weapons; now it works for melee weapons too, and potentially allows melee weapons with combat range longer than 1 tile
MAXRANGE item property can now be used to define max combat range for melee weapons
Fixed an issue (non-critical) with .PlaceInPack() JS Method that would cause UOX3 to try adding items marked for deletion to refreshQueue and spam console with errors
Added missing AI scripts to summoned Blade Spirits and Energy Vortexes (dfndata/npc/magicsummon.dfn)
Fixed an issue with weight calculation for hireling backpacks (js/npc/ai/hireling.js)
Fixed an issue with the 'fix command, which would in most cases set character's Z to -1 regardless of location, but now adheres to map elevation instead
Fixed an issue with Pack AI (js/npc/ai/pack_ai.js) that prevented pack members from attacking target correctly (thanks Dragon Slayer)
Fixed an issue with DoesMapBlock JS Function that incorrectly checked for 6 function arguments, when it actually requires 8
Fixed an issue with DoesDynamicBlock JS Function that incorrectly checked for 8 function arguments, when it actually requires 9
Fixed an issue with runebook script (js/item/runebook.js) that prevented players from being able to use recall charges without having spellbook with spell in inventory
Fixed issues with placement of tall items on ground/floor, and with stacking of items in houses
Fixed incorrect alias for woodland armor (dfndata/items/gear/armor/other/armor/wood.dfn - thanks Dragon Slayer)
Fixed a critical issue with script context sometimes changing while executing a script, because of events in other scripts being triggered. Affected scripts can be safeguarded against this by the addition of a dummy callback function anywhere in the script: function _restorecontext_() {}
Fixed an issue with non-animal pets not gaining loyalty when being fed (thanks Dragon Slayer)
Added new JS Object Methods for Chars/Items/Multis to fetch list of custom tags associated with object:
.GetTagMap() // Gets list of persistent custom tags associated with object
.GetTempTagMap() // Gets list of temporary custom tags associated with object
Added new JS commands ('GETTAGMAP and 'GETTEMPTAGMAP) that spits out details of custom tags associated with targeted object (js/commands/custom/misc-cmd.js)
Added new JS command ('USEITEM) that acts as a short-cut for double-clicking on targeted item (js/commands/custom/misc-cmd.js)
Updated 'ADD # and 'ADD ITEM # JS commands to support targeting a container directly and adding the new item inside (js/commands/targeting/add.js)
Updated axe script to only perform lumberjacking skill-check when there's still wood available in a given area, and to play appropriate animations for Gargoyle players (js/item/axe.js)
Updated script for gameboards to make generated pieces newbiefied so they won't appear on ground if board decays (js/item/gameboards.js)
Updated script for stablemasters to avoid relying on global variables (js/npc/ai/stablemaster.js)
Updated names of items crafted with runic hammers to include the material name of the hammers used to craft them (js/skill/craft/crafting_complete.js)
Fixed a small issue with Detect Hidden skill that would return the wrong message if players found anyone hiding nearby (js/skill/detecthidden.js)
Fixed an issue that prevented tile overrides in dfndata/maps/tiles.dfn from loading properly
Added entries for a couple of walls with missing no-shoot flags to tile overrides in dfndata/maps/tiles.dfn
Updated JS Method .SoundEffect() to support optional third argument (creatureSoundNum) to play creature-defined sounds from dfndata/creatures/creatures.dfn. New syntax:
.SoundEffect( soundID, allHear[, creatureSoundNum] ) // 0=SOUND_STARTATTACK, 1=SOUND_IDLE, 2=SOUND_ATTACK, 3=SOUND_DEFEND, 4=SOUND_DIE
Added new Character JS Methods:
.SetRandomName( nameListID ) // apply a random name from specified namelist to character
.FindItemSection( sectionID ) // find item in player's backpack with specified sectionID
Added new Socket JS Method:
.OpenContainer() // Opens specified container for socket
2023-05-30 01:47:26 +08:00
|
|
|
foundTileId = multiItem.tileId;
|
2023-03-17 16:01:22 +08:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Search map region of given location for all potentially blocking dynamic items
|
|
|
|
|
for( auto &cellResponse : MapRegion->PopulateList( x, y, worldNumber ))
|
|
|
|
|
{
|
|
|
|
|
if( cellResponse == nullptr )
|
2022-10-24 18:39:33 +08:00
|
|
|
continue;
|
2023-03-17 16:01:22 +08:00
|
|
|
|
|
|
|
|
auto regItems = cellResponse->GetItemList();
|
|
|
|
|
for( const auto &item : regItems->collection() )
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-17 16:01:22 +08:00
|
|
|
if( !ValidateObject( item ) || item->GetInstanceId() != instanceId )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if(( item->GetId( 1 ) >= 0x40 ) && (( item->GetObjType() == OT_MULTI ) || (item->CanBeObjType( OT_MULTI ))))
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-17 16:01:22 +08:00
|
|
|
// Found a multi
|
|
|
|
|
// Look for a multi item at specific location
|
|
|
|
|
auto multiId = static_cast<UI16>( item->GetId() - 0x4000 );
|
|
|
|
|
for( auto &multiItem : SeekMulti( multiId ).items )
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-17 16:01:22 +08:00
|
|
|
if( multiItem.flag > 0 && ( abs( item->GetZ() + multiItem.altitude - z ) <= 1 ))
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-17 16:01:22 +08:00
|
|
|
if(( item->GetX() + multiItem.offsetX == x ) && ( item->GetY() + multiItem.offsetY == y ))
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-17 16:01:22 +08:00
|
|
|
if( SeekTile( multiItem.tileId ).CheckFlag( toCheck ))
|
|
|
|
|
{
|
UOX3 0.99.6-RC4
Fixed an issue that prevented onBuyFromVendor() and onBoughtFromVendor() JS Events from triggering when attached to NPC shopkeepers
Fixed an issue with help gump that prevented password management section from working as intended (js/server/misc/helpgump.js)
Fixed an issue where UOX3 would fail to load pre-HS multi.mul files
Added chess board to Misc->Games add menu (dfndata/items/ItemMenu.bulk.dfn)
Fixed an issue with 'move (alias for 'telestuff) command that referenced the wrong variable name (js/commands/targeting/tele.js)
When a player is teleported via the GM 'wholist menu, any pets within range are now also brought along for the ride
Consolidated error-reporting for JS Functions, Object Methods and Object Properties to provide more context (scriptID, filename, line number) when something goes wrong
Added some missing shield IDs (0xA649, 0xA64A, 0xA831, 0xA832) to IsShieldType() function
MAXRANGE item property previously only worked for ranged weapons; now it works for melee weapons too, and potentially allows melee weapons with combat range longer than 1 tile
MAXRANGE item property can now be used to define max combat range for melee weapons
Fixed an issue (non-critical) with .PlaceInPack() JS Method that would cause UOX3 to try adding items marked for deletion to refreshQueue and spam console with errors
Added missing AI scripts to summoned Blade Spirits and Energy Vortexes (dfndata/npc/magicsummon.dfn)
Fixed an issue with weight calculation for hireling backpacks (js/npc/ai/hireling.js)
Fixed an issue with the 'fix command, which would in most cases set character's Z to -1 regardless of location, but now adheres to map elevation instead
Fixed an issue with Pack AI (js/npc/ai/pack_ai.js) that prevented pack members from attacking target correctly (thanks Dragon Slayer)
Fixed an issue with DoesMapBlock JS Function that incorrectly checked for 6 function arguments, when it actually requires 8
Fixed an issue with DoesDynamicBlock JS Function that incorrectly checked for 8 function arguments, when it actually requires 9
Fixed an issue with runebook script (js/item/runebook.js) that prevented players from being able to use recall charges without having spellbook with spell in inventory
Fixed issues with placement of tall items on ground/floor, and with stacking of items in houses
Fixed incorrect alias for woodland armor (dfndata/items/gear/armor/other/armor/wood.dfn - thanks Dragon Slayer)
Fixed a critical issue with script context sometimes changing while executing a script, because of events in other scripts being triggered. Affected scripts can be safeguarded against this by the addition of a dummy callback function anywhere in the script: function _restorecontext_() {}
Fixed an issue with non-animal pets not gaining loyalty when being fed (thanks Dragon Slayer)
Added new JS Object Methods for Chars/Items/Multis to fetch list of custom tags associated with object:
.GetTagMap() // Gets list of persistent custom tags associated with object
.GetTempTagMap() // Gets list of temporary custom tags associated with object
Added new JS commands ('GETTAGMAP and 'GETTEMPTAGMAP) that spits out details of custom tags associated with targeted object (js/commands/custom/misc-cmd.js)
Added new JS command ('USEITEM) that acts as a short-cut for double-clicking on targeted item (js/commands/custom/misc-cmd.js)
Updated 'ADD # and 'ADD ITEM # JS commands to support targeting a container directly and adding the new item inside (js/commands/targeting/add.js)
Updated axe script to only perform lumberjacking skill-check when there's still wood available in a given area, and to play appropriate animations for Gargoyle players (js/item/axe.js)
Updated script for gameboards to make generated pieces newbiefied so they won't appear on ground if board decays (js/item/gameboards.js)
Updated script for stablemasters to avoid relying on global variables (js/npc/ai/stablemaster.js)
Updated names of items crafted with runic hammers to include the material name of the hammers used to craft them (js/skill/craft/crafting_complete.js)
Fixed a small issue with Detect Hidden skill that would return the wrong message if players found anyone hiding nearby (js/skill/detecthidden.js)
Fixed an issue that prevented tile overrides in dfndata/maps/tiles.dfn from loading properly
Added entries for a couple of walls with missing no-shoot flags to tile overrides in dfndata/maps/tiles.dfn
Updated JS Method .SoundEffect() to support optional third argument (creatureSoundNum) to play creature-defined sounds from dfndata/creatures/creatures.dfn. New syntax:
.SoundEffect( soundID, allHear[, creatureSoundNum] ) // 0=SOUND_STARTATTACK, 1=SOUND_IDLE, 2=SOUND_ATTACK, 3=SOUND_DEFEND, 4=SOUND_DIE
Added new Character JS Methods:
.SetRandomName( nameListID ) // apply a random name from specified namelist to character
.FindItemSection( sectionID ) // find item in player's backpack with specified sectionID
Added new Socket JS Method:
.OpenContainer() // Opens specified container for socket
2023-05-30 01:47:26 +08:00
|
|
|
foundTileId = multiItem.tileId;
|
2023-03-17 16:01:22 +08:00
|
|
|
return true;
|
|
|
|
|
}
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
}
|
2023-03-17 16:01:22 +08:00
|
|
|
else
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-17 16:01:22 +08:00
|
|
|
// item is not a multi
|
|
|
|
|
if(( item->GetX() == x ) && ( item->GetY() == y ) && ( item->GetZ() == z ))
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-17 16:01:22 +08:00
|
|
|
auto itemZ = item->GetZ();
|
|
|
|
|
const SI08 tileHeight = static_cast<SI08>( TileHeight( item->GetId() ));
|
|
|
|
|
if(( itemZ == z && itemZ + tileHeight > z ) || ( itemZ < z && itemZ + tileHeight >= z ))
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-17 16:01:22 +08:00
|
|
|
if( SeekTile( item->GetId() ).CheckFlag( toCheck ))
|
|
|
|
|
{
|
UOX3 0.99.6-RC4
Fixed an issue that prevented onBuyFromVendor() and onBoughtFromVendor() JS Events from triggering when attached to NPC shopkeepers
Fixed an issue with help gump that prevented password management section from working as intended (js/server/misc/helpgump.js)
Fixed an issue where UOX3 would fail to load pre-HS multi.mul files
Added chess board to Misc->Games add menu (dfndata/items/ItemMenu.bulk.dfn)
Fixed an issue with 'move (alias for 'telestuff) command that referenced the wrong variable name (js/commands/targeting/tele.js)
When a player is teleported via the GM 'wholist menu, any pets within range are now also brought along for the ride
Consolidated error-reporting for JS Functions, Object Methods and Object Properties to provide more context (scriptID, filename, line number) when something goes wrong
Added some missing shield IDs (0xA649, 0xA64A, 0xA831, 0xA832) to IsShieldType() function
MAXRANGE item property previously only worked for ranged weapons; now it works for melee weapons too, and potentially allows melee weapons with combat range longer than 1 tile
MAXRANGE item property can now be used to define max combat range for melee weapons
Fixed an issue (non-critical) with .PlaceInPack() JS Method that would cause UOX3 to try adding items marked for deletion to refreshQueue and spam console with errors
Added missing AI scripts to summoned Blade Spirits and Energy Vortexes (dfndata/npc/magicsummon.dfn)
Fixed an issue with weight calculation for hireling backpacks (js/npc/ai/hireling.js)
Fixed an issue with the 'fix command, which would in most cases set character's Z to -1 regardless of location, but now adheres to map elevation instead
Fixed an issue with Pack AI (js/npc/ai/pack_ai.js) that prevented pack members from attacking target correctly (thanks Dragon Slayer)
Fixed an issue with DoesMapBlock JS Function that incorrectly checked for 6 function arguments, when it actually requires 8
Fixed an issue with DoesDynamicBlock JS Function that incorrectly checked for 8 function arguments, when it actually requires 9
Fixed an issue with runebook script (js/item/runebook.js) that prevented players from being able to use recall charges without having spellbook with spell in inventory
Fixed issues with placement of tall items on ground/floor, and with stacking of items in houses
Fixed incorrect alias for woodland armor (dfndata/items/gear/armor/other/armor/wood.dfn - thanks Dragon Slayer)
Fixed a critical issue with script context sometimes changing while executing a script, because of events in other scripts being triggered. Affected scripts can be safeguarded against this by the addition of a dummy callback function anywhere in the script: function _restorecontext_() {}
Fixed an issue with non-animal pets not gaining loyalty when being fed (thanks Dragon Slayer)
Added new JS Object Methods for Chars/Items/Multis to fetch list of custom tags associated with object:
.GetTagMap() // Gets list of persistent custom tags associated with object
.GetTempTagMap() // Gets list of temporary custom tags associated with object
Added new JS commands ('GETTAGMAP and 'GETTEMPTAGMAP) that spits out details of custom tags associated with targeted object (js/commands/custom/misc-cmd.js)
Added new JS command ('USEITEM) that acts as a short-cut for double-clicking on targeted item (js/commands/custom/misc-cmd.js)
Updated 'ADD # and 'ADD ITEM # JS commands to support targeting a container directly and adding the new item inside (js/commands/targeting/add.js)
Updated axe script to only perform lumberjacking skill-check when there's still wood available in a given area, and to play appropriate animations for Gargoyle players (js/item/axe.js)
Updated script for gameboards to make generated pieces newbiefied so they won't appear on ground if board decays (js/item/gameboards.js)
Updated script for stablemasters to avoid relying on global variables (js/npc/ai/stablemaster.js)
Updated names of items crafted with runic hammers to include the material name of the hammers used to craft them (js/skill/craft/crafting_complete.js)
Fixed a small issue with Detect Hidden skill that would return the wrong message if players found anyone hiding nearby (js/skill/detecthidden.js)
Fixed an issue that prevented tile overrides in dfndata/maps/tiles.dfn from loading properly
Added entries for a couple of walls with missing no-shoot flags to tile overrides in dfndata/maps/tiles.dfn
Updated JS Method .SoundEffect() to support optional third argument (creatureSoundNum) to play creature-defined sounds from dfndata/creatures/creatures.dfn. New syntax:
.SoundEffect( soundID, allHear[, creatureSoundNum] ) // 0=SOUND_STARTATTACK, 1=SOUND_IDLE, 2=SOUND_ATTACK, 3=SOUND_DEFEND, 4=SOUND_DIE
Added new Character JS Methods:
.SetRandomName( nameListID ) // apply a random name from specified namelist to character
.FindItemSection( sectionID ) // find item in player's backpack with specified sectionID
Added new Socket JS Method:
.OpenContainer() // Opens specified container for socket
2023-05-30 01:47:26 +08:00
|
|
|
foundTileId = item->GetId();
|
2023-03-17 16:01:22 +08:00
|
|
|
return true;
|
|
|
|
|
}
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-14 17:53:00 -04:00
|
|
|
}
|
2022-06-15 11:24:57 -04:00
|
|
|
return false;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::CheckTileFlag()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Checks to see whether given tile ID has a specified flag
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::CheckTileFlag( std::uint16_t itemId, TileFlags flagToCheck ) -> bool
|
|
|
|
|
{
|
|
|
|
|
if( !SeekTile( itemId ).CheckFlag( flagToCheck ))
|
|
|
|
|
{
|
2021-05-28 03:41:43 +08:00
|
|
|
return false;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
2022-06-15 11:24:57 -04:00
|
|
|
return true;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::StaticTop()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Top of statics at/above given coordinates
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::StaticTop( std::int16_t x, std::int16_t y, std::int8_t z, std::uint8_t worldNumber, std::int8_t maxZ ) -> std::int8_t
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
auto top = ILLEGAL_Z;
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
const auto &artTiles = Map->ArtAt( x, y, worldNumber );
|
|
|
|
|
for( const auto &tile : artTiles )
|
|
|
|
|
{
|
|
|
|
|
auto tempTop = static_cast<std::int8_t>( tile.altitude + tile.artInfo->ClimbHeight() );
|
|
|
|
|
if(( tempTop <= z + maxZ ) && ( tempTop > top ))
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
top = tempTop;
|
2022-10-24 18:39:33 +08:00
|
|
|
}
|
2012-11-03 18:11:04 +00:00
|
|
|
}
|
2022-06-15 11:24:57 -04:00
|
|
|
return top;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::DynamicElevation()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - This was fixed to actually return the *elevation* of dynamic items at/above given coordinates
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-11-01 02:25:52 +08:00
|
|
|
auto CMulHandler::DynamicElevation( std::int16_t x, std::int16_t y, std::int8_t z, std::uint8_t worldNumber, std::uint16_t instanceId, std::int8_t maxZ ) -> std::int8_t
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
|
|
|
|
auto dynZ = ILLEGAL_Z;
|
|
|
|
|
|
2023-03-08 13:08:12 +08:00
|
|
|
// Special case for handling multis that cross over between multiple map regions because of size
|
|
|
|
|
CMultiObj *tempMulti = FindMulti( x, y, z, worldNumber, instanceId );
|
2023-03-17 16:01:22 +08:00
|
|
|
if( ValidateObject( tempMulti ))
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-08 13:08:12 +08:00
|
|
|
dynZ = MultiHeight( tempMulti, x, y, z, maxZ );
|
2023-03-17 16:01:22 +08:00
|
|
|
|
|
|
|
|
// Also check dynamic items inside the multi
|
|
|
|
|
for( const auto &tempMultiItem : tempMulti->GetItemsInMultiList()->collection() )
|
|
|
|
|
{
|
|
|
|
|
if( tempMultiItem->GetX() == x && tempMultiItem->GetY() == y )
|
|
|
|
|
{
|
|
|
|
|
SI08 zTemp = static_cast<SI08>( tempMultiItem->GetZ() + TileHeight( tempMultiItem->GetId() ));
|
|
|
|
|
if(( zTemp <= z + maxZ ) && ( zTemp > dynZ || ( dynZ >= z + maxZ )))
|
|
|
|
|
{
|
|
|
|
|
dynZ = zTemp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-08 13:08:12 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
auto MapArea = MapRegion->GetMapRegion( MapRegion->GetGridX( x ), MapRegion->GetGridY( y ), worldNumber );
|
|
|
|
|
if( MapArea )
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-08 13:08:12 +08:00
|
|
|
auto regItems = MapArea->GetItemList();
|
|
|
|
|
for( const auto tempItem : regItems->collection() )
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
Small update
Fixed an issue with an internal movement check that prevented characters from moving in valid map areas in Felucca/Trammel from X 6144 to X 7168
Fixed an issue where .instanceID property was misspelled in 'xgo GM command script, causing characters to be teleported to an out of bounds area where they would no longer be saved (js/commands/targeting/x.js)
Added some additional error-checking to .Teleport()/.SetLocation() JS Method to prevent script-accidents from sending characters out of bounds.
Updated Poisoning skill to add poison-charges to weapons being poisoned. Charges are consumed when applying poison in combat (js/skill/poisoning.js)
Updated combat code to consume poison-charges if a poisoned weapon is used to poison an opponent
Updated shoplists for Blacksmiths and Weaponsmiths - they now buy/sell longswords (dfndata/items/shoplist.dfn)
Updated MageShopping shoplist for mage vendors - they now buy/sell mass curse scrolls (dfndata/items/shoplist.dfn)
Added new Spawn Region DFN tag that can specify which era or eras of UO (Multiple comma-separated entries supported) a given spawn region is valid for. Spawn region not valid for core shard era will be ignored. Syntax:
ERAS=UO,T2A,UOR,LBR,AOS,SE,ML,SA,HS,TOL
Added new Spawn Region DFN tag that allows using another spawn region as a "parent". All properties of this parent will be inherited except for these, which are ignored: ERAS, NPCLIST, ITEMLIST, NPC and ITEM. Syntax for new tag:
GET=# // Inherit a specified spawn region
Added spawn region for animal trainer vendor in Vesper stable
Added spawn region for fur trader/tanner vendors in The Best Hides of Britain
Added spawn region for spinner vendor in The Lord's Clothier's and The Right Fit shops in Britain
Added spawn region for tanner NPC to Nujel'm Tannery (and fixed leatherworker spawn region for same area)
Added spawn regions for banker NPCs in East Bank of Britain, First Bank of Moonglow, Jhelom Bank and Jeweler, Bank of Skara Brae
Added spawn regions for stables, tailor and blacksmith inside Castle British
Added spawn regions for mage shops, mage guilds and farm houses in Moonglow
Added spawn regions for misc vendors and townfolk in multiple cities
Added spawn regions for Fire Island
Updated spawn regions for Dagger Isle/Ice Island
Added spawn regions for forests and jungles in southern Britannia and on various islands including Bucc's Den, Moonglow, Serpent's Hold, and misc unpopulated islands
Added spawn regions for area east of Skara Brae, around Hedge Maze and south of Britain
Added spawn regions for wandering healers outside every dungeon entrance in Britannia and Lost Lands
Re-integrated ocean spawn regions for ocean creatures (dolphin, walrus, water elemental, sea serpent) from the original community-based spawn file
Added reagent spawns in overworld spawn regions in Britannia/Lost Lands
Added special reagent spawns in swamp areas
Added additional overworld spawn regions in Britannia/Lost Lands
Added spawn regions for Khaldun dungeon that spawn some new and some old NPCs:
Old: Zombies, skeletons, skeletal mages, skeletal knights, ancient liches
New: Cursed (and named) NPCs, shadowfiends, zealots of khaldun (knights/summoners), tentacles of the harrower
Updated size and positions of some existing overworld spawn regions
Fixed incorrect spawn region size for small island south of Trinsic
Added switch/door puzzle functionality in Khaldun dungeon using new switch/door combo script (js/item/dungeons/switch_door_combo.js)
Added "smart objects" in Khaldun dungeon that activate when you come close enough (js/item/dungeons/smart_activate_item.js)
Added teleport locations within Khaldun dungeon (js/teleport.scp)
Added custom AIs to existing NPC spawning in Khaldun dungeon:
Ancient Lich (summons other undead, and can turn into one of them for disguise)
Added DFN entries for new NPCs spawning in Khaldun dungeon, some with custom AIs:
[tentacles_of_the_harrower] -> Tentacles of the Harrower (life steal)
[shadowfiend] -> Shadowfiends (seek out and reveal hidden players)
[zealot_knight]/[zealot_summoner] -> Zealots of Khaldun (turn into undead on death, male/female variants)
[cursed] -> Cursed (male/female variants)
[spectralarmor] -> Spectral Armor
Added DFN entries for new (named) NPCs spawning in Khaldun dungeon:
[lysander_gathenwale] -> Lysander Gathenwale
[grimmoch_drummel] -> Grimmoch Drummel
[morg_bergen] -> Morg Bergen
[tavara_sewel] -> Tavara Sewel
Added new NPC DFN entries:
[leatherworker] -> alias for male/female leatherworker vendors
[mapmaker] -> alias for male/female mapmaker vendors
Added new Race DFN entries:
[RACE 29] -> Cursed (enemies of RACE 30)
[RACE 30] -> Zealots (enemies of RACE 29)
Added new book DFN entries for Khaldun journals of Lysander, Tavara and Grimmoch - available as loot from the respective NPCs (dfndata/misc/books.dfn and dfndata/items/misc/books.dfn)
Added 25% chance for hit-animations and hit-SFX to play for targets in combat, instead of playing every time - can get very spammy
Monsters with actual weapons equipped (like Ophidian Enforcer with Halberd/Bardiche) will now get appropriate combat SFX for hitting with that weapon
Updated Healing skill to base cure/resurrection skill requirements on the calculated skill, rather than base skill (js/skill/healing.js)
Fixed an issue where healing with bandages and dying in the process would not properly reset the healing-related tags and skills used
Updated healing script to show a resurrection confirmation menu for players targeted with bandages for resurrect (js/skill/healing.js)
All skill usage states now reset on death, to prevent cases of players being "busy" while trying to use skills that got stuck due to script bugs.
The 'regspawn GM command now supports a new parameter called "max". Updated command syntax:
'regspawn # // perform a single respawn cycle in a specific spawn region
'regspawn all // perform a single respawn cycle across all spawn regions
'regspawn max // respawn ALL spawn regions to MAX capacity in one go
Added new UOX.INI setting that determines the maximum range at which NPCs can initiate attacks on players/NPCs (the old MAXRANGE=10 setting now instead defines max range at which players can initiate attacks on players/NPCs):
MAXNPCAGGRORANGE=10
Optimized performance by significantly reducing the number of line-of-sight checks performed by characters, especially in combat scenarios, or when evaluating potential targets for NPC AIs. The amount of checks done is also affected by the new ini setting for max aggro range.
Fixed an issue where both NPC and player characters would instantly drop one hunger level (from 6 to 5) upon creation since hungerrate was not initialized until after first hunger-event
Updated character priv property from UI16 to UI32, and added a new flag that determines if fame/karma title is hidden for character:
HIDEFAMEKARMATITLE (0x10000)
NPCs will no longer aggro other NPCs if the Z difference between them is greater or equal to 20 (i.e. they're on different floors), unless both are using ranged weapons and both are in range
Fixed an issue where players could get discounts from shopkeepers even though neither player nor shopkeeper were members of a NPC guild (js/npc/ai/shopkeeper.js)
Fixed an issue where the "premium" a player would get when selling items to a shopkeeper in the same NPC guild as them would be 110% extra on top of the item's value, instead of the intended 10% (js/npc/ai/shopkeeper.js) (Thanks, cobrag0318!)
Added missing tall straw hat to tailoring crafting scripts (Thanks, Dragon Slayer!)
Improved error reporting during compilation of individual scripts being reloaded - will now show more context and line number
onCombatEnd JS Event now also triggers when NPCs ignore their target and/or evade during combat
Updated 'decorate command to support saving/loading custom tags on items for world templates. These are stored after a @ symbol in the world template, each custom tag separated by a | symbol, and with each custom tag saved using this syntax: key$type$value
Updated resource-harvesting scripts to use script-specific global (const) variables, to avoid interference between different scripts (js/server/resource/*)
Added new resource-harvesting scripts and added spawn regions for these in fields on farms all over Britannia/Lost Lands
cabbages (js/server/resource/cabbages.js)
canteloupes (js/server/resource/canteloupes.js)
carrots (js/server/resource/carrots.js)
garlic (js/server/resource/garlic.js)
gourds (js/server/resource/gourds.js)
honeydew melons (js/server/resource/honeydewmelon.js)
onions (js/server/resource/onions.js)
pumpkins (js/server/resource/pumpkins.js)
squashes (js/server/resource/squashes.js)
turnips (js/server/resource/turnips.js)
watermelons (js/server/resource/watermelon.js)
Updated CSpawnRegion::FindItemSpotToSpawn() function in cSpawnRegion.cpp to prevent duplicate spawning of exact same item in exact same location
Updated sectionid of all potion and scroll aliases to match main item, so they'll get correctly picked up by NPC shopkeepers (dfndata/items/magic/potions.dfn and scrolls.dfn)
Specified sectionid for backpacks, so it also gets applied to packs added using the alias [backpack] (dfndata/items/misc/provisions.dfn)
Fixed a code issue that prevented players from selling empty containers to NPC shopkeepers willing to buy such containers
Fixed an issue where field-spells (wall of stone, poison field, etc) would ignore dynamic/static items that should block these
Fixed an issue where field-spells could be cast into houses from the outside by standing next to a wall and targeting self
Fixed a War/Peace-mode desync between client and server by having server always notify client (using war-toggle packet) when the "at war" flag is toggled for player character
Fixed an issue with hiding skill that wouldn't allow player to hide after having acquired self as target in combat (through spellcasting, for instance) (Thanks, Dragon Slayer!)
Fixed an issue where mana/reagents were consumed and skillcheck performed before all spellcast-validations had succeeded, resulting in the occasional loss of reagents/mana when spellcasting was disallowed (code and js/magic/clumsy.js and level1targ.js)
Fixed an issue with lack of criminal-flagging for casting of hostile spells scripted in JS (clumsy, magic arrow, feeblemind) vs blue targets (js/magic/clumsy.js and level1targ.js)
Fixed some issues with Line-of-Sight checking code that returned incorrect results, which amongst other things affected spellcasting in areas with uneven terrain
Fixed some issues with movement code and climbing of ladders, in particular the rope ladder in the 2-story log cabin. Code now sets a "is climbing" flag when character steps onto a rope ladder, and uses that to help resolve some edge cases, and then unsets it when they step off.
Renamed section headers of some map-items in DFNs from "locationname" to "locationnamemap" for clarity (example: "britain" to "britainmap")
Fixed broken "map wrapping" when sailing to edges of map in Felucca or Trammel
Fixed a server crash related to attempts at reading data from invalid map tiles
2025-06-27 08:40:02 +08:00
|
|
|
if( ValidateObject( tempItem ) && tempItem->GetInstanceId() == instanceId )
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-08 13:08:12 +08:00
|
|
|
if( tempItem->GetId( 1 ) >= 0x40 && tempItem->CanBeObjType( OT_MULTI ))
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2023-03-08 13:08:12 +08:00
|
|
|
dynZ = MultiHeight( tempItem, x, y, z, maxZ );
|
|
|
|
|
}
|
|
|
|
|
else if( tempItem->GetX() == x && tempItem->GetY() == y )
|
|
|
|
|
{
|
|
|
|
|
SI08 zTemp = static_cast<SI08>( tempItem->GetZ() + TileHeight( tempItem->GetId() ));
|
|
|
|
|
if(( zTemp <= z + maxZ ) && zTemp > dynZ )
|
|
|
|
|
{
|
|
|
|
|
dynZ = zTemp;
|
|
|
|
|
}
|
2022-06-15 07:04:28 -04:00
|
|
|
}
|
Housing Revamp and more
Updated JS SysMessage function to accept up to 10 extra, optional arguments, which can be used with dictionary messages that require additional parameters like %s or %i
Added new type of house privilege in cMultiObj.cpp to keep track of friends of the multi - HOUSEPRIV_FRIEND - which is stored during worldsaves as one or more Friend=<player serial> tags in house.wsc
Added new type of house privilege in cMultiObj.cpp to keep track of guests of the multi - HOUSEPRIV_GUEST - which is stored during worldsaves as one or more Guest=<player serial> tags in house.wsc
When items are created for houses upon house placement, a reference to the multi's serial is now stored in the house sign's MORE property to allow easier tracking of which house a particular sign belongs to
Added tracking of new, persistent properties for houses via cMultiObj.cpp/h:
lockdowns, secure containers, vendors, guests, friends, owners, ban location, public status, number of visits, timestamps
Added a multitude of new methods in cMultiObj.cpp/h to assist in improving the functionality of houses
Added new tags for houses in house.dfn (default values applied if tag not specified):
MAXSECURECONTAINERS=4 - Max amount of secure containers allowed in a multi
MAXLOCKDOWNS=256 - Max amount of lockdowns allowed in a multi
MAXVENDORS=10 - Max amount of vendors allowed in a multi
MAXBANS=50 - Max amount of bans in a multi's ban list
MAXFRIENDS=50 - Max amount of friends in a multi's friend list
MAXGUESTS=50 - Max amount of guests in a multi's guest list
MAXOWNERS=8 - Max amount of owners and co-owners in a multi's owner list
MAXTRASHCONTAINERS=1 - Max amount of trash containers allowed in multi
SCRIPT=<scriptID> - Assign a JS script-ID directly to a multi
FRONTDOOR - indicates that a door is the front door of a house. Cannot be locked in public houses!
INTERIORDOOR - indicates that a door is an interior door of a house. Can be locked in public houses.
BANX - Location X offset for multi's ban location, if not used, will try to use SE corner of multi instead
BANY - Location Y offset for multi's ban location, if not used, will try to use SE corner of multi instead
Added JS Event:
onHouseCommand( tSock, multiObj, cmdID ) - For handling spoken house commands via JS scripts attached to multi.
Updated JS Events:
onEntrance() - can now trigger both for multi being entered and/or object entering
onLeaving() - can now trigger both for multi being left and/or object entering
onSpeech() - can now also trigger for items (in addition to chars) with event & script attached, if UOX.INI setting ITEMSDETECTSPEECH is enabled
Added JS Multi methods:
.IsBoat() - Returns whether the item (or multi) is a boat
.IsOwner( playerToCheck ) - Returns whether a player is the owner of a multi
.IsOnOwnerList( playerToCheck ) - Returns whether a player is on the (co-)owner list of a multi
.IsOnFriendList( playerToCheck ) - Returns whether a player is on the friend list of a multi
.IsOnGuestList( playerToCheck ) - Returns whether a player is on the guest list of a multi
.IsOnBanList( playerToCheck ) - Returns whether a player is on the ban list of a multi
.AddToFriendList( playertoAdd ) - Adds player to the friend list of a multi
.RemoveFromFriendList( playertoRemove ) - Removes player from the friend list of a multi
.AddToGuestList( playertoAdd ) - Adds player to the guest list of a multi
.RemoveFromGuestList( playertoRemove ) - Removes player from the guest list of a multi
.ClearOwnerList() - Clears all entries from a multi's (co-)owner list
.ClearFriendList() - Clears all entries from a multi's friend list
.ClearGuestList() - Clears all entries from a multi's guest list
.ClearBanList() - Clears all entries from a multi's ban list
.SecureContainer( itemToSecure ) - Secures a container in a multi
.UnsecureContainer( itemToUnsecure ) - Unsecures a container in a multi
.IsSecureContainer( itemToCheck ) - Checks if specified item is a secure container in a multi
.LockDownItem( itemToLockDown) - Locks down an item in a multi
.ReleaseItem( itemToRelease ) - Releases a locked down item in a multi
.KillKeys() - Deletes ALL keys associated with a multi
.AddTrashCont( itemToAdd ) - Add trash container to multi's list of trash containers
.RemoveTrashCont( itemToRemove ) - Remove trash container from multi's list of trash containers
Added JS Item (Multi only) properties:
.lockdowns - Get the number of lockdowns in a multi
.maxLockdowns - Get/Set the max number of lockdowns allowed in a multi
.secureContainers - Get the number of secure containers in a multi
.maxSecureContainers - Get/Set the max number of secure containers allowed in a multi
.trashContainers - Get the number of trash containers in a multi
.maxTrashContainers - Get/Set the max number of trash containers allowed in a multi
.friends - Get the number of friends in a multi's friend list
.maxFriends - Get/Set the max number of friends allowed in a multi's friend list
.guests - Get the number of guests in a multi's guest list
.maxGuests - Get/Set the max number of guests allowed in a multi's guest list
.owners - Get the number of owners in a multi's owner list
.maxOwners - Get/Set the max number of owners allowed in a multi's owner list
.bans - Get the number of banned players in a multi's ban list
.maxBans - Get/Set the max number of banned players allowed in a multi's ban list
.vendors - Get the number of player vendors in a multi
.maxVendors - Get the max number of player vendors allowed in a multi
.deed - Get the item sectionID for deed used to place multi
.isPublic - Get/Set the private/public state of a multi
.buildTimestamp - Get the timestamp for when the house was originally placed
.tradeTimestamp - Get the timestamp for when the house was last traded to another player
.banX - Get/Set the ban location X offset for the multi
.banY - Get/Set the ban location Y offset for the multi
Added JS Character properties:
.multi = Get/Set the multi object the character is in
.accountNum = Get the account number the character belongs to
.housesOwned = Get a count of houses owned by the character
.housesCoOwned = Get a count of houses co-owned by the character
Updated JS cBaseObject Methods .FirstItem(), .NextItem() and .FinishedItems() to also support iterating through items in multis
Updated JS multi Methods .FirstChar(), .NextChar() and .FinishedChars() to support an additional parameter to specify what kind of characters to loop through:
"default" or no parameter - all characters inside the multi
"owner" - players on multi's owner list
"friend" - players on multi's friend list
"guest" - players on multi's guest list
"banned" - players on multi's ban list
Added new INI tags to a new section of uox.ini called [houses]
DECAYTIMERINHOUSE=3600 // Decay timer in seconds for non-locked down items inside houses
PROTECTPRIVATEHOUSES=1 // Toggles whether private houses will automatically boot unauthorized visitors (1) or not (0)
TRACKHOUSESPERACCOUNT=1 // Toggles whether to track (and restrict) house ownership per account (1) or per character (0)
MAXHOUSESOWNABLE=1 // Specifies the max amount of houses a player can own per account/char, depending on how house ownership is tracked
MAXHOUSESCOOWNABLE=10 // Specifies the max amount of houses a player can co-own per character
CANOWNANDCOOWNHOUSES=1 // Toggles whether players can own and co-own houses at the same time
COOWNHOUSESONSAMEACCOUNT=1 // Toggles whether characters on same account as house owner will be treated as co-owners
Added new INI tags in [settings] section of uox.ini:
ITEMSDETECTSPEECH=0 // If enabled, server will search for nearby items with onSpeech JS event running whenever a character speaks. Disabled by default.
MAXPLAYERPACKITEMS=125 // Defines max item capacity for player (and NPC) backpacks. Defaults to 125.
Moved most of the existing house functionality to JS and expanded upon it to reach feature parity with houses in regular UO around Publish 15/16, with various extras thrown in for good measure and all functionality being customizable:
js/server/house/house.js (15000) - handles detection of house commands and characters entering/leaving houses
js/server/house/houseSign.js (15001) - contains and handles all house-related gumps/menus and what is shown when players interact with house sign
js/server/house/houseCommands.js (15002) - handles functionality of house commands and other functionality such as transfer of ownership, demolishing house, etc.
js/server/house/houseDeed.js (15003) - handles initial rules that allow/disallow placement of additional houses for players
All house-related menus now fully handled through JS
All house commands and other functionality now fully handled through JS
Removed redundant hard-coded house functionality
Implemented Co-owners, friends, guests for houses, with access rules in place for entry, lockdowns, house commands, etc.
Implemented Private and Public houses
Implemented Secure Containers and Trash Barrels
Definable max lockdowns, secure containers, player vendors, bans, friends, guests, owners, trash containers and more - per house type
JS scripts can now be attached directly to houses
Doors in houses can be marked as front doors or interior doors, and will be treated differently with regards to private and public houses
Added new item to dfndata/items/containers/misc.dfn - [trashbarrel]
Added new JS script (js/items/trashbarrel.js) with trash barrel functionality for houses. Trash barrels that are marked as secure containers are only accessible by owners, co-owners and friends of the house. Various options available at top of script.
Updated js/items/axe.js to support chopping up trash barrels and house add-ons in houses owned by the player
Fixed an issue with house doors being left behind after demolishing houses while their doors were open
Fixed an issue where GMs could be banned from player houses
Added Line of Sight checks to speech, to give players some privacy in their own homes
Updated house placement code to more accurately check for other multis, dynamic and static objects when placing houses; now requires free space around each house that cannot be blocked by other houses or items that can block player movement, and disallows placement of houses on roads
Updated house placement code to move characters blocking house placement to SE corner of the house
Updated house placement code to disallow placing houses in guarded regions, or in dungeons
Added new DFN tag for regions to enable/disable player houses in specific regions: HOUSING=0/1
Added new region (247) that covers path to Valley of Eodon in Felucca
Added new region (248) that covers Valley of Eodon in Ter-Mur, with player housing disabled
Added new region (249) that covers entire T2A lands, with player housing disabled
Updated SPACEX and SPACEY values for all houses in dfndata/house/house.dfn to match updated house placement code
Added new JS property to Regions that can be used to determine or change state of player housing in a region: .canPlaceHouse()
Updated rules for usage of dye tubs to dye locked down items; now only house owners or co-owners may dye locked down items
Updated rules for usage of the following locked down items in a house, which are now only usable by house owners and co-owners
Dyes, Guildstone Deeds, Recall Runes (renaming), Rename Deeds, Townstone Deeds, House Deeds, Boat Models, Player Vendor Deeds, Ore, Hair Dye
Updated rules for usage of the following locked down items in a house, which are now only usable by house owners, co-owners and friends:
Keys, Dye Tubs, Magic Scrolls, Fireworks Wands, Magic Wands, Smithing Tools, Mining Tools, Fishing Poles
Updated item lockdown rules to allow locking down (and releasing) items in a container as long as the container is locked down, and to only allow releasing a locked down container if it's empty of locked down items
Updated item lockdown rules to only allow locking down movement-blocking items further than 2 tiles away from doors
Updated rules for releasing items in houses - now the house owner can release any locked down items, co-owners can release items locked down by themselves or by friends, while friends can release only items locked down by themselves
Added some feedback to player about why their attempted house placement failed
Items added by GMs directly into multis will now decay based on the house-specific decay timer instead of the regular one
Fixed an issue that could cause items to almost instantly decay after being released from lockdown in a house
Placing house add-ons now properly takes into account SPACEX and SPACEY values when checking if they can fit in selected area of houses
Re-added SPACEX and SPACEY values for Pentagram and Loom house add-ons
House add-ons can now be converted back into house add-on deeds by chopping them with an axe
Added new item type - IT_HOUSEADDON (201) - used by house add-ons placed in player houses
Fixed a bug where keys would stop working after being added to a keyring, and would turn into blank keys upon release from the keyring
Added visitor count for public player houses, which keeps track of how many visits a public house has received, with each player counted max 1 time every 24 hours
Fixed an issue with FindPlayersInOldVisrange() where it didn't take into account that players could see buildings further away than the standard update range. This could cause players to see ghost images of buildings if they were at the "right" distance when the building was being demolished
Added NODECAY tag to all signs and doors in dfndata/house/house.dfn
Added FRONTDOOR or INTERIORDOOR (as appropriate) to all doors in dfndata/house/house.dfn
Added BANX and BANY to specify ban location for some houses in dfndata/house/house.dfn instead of relying on finding SE corner automatically
Implemented strongboxes (js/server/house/strongbox.js) for co-owners of a house, which can be placed with the house command "i wish to place a strongbox". Max capacity is 25 items
Updated 'REMOVE command to take an optional parameter - itemID. If supplied, the command will remove all items with this itemID from a targeted container
Fixed a bug when checking if dynamic items were blocking valid spawn locations for NPCs, some function arguments were in the wrong order!
Improved code that finds valid spawn locations for items and NPCs spawned via spawn regions. As server gradually builds up lists of valid spawn locations per region over time, it will start using these lists more often, rather than always look for brand new spawn locations.
Fixed a bug with CMulHandler::CheckStaticFlag() that prevented NPCs from spawning inside buildings with no static floors!
Fixed an issue with repeating commands that prevented GMs from being able to cancel them when using the ClassicUO client
Exposed character property .accountNum to JS engine
Extended CDataList class to include a Clear() method for clearing lists
Updated JS File method .Open() to support an optional, third argument - subFolderName - that defines in which sub-folder of UOX3/shared/ to store/look for a file. If no third argument is supplied, UOX3 will default to using the shared folder itself.
Updated JS File method .Length() to return a value of -1 for files that don't exist
Added new code function, exposed to JS engine with same parameters, which simply checks if a given tile ID has a specific flag
bool CheckTileFlag( UI16 itemID, TILEFLAG flagToCheck )
Added JS function used to find the root container of an item (if any)
FindRootContainer( itemSerial )
FindRootContainer( item )
Added new JS function that allows deleting files from UOX3/shared/ folder or subfolders of shared folder. If no subFolderName is provided, looks for file directly in shared folder itself. Restrictions on file- and folder-names apply.
bool DeleteFile( fileName, subFolderName )
Added new JS functions for checking if a specific client or server feature is enabled. See documentation for full list of client/server features.
GetClientFeature( bitNum ) // Returns true if specified client feature is enabled on server
GetServerFeature( bitNum ) // Returns true if specified server feature is enabled on server
Added new JS function for returning the value of almost any server setting from UOX.INI
GetServerSetting( settingNameInDoubleQuotes )
Updated JS function DoesDynamicBlock() with two new parameters - checkOnlyMultis and checkOnlyNonMultis
Updated JS function DoesMapBlock() with two new parameters - checkMultiPlacement and checkForRoad
Fixed an issue where a LoS check would prevent players from accessing containers in their own backpack
Added new functions in findfuncs.cpp to make it easier to find items near another object or location:
findNearbyItems( object, distance )
findNearbyItems( x, y, worldNumber, instanceID, distance )
Added new Item property - maxItems - used by containers to determine their max item capacity
Added new Item property - totalItemCount - used to get total item count in a container (including sub-containers)
Added check for max item capacity when creating new items that are added to a character's backpack - items will be created below character's feet if backpack is full!
Added new DFN tag for items, used by containers to determine item capacity for a given container:
MAXITEMS=# // 125 is the default for all containers if not set
Added new JS Item properties:
.maxItems // gets/sets item capacity for a given container
.totalItemCount // gets total item count in a container, including sub-containers
Updated item tooltips for containers to show accurate total item count, as well as to display max item capacity
Fixed a bug where picking up items from a non-locked down pile of items on the floor inside a multi could cause the remaining pile to be seen as no longer inside the multi, disallowing locking it back down and causing it to decay based on regular decay timer instead of house-specific one
Updated JS command set to allow setting poison-level on items ('set poison #) and hunger-level on characters ('set hunger #)
Fixed an issue with js/item/food.js that prevented poisoned food from poisoning characters when eaten
Fixed an issue with js/skill/poisoning.js that prevented players from poisoning food!
Updated various JS scripts and hardcoded targeting functions to disallow the targeting of locked down resources using skills and tools
Updated JS Method TextMessage() to support three extra, optional parameters. Note that if one optional parameter is included, all preceding optional parameters are also required!
speechTarget - What kind of target is this message intended for?
0 - Only visible for sender and receiver of message
1 - Visible to all players in range
2 - Visible to all NPCs and players in range
3 - Visible to all PCs everywhere + NPCs in range
4 - Visible to all PCs everywhere (broadcast)
5 - Only visible for the receiver of the message
speechTargetSerial - The serial of the receiver of the message, used if speechTarget is 0 or 5
speechFontType - The type of font to display the text in. Defaults to normal.
0 - Bold
1 - Normal with shadow
2 - Bold with shadow
3 - Normal
4 - Gothic
5 - Italic
6 - Small, dark
7 - Colourful
8 - Runic (only works with CAPS)
9 - Small, light
Added timestamp to worldsaves in console, to make it easier to see when a particular world-save was done
Added info about compiler/environment displayed at the top of the UOX3 console during startup
Updated dictionary files with new messages primarily related to housing
2020-11-04 02:00:37 +08:00
|
|
|
}
|
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms
Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt)
Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri)
Updated SpiderMonkey from v1.6.0 to v1.7.0
Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri)
Added StringUtility file with general common string manipulation functions (punt)
Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt)
Overall code cleanup to remove/replace platform-dependent code (punt)
Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt)
Replaced usage of char in many places with std::string (punt)
Started process of replacing UString usage with functions provided through StringUtility instead (punt)
Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt)
Replaced platform specific time handling by using cross-platform chrono library (punt)
Removed UOX namespace to reduce complexity (punt)
Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt)
Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt)
Removed some platform specific files like uoxlinux.h, which is no longer required (punt)
Removed legacy crash protection code, and removed support for cluox (punt)
Removed legacy "support" for Borland compiler (punt)
Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri)
Removed legacy BUILD folder with outdated compilation instructions (Xuri)
Removed old Changelog file (merged into Changelog.txt) (Xuri)
Fixed a pointer bug for items in multis on world load (punt)
Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt)
Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt)
Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt)
Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt)
Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt)
Added some new commands to js/commands/custom/misc-cmd.js (Xuri)
cont // Targeted item will be made a container, set to nondecay and movable 2
endfight // Targeted character (and character being fought) will stop fighting
getmulti // Get multiObject for targeted item
finditem // Find item at layer X
movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen)
Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri)
Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
|
|
|
}
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return dynZ;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::MapElevation()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Returns the map elevation at given coordinates, we'll assume since its land
|
|
|
|
|
//| the height is inherently 0
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2023-11-18 03:15:38 -06:00
|
|
|
auto CMulHandler::MapElevation( std::int16_t x, std::int16_t y, std::uint8_t worldNumber, bool ignoreVoid ) -> std::int8_t
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
Minor pathfinding revamp plus misc fixes
Updated target-based 'wipe command to also affect valid NPCs (non-invulnerable, non-pets) (js/commands/wipe.js)
NPC admin gump (js/commands/wholist.js) will now force-refresh on next open after NPCs have been removed via the remove button in the menu
Spawn Object admin gump (js/commands/spawnadmin.js) will now force-refresh on next open after spawn objects have been removed via the remove button in the menu
Added three new GM commands (js/commands/targeting/xwalk.js) that can be used to control NPCs remotely:
'xwalk // Makes targeted NPC pathfind and walk to target location
'xrun // Makes targeted NPC pathfind and run to target location
'xturn // Makes targeted NPC turn towards target location
Updated AdvancedPathfinding() in movement.cpp to include two optional parameters
allowPartial // if true, move even if calculated path is blocked, until blocked (defaults to false)
ignoreDoors // if true, ignore doors during pathfinding calculations and calculate the path is if the door was not there (defaults to false)
Updated .WalkTo() and .RunTo() JS Character Methods to support the two additional pathfinding parameters, and also to support maxSteps values beyond 255
Updated pathfinding heuristic from Manhattan (4-way) to Octile (8-way) distance for improved pathfinding accuracy and increased performance with diagonal movement
In some situations, UOX3 will now calculate a new partial path for NPCs who failed to follow their assigned path, to get them closer to their final destination
Optimized pathfinding logic for NPCs following a target (like pets/hirelings, or NPCs in combat), to reduce the amount of pathfinding calculations required when target is moving. The NPCs will now keep track of the general direction towards their target, and if the NPCs are already heading in the right direction, they'll keep going as long as they have a path left to follow or until direction towards target has changed. This also eliminates a problem where NPCs would stick to their path until they reach the end, even if target has gone in a different direction.
Updated logic for how NPCs turn during pathfinding. Instead of adding an extra "push" for direction into the calculated path itself to ensure NPC will both turn and move in that direction, which allowed some inaccuracies to creep into the calculated paths, that extra push is now handled while NPC is executing the path instead, whenever direction changes are needed
Partial pathfinding is now enabled for fleeing NPCs by default, to increase their chances of getting further away from their opponent in combat
Partial pathfinding is now enabled for NPCs in water by default, to allow them to get as close as possible to their opponent in combat
Fixed an issue where NPC movement speeds would misbehave at certain speeds where the calculated movement time would get rounded down to zero
NPCs will now play a fidgeting animation if they've remained motionless for 3 seconds or more while not in a state of actively trying to move/pathfind
Increased max pathfinding steps for NPCs in combat from 50 to 75
Fixed an issue where NPCs would stop and wait when they should have been moving, after successful pathfinding calculation
Fixed an issue where NPCs that ignore a target and enter evade state would not leave combat
Added two new JS Character properties that can be used to evaluate pathfinding success (for instance in combination with onPathFindEnd Event), and/or opens for manipulating pathfinding target locations via scripts:
.pathTargX // Current NPC pathfinding target, X coordinate
.pathTargY // Current NPC pathfinding target, Y coordinate
2025-05-05 00:03:09 +08:00
|
|
|
const auto &map = SeekMap( x, y, worldNumber );
|
|
|
|
|
// make sure nothing can move into black areas
|
Small update
Fixed an issue with an internal movement check that prevented characters from moving in valid map areas in Felucca/Trammel from X 6144 to X 7168
Fixed an issue where .instanceID property was misspelled in 'xgo GM command script, causing characters to be teleported to an out of bounds area where they would no longer be saved (js/commands/targeting/x.js)
Added some additional error-checking to .Teleport()/.SetLocation() JS Method to prevent script-accidents from sending characters out of bounds.
Updated Poisoning skill to add poison-charges to weapons being poisoned. Charges are consumed when applying poison in combat (js/skill/poisoning.js)
Updated combat code to consume poison-charges if a poisoned weapon is used to poison an opponent
Updated shoplists for Blacksmiths and Weaponsmiths - they now buy/sell longswords (dfndata/items/shoplist.dfn)
Updated MageShopping shoplist for mage vendors - they now buy/sell mass curse scrolls (dfndata/items/shoplist.dfn)
Added new Spawn Region DFN tag that can specify which era or eras of UO (Multiple comma-separated entries supported) a given spawn region is valid for. Spawn region not valid for core shard era will be ignored. Syntax:
ERAS=UO,T2A,UOR,LBR,AOS,SE,ML,SA,HS,TOL
Added new Spawn Region DFN tag that allows using another spawn region as a "parent". All properties of this parent will be inherited except for these, which are ignored: ERAS, NPCLIST, ITEMLIST, NPC and ITEM. Syntax for new tag:
GET=# // Inherit a specified spawn region
Added spawn region for animal trainer vendor in Vesper stable
Added spawn region for fur trader/tanner vendors in The Best Hides of Britain
Added spawn region for spinner vendor in The Lord's Clothier's and The Right Fit shops in Britain
Added spawn region for tanner NPC to Nujel'm Tannery (and fixed leatherworker spawn region for same area)
Added spawn regions for banker NPCs in East Bank of Britain, First Bank of Moonglow, Jhelom Bank and Jeweler, Bank of Skara Brae
Added spawn regions for stables, tailor and blacksmith inside Castle British
Added spawn regions for mage shops, mage guilds and farm houses in Moonglow
Added spawn regions for misc vendors and townfolk in multiple cities
Added spawn regions for Fire Island
Updated spawn regions for Dagger Isle/Ice Island
Added spawn regions for forests and jungles in southern Britannia and on various islands including Bucc's Den, Moonglow, Serpent's Hold, and misc unpopulated islands
Added spawn regions for area east of Skara Brae, around Hedge Maze and south of Britain
Added spawn regions for wandering healers outside every dungeon entrance in Britannia and Lost Lands
Re-integrated ocean spawn regions for ocean creatures (dolphin, walrus, water elemental, sea serpent) from the original community-based spawn file
Added reagent spawns in overworld spawn regions in Britannia/Lost Lands
Added special reagent spawns in swamp areas
Added additional overworld spawn regions in Britannia/Lost Lands
Added spawn regions for Khaldun dungeon that spawn some new and some old NPCs:
Old: Zombies, skeletons, skeletal mages, skeletal knights, ancient liches
New: Cursed (and named) NPCs, shadowfiends, zealots of khaldun (knights/summoners), tentacles of the harrower
Updated size and positions of some existing overworld spawn regions
Fixed incorrect spawn region size for small island south of Trinsic
Added switch/door puzzle functionality in Khaldun dungeon using new switch/door combo script (js/item/dungeons/switch_door_combo.js)
Added "smart objects" in Khaldun dungeon that activate when you come close enough (js/item/dungeons/smart_activate_item.js)
Added teleport locations within Khaldun dungeon (js/teleport.scp)
Added custom AIs to existing NPC spawning in Khaldun dungeon:
Ancient Lich (summons other undead, and can turn into one of them for disguise)
Added DFN entries for new NPCs spawning in Khaldun dungeon, some with custom AIs:
[tentacles_of_the_harrower] -> Tentacles of the Harrower (life steal)
[shadowfiend] -> Shadowfiends (seek out and reveal hidden players)
[zealot_knight]/[zealot_summoner] -> Zealots of Khaldun (turn into undead on death, male/female variants)
[cursed] -> Cursed (male/female variants)
[spectralarmor] -> Spectral Armor
Added DFN entries for new (named) NPCs spawning in Khaldun dungeon:
[lysander_gathenwale] -> Lysander Gathenwale
[grimmoch_drummel] -> Grimmoch Drummel
[morg_bergen] -> Morg Bergen
[tavara_sewel] -> Tavara Sewel
Added new NPC DFN entries:
[leatherworker] -> alias for male/female leatherworker vendors
[mapmaker] -> alias for male/female mapmaker vendors
Added new Race DFN entries:
[RACE 29] -> Cursed (enemies of RACE 30)
[RACE 30] -> Zealots (enemies of RACE 29)
Added new book DFN entries for Khaldun journals of Lysander, Tavara and Grimmoch - available as loot from the respective NPCs (dfndata/misc/books.dfn and dfndata/items/misc/books.dfn)
Added 25% chance for hit-animations and hit-SFX to play for targets in combat, instead of playing every time - can get very spammy
Monsters with actual weapons equipped (like Ophidian Enforcer with Halberd/Bardiche) will now get appropriate combat SFX for hitting with that weapon
Updated Healing skill to base cure/resurrection skill requirements on the calculated skill, rather than base skill (js/skill/healing.js)
Fixed an issue where healing with bandages and dying in the process would not properly reset the healing-related tags and skills used
Updated healing script to show a resurrection confirmation menu for players targeted with bandages for resurrect (js/skill/healing.js)
All skill usage states now reset on death, to prevent cases of players being "busy" while trying to use skills that got stuck due to script bugs.
The 'regspawn GM command now supports a new parameter called "max". Updated command syntax:
'regspawn # // perform a single respawn cycle in a specific spawn region
'regspawn all // perform a single respawn cycle across all spawn regions
'regspawn max // respawn ALL spawn regions to MAX capacity in one go
Added new UOX.INI setting that determines the maximum range at which NPCs can initiate attacks on players/NPCs (the old MAXRANGE=10 setting now instead defines max range at which players can initiate attacks on players/NPCs):
MAXNPCAGGRORANGE=10
Optimized performance by significantly reducing the number of line-of-sight checks performed by characters, especially in combat scenarios, or when evaluating potential targets for NPC AIs. The amount of checks done is also affected by the new ini setting for max aggro range.
Fixed an issue where both NPC and player characters would instantly drop one hunger level (from 6 to 5) upon creation since hungerrate was not initialized until after first hunger-event
Updated character priv property from UI16 to UI32, and added a new flag that determines if fame/karma title is hidden for character:
HIDEFAMEKARMATITLE (0x10000)
NPCs will no longer aggro other NPCs if the Z difference between them is greater or equal to 20 (i.e. they're on different floors), unless both are using ranged weapons and both are in range
Fixed an issue where players could get discounts from shopkeepers even though neither player nor shopkeeper were members of a NPC guild (js/npc/ai/shopkeeper.js)
Fixed an issue where the "premium" a player would get when selling items to a shopkeeper in the same NPC guild as them would be 110% extra on top of the item's value, instead of the intended 10% (js/npc/ai/shopkeeper.js) (Thanks, cobrag0318!)
Added missing tall straw hat to tailoring crafting scripts (Thanks, Dragon Slayer!)
Improved error reporting during compilation of individual scripts being reloaded - will now show more context and line number
onCombatEnd JS Event now also triggers when NPCs ignore their target and/or evade during combat
Updated 'decorate command to support saving/loading custom tags on items for world templates. These are stored after a @ symbol in the world template, each custom tag separated by a | symbol, and with each custom tag saved using this syntax: key$type$value
Updated resource-harvesting scripts to use script-specific global (const) variables, to avoid interference between different scripts (js/server/resource/*)
Added new resource-harvesting scripts and added spawn regions for these in fields on farms all over Britannia/Lost Lands
cabbages (js/server/resource/cabbages.js)
canteloupes (js/server/resource/canteloupes.js)
carrots (js/server/resource/carrots.js)
garlic (js/server/resource/garlic.js)
gourds (js/server/resource/gourds.js)
honeydew melons (js/server/resource/honeydewmelon.js)
onions (js/server/resource/onions.js)
pumpkins (js/server/resource/pumpkins.js)
squashes (js/server/resource/squashes.js)
turnips (js/server/resource/turnips.js)
watermelons (js/server/resource/watermelon.js)
Updated CSpawnRegion::FindItemSpotToSpawn() function in cSpawnRegion.cpp to prevent duplicate spawning of exact same item in exact same location
Updated sectionid of all potion and scroll aliases to match main item, so they'll get correctly picked up by NPC shopkeepers (dfndata/items/magic/potions.dfn and scrolls.dfn)
Specified sectionid for backpacks, so it also gets applied to packs added using the alias [backpack] (dfndata/items/misc/provisions.dfn)
Fixed a code issue that prevented players from selling empty containers to NPC shopkeepers willing to buy such containers
Fixed an issue where field-spells (wall of stone, poison field, etc) would ignore dynamic/static items that should block these
Fixed an issue where field-spells could be cast into houses from the outside by standing next to a wall and targeting self
Fixed a War/Peace-mode desync between client and server by having server always notify client (using war-toggle packet) when the "at war" flag is toggled for player character
Fixed an issue with hiding skill that wouldn't allow player to hide after having acquired self as target in combat (through spellcasting, for instance) (Thanks, Dragon Slayer!)
Fixed an issue where mana/reagents were consumed and skillcheck performed before all spellcast-validations had succeeded, resulting in the occasional loss of reagents/mana when spellcasting was disallowed (code and js/magic/clumsy.js and level1targ.js)
Fixed an issue with lack of criminal-flagging for casting of hostile spells scripted in JS (clumsy, magic arrow, feeblemind) vs blue targets (js/magic/clumsy.js and level1targ.js)
Fixed some issues with Line-of-Sight checking code that returned incorrect results, which amongst other things affected spellcasting in areas with uneven terrain
Fixed some issues with movement code and climbing of ladders, in particular the rope ladder in the 2-story log cabin. Code now sets a "is climbing" flag when character steps onto a rope ladder, and uses that to help resolve some edge cases, and then unsets it when they step off.
Renamed section headers of some map-items in DFNs from "locationname" to "locationnamemap" for clarity (example: "britain" to "britainmap")
Fixed broken "map wrapping" when sailing to edges of map in Felucca or Trammel
Fixed a server crash related to attempts at reading data from invalid map tiles
2025-06-27 08:40:02 +08:00
|
|
|
if( map.artInfo == nullptr || ( !ignoreVoid && map.isVoid() ))
|
Minor pathfinding revamp plus misc fixes
Updated target-based 'wipe command to also affect valid NPCs (non-invulnerable, non-pets) (js/commands/wipe.js)
NPC admin gump (js/commands/wholist.js) will now force-refresh on next open after NPCs have been removed via the remove button in the menu
Spawn Object admin gump (js/commands/spawnadmin.js) will now force-refresh on next open after spawn objects have been removed via the remove button in the menu
Added three new GM commands (js/commands/targeting/xwalk.js) that can be used to control NPCs remotely:
'xwalk // Makes targeted NPC pathfind and walk to target location
'xrun // Makes targeted NPC pathfind and run to target location
'xturn // Makes targeted NPC turn towards target location
Updated AdvancedPathfinding() in movement.cpp to include two optional parameters
allowPartial // if true, move even if calculated path is blocked, until blocked (defaults to false)
ignoreDoors // if true, ignore doors during pathfinding calculations and calculate the path is if the door was not there (defaults to false)
Updated .WalkTo() and .RunTo() JS Character Methods to support the two additional pathfinding parameters, and also to support maxSteps values beyond 255
Updated pathfinding heuristic from Manhattan (4-way) to Octile (8-way) distance for improved pathfinding accuracy and increased performance with diagonal movement
In some situations, UOX3 will now calculate a new partial path for NPCs who failed to follow their assigned path, to get them closer to their final destination
Optimized pathfinding logic for NPCs following a target (like pets/hirelings, or NPCs in combat), to reduce the amount of pathfinding calculations required when target is moving. The NPCs will now keep track of the general direction towards their target, and if the NPCs are already heading in the right direction, they'll keep going as long as they have a path left to follow or until direction towards target has changed. This also eliminates a problem where NPCs would stick to their path until they reach the end, even if target has gone in a different direction.
Updated logic for how NPCs turn during pathfinding. Instead of adding an extra "push" for direction into the calculated path itself to ensure NPC will both turn and move in that direction, which allowed some inaccuracies to creep into the calculated paths, that extra push is now handled while NPC is executing the path instead, whenever direction changes are needed
Partial pathfinding is now enabled for fleeing NPCs by default, to increase their chances of getting further away from their opponent in combat
Partial pathfinding is now enabled for NPCs in water by default, to allow them to get as close as possible to their opponent in combat
Fixed an issue where NPC movement speeds would misbehave at certain speeds where the calculated movement time would get rounded down to zero
NPCs will now play a fidgeting animation if they've remained motionless for 3 seconds or more while not in a state of actively trying to move/pathfind
Increased max pathfinding steps for NPCs in combat from 50 to 75
Fixed an issue where NPCs would stop and wait when they should have been moving, after successful pathfinding calculation
Fixed an issue where NPCs that ignore a target and enter evade state would not leave combat
Added two new JS Character properties that can be used to evaluate pathfinding success (for instance in combination with onPathFindEnd Event), and/or opens for manipulating pathfinding target locations via scripts:
.pathTargX // Current NPC pathfinding target, X coordinate
.pathTargY // Current NPC pathfinding target, Y coordinate
2025-05-05 00:03:09 +08:00
|
|
|
{
|
|
|
|
|
return ILLEGAL_Z;
|
|
|
|
|
}
|
|
|
|
|
return map.altitude;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::TileHeight()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Height of a given tile (If climbable it return 1/2 its height).
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::TileHeight( std::uint16_t tilenum ) -> std::int8_t
|
|
|
|
|
{
|
|
|
|
|
return SeekTile( tilenum ).ClimbHeight();
|
2022-06-14 17:53:00 -04:00
|
|
|
}
|
2002-04-07 21:27:53 +00:00
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::Height()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Returns new height of player who walked to X/Y but from OLDZ
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::Height( std::int16_t x, std::int16_t y, std::int8_t z, std::uint8_t worldNumber, std::uint16_t instanceId ) -> std::int8_t
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
// let's check in this order.. dynamic, static, then the map
|
2022-11-01 02:25:52 +08:00
|
|
|
auto dynZ = DynamicElevation( x, y, z, worldNumber, instanceId, MAX_Z_STEP );
|
2022-10-24 18:39:33 +08:00
|
|
|
if( ILLEGAL_Z != dynZ )
|
|
|
|
|
return dynZ;
|
|
|
|
|
|
|
|
|
|
auto staticZ = StaticTop( x, y, z, worldNumber, MAX_Z_STEP );
|
Small update
Fixed an issue with an internal movement check that prevented characters from moving in valid map areas in Felucca/Trammel from X 6144 to X 7168
Fixed an issue where .instanceID property was misspelled in 'xgo GM command script, causing characters to be teleported to an out of bounds area where they would no longer be saved (js/commands/targeting/x.js)
Added some additional error-checking to .Teleport()/.SetLocation() JS Method to prevent script-accidents from sending characters out of bounds.
Updated Poisoning skill to add poison-charges to weapons being poisoned. Charges are consumed when applying poison in combat (js/skill/poisoning.js)
Updated combat code to consume poison-charges if a poisoned weapon is used to poison an opponent
Updated shoplists for Blacksmiths and Weaponsmiths - they now buy/sell longswords (dfndata/items/shoplist.dfn)
Updated MageShopping shoplist for mage vendors - they now buy/sell mass curse scrolls (dfndata/items/shoplist.dfn)
Added new Spawn Region DFN tag that can specify which era or eras of UO (Multiple comma-separated entries supported) a given spawn region is valid for. Spawn region not valid for core shard era will be ignored. Syntax:
ERAS=UO,T2A,UOR,LBR,AOS,SE,ML,SA,HS,TOL
Added new Spawn Region DFN tag that allows using another spawn region as a "parent". All properties of this parent will be inherited except for these, which are ignored: ERAS, NPCLIST, ITEMLIST, NPC and ITEM. Syntax for new tag:
GET=# // Inherit a specified spawn region
Added spawn region for animal trainer vendor in Vesper stable
Added spawn region for fur trader/tanner vendors in The Best Hides of Britain
Added spawn region for spinner vendor in The Lord's Clothier's and The Right Fit shops in Britain
Added spawn region for tanner NPC to Nujel'm Tannery (and fixed leatherworker spawn region for same area)
Added spawn regions for banker NPCs in East Bank of Britain, First Bank of Moonglow, Jhelom Bank and Jeweler, Bank of Skara Brae
Added spawn regions for stables, tailor and blacksmith inside Castle British
Added spawn regions for mage shops, mage guilds and farm houses in Moonglow
Added spawn regions for misc vendors and townfolk in multiple cities
Added spawn regions for Fire Island
Updated spawn regions for Dagger Isle/Ice Island
Added spawn regions for forests and jungles in southern Britannia and on various islands including Bucc's Den, Moonglow, Serpent's Hold, and misc unpopulated islands
Added spawn regions for area east of Skara Brae, around Hedge Maze and south of Britain
Added spawn regions for wandering healers outside every dungeon entrance in Britannia and Lost Lands
Re-integrated ocean spawn regions for ocean creatures (dolphin, walrus, water elemental, sea serpent) from the original community-based spawn file
Added reagent spawns in overworld spawn regions in Britannia/Lost Lands
Added special reagent spawns in swamp areas
Added additional overworld spawn regions in Britannia/Lost Lands
Added spawn regions for Khaldun dungeon that spawn some new and some old NPCs:
Old: Zombies, skeletons, skeletal mages, skeletal knights, ancient liches
New: Cursed (and named) NPCs, shadowfiends, zealots of khaldun (knights/summoners), tentacles of the harrower
Updated size and positions of some existing overworld spawn regions
Fixed incorrect spawn region size for small island south of Trinsic
Added switch/door puzzle functionality in Khaldun dungeon using new switch/door combo script (js/item/dungeons/switch_door_combo.js)
Added "smart objects" in Khaldun dungeon that activate when you come close enough (js/item/dungeons/smart_activate_item.js)
Added teleport locations within Khaldun dungeon (js/teleport.scp)
Added custom AIs to existing NPC spawning in Khaldun dungeon:
Ancient Lich (summons other undead, and can turn into one of them for disguise)
Added DFN entries for new NPCs spawning in Khaldun dungeon, some with custom AIs:
[tentacles_of_the_harrower] -> Tentacles of the Harrower (life steal)
[shadowfiend] -> Shadowfiends (seek out and reveal hidden players)
[zealot_knight]/[zealot_summoner] -> Zealots of Khaldun (turn into undead on death, male/female variants)
[cursed] -> Cursed (male/female variants)
[spectralarmor] -> Spectral Armor
Added DFN entries for new (named) NPCs spawning in Khaldun dungeon:
[lysander_gathenwale] -> Lysander Gathenwale
[grimmoch_drummel] -> Grimmoch Drummel
[morg_bergen] -> Morg Bergen
[tavara_sewel] -> Tavara Sewel
Added new NPC DFN entries:
[leatherworker] -> alias for male/female leatherworker vendors
[mapmaker] -> alias for male/female mapmaker vendors
Added new Race DFN entries:
[RACE 29] -> Cursed (enemies of RACE 30)
[RACE 30] -> Zealots (enemies of RACE 29)
Added new book DFN entries for Khaldun journals of Lysander, Tavara and Grimmoch - available as loot from the respective NPCs (dfndata/misc/books.dfn and dfndata/items/misc/books.dfn)
Added 25% chance for hit-animations and hit-SFX to play for targets in combat, instead of playing every time - can get very spammy
Monsters with actual weapons equipped (like Ophidian Enforcer with Halberd/Bardiche) will now get appropriate combat SFX for hitting with that weapon
Updated Healing skill to base cure/resurrection skill requirements on the calculated skill, rather than base skill (js/skill/healing.js)
Fixed an issue where healing with bandages and dying in the process would not properly reset the healing-related tags and skills used
Updated healing script to show a resurrection confirmation menu for players targeted with bandages for resurrect (js/skill/healing.js)
All skill usage states now reset on death, to prevent cases of players being "busy" while trying to use skills that got stuck due to script bugs.
The 'regspawn GM command now supports a new parameter called "max". Updated command syntax:
'regspawn # // perform a single respawn cycle in a specific spawn region
'regspawn all // perform a single respawn cycle across all spawn regions
'regspawn max // respawn ALL spawn regions to MAX capacity in one go
Added new UOX.INI setting that determines the maximum range at which NPCs can initiate attacks on players/NPCs (the old MAXRANGE=10 setting now instead defines max range at which players can initiate attacks on players/NPCs):
MAXNPCAGGRORANGE=10
Optimized performance by significantly reducing the number of line-of-sight checks performed by characters, especially in combat scenarios, or when evaluating potential targets for NPC AIs. The amount of checks done is also affected by the new ini setting for max aggro range.
Fixed an issue where both NPC and player characters would instantly drop one hunger level (from 6 to 5) upon creation since hungerrate was not initialized until after first hunger-event
Updated character priv property from UI16 to UI32, and added a new flag that determines if fame/karma title is hidden for character:
HIDEFAMEKARMATITLE (0x10000)
NPCs will no longer aggro other NPCs if the Z difference between them is greater or equal to 20 (i.e. they're on different floors), unless both are using ranged weapons and both are in range
Fixed an issue where players could get discounts from shopkeepers even though neither player nor shopkeeper were members of a NPC guild (js/npc/ai/shopkeeper.js)
Fixed an issue where the "premium" a player would get when selling items to a shopkeeper in the same NPC guild as them would be 110% extra on top of the item's value, instead of the intended 10% (js/npc/ai/shopkeeper.js) (Thanks, cobrag0318!)
Added missing tall straw hat to tailoring crafting scripts (Thanks, Dragon Slayer!)
Improved error reporting during compilation of individual scripts being reloaded - will now show more context and line number
onCombatEnd JS Event now also triggers when NPCs ignore their target and/or evade during combat
Updated 'decorate command to support saving/loading custom tags on items for world templates. These are stored after a @ symbol in the world template, each custom tag separated by a | symbol, and with each custom tag saved using this syntax: key$type$value
Updated resource-harvesting scripts to use script-specific global (const) variables, to avoid interference between different scripts (js/server/resource/*)
Added new resource-harvesting scripts and added spawn regions for these in fields on farms all over Britannia/Lost Lands
cabbages (js/server/resource/cabbages.js)
canteloupes (js/server/resource/canteloupes.js)
carrots (js/server/resource/carrots.js)
garlic (js/server/resource/garlic.js)
gourds (js/server/resource/gourds.js)
honeydew melons (js/server/resource/honeydewmelon.js)
onions (js/server/resource/onions.js)
pumpkins (js/server/resource/pumpkins.js)
squashes (js/server/resource/squashes.js)
turnips (js/server/resource/turnips.js)
watermelons (js/server/resource/watermelon.js)
Updated CSpawnRegion::FindItemSpotToSpawn() function in cSpawnRegion.cpp to prevent duplicate spawning of exact same item in exact same location
Updated sectionid of all potion and scroll aliases to match main item, so they'll get correctly picked up by NPC shopkeepers (dfndata/items/magic/potions.dfn and scrolls.dfn)
Specified sectionid for backpacks, so it also gets applied to packs added using the alias [backpack] (dfndata/items/misc/provisions.dfn)
Fixed a code issue that prevented players from selling empty containers to NPC shopkeepers willing to buy such containers
Fixed an issue where field-spells (wall of stone, poison field, etc) would ignore dynamic/static items that should block these
Fixed an issue where field-spells could be cast into houses from the outside by standing next to a wall and targeting self
Fixed a War/Peace-mode desync between client and server by having server always notify client (using war-toggle packet) when the "at war" flag is toggled for player character
Fixed an issue with hiding skill that wouldn't allow player to hide after having acquired self as target in combat (through spellcasting, for instance) (Thanks, Dragon Slayer!)
Fixed an issue where mana/reagents were consumed and skillcheck performed before all spellcast-validations had succeeded, resulting in the occasional loss of reagents/mana when spellcasting was disallowed (code and js/magic/clumsy.js and level1targ.js)
Fixed an issue with lack of criminal-flagging for casting of hostile spells scripted in JS (clumsy, magic arrow, feeblemind) vs blue targets (js/magic/clumsy.js and level1targ.js)
Fixed some issues with Line-of-Sight checking code that returned incorrect results, which amongst other things affected spellcasting in areas with uneven terrain
Fixed some issues with movement code and climbing of ladders, in particular the rope ladder in the 2-story log cabin. Code now sets a "is climbing" flag when character steps onto a rope ladder, and uses that to help resolve some edge cases, and then unsets it when they step off.
Renamed section headers of some map-items in DFNs from "locationname" to "locationnamemap" for clarity (example: "britain" to "britainmap")
Fixed broken "map wrapping" when sailing to edges of map in Felucca or Trammel
Fixed a server crash related to attempts at reading data from invalid map tiles
2025-06-27 08:40:02 +08:00
|
|
|
if( ILLEGAL_Z != staticZ && abs( staticZ - z ) <= MAX_Z_STEP )
|
2022-10-24 18:39:33 +08:00
|
|
|
return staticZ;
|
|
|
|
|
|
2022-06-15 11:24:57 -04:00
|
|
|
return MapElevation( x, y, worldNumber );
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::InBuilding()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Returns whether give coordinates are inside a building by checking if there is
|
|
|
|
|
//| a multi or static above them
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::InBuilding( std::int16_t x, std::int16_t y, std::int8_t z, std::uint8_t worldNumber, std::uint16_t instanceId) -> bool
|
|
|
|
|
{
|
2022-11-01 02:25:52 +08:00
|
|
|
auto dynZ = Map->DynamicElevation( x, y, z, worldNumber, instanceId, static_cast<std::int8_t>( 127 ) );
|
2022-10-24 18:39:33 +08:00
|
|
|
if( dynZ > ( z + 10 ))
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
return true;
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const SI08 staticZ = Map->StaticTop( x, y, z, worldNumber, static_cast<std::int8_t>( 127 ));
|
|
|
|
|
if( staticZ > ( z + 10 ))
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::MultiArea()
|
|
|
|
|
//o--------------------------------------------------------------------------
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Finds the corners of a multi object
|
|
|
|
|
//o--------------------------------------------------------------------------
|
2022-10-24 18:39:33 +08:00
|
|
|
auto CMulHandler::MultiArea( CMultiObj *i, std::int16_t &x1, std::int16_t &y1, std::int16_t &x2, std::int16_t &y2 ) -> void
|
|
|
|
|
{
|
|
|
|
|
if( ValidateObject( i ))
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
const SI16 xAdd = i->GetX();
|
|
|
|
|
const SI16 yAdd = i->GetY();
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
const UI16 multiNum = static_cast<UI16>( i->GetId() - 0x4000 );
|
|
|
|
|
if( MultiExists( multiNum ))
|
|
|
|
|
{
|
|
|
|
|
auto structure = SeekMulti( multiNum );
|
|
|
|
|
x1 = static_cast<SI16>( structure.minX + xAdd );
|
|
|
|
|
x2 = static_cast<SI16>( structure.maxX + xAdd );
|
|
|
|
|
y1 = static_cast<SI16>( structure.minY + yAdd );
|
|
|
|
|
y2 = static_cast<SI16>( structure.maxY + yAdd );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::MultiExists()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Verify that specified multi exists
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::MultiExists( std::uint16_t multinum ) const -> bool
|
|
|
|
|
{
|
|
|
|
|
return multiData.Exists( multinum );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::SeekMulti()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Returns data for items contained in given multi
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::SeekMulti( std::uint16_t multinum ) const -> const CollectionItem_st &
|
|
|
|
|
{
|
|
|
|
|
return multiData.Multi( multinum );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::IsValidTile()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Checks if a given tile number falls within the range of tiles loaded in memory
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::IsValidTile( std::uint16_t tileNum ) const -> bool
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
bool retVal = true;
|
2022-10-24 18:39:33 +08:00
|
|
|
if(( tileNum == INVALIDID ) || ( tileNum >= tileInfo.SizeArt() ))
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
retVal = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::SeekTile()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Fetches data about a specific tile from memory
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::SeekTile( std::uint16_t tileNum ) -> CTile&
|
|
|
|
|
{
|
|
|
|
|
if( !IsValidTile( tileNum ))
|
|
|
|
|
{
|
|
|
|
|
Console.Warning( oldstrutil::format( "Invalid tile access, the offending tile number is %u", tileNum ));
|
2022-06-15 11:24:57 -04:00
|
|
|
static CTile emptyTile;
|
|
|
|
|
return emptyTile;
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return tileInfo.ArtInfo( tileNum );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
//=================================================================================================
|
|
|
|
|
auto CMulHandler::SeekTile( std::uint16_t tileNum ) const -> const CTile&
|
|
|
|
|
{
|
|
|
|
|
if( !IsValidTile( tileNum ))
|
|
|
|
|
{
|
|
|
|
|
Console.Warning( oldstrutil::format( "Invalid tile access, the offending tile number is %u", tileNum ));
|
2022-06-15 11:24:57 -04:00
|
|
|
static CTile emptyTile;
|
|
|
|
|
return emptyTile;
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return tileInfo.ArtInfo( tileNum );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::SeekLand()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Fetches data about a specific land tile from memory.
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::SeekLand( std::uint16_t landNum ) ->CLand&
|
|
|
|
|
{
|
|
|
|
|
if( landNum == INVALIDID || landNum >= tileInfo.SizeTerrain() )
|
|
|
|
|
{
|
|
|
|
|
Console.Warning( oldstrutil::format( "Invalid land access, the offending land number is %u", landNum ));
|
2022-06-15 11:24:57 -04:00
|
|
|
static CLand emptyTile;
|
|
|
|
|
return emptyTile;
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return tileInfo.TerrainInfo( landNum );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
//=================================================================================================
|
|
|
|
|
auto CMulHandler::SeekLand( std::uint16_t landNum ) const -> const CLand&
|
|
|
|
|
{
|
|
|
|
|
if( landNum == INVALIDID || landNum >= tileInfo.SizeTerrain() )
|
|
|
|
|
{
|
|
|
|
|
Console.Warning( oldstrutil::format( "Invalid land access, the offending land number is %u", landNum ));
|
2022-06-15 11:24:57 -04:00
|
|
|
static CLand emptyTile;
|
|
|
|
|
return emptyTile;
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return tileInfo.TerrainInfo( landNum );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::SeekMap()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Fetches map data for a specific map/world
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::SeekMap( std::int16_t x, std::int16_t y, std::uint8_t worldNumber ) ->Tile_st&
|
|
|
|
|
{
|
|
|
|
|
static Tile_st badTile;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return uoWorlds.at( worldNumber ).TerrainAt( x, y );
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
std::cerr << "Bad tile access attempted: " << x << "," << y << static_cast<int>( worldNumber ) << std::endl;
|
|
|
|
|
return badTile;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//=================================================================================================
|
|
|
|
|
auto CMulHandler::SeekMap( std::int16_t x, std::int16_t y, std::uint8_t worldNumber ) const -> const Tile_st&
|
|
|
|
|
{
|
|
|
|
|
static Tile_st badTile;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return uoWorlds.at( worldNumber ).TerrainAt( x, y );
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
std::cerr << "Bad tile access attempted: " << x << "," << y << static_cast<int>( worldNumber ) << std::endl;
|
|
|
|
|
return badTile;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::ValidSpawnLocation()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Checks if location at given coordinates is considered valid for spawning objects
|
|
|
|
|
//| Also used to verify teleport location for NPCs teleporting back to bounding box
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::ValidSpawnLocation( std::int16_t x, std::int16_t y, std::int8_t z, std::uint8_t worldNumber, std::uint16_t instanceId, bool checkWater ) -> bool
|
|
|
|
|
{
|
|
|
|
|
if( !InsideValidWorld( x, y, worldNumber ))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// get the tile id of any dynamic tiles at this spot
|
|
|
|
|
if( DoesDynamicBlock( x, y, z, worldNumber, instanceId, checkWater, !checkWater, false, false ))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// if there's a static block here in our way, return false
|
|
|
|
|
if( DoesStaticBlock( x, y, z, worldNumber, checkWater ))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// if the static isn't a surface return false
|
UOX3 0.99.6-RC4
Fixed an issue that prevented onBuyFromVendor() and onBoughtFromVendor() JS Events from triggering when attached to NPC shopkeepers
Fixed an issue with help gump that prevented password management section from working as intended (js/server/misc/helpgump.js)
Fixed an issue where UOX3 would fail to load pre-HS multi.mul files
Added chess board to Misc->Games add menu (dfndata/items/ItemMenu.bulk.dfn)
Fixed an issue with 'move (alias for 'telestuff) command that referenced the wrong variable name (js/commands/targeting/tele.js)
When a player is teleported via the GM 'wholist menu, any pets within range are now also brought along for the ride
Consolidated error-reporting for JS Functions, Object Methods and Object Properties to provide more context (scriptID, filename, line number) when something goes wrong
Added some missing shield IDs (0xA649, 0xA64A, 0xA831, 0xA832) to IsShieldType() function
MAXRANGE item property previously only worked for ranged weapons; now it works for melee weapons too, and potentially allows melee weapons with combat range longer than 1 tile
MAXRANGE item property can now be used to define max combat range for melee weapons
Fixed an issue (non-critical) with .PlaceInPack() JS Method that would cause UOX3 to try adding items marked for deletion to refreshQueue and spam console with errors
Added missing AI scripts to summoned Blade Spirits and Energy Vortexes (dfndata/npc/magicsummon.dfn)
Fixed an issue with weight calculation for hireling backpacks (js/npc/ai/hireling.js)
Fixed an issue with the 'fix command, which would in most cases set character's Z to -1 regardless of location, but now adheres to map elevation instead
Fixed an issue with Pack AI (js/npc/ai/pack_ai.js) that prevented pack members from attacking target correctly (thanks Dragon Slayer)
Fixed an issue with DoesMapBlock JS Function that incorrectly checked for 6 function arguments, when it actually requires 8
Fixed an issue with DoesDynamicBlock JS Function that incorrectly checked for 8 function arguments, when it actually requires 9
Fixed an issue with runebook script (js/item/runebook.js) that prevented players from being able to use recall charges without having spellbook with spell in inventory
Fixed issues with placement of tall items on ground/floor, and with stacking of items in houses
Fixed incorrect alias for woodland armor (dfndata/items/gear/armor/other/armor/wood.dfn - thanks Dragon Slayer)
Fixed a critical issue with script context sometimes changing while executing a script, because of events in other scripts being triggered. Affected scripts can be safeguarded against this by the addition of a dummy callback function anywhere in the script: function _restorecontext_() {}
Fixed an issue with non-animal pets not gaining loyalty when being fed (thanks Dragon Slayer)
Added new JS Object Methods for Chars/Items/Multis to fetch list of custom tags associated with object:
.GetTagMap() // Gets list of persistent custom tags associated with object
.GetTempTagMap() // Gets list of temporary custom tags associated with object
Added new JS commands ('GETTAGMAP and 'GETTEMPTAGMAP) that spits out details of custom tags associated with targeted object (js/commands/custom/misc-cmd.js)
Added new JS command ('USEITEM) that acts as a short-cut for double-clicking on targeted item (js/commands/custom/misc-cmd.js)
Updated 'ADD # and 'ADD ITEM # JS commands to support targeting a container directly and adding the new item inside (js/commands/targeting/add.js)
Updated axe script to only perform lumberjacking skill-check when there's still wood available in a given area, and to play appropriate animations for Gargoyle players (js/item/axe.js)
Updated script for gameboards to make generated pieces newbiefied so they won't appear on ground if board decays (js/item/gameboards.js)
Updated script for stablemasters to avoid relying on global variables (js/npc/ai/stablemaster.js)
Updated names of items crafted with runic hammers to include the material name of the hammers used to craft them (js/skill/craft/crafting_complete.js)
Fixed a small issue with Detect Hidden skill that would return the wrong message if players found anyone hiding nearby (js/skill/detecthidden.js)
Fixed an issue that prevented tile overrides in dfndata/maps/tiles.dfn from loading properly
Added entries for a couple of walls with missing no-shoot flags to tile overrides in dfndata/maps/tiles.dfn
Updated JS Method .SoundEffect() to support optional third argument (creatureSoundNum) to play creature-defined sounds from dfndata/creatures/creatures.dfn. New syntax:
.SoundEffect( soundID, allHear[, creatureSoundNum] ) // 0=SOUND_STARTATTACK, 1=SOUND_IDLE, 2=SOUND_ATTACK, 3=SOUND_DEFEND, 4=SOUND_DIE
Added new Character JS Methods:
.SetRandomName( nameListID ) // apply a random name from specified namelist to character
.FindItemSection( sectionID ) // find item in player's backpack with specified sectionID
Added new Socket JS Method:
.OpenContainer() // Opens specified container for socket
2023-05-30 01:47:26 +08:00
|
|
|
[[maybe_unused]] UI16 ignoreMe = 0;
|
|
|
|
|
if( !CheckStaticFlag( x, y, z, worldNumber, ( checkWater ? TF_SURFACE : TF_WET ), ignoreMe, true ))
|
2022-10-24 18:39:33 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if( DoesMapBlock( x, y, z, worldNumber, checkWater, !checkWater, false, false ))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::ValidMultiLocation()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Checks whether given location is valid for house/boat placement
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::ValidMultiLocation( std::int16_t x, std::int16_t y, std::int8_t z, std::uint8_t worldNumber, std::uint16_t instanceId,
|
|
|
|
|
bool checkWater, bool checkOnlyOtherMultis, bool checkOnlyNonMultis, bool checkForRoads ) -> std::uint8_t
|
|
|
|
|
{
|
|
|
|
|
if( !InsideValidWorld( x, y, worldNumber ))
|
2022-06-15 11:24:57 -04:00
|
|
|
return 0;
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
const SI08 elev = Height( x, y, z, worldNumber, instanceId );
|
2022-06-15 11:24:57 -04:00
|
|
|
if( ILLEGAL_Z == elev )
|
|
|
|
|
return 0;
|
2022-10-24 18:39:33 +08:00
|
|
|
|
2022-06-15 11:24:57 -04:00
|
|
|
// We don't want the house to be halfway embedded in a hill... or hanging off one for that matter.
|
2022-10-24 18:39:33 +08:00
|
|
|
if( z != ILLEGAL_Z )
|
|
|
|
|
{
|
|
|
|
|
if( elev - z > MAX_Z_STEP )
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
return 0;
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else if( z - elev > MAX_Z_FALL )
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
2022-06-15 11:24:57 -04:00
|
|
|
// get the tile id of any dynamic tiles at this spot
|
2022-10-24 18:39:33 +08:00
|
|
|
if( !checkOnlyNonMultis && DoesDynamicBlock( x, y, elev, worldNumber, instanceId, checkWater, false, checkOnlyOtherMultis, checkOnlyNonMultis ))
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
return 2;
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
2022-06-15 11:24:57 -04:00
|
|
|
// if there's a static block here in our way, return false
|
2022-10-24 18:39:33 +08:00
|
|
|
if( !checkOnlyOtherMultis && DoesStaticBlock( x, y, elev, worldNumber, checkWater ))
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
return 2;
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
if( DoesMapBlock( x, y, elev, worldNumber, checkWater, false, true, checkForRoads ))
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
return 0;
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
2022-06-15 11:24:57 -04:00
|
|
|
// Check if house placement is allowed in region
|
2022-10-24 18:39:33 +08:00
|
|
|
CTownRegion *calcReg = CalcRegionFromXY( x, y, worldNumber, instanceId );
|
2022-06-15 11:24:57 -04:00
|
|
|
if(( !calcReg->CanPlaceHouse() && checkWater) || calcReg->IsDungeon() || ( calcReg->IsGuarded() && checkWater ))
|
|
|
|
|
return 3;
|
2022-10-24 18:39:33 +08:00
|
|
|
|
2022-06-15 11:24:57 -04:00
|
|
|
// Else, all good!
|
|
|
|
|
return 1;
|
2022-06-15 07:32:55 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::MapExists()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Returns true if the server has that map in memory
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::MapExists( std::uint8_t worldNumber ) const -> bool
|
|
|
|
|
{
|
|
|
|
|
auto iter = uoWorlds.find( worldNumber );
|
|
|
|
|
return iter != uoWorlds.end();
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::InsideValidWorld()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Checks if a given location is within the bounds of the specified world
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::InsideValidWorld( std::int16_t x, std::int16_t y, std::uint8_t worldNumber ) const -> bool
|
|
|
|
|
{
|
|
|
|
|
auto rValue = false;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
auto [width, height] = uoWorlds.at( worldNumber ).Size();
|
|
|
|
|
if(( x >= 0 && x < width ) && ( y >= 0 && y < height ))
|
|
|
|
|
{
|
|
|
|
|
rValue = true;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
catch(...)
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
// Do nothing, all rady set to false
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return rValue;
|
2022-06-15 07:32:55 -04:00
|
|
|
}
|
2022-06-12 14:31:18 -04:00
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - CMulHandler::MapCount()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-06-15 11:24:57 -04:00
|
|
|
//| Purpose - Returns count of how many maps have been loaded
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto CMulHandler::MapCount() const -> std::uint8_t
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
// This ASSUMES the map numbers are consequtive. You dont have say map 0,1,3 <<<< missing 2
|
2022-10-24 18:39:33 +08:00
|
|
|
return static_cast<std::uint8_t>( uoWorlds.size() );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-06-12 14:31:18 -04:00
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| TileInfo
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
TileInfo::TileInfo( const std::string &filename ) : isHsFormat( false )
|
|
|
|
|
{
|
|
|
|
|
if( !filename.empty() )
|
|
|
|
|
{
|
|
|
|
|
this->LoadTiles( filename );
|
2021-05-28 03:41:43 +08:00
|
|
|
}
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - TileInfo::LoadTiles()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Loads tiles from tiledata file into memory
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto TileInfo::LoadTiles( const std::string &filename ) -> bool
|
|
|
|
|
{
|
|
|
|
|
auto rValue = false;
|
|
|
|
|
artData.clear();
|
|
|
|
|
terrainData.clear();
|
|
|
|
|
isHsFormat = false;
|
|
|
|
|
auto path = std::filesystem::path( filename );
|
|
|
|
|
if( std::filesystem::exists( path ))
|
|
|
|
|
{
|
|
|
|
|
if( std::filesystem::file_size( path ) >= hsSize )
|
|
|
|
|
{
|
|
|
|
|
isHsFormat = true;
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
auto input = std::ifstream( filename, std::ios::binary );
|
|
|
|
|
if( input.is_open() )
|
|
|
|
|
{
|
|
|
|
|
rValue = true;
|
|
|
|
|
ProcessTerrain( input );
|
|
|
|
|
ProcessArt( input );
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return rValue;
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - TileInfo::TerrainInfo()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Returns terrain data for given tileId
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto TileInfo::TerrainInfo( std::uint16_t tileId ) const -> const CLand&
|
|
|
|
|
{
|
|
|
|
|
return terrainData[tileId];
|
|
|
|
|
}
|
|
|
|
|
auto TileInfo::TerrainInfo( std::uint16_t tileId ) -> CLand&
|
|
|
|
|
{
|
|
|
|
|
return terrainData[tileId];
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - TileInfo::ArtInfo()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Returns art/statics data for given tileId
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto TileInfo::ArtInfo( std::uint16_t tileId ) const -> const CTile&
|
|
|
|
|
{
|
|
|
|
|
return artData[tileId];
|
|
|
|
|
}
|
|
|
|
|
auto TileInfo::ArtInfo( std::uint16_t tileId) -> CTile&
|
|
|
|
|
{
|
|
|
|
|
return artData[tileId];
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - TileInfo::SizeTerrain()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Returns size of terrain data loaded by UOX3
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto TileInfo::SizeTerrain() const -> size_t
|
|
|
|
|
{
|
|
|
|
|
return terrainData.size();
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - TileInfo::SizeArt()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Returns size of art/statics data loaded by UOX3
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto TileInfo::SizeArt() const -> size_t
|
|
|
|
|
{
|
|
|
|
|
return artData.size();
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - TileInfo::CollectionTerrain()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Returns collection of terrain tiles loaded by UOX3
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto TileInfo::CollectionTerrain() const -> const std::vector<CLand>&
|
|
|
|
|
{
|
|
|
|
|
return terrainData;
|
|
|
|
|
}
|
|
|
|
|
auto TileInfo::CollectionTerrain() -> std::vector<CLand> &
|
|
|
|
|
{
|
|
|
|
|
return terrainData;
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - TileInfo::CollectionArt()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Returns collection of art/statics tiles loaded by UOX3
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto TileInfo::CollectionArt() const -> const std::vector<CTile>&
|
|
|
|
|
{
|
|
|
|
|
return artData;
|
|
|
|
|
}
|
|
|
|
|
auto TileInfo::CollectionArt() -> std::vector<CTile>&
|
|
|
|
|
{
|
|
|
|
|
return artData;
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - TileInfo::ProcessTerrain()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Process terrain data read from tiledata file
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2023-08-27 21:42:47 -04:00
|
|
|
auto TileInfo::ProcessTerrain( std::istream &input ) -> void
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
|
|
|
|
terrainData.reserve( 0x4000 );
|
|
|
|
|
std::uint32_t value32 = 0;
|
|
|
|
|
std::uint64_t value64 = 0;
|
|
|
|
|
std::array<char, 20> string_buffer;
|
|
|
|
|
string_buffer.fill( 0 );
|
|
|
|
|
for( auto i = 0; i < 0x4000; i++ )
|
|
|
|
|
{
|
2022-06-12 14:31:18 -04:00
|
|
|
// We have to get rid of the header on blocks of information
|
2022-10-24 18:39:33 +08:00
|
|
|
// HS has the first entry messed up
|
|
|
|
|
if( isHsFormat )
|
|
|
|
|
{
|
|
|
|
|
if(((( i & 0x1F ) == 0 ) && ( i > 0 )) || ( i == 1 ))
|
|
|
|
|
{
|
|
|
|
|
input.read( reinterpret_cast<char*>( &value32 ), 4 ); // read off the group header
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(( i & 0x1f ) == 0 )
|
|
|
|
|
{
|
|
|
|
|
input.read( reinterpret_cast<char*>( &value32 ), 4 ); // read off the group header
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// now create the info_t we will use
|
|
|
|
|
auto info = CLand();
|
|
|
|
|
// read off the flags, 32 bit on pre-HS, 64 bit after
|
2022-10-24 18:39:33 +08:00
|
|
|
if( isHsFormat )
|
|
|
|
|
{
|
|
|
|
|
input.read( reinterpret_cast<char*>( &value64), 8 );
|
|
|
|
|
info.flags = std::bitset<64>( value64 );
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
input.read( reinterpret_cast<char*>( &value32 ), 4 );
|
|
|
|
|
info.flags = std::bitset<64>( value32 );
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
|
|
|
|
// only other thing for terrain is the texture
|
|
|
|
|
// and name
|
2022-10-24 18:39:33 +08:00
|
|
|
input.read( reinterpret_cast<char*>( &info.textureId ), 2 );
|
|
|
|
|
input.read( string_buffer.data(), 20 );
|
|
|
|
|
if( input.gcount() == 20 )
|
|
|
|
|
{
|
2022-06-12 14:31:18 -04:00
|
|
|
// We need to find the "0", if any
|
2022-10-24 18:39:33 +08:00
|
|
|
auto iter = std::find( string_buffer.begin(), string_buffer.end(), 0 );
|
|
|
|
|
info.name = std::string( string_buffer.begin(), iter );
|
|
|
|
|
terrainData.push_back( std::move( info ));
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
2022-06-12 14:31:18 -04:00
|
|
|
break;
|
|
|
|
|
}
|
2021-05-28 03:41:43 +08:00
|
|
|
}
|
2022-06-12 14:31:18 -04:00
|
|
|
|
2002-04-07 21:27:53 +00:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - TileInfo::ProcessArt()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Process art/statics data read from tiledata file
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2023-08-27 21:42:47 -04:00
|
|
|
auto TileInfo::ProcessArt( std::istream &input ) -> void
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
|
|
|
|
artData.reserve( 0xFFFF );
|
|
|
|
|
std::uint32_t value32 = 0;
|
|
|
|
|
std::uint64_t value64 = 0;
|
|
|
|
|
std::array<char, 20> string_buffer;
|
|
|
|
|
string_buffer.fill( 0 );
|
|
|
|
|
if( !( input.eof() || input.bad() ))
|
|
|
|
|
{
|
|
|
|
|
auto loopCount = 0;
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
if(( loopCount & 0x1f ) == 0 )
|
|
|
|
|
{
|
|
|
|
|
input.read( reinterpret_cast<char*>( &value32 ), 4 ); // read off the group header
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
|
|
|
|
auto info = CTile();
|
2022-10-24 18:39:33 +08:00
|
|
|
if( isHsFormat )
|
|
|
|
|
{
|
|
|
|
|
input.read( reinterpret_cast<char*>( &value64 ), 8 );
|
|
|
|
|
info.flags = std::bitset<64>( value64 );
|
2022-06-12 14:31:18 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
input.read( reinterpret_cast<char*>( &value32 ), 4 );
|
|
|
|
|
info.flags = std::bitset<64>( value32 );
|
2002-04-07 21:27:53 +00:00
|
|
|
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
input.read( reinterpret_cast<char*>( &info.weight ), 1 );
|
|
|
|
|
input.read( reinterpret_cast<char*>( &info.layer ), 1 );
|
2022-06-12 14:31:18 -04:00
|
|
|
//misc data
|
2022-10-24 18:39:33 +08:00
|
|
|
input.read( reinterpret_cast<char*>( &info.unknown1 ), 2 );
|
2022-06-12 14:31:18 -04:00
|
|
|
//Second unkown
|
2022-10-24 18:39:33 +08:00
|
|
|
input.read( reinterpret_cast<char*>( &info.unknown2), 1 );
|
2022-06-12 14:31:18 -04:00
|
|
|
// Quantity
|
2022-10-24 18:39:33 +08:00
|
|
|
input.read( reinterpret_cast<char*>( &info.quantity), 1 );
|
2022-06-12 14:31:18 -04:00
|
|
|
// Animation
|
2022-10-24 18:39:33 +08:00
|
|
|
input.read( reinterpret_cast<char*>( &info.animation), 2 );
|
2022-06-12 14:31:18 -04:00
|
|
|
|
|
|
|
|
//Third a byte
|
2022-10-24 18:39:33 +08:00
|
|
|
input.read( reinterpret_cast<char*>( &info.unknown3), 1 );
|
2022-06-12 14:31:18 -04:00
|
|
|
|
|
|
|
|
// Hue/Value
|
2022-10-24 18:39:33 +08:00
|
|
|
input.read( reinterpret_cast<char*>( &info.hue), 1 );
|
2022-06-12 14:31:18 -04:00
|
|
|
//stacking offset/value = 16 bits, but UOX3 doesn't know that, so two eight bit unkowns
|
2022-10-24 18:39:33 +08:00
|
|
|
input.read( reinterpret_cast<char*>( &info.unknown4 ), 1 );
|
|
|
|
|
input.read( reinterpret_cast<char*>( &info.unknown5 ), 1 );
|
2022-06-12 14:31:18 -04:00
|
|
|
// Height
|
2022-10-24 18:39:33 +08:00
|
|
|
input.read( reinterpret_cast<char*>( &info.height ), 1 );
|
2022-06-12 14:31:18 -04:00
|
|
|
// and name
|
2022-10-24 18:39:33 +08:00
|
|
|
input.read( string_buffer.data(), 20 );
|
|
|
|
|
if(( input.gcount() == 20 ) && input.good() )
|
|
|
|
|
{
|
2022-06-12 14:31:18 -04:00
|
|
|
// We need to find the "0", if any
|
2022-10-24 18:39:33 +08:00
|
|
|
auto iter = std::find( string_buffer.begin(), string_buffer.end(), 0 );
|
|
|
|
|
info.name = std::string( string_buffer.begin(), iter );
|
|
|
|
|
artData.push_back( std::move( info ));
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
loopCount++;
|
2022-06-12 14:31:18 -04:00
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
} while(( !input.eof() ) && input.good() );
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2021-05-28 03:41:43 +08:00
|
|
|
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - TileInfo::TotalMemory()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Calculate total memory used for loading art/terrain tiledata
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto TileInfo::TotalMemory() const -> size_t
|
|
|
|
|
{
|
|
|
|
|
auto flag = isHsFormat ? 8 : 4;
|
|
|
|
|
auto terrain = flag + 20 + 2;
|
|
|
|
|
auto art = flag + 20 + 23;
|
|
|
|
|
return static_cast<size_t>(( terrain * terrainData.size() ) + ( art * artData.size() ));
|
2022-06-12 14:31:18 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| TerrainBlock::TerrainBlock()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
TerrainBlock::TerrainBlock( std::uint8_t *data, const TileInfo *info )
|
|
|
|
|
{
|
|
|
|
|
if( data != nullptr )
|
|
|
|
|
{
|
|
|
|
|
LoadBlock( data, info );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - TerrainBlock::LoadBlock()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Load details for terrain tiles in a 8x8 block of the map
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto TerrainBlock::LoadBlock( std::uint8_t *data, const TileInfo *info ) -> void
|
|
|
|
|
{
|
|
|
|
|
if( data != nullptr )
|
|
|
|
|
{
|
|
|
|
|
data += 4;
|
|
|
|
|
for( auto y = 0; y < 8; ++y )
|
|
|
|
|
{
|
|
|
|
|
for( auto x = 0; x < 8; ++x )
|
|
|
|
|
{
|
|
|
|
|
auto tileId = std::uint16_t( 0 );
|
2022-06-15 11:24:57 -04:00
|
|
|
// we copy here, because of potential alignment issues
|
2022-10-24 18:39:33 +08:00
|
|
|
std::copy( data, data + 2, reinterpret_cast<std::uint8_t*>( &( tileId )));
|
|
|
|
|
_tiles[x][y].tileId = tileId;
|
|
|
|
|
if( info )
|
|
|
|
|
{
|
|
|
|
|
_tiles[x][y].terrainInfo = &info->TerrainInfo( tileId );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
_tiles[x][y].altitude = *( reinterpret_cast<std::int8_t*>( data + 2 ));
|
|
|
|
|
data += 3; // advance data three bytes;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto TerrainBlock::TerrainTileAt( int x, int y ) -> Tile_st&
|
|
|
|
|
{
|
|
|
|
|
return _tiles.at( x ).at( y );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto TerrainBlock::TerrainTileAt( int x, int y ) const -> const Tile_st&
|
|
|
|
|
{
|
|
|
|
|
return _tiles.at( x ).at( y );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//================================================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
// ArtBlock
|
2022-06-15 11:24:57 -04:00
|
|
|
//================================================================================
|
|
|
|
|
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
ArtBlock::ArtBlock( int length, std::uint8_t *data, const TileInfo *info )
|
|
|
|
|
{
|
|
|
|
|
if( data != nullptr )
|
|
|
|
|
{
|
|
|
|
|
LoadArtBlock( length, data, info );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto ArtBlock::ArtTileAt( int x, int y ) -> std::vector<Tile_st>&
|
|
|
|
|
{
|
|
|
|
|
return _tiles.at( x ).at( y );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto ArtBlock::ArtTileAt( int x, int y ) const -> const std::vector<Tile_st>&
|
|
|
|
|
{
|
|
|
|
|
return _tiles.at( x ).at( y );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto ArtBlock::Clear() -> void
|
|
|
|
|
{
|
|
|
|
|
for( auto &row : _tiles )
|
|
|
|
|
{
|
|
|
|
|
for( auto &tile: row )
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
tile.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - ArtBlock::LoadArtBlock()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Load details for all art/statics tiles in a given location from statics files
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto ArtBlock::LoadArtBlock( int length, std::istream &input, const TileInfo *info ) -> void
|
|
|
|
|
{
|
|
|
|
|
this->Clear();
|
|
|
|
|
auto count = length / 7;
|
|
|
|
|
auto x = std::uint8_t( 0 );
|
|
|
|
|
auto y = std::uint8_t( 0 );
|
|
|
|
|
auto alt = std::int8_t( 0 );
|
|
|
|
|
for( auto i = 0; i < count; ++i )
|
|
|
|
|
{
|
|
|
|
|
auto artTile = Tile_st();
|
|
|
|
|
artTile.type = TileType_t::art;
|
|
|
|
|
input.read( reinterpret_cast<char*>( &artTile.tileId ), 2 );
|
|
|
|
|
input.read( reinterpret_cast<char*>( &x ), 1 );
|
|
|
|
|
input.read( reinterpret_cast<char*>( &y ), 1 );
|
|
|
|
|
input.read( reinterpret_cast<char*>( &alt ), 1 );
|
|
|
|
|
artTile.altitude = alt;
|
|
|
|
|
input.read( reinterpret_cast<char*>( &artTile.staticHue ), 2 );
|
|
|
|
|
if( info )
|
|
|
|
|
{
|
|
|
|
|
artTile.artInfo = &info->ArtInfo( artTile.tileId );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
ArtTileAt( x, y ).push_back( std::move( artTile ));
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - ArtBlock::LoadArtBlock()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Retrieve details for all art/statics tiles in a given location from memory
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto ArtBlock::LoadArtBlock( int length, std::uint8_t *data, const TileInfo *info ) -> void
|
|
|
|
|
{
|
|
|
|
|
this->Clear();
|
2022-06-15 11:24:57 -04:00
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
auto count = length / 7;
|
|
|
|
|
auto x = std::uint8_t( 0 );
|
|
|
|
|
auto y = std::uint8_t( 0 );
|
|
|
|
|
for( auto i = 0; i < count; ++i )
|
|
|
|
|
{
|
|
|
|
|
auto artTile = Tile_st();
|
|
|
|
|
artTile.type = TileType_t::art;
|
|
|
|
|
std::copy( data, data + 2, reinterpret_cast<char*>( &artTile.tileId ));
|
|
|
|
|
x = * ( data + 2 );
|
|
|
|
|
y = * ( data + 3 );
|
|
|
|
|
artTile.altitude = static_cast<int>( *( reinterpret_cast<std::int8_t*>( data + 4 )));
|
|
|
|
|
std::copy( data + 5, data + 7, reinterpret_cast<char*>( &artTile.staticHue ));
|
|
|
|
|
if( info )
|
|
|
|
|
{
|
|
|
|
|
artTile.artInfo = &info->ArtInfo( artTile.tileId );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
ArtTileAt( x, y ).push_back( std::move( artTile ));
|
|
|
|
|
data += 7;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-24 18:39:33 +08:00
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| UltimaMap
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
2022-11-04 17:12:13 -04:00
|
|
|
UltimaMap::UltimaMap() : tileInfo( nullptr ), _width( 0 ), _height( 0 ), _diffCount( 0 ), _diffTerrain( 0 )
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
UltimaMap::UltimaMap( int mapNum, int width, int height, const TileInfo *info ) : UltimaMap()
|
|
|
|
|
{
|
|
|
|
|
_width = width;
|
|
|
|
|
_height= height;
|
|
|
|
|
tileInfo = info;
|
|
|
|
|
_mapNum = mapNum;
|
|
|
|
|
auto size = _mapSizes.at( mapNum );
|
|
|
|
|
if( _width == 0 )
|
|
|
|
|
{
|
|
|
|
|
_width = size.first;
|
|
|
|
|
}
|
|
|
|
|
if( _height == 0 )
|
|
|
|
|
{
|
|
|
|
|
_height = size.second;
|
|
|
|
|
}
|
|
|
|
|
_terrain.resize(( _width / 8 ) * ( _height / 8 ));
|
|
|
|
|
_art.resize( _terrain.size() );
|
|
|
|
|
isUop = true;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - UltimaMap::Width()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Get width of map
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto UltimaMap::Width() const -> int
|
|
|
|
|
{
|
|
|
|
|
return _width;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - UltimaMap::Height()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Get height of map
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto UltimaMap::Height() const -> int
|
|
|
|
|
{
|
|
|
|
|
return _height;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - UltimaMap::SetSize()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Set width and height of map
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto UltimaMap::SetSize( int width, int height ) -> void
|
|
|
|
|
{
|
|
|
|
|
_width = width;
|
|
|
|
|
_height = height;
|
|
|
|
|
_terrain.resize(( _width / 8 ) * ( _height / 8 ));
|
|
|
|
|
_art.resize( _terrain.size() );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - UltimaMap::Size()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Get size of map as width/height pair
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto UltimaMap::Size() const -> std::pair<int, int>
|
|
|
|
|
{
|
|
|
|
|
return std::make_pair( static_cast<int>( _width ), static_cast<int>( _height ));
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto UltimaMap::DiffArt() const -> int
|
|
|
|
|
{
|
|
|
|
|
return _diffCount;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto UltimaMap::DiffTerrain() const -> int
|
|
|
|
|
{
|
|
|
|
|
return _diffTerrain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - UltimaMap::LoadUOPTerrainFile()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Load map data from uop-version of map files
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto UltimaMap::LoadUOPTerrainFile( const std::string &fileName ) -> bool
|
|
|
|
|
{
|
|
|
|
|
auto hash = this->Format( "build/map%ilegacymul/%s", _mapNum, "%.8u.dat" );
|
|
|
|
|
//auto fileName = this->format( "map%iLegacyMUL.uop", _mapNum );
|
|
|
|
|
isUop = LoadUop( fileName, 0x300, hash );
|
|
|
|
|
return isUop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - UltimaMap::LoadMulTerrainFile()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Load map data from mul-version of map files
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto UltimaMap::LoadMulTerrainFile(const std::string &fileName) -> bool {
|
|
|
|
|
auto rValue = false;
|
|
|
|
|
auto mul = std::ifstream( fileName, std::ios::binary );
|
|
|
|
|
if( mul.is_open() )
|
|
|
|
|
{
|
|
|
|
|
rValue = true;
|
|
|
|
|
isUop = false;
|
|
|
|
|
auto data = std::vector<std::uint8_t>( 196, 0 );
|
|
|
|
|
auto blockNum = 0;
|
|
|
|
|
while( mul.good() && !mul.eof() )
|
|
|
|
|
{
|
|
|
|
|
mul.read( reinterpret_cast<char*>( data.data() ), 196 );
|
|
|
|
|
if( mul.gcount() == 196 )
|
|
|
|
|
{
|
|
|
|
|
LoadTerrainBlock( blockNum, data.data() );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
blockNum++;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return rValue;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - UltimaMap::LoadArt()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Load data from statics/staidx files
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto UltimaMap::LoadArt( const std::string &mulFile, const std::string &idxFile ) -> bool
|
|
|
|
|
{
|
|
|
|
|
auto idx = std::ifstream( idxFile, std::ios::binary );
|
|
|
|
|
auto rValue = idx.is_open();
|
|
|
|
|
if( rValue )
|
|
|
|
|
{
|
|
|
|
|
auto mul = std::ifstream( mulFile, std::ios::binary );
|
|
|
|
|
rValue = mul.is_open();
|
|
|
|
|
if( rValue )
|
|
|
|
|
{
|
|
|
|
|
auto offset = std::uint32_t( 0 );
|
|
|
|
|
auto length = std::int32_t( 0 );
|
|
|
|
|
auto extra = std::uint32_t( 0 );
|
2022-11-04 17:12:13 -04:00
|
|
|
size_t block = 0;
|
2022-10-24 18:39:33 +08:00
|
|
|
while( idx.good() && !idx.eof() )
|
|
|
|
|
{
|
|
|
|
|
idx.read( reinterpret_cast<char*>( &offset ), 4 );
|
|
|
|
|
idx.read( reinterpret_cast<char*>( &length ), 4 );
|
|
|
|
|
idx.read( reinterpret_cast<char*>( &extra ), 4 );
|
|
|
|
|
if(( length > 0 ) && ( idx.gcount() == 4 ))
|
|
|
|
|
{
|
|
|
|
|
mul.seekg( offset, std::ios::beg );
|
|
|
|
|
if( block < _art.size() )
|
|
|
|
|
{
|
|
|
|
|
_art[block].LoadArtBlock( length, mul, tileInfo );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
++block;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return rValue;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - UltimaMap::ApplyDiff()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Apply patches from diff files to statics for map loaded by UOX3
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto UltimaMap::ApplyDiff( const std::string &difflPath, const std::string &diffiPath, const std::string &diffPath ) -> int
|
|
|
|
|
{
|
|
|
|
|
_diffCount = 0;
|
|
|
|
|
auto diffBlock = std::ifstream( difflPath, std::ios::binary );
|
|
|
|
|
if( diffBlock.is_open() )
|
|
|
|
|
{
|
|
|
|
|
auto diffIdx = std::ifstream( diffiPath, std::ios::binary );
|
|
|
|
|
if( diffIdx.is_open() )
|
|
|
|
|
{
|
|
|
|
|
auto diff = std::ifstream( diffPath, std::ios::binary );
|
|
|
|
|
if( diff.is_open() )
|
|
|
|
|
{
|
|
|
|
|
auto blockNum = std::uint32_t( 0 );
|
|
|
|
|
auto offset = std::uint32_t( 0 );
|
|
|
|
|
auto length = std::int32_t( 0 );
|
|
|
|
|
auto extra = std::uint32_t( 0 );
|
|
|
|
|
while( diffBlock.good() && !diffBlock.eof() )
|
|
|
|
|
{
|
|
|
|
|
diffBlock.read( reinterpret_cast<char*>( &blockNum ), 4 );
|
|
|
|
|
diffIdx.read( reinterpret_cast<char*>( &offset ), 4 );
|
|
|
|
|
diffIdx.read( reinterpret_cast<char*>( &length ), 4 );
|
|
|
|
|
diffIdx.read( reinterpret_cast<char*>( &extra ), 4 );
|
|
|
|
|
if(( diffBlock.gcount() == 4 ) && ( diffIdx.gcount() == 4 ))
|
|
|
|
|
{
|
|
|
|
|
if( blockNum < _art.size() )
|
|
|
|
|
{
|
|
|
|
|
if( length > 0 )
|
|
|
|
|
{
|
|
|
|
|
diff.seekg( offset, std::ios::beg );
|
|
|
|
|
_art[blockNum].LoadArtBlock( length, diff, tileInfo );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_art[blockNum].Clear();
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
++_diffCount;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return _diffCount;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Function - UltimaMap::ApplyTerrainDiff()
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
//| Purpose - Apply patches from diff files to map loaded by UOX3
|
|
|
|
|
//o------------------------------------------------------------------------------------------------o
|
|
|
|
|
auto UltimaMap::ApplyTerrainDiff( const std::string &difflPath, const std::string &diffPath ) -> int
|
|
|
|
|
{
|
|
|
|
|
auto diffblock = std::ifstream( difflPath, std::ios::binary );
|
|
|
|
|
_diffTerrain = 0;
|
|
|
|
|
if( diffblock.is_open() )
|
|
|
|
|
{
|
|
|
|
|
auto diff = std::ifstream( diffPath, std::ios::binary );
|
|
|
|
|
if( diff.is_open() )
|
|
|
|
|
{
|
|
|
|
|
auto blocknum = std::uint32_t( 0 );
|
|
|
|
|
auto data = std::vector<std::uint8_t>( 196, 0 );
|
|
|
|
|
while( diffblock.good() && !diffblock.eof() )
|
|
|
|
|
{
|
|
|
|
|
diffblock.read( reinterpret_cast<char*>( &blocknum ), 4 );
|
|
|
|
|
if( diffblock.gcount() == 4 )
|
|
|
|
|
{
|
|
|
|
|
diff.read( reinterpret_cast<char*>( data.data() ), 196 );
|
|
|
|
|
if( diff.gcount() == 196 )
|
|
|
|
|
{
|
|
|
|
|
_terrain[blocknum].LoadBlock( data.data(), tileInfo );
|
|
|
|
|
_diffTerrain++;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return _diffTerrain;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto UltimaMap::CalcBlock( int x, int y) const -> int
|
|
|
|
|
{
|
2022-06-15 11:24:57 -04:00
|
|
|
// How many blocks is x across?
|
2022-10-24 18:39:33 +08:00
|
|
|
return (( x / 8 ) * ( _height / 8 )) + ( y / 8 );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto UltimaMap::CalcXYOffset( int block ) const -> std::pair<int, int>
|
|
|
|
|
{
|
|
|
|
|
auto x = ( block / ( _height / 8 )) * 8;
|
|
|
|
|
auto y = ( block % ( _height / 8 )) * 8;
|
|
|
|
|
return std::make_pair( x, y );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto UltimaMap::BlockAndIndexFor( int x, int y ) const -> std::tuple<int, int, int>
|
|
|
|
|
{
|
|
|
|
|
auto block = CalcBlock( x, y );
|
|
|
|
|
auto offset = CalcXYOffset( block );
|
|
|
|
|
return std::make_tuple( block, x - offset.first, y - offset.second );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
//=========================================================
|
2022-11-14 21:12:12 -05:00
|
|
|
auto UltimaMap::ProcessEntry( [[maybe_unused]] std::size_t entry, std::size_t index, std::vector<std::uint8_t> &data ) -> bool
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
|
|
|
|
auto count = data.size() / 196;
|
2022-11-04 17:12:13 -04:00
|
|
|
size_t block = ( static_cast<int>( index ) * 0xC4000 ) / 196;
|
2022-12-04 02:03:43 -05:00
|
|
|
for( auto i = 0; i < static_cast<int>( count ); ++i )
|
2022-10-24 18:39:33 +08:00
|
|
|
{
|
|
|
|
|
auto ptr = data.data() + ( i * 196 );
|
|
|
|
|
if( block < _terrain.size() )
|
|
|
|
|
{
|
0.99.6-RC6x
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
2023-10-14 05:03:53 +08:00
|
|
|
LoadTerrainBlock( static_cast<int>( block ), ptr );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
++block;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
2022-10-24 18:39:33 +08:00
|
|
|
return true;
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto UltimaMap::LoadTerrainBlock( int blocknum, std::uint8_t *data ) -> void
|
|
|
|
|
{
|
|
|
|
|
_terrain[blocknum].LoadBlock( data, tileInfo );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto UltimaMap::TerrainAt( int x, int y ) const -> const Tile_st&
|
|
|
|
|
{
|
|
|
|
|
auto [blocknum, xoffset, yoffset] = BlockAndIndexFor( x, y );
|
|
|
|
|
return _terrain[blocknum].TerrainTileAt( xoffset, yoffset );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto UltimaMap::TerrainAt( int x, int y ) -> Tile_st&
|
|
|
|
|
{
|
|
|
|
|
auto [blocknum, xoffset, yoffset] = BlockAndIndexFor( x, y );
|
|
|
|
|
return _terrain[blocknum].TerrainTileAt( xoffset, yoffset );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto UltimaMap::ArtAt( int x, int y ) const -> const std::vector<Tile_st>&
|
|
|
|
|
{
|
|
|
|
|
auto [blocknum, xoffset, yoffset] = BlockAndIndexFor( x, y );
|
|
|
|
|
return _art[blocknum].ArtTileAt( xoffset, yoffset );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|
|
|
|
|
//=========================================================
|
2022-10-24 18:39:33 +08:00
|
|
|
auto UltimaMap::ArtAt( int x, int y ) -> std::vector<Tile_st>&
|
|
|
|
|
{
|
|
|
|
|
auto [blocknum, xoffset,yoffset] = BlockAndIndexFor( x, y );
|
|
|
|
|
return _art[blocknum].ArtTileAt( xoffset, yoffset );
|
2022-06-15 11:24:57 -04:00
|
|
|
}
|