mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-22 12:47:45 +00:00
Merge pull request #948 from Skyliegirl33/actions-war
[3.x] Sync action branch to master
This commit is contained in:
commit
6fd5720f74
90 changed files with 4039 additions and 688 deletions
50
deps/datReader/DatCategories/bg/lgb.h
vendored
50
deps/datReader/DatCategories/bg/lgb.h
vendored
|
@ -227,6 +227,8 @@ struct LGB_GROUP
|
||||||
memcpy( (char*)&refs[0], buf + offset + header.LayerSetRef + layerSetReferencedList.LayerSets, layerSetReferencedList.LayerSetCount * sizeof( LayerSetReferenced ) );
|
memcpy( (char*)&refs[0], buf + offset + header.LayerSetRef + layerSetReferencedList.LayerSets, layerSetReferencedList.LayerSetCount * sizeof( LayerSetReferenced ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entries.reserve( header.entryCount );
|
||||||
|
|
||||||
const auto entriesOffset = offset + header.entriesOffset;
|
const auto entriesOffset = offset + header.entriesOffset;
|
||||||
for( auto i = 0; i < header.entryCount; ++i )
|
for( auto i = 0; i < header.entryCount; ++i )
|
||||||
{
|
{
|
||||||
|
@ -235,41 +237,53 @@ struct LGB_GROUP
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const auto type = *reinterpret_cast< LgbEntryType* >( buf + entryOffset );
|
const auto type = *reinterpret_cast< LgbEntryType* >( buf + entryOffset );
|
||||||
if( type == LgbEntryType::BgParts )
|
switch( type )
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) );
|
case LgbEntryType::BgParts:
|
||||||
|
{
|
||||||
|
entries.emplace_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( type == LgbEntryType::Gimmick )
|
case LgbEntryType::Gimmick:
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< LGB_GIMMICK_ENTRY >( buf, entryOffset ) );
|
entries.emplace_back( std::make_shared< LGB_GIMMICK_ENTRY >( buf, entryOffset ) );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( type == LgbEntryType::EventNpc )
|
case LgbEntryType::EventNpc:
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< LGB_ENPC_ENTRY >( buf, entryOffset ) );
|
entries.emplace_back( std::make_shared< LGB_ENPC_ENTRY >( buf, entryOffset ) );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( type == LgbEntryType::EventObject )
|
case LgbEntryType::EventObject:
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) );
|
entries.emplace_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( type == LgbEntryType::ExitRange )
|
case LgbEntryType::ExitRange:
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< LGB_EXIT_RANGE_ENTRY >( buf, entryOffset ) );
|
entries.emplace_back( std::make_shared< LGB_EXIT_RANGE_ENTRY >( buf, entryOffset ) );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( type == LgbEntryType::EventRange )
|
case LgbEntryType::EventRange:
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< LGB_EVENT_RANGE_ENTRY >( buf, entryOffset ) );
|
entries.emplace_back( std::make_shared< LGB_EVENT_RANGE_ENTRY >( buf, entryOffset ) );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( type == LgbEntryType::PopRange )
|
case LgbEntryType::PopRange:
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< LGB_POP_RANGE_ENTRY >( buf, entryOffset ) );
|
entries.emplace_back( std::make_shared< LGB_POP_RANGE_ENTRY >( buf, entryOffset ) );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( type == LgbEntryType::MapRange )
|
case LgbEntryType::MapRange:
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< LGB_MAP_RANGE_ENTRY >( buf, entryOffset ) );
|
entries.emplace_back( std::make_shared< LGB_MAP_RANGE_ENTRY >( buf, entryOffset ) );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
default:
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< LgbEntry >( buf, entryOffset ) );
|
entries.emplace_back( std::make_shared< LgbEntry >( buf, entryOffset ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( std::exception& e )
|
catch( std::exception& e )
|
||||||
|
|
60
deps/datReader/Exd.cpp
vendored
60
deps/datReader/Exd.cpp
vendored
|
@ -7,50 +7,6 @@
|
||||||
|
|
||||||
using xiv::utils::bparse::extract;
|
using xiv::utils::bparse::extract;
|
||||||
|
|
||||||
|
|
||||||
namespace xiv::exd
|
|
||||||
{
|
|
||||||
struct ExdHeader
|
|
||||||
{
|
|
||||||
char magic[0x4];
|
|
||||||
uint16_t unknown;
|
|
||||||
uint16_t unknown2;
|
|
||||||
uint32_t index_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ExdRecordIndex
|
|
||||||
{
|
|
||||||
uint32_t id;
|
|
||||||
uint32_t offset;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace xiv::utils::bparse {
|
|
||||||
template<>
|
|
||||||
inline void reorder< xiv::exd::ExdHeader >( xiv::exd::ExdHeader& i_struct )
|
|
||||||
{
|
|
||||||
for( int32_t i = 0; i < 0x4; ++i )
|
|
||||||
{
|
|
||||||
xiv::utils::bparse::reorder( i_struct.magic[ i ] );
|
|
||||||
}
|
|
||||||
i_struct.unknown = xiv::utils::bparse::byteswap( i_struct.unknown );
|
|
||||||
xiv::utils::bparse::reorder( i_struct.unknown );
|
|
||||||
i_struct.unknown2 = xiv::utils::bparse::byteswap( i_struct.unknown2 );
|
|
||||||
xiv::utils::bparse::reorder( i_struct.unknown2 );
|
|
||||||
i_struct.index_size = xiv::utils::bparse::byteswap( i_struct.index_size );
|
|
||||||
xiv::utils::bparse::reorder( i_struct.index_size );
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline void reorder< xiv::exd::ExdRecordIndex >( xiv::exd::ExdRecordIndex& i_struct )
|
|
||||||
{
|
|
||||||
i_struct.id = xiv::utils::bparse::byteswap( i_struct.id );
|
|
||||||
xiv::utils::bparse::reorder( i_struct.id );
|
|
||||||
i_struct.offset = xiv::utils::bparse::byteswap( i_struct.offset );
|
|
||||||
xiv::utils::bparse::reorder( i_struct.offset );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace xiv::exd
|
namespace xiv::exd
|
||||||
{
|
{
|
||||||
Exd::Exd( std::shared_ptr< Exh > i_exh, const std::vector< std::shared_ptr< dat::File>>& i_files )
|
Exd::Exd( std::shared_ptr< Exh > i_exh, const std::vector< std::shared_ptr< dat::File>>& i_files )
|
||||||
|
@ -68,16 +24,16 @@ namespace xiv::exd
|
||||||
std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
|
std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
|
||||||
|
|
||||||
// Extract the header and skip to the record indices
|
// Extract the header and skip to the record indices
|
||||||
auto exd_header = extract< ExdHeader >( iss );
|
auto exd_header = extract< ExdHeaderMinimal >( iss );
|
||||||
iss.seekg( 0x20 );
|
iss.seekg( 0x20 );
|
||||||
|
|
||||||
// Preallocate and extract the record_indices
|
// Preallocate and extract the record_indices
|
||||||
const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndex );
|
const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndexData );
|
||||||
std::vector< ExdRecordIndex > record_indices;
|
std::vector< ExdRecordIndexData > record_indices;
|
||||||
record_indices.reserve( record_count );
|
record_indices.reserve( record_count );
|
||||||
for( uint32_t i = 0; i < record_count; ++i )
|
for( uint32_t i = 0; i < record_count; ++i )
|
||||||
{
|
{
|
||||||
auto recordIndex = extract< ExdRecordIndex >( iss );
|
auto recordIndex = extract< ExdRecordIndexData >( iss );
|
||||||
_idCache[ recordIndex.id ] = ExdCacheEntry{ file_ptr, recordIndex.offset };
|
_idCache[ recordIndex.id ] = ExdCacheEntry{ file_ptr, recordIndex.offset };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,16 +246,16 @@ namespace xiv::exd
|
||||||
std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
|
std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
|
||||||
|
|
||||||
// Extract the header and skip to the record indices
|
// Extract the header and skip to the record indices
|
||||||
auto exd_header = extract< ExdHeader >( iss );
|
auto exd_header = extract< ExdHeaderMinimal >( iss );
|
||||||
iss.seekg( 0x20 );
|
iss.seekg( 0x20 );
|
||||||
|
|
||||||
// Preallocate and extract the record_indices
|
// Preallocate and extract the record_indices
|
||||||
const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndex );
|
const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndexData );
|
||||||
std::vector< ExdRecordIndex > record_indices;
|
std::vector< ExdRecordIndexData > record_indices;
|
||||||
record_indices.reserve( record_count );
|
record_indices.reserve( record_count );
|
||||||
for( uint32_t i = 0; i < record_count; ++i )
|
for( uint32_t i = 0; i < record_count; ++i )
|
||||||
{
|
{
|
||||||
record_indices.emplace_back( extract< ExdRecordIndex >( iss ) );
|
record_indices.emplace_back( extract< ExdRecordIndexData >( iss ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( auto& record_index : record_indices )
|
for( auto& record_index : record_indices )
|
||||||
|
|
185
deps/datReader/Exd.h
vendored
185
deps/datReader/Exd.h
vendored
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
@ -12,6 +13,49 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "Exh.h"
|
#include "Exh.h"
|
||||||
#include "bparse.h"
|
#include "bparse.h"
|
||||||
|
|
||||||
|
namespace xiv::exd
|
||||||
|
{
|
||||||
|
struct ExdHeaderMinimal {
|
||||||
|
char magic[ 0x4 ];
|
||||||
|
uint16_t unknown;
|
||||||
|
uint16_t unknown2;
|
||||||
|
uint32_t index_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExdRecordIndexData {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t offset;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace xiv::utils::bparse
|
||||||
|
{
|
||||||
|
template<>
|
||||||
|
inline void reorder< xiv::exd::ExdHeaderMinimal >( xiv::exd::ExdHeaderMinimal& i_struct )
|
||||||
|
{
|
||||||
|
for( int32_t i = 0; i < 0x4; ++i )
|
||||||
|
{
|
||||||
|
xiv::utils::bparse::reorder( i_struct.magic[ i ] );
|
||||||
|
}
|
||||||
|
i_struct.unknown = xiv::utils::bparse::byteswap( i_struct.unknown );
|
||||||
|
xiv::utils::bparse::reorder( i_struct.unknown );
|
||||||
|
i_struct.unknown2 = xiv::utils::bparse::byteswap( i_struct.unknown2 );
|
||||||
|
xiv::utils::bparse::reorder( i_struct.unknown2 );
|
||||||
|
i_struct.index_size = xiv::utils::bparse::byteswap( i_struct.index_size );
|
||||||
|
xiv::utils::bparse::reorder( i_struct.index_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void reorder< xiv::exd::ExdRecordIndexData >( xiv::exd::ExdRecordIndexData& i_struct )
|
||||||
|
{
|
||||||
|
i_struct.id = xiv::utils::bparse::byteswap( i_struct.id );
|
||||||
|
xiv::utils::bparse::reorder( i_struct.id );
|
||||||
|
i_struct.offset = xiv::utils::bparse::byteswap( i_struct.offset );
|
||||||
|
xiv::utils::bparse::reorder( i_struct.offset );
|
||||||
|
}
|
||||||
|
};// namespace xiv::utils::bparse
|
||||||
|
|
||||||
namespace xiv::exd
|
namespace xiv::exd
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -186,6 +230,147 @@ namespace xiv::exd
|
||||||
// Get all rows
|
// Get all rows
|
||||||
const std::map< uint32_t, std::vector< Field > >& get_rows();
|
const std::map< uint32_t, std::vector< Field > >& get_rows();
|
||||||
|
|
||||||
|
// Get all rows
|
||||||
|
template< typename T >
|
||||||
|
const std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > get_sheet_rows()
|
||||||
|
{
|
||||||
|
std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > sheets;
|
||||||
|
|
||||||
|
// Iterates over all the files
|
||||||
|
const uint32_t member_count = static_cast< uint32_t >( _exh->get_members().size() );
|
||||||
|
for( auto& file_ptr : _files )
|
||||||
|
{
|
||||||
|
// Get a stream
|
||||||
|
std::vector< char > dataCpy = file_ptr->get_data_sections().front();
|
||||||
|
std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
|
||||||
|
|
||||||
|
// Extract the header and skip to the record indices
|
||||||
|
auto exd_header = xiv::utils::bparse::extract< ExdHeaderMinimal >( iss );
|
||||||
|
iss.seekg( 0x20 );
|
||||||
|
|
||||||
|
// Preallocate and extract the record_indices
|
||||||
|
const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndexData );
|
||||||
|
std::vector< ExdRecordIndexData > record_indices;
|
||||||
|
record_indices.reserve( record_count );
|
||||||
|
for( uint32_t i = 0; i < record_count; ++i )
|
||||||
|
{
|
||||||
|
record_indices.emplace_back( xiv::utils::bparse::extract< ExdRecordIndexData >( iss ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( auto& record_index : record_indices )
|
||||||
|
{
|
||||||
|
auto cacheEntryIt = _idCache.find( record_index.id );
|
||||||
|
if( cacheEntryIt == _idCache.end() )
|
||||||
|
throw std::out_of_range( "Id not found: " + std::to_string( record_index.id ) );
|
||||||
|
|
||||||
|
auto pSheet = std::make_shared< Excel::ExcelStruct< T > >();
|
||||||
|
|
||||||
|
// Get the vector fields for the given record and preallocate it
|
||||||
|
auto fields = _data[ record_index.id ];
|
||||||
|
fields.reserve( member_count );
|
||||||
|
iss.seekg( cacheEntryIt->second.offset + 6 );
|
||||||
|
|
||||||
|
iss.read( reinterpret_cast<char*>( &pSheet.get()->_data ), sizeof( T ) );
|
||||||
|
|
||||||
|
int stringCount = 0;
|
||||||
|
for( auto& member_entry : _exh->get_exh_members() )
|
||||||
|
{
|
||||||
|
|
||||||
|
// Seek to the position of the member to extract.
|
||||||
|
// 6 is because we have uint32_t/uint16_t at the start of each record
|
||||||
|
iss.seekg( cacheEntryIt->second.offset + 6 + member_entry.offset );
|
||||||
|
|
||||||
|
// Switch depending on the type to extract
|
||||||
|
switch( member_entry.type )
|
||||||
|
{
|
||||||
|
case DataType::string:
|
||||||
|
// Extract the offset to the actual string
|
||||||
|
// Seek to it then extract the actual string
|
||||||
|
{
|
||||||
|
auto string_offset = xiv::utils::bparse::extract< uint32_t >( iss, "string_offset", false );
|
||||||
|
iss.seekg( cacheEntryIt->second.offset + 6 + _exh->get_header().data_offset + string_offset );
|
||||||
|
std::string value = xiv::utils::bparse::extract_cstring( iss, "string" );
|
||||||
|
auto it = pSheet->_strings.insert( pSheet->_strings.end(), value );
|
||||||
|
*reinterpret_cast< uint32_t* >( pSheet->ptr() + member_entry.offset ) =
|
||||||
|
static_cast< uint32_t >( std::distance( pSheet->_strings.begin(), it ) );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DataType::boolean:
|
||||||
|
xiv::utils::bparse::extract< bool >( iss, "bool" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DataType::int8:
|
||||||
|
xiv::utils::bparse::extract< int8_t >( iss, "int8_t" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DataType::uint8:
|
||||||
|
xiv::utils::bparse::extract< uint8_t >( iss, "uint8_t" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case DataType::int16:
|
||||||
|
{
|
||||||
|
int16_t value = xiv::utils::bparse::extract< int16_t >( iss, "int16_t", false );
|
||||||
|
*reinterpret_cast< int16_t* >( pSheet->ptr() + member_entry.offset ) = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DataType::uint16:
|
||||||
|
{
|
||||||
|
uint16_t value = xiv::utils::bparse::extract< uint16_t >( iss, "uint16_t", false );
|
||||||
|
*reinterpret_cast< uint16_t* >( pSheet->ptr() + member_entry.offset ) = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DataType::int32:
|
||||||
|
{
|
||||||
|
int32_t value = xiv::utils::bparse::extract< int32_t >( iss, "int32_t", false );
|
||||||
|
*reinterpret_cast< int32_t* >( pSheet->ptr() + member_entry.offset ) = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DataType::uint32:
|
||||||
|
{
|
||||||
|
uint32_t value = xiv::utils::bparse::extract< uint32_t >( iss, "uint32_t", false );
|
||||||
|
*reinterpret_cast< uint32_t* >( pSheet->ptr() + member_entry.offset ) = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DataType::float32:
|
||||||
|
{
|
||||||
|
float value = xiv::utils::bparse::extract< float >( iss, "float", false );
|
||||||
|
*reinterpret_cast< float* >( pSheet->ptr() + member_entry.offset ) = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DataType::uint64:
|
||||||
|
{
|
||||||
|
uint64_t value = xiv::utils::bparse::extract< uint64_t >( iss, "uint64_t", false );
|
||||||
|
*reinterpret_cast< uint64_t* >( pSheet->ptr() + member_entry.offset ) = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
auto type = static_cast< uint16_t >( member_entry.type );
|
||||||
|
if( type < 0x19 || type > 0x20 )
|
||||||
|
throw std::runtime_error( "Unknown DataType: " + std::to_string( type ) );
|
||||||
|
uint64_t val = xiv::utils::bparse::extract< uint64_t >( iss, "bool" );
|
||||||
|
int32_t shift = type - 0x19;
|
||||||
|
int32_t i = 1 << shift;
|
||||||
|
val &= i;
|
||||||
|
fields.emplace_back( ( val & i ) == i );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sheets[ record_index.id ] = pSheet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sheets;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Data indexed by the ID of the row, the vector is field with the same order as exh.members
|
// Data indexed by the ID of the row, the vector is field with the same order as exh.members
|
||||||
std::map< uint32_t, std::vector< Field > > _data;
|
std::map< uint32_t, std::vector< Field > > _data;
|
||||||
|
|
|
@ -983,74 +983,64 @@ namespace Sapphire::Common
|
||||||
LimitBreak = 8,
|
LimitBreak = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ActionEffectType : uint8_t
|
enum CalcResultType : uint8_t
|
||||||
{
|
{
|
||||||
CALC_RESULT_TYPE_NONE = 0x0,
|
TypeNone = 0x0,
|
||||||
CALC_RESULT_TYPE_MISS = 0x1,
|
TypeMiss = 0x1,
|
||||||
CALC_RESULT_TYPE_RESIST = 0x2,
|
TypeResist = 0x2,
|
||||||
CALC_RESULT_TYPE_DAMAGE_HP = 0x3,
|
TypeDamageHp = 0x3,
|
||||||
CALC_RESULT_TYPE_RECOVER_HP = 0x4,
|
TypeRecoverHp = 0x4,
|
||||||
CALC_RESULT_TYPE_CRITICAL_DAMAGE_HP = 0x5,
|
TypeCriticalDamageHp = 0x5,
|
||||||
CALC_RESULT_TYPE_CRITICAL_RECOVER_HP = 0x6,
|
TypeCriticalRecoverHp = 0x6,
|
||||||
CALC_RESULT_TYPE_GUARD = 0x7,
|
TypeGuard = 0x7,
|
||||||
CALC_RESULT_TYPE_PARRY = 0x8,
|
TypeParry = 0x8,
|
||||||
CALC_RESULT_TYPE_INVALID = 0x9,
|
TypeInvalid = 0x9,
|
||||||
CALC_RESULT_TYPE_UNEFFECTIVE = 0xA,
|
TypeUneffective = 0xA,
|
||||||
CALC_RESULT_TYPE_NEGLECT = 0xB,
|
TypeNeglect = 0xB,
|
||||||
CALC_RESULT_TYPE_DAMAGE_MP = 0xC,
|
TypeDamageMp = 0xC,
|
||||||
CALC_RESULT_TYPE_RECOVER_MP = 0xD,
|
TypeRecoverMp = 0xD,
|
||||||
CALC_RESULT_TYPE_DAMAGE_TP = 0xE,
|
TypeDamageTp = 0xE,
|
||||||
CALC_RESULT_TYPE_RECOVER_TP = 0xF,
|
TypeRecoverTp = 0xF,
|
||||||
CALC_RESULT_TYPE_RECOVER_GP = 0x10,
|
TypeRecoverGp = 0x10,
|
||||||
CALC_RESULT_TYPE_SET_STATUS = 0x11,
|
TypeSetStatus = 0x11,
|
||||||
CALC_RESULT_TYPE_SET_STATUS_ME = 0x12,
|
TypeSetStatusMe = 0x12,
|
||||||
CALC_RESULT_TYPE_RESET_STATUS = 0x13,
|
TypeResetStatus = 0x13,
|
||||||
CALC_RESULT_TYPE_RESET_STATUS_ME = 0x14,
|
TypeResetStatusMe = 0x14,
|
||||||
CALC_RESULT_TYPE_RESET_BAD_STATUS = 0x15,
|
TypeResetBadStatus = 0x15,
|
||||||
CALC_RESULT_TYPE_UNEFFECTIVE_STATUS = 0x16,
|
TypeUneffectiveStatus = 0x16,
|
||||||
CALC_RESULT_TYPE_HALF_GOOD_STATUS = 0x17,
|
TypeHalfGoodStatus = 0x17,
|
||||||
CALC_RESULT_TYPE_HATE_DIRECT = 0x18,
|
TypeHateDirect = 0x18,
|
||||||
CALC_RESULT_TYPE_HATE_INDIRECTION = 0x19,
|
TypeHateIndirection = 0x19,
|
||||||
CALC_RESULT_TYPE_HATE_TOP = 0x1A,
|
TypeHateTop = 0x1A,
|
||||||
CALC_RESULT_TYPE_HATE_ADD = 0x1B,
|
TypeHateAdd = 0x1B,
|
||||||
CALC_RESULT_TYPE_HATE_MULT = 0x1C,
|
TypeHateMult = 0x1C,
|
||||||
CALC_RESULT_TYPE_COMBO = 0x1D,
|
TypeCombo = 0x1D,
|
||||||
CALC_RESULT_TYPE_COMBO_HIT = 0x1E,
|
TypeComboHit = 0x1E,
|
||||||
CALC_RESULT_TYPE_COUNTER = 0x1F,
|
TypeCounter = 0x1F,
|
||||||
CALC_RESULT_TYPE_DESTRUCT = 0x20,
|
TypeDestruct = 0x20,
|
||||||
CALC_RESULT_TYPE_PARALYSIS = 0x21,
|
TypeParalysis = 0x21,
|
||||||
CALC_RESULT_TYPE_KNOCK_BACK = 0x22,
|
TypeKnockBack = 0x22,
|
||||||
CALC_RESULT_TYPE_DRAW_UP_CHAIRS = 0x23,
|
TypeDrawUpChairs = 0x23,
|
||||||
CALC_RESULT_TYPE_SUCKED = 0x24,
|
TypeSucked = 0x24,
|
||||||
CALC_RESULT_TYPE_CT_DRAW_UP_CHAIRS = 0x25,
|
TypeCtDrawUpChairs = 0x25,
|
||||||
CALC_RESULT_TYPE_LIVE_CALLBACK = 0x26,
|
TypeLiveCallback = 0x26,
|
||||||
CALC_RESULT_TYPE_MOUNT = 0x27,
|
TypeMount = 0x27,
|
||||||
CALC_RESULT_ARCHER_DOT = 0x28,
|
TypeArcherDot = 0x28,
|
||||||
CALC_RESULT_MASTER_DOT = 0x29,
|
TypeMasterDot = 0x29,
|
||||||
CALC_RESULT_BLESSINGS_OF_GODDESS = 0x2A,
|
TypeBlessingOfGoddess = 0x2A,
|
||||||
CALC_RESULT_BAD_BREATH = 0x2B,
|
TypeBadBreath = 0x2B,
|
||||||
CALC_RESULT_REVIVAL = 0x2C,
|
TypeRevival = 0x2C,
|
||||||
CALC_RESULT_PET = 0x2D,
|
TypePet = 0x2D,
|
||||||
CALC_RESULT_TYPE_BLOW = 0x2E,
|
TypeBlow = 0x2E,
|
||||||
CALC_RESULT_TYPE_STATUS_RESIST = 0x2F,
|
TypeStatusResist = 0x2F,
|
||||||
CALC_RESULT_TYPE_CLEAR_PHYSICAL = 0x30,
|
TypeClearPhysical = 0x30,
|
||||||
CALC_RESULT_BNPC_STATE = 0x31,
|
TypeBNpcState = 0x31,
|
||||||
CALC_RESULT_TYPE_VFX = 0x32,
|
TypeVfx = 0x32,
|
||||||
CALC_RESULT_TYPE_HARD_CODE = 0x33,
|
TypeHardCode = 0x33,
|
||||||
CALC_RESULT_CALC_ID = 0x34,
|
TypeCalcId = 0x34,
|
||||||
CALC_RESULT_TYPE_CLEAR_PVP_POINT = 0x35,
|
TypeClearPvpPoint = 0x35,
|
||||||
CALC_RESULT_TYPE_CHECK_BARRIER = 0x36,
|
TypeCheckBarrier = 0x36,
|
||||||
CALC_RESULT_TYPE_REFLEC = 0x37,
|
TypeReflect = 0x37,
|
||||||
};
|
|
||||||
|
|
||||||
enum class ActionHitSeverityType : uint8_t
|
|
||||||
{
|
|
||||||
NormalDamage = 0,
|
|
||||||
CritHeal = 0,
|
|
||||||
CritDamage = 1,
|
|
||||||
NormalHeal = 1,
|
|
||||||
DirectHitDamage = 2,
|
|
||||||
CritDirectHitDamage = 3
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ActionResultFlag : uint8_t
|
enum class ActionResultFlag : uint8_t
|
||||||
|
@ -1418,9 +1408,10 @@ namespace Sapphire::Common
|
||||||
{
|
{
|
||||||
None1 = 0,
|
None1 = 0,
|
||||||
HideUILockChar = 1, // as the name suggests, hides the ui and logs the char...
|
HideUILockChar = 1, // as the name suggests, hides the ui and logs the char...
|
||||||
InCombat = 2, // in Combat, locks gearchange/return/teleport
|
InCombat = 18, // in Combat, locks gearchange/return/teleport
|
||||||
Casting = 3,
|
Casting = 19,
|
||||||
InNpcEvent = 6, // when talking to an npc, locks ui giving "occupied" message
|
EventAction = 22,
|
||||||
|
InNpcEvent = 24, // when talking to an npc, locks ui giving "occupied" message
|
||||||
|
|
||||||
// InNpcEvent1 = 10, // Sent together with InNpcEvent, when waiting for input? just a guess...
|
// InNpcEvent1 = 10, // Sent together with InNpcEvent, when waiting for input? just a guess...
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,27 @@ namespace Sapphire::Data
|
||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > getRows()
|
||||||
|
{
|
||||||
|
xiv::exd::Exd sheet;
|
||||||
|
auto needle = m_sheets.find( typeid( T ) );
|
||||||
|
if( needle == m_sheets.end() )
|
||||||
|
{
|
||||||
|
auto sheetName = getSheetName< T >();
|
||||||
|
|
||||||
|
// load sheet
|
||||||
|
auto& cat = m_exd_data->get_category( sheetName );
|
||||||
|
m_sheets[ typeid( T ) ] = sheet = static_cast< xiv::exd::Exd >( cat.get_data( xiv::exd::Language::en ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sheet = needle->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sheet.get_sheet_rows< T >();
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr< xiv::dat::GameData > getGameData()
|
std::shared_ptr< xiv::dat::GameData > getGameData()
|
||||||
{
|
{
|
||||||
return m_data;
|
return m_data;
|
||||||
|
|
|
@ -31,8 +31,7 @@ public:
|
||||||
|
|
||||||
auto dmg = action.calcDamage( Potency );
|
auto dmg = action.calcDamage( Potency );
|
||||||
action.getActionResultBuilder()->damage( pSource, pTarget, dmg.first, dmg.second );
|
action.getActionResultBuilder()->damage( pSource, pTarget, dmg.first, dmg.second );
|
||||||
action.getActionResultBuilder()->heal( pTarget, pSource, dmg.first, Common::ActionHitSeverityType::NormalHeal,
|
action.getActionResultBuilder()->heal( pTarget, pSource, dmg.first, Common::CalcResultType::TypeRecoverHp, Common::ActionResultFlag::EffectOnSource );
|
||||||
Common::ActionResultFlag::EffectOnSource );
|
|
||||||
|
|
||||||
action.getActionResultBuilder()->applyStatusEffectSelf( InnerBeast, 15000, 0, { StatusModifier{ Common::ParamModifier::DamageTakenPercent, -20 } } );
|
action.getActionResultBuilder()->applyStatusEffectSelf( InnerBeast, 15000, 0, { StatusModifier{ Common::ParamModifier::DamageTakenPercent, -20 } } );
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#include <ScriptObject.h>
|
#include <ScriptObject.h>
|
||||||
#include <Territory/QuestBattle.h>
|
#include <Territory/QuestBattle.h>
|
||||||
|
#include <Actor/Player.h>
|
||||||
|
#include <Actor/GameObject.h>
|
||||||
|
#include <Actor/BNpc.h>
|
||||||
|
|
||||||
using namespace Sapphire;
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
@ -100,15 +103,126 @@ public:
|
||||||
instance.addEObj( "Millioncornseedling", 2001255, 0, 3927161, 4, { -320.576813f, 25.833500f, -527.550171f }, 0.961304f, -0.384837f, 0);
|
instance.addEObj( "Millioncornseedling", 2001255, 0, 3927161, 4, { -320.576813f, 25.833500f, -527.550171f }, 0.961304f, -0.384837f, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
enum vars
|
||||||
|
{
|
||||||
|
SET_1_SPAWNED,
|
||||||
|
SET_2_SPAWNED,
|
||||||
|
SUCCESS_CALLED,
|
||||||
|
};
|
||||||
|
|
||||||
|
void onPlayerSetup( Sapphire::QuestBattle& instance, Entity::Player& player ) override
|
||||||
|
{
|
||||||
|
player.setRot( -71.03f );
|
||||||
|
player.setPos( { 198.303f, 14.244f, 538.248f } );
|
||||||
|
}
|
||||||
|
|
||||||
void onUpdate( QuestBattle& instance, uint64_t tickCount ) override
|
void onUpdate( QuestBattle& instance, uint64_t tickCount ) override
|
||||||
{
|
{
|
||||||
|
auto pair1Spawnd = instance.getDirectorVar( SET_1_SPAWNED );
|
||||||
|
auto pair2Spawnd = instance.getDirectorVar( SET_2_SPAWNED );
|
||||||
|
auto successCalled = instance.getDirectorVar( SUCCESS_CALLED );
|
||||||
|
|
||||||
|
auto boss = instance.getActiveBNpcByLayoutId( INIT_POP_BOSS );
|
||||||
|
auto thancred = instance.getActiveBNpcByLayoutId( INIT_P_POP_01 );
|
||||||
|
auto pPlayer = instance.getPlayerPtr();
|
||||||
|
|
||||||
|
uint32_t bossHpPercent = 0;
|
||||||
|
if( boss )
|
||||||
|
bossHpPercent = boss->getHpPercent();
|
||||||
|
|
||||||
|
if( pPlayer && !pPlayer->isAlive() )
|
||||||
|
{
|
||||||
|
instance.fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!thancred)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( pair1Spawnd == 0 && bossHpPercent <= 70 )
|
||||||
|
{
|
||||||
|
instance.setDirectorVar( SET_1_SPAWNED, 1 );
|
||||||
|
auto a2 = instance.createBNpcFromLayoutId( INIT_POP_01_01, 1440 /*TODO: Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
auto a3 = instance.createBNpcFromLayoutId( INIT_POP_01_02, 1440 /*TODO: Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
a2->setFlag( Entity::NoDeaggro );
|
||||||
|
a3->setFlag( Entity::NoDeaggro );
|
||||||
|
|
||||||
|
auto pPlayer = instance.getPlayerPtr();
|
||||||
|
a2->hateListAdd( pPlayer, 1 );
|
||||||
|
a3->hateListAdd( pPlayer, 1 );
|
||||||
|
|
||||||
|
thancred->hateListAdd( a2, 9999 );
|
||||||
|
thancred->hateListAdd( a3, 9999 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pair2Spawnd == 0 && bossHpPercent <= 40 )
|
||||||
|
{
|
||||||
|
instance.setDirectorVar( SET_2_SPAWNED, 1 );
|
||||||
|
auto a2 = instance.createBNpcFromLayoutId( INIT_POP_02_01, 1440 /*TODO: Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
auto a3 = instance.createBNpcFromLayoutId( INIT_POP_02_02, 1440 /*TODO: Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
auto a4 = instance.createBNpcFromLayoutId( INIT_POP_02_03, 1440 /*TODO: Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
auto a5 = instance.createBNpcFromLayoutId( INIT_POP_02_04, 1440 /*TODO: Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
a2->setFlag( Entity::NoDeaggro );
|
||||||
|
a3->setFlag( Entity::NoDeaggro );
|
||||||
|
a4->setFlag( Entity::NoDeaggro );
|
||||||
|
a5->setFlag( Entity::NoDeaggro );
|
||||||
|
|
||||||
|
auto pPlayer = instance.getPlayerPtr();
|
||||||
|
a2->hateListAdd( pPlayer, 1 );
|
||||||
|
a3->hateListAdd( pPlayer, 1 );
|
||||||
|
a4->hateListAdd( pPlayer, 1 );
|
||||||
|
a5->hateListAdd( pPlayer, 1 );
|
||||||
|
|
||||||
|
thancred->hateListAdd( a2, 9999 );
|
||||||
|
thancred->hateListAdd( a3, 9999 );
|
||||||
|
thancred->hateListAdd( a4, 9999 );
|
||||||
|
thancred->hateListAdd( a5, 9999 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( instance.getCountEnemyBNpc() == 0 && successCalled == 0 )
|
||||||
|
{
|
||||||
|
instance.setDirectorVar( SUCCESS_CALLED, 1 );
|
||||||
|
instance.success();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onEnterTerritory( QuestBattle& instance, Entity::Player& player, uint32_t eventId, uint16_t param1,
|
void onEnterTerritory( QuestBattle& instance, Entity::Player& player, uint32_t eventId, uint16_t param1,
|
||||||
uint16_t param2 ) override
|
uint16_t param2 ) override
|
||||||
{
|
{
|
||||||
|
eventMgr().playScene( player, instance.getDirectorId(), 1,
|
||||||
|
NO_DEFAULT_CAMERA | CONDITION_CUTSCENE | SILENT_ENTER_TERRI_ENV |
|
||||||
|
HIDE_HOTBAR | SILENT_ENTER_TERRI_BGM | SILENT_ENTER_TERRI_SE |
|
||||||
|
DISABLE_STEALTH | 0x00100000 | LOCK_HUD | LOCK_HOTBAR |
|
||||||
|
// todo: wtf is 0x00100000
|
||||||
|
DISABLE_CANCEL_EMOTE, [ & ]( Entity::Player& player, const Event::SceneResult& result ) {
|
||||||
|
player.setOnEnterEventDone( true );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDutyComplete( QuestBattle& instance, Entity::Player& player ) override
|
||||||
|
{
|
||||||
|
auto idx = player.getQuestIndex( instance.getQuestId() );
|
||||||
|
if( idx == -1 )
|
||||||
|
return;
|
||||||
|
auto& quest = player.getQuestByIndex( idx );
|
||||||
|
quest.setSeq( 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDutyCommence( QuestBattle& instance, Entity::Player& player ) override
|
||||||
|
{
|
||||||
|
// TODO: Change to correct HP values
|
||||||
|
auto boss = instance.createBNpcFromLayoutId( INIT_POP_BOSS, 10571 /*TODO: Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
auto thancred = instance.createBNpcFromLayoutId( INIT_P_POP_01, 27780 /*TODO: Find the right value*/, Common::BNpcType::Friendly );
|
||||||
|
|
||||||
|
boss->setFlag( Entity::NoDeaggro );
|
||||||
|
thancred->setFlag( Entity::NoDeaggro );
|
||||||
|
|
||||||
|
boss->hateListAdd( thancred, 10000 );
|
||||||
|
boss->hateListAdd( player.getAsPlayer(), 1 );
|
||||||
|
|
||||||
|
thancred->hateListAdd( boss, 10000 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
318
src/scripts/quest/ManWil005.cpp
Normal file
318
src/scripts/quest/ManWil005.cpp
Normal file
|
@ -0,0 +1,318 @@
|
||||||
|
// This is an automatically generated C++ script template
|
||||||
|
// Content needs to be added by hand to make it function
|
||||||
|
// In order for this script to be loaded, move it to the correct folder in <root>/scripts/
|
||||||
|
|
||||||
|
#include <Actor/Player.h>
|
||||||
|
#include "Manager/EventMgr.h"
|
||||||
|
#include <ScriptObject.h>
|
||||||
|
#include <Service.h>
|
||||||
|
|
||||||
|
// Quest Script: ManWil005_00550
|
||||||
|
// Quest Name: Underneath the Sultantree
|
||||||
|
// Quest ID: 66086
|
||||||
|
// Start NPC: 1003995 (Papashan)
|
||||||
|
// End NPC: 1003995 (Papashan)
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
class ManWil005 : public Sapphire::ScriptAPI::QuestScript
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Basic quest information
|
||||||
|
// Quest vars / flags used
|
||||||
|
// BitFlag8
|
||||||
|
// UI8AL
|
||||||
|
|
||||||
|
/// Countable Num: 1 Seq: 1 Event: 1 Listener: 1003996
|
||||||
|
/// Countable Num: 1 Seq: 2 Event: 1 Listener: 2001853
|
||||||
|
/// Countable Num: 0 Seq: 255 Event: 15 Listener: 5020000
|
||||||
|
// Steps in this quest ( 0 is before accepting,
|
||||||
|
// 1 is first, 255 means ready for turning it in
|
||||||
|
enum Sequence : uint8_t
|
||||||
|
{
|
||||||
|
Seq0 = 0,
|
||||||
|
Seq1 = 1,
|
||||||
|
Seq2 = 2,
|
||||||
|
SeqFinish = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Entities found in the script data of the quest
|
||||||
|
static constexpr auto Actor0 = 1003995; // Papashan ( Pos: 75.338402 2.138110 316.362000 Teri: 141 )
|
||||||
|
static constexpr auto Actor1 = 1003996; // Hooded Lalafell ( Pos: 202.662994 14.104900 536.909973 Teri: 141 )
|
||||||
|
static constexpr auto Actor2 = 1003997; // ×次女a ( Pos: 76.674599 2.137120 317.433014 Teri: 141 )
|
||||||
|
static constexpr auto Actor3 = 1003998; // ×近衛a ( Pos: 77.176598 2.137340 315.631989 Teri: 141 )
|
||||||
|
static constexpr auto Actor4 = 1003999; // ×近衛b ( Pos: 77.310501 2.136910 316.973999 Teri: 141 )
|
||||||
|
static constexpr auto Actor5 = 1004000; // ×近衛c ( Pos: 78.402603 2.136520 316.269012 Teri: 141 )
|
||||||
|
static constexpr auto Actor6 = 1004001; // Lilira ( Pos: 76.643402 2.136930 318.191010 Teri: 141 )
|
||||||
|
static constexpr auto Actor20 = 1006171; // Lilira
|
||||||
|
static constexpr auto Actor30 = 1006167; // 侍女a
|
||||||
|
static constexpr auto Actor40 = 1006168; // 近衛a
|
||||||
|
static constexpr auto Actor50 = 1006169; // 近衛b
|
||||||
|
static constexpr auto Actor60 = 1006170; // 近衛c
|
||||||
|
static constexpr auto CutScene02 = 141;
|
||||||
|
static constexpr auto CutScene03 = 56;
|
||||||
|
static constexpr auto CutScene04 = 142;
|
||||||
|
static constexpr auto Eobject0 = 2001853; // ( Pos: 202.638000 14.137900 536.905029 Teri: 141 )
|
||||||
|
static constexpr auto EventActionSearch = 1; // Interaction
|
||||||
|
static constexpr auto Questbattle0 = 37;
|
||||||
|
static constexpr auto Seq0Actor0Lq = 50; // Goblin Thug
|
||||||
|
static constexpr auto Territorytype0 = 270;
|
||||||
|
static constexpr auto Territorytype1 = 141;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ManWil005() : Sapphire::ScriptAPI::QuestScript( 66086 ){};
|
||||||
|
~ManWil005() = default;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Event Handlers
|
||||||
|
void onTalk( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
switch( actorId )
|
||||||
|
{
|
||||||
|
case Actor0:
|
||||||
|
{
|
||||||
|
if (quest.getSeq() == Seq0)
|
||||||
|
{
|
||||||
|
Scene00000( quest, player );
|
||||||
|
}
|
||||||
|
else if (quest.getSeq() == SeqFinish)
|
||||||
|
{
|
||||||
|
Scene00006( quest, player );
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor1:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq1 )
|
||||||
|
Scene00002( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor2:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor3:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor4:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor5:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor6:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor20:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor30:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor40:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor50:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor60:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onEnterTerritory( World::Quest& quest, Entity::Player& player, uint16_t param1, uint16_t param2 ) override
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq2 )
|
||||||
|
{
|
||||||
|
Scene00005( quest, player );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Available Scenes in this quest, not necessarly all are used
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00000( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 0, HIDE_HOTBAR, bindSceneReturn( &ManWil005::Scene00000Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00000Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 ) // accept quest
|
||||||
|
{
|
||||||
|
Scene00001( quest, player );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00001( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 1, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, bindSceneReturn( &ManWil005::Scene00001Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
quest.setSeq( Seq1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00002( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 2, NONE, bindSceneReturn( &ManWil005::Scene00002Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
auto& pTeriMgr = Common::Service< Sapphire::World::Manager::TerritoryMgr >::ref();
|
||||||
|
|
||||||
|
eventMgr().eventFinish( player, result.eventId, 0 );
|
||||||
|
pTeriMgr.createAndJoinQuestBattle( player, Questbattle0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00003( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 3, NONE, bindSceneReturn( &ManWil005::Scene00003Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00004( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 4, NONE, bindSceneReturn( &ManWil005::Scene00004Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00004Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00005( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 5, NO_DEFAULT_CAMERA | CONDITION_CUTSCENE | SILENT_ENTER_TERRI_ENV | HIDE_HOTBAR | SILENT_ENTER_TERRI_BGM | SILENT_ENTER_TERRI_SE | DISABLE_STEALTH | 0x00100000 | LOCK_HUD | LOCK_HOTBAR |
|
||||||
|
// todo: wtf is 0x00100000
|
||||||
|
DISABLE_CANCEL_EMOTE,
|
||||||
|
bindSceneReturn( &ManWil005::Scene00005Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00005Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
quest.setSeq( SeqFinish );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00006( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 6, FADE_OUT | HIDE_HOTBAR | CONDITION_CUTSCENE | HIDE_UI, bindSceneReturn( &ManWil005::Scene00006Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00006Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
player.finishQuest( getId(), result.getResult( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00007( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 7, NONE, bindSceneReturn( &ManWil005::Scene00007Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00007Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00008( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 8, NONE, bindSceneReturn( &ManWil005::Scene00008Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00008Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00009( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 9, NONE, bindSceneReturn( &ManWil005::Scene00009Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00009Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00010( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 10, NONE, bindSceneReturn( &ManWil005::Scene00010Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00010Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00011( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 11, NONE, bindSceneReturn( &ManWil005::Scene00011Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00011Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_SCRIPT( ManWil005 );
|
|
@ -45,6 +45,7 @@ private:
|
||||||
static constexpr auto Actor4 = 1013231;//Hatchling
|
static constexpr auto Actor4 = 1013231;//Hatchling
|
||||||
static constexpr auto BindActor1 = 5896086;
|
static constexpr auto BindActor1 = 5896086;
|
||||||
static constexpr auto Item0 = 2001726;
|
static constexpr auto Item0 = 2001726;
|
||||||
|
static constexpr auto Item0Icon = 26177;
|
||||||
static constexpr auto LocBgm1 = 313;
|
static constexpr auto LocBgm1 = 313;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -137,7 +138,7 @@ private:
|
||||||
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
quest.setUI8BH( 1 );
|
quest.setUI8BH( 1 );
|
||||||
eventMgr().sendEventNotice( player, getId(), 0, 0 );//TODO: Item Icon, probably
|
eventMgr().sendNotice( player, getId(), 0, { Item0Icon } );
|
||||||
quest.setSeq( Seq2 );
|
quest.setSeq( Seq2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ private:
|
||||||
static constexpr auto Eobject2 = 2005950;
|
static constexpr auto Eobject2 = 2005950;
|
||||||
static constexpr auto EventActionGatherMiddle = 7;
|
static constexpr auto EventActionGatherMiddle = 7;
|
||||||
static constexpr auto Item0 = 2001728;
|
static constexpr auto Item0 = 2001728;
|
||||||
|
static constexpr auto Item0Icon = 21223;
|
||||||
static constexpr auto LocActor1 = 1013860;
|
static constexpr auto LocActor1 = 1013860;
|
||||||
static constexpr auto LocActor2 = 1013870;
|
static constexpr auto LocActor2 = 1013870;
|
||||||
static constexpr auto LocActor3 = 1013871;
|
static constexpr auto LocActor3 = 1013871;
|
||||||
|
@ -207,7 +208,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void checkQuestCompletion( World::Quest& quest, Entity::Player& player )
|
void checkQuestCompletion( World::Quest& quest, Entity::Player& player )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 1, 2, quest.getUI8AL(), 3 );//TODO: Item Icon, probably
|
eventMgr().sendNotice( player, getId(), 1, { quest.getUI8AL(), 3, Item0Icon } );
|
||||||
|
|
||||||
if( quest.getUI8AL() >= 3 )
|
if( quest.getUI8AL() >= 3 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,6 +56,7 @@ private:
|
||||||
static constexpr auto Actor7 = 1013961;//Goblin Trader (Seq5)
|
static constexpr auto Actor7 = 1013961;//Goblin Trader (Seq5)
|
||||||
static constexpr auto BindActor1 = 5896328;
|
static constexpr auto BindActor1 = 5896328;
|
||||||
static constexpr auto Item0 = 2001729;
|
static constexpr auto Item0 = 2001729;
|
||||||
|
static constexpr auto Item0Icon = 25919;
|
||||||
static constexpr auto LocActor1 = 1013954;
|
static constexpr auto LocActor1 = 1013954;
|
||||||
static constexpr auto LocActor2 = 1013955;
|
static constexpr auto LocActor2 = 1013955;
|
||||||
static constexpr auto LocBgm1 = 313;
|
static constexpr auto LocBgm1 = 313;
|
||||||
|
@ -390,7 +391,7 @@ private:
|
||||||
|
|
||||||
void Scene00019Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00019Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 5, 0 );//TODO: Item Icon?
|
eventMgr().sendNotice( player, getId(), 5, { Item0Icon } );
|
||||||
quest.setSeq( SeqFinish );
|
quest.setSeq( SeqFinish );
|
||||||
quest.setUI8BH( 0 );
|
quest.setUI8BH( 0 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,8 @@ private:
|
||||||
static constexpr auto Item4 = 2001029;
|
static constexpr auto Item4 = 2001029;
|
||||||
static constexpr auto Item5 = 2001038;
|
static constexpr auto Item5 = 2001038;
|
||||||
static constexpr auto Item6 = 2001047;
|
static constexpr auto Item6 = 2001047;
|
||||||
|
static constexpr auto Item0Icon = 21003;
|
||||||
|
static constexpr auto Item3Icon = 26002;
|
||||||
static constexpr auto LocAction0 = 858;
|
static constexpr auto LocAction0 = 858;
|
||||||
static constexpr auto LocAction1 = 995;
|
static constexpr auto LocAction1 = 995;
|
||||||
static constexpr auto LocAction2 = 936;
|
static constexpr auto LocAction2 = 936;
|
||||||
|
@ -109,6 +111,7 @@ private:
|
||||||
static constexpr auto Ritem0 = 2049;//Madman's Whispering Rod
|
static constexpr auto Ritem0 = 2049;//Madman's Whispering Rod
|
||||||
static constexpr auto Ritem1 = 2046;//Unfinished Thyrus
|
static constexpr auto Ritem1 = 2046;//Unfinished Thyrus
|
||||||
static constexpr auto Ritem2 = 6267;//Radz-at-Han Quenching Oil
|
static constexpr auto Ritem2 = 6267;//Radz-at-Han Quenching Oil
|
||||||
|
static constexpr auto Ritem1Icon = 32627;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JobWhm001() : Sapphire::ScriptAPI::QuestScript( 66660 ){};
|
JobWhm001() : Sapphire::ScriptAPI::QuestScript( 66660 ){};
|
||||||
|
@ -327,7 +330,7 @@ private:
|
||||||
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
quest.setUI8BH( 1 );
|
quest.setUI8BH( 1 );
|
||||||
eventMgr().sendEventNotice( player, getId(), 0, 0 );//TODO:Item Icon
|
eventMgr().sendNotice( player, getId(), 0, { Item0Icon } );
|
||||||
quest.setSeq( Seq2 );
|
quest.setSeq( Seq2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,7 +472,7 @@ private:
|
||||||
|
|
||||||
void Scene00013Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00013Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 7, 0 );//TODO: Item Icon
|
eventMgr().sendNotice( player, getId(), 7, { Item3Icon } );
|
||||||
quest.setSeq( Seq9 );
|
quest.setSeq( Seq9 );
|
||||||
quest.setUI8BH( 1 );
|
quest.setUI8BH( 1 );
|
||||||
}
|
}
|
||||||
|
@ -497,7 +500,7 @@ private:
|
||||||
void Scene00015Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00015Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
quest.setUI8BH( 0 );
|
quest.setUI8BH( 0 );
|
||||||
eventMgr().sendEventNotice( player, getId(), 8, 0 );//TODO: Item Icon?
|
eventMgr().sendNotice( player, getId(), 8, { Ritem1Icon } );
|
||||||
player.addItem( Ritem1 );
|
player.addItem( Ritem1 );
|
||||||
quest.setSeq( Seq10 );
|
quest.setSeq( Seq10 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,10 @@ private:
|
||||||
static constexpr auto Ritem1 = 3894;
|
static constexpr auto Ritem1 = 3894;
|
||||||
static constexpr auto Ritem2 = 3463;
|
static constexpr auto Ritem2 = 3463;
|
||||||
static constexpr auto Ritem3 = 2902;
|
static constexpr auto Ritem3 = 2902;
|
||||||
|
static constexpr auto Ritem0Icon = 48242;
|
||||||
|
static constexpr auto Ritem1Icon = 48219;
|
||||||
|
static constexpr auto Ritem2Icon = 45189;
|
||||||
|
static constexpr auto Ritem3Icon = 40616;
|
||||||
static constexpr auto VfxReaction = 177;
|
static constexpr auto VfxReaction = 177;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -214,7 +218,7 @@ private:
|
||||||
|
|
||||||
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 0, 0 );//TODO:Item Icon, Cleric's Gloves
|
eventMgr().sendNotice( player, getId(), 0, { Ritem0Icon } );
|
||||||
playerMgr().sendLogMessage( player, Logmessage0 );
|
playerMgr().sendLogMessage( player, Logmessage0 );
|
||||||
quest.setUI8AL( 1 );
|
quest.setUI8AL( 1 );
|
||||||
quest.setUI8CH( 0 );
|
quest.setUI8CH( 0 );
|
||||||
|
@ -241,7 +245,7 @@ private:
|
||||||
|
|
||||||
void Scene00005Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00005Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 1, 0 );//TODO:Item Icon, Cleric's Culottes
|
eventMgr().sendNotice( player, getId(), 1, { Ritem2Icon } );
|
||||||
playerMgr().sendLogMessage( player, Logmessage0 );
|
playerMgr().sendLogMessage( player, Logmessage0 );
|
||||||
quest.setUI8BH( 1 );
|
quest.setUI8BH( 1 );
|
||||||
quest.setUI8CL( 0 );
|
quest.setUI8CL( 0 );
|
||||||
|
@ -268,7 +272,7 @@ private:
|
||||||
|
|
||||||
void Scene00007Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00007Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 2, 0 );//TODO:Item Icon, Cleric's Boots
|
eventMgr().sendNotice( player, getId(), 2, {Ritem1Icon} );
|
||||||
playerMgr().sendLogMessage( player, Logmessage0 );
|
playerMgr().sendLogMessage( player, Logmessage0 );
|
||||||
quest.setUI8BL( 1 );
|
quest.setUI8BL( 1 );
|
||||||
quest.setUI8DH( 0 );
|
quest.setUI8DH( 0 );
|
||||||
|
@ -436,7 +440,7 @@ private:
|
||||||
|
|
||||||
void Scene00021Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00021Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 6, 0 );//TODO:Item Icon, Cleric's Circlet
|
eventMgr().sendNotice( player, getId(), 6, { Ritem3Icon } );
|
||||||
playerMgr().sendLogMessage( player, Logmessage0 );
|
playerMgr().sendLogMessage( player, Logmessage0 );
|
||||||
quest.setSeq( SeqFinish );
|
quest.setSeq( SeqFinish );
|
||||||
quest.setUI8BH( 0 );
|
quest.setUI8BH( 0 );
|
||||||
|
|
|
@ -54,6 +54,7 @@ private:
|
||||||
static constexpr auto Eobject1 = 2000017;//Decaying Tree (South)
|
static constexpr auto Eobject1 = 2000017;//Decaying Tree (South)
|
||||||
static constexpr auto Eobject2 = 2000018;//Decaying Tree (East)
|
static constexpr auto Eobject2 = 2000018;//Decaying Tree (East)
|
||||||
static constexpr auto Item0 = 2000061;
|
static constexpr auto Item0 = 2000061;
|
||||||
|
static constexpr auto Item0Icon = 20661;
|
||||||
static constexpr auto Seq0Actor0 = 0;
|
static constexpr auto Seq0Actor0 = 0;
|
||||||
static constexpr auto Seq1Eobject0 = 1;
|
static constexpr auto Seq1Eobject0 = 1;
|
||||||
static constexpr auto Seq1Eobject0Useitemno = 99;
|
static constexpr auto Seq1Eobject0Useitemno = 99;
|
||||||
|
@ -184,7 +185,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void checkQuestCompletion( World::Quest& quest, Entity::Player& player )
|
void checkQuestCompletion( World::Quest& quest, Entity::Player& player )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 0, 2, quest.getUI8AH(), 3 );//TODO: Probably needs item icon
|
eventMgr().sendNotice( player, getId(), 0, { quest.getUI8AH(), 3, Item0Icon } );
|
||||||
|
|
||||||
if( quest.getUI8AH() >= 3 )
|
if( quest.getUI8AH() >= 3 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,6 +45,8 @@ private:
|
||||||
static constexpr auto Enemy0 = 54;//Hornet Swarm (INCORRECT: 57)
|
static constexpr auto Enemy0 = 54;//Hornet Swarm (INCORRECT: 57)
|
||||||
static constexpr auto Item0 = 2000099;
|
static constexpr auto Item0 = 2000099;
|
||||||
static constexpr auto Item1 = 2000094;
|
static constexpr auto Item1 = 2000094;
|
||||||
|
static constexpr auto Item0Icon = 22623;
|
||||||
|
static constexpr auto Item1Icon = 24403;
|
||||||
static constexpr auto Seq0Actor0 = 0;
|
static constexpr auto Seq0Actor0 = 0;
|
||||||
static constexpr auto Seq2Actor0 = 1;
|
static constexpr auto Seq2Actor0 = 1;
|
||||||
static constexpr auto Seq2Actor0Npctradeno = 99;
|
static constexpr auto Seq2Actor0Npctradeno = 99;
|
||||||
|
@ -88,7 +90,7 @@ public:
|
||||||
{
|
{
|
||||||
quest.setUI8BH( quest.getUI8BH() + 1 );
|
quest.setUI8BH( quest.getUI8BH() + 1 );
|
||||||
quest.setUI8AL( quest.getUI8AL() + 1 );
|
quest.setUI8AL( quest.getUI8AL() + 1 );
|
||||||
eventMgr().sendEventNotice( player, getId(), 0, 2, quest.getUI8AL(), 4 );//TODO: Probably needs item icon
|
eventMgr().sendNotice( player, getId(), 0, { quest.getUI8AL(), 4, Item0Icon } ); // item Icon 2 missing
|
||||||
|
|
||||||
if( quest.getUI8AL() >= 4 )
|
if( quest.getUI8AL() >= 4 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,7 @@ private:
|
||||||
static constexpr auto Eventrange0 = 3841476;
|
static constexpr auto Eventrange0 = 3841476;
|
||||||
static constexpr auto EventActionSearch = 1;
|
static constexpr auto EventActionSearch = 1;
|
||||||
static constexpr auto Item0 = 2000192;
|
static constexpr auto Item0 = 2000192;
|
||||||
|
static constexpr auto Item0Icon = 22627;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SubFst067() : Sapphire::ScriptAPI::QuestScript( 65919 ){};
|
SubFst067() : Sapphire::ScriptAPI::QuestScript( 65919 ){};
|
||||||
|
@ -182,7 +183,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void checkQuestCompletion( World::Quest& quest, Entity::Player& player )
|
void checkQuestCompletion( World::Quest& quest, Entity::Player& player )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 1, 2, quest.getUI8AL(), 3 );//TODO: Item Icon
|
eventMgr().sendNotice( player, getId(), 1, { quest.getUI8AL(), 3, Item0Icon } );
|
||||||
if( quest.getUI8AL() >= 3 )
|
if( quest.getUI8AL() >= 3 )
|
||||||
{
|
{
|
||||||
quest.setUI8AL( 0 );
|
quest.setUI8AL( 0 );
|
||||||
|
|
|
@ -39,6 +39,7 @@ private:
|
||||||
static constexpr auto Eobject0 = 2000685;//Well-worn Fishing Rod
|
static constexpr auto Eobject0 = 2000685;//Well-worn Fishing Rod
|
||||||
static constexpr auto EventActionSearch = 1;
|
static constexpr auto EventActionSearch = 1;
|
||||||
static constexpr auto Item0 = 2000185;
|
static constexpr auto Item0 = 2000185;
|
||||||
|
static constexpr auto Item0Icon = 38201;
|
||||||
static constexpr auto Seq0Actor0 = 0;
|
static constexpr auto Seq0Actor0 = 0;
|
||||||
static constexpr auto Seq1Eobject0 = 1;
|
static constexpr auto Seq1Eobject0 = 1;
|
||||||
static constexpr auto Seq1Eobject0Eventactionno = 99;
|
static constexpr auto Seq1Eobject0Eventactionno = 99;
|
||||||
|
@ -169,7 +170,7 @@ private:
|
||||||
|
|
||||||
void Scene00100Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00100Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 0, 0 );//TODO: Probably Item Icon
|
eventMgr().sendNotice( player, getId(), 0, { Item0Icon } );
|
||||||
quest.setUI8BH( 1 );
|
quest.setUI8BH( 1 );
|
||||||
quest.setSeq( SeqFinish );
|
quest.setSeq( SeqFinish );
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ private:
|
||||||
static constexpr auto EventActionSearchMiddle = 3;
|
static constexpr auto EventActionSearchMiddle = 3;
|
||||||
static constexpr auto Item0 = 2000616;
|
static constexpr auto Item0 = 2000616;
|
||||||
static constexpr auto Item1 = 2000617;
|
static constexpr auto Item1 = 2000617;
|
||||||
|
static constexpr auto Item1Icon = 20005;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GaiUsa803() : Sapphire::ScriptAPI::QuestScript( 66323 ){};
|
GaiUsa803() : Sapphire::ScriptAPI::QuestScript( 66323 ){};
|
||||||
|
@ -140,7 +141,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void checkQuestCompletion( World::Quest& quest, Entity::Player& player )
|
void checkQuestCompletion( World::Quest& quest, Entity::Player& player )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 1, 2, quest.getUI8AH(), 5 );//TODO:Show Item Icon
|
eventMgr().sendNotice( player, getId(), 1, { quest.getUI8AH(), 5, Item1Icon } );
|
||||||
if( quest.getUI8AH() >= 5 )
|
if( quest.getUI8AH() >= 5 )
|
||||||
{
|
{
|
||||||
quest.setUI8BH( quest.getUI8DH() );
|
quest.setUI8BH( quest.getUI8DH() );
|
||||||
|
|
|
@ -55,6 +55,7 @@ private:
|
||||||
static constexpr auto Item0 = 2000720;
|
static constexpr auto Item0 = 2000720;
|
||||||
static constexpr auto Item1 = 2000721;
|
static constexpr auto Item1 = 2000721;
|
||||||
static constexpr auto Item2 = 2000722;
|
static constexpr auto Item2 = 2000722;
|
||||||
|
static constexpr auto Item0Icon = 26002;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GaiUsb808() : Sapphire::ScriptAPI::QuestScript( 66453 ){};
|
GaiUsb808() : Sapphire::ScriptAPI::QuestScript( 66453 ){};
|
||||||
|
@ -162,7 +163,7 @@ private:
|
||||||
|
|
||||||
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 1, 0 );//TODO:Show Item Icon (Needs func update)
|
eventMgr().sendNotice( player, getId(), 1, { Item0Icon } );
|
||||||
quest.setUI8BH( 1 );
|
quest.setUI8BH( 1 );
|
||||||
quest.setSeq( Seq3 );
|
quest.setSeq( Seq3 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,8 @@ private:
|
||||||
static constexpr auto EventActionSearch = 1;
|
static constexpr auto EventActionSearch = 1;
|
||||||
static constexpr auto Item0 = 2000963;
|
static constexpr auto Item0 = 2000963;
|
||||||
static constexpr auto Item1 = 2000965;
|
static constexpr auto Item1 = 2000965;
|
||||||
|
static constexpr auto Item0Icon = 22614;
|
||||||
|
static constexpr auto Item1Icon = 21452;
|
||||||
static constexpr auto Poprange0 = 3884000;
|
static constexpr auto Poprange0 = 3884000;
|
||||||
static constexpr auto Territorytype0 = 204;
|
static constexpr auto Territorytype0 = 204;
|
||||||
|
|
||||||
|
@ -263,7 +265,7 @@ private:
|
||||||
|
|
||||||
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 0, 0 );
|
eventMgr().sendNotice( player, getId(), 0, { Item0Icon } );
|
||||||
quest.setUI8BH( 1 );
|
quest.setUI8BH( 1 );
|
||||||
quest.setSeq( Seq2 );
|
quest.setSeq( Seq2 );
|
||||||
}
|
}
|
||||||
|
@ -393,7 +395,7 @@ private:
|
||||||
{
|
{
|
||||||
quest.setSeq( Seq4 );
|
quest.setSeq( Seq4 );
|
||||||
quest.setUI8BH( 1 );
|
quest.setUI8BH( 1 );
|
||||||
eventMgr().sendEventNotice( player, getId(), 2, 0 /*1, Item1*/ );//TODO:Item Icon Event Notice
|
eventMgr().sendNotice( player, getId(), 2, { Item1Icon } );
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -55,6 +55,8 @@ private:
|
||||||
static constexpr auto EventActionSearch = 1;
|
static constexpr auto EventActionSearch = 1;
|
||||||
static constexpr auto Item0 = 2000669;
|
static constexpr auto Item0 = 2000669;
|
||||||
static constexpr auto Item1 = 2000929;
|
static constexpr auto Item1 = 2000929;
|
||||||
|
static constexpr auto Item0Icon = 27241;
|
||||||
|
static constexpr auto Item1Icon = 22301;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GaiUsb406() : Sapphire::ScriptAPI::QuestScript( 66398 ){};
|
GaiUsb406() : Sapphire::ScriptAPI::QuestScript( 66398 ){};
|
||||||
|
@ -143,7 +145,11 @@ private:
|
||||||
{
|
{
|
||||||
if( quest.getSeq() == Seq1 )
|
if( quest.getSeq() == Seq1 )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), type, 2, ( type == 0 ) ? quest.getUI8AL() : quest.getUI8BH(), 3 ); //TODO: Item Icons
|
if( type == 0 )
|
||||||
|
eventMgr().sendNotice( player, getId(), type, { quest.getUI8AL(), 3, Item1Icon } );
|
||||||
|
else
|
||||||
|
eventMgr().sendNotice( player, getId(), type, { quest.getUI8BH(), 3, Item0Icon } );
|
||||||
|
|
||||||
if( quest.getUI8BL() >= 3 && quest.getUI8CH() >= 3 )
|
if( quest.getUI8BL() >= 3 && quest.getUI8CH() >= 3 )
|
||||||
{
|
{
|
||||||
quest.setUI8BH( quest.getUI8BL() );
|
quest.setUI8BH( quest.getUI8BL() );
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <Service.h>
|
#include <Service.h>
|
||||||
|
|
||||||
// Quest Script: SubSea002_00112
|
// Quest Script: SubSea002_00112
|
||||||
// Quest Name: Suspiciously SoberF
|
// Quest Name: Suspiciously Sober
|
||||||
// Quest ID: 65648
|
// Quest ID: 65648
|
||||||
// Start NPC: 1003604 (Ahldskyf)
|
// Start NPC: 1003604 (Ahldskyf)
|
||||||
// End NPC: 1003275 (Frydwyb)
|
// End NPC: 1003275 (Frydwyb)
|
||||||
|
|
|
@ -145,6 +145,7 @@ private:
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 0, 0 );
|
eventMgr().sendEventNotice( player, getId(), 0, 0 );
|
||||||
quest.setUI8AL( 1 );
|
quest.setUI8AL( 1 );
|
||||||
|
quest.setBitFlag8( 1, true );
|
||||||
checkQuestCompletion( quest, player, 1 );
|
checkQuestCompletion( quest, player, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +160,7 @@ private:
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 1, 0 );
|
eventMgr().sendEventNotice( player, getId(), 1, 0 );
|
||||||
quest.setUI8BH( 1 );
|
quest.setUI8BH( 1 );
|
||||||
|
quest.setBitFlag8( 2, true );
|
||||||
checkQuestCompletion( quest, player, 1 );
|
checkQuestCompletion( quest, player, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +175,7 @@ private:
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 2, 0 );
|
eventMgr().sendEventNotice( player, getId(), 2, 0 );
|
||||||
quest.setUI8BL( 1 );
|
quest.setUI8BL( 1 );
|
||||||
|
quest.setBitFlag8( 3, true );
|
||||||
checkQuestCompletion( quest, player, 1 );
|
checkQuestCompletion( quest, player, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ class SubSea007 : public Sapphire::ScriptAPI::QuestScript
|
||||||
static constexpr auto Actor1 = 1000957; // R'sushmo ( Pos: -49.240898 43.991699 -146.380005 Teri: 128 )
|
static constexpr auto Actor1 = 1000957; // R'sushmo ( Pos: -49.240898 43.991699 -146.380005 Teri: 128 )
|
||||||
static constexpr auto Actor2 = 1000937; // Godebert ( Pos: -12.222500 44.998798 -251.850006 Teri: 128 )
|
static constexpr auto Actor2 = 1000937; // Godebert ( Pos: -12.222500 44.998798 -251.850006 Teri: 128 )
|
||||||
static constexpr auto Item0 = 2000455;
|
static constexpr auto Item0 = 2000455;
|
||||||
|
static constexpr auto Item0Icon = 25906;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SubSea007() : Sapphire::ScriptAPI::QuestScript( 65653 ){};
|
SubSea007() : Sapphire::ScriptAPI::QuestScript( 65653 ){};
|
||||||
|
@ -117,7 +118,7 @@ class SubSea007 : public Sapphire::ScriptAPI::QuestScript
|
||||||
|
|
||||||
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 0, 0 ); // TODO: Show item icon
|
eventMgr().sendNotice( player, getId(), 0, { Item0Icon } );
|
||||||
quest.setUI8BH( 1 );
|
quest.setUI8BH( 1 );
|
||||||
quest.setSeq( Seq2 );
|
quest.setSeq( Seq2 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ class SubSea008 : public Sapphire::ScriptAPI::QuestScript
|
||||||
static constexpr auto Actor2 = 1000938; // Ginnade ( Pos: -4.651690 45.018398 -241.815002 Teri: 128 )
|
static constexpr auto Actor2 = 1000938; // Ginnade ( Pos: -4.651690 45.018398 -241.815002 Teri: 128 )
|
||||||
static constexpr auto Actor3 = 1000947; // Lyngsath ( Pos: -54.642601 43.991699 -151.201996 Teri: 128 )
|
static constexpr auto Actor3 = 1000947; // Lyngsath ( Pos: -54.642601 43.991699 -151.201996 Teri: 128 )
|
||||||
static constexpr auto Item0 = 2000451;
|
static constexpr auto Item0 = 2000451;
|
||||||
|
static constexpr auto Item0Icon = 25919;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SubSea008() : Sapphire::ScriptAPI::QuestScript( 65654 ){};
|
SubSea008() : Sapphire::ScriptAPI::QuestScript( 65654 ){};
|
||||||
|
@ -58,6 +59,7 @@ class SubSea008 : public Sapphire::ScriptAPI::QuestScript
|
||||||
{
|
{
|
||||||
case Actor0:
|
case Actor0:
|
||||||
{
|
{
|
||||||
|
if( quest.getSeq() == Seq0 )
|
||||||
Scene00000( quest, player );
|
Scene00000( quest, player );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -71,11 +73,13 @@ class SubSea008 : public Sapphire::ScriptAPI::QuestScript
|
||||||
}
|
}
|
||||||
case Actor2:
|
case Actor2:
|
||||||
{
|
{
|
||||||
|
if( quest.getSeq() == Seq2 )
|
||||||
Scene00003( quest, player );
|
Scene00003( quest, player );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Actor3:
|
case Actor3:
|
||||||
{
|
{
|
||||||
|
if( quest.getSeq() == Seq2 )
|
||||||
Scene00005( quest, player );
|
Scene00005( quest, player );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -137,7 +141,7 @@ private:
|
||||||
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
quest.setUI8BL( 1 );
|
quest.setUI8BL( 1 );
|
||||||
eventMgr().sendEventNotice( player, getId(), 0, 0 ); //TODO: add item icon
|
eventMgr().sendNotice( player, getId(), 0, { Item0Icon } );
|
||||||
quest.setSeq( Seq2 );
|
quest.setSeq( Seq2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +171,7 @@ private:
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 1, 0 );
|
eventMgr().sendEventNotice( player, getId(), 1, 0 );
|
||||||
quest.setUI8AL( 1 );
|
quest.setUI8AL( 1 );
|
||||||
|
quest.setBitFlag8( 1, true );
|
||||||
checkQuestCompletion( quest, player, 1 );
|
checkQuestCompletion( quest, player, 1 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -197,6 +202,7 @@ private:
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 2, 0 );
|
eventMgr().sendEventNotice( player, getId(), 2, 0 );
|
||||||
quest.setUI8BH( 1 );
|
quest.setUI8BH( 1 );
|
||||||
|
quest.setBitFlag8( 2, true );
|
||||||
checkQuestCompletion( quest, player, 1 );
|
checkQuestCompletion( quest, player, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ class SubSea016 : public Sapphire::ScriptAPI::QuestScript
|
||||||
}
|
}
|
||||||
case Actor1:
|
case Actor1:
|
||||||
{
|
{
|
||||||
|
if( quest.getSeq() == Seq1 )
|
||||||
Scene00002( quest, player );
|
Scene00002( quest, player );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -131,6 +132,7 @@ class SubSea016 : public Sapphire::ScriptAPI::QuestScript
|
||||||
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
eventMgr().sendEventNotice( player, getId(), 0, 0 );
|
eventMgr().sendEventNotice( player, getId(), 0, 0 );
|
||||||
|
quest.setBitFlag8( 1, true );
|
||||||
quest.setSeq( SeqFinish );
|
quest.setSeq( SeqFinish );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
324
src/scripts/quest/subquest/thanalan_central/SubWil025.cpp
Normal file
324
src/scripts/quest/subquest/thanalan_central/SubWil025.cpp
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
// This is an automatically generated C++ script template
|
||||||
|
// Content needs to be added by hand to make it function
|
||||||
|
// In order for this script to be loaded, move it to the correct folder in <root>/scripts/
|
||||||
|
|
||||||
|
#include "Manager/EventMgr.h"
|
||||||
|
#include <Actor/Player.h>
|
||||||
|
#include <ScriptObject.h>
|
||||||
|
#include <Service.h>
|
||||||
|
|
||||||
|
// Quest Script: SubWil025_00671
|
||||||
|
// Quest Name: Nothing to See Here
|
||||||
|
// Quest ID: 66207
|
||||||
|
// Start NPC: 1003995 (Papashan)
|
||||||
|
// End NPC: 1003995 (Papashan)
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
class SubWil025 : public Sapphire::ScriptAPI::QuestScript
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Basic quest information
|
||||||
|
// Quest vars / flags used
|
||||||
|
// BitFlag8
|
||||||
|
// UI8AH
|
||||||
|
// UI8AL
|
||||||
|
// UI8BH
|
||||||
|
// UI8BL
|
||||||
|
// UI8CH
|
||||||
|
// UI8CL
|
||||||
|
|
||||||
|
/// Countable Num: 0 Seq: 1 Event: 1 Listener: 1004599
|
||||||
|
/// Countable Num: 0 Seq: 255 Event: 1 Listener: 1004600
|
||||||
|
// Steps in this quest ( 0 is before accepting,
|
||||||
|
// 1 is first, 255 means ready for turning it in
|
||||||
|
enum Sequence : uint8_t
|
||||||
|
{
|
||||||
|
Seq0 = 0,
|
||||||
|
Seq1 = 1,
|
||||||
|
SeqFinish = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Entities found in the script data of the quest
|
||||||
|
static constexpr auto Actor0 = 1003995;// Papashan ( Pos: 75.338402 2.138110 316.362000 Teri: 141 )
|
||||||
|
static constexpr auto Actor1 = 1004599;// Stern Sultansworn ( Pos: 89.876198 4.633540 425.415009 Teri: 141 )
|
||||||
|
static constexpr auto Actor2 = 1004600;// Serious Sultansworn ( Pos: 126.024002 14.465300 278.462006 Teri: 141 )
|
||||||
|
static constexpr auto Actor3 = 1004601;// Servile Sultansworn ( Pos: -62.415001 4.641350 261.281006 Teri: 141 )
|
||||||
|
static constexpr auto Item0 = 2000463;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SubWil025() : Sapphire::ScriptAPI::QuestScript( 66207 ){};
|
||||||
|
~SubWil025() = default;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Event Handlers
|
||||||
|
void onTalk( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
switch( actorId )
|
||||||
|
{
|
||||||
|
case Actor0:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq0 )
|
||||||
|
Scene00000( quest, player );
|
||||||
|
else if( quest.getSeq() == SeqFinish )
|
||||||
|
Scene00010( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Actor1:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq1 )
|
||||||
|
{
|
||||||
|
if( quest.getUI8AL() == 0 )
|
||||||
|
Scene00001( quest, player );
|
||||||
|
else
|
||||||
|
Scene00003( quest, player );
|
||||||
|
}
|
||||||
|
else if( quest.getSeq() == SeqFinish )
|
||||||
|
{
|
||||||
|
Scene00011( quest, player );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Actor2:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq1 )
|
||||||
|
{
|
||||||
|
if( quest.getUI8BH() == 0 )
|
||||||
|
Scene00004( quest, player );
|
||||||
|
else
|
||||||
|
Scene00006( quest, player );
|
||||||
|
}
|
||||||
|
else if( quest.getSeq() == SeqFinish )
|
||||||
|
{
|
||||||
|
Scene00012( quest, player );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Actor3:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq1 )
|
||||||
|
{
|
||||||
|
if( quest.getUI8BL() == 0 )
|
||||||
|
Scene00007( quest, player );
|
||||||
|
else
|
||||||
|
Scene00009( quest, player );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onEventItem( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void checkQuestCompletion( World::Quest& quest, Entity::Player& player, uint32_t varIdx )
|
||||||
|
{
|
||||||
|
if( varIdx == 1 )
|
||||||
|
{
|
||||||
|
quest.setUI8AH( quest.getUI8AH() + 1 );
|
||||||
|
quest.setUI8CH( quest.getUI8CH() - 1 );
|
||||||
|
auto actor1Talked = quest.getUI8AL();
|
||||||
|
auto actor2Talked = quest.getUI8BH();
|
||||||
|
auto actor3Talked = quest.getUI8BL();
|
||||||
|
if( actor1Talked && actor2Talked && actor3Talked )
|
||||||
|
{
|
||||||
|
quest.setSeq( SeqFinish );
|
||||||
|
}
|
||||||
|
eventMgr().sendEventNotice( player, getId(), 0, 2, quest.getUI8AH(), 3 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Available Scenes in this quest, not necessarly all are used
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00000( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 0, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00000Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00000Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 )// accept quest
|
||||||
|
{
|
||||||
|
quest.setSeq( Seq1 );
|
||||||
|
quest.setUI8CH( 3 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00001( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 1, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00001Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
Scene00002( quest, player );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00002( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 2, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00002Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
quest.setUI8AL( 1 );
|
||||||
|
quest.setBitFlag8( 1, true );
|
||||||
|
checkQuestCompletion( quest, player, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00003( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 3, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00003Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00004( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 4, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00004Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00004Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
Scene00005( quest, player );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00005( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 5, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00005Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00005Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
quest.setUI8BH( 1 );
|
||||||
|
quest.setBitFlag8( 2, true );
|
||||||
|
checkQuestCompletion( quest, player, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00006( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 6, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00006Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00006Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00007( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 7, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00007Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00007Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
Scene00008( quest, player );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00008( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 8, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00008Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00008Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
quest.setUI8BL( 1 );
|
||||||
|
quest.setBitFlag8( 3, true );
|
||||||
|
checkQuestCompletion( quest, player, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00009( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 9, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00009Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00009Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00010( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 10, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00010Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00010Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
player.finishQuest( getId(), result.getResult( 1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00011( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 11, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00011Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00011Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00012( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 12, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00012Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00012Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00013( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 13, HIDE_HOTBAR, bindSceneReturn( &SubWil025::Scene00013Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00013Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_SCRIPT( SubWil025 );
|
117
src/scripts/quest/subquest/thanalan_central/SubWil026.cpp
Normal file
117
src/scripts/quest/subquest/thanalan_central/SubWil026.cpp
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
// This is an automatically generated C++ script template
|
||||||
|
// Content needs to be added by hand to make it function
|
||||||
|
// In order for this script to be loaded, move it to the correct folder in <root>/scripts/
|
||||||
|
|
||||||
|
#include <Actor/Player.h>
|
||||||
|
#include "Manager/EventMgr.h"
|
||||||
|
#include <ScriptObject.h>
|
||||||
|
#include <Service.h>
|
||||||
|
|
||||||
|
// Quest Script: SubWil026_00623
|
||||||
|
// Quest Name: Takin' What They're Givin'
|
||||||
|
// Quest ID: 66159
|
||||||
|
// Start NPC: 1001353 (Momodi)
|
||||||
|
// End NPC: 1002065 (Dadanen)
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
class SubWil026 : public Sapphire::ScriptAPI::QuestScript
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Basic quest information
|
||||||
|
// Quest vars / flags used
|
||||||
|
// UI8AL
|
||||||
|
|
||||||
|
/// Countable Num: 1 Seq: 255 Event: 1 Listener: 1002065
|
||||||
|
// Steps in this quest ( 0 is before accepting,
|
||||||
|
// 1 is first, 255 means ready for turning it in
|
||||||
|
enum Sequence : uint8_t
|
||||||
|
{
|
||||||
|
Seq0 = 0,
|
||||||
|
SeqFinish = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Entities found in the script data of the quest
|
||||||
|
static constexpr auto Actor0 = 1001353; // Momodi ( Pos: 21.072599 7.450000 -78.782303 Teri: 130 )
|
||||||
|
static constexpr auto Actor1 = 1002065; // Dadanen ( Pos: 60.946701 45.145302 -204.985992 Teri: 140 )
|
||||||
|
|
||||||
|
public:
|
||||||
|
SubWil026() : Sapphire::ScriptAPI::QuestScript( 66159 ){};
|
||||||
|
~SubWil026() = default;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Event Handlers
|
||||||
|
void onTalk( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
switch( actorId )
|
||||||
|
{
|
||||||
|
case Actor0:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq0 )
|
||||||
|
Scene00000( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor1:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == SeqFinish )
|
||||||
|
Scene00001( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onEventItem( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Available Scenes in this quest, not necessarly all are used
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00000( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 0, HIDE_HOTBAR, bindSceneReturn( &SubWil026::Scene00000Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00000Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 ) // accept quest
|
||||||
|
{
|
||||||
|
quest.setUI8AL( 1 );
|
||||||
|
quest.setSeq( SeqFinish );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00001( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 1, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, bindSceneReturn( &SubWil026::Scene00001Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
Scene00002( quest, player );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00002( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 2, HIDE_HOTBAR, bindSceneReturn( &SubWil026::Scene00002Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
player.finishQuest( getId(), result.getResult( 1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_SCRIPT( SubWil026 );
|
194
src/scripts/quest/subquest/thanalan_central/SubWil060.cpp
Normal file
194
src/scripts/quest/subquest/thanalan_central/SubWil060.cpp
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
// This is an automatically generated C++ script template
|
||||||
|
// Content needs to be added by hand to make it function
|
||||||
|
// In order for this script to be loaded, move it to the correct folder in <root>/scripts/
|
||||||
|
|
||||||
|
#include <Actor/Player.h>
|
||||||
|
#include "Manager/EventMgr.h"
|
||||||
|
#include <ScriptObject.h>
|
||||||
|
#include <Service.h>
|
||||||
|
|
||||||
|
// Quest Script: SubWil060_00303
|
||||||
|
// Quest Name: Step Nine
|
||||||
|
// Quest ID: 65839
|
||||||
|
// Start NPC: 1001500 (Cicidoa)
|
||||||
|
// End NPC: 1001541 (Roger)
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
class SubWil060 : public Sapphire::ScriptAPI::QuestScript
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Basic quest information
|
||||||
|
// Quest vars / flags used
|
||||||
|
// UI8AL
|
||||||
|
// UI8BH
|
||||||
|
// UI8BL
|
||||||
|
|
||||||
|
/// Countable Num: 1 Seq: 1 Event: 1 Listener: 1001455
|
||||||
|
/// Countable Num: 1 Seq: 255 Event: 1 Listener: 1001541
|
||||||
|
// Steps in this quest ( 0 is before accepting,
|
||||||
|
// 1 is first, 255 means ready for turning it in
|
||||||
|
enum Sequence : uint8_t
|
||||||
|
{
|
||||||
|
Seq0 = 0,
|
||||||
|
Seq1 = 1,
|
||||||
|
SeqFinish = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Entities found in the script data of the quest
|
||||||
|
static constexpr auto Actor0 = 1001500; // Cicidoa ( Pos: 81.792099 1.050750 311.240997 Teri: 141 )
|
||||||
|
static constexpr auto Actor1 = 1001455; // Gagari ( Pos: 59.952599 0.999894 255.863998 Teri: 141 )
|
||||||
|
static constexpr auto Actor2 = 1001541; // Roger ( Pos: -99.395401 -11.380900 -41.723999 Teri: 141 )
|
||||||
|
static constexpr auto Item0 = 2000199;
|
||||||
|
static constexpr auto Item1 = 2000238;
|
||||||
|
static constexpr auto Item1Icon = 25210;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SubWil060() : Sapphire::ScriptAPI::QuestScript( 65839 ){};
|
||||||
|
~SubWil060() = default;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Event Handlers
|
||||||
|
void onTalk( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
switch( actorId )
|
||||||
|
{
|
||||||
|
case Actor0:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq0 )
|
||||||
|
Scene00000( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor1:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq1 )
|
||||||
|
Scene00001( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor2:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == SeqFinish )
|
||||||
|
Scene00004( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onEventItem( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Available Scenes in this quest, not necessarly all are used
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00000( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 0, HIDE_HOTBAR, bindSceneReturn( &SubWil060::Scene00000Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00000Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 ) // accept quest
|
||||||
|
{
|
||||||
|
quest.setUI8BH( 1 );
|
||||||
|
quest.setSeq( Seq1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00001( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 1, HIDE_HOTBAR, bindSceneReturn( &SubWil060::Scene00001Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
Scene00002( quest, player );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00002( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 2, HIDE_HOTBAR, bindSceneReturn( &SubWil060::Scene00002Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
quest.setUI8BH( 0 );
|
||||||
|
quest.setUI8BL( 1 );
|
||||||
|
eventMgr().sendNotice( player, getId(), 0, { Item1Icon } );
|
||||||
|
quest.setSeq( SeqFinish );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00003( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 3, NONE, bindSceneReturn( &SubWil060::Scene00003Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00004( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 4, HIDE_HOTBAR, bindSceneReturn( &SubWil060::Scene00004Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00004Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
Scene00005( quest, player );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00005( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 5, HIDE_HOTBAR, bindSceneReturn( &SubWil060::Scene00005Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00005Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
player.finishQuest( getId(), result.getResult( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00006( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 6, NONE, bindSceneReturn( &SubWil060::Scene00006Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00006Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_SCRIPT( SubWil060 );
|
169
src/scripts/quest/subquest/thanalan_central/SubWil062.cpp
Normal file
169
src/scripts/quest/subquest/thanalan_central/SubWil062.cpp
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
// This is an automatically generated C++ script template
|
||||||
|
// Content needs to be added by hand to make it function
|
||||||
|
// In order for this script to be loaded, move it to the correct folder in <root>/scripts/
|
||||||
|
|
||||||
|
#include "Manager/EventMgr.h"
|
||||||
|
#include <Actor/Player.h>
|
||||||
|
#include <Actor/BNpc.h>
|
||||||
|
#include <ScriptObject.h>
|
||||||
|
#include <Service.h>
|
||||||
|
|
||||||
|
// Quest Script: SubWil062_00305
|
||||||
|
// Quest Name: Until a Quieter Time
|
||||||
|
// Quest ID: 65841
|
||||||
|
// Start NPC: 1001541 (Roger)
|
||||||
|
// End NPC: 1001447 (Warin)
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
class SubWil062 : public Sapphire::ScriptAPI::QuestScript
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Basic quest information
|
||||||
|
// Quest vars / flags used
|
||||||
|
// UI8AL
|
||||||
|
// UI8BH
|
||||||
|
|
||||||
|
/// Countable Num: 8 Seq: 1 Event: 9 Listener: 432
|
||||||
|
/// Countable Num: 1 Seq: 255 Event: 1 Listener: 1001447
|
||||||
|
// Steps in this quest ( 0 is before accepting,
|
||||||
|
// 1 is first, 255 means ready for turning it in
|
||||||
|
enum Sequence : uint8_t
|
||||||
|
{
|
||||||
|
Seq0 = 0,
|
||||||
|
Seq1 = 1,
|
||||||
|
SeqFinish = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Entities found in the script data of the quest
|
||||||
|
static constexpr auto Actor0 = 1001541; // Roger ( Pos: -99.395401 -11.380900 -41.723999 Teri: 141 )
|
||||||
|
static constexpr auto Actor1 = 1001447; // Warin ( Pos: -32.639099 -1.033260 -148.485992 Teri: 141 )
|
||||||
|
static constexpr auto Enemy0 = 294; // Antling Worker
|
||||||
|
static constexpr auto Item0 = 2000168;
|
||||||
|
static constexpr auto Item0Icon = 22205;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SubWil062() : Sapphire::ScriptAPI::QuestScript( 65841 ){};
|
||||||
|
~SubWil062() = default;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Event Handlers
|
||||||
|
void onTalk( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
switch( actorId )
|
||||||
|
{
|
||||||
|
case Actor0:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq0 )
|
||||||
|
Scene00000( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor1:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == SeqFinish )
|
||||||
|
Scene00002( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onEventItem( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void onBNpcKill( World::Quest& quest, Entity::BNpc& bnpc, Entity::Player& player ) override
|
||||||
|
{
|
||||||
|
if( bnpc.getBNpcNameId() != Enemy0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned currentKC = quest.getUI8AL() + 1;
|
||||||
|
quest.setUI8BH( currentKC );
|
||||||
|
quest.setUI8AL( currentKC );
|
||||||
|
|
||||||
|
if( currentKC >= 5 )
|
||||||
|
quest.setSeq( SeqFinish );
|
||||||
|
|
||||||
|
eventMgr().sendNotice( player, getId(), 0, { currentKC, 5, Item0Icon } );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Available Scenes in this quest, not necessarly all are used
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00000( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 0, HIDE_HOTBAR, bindSceneReturn( &SubWil062::Scene00000Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00000Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 ) // accept quest
|
||||||
|
{
|
||||||
|
quest.setUI8AL( 0 );
|
||||||
|
quest.setSeq( Seq1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00001( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 1, NONE, bindSceneReturn( &SubWil062::Scene00001Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00002( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 2, HIDE_HOTBAR, bindSceneReturn( &SubWil062::Scene00002Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
quest.setUI8BH( 0 );
|
||||||
|
Scene00003( quest, player );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00003( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 3, HIDE_HOTBAR, bindSceneReturn( &SubWil062::Scene00003Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
player.finishQuest( getId(), result.getResult( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00004( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 4, NONE, bindSceneReturn( &SubWil062::Scene00004Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00004Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_SCRIPT( SubWil062 );
|
103
src/scripts/quest/subquest/thanalan_central/SubWil063.cpp
Normal file
103
src/scripts/quest/subquest/thanalan_central/SubWil063.cpp
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
// This is an automatically generated C++ script template
|
||||||
|
// Content needs to be added by hand to make it function
|
||||||
|
// In order for this script to be loaded, move it to the correct folder in <root>/scripts/
|
||||||
|
|
||||||
|
#include <Actor/Player.h>
|
||||||
|
#include "Manager/EventMgr.h"
|
||||||
|
#include <ScriptObject.h>
|
||||||
|
#include <Service.h>
|
||||||
|
|
||||||
|
// Quest Script: SubWil063_00306
|
||||||
|
// Quest Name: Prudence at This Junction
|
||||||
|
// Quest ID: 65842
|
||||||
|
// Start NPC: 1001447 (Warin)
|
||||||
|
// End NPC: 1001447 (Warin)
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
class SubWil063 : public Sapphire::ScriptAPI::QuestScript
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Basic quest information
|
||||||
|
// Quest vars / flags used
|
||||||
|
// UI8AL
|
||||||
|
|
||||||
|
/// Countable Num: 1 Seq: 255 Event: 1 Listener: 1001447
|
||||||
|
// Steps in this quest ( 0 is before accepting,
|
||||||
|
// 1 is first, 255 means ready for turning it in
|
||||||
|
enum Sequence : uint8_t
|
||||||
|
{
|
||||||
|
Seq0 = 0,
|
||||||
|
SeqFinish = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Entities found in the script data of the quest
|
||||||
|
static constexpr auto Actor0 = 1001447; // Warin ( Pos: -32.639099 -1.033260 -148.485992 Teri: 141 )
|
||||||
|
static constexpr auto Seq0Actor0 = 0; //
|
||||||
|
static constexpr auto Seq1Actor0 = 1; //
|
||||||
|
|
||||||
|
public:
|
||||||
|
SubWil063() : Sapphire::ScriptAPI::QuestScript( 65842 ){};
|
||||||
|
~SubWil063() = default;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Event Handlers
|
||||||
|
void onTalk( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
switch( actorId )
|
||||||
|
{
|
||||||
|
case Actor0:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq0 )
|
||||||
|
Scene00000( quest, player );
|
||||||
|
else if( quest.getSeq() == SeqFinish )
|
||||||
|
Scene00001( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onEventItem( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Available Scenes in this quest, not necessarly all are used
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00000( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 0, HIDE_HOTBAR, bindSceneReturn( &SubWil063::Scene00000Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00000Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 ) // accept quest
|
||||||
|
{
|
||||||
|
quest.setSeq( SeqFinish );
|
||||||
|
eventMgr().sendNotice( player, getId(), 0, {} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00001( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 1, HIDE_HOTBAR, bindSceneReturn( &SubWil063::Scene00001Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
player.finishQuest( getId(), result.getResult( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_SCRIPT( SubWil063 );
|
315
src/scripts/quest/subquest/thanalan_central/SubWil064.cpp
Normal file
315
src/scripts/quest/subquest/thanalan_central/SubWil064.cpp
Normal file
|
@ -0,0 +1,315 @@
|
||||||
|
// This is an automatically generated C++ script template
|
||||||
|
// Content needs to be added by hand to make it function
|
||||||
|
// In order for this script to be loaded, move it to the correct folder in <root>/scripts/
|
||||||
|
|
||||||
|
#include "Manager/EventMgr.h"
|
||||||
|
#include <Actor/Player.h>
|
||||||
|
#include <Actor/BNpc.h>
|
||||||
|
#include <ScriptObject.h>
|
||||||
|
#include <Service.h>
|
||||||
|
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "Manager/TerritoryMgr.h"
|
||||||
|
#include "Territory/Territory.h"
|
||||||
|
|
||||||
|
// Quest Script: SubWil064_00307
|
||||||
|
// Quest Name: Out of House and Home
|
||||||
|
// Quest ID: 65843
|
||||||
|
// Start NPC: 1001447 (Warin)
|
||||||
|
// End NPC: 1001447 (Warin)
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
class SubWil064 : public Sapphire::ScriptAPI::QuestScript
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Basic quest information
|
||||||
|
// Quest vars / flags used
|
||||||
|
// BitFlag8
|
||||||
|
// UI8AL
|
||||||
|
// UI8BH
|
||||||
|
|
||||||
|
/// Countable Num: 0 Seq: 1 Event: 1 Listener: 2000268
|
||||||
|
/// Countable Num: 1 Seq: 255 Event: 8 Listener: 2000268
|
||||||
|
// Steps in this quest ( 0 is before accepting,
|
||||||
|
// 1 is first, 255 means ready for turning it in
|
||||||
|
enum Sequence : uint8_t
|
||||||
|
{
|
||||||
|
Seq0 = 0,
|
||||||
|
Seq1 = 1,
|
||||||
|
SeqFinish = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Entities found in the script data of the quest
|
||||||
|
static constexpr auto Actor0 = 1001447; // Warin ( Pos: -32.639099 -1.033260 -148.485992 Teri: 141 )
|
||||||
|
static constexpr auto Enemy0 = 3785130; //
|
||||||
|
static constexpr auto Enemy1 = 3785131; //
|
||||||
|
static constexpr auto Enemy2 = 3785134; //
|
||||||
|
static constexpr auto Eobject0 = 2000268; // Narrow Fissure ( Pos: 25.690800 13.106300 47.828999 Teri: 141 )
|
||||||
|
static constexpr auto Item0 = 2000212;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SubWil064() : Sapphire::ScriptAPI::QuestScript( 65843 ){};
|
||||||
|
~SubWil064() = default;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Event Handlers
|
||||||
|
void onTalk( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
switch( actorId )
|
||||||
|
{
|
||||||
|
case Actor0:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq0 )
|
||||||
|
{
|
||||||
|
Scene00000( quest, player );
|
||||||
|
}
|
||||||
|
else if( quest.getSeq() == SeqFinish )
|
||||||
|
{
|
||||||
|
Scene00013( quest,player );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onEventItem( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
if (actorId == Eobject0)
|
||||||
|
{
|
||||||
|
Scene00002( quest, player );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onBNpcKill( World::Quest& quest, Entity::BNpc& bnpc, Entity::Player& player ) override
|
||||||
|
{
|
||||||
|
switch( bnpc.getLayoutId() )
|
||||||
|
{
|
||||||
|
case Enemy0:
|
||||||
|
{
|
||||||
|
auto instance = teriMgr().getTerritoryByGuId( player.getTerritoryId() );
|
||||||
|
auto enemy1 = instance->createBNpcFromLayoutId( Enemy1, 1220 /*Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
auto enemy2 = instance->createBNpcFromLayoutId( Enemy2, 1220 /*Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
|
||||||
|
enemy1->setTriggerOwnerId( player.getId() );
|
||||||
|
enemy2->setTriggerOwnerId( player.getId() );
|
||||||
|
enemy1->hateListAddDelayed( player.getAsPlayer(), 1 );
|
||||||
|
enemy2->hateListAddDelayed( player.getAsPlayer(), 1 );
|
||||||
|
quest.setUI8AL( 1 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enemy1:
|
||||||
|
case Enemy2:
|
||||||
|
{
|
||||||
|
quest.setUI8AL( quest.getUI8AL() + 1 );
|
||||||
|
if( quest.getUI8AL() >= 4 )
|
||||||
|
{
|
||||||
|
quest.setUI8BH( 0 );
|
||||||
|
quest.setUI8AL( 0 );
|
||||||
|
quest.setSeq( SeqFinish );
|
||||||
|
eventMgr().sendNotice( player, getId(), 0, {} );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Available Scenes in this quest, not necessarly all are used
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00000( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 0, NONE, bindSceneReturn( &SubWil064::Scene00000Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00000Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 ) // accept quest
|
||||||
|
{
|
||||||
|
Scene00001( quest, player );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00001( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 1, NONE, bindSceneReturn( &SubWil064::Scene00001Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
quest.setUI8BH( 1 );
|
||||||
|
quest.setSeq( Seq1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00002( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 2, NONE, bindSceneReturn( &SubWil064::Scene00002Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
quest.setBitFlag8( 1, true );
|
||||||
|
auto instance = teriMgr().getTerritoryByGuId( player.getTerritoryId() );
|
||||||
|
auto enemy0 = instance->createBNpcFromLayoutId( Enemy0, 1220 /*Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
enemy0->setTriggerOwnerId( player.getId() );
|
||||||
|
enemy0->hateListAddDelayed( player.getAsPlayer(), 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00003( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 3, NONE, bindSceneReturn( &SubWil064::Scene00003Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00004( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 4, NONE, bindSceneReturn( &SubWil064::Scene00004Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00004Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00005( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 5, NONE, bindSceneReturn( &SubWil064::Scene00005Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00005Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00006( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 6, NONE, bindSceneReturn( &SubWil064::Scene00006Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00006Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00007( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 7, NONE, bindSceneReturn( &SubWil064::Scene00007Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00007Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00008( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 8, NONE, bindSceneReturn( &SubWil064::Scene00008Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00008Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00009( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 9, NONE, bindSceneReturn( &SubWil064::Scene00009Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00009Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00010( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 10, NONE, bindSceneReturn( &SubWil064::Scene00010Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00010Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00011( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 11, NONE, bindSceneReturn( &SubWil064::Scene00011Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00011Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00012( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 12, NONE, bindSceneReturn( &SubWil064::Scene00012Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00012Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00013( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 13, NONE, bindSceneReturn( &SubWil064::Scene00013Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00013Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
player.finishQuest( getId(), result.getResult( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_SCRIPT( SubWil064 );
|
234
src/scripts/quest/subquest/thanalan_central/SubWil070.cpp
Normal file
234
src/scripts/quest/subquest/thanalan_central/SubWil070.cpp
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
// This is an automatically generated C++ script template
|
||||||
|
// Content needs to be added by hand to make it function
|
||||||
|
// In order for this script to be loaded, move it to the correct folder in <root>/scripts/
|
||||||
|
|
||||||
|
#include <Actor/Player.h>
|
||||||
|
#include "Manager/EventMgr.h"
|
||||||
|
#include <ScriptObject.h>
|
||||||
|
#include <Service.h>
|
||||||
|
|
||||||
|
// Quest Script: SubWil070_00324
|
||||||
|
// Quest Name: Disorderly Conduct
|
||||||
|
// Quest ID: 65860
|
||||||
|
// Start NPC: 1001541 (Roger)
|
||||||
|
// End NPC: 1001541 (Roger)
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
class SubWil070 : public Sapphire::ScriptAPI::QuestScript
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Basic quest information
|
||||||
|
// Quest vars / flags used
|
||||||
|
// BitFlag8
|
||||||
|
// UI8AL
|
||||||
|
// UI8BH
|
||||||
|
|
||||||
|
/// Countable Num: 4 Seq: 1 Event: 1 Listener: 1001462
|
||||||
|
/// Countable Num: 1 Seq: 255 Event: 1 Listener: 1001463
|
||||||
|
// Steps in this quest ( 0 is before accepting,
|
||||||
|
// 1 is first, 255 means ready for turning it in
|
||||||
|
enum Sequence : uint8_t
|
||||||
|
{
|
||||||
|
Seq0 = 0,
|
||||||
|
Seq1 = 1,
|
||||||
|
SeqFinish = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Entities found in the script data of the quest
|
||||||
|
static constexpr auto Actor0 = 1001541; // Roger ( Pos: -99.395401 -11.380900 -41.723999 Teri: 141 )
|
||||||
|
static constexpr auto Actor1 = 1001462; // Roundelph ( Pos: -93.339500 -11.350300 -41.367199 Teri: 141 )
|
||||||
|
static constexpr auto Actor2 = 1001463; // Adalfuns ( Pos: -72.826401 -12.667800 -54.076199 Teri: 141 )
|
||||||
|
static constexpr auto Actor3 = 1001465; // Solid Trunk ( Pos: -90.043503 -11.398500 -53.666000 Teri: 141 )
|
||||||
|
static constexpr auto Actor4 = 1001466; // Ricard ( Pos: -89.735001 -11.350000 -51.539902 Teri: 141 )
|
||||||
|
static constexpr auto Item0 = 2000234;
|
||||||
|
static constexpr auto Item0Icon = 26153;
|
||||||
|
static constexpr auto Seq0Actor0 = 0;
|
||||||
|
static constexpr auto Seq1Actor1 = 1;
|
||||||
|
static constexpr auto Seq1Actor2 = 2;
|
||||||
|
static constexpr auto Seq1Actor3 = 3;
|
||||||
|
static constexpr auto Seq1Actor4 = 4;
|
||||||
|
static constexpr auto Seq2Actor0 = 5;
|
||||||
|
static constexpr auto Seq2Actor0Npctradeno = 99;
|
||||||
|
static constexpr auto Seq2Actor0Npctradeok = 100;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SubWil070() : Sapphire::ScriptAPI::QuestScript( 65860 ){};
|
||||||
|
~SubWil070() = default;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Event Handlers
|
||||||
|
void onTalk( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
switch( actorId )
|
||||||
|
{
|
||||||
|
case Actor0:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == 0 )
|
||||||
|
Scene00000( quest, player );
|
||||||
|
else if( quest.getSeq() == SeqFinish )
|
||||||
|
Scene00005( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor1:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == 1 )
|
||||||
|
Scene00001( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor2:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == 1 )
|
||||||
|
Scene00002( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor3:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == 1 )
|
||||||
|
Scene00003( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor4:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == 1 )
|
||||||
|
Scene00004( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onEventItem( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void checkQuestCompletion( World::Quest& quest, Entity::Player& player, uint32_t varIdx )
|
||||||
|
{
|
||||||
|
if( varIdx == 1 )
|
||||||
|
{
|
||||||
|
quest.setUI8AL( quest.getUI8AL() + 1 );
|
||||||
|
if (quest.getUI8AL() == 4)
|
||||||
|
quest.setSeq( SeqFinish );
|
||||||
|
}
|
||||||
|
eventMgr().sendNotice( player, getId(), 0, { quest.getUI8AL(), 4, Item0Icon } );
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Available Scenes in this quest, not necessarly all are used
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00000( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 0, HIDE_HOTBAR, bindSceneReturn( &SubWil070::Scene00000Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00000Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 ) // accept quest
|
||||||
|
{
|
||||||
|
quest.setUI8BH( 1 );
|
||||||
|
quest.setSeq( Seq1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00001( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 1, HIDE_HOTBAR, bindSceneReturn( &SubWil070::Scene00001Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
checkQuestCompletion( quest, player, 1 );
|
||||||
|
quest.setBitFlag8( 1, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00002( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 2, HIDE_HOTBAR, bindSceneReturn( &SubWil070::Scene00002Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
checkQuestCompletion( quest, player, 1 );
|
||||||
|
quest.setBitFlag8( 2, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00003( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 3, HIDE_HOTBAR, bindSceneReturn( &SubWil070::Scene00003Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
checkQuestCompletion( quest, player, 1 );
|
||||||
|
quest.setBitFlag8( 3, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00004( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 4, HIDE_HOTBAR, bindSceneReturn( &SubWil070::Scene00004Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00004Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
checkQuestCompletion( quest, player, 1 );
|
||||||
|
quest.setBitFlag8( 4, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00005( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 5, NONE, bindSceneReturn( &SubWil070::Scene00005Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00005Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
Scene00100( quest, player );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00099( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 99, NONE, bindSceneReturn( &SubWil070::Scene00099Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00099Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00100( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 100, HIDE_HOTBAR, bindSceneReturn( &SubWil070::Scene00100Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00100Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
player.finishQuest( getId(), result.getResult( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_SCRIPT( SubWil070 );
|
415
src/scripts/quest/subquest/thanalan_central/SubWil073.cpp
Normal file
415
src/scripts/quest/subquest/thanalan_central/SubWil073.cpp
Normal file
|
@ -0,0 +1,415 @@
|
||||||
|
// This is an automatically generated C++ script template
|
||||||
|
// Content needs to be added by hand to make it function
|
||||||
|
// In order for this script to be loaded, move it to the correct folder in <root>/scripts/
|
||||||
|
|
||||||
|
#include "Manager/EventMgr.h"
|
||||||
|
#include <Actor/Player.h>
|
||||||
|
#include <Actor/BNpc.h>
|
||||||
|
#include <ScriptObject.h>
|
||||||
|
#include <Service.h>
|
||||||
|
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "Manager/TerritoryMgr.h"
|
||||||
|
#include "Territory/Territory.h"
|
||||||
|
|
||||||
|
// Quest Script: SubWil073_00327
|
||||||
|
// Quest Name: Spriggan Cleaning
|
||||||
|
// Quest ID: 65863
|
||||||
|
// Start NPC: 1001447 (Warin)
|
||||||
|
// End NPC: 1001447 (Warin)
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
class SubWil073 : public Sapphire::ScriptAPI::QuestScript
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Basic quest information
|
||||||
|
// Quest vars / flags used
|
||||||
|
// BitFlag8
|
||||||
|
// UI8AH
|
||||||
|
// UI8AL
|
||||||
|
// UI8BH
|
||||||
|
// UI8BL
|
||||||
|
// UI8CH
|
||||||
|
// UI8CL
|
||||||
|
// UI8DH
|
||||||
|
// UI8DL
|
||||||
|
// UI8EH
|
||||||
|
|
||||||
|
/// Countable Num: 4 Seq: 1 Event: 1 Listener: 2000377
|
||||||
|
/// Countable Num: 1 Seq: 255 Event: 5 Listener: 100
|
||||||
|
// Steps in this quest ( 0 is before accepting,
|
||||||
|
// 1 is first, 255 means ready for turning it in
|
||||||
|
enum Sequence : uint8_t
|
||||||
|
{
|
||||||
|
Seq0 = 0,
|
||||||
|
Seq1 = 1,
|
||||||
|
SeqFinish = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Entities found in the script data of the quest
|
||||||
|
static constexpr auto Actor0 = 1001447; // Warin ( Pos: -32.639099 -1.033260 -148.485992 Teri: 141 )
|
||||||
|
static constexpr auto Enemy0 = 3742257; //
|
||||||
|
static constexpr auto Enemy1 = 3742258; //
|
||||||
|
static constexpr auto Enemy2 = 3742259; //
|
||||||
|
static constexpr auto Enemy3 = 3742261; //
|
||||||
|
static constexpr auto Eobject0 = 2000377; // Pockmarked Silver Ore ( Pos: -134.695999 6.168210 -116.594002 Teri: 141 )
|
||||||
|
static constexpr auto Eobject1 = 2000378; // Pockmarked Silver Ore ( Pos: -95.958298 -1.021940 -163.731003 Teri: 141 )
|
||||||
|
static constexpr auto Eobject2 = 2000379; // Pockmarked Silver Ore ( Pos: -103.938004 0.491295 -213.695007 Teri: 141 )
|
||||||
|
static constexpr auto Eobject3 = 2000380; // Pockmarked Silver Ore ( Pos: -1.174590 -1.322410 -111.265999 Teri: 141 )
|
||||||
|
static constexpr auto EventActionSearch = 1;
|
||||||
|
static constexpr auto Seq0Actor0 = 0; //
|
||||||
|
static constexpr auto Seq1Eobject0 = 1; //
|
||||||
|
static constexpr auto Seq1Eobject0Eventactionno = 99; // Hecatoncheir Piledriver
|
||||||
|
static constexpr auto Seq1Eobject0Eventactionok = 100; // Hecatoncheir Blastmaster ( Pos: -135.210007 5.708900 -117.417999 Teri: 141 )
|
||||||
|
static constexpr auto Seq1Eobject1 = 2; // Ruins Runner ( Pos: -5.462710 -1.142520 27.215000 Teri: 5 )
|
||||||
|
static constexpr auto Seq1Eobject1Eventactionno = 97; // Hecatoncheir Stonehauler
|
||||||
|
static constexpr auto Seq1Eobject1Eventactionok = 98; // Hecatoncheir Shockblocker
|
||||||
|
static constexpr auto Seq1Eobject2 = 3; // Antelope Doe
|
||||||
|
static constexpr auto Seq1Eobject2Eventactionno = 95; // Flux Flan
|
||||||
|
static constexpr auto Seq1Eobject2Eventactionok = 96; // Hecatoncheir Overseer
|
||||||
|
static constexpr auto Seq1Eobject3 = 4; // Antelope Stag
|
||||||
|
static constexpr auto Seq1Eobject3Eventactionno = 93; // Sargas
|
||||||
|
static constexpr auto Seq1Eobject3Eventactionok = 94; // Shaula
|
||||||
|
static constexpr auto Seq2Actor0 = 5; // Opo-opo
|
||||||
|
|
||||||
|
public:
|
||||||
|
SubWil073() : Sapphire::ScriptAPI::QuestScript( 65863 ){};
|
||||||
|
~SubWil073() = default;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Event Handlers
|
||||||
|
void onTalk( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
switch( actorId )
|
||||||
|
{
|
||||||
|
case Actor0:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq0 )
|
||||||
|
Scene00000( quest, player );
|
||||||
|
else if( quest.getSeq() == SeqFinish )
|
||||||
|
Scene00005( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Eobject0:
|
||||||
|
{
|
||||||
|
eventMgr().eventActionStart(
|
||||||
|
player, getId(), EventActionSearch,
|
||||||
|
[ & ]( Entity::Player& player, uint32_t eventId, uint64_t additional ) {
|
||||||
|
Scene00094( quest, player );
|
||||||
|
},
|
||||||
|
nullptr, 0 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
case Eobject1:
|
||||||
|
{
|
||||||
|
eventMgr().eventActionStart(
|
||||||
|
player, getId(), EventActionSearch,
|
||||||
|
[ & ]( Entity::Player& player, uint32_t eventId, uint64_t additional ) {
|
||||||
|
Scene00095( quest, player );
|
||||||
|
},
|
||||||
|
nullptr, 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Eobject2:
|
||||||
|
{
|
||||||
|
eventMgr().eventActionStart(
|
||||||
|
player, getId(), EventActionSearch,
|
||||||
|
[ & ]( Entity::Player& player, uint32_t eventId, uint64_t additional ) {
|
||||||
|
Scene00096( quest, player );
|
||||||
|
},
|
||||||
|
nullptr, 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Eobject3:
|
||||||
|
{
|
||||||
|
eventMgr().eventActionStart(
|
||||||
|
player, getId(), EventActionSearch,
|
||||||
|
[ & ]( Entity::Player& player, uint32_t eventId, uint64_t additional ) {
|
||||||
|
Scene00097( quest, player );
|
||||||
|
},
|
||||||
|
nullptr, 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onEventItem( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void onBNpcKill( World::Quest& quest, Entity::BNpc& bnpc, Entity::Player& player ) override
|
||||||
|
{
|
||||||
|
switch (bnpc.getLayoutId())
|
||||||
|
{
|
||||||
|
case Enemy0:
|
||||||
|
{
|
||||||
|
quest.setUI8AL( 1 );
|
||||||
|
quest.setUI8BH( 1 );
|
||||||
|
checkQuestCompletion( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enemy1:
|
||||||
|
{
|
||||||
|
quest.setUI8BL( 1 );
|
||||||
|
quest.setUI8CH( 1 );
|
||||||
|
checkQuestCompletion( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enemy2:
|
||||||
|
{
|
||||||
|
quest.setUI8CL( 1 );
|
||||||
|
quest.setUI8DH( 1 );
|
||||||
|
checkQuestCompletion( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enemy3:
|
||||||
|
{
|
||||||
|
quest.setUI8DL( 1 );
|
||||||
|
quest.setUI8EH( 1 );
|
||||||
|
checkQuestCompletion( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void checkQuestCompletion( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
quest.setUI8AH( quest.getUI8AH() + 1 );
|
||||||
|
eventMgr().sendEventNotice( player, getId(), 0, 2, quest.getUI8AH(), 4 );
|
||||||
|
|
||||||
|
if( quest.getUI8AH() >= 4 )
|
||||||
|
{
|
||||||
|
quest.setUI8AL( 0 );
|
||||||
|
quest.setUI8BH( 0 );
|
||||||
|
quest.setUI8BL( 0 );
|
||||||
|
quest.setUI8CH( 0 );
|
||||||
|
quest.setUI8CL( 0 );
|
||||||
|
quest.setUI8DH( 0 );
|
||||||
|
quest.setUI8DL( 0 );
|
||||||
|
quest.setUI8EH( 0 );
|
||||||
|
quest.setUI8AH( 0 );
|
||||||
|
quest.setBitFlag8( 1, false );
|
||||||
|
quest.setBitFlag8( 2, false );
|
||||||
|
quest.setBitFlag8( 3, false );
|
||||||
|
quest.setBitFlag8( 4, false );
|
||||||
|
quest.setSeq( SeqFinish );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Available Scenes in this quest, not necessarly all are used
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00000( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 0, HIDE_HOTBAR, bindSceneReturn( &SubWil073::Scene00000Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00000Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 ) // accept quest
|
||||||
|
{
|
||||||
|
Scene00001( quest, player );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00001( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 1, HIDE_HOTBAR, bindSceneReturn( &SubWil073::Scene00001Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
quest.setSeq( Seq1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00002( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 2, NONE, bindSceneReturn( &SubWil073::Scene00002Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00003( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 3, NONE, bindSceneReturn( &SubWil073::Scene00003Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00004( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 4, NONE, bindSceneReturn( &SubWil073::Scene00004Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00004Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00005( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 5, HIDE_HOTBAR, bindSceneReturn( &SubWil073::Scene00005Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00005Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
player.finishQuest( getId(), result.getResult( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00093( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 93, NONE, bindSceneReturn( &SubWil073::Scene00093Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00093Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00094( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 94, NONE, bindSceneReturn( &SubWil073::Scene00094Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00094Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
auto instance = teriMgr().getTerritoryByGuId( player.getTerritoryId() );
|
||||||
|
auto enemy = instance->createBNpcFromLayoutId( Enemy0, 1220 /*Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
|
||||||
|
enemy->setTriggerOwnerId( player.getId() );
|
||||||
|
enemy->hateListAddDelayed( player.getAsPlayer(), 1 );
|
||||||
|
quest.setBitFlag8( 1, true );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00095( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 95, NONE, bindSceneReturn( &SubWil073::Scene00095Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00095Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
auto instance = teriMgr().getTerritoryByGuId( player.getTerritoryId() );
|
||||||
|
auto enemy = instance->createBNpcFromLayoutId( Enemy1, 1220 /*Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
|
||||||
|
enemy->setTriggerOwnerId( player.getId() );
|
||||||
|
enemy->hateListAddDelayed( player.getAsPlayer(), 1 );
|
||||||
|
quest.setBitFlag8( 2, true );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00096( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 96, NONE, bindSceneReturn( &SubWil073::Scene00096Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00096Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
auto instance = teriMgr().getTerritoryByGuId( player.getTerritoryId() );
|
||||||
|
auto enemy = instance->createBNpcFromLayoutId( Enemy2, 1220 /*Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
|
||||||
|
enemy->setTriggerOwnerId( player.getId() );
|
||||||
|
enemy->hateListAddDelayed( player.getAsPlayer(), 1 );
|
||||||
|
quest.setBitFlag8( 3, true );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00097( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 97, NONE, bindSceneReturn( &SubWil073::Scene00097Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00097Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
auto instance = teriMgr().getTerritoryByGuId( player.getTerritoryId() );
|
||||||
|
auto enemy = instance->createBNpcFromLayoutId( Enemy3, 1220 /*Find the right value*/, Common::BNpcType::Enemy );
|
||||||
|
|
||||||
|
enemy->setTriggerOwnerId( player.getId() );
|
||||||
|
enemy->hateListAddDelayed( player.getAsPlayer(), 1 );
|
||||||
|
quest.setBitFlag8( 4, true );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00098( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 98, NONE, bindSceneReturn( &SubWil073::Scene00098Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00098Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00099( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 99, NONE, bindSceneReturn( &SubWil073::Scene00099Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00099Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00100( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 100, NONE, bindSceneReturn( &SubWil073::Scene00100Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00100Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_SCRIPT( SubWil073 );
|
136
src/scripts/quest/subquest/thanalan_central/SubWil080.cpp
Normal file
136
src/scripts/quest/subquest/thanalan_central/SubWil080.cpp
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
// This is an automatically generated C++ script template
|
||||||
|
// Content needs to be added by hand to make it function
|
||||||
|
// In order for this script to be loaded, move it to the correct folder in <root>/scripts/
|
||||||
|
|
||||||
|
#include <Actor/Player.h>
|
||||||
|
#include "Manager/EventMgr.h"
|
||||||
|
#include <ScriptObject.h>
|
||||||
|
#include <Service.h>
|
||||||
|
|
||||||
|
// Quest Script: SubWil080_00328
|
||||||
|
// Quest Name: Supply and Demands
|
||||||
|
// Quest ID: 65864
|
||||||
|
// Start NPC: 1002065 (Dadanen)
|
||||||
|
// End NPC: 1002061 (Drunken Stag)
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
class SubWil080 : public Sapphire::ScriptAPI::QuestScript
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Basic quest information
|
||||||
|
// Quest vars / flags used
|
||||||
|
// UI8AL
|
||||||
|
// UI8BH
|
||||||
|
|
||||||
|
/// Countable Num: 1 Seq: 255 Event: 1 Listener: 1002061
|
||||||
|
// Steps in this quest ( 0 is before accepting,
|
||||||
|
// 1 is first, 255 means ready for turning it in
|
||||||
|
enum Sequence : uint8_t
|
||||||
|
{
|
||||||
|
Seq0 = 0,
|
||||||
|
SeqFinish = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Entities found in the script data of the quest
|
||||||
|
static constexpr auto Actor0 = 1002065; // Dadanen ( Pos: 60.946701 45.145302 -204.985992 Teri: 140 )
|
||||||
|
static constexpr auto Actor1 = 1002061; // Drunken Stag ( Pos: 240.998993 58.318298 -160.998001 Teri: 140 )
|
||||||
|
static constexpr auto Item0 = 2000368;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SubWil080() : Sapphire::ScriptAPI::QuestScript( 65864 ){};
|
||||||
|
~SubWil080() = default;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Event Handlers
|
||||||
|
void onTalk( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
switch( actorId )
|
||||||
|
{
|
||||||
|
case Actor0:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == Seq0 )
|
||||||
|
Scene00000( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Actor1:
|
||||||
|
{
|
||||||
|
if( quest.getSeq() == SeqFinish )
|
||||||
|
Scene00001( quest, player );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onEventItem( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Available Scenes in this quest, not necessarly all are used
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00000( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 0, HIDE_HOTBAR, bindSceneReturn( &SubWil080::Scene00000Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00000Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if( result.getResult( 0 ) == 1 ) // accept quest
|
||||||
|
{
|
||||||
|
quest.setUI8BH( 1 );
|
||||||
|
quest.setSeq( SeqFinish );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00001( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 1, HIDE_HOTBAR, bindSceneReturn( &SubWil080::Scene00001Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
if (result.getResult(0) == 1)
|
||||||
|
{
|
||||||
|
Scene00002( quest, player );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00002( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 2, NONE, bindSceneReturn( &SubWil080::Scene00002Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00002Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( result.getResult( 0 ) == 1 )
|
||||||
|
{
|
||||||
|
player.finishQuest( getId(), result.getResult( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Scene00003( World::Quest& quest, Entity::Player& player )
|
||||||
|
{
|
||||||
|
eventMgr().playQuestScene( player, getId(), 3, NONE, bindSceneReturn( &SubWil080::Scene00003Return ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene00003Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_SCRIPT( SubWil080 );
|
|
@ -161,22 +161,20 @@ int main( int argc, char* argv[] )
|
||||||
Logger::fatal( "Error setting up EXD data " );
|
Logger::fatal( "Error setting up EXD data " );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
auto idList = g_exdDataGen.getIdList< Excel::Action >();
|
auto actionList = g_exdDataGen.getRows< Excel::Action >();
|
||||||
|
|
||||||
std::map< uint32_t, ActionEntry > actions;
|
std::map< uint32_t, ActionEntry > actions;
|
||||||
std::map< uint32_t, std::vector< uint32_t > > traversedCombos;
|
std::map< uint32_t, std::vector< uint32_t > > traversedCombos;
|
||||||
|
|
||||||
auto total = idList.size();
|
auto total = actionList.size();
|
||||||
int cursor = 0;
|
int cursor = 0;
|
||||||
|
|
||||||
for( auto id : idList )
|
for( const auto& [ id, action ] : actionList )
|
||||||
{
|
{
|
||||||
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
|
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
|
||||||
if( cursor % 50 == 0 && cursor > 0 )
|
if( cursor % 50 == 0 && cursor > 0 )
|
||||||
Logger::info( "Processing {} actions of {} ({:.2f}%)", cursor, total, done );
|
Logger::info( "Processing {} actions of {} ({:.2f}%)", cursor, total, done );
|
||||||
|
|
||||||
auto action = g_exdDataGen.getRow< Excel::Action >( id );
|
|
||||||
|
|
||||||
//auto actionTransient = g_exdData.get< Sapphire::Data::ActionTransient >( id );
|
//auto actionTransient = g_exdData.get< Sapphire::Data::ActionTransient >( id );
|
||||||
if( action )
|
if( action )
|
||||||
{
|
{
|
||||||
|
|
|
@ -89,11 +89,11 @@ int main( int argc, char* argv[] )
|
||||||
// CFC list
|
// CFC list
|
||||||
{
|
{
|
||||||
|
|
||||||
auto idList = g_exdDataGen.getIdList< Excel::ContentFinderCondition >();
|
auto cfcList = g_exdDataGen.getRows< Excel::ContentFinderCondition >();
|
||||||
|
|
||||||
std::stringstream cfcOutputStream;
|
std::stringstream cfcOutputStream;
|
||||||
|
|
||||||
auto total = idList.size();
|
auto total = cfcList.size();
|
||||||
int cursor = 0;
|
int cursor = 0;
|
||||||
|
|
||||||
std::map< uint8_t, std::string > instanceContentTypeMap;
|
std::map< uint8_t, std::string > instanceContentTypeMap;
|
||||||
|
@ -118,7 +118,7 @@ int main( int argc, char* argv[] )
|
||||||
cfcOutputStream << "| ID | Instance | Territory | Name | Type |" << std::endl
|
cfcOutputStream << "| ID | Instance | Territory | Name | Type |" << std::endl
|
||||||
<< "| --- | --- | --- | --- | --- |" << std::endl;
|
<< "| --- | --- | --- | --- | --- |" << std::endl;
|
||||||
|
|
||||||
for( auto id : idList )
|
for( const auto& [ id, cfc ] : cfcList )
|
||||||
{
|
{
|
||||||
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
|
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
|
||||||
if( cursor % 50 == 0 && cursor > 0 )
|
if( cursor % 50 == 0 && cursor > 0 )
|
||||||
|
@ -127,8 +127,6 @@ int main( int argc, char* argv[] )
|
||||||
if( id == 0 )
|
if( id == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto cfc = g_exdDataGen.getRow< Excel::ContentFinderCondition >( id );
|
|
||||||
|
|
||||||
if( cfc )
|
if( cfc )
|
||||||
{
|
{
|
||||||
auto& cfcData = cfc->data();
|
auto& cfcData = cfc->data();
|
||||||
|
@ -234,24 +232,22 @@ int main( int argc, char* argv[] )
|
||||||
teriTypeIntendedUseMap[ TheFeastArea ] = "TheFeastArea";
|
teriTypeIntendedUseMap[ TheFeastArea ] = "TheFeastArea";
|
||||||
teriTypeIntendedUseMap[ PrivateEventArea ] = "PrivateEventArea";
|
teriTypeIntendedUseMap[ PrivateEventArea ] = "PrivateEventArea";
|
||||||
|
|
||||||
auto idList = g_exdDataGen.getIdList< Excel::TerritoryType >();
|
auto teriList = g_exdDataGen.getRows< Excel::TerritoryType >();
|
||||||
|
|
||||||
std::stringstream teritypeOutputStream;
|
std::stringstream teritypeOutputStream;
|
||||||
|
|
||||||
teritypeOutputStream << "| ID | Place Name | Name | Intended Use |" << std::endl
|
teritypeOutputStream << "| ID | Place Name | Name | Intended Use |" << std::endl
|
||||||
<< "| --- | --- | --- | --- |" << std::endl;
|
<< "| --- | --- | --- | --- |" << std::endl;
|
||||||
|
|
||||||
auto total = idList.size();
|
auto total = teriList.size();
|
||||||
int cursor = 0;
|
int cursor = 0;
|
||||||
|
|
||||||
for( auto id : idList )
|
for( const auto& [ id, teriType ] : teriList )
|
||||||
{
|
{
|
||||||
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
|
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
|
||||||
if( cursor % 50 == 0 && cursor > 0 )
|
if( cursor % 50 == 0 && cursor > 0 )
|
||||||
Logger::info( "Processing {} teritypes of {} ({:.2f}%)", cursor, total, done );
|
Logger::info( "Processing {} teritypes of {} ({:.2f}%)", cursor, total, done );
|
||||||
|
|
||||||
auto teriType = g_exdDataGen.getRow< Excel::TerritoryType >( id );
|
|
||||||
|
|
||||||
if( teriType )
|
if( teriType )
|
||||||
{
|
{
|
||||||
auto& teriTypeData = teriType->data();
|
auto& teriTypeData = teriType->data();
|
||||||
|
@ -291,24 +287,22 @@ int main( int argc, char* argv[] )
|
||||||
|
|
||||||
// class/job list
|
// class/job list
|
||||||
{
|
{
|
||||||
auto idList = g_exdDataGen.getIdList< Excel::ClassJob >();
|
auto classJobList = g_exdDataGen.getRows< Excel::ClassJob >();
|
||||||
|
|
||||||
std::stringstream classjobOutputStream;
|
std::stringstream classjobOutputStream;
|
||||||
|
|
||||||
classjobOutputStream << "| ID | Name | Short | Main Class |" << std::endl
|
classjobOutputStream << "| ID | Name | Short | Main Class |" << std::endl
|
||||||
<< "| --- | --- | --- | --- |" << std::endl;
|
<< "| --- | --- | --- | --- |" << std::endl;
|
||||||
|
|
||||||
auto total = idList.size();
|
auto total = classJobList.size();
|
||||||
int cursor = 0;
|
int cursor = 0;
|
||||||
|
|
||||||
for( auto id : idList )
|
for( const auto& [ id, classJob ] : classJobList )
|
||||||
{
|
{
|
||||||
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
|
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
|
||||||
if( cursor % 50 == 0 && cursor > 0 )
|
if( cursor % 50 == 0 && cursor > 0 )
|
||||||
Logger::info( "Processing {} classjobs of {} ({:.2f}%)", cursor, total, done );
|
Logger::info( "Processing {} classjobs of {} ({:.2f}%)", cursor, total, done );
|
||||||
|
|
||||||
auto classJob = g_exdDataGen.getRow< Excel::ClassJob >( id );
|
|
||||||
|
|
||||||
if( classJob )
|
if( classJob )
|
||||||
{
|
{
|
||||||
auto& classJobData = classJob->data();
|
auto& classJobData = classJob->data();
|
||||||
|
@ -338,7 +332,7 @@ int main( int argc, char* argv[] )
|
||||||
|
|
||||||
// achievement list
|
// achievement list
|
||||||
{
|
{
|
||||||
auto idList = g_exdDataGen.getIdList< Excel::Achievement >();
|
auto achvList = g_exdDataGen.getRows< Excel::Achievement >();
|
||||||
|
|
||||||
enum class Type : uint8_t
|
enum class Type : uint8_t
|
||||||
{
|
{
|
||||||
|
@ -394,17 +388,15 @@ int main( int argc, char* argv[] )
|
||||||
achvOutputStream << "| ID | Name | Type (Subtype) | Description |" << std::endl
|
achvOutputStream << "| ID | Name | Type (Subtype) | Description |" << std::endl
|
||||||
<< "| --- | --- | --- | --- |" << std::endl;
|
<< "| --- | --- | --- | --- |" << std::endl;
|
||||||
|
|
||||||
auto total = idList.size();
|
auto total = achvList.size();
|
||||||
int cursor = 0;
|
int cursor = 0;
|
||||||
|
|
||||||
for( auto id : idList )
|
for( const auto& [ id, pAchv ] : achvList )
|
||||||
{
|
{
|
||||||
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
|
auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f;
|
||||||
if( cursor % 50 == 0 && cursor > 0 )
|
if( cursor % 50 == 0 && cursor > 0 )
|
||||||
Logger::info( "Processing {} achievements of {} ({:.2f}%)", cursor, total, done );
|
Logger::info( "Processing {} achievements of {} ({:.2f}%)", cursor, total, done );
|
||||||
|
|
||||||
auto pAchv = g_exdDataGen.getRow< Excel::Achievement >( id );
|
|
||||||
|
|
||||||
if( pAchv )
|
if( pAchv )
|
||||||
{
|
{
|
||||||
auto& achvData = pAchv->data();
|
auto& achvData = pAchv->data();
|
||||||
|
|
95
src/world/AI/Fsm/Condition.h
Normal file
95
src/world/AI/Fsm/Condition.h
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include "ForwardsZone.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include <Util/Util.h>
|
||||||
|
#include <Util/UtilMath.h>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Sapphire::World::AI::Fsm
|
||||||
|
{
|
||||||
|
class Condition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Condition() = default;
|
||||||
|
virtual ~Condition() = default;
|
||||||
|
|
||||||
|
virtual bool isConditionMet( Sapphire::Entity::BNpc& src ) const = 0;
|
||||||
|
virtual bool update( Sapphire::Entity::BNpc& src, float time )
|
||||||
|
{
|
||||||
|
if( isConditionMet( src ) )
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class RoamNextTimeReachedCondition : public Condition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool isConditionMet( Sapphire::Entity::BNpc& src ) const override
|
||||||
|
{
|
||||||
|
if( ( Common::Util::getTimeSeconds() - src.getLastRoamTargetReachedTime() ) > 20 )
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class RoamTargetReachedCondition : public Condition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool isConditionMet( Sapphire::Entity::BNpc& src ) const override
|
||||||
|
{
|
||||||
|
if( src.isRoamTargetReached() )
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HateListEmptyCondition : public Condition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool isConditionMet( Sapphire::Entity::BNpc& src ) const override
|
||||||
|
{
|
||||||
|
if( src.hateListGetHighest() )
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HateListHasEntriesCondition : public Condition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool isConditionMet( Sapphire::Entity::BNpc& src ) const override
|
||||||
|
{
|
||||||
|
if( src.hateListGetHighest() )
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpawnPointDistanceGtMaxDistanceCondition : public Condition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool isConditionMet( Sapphire::Entity::BNpc& src ) const override
|
||||||
|
{
|
||||||
|
auto distanceOrig = Common::Util::distance( src.getPos(), src.getSpawnPos() );
|
||||||
|
if( distanceOrig > 40 )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class IsDeadCondition : public Condition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool isConditionMet( Sapphire::Entity::BNpc& src ) const override
|
||||||
|
{
|
||||||
|
if( !src.isAlive() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
43
src/world/AI/Fsm/State.h
Normal file
43
src/world/AI/Fsm/State.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include "ForwardsZone.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "Transition.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Sapphire::World::AI::Fsm
|
||||||
|
{
|
||||||
|
class State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~State() = default;
|
||||||
|
|
||||||
|
virtual void onUpdate( Entity::BNpc& bnpc, uint64_t tickCount ) = 0;
|
||||||
|
virtual void onEnter( Entity::BNpc& bnpc ) { }
|
||||||
|
virtual void onExit( Entity::BNpc& bnpc ) { }
|
||||||
|
|
||||||
|
void addTransition( TransitionPtr transition )
|
||||||
|
{
|
||||||
|
m_transitions.push_back( transition );
|
||||||
|
}
|
||||||
|
|
||||||
|
void addTransition( StatePtr targetState, ConditionPtr condition )
|
||||||
|
{
|
||||||
|
m_transitions.push_back( make_Transition( targetState, condition ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TransitionPtr getTriggeredTransition( Entity::BNpc& bnpc )
|
||||||
|
{
|
||||||
|
for( auto transition : m_transitions )
|
||||||
|
{
|
||||||
|
if( transition->hasTriggered( bnpc ) )
|
||||||
|
return transition;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector< TransitionPtr > m_transitions;
|
||||||
|
};
|
||||||
|
}
|
79
src/world/AI/Fsm/StateCombat.cpp
Normal file
79
src/world/AI/Fsm/StateCombat.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#include "StateCombat.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "Logging/Logger.h"
|
||||||
|
#include <Service.h>
|
||||||
|
|
||||||
|
#include <Manager/TerritoryMgr.h>
|
||||||
|
#include <Territory/Territory.h>
|
||||||
|
#include <Navi/NaviProvider.h>
|
||||||
|
|
||||||
|
using namespace Sapphire::World;
|
||||||
|
|
||||||
|
void AI::Fsm::StateCombat::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount )
|
||||||
|
{
|
||||||
|
|
||||||
|
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
|
||||||
|
auto pZone = teriMgr.getTerritoryByGuId( bnpc.getTerritoryId() );
|
||||||
|
auto pNaviProvider = pZone->getNaviProvider();
|
||||||
|
|
||||||
|
auto pHatedActor = bnpc.hateListGetHighest();
|
||||||
|
if( !pHatedActor )
|
||||||
|
return;
|
||||||
|
|
||||||
|
pNaviProvider->updateAgentParameters( bnpc );
|
||||||
|
|
||||||
|
auto distanceOrig = Common::Util::distance( bnpc.getPos(), bnpc.getSpawnPos() );
|
||||||
|
|
||||||
|
if( !pHatedActor->isAlive() || bnpc.getTerritoryId() != pHatedActor->getTerritoryId() )
|
||||||
|
{
|
||||||
|
bnpc.hateListRemove( pHatedActor );
|
||||||
|
pHatedActor = bnpc.hateListGetHighest();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !pHatedActor )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto distance = Common::Util::distance( bnpc.getPos(), pHatedActor->getPos() );
|
||||||
|
|
||||||
|
if( !bnpc.hasFlag( Entity::NoDeaggro ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !bnpc.hasFlag( Entity::Immobile ) && distance > ( bnpc.getNaviTargetReachedDistance() + pHatedActor->getRadius() ) )
|
||||||
|
{
|
||||||
|
if( pNaviProvider )
|
||||||
|
pNaviProvider->setMoveTarget( bnpc, pHatedActor->getPos() );
|
||||||
|
|
||||||
|
bnpc.moveTo( *pHatedActor );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pNaviProvider->syncPosToChara( bnpc ) )
|
||||||
|
bnpc.sendPositionUpdate();
|
||||||
|
|
||||||
|
if( distance < ( bnpc.getNaviTargetReachedDistance() + pHatedActor->getRadius() ) )
|
||||||
|
{
|
||||||
|
if( !bnpc.hasFlag( Entity::TurningDisabled ) && bnpc.face( pHatedActor->getPos() ) )
|
||||||
|
bnpc.sendPositionUpdate();
|
||||||
|
|
||||||
|
if( !bnpc.checkAction() )
|
||||||
|
bnpc.processGambits( tickCount );
|
||||||
|
|
||||||
|
// in combat range. ATTACK!
|
||||||
|
bnpc.autoAttack( pHatedActor );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::Fsm::StateCombat::onEnter( Entity::BNpc& bnpc )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::Fsm::StateCombat::onExit( Entity::BNpc& bnpc )
|
||||||
|
{
|
||||||
|
bnpc.hateListClear();
|
||||||
|
bnpc.changeTarget( Common::INVALID_GAME_OBJECT_ID64 );
|
||||||
|
bnpc.setStance( Common::Stance::Passive );
|
||||||
|
bnpc.setOwner( nullptr );
|
||||||
|
}
|
||||||
|
|
20
src/world/AI/Fsm/StateCombat.h
Normal file
20
src/world/AI/Fsm/StateCombat.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include "ForwardsZone.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "State.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Sapphire::World::AI::Fsm
|
||||||
|
{
|
||||||
|
class StateCombat : public State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~StateCombat() = default;
|
||||||
|
|
||||||
|
void onUpdate( Entity::BNpc& bnpc, uint64_t tickCount );
|
||||||
|
void onEnter( Entity::BNpc& bnpc );
|
||||||
|
void onExit( Entity::BNpc& bnpc );
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
26
src/world/AI/Fsm/StateDead.cpp
Normal file
26
src/world/AI/Fsm/StateDead.cpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include "StateDead.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "Logging/Logger.h"
|
||||||
|
#include <Service.h>
|
||||||
|
#include <Manager/TerritoryMgr.h>
|
||||||
|
|
||||||
|
#include <Territory/Territory.h>
|
||||||
|
#include <Navi/NaviProvider.h>
|
||||||
|
|
||||||
|
using namespace Sapphire::World;
|
||||||
|
|
||||||
|
void AI::Fsm::StateDead::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::Fsm::StateDead::onEnter( Entity::BNpc& bnpc )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::Fsm::StateDead::onExit( Entity::BNpc& bnpc )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
20
src/world/AI/Fsm/StateDead.h
Normal file
20
src/world/AI/Fsm/StateDead.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include "ForwardsZone.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "State.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Sapphire::World::AI::Fsm
|
||||||
|
{
|
||||||
|
class StateDead : public State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~StateDead() = default;
|
||||||
|
|
||||||
|
void onUpdate( Entity::BNpc& bnpc, uint64_t tickCount );
|
||||||
|
void onEnter( Entity::BNpc& bnpc );
|
||||||
|
void onExit( Entity::BNpc& bnpc );
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
20
src/world/AI/Fsm/StateIdle.cpp
Normal file
20
src/world/AI/Fsm/StateIdle.cpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "StateIdle.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "Logging/Logger.h"
|
||||||
|
|
||||||
|
using namespace Sapphire::World;
|
||||||
|
|
||||||
|
void AI::Fsm::StateIdle::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::Fsm::StateIdle::onEnter( Entity::BNpc& bnpc )
|
||||||
|
{
|
||||||
|
bnpc.setLastRoamTargetReachedTime( Common::Util::getTimeSeconds() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::Fsm::StateIdle::onExit( Entity::BNpc& bnpc )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
20
src/world/AI/Fsm/StateIdle.h
Normal file
20
src/world/AI/Fsm/StateIdle.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include "ForwardsZone.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "State.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Sapphire::World::AI::Fsm
|
||||||
|
{
|
||||||
|
class StateIdle : public State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~StateIdle() = default;
|
||||||
|
|
||||||
|
void onUpdate( Entity::BNpc& bnpc, uint64_t tickCount );
|
||||||
|
void onEnter( Entity::BNpc& bnpc );
|
||||||
|
void onExit( Entity::BNpc& bnpc );
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
38
src/world/AI/Fsm/StateMachine.cpp
Normal file
38
src/world/AI/Fsm/StateMachine.cpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include "ForwardsZone.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "StateMachine.h"
|
||||||
|
#include "State.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
using namespace Sapphire::World;
|
||||||
|
|
||||||
|
AI::Fsm::StatePtr AI::Fsm::StateMachine::addState( Fsm::StatePtr state )
|
||||||
|
{
|
||||||
|
m_states.push_back( state );
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::Fsm::StateMachine::setCurrentState( Fsm::StatePtr state )
|
||||||
|
{
|
||||||
|
m_pCurrentState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::Fsm::StateMachine::update( Entity::BNpc& bnpc, uint64_t tickCount )
|
||||||
|
{
|
||||||
|
if( !m_pCurrentState )
|
||||||
|
return;
|
||||||
|
|
||||||
|
TransitionPtr transition = m_pCurrentState->getTriggeredTransition( bnpc );
|
||||||
|
|
||||||
|
if( transition )
|
||||||
|
{
|
||||||
|
m_pCurrentState->onExit( bnpc );
|
||||||
|
m_pCurrentState = transition->getTargetState();
|
||||||
|
m_pCurrentState->onEnter( bnpc );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pCurrentState->onUpdate( bnpc, tickCount );
|
||||||
|
}
|
23
src/world/AI/Fsm/StateMachine.h
Normal file
23
src/world/AI/Fsm/StateMachine.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include "ForwardsZone.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Sapphire::World::AI::Fsm
|
||||||
|
{
|
||||||
|
class StateMachine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StateMachine() = default;
|
||||||
|
~StateMachine() = default;
|
||||||
|
|
||||||
|
StatePtr addState( StatePtr state );
|
||||||
|
void setCurrentState( StatePtr state );
|
||||||
|
virtual void update( Entity::BNpc& bnpc, uint64_t tickCount );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector< StatePtr > m_states;
|
||||||
|
StatePtr m_pCurrentState;
|
||||||
|
};
|
||||||
|
}
|
41
src/world/AI/Fsm/StateRetreat.cpp
Normal file
41
src/world/AI/Fsm/StateRetreat.cpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#include "StateRetreat.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "Logging/Logger.h"
|
||||||
|
#include <Service.h>
|
||||||
|
#include <Manager/TerritoryMgr.h>
|
||||||
|
|
||||||
|
#include <Territory/Territory.h>
|
||||||
|
#include <Navi/NaviProvider.h>
|
||||||
|
|
||||||
|
using namespace Sapphire::World;
|
||||||
|
|
||||||
|
void AI::Fsm::StateRetreat::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount )
|
||||||
|
{
|
||||||
|
if( bnpc.moveTo( bnpc.getSpawnPos() ) )
|
||||||
|
{
|
||||||
|
bnpc.setRoamTargetReached( true );
|
||||||
|
bnpc.setLastRoamTargetReachedTime( Common::Util::getTimeSeconds() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::Fsm::StateRetreat::onEnter( Entity::BNpc& bnpc )
|
||||||
|
{
|
||||||
|
bnpc.setRoamTargetReached( false );
|
||||||
|
|
||||||
|
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
|
||||||
|
auto pZone = teriMgr.getTerritoryByGuId( bnpc.getTerritoryId() );
|
||||||
|
auto pNaviProvider = pZone->getNaviProvider();
|
||||||
|
|
||||||
|
bnpc.setInvincibilityType( Common::InvincibilityType::InvincibilityIgnoreDamage );
|
||||||
|
|
||||||
|
if( pNaviProvider )
|
||||||
|
pNaviProvider->setMoveTarget( bnpc, bnpc.getSpawnPos() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::Fsm::StateRetreat::onExit( Entity::BNpc& bnpc )
|
||||||
|
{
|
||||||
|
bnpc.setOwner( nullptr );
|
||||||
|
bnpc.setRoamTargetReached( false );
|
||||||
|
bnpc.setInvincibilityType( Common::InvincibilityType::InvincibilityNone );
|
||||||
|
}
|
||||||
|
|
20
src/world/AI/Fsm/StateRetreat.h
Normal file
20
src/world/AI/Fsm/StateRetreat.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include "ForwardsZone.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "State.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Sapphire::World::AI::Fsm
|
||||||
|
{
|
||||||
|
class StateRetreat : public State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~StateRetreat() = default;
|
||||||
|
|
||||||
|
void onUpdate( Entity::BNpc& bnpc, uint64_t tickCount );
|
||||||
|
void onEnter( Entity::BNpc& bnpc );
|
||||||
|
void onExit( Entity::BNpc& bnpc );
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
49
src/world/AI/Fsm/StateRoam.cpp
Normal file
49
src/world/AI/Fsm/StateRoam.cpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#include "StateRoam.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "Logging/Logger.h"
|
||||||
|
#include <Service.h>
|
||||||
|
#include <Manager/TerritoryMgr.h>
|
||||||
|
|
||||||
|
#include <Territory/Territory.h>
|
||||||
|
#include <Navi/NaviProvider.h>
|
||||||
|
|
||||||
|
using namespace Sapphire::World;
|
||||||
|
|
||||||
|
void AI::Fsm::StateRoam::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount )
|
||||||
|
{
|
||||||
|
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
|
||||||
|
auto pZone = teriMgr.getTerritoryByGuId( bnpc.getTerritoryId() );
|
||||||
|
auto pNaviProvider = pZone->getNaviProvider();
|
||||||
|
|
||||||
|
if( pNaviProvider )
|
||||||
|
pNaviProvider->setMoveTarget( bnpc, bnpc.getRoamTargetPos() );
|
||||||
|
|
||||||
|
if( bnpc.moveTo( bnpc.getRoamTargetPos() ) )
|
||||||
|
{
|
||||||
|
bnpc.setRoamTargetReached( true );
|
||||||
|
bnpc.setLastRoamTargetReachedTime( Common::Util::getTimeSeconds() );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::Fsm::StateRoam::onEnter( Entity::BNpc& bnpc )
|
||||||
|
{
|
||||||
|
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
|
||||||
|
auto pZone = teriMgr.getTerritoryByGuId( bnpc.getTerritoryId() );
|
||||||
|
auto pNaviProvider = pZone->getNaviProvider();
|
||||||
|
|
||||||
|
if( !pNaviProvider )
|
||||||
|
{
|
||||||
|
bnpc.setRoamTargetReached( true );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pos = pNaviProvider->findRandomPositionInCircle( bnpc.getSpawnPos(), bnpc.getInstanceObjectInfo()->WanderingRange );
|
||||||
|
bnpc.setRoamTargetPos( pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::Fsm::StateRoam::onExit( Entity::BNpc& bnpc )
|
||||||
|
{
|
||||||
|
bnpc.setRoamTargetReached( false );
|
||||||
|
}
|
||||||
|
|
20
src/world/AI/Fsm/StateRoam.h
Normal file
20
src/world/AI/Fsm/StateRoam.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include "ForwardsZone.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "State.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Sapphire::World::AI::Fsm
|
||||||
|
{
|
||||||
|
class StateRoam : public State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~StateRoam() = default;
|
||||||
|
|
||||||
|
void onUpdate( Entity::BNpc& bnpc, uint64_t tickCount );
|
||||||
|
void onEnter( Entity::BNpc& bnpc );
|
||||||
|
void onExit( Entity::BNpc& bnpc );
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
22
src/world/AI/Fsm/Transition.h
Normal file
22
src/world/AI/Fsm/Transition.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include "ForwardsZone.h"
|
||||||
|
#include "Actor/BNpc.h"
|
||||||
|
#include "AI/Fsm/Condition.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Sapphire::World::AI::Fsm
|
||||||
|
{
|
||||||
|
class Transition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Transition( StatePtr targetState, ConditionPtr condition ) : m_pTargetState( targetState ), m_pCondition( condition ) { }
|
||||||
|
virtual ~Transition() = default;
|
||||||
|
|
||||||
|
StatePtr getTargetState() { return m_pTargetState; }
|
||||||
|
bool hasTriggered( Entity::BNpc& bnpc ) { return m_pCondition->isConditionMet( bnpc ); }
|
||||||
|
private:
|
||||||
|
StatePtr m_pTargetState;
|
||||||
|
ConditionPtr m_pCondition;
|
||||||
|
};
|
||||||
|
}
|
135
src/world/AI/GambitPack.cpp
Normal file
135
src/world/AI/GambitPack.cpp
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include <ForwardsZone.h>
|
||||||
|
#include <Service.h>
|
||||||
|
#include <Manager/ActionMgr.h>
|
||||||
|
#include <Action/Action.h>
|
||||||
|
#include "GambitTargetCondition.h"
|
||||||
|
#include "GambitRule.h"
|
||||||
|
#include "GambitPack.h"
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
using namespace Sapphire::World;
|
||||||
|
|
||||||
|
AI::GambitTimeLinePack::GambitTimeLinePack( int8_t loopCount ) :
|
||||||
|
GambitPack( GambitPackType::TimeLine ),
|
||||||
|
m_loopCount( loopCount ),
|
||||||
|
m_currentIndex( 0 ),
|
||||||
|
m_currentLoop( 0 ),
|
||||||
|
m_startTimeMs( 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::GambitTimeLinePack::start()
|
||||||
|
{
|
||||||
|
m_startTimeMs = Common::Util::getTimeMs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::GambitTimeLinePack::addTimeLine( const GambitRulePtr& pRule, uint32_t offsetInSeconds )
|
||||||
|
{
|
||||||
|
auto timeLine = std::make_pair( pRule, offsetInSeconds );
|
||||||
|
m_gambits.push_back( timeLine );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::GambitTimeLinePack::addTimeLine( const GambitTargetConditionPtr& targetCondition, const Action::ActionPtr& action, uint32_t offsetInSeconds )
|
||||||
|
{
|
||||||
|
auto pRule = make_GambitRule( targetCondition, action, 0 );
|
||||||
|
auto timeLine = std::make_pair( pRule, offsetInSeconds );
|
||||||
|
m_gambits.push_back( timeLine );
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t AI::GambitTimeLinePack::getLoopCount() const
|
||||||
|
{
|
||||||
|
return m_loopCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t AI::GambitTimeLinePack::getCurrentIndex() const
|
||||||
|
{
|
||||||
|
return m_currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::GambitTimeLinePack::update( Entity::BNpc& bnpc, uint64_t tickCount )
|
||||||
|
{
|
||||||
|
if( m_startTimeMs == 0 || m_gambits.empty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto& actionMgr = Common::Service< World::Manager::ActionMgr >::ref();
|
||||||
|
|
||||||
|
if( m_gambits.size() <= m_currentIndex )
|
||||||
|
{
|
||||||
|
if( m_currentLoop < m_loopCount || m_loopCount == -1 )
|
||||||
|
{
|
||||||
|
m_currentIndex = 0;
|
||||||
|
m_currentLoop++;
|
||||||
|
m_startTimeMs = Common::Util::getTimeMs();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_startTimeMs = 0;
|
||||||
|
m_currentLoop = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto currentTimeLine = m_gambits.at( m_currentIndex );
|
||||||
|
auto& pRule = currentTimeLine.first;
|
||||||
|
auto offset = currentTimeLine.second * 1000;
|
||||||
|
|
||||||
|
if( tickCount - m_startTimeMs >= offset )
|
||||||
|
{
|
||||||
|
if( pRule->getGambitTargetCondition()->isConditionMet( bnpc ) )
|
||||||
|
{
|
||||||
|
pRule->setLastExecutionMs( tickCount );
|
||||||
|
actionMgr.handleTargetedAction( bnpc, pRule->getActionPtr()->getId(), pRule->getGambitTargetCondition()->getTarget()->getId(), 0 );
|
||||||
|
}
|
||||||
|
m_currentIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
AI::GambitRuleSetPack::GambitRuleSetPack() : GambitPack( GambitPackType::RuleSetList )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::GambitRuleSetPack::addRule( const GambitRulePtr& pRule )
|
||||||
|
{
|
||||||
|
m_gambits.push_back( pRule );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::GambitRuleSetPack::addRule( const GambitTargetConditionPtr& targetCondition, const Action::ActionPtr& action, uint32_t coolDown )
|
||||||
|
{
|
||||||
|
auto pRule = make_GambitRule( targetCondition, action, coolDown );
|
||||||
|
m_gambits.push_back( pRule );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AI::GambitRuleSetPack::update( Entity::BNpc& bnpc, uint64_t tickCount )
|
||||||
|
{
|
||||||
|
auto& actionMgr = Common::Service< World::Manager::ActionMgr >::ref();
|
||||||
|
for( auto& gambitRule : m_gambits )
|
||||||
|
{
|
||||||
|
if( !gambitRule->isEnabled() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( ( tickCount - gambitRule->getLastExecutionMs() ) > gambitRule->getCoolDown() )
|
||||||
|
{
|
||||||
|
if( !gambitRule->getGambitTargetCondition()->isConditionMet( bnpc ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
gambitRule->setLastExecutionMs( tickCount );
|
||||||
|
actionMgr.handleTargetedAction( bnpc, gambitRule->getActionPtr()->getId(), gambitRule->getGambitTargetCondition()->getTarget()->getId(), 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AI::GambitTimeLinePackPtr AI::GambitPack::getAsTimeLine()
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast< GambitTimeLinePack, GambitPack >( shared_from_this() );
|
||||||
|
}
|
||||||
|
|
||||||
|
AI::GambitRuleSetPackPtr AI::GambitPack::getAsRuleSet()
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast< GambitRuleSetPack, GambitPack >( shared_from_this() );
|
||||||
|
}
|
60
src/world/AI/GambitPack.h
Normal file
60
src/world/AI/GambitPack.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include <ForwardsZone.h>
|
||||||
|
#include "GambitTargetCondition.h"
|
||||||
|
#include "GambitRule.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Sapphire::World::AI
|
||||||
|
{
|
||||||
|
enum class GambitPackType : uint8_t
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
RuleSetList,
|
||||||
|
TimeLine
|
||||||
|
};
|
||||||
|
|
||||||
|
class GambitPack : public std::enable_shared_from_this< GambitPack >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GambitPack( GambitPackType type ) : m_type( type ) { };
|
||||||
|
virtual ~GambitPack() = default;
|
||||||
|
GambitPackType getType() const { return m_type; }
|
||||||
|
virtual void update( Entity::BNpc& bnpc, uint64_t tickCount ) = 0;
|
||||||
|
GambitTimeLinePackPtr getAsTimeLine();
|
||||||
|
GambitRuleSetPackPtr getAsRuleSet();
|
||||||
|
private:
|
||||||
|
GambitPackType m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GambitTimeLinePack : public GambitPack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GambitTimeLinePack( int8_t loopCount );
|
||||||
|
void update( Entity::BNpc& bnpc, uint64_t tickCount );
|
||||||
|
void addTimeLine( const GambitRulePtr& pRule, uint32_t offsetInSeconds );
|
||||||
|
void addTimeLine( const GambitTargetConditionPtr& targetCondition, const Action::ActionPtr& action, uint32_t offsetInSeconds );
|
||||||
|
uint8_t getLoopCount() const;
|
||||||
|
uint8_t getCurrentIndex() const;
|
||||||
|
void start();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector< std::pair< GambitRulePtr, uint32_t > > m_gambits;
|
||||||
|
|
||||||
|
uint64_t m_startTimeMs;
|
||||||
|
uint8_t m_currentIndex;
|
||||||
|
int8_t m_loopCount;
|
||||||
|
uint8_t m_currentLoop;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GambitRuleSetPack : public GambitPack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GambitRuleSetPack();
|
||||||
|
void addRule( const GambitRulePtr& pRule );
|
||||||
|
void addRule( const GambitTargetConditionPtr& targetCondition, const Action::ActionPtr& action, uint32_t coolDown );
|
||||||
|
void update( Entity::BNpc& bnpc, uint64_t tickCount );
|
||||||
|
private:
|
||||||
|
std::vector< GambitRulePtr > m_gambits;
|
||||||
|
};
|
||||||
|
}
|
|
@ -18,20 +18,19 @@ namespace Sapphire::World::AI
|
||||||
class GambitTargetCondition
|
class GambitTargetCondition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GambitTargetCondition( GambitTargetType targetType ) : m_targetType( targetType ) {};
|
GambitTargetCondition() = default;
|
||||||
virtual ~GambitTargetCondition() = default;
|
virtual ~GambitTargetCondition() = default;
|
||||||
|
|
||||||
virtual bool isConditionMet( Sapphire::Entity::BNpc& src ) { return false; };
|
virtual bool isConditionMet( Sapphire::Entity::BNpc& src ) { return false; };
|
||||||
Sapphire::Entity::CharaPtr getTarget() const { return m_pTarget; };
|
Sapphire::Entity::CharaPtr getTarget() const { return m_pTarget; };
|
||||||
protected:
|
protected:
|
||||||
GambitTargetType m_targetType;
|
|
||||||
Sapphire::Entity::CharaPtr m_pTarget;
|
Sapphire::Entity::CharaPtr m_pTarget;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TopHateTargetCondition : public GambitTargetCondition
|
class TopHateTargetCondition : public GambitTargetCondition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TopHateTargetCondition() : GambitTargetCondition( PlayerAndAlly ) {};
|
TopHateTargetCondition() = default;
|
||||||
|
|
||||||
bool isConditionMet( Sapphire::Entity::BNpc& src ) override
|
bool isConditionMet( Sapphire::Entity::BNpc& src ) override
|
||||||
{
|
{
|
||||||
|
@ -45,12 +44,12 @@ namespace Sapphire::World::AI
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class HPSelfPctLessThan : public GambitTargetCondition
|
class HPSelfPctLessThanTargetCondition : public GambitTargetCondition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HPSelfPctLessThan( uint8_t pct ) : GambitTargetCondition( Self ), m_HpPct( pct ) {};
|
HPSelfPctLessThanTargetCondition( uint8_t pct ) : m_HpPct( pct ) {};
|
||||||
|
|
||||||
virtual bool isConditionMet( Sapphire::Entity::BNpc& src )
|
bool isConditionMet( Sapphire::Entity::BNpc& src ) override
|
||||||
{
|
{
|
||||||
if( src.getHpPercent() < m_HpPct )
|
if( src.getHpPercent() < m_HpPct )
|
||||||
{
|
{
|
||||||
|
|
|
@ -457,7 +457,7 @@ void Action::Action::execute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcDamage( uint32_t potency )
|
std::pair< uint32_t, Common::CalcResultType > Action::Action::calcDamage( uint32_t potency )
|
||||||
{
|
{
|
||||||
// todo: what do for npcs?
|
// todo: what do for npcs?
|
||||||
auto wepDmg = 1.f;
|
auto wepDmg = 1.f;
|
||||||
|
@ -481,7 +481,7 @@ std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcDamage(
|
||||||
return Math::CalcStats::calcActionDamage( *m_pSource, potency, wepDmg );
|
return Math::CalcStats::calcActionDamage( *m_pSource, potency, wepDmg );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcHealing( uint32_t potency )
|
std::pair< uint32_t, Common::CalcResultType > Action::Action::calcHealing( uint32_t potency )
|
||||||
{
|
{
|
||||||
auto wepDmg = 1.f;
|
auto wepDmg = 1.f;
|
||||||
|
|
||||||
|
@ -520,7 +520,7 @@ void Action::Action::buildActionResults()
|
||||||
|
|
||||||
Network::Util::Packet::sendHudParam( *m_pSource );
|
Network::Util::Packet::sendHudParam( *m_pSource );
|
||||||
|
|
||||||
if( !m_enableGenericHandler || !hasLutEntry || m_hitActors.empty() )
|
if( m_hitActors.empty() )
|
||||||
{
|
{
|
||||||
// send any effect packet added by script or an empty one just to play animation for other players
|
// send any effect packet added by script or an empty one just to play animation for other players
|
||||||
m_actionResultBuilder->sendActionResults( {} );
|
m_actionResultBuilder->sendActionResults( {} );
|
||||||
|
@ -539,6 +539,8 @@ void Action::Action::buildActionResults()
|
||||||
bool shouldRestoreMP = true;
|
bool shouldRestoreMP = true;
|
||||||
bool shouldApplyComboSucceedEffect = true;
|
bool shouldApplyComboSucceedEffect = true;
|
||||||
|
|
||||||
|
if( m_enableGenericHandler && hasLutEntry )
|
||||||
|
{
|
||||||
for( auto& actor : m_hitActors )
|
for( auto& actor : m_hitActors )
|
||||||
{
|
{
|
||||||
if( m_lutEntry.potency > 0 )
|
if( m_lutEntry.potency > 0 )
|
||||||
|
@ -591,6 +593,10 @@ void Action::Action::buildActionResults()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( m_lutEntry.statuses.caster.size() > 0 || m_lutEntry.statuses.target.size() > 0 )
|
||||||
|
handleStatusEffects();
|
||||||
|
}
|
||||||
|
|
||||||
// If we hit an enemy
|
// If we hit an enemy
|
||||||
if( m_hitActors.size() > 0 && getHitChara()->getObjKind() != m_pSource->getObjKind() )
|
if( m_hitActors.size() > 0 && getHitChara()->getObjKind() != m_pSource->getObjKind() )
|
||||||
{
|
{
|
||||||
|
@ -599,9 +605,6 @@ void Action::Action::buildActionResults()
|
||||||
|
|
||||||
handleJobAction();
|
handleJobAction();
|
||||||
|
|
||||||
if( m_lutEntry.statuses.caster.size() > 0 || m_lutEntry.statuses.target.size() > 0 )
|
|
||||||
handleStatusEffects();
|
|
||||||
|
|
||||||
m_actionResultBuilder->sendActionResults( m_hitActors );
|
m_actionResultBuilder->sendActionResults( m_hitActors );
|
||||||
|
|
||||||
// TODO: disabled, reset kills our queued actions
|
// TODO: disabled, reset kills our queued actions
|
||||||
|
|
|
@ -128,9 +128,9 @@ namespace Sapphire::World::Action
|
||||||
*/
|
*/
|
||||||
void addDefaultActorFilters();
|
void addDefaultActorFilters();
|
||||||
|
|
||||||
std::pair< uint32_t, Common::ActionHitSeverityType > calcDamage( uint32_t potency );
|
std::pair< uint32_t, Common::CalcResultType > calcDamage( uint32_t potency );
|
||||||
|
|
||||||
std::pair< uint32_t, Common::ActionHitSeverityType > calcHealing( uint32_t potency );
|
std::pair< uint32_t, Common::CalcResultType > calcHealing( uint32_t potency );
|
||||||
|
|
||||||
|
|
||||||
std::vector< Entity::CharaPtr >& getHitCharas();
|
std::vector< Entity::CharaPtr >& getHitCharas();
|
||||||
|
|
|
@ -10,19 +10,19 @@
|
||||||
#include "StatusEffect/StatusEffect.h"
|
#include "StatusEffect/StatusEffect.h"
|
||||||
|
|
||||||
using namespace Sapphire;
|
using namespace Sapphire;
|
||||||
|
using namespace Sapphire::Common;
|
||||||
using namespace Sapphire::World::Action;
|
using namespace Sapphire::World::Action;
|
||||||
|
|
||||||
|
|
||||||
ActionResult::ActionResult( Entity::CharaPtr target, uint64_t runAfter ) :
|
ActionResult::ActionResult( Entity::CharaPtr target ) :
|
||||||
m_target( std::move( target ) ),
|
m_target( std::move( target ) )
|
||||||
m_delayMs( runAfter )
|
|
||||||
{
|
{
|
||||||
m_result.Arg0 = 0;
|
m_result.Arg0 = 0;
|
||||||
m_result.Arg1 = 0;
|
m_result.Arg1 = 0;
|
||||||
m_result.Arg2 = 0;
|
m_result.Arg2 = 0;
|
||||||
m_result.Value = 0;
|
m_result.Value = 0;
|
||||||
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::None );
|
m_result.Flag = static_cast< uint8_t >( ActionResultFlag::None );
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_NONE;
|
m_result.Type = CalcResultType::TypeNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity::CharaPtr ActionResult::getTarget() const
|
Entity::CharaPtr ActionResult::getTarget() const
|
||||||
|
@ -30,52 +30,47 @@ Entity::CharaPtr ActionResult::getTarget() const
|
||||||
return m_target;
|
return m_target;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ActionResult::getDelay()
|
void ActionResult::damage( uint32_t amount, CalcResultType hitType, uint8_t hitEffect, ActionResultFlag flag )
|
||||||
{
|
{
|
||||||
return m_delayMs;
|
m_result.Arg0 = hitEffect;
|
||||||
}
|
|
||||||
|
|
||||||
void ActionResult::damage( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag )
|
|
||||||
{
|
|
||||||
m_result.Arg0 = static_cast< uint8_t >( severity );
|
|
||||||
m_result.Value = static_cast< int16_t >( amount );
|
m_result.Value = static_cast< int16_t >( amount );
|
||||||
m_result.Flag = static_cast< uint8_t >( flag );
|
m_result.Flag = static_cast< uint8_t >( flag );
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP;
|
m_result.Type = hitType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResult::heal( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag )
|
void ActionResult::heal( uint32_t amount, CalcResultType hitType, uint8_t hitEffect, ActionResultFlag flag )
|
||||||
{
|
{
|
||||||
m_result.Arg1 = static_cast< uint8_t >( severity );
|
m_result.Arg0 = hitEffect;
|
||||||
m_result.Value = static_cast< int16_t >( amount );
|
m_result.Value = static_cast< int16_t >( amount );
|
||||||
m_result.Flag = static_cast< uint8_t >( flag );
|
m_result.Flag = static_cast< uint8_t >( flag );
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_RECOVER_HP;
|
m_result.Type = hitType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResult::restoreMP( uint32_t amount, Common::ActionResultFlag flag )
|
void ActionResult::restoreMP( uint32_t amount, ActionResultFlag flag )
|
||||||
{
|
{
|
||||||
m_result.Value = static_cast< int16_t >( amount );
|
m_result.Value = static_cast< int16_t >( amount );
|
||||||
m_result.Flag = static_cast< uint8_t >( flag );
|
m_result.Flag = static_cast< uint8_t >( flag );
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_RECOVER_MP;
|
m_result.Type = CalcResultType::TypeRecoverMp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResult::startCombo( uint16_t actionId )
|
void ActionResult::startCombo( uint16_t actionId )
|
||||||
{
|
{
|
||||||
m_result.Value = static_cast< int16_t >( actionId );
|
m_result.Value = static_cast< int16_t >( actionId );
|
||||||
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::EffectOnSource );
|
m_result.Flag = static_cast< uint8_t >( ActionResultFlag::EffectOnSource );
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_COMBO;
|
m_result.Type = CalcResultType::TypeCombo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResult::comboSucceed()
|
void ActionResult::comboSucceed()
|
||||||
{
|
{
|
||||||
// no EffectOnSource flag on this
|
// no EffectOnSource flag on this
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_COMBO_HIT;
|
m_result.Type = CalcResultType::TypeComboHit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResult::applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param, bool shouldOverride )
|
void ActionResult::applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param, bool shouldOverride )
|
||||||
{
|
{
|
||||||
m_result.Value = static_cast< int16_t >( id );
|
m_result.Value = static_cast< int16_t >( id );
|
||||||
m_result.Arg2 = param;
|
m_result.Arg2 = param;
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS;
|
m_result.Type = CalcResultType::TypeSetStatus;
|
||||||
|
|
||||||
m_bOverrideStatus = shouldOverride;
|
m_bOverrideStatus = shouldOverride;
|
||||||
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, 3000 );
|
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, 3000 );
|
||||||
|
@ -87,7 +82,7 @@ void ActionResult::applyStatusEffect( uint32_t id, int32_t duration, Entity::Cha
|
||||||
{
|
{
|
||||||
m_result.Value = static_cast< int16_t >( id );
|
m_result.Value = static_cast< int16_t >( id );
|
||||||
m_result.Arg2 = param;
|
m_result.Arg2 = param;
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS;
|
m_result.Type = CalcResultType::TypeSetStatus;
|
||||||
|
|
||||||
m_bOverrideStatus = shouldOverride;
|
m_bOverrideStatus = shouldOverride;
|
||||||
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, modifiers, flag, 3000 );
|
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, modifiers, flag, 3000 );
|
||||||
|
@ -98,8 +93,8 @@ void ActionResult::applyStatusEffectSelf( uint32_t id, int32_t duration, uint8_t
|
||||||
{
|
{
|
||||||
m_result.Value = static_cast< int16_t >( id );
|
m_result.Value = static_cast< int16_t >( id );
|
||||||
m_result.Arg2 = param;
|
m_result.Arg2 = param;
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS_ME;
|
m_result.Type = CalcResultType::TypeSetStatusMe;
|
||||||
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::EffectOnSource );
|
m_result.Flag = static_cast< uint8_t >( ActionResultFlag::EffectOnSource );
|
||||||
|
|
||||||
m_bOverrideStatus = shouldOverride;
|
m_bOverrideStatus = shouldOverride;
|
||||||
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, m_target, m_target, duration, 3000 );
|
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, m_target, m_target, duration, 3000 );
|
||||||
|
@ -111,7 +106,7 @@ void ActionResult::applyStatusEffectSelf( uint32_t id, int32_t duration, uint8_t
|
||||||
{
|
{
|
||||||
m_result.Value = static_cast< int16_t >( id );
|
m_result.Value = static_cast< int16_t >( id );
|
||||||
m_result.Arg2 = param;
|
m_result.Arg2 = param;
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS_ME;
|
m_result.Type = CalcResultType::TypeSetStatusMe;
|
||||||
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::EffectOnSource );
|
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::EffectOnSource );
|
||||||
|
|
||||||
m_bOverrideStatus = shouldOverride;
|
m_bOverrideStatus = shouldOverride;
|
||||||
|
@ -123,7 +118,7 @@ void ActionResult::mount( uint16_t mountId )
|
||||||
{
|
{
|
||||||
m_result.Value = static_cast< int16_t >( mountId );
|
m_result.Value = static_cast< int16_t >( mountId );
|
||||||
m_result.Arg0 = 1;
|
m_result.Arg0 = 1;
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_MOUNT;
|
m_result.Type = CalcResultType::TypeMount;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Common::CalcResultParam& ActionResult::getCalcResultParam() const
|
const Common::CalcResultParam& ActionResult::getCalcResultParam() const
|
||||||
|
@ -143,26 +138,28 @@ void ActionResult::execute()
|
||||||
|
|
||||||
switch( m_result.Type )
|
switch( m_result.Type )
|
||||||
{
|
{
|
||||||
case Common::ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP:
|
case CalcResultType::TypeDamageHp:
|
||||||
|
case CalcResultType::TypeCriticalDamageHp:
|
||||||
{
|
{
|
||||||
m_target->takeDamage( m_result.Value );
|
m_target->takeDamage( m_result.Value );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Common::ActionEffectType::CALC_RESULT_TYPE_RECOVER_HP:
|
case CalcResultType::TypeRecoverHp:
|
||||||
|
case CalcResultType::TypeCriticalRecoverHp:
|
||||||
{
|
{
|
||||||
m_target->heal( m_result.Value );
|
m_target->heal( m_result.Value );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Common::ActionEffectType::CALC_RESULT_TYPE_RECOVER_MP:
|
case CalcResultType::TypeRecoverMp:
|
||||||
{
|
{
|
||||||
m_target->restoreMP( m_result.Value );
|
m_target->restoreMP( m_result.Value );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS:
|
case CalcResultType::TypeSetStatus:
|
||||||
case Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS_ME:
|
case CalcResultType::TypeSetStatusMe:
|
||||||
{
|
{
|
||||||
if( !m_bOverrideStatus )
|
if( !m_bOverrideStatus )
|
||||||
m_target->addStatusEffectByIdIfNotExist( m_pStatus );
|
m_target->addStatusEffectByIdIfNotExist( m_pStatus );
|
||||||
|
@ -171,7 +168,7 @@ void ActionResult::execute()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Common::ActionEffectType::CALC_RESULT_TYPE_MOUNT:
|
case CalcResultType::TypeMount:
|
||||||
{
|
{
|
||||||
auto pPlayer = m_target->getAsPlayer();
|
auto pPlayer = m_target->getAsPlayer();
|
||||||
pPlayer->setMount( m_result.Value );
|
pPlayer->setMount( m_result.Value );
|
||||||
|
|
|
@ -13,10 +13,10 @@ namespace Sapphire::World::Action
|
||||||
class ActionResult
|
class ActionResult
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ActionResult( Entity::CharaPtr target, uint64_t delayMs );
|
explicit ActionResult( Entity::CharaPtr target );
|
||||||
|
|
||||||
void damage( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
void damage( uint32_t amount, Common::CalcResultType hitType, uint8_t hitEffect, Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
||||||
void heal( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
void heal( uint32_t amount, Common::CalcResultType hitType, uint8_t hitEffect, Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
||||||
void restoreMP( uint32_t amount, Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
void restoreMP( uint32_t amount, Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
||||||
void startCombo( uint16_t actionId );
|
void startCombo( uint16_t actionId );
|
||||||
void comboSucceed();
|
void comboSucceed();
|
||||||
|
@ -30,16 +30,12 @@ namespace Sapphire::World::Action
|
||||||
|
|
||||||
Entity::CharaPtr getTarget() const;
|
Entity::CharaPtr getTarget() const;
|
||||||
|
|
||||||
uint64_t getDelay();
|
|
||||||
|
|
||||||
const Common::CalcResultParam& getCalcResultParam() const;
|
const Common::CalcResultParam& getCalcResultParam() const;
|
||||||
const Sapphire::StatusEffect::StatusEffectPtr getStatusEffect() const;
|
const Sapphire::StatusEffect::StatusEffectPtr getStatusEffect() const;
|
||||||
|
|
||||||
void execute();
|
void execute();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t m_delayMs;
|
|
||||||
|
|
||||||
Entity::CharaPtr m_target;
|
Entity::CharaPtr m_target;
|
||||||
|
|
||||||
Common::CalcResultParam m_result;
|
Common::CalcResultParam m_result;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <Util/Util.h>
|
#include <Util/Util.h>
|
||||||
#include <Util/UtilMath.h>
|
#include <Util/UtilMath.h>
|
||||||
|
#include <Exd/ExdData.h>
|
||||||
|
|
||||||
#include <Logging/Logger.h>
|
#include <Logging/Logger.h>
|
||||||
#include <Manager/TerritoryMgr.h>
|
#include <Manager/TerritoryMgr.h>
|
||||||
|
@ -46,44 +47,48 @@ void ActionResultBuilder::addResultToActor( Entity::CharaPtr& chara, ActionResul
|
||||||
it->second.push_back( std::move( result ) );
|
it->second.push_back( std::move( result ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResultBuilder::heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag )
|
void ActionResultBuilder::heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount, Common::CalcResultType hitType, Common::ActionResultFlag flag )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( healingTarget, 0 );
|
ActionResultPtr nextResult = make_ActionResult( healingTarget );
|
||||||
nextResult->heal( amount, severity, flag );
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||||
|
auto actionData = exdData.getRow< Excel::Action >( m_actionId );
|
||||||
|
nextResult->heal( amount, hitType, std::abs( actionData->data().AttackType ), flag );
|
||||||
addResultToActor( effectTarget, nextResult );
|
addResultToActor( effectTarget, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResultBuilder::restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& restoringTarget, uint32_t amount, Common::ActionResultFlag flag )
|
void ActionResultBuilder::restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& restoringTarget, uint32_t amount, Common::ActionResultFlag flag )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( restoringTarget, 0 ); // restore mp source actor
|
ActionResultPtr nextResult = make_ActionResult( restoringTarget ); // restore mp source actor
|
||||||
nextResult->restoreMP( amount, flag );
|
nextResult->restoreMP( amount, flag );
|
||||||
addResultToActor( target, nextResult );
|
addResultToActor( target, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResultBuilder::damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag )
|
void ActionResultBuilder::damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, Common::CalcResultType hitType, Common::ActionResultFlag flag )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( damagingTarget, 0 );
|
ActionResultPtr nextResult = make_ActionResult( damagingTarget );
|
||||||
nextResult->damage( amount, severity, flag );
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||||
|
auto actionData = exdData.getRow< Excel::Action >( m_actionId );
|
||||||
|
nextResult->damage( amount, hitType, std::abs( actionData->data().AttackType ), flag );
|
||||||
addResultToActor( damagingTarget, nextResult );
|
addResultToActor( damagingTarget, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResultBuilder::startCombo( Entity::CharaPtr& target, uint16_t actionId )
|
void ActionResultBuilder::startCombo( Entity::CharaPtr& target, uint16_t actionId )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( target, 0 );
|
ActionResultPtr nextResult = make_ActionResult( target );
|
||||||
nextResult->startCombo( actionId );
|
nextResult->startCombo( actionId );
|
||||||
addResultToActor( target, nextResult );
|
addResultToActor( target, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResultBuilder::comboSucceed( Entity::CharaPtr& target )
|
void ActionResultBuilder::comboSucceed( Entity::CharaPtr& target )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( target, 0 );
|
ActionResultPtr nextResult = make_ActionResult( target );
|
||||||
nextResult->comboSucceed();
|
nextResult->comboSucceed();
|
||||||
addResultToActor( target, nextResult );
|
addResultToActor( target, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride )
|
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( target, 0 );
|
ActionResultPtr nextResult = make_ActionResult( target );
|
||||||
nextResult->applyStatusEffect( statusId, duration, *m_sourceChara, param, shouldOverride );
|
nextResult->applyStatusEffect( statusId, duration, *m_sourceChara, param, shouldOverride );
|
||||||
addResultToActor( target, nextResult );
|
addResultToActor( target, nextResult );
|
||||||
}
|
}
|
||||||
|
@ -91,14 +96,14 @@ void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t
|
||||||
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
|
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||||
std::vector< World::Action::StatusModifier > modifiers, uint32_t flag, bool shouldOverride )
|
std::vector< World::Action::StatusModifier > modifiers, uint32_t flag, bool shouldOverride )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( target, 0 );
|
ActionResultPtr nextResult = make_ActionResult( target );
|
||||||
nextResult->applyStatusEffect( statusId, duration, *m_sourceChara, param, modifiers, flag, shouldOverride );
|
nextResult->applyStatusEffect( statusId, duration, *m_sourceChara, param, modifiers, flag, shouldOverride );
|
||||||
addResultToActor( target, nextResult );
|
addResultToActor( target, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResultBuilder::applyStatusEffectSelf( uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride )
|
void ActionResultBuilder::applyStatusEffectSelf( uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( m_sourceChara, 0 );
|
ActionResultPtr nextResult = make_ActionResult( m_sourceChara );
|
||||||
nextResult->applyStatusEffectSelf( statusId, duration, param, shouldOverride );
|
nextResult->applyStatusEffectSelf( statusId, duration, param, shouldOverride );
|
||||||
addResultToActor( m_sourceChara, nextResult );
|
addResultToActor( m_sourceChara, nextResult );
|
||||||
}
|
}
|
||||||
|
@ -106,14 +111,14 @@ void ActionResultBuilder::applyStatusEffectSelf( uint16_t statusId, uint32_t dur
|
||||||
void ActionResultBuilder::applyStatusEffectSelf( uint16_t statusId, uint32_t duration, uint8_t param, std::vector< World::Action::StatusModifier > modifiers,
|
void ActionResultBuilder::applyStatusEffectSelf( uint16_t statusId, uint32_t duration, uint8_t param, std::vector< World::Action::StatusModifier > modifiers,
|
||||||
uint32_t flag, bool shouldOverride )
|
uint32_t flag, bool shouldOverride )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( m_sourceChara, 0 );
|
ActionResultPtr nextResult = make_ActionResult( m_sourceChara );
|
||||||
nextResult->applyStatusEffectSelf( statusId, duration, param, modifiers, flag, shouldOverride );
|
nextResult->applyStatusEffectSelf( statusId, duration, param, modifiers, flag, shouldOverride );
|
||||||
addResultToActor( m_sourceChara, nextResult );
|
addResultToActor( m_sourceChara, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResultBuilder::mount( Entity::CharaPtr& target, uint16_t mountId )
|
void ActionResultBuilder::mount( Entity::CharaPtr& target, uint16_t mountId )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( target, 0 );
|
ActionResultPtr nextResult = make_ActionResult( target );
|
||||||
nextResult->mount( mountId );
|
nextResult->mount( mountId );
|
||||||
addResultToActor( target, nextResult );
|
addResultToActor( target, nextResult );
|
||||||
}
|
}
|
||||||
|
@ -140,19 +145,17 @@ std::shared_ptr< FFXIVPacketBase > ActionResultBuilder::createActionResultPacket
|
||||||
|
|
||||||
if( targetCount > 1 ) // use AoeEffect packets
|
if( targetCount > 1 ) // use AoeEffect packets
|
||||||
{
|
{
|
||||||
auto actionResult = std::make_shared< EffectPacket >( m_sourceChara->getId(), targetList[ 0 ]->getId(), m_actionId );
|
auto actionResult = makeEffectPacket( m_sourceChara->getId(), targetList[ 0 ]->getId(), m_actionId );
|
||||||
actionResult->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) );
|
actionResult->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) );
|
||||||
actionResult->setRequestId( m_requestId );
|
actionResult->setRequestId( m_requestId );
|
||||||
actionResult->setResultId( m_resultId );
|
actionResult->setResultId( m_resultId );
|
||||||
|
|
||||||
uint8_t targetIndex = 0;
|
uint8_t targetIndex = 0;
|
||||||
for( auto it = m_actorResultsMap.begin(); it != m_actorResultsMap.end(); ++it )
|
for( auto& [ actor, actorResultList ] : m_actorResultsMap )
|
||||||
{
|
{
|
||||||
// get all effect results for an actor
|
|
||||||
auto actorResultList = it->second;
|
|
||||||
|
|
||||||
if( it->first )
|
if( actor )
|
||||||
taskMgr.queueTask( World::makeActionIntegrityTask( m_resultId, it->first, actorResultList, 300 ) );
|
taskMgr.queueTask( World::makeActionIntegrityTask( m_resultId, actor, actorResultList, 300 ) );
|
||||||
|
|
||||||
for( auto& result : actorResultList )
|
for( auto& result : actorResultList )
|
||||||
{
|
{
|
||||||
|
@ -173,23 +176,21 @@ std::shared_ptr< FFXIVPacketBase > ActionResultBuilder::createActionResultPacket
|
||||||
else // use Effect for single target
|
else // use Effect for single target
|
||||||
{
|
{
|
||||||
uint32_t mainTargetId = targetList.empty() ? m_sourceChara->getId() : targetList[ 0 ]->getId();
|
uint32_t mainTargetId = targetList.empty() ? m_sourceChara->getId() : targetList[ 0 ]->getId();
|
||||||
auto actionResult = std::make_shared< EffectPacket1 >( m_sourceChara->getId(), mainTargetId, m_actionId );
|
auto actionResult = makeEffectPacket1( m_sourceChara->getId(), mainTargetId, m_actionId );
|
||||||
actionResult->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) );
|
actionResult->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) );
|
||||||
actionResult->setRequestId( m_requestId );
|
actionResult->setRequestId( m_requestId );
|
||||||
actionResult->setResultId( m_resultId );
|
actionResult->setResultId( m_resultId );
|
||||||
|
|
||||||
for( auto it = m_actorResultsMap.begin(); it != m_actorResultsMap.end(); ++it )
|
for( auto& [ actor, actorResultList ] : m_actorResultsMap )
|
||||||
{
|
{
|
||||||
// get all effect results for an actor
|
if( actor )
|
||||||
auto actorResultList = it->second;
|
taskMgr.queueTask( World::makeActionIntegrityTask( m_resultId, actor, actorResultList, 300 ) );
|
||||||
|
|
||||||
if( it->first )
|
|
||||||
taskMgr.queueTask( World::makeActionIntegrityTask( m_resultId, it->first, actorResultList, 300 ) );
|
|
||||||
|
|
||||||
for( auto& result : actorResultList )
|
for( auto& result : actorResultList )
|
||||||
{
|
{
|
||||||
auto effect = result->getCalcResultParam();
|
auto effect = result->getCalcResultParam();
|
||||||
if( result->getTarget() == m_sourceChara && result->getCalcResultParam().Type != Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS_ME )
|
if( result->getTarget() == m_sourceChara &&
|
||||||
|
result->getCalcResultParam().Type != Common::CalcResultType::TypeSetStatusMe )
|
||||||
actionResult->addSourceEffect( effect );
|
actionResult->addSourceEffect( effect );
|
||||||
else
|
else
|
||||||
actionResult->addTargetEffect( effect );
|
actionResult->addTargetEffect( effect );
|
||||||
|
|
|
@ -12,14 +12,14 @@ namespace Sapphire::World::Action
|
||||||
ActionResultBuilder( Entity::CharaPtr source, uint32_t actionId, uint32_t resultId, uint16_t requestId );
|
ActionResultBuilder( Entity::CharaPtr source, uint32_t actionId, uint32_t resultId, uint16_t requestId );
|
||||||
|
|
||||||
void heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount,
|
void heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount,
|
||||||
Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalHeal,
|
Common::CalcResultType hitType = Common::CalcResultType::TypeRecoverMp,
|
||||||
Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
||||||
|
|
||||||
void restoreMP( Entity::CharaPtr& effectTarget, Entity::CharaPtr& restoringTarget, uint32_t amount,
|
void restoreMP( Entity::CharaPtr& effectTarget, Entity::CharaPtr& restoringTarget, uint32_t amount,
|
||||||
Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
||||||
|
|
||||||
void damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount,
|
void damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount,
|
||||||
Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalDamage,
|
Common::CalcResultType hitType = Common::CalcResultType::TypeDamageHp,
|
||||||
Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
||||||
|
|
||||||
void startCombo( Entity::CharaPtr& target, uint16_t actionId );
|
void startCombo( Entity::CharaPtr& target, uint16_t actionId );
|
||||||
|
|
|
@ -78,7 +78,7 @@ void ItemAction::interrupt()
|
||||||
void ItemAction::handleVFXItem()
|
void ItemAction::handleVFXItem()
|
||||||
{
|
{
|
||||||
Common::CalcResultParam effect{};
|
Common::CalcResultParam effect{};
|
||||||
effect.Type = Common::ActionEffectType::CALC_RESULT_TYPE_CHECK_BARRIER;
|
effect.Type = Common::CalcResultType::TypeCheckBarrier;
|
||||||
effect.Value = m_itemAction->data().Calcu0Arg[ 0 ];
|
effect.Value = m_itemAction->data().Calcu0Arg[ 0 ];
|
||||||
|
|
||||||
auto effectPacket = std::make_shared< EffectPacket >( getSourceChara()->getId(), getSourceChara()->getId(), getId() );
|
auto effectPacket = std::make_shared< EffectPacket >( getSourceChara()->getId(), getSourceChara()->getId(), getId() );
|
||||||
|
|
|
@ -46,7 +46,15 @@
|
||||||
|
|
||||||
#include <Action/Action.h>
|
#include <Action/Action.h>
|
||||||
#include <AI/GambitRule.h>
|
#include <AI/GambitRule.h>
|
||||||
|
#include <AI/GambitPack.h>
|
||||||
#include <AI/GambitTargetCondition.h>
|
#include <AI/GambitTargetCondition.h>
|
||||||
|
#include <AI/Fsm/StateMachine.h>
|
||||||
|
#include <AI/Fsm/Condition.h>
|
||||||
|
#include <AI/Fsm/StateIdle.h>
|
||||||
|
#include <AI/Fsm/StateRoam.h>
|
||||||
|
#include <AI/Fsm/StateCombat.h>
|
||||||
|
#include <AI/Fsm/StateRetreat.h>
|
||||||
|
#include <AI/Fsm/StateDead.h>
|
||||||
|
|
||||||
using namespace Sapphire;
|
using namespace Sapphire;
|
||||||
using namespace Sapphire::World;
|
using namespace Sapphire::World;
|
||||||
|
@ -88,8 +96,7 @@ BNpc::BNpc( uint32_t id, std::shared_ptr< Common::BNPCInstanceObject > pInfo, co
|
||||||
m_flags = 0;
|
m_flags = 0;
|
||||||
m_rank = pInfo->BNPCRankId;
|
m_rank = pInfo->BNPCRankId;
|
||||||
|
|
||||||
if( pInfo->WanderingRange == 0 || pInfo->BoundInstanceID != 0 )
|
|
||||||
setFlag( Immobile );
|
|
||||||
|
|
||||||
// Striking Dummy
|
// Striking Dummy
|
||||||
if( pInfo->NameId == 541 )
|
if( pInfo->NameId == 541 )
|
||||||
|
@ -107,6 +114,9 @@ BNpc::BNpc( uint32_t id, std::shared_ptr< Common::BNPCInstanceObject > pInfo, co
|
||||||
m_modelChara = bNpcBaseData->data().Model;
|
m_modelChara = bNpcBaseData->data().Model;
|
||||||
m_enemyType = bNpcBaseData->data().Battalion;
|
m_enemyType = bNpcBaseData->data().Battalion;
|
||||||
|
|
||||||
|
if( pInfo->WanderingRange == 0 || pInfo->BoundInstanceID != 0 || m_enemyType == 0 )
|
||||||
|
setFlag( Immobile );
|
||||||
|
|
||||||
m_class = ClassJob::Gladiator;
|
m_class = ClassJob::Gladiator;
|
||||||
|
|
||||||
m_territoryTypeId = zone.getTerritoryTypeId();
|
m_territoryTypeId = zone.getTerritoryTypeId();
|
||||||
|
@ -324,7 +334,7 @@ uint32_t BNpc::getBNpcNameId() const
|
||||||
|
|
||||||
void BNpc::spawn( PlayerPtr pTarget )
|
void BNpc::spawn( PlayerPtr pTarget )
|
||||||
{
|
{
|
||||||
m_lastRoamTargetReached = Common::Util::getTimeSeconds();
|
m_lastRoamTargetReachedTime = Common::Util::getTimeSeconds();
|
||||||
|
|
||||||
auto& server = Common::Service< World::WorldServer >::ref();
|
auto& server = Common::Service< World::WorldServer >::ref();
|
||||||
server.queueForPlayer( pTarget->getCharacterId(), std::make_shared< NpcSpawnPacket >( *this, *pTarget ) );
|
server.queueForPlayer( pTarget->getCharacterId(), std::make_shared< NpcSpawnPacket >( *this, *pTarget ) );
|
||||||
|
@ -589,6 +599,11 @@ void BNpc::aggro( const Sapphire::Entity::CharaPtr& pChara )
|
||||||
auto& pRNGMgr = Common::Service< World::Manager::RNGMgr >::ref();
|
auto& pRNGMgr = Common::Service< World::Manager::RNGMgr >::ref();
|
||||||
auto variation = static_cast< uint32_t >( pRNGMgr.getRandGenerator< float >( 500, 1000 ).next() );
|
auto variation = static_cast< uint32_t >( pRNGMgr.getRandGenerator< float >( 500, 1000 ).next() );
|
||||||
|
|
||||||
|
if( m_pGambitPack && m_pGambitPack->getAsTimeLine() )
|
||||||
|
{
|
||||||
|
m_pGambitPack->getAsTimeLine()->start();
|
||||||
|
}
|
||||||
|
|
||||||
m_lastAttack = Common::Util::getTimeMs() + variation;
|
m_lastAttack = Common::Util::getTimeMs() + variation;
|
||||||
|
|
||||||
setStance( Stance::Active );
|
setStance( Stance::Active );
|
||||||
|
@ -638,165 +653,8 @@ void BNpc::onTick()
|
||||||
|
|
||||||
void BNpc::update( uint64_t tickCount )
|
void BNpc::update( uint64_t tickCount )
|
||||||
{
|
{
|
||||||
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
|
|
||||||
auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() );
|
|
||||||
|
|
||||||
const uint8_t maxDistanceToOrigin = 40;
|
|
||||||
const uint32_t roamTick = 20;
|
|
||||||
|
|
||||||
auto pNaviProvider = pZone->getNaviProvider();
|
|
||||||
|
|
||||||
if( !pNaviProvider )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( !checkAction() )
|
|
||||||
processGambits( tickCount );
|
|
||||||
|
|
||||||
switch( m_state )
|
|
||||||
{
|
|
||||||
case BNpcState::Dead:
|
|
||||||
case BNpcState::JustDied:
|
|
||||||
return;
|
|
||||||
|
|
||||||
case BNpcState::Retreat:
|
|
||||||
{
|
|
||||||
setInvincibilityType( InvincibilityType::InvincibilityIgnoreDamage );
|
|
||||||
|
|
||||||
if( pNaviProvider )
|
|
||||||
pNaviProvider->setMoveTarget( *this, m_spawnPos );
|
|
||||||
|
|
||||||
if( moveTo( m_spawnPos ) )
|
|
||||||
{
|
|
||||||
setInvincibilityType( InvincibilityType::InvincibilityNone );
|
|
||||||
|
|
||||||
// retail doesn't seem to roam straight after retreating
|
|
||||||
// todo: perhaps requires more investigation?
|
|
||||||
m_lastRoamTargetReached = Common::Util::getTimeSeconds();
|
|
||||||
|
|
||||||
// resetHp
|
|
||||||
setHp( getMaxHp() );
|
|
||||||
|
|
||||||
m_state = BNpcState::Idle;
|
|
||||||
setOwner( nullptr );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BNpcState::Roaming:
|
|
||||||
{
|
|
||||||
|
|
||||||
if( pNaviProvider )
|
|
||||||
pNaviProvider->setMoveTarget( *this, m_roamPos );
|
|
||||||
|
|
||||||
if( moveTo( m_roamPos ) )
|
|
||||||
{
|
|
||||||
m_lastRoamTargetReached = Common::Util::getTimeSeconds();
|
|
||||||
m_state = BNpcState::Idle;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkAggro();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BNpcState::Idle:
|
|
||||||
{
|
|
||||||
auto pHatedActor = hateListGetHighest();
|
|
||||||
if( pHatedActor )
|
|
||||||
aggro( pHatedActor );
|
|
||||||
|
|
||||||
if( pNaviProvider->syncPosToChara( *this ) )
|
|
||||||
sendPositionUpdate();
|
|
||||||
|
|
||||||
if( !hasFlag( Immobile ) && ( Common::Util::getTimeSeconds() - m_lastRoamTargetReached > roamTick ) )
|
|
||||||
{
|
|
||||||
|
|
||||||
if( !pNaviProvider )
|
|
||||||
{
|
|
||||||
m_lastRoamTargetReached = Common::Util::getTimeSeconds();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if( m_pInfo->WanderingRange != 0 && getEnemyType() != 0 )
|
|
||||||
{
|
|
||||||
m_roamPos = pNaviProvider->findRandomPositionInCircle( m_spawnPos, m_pInfo->WanderingRange );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_roamPos = m_spawnPos;
|
|
||||||
}
|
|
||||||
m_state = BNpcState::Roaming;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkAggro();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case BNpcState::Combat:
|
|
||||||
{
|
|
||||||
auto pHatedActor = hateListGetHighest();
|
|
||||||
if( !pHatedActor )
|
|
||||||
return;
|
|
||||||
|
|
||||||
pNaviProvider->updateAgentParameters( *this );
|
|
||||||
|
|
||||||
auto distanceOrig = Common::Util::distance( getPos(), m_spawnPos );
|
|
||||||
|
|
||||||
if( pHatedActor && !pHatedActor->isAlive() )
|
|
||||||
{
|
|
||||||
hateListRemove( pHatedActor );
|
|
||||||
pHatedActor = hateListGetHighest();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pHatedActor )
|
|
||||||
{
|
|
||||||
auto distance = Common::Util::distance( getPos(), pHatedActor->getPos() );
|
|
||||||
|
|
||||||
if( !hasFlag( NoDeaggro ) && ( ( distanceOrig > maxDistanceToOrigin ) || distance > 30.0f ) )
|
|
||||||
{
|
|
||||||
hateListClear();
|
|
||||||
changeTarget( INVALID_GAME_OBJECT_ID64 );
|
|
||||||
setStance( Stance::Passive );
|
|
||||||
setOwner( nullptr );
|
|
||||||
m_state = BNpcState::Retreat;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( distance > ( getNaviTargetReachedDistance() + pHatedActor->getRadius() ) )
|
|
||||||
{
|
|
||||||
if( hasFlag( Immobile ) )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if( pNaviProvider )
|
|
||||||
pNaviProvider->setMoveTarget( *this, pHatedActor->getPos() );
|
|
||||||
|
|
||||||
moveTo( *pHatedActor );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pNaviProvider->syncPosToChara( *this ) )
|
|
||||||
sendPositionUpdate();
|
|
||||||
|
|
||||||
if( distance < ( getNaviTargetReachedDistance() + pHatedActor->getRadius() ) )
|
|
||||||
{
|
|
||||||
if( !hasFlag( TurningDisabled ) && face( pHatedActor->getPos() ) )
|
|
||||||
sendPositionUpdate();
|
|
||||||
|
|
||||||
// in combat range. ATTACK!
|
|
||||||
autoAttack( pHatedActor );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
changeTarget( INVALID_GAME_OBJECT_ID64 );
|
|
||||||
setStance( Stance::Passive );
|
|
||||||
//setOwner( nullptr );
|
|
||||||
m_state = BNpcState::Retreat;
|
|
||||||
pNaviProvider->updateAgentParameters( *this );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Chara::update( tickCount );
|
Chara::update( tickCount );
|
||||||
|
m_fsm->update( *this, tickCount );
|
||||||
}
|
}
|
||||||
|
|
||||||
void BNpc::restHp()
|
void BNpc::restHp()
|
||||||
|
@ -1054,31 +912,98 @@ void BNpc::init()
|
||||||
m_maxHp = Math::CalcStats::calculateMaxHp( *getAsChara() );
|
m_maxHp = Math::CalcStats::calculateMaxHp( *getAsChara() );
|
||||||
m_hp = m_maxHp;
|
m_hp = m_maxHp;
|
||||||
|
|
||||||
|
m_lastRoamTargetReachedTime = Common::Util::getTimeSeconds();
|
||||||
|
|
||||||
//setup a test gambit
|
//setup a test gambit
|
||||||
auto testGambitRule = AI::make_GambitRule( AI::make_TopHateTargetCondition(), Action::make_Action( getAsChara(), 88, 0 ), 5000 );
|
auto testGambitRule = AI::make_GambitRule( AI::make_TopHateTargetCondition(), Action::make_Action( getAsChara(), 88, 0 ), 5000 );
|
||||||
auto testGambitRule1 = AI::make_GambitRule( AI::make_HPSelfPctLessThan( 50 ), Action::make_Action( getAsChara(), 120, 0 ), 5000 );
|
auto testGambitRule1 = AI::make_GambitRule( AI::make_HPSelfPctLessThanTargetCondition( 50 ), Action::make_Action( getAsChara(), 120, 0 ), 5000 );
|
||||||
|
/*
|
||||||
|
auto gambitPack = AI::make_GambitRuleSetPack();
|
||||||
|
gambitPack->addRule( AI::make_TopHateTargetCondition(), Action::make_Action( getAsChara(), 88, 0 ), 5000 );
|
||||||
|
gambitPack->addRule( AI::make_HPSelfPctLessThanTargetCondition( 50 ), Action::make_Action( getAsChara(), 120, 0 ), 10000 );
|
||||||
|
m_pGambitPack = gambitPack;
|
||||||
|
*/
|
||||||
|
|
||||||
m_gambits.push_back( testGambitRule );
|
auto gambitPack = AI::make_GambitTimeLinePack( -1 );
|
||||||
m_gambits.push_back( testGambitRule1 );
|
gambitPack->addTimeLine( AI::make_TopHateTargetCondition(), Action::make_Action( getAsChara(), 88, 0 ), 2 );
|
||||||
|
gambitPack->addTimeLine( AI::make_TopHateTargetCondition(), Action::make_Action( getAsChara(), 89, 0 ), 4 );
|
||||||
|
gambitPack->addTimeLine( AI::make_TopHateTargetCondition(), Action::make_Action( getAsChara(), 90, 0 ), 6 );
|
||||||
|
gambitPack->addTimeLine( AI::make_TopHateTargetCondition(), Action::make_Action( getAsChara(), 91, 0 ), 8 );
|
||||||
|
gambitPack->addTimeLine( AI::make_TopHateTargetCondition(), Action::make_Action( getAsChara(), 92, 0 ), 10 );
|
||||||
|
gambitPack->addTimeLine( AI::make_TopHateTargetCondition(), Action::make_Action( getAsChara(), 81, 0 ), 12 );
|
||||||
|
gambitPack->addTimeLine( AI::make_TopHateTargetCondition(), Action::make_Action( getAsChara(), 82, 0 ), 14 );
|
||||||
|
m_pGambitPack = gambitPack;
|
||||||
|
|
||||||
|
using namespace AI::Fsm;
|
||||||
|
m_fsm = make_StateMachine();
|
||||||
|
auto stateIdle = make_StateIdle();
|
||||||
|
auto stateCombat = make_StateCombat();
|
||||||
|
auto stateDead = make_StateDead();
|
||||||
|
if( !hasFlag( Immobile ) )
|
||||||
|
{
|
||||||
|
auto stateRoam = make_StateRoam();
|
||||||
|
stateIdle->addTransition( stateRoam, make_RoamNextTimeReachedCondition() );
|
||||||
|
stateRoam->addTransition( stateIdle, make_RoamTargetReachedCondition() );
|
||||||
|
stateRoam->addTransition( stateCombat, make_HateListHasEntriesCondition() );
|
||||||
|
stateRoam->addTransition( stateDead, make_IsDeadCondition() );
|
||||||
|
m_fsm->addState( stateRoam );
|
||||||
|
}
|
||||||
|
stateIdle->addTransition( stateCombat, make_HateListHasEntriesCondition() );
|
||||||
|
stateCombat->addTransition( stateIdle, make_HateListEmptyCondition() );
|
||||||
|
stateIdle->addTransition( stateDead, make_IsDeadCondition() );
|
||||||
|
stateCombat->addTransition( stateDead, make_IsDeadCondition() );
|
||||||
|
m_fsm->addState( stateIdle );
|
||||||
|
if( !hasFlag( NoDeaggro ) )
|
||||||
|
{
|
||||||
|
auto stateRetreat = make_StateRetreat();
|
||||||
|
stateCombat->addTransition( stateRetreat, make_SpawnPointDistanceGtMaxDistanceCondition() );
|
||||||
|
stateRetreat->addTransition( stateIdle, make_RoamTargetReachedCondition() );
|
||||||
|
}
|
||||||
|
m_fsm->setCurrentState( stateIdle );
|
||||||
}
|
}
|
||||||
|
|
||||||
void BNpc::processGambits( uint64_t tickCount )
|
void BNpc::processGambits( uint64_t tickCount )
|
||||||
{
|
{
|
||||||
auto& actionMgr = Common::Service< World::Manager::ActionMgr >::ref();
|
m_tp = 1000;
|
||||||
for( auto& gambitRule : m_gambits )
|
m_pGambitPack->update( *this, tickCount );
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t BNpc::getLastRoamTargetReachedTime() const
|
||||||
{
|
{
|
||||||
if( !gambitRule->isEnabled() )
|
return m_lastRoamTargetReachedTime;
|
||||||
continue;
|
}
|
||||||
|
|
||||||
if( ( tickCount - gambitRule->getLastExecutionMs() ) > gambitRule->getCoolDown() )
|
void BNpc::setLastRoamTargetReachedTime( uint32_t time )
|
||||||
{
|
{
|
||||||
if( !gambitRule->getGambitTargetCondition()->isConditionMet( *this ) )
|
m_lastRoamTargetReachedTime = time;
|
||||||
continue;
|
|
||||||
|
|
||||||
gambitRule->setLastExecutionMs( tickCount );
|
|
||||||
actionMgr.handleTargetedAction( *this, gambitRule->getActionPtr()->getId(), gambitRule->getGambitTargetCondition()->getTarget()->getId(), 0 );
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr< Common::BNPCInstanceObject > BNpc::getInstanceObjectInfo() const
|
||||||
|
{
|
||||||
|
return m_pInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BNpc::setRoamTargetReached( bool reached )
|
||||||
|
{
|
||||||
|
m_roamTargetReached = reached;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BNpc::isRoamTargetReached() const
|
||||||
|
{
|
||||||
|
return m_roamTargetReached;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BNpc::setRoamTargetPos( const FFXIVARR_POSITION3& targetPos )
|
||||||
|
{
|
||||||
|
m_roamPos = targetPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Common::FFXIVARR_POSITION3& BNpc::getRoamTargetPos() const
|
||||||
|
{
|
||||||
|
return m_roamPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Common::FFXIVARR_POSITION3& BNpc::getSpawnPos() const
|
||||||
|
{
|
||||||
|
return m_spawnPos;
|
||||||
}
|
}
|
|
@ -151,6 +151,19 @@ namespace Sapphire::Entity
|
||||||
|
|
||||||
void processGambits( uint64_t tickCount );
|
void processGambits( uint64_t tickCount );
|
||||||
|
|
||||||
|
uint32_t getLastRoamTargetReachedTime() const;
|
||||||
|
void setLastRoamTargetReachedTime( uint32_t time );
|
||||||
|
|
||||||
|
std::shared_ptr< Common::BNPCInstanceObject > getInstanceObjectInfo() const;
|
||||||
|
|
||||||
|
void setRoamTargetReached( bool reached );
|
||||||
|
bool isRoamTargetReached() const;
|
||||||
|
|
||||||
|
void setRoamTargetPos( const Common::FFXIVARR_POSITION3& targetPos );
|
||||||
|
|
||||||
|
const Common::FFXIVARR_POSITION3& getRoamTargetPos() const;
|
||||||
|
const Common::FFXIVARR_POSITION3& getSpawnPos() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t m_bNpcBaseId;
|
uint32_t m_bNpcBaseId;
|
||||||
uint32_t m_bNpcNameId;
|
uint32_t m_bNpcNameId;
|
||||||
|
@ -178,7 +191,8 @@ namespace Sapphire::Entity
|
||||||
std::shared_ptr< Common::BNPCInstanceObject > m_pInfo;
|
std::shared_ptr< Common::BNPCInstanceObject > m_pInfo;
|
||||||
|
|
||||||
uint32_t m_timeOfDeath;
|
uint32_t m_timeOfDeath;
|
||||||
uint32_t m_lastRoamTargetReached;
|
uint32_t m_lastRoamTargetReachedTime;
|
||||||
|
bool m_roamTargetReached{ false };
|
||||||
|
|
||||||
Common::FFXIVARR_POSITION3 m_spawnPos;
|
Common::FFXIVARR_POSITION3 m_spawnPos;
|
||||||
Common::FFXIVARR_POSITION3 m_roamPos;
|
Common::FFXIVARR_POSITION3 m_roamPos;
|
||||||
|
@ -192,7 +206,9 @@ namespace Sapphire::Entity
|
||||||
Common::FFXIVARR_POSITION3 m_naviTarget;
|
Common::FFXIVARR_POSITION3 m_naviTarget;
|
||||||
|
|
||||||
CharaPtr m_pOwner;
|
CharaPtr m_pOwner;
|
||||||
std::vector< World::AI::GambitRulePtr > m_gambits;
|
World::AI::GambitPackPtr m_pGambitPack;
|
||||||
|
|
||||||
|
std::shared_ptr< World::AI::Fsm::StateMachine > m_fsm;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -475,8 +475,8 @@ void Chara::autoAttack( CharaPtr pTarget )
|
||||||
|
|
||||||
Common::CalcResultParam effectEntry{};
|
Common::CalcResultParam effectEntry{};
|
||||||
effectEntry.Value = static_cast< int16_t >( damage );
|
effectEntry.Value = static_cast< int16_t >( damage );
|
||||||
effectEntry.Type = ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP;
|
effectEntry.Type = CalcResultType::TypeDamageHp;
|
||||||
effectEntry.Arg0 = static_cast< uint8_t >( ActionHitSeverityType::NormalDamage );
|
effectEntry.Arg0 = 1;
|
||||||
effectEntry.Arg2 = 0x71;
|
effectEntry.Arg2 = 0x71;
|
||||||
effectPacket->addTargetEffect( effectEntry );
|
effectPacket->addTargetEffect( effectEntry );
|
||||||
|
|
||||||
|
@ -825,7 +825,7 @@ void Chara::onTick()
|
||||||
{
|
{
|
||||||
takeDamage( thisTickDmg );
|
takeDamage( thisTickDmg );
|
||||||
Network::Util::Packet::sendActorControl( getInRangePlayerIds( isPlayer() ), getId(), HPFloatingText, 0,
|
Network::Util::Packet::sendActorControl( getInRangePlayerIds( isPlayer() ), getId(), HPFloatingText, 0,
|
||||||
ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP, thisTickDmg );
|
CalcResultType::TypeDamageHp, thisTickDmg );
|
||||||
|
|
||||||
Network::Util::Packet::sendHudParam( *this );
|
Network::Util::Packet::sendHudParam( *this );
|
||||||
}
|
}
|
||||||
|
@ -834,7 +834,7 @@ void Chara::onTick()
|
||||||
{
|
{
|
||||||
heal( thisTickHeal );
|
heal( thisTickHeal );
|
||||||
Network::Util::Packet::sendActorControl( getInRangePlayerIds( isPlayer() ), getId(), HPFloatingText, 0,
|
Network::Util::Packet::sendActorControl( getInRangePlayerIds( isPlayer() ), getId(), HPFloatingText, 0,
|
||||||
ActionEffectType::CALC_RESULT_TYPE_RECOVER_HP, thisTickHeal );
|
CalcResultType::TypeRecoverMp, thisTickHeal );
|
||||||
|
|
||||||
Network::Util::Packet::sendHudParam( *this );
|
Network::Util::Packet::sendHudParam( *this );
|
||||||
}
|
}
|
||||||
|
|
|
@ -658,11 +658,6 @@ void Player::levelUp()
|
||||||
m_mp = getMaxMp();
|
m_mp = getMaxMp();
|
||||||
|
|
||||||
setLevel( getLevel() + 1 );
|
setLevel( getLevel() + 1 );
|
||||||
Network::Util::Packet::sendActorControl( getInRangePlayerIds( true ), getId(), LevelUpEffect, static_cast< uint8_t >( getClass() ), getLevel(), getLevel() - 1 );
|
|
||||||
|
|
||||||
auto& achvMgr = Common::Service< World::Manager::AchievementMgr >::ref();
|
|
||||||
achvMgr.progressAchievementByType< Common::Achievement::Type::Classjob >( *this, static_cast< uint32_t >( getClass() ) );
|
|
||||||
Service< World::Manager::MapMgr >::ref().updateQuests( *this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Player::getLevel() const
|
uint8_t Player::getLevel() const
|
||||||
|
@ -750,6 +745,11 @@ void Player::setLevel( uint8_t level )
|
||||||
Network::Util::Packet::sendBaseParams( *this );
|
Network::Util::Packet::sendBaseParams( *this );
|
||||||
Network::Util::Packet::sendHudParam( *this );
|
Network::Util::Packet::sendHudParam( *this );
|
||||||
Network::Util::Packet::sendStatusUpdate( *this );
|
Network::Util::Packet::sendStatusUpdate( *this );
|
||||||
|
Network::Util::Packet::sendActorControl( getInRangePlayerIds( true ), getId(), LevelUpEffect, static_cast< uint8_t >( getClass() ), getLevel(), getLevel() - 1 );
|
||||||
|
|
||||||
|
auto& achvMgr = Common::Service< World::Manager::AchievementMgr >::ref();
|
||||||
|
achvMgr.progressAchievementByType< Common::Achievement::Type::Classjob >( *this, static_cast< uint32_t >( getClass() ) );
|
||||||
|
Service< World::Manager::MapMgr >::ref().updateQuests( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::setLevelForClass( uint8_t level, Common::ClassJob classjob )
|
void Player::setLevelForClass( uint8_t level, Common::ClassJob classjob )
|
||||||
|
@ -1151,6 +1151,7 @@ const std::map< uint32_t, uint8_t >& Player::getActorIdToHateSlotMap()
|
||||||
void Player::onMobAggro( const BNpc& bnpc )
|
void Player::onMobAggro( const BNpc& bnpc )
|
||||||
{
|
{
|
||||||
hateListAdd( bnpc );
|
hateListAdd( bnpc );
|
||||||
|
setCondition( PlayerCondition::InCombat );
|
||||||
Network::Util::Packet::sendActorControl( *this, getId(), SetBattle, 1 );
|
Network::Util::Packet::sendActorControl( *this, getId(), SetBattle, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1158,8 +1159,11 @@ void Player::onMobDeaggro( const BNpc& bnpc )
|
||||||
{
|
{
|
||||||
hateListRemove( bnpc );
|
hateListRemove( bnpc );
|
||||||
if( m_actorIdTohateSlotMap.empty() )
|
if( m_actorIdTohateSlotMap.empty() )
|
||||||
|
{
|
||||||
|
removeCondition( PlayerCondition::InCombat );
|
||||||
Network::Util::Packet::sendActorControl( *this, getId(), SetBattle, 0 );
|
Network::Util::Packet::sendActorControl( *this, getId(), SetBattle, 0 );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Player::isLogin() const
|
bool Player::isLogin() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,7 @@ file( GLOB SERVER_SOURCE_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
Action/*.cpp
|
Action/*.cpp
|
||||||
Action/Job/*.cpp
|
Action/Job/*.cpp
|
||||||
AI/*.cpp
|
AI/*.cpp
|
||||||
|
AI/Fsm/*.cpp
|
||||||
ContentFinder/*.cpp
|
ContentFinder/*.cpp
|
||||||
DebugCommand/*.cpp
|
DebugCommand/*.cpp
|
||||||
Event/*.cpp
|
Event/*.cpp
|
||||||
|
|
|
@ -131,12 +131,11 @@ void World::ContentFinder::registerContentRequest( Entity::Player &player, uint3
|
||||||
void World::ContentFinder::registerRandomContentRequest( Entity::Player &player, uint32_t randomContentTypeId )
|
void World::ContentFinder::registerRandomContentRequest( Entity::Player &player, uint32_t randomContentTypeId )
|
||||||
{
|
{
|
||||||
auto& exdData = Service< Data::ExdData >::ref();
|
auto& exdData = Service< Data::ExdData >::ref();
|
||||||
auto contentListIds = exdData.getIdList< Excel::ContentFinderCondition >();
|
auto contentFinderList = exdData.getRows< Excel::ContentFinderCondition >();
|
||||||
std::vector< uint32_t > idList;
|
std::vector< uint32_t > idList;
|
||||||
|
|
||||||
for( auto id : contentListIds )
|
for( const auto& [ id, instanceContent ] : contentFinderList )
|
||||||
{
|
{
|
||||||
auto instanceContent = exdData.getRow< Excel::ContentFinderCondition >( id );
|
|
||||||
if( instanceContent->data().RandomContentType == randomContentTypeId )
|
if( instanceContent->data().RandomContentType == randomContentTypeId )
|
||||||
{
|
{
|
||||||
if( instanceContent->data().LevelMin <= player.getLevel() )
|
if( instanceContent->data().LevelMin <= player.getLevel() )
|
||||||
|
|
|
@ -51,9 +51,37 @@ namespace World::AI
|
||||||
{
|
{
|
||||||
TYPE_FORWARD( GambitTargetCondition );
|
TYPE_FORWARD( GambitTargetCondition );
|
||||||
TYPE_FORWARD( TopHateTargetCondition );
|
TYPE_FORWARD( TopHateTargetCondition );
|
||||||
TYPE_FORWARD( HPSelfPctLessThan );
|
TYPE_FORWARD( HPSelfPctLessThanTargetCondition );
|
||||||
|
|
||||||
TYPE_FORWARD( GambitRule );
|
TYPE_FORWARD( GambitRule );
|
||||||
|
TYPE_FORWARD( GambitPack );
|
||||||
|
TYPE_FORWARD( GambitTimeLinePack );
|
||||||
|
TYPE_FORWARD( GambitRuleSetPack );
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace World::AI::Fsm
|
||||||
|
{
|
||||||
|
|
||||||
|
TYPE_FORWARD( Condition );
|
||||||
|
TYPE_FORWARD( State );
|
||||||
|
TYPE_FORWARD( Transition );
|
||||||
|
TYPE_FORWARD( StateMachine );
|
||||||
|
|
||||||
|
TYPE_FORWARD( StateIdle );
|
||||||
|
TYPE_FORWARD( StateRoam );
|
||||||
|
TYPE_FORWARD( StateCombat );
|
||||||
|
TYPE_FORWARD( StateRetreat );
|
||||||
|
TYPE_FORWARD( StateDead );
|
||||||
|
|
||||||
|
TYPE_FORWARD( RoamNextTimeReachedCondition );
|
||||||
|
TYPE_FORWARD( RoamTargetReachedCondition );
|
||||||
|
TYPE_FORWARD( HateListEmptyCondition );
|
||||||
|
TYPE_FORWARD( HateListHasEntriesCondition );
|
||||||
|
TYPE_FORWARD( SpawnPointDistanceGtMaxDistanceCondition );
|
||||||
|
TYPE_FORWARD( IsDeadCondition );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Inventory
|
namespace Inventory
|
||||||
|
|
|
@ -14,12 +14,10 @@ using namespace Sapphire::World::Manager;
|
||||||
bool AchievementMgr::cacheAchievements()
|
bool AchievementMgr::cacheAchievements()
|
||||||
{
|
{
|
||||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||||
auto idList = exdData.getIdList< Excel::Achievement >();
|
auto achvDat = exdData.getRows< Excel::Achievement >();
|
||||||
|
|
||||||
for( auto id : idList )
|
for( const auto& [ id, achvExdData ] : achvDat )
|
||||||
{
|
{
|
||||||
auto achvExdData = exdData.getRow< Excel::Achievement >( id );
|
|
||||||
|
|
||||||
uint32_t key = achvExdData->data().ConditionType;
|
uint32_t key = achvExdData->data().ConditionType;
|
||||||
auto achvType = static_cast< Common::Achievement::Type >( key );
|
auto achvType = static_cast< Common::Achievement::Type >( key );
|
||||||
|
|
||||||
|
|
|
@ -534,8 +534,8 @@ void DebugCommandMgr::add( char* data, Entity::Player& player, std::shared_ptr<
|
||||||
|
|
||||||
Common::CalcResultParam entry{};
|
Common::CalcResultParam entry{};
|
||||||
entry.Value = static_cast< int16_t >( param1 );
|
entry.Value = static_cast< int16_t >( param1 );
|
||||||
entry.Type = Common::ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP;
|
entry.Type = Common::CalcResultType::TypeDamageHp;
|
||||||
entry.Arg0 = static_cast< uint8_t >( Common::ActionHitSeverityType::NormalDamage );
|
entry.Arg0 = 1;
|
||||||
|
|
||||||
effectPacket->addTargetEffect( entry, static_cast< uint64_t >( player.getId() ) );
|
effectPacket->addTargetEffect( entry, static_cast< uint64_t >( player.getId() ) );
|
||||||
effectPacket->setResultId( pCurrentZone->getNextActionResultId() );
|
effectPacket->setResultId( pCurrentZone->getNextActionResultId() );
|
||||||
|
|
|
@ -35,12 +35,10 @@ using namespace Sapphire::World::Manager;
|
||||||
bool MapMgr::loadQuests()
|
bool MapMgr::loadQuests()
|
||||||
{
|
{
|
||||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||||
auto idList = exdData.getIdList< Excel::Quest >();
|
auto questList = exdData.getRows< Excel::Quest >();
|
||||||
|
|
||||||
for( auto id : idList )
|
for( auto& [ id, questExdData ] : questList )
|
||||||
{
|
{
|
||||||
auto questExdData = exdData.getRow< Excel::Quest >( id );
|
|
||||||
|
|
||||||
m_quests.emplace( id, std::move( questExdData ) );
|
m_quests.emplace( id, std::move( questExdData ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -313,7 +313,7 @@ void PlayerMgr::onUpdate( Entity::Player& player, uint64_t tickCount )
|
||||||
void PlayerMgr::checkAutoAttack( Entity::Player& player, uint64_t tickCount ) const
|
void PlayerMgr::checkAutoAttack( Entity::Player& player, uint64_t tickCount ) const
|
||||||
{
|
{
|
||||||
auto mainWeap = player.getItemAt( Common::GearSet0, Common::MainHand );
|
auto mainWeap = player.getItemAt( Common::GearSet0, Common::MainHand );
|
||||||
if( !mainWeap || !player.isAutoattackOn() || player.checkAction() || !player.getTargetId() || player.getStance() != Common::Active )
|
if( !mainWeap || player.checkAction() || !player.isAutoattackOn() || !player.getTargetId() || player.getStance() != Common::Active )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for( const auto& actor : player.getInRangeActors() )
|
for( const auto& actor : player.getInRangeActors() )
|
||||||
|
|
|
@ -12,13 +12,12 @@ using namespace Sapphire::World::Manager;
|
||||||
void ShopMgr::cacheShop( uint32_t shopId )
|
void ShopMgr::cacheShop( uint32_t shopId )
|
||||||
{
|
{
|
||||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||||
auto itemShopList = exdData.getIdList< Excel::Shop >();
|
auto itemShopList = exdData.getRows< Excel::Shop >();
|
||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
for( auto itemShop : itemShopList )
|
for( const auto& [ itemShop, shop ] : itemShopList )
|
||||||
{
|
{
|
||||||
if( shopId == itemShop )
|
if( shopId == itemShop )
|
||||||
{
|
{
|
||||||
auto shop = exdData.getRow< Excel::Shop >( itemShop );
|
|
||||||
for( auto shopItemId : shop->data().Item )
|
for( auto shopItemId : shop->data().Item )
|
||||||
{
|
{
|
||||||
auto shopItem = exdData.getRow< Excel::ShopItem >( shopItemId );
|
auto shopItem = exdData.getRow< Excel::ShopItem >( shopItemId );
|
||||||
|
|
|
@ -35,14 +35,12 @@ TerritoryMgr::TerritoryMgr() :
|
||||||
void TerritoryMgr::loadTerritoryTypeDetailCache()
|
void TerritoryMgr::loadTerritoryTypeDetailCache()
|
||||||
{
|
{
|
||||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||||
auto idList = exdData.getIdList< Excel::TerritoryType >();
|
auto teriList = exdData.getRows< Excel::TerritoryType >();
|
||||||
|
|
||||||
for( auto id : idList )
|
for( const auto& [ id, teri ] : teriList )
|
||||||
{
|
{
|
||||||
auto teri1 = exdData.getRow< Excel::TerritoryType >( id );
|
if( !teri->getString( teri->data().Name ).empty() && id > 90 )
|
||||||
|
m_territoryTypeDetailCacheMap[ id ] = teri;
|
||||||
if( !teri1->getString( teri1->data().Name ).empty() && id > 90 )
|
|
||||||
m_territoryTypeDetailCacheMap[ id ] = teri1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -77,12 +75,11 @@ uint32_t TerritoryMgr::getNextInstanceId()
|
||||||
|
|
||||||
Excel::ExcelStructPtr< Excel::TerritoryType > TerritoryMgr::getTerritoryDetail( uint32_t territoryTypeId ) const
|
Excel::ExcelStructPtr< Excel::TerritoryType > TerritoryMgr::getTerritoryDetail( uint32_t territoryTypeId ) const
|
||||||
{
|
{
|
||||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
auto it = m_territoryTypeDetailCacheMap.find( territoryTypeId );
|
||||||
auto teri1 = exdData.getRow< Excel::TerritoryType >( territoryTypeId );
|
if( it == m_territoryTypeDetailCacheMap.end() )
|
||||||
if( !teri1 )
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return teri1;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TerritoryMgr::isInstanceContentTerritory( uint32_t territoryTypeId ) const
|
bool TerritoryMgr::isInstanceContentTerritory( uint32_t territoryTypeId ) const
|
||||||
|
@ -159,11 +156,10 @@ bool TerritoryMgr::isHousingTerritory( uint32_t territoryTypeId ) const
|
||||||
uint32_t TerritoryMgr::getInstanceContentId( uint32_t territoryTypeId ) const
|
uint32_t TerritoryMgr::getInstanceContentId( uint32_t territoryTypeId ) const
|
||||||
{
|
{
|
||||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||||
auto contentListIds = exdData.getIdList< Excel::InstanceContent >();
|
auto contentFinderList = exdData.getRows< Excel::InstanceContent >();
|
||||||
|
|
||||||
for( auto id : contentListIds )
|
for( const auto& [ id, instanceContent ] : contentFinderList )
|
||||||
{
|
{
|
||||||
auto instanceContent = exdData.getRow< Excel::InstanceContent >( id );
|
|
||||||
if( instanceContent->data().TerritoryType == territoryTypeId )
|
if( instanceContent->data().TerritoryType == territoryTypeId )
|
||||||
{
|
{
|
||||||
return id;
|
return id;
|
||||||
|
@ -198,8 +194,6 @@ bool TerritoryMgr::createDefaultTerritories()
|
||||||
pPlaceName->getString( pPlaceName->data().Text.SGL ) );
|
pPlaceName->getString( pPlaceName->data().Text.SGL ) );
|
||||||
pZone->init();
|
pZone->init();
|
||||||
|
|
||||||
std::string bgPath = territoryInfo->getString( territoryData.LVB );
|
|
||||||
|
|
||||||
bool hasNaviMesh = pZone->getNaviProvider() != nullptr;
|
bool hasNaviMesh = pZone->getNaviProvider() != nullptr;
|
||||||
|
|
||||||
Logger::info( "{0}\t{1}\t{2}\t{3:<10}\t{4}\t{5}\t{6}",
|
Logger::info( "{0}\t{1}\t{2}\t{3:<10}\t{4}\t{5}\t{6}",
|
||||||
|
@ -309,10 +303,10 @@ TerritoryPtr TerritoryMgr::createQuestBattle( uint32_t questBattleId )
|
||||||
if( !pQuestInfo || pQuestInfo->getString( pQuestInfo->data().Text.Name ).empty() )
|
if( !pQuestInfo || pQuestInfo->getString( pQuestInfo->data().Text.Name ).empty() )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
for( auto& teriId : exdData.getIdList< Excel::TerritoryType >() )
|
auto teriList = exdData.getRows< Excel::TerritoryType >();
|
||||||
{
|
|
||||||
|
|
||||||
auto pTeri = exdData.getRow< Excel::TerritoryType >( teriId );
|
for( const auto& [ teriId, pTeri ] : teriList )
|
||||||
|
{
|
||||||
if( !pTeri || pTeri->data().QuestBattle != questBattleId )
|
if( !pTeri || pTeri->data().QuestBattle != questBattleId )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -332,8 +326,6 @@ TerritoryPtr TerritoryMgr::createQuestBattle( uint32_t questBattleId )
|
||||||
m_instanceZoneSet.insert( pZone );
|
m_instanceZoneSet.insert( pZone );
|
||||||
|
|
||||||
return pZone;
|
return pZone;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -85,9 +85,7 @@ const int levelTable[61][6] =
|
||||||
{ 218, 354, 858, 2600, 282, 215 },
|
{ 218, 354, 858, 2600, 282, 215 },
|
||||||
};
|
};
|
||||||
|
|
||||||
std::random_device CalcStats::dev;
|
std::unique_ptr< RandGenerator< float > > CalcStats::rnd = nullptr;
|
||||||
std::mt19937 CalcStats::rng( dev() );
|
|
||||||
std::uniform_int_distribution< std::mt19937::result_type > CalcStats::range100( 0, 99 );
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Class used for battle-related formulas and calculations.
|
Class used for battle-related formulas and calculations.
|
||||||
|
@ -144,12 +142,15 @@ uint32_t CalcStats::calculateMaxHp( Player& player )
|
||||||
uint16_t hpMod = paramGrowthInfo->data().ParamBase;
|
uint16_t hpMod = paramGrowthInfo->data().ParamBase;
|
||||||
uint16_t jobModHp = classInfo->data().Hp;
|
uint16_t jobModHp = classInfo->data().Hp;
|
||||||
float approxBaseHp = 0.0f; // Read above
|
float approxBaseHp = 0.0f; // Read above
|
||||||
|
float hpModPercent = player.getModifier( Common::ParamModifier::HPPercent );
|
||||||
|
|
||||||
approxBaseHp = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::HP ] );
|
approxBaseHp = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::HP ] );
|
||||||
|
|
||||||
auto result = static_cast< uint32_t >( floor( jobModHp * ( approxBaseHp / 100.0f ) ) +
|
auto result = static_cast< uint32_t >( floor( jobModHp * ( approxBaseHp / 100.0f ) ) +
|
||||||
floor( hpMod / 100.0f * ( vitStat - baseStat ) ) );
|
floor( hpMod / 100.0f * ( vitStat - baseStat ) ) );
|
||||||
|
|
||||||
|
result *= hpModPercent;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,19 +288,6 @@ float CalcStats::blockProbability( const Chara& chara )
|
||||||
return std::floor( ( 30 * blockRate ) / levelVal + 10 );
|
return std::floor( ( 30 * blockRate ) / levelVal + 10 );
|
||||||
}
|
}
|
||||||
|
|
||||||
float CalcStats::directHitProbability( const Chara& chara )
|
|
||||||
{
|
|
||||||
const auto& baseStats = chara.getStats();
|
|
||||||
auto level = chara.getLevel();
|
|
||||||
|
|
||||||
auto dhRate = chara.getStatValueFloat( Common::BaseParam::Accuracy );
|
|
||||||
|
|
||||||
auto divVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] );
|
|
||||||
auto subVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::SUB ] );
|
|
||||||
|
|
||||||
return std::floor( 550.f * ( dhRate - subVal ) / divVal ) / 10.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
float CalcStats::criticalHitProbability( const Chara& chara )
|
float CalcStats::criticalHitProbability( const Chara& chara )
|
||||||
{
|
{
|
||||||
const auto& baseStats = chara.getStats();
|
const auto& baseStats = chara.getStats();
|
||||||
|
@ -564,7 +552,7 @@ float CalcStats::healingMagicPotency( const Sapphire::Entity::Chara& chara )
|
||||||
return std::floor( 100.f * ( chara.getStatValue( Common::BaseParam::HealingMagicPotency ) - 292.f ) / 264.f + 100.f ) / 100.f;
|
return std::floor( 100.f * ( chara.getStatValue( Common::BaseParam::HealingMagicPotency ) - 292.f ) / 264.f + 100.f ) / 100.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcAutoAttackDamage( const Sapphire::Entity::Chara& chara )
|
std::pair< float, Sapphire::Common::CalcResultType > CalcStats::calcAutoAttackDamage( const Sapphire::Entity::Chara& chara )
|
||||||
{
|
{
|
||||||
// D = ⌊ f(ptc) × f(aa) × f(ap) × f(det) × f(tnc) × traits ⌋ × f(ss) ⌋ ×
|
// D = ⌊ f(ptc) × f(aa) × f(ap) × f(det) × f(tnc) × traits ⌋ × f(ss) ⌋ ×
|
||||||
// f(chr) ⌋ × f(dhr) ⌋ × rand[ 0.95, 1.05 ] ⌋ × buff_1 ⌋ × buff... ⌋
|
// f(chr) ⌋ × f(dhr) ⌋ × rand[ 0.95, 1.05 ] ⌋ × buff_1 ⌋ × buff... ⌋
|
||||||
|
@ -577,27 +565,19 @@ std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcAutoA
|
||||||
|
|
||||||
// todo: everything after tenacity
|
// todo: everything after tenacity
|
||||||
auto factor = Common::Util::trunc( pot * aa * ap * det, 0 );
|
auto factor = Common::Util::trunc( pot * aa * ap * det, 0 );
|
||||||
Sapphire::Common::ActionHitSeverityType hitType = Sapphire::Common::ActionHitSeverityType::NormalDamage;
|
Sapphire::Common::CalcResultType hitType = Sapphire::Common::CalcResultType::TypeDamageHp;
|
||||||
|
|
||||||
// todo: traits
|
// todo: traits
|
||||||
|
|
||||||
factor = std::floor( factor * speed( chara ) );
|
factor = std::floor( factor * speed( chara ) );
|
||||||
|
|
||||||
if( criticalHitProbability( chara ) > range100( rng ) )
|
if( criticalHitProbability( chara ) > getRandomNumber0To100() )
|
||||||
{
|
{
|
||||||
factor *= criticalHitBonus( chara );
|
factor *= criticalHitBonus( chara );
|
||||||
hitType = Sapphire::Common::ActionHitSeverityType::CritDamage;
|
hitType = Sapphire::Common::CalcResultType::TypeCriticalDamageHp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( directHitProbability( chara ) > range100( rng ) )
|
factor *= 1.0f + ( ( getRandomNumber0To100() - 50.0f ) / 1000.0f );
|
||||||
{
|
|
||||||
factor *= 1.25f;
|
|
||||||
hitType = hitType == Sapphire::Common::ActionHitSeverityType::CritDamage ?
|
|
||||||
Sapphire::Common::ActionHitSeverityType::CritDirectHitDamage :
|
|
||||||
Sapphire::Common::ActionHitSeverityType::DirectHitDamage;
|
|
||||||
}
|
|
||||||
|
|
||||||
factor *= 1.0f + ( ( range100( rng ) - 50.0f ) / 1000.0f );
|
|
||||||
|
|
||||||
// todo: buffs
|
// todo: buffs
|
||||||
|
|
||||||
|
@ -615,7 +595,7 @@ std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcAutoA
|
||||||
return std::pair( factor, hitType );
|
return std::pair( factor, hitType );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcActionDamage( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg )
|
std::pair< float, Sapphire::Common::CalcResultType > CalcStats::calcActionDamage( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg )
|
||||||
{
|
{
|
||||||
// D = ⌊ f(pot) × f(wd) × f(ap) × f(det) × f(tnc) × traits ⌋
|
// D = ⌊ f(pot) × f(wd) × f(ap) × f(det) × f(tnc) × traits ⌋
|
||||||
// × f(chr) ⌋ × f(dhr) ⌋ × rand[ 0.95, 1.05 ] ⌋ buff_1 ⌋ × buff_1 ⌋ × buff... ⌋
|
// × f(chr) ⌋ × f(dhr) ⌋ × rand[ 0.95, 1.05 ] ⌋ buff_1 ⌋ × buff_1 ⌋ × buff... ⌋
|
||||||
|
@ -624,33 +604,29 @@ std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcActio
|
||||||
auto wd = weaponDamage( chara, wepDmg );
|
auto wd = weaponDamage( chara, wepDmg );
|
||||||
auto ap = getPrimaryAttackPower( chara );
|
auto ap = getPrimaryAttackPower( chara );
|
||||||
auto det = determination( chara );
|
auto det = determination( chara );
|
||||||
|
auto damageDealtMod = chara.getModifier( Common::ParamModifier::DamageDealtPercent );
|
||||||
|
|
||||||
auto factor = Common::Util::trunc( pot * wd * ap * det, 0 );
|
auto factor = Common::Util::trunc( pot * wd * ap * det, 0 );
|
||||||
Sapphire::Common::ActionHitSeverityType hitType = Sapphire::Common::ActionHitSeverityType::NormalDamage;
|
Sapphire::Common::CalcResultType hitType = Sapphire::Common::CalcResultType::TypeDamageHp;
|
||||||
|
|
||||||
if( criticalHitProbability( chara ) > range100( rng ) )
|
if( criticalHitProbability( chara ) > getRandomNumber0To100() )
|
||||||
{
|
{
|
||||||
factor *= criticalHitBonus( chara );
|
factor *= criticalHitBonus( chara );
|
||||||
hitType = Sapphire::Common::ActionHitSeverityType::CritDamage;
|
hitType = Sapphire::Common::CalcResultType::TypeCriticalDamageHp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( directHitProbability( chara ) > range100( rng ) )
|
factor *= 1.0f + ( ( getRandomNumber0To100() - 50.0f ) / 1000.0f );
|
||||||
{
|
|
||||||
factor *= 1.25f;
|
|
||||||
hitType = hitType == Sapphire::Common::ActionHitSeverityType::CritDamage ?
|
|
||||||
Sapphire::Common::ActionHitSeverityType::CritDirectHitDamage :
|
|
||||||
Sapphire::Common::ActionHitSeverityType::DirectHitDamage;
|
|
||||||
}
|
|
||||||
|
|
||||||
factor *= 1.0f + ( ( range100( rng ) - 50.0f ) / 1000.0f );
|
|
||||||
|
|
||||||
// todo: buffs
|
// todo: buffs
|
||||||
|
|
||||||
|
factor *= damageDealtMod;
|
||||||
|
|
||||||
constexpr auto format = "dmg: pot: {} ({}) wd: {} ({}) ap: {} det: {} = {}";
|
constexpr auto format = "dmg: pot: {} ({}) wd: {} ({}) ap: {} det: {} = {}";
|
||||||
|
|
||||||
if( auto player = const_cast< Entity::Chara& >( chara ).getAsPlayer() )
|
if( auto player = const_cast< Entity::Chara& >( chara ).getAsPlayer() )
|
||||||
{
|
{
|
||||||
PlayerMgr::sendDebug( *player, format, pot, ptc, wd, wepDmg, ap, det, factor );
|
PlayerMgr::sendDebug( *player, format, pot, ptc, wd, wepDmg, ap, det, factor );
|
||||||
|
PlayerMgr::sendDebug( *player, "DamageDealtPercent: {}", damageDealtMod );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -660,22 +636,23 @@ std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcActio
|
||||||
return std::pair( factor, hitType );
|
return std::pair( factor, hitType );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcActionHealing( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg )
|
std::pair< float, Sapphire::Common::CalcResultType > CalcStats::calcActionHealing( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg )
|
||||||
{
|
{
|
||||||
// lol just for testing
|
// lol just for testing
|
||||||
float det = chara.getStatValue( Common::BaseParam::Determination );
|
float det = chara.getStatValue( Common::BaseParam::Determination );
|
||||||
float mnd = chara.getStatValue( Common::BaseParam::Mind );
|
float mnd = chara.getStatValue( Common::BaseParam::Mind );
|
||||||
|
|
||||||
auto factor = std::floor( ( wepDmg * ( mnd / 200 ) + ( det / 10 ) ) * ( ptc / 100 ) * 1.3f );
|
auto factor = std::floor( ( wepDmg * ( mnd / 200 ) + ( det / 10 ) ) * ( ptc / 100 ) * 1.3f );
|
||||||
Sapphire::Common::ActionHitSeverityType hitType = Sapphire::Common::ActionHitSeverityType::NormalHeal;
|
|
||||||
|
|
||||||
if( criticalHitProbability( chara ) > range100( rng ) )
|
Sapphire::Common::CalcResultType hitType = Sapphire::Common::CalcResultType::TypeRecoverHp;
|
||||||
|
|
||||||
|
if( criticalHitProbability( chara ) > getRandomNumber0To100() )
|
||||||
{
|
{
|
||||||
factor *= criticalHitBonus( chara );
|
factor *= criticalHitBonus( chara );
|
||||||
hitType = Sapphire::Common::ActionHitSeverityType::CritHeal;
|
hitType = Sapphire::Common::CalcResultType::TypeCriticalRecoverHp;
|
||||||
}
|
}
|
||||||
|
|
||||||
factor *= 1.0f + ( ( range100( rng ) - 50.0f ) / 1000.0f );
|
factor *= 1.0f + ( ( getRandomNumber0To100() - 50.0f ) / 1000.0f );
|
||||||
|
|
||||||
return std::pair( factor, hitType );
|
return std::pair( factor, hitType );
|
||||||
}
|
}
|
||||||
|
@ -684,3 +661,12 @@ uint32_t CalcStats::primaryStatValue( const Sapphire::Entity::Chara& chara )
|
||||||
{
|
{
|
||||||
return chara.getStatValue( chara.getPrimaryStat() );
|
return chara.getStatValue( chara.getPrimaryStat() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float CalcStats::getRandomNumber0To100()
|
||||||
|
{
|
||||||
|
if( !rnd )
|
||||||
|
{
|
||||||
|
rnd = std::make_unique< RandGenerator< float > >( Common::Service< RNGMgr >::ref().getRandGenerator< float >( 0, 100 ) );
|
||||||
|
}
|
||||||
|
return rnd->next();
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <random>
|
|
||||||
#include <Common.h>
|
#include <Common.h>
|
||||||
#include "Forwards.h"
|
#include "Forwards.h"
|
||||||
|
#include "Manager/RNGMgr.h"
|
||||||
|
|
||||||
namespace Sapphire::Math
|
namespace Sapphire::Math
|
||||||
{
|
{
|
||||||
|
using namespace Sapphire::World::Manager;
|
||||||
|
|
||||||
class CalcStats
|
class CalcStats
|
||||||
{
|
{
|
||||||
|
@ -34,11 +35,6 @@ namespace Sapphire::Math
|
||||||
*/
|
*/
|
||||||
static float blockProbability( const Sapphire::Entity::Chara& chara );
|
static float blockProbability( const Sapphire::Entity::Chara& chara );
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief Calculates the probability of a direct hit happening
|
|
||||||
*/
|
|
||||||
static float directHitProbability( const Sapphire::Entity::Chara& chara );
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Calculates the probability of a critical hit happening
|
* @brief Calculates the probability of a critical hit happening
|
||||||
*/
|
*/
|
||||||
|
@ -140,11 +136,11 @@ namespace Sapphire::Math
|
||||||
|
|
||||||
////////////////////////////////////////////
|
////////////////////////////////////////////
|
||||||
|
|
||||||
static std::pair< float, Common::ActionHitSeverityType > calcAutoAttackDamage( const Sapphire::Entity::Chara& chara );
|
static std::pair< float, Common::CalcResultType > calcAutoAttackDamage( const Sapphire::Entity::Chara& chara );
|
||||||
|
|
||||||
static std::pair< float, Common::ActionHitSeverityType > calcActionDamage( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg );
|
static std::pair< float, Common::CalcResultType > calcActionDamage( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg );
|
||||||
|
|
||||||
static std::pair< float, Common::ActionHitSeverityType > calcActionHealing( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg );
|
static std::pair< float, Common::CalcResultType > calcActionHealing( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg );
|
||||||
|
|
||||||
static uint32_t primaryStatValue( const Sapphire::Entity::Chara& chara );
|
static uint32_t primaryStatValue( const Sapphire::Entity::Chara& chara );
|
||||||
private:
|
private:
|
||||||
|
@ -156,9 +152,8 @@ namespace Sapphire::Math
|
||||||
*/
|
*/
|
||||||
static float calcAttackPower( const Sapphire::Entity::Chara& chara, uint32_t attackPower );
|
static float calcAttackPower( const Sapphire::Entity::Chara& chara, uint32_t attackPower );
|
||||||
|
|
||||||
static std::random_device dev;
|
static float getRandomNumber0To100();
|
||||||
static std::mt19937 rng;
|
static std::unique_ptr< RandGenerator< float > > rnd;
|
||||||
static std::uniform_int_distribution< std::mt19937::result_type > range100;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,12 +74,12 @@ void Sapphire::Network::GameConnection::find5Contents( const Packets::FFXIVARR_P
|
||||||
if( territoryType != 0 )
|
if( territoryType != 0 )
|
||||||
selectedContent.insert( territoryType );
|
selectedContent.insert( territoryType );
|
||||||
|
|
||||||
auto contentListIds = exdData.getIdList< Excel::InstanceContent >();
|
|
||||||
|
|
||||||
std::vector< uint32_t > idList;
|
std::vector< uint32_t > idList;
|
||||||
for( auto id : contentListIds )
|
|
||||||
|
auto contentFinderList = exdData.getRows< Excel::InstanceContent >();
|
||||||
|
|
||||||
|
for( const auto& [ id, instanceContent ] : contentFinderList )
|
||||||
{
|
{
|
||||||
auto instanceContent = exdData.getRow< Excel::InstanceContent >( id );
|
|
||||||
if( selectedContent.count( instanceContent->data().TerritoryType ) )
|
if( selectedContent.count( instanceContent->data().TerritoryType ) )
|
||||||
{
|
{
|
||||||
idList.push_back( id );
|
idList.push_back( id );
|
||||||
|
|
|
@ -506,19 +506,14 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR
|
||||||
|
|
||||||
bool doTeleport = false;
|
bool doTeleport = false;
|
||||||
uint16_t teleport;
|
uint16_t teleport;
|
||||||
auto idList = exdData.getIdList< Excel::Aetheryte >();
|
auto aetheryteList = exdData.getRows< Excel::Aetheryte >();
|
||||||
|
|
||||||
for( auto i : idList )
|
for( const auto& [ id, data ] : aetheryteList )
|
||||||
{
|
{
|
||||||
auto data = exdData.getRow< Excel::Aetheryte >( i );
|
|
||||||
|
|
||||||
if( !data )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( data->data().TerritoryType == param1 && data->data().Telepo )
|
if( data->data().TerritoryType == param1 && data->data().Telepo )
|
||||||
{
|
{
|
||||||
doTeleport = true;
|
doTeleport = true;
|
||||||
teleport = static_cast< uint16_t >( i );
|
teleport = static_cast< uint16_t >( id );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,4 +92,10 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
|
||||||
uint8_t m_sourceEffectCount{ 0 };
|
uint8_t m_sourceEffectCount{ 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template< typename... Args >
|
||||||
|
std::shared_ptr< EffectPacket > makeEffectPacket( Args... args )
|
||||||
|
{
|
||||||
|
return std::make_shared< EffectPacket >( args... );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -83,5 +83,10 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
|
||||||
uint8_t m_sourceEffectCount{ 0 };
|
uint8_t m_sourceEffectCount{ 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template< typename... Args >
|
||||||
|
std::shared_ptr< EffectPacket1 > makeEffectPacket1( Args... args )
|
||||||
|
{
|
||||||
|
return std::make_shared< EffectPacket1 >( args... );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,16 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
|
||||||
m_data.NpcId = bnpc.getBNpcBaseId();
|
m_data.NpcId = bnpc.getBNpcBaseId();
|
||||||
m_data.NameId = bnpc.getBNpcNameId();
|
m_data.NameId = bnpc.getBNpcNameId();
|
||||||
|
|
||||||
|
if( bnpc.getInstanceObjectInfo() )
|
||||||
|
{
|
||||||
|
m_data.LinkCountLimit = bnpc.getInstanceObjectInfo()->LinkCountLimit;
|
||||||
|
m_data.LinkFamily = bnpc.getInstanceObjectInfo()->LinkFamily;
|
||||||
|
m_data.LinkGroup = bnpc.getInstanceObjectInfo()->LinkGroup;
|
||||||
|
m_data.LinkParent = bnpc.getInstanceObjectInfo()->LinkParent;
|
||||||
|
m_data.LinkRange = bnpc.getInstanceObjectInfo()->LinkRange;
|
||||||
|
m_data.LinkReply = bnpc.getInstanceObjectInfo()->LinkReply;
|
||||||
|
}
|
||||||
|
|
||||||
assert( target.getId() != bnpc.getId() );
|
assert( target.getId() != bnpc.getId() );
|
||||||
|
|
||||||
m_data.Index = target.getSpawnIdForActorId( bnpc.getId() );
|
m_data.Index = target.getSpawnIdForActorId( bnpc.getId() );
|
||||||
|
|
|
@ -52,15 +52,13 @@ void Util::Packet::sendBaseParams( Entity::Player& player )
|
||||||
std::fill( std::begin( statParams ), std::end( statParams ), 0 );
|
std::fill( std::begin( statParams ), std::end( statParams ), 0 );
|
||||||
|
|
||||||
auto& exd = Common::Service< Data::ExdData >::ref();
|
auto& exd = Common::Service< Data::ExdData >::ref();
|
||||||
auto idList = exd.getIdList< Excel::BaseParam >();
|
auto baseParamList = exd.getRows< Excel::BaseParam >();
|
||||||
|
|
||||||
for( const auto id : idList )
|
for( const auto& [ id, row ] : baseParamList )
|
||||||
{
|
{
|
||||||
auto row = exd.getRow< Excel::BaseParam >( id );
|
if( !row || row->data().PacketIndex < 0 )
|
||||||
if( !row )
|
|
||||||
continue;
|
|
||||||
if( row->data().PacketIndex < 0 )
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
statParams[ row->data().PacketIndex ] = player.getStatValue( static_cast< Common::BaseParam >( id ) );
|
statParams[ row->data().PacketIndex ] = player.getStatValue( static_cast< Common::BaseParam >( id ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,8 @@ void ActionIntegrityTask::execute()
|
||||||
if( actionResult && actionResult->getTarget() )
|
if( actionResult && actionResult->getTarget() )
|
||||||
actionResult->execute();
|
actionResult->execute();
|
||||||
|
|
||||||
if( ( actionResult->getCalcResultParam().Type == Common::CALC_RESULT_TYPE_SET_STATUS ) ||
|
if( ( actionResult->getCalcResultParam().Type == Common::TypeSetStatus ) ||
|
||||||
( actionResult->getCalcResultParam().Type == Common::CALC_RESULT_TYPE_SET_STATUS_ME ) )
|
( actionResult->getCalcResultParam().Type == Common::TypeSetStatusMe ) )
|
||||||
{
|
{
|
||||||
auto& status = data.Status[ statusIdx++ ];
|
auto& status = data.Status[ statusIdx++ ];
|
||||||
auto pEffect = actionResult->getStatusEffect();
|
auto pEffect = actionResult->getStatusEffect();
|
||||||
|
|
|
@ -41,6 +41,10 @@ void MoveTerritoryTask::execute()
|
||||||
if( !pPlayer )
|
if( !pPlayer )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
pPlayer->setTargetId( 0 );
|
||||||
|
pPlayer->setStance( Common::Stance::Passive );
|
||||||
|
pPlayer->setAutoattack( false );
|
||||||
|
|
||||||
auto inRangePlayerIds = pPlayer->getInRangePlayerIds( true );
|
auto inRangePlayerIds = pPlayer->getInRangePlayerIds( true );
|
||||||
|
|
||||||
auto warpStart = makeActorControlSelf( pPlayer->getId(), WarpStart, m_warpInfo.m_warpType, 1, 0, m_warpInfo.m_targetTerritoryId, 1 );
|
auto warpStart = makeActorControlSelf( pPlayer->getId(), WarpStart, m_warpInfo.m_warpType, 1, 0, m_warpInfo.m_targetTerritoryId, 1 );
|
||||||
|
|
|
@ -102,3 +102,12 @@ void Sapphire::Cell::unload()
|
||||||
removeActors();
|
removeActors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t Sapphire::Cell::getLastActiveTime() const
|
||||||
|
{
|
||||||
|
return m_lastActiveTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sapphire::Cell::setLastActiveTime( uint32_t lastActiveTime )
|
||||||
|
{
|
||||||
|
m_lastActiveTime = lastActiveTime;
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ private:
|
||||||
bool m_bActive;
|
bool m_bActive;
|
||||||
|
|
||||||
uint16_t m_playerCount;
|
uint16_t m_playerCount;
|
||||||
|
uint32_t m_lastActiveTime;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Cell();
|
Cell();
|
||||||
|
@ -82,6 +83,9 @@ public:
|
||||||
{
|
{
|
||||||
return m_posY;
|
return m_posY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t getLastActiveTime() const;
|
||||||
|
void setLastActiveTime( uint32_t lastActiveTime );
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,27 +11,24 @@
|
||||||
#include <ExdCat.h>
|
#include <ExdCat.h>
|
||||||
#include <Exd.h>
|
#include <Exd.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <execution>
|
||||||
|
|
||||||
#include <Logging/Logger.h>
|
#include <Logging/Logger.h>
|
||||||
#include <Service.h>
|
#include <Service.h>
|
||||||
#include <Util/UtilMath.h>
|
#include <Util/UtilMath.h>
|
||||||
|
|
||||||
Sapphire::InstanceObjectCache::InstanceObjectCache()
|
Sapphire::InstanceObjectCache::InstanceObjectCache()
|
||||||
{
|
{
|
||||||
|
|
||||||
auto& exdData = Common::Service< Sapphire::Data::ExdData >::ref();
|
auto& exdData = Common::Service< Sapphire::Data::ExdData >::ref();
|
||||||
auto idList = exdData.getIdList< Excel::TerritoryType >();
|
auto teriList = exdData.getRows< Excel::TerritoryType >();
|
||||||
|
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
for( const auto& id : idList )
|
for( const auto& [ id, territoryType ] : teriList ) {
|
||||||
{
|
|
||||||
// show some loading indication...
|
// show some loading indication...
|
||||||
if( count++ % 10 == 0 )
|
if( count++ % 10 == 0 )
|
||||||
std::cout << ".";
|
std::cout << ".";
|
||||||
|
|
||||||
auto territoryType = exdData.getRow< Excel::TerritoryType >( id );
|
|
||||||
if( !territoryType )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto path = territoryType->getString( territoryType->data().LVB );
|
auto path = territoryType->getString( territoryType->data().LVB );
|
||||||
|
|
||||||
if( path.empty() )
|
if( path.empty() )
|
||||||
|
@ -56,7 +53,11 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if( exdData.getGameData()->doesFileExist( bgLgbPath ) )
|
||||||
bgFile = exdData.getGameData()->getFile( bgLgbPath );
|
bgFile = exdData.getGameData()->getFile( bgLgbPath );
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
planmap_file = exdData.getGameData()->getFile( planmapLgbPath );
|
planmap_file = exdData.getGameData()->getFile( planmapLgbPath );
|
||||||
planevent_file = exdData.getGameData()->getFile( planeventLgbPath );
|
planevent_file = exdData.getGameData()->getFile( planeventLgbPath );
|
||||||
}
|
}
|
||||||
|
@ -101,49 +102,60 @@ Sapphire::InstanceObjectCache::InstanceObjectCache()
|
||||||
{
|
{
|
||||||
for( const auto& pEntry : group.entries )
|
for( const auto& pEntry : group.entries )
|
||||||
{
|
{
|
||||||
|
switch( pEntry->getType() )
|
||||||
if( pEntry->getType() == LgbEntryType::MapRange )
|
{
|
||||||
|
case LgbEntryType::MapRange:
|
||||||
{
|
{
|
||||||
auto pMapRange = std::reinterpret_pointer_cast< LGB_MAP_RANGE_ENTRY >( pEntry );
|
auto pMapRange = std::reinterpret_pointer_cast< LGB_MAP_RANGE_ENTRY >( pEntry );
|
||||||
m_mapRangeCache.insert( id, pMapRange );
|
m_mapRangeCache.insert( id, pMapRange );
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( pEntry->getType() == LgbEntryType::ExitRange )
|
case LgbEntryType::ExitRange:
|
||||||
{
|
{
|
||||||
auto pExitRange = std::reinterpret_pointer_cast< LGB_EXIT_RANGE_ENTRY >( pEntry );
|
auto pExitRange = std::reinterpret_pointer_cast< LGB_EXIT_RANGE_ENTRY >( pEntry );
|
||||||
m_exitRangeCache.insert( id, pExitRange );
|
m_exitRangeCache.insert( id, pExitRange );
|
||||||
}
|
|
||||||
else if( pEntry->getType() == LgbEntryType::PopRange )
|
|
||||||
{
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LgbEntryType::PopRange:
|
||||||
|
{
|
||||||
auto pPopRange = std::reinterpret_pointer_cast< LGB_POP_RANGE_ENTRY >( pEntry );
|
auto pPopRange = std::reinterpret_pointer_cast< LGB_POP_RANGE_ENTRY >( pEntry );
|
||||||
m_popRangeCache.insert( id, pPopRange );
|
m_popRangeCache.insert( id, pPopRange );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( pEntry->getType() == LgbEntryType::CollisionBox )
|
case LgbEntryType::CollisionBox:
|
||||||
{
|
{
|
||||||
//auto pEObj = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry );
|
//auto pEObj = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry );
|
||||||
|
|
||||||
//Logger::debug( "CollisionBox {}", pEntry->header.nameOffset );
|
//Logger::debug( "CollisionBox {}", pEntry->header.nameOffset );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( pEntry->getType() == LgbEntryType::EventObject )
|
case LgbEntryType::EventObject:
|
||||||
{
|
{
|
||||||
auto pEObj = std::reinterpret_pointer_cast< LGB_EOBJ_ENTRY >( pEntry );
|
auto pEObj = std::reinterpret_pointer_cast< LGB_EOBJ_ENTRY >( pEntry );
|
||||||
m_eobjCache.insert( id, pEObj );
|
m_eobjCache.insert( id, pEObj );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( pEntry->getType() == LgbEntryType::EventNpc )
|
case LgbEntryType::EventNpc:
|
||||||
{
|
{
|
||||||
auto pENpc = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry );
|
auto pENpc = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry );
|
||||||
m_enpcCache.insert( id, pENpc );
|
m_enpcCache.insert( id, pENpc );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if( pEntry->getType() == LgbEntryType::EventRange )
|
case LgbEntryType::EventRange:
|
||||||
{
|
{
|
||||||
auto pEventRange = std::reinterpret_pointer_cast< LGB_EVENT_RANGE_ENTRY >( pEntry );
|
auto pEventRange = std::reinterpret_pointer_cast< LGB_EVENT_RANGE_ENTRY >( pEntry );
|
||||||
m_eventRangeCache.insert( 0, pEventRange );
|
m_eventRangeCache.insert( 0, pEventRange );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << "\n";
|
}
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
Logger::debug(
|
Logger::debug(
|
||||||
"InstanceObjectCache Cached: MapRange: {} ExitRange: {} PopRange: {} EventObj: {} EventNpc: {} EventRange: {}",
|
"InstanceObjectCache Cached: MapRange: {} ExitRange: {} PopRange: {} EventObj: {} EventNpc: {} EventRange: {}",
|
||||||
|
|
|
@ -528,6 +528,7 @@ bool Territory::isCellActive( uint32_t x, uint32_t y )
|
||||||
uint32_t posY;
|
uint32_t posY;
|
||||||
|
|
||||||
CellPtr pCell;
|
CellPtr pCell;
|
||||||
|
uint32_t time = Common::Util::getTimeSeconds();
|
||||||
|
|
||||||
for( posX = startX; posX <= endX; posX++ )
|
for( posX = startX; posX <= endX; posX++ )
|
||||||
{
|
{
|
||||||
|
@ -535,7 +536,7 @@ bool Territory::isCellActive( uint32_t x, uint32_t y )
|
||||||
{
|
{
|
||||||
pCell = getCellPtr( posX, posY );
|
pCell = getCellPtr( posX, posY );
|
||||||
|
|
||||||
if( pCell && ( pCell->hasPlayers() || pCell->isForcedActive() ) )
|
if( pCell && ( pCell->hasPlayers() || pCell->isForcedActive() || ( time - pCell->getLastActiveTime() ) < 20 ) )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -566,13 +567,13 @@ void Territory::updateCellActivity( uint32_t x, uint32_t y, int32_t radius )
|
||||||
{
|
{
|
||||||
pCell = create( posX, posY );
|
pCell = create( posX, posY );
|
||||||
pCell->init( posX, posY );
|
pCell->init( posX, posY );
|
||||||
|
|
||||||
pCell->setActivity( true );
|
pCell->setActivity( true );
|
||||||
|
pCell->setLastActiveTime( Common::Util::getTimeSeconds() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
pCell->setLastActiveTime( Common::Util::getTimeSeconds() );
|
||||||
//Cell is now active
|
//Cell is now active
|
||||||
if( isCellActive( posX, posY ) && !pCell->isActive() )
|
if( isCellActive( posX, posY ) && !pCell->isActive() )
|
||||||
{
|
{
|
||||||
|
@ -581,6 +582,7 @@ void Territory::updateCellActivity( uint32_t x, uint32_t y, int32_t radius )
|
||||||
else if( !isCellActive( posX, posY ) && pCell->isActive() )
|
else if( !isCellActive( posX, posY ) && pCell->isActive() )
|
||||||
pCell->setActivity( false );
|
pCell->setActivity( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -834,6 +836,7 @@ Entity::BNpcPtr Territory::createBNpcFromLayoutId( uint32_t layoutId, uint32_t h
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto pBNpc = std::make_shared< Entity::BNpc >( getNextActorId(), infoPtr->second, *this, hp, bnpcType );
|
auto pBNpc = std::make_shared< Entity::BNpc >( getNextActorId(), infoPtr->second, *this, hp, bnpcType );
|
||||||
|
pBNpc->init();
|
||||||
pBNpc->setTriggerOwnerId( triggerOwnerId );
|
pBNpc->setTriggerOwnerId( triggerOwnerId );
|
||||||
pushActor( pBNpc );
|
pushActor( pBNpc );
|
||||||
return pBNpc;
|
return pBNpc;
|
||||||
|
|
|
@ -144,6 +144,11 @@ std::string readFileToString( const std::string& filename )
|
||||||
// Close the file
|
// Close the file
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
// Remove all newlines from the file contents
|
||||||
|
fileContents.erase( std::remove( fileContents.begin(), fileContents.end(), '\n' ), fileContents.end() );
|
||||||
|
fileContents.erase( std::remove( fileContents.begin(), fileContents.end(), '\r' ), fileContents.end() );
|
||||||
|
|
||||||
|
|
||||||
// Return the file contents as a string
|
// Return the file contents as a string
|
||||||
return fileContents;
|
return fileContents;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue