1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-06-03 22:57:45 +00:00

Merge branch 'develop' of https://github.com/SapphireMordred/Sapphire into social_implementation

# Conflicts:
#	sql/update.sql
#	src/common/Common.h
#	src/common/Network/PacketDef/Ipcs.h
#	src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp
This commit is contained in:
Tahir Akhlaq 2018-08-17 13:36:49 +01:00
commit 42d2e5e2fa
185 changed files with 18590 additions and 5782 deletions

9
.gitignore vendored
View file

@ -117,4 +117,11 @@ src/servers/Scripts/*/ScriptLoader.cpp
# cotire generated files/folders
cotire/
*_cotire.cmake
*_cotire.cmake
*objects.txt
*exports.def
# doxygen output folder
doxygen/generated/
doxygen/*.tmp

View file

@ -13,32 +13,14 @@ Sapphire requires the following software:
| *Name* | *Windows* | *Linux* |
| ------ | --------- | ------- |
| CMake 2.6+ and C++14 capable compiler | [Visual Studio 2017](https://www.visualstudio.com/) | `gcc 4.9` and `g++ 4.9` or newer |
| CMake 3.0.2+ and C++14 capable compiler | [Visual Studio 2017](https://www.visualstudio.com/) | `gcc 4.9` and `g++ 4.9` or newer |
| Boost 1.63.0 | [Win32 precompiled binaries](https://sourceforge.net/projects/boost/files/boost-binaries/1.63.0/boost_1_63_0-msvc-14.0-32.exe/download) | Boost libraries from your distribution's package manager |
| MySQL Server 5.7 | [Official Site](https://dev.mysql.com/downloads/mysql/) | MySQL server from your distribution's package manager |
**Windows**
Set the environment variables ``BOOST_ROOT_DIR`` and ``BOOST_LIB_DIR`` to ``[boost main folder]`` and ``[boost main folder]/lib32-msvc-14.0`` respectively **or** copy your boost installation into the project's ``src/lib`` folder.
Visual Studio 2017 users: open `Visual Studio Installer` and ensure `Individual Components > SDKs, libraries, and frameworks > Windows Universal C Runtime` is installed. You may also need to install `Individual Components > Compilers, build tools, and runtimes > VC++ 2015.3 v140 toolset for desktop (x86, 64)`.
To enable [Edit and Continue](https://msdn.microsoft.com/en-us/library/esaeyddf.aspx) ensure you define `-DCMAKE_BUILD_TYPE="Debug"` when generating with CMake.
If you installed CMake outside of Visual Studio and have it in your `PATH` environment variable, navigate to Sapphire folder and `cmake -DCMAKE_BUILD_TYPE="Debug" && cmake --build .`.
Otherwise:
* In *Visual Studio 2017*: Open the project via ``File`` > ``Open`` > ``Folder`` and wait, till CMake automatically finishes cache generation. Right click any CMakeLists.txt and select build to build a application.
To configure debug startup parameters, select ``Debug and Launch settings``, the application you want to set up parameters for, and add a ``args`` json array containing your launch parameters in ``configurations``.
If Visual Studio fails to generate a CMake Cache or does not show options to build, make sure that the newest version of it is installed and all environment variables are set correctly. Keep in mind that generating a cache can take a while on some machines.
The solution `Sapphire.sln` is also generated in the main Sapphire folder.
**Linux**
`cmake . -DSAPPHIRE_BOOST_VER="your.boost.ver" && make -j JOBS` where `JOBS` is number of cores on your system.
`-j JOBS` can be omitted if your system lacks resources (spoiler: your system probably lacks resources if running on 1GB RAM or lower, or if the build fails due to being out of memory)
Please check the [wiki](https://github.com/SapphireMordred/Sapphire/wiki) for detailed installation/build instructions for your OS.
## Links
* [Sapphire on YouTube](https://www.youtube.com/channel/UCJKYuovoGsq7PxSAfrNJKbw)
Final Fantasy XIV © 2010-2017 SQUARE ENIX CO., LTD. All Rights Reserved. We are not affiliated with SQUARE ENIX CO., LTD. in any way.
Final Fantasy XIV © 2010-2018 SQUARE ENIX CO., LTD. All Rights Reserved. We are not affiliated with SQUARE ENIX CO., LTD. in any way.

View file

@ -0,0 +1,23 @@
[Database]
Host = 127.0.0.1
Port = 3306
Database = sapphire
Username = root
Password =
SyncThreads = 2
AsyncThreads = 2
[GlobalParameters]
ServerSecret = default
DataPath = C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack
[GlobalNetwork]
; Values definining how Users and other servers will access - these have to be set to your public IP when running a public server
ZoneHost = 127.0.0.1
ZonePort = 54992
LobbyHost = 127.0.0.1
LobbyPort = 54994
RestHost = 127.0.0.1
RestPort = 80

View file

@ -0,0 +1,8 @@
[Lobby]
WorldID = 67
AllowNoSessionConnect = false
WorldName = Sapphire
[LobbyNetwork]
ListenIp = 0.0.0.0
ListenPort = 54994

View file

@ -0,0 +1,6 @@
[CharacterCreation]
DefaultGMRank = 255
[RestNetwork]
ListenIp = 0.0.0.0
ListenPort = 80

View file

@ -1,34 +0,0 @@
<Settings>
<General>
<!-- Port the lobby server accepts client connections on -->
<ListenPort>54994</ListenPort>
<AuthPort>54998</AuthPort>
<!-- Ip the lobby server listens on -->
<ListenIp>127.0.0.1</ListenIp>
<!-- IP of the world server -->
<ZoneIp>127.0.0.1</ZoneIp>
<!-- Port the world server listens for clients -->
<ZonePort>54992</ZonePort>
<!-- Address to connect to the rest server -->
<RestHost>127.0.0.1:80</RestHost>
<!-- Secret for server authentication -->
<ServerSecret>default</ServerSecret>
<!-- Connection settings for the mysql db -->
<Mysql>
<Host>127.0.0.1</Host>
<Port>3306</Port>
<Username>root</Username>
<Pass></Pass>
<Database>sapphire</Database>
</Mysql>
</General>
<Parameters>
<!-- Do not disconnect players without a session - this should be definitely disabled unless you are testing on a PS4 -->
<AllowNoSessionConnect>false</AllowNoSessionConnect>
<!-- The ID of the Sapphire world - this is what the game determines your datacenter with, check world.exh -->
<WorldID>67</WorldID>
<!-- The name of the world -->
<!-- TODO: Allow multiple world servers -->
<WorldName>Sapphire</WorldName>
</Parameters>
</Settings>

View file

@ -1,32 +0,0 @@
<Settings>
<General>
<!-- Port the lobby server accepts client connections on -->
<ListenPort>54994</ListenPort>
<AuthPort>54998</AuthPort>
<!-- Ip the lobby server listens on -->
<ListenIp>127.0.0.1</ListenIp>
<!-- Path of FFXIV dat files -->
<DataPath>C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack</DataPath>
<!-- <DataPath>/opt/sapphire_3_15_0/bin/sqpack</DataPath> -->
<!-- IP of the lobby server -->
<LobbyHost>127.0.0.1</LobbyHost>
<!-- IP of the frontier server -->
<FrontierHost>127.0.0.1</FrontierHost>
<!-- Secret used for server auth - you *must* change this for public servers -->
<ServerSecret>default</ServerSecret>
<!-- Web server port -->
<HttpPort>80</HttpPort>
<Mysql>
<Host>127.0.0.1</Host>
<Port>3306</Port>
<Username>root</Username>
<Pass></Pass>
<Database>sapphire</Database>
</Mysql>
</General>
<Parameters>
<!-- GM Rank for newly created characters - should be changed to 0 for public servers -->
<DefaultGMRank>255</DefaultGMRank>
</Parameters>
</Settings>

View file

@ -1,45 +0,0 @@
<Settings>
<General>
<!-- Port the zone server accepts game conenctions on -->
<ListenPort>54992</ListenPort>
<!-- Ip the zone server conenctions on -->
<ListenIp>127.0.0.1</ListenIp>
<!-- Path of FFXIV dat files -->
<DataPath>C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack</DataPath>
<Scripts>
<!-- where compiled scripts are placed -->
<Path>./compiledscripts/</Path>
<CachePath>./cache/</CachePath>
<HotSwap>
<Enabled>true</Enabled>
<ScriptsDir>../scripts/native/</ScriptsDir>
<BuildDir>../cmake-build-debug/</BuildDir>
<BuildCmd>cmake --build %1% --target %2%</BuildCmd>
</HotSwap>
</Scripts>
<!-- Path of Chai script files -->
<ScriptPath>./compiledscripts/</ScriptPath>
<!-- Connection settings for the mysql db -->
<Mysql>
<Host>127.0.0.1</Host>
<Port>3306</Port>
<Username>root</Username>
<Pass></Pass>
<Database>sapphire</Database>
<SyncThreads>2</SyncThreads>
<AsyncThreads>2</AsyncThreads>
</Mysql>
</General>
<Parameters>
<!-- Messages players see upon logging in - These *must* be smaller than 307 characters -->
<MotDArray>
<MotD>&lt;&lt;&lt;Welcome to Sapphire&gt;&gt;&gt;</MotD>
<MotD>This is a very good server</MotD>
<MotD>You can change these messages by editing MotDArray in config/settings_zone.xml</MotD>
</MotDArray>
</Parameters>
</Settings>

View file

@ -0,0 +1,18 @@
[Scripts]
; where compiled script modules are located
Path = ./compiledscripts/
; relative to Path, where we copy and load modules from
CachePath = ./cache/
; whether we should detect changes to script modules and reload them
HotSwap = true
[Network]
DisconnectTimeout = 20
[ZoneNetwork]
ListenIp = 0.0.0.0
ListenPort = 54992
[General]
; Sent on login - each line must be shorter than 307 characters, split lines with ';'
MotD = Welcome to Sapphire!;This is a very good server;You can change these messages by editing General.MotD in config/zone.ini

View file

@ -139,11 +139,25 @@ p.pageSubTitle{
}
.commit-history {
padding-left: 20px;
padding: 0;
list-style: none;
margin: 0 -15px 0 -15px;
}
.commit-history li a {
.commit-history > li {
}
.commit-history > li:nth-child(odd) {
background: #444;
}
.commit-history> li > a {
color: #fff;
padding: 5px 20px;
display: block;
font-size: 11px;
line-height: 12px;
}
.commit-history li a:hover {

View file

@ -95,7 +95,6 @@
.s-login-btn {
width: 150px;
background: #0e6bc9;
right: -7px; /* ugh. refer to padding-left on input above - more bounding box issues... */
position: relative;
}
@ -153,7 +152,7 @@ h2.text-center{
.s-link-badge-wrapper {
clear: both;
padding: 0 5px;
}
.s-link-badge {
@ -166,12 +165,10 @@ h2.text-center{
margin-top: 25px;
color: white;
border-bottom: 3px solid #43348D;
margin-bottom: 15px;
}
.s-link-badge-discord {
background: #7082E1 url("../img/fa-discord-icon.png") 10px 7px no-repeat;
margin-right: 60px; /* Ideally we'd just use pull-right with the last col-xs-5 but IE7 bounding box render??? */
}
.s-link-badge-github {

View file

@ -18,11 +18,11 @@
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
try{
try {
var response = readBody(xhr);
var parsed = JSON.parse(response);
window.external.Boot(parsed.sId, parsed.lobbyHost, parsed.frontierHost);
}catch(err){
} catch(err) {
document.getElementById("Error").innerHTML = "User creation failed.";
}
}
@ -51,11 +51,14 @@
<a href="https://discord.gg/KfrZCkx" class="s-link-badge s-link-badge-discord col-xs-5">
Join us on Discord!
</a>
<a href="https://github.com/SapphireMordred/Sapphire" class="s-link-badge s-link-badge-github col-xs-5 pull-left">
<a href="https://github.com/SapphireMordred/Sapphire" class="s-link-badge s-link-badge-github col-xs-5 pull-right">
Our Github repository
</a>
</div>
<h2>Github stuff here soon!</h2>
<h2>Recent Activity</h2>
<ul id="commit-log" class="commit-history">
</ul>
</div>
<div class="s-full-split s-right-half col-xs-5">
<div class="s-logo">
@ -94,6 +97,26 @@
$(function() {
$('[autofocus]:not(:focus)').eq(0).focus();
});
fetch( "https://api.github.com/repos/SapphireMordred/Sapphire/events" ).then( function( resp ) {
return resp.json();
}).then( function( data ) {
data = data.filter( function( e ) {
return e.type == "PushEvent";
});
let commitContainer = document.getElementById( 'commit-log' );
for ( var evnt of data ) {
for ( var commit of evnt.payload.commits ) {
let e = document.createElement( 'li' );
e.innerHTML = '<a href="https://github.com/SapphireMordred/Sapphire/commit/' + commit.sha + '">' + commit.message + '</a>';
commitContainer.appendChild( e );
}
}
});
</script>
</body>

View file

@ -18,11 +18,11 @@
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
try{
try {
var response = readBody(xhr);
var parsed = JSON.parse(response);
window.external.Boot(parsed.sId, parsed.lobbyHost, parsed.frontierHost);
}catch(err){
} catch(err) {
document.getElementById("Error").innerHTML = "Login failed.";
}
}
@ -54,7 +54,7 @@
<a href="https://discord.gg/KfrZCkx" class="s-link-badge s-link-badge-discord col-xs-5">
Join us on Discord!
</a>
<a href="https://github.com/SapphireMordred/Sapphire" class="s-link-badge s-link-badge-github col-xs-5 pull-left">
<a href="https://github.com/SapphireMordred/Sapphire" class="s-link-badge s-link-badge-github col-xs-5 pull-right">
Our Github repository
</a>
</div>

2494
doxygen/Doxyfile Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,129 @@
body {
background-color: #222;
color: #ccc;
overflow-x: hidden;
}
#nav-tree {
background-color: #222;
background-image: none;
}
#side-nav {
width: 300px;
}
#titlearea {
border: none;
padding: 5px;
}
div.header {
background-color: #2a2a2a !important;
}
h2.groupheader {
color: #ccc;
}
.mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams {
background-color: #333;
color: #ccc;
}
.directory tr.even {
background-color: #3f3f3f;
}
a, .contents a:visited {
color: #548cff;
}
.memtitle {
background-color: #555 !important;
background-image: none;
border-top: 1px solid #717171;
border-left: 1px solid #717171;
border-right: 1px solid #717171;
}
.memdoc, dl.reflist dd {
background-color: #444;
border-bottom: 1px solid #717171;
border-left: 1px solid #717171;
border-right: 1px solid #717171;
}
.memproto, dl.reflist dt {
background-color: #555;
color: #ccc;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.9);
border-top: 1px solid #717171;
border-left: 1px solid #717171;
border-right: 1px solid #717171;
}
div.header {
border-bottom: 1px solid #717171;
background-image: none;
}
.paramname {
color: #ff5a5a;
}
.memtemplate {
color: #6e9eff;
}
.memSeparator, h2.groupheader {
border-bottom: 1px solid #545454;
}
.navelem, .navpath ul {
background-color: #333;
background-image: none;
}
.navpath ul {
border: solid 1px #717171;
}
.navpath li.footer {
color: #548cff;
}
.navpath li.navelem a, .navpath li.navelem a:visited {
color: #ccc;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.9);
}
.ui-resizable-e {
background-image: none;
background-color: #717171;
}
.sm-dox {
background-image: none;
background-color: #333;
}
.sm-dox a {
color: #ccc;
text-shadow: 0px 1px 1px #000;
}
.sm-dox a span.sub-arrow {
border-color: #ccc transparent transparent transparent;
}
.sm-dox a, .sm-dox a:focus, .sm-dox a:active, .sm-dox a:hover, .sm-dox a.highlighted {
background-image: none;
}
#main-nav {
border-top: 1px solid #717171;
}

BIN
doxygen/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

6
doxygen/pages/index.md Normal file
View file

@ -0,0 +1,6 @@
# Sapphire Developer Documentation
The intent is to provide developers with a sense of pride and enjoyment for documenting their code.
Please look forward to it.
![pls](https://i.imgur.com/O8NBR9X.png)

View file

@ -1,74 +0,0 @@
-- MySQL dump 10.13 Distrib 5.7.13, for Win64 (x86_64)
--
-- Host: localhost Database: sapphire
-- ------------------------------------------------------
-- Server version 5.7.13-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `charaitemcrystal`
--
DROP TABLE IF EXISTS `charaitemcrystal`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `charaitemcrystal` (
`CharacterId` int(20) DEFAULT '0',
`storageId` int(10) DEFAULT '2001',
`type` int(5) DEFAULT '0',
`idx` int(5) NOT NULL AUTO_INCREMENT,
`container_0` int(20) DEFAULT '0',
`container_1` int(20) DEFAULT '0',
`container_2` int(20) DEFAULT '0',
`container_3` int(20) DEFAULT '0',
`container_4` int(20) DEFAULT '0',
`container_5` int(20) DEFAULT '0',
`container_6` int(20) DEFAULT '0',
`container_7` int(20) DEFAULT '0',
`container_8` int(20) DEFAULT '0',
`container_9` int(20) DEFAULT '0',
`container_10` int(20) DEFAULT '0',
`container_11` int(20) DEFAULT '0',
`container_12` int(20) DEFAULT '0',
`container_13` int(20) DEFAULT '0',
`container_14` int(20) DEFAULT '0',
`container_15` int(20) DEFAULT '0',
`container_16` int(20) DEFAULT '0',
`container_17` int(20) DEFAULT '0',
`IS_DELETE` int(3) DEFAULT '0',
`IS_NOT_ACTIVE_FLG` int(3) DEFAULT '0',
`UPDATE_DATE` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`idx`),
KEY `CharacterId` (`CharacterId`)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `charaitemcrystal`
--
LOCK TABLES `charaitemcrystal` WRITE;
/*!40000 ALTER TABLE `charaitemcrystal` DISABLE KEYS */;
/*!40000 ALTER TABLE `charaitemcrystal` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2016-12-09 17:37:10

View file

@ -1,68 +0,0 @@
-- MySQL dump 10.13 Distrib 5.7.13, for Win64 (x86_64)
--
-- Host: localhost Database: sapphire
-- ------------------------------------------------------
-- Server version 5.7.13-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `charaitemcurrency`
--
DROP TABLE IF EXISTS `charaitemcurrency`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `charaitemcurrency` (
`CharacterId` int(20) NOT NULL,
`storageId` int(10) DEFAULT '2000',
`type` int(5) DEFAULT '0',
`idx` int(5) NOT NULL AUTO_INCREMENT,
`container_0` int(20) DEFAULT '0',
`container_1` int(20) DEFAULT '0',
`container_2` int(20) DEFAULT '0',
`container_3` int(20) DEFAULT '0',
`container_4` int(20) DEFAULT '0',
`container_5` int(20) DEFAULT '0',
`container_6` int(20) DEFAULT '0',
`container_7` int(20) DEFAULT '0',
`container_8` int(20) NOT NULL DEFAULT '0',
`container_9` int(20) NOT NULL DEFAULT '0',
`container_10` int(20) NOT NULL DEFAULT '0',
`container_11` int(20) NOT NULL DEFAULT '0',
`IS_DELETE` int(3) DEFAULT '0',
`IS_NOT_ACTIVE_FLG` int(3) DEFAULT '0',
`UPDATE_DATE` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`idx`),
UNIQUE KEY `CharacterId` (`CharacterId`)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `charaitemcurrency`
--
LOCK TABLES `charaitemcurrency` WRITE;
/*!40000 ALTER TABLE `charaitemcurrency` DISABLE KEYS */;
/*!40000 ALTER TABLE `charaitemcurrency` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2016-12-09 17:37:11

File diff suppressed because it is too large Load diff

View file

@ -48,6 +48,8 @@ ALTER TABLE `charainfo` CHANGE `Orchestrion` `Orchestrion` BINARY(40) NULL DEFAU
ALTER TABLE `charainfo` CHANGE `Minions` `Minions` BINARY(37) NULL DEFAULT NULL;
ALTER TABLE `charainfo` CHANGE `QuestCompleteFlags` `QuestCompleteFlags` VARBINARY(396) NULL DEFAULT NULL;
ALTER TABLE `charainfo` ADD COLUMN `EquipDisplayFlags` INT(3) NULL DEFAULT '0' AFTER `GMRank`;
ALTER TABLE `charainfo` ADD COLUMN `Pose` INT(3) NULL DEFAULT '0' AFTER `EquipDisplayFlags`;
ALTER TABLE `charainfo` ADD COLUMN `EquipDisplayFlags` INT(3) NULL DEFAULT '0' AFTER `GMRank`;
ALTER TABLE `charainfofriendlist` CHANGE `CharacterId` `ContentId` bigint(20) NULL DEFAULT NULL;
ALTER TABLE `charainfofriendlist` CHANGE `CharacterIdList` `ContentIdList` blob NULL DEFAULT NULL;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,66 @@
#include "ConfigMgr.h"
#include <boost/property_tree/ini_parser.hpp>
#include <boost/filesystem.hpp>
/**
* Loads an ini file and parses it
* @param configName the name of ini file relative to m_configFolderRoot to load alongside global.ini
* @return true if loading was successful
*/
bool Core::ConfigMgr::loadConfig( const std::string& configName )
{
std::stringstream configStream;
// get global config
auto configDir = boost::filesystem::path( m_configFolderRoot );
if( !boost::filesystem::exists( configDir ) )
{
return false;
}
auto globalConfig = boost::filesystem::path( configDir / m_globalConfigFile );
if( !boost::filesystem::exists( globalConfig ) )
{
if( !copyDefaultConfig( globalConfig.filename().string() ) )
return false;
}
std::ifstream globalConfigFile( globalConfig.c_str() );
configStream << globalConfigFile.rdbuf();
// add some newlines just in case there's no newline at the end of the global file
configStream << "\n\n";
// get local config
auto localConfig = boost::filesystem::path( configDir / configName );
if( !boost::filesystem::exists( localConfig ) )
{
if( !copyDefaultConfig( localConfig.filename().string() ) )
return false;
}
std::ifstream configFile( localConfig.c_str() );
configStream << configFile.rdbuf();
// parse the tree and we're fuckin done
boost::property_tree::read_ini( configStream, m_propTree );
return true;
}
bool Core::ConfigMgr::copyDefaultConfig( const std::string& configName )
{
boost::filesystem::path configPath( m_configFolderRoot );
configPath /= configName;
if( !boost::filesystem::exists( configPath.string() + m_configDefaultSuffix ) )
{
// no default file :(
return false;
}
boost::filesystem::copy_file( configPath.string() + m_configDefaultSuffix, configPath );
return true;
}

View file

@ -0,0 +1,45 @@
#ifndef SAPPHIRE_CONFIGMGR_H
#define SAPPHIRE_CONFIGMGR_H
#include <boost/property_tree/ptree.hpp>
namespace Core
{
class ConfigMgr
{
public:
ConfigMgr() = default;
~ConfigMgr() = default;
bool loadConfig( const std::string& configName );
template< class T >
T getValue( const std::string& name, T defaultValue = T() )
{
try
{
return m_propTree.get< T >( name );
}
catch( ... )
{
return defaultValue;
}
}
template< class T >
void setValue( const std::string& name, T defaultValue = T() )
{
m_propTree.put( name, defaultValue );
}
private:
bool copyDefaultConfig( const std::string& configName );
boost::property_tree::ptree m_propTree;
const std::string m_globalConfigFile = "global.ini";
const std::string m_configFolderRoot = "./config/";
const std::string m_configDefaultSuffix = ".default";
};
}
#endif //SAPPHIRE_CONFIGMGR_H

View file

@ -1,35 +0,0 @@
#include "XMLConfig.h"
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/foreach.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/lexical_cast.hpp>
namespace Core {
// instanciate and load a config
XMLConfig::XMLConfig()
{
}
XMLConfig::~XMLConfig()
{
}
using boost::property_tree::ptree;
const ptree& empty_ptree()
{
static ptree t;
return t;
};
bool XMLConfig::loadConfig( const std::string& fileName )
{
boost::property_tree::read_xml( fileName, m_propTree );
return true;
}
}

View file

@ -1,73 +0,0 @@
#ifndef __XMLCONFIG_H
#define __XMLCONFIG_H
#include <stdint.h>
#include <boost/property_tree/ptree.hpp>
#include <map>
namespace Core {
// very simple XML parser class
// this hasn't gotten much attention yet as it works good as it is.
class XMLConfig
{
public:
typedef std::map<std::string, std::string> SettingMap;
typedef std::map<std::string, SettingMap> CategoryMap;
// instanciate and load a config
XMLConfig();
~XMLConfig();
// load a config file
bool loadConfig( const std::string& fileName );
template< class T >
T getValue( const std::string& name, T defaultValue = T() )
{
try
{
return m_propTree.get< T >( name );
}
catch( ... )
{
return defaultValue;
}
}
template< class T >
void setValue( const std::string& name, T defaultValue = T() )
{
m_propTree.put( name, defaultValue );
}
template< class T >
T getAttrValue( boost::property_tree::ptree node, const std::string& name, T defaultValue = T() )
{
try
{
T outVal = node.get< T >( "<xmlattr>." + name );
return outVal;
}
catch( const std::runtime_error& )
{
T outVal = defaultValue;
return outVal;
}
}
boost::property_tree::ptree getChild( const std::string& name )
{
auto val = m_propTree.get_child( name );
return val;
}
private:
boost::property_tree::ptree m_propTree;
};
}
#endif

View file

@ -29,7 +29,8 @@ void Core::Db::CharaDbConnection::doPrepareStatements()
"FavoritePoint, RestPoint, StartTown, ActiveTitle, TitleList, Achievement, "
"Aetheryte, HowTo, Minions, Mounts, Orchestrion, EquippedMannequin, ConfigFlags, "
"QuestCompleteFlags, OpeningSequence, QuestTracking, GrandCompany, "
"GrandCompanyRank, Discovery, GMRank, EquipDisplayFlags, Unlocks, CFPenaltyUntil "
"GrandCompanyRank, Discovery, GMRank, EquipDisplayFlags, Unlocks, CFPenaltyUntil, "
"Pose "
"FROM charainfo WHERE CharacterId = ?;", CONNECTION_SYNC );
@ -44,7 +45,7 @@ void Core::Db::CharaDbConnection::doPrepareStatements()
"ActiveTitle = ?, TitleList = ?, Achievement = ?, Aetheryte = ?, HowTo = ?, Minions = ?, Mounts = ?, Orchestrion = ?, "
"EquippedMannequin = ?, ConfigFlags = ?, QuestCompleteFlags = ?, OpeningSequence = ?, "
"QuestTracking = ?, GrandCompany = ?, GrandCompanyRank = ?, Discovery = ?, GMRank = ?, EquipDisplayFlags = ?, Unlocks = ?, "
"CFPenaltyUntil = ? WHERE CharacterId = ?;", CONNECTION_ASYNC );
"CFPenaltyUntil = ?, Pose = ? WHERE CharacterId = ?;", CONNECTION_ASYNC );
prepareStatement( CHARA_SEL_MINIMAL, "SELECT Name, Customize, ModelEquip, TerritoryId, GuardianDeity, "

View file

@ -1425,12 +1425,21 @@ Core::Data::Emote::Emote( uint32_t row_id, Core::Data::ExdDataGenerated* exdData
auto row = exdData->m_EmoteDat.get_row( row_id );
name = exdData->getField< std::string >( row, 0 );
emoteCategory = exdData->getField< uint8_t >( row, 11 );
emoteMode = exdData->getField< uint8_t >( row, 12 );
hasCancelEmote = exdData->getField< bool >( row, 15 );
drawsWeapon = exdData->getField< bool >( row, 16 );
textCommand = exdData->getField< int32_t >( row, 18 );
icon = exdData->getField< uint16_t >( row, 19 );
logMessageTargeted = exdData->getField< uint16_t >( row, 20 );
logMessageUntargeted = exdData->getField< uint16_t >( row, 21 );
}
Core::Data::EmoteMode::EmoteMode( uint32_t row_id, Core::Data::ExdDataGenerated* exdData )
{
auto row = exdData->m_EmoteDat.get_row( row_id );
}
Core::Data::EmoteCategory::EmoteCategory( uint32_t row_id, Core::Data::ExdDataGenerated* exdData )
{
auto row = exdData->m_EmoteCategoryDat.get_row( row_id );
@ -4553,6 +4562,7 @@ bool Core::Data::ExdDataGenerated::init( const std::string& path )
m_DpsChallengeTransientDat = setupDatAccess( "DpsChallengeTransient", xiv::exd::Language::none );
m_EmoteDat = setupDatAccess( "Emote", xiv::exd::Language::en );
m_EmoteCategoryDat = setupDatAccess( "EmoteCategory", xiv::exd::Language::en );
m_EmoteModeDat = setupDatAccess( "EmoteMode", xiv::exd::Language::none );
m_ENpcBaseDat = setupDatAccess( "ENpcBase", xiv::exd::Language::none );
m_ENpcResidentDat = setupDatAccess( "ENpcResident", xiv::exd::Language::en );
m_EObjDat = setupDatAccess( "EObj", xiv::exd::Language::none );

View file

@ -1603,6 +1603,9 @@ struct Emote
uint16_t icon;
uint16_t logMessageTargeted;
uint16_t logMessageUntargeted;
uint8_t emoteMode;
bool hasCancelEmote;
bool drawsWeapon;
Emote( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
@ -1614,6 +1617,19 @@ struct EmoteCategory
EmoteCategory( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct EmoteMode
{
std::string name;
uint8_t emoteCategory;
int32_t textCommand;
uint16_t icon;
uint16_t logMessageTargeted;
uint16_t logMessageUntargeted;
EmoteMode( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct ENpcBase
{
std::vector< uint32_t > eNpcData;
@ -4133,6 +4149,7 @@ struct ZoneSharedGroup
xiv::exd::Exd m_DpsChallengeTransientDat;
xiv::exd::Exd m_EmoteDat;
xiv::exd::Exd m_EmoteCategoryDat;
xiv::exd::Exd m_EmoteModeDat;
xiv::exd::Exd m_ENpcBaseDat;
xiv::exd::Exd m_ENpcResidentDat;
xiv::exd::Exd m_EObjDat;
@ -4861,6 +4878,7 @@ struct ZoneSharedGroup
std::set< uint32_t > m_DpsChallengeOfficerIdList;
std::set< uint32_t > m_DpsChallengeTransientIdList;
std::set< uint32_t > m_EmoteIdList;
std::set< uint32_t > m_EmoteModeIdList;
std::set< uint32_t > m_EmoteCategoryIdList;
std::set< uint32_t > m_ENpcBaseIdList;
std::set< uint32_t > m_ENpcResidentIdList;
@ -5823,6 +5841,12 @@ const std::set< uint32_t >& getEmoteIdList()
loadIdList( m_EmoteDat, m_EmoteIdList );
return m_EmoteIdList;
}
const std::set< uint32_t >& getEmoteModeIdList()
{
if( m_EmoteModeIdList.size() == 0 )
loadIdList( m_EmoteModeDat, m_EmoteModeIdList );
return m_EmoteModeIdList;
}
const std::set< uint32_t >& getEmoteCategoryIdList()
{
if( m_EmoteCategoryIdList.size() == 0 )

View file

@ -1,5 +1,5 @@
#ifndef _COMMON_FORWARDS_H
#define _COMMON_FORWARDS_H
#ifndef COMMON_FORWARDS_H
#define COMMON_FORWARDS_H
#include <boost/shared_ptr.hpp>
#include <chrono>
@ -11,9 +11,9 @@ using duration = std::chrono::steady_clock::duration;
namespace Core
{
class XMLConfig;
class ConfigMgr;
typedef boost::shared_ptr<XMLConfig> XMLConfigPtr;
typedef boost::shared_ptr< ConfigMgr > ConfigMgrPtr;
namespace Network
@ -22,15 +22,17 @@ namespace Core
class Acceptor;
class Connection;
typedef boost::shared_ptr<Hive> HivePtr;
typedef boost::shared_ptr<Acceptor> AcceptorPtr;
typedef boost::shared_ptr<Connection> ConnectionPtr;
typedef boost::shared_ptr< Hive > HivePtr;
typedef boost::shared_ptr< Acceptor > AcceptorPtr;
typedef boost::shared_ptr< Connection > ConnectionPtr;
namespace Packets
{
class GamePacket;
class FFXIVPacketBase;
typedef boost::shared_ptr<GamePacket> GamePacketPtr;
typedef boost::shared_ptr< GamePacket > GamePacketPtr;
typedef boost::shared_ptr< FFXIVPacketBase > FFXIVPacketBasePtr;
}
}

View file

@ -0,0 +1,299 @@
#ifndef _COMMONACTORCONTROL_H
#define _COMMONACTORCONTROL_H
#include <cstdint>
#include <vector>
#include <boost/make_shared.hpp>
#include "CommonGen.h"
// +---------------------------------------------------------------------------
// The following enumerations are structures to require their type be included.
// They are also defined within the Core::Common namespace to avoid collisions.
// +---------------------------------------------------------------------------
namespace Core {
namespace Network {
namespace ActorControl {
enum ActorControlType : uint16_t
{
/*! Toggles weapon status -> Sheathed/UnSheathed
\param param1 status 0|1 */
ToggleWeapon = 0x00,
/*! Toggles Autoattack status on/off
\param param1 status 0|1 */
AutoAttack = 0x01,
SetStatus = 0x02,
CastStart = 0x03,
ToggleAggro = 0x04,
ClassJobChange = 0x05,
DefeatMsg = 0x06,
GainExpMsg = 0x07,
LevelUpEffect = 0x0A,
ExpChainMsg = 0x0C,
HpSetStat = 0x0D,
DeathAnimation = 0x0E,
CastInterrupt = 0x0F,
ActionStart = 0x11,
StatusEffectGain = 0x14,
StatusEffectLose = 0x15,
HPFloatingText = 0x17,
UpdateRestedExp = 0x018,
Unk2 = 0x19,
Flee = 0x1B,
Unk3 = 0x20, // Animation related?
CombatIndicationShow = 0x22,
SpawnEffect = 0x25,
ToggleInvisible = 0x26,
ToggleActionUnlock = 0x29,
UpdateUiExp = 0x2B,
DmgTakenMsg = 0x2D,
SetTarget = 0x32,
ToggleNameHidden = 0x36,
LimitbreakStart = 0x47,
LimitbreakPartyStart = 0x48,
BubbleText = 0x49,
DamageEffect = 0x50,
RaiseAnimation = 0x51,
TreasureScreenMsg = 0x57,
SetOwnerId = 0x59,
ItemRepairMsg = 0x5C,
DirectorInit = 0x64,
DirectorClear = 0x65,
LeveStartAnim = 0x66,
LeveStartError = 0x67,
DirectorEObjMod = 0x6A,
DirectorUpdate = 0x6D,
ItemObtainMsg = 0x75,
DutyQuestScreenMsg = 0x7B,
ItemObtainIcon = 0x84,
FateItemFailMsg = 0x85,
ItemFailMsg = 0x86,
ActionLearnMsg1 = 0x87,
FreeEventPos = 0x8A,
SetBGM = 0xA1,
UnlockAetherCurrentMsg = 0xA4,
RemoveName = 0xA8,
ScreenFadeOut = 0xAA,
ZoneIn = 0xC8,
ZoneInDefaultPos = 0xC9,
TeleportStart = 0xCB,
TeleportDone = 0xCD,
TeleportDoneFadeOut = 0xCE,
DespawnZoneScreenMsg = 0xCF,
InstanceSelectDlg = 0xD2,
ActorDespawnEffect = 0xD4,
CompanionUnlock = 0xFD,
ObtainBarding = 0xFE,
EquipBarding = 0xFF,
CompanionMsg1 = 0x102,
CompanionMsg2 = 0x103,
ShowPetHotbar = 0x104,
ActionLearnMsg = 0x109,
ActorFadeOut = 0x10A,
ActorFadeIn = 0x10B,
WithdrawMsg = 0x10C,
OrderMinion = 0x10D,
ToggleMinion = 0x10E,
LearnMinion = 0x10F,
ActorFateOut1 = 0x110,
Emote = 0x122,
EmoteInterrupt = 0x123,
SetPose = 0x127,
CraftingUnk = 0x12C,
GatheringSenseMsg = 0x130,
PartyMsg = 0x131,
GatheringSenseMsg1 = 0x132,
GatheringSenseMsg2 = 0x138,
FishingMsg = 0x140,
FishingBaitMsg = 0x145,
FishingReachMsg = 0x147,
FishingFailMsg = 0x148,
MateriaConvertMsg = 0x15E,
MeldSuccessMsg = 0x15F,
MeldFailMsg = 0x160,
MeldModeToggle = 0x161,
AetherRestoreMsg = 0x163,
DyeMsg = 0x168,
ToggleCrestMsg = 0x16A,
ToggleBulkCrestMsg = 0x16B,
MateriaRemoveMsg = 0x16C,
GlamourCastMsg = 0x16D,
GlamourRemoveMsg = 0x16E,
RelicInfuseMsg = 0x179,
AetherReductionDlg = 0x17D,
Unk6 = 0x19C,
EObjAnimation = 0x19D,
SetTitle = 0x1F4,
SetStatusIcon = 0x1F8,
LimitBreakGauge = 0x1F9, // Max level, amount, build type (chop sound), lb type(0=pve lb 1=pvp lb)
SetHomepoint = 0x1FB,
SetFavorite = 0x1FC,
LearnTeleport = 0x1FD,
OpenRecommendationGuide = 0x200,
ArmoryErrorMsg = 0x201,
AchievementPopup = 0x203,
Unk7 = 0x205, // LogMessage?
AchievementMsg = 0x206,
SetItemLevel = 0x209,
ChallengeEntryCompleteMsg = 0x20B,
ChallengeEntryUnlockMsg = 0x20C,
GilTrailMsg = 0x211,
SetMaxGearSets = 0x230,
SetCharaGearParamUI = 0x260,
GearSetEquipMsg = 0x321,
SetFestival = 0x386, // param1: festival.exd index
ToggleOrchestrionUnlock = 0x396,
Dismount = 0x3A0,
// Duty Recorder
BeginReplayAck = 0x3A1,
EndReplayAck = 0x3A2,
// PvP Duel
SetPvPState = 0x5E0, // param3 must be 6 to engage a duel (hardcoded in the client)
EndDuelSession = 0x5E1, // because someone went oob?
StartDuelCountdown = 0x5E2, // begins a countdown; also does some duel bgm thing.
StartDuel = 0x5E3, // actually all it does is set the challenger actor id;
DuelResultScreen = 0x5E4, // win/lose thing, also reset a target id just like what EndDuelSession does.
// Duty Action
SetDutyActionId = 0x5E8, // ContentExAction
SetDutyActionHud = 0x5E9, // disable/enable
SetDutyActionActive = 0x5EA,
SetDutyActionRemaining = 0x5EB,
};
enum ClientTriggerType
{
ToggleSheathe = 0x01,
ToggleAutoAttack = 0x02,
ChangeTarget = 0x03,
DismountReq = 0x65,
RemoveStatusEffect = 0x68,
CastCancel = 0x69,
Return = 0xC8, // return dead / accept raise
FinishZoning = 0xC9,
Teleport = 0xCA,
MarkPlayer = 0x12D, // Mark player, visible to party only
SetTitleReq = 0x12E,
TitleList = 0x12F,
UpdatedSeenHowTos = 0x133,
AllotAttribute = 0x135,
ClearWaymarks = 0x13A,
CameraMode = 0x13B, // param12, 1 = camera mode enable, 0 = disable
HuntingLogDetails = 0x194,
Timers = 0x1AB,
DyeItem = 0x1B5,
RequestChocoboInventory = 0x1C4,
EmoteReq = 0x1F4,
EmoteCancel = 0x1F6,
PersistentEmoteCancel = 0x1F7,
PoseChange = 0x1F9,
PoseReapply = 0x1FA,
PoseCancel = 0x1FB,
AchievementCrit = 0x202,
AchievementComp = 0x203,
AchievementCatChat = 0x206,
DirectorInitFinish = 0x321,
DirectorSync = 0x328, // unsure what exactly triggers it, starts director when returning to instance though
EnterTerritoryEventFinished = 0x330,
RequestInstanceLeave = 0x333, // df menu button
AchievementCritReq = 0x3E8,
AchievementList = 0x3E9,
CompanionAction = 0x6A4,
CompanionSetBarding = 0x6A5,
CompanionActionUnlock = 0x6A6,
OpenPerformInstrumentUI = 0x71C,
StartReplay = 0x7BC,
EndReplay = 0x7BD, // request for restoring the original player state (actor, buff, gauge, etc..)
OpenDuelUI = 0x898, // Open a duel ui
DuelRequestResult = 0x899, // either accept/reject
};
} /* ActorControl */
} /* Common */
} /* Core */
#endif

View file

@ -130,6 +130,20 @@ struct FFXIVARR_PACKET_RAW
std::vector< uint8_t > data;
};
/**
* Indicates the type of the segment
* IPC type will contain an additional header: FFXIVARR_PACKET_SEGMENT_HEADER + FFXIVARR_IPC_HEADER + data
* The remaining types don't contain an additonal header, FFXIVARR_PACKET_SEGMENT_HEADER + data
*/
enum FFXIVARR_SEGMENT_TYPE
{
SEGMENTTYPE_SESSIONINIT = 1,
SEGMENTTYPE_IPC = 3,
SEGMENTTYPE_KEEPALIVE = 7,
//SEGMENTTYPE_RESPONSE = 8,
SEGMENTTYPE_ENCRYPTIONINIT = 9,
};
/**
* Structural representation of the common header for IPC packet segments.
* NOTE: This is packet segment type 3.

View file

@ -1,102 +0,0 @@
#include <stdio.h>
#include "GamePacket.h"
#include <time.h>
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
#include "Util/Util.h"
Core::Network::Packets::GamePacket::GamePacket( uint16_t subType, uint16_t size, uint32_t id1, uint32_t id2, uint16_t type )
{
m_dataBuf = std::vector<uint8_t>( size );
memset( &m_segHdr, 0, sizeof( m_segHdr ) );
setHeader( size, type, id1, id2, subType, 0x00 );
}
void Core::Network::Packets::GamePacket::setHeader( uint16_t size, uint16_t type, uint32_t id1, uint32_t id2, uint16_t subType, uint32_t unknown )
{
m_segHdr.size = size;
m_segHdr.type = type;
m_segHdr.source_actor = id1;
m_segHdr.target_actor = id2;
//m_segHdr._reserved_E = 0x00;
m_subType = subType;
m_timeStamp = static_cast< uint32_t >( time( nullptr ) );
if( size > 0 )
{
memcpy( &m_dataBuf[0], &m_segHdr, sizeof( m_segHdr ) );
m_dataBuf[0x10] = 0x14;
*reinterpret_cast< uint16_t* >( &m_dataBuf[0] + 0x12 ) = m_subType;
}
if( size > 0x18 )
*reinterpret_cast< uint32_t* >( &m_dataBuf[0] + 0x18 ) = m_timeStamp;
}
Core::Network::Packets::GamePacket::GamePacket( char * pData, uint16_t size, bool bWriteStamp )
{
m_dataBuf = std::vector<uint8_t>( size );
memcpy( &m_dataBuf[0], pData, size );
m_unknown2 = 0;
if( bWriteStamp && size > 0x18 )
{
m_timeStamp = static_cast< uint32_t >( time( nullptr ) );
*reinterpret_cast< uint16_t* >( &m_dataBuf[0] + 0x10 ) = 0x14;
*reinterpret_cast< uint32_t* >( &m_dataBuf[0] + 0x18 ) = m_timeStamp;
}
//m_segHdr._reserved_E = 0;
m_segHdr.size = *reinterpret_cast< uint32_t* >( &m_dataBuf[0] );
m_segHdr.type = *reinterpret_cast< uint16_t* >( &m_dataBuf[0] + 0x0C );
m_subType = *reinterpret_cast< uint16_t* >( &m_dataBuf[0] + 0x12 );
m_segHdr.source_actor = *reinterpret_cast< uint32_t* >( &m_dataBuf[0] + 0x04 );
m_segHdr.target_actor = *reinterpret_cast< uint32_t* >( &m_dataBuf[0] + 0x08 );
}
Core::Network::Packets::GamePacket::GamePacket( const Packets::FFXIVARR_PACKET_RAW& packetData )
{
m_segHdr = packetData.segHdr;
m_dataBuf = std::vector<uint8_t>( m_segHdr.size );
memcpy( &m_dataBuf[0] + sizeof( Packets::FFXIVARR_PACKET_SEGMENT_HEADER ), &packetData.data[0], m_segHdr.size - sizeof( Packets::FFXIVARR_PACKET_SEGMENT_HEADER ) );
memcpy( &m_dataBuf[0], &m_segHdr, sizeof( Packets::FFXIVARR_PACKET_SEGMENT_HEADER ) );
m_subType = *reinterpret_cast< uint16_t* >( &m_dataBuf[0] + 0x12 );
if( m_segHdr.size > 0x18 )
m_timeStamp = *reinterpret_cast< uint32_t* >( &m_dataBuf[0] + 0x18 );
}
Core::Network::Packets::GamePacket::GamePacket()
{
}
Core::Network::Packets::GamePacket::~GamePacket()
{
}
void Core::Network::Packets::GamePacket::savePacket()
{
char filename[20];
sprintf( filename, "dump_0x%x_%i.dat", m_subType, Util::getTimeMs() );
FILE * fp = nullptr;
fp = fopen( filename, "wb" );
fwrite( &m_dataBuf[0], 1, m_segHdr.size, fp );
fclose( fp );
}
std::string Core::Network::Packets::GamePacket::toString() const
{
return Core::Util::binaryToHexDump( const_cast<uint8_t *>( &m_dataBuf[0] ), getSize() );
}

View file

@ -1,104 +0,0 @@
#ifndef _GAMEPACKET_H_
#define _GAMEPACKET_H_
#include "CommonNetwork.h"
#include "Forwards.h"
#include <stdint.h>
#include <string.h>
namespace Core {
namespace Network {
namespace Packets {
class GamePacket
{
public:
GamePacket( uint16_t subType, uint16_t size, uint32_t id1, uint32_t id2, uint16_t type = 0x03 );
GamePacket( char* pData, uint16_t size, bool bWriteStamp = true );
GamePacket( const Packets::FFXIVARR_PACKET_RAW& packetData );
GamePacket( void );
~GamePacket( void );
uint16_t getSize() const
{
return m_segHdr.size;
}
uint16_t getType() const
{
return m_segHdr.type;
}
uint16_t getSubType() const
{
return m_subType;
}
template< class T >
void setValAt( uint16_t pos, T value )
{
assert( m_segHdr.size > pos );
memcpy( reinterpret_cast< uint8_t* >( &m_dataBuf[0] + pos ), &value, sizeof( T ) );
}
template< class T >
T getValAt( uint16_t pos ) const
{
assert( m_segHdr.size > pos );
return *reinterpret_cast< const T* >( &m_dataBuf[0] + pos );
}
void setBytesAt( uint16_t offset, uint8_t * bytes, uint16_t length )
{
assert( m_segHdr.size > offset );
memcpy( reinterpret_cast< uint8_t* >( &m_dataBuf[0] + offset ), bytes, length );
}
const char* getStringAt( uint16_t pos ) const
{
assert( m_segHdr.size > pos );
return reinterpret_cast< const char* >( &m_dataBuf[0] + pos );
}
void setStringAt( uint16_t pos, const std::string& str )
{
assert( m_segHdr.size > pos );
memcpy( reinterpret_cast< uint8_t* >( &m_dataBuf[0] + pos ), str.c_str(), str.length() );
}
const uint8_t* getData() const
{
return reinterpret_cast< const uint8_t* >( &m_dataBuf[0] );
}
const uint8_t* getDataAt(uint16_t pos) const
{
assert( m_segHdr.size > pos );
return reinterpret_cast< const uint8_t* >( &m_dataBuf[0] + pos );
}
void setHeader( uint16_t size, uint16_t type, uint32_t id1, uint32_t id2, uint16_t subType, uint32_t unknown = 0xFED2E000 );
std::string toString() const;
void savePacket();
FFXIVARR_PACKET_SEGMENT_HEADER m_segHdr;
protected:
uint16_t m_unknown2;
uint16_t m_subType;
uint32_t m_timeStamp;
std::vector< uint8_t > m_dataBuf;
};
}
}
}
#endif

View file

@ -1,14 +1,20 @@
#ifndef _GAMEPACKETNEW_H
#define _GAMEPACKETNEW_H
#ifndef _GAMEPACKET_NEW_H
#define _GAMEPACKET_NEW_H
#include <stdint.h>
#include <iostream>
#include "GamePacket.h"
#include <sstream>
#include <time.h>
#include <boost/make_shared.hpp>
#include <string.h>
#include <memory>
#include <Util/Util.h>
#include "CommonNetwork.h"
#include "PacketDef/Ipcs.h"
namespace Core {
namespace Network {
namespace Packets {
@ -17,225 +23,293 @@ namespace Packets {
// correct template functions.
template < typename T, typename T1 >
class GamePacketNew;
template < typename T, typename T1 >
std::ostream& operator<< ( std::ostream& os, const GamePacketNew< T, T1 >& packet );
class FFXIVIpcPacket;
template< class T >
using ZoneChannelPacket = GamePacketNew< T, ServerZoneIpcType >;
using ZoneChannelPacket = FFXIVIpcPacket< T, ServerZoneIpcType >;
template< class T >
using ChatChannelPacket = GamePacketNew< T, ServerChatIpcType >;
using ChatChannelPacket = FFXIVIpcPacket< T, ServerChatIpcType >;
template< class T >
using LobbyChannelPacket = FFXIVIpcPacket< T, ServerLobbyIpcType >;
template< class T, typename... Args >
boost::shared_ptr< ZoneChannelPacket< T > > makeZonePacket( Args... args )
{
return boost::make_shared< ZoneChannelPacket< T > >( args... );
}
template< class T, typename... Args >
boost::shared_ptr< ChatChannelPacket< T > > makeChatPacket( Args... args )
{
return boost::make_shared< ChatChannelPacket< T > >( args... );
}
template< class T, typename... Args >
boost::shared_ptr< LobbyChannelPacket< T > > makeLobbyPacket( Args... args )
{
return boost::make_shared< LobbyChannelPacket< T > >( args... );
}
/**
* The base implementation of a game packet. Needed for parsing packets.
*/
template < typename T1 >
class FFXIVPacketBase
class FFXIVIpcPacketBase
{
public:
virtual ~FFXIVPacketBase() = default;
virtual ~FFXIVIpcPacketBase() = default;
/**
* @brief Gets the IPC type of this packet. (Useful for determining the
* type of a parsed packet.)
*/
virtual T1 ipcType( void ) = 0;
virtual T1 ipcType() = 0;
};
/**
* A game packet, or IPC packet, object is a template class for constructing
* the data to be sent or parsed. The template works by accepting a structure
* type that represents just the IPC data portion (the bytes after the initial
* 32 byte header information.)
*/
template < typename T, typename T1 >
class GamePacketNew : public FFXIVPacketBase< T1 >
////////////////////////////////////////////////7
class FFXIVPacketBase
{
public:
/**
* @brief Constructs a new game packet with the specified actors.
* @param sourceActorId The source actor id.
* @param targetActorId The target actor id.
*/
GamePacketNew< T, T1 >( uint32_t sourceActorId, uint32_t targetActorId )
FFXIVPacketBase() :
m_segmentType( 0 )
{
initialize();
m_segHdr.source_actor = sourceActorId;
m_segHdr.target_actor = targetActorId;
};
initializeSegmentHeader();
}
/**
* @brief Constructs a new game packet with the specified actors.
* @param sourceActorId The source and target actor id.
*/
GamePacketNew< T, T1 >( uint32_t bothActorId )
FFXIVPacketBase( uint16_t segmentType, uint32_t sourceActorId, uint32_t targetActorId ) :
m_segmentType( segmentType )
{
initialize();
m_segHdr.source_actor = bothActorId;
m_segHdr.target_actor = bothActorId;
};
initializeSegmentHeader();
setSourceActor( sourceActorId );
setTargetActor( targetActorId );
}
std::size_t getSize() const
{
return m_segHdr.size;
}
virtual std::vector< uint8_t > getData() const
{
return {};
}
protected:
/** Initializes the fields of the header structures */
virtual void initialize( void )
{
// Zero out the structures.
memset( &m_segHdr, 0, sizeof( FFXIVARR_PACKET_SEGMENT_HEADER ) );
memset( &m_ipcHdr, 0, sizeof( FFXIVARR_IPC_HEADER ) );
memset( &m_data, 0, sizeof( T ) );
// Set the values of static fields.
// The size must be the sum of the segment header, the ipc header, and
// the IPC data itself.
m_segHdr.size = sizeof( FFXIVARR_PACKET_SEGMENT_HEADER ) + sizeof( FFXIVARR_IPC_HEADER ) + sizeof( T );
// Game packets (IPC) are type 3.
m_segHdr.type = 3;
// The IPC type itself.
m_ipcHdr.type = static_cast< ServerZoneIpcType >( m_data._ServerIpcType );
};
/** The segment header */
FFXIVARR_PACKET_SEGMENT_HEADER m_segHdr;
uint16_t m_segmentType;
public:
virtual T1 ipcType( void )
{
return static_cast< T1 >( m_data._ServerIpcType );
};
/** Gets a reference to the underlying IPC data structure. */
T& data( void ) { return m_data; };
virtual uint32_t getContentSize() { return 0; };
virtual std::vector< uint8_t > getContent() { return{}; };
/**
* @brief Sets the source actor id for this IPC packet.
* @param actorId The source actor id.
* @return This IPC packet object (can be used for chaining).
* @brief Gets the segment type of this packet.
*/
GamePacketNew< T, T1 > sourceActor( uint32_t actorId )
uint16_t getSegmentType() const
{
return m_segmentType;
}
/**
* @brief Sets the source actor id for this packet.
* @param actorId The source actor id.
*/
void setSourceActor( uint32_t actorId )
{
m_segHdr.source_actor = actorId;
return this;
};
/**
* @brief Gets the source actor id for this IPC packet.
* @brief Gets the source actor id for this packet.
* @return The source actor id.
*/
uint32_t sourceActor( void ) const
uint32_t getSourceActor() const
{
return m_segHdr.source_actor;
};
/**
* @brief Sets the target actor id for this IPC packet.
* @brief Sets the target actor id for this packet.
* @param actorId The target actor id.
* @return This IPC packet object (can be used for chaining).
*/
GamePacketNew< T, T1 > targetActor( uint32_t actorId )
void setTargetActor( uint32_t actorId )
{
m_segHdr.target_actor = actorId;
return this;
};
/**
* @brief Gets the target actor id for this IPC packet.
* @return The target actor id.
* @brief Gets the target actor id for this packet.
*/
uint32_t targetActor( void ) const
uint32_t getTargetActor( void ) const
{
return m_segHdr.target_actor;
};
friend std::ostream& operator<< <> ( std::ostream& os, const GamePacketNew< T, T1 >& packet );
friend class GamePacketFactory;
/**
* @brief Adapts the new-style packet into the old style.
*/
operator GamePacket* ( ) const
/** Initializes the fields of the segment header structure */
virtual void initializeSegmentHeader( void )
{
std::ostringstream buf;
serialize( buf );
// NOTE: This should be ok because CGamePacket's constructor will
// copy the contents of the buffer.
GamePacket* pOldStyle = new GamePacket( const_cast< char* >( buf.str().c_str() ), m_segHdr.size, false );
return pOldStyle;
// Zero out the structure.
memset( &m_segHdr, 0, sizeof( FFXIVARR_PACKET_SEGMENT_HEADER ) );
// Set the values of static fields.
// The size must be the sum of the segment header and the content
m_segHdr.size = sizeof( FFXIVARR_PACKET_SEGMENT_HEADER ) + getContentSize();
m_segHdr.type = getSegmentType();
}
};
template < typename T, typename T1 >
class FFXIVIpcPacket : public FFXIVIpcPacketBase< T1 >, public FFXIVPacketBase
{
public:
FFXIVIpcPacket< T, T1 >( uint32_t sourceActorId, uint32_t targetActorId ) :
FFXIVPacketBase( 3, sourceActorId, targetActorId )
{
initialize();
};
operator GamePacketPtr () const
FFXIVIpcPacket< T, T1 >( uint32_t sourceActorId ) :
FFXIVPacketBase( 3, sourceActorId, sourceActorId )
{
std::ostringstream buf;
serialize( buf );
// NOTE: This should be ok because CGamePacket's constructor will
// copy the contents of the buffer.
GamePacketPtr pOldStyle( new GamePacket( const_cast< char* >( buf.str().c_str() ), m_segHdr.size, true ) );
return pOldStyle;
initialize();
};
FFXIVIpcPacket< T, T1 >( const FFXIVARR_PACKET_RAW& rawPacket )
{
auto ipcHdrSize = sizeof( FFXIVARR_IPC_HEADER );
auto copySize = std::min< uint32_t >( sizeof( T ), rawPacket.segHdr.size - ipcHdrSize );
memcpy( &m_segHdr, &rawPacket.segHdr, sizeof( FFXIVARR_PACKET_SEGMENT_HEADER ) );
memcpy( &m_data, &rawPacket.data[0] + ipcHdrSize, copySize );
memset( &m_ipcHdr, 0, ipcHdrSize );
m_ipcHdr.type = static_cast< ServerZoneIpcType >( m_data._ServerIpcType );
}
uint32_t getContentSize() override
{
return sizeof( FFXIVARR_IPC_HEADER ) + sizeof( T );
}
std::vector< uint8_t > getContent() override
{
std::vector< uint8_t > content( getContentSize() );
memcpy( content.data(), &m_ipcHdr, sizeof( FFXIVARR_IPC_HEADER ) );
memcpy( content.data() + sizeof( FFXIVARR_IPC_HEADER ), &m_data, sizeof( T ) );
return content;
}
std::vector< uint8_t > getData() const override
{
auto segmentHeaderSize = sizeof( FFXIVARR_PACKET_SEGMENT_HEADER );
auto ipcHeaderSize = sizeof( FFXIVARR_IPC_HEADER );
auto dataSize = sizeof( m_data );
std::vector< uint8_t > data( segmentHeaderSize + ipcHeaderSize + dataSize );
memcpy( &data[0], &m_segHdr, segmentHeaderSize );
memcpy( &data[segmentHeaderSize], &m_ipcHdr, ipcHeaderSize );
memcpy( &data[segmentHeaderSize + ipcHeaderSize], &m_data, dataSize );
return data;
}
virtual T1 ipcType()
{
return static_cast< T1 >( m_data._ServerIpcType );
};
/** Gets a reference to the underlying IPC data structure. */
T& data() { return m_data; };
const T& data() const { return m_data; }
protected:
/** Initializes the fields of the header structures */
virtual void initialize()
{
// Zero out the structures.
memset( &m_ipcHdr, 0, sizeof( FFXIVARR_IPC_HEADER ) );
memset( &m_data, 0, sizeof( T ) );
// The IPC type itself.
m_ipcHdr.type = static_cast< ServerZoneIpcType >( m_data._ServerIpcType );
m_ipcHdr.timestamp = static_cast< uint32_t >( Util::getTimeSeconds() );
m_segHdr.size = sizeof( T ) + sizeof( FFXIVARR_IPC_HEADER ) + sizeof( FFXIVARR_PACKET_SEGMENT_HEADER );
};
protected:
// TODO: Is this a waste of storage memory?
/** The segment header */
FFXIVARR_PACKET_SEGMENT_HEADER m_segHdr;
/** The IPC packet header */
FFXIVARR_IPC_HEADER m_ipcHdr;
/** The underlying data portion of the packet as a structure */
T m_data;
private:
std::ostream& serialize( std::ostream& os ) const
{
// Since the packet itself is constant, we need to make a copy of the IPC
// header in order to set the timestamp.
FFXIVARR_IPC_HEADER ipcHdr;
memcpy( &ipcHdr, &m_ipcHdr, sizeof( ipcHdr ) );
// TODO: Fixed timestamp? Can we use a manipulator on the stream to assign
// a fixed timestamp value. This might be useful if several packets must
// be sent having the exact same timestamp. (Maybe this doesn't really
// need to happen though...)
ipcHdr.timestamp = static_cast< uint32_t >( time( nullptr ) );
// TODO: What about encryption? compression?
// Ideally, these could come directly from the stream using manipulators.
// We could check the stream's flags, and perform the appropriate
// operations here. The snag is encryption, which does not occur for
// segment headers, but may occur for IPC headers, and their data.
// Compression occurs for the entire segment header down.
os << m_segHdr << ipcHdr;
return os.write( reinterpret_cast< const char* >( &m_data ), sizeof( T ) );
};
};
template < typename T, typename T1 >
std::ostream& operator<<( std::ostream& os, const GamePacketNew<T, T1>& packet )
class FFXIVRawPacket : public FFXIVPacketBase
{
#if 0
// Since the packet itself is constant, we need to make a copy of the IPC
// header in order to set the timestamp.
FFXIVARR_IPC_HEADER ipcHdr;
memcpy( &ipcHdr, &packet.m_ipcHdr, sizeof( ipcHdr ) );
public:
FFXIVRawPacket( uint16_t type, uint32_t size, uint32_t sourceActorId, uint32_t targetActorId ) :
m_data( std::vector< uint8_t >( size - sizeof( FFXIVARR_PACKET_SEGMENT_HEADER ) ) ),
FFXIVPacketBase( type, sourceActorId, targetActorId )
{
initialize();
m_segHdr.size = size;
};
// TODO: Fixed timestamp? Can we use a manipulator on the stream to assign
// a fixed timestamp value. This might be useful if several packets must
// be sent having the exact same timestamp. (Maybe this doesn't really
// need to happen though...)
ipcHdr.timestamp = time( NULL );
FFXIVRawPacket( char* data, uint16_t size ) :
m_data( std::vector< uint8_t >( size ) )
{
auto segmentHdrSize = sizeof( FFXIVARR_PACKET_SEGMENT_HEADER );
memcpy( &m_data[0], data + segmentHdrSize, size - segmentHdrSize );
memcpy( &m_segHdr, data, segmentHdrSize );
}
uint32_t getContentSize() override
{
return m_data.size();
}
std::vector< uint8_t > getContent() override
{
return m_data;
}
virtual std::vector< uint8_t > getData() const override
{
std::vector< uint8_t > data( sizeof( FFXIVARR_PACKET_SEGMENT_HEADER ) + m_data.size() );
memcpy( &data[0], &m_segHdr, sizeof( FFXIVARR_PACKET_SEGMENT_HEADER ) );
memcpy( &data[sizeof( FFXIVARR_PACKET_SEGMENT_HEADER )], &m_data[0], m_data.size() );
return data;
}
/** Gets a reference to the underlying IPC data structure. */
std::vector< uint8_t >& data() { return m_data; };
protected:
/** Initializes the fields of the header structures */
virtual void initialize()
{
// Zero out the structures.
memset( &m_data[0], 0, m_data.size() );
};
protected:
/** The underlying data portion of the packet as a structure */
std::vector< uint8_t > m_data;
};
// TODO: What about encryption? compression?
// Ideally, these could come directly from the stream using manipulators.
// We could check the stream's flags, and perform the appropriate
// operations here. The snag is encryption, which does not occur for
// segment headers, but may occur for IPC headers, and their data.
// Compression occurs for the entire segment header down.
os << packet.m_segHdr << ipcHdr;
return os.write(
reinterpret_cast< const char* >( &packet.m_data ), sizeof( T ) );
#else
return packet.serialize( os );
#endif
}
} /* Packets */
} /* Network */
} /* Core */
#endif /*_CORE_NETWORK_PACKETS_CGAMEPACKETNEW_H*/
#endif /*_CORE_NETWORK_PACKETS_CGAMEPACKETNEW_H*/

View file

@ -5,131 +5,122 @@
using namespace Core::Network::Packets;
namespace Core
PacketParseResult Core::Network::Packets::getHeader( const std::vector< uint8_t > &buffer,
const uint32_t offset,
FFXIVARR_PACKET_HEADER &header )
{
namespace Network
{
namespace Packets
{
PacketParseResult getHeader( const std::vector< uint8_t > &buffer,
const uint32_t offset,
FFXIVARR_PACKET_HEADER &header )
{
const auto headerSize = sizeof( FFXIVARR_PACKET_HEADER );
const auto headerSize = sizeof( FFXIVARR_PACKET_HEADER );
// Check if we have enough bytes in the buffer.
auto remainingBytes = buffer.size() - offset;
if( remainingBytes < headerSize )
return Incomplete;
// Check if we have enough bytes in the buffer.
auto remainingBytes = buffer.size() - offset;
if( remainingBytes < headerSize )
return Incomplete;
// Copy packet header.
memcpy( &header, buffer.data() + offset, headerSize );
// Copy packet header.
memcpy( &header, buffer.data() + offset, headerSize );
if( !checkHeader(header) )
return Malformed;
if( !checkHeader(header) )
return Malformed;
return Success;
}
PacketParseResult getSegmentHeader( const std::vector< uint8_t > &buffer,
const uint32_t offset,
FFXIVARR_PACKET_SEGMENT_HEADER &header )
{
const auto headerSize = sizeof( FFXIVARR_PACKET_SEGMENT_HEADER );
// Check if we have enough bytes in the buffer.
auto remainingBytes = buffer.size() - offset;
if( remainingBytes < headerSize )
return Incomplete;
// Copy segment header
memcpy( &header, buffer.data() + offset, headerSize );
return Success;
}
PacketParseResult getPackets( const std::vector< uint8_t > &buffer,
const uint32_t offset,
const FFXIVARR_PACKET_HEADER &packetHeader,
std::vector< FFXIVARR_PACKET_RAW > &packets )
{
// sanity check: check there's enough bytes in the buffer
const auto bytesExpected = packetHeader.size - sizeof( struct FFXIVARR_PACKET_HEADER );
if( buffer.size() - offset < bytesExpected )
return Incomplete;
// Loop each message
uint32_t count = 0;
uint32_t bytesProcessed = 0;
while( count < packetHeader.count )
{
FFXIVARR_PACKET_RAW rawPacket;
// Copy ipc packet message
const auto packetResult = getPacket( buffer, offset + bytesProcessed, rawPacket );
if( packetResult != Success )
return packetResult;
// NOTE: isn't rawPacket is allocated on stack?
// why is okay to do this?
packets.push_back( rawPacket );
// Add message size and count
bytesProcessed += rawPacket.segHdr.size;
count += 1;
}
// sanity check: check if we processed all bytes.
// this check can fail if size of messages don't add up to size reported from packet header.
if( bytesExpected != bytesProcessed )
return Malformed;
return Success;
}
PacketParseResult getPacket( const std::vector< uint8_t > &buffer, const uint32_t offset,
FFXIVARR_PACKET_RAW &packet )
{
// Copy segment header
const auto headerResult = getSegmentHeader( buffer, offset, packet.segHdr );
if( headerResult != Success )
return headerResult;
// Check header sanity and it's size
if( !checkSegmentHeader( packet.segHdr ) )
return Malformed;
const auto dataOffset = offset + sizeof( struct FFXIVARR_PACKET_SEGMENT_HEADER );
const auto dataSize = packet.segHdr.size;
// Allocate data buffer and copy
packet.data.resize( dataSize );
memcpy( packet.data.data(), buffer.data() + dataOffset, dataSize );
return Success;
}
bool checkHeader( const FFXIVARR_PACKET_HEADER &header )
{
// Max size of the packet is capped at 1MB for now.
if( header.size > 1 * 1024 * 1024 )
return false;
// Max number of message is capped at 255 for now.
if( header.count > 255 )
return false;
return true;
}
bool checkSegmentHeader( const FFXIVARR_PACKET_SEGMENT_HEADER &header )
{
// Max size of individual message is capped at 256KB for now.
if( header.size > 256 * 1024 )
return false;
return true;
}
}
}
return Success;
}
PacketParseResult Core::Network::Packets::getSegmentHeader( const std::vector< uint8_t > &buffer,
const uint32_t offset,
FFXIVARR_PACKET_SEGMENT_HEADER &header )
{
const auto headerSize = sizeof( FFXIVARR_PACKET_SEGMENT_HEADER );
// Check if we have enough bytes in the buffer.
auto remainingBytes = buffer.size() - offset;
if( remainingBytes < headerSize )
return Incomplete;
// Copy segment header
memcpy( &header, buffer.data() + offset, headerSize );
return Success;
}
PacketParseResult Core::Network::Packets::getPackets( const std::vector< uint8_t > &buffer,
const uint32_t offset,
const FFXIVARR_PACKET_HEADER &packetHeader,
std::vector< FFXIVARR_PACKET_RAW > &packets )
{
// sanity check: check there's enough bytes in the buffer
const auto bytesExpected = packetHeader.size - sizeof( struct FFXIVARR_PACKET_HEADER );
if( buffer.size() - offset < bytesExpected )
return Incomplete;
// Loop each message
uint32_t count = 0;
uint32_t bytesProcessed = 0;
while( count < packetHeader.count )
{
FFXIVARR_PACKET_RAW rawPacket;
// Copy ipc packet message
const auto packetResult = getPacket( buffer, offset + bytesProcessed, rawPacket );
if( packetResult != Success )
return packetResult;
// NOTE: isn't rawPacket is allocated on stack?
// why is okay to do this?
packets.push_back( rawPacket );
// Add message size and count
bytesProcessed += rawPacket.segHdr.size;
count += 1;
}
// sanity check: check if we processed all bytes.
// this check can fail if size of messages don't add up to size reported from packet header.
if( bytesExpected != bytesProcessed )
return Malformed;
return Success;
}
PacketParseResult Core::Network::Packets::getPacket( const std::vector< uint8_t > &buffer, const uint32_t offset,
FFXIVARR_PACKET_RAW &packet )
{
// Copy segment header
const auto headerResult = getSegmentHeader( buffer, offset, packet.segHdr );
if( headerResult != Success )
return headerResult;
// Check header sanity and it's size
if( !checkSegmentHeader( packet.segHdr ) )
return Malformed;
const auto dataOffset = offset + sizeof( struct FFXIVARR_PACKET_SEGMENT_HEADER );
const auto dataSize = packet.segHdr.size;
// Allocate data buffer and copy
packet.data.resize( dataSize );
memcpy( packet.data.data(), buffer.data() + dataOffset, dataSize );
return Success;
}
bool Core::Network::Packets::checkHeader( const FFXIVARR_PACKET_HEADER &header )
{
// Max size of the packet is capped at 1MB for now.
if( header.size > 1 * 1024 * 1024 )
return false;
// Max number of message is capped at 255 for now.
if( header.count > 255 )
return false;
return true;
}
bool Core::Network::Packets::checkSegmentHeader( const FFXIVARR_PACKET_SEGMENT_HEADER &header )
{
// Max size of individual message is capped at 256KB for now.
if( header.size > 256 * 1024 )
return false;
return true;
}

View file

@ -2,62 +2,49 @@
#define _GAMEPACKETPARSER_H
#include "CommonNetwork.h"
namespace Core
{
namespace Network
namespace Core {
namespace Network {
namespace Packets {
enum PacketParseResult
{
namespace Packets
{
enum PacketParseResult
{
/// Dissected game packet successfully
Success,
/// Dissected game packet successfully
Success,
/// Buffer is too short to dissect a message.
Incomplete,
/// Invalid data detected.
Malformed
};
/// Buffer is too short to dissect a message.
Incomplete,
/// Read packet header from buffer with given offset.
/// Buffer with given offset must be pointing to start of the new FFXIV packet.
PacketParseResult getHeader(
const std::vector< uint8_t > &buffer,
const uint32_t offset,
FFXIVARR_PACKET_HEADER &header
);
/// Invalid data detected.
Malformed
};
/// Read packet header from buffer with given offset.
/// Buffer with given offset must be pointing to start of FFXIVARR_PACKET_SEGMENT_HEADER data.
/// Keep in mind that this function does check for data validity. Call checkSegmentHeader() if that's needed.
PacketParseResult getSegmentHeader(
const std::vector< uint8_t > &buffer,
const uint32_t offset,
FFXIVARR_PACKET_SEGMENT_HEADER &header
);
/// Read packet header from buffer with given offset.
/// Buffer with given offset must be pointing to start of the new FFXIV packet.
PacketParseResult getHeader( const std::vector< uint8_t > &buffer, const uint32_t offset,
FFXIVARR_PACKET_HEADER &header );
/// Read packets from the buffer with given offset.
/// Buffer with given offset must be pointing to end of FFXIVARR_PACKET_HEADER data.
PacketParseResult getPackets(
const std::vector< uint8_t > &buffer,
const uint32_t offset,
const FFXIVARR_PACKET_HEADER &header,
std::vector< Packets::FFXIVARR_PACKET_RAW > &packets);
/// Read single packet from the buffer with given offset.
/// Buffer with an offset must be pointing to start of FFXIVARR_PACKET_SEGMENT_HEADER data.
PacketParseResult getPacket(
const std::vector< uint8_t > &buffer,
const uint32_t offset,
FFXIVARR_PACKET_RAW &packet
);
/// Read packet header from buffer with given offset.
/// Buffer with given offset must be pointing to start of FFXIVARR_PACKET_SEGMENT_HEADER data.
/// Keep in mind that this function does check for data validity. Call checkSegmentHeader() if that's needed.
PacketParseResult getSegmentHeader( const std::vector< uint8_t > &buffer, const uint32_t offset,
FFXIVARR_PACKET_SEGMENT_HEADER &header );
bool checkHeader(const FFXIVARR_PACKET_HEADER &header);
bool checkSegmentHeader(const FFXIVARR_PACKET_SEGMENT_HEADER &header);
/// Read packets from the buffer with given offset.
/// Buffer with given offset must be pointing to end of FFXIVARR_PACKET_HEADER data.
PacketParseResult getPackets( const std::vector< uint8_t > &buffer, const uint32_t offset,
const FFXIVARR_PACKET_HEADER &header,
std::vector< Packets::FFXIVARR_PACKET_RAW > &packets );
}
}
/// Read single packet from the buffer with given offset.
/// Buffer with an offset must be pointing to start of FFXIVARR_PACKET_SEGMENT_HEADER data.
PacketParseResult getPacket( const std::vector< uint8_t > &buffer, const uint32_t offset,
FFXIVARR_PACKET_RAW &packet );
bool checkHeader(const FFXIVARR_PACKET_HEADER &header);
bool checkSegmentHeader(const FFXIVARR_PACKET_SEGMENT_HEADER &header);
}
}
}

View file

@ -1,13 +1,16 @@
#include "PacketContainer.h"
#include "GamePacket.h"
#include "Common.h"
#include "Forwards.h"
#include <boost/format.hpp>
#include <chrono>
#include <string.h>
#include <memory>
Core::Network::Packets::PacketContainer::PacketContainer()
Core::Network::Packets::PacketContainer::PacketContainer( uint32_t segmentTargetOverride ) :
m_segmentTargetOverride( segmentTargetOverride )
{
memset( &m_ipcHdr, 0, sizeof( FFXIVARR_PACKET_HEADER ) );
m_ipcHdr.size = sizeof( FFXIVARR_PACKET_HEADER );
@ -19,18 +22,18 @@ Core::Network::Packets::PacketContainer::~PacketContainer()
m_entryList.clear();
}
void Core::Network::Packets::PacketContainer::addPacket( GamePacket pEntry )
void Core::Network::Packets::PacketContainer::addPacket( Core::Network::Packets::FFXIVPacketBasePtr entry )
{
m_entryList.push_back( pEntry );
m_entryList.push_back( entry );
m_ipcHdr.size += pEntry.getSize();
m_ipcHdr.size += entry->getSize();
m_ipcHdr.count++;
}
void Core::Network::Packets::PacketContainer::fillSendBuffer( std::vector< uint8_t >& sendBuffer )
{
uint8_t* tempBuffer = new uint8_t[m_ipcHdr.size];
memset( tempBuffer, 0, m_ipcHdr.size );
std::vector< uint8_t > tempBuffer( m_ipcHdr.size );
memset( &tempBuffer[0], 0, m_ipcHdr.size );
using namespace std::chrono;
auto ms = duration_cast< milliseconds >( system_clock::now().time_since_epoch() );
@ -40,23 +43,29 @@ void Core::Network::Packets::PacketContainer::fillSendBuffer( std::vector< uint8
m_ipcHdr.timestamp = tick;
m_ipcHdr.unknown_20 = 1;
memcpy( tempBuffer, &m_ipcHdr, sizeof( FFXIVARR_PACKET_HEADER ) );
memcpy( &tempBuffer[0], &m_ipcHdr, sizeof( FFXIVARR_PACKET_HEADER ) );
auto it = m_entryList.begin();
uint16_t offset = 0;
std::size_t offset = 0;
if( m_entryList.size() > 1 )
offset = 0;
for( ; it != m_entryList.end(); ++it )
{
memcpy( tempBuffer + sizeof( FFXIVARR_PACKET_HEADER ) + offset, it->getData(), it->m_segHdr.size );
offset += it->m_segHdr.size;
auto pPacket = (*it);
if( m_segmentTargetOverride != 0 && pPacket->getSegmentType() == SEGMENTTYPE_IPC )
{
pPacket->setTargetActor( m_segmentTargetOverride );
}
auto data = pPacket->getData();
memcpy( &tempBuffer[0] + sizeof( FFXIVARR_PACKET_HEADER ) + offset, &data[0], pPacket->getSize() );
offset += pPacket->getSize();
}
sendBuffer.assign( tempBuffer, tempBuffer + m_ipcHdr.size );
delete[] tempBuffer;
sendBuffer.assign( &tempBuffer[0], &tempBuffer[0] + m_ipcHdr.size );
}

View file

@ -5,30 +5,34 @@
#include "Common.h"
#include "CommonNetwork.h"
#include "GamePacket.h"
#include "GamePacketNew.h"
#include "Forwards.h"
namespace Core {
namespace Network {
namespace Packets {
class GamePacket;
typedef boost::shared_ptr< FFXIVPacketBase > FFXIVPacketBasePtr;
class PacketContainer
{
public:
PacketContainer();
PacketContainer( uint32_t segmentTargetOverride = 0 );
~PacketContainer();
void addPacket( GamePacket pEntry );
void addPacket( FFXIVPacketBasePtr entry );
FFXIVARR_PACKET_HEADER m_ipcHdr;
std::vector< GamePacket > m_entryList;
std::vector< FFXIVPacketBasePtr > m_entryList;
std::string toString();
void fillSendBuffer( std::vector< uint8_t >& sendBuffer );
private:
uint32_t m_segmentTargetOverride;
};
}

View file

@ -20,7 +20,7 @@ struct FFXIVIpcTell : FFXIVIpcBasePacket<Tell>
uint16_t u2b;
uint8_t preName;
uint8_t u3a;
uint8_t u3b;
uint8_t u3b; //Setting this to 1 seems to mark the tell as a GM tell (More research needed)
char receipientName[32];
char msg[1031];
};

View file

@ -14,13 +14,13 @@ namespace Packets {
*/
enum ServerLobbyIpcType : uint16_t
{
LobbyError = 0x0002,
LobbyServiceAccountList = 0x000C,
LobbyCharList = 0x000D,
LobbyCharCreate = 0x000E,
LobbyEnterWorld = 0x000F,
LobbyServerList = 0x0015,
LobbyRetainerList = 0x0017,
LobbyError = 0x0002,
LobbyServiceAccountList = 0x000C,
LobbyCharList = 0x000D,
LobbyCharCreate = 0x000E,
LobbyEnterWorld = 0x000F,
LobbyServerList = 0x0015,
LobbyRetainerList = 0x0017,
};
@ -29,12 +29,12 @@ namespace Packets {
*/
enum ClientLobbyIpcType : uint16_t
{
ReqCharList = 0x0003,
ReqEnterWorld = 0x0004,
ReqServiceAccountList = 0x0005,
ReqCharList = 0x0003,
ReqEnterWorld = 0x0004,
ReqServiceAccountList = 0x0005,
ReqCharDelete = 0x000A,
ReqCharCreate = 0x000B,
ReqCharDelete = 0x000A,
ReqCharCreate = 0x000B,
};
////////////////////////////////////////////////////////////////////////////////
@ -46,134 +46,150 @@ namespace Packets {
{
// static opcode ( the ones that rarely, if ever, change )
Ping = 0x0065,
Init = 0x0066,
Ping = 0x0065,
Init = 0x0066,
ActorFreeSpawn = 0x0191,
InitZone = 0x019A,
ActorFreeSpawn = 0x0191,
InitZone = 0x019A,
AddStatusEffect = 0x0141,
ActorControl142 = 0x0142,
ActorControl143 = 0x0143,
ActorControl144 = 0x0144,
UpdateHpMpTp = 0x0145,
AddStatusEffect = 0x0141,
ActorControl142 = 0x0142,
ActorControl143 = 0x0143,
ActorControl144 = 0x0144,
UpdateHpMpTp = 0x0145,
///////////////////////////////////////////////////
ChatBanned = 0x006B,
Logout = 0x0077, // updated 4.3
CFNotify = 0x0078,
CFMemberStatus = 0x0079,
CFDutyInfo = 0x007A,
CFPlayerInNeed = 0x007F,
ChatBanned = 0x006B,
Logout = 0x0077, // updated 4.3
CFNotify = 0x0078,
CFMemberStatus = 0x0079,
CFDutyInfo = 0x007A,
CFPlayerInNeed = 0x007F,
Playtime = 0x00DF, // updated 4.2
CFRegistered = 0x00B8, // updated 4.1
CancelAllianceForming = 0x00C6, // updated 4.2
SocialRequestError = 0x00AD,
Chat = 0x00F7, // updated 4.3
SocialList = 0x00FD, // updated 4.3
CFRegistered = 0x00B8, // updated 4.1
CancelAllianceForming = 0x00C6, // updated 4.2
UpdateSearchInfo = 0x0100, // updated 4.3
InitSearchInfo = 0x0101, // updated 4.3
Playtime = 0x00F5, // updated 4.3
Chat = 0x00F7, // updated 4.3
SocialRequestResponse = 0x00FB, // fake // updated 4.36
SocialRequestReceive = 0x00FC, // fake // updated 4.36
SocialList = 0x00FD, // updated 4.3
ServerNotice = 0x0106, // updated 4.3
SetOnlineStatus = 0x0107, // updated 4.3
UpdateSearchInfo = 0x0100, // updated 4.3
InitSearchInfo = 0x0101, // updated 4.3
CountdownInitiate = 0x0111, // updated 4.3
CountdownCancel = 0x0112, // updated 4.3
ServerNotice = 0x0106, // updated 4.3
SetOnlineStatus = 0x0107, // updated 4.3
BlackList = 0x0115, // updated 4.3
CountdownInitiate = 0x0111, // updated 4.3
CountdownCancel = 0x0112, // updated 4.3
LogMessage = 0x00D0,
BlackList = 0x0115, // updated 4.3
LinkshellList = 0x011C, // updated 4.3
SetCharaFCTag = 0x013B, // updated 4.3
SetFreeCompanyInfo = 0x013D, // updated 4.3
LogMessage = 0x00D0,
StatusEffectList = 0x014E, // updated 4.3
Effect = 0x0151, // updated 4.3
PersistantEffect = 0x0158, // updated 4.3
LinkshellList = 0x011C, // updated 4.3
CharaFreeCompanyTag = 0x013B, // updated 4.3
FreeCompanyBoardMsg = 0x013C, // updated 4.3
FreeCompanyInfo = 0x013D, // updated 4.3
GCAffiliation = 0xCCFC, // OUTDATED
StatusEffectList = 0x014E, // updated 4.3
Effect = 0x0151, // updated 4.3
AoeEffect8 = 0x0154, // updated 4.3
AoeEffect16 = 0x0155, // updated 4.3
AoeEffect24 = 0x0156, // updated 4.3
AoeEffect32 = 0x0157, // updated 4.3
PersistantEffect = 0x0158, // updated 4.3
PlayerSpawn = 0x0172, // updated 4.3
NpcSpawn = 0x0173, // updated 4.3
ActorMove = 0x0174, // updated 4.3
ActorSetPos = 0x0176, // updated 4.3
GCAffiliation = 0x0162, // updated 4.3
ActorCast = 0x0178, // updated 4.3
PlayerSpawn = 0x0172, // updated 4.3
NpcSpawn = 0x0173, // updated 4.3
ActorMove = 0x0174, // updated 4.3
ActorSetPos = 0x0176, // updated 4.3
HateList = 0x017B, // updated 4.3
ActorCast = 0x0178, // updated 4.3
ObjectSpawn = 0x017D, // updated 4.3
ObjectDespawn = 0x017E, // updated 4.3
PartyList = 0x017A, // updated 4.3
HateList = 0x017B, // updated 4.3
InventoryActionAck = 0x0180, // updated 4.2 ?
ObjectSpawn = 0x017D, // updated 4.3
ObjectDespawn = 0x017E, // updated 4.3
InitUI = 0x0181, // updated 4.3
PlayerStats = 0x0182, // updated 4.3
ActorOwner = 0x0183, // updated 4.3 ?
PlayerStateFlags = 0x0184, // updated 4.3
PlayerClassInfo = 0x0185, // updated 4.3
ModelEquip = 0x0186, // updated 4.3
SetLevelSync = 0x017F, // updated 4.3
SilentSetClassJob = 0x0180, // updated 4.3 - seems to be the case, not sure if it's actually used for anything
UpdateClassInfo = 0x018A, // updated 4.3
InitUI = 0x0181, // updated 4.3
PlayerStats = 0x0182, // updated 4.3
ActorOwner = 0x0183, // updated 4.3 ?
PlayerStateFlags = 0x0184, // updated 4.3
PlayerClassInfo = 0x0185, // updated 4.3
ModelEquip = 0x0186, // updated 4.3
ItemInfo = 0x0190, // updated 4.3
ContainerInfo = 0x0192, // updated 4.3
InventoryTransactionFinish = 0x0193, // updated 4.3
InventoryTransaction = 0x0194, // updated 4.3
CurrencyCrystalInfo = 0x0197, // updated 4.3
UpdateClassInfo = 0x018A, // updated 4.3
UpdateInventorySlot = 0x0198, // updated 4.3
ItemInfo = 0x0190, // updated 4.3
ContainerInfo = 0x0192, // updated 4.3
InventoryTransactionFinish = 0x0193, // updated 4.3
InventoryTransaction = 0x0194, // updated 4.3
CurrencyCrystalInfo = 0x0195, // updated 4.3
InventoryActionAck = 0x0197, // updated 4.3
UpdateInventorySlot = 0x0198, // updated 4.3
EventPlay = 0x01A6, // updated 4.3
DirectorPlayScene = 0x01AA, // updated 4.3
EventPlay = 0x01A6, // updated 4.3
EventOpenGilShop = 0x01AD, // updated 4.3
DirectorPlayScene = 0x01AA, // updated 4.3
EventStart = 0x01AF, // updated 4.3
EventFinish = 0x01B0, // updated 4.3
EventStart = 0x01AF, // updated 4.3
EventFinish = 0x01B0, // updated 4.3
EventLinkshell = 0x1169,
EventLinkshell = 0x1169,
QuestActiveList = 0x01C3, // updated 4.3
QuestUpdate = 0x01C4, // updated 4.3
QuestCompleteList = 0x01C5, // updated 4.3
QuestActiveList = 0x01C3, // updated 4.3
QuestUpdate = 0x01C4, // updated 4.3
QuestCompleteList = 0x01C5, // updated 4.3
QuestFinish = 0x01C6, // updated 4.3
MSQTrackerComplete = 0x01C7, // updated 4.3
MSQTrackerProgress = 0x01C8, // updated 4.3
QuestFinish = 0x01C6, // updated 4.3
MSQTrackerComplete = 0x01C7, // updated 4.3
MSQTrackerProgress = 0x01C8, // updated 4.3
QuestMessage = 0x01CE, // updated 4.3
QuestMessage = 0x01CE, // updated 4.3
QuestTracker = 0x01D3, // updated 4.3
QuestTracker = 0x01D3, // updated 4.3
Mount = 0x01E3, // updated 4.3
Mount = 0x01E3, // updated 4.3
DirectorVars = 0x01E5, // updated 4.3
DirectorVars = 0x01E5, // updated 4.3
CFAvailableContents = 0x01FD, // updated 4.2
CFAvailableContents = 0x01FD, // updated 4.2
WeatherChange = 0x0200, // updated 4.3
PlayerTitleList = 0x0201, // updated 4.3
Discovery = 0x0202, // updated 4.3
WeatherChange = 0x0200, // updated 4.3
PlayerTitleList = 0x0201, // updated 4.3
Discovery = 0x0202, // updated 4.3
EorzeaTimeOffset = 0x0204, // updated 4.3
EorzeaTimeOffset = 0x0204, // updated 4.3
EquipDisplayFlags = 0x0210, // updated 4.3
EquipDisplayFlags = 0x0210, // updated 4.3
DuelChallenge = 0x0277, // 4.2; this is responsible for opening the ui
PerformNote = 0x0286, // updated 4.3
WardInfo = 0x0224, // updated 4.3
WardHousingPermission = 0x022D, // updated 4.3
WardYardInfo = 0x022F, // updated 4.3
PrepareZoning = 0x0291, // updated 4.3
ActorGauge = 0x0292, // updated 4.3
DuelChallenge = 0x0277, // 4.2; this is responsible for opening the ui
PerformNote = 0x0286, // updated 4.3
PrepareZoning = 0x0291, // updated 4.3
ActorGauge = 0x0292, // updated 4.3
// Unknown IPC types that still need to be sent
// TODO: figure all these out properly
IPCTYPE_UNK_320 = 0x024C, // updated 4.3
IPCTYPE_UNK_322 = 0x024E, // updated 4.3
IPCTYPE_UNK_320 = 0x024C, // updated 4.3
IPCTYPE_UNK_322 = 0x024E, // updated 4.3
};
@ -183,71 +199,80 @@ namespace Packets {
enum ClientZoneIpcType : uint16_t
{
PingHandler = 0x0065, // unchanged 4.3
InitHandler = 0x0066, // unchanged 4.3
PingHandler = 0x0065, // unchanged 4.3
InitHandler = 0x0066, // unchanged 4.3
FinishLoadingHandler = 0x0069, // unchanged 4.3
FinishLoadingHandler = 0x0069, // unchanged 4.3
CFCommenceHandler = 0x006F,
CFCommenceHandler = 0x006F,
CFRegisterDuty = 0x0071,
CFRegisterRoulette = 0x0072,
PlayTimeHandler = 0x0073, // unchanged 4.3
LogoutHandler = 0x0074, // unchanged 4.3
CFRegisterDuty = 0x0071,
CFRegisterRoulette = 0x0072,
PlayTimeHandler = 0x0073, // unchanged 4.3
LogoutHandler = 0x0074, // unchanged 4.3
CFDutyInfoHandler = 0x0078, // updated 4.2
CFDutyInfoHandler = 0x0078, // updated 4.2
SocialReqSendHandler = 0x00AE, // updated 4.1
CreateCrossWorldLS = 0x00AF, // updated 4.3
SocialReqSendHandler = 0x00AE, // updated 4.1
SocialReqProcessHandler = 0x00AB, // fake
SocialReqRemoveHandler = 0x00AC, // fake
CreateCrossWorldLS = 0x00AF, // updated 4.3
ChatHandler = 0x00D3, // updated 4.3
ChatHandler = 0x00D3, // updated 4.3
SocialListHandler = 0x00DB, // updated 4.3
ReqSearchInfoHandler = 0x00E0, // updated 4.3
SetSearchInfoHandler = 0x00DE, // updated 4.3
SocialListHandler = 0x00DB, // updated 4.3
ReqSearchInfoHandler = 0x00E0, // updated 4.3
SetSearchInfoHandler = 0x00DE, // updated 4.3
BlackListHandler = 0x00EC, // updated 4.3
PlayerSearchHandler = 0x00E2, // updated 4.2
BlackListHandler = 0x00EC, // updated 4.3
PlayerSearchHandler = 0x00E2, // updated 4.2
LinkshellListHandler = 0x00F4, // updated 4.3
LinkshellListHandler = 0x00F4, // updated 4.3
FcInfoReqHandler = 0x011A, // updated 4.2
SearchMarketboard = 0x0103, // updated 4.3
FcInfoReqHandler = 0x011A, // updated 4.2
ReqJoinNoviceNetwork = 0x0129, // updated 4.2
ReqCountdownInitiate = 0x012C, // updated 4.2
ReqCountdownCancel = 0x012D, // updated 4.2
ReqMarketWishList = 0x012C, // updated 4.3
ZoneLineHandler = 0x013C, // updated 4.3
ActionHandler = 0x013D, // updated 4.3
DiscoveryHandler = 0x013E, // updated 4.3
ReqJoinNoviceNetwork = 0x0129, // updated 4.2
SkillHandler = 0x0140, // updated 4.3
GMCommand1 = 0x0141, // updated 4.3
GMCommand2 = 0x0142, // updated 4.3
ReqCountdownInitiate = 0x0138, // updated 4.3
ReqCountdownCancel = 0x0139, // updated 4.3
ClearWaymarks = 0x013A, // updated 4.3
UpdatePositionHandler = 0x0144, // updated 4.3
UpdatePositionInstance = 0x0183, // updated 4.3
ZoneLineHandler = 0x013C, // updated 4.3
ClientTrigger = 0x013D, // updated 4.3
DiscoveryHandler = 0x013E, // updated 4.3
InventoryModifyHandler = 0x014B, // updated 4.3
AddWaymark = 0x013F, // updated 4.3
TalkEventHandler = 0x0154, // updated 4.3
EmoteEventHandler = 0x0155, // updated 4.3
WithinRangeEventHandler = 0x0156, // updated 4.3
OutOfRangeEventHandler = 0x0157, // updated 4.3
EnterTeriEventHandler = 0x0158, // updated 4.3
SkillHandler = 0x0140, // updated 4.3
GMCommand1 = 0x0141, // updated 4.3
GMCommand2 = 0x0142, // updated 4.3
ReturnEventHandler = 0x015D, // updated 4.3
TradeReturnEventHandler = 0x015E, // updated 4.3
UpdatePositionHandler = 0x0144, // updated 4.3
UpdatePositionInstance = 0x0183, // updated 4.3
LinkshellEventHandler = 0x0150, // updated 4.1 ??
LinkshellEventHandler1 = 0x0151, // updated 4.1 ??
InventoryModifyHandler = 0x014B, // updated 4.3
PerformNoteHandler = 0x029B, // updated 4.3
TalkEventHandler = 0x0154, // updated 4.3
EmoteEventHandler = 0x0155, // updated 4.3
WithinRangeEventHandler = 0x0156, // updated 4.3
OutOfRangeEventHandler = 0x0157, // updated 4.3
EnterTeriEventHandler = 0x0158, // updated 4.3
ReqEquipDisplayFlagsChange = 0x0178, // updated 4.3
ReturnEventHandler = 0x015D, // updated 4.3
TradeReturnEventHandler = 0x015E, // updated 4.3
LinkshellEventHandler = 0x0150, // updated 4.1 ??
LinkshellEventHandler1 = 0x0151, // updated 4.1 ??
PerformNoteHandler = 0x029B, // updated 4.3
ReqEquipDisplayFlagsChange = 0x0178, // updated 4.3
};
@ -259,8 +284,8 @@ namespace Packets {
*/
enum ServerChatIpcType : uint16_t
{
Tell = 0x0064, // updated for sb
TellErrNotFound = 0x0066,
Tell = 0x0064, // updated for sb
TellErrNotFound = 0x0066,
};
/**
@ -268,7 +293,7 @@ namespace Packets {
*/
enum ClientChatIpcType : uint16_t
{
TellReq = 0x0064,
TellReq = 0x0064,
};

View file

@ -91,7 +91,7 @@ struct FFXIVIpcCharList : FFXIVIpcBasePacket<LobbyCharList>
char nameChara[32];
char nameServer[32];
char nameServer1[32];
char charDetailJson[1030];
char charDetailJson[1028];
} charaDetails[2];
};

View file

@ -0,0 +1,173 @@
#ifndef _CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H
#define _CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H
#include <Common.h>
#include <Network/CommonNetwork.h>
namespace Core {
namespace Network {
namespace Packets {
namespace Client {
struct FFXIVIpcGmCommand1 : FFXIVIpcBasePacket< GMCommand1 >
{
/* 0000 */ uint32_t commandId;
/* 0004 */ uint32_t param1;
/* 0008 */ uint32_t param2;
/* 000C */ uint8_t unknown_C[0xC];
/* 0018 */ uint32_t param3;
};
struct FFXIVIpcGmCommand2 : FFXIVIpcBasePacket< GMCommand2 >
{
/* 0000 */ uint32_t commandId;
/* 0004 */ char unk_4[0x10];
/* 0014 */ char param1[0x20];
};
struct FFXIVIpcClientTrigger : FFXIVIpcBasePacket< ClientTrigger >
{
/* 0000 */ uint16_t commandId;
/* 0002 */ uint8_t unk_2[2];
/* 0004 */ uint32_t param11;
/* 0008 */ uint32_t param12;
/* 000C */ uint32_t param2;
/* 0010 */ char unk_10[8];
/* 0018 */ uint64_t param3;
};
struct FFXIVIpcSkillHandler : FFXIVIpcBasePacket< SkillHandler >
{
/* 0000 */ char pad_0000[1];
/* 0001 */ uint8_t type;
/* 0002 */ char pad_0002[2];
/* 0004 */ uint32_t actionId;
/* 0008 */ uint32_t useCount;
/* 000C */ char pad_000C[4];
/* 0010 */ uint64_t targetId;
};
struct FFXIVIpcZoneLineHandler : FFXIVIpcBasePacket< ZoneLineHandler >
{
/* 0000 */ uint32_t zoneLineId;
};
struct FFXIVIpcDiscoveryHandler : FFXIVIpcBasePacket< DiscoveryHandler >
{
/* 0000 */ uint32_t positionRef;
};
struct FFXIVIpcEventHandlerReturn : FFXIVIpcBasePacket< ReturnEventHandler >
{
/* 0000 */ uint32_t eventId;
/* 0004 */ uint16_t scene;
/* 0006 */ uint16_t param1;
/* 0008 */ uint16_t param2;
/* 000A */ char pad_000A[2];
/* 000C */ uint16_t param3;
/* 000E */ char pad_000E[2];
/* 0010 */ uint16_t param4;
};
struct FFXIVIpcEnterTerritoryHandler : FFXIVIpcBasePacket< EnterTeriEventHandler >
{
/* 0000 */ uint32_t eventId;
/* 0004 */ uint16_t param1;
/* 0006 */ uint16_t param2;
};
struct FFXIVIpcEventHandlerOutsideRange : FFXIVIpcBasePacket< OutOfRangeEventHandler >
{
/* 0000 */ uint32_t param1;
/* 0004 */ uint32_t eventId;
/* 0008 */ Common::FFXIVARR_POSITION3 position;
};
struct FFXIVIpcEventHandlerWithinRange : FFXIVIpcBasePacket< WithinRangeEventHandler >
{
/* 0000 */ uint32_t param1;
/* 0004 */ uint32_t eventId;
/* 0008 */ Common::FFXIVARR_POSITION3 position;
};
struct FFXIVIpcEventHandlerEmote : FFXIVIpcBasePacket< EmoteEventHandler >
{
/* 0000 */ uint64_t actorId;
/* 0008 */ uint32_t eventId;
/* 000C */ uint16_t emoteId;
};
struct FFXIVIpcEventHandlerTalk : FFXIVIpcBasePacket< TalkEventHandler >
{
/* 0000 */ uint64_t actorId;
/* 0008 */ uint32_t eventId;
};
struct FFXIVIpcPingHandler : FFXIVIpcBasePacket< PingHandler >
{
/* 0000 */ uint32_t timestamp; // maybe lol..
};
struct FFXIVIpcSetSearchInfo : FFXIVIpcBasePacket< SetSearchInfoHandler >
{
union
{
/* 0000 */ uint64_t status;
struct
{
/* 0000 */ uint32_t status1;
/* 0004 */ uint32_t status2;
};
};
/* 0008 */ char pad_0008[9];
/* 0011 */ Common::ClientLanguage language;
/* 0012 */ char searchComment[193];
};
struct FFXIVIpcTellHandler : FFXIVIpcBasePacket< TellReq >
{
/* 0000 */ char pad_0000[4];
/* 0004 */ char targetPCName[32];
/* 0024 */ char message[1012];
};
struct FFXIVIpcChatHandler : FFXIVIpcBasePacket< ChatHandler >
{
/* 0000 */ char pad_0000[4];
/* 0004 */ uint32_t sourceId;
/* 0008 */ char pad_0008[16];
/* 0018 */ Common::ChatType chatType;
/* 001A */ char message[1012];
};
struct FFXIVIpcLinkshellEventHandler : FFXIVIpcBasePacket< LinkshellEventHandler >
{
/* 0000 */ uint32_t eventId;
/* 0004 */ uint16_t scene;
/* 0006 */ char pad_0006[1];
/* 0007 */ char lsName[21];
};
struct FFXIVIpcInventoryModifyHandler : FFXIVIpcBasePacket< InventoryModifyHandler >
{
/* 0000 */ uint32_t seq;
/* 0004 */ Common::InventoryOperation action;
/* 0005 */ char pad_0005[7];
/* 000C */ uint16_t fromContainer;
/* 000E */ char pad_000E[2];
/* 0010 */ uint8_t fromSlot;
/* 0011 */ char pad_0011[15];
/* 0020 */ uint16_t toContainer;
/* 0022 */ char pad_0022[2];
/* 0024 */ uint8_t toSlot;
/* 0025 */ uint8_t pad_0025[3];
/* 0028 */ uint32_t splitCount;
};
}
}
}
}
#endif //_CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H

View file

@ -350,38 +350,77 @@ struct FFXIVIpcUpdateHpMpTp : FFXIVIpcBasePacket<UpdateHpMpTp>
* Structural representation of the packet sent by the server
* for battle actions
*/
struct effectEntry
struct EffectEntry
{
Common::ActionEffectType effectType;
Common::ActionHitSeverityType hitSeverity;
uint8_t unknown_3;
int8_t bonusPercent;
int16_t value;
uint8_t param;
int8_t bonusPercent; // shows an additional percentage in the battle log, will not change the damage number sent & shown
uint8_t valueMultiplier; // This multiplies whatever value is in the 'value' param by 10. Possibly a workaround for big numbers
uint8_t unknown_6;
uint8_t flags;
int16_t value;
};
struct EffectHeader
{
uint64_t animationTargetId; // who the animation targets
uint32_t actionId; // what the casting player casts, shown in battle log/ui
uint32_t globalEffectCounter; // seems to only increment on retail?
float animationLockTime; // maybe? doesn't seem to do anything
uint32_t someTargetId; // always 00 00 00 E0, 0x0E000000 is the internal def for INVALID TARGET ID
uint16_t hiddenAnimation; // if 0, always shows animation, otherwise hides it. counts up by 1 for each animation skipped on a caster
uint16_t rotation;
uint16_t actionAnimationId; // the animation that is played by the casting character
uint8_t unknown1E; // can be 0,1,2 - maybe other values? - doesn't do anything?
Common::ActionEffectDisplayType effectDisplayType;
uint8_t unknown20; // is read by handler, runs code which gets the LODWORD of animationLockTime (wtf?)
uint8_t effectCount; // ignores effects if 0, otherwise parses all of them
uint32_t padding_22[2];
};
struct FFXIVIpcEffect : FFXIVIpcBasePacket<Effect>
{
uint32_t targetId;
uint32_t unknown_1;
uint32_t actionAnimationId;
uint32_t unknown_2;
uint32_t unknown_5;
uint32_t unknown_6;
uint32_t effectTargetId;
uint16_t rotation;
uint16_t actionTextId;
uint8_t unknown_61;
uint8_t unknown_62;
uint8_t unknown_10;
uint8_t numEffects;
uint32_t u11;
effectEntry effects[8];
uint32_t effectTarget;
uint64_t unknown_8;
EffectHeader header;
EffectEntry effects[8];
uint16_t padding_6A[3];
uint32_t effectTargetId; // who the effect targets
uint32_t effectFlags; // nonzero = effects do nothing, no battle log, no ui text - only shows animations
uint32_t padding_78;
};
template< int size >
struct FFXIVIpcAoeEffect
{
EffectHeader header;
EffectEntry effects[size];
uint16_t padding_6A[3];
uint32_t effectTargetId[size];
Common::FFXIVARR_POSITION3 position;
uint32_t effectFlags;
uint32_t padding_78;
};
struct FFXIVIpcAoeEffect8 : FFXIVIpcBasePacket< AoeEffect8 >, FFXIVIpcAoeEffect< 8 > {};
struct FFXIVIpcAoeEffect16 : FFXIVIpcBasePacket< AoeEffect16 >, FFXIVIpcAoeEffect< 16 > {};
struct FFXIVIpcAoeEffect24 : FFXIVIpcBasePacket< AoeEffect24 >, FFXIVIpcAoeEffect< 24 > {};
struct FFXIVIpcAoeEffect32 : FFXIVIpcBasePacket< AoeEffect32 >, FFXIVIpcAoeEffect< 32 > {};
/**
* Structural representation of the packet sent by the server
@ -432,7 +471,7 @@ struct FFXIVIpcPlayerSpawn : FFXIVIpcBasePacket<PlayerSpawn>
uint16_t activeMinion;
uint8_t spawnIndex;
uint8_t state;
uint8_t persistantEmote;
uint8_t persistentEmote;
uint8_t modelType; // modelType -> eventSystemDefine
uint8_t subtype;
uint8_t voice;
@ -492,8 +531,8 @@ struct FFXIVIpcNpcSpawn : FFXIVIpcBasePacket<NpcSpawn>
uint32_t u18;
uint32_t u19;
uint32_t directorId;
uint32_t ownerId;
uint32_t u22;
uint32_t spawnerId;
uint32_t parentActorId;
uint32_t hPMax;
uint32_t hPCurr;
uint32_t displayFlags;
@ -532,6 +571,11 @@ struct FFXIVIpcNpcSpawn : FFXIVIpcBasePacket<NpcSpawn>
uint8_t look[26];
char fcTag[6];
uint32_t unk30;
uint32_t unk31;
uint8_t bNPCPartSlot;
uint8_t unk32;
uint16_t unk33;
uint32_t unk34;
};
/**
@ -663,146 +707,142 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
// plain C types for a bit until the packet is actually fixed.
// makes conversion between different editors easier.
uint64_t contentId;
uint32_t unknown8;
uint32_t unknownC;
uint32_t charId;
uint32_t restedExp;
uint32_t companionCurrentExp;
uint32_t unknown3C;
uint32_t fishCaught;
uint32_t useBaitCatalogId;
uint32_t pvpWolfFoldMatches;
uint16_t pvpWolfFoldWeeklyMatches;
uint16_t pvpWolfFoldWeeklyVictories;
uint16_t pvpStats[6];
uint16_t playerCommendations;
uint16_t pvpStats1;
uint16_t frontlineCampaigns[4];
uint16_t frontlineCampaignsWeekly;
uint16_t currentRelic;
uint16_t currentBook;
uint16_t masterCrafterMask;
uint16_t unknown69;
uint16_t unknown6A;
uint16_t unknown6B;
uint16_t unknown6C[4];
uint16_t unknown50[34];
uint16_t unknown18;
uint16_t maxLevel;
uint16_t expansion;
uint16_t unknown76;
uint16_t race;
uint16_t tribe;
uint16_t gender;
uint16_t currentJob;
uint16_t currentClass;
uint16_t deity;
uint16_t namedayMonth;
uint16_t namedayDay;
uint16_t cityState;
uint16_t homepoint;
uint16_t unknown26;
uint16_t petHotBar;
uint16_t companionRank;
uint16_t companionStars;
uint16_t companionSp;
uint16_t companionUnk2B;
uint16_t companionColor;
uint16_t companionFavoFeed;
uint16_t companionUnk89;
uint16_t companionUnk90[5];
uint16_t unknown90[7];
uint16_t unknown9E;
uint16_t unknownA0;
uint32_t exp[25];
uint16_t unknown564[16];
uint32_t pvpFrontlineOverall1st;
uint32_t pvpFrontlineOverall2nd;
uint32_t pvpFrontlineOverall3rd;
uint16_t relicBookCompletion1[4];
uint16_t levels[25];
uint16_t levelsPadding;
uint16_t unknown15C[8];
uint16_t fishingRecordsFish[26];
uint16_t fishingRecordsFishWeight[26];
uint16_t unknownMask554[44];
uint16_t companion_name[21];
uint16_t companionDefRank;
uint16_t companionAttRank;
uint16_t companionHealRank;
uint16_t mountGuideMask[16];
unsigned int unknown8;
unsigned int unknownC;
unsigned int charId;
unsigned int restedExp;
unsigned int companionCurrentExp;
unsigned int unknown1C;
unsigned int fishCaught;
unsigned int useBaitCatalogId;
unsigned int unknown28;
unsigned short unknownPvp2C;
unsigned short unknown3;
unsigned int pvpFrontlineOverallCampaigns;
unsigned int unknownTimestamp34;
unsigned int unknownTimestamp38;
unsigned int unknown3C;
unsigned int unknown40;
unsigned int unknown44;
float companionTimePassed;
unsigned int unknown4C;
unsigned short unknown50;
unsigned short unknownPvp52[4];
unsigned short playerCommendations;
unsigned short unknown5C;
unsigned short unknown5E;
unsigned short pvpFrontlineWeeklyCampaigns;
unsigned short enhancedAnimaGlassProgress;
unsigned short unknown64[4]; // needs confirmation, probably pvp total/weeklies
unsigned short pvpRivalWingsTotalMatches;
unsigned short pvpRivalWingsTotalVictories;
unsigned short pvpRivalWingsWeeklyMatches; // needs confirmation
unsigned short pvpRivalWingsWeeklyVictories; // needs confirmation
unsigned char maxLevel;
unsigned char expansion;
unsigned char unknown76;
unsigned char race;
unsigned char tribe;
unsigned char gender;
unsigned char currentJob;
unsigned char currentClass;
unsigned char deity;
unsigned char namedayMonth;
unsigned char namedayDay;
unsigned char cityState;
unsigned char homepoint;
unsigned char unknown81;
unsigned char petHotBar;
unsigned char companionRank;
unsigned char companionStars;
unsigned char companionSp;
unsigned char companionUnk86;
unsigned char companionColor;
unsigned char companionFavoFeed;
unsigned char unknown89;
unsigned char unknown8A[4];
unsigned char hasRelicBook;
unsigned char relicBookId;
unsigned char unknown90[4];
unsigned char craftingMasterMask;
unsigned char unknown95[10];
unsigned char unknown9F[2];
unsigned char unknownA1[3];
unsigned int exp[25];
unsigned int unknown108;
unsigned int pvpTotalExp;
unsigned int unknownPvp110;
unsigned int pvpExp;
unsigned int pvpFrontlineOverallRanks[3];
unsigned int exploratoryMissionNextTimestamp;
unsigned short levels[25];
unsigned short unknown15C[9];
unsigned short fishingRecordsFish[26];
unsigned short fishingRecordsFishWeight[26];
unsigned short beastExp[11];
unsigned short unknown1EA[5];
unsigned short pvpFrontlineWeeklyRanks[3];
unsigned short unknownMask1FA[3];
unsigned char companionName[21];
unsigned char companionDefRank;
unsigned char companionAttRank;
unsigned char companionHealRank;
unsigned char mountGuideMask[16];
char name[32];
uint16_t unknownOword[16];
uint16_t unknown258;
uint16_t unlockBitmask[64];
uint16_t aetheryte[17];
uint16_t discovery[421];
uint16_t howto[33];
uint16_t minions[38];
uint16_t chocoboTaxiMask[8];
uint16_t contentClearMask[111];
uint16_t contentClearPadding;
uint16_t unknown428[8];
uint16_t companionBardingMask[8];
uint16_t companionEquippedHead;
uint16_t companionEquippedBody;
uint16_t companionEquippedFeet;
uint16_t companionUnk4[4];
uint16_t companion_fields[11];
uint16_t fishingGuideMask[89];
uint16_t fishingSpotVisited[25];
uint16_t unknownMask4Padding;
uint16_t rankAmalJaa;
uint16_t rankSylph;
uint16_t rankKobold;
uint16_t rankSahagin;
uint16_t rankIxal;
uint16_t rankVanu;
uint16_t rankVath;
uint16_t rankMoogle;
uint16_t rankKojin;
uint16_t rankAnata;
uint16_t expAmalJaa;
uint16_t expSylph;
uint16_t expKobold;
uint16_t expSahagin;
uint16_t expIxal;
uint16_t expVanu;
uint16_t expVath;
uint16_t expMoogle;
uint16_t expKojin;
uint16_t expAnata;
uint16_t unknown596[10];
uint16_t unknown5A0[5];
uint16_t unknownMask59E[5];
uint16_t unknown5A3[18];
uint16_t unknownMask5C1[28];
uint16_t unknown_03411;
uint32_t unknownDword5E0;
uint16_t pvpFrontlineWeekly1st;
uint16_t pvpFrontlineWeekly2nd;
uint16_t pvpFrontlineWeekly3rd;
uint16_t relicBookCompletion2[8];
uint16_t sightseeingMask[26];
uint16_t unknown_XXX;
uint16_t unknown61E[20];
uint16_t unknown656[29];
uint16_t unknown63F[22];
uint16_t tripleTriadCards[28];
uint16_t unknown671[11];
uint16_t unknownMask67C[22];
uint16_t unknown692[3];
uint16_t orchestrionMask[40];
uint16_t hallOfNoviceCompleteMask[3];
uint16_t unknownMask6C0[11];
uint16_t unknownMask6CB[16];
uint16_t unknown6DB[14];
uint16_t unlockedRaids[28];
uint16_t unlockedDungeons[18];
uint16_t unlockedGuildhests[10];
uint16_t unlockedTrials[7];
uint16_t unlockedPvp[5];
uint16_t unknownMask72D[28];
unsigned char unknownOword[16];
unsigned char unknown258;
unsigned char unlockBitmask[64];
unsigned char aetheryte[17];
unsigned char discovery[421];
unsigned char howto[33];
unsigned char minions[38];
unsigned char chocoboTaxiMask[8];
unsigned char watchedCutscenes[111];
unsigned char companionBardingMask[9];
unsigned char companionEquippedHead;
unsigned char companionEquippedBody;
unsigned char companionEquippedLegs;
unsigned char unknown519[4];
unsigned char unknownMask51D[11];
unsigned char fishingGuideMask[89];
unsigned char fishingSpotVisited[25];
unsigned char unknown59A[15];
unsigned char unknown5A9[2];
unsigned char unknownPvp5AB[2];
unsigned char pvpLevel;
unsigned char beastRank[11];
unsigned char unknown5B9[11];
unsigned char pose;
unsigned char weaponPose;
unsigned char unknownMask5C4[3];
unsigned char unknown5C9[2];
unsigned char challengeLogComplete[9];
unsigned char unknown5D4[9];
unsigned char unknownMask5DD[28];
unsigned char relicCompletion[12];
unsigned char sightseeingMask[26];
unsigned char huntingMarkMask[55];
unsigned char tripleTriadCards[29];
unsigned char unknownMask673[10];
unsigned char unknown67D;
unsigned char aetherCurrentMask[22];
unsigned char unknown694[3];
unsigned char orchestrionMask[40];
unsigned char hallOfNoviceCompleteMask[3];
unsigned char animaCompletion[11];
unsigned char unknown6CD[3];
unsigned char unknownMask6C0[11];
unsigned char unknownMask6DB[13];
unsigned char unlockedRaids[28];
unsigned char unlockedDungeons[18];
unsigned char unlockedGuildhests[10];
unsigned char unlockedTrials[7];
unsigned char unlockedPvp[5];
unsigned char clearedRaids[28];
unsigned char clearedDungeons[18];
unsigned char clearedGuildhests[10];
unsigned char clearedTrials[7];
unsigned char clearedPvp[5];
};
@ -1109,6 +1149,17 @@ struct FFXIVIpcEventFinish : FFXIVIpcBasePacket<EventFinish>
/* 000C */ uint32_t padding1;
};
struct FFXIVIpcEventOpenGilShop : FFXIVIpcBasePacket<EventOpenGilShop>
{
uint64_t actorId;
uint32_t eventId;
uint16_t scene;
uint16_t padding;
uint32_t sceneFlags;
uint32_t unknown_wtf[0x101];
};
/**
* Structural representation of the packet sent by the server
@ -1372,6 +1423,58 @@ struct FFXIVIpcPerformNote : FFXIVIpcBasePacket<PerformNote>
uint8_t data[32];
};
struct FFXIVIpcWardInfo : FFXIVIpcBasePacket<WardInfo>
{
uint16_t unknown0;
uint16_t wardNum; // set 1 for "Mist, Ward 2"
uint16_t zoneId;
uint16_t worldId;
uint8_t unknown1;
uint8_t subInstance; // (default : 1/2)
uint8_t unknown3;
uint8_t unknown4;
uint8_t unknown5;
uint8_t unknown6;
uint8_t unknown7;
uint8_t unknown8;
struct {
uint8_t houseSize; //1 = small, 2 = middle, 3 = big; 1
uint8_t houseState; //1 = for sell, 2 = sold, 3 = hasOwner, 0x0A = House sharing; 2
uint8_t iconColor; //HouseState has to be 3; 1 = Private, 2 = FC House; 4
uint8_t iconAddIcon; //Heart Icon = 2; 6
uint32_t unknown9; //can be 0 (default) maybe fcId; 8
uint32_t fcIcon; //can be 0 (default); 12
uint32_t fcIconColor; //can be 0 (default); 16
uint16_t houseRoofId; //18
uint16_t houseFacadeId;//20
uint16_t houseWindowId;//22
uint16_t houseDoorId;//24
uint8_t gardenData[4];//28
uint16_t gardenSignId; //For fcIcon; 30
uint16_t gardenFenceId; //32
uint8_t color[8]; //40
} landSet[30];
};
struct FFXIVIpcWardYardInfo : FFXIVIpcBasePacket<WardYardInfo>
{
/* consistency check? */
uint32_t unknown1; //always 0xFFFFFFFF
uint32_t unknown2; //always 0xFFFFFFFF
uint8_t unknown3; //always 0xFF
/* --- */
uint8_t packetNum;
uint16_t packetTotal;
struct
{
uint32_t itemId;
uint16_t itemRotation;
uint16_t pos_x;
uint16_t pos_y;
uint16_t pos_z;
} object[100];
};
struct FFXIVIpcMSQTrackerProgress : FFXIVIpcBasePacket<MSQTrackerProgress>
{
uint32_t id;

@ -1 +1 @@
Subproject commit 67b949dfe3ffbbba7963b0861670ab4bb1819991
Subproject commit 61712f8f11892d12ad6878a80b9b89b318908558

View file

@ -0,0 +1,15 @@
#include <Script/NativeScriptApi.h>
#include "../ScriptObject.h"
#include <Actor/Player.h>
class ActionReturn6 : public ActionScript
{
public:
ActionReturn6() : ActionScript( 6 )
{}
void onCastFinish( Core::Entity::Player& player, Core::Entity::Chara& targetActor ) override
{
player.returnToHomepoint();
}
};

View file

@ -1,5 +1,4 @@
#include <Script/NativeScriptApi.h>
#include "../ScriptObject.h"
#include <ScriptObject.h>
#include <Actor/Player.h>
class ActionSprint3 : public ActionScript

View file

@ -1,5 +1,4 @@
#include "Script/NativeScriptApi.h"
#include "../ScriptObject.h"
#include <ScriptObject.h>
#include <Actor/Player.h>
#define ACTION_ATTUNE 0x13

View file

@ -1,5 +1,4 @@
#include <Script/NativeScriptApi.h>
#include "../ScriptObject.h"
#include <ScriptObject.h>
#include <Actor/Player.h>

View file

@ -1,5 +1,4 @@
#include <Script/NativeScriptApi.h>
#include "../ScriptObject.h"
#include <ScriptObject.h>
#include <Actor/Player.h>
class CmnDefCutSceneReplay : public EventScript
@ -18,7 +17,7 @@ public:
}
};
player.playScene( getId(), 0, 0x2000, 0, 1, callback );
player.playScene( getId(), 0, HIDE_HOTBAR, 0, 1, callback );
}
void Scene00001( Entity::Player& player, uint16_t returnScene )

View file

@ -0,0 +1,19 @@
#include <ScriptObject.h>
#include <Actor/Player.h>
class CmnDefHousingSignboard : public EventScript
{
public:
CmnDefHousingSignboard() : EventScript( 721031 )
{}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR, 0, 1 );
}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
Scene00000( player );
}
};

View file

@ -1,5 +1,4 @@
#include <Script/NativeScriptApi.h>
#include "../ScriptObject.h"
#include <ScriptObject.h>
#include <Actor/Player.h>
class CmnDefInnBed : public EventScript
@ -17,7 +16,7 @@ public:
Scene00001( player, result.param2 );
};
player.playScene( getId(), 0, 0x2000, 0, 1, callback );
player.playScene( getId(), 0, HIDE_HOTBAR, 0, 1, callback );
}
// lay down

View file

@ -1,5 +1,4 @@
#include <Script/NativeScriptApi.h>
#include "../ScriptObject.h"
#include <ScriptObject.h>
#include <Actor/Player.h>
#define ACTION_CREATE 2

View file

@ -0,0 +1,19 @@
#include <ScriptObject.h>
#include <Actor/Player.h>
class CmnDefMarketBoardGridania : public EventScript
{
public:
CmnDefMarketBoardGridania() : EventScript( 0xB0027 )
{}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR, 0, 1 );
}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
Scene00000( player );
}
};

View file

@ -0,0 +1,22 @@
#include <ScriptObject.h>
#include <Actor/Player.h>
class CmnDefMogLetter : public EventScript
{
public:
CmnDefMogLetter() : EventScript( 720898 )
{}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
Scene00000( player );
}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, 0,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
};

View file

@ -0,0 +1,19 @@
#include <ScriptObject.h>
#include <Actor/Player.h>
class CmnDefNpcRepair : public EventScript
{
public:
CmnDefNpcRepair() : EventScript( 0xB0013 )
{}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR, 0, 1 );
}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
Scene00000( player );
}
};

View file

@ -0,0 +1,22 @@
#include <ScriptObject.h>
#include <Actor/Player.h>
class CmnDefWeatherForeCast : public EventScript
{
public:
CmnDefWeatherForeCast() : EventScript( 721100 )
{}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
Scene00000( player );
}
};

View file

@ -0,0 +1,19 @@
#include <ScriptObject.h>
#include <Actor/Player.h>
class ComDefMobHuntBoard : public EventScript
{
public:
ComDefMobHuntBoard() : EventScript( 0xB00CA )
{}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR, 0, 1 );
}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
Scene00000( player );
}
};

View file

@ -0,0 +1,48 @@
#include <ScriptObject.h>
#include <Actor/Player.h>
class GilShop : public EventScript
{
public:
GilShop() : EventScript( 0x00040001 )
{}
constexpr static auto SCENE_FLAGS = HIDE_HOTBAR | NO_DEFAULT_CAMERA;
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
player.playScene( eventId, 0, SCENE_FLAGS, 0, 2, shopCallback );
}
private:
static void shopInteractionCallback( Entity::Player& player, const Event::SceneResult& result )
{
// item purchase
if( result.param1 == 768 )
{
// buy
if( result.param2 == 1 )
{
}
// sell
else if( result.param2 == 2 )
{
}
player.sendDebug( "got tradeQuantity: " + std::to_string( result.param4 ) );
player.playGilShop( result.eventId, SCENE_FLAGS, shopInteractionCallback );
return;
}
// exit
player.playScene( result.eventId, 255, SCENE_FLAGS );
}
static void shopCallback( Entity::Player& player, const Event::SceneResult& result )
{
player.playGilShop( result.eventId, SCENE_FLAGS, shopInteractionCallback );
}
};

View file

@ -1,5 +1,4 @@
#include <Script/NativeScriptApi.h>
#include "../ScriptObject.h"
#include <ScriptObject.h>
#include <Actor/Player.h>
class HouFurOrchestrion : public EventScript
@ -10,7 +9,7 @@ public:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, 0x2000, 0, 1 );
player.playScene( getId(), 0, HIDE_HOTBAR, 0, 1 );
}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override

View file

@ -0,0 +1,36 @@
#include <ScriptObject.h>
#include <Zone/InstanceContent.h>
class TheWeaponsRefrainUltimate : public InstanceContentScript
{
public:
TheWeaponsRefrainUltimate() : InstanceContentScript( 30067 )
{ }
void onInit( InstanceContentPtr instance ) override
{
instance->registerEObj( "unknown_0", 2009480, 0, 4, { 94.011192f, 0.000000f, 107.700996f }, 1.000000f, 0.000000f );
instance->registerEObj( "sgvf_w1fz_b1432", 2007457, 7372735, 4, { 100.000000f, 0.000000f, 100.000000f }, 1.000000f, 0.000000f );
instance->registerEObj( "unknown_1", 2007457, 7373056, 4, { 100.000000f, 0.000000f, 100.000000f }, 1.000000f, 0.000000f );
instance->registerEObj( "unknown_2", 2009481, 0, 4, { 101.695602f, 0.000000f, 101.959396f }, 1.000000f, 0.000000f );
instance->registerEObj( "unknown_3", 2007457, 7237754, 4, { 100.000000f, 0.000000f, 100.000000f }, 1.000000f, 0.000000f );
instance->registerEObj( "unknown_4", 2007457, 7237753, 4, { 100.000000f, 0.000000f, 100.000000f }, 1.000000f, 0.000000f );
instance->registerEObj( "unknown_5", 2007457, 7237756, 4, { 100.000000f, 0.000000f, 100.000000f }, 1.000000f, 0.000000f );
instance->registerEObj( "unknown_6", 2007457, 7237755, 4, { 100.000000f, 0.000000f, 100.000000f }, 1.000000f, 0.000000f );
instance->registerEObj( "Entrance", 2007457, 7343478, 5, { 100.000000f, 0.000000f, 116.000000f }, 1.000000f, 0.000000f );
// States -> vf_lock_on vf_lock_of
instance->registerEObj( "Exit", 2000139, 0, 4, { 100.000000f, 0.000000f, 85.000000f }, 1.000000f, 0.000000f );
instance->registerEObj( "unknown_7", 2007457, 7538258, 4, { 100.160004f, 0.000000f, 101.443398f }, 1.000000f, 0.000000f );
}
void onUpdate( InstanceContentPtr instance, uint32_t currTime ) override
{
}
void onEnterTerritory( InstanceContentPtr instance, Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override
{
}
};

View file

@ -1,4 +1,3 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include <ScriptObject.h>
@ -30,6 +29,24 @@ private:
{
auto callback = [this]( Entity::Player& player, const Event::SceneResult& result )
{
auto questionAnswer = result.param2;
uint16_t itemId = 0;
switch( questionAnswer )
{
case 1: itemId = 4423; break;
case 2: itemId = 4424; break;
case 3: itemId = 4425; break;
case 4: itemId = 4426; break;
default: itemId = 4426; break;
}
auto item = player.addItem( Common::InventoryType::ArmoryRing, -1, itemId, 1, false, true );
if( item )
player.equipItem( Common::EquipSlot::Ring2, item, true );
player.setOpeningSequence( 1 );
Scene00001( player );
};

View file

@ -1,4 +1,3 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include <ScriptObject.h>
@ -45,6 +44,24 @@ private:
{
auto callback = [this]( Entity::Player& player, const Event::SceneResult& result )
{
auto questionAnswer = result.param2;
uint16_t itemId = 0;
switch( questionAnswer )
{
case 1: itemId = 4423; break;
case 2: itemId = 4424; break;
case 3: itemId = 4425; break;
case 4: itemId = 4426; break;
default: itemId = 4426; break;
}
auto item = player.addItem( Common::InventoryType::ArmoryRing, -1, itemId, 1, false, true );
if( item )
player.equipItem( Common::EquipSlot::Ring2, item, true );
player.setOpeningSequence( 1 );
Scene00001( player );
};

View file

@ -1,4 +1,3 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include <ScriptObject.h>
@ -31,6 +30,24 @@ private:
{
auto callback = [this]( Entity::Player& player, const Event::SceneResult& result )
{
auto questionAnswer = result.param2;
uint16_t itemId = 0;
switch( questionAnswer )
{
case 1: itemId = 4423; break;
case 2: itemId = 4424; break;
case 3: itemId = 4425; break;
case 4: itemId = 4426; break;
default: itemId = 4426; break;
}
auto item = player.addItem( Common::InventoryType::ArmoryRing, -1, itemId, 1, false, true );
if( item )
player.equipItem( Common::EquipSlot::Ring2, item, true );
player.setOpeningSequence( 1 );
Scene00001( player );
};

View file

@ -1,7 +1,6 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include <sapphire_zone/Event/EventHandler.h>
#include "../ScriptObject.h"
#include <ScriptObject.h>
#include "Event/EventHelper.h"
// Quest Script: ManFst001_00039

View file

@ -1,8 +1,7 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include <sapphire_zone/Event/EventHandler.h>
#include "Event/EventHelper.h"
#include "../ScriptObject.h"
#include <ScriptObject.h>
// Quest Script: ManFst002_00124
// Quest Name: Close to Home

View file

@ -1,7 +1,6 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include "../ScriptObject.h"
#include <ScriptObject.h>
// Quest Script: ManFst003_00123
// Quest Name: Close to Home
@ -11,15 +10,238 @@
class ManFst003 : public EventScript
{
private:
private:
// Basic quest information
// Quest vars / flags used
// GetQuestBitFlag8
// GetQuestUI8AL
// GetQuestUI8BH
// GetQuestUI8BL
// GetQuestUI8CH
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
SeqFinish = 255,
};
public:
ManFst003() : EventScript( 65659 )
{}
// Quest rewards
static constexpr auto RewardExpFactor = 100;
static constexpr auto RewardGil = 107;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1001140;
static constexpr auto Actor1 = 2;
static constexpr auto Actor2 = 1000197;
static constexpr auto Actor20 = 1000159;
static constexpr auto Actor3 = 1000768;
static constexpr auto Actor4 = 1000100;
static constexpr auto BindActor0 = 6229224;
static constexpr auto Item0 = 2000119;
static constexpr auto LocActor0 = 1003159;
static constexpr auto LocMarker01 = 2153091;
static constexpr auto LocMarker02 = 2153104;
static constexpr auto LocMarker03 = 2153111;
static constexpr auto LocMarker04 = 2154539;
static constexpr auto LocMarker05 = 2154540;
static constexpr auto LocMarker06 = 2154541;
static constexpr auto LocMarker07 = 2210446;
static constexpr auto LocMarker08 = 2210454;
static constexpr auto LocMarker09 = 2210461;
static constexpr auto LocMotion0 = 799;
static constexpr auto Poprange0 = 2280858;
static constexpr auto RewardDesion = 1;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq0Actor0Lq = 50;
static constexpr auto Seq1Actor0 = 4;
static constexpr auto Seq1Actor1 = 1;
static constexpr auto Seq1Actor1Wait = 51;
static constexpr auto Seq1Actor2 = 2;
static constexpr auto Seq1Actor3 = 3;
static constexpr auto Seq1Actor3Npctradeno = 99;
static constexpr auto Seq1Actor3Npctradeok = 100;
static constexpr auto Seq2Actor4 = 5;
static constexpr auto Territorytype0 = 132;
static constexpr auto UnlockDesion = 14;
public:
ManFst003() : EventScript( 65659 ){};
~ManFst003(){};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
player.eventActionStart( 0x050002, 0x13,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
player.sendQuestMessage( 0x050002, 0, 1, 0, 0 );
player.registerAetheryte( 2 );
player.learnAction( 1 );
Scene00051( player );
},
nullptr, eventId );
}
else if( actor == Actor2 )
{
Scene00002( player );
}
else if( actor == Actor3 )
{
Scene00003( player );
}
else if( actor == Actor4 )
{
Scene00005( player );
}
}
};
private:
void checkQuestCompletion( Entity::Player& player, uint32_t varIdx )
{
if( varIdx == 3 )
{
player.sendQuestMessage( getId(), 1, 0, 0, 0 );
}
else if( varIdx == 2 )
{
player.sendQuestMessage( getId(), 2, 0, 0, 0 );
}
else
{
player.sendQuestMessage( getId(), 0, 0, 0, 0 );
}
auto questId = getId();
auto QUEST_VAR_ATTUNE = player.getQuestUI8AL( questId );
auto QUEST_VAR_CLASS = player.getQuestUI8BH( questId );
auto QUEST_VAR_TRADE = player.getQuestUI8BL( questId );
if( QUEST_VAR_ATTUNE == 1 && QUEST_VAR_CLASS == 1 && QUEST_VAR_TRADE == 1 )
{
player.updateQuest( questId, SeqFinish );
}
}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00050( player );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8AL( getId(), 1 );
checkQuestCompletion( player, 0 );
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8BH( getId(), 1 );
checkQuestCompletion( player, 3 );
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene( getId(), 3, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00100( player );
}
else
{
Scene00099( player );
}
} );
}
void Scene00004( Entity::Player& player )
{
player.playScene( getId(), 4, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 4, 0, 0, 0 );
} );
}
void Scene00005( Entity::Player& player )
{
player.playScene( getId(), 5, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
void Scene00050( Entity::Player& player )
{
player.playScene( getId(), 50, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.updateQuest( getId(), Seq1 );
player.setQuestUI8CH( getId(), 1 );
player.forceZoneing( 132 );
} );
}
void Scene00051( Entity::Player& player )
{
player.playScene( getId(), 51, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00001( player );
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00004( player );
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8CH( getId(), 0 );
player.setQuestUI8BL( getId(), 1 );
checkQuestCompletion( player, 2 );
} );
}
};

View file

@ -1,4 +1,3 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include <ScriptObject.h>
@ -20,8 +19,6 @@ private:
// GetQuestUI8BL
// GetQuestUI8CH
// Steps in this quest ( 0 is before accepting,
// 1 is first, 255 means ready for turning it in
enum Sequence : uint8_t
{
Seq0 = 0,
@ -75,8 +72,6 @@ public:
~ManFst004()
{ };
//////////////////////////////////////////////////////////////////////
// Event Handlers
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
@ -98,9 +93,7 @@ public:
player.learnAction( 1 );
Scene00051( player );
},
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{ },
eventId );
nullptr, eventId);
}
else if( actor == ManFst004::Actor2 )
{
@ -122,16 +115,18 @@ private:
{
if( varIdx == 3 )
{
player.sendQuestMessage( m_id, 1, 0, 0, 0 );
} else if( varIdx == 2 )
player.sendQuestMessage( getId(), 1, 0, 0, 0 );
}
else if( varIdx == 2 )
{
player.sendQuestMessage( m_id, 2, 0, 0, 0 );
} else
player.sendQuestMessage( getId(), 2, 0, 0, 0 );
}
else
{
player.sendQuestMessage( m_id, 0, 0, 0, 0 );
player.sendQuestMessage( getId(), 0, 0, 0, 0 );
}
auto questId = m_id;
auto questId = getId();
auto QUEST_VAR_ATTUNE = player.getQuestUI8AL( questId );
auto QUEST_VAR_CLASS = player.getQuestUI8BH( questId );
@ -143,11 +138,9 @@ private:
}
}
//////////////////////////////////////////////////////////////////////
// Available Scenes in this quest, not necessarly all are used
void Scene00000( Entity::Player& player )
{
player.playScene( m_id, 0, 0x2000,
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 ) // accept quest
@ -159,27 +152,27 @@ private:
void Scene00001( Entity::Player& player )
{
player.playScene( m_id, 1, 0,
player.playScene( getId(), 1, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8AL( m_id, 1 );
player.setQuestUI8AL( getId(), 1 );
checkQuestCompletion( player, 0 );
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( m_id, 2, 0,
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8BH( m_id, 1 );
player.setQuestUI8BH( getId(), 1 );
checkQuestCompletion( player, 3 );
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene( m_id, 3, 0,
player.playScene( getId(), 3, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
@ -194,19 +187,23 @@ private:
void Scene00004( Entity::Player& player )
{
player.playScene( m_id, 4, 0, 0, 0 );
player.playScene( getId(), 4, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 4, 0, 0, 0 );
} );
}
void Scene00005( Entity::Player& player )
{
player.playScene( m_id, 5, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, 0, 0,
player.playScene( getId(), 5, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, 0, 0,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 ) // finish quest
{
if( player.giveQuestRewards( m_id, 0 ) )
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( m_id );
player.finishQuest( getId() );
}
}
} );
@ -214,12 +211,12 @@ private:
void Scene00050( Entity::Player& player )
{
player.playScene( m_id, 50, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, 0/*unk*/, 0/*unk*/,
player.playScene( getId(), 50, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, 0/*unk*/, 0/*unk*/,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
// accepting quest "close to home"
player.updateQuest( m_id, 1 );
player.setQuestUI8CH( m_id, 1 ); // receive key item
player.updateQuest( getId(), 1 );
player.setQuestUI8CH( getId(), 1 ); // receive key item
// event is done, need to teleport to real zone.
player.setZone( 132 );
//player.setZone(183); back to starting griania for debug purpose
@ -228,7 +225,7 @@ private:
void Scene00051( Entity::Player& player )
{
player.playScene( m_id, 51, NONE,
player.playScene( getId(), 51, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00001( player );
@ -237,7 +234,7 @@ private:
void Scene00099( Entity::Player& player )
{
player.playScene( m_id, 99, NONE,
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00004( player );
@ -246,13 +243,12 @@ private:
void Scene00100( Entity::Player& player )
{
player.playScene( m_id, 100, NONE,
player.playScene( getId(), 100, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8CH( m_id, 0 ); // remove key item, since we have just traded it
player.setQuestUI8BL( m_id, 1 );
player.setQuestUI8CH( getId(), 0 ); // remove key item, since we have just traded it
player.setQuestUI8BL( getId(), 1 );
checkQuestCompletion( player, 2 );
} );
}
};

View file

@ -1,4 +1,3 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include <ScriptObject.h>
@ -50,7 +49,7 @@ private:
void Scene00002( Entity::Player& player )
{
player.updateQuest( getId(), 1 );
player.updateQuest( getId(), SEQ_1 );
player.playSceneChain( getId(), 2, NONE, bindScene( &ManSea001::Scene00003 ) );
}
@ -58,9 +57,9 @@ private:
{
player.playScene( getId(), 3, NONE,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( OPENING_EVENT_HANDLER, 0x1E, HIDE_HOTBAR | NO_DEFAULT_CAMERA, 1, 0 );
} );
{
player.playScene( OPENING_EVENT_HANDLER, 0x1E, HIDE_HOTBAR | NO_DEFAULT_CAMERA, 1, 0 );
} );
}
void Scene00004( Entity::Player& player )
@ -77,14 +76,14 @@ private:
{
player.playScene( getId(), 6, INVIS_OTHER_PC,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), SEQ_FINISH );
player.prepareZoning( player.getZoneId(), true, 1, 0 );
player.changePosition( 9, 40, 14, 2 );
}
} );
if( result.param2 == 1 )
{
player.updateQuest( getId(), SEQ_FINISH );
player.prepareZoning( player.getZoneId(), true, 1, 0 );
player.changePosition( 9, 40, 14, 2 );
}
} );
}
void Scene00007( Entity::Player& player )
@ -116,13 +115,13 @@ private:
{
player.playScene( getId(), 12, INVIS_OTHER_PC,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 ) // finish quest
{
if(player.giveQuestRewards( getId(), 0 ) )
player.finishQuest( getId() );
}
} );
if( result.param2 == 1 ) // finish quest
{
if(player.giveQuestRewards( getId(), 0 ) )
player.finishQuest( getId() );
}
} );
}
void Scene00013( Entity::Player& player )

View file

@ -1,7 +1,6 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include "../ScriptObject.h"
#include <ScriptObject.h>
// Quest Script: ManSea002_00108
// Quest Name: Close to Home
@ -33,122 +32,162 @@ private:
static constexpr auto SCREENIMAGE0 = 14;
static constexpr auto UNLOCK_DESION = 14;
void Scene00000( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 ) // accept quest
Scene00050( player );
};
player.playScene( getId(), 0, HIDE_HOTBAR, 0, 0, callback );
}
void Scene00001( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 1, NONE, callback );
}
void Scene00002( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 2, NONE, callback );
}
void Scene00003( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 3, NONE, callback );
}
void Scene00004( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 4, NONE, callback );
}
void Scene00005( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 5, NONE, callback );
}
void Scene00006( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 6, NONE, callback );
}
void Scene00007( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 7, NONE, callback );
}
void Scene00008( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 8, NONE, callback );
}
void Scene00050( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
// on quest accept
player.updateQuest( getId(), 1 );
player.setQuestUI8CH( getId(), 1 ); // receive key item
// teleport to real limsa
player.forceZoneing( 128 );
};
player.playScene( getId(), 50, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, 0, 0, callback );
}
public:
ManSea002() : EventScript( 65644 )
{}
~ManSea002()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
// todo: this doesn't actually play a cutscene after accepting the quest
if( actor == ACTOR0 )
{
Scene00000( player );
}
else if( actor == AETHERYTE0 )
{
player.eventActionStart( 0x050002, 0x13,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
player.sendQuestMessage( 0x050002, 0, 1, 0, 0 );
player.registerAetheryte( 2 );
player.learnAction( 1 );
Scene00002( player );
},
nullptr, eventId );
}
else if( actor == ACTOR1 )
{
Scene00004( player );
}
else if( actor == ACTOR2 )
{
Scene00006( player );
}
else if( actor == ACTOR3 )
{
Scene00007( player );
}
}
private:
void checkQuestCompletion( Entity::Player& player, uint32_t varIdx )
{
if( varIdx == 1 )
{
player.sendQuestMessage( getId(), 1, 0, 0, 0 );
}
else if( varIdx == 2 )
{
player.sendQuestMessage( getId(), 2, 0, 0, 0 );
}
else
{
player.sendQuestMessage( getId(), 0, 0, 0, 0 );
}
auto questId = getId();
auto QUEST_VAR_ATTUNE = player.getQuestUI8AL( questId );
auto QUEST_VAR_CLASS = player.getQuestUI8BH( questId );
auto QUEST_VAR_TRADE = player.getQuestUI8BL( questId );
if( QUEST_VAR_ATTUNE == 1 && QUEST_VAR_CLASS == 1 && QUEST_VAR_TRADE == 1 )
{
player.updateQuest( questId, SEQ_FINISH );
}
}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00001( player );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.updateQuest( getId(), SEQ_1 );
player.setQuestUI8CH( getId(), 1 );
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00003( player );
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene( getId(), 3, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8BL( getId(), 1 );
checkQuestCompletion( player, 0 );
} );
}
void Scene00004( Entity::Player& player )
{
player.playScene( getId(), 4, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00005( player );
}
else return;
} );
}
void Scene00005( Entity::Player& player )
{
player.playScene( getId(), 5, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ, 0, 0,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8CH( getId(), 0 );
player.setQuestUI8BH( getId(), 1 );
checkQuestCompletion( player, 1 );
} );
}
void Scene00006( Entity::Player& player )
{
player.playScene( getId(), 6, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8AL( getId(), 1 );
checkQuestCompletion( player, 2 );
} );
}
void Scene00007( Entity::Player& player )
{
player.playScene( getId(), 7, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ, 0, 0,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,208 @@
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include <ScriptObject.h>
// Quest Script: ManSea003_00109
// Quest Name: Close to Home
// Quest ID: 65645
// Start NPC: 1002697
// End NPC: 1000972
class ManSea003 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestBitFlag8
// GetQuestUI8AL
// GetQuestUI8BH
// GetQuestUI8BL
// GetQuestUI8CH
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 100;
static constexpr auto RewardGil = 107;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1002697;
static constexpr auto Actor1 = 1001217;
static constexpr auto Actor2 = 1000895;
static constexpr auto Actor3 = 1000972;
static constexpr auto Aetheryte0 = 8;
static constexpr auto BindActor0 = 6229226;
static constexpr auto Item0 = 2000105;
static constexpr auto LocActor1 = 1001023;
static constexpr auto LocFace0 = 604;
static constexpr auto LocFace1 = 605;
static constexpr auto LocPosCam1 = 4106696;
static constexpr auto LocPosCam2 = 4106698;
static constexpr auto Reward0 = 1;
static constexpr auto Screenimage0 = 14;
static constexpr auto UnlockDesion = 14;
public:
ManSea003() : EventScript( 65645 )
{};
~ManSea003()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0)
{
Scene00000( player );
}
else if( actor == Aetheryte0 )
{
player.eventActionStart( 0x050002, 0x13,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
player.sendQuestMessage( 0x050002, 0, 1, 0, 0 );
player.registerAetheryte( 2 );
player.learnAction( 1 );
Scene00002( player );
},
nullptr, eventId );
}
else if( actor == Actor1 )
{
Scene00004( player );
}
else if( actor == Actor2 )
{
Scene00006( player );
}
else if( actor == Actor3 )
{
Scene00007( player );
}
}
private:
void checkQuestCompletion( Entity::Player& player, uint32_t varIdx )
{
if( varIdx == 1 )
{
player.sendQuestMessage( getId(), 1, 0, 0, 0 );
}
else if( varIdx == 2 )
{
player.sendQuestMessage( getId(), 2, 0, 0, 0 );
}
else
{
player.sendQuestMessage( getId(), 0, 0, 0, 0 );
}
auto questId = getId();
auto QUEST_VAR_ATTUNE = player.getQuestUI8AL( questId );
auto QUEST_VAR_CLASS = player.getQuestUI8BH( questId );
auto QUEST_VAR_TRADE = player.getQuestUI8BL( questId );
if( QUEST_VAR_ATTUNE == 1 && QUEST_VAR_CLASS == 1 && QUEST_VAR_TRADE == 1 )
{
player.updateQuest( questId, 255 );
}
}
void Scene00000( Entity::Player& player)
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if (result.param2 == 1)
{
Scene00001(player);
}
} );
}
void Scene00001( Entity::Player& player)
{
player.playScene( getId(), 1, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.updateQuest( getId(), 1 );
player.setQuestUI8CH( getId(), 1 );
} );
}
void Scene00002( Entity::Player& player)
{
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00003( player );
} );
}
void Scene00003( Entity::Player& player)
{
player.playScene( getId(), 3, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8BL( getId(), 1 );
checkQuestCompletion( player, 0 );
} );
}
void Scene00004( Entity::Player& player)
{
player.playScene( getId(), 4, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00005( player );
}
else return;
} );
}
void Scene00005( Entity::Player& player)
{
player.playScene( getId(), 5, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ, 0, 0,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8CH( getId(), 0 );
player.setQuestUI8BH( getId(), 1 );
checkQuestCompletion( player, 1 );
} );
}
void Scene00006( Entity::Player& player)
{
player.playScene( getId(), 6, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8AL( getId(), 1 );
checkQuestCompletion( player, 2 );
} );
}
void Scene00007( Entity::Player& player)
{
player.playScene( getId(), 7, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ, 0, 0,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if(player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -1,7 +1,6 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include "../ScriptObject.h"
#include <ScriptObject.h>
// Quest Script: ManWil001_00594
// Quest Name: Coming to Ul'dah
@ -28,100 +27,137 @@ private:
void Scene00000( Entity::Player& player )
{
auto callback = [this]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setOpeningSequence( 2 );
Scene00001( player );
}
};
player.playScene( getId(), 0, HIDE_HOTBAR, 0, 0, callback );
if( result.param2 == 1 )
{
player.setOpeningSequence( 2 );
Scene00001( player );
}
} );
}
void Scene00001( Entity::Player& player )
{
auto callback = [this]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00002( player );
};
player.playScene( getId(), 1, DISABLE_SKIP | HIDE_HOTBAR | SET_BASE, 0, 0, callback );
player.playScene( getId(), 1, 0xF8482EFB,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00002( player );
player.updateQuest( getId(), SEQ_FINISH );
} );
}
void Scene00002( Entity::Player& player )
{
auto callback = [this]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( OPENING_EVENT_HANDLER, 0x1E, HIDE_HOTBAR | NO_DEFAULT_CAMERA, 0, 0 );
};
player.playScene( getId(), 2, NONE, 0, 0, callback );
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( OPENING_EVENT_HANDLER, 0x1E, HIDE_HOTBAR | NO_DEFAULT_CAMERA, 0, 0 );
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene( getId(), 3, NONE, 0, 0 );
player.playScene( getId(), 3, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 3, NONE, 0, 0 );
});
}
void Scene00004( Entity::Player& player )
{
player.playSceneChain( getId(), 4, 0x2c02, bindScene( &ManWil001::Scene00005 ) );
player.playScene( getId(), 4, 0x2c02,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00005( player );
} );
}
void Scene00005( Entity::Player& player )
{
auto callback = [this]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
player.playScene( getId(), 5, INVIS_OTHER_PC,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( player.giveQuestRewards( getId(), 0 ))
player.finishQuest( getId());
}
};
player.playScene( getId(), 5, INVIS_OTHER_PC, 0, 0, callback );
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
player.finishQuest( getId() );
}
} );
}
void Scene00006( Entity::Player& player )
{
player.playScene( getId(), 6, 0, 0, 0 );
player.playScene( getId(), 6, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 6, 0, 0, 0 );
} );
}
void Scene00007( Entity::Player& player )
{
player.playScene( getId(), 7, 0, 0, 0 );
player.playScene( getId(), 7, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 7, 0, 0, 0 );
} );
}
void Scene00008( Entity::Player& player )
{
player.playScene( getId(), 8, 0, 0, 0 );
player.playScene( getId(), 8, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 8, 0, 0, 0 );
} );
}
void Scene00009( Entity::Player& player )
{
player.playScene( getId(), 9, 0, 0, 0 );
player.playScene( getId(), 9, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 9, 0, 0, 0 );
} );
}
void Scene00010( Entity::Player& player )
{
player.playScene( getId(), 10, 0, 0, 0 );
player.playScene( getId(), 10, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 10, 0, 0, 0 );
} );
}
void Scene00011( Entity::Player& player )
{
player.playScene( getId(), 11, 0, 0, 0 );
player.playScene( getId(), 11, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 11, 0, 0, 0 );
} );
}
void Scene00012( Entity::Player& player )
{
player.playScene( getId(), 12, 0, 0, 0 );
player.playScene( getId(), 12, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 12, 0, 0, 0 );
} );
}
void Scene00013( Entity::Player& player )
{
player.playScene( getId(), 13, 0, 0, 0 );
player.playScene( getId(), 13, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 13, 0, 0, 0 );
} );
}
@ -134,8 +170,12 @@ public:
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == ACTOR0 )
{
Scene00000( player );
}
else if( actor == ACTOR1 )
{
Scene00004( player );
}
}
};

View file

@ -1,7 +1,6 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include "../ScriptObject.h"
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: ManWil002_00568
// Quest Name: Close to Home
@ -11,150 +10,226 @@
class ManWil002 : public EventScript
{
private:
static constexpr auto SEQ_0 = 0;
static constexpr auto SEQ_1 = 1;
static constexpr auto SEQ_FINISH = 255;
private:
// Basic quest information
// Quest vars / flags used
// GetQuestBitFlag8
// GetQuestUI8AL
// GetQuestUI8BH
// GetQuestUI8BL
// GetQuestUI8CH
static constexpr auto ACTOR0 = 1003988;
static constexpr auto ACTOR1 = 1002277;
static constexpr auto ACTOR2 = 1003908;
static constexpr auto ACTOR20 = 1001637;
static constexpr auto ACTOR3 = 1001353;
static constexpr auto AETHERYTE0 = 9;
static constexpr auto BIND_ACTOR0 = 6229228;
static constexpr auto ITEM0 = 2000386;
static constexpr auto LOC_ACTION1 = 605;
static constexpr auto LOC_ACTION2 = 1005;
static constexpr auto LOC_MARKER_01 = 4009142;
static constexpr auto LOC_MARKER_02 = 4009152;
static constexpr auto LOC_POS_CAM1 = 4105872;
static constexpr auto LOC_POS_CAM2 = 4105874;
static constexpr auto LOC_POS_CAM3 = 4009150;
static constexpr auto LOC_POS_CAM4 = 4143488;
static constexpr auto POPRANGE0 = 4110794;
static constexpr auto REWARD0 = 1;
static constexpr auto SCREENIMAGE0 = 14;
static constexpr auto SEQ_0_ACTOR0_LQ = 50;
static constexpr auto TERRITORYTYPE0 = 130;
void Scene00000( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
enum Sequence : uint8_t
{
if( result.param2 == 1 ) // accept quest
Scene00050( player );
Seq0 = 0,
Seq1 = 1,
SeqFinish = 255,
};
player.playScene( getId(), 0, HIDE_HOTBAR, 0, 0, callback );
}
// Quest rewards
static constexpr auto RewardExpFactor = 100;
static constexpr auto RewardGil = 107;
void Scene00001( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1003988;
static constexpr auto Actor1 = 1002277;
static constexpr auto Actor2 = 1003908;
static constexpr auto Actor20 = 1001637;
static constexpr auto Actor3 = 1001353;
static constexpr auto Aetheryte0 = 9;
static constexpr auto BindActor0 = 6229228;
static constexpr auto Item0 = 2000386;
static constexpr auto LocAction1 = 605;
static constexpr auto LocAction2 = 1005;
static constexpr auto LocMarker01 = 4009142;
static constexpr auto LocMarker02 = 4009152;
static constexpr auto LocPosCam1 = 4105872;
static constexpr auto LocPosCam2 = 4105874;
static constexpr auto LocPosCam3 = 4009150;
static constexpr auto LocPosCam4 = 4143488;
static constexpr auto Poprange0 = 4110794;
static constexpr auto Reward0 = 1;
static constexpr auto Screenimage0 = 14;
static constexpr auto Seq0Actor0Lq = 50;
static constexpr auto Territorytype0 = 130;
};
player.playScene( getId(), 1, NONE, callback );
}
void Scene00002( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 2, NONE, callback );
}
void Scene00003( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 3, NONE, callback );
}
void Scene00004( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 4, NONE, callback );
}
void Scene00005( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 5, NONE, callback );
}
void Scene00006( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 6, NONE, callback );
}
void Scene00007( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 7, NONE, callback );
}
void Scene00008( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
};
player.playScene( getId(), 8, NONE, callback );
}
void Scene00050( Entity::Player& player )
{
auto callback = [&]( Entity::Player& player, const Event::SceneResult& result )
{
// on quest accept
player.updateQuest( getId(), 1 );
player.setQuestUI8CH( getId(), 1 ); // receive key item
// teleport to real gridania
player.forceZoneing( 130 );
};
player.playScene( getId(), 50, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, 0, 0, callback );
}
public:
ManWil002() : EventScript( 66104 )
{ }
public:
ManWil002() : EventScript( 66104 )
{};
~ManWil002()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == ACTOR0 )
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1)
{
Scene00003( player );
}
else if( actor == Actor2 )
{
Scene00004(player);
}
else if( actor == Actor3 )
{
Scene00008( player );
}
else if( actor == Aetheryte0 )
{
player.eventActionStart( 0x050002, 0x13,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
player.sendQuestMessage( 0x050002, 0, 1, 0, 0 );
player.registerAetheryte( 2 );
player.learnAction( 1 );
Scene00001( player );
},
nullptr, eventId );
}
}
};
private:
void checkQuestCompletion( Entity::Player& player, uint32_t varIdx )
{
if( varIdx == 1 )
{
player.sendQuestMessage( getId(), 1, 0, 0, 0 );
}
else if( varIdx == 2 )
{
player.sendQuestMessage( getId(), 2, 0, 0, 0 );
}
else
{
player.sendQuestMessage( getId(), 0, 0, 0, 0 );
}
auto questId = getId();
auto QUEST_VAR_ATTUNE = player.getQuestUI8AL( questId );
auto QUEST_VAR_CLASS = player.getQuestUI8BH( questId );
auto QUEST_VAR_TRADE = player.getQuestUI8BL( questId );
if( QUEST_VAR_ATTUNE == 1 && QUEST_VAR_CLASS == 1 && QUEST_VAR_TRADE == 1 )
{
player.updateQuest( questId, SeqFinish );
}
}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 ) // accept quest
{
Scene00050( player );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00002( player );
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( getId(), 2, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8BL( getId(), 1 );
checkQuestCompletion( player, 0 );
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene( getId(), 3, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8AL( getId(), 1 );
checkQuestCompletion( player, 1 );
} );
}
void Scene00004( Entity::Player& player )
{
player.playScene( getId(), 4, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00005( player );
}
else return;
} );
}
void Scene00005( Entity::Player& player )
{
player.playScene( getId(), 5, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8CH( getId(), 0 );
player.setQuestUI8BH( getId(), 1 );
checkQuestCompletion( player, 2 );
} );
}
void Scene00006( Entity::Player& player )
{
player.playScene( getId(), 6, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00007( Entity::Player& player )
{
player.playScene( getId(), 7, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00008( Entity::Player& player )
{
player.playScene( getId(), 8, SET_EOBJ_BASE | HIDE_HOTBAR | INVIS_EOBJ,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
void Scene00050( Entity::Player& player )
{
player.playScene( getId(), 50, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
// on quest accept
player.updateQuest( getId(), Seq1 );
player.setQuestUI8CH( getId(), 1 ); // receive key item
// teleport to real ul'dah
player.forceZoneing( 130 );
} );
}
};

View file

@ -1,7 +1,6 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include "../../../ScriptObject.h"
#include <ScriptObject.h>
// Quest Script: SubFst001_00024
// Quest Name: Coarse Correspondence

View file

@ -1,7 +1,6 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include "../../../ScriptObject.h"
#include <ScriptObject.h>
// Quest Script: SubFst002_00025
// Quest Name: Quarrels with Squirrels

View file

@ -0,0 +1,114 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubFst003_00026
// Quest Name: Once Bitten, Twice Shy
// Quest ID: 65562
// Start NPC: 1000297
// End NPC: 1000315
class SubFst003 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardGil = 118;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1000297;
static constexpr auto Actor1 = 1000315;
static constexpr auto Item0 = 2000028;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq1Actor1 = 1;
static constexpr auto Seq1Actor1Npctradeno = 99;
static constexpr auto Seq1Actor1Npctradeok = 100;
public:
SubFst003() : EventScript( 65562 )
{};
~SubFst003()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), SeqFinish );
player.setQuestUI8BH( getId(), 1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00100( player );
}
else
{
Scene00099( player );
}
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 99, 0, 0, 0 );
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.setQuestUI8BH( getId(), 0 );
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,131 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubFst004_00027
// Quest Name: Preserving the Past
// Quest ID: 65563
// Start NPC: 1000194
// End NPC: 1000789
class SubFst004 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardItem = 5594;
static constexpr auto RewardItemCount = 10 ;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1000194;
static constexpr auto Actor1 = 1000686;
static constexpr auto Actor2 = 1000789;
static constexpr auto Item0 = 2000024;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq1Actor1 = 1;
static constexpr auto Seq2Actor2 = 2;
static constexpr auto Seq2Actor2Npctradeno = 99;
static constexpr auto Seq2Actor2Npctradeok = 100;
public:
SubFst004() : EventScript( 65563 )
{};
~SubFst004()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
else if( actor == Actor2 )
{
Scene00002( player );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), Seq1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.sendQuestMessage( getId(), 0, 1, 21002, 0 );
player.setQuestUI8BH( getId(), 1 );
player.updateQuest( getId(), SeqFinish );
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00100( player );
}
else
{
Scene00099( player );
}
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 99, 0, 0, 0 );
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if(player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,131 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubFst008_00032
// Quest Name: A Hard Nut to Crack
// Quest ID: 65568
// Start NPC: 1000372
// End NPC: 1000629
class SubFst008 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 100;
uint32_t RewardItemOptional[3] = { 2999, 3010, 5824 };
uint32_t RewardItemOptionalCount[3] = { 1, 1, 1 };
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1000372;
static constexpr auto Actor1 = 1000311;
static constexpr auto Actor2 = 1000629;
static constexpr auto Item0 = 2000029;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq1Actor1 = 1;
static constexpr auto Seq2Actor2 = 2;
static constexpr auto Seq2Actor2Npctradeno = 99;
static constexpr auto Seq2Actor2Npctradeok = 100;
public:
SubFst008() : EventScript( 65568 )
{};
~SubFst008()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
else if( Actor2 == Actor2 )
{
Scene00002( player );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), Seq1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.setQuestUI8BH( getId(), 1 );
player.updateQuest( getId(), SeqFinish );
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if ( result.param2 == 1 )
{
Scene00100( player );
}
else
{
Scene00099( player );
}
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 99, 0, 0, 0 );
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene(getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if ( player.giveQuestRewards( getId(), 0 ) )
{
player.setQuestUI8BH( getId(), 0 );
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,113 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubFst009_00034
// Quest Name: Derision of Labor
// Quest ID: 65570
// Start NPC: 1000370
// End NPC: 1000408
class SubFst009 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 100;
static constexpr auto RewardGil = 127;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1000370;
static constexpr auto Actor1 = 1000408;
static constexpr auto Item0 = 2000080;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq1Actor1 = 1;
static constexpr auto Seq1Actor1Npctradeno = 99;
static constexpr auto Seq1Actor1Npctradeok = 100;
public:
SubFst009() : EventScript( 65570 )
{};
~SubFst009()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), SeqFinish );
player.setQuestUI8BH( getId(), 1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00100( player );
}
else
{
Scene00099( player );
}
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 99, 0 );
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -1,7 +1,6 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include "../../../ScriptObject.h"
#include <ScriptObject.h>
// Quest Script: SubFst010_00001
// Quest Name: A Good Adventurer Is Hard to Find

View file

@ -0,0 +1,99 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubFst011_00037
// Quest Name: Population Control
// Quest ID: 65573
// Start NPC: 1000195
// End NPC: 1000195
//NEED TEST KILLCREDIT
class SubFst011 : public EventScript
{
private:
// GetQuestUI8AL
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 100;
uint32_t RewardItemOptional[3] = { 2653, 2655, 5823 };
uint32_t RewardItemCount[3] = { 1, 1, 3 };
static constexpr auto Actor0 = 1000195;
static constexpr auto Enemy0 = 47;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq2Actor0 = 1;
public:
SubFst011() : EventScript( 65573 )
{};
~SubFst011()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 && !player.hasQuest( getId() ) )
{
Scene00000( player );
}
else if( actor == Actor0 && player.getQuestSeq( getId() ) == SeqFinish )
{
Scene00001( player );
}
}
void onMobKill( Entity::Player& player, uint64_t npcId)
{
if( npcId != Enemy0 )
return;
auto currentKC = player.getQuestUI8AL( getId() ) + 1;
if( currentKC >= 6 )
player.updateQuest( getId(), SeqFinish );
else
{
player.setQuestUI8AL( getId(), currentKC );
player.sendQuestMessage( getId(), 0, 2, currentKC, 6 );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), Seq1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if (player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
};
};

View file

@ -1,7 +1,6 @@
#include <Script/NativeScriptApi.h>
#include <ScriptObject.h>
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include "../../../ScriptObject.h"
// Quest Script: SubFst013_00040
// Quest Name: For Friendship

View file

@ -0,0 +1,348 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubFst014_00041
// Quest Name: Covered in Roses
// Quest ID: 65577
// Start NPC: 1000300
// End NPC: 1000300
class SubFst014 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// setQuestBitFlag8
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardGil = 111;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1000300;
static constexpr auto Eobject0 = 2000026;
static constexpr auto Eobject1 = 2000027;
static constexpr auto Eobject2 = 2000028;
static constexpr auto Eobject3 = 2000029;
static constexpr auto Eobject4 = 2000030;
static constexpr auto Eobject5 = 2000031;
static constexpr auto EventActionSearch = 1;
static constexpr auto Item0 = 2000084;
public:
SubFst014() : EventScript( 65577 )
{};
~SubFst014()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 && !player.hasQuest( getId() ) )
{
Scene00000( player );
}
else if ( actor == Actor0 )
{
Scene00007( player );
}
//EOBJECTS CHECK
else if( actor == Eobject0 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00001( player );
},
nullptr, eventId );
}
else if( actor == Eobject1 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00002( player );
},
nullptr, eventId );
}
else if( actor == Eobject2 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00003( player );
},
nullptr, eventId );
}
else if( actor == Eobject3 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00004( player );
},
nullptr, eventId );
}
else if( actor == Eobject4 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00005( player );
},
nullptr, eventId );
}
else if( actor == Eobject5 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00006( player );
},
nullptr, eventId );
}
}
private:
void checkQuestCompletion( Entity::Player& player )
{
auto currentCC = player.getQuestUI8AL( getId() );
player.sendQuestMessage( getId(), 0, 2, currentCC + 1, 6 );
if( currentCC + 1 >= 6 )
{
player.updateQuest( getId(), SeqFinish );
}
else
{
player.setQuestUI8AL( getId(), currentCC + 1 );
}
}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
player.updateQuest( getId(), Seq1 );
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00100( player );
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00098( player );
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene( getId(), 3, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00096( player );
} );
}
void Scene00004( Entity::Player& player )
{
player.playScene( getId(), 4, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00094( player );
} );
}
void Scene00005( Entity::Player& player )
{
player.playScene( getId(), 5, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00092( player );
} );
}
void Scene00006( Entity::Player& player )
{
player.playScene( getId(), 6, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00090( player );
} );
}
void Scene00007( Entity::Player& player )
{
player.playScene( getId(), 7, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00088( player );
}
else
{
Scene00087( player );
}
} );
}
void Scene00087( Entity::Player& player )
{
player.playScene( getId(), 87, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 87, 0, 0, 0 );
} );
}
void Scene00088( Entity::Player& player )
{
player.playScene( getId(), 88, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0) )
{
player.setQuestUI8AL( getId(), 0 );
player.finishQuest( getId() );
}
}
} );
}
void Scene00089( Entity::Player& player )
{
player.playScene( getId(), 89, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00090( Entity::Player& player )
{
player.playScene( getId(), 90, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 2, true );
} );
}
void Scene00091( Entity::Player& player )
{
player.playScene( getId(), 91, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00092( Entity::Player& player )
{
player.playScene( getId(), 92, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 3, true );
} );
}
void Scene00093( Entity::Player& player )
{
player.playScene( getId(), 93, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00094( Entity::Player& player )
{
player.playScene( getId(), 94, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 4, true );
} );
}
void Scene00095( Entity::Player& player )
{
player.playScene( getId(), 95, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00096( Entity::Player& player )
{
player.playScene( getId(), 96, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 5, true );
} );
}
void Scene00097( Entity::Player& player )
{
player.playScene( getId(), 97, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00098( Entity::Player& player )
{
player.playScene( getId(), 98, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 6, true );
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 7, true );
} );
}
};

View file

@ -0,0 +1,322 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubFst015_00042
// Quest Name: Sylphic Gratitude
// Quest ID: 65578
// Start NPC: 1000286
// End NPC: 1000286
class SubFst015 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestBitFlag8
// GetQuestUI8AL
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardGil = 110;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1000286;
static constexpr auto Eobject0 = 2000020;
static constexpr auto Eobject1 = 2000021;
static constexpr auto Eobject2 = 2000022;
static constexpr auto Eobject3 = 2000023;
static constexpr auto Eobject4 = 2000024;
static constexpr auto Eobject5 = 2000025;
static constexpr auto EventActionSearch = 1;
public:
SubFst015() : EventScript( 65578 )
{};
~SubFst015()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 && !player.hasQuest( getId() ) )
{
Scene00000( player );
}
else if( actor == Actor0 )
{
Scene00007( player );
}
//EOBJECTS CHECK
else if( actor == Eobject0 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00001( player );
},
nullptr, eventId );
}
else if( actor == Eobject1 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00002( player );
},
nullptr, eventId );
}
else if( actor == Eobject2 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00003( player );
},
nullptr, eventId );
}
else if( actor == Eobject3 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00004( player );
},
nullptr, eventId );
}
else if( actor == Eobject4 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00005( player );
},
nullptr, eventId );
}
else if( actor == Eobject5 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00006( player );
},
nullptr, eventId );
}
}
private:
void checkQuestCompletion( Entity::Player& player )
{
auto currentCC = player.getQuestUI8AL( getId() );
player.sendQuestMessage( getId(), 0, 2, currentCC + 1, 6 );
if( currentCC + 1 >= 6 )
{
player.updateQuest( getId(), SeqFinish );
}
else
{
player.setQuestUI8AL( getId(), currentCC + 1 );
}
}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), Seq1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00100( player );
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00098( player );
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene( getId(), 3, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00096( player );
} );
}
void Scene00004( Entity::Player& player )
{
player.playScene( getId(), 4, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00094( player );
} );
}
void Scene00005( Entity::Player& player )
{
player.playScene( getId(), 5, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00092( player );
} );
}
void Scene00006( Entity::Player& player )
{
player.playScene( getId(), 6, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00090( player );
} );
}
void Scene00007( Entity::Player& player )
{
player.playScene( getId(), 7, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if (player.giveQuestRewards( getId(), 0) )
{
player.finishQuest( getId() );
}
}
} );
}
void Scene00089( Entity::Player& player )
{
player.playScene( getId(), 89, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00090( Entity::Player& player )
{
player.playScene( getId(), 90, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 2, true );
} );
}
void Scene00091( Entity::Player& player )
{
player.playScene( getId(), 91, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00092( Entity::Player& player )
{
player.playScene( getId(), 92, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 3, true );
} );
}
void Scene00093( Entity::Player& player )
{
player.playScene( getId(), 93, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00094( Entity::Player& player )
{
player.playScene( getId(), 94, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 4, true );
} );
}
void Scene00095( Entity::Player& player )
{
player.playScene( getId(), 95, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00096( Entity::Player& player )
{
player.playScene( getId(), 96, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 5, true );
} );
}
void Scene00097( Entity::Player& player )
{
player.playScene( getId(), 97, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00098( Entity::Player& player )
{
player.playScene( getId(), 98, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 6, true );
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 7, true );
} );
}
};

View file

@ -0,0 +1,84 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubFst019_00049
// Quest Name: I Am Millicent, Hear Me Roar
// Quest ID: 65585
// Start NPC: 1000788
// End NPC: 1000429
class SubFst019 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
enum Sequence : uint8_t
{
Seq0 = 0,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardItem = 4551;
static constexpr auto RewardItemCount = 5;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1000788;
static constexpr auto Actor1 = 1000429;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq1Actor1 = 1;
public:
SubFst019() : EventScript( 65585 )
{};
~SubFst019()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), SeqFinish );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,102 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubFst026_00170
// Quest Name: Jumping at Shadows
// Quest ID: 65706
// Start NPC: 1000629
// End NPC: 1000629
//NEED TEST KILLCREDIT
class SubFst026 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 100;
static constexpr auto RewardGil = 135;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1000629;
static constexpr auto Enemy0 = 9;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq2Actor0 = 1;
public:
SubFst026() : EventScript( 65706 )
{};
~SubFst026()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 && !player.hasQuest( getId() ) )
{
Scene00000( player );
}
else if( actor == Actor0 && player.getQuestSeq( getId() ) == SeqFinish )
{
Scene00001( player );
}
}
void onMobKill( Entity::Player& player, uint64_t npcId )
{
if(npcId != Enemy0)
return;
auto currentKC = player.getQuestUI8AL( getId() ) + 1;
if( currentKC >= 6 )
player.updateQuest( getId(), SeqFinish );
else
{
player.setQuestUI8AL( getId(), currentKC );
player.sendQuestMessage( getId(), 0, 2, currentKC, 6 );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), Seq1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if ( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,109 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubFst029_00172
// Quest Name: More than a Flesh Wound
// Quest ID: 65708
// Start NPC: 1000430
// End NPC: 1000430
class SubFst029 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AH
enum Sequence : uint8_t
{
Seq0 = 0,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 100;
static constexpr auto RewardGil = 146;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1000430;
static constexpr auto Ritem0 = 4552;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq1Actor0 = 1;
static constexpr auto Seq1Actor0Npctradeno = 99;
static constexpr auto Seq1Actor0Npctradeok = 100;
public:
SubFst029() : EventScript( 65708 )
{};
~SubFst029()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
//NOT SAFE - CRASH
/*if( actor == SubFst029::Actor0 && !player.hasQuest( getId() ) )
{
Scene00000( player );
}
if( actor == SubFst029::Actor0 && player.getQuestSeq ( getId() ) == 255 )
{
Scene00001( player );
}*/
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), SeqFinish );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00100( player );
}
else
{
Scene00099( player );
}
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 99, 0, 0, 0 );
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
} );
}
};

View file

@ -0,0 +1,191 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include <ScriptObject.h>
// Quest Script: SubFst030_00173
// Quest Name: The Nose Knows
// Quest ID: 65709
// Start NPC: 1000632
// End NPC: 1000632
class SubFst030 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
Seq2 = 2,
Seq3 = 3,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 100;
static constexpr auto RewardItem = 4551;
static constexpr auto RewardItemCount = 10;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1000632;
static constexpr auto Actor1 = 1000784;
static constexpr auto Actor2 = 1000764;
static constexpr auto Eobject0 = 2000146;
static constexpr auto EventActionGatherShort = 6;
static constexpr auto Item0 = 2000140;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq1Actor1 = 1;
static constexpr auto Seq2Eobject0 = 2;
static constexpr auto Seq2Eobject0Eventactionno = 99;
static constexpr auto Seq2Eobject0Eventactionok = 100;
static constexpr auto Seq3Actor2 = 3;
static constexpr auto Seq3Actor2Npctradeno = 97;
static constexpr auto Seq3Actor2Npctradeok = 98;
static constexpr auto Seq4Actor0 = 4;
public:
SubFst030() : EventScript( 65709 )
{};
~SubFst030()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 && !player.hasQuest( getId() ) )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
else if( actor == Actor2 )
{
Scene00003( player );
}
else if( actor == Actor0 )
{
Scene00004( player );
}
// EOBJECT
else if( actor == Eobject0 )
{
player.eventActionStart( getId(), 0x06,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00002( player );
},
nullptr, eventId );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), Seq1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.updateQuest( getId(), Seq2 );
player.sendQuestMessage( getId(), 0, 2, 0, 0 );
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene(getId(), 2, HIDE_HOTBAR,
[&](Entity::Player& player, const Event::SceneResult& result)
{
Scene00100( player );
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene(getId(), 3, HIDE_HOTBAR,
[&](Entity::Player& player, const Event::SceneResult& result)
{
if( result.param2 == 1 )
{
Scene00098( player );
}
else
Scene00097( player );
} );
}
void Scene00004( Entity::Player& player )
{
player.playScene(getId(), 4, HIDE_HOTBAR,
[&](Entity::Player& player, const Event::SceneResult& result)
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
void Scene00097( Entity::Player& player )
{
player.playScene( getId(), 97, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 97, 0, 0, 0 );
} );
}
void Scene00098( Entity::Player& player )
{
player.playScene( getId(), 98, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.updateQuest( getId(), SeqFinish );
player.sendQuestMessage( getId(), 2, 2, 0, 0 );
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 99, 0, 0, 0 );
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.updateQuest( getId(), 3 );
player.sendQuestMessage( getId(), 1, 2, 0, 0 );
player.setQuestUI8FL( getId(), 1 );
player.setQuestUI8BH( getId(), 1 );
} );
}
};

View file

@ -0,0 +1,134 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubFst041_00197
// Quest Name: Splitting Shells
// Quest ID: 65733
// Start NPC: 1000432
// End NPC: 1000411
//NEED TEST KILLCREDIT
class SubFst041 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 100;
uint32_t RewardItemOptional[3] = { 4657, 4658, 5823 };
uint32_t RewardItemOptionalCount[3] = { 3, 3, 3 };
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1000432;
static constexpr auto Actor1 = 1000411;
static constexpr auto Enemy0 = 159;
static constexpr auto Item0 = 2000142;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq2Actor1 = 1;
static constexpr auto Seq2Actor1Npctradeno = 99;
static constexpr auto Seq2Actor1Npctradeok = 100;
public:
SubFst041() : EventScript( 65733 )
{};
~SubFst041()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
if( actor == Actor1 )
{
Scene00001(player);
}
}
void onMobKill( Entity::Player& player, uint64_t npcId )
{
if( npcId != Enemy0 )
return;
auto currentKC = player.getQuestUI8BH( getId() ) + 1;
if( currentKC >= 6 )
player.updateQuest( getId(), SeqFinish );
else
{
player.setQuestUI8BH( getId(), currentKC );
player.sendQuestMessage( getId(), 0, 2, currentKC, 6 );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), Seq1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00100( player );
}
else
{
Scene00099( player );
}
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 99, 0, 0, 0 );
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.setQuestUI8BH( getId(), 0 );
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,335 @@
#include <Script/NativeScriptApi.h>
#include <Actor/Player.h>
#include "Event/EventHelper.h"
#include <ScriptObject.h>
// Quest Script: SubSea001_00111
// Quest Name: Making a Name
// Quest ID: 65647
// Start NPC: 1002698
// End NPC: 1003604
class SubSea001 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestBitFlag8
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
Seq2 = 2,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardItem = 4551;
static constexpr auto RewardItemCount = 2;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1002698;
static constexpr auto Actor1 = 1000969;
static constexpr auto Actor2 = 1003604;
static constexpr auto Eobject0 = 2001563;
static constexpr auto Eobject1 = 2001564;
static constexpr auto Eobject2 = 2001565;
static constexpr auto Eobject3 = 2001566;
static constexpr auto Eobject4 = 2001567;
static constexpr auto Eobject5 = 2001568;
static constexpr auto EventActionProcess = 14;
static constexpr auto Item0 = 2000447;
static constexpr auto Poprange0 = 4161445;
static constexpr auto Quest0 = 65644;
static constexpr auto Quest1 = 65645;
static constexpr auto Territorytype0 = 129;
public:
SubSea001() : EventScript( 65647 )
{};
~SubSea001()
{};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00002( player );
}
else if( actor == Actor2 )
{
Scene00016( player );
}
//EOBJECTS CHECK
else if( actor == Eobject0 )
{
player.eventActionStart( getId(), 0x0E,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00003( player );
},
nullptr, eventId );
}
else if( actor == Eobject1 )
{
player.eventActionStart( getId(), 0x0E,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00005( player );
},
nullptr, eventId );
}
else if( actor == Eobject2 )
{
player.eventActionStart( getId(), 0x0E,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00007( player );
},
nullptr, eventId );
}
else if( actor == Eobject3 )
{
player.eventActionStart( getId(), 0x0E,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00009( player );
},
nullptr, eventId );
}
else if( actor == Eobject4 )
{
player.eventActionStart( getId(), 0x0E,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00011( player );
},
nullptr, eventId );
}
else if( actor == Eobject5 )
{
player.eventActionStart( getId(), 0x0E,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00013( player );
},
nullptr, eventId );
}
};
private:
void checkQuestCompletion( Entity::Player& player )
{
auto currentCC = player.getQuestUI8BH( getId() );
player.sendQuestMessage( getId(), 1, 3, currentCC + 1, 6 );
if( currentCC + 1 >= 6 )
{
player.updateQuest( getId(), SeqFinish );
player.setQuestUI8BH( getId(), currentCC + 1 );
player.setQuestUI8AL( getId(), currentCC + 1 );
}
else
{
player.setQuestUI8BH( getId(), currentCC + 1 );
player.setQuestUI8AL( getId(), currentCC + 1 );
}
}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
player.updateQuest( getId(), 1 );
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( player.hasQuest( Quest0 ) || player.hasQuest( Quest1 ) )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), 2 );
player.changePosition( 10, 21, 13, -2 );
player.forceZoneing( Territorytype0 ); // teleport to real limsa
}
}
else return;
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene( getId(), 3, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00004( player );
} );
}
void Scene00004( Entity::Player& player )
{
player.playScene( getId(), 4, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 7, true );
} );
}
void Scene00005( Entity::Player& player )
{
player.playScene( getId(), 5, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00006( player );
} );
}
void Scene00006( Entity::Player& player )
{
player.playScene( getId(), 6, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 6, true );
} );
}
void Scene00007( Entity::Player& player )
{
player.playScene( getId(), 7, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00008( player );
} );
}
void Scene00008( Entity::Player& player )
{
player.playScene( getId(), 8, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 5, true );
} );
}
void Scene00009( Entity::Player& player )
{
player.playScene( getId(), 9, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00010( player );
} );
}
void Scene00010( Entity::Player& player )
{
player.playScene( getId(), 10, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 4, true );
} );
}
void Scene00011( Entity::Player& player )
{
player.playScene( getId(), 11, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00012( player );
} );
}
void Scene00012( Entity::Player& player )
{
player.playScene( getId(), 12, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 3, true );
} );
}
void Scene00013( Entity::Player& player )
{
player.playScene( getId(), 13, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00014( player );
} );
}
void Scene00014( Entity::Player& player )
{
player.playScene( getId(), 14, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 2, true );
} );
}
void Scene00015( Entity::Player& player )
{
player.playScene( getId(), 15, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.playScene( getId(), 15, 0, 0, 0 );
} );
}
void Scene00016( Entity::Player& player )
{
player.playScene( getId(), 16, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00017( player );
}
} );
}
void Scene00017( Entity::Player& player )
{
player.playScene( getId(), 17, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
player.finishQuest( getId() );
}
} );
}
};

View file

@ -0,0 +1,106 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubWil000_00149
// Quest Name: Due Diligence
// Quest ID: 65685
// Start NPC: 1001285
// End NPC: 1002278
class SubWil000 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardGil = 103;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1001285;
static constexpr auto Actor1 = 1002278;
static constexpr auto Item0 = 2000136;
public:
SubWil000() : EventScript( 65685 ){};
~SubWil000(){};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), SeqFinish );
player.setQuestUI8BH( getId(), 1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00100( player );
}
else
{
Scene00099( player );
}
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,81 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubWil001_00150
// Quest Name: Motivational Speaking
// Quest ID: 65686
// Start NPC: 1001287
// End NPC: 1001288
class SubWil001 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
enum Sequence : uint8_t
{
Seq0 = 0,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardItem = 4551;
static constexpr auto RewardItemCount = 2;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1001287;
static constexpr auto Actor1 = 1001288;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq1Actor1 = 1;
public:
SubWil001() : EventScript( 65686 ) {};
~SubWil001() {};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
}
private:
void Scene00000(Entity::Player& player)
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), SeqFinish );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,109 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubWil002_00151
// Quest Name: Gil for Gold
// Quest ID: 65687
// Start NPC: 1001288
// End NPC: 1001289
class SubWil002 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
uint16_t RewardItemOptional[2] = { 4551, 4555 };
uint16_t RewardItemOptionalCount[2] = { 3, 3 };
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1001288;
static constexpr auto Actor1 = 1001289;
static constexpr auto Item0 = 2000245;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq1Actor1 = 1;
static constexpr auto Seq1Actor1Npctradeno = 99;
static constexpr auto Seq1Actor1Npctradeok = 100;
public:
SubWil002() : EventScript( 65687 ){};
~SubWil002(){};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), SeqFinish );
player.setQuestUI8BH( getId(), 1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00100( player );
}
else
{
Scene00099( player );
}
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
player.finishQuest( getId() );
}
} );
}
};

View file

@ -0,0 +1,261 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubWil004_00153
// Quest Name: Unholy Matrimony
// Quest ID: 65689
// Start NPC: 1001291
// End NPC: 1003896
class SubWil004 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestBitFlag8
// GetQuestUI8AH
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
Seq2 = 2,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardItem = 4551;
static constexpr auto RewardItemCount = 5;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1001291;
static constexpr auto Actor1 = 1001292;
static constexpr auto Actor2 = 1003896;
static constexpr auto Eobject0 = 2000691;
static constexpr auto Eobject1 = 2000692;
static constexpr auto Eobject2 = 2000693;
static constexpr auto EventActionSearch = 1;
static constexpr auto Item0 = 2000137;
public:
SubWil004() : EventScript( 65689 ){};
~SubWil004(){};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
else if( actor == Actor2 )
{
Scene00008( player );
}
//EOBJECTS CHECK
else if( actor == Eobject0 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00003( player );
},
nullptr, eventId );
}
else if( actor == Eobject1 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00005( player );
},
nullptr, eventId );
}
else if( actor == Eobject2 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00007( player );
},
nullptr, eventId );
}
}
private:
void checkQuestCompletion( Entity::Player& player )
{
auto currentCC = player.getQuestUI8AL( getId() );
auto currentQC = player.getQuestUI8BH( getId() );
player.sendQuestMessage( getId(), 1, 3, currentCC + 1, 3 );
if( currentCC + 1 >= 3 )
{
player.updateQuest( getId(), SeqFinish );
player.setQuestUI8AH( getId(), currentCC + 1 );
player.setQuestUI8AL( getId(), currentCC + 1 );
player.setQuestUI8BH( getId(), 0 );
}
else
{
player.setQuestUI8AH( getId(), currentCC + 1 );
player.setQuestUI8AL( getId(), currentCC + 1 );
player.setQuestUI8BH( getId(), currentQC - 1 );
}
}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), Seq1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.updateQuest( getId(), Seq2 );
player.sendQuestMessage( getId(), 0, 2, 0, 0 );
player.setQuestUI8BH( getId(), 3 );
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00003( player );
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene( getId(), 3, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 7, true );
} );
}
void Scene00004( Entity::Player& player )
{
player.playScene( getId(), 4, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00005( player );
} );
}
void Scene00005( Entity::Player& player )
{
player.playScene( getId(), 5, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 6, true );
} );
}
void Scene00006( Entity::Player& player )
{
player.playScene( getId(), 6, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00007( player );
} );
}
void Scene00007( Entity::Player& player )
{
player.playScene( getId(), 7, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 5, true );
} );
}
void Scene00008( Entity::Player& player )
{
player.playScene( getId(), 8, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
void Scene00009( Entity::Player& player )
{
player.playScene( getId(), 9, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00010( Entity::Player& player )
{
player.playScene( getId(), 10, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00011( Entity::Player& player )
{
player.playScene( getId(), 11, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00012( Entity::Player& player )
{
player.playScene( getId(), 12, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00013( Entity::Player& player )
{
player.playScene( getId(), 13, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00014( Entity::Player& player )
{
player.playScene( getId(), 14, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
};

View file

@ -0,0 +1,123 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubWil006_00165
// Quest Name: The Great Gladiator
// Quest ID: 65701
// Start NPC: 1001295
// End NPC: 1001299
class SubWil006 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardItem = 5594;
static constexpr auto RewardItemCount = 10;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1001295;
static constexpr auto Actor1 = 1002280;
static constexpr auto Actor2 = 1001299;
static constexpr auto Item0 = 2000201;
public:
SubWil006() : EventScript( 65701 ){};
~SubWil006(){};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
else if( actor == Actor2 )
{
Scene00004( player );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), Seq1 );
player.setQuestUI8BH( getId(), 1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00002( player );
}
else
{
Scene00003( player );
}
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.updateQuest( getId(), SeqFinish );
player.sendQuestMessage( getId(), 0, 2, 0, 0 );
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene( getId(), 3, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00004( Entity::Player& player )
{
player.playScene( getId(), 4, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,319 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
#include <ctime>
// Quest Script: SubWil007_00167
// Quest Name: With Open Arms
// Quest ID: 65703
// Start NPC: 1007621
// End NPC: 1007621
class SubWil007 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestBitFlag8
// GetQuestUI8AL
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
Seq2 = 2,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardGil = 102;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1007621;
static constexpr auto Actor1 = 1001297;
static constexpr auto Actor2 = 1001692;
static constexpr auto Actor3 = 1001693;
static constexpr auto Actor4 = 1001697;
static constexpr auto Actor5 = 1001698;
static constexpr auto FirstQuest = 66130;
public:
SubWil007() : EventScript( 65703 ){};
~SubWil007(){};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 && !player.hasQuest( getId() ) )
{
Scene00000( player );
}
if( actor == Actor0 && player.getQuestSeq( getId() ) == SeqFinish )
{
Scene00020( player );
}
else if( actor == Actor1 )
{
Scene00005( player );
}
else if( actor == Actor2 )
{
Scene00008( player );
}
else if( actor == Actor3 )
{
Scene00011( player );
}
else if( actor == Actor4 )
{
Scene00014( player );
}
else if( actor == Actor5 )
{
Scene00017( player );
}
}
void onEmote( uint64_t actorId, uint32_t eventId, uint32_t emoteId, Entity::Player& player ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 && emoteId == 41 && player.getQuestSeq( getId() ) == Seq1 )
{
Scene00003( player );
}
else if( actor == Actor1 && emoteId == 41 && player.getQuestSeq( getId() ) == Seq2 )
{
Scene00006( player );
}
else if( actor == Actor2 && emoteId == 41 && player.getQuestSeq( getId() ) == Seq2 )
{
Scene00009( player );
}
else if( actor == Actor3 && emoteId == 41 && player.getQuestSeq( getId() ) == Seq2 )
{
Scene00012( player );
}
else if( actor == Actor4 && emoteId == 41 && player.getQuestSeq( getId() ) == Seq2 )
{
Scene00015( player );
}
else if( actor == Actor5 && emoteId == 41 && player.getQuestSeq( getId() ) == Seq2 )
{
Scene00018( player );
}
}
private:
void checkQuestCompletion( Entity::Player& player )
{
auto currentQC = player.getQuestUI8AL( getId() ) + 1;
if( currentQC >= 5 )
{
player.updateQuest( getId(), SeqFinish );
player.sendQuestMessage( getId(), 1, 2, currentQC, 5 );
}
else
{
player.setQuestUI8AL( getId(), currentQC );
player.sendQuestMessage( getId(), 1, 2, currentQC, 5 );
}
}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00001( player );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.updateQuest( getId(), Seq1 );
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene( getId(), 3, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
player.updateQuest( getId(), Seq2 );
player.sendQuestMessage( getId(), 0, 1, 0, 0 );
} );
}
void Scene00004( Entity::Player& player )
{
player.playScene( getId(), 4, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00005( Entity::Player& player )
{
player.playScene( getId(), 5, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00006( Entity::Player& player )
{
player.playScene( getId(), 6, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion(player);
player.setQuestBitFlag8(getId(), 7, true);
} );
}
void Scene00007( Entity::Player& player )
{
player.playScene( getId(), 7, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00008( Entity::Player& player )
{
player.playScene( getId(), 8, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00009( Entity::Player& player )
{
player.playScene( getId(), 9, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 6, true );
} );
}
void Scene00010( Entity::Player& player )
{
player.playScene( getId(), 10, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00011( Entity::Player& player )
{
player.playScene( getId(), 11, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00012( Entity::Player& player )
{
player.playScene( getId(), 12, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 5, true );
} );
}
void Scene00013( Entity::Player& player )
{
player.playScene( getId(), 13, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00014( Entity::Player& player )
{
player.playScene( getId(), 14, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00015( Entity::Player& player )
{
player.playScene( getId(), 15, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 4, true );
} );
}
void Scene00016( Entity::Player& player )
{
player.playScene( getId(), 16, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00017( Entity::Player& player )
{
player.playScene( getId(), 17, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00018( Entity::Player& player )
{
player.playScene( getId(), 18, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 3, true );
} );
}
void Scene00019( Entity::Player& player )
{
player.playScene( getId(), 19, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00020( Entity::Player& player )
{
player.playScene( getId(), 20, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,312 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubWil018_00396
// Quest Name: No Lady Is an Island
// Quest ID: 65932
// Start NPC: 1001675
// End NPC: 1001675
class SubWil018 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestBitFlag8
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
Seq1 = 1,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardGil = 102;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1001675;
static constexpr auto Eobject0 = 2000695;
static constexpr auto Eobject1 = 2000696;
static constexpr auto Eobject2 = 2000697;
static constexpr auto Eobject3 = 2001089;
static constexpr auto Eobject4 = 2001090;
static constexpr auto EventActionSearch = 1;
static constexpr auto Item0 = 2000198;
public:
SubWil018() : EventScript( 65932 ){};
~SubWil018(){};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 && !player.hasQuest( getId() ) )
{
Scene00000( player );
}
if( actor == Actor0 )
{
Scene00016( player );
}
//EOBJECTS CHECK
else if( actor == Eobject0 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00001( player );
},
nullptr, eventId);
}
else if( actor == Eobject1 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00004( player );
},
nullptr, eventId );
}
else if( actor == Eobject2 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00007( player );
},
nullptr, eventId );
}
else if( actor == Eobject3 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00010( player );
},
nullptr, eventId );
}
else if( actor == Eobject4 )
{
player.eventActionStart( getId(), 0x01,
[&]( Entity::Player& player, uint32_t eventId, uint64_t additional )
{
Scene00013( player );
},
nullptr, eventId );
}
}
private:
void checkQuestCompletion( Entity::Player& player )
{
auto currentCC = player.getQuestUI8AL( getId() );
player.sendQuestMessage( getId(), 0, 3, currentCC + 1, 5 );
if( currentCC + 1 >= 5 )
{
player.updateQuest( getId(), SeqFinish );
player.setQuestUI8BH( getId(), currentCC + 1 );
player.setQuestUI8AL( getId(), currentCC + 1 );
}
else
{
player.setQuestUI8BH( getId(), currentCC + 1 );
player.setQuestUI8AL( getId(), currentCC + 1 );
}
}
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), Seq1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00002( player );
} );
}
void Scene00002( Entity::Player& player )
{
player.playScene( getId(), 2, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 7, true );
} );
}
void Scene00003( Entity::Player& player )
{
player.playScene( getId(), 3, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00004( Entity::Player& player )
{
player.playScene( getId(), 4, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00005( player );
} );
}
void Scene00005( Entity::Player& player )
{
player.playScene( getId(), 5, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 6, true );
} );
}
void Scene00006( Entity::Player& player )
{
player.playScene( getId(), 6, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00007( Entity::Player& player )
{
player.playScene( getId(), 7, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00008( player );
} );
}
void Scene00008( Entity::Player& player )
{
player.playScene( getId(), 8, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 5, true );
} );
}
void Scene00009( Entity::Player& player )
{
player.playScene( getId(), 9, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00010( Entity::Player& player )
{
player.playScene( getId(), 10, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00011( player );
} );
}
void Scene00011( Entity::Player& player )
{
player.playScene( getId(), 11, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 4, true );
} );
}
void Scene00012( Entity::Player& player )
{
player.playScene( getId(), 12, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00013( Entity::Player& player )
{
player.playScene( getId(), 13, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
Scene00014(player);
} );
}
void Scene00014( Entity::Player& player )
{
player.playScene( getId(), 14, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
checkQuestCompletion( player );
player.setQuestBitFlag8( getId(), 3, true );
} );
}
void Scene00015( Entity::Player& player )
{
player.playScene( getId(), 15, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00016( Entity::Player& player )
{
player.playScene( getId(), 16, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00017( player );
}
else
{
Scene00018( player );
}
} );
}
void Scene00017( Entity::Player& player )
{
player.playScene( getId(), 17, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
void Scene00018( Entity::Player& player )
{
player.playScene( getId(), 18, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
};

View file

@ -0,0 +1,81 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubWil019_00392
// Quest Name: Decisions, Decisions
// Quest ID: 65928
// Start NPC: 1001680
// End NPC: 1001691
class SubWil019 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
enum Sequence : uint8_t
{
Seq0 = 0,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardGil = 111;
static constexpr auto RewardItem = 5539;
static constexpr auto RewardItemCount = 1;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1001680;
static constexpr auto Actor1 = 1001691;
public:
SubWil019() : EventScript( 65928 ){};
~SubWil019(){};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), SeqFinish );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,110 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubWil021_00394
// Quest Name: A Luxury Long Lost
// Quest ID: 65930
// Start NPC: 1001766
// End NPC: 1001657
class SubWil021 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardGil = 111;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1001766;
static constexpr auto Actor1 = 1001657;
static constexpr auto Item0 = 2000196;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq1Actor1 = 1;
static constexpr auto Seq1Actor1Npctradeno = 99;
static constexpr auto Seq1Actor1Npctradeok = 100;
public:
SubWil021() : EventScript( 65930 ){};
~SubWil021(){};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), SeqFinish );
player.setQuestUI8BH( getId(), 1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00100( player );
}
else
{
Scene00099( player );
}
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if(player.giveQuestRewards( getId(), 0 ) )
{
player.finishQuest( getId() );
}
}
} );
}
};

View file

@ -0,0 +1,108 @@
#include <Actor/Player.h>
#include <Event/EventHelper.h>
#include <ScriptObject.h>
// Quest Script: SubWil022_00395
// Quest Name: The Wealth of Nations
// Quest ID: 65931
// Start NPC: 1001657
// End NPC: 1001679
class SubWil022 : public EventScript
{
private:
// Basic quest information
// Quest vars / flags used
// GetQuestUI8AL
// GetQuestUI8BH
enum Sequence : uint8_t
{
Seq0 = 0,
SeqFinish = 255,
};
// Quest rewards
static constexpr auto RewardExpFactor = 50;
static constexpr auto RewardGil = 111;
// Entities found in the script data of the quest
static constexpr auto Actor0 = 1001657;
static constexpr auto Actor1 = 1001679;
static constexpr auto Item0 = 2000197;
static constexpr auto Seq0Actor0 = 0;
static constexpr auto Seq1Actor1 = 1;
static constexpr auto Seq1Actor1Npctradeno = 99;
static constexpr auto Seq1Actor1Npctradeok = 100;
public:
SubWil022() : EventScript( 65931 ){};
~SubWil022(){};
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == Actor0 )
{
Scene00000( player );
}
else if( actor == Actor1 )
{
Scene00001( player );
}
}
private:
void Scene00000( Entity::Player& player )
{
player.playScene( getId(), 0, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( getId(), SeqFinish );
player.setQuestUI8BH( getId(), 1 );
}
} );
}
void Scene00001( Entity::Player& player )
{
player.playScene( getId(), 1, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
Scene00100( player );
}
else
{
Scene00099( player );
}
} );
}
void Scene00099( Entity::Player& player )
{
player.playScene( getId(), 99, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
} );
}
void Scene00100( Entity::Player& player )
{
player.playScene( getId(), 100, HIDE_HOTBAR,
[&]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
if( player.giveQuestRewards( getId(), 0 ) )
player.finishQuest( getId() );
}
} );
}
};

Some files were not shown because too many files have changed in this diff Show more