2019¶
12/25/2019¶
Akkadius
World CLI Interface Overhaul¶
- We've added a CLI interface to the world process which can be handy for various things, such as showing build version, database schema, database version or other utility things like setting account status. This feature is built in such a way that makes it easier for the development team to also add other commands in the future
- Added an internal single source of truth for where we maintain our database schema for different types of tables. These lists will be significant for things like export/import commands, future plans for multi-tenancy etc.
- Player Tables
- Content Tables
- State Tables
- Server Tables
- Login Tables
- CLI Interface Changes
- Commands that used option flags are arguments are now proper arguments as shown in examples. This is reflected in the Loginserver CLI as well and the documentation has been changed to reflect
- Old
- ./world database:set-account-status --name=* --status=*
- New
- ./world database:set-account-status {name} {status}
- ./world database:set-account-status myaccount 255
eqemu@9044748fdbe2:~/server$ ./bin/world --help
> EQEmulator [WorldServer] CLI Menu
database
database:schema Displays server database schema
database:set-account-status Sets account status by account name
database:version Shows database version
world
world:version Shows server version
12/10/2019¶
Uleat¶
Fixes and New Bot Command¶
- Fix for pets breaking mez during combat
- Fix for bot classes having skills they should not
- Added bot command
itemuse
- This command will cause spawned bots to report if they can use the item which you currently hold on your cursor
- To use this command, simply pick up an item and type
^itemuse
- All spawned bots will check their inventories based on the items 'Slots' property and report that it is usable by them (no report if not usable)
- Each bot will give a report for each eligible slot
- To give the item to any reporting bot, simply click the text link with their name in it
- This will invoke the
inventorygive
command using^inventorygive byname botname
- All rules governing use of the bot command
inventorygive
apply - You may also use the optional argument
^itemuse empty
to have bots only report empty inventory slots that can use it
12/8/2019¶
Uleat¶
New Bot Command Option ^follow chain
¶
- This command will affect a chain follow effect, starting with the bot owner
- All spawned bots will be included in this follow order unless they have previously been issued a follow command
- The chain processing will skip all bots with the
manual_follow
flag set - This flag may be removed by issuing a
^follow reset
on the affected bot or bots - The flag is temporary and is reset upon camping or zoning
12/3/2019¶
Uleat¶
New Bot Commands and Owner Option¶
- Added bot command
applypoison
- This will apply item type
42
poisons (rogue-crafted) to an owner's targeted rogue bot's weapon - Class and level restrictions are observed
- The application chance is the same as that for rogue players attempting to apply poison
- To apply, simply place the poison on your cursor and type
^applypoison
- You will receive a success/fail message and the item will be consumed in both cases
- This effect remains active during the time in zone - just like a player's poison application
- Added rule
Bots:AllowApplyPoisonCommand
to allow the command to be enabled or disabled per server admin's needs (default is true) - Added bot command
applypotion
- This will apply item type
21
potions to any bot targeted by its owner - Class, race and level restrictions are observed
- Potion-type rogue poisons must be applied using this command
- Casting time requirements are currently bypassed - expect a change in behavior at some point
- To apply, simply place the potion on your cursor and type
^applypotion
- You will receive a success/fail message and the item will be consumed in both cases
- This effect is retained as a 'casted buff' and will remain until expired or removed
- Added rule
Bots:AllowApplyPotionCommand
to allow the command to be enabled or disabled per server admin's needs (default is true) - Added rule
Bots:RestrictApplyPotionToRogue
to allow a restriction ofapplypotion
to rogue-only potions (i.e., poisons) (default is true) - Added bot owner option
buffcounter
- When enabled, any bot buff with a counter will display a marquee message indicating how many 'hits' remain
Note: Bot owner option deathmarquee
messages have been changed to red
in color.
Notes:
In order to get potion effects to work properly after zoning or camping, I had to borrow code from the client connection handler.
It's unknown whether this code helps in the case of bots recasting buffs upon zoning and spawning..but, I did notice the lack of rebuffing in many cases - will watch!
Uleat¶
Changed Bots:AAExpansion
to Bots:BotExpansionSettings
¶
- Changed this rule property from an enumerated value to a bitmask
- Renamed rule to coincide with the property change
- Works the same as
World:ExpansionSettings
in regards to active expansions (defaults to 16383 - same as the world rule) - Added code to bot aa assignment to honor the per-expansion restrictions
- This rule may be expanded in the future to other bot-related systems
11/25/2019¶
Uleat¶
New Command #nudge
¶
- Added command
nudge
to facilitate npc placement and orientation - Command accepts up to 4 arguments (x,y,z,h) and may use any combination, in any order
- Acceptable values are float-type for all parameters
- Values are interpreted as offsets and not absolute values
- Adjustments are 'set' by applying the command
#fixnpc
- This command is ideally suited for macro (hotkey) use
- Real-time updates are broadcast to clients..but, there may be 'visible' glitches if you try to use the command too fast (limited by packet broadcast timer)
- Examples of use:
#nudge x=1.00 y=-1.00 z=3.45 h=-11.38
#nudge x=2.33 z=-1.01
#nudge h=133.00 z=-12.34
11/18/2019¶
Uleat¶
EVENT_COMBINE_VALIDATE¶
- Added the new event
EVENT_COMBINE_VALIDATE
- This event is processed as the very last step in a tradeskill combine process just before the actual combine action
- Its use is automatic and criteria may be added to the
global_player
file for whichever scripting api that you are using - The initial candidate for special validation is tradeskill recipe #10344 - "Clockwork Scout Module"
function event_combine_validate(e)
if (e.recipe_id == 10344) then
if (e.validate_type:find("check_zone")) then
if (e.zone_id ~= 289 and e.zone_id ~= 290) then
return 1;
end
end
end
return 0;
end
- For this recipe, the combine is only allowed in two zones,
tipt
andvxed
- The active recipe id will always be passed by integer as the variable
recipe_id
- In this case, the active
validation_type
ofcheck_zone
, the current zone id will be passed by integer as the variablezone_id
- From there, a simple check against valid zones can be made
- Invalid zones will return a non-zero value resulting in a failure to validate the combine..hence, cancelling it
- Valid zones will return a zero value and allow the combine to occur normally
- The validation types can be expanded
- This initial implementation is to alleviate a current bug
Note: This change requires a quest update to capture the new global player files, or the changes may be added manually.
Noudess¶
Fix for client positions upon entering or exiting a boat¶
10/5/2019¶
Uleat¶
Bot AI and Command Changes¶
- Added two new 'Owner Option' features: *
altcombat
- enabled, bots aggro based on owner's attack state; disabled, pet-like behaviorautodefend
- enabled, bots defend owner on aggro; disabled, no action taken- Renamed bot command
^hold
to^suspend
(same action and counter to^release
) - Repurposed bot command
^hold
to override all attack actions - Reworked
^guard
to allow all 'normal' actions and for bots to return to their guard spots when idle - Bot command
^attack
should now work as intended - with noted exceptions above - Revamped bot command
^pull
: * - Pulling bot will travel to entity, gain aggro, then return to home position
- Aggro is attained through the use of the low-damage spell 'Throw Stone'
- Pulling candidacy is currently determined by a 4-tier ranking system
9/30/2019¶
Akkadius
Login Server Changes¶
- Auto convert insecure world server admin passwords during the world authentication process
- Add CLI support for updating world admin account
world-admin:update --username=* --password=
*
9/19/2019¶
Kinglykrab
Fixed Maximum Status value in entity_list.QueueClientsStatus.
- Maximum Status of 250 was causing status levels 251 to 254 to be excluded from the queue.
9/17/2019¶
Akkadius
Login Server Overhaul¶
Info
There's a few weeks of solid work wrapped in this update, you can review the changes in this pull request if you wish
Login Server Highlights¶
- Database schema includes all new tables, to migrate see migration reference below
- All new config file JSON format
login.json
found in./loginserver/login_util/login.json
- Now has an embedded Web API on port 6000 by default, details can be found at Loginserver API
- Now has a rich embedded CLI interface, details found at Login CLI Interface
- Now uses Scrypt for encryption which you can learn more about here
- Now automatically updates weak encryption methods during client login to the latest encryption method (Scrypt) in use on the fly
- Now properly supports string escaping in all database calls
- Now no longer requires you to specify a Local LAN subnet in the config to detect LAN world servers and LAN player connections. The server now can intelligently detect RFC1918 local LAN subnets in the requests to properly mark both World Server connections and Player connections appropriately (Plug-N-Play)
- A production and stage/testing server of the same long name / short name pair can now live together as long as one world is registered
- Code is heavily cleaned up, many parts not perfect but far far improved
- Many many bug fixes, stability improvements
- Improvements made to world -> loginserver and loginserver -> world reconnects through keep-alive. If a world is disconnected it will properly picked up by world and vise versa. Which also allows the chance for the process to reconnect sooner because it knows it had a connection die instead of waiting for it to be told
- Improvements made to world -> zone and zone -> world disconnects through keep-alive for example on Linux if world had been killed, it would not gracefully reconnect to all zone processes and vise versa
Migrating a Legacy Login Server¶
Info
To migrate your Legacy login server, follow this guide Migrating your Legacy Loginserver
Log System Enhancements¶
- The popular C++ library FMT is now powering most of our logging FMT Library
- Migrated thousands of log calls to use now simplified log aliases, the most recent up to date list can be found here
https://github.com/EQEmu/Server/blob/master/common/eqemu_logsys_log_aliases.h
The main reason for these changes is that it simplifies the use of logging by developers, it also makes it far easier to create logging statements because we no longer need to look up printf codes to match variable types going into logging calls as our FMT library that we are using will detect the types at runtime
Using the category log aliases also heavily simplifies the amount of verbosity that goes into simply typing the log statements to begin with
We have Detail level aliases, but we are trying to keep from using detail in categorized logging, if you are using detail you probably either need to use another specialized category. The only time detail should ever really be used is if it is incredibly spammy to the rest of the logging in the same category
Log(Logs::General, Logs::ZoneServer, "Connecting to MySQL... ");
Log(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf);
Log(Logs::Detail, Logs::Spells, "Bard song %d started: slot %d, target id %d", bardsong, bardsong_slot, bardsong_target_id);
Log(Logs::Detail, Logs::Combat, "Final damage after all reductions: %d", hit.damage_done);
LogInfo("Connecting to MySQL... ");
LogError("Failed to connect to database: Error: {}", errbuf);
LogSpells("Bard song [{}] started: slot [{}], target id [{}]", bardsong, (int) bardsong_slot, bardsong_target_id);
LogCombat("Final damage after all reductions: [{}]", hit.damage_done);
LogEmergency
LogAlert
LogCritical
LogError
LogWarning
LogNotice
LogInfo
LogDebug
LogAA
LogAADetail
LogAI
LogAIDetail
LogAggro
LogAggroDetail
LogAttack
LogAttackDetail
LogPacketClientServer
LogPacketClientServerDetail
LogCombat
LogCombatDetail
LogCommands
LogCommandsDetail
LogCrash
LogCrashDetail
LogDoors
LogDoorsDetail
LogGuilds
LogGuildsDetail
LogInventory
LogInventoryDetail
LogLauncher
LogLauncherDetail
LogNetcode
LogNetcodeDetail
LogNormal
LogNormalDetail
LogObject
LogObjectDetail
LogPathing
LogPathingDetail
LogQSServer
LogQSServerDetail
LogQuests
LogQuestsDetail
LogRules
LogRulesDetail
LogSkills
LogSkillsDetail
LogSpawns
LogSpawnsDetail
LogSpells
LogSpellsDetail
LogTCPConnection
LogTCPConnectionDetail
LogTasks
LogTasksDetail
LogTradeskills
LogTradeskillsDetail
LogTrading
LogTradingDetail
LogTribute
LogTributeDetail
LogMySQLError
LogMySQLErrorDetail
LogMySQLQuery
LogMySQLQueryDetail
LogMercenaries
LogMercenariesDetail
LogQuestDebug
LogQuestDebugDetail
LogLoginserver
LogLoginserverDetail
LogClientLogin
LogClientLoginDetail
LogHeadlessClient
LogHeadlessClientDetail
LogHPUpdate
LogHPUpdateDetail
LogFixZ
LogFixZDetail
LogFood
LogFoodDetail
LogTraps
LogTrapsDetail
LogNPCRoamBox
LogNPCRoamBoxDetail
LogNPCScaling
LogNPCScalingDetail
LogMobAppearance
LogMobAppearanceDetail
LogStatus
LogStatusDetail
RFC5424 Log Categories¶
RFC5424 Log Categories have been introduced, they are meant to simplify the use of common logging scenarios that don't require specific categories
LogEmergency
LogAlert
LogCritical
LogError
LogWarning
LogNotice
LogInfo
LogDebug
When using any of these macros, logging output will append the process name before the message itself, thus deprecating process specific categories
Example¶
[WorldServer] [Info] Purging expired data buckets
[WorldServer] [Info] Loading zones
[WorldServer] [Info] Clearing groups
[WorldServer] [Info] Clearing raids
[WorldServer] [Info] Clearing inventory snapshots
[WorldServer] [Info] Loading items
[WorldServer] [Info] Loading skill caps
[WorldServer] [Info] Loading guilds
[LoginServer] [Warning] Remote address was null, defaulting to stream address 127.0.0.1
9/4/2019¶
Uleat
Added code to restore rule notes to their original values
9/2/2019¶
Uleat
Added code to inject new rules into the 'default' ruleset and remove orphaned rules from all rulesets
- New rules are only added using the 'default' ruleset - Other rulesets will need to be added manually or through in-game updates
- Rule notes are now loaded into the system's hard-coded entries and will now propagate properly into database updates
- Defunct rules will have their orphaned entries removed from the 'rule_values' table for the all rulesets
8/30/2019¶
Uleat
Added code to inject new commands and remove orphaned commands from both command systems
- New commands are added with their status ('access') set to the server default value - no aliases are defined
- Defunct commands will have their orhpaned entries removed from the command settings table for each system
8/16/2019¶
Akkadius
Simplified Roambox Usage and Improve Roambox AI¶
New Roambox GM Commands¶
- Implemented command #roambox set [move_delay]
- Implemented command #roambox remove
New Roambox Quest API Calls¶
$npc->SetSimpleRoamBox(box_size, [move_distance], [move_delay]);
NPC:SetSimpleRoamBox(box_size, [move_distance], [move_delay]);
New GM Commands!¶
- Spawngroup data now hot reloads on #repop
- Command #npceditmass now lists column options when one isn't properly specified
- Implemented command #spawneditmass [search] [option] with options [respawn_time] currently implemented
8/11/2019¶
Akkadius
Bulk Editing GM Commands! #npceditmass¶
Added bulk edit command #npceditmass [column-to-search] [column-search-value] [change-column] [change-value]
#findzone Enhancements!¶
- Modified #findzone to include clickable saylinks to both regular zone (if able) and private gmzone instances
- Added command #findzone [expansion-number] expansion to show zones via expansion
8/6/2019¶
Akkadius Optimizations to movement updates to eliminate ghosting possibilities in larger zones
7/22/2019¶
Uleat
Windows Build Work¶
Added script \vcxproj_dependencies.py a script to help determine conflicting project dependencies (alpha-stage)
7/10/2019¶
Akkadius
NPC Flymode Changes - Commands and DB Changes¶
- Add #npcedit flymode [0 = ground, 1 = flying, 2 = levitate, 3 = water, 4 = floating]
- Added "flymode" to npc_types database table
7/3/2019¶
Akkadius/KLS
Packet Compress, CPU, Position Update Optimizations¶
- Optimizations to packet updates introduced back into the source post network code overhaul
- Optimizations made to position update packets by sending updates far less frequently when not in line with zone:max_movement_update_range
- Optimizations made to position updates in respect to the much higher resolution of navmesh path finding that we were using. We have cut down on the resolution of path finding / updating so that we reduce the CPU overhead of path*finding and subsequent client update packets that get generated this action
- Optimization made by adjusting ZLIB compression rate that was accidentally set to a compression level of 4 a long time ago
Added #netstats Command¶
- Added #netstats admin command to troubleshoot connection issues in detail
Zone Process now Has an Embedded Websocket Server¶
Websocket server is now available in zone and is bound to the same UDP port that the zoneserver listens on
- Currently implemented websocket API calls at the zone level
- get_packet_statistics
- get_opcode_list
- get_npc_list_detail
- get_door_list_detail
- get_corpse_list_detail
- get_object_list_detail
- get_mob_list_detail
- get_client_list_detail
- get_zone_attributes
- get_logsys_categories
- set_logging_level
- Example of a Typescript client: https://gist.github.com/Akkadius/52d12d0379f36cf81c51b3b7da13db37
- Library Changes
EQEmu Server Build Changes - Using Submodules¶
-
We now use git submodules for libraries / dependencies versus manually downloading to the dependencies folder and/or storing
said dependencies within our codebase itself * To update dependencies (Required for compiling) *
git submodule init
*git submodule update
* Libraries now in submodules * [glm] https://github.com/g-truc/glm.git * [flm] https://github.com/fmtlib/fmt.git * [libuv] https://github.com/libuv/libuv.git * [cereal] https://github.com/USCiLab/cereal.git * [websocketpp] https://github.com/zaphoyd/websocketpp.git * [recastnavigation] https://github.com/EQEmu/recastnavigation.git
6/24/2019¶
Uleat
Reworked BotDatabase Into a Functional Add-On for ZoneDatabase¶
- Eliminated the database connection associated with class BotDatabase
- All behaviors remain the same with the exception of the calling object
- To invoke a BotDatabase function, use
database.botdb
rather thanbotdb
3/1/2019¶
Noudess
Major Faction Conversion to Use Real Client Data¶
Pull request #802 New min/max personal faction per faction. Use of actual client mods for race/class/deity.
This PR involves major changes to your database and server operators quests
The clients recently exposed raw data included
- Min/Max personal faction for each faction
- Actual faction id the client uses for each faction
- Actual mods that come into play when a PC cons an opponent that determine your overall con to that faction
Approach¶
The approach I took resulted in minimal change to the code base. I did alter the code to enforce the new validated min/max from the client. This min/max applies to personally earned faction. So if a faction has a min of 0 and a max of 2000, that means your personally earned value can never go below 0 or over 2000. The actual con, will, however often do so because of class/race/deity modifications. I also changed the con ranges, per Mackal's data that was proven to be accurate
Faction | Value |
---|---|
Ally | 1100+ |
Warmly | 750 to 1099 |
Kindly | 500 to 749 |
Amiable | 100 to 499 |
Indifferent | 0 to 99 |
Apprehensive | -1 to -100 |
Dubious | -101 to -500 |
Threateningly | -501 to -750 |
Ready to Attack | -751 |
The above means that dubious is a much smaller range now. For that reason the scripts modify any custom faction base values to put them in the same range, hopefully as the creators of the custom factions intended.
Also to be noted as characters that have a faction between -501 and -700 wont be dubious anymore, they will be threateningly. This is expected with the new ranges, but might take players by surprise as the old ranges we used were more liberal but were incorrect.
The database is changed extensively, but really only content. We're translating faction_list
to use the clients ids. As such every place a faction_is is used, namely (see below) are being converted
- faction_list
- faction_list_mod
- npc_faction (primary_faction field only)
- npc_faction_entries (faction_id field only)
- faction_values
Quests will also automatically be adjusted. This MUST be done after the PR sql and before starting the server. This is automated by eqemu_server.pl (or starting world)
Be assured, custom factions that you may have created, or obsolete or duplicate factions in our original faction_list, that you may have used, will be preserved. Anything that does not map directly is being moved to the 5000 range in faction_list and any references are corrected to point there.
A great example of this is Ebon Mask and Hall of the Ebon Mask. Many PEQ DB style servers have both of these. Some have used one, some the other. We map Ebon Mask to the clients Ebon mask and the Hall of the Ebon Mask gets moved to the 5000 range, and all its references are preserved. However, if you would like to make proper use of client mobs to Ebon mask, or other factions that have duplicitous entries, I recommend you manually move to using the correct one. In that way all of the new raw data mapped in from the client into faction_list_mod will get used instead of what your db had before these values were known.
In my experience converting 4 different server's data, there are only about 20 factions moved into the 5000 range.
This PR has only 1 new, permanent table faction_base_data, which is taken right from the client. The base field is left in case you want to mod your server, but we are very sure that the client doesn't use a base. It uses global mods to race or class for this as you'll see in the new faction_list_mod
The PR makes many backup tables, and two mapping tables that are used during the conversion process to fix quests. This table was hand created by analysis. This table serves no purpose after conversion except an audit trail if we see any issues.
I will release a new PR that will clean up all these backups and temporary tables in about a month.
2/7/2019¶
Uleat
Merc and Bots Now Use the Same Stance Standard¶
- Both classes will now use the same stance standard
- Pushed stance types up to EQEmu::constants
2/4/2019¶
Uleat
Added GM-Command "profanity"¶
- This is a server-based tool for redacting any language that an admin deems as profanity (socially unacceptable within their community)
- Five options are available under this command
list
__ shows the current list of banned wordsclears
the current list of banned wordsadd
adds to the banned word listdel
deletes from the banned word listreload
forces a reload of the banned word list- All actions are immediate and a world broadcast refreshes other active zones
- The system is in stand-by when the list is empty..just add a word to the list to begin censorship
- Redaction only occurs on genuine occurrences of any banned word
- Banned words are replaced with a series of '' characters
- Compounded words are ignored to avoid issues with allowed words containing a banned substring
- If 'test' is banned, 'testing' will not be banned .. it must be added separately
- Extreme care should be exercised when adding words to the banned list
- Quest failures and limited social interactions may alienate players if they become inhibiting
- System commands are allowed to be processed before redaction occurs in the 'say' channel
- A longer list requires more clock cycles to process - so, try to keep them to the most offensible occurrences
- Fix for bots ceasing combat when their 'follow me' mob dies
- Bots will revert to their client leash owner (bot owner or client group leader) when their FollowID() mob is no longer valid
- Combat will no longer be interrupted in these cases
- Does not apply to bot owner death
1/26/2019¶
Uleat
Fix for class Bot not honoring NPCType data reference¶
- Fixes bots not moving on spawn/grouping issue
- Report any issues with non movement-related behavior
1/24/2019¶
Uleat
Extended Server SpellBook Entries to RoF2 Standard...¶
...and added per-client restriction of spell id max
- Bumped server spellbook entry capacity to 720 spells
- Server keeps all 'learned' spells as found
- Access is limited by the clients' limitations of spellbook capacities and max spell ids
- This is done to avoid losing spells by switching from newer clients to older ones
- Existing behavior is kept in place for illegal access conditions
- Each client is still restricted to its spellbook capacity (400, 480, 480, 720, 720, 720 - respectively)
- Each client is restricted to its max supported spell id (9999, 15999, 23000, 28000, 45000, 45000 respectively)
- Please report any abnormal behavior so it may be addressed
- Removed server-side checksum of player profile..wasted calculation since it's performed again in all translators
1/20/2019¶
Uleat
Added "spells" Entry to EQDictionary¶
Akkadius
Extended GM-Command #goto, New #who, #gmzone Commands¶
- [Command] Extended #goto via #goto [playername]
- This will work cross zone, cross instance, in zone etc.
- It works on top of the original #goto (target) and #goto x y z
- [Command] Implemented server side #who
- Searches can be filtered by
- Account Name
- Base Class Name
- Guild Name
- IP
- Player Name
- Race Name
- Zone Short Name
-
Features a clickable (Goto) saylink that will bring you directly to a player regardless of
whether or not they are in an instance * [Command] Implemented: #gmzone [zone_short_name] [zone_version=0] [identifier=gmzone] * Zones to a private GM instance
Fixes to NPC's Ghosting at Zone Entrances¶
Fix issue where NPC's clip into the world and the client interprets them at coordinates _**_0,0,0
This issue would show itself when NPC's would bunch up by a zone-in
1/15/2019¶
Uleat
Activated Per-Expansion Support for Active Inventory Slot Addressing¶
- Server honors expansions that alter bank size and power source, general9 and general10 slots
- Server honors gm flag behaviors for the active inventory slots of each client
1/11/2019¶
Uleat
Modified Rules System to Ignore All Runtime Modifications...¶
of 'World:ExpansionSettings' and 'World:UseClientBasedExpansionSettings' fields.
- These fields are no longer allowed to be changed during server runtime through the command system
- Major synchronization issues between server and clients result when these fields are altered in-game
- It is not recommended to update these fields via sql queries while the server is in operation
- Failure to observe these warnings will result in abhorant behavior and loss of items
- Modify these fields during server operation at your own risk!
¼/2019¶
Akkadius
Global base scaling data has been updated in new database binary revision
1/1/2019¶
Akkadius
New DevTool Commands, Categories, Logging and Scaling¶
- Logging: Added new logging category
MobAppearance
- DevTools Proximity show of NPC now shows a "Path finding" circle around the proximity nodes to more clearly display
- Scaling Global base scaling data now refreshes from the database on #repop
- Commands Implemented command #killallnpcs [npc_name] for testing, leave blank for all attackable NPC's
NPC and Player Textures¶
- Textures that have been changed with #wearchange / #wc or any wearchange quest script call will now stick for new clients entering a zone
- Weapon models for NPCs changed using wearchange will stick as well during combat and when new clients enter the zone
- The above changes allow for customization of a zone and NPC's without needing static data configured on npc_types table data and allows for much more customization options
Implemented Ornamentation Quest API Calls¶
$client->SetPrimaryWeaponOrnamentation(uint32 model_id);
$client->SetSecondaryWeaponOrnamentation(uint32 model_id);
client:SetPrimaryWeaponOrnamentation(uint32 model_id);
client:SetSecondaryWeaponOrnamentation(uint32 model_id);
Both of these API calls persist an ornamentation to the weapon in the inventory table and will load both in character select and cross zone