diff --git a/CMakeLists.txt b/CMakeLists.txt index 494959cbc..ec126b241 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ #EQEMU_BUILD_LUA #EQEMU_SANITIZE_LUA_LIBS #EQEMU_BUILD_CLIENT_FILES +#EQEMU_USE_MAP_MMFS #EQEMU_MAP_DIR #We set a fairly new version (as of 2013) because I found finding perl was a bit... buggy on older ones @@ -275,6 +276,11 @@ IF(EQEMU_BUILD_LUA) ADD_DEFINITIONS(-DLUA_EQEMU) ENDIF(EQEMU_BUILD_LUA) +OPTION(EQEMU_USE_MAP_MMFS "Create and use Zone Map MMF files." OFF) +IF(EQEMU_USE_MAP_MMFS) + ADD_DEFINITIONS(-DUSE_MAP_MMFS) +ENDIF(EQEMU_USE_MAP_MMFS) + SET(EQEMU_MAP_DIR "./Maps" CACHE STRING "The dir that maps, water maps, and paths are located in.") ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL}) diff --git a/README.md b/README.md index 0c973ed43..057937a0c 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,59 @@ -EQEmu -=== +# EQEmulator Core Server +|Travis CI (Linux)|Appveyor (Windows) | +|:---:|:---:| +|[![Linux CI](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) |[![Windows CI](https://ci.appveyor.com/api/projects/status/d0cvokm7u732v8vl/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server/branch/master) | -[![Build Status](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) +*** -Overview ---- +**EQEmulator is a custom completely from-scratch open source server implementation for EverQuest built mostly on C++** + * MySQL/MariaDB is used as the database engine (over 200+ tables) + * Perl and LUA are both supported scripting languages for NPC/Player/Quest oriented events + * Open source database (Project EQ) has content up to expansion GoD (included in server installs) + * Game server environments and databases can be heavily customized to create all new experiences + * Hundreds of Quests/events created and maintained by Project EQ -EQEmu is a custom server implementation for EverQuest +## Server Installs +| |Windows|Linux| +|:---:|:---:|:---:| +|**Install Count**|![Windows Install Count](http://analytics.akkadius.com/?install_count&windows_count)|![Linux Install Count](http://analytics.akkadius.com/?install_count&linux_count)| +### > Windows +* [Easy Install](http://wiki.eqemulator.org/p?Akkas_PEQ_Server_Installer&frm=Main#from-scratch-installation-instructions-windows) +* [Advanced Setup](http://wiki.eqemulator.org/p?Complete_Windows-based_Server_Setup_Guide) -Dependencies ---- +### > Debian/Ubuntu -For Windows: http://eqemu.github.io +> wget --no-check-certificate https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh -O install.sh && chmod 755 install.sh && ./install.sh -Login Server dependencies for Windows/Linux/OSX: http://eqemu.github.io +### > CentOS/Fedora -For Debian based distros (adjust to your local flavor): +> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh -- libmysqlclient-dev -- libperl-dev -- liblua5.1-0-dev (5.2 should work as well) -- libboost-dev +## Supported Clients -Further instructions on building the source can be found on the -[wiki](http://wiki.eqemulator.org/i?M=Wiki). +|Titanium Edition|Secrets of Faydwer|Seeds of Destruction|Underfoot|Rain of Fear| +|:---:|:---:|:---:|:---:|:---:| +|||||| -Bug reports ---- - -Please use the [issue tracker](https://github.com/EQEmu/Server/issues) provided by GitHub to send us bug +## Bug Reports +* Please use the [issue tracker](https://github.com/EQEmu/Server/issues) provided by GitHub to send us bug reports or feature requests. +* The [EQEmu Forums](http://www.eqemulator.org/forums/) are also a place to submit and get help with bugs. -The [EQEmu Forums](http://www.eqemulator.org/forums/) also have forums to submit -bugs/get help with bugs. +## Contributions -Contributions ---- - -The preferred way to contribute is to fork the repo and submit a pull request on +* The preferred way to contribute is to fork the repo and submit a pull request on GitHub. If you need help with your changes, you can always post on the forums or -try IRC. You can also post unified diffs (`git diff` should do the trick) on the +try Discord. You can also post unified diffs (`git diff` should do the trick) on the [Server Code Submissions](http://www.eqemulator.org/forums/forumdisplay.php?f=669) forum, although pull requests will be much quicker and easier on all parties. -Contact ---- - - **User IRC Channel**: `#eqemu` on `irc.eqemulator.net` - - **Developer IRC Channel**: `#eqemucoders` on `irc.eqemulator.net` +## Contact + - Discord Channel: https://discord.gg/QHsm7CD + - **User Discord Channel**: `#general` + - **Developer Discord Channel**: `#eqemucoders` + +Resources +--- - [EQEmulator Forums](http://www.eqemulator.org/forums) - [EQEmulator Wiki](http://wiki.eqemulator.org/i?M=Wiki) - diff --git a/changelog.txt b/changelog.txt index e3762b3dd..7386c7602 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,449 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 4/1/2017 == +Akkadius: Cleaned up some of the NPC to NPC aggro code, only do aggro checks to other NPC's when the NPC is flagged for it +Akkadius: [Performance] Reworked how all log calls are made in the source + - Before we used Log.Out, we will now use a macro Log( + - Before: Log.Out(Logs::General, Logs::Status, "Importing Spells..."); + - After: Log(Logs::General, Logs::Status, "Importing Spells..."); + - The difference is + 1) It's 200-300x faster especially when log statements are inside very hot code paths. We already + had most hot paths checked before we logged them, but this blankets all existing logging calls now and not just the + select few we had picked out in the source. + 2) Strings don't get copied to the stack, popped and pushed constantly even when we hit a log statement that + actually isn't going to log anything. + - We do an 'if (LogSys.log_settings[log_category].is_category_enabled == 1)' before we call a log function + in the log macro so the log function doesn't get called at all if we're not logging the category + - This has increased binary executables roughly 15KB + - The old extern for EQEmuLogSys is now named LogSys appropriately instead of Log (Ex: LogSys.StartFileLogs()) + - The result keeps logging footprint non-existent for when we're not logging that category + +== 03/30/2017 == +Akkadius: [Performance] Fixed an overhead issue where many hot paths would trigger quest subroutines and beneath that the code would + try to see if a quest existed perpetually (checking if file exists) even though it should have determined the quest + didn't exist the first time. + - This caused a lot of overhead in an instance where an entire zone of NPC's is pathing, triggering EVENT_WAYPOINT_ARRIVE + and EVENT_WAYPOINT_DEPART when there is no global_npc.pl/lua, or all NPC's pathing don't have a quest assigned, similar + behavior would occur. This goes for any other type of quests: spells, items, encounters etc. + +== 03/28/2017 == +Akkadius: [Performance] Fixed a large overhead issue where every single NPC in a zone was checking to depop themselves + as a swarm pet every 3ms regardless of being a swarm pet or not. Swarm pets now check to depop only when their timer is up +Akkadius: [Performance] Removed a timer where clients would constantly calculate light amount on equipment every 600ms, instead + clients will update light when changing equipment or entering a zone +Akkadius: [Performance] Disabled enraged timer checks for NPC's that do not actually have enrage as a special attack +Akkadius: [Performance] Don't process ProjectileAttack checks for NPC's that are not engaged in any combat + +== 03/27/2017 == +Akkadius: [Performance] Reworked how client to NPC aggro checks are made + - Before when reverse aggro checks were done (client to NPC), checks would happen every 750 millseconds where a client would + check an entire entity list with distance calcs and other checks for aggro, with many clients in a zone and many NPC's this would + add a lot of unecessary overhead. A temporary adjustment on 3/25 was made and upped the check to 6 seconds. + - Now, there is a new methodology to scanning. The client will build a cache list of NPC's within close range as defined in new rule: + RULE_INT(Range, ClientNPCScan, 300) and will also get any NPC that has an aggro range beyond that defined range to use in + the frequent checks for aggro, the result is far less overhead + - Client scanning changes when moving versus not moving, the client will scan aggro every 500 milliseconds while moving, and + 3000 millseconds aggro check when not moving, with a 6000ms re-fetch for close NPC's + - A demo of these changes can be found here: + https://youtu.be/aGroiwLSTVU + +== 03/25/2017 == +Akkadius: [Performance] Reduced CPU footprint in non-combat zones doing constant checks for combat related activities +Akkadius: [Performance] Reduced CPU footprint in cases where a client is checking for aggro excessively every 750 millseconds. This has + been adjusted to 6 seconds per new rule RULE_INT(Aggro, ClientAggroCheckInterval) + - When zones have many players, with many NPC's, this adds up quickly + +== 03/12/2017 == +Akkadius: [Performance] +- Implemented range rules for packets and other functions + RULE_INT ( Range, Say, 135 ) + RULE_INT ( Range, Emote, 135 ) + RULE_INT ( Range, BeginCast, 200) + RULE_INT ( Range, Anims, 135) + RULE_INT ( Range, SpellParticles, 135) + RULE_INT ( Range, DamageMessages, 50) + RULE_INT ( Range, SpellMessages, 75) + RULE_INT ( Range, SongMessages, 75) + RULE_INT ( Range, MobPositionUpdates, 600) + RULE_INT ( Range, CriticalDamage, 80) + + - (Readability) Also cleaned up some formatting in messaging and packets so it is easier to understand what is going on with the code + +== 03/09/2017 == +Uleat: Fixed a few glitches related to bot trading and other affected code + - Added a temporary fail clause for partial stack transfers to prevent client item overwrites + - Return messages no longer repeat the top cursor item when multiple items are pushed there + - Test slot for client returns is now handled appropriately for parent and bag searches + - FindFreeSlotForTradeItem() now begins at the correct bag index on subsequent parent iterations +Uleat: First step of implementing inventory v2.0 + +== 03/08/2017 == +Uleat: Complete rework of the bot trading system + - Equipment slot priority can now be tailored..though, a recompile will be required + - All item validations and slot assignments for trades and returns are now performed before any actual item movements occur + - Failed trade/returned items will now go straight into the client's inventory, just like a normal trade transaction + - A 'green' message appears at the end of each successful trade informing the trader of 'accepted' and 'returned' item counts + - Bots respond to the trader directly now instead of using BotGroupSay() + - Bots will still only allow trades from their owner (currently, too high a risk of exploit and/or malicious activity) + - Partial stack movements (i.e., ammo refills) have been scoped..but, not implemented + - I have not been able to reproduce any 'illegal' weapon combinations with this code + - NOTE: The report of item duplication with bot return items appears to be an inventory desync condition + - I experienced this condition both before and after the rework with RoF+ clients (UF- appears ok) + - The bug lies within the actual client inventory system and not with bot trades + - Please post any issues with this change as they arise + +== 02/27/2017 == +Uleat: Notes on bot movement speed changes: + - Clients (players) appear to be on a different speed scale than other entities (NPCs, etc...) + - The server does not calculate deltas/velocities for moving players..those come the client itself + - GetBotWalkspeed() and GetBotRunspeed() are specific to bot movement calculations + - The class Mob equivilents are not scalared so that a 'client-oriented' value can still be attained + - The value of ~1.786f is derived from the ratio of 1.25f/0.7f (npc speed/client speed) + - Modifying the two speeds like this is a rough guess-timate..but, appears to at least bring the incongruous behavior to acceptable levels + +== 02/26/2017 == +Uleat: Moved bot `npc_spells` entries from '701-712' to 3000 + .. also, added melee types for future expansion +Uleat: Moved bot spell casting chance values into database - this will allow admins to tailor their bots without having to rebuild server code + - Each entry uses a 3-dimensional identifier: [spell type index][class id][stance index] + - [spell type index] is not the SpellType_## bit value..use SpellType_##Index instead + - [class id] values of 1-16 are valid and hold a direct correlation to server-coded player class values + - [stance index] is a direct correlation (0-6) + - the 'conditional fields' are currently predicated on 4 compounded boolean states: + - `pH_value` represents bit '0' + - `pS_value` represents bit '1' + - `pN_value` represents bit '2' + - `pD_value` represents bit '3' + - all other conditional fields are masked based on these 4 predicates + - the full conditional field enumeration is as follows: + - `nHSND_value` - negative Healer/Slower/Nuker/Doter + - `pH_value` - positive Healer + - `pS_value` - positive Slower + - `pHS_value` - positive Healer/Slower + - `pN_value` - positive Nuker + - `pHN_value` - positive Healer/Nuker + - `pSN_value` - positive Slower/Nuker + - `pHSN_value` - positive Healer/Slower/Nuker + - `pD_value` - positive Doter + - `pHD_value` - positive Healer/Doter + - `pSD_value` - positive Slower/Doter + - `pHSD_value` - positive Healer/Slower/Doter + - `pND_value` - positive Nuker/Doter + - `pHND_value` - positive Healer/Nuker/Doter + - `pSND_value` - positive Slower/Nuker/Doter + - `pHSND_value` - positive Healer/Slower/Nuker/Doter + - Single- and mixed-bits fields should be filled-in based on the boolean 'AND' concept + - (i.e., if 'healer' then `pH_value`=x; if 'slower' then `pS_value`=y; if 'healer' AND 'slower' then `pHS_value`=z; ) + - most cases can allow the same value across all fields..but, there are some that shouldn't and this format allows for their discrimination + - Valid `##_value` entries are 0-100..though, the field accepts up to 255... Anything above 100 is clamped to 100 upon loading, however... + - Not all conditions are currently coded and changing a field may not produce any results + - The 'default' database values will be changed and tweaked as bot spell code modifications occur + +== 02/25/2017 == +Uleat: Implemented rule-based node pathing for bots + - This currently applies to out-of-combat following movement and blocked los in-combat movement + - The default is set to 'true' (use node pathing)..so, consider disabling it if cpu use is too high + - If you want to disable node pathing, apply the optional sql '2017_02_25_bots_use_pathing_rule.sql' file located in the utils/sql/git/bots/optional sub-directory. This will apply a 'false' rule..but, it can be changed as desired + - This helps with bot movement..but, there are still issues... +Uleat: Implemented rule-based position update packet with movement timer check for bots + - This currently only applies to out-of-combat movement + - The default is set to 'false' (original behavior) to help save bandwidth (each bot will send an update packet every 1/10th of a second when enabled) + - If you want to enable the position update packet, apply the optional sql '2017_02_25_bots_update_position_with_timer_rule.sql' file located in the utils/sql/git/bots/optional sub-directory. This will apply a 'true' rule..but, it can be changed as desired + - This appears to help with/eliminate rubber banding + +== 02/23/2017 == +** THIS NOTE HAS BEEN SUPERCEDED ON 02/26/2017 ** +Uleat: Moved bot spell casting chance values into database - this will allow admins to tailor their bots without having to rebuild server code + - Each entry uses a 4-dimensional identifier: [spell type index][class index][stance index][conditional index] + - [spell type index] is not the SpellType_## bit value..use SpellType_##Index instead + - [class index] values of 0-15 are valid and determined by subtracting 1 from the actual class value + - [stance index] is a direct correlation (0-6) + - the [conditional index] is currently predicated on 2 compounded boolean states: + - not primary healer/not primary slower: 0 + - primary healer/not primary slower: 1 + - not primary healer/ primary slower: 2 + - primary healer/primary slower: 3 + - Valid `value` entries are 0-100..though, the field accepts up to 255... Anything above 100 is clamped to 100 upon loading, however + - Not all conditions are currently coded and changing a field may not produce any results + - The 'default' database values will be changed and tweaked as bot spell code modifications occur + +== 02/20/2017 == +Uleat: Reworked bard bot spell twisting and updated their spell (song) list +Uleat: Added ability to shift to pre-combat song buffing by selecting a non-pet npc target, eliminating the need to mix all bard buff songs together + +== 2/19/2017 == +Akkadius: Added a fix for limiting the amount of items sold in a stack when the resulting return coin is higher than the supporting struct for returning coin + +== 01/31/2017 == +Uleat: Modifed bot movement behavior in an attempt to 'normalize' it. This is a hack fix and will be revisited at some point. (Probably just need a follow function rather than use movement, when the leader of the follow chain is moving.) + +== 01/26/2017 == +Uleat: Change rogue bot behavior to eliminate twirling combat. They will only get behind the mob if they are not the mob's target or if the mob is feared or fleeing. This may lower rogue bot dps a small fraction..but, is more in-line with realistic game mechanics. + +== 01/17/2017 == +Mackal: Combat Revamp + - This change brings melee combat into line with how combat is done on live. + - This correctly applies the PC damage tables and corrects stacking order of many spells + - Given the scope of what had to be rewritten, it was not feasible to preserve the old combat system. + This means you will likely have to rebalance your server, which sucks, but this is very + accurate so shouldn't require any more changes, at least none that would cause you to have + to rebalance your server again. + - For rebalancing, I would recommend running the optional SQL and tweaking from there. + - To help with rebalancing there is a simulator included at utils/combat-sim. + - You can enter the mitigation or offense values you would like to balance around (#showstats will show you them) + a 1 on the sim is min damage 20 is max. + - Quick recommendations for best ways to improve PC DPS, give them some worn (or AA) SE_DamageModifier and/or SE_MinDamageModifier +== 12/03/2016 == +Uleat: Added hack detection to trade code + - If illegal items are found in trade slots when the 'trade' button is clicked, the trade is cancelled and a message is sent to the offending player + - Future revisions will, at a minimum, log the player as a hacker once the quirks have been worked out + +== 12/01/2016 == +Uleat: Disabled RoF+ clients from augmenting items not in their possessions slots (0-29, 9999, 251-330) to abate an exploit in the current code + +== 10/17/2016 == +Uleat: Moved namespace ItemField from item_instance.h to shareddb.cpp - the only place it is used +Uleat: Separated class Inventory from item_instance files into inventory_profile files +Uleat: Renamed class Inventory to EQEmu::InventoryProfile +Uleat: Renamed enum class InventoryVersion to MobVersion + +== 10/16/2016 == +Uleat: Renamed struct EQEmu::ItemBase to EQEmu::ItemData and class ItemInst to EQEmu::ItemInstance +Uleat: Added class EQEmu::InventorySlot. Re-attached pertinent inventory token references to EQDictionary + +== 10/15/2016 == +Uleat: Changed filenames to facilitate future inventory naming conventions + +== 10/09/2016 == +Noudess: Rogue usage of merchants while utilizing sneak was limited to +temporary items, as the code that checked faction per item sold did not +take into account that rogue was sneaking. Now sneaking rogues can see full +inventory on merchants (well, unless an item requires a + faction value). + +== 09/12/2016 == +Akkadius: Massive overhaul of the update system and EQEmu Server management utility framework + (known as eqemu_update.pl) now known as eqemu_server.pl + - eqemu_server.pl is now a general EQEmu Server management utiltiy framework that can be used + to extend to many purposes. It's main purpose is to simplify server management + - eqemu_server.pl changes: + - Menu has been completely changed, instead of a number based (enter number and hit enter) + you now type commands within the menu (Ex: 'database') + - Handles last mile installation for Windows Servers (See Github Readme) + - Handles last mile installation for Linux Servers (See Github Readme) + - Ubuntu + - Debian + - Fedora + - CentOS + - Now checks for Internet connection before performing web requests + - Database: + - Regular schema updates now happen automatically, if new binaries present updated + database schema changes, script will backup first, auto update database, and continue + world bootup + - Regular bots database schema changes now happen automatically similarily to the above + - Database checks can also be ran manually via the script menu + - CLI Arguments + - Arguments passed to eqemu_server.pl can execute the same name-based operations that + are present in the interactive menu + - Example: "perl eqemu_server.pl opcodes" will download opcodes + - Example: "perl eqemu_server.pl backup_player_tables" will backup and export player tables + - Bots + - Bots can now be automatically setup in Linux or Windows via the 'setup_bots' command + - Windows will auto download binaries and install, along with installing bots db schema + - Linxu will auto compile binaries and install, along with installings bots db schema + - Utility scripts + - Linux now has the following utility scripts for download, available via menu 'utility_scripts' + and via Linux default install: + - server_launcher.pl + - server_start_dev.sh + - server_start.sh + - server_status.sh + - server_stop.sh + - Usage analytics + - eqemu_server.pl now collects usage analytics, this is very helpful for our developers + - Example: We can see how many installs have been performed: + https://github.com/EQEmu/Server#server-installs + - This helps us see how often certain utilities are used as well + - Console Messages + - All script messages have been prefixed with a bracket action Ex: [Update] [Database] [Info] + to be more consistent with our log conventions + - 'New Server' Utility + - Running 'new_server' from the main menu or 'perl eqemu_server.pl new_server' while in + a completely new folder with just the script present, will allow a server operator + to initiate a full clean PEQ install in that folder. Pulling down all assets and + installing a PEQ database with the name the server operator gives the prompts in the + script + +== 09/10/2016 == +noudess: Task system experience based on a % of a level did not take into +account the hell levels rule. Now it does. + +== 09/04/2016 (Changes over past few months) == +Akkadius: Fixed an issue where clients would crash with health marquee's +Akkadius: Fixed issues with NPC's "ghosting" when they path +Akkadius: Overhauled worldserver logging +Akkadius: Pets now don't actually spawn until the player has fully entered the zone (Live-like) +demonstar/KLS: Adjusted some background workings on how spell buff tics are synced with the client +Uleat: Optimizations to map loading and zone times +Uleat/Akkadius: Fixed bandolier exploit where you could equip a 2H and Shield +mackal: Re-worked spell re-use timer logic +mackal: Source optimizations all over, crash fixes +mackal: Fixed some issues with illusions on zoning +mackal: Fixed some client DOT stacking bugs +mackal: Invis will now break on AA spell casts and item cast +mackal: Changed how Loot response code works +mackal: Implemented 3 additional spell gems with (Mnemonic Retention) +mackal: Instant spells now have instrument mods +mackal: Rate limit character saves +mackal: Made it so items no longer do TGB (Live-like) Rule implemented to disable +mackal: Set pet buffs limit to 30 + +== 09/03/2016 == +Uleat: Changed 'Bind Wound' behavior to match the best references that I could find for post-2004 era. + Note: If you wish to retain the old method, source in the optional '2016_09_03_old_bind_wound_rule.sql' script file. + +== 08/27/2016 == +Kinglykrab: Added optional IP-based account exemptions. + - To use this system simply set World:EnableIPExemptions to true and create an entry in the ip_exemptions table. + - Example: exemption_ip of IP 192.168.1.4 in ip_exemptions with exemption_amount of 1 will allow only 1 account to login from IP 192.168.1.4. + - Note: If there is no exemption, the amount of accounts logged in from a singular IP will default to World:MaxClientsPerIP + +== 08/23/2016 == +noudess: Force mobs on a depop @ end pathgrid to still do this on idle zones. +This makes them be more random after a zone is idle, rather than always showing +up at start point when 1st person logs into an idle zone. Much more like live. +I dion't think this will be much of a performance problem. Once they path and +depop, no mkore cpu usage. + +== 08/14/2016 == +mackal: Implement Linked Spell Reuse Timers + - For whatever reason this is a bit unfriendly, but that's how it is on live. + - Titanium is especially unfriendly with large differences in reuse times (ex higher canni and the first 4) + - Unsure when this went live for spells, but canni was at least linked at OoW launch + +== 08/13/2016 == +Kinglykrab: Implemented optional avoidance cap rules. + - Serves to eliminate God-like characters on custom servers with high item stats + - Rule Names: + - Character:EnableAvoidanceCap (default is false) + - Character:AvoidanceCap (default is 750, beyond 1,000 seems to make characters dodge all attacks) + +== 08/02/2016 == +Uleat: Changed 'SendZoneSpawnsBulk' behavior to use near/far criteria (live-like) when sending packets. + - Zone-to-Zone client loading will see a small decrease in time (less than 10~15%) + - World-to-Zone client loading appears to greatly benefit from this (tested 'devastation' - pre-change: ~22 seconds, post-change: 12~15 seconds) + - This change does not affect the final spawning of mobs in the client + +== 07/31/2016 == +mackal: Implement more spell gems! + - There are a few things still left to due like make dealing with losing gems nice (reset AAs, going to an older client etc) + - Sadly SoF disc release doesn't support gem 10 like one might expect :( + - So changed clients: + - SoD = 10 + - UF = 12 + - RoF/RoF2 = 12. I know the UI supports 16, but the client does not and can cause client crashes + - The quest APIs assume you pass a valid spell gem ... + +== 07/28/2016 == +Uleat: Implemented zone memory-mapped file usage + - Zone map files are converted to pre-loaded binary files, bypassing the (sometimes) time-consuming raw data transform process + - There are three ways to convert files: + -- Do nothing! The zone bootup process will check for a mmf file and load it, if found, or create it after the 'normal' transform process is complete + -- Use the command line option: zone convert_map .map (for singular conversions) + -- Drop the 'convert_maps_to_mmfs.pl' into your server directory and execute it for a batch conversion + -- Note: Any zone maps not pre-converted will be processed once a zone is booted up that does not have one + - To enable this feature, you must have the 'USE_MAP_MMFS' option checked in cmake and have built binaries on that + - To disable this feature, or if you encouter problems, disable the 'USE_MAP_MMFS' option and rebuild your binaries + - This feature will test the validity of your zlib library. If you get errors/crashes upon conversion, then your zlib1.dll is most likely suspect (check our forum for solutions) + +== 07/25/2016 == +mackal: Fix up the SpellBuff struct + - THERE MAYBE BUGS + - there shouldn't though, most of the hackery was from badly named fields causing confusion + +== 07/09/2016 == +Uleat: Important fix for mob pathing + - This should fix failed pathing issues (and high cpu usage for zone.exe) for mobs in affect zones + - Changed variable 'gridno' type from int16 to int32 to reflect actual return value of fetch (values do exceed 32767 aka int16.max) + - Precision loss from int32 to int16 conversion was causing grid id to be changed to quest controlled movement in cases where (gridno & 0x8000 == true) + +== 06/28/2016 == +Noudess: Resurrection effects now block certain buffs like on live. +Noudess: Added message about why spells are blocked (rule based) +Noudess: Added new rule: Client:UseLiveBlockedMessage +Uleat: Fix for bot inventory save failure involving items with unlimited charges + +== 06/13/2016 == +Noudess: Changes personal faction earned min/max to -2000/2000 from -3000/1200 + +== 06/06/2016 == +Uleat: Reworked EQEmuDictionary to use class LookupEntry + +== 06/01/2016 == +Uleat: Implemented EQEmu::TintProfile +Uleat: Implemented EQEmu::TextureProfile + +== 05/31/2016 == +Uleat: Converted enumeration MaterialSlots to EQEmu::textures::TextureSlot + +== 05/28/2016 == +Uleat: Merged client_version and inventory_version into emu_versions files + +== 05/27/2016 == +Uleat: Renamed EQEmu::Item_Struct to EQEmu::ItemBase (and appropriate files) to coincide with new inventory naming conventions + +== 05/25/2016 == +Uleat: Renamed and moved enumeration SkillUseTypes to EQEmu::skill::SkillType - added class EQEmu::SkillProfile, though not implemented at this time +Uleat: Some more work on eq_dictionary + +== 05/21/2016 == +Uleat: Moved struct Item_Struct into namespace EQEmu along with associated enumerations - enumerations into namespace EQEmu::item (run shared_memory) +Uleat: Fixed a few possible crash points in linux builds associated with augments/ornamentations + +== 05/18/2016 == +Uleat: Changed client 'constants' files to 'limits' + +== 05/10/2016 == +Uleat: Converted client translators' 'SerializeItem()' to recursive, single buffer methodology. Titanium SerializeItem() now adds a null term between parent items instead of the invoking function +Uleat: Converted server 'BulkSendInventoryItems()' to use single buffer methodology +Uleat: Added 'ItemInst::Serialize()' overload to make use of the above single buffer methodology + +== 05/08/2016 == +Uleat: Re-coded Titanium client translator 'SerializeItem()' to use coded property assignments over file enumerated ones + +== 04/22/2016 == +Uleat: Reworked ClientVersion into namespace EQEmu; Added InventoryVersion +Uleat: Delinked current inventory slot enumeration and constants from EQEmu::constants and global definition (inv2 pre-work) + +== 04/19/2016 == +Uleat: Changed the recent EQEmu rework to eliminate the nested class design (possible cause of VS2015 update crashes - unverified) +Uleat: Some more inv2 convergence work + +== 04/15/2016 == +Uleat: Reworked EQDictionary into namespace EQEmu + +== 04/08/2016 == +Uleat: Added Heal Rotation HOTs (Heal Override Targets) that can be set for proactive healing (default HR behavior is reactive) +Uleat: Added the ability to save/load/delete Heal Rotations based on targeted member - load is automatic when ^hrcreate is used on a bot that has a saved HR entry + +== 04/07/2016 == +Uleat: Rework of eq_dictionary to facilitate inventory work + +== 04/05/2016 == +Uleat: Moved database query code out of bot.cpp and into the new BotDatabase class + +== 03/25/2016 == +Uleat: Fix for heal rotation 'Stack Overflow' error +Kayen: Defensive procs will now only proc once per attack round (instead of every attack chance). + Live like modifier added that decreases defensive proc chance if you are higher level then your attacker. + +== 03/24/2016 == +Kayen: Fix for AE taunt to use correct range and hate modifier. + Fix for spell effect version of taunt to use correct range. +Uleat: Activation of new 'Bots' command system + - You will need to re-run cmake to capture the file additions and then re-compile your server binaries + - You will also need to manually run eqemu_update.pl and select the bots update option - you should have 2 pending updates: 9001 & 9002 + - The new command system is accessed with the '^' character - start with '^help' and see where that takes you + - More information can be found on the eqemu forums + == 03/05/2016 == mackal: Implement extra bind points (secondary recall) For SE_Gate, base2 is which bind to use (starting at 1) @@ -31,7 +475,7 @@ Kinglykrab: Modified #flag so you can refresh your target's account status (GM s - Just target the person whose flag you want to refresh and type #flag. Uleat: Added itemlink functionality to the #summonitem command. Current use is limited to extracting the item id from the link. - Invoking by item link '#summonitem Arrow' produces the same result as by item id '#summonitem 8005' - + == 01/12/2016 == Athrogate: Adding ClearCompassMark() to Lua. - Lua didn't have ClearCompassMark(). Perl already had this. @@ -61,7 +505,7 @@ Kinglykrab: Added GetInstanceTimer() to Perl and Lua. - Note: If you do not provide an instance id in the method it defaults to instance id 0 and returns 0 for time remaining. - Added UpdateZoneHeader(type, value) to Perl and Lua. - Note: UpdateZoneHeader allows you to manipulate fog color, fog density, and many other zone header settings on the fly in Perl and Lua. - + == 12/21/2015 == Natedog: Updated item table fields and added a few missing fields for evolving items -DO NOT implement Heirloom items till the inventory code is fixed to allow placing NO DROP @@ -70,7 +514,7 @@ Natedog: Updated item table fields and added a few missing fields for evolving i 100% 2HSlashing (Max 50) - can only increase 2hslash by 50 MAX! (item field located though) Kinglykrab: Added GetMeleeMitigation() for NPCs and Clients in Perl and Lua. - This allows you to check total item, spell, and AA melee mitigation contribution. - + == 12/19/2015 == Kinglykrab: Added many methods to Perl and Lua, list below: - SeeInvisible() @@ -92,7 +536,7 @@ Kinglykrab: Added many methods to Perl and Lua, list below: - HasPet() - IsSilenced() - IsAmnesiad() - + == 12/16/2015 == Noudess: Repaired issue with Bind Wounds on someone else. Message was not coming out on client (hold still) and a bind wounds on someone already binding their wounds would interrupt their bind and make them stand. Also removed some duplicate messaging. @@ -101,7 +545,7 @@ Kinglykrab: Added IsBlind() and IsFeared() functionality to Perl and Lua. - Note: Both methods are Mob methods and may be used on NPCs or PCs. Natedog: Added Discipline functions, UpdateInstanceTimer function, and UnmemSpellBySpellID to lua and perl -Examples: http://wiki.eqemulator.org/i?M=Pastebin&Paste=BJ0ygmNM - + == 12/07/2015 == Uleat: Command aliases are no longer handled through the command_add() function. - To add a command alias, edit the database table `command_settings` - here, you will find three columns: `command`, `access` and `aliases` @@ -114,7 +558,7 @@ Uleat: Command aliases are no longer handled through the command_add() function. - If you need need more name space for aliases, simply edit the `command_settings` table and increase the size of the `aliases` column - The old `commands` table has been renamed to `commands_old` for reference - All of the current 'standard' commands have been added to the new `command_settings` table - + - YOU WILL NEED TO VERIFY/IMPORT OLD ACCESS VALUES AS THIS CHANGE REVERTS ALL COMMAND ACCESS VALUES TO THEIR PEQDB DEFAULTS == 11/30/2015 == @@ -136,7 +580,7 @@ Akkadius: Performance boost (exponential) - Adjusted default idle cast check tim - Database version 9089 will take care of this update automatically only if you used the default values - The CPU cost of NPC's checking the entire entity list to cast beneficial spells (Heals/Buffs) becomes extremely high when higher NPC count zones exist (Based off of process profiling) - Distance checks for every single NPC to every single other NPC who are casting beneficial spells occur every .5 - 2 seconds unless npc_spells dictates other values, which most of the time it does not - - Zones that once fluctuated from 1-8% CPU with no activity (Idle but players present) now idle at .5% based on my testings due + - Zones that once fluctuated from 1-8% CPU with no activity (Idle but players present) now idle at .5% based on my testings due to this change in conjunction with the past few performance commits, these are zones that have 600-800 NPC's in them - These values normally are overidden by the spells table (npc_spells), fields (idle_no_sp_recast_min, idle_no_sp_recast_max) @@ -144,7 +588,7 @@ Akkadius: Performance boost (exponential) - Adjusted default idle cast check tim Akkadius: Made many performance optimizing oriented code changes in the source - Added Rate limit the rate in which signals are processed for NPC's (.5 seconds instead of .01 seconds) Akkadius: Added Perl Export Settings which should heavily reduce the Perl footprint - - Normally when any sub EVENT_ gets triggered, all kinds of variables have to get exported every single time an event is triggered and + - Normally when any sub EVENT_ gets triggered, all kinds of variables have to get exported every single time an event is triggered and this can make Perl very slow when events are triggered constantly - The two most taxing variable exports are the item variables ($itemcount{} $hasitem{} $oncursor{}) and qglobals ($qglobals{}) - qglobals can pose to be an issue quickly when global qglobals build up, it is highly recommend to use the GetGlobal() and SetGlobal() @@ -172,7 +616,7 @@ Akkadius: Added Perl Export Settings which should heavily reduce the Perl footpr | 4 | EVENT_ATTACK | 0 | 1 | 1 | 0 | 1 | | 5 | EVENT_COMBAT | 1 | 1 | 1 | 0 | 1 | +----------+-----------------------------------------+-----------------+------------+-------------+-------------+--------------+ - + - If a change is made to this table while the server is live and running, you can hot reload all zone process settings via: #reloadperlexportsettings - For those who wonder what "exports" are, they are reference to variables that are made available at runtime of the sub event, such as: @@ -181,7 +625,7 @@ Akkadius: Added Perl Export Settings which should heavily reduce the Perl footpr (export_zone) : $zoneid, $instanceid, $zoneln etc. https://github.com/EQEmu/Server/blob/master/zone/embparser.cpp#L1083 (export_mob) : $x, $y, $z, $h, $hpratio etc. https://github.com/EQEmu/Server/blob/master/zone/embparser.cpp#L1032 (export_event) : (event specific) IE: EVENT_SAY ($text) https://github.com/EQEmu/Server/blob/master/zone/embparser.cpp#L1141 - + == 10/16/2015 == Uleat: Added command '#bot clearfollowdistance [ | spawned | all ]' to coincide with the activation of the load/save feature for follow_distance @@ -213,7 +657,7 @@ rules: commands: '#invsnapshot' - Takes a snapshot of target client's inventory (feature active or inactive) '#clearinvsnapshots [use rule]' - Clears snapshot entries based on bool argument ([true] - honors the 'InvSnapshotHistoryD' rule, [false] - erases all) - + == 08/02/2015 == Shendare: VS2013 query StringFormat glitches when "%f" is passed for the int GetRunSpeed(). Shendare: In CreateNewNPCCommand(), the npc_type_id and spawngroupid are created in the database, but never set in the spawn class, so later it can't delete them with #npcspawn remove or #npcspawn delete. @@ -264,10 +708,10 @@ mackal: Reworked the activated avoidace skills (riposte, dodge, etc) based on de Also riposte immunity from the increase riposte chance spell effect. == 7/2/2015 == -KLS/Demonstar55: AA system has been rewritten fixing a ton of bugs and extending functionality while making it easier to create new AA points. -KLS/Demonstar55: New tables are needed and so older data will need to be migrated to the new system. -KLS/Demonstar55: The SQL saves the old aa points spent/avail/character_alt_abilities data if any server ops want to do something different than PEQ did with it. -KLS/Demonstar55: Will try to get a wiki entry written up next week some time explaining the system but it's really not hard to follow the db tables in the meantime. +KLS/mackal: AA system has been rewritten fixing a ton of bugs and extending functionality while making it easier to create new AA points. +KLS/mackal: New tables are needed and so older data will need to be migrated to the new system. +KLS/mackal: The SQL saves the old aa points spent/avail/character_alt_abilities data if any server ops want to do something different than PEQ did with it. +KLS/mackal: Will try to get a wiki entry written up next week some time explaining the system but it's really not hard to follow the db tables in the meantime. == 7/1/2015 == Akkadius: Fix an issue where emote messages would overflow the buffer of 256 by increasing the size and changing some of the initialization @@ -297,7 +741,7 @@ Akkadius: Added DB ver 9082 with update to add npc_types texture columns if tabl Uleat: Added null-term declaration for character names in ENCODE(OP_CharInfo) - where appropriate == 05/20/2015 == -demonstar55: Bard instrument mods should be more consistent with live. Zoning will keep instrument mod for long duration buffs (selo's) +mackal: Bard instrument mods should be more consistent with live. Zoning will keep instrument mod for long duration buffs (selo's) Still need to have procs/doom effects to inherit the instrument mods from their source buff/whatever == 05/18/2015 == @@ -307,7 +751,7 @@ KLS: Changed how fishing locates water to hopefully be a bit more accurate at th Uleat: Added check to EntityList::CheckSpawnQueue() to bypass dereference if returned iterator is npc_list.end() - should fix the debug assertion failure crash == 04/30/2015 == -demonstar55: Implement mob and client melee push +mackal: Implement mob and client melee push You can set Combat:MeleePush to false to turn off or change Combat:MeleePushChance to increase the chance an NPC can be pushed PCs are always pushed, need to do more testing to verify. @@ -361,7 +805,7 @@ Uleat: Fix for RoF+ clients showing active 'Return Home' button when action is n Noudess: Starting erudites that were supposed to start in paineel were landing in erudin on Titanium. Fixed to be paineel. == 02/20/2015 == -demonstar55: Implement claims for RoF/RoF2 (should no longer crash the client!) +mackal: Implement claims for RoF/RoF2 (should no longer crash the client!) - fixed bugs related to claims for the rest of the clients (woo infinite loops) == 02/18/2015 == @@ -380,7 +824,7 @@ Notes: == 02/16/2015 == Trevius: (RoF2) Bazaar Trading (Buying/Selling) is now fully functional. Bazaar (/bazaar) search is not yet functional. -demonstar55: (RoF2) Send the bard focus effects, note custom servers will need to fix their items, server side we still use the old system, but RoF2 wasn't showing anything with not sending focus, so send them +mackal: (RoF2) Send the bard focus effects, note custom servers will need to fix their items, server side we still use the old system, but RoF2 wasn't showing anything with not sending focus, so send them == 02/14/2015 == Trevius: (RoF2) Bazaar is now partially functional. RoF2 clients can start/end trader mode and other clients can purchase from them. No other functionality yet. @@ -430,7 +874,7 @@ Akkadius: Implement Packet logs with dumps See: http://wiki.eqemulator.org/p?Logging_System_Overhaul#packet-logging-levels == 02/01/2015 == -demonstar55: Add quest debugging to lua +mackal: Add quest debugging to lua eq.debug("Test debug level implicit 1") eq.debug("Test debug level explicit 1", 1) eq.debug("Test debug level explicit 2", 2) @@ -623,7 +1067,7 @@ Trevius: Finished lining up the RoF2 Player Profile Struct. Zone times are now Trevius: Fixed zoning after death for RoF2. == 12/17/2014 == -demonstar55: Use vectors for route stuff, should be more CPU cache friendly so faster +mackal: Use vectors for route stuff, should be more CPU cache friendly so faster Secrets: EQStream changes as recommended by a community member in private. == 12/15/2014 == @@ -633,7 +1077,7 @@ Trevius: Player Corpses now saved attuned settings for Items. Required SQL: utils/sql/git/required/2014_12_15_multiple_table_updates.sql == 12/13/2014 == -demonstar55: Fix guild rank spam on zone (needed to be in OP_PP). +mackal: Fix guild rank spam on zone (needed to be in OP_PP). Trevius: (RoF+) Implemented Armor Ornamentation using Hero's Forge Armor Models. To use, create an ornamentation augment and set the herosforgemodel field in the items table. Trevius: (RoF+) Added command #heromodel (#hm for short) - Usage: #heromodel [hero forge model] [ [slot] ] (example: #heromodel 63) @@ -641,11 +1085,11 @@ Be sure to run this or there will be item loss: Required SQL: utils/sql/git/required/2014_12_13_inventory_table_update.sql == 12/12/2014 == -demonstar55: Add special attack 42, Ignore Root Aggro Rules. This allows you to root a mob and have them still use the normal aggro rules (so they will attack the one with most hate, not closest) +mackal: Add special attack 42, Ignore Root Aggro Rules. This allows you to root a mob and have them still use the normal aggro rules (so they will attack the one with most hate, not closest) == 12/09/2014 == Trevius: (RoF+) Implemented Hero's Forge Armor Models for Items. To use, set herosforgemodel field in the item table to a model number such as 63 (for example). -demonstar55: SoF+ swarm pets will no longer be F8able (without a hack!) +mackal: SoF+ swarm pets will no longer be F8able (without a hack!) == 12/08/2014 == Secrets: Added a feature that allows an EQ client to log in directly to World without having to enter the LoginServer, provided the 'password' field is set in WorldServer. @@ -691,10 +1135,10 @@ Trevius: Mercenaries now Dismiss, Suspend, Unsuspend, and Die correctly. Trevius: Mercenaries can now zone once again. == 11/17/2014 == -demonstar55: Correct OP_AugmentInfo reply. This fixes RoF display issue with Adventurer's Stone. Still issues with UF/SoF/SoD though. +mackal: Correct OP_AugmentInfo reply. This fixes RoF display issue with Adventurer's Stone. Still issues with UF/SoF/SoD though. == 11/16/2014 == -demonstar55: fix size issue with ControlBoat_Struct and exploit fix in OP_BoardBoat +mackal: fix size issue with ControlBoat_Struct and exploit fix in OP_BoardBoat Akkadius: Implemented Automatic Database update and versioning system Akkadius: Created database revision define, this is located in version.h in common #define CURRENT_BINARY_DATABASE_VERSION 9057 @@ -771,12 +1215,12 @@ Optional SQL: utils/sql/git/optional/2014_11_15_SwarmPetTargetLock.sql == 11/14/2014 == Secrets: Identified object size and solidtype as flags. Exported them as functions to Perl. -demonstar55: Don't use the hack for charms that doesn't work on RoF -demonstar55: UF too -demonstar55: Tit -demonstar55: SoF -demonstar55: SoD -demonstar55: 62 (untested) +mackal: Don't use the hack for charms that doesn't work on RoF +mackal: UF too +mackal: Tit +mackal: SoF +mackal: SoD +mackal: 62 (untested) == 11/13/2014 == Kayen: Implemented target type (44) 'Beams' (which projects an AE infront of caster with a specified length and width). @@ -802,7 +1246,7 @@ JJ: Implement new Live-like faction adjustment message using rule Client:UseLive Optional SQL: utils/sql/git/optional/2014_11_09_LiveFactionMessages.sql == 11/06/2014 == -demonstar55: Tracking default sort will now be correct order +mackal: Tracking default sort will now be correct order Trevius: Fixed dynamic merchant list loading. Allows any merchant to be used in any zone. == 11/03/2014 == @@ -826,17 +1270,17 @@ Uleat: Added Client::InterrogateInventory(). Can be invoked by #interrogateinv a Uleat: Fix for stacking items in a world object..added a new command option: #peekinv world - will show world container contents, if one is in use by target. == 10/20/2014 == -demonstar55: Inspect Buffs rank 1 will now show NPC buffs in target window (SoD+) +mackal: Inspect Buffs rank 1 will now show NPC buffs in target window (SoD+) == 10/19/2014 == Uleat: Updated command #peekinv to display item links properly in RoF clients -demonstar55: Group Mentoring in raids -demonstar55: Inspect Buffs (text only version) works in raid groups -demonstar55: Make use of the Inspect Buffs op/packet. 62 SOL until someone finds its op +mackal: Group Mentoring in raids +mackal: Inspect Buffs (text only version) works in raid groups +mackal: Make use of the Inspect Buffs op/packet. 62 SOL until someone finds its op == 10/18/2014== -demonstar55: Implement group mentor, sharing leadership exp (SoF+ only) -demonstar55: Add gaining of group leadership while in raids +mackal: Implement group mentor, sharing leadership exp (SoF+ only) +mackal: Add gaining of group leadership while in raids == 10/16/2014 == Uleat: Fixed the auto-conversion view naming error and renamed the views in the script files. Added a fix sql for databases that auto-converted. @@ -849,7 +1293,7 @@ Notes: I modifed the behavior of both load and drop bots to fail on the first op a few altered tables back to their original state - as of the date in the file. == 10/13/2014 == -demonstar55: Partially implement leadership and raids +mackal: Partially implement leadership and raids Currently working: client side only effects and stat bonuses. Not working: Mark NPC, and other stuff that need extra server side support Currently only UF tested (Tit and 62 may just work, others need packet work) @@ -858,7 +1302,7 @@ demonstar55: Partially implement leadership and raids Akkadius: Fix for LDON Character Stat load == 10/11/2014 == -demonstar55: Implement Raid MOTD for UF +mackal: Implement Raid MOTD for UF Don't forget 2014_10_11_RaidMOTD.sql! == 10/09/2014 == @@ -871,7 +1315,7 @@ previously and/or manually changed code, or just have a need for it to re-run, c ** This will only work if you haven't deleted your `character_old` table ** == 10/07/2014 == -demonstar55: Identified tutorial flag in all charcreate packets, reworked logic to correctly set homes binds +mackal: Identified tutorial flag in all charcreate packets, reworked logic to correctly set homes binds == 10/05/2014 == Uleat: Added Server<->Corpse slot translators needed for re-enumeration (inactive until phased in) @@ -889,13 +1333,13 @@ Uleat: First round of Ti/6.2 translators added - needed for re-enumeration == 10/01/2014 == Kayen: Exported to PERL $client->SendColoredText(color, msg) -demonstar55: Exported SendColoredText to lua +mackal: Exported SendColoredText to lua == 09/30/2014 == Uleat: Implemented click-casting from bag slots for clients that natively support it (RoF) == 09/28/2014 == -demonstar55: Add support for post June 18, 2014 Hundred Hands Effect spells (they changed the formula and stuff) +mackal: Add support for post June 18, 2014 Hundred Hands Effect spells (they changed the formula and stuff) set Spells:Jun182014HundredHandsRevamp to true if you're using a spell file from June 18, 2014+ == 09/27/2014 == @@ -904,15 +1348,15 @@ Note: identifier is the stat field in spells_new, slot is used for certain effec Example $mob->GetSpellStat(121, "range"); //Returns spell range Example $mob->GetSpellStat(121, "effectid", 1); //Returns the the value of effectid1 This will allow you to pull almost all the data for any spell in quest files. -demonstar55: Move the client's SetAttackTimer to the end of Client::CalcBonuses to keep the haste in sync -demonstar55: Correct haste/slow "stacking" rules -demonstar55: Correct SE_AttackSpeed4 to respect unslowable -demonstar55: Make the haste be between 1-225 like the client (<100 = slow, >100 = haste) to ... -demonstar55: Correct Hundred Hands effect and use formula provided by devs +mackal: Move the client's SetAttackTimer to the end of Client::CalcBonuses to keep the haste in sync +mackal: Correct haste/slow "stacking" rules +mackal: Correct SE_AttackSpeed4 to respect unslowable +mackal: Make the haste be between 1-225 like the client (<100 = slow, >100 = haste) to ... +mackal: Correct Hundred Hands effect and use formula provided by devs == 09/24/2014 == Uleat: Re-ordered server opcodes and handlers to give them some predictability of location (I need this for the inventory re-enumeration.) -demonstar55: Added helper function bool EQEmu::IsTradeskill(uint32 skill) +mackal: Added helper function bool EQEmu::IsTradeskill(uint32 skill) == 09/23/2014 == Kayen: Spell recourse effects will now be applied AFTER the base spells effects have been applied (consistent with live). @@ -1021,46 +1465,46 @@ Akkadius: Player Profile Blob to Database Conversion ORDER BY DATA DESC; == 09/20/2014 == -demonstar55: Fix crash in SendEnterWorld on illegally long names -demonstar55: The client only lets you enter 15 characters for your name (UF at least) -demonstar55: Add rule Spells:SHDProcIDOffByOne for pre-UF spell file, set to true, UF+ set to false +mackal: Fix crash in SendEnterWorld on illegally long names +mackal: The client only lets you enter 15 characters for your name (UF at least) +mackal: Add rule Spells:SHDProcIDOffByOne for pre-UF spell file, set to true, UF+ set to false KLS: #suspend and #ban now have required messages to record the reason for the ban/suspension. == 09/19/2014 == -demonstar55: Added Client::Tell_StringID (used in tell queue messages) -demonstar55: Tell queues (and offline) messages now show correctly -demonstar55: Fix starting with capital check +mackal: Added Client::Tell_StringID (used in tell queue messages) +mackal: Tell queues (and offline) messages now show correctly +mackal: Fix starting with capital check == 09/18/2014== -demonstar55: Implement tell queues +mackal: Implement tell queues Currently set to a limit of 20 by default (World:TellQueueSize) I was unable to hit the limit on live though (100+) The required SQL nukes the old tell queue table, which may or may not be in your DB Optional SQL adds the rule to the DB to allow easy of change Note: this does not play well with multiple sessions with the same name on (crash and relog and have multiple sessions) but normal tells don't play well either == 09/16/2014 == -demonstar55: Implement spell formula 137 (BER AA Desperation) +mackal: Implement spell formula 137 (BER AA Desperation) Uleat (NateDog): Fix for LoadBuffs() crash when a spell with a non-persistent Illusion effect was loaded. -demonstar55: Fix some effect calcs + implement more (derived from the client) +mackal: Fix some effect calcs + implement more (derived from the client) == 09/15/2014 == Kayen: Nimbus effects will now be reapplied after zoning and will be removed when associated buff fades. == 09/13/2014 == -demonstar55: Fix rogues not having Thieves' Cant +mackal: Fix rogues not having Thieves' Cant == 09/09/2014 == -demonstar55: Incrase Mob kick/bash timer by 3 +mackal: Incrase Mob kick/bash timer by 3 see: http://www.eqemulator.org/forums/showthread.php?t=38734 -demonstar55: Fix slow effect on NPC special attack reuse timers +mackal: Fix slow effect on NPC special attack reuse timers see: http://www.eqemulator.org/forums/showthread.php?t=38734 -demonstar55: Slow fixes to bots! -demonstar55: Revamped how NPC attack rate is set +mackal: Slow fixes to bots! +mackal: Revamped how NPC attack rate is set SQL: 2014_09_09_attack_delay.sql -demonstar55: Added attackdelay to #npcedit +mackal: Added attackdelay to #npcedit == 09/08/2014 == -demonstar55: Fix slow calc +mackal: Fix slow calc see: http://www.eqemulator.org/forums/showthread.php?t=38734 == 09/07/2014 == @@ -1071,18 +1515,18 @@ Uleat: Tweaked 'Smart' trading code to return main slots before sub slots in sta == 09/05/2014 == Uleat: Fix for cursor item loss when zoning. (Thanks to the other devs who traced and fixed the 'macro' issue!) -demonstar55: Fix size getting nuked with lua's SendIllusionPacket +mackal: Fix size getting nuked with lua's SendIllusionPacket == 09/03/2014 == Secrets: Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor. -demonstar55: Added work around command to show numhits on your buffs (#shownumhits) +mackal: Added work around command to show numhits on your buffs (#shownumhits) Uleat: Fix for timer issue introduced by Zone::ShutDown() fix. == 09/02/2014 == Secrets: Identified OP_GuildPromote for RoF clients. Secrets: Fixed promotion, demotion, transferring a leader and displaying of client ranks in the Rain of Fear client. The rain of fear client, as such, will only have 3 ranks like the other clients, but supports a theoretical 8 ranks later. Secrets/Akkadius: Fixed an issue involving character name lookup in the new DB code. -demonstar55: crash fix checking DivineAura in hate_list.cpp +mackal: crash fix checking DivineAura in hate_list.cpp Secrets: Reverted some code that got in the main branch that shouldn't have gotten there. Uleat: Changed #loc to report the same precision as /loc for Cartesians @@ -1093,7 +1537,7 @@ KLS: Fixed a few quest related inconsistencies. KLS: Added Lua EntityList::ChannelMessage(from, type, msg, language) == 08/30/2014 == -demonstar55: (noudess) Merchants should be more descriptive of why they don't sell to you +mackal: (noudess) Merchants should be more descriptive of why they don't sell to you == 08/26/2014 == Uleat: Implemented 'Smart' Player Trade transfers. Trades are processed by containers, stackables and then all remaining. QueryServ logs have been updated to match these transactions. @@ -1471,7 +1915,7 @@ Optional SQL: utils/sql/git/optional/2014_04_03_SpellProjectileRules.sql Note: The rules in this SQL are for setting the item id for the graphic used by the projectile on different clients. == 04/01/2014 == -demonstar55: Implemented ability for a merchant to open and close shop. +mackal: Implemented ability for a merchant to open and close shop. Lua quest functions: e.self:MerchantOpenShop() and e.self:MerchantCloseShop() GM Commands: #merchant_open_shop (short: #open_shop) and #merchant_close_shop (short: #close_shop) default to status 100, just in case you need to force the merchants status @@ -1537,7 +1981,7 @@ Kayen: Revision to lull/harmony/pacification code to be consistent with live bas which if 'resisted' will cause the caster to gain aggro. == 03/05/2014 == -demonstar55: Corrected rogue's evade to be single target +mackal: Corrected rogue's evade to be single target sorvani: fixed crash issue 119 == 03/04/2014 == @@ -1552,7 +1996,7 @@ Kayen: Revision to root code to be consistent with live based on extensive perso Optional SQL: utils/sql/git/optional/2014_03_04_RootRule.sql == 03/03/2014 == -demonstar55: Implemented deadly strikes and gave rogues higher innate throwing crit chance +mackal: Implemented deadly strikes and gave rogues higher innate throwing crit chance New rules: Combat:RogueCritThrowingChance, Combat:RogueDeadlyStrikeChance, Combat:RogueDeadlyStrikeMod Defaults should give fairly close to live results @@ -1564,7 +2008,7 @@ Kayen: Revision to charm code to be consistent with live based on extensive pers Optional SQL: utils/sql/git/optional/2014_03_02_CharmRules.sql -demonstar55: Melee Crits, HoTs, DoTs messages should now be filtered correctly on all clients. +mackal: Melee Crits, HoTs, DoTs messages should now be filtered correctly on all clients. Clients that also support seeing others DoTs will now see them if they don't filter them note: some newer clients have a 'mine only' option for HoTs but it functions the same as show @@ -1616,7 +2060,7 @@ Sorvani: Renamed the instance_lockout and instance_lockout_player tables to inst Required SQL: utils/sql/git/2014_02_13_Rename_instance_lockout_tables.sql == 02/10/2014 == -demonstar55 (Secrets): Re-wrote the entity list to be a std::map. This should be used for direct entityID lookups and is noticably faster performance-wise. Also should result in less nil pointers potentially. +mackal (Secrets): Re-wrote the entity list to be a std::map. This should be used for direct entityID lookups and is noticably faster performance-wise. Also should result in less nil pointers potentially. Secrets: Fixed a crash issue that could occur on #repop related to quest timers. Kayen: Divine Arbiration and other similar spell effects will now utilize a spell range check. Kayen: Revised how heal amount is calculated to properly incorporate all current focus effects/bonuses. @@ -1647,14 +2091,14 @@ Kayen: Implemented SE_FfLimitUseType (focus limit to numhits type) == 01/20/2014 == cavedude: Live-Like weather system (Thanks to robregen for figuring it out!) -demonstar55: Implemented not_extendable spell flag -demonstar55: Moved Spell Casting Reinforcement to DB -demonstar55: Moved Mez Mastery to DB +mackal: Implemented not_extendable spell flag +mackal: Moved Spell Casting Reinforcement to DB +mackal: Moved Mez Mastery to DB Kayen: Complete revision of the numhits systems to utilize 'numhits type' field in spell file. == 01/18/2014 == sorvani: Implemented for Lua eq.get_characters_in_instance(uint16 instance_id), return a Lua HashTable -demonstar55: NPCs will now cast their charms. +mackal: NPCs will now cast their charms. == 01/13/2014 == Kayen: Numerous minor fixes to spell effects. @@ -1674,19 +2118,19 @@ Kayen: Implemented SE_LimitRace (Limits to spells cast by a certain race) Kayen: Implemented SE_FcMute (silences casting of spells that contain specific spell effects) ie silence only heals == 01/09/2014 == -demonstar55: Add pet size preservation like live (zone, camp, etc) +mackal: Add pet size preservation like live (zone, camp, etc) == 01/07/2014 == -demonstar55: Moved pet can attack check to before it tries to attack, which is more live like. +mackal: Moved pet can attack check to before it tries to attack, which is more live like. == 01/03/2014 == -demonstar55: Crash prevention for emote. +mackal: Crash prevention for emote. == 01/02/2014 == -demonstar55: Stuns from beneficial spells (Harvest) ignore immunity +mackal: Stuns from beneficial spells (Harvest) ignore immunity == 12/26/2013 == -demonstar55: Added classes_required to merchantlist (same bitmask as items) +mackal: Added classes_required to merchantlist (same bitmask as items) == 12/24/2013 == Secrets (Akkadius): Perl $client->SilentMessage("Message"); addition, this is a pre-req for a Perl plugin I've shared with EQEmu. This function essentially mimics a player speaking with an NPC - which is used in popup window responses @@ -1707,14 +2151,14 @@ Kayen: Implemented SE_TriggerOnAmountValue (Trigger spell if HP/Mana/End bellow Kayen: Fix to SE_BlockNextSpellFocus to make it functional again. == 12/15/2013 == -demonstar55: Moved the blocked buff check down so we get spell effects like on live +mackal: Moved the blocked buff check down so we get spell effects like on live Kayen: Implemented SE_ReduceHealing (Reduces amount of healing on target by X amount) Kayen: Implemented SE_CastonFocusEffect (Triggers spell as part of a focus, when that focus effect is used) Kayen: Implemented SE_IncreaseHitDmgTaken (Effect is triggered when X amount of damage is taken) Kayen: More fixes for various spell triggers/procs to now properly use their resist modifier. == 12/14/2013 == -demonstar55: Blocked buffs shouldn't fail, they should just not be applied. +mackal: Blocked buffs shouldn't fail, they should just not be applied. JJ: Changed enable/disable recipe to confirm change made. == 12/13/2013 == @@ -1725,52 +2169,52 @@ Kayen: Fix for various spell triggers/procs to now properly use their resist mod Kayen: Fix to mob->ModSkillDmgTaken(skill_num, value), setting value to -1 will now properly effect all skills. == 12/11/2013 == -demonstar55: Fixed issue with crippling blow from berserker frenzy not actually doing anything -demonstar55: Fix haste caps +mackal: Fixed issue with crippling blow from berserker frenzy not actually doing anything +mackal: Fix haste caps == 12/04/2013 == -demonstar55: Fixed SpellType_Charm case in AICastSpell +mackal: Fixed SpellType_Charm case in AICastSpell == 12/03/2013 == -demonstar55: Added #showspellslist to view a mobs spell list -demonstar55: Fix procing off of unattackable things +mackal: Added #showspellslist to view a mobs spell list +mackal: Fix procing off of unattackable things == 12/02/2013 == JJ: Bandaid fix to CopyCharacter function. == 11/29/2013 == -demonstar55: Stacking issues should be resolved now, probably could be optimized more, but went from 3 loops that do stuff to 3 where only 2 really does stuff and one breaks early in most cases, so slightly better +mackal: Stacking issues should be resolved now, probably could be optimized more, but went from 3 loops that do stuff to 3 where only 2 really does stuff and one breaks early in most cases, so slightly better == 11/23/2013 == Secrets: Fixed an issue related to a zone crash where the count of the abilities in an AA was 0, leading to a size 0 buffer issue. == 11/19/2013 == Secrets: Fixed an issue with two zone crashes reported on PEQ related to the buff restrictions code and AAs. -demonstar55: Partially make use of dot_stacking_exempt (case when it's 1 is implemented, -1 case isn't) +mackal: Partially make use of dot_stacking_exempt (case when it's 1 is implemented, -1 case isn't) == 11/18/2013 == -demonstar55: Added assistradius to npc_types, defaults to aggroradius if set to 0 (old behaviour) +mackal: Added assistradius to npc_types, defaults to aggroradius if set to 0 (old behaviour) == 11/17/2013 == Sorvani: fixed leash and tether special abilities to use the specified range correctly. -demonstar55: Rewrote the Mob::_GetMovementSpeed fix an issue that arose from the change on 11/11 +mackal: Rewrote the Mob::_GetMovementSpeed fix an issue that arose from the change on 11/11 - Added the rule Character:BaseRunSpeedCap (default 158) so people can customize what their runspeed cap is. Hardcapped to 225 so stuff doesn't get too crazy. == 11/16/2013 == Leere: Fixed the drinking message for auto-consume, it will again correctly show up for forced consumption instead. -demonstar55: Added Mob::DoCastingChecks() which will check for various fail conditions while the casting bar is up. This is called after Mob::DoCastSpell() starts the casting and before it returns. +mackal: Added Mob::DoCastingChecks() which will check for various fail conditions while the casting bar is up. This is called after Mob::DoCastSpell() starts the casting and before it returns. == 11/15/2013 == -demonstar55: Fixed Mob::CalcFocusEffect()'s SE_LimitEffect +mackal: Fixed Mob::CalcFocusEffect()'s SE_LimitEffect Leere: Fixed a stacking issue for SE_StackingCommand_Block == 11/13/2013 == -demonstar55: Implemented bard song effect cap. You can set the base cap with the rule Character:BaseInstrumentSoftCap, defaults to 36 or "3.6" as it is sometimes referred to. -demonstar55: Fix Echo of Taelosia and Ayonae's Tutelage to increase the mod cap instead of further improving the instrument mod -demonstar55: Implemented Singing/Instrument Mastery as an AA bonus. +mackal: Implemented bard song effect cap. You can set the base cap with the rule Character:BaseInstrumentSoftCap, defaults to 36 or "3.6" as it is sometimes referred to. +mackal: Fix Echo of Taelosia and Ayonae's Tutelage to increase the mod cap instead of further improving the instrument mod +mackal: Implemented Singing/Instrument Mastery as an AA bonus. == 11/11/2013 == -demonstar55: Changed the way walk speed is calculated to allow mobs to have their walk speed equal a 100% movement reduction +mackal: Changed the way walk speed is calculated to allow mobs to have their walk speed equal a 100% movement reduction == 11/09/2013 == Leere: Fixed Bard mana regen, they now only are affected by items and AA. @@ -1820,50 +2264,50 @@ Uleat: Converted SkillType typedef enumeration to SkillUseTypes enumeration - So Uleat: Prepped the client patch files for larger skill buffer size (not active) == 10/24/2013 == -demonstar55: Fix some memory leaks in Mob::SpellOnTarget +mackal: Fix some memory leaks in Mob::SpellOnTarget == 10/21/2013 == -demonstar55: Changed GetMinLevel return 0 for more cases that EQ uses for some reason ... -demonstar55: Added buff level restrictions, set the Spells:BuffLevelRestrictions to false to have the old behavior. +mackal: Changed GetMinLevel return 0 for more cases that EQ uses for some reason ... +mackal: Added buff level restrictions, set the Spells:BuffLevelRestrictions to false to have the old behavior. == 10/18/2013 == Uleat: Expanded the 'Bag Type' enumeration to include all known values. Also, set in place additional 'Bag Type' to 'Skill Type' conversions. Some of these will need to be verified before activation. Uleat: Cleaned up some unused enumerations to show a move towards standardization. More to come... == 10/12/2013 == -demonstar55: Allow Titanium and lower clients to enter Tutorial zone from character select +mackal: Allow Titanium and lower clients to enter Tutorial zone from character select Bad_Captain: Fixed merc crash issue by updating special_abilities & vwMercNpcTypes (Sorvani). Bad_Captain: Bots- added out of combat bard songs & #bot bardoutofcombat on|off command to turn them on/off. == 10/11/2013 == -JJ: (demonstar55) Allow use of Go Home button when Tutorial still selected in RoF. +JJ: (mackal) Allow use of Go Home button when Tutorial still selected in RoF. == 10/10/2013 == Secrets: Fixed zone shutdown (or #reloadqst) reinitalization of Perl. This should allow for Perl 5.14 and later to work on Windows under the new quest system. -demonstar55: Beneficial single target buffs shouldn't have their mana/timers set if they fail to cast after the Mob::SpellOnTarget call in Mob::SpellFinished +mackal: Beneficial single target buffs shouldn't have their mana/timers set if they fail to cast after the Mob::SpellOnTarget call in Mob::SpellFinished JJ: Revert change to EnterWorldPacket introduced on 22 April 2013 to fix inability to enter Tutorial or Go Home from character select screen. == 10/09/2013 == -demonstar55: Fixed some more instances of the AA timer being eaten +mackal: Fixed some more instances of the AA timer being eaten == 10/08/2013 == -demonstar55: Added IsBuffSpell(spell_id) that will return true if the spell has a duration, so would end up in effects/song/discs etc windows on the client -demonstar55: Replaced instances of using CalcBuffDuration to determine if a spell was a buff with IsBuffSpell -demonstar55: Removed Mob::HasBuffIcon since it was doing what IsBuffSpell does in a more convoluted way with a rather misleading name -demonstar55: Fixed issues that arose from the 10/03/2013 change +mackal: Added IsBuffSpell(spell_id) that will return true if the spell has a duration, so would end up in effects/song/discs etc windows on the client +mackal: Replaced instances of using CalcBuffDuration to determine if a spell was a buff with IsBuffSpell +mackal: Removed Mob::HasBuffIcon since it was doing what IsBuffSpell does in a more convoluted way with a rather misleading name +mackal: Fixed issues that arose from the 10/03/2013 change == 10/05/2013 == Sorvani: fixed issue with stackable items being created with 0 charges cause by fix to SummonItems == 10/03/2013 == -demonstar55: Fix when the random +1 tick is added to nerf extension focus effects to where they should be +mackal: Fix when the random +1 tick is added to nerf extension focus effects to where they should be == 09/30/2013 == Sorvani: Changed SummonItem to only summon an item with max charges when said default value is present and not on zero charges -demonstar55: Fixed issue with #showstats showing your level for a bunch of values +mackal: Fixed issue with #showstats showing your level for a bunch of values == 09/13/2013 == -demonstar55: Add support for /pet hold on and /pet hold off (UF and RoF) +mackal: Add support for /pet hold on and /pet hold off (UF and RoF) == 08/29/2013 == KLS: Removed Common Profiler and Zone Profiler. They're well past outdated status and are just code bloat. @@ -2009,8 +2453,8 @@ KLS: Perl now will (like lua) keep track of the values you return from EVENT_*. KLS: Exported eq.follow(entity_id, [distance]) and eq.stop_follow() to lua. == 07/01/2013 == -demonstar55: Fix Monster Summoning related to giants/cyclops -demonstar55: Prevent Monster Summoning from summoning a portal in bothunder +mackal: Fix Monster Summoning related to giants/cyclops +mackal: Prevent Monster Summoning from summoning a portal in bothunder KLS: Merge of lua branch to master See: http://www.eqemulator.org/forums/showthread.php?t=37008 for more detailed information on what is added. Upgrade notes: @@ -2078,35 +2522,35 @@ JJ: Fixed rare case where heals from buffs could go negative. Derision: Moved entity_list.Clear() prior to destruction of Perl objects in zone shutdown as I was seeing a segfault due to attempts to call EVENT_HATE_LIST as mobs were being destroyed. == 04/09/2013 == -demonstar55: Realized I was an idiot, changed salvage script to be better +mackal: Realized I was an idiot, changed salvage script to be better optional SQL: 2013_04_09_SalvageCleanOld.sql - run if ran old script == 04/08/2013 == -demonstar55: Implemented Salvage AA +mackal: Implemented Salvage AA required SQL: 2013_04_08_Salvage.sql script: generate_salvage.py - will generate the entries for some exceptions for salvage returns. == 04/04/2013 == -demonstar55: Implemented SE_ForageAdditionalItems as a bonus +mackal: Implemented SE_ForageAdditionalItems as a bonus required SQL: 2013_04_04_NaturesBounty.sql == 04/03/2013 == -demonstar55: Overloaded Mob::Say_StringID with the option to provide a message type -demonstar55: Switched rest of the Pet Messages to MT_PetResponse (Leader commands intentionally left the old way) +mackal: Overloaded Mob::Say_StringID with the option to provide a message type +mackal: Switched rest of the Pet Messages to MT_PetResponse (Leader commands intentionally left the old way) == 04/2/2013 == Bad_Captain: Fixed Merc lack of use of heal over time spells (causing excessive healing). Bad_Captain: Fixed pet mitigation/AC issues. == 04/01/2013 == -demonstar55: AA reuse timers now start when you hit the button and are reset upon failure -demonstar55: Instant Cast bard AAs can now be used while singing a song +mackal: AA reuse timers now start when you hit the button and are reset upon failure +mackal: Instant Cast bard AAs can now be used while singing a song == 03/30/2013 == -demonstar55: Fixed most of the pet talking, all use StringIDs now. Pet now informs you when it taunts. +mackal: Fixed most of the pet talking, all use StringIDs now. Pet now informs you when it taunts. == 03/23/2013 == -demonstar55: Fix issues with escape not always working and fixed SE_FadingMemories to have the message since the message isn't part of the spell data. +mackal: Fix issues with escape not always working and fixed SE_FadingMemories to have the message since the message isn't part of the spell data. Escape now uses just the spell and not the AA Actoin Fading Memories now only uses the AA Action to eat mana @@ -2116,7 +2560,7 @@ Bad_Captain: Added checks before dismissing merc to prevent possible bugged merc Bad_Captain: Merged in Secret's merc memory leak fixes. == 03/20/2013 == -demonstar55: Fixed stacking issues with SE_Limit* (ex. Unholy Aura Discipline and Aura of Reverence) +mackal: Fixed stacking issues with SE_Limit* (ex. Unholy Aura Discipline and Aura of Reverence) == 03/18/2013 == Bad_Captain: Fixed zone crash due to merc focus effects & tribute. @@ -2179,7 +2623,7 @@ KLS: Changed how shared memory works: af4t: Add Touch of the Wicked AA redux to SK Improved Harm Touch and Leech Touch. == 02/22/2013 == -demonstar55: Mobs will now be removed from XTargets when they get back to their way point, should be last instance of XTarget mobs not clearing when they are not aggroed anymore +mackal: Mobs will now be removed from XTargets when they get back to their way point, should be last instance of XTarget mobs not clearing when they are not aggroed anymore == 02/19/2013 == Derision: World should no longer crash if the start_zone query fails at character creation. @@ -2188,7 +2632,7 @@ Derision: World should no longer crash if the start_zone query fails at characte Bad_Captain: Moved merc save to merc table, save merc buffs, added cure and rez spells to healer merc. JJ: Chat garbled for drunk characters. Derision: Charmed pets should no longer be targettable with F8. Charmed pets no longer get a surname of Soandso's Pet. -demonstar55: Added potionbelt tool tip +mackal: Added potionbelt tool tip KLS: Added EVENT_DEATH to Player Quests REQUIRED SQL: 2013_02_18_Merc_Rules_and_Tables.sql @@ -2200,8 +2644,8 @@ Derision: Client version is now returned by the stream proxy as a number. Derision: Fixed bug where BecomeTrader packets were only being sent to the Trader, not all other clients in the bazaar. == 02/16/2013 == -demonstar55: Fix AA reuse timer calc -demonstar55: Remove old filters and change all remaining old to new (Also fix Auction filtering out OOC as well due to incorrect define) +mackal: Fix AA reuse timer calc +mackal: Remove old filters and change all remaining old to new (Also fix Auction filtering out OOC as well due to incorrect define) == 02/12/2013 == Kayen: AA fix @@ -2212,7 +2656,7 @@ REQUIRED SQL: utils/sql/svn/2504_required_aa_updates.sql Derision: RoF: Added ENCODE for OP_BeginCast (fixes no sound during spell casting). Corrected OP_DeleteSpell. == 02/10/2013 == -JJ: (demonstar55) Language skill up should use proper function. +JJ: (mackal) Language skill up should use proper function. JJ: SetLanguageSkill now updates client immediately. Both functions do proper limit checks. Added two missing languages. Skill level 0 in a spoken language now shows 'in an unknown tongue'. JJ: Initial implementation of a GarbleMessage function and implemented for languages. Can be shared with drunk speaking. @@ -2248,7 +2692,7 @@ Trevius: RoF: Turning on Trader mode in bazaar now works, but no further trader Akkadius: Fixed an issue where global_npc.pl was not initializing (initially) == 01/31/2013 == -cavedude00: (demonstar55) Rune aggro fix +cavedude00: (mackal) Rune aggro fix cavedude00: (Drajor) Tradeskill skillneeded fix. == 01/30/2013 == @@ -2282,7 +2726,7 @@ Bad_Captain: Mercs - Initial spell casting AI committed. KLS: Added crash logging for Windows builds. Trevius: Mercenaries now despawn when a player camps out or disconnects in any way. Trevius: Players with a Mercenary spawned can now be invited to and join another group with their mercenary. -Sorvani: (Demonstar55): Moved stunproc rule implmentation to catch all cases +Sorvani: (mackal): Moved stunproc rule implmentation to catch all cases OPTIONAL SQL: utils/sql/svn/mercs.sql -- rerun for updated merc stats & merc spell lists @@ -2733,9 +3177,9 @@ references: http://www.eqemulator.org/forums/showthread.php?t=35629 - CSD Bugged Corpse Patch http://www.eqemulator.org/forums/showthread.php?t=35699 - CSD Bandolier Patch -cavedude: (demonstar55) Damage shields by default will no longer count towards EXP gain. (Rule also added to change this behaviour.) -cavedude: (demonstar55) Extended targets should now clear when aggro is lost using skills. -cavedude: (demonstar55) AAs with shorter reuse timers should now reset if the cast failed (interrupted.) +cavedude: (mackal) Damage shields by default will no longer count towards EXP gain. (Rule also added to change this behaviour.) +cavedude: (mackal) Extended targets should now clear when aggro is lost using skills. +cavedude: (mackal) AAs with shorter reuse timers should now reset if the cast failed (interrupted.) KLS: Fixed a cause of raids disbanding on zoning. OPTIONAL SQL: INSERT INTO `rule_values` VALUES (1, 'Combat:EXPFromDmgShield', 'false', 'Determine if damage from a damage shield counts for EXP gain.'); @@ -3112,7 +3556,7 @@ Kayen: Implemented Perl Mob Quest Object GetModVulnerability(resist type) - Retu Optional SQL: utils/sql/svn/2154_optional_rule_spell_procs_resists_falloff.sql ==06/22/2012== -Secrets: (demonstar55) Spells now display to all clients and can be filtered as such. +Secrets: (mackal) Spells now display to all clients and can be filtered as such. Secrets: Damage Shields now go to the proper filter, and do not show the non-melee damage to everyone. ==06/03/2012== @@ -5267,10 +5711,10 @@ WildcardX: *BOTS* Bots can now be invited and disbanded from your group by simpl WildcardX: *BOTS* Tweak to the bots total play time calculation to make it more accurate. KLS: Added #path meshtest simple to do a faster search on errant path nodes. KLS: Modified the accurate hazard code to make automatic path maps with more accurate info that requires less manual editing afterward. -cavedude: (demonstar55) Pets will now be amiable to their owners, indifferent to all else. -cavedude: (demonstar55) Added $client->KeyRingCheck() and $client->KeyRingAdd() to allow Perl to manipulate the keyring. -cavedude: (demonstar55) Casting an invis spell on a player that already has a similar type invis spell will no longer drop the existing buff. -cavedude: (demonstar55) Corrected message string for heal spells. +cavedude: (mackal) Pets will now be amiable to their owners, indifferent to all else. +cavedude: (mackal) Added $client->KeyRingCheck() and $client->KeyRingAdd() to allow Perl to manipulate the keyring. +cavedude: (mackal) Casting an invis spell on a player that already has a similar type invis spell will no longer drop the existing buff. +cavedude: (mackal) Corrected message string for heal spells. cavedude: Added rule to determine at what HP a fleeing NPC will halt due to being snared. ==08/07/2009== @@ -5906,7 +6350,7 @@ KLS: Fixed the /bug structure and updated the table to be more useful. Required SQL: .\utils\sql\svn\503_bugs.sql ==05/11/2009== -demonstar55: Added a function to allow Perl to check augments within items. +mackal: Added a function to allow Perl to check augments within items. cavedude: Increased bind wound skill up speed some. KLS: Fix for potentially dangerous typo in spawn conditions code. KLS: Removed some non-functioning but still taking up database resources database code. @@ -6207,7 +6651,7 @@ cavedude: Removed the USE_RACE_CLASS_XP_MODS define as it was outdated and horri cavedude: Added group XP bonus. The larger the group, the higher the XP gain. cavedude: Added XP bonus for Warrior, Rogue, and Halfling. cavedude: Corrected ZEM for AAs. -cavedude: (Thanks to demonstar55) Pet Affinity will no longer effect charmed pets. +cavedude: (Thanks to mackal) Pet Affinity will no longer effect charmed pets. cavedude: (realityincarnate) Bard songs that require instruments will now require them. Please note: XP gain has pretty much been overhauled. You may need tweak the multiplier rules for your server. @@ -6341,7 +6785,7 @@ AndMetal: Augments are now visible when linking items. Trevius: SoF - Adjusted the new Item Structure to align more fields Trevius: SoF - Added OP_Consume and OP_LootRequest opcodes cavedude00: (AndMetal) AAs now use skill_id instead of index for prereqs. -cavedude00: (demonstar55) Implemented Improved Instrument Mastery, Improved Singing Mastery, and Echo of Taelosia AAs. +cavedude00: (mackal) Implemented Improved Instrument Mastery, Improved Singing Mastery, and Echo of Taelosia AAs. cavedude00: Created Combat:ChanceToHitDivideBy rule and increased default value to 1250. Required and Optional SQL: utils/sql/svn/326_aas.sql KLS: SoF - Fix for item slots in bags. diff --git a/client_files/export/main.cpp b/client_files/export/main.cpp index 708d48456..8009e81b4 100644 --- a/client_files/export/main.cpp +++ b/client_files/export/main.cpp @@ -27,7 +27,7 @@ #include "../../common/rulesys.h" #include "../../common/string_util.h" -EQEmuLogSys Log; +EQEmuLogSys LogSys; void ExportSpells(SharedDatabase *db); void ExportSkillCaps(SharedDatabase *db); @@ -36,46 +36,46 @@ void ExportDBStrings(SharedDatabase *db); int main(int argc, char **argv) { RegisterExecutablePlatform(ExePlatformClientExport); - Log.LoadLogSettingsDefaults(); + LogSys.LoadLogSettingsDefaults(); set_exception_handler(); - Log.Out(Logs::General, Logs::Status, "Client Files Export Utility"); + Log(Logs::General, Logs::Status, "Client Files Export Utility"); if(!EQEmuConfig::LoadConfig()) { - Log.Out(Logs::General, Logs::Error, "Unable to load configuration file."); + Log(Logs::General, Logs::Error, "Unable to load configuration file."); return 1; } - const EQEmuConfig *config = EQEmuConfig::get(); + auto Config = EQEmuConfig::get(); SharedDatabase database; - Log.Out(Logs::General, Logs::Status, "Connecting to database..."); - if(!database.Connect(config->DatabaseHost.c_str(), config->DatabaseUsername.c_str(), - config->DatabasePassword.c_str(), config->DatabaseDB.c_str(), config->DatabasePort)) { - Log.Out(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a " + Log(Logs::General, Logs::Status, "Connecting to database..."); + if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(), + Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) { + Log(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a " "database connection"); return 1; } /* Register Log System and Settings */ - database.LoadLogSettings(Log.log_settings); - Log.StartFileLogs(); + database.LoadLogSettings(LogSys.log_settings); + LogSys.StartFileLogs(); ExportSpells(&database); ExportSkillCaps(&database); ExportBaseData(&database); ExportDBStrings(&database); - Log.CloseFileLogs(); + LogSys.CloseFileLogs(); return 0; } void ExportSpells(SharedDatabase *db) { - Log.Out(Logs::General, Logs::Status, "Exporting Spells..."); + Log(Logs::General, Logs::Status, "Exporting Spells..."); FILE *f = fopen("export/spells_us.txt", "w"); if(!f) { - Log.Out(Logs::General, Logs::Error, "Unable to open export/spells_us.txt to write, skipping."); + Log(Logs::General, Logs::Error, "Unable to open export/spells_us.txt to write, skipping."); return; } @@ -142,11 +142,11 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level) { } void ExportSkillCaps(SharedDatabase *db) { - Log.Out(Logs::General, Logs::Status, "Exporting Skill Caps..."); + Log(Logs::General, Logs::Status, "Exporting Skill Caps..."); FILE *f = fopen("export/SkillCaps.txt", "w"); if(!f) { - Log.Out(Logs::General, Logs::Error, "Unable to open export/SkillCaps.txt to write, skipping."); + Log(Logs::General, Logs::Error, "Unable to open export/SkillCaps.txt to write, skipping."); return; } @@ -171,11 +171,11 @@ void ExportSkillCaps(SharedDatabase *db) { } void ExportBaseData(SharedDatabase *db) { - Log.Out(Logs::General, Logs::Status, "Exporting Base Data..."); + Log(Logs::General, Logs::Status, "Exporting Base Data..."); FILE *f = fopen("export/BaseData.txt", "w"); if(!f) { - Log.Out(Logs::General, Logs::Error, "Unable to open export/BaseData.txt to write, skipping."); + Log(Logs::General, Logs::Error, "Unable to open export/BaseData.txt to write, skipping."); return; } @@ -202,11 +202,11 @@ void ExportBaseData(SharedDatabase *db) { } void ExportDBStrings(SharedDatabase *db) { - Log.Out(Logs::General, Logs::Status, "Exporting DB Strings..."); + Log(Logs::General, Logs::Status, "Exporting DB Strings..."); FILE *f = fopen("export/dbstr_us.txt", "w"); if(!f) { - Log.Out(Logs::General, Logs::Error, "Unable to open export/dbstr_us.txt to write, skipping."); + Log(Logs::General, Logs::Error, "Unable to open export/dbstr_us.txt to write, skipping."); return; } diff --git a/client_files/import/main.cpp b/client_files/import/main.cpp index 72ae6fd5d..a8e2ad0fe 100644 --- a/client_files/import/main.cpp +++ b/client_files/import/main.cpp @@ -25,7 +25,7 @@ #include "../../common/rulesys.h" #include "../../common/string_util.h" -EQEmuLogSys Log; +EQEmuLogSys LogSys; void ImportSpells(SharedDatabase *db); void ImportSkillCaps(SharedDatabase *db); @@ -34,35 +34,35 @@ void ImportDBStrings(SharedDatabase *db); int main(int argc, char **argv) { RegisterExecutablePlatform(ExePlatformClientImport); - Log.LoadLogSettingsDefaults(); + LogSys.LoadLogSettingsDefaults(); set_exception_handler(); - Log.Out(Logs::General, Logs::Status, "Client Files Import Utility"); + Log(Logs::General, Logs::Status, "Client Files Import Utility"); if(!EQEmuConfig::LoadConfig()) { - Log.Out(Logs::General, Logs::Error, "Unable to load configuration file."); + Log(Logs::General, Logs::Error, "Unable to load configuration file."); return 1; } - const EQEmuConfig *config = EQEmuConfig::get(); + auto Config = EQEmuConfig::get(); SharedDatabase database; - Log.Out(Logs::General, Logs::Status, "Connecting to database..."); - if(!database.Connect(config->DatabaseHost.c_str(), config->DatabaseUsername.c_str(), - config->DatabasePassword.c_str(), config->DatabaseDB.c_str(), config->DatabasePort)) { - Log.Out(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a " + Log(Logs::General, Logs::Status, "Connecting to database..."); + if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(), + Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) { + Log(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a " "database connection"); return 1; } - database.LoadLogSettings(Log.log_settings); - Log.StartFileLogs(); + database.LoadLogSettings(LogSys.log_settings); + LogSys.StartFileLogs(); ImportSpells(&database); ImportSkillCaps(&database); ImportBaseData(&database); ImportDBStrings(&database); - Log.CloseFileLogs(); + LogSys.CloseFileLogs(); return 0; } @@ -97,10 +97,10 @@ bool IsStringField(int i) { } void ImportSpells(SharedDatabase *db) { - Log.Out(Logs::General, Logs::Status, "Importing Spells..."); + Log(Logs::General, Logs::Status, "Importing Spells..."); FILE *f = fopen("import/spells_us.txt", "r"); if(!f) { - Log.Out(Logs::General, Logs::Error, "Unable to open import/spells_us.txt to read, skipping."); + Log(Logs::General, Logs::Error, "Unable to open import/spells_us.txt to read, skipping."); return; } @@ -173,23 +173,23 @@ void ImportSpells(SharedDatabase *db) { spells_imported++; if(spells_imported % 1000 == 0) { - Log.Out(Logs::General, Logs::Status, "%d spells imported.", spells_imported); + Log(Logs::General, Logs::Status, "%d spells imported.", spells_imported); } } if(spells_imported % 1000 != 0) { - Log.Out(Logs::General, Logs::Status, "%d spells imported.", spells_imported); + Log(Logs::General, Logs::Status, "%d spells imported.", spells_imported); } fclose(f); } void ImportSkillCaps(SharedDatabase *db) { - Log.Out(Logs::General, Logs::Status, "Importing Skill Caps..."); + Log(Logs::General, Logs::Status, "Importing Skill Caps..."); FILE *f = fopen("import/SkillCaps.txt", "r"); if(!f) { - Log.Out(Logs::General, Logs::Error, "Unable to open import/SkillCaps.txt to read, skipping."); + Log(Logs::General, Logs::Error, "Unable to open import/SkillCaps.txt to read, skipping."); return; } @@ -220,11 +220,11 @@ void ImportSkillCaps(SharedDatabase *db) { } void ImportBaseData(SharedDatabase *db) { - Log.Out(Logs::General, Logs::Status, "Importing Base Data..."); + Log(Logs::General, Logs::Status, "Importing Base Data..."); FILE *f = fopen("import/BaseData.txt", "r"); if(!f) { - Log.Out(Logs::General, Logs::Error, "Unable to open import/BaseData.txt to read, skipping."); + Log(Logs::General, Logs::Error, "Unable to open import/BaseData.txt to read, skipping."); return; } @@ -265,11 +265,11 @@ void ImportBaseData(SharedDatabase *db) { } void ImportDBStrings(SharedDatabase *db) { - Log.Out(Logs::General, Logs::Status, "Importing DB Strings..."); + Log(Logs::General, Logs::Status, "Importing DB Strings..."); FILE *f = fopen("import/dbstr_us.txt", "r"); if(!f) { - Log.Out(Logs::General, Logs::Error, "Unable to open import/dbstr_us.txt to read, skipping."); + Log(Logs::General, Logs::Error, "Unable to open import/dbstr_us.txt to read, skipping."); return; } diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 09ed7e02c..cecb47d12 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -11,15 +11,20 @@ SET(common_sources database_conversions.cpp database_instances.cpp dbcore.cpp + deity.cpp + emu_constants.cpp + emu_legacy.cpp + emu_limits.cpp emu_opcodes.cpp emu_tcp_connection.cpp emu_tcp_server.cpp - eq_dictionary.cpp + emu_versions.cpp eqdb.cpp eqdb_res.cpp eqemu_exception.cpp eqemu_config.cpp eqemu_logsys.cpp + eq_limits.cpp eq_packet.cpp eq_stream.cpp eq_stream_factory.cpp @@ -30,9 +35,14 @@ SET(common_sources faction.cpp guild_base.cpp guilds.cpp + inventory_profile.cpp + inventory_slot.cpp ipc_mutex.cpp - item.cpp + item_data.cpp + item_instance.cpp + light_source.cpp md5.cpp + memory_buffer.cpp memory_mapped_file.cpp misc.cpp misc_functions.cpp @@ -51,6 +61,7 @@ SET(common_sources races.cpp rdtsc.cpp rulesys.cpp + say_link.cpp serverinfo.cpp shareddb.cpp skills.cpp @@ -59,6 +70,7 @@ SET(common_sources struct_strategy.cpp tcp_connection.cpp tcp_server.cpp + textures.cpp timeoutmgr.cpp timer.cpp unix.cpp @@ -67,11 +79,17 @@ SET(common_sources platform.cpp patches/patches.cpp patches/sod.cpp + patches/sod_limits.cpp patches/sof.cpp + patches/sof_limits.cpp patches/rof.cpp + patches/rof_limits.cpp patches/rof2.cpp + patches/rof2_limits.cpp patches/titanium.cpp + patches/titanium_limits.cpp patches/uf.cpp + patches/uf_limits.cpp SocketLib/Base64.cpp SocketLib/File.cpp SocketLib/HttpdCookies.cpp @@ -104,12 +122,15 @@ SET(common_headers database.h dbcore.h deity.h + emu_constants.h + emu_legacy.h + emu_limits.h emu_opcodes.h emu_oplist.h emu_tcp_connection.h emu_tcp_server.h + emu_versions.h eq_constants.h - eq_dictionary.h eq_packet_structs.h eqdb.h eqdb_res.h @@ -117,6 +138,7 @@ SET(common_headers eqemu_config.h eqemu_config_elements.h eqemu_logsys.h + eq_limits.h eq_packet.h eq_stream.h eq_stream_factory.h @@ -135,15 +157,19 @@ SET(common_headers global_define.h guild_base.h guilds.h + inventory_profile.h + inventory_slot.h ipc_mutex.h - item.h + item_data.h item_fieldlist.h - item_struct.h + item_instance.h languages.h + light_source.h linked_list.h loottable.h mail_oplist.h md5.h + memory_buffer.h memory_mapped_file.h misc.h misc_functions.h @@ -166,6 +192,7 @@ SET(common_headers rdtsc.h rulesys.h ruletypes.h + say_link.h seperator.h serverinfo.h servertalk.h @@ -177,6 +204,7 @@ SET(common_headers tcp_basic_server.h tcp_connection.h tcp_server.h + textures.h timeoutmgr.h timer.h types.h @@ -188,38 +216,30 @@ SET(common_headers zone_numbers.h patches/patches.h patches/sod.h - patches/sod_constants.h - patches/sod_itemfields.h + patches/sod_limits.h patches/sod_ops.h patches/sod_structs.h patches/sof.h - patches/sof_constants.h - patches/sof_itemfields.h - patches/sof_opcode_list.h + patches/sof_limits.h patches/sof_ops.h patches/sof_structs.h patches/ss_declare.h patches/ss_define.h patches/ss_register.h patches/rof.h - patches/rof_constants.h - patches/rof_itemfields.h + patches/rof_limits.h patches/rof_ops.h patches/rof_structs.h patches/rof2.h - patches/rof2_constants.h - patches/rof2_itemfields.h + patches/rof2_limits.h patches/rof2_ops.h patches/rof2_structs.h patches/titanium.h - patches/titanium_constants.h - patches/titanium_itemfields_a.h - patches/titanium_itemfields_b.h + patches/titanium_limits.h patches/titanium_ops.h patches/titanium_structs.h patches/uf.h - patches/uf_constants.h - patches/uf_itemfields.h + patches/uf_limits.h patches/uf_ops.h patches/uf_structs.h SocketLib/Base64.h @@ -242,47 +262,45 @@ SET(common_headers SOURCE_GROUP(Patches FILES patches/patches.h patches/sod.h - patches/sod_itemfields.h + patches/sod_limits.h patches/sod_ops.h - patches/sod_constants.h patches/sod_structs.h patches/sof.h - patches/sof_itemfields.h - patches/sof_opcode_list.h + patches/sof_limits.h patches/sof_ops.h - patches/sof_constants.h patches/sof_structs.h patches/ss_declare.h patches/ss_define.h patches/ss_register.h patches/rof.h - patches/rof_itemfields.h + patches/rof_limits.h patches/rof_ops.h - patches/rof_constants.h patches/rof_structs.h patches/rof2.h - patches/rof2_itemfields.h + patches/rof2_limits.h patches/rof2_ops.h - patches/rof2_constants.h patches/rof2_structs.h patches/titanium.h - patches/titanium_itemfields_a.h - patches/titanium_itemfields_b.h + patches/titanium_limits.h patches/titanium_ops.h - patches/titanium_constants.h patches/titanium_structs.h patches/uf.h - patches/uf_itemfields.h + patches/uf_limits.h patches/uf_ops.h - patches/uf_constants.h patches/uf_structs.h patches/patches.cpp patches/sod.cpp + patches/sod_limits.cpp patches/sof.cpp + patches/sof_limits.cpp patches/rof.cpp + patches/rof_limits.cpp patches/rof2.cpp + patches/rof2_limits.cpp patches/titanium.cpp + patches/titanium_limits.cpp patches/uf.cpp + patches/uf_limits.cpp ) SOURCE_GROUP(SocketLib FILES diff --git a/common/base_packet.h b/common/base_packet.h index 16a527ade..bdd774aa2 100644 --- a/common/base_packet.h +++ b/common/base_packet.h @@ -22,10 +22,10 @@ #include #include -#ifdef WIN32 +#ifdef _WINDOWS #include - #include #include + #include #else #include #include diff --git a/common/classes.cpp b/common/classes.cpp index 1f54c9234..58aa56602 100644 --- a/common/classes.cpp +++ b/common/classes.cpp @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org) + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemu.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,275 +18,576 @@ #include "../common/global_define.h" #include "../common/classes.h" -const char* GetEQClassName(uint8 class_, uint8 level) { - switch(class_) { - case WARRIOR: - if (level >= 70) - return "Vanquisher"; - else if (level >= 65) - return "Overlord"; //Baron-Sprite: LEAVE MY CLASSES ALONE. - else if (level >= 60) - return "Warlord"; - else if (level >= 55) - return "Myrmidon"; - else if (level >= 51) - return "Champion"; - else - return "Warrior"; - case CLERIC: - if (level >= 70) - return "Prelate"; - else if (level >= 65) - return "Archon"; - else if (level >= 60) - return "High Priest"; - else if (level >= 55) - return "Templar"; - else if (level >= 51) - return "Vicar"; - else - return "Cleric"; - case PALADIN: - if (level >= 70) - return "Lord"; - else if (level >= 65) - return "Lord Protector"; - else if (level >= 60) - return "Crusader"; - else if (level >= 55) - return "Knight"; - else if (level >= 51) - return "Cavalier"; - else - return "Paladin"; - case RANGER: - if (level >= 70) - return "Plainswalker"; - else if (level >= 65) - return "Forest Stalker"; - else if (level >= 60) - return "Warder"; - else if (level >= 55) - return "Outrider"; - else if (level >= 51) - return "Pathfinder"; - else - return "Ranger"; - case SHADOWKNIGHT: - if (level >= 70) - return "Scourge Knight"; - else if (level >= 65) - return "Dread Lord"; - else if (level >= 60) - return "Grave Lord"; - else if (level >= 55) - return "Revenant"; - else if (level >= 51) - return "Reaver"; - else - return "Shadowknight"; - case DRUID: - if (level >= 70) - return "Natureguard"; - else if (level >= 65) - return "Storm Warden"; - else if (level >= 60) - return "Hierophant"; - else if (level >= 55) - return "Preserver"; - else if (level >= 51) - return "Wanderer"; - else - return "Druid"; - case MONK: - if (level >= 70) - return "Stone Fist"; - else if (level >= 65) - return "Transcendent"; - else if (level >= 60) - return "Grandmaster"; - else if (level >= 55) - return "Master"; - else if (level >= 51) - return "Disciple"; - else - return "Monk"; - case BARD: - if (level >= 70) - return "Performer"; - else if (level >= 65) - return "Maestro"; - else if (level >= 60) - return "Virtuoso"; - else if (level >= 55) - return "Troubadour"; - else if (level >= 51) - return "Minstrel"; - else - return "Bard"; - case ROGUE: - if (level >= 70) - return "Nemesis"; - else if (level >= 65) - return "Deceiver"; - else if (level >= 60) - return "Assassin"; - else if (level >= 55) - return "Blackguard"; - else if (level >= 51) - return "Rake"; - else - return "Rogue"; - case SHAMAN: - if (level >= 70) - return "Soothsayer"; - else if (level >= 65) - return "Prophet"; - else if (level >= 60) - return "Oracle"; - else if (level >= 55) - return "Luminary"; - else if (level >= 51) - return "Mystic"; - else - return "Shaman"; - case NECROMANCER: - if (level >= 70) - return "Wraith"; - else if (level >= 65) - return "Arch Lich"; - else if (level >= 60) - return "Warlock"; - else if (level >= 55) - return "Defiler"; - else if (level >= 51) - return "Heretic"; - else - return "Necromancer"; - case WIZARD: - if (level >= 70) - return "Grand Arcanist"; - else if (level >= 65) - return "Arcanist"; - else if (level >= 60) - return "Sorcerer"; - else if (level >= 55) - return "Evoker"; - else if (level >= 51) - return "Channeler"; - else - return "Wizard"; - case MAGICIAN: - if (level >= 70) - return "Arch Magus"; - else if (level >= 65) - return "Arch Convoker"; - else if (level >= 60) - return "Arch Mage"; - else if (level >= 55) - return "Conjurer"; - if (level >= 51) - return "Elementalist"; - else - return "Magician"; - case ENCHANTER: - if (level >= 70) - return "Bedazzler"; - else if (level >= 65) - return "Coercer"; - else if (level >= 60) - return "Phantasmist"; - else if (level >= 55) - return "Beguiler"; - else if (level >= 51) - return "Illusionist"; - else - return "Enchanter"; - case BEASTLORD: - if (level >= 70) - return "Wildblood"; - else if (level >= 65) - return "Feral Lord"; - else if (level >= 60) - return "Savage Lord"; - else if (level >= 55) - return "Animist"; - else if (level >= 51) - return "Primalist"; - else - return "Beastlord"; - case BERSERKER: - if (level >= 70) - return "Ravager"; - else if (level >= 65) - return "Fury"; - else if (level >= 60) - return "Rager"; - else if (level >= 55) - return "Vehement"; - else if (level >= 51) - return "Brawler"; - else - return "Berserker"; - case BANKER: - if (level >= 70) - return "Master Banker"; - else if (level >= 65) - return "Elder Banker"; - else if (level >= 60) - return "Oldest Banker"; - else if (level >= 55) - return "Older Banker"; - else if (level >= 51) - return "Old Banker"; - else - return "Banker"; - case WARRIORGM: - return "Warrior Guildmaster"; - case CLERICGM: - return "Cleric Guildmaster"; - case PALADINGM: - return "Paladin Guildmaster"; - case RANGERGM: - return "Ranger Guildmaster"; - case SHADOWKNIGHTGM: - return "Shadowknight Guildmaster"; - case DRUIDGM: - return "Druid Guildmaster"; - case MONKGM: - return "Monk Guildmaster"; - case BARDGM: - return "Bard Guildmaster"; - case ROGUEGM: - return "Rogue Guildmaster"; - case SHAMANGM: - return "Shaman Guildmaster"; - case NECROMANCERGM: - return "Necromancer Guildmaster"; - case WIZARDGM: - return "Wizard Guildmaster"; - case MAGICIANGM: - return "Magician Guildmaster"; - case ENCHANTERGM: - return "Enchanter Guildmaster"; - case BEASTLORDGM: - return "Beastlord Guildmaster"; - case BERSERKERGM: - return "Berserker Guildmaster"; - case MERCHANT: - return "Merchant"; - case ADVENTURERECRUITER: - return "Adventure Recruiter"; - case ADVENTUREMERCHANT: - return "Adventure Merchant"; - case CORPSE_CLASS: - return "Corpse Class"; - case TRIBUTE_MASTER: - return "Tribute Master"; - case GUILD_TRIBUTE_MASTER: - return "Guild Tribute Master"; - default: - return "Unknown"; +const char* GetClassIDName(uint8 class_id, uint8 level) +{ + switch (class_id) { + case WARRIOR: + if (level >= 70) + return "Vanquisher"; + else if (level >= 65) + return "Overlord"; //Baron-Sprite: LEAVE MY CLASSES ALONE. + else if (level >= 60) + return "Warlord"; + else if (level >= 55) + return "Myrmidon"; + else if (level >= 51) + return "Champion"; + else + return "Warrior"; + case CLERIC: + if (level >= 70) + return "Prelate"; + else if (level >= 65) + return "Archon"; + else if (level >= 60) + return "High Priest"; + else if (level >= 55) + return "Templar"; + else if (level >= 51) + return "Vicar"; + else + return "Cleric"; + case PALADIN: + if (level >= 70) + return "Lord"; + else if (level >= 65) + return "Lord Protector"; + else if (level >= 60) + return "Crusader"; + else if (level >= 55) + return "Knight"; + else if (level >= 51) + return "Cavalier"; + else + return "Paladin"; + case RANGER: + if (level >= 70) + return "Plainswalker"; + else if (level >= 65) + return "Forest Stalker"; + else if (level >= 60) + return "Warder"; + else if (level >= 55) + return "Outrider"; + else if (level >= 51) + return "Pathfinder"; + else + return "Ranger"; + case SHADOWKNIGHT: + if (level >= 70) + return "Scourge Knight"; + else if (level >= 65) + return "Dread Lord"; + else if (level >= 60) + return "Grave Lord"; + else if (level >= 55) + return "Revenant"; + else if (level >= 51) + return "Reaver"; + else + return "Shadowknight"; + case DRUID: + if (level >= 70) + return "Natureguard"; + else if (level >= 65) + return "Storm Warden"; + else if (level >= 60) + return "Hierophant"; + else if (level >= 55) + return "Preserver"; + else if (level >= 51) + return "Wanderer"; + else + return "Druid"; + case MONK: + if (level >= 70) + return "Stone Fist"; + else if (level >= 65) + return "Transcendent"; + else if (level >= 60) + return "Grandmaster"; + else if (level >= 55) + return "Master"; + else if (level >= 51) + return "Disciple"; + else + return "Monk"; + case BARD: + if (level >= 70) + return "Performer"; + else if (level >= 65) + return "Maestro"; + else if (level >= 60) + return "Virtuoso"; + else if (level >= 55) + return "Troubadour"; + else if (level >= 51) + return "Minstrel"; + else + return "Bard"; + case ROGUE: + if (level >= 70) + return "Nemesis"; + else if (level >= 65) + return "Deceiver"; + else if (level >= 60) + return "Assassin"; + else if (level >= 55) + return "Blackguard"; + else if (level >= 51) + return "Rake"; + else + return "Rogue"; + case SHAMAN: + if (level >= 70) + return "Soothsayer"; + else if (level >= 65) + return "Prophet"; + else if (level >= 60) + return "Oracle"; + else if (level >= 55) + return "Luminary"; + else if (level >= 51) + return "Mystic"; + else + return "Shaman"; + case NECROMANCER: + if (level >= 70) + return "Wraith"; + else if (level >= 65) + return "Arch Lich"; + else if (level >= 60) + return "Warlock"; + else if (level >= 55) + return "Defiler"; + else if (level >= 51) + return "Heretic"; + else + return "Necromancer"; + case WIZARD: + if (level >= 70) + return "Grand Arcanist"; + else if (level >= 65) + return "Arcanist"; + else if (level >= 60) + return "Sorcerer"; + else if (level >= 55) + return "Evoker"; + else if (level >= 51) + return "Channeler"; + else + return "Wizard"; + case MAGICIAN: + if (level >= 70) + return "Arch Magus"; + else if (level >= 65) + return "Arch Convoker"; + else if (level >= 60) + return "Arch Mage"; + else if (level >= 55) + return "Conjurer"; + if (level >= 51) + return "Elementalist"; + else + return "Magician"; + case ENCHANTER: + if (level >= 70) + return "Bedazzler"; + else if (level >= 65) + return "Coercer"; + else if (level >= 60) + return "Phantasmist"; + else if (level >= 55) + return "Beguiler"; + else if (level >= 51) + return "Illusionist"; + else + return "Enchanter"; + case BEASTLORD: + if (level >= 70) + return "Wildblood"; + else if (level >= 65) + return "Feral Lord"; + else if (level >= 60) + return "Savage Lord"; + else if (level >= 55) + return "Animist"; + else if (level >= 51) + return "Primalist"; + else + return "Beastlord"; + case BERSERKER: + if (level >= 70) + return "Ravager"; + else if (level >= 65) + return "Fury"; + else if (level >= 60) + return "Rager"; + else if (level >= 55) + return "Vehement"; + else if (level >= 51) + return "Brawler"; + else + return "Berserker"; + case BANKER: + if (level >= 70) + return "Master Banker"; + else if (level >= 65) + return "Elder Banker"; + else if (level >= 60) + return "Oldest Banker"; + else if (level >= 55) + return "Older Banker"; + else if (level >= 51) + return "Old Banker"; + else + return "Banker"; + case WARRIORGM: + return "Warrior Guildmaster"; + case CLERICGM: + return "Cleric Guildmaster"; + case PALADINGM: + return "Paladin Guildmaster"; + case RANGERGM: + return "Ranger Guildmaster"; + case SHADOWKNIGHTGM: + return "Shadowknight Guildmaster"; + case DRUIDGM: + return "Druid Guildmaster"; + case MONKGM: + return "Monk Guildmaster"; + case BARDGM: + return "Bard Guildmaster"; + case ROGUEGM: + return "Rogue Guildmaster"; + case SHAMANGM: + return "Shaman Guildmaster"; + case NECROMANCERGM: + return "Necromancer Guildmaster"; + case WIZARDGM: + return "Wizard Guildmaster"; + case MAGICIANGM: + return "Magician Guildmaster"; + case ENCHANTERGM: + return "Enchanter Guildmaster"; + case BEASTLORDGM: + return "Beastlord Guildmaster"; + case BERSERKERGM: + return "Berserker Guildmaster"; + case MERCHANT: + return "Merchant"; + case ADVENTURERECRUITER: + return "Adventure Recruiter"; + case ADVENTUREMERCHANT: + return "Adventure Merchant"; + case CORPSE_CLASS: + return "Corpse Class"; + case TRIBUTE_MASTER: + return "Tribute Master"; + case GUILD_TRIBUTE_MASTER: + return "Guild Tribute Master"; + default: + return "Unknown"; } } +const char* GetPlayerClassName(uint32 player_class_value, uint8 level) +{ + return GetClassIDName(GetClassIDFromPlayerClassValue(player_class_value), level); +} + +uint32 GetPlayerClassValue(uint8 class_id) +{ + switch (class_id) { + case WARRIOR: + case CLERIC: + case PALADIN: + case RANGER: + case SHADOWKNIGHT: + case DRUID: + case MONK: + case BARD: + case ROGUE: + case SHAMAN: + case NECROMANCER: + case WIZARD: + case MAGICIAN: + case ENCHANTER: + case BEASTLORD: + case BERSERKER: + return class_id; + default: + return PLAYER_CLASS_UNKNOWN; // watch + } +} + +uint32 GetPlayerClassBit(uint8 class_id) +{ + switch (class_id) { + case WARRIOR: + return PLAYER_CLASS_WARRIOR_BIT; + case CLERIC: + return PLAYER_CLASS_CLERIC_BIT; + case PALADIN: + return PLAYER_CLASS_PALADIN_BIT; + case RANGER: + return PLAYER_CLASS_RANGER_BIT; + case SHADOWKNIGHT: + return PLAYER_CLASS_SHADOWKNIGHT_BIT; + case DRUID: + return PLAYER_CLASS_DRUID_BIT; + case MONK: + return PLAYER_CLASS_MONK_BIT; + case BARD: + return PLAYER_CLASS_BARD_BIT; + case ROGUE: + return PLAYER_CLASS_ROGUE_BIT; + case SHAMAN: + return PLAYER_CLASS_SHAMAN_BIT; + case NECROMANCER: + return PLAYER_CLASS_NECROMANCER_BIT; + case WIZARD: + return PLAYER_CLASS_WIZARD_BIT; + case MAGICIAN: + return PLAYER_CLASS_MAGICIAN_BIT; + case ENCHANTER: + return PLAYER_CLASS_ENCHANTER_BIT; + case BEASTLORD: + return PLAYER_CLASS_BEASTLORD_BIT; + case BERSERKER: + return PLAYER_CLASS_BERSERKER_BIT; + default: + return PLAYER_CLASS_UNKNOWN_BIT; + } +} + +uint8 GetClassIDFromPlayerClassValue(uint32 player_class_value) +{ + switch (player_class_value) { + case PLAYER_CLASS_WARRIOR: + case PLAYER_CLASS_CLERIC: + case PLAYER_CLASS_PALADIN: + case PLAYER_CLASS_RANGER: + case PLAYER_CLASS_SHADOWKNIGHT: + case PLAYER_CLASS_DRUID: + case PLAYER_CLASS_MONK: + case PLAYER_CLASS_BARD: + case PLAYER_CLASS_ROGUE: + case PLAYER_CLASS_SHAMAN: + case PLAYER_CLASS_NECROMANCER: + case PLAYER_CLASS_WIZARD: + case PLAYER_CLASS_MAGICIAN: + case PLAYER_CLASS_ENCHANTER: + case PLAYER_CLASS_BEASTLORD: + case PLAYER_CLASS_BERSERKER: + return player_class_value; + default: + return PLAYER_CLASS_UNKNOWN; // watch + } +} + +uint8 GetClassIDFromPlayerClassBit(uint32 player_class_bit) +{ + switch (player_class_bit) { + case PLAYER_CLASS_WARRIOR_BIT: + return WARRIOR; + case PLAYER_CLASS_CLERIC_BIT: + return CLERIC; + case PLAYER_CLASS_PALADIN_BIT: + return PALADIN; + case PLAYER_CLASS_RANGER_BIT: + return RANGER; + case PLAYER_CLASS_SHADOWKNIGHT_BIT: + return SHADOWKNIGHT; + case PLAYER_CLASS_DRUID_BIT: + return DRUID; + case PLAYER_CLASS_MONK_BIT: + return MONK; + case PLAYER_CLASS_BARD_BIT: + return BARD; + case PLAYER_CLASS_ROGUE_BIT: + return ROGUE; + case PLAYER_CLASS_SHAMAN_BIT: + return SHAMAN; + case PLAYER_CLASS_NECROMANCER_BIT: + return NECROMANCER; + case PLAYER_CLASS_WIZARD_BIT: + return WIZARD; + case PLAYER_CLASS_MAGICIAN_BIT: + return MAGICIAN; + case PLAYER_CLASS_ENCHANTER_BIT: + return ENCHANTER; + case PLAYER_CLASS_BEASTLORD_BIT: + return BEASTLORD; + case PLAYER_CLASS_BERSERKER_BIT: + return BERSERKER; + default: + return PLAYER_CLASS_UNKNOWN; // watch + } +} + +bool IsFighterClass(uint8 class_id) +{ + switch (class_id) { + case WARRIOR: + case PALADIN: + case RANGER: + case SHADOWKNIGHT: + case MONK: + case BARD: + case ROGUE: + case BEASTLORD: + case BERSERKER: + return true; + default: + return false; + } +} + +bool IsSpellFighterClass(uint8 class_id) +{ + switch (class_id) { + case PALADIN: + case RANGER: + case SHADOWKNIGHT: + case BEASTLORD: + return true; + default: + return false; + } +} + +bool IsNonSpellFighterClass(uint8 class_id) +{ + switch (class_id) { + case WARRIOR: + case MONK: + case BARD: + case ROGUE: + case BERSERKER: + return true; + default: + return false; + } +} + +bool IsCasterClass(uint8 class_id) +{ + switch (class_id) { + case CLERIC: + case DRUID: + case SHAMAN: + case NECROMANCER: + case WIZARD: + case MAGICIAN: + case ENCHANTER: + return true; + default: + return false; + } +} + +bool IsINTCasterClass(uint8 class_id) +{ + switch (class_id) { + case NECROMANCER: + case WIZARD: + case MAGICIAN: + case ENCHANTER: + return true; + default: + return false; + } +} + +bool IsWISCasterClass(uint8 class_id) +{ + switch (class_id) { + case CLERIC: + case DRUID: + case SHAMAN: + return true; + default: + return false; + } +} + +bool IsPlateClass(uint8 class_id) +{ + switch (class_id) { + case WARRIOR: + case CLERIC: + case PALADIN: + case SHADOWKNIGHT: + case BARD: + return true; + default: + return false; + } +} + +bool IsChainClass(uint8 class_id) +{ + switch (class_id) { + case RANGER: + case ROGUE: + case SHAMAN: + case BERSERKER: + return true; + default: + return false; + } +} + +bool IsLeatherClass(uint8 class_id) +{ + switch (class_id) { + case DRUID: + case MONK: + case BEASTLORD: + return true; + default: + return false; + } +} + +bool IsClothClass(uint8 class_id) +{ + switch (class_id) { + case NECROMANCER: + case WIZARD: + case MAGICIAN: + case ENCHANTER: + return true; + default: + return false; + } +} + +uint8 ClassArmorType(uint8 class_id) +{ + switch (class_id) { + case WARRIOR: + case CLERIC: + case PALADIN: + case SHADOWKNIGHT: + case BARD: + return ARMOR_TYPE_PLATE; + case RANGER: + case ROGUE: + case SHAMAN: + case BERSERKER: + return ARMOR_TYPE_CHAIN; + case DRUID: + case MONK: + case BEASTLORD: + return ARMOR_TYPE_LEATHER; + case NECROMANCER: + case WIZARD: + case MAGICIAN: + case ENCHANTER: + return ARMOR_TYPE_CLOTH; + default: + return ARMOR_TYPE_UNKNOWN; + } +} diff --git a/common/classes.h b/common/classes.h index c2f0c8acf..2ca9a3c4d 100644 --- a/common/classes.h +++ b/common/classes.h @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org) + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemu.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,26 +17,25 @@ */ #ifndef CLASSES_CH #define CLASSES_CH + #include "../common/types.h" -#define Array_Class_UNKNOWN 0 -#define WARRIOR 1 -#define CLERIC 2 -#define PALADIN 3 -#define RANGER 4 -#define SHADOWKNIGHT 5 -#define DRUID 6 -#define MONK 7 -#define BARD 8 -#define ROGUE 9 -#define SHAMAN 10 -#define NECROMANCER 11 -#define WIZARD 12 -#define MAGICIAN 13 -#define ENCHANTER 14 -#define BEASTLORD 15 -#define BERSERKER 16 -#define PLAYER_CLASS_COUNT 16 // used for array defines, must be the count of playable classes +#define WARRIOR 1 +#define CLERIC 2 +#define PALADIN 3 +#define RANGER 4 +#define SHADOWKNIGHT 5 +#define DRUID 6 +#define MONK 7 +#define BARD 8 +#define ROGUE 9 +#define SHAMAN 10 +#define NECROMANCER 11 +#define WIZARD 12 +#define MAGICIAN 13 +#define ENCHANTER 14 +#define BEASTLORD 15 +#define BERSERKER 16 #define WARRIORGM 20 #define CLERICGM 21 #define PALADINGM 22 @@ -58,33 +57,92 @@ #define DISCORD_MERCHANT 59 #define ADVENTURERECRUITER 60 #define ADVENTUREMERCHANT 61 -#define LDON_TREASURE 62 //objects you can use /open on first seen in LDONs -#define CORPSE_CLASS 62 //only seen on Danvi's Corpse in Akheva so far.. -#define TRIBUTE_MASTER 63 -#define GUILD_TRIBUTE_MASTER 64 //not sure +#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs +#define CORPSE_CLASS 62 // only seen on Danvi's Corpse in Akheva so far.. +#define TRIBUTE_MASTER 63 +#define GUILD_TRIBUTE_MASTER 64 // not sure #define NORRATHS_KEEPERS_MERCHANT 67 #define DARK_REIGN_MERCHANT 68 #define FELLOWSHIP_MASTER 69 #define ALT_CURRENCY_MERCHANT 70 #define MERCERNARY_MASTER 71 -#define warrior_1 1 -#define monk_1 64 -#define paladin_1 4 -#define shadow_1 16 -#define bard_1 128 -#define cleric_1 2 -#define necromancer_1 1024 -#define ranger_1 8 -#define druid_1 32 -#define mage_1 4096 -#define wizard_1 2048 -#define enchanter_1 8192 -#define rogue_1 256 -#define shaman_1 512 -#define beastlord_1 16384 -#define berserker_1 32768 -#define call_1 65536 -const char* GetEQClassName(uint8 class_, uint8 level = 0); + +// player class values +#define PLAYER_CLASS_UNKNOWN 0 +#define PLAYER_CLASS_WARRIOR 1 +#define PLAYER_CLASS_CLERIC 2 +#define PLAYER_CLASS_PALADIN 3 +#define PLAYER_CLASS_RANGER 4 +#define PLAYER_CLASS_SHADOWKNIGHT 5 +#define PLAYER_CLASS_DRUID 6 +#define PLAYER_CLASS_MONK 7 +#define PLAYER_CLASS_BARD 8 +#define PLAYER_CLASS_ROGUE 9 +#define PLAYER_CLASS_SHAMAN 10 +#define PLAYER_CLASS_NECROMANCER 11 +#define PLAYER_CLASS_WIZARD 12 +#define PLAYER_CLASS_MAGICIAN 13 +#define PLAYER_CLASS_ENCHANTER 14 +#define PLAYER_CLASS_BEASTLORD 15 +#define PLAYER_CLASS_BERSERKER 16 + +#define PLAYER_CLASS_COUNT 16 + + +// player class bits +#define PLAYER_CLASS_UNKNOWN_BIT 0 +#define PLAYER_CLASS_WARRIOR_BIT 1 +#define PLAYER_CLASS_CLERIC_BIT 2 +#define PLAYER_CLASS_PALADIN_BIT 4 +#define PLAYER_CLASS_RANGER_BIT 8 +#define PLAYER_CLASS_SHADOWKNIGHT_BIT 16 +#define PLAYER_CLASS_DRUID_BIT 32 +#define PLAYER_CLASS_MONK_BIT 64 +#define PLAYER_CLASS_BARD_BIT 128 +#define PLAYER_CLASS_ROGUE_BIT 256 +#define PLAYER_CLASS_SHAMAN_BIT 512 +#define PLAYER_CLASS_NECROMANCER_BIT 1024 +#define PLAYER_CLASS_WIZARD_BIT 2048 +#define PLAYER_CLASS_MAGICIAN_BIT 4096 +#define PLAYER_CLASS_ENCHANTER_BIT 8192 +#define PLAYER_CLASS_BEASTLORD_BIT 16384 +#define PLAYER_CLASS_BERSERKER_BIT 32768 + +#define PLAYER_CLASS_ALL_MASK 65535 // was 65536 + + +#define ARMOR_TYPE_UNKNOWN 0 +#define ARMOR_TYPE_CLOTH 1 +#define ARMOR_TYPE_LEATHER 2 +#define ARMOR_TYPE_CHAIN 3 +#define ARMOR_TYPE_PLATE 4 + +#define ARMOR_TYPE_FIRST ARMOR_TYPE_UNKNOWN +#define ARMOR_TYPE_LAST ARMOR_TYPE_PLATE +#define ARMOR_TYPE_COUNT 5 + + +const char* GetClassIDName(uint8 class_id, uint8 level = 0); +const char* GetPlayerClassName(uint32 player_class_value, uint8 level = 0); + +uint32 GetPlayerClassValue(uint8 class_id); +uint32 GetPlayerClassBit(uint8 class_id); + +uint8 GetClassIDFromPlayerClassValue(uint32 player_class_value); +uint8 GetClassIDFromPlayerClassBit(uint32 player_class_bit); + +bool IsFighterClass(uint8 class_id); +bool IsSpellFighterClass(uint8 class_id); +bool IsNonSpellFighterClass(uint8 class_id); +bool IsCasterClass(uint8 class_id); +bool IsINTCasterClass(uint8 class_id); +bool IsWISCasterClass(uint8 class_id); + +bool IsPlateClass(uint8 class_id); +bool IsChainClass(uint8 class_id); +bool IsLeatherClass(uint8 class_id); +bool IsClothClass(uint8 class_id); +uint8 ClassArmorType(uint8 class_id); + #endif - diff --git a/common/clientversions.h b/common/clientversions.h deleted file mode 100644 index 308a5f091..000000000 --- a/common/clientversions.h +++ /dev/null @@ -1,182 +0,0 @@ -/* -EQEMu: Everquest Server Emulator - -Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY except by those people which sell it, which -are required to give you total support for your newly bought product; -without even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -#ifndef CLIENTVERSIONS_H -#define CLIENTVERSIONS_H - -#include "types.h" - -static const uint32 BIT_Client62 = 0x00000001; // 1 (unsupported - placeholder for scripts) - -static const uint32 BIT_Titanium = 0x00000002; // 2 -static const uint32 BIT_SoF = 0x00000004; // 4 -static const uint32 BIT_SoD = 0x00000008; // 8 -static const uint32 BIT_UF = 0x00000010; // 16 -static const uint32 BIT_RoF = 0x00000020; // 32 -static const uint32 BIT_RoF2 = 0x00000040; // 64 - -static const uint32 BIT_TitaniumAndEarlier = 0x00000003; // 3 -static const uint32 BIT_SoFAndEarlier = 0x00000007; // 7 -static const uint32 BIT_SoDAndEarlier = 0x0000000F; // 15 -static const uint32 BIT_UFAndEarlier = 0x0000001F; // 31 -static const uint32 BIT_RoFAndEarlier = 0x0000003F; // 63 - -static const uint32 BIT_SoFAndLater = 0xFFFFFFFC; // 4294967292 -static const uint32 BIT_SoDAndLater = 0xFFFFFFF8; // 4294967288 -static const uint32 BIT_UFAndLater = 0xFFFFFFF0; // 4294967280 -static const uint32 BIT_RoFAndLater = 0xFFFFFFE0; // 4294967264 -static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0; // 4294967232 - -static const uint32 BIT_AllClients = 0xFFFFFFFF; - -enum class ClientVersion -{ - Unknown = 0, - Client62, // Build: 'Aug 4 2005 15:40:59' - Titanium, // Build: 'Oct 31 2005 10:33:37' - SoF, // Build: 'Sep 7 2007 09:11:49' - SoD, // Build: 'Dec 19 2008 15:22:49' - UF, // Build: 'Jun 8 2010 16:44:32' - RoF, // Build: 'Dec 10 2012 17:35:44' - RoF2, // Build: 'May 10 2013 23:30:08' - - MobNPC, - MobMerc, - MobBot, - MobPet, -}; - -#define CLIENT_VERSION_COUNT 12 -#define LAST_PC_CLIENT ClientVersion::RoF2 -#define LAST_NPC_CLIENT ClientVersion::MobPet - - -static const char* ClientVersionName(ClientVersion version) -{ - switch (version) - { - case ClientVersion::Unknown: - return "Unknown"; - case ClientVersion::Client62: - return "Client62"; - case ClientVersion::Titanium: - return "Titanium"; - case ClientVersion::SoF: - return "SoF"; - case ClientVersion::SoD: - return "SoD"; - case ClientVersion::UF: - return "UF"; - case ClientVersion::RoF: - return "RoF"; - case ClientVersion::RoF2: - return "RoF2"; - case ClientVersion::MobNPC: - return "MobNPC"; - case ClientVersion::MobMerc: - return "MobMerc"; - case ClientVersion::MobBot: - return "MobBot"; - case ClientVersion::MobPet: - return "MobPet"; - default: - return " Invalid ClientVersion"; - }; -} - -static uint32 ClientBitFromVersion(ClientVersion clientVersion) -{ - switch (clientVersion) - { - case ClientVersion::Unknown: - case ClientVersion::Client62: - return 0; - case ClientVersion::Titanium: - case ClientVersion::SoF: - case ClientVersion::SoD: - case ClientVersion::UF: - case ClientVersion::RoF: - case ClientVersion::RoF2: - case ClientVersion::MobNPC: - case ClientVersion::MobMerc: - case ClientVersion::MobBot: - case ClientVersion::MobPet: - return ((uint32)1 << (static_cast(clientVersion) - 1)); - default: - return 0; - } -} - -static ClientVersion ClientVersionFromBit(uint32 clientVersionBit) -{ - switch (clientVersionBit) - { - case (uint32)static_cast(ClientVersion::Unknown): - case ((uint32)1 << (static_cast(ClientVersion::Client62) - 1)): - return ClientVersion::Unknown; - case ((uint32)1 << (static_cast(ClientVersion::Titanium) - 1)): - return ClientVersion::Titanium; - case ((uint32)1 << (static_cast(ClientVersion::SoF) - 1)): - return ClientVersion::SoF; - case ((uint32)1 << (static_cast(ClientVersion::SoD) - 1)): - return ClientVersion::SoD; - case ((uint32)1 << (static_cast(ClientVersion::UF) - 1)): - return ClientVersion::UF; - case ((uint32)1 << (static_cast(ClientVersion::RoF) - 1)): - return ClientVersion::RoF; - case ((uint32)1 << (static_cast(ClientVersion::RoF2) - 1)): - return ClientVersion::RoF2; - case ((uint32)1 << (static_cast(ClientVersion::MobNPC) - 1)): - return ClientVersion::MobNPC; - case ((uint32)1 << (static_cast(ClientVersion::MobMerc) - 1)): - return ClientVersion::MobMerc; - case ((uint32)1 << (static_cast(ClientVersion::MobBot) - 1)): - return ClientVersion::MobBot; - case ((uint32)1 << (static_cast(ClientVersion::MobPet) - 1)): - return ClientVersion::MobPet; - default: - return ClientVersion::Unknown; - } -} - -static uint32 ExpansionFromClientVersion(ClientVersion clientVersion) -{ - switch(clientVersion) - { - case ClientVersion::Unknown: - case ClientVersion::Client62: - case ClientVersion::Titanium: - return 0x000007FFU; - case ClientVersion::SoF: - return 0x00007FFFU; - case ClientVersion::SoD: - return 0x0000FFFFU; - case ClientVersion::UF: - return 0x0001FFFFU; - case ClientVersion::RoF: - case ClientVersion::RoF2: - return 0x000FFFFFU; - default: - return 0; - } -} - -#endif /* CLIENTVERSIONS_H */ diff --git a/common/crash.cpp b/common/crash.cpp index 1f700f151..522d5f171 100644 --- a/common/crash.cpp +++ b/common/crash.cpp @@ -25,7 +25,7 @@ public: } } - Log.Out(Logs::General, Logs::Crash, buffer); + Log(Logs::General, Logs::Crash, buffer); StackWalker::OnOutput(szText); } }; @@ -35,67 +35,67 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo) switch(ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_ACCESS_VIOLATION"); + Log(Logs::General, Logs::Crash, "EXCEPTION_ACCESS_VIOLATION"); break; case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"); + Log(Logs::General, Logs::Crash, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"); break; case EXCEPTION_BREAKPOINT: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_BREAKPOINT"); + Log(Logs::General, Logs::Crash, "EXCEPTION_BREAKPOINT"); break; case EXCEPTION_DATATYPE_MISALIGNMENT: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_DATATYPE_MISALIGNMENT"); + Log(Logs::General, Logs::Crash, "EXCEPTION_DATATYPE_MISALIGNMENT"); break; case EXCEPTION_FLT_DENORMAL_OPERAND: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_DENORMAL_OPERAND"); + Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_DENORMAL_OPERAND"); break; case EXCEPTION_FLT_DIVIDE_BY_ZERO: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_DIVIDE_BY_ZERO"); + Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_DIVIDE_BY_ZERO"); break; case EXCEPTION_FLT_INEXACT_RESULT: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_INEXACT_RESULT"); + Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_INEXACT_RESULT"); break; case EXCEPTION_FLT_INVALID_OPERATION: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_INVALID_OPERATION"); + Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_INVALID_OPERATION"); break; case EXCEPTION_FLT_OVERFLOW: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_OVERFLOW"); + Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_OVERFLOW"); break; case EXCEPTION_FLT_STACK_CHECK: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_STACK_CHECK"); + Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_STACK_CHECK"); break; case EXCEPTION_FLT_UNDERFLOW: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_UNDERFLOW"); + Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_UNDERFLOW"); break; case EXCEPTION_ILLEGAL_INSTRUCTION: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_ILLEGAL_INSTRUCTION"); + Log(Logs::General, Logs::Crash, "EXCEPTION_ILLEGAL_INSTRUCTION"); break; case EXCEPTION_IN_PAGE_ERROR: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_IN_PAGE_ERROR"); + Log(Logs::General, Logs::Crash, "EXCEPTION_IN_PAGE_ERROR"); break; case EXCEPTION_INT_DIVIDE_BY_ZERO: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_INT_DIVIDE_BY_ZERO"); + Log(Logs::General, Logs::Crash, "EXCEPTION_INT_DIVIDE_BY_ZERO"); break; case EXCEPTION_INT_OVERFLOW: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_INT_OVERFLOW"); + Log(Logs::General, Logs::Crash, "EXCEPTION_INT_OVERFLOW"); break; case EXCEPTION_INVALID_DISPOSITION: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_INVALID_DISPOSITION"); + Log(Logs::General, Logs::Crash, "EXCEPTION_INVALID_DISPOSITION"); break; case EXCEPTION_NONCONTINUABLE_EXCEPTION: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_NONCONTINUABLE_EXCEPTION"); + Log(Logs::General, Logs::Crash, "EXCEPTION_NONCONTINUABLE_EXCEPTION"); break; case EXCEPTION_PRIV_INSTRUCTION: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_PRIV_INSTRUCTION"); + Log(Logs::General, Logs::Crash, "EXCEPTION_PRIV_INSTRUCTION"); break; case EXCEPTION_SINGLE_STEP: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_SINGLE_STEP"); + Log(Logs::General, Logs::Crash, "EXCEPTION_SINGLE_STEP"); break; case EXCEPTION_STACK_OVERFLOW: - Log.Out(Logs::General, Logs::Crash, "EXCEPTION_STACK_OVERFLOW"); + Log(Logs::General, Logs::Crash, "EXCEPTION_STACK_OVERFLOW"); break; default: - Log.Out(Logs::General, Logs::Crash, "Unknown Exception"); + Log(Logs::General, Logs::Crash, "Unknown Exception"); break; } diff --git a/common/data_verification.h b/common/data_verification.h index 9da85a579..fe1152cb4 100644 --- a/common/data_verification.h +++ b/common/data_verification.h @@ -1,5 +1,6 @@ /* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net) + + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,36 +14,42 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #ifndef COMMON_DATA_VERIFICATION_H #define COMMON_DATA_VERIFICATION_H #include + namespace EQEmu { + template + T Clamp(const T& value, const T& lower, const T& upper) { + return std::max(lower, std::min(value, upper)); + } -template -T Clamp(const T& value, const T& lower, const T& upper) { - return std::max(lower, std::min(value, upper)); -} + template + T ClampLower(const T& value, const T& lower) { + return std::max(lower, value); + } -template -T ClampLower(const T& value, const T& lower) { - return std::max(lower, value); -} + template + T ClampUpper(const T& value, const T& upper) { + return std::min(value, upper); + } -template -T ClampUpper(const T& value, const T& upper) { - return std::min(value, upper); -} + template + bool ValueWithin(const T& value, const T& lower, const T& upper) { + return value >= lower && value <= upper; + } -template -bool ValueWithin(const T& value, const T& lower, const T& upper) { - return value >= lower && value <= upper; -} + template + bool ValueWithin(const T1& value, const T2& lower, const T3& upper) { + return value >= (T1)lower && value <= (T1)upper; + } -} +} /*EQEmu*/ -#endif +#endif /*COMMON_DATA_VERIFICATION_H*/ diff --git a/common/database.cpp b/common/database.cpp index cdafaa165..62a8453d1 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -48,7 +49,6 @@ extern Client client; Database::Database () { - DBInitVars(); } /* @@ -57,7 +57,6 @@ Establish a connection to a mysql database with the supplied parameters Database::Database(const char* host, const char* user, const char* passwd, const char* database, uint32 port) { - DBInitVars(); Connect(host, user, passwd, database, port); } @@ -65,34 +64,21 @@ bool Database::Connect(const char* host, const char* user, const char* passwd, c uint32 errnum= 0; char errbuf[MYSQL_ERRMSG_SIZE]; if (!Open(host, user, passwd, database, port, &errnum, errbuf)) { - Log.Out(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf); + Log(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf); return false; } else { - Log.Out(Logs::General, Logs::Status, "Using database '%s' at %s:%d", database, host,port); + Log(Logs::General, Logs::Status, "Using database '%s' at %s:%d", database, host,port); return true; } } -void Database::DBInitVars() { - varcache_array = 0; - varcache_max = 0; - varcache_lastupdate = 0; -} - /* Close the connection to the database */ Database::~Database() { - unsigned int x; - if (varcache_array) { - for (x=0; x 0){ - Log.Out(Logs::General, Logs::World_Server, "Account: %i tried to request name: %s, but it is already taken...", account_id, name); + Log(Logs::General, Logs::World_Server, "Account: %i tried to request name: %s, but it is already taken...", account_id, name); return false; } } @@ -304,20 +290,24 @@ bool Database::ReserveName(uint32 account_id, char* name) { bool Database::DeleteCharacter(char *name) { uint32 charid = 0; if(!name || !strlen(name)) { - Log.Out(Logs::General, Logs::World_Server, "DeleteCharacter: request to delete without a name (empty char slot)"); + Log(Logs::General, Logs::World_Server, "DeleteCharacter: request to delete without a name (empty char slot)"); return false; } - Log.Out(Logs::General, Logs::World_Server, "Database::DeleteCharacter name : '%s'", name); + Log(Logs::General, Logs::World_Server, "Database::DeleteCharacter name : '%s'", name); /* Get id from character_data before deleting record so we can clean up the rest of the tables */ std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", name); auto results = QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { charid = atoi(row[0]); } - if (charid <= 0){ std::cerr << "Database::DeleteCharacter :: Character not found, stopping delete...\n"; return false; } + if (charid <= 0){ + Log(Logs::General, Logs::Error, "Database::DeleteCharacter :: Character (%s) not found, stopping delete...", name); + return false; + } query = StringFormat("DELETE FROM `quest_globals` WHERE `charid` = '%d'", charid); QueryDatabase(query); query = StringFormat("DELETE FROM `character_activities` WHERE `charid` = '%d'", charid); QueryDatabase(query); query = StringFormat("DELETE FROM `character_enabledtasks` WHERE `charid` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_tasks` WHERE `charid` = '%d'", charid); QueryDatabase(query); query = StringFormat("DELETE FROM `completed_tasks` WHERE `charid` = '%d'", charid); QueryDatabase(query); query = StringFormat("DELETE FROM `friends` WHERE `charid` = '%d'", charid); QueryDatabase(query); query = StringFormat("DELETE FROM `mail` WHERE `charid` = '%d'", charid); QueryDatabase(query); @@ -638,10 +628,23 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe /* Save Bind Points */ query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)" " VALUES (%u, %u, %u, %f, %f, %f, %f, %i), " + "(%u, %u, %u, %f, %f, %f, %f, %i), " + "(%u, %u, %u, %f, %f, %f, %f, %i), " + "(%u, %u, %u, %f, %f, %f, %f, %i), " "(%u, %u, %u, %f, %f, %f, %f, %i)", character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading, 0, + character_id, pp->binds[1].zoneId, 0, pp->binds[1].x, pp->binds[1].y, pp->binds[1].z, pp->binds[1].heading, 1, + character_id, pp->binds[2].zoneId, 0, pp->binds[2].x, pp->binds[2].y, pp->binds[2].z, pp->binds[2].heading, 2, + character_id, pp->binds[3].zoneId, 0, pp->binds[3].x, pp->binds[3].y, pp->binds[3].z, pp->binds[3].heading, 3, character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading, 4 - ); results = QueryDatabase(query); + ); results = QueryDatabase(query); + + /* HoTT Ability */ + if(RuleB(Character, GrantHoTTOnCreate)) + { + query = StringFormat("INSERT INTO `character_leadership_abilities` (id, slot, rank) VALUES (%u, %i, %i)", character_id, 14, 1); + results = QueryDatabase(query); + } /* Save Skills */ int firstquery = 0; @@ -677,14 +680,14 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe } /* This only for new Character creation storing */ -bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv) { +bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv) { uint32 charid = 0; char zone[50]; float x, y, z; charid = GetCharacterID(pp->name); if(!charid) { - Log.Out(Logs::General, Logs::Error, "StoreCharacter: no character id"); + Log(Logs::General, Logs::Error, "StoreCharacter: no character id"); return false; } @@ -705,8 +708,8 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven /* Insert starting inventory... */ std::string invquery; - for (int16 i=EmuConstants::EQUIPMENT_BEGIN; i<=EmuConstants::BANK_BAGS_END;) { - const ItemInst* newinv = inv->GetItem(i); + for (int16 i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::BANK_BAGS_END;) { + const EQEmu::ItemInstance* newinv = inv->GetItem(i); if (newinv) { invquery = StringFormat("INSERT INTO `inventory` (charid, slotid, itemid, charges, color) VALUES (%u, %i, %u, %i, %u)", charid, i, newinv->GetItem()->ID, newinv->GetCharges(), newinv->GetColor()); @@ -714,16 +717,16 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven auto results = QueryDatabase(invquery); } - if (i == MainCursor) { - i = EmuConstants::GENERAL_BAGS_BEGIN; + if (i == EQEmu::inventory::slotCursor) { + i = EQEmu::legacy::GENERAL_BAGS_BEGIN; continue; } - else if (i == EmuConstants::CURSOR_BAG_END) { - i = EmuConstants::BANK_BEGIN; + else if (i == EQEmu::legacy::CURSOR_BAG_END) { + i = EQEmu::legacy::BANK_BEGIN; continue; } - else if (i == EmuConstants::BANK_END) { - i = EmuConstants::BANK_BAGS_BEGIN; + else if (i == EQEmu::legacy::BANK_END) { + i = EQEmu::legacy::BANK_BAGS_BEGIN; continue; } i++; @@ -836,7 +839,7 @@ void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID } -void Database::GetCharName(uint32 char_id, char* name) { +void Database::GetCharName(uint32 char_id, char* name) { std::string query = StringFormat("SELECT `name` FROM `character_data` WHERE id='%i'", char_id); auto results = QueryDatabase(query); @@ -851,145 +854,69 @@ void Database::GetCharName(uint32 char_id, char* name) { } bool Database::LoadVariables() { - char *query = nullptr; - - auto results = QueryDatabase(query, LoadVariables_MQ(&query)); + auto results = QueryDatabase(StringFormat("SELECT varname, value, unix_timestamp() FROM variables where unix_timestamp(ts) >= %d", varcache.last_update)); if (!results.Success()) - { - safe_delete_array(query); return false; - } - - safe_delete_array(query); - return LoadVariables_result(std::move(results)); -} - -uint32 Database::LoadVariables_MQ(char** query) -{ - return MakeAnyLenString(query, "SELECT varname, value, unix_timestamp() FROM variables where unix_timestamp(ts) >= %d", varcache_lastupdate); -} - -// always returns true? not sure about this. -bool Database::LoadVariables_result(MySQLRequestResult results) -{ - uint32 i = 0; - LockMutex lock(&Mvarcache); if (results.RowCount() == 0) return true; - if (!varcache_array) { - varcache_max = results.RowCount(); - varcache_array = new VarCache_Struct*[varcache_max]; - for (i=0; ivarname, row[0]) == 0) { - delete varcache_array[i]; - varcache_array[i] = (VarCache_Struct*) new uint8[sizeof(VarCache_Struct) + strlen(row[1]) + 1]; - strn0cpy(varcache_array[i]->varname, row[0], sizeof(varcache_array[i]->varname)); - strcpy(varcache_array[i]->value, row[1]); - break; - } - } - else { - varcache_array[i] = (VarCache_Struct*) new uint8[sizeof(VarCache_Struct) + strlen(row[1]) + 1]; - strcpy(varcache_array[i]->varname, row[0]); - strcpy(varcache_array[i]->value, row[1]); - break; - } - } + std::string key, value; + for (auto row = results.begin(); row != results.end(); ++row) { + varcache.last_update = atoi(row[2]); // ahh should we be comparing if this is newer? + key = row[0]; + value = row[1]; + std::transform(std::begin(key), std::end(key), std::begin(key), ::tolower); // keys are lower case, DB doesn't have to be + varcache.Add(key, value); } - uint32 max_used = 0; - for (i=0; i max_used) - max_used = i; - } - } - - varcache_max = max_used + 1; - return true; } // Gets variable from 'variables' table -bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_len) { - varvalue[0] = '\0'; +bool Database::GetVariable(std::string varname, std::string &varvalue) +{ + varvalue.clear(); LockMutex lock(&Mvarcache); - if (strlen(varname) <= 1) - return false; - for (uint32 i=0; ivarname, varname) == 0) { - snprintf(varvalue, varvalue_len, "%s", varcache_array[i]->value); - varvalue[varvalue_len-1] = 0; - return true; - } - } - else - return false; + if (varname.empty()) + return false; + + std::transform(std::begin(varname), std::end(varname), std::begin(varname), ::tolower); // all keys are lower case + auto tmp = varcache.Get(varname); + if (tmp) { + varvalue = *tmp; + return true; } return false; } -bool Database::SetVariable(const char* varname_in, const char* varvalue_in) { - - char *varname,*varvalue; - - varname=(char *)malloc(strlen(varname_in)*2+1); - varvalue=(char *)malloc(strlen(varvalue_in)*2+1); - DoEscapeString(varname, varname_in, strlen(varname_in)); - DoEscapeString(varvalue, varvalue_in, strlen(varvalue_in)); - - std::string query = StringFormat("Update variables set value='%s' WHERE varname like '%s'", varvalue, varname); +bool Database::SetVariable(const std::string varname, const std::string &varvalue) +{ + std::string escaped_name = EscapeString(varname); + std::string escaped_value = EscapeString(varvalue); + std::string query = StringFormat("Update variables set value='%s' WHERE varname like '%s'", escaped_value.c_str(), escaped_name.c_str()); auto results = QueryDatabase(query); if (!results.Success()) - { - free(varname); - free(varvalue); return false; - } if (results.RowsAffected() == 1) { LoadVariables(); // refresh cache - free(varname); - free(varvalue); return true; } - query = StringFormat("Insert Into variables (varname, value) values ('%s', '%s')", varname, varvalue); + query = StringFormat("Insert Into variables (varname, value) values ('%s', '%s')", escaped_name.c_str(), escaped_value.c_str()); results = QueryDatabase(query); - free(varname); - free(varvalue); if (results.RowsAffected() != 1) return false; - + LoadVariables(); // refresh cache return true; } @@ -1555,8 +1482,9 @@ void Database::SetFirstLogon(uint32 CharID, uint8 firstlogon) { QueryDatabase(query); } -void Database::AddReport(std::string who, std::string against, std::string lines) { - char *escape_str = new char[lines.size()*2+1]; +void Database::AddReport(std::string who, std::string against, std::string lines) +{ + auto escape_str = new char[lines.size() * 2 + 1]; DoEscapeString(escape_str, lines.c_str(), lines.size()); std::string query = StringFormat("INSERT INTO reports (name, reported, reported_text) VALUES('%s', '%s', '%s')", EscapeString(who).c_str(), EscapeString(against).c_str(), escape_str); @@ -1572,7 +1500,7 @@ void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ism auto results = QueryDatabase(query); if (!results.Success()) - Log.Out(Logs::General, Logs::Error, "Error deleting character from group id: %s", results.ErrorMessage().c_str()); + Log(Logs::General, Logs::Error, "Error deleting character from group id: %s", results.ErrorMessage().c_str()); return; } @@ -1615,7 +1543,7 @@ uint32 Database::GetGroupID(const char* name){ if (results.RowCount() == 0) { // Commenting this out until logging levels can prevent this from going to console - //Log.Out(Logs::General, Logs::None,, "Character not in a group: %s", name); + //Log(Logs::General, Logs::None,, "Character not in a group: %s", name); return 0; } @@ -1662,7 +1590,7 @@ void Database::SetGroupLeaderName(uint32 gid, const char* name) { result = QueryDatabase(query); if(!result.Success()) { - Log.Out(Logs::General, Logs::None, "Error in Database::SetGroupLeaderName: %s", result.ErrorMessage().c_str()); + Log(Logs::General, Logs::None, "Error in Database::SetGroupLeaderName: %s", result.ErrorMessage().c_str()); } } @@ -1859,7 +1787,7 @@ const char* Database::GetRaidLeaderName(uint32 raid_id) auto results = QueryDatabase(query); if (!results.Success()) { - Log.Out(Logs::General, Logs::Debug, "Unable to get Raid Leader Name for Raid ID: %u", raid_id); + Log(Logs::General, Logs::Debug, "Unable to get Raid Leader Name for Raid ID: %u", raid_id); return "UNKNOWN"; } @@ -2128,6 +2056,8 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id) void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) { + // log_settings previously initialized to '0' by EQEmuLogSys::LoadLogSettingsDefaults() + std::string query = "SELECT " "log_category_id, " @@ -2141,10 +2071,13 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) auto results = QueryDatabase(query); int log_category = 0; - Log.file_logs_enabled = false; + LogSys.file_logs_enabled = false; for (auto row = results.begin(); row != results.end(); ++row) { log_category = atoi(row[0]); + if (log_category <= Logs::None || log_category >= Logs::MaxCategoryID) + continue; + log_settings[log_category].log_to_console = atoi(row[2]); log_settings[log_category].log_to_file = atoi(row[3]); log_settings[log_category].log_to_gmsay = atoi(row[4]); @@ -2164,7 +2097,7 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) If we go through this whole loop and nothing is set to any debug level, there is no point to create a file or keep anything open */ if (log_settings[log_category].log_to_file > 0){ - Log.file_logs_enabled = true; + LogSys.file_logs_enabled = true; } } } @@ -2186,7 +2119,7 @@ struct TimeOfDay_Struct Database::LoadTime(time_t &realtime) auto results = QueryDatabase(query); if (!results.Success() || results.RowCount() == 0){ - Log.Out(Logs::Detail, Logs::World_Server, "Loading EQ time of day failed. Using defaults."); + Log(Logs::Detail, Logs::World_Server, "Loading EQ time of day failed. Using defaults."); eqTime.minute = 0; eqTime.hour = 9; eqTime.day = 1; @@ -2216,3 +2149,27 @@ bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year return results.Success(); } + +int Database::GetIPExemption(std::string account_ip) { + std::string query = StringFormat("SELECT `exemption_amount` FROM `ip_exemptions` WHERE `exemption_ip` = '%s'", account_ip.c_str()); + auto results = QueryDatabase(query); + + if (results.Success() && results.RowCount() > 0) { + auto row = results.begin(); + return atoi(row[0]); + } + + return RuleI(World, MaxClientsPerIP); +} + +int Database::GetInstanceID(uint32 char_id, uint32 zone_id) { + std::string query = StringFormat("SELECT instance_list.id FROM instance_list INNER JOIN instance_list_player ON instance_list.id = instance_list_player.id WHERE instance_list.zone = '%i' AND instance_list_player.charid = '%i'", zone_id, char_id); + auto results = QueryDatabase(query); + + if (results.Success() && results.RowCount() > 0) { + auto row = results.begin(); + return atoi(row[0]);; + } + + return 0; +} diff --git a/common/database.h b/common/database.h index 02110b9a6..6f3fd0642 100644 --- a/common/database.h +++ b/common/database.h @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2003 EQEMu Development Team (http://eqemulator.net) + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,10 +37,14 @@ //atoi is not uint32 or uint32 safe!!!! #define atoul(str) strtoul(str, nullptr, 10) -class Inventory; class MySQLRequestResult; class Client; +namespace EQEmu +{ + class InventoryProfile; +} + struct EventLogDetails_Struct { uint32 id; char accountname[64]; @@ -67,8 +71,14 @@ struct npcDecayTimes_Struct { struct VarCache_Struct { - char varname[26]; - char value[0]; + std::map m_cache; + uint32 last_update; + VarCache_Struct() : last_update(0) { } + void Add(const std::string &key, const std::string &value) { m_cache[key] = value; } + const std::string *Get(const std::string &key) { + auto it = m_cache.find(key); + return (it != m_cache.end() ? &it->second : nullptr); + } }; class PTimerList; @@ -88,7 +98,7 @@ class Database : public DBcore { public: Database(); Database(const char* host, const char* user, const char* passwd, const char* database,uint32 port); - bool Connect(const char* host, const char* user, const char* passwd, const char* database,uint32 port); + bool Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port); ~Database(); /* Character Creation */ @@ -103,7 +113,7 @@ public: bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp); bool SetHackerFlag(const char* accountname, const char* charactername, const char* hacked); bool SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone); - bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv); + bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv); bool UpdateName(const char* oldname, const char* newname); /* General Information Queries */ @@ -180,6 +190,10 @@ public: void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus); void SetAgreementFlag(uint32 acctid); + + int GetIPExemption(std::string account_ip); + + int GetInstanceID(uint32 char_id, uint32 zone_id); /* Groups */ @@ -215,11 +229,9 @@ public: /* Database Variables */ - bool GetVariable(const char* varname, char* varvalue, uint16 varvalue_len); - bool SetVariable(const char* varname, const char* varvalue); + bool GetVariable(std::string varname, std::string &varvalue); + bool SetVariable(const std::string varname, const std::string &varvalue); bool LoadVariables(); - uint32 LoadVariables_MQ(char** query); - bool LoadVariables_result(MySQLRequestResult results); /* General Queries */ @@ -256,14 +268,10 @@ public: void LoadLogSettings(EQEmuLogSys::LogSettings* log_settings); private: - void DBInitVars(); - std::map zonename_array; - Mutex Mvarcache; - uint32 varcache_max; - VarCache_Struct** varcache_array; - uint32 varcache_lastupdate; + Mutex Mvarcache; + VarCache_Struct varcache; /* Groups, utility methods. */ void ClearAllGroupLeaders(); diff --git a/common/database_conversions.cpp b/common/database_conversions.cpp index c7428c07e..d5cdbdb25 100644 --- a/common/database_conversions.cpp +++ b/common/database_conversions.cpp @@ -186,7 +186,7 @@ namespace Convert { /*002*/ uint32 HP; /*006*/ uint32 Mana; /*010*/ Convert::SpellBuff_Struct Buffs[BUFF_COUNT]; - /*510*/ uint32 Items[_MaterialCount]; + /*510*/ uint32 Items[EQEmu::textures::materialCount]; /*546*/ char Name[64]; /*610*/ }; @@ -227,9 +227,9 @@ namespace Convert { /*0304*/ uint8 ability_time_minutes; /*0305*/ uint8 ability_time_hours; //place holder /*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag? - /*0312*/ uint32 item_material[_MaterialCount]; // Item texture/material of worn/held items + /*0312*/ uint32 item_material[EQEmu::textures::materialCount]; // Item texture/material of worn/held items /*0348*/ uint8 unknown0348[44]; - /*0392*/ Convert::Color_Struct item_tint[_MaterialCount]; + /*0392*/ Convert::Color_Struct item_tint[EQEmu::textures::materialCount]; /*0428*/ Convert::AA_Array aa_array[MAX_PP_AA_ARRAY]; /*2348*/ float unknown2384; //seen ~128, ~47 /*2352*/ char servername[32]; // length probably not right @@ -330,7 +330,7 @@ namespace Convert { /*7212*/ uint32 tribute_points; /*7216*/ uint32 unknown7252; /*7220*/ uint32 tribute_active; //1=active - /*7224*/ Convert::Tribute_Struct tributes[EmuConstants::TRIBUTE_SIZE]; + /*7224*/ Convert::Tribute_Struct tributes[EQEmu::legacy::TRIBUTE_SIZE]; /*7264*/ Convert::Disciplines_Struct disciplines; /*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use) /*7744*/ char unknown7780[160]; @@ -472,31 +472,18 @@ bool Database::CheckDatabaseConversions() { CheckDatabaseConvertPPDeblob(); CheckDatabaseConvertCorpseDeblob(); - /* Fetch Automatic Upgrade Script */ - if (!std::ifstream("eqemu_update.pl")){ + /* Fetch EQEmu Server script */ + if (!std::ifstream("eqemu_server.pl")){ std::cout << "Pulling down automatic database upgrade script..." << std::endl; #ifdef _WIN32 - system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_update.pl'); if ($response->is_success){ open(FILE, '> eqemu_update.pl'); print FILE $response->decoded_content; close(FILE); }\""); + system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl'); if ($response->is_success){ open(FILE, '> eqemu_server.pl'); print FILE $response->decoded_content; close(FILE); }\""); #else - system("wget --no-check-certificate -O eqemu_update.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_update.pl"); + system("wget --no-check-certificate -O eqemu_server.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl"); #endif } - /* - Automatic (Database) Upgrade Script - Script: eqemu_update.pl V 1 - the number that world passes to the script will - force the script to check for a newer version to update itself with - eqemu_update.pl ran_from_world - won't bring up a menu if your database versions match - eqemu_update.pl - ran standalone will bring up a menu prompt - */ - - /* Check for a new version of this script, the arg passed - would have to be higher than the copy they have downloaded - locally and they will re fetch */ - system("perl eqemu_update.pl V 14"); - - /* Run Automatic Database Upgrade Script */ - system("perl eqemu_update.pl ran_from_world"); + /* Run EQEmu Server script (Checks for database updates) */ + system("perl eqemu_server.pl ran_from_world"); return true; } @@ -1416,7 +1403,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){ if (rquery != ""){ results = QueryDatabase(rquery); } /* Run Material Color Convert */ first_entry = 0; rquery = ""; - for (i = 0; i < _MaterialCount; i++){ + for (i = EQEmu::textures::textureBegin; i < EQEmu::textures::materialCount; i++){ if (pp->item_tint[i].color > 0){ if (first_entry != 1){ rquery = StringFormat("REPLACE INTO `character_material` (id, slot, blue, green, red, use_tint, color) VALUES (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color); @@ -1428,7 +1415,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){ if (rquery != ""){ results = QueryDatabase(rquery); } /* Run Tribute Convert */ first_entry = 0; rquery = ""; - for (i = 0; i < EmuConstants::TRIBUTE_SIZE; i++){ + for (i = 0; i < EQEmu::legacy::TRIBUTE_SIZE; i++){ if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != 4294967295){ if (first_entry != 1){ rquery = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); diff --git a/common/dbcore.cpp b/common/dbcore.cpp index 76e87cde1..0468bdc77 100644 --- a/common/dbcore.cpp +++ b/common/dbcore.cpp @@ -98,20 +98,20 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo pStatus = Error; - char *errorBuffer = new char[MYSQL_ERRMSG_SIZE]; + auto errorBuffer = new char[MYSQL_ERRMSG_SIZE]; snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32)mysql_errno(&mysql), errorBuffer); } - char *errorBuffer = new char[MYSQL_ERRMSG_SIZE]; + auto errorBuffer = new char[MYSQL_ERRMSG_SIZE]; snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); /* Implement Logging at the Root */ if (mysql_errno(&mysql) > 0 && strlen(query) > 0){ - if (Log.log_settings[Logs::MySQLError].is_category_enabled == 1) - Log.Out(Logs::General, Logs::MySQLError, "%i: %s \n %s", mysql_errno(&mysql), mysql_error(&mysql), query); + if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1) + Log(Logs::General, Logs::MySQLError, "%i: %s \n %s", mysql_errno(&mysql), mysql_error(&mysql), query); } return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql),errorBuffer); @@ -127,12 +127,14 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql)); - if (Log.log_settings[Logs::MySQLQuery].is_category_enabled == 1) + if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) { - if ((strncasecmp(query, "select", 6) == 0)) - Log.Out(Logs::General, Logs::MySQLQuery, "%s (%u row%s returned)", query, requestResult.RowCount(), requestResult.RowCount() == 1 ? "" : "s"); - else - Log.Out(Logs::General, Logs::MySQLQuery, "%s (%u row%s affected)", query, requestResult.RowsAffected(), requestResult.RowsAffected() == 1 ? "" : "s"); + if ((strncasecmp(query, "select", 6) == 0)) { + Log(Logs::General, Logs::MySQLQuery, "%s (%u row%s returned)", query, requestResult.RowCount(), requestResult.RowCount() == 1 ? "" : "s"); + } + else { + Log(Logs::General, Logs::MySQLQuery, "%s (%u row%s affected)", query, requestResult.RowsAffected(), requestResult.RowsAffected() == 1 ? "" : "s"); + } } return requestResult; diff --git a/common/dbcore.h b/common/dbcore.h index b23d58a9e..6fd09218e 100644 --- a/common/dbcore.h +++ b/common/dbcore.h @@ -2,7 +2,7 @@ #define DBCORE_H #ifdef _WINDOWS - #include + #include #include #endif diff --git a/common/deity.cpp b/common/deity.cpp new file mode 100644 index 000000000..b8a2d87d7 --- /dev/null +++ b/common/deity.cpp @@ -0,0 +1,149 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "deity.h" + + +EQEmu::deity::DeityTypeBit EQEmu::deity::ConvertDeityTypeToDeityTypeBit(DeityType deity_type) +{ + switch (deity_type) { + case DeityBertoxxulous: + return bit_DeityBertoxxulous; + case DeityBrellSirilis: + return bit_DeityBrellSirilis; + case DeityCazicThule: + return bit_DeityCazicThule; + case DeityErollisiMarr: + return bit_DeityErollisiMarr; + case DeityBristlebane: + return bit_DeityBristlebane; + case DeityInnoruuk: + return bit_DeityInnoruuk; + case DeityKarana: + return bit_DeityKarana; + case DeityMithanielMarr: + return bit_DeityMithanielMarr; + case DeityPrexus: + return bit_DeityPrexus; + case DeityQuellious: + return bit_DeityQuellious; + case DeityRallosZek: + return bit_DeityRallosZek; + case DeityRodcetNife: + return bit_DeityRodcetNife; + case DeitySolusekRo: + return bit_DeitySolusekRo; + case DeityTheTribunal: + return bit_DeityTheTribunal; + case DeityTunare: + return bit_DeityTunare; + case DeityVeeshan: + return bit_DeityVeeshan; + case DeityAgnostic_LB: + case DeityAgnostic: + return bit_DeityAgnostic; + default: + return bit_DeityAll; + }; +} + +EQEmu::deity::DeityType EQEmu::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit) +{ + switch (deity_type_bit) { + case bit_DeityAgnostic: + return DeityAgnostic; + case bit_DeityBertoxxulous: + return DeityBertoxxulous; + case bit_DeityBrellSirilis: + return DeityBrellSirilis; + case bit_DeityCazicThule: + return DeityCazicThule; + case bit_DeityErollisiMarr: + return DeityErollisiMarr; + case bit_DeityBristlebane: + return DeityBristlebane; + case bit_DeityInnoruuk: + return DeityInnoruuk; + case bit_DeityKarana: + return DeityKarana; + case bit_DeityMithanielMarr: + return DeityMithanielMarr; + case bit_DeityPrexus: + return DeityPrexus; + case bit_DeityQuellious: + return DeityQuellious; + case bit_DeityRallosZek: + return DeityRallosZek; + case bit_DeityRodcetNife: + return DeityRodcetNife; + case bit_DeitySolusekRo: + return DeitySolusekRo; + case bit_DeityTheTribunal: + return DeityTheTribunal; + case bit_DeityTunare: + return DeityTunare; + case bit_DeityVeeshan: + return DeityVeeshan; + default: + return DeityUnknown; + }; +} + +const char* EQEmu::deity::DeityName(DeityType deity_type) +{ + switch (deity_type) { + case DeityBertoxxulous: + return "Bertoxxulous"; + case DeityBrellSirilis: + return "Brell Serilis"; + case DeityCazicThule: + return "Cazic-Thule"; + case DeityErollisiMarr: + return "Erollisi Marr"; + case DeityBristlebane: + return "Bristlebane"; + case DeityInnoruuk: + return "Innoruuk"; + case DeityKarana: + return "Karana"; + case DeityMithanielMarr: + return "Mithaniel Marr"; + case DeityPrexus: + return "Prexus"; + case DeityQuellious: + return "Quellious"; + case DeityRallosZek: + return "Rallos Zek"; + case DeityRodcetNife: + return "Rodcet Nife"; + case DeitySolusekRo: + return "Solusek Ro"; + case DeityTheTribunal: + return "The Tribunal"; + case DeityTunare: + return "Tunare"; + case DeityVeeshan: + return "Veeshan"; + case DeityAgnostic_LB: + case DeityAgnostic: + return "Agnostic"; + default: + return "Unknown"; + }; +} diff --git a/common/deity.h b/common/deity.h index 486d17263..f754352a0 100644 --- a/common/deity.h +++ b/common/deity.h @@ -1,5 +1,6 @@ /* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org) + + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemu.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,154 +14,68 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef DEITY_H -#define DEITY_H + +#ifndef COMMON_DEITY_H +#define COMMON_DEITY_H #include "types.h" -#include -// NOTE: This code is not fully implemented since there are no references in the existing code -/* -** Diety types -** -** (ref: eqstr_us.txt) -** -** (Another orphaned enumeration...) -*/ -enum DeityTypes +namespace EQEmu { -/*----*/ DeityUnknown = 0, -/*----*/ DeityAgnostic_LB = 140, -/*3251*/ DeityBertoxxulous = 201, -/*3262*/ DeityBrellSirilis, -/*3253*/ DeityCazicThule, -/*3256*/ DeityErollisiMarr, -/*3252*/ DeityBristlebane, -/*3254*/ DeityInnoruuk, -/*3255*/ DeityKarana, -/*3257*/ DeityMithanielMarr, -/*3259*/ DeityPrexus, -/*3260*/ DeityQuellious, -/*3266*/ DeityRallosZek, -/*3258*/ DeityRodcetNife, -/*3261*/ DeitySolusekRo, -/*3263*/ DeityTheTribunal, -/*3264*/ DeityTunare, -/*3265*/ DeityVeeshan, -/*3250*/ DeityAgnostic = 396 -}; + namespace deity { + enum DeityType { + DeityUnknown = 0, + DeityAgnostic_LB = 140, + DeityBertoxxulous = 201, + DeityBrellSirilis, + DeityCazicThule, + DeityErollisiMarr, + DeityBristlebane, + DeityInnoruuk, + DeityKarana, + DeityMithanielMarr, + DeityPrexus, + DeityQuellious, + DeityRallosZek, + DeityRodcetNife, + DeitySolusekRo, + DeityTheTribunal, + DeityTunare, + DeityVeeshan, + DeityAgnostic = 396 + }; -/* -** Deity type bits -** -** (New orphan, but make use of it!) -*/ -enum DeityTypeBits : uint32 -{ - BIT_DeityAll = 0x00000000, - BIT_DeityAgnostic = 0x00000001, - BIT_DeityBertoxxulous = 0x00000002, - BIT_DeityBrellSirilis = 0x00000004, - BIT_DeityCazicThule = 0x00000008, - BIT_DeityErollisiMarr = 0x00000010, - BIT_DeityBristlebane = 0x00000020, - BIT_DeityInnoruuk = 0x00000040, - BIT_DeityKarana = 0x00000080, - BIT_DeityMithanielMarr = 0x00000100, - BIT_DeityPrexus = 0x00000200, - BIT_DeityQuellious = 0x00000400, - BIT_DeityRallosZek = 0x00000800, - BIT_DeityRodcetNife = 0x00001000, - BIT_DeitySolusekRo = 0x00002000, - BIT_DeityTheTribunal = 0x00004000, - BIT_DeityTunare = 0x00008000, - BIT_DeityVeeshan = 0x00010000 -}; + enum DeityTypeBit : uint32 { + bit_DeityNone = 0x00000000, + bit_DeityAgnostic = 0x00000001, + bit_DeityBertoxxulous = 0x00000002, + bit_DeityBrellSirilis = 0x00000004, + bit_DeityCazicThule = 0x00000008, + bit_DeityErollisiMarr = 0x00000010, + bit_DeityBristlebane = 0x00000020, + bit_DeityInnoruuk = 0x00000040, + bit_DeityKarana = 0x00000080, + bit_DeityMithanielMarr = 0x00000100, + bit_DeityPrexus = 0x00000200, + bit_DeityQuellious = 0x00000400, + bit_DeityRallosZek = 0x00000800, + bit_DeityRodcetNife = 0x00001000, + bit_DeitySolusekRo = 0x00002000, + bit_DeityTheTribunal = 0x00004000, + bit_DeityTunare = 0x00008000, + bit_DeityVeeshan = 0x00010000, + bit_DeityAll = 0xFFFFFFFF + }; -static DeityTypeBits ConvertDeityToBitDeity(DeityTypes deity) -{ - switch(deity) - { - case DeityBertoxxulous: { return BIT_DeityBertoxxulous; } - case DeityBrellSirilis: { return BIT_DeityBrellSirilis; } - case DeityCazicThule: { return BIT_DeityCazicThule; } - case DeityErollisiMarr: { return BIT_DeityErollisiMarr; } - case DeityBristlebane: { return BIT_DeityBristlebane; } - case DeityInnoruuk: { return BIT_DeityInnoruuk; } - case DeityKarana: { return BIT_DeityKarana; } - case DeityMithanielMarr: { return BIT_DeityMithanielMarr; } - case DeityPrexus: { return BIT_DeityPrexus; } - case DeityQuellious: { return BIT_DeityQuellious; } - case DeityRallosZek: { return BIT_DeityRallosZek; } - case DeityRodcetNife: { return BIT_DeityRodcetNife; } - case DeitySolusekRo: { return BIT_DeitySolusekRo; } - case DeityTheTribunal: { return BIT_DeityTheTribunal; } - case DeityTunare: { return BIT_DeityTunare; } - case DeityVeeshan: { return BIT_DeityVeeshan; } - case DeityAgnostic_LB: - case DeityAgnostic: { return BIT_DeityAgnostic; } - default: { break; } - }; + extern DeityTypeBit ConvertDeityTypeToDeityTypeBit(DeityType deity_type); + extern DeityType ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit); + extern const char* DeityName(DeityType deity_type); - return BIT_DeityAll; -}; + } /*deity*/ -static DeityTypes ConvertBitDeityToDeity(DeityTypeBits deity_bit) -{ - switch(deity_bit) - { - case BIT_DeityAgnostic: { return DeityAgnostic; } - case BIT_DeityBertoxxulous: { return DeityBertoxxulous; } - case BIT_DeityBrellSirilis: { return DeityBrellSirilis; } - case BIT_DeityCazicThule: { return DeityCazicThule; } - case BIT_DeityErollisiMarr: { return DeityErollisiMarr; } - case BIT_DeityBristlebane: { return DeityBristlebane; } - case BIT_DeityInnoruuk: { return DeityInnoruuk; } - case BIT_DeityKarana: { return DeityKarana; } - case BIT_DeityMithanielMarr: { return DeityMithanielMarr; } - case BIT_DeityPrexus: { return DeityPrexus; } - case BIT_DeityQuellious: { return DeityQuellious; } - case BIT_DeityRallosZek: { return DeityRallosZek; } - case BIT_DeityRodcetNife: { return DeityRodcetNife; } - case BIT_DeitySolusekRo: { return DeitySolusekRo; } - case BIT_DeityTheTribunal: { return DeityTheTribunal; } - case BIT_DeityTunare: { return DeityTunare; } - case BIT_DeityVeeshan: { return DeityVeeshan; } - default: { break; } - }; +} /*EQEmu*/ - return DeityUnknown; -}; - -static std::string GetDeityName(DeityTypes deity) -{ - switch(deity) - { - case DeityBertoxxulous: { return "Bertoxxulous"; } - case DeityBrellSirilis: { return "Brell Serilis"; } - case DeityCazicThule: { return "Cazic-Thule"; } - case DeityErollisiMarr: { return "Erollisi Marr"; } - case DeityBristlebane: { return "Bristlebane"; } - case DeityInnoruuk: { return "Innoruuk"; } - case DeityKarana: { return "Karana"; } - case DeityMithanielMarr: { return "Mithaniel Marr"; } - case DeityPrexus: { return "Prexus"; } - case DeityQuellious: { return "Quellious"; } - case DeityRallosZek: { return "Rallos Zek"; } - case DeityRodcetNife: { return "Rodcet Nife"; } - case DeitySolusekRo: { return "Solusek Ro"; } - case DeityTheTribunal: { return "The Tribunal"; } - case DeityTunare: { return "Tunare"; } - case DeityVeeshan: { return "Veeshan"; } - case DeityAgnostic_LB: - case DeityAgnostic: { return "Agnostic"; } - default: { break; } - }; - - return "Unknown"; -}; - -#endif +#endif /* COMMON_DEITY_H */ diff --git a/common/emu_constants.cpp b/common/emu_constants.cpp new file mode 100644 index 000000000..a8fa73d1c --- /dev/null +++ b/common/emu_constants.cpp @@ -0,0 +1,20 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "emu_constants.h" diff --git a/common/emu_constants.h b/common/emu_constants.h new file mode 100644 index 000000000..e156fe98a --- /dev/null +++ b/common/emu_constants.h @@ -0,0 +1,158 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef COMMON_EMU_CONSTANTS_H +#define COMMON_EMU_CONSTANTS_H + +#include "eq_limits.h" +#include "emu_legacy.h" +#include "emu_versions.h" + +#include + + +namespace EQEmu +{ + namespace inventory { + //using namespace RoF2::invtype; + //using namespace RoF2::invslot; + //using namespace RoF2::invbag; + //using namespace RoF2::invaug; + + enum : int16 { typeInvalid = -1, slotInvalid = -1, containerInvalid = -1, socketInvalid = -1 }; // temporary + enum : int16 { typeBegin = 0, slotBegin = 0, containerBegin = 0, socketBegin = 0 }; // temporary + + enum PossessionsSlots : int16 { // temporary + slotCharm = 0, + slotEar1, + slotHead, + slotFace, + slotEar2, + slotNeck, // 5 + slotShoulders, + slotArms, + slotBack, + slotWrist1, + slotWrist2, // 10 + slotRange, + slotHands, + slotPrimary, + slotSecondary, + slotFinger1, // 15 + slotFinger2, + slotChest, + slotLegs, + slotFeet, + slotWaist, // 20 + slotPowerSource = 9999, + slotAmmo = 21, + slotGeneral1, + slotGeneral2, + slotGeneral3, + slotGeneral4, // 25 + slotGeneral5, + slotGeneral6, + slotGeneral7, + slotGeneral8, + slotCursor, // 30 + slotCount + }; + + enum InventoryTypes : int16 { // temporary + typePossessions = 0, + typeBank, + typeSharedBank, + typeTrade, + typeWorld, + typeLimbo, // 5 + typeTribute, + typeTrophyTribute, + typeGuildTribute, + typeMerchant, + typeDeleted, // 10 + typeCorpse, + typeBazaar, + typeInspect, + typeRealEstate, + typeViewMODPC, // 15 + typeViewMODBank, + typeViewMODSharedBank, + typeViewMODLimbo, + typeAltStorage, + typeArchived, // 20 + typeMail, + typeGuildTrophyTribute, + typeKrono, + typeOther, + typeCount + }; + + static int16 SlotCount(int16 type_index) { return 0; } // temporary + + const int16 ContainerCount = 10; // temporary + const int16 SocketCount = 6; // temporary + + } /*inventory*/ + + namespace constants { + const EQEmu::versions::ClientVersion CharacterCreationClient = EQEmu::versions::ClientVersion::RoF2; + const size_t CharacterCreationMax = RoF2::constants::CharacterCreationLimit; + + const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize; + + const int LongBuffs = RoF2::constants::LongBuffs; + const int ShortBuffs = RoF2::constants::ShortBuffs; + const int DiscBuffs = RoF2::constants::DiscBuffs; + const int TotalBuffs = RoF2::constants::TotalBuffs; + const int NPCBuffs = RoF2::constants::NPCBuffs; + const int PetBuffs = RoF2::constants::PetBuffs; + const int MercBuffs = RoF2::constants::MercBuffs; + + } /*constants*/ + + enum class CastingSlot : uint32 { + Gem1 = 0, + Gem2 = 1, + Gem3 = 2, + Gem4 = 3, + Gem5 = 4, + Gem6 = 5, + Gem7 = 6, + Gem8 = 7, + Gem9 = 8, + Gem10 = 9, + Gem11 = 10, + Gem12 = 11, + MaxGems = 12, + Ability = 20, // HT/LoH for Tit + PotionBelt = 21, // Tit uses a different slot for PB + Item = 22, + Discipline = 23, + AltAbility = 0xFF + }; + +} /*EQEmu*/ + +#endif /*COMMON_EMU_CONSTANTS_H*/ + +/* hack list to prevent circular references + + eq_limits.h:EQEmu::inventory::LookupEntry::InventoryTypeSize[n]; + +*/ diff --git a/common/emu_legacy.cpp b/common/emu_legacy.cpp new file mode 100644 index 000000000..36cb21c36 --- /dev/null +++ b/common/emu_legacy.cpp @@ -0,0 +1,20 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "emu_legacy.h" diff --git a/common/emu_legacy.h b/common/emu_legacy.h new file mode 100644 index 000000000..a624be883 --- /dev/null +++ b/common/emu_legacy.h @@ -0,0 +1,182 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef COMMON_EMU_LEGACY_H +#define COMMON_EMU_LEGACY_H + +#include "types.h" + +#include + + +namespace EQEmu +{ + // this is for perl and other legacy systems + namespace legacy { + enum InventorySlot { + SLOT_CHARM = 0, + SLOT_EAR01 = 1, + SLOT_HEAD = 2, + SLOT_FACE = 3, + SLOT_EAR02 = 4, + SLOT_NECK = 5, + SLOT_SHOULDER = 6, + SLOT_ARMS = 7, + SLOT_BACK = 8, + SLOT_BRACER01 = 9, + SLOT_BRACER02 = 10, + SLOT_RANGE = 11, + SLOT_HANDS = 12, + SLOT_PRIMARY = 13, + SLOT_SECONDARY = 14, + SLOT_RING01 = 15, + SLOT_RING02 = 16, + SLOT_CHEST = 17, + SLOT_LEGS = 18, + SLOT_FEET = 19, + SLOT_WAIST = 20, + SLOT_POWER_SOURCE = 9999, + SLOT_AMMO = 21, + SLOT_GENERAL_1 = 22, + SLOT_GENERAL_2 = 23, + SLOT_GENERAL_3 = 24, + SLOT_GENERAL_4 = 25, + SLOT_GENERAL_5 = 26, + SLOT_GENERAL_6 = 27, + SLOT_GENERAL_7 = 28, + SLOT_GENERAL_8 = 29, + SLOT_CURSOR = 30, + SLOT_CURSOR_END = (int16)0xFFFE, // I hope no one is using this... + SLOT_TRADESKILL = 1000, + SLOT_AUGMENT = 1001, + SLOT_INVALID = (int16)0xFFFF, + SLOT_POSSESSIONS_BEGIN = 0, + SLOT_POSSESSIONS_END = 30, + SLOT_EQUIPMENT_BEGIN = 0, + SLOT_EQUIPMENT_END = 21, + SLOT_PERSONAL_BEGIN = 22, + SLOT_PERSONAL_END = 29, + SLOT_PERSONAL_BAGS_BEGIN = 251, + SLOT_PERSONAL_BAGS_END = 330, + SLOT_CURSOR_BAG_BEGIN = 331, + SLOT_CURSOR_BAG_END = 340, + SLOT_TRIBUTE_BEGIN = 400, + SLOT_TRIBUTE_END = 404, + SLOT_BANK_BEGIN = 2000, + SLOT_BANK_END = 2023, + SLOT_BANK_BAGS_BEGIN = 2031, + SLOT_BANK_BAGS_END = 2270, + SLOT_SHARED_BANK_BEGIN = 2500, + SLOT_SHARED_BANK_END = 2501, + SLOT_SHARED_BANK_BAGS_BEGIN = 2531, + SLOT_SHARED_BANK_BAGS_END = 2550, + SLOT_TRADE_BEGIN = 3000, + SLOT_TRADE_END = 3007, + SLOT_TRADE_BAGS_BEGIN = 3031, + SLOT_TRADE_BAGS_END = 3110, + SLOT_WORLD_BEGIN = 4000, + SLOT_WORLD_END = 4009 + }; + + // these are currently hard-coded for existing inventory system..do not use in place of special client version handlers until ready + static const uint16 TYPE_POSSESSIONS_SIZE = 31; + static const uint16 TYPE_BANK_SIZE = 24; + static const uint16 TYPE_SHARED_BANK_SIZE = 2; + static const uint16 TYPE_TRADE_SIZE = 8; + static const uint16 TYPE_WORLD_SIZE = 10; + static const uint16 TYPE_LIMBO_SIZE = 36; + static const uint16 TYPE_TRIBUTE_SIZE = 5; // (need client values) + static const uint16 TYPE_TROPHY_TRIBUTE_SIZE = 0; + static const uint16 TYPE_GUILD_TRIBUTE_SIZE = 0; + static const uint16 TYPE_MERCHANT_SIZE = 0; + static const uint16 TYPE_DELETED_SIZE = 0; + static const uint16 TYPE_CORPSE_SIZE = 31; // no bitmask use..limits to size of client corpse window (see EQLimits::InventoryMapSize(MapCorpse, + + +namespace EntityLimits +{ + namespace NPC { + enum : int { Invalid = -1, Null, Safety }; + + enum : bool { False = false, True = true }; + + const size_t InvTypeTradeSize = 4; + + } /*NPC*/ + + namespace NPCMerchant { + enum : int { Invalid = -1, Null, Safety }; + + enum : bool { False = false, True = true }; + + const size_t InvTypeTradeSize = 4; + + } /*NPCMerchant*/ + + namespace Merc { + enum : int { Invalid = -1, Null, Safety }; + + enum : bool { False = false, True = true }; + + const size_t InvTypeTradeSize = 4; + + } /*Merc*/ + + namespace Bot { + enum : int { Invalid = -1, Null, Safety }; + + enum : bool { False = false, True = true }; + + const size_t InvTypeTradeSize = 8; + + } /*Bot*/ + + namespace ClientPet { + enum : int { Invalid = -1, Null, Safety }; + + enum : bool { False = false, True = true }; + + const size_t InvTypeTradeSize = 4; + + } /*Pet*/ + + namespace NPCPet { + enum : int { Invalid = -1, Null, Safety }; + + enum : bool { False = false, True = true }; + + const size_t InvTypeTradeSize = 4; + + } /*Pet*/ + + namespace MercPet { + enum : int { Invalid = -1, Null, Safety }; + + enum : bool { False = false, True = true }; + + const size_t InvTypeTradeSize = 4; + + } /*Pet*/ + + namespace BotPet { + enum : int { Invalid = -1, Null, Safety }; + + enum : bool { False = false, True = true }; + + const size_t InvTypeTradeSize = 4; + + } /*Pet*/ + +}; /*EntityLimits*/ + +#endif /*COMMON_EMU_LIMITS_H*/ diff --git a/common/emu_oplist.h b/common/emu_oplist.h index 223491ecd..cf6f4ca28 100644 --- a/common/emu_oplist.h +++ b/common/emu_oplist.h @@ -25,6 +25,9 @@ N(OP_AdventureRequest), N(OP_AdventureStatsReply), N(OP_AdventureStatsRequest), N(OP_AdventureUpdate), +N(OP_AggroMeterLockTarget), +N(OP_AggroMeterTargetInfo), +N(OP_AggroMeterUpdate), N(OP_AltCurrency), N(OP_AltCurrencyMerchantReply), N(OP_AltCurrencyMerchantRequest), @@ -64,6 +67,7 @@ N(OP_BuffRemoveRequest), N(OP_Bug), N(OP_CameraEffect), N(OP_Camp), +N(OP_CancelSneakHide), N(OP_CancelTask), N(OP_CancelTrade), N(OP_CastSpell), @@ -164,6 +168,7 @@ N(OP_FinishTrade), N(OP_FinishWindow), N(OP_FinishWindow2), N(OP_Fishing), +N(OP_Fling), N(OP_FloatListThing), N(OP_Forage), N(OP_ForceFindPerson), @@ -287,6 +292,7 @@ N(OP_LFGuild), N(OP_LFPCommand), N(OP_LFPGetMatchesRequest), N(OP_LFPGetMatchesResponse), +N(OP_LinkedReuse), N(OP_LoadSpellSet), N(OP_LocInfo), N(OP_LockoutTimerInfo), diff --git a/common/emu_tcp_connection.cpp b/common/emu_tcp_connection.cpp index da34f1ee7..0a0444c69 100644 --- a/common/emu_tcp_connection.cpp +++ b/common/emu_tcp_connection.cpp @@ -456,21 +456,21 @@ void EmuTCPConnection::SendNetErrorPacket(const char* reason) { std::cout << reason; std::cout << "': " << inet_ntoa(in) << ":" << GetPort() << std::endl; #endif - ServerPacket* pack = new ServerPacket(0); - pack->size = 1; - if (reason) - pack->size += strlen(reason) + 1; - pack->pBuffer = new uchar[pack->size]; - memset(pack->pBuffer, 0, pack->size); - pack->pBuffer[0] = 255; - strcpy((char*) &pack->pBuffer[1], reason); - SendPacket(pack); - safe_delete(pack); + auto pack = new ServerPacket(0); + pack->size = 1; + if (reason) + pack->size += strlen(reason) + 1; + pack->pBuffer = new uchar[pack->size]; + memset(pack->pBuffer, 0, pack->size); + pack->pBuffer[0] = 255; + strcpy((char *)&pack->pBuffer[1], reason); + SendPacket(pack); + safe_delete(pack); } void EmuTCPConnection::RemoveRelay(EmuTCPConnection* relay, bool iSendRelayDisconnect) { if (iSendRelayDisconnect) { - ServerPacket* pack = new ServerPacket(0, 5); + auto pack = new ServerPacket(0, 5); pack->pBuffer[0] = 3; *((uint32*) &pack->pBuffer[1]) = relay->GetRemoteID(); SendPacket(pack); @@ -609,7 +609,7 @@ bool EmuTCPConnection::ProcessReceivedDataAsPackets(char* errbuf) { if (base >= recvbuf_used) { safe_delete_array(recvbuf); } else { - uchar* tmpbuf = new uchar[recvbuf_size - base]; + auto tmpbuf = new uchar[recvbuf_size - base]; memcpy(tmpbuf, &recvbuf[base], recvbuf_used - base); safe_delete_array(recvbuf); recvbuf = tmpbuf; @@ -683,7 +683,7 @@ bool EmuTCPConnection::ProcessReceivedDataAsOldPackets(char* errbuf) { safe_delete_array(recvbuf); } else { - uchar* tmpbuf = new uchar[recvbuf_size - base]; + auto tmpbuf = new uchar[recvbuf_size - base]; memcpy(tmpbuf, &recvbuf[base], recvbuf_used - base); safe_delete_array(recvbuf); recvbuf = tmpbuf; @@ -739,7 +739,8 @@ void EmuTCPConnection::ProcessNetworkLayerPacket(ServerPacket* pack) { SendNetErrorPacket("New RelayClient: illegal on outgoing connection"); break; } - EmuTCPConnection* con = new EmuTCPConnection(Server->GetNextID(), Server, this, *((uint32*) data), *((uint32*) &data[4]), *((uint16*) &data[8])); + auto con = new EmuTCPConnection(Server->GetNextID(), Server, this, *((uint32 *)data), + *((uint32 *)&data[4]), *((uint16 *)&data[8])); Server->AddConnection(con); RelayCount++; break; @@ -787,7 +788,7 @@ bool EmuTCPConnection::SendData(bool &sent_something, char* errbuf) { if(sent_something) keepalive_timer.Start(); else if (TCPMode == modePacket && keepalive_timer.Check()) { - ServerPacket* pack = new ServerPacket(0, 0); + auto pack = new ServerPacket(0, 0); SendPacket(pack); safe_delete(pack); #if TCPN_DEBUG >= 5 diff --git a/common/emu_tcp_server.cpp b/common/emu_tcp_server.cpp index 4509c399f..00a241859 100644 --- a/common/emu_tcp_server.cpp +++ b/common/emu_tcp_server.cpp @@ -24,7 +24,7 @@ void EmuTCPServer::Process() { void EmuTCPServer::CreateNewConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort) { - EmuTCPConnection *conn = new EmuTCPConnection(ID, this, in_socket, irIP, irPort, pOldFormat); + auto conn = new EmuTCPConnection(ID, this, in_socket, irIP, irPort, pOldFormat); AddConnection(conn); } diff --git a/common/emu_versions.cpp b/common/emu_versions.cpp new file mode 100644 index 000000000..ee4970638 --- /dev/null +++ b/common/emu_versions.cpp @@ -0,0 +1,370 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "emu_versions.h" + + +bool EQEmu::versions::IsValidClientVersion(ClientVersion client_version) +{ + if (client_version <= ClientVersion::Unknown || client_version > LastClientVersion) + return false; + + return true; +} + +EQEmu::versions::ClientVersion EQEmu::versions::ValidateClientVersion(ClientVersion client_version) +{ + if (client_version <= ClientVersion::Unknown || client_version > LastClientVersion) + return ClientVersion::Unknown; + + return client_version; +} + +const char* EQEmu::versions::ClientVersionName(ClientVersion client_version) +{ + switch (client_version) { + case ClientVersion::Unknown: + return "Unknown Version"; + case ClientVersion::Client62: + return "Client 6.2"; + case ClientVersion::Titanium: + return "Titanium"; + case ClientVersion::SoF: + return "SoF"; + case ClientVersion::SoD: + return "SoD"; + case ClientVersion::UF: + return "UF"; + case ClientVersion::RoF: + return "RoF"; + case ClientVersion::RoF2: + return "RoF2"; + default: + return "Invalid Version"; + }; +} + +uint32 EQEmu::versions::ConvertClientVersionToClientVersionBit(ClientVersion client_version) +{ + switch (client_version) { + case ClientVersion::Unknown: + case ClientVersion::Client62: + return bit_Unknown; + case ClientVersion::Titanium: + return bit_Titanium; + case ClientVersion::SoF: + return bit_SoF; + case ClientVersion::SoD: + return bit_SoD; + case ClientVersion::UF: + return bit_UF; + case ClientVersion::RoF: + return bit_RoF; + case ClientVersion::RoF2: + return bit_RoF2; + default: + return bit_Unknown; + } +} + +EQEmu::versions::ClientVersion EQEmu::versions::ConvertClientVersionBitToClientVersion(uint32 client_version_bit) +{ + switch (client_version_bit) { + case (uint32)static_cast(ClientVersion::Unknown) : + case ((uint32)1 << (static_cast(ClientVersion::Client62) - 1)) : + return ClientVersion::Unknown; + case ((uint32)1 << (static_cast(ClientVersion::Titanium) - 1)) : + return ClientVersion::Titanium; + case ((uint32)1 << (static_cast(ClientVersion::SoF) - 1)) : + return ClientVersion::SoF; + case ((uint32)1 << (static_cast(ClientVersion::SoD) - 1)) : + return ClientVersion::SoD; + case ((uint32)1 << (static_cast(ClientVersion::UF) - 1)) : + return ClientVersion::UF; + case ((uint32)1 << (static_cast(ClientVersion::RoF) - 1)) : + return ClientVersion::RoF; + case ((uint32)1 << (static_cast(ClientVersion::RoF2) - 1)) : + return ClientVersion::RoF2; + default: + return ClientVersion::Unknown; + } +} + +uint32 EQEmu::versions::ConvertClientVersionToExpansion(ClientVersion client_version) +{ + switch (client_version) { + case ClientVersion::Unknown: + case ClientVersion::Client62: + case ClientVersion::Titanium: + return 0x000007FFU; + case ClientVersion::SoF: + return 0x00007FFFU; + case ClientVersion::SoD: + return 0x0000FFFFU; + case ClientVersion::UF: + return 0x0001FFFFU; + case ClientVersion::RoF: + case ClientVersion::RoF2: + return 0x000FFFFFU; + default: + return 0; + } +} + +bool EQEmu::versions::IsValidMobVersion(MobVersion mob_version) +{ + if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion) + return false; + + return true; +} + +bool EQEmu::versions::IsValidPCMobVersion(MobVersion mob_version) +{ + if (mob_version <= MobVersion::Unknown || mob_version > LastPCMobVersion) + return false; + + return true; +} + +bool EQEmu::versions::IsValidNonPCMobVersion(MobVersion mob_version) +{ + if (mob_version <= LastPCMobVersion || mob_version > LastNonPCMobVersion) + return false; + + return true; +} + +bool EQEmu::versions::IsValidOfflinePCMobVersion(MobVersion mob_version) +{ + if (mob_version <= LastNonPCMobVersion || mob_version > LastOfflinePCMobVersion) + return false; + + return true; +} + +EQEmu::versions::MobVersion EQEmu::versions::ValidateMobVersion(MobVersion mob_version) +{ + if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion) + return MobVersion::Unknown; + + return mob_version; +} + +EQEmu::versions::MobVersion EQEmu::versions::ValidatePCMobVersion(MobVersion mob_version) +{ + if (mob_version <= MobVersion::Unknown || mob_version > LastPCMobVersion) + return MobVersion::Unknown; + + return mob_version; +} + +EQEmu::versions::MobVersion EQEmu::versions::ValidateNonPCMobVersion(MobVersion mob_version) +{ + if (mob_version <= LastPCMobVersion || mob_version > LastNonPCMobVersion) + return MobVersion::Unknown; + + return mob_version; +} + +EQEmu::versions::MobVersion EQEmu::versions::ValidateOfflinePCMobVersion(MobVersion mob_version) +{ + if (mob_version <= LastNonPCMobVersion || mob_version > LastOfflinePCMobVersion) + return MobVersion::Unknown; + + return mob_version; +} + +const char* EQEmu::versions::MobVersionName(MobVersion mob_version) +{ + switch (mob_version) { + case MobVersion::Unknown: + return "Unknown Version"; + case MobVersion::Client62: + return "Client 6.2"; + case MobVersion::Titanium: + return "Titanium"; + case MobVersion::SoF: + return "SoF"; + case MobVersion::SoD: + return "SoD"; + case MobVersion::UF: + return "UF"; + case MobVersion::RoF: + return "RoF"; + case MobVersion::RoF2: + return "RoF2"; + case MobVersion::NPC: + return "NPC"; + case MobVersion::NPCMerchant: + return "NPC Merchant"; + case MobVersion::Merc: + return "Merc"; + case MobVersion::Bot: + return "Bot"; + case MobVersion::ClientPet: + return "Client Pet"; + case MobVersion::NPCPet: + return "NPC Pet"; + case MobVersion::MercPet: + return "Merc Pet"; + case MobVersion::BotPet: + return "Bot Pet"; + case MobVersion::OfflineTitanium: + return "Offline Titanium"; + case MobVersion::OfflineSoF: + return "Offline SoF"; + case MobVersion::OfflineSoD: + return "Offline SoD"; + case MobVersion::OfflineUF: + return "Offline UF"; + case MobVersion::OfflineRoF: + return "Offline RoF"; + case MobVersion::OfflineRoF2: + return "Offline RoF2"; + default: + return "Invalid Version"; + }; +} + +EQEmu::versions::ClientVersion EQEmu::versions::ConvertMobVersionToClientVersion(MobVersion mob_version) +{ + switch (mob_version) { + case MobVersion::Unknown: + case MobVersion::Client62: + return ClientVersion::Unknown; + case MobVersion::Titanium: + return ClientVersion::Titanium; + case MobVersion::SoF: + return ClientVersion::SoF; + case MobVersion::SoD: + return ClientVersion::SoD; + case MobVersion::UF: + return ClientVersion::UF; + case MobVersion::RoF: + return ClientVersion::RoF; + case MobVersion::RoF2: + return ClientVersion::RoF2; + default: + return ClientVersion::Unknown; + } +} + +EQEmu::versions::MobVersion EQEmu::versions::ConvertClientVersionToMobVersion(ClientVersion client_version) +{ + switch (client_version) { + case ClientVersion::Unknown: + case ClientVersion::Client62: + return MobVersion::Unknown; + case ClientVersion::Titanium: + return MobVersion::Titanium; + case ClientVersion::SoF: + return MobVersion::SoF; + case ClientVersion::SoD: + return MobVersion::SoD; + case ClientVersion::UF: + return MobVersion::UF; + case ClientVersion::RoF: + return MobVersion::RoF; + case ClientVersion::RoF2: + return MobVersion::RoF2; + default: + return MobVersion::Unknown; + } +} + +EQEmu::versions::MobVersion EQEmu::versions::ConvertPCMobVersionToOfflinePCMobVersion(MobVersion mob_version) +{ + switch (mob_version) { + case MobVersion::Titanium: + return MobVersion::OfflineTitanium; + case MobVersion::SoF: + return MobVersion::OfflineSoF; + case MobVersion::SoD: + return MobVersion::OfflineSoD; + case MobVersion::UF: + return MobVersion::OfflineUF; + case MobVersion::RoF: + return MobVersion::OfflineRoF; + case MobVersion::RoF2: + return MobVersion::OfflineRoF2; + default: + return MobVersion::Unknown; + } +} + +EQEmu::versions::MobVersion EQEmu::versions::ConvertOfflinePCMobVersionToPCMobVersion(MobVersion mob_version) +{ + switch (mob_version) { + case MobVersion::OfflineTitanium: + return MobVersion::Titanium; + case MobVersion::OfflineSoF: + return MobVersion::SoF; + case MobVersion::OfflineSoD: + return MobVersion::SoD; + case MobVersion::OfflineUF: + return MobVersion::UF; + case MobVersion::OfflineRoF: + return MobVersion::RoF; + case MobVersion::OfflineRoF2: + return MobVersion::RoF2; + default: + return MobVersion::Unknown; + } +} + +EQEmu::versions::ClientVersion EQEmu::versions::ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version) +{ + switch (mob_version) { + case MobVersion::OfflineTitanium: + return ClientVersion::Titanium; + case MobVersion::OfflineSoF: + return ClientVersion::SoF; + case MobVersion::OfflineSoD: + return ClientVersion::SoD; + case MobVersion::OfflineUF: + return ClientVersion::UF; + case MobVersion::OfflineRoF: + return ClientVersion::RoF; + case MobVersion::OfflineRoF2: + return ClientVersion::RoF2; + default: + return ClientVersion::Unknown; + } +} + +EQEmu::versions::MobVersion EQEmu::versions::ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version) +{ + switch (client_version) { + case ClientVersion::Titanium: + return MobVersion::OfflineTitanium; + case ClientVersion::SoF: + return MobVersion::OfflineSoF; + case ClientVersion::SoD: + return MobVersion::OfflineSoD; + case ClientVersion::UF: + return MobVersion::OfflineUF; + case ClientVersion::RoF: + return MobVersion::OfflineRoF; + case ClientVersion::RoF2: + return MobVersion::OfflineRoF2; + default: + return MobVersion::Unknown; + } +} diff --git a/common/emu_versions.h b/common/emu_versions.h new file mode 100644 index 000000000..9d9e1f580 --- /dev/null +++ b/common/emu_versions.h @@ -0,0 +1,128 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef COMMON_EMU_VERSIONS_H +#define COMMON_EMU_VERSIONS_H + +#include "types.h" + +#include + + +namespace EQEmu +{ + namespace versions { + enum class ClientVersion { + Unknown = 0, + Client62, // Build: 'Aug 4 2005 15:40:59' + Titanium, // Build: 'Oct 31 2005 10:33:37' + SoF, // Build: 'Sep 7 2007 09:11:49' + SoD, // Build: 'Dec 19 2008 15:22:49' + UF, // Build: 'Jun 8 2010 16:44:32' + RoF, // Build: 'Dec 10 2012 17:35:44' + RoF2 // Build: 'May 10 2013 23:30:08' + }; + + enum ClientVersionBit : uint32 { + bit_Unknown = 0, + bit_Client62 = 0x00000001, // unsupported (placeholder for scripts) + bit_Titanium = 0x00000002, + bit_SoF = 0x00000004, + bit_SoD = 0x00000008, + bit_UF = 0x00000010, + bit_RoF = 0x00000020, + bit_RoF2 = 0x00000040, + bit_TitaniumAndEarlier = 0x00000003, + bit_SoFAndEarlier = 0x00000007, + bit_SoDAndEarlier = 0x0000000F, + bit_UFAndEarlier = 0x0000001F, + bit_RoFAndEarlier = 0x0000003F, + bit_SoFAndLater = 0xFFFFFFFC, + bit_SoDAndLater = 0xFFFFFFF8, + bit_UFAndLater = 0xFFFFFFF0, + bit_RoFAndLater = 0xFFFFFFE0, + bit_RoF2AndLater = 0xFFFFFFC0, + bit_AllClients = 0xFFFFFFFF + }; + + const ClientVersion LastClientVersion = ClientVersion::RoF2; + const size_t ClientVersionCount = (static_cast(LastClientVersion) + 1); + + bool IsValidClientVersion(ClientVersion client_version); + ClientVersion ValidateClientVersion(ClientVersion client_version); + const char* ClientVersionName(ClientVersion client_version); + uint32 ConvertClientVersionToClientVersionBit(ClientVersion client_version); + ClientVersion ConvertClientVersionBitToClientVersion(uint32 client_version_bit); + uint32 ConvertClientVersionToExpansion(ClientVersion client_version); + + + enum class MobVersion { + Unknown = 0, + Client62, + Titanium, + SoF, + SoD, + UF, + RoF, + RoF2, + NPC, + NPCMerchant, + Merc, + Bot, + ClientPet, + NPCPet, + MercPet, + BotPet, + OfflineTitanium, + OfflineSoF, + OfflineSoD, + OfflineUF, + OfflineRoF, + OfflineRoF2 + }; + + const MobVersion LastMobVersion = MobVersion::OfflineRoF2; + const MobVersion LastPCMobVersion = MobVersion::RoF2; + const MobVersion LastNonPCMobVersion = MobVersion::BotPet; + const MobVersion LastOfflinePCMobVersion = MobVersion::OfflineRoF2; + const size_t MobVersionCount = (static_cast(LastMobVersion) + 1); + + bool IsValidMobVersion(MobVersion mob_version); + bool IsValidPCMobVersion(MobVersion mob_version); + bool IsValidNonPCMobVersion(MobVersion mob_version); + bool IsValidOfflinePCMobVersion(MobVersion mob_version); + + MobVersion ValidateMobVersion(MobVersion mob_version); + MobVersion ValidatePCMobVersion(MobVersion mob_version); + MobVersion ValidateNonPCMobVersion(MobVersion mob_version); + MobVersion ValidateOfflinePCMobVersion(MobVersion mob_version); + + const char* MobVersionName(MobVersion mob_version); + ClientVersion ConvertMobVersionToClientVersion(MobVersion mob_version); + MobVersion ConvertClientVersionToMobVersion(ClientVersion client_version); + MobVersion ConvertPCMobVersionToOfflinePCMobVersion(MobVersion mob_version); + MobVersion ConvertOfflinePCMobVersionToPCMobVersion(MobVersion mob_version); + ClientVersion ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version); + MobVersion ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version); + + } /*versions*/ + +} /*EQEmu*/ + +#endif /*COMMON_EMU_VERSIONS_H*/ diff --git a/common/eq_constants.h b/common/eq_constants.h index 728013eba..b4e887b0a 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -1,5 +1,6 @@ /* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2003 EQEMu Development Team (http://eqemulator.net) + + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,407 +14,57 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef EQ_CONSTANTS_H -#define EQ_CONSTANTS_H + +#ifndef COMMON_EQ_CONSTANTS_H +#define COMMON_EQ_CONSTANTS_H #include "skills.h" #include "types.h" -/* -** Light Types -** -*/ -enum LightTypes -{ - lightTypeNone = 0, - lightTypeCandle, - lightTypeTorch, - lightTypeTinyGlowingSkull, - lightTypeSmallLantern, - lightTypeSteinOfMoggok, // 5 - lightTypeLargeLantern, - lightTypeFlamelessLantern, - lightTypeGlobeOfStars, - lightTypeLightGlobe, - lightTypeLightstone, // 10 - lightTypeGreaterLightstone, - lightTypeFireBeetleEye, - lightTypeColdlight, - lightTypeUnknown1, - lightTypeUnknown2 // 15 -}; -#define LIGHT_TYPES_COUNT 16 +//SpawnAppearance types: (compared two clients for server-originating types: SoF & RoF2) +#define AT_Die 0 // this causes the client to keel over and zone to bind point (default action) +#define AT_WhoLevel 1 // the level that shows up on /who +//#define AT_2 2 // unknown +#define AT_Invis 3 // 0 = visible, 1 = invisible +#define AT_PVP 4 // 0 = blue, 1 = pvp (red) +#define AT_Light 5 // light type emitted by player (lightstone, shiny shield) +#define AT_Anim 14 // 100=standing, 110=sitting, 111=ducking, 115=feigned, 105=looting +#define AT_Sneak 15 // 0 = normal, 1 = sneaking +#define AT_SpawnID 16 // server to client, sets player spawn id +#define AT_HP 17 // Client->Server, my HP has changed (like regen tic) +#define AT_Linkdead 18 // 0 = normal, 1 = linkdead +#define AT_Levitate 19 // 0=off, 1=flymode, 2=levitate +#define AT_GM 20 // 0 = normal, 1 = GM - all odd numbers seem to make it GM +#define AT_Anon 21 // 0 = normal, 1 = anon, 2 = roleplay +#define AT_GuildID 22 +#define AT_GuildRank 23 // 0=member, 1=officer, 2=leader +#define AT_AFK 24 // 0 = normal, 1 = afk +#define AT_Pet 25 // Param is EntityID of owner, or 0 for when charm breaks +//#define AT_27 27 // unknown +#define AT_Split 28 // 0 = normal, 1 = autosplit on (not showing in SoF+) (client-to-server only) +#define AT_Size 29 // spawn's size (present: SoF, absent: RoF2) +//#define AT_30 30 // unknown +#define AT_NPCName 31 // change PC's name's color to NPC color 0 = normal, 1 = npc name +//#define AT_32 32 // unknown +//#define AT_33 33 // unknown +//#define AT_34 34 // unknown (present: SoF, absent: RoF2) +//#define AT_35 35 // unknown +//#define AT_36 36 // unknown +//#define AT_37 37 // unknown +//#define AT_38 38 // unknown +//#define AT_39 39 // unknown +#define AT_ShowHelm 43 // 0 = hide graphic, 1 = show graphic +#define AT_DamageState 44 // The damage state of a destructible object (0 through 4) +//#define AT_46 46 // unknown +//#define AT_48 48 // unknown +//#define AT_49 49 // unknown +//#define AT_52 52 // (absent: SoF, present: RoF2) (not a replacement for RoF absent 29 or 34) +//#define AT_53 53 // (absent: SoF, present: RoF2) (not a replacement for RoF absent 29 or 34) -/* -** Light Levels -** -*/ -enum LightLevels -{ - lightLevelUnlit = 0, - lightLevelCandle, - lightLevelTorch, - lightLevelSmallMagic, - lightLevelRedLight, - lightLevelBlueLight, // 5 - lightLevelSmallLantern, - lightLevelMagicLantern, - lightLevelLargeLantern, - lightLevelLargeMagic, - lightLevelBrilliant // 10 -}; - -#define LIGHT_LEVELS_COUNT 11 - -/* -** Item attributes -** -** (There are no grepwin hits other than these declarations... Do they have a use?) -*/ -enum ItemAttributes : uint32 -{ - ItemAttrNone = 0x00000000, - ItemAttrLore = 0x00000001, - ItemAttrArtifact = 0x00000002, - ItemAttrSummoned = 0x00000004, - ItemAttrMagic = 0x00000008, - ItemAttrAugment = 0x00000010, - ItemAttrPendingLore = 0x00000020, - ItemAttrUnknown = 0xFFFFFFFF -}; - -/* -** Item class types -** -*/ -enum ItemClassTypes -{ - ItemClassCommon = 0, - ItemClassContainer, - ItemClassBook, - _ItemClassCount -}; - -/* -** Item use types -** -** (ref: database and eqstr_us.txt) -** -** (Looking at a recent database, it's possible that some of the item values may be off [10-27-2013]) -*/ -enum ItemUseTypes : uint8 -{ -/*9138*/ ItemType1HSlash = 0, -/*9141*/ ItemType2HSlash, -/*9140*/ ItemType1HPiercing, -/*9139*/ ItemType1HBlunt, -/*9142*/ ItemType2HBlunt, -/*5504*/ ItemTypeBow, // 5 -/*----*/ ItemTypeUnknown1, -/*----*/ ItemTypeLargeThrowing, -/*5505*/ ItemTypeShield, -/*5506*/ ItemTypeScroll, -/*5507*/ ItemTypeArmor, // 10 -/*5508*/ ItemTypeMisc, // a lot of random crap has this item use. -/*7564*/ ItemTypeLockPick, -/*----*/ ItemTypeUnknown2, -/*5509*/ ItemTypeFood, -/*5510*/ ItemTypeDrink, // 15 -/*5511*/ ItemTypeLight, -/*5512*/ ItemTypeCombinable, // not all stackable items are this use... -/*5513*/ ItemTypeBandage, -/*----*/ ItemTypeSmallThrowing, -/*----*/ ItemTypeSpell, // 20 // spells and tomes -/*5514*/ ItemTypePotion, -/*----*/ ItemTypeUnknown3, -/*0406*/ ItemTypeWindInstrument, -/*0407*/ ItemTypeStringedInstrument, -/*0408*/ ItemTypeBrassInstrument, // 25 -/*0405*/ ItemTypePercussionInstrument, -/*5515*/ ItemTypeArrow, -/*----*/ ItemTypeUnknown4, -/*5521*/ ItemTypeJewelry, -/*----*/ ItemTypeSkull, // 30 -/*5516*/ ItemTypeBook, // skill-up tomes/books? (would probably need a pp flag if true...) -/*5517*/ ItemTypeNote, -/*5518*/ ItemTypeKey, -/*----*/ ItemTypeCoin, -/*5520*/ ItemType2HPiercing, // 35 -/*----*/ ItemTypeFishingPole, -/*----*/ ItemTypeFishingBait, -/*5519*/ ItemTypeAlcohol, -/*----*/ ItemTypeKey2, // keys and satchels?? (questable keys?) -/*----*/ ItemTypeCompass, // 40 -/*----*/ ItemTypeUnknown5, -/*----*/ ItemTypePoison, // might be wrong, but includes poisons -/*----*/ ItemTypeUnknown6, -/*----*/ ItemTypeUnknown7, -/*5522*/ ItemTypeMartial, // 45 -/*----*/ ItemTypeUnknown8, -/*----*/ ItemTypeUnknown9, -/*----*/ ItemTypeUnknown10, -/*----*/ ItemTypeUnknown11, -/*----*/ ItemTypeSinging, // 50 -/*5750*/ ItemTypeAllInstrumentTypes, -/*5776*/ ItemTypeCharm, -/*----*/ ItemTypeDye, -/*----*/ ItemTypeAugmentation, -/*----*/ ItemTypeAugmentationSolvent, // 55 -/*----*/ ItemTypeAugmentationDistiller, -/*----*/ ItemTypeUnknown12, -/*----*/ ItemTypeFellowshipKit, -/*----*/ ItemTypeUnknown13, -/*----*/ ItemTypeRecipe, // 60 -/*----*/ ItemTypeAdvancedRecipe, -/*----*/ ItemTypeJournal, // only one(1) database entry -/*----*/ ItemTypeAltCurrency, // alt-currency (as opposed to coinage) -/*5881*/ ItemTypePerfectedAugmentationDistiller, -/*----*/ _ItemTypeCount - -/* - Unknowns: - - Mounts? - Ornamentations? - GuildBanners? - Collectible? - Placeable? - (others?) -*/ -}; - -/* -** Augmentation use type bitmasks (1-based) -** -** (ref: dbstr_us.txt) -** -*/ -enum AugmentationUseTypeBitmasks : uint32 { - AugUseNone = 0x00000000, - AugUseGeneralSingleStat = 0x00000001, /*1^16^1 (General: Single Stat)^0*/ - AugUseGeneralMultipleStat = 0x00000002, /*2^16^2 (General: Multiple Stat)^0*/ - AugUseGeneralSpellEffect = 0x00000004, /*3^16^3 (General: Spell Effect)^0*/ - AugUseWeaponGeneral = 0x00000008, /*4^16^4 (Weapon: General)^0*/ - AugUseWeaponElemDamage = 0x00000010, /*5^16^5 (Weapon: Elem Damage)^0*/ - AugUseWeaponBaseDamage = 0x00000020, /*6^16^6 (Weapon: Base Damage)^0*/ - AugUseGeneralGroup = 0x00000040, /*7^16^7 (General: Group)^0*/ - AugUseGeneralRaid = 0x00000080, /*8^16^8 (General: Raid)^0*/ - AugUseGeneralDragonsPoints = 0x00000100, /*9^16^9 (General: Dragons Points)^0*/ - AugUseCraftedCommon = 0x00000200, /*10^16^10 (Crafted: Common)^0*/ - AugUseCraftedGroup1 = 0x00000400, /*11^16^11 (Crafted: Group)^0*/ - AugUseCraftedRaid1 = 0x00000800, /*12^16^12 (Crafted: Raid)^0*/ - AugUseEnergeiacGroup = 0x00001000, /*13^16^13 (Energeiac: Group)^0*/ - AugUseEnergeiacRaid = 0x00002000, /*14^16^14 (Energeiac: Raid)^0*/ - AugUseEmblem = 0x00004000, /*15^16^15 (Emblem)^0*/ - AugUseCraftedGroup2 = 0x00008000, /*16^16^16 (Crafted: Group)^0*/ - AugUseCraftedRaid2 = 0x00010000, /*17^16^17 (Crafted: Raid)^0*/ - AugUseUnknown1 = 0x00020000, /*18^16^18^0*/ - AugUseUnknown2 = 0x00040000, /*19^16^19^0*/ - AugUseOrnamentation = 0x00080000, /*20^16^20 (Ornamentation)^0*/ - AugUseSpecialOrnamentation = 0x00100000, /*21^16^21 (Special Ornamentation)^0*/ - AugUseUnknown3 = 0x00200000, /*22^16^22^0*/ - AugUseUnknown4 = 0x00400000, /*23^16^23^0*/ - AugUseUnknown5 = 0x00800000, /*24^16^24^0*/ - AugUseUnknown6 = 0x01000000, /*25^16^25^0*/ - AugUseUnknown7 = 0x02000000, /*26^16^26^0*/ - AugUseUnknown8 = 0x04000000, /*27^16^27^0*/ - AugUseUnknown9 = 0x08000000, /*28^16^28^0*/ - AugUseUnknown10 = 0x10000000, /*29^16^29^0*/ - AugUseEpic25 = 0x20000000, /*30^16^30^0*/ - AugUseTest = 0x40000000, /*31^16^Test^0*/ // listed as 31^16^31^0 in 5-10 client - AugUseAll = 0xFFFFFFFF -}; - -/* -** Augmentation use types (enumerated) -** -*/ -enum AugmentationUseTypes : uint8 { - AugTypeNone = 0, - AugTypeGeneralSingleStat, - AugTypeGeneralMultipleStat, - AugTypeGeneralSpellEffect, - AugTypeWeaponGeneral, - AugTypeWeaponElemDamage, // 5 - AugTypeWeaponBaseDamage, - AugTypeGeneralGroup, - AugTypeGeneralRaid, - AugTypeGeneralDragonsPoints, - AugTypeCraftedCommon, // 10 - AugTypeCraftedGroup1, - AugTypeCraftedRaid1, - AugTypeEnergeiacGroup, - AugTypeEnergeiacRaid, - AugTypeEmblem, // 15 - AugTypeCraftedGroup2, - AugTypeCraftedRaid2, - AugTypeUnknown1, - AugTypeUnknown2, - AugTypeOrnamentation, // 20 - AugTypeSpecialOrnamentation, - AugTypeUnknown3, - AugTypeUnknown4, - AugTypeUnknown5, - AugTypeUnknown6, // 25 - AugTypeUnknown7, - AugTypeUnknown8, - AugTypeUnknown9, - AugTypeUnknown10, - AugTypeEpic25, // 30 - AugTypeTest, - _AugTypeCount, - AugTypeAll = 255 -}; - -/* -** Augmentation restriction types (in-work) -** -** (ref: eqstr_us.txt) -** -*/ -enum AugmentationRestrictionTypes : uint8 { -/*4690*/ AugRestrAny = 0, -/*9134*/ AugRestrArmor, -/*9135*/ AugRestrWeapons, -/*9136*/ AugRestr1HWeapons, -/*9137*/ AugRestr2HWeapons, -/*9138*/ AugRestr1HSlash, // 5 -/*9139*/ AugRestr1HBlunt, -/*9140*/ AugRestrPiercing, -/*9148*/ AugRestrHandToHand, -/*9141*/ AugRestr2HSlash, -/*9142*/ AugRestr2HBlunt, // 10 -/*9143*/ AugRestr2HPierce, -/*9144*/ AugRestrBows, -/*9145*/ AugRestrShields, -/*8052*/ AugRestr1HSlash1HBluntOrHandToHand, -/*9200*/ AugRestr1HBluntOrHandToHand, // 15 // no listed peq entries - -// these three appear to be post-RoF (12-10-2012) and can not be verified until RoF (05-10-2013) is supported -/*????*/ AugRestrUnknown1, -/*????*/ AugRestrUnknown2, -/*????*/ AugRestrUnknown3, // last value in peq entries - _AugRestrCount - -/*4687*/ //AugTypeAllItems, // ?? unknown atm -/*4688*/ //AugTypePrestige, // ?? unknown atm -/*4689*/ //AugTypeNonPrestige, // ?? unknown atm -}; - -/* -** Container use types -** -** This correlates to world 'object.type' (object.h/Object.cpp) as well as Item_Struct.BagType -** -** (ref: database, web forums and eqstr_us.txt) -*/ -enum ContainerUseTypes : uint8 -{ -/*3400*/ BagTypeSmallBag = 0, -/*3401*/ BagTypeLargeBag, -/*3402*/ BagTypeQuiver, -/*3403*/ BagTypeBeltPouch, -/*3404*/ BagTypeWristPouch, -/*3405*/ BagTypeBackPack, // 5 -/*3406*/ BagTypeSmallChest, -/*3407*/ BagTypeLargeChest, -/*----*/ BagTypeBandolier, // <*Database Reference Only> -/*3408*/ BagTypeMedicineBag, -/*3409*/ BagTypeToolBox, // 10 -/*3410*/ BagTypeLexicon, -/*3411*/ BagTypeMortar, -/*3412*/ BagTypeSelfDusting, // Quest container (Auto-clear contents?) -/*3413*/ BagTypeMixingBowl, -/*3414*/ BagTypeOven, // 15 -/*3415*/ BagTypeSewingKit, -/*3416*/ BagTypeForge, -/*3417*/ BagTypeFletchingKit, -/*3418*/ BagTypeBrewBarrel, -/*3419*/ BagTypeJewelersKit, // 20 -/*3420*/ BagTypePotteryWheel, -/*3421*/ BagTypeKiln, -/*3422*/ BagTypeKeymaker, // (no database entries as of peq rev 69) -/*3423*/ BagTypeWizardsLexicon, -/*3424*/ BagTypeMagesLexicon, // 25 -/*3425*/ BagTypeNecromancersLexicon, -/*3426*/ BagTypeEnchantersLexicon, -/*----*/ BagTypeUnknown1, // (a coin pouch/purse?) (no database entries as of peq rev 69) -/*----*/ BagTypeConcordanceofResearch, // <*Database Reference Only> -/*3427*/ BagTypeAlwaysWorks, // 30 // Quest container (Never-fail combines?) -/*3428*/ BagTypeKoadaDalForge, // High Elf -/*3429*/ BagTypeTeirDalForge, // Dark Elf -/*3430*/ BagTypeOggokForge, // Ogre -/*3431*/ BagTypeStormguardForge, // Dwarf -/*3432*/ BagTypeAkanonForge, // 35 // Gnome -/*3433*/ BagTypeNorthmanForge, // Barbarian -/*----*/ BagTypeUnknown2, // (no database entries as of peq rev 69) -/*3434*/ BagTypeCabilisForge, // Iksar -/*3435*/ BagTypeFreeportForge, // Human 1 -/*3436*/ BagTypeRoyalQeynosForge, // 40 // Human 2 -/*3439*/ BagTypeHalflingTailoringKit, -/*3438*/ BagTypeErudTailoringKit, -/*3440*/ BagTypeFierDalTailoringKit, // Wood Elf -/*3441*/ BagTypeFierDalFletchingKit, // Wood Elf -/*3437*/ BagTypeIksarPotteryWheel, // 45 -/*3442*/ BagTypeTackleBox, -/*3443*/ BagTypeTrollForge, -/*3445*/ BagTypeFierDalForge, // Wood Elf -/*3444*/ BagTypeValeForge, // Halfling -/*3446*/ BagTypeErudForge, // 50 -/*----*/ BagTypeTradersSatchel, // <*Database Reference Only> (db: Yellow Trader's Satchel Token?) -/*5785*/ BagTypeGuktaForge, // Froglok (no database entries as of peq rev 69) -/*3359*/ BagTypeAugmentationSealer, -/*----*/ BagTypeIceCreamChurn, // <*Database Reference Only> -/*6325*/ BagTypeTransformationmold, // 55 // Ornamentation -/*6340*/ BagTypeDetransformationmold, // Ornamentation Stripper -/*5400*/ BagTypeUnattuner, -/*7684*/ BagTypeTradeskillBag, -/*7692*/ BagTypeCollectibleBag, -/*----*/ _BagTypeCount -}; - -/* -** Item Effect Types -** -*/ -enum { - ET_CombatProc = 0, - ET_ClickEffect = 1, - ET_WornEffect = 2, - ET_Expendable = 3, - ET_EquipClick = 4, - ET_ClickEffect2 = 5, //name unknown - ET_Focus = 6, - ET_Scroll = 7 -}; - -//SpawnAppearance types: -#define AT_Die 0 // this causes the client to keel over and zone to bind point -#define AT_WhoLevel 1 // the level that shows up on /who -#define AT_Invis 3 // 0 = visible, 1 = invisible -#define AT_PVP 4 // 0 = blue, 1 = pvp (red) -#define AT_Light 5 // light type emitted by player (lightstone, shiny shield) -#define AT_Anim 14 // 100=standing, 110=sitting, 111=ducking, 115=feigned, 105=looting -#define AT_Sneak 15 // 0 = normal, 1 = sneaking -#define AT_SpawnID 16 // server to client, sets player spawn id -#define AT_HP 17 // Client->Server, my HP has changed (like regen tic) -#define AT_Linkdead 18 // 0 = normal, 1 = linkdead -#define AT_Levitate 19 // 0=off, 1=flymode, 2=levitate -#define AT_GM 20 // 0 = normal, 1 = GM - all odd numbers seem to make it GM -#define AT_Anon 21 // 0 = normal, 1 = anon, 2 = roleplay -#define AT_GuildID 22 -#define AT_GuildRank 23 // 0=member, 1=officer, 2=leader -#define AT_AFK 24 // 0 = normal, 1 = afk -#define AT_Pet 25 // Param is EntityID of owner, or 0 for when charm breaks -#define AT_Split 28 // 0 = normal, 1 = autosplit on -#define AT_Size 29 // spawn's size -#define AT_NPCName 31 // change PC's name's color to NPC color 0 = normal, 1 = npc name -#define AT_ShowHelm 43 // 0 = do not show helmet graphic, 1 = show graphic -#define AT_DamageState 44 // The damage state of a destructible object (0 through 4) -//#define AT_Trader 300 // Bazzar Trader Mode +//#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2) // animations for AT_Anim #define ANIM_FREEZE 102 @@ -519,15 +170,40 @@ typedef enum { #define MT_StrikeThrough 339 #define MT_Stun 340 +// TODO: Really should combine above and below into one + //from showeq enum ChatColor { + /* CC_Default = 0, CC_DarkGrey = 1, CC_DarkGreen = 2, CC_DarkBlue = 3, CC_Purple = 5, CC_LightGrey = 6, + */ + + CC_WhiteSmoke = 0, // FF|F0F0F0 + CC_Green = 2, // FF|008000 + CC_BrightBlue = 3, // FF|0040FF + CC_Magenta = 5, // FF|F000F0 + CC_Gray = 6, // FF|808080 + CC_LightGray = 7, // FF|E0E0E0 + //CC_WhiteSmoke2 = 10, // FF|F0F0F0 + CC_DarkGray = 12, // FF|A0A0A0 + CC_Red = 13, // FF|F00000 + CC_Lime = 14, // FF|00F000 + CC_Yellow = 15, // FF|F0F000 + CC_Blue = 16, // FF|0000F0 + CC_LightNavy = 17, // FF|0000AF + CC_Cyan = 18, // FF|00F0F0 + CC_Black = 20, // FF|000000 + + // any index <= 255 that is not defined above + CC_DimGray = 1, // FF|606060 + CC_Default = 1, + CC_User_Say = 256, CC_User_Tell = 257, CC_User_Group = 258, @@ -723,7 +399,7 @@ static const uint8 DamageTypeUnknown = 0xFF; ** ** (indexed by 'Skill' of SkillUseTypes) */ -static const uint8 SkillDamageTypes[HIGHEST_SKILL + 1] = // change to _SkillServerArraySize once activated +static const uint8 SkillDamageTypes[EQEmu::skills::HIGHEST_SKILL + 1] = // change to _SkillServerArraySize once activated { /*1HBlunt*/ 0, /*1HSlashing*/ 1, @@ -805,25 +481,6 @@ static const uint8 SkillDamageTypes[HIGHEST_SKILL + 1] = // change to _SkillServ /*2HPiercing*/ 36 // Needs research (set for 1HPiercing value - similar to slash/blunt) }; -/* -** Material use slots -** -*/ -enum MaterialUseSlots : uint8 -{ - MaterialHead = 0, - MaterialChest, - MaterialArms, - MaterialWrist, - MaterialHands, - MaterialLegs, // 5 - MaterialFeet, - MaterialPrimary, - MaterialSecondary, - _MaterialCount, - _MaterialInvalid = 255 -}; - /* // Used for worn NPC inventory tracking. NPCs don't use // augments, so only the basic slots need to be kept track of. @@ -858,164 +515,8 @@ enum MaterialUseSlots : uint8 ** */ -enum InventoryMapTypes : int16 { - MapPossessions = 0, - MapBank, - MapSharedBank, - MapTrade, - MapWorld, - MapLimbo, // 5 - MapTribute, - MapTrophyTribute, - MapGuildTribute, - MapMerchant, - MapDeleted, // 10 - MapCorpse, - MapBazaar, - MapInspect, - MapRealEstate, - MapViewMODPC, // 15 - MapViewMODBank, - MapViewMODSharedBank, - MapViewMODLimbo, - MapAltStorage, - MapArchived, // 20 - MapMail, - MapGuildTrophyTribute, - MapKrono, - MapOther, - _MapCount -}; - -enum InventoryMainTypes : int16 { - MainCharm = 0, - MainEar1, - MainHead, - MainFace, - MainEar2, - MainNeck, // 5 - MainShoulders, - MainArms, - MainBack, - MainWrist1, - MainWrist2, // 10 - MainRange, - MainHands, - MainPrimary, - MainSecondary, - MainFinger1, // 15 - MainFinger2, - MainChest, - MainLegs, - MainFeet, - MainWaist, // 20 - MainPowerSource = 9999, // temp - MainAmmo = 21, // temp - MainGeneral1, - MainGeneral2, - MainGeneral3, - MainGeneral4, // 25 - MainGeneral5, - MainGeneral6, - MainGeneral7, - MainGeneral8, - //MainGeneral9, - //MainGeneral10, - MainCursor, // 30 - _MainCount -}; - #define INVALID_INDEX -1 -#define NOT_USED 0 -#define NO_ITEM 0 - -// yes..these are redundant... but, they help to identify and define what is actually being performed -// plus, since they're pre-op's, they don't affect the actual binary size -#define MAP_BEGIN 0 -#define MAIN_BEGIN 0 -#define SUB_BEGIN 0 -#define AUG_BEGIN 0 - -namespace legacy { - // this is for perl and other legacy systems - - typedef enum { - SLOT_CHARM = 0, - SLOT_EAR01 = 1, - SLOT_HEAD = 2, - SLOT_FACE = 3, - SLOT_EAR02 = 4, - SLOT_NECK = 5, - SLOT_SHOULDER = 6, - SLOT_ARMS = 7, - SLOT_BACK = 8, - SLOT_BRACER01 = 9, - SLOT_BRACER02 = 10, - SLOT_RANGE = 11, - SLOT_HANDS = 12, - SLOT_PRIMARY = 13, - SLOT_SECONDARY = 14, - SLOT_RING01 = 15, - SLOT_RING02 = 16, - SLOT_CHEST = 17, - SLOT_LEGS = 18, - SLOT_FEET = 19, - SLOT_WAIST = 20, - SLOT_POWER_SOURCE = 9999, - SLOT_AMMO = 21, - SLOT_GENERAL_1 = 22, - SLOT_GENERAL_2 = 23, - SLOT_GENERAL_3 = 24, - SLOT_GENERAL_4 = 25, - SLOT_GENERAL_5 = 26, - SLOT_GENERAL_6 = 27, - SLOT_GENERAL_7 = 28, - SLOT_GENERAL_8 = 29, - //SLOT_GENERAL_9 = not supported - //SLOT_GENERAL_10 = not supported - SLOT_CURSOR = 30, - SLOT_CURSOR_END = (int16)0xFFFE, // I hope no one is using this... - SLOT_TRADESKILL = 1000, - SLOT_AUGMENT = 1001, - SLOT_INVALID = (int16)0xFFFF, - - SLOT_POSSESSIONS_BEGIN = 0, - SLOT_POSSESSIONS_END = 30, - - SLOT_EQUIPMENT_BEGIN = 0, - SLOT_EQUIPMENT_END = 21, - - SLOT_PERSONAL_BEGIN = 22, - SLOT_PERSONAL_END = 29, - SLOT_PERSONAL_BAGS_BEGIN = 251, - SLOT_PERSONAL_BAGS_END = 330, - - SLOT_CURSOR_BAG_BEGIN = 331, - SLOT_CURSOR_BAG_END = 340, - - SLOT_TRIBUTE_BEGIN = 400, - SLOT_TRIBUTE_END = 404, - - SLOT_BANK_BEGIN = 2000, - SLOT_BANK_END = 2023, - SLOT_BANK_BAGS_BEGIN = 2031, - SLOT_BANK_BAGS_END = 2270, - - SLOT_SHARED_BANK_BEGIN = 2500, - SLOT_SHARED_BANK_END = 2501, - SLOT_SHARED_BANK_BAGS_BEGIN = 2531, - SLOT_SHARED_BANK_BAGS_END = 2550, - - SLOT_TRADE_BEGIN = 3000, - SLOT_TRADE_END = 3007, - SLOT_TRADE_BAGS_BEGIN = 3031, - SLOT_TRADE_BAGS_END = 3110, - - SLOT_WORLD_BEGIN = 4000, - SLOT_WORLD_END = 4009 - } InventorySlot; -} static const uint32 MAX_SPELL_DB_ID_VAL = 65535; -#endif +#endif /*COMMON_EQ_CONSTANTS_H*/ diff --git a/common/eq_dictionary.cpp b/common/eq_dictionary.cpp deleted file mode 100644 index 9bc602aa1..000000000 --- a/common/eq_dictionary.cpp +++ /dev/null @@ -1,943 +0,0 @@ -/* -EQEMu: Everquest Server Emulator - -Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY except by those people which sell it, which -are required to give you total support for your newly bought product; -without even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -#include "eq_dictionary.h" -#include "string_util.h" - -// -// class EmuConstants -// -uint16 EmuConstants::InventoryMapSize(int16 indexMap) -{ - switch (indexMap) - { - case MapPossessions: - return MAP_POSSESSIONS_SIZE; - case MapBank: - return MAP_BANK_SIZE; - case MapSharedBank: - return MAP_SHARED_BANK_SIZE; - case MapTrade: - return MAP_TRADE_SIZE; - case MapWorld: - return MAP_WORLD_SIZE; - case MapLimbo: - return MAP_LIMBO_SIZE; - case MapTribute: - return MAP_TRIBUTE_SIZE; - case MapTrophyTribute: - return MAP_TROPHY_TRIBUTE_SIZE; - case MapGuildTribute: - return MAP_GUILD_TRIBUTE_SIZE; - case MapMerchant: - return MAP_MERCHANT_SIZE; - case MapDeleted: - return MAP_DELETED_SIZE; - case MapCorpse: - return MAP_CORPSE_SIZE; - case MapBazaar: - return MAP_BAZAAR_SIZE; - case MapInspect: - return MAP_INSPECT_SIZE; - case MapRealEstate: - return MAP_REAL_ESTATE_SIZE; - case MapViewMODPC: - return MAP_VIEW_MOD_PC_SIZE; - case MapViewMODBank: - return MAP_VIEW_MOD_BANK_SIZE; - case MapViewMODSharedBank: - return MAP_VIEW_MOD_SHARED_BANK_SIZE; - case MapViewMODLimbo: - return MAP_VIEW_MOD_LIMBO_SIZE; - case MapAltStorage: - return MAP_ALT_STORAGE_SIZE; - case MapArchived: - return MAP_ARCHIVED_SIZE; - case MapMail: - return MAP_MAIL_SIZE; - case MapGuildTrophyTribute: - return MAP_GUILD_TROPHY_TRIBUTE_SIZE; - case MapKrono: - return MAP_KRONO_SIZE; - case MapOther: - return MAP_OTHER_SIZE; - default: - return NOT_USED; - } -} - -/* -std::string EmuConstants::InventoryLocationName(Location_Struct location) -{ - // not ready for implementation... - std::string ret_str; - StringFormat(ret_str, "%s, %s, %s, %s", InventoryMapName(location.map), InventoryMainName(location.main), InventorySubName(location.sub), InventoryAugName(location.aug)); - return ret_str; -} -*/ - -std::string EmuConstants::InventoryMapName(int16 indexMap) -{ - switch (indexMap) - { - case INVALID_INDEX: - return "Invalid Map"; - case MapPossessions: - return "Possessions"; - case MapBank: - return "Bank"; - case MapSharedBank: - return "SharedBank"; - case MapTrade: - return "Trade"; - case MapWorld: - return "World"; - case MapLimbo: - return "Limbo"; - case MapTribute: - return "Tribute"; - case MapTrophyTribute: - return "TrophyTribute"; - case MapGuildTribute: - return "GuildTribute"; - case MapMerchant: - return "Merchant"; - case MapDeleted: - return "Deleted"; - case MapCorpse: - return "Corpse"; - case MapBazaar: - return "Bazaar"; - case MapInspect: - return "Inspect"; - case MapRealEstate: - return "RealEstate"; - case MapViewMODPC: - return "ViewMODPC"; - case MapViewMODBank: - return "ViewMODBank"; - case MapViewMODSharedBank: - return "ViewMODSharedBank"; - case MapViewMODLimbo: - return "ViewMODLimbo"; - case MapAltStorage: - return "AltStorage"; - case MapArchived: - return "Archived"; - case MapMail: - return "Mail"; - case MapGuildTrophyTribute: - return "GuildTrophyTribute"; - case MapKrono: - return "Krono"; - case MapOther: - return "Other"; - default: - return "Unknown Map"; - } -} - -std::string EmuConstants::InventoryMainName(int16 indexMain) -{ - switch (indexMain) - { - case INVALID_INDEX: - return "Invalid Main"; - case MainCharm: - return "Charm"; - case MainEar1: - return "Ear1"; - case MainHead: - return "Head"; - case MainFace: - return "Face"; - case MainEar2: - return "Ear2"; - case MainNeck: - return "Neck"; - case MainShoulders: - return "Shoulders"; - case MainArms: - return "Arms"; - case MainBack: - return "Back"; - case MainWrist1: - return "Wrist1"; - case MainWrist2: - return "Wrist2"; - case MainRange: - return "Range"; - case MainHands: - return "Hands"; - case MainPrimary: - return "Primary"; - case MainSecondary: - return "Secondary"; - case MainFinger1: - return "Finger1"; - case MainFinger2: - return "Finger2"; - case MainChest: - return "Chest"; - case MainLegs: - return "Legs"; - case MainFeet: - return "Feet"; - case MainWaist: - return "Waist"; - case MainPowerSource: - return "PowerSource"; - case MainAmmo: - return "Ammo"; - case MainGeneral1: - return "General1"; - case MainGeneral2: - return "General2"; - case MainGeneral3: - return "General3"; - case MainGeneral4: - return "General4"; - case MainGeneral5: - return "General5"; - case MainGeneral6: - return "General6"; - case MainGeneral7: - return "General7"; - case MainGeneral8: - return "General8"; - /* - case MainGeneral9: - return "General9"; - case MainGeneral10: - return "General10"; - */ - case MainCursor: - return "Cursor"; - default: - return "Unknown Main"; - } -} - -std::string EmuConstants::InventorySubName(int16 indexSub) -{ - if (indexSub == INVALID_INDEX) - return "Invalid Sub"; - - if ((uint16)indexSub >= ITEM_CONTAINER_SIZE) - return "Unknown Sub"; - - std::string ret_str; - ret_str = StringFormat("Container%i", (indexSub + 1)); // zero-based index..but, count starts at one - - return ret_str; -} - -std::string EmuConstants::InventoryAugName(int16 indexAug) -{ - if (indexAug == INVALID_INDEX) - return "Invalid Aug"; - - if ((uint16)indexAug >= ITEM_COMMON_SIZE) - return "Unknown Aug"; - - std::string ret_str; - ret_str = StringFormat("Augment%i", (indexAug + 1)); // zero-based index..but, count starts at one - - return ret_str; -} - - -// -// class EQLimits -// -// client validation -bool EQLimits::IsValidPCClientVersion(ClientVersion clientVersion) -{ - if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_PC_CLIENT) - return true; - - return false; -} - -ClientVersion EQLimits::ValidatePCClientVersion(ClientVersion clientVersion) -{ - if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_PC_CLIENT) - return clientVersion; - - return ClientVersion::Unknown; -} - -// npc validation -bool EQLimits::IsValidNPCClientVersion(ClientVersion clientVersion) -{ - if (clientVersion > LAST_PC_CLIENT && clientVersion <= LAST_NPC_CLIENT) - return true; - - return false; -} - -ClientVersion EQLimits::ValidateNPCClientVersion(ClientVersion clientVersion) -{ - if (clientVersion > LAST_PC_CLIENT && clientVersion <= LAST_NPC_CLIENT) - return clientVersion; - - return ClientVersion::Unknown; -} - -// mob validation -bool EQLimits::IsValidMobClientVersion(ClientVersion clientVersion) -{ - if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_NPC_CLIENT) - return true; - - return false; -} - -ClientVersion EQLimits::ValidateMobClientVersion(ClientVersion clientVersion) -{ - if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_NPC_CLIENT) - return clientVersion; - - return ClientVersion::Unknown; -} - -// database -size_t EQLimits::CharacterCreationLimit(ClientVersion clientVersion) -{ - static const size_t local[CLIENT_VERSION_COUNT] = { -/*Unknown*/ NOT_USED, -/*Client62*/ NOT_USED, -/*Titanium*/ Titanium::consts::CHARACTER_CREATION_LIMIT, -/*SoF*/ SoF::consts::CHARACTER_CREATION_LIMIT, -/*SoD*/ SoD::consts::CHARACTER_CREATION_LIMIT, -/*UF*/ UF::consts::CHARACTER_CREATION_LIMIT, -/*RoF*/ RoF::consts::CHARACTER_CREATION_LIMIT, -/*RoF2*/ RoF2::consts::CHARACTER_CREATION_LIMIT, - -/*MobNPC*/ NOT_USED, -/*MobMerc*/ NOT_USED, -/*MobBot*/ NOT_USED, -/*MobPet*/ NOT_USED - }; - - return local[static_cast(ValidateMobClientVersion(clientVersion))]; -} - -// inventory -uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion) -{ - // not all maps will have an instantiated container..some are references for queue generators (i.e., bazaar, mail, etc...) - // a zero '0' indicates a needed value..otherwise, change to '_NOTUSED' for a null value so indices requiring research can be identified - // ALL of these values need to be verified before pushing to live - // - // make sure that you transcribe the actual value from 'defaults' to here before updating or client crashes will ensue..and/or... - // insert older clients inside of the progression of client order - // - // MAP_POSSESSIONS_SIZE does not reflect all actual _constants size due to bitmask-use compatibility - // - // when setting NPC-based values, try to adhere to an EmuConstants:: or NOT_USED value to avoid unnecessary issues - - static const uint16 local[_MapCount][CLIENT_VERSION_COUNT] = { - // server and database are sync'd to current MapPossessions's client as set in 'using namespace RoF::slots;' and - // 'EmuConstants::MAP_POSSESSIONS_SIZE' - use/update EquipmentBitmask(), GeneralBitmask() and CursorBitmask() - // for partial range validation checks and 'EmuConstants::MAP_POSSESSIONS_SIZE' for full range iterations - { // local[MainPossessions] -/*Unknown*/ NOT_USED, -/*62*/ EmuConstants::MAP_POSSESSIONS_SIZE, -/*Titanium*/ EmuConstants::MAP_POSSESSIONS_SIZE, -/*SoF*/ EmuConstants::MAP_POSSESSIONS_SIZE, -/*SoD*/ EmuConstants::MAP_POSSESSIONS_SIZE, -/*Underfoot*/ EmuConstants::MAP_POSSESSIONS_SIZE, -/*RoF*/ EmuConstants::MAP_POSSESSIONS_SIZE, -/*RoF2*/ EmuConstants::MAP_POSSESSIONS_SIZE, - -/*NPC*/ EmuConstants::MAP_POSSESSIONS_SIZE, -/*Merc*/ EmuConstants::MAP_POSSESSIONS_SIZE, -/*Bot*/ EmuConstants::MAP_POSSESSIONS_SIZE, -/*Pet*/ EmuConstants::MAP_POSSESSIONS_SIZE - }, - { // local[MapBank] -/*Unknown*/ NOT_USED, -/*62*/ NOT_USED, -/*Titanium*/ Titanium::consts::MAP_BANK_SIZE, -/*SoF*/ EmuConstants::MAP_BANK_SIZE, -/*SoD*/ EmuConstants::MAP_BANK_SIZE, -/*Underfoot*/ EmuConstants::MAP_BANK_SIZE, -/*RoF*/ EmuConstants::MAP_BANK_SIZE, -/*RoF2*/ EmuConstants::MAP_BANK_SIZE, - -/*NPC*/ NOT_USED, -/*Merc*/ NOT_USED, -/*Bot*/ NOT_USED, -/*Pet*/ NOT_USED - }, - { // local[MapSharedBank] -/*Unknown*/ NOT_USED, -/*62*/ EmuConstants::MAP_SHARED_BANK_SIZE, -/*Titanium*/ EmuConstants::MAP_SHARED_BANK_SIZE, -/*SoF*/ EmuConstants::MAP_SHARED_BANK_SIZE, -/*SoD*/ EmuConstants::MAP_SHARED_BANK_SIZE, -/*Underfoot*/ EmuConstants::MAP_SHARED_BANK_SIZE, -/*RoF*/ EmuConstants::MAP_SHARED_BANK_SIZE, -/*RoF2*/ EmuConstants::MAP_SHARED_BANK_SIZE, - -/*NPC*/ NOT_USED, -/*Merc*/ NOT_USED, -/*Bot*/ NOT_USED, -/*Pet*/ NOT_USED - }, - { // local[MapTrade] -/*Unknown*/ NOT_USED, -/*62*/ EmuConstants::MAP_TRADE_SIZE, -/*Titanium*/ EmuConstants::MAP_TRADE_SIZE, -/*SoF*/ EmuConstants::MAP_TRADE_SIZE, -/*SoD*/ EmuConstants::MAP_TRADE_SIZE, -/*Underfoot*/ EmuConstants::MAP_TRADE_SIZE, -/*RoF*/ EmuConstants::MAP_TRADE_SIZE, -/*RoF2*/ EmuConstants::MAP_TRADE_SIZE, - -/*NPC*/ 4, -/*Merc*/ 4, -/*Bot*/ EmuConstants::MAP_TRADE_SIZE, // client thinks this is another client -/*Pet*/ 4 - }, - { // local[MapWorld] -/*Unknown*/ NOT_USED, -/*62*/ EmuConstants::MAP_WORLD_SIZE, -/*Titanium*/ EmuConstants::MAP_WORLD_SIZE, -/*SoF*/ EmuConstants::MAP_WORLD_SIZE, -/*SoD*/ EmuConstants::MAP_WORLD_SIZE, -/*Underfoot*/ EmuConstants::MAP_WORLD_SIZE, -/*RoF*/ EmuConstants::MAP_WORLD_SIZE, -/*RoF2*/ EmuConstants::MAP_WORLD_SIZE, - -/*NPC*/ NOT_USED, -/*Merc*/ NOT_USED, -/*Bot*/ NOT_USED, -/*Pet*/ NOT_USED - }, - { // local[MapLimbo] -/*Unknown*/ NOT_USED, -/*62*/ EmuConstants::MAP_LIMBO_SIZE, -/*Titanium*/ EmuConstants::MAP_LIMBO_SIZE, -/*SoF*/ EmuConstants::MAP_LIMBO_SIZE, -/*SoD*/ EmuConstants::MAP_LIMBO_SIZE, -/*Underfoot*/ EmuConstants::MAP_LIMBO_SIZE, -/*RoF*/ EmuConstants::MAP_LIMBO_SIZE, -/*RoF2*/ EmuConstants::MAP_LIMBO_SIZE, - -/*NPC*/ NOT_USED, -/*Merc*/ NOT_USED, -/*Bot*/ NOT_USED, -/*Pet*/ NOT_USED - }, - { // local[MapTribute] -/*Unknown*/ NOT_USED, -/*62*/ EmuConstants::MAP_TRIBUTE_SIZE, -/*Titanium*/ EmuConstants::MAP_TRIBUTE_SIZE, -/*SoF*/ EmuConstants::MAP_TRIBUTE_SIZE, -/*SoD*/ EmuConstants::MAP_TRIBUTE_SIZE, -/*Underfoot*/ EmuConstants::MAP_TRIBUTE_SIZE, -/*RoF*/ EmuConstants::MAP_TRIBUTE_SIZE, -/*RoF2*/ EmuConstants::MAP_TRIBUTE_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapTrophyTribute] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_TROPHY_TRIBUTE_SIZE, -/*RoF2*/ EmuConstants::MAP_TROPHY_TRIBUTE_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapGuildTribute] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_GUILD_TRIBUTE_SIZE, -/*RoF2*/ EmuConstants::MAP_GUILD_TRIBUTE_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapMerchant] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_MERCHANT_SIZE, -/*RoF2*/ EmuConstants::MAP_MERCHANT_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapDeleted] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_DELETED_SIZE, -/*RoF2*/ EmuConstants::MAP_DELETED_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapCorpse] -/*Unknown*/ NOT_USED, -/*62*/ NOT_USED, -/*Titanium*/ Titanium::consts::MAP_CORPSE_SIZE, -/*SoF*/ SoF::consts::MAP_CORPSE_SIZE, -/*SoD*/ SoD::consts::MAP_CORPSE_SIZE, -/*Underfoot*/ UF::consts::MAP_CORPSE_SIZE, -/*RoF*/ RoF::consts::MAP_CORPSE_SIZE, -/*RoF2*/ RoF2::consts::MAP_CORPSE_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapBazaar] -/*Unknown*/ NOT_USED, -/*62*/ EmuConstants::MAP_BAZAAR_SIZE, -/*Titanium*/ EmuConstants::MAP_BAZAAR_SIZE, -/*SoF*/ EmuConstants::MAP_BAZAAR_SIZE, -/*SoD*/ EmuConstants::MAP_BAZAAR_SIZE, -/*Underfoot*/ EmuConstants::MAP_BAZAAR_SIZE, -/*RoF*/ EmuConstants::MAP_BAZAAR_SIZE, -/*RoF2*/ EmuConstants::MAP_BAZAAR_SIZE, - -/*NPC*/ 0, // this may need to be 'EmuConstants::MAP_BAZAAR_SIZE' if offline client traders respawn as an npc -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapInspect] -/*Unknown*/ NOT_USED, -/*62*/ NOT_USED, -/*Titanium*/ Titanium::consts::MAP_INSPECT_SIZE, -/*SoF*/ SoF::consts::MAP_INSPECT_SIZE, -/*SoD*/ SoD::consts::MAP_INSPECT_SIZE, -/*Underfoot*/ UF::consts::MAP_INSPECT_SIZE, -/*RoF*/ RoF::consts::MAP_INSPECT_SIZE, -/*RoF2*/ RoF2::consts::MAP_INSPECT_SIZE, - -/*NPC*/ NOT_USED, -/*Merc*/ NOT_USED, -/*Bot*/ NOT_USED, -/*Pet*/ NOT_USED - }, - { // local[MapRealEstate] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_REAL_ESTATE_SIZE, -/*RoF2*/ EmuConstants::MAP_REAL_ESTATE_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapViewMODPC] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_VIEW_MOD_PC_SIZE, -/*RoF2*/ EmuConstants::MAP_VIEW_MOD_PC_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapViewMODBank] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_VIEW_MOD_BANK_SIZE, -/*RoF2*/ EmuConstants::MAP_VIEW_MOD_BANK_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapViewMODSharedBank] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_VIEW_MOD_SHARED_BANK_SIZE, -/*RoF2*/ EmuConstants::MAP_VIEW_MOD_SHARED_BANK_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapViewMODLimbo] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_VIEW_MOD_LIMBO_SIZE, -/*RoF2*/ EmuConstants::MAP_VIEW_MOD_LIMBO_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapAltStorage] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_ALT_STORAGE_SIZE, -/*RoF2*/ EmuConstants::MAP_ALT_STORAGE_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapArchived] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_ARCHIVED_SIZE, -/*RoF2*/ EmuConstants::MAP_ARCHIVED_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapMail] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_MAIL_SIZE, -/*RoF2*/ EmuConstants::MAP_MAIL_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapGuildTrophyTribute] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_GUILD_TROPHY_TRIBUTE_SIZE, -/*RoF2*/ EmuConstants::MAP_GUILD_TROPHY_TRIBUTE_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapKrono] -/*Unknown*/ NOT_USED, -/*62*/ NOT_USED, -/*Titanium*/ NOT_USED, -/*SoF*/ NOT_USED, -/*SoD*/ NOT_USED, -/*Underfoot*/ NOT_USED, -/*RoF*/ EmuConstants::MAP_KRONO_SIZE, -/*RoF2*/ EmuConstants::MAP_KRONO_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }, - { // local[MapOther] -/*Unknown*/ NOT_USED, -/*62*/ 0, -/*Titanium*/ 0, -/*SoF*/ 0, -/*SoD*/ 0, -/*Underfoot*/ 0, -/*RoF*/ EmuConstants::MAP_OTHER_SIZE, -/*RoF2*/ EmuConstants::MAP_OTHER_SIZE, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - } - }; - - if ((uint16)indexMap < _MapCount) - return local[indexMap][static_cast(ValidateMobClientVersion(clientVersion))]; - - return NOT_USED; -} - -uint64 EQLimits::PossessionsBitmask(ClientVersion clientVersion) -{ - // these are for the new inventory system (RoF)..not the current (Ti) one... - // 0x0000000000200000 is SlotPowerSource (SoF+) - // 0x0000000080000000 is SlotGeneral9 (RoF+) - // 0x0000000100000000 is SlotGeneral10 (RoF+) - - static const uint64 local[CLIENT_VERSION_COUNT] = { -/*Unknown*/ NOT_USED, -/*62*/ 0x000000027FDFFFFF, -/*Titanium*/ 0x000000027FDFFFFF, -/*SoF*/ 0x000000027FFFFFFF, -/*SoD*/ 0x000000027FFFFFFF, -/*Underfoot*/ 0x000000027FFFFFFF, -/*RoF*/ 0x00000003FFFFFFFF, -/*RoF2*/ 0, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }; - - return NOT_USED; - //return local[static_cast(ValidateMobClientVersion(clientVersion))]; -} - -uint64 EQLimits::EquipmentBitmask(ClientVersion clientVersion) -{ - static const uint64 local[CLIENT_VERSION_COUNT] = { -/*Unknown*/ NOT_USED, -/*62*/ 0x00000000005FFFFF, -/*Titanium*/ 0x00000000005FFFFF, -/*SoF*/ 0x00000000007FFFFF, -/*SoD*/ 0x00000000007FFFFF, -/*Underfoot*/ 0x00000000007FFFFF, -/*RoF*/ 0x00000000007FFFFF, -/*RoF2*/ 0, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }; - - return NOT_USED; - //return local[static_cast(ValidateMobClientVersion(clientVersion))]; -} - -uint64 EQLimits::GeneralBitmask(ClientVersion clientVersion) -{ - static const uint64 local[CLIENT_VERSION_COUNT] = { -/*Unknown*/ NOT_USED, -/*62*/ 0x000000007F800000, -/*Titanium*/ 0x000000007F800000, -/*SoF*/ 0x000000007F800000, -/*SoD*/ 0x000000007F800000, -/*Underfoot*/ 0x000000007F800000, -/*RoF*/ 0x00000001FF800000, -/*RoF2*/ 0, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }; - - return NOT_USED; - //return local[static_cast(ValidateMobClientVersion(clientVersion))]; -} - -uint64 EQLimits::CursorBitmask(ClientVersion clientVersion) -{ - static const uint64 local[CLIENT_VERSION_COUNT] = { -/*Unknown*/ NOT_USED, -/*62*/ 0x0000000200000000, -/*Titanium*/ 0x0000000200000000, -/*SoF*/ 0x0000000200000000, -/*SoD*/ 0x0000000200000000, -/*Underfoot*/ 0x0000000200000000, -/*RoF*/ 0x0000000200000000, -/*RoF2*/ 0, - -/*NPC*/ 0, -/*Merc*/ 0, -/*Bot*/ 0, -/*Pet*/ 0 - }; - - return NOT_USED; - //return local[static_cast(ValidateMobClientVersion(clientVersion))]; -} - -bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion) -{ - static const bool local[CLIENT_VERSION_COUNT] = { -/*Unknown*/ false, -/*62*/ false, -/*Titanium*/ Titanium::limits::ALLOWS_EMPTY_BAG_IN_BAG, -/*SoF*/ SoF::limits::ALLOWS_EMPTY_BAG_IN_BAG, -/*SoD*/ SoD::limits::ALLOWS_EMPTY_BAG_IN_BAG, -/*Underfoot*/ UF::limits::ALLOWS_EMPTY_BAG_IN_BAG, -/*RoF*/ RoF::limits::ALLOWS_EMPTY_BAG_IN_BAG, -/*RoF2*/ RoF2::limits::ALLOWS_EMPTY_BAG_IN_BAG, - -/*NPC*/ false, -/*Merc*/ false, -/*Bot*/ false, -/*Pet*/ false - }; - - return false; // not implemented - //return local[static_cast(ValidateMobClientVersion(clientVersion))]; -} - -bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion) -{ - static const bool local[CLIENT_VERSION_COUNT] = { -/*Unknown*/ false, -/*62*/ false, -/*Titanium*/ Titanium::limits::ALLOWS_CLICK_CAST_FROM_BAG, -/*SoF*/ SoF::limits::ALLOWS_CLICK_CAST_FROM_BAG, -/*SoD*/ SoD::limits::ALLOWS_CLICK_CAST_FROM_BAG, -/*Underfoot*/ UF::limits::ALLOWS_CLICK_CAST_FROM_BAG, -/*RoF*/ RoF::limits::ALLOWS_CLICK_CAST_FROM_BAG, -/*RoF2*/ RoF2::limits::ALLOWS_CLICK_CAST_FROM_BAG, - -/*NPC*/ false, -/*Merc*/ false, -/*Bot*/ false, -/*Pet*/ false - }; - - return local[static_cast(ValidateMobClientVersion(clientVersion))]; -} - -// items -uint16 EQLimits::ItemCommonSize(ClientVersion clientVersion) -{ - static const uint16 local[CLIENT_VERSION_COUNT] = { -/*Unknown*/ NOT_USED, -/*62*/ EmuConstants::ITEM_COMMON_SIZE, -/*Titanium*/ EmuConstants::ITEM_COMMON_SIZE, -/*SoF*/ EmuConstants::ITEM_COMMON_SIZE, -/*SoD*/ EmuConstants::ITEM_COMMON_SIZE, -/*Underfoot*/ EmuConstants::ITEM_COMMON_SIZE, -/*RoF*/ EmuConstants::ITEM_COMMON_SIZE, -/*RoF2*/ EmuConstants::ITEM_COMMON_SIZE, - -/*NPC*/ EmuConstants::ITEM_COMMON_SIZE, -/*Merc*/ EmuConstants::ITEM_COMMON_SIZE, -/*Bot*/ EmuConstants::ITEM_COMMON_SIZE, -/*Pet*/ EmuConstants::ITEM_COMMON_SIZE - }; - - return local[static_cast(ValidateMobClientVersion(clientVersion))]; -} - -uint16 EQLimits::ItemContainerSize(ClientVersion clientVersion) -{ - static const uint16 local[CLIENT_VERSION_COUNT] = { -/*Unknown*/ NOT_USED, -/*62*/ EmuConstants::ITEM_CONTAINER_SIZE, -/*Titanium*/ EmuConstants::ITEM_CONTAINER_SIZE, -/*SoF*/ EmuConstants::ITEM_CONTAINER_SIZE, -/*SoD*/ EmuConstants::ITEM_CONTAINER_SIZE, -/*Underfoot*/ EmuConstants::ITEM_CONTAINER_SIZE, -/*RoF*/ EmuConstants::ITEM_CONTAINER_SIZE, -/*RoF2*/ EmuConstants::ITEM_CONTAINER_SIZE, - -/*NPC*/ EmuConstants::ITEM_CONTAINER_SIZE, -/*Merc*/ EmuConstants::ITEM_CONTAINER_SIZE, -/*Bot*/ EmuConstants::ITEM_CONTAINER_SIZE, -/*Pet*/ EmuConstants::ITEM_CONTAINER_SIZE - }; - - return local[static_cast(ValidateMobClientVersion(clientVersion))]; -} - -bool EQLimits::CoinHasWeight(ClientVersion clientVersion) -{ - static const bool local[CLIENT_VERSION_COUNT] = { -/*Unknown*/ true, -/*62*/ true, -/*Titanium*/ Titanium::limits::COIN_HAS_WEIGHT, -/*SoF*/ SoF::limits::COIN_HAS_WEIGHT, -/*SoD*/ SoD::limits::COIN_HAS_WEIGHT, -/*Underfoot*/ UF::limits::COIN_HAS_WEIGHT, -/*RoF*/ RoF::limits::COIN_HAS_WEIGHT, -/*RoF2*/ RoF::limits::COIN_HAS_WEIGHT, - -/*NPC*/ true, -/*Merc*/ true, -/*Bot*/ true, -/*Pet*/ true - }; - - return local[static_cast(ValidateMobClientVersion(clientVersion))]; -} diff --git a/common/eq_dictionary.h b/common/eq_dictionary.h deleted file mode 100644 index 7828dd5cc..000000000 --- a/common/eq_dictionary.h +++ /dev/null @@ -1,205 +0,0 @@ -/* -EQEMu: Everquest Server Emulator - -Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY except by those people which sell it, which -are required to give you total support for your newly bought product; -without even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -#ifndef EQ_DICTIONARY_H -#define EQ_DICTIONARY_H - -#include "types.h" -#include "eq_constants.h" -#include "clientversions.h" -#include -#include "../common/patches/titanium_constants.h" -#include "../common/patches/sof_constants.h" -#include "../common/patches/sod_constants.h" -#include "../common/patches/uf_constants.h" -#include "../common/patches/rof_constants.h" -#include "../common/patches/rof2_constants.h" - -// *** DO NOT CHANGE without a full understanding of the consequences..the server is set up to use these settings explicitly!! *** -// *** You will cause compilation failures and corrupt your database if partial or incorrect attempts to change them are made!! *** - -// Hard-coded values usually indicate that further research is needed and the values given are from the old (known) system - -// (future use) -//using namespace RoF2::maps; // server inventory maps enumeration (code and database sync'd to reference) -//using namespace RoF::slots; // server possessions slots enumeration (code and database sync'd to reference) - -class EmuConstants -{ - // an immutable value is required to initialize arrays, etc... use this class as a repository for those -public: - // database - static const ClientVersion CHARACTER_CREATION_CLIENT = ClientVersion::RoF2; // adjust according to starting item placement and target client - - static const size_t CHARACTER_CREATION_LIMIT = RoF2::consts::CHARACTER_CREATION_LIMIT; - - // inventory - static uint16 InventoryMapSize(int16 indexMap); - //static std::string InventoryLocationName(Location_Struct location); - static std::string InventoryMapName(int16 indexMap); - static std::string InventoryMainName(int16 indexMain); - static std::string InventorySubName(int16 indexSub); - static std::string InventoryAugName(int16 indexAug); - - // these are currently hard-coded for existing inventory system..do not use in place of special client version handlers until ready - static const uint16 MAP_POSSESSIONS_SIZE = _MainCount; - static const uint16 MAP_BANK_SIZE = 24; - static const uint16 MAP_SHARED_BANK_SIZE = 2; - static const uint16 MAP_TRADE_SIZE = 8; - static const uint16 MAP_WORLD_SIZE = 10; - static const uint16 MAP_LIMBO_SIZE = 36; - static const uint16 MAP_TRIBUTE_SIZE = 5; // (need client values) - static const uint16 MAP_TROPHY_TRIBUTE_SIZE = 0; - static const uint16 MAP_GUILD_TRIBUTE_SIZE = 0; - static const uint16 MAP_MERCHANT_SIZE = 0; - static const uint16 MAP_DELETED_SIZE = 0; - static const uint16 MAP_CORPSE_SIZE = _MainCount; // no bitmask use..limits to size of client corpse window (see EQLimits::InventoryMapSize(MapCorpse, (versions::ValidateClientVersion(client_version))]; +} + +static const EQEmu::inventory::LookupEntry inventory_lookup_entries[EQEmu::versions::MobVersionCount] = +{ + { + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + + ClientUnknown::False, + ClientUnknown::False, + ClientUnknown::False, + ClientUnknown::False + }, + { + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + + Client62::Null, + Client62::Null, + Client62::Null, + + Client62::False, + Client62::False, + Client62::False, + Client62::False + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*Titanium::invtype::InvTypePossessionsSize,*/ + Titanium::invtype::InvTypeBankSize, + Titanium::invtype::InvTypeSharedBankSize, + Titanium::invtype::InvTypeTradeSize, + Titanium::invtype::InvTypeWorldSize, + Titanium::invtype::InvTypeLimboSize, + Titanium::invtype::InvTypeTributeSize, + Titanium::Null, + Titanium::Null, /*Titanium::invtype::InvTypeGuildTributeSize,*/ + Titanium::invtype::InvTypeMerchantSize, + Titanium::Null, + Titanium::invtype::InvTypeCorpseSize, + EQEmu::legacy::TYPE_BAZAAR_SIZE, /*Titanium::invtype::InvTypeBazaarSize,*/ + Titanium::invtype::InvTypeInspectSize, + Titanium::Null, + Titanium::invtype::InvTypeViewMODPCSize, + Titanium::invtype::InvTypeViewMODBankSize, + Titanium::invtype::InvTypeViewMODSharedBankSize, + Titanium::invtype::InvTypeViewMODLimboSize, + Titanium::invtype::InvTypeAltStorageSize, + Titanium::invtype::InvTypeArchivedSize, + Titanium::Null, + Titanium::Null, + Titanium::Null, + Titanium::invtype::InvTypeOtherSize, + + Titanium::Null, /*0x000000027FDFFFFF,*/ + EQEmu::inventory::ContainerCount, /*Titanium::invbag::ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*Titanium::invaug::ItemAugSize,*/ + + Titanium::inventory::AllowEmptyBagInBag, + Titanium::inventory::AllowClickCastFromBag, + Titanium::inventory::ConcatenateInvTypeLimbo, + Titanium::inventory::AllowOverLevelEquipment + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*SoF::invtype::InvTypePossessionsSize,*/ + SoF::invtype::InvTypeBankSize, + SoF::invtype::InvTypeSharedBankSize, + SoF::invtype::InvTypeTradeSize, + SoF::invtype::InvTypeWorldSize, + SoF::invtype::InvTypeLimboSize, + SoF::invtype::InvTypeTributeSize, + SoF::Null, + SoF::Null, /*SoF::invtype::InvTypeGuildTributeSize,*/ + SoF::invtype::InvTypeMerchantSize, + SoF::Null, + SoF::invtype::InvTypeCorpseSize, + EQEmu::legacy::TYPE_BAZAAR_SIZE, /*SoF::invtype::InvTypeBazaarSize,*/ + SoF::invtype::InvTypeInspectSize, + SoF::Null, + SoF::invtype::InvTypeViewMODPCSize, + SoF::invtype::InvTypeViewMODBankSize, + SoF::invtype::InvTypeViewMODSharedBankSize, + SoF::invtype::InvTypeViewMODLimboSize, + SoF::invtype::InvTypeAltStorageSize, + SoF::invtype::InvTypeArchivedSize, SoF::Null, SoF::Null, SoF::Null, SoF::invtype::InvTypeOtherSize, + + SoF::Null, /*0x000000027FFFFFFF,*/ + EQEmu::inventory::ContainerCount, /*SoF::invbag::ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*SoF::invaug::ItemAugSize,*/ + + SoF::inventory::AllowEmptyBagInBag, + SoF::inventory::AllowClickCastFromBag, + SoF::inventory::ConcatenateInvTypeLimbo, + SoF::inventory::AllowOverLevelEquipment + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*SoD::invtype::InvTypePossessionsSize,*/ + SoD::invtype::InvTypeBankSize, + SoD::invtype::InvTypeSharedBankSize, + SoD::invtype::InvTypeTradeSize, + SoD::invtype::InvTypeWorldSize, + SoD::invtype::InvTypeLimboSize, + SoD::invtype::InvTypeTributeSize, + SoD::Null, + SoD::Null, /*SoD::invtype::InvTypeGuildTributeSize,*/ + SoD::invtype::InvTypeMerchantSize, + SoD::Null, + SoD::invtype::InvTypeCorpseSize, + EQEmu::legacy::TYPE_BAZAAR_SIZE, /*SoD::invtype::InvTypeBazaarSize,*/ + SoD::invtype::InvTypeInspectSize, + SoD::Null, + SoD::invtype::InvTypeViewMODPCSize, + SoD::invtype::InvTypeViewMODBankSize, + SoD::invtype::InvTypeViewMODSharedBankSize, + SoD::invtype::InvTypeViewMODLimboSize, + SoD::invtype::InvTypeAltStorageSize, + SoD::invtype::InvTypeArchivedSize, + SoD::Null, + SoD::Null, + SoD::Null, + SoD::invtype::InvTypeOtherSize, + + SoD::Null, /*0x000000027FFFFFFF,*/ + EQEmu::inventory::ContainerCount, /*SoD::invbag::ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*SoD::invaug::ItemAugSize,*/ + + SoD::inventory::AllowEmptyBagInBag, + SoD::inventory::AllowClickCastFromBag, + SoD::inventory::ConcatenateInvTypeLimbo, + SoD::inventory::AllowOverLevelEquipment + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*UF::invtype::InvTypePossessionsSize,*/ + UF::invtype::InvTypeBankSize, + UF::invtype::InvTypeSharedBankSize, + UF::invtype::InvTypeTradeSize, + UF::invtype::InvTypeWorldSize, + UF::invtype::InvTypeLimboSize, + UF::invtype::InvTypeTributeSize, + UF::Null, + UF::Null, /*UF::invtype::InvTypeGuildTributeSize,*/ + UF::invtype::InvTypeMerchantSize, + UF::Null, + UF::invtype::InvTypeCorpseSize, + EQEmu::legacy::TYPE_BAZAAR_SIZE, /*UF::invtype::InvTypeBazaarSize,*/ + UF::invtype::InvTypeInspectSize, + UF::Null, + UF::invtype::InvTypeViewMODPCSize, + UF::invtype::InvTypeViewMODBankSize, + UF::invtype::InvTypeViewMODSharedBankSize, + UF::invtype::InvTypeViewMODLimboSize, + UF::invtype::InvTypeAltStorageSize, + UF::invtype::InvTypeArchivedSize, + UF::Null, + UF::Null, + UF::Null, + UF::invtype::InvTypeOtherSize, + + UF::Null, /*0x000000027FFFFFFF,*/ + EQEmu::inventory::ContainerCount, /*UF::invbag::ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*UF::invaug::ItemAugSize,*/ + + UF::inventory::AllowEmptyBagInBag, + UF::inventory::AllowClickCastFromBag, + UF::inventory::ConcatenateInvTypeLimbo, + UF::inventory::AllowOverLevelEquipment + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*RoF::invtype::InvTypePossessionsSize,*/ + RoF::invtype::InvTypeBankSize, + RoF::invtype::InvTypeSharedBankSize, + RoF::invtype::InvTypeTradeSize, + RoF::invtype::InvTypeWorldSize, + RoF::invtype::InvTypeLimboSize, + RoF::invtype::InvTypeTributeSize, + RoF::Null, /*RoF::invtype::InvTypeTrophyTributeSize,*/ + RoF::Null, /*RoF::invtype::InvTypeGuildTributeSize,*/ + RoF::invtype::InvTypeMerchantSize, + RoF::Null, /*RoF::invtype::InvTypeDeletedSize,*/ + RoF::invtype::InvTypeCorpseSize, + EQEmu::legacy::TYPE_BAZAAR_SIZE, /*RoF::invtype::InvTypeBazaarSize,*/ + RoF::invtype::InvTypeInspectSize, + RoF::Null, /*RoF::invtype::InvTypeRealEstateSize,*/ + RoF::invtype::InvTypeViewMODPCSize, + RoF::invtype::InvTypeViewMODBankSize, + RoF::invtype::InvTypeViewMODSharedBankSize, + RoF::invtype::InvTypeViewMODLimboSize, + RoF::invtype::InvTypeAltStorageSize, + RoF::invtype::InvTypeArchivedSize, + RoF::invtype::InvTypeMailSize, + RoF::invtype::InvTypeGuildTrophyTributeSize, + RoF::Null, + RoF::invtype::InvTypeOtherSize, + + RoF::Null, /*0x00000003FFFFFFFF,*/ + EQEmu::inventory::ContainerCount, /*RoF::invbag::ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*RoF::invaug::ItemAugSize,*/ + + RoF::False, /*RoF::inventory::AllowEmptyBagInBag,*/ + RoF::inventory::AllowClickCastFromBag, + RoF::inventory::ConcatenateInvTypeLimbo, + RoF::inventory::AllowOverLevelEquipment + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*RoF2::invtype::InvTypePossessionsSize,*/ + RoF2::invtype::InvTypeBankSize, + RoF2::invtype::InvTypeSharedBankSize, + RoF2::invtype::InvTypeTradeSize, + RoF2::invtype::InvTypeWorldSize, + RoF2::invtype::InvTypeLimboSize, + RoF2::invtype::InvTypeTributeSize, + RoF2::Null, /*RoF2::invtype::InvTypeTrophyTributeSize,*/ + RoF2::Null, /*RoF2::invtype::InvTypeGuildTributeSize,*/ + RoF2::invtype::InvTypeMerchantSize, + RoF2::Null, /*RoF2::invtype::InvTypeDeletedSize,*/ + RoF2::invtype::InvTypeCorpseSize, + EQEmu::legacy::TYPE_BAZAAR_SIZE, /*RoF2::invtype::InvTypeBazaarSize,*/ + RoF2::invtype::InvTypeInspectSize, + RoF2::Null, /*RoF2::invtype::InvTypeRealEstateSize*/ + RoF2::invtype::InvTypeViewMODPCSize, + RoF2::invtype::InvTypeViewMODBankSize, + RoF2::invtype::InvTypeViewMODSharedBankSize, + RoF2::invtype::InvTypeViewMODLimboSize, + RoF2::invtype::InvTypeAltStorageSize, + RoF2::invtype::InvTypeArchivedSize, + RoF2::invtype::InvTypeMailSize, + RoF2::invtype::InvTypeGuildTrophyTributeSize, + RoF2::invtype::InvTypeKronoSize, + RoF2::invtype::InvTypeOtherSize, + + RoF2::Null, /*0x00000003FFFFFFFF,*/ + EQEmu::inventory::ContainerCount, /*RoF2::invbag::ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*RoF2::invaug::ItemAugSize,*/ + + RoF2::False, /*RoF2::inventory::AllowEmptyBagInBag,*/ + RoF2::inventory::AllowClickCastFromBag, + RoF2::inventory::ConcatenateInvTypeLimbo, + RoF2::inventory::AllowOverLevelEquipment + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::InvTypeTradeSize, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, /*InvTypeCorpseSize,*/ + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + EntityLimits::NPC::Null, + + EntityLimits::NPC::Null, + EQEmu::inventory::ContainerCount, /*ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*ItemAugSize,*/ + + EntityLimits::NPC::False, + EntityLimits::NPC::False, + EntityLimits::NPC::False, + EntityLimits::NPC::False + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::InvTypeTradeSize, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, /*InvTypeCorpseSize,*/ + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + EntityLimits::NPCMerchant::Null, + + EntityLimits::NPCMerchant::Null, + EQEmu::inventory::ContainerCount, /*ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*ItemAugSize,*/ + + EntityLimits::NPCMerchant::False, + EntityLimits::NPCMerchant::False, + EntityLimits::NPCMerchant::False, + EntityLimits::NPCMerchant::False + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::InvTypeTradeSize, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, /*InvTypeCorpseSize,*/ + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + EntityLimits::Merc::Null, + + EntityLimits::Merc::Null, + EQEmu::inventory::ContainerCount, /*ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*ItemAugSize,*/ + + EntityLimits::Merc::False, + EntityLimits::Merc::False, + EntityLimits::Merc::False, + EntityLimits::Merc::False + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::InvTypeTradeSize, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, /*InvTypeCorpseSize,*/ + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + EntityLimits::Bot::Null, + + EntityLimits::Bot::Null, + EQEmu::inventory::ContainerCount, /*ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*ItemAugSize,*/ + + EntityLimits::Bot::False, + EntityLimits::Bot::False, + EntityLimits::Bot::False, + EntityLimits::Bot::False + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::InvTypeTradeSize, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, /*InvTypeCorpseSize,*/ + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + EntityLimits::ClientPet::Null, + + EntityLimits::ClientPet::Null, + EQEmu::inventory::ContainerCount, /*ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*ItemAugSize,*/ + + EntityLimits::ClientPet::False, + EntityLimits::ClientPet::False, + EntityLimits::ClientPet::False, + EntityLimits::ClientPet::False + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::InvTypeTradeSize, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, /*InvTypeCorpseSize,*/ + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + EntityLimits::NPCPet::Null, + + EntityLimits::NPCPet::Null, + EQEmu::inventory::ContainerCount, /*ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*ItemAugSize,*/ + + EntityLimits::NPCPet::False, + EntityLimits::NPCPet::False, + EntityLimits::NPCPet::False, + EntityLimits::NPCPet::False + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::InvTypeTradeSize, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, /*InvTypeCorpseSize,*/ + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + EntityLimits::MercPet::Null, + + EntityLimits::MercPet::Null, + EQEmu::inventory::ContainerCount, /*ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*ItemAugSize,*/ + + EntityLimits::MercPet::False, + EntityLimits::MercPet::False, + EntityLimits::MercPet::False, + EntityLimits::MercPet::False + }, + { + EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::InvTypeTradeSize, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, /*InvTypeCorpseSize,*/ + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + EntityLimits::BotPet::Null, + + EntityLimits::BotPet::Null, + EQEmu::inventory::ContainerCount, /*ItemBagSize,*/ + EQEmu::inventory::SocketCount, /*ItemAugSize,*/ + + EntityLimits::BotPet::False, + EntityLimits::BotPet::False, + EntityLimits::BotPet::False, + EntityLimits::BotPet::False + }, + { // OfflineTitanium + Titanium::Null, + Titanium::Null, + Titanium::Null, + Titanium::invtype::InvTypeTradeSize, + Titanium::Null, + Titanium::Null, + Titanium::Null, + Titanium::Null, + Titanium::Null, + Titanium::invtype::InvTypeMerchantSize, + Titanium::Null, + Titanium::Null, + Titanium::Null, /*Titanium::invtype::InvTypeBazaarSize,*/ + Titanium::invtype::InvTypeInspectSize, + Titanium::Null, + Titanium::invtype::InvTypeViewMODPCSize, + Titanium::invtype::InvTypeViewMODBankSize, + Titanium::invtype::InvTypeViewMODSharedBankSize, + Titanium::invtype::InvTypeViewMODLimboSize, + Titanium::Null, + Titanium::Null, + Titanium::Null, + Titanium::Null, + Titanium::Null, + Titanium::Null, + + Titanium::Null, + EQEmu::inventory::ContainerCount, /*Titanium::Null,*/ + Titanium::Null, + + Titanium::False, + Titanium::False, + Titanium::False, + Titanium::False + }, + { // OfflineSoF + SoF::Null, + SoF::Null, + SoF::Null, + SoF::invtype::InvTypeTradeSize, + SoF::Null, + SoF::Null, + SoF::Null, + SoF::Null, + SoF::Null, + SoF::invtype::InvTypeMerchantSize, + SoF::Null, + SoF::Null, + SoF::Null, /*SoF::invtype::InvTypeBazaarSize,*/ + SoF::invtype::InvTypeInspectSize, + SoF::Null, + SoF::invtype::InvTypeViewMODPCSize, + SoF::invtype::InvTypeViewMODBankSize, + SoF::invtype::InvTypeViewMODSharedBankSize, + SoF::invtype::InvTypeViewMODLimboSize, + SoF::Null, + SoF::Null, + SoF::Null, + SoF::Null, + SoF::Null, + SoF::Null, + + SoF::Null, + EQEmu::inventory::ContainerCount, /*SoF::Null,*/ + SoF::Null, + + SoF::False, + SoF::False, + SoF::False, + SoF::False + }, + { // OfflineSoD + SoD::Null, + SoD::Null, + SoD::Null, + SoD::invtype::InvTypeTradeSize, + SoD::Null, + SoD::Null, + SoD::Null, + SoD::Null, + SoD::Null, + SoD::invtype::InvTypeMerchantSize, + SoD::Null, + SoD::Null, + SoD::Null, /*SoD::invtype::InvTypeBazaarSize,*/ + SoD::invtype::InvTypeInspectSize, + SoD::Null, + SoD::invtype::InvTypeViewMODPCSize, + SoD::invtype::InvTypeViewMODBankSize, + SoD::invtype::InvTypeViewMODSharedBankSize, + SoD::invtype::InvTypeViewMODLimboSize, + SoD::Null, + SoD::Null, + SoD::Null, + SoD::Null, + SoD::Null, + SoD::Null, + + SoD::Null, + EQEmu::inventory::ContainerCount, /*SoD::Null,*/ + SoD::Null, + + SoD::False, + SoD::False, + SoD::False, + SoD::False + }, + { // OfflineUF + UF::Null, + UF::Null, + UF::Null, + UF::invtype::InvTypeTradeSize, + UF::Null, + UF::Null, + UF::Null, + UF::Null, + UF::Null, + UF::invtype::InvTypeMerchantSize, + UF::Null, + UF::Null, + UF::Null, /*UF::invtype::InvTypeBazaarSize,*/ + UF::invtype::InvTypeInspectSize, + UF::Null, + UF::invtype::InvTypeViewMODPCSize, + UF::invtype::InvTypeViewMODBankSize, + UF::invtype::InvTypeViewMODSharedBankSize, + UF::invtype::InvTypeViewMODLimboSize, + UF::Null, + UF::Null, + UF::Null, + UF::Null, + UF::Null, + UF::Null, + + UF::Null, + EQEmu::inventory::ContainerCount, /*UF::Null,*/ + UF::Null, + + UF::False, + UF::False, + UF::False, + UF::False + }, + { // OfflineRoF + RoF::Null, + RoF::Null, + RoF::Null, + RoF::invtype::InvTypeTradeSize, + RoF::Null, + RoF::Null, + RoF::Null, + RoF::Null, + RoF::Null, + RoF::invtype::InvTypeMerchantSize, + RoF::Null, + RoF::Null, + RoF::Null, /*RoF::invtype::InvTypeBazaarSize,*/ + RoF::invtype::InvTypeInspectSize, + RoF::Null, + RoF::invtype::InvTypeViewMODPCSize, + RoF::invtype::InvTypeViewMODBankSize, + RoF::invtype::InvTypeViewMODSharedBankSize, + RoF::invtype::InvTypeViewMODLimboSize, + RoF::Null, + RoF::Null, + RoF::Null, + RoF::Null, + RoF::Null, + RoF::Null, + + RoF::Null, + EQEmu::inventory::ContainerCount, /*RoF::Null,*/ + RoF::Null, + + RoF::False, + RoF::False, + RoF::False, + RoF::False + }, + { // OfflineRoF2 + RoF2::Null, + RoF2::Null, + RoF2::Null, + RoF2::invtype::InvTypeTradeSize, + RoF2::Null, + RoF2::Null, + RoF2::Null, + RoF2::Null, + RoF2::Null, + RoF2::invtype::InvTypeMerchantSize, + RoF2::Null, + RoF2::Null, + RoF2::Null, /*RoF2::invtype::InvTypeBazaarSize,*/ + RoF2::invtype::InvTypeInspectSize, + RoF2::Null, + RoF2::invtype::InvTypeViewMODPCSize, + RoF2::invtype::InvTypeViewMODBankSize, + RoF2::invtype::InvTypeViewMODSharedBankSize, + RoF2::invtype::InvTypeViewMODLimboSize, + RoF2::Null, + RoF2::Null, + RoF2::Null, + RoF2::Null, + RoF2::Null, + RoF2::Null, + + RoF2::Null, + EQEmu::inventory::ContainerCount, /*RoF2::Null,*/ + RoF2::Null, + + RoF2::False, + RoF2::False, + RoF2::False, + RoF2::False + } +}; + +const EQEmu::inventory::LookupEntry* EQEmu::inventory::Lookup(versions::MobVersion mob_version) +{ + return &inventory_lookup_entries[static_cast(versions::ValidateMobVersion(mob_version))]; +} + +static const EQEmu::behavior::LookupEntry behavior_lookup_entries[EQEmu::versions::MobVersionCount] = +{ + { // Unknown + ClientUnknown::True + }, + { // Client62 + Client62::True + }, + { // Titanium + Titanium::behavior::CoinHasWeight + }, + { // SoF + SoF::behavior::CoinHasWeight + }, + { // SoD + SoD::behavior::CoinHasWeight + }, + { // UF + UF::behavior::CoinHasWeight + }, + { // RoF + RoF::behavior::CoinHasWeight + }, + { // RoF2 + RoF2::behavior::CoinHasWeight + }, + { // NPC + EntityLimits::NPC::True /*CoinHasWeight*/ + }, + { // NPCMerchant + EntityLimits::NPC::True /*CoinHasWeight*/ + }, + { // Merc + EntityLimits::Merc::True /*CoinHasWeight*/ + }, + { // Bot + EntityLimits::Bot::True /*CoinHasWeight*/ + }, + { // ClientPet + EntityLimits::ClientPet::True /*CoinHasWeight*/ + }, + { // NPCPet + EntityLimits::NPCPet::True /*CoinHasWeight*/ + }, + { // MercPet + EntityLimits::MercPet::True /*CoinHasWeight*/ + }, + { // BotPet + EntityLimits::BotPet::True /*CoinHasWeight*/ + }, + { // OfflineTitanium + Titanium::False + }, + { // OfflineSoF + SoF::False + }, + { // OfflineSoD + SoD::False + }, + { // OfflineUF + UF::False + }, + { // OfflineRoF + RoF::False + }, + { // OfflineRoF2 + RoF2::False + } +}; + +const EQEmu::behavior::LookupEntry* EQEmu::behavior::Lookup(versions::MobVersion mob_version) +{ + return &behavior_lookup_entries[static_cast(versions::ValidateMobVersion(mob_version))]; +} diff --git a/common/eq_limits.h b/common/eq_limits.h new file mode 100644 index 000000000..252d23053 --- /dev/null +++ b/common/eq_limits.h @@ -0,0 +1,101 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef COMMON_EQ_LIMITS_H +#define COMMON_EQ_LIMITS_H + +#include "emu_legacy.h" +#include "types.h" +#include "eq_constants.h" +#include "emu_versions.h" +#include "../common/patches/titanium_limits.h" +#include "../common/patches/sof_limits.h" +#include "../common/patches/sod_limits.h" +#include "../common/patches/uf_limits.h" +#include "../common/patches/rof_limits.h" +#include "../common/patches/rof2_limits.h" + + +namespace EQEmu +{ + namespace constants { + class LookupEntry { + public: + size_t CharacterCreationLimit; + int LongBuffs; + int ShortBuffs; + int DiscBuffs; + int TotalBuffs; + int NPCBuffs; + int PetBuffs; + int MercBuffs; + }; + + const LookupEntry* Lookup(versions::ClientVersion client_version); + + } /*constants*/ + + namespace inventory { + class LookupEntry { + public: + size_t InventoryTypeSize[25]; // should reflect EQEmu::inventory::typeCount referenced in emu_constants.h + + uint64 PossessionsBitmask; + size_t ItemBagSize; + size_t ItemAugSize; + + bool AllowEmptyBagInBag; + bool AllowClickCastFromBag; + bool ConcatenateInvTypeLimbo; + bool AllowOverLevelEquipment; + }; + + const LookupEntry* Lookup(versions::MobVersion mob_version); + + } /*inventory*/ + + namespace behavior { + class LookupEntry { + public: + bool CoinHasWeight; + }; + + const LookupEntry* Lookup(versions::MobVersion mob_version); + + } /*behavior*/ + +} /*EQEmu*/ + +namespace ClientUnknown +{ + enum : int { Invalid = -1, Null, Safety }; + + enum : bool { False = false, True = true }; + +} /*ClientUnknown*/ + +namespace Client62 +{ + enum : int { Invalid = -1, Null, Safety }; + + enum : bool { False = false, True = true }; + +} /*Client62*/ + +#endif /*COMMON_EQ_LIMITS_H*/ diff --git a/common/eq_packet.cpp b/common/eq_packet.cpp index e01f6a3f8..d7e607d77 100644 --- a/common/eq_packet.cpp +++ b/common/eq_packet.cpp @@ -260,7 +260,7 @@ bool EQProtocolPacket::combine(const EQProtocolPacket *rhs) { bool result=false; if (opcode==OP_Combined && size+rhs->size+5<256) { - unsigned char *tmpbuffer=new unsigned char [size+rhs->size+3]; + auto tmpbuffer = new unsigned char[size + rhs->size + 3]; memcpy(tmpbuffer,pBuffer,size); uint32 offset=size; tmpbuffer[offset++]=rhs->Size(); @@ -270,7 +270,7 @@ bool result=false; pBuffer=tmpbuffer; result=true; } else if (size+rhs->size+7<256) { - unsigned char *tmpbuffer=new unsigned char [size+rhs->size+6]; + auto tmpbuffer = new unsigned char[size + rhs->size + 6]; uint32 offset=0; tmpbuffer[offset++]=Size(); offset+=serialize(tmpbuffer+offset); @@ -457,7 +457,7 @@ EQApplicationPacket *EQApplicationPacket::Copy() const { } EQRawApplicationPacket *EQProtocolPacket::MakeAppPacket() const { - EQRawApplicationPacket *res = new EQRawApplicationPacket(opcode, pBuffer, size); + auto res = new EQRawApplicationPacket(opcode, pBuffer, size); res->copyInfo(this); return(res); } diff --git a/common/eq_packet.h b/common/eq_packet.h index ed90d132a..94c8a1e10 100644 --- a/common/eq_packet.h +++ b/common/eq_packet.h @@ -62,7 +62,7 @@ class EQProtocolPacket : public BasePacket { friend class EQStream; friend class EQStreamPair; public: - EQProtocolPacket(uint16 op, const unsigned char *buf, uint32 len) : BasePacket(buf,len), opcode(op) { acked = false; } + EQProtocolPacket(uint16 op, const unsigned char *buf, uint32 len) : BasePacket(buf, len), opcode(op) { acked = false; sent_time = 0; } // EQProtocolPacket(const unsigned char *buf, uint32 len); bool combine(const EQProtocolPacket *rhs); uint32 serialize (unsigned char *dest) const; @@ -70,6 +70,7 @@ public: EQRawApplicationPacket *MakeAppPacket() const; bool acked; + uint32 sent_time; virtual void build_raw_header_dump(char *buffer, uint16 seq=0xffff) const; virtual void build_header_dump(char *buffer) const; diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index 74eb9536e..3730e1d14 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2003 EQEMu Development Team (http://eqemulator.net) + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,16 +25,17 @@ #include #include #include "../common/version.h" -//#include "../common/item_struct.h" +#include "emu_constants.h" +#include "textures.h" + static const uint32 BUFF_COUNT = 25; +static const uint32 PET_BUFF_COUNT = 30; static const uint32 MAX_MERC = 100; static const uint32 MAX_MERC_GRADES = 10; static const uint32 MAX_MERC_STANCES = 10; static const uint32 BLOCKED_BUFF_COUNT = 20; -//#include "eq_constants.h" -#include "eq_dictionary.h" /* ** Compiler override to ensure @@ -126,37 +127,7 @@ struct LDoNTrapTemplate // All clients translate the character select information to some degree -struct Color_Struct -{ - union { - struct { - uint8 Blue; - uint8 Green; - uint8 Red; - uint8 UseTint; // if there's a tint this is FF - } RGB; - uint32 Color; - }; -}; - -struct EquipStruct -{ - uint32 Material; - uint32 Unknown1; - uint32 EliteMaterial; - uint32 HeroForgeModel; - uint32 Material2; // Same as material? -}; - -struct CharSelectEquip -{ - uint32 Material; - uint32 Unknown1; - uint32 EliteMaterial; - uint32 HeroForgeModel; - uint32 Material2; - Color_Struct Color; -}; +struct CharSelectEquip : EQEmu::textures::Texture_Struct, EQEmu::textures::Tint_Struct {}; // RoF2-based hybrid struct struct CharacterSelectEntry_Struct @@ -171,7 +142,7 @@ struct CharacterSelectEntry_Struct uint16 Instance; uint8 Gender; uint8 Face; - CharSelectEquip Equip[9]; + CharSelectEquip Equip[EQEmu::textures::materialCount]; uint8 Unknown15; // Seen FF uint8 Unknown19; // Seen FF uint32 DrakkinTattoo; @@ -280,22 +251,7 @@ struct Spawn_Struct { /*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner /*0193*/ uint8 guildrank; // 0=normal, 1=officer, 2=leader /*0194*/ uint8 unknown0194[3]; -/*0197*/ union -{ - struct - { - /*0000*/ EquipStruct equip_helmet; // Equipment: Helmet visual - /*0000*/ EquipStruct equip_chest; // Equipment: Chest visual - /*0000*/ EquipStruct equip_arms; // Equipment: Arms visual - /*0000*/ EquipStruct equip_bracers; // Equipment: Wrist visual - /*0000*/ EquipStruct equip_hands; // Equipment: Hands visual - /*0000*/ EquipStruct equip_legs; // Equipment: Legs visual - /*0000*/ EquipStruct equip_feet; // Equipment: Boots visual - /*0000*/ EquipStruct equip_primary; // Equipment: Main visual - /*0000*/ EquipStruct equip_secondary; // Equipment: Off visual - } equip; - /*0000*/ EquipStruct equipment[_MaterialCount]; -}; +/*0197*/ EQEmu::TextureProfile equipment; /*0233*/ float runspeed; // Speed when running /*0036*/ uint8 afk; // 0=no, 1=afk /*0238*/ uint32 guildID; // Current guild @@ -326,22 +282,7 @@ union /*0340*/ uint32 spawnId; // Spawn Id /*0344*/ uint8 unknown0344[3]; /*0347*/ uint8 IsMercenary; -/*0348*/ union - { - struct - { - /*0348*/ Color_Struct color_helmet; // Color of helmet item - /*0352*/ Color_Struct color_chest; // Color of chest item - /*0356*/ Color_Struct color_arms; // Color of arms item - /*0360*/ Color_Struct color_bracers; // Color of bracers item - /*0364*/ Color_Struct color_hands; // Color of hands item - /*0368*/ Color_Struct color_legs; // Color of legs item - /*0372*/ Color_Struct color_feet; // Color of feet item - /*0376*/ Color_Struct color_primary; // Color of primary item - /*0380*/ Color_Struct color_secondary; // Color of secondary item - } equipment_colors; - /*0348*/ Color_Struct colors[_MaterialCount]; // Array elements correspond to struct equipment_colors above - }; +/*0348*/ EQEmu::TintProfile equipment_tint; /*0384*/ uint8 lfg; // 0=off, 1=lfg on /*0385*/ @@ -446,7 +387,19 @@ struct MemorizeSpell_Struct { uint32 slot; // Spot in the spell book/memorized slot uint32 spell_id; // Spell id (200 or c8 is minor healing, etc) uint32 scribing; // 1 if memorizing a spell, set to 0 if scribing to book, 2 if un-memming -uint32 unknown12; +uint32 reduction; // lower reuse +}; + +/* +** Linked Spell Reuse Timer +** Length: 12 +** Comes before the OP_Memorize +** Live (maybe TDS steam) has an extra DWORD after timer_id +*/ +struct LinkedSpellReuseTimer_Struct { + uint32 timer_id; // Timer ID of the spell + uint32 end_time; // timestamp of when it will be ready + uint32 start_time; // timestamp of when it started }; /* @@ -479,10 +432,11 @@ struct DeleteSpell_Struct struct ManaChange_Struct { - uint32 new_mana; // New Mana AMount - uint32 stamina; - uint32 spell_id; - uint32 unknown12; +/*00*/ uint32 new_mana; // New Mana AMount +/*04*/ uint32 stamina; +/*08*/ uint32 spell_id; +/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting? +/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like }; struct SwapSpell_Struct @@ -548,30 +502,28 @@ struct SpawnAppearance_Struct // this is used inside profile struct SpellBuff_Struct { -/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise -/*001*/ uint8 level; +/*000*/ uint8 effect_type; // 0 = no buff, 2 = buff, 4 = inverse affects of buff +/*001*/ uint8 level; /*002*/ uint8 bard_modifier; -/*003*/ uint8 effect; //not real +/*003*/ uint8 unknown003; // MQ2 used to call this "damage shield" -- don't see client referencing it, so maybe server side DS type tracking? -- OSX client calls this "activated" /*004*/ uint32 spellid; -/*008*/ int32 duration; -/*012*/ uint32 counters; -/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages -/*020*/ +/*008*/ int32 duration; +/*012*/ uint32 counters; // single book keeping value (counters, rune/vie) +/*016*/ uint32 player_id; // caster ID, pretty sure just zone ID +// extra stuff for newer packets +/*020*/ uint32 num_hits; +/*024*/ float y; // referenced by SPA 441 +/*028*/ float x; // unsure if all buffs get them +/*032*/ float z; // as valid data +/*036*/ }; -struct SpellBuffFade_Struct { +struct SpellBuffPacket_Struct { /*000*/ uint32 entityid; -/*004*/ uint8 slot; -/*005*/ uint8 level; -/*006*/ uint8 effect; -/*007*/ uint8 unknown7; -/*008*/ uint32 spellid; -/*012*/ int32 duration; -/*016*/ uint32 num_hits; -/*020*/ uint32 unknown020; //prolly global player ID -/*024*/ uint32 slotid; -/*028*/ uint32 bufffade; -/*032*/ +/*004*/ SpellBuff_Struct buff; +/*040*/ uint32 slotid; +/*044*/ uint32 bufffade; +/*048*/ }; // Underfoot & later struct. @@ -584,8 +536,8 @@ struct BuffRemoveRequest_Struct struct PetBuff_Struct { /*000*/ uint32 petid; -/*004*/ uint32 spellid[BUFF_COUNT+5]; -/*124*/ int32 ticsremaining[BUFF_COUNT+5]; +/*004*/ uint32 spellid[PET_BUFF_COUNT]; +/*124*/ int32 ticsremaining[PET_BUFF_COUNT]; /*244*/ uint32 buffcount; }; @@ -777,7 +729,7 @@ struct BandolierItem_Struct struct Bandolier_Struct { char Name[32]; - BandolierItem_Struct Items[EmuConstants::BANDOLIER_ITEM_COUNT]; + BandolierItem_Struct Items[EQEmu::legacy::BANDOLIER_ITEM_COUNT]; }; //len = 72 @@ -791,7 +743,7 @@ struct PotionBeltItem_Struct //len = 288 struct PotionBelt_Struct { - PotionBeltItem_Struct Items[EmuConstants::POTION_BELT_ITEM_COUNT]; + PotionBeltItem_Struct Items[EQEmu::legacy::POTION_BELT_ITEM_COUNT]; }; struct MovePotionToBelt_Struct @@ -882,7 +834,7 @@ struct SuspendedMinion_Struct /*002*/ uint32 HP; /*006*/ uint32 Mana; /*010*/ SpellBuff_Struct Buffs[BUFF_COUNT]; - /*510*/ uint32 Items[_MaterialCount]; + /*510*/ EQEmu::TextureMaterialProfile Items; /*546*/ char Name[64]; /*610*/ }; @@ -896,7 +848,7 @@ struct SuspendedMinion_Struct */ static const uint32 MAX_PP_LANGUAGE = 28; static const uint32 MAX_PP_SPELLBOOK = 480; // Set for all functions -static const uint32 MAX_PP_MEMSPELL = 9; // Set to latest client so functions can work right +static const uint32 MAX_PP_MEMSPELL = static_cast(EQEmu::CastingSlot::MaxGems); // Set to latest client so functions can work right -- 12 static const uint32 MAX_PP_REF_SPELLBOOK = 480; // Set for Player Profile size retain static const uint32 MAX_PP_REF_MEMSPELL = 9; // Set for Player Profile size retain @@ -977,7 +929,7 @@ struct PlayerProfile_Struct /*0245*/ uint8 guildbanker; /*0246*/ uint8 unknown0246[6]; // /*0252*/ uint32 intoxication; -/*0256*/ uint32 spellSlotRefresh[MAX_PP_REF_MEMSPELL]; //in ms +/*0256*/ uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; //in ms /*0292*/ uint32 abilitySlotRefresh; /*0296*/ uint8 haircolor; // Player hair color /*0297*/ uint8 beardcolor; // Player beard color @@ -990,9 +942,9 @@ struct PlayerProfile_Struct /*0304*/ uint8 ability_time_minutes; /*0305*/ uint8 ability_time_hours; //place holder /*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag? -/*0312*/ uint32 item_material[_MaterialCount]; // Item texture/material of worn/held items +/*0312*/ EQEmu::TextureMaterialProfile item_material; // Item texture/material of worn/held items /*0348*/ uint8 unknown0348[44]; -/*0392*/ Color_Struct item_tint[_MaterialCount]; +/*0392*/ EQEmu::TintProfile item_tint; /*0428*/ AA_Array aa_array[MAX_PP_AA_ARRAY]; /*2348*/ float unknown2384; //seen ~128, ~47 /*2352*/ char servername[32]; // length probably not right @@ -1018,7 +970,7 @@ struct PlayerProfile_Struct /*2580*/ uint8 unknown2616[4]; /*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK]; /*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff -/*4632*/ uint32 mem_spells[MAX_PP_REF_MEMSPELL]; +/*4632*/ uint32 mem_spells[MAX_PP_MEMSPELL]; /*4668*/ uint8 unknown4704[32]; // /*4700*/ float y; // Player y position /*4704*/ float x; // Player x position @@ -1093,7 +1045,7 @@ struct PlayerProfile_Struct /*7212*/ uint32 tribute_points; /*7216*/ uint32 unknown7252; /*7220*/ uint32 tribute_active; //1=active -/*7224*/ Tribute_Struct tributes[EmuConstants::TRIBUTE_SIZE]; +/*7224*/ Tribute_Struct tributes[EQEmu::legacy::TRIBUTE_SIZE]; /*7264*/ Disciplines_Struct disciplines; /*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use) /*7744*/ char unknown7780[160]; @@ -1120,7 +1072,7 @@ struct PlayerProfile_Struct /*12800*/ uint32 expAA; /*12804*/ uint32 aapoints; //avaliable, unspent /*12808*/ uint8 unknown12844[36]; -/*12844*/ Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_SIZE]; +/*12844*/ Bandolier_Struct bandoliers[EQEmu::legacy::BANDOLIERS_SIZE]; /*14124*/ uint8 unknown14160[4506]; /*18630*/ SuspendedMinion_Struct SuspendedMinion; // No longer in use /*19240*/ uint32 timeentitledonaccount; @@ -1227,7 +1179,7 @@ struct WearChange_Struct{ /*010*/ uint32 elite_material; // 1 for Drakkin Elite Material /*014*/ uint32 hero_forge_model; // New to VoA /*018*/ uint32 unknown18; // New to RoF -/*022*/ Color_Struct color; +/*022*/ EQEmu::textures::Tint_Struct color; /*026*/ uint8 wear_slot_id; /*027*/ }; @@ -1518,17 +1470,38 @@ struct ExpUpdate_Struct enum ItemPacketType { ItemPacketViewLink = 0x00, + ItemPacketMerchant = 0x64, ItemPacketTradeView = 0x65, ItemPacketLoot = 0x66, ItemPacketTrade = 0x67, ItemPacketCharInventory = 0x69, - ItemPacketSummonItem = 0x6A, - ItemPacketTributeItem = 0x6C, - ItemPacketMerchant = 0x64, + ItemPacketLimbo = 0x6A, ItemPacketWorldContainer = 0x6B, - ItemPacketCharmUpdate = 0x6E, + ItemPacketTributeItem = 0x6C, + ItemPacketGuildTribute = 0x6D, + ItemPacketCharmUpdate = 0x6E, // noted as incorrect ItemPacketInvalid = 0xFF }; + +//enum ItemPacketType +//{ +// ItemPacketMerchant = /*100*/ 0x64, // Titanium+ +// ItemPacketTradeView = /*101*/ 0x65, +// ItemPacketLoot = /*102*/ 0x66, +// ItemPacketTrade = /*103*/ 0x67, +// ItemPacketCharInventory = /*105*/ 0x69, // 105 looks like raw item packet (no appearance update) thru shared bank..110, possibly possessions with appearance update +// ItemPacketLimbo = /*106*/ 0x6A, +// ItemPacketWorldContainer = /*107*/ 0x6B, +// ItemPacketTributeItem = /*108*/ 0x6C, +// ItemPacketGuildTribute = /*109*/ 0x6D, // missing from EQEmu +// ItemPacket10 = /*110*/ 0x6E, +// ItemPacket11 = /*111*/ 0x6F, // UF+ (equipment slots only) (RoF+ checks '(WORD*)slot + 4 != -1' [(WORD*)]slot + 2 would be bag index - if used) (guess) (appearance (over-level) items?) +// ItemPacket12 = /*112*/ 0x70, // RoF+ (causes stat update) (could be TrophyTribute and GuildTrophyTribute together - two case methodology - is it checking for GuildID?) +// ItemPacketMerchantRecovery = /*113*/ 0x71, +// ItemPacket14 = /*115*/ 0x73, (real estate/moving crate?) +// ItemPacket__ = /*xxx*/ 0xXX // switch 'default' - all clients +//}; + struct ItemPacket_Struct { /*00*/ ItemPacketType PacketType; @@ -1670,7 +1643,7 @@ struct LootingItem_Struct { /*002*/ uint32 looter; /*004*/ uint16 slot_id; /*006*/ uint8 unknown3[2]; -/*008*/ uint32 auto_loot; +/*008*/ int32 auto_loot; }; struct GuildManageStatus_Struct{ @@ -1961,8 +1934,7 @@ struct Merchant_Sell_Struct { /*004*/ uint32 playerid; // Player's entity id /*008*/ uint32 itemslot; uint32 unknown12; -/*016*/ uint8 quantity; // Already sold -/*017*/ uint8 Unknown016[3]; +/*016*/ uint32 quantity; /*020*/ uint32 price; }; struct Merchant_Purchase_Struct { @@ -2099,7 +2071,7 @@ struct AdventureLeaderboard_Struct /*struct Item_Shop_Struct { uint16 merchantid; uint8 itemtype; - Item_Struct item; + EQEmu::ItemData item; uint8 iss_unknown001[6]; };*/ @@ -2125,7 +2097,7 @@ struct Illusion_Struct { //size: 256 - SoF /*092*/ uint32 drakkin_heritage; // /*096*/ uint32 drakkin_tattoo; // /*100*/ uint32 drakkin_details; // -/*104*/ uint32 armor_tint[_MaterialCount]; // +/*104*/ EQEmu::TintProfile armor_tint; // /*140*/ uint8 eyecolor1; // Field Not Identified in any Illusion Struct /*141*/ uint8 eyecolor2; // Field Not Identified in any Illusion Struct /*142*/ uint8 unknown138[114]; // @@ -2271,6 +2243,7 @@ struct GroupFollow_Struct { // SoF Follow Struct /*0132*/ }; +// this is generic struct struct GroupLeaderChange_Struct { /*000*/ char Unknown000[64]; @@ -2523,6 +2496,7 @@ struct BookRequest_Struct { uint8 window; // where to display the text (0xFF means new window) uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others. uint32 invslot; // Only used in Sof and later clients; + int16 subslot; // The subslot inside of a bag if it is inside one. char txtfile[20]; }; @@ -2536,23 +2510,25 @@ struct BookRequest_Struct { */ struct Object_Struct { /*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list -/*08*/ uint16 size; // +/*08*/ float size; // /*10*/ uint16 solidtype; // /*12*/ uint32 drop_id; // Unique object id for zone /*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in /*18*/ uint16 zone_instance; // /*20*/ uint32 unknown020; // /*24*/ uint32 unknown024; // -/*28*/ float heading; // heading -/*32*/ float z; // z coord -/*36*/ float x; // x coord -/*40*/ float y; // y coord -/*44*/ char object_name[32]; // Name of object, usually something like IT63_ACTORDEF -/*76*/ uint32 unknown076; // -/*80*/ uint32 object_type; // Type of object, not directly translated to OP_OpenObject -/*84*/ uint32 unknown084; //set to 0xFF -/*88*/ uint32 spawn_id; // Spawn Id of client interacting with object -/*92*/ +/*28*/ float tilt_x; +/*32*/ float tilt_y; +/*36*/ float heading; // heading +/*40*/ float z; // z coord +/*44*/ float x; // x coord +/*76*/ float y; // y coord +/*80*/ char object_name[32]; // Name of object, usually something like IT63_ACTORDEF +/*84*/ uint32 unknown076; // +/*88*/ uint32 object_type; // Type of object, not directly translated to OP_OpenObject +/*92*/ uint32 unknown084; //set to 0xFF + uint32 spawn_id; // Spawn Id of client interacting with object + }; // 01 = generic drop, 02 = armor, 19 = weapon //[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject @@ -3395,27 +3371,6 @@ struct PetitionBug_Struct{ char text[1028]; }; -struct DyeStruct -{ - union - { - struct - { - struct Color_Struct head; - struct Color_Struct chest; - struct Color_Struct arms; - struct Color_Struct wrists; - struct Color_Struct hands; - struct Color_Struct legs; - struct Color_Struct feet; - struct Color_Struct primary; // you can't actually dye this - struct Color_Struct secondary; // or this - } - dyes; - struct Color_Struct dye[_MaterialCount]; - }; -}; - struct ApproveZone_Struct { char name[64]; uint32 zoneid; @@ -3473,8 +3428,8 @@ struct SelectTributeReply_Struct { struct TributeInfo_Struct { uint32 active; //0 == inactive, 1 == active - uint32 tributes[EmuConstants::TRIBUTE_SIZE]; //-1 == NONE - uint32 tiers[EmuConstants::TRIBUTE_SIZE]; //all 00's + uint32 tributes[EQEmu::legacy::TRIBUTE_SIZE]; //-1 == NONE + uint32 tiers[EQEmu::legacy::TRIBUTE_SIZE]; //all 00's uint32 tribute_master_id; }; @@ -3564,6 +3519,20 @@ struct RecipeAutoCombine_Struct { // f5 ff ff ff in 'you dont have all the stuff' reply }; +// this is the "value#a" data +enum EParticlePoint { + eDefault, + eChest, + eHead, + eLeftHand, + eRigthHand, + eLeftFoot, + eRightFood, + eLeftEye, + eRightEye, + eMouth +}; + struct LevelAppearance_Struct { //Sends a little graphic on level up uint32 spawn_id; uint32 parm1; @@ -4796,6 +4765,7 @@ struct BuffIcon_Struct uint8 all_buffs; uint16 count; uint8 type; // 0 = self buff window, 1 = self target window, 4 = group, 5 = PC, 7 = NPC + int32 tic_timer; BuffIconEntry_Struct entries[0]; }; @@ -5342,21 +5312,18 @@ struct ClientMarqueeMessage_Struct { typedef std::list ItemList; -struct TextLinkBody_Struct { - // Current server mask: EQClientRoF2 - uint8 unknown_1; /* %1X */ - uint32 item_id; /* %05X */ - uint32 augment_1; /* %05X */ - uint32 augment_2; /* %05X */ - uint32 augment_3; /* %05X */ - uint32 augment_4; /* %05X */ - uint32 augment_5; /* %05X */ - uint32 augment_6; /* %05X */ - uint8 is_evolving; /* %1X */ - uint32 evolve_group; /* %05X */ - uint8 evolve_level; /* %02X */ - uint32 ornament_icon; /* %05X */ - int hash; /* %08X */ + +struct fling_struct { +/* 00 */ uint32 collision; // 0 collision is off, anything else it's on +/* 04 */ int32 travel_time; // ms -- UF we need to calc this, RoF+ -1 auto calcs +/* 08 */ uint8 unk3; // bool, set to 1 has something to do with z-axis or something weird things happen if the new Z is above or equal to yours +/* 09 */ uint8 disable_fall_damage; // 1 you take no fall damage, 0 you take fall damage +/* 10 */ uint8 padding[2]; +/* 12 */ float speed_z; +/* 16 */ float new_y; +/* 20 */ float new_x; +/* 24 */ float new_z; +/* 28 */ }; // Restore structure packing to default diff --git a/common/eq_stream.cpp b/common/eq_stream.cpp index 3438f533c..5ae6c15f1 100644 --- a/common/eq_stream.cpp +++ b/common/eq_stream.cpp @@ -75,7 +75,7 @@ void EQStream::init(bool resetSession) { sent_packet_count = 0; received_packet_count = 0; SequencedBase = 0; - NextSequencedSend = 0; + AverageDelta = 500; if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { retransmittimer = Timer::GetCurrentTime(); @@ -84,18 +84,14 @@ void EQStream::init(bool resetSession) { OpMgr = nullptr; if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - Log.Out(Logs::Detail, Logs::Netcode, _L "init Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); - } - - if(NextSequencedSend > SequencedQueue.size()) { - Log.Out(Logs::Detail, Logs::Netcode, _L "init Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + Log(Logs::Detail, Logs::Netcode, _L "init Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); } } EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p) { EQRawApplicationPacket *ap=nullptr; - Log.Out(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, p->size); + Log(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, p->size); // _raw(NET__APP_CREATE_HEX, 0xFFFF, p); ap = p->MakeAppPacket(); return ap; @@ -104,7 +100,7 @@ EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p) EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf, uint32 len) { EQRawApplicationPacket *ap=nullptr; - Log.Out(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, len); + Log(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, len); ap = new EQRawApplicationPacket(buf, len); return ap; } @@ -134,7 +130,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) } if (!Session && p->opcode!=OP_SessionRequest && p->opcode!=OP_SessionResponse) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Session not initialized, packet ignored" __L); + Log(Logs::Detail, Logs::Netcode, _L "Session not initialized, packet ignored" __L); // _raw(NET__DEBUG, 0xFFFF, p); return; } @@ -145,7 +141,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) while(processed < p->size) { subpacket_length=*(p->pBuffer+processed); EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+processed+1,subpacket_length); - Log.Out(Logs::Detail, Logs::Netcode, _L "Extracting combined packet of length %d" __L, subpacket_length); + Log(Logs::Detail, Logs::Netcode, _L "Extracting combined packet of length %d" __L, subpacket_length); // _raw(NET__NET_CREATE_HEX, 0xFFFF, subp); subp->copyInfo(p); ProcessPacket(subp); @@ -160,12 +156,12 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) while(processedsize) { EQRawApplicationPacket *ap=nullptr; if ((subpacket_length=(unsigned char)*(p->pBuffer+processed))!=0xff) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length); + Log(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length); ap=MakeApplicationPacket(p->pBuffer+processed+1,subpacket_length); processed+=subpacket_length+1; } else { subpacket_length=ntohs(*(uint16 *)(p->pBuffer+processed+1)); - Log.Out(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length); + Log(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length); ap=MakeApplicationPacket(p->pBuffer+processed+3,subpacket_length); processed+=subpacket_length+3; } @@ -180,29 +176,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) case OP_Packet: { if(!p->pBuffer || (p->Size() < 4)) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_Packet that was of malformed size" __L); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_Packet that was of malformed size" __L); break; } uint16 seq=ntohs(*(uint16 *)(p->pBuffer)); SeqOrder check=CompareSequence(NextInSeq,seq); if (check == SeqFuture) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Future OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); + Log(Logs::Detail, Logs::Netcode, _L "Future OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); // _raw(NET__DEBUG, seq, p); PacketQueue[seq]=p->Copy(); - Log.Out(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); + Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); //SendOutOfOrderAck(seq); } else if (check == SeqPast) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); + Log(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); // _raw(NET__DEBUG, seq, p); SendOutOfOrderAck(seq); //we already got this packet but it was out of order } else { // In case we did queue one before as well. EQProtocolPacket *qp=RemoveQueue(seq); if (qp) { - Log.Out(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Packet: Removing older queued packet with sequence %d", seq); + Log(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Packet: Removing older queued packet with sequence %d", seq); delete qp; } @@ -211,7 +207,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) // Check for an embedded OP_AppCombinded (protocol level 0x19) if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) { EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+2,p->size-2); - Log.Out(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined packet of length %d" __L, seq, subp->size); + Log(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined packet of length %d" __L, seq, subp->size); // _raw(NET__NET_CREATE_HEX, seq, subp); subp->copyInfo(p); ProcessPacket(subp); @@ -230,29 +226,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) case OP_Fragment: { if(!p->pBuffer || (p->Size() < 4)) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_Fragment that was of malformed size" __L); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_Fragment that was of malformed size" __L); break; } uint16 seq=ntohs(*(uint16 *)(p->pBuffer)); SeqOrder check=CompareSequence(NextInSeq,seq); if (check == SeqFuture) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Future OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); + Log(Logs::Detail, Logs::Netcode, _L "Future OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); // _raw(NET__DEBUG, seq, p); PacketQueue[seq]=p->Copy(); - Log.Out(Logs::Detail, Logs::Netcode, _L "OP_Fragment Queue size=%d" __L, PacketQueue.size()); + Log(Logs::Detail, Logs::Netcode, _L "OP_Fragment Queue size=%d" __L, PacketQueue.size()); //SendOutOfOrderAck(seq); } else if (check == SeqPast) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); + Log(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); // _raw(NET__DEBUG, seq, p); SendOutOfOrderAck(seq); } else { // In case we did queue one before as well. EQProtocolPacket *qp=RemoveQueue(seq); if (qp) { - Log.Out(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Fragment: Removing older queued packet with sequence %d", seq); + Log(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Fragment: Removing older queued packet with sequence %d", seq); delete qp; } SetNextAckToSend(seq); @@ -260,18 +256,18 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) if (oversize_buffer) { memcpy(oversize_buffer+oversize_offset,p->pBuffer+2,p->size-2); oversize_offset+=p->size-2; - Log.Out(Logs::Detail, Logs::Netcode, _L "Fragment of oversized of length %d, seq %d: now at %d/%d" __L, p->size-2, seq, oversize_offset, oversize_length); + Log(Logs::Detail, Logs::Netcode, _L "Fragment of oversized of length %d, seq %d: now at %d/%d" __L, p->size-2, seq, oversize_offset, oversize_length); if (oversize_offset==oversize_length) { if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) { EQProtocolPacket *subp=MakeProtocolPacket(oversize_buffer,oversize_offset); - Log.Out(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined oversize packet of length %d" __L, seq, subp->size); + Log(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined oversize packet of length %d" __L, seq, subp->size); //// _raw(NET__NET_CREATE_HEX, subp); subp->copyInfo(p); ProcessPacket(subp); delete subp; } else { EQRawApplicationPacket *ap=MakeApplicationPacket(oversize_buffer,oversize_offset); - Log.Out(Logs::Detail, Logs::Netcode, _L "seq %d, completed combined oversize packet of length %d" __L, seq, ap->size); + Log(Logs::Detail, Logs::Netcode, _L "seq %d, completed combined oversize packet of length %d" __L, seq, ap->size); if (ap) { ap->copyInfo(p); InboundQueuePush(ap); @@ -286,43 +282,38 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) oversize_buffer=new unsigned char[oversize_length]; memcpy(oversize_buffer,p->pBuffer+6,p->size-6); oversize_offset=p->size-6; - Log.Out(Logs::Detail, Logs::Netcode, _L "First fragment of oversized of seq %d: now at %d/%d" __L, seq, oversize_offset, oversize_length); + Log(Logs::Detail, Logs::Netcode, _L "First fragment of oversized of seq %d: now at %d/%d" __L, seq, oversize_offset, oversize_length); } } } break; case OP_KeepAlive: { -#ifndef COLLECTOR NonSequencedPush(new EQProtocolPacket(p->opcode,p->pBuffer,p->size)); - Log.Out(Logs::Detail, Logs::Netcode, _L "Received and queued reply to keep alive" __L); -#endif + Log(Logs::Detail, Logs::Netcode, _L "Received and queued reply to keep alive" __L); } break; case OP_Ack: { if(!p->pBuffer || (p->Size() < 4)) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_Ack that was of malformed size" __L); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_Ack that was of malformed size" __L); break; } -#ifndef COLLECTOR uint16 seq=ntohs(*(uint16 *)(p->pBuffer)); AckPackets(seq); if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { retransmittimer = Timer::GetCurrentTime(); } -#endif } break; case OP_SessionRequest: { if(p->Size() < sizeof(SessionRequest)) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest that was of malformed size" __L); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest that was of malformed size" __L); break; } -#ifndef COLLECTOR if (GetState()==ESTABLISHED) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest in ESTABLISHED state (%d) streamactive (%i) attempt (%i)" __L, GetState(),streamactive,sessionAttempts); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest in ESTABLISHED state (%d) streamactive (%i) attempt (%i)" __L, GetState(),streamactive,sessionAttempts); // client seems to try a max of 30 times (initial+3 retries) then gives up, giving it a few more attempts just in case // streamactive means we identified the opcode for the stream, we cannot re-establish this connection @@ -333,7 +324,6 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) break; } } -#endif sessionAttempts++; // we set established below, so statistics will not be reset for session attempts/stream active. init(GetState()!=ESTABLISHED); @@ -341,18 +331,16 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) SessionRequest *Request=(SessionRequest *)p->pBuffer; Session=ntohl(Request->Session); SetMaxLen(ntohl(Request->MaxLength)); - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest: session %lu, maxlen %d" __L, (unsigned long)Session, MaxLen); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest: session %lu, maxlen %d" __L, (unsigned long)Session, MaxLen); SetState(ESTABLISHED); -#ifndef COLLECTOR Key=0x11223344; SendSessionResponse(); -#endif } break; case OP_SessionResponse: { if(p->Size() < sizeof(SessionResponse)) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse that was of malformed size" __L); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse that was of malformed size" __L); break; } @@ -368,7 +356,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) compressed=(Response->Format&FLAG_COMPRESSED); encoded=(Response->Format&FLAG_ENCODED); - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse: session %lu, maxlen %d, key %lu, compressed? %s, encoded? %s" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no"); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse: session %lu, maxlen %d, key %lu, compressed? %s, encoded? %s" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no"); // Kinda kludgy, but trie for now if (StreamType==UnknownStream) { @@ -391,17 +379,17 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) EQStreamState state = GetState(); if(state == ESTABLISHED) { //client initiated disconnect? - Log.Out(Logs::Detail, Logs::Netcode, _L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect." __L); + Log(Logs::Detail, Logs::Netcode, _L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect." __L); _SendDisconnect(); SetState(CLOSED); } else if(state == CLOSING) { //we were waiting for this anyways, ignore pending messages, send the reply and be closed. - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though." __L); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though." __L); _SendDisconnect(); SetState(CLOSED); } else { //we are expecting this (or have already gotten it, but dont care either way) - Log.Out(Logs::Detail, Logs::Netcode, _L "Received expected OP_SessionDisconnect. Moving to closed state." __L); + Log(Logs::Detail, Logs::Netcode, _L "Received expected OP_SessionDisconnect. Moving to closed state." __L); SetState(CLOSED); } } @@ -409,71 +397,59 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) case OP_OutOfOrderAck: { if(!p->pBuffer || (p->Size() < 4)) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck that was of malformed size" __L); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck that was of malformed size" __L); break; } -#ifndef COLLECTOR uint16 seq=ntohs(*(uint16 *)(p->pBuffer)); MOutboundQueue.lock(); if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + Log(Logs::Detail, Logs::Netcode, _L "Pre-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); } - if(NextSequencedSend > SequencedQueue.size()) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-OOA Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); - } //if the packet they got out of order is between our last acked packet and the last sent packet, then its valid. if (CompareSequence(SequencedBase,seq) != SeqPast && CompareSequence(NextOutSeq,seq) == SeqPast) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for sequence %d, starting retransmit at the start of our unacked buffer (seq %d, was %d)." __L, - seq, SequencedBase, SequencedBase+NextSequencedSend); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for sequence %d, starting retransmit at the start of our unacked buffer (seq %d, was %d)." __L, + seq, SequencedBase, SequencedBase+SequencedQueue.size()); - bool retransmit_acked_packets = false; - if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { - retransmit_acked_packets = RETRANSMIT_ACKED_PACKETS; - } - - if(!retransmit_acked_packets) { - uint16 sqsize = SequencedQueue.size(); - uint16 index = seq - SequencedBase; - Log.Out(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck marking packet acked in queue (queue index = %d, queue size = %d)." __L, index, sqsize); - if (index < sqsize) { - std::deque::iterator sitr; - sitr = SequencedQueue.begin(); - sitr += index; - (*sitr)->acked = true; + uint16 sqsize = SequencedQueue.size(); + uint16 index = seq - SequencedBase; + Log(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck marking packet acked in queue (queue index = %d, queue size = %d)." __L, index, sqsize); + if (index < sqsize) { + SequencedQueue[index]->acked = true; + // flag packets for a resend + uint16 count = 0; + uint32 timeout = AverageDelta * 2 + 100; + for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end() && count < index; ++sitr, ++count) { + if (!(*sitr)->acked && (*sitr)->sent_time > 0 && (((*sitr)->sent_time + timeout) < Timer::GetCurrentTime())) { + (*sitr)->sent_time = 0; + Log(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck Flagging packet %d for retransmission" __L, SequencedBase + count); + } } } if(RETRANSMIT_TIMEOUT_MULT) { retransmittimer = Timer::GetCurrentTime(); } - - NextSequencedSend = 0; } else { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for out-of-window %d. Window (%d->%d)." __L, seq, SequencedBase, NextOutSeq); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for out-of-window %d. Window (%d->%d)." __L, seq, SequencedBase, NextOutSeq); } if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Post-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + Log(Logs::Detail, Logs::Netcode, _L "Post-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); } - if(NextSequencedSend > SequencedQueue.size()) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Post-OOA Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); - } MOutboundQueue.unlock(); -#endif } break; case OP_SessionStatRequest: { if(p->Size() < sizeof(ClientSessionStats)) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatRequest that was of malformed size" __L); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatRequest that was of malformed size" __L); break; } -#ifndef COLLECTOR ClientSessionStats *ClientStats=(ClientSessionStats *)p->pBuffer; - Log.Out(Logs::Detail, Logs::Netcode, _L "Received Stats: %lu packets received, %lu packets sent, Deltas: local %lu, (%lu <- %lu -> %lu) remote %lu" __L, + Log(Logs::Detail, Logs::Netcode, _L "Received Stats: %lu packets received, %lu packets sent, Deltas: local %lu, (%lu <- %lu -> %lu) remote %lu" __L, (unsigned long)ntohl(ClientStats->packets_received), (unsigned long)ntohl(ClientStats->packets_sent), (unsigned long)ntohl(ClientStats->last_local_delta), (unsigned long)ntohl(ClientStats->low_delta), (unsigned long)ntohl(ClientStats->average_delta), (unsigned long)ntohl(ClientStats->high_delta), (unsigned long)ntohl(ClientStats->last_remote_delta)); @@ -489,9 +465,10 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) } else { retransmittimeout = ntohl(ClientStats->average_delta) * 2 * RETRANSMIT_TIMEOUT_MULT; } + retransmittimeout += 300; if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX) retransmittimeout = RETRANSMIT_TIMEOUT_MAX; - Log.Out(Logs::Detail, Logs::Netcode, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout); + Log(Logs::Detail, Logs::Netcode, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout); } } @@ -505,15 +482,14 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) ServerStats->packets_received = htonll(GetPacketsReceived()); NonSequencedPush(new EQProtocolPacket(OP_SessionStatResponse, p->pBuffer, p->size)); -#endif } break; case OP_SessionStatResponse: { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatResponse. Ignoring." __L); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatResponse. Ignoring." __L); } break; case OP_OutOfSession: { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfSession. Ignoring." __L); + Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfSession. Ignoring." __L); } break; default: @@ -544,7 +520,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req) return; if(OpMgr == nullptr || *OpMgr == nullptr) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Packet enqueued into a stream with no opcode manager, dropping." __L); + Log(Logs::Detail, Logs::Netcode, _L "Packet enqueued into a stream with no opcode manager, dropping." __L); delete pack; return; } @@ -569,32 +545,32 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p) uint32 chunksize, used; uint32 length; - if (Log.log_settings[Logs::Server_Client_Packet].is_category_enabled == 1){ + if (LogSys.log_settings[Logs::Server_Client_Packet].is_category_enabled == 1){ if (p->GetOpcode() != OP_SpecialMesg){ - Log.Out(Logs::General, Logs::Server_Client_Packet, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size()); + Log(Logs::General, Logs::Server_Client_Packet, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size()); } } - if (Log.log_settings[Logs::Server_Client_Packet_With_Dump].is_category_enabled == 1){ + if (LogSys.log_settings[Logs::Server_Client_Packet_With_Dump].is_category_enabled == 1){ if (p->GetOpcode() != OP_SpecialMesg){ - Log.Out(Logs::General, Logs::Server_Client_Packet_With_Dump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str()); + Log(Logs::General, Logs::Server_Client_Packet_With_Dump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str()); } } // Convert the EQApplicationPacket to 1 or more EQProtocolPackets if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2) - Log.Out(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->Size()); + Log(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->Size()); - unsigned char *tmpbuff=new unsigned char[p->size+3]; + auto tmpbuff = new unsigned char[p->size + 3]; length=p->serialize(opcode, tmpbuff); if (length != p->Size()) - Log.Out(Logs::Detail, Logs::Netcode, _L "Packet adjustment, len %d to %d" __L, p->Size(), length); + Log(Logs::Detail, Logs::Netcode, _L "Packet adjustment, len %d to %d" __L, p->Size(), length); - EQProtocolPacket *out=new EQProtocolPacket(OP_Fragment,nullptr,MaxLen-4); + auto out = new EQProtocolPacket(OP_Fragment, nullptr, MaxLen - 4); *(uint32 *)(out->pBuffer+2)=htonl(length); used=MaxLen-10; memcpy(out->pBuffer+6,tmpbuff,used); - Log.Out(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Payload size %d in the packet" __L, used, length, p->size); + Log(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Payload size %d in the packet" __L, used, length, p->size); SequencedPush(out); @@ -605,16 +581,16 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p) out->size=chunksize+2; SequencedPush(out); used+=chunksize; - Log.Out(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, length); + Log(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, length); } delete p; delete[] tmpbuff; } else { - unsigned char *tmpbuff=new unsigned char[p->Size()+3]; + auto tmpbuff = new unsigned char[p->Size() + 3]; length=p->serialize(opcode, tmpbuff+2) + 2; - EQProtocolPacket *out=new EQProtocolPacket(OP_Packet,tmpbuff,length); + auto out = new EQProtocolPacket(OP_Packet, tmpbuff, length); delete[] tmpbuff; SequencedPush(out); @@ -624,55 +600,45 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p) void EQStream::SequencedPush(EQProtocolPacket *p) { -#ifdef COLLECTOR - delete p; -#else MOutboundQueue.lock(); -if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); -} -if(NextSequencedSend > SequencedQueue.size()) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); -} + if (uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { + Log(Logs::Detail, Logs::Netcode, _L "Pre-Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, + SequencedBase, SequencedQueue.size(), NextOutSeq); + } - Log.Out(Logs::Detail, Logs::Netcode, _L "Pushing sequenced packet %d of length %d. Base Seq is %d." __L, NextOutSeq, p->size, SequencedBase); - *(uint16 *)(p->pBuffer)=htons(NextOutSeq); + Log(Logs::Detail, Logs::Netcode, _L "Pushing sequenced packet %d of length %d. Base Seq is %d." __L, + NextOutSeq, p->size, SequencedBase); + *(uint16 *)(p->pBuffer) = htons(NextOutSeq); SequencedQueue.push_back(p); NextOutSeq++; -if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); -} -if(NextSequencedSend > SequencedQueue.size()) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); -} + if (uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { + Log(Logs::Detail, Logs::Netcode, _L "Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, + SequencedBase, SequencedQueue.size(), NextOutSeq); + } + MOutboundQueue.unlock(); -#endif } void EQStream::NonSequencedPush(EQProtocolPacket *p) { -#ifdef COLLECTOR - delete p; -#else MOutboundQueue.lock(); - Log.Out(Logs::Detail, Logs::Netcode, _L "Pushing non-sequenced packet of length %d" __L, p->size); + Log(Logs::Detail, Logs::Netcode, _L "Pushing non-sequenced packet of length %d" __L, p->size); NonSequencedQueue.push(p); MOutboundQueue.unlock(); -#endif } void EQStream::SendAck(uint16 seq) { uint16 Seq=htons(seq); - Log.Out(Logs::Detail, Logs::Netcode, _L "Sending ack with sequence %d" __L, seq); + Log(Logs::Detail, Logs::Netcode, _L "Sending ack with sequence %d" __L, seq); SetLastAckSent(seq); NonSequencedPush(new EQProtocolPacket(OP_Ack,(unsigned char *)&Seq,sizeof(uint16))); } void EQStream::SendOutOfOrderAck(uint16 seq) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Sending out of order ack with sequence %d" __L, seq); + Log(Logs::Detail, Logs::Netcode, _L "Sending out of order ack with sequence %d" __L, seq); uint16 Seq=htons(seq); NonSequencedPush(new EQProtocolPacket(OP_OutOfOrderAck,(unsigned char *)&Seq,sizeof(uint16))); } @@ -703,21 +669,15 @@ void EQStream::Write(int eq_fd) // Place to hold the base packet t combine into EQProtocolPacket *p=nullptr; - if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { - // if we have a timeout defined and we have not received an ack recently enough, retransmit from beginning of queue - if (RETRANSMIT_TIMEOUT_MULT && !SequencedQueue.empty() && NextSequencedSend && - (GetState()==ESTABLISHED) && ((retransmittimer+retransmittimeout) < Timer::GetCurrentTime())) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout since last ack received, starting retransmit at the start of our unacked " - "buffer (seq %d, was %d)." __L, SequencedBase, SequencedBase+NextSequencedSend); - NextSequencedSend = 0; - retransmittimer = Timer::GetCurrentTime(); // don't want to endlessly retransmit the first packet - } - } - // Find the next sequenced packet to send from the "queue" sitr = SequencedQueue.begin(); - if (sitr!=SequencedQueue.end()) - sitr += NextSequencedSend; + + uint16 count = 0; + // get to start of packets + while (sitr != SequencedQueue.end() && (*sitr)->sent_time > 0) { + ++sitr; + ++count; + } // Loop until both are empty or MaxSends is reached while(!SeqEmpty || !NonSeqEmpty) { @@ -728,24 +688,24 @@ void EQStream::Write(int eq_fd) // If we don't have a packet to try to combine into, use this one as the base // And remove it form the queue p = NonSequencedQueue.front(); - Log.Out(Logs::Detail, Logs::Netcode, _L "Starting combined packet with non-seq packet of len %d" __L, p->size); + Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with non-seq packet of len %d" __L, p->size); NonSequencedQueue.pop(); } else if (!p->combine(NonSequencedQueue.front())) { - // Tryint to combine this packet with the base didn't work (too big maybe) + // Trying to combine this packet with the base didn't work (too big maybe) // So just send the base packet (we'll try this packet again later) - Log.Out(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next non-seq packet is len %d" __L, p->size, (NonSequencedQueue.front())->size); + Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next non-seq packet is len %d" __L, p->size, (NonSequencedQueue.front())->size); ReadyToSend.push(p); BytesWritten+=p->size; p=nullptr; if (BytesWritten > threshold) { // Sent enough this round, lets stop to be fair - Log.Out(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in nonseq (%d > %d)" __L, BytesWritten, threshold); + Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in nonseq (%d > %d)" __L, BytesWritten, threshold); break; } } else { // Combine worked, so just remove this packet and it's spot in the queue - Log.Out(Logs::Detail, Logs::Netcode, _L "Combined non-seq packet of len %d, yeilding %d combined." __L, (NonSequencedQueue.front())->size, p->size); + Log(Logs::Detail, Logs::Netcode, _L "Combined non-seq packet of len %d, yeilding %d combined." __L, (NonSequencedQueue.front())->size, p->size); delete NonSequencedQueue.front(); NonSequencedQueue.pop(); } @@ -754,87 +714,95 @@ void EQStream::Write(int eq_fd) NonSeqEmpty=true; } - if (sitr!=SequencedQueue.end()) { - if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Send Seq NSS=%d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, NextSequencedSend, SequencedBase, SequencedQueue.size(), NextOutSeq); - } + if (sitr != SequencedQueue.end()) { + uint16 seq_send = SequencedBase + count; //just for logging... - if(NextSequencedSend > SequencedQueue.size()) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Send Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); - } - uint16 seq_send = SequencedBase + NextSequencedSend; //just for logging... - if(SequencedQueue.empty()) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Tried to write a packet with an empty queue (%d is past next out %d)" __L, seq_send, NextOutSeq); + Log(Logs::Detail, Logs::Netcode, _L "Tried to write a packet with an empty queue (%d is past next out %d)" __L, seq_send, NextOutSeq); SeqEmpty=true; continue; } if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { - if (!RETRANSMIT_ACKED_PACKETS && (*sitr)->acked) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Not retransmitting seq packet %d because already marked as acked" __L, seq_send); - sitr++; - NextSequencedSend++; + if ((*sitr)->acked || (*sitr)->sent_time != 0) { + ++sitr; + ++count; + if (p) { + Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size); + ReadyToSend.push(p); + BytesWritten += p->size; + p = nullptr; + } + Log(Logs::Detail, Logs::Netcode, _L "Not retransmitting seq packet %d because already marked as acked" __L, seq_send); } else if (!p) { // If we don't have a packet to try to combine into, use this one as the base // Copy it first as it will still live until it is acked p=(*sitr)->Copy(); - Log.Out(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); + Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); + (*sitr)->sent_time = Timer::GetCurrentTime(); ++sitr; - NextSequencedSend++; + ++count; } else if (!p->combine(*sitr)) { // Trying to combine this packet with the base didn't work (too big maybe) // So just send the base packet (we'll try this packet again later) - Log.Out(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size); + Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send + 1, (*sitr)->size); ReadyToSend.push(p); BytesWritten+=p->size; p=nullptr; - - if (BytesWritten > threshold) { + if ((*sitr)->opcode != OP_Fragment && BytesWritten > threshold) { // Sent enough this round, lets stop to be fair - Log.Out(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); + Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); break; } } else { // Combine worked - Log.Out(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size); + Log(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size); + (*sitr)->sent_time = Timer::GetCurrentTime(); ++sitr; - NextSequencedSend++; + ++count; } } else { - if (!p) { + if ((*sitr)->sent_time != 0) { + ++sitr; + ++count; + if (p) { + Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size); + ReadyToSend.push(p); + BytesWritten += p->size; + p = nullptr; + } + } else if (!p) { // If we don't have a packet to try to combine into, use this one as the base // Copy it first as it will still live until it is acked p=(*sitr)->Copy(); - Log.Out(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); + (*sitr)->sent_time = Timer::GetCurrentTime(); + Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); ++sitr; - NextSequencedSend++; + ++count; } else if (!p->combine(*sitr)) { // Trying to combine this packet with the base didn't work (too big maybe) // So just send the base packet (we'll try this packet again later) - Log.Out(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size); + Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size); ReadyToSend.push(p); BytesWritten+=p->size; p=nullptr; if (BytesWritten > threshold) { // Sent enough this round, lets stop to be fair - Log.Out(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); + Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); break; } } else { // Combine worked - Log.Out(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size); + Log(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yielding %d combined." __L, seq_send, (*sitr)->size, p->size); + (*sitr)->sent_time = Timer::GetCurrentTime(); ++sitr; - NextSequencedSend++; + ++count; } } if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Post send Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); - } - if(NextSequencedSend > SequencedQueue.size()) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Post send Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + Log(Logs::Detail, Logs::Netcode, _L "Post send Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); } } else { // No more sequenced packets @@ -846,7 +814,7 @@ void EQStream::Write(int eq_fd) // We have a packet still, must have run out of both seq and non-seq, so send it if (p) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size); + Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size); ReadyToSend.push(p); BytesWritten+=p->size; } @@ -863,7 +831,7 @@ void EQStream::Write(int eq_fd) if(SeqEmpty && NonSeqEmpty) { //no more data to send if(CheckState(CLOSING)) { - Log.Out(Logs::Detail, Logs::Netcode, _L "All outgoing data flushed, closing stream." __L ); + Log(Logs::Detail, Logs::Netcode, _L "All outgoing data flushed, closing stream." __L ); //we are waiting for the queues to empty, now we can do our disconnect. //this packet will not actually go out until the next call to Write(). _SendDisconnect(); @@ -894,9 +862,11 @@ sockaddr_in address; length=p->serialize(buffer); if (p->opcode!=OP_SessionRequest && p->opcode!=OP_SessionResponse) { if (compressed) { + BytesWritten -= p->size; uint32 newlen=EQProtocolPacket::Compress(buffer,length, _tempBuffer, 2048); memcpy(buffer,_tempBuffer,newlen); length=newlen; + BytesWritten += newlen; } if (encoded) { EQProtocolPacket::ChatEncode(buffer,length,Key); @@ -912,7 +882,7 @@ sockaddr_in address; void EQStream::SendSessionResponse() { -EQProtocolPacket *out=new EQProtocolPacket(OP_SessionResponse,nullptr,sizeof(SessionResponse)); + auto out = new EQProtocolPacket(OP_SessionResponse, nullptr, sizeof(SessionResponse)); SessionResponse *Response=(SessionResponse *)out->pBuffer; Response->Session=htonl(Session); Response->MaxLength=htonl(MaxLen); @@ -926,7 +896,7 @@ EQProtocolPacket *out=new EQProtocolPacket(OP_SessionResponse,nullptr,sizeof(Ses out->size=sizeof(SessionResponse); - Log.Out(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionResponse: session %lu, maxlen=%d, key=0x%x, compressed? %s, encoded? %s" __L, + Log(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionResponse: session %lu, maxlen=%d, key=0x%x, compressed? %s, encoded? %s" __L, (unsigned long)Session, MaxLen, Key, compressed?"yes":"no", encoded?"yes":"no"); NonSequencedPush(out); @@ -934,13 +904,13 @@ EQProtocolPacket *out=new EQProtocolPacket(OP_SessionResponse,nullptr,sizeof(Ses void EQStream::SendSessionRequest() { -EQProtocolPacket *out=new EQProtocolPacket(OP_SessionRequest,nullptr,sizeof(SessionRequest)); + auto out = new EQProtocolPacket(OP_SessionRequest, nullptr, sizeof(SessionRequest)); SessionRequest *Request=(SessionRequest *)out->pBuffer; memset(Request,0,sizeof(SessionRequest)); Request->Session=htonl(time(nullptr)); Request->MaxLength=htonl(512); - Log.Out(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionRequest: session %lu, maxlen=%d" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength)); + Log(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionRequest: session %lu, maxlen=%d" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength)); NonSequencedPush(out); } @@ -950,11 +920,11 @@ void EQStream::_SendDisconnect() if(GetState() == CLOSED) return; - EQProtocolPacket *out=new EQProtocolPacket(OP_SessionDisconnect,nullptr,sizeof(uint32)); + auto out = new EQProtocolPacket(OP_SessionDisconnect, nullptr, sizeof(uint32)); *(uint32 *)out->pBuffer=htonl(Session); NonSequencedPush(out); - Log.Out(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionDisconnect: session %lu" __L, (unsigned long)Session); + Log(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionDisconnect: session %lu" __L, (unsigned long)Session); } void EQStream::InboundQueuePush(EQRawApplicationPacket *p) @@ -969,8 +939,8 @@ EQApplicationPacket *EQStream::PopPacket() EQRawApplicationPacket *p=nullptr; MInboundQueue.lock(); - if (InboundQueue.size()) { - std::vector::iterator itr=InboundQueue.begin(); + if (!InboundQueue.empty()) { + auto itr = InboundQueue.begin(); p=*itr; InboundQueue.erase(itr); } @@ -980,7 +950,7 @@ EQRawApplicationPacket *p=nullptr; if (OpMgr != nullptr && *OpMgr != nullptr) { EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode); if (emu_op == OP_Unknown) { - // Log.Out(Logs::General, Logs::Client_Server_Packet_Unhandled, "Unknown :: [%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->opcode, p->Size(), DumpPacketToString(p).c_str()); + // Log(Logs::General, Logs::Client_Server_Packet_Unhandled, "Unknown :: [%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->opcode, p->Size(), DumpPacketToString(p).c_str()); } p->SetOpcode(emu_op); } @@ -994,8 +964,8 @@ EQRawApplicationPacket *EQStream::PopRawPacket() EQRawApplicationPacket *p=nullptr; MInboundQueue.lock(); - if (InboundQueue.size()) { - std::vector::iterator itr=InboundQueue.begin(); + if (!InboundQueue.empty()) { + auto itr = InboundQueue.begin(); p=*itr; InboundQueue.erase(itr); } @@ -1006,7 +976,7 @@ EQRawApplicationPacket *p=nullptr; if(OpMgr != nullptr && *OpMgr != nullptr) { EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode); if(emu_op == OP_Unknown) { - Log.Out(Logs::General, Logs::Netcode, "Unable to convert EQ opcode 0x%.4x to an Application opcode.", p->opcode); + Log(Logs::General, Logs::Netcode, "Unable to convert EQ opcode 0x%.4x to an Application opcode.", p->opcode); } p->SetOpcode(emu_op); @@ -1021,8 +991,8 @@ EQRawApplicationPacket *EQStream::PeekPacket() EQRawApplicationPacket *p=nullptr; MInboundQueue.lock(); - if (InboundQueue.size()) { - std::vector::iterator itr=InboundQueue.begin(); + if (!InboundQueue.empty()) { + auto itr = InboundQueue.begin(); p=*itr; } MInboundQueue.unlock(); @@ -1034,7 +1004,7 @@ void EQStream::InboundQueueClear() { EQApplicationPacket *p=nullptr; - Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing inbound queue" __L); + Log(Logs::Detail, Logs::Netcode, _L "Clearing inbound queue" __L); MInboundQueue.lock(); if (!InboundQueue.empty()) { @@ -1077,7 +1047,7 @@ void EQStream::OutboundQueueClear() { EQProtocolPacket *p=nullptr; - Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing outbound queue" __L); + Log(Logs::Detail, Logs::Netcode, _L "Clearing outbound queue" __L); MOutboundQueue.lock(); while(!NonSequencedQueue.empty()) { @@ -1099,7 +1069,7 @@ void EQStream::PacketQueueClear() { EQProtocolPacket *p=nullptr; - Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing future packet queue" __L); + Log(Logs::Detail, Logs::Netcode, _L "Clearing future packet queue" __L); if(!PacketQueue.empty()) { std::map::iterator itr; @@ -1131,7 +1101,7 @@ void EQStream::Process(const unsigned char *buffer, const uint32 length) delete p; ProcessQueue(); } else { - Log.Out(Logs::Detail, Logs::Netcode, _L "Incoming packet failed checksum" __L); + Log(Logs::Detail, Logs::Netcode, _L "Incoming packet failed checksum" __L); } } @@ -1158,50 +1128,36 @@ void EQStream::AckPackets(uint16 seq) std::deque::iterator itr, tmp; MOutboundQueue.lock(); -//do a bit of sanity checking. -if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Ack Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); -} -if(NextSequencedSend > SequencedQueue.size()) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); -} SeqOrder ord = CompareSequence(SequencedBase, seq); if(ord == SeqInOrder) { //they are not acking anything new... - Log.Out(Logs::Detail, Logs::Netcode, _L "Received an ack with no window advancement (seq %d)." __L, seq); + Log(Logs::Detail, Logs::Netcode, _L "Received an ack with no window advancement (seq %d)." __L, seq); } else if(ord == SeqPast) { //they are nacking blocks going back before our buffer, wtf? - Log.Out(Logs::Detail, Logs::Netcode, _L "Received an ack with backward window advancement (they gave %d, our window starts at %d). This is bad." __L, seq, SequencedBase); + Log(Logs::Detail, Logs::Netcode, _L "Received an ack with backward window advancement (they gave %d, our window starts at %d). This is bad." __L, seq, SequencedBase); } else { - Log.Out(Logs::Detail, Logs::Netcode, _L "Received an ack up through sequence %d. Our base is %d." __L, seq, SequencedBase); + Log(Logs::Detail, Logs::Netcode, _L "Received an ack up through sequence %d. Our base is %d." __L, seq, SequencedBase); //this is a good ack, we get to ack some blocks. seq++; //we stop at the block right after their ack, counting on the wrap of both numbers. while(SequencedBase != seq) { -if(SequencedQueue.empty()) { -Log.Out(Logs::Detail, Logs::Netcode, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, NextSequencedSend); - SequencedBase = NextOutSeq; - NextSequencedSend = 0; - break; -} - Log.Out(Logs::Detail, Logs::Netcode, _L "Removing acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, NextSequencedSend); + if(SequencedQueue.empty()) { + Log(Logs::Detail, Logs::Netcode, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, SequencedQueue.size()); + SequencedBase = NextOutSeq; + break; + } + Log(Logs::Detail, Logs::Netcode, _L "Removing acked packet with sequence %lu." __L, (unsigned long)SequencedBase); //clean out the acked packet delete SequencedQueue.front(); SequencedQueue.pop_front(); - //adjust our "next" pointer - if(NextSequencedSend > 0) - NextSequencedSend--; //advance the base sequence number to the seq of the block after the one we just got rid of. SequencedBase++; } -if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq); -} -if(NextSequencedSend > SequencedQueue.size()) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); -} + if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { + Log(Logs::Detail, Logs::Netcode, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq); + } } MOutboundQueue.unlock(); @@ -1210,7 +1166,7 @@ if(NextSequencedSend > SequencedQueue.size()) { void EQStream::SetNextAckToSend(uint32 seq) { MAcks.lock(); - Log.Out(Logs::Detail, Logs::Netcode, _L "Set Next Ack To Send to %lu" __L, (unsigned long)seq); + Log(Logs::Detail, Logs::Netcode, _L "Set Next Ack To Send to %lu" __L, (unsigned long)seq); NextAckToSend=seq; MAcks.unlock(); } @@ -1218,7 +1174,7 @@ void EQStream::SetNextAckToSend(uint32 seq) void EQStream::SetLastAckSent(uint32 seq) { MAcks.lock(); - Log.Out(Logs::Detail, Logs::Netcode, _L "Set Last Ack Sent to %lu" __L, (unsigned long)seq); + Log(Logs::Detail, Logs::Netcode, _L "Set Last Ack Sent to %lu" __L, (unsigned long)seq); LastAckSent=seq; MAcks.unlock(); } @@ -1231,10 +1187,10 @@ void EQStream::ProcessQueue() EQProtocolPacket *qp=nullptr; while((qp=RemoveQueue(NextInSeq))!=nullptr) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Processing Queued Packet: Seq=%d" __L, NextInSeq); + Log(Logs::Detail, Logs::Netcode, _L "Processing Queued Packet: Seq=%d" __L, NextInSeq); ProcessPacket(qp); delete qp; - Log.Out(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); + Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); } } @@ -1245,21 +1201,21 @@ EQProtocolPacket *qp=nullptr; if ((itr=PacketQueue.find(seq))!=PacketQueue.end()) { qp=itr->second; PacketQueue.erase(itr); - Log.Out(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); + Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); } return qp; } void EQStream::SetStreamType(EQStreamType type) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Changing stream type from %s to %s" __L, StreamTypeString(StreamType), StreamTypeString(type)); + Log(Logs::Detail, Logs::Netcode, _L "Changing stream type from %s to %s" __L, StreamTypeString(StreamType), StreamTypeString(type)); StreamType=type; switch (StreamType) { case LoginStream: app_opcode_size=1; compressed=false; encoded=false; - Log.Out(Logs::Detail, Logs::Netcode, _L "Login stream has app opcode size %d, is not compressed or encoded." __L, app_opcode_size); + Log(Logs::Detail, Logs::Netcode, _L "Login stream has app opcode size %d, is not compressed or encoded." __L, app_opcode_size); break; case ChatOrMailStream: case ChatStream: @@ -1267,7 +1223,7 @@ void EQStream::SetStreamType(EQStreamType type) app_opcode_size=1; compressed=false; encoded=true; - Log.Out(Logs::Detail, Logs::Netcode, _L "Chat/Mail stream has app opcode size %d, is not compressed, and is encoded." __L, app_opcode_size); + Log(Logs::Detail, Logs::Netcode, _L "Chat/Mail stream has app opcode size %d, is not compressed, and is encoded." __L, app_opcode_size); break; case ZoneStream: case WorldStream: @@ -1275,7 +1231,7 @@ void EQStream::SetStreamType(EQStreamType type) app_opcode_size=2; compressed=true; encoded=false; - Log.Out(Logs::Detail, Logs::Netcode, _L "World/Zone stream has app opcode size %d, is compressed, and is not encoded." __L, app_opcode_size); + Log(Logs::Detail, Logs::Netcode, _L "World/Zone stream has app opcode size %d, is compressed, and is not encoded." __L, app_opcode_size); break; } } @@ -1325,7 +1281,7 @@ EQStream::SeqOrder EQStream::CompareSequence(uint16 expected_seq , uint16 seq) void EQStream::SetState(EQStreamState state) { MState.lock(); - Log.Out(Logs::Detail, Logs::Netcode, _L "Changing state from %d to %d" __L, State, state); + Log(Logs::Detail, Logs::Netcode, _L "Changing state from %d to %d" __L, State, state); State=state; MState.unlock(); } @@ -1337,29 +1293,29 @@ void EQStream::CheckTimeout(uint32 now, uint32 timeout) { EQStreamState orig_state = GetState(); if (orig_state == CLOSING && !outgoing_data) { - Log.Out(Logs::Detail, Logs::Netcode, _L "Out of data in closing state, disconnecting." __L); + Log(Logs::Detail, Logs::Netcode, _L "Out of data in closing state, disconnecting." __L); _SendDisconnect(); SetState(DISCONNECTING); } else if (LastPacket && (now-LastPacket) > timeout) { switch(orig_state) { case CLOSING: //if we time out in the closing state, they are not acking us, just give up - Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout expired in closing state. Moving to closed state." __L); + Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in closing state. Moving to closed state." __L); _SendDisconnect(); SetState(CLOSED); break; case DISCONNECTING: //we timed out waiting for them to send us the disconnect reply, just give up. - Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout expired in disconnecting state. Moving to closed state." __L); + Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in disconnecting state. Moving to closed state." __L); SetState(CLOSED); break; case CLOSED: - Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout expired in closed state??" __L); + Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in closed state??" __L); break; case ESTABLISHED: //we timed out during normal operation. Try to be nice about it. //we will almost certainly time out again waiting for the disconnect reply, but oh well. - Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout expired in established state. Closing connection." __L); + Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in established state. Closing connection." __L); _SendDisconnect(); SetState(DISCONNECTING); break; @@ -1379,6 +1335,18 @@ void EQStream::Decay() if (BytesWritten<0) BytesWritten=0; } + // check for any timed out acks + if ((GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) && RETRANSMIT_TIMEOUT_MULT && retransmittimeout) { + int count = 0; + MOutboundQueue.lock(); + for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end(); ++sitr, count++) { + if (!(*sitr)->acked && (*sitr)->sent_time > 0 && ((*sitr)->sent_time + retransmittimeout) < Timer::GetCurrentTime()) { + (*sitr)->sent_time = 0; + Log(Logs::Detail, Logs::Netcode, _L "Timeout exceeded for seq %d. Flagging packet for retransmission" __L, SequencedBase + count); + } + } + MOutboundQueue.unlock(); + } } void EQStream::AdjustRates(uint32 average_delta) @@ -1386,21 +1354,27 @@ void EQStream::AdjustRates(uint32 average_delta) if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { if (average_delta && (average_delta <= AVERAGE_DELTA_MAX)) { MRate.lock(); + AverageDelta = average_delta; RateThreshold=RATEBASE/average_delta; DecayRate=DECAYBASE/average_delta; - Log.Out(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L, + if (BytesWritten > RateThreshold) + BytesWritten = RateThreshold + DecayRate; + Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L, RateThreshold, DecayRate, average_delta); MRate.unlock(); } else { - Log.Out(Logs::Detail, Logs::Netcode, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L, + Log(Logs::Detail, Logs::Netcode, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L, average_delta, AVERAGE_DELTA_MAX); + AverageDelta = AVERAGE_DELTA_MAX; } } else { if (average_delta) { MRate.lock(); + AverageDelta = average_delta; + BytesWritten = 0; RateThreshold=RATEBASE/average_delta; DecayRate=DECAYBASE/average_delta; - Log.Out(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L, + Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L, RateThreshold, DecayRate, average_delta); MRate.unlock(); } @@ -1410,12 +1384,12 @@ void EQStream::AdjustRates(uint32 average_delta) void EQStream::Close() { if(HasOutgoingData()) { //there is pending data, wait for it to go out. - Log.Out(Logs::Detail, Logs::Netcode, _L "Stream requested to Close(), but there is pending data, waiting for it." __L); + Log(Logs::Detail, Logs::Netcode, _L "Stream requested to Close(), but there is pending data, waiting for it." __L); SetState(CLOSING); } else { //otherwise, we are done, we can drop immediately. _SendDisconnect(); - Log.Out(Logs::Detail, Logs::Netcode, _L "Stream closing immediate due to Close()" __L); + Log(Logs::Detail, Logs::Netcode, _L "Stream closing immediate due to Close()" __L); SetState(DISCONNECTING); } } @@ -1443,19 +1417,19 @@ EQStream::MatchState EQStream::CheckSignature(const Signature *sig) { } else if(p->opcode == sig->first_eq_opcode) { //opcode matches, check length.. if(p->size == sig->first_length) { - Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length matched %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size); + Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length matched %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size); res = MatchSuccessful; } else if(sig->first_length == 0) { - Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length (%d) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size); + Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length (%d) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size); res = MatchSuccessful; } else { //opcode matched but length did not. - Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x, but length %d did not match expected %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length); + Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x, but length %d did not match expected %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length); res = MatchFailed; } } else { //first opcode did not match.. - Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode 0x%x did not match expected 0x%x", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode); + Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode 0x%x did not match expected 0x%x", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode); res = MatchFailed; } } diff --git a/common/eq_stream.h b/common/eq_stream.h index 0bdfeab53..d5e78c085 100644 --- a/common/eq_stream.h +++ b/common/eq_stream.h @@ -153,7 +153,6 @@ class EQStream : public EQStreamInterface { std::deque SequencedQueue; uint16 NextOutSeq; uint16 SequencedBase; //the sequence number of SequencedQueue[0] - long NextSequencedSend; //index into SequencedQueue Mutex MOutboundQueue; //a buffer we use for compression/decompression @@ -174,7 +173,7 @@ class EQStream : public EQStreamInterface { Mutex MRate; int32 RateThreshold; int32 DecayRate; - + uint32 AverageDelta; OpcodeManager **OpMgr; diff --git a/common/eq_stream_factory.cpp b/common/eq_stream_factory.cpp index f48b0f723..429f258f6 100644 --- a/common/eq_stream_factory.cpp +++ b/common/eq_stream_factory.cpp @@ -3,7 +3,7 @@ #include "eq_stream_factory.h" #ifdef _WINDOWS - #include + #include #include #include #include @@ -23,18 +23,10 @@ ThreadReturnType EQStreamFactoryReaderLoop(void *eqfs) { -EQStreamFactory *fs=(EQStreamFactory *)eqfs; - -#ifndef WIN32 - Log.Out(Logs::Detail, Logs::None, "Starting EQStreamFactoryReaderLoop with thread ID %d", pthread_self()); -#endif + EQStreamFactory *fs=(EQStreamFactory *)eqfs; fs->ReaderLoop(); -#ifndef WIN32 - Log.Out(Logs::Detail, Logs::None, "Ending EQStreamFactoryReaderLoop with thread ID %d", pthread_self()); -#endif - THREAD_RETURN(nullptr); } @@ -42,16 +34,8 @@ ThreadReturnType EQStreamFactoryWriterLoop(void *eqfs) { EQStreamFactory *fs=(EQStreamFactory *)eqfs; -#ifndef WIN32 - Log.Out(Logs::Detail, Logs::None, "Starting EQStreamFactoryWriterLoop with thread ID %d", pthread_self()); -#endif - fs->WriterLoop(); -#ifndef WIN32 - Log.Out(Logs::Detail, Logs::None, "Ending EQStreamFactoryWriterLoop with thread ID %d", pthread_self()); -#endif - THREAD_RETURN(nullptr); } @@ -120,7 +104,7 @@ std::shared_ptr EQStreamFactory::Pop() { std::shared_ptr s = nullptr; MNewStreams.lock(); - if (NewStreams.size()) { + if (!NewStreams.empty()) { s = NewStreams.front(); NewStreams.pop(); s->PutInUse(); @@ -235,7 +219,7 @@ void EQStreamFactory::CheckTimeout() //give it a little time for everybody to finish with it } else { //everybody is done, we can delete it now - std::map, std::shared_ptr>::iterator temp = stream_itr; + auto temp = stream_itr; ++stream_itr; temp->second = nullptr; Streams.erase(temp); @@ -250,8 +234,7 @@ void EQStreamFactory::CheckTimeout() void EQStreamFactory::WriterLoop() { - std::map, std::shared_ptr>::iterator stream_itr; - bool havework=true; + bool havework = true; std::vector> wants_write; std::vector>::iterator cur, end; bool decay = false; @@ -260,7 +243,7 @@ void EQStreamFactory::WriterLoop() WriterRunning = true; DecayTimer.Enable(); - while(sock!=-1) { + while (sock != -1) { MWriterRunning.lock(); if (!WriterRunning) break; @@ -269,34 +252,36 @@ void EQStreamFactory::WriterLoop() havework = false; wants_write.clear(); - decay=DecayTimer.Check(); + decay = DecayTimer.Check(); - //copy streams into a seperate list so we dont have to keep - //MStreams locked while we are writting + // copy streams into a seperate list so we dont have to keep + // MStreams locked while we are writting MStreams.lock(); - for(stream_itr=Streams.begin();stream_itr!=Streams.end();++stream_itr) { + for (auto stream_itr = Streams.begin(); stream_itr != Streams.end(); ++stream_itr) { // If it's time to decay the bytes sent, then let's do it before we try to write if (decay) stream_itr->second->Decay(); - //bullshit checking, to see if this is really happening, GDB seems to think so... - if(stream_itr->second == nullptr) { - fprintf(stderr, "ERROR: nullptr Stream encountered in EQStreamFactory::WriterLoop for: %i:%i", stream_itr->first.first, stream_itr->first.second); + // bullshit checking, to see if this is really happening, GDB seems to think so... + if (stream_itr->second == nullptr) { + fprintf(stderr, + "ERROR: nullptr Stream encountered in EQStreamFactory::WriterLoop for: %i:%i", + stream_itr->first.first, stream_itr->first.second); continue; } if (stream_itr->second->HasOutgoingData()) { - havework=true; + havework = true; stream_itr->second->PutInUse(); wants_write.push_back(stream_itr->second); } } MStreams.unlock(); - //do the actual writes + // do the actual writes cur = wants_write.begin(); end = wants_write.end(); - for(; cur != end; ++cur) { + for (; cur != end; ++cur) { (*cur)->Write(sock); (*cur)->ReleaseFromUse(); } diff --git a/common/eq_stream_ident.cpp b/common/eq_stream_ident.cpp index 4640c75f1..83cd11133 100644 --- a/common/eq_stream_ident.cpp +++ b/common/eq_stream_ident.cpp @@ -1,3 +1,5 @@ +#include + #include "global_define.h" #include "eqemu_logsys.h" #include "eq_stream_ident.h" @@ -25,7 +27,7 @@ EQStreamIdentifier::~EQStreamIdentifier() { } void EQStreamIdentifier::RegisterPatch(const EQStream::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) { - Patch *p = new Patch; + auto p = new Patch; p->signature = sig; p->name = name; p->opcodes = opcodes; @@ -45,7 +47,7 @@ void EQStreamIdentifier::Process() { //first see if this stream has expired if(r.expire.Check(false)) { //this stream has failed to match any pattern in our timeframe. - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before timeout.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort())); + Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before timeout.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort())); r.stream->ReleaseFromUse(); cur = m_streams.erase(cur); continue; @@ -60,23 +62,23 @@ void EQStreamIdentifier::Process() { } if(r.stream->GetState() != ESTABLISHED) { //the stream closed before it was identified. - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before it closed.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort())); + Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before it closed.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort())); switch(r.stream->GetState()) { case ESTABLISHED: - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Established"); + Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Established"); break; case CLOSING: - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closing"); + Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closing"); break; case DISCONNECTING: - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Disconnecting"); + Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Disconnecting"); break; case CLOSED: - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closed"); + Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closed"); break; default: - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Unestablished or unknown"); + Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Unestablished or unknown"); break; } r.stream->ReleaseFromUse(); @@ -106,7 +108,7 @@ void EQStreamIdentifier::Process() { case EQStream::MatchSuccessful: { //yay, a match. - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Identified stream %s:%d with signature %s", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str()); + Log(Logs::General, Logs::Netcode, "[IDENTIFY] Identified stream %s:%d with signature %s", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str()); // before we assign the eqstream to an interface, let the stream recognize it is in use and the session should not be reset any further r.stream->SetActive(true); @@ -120,7 +122,7 @@ void EQStreamIdentifier::Process() { } case EQStream::MatchFailed: //do nothing... - Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, and it did not match.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str()); + Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, and it did not match.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str()); break; } } @@ -128,7 +130,7 @@ void EQStreamIdentifier::Process() { //if we checked all patches and did not find a match. if(all_ready && !found_one) { //the stream cannot be identified. - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d, no match found.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort())); + Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d, no match found.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort())); r.stream->ReleaseFromUse(); } @@ -156,7 +158,7 @@ EQStreamInterface *EQStreamIdentifier::PopIdentified() { } EQStreamIdentifier::Record::Record(std::shared_ptr s) -: stream(s), +: stream(std::move(s)), expire(STREAM_IDENT_WAIT_MS) { } diff --git a/common/eq_stream_intf.h b/common/eq_stream_intf.h index 68b8ffc96..917a13a86 100644 --- a/common/eq_stream_intf.h +++ b/common/eq_stream_intf.h @@ -4,7 +4,7 @@ //this is the only part of an EQStream that is seen by the application. #include -#include "clientversions.h" +#include "emu_versions.h" typedef enum { ESTABLISHED, @@ -35,7 +35,7 @@ public: virtual const uint32 GetBytesRecieved() const { return 0; } virtual const uint32 GetBytesSentPerSecond() const { return 0; } virtual const uint32 GetBytesRecvPerSecond() const { return 0; } - virtual const ClientVersion GetClientVersion() const { return ClientVersion::Unknown; } + virtual const EQEmu::versions::ClientVersion ClientVersion() const { return EQEmu::versions::ClientVersion::Unknown; } }; #endif /*EQSTREAMINTF_H_*/ diff --git a/common/eq_stream_proxy.cpp b/common/eq_stream_proxy.cpp index 117ae8c94..0c41988e4 100644 --- a/common/eq_stream_proxy.cpp +++ b/common/eq_stream_proxy.cpp @@ -21,9 +21,9 @@ std::string EQStreamProxy::Describe() const { return(m_structs->Describe()); } -const ClientVersion EQStreamProxy::GetClientVersion() const +const EQEmu::versions::ClientVersion EQStreamProxy::ClientVersion() const { - return m_structs->GetClientVersion(); + return m_structs->ClientVersion(); } void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) { diff --git a/common/eq_stream_proxy.h b/common/eq_stream_proxy.h index 93ad1d884..def543b34 100644 --- a/common/eq_stream_proxy.h +++ b/common/eq_stream_proxy.h @@ -28,7 +28,7 @@ public: virtual void RemoveData(); virtual bool CheckState(EQStreamState state); virtual std::string Describe() const; - virtual const ClientVersion GetClientVersion() const; + virtual const EQEmu::versions::ClientVersion ClientVersion() const; virtual const uint32 GetBytesSent() const; virtual const uint32 GetBytesRecieved() const; diff --git a/common/eqdb.cpp b/common/eqdb.cpp index 2c912afba..a94be7768 100644 --- a/common/eqdb.cpp +++ b/common/eqdb.cpp @@ -63,7 +63,7 @@ EQDBRes * EQDB::query(Const_char *q) { //NOT THREAD SAFE! Const_char *EQDB::escape_string(Const_char *from) { int len = strlen(from); - char *res = new char[len*2+1]; + auto res = new char[len * 2 + 1]; mysql_real_escape_string(mysql_ref,res,from,len); diff --git a/common/eqemu_config.cpp b/common/eqemu_config.cpp index fb295cec1..900b83787 100644 --- a/common/eqemu_config.cpp +++ b/common/eqemu_config.cpp @@ -80,7 +80,7 @@ void EQEmuConfig::do_world(TiXmlElement *ele) sprintf(str, "loginserver%i", ++LoginCount); sub_ele = ele->FirstChildElement(str); if (sub_ele) { - LoginConfig* loginconfig = new LoginConfig; + auto loginconfig = new LoginConfig; text = ParseTextBlock(sub_ele, "host", true); if (text) { loginconfig->LoginHost = text; @@ -254,6 +254,10 @@ void EQEmuConfig::do_files(TiXmlElement *ele) if (text) { OpCodesFile = text; } + text = ParseTextBlock(ele, "plugin.pl", true); + if (text) { + PluginPlFile = text; + } } void EQEmuConfig::do_directories(TiXmlElement *ele) @@ -262,14 +266,45 @@ void EQEmuConfig::do_directories(TiXmlElement *ele) text = ParseTextBlock(ele, "maps", true); if (text) { MapDir = text; + if ( MapDir.back() != '/' ) + MapDir += '/'; } text = ParseTextBlock(ele, "quests", true); if (text) { QuestDir = text; + if ( QuestDir.back() != '/' ) + QuestDir += '/'; } text = ParseTextBlock(ele, "plugins", true); if (text) { PluginDir = text; + if ( PluginDir.back() != '/' ) + PluginDir += '/'; + } + text = ParseTextBlock(ele, "lua_modules", true); + if (text) { + LuaModuleDir = text; + if ( LuaModuleDir.back() != '/' ) + LuaModuleDir += '/'; + } + text = ParseTextBlock(ele, "patches", true); + if (text) { + PatchDir = text; + if ( PatchDir.back() != '/' ) + PatchDir += '/'; + } + text = ParseTextBlock(ele, "shared_memory", true); + if (text) { + SharedMemDir = text; + if ( SharedMemDir.back() != '/' ) + SharedMemDir += '/'; + } + //Not Fully Implemented yet LogDir + text = ParseTextBlock(ele, "logs", true); + if (text) { + LogDir = text; + if ( LogDir.back() != '/' ) + LogDir += '/'; } } @@ -404,6 +439,9 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const if (var_name == "OpCodesFile") { return (OpCodesFile); } + if (var_name == "PluginPlFile") { + return (PluginPlFile); + } if (var_name == "MapDir") { return (MapDir); } @@ -413,6 +451,18 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const if (var_name == "PluginDir") { return (PluginDir); } + if (var_name == "LuaModuleDir") { + return (LuaModuleDir); + } + if (var_name == "PatchDir") { + return (PatchDir); + } + if (var_name == "SharedMemDir") { + return (SharedMemDir); + } + if (var_name == "LogDir") { + return (LogDir); + } if (var_name == "LogPrefix") { return (LogPrefix); } @@ -468,9 +518,14 @@ void EQEmuConfig::Dump() const std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl; std::cout << "SpellsFile = " << SpellsFile << std::endl; std::cout << "OpCodesFile = " << OpCodesFile << std::endl; + std::cout << "PluginPlFile = " << PluginPlFile << std::endl; std::cout << "MapDir = " << MapDir << std::endl; std::cout << "QuestDir = " << QuestDir << std::endl; std::cout << "PluginDir = " << PluginDir << std::endl; + std::cout << "LuaModuleDir = " << LuaModuleDir << std::endl; + std::cout << "PatchDir = " << PatchDir << std::endl; + std::cout << "SharedMemDir = " << SharedMemDir << std::endl; + std::cout << "LogDir = " << LogDir << std::endl; std::cout << "ZonePortLow = " << ZonePortLow << std::endl; std::cout << "ZonePortHigh = " << ZonePortHigh << std::endl; std::cout << "DefaultStatus = " << (int)DefaultStatus << std::endl; diff --git a/common/eqemu_config.h b/common/eqemu_config.h index 039b6c327..58b1bee9b 100644 --- a/common/eqemu_config.h +++ b/common/eqemu_config.h @@ -79,11 +79,16 @@ class EQEmuConfig : public XMLParser // From std::string SpellsFile; std::string OpCodesFile; + std::string PluginPlFile; // From std::string MapDir; std::string QuestDir; std::string PluginDir; + std::string LuaModuleDir; + std::string PatchDir; + std::string SharedMemDir; + std::string LogDir; // From std::string LogPrefix; @@ -153,10 +158,16 @@ class EQEmuConfig : public XMLParser // Files SpellsFile = "spells_us.txt"; OpCodesFile = "opcodes.conf"; + PluginPlFile = "plugin.pl"; // Dirs - MapDir = "Maps"; - QuestDir = "quests"; - PluginDir = "plugins"; + MapDir = "Maps/"; + QuestDir = "quests/"; + PluginDir = "plugins/"; + LuaModuleDir = "lua_modules/"; + PatchDir = "./"; + SharedMemDir = "shared/"; + LogDir = "logs/"; + // Launcher LogPrefix = "logs/zone-"; LogSuffix = ".log"; diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index 4c0ee1c9f..78a26c5dc 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -123,26 +123,21 @@ void EQEmuLogSys::LoadLogSettingsDefaults() std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message) { - std::string category_string; - if (log_category > 0 && Logs::LogCategoryName[log_category]) - category_string = StringFormat("[%s] ", Logs::LogCategoryName[log_category]); - return StringFormat("%s%s", category_string.c_str(), in_message.c_str()); + std::string ret; + ret.push_back('['); + ret.append(Logs::LogCategoryName[log_category]); + ret.push_back(']'); + ret.push_back(' '); + ret.append(in_message); + return ret; } void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message) { - /* Check if category enabled for process */ - if (log_settings[log_category].log_to_gmsay == 0) - return; - /* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash */ if (log_category == Logs::LogCategory::Netcode) return; - /* Make sure the message inbound is at a debug level we're set at */ - if (log_settings[log_category].log_to_gmsay < debug_level) - return; - /* Check to see if the process that actually ran this is zone */ if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) on_log_gmsay_hook(log_category, message); @@ -160,14 +155,6 @@ void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const crash_log.close(); } - /* Check if category enabled for process */ - if (log_settings[log_category].log_to_file == 0) - return; - - /* Make sure the message inbound is at a debug level we're set at */ - if (log_settings[log_category].log_to_file < debug_level) - return; - char time_stamp[80]; EQEmuLogSys::SetCurrentTimeStamp(time_stamp); @@ -246,13 +233,6 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) { void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message) { - /* Check if category enabled for process */ - if (log_settings[log_category].log_to_console == 0) - return; - - /* Make sure the message inbound is at a debug level we're set at */ - if (log_settings[log_category].log_to_console < debug_level) - return; #ifdef _WINDOWS HANDLE console_handle; @@ -273,12 +253,25 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...) { - const bool log_to_console = log_settings[log_category].log_to_console > 0; - const bool log_to_file = log_settings[log_category].log_to_file > 0; - const bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0; - const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay; - if (nothing_to_log) return; + bool log_to_console = true; + if (log_settings[log_category].log_to_console < debug_level) { + log_to_console = false; + } + + bool log_to_file = true; + if (log_settings[log_category].log_to_file < debug_level) { + log_to_file = false; + } + + bool log_to_gmsay = true; + if (log_settings[log_category].log_to_gmsay < debug_level) { + log_to_gmsay = false; + } + + const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay; + if (nothing_to_log) + return; va_list args; va_start(args, message); diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index 153d61582..71a270322 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -1,3 +1,4 @@ + /* EQEMu: Everquest Server Emulator Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) @@ -38,103 +39,110 @@ namespace Logs { NOTE: Only add to the bottom of the enum because that is the type ID assignment */ - enum LogCategory { - None = 0, - AA, - AI, - Aggro, - Attack, - Client_Server_Packet, - Combat, - Commands, - Crash, - Debug, - Doors, - Error, - Guilds, - Inventory, - Launcher, - Netcode, - Normal, - Object, - Pathing, - QS_Server, - Quests, - Rules, - Skills, - Spawns, - Spells, - Status, - TCP_Connection, - Tasks, - Tradeskills, - Trading, - Tribute, - UCS_Server, - WebInterface_Server, - World_Server, - Zone_Server, - MySQLError, - MySQLQuery, - Mercenaries, - QuestDebug, - Server_Client_Packet, - Client_Server_Packet_Unhandled, - Server_Client_Packet_With_Dump, - Client_Server_Packet_With_Dump, - Login_Server, - MaxCategoryID /* Don't Remove this*/ - }; +enum LogCategory { + None = 0, + AA, + AI, + Aggro, + Attack, + Client_Server_Packet, + Combat, + Commands, + Crash, + Debug, + Doors, + Error, + Guilds, + Inventory, + Launcher, + Netcode, + Normal, + Object, + Pathing, + QS_Server, + Quests, + Rules, + Skills, + Spawns, + Spells, + Status, + TCP_Connection, + Tasks, + Tradeskills, + Trading, + Tribute, + UCS_Server, + WebInterface_Server, + World_Server, + Zone_Server, + MySQLError, + MySQLQuery, + Mercenaries, + QuestDebug, + Server_Client_Packet, + Client_Server_Packet_Unhandled, + Server_Client_Packet_With_Dump, + Client_Server_Packet_With_Dump, + Login_Server, + Client_Login, + MaxCategoryID /* Don't Remove this*/ +}; - /* If you add to this, make sure you update LogCategory */ - static const char* LogCategoryName[LogCategory::MaxCategoryID] = { - "", - "AA", - "AI", - "Aggro", - "Attack", - "Packet :: Client -> Server", - "Combat", - "Commands", - "Crash", - "Debug", - "Doors", - "Error", - "Guilds", - "Inventory", - "Launcher", - "Netcode", - "Normal", - "Object", - "Pathing", - "QS Server", - "Quests", - "Rules", - "Skills", - "Spawns", - "Spells", - "Status", - "TCP Connection", - "Tasks", - "Tradeskills", - "Trading", - "Tribute", - "UCS Server", - "WebInterface Server", - "World Server", - "Zone Server", - "MySQL Error", - "MySQL Query", - "Mercenaries", - "Quest Debug", - "Packet :: Server -> Client", - "Packet :: Client -> Server Unhandled", - "Packet :: Server -> Client (Dump)", - "Packet :: Client -> Server (Dump)", - "Login Server" - }; +/* If you add to this, make sure you update LogCategory */ +static const char* LogCategoryName[LogCategory::MaxCategoryID] = { + "", + "AA", + "AI", + "Aggro", + "Attack", + "Packet :: Client -> Server", + "Combat", + "Commands", + "Crash", + "Debug", + "Doors", + "Error", + "Guilds", + "Inventory", + "Launcher", + "Netcode", + "Normal", + "Object", + "Pathing", + "QS Server", + "Quests", + "Rules", + "Skills", + "Spawns", + "Spells", + "Status", + "TCP Connection", + "Tasks", + "Tradeskills", + "Trading", + "Tribute", + "UCS Server", + "WebInterface Server", + "World Server", + "Zone Server", + "MySQL Error", + "MySQL Query", + "Mercenaries", + "Quest Debug", + "Packet :: Server -> Client", + "Packet :: Client -> Server Unhandled", + "Packet :: Server -> Client (Dump)", + "Packet :: Client -> Server (Dump)", + "Login Server", + "Client Login" +}; } +#define Log(debug_level, log_category, message, ...) do {\ + if (LogSys.log_settings[log_category].is_category_enabled == 1)\ + LogSys.Out(debug_level, log_category, message, ##__VA_ARGS__);\ +} while (0) + class EQEmuLogSys { public: EQEmuLogSys(); @@ -201,6 +209,6 @@ private: void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessLogWrite called via Log.Out */ }; -extern EQEmuLogSys Log; +extern EQEmuLogSys LogSys; #endif diff --git a/common/extprofile.h b/common/extprofile.h index 49b8fb8f3..bdb746068 100644 --- a/common/extprofile.h +++ b/common/extprofile.h @@ -19,7 +19,7 @@ #define EXTENDED_PROFILE_H #include "eq_packet_structs.h" -#include "item.h" +#include "inventory_profile.h" #pragma pack(1) @@ -40,7 +40,7 @@ struct ExtendedProfile_Struct { uint16 old_pet_hp; /* Not Used */ uint16 old_pet_mana; /* Not Used */ SpellBuff_Struct pet_buffs[BUFF_COUNT]; /* Not Used */ - uint32 pet_items[_MaterialCount]; /* Not Used */ + EQEmu::TextureMaterialProfile pet_items; /* Not Used */ char merc_name[64]; /* Used */ uint32 aa_effects; /* Used */ diff --git a/common/features.h b/common/features.h index 9ceddb31b..7e347db6d 100644 --- a/common/features.h +++ b/common/features.h @@ -111,9 +111,6 @@ Zone extensions and features //path to where sql logs should be placed #define SQL_LOG_PATH "sql_logs/" -//New aggro system to reduce overhead. -#define REVERSE_AGGRO - //The highest you can #setskill / #setallskill #define HIGHEST_CAN_SET_SKILL 400 @@ -157,7 +154,7 @@ enum { //timer settings, all in milliseconds AIscanarea_delay = 6000, AIfeignremember_delay = 500, AItarget_check_duration = 500, - AIClientScanarea_delay = 750, //used in REVERSE_AGGRO + // AIClientScanarea_delay = 750, //used in REVERSE_AGGRO AIassistcheck_delay = 3000, //now often a fighting NPC will yell for help AI_check_signal_timer_delay = 500, // How often EVENT_SIGNAL checks are processed ClientProximity_interval = 150, @@ -213,8 +210,8 @@ enum { //some random constants #define MAX_NPC_FACTIONS 20 //individual faction pool -#define MAX_PERSONAL_FACTION 1200 -#define MIN_PERSONAL_FACTION -3000 +#define MAX_PERSONAL_FACTION 2000 +#define MIN_PERSONAL_FACTION -2000 //The Level Cap: //#define LEVEL_CAP RuleI(Character, MaxLevel) //hard cap is 127 @@ -235,6 +232,9 @@ enum { //some random constants #define ZONE_CONTROLLER_NPC_ID 10 +// Timer to update aggrometer +#define AGGRO_METER_UPDATE_MS 1000 + //Some hard coded statuses from commands and other places: enum { minStatusToBeGM = 40, diff --git a/common/glm/copying.txt b/common/glm/copying.txt index efd93bab9..7c20b4a67 100644 --- a/common/glm/copying.txt +++ b/common/glm/copying.txt @@ -1,6 +1,39 @@ -The MIT License +================================================================================ +OpenGL Mathematics (GLM) +-------------------------------------------------------------------------------- +GLM can be distributed and/or modified under the terms of either +a) The Happy Bunny License, or b) the MIT License. -Copyright (c) 2005 - 2013 G-Truc Creation +================================================================================ +The Happy Bunny License (Modified MIT License) +-------------------------------------------------------------------------------- +Copyright (c) 2005 - 2016 G-Truc Creation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Restrictions: By making use of the Software for military purposes, you choose +to make a Bunny unhappy. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +================================================================================ +The MIT License +-------------------------------------------------------------------------------- +Copyright (c) 2005 - 2016 G-Truc Creation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/common/glm/glm/CMakeLists.txt b/common/glm/glm/CMakeLists.txt index 9dbe11cab..d60a88771 100644 --- a/common/glm/glm/CMakeLists.txt +++ b/common/glm/glm/CMakeLists.txt @@ -1,9 +1,9 @@ -set(NAME glm_dummy) - file(GLOB ROOT_SOURCE *.cpp) file(GLOB ROOT_INLINE *.inl) file(GLOB ROOT_HEADER *.hpp) file(GLOB ROOT_TEXT ../*.txt) +file(GLOB ROOT_MD ../*.md) +file(GLOB ROOT_NAT ../util/glm.natvis) file(GLOB_RECURSE CORE_SOURCE ./detail/*.cpp) file(GLOB_RECURSE CORE_INLINE ./detail/*.inl) @@ -17,7 +17,11 @@ file(GLOB_RECURSE GTX_SOURCE ./gtx/*.cpp) file(GLOB_RECURSE GTX_INLINE ./gtx/*.inl) file(GLOB_RECURSE GTX_HEADER ./gtx/*.hpp) -source_group("Text Files" FILES ${ROOT_TEXT}) +file(GLOB_RECURSE SIMD_SOURCE ./simd/*.cpp) +file(GLOB_RECURSE SIMD_INLINE ./simd/*.inl) +file(GLOB_RECURSE SIMD_HEADER ./simd/*.h) + +source_group("Text Files" FILES ${ROOT_TEXT} ${ROOT_MD}) source_group("Core Files" FILES ${CORE_SOURCE}) source_group("Core Files" FILES ${CORE_INLINE}) source_group("Core Files" FILES ${CORE_HEADER}) @@ -27,16 +31,37 @@ source_group("GTC Files" FILES ${GTC_HEADER}) source_group("GTX Files" FILES ${GTX_SOURCE}) source_group("GTX Files" FILES ${GTX_INLINE}) source_group("GTX Files" FILES ${GTX_HEADER}) +source_group("SIMD Files" FILES ${SIMD_SOURCE}) +source_group("SIMD Files" FILES ${SIMD_INLINE}) +source_group("SIMD Files" FILES ${SIMD_HEADER}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) -if(GLM_TEST_ENABLE) - add_executable(${NAME} ${ROOT_TEXT} +if(GLM_STATIC_LIBRARY_ENABLE OR GLM_DYNAMIC_LIBRARY_ENABLE) + if(GLM_STATIC_LIBRARY_ENABLE) + add_library(glm_static STATIC ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT} + ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER} + ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER} + ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER} + ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER} + ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER}) + endif(GLM_STATIC_LIBRARY_ENABLE) + + if(GLM_DYNAMIC_LIBRARY_ENABLE) + add_library(glm_shared SHARED ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT} + ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER} + ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER} + ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER} + ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER} + ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER}) + endif(GLM_DYNAMIC_LIBRARY_ENABLE) + +else(GLM_STATIC_LIBRARY_ENABLE OR GLM_DYNAMIC_LIBRARY_ENABLE) + add_executable(glm_dummy ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT} ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER} ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER} ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER} - ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER}) -endif(GLM_TEST_ENABLE) + ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER} + ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER}) -#add_library(glm STATIC glm.cpp) -#add_library(glm_shared SHARED glm.cpp) +endif(GLM_STATIC_LIBRARY_ENABLE OR GLM_DYNAMIC_LIBRARY_ENABLE) diff --git a/common/glm/glm/common.hpp b/common/glm/glm/common.hpp index 8f1c3171e..f57e800ee 100644 --- a/common/glm/glm/common.hpp +++ b/common/glm/glm/common.hpp @@ -1,34 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////////// -/// OpenGL Mathematics (glm.g-truc.net) -/// -/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) -/// Permission is hereby granted, free of charge, to any person obtaining a copy -/// of this software and associated documentation files (the "Software"), to deal -/// in the Software without restriction, including without limitation the rights -/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/// copies of the Software, and to permit persons to whom the Software is -/// furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// Restrictions: -/// By making use of the Software for military purposes, you choose to make -/// a Bunny unhappy. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. -/// /// @ref core /// @file glm/common.hpp -/// @date 2013-12-24 / 2013-12-24 -/// @author Christophe Riccio -/////////////////////////////////////////////////////////////////////////////////// #pragma once diff --git a/common/glm/glm/detail/_features.hpp b/common/glm/glm/detail/_features.hpp index 51eda577c..97dd63303 100644 --- a/common/glm/glm/detail/_features.hpp +++ b/common/glm/glm/detail/_features.hpp @@ -1,34 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////////// -/// OpenGL Mathematics (glm.g-truc.net) -/// -/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) -/// Permission is hereby granted, free of charge, to any person obtaining a copy -/// of this software and associated documentation files (the "Software"), to deal -/// in the Software without restriction, including without limitation the rights -/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/// copies of the Software, and to permit persons to whom the Software is -/// furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// Restrictions: -/// By making use of the Software for military purposes, you choose to make -/// a Bunny unhappy. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. -/// /// @ref core /// @file glm/detail/_features.hpp -/// @date 2013-02-20 / 2013-02-20 -/// @author Christophe Riccio -/////////////////////////////////////////////////////////////////////////////////// #pragma once @@ -284,7 +255,7 @@ # define GLM_CXX11_STATIC_ASSERT # endif -#elif(GLM_COMPILER & (GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM)) +#elif(GLM_COMPILER & GLM_COMPILER_CLANG) # if(__has_feature(cxx_exceptions)) # define GLM_CXX98_EXCEPTIONS # endif @@ -425,4 +396,4 @@ # define GLM_CXX11_VARIADIC_TEMPLATES # endif -#endif//(GLM_COMPILER & (GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM)) +#endif//(GLM_COMPILER & GLM_COMPILER_CLANG) diff --git a/common/glm/glm/detail/_fixes.hpp b/common/glm/glm/detail/_fixes.hpp index 6185dcbb7..c957562b4 100644 --- a/common/glm/glm/detail/_fixes.hpp +++ b/common/glm/glm/detail/_fixes.hpp @@ -1,34 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////////// -/// OpenGL Mathematics (glm.g-truc.net) -/// -/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) -/// Permission is hereby granted, free of charge, to any person obtaining a copy -/// of this software and associated documentation files (the "Software"), to deal -/// in the Software without restriction, including without limitation the rights -/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/// copies of the Software, and to permit persons to whom the Software is -/// furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// Restrictions: -/// By making use of the Software for military purposes, you choose to make -/// a Bunny unhappy. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. -/// /// @ref core /// @file glm/detail/_fixes.hpp -/// @date 2011-02-21 / 2011-11-22 -/// @author Christophe Riccio -/////////////////////////////////////////////////////////////////////////////////// #include diff --git a/common/glm/glm/detail/_noise.hpp b/common/glm/glm/detail/_noise.hpp index 94c835d54..89403f4a7 100644 --- a/common/glm/glm/detail/_noise.hpp +++ b/common/glm/glm/detail/_noise.hpp @@ -1,34 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////////// -/// OpenGL Mathematics (glm.g-truc.net) -/// -/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) -/// Permission is hereby granted, free of charge, to any person obtaining a copy -/// of this software and associated documentation files (the "Software"), to deal -/// in the Software without restriction, including without limitation the rights -/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/// copies of the Software, and to permit persons to whom the Software is -/// furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// Restrictions: -/// By making use of the Software for military purposes, you choose to make -/// a Bunny unhappy. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. -/// /// @ref core /// @file glm/detail/_noise.hpp -/// @date 2013-12-24 / 2013-12-24 -/// @author Christophe Riccio -/////////////////////////////////////////////////////////////////////////////////// #pragma once diff --git a/common/glm/glm/detail/_swizzle.hpp b/common/glm/glm/detail/_swizzle.hpp index 3edf6cb23..8e134d90e 100644 --- a/common/glm/glm/detail/_swizzle.hpp +++ b/common/glm/glm/detail/_swizzle.hpp @@ -1,34 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////////// -/// OpenGL Mathematics (glm.g-truc.net) -/// -/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) -/// Permission is hereby granted, free of charge, to any person obtaining a copy -/// of this software and associated documentation files (the "Software"), to deal -/// in the Software without restriction, including without limitation the rights -/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/// copies of the Software, and to permit persons to whom the Software is -/// furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// Restrictions: -/// By making use of the Software for military purposes, you choose to make -/// a Bunny unhappy. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. -/// /// @ref core /// @file glm/detail/_swizzle.hpp -/// @date 2006-04-20 / 2011-02-16 -/// @author Christophe Riccio -/////////////////////////////////////////////////////////////////////////////////// #pragma once @@ -39,11 +10,9 @@ namespace detail template struct _swizzle_base0 { - typedef T value_type; - protected: - GLM_FUNC_QUALIFIER value_type& elem (size_t i) { return (reinterpret_cast(_buffer))[i]; } - GLM_FUNC_QUALIFIER const value_type& elem (size_t i) const { return (reinterpret_cast(_buffer))[i]; } + GLM_FUNC_QUALIFIER T& elem(size_t i){ return (reinterpret_cast(_buffer))[i]; } + GLM_FUNC_QUALIFIER T const& elem(size_t i) const{ return (reinterpret_cast(_buffer))[i]; } // Use an opaque buffer to *ensure* the compiler doesn't call a constructor. // The size 1 buffer is assumed to aligned to the actual members so that the @@ -51,27 +20,27 @@ namespace detail char _buffer[1]; }; - template + template class vecType, int E0, int E1, int E2, int E3, bool Aligned> struct _swizzle_base1 : public _swizzle_base0 { }; - template - struct _swizzle_base1 : public _swizzle_base0 + template class vecType, int E0, int E1, bool Aligned> + struct _swizzle_base1<2, T, P, vecType, E0,E1,-1,-2, Aligned> : public _swizzle_base0 { - GLM_FUNC_QUALIFIER V operator ()() const { return V(this->elem(E0), this->elem(E1)); } + GLM_FUNC_QUALIFIER vecType operator ()() const { return vecType(this->elem(E0), this->elem(E1)); } }; - template - struct _swizzle_base1 : public _swizzle_base0 + template class vecType, int E0, int E1, int E2, bool Aligned> + struct _swizzle_base1<3, T, P, vecType, E0,E1,E2,-1, Aligned> : public _swizzle_base0 { - GLM_FUNC_QUALIFIER V operator ()() const { return V(this->elem(E0), this->elem(E1), this->elem(E2)); } + GLM_FUNC_QUALIFIER vecType operator ()() const { return vecType(this->elem(E0), this->elem(E1), this->elem(E2)); } }; - template - struct _swizzle_base1 : public _swizzle_base0 + template class vecType, int E0, int E1, int E2, int E3, bool Aligned> + struct _swizzle_base1<4, T, P, vecType, E0,E1,E2,E3, Aligned> : public _swizzle_base0 { - GLM_FUNC_QUALIFIER V operator ()() const { return V(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); } + GLM_FUNC_QUALIFIER vecType operator ()() const { return vecType(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); } }; // Internal class for implementing swizzle operators @@ -86,79 +55,76 @@ namespace detail DUPLICATE_ELEMENTS = 1 if there is a repeated element, 0 otherwise (used to specialize swizzles containing duplicate elements so that they cannot be used as r-values). */ - template - struct _swizzle_base2 : public _swizzle_base1 + template class vecType, int E0, int E1, int E2, int E3, int DUPLICATE_ELEMENTS> + struct _swizzle_base2 : public _swizzle_base1::value> { - typedef VecType vec_type; - typedef ValueType value_type; - - GLM_FUNC_QUALIFIER _swizzle_base2& operator= (const ValueType& t) + GLM_FUNC_QUALIFIER _swizzle_base2& operator= (const T& t) { for (int i = 0; i < N; ++i) (*this)[i] = t; return *this; } - GLM_FUNC_QUALIFIER _swizzle_base2& operator= (const VecType& that) + GLM_FUNC_QUALIFIER _swizzle_base2& operator= (vecType const& that) { struct op { - GLM_FUNC_QUALIFIER void operator() (value_type& e, value_type& t) { e = t; } + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) { e = t; } }; _apply_op(that, op()); return *this; } - GLM_FUNC_QUALIFIER void operator -= (const VecType& that) + GLM_FUNC_QUALIFIER void operator -= (vecType const& that) { struct op { - GLM_FUNC_QUALIFIER void operator() (value_type& e, value_type& t) { e -= t; } + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) { e -= t; } }; _apply_op(that, op()); } - GLM_FUNC_QUALIFIER void operator += (const VecType& that) + GLM_FUNC_QUALIFIER void operator += (vecType const& that) { struct op { - GLM_FUNC_QUALIFIER void operator() (value_type& e, value_type& t) { e += t; } + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) { e += t; } }; _apply_op(that, op()); } - GLM_FUNC_QUALIFIER void operator *= (const VecType& that) + GLM_FUNC_QUALIFIER void operator *= (vecType const& that) { struct op { - GLM_FUNC_QUALIFIER void operator() (value_type& e, value_type& t) { e *= t; } + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) { e *= t; } }; _apply_op(that, op()); } - GLM_FUNC_QUALIFIER void operator /= (const VecType& that) + GLM_FUNC_QUALIFIER void operator /= (vecType const& that) { struct op { - GLM_FUNC_QUALIFIER void operator() (value_type& e, value_type& t) { e /= t; } + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) { e /= t; } }; _apply_op(that, op()); } - GLM_FUNC_QUALIFIER value_type& operator[] (size_t i) + GLM_FUNC_QUALIFIER T& operator[](size_t i) { const int offset_dst[4] = { E0, E1, E2, E3 }; return this->elem(offset_dst[i]); } - GLM_FUNC_QUALIFIER value_type operator[] (size_t i) const + GLM_FUNC_QUALIFIER T operator[](size_t i) const { const int offset_dst[4] = { E0, E1, E2, E3 }; return this->elem(offset_dst[i]); } protected: - template - GLM_FUNC_QUALIFIER void _apply_op(const VecType& that, T op) + template + GLM_FUNC_QUALIFIER void _apply_op(vecType const& that, U op) { // Make a copy of the data in this == &that. // The copier should optimize out the copy in cases where the function is // properly inlined and the copy is not necessary. - ValueType t[N]; + T t[N]; for (int i = 0; i < N; ++i) t[i] = that[i]; for (int i = 0; i < N; ++i) @@ -167,56 +133,54 @@ namespace detail }; // Specialization for swizzles containing duplicate elements. These cannot be modified. - template - struct _swizzle_base2 : public _swizzle_base1 + template class vecType, int E0, int E1, int E2, int E3> + struct _swizzle_base2 : public _swizzle_base1::value> { - typedef VecType vec_type; - typedef ValueType value_type; - struct Stub {}; + GLM_FUNC_QUALIFIER _swizzle_base2& operator= (Stub const &) { return *this; } - GLM_FUNC_QUALIFIER value_type operator[] (size_t i) const + GLM_FUNC_QUALIFIER T operator[] (size_t i) const { const int offset_dst[4] = { E0, E1, E2, E3 }; return this->elem(offset_dst[i]); } }; - template - struct _swizzle : public _swizzle_base2 + template class vecType, int E0, int E1, int E2, int E3> + struct _swizzle : public _swizzle_base2 { - typedef _swizzle_base2 base_type; + typedef _swizzle_base2 base_type; using base_type::operator=; - GLM_FUNC_QUALIFIER operator VecType () const { return (*this)(); } + GLM_FUNC_QUALIFIER operator vecType () const { return (*this)(); } }; // // To prevent the C++ syntax from getting entirely overwhelming, define some alias macros // -#define _GLM_SWIZZLE_TEMPLATE1 template -#define _GLM_SWIZZLE_TEMPLATE2 template -#define _GLM_SWIZZLE_TYPE1 _swizzle -#define _GLM_SWIZZLE_TYPE2 _swizzle +#define _GLM_SWIZZLE_TEMPLATE1 template class vecType, int E0, int E1, int E2, int E3> +#define _GLM_SWIZZLE_TEMPLATE2 template class vecType, int E0, int E1, int E2, int E3, int F0, int F1, int F2, int F3> +#define _GLM_SWIZZLE_TYPE1 _swizzle +#define _GLM_SWIZZLE_TYPE2 _swizzle // // Wrapper for a binary operator (e.g. u.yy + v.zy) // #define _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \ _GLM_SWIZZLE_TEMPLATE2 \ - GLM_FUNC_QUALIFIER V operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b) \ + GLM_FUNC_QUALIFIER vecType operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b) \ { \ return a() OPERAND b(); \ } \ _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER V operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const V& b) \ + GLM_FUNC_QUALIFIER vecType operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const vecType& b) \ { \ return a() OPERAND b; \ } \ _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER V operator OPERAND ( const V& a, const _GLM_SWIZZLE_TYPE1& b) \ + GLM_FUNC_QUALIFIER vecType operator OPERAND ( const vecType& a, const _GLM_SWIZZLE_TYPE1& b) \ { \ return a OPERAND b(); \ } @@ -226,12 +190,12 @@ namespace detail // #define _GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \ _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER V operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const T& b) \ + GLM_FUNC_QUALIFIER vecType operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const T& b) \ { \ return a() OPERAND b; \ } \ _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER V operator OPERAND ( const T& a, const _GLM_SWIZZLE_TYPE1& b) \ + GLM_FUNC_QUALIFIER vecType operator OPERAND ( const T& a, const _GLM_SWIZZLE_TYPE1& b) \ { \ return a OPERAND b(); \ } @@ -334,500 +298,500 @@ namespace glm } #define _GLM_SWIZZLE2_2_MEMBERS(T, P, V, E0,E1) \ - struct { detail::_swizzle<2, T, P, V, 0,0,-1,-2> E0 ## E0; }; \ - struct { detail::_swizzle<2, T, P, V, 0,1,-1,-2> E0 ## E1; }; \ - struct { detail::_swizzle<2, T, P, V, 1,0,-1,-2> E1 ## E0; }; \ - struct { detail::_swizzle<2, T, P, V, 1,1,-1,-2> E1 ## E1; }; + struct { detail::_swizzle<2, T, P, V, 0,0,-1,-2> E0 ## E0; }; \ + struct { detail::_swizzle<2, T, P, V, 0,1,-1,-2> E0 ## E1; }; \ + struct { detail::_swizzle<2, T, P, V, 1,0,-1,-2> E1 ## E0; }; \ + struct { detail::_swizzle<2, T, P, V, 1,1,-1,-2> E1 ## E1; }; #define _GLM_SWIZZLE2_3_MEMBERS(T, P, V, E0,E1) \ - struct { detail::_swizzle<3,T, P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<3,T, P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<3,T, P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<3,T, P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<3,T, P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<3,T, P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<3,T, P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<3,T, P, V, 1,1,1,-1> E1 ## E1 ## E1; }; + struct { detail::_swizzle<3,T, P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T, P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T, P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T, P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3,T, P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T, P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T, P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T, P, V, 1,1,1,-1> E1 ## E1 ## E1; }; #define _GLM_SWIZZLE2_4_MEMBERS(T, P, V, E0,E1) \ - struct { detail::_swizzle<4,T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; + struct { detail::_swizzle<4,T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; #define _GLM_SWIZZLE3_2_MEMBERS(T, P, V, E0,E1,E2) \ - struct { detail::_swizzle<2,T, P, V, 0,0,-1,-2> E0 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 0,1,-1,-2> E0 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 0,2,-1,-2> E0 ## E2; }; \ - struct { detail::_swizzle<2,T, P, V, 1,0,-1,-2> E1 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 1,1,-1,-2> E1 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 1,2,-1,-2> E1 ## E2; }; \ - struct { detail::_swizzle<2,T, P, V, 2,0,-1,-2> E2 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 2,1,-1,-2> E2 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 2,2,-1,-2> E2 ## E2; }; + struct { detail::_swizzle<2,T, P, V, 0,0,-1,-2> E0 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 0,1,-1,-2> E0 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 0,2,-1,-2> E0 ## E2; }; \ + struct { detail::_swizzle<2,T, P, V, 1,0,-1,-2> E1 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 1,1,-1,-2> E1 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 1,2,-1,-2> E1 ## E2; }; \ + struct { detail::_swizzle<2,T, P, V, 2,0,-1,-2> E2 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 2,1,-1,-2> E2 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 2,2,-1,-2> E2 ## E2; }; #define _GLM_SWIZZLE3_3_MEMBERS(T, P, V ,E0,E1,E2) \ - struct { detail::_swizzle<3,T,P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 0,0,2,-1> E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 0,1,2,-1> E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 0,2,0,-1> E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 0,2,1,-1> E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 0,2,2,-1> E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 1,0,2,-1> E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 1,1,1,-1> E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 1,1,2,-1> E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 1,2,0,-1> E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 1,2,1,-1> E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 1,2,2,-1> E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 2,0,0,-1> E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 2,0,1,-1> E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 2,0,2,-1> E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 2,1,0,-1> E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 2,1,1,-1> E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 2,1,2,-1> E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 2,2,0,-1> E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 2,2,1,-1> E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 2,2,2,-1> E2 ## E2 ## E2; }; + struct { detail::_swizzle<3, T, P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 0,0,2,-1> E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 0,1,2,-1> E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 0,2,0,-1> E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 0,2,1,-1> E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 0,2,2,-1> E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 1,0,2,-1> E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 1,1,1,-1> E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 1,1,2,-1> E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 1,2,0,-1> E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 1,2,1,-1> E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 1,2,2,-1> E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 2,0,0,-1> E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 2,0,1,-1> E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 2,0,2,-1> E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 2,1,0,-1> E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 2,1,1,-1> E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 2,1,2,-1> E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 2,2,0,-1> E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 2,2,1,-1> E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 2,2,2,-1> E2 ## E2 ## E2; }; #define _GLM_SWIZZLE3_4_MEMBERS(T, P, V, E0,E1,E2) \ - struct { detail::_swizzle<4,T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; + struct { detail::_swizzle<4,T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; #define _GLM_SWIZZLE4_2_MEMBERS(T, P, V, E0,E1,E2,E3) \ - struct { detail::_swizzle<2,T, P, V, 0,0,-1,-2> E0 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 0,1,-1,-2> E0 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 0,2,-1,-2> E0 ## E2; }; \ - struct { detail::_swizzle<2,T, P, V, 0,3,-1,-2> E0 ## E3; }; \ - struct { detail::_swizzle<2,T, P, V, 1,0,-1,-2> E1 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 1,1,-1,-2> E1 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 1,2,-1,-2> E1 ## E2; }; \ - struct { detail::_swizzle<2,T, P, V, 1,3,-1,-2> E1 ## E3; }; \ - struct { detail::_swizzle<2,T, P, V, 2,0,-1,-2> E2 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 2,1,-1,-2> E2 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 2,2,-1,-2> E2 ## E2; }; \ - struct { detail::_swizzle<2,T, P, V, 2,3,-1,-2> E2 ## E3; }; \ - struct { detail::_swizzle<2,T, P, V, 3,0,-1,-2> E3 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 3,1,-1,-2> E3 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 3,2,-1,-2> E3 ## E2; }; \ - struct { detail::_swizzle<2,T, P, V, 3,3,-1,-2> E3 ## E3; }; + struct { detail::_swizzle<2,T, P, V, 0,0,-1,-2> E0 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 0,1,-1,-2> E0 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 0,2,-1,-2> E0 ## E2; }; \ + struct { detail::_swizzle<2,T, P, V, 0,3,-1,-2> E0 ## E3; }; \ + struct { detail::_swizzle<2,T, P, V, 1,0,-1,-2> E1 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 1,1,-1,-2> E1 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 1,2,-1,-2> E1 ## E2; }; \ + struct { detail::_swizzle<2,T, P, V, 1,3,-1,-2> E1 ## E3; }; \ + struct { detail::_swizzle<2,T, P, V, 2,0,-1,-2> E2 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 2,1,-1,-2> E2 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 2,2,-1,-2> E2 ## E2; }; \ + struct { detail::_swizzle<2,T, P, V, 2,3,-1,-2> E2 ## E3; }; \ + struct { detail::_swizzle<2,T, P, V, 3,0,-1,-2> E3 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 3,1,-1,-2> E3 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 3,2,-1,-2> E3 ## E2; }; \ + struct { detail::_swizzle<2,T, P, V, 3,3,-1,-2> E3 ## E3; }; -#define _GLM_SWIZZLE4_3_MEMBERS(T,P, V, E0,E1,E2,E3) \ - struct { detail::_swizzle<3,T,P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 0,0,2,-1> E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 0,0,3,-1> E0 ## E0 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 0,1,2,-1> E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 0,1,3,-1> E0 ## E1 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 0,2,0,-1> E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 0,2,1,-1> E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 0,2,2,-1> E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 0,2,3,-1> E0 ## E2 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 0,3,0,-1> E0 ## E3 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 0,3,1,-1> E0 ## E3 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 0,3,2,-1> E0 ## E3 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 0,3,3,-1> E0 ## E3 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 1,0,2,-1> E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 1,0,3,-1> E1 ## E0 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 1,1,1,-1> E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 1,1,2,-1> E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 1,1,3,-1> E1 ## E1 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 1,2,0,-1> E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 1,2,1,-1> E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 1,2,2,-1> E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 1,2,3,-1> E1 ## E2 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 1,3,0,-1> E1 ## E3 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 1,3,1,-1> E1 ## E3 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 1,3,2,-1> E1 ## E3 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 1,3,3,-1> E1 ## E3 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 2,0,0,-1> E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 2,0,1,-1> E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 2,0,2,-1> E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 2,0,3,-1> E2 ## E0 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 2,1,0,-1> E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 2,1,1,-1> E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 2,1,2,-1> E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 2,1,3,-1> E2 ## E1 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 2,2,0,-1> E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 2,2,1,-1> E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 2,2,2,-1> E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 2,2,3,-1> E2 ## E2 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 2,3,0,-1> E2 ## E3 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 2,3,1,-1> E2 ## E3 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 2,3,2,-1> E2 ## E3 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 2,3,3,-1> E2 ## E3 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 3,0,0,-1> E3 ## E0 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 3,0,1,-1> E3 ## E0 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 3,0,2,-1> E3 ## E0 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 3,0,3,-1> E3 ## E0 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 3,1,0,-1> E3 ## E1 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 3,1,1,-1> E3 ## E1 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 3,1,2,-1> E3 ## E1 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 3,1,3,-1> E3 ## E1 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 3,2,0,-1> E3 ## E2 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 3,2,1,-1> E3 ## E2 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 3,2,2,-1> E3 ## E2 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 3,2,3,-1> E3 ## E2 ## E3; }; \ - struct { detail::_swizzle<3,T,P, V, 3,3,0,-1> E3 ## E3 ## E0; }; \ - struct { detail::_swizzle<3,T,P, V, 3,3,1,-1> E3 ## E3 ## E1; }; \ - struct { detail::_swizzle<3,T,P, V, 3,3,2,-1> E3 ## E3 ## E2; }; \ - struct { detail::_swizzle<3,T,P, V, 3,3,3,-1> E3 ## E3 ## E3; }; +#define _GLM_SWIZZLE4_3_MEMBERS(T, P, V, E0,E1,E2,E3) \ + struct { detail::_swizzle<3, T, P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 0,0,2,-1> E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 0,0,3,-1> E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 0,1,2,-1> E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 0,1,3,-1> E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 0,2,0,-1> E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 0,2,1,-1> E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 0,2,2,-1> E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 0,2,3,-1> E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 0,3,0,-1> E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 0,3,1,-1> E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 0,3,2,-1> E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 0,3,3,-1> E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 1,0,2,-1> E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 1,0,3,-1> E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 1,1,1,-1> E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 1,1,2,-1> E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 1,1,3,-1> E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 1,2,0,-1> E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 1,2,1,-1> E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 1,2,2,-1> E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 1,2,3,-1> E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 1,3,0,-1> E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 1,3,1,-1> E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 1,3,2,-1> E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 1,3,3,-1> E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 2,0,0,-1> E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 2,0,1,-1> E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 2,0,2,-1> E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 2,0,3,-1> E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 2,1,0,-1> E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 2,1,1,-1> E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 2,1,2,-1> E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 2,1,3,-1> E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 2,2,0,-1> E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 2,2,1,-1> E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 2,2,2,-1> E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 2,2,3,-1> E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 2,3,0,-1> E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 2,3,1,-1> E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 2,3,2,-1> E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 2,3,3,-1> E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 3,0,0,-1> E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 3,0,1,-1> E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 3,0,2,-1> E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 3,0,3,-1> E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 3,1,0,-1> E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 3,1,1,-1> E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 3,1,2,-1> E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 3,1,3,-1> E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 3,2,0,-1> E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 3,2,1,-1> E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 3,2,2,-1> E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 3,2,3,-1> E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, P, V, 3,3,0,-1> E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, P, V, 3,3,1,-1> E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, P, V, 3,3,2,-1> E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, P, V, 3,3,3,-1> E3 ## E3 ## E3; }; #define _GLM_SWIZZLE4_4_MEMBERS(T, P, V, E0,E1,E2,E3) \ - struct { detail::_swizzle<4, T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,0,3> E0 ## E0 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,1,3> E0 ## E0 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,2,3> E0 ## E0 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,3,0> E0 ## E0 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,3,1> E0 ## E0 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,3,2> E0 ## E0 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,3,3> E0 ## E0 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,0,3> E0 ## E1 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,1,3> E0 ## E1 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,2,3> E0 ## E1 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,3,0> E0 ## E1 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,3,1> E0 ## E1 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,3,2> E0 ## E1 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,3,3> E0 ## E1 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,0,3> E0 ## E2 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,1,3> E0 ## E2 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,2,3> E0 ## E2 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,3,0> E0 ## E2 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,3,1> E0 ## E2 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,3,2> E0 ## E2 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,3,3> E0 ## E2 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,0,0> E0 ## E3 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,0,1> E0 ## E3 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,0,2> E0 ## E3 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,0,3> E0 ## E3 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,1,0> E0 ## E3 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,1,1> E0 ## E3 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,1,2> E0 ## E3 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,1,3> E0 ## E3 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,2,0> E0 ## E3 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,2,1> E0 ## E3 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,2,2> E0 ## E3 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,2,3> E0 ## E3 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,3,0> E0 ## E3 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,3,1> E0 ## E3 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,3,2> E0 ## E3 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,3,3> E0 ## E3 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,0,3> E1 ## E0 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,1,3> E1 ## E0 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,2,3> E1 ## E0 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,3,0> E1 ## E0 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,3,1> E1 ## E0 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,3,2> E1 ## E0 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,3,3> E1 ## E0 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,0,3> E1 ## E1 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,1,3> E1 ## E1 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,2,3> E1 ## E1 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,3,0> E1 ## E1 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,3,1> E1 ## E1 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,3,2> E1 ## E1 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,3,3> E1 ## E1 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,0,3> E1 ## E2 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,1,3> E1 ## E2 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,2,3> E1 ## E2 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,3,0> E1 ## E2 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,3,1> E1 ## E2 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,3,2> E1 ## E2 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,3,3> E1 ## E2 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,0,0> E1 ## E3 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,0,1> E1 ## E3 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,0,2> E1 ## E3 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,0,3> E1 ## E3 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,1,0> E1 ## E3 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,1,1> E1 ## E3 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,1,2> E1 ## E3 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,1,3> E1 ## E3 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,2,0> E1 ## E3 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,2,1> E1 ## E3 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,2,2> E1 ## E3 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,2,3> E1 ## E3 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,3,0> E1 ## E3 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,3,1> E1 ## E3 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,3,2> E1 ## E3 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,3,3> E1 ## E3 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,0,3> E2 ## E0 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,1,3> E2 ## E0 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,2,3> E2 ## E0 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,3,0> E2 ## E0 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,3,1> E2 ## E0 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,3,2> E2 ## E0 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,3,3> E2 ## E0 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,0,3> E2 ## E1 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,1,3> E2 ## E1 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,2,3> E2 ## E1 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,3,0> E2 ## E1 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,3,1> E2 ## E1 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,3,2> E2 ## E1 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,3,3> E2 ## E1 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,0,3> E2 ## E2 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,1,3> E2 ## E2 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,2,3> E2 ## E2 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,3,0> E2 ## E2 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,3,1> E2 ## E2 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,3,2> E2 ## E2 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,3,3> E2 ## E2 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,0,0> E2 ## E3 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,0,1> E2 ## E3 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,0,2> E2 ## E3 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,0,3> E2 ## E3 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,1,0> E2 ## E3 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,1,1> E2 ## E3 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,1,2> E2 ## E3 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,1,3> E2 ## E3 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,2,0> E2 ## E3 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,2,1> E2 ## E3 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,2,2> E2 ## E3 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,2,3> E2 ## E3 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,3,0> E2 ## E3 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,3,1> E2 ## E3 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,3,2> E2 ## E3 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,3,3> E2 ## E3 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,0,0> E3 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,0,1> E3 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,0,2> E3 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,0,3> E3 ## E0 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,1,0> E3 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,1,1> E3 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,1,2> E3 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,1,3> E3 ## E0 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,2,0> E3 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,2,1> E3 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,2,2> E3 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,2,3> E3 ## E0 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,3,0> E3 ## E0 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,3,1> E3 ## E0 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,3,2> E3 ## E0 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,3,3> E3 ## E0 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,0,0> E3 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,0,1> E3 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,0,2> E3 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,0,3> E3 ## E1 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,1,0> E3 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,1,1> E3 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,1,2> E3 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,1,3> E3 ## E1 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,2,0> E3 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,2,1> E3 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,2,2> E3 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,2,3> E3 ## E1 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,3,0> E3 ## E1 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,3,1> E3 ## E1 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,3,2> E3 ## E1 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,3,3> E3 ## E1 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,0,0> E3 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,0,1> E3 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,0,2> E3 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,0,3> E3 ## E2 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,1,0> E3 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,1,1> E3 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,1,2> E3 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,1,3> E3 ## E2 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,2,0> E3 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,2,1> E3 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,2,2> E3 ## E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,2,3> E3 ## E2 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,3,0> E3 ## E2 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,3,1> E3 ## E2 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,3,2> E3 ## E2 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,3,3> E3 ## E2 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,0,0> E3 ## E3 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,0,1> E3 ## E3 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,0,2> E3 ## E3 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,0,3> E3 ## E3 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,1,0> E3 ## E3 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,1,1> E3 ## E3 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,1,2> E3 ## E3 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,1,3> E3 ## E3 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,2,0> E3 ## E3 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,2,1> E3 ## E3 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,2,2> E3 ## E3 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,2,3> E3 ## E3 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,3,0> E3 ## E3 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,3,1> E3 ## E3 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,3,2> E3 ## E3 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,3,3> E3 ## E3 ## E3 ## E3; }; + struct { detail::_swizzle<4, T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,0,3> E0 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,1,3> E0 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,2,3> E0 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,3,0> E0 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,3,1> E0 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,3,2> E0 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,3,3> E0 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,0,3> E0 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,1,3> E0 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,2,3> E0 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,3,0> E0 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,3,1> E0 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,3,2> E0 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,3,3> E0 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,0,3> E0 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,1,3> E0 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,2,3> E0 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,3,0> E0 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,3,1> E0 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,3,2> E0 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,3,3> E0 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,0,0> E0 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,0,1> E0 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,0,2> E0 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,0,3> E0 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,1,0> E0 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,1,1> E0 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,1,2> E0 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,1,3> E0 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,2,0> E0 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,2,1> E0 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,2,2> E0 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,2,3> E0 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,3,0> E0 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,3,1> E0 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,3,2> E0 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,3,3> E0 ## E3 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,0,3> E1 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,1,3> E1 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,2,3> E1 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,3,0> E1 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,3,1> E1 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,3,2> E1 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,3,3> E1 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,0,3> E1 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,1,3> E1 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,2,3> E1 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,3,0> E1 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,3,1> E1 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,3,2> E1 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,3,3> E1 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,0,3> E1 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,1,3> E1 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,2,3> E1 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,3,0> E1 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,3,1> E1 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,3,2> E1 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,3,3> E1 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,0,0> E1 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,0,1> E1 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,0,2> E1 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,0,3> E1 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,1,0> E1 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,1,1> E1 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,1,2> E1 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,1,3> E1 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,2,0> E1 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,2,1> E1 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,2,2> E1 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,2,3> E1 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,3,0> E1 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,3,1> E1 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,3,2> E1 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,3,3> E1 ## E3 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,0,3> E2 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,1,3> E2 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,2,3> E2 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,3,0> E2 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,3,1> E2 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,3,2> E2 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,3,3> E2 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,0,3> E2 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,1,3> E2 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,2,3> E2 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,3,0> E2 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,3,1> E2 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,3,2> E2 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,3,3> E2 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,0,3> E2 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,1,3> E2 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,2,3> E2 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,3,0> E2 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,3,1> E2 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,3,2> E2 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,3,3> E2 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,0,0> E2 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,0,1> E2 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,0,2> E2 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,0,3> E2 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,1,0> E2 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,1,1> E2 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,1,2> E2 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,1,3> E2 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,2,0> E2 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,2,1> E2 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,2,2> E2 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,2,3> E2 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,3,0> E2 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,3,1> E2 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,3,2> E2 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,3,3> E2 ## E3 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,0,0> E3 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,0,1> E3 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,0,2> E3 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,0,3> E3 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,1,0> E3 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,1,1> E3 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,1,2> E3 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,1,3> E3 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,2,0> E3 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,2,1> E3 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,2,2> E3 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,2,3> E3 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,3,0> E3 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,3,1> E3 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,3,2> E3 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,3,3> E3 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,0,0> E3 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,0,1> E3 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,0,2> E3 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,0,3> E3 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,1,0> E3 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,1,1> E3 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,1,2> E3 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,1,3> E3 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,2,0> E3 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,2,1> E3 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,2,2> E3 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,2,3> E3 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,3,0> E3 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,3,1> E3 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,3,2> E3 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,3,3> E3 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,0,0> E3 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,0,1> E3 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,0,2> E3 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,0,3> E3 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,1,0> E3 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,1,1> E3 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,1,2> E3 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,1,3> E3 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,2,0> E3 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,2,1> E3 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,2,2> E3 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,2,3> E3 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,3,0> E3 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,3,1> E3 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,3,2> E3 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,3,3> E3 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,0,0> E3 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,0,1> E3 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,0,2> E3 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,0,3> E3 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,1,0> E3 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,1,1> E3 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,1,2> E3 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,1,3> E3 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,2,0> E3 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,2,1> E3 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,2,2> E3 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,2,3> E3 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,3,0> E3 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,3,1> E3 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,3,2> E3 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,3,3> E3 ## E3 ## E3 ## E3; }; diff --git a/common/glm/glm/detail/_swizzle_func.hpp b/common/glm/glm/detail/_swizzle_func.hpp index 7d725e10a..4b37edbbf 100644 --- a/common/glm/glm/detail/_swizzle_func.hpp +++ b/common/glm/glm/detail/_swizzle_func.hpp @@ -1,34 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////////// -/// OpenGL Mathematics (glm.g-truc.net) -/// -/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) -/// Permission is hereby granted, free of charge, to any person obtaining a copy -/// of this software and associated documentation files (the "Software"), to deal -/// in the Software without restriction, including without limitation the rights -/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/// copies of the Software, and to permit persons to whom the Software is -/// furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// Restrictions: -/// By making use of the Software for military purposes, you choose to make -/// a Bunny unhappy. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. -/// /// @ref core /// @file glm/detail/_swizzle_func.hpp -/// @date 2011-10-16 / 2011-10-16 -/// @author Christophe Riccio -/////////////////////////////////////////////////////////////////////////////////// #pragma once diff --git a/common/glm/glm/detail/_vectorize.hpp b/common/glm/glm/detail/_vectorize.hpp index 8eea6b871..a08ed34df 100644 --- a/common/glm/glm/detail/_vectorize.hpp +++ b/common/glm/glm/detail/_vectorize.hpp @@ -1,34 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////////// -/// OpenGL Mathematics (glm.g-truc.net) -/// -/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) -/// Permission is hereby granted, free of charge, to any person obtaining a copy -/// of this software and associated documentation files (the "Software"), to deal -/// in the Software without restriction, including without limitation the rights -/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/// copies of the Software, and to permit persons to whom the Software is -/// furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// Restrictions: -/// By making use of the Software for military purposes, you choose to make -/// a Bunny unhappy. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. -/// /// @ref core /// @file glm/detail/_vectorize.hpp -/// @date 2011-10-14 / 2011-10-14 -/// @author Christophe Riccio -/////////////////////////////////////////////////////////////////////////////////// #pragma once diff --git a/common/glm/glm/detail/dummy.cpp b/common/glm/glm/detail/dummy.cpp index c7ef99edb..a519a6dc2 100644 --- a/common/glm/glm/detail/dummy.cpp +++ b/common/glm/glm/detail/dummy.cpp @@ -1,40 +1,13 @@ -/////////////////////////////////////////////////////////////////////////////////// -/// OpenGL Mathematics (glm.g-truc.net) -/// -/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) -/// Permission is hereby granted, free of charge, to any person obtaining a copy -/// of this software and associated documentation files (the "Software"), to deal -/// in the Software without restriction, including without limitation the rights -/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/// copies of the Software, and to permit persons to whom the Software is -/// furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// Restrictions: -/// By making use of the Software for military purposes, you choose to make -/// a Bunny unhappy. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. -/// /// @ref core /// @file glm/core/dummy.cpp -/// @date 2011-01-19 / 2011-06-15 -/// @author Christophe Riccio /// /// GLM is a header only library. There is nothing to compile. /// dummy.cpp exist only a wordaround for CMake file. -/////////////////////////////////////////////////////////////////////////////////// +/* #define GLM_MESSAGES -#include "../glm.hpp" +#include +#include #include struct material @@ -148,6 +121,8 @@ struct intersection glm::vec4 position; glm::vec3 normal; }; +*/ + /* // Sample 4 @@ -190,7 +165,7 @@ glm::vec3 lighting } */ - +/* template class vecType> T normalizeDotA(vecType const & x, vecType const & y) { @@ -210,13 +185,23 @@ typename vecType::value_type normalizeDotC(vecType const & a, vecType const & b) { return glm::dot(a, b) * glm::inversesqrt(glm::dot(a, a) * glm::dot(b, b)); } - +*/ int main() { - glm::vec4 v(1); - float a = normalizeDotA(v, v); - float b = normalizeDotB(v, v); - float c = normalizeDotC(v, v); +/* + glm::vec1 o(1); + glm::vec2 a(1); + glm::vec3 b(1); + glm::vec4 c(1); + glm::quat q; + glm::dualquat p; + + glm::mat4 m(1); + + float a0 = normalizeDotA(a, a); + float b0 = normalizeDotB(b, b); + float c0 = normalizeDotC(c, c); +*/ return 0; } diff --git a/common/glm/glm/detail/func_common.hpp b/common/glm/glm/detail/func_common.hpp index 0cea49426..871fed6c4 100644 --- a/common/glm/glm/detail/func_common.hpp +++ b/common/glm/glm/detail/func_common.hpp @@ -1,33 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////////// -/// OpenGL Mathematics (glm.g-truc.net) -/// -/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) -/// Permission is hereby granted, free of charge, to any person obtaining a copy -/// of this software and associated documentation files (the "Software"), to deal -/// in the Software without restriction, including without limitation the rights -/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/// copies of the Software, and to permit persons to whom the Software is -/// furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// Restrictions: -/// By making use of the Software for military purposes, you choose to make -/// a Bunny unhappy. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. -/// /// @ref core /// @file glm/detail/func_common.hpp -/// @date 2008-03-08 / 2010-01-26 -/// @author Christophe Riccio /// /// @see GLSL 4.20.8 specification, section 8.3 Common Functions /// @@ -35,7 +7,6 @@ /// @ingroup core /// /// These all operate component-wise. The description is per component. -/////////////////////////////////////////////////////////////////////////////////// #pragma once diff --git a/common/glm/glm/detail/func_common.inl b/common/glm/glm/detail/func_common.inl index e3cd4e221..327b058a2 100644 --- a/common/glm/glm/detail/func_common.inl +++ b/common/glm/glm/detail/func_common.inl @@ -1,34 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////////// -/// OpenGL Mathematics (glm.g-truc.net) -/// -/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) -/// Permission is hereby granted, free of charge, to any person obtaining a copy -/// of this software and associated documentation files (the "Software"), to deal -/// in the Software without restriction, including without limitation the rights -/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/// copies of the Software, and to permit persons to whom the Software is -/// furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// Restrictions: -/// By making use of the Software for military purposes, you choose to make -/// a Bunny unhappy. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. -/// /// @ref core /// @file glm/detail/func_common.inl -/// @date 2008-08-03 / 2011-06-15 -/// @author Christophe Riccio -/////////////////////////////////////////////////////////////////////////////////// #include "func_vector_relational.hpp" #include "type_vec2.hpp" @@ -37,142 +8,24 @@ #include "_vectorize.hpp" #include -namespace glm{ -namespace detail +namespace glm { - template - struct compute_abs - {}; - - template - struct compute_abs + // min + template + GLM_FUNC_QUALIFIER genType min(genType x, genType y) { - GLM_FUNC_QUALIFIER static genFIType call(genFIType x) - { - GLM_STATIC_ASSERT( - std::numeric_limits::is_iec559 || std::numeric_limits::is_signed, - "'abs' only accept floating-point and integer scalar or vector inputs"); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_UNRESTRICTED_GENTYPE, "'min' only accept floating-point or integer inputs"); + return x < y ? x : y; + } - return x >= genFIType(0) ? x : -x; - // TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff; - } - }; - - template - struct compute_abs + // max + template + GLM_FUNC_QUALIFIER genType max(genType x, genType y) { - GLM_FUNC_QUALIFIER static genFIType call(genFIType x) - { - GLM_STATIC_ASSERT( - !std::numeric_limits::is_signed && std::numeric_limits::is_integer, - "'abs' only accept floating-point and integer scalar or vector inputs"); - return x; - } - }; + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_UNRESTRICTED_GENTYPE, "'max' only accept floating-point or integer inputs"); - template class vecType> - struct compute_mix_vector - { - GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y, vecType const & a) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'mix' only accept floating-point inputs for the interpolator a"); - - return vecType(vecType(x) + a * vecType(y - x)); - } - }; - - template class vecType> - struct compute_mix_vector - { - GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y, vecType const & a) - { - vecType Result(uninitialize); - for(detail::component_count_t i = 0; i < detail::component_count(x); ++i) - Result[i] = a[i] ? y[i] : x[i]; - return Result; - } - }; - - template class vecType> - struct compute_mix_scalar - { - GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y, U const & a) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'mix' only accept floating-point inputs for the interpolator a"); - - return vecType(vecType(x) + a * vecType(y - x)); - } - }; - - template class vecType> - struct compute_mix_scalar - { - GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y, bool const & a) - { - return a ? y : x; - } - }; - - template - struct compute_mix - { - GLM_FUNC_QUALIFIER static T call(T const & x, T const & y, U const & a) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'mix' only accept floating-point inputs for the interpolator a"); - - return static_cast(static_cast(x) + a * static_cast(y - x)); - } - }; - - template - struct compute_mix - { - GLM_FUNC_QUALIFIER static T call(T const & x, T const & y, bool const & a) - { - return a ? y : x; - } - }; - - template class vecType, bool isFloat = true, bool isSigned = true> - struct compute_sign - { - GLM_FUNC_QUALIFIER static vecType call(vecType const & x) - { - return vecType(glm::lessThan(vecType(0), x)) - vecType(glm::lessThan(x, vecType(0))); - } - }; - - template class vecType> - struct compute_sign - { - GLM_FUNC_QUALIFIER static vecType call(vecType const & x) - { - return vecType(glm::greaterThan(x , vecType(0))); - } - }; - - template class vecType> - struct compute_sign - { - GLM_FUNC_QUALIFIER static vecType call(vecType const & x) - { - T const Shift(static_cast(sizeof(T) * 8 - 1)); - vecType const y(vecType::type, P>(-x) >> typename make_unsigned::type(Shift)); - - return (x >> Shift) | y; - } - }; - - template class vecType, typename genType, bool isFloat = true> - struct compute_mod - { - GLM_FUNC_QUALIFIER static vecType call(vecType const & a, genType const & b) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'mod' only accept floating-point inputs. Include for integer inputs."); - return a - b * floor(a / b); - } - }; -}//namespace detail + return x > y ? x : y; + } // abs template <> @@ -182,67 +35,6 @@ namespace detail return (x ^ y) - y; } - template - GLM_FUNC_QUALIFIER genFIType abs(genFIType x) - { - return detail::compute_abs::is_signed>::call(x); - } - - template class vecType> - GLM_FUNC_QUALIFIER vecType abs(vecType const & x) - { - return detail::functor1::call(abs, x); - } - - // sign - // fast and works for any type - template - GLM_FUNC_QUALIFIER genFIType sign(genFIType x) - { - GLM_STATIC_ASSERT( - std::numeric_limits::is_iec559 || (std::numeric_limits::is_signed && std::numeric_limits::is_integer), - "'sign' only accept signed inputs"); - - return detail::compute_sign::is_iec559>::call(tvec1(x)).x; - } - - template class vecType> - GLM_FUNC_QUALIFIER vecType sign(vecType const & x) - { - GLM_STATIC_ASSERT( - std::numeric_limits::is_iec559 || (std::numeric_limits::is_signed && std::numeric_limits::is_integer), - "'sign' only accept signed inputs"); - - return detail::compute_sign::is_iec559>::call(x); - } - - // floor - using ::std::floor; - template class vecType> - GLM_FUNC_QUALIFIER vecType floor(vecType const & x) - { - return detail::functor1::call(floor, x); - } - - // trunc -# if GLM_HAS_CXX11_STL - using ::std::trunc; -# else - template - GLM_FUNC_QUALIFIER genType trunc(genType x) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'trunc' only accept floating-point inputs"); - - return x < static_cast(0) ? -floor(-x) : floor(x); - } -# endif - - template class vecType> - GLM_FUNC_QUALIFIER vecType trunc(vecType const & x) - { - return detail::functor1::call(trunc, x); - } - // round # if GLM_HAS_CXX11_STL using ::std::round; @@ -256,10 +48,318 @@ namespace detail } # endif + // trunc +# if GLM_HAS_CXX11_STL + using ::std::trunc; +# else + template + GLM_FUNC_QUALIFIER genType trunc(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'trunc' only accept floating-point inputs"); + + return x < static_cast(0) ? -std::floor(-x) : std::floor(x); + } +# endif + +}//namespace glm + +namespace glm{ +namespace detail +{ + template + struct compute_abs + {}; + + template + struct compute_abs + { + GLM_FUNC_QUALIFIER static genFIType call(genFIType x) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559 || std::numeric_limits::is_signed || GLM_UNRESTRICTED_GENTYPE, + "'abs' only accept floating-point and integer scalar or vector inputs"); + + return x >= genFIType(0) ? x : -x; + // TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff; + } + }; + + #if GLM_COMPILER & GLM_COMPILER_CUDA + template <> + struct compute_abs + { + GLM_FUNC_QUALIFIER static float call(float x) + { + return fabsf(x); + } + }; + #endif + + template + struct compute_abs + { + GLM_FUNC_QUALIFIER static genFIType call(genFIType x) + { + GLM_STATIC_ASSERT( + (!std::numeric_limits::is_signed && std::numeric_limits::is_integer) || GLM_UNRESTRICTED_GENTYPE, + "'abs' only accept floating-point and integer scalar or vector inputs"); + return x; + } + }; + + template class vecType, bool Aligned> + struct compute_abs_vector + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return detail::functor1::call(abs, x); + } + }; + + template class vecType, bool Aligned> + struct compute_mix_vector + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y, vecType const & a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a"); + + return vecType(vecType(x) + a * vecType(y - x)); + } + }; + + template class vecType, bool Aligned> + struct compute_mix_vector + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y, vecType const & a) + { + vecType Result(uninitialize); + for(length_t i = 0; i < x.length(); ++i) + Result[i] = a[i] ? y[i] : x[i]; + return Result; + } + }; + + template class vecType, bool Aligned> + struct compute_mix_scalar + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y, U const & a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a"); + + return vecType(vecType(x) + a * vecType(y - x)); + } + }; + + template class vecType, bool Aligned> + struct compute_mix_scalar + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y, bool const & a) + { + return a ? y : x; + } + }; + + template + struct compute_mix + { + GLM_FUNC_QUALIFIER static T call(T const & x, T const & y, U const & a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a"); + + return static_cast(static_cast(x) + a * static_cast(y - x)); + } + }; + + template + struct compute_mix + { + GLM_FUNC_QUALIFIER static T call(T const & x, T const & y, bool const & a) + { + return a ? y : x; + } + }; + + template class vecType, bool isFloat, bool Aligned> + struct compute_sign + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return vecType(glm::lessThan(vecType(0), x)) - vecType(glm::lessThan(x, vecType(0))); + } + }; + +# if GLM_ARCH == GLM_ARCH_X86 + template class vecType, bool Aligned> + struct compute_sign + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + T const Shift(static_cast(sizeof(T) * 8 - 1)); + vecType const y(vecType::type, P>(-x) >> typename make_unsigned::type(Shift)); + + return (x >> Shift) | y; + } + }; +# endif + + template class vecType, bool Aligned> + struct compute_floor + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return detail::functor1::call(std::floor, x); + } + }; + + template class vecType, bool Aligned> + struct compute_ceil + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return detail::functor1::call(std::ceil, x); + } + }; + + template class vecType, bool Aligned> + struct compute_fract + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return x - floor(x); + } + }; + + template class vecType, bool Aligned> + struct compute_trunc + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return detail::functor1::call(trunc, x); + } + }; + + template class vecType, bool Aligned> + struct compute_round + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return detail::functor1::call(round, x); + } + }; + + template class vecType, bool Aligned> + struct compute_mod + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & a, vecType const & b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'mod' only accept floating-point inputs. Include for integer inputs."); + return a - b * floor(a / b); + } + }; + + template class vecType, bool Aligned> + struct compute_min_vector + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y) + { + return detail::functor2::call(min, x, y); + } + }; + + template class vecType, bool Aligned> + struct compute_max_vector + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y) + { + return detail::functor2::call(max, x, y); + } + }; + + template class vecType, bool Aligned> + struct compute_clamp_vector + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & minVal, vecType const & maxVal) + { + return min(max(x, minVal), maxVal); + } + }; + + template class vecType, bool Aligned> + struct compute_step_vector + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & edge, vecType const & x) + { + return mix(vecType(1), vecType(0), glm::lessThan(x, edge)); + } + }; + + template class vecType, bool Aligned> + struct compute_smoothstep_vector + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & edge0, vecType const & edge1, vecType const & x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_UNRESTRICTED_GENTYPE, "'step' only accept floating-point inputs"); + vecType const tmp(clamp((x - edge0) / (edge1 - edge0), static_cast(0), static_cast(1))); + return tmp * tmp * (static_cast(3) - static_cast(2) * tmp); + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER genFIType abs(genFIType x) + { + return detail::compute_abs::is_signed>::call(x); + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType abs(vecType const & x) + { + return detail::compute_abs_vector::value>::call(x); + } + + // sign + // fast and works for any type + template + GLM_FUNC_QUALIFIER genFIType sign(genFIType x) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559 || (std::numeric_limits::is_signed && std::numeric_limits::is_integer), + "'sign' only accept signed inputs"); + + return detail::compute_sign::is_iec559, highp>::call(tvec1(x)).x; + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType sign(vecType const & x) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559 || (std::numeric_limits::is_signed && std::numeric_limits::is_integer), + "'sign' only accept signed inputs"); + + return detail::compute_sign::is_iec559, detail::is_aligned

::value>::call(x); + } + + // floor + using ::std::floor; + template class vecType> + GLM_FUNC_QUALIFIER vecType floor(vecType const & x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'floor' only accept floating-point inputs."); + return detail::compute_floor::value>::call(x); + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType trunc(vecType const & x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'trunc' only accept floating-point inputs"); + return detail::compute_trunc::value>::call(x); + } + template class vecType> GLM_FUNC_QUALIFIER vecType round(vecType const & x) { - return detail::functor1::call(round, x); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'round' only accept floating-point inputs"); + return detail::compute_round::value>::call(x); } /* @@ -308,6 +408,7 @@ namespace detail template class vecType> GLM_FUNC_QUALIFIER vecType roundEven(vecType const & x) { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'roundEven' only accept floating-point inputs"); return detail::functor1::call(roundEven, x); } @@ -316,41 +417,47 @@ namespace detail template class vecType> GLM_FUNC_QUALIFIER vecType ceil(vecType const & x) { - return detail::functor1::call(ceil, x); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'ceil' only accept floating-point inputs"); + return detail::compute_ceil::value>::call(x); } // fract template GLM_FUNC_QUALIFIER genType fract(genType x) { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fract' only accept floating-point inputs"); - return fract(tvec1(x)).x; } template class vecType> GLM_FUNC_QUALIFIER vecType fract(vecType const & x) { - return x - floor(x); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fract' only accept floating-point inputs"); + return detail::compute_fract::value>::call(x); } // mod template GLM_FUNC_QUALIFIER genType mod(genType x, genType y) { - return mod(tvec1(x), y).x; +# if GLM_COMPILER & GLM_COMPILER_CUDA + // Another Cuda compiler bug https://github.com/g-truc/glm/issues/530 + tvec1 Result(mod(tvec1(x), y)); + return Result.x; +# else + return mod(tvec1(x), y).x; +# endif } template class vecType> GLM_FUNC_QUALIFIER vecType mod(vecType const & x, T y) { - return detail::compute_mod::is_iec559>::call(x, y); + return detail::compute_mod::value>::call(x, vecType(y)); } template class vecType> GLM_FUNC_QUALIFIER vecType mod(vecType const & x, vecType const & y) { - return detail::compute_mod, std::numeric_limits::is_iec559>::call(x, y); + return detail::compute_mod::value>::call(x, y); } // modf @@ -358,7 +465,6 @@ namespace detail GLM_FUNC_QUALIFIER genType modf(genType x, genType & i) { GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'modf' only accept floating-point inputs"); - return std::modf(x, &i); } @@ -405,70 +511,53 @@ namespace detail //CHAR_BIT - 1))); // min - template - GLM_FUNC_QUALIFIER genType min(genType x, genType y) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'min' only accept floating-point or integer inputs"); - - return x < y ? x : y; - } - template class vecType> GLM_FUNC_QUALIFIER vecType min(vecType const & a, T b) { - return detail::functor2_vec_sca::call(min, a, b); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_UNRESTRICTED_GENTYPE, "'min' only accept floating-point inputs for the interpolator a"); + return detail::compute_min_vector::value>::call(a, vecType(b)); } template class vecType> GLM_FUNC_QUALIFIER vecType min(vecType const & a, vecType const & b) { - return detail::functor2::call(min, a, b); + return detail::compute_min_vector::value>::call(a, b); } // max - template - GLM_FUNC_QUALIFIER genType max(genType x, genType y) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'max' only accept floating-point or integer inputs"); - - return x > y ? x : y; - } - template class vecType> GLM_FUNC_QUALIFIER vecType max(vecType const & a, T b) { - return detail::functor2_vec_sca::call(max, a, b); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_UNRESTRICTED_GENTYPE, "'max' only accept floating-point inputs for the interpolator a"); + return detail::compute_max_vector::value>::call(a, vecType(b)); } template class vecType> GLM_FUNC_QUALIFIER vecType max(vecType const & a, vecType const & b) { - return detail::functor2::call(max, a, b); + return detail::compute_max_vector::value>::call(a, b); } // clamp template GLM_FUNC_QUALIFIER genType clamp(genType x, genType minVal, genType maxVal) { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'clamp' only accept floating-point or integer inputs"); - + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_UNRESTRICTED_GENTYPE, "'clamp' only accept floating-point or integer inputs"); return min(max(x, minVal), maxVal); } template class vecType> GLM_FUNC_QUALIFIER vecType clamp(vecType const & x, T minVal, T maxVal) { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'clamp' only accept floating-point or integer inputs"); - - return min(max(x, minVal), maxVal); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_UNRESTRICTED_GENTYPE, "'clamp' only accept floating-point or integer inputs"); + return detail::compute_clamp_vector::value>::call(x, vecType(minVal), vecType(maxVal)); } template class vecType> GLM_FUNC_QUALIFIER vecType clamp(vecType const & x, vecType const & minVal, vecType const & maxVal) { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'clamp' only accept floating-point or integer inputs"); - - return min(max(x, minVal), maxVal); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_UNRESTRICTED_GENTYPE, "'clamp' only accept floating-point or integer inputs"); + return detail::compute_clamp_vector::value>::call(x, minVal, maxVal); } template @@ -480,13 +569,13 @@ namespace detail template class vecType> GLM_FUNC_QUALIFIER vecType mix(vecType const & x, vecType const & y, U a) { - return detail::compute_mix_scalar::call(x, y, a); + return detail::compute_mix_scalar::value>::call(x, y, a); } template class vecType> GLM_FUNC_QUALIFIER vecType mix(vecType const & x, vecType const & y, vecType const & a) { - return detail::compute_mix_vector::call(x, y, a); + return detail::compute_mix_vector::value>::call(x, y, a); } // step @@ -499,22 +588,20 @@ namespace detail template