1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-28 20:27:46 +00:00

Merge sapphire master

This commit is contained in:
Maru 2018-03-02 02:54:09 -03:00
commit 4dd1db1dc2
89 changed files with 6201 additions and 9403 deletions

View file

@ -5,8 +5,6 @@
<AuthPort>54998</AuthPort>
<!-- Ip the lobby server listens on -->
<ListenIp>127.0.0.1</ListenIp>
<!-- Path of FFXIV dat files -->
<DataPath>C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv</DataPath>
<!-- IP of the world server -->
<ZoneIp>127.0.0.1</ZoneIp>
<!-- Port the world server listens for clients -->

View file

@ -6,7 +6,7 @@
<!-- Ip the lobby server listens on -->
<ListenIp>127.0.0.1</ListenIp>
<!-- Path of FFXIV dat files -->
<DataPath>C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv</DataPath>
<DataPath>C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack</DataPath>
<!-- <DataPath>/opt/sapphire_3_15_0/bin/sqpack</DataPath> -->
<!-- IP of the lobby server -->
<LobbyHost>127.0.0.1</LobbyHost>

View file

@ -5,7 +5,7 @@
<!-- Ip the zone server conenctions on -->
<ListenIp>127.0.0.1</ListenIp>
<!-- Path of FFXIV dat files -->
<DataPath>C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv</DataPath>
<DataPath>C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack</DataPath>
<Scripts>
<!-- where compiled scripts are placed -->

View file

@ -113,7 +113,6 @@ function(git_describe _var)
execute_process(COMMAND
"${GIT_EXECUTABLE}"
describe
${hash}
${ARGN}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"

View file

@ -564,14 +564,13 @@ namespace Core {
LeveStartError = 0x67,
PlayerNameGrayout = 0x6A,
LeveStartAnim = 0x66,
LeveStartError = 0x67,
PlayerNameGrayout = 0x6A,
ItemObtainMsg = 0x75,
DutyQuestScreenMsg = 0x7B,
ItemObtainIcon = 0x84,
FateItemFailMsg = 0x85,
ItemFailMsg = 0x86,
ActionLearnMsg1 = 0x87,
FreeEventPos = 0x8A,
UnlockAetherCurrentMsg = 0xA4,

File diff suppressed because it is too large Load diff

View file

@ -11,6 +11,7 @@
#include <ExdCat.h>
#include <Exd.h>
#include <set>
#include <boost/make_shared.hpp>
namespace Core {
namespace Data {
@ -244,7 +245,9 @@ struct Omen;
struct OnlineStatus;
struct Opening;
struct Orchestrion;
struct OrchestrionCategory;
struct OrchestrionPath;
struct OrchestrionUiparam;
struct ParamGrow;
struct Pet;
struct PetAction;
@ -252,6 +255,8 @@ struct Picture;
struct PlaceName;
struct Quest;
struct QuestRewardOther;
struct QuickChat;
struct QuickChatTransient;
struct Race;
struct RacingChocoboItem;
struct RacingChocoboName;
@ -284,6 +289,9 @@ struct SpecialShopItemCategory;
struct Stain;
struct Status;
struct Story;
struct SubmarineExploration;
struct SubmarinePart;
struct SubmarineRank;
struct SwitchTalk;
struct TerritoryType;
struct TextCommand;
@ -295,6 +303,7 @@ struct Town;
struct Trait;
struct TraitRecast;
struct TraitTransient;
struct TreasureHuntRank;
struct Tribe;
struct TripleTriad;
struct TripleTriadCard;
@ -487,7 +496,6 @@ struct Aetheryte
uint16_t placeName;
uint16_t aethernetName;
uint16_t territory;
uint32_t destination;
bool isAetheryte;
uint8_t aethernetGroup;
uint16_t map;
@ -693,9 +701,16 @@ struct BeastReputationRank
struct BeastTribe
{
uint8_t minLevel;
uint8_t maxLevel;
uint8_t beastRankBonus;
uint32_t iconReputation;
uint32_t icon;
uint8_t maxRank;
uint32_t alliedBeastTribeQuest;
uint8_t expansion;
uint32_t currencyItem;
uint8_t displayOrder;
std::string name;
std::string nameRelation;
@ -1536,7 +1551,7 @@ struct EventAction
{
std::string name;
uint16_t icon;
uint16_t castTime;
uint8_t castTime;
EventAction( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
@ -1996,6 +2011,9 @@ struct GilShop
struct GilShopItem
{
int32_t item;
std::vector< int32_t > rowRequired;
uint16_t stateRequired;
uint16_t patch;
GilShopItem( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
@ -2284,6 +2302,7 @@ struct Leve
int32_t placeNameStart;
int32_t placeNameIssued;
uint8_t classJobCategory;
int32_t journalGenre;
int32_t placeNameStartZone;
int32_t iconCityState;
int32_t dataId;
@ -2552,6 +2571,7 @@ struct Mount
uint8_t flyingCondition;
uint8_t isFlying;
uint16_t rideBGM;
int8_t order;
uint16_t icon;
Mount( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
@ -2604,6 +2624,7 @@ struct Omen
struct OnlineStatus
{
uint8_t priority;
std::string name;
uint32_t icon;
@ -2625,6 +2646,13 @@ struct Orchestrion
Orchestrion( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct OrchestrionCategory
{
std::string name;
OrchestrionCategory( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct OrchestrionPath
{
std::string file;
@ -2632,6 +2660,14 @@ struct OrchestrionPath
OrchestrionPath( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct OrchestrionUiparam
{
uint8_t orchestrionCategory;
uint16_t order;
OrchestrionUiparam( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct ParamGrow
{
int32_t expToNext;
@ -2753,6 +2789,22 @@ struct QuestRewardOther
QuestRewardOther( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct QuickChat
{
std::string nameAction;
int32_t icon1;
int8_t quickChatTransient;
QuickChat( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct QuickChatTransient
{
std::string textOutput;
QuickChatTransient( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct Race
{
std::string masculine;
@ -3086,6 +3138,41 @@ struct Story
Story( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct SubmarineExploration
{
std::string destination;
std::string location;
uint8_t rankReq;
uint8_t ceruleumTankReq;
uint16_t durationmin;
uint8_t distanceForSurvey;
uint32_t expReward;
SubmarineExploration( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct SubmarinePart
{
uint8_t slot;
uint8_t rank;
uint8_t components;
int16_t surveillance;
int16_t retrieval;
int16_t speed;
int16_t range;
int16_t favor;
uint8_t repairMaterials;
SubmarinePart( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct SubmarineRank
{
uint32_t expToNext;
SubmarineRank( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct SwitchTalk
{
std::vector< uint32_t > quest;
@ -3187,6 +3274,18 @@ struct TraitTransient
TraitTransient( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct TreasureHuntRank
{
uint32_t icon;
int32_t itemName;
int32_t keyItemName;
int32_t instanceMap;
uint8_t maxPartySize;
uint8_t minPartySize;
TreasureHuntRank( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
};
struct Tribe
{
std::string masculine;
@ -3623,7 +3722,9 @@ struct WorldDCGroupType
xiv::exd::Exd m_OnlineStatusDat;
xiv::exd::Exd m_OpeningDat;
xiv::exd::Exd m_OrchestrionDat;
xiv::exd::Exd m_OrchestrionCategoryDat;
xiv::exd::Exd m_OrchestrionPathDat;
xiv::exd::Exd m_OrchestrionUiparamDat;
xiv::exd::Exd m_ParamGrowDat;
xiv::exd::Exd m_PetDat;
xiv::exd::Exd m_PetActionDat;
@ -3631,6 +3732,8 @@ struct WorldDCGroupType
xiv::exd::Exd m_PlaceNameDat;
xiv::exd::Exd m_QuestDat;
xiv::exd::Exd m_QuestRewardOtherDat;
xiv::exd::Exd m_QuickChatDat;
xiv::exd::Exd m_QuickChatTransientDat;
xiv::exd::Exd m_RaceDat;
xiv::exd::Exd m_RacingChocoboItemDat;
xiv::exd::Exd m_RacingChocoboNameDat;
@ -3663,6 +3766,9 @@ struct WorldDCGroupType
xiv::exd::Exd m_StainDat;
xiv::exd::Exd m_StatusDat;
xiv::exd::Exd m_StoryDat;
xiv::exd::Exd m_SubmarineExplorationDat;
xiv::exd::Exd m_SubmarinePartDat;
xiv::exd::Exd m_SubmarineRankDat;
xiv::exd::Exd m_SwitchTalkDat;
xiv::exd::Exd m_TerritoryTypeDat;
xiv::exd::Exd m_TextCommandDat;
@ -3674,6 +3780,7 @@ struct WorldDCGroupType
xiv::exd::Exd m_TraitDat;
xiv::exd::Exd m_TraitRecastDat;
xiv::exd::Exd m_TraitTransientDat;
xiv::exd::Exd m_TreasureHuntRankDat;
xiv::exd::Exd m_TribeDat;
xiv::exd::Exd m_TripleTriadDat;
xiv::exd::Exd m_TripleTriadCardDat;
@ -3697,601 +3804,326 @@ struct WorldDCGroupType
using AchievementPtr = boost::shared_ptr< Achievement >;
AchievementPtr getAchievement( uint32_t AchievementId );
using AchievementCategoryPtr = boost::shared_ptr< AchievementCategory >;
AchievementCategoryPtr getAchievementCategory( uint32_t AchievementCategoryId );
using AchievementKindPtr = boost::shared_ptr< AchievementKind >;
AchievementKindPtr getAchievementKind( uint32_t AchievementKindId );
using ActionPtr = boost::shared_ptr< Action >;
ActionPtr getAction( uint32_t ActionId );
using ActionCategoryPtr = boost::shared_ptr< ActionCategory >;
ActionCategoryPtr getActionCategory( uint32_t ActionCategoryId );
using ActionComboRoutePtr = boost::shared_ptr< ActionComboRoute >;
ActionComboRoutePtr getActionComboRoute( uint32_t ActionComboRouteId );
using ActionIndirectionPtr = boost::shared_ptr< ActionIndirection >;
ActionIndirectionPtr getActionIndirection( uint32_t ActionIndirectionId );
using ActionProcStatusPtr = boost::shared_ptr< ActionProcStatus >;
ActionProcStatusPtr getActionProcStatus( uint32_t ActionProcStatusId );
using ActionTimelinePtr = boost::shared_ptr< ActionTimeline >;
ActionTimelinePtr getActionTimeline( uint32_t ActionTimelineId );
using ActionTransientPtr = boost::shared_ptr< ActionTransient >;
ActionTransientPtr getActionTransient( uint32_t ActionTransientId );
using AddonPtr = boost::shared_ptr< Addon >;
AddonPtr getAddon( uint32_t AddonId );
using AdventurePtr = boost::shared_ptr< Adventure >;
AdventurePtr getAdventure( uint32_t AdventureId );
using AdventureExPhasePtr = boost::shared_ptr< AdventureExPhase >;
AdventureExPhasePtr getAdventureExPhase( uint32_t AdventureExPhaseId );
using AetherCurrentPtr = boost::shared_ptr< AetherCurrent >;
AetherCurrentPtr getAetherCurrent( uint32_t AetherCurrentId );
using AetherialWheelPtr = boost::shared_ptr< AetherialWheel >;
AetherialWheelPtr getAetherialWheel( uint32_t AetherialWheelId );
using AetherytePtr = boost::shared_ptr< Aetheryte >;
AetherytePtr getAetheryte( uint32_t AetheryteId );
using AirshipExplorationLevelPtr = boost::shared_ptr< AirshipExplorationLevel >;
AirshipExplorationLevelPtr getAirshipExplorationLevel( uint32_t AirshipExplorationLevelId );
using AirshipExplorationLogPtr = boost::shared_ptr< AirshipExplorationLog >;
AirshipExplorationLogPtr getAirshipExplorationLog( uint32_t AirshipExplorationLogId );
using AirshipExplorationParamTypePtr = boost::shared_ptr< AirshipExplorationParamType >;
AirshipExplorationParamTypePtr getAirshipExplorationParamType( uint32_t AirshipExplorationParamTypeId );
using AirshipExplorationPartPtr = boost::shared_ptr< AirshipExplorationPart >;
AirshipExplorationPartPtr getAirshipExplorationPart( uint32_t AirshipExplorationPartId );
using AirshipExplorationPointPtr = boost::shared_ptr< AirshipExplorationPoint >;
AirshipExplorationPointPtr getAirshipExplorationPoint( uint32_t AirshipExplorationPointId );
using AnimaWeapon5Ptr = boost::shared_ptr< AnimaWeapon5 >;
AnimaWeapon5Ptr getAnimaWeapon5( uint32_t AnimaWeapon5Id );
using AnimaWeapon5ParamPtr = boost::shared_ptr< AnimaWeapon5Param >;
AnimaWeapon5ParamPtr getAnimaWeapon5Param( uint32_t AnimaWeapon5ParamId );
using AnimaWeapon5PatternGroupPtr = boost::shared_ptr< AnimaWeapon5PatternGroup >;
AnimaWeapon5PatternGroupPtr getAnimaWeapon5PatternGroup( uint32_t AnimaWeapon5PatternGroupId );
using AnimaWeapon5SpiritTalkPtr = boost::shared_ptr< AnimaWeapon5SpiritTalk >;
AnimaWeapon5SpiritTalkPtr getAnimaWeapon5SpiritTalk( uint32_t AnimaWeapon5SpiritTalkId );
using AnimaWeapon5SpiritTalkParamPtr = boost::shared_ptr< AnimaWeapon5SpiritTalkParam >;
AnimaWeapon5SpiritTalkParamPtr getAnimaWeapon5SpiritTalkParam( uint32_t AnimaWeapon5SpiritTalkParamId );
using AnimaWeapon5TradeItemPtr = boost::shared_ptr< AnimaWeapon5TradeItem >;
AnimaWeapon5TradeItemPtr getAnimaWeapon5TradeItem( uint32_t AnimaWeapon5TradeItemId );
using AnimaWeaponFUITalkPtr = boost::shared_ptr< AnimaWeaponFUITalk >;
AnimaWeaponFUITalkPtr getAnimaWeaponFUITalk( uint32_t AnimaWeaponFUITalkId );
using AnimaWeaponFUITalkParamPtr = boost::shared_ptr< AnimaWeaponFUITalkParam >;
AnimaWeaponFUITalkParamPtr getAnimaWeaponFUITalkParam( uint32_t AnimaWeaponFUITalkParamId );
using AnimaWeaponIconPtr = boost::shared_ptr< AnimaWeaponIcon >;
AnimaWeaponIconPtr getAnimaWeaponIcon( uint32_t AnimaWeaponIconId );
using AnimaWeaponItemPtr = boost::shared_ptr< AnimaWeaponItem >;
AnimaWeaponItemPtr getAnimaWeaponItem( uint32_t AnimaWeaponItemId );
using AquariumFishPtr = boost::shared_ptr< AquariumFish >;
AquariumFishPtr getAquariumFish( uint32_t AquariumFishId );
using AquariumWaterPtr = boost::shared_ptr< AquariumWater >;
AquariumWaterPtr getAquariumWater( uint32_t AquariumWaterId );
using AttackTypePtr = boost::shared_ptr< AttackType >;
AttackTypePtr getAttackType( uint32_t AttackTypeId );
using BalloonPtr = boost::shared_ptr< Balloon >;
BalloonPtr getBalloon( uint32_t BalloonId );
using BaseParamPtr = boost::shared_ptr< BaseParam >;
BaseParamPtr getBaseParam( uint32_t BaseParamId );
using BattleLevePtr = boost::shared_ptr< BattleLeve >;
BattleLevePtr getBattleLeve( uint32_t BattleLeveId );
using BeastRankBonusPtr = boost::shared_ptr< BeastRankBonus >;
BeastRankBonusPtr getBeastRankBonus( uint32_t BeastRankBonusId );
using BeastReputationRankPtr = boost::shared_ptr< BeastReputationRank >;
BeastReputationRankPtr getBeastReputationRank( uint32_t BeastReputationRankId );
using BeastTribePtr = boost::shared_ptr< BeastTribe >;
BeastTribePtr getBeastTribe( uint32_t BeastTribeId );
using BehaviorPtr = boost::shared_ptr< Behavior >;
BehaviorPtr getBehavior( uint32_t BehaviorId );
using BGMPtr = boost::shared_ptr< BGM >;
BGMPtr getBGM( uint32_t BGMId );
using BNpcAnnounceIconPtr = boost::shared_ptr< BNpcAnnounceIcon >;
BNpcAnnounceIconPtr getBNpcAnnounceIcon( uint32_t BNpcAnnounceIconId );
using BNpcBasePtr = boost::shared_ptr< BNpcBase >;
BNpcBasePtr getBNpcBase( uint32_t BNpcBaseId );
using BNpcCustomizePtr = boost::shared_ptr< BNpcCustomize >;
BNpcCustomizePtr getBNpcCustomize( uint32_t BNpcCustomizeId );
using BNpcNamePtr = boost::shared_ptr< BNpcName >;
BNpcNamePtr getBNpcName( uint32_t BNpcNameId );
using BuddyActionPtr = boost::shared_ptr< BuddyAction >;
BuddyActionPtr getBuddyAction( uint32_t BuddyActionId );
using BuddyEquipPtr = boost::shared_ptr< BuddyEquip >;
BuddyEquipPtr getBuddyEquip( uint32_t BuddyEquipId );
using BuddyItemPtr = boost::shared_ptr< BuddyItem >;
BuddyItemPtr getBuddyItem( uint32_t BuddyItemId );
using BuddyRankPtr = boost::shared_ptr< BuddyRank >;
BuddyRankPtr getBuddyRank( uint32_t BuddyRankId );
using BuddySkillPtr = boost::shared_ptr< BuddySkill >;
BuddySkillPtr getBuddySkill( uint32_t BuddySkillId );
using CabinetPtr = boost::shared_ptr< Cabinet >;
CabinetPtr getCabinet( uint32_t CabinetId );
using CabinetCategoryPtr = boost::shared_ptr< CabinetCategory >;
CabinetCategoryPtr getCabinetCategory( uint32_t CabinetCategoryId );
using CalendarPtr = boost::shared_ptr< Calendar >;
CalendarPtr getCalendar( uint32_t CalendarId );
using CharaMakeCustomizePtr = boost::shared_ptr< CharaMakeCustomize >;
CharaMakeCustomizePtr getCharaMakeCustomize( uint32_t CharaMakeCustomizeId );
using CharaMakeTypePtr = boost::shared_ptr< CharaMakeType >;
CharaMakeTypePtr getCharaMakeType( uint32_t CharaMakeTypeId );
using ChocoboRacePtr = boost::shared_ptr< ChocoboRace >;
ChocoboRacePtr getChocoboRace( uint32_t ChocoboRaceId );
using ChocoboRaceAbilityPtr = boost::shared_ptr< ChocoboRaceAbility >;
ChocoboRaceAbilityPtr getChocoboRaceAbility( uint32_t ChocoboRaceAbilityId );
using ChocoboRaceAbilityTypePtr = boost::shared_ptr< ChocoboRaceAbilityType >;
ChocoboRaceAbilityTypePtr getChocoboRaceAbilityType( uint32_t ChocoboRaceAbilityTypeId );
using ChocoboRaceItemPtr = boost::shared_ptr< ChocoboRaceItem >;
ChocoboRaceItemPtr getChocoboRaceItem( uint32_t ChocoboRaceItemId );
using ChocoboRaceRankPtr = boost::shared_ptr< ChocoboRaceRank >;
ChocoboRaceRankPtr getChocoboRaceRank( uint32_t ChocoboRaceRankId );
using ChocoboRaceStatusPtr = boost::shared_ptr< ChocoboRaceStatus >;
ChocoboRaceStatusPtr getChocoboRaceStatus( uint32_t ChocoboRaceStatusId );
using ChocoboRaceTerritoryPtr = boost::shared_ptr< ChocoboRaceTerritory >;
ChocoboRaceTerritoryPtr getChocoboRaceTerritory( uint32_t ChocoboRaceTerritoryId );
using ChocoboTaxiStandPtr = boost::shared_ptr< ChocoboTaxiStand >;
ChocoboTaxiStandPtr getChocoboTaxiStand( uint32_t ChocoboTaxiStandId );
using ClassJobPtr = boost::shared_ptr< ClassJob >;
ClassJobPtr getClassJob( uint32_t ClassJobId );
using ClassJobCategoryPtr = boost::shared_ptr< ClassJobCategory >;
ClassJobCategoryPtr getClassJobCategory( uint32_t ClassJobCategoryId );
using CompanionPtr = boost::shared_ptr< Companion >;
CompanionPtr getCompanion( uint32_t CompanionId );
using CompanionMovePtr = boost::shared_ptr< CompanionMove >;
CompanionMovePtr getCompanionMove( uint32_t CompanionMoveId );
using CompanionTransientPtr = boost::shared_ptr< CompanionTransient >;
CompanionTransientPtr getCompanionTransient( uint32_t CompanionTransientId );
using CompanyActionPtr = boost::shared_ptr< CompanyAction >;
CompanyActionPtr getCompanyAction( uint32_t CompanyActionId );
using CompanyCraftDraftPtr = boost::shared_ptr< CompanyCraftDraft >;
CompanyCraftDraftPtr getCompanyCraftDraft( uint32_t CompanyCraftDraftId );
using CompanyCraftDraftCategoryPtr = boost::shared_ptr< CompanyCraftDraftCategory >;
CompanyCraftDraftCategoryPtr getCompanyCraftDraftCategory( uint32_t CompanyCraftDraftCategoryId );
using CompanyCraftManufactoryStatePtr = boost::shared_ptr< CompanyCraftManufactoryState >;
CompanyCraftManufactoryStatePtr getCompanyCraftManufactoryState( uint32_t CompanyCraftManufactoryStateId );
using CompanyCraftPartPtr = boost::shared_ptr< CompanyCraftPart >;
CompanyCraftPartPtr getCompanyCraftPart( uint32_t CompanyCraftPartId );
using CompanyCraftProcessPtr = boost::shared_ptr< CompanyCraftProcess >;
CompanyCraftProcessPtr getCompanyCraftProcess( uint32_t CompanyCraftProcessId );
using CompanyCraftSequencePtr = boost::shared_ptr< CompanyCraftSequence >;
CompanyCraftSequencePtr getCompanyCraftSequence( uint32_t CompanyCraftSequenceId );
using CompanyCraftSupplyItemPtr = boost::shared_ptr< CompanyCraftSupplyItem >;
CompanyCraftSupplyItemPtr getCompanyCraftSupplyItem( uint32_t CompanyCraftSupplyItemId );
using CompanyCraftTypePtr = boost::shared_ptr< CompanyCraftType >;
CompanyCraftTypePtr getCompanyCraftType( uint32_t CompanyCraftTypeId );
using CompleteJournalPtr = boost::shared_ptr< CompleteJournal >;
CompleteJournalPtr getCompleteJournal( uint32_t CompleteJournalId );
using CompleteJournalCategoryPtr = boost::shared_ptr< CompleteJournalCategory >;
CompleteJournalCategoryPtr getCompleteJournalCategory( uint32_t CompleteJournalCategoryId );
using ContentExActionPtr = boost::shared_ptr< ContentExAction >;
ContentExActionPtr getContentExAction( uint32_t ContentExActionId );
using ContentFinderConditionPtr = boost::shared_ptr< ContentFinderCondition >;
ContentFinderConditionPtr getContentFinderCondition( uint32_t ContentFinderConditionId );
using ContentFinderConditionTransientPtr = boost::shared_ptr< ContentFinderConditionTransient >;
ContentFinderConditionTransientPtr getContentFinderConditionTransient( uint32_t ContentFinderConditionTransientId );
using ContentMemberTypePtr = boost::shared_ptr< ContentMemberType >;
ContentMemberTypePtr getContentMemberType( uint32_t ContentMemberTypeId );
using ContentRoulettePtr = boost::shared_ptr< ContentRoulette >;
ContentRoulettePtr getContentRoulette( uint32_t ContentRouletteId );
using ContentTypePtr = boost::shared_ptr< ContentType >;
ContentTypePtr getContentType( uint32_t ContentTypeId );
using CraftActionPtr = boost::shared_ptr< CraftAction >;
CraftActionPtr getCraftAction( uint32_t CraftActionId );
using CraftLevePtr = boost::shared_ptr< CraftLeve >;
CraftLevePtr getCraftLeve( uint32_t CraftLeveId );
using CraftTypePtr = boost::shared_ptr< CraftType >;
CraftTypePtr getCraftType( uint32_t CraftTypeId );
using CurrencyPtr = boost::shared_ptr< Currency >;
CurrencyPtr getCurrency( uint32_t CurrencyId );
using CustomTalkPtr = boost::shared_ptr< CustomTalk >;
CustomTalkPtr getCustomTalk( uint32_t CustomTalkId );
using CutscenePtr = boost::shared_ptr< Cutscene >;
CutscenePtr getCutscene( uint32_t CutsceneId );
using CutScreenImagePtr = boost::shared_ptr< CutScreenImage >;
CutScreenImagePtr getCutScreenImage( uint32_t CutScreenImageId );
using DailySupplyItemPtr = boost::shared_ptr< DailySupplyItem >;
DailySupplyItemPtr getDailySupplyItem( uint32_t DailySupplyItemId );
using DeepDungeonBanPtr = boost::shared_ptr< DeepDungeonBan >;
DeepDungeonBanPtr getDeepDungeonBan( uint32_t DeepDungeonBanId );
using DeepDungeonDangerPtr = boost::shared_ptr< DeepDungeonDanger >;
DeepDungeonDangerPtr getDeepDungeonDanger( uint32_t DeepDungeonDangerId );
using DeepDungeonEquipmentPtr = boost::shared_ptr< DeepDungeonEquipment >;
DeepDungeonEquipmentPtr getDeepDungeonEquipment( uint32_t DeepDungeonEquipmentId );
using DeepDungeonFloorEffectUIPtr = boost::shared_ptr< DeepDungeonFloorEffectUI >;
DeepDungeonFloorEffectUIPtr getDeepDungeonFloorEffectUI( uint32_t DeepDungeonFloorEffectUIId );
using DeepDungeonItemPtr = boost::shared_ptr< DeepDungeonItem >;
DeepDungeonItemPtr getDeepDungeonItem( uint32_t DeepDungeonItemId );
using DeepDungeonStatusPtr = boost::shared_ptr< DeepDungeonStatus >;
DeepDungeonStatusPtr getDeepDungeonStatus( uint32_t DeepDungeonStatusId );
using DefaultTalkPtr = boost::shared_ptr< DefaultTalk >;
DefaultTalkPtr getDefaultTalk( uint32_t DefaultTalkId );
using DeliveryQuestPtr = boost::shared_ptr< DeliveryQuest >;
DeliveryQuestPtr getDeliveryQuest( uint32_t DeliveryQuestId );
using DisposalShopPtr = boost::shared_ptr< DisposalShop >;
DisposalShopPtr getDisposalShop( uint32_t DisposalShopId );
using DisposalShopFilterTypePtr = boost::shared_ptr< DisposalShopFilterType >;
DisposalShopFilterTypePtr getDisposalShopFilterType( uint32_t DisposalShopFilterTypeId );
using DisposalShopItemPtr = boost::shared_ptr< DisposalShopItem >;
DisposalShopItemPtr getDisposalShopItem( uint32_t DisposalShopItemId );
using DpsChallengePtr = boost::shared_ptr< DpsChallenge >;
DpsChallengePtr getDpsChallenge( uint32_t DpsChallengeId );
using DpsChallengeOfficerPtr = boost::shared_ptr< DpsChallengeOfficer >;
DpsChallengeOfficerPtr getDpsChallengeOfficer( uint32_t DpsChallengeOfficerId );
using DpsChallengeTransientPtr = boost::shared_ptr< DpsChallengeTransient >;
DpsChallengeTransientPtr getDpsChallengeTransient( uint32_t DpsChallengeTransientId );
using EmotePtr = boost::shared_ptr< Emote >;
EmotePtr getEmote( uint32_t EmoteId );
using EmoteCategoryPtr = boost::shared_ptr< EmoteCategory >;
EmoteCategoryPtr getEmoteCategory( uint32_t EmoteCategoryId );
using ENpcBasePtr = boost::shared_ptr< ENpcBase >;
ENpcBasePtr getENpcBase( uint32_t ENpcBaseId );
using ENpcResidentPtr = boost::shared_ptr< ENpcResident >;
ENpcResidentPtr getENpcResident( uint32_t ENpcResidentId );
using EObjPtr = boost::shared_ptr< EObj >;
EObjPtr getEObj( uint32_t EObjId );
using EquipRaceCategoryPtr = boost::shared_ptr< EquipRaceCategory >;
EquipRaceCategoryPtr getEquipRaceCategory( uint32_t EquipRaceCategoryId );
using EquipSlotCategoryPtr = boost::shared_ptr< EquipSlotCategory >;
EquipSlotCategoryPtr getEquipSlotCategory( uint32_t EquipSlotCategoryId );
using EventActionPtr = boost::shared_ptr< EventAction >;
EventActionPtr getEventAction( uint32_t EventActionId );
using EventIconPriorityPtr = boost::shared_ptr< EventIconPriority >;
EventIconPriorityPtr getEventIconPriority( uint32_t EventIconPriorityId );
using EventIconTypePtr = boost::shared_ptr< EventIconType >;
EventIconTypePtr getEventIconType( uint32_t EventIconTypeId );
using EventItemPtr = boost::shared_ptr< EventItem >;
EventItemPtr getEventItem( uint32_t EventItemId );
using EventItemHelpPtr = boost::shared_ptr< EventItemHelp >;
EventItemHelpPtr getEventItemHelp( uint32_t EventItemHelpId );
using ExVersionPtr = boost::shared_ptr< ExVersion >;
ExVersionPtr getExVersion( uint32_t ExVersionId );
using FatePtr = boost::shared_ptr< Fate >;
FatePtr getFate( uint32_t FateId );
using FCActivityPtr = boost::shared_ptr< FCActivity >;
FCActivityPtr getFCActivity( uint32_t FCActivityId );
using FCActivityCategoryPtr = boost::shared_ptr< FCActivityCategory >;
FCActivityCategoryPtr getFCActivityCategory( uint32_t FCActivityCategoryId );
using FCAuthorityPtr = boost::shared_ptr< FCAuthority >;
FCAuthorityPtr getFCAuthority( uint32_t FCAuthorityId );
using FCAuthorityCategoryPtr = boost::shared_ptr< FCAuthorityCategory >;
FCAuthorityCategoryPtr getFCAuthorityCategory( uint32_t FCAuthorityCategoryId );
using FCChestNamePtr = boost::shared_ptr< FCChestName >;
FCChestNamePtr getFCChestName( uint32_t FCChestNameId );
using FccShopPtr = boost::shared_ptr< FccShop >;
FccShopPtr getFccShop( uint32_t FccShopId );
using FCHierarchyPtr = boost::shared_ptr< FCHierarchy >;
FCHierarchyPtr getFCHierarchy( uint32_t FCHierarchyId );
using FCProfilePtr = boost::shared_ptr< FCProfile >;
FCProfilePtr getFCProfile( uint32_t FCProfileId );
using FCReputationPtr = boost::shared_ptr< FCReputation >;
FCReputationPtr getFCReputation( uint32_t FCReputationId );
using FCRightsPtr = boost::shared_ptr< FCRights >;
FCRightsPtr getFCRights( uint32_t FCRightsId );
using FishingSpotPtr = boost::shared_ptr< FishingSpot >;
FishingSpotPtr getFishingSpot( uint32_t FishingSpotId );
using FishParameterPtr = boost::shared_ptr< FishParameter >;
FishParameterPtr getFishParameter( uint32_t FishParameterId );
using GardeningSeedPtr = boost::shared_ptr< GardeningSeed >;
GardeningSeedPtr getGardeningSeed( uint32_t GardeningSeedId );
using GatheringConditionPtr = boost::shared_ptr< GatheringCondition >;
GatheringConditionPtr getGatheringCondition( uint32_t GatheringConditionId );
using GatheringExpPtr = boost::shared_ptr< GatheringExp >;
GatheringExpPtr getGatheringExp( uint32_t GatheringExpId );
using GatheringItemPtr = boost::shared_ptr< GatheringItem >;
GatheringItemPtr getGatheringItem( uint32_t GatheringItemId );
using GatheringItemLevelConvertTablePtr = boost::shared_ptr< GatheringItemLevelConvertTable >;
GatheringItemLevelConvertTablePtr getGatheringItemLevelConvertTable( uint32_t GatheringItemLevelConvertTableId );
using GatheringItemPointPtr = boost::shared_ptr< GatheringItemPoint >;
GatheringItemPointPtr getGatheringItemPoint( uint32_t GatheringItemPointId );
using GatheringNotebookListPtr = boost::shared_ptr< GatheringNotebookList >;
GatheringNotebookListPtr getGatheringNotebookList( uint32_t GatheringNotebookListId );
using GatheringPointPtr = boost::shared_ptr< GatheringPoint >;
GatheringPointPtr getGatheringPoint( uint32_t GatheringPointId );
using GatheringPointBasePtr = boost::shared_ptr< GatheringPointBase >;
GatheringPointBasePtr getGatheringPointBase( uint32_t GatheringPointBaseId );
using GatheringPointBonusPtr = boost::shared_ptr< GatheringPointBonus >;
GatheringPointBonusPtr getGatheringPointBonus( uint32_t GatheringPointBonusId );
using GatheringPointBonusTypePtr = boost::shared_ptr< GatheringPointBonusType >;
GatheringPointBonusTypePtr getGatheringPointBonusType( uint32_t GatheringPointBonusTypeId );
using GatheringPointNamePtr = boost::shared_ptr< GatheringPointName >;
GatheringPointNamePtr getGatheringPointName( uint32_t GatheringPointNameId );
using GatheringSubCategoryPtr = boost::shared_ptr< GatheringSubCategory >;
GatheringSubCategoryPtr getGatheringSubCategory( uint32_t GatheringSubCategoryId );
using GatheringTypePtr = boost::shared_ptr< GatheringType >;
GatheringTypePtr getGatheringType( uint32_t GatheringTypeId );
using GcArmyExpeditionPtr = boost::shared_ptr< GcArmyExpedition >;
GcArmyExpeditionPtr getGcArmyExpedition( uint32_t GcArmyExpeditionId );
using GcArmyExpeditionMemberBonusPtr = boost::shared_ptr< GcArmyExpeditionMemberBonus >;
GcArmyExpeditionMemberBonusPtr getGcArmyExpeditionMemberBonus( uint32_t GcArmyExpeditionMemberBonusId );
using GcArmyExpeditionTypePtr = boost::shared_ptr< GcArmyExpeditionType >;
GcArmyExpeditionTypePtr getGcArmyExpeditionType( uint32_t GcArmyExpeditionTypeId );
using GcArmyMemberGrowPtr = boost::shared_ptr< GcArmyMemberGrow >;
GcArmyMemberGrowPtr getGcArmyMemberGrow( uint32_t GcArmyMemberGrowId );
using GcArmyTrainingPtr = boost::shared_ptr< GcArmyTraining >;
GcArmyTrainingPtr getGcArmyTraining( uint32_t GcArmyTrainingId );
using GCRankGridaniaFemaleTextPtr = boost::shared_ptr< GCRankGridaniaFemaleText >;
GCRankGridaniaFemaleTextPtr getGCRankGridaniaFemaleText( uint32_t GCRankGridaniaFemaleTextId );
using GCRankGridaniaMaleTextPtr = boost::shared_ptr< GCRankGridaniaMaleText >;
GCRankGridaniaMaleTextPtr getGCRankGridaniaMaleText( uint32_t GCRankGridaniaMaleTextId );
using GCRankLimsaFemaleTextPtr = boost::shared_ptr< GCRankLimsaFemaleText >;
GCRankLimsaFemaleTextPtr getGCRankLimsaFemaleText( uint32_t GCRankLimsaFemaleTextId );
using GCRankLimsaMaleTextPtr = boost::shared_ptr< GCRankLimsaMaleText >;
GCRankLimsaMaleTextPtr getGCRankLimsaMaleText( uint32_t GCRankLimsaMaleTextId );
using GCRankUldahFemaleTextPtr = boost::shared_ptr< GCRankUldahFemaleText >;
GCRankUldahFemaleTextPtr getGCRankUldahFemaleText( uint32_t GCRankUldahFemaleTextId );
using GCRankUldahMaleTextPtr = boost::shared_ptr< GCRankUldahMaleText >;
GCRankUldahMaleTextPtr getGCRankUldahMaleText( uint32_t GCRankUldahMaleTextId );
using GCScripShopCategoryPtr = boost::shared_ptr< GCScripShopCategory >;
GCScripShopCategoryPtr getGCScripShopCategory( uint32_t GCScripShopCategoryId );
using GCScripShopItemPtr = boost::shared_ptr< GCScripShopItem >;
GCScripShopItemPtr getGCScripShopItem( uint32_t GCScripShopItemId );
using GCShopPtr = boost::shared_ptr< GCShop >;
GCShopPtr getGCShop( uint32_t GCShopId );
using GCShopItemCategoryPtr = boost::shared_ptr< GCShopItemCategory >;
GCShopItemCategoryPtr getGCShopItemCategory( uint32_t GCShopItemCategoryId );
using GCSupplyDutyPtr = boost::shared_ptr< GCSupplyDuty >;
GCSupplyDutyPtr getGCSupplyDuty( uint32_t GCSupplyDutyId );
using GCSupplyDutyRewardPtr = boost::shared_ptr< GCSupplyDutyReward >;
GCSupplyDutyRewardPtr getGCSupplyDutyReward( uint32_t GCSupplyDutyRewardId );
using GeneralActionPtr = boost::shared_ptr< GeneralAction >;
GeneralActionPtr getGeneralAction( uint32_t GeneralActionId );
using GilShopPtr = boost::shared_ptr< GilShop >;
GilShopPtr getGilShop( uint32_t GilShopId );
using GilShopItemPtr = boost::shared_ptr< GilShopItem >;
GilShopItemPtr getGilShopItem( uint32_t GilShopItemId );
using GoldSaucerTextDataPtr = boost::shared_ptr< GoldSaucerTextData >;
GoldSaucerTextDataPtr getGoldSaucerTextData( uint32_t GoldSaucerTextDataId );
using GrandCompanyPtr = boost::shared_ptr< GrandCompany >;
GrandCompanyPtr getGrandCompany( uint32_t GrandCompanyId );
using GrandCompanyRankPtr = boost::shared_ptr< GrandCompanyRank >;
GrandCompanyRankPtr getGrandCompanyRank( uint32_t GrandCompanyRankId );
using GuardianDeityPtr = boost::shared_ptr< GuardianDeity >;
GuardianDeityPtr getGuardianDeity( uint32_t GuardianDeityId );
using GuildleveAssignmentPtr = boost::shared_ptr< GuildleveAssignment >;
GuildleveAssignmentPtr getGuildleveAssignment( uint32_t GuildleveAssignmentId );
using GuildOrderGuidePtr = boost::shared_ptr< GuildOrderGuide >;
GuildOrderGuidePtr getGuildOrderGuide( uint32_t GuildOrderGuideId );
using GuildOrderOfficerPtr = boost::shared_ptr< GuildOrderOfficer >;
GuildOrderOfficerPtr getGuildOrderOfficer( uint32_t GuildOrderOfficerId );
using HouseRetainerPosePtr = boost::shared_ptr< HouseRetainerPose >;
HouseRetainerPosePtr getHouseRetainerPose( uint32_t HouseRetainerPoseId );
using HousingFurniturePtr = boost::shared_ptr< HousingFurniture >;
HousingFurniturePtr getHousingFurniture( uint32_t HousingFurnitureId );
using HousingYardObjectPtr = boost::shared_ptr< HousingYardObject >;
HousingYardObjectPtr getHousingYardObject( uint32_t HousingYardObjectId );
using InstanceContentPtr = boost::shared_ptr< InstanceContent >;
InstanceContentPtr getInstanceContent( uint32_t InstanceContentId );
using InstanceContentBuffPtr = boost::shared_ptr< InstanceContentBuff >;
InstanceContentBuffPtr getInstanceContentBuff( uint32_t InstanceContentBuffId );
using InstanceContentTextDataPtr = boost::shared_ptr< InstanceContentTextData >;
InstanceContentTextDataPtr getInstanceContentTextData( uint32_t InstanceContentTextDataId );
using InstanceContentTypePtr = boost::shared_ptr< InstanceContentType >;
InstanceContentTypePtr getInstanceContentType( uint32_t InstanceContentTypeId );
using ItemPtr = boost::shared_ptr< Item >;
ItemPtr getItem( uint32_t ItemId );
using ItemActionPtr = boost::shared_ptr< ItemAction >;
ItemActionPtr getItemAction( uint32_t ItemActionId );
using ItemFoodPtr = boost::shared_ptr< ItemFood >;
ItemFoodPtr getItemFood( uint32_t ItemFoodId );
using ItemSearchCategoryPtr = boost::shared_ptr< ItemSearchCategory >;
ItemSearchCategoryPtr getItemSearchCategory( uint32_t ItemSearchCategoryId );
using ItemSeriesPtr = boost::shared_ptr< ItemSeries >;
ItemSeriesPtr getItemSeries( uint32_t ItemSeriesId );
using ItemSpecialBonusPtr = boost::shared_ptr< ItemSpecialBonus >;
ItemSpecialBonusPtr getItemSpecialBonus( uint32_t ItemSpecialBonusId );
using ItemUICategoryPtr = boost::shared_ptr< ItemUICategory >;
ItemUICategoryPtr getItemUICategory( uint32_t ItemUICategoryId );
using JournalCategoryPtr = boost::shared_ptr< JournalCategory >;
JournalCategoryPtr getJournalCategory( uint32_t JournalCategoryId );
using JournalGenrePtr = boost::shared_ptr< JournalGenre >;
JournalGenrePtr getJournalGenre( uint32_t JournalGenreId );
using JournalSectionPtr = boost::shared_ptr< JournalSection >;
JournalSectionPtr getJournalSection( uint32_t JournalSectionId );
using LevePtr = boost::shared_ptr< Leve >;
LevePtr getLeve( uint32_t LeveId );
using LeveAssignmentTypePtr = boost::shared_ptr< LeveAssignmentType >;
LeveAssignmentTypePtr getLeveAssignmentType( uint32_t LeveAssignmentTypeId );
using LeveClientPtr = boost::shared_ptr< LeveClient >;
LeveClientPtr getLeveClient( uint32_t LeveClientId );
using LevelPtr = boost::shared_ptr< Level >;
LevelPtr getLevel( uint32_t LevelId );
using LeveRewardItemPtr = boost::shared_ptr< LeveRewardItem >;
LeveRewardItemPtr getLeveRewardItem( uint32_t LeveRewardItemId );
using LeveRewardItemGroupPtr = boost::shared_ptr< LeveRewardItemGroup >;
LeveRewardItemGroupPtr getLeveRewardItemGroup( uint32_t LeveRewardItemGroupId );
using LeveVfxPtr = boost::shared_ptr< LeveVfx >;
LeveVfxPtr getLeveVfx( uint32_t LeveVfxId );
using LogFilterPtr = boost::shared_ptr< LogFilter >;
LogFilterPtr getLogFilter( uint32_t LogFilterId );
using LogKindPtr = boost::shared_ptr< LogKind >;
LogKindPtr getLogKind( uint32_t LogKindId );
using LogKindCategoryTextPtr = boost::shared_ptr< LogKindCategoryText >;
LogKindCategoryTextPtr getLogKindCategoryText( uint32_t LogKindCategoryTextId );
using LogMessagePtr = boost::shared_ptr< LogMessage >;
LogMessagePtr getLogMessage( uint32_t LogMessageId );
using MacroIconPtr = boost::shared_ptr< MacroIcon >;
MacroIconPtr getMacroIcon( uint32_t MacroIconId );
using MacroIconRedirectOldPtr = boost::shared_ptr< MacroIconRedirectOld >;
MacroIconRedirectOldPtr getMacroIconRedirectOld( uint32_t MacroIconRedirectOldId );
using MainCommandPtr = boost::shared_ptr< MainCommand >;
MainCommandPtr getMainCommand( uint32_t MainCommandId );
using MainCommandCategoryPtr = boost::shared_ptr< MainCommandCategory >;
MainCommandCategoryPtr getMainCommandCategory( uint32_t MainCommandCategoryId );
using MapPtr = boost::shared_ptr< Map >;
MapPtr getMap( uint32_t MapId );
using MapMarkerPtr = boost::shared_ptr< MapMarker >;
MapMarkerPtr getMapMarker( uint32_t MapMarkerId );
using MapSymbolPtr = boost::shared_ptr< MapSymbol >;
MapSymbolPtr getMapSymbol( uint32_t MapSymbolId );
using MasterpieceSupplyDutyPtr = boost::shared_ptr< MasterpieceSupplyDuty >;
MasterpieceSupplyDutyPtr getMasterpieceSupplyDuty( uint32_t MasterpieceSupplyDutyId );
using MasterpieceSupplyMultiplierPtr = boost::shared_ptr< MasterpieceSupplyMultiplier >;
MasterpieceSupplyMultiplierPtr getMasterpieceSupplyMultiplier( uint32_t MasterpieceSupplyMultiplierId );
using MateriaPtr = boost::shared_ptr< Materia >;
MateriaPtr getMateria( uint32_t MateriaId );
using MinionRacePtr = boost::shared_ptr< MinionRace >;
MinionRacePtr getMinionRace( uint32_t MinionRaceId );
using MinionRulesPtr = boost::shared_ptr< MinionRules >;
MinionRulesPtr getMinionRules( uint32_t MinionRulesId );
using MinionSkillTypePtr = boost::shared_ptr< MinionSkillType >;
MinionSkillTypePtr getMinionSkillType( uint32_t MinionSkillTypeId );
using MobHuntTargetPtr = boost::shared_ptr< MobHuntTarget >;
MobHuntTargetPtr getMobHuntTarget( uint32_t MobHuntTargetId );
using ModelCharaPtr = boost::shared_ptr< ModelChara >;
ModelCharaPtr getModelChara( uint32_t ModelCharaId );
using MonsterNotePtr = boost::shared_ptr< MonsterNote >;
MonsterNotePtr getMonsterNote( uint32_t MonsterNoteId );
using MonsterNoteTargetPtr = boost::shared_ptr< MonsterNoteTarget >;
MonsterNoteTargetPtr getMonsterNoteTarget( uint32_t MonsterNoteTargetId );
using MountPtr = boost::shared_ptr< Mount >;
MountPtr getMount( uint32_t MountId );
using MountActionPtr = boost::shared_ptr< MountAction >;
MountActionPtr getMountAction( uint32_t MountActionId );
using NpcEquipPtr = boost::shared_ptr< NpcEquip >;
NpcEquipPtr getNpcEquip( uint32_t NpcEquipId );
using OmenPtr = boost::shared_ptr< Omen >;
OmenPtr getOmen( uint32_t OmenId );
using OnlineStatusPtr = boost::shared_ptr< OnlineStatus >;
OnlineStatusPtr getOnlineStatus( uint32_t OnlineStatusId );
using OpeningPtr = boost::shared_ptr< Opening >;
OpeningPtr getOpening( uint32_t OpeningId );
using OrchestrionPtr = boost::shared_ptr< Orchestrion >;
OrchestrionPtr getOrchestrion( uint32_t OrchestrionId );
using OrchestrionCategoryPtr = boost::shared_ptr< OrchestrionCategory >;
using OrchestrionPathPtr = boost::shared_ptr< OrchestrionPath >;
OrchestrionPathPtr getOrchestrionPath( uint32_t OrchestrionPathId );
using OrchestrionUiparamPtr = boost::shared_ptr< OrchestrionUiparam >;
using ParamGrowPtr = boost::shared_ptr< ParamGrow >;
ParamGrowPtr getParamGrow( uint32_t ParamGrowId );
using PetPtr = boost::shared_ptr< Pet >;
PetPtr getPet( uint32_t PetId );
using PetActionPtr = boost::shared_ptr< PetAction >;
PetActionPtr getPetAction( uint32_t PetActionId );
using PicturePtr = boost::shared_ptr< Picture >;
PicturePtr getPicture( uint32_t PictureId );
using PlaceNamePtr = boost::shared_ptr< PlaceName >;
PlaceNamePtr getPlaceName( uint32_t PlaceNameId );
using QuestPtr = boost::shared_ptr< Quest >;
QuestPtr getQuest( uint32_t QuestId );
using QuestRewardOtherPtr = boost::shared_ptr< QuestRewardOther >;
QuestRewardOtherPtr getQuestRewardOther( uint32_t QuestRewardOtherId );
using QuickChatPtr = boost::shared_ptr< QuickChat >;
using QuickChatTransientPtr = boost::shared_ptr< QuickChatTransient >;
using RacePtr = boost::shared_ptr< Race >;
RacePtr getRace( uint32_t RaceId );
using RacingChocoboItemPtr = boost::shared_ptr< RacingChocoboItem >;
RacingChocoboItemPtr getRacingChocoboItem( uint32_t RacingChocoboItemId );
using RacingChocoboNamePtr = boost::shared_ptr< RacingChocoboName >;
RacingChocoboNamePtr getRacingChocoboName( uint32_t RacingChocoboNameId );
using RacingChocoboNameCategoryPtr = boost::shared_ptr< RacingChocoboNameCategory >;
RacingChocoboNameCategoryPtr getRacingChocoboNameCategory( uint32_t RacingChocoboNameCategoryId );
using RacingChocoboNameInfoPtr = boost::shared_ptr< RacingChocoboNameInfo >;
RacingChocoboNameInfoPtr getRacingChocoboNameInfo( uint32_t RacingChocoboNameInfoId );
using RacingChocoboParamPtr = boost::shared_ptr< RacingChocoboParam >;
RacingChocoboParamPtr getRacingChocoboParam( uint32_t RacingChocoboParamId );
using RecipePtr = boost::shared_ptr< Recipe >;
RecipePtr getRecipe( uint32_t RecipeId );
using RecipeElementPtr = boost::shared_ptr< RecipeElement >;
RecipeElementPtr getRecipeElement( uint32_t RecipeElementId );
using RecipeLevelTablePtr = boost::shared_ptr< RecipeLevelTable >;
RecipeLevelTablePtr getRecipeLevelTable( uint32_t RecipeLevelTableId );
using RecipeNotebookListPtr = boost::shared_ptr< RecipeNotebookList >;
RecipeNotebookListPtr getRecipeNotebookList( uint32_t RecipeNotebookListId );
using RelicPtr = boost::shared_ptr< Relic >;
RelicPtr getRelic( uint32_t RelicId );
using Relic3Ptr = boost::shared_ptr< Relic3 >;
Relic3Ptr getRelic3( uint32_t Relic3Id );
using RelicItemPtr = boost::shared_ptr< RelicItem >;
RelicItemPtr getRelicItem( uint32_t RelicItemId );
using RelicNotePtr = boost::shared_ptr< RelicNote >;
RelicNotePtr getRelicNote( uint32_t RelicNoteId );
using RelicNoteCategoryPtr = boost::shared_ptr< RelicNoteCategory >;
RelicNoteCategoryPtr getRelicNoteCategory( uint32_t RelicNoteCategoryId );
using RetainerTaskPtr = boost::shared_ptr< RetainerTask >;
RetainerTaskPtr getRetainerTask( uint32_t RetainerTaskId );
using RetainerTaskNormalPtr = boost::shared_ptr< RetainerTaskNormal >;
RetainerTaskNormalPtr getRetainerTaskNormal( uint32_t RetainerTaskNormalId );
using RetainerTaskParameterPtr = boost::shared_ptr< RetainerTaskParameter >;
RetainerTaskParameterPtr getRetainerTaskParameter( uint32_t RetainerTaskParameterId );
using RetainerTaskRandomPtr = boost::shared_ptr< RetainerTaskRandom >;
RetainerTaskRandomPtr getRetainerTaskRandom( uint32_t RetainerTaskRandomId );
using SalvagePtr = boost::shared_ptr< Salvage >;
SalvagePtr getSalvage( uint32_t SalvageId );
using SatisfactionNpcPtr = boost::shared_ptr< SatisfactionNpc >;
SatisfactionNpcPtr getSatisfactionNpc( uint32_t SatisfactionNpcId );
using SatisfactionSupplyPtr = boost::shared_ptr< SatisfactionSupply >;
SatisfactionSupplyPtr getSatisfactionSupply( uint32_t SatisfactionSupplyId );
using SatisfactionSupplyRewardPtr = boost::shared_ptr< SatisfactionSupplyReward >;
SatisfactionSupplyRewardPtr getSatisfactionSupplyReward( uint32_t SatisfactionSupplyRewardId );
using ScreenImagePtr = boost::shared_ptr< ScreenImage >;
ScreenImagePtr getScreenImage( uint32_t ScreenImageId );
using SecretRecipeBookPtr = boost::shared_ptr< SecretRecipeBook >;
SecretRecipeBookPtr getSecretRecipeBook( uint32_t SecretRecipeBookId );
using SpearfishingItemPtr = boost::shared_ptr< SpearfishingItem >;
SpearfishingItemPtr getSpearfishingItem( uint32_t SpearfishingItemId );
using SpearfishingNotebookPtr = boost::shared_ptr< SpearfishingNotebook >;
SpearfishingNotebookPtr getSpearfishingNotebook( uint32_t SpearfishingNotebookId );
using SpecialShopPtr = boost::shared_ptr< SpecialShop >;
SpecialShopPtr getSpecialShop( uint32_t SpecialShopId );
using SpecialShopItemCategoryPtr = boost::shared_ptr< SpecialShopItemCategory >;
SpecialShopItemCategoryPtr getSpecialShopItemCategory( uint32_t SpecialShopItemCategoryId );
using StainPtr = boost::shared_ptr< Stain >;
StainPtr getStain( uint32_t StainId );
using StatusPtr = boost::shared_ptr< Status >;
StatusPtr getStatus( uint32_t StatusId );
using StoryPtr = boost::shared_ptr< Story >;
StoryPtr getStory( uint32_t StoryId );
using SubmarineExplorationPtr = boost::shared_ptr< SubmarineExploration >;
using SubmarinePartPtr = boost::shared_ptr< SubmarinePart >;
using SubmarineRankPtr = boost::shared_ptr< SubmarineRank >;
using SwitchTalkPtr = boost::shared_ptr< SwitchTalk >;
SwitchTalkPtr getSwitchTalk( uint32_t SwitchTalkId );
using TerritoryTypePtr = boost::shared_ptr< TerritoryType >;
TerritoryTypePtr getTerritoryType( uint32_t TerritoryTypeId );
using TextCommandPtr = boost::shared_ptr< TextCommand >;
TextCommandPtr getTextCommand( uint32_t TextCommandId );
using TitlePtr = boost::shared_ptr< Title >;
TitlePtr getTitle( uint32_t TitleId );
using TomestonesPtr = boost::shared_ptr< Tomestones >;
TomestonesPtr getTomestones( uint32_t TomestonesId );
using TomestonesItemPtr = boost::shared_ptr< TomestonesItem >;
TomestonesItemPtr getTomestonesItem( uint32_t TomestonesItemId );
using TopicSelectPtr = boost::shared_ptr< TopicSelect >;
TopicSelectPtr getTopicSelect( uint32_t TopicSelectId );
using TownPtr = boost::shared_ptr< Town >;
TownPtr getTown( uint32_t TownId );
using TraitPtr = boost::shared_ptr< Trait >;
TraitPtr getTrait( uint32_t TraitId );
using TraitRecastPtr = boost::shared_ptr< TraitRecast >;
TraitRecastPtr getTraitRecast( uint32_t TraitRecastId );
using TraitTransientPtr = boost::shared_ptr< TraitTransient >;
TraitTransientPtr getTraitTransient( uint32_t TraitTransientId );
using TreasureHuntRankPtr = boost::shared_ptr< TreasureHuntRank >;
using TribePtr = boost::shared_ptr< Tribe >;
TribePtr getTribe( uint32_t TribeId );
using TripleTriadPtr = boost::shared_ptr< TripleTriad >;
TripleTriadPtr getTripleTriad( uint32_t TripleTriadId );
using TripleTriadCardPtr = boost::shared_ptr< TripleTriadCard >;
TripleTriadCardPtr getTripleTriadCard( uint32_t TripleTriadCardId );
using TripleTriadCardRarityPtr = boost::shared_ptr< TripleTriadCardRarity >;
TripleTriadCardRarityPtr getTripleTriadCardRarity( uint32_t TripleTriadCardRarityId );
using TripleTriadCardResidentPtr = boost::shared_ptr< TripleTriadCardResident >;
TripleTriadCardResidentPtr getTripleTriadCardResident( uint32_t TripleTriadCardResidentId );
using TripleTriadCardTypePtr = boost::shared_ptr< TripleTriadCardType >;
TripleTriadCardTypePtr getTripleTriadCardType( uint32_t TripleTriadCardTypeId );
using TripleTriadCompetitionPtr = boost::shared_ptr< TripleTriadCompetition >;
TripleTriadCompetitionPtr getTripleTriadCompetition( uint32_t TripleTriadCompetitionId );
using TripleTriadRulePtr = boost::shared_ptr< TripleTriadRule >;
TripleTriadRulePtr getTripleTriadRule( uint32_t TripleTriadRuleId );
using TutorialPtr = boost::shared_ptr< Tutorial >;
TutorialPtr getTutorial( uint32_t TutorialId );
using TutorialDPSPtr = boost::shared_ptr< TutorialDPS >;
TutorialDPSPtr getTutorialDPS( uint32_t TutorialDPSId );
using TutorialHealerPtr = boost::shared_ptr< TutorialHealer >;
TutorialHealerPtr getTutorialHealer( uint32_t TutorialHealerId );
using TutorialTankPtr = boost::shared_ptr< TutorialTank >;
TutorialTankPtr getTutorialTank( uint32_t TutorialTankId );
using WarpPtr = boost::shared_ptr< Warp >;
WarpPtr getWarp( uint32_t WarpId );
using WeatherPtr = boost::shared_ptr< Weather >;
WeatherPtr getWeather( uint32_t WeatherId );
using WeatherGroupPtr = boost::shared_ptr< WeatherGroup >;
WeatherGroupPtr getWeatherGroup( uint32_t WeatherGroupId );
using WeatherRatePtr = boost::shared_ptr< WeatherRate >;
WeatherRatePtr getWeatherRate( uint32_t WeatherRateId );
using WeeklyBingoOrderDataPtr = boost::shared_ptr< WeeklyBingoOrderData >;
WeeklyBingoOrderDataPtr getWeeklyBingoOrderData( uint32_t WeeklyBingoOrderDataId );
using WeeklyBingoRewardDataPtr = boost::shared_ptr< WeeklyBingoRewardData >;
WeeklyBingoRewardDataPtr getWeeklyBingoRewardData( uint32_t WeeklyBingoRewardDataId );
using WeeklyBingoTextPtr = boost::shared_ptr< WeeklyBingoText >;
WeeklyBingoTextPtr getWeeklyBingoText( uint32_t WeeklyBingoTextId );
using WorldDCGroupTypePtr = boost::shared_ptr< WorldDCGroupType >;
WorldDCGroupTypePtr getWorldDCGroupType( uint32_t WorldDCGroupTypeId );
template< class T >
boost::shared_ptr< T > get( uint32_t id )
{
try
{
auto info = boost::make_shared< T >( id, this );
return info;
}
catch( ... )
{
return nullptr;
}
return nullptr;
}
std::set< uint32_t > m_AchievementIdList;
@ -4521,7 +4353,9 @@ struct WorldDCGroupType
std::set< uint32_t > m_OnlineStatusIdList;
std::set< uint32_t > m_OpeningIdList;
std::set< uint32_t > m_OrchestrionIdList;
std::set< uint32_t > m_OrchestrionCategoryIdList;
std::set< uint32_t > m_OrchestrionPathIdList;
std::set< uint32_t > m_OrchestrionUiparamIdList;
std::set< uint32_t > m_ParamGrowIdList;
std::set< uint32_t > m_PetIdList;
std::set< uint32_t > m_PetActionIdList;
@ -4529,6 +4363,8 @@ struct WorldDCGroupType
std::set< uint32_t > m_PlaceNameIdList;
std::set< uint32_t > m_QuestIdList;
std::set< uint32_t > m_QuestRewardOtherIdList;
std::set< uint32_t > m_QuickChatIdList;
std::set< uint32_t > m_QuickChatTransientIdList;
std::set< uint32_t > m_RaceIdList;
std::set< uint32_t > m_RacingChocoboItemIdList;
std::set< uint32_t > m_RacingChocoboNameIdList;
@ -4561,6 +4397,9 @@ struct WorldDCGroupType
std::set< uint32_t > m_StainIdList;
std::set< uint32_t > m_StatusIdList;
std::set< uint32_t > m_StoryIdList;
std::set< uint32_t > m_SubmarineExplorationIdList;
std::set< uint32_t > m_SubmarinePartIdList;
std::set< uint32_t > m_SubmarineRankIdList;
std::set< uint32_t > m_SwitchTalkIdList;
std::set< uint32_t > m_TerritoryTypeIdList;
std::set< uint32_t > m_TextCommandIdList;
@ -4572,6 +4411,7 @@ struct WorldDCGroupType
std::set< uint32_t > m_TraitIdList;
std::set< uint32_t > m_TraitRecastIdList;
std::set< uint32_t > m_TraitTransientIdList;
std::set< uint32_t > m_TreasureHuntRankIdList;
std::set< uint32_t > m_TribeIdList;
std::set< uint32_t > m_TripleTriadIdList;
std::set< uint32_t > m_TripleTriadCardIdList;
@ -5956,12 +5796,24 @@ const std::set< uint32_t >& getOrchestrionIdList()
loadIdList( m_OrchestrionDat, m_OrchestrionIdList );
return m_OrchestrionIdList;
}
const std::set< uint32_t >& getOrchestrionCategoryIdList()
{
if( m_OrchestrionCategoryIdList.size() == 0 )
loadIdList( m_OrchestrionCategoryDat, m_OrchestrionCategoryIdList );
return m_OrchestrionCategoryIdList;
}
const std::set< uint32_t >& getOrchestrionPathIdList()
{
if( m_OrchestrionPathIdList.size() == 0 )
loadIdList( m_OrchestrionPathDat, m_OrchestrionPathIdList );
return m_OrchestrionPathIdList;
}
const std::set< uint32_t >& getOrchestrionUiparamIdList()
{
if( m_OrchestrionUiparamIdList.size() == 0 )
loadIdList( m_OrchestrionUiparamDat, m_OrchestrionUiparamIdList );
return m_OrchestrionUiparamIdList;
}
const std::set< uint32_t >& getParamGrowIdList()
{
if( m_ParamGrowIdList.size() == 0 )
@ -6004,6 +5856,18 @@ const std::set< uint32_t >& getQuestRewardOtherIdList()
loadIdList( m_QuestRewardOtherDat, m_QuestRewardOtherIdList );
return m_QuestRewardOtherIdList;
}
const std::set< uint32_t >& getQuickChatIdList()
{
if( m_QuickChatIdList.size() == 0 )
loadIdList( m_QuickChatDat, m_QuickChatIdList );
return m_QuickChatIdList;
}
const std::set< uint32_t >& getQuickChatTransientIdList()
{
if( m_QuickChatTransientIdList.size() == 0 )
loadIdList( m_QuickChatTransientDat, m_QuickChatTransientIdList );
return m_QuickChatTransientIdList;
}
const std::set< uint32_t >& getRaceIdList()
{
if( m_RaceIdList.size() == 0 )
@ -6196,6 +6060,24 @@ const std::set< uint32_t >& getStoryIdList()
loadIdList( m_StoryDat, m_StoryIdList );
return m_StoryIdList;
}
const std::set< uint32_t >& getSubmarineExplorationIdList()
{
if( m_SubmarineExplorationIdList.size() == 0 )
loadIdList( m_SubmarineExplorationDat, m_SubmarineExplorationIdList );
return m_SubmarineExplorationIdList;
}
const std::set< uint32_t >& getSubmarinePartIdList()
{
if( m_SubmarinePartIdList.size() == 0 )
loadIdList( m_SubmarinePartDat, m_SubmarinePartIdList );
return m_SubmarinePartIdList;
}
const std::set< uint32_t >& getSubmarineRankIdList()
{
if( m_SubmarineRankIdList.size() == 0 )
loadIdList( m_SubmarineRankDat, m_SubmarineRankIdList );
return m_SubmarineRankIdList;
}
const std::set< uint32_t >& getSwitchTalkIdList()
{
if( m_SwitchTalkIdList.size() == 0 )
@ -6262,6 +6144,12 @@ const std::set< uint32_t >& getTraitTransientIdList()
loadIdList( m_TraitTransientDat, m_TraitTransientIdList );
return m_TraitTransientIdList;
}
const std::set< uint32_t >& getTreasureHuntRankIdList()
{
if( m_TreasureHuntRankIdList.size() == 0 )
loadIdList( m_TreasureHuntRankDat, m_TreasureHuntRankIdList );
return m_TreasureHuntRankIdList;
}
const std::set< uint32_t >& getTribeIdList()
{
if( m_TribeIdList.size() == 0 )

View file

@ -96,6 +96,7 @@ namespace Packets {
SetCharacterFCInfo = 0x0114, // updated 4.2
StatusEffectList = 0x0125, // updated 4.2
Effect = 0x0128, // updated 4.2
PersistantEffect = 0x013B, // updated 4.2
GCAffiliation = 0xCCFC, // OUTDATED
@ -105,6 +106,7 @@ namespace Packets {
ActorSetPos = 0x0160, // updated 4.2
ActorCast = 0x0162, // updated 4.2
HateList = 0x0165, // updated 4.2
ObjectSpawn = 0x0167, // updated 4.2
UpdateClassInfo = 0x0169, // updated 4.2
InitUI = 0x016B, // updated 4.2
@ -145,6 +147,8 @@ namespace Packets {
Mount = 0x01CD, // updated 4.2
DirectorVars = 0x01CF, // updated 4.2
WeatherChange = 0x01EA, // updated 4.2
PlayerTitleList = 0x01EB, // updated 4.2
Discovery = 0x01EC, // updated 4.2
@ -153,7 +157,7 @@ namespace Packets {
EquipDisplayFlags = 0x01FA, // updated 4.2
CFAvailableContents = 0x01CF,
CFAvailableContents = 0x01FD, // updated 4.2
PrepareZoning = 0x027C, // updated 4.2
ActorGauge = 0x027D, // updated 4.2

View file

@ -461,20 +461,21 @@ struct FFXIVIpcNpcSpawn : FFXIVIpcBasePacket<NpcSpawn>
{
uint16_t title;
uint16_t u1b;
uint16_t u2a;
uint16_t u2b;
uint8_t pose;
uint8_t u2b;
uint8_t u2ab;
uint8_t gmRank;
uint8_t u3b;
uint8_t u3a;
uint8_t onlineStatus;
uint8_t u3c;
uint8_t u3d;
uint8_t pose;
uint32_t u4;
uint64_t targetId;
uint32_t u6;
uint32_t u7;
uint64_t mainWeaponModel;
uint64_t secWeaponModel;
uint64_t craftToolModel;
@ -485,44 +486,40 @@ struct FFXIVIpcNpcSpawn : FFXIVIpcBasePacket<NpcSpawn>
uint32_t bNPCName;
uint32_t u18;
uint32_t u19;
uint32_t u20;
uint32_t u21;
uint32_t directorId;
uint32_t ownerId;
uint32_t u22;
uint32_t hPCurr;
uint32_t hPMax;
uint32_t hPCurr;
uint32_t displayFlags;
uint16_t fateID;
uint16_t mPCurr;
uint16_t tPCurr;
uint16_t mPMax;
uint16_t unk21a;
uint16_t tPMax;
uint16_t modelChara;
uint16_t rotation;
uint16_t unk22b;
uint16_t activeMinion;
uint8_t spawnIndex;
uint8_t state; // ActorState
uint8_t u24a;
uint8_t type; // 1 for player, 2 for NPC, else furniture;
uint8_t subtype; // 4 for players, 2 for pet, 3 for companion, 5 for mob, 7 for minion
uint8_t u25b;
uint8_t state;
uint8_t persistantEmote;
uint8_t type;
uint8_t subtype;
uint8_t voice;
uint16_t u25c;
uint8_t enemyType; // 0 for friendly, anything else is an enemy
uint8_t enemyType;
uint8_t level;
uint8_t classJob;
uint8_t u26d;
uint16_t u27a;
uint8_t currentMount;
uint8_t mountHead;
uint8_t mountBody;
uint8_t mountFeet;
uint16_t mountColor;
uint8_t mountColor;
uint8_t scale;
uint32_t u29b;
uint32_t u30b;
Common::StatusEffect effect[30];
Common::FFXIVARR_POSITION3 pos;
uint32_t models[10];
@ -1321,6 +1318,23 @@ struct FFXIVIpcMount : FFXIVIpcBasePacket<Mount>
uint32_t id;
};
/**
* Structural representation of the packet sent by the server
* to mount a player
*/
struct FFXIVIpcDirectorVars : FFXIVIpcBasePacket<DirectorVars>
{
/*! DirectorType | ContentId */
uint32_t m_directorId;
/*! currect sequence */
uint8_t m_sequence;
/*! current branch */
uint8_t m_branch;
/*! raw storage for flags/vars */
uint8_t m_unionData[10];
};
struct FFXIVIpcActorGauge : FFXIVIpcBasePacket<ActorGauge>
{
uint8_t classJobId;
@ -1347,6 +1361,28 @@ struct FFXIVIpcMSQTrackerComplete : FFXIVIpcBasePacket<MSQTrackerComplete>
uint64_t padding4; // last 4 bytes is uint32_t but who cares
};
struct FFXIVIpcObjectSpawn : FFXIVIpcBasePacket<ObjectSpawn>
{
uint8_t count;
uint8_t objKind;
uint8_t unknown2;
uint8_t state;
uint32_t objId;
uint32_t actorId;
uint32_t levelId;
uint32_t unknown10;
uint32_t someActorId14;
uint32_t hierachyId;
uint32_t unknown1C;
uint32_t unknown20;
uint32_t unknown24;
uint32_t unknown28;
uint32_t unknown2c;
Common::FFXIVARR_POSITION3 position;
int16_t rotation;
int16_t unknown;
};
} /* Server */
} /* Packets */

@ -1 +1 @@
Subproject commit 978d3d2a336b97bb6ea0d95dc7000cbc1618a8cc
Subproject commit 732e26b4bfb15875d71ae4ec13b8bd6155013840

View file

@ -220,7 +220,7 @@ namespace Core {
// CharacterId, ClassIdx, Exp, Lvl
auto stmtClass = g_charaDb.getPreparedStatement( Db::CharaDbStatements::CHARA_CLASS_INS );
stmtClass->setInt( 1, m_id );
stmtClass->setInt( 2, g_exdDataGen.getClassJob( m_class )->expArrayIndex );
stmtClass->setInt( 2, g_exdDataGen.get< Core::Data::ClassJob >( m_class )->expArrayIndex );
stmtClass->setInt( 3, 0 );
stmtClass->setInt( 4, 1 );
g_charaDb.directExecute( stmtClass );
@ -292,14 +292,14 @@ namespace Core {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// SETUP EQUIPMENT / STARTING GEAR
auto classJobInfo = g_exdDataGen.getClassJob( m_class );
auto classJobInfo = g_exdDataGen.get< Core::Data::ClassJob >( m_class );
uint32_t weaponId = classJobInfo->itemStartingWeapon;
uint64_t uniqueId = getNextUId64();
uint8_t race = customize[CharaLook::Race];
uint8_t gender = customize[CharaLook::Gender];
auto raceInfo = g_exdDataGen.getRace( race );
auto raceInfo = g_exdDataGen.get< Core::Data::Race >( race );
uint32_t body;
uint32_t hands;

View file

@ -241,7 +241,7 @@ std::string buildHttpResponse( uint16_t rCode, const std::string& content = "",
void getZoneName( shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request )
{
string number = request->path_match[1];
auto info = g_exdDataGen.getTerritoryType( atoi( number.c_str() ) );
auto info = g_exdDataGen.get< Core::Data::TerritoryType >( atoi( number.c_str() ) );
std::string responseStr = "Not found!";
if( info )
responseStr = info->name + ", " + info->bg;
@ -739,7 +739,7 @@ void defaultGet( shared_ptr<HttpServer::Response> response, shared_ptr<HttpServe
int main( int argc, char* argv[] )
{
g_log.setLogPath( "log\\SapphireAPI" );
g_log.setLogPath( "log/SapphireAPI" );
g_log.init();
g_log.info( "===========================================================" );

View file

@ -2,11 +2,15 @@
#define _FORWARDS_H
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <vector>
#define TYPE_FORWARD( x ) \
class x; \
typedef boost::shared_ptr< x > x ## Ptr; \
template< typename...Args > \
x ## Ptr make_ ## x( Args &&...args ) { \
return boost::make_shared< x >( std::forward< Args >( args ) ... ); }\
typedef std::vector< x > x ## PtrList;
namespace Core

View file

@ -42,7 +42,7 @@ Core::Network::GameConnection::~GameConnection()
// overwrite the parents onConnect for our game socket needs
void Core::Network::GameConnection::OnAccept( const std::string & host, uint16_t port )
{
GameConnectionPtr connection( new GameConnection( m_hive, m_pAcceptor ) );
auto connection = make_GameConnection( m_hive, m_pAcceptor );
m_pAcceptor->Accept( connection );
g_log.info( "Connect from " + m_socket.remote_endpoint().address().to_string() );
@ -76,7 +76,8 @@ void Core::Network::GameConnection::OnRecv( std::vector< uint8_t > & buffer )
// Dissect packet list
std::vector< Packets::FFXIVARR_PACKET_RAW > packetList;
const auto packetResult = Packets::getPackets(buffer, sizeof(struct FFXIVARR_PACKET_HEADER), packetHeader, packetList);
const auto packetResult = Packets::getPackets( buffer, sizeof( struct FFXIVARR_PACKET_HEADER ),
packetHeader, packetList );
if( packetResult == Incomplete )
{
@ -252,7 +253,7 @@ bool Core::Network::GameConnection::sendServiceAccountList( FFXIVARR_PACKET_RAW&
if( g_serverLobby.getConfig()->getValue< bool >( "Settings.Parameters.AllowNoSessionConnect" ) && pSession == nullptr )
{
LobbySessionPtr session( new Core::LobbySession() );
auto session = make_LobbySession();
session->setAccountID( 0 );
session->setSessionId( (uint8_t *)&packet.data[0] + 0x20 );
pSession = session;

View file

@ -54,7 +54,7 @@ namespace Core {
void ServerLobby::run( int32_t argc, char* argv[] )
{
g_log.setLogPath( "log\\SapphireLobby" );
g_log.setLogPath( "log/SapphireLobby" );
g_log.init();
g_log.info( "===========================================================" );

View file

@ -31,7 +31,7 @@ Core::Action::ActionCast::ActionCast( Entity::ActorPtr pActor, Entity::ActorPtr
m_startTime = 0;
m_id = actionId;
m_handleActionType = HandleActionType::Spell;
m_castTime = g_exdDataGen.getAction( actionId )->cast100ms * 100; // TODO: Add security checks.
m_castTime = g_exdDataGen.get< Core::Data::Action >( actionId )->cast100ms * 100; // TODO: Add security checks.
m_pSource = pActor;
m_pTarget = pTarget;
m_bInterrupt = false;

View file

@ -1,5 +1,4 @@
#include <common/Util/Util.h>
#include <common/Exd/ExdData.h>
#include <common/Util/UtilMath.h>
#include "ActionCollision.h"
@ -14,7 +13,7 @@ using namespace Core::Common;
// todo: add AoE actor limits (16, 32)
bool ActionCollision::isActorApplicable( ActorPtr actorPtr, TargetFilter targetFilter )
bool ActionCollision::isActorApplicable( Actor& actor, TargetFilter targetFilter )
{
bool actorApplicable = false;
switch( targetFilter )
@ -26,29 +25,29 @@ bool ActionCollision::isActorApplicable( ActorPtr actorPtr, TargetFilter targetF
}
case TargetFilter::Players:
{
actorApplicable = actorPtr->isPlayer();
actorApplicable = actor.isPlayer();
break;
}
case TargetFilter::Allies:
{
// todo: implement ally NPCs
actorApplicable = !actorPtr->isMob();
actorApplicable = !actor.isBattleNpc();
break;
}
case TargetFilter::Party:
{
// todo: implement party
actorApplicable = actorPtr->isPlayer();
actorApplicable = actor.isPlayer();
break;
}
case TargetFilter::Enemies:
{
actorApplicable = actorPtr->isMob();
actorApplicable = actor.isBattleNpc();
break;
}
}
return ( actorApplicable && actorPtr->isAlive() );
return ( actorApplicable && actor.isAlive() );
}
std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition,
@ -71,7 +70,7 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI
assert( pActor );
// Don't bother wasting on collision if actor doesn't apply for it
if ( !isActorApplicable( pActor, targetFilter ) )
if ( !isActorApplicable( *pActor, targetFilter ) )
continue;
// Test our collision from actor with the area generated by the action from the AoE data
@ -89,7 +88,7 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI
{
assert( pActor );
if ( !isActorApplicable( pActor, targetFilter ) )
if ( !isActorApplicable( *pActor, targetFilter ) )
continue;
if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) )
@ -103,7 +102,7 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI
{
assert( pActor );
if ( !isActorApplicable( pActor, targetFilter ) )
if ( !isActorApplicable( *pActor, targetFilter ) )
continue;
if ( boxCollision( pActor->getPos(), aoePosition, actionInfo->xAxisModifier, actionInfo->effectRange ) )

View file

@ -23,7 +23,7 @@ namespace Entity {
{
public:
static bool isActorApplicable( ActorPtr actorPtr, TargetFilter targetFilter );
static bool isActorApplicable( Actor& actor, TargetFilter targetFilter );
static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition,
std::set< ActorPtr > actorsInRange,
boost::shared_ptr< Data::Action > actionInfo,

View file

@ -3,7 +3,6 @@
#include <common/Common.h>
#include <common/Util/Util.h>
#include <common/Util/UtilMath.h>
#include <common/Exd/ExdData.h>
#include <common/Logging/Logger.h>
#include "Network/PacketWrappers/ActorControlPacket142.h"
@ -17,7 +16,6 @@ using namespace Core::Network;
using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server;
extern Core::Data::ExdData g_exdData;
extern Core::Logger g_log;
extern Core::Scripting::ScriptManager g_scriptMgr;

View file

@ -26,7 +26,7 @@ Core::Action::ActionTeleport::ActionTeleport( Entity::ActorPtr pActor, uint16_t
m_startTime = 0;
m_id = 5;
m_handleActionType = HandleActionType::Teleport;
m_castTime = g_exdDataGen.getAction( 5 )->cast100ms * 100; // TODO: Add security checks.
m_castTime = g_exdDataGen.get< Core::Data::Action >( 5 )->cast100ms * 100; // TODO: Add security checks.
m_pSource = pActor;
m_bInterrupt = false;
m_targetAetheryte = targetZone;

View file

@ -28,7 +28,7 @@ Core::Action::EventAction::EventAction( Entity::ActorPtr pActor, uint32_t eventI
m_handleActionType = HandleActionType::Event;
m_eventId = eventId;
m_id = action;
m_castTime = g_exdDataGen.getEventAction( action )->castTime * 1000; // TODO: Add security checks.
m_castTime = g_exdDataGen.get< Core::Data::EventAction >( action )->castTime * 1000; // TODO: Add security checks.
m_onActionFinishClb = finishRef;
m_onActionInterruptClb = interruptRef;
m_pSource = pActor;

View file

@ -1,7 +1,6 @@
#include <common/Util/Util.h>
#include <common/Util/UtilMath.h>
#include <common/Network/PacketContainer.h>
#include <common/Exd/ExdData.h>
#include <common/Exd/ExdDataGenerated.h>
#include <common/Network/GamePacket.h>
@ -23,15 +22,18 @@
#include "Math/CalcBattle.h"
#include "Actor.h"
#include "Player.h"
#include "Zone/TerritoryMgr.h"
extern Core::ServerZone g_serverZone;
extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::TerritoryMgr g_territoryMgr;
using namespace Core::Common;
using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server;
Core::Entity::Actor::Actor()
Core::Entity::Actor::Actor( ObjKind type ) :
GameObject( type )
{
// initialize the free slot queue
for( uint8_t i = 0; i < MAX_STATUS_EFFECTS; i++ )
@ -44,48 +46,19 @@ Core::Entity::Actor::~Actor()
{
}
/*! \return the id of the actor */
uint32_t Core::Entity::Actor::getId() const
{
return m_id;
}
/*! \return the actors position object */
Core::Common::FFXIVARR_POSITION3& Core::Entity::Actor::getPos()
{
return m_pos;
}
/*! \return the actors name */
std::string Core::Entity::Actor::getName() const
{
return std::string( m_name );
}
/*! \return true if the actor is of type player */
bool Core::Entity::Actor::isPlayer() const
{
return m_objKind == ObjKind::Player;
}
/*! \return true if the actor is of type mob */
bool Core::Entity::Actor::isMob() const
{
return m_objKind == ObjKind::BattleNpc;
}
/*! \return true if the actor is of type resident */
bool Core::Entity::Actor::isEventNpc() const
{
return m_objKind == ObjKind::EventNpc;
}
/*! \return list of actors currently in range */
std::set< Core::Entity::ActorPtr > Core::Entity::Actor::getInRangeActors( bool includeSelf )
{
auto tempInRange = m_inRangeActors;
if( includeSelf )
tempInRange.insert( shared_from_this() );
tempInRange.insert( getAsActor() );
return tempInRange;
}
@ -285,7 +258,7 @@ Sets the actors position and notifies the zone to propagate the change
void Core::Entity::Actor::setPosition( const Common::FFXIVARR_POSITION3& pos )
{
m_pos = pos;
m_pCurrentZone->changeActorPosition( shared_from_this() );
m_pCurrentZone->updateActorPosition( *this );
}
void Core::Entity::Actor::setPosition( float x, float y, float z )
@ -293,7 +266,7 @@ void Core::Entity::Actor::setPosition( float x, float y, float z )
m_pos.x = x;
m_pos.y = y;
m_pos.z = z;
m_pCurrentZone->changeActorPosition( shared_from_this() );
m_pCurrentZone->updateActorPosition( *this );
}
/*!
@ -336,9 +309,7 @@ Change the current target and propagate to in range players
void Core::Entity::Actor::changeTarget( uint64_t targetId )
{
setTargetId( targetId );
sendToInRangeSet( ActorControlPacket144( m_id, SetTarget,
0, 0, 0, 0, targetId ) );
sendToInRangeSet( ActorControlPacket144( m_id, SetTarget, 0, 0, 0, 0, targetId ) );
}
/*!
@ -409,28 +380,10 @@ so players can have their own version and we can abolish the param.
*/
void Core::Entity::Actor::sendStatusUpdate( bool toSelf )
{
UpdateHpMpTpPacket updateHpPacket( shared_from_this() );
UpdateHpMpTpPacket updateHpPacket( *this );
sendToInRangeSet( updateHpPacket );
}
/*! \return pointer to this instance as PlayerPtr */
Core::Entity::PlayerPtr Core::Entity::Actor::getAsPlayer()
{
return boost::dynamic_pointer_cast< Entity::Player, Entity::Actor >( shared_from_this() );
}
/*! \return pointer to this instance as BattleNpcPtr */
Core::Entity::BattleNpcPtr Core::Entity::Actor::getAsBattleNpc()
{
return boost::reinterpret_pointer_cast< Entity::BattleNpc, Entity::Actor >( shared_from_this() );
}
/*! \return pointer to this instance as EventNpcPtr */
Core::Entity::EventNpcPtr Core::Entity::Actor::getAsEventNpc()
{
return boost::reinterpret_pointer_cast< Entity::EventNpc, Entity::Actor >( shared_from_this() );
}
/*! \return ActionPtr of the currently registered action, or nullptr */
Core::Action::ActionPtr Core::Entity::Actor::getCurrentAction() const
{
@ -540,39 +493,29 @@ void Core::Entity::Actor::addInRangeActor( ActorPtr pActor )
// if actor is a player, add it to the in range player set
m_inRangePlayers.insert( pPlayer );
}
m_inRangeActorMap[pActor->getId()] = pActor;
}
/*!
Remove a given actor from the fitting in range set according to type
Remove a given actor from the matching in range set according to type
but also to the global actor map
\param ActorPtr to remove
*/
void Core::Entity::Actor::removeInRangeActor( ActorPtr pActor )
void Core::Entity::Actor::removeInRangeActor( Actor& actor )
{
// if this is null, something went wrong
assert( pActor );
// call virtual event
onRemoveInRangeActor( pActor );
onRemoveInRangeActor( actor );
// remove actor from in range actor set
m_inRangeActors.erase( pActor );
m_inRangeActors.erase( actor.getAsActor() );
// if actor is a player, despawn ourself for him
// TODO: move to virtual onRemove?
if( isPlayer() )
pActor->despawn( shared_from_this() );
actor.despawn( getAsPlayer() );
if( pActor->isPlayer() )
{
auto pPlayer = pActor->getAsPlayer();
m_inRangePlayers.erase( pPlayer );
}
m_inRangeActorMap.erase( pActor->getId() );
if( actor.isPlayer() )
m_inRangePlayers.erase( actor.getAsPlayer() );
}
/*! \return true if there is at least one actor in the in range set */
@ -581,12 +524,57 @@ bool Core::Entity::Actor::hasInRangeActor() const
return ( m_inRangeActors.size() > 0 );
}
void Core::Entity::Actor::removeFromInRange()
{
if( !hasInRangeActor() )
return;
Entity::ActorPtr pCurAct;
for( auto& pCurAct : m_inRangeActors )
{
pCurAct->removeInRangeActor( *this );
}
}
void Core::Entity::Actor::checkInRangeActors()
{
if( hasInRangeActor() )
{
Entity::ActorPtr pCurAct;
float fRange = 70.0f;
for( auto iter = m_inRangeActors.begin(); iter != m_inRangeActors.end();)
{
pCurAct = *iter;
auto iter2 = iter++;
float distance = Math::Util::distance( pCurAct->getPos().x, pCurAct->getPos().y, pCurAct->getPos().z,
getPos().x, getPos().y, getPos().z );
if( fRange > 0.0f && distance > fRange )
{
pCurAct->removeInRangeActor( *this );
if( getCurrentZone() != pCurAct->getCurrentZone() )
return;
removeInRangeActor( **iter2 );
// @TODO FIXME!
// this break is more or less a hack, iteration will break otherwise after removing
break;
}
}
}
}
/*! Clear the whole in range set, this does no cleanup */
void Core::Entity::Actor::clearInRangeSet()
{
m_inRangeActors.clear();
m_inRangePlayers.clear();
m_inRangeActorMap.clear();
}
/*! \return ZonePtr to the current zone, nullptr if not set */
@ -637,7 +625,7 @@ void Core::Entity::Actor::autoAttack( ActorPtr pTarget )
if( ( tick - m_lastAttack ) > 2500 )
{
pTarget->onActionHostile( shared_from_this() );
pTarget->onActionHostile( *this );
m_lastAttack = tick;
srand( static_cast< uint32_t >( tick ) );
@ -674,29 +662,29 @@ ChaiScript Skill Handler.
\param bool should be send to self?
*/
void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint16_t actionId, uint64_t param1,
uint64_t param2, Entity::Actor& pTarget )
uint64_t param2, Entity::Actor& target )
{
if( isPlayer() )
{
getAsPlayer()->sendDebug( std::to_string( pTarget.getId() ) );
getAsPlayer()->sendDebug( std::to_string( target.getId() ) );
getAsPlayer()->sendDebug( "Handle script skill type: " + std::to_string( type ) );
}
auto actionInfoPtr = g_exdDataGen.getAction( actionId );
auto actionInfoPtr = g_exdDataGen.get< Core::Data::Action >( actionId );
// Todo: Effect packet generator. 90% of this is basically setting params and it's basically unreadable.
// Prepare packet. This is seemingly common for all packets in the action handler.
ZoneChannelPacket< FFXIVIpcEffect > effectPacket( getId() );
effectPacket.data().targetId = pTarget.getId();
effectPacket.data().targetId = target.getId();
effectPacket.data().actionAnimationId = actionId;
effectPacket.data().unknown_62 = 1; // Affects displaying action name next to number in floating text
effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation
effectPacket.data().actionTextId = actionId;
effectPacket.data().numEffects = 1;
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
effectPacket.data().effectTarget = pTarget.getId();
effectPacket.data().effectTarget = target.getId();
// Todo: for each actor, calculate how much damage the calculated value should deal to them - 2-step damage calc. we only have 1-step
switch( type )
@ -712,21 +700,21 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint16_t actionId, u
if( actionInfoPtr->castType == 1 && actionInfoPtr->effectRange != 0 || actionInfoPtr->castType != 1 )
{
// If action on this specific target is valid...
if ( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Enemies ) )
if ( isPlayer() && !ActionCollision::isActorApplicable( target, TargetFilter::Enemies ) )
break;
sendToInRangeSet( effectPacket, true );
if ( pTarget.isAlive() )
pTarget.onActionHostile( shared_from_this() );
if ( target.isAlive() )
target.onActionHostile( *this );
pTarget.takeDamage( static_cast< uint32_t >( param1 ) );
target.takeDamage( static_cast< uint32_t >( param1 ) );
}
else
{
auto actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ),
auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors( true ),
actionInfoPtr, TargetFilter::Enemies );
for( const auto& pHitActor : actorsCollided )
@ -739,7 +727,7 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint16_t actionId, u
if( pHitActor->isAlive() )
pHitActor->onActionHostile( shared_from_this() );
pHitActor->onActionHostile( *this );
pHitActor->takeDamage( static_cast< uint32_t >( param1 ) );
@ -767,23 +755,23 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint16_t actionId, u
if( actionInfoPtr->castType == 1 && actionInfoPtr->effectRange != 0 || actionInfoPtr->castType != 1 )
{
if( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Allies ) )
if( isPlayer() && !ActionCollision::isActorApplicable( target, TargetFilter::Allies ) )
break;
sendToInRangeSet( effectPacket, true );
pTarget.heal( calculatedHeal );
target.heal( calculatedHeal );
}
else
{
// todo: get proper packets: the following was just kind of thrown together from what we know.
// atm buggy (packets look "delayed" from client)
auto actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ),
auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors( true ),
actionInfoPtr, TargetFilter::Allies );
for( auto pHitActor : actorsCollided )
{
effectPacket.data().targetId = pTarget.getId();
effectPacket.data().targetId = target.getId();
effectPacket.data().effectTarget = pHitActor->getId();
sendToInRangeSet( effectPacket, true );
@ -837,22 +825,20 @@ void Core::Entity::Actor::addStatusEffect( StatusEffect::StatusEffectPtr pEffect
}
/*! \param StatusEffectPtr to be applied to the actor */
void Core::Entity::Actor::addStatusEffectById( uint32_t id, int32_t duration, Entity::Actor& pSource, uint16_t param )
void Core::Entity::Actor::addStatusEffectById( uint32_t id, int32_t duration, Entity::Actor& source, uint16_t param )
{
StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pSource.shared_from_this(),
shared_from_this(), duration, 3000 ) );
auto effect = StatusEffect::make_StatusEffect( id, source.getAsActor(), getAsActor(), duration, 3000 );
effect->setParam( param );
addStatusEffect( effect );
}
/*! \param StatusEffectPtr to be applied to the actor */
void Core::Entity::Actor::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Actor& pSource, uint16_t param )
void Core::Entity::Actor::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Actor& source, uint16_t param )
{
if( hasStatusEffect( id ) )
return;
StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pSource.shared_from_this(),
shared_from_this(), duration, 3000 ) );
auto effect = StatusEffect::make_StatusEffect( id, source.getAsActor(), getAsActor(), duration, 3000 );
effect->setParam( param );
addStatusEffect( effect );

View file

@ -5,6 +5,7 @@
#include <boost/enable_shared_from_this.hpp>
#include "Forwards.h"
#include "GameObject.h"
#include <set>
#include <map>
#include <queue>
@ -17,28 +18,9 @@ namespace Entity {
\brief Base class for all actors
*/
class Actor : public boost::enable_shared_from_this< Actor >
class Actor : public GameObject
{
public:
enum ObjKind : uint8_t
{
None = 0x00,
Player = 0x01,
BattleNpc = 0x02,
EventNpc = 0x03,
Treasure = 0x04,
Aetheryte = 0x05,
GatheringPoint = 0x06,
EventObj = 0x07,
Mount = 0x08,
Companion = 0x09,
Retainer = 0x0A,
Area = 0x0B,
Housing = 0x0C,
Cutscene = 0x0D,
CardStand = 0x0E,
};
enum Stance : uint8_t
{
Passive = 0,
@ -113,21 +95,9 @@ public:
} m_baseStats;
protected:
// TODO: The position class should probably be abolished and
// the FFXIV_POS struct used instead ( the functions in there
// could be moved to a FFXIV_POS_Helper namespace and rotation to
// its own member )
/*! Position of the actor */
Common::FFXIVARR_POSITION3 m_pos;
float m_rot;
/*! Name of the actor */
char m_name[34];
/*! Id of the zone the actor currently is in */
uint32_t m_zoneId;
/*! Id of the actor */
uint32_t m_id;
/*! Type of the actor */
ObjKind m_objKind;
/*! Ptr to the ZoneObj the actor belongs to */
ZonePtr m_pCurrentZone;
/*! Last tick time for the actor ( in ms ) */
@ -169,15 +139,16 @@ protected:
std::vector< std::pair< uint8_t, uint32_t> > m_statusEffectList;
std::map< uint8_t, StatusEffect::StatusEffectPtr > m_statusEffectMap;
public:
Actor();
std::set< ActorPtr > m_inRangeActors;
std::set< PlayerPtr > m_inRangePlayers;
virtual ~Actor();
public:
Actor( ObjKind type );
virtual ~Actor() override;
virtual void calculateStats() {};
uint32_t getId() const;
/// Status effect functions
void addStatusEffect( StatusEffect::StatusEffectPtr pEffect );
void removeStatusEffect( uint8_t effectSlotId );
@ -209,16 +180,8 @@ public:
float getRotation() const;
Common::FFXIVARR_POSITION3& getPos();
std::string getName() const;
bool isPlayer() const;
bool isMob() const;
bool isEventNpc() const;
std::set< ActorPtr > getInRangeActors( bool includeSelf = false );
bool face( const Common::FFXIVARR_POSITION3& p );
@ -230,11 +193,8 @@ public:
ActorStats getStats() const;
uint32_t getHp() const;
uint32_t getMp() const;
uint16_t getTp() const;
uint16_t getGp() const;
Common::InvincibilityType getInvincibilityType() const;
@ -252,17 +212,13 @@ public:
bool isAlive() const;
virtual uint32_t getMaxHp() const;
virtual uint32_t getMaxMp() const;
void resetHp();
void resetMp();
void setHp( uint32_t hp );
void setMp( uint32_t mp );
void setGp( uint32_t gp );
void setInvincibilityType( Common::InvincibilityType type );
@ -277,13 +233,11 @@ public:
virtual void autoAttack( ActorPtr pTarget );
virtual void spawn( PlayerPtr pTarget ) {}
virtual void despawn( ActorPtr pTarget ) {}
virtual void onRemoveInRangeActor( Actor& pActor ) {}
virtual void onRemoveInRangeActor( ActorPtr pActor ) {}
virtual void onDeath() {};
virtual void onDamageTaken( Actor& pSource ) {};
virtual void onActionHostile( Core::Entity::ActorPtr pSource ) {};
virtual void onActionHostile( Actor& source ) {};
virtual void onActionFriendly( Actor& pSource ) {};
virtual void onTick() {};
@ -295,10 +249,6 @@ public:
virtual bool checkAction();
virtual void update( int64_t currTime ) {};
PlayerPtr getAsPlayer();
BattleNpcPtr getAsBattleNpc();
EventNpcPtr getAsEventNpc();
Action::ActionPtr getCurrentAction() const;
void setCurrentAction( Action::ActionPtr pAction );
@ -313,14 +263,18 @@ public:
void sendToInRangeSet( Network::Packets::GamePacketPtr pPacket, bool bToSelf = false );
// add an actor to in range set
virtual void addInRangeActor( ActorPtr pActor );
void addInRangeActor( ActorPtr pActor );
// remove an actor from the in range set
void removeInRangeActor( ActorPtr pActor );
void removeInRangeActor( Actor& pActor );
// return true if there is at least one actor in the in range set
bool hasInRangeActor() const;
void checkInRangeActors();
void removeFromInRange();
// clear the whole in range set, this does no cleanup
virtual void clearInRangeSet();
@ -334,12 +288,6 @@ public:
// set the current cell
void setCell( Cell* pCell );
// TODO: Why did i even declare them publicly here?!
std::set< ActorPtr > m_inRangeActors;
std::set< PlayerPtr > m_inRangePlayers;
std::map< uint32_t, ActorPtr > m_inRangeActorMap;
Core::Cell* m_pCell;
};

View file

@ -25,10 +25,10 @@ extern Core::Data::ExdDataGenerated g_exdDataGen;
uint32_t Core::Entity::BattleNpc::m_nextID = 1149241694;
Core::Entity::BattleNpc::BattleNpc()
Core::Entity::BattleNpc::BattleNpc() :
Actor( ObjKind::BattleNpc )
{
m_id = 0;
m_objKind = ObjKind::BattleNpc;
m_status = ActorStatus::Idle;
}
@ -39,7 +39,8 @@ Core::Entity::BattleNpc::~BattleNpc()
Core::Entity::BattleNpc::BattleNpc( uint16_t modelId, uint16_t nameid, const Common::FFXIVARR_POSITION3& spawnPos,
uint16_t bnpcBaseId, uint32_t type, uint8_t level, uint8_t behaviour,
uint32_t mobType ) : Actor()
uint32_t mobType ) :
Actor( ObjKind::BattleNpc )
{
BattleNpc::m_nextID++;
m_id = BattleNpc::m_nextID;
@ -48,8 +49,6 @@ Core::Entity::BattleNpc::BattleNpc( uint16_t modelId, uint16_t nameid, const Com
m_pos = spawnPos;
m_posOrigin = spawnPos;
m_objKind = ObjKind::BattleNpc;
m_mode = MODE_IDLE;
m_targetId = static_cast< uint64_t >( INVALID_GAME_OBJECT_ID );
@ -149,11 +148,8 @@ void Core::Entity::BattleNpc::spawn( PlayerPtr pTarget )
}
// despawn
void Core::Entity::BattleNpc::despawn( ActorPtr pTarget )
void Core::Entity::BattleNpc::despawn( PlayerPtr pPlayer )
{
auto pPlayer = pTarget->getAsPlayer();
pPlayer->freePlayerSpawnId( getId() );
ActorControlPacket143 controlPacket( m_id, DespawnZoneScreenMsg, 0x04, getId(), 0x01 );
@ -181,11 +177,11 @@ uint8_t Core::Entity::BattleNpc::getbehavior() const
return m_behavior;
}
void Core::Entity::BattleNpc::hateListAdd( ActorPtr pActor, int32_t hateAmount )
void Core::Entity::BattleNpc::hateListAdd( Actor& actor, int32_t hateAmount )
{
auto hateEntry = new HateListEntry();
hateEntry->m_hateAmount = hateAmount;
hateEntry->m_pActor = pActor;
hateEntry->m_pActor = actor.getAsActor();
m_hateList.insert( hateEntry );
}
@ -278,32 +274,32 @@ bool Core::Entity::BattleNpc::moveTo( Common::FFXIVARR_POSITION3& pos )
}
void Core::Entity::BattleNpc::aggro( ActorPtr pActor )
void Core::Entity::BattleNpc::aggro( Actor& actor )
{
m_lastAttack = Util::getTimeMs();
hateListUpdate( pActor, 1 );
hateListUpdate( actor, 1 );
changeTarget( pActor->getId() );
changeTarget( actor.getId() );
setStance( Stance::Active );
m_mode = MODE_COMBAT;
if( pActor->isPlayer() )
if( actor.isPlayer() )
{
PlayerPtr tmpPlayer = pActor->getAsPlayer();
PlayerPtr tmpPlayer = actor.getAsPlayer();
tmpPlayer->queuePacket( ActorControlPacket142( getId(), 0, 1, 1 ) );
tmpPlayer->onMobAggro( getAsBattleNpc() );
}
}
void Core::Entity::BattleNpc::deaggro( ActorPtr pActor )
void Core::Entity::BattleNpc::deaggro( Actor& actor )
{
if( !hateListHasActor( pActor ) )
hateListRemove( pActor );
if( !hateListHasActor( actor ) )
hateListRemove( actor );
if( pActor->isPlayer() )
if( actor.isPlayer() )
{
PlayerPtr tmpPlayer = pActor->getAsPlayer();
PlayerPtr tmpPlayer = actor.getAsPlayer();
tmpPlayer->onMobDeaggro( getAsBattleNpc() );
}
}
@ -314,7 +310,7 @@ void Core::Entity::BattleNpc::hateListClear()
for( ; it != m_hateList.end(); ++it )
{
if( isInRangeSet( ( *it )->m_pActor ) )
deaggro( ( *it )->m_pActor );
deaggro( *( *it )->m_pActor );
HateListEntry* tmpListEntry = ( *it );
delete tmpListEntry;
}
@ -322,19 +318,19 @@ void Core::Entity::BattleNpc::hateListClear()
}
void Core::Entity::BattleNpc::hateListRemove( ActorPtr pActor )
void Core::Entity::BattleNpc::hateListRemove( Actor& actor )
{
auto it = m_hateList.begin();
for( ; it != m_hateList.end(); ++it )
{
if( ( *it )->m_pActor == pActor )
if( ( *it )->m_pActor->getId() == actor.getId() )
{
HateListEntry* pEntry = *it;
m_hateList.erase( it );
delete pEntry;
if( pActor->isPlayer() )
if( actor.isPlayer() )
{
PlayerPtr tmpPlayer = pActor->getAsPlayer();
PlayerPtr tmpPlayer = actor.getAsPlayer();
tmpPlayer->onMobDeaggro( getAsBattleNpc() );
}
return;
@ -342,12 +338,12 @@ void Core::Entity::BattleNpc::hateListRemove( ActorPtr pActor )
}
}
bool Core::Entity::BattleNpc::hateListHasActor( ActorPtr pActor )
bool Core::Entity::BattleNpc::hateListHasActor( Actor& actor )
{
auto it = m_hateList.begin();
for( ; it != m_hateList.end(); ++it )
{
if( ( *it )->m_pActor == pActor )
if( ( *it )->m_pActor->getId() == actor.getId() )
return true;
}
return false;
@ -363,13 +359,13 @@ uint32_t Core::Entity::BattleNpc::getNameId() const
return m_nameId;
}
void Core::Entity::BattleNpc::hateListUpdate( ActorPtr pActor, int32_t hateAmount )
void Core::Entity::BattleNpc::hateListUpdate( Actor& actor, int32_t hateAmount )
{
auto it = m_hateList.begin();
for( ; it != m_hateList.end(); ++it )
{
if( ( *it )->m_pActor == pActor )
if( ( *it )->m_pActor->getId() == actor.getId() )
{
( *it )->m_hateAmount += hateAmount;
return;
@ -378,7 +374,7 @@ void Core::Entity::BattleNpc::hateListUpdate( ActorPtr pActor, int32_t hateAmoun
auto hateEntry = new HateListEntry();
hateEntry->m_hateAmount = hateAmount;
hateEntry->m_pActor = pActor;
hateEntry->m_pActor = actor.getAsActor();
m_hateList.insert( hateEntry );
}
@ -422,7 +418,7 @@ void Core::Entity::BattleNpc::onDeath()
auto levelDiff = static_cast< int32_t >( this->m_level ) - level;
auto cappedLevelDiff = Math::Util::clamp( levelDiff, 1, 6 );
auto expNeeded = g_exdDataGen.getParamGrow( m_level + cappedLevelDiff - 1 )->expToNext;
auto expNeeded = g_exdDataGen.get< Core::Data::ParamGrow >( m_level + cappedLevelDiff - 1 )->expToNext;
int32_t exp = 0;
// todo: arbitrary numbers pulled out of my ass
@ -452,14 +448,14 @@ void Core::Entity::BattleNpc::onDeath()
hateListClear();
}
void Core::Entity::BattleNpc::onActionHostile( ActorPtr pSource )
void Core::Entity::BattleNpc::onActionHostile( Actor& source )
{
if( hateListGetHighest() == nullptr )
aggro( pSource );
aggro( source );
if( getClaimer() == nullptr )
setOwner( pSource->getAsPlayer() );
setOwner( source.getAsPlayer() );
}
Core::Entity::ActorPtr Core::Entity::BattleNpc::getClaimer() const
@ -526,7 +522,7 @@ void Core::Entity::BattleNpc::update( int64_t currTime )
if( pClosestActor != nullptr && !pClosestActor->isAlive() )
{
hateListRemove( pClosestActor );
hateListRemove( *pClosestActor );
pClosestActor = hateListGetHighest();
}

View file

@ -24,7 +24,7 @@ class BattleNpc : public Actor
{
public:
BattleNpc();
~BattleNpc();
virtual ~BattleNpc() override;
BattleNpc( uint16_t modelId, uint16_t nameid, const Common::FFXIVARR_POSITION3& spawnPos, uint16_t bnpcBaseId = 0,
uint32_t type = 2, uint8_t level = 0, uint8_t behaviour = 1, uint32_t mobType = 0 );
@ -42,7 +42,7 @@ public:
void spawn( PlayerPtr pTarget ) override;
// send despawn packets to pTarget
void despawn( ActorPtr pTarget ) override;
void despawn( PlayerPtr pTarget ) override;
uint8_t getLevel() const override;
@ -52,12 +52,12 @@ public:
uint8_t getbehavior() const;
void hateListAdd( ActorPtr pActor, int32_t hateAmount );
void hateListAdd( Actor& actor, int32_t hateAmount );
void hateListUpdate( ActorPtr pActor, int32_t hateAmount );
void hateListRemove( ActorPtr pActor );
void hateListUpdate( Actor& actor, int32_t hateAmount );
void hateListRemove( Actor& actor );
bool hateListHasActor( ActorPtr pActor );
bool hateListHasActor( Actor& actor );
void resetPos();
@ -67,15 +67,15 @@ public:
ActorPtr hateListGetHighest();
void aggro( ActorPtr pActor );
void aggro( Actor& actor );
void deaggro( ActorPtr pActor );
void deaggro( Actor& actor );
void setOwner( PlayerPtr pPlayer );
void onDeath() override;
void onActionHostile( ActorPtr pSource ) override;
void onActionHostile( Actor& source ) override;
ActorPtr getClaimer() const;

View file

@ -5,7 +5,6 @@
#include <cmath>
#include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h>
#include <common/Util/Util.h>
#include <common/Util/UtilMath.h>
@ -21,14 +20,13 @@ using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server;
extern Core::Logger g_log;
extern Core::Data::ExdData g_exdData;
uint32_t Core::Entity::EventNpc::m_nextID = 1249241694;
Core::Entity::EventNpc::EventNpc()
Core::Entity::EventNpc::EventNpc() :
Actor( ObjKind::EventNpc )
{
m_id = 0;
m_objKind = ObjKind::EventNpc;
m_status = ActorStatus::Idle;
}
@ -37,7 +35,8 @@ Core::Entity::EventNpc::~EventNpc()
}
Core::Entity::EventNpc::EventNpc( uint32_t enpcId, const Common::FFXIVARR_POSITION3& spawnPos, float rotation ) : Actor()
Core::Entity::EventNpc::EventNpc( uint32_t enpcId, const Common::FFXIVARR_POSITION3& spawnPos, float rotation ) :
Actor( ObjKind::EventNpc )
{
EventNpc::m_nextID++;
m_id = EventNpc::m_nextID;
@ -45,8 +44,6 @@ Core::Entity::EventNpc::EventNpc( uint32_t enpcId, const Common::FFXIVARR_POSITI
m_pos = spawnPos;
m_posOrigin = spawnPos;
m_objKind = ObjKind::EventNpc;
m_targetId = static_cast< uint64_t >( INVALID_GAME_OBJECT_ID );
m_maxHp = 150;
@ -70,7 +67,8 @@ Core::Entity::EventNpc::EventNpc( uint32_t enpcId, const Common::FFXIVARR_POSITI
}
// spawn this player for pTarget
// TODO: Retail additionally sends Look+Models for EventNpcs even though it is not needed, add when the new exd reader is implemented(also counts for BNPCs)
/*! TODO: Retail additionally sends Look+Models for EventNpcs even though it is not needed,
add when the new exd reader is implemented(also counts for BNPCs) */
void Core::Entity::EventNpc::spawn( PlayerPtr pTarget )
{
ZoneChannelPacket< FFXIVIpcNpcSpawn > spawnPacket( getId(), pTarget->getId() );
@ -96,16 +94,12 @@ void Core::Entity::EventNpc::spawn( PlayerPtr pTarget )
}
// despawn
void Core::Entity::EventNpc::despawn( ActorPtr pTarget )
void Core::Entity::EventNpc::despawn( PlayerPtr pTarget )
{
auto pPlayer = pTarget->getAsPlayer();
pPlayer->freePlayerSpawnId( getId() );
pTarget->freePlayerSpawnId( getId() );
ActorControlPacket143 controlPacket( m_id, DespawnZoneScreenMsg, 0x04, getId(), 0x01 );
pPlayer->queuePacket( controlPacket );
pTarget->queuePacket( controlPacket );
}
uint8_t Core::Entity::EventNpc::getLevel() const

View file

@ -11,7 +11,7 @@ class EventNpc : public Actor
{
public:
EventNpc();
~EventNpc();
virtual ~EventNpc() override;
EventNpc( uint32_t enpcId, const Common::FFXIVARR_POSITION3& spawnPos, float rotation );
@ -19,7 +19,7 @@ public:
void spawn( PlayerPtr pTarget ) override;
// send despawn packets to pTarget
void despawn( ActorPtr pTarget ) override;
void despawn( PlayerPtr pTarget ) override;
uint8_t getLevel() const override;

View file

@ -0,0 +1,94 @@
#include "GameObject.h"
#include "Player.h"
#include "Actor.h"
#include "BattleNpc.h"
#include "EventNpc.h"
Core::Entity::GameObject::GameObject( ObjKind type ) :
m_objKind( type )
{
}
uint32_t Core::Entity::GameObject::getId() const
{
return m_id;
}
Core::Entity::GameObject::ObjKind Core::Entity::GameObject::getObjKind() const
{
return m_objKind;
}
Core::Common::FFXIVARR_POSITION3& Core::Entity::GameObject::getPos()
{
return m_pos;
}
void Core::Entity::GameObject::setPos( float x, float y, float z )
{
m_pos.x = x;
m_pos.y = y;
m_pos.z = z;
}
void Core::Entity::GameObject::setPos( const Core::Common::FFXIVARR_POSITION3& pos )
{
m_pos = pos;
}
float Core::Entity::GameObject::getRot() const
{
return m_rot;
}
void Core::Entity::GameObject::setRot( float rot )
{
m_rot = rot;
}
bool Core::Entity::GameObject::isPlayer() const
{
return m_objKind == ObjKind::Player;
}
bool Core::Entity::GameObject::isBattleNpc() const
{
return m_objKind == ObjKind::BattleNpc;
}
bool Core::Entity::GameObject::isEventNpc() const
{
return m_objKind == ObjKind::EventNpc;
}
/*! \return pointer to this instance as ActorPtr */
Core::Entity::ActorPtr Core::Entity::GameObject::getAsActor()
{
return boost::dynamic_pointer_cast< Entity::Actor, Entity::GameObject >( shared_from_this() );
}
/*! \return pointer to this instance as PlayerPtr */
Core::Entity::PlayerPtr Core::Entity::GameObject::getAsPlayer()
{
if( !isPlayer() )
return nullptr;
return boost::dynamic_pointer_cast< Entity::Player, Entity::GameObject >( shared_from_this() );
}
/*! \return pointer to this instance as BattleNpcPtr */
Core::Entity::BattleNpcPtr Core::Entity::GameObject::getAsBattleNpc()
{
if( !isBattleNpc() )
return nullptr;
return boost::dynamic_pointer_cast< Entity::BattleNpc, Entity::GameObject >( shared_from_this() );
}
/*! \return pointer to this instance as EventNpcPtr */
Core::Entity::EventNpcPtr Core::Entity::GameObject::getAsEventNpc()
{
if( !isEventNpc() )
return nullptr;
return boost::dynamic_pointer_cast< Entity::EventNpc, Entity::GameObject >( shared_from_this() );
}

View file

@ -0,0 +1,82 @@
#ifndef _GAME_OBJECT_H_
#define _GAME_OBJECT_H_
#include <common/Common.h>
#include <boost/enable_shared_from_this.hpp>
#include "Forwards.h"
#include <set>
#include <map>
#include <queue>
namespace Core {
namespace Entity {
/*!
\class GameObject
\brief Base class for all actor/objects
*/
class GameObject : public boost::enable_shared_from_this< GameObject >
{
public:
enum ObjKind : uint8_t
{
None = 0x00,
Player = 0x01,
BattleNpc = 0x02,
EventNpc = 0x03,
Treasure = 0x04,
Aetheryte = 0x05,
GatheringPoint = 0x06,
EventObj = 0x07,
Mount = 0x08,
Companion = 0x09,
Retainer = 0x0A,
Area = 0x0B,
Housing = 0x0C,
Cutscene = 0x0D,
CardStand = 0x0E,
};
protected:
/*! Position of the object */
Common::FFXIVARR_POSITION3 m_pos;
/*! Rotation of the object */
float m_rot;
/*! Id of the actor */
uint32_t m_id;
/*! Type of the actor */
ObjKind m_objKind;
public:
explicit GameObject( ObjKind type );
virtual ~GameObject() {};
virtual void spawn( PlayerPtr pTarget ) {}
virtual void despawn( PlayerPtr pTarget ) {}
uint32_t getId() const;
ObjKind getObjKind() const;
Common::FFXIVARR_POSITION3& getPos();
void setPos( const Common::FFXIVARR_POSITION3& pos );
void setPos( float x, float y, float z );
float getRot() const;
void setRot( float rot );
bool isPlayer() const;
bool isBattleNpc() const;
bool isEventNpc() const;
ActorPtr getAsActor();
PlayerPtr getAsPlayer();
BattleNpcPtr getAsBattleNpc();
EventNpcPtr getAsEventNpc();
};
}
}
#endif

View file

@ -0,0 +1,48 @@
#include "InstanceObject.h"
#include "Zone/InstanceContent.h"
Core::Entity::InstanceObject::InstanceObject( uint32_t objectId, uint32_t mapLinkId ) :
Core::Entity::GameObject( ObjKind::EventObj ),
m_mapLinkId( mapLinkId ),
m_state( 0 )
{
m_id = objectId;
}
Core::Entity::InstanceObject::InstanceObject( uint32_t objectId, uint32_t mapLinkId, Common::FFXIVARR_POSITION3 pos ) :
InstanceObject( objectId, mapLinkId )
{
}
uint32_t Core::Entity::InstanceObject::getHierachyId() const
{
return m_mapLinkId;
}
void Core::Entity::InstanceObject::setHierachyId( uint32_t hierachyId )
{
m_mapLinkId = hierachyId;
}
uint8_t Core::Entity::InstanceObject::getState() const
{
return m_state;
}
void Core::Entity::InstanceObject::setState( uint8_t state )
{
m_state = state;
//m_parentInstance->updateInstanceObj( InstanceObjectPtr( this ) );
}
void Core::Entity::InstanceObject::setParentInstance( Core::InstanceContentPtr instance )
{
m_parentInstance = instance;
}
Core::InstanceContentPtr Core::Entity::InstanceObject::getParentInstance() const
{
return m_parentInstance;
}

View file

@ -0,0 +1,33 @@
#ifndef SAPPHIRE_INSTANCEOBJECT_H
#define SAPPHIRE_INSTANCEOBJECT_H
#include "GameObject.h"
namespace Core
{
namespace Entity
{
class InstanceObject : public GameObject
{
public:
InstanceObject( uint32_t objectId, uint32_t mapLinkId );
InstanceObject( uint32_t objectId, uint32_t mapLinkId, Common::FFXIVARR_POSITION3 pos );
uint32_t getHierachyId() const;
void setHierachyId( uint32_t hierachyId );
uint8_t getState() const;
void setState( uint8_t state );
InstanceContentPtr getParentInstance() const;
void setParentInstance( InstanceContentPtr instance );
protected:
uint32_t m_mapLinkId;
uint8_t m_state;
InstanceContentPtr m_parentInstance;
};
}
}
#endif //SAPPHIRE_INSTANCEOBJECT_H

View file

@ -58,7 +58,7 @@ using namespace Core::Network::Packets::Server;
// player constructor
Core::Entity::Player::Player() :
Actor(),
Actor( ObjKind::Player ),
m_lastWrite( 0 ),
m_lastPing( 0 ),
m_bIsLogin( false ),
@ -75,10 +75,10 @@ Core::Entity::Player::Player() :
m_zoningType( Common::ZoneingType::None ),
m_bAutoattack( false ),
m_markedForRemoval( false ),
m_mount( 0 )
m_mount( 0 ),
m_directorInitialized( false )
{
m_id = 0;
m_objKind = ObjKind::Player;
m_currentStance = Stance::Passive;
m_onlineStatus = 0;
m_queuedZoneing = nullptr;
@ -95,7 +95,6 @@ Core::Entity::Player::Player() :
Core::Entity::Player::~Player()
{
g_log.debug( "PlayerObj destroyed" );
}
// TODO: add a proper calculation based on race / job / level / gear
@ -216,9 +215,9 @@ void Core::Entity::Player::calculateStats()
uint8_t level = getLevel();
uint8_t job = static_cast< uint8_t >( getClass() );
auto classInfo = g_exdDataGen.getClassJob( job );
auto tribeInfo = g_exdDataGen.getTribe( tribe );
auto paramGrowthInfo = g_exdDataGen.getParamGrow( level );
auto classInfo = g_exdDataGen.get< Core::Data::ClassJob >( job );
auto tribeInfo = g_exdDataGen.get< Core::Data::Tribe >( tribe );
auto paramGrowthInfo = g_exdDataGen.get< Core::Data::ParamGrow >( level );
// TODO: put formula somewhere else...
float base = Math::CalcStats::calculateBaseStat( getAsPlayer() );
@ -301,7 +300,7 @@ uint64_t Core::Entity::Player::getFriendsListId() const
void Core::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
{
auto data = g_exdDataGen.getAetheryte( aetheryteId );
auto data = g_exdDataGen.get< Core::Data::Aetheryte >( aetheryteId );
if( data == nullptr )
{
@ -310,7 +309,7 @@ void Core::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
setStateFlag( PlayerStateFlag::BetweenAreas );
auto z_pos = g_territoryMgr.getTerritoryPosition( data->destination );
auto z_pos = g_territoryMgr.getTerritoryPosition( data->territory );
Common::FFXIVARR_POSITION3 pos;
pos.x = 0;
@ -324,7 +323,8 @@ void Core::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
rot = z_pos->getTargetRotation();
}
sendDebug( "Teleport: " + g_exdDataGen.getPlaceName( data->placeName )->name + " " + g_exdDataGen.getPlaceName( data->aethernetName )->name +
sendDebug( "Teleport: " + g_exdDataGen.get< Core::Data::PlaceName >( data->placeName )->name + " " +
g_exdDataGen.get< Core::Data::PlaceName >( data->aethernetName )->name +
"(" + std::to_string( data->territory ) + ")" );
// TODO: this should be simplified and a type created in server_common/common.h.
@ -503,7 +503,7 @@ void Core::Entity::Player::discover( int16_t map_id, int16_t sub_id )
int32_t offset = 4;
auto info = g_exdDataGen.getMap( g_exdDataGen.getTerritoryType( getCurrentZone()->getTerritoryId() )->map );
auto info = g_exdDataGen.get< Core::Data::Map >( g_exdDataGen.get< Core::Data::TerritoryType >( getCurrentZone()->getTerritoryId() )->map );
if( info->discoveryArrayByte )
offset = 4 + 2 * info->discoveryIndex;
else
@ -518,7 +518,7 @@ void Core::Entity::Player::discover( int16_t map_id, int16_t sub_id )
uint16_t level = getLevel();
uint32_t exp = ( g_exdDataGen.getParamGrow( level )->expToNext * 5 / 100 );
uint32_t exp = ( g_exdDataGen.get< Core::Data::ParamGrow >( level )->expToNext * 5 / 100 );
gainExp( exp );
@ -595,9 +595,9 @@ void Core::Entity::Player::gainExp( uint32_t amount )
uint16_t level = getLevel();
uint32_t neededExpToLevel = g_exdDataGen.getParamGrow( level )->expToNext;
uint32_t neededExpToLevel = g_exdDataGen.get< Core::Data::ParamGrow >( level )->expToNext;
uint32_t neededExpToLevelplus1 = g_exdDataGen.getParamGrow( level + 1 )->expToNext;
uint32_t neededExpToLevelplus1 = g_exdDataGen.get< Core::Data::ParamGrow >( level + 1 )->expToNext;
queuePacket( ActorControlPacket143( getId(), GainExpMsg, static_cast< uint8_t >( getClass() ), amount ) );
@ -629,8 +629,8 @@ void Core::Entity::Player::gainExp( uint32_t amount )
void Core::Entity::Player::gainLevel()
{
setLevel( getLevel() + 1 );
setLevel( getLevel() + 1 );
calculateStats();
sendStats();
sendStatusUpdate();
@ -661,6 +661,12 @@ void Core::Entity::Player::gainLevel()
classInfoPacket.data().currentExp = getExp();
queuePacket( classInfoPacket );
}
void Core::Entity::Player::unlock()
@ -670,52 +676,30 @@ void Core::Entity::Player::unlock()
void Core::Entity::Player::sendStatusUpdate( bool toSelf )
{
// CGamePacket* pPE = new CGamePacket(0x140, 0x0128, getId(), getId());
//pPE->setInt8At(0x20, static_cast<uint8_t>(getClass()));
// pPE->setInt8At(0x21, getLevel());
// pPE->setInt8At(0x22, getLevel());
// // current exp
// pPE->setInt32At(0x28, getExp());
// // rested exp
// //pPE->setInt32At(0x2C, m_hp);
// pPE->setInt32At(0x24, m_hp);
// pPE->setInt32At(0x28, getMaxHp());
// pPE->setInt16At(0x2C, m_mp);
// pPE->setInt16At(0x2E, getMaxMp());
// pPE->setInt16At(0x30, m_tp);
// sendToInRangeSet(pPE, toSelf);
sendToInRangeSet( UpdateHpMpTpPacket( shared_from_this() ), true );
sendToInRangeSet( UpdateHpMpTpPacket( *this ), true );
}
uint8_t Core::Entity::Player::getLevel() const
{
uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast< uint8_t >( getClass() ) )->expArrayIndex;
uint8_t classJobIndex = g_exdDataGen.get< Core::Data::ClassJob >( static_cast< uint8_t >( getClass() ) )->expArrayIndex;
return static_cast< uint8_t >( m_classArray[classJobIndex] );
}
uint8_t Core::Entity::Player::getLevelForClass( Common::ClassJob pClass ) const
{
uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast< uint8_t >( pClass ) )->expArrayIndex;
uint8_t classJobIndex = g_exdDataGen.get< Core::Data::ClassJob >( static_cast< uint8_t >( pClass ) )->expArrayIndex;
return static_cast< uint8_t >( m_classArray[classJobIndex] );
}
uint32_t Core::Entity::Player::getExp() const
{
uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast< uint8_t >( getClass() ) )->expArrayIndex;
uint8_t classJobIndex = g_exdDataGen.get< Core::Data::ClassJob >( static_cast< uint8_t >( getClass() ) )->expArrayIndex;
return m_expArray[classJobIndex];
}
void Core::Entity::Player::setExp( uint32_t amount )
{
uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast< uint8_t >( getClass() ) )->expArrayIndex;
uint8_t classJobIndex = g_exdDataGen.get< Core::Data::ClassJob >( static_cast< uint8_t >( getClass() ) )->expArrayIndex;
m_expArray[classJobIndex] = amount;
}
@ -755,13 +739,13 @@ void Core::Entity::Player::setClassJob( Common::ClassJob classJob )
void Core::Entity::Player::setLevel( uint8_t level )
{
uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast< uint8_t >( getClass() ) )->expArrayIndex;
uint8_t classJobIndex = g_exdDataGen.get< Core::Data::ClassJob >( static_cast< uint8_t >( getClass() ) )->expArrayIndex;
m_classArray[classJobIndex] = level;
}
void Core::Entity::Player::setLevelForClass( uint8_t level, Common::ClassJob classjob )
{
uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast< uint8_t >( classjob ) )->expArrayIndex;
uint8_t classJobIndex = g_exdDataGen.get< Core::Data::ClassJob >( static_cast< uint8_t >( classjob ) )->expArrayIndex;
if( m_classArray[classJobIndex] == 0 )
insertDbClass( classJobIndex );
@ -844,9 +828,9 @@ void Core::Entity::Player::spawn( Entity::PlayerPtr pTarget )
}
// despawn
void Core::Entity::Player::despawn( Entity::ActorPtr pTarget )
void Core::Entity::Player::despawn( Entity::PlayerPtr pTarget )
{
auto pPlayer = pTarget->getAsPlayer();
auto pPlayer = pTarget;
pPlayer->freePlayerSpawnId( getId() );
@ -911,7 +895,7 @@ const uint8_t* Core::Entity::Player::getStateFlags() const
bool Core::Entity::Player::actionHasCastTime( uint32_t actionId ) //TODO: Add logic for special cases
{
auto actionInfoPtr = g_exdDataGen.getAction( actionId );
auto actionInfoPtr = g_exdDataGen.get< Core::Data::Action >( actionId );
if( actionInfoPtr->preservesCombo )
return false;
@ -1454,7 +1438,7 @@ void Core::Entity::Player::autoAttack( ActorPtr pTarget )
auto mainWeap = m_pInventory->getItemAt( Inventory::GearSet0,
Inventory::EquipSlot::MainHand );
pTarget->onActionHostile( shared_from_this() );
pTarget->onActionHostile( *this );
//uint64_t tick = Util::getTimeMs();
//srand(static_cast< uint32_t >(tick));
@ -1591,8 +1575,8 @@ void Player::sendZonePackets()
}
// set flags, will be reset automatically by zoning ( only on client side though )
setStateFlag( PlayerStateFlag::BetweenAreas );
setStateFlag( PlayerStateFlag::BetweenAreas1 );
//setStateFlag( PlayerStateFlag::BetweenAreas );
//setStateFlag( PlayerStateFlag::BetweenAreas1 );
sendStats();
@ -1644,5 +1628,17 @@ void Player::sendZonePackets()
if( getLastPing() == 0 )
sendQuestInfo();
getCurrentZone()->onEnterTerritory( *this );
m_bMarkedForZoning = false;
}
void Player::setDirectorInitialized( bool isInitialized )
{
m_directorInitialized = isInitialized;
}
bool Player::isDirectorInitialized() const
{
return m_directorInitialized;
}

View file

@ -430,7 +430,7 @@ public:
/*! send spawn packets to pTarget */
void spawn( PlayerPtr pTarget ) override;
/*! send despawn packets to pTarget */
void despawn( ActorPtr pTarget ) override;
void despawn( PlayerPtr pTarget ) override;
// Player State Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
@ -508,6 +508,9 @@ public:
void sendUrgent( const std::string& message );
void sendDebug( const std::string& message );
bool isDirectorInitialized() const;
void setDirectorInitialized( bool isInitialized );
// Player Battle Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
void onMobAggro( BattleNpcPtr pBNpc );
@ -575,6 +578,8 @@ private:
bool m_markedForRemoval;
bool m_directorInitialized;
private:
Common::FFXIVARR_POSITION3 m_prevPos;

View file

@ -80,7 +80,7 @@ void Core::Entity::Player::eventStart( uint64_t actorId, uint32_t eventId,
uint32_t eventParam2 )
{
Event::EventHandlerPtr newEvent( new Event::EventHandler( this, actorId, eventId, eventType, eventParam2 ) );
auto newEvent = Event::make_EventHandler( this, actorId, eventId, eventType, eventParam2 );
addEvent( newEvent );
@ -227,8 +227,8 @@ void Core::Entity::Player::eventActionStart( uint32_t eventId,
ActionCallback interruptCallback,
uint64_t additional )
{
Action::ActionPtr pEventAction( new Action::EventAction( shared_from_this(), eventId, action,
finishCallback, interruptCallback, additional ) );
auto pEventAction = Action::make_EventAction( getAsActor(), eventId, action,
finishCallback, interruptCallback, additional );
setCurrentAction( pEventAction );
auto pEvent = getEvent( eventId );
@ -257,8 +257,8 @@ void Core::Entity::Player::eventItemActionStart( uint32_t eventId,
ActionCallback interruptCallback,
uint64_t additional )
{
Action::ActionPtr pEventItemAction( new Action::EventItemAction( shared_from_this(), eventId, action,
finishCallback, interruptCallback, additional ) );
Action::ActionPtr pEventItemAction = Action::make_EventItemAction( getAsActor(), eventId, action,
finishCallback, interruptCallback, additional );
setCurrentAction( pEventItemAction );

View file

@ -1,5 +1,4 @@
#include <common/Common.h>
#include <common/Exd/ExdData.h>
#include <common/Network/GamePacket.h>
#include <common/Logging/Logger.h>

View file

@ -1015,13 +1015,13 @@ void Core::Entity::Player::removeQuestsCompleted( uint32_t questId )
bool Core::Entity::Player::giveQuestRewards( uint32_t questId, uint32_t optionalChoice )
{
uint32_t playerLevel = getLevel();
auto questInfo = g_exdDataGen.getQuest( questId );
auto questInfo = g_exdDataGen.get< Core::Data::Quest >( questId );
if( !questInfo )
return false;
auto paramGrowth = g_exdDataGen.getParamGrow( questInfo->classJobLevel0 );
auto paramGrowth = g_exdDataGen.get< Core::Data::ParamGrow >( questInfo->classJobLevel0 );
// TODO: use the correct formula, this one is wrong
uint32_t exp = ( questInfo->expFactor * paramGrowth->questExpModifier * ( 45 + 5 * questInfo->classJobLevel0 ) ) / 100;

View file

@ -60,7 +60,40 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
m_prevZoneId = res->getUInt( "OTerritoryId" );
m_prevZoneType = res->getUInt( "OTerritoryType" );
ZonePtr pCurrZone = g_territoryMgr.getZoneByTerriId( zoneId );
// Position
m_pos.x = res->getFloat( "PosX" );
m_pos.y = res->getFloat( "PosY" );
m_pos.z = res->getFloat( "PosZ" );
setRotation( res->getFloat( "PosR" ) );
m_prevPos.x = res->getFloat( "OPosX" );
m_prevPos.y = res->getFloat( "OPosY" );
m_prevPos.z = res->getFloat( "OPosZ" );
m_prevRot = res->getFloat( "OPosR" );
ZonePtr pCurrZone = nullptr;
// if the zone is an instanceContent zone, we need to actually find the instance
if( g_territoryMgr.isInstanceContentTerritory( zoneId ) )
{
// try to find an instance actually linked to this player
pCurrZone = g_territoryMgr.getLinkedInstance( m_id );
// if none found, revert to previous zone and position
if( !pCurrZone )
{
zoneId = m_prevZoneId;
m_pos.x = m_prevPos.x;
m_pos.y = m_prevPos.y;
m_pos.z = m_prevPos.z;
setRotation( m_prevRot );
pCurrZone = g_territoryMgr.getZoneByTerriId( zoneId );
}
}
else
{
pCurrZone = g_territoryMgr.getZoneByTerriId( zoneId );
}
m_zoneId = zoneId;
// TODO: logic for instances needs to be added here
@ -86,20 +119,8 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
m_mp = res->getUInt( "Mp" );
m_tp = 0;
// Position
m_pos.x = res->getFloat( "PosX" );
m_pos.y = res->getFloat( "PosY" );
m_pos.z = res->getFloat( "PosZ" );
setRotation( res->getFloat( "PosR" ) );
m_prevPos.x = res->getFloat( "OPosX" );
m_prevPos.y = res->getFloat( "OPosY" );
m_prevPos.z = res->getFloat( "OPosZ" );
m_prevRot = res->getFloat( "OPosR" );
// Model
auto custom = res->getBlobVector( "Customize" );
memcpy( reinterpret_cast< char* >( m_customize ), custom.data(), custom.size() );
@ -181,11 +202,10 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
m_modelSubWeapon = 0;
m_lastTickTime = 0;
auto pPlayer = getAsPlayer();
// TODO: remove Inventory and actually inline it in Player class
m_pInventory = InventoryPtr( new Inventory( pPlayer.get() ) );
m_pInventory = make_Inventory( this );
pPlayer->calculateStats();
calculateStats();
// first login, run the script event
if( m_bNewGame )
@ -219,6 +239,9 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
if( !m_playerIdToSpawnIdMap.empty() )
m_playerIdToSpawnIdMap.clear();
if( !g_territoryMgr.movePlayer( pCurrZone, getAsPlayer() ) )
return false;
return true;
}
@ -433,7 +456,7 @@ void Core::Entity::Player::updateSql()
void Core::Entity::Player::updateDbClass() const
{
uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast<uint8_t>( getClass() ) )->expArrayIndex;
uint8_t classJobIndex = g_exdDataGen.get< Core::Data::ClassJob >( static_cast<uint8_t>( getClass() ) )->expArrayIndex;
//Exp = ?, Lvl = ? WHERE CharacterId = ? AND ClassIdx = ?
auto stmtS = g_charaDb.getPreparedStatement( Db::CHARA_CLASS_UP );

View file

@ -27,6 +27,7 @@
#include "Actor/EventNpc.h"
#include "Zone/Zone.h"
#include "Zone/InstanceContent.h"
#include "ServerZone.h"
@ -345,7 +346,7 @@ void Core::DebugCommandHandler::add( char * data, Entity::Player& player, boost:
sscanf( params.c_str(), "%d %d %hu", &id, &duration, &param );
StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, player.getAsPlayer(), player.getAsPlayer(), duration, 3000 ) );
auto effect = StatusEffect::make_StatusEffect( id, player.getAsPlayer(), player.getAsPlayer(), duration, 3000 );
effect->setParam( param );
player.addStatusEffect( effect );
@ -364,7 +365,7 @@ void Core::DebugCommandHandler::add( char * data, Entity::Player& player, boost:
sscanf( params.c_str(), "%d %d", &model, &name );
Entity::BattleNpcPtr pBNpc( new Entity::BattleNpc( model, name, player.getPos() ) );
auto pBNpc = Entity::make_BattleNpc( model, name, player.getPos() );
auto pZone = player.getCurrentZone();
pBNpc->setCurrentZone( pZone );
@ -400,7 +401,7 @@ void Core::DebugCommandHandler::add( char * data, Entity::Player& player, boost:
// temporary research packet
int32_t opcode;
sscanf( params.c_str(), "%x", &opcode );
Network::Packets::GamePacketPtr pPe( new Network::Packets::GamePacket( opcode, 0x30, player.getId(), player.getId() ) );
auto pPe = Network::Packets::make_GamePacket( opcode, 0x30, player.getId(), player.getId() );
player.queuePacket( pPe );
}
else if( subCommand == "eventnpc-self" )
@ -424,7 +425,7 @@ void Core::DebugCommandHandler::add( char * data, Entity::Player& player, boost:
sscanf( params.c_str(), "%d", &id );
Entity::EventNpcPtr pENpc( new Entity::EventNpc( id, player.getPos(), player.getRotation() ) );
auto pENpc = Entity::make_EventNpc( id, player.getPos(), player.getRotation() );
auto pZone = player.getCurrentZone();
pENpc->setCurrentZone( pZone );
@ -505,7 +506,7 @@ void Core::DebugCommandHandler::get( char * data, Entity::Player& player, boost:
if( ( subCommand == "pos" ) )
{
int16_t map_id = g_exdDataGen.getTerritoryType( player.getCurrentZone()->getTerritoryId() )->map;
int16_t map_id = g_exdDataGen.get< Core::Data::TerritoryType >( player.getCurrentZone()->getTerritoryId() )->map;
player.sendNotice( "Pos:\n" +
std::to_string( player.getPos().x ) + "\n" +
@ -778,6 +779,53 @@ void Core::DebugCommandHandler::instance( char* data, Entity::Player &player, bo
{
player.exitInstance();
}
else if( subCommand == "set" )
{
uint32_t instanceId;
uint32_t index;
uint32_t value;
sscanf( params.c_str(), "%d %d %d", &instanceId, &index, &value );
auto pInstance = g_territoryMgr.getInstanceZonePtr( instanceId );
if( !pInstance )
return;
auto instance = boost::dynamic_pointer_cast< InstanceContent >( pInstance );
instance->setVar( static_cast< uint8_t >( index ), static_cast< uint8_t >( value ) );
}
else if( subCommand == "objupdate" )
{
uint32_t objId;
sscanf( params.c_str(), "%d", &objId );
auto instance = boost::dynamic_pointer_cast< InstanceContent >( player.getCurrentZone() );
if( !instance )
return;
auto obj = instance->getInstanceObject( objId );
if( !obj )
return;
instance->updateInstanceObj( obj );
}
else if( subCommand == "objstate" )
{
uint32_t objId;
uint8_t state;
sscanf( params.c_str(), "%d %hhu", &objId, &state );
auto instance = boost::dynamic_pointer_cast< InstanceContent >( player.getCurrentZone() );
if( !instance )
return;
auto obj = instance->getInstanceObject( objId );
if( !obj )
return;
obj->setState( state );
}
else if( subCommand == "festival" )
{
uint32_t festivalId;

View file

@ -1 +1,170 @@
#include "Director.h"
#include <common/Network/PacketDef/Ipcs.h>
#include <common/Network/PacketDef/Zone/ServerZoneDef.h>
#include "Actor/Player.h"
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
using namespace Core::Common;
using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server;
Core::Event::Director::Director( Core::Event::Director::DirectorType type, uint16_t contentId ) :
m_contentId( contentId ),
m_type( type ),
m_directorId( ( static_cast< uint32_t >( type ) << 16 ) | contentId ),
m_sequence( 1 ),
m_branch( 0 ),
m_elapsedTime( 0 )
{
memset( m_unionData.arrData, 0, sizeof( m_unionData ) );
}
uint32_t Core::Event::Director::getDirectorId() const
{
return m_directorId;
}
uint16_t Core::Event::Director::getContentId() const
{
return m_contentId;
}
uint8_t Core::Event::Director::getSequence() const
{
return m_sequence;
}
void Core::Event::Director::sendDirectorClear( Core::Entity::Player& player ) const
{
player.queuePacket( ActorControlPacket143( player.getId(), DirectorClear, m_directorId ) );
}
void Core::Event::Director::sendDirectorVars( Core::Entity::Player& player ) const
{
ZoneChannelPacket< FFXIVIpcDirectorVars > varPacket( player.getId() );
varPacket.data().m_directorId = getDirectorId();
varPacket.data().m_sequence = getSequence();
varPacket.data().m_branch = 0;
memcpy( varPacket.data().m_unionData, m_unionData.arrData, sizeof( varPacket.data().m_unionData ) );
player.queuePacket( varPacket );
}
void Core::Event::Director::sendDirectorInit( Core::Entity::Player& player ) const
{
player.queuePacket( ActorControlPacket143( player.getId(), DirectorInit, m_directorId, m_contentId ) );
}
Core::Event::Director::DirectorType Core::Event::Director::getType() const
{
return m_type;
}
uint8_t Core::Event::Director::getBranch() const
{
return m_branch;
}
void Core::Event::Director::setDirectorUI8AL( uint8_t value )
{
m_unionData.ui8lh.UI8AL = value;
}
void Core::Event::Director::setDirectorUI8AH( uint8_t value )
{
m_unionData.ui8lh.UI8AH = value;
}
void Core::Event::Director::setDirectorUI8BL( uint8_t value )
{
m_unionData.ui8lh.UI8BL = value;
}
void Core::Event::Director::setDirectorUI8BH( uint8_t value )
{
m_unionData.ui8lh.UI8BH = value;
}
void Core::Event::Director::setDirectorUI8CL( uint8_t value )
{
m_unionData.ui8lh.UI8CL = value;
}
void Core::Event::Director::setDirectorUI8CH( uint8_t value )
{
m_unionData.ui8lh.UI8CH = value;
}
void Core::Event::Director::setDirectorUI8DL( uint8_t value )
{
m_unionData.ui8lh.UI8DL = value;
}
void Core::Event::Director::setDirectorUI8DH( uint8_t value )
{
m_unionData.ui8lh.UI8DH = value;
}
void Core::Event::Director::setDirectorUI8EL( uint8_t value )
{
m_unionData.ui8lh.UI8EL = value;
}
void Core::Event::Director::setDirectorUI8EH( uint8_t value )
{
m_unionData.ui8lh.UI8EH = value;
}
void Core::Event::Director::setDirectorUI8FL( uint8_t value )
{
m_unionData.ui8lh.UI8FL = value;
}
void Core::Event::Director::setDirectorUI8FH( uint8_t value )
{
m_unionData.ui8lh.UI8FH = value;
}
void Core::Event::Director::setDirectorUI8GL( uint8_t value )
{
m_unionData.ui8lh.UI8GL = value;
}
void Core::Event::Director::setDirectorUI8GH( uint8_t value )
{
m_unionData.ui8lh.UI8GH = value;
}
void Core::Event::Director::setDirectorUI8HL( uint8_t value )
{
m_unionData.ui8lh.UI8HL = value;
}
void Core::Event::Director::setDirectorUI8HH( uint8_t value )
{
m_unionData.ui8lh.UI8HH = value;
}
void Core::Event::Director::setDirectorUI8IL( uint8_t value )
{
m_unionData.ui8lh.UI8IL = value;
}
void Core::Event::Director::setDirectorUI8IH( uint8_t value )
{
m_unionData.ui8lh.UI8IH = value;
}
void Core::Event::Director::setDirectorUI8JL( uint8_t value )
{
m_unionData.ui8lh.UI8JL = value;
}
void Core::Event::Director::setDirectorUI8JH( uint8_t value )
{
m_unionData.ui8lh.UI8JH = value;
}

View file

@ -30,9 +30,51 @@ public:
DpsChallange = 0x800D
};
Director( DirectorType type, uint16_t contentId );
uint32_t getDirectorId() const;
uint16_t getContentId() const;
DirectorType getType() const;
uint8_t getSequence() const;
uint8_t getBranch() const;
void sendDirectorInit( Entity::Player& player ) const;
void sendDirectorClear( Entity::Player& player ) const;
void sendDirectorVars( Entity::Player& player ) const;
void setDirectorUI8AL( uint8_t value );
void setDirectorUI8AH( uint8_t value );
void setDirectorUI8BL( uint8_t value );
void setDirectorUI8BH( uint8_t value );
void setDirectorUI8CL( uint8_t value );
void setDirectorUI8CH( uint8_t value );
void setDirectorUI8DL( uint8_t value );
void setDirectorUI8DH( uint8_t value );
void setDirectorUI8EL( uint8_t value );
void setDirectorUI8EH( uint8_t value );
void setDirectorUI8FL( uint8_t value );
void setDirectorUI8FH( uint8_t value );
void setDirectorUI8GL( uint8_t value );
void setDirectorUI8GH( uint8_t value );
void setDirectorUI8HL( uint8_t value );
void setDirectorUI8HH( uint8_t value );
void setDirectorUI8IL( uint8_t value );
void setDirectorUI8IH( uint8_t value );
void setDirectorUI8JL( uint8_t value );
void setDirectorUI8JH( uint8_t value );
private:
/*! Id of the content of the director */
uint16_t m_id;
uint16_t m_contentId;
/*! DirectorType | ContentId */
uint32_t m_directorId;
@ -43,17 +85,69 @@ private:
/*! current branch */
uint8_t m_branch;
union
{
struct UI8LH
{
uint8_t UI8AL : 4;
uint8_t UI8AH : 4;
uint8_t UI8BL : 4;
uint8_t UI8BH : 4;
uint8_t UI8CL : 4;
uint8_t UI8CH : 4;
uint8_t UI8DL : 4;
uint8_t UI8DH : 4;
uint8_t UI8EL : 4;
uint8_t UI8EH : 4;
uint8_t UI8FL : 4;
uint8_t UI8FH : 4;
uint8_t UI8GL : 4;
uint8_t UI8GH : 4;
uint8_t UI8HL : 4;
uint8_t UI8HH : 4;
uint8_t UI8IL : 4;
uint8_t UI8IH : 4;
uint8_t UI8JL : 4;
uint8_t UI8JH : 4;
} ui8lh;
struct UI8
{
uint8_t UI8A;
uint8_t UI8B;
uint8_t UI8C;
uint8_t UI8D;
uint8_t UI8E;
uint8_t UI8F;
uint8_t UI8G;
uint8_t UI8H;
uint8_t UI8I;
uint8_t UI8J;
} ui8;
struct FLAGS
{
uint8_t flags80;
uint8_t flags72;
uint8_t flags64;
uint8_t flags56;
uint8_t flags48;
uint8_t flags40;
uint8_t flags32;
uint8_t flags24;
uint8_t flags16;
uint8_t flags8;
} flags;
/*! raw storage for flags/vars */
uint8_t m_unionData[10];
uint8_t arrData[10];
} m_unionData;
/*! type of the director */
DirectorType m_type;
uint32_t getDirectorId() const;
uint16_t getContentId() const;
DirectorType getType() const;
uint8_t getSequence() const;
uint8_t getBranch() const;
uint32_t m_elapsedTime;
};

View file

@ -17,7 +17,7 @@ std::string Core::Event::getEventName( uint32_t eventId )
{
case Event::EventHandler::EventHandlerType::Quest:
{
auto questInfo = g_exdDataGen.getQuest( eventId );
auto questInfo = g_exdDataGen.get< Core::Data::Quest >( eventId );
if( !questInfo )
return unknown + "Quest";
@ -28,7 +28,7 @@ std::string Core::Event::getEventName( uint32_t eventId )
}
case Event::EventHandler::EventHandlerType::CustomTalk:
{
auto customTalkInfo = g_exdDataGen.getCustomTalk( eventId );
auto customTalkInfo = g_exdDataGen.get< Core::Data::CustomTalk >( eventId );
if( !customTalkInfo )
return unknown + "CustomTalk";
@ -39,14 +39,14 @@ std::string Core::Event::getEventName( uint32_t eventId )
}
case Event::EventHandler::EventHandlerType::Opening:
{
auto openingInfo = g_exdDataGen.getOpening( eventId );
auto openingInfo = g_exdDataGen.get< Core::Data::Opening >( eventId );
if( openingInfo )
return openingInfo->name;
return unknown + "Opening";
}
case Event::EventHandler::EventHandlerType::Aetheryte:
{
auto aetherInfo = g_exdDataGen.getAetheryte( eventId & 0xFFFF );
auto aetherInfo = g_exdDataGen.get< Core::Data::Aetheryte >( eventId & 0xFFFF );
if( aetherInfo->isAetheryte )
return "Aetheryte";
return "Aethernet";
@ -65,7 +65,7 @@ std::string Core::Event::getEventName( uint32_t eventId )
uint32_t Core::Event::mapEventActorToRealActor( uint32_t eventActorId )
{
auto levelInfo = g_exdDataGen.getLevel( eventActorId );
auto levelInfo = g_exdDataGen.get< Core::Data::Level >( eventActorId );
if( levelInfo )
return levelInfo->objectKey;

View file

@ -1,18 +1,24 @@
#ifndef _FORWARDS_H
#define _FORWARDS_H
#include <utility>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <vector>
#define TYPE_FORWARD( x ) \
class x; \
typedef boost::shared_ptr< x > x ## Ptr; \
template< typename...Args > \
x ## Ptr make_ ## x( Args &&...args ) { \
return boost::make_shared< x >( std::forward< Args >( args ) ... ); }\
typedef std::vector< x > x ## PtrList;
namespace Core
{
TYPE_FORWARD( Cell );
TYPE_FORWARD( Zone );
TYPE_FORWARD( InstanceContent );
TYPE_FORWARD( Item );
TYPE_FORWARD( ItemContainer );
TYPE_FORWARD( Inventory );
@ -28,11 +34,13 @@ namespace Core
namespace Entity
{
TYPE_FORWARD( GameObject );
TYPE_FORWARD( Actor );
TYPE_FORWARD( Player );
TYPE_FORWARD( BattleNpc );
TYPE_FORWARD( EventNpc );
TYPE_FORWARD( BattleNpcTemplate );
TYPE_FORWARD( InstanceObject );
}
namespace Event
@ -48,6 +56,7 @@ namespace Core
TYPE_FORWARD( ActionCast );
TYPE_FORWARD( ActionMount );
TYPE_FORWARD( EventAction );
TYPE_FORWARD( EventItemAction );
}
namespace Network

View file

@ -36,7 +36,7 @@ Core::Inventory::Inventory( Core::Entity::Player* pOwner )
// shortcut for setting up inventory
// TODO: use a loop to set theese up?
auto setupContainer = []( InventoryMap& map, InventoryType type )
{ map[type] = ItemContainerPtr( new ItemContainer( type ) ); };
{ map[type] = make_ItemContainer( type ); };
// main bags
setupContainer( m_inventoryMap, Bag0 );
@ -135,7 +135,7 @@ Core::ItemPtr Core::Inventory::getItemAt( uint16_t containerId, uint8_t slotId )
Core::ItemPtr Core::Inventory::createItem( uint32_t catalogId, uint8_t quantity )
{
auto itemInfo = g_exdDataGen.getItem( catalogId );
auto itemInfo = g_exdDataGen.get< Core::Data::Item >( catalogId );
uint8_t itemAmount = quantity;
@ -473,7 +473,7 @@ bool Core::Inventory::isObtainable( uint32_t catalogId, uint8_t quantity )
int16_t Core::Inventory::addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint8_t quantity )
{
auto itemInfo = g_exdDataGen.getItem( catalogId );
auto itemInfo = g_exdDataGen.get< Core::Data::Item >( catalogId );
// if item data doesn't exist or it's a blank field
if( !itemInfo || itemInfo->levelItem == 0 )
@ -656,7 +656,7 @@ Core::ItemPtr Core::Inventory::loadItem( uint64_t uId )
try
{
auto itemInfo = g_exdDataGen.getItem( itemRes->getUInt( 1 ) );
auto itemInfo = g_exdDataGen.get< Core::Data::Item >( itemRes->getUInt( 1 ) );
bool isHq = itemRes->getUInt( 3 ) == 1 ? true : false;
ItemPtr pItem( new Item( uId,
itemRes->getUInt( 1 ),

View file

@ -24,7 +24,7 @@ Core::Item::Item( uint64_t uId, uint32_t catalogId, uint64_t model1, uint64_t mo
m_model2( model2 ),
m_isHq( isHq )
{
auto itemInfo = g_exdDataGen.getItem( catalogId );
auto itemInfo = g_exdDataGen.get< Core::Data::Item >( catalogId );
m_delayMs = itemInfo->delayms;
m_physicalDmg = itemInfo->damagePhys;
m_magicalDmg = itemInfo->damageMag;

View file

@ -30,8 +30,8 @@ extern Core::Data::ExdDataGenerated g_exdDataGen;
uint32_t CalcBattle::calculateHealValue( PlayerPtr pPlayer, uint32_t potency )
{
auto classInfo = g_exdDataGen.getClassJob( static_cast< uint8_t >( pPlayer->getClass() ) );
auto paramGrowthInfo = g_exdDataGen.getParamGrow( pPlayer->getLevel() );
auto classInfo = g_exdDataGen.get< Core::Data::ClassJob >( static_cast< uint8_t >( pPlayer->getClass() ) );
auto paramGrowthInfo = g_exdDataGen.get< Core::Data::ParamGrow >( pPlayer->getLevel() );
if ( !classInfo || !paramGrowthInfo )
return 0;

View file

@ -61,8 +61,8 @@ uint32_t CalcStats::calculateMaxHp( PlayerPtr pPlayer )
// Is there any way to pull reliable BaseHP without having to manually use a pet for every level, and using the values from a table?
// More info here: https://docs.google.com/spreadsheets/d/1de06KGT0cNRUvyiXNmjNgcNvzBCCQku7jte5QxEQRbs/edit?usp=sharing
auto classInfo = g_exdDataGen.getClassJob( static_cast< uint8_t >( pPlayer->getClass() ) );
auto paramGrowthInfo = g_exdDataGen.getParamGrow( pPlayer->getLevel() );
auto classInfo = g_exdDataGen.get< Core::Data::ClassJob >( static_cast< uint8_t >( pPlayer->getClass() ) );
auto paramGrowthInfo = g_exdDataGen.get< Core::Data::ParamGrow >( pPlayer->getLevel() );
if ( !classInfo || !paramGrowthInfo )
return 0;
@ -94,8 +94,8 @@ uint32_t CalcStats::calculateMaxHp( PlayerPtr pPlayer )
uint32_t CalcStats::calculateMaxMp( PlayerPtr pPlayer )
{
auto classInfo = g_exdDataGen.getClassJob( static_cast< uint8_t >( pPlayer->getClass() ) );
auto paramGrowthInfo = g_exdDataGen.getParamGrow( pPlayer->getLevel() );
auto classInfo = g_exdDataGen.get< Core::Data::ClassJob >( static_cast< uint8_t >( pPlayer->getClass() ) );
auto paramGrowthInfo = g_exdDataGen.get< Core::Data::ParamGrow >( pPlayer->getLevel() );
if ( !classInfo || !paramGrowthInfo )
return 0;

View file

@ -200,11 +200,11 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
case 0xCA: // Teleport
{
// TODO: only register this action if enough gil is in possession
auto targetAetheryte = g_exdDataGen.getAetheryte( param11 );
auto targetAetheryte = g_exdDataGen.get< Core::Data::Aetheryte >( param11 );
if( targetAetheryte )
{
auto fromAetheryte = g_exdDataGen.getAetheryte( g_exdDataGen.getTerritoryType( player.getZoneId() )->aetheryte );
auto fromAetheryte = g_exdDataGen.get< Core::Data::Aetheryte >( g_exdDataGen.get< Core::Data::TerritoryType >( player.getZoneId() )->aetheryte );
// calculate cost - does not apply for favorite points or homepoints neither checks for aether tickets
auto cost = static_cast< uint16_t > ( ( sqrt( pow( fromAetheryte->aetherstreamX - targetAetheryte->aetherstreamX, 2 ) +
@ -219,7 +219,7 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
if( !insufficientGil )
{
Action::ActionTeleportPtr pActionTeleport( new Action::ActionTeleport( player.getAsPlayer(), param11, cost ) );
auto pActionTeleport = Action::make_ActionTeleport( player.getAsPlayer(), param11, cost );
player.setCurrentAction( pActionTeleport );
}
}
@ -229,6 +229,11 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
{
break;
}
case 0x321: // Director init finish
{
player.getCurrentZone()->onInitDirector( player );
break;
}
default:
{
g_log.debug( "[" + std::to_string( m_pSession->getId() ) + "] Unhandled action: " +

View file

@ -14,8 +14,13 @@
#include "Actor/Player.h"
#include "Forwards.h"
#include <common/Exd/ExdDataGenerated.h>
#include "Zone/TerritoryMgr.h"
#include "Zone/Zone.h"
extern Core::Logger g_log;
extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::TerritoryMgr g_territoryMgr;
using namespace Core::Common;
using namespace Core::Network::Packets;
@ -46,24 +51,36 @@ void Core::Network::GameConnection::cfRegisterDuty( const Packets::GamePacket& i
Entity::Player& player)
{
// TODO use for loop for this
auto contentId1 = inPacket.getValAt< uint16_t >( 46 );
auto contentId2 = inPacket.getValAt< uint16_t >( 48 );
auto contentId3 = inPacket.getValAt< uint16_t >( 50 );
auto contentId4 = inPacket.getValAt< uint16_t >( 52 );
auto contentId5 = inPacket.getValAt< uint16_t >( 54 );
auto contentId1 = inPacket.getValAt< uint16_t >( 0x2E );
auto contentId2 = inPacket.getValAt< uint16_t >( 0x30 );
auto contentId3 = inPacket.getValAt< uint16_t >( 0x32 );
auto contentId4 = inPacket.getValAt< uint16_t >( 0x34 );
auto contentId5 = inPacket.getValAt< uint16_t >( 0x36 );
player.sendDebug("Duty register request");
player.sendDebug("ContentId1" + std::to_string(contentId1));
player.sendDebug("ContentId2" + std::to_string(contentId2));
player.sendDebug("ContentId3" + std::to_string(contentId3));
player.sendDebug("ContentId4" + std::to_string(contentId4));
player.sendDebug("ContentId5" + std::to_string(contentId5));
player.sendDebug("ContentId1: " + std::to_string(contentId1));
player.sendDebug("ContentId2: " + std::to_string(contentId2));
player.sendDebug("ContentId3: " + std::to_string(contentId3));
player.sendDebug("ContentId4: " + std::to_string(contentId4));
player.sendDebug("ContentId5: " + std::to_string(contentId5));
// let's cancel it because otherwise you can't register it again
ZoneChannelPacket< FFXIVIpcCFNotify > cfCancelPacket( player.getId() );
cfCancelPacket.data().state1 = 3;
cfCancelPacket.data().state2 = 1; // Your registration is withdrawn.
queueOutPacket( cfCancelPacket );
auto cfCondition = g_exdDataGen.get< Core::Data::ContentFinderCondition >( contentId1 );
if( !cfCondition )
return;
auto instance = g_territoryMgr.createInstanceContent( cfCondition->instanceContent );
if( !instance )
return;
player.sendDebug( "Created instance with id: " + std::to_string( instance->getGuId() ) );
player.setInstance( instance );
}
void Core::Network::GameConnection::cfRegisterRoulette( const Packets::GamePacket& inPacket,

View file

@ -52,7 +52,7 @@ void Core::Network::GameConnection::eventHandlerTalk( const Packets::GamePacket&
if( !g_scriptMgr.onTalk( player, actorId, eventId ) &&
eventType == Event::EventHandler::EventHandlerType::Quest )
{
auto questInfo = g_exdDataGen.getQuest( eventId );
auto questInfo = g_exdDataGen.get< Core::Data::Quest >( eventId );
if ( questInfo )
player.sendUrgent( "Quest not implemented: " + questInfo->name + " (" + questInfo->id + ")" );
}
@ -87,7 +87,7 @@ void Core::Network::GameConnection::eventHandlerEmote( const Packets::GamePacket
if( !g_scriptMgr.onEmote( player, actorId, eventId, static_cast< uint8_t >( emoteId ) ) &&
eventType == Event::EventHandler::EventHandlerType::Quest )
{
auto questInfo = g_exdDataGen.getQuest( eventId );
auto questInfo = g_exdDataGen.get< Core::Data::Quest >( eventId );
if( questInfo )
player.sendUrgent( "Quest not implemented: " + questInfo->name );
}

View file

@ -2,7 +2,6 @@
#include <common/Network/CommonNetwork.h>
#include <common/Network/GamePacketNew.h>
#include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h>
#include <common/Network/PacketContainer.h>
#include <boost/format.hpp>
@ -38,7 +37,6 @@
extern Core::Logger g_log;
extern Core::ServerZone g_serverZone;
extern Core::TerritoryMgr g_territoryMgr;
extern Core::Data::ExdData g_exdData;
extern Core::DebugCommandHandler g_gameCommandMgr;
using namespace Core::Common;

View file

@ -2,7 +2,6 @@
#include <common/Network/CommonNetwork.h>
#include <common/Network/GamePacketNew.h>
#include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h>
#include <common/Network/PacketContainer.h>
#include <boost/format.hpp>
@ -26,7 +25,6 @@
extern Core::Logger g_log;
extern Core::ServerZone g_serverZone;
extern Core::Data::ExdData g_exdData;
extern Core::DebugCommandHandler g_gameCommandMgr;
using namespace Core::Common;

View file

@ -2,7 +2,6 @@
#include <common/Network/CommonNetwork.h>
#include <common/Network/GamePacketNew.h>
#include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h>
#include <common/Network/PacketContainer.h>
#include <common/Network/PacketDef/Chat/ServerChatDef.h>
#include <common/Database/DatabaseDef.h>
@ -42,7 +41,6 @@
extern Core::Logger g_log;
extern Core::ServerZone g_serverZone;
extern Core::TerritoryMgr g_territoryMgr;
extern Core::Data::ExdData g_exdData;
extern Core::DebugCommandHandler g_gameCommandMgr;
extern Core::Social::SocialMgr< Core::Social::FriendList > g_friendListMgr;
@ -375,7 +373,7 @@ void Core::Network::GameConnection::initHandler( const Packets::GamePacket& inPa
// init handler means this is a login procedure
player.setIsLogin( true );
player.setZone( player.getZoneId() );
player.sendZonePackets();
}
@ -408,6 +406,8 @@ void Core::Network::GameConnection::pingHandler( const Packets::GamePacket& inPa
void Core::Network::GameConnection::finishLoadingHandler( const Packets::GamePacket& inPacket,
Entity::Player& player )
{
player.getCurrentZone()->onFinishLoading( player );
// player is done zoning
player.setLoadingComplete( true );
@ -423,7 +423,7 @@ void Core::Network::GameConnection::finishLoadingHandler( const Packets::GamePac
player.spawn( player.getAsPlayer() );
// notify the zone of a change in position to force an "inRangeActor" update
player.getCurrentZone()->changeActorPosition( player.getAsPlayer() );
player.getCurrentZone()->updateActorPosition(player);
}
void Core::Network::GameConnection::socialListHandler( const Packets::GamePacket& inPacket,

View file

@ -60,7 +60,7 @@ void Core::Network::GameConnection::skillHandler( const Packets::GamePacket& inP
std::string actionIdStr = boost::str( boost::format( "%|04X|" ) % action );
player.sendDebug( "---------------------------------------" );
player.sendDebug( "ActionHandler ( " + actionIdStr + " | " +
g_exdDataGen.getAction( action )->name +
g_exdDataGen.get< Core::Data::Action >( action )->name +
" | " + std::to_string( targetId ) + " )" );
player.queuePacket( ActorControlPacket142( player.getId(), ActorControlType::ActionStart, 0x01, action ) );
@ -87,7 +87,7 @@ void Core::Network::GameConnection::skillHandler( const Packets::GamePacket& inP
}
else
{
Action::ActionCastPtr pActionCast( new Action::ActionCast( player.getAsPlayer(), targetActor, action ) );
auto pActionCast = Action::make_ActionCast( player.getAsPlayer(), targetActor, action );
player.setCurrentAction( pActionCast );
player.sendDebug( "setCurrentAction()" );
player.getCurrentAction()->onStart();
@ -100,7 +100,7 @@ void Core::Network::GameConnection::skillHandler( const Packets::GamePacket& inP
}
else if( action < 3000000 ) // item action
{
auto info = g_exdDataGen.getEventItem( action );
auto info = g_exdDataGen.get< Core::Data::EventItem >( action );
if( info )
{
g_log.debug( info->name );
@ -118,7 +118,7 @@ void Core::Network::GameConnection::skillHandler( const Packets::GamePacket& inP
player.sendDebug( "Request mount " + std::to_string( action ) );
Action::ActionMountPtr pActionMount( new Action::ActionMount( player.getAsPlayer(), action ) );
auto pActionMount = Action::make_ActionMount( player.getAsPlayer(), action );
player.setCurrentAction( pActionMount );
player.sendDebug( "setCurrentAction()" );
player.getCurrentAction()->onStart();

View file

@ -32,8 +32,6 @@ namespace Server {
void initialize( Entity::Player& player, Entity::Player& target )
{
// todo: figure out unkown offsets
// TODO: temporary gm rank
//m_data.gmRank = 0xff;
m_data.classJob = static_cast< uint8_t >( player.getClass() );
//m_data.status = static_cast< uint8_t >( pPlayer->getStatus() );

View file

@ -17,18 +17,18 @@ class UpdateHpMpTpPacket :
public ZoneChannelPacket< FFXIVIpcUpdateHpMpTp >
{
public:
UpdateHpMpTpPacket( Entity::ActorPtr pActor ) :
ZoneChannelPacket< FFXIVIpcUpdateHpMpTp >( pActor->getId(), pActor->getId() )
UpdateHpMpTpPacket( Entity::Actor& actor ) :
ZoneChannelPacket< FFXIVIpcUpdateHpMpTp >( actor.getId(), actor.getId() )
{
initialize( pActor );
initialize( actor );
};
private:
void initialize( Entity::ActorPtr pActor )
void initialize( Entity::Actor& actor )
{
m_data.hp = pActor->getHp();
m_data.mp = pActor->getMp();
m_data.tp = pActor->getTp();
m_data.hp = actor.getHp();
m_data.mp = actor.getMp();
m_data.tp = actor.getTp();
};
};

View file

@ -8,6 +8,7 @@
#include <Actor/Actor.h>
#include <Actor/Player.h>
#include <StatusEffect/StatusEffect.h>
#include <Zone/InstanceContent.h>
#ifdef _MSC_VER
#define EXPORT __declspec( dllexport )
@ -48,7 +49,7 @@ public:
class StatusEffectScript : public ScriptObject
{
public:
StatusEffectScript( uint32_t effectId ) :
explicit StatusEffectScript( uint32_t effectId ) :
ScriptObject( effectId, typeid( StatusEffectScript ).hash_code() )
{ }
@ -66,7 +67,7 @@ public:
class ActionScript : public ScriptObject
{
public:
ActionScript( uint32_t abilityId ) :
explicit ActionScript( uint32_t abilityId ) :
ScriptObject( abilityId, typeid( ActionScript ).hash_code() )
{ }
@ -79,7 +80,7 @@ public:
class EventScript : public ScriptObject
{
public:
EventScript( uint32_t questId ) :
explicit EventScript( uint32_t questId ) :
ScriptObject( questId, typeid( EventScript ).hash_code() )
{ }
@ -97,7 +98,7 @@ public:
class BattleNpcScript : public ScriptObject
{
public:
BattleNpcScript( uint32_t npcId ) :
explicit BattleNpcScript( uint32_t npcId ) :
ScriptObject( npcId, typeid( BattleNpcScript ).hash_code() )
{ }
};
@ -105,11 +106,22 @@ public:
class ZoneScript : public ScriptObject
{
public:
ZoneScript( uint32_t zoneId ) :
explicit ZoneScript( uint32_t zoneId ) :
ScriptObject( zoneId, typeid( ZoneScript ).hash_code() )
{ }
virtual void onZoneInit() { }
};
class InstanceContentScript : public ScriptObject
{
public:
explicit InstanceContentScript( uint32_t instanceContentId ) :
ScriptObject( instanceContentId, typeid( InstanceContentScript ).hash_code() )
{ }
virtual void onInit( InstanceContent& instance ) { }
virtual void onUpdate( InstanceContent& instance, uint32_t currTime ) { }
};
#endif

View file

@ -154,7 +154,7 @@ bool Core::Scripting::ScriptManager::onTalk( Entity::Player& player, uint64_t ac
// aethernet/aetherytes need to be handled separately
if( eventType == Event::EventHandler::EventHandlerType::Aetheryte )
{
auto aetherInfo = g_exdDataGen.getAetheryte( eventId & 0xFFFF );
auto aetherInfo = g_exdDataGen.get< Core::Data::Aetheryte >( eventId & 0xFFFF );
scriptId = EVENTSCRIPT_AETHERYTE_ID;
if( !aetherInfo->isAetheryte )
scriptId = EVENTSCRIPT_AETHERNET_ID;
@ -342,6 +342,30 @@ bool Core::Scripting::ScriptManager::onZoneInit( ZonePtr pZone )
return false;
}
bool Core::Scripting::ScriptManager::onInstanceInit( InstanceContent& instance )
{
auto script = m_nativeScriptManager->getScript< InstanceContentScript >( instance.getInstanceContentId() );
if( script )
{
script->onInit( instance );
return true;
}
return false;
}
bool Core::Scripting::ScriptManager::onInstanceUpdate( InstanceContent& instance, uint32_t currTime )
{
auto script = m_nativeScriptManager->getScript< InstanceContentScript >( instance.getInstanceContentId() );
if( script )
{
script->onUpdate( instance, currTime );
return true;
}
return false;
}
Scripting::NativeScriptManager& Core::Scripting::ScriptManager::getNativeScriptHandler()
{
return *m_nativeScriptManager;

View file

@ -59,6 +59,8 @@ namespace Core
bool onEventHandlerReturn( Entity::Player& player, uint32_t eventId, uint16_t subEvent, uint16_t param1, uint16_t param2, uint16_t param3 );
bool onEventHandlerTradeReturn( Entity::Player& player, uint32_t eventId, uint16_t subEvent, uint16_t param, uint32_t catalogId );
bool onInstanceInit( InstanceContent& instance );
bool onInstanceUpdate( InstanceContent& instance, uint32_t currTime );
void loadDir( const std::string& dirname, std::set<std::string> &files, const std::string& ext );

View file

@ -21,7 +21,8 @@ foreach(_scriptDir ${children})
if(IS_DIRECTORY ${_scriptDir} AND NOT ${_name} MATCHES "CMakeFiles")
message("discovered plugin lib: ${_scriptDir} (${_name})")
file(GLOB_RECURSE SCRIPT_FILES "${_scriptDir}/*.cpp")
file(GLOB_RECURSE SCRIPT_BUILD_FILES "${_scriptDir}/*.cpp")
file(GLOB_RECURSE SCRIPT_FILES RELATIVE "${_scriptDir}" "${_name}/*.cpp")
# build file list
foreach(_script ${SCRIPT_FILES})
@ -38,7 +39,7 @@ foreach(_scriptDir ${children})
endif()
endforeach()
add_library("script_${_name}" MODULE "${SCRIPT_FILES}" "${SCRIPT_INCLUDE_FILES}" "${_scriptDir}/ScriptLoader.cpp")
add_library("script_${_name}" MODULE "${SCRIPT_BUILD_FILES}" "${SCRIPT_INCLUDE_FILES}" "${_scriptDir}/ScriptLoader.cpp")
target_link_libraries("script_${_name}" sapphire_zone)
if(MSVC)
@ -55,11 +56,13 @@ foreach(_scriptDir ${children})
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/ScriptLoader.cpp.in" "${_scriptDir}/ScriptLoader.cpp")
if(MSVC)
add_custom_command(TARGET "script_${_name}" POST_BUILD
COMMAND ${CMAKE_COMMAND} -E remove "${SCRIPT_LIB_DIR}/script_${_name}.exp"
COMMAND ${CMAKE_COMMAND} -E remove "${SCRIPT_LIB_DIR}/script_${_name}.lib"
COMMAND ${CMAKE_COMMAND} -E remove "${SCRIPT_LIB_DIR}/script_${_name}.ilk"
)
endif()
unset(ScriptIncludes)
unset(ScriptNames)

View file

@ -1,8 +1,5 @@
#include <vector>
#include <Script/NativeScriptApi.h>
class ScriptObject;
@ScriptIncludes@
const ScriptObject* ptrs[] =

View file

@ -0,0 +1,27 @@
#include <ScriptObject.h>
#include <Zone/InstanceContent.h>
class TheNavel : public InstanceContentScript
{
public:
TheNavel() : InstanceContentScript( 20002 )
{ }
void onInit( InstanceContent& instance ) override
{
auto exit = new Entity::InstanceObject( EXIT_OBJECT, 0, { 0, 0, -10 } );
instance.registerInstanceObj( Entity::InstanceObjectPtr( exit ) );
auto start = new Entity::InstanceObject( START_CIRCLE, 4236868, { 0, 0, 24 } );
instance.registerInstanceObj( Entity::InstanceObjectPtr( start ) );
}
void onUpdate( InstanceContent& instance, uint32_t currTime ) override
{
}
private:
static constexpr auto EXIT_OBJECT = 2000139;
static constexpr auto START_CIRCLE = 2000182;
};

View file

@ -1,4 +1,4 @@
#include "../ScriptObject.h"
#include <ScriptObject.h>
class OpeningGridania : public EventScript
{

View file

@ -1,4 +1,4 @@
#include "../ScriptObject.h"
#include <ScriptObject.h>
// Opening Script: OpeningLimsaLominsa
// Quest Name: OpeningLimsaLominsa

View file

@ -1,4 +1,4 @@
#include "../ScriptObject.h"
#include <ScriptObject.h>
class OpeningUldah : public EventScript
{

View file

@ -196,7 +196,7 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] )
void Core::ServerZone::run( int32_t argc, char* argv[] )
{
// TODO: add more error checks for the entire initialisation
g_log.setLogPath( "log\\SapphireZone_" );
g_log.setLogPath( "log/SapphireZone_" );
g_log.init();
printBanner();

View file

@ -49,7 +49,7 @@ Core::Network::GameConnectionPtr Core::Session::getChatConnection() const
bool Core::Session::loadPlayer()
{
m_pPlayer = Entity::PlayerPtr( new Entity::Player() );
m_pPlayer = Entity::make_Player();
if( !m_pPlayer->load( m_sessionId, shared_from_this() ) )
{

View file

@ -67,5 +67,5 @@ private:
};
}
}
};
#endif /* ! _SOCIALMGR_H */

View file

@ -2,7 +2,6 @@
#include <common/Util/Util.h>
#include <common/Network/PacketDef/Zone/ServerZoneDef.h>
#include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h>
#include <boost/algorithm/string.hpp>
#include <algorithm>
@ -31,7 +30,7 @@ Core::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::ActorPtr so
, m_tickRate( tickRate )
, m_lastTick( 0 )
{
auto entry = g_exdDataGen.getStatus( id );
auto entry = g_exdDataGen.get< Core::Data::Status >( id );
m_name = entry->name;
std::replace( m_name.begin(), m_name.end(), ' ', '_' );

View file

@ -1,16 +1,37 @@
#include "InstanceContent.h"
#include <common/Common.h>
#include <common/Logging/Logger.h>
#include <common/Util/Util.h>
#include <common/Util/UtilMath.h>
#include "Event/Director.h"
#include "Script/ScriptManager.h"
#include "Actor/Player.h"
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
extern Core::Logger g_log;
extern Core::Scripting::ScriptManager g_scriptMgr;
using namespace Core::Common;
using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server;
Core::InstanceContent::InstanceContent( boost::shared_ptr< Core::Data::InstanceContent > pInstanceContent,
uint32_t guId,
const std::string& internalName,
const std::string& contentName,
uint32_t instanceContentId )
: Zone( pInstanceContent->territoryType, guId, internalName, contentName ),
: Zone( static_cast< uint16_t >( pInstanceContent->territoryType ), guId, internalName, contentName ),
Director( Event::Director::InstanceContent, instanceContentId ),
m_instanceContentInfo( pInstanceContent ),
m_instanceContentId( instanceContentId ),
m_state( Created )
{
g_scriptMgr.onInstanceInit( *this );
}
Core::InstanceContent::~InstanceContent()
@ -23,7 +44,170 @@ uint32_t Core::InstanceContent::getInstanceContentId() const
return m_instanceContentId;
}
boost::shared_ptr< Core::Data::InstanceContent > Core::InstanceContent::getInstanceContentInfo() const
Core::Data::ExdDataGenerated::InstanceContentPtr Core::InstanceContent::getInstanceContentInfo() const
{
return m_instanceContentInfo;
}
void Core::InstanceContent::onEnterTerritory( Entity::Player& player )
{
g_log.debug( "InstanceContent::onEnterTerritory: Zone#" + std::to_string( getGuId() ) + "|"
+ std::to_string( getInstanceContentId() ) +
+ ", Entity#" + std::to_string( player.getId() ) );
// mark player as "bound by duty"
player.setStateFlag( PlayerStateFlag::BoundByDuty );
// if the instance was not started yet, director init is sent on enter event.
// else it will be sent on finish loading.
if( m_state == Created )
sendDirectorInit( player );
}
void Core::InstanceContent::onLeaveTerritory( Entity::Player& player )
{
g_log.debug( "InstanceContent::onLeaveTerritory: Zone#" + std::to_string( getGuId() ) + "|"
+ std::to_string( getInstanceContentId() ) +
+ ", Entity#" + std::to_string( player.getId() ) );
sendDirectorClear( player );
player.setDirectorInitialized( false );
// remove "bound by duty" state
player.unsetStateFlag( PlayerStateFlag::BoundByDuty );
}
void Core::InstanceContent::onUpdate( uint32_t currTime )
{
switch( m_state )
{
case Created:
{
// temporary handling for instance state progression
if( m_playerMap.size() < 1 )
return;
for( const auto &playerIt : m_playerMap )
{
if( !playerIt.second->isLoadingComplete() || !playerIt.second->isDirectorInitialized() )
return;
}
for( const auto &playerIt : m_playerMap )
{
auto pPlayer = playerIt.second;
pPlayer->queuePacket(
ActorControlPacket143( pPlayer->getId(), DirectorUpdate,
getDirectorId(), 0x40000001, m_instanceContentInfo->timeLimitmin * 60u ) );
}
m_state = DutyInProgress;
m_instanceExpireTime = Util::getTimeSeconds() + ( m_instanceContentInfo->timeLimitmin * 60u );
break;
}
case DutyReset:
break;
case DutyInProgress:
{
break;
}
case DutyFinished:
break;
}
g_scriptMgr.onInstanceUpdate( *this, currTime );
}
void Core::InstanceContent::onFinishLoading( Entity::Player& player )
{
if( m_state != Created )
sendDirectorInit( player );
}
void Core::InstanceContent::onInitDirector( Entity::Player& player )
{
sendDirectorVars( player );
player.setDirectorInitialized( true );
}
void Core::InstanceContent::setVar( uint8_t index, uint8_t value )
{
if( index > 19 )
return;
switch( index )
{
case 0:
setDirectorUI8AL( value );
break;
case 1:
setDirectorUI8AH( value );
break;
case 2:
setDirectorUI8BL( value );
break;
case 3:
setDirectorUI8BH( value );
break;
case 4:
setDirectorUI8CL( value );
break;
case 5:
setDirectorUI8CH( value );
break;
case 6:
setDirectorUI8DL( value );
break;
case 7:
setDirectorUI8DH( value );
break;
case 8:
setDirectorUI8EL( value );
break;
case 9:
setDirectorUI8EH( value );
break;
case 10:
setDirectorUI8FL( value );
break;
case 11:
setDirectorUI8FH( value );
break;
case 12:
setDirectorUI8GL( value );
break;
case 13:
setDirectorUI8GH( value );
break;
case 14:
setDirectorUI8HL( value );
break;
case 15:
setDirectorUI8HH( value );
break;
case 16:
setDirectorUI8IL( value );
break;
case 17:
setDirectorUI8IH( value );
break;
case 18:
setDirectorUI8JL( value );
break;
case 19:
setDirectorUI8JH( value );
break;
}
for( const auto &playerIt : m_playerMap )
{
sendDirectorVars( *playerIt.second );
}
}

View file

@ -2,19 +2,21 @@
#define SAPPHIRE_INSTANCECONTENT_H
#include "Zone.h"
#include "Event/Director.h"
#include "Forwards.h"
#include <common/Exd/ExdDataGenerated.h>
namespace Core
{
class InstanceContent : public Zone
class InstanceContent : public Zone, Event::Director
{
public:
enum InstanceContentState
{
Created,
DutyStarted,
DutyReset,
DutyInProgress,
DutyFinished
};
@ -25,16 +27,25 @@ public:
uint32_t instanceContentId );
virtual ~InstanceContent();
boost::shared_ptr< Core::Data::InstanceContent > getInstanceContentInfo() const;
void onEnterTerritory( Entity::Player& player ) override;
void onLeaveTerritory( Entity::Player& player ) override;
void onFinishLoading( Entity::Player& player ) override;
void onInitDirector( Entity::Player& player ) override;
void onUpdate( uint32_t currTime ) override;
void setVar( uint8_t index, uint8_t value );
Core::Data::ExdDataGenerated::InstanceContentPtr getInstanceContentInfo() const;
uint32_t getInstanceContentId() const;
private:
Event::DirectorPtr m_pDirector;
boost::shared_ptr< Core::Data::InstanceContent > m_instanceContentInfo;
Core::Data::ExdDataGenerated::InstanceContentPtr m_instanceContentInfo;
uint32_t m_instanceContentId;
InstanceContentState m_state;
int64_t m_instanceExpireTime;
};
}

View file

@ -11,7 +11,6 @@
#include "InstanceContent.h"
extern Core::Logger g_log;
extern Core::Data::ExdData g_exdData;
extern Core::Data::ExdDataGenerated g_exdDataGen;
Core::TerritoryMgr::TerritoryMgr() :
@ -26,7 +25,7 @@ void Core::TerritoryMgr::loadTerritoryTypeDetailCache()
for( auto id : idList )
{
auto teri1 = g_exdDataGen.getTerritoryType( id );
auto teri1 = g_exdDataGen.get< Core::Data::TerritoryType >( id );
if( !teri1->name.empty() )
m_territoryTypeDetailCacheMap[id] = teri1;
@ -107,7 +106,7 @@ bool Core::TerritoryMgr::createDefaultTerritories()
if( territoryInfo->name.empty() )
continue;
auto pPlaceName = g_exdDataGen.getPlaceName( territoryInfo->placeName );
auto pPlaceName = g_exdDataGen.get< Core::Data::PlaceName >( territoryInfo->placeName );
if( !pPlaceName || pPlaceName->name.empty() || !isDefaultTerritory( territoryId ) )
continue;
@ -117,9 +116,10 @@ bool Core::TerritoryMgr::createDefaultTerritories()
"\t" + std::to_string( guid ) +
"\t" + std::to_string( territoryInfo->territoryIntendedUse ) +
"\t" + territoryInfo->name +
"\t" + pPlaceName->name );
"\t" + pPlaceName->name +
"\t" + ( isPrivateTerritory( territoryId ) ? "PRIVATE" : "PUBLIC" ) );
ZonePtr pZone( new Zone( territoryId, guid, territoryInfo->name, pPlaceName->name ) );
auto pZone = make_Zone( territoryId, guid, territoryInfo->name, pPlaceName->name );
pZone->init();
InstanceIdToZonePtrMap instanceMap;
@ -142,14 +142,14 @@ Core::ZonePtr Core::TerritoryMgr::createTerritoryInstance( uint32_t territoryTyp
return nullptr;
auto pTeri = getTerritoryDetail( territoryTypeId );
auto pPlaceName = g_exdDataGen.getPlaceName( pTeri->placeName );
auto pPlaceName = g_exdDataGen.get< Core::Data::PlaceName >( pTeri->placeName );
if( !pTeri || !pPlaceName )
return nullptr;
g_log.debug( "Starting instance for territory: " + std::to_string( territoryTypeId ) + " (" + pPlaceName->name + ")" );
ZonePtr pZone = ZonePtr( new Zone( territoryTypeId, getNextInstanceId(), pTeri->name, pPlaceName->name ) );
auto pZone = make_Zone( territoryTypeId, getNextInstanceId(), pTeri->name, pPlaceName->name );
pZone->init();
m_territoryInstanceMap[pZone->getTerritoryId()][pZone->getGuId()] = pZone;
@ -160,7 +160,7 @@ Core::ZonePtr Core::TerritoryMgr::createTerritoryInstance( uint32_t territoryTyp
Core::ZonePtr Core::TerritoryMgr::createInstanceContent( uint32_t instanceContentId )
{
auto pInstanceContent = g_exdDataGen.getInstanceContent( instanceContentId );
auto pInstanceContent = g_exdDataGen.get< Core::Data::InstanceContent >( instanceContentId );
if( !pInstanceContent )
return nullptr;
@ -175,8 +175,8 @@ Core::ZonePtr Core::TerritoryMgr::createInstanceContent( uint32_t instanceConten
g_log.debug( "Starting instance for InstanceContent id: " + std::to_string( instanceContentId ) +
" (" + pInstanceContent->name + ")" );
ZonePtr pZone = ZonePtr( new InstanceContent( pInstanceContent, getNextInstanceId(), pTeri->name,
pInstanceContent->name, instanceContentId ) );
auto pZone = make_InstanceContent( pInstanceContent, getNextInstanceId(),
pTeri->name, pInstanceContent->name, instanceContentId );
pZone->init();
m_instanceContentToInstanceMap[instanceContentId][pZone->getGuId()] = pZone;
@ -233,7 +233,7 @@ void Core::TerritoryMgr::loadTerritoryPositionMap()
float posO = pQR->getFloat( 6 );
uint32_t radius = pQR->getUInt( 7 );
m_territoryPositionMap[id] = ZonePositionPtr( new ZonePosition( id, targetZoneId, pos, radius, posO ) );
m_territoryPositionMap[id] = make_ZonePosition( id, targetZoneId, pos, radius, posO );
}
}
@ -275,12 +275,12 @@ void Core::TerritoryMgr::updateTerritoryInstances( uint32_t currentTime )
{
for( auto& zone : m_zoneSet )
{
zone->runZoneLogic( currentTime );
zone->update( currentTime );
}
for( auto& zone : m_instanceZoneSet )
{
zone->runZoneLogic( currentTime );
zone->update( currentTime );
}
}
@ -302,25 +302,7 @@ Core::TerritoryMgr::InstanceIdList Core::TerritoryMgr::getInstanceContentIdList(
bool Core::TerritoryMgr::movePlayer( uint32_t territoryId, Core::Entity::PlayerPtr pPlayer )
{
auto pZone = getZoneByTerriId( territoryId );
if( !pZone )
{
g_log.error( "Zone " + std::to_string( territoryId ) + " not found on this server." );
return false;
}
pPlayer->setTerritoryId( territoryId );
// mark character as zoning in progress
pPlayer->setLoadingComplete( false );
if( pPlayer->getLastPing() != 0 )
pPlayer->getCurrentZone()->removeActor( pPlayer );
pPlayer->setCurrentZone( pZone );
pZone->pushActor( pPlayer );
return true;
return movePlayer( pZone, pPlayer );
}
bool Core::TerritoryMgr::movePlayer( ZonePtr pZone, Core::Entity::PlayerPtr pPlayer )
@ -342,8 +324,21 @@ bool Core::TerritoryMgr::movePlayer( ZonePtr pZone, Core::Entity::PlayerPtr pPla
pPlayer->setCurrentZone( pZone );
pZone->pushActor( pPlayer );
// map player to instanceId so it can be tracked.
m_playerIdToInstanceMap[pPlayer->getId()] = pZone->getGuId();
return true;
}
Core::ZonePtr Core::TerritoryMgr::getLinkedInstance( uint32_t playerId ) const
{
auto it = m_playerIdToInstanceMap.find( playerId );
if( it != m_playerIdToInstanceMap.end() )
{
return getInstanceZonePtr( it->second );
}
return nullptr;
}

View file

@ -1,7 +1,7 @@
#ifndef SAPPHIRE_TERRITORYMGR_H
#define SAPPHIRE_TERRITORYMGR_H
#include <common/Exd/ExdData.h>
#include <common/Exd/ExdDataGenerated.h>
#include "Forwards.h"
#include <set>
@ -109,10 +109,12 @@ namespace Core
TODO: Mind multiple instances?! */
ZonePtr getZoneByTerriId( uint32_t territoryId ) const;
bool movePlayer( uint32_t territoryId, Entity::PlayerPtr pPlayer );
bool movePlayer( ZonePtr, Entity::PlayerPtr pPlayer );
/*! returns an instancePtr if the player is still bound to an isntance */
ZonePtr getLinkedInstance( uint32_t playerId ) const;
private:
using TerritoryTypeDetailCache = std::unordered_map< uint16_t, Data::TerritoryTypePtr >;
using InstanceIdToZonePtrMap = std::unordered_map< uint32_t, ZonePtr >;
@ -137,6 +139,9 @@ namespace Core
/*! map holding positions for zonelines */
PositionMap m_territoryPositionMap;
/*! map storing playerIds to instanceIds, used for instanceContent */
PlayerIdToInstanceIdMap m_playerIdToInstanceMap;
/*! internal counter for instanceIds */
uint32_t m_lastInstanceId;

View file

@ -35,26 +35,24 @@ extern Core::Logger g_log;
extern Core::ServerZone g_serverZone;
extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::Scripting::ScriptManager g_scriptMgr;
extern Core::TerritoryMgr g_territoryMgr;
namespace Core {
/**
* \brief
*/
Zone::Zone()
: m_territoryId( 0 )
, m_guId( 0 )
, m_type( Common::RegionType::normal )
, m_currentWeather( static_cast< uint8_t >( Common::Weather::FairSkies ) )
, m_weatherOverride( 0 )
, m_lastMobUpdate( 0 )
, m_currentFestivalId( 0 )
Core::Zone::Zone() :
m_territoryId( 0 ),
m_guId( 0 ),
m_currentWeather( static_cast< uint8_t >( Common::Weather::FairSkies ) ),
m_weatherOverride( 0 ),
m_lastMobUpdate( 0 ),
m_currentFestivalId( 0 )
{
}
Zone::Zone( uint16_t territoryId, uint32_t guId, const std::string& internalName, const std::string& placeName )
: m_type( Common::RegionType::normal )
, m_currentWeather( static_cast< uint8_t >( Common::Weather::FairSkies ) )
Core::Zone::Zone( uint16_t territoryId, uint32_t guId, const std::string& internalName, const std::string& placeName ) :
m_currentWeather( static_cast< uint8_t >( Common::Weather::FairSkies ) )
{
m_guId = guId;
@ -64,7 +62,7 @@ Zone::Zone( uint16_t territoryId, uint32_t guId, const std::string& internalName
m_lastMobUpdate = 0;
m_weatherOverride = 0;
m_territoryTypeInfo = g_exdDataGen.getTerritoryType( territoryId );
m_territoryTypeInfo = g_exdDataGen.get< Core::Data::TerritoryType >( territoryId );
uint8_t weatherRateId = m_territoryTypeInfo->weatherRate > g_exdDataGen.getWeatherRateIdList().size() ?
uint8_t{ 0 } : m_territoryTypeInfo->weatherRate;
@ -86,11 +84,11 @@ Zone::Zone( uint16_t territoryId, uint32_t guId, const std::string& internalName
m_currentWeather = getNextWeather();
}
Zone::~Zone()
Core::Zone::~Zone()
{
}
bool Zone::init()
bool Core::Zone::init()
{
memset( m_pCellCache, 0, sizeof( CellCache* ) * _sizeX );
@ -104,32 +102,27 @@ bool Zone::init()
return true;
}
bool Zone::isPrivateZone() const
{
return m_bPrivate;
}
void Zone::setWeatherOverride( uint8_t weather )
void Core::Zone::setWeatherOverride( uint8_t weather )
{
m_weatherOverride = weather;
}
uint8_t Zone::getCurrentWeather() const
uint8_t Core::Zone::getCurrentWeather() const
{
return m_currentWeather;
}
uint16_t Zone::getCurrentFestival() const
uint16_t Core::Zone::getCurrentFestival() const
{
return m_currentFestivalId;
}
void Zone::setCurrentFestival( uint16_t festivalId )
void Core::Zone::setCurrentFestival( uint16_t festivalId )
{
m_currentFestivalId = festivalId;
}
CellCache* Zone::getCellCacheList( uint32_t cellx, uint32_t celly )
Core::CellCache* Core::Zone::getCellCacheList( uint32_t cellx, uint32_t celly )
{
assert( cellx < _sizeX );
assert( celly < _sizeY );
@ -139,7 +132,7 @@ CellCache* Zone::getCellCacheList( uint32_t cellx, uint32_t celly )
return m_pCellCache[cellx][celly];
}
CellCache* Zone::getCellCacheAndCreate( uint32_t cellx, uint32_t celly )
Core::CellCache* Core::Zone::getCellCacheAndCreate( uint32_t cellx, uint32_t celly )
{
assert( cellx < _sizeX );
assert( celly < _sizeY );
@ -157,7 +150,7 @@ CellCache* Zone::getCellCacheAndCreate( uint32_t cellx, uint32_t celly )
return m_pCellCache[cellx][celly];
}
void Zone::loadCellCache()
void Core::Zone::loadCellCache()
{
auto pQR = g_charaDb.query( "SELECT Id,"
"Zoneid,"
@ -205,8 +198,7 @@ void Zone::loadCellCache()
uint32_t type = pQR->getUInt( 18 );
Common::FFXIVARR_POSITION3 pos{ posX, posY, posZ };
Entity::BattleNpcPtr pBNpc( new Entity::BattleNpc( modelId, nameId, pos,
sizeId, type, level, behaviour, mobType ) );
auto pBNpc = Entity::make_BattleNpc( modelId, nameId, pos, sizeId, type, level, behaviour, mobType );
pBNpc->setRotation( static_cast< float >( rotation ) );
cache.push_back( pBNpc );
}
@ -235,7 +227,7 @@ void Zone::loadCellCache()
}
uint8_t Zone::getNextWeather()
uint8_t Core::Zone::getNextWeather()
{
uint32_t unixTime = static_cast< uint32_t >( Util::getTimeSeconds() );
// Get Eorzea hour for weather start
@ -265,7 +257,7 @@ uint8_t Zone::getNextWeather()
return 1;
}
void Zone::pushActor( Entity::ActorPtr pActor )
void Core::Zone::pushActor( Entity::ActorPtr pActor )
{
float mx = pActor->getPos().x;
float my = pActor->getPos().z;
@ -304,7 +296,6 @@ void Zone::pushActor( Entity::ActorPtr pActor )
if( pActor->isPlayer() )
{
g_log.debug( "[Zone:" + m_internalName + "] Adding player [" + std::to_string( pActor->getId() ) + "]" );
auto pPlayer = pActor->getAsPlayer();
auto pSession = g_serverZone.getSession( pPlayer->getId() );
@ -312,9 +303,8 @@ void Zone::pushActor( Entity::ActorPtr pActor )
m_sessionSet.insert( pSession );
m_playerMap[pPlayer->getId()] = pPlayer;
updateCellActivity( cx, cy, 2 );
}
else if( pActor->isMob() )
else if( pActor->isBattleNpc() )
{
Entity::BattleNpcPtr pBNpc = pActor->getAsBattleNpc();
@ -329,9 +319,10 @@ void Zone::pushActor( Entity::ActorPtr pActor )
pENpc->setPosition( pENpc->getPos() );
}
}
void Zone::removeActor( Entity::ActorPtr pActor )
void Core::Zone::removeActor( Entity::ActorPtr pActor )
{
if( pActor->m_pCell )
@ -343,7 +334,6 @@ void Zone::removeActor( Entity::ActorPtr pActor )
if( pActor->isPlayer() )
{
g_log.debug( "[Zone:" + m_internalName + "] Removing player [" + std::to_string( pActor->getId() ) + "]" );
// If it's a player and he's inside boundaries - update his nearby cells
if( pActor->getPos().x <= _maxX && pActor->getPos().x >= _minX &&
pActor->getPos().z <= _maxY && pActor->getPos().z >= _minY )
@ -354,28 +344,23 @@ void Zone::removeActor( Entity::ActorPtr pActor )
}
m_playerMap.erase( pActor->getId() );
onLeaveTerritory( *pActor->getAsPlayer() );
}
else if( pActor->isMob() )
else if( pActor->isBattleNpc() )
m_BattleNpcMap.erase( pActor->getId() );
// remove from lists of other actors
if( pActor->hasInRangeActor() )
{
Entity::ActorPtr pCurAct;
for( auto iter = pActor->m_inRangeActors.begin(); iter != pActor->m_inRangeActors.end(); )
{
pCurAct = *iter;
auto iter2 = iter++;
pCurAct->removeInRangeActor( pActor );
}
}
pActor->removeFromInRange();
pActor->clearInRangeSet();
}
void Zone::queueOutPacketForRange( Entity::Player& sourcePlayer, uint32_t range, Network::Packets::GamePacketPtr pPacketEntry )
void Core::Zone::queueOutPacketForRange( Entity::Player& sourcePlayer, uint32_t range, Network::Packets::GamePacketPtr pPacketEntry )
{
if( g_territoryMgr.isPrivateTerritory( getTerritoryId() ) )
return;
for( auto it = m_playerMap.begin(); it != m_playerMap.end(); ++it )
{
float distance = Math::Util::distance( sourcePlayer.getPos().x,
@ -395,42 +380,32 @@ void Zone::queueOutPacketForRange( Entity::Player& sourcePlayer, uint32_t range,
}
}
uint32_t Zone::getTerritoryId()
uint32_t Core::Zone::getTerritoryId() const
{
return m_territoryId;
}
Common::RegionType Zone::getType() const
{
return m_type;
}
uint16_t Zone::getGuId() const
uint32_t Core::Zone::getGuId() const
{
return m_guId;
}
bool Zone::isInstance() const
{
return m_type == Common::RegionType::instance;
}
const std::string& Zone::getName() const
const std::string& Core::Zone::getName() const
{
return m_placeName;
}
const std::string& Zone::getInternalName() const
const std::string& Core::Zone::getInternalName() const
{
return m_internalName;
}
std::size_t Zone::getPopCount() const
std::size_t Core::Zone::getPopCount() const
{
return m_playerMap.size();
}
bool Zone::checkWeather()
bool Core::Zone::checkWeather()
{
if ( m_weatherOverride != 0 )
{
@ -454,7 +429,7 @@ bool Zone::checkWeather()
return false;
}
void Zone::updateBnpcs( int64_t tickCount )
void Core::Zone::updateBnpcs( int64_t tickCount )
{
if( ( tickCount - m_lastMobUpdate ) > 250 )
{
@ -502,7 +477,7 @@ void Zone::updateBnpcs( int64_t tickCount )
}
}
bool Zone::runZoneLogic( uint32_t currTime )
bool Core::Zone::update( uint32_t currTime )
{
int64_t tickCount = Util::getTimeMs();
@ -523,10 +498,9 @@ bool Zone::runZoneLogic( uint32_t currTime )
}
// this session is not linked to this area anymore, remove it from zone session list
if( ( !pSession->getPlayer()->getCurrentZone() ) || ( pSession->getPlayer()->getCurrentZone() != shared_from_this() ) )
if( ( !pSession->getPlayer()->getCurrentZone() )
|| ( pSession->getPlayer()->getCurrentZone() != shared_from_this() ) )
{
g_log.debug( "[Zone:" + m_internalName + "] removing session " + std::to_string( pSession->getId() ) );
if( pSession->getPlayer()->getCell() )
removeActor( pSession->getPlayer() );
@ -550,10 +524,12 @@ bool Zone::runZoneLogic( uint32_t currTime )
updateBnpcs( tickCount );
onUpdate( currTime );
return true;
}
bool Zone::isCellActive( uint32_t x, uint32_t y )
bool Core::Zone::isCellActive( uint32_t x, uint32_t y )
{
uint32_t endX = ( ( x + 1 ) <= _sizeX ) ? x + 1 : ( _sizeX - 1 );
uint32_t endY = ( ( y + 1 ) <= _sizeY ) ? y + 1 : ( _sizeY - 1 );
@ -578,7 +554,7 @@ bool Zone::isCellActive( uint32_t x, uint32_t y )
return false;
}
void Zone::updateCellActivity( uint32_t x, uint32_t y, int32_t radius )
void Core::Zone::updateCellActivity( uint32_t x, uint32_t y, int32_t radius )
{
uint32_t endX = ( x + radius ) <= _sizeX ? x + radius : ( _sizeX - 1 );
@ -632,55 +608,22 @@ void Zone::updateCellActivity( uint32_t x, uint32_t y, int32_t radius )
}
}
void Zone::changeActorPosition( Entity::ActorPtr pActor )
void Core::Zone::updateActorPosition( Entity::Actor &actor )
{
if( pActor->getCurrentZone() != shared_from_this() )
if( actor.getCurrentZone() != shared_from_this() )
return;
if( pActor->hasInRangeActor() )
{
Entity::ActorPtr pCurAct;
actor.checkInRangeActors();
float fRange = 70.0f;
for( auto iter = pActor->m_inRangeActors.begin(); iter != pActor->m_inRangeActors.end();)
{
pCurAct = *iter;
auto iter2 = iter++;
float distance = Math::Util::distance( pCurAct->getPos().x,
pCurAct->getPos().y,
pCurAct->getPos().z,
pActor->getPos().x,
pActor->getPos().y,
pActor->getPos().z );
if( fRange > 0.0f && distance > fRange )
{
pCurAct->removeInRangeActor( pActor );
if( pActor->getCurrentZone() != shared_from_this() )
return;
pActor->removeInRangeActor( *iter2 );
// @TODO FIXME!
// this break is more or less a hack, iteration will break otherwise after removing
break;
}
}
}
uint32_t cellX = getPosX( pActor->getPos().x );
uint32_t cellY = getPosY( pActor->getPos().z );
uint32_t cellX = getPosX( actor.getPos().x );
uint32_t cellY = getPosY( actor.getPos().z );
if( cellX >= _sizeX || cellY >= _sizeY )
{
return;
}
Cell* pCell = getCell( cellX, cellY );
Cell* pOldCell = pActor->m_pCell;
Cell* pOldCell = actor.m_pCell;
if( !pCell )
{
pCell = create( cellX, cellY );
@ -692,15 +635,15 @@ void Zone::changeActorPosition( Entity::ActorPtr pActor )
{
if( pOldCell )
pOldCell->removeActor( pActor );
pOldCell->removeActor( actor.getAsActor() );
pCell->addActor( pActor );
pActor->m_pCell = pCell;
pCell->addActor( actor.getAsActor() );
actor.m_pCell = pCell;
// if player we need to update cell activity
// radius = 2 is used in order to update both
// old and new cells
if( pActor->isPlayer() )
if( actor.isPlayer() )
{
updateCellActivity( cellX, cellY, 2 );
if( pOldCell != nullptr )
@ -726,17 +669,21 @@ void Zone::changeActorPosition( Entity::ActorPtr pActor )
{
pCell = getCell( posX, posY );
if( pCell )
updateInRangeSet( pActor, pCell );
updateInRangeSet( actor.getAsActor(), pCell );
}
}
}
void Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
void Core::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
{
if( pCell == nullptr )
return;
// TODO: make sure gms can overwrite this. Potentially temporary solution
if( g_territoryMgr.isPrivateTerritory( getTerritoryId() ) )
return;
Entity::ActorPtr pCurAct;
auto iter = pCell->m_actors.begin();
@ -751,12 +698,8 @@ void Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
if( !pCurAct )
continue;
float distance = Math::Util::distance( pCurAct->getPos().x,
pCurAct->getPos().y,
pCurAct->getPos().z,
pActor->getPos().x,
pActor->getPos().y,
pActor->getPos().z );
float distance = Math::Util::distance( pCurAct->getPos().x, pCurAct->getPos().y, pCurAct->getPos().z,
pActor->getPos().x, pActor->getPos().y, pActor->getPos().z );
// Add if we are not ourself and range == 0 or distance is withing range.
if( pCurAct != pActor && ( fRange == 0.0f || distance <= fRange ) )
@ -773,8 +716,9 @@ void Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
if( !pOwnPlayer->isLoadingComplete() )
continue;
// this is a hack to limit actor spawn in one packetset
count++;
if( count > 15 )
if( count > 12 )
break;
pActor->addInRangeActor( pCurAct );
@ -792,7 +736,7 @@ void Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
}
}
else if( ( pActor->isMob() || pActor->isEventNpc() ) && pCurAct->isPlayer() && pActor->isAlive() )
else if( ( pActor->isBattleNpc() || pActor->isEventNpc() ) && pCurAct->isPlayer() && pActor->isAlive() )
{
auto pPlayer = pCurAct->getAsPlayer();
if( pPlayer->isLoadingComplete() )
@ -811,4 +755,77 @@ void Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
}
}
void Core::Zone::onEnterTerritory( Entity::Player& player )
{
g_log.debug( "Zone::onEnterTerritory: Zone#" + std::to_string( getGuId() ) + "|" + std::to_string( getTerritoryId() ) +
+ ", Entity#" + std::to_string( player.getId() ) );
}
void Core::Zone::onLeaveTerritory( Entity::Player& player )
{
g_log.debug( "Zone::onLeaveTerritory: Zone#" + std::to_string( getGuId() ) + "|" + std::to_string( getTerritoryId() ) +
+ ", Entity#" + std::to_string( player.getId() ) );
}
void Core::Zone::onUpdate( uint32_t currTime )
{
}
void Core::Zone::onFinishLoading( Entity::Player& player )
{
}
void Core::Zone::onInitDirector( Entity::Player& player )
{
}
void Core::Zone::registerInstanceObj( Entity::InstanceObjectPtr object )
{
if( !object )
return;
//object->setParentInstance( InstanceContentPtr( this ) );
m_instanceObjects[object->getId()] = object;
g_log.debug( "Registered instance eobj: " + std::to_string( object->getId() ) );
}
Core::Entity::InstanceObjectPtr Core::Zone::getInstanceObject( uint32_t objId )
{
auto obj = m_instanceObjects.find( objId );
if( obj == m_instanceObjects.end() )
return nullptr;
return obj->second;
}
void Core::Zone::updateInstanceObj( Core::Entity::InstanceObjectPtr object )
{
if( !object )
return;
for( const auto& playerIt : m_playerMap )
{
// send that packet with le data
Network::Packets::ZoneChannelPacket< Network::Packets::Server::FFXIVIpcObjectSpawn > eobjStatePacket( playerIt.second->getId() );
eobjStatePacket.data().objKind = object->getObjKind();
eobjStatePacket.data().state = object->getState();
eobjStatePacket.data().objId = object->getId();
eobjStatePacket.data().hierachyId = object->getHierachyId();
eobjStatePacket.data().position = object->getPos();
// ????
//eobjStatePacket.data().levelId = 4236873;
//eobjStatePacket.data().unknown2 = 5;
//eobjStatePacket.data().unknown1C = 1065353216;
//eobjStatePacket.data().unknown20 = 2147423605;
//eobjStatePacket.data().actorId = 1074105831;
//eobjStatePacket.data().unknown = 1;
playerIt.second->queuePacket( eobjStatePacket );
}
}

View file

@ -6,6 +6,7 @@
#include "Cell.h"
#include "CellHandler.h"
#include "Actor/InstanceObject.h"
#include "Forwards.h"
@ -32,11 +33,10 @@ protected:
std::string m_placeName;
std::string m_internalName;
bool m_bPrivate;
std::unordered_map< int32_t, Entity::PlayerPtr > m_playerMap;
std::unordered_map< int32_t, Entity::BattleNpcPtr > m_BattleNpcMap;
std::unordered_map< int32_t, Entity::EventNpcPtr > m_EventNpcMap;
std::unordered_map< int32_t, Entity::InstanceObjectPtr > m_instanceObjects;
std::set< Entity::BattleNpcPtr > m_BattleNpcDeadMap;
@ -44,8 +44,6 @@ protected:
CellCache** m_pCellCache[_sizeX];
Common::RegionType m_type;
uint8_t m_currentWeather;
uint8_t m_weatherOverride;
@ -56,6 +54,8 @@ protected:
std::map< uint8_t, int32_t> m_weatherRateMap;
public:
Zone();
@ -64,8 +64,6 @@ public:
bool init();
bool isPrivateZone() const;
/*! overrides the zone's weather, set to 0 to unlock */
void setWeatherOverride( uint8_t weather );
@ -79,6 +77,12 @@ public:
CellCache* getCellCacheAndCreate( uint32_t cellx, uint32_t celly );
virtual void loadCellCache();
virtual uint32_t getTerritoryId() const;
virtual void onEnterTerritory( Entity::Player& player );
virtual void onFinishLoading( Entity::Player& player );
virtual void onInitDirector( Entity::Player& player );
virtual void onLeaveTerritory( Entity::Player& player );
virtual void onUpdate( uint32_t currTime );
uint8_t getNextWeather();
@ -86,7 +90,7 @@ public:
void removeActor( Entity::ActorPtr pActor );
void changeActorPosition( Entity::ActorPtr pActor );
void updateActorPosition( Entity::Actor &pActor );
bool isCellActive( uint32_t x, uint32_t y );
@ -96,23 +100,22 @@ public:
void queueOutPacketForRange( Entity::Player& sourcePlayer, uint32_t range, Network::Packets::GamePacketPtr pPacketEntry );
virtual uint32_t getTerritoryId();
Common::RegionType getType() const;
uint16_t getGuId() const;
bool isInstance() const;
uint32_t getGuId() const;
const std::string& getName() const;
const std::string& getInternalName() const;
std::size_t getPopCount() const;
bool checkWeather();
void updateBnpcs( int64_t tickCount );
bool runZoneLogic( uint32_t currTime );
bool update( uint32_t currTime );
void registerInstanceObj( Entity::InstanceObjectPtr object );
Entity::InstanceObjectPtr getInstanceObject( uint32_t objId );
void updateInstanceObj( Entity::InstanceObjectPtr object );
InstanceContentPtr getAsInstanceContent();
};

View file

@ -11,6 +11,7 @@
#include <ExdCat.h>
#include <Exd.h>
#include <set>
#include <boost/make_shared.hpp>
namespace Core {
namespace Data {

View file

@ -532,10 +532,6 @@
"target": "TerritoryType"
}
},
{
"index": 11,
"name": "Destination"
},
{
"index": 15,
"name": "IsAetheryte"
@ -1027,6 +1023,13 @@
"sheet": "BeastTribe",
"defaultColumn": "Name",
"definitions": [
{
"name": "MinLevel"
},
{
"index": 1,
"name": "MaxLevel"
},
{
"index": 2,
"name": "BeastRankBonus",
@ -1049,6 +1052,34 @@
"type": "icon"
}
},
{
"index": 5,
"name": "MaxRank"
},
{
"index": 6,
"name": "AlliedBeastTribeQuest",
"converter": {
"type": "link",
"target": "Quest"
}
},
{
"index": 7,
"name": "Expansion"
},
{
"index": 8,
"name": "CurrencyItem",
"converter": {
"type": "link",
"target": "Item"
}
},
{
"index": 9,
"name": "DisplayOrder"
},
{
"index": 10,
"name": "Name"
@ -3596,7 +3627,7 @@
}
},
{
"index": 3,
"index": 2,
"name": "CastTime"
}
]
@ -4846,6 +4877,29 @@
"type": "link",
"target": "Item"
}
},
{
"type": "repeat",
"count": 3,
"index": 3,
"definition": {
"name": "Row{Required}",
"converter": {
"type": "multiref",
"targets": [
"Quest",
"Achievement"
]
}
}
},
{
"index": 7,
"name": "State{Required}"
},
{
"index": 8,
"name": "Patch"
}
]
},
@ -5830,6 +5884,14 @@
"target": "ClassJobCategory"
}
},
{
"index": 13,
"name": "JournalGenre",
"converter": {
"type": "link",
"target": "JournalGenre"
}
},
{
"index": 15,
"name": "PlaceName{StartZone}",
@ -6662,6 +6724,10 @@
"target": "BGM"
}
},
{
"index": 29,
"name": "Order"
},
{
"index": 30,
"name": "Icon",
@ -6852,6 +6918,10 @@
"sheet": "OnlineStatus",
"defaultColumn": "Name",
"definitions": [
{
"index": 2,
"name": "Priority"
},
{
"index": 3,
"name": "Name"
@ -6886,6 +6956,15 @@
}
]
},
{
"sheet": "OrchestrionCategory",
"defaultColumn": "Name",
"definitions": [
{
"name": "Name"
}
]
},
{
"sheet": "OrchestrionPath",
"definitions": [
@ -6894,6 +6973,22 @@
}
]
},
{
"sheet": "OrchestrionUiparam",
"definitions": [
{
"name": "OrchestrionCategory",
"converter": {
"type": "link",
"target": "OrchestrionCategory"
}
},
{
"index": 1,
"name": "Order"
}
]
},
{
"sheet": "ParamGrow",
"definitions": [
@ -7461,6 +7556,42 @@
}
]
},
{
"sheet": "QuickChat",
"defaultColumn": "Text",
"definitions": [
{
"index": 0,
"name": "Name{Action}"
},
{
"index": 1,
"name": "Icon1",
"converter": {
"type": "icon",
"target": "Action"
}
},
{
"index": 3,
"name": "QuickChatTransient",
"converter": {
"type": "link",
"target": "QuickChatTransient"
}
}
]
},
{
"sheet": "QuickChatTransient",
"defaultColumn": "Text{Output}",
"definitions": [
{
"index": 0,
"name": "Text{Output}"
}
]
},
{
"sheet": "Race",
"defaultColumn": "Feminine",
@ -8687,6 +8818,90 @@
"isGenericReferenceTarget": true,
"definitions": []
},
{
"sheet": "SubmarineExploration",
"defaultColumn": "Destination",
"definitions": [
{
"name": "Destination"
},
{
"index": 1,
"name": "Location"
},
{
"index": 5,
"name": "RankReq"
},
{
"index": 6,
"name": "CeruleumTankReq"
},
{
"index": 7,
"name": "Duration<min>"
},
{
"index": 8,
"name": "DistanceForSurvey"
},
{
"index": 9,
"name": "ExpReward"
}
]
},
{
"sheet": "SubmarinePart",
"defaultColumn": "Slot",
"definitions": [
{
"name": "Slot"
},
{
"index": 1,
"name": "Rank"
},
{
"index": 2,
"name": "Components"
},
{
"index": 3,
"name": "Surveillance"
},
{
"index": 4,
"name": "Retrieval"
},
{
"index": 5,
"name": "Speed"
},
{
"index": 6,
"name": "Range"
},
{
"index": 7,
"name": "Favor"
},
{
"index": 9,
"name": "RepairMaterials"
}
]
},
{
"sheet": "SubmarineRank",
"defaultColumn": "Slot",
"definitions": [
{
"index": 1,
"name": "ExpToNext"
}
]
},
{
"sheet": "SwitchTalk",
"isGenericReferenceTarget": true,
@ -8971,6 +9186,52 @@
}
]
},
{
"sheet": "TreasureHuntRank",
"defaultColumn": "Name",
"definitions": [
{
"index": 1,
"name": "Icon",
"converter": {
"type": "icon",
"target": "Item"
}
},
{
"index": 2,
"name": "ItemName",
"converter": {
"type": "link",
"target": "Item"
}
},
{
"index": 3,
"name": "KeyItemName",
"converter": {
"type": "link",
"target": "EventItem"
}
},
{
"index": 4,
"name": "InstanceMap",
"converter": {
"type": "link",
"target": "EventItem"
}
},
{
"index": 5,
"name": "MaxPartySize"
},
{
"index": 6,
"name": "MinPartySize"
}
]
},
{
"sheet": "Tribe",
"defaultColumn": "Feminine",

View file

@ -31,8 +31,8 @@ Core::Logger g_log;
Core::Data::ExdData g_exdData;
bool skipUnmapped = true;
//const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" );
std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv" );
std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" );
//std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv" );
std::map< uint8_t, std::string > g_typeMap;
@ -48,9 +48,7 @@ std::string generateIdListDecl( const std::string &exd )
std::string generateDirectGetters( const std::string& exd )
{
return " using " + exd + "Ptr = boost::shared_ptr< " + exd + " >;\n" +
" " + exd + "Ptr get" + exd + "( uint32_t " + exd + "Id );\n";
return " using " + exd + "Ptr = boost::shared_ptr< " + exd + " >;\n";
}
std::string generateIdListGetter( const std::string &exd )
@ -77,25 +75,9 @@ std::string generateSetDatAccessCall( const std::string &exd )
return " m_" + exd + "Dat = setupDatAccess( \"" + exd + "\", " + lang + " );\n";
}
std::string generateDirectGetterDef( const std::string& exd )
std::string generateDirectGetterDef()
{
std::string result = "";
result =
"Core::Data::ExdDataGenerated::" + exd + "Ptr\n"
" Core::Data::ExdDataGenerated::get" + exd + "( uint32_t " + exd + "Id )\n"
"{\n"
" try\n"
" {\n"
" auto row = m_" + exd + "Dat.get_row( " + exd + "Id );\n"
" auto info = boost::make_shared< " + exd + " >( " + exd + "Id, this );\n"
" return info;\n"
" }\n"
" catch( ... )\n"
" {\n"
" return nullptr;\n"
" }\n"
" return nullptr;\n"
"}\n";
return result;
}
std::map< uint32_t, std::string > indexToNameMap;
@ -342,11 +324,28 @@ int main( int argc, char** argv )
idListsDecl += generateIdListDecl( name );
getterDecl += generateDirectGetters( name );
datAccCall += generateSetDatAccessCall( name );
getterDef += generateDirectGetterDef( name );
constructorDecl += generateConstructorsDecl( name );
idListGetters += generateIdListGetter( name );
}
getterDecl +=
"\n template< class T >\n"
" boost::shared_ptr< T > get( uint32_t id )\n"
" {\n"
" try\n"
" {\n"
" auto info = boost::make_shared< T >( id, this );\n"
" return info;\n"
" }\n"
" catch( ... )\n"
" {\n"
" return nullptr;\n"
" }\n"
" return nullptr;\n"
" }\n";
getterDef += generateDirectGetterDef();
// for all sheets in the json i guess....
std::string result;

View file

@ -10,6 +10,7 @@
#include <ExdData.h>
#include <ExdCat.h>
#include <Exd.h>
#include <boost/make_shared.hpp>
namespace Core {
namespace Data {

View file

@ -25,8 +25,8 @@ Core::Logger g_log;
Core::Data::ExdDataGenerated g_exdData;
//const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" );
const std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv" );
const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" );
//const std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv" );
int main()
@ -41,14 +41,16 @@ int main()
return 0;
}
g_log.info( "getting id list " );
auto idList = g_exdData.getTerritoryTypeIdList();
g_log.info( "getting id list done" );
for( auto id : idList )
{
auto teri1 = g_exdData.getTerritoryType( id );
auto teri1 = g_exdData.get<Core::Data::TerritoryType>( id );
g_log.info( teri1->name );
g_log.info( teri1->bg );
}
return 0;

View file

@ -13,6 +13,9 @@
#include "vec3.h"
#include "sgb.h"
// garbage to skip model loading
extern bool ignoreModels;
// all credit to
// https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Lgb/
// this is simply their work ported to c++ since we dont c#
@ -70,23 +73,30 @@ struct LGB_ENTRY_HEADER
vec3 scale;
};
class LGB_MODEL_ENTRY
class LGB_ENTRY
{
public:
char* m_buf;
uint32_t m_offset;
LGB_ENTRY_HEADER header;
LGB_MODEL_ENTRY()
LGB_ENTRY()
{
m_buf = nullptr;
m_offset = 0;
memset( &header, 0, sizeof( header ) );
};
LGB_MODEL_ENTRY( char* buf, uint32_t offset )
LGB_ENTRY( char* buf, uint32_t offset )
{
m_buf = buf;
m_offset = offset;
header = *reinterpret_cast< LGB_ENTRY_HEADER* >( buf + offset );
};
virtual ~LGB_MODEL_ENTRY() {};
const LgbEntryType getType() const
{
return header.type;
};
virtual ~LGB_ENTRY() {};
};
@ -102,7 +112,7 @@ struct LGB_BGPARTS_HEADER : public LGB_ENTRY_HEADER
uint32_t unknown9;
};
class LGB_BGPARTS_ENTRY : public LGB_MODEL_ENTRY
class LGB_BGPARTS_ENTRY : public LGB_ENTRY
{
public:
LGB_BGPARTS_HEADER header;
@ -110,7 +120,7 @@ public:
std::string modelFileName;
std::string collisionFileName;
LGB_BGPARTS_ENTRY() {};
LGB_BGPARTS_ENTRY( char* buf, uint32_t offset )
LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) : LGB_ENTRY( buf, offset )
{
header = *reinterpret_cast<LGB_BGPARTS_HEADER*>( buf + offset );
name = std::string( buf + offset + header.nameOffset );
@ -125,14 +135,14 @@ struct LGB_GIMMICK_HEADER : public LGB_ENTRY_HEADER
char unknownBytes[100];
};
class LGB_GIMMICK_ENTRY : public LGB_MODEL_ENTRY
class LGB_GIMMICK_ENTRY : public LGB_ENTRY
{
public:
LGB_GIMMICK_HEADER header;
std::string name;
std::string gimmickFileName;
LGB_GIMMICK_ENTRY( char* buf, uint32_t offset )
LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) : LGB_ENTRY( buf, offset )
{
header = *reinterpret_cast<LGB_GIMMICK_HEADER*>( buf + offset );
name = std::string( buf + offset + header.nameOffset );
@ -147,13 +157,13 @@ struct LGB_ENPC_HEADER : public LGB_ENTRY_HEADER
uint8_t unknown1[0x24];
};
class LGB_ENPC_ENTRY : public LGB_MODEL_ENTRY
class LGB_ENPC_ENTRY : public LGB_ENTRY
{
public:
LGB_ENPC_HEADER header;
std::string name;
LGB_ENPC_ENTRY( char* buf, uint32_t offset )
LGB_ENPC_ENTRY( char* buf, uint32_t offset ) : LGB_ENTRY( buf, offset )
{
header = *reinterpret_cast< LGB_ENPC_HEADER* >( buf + offset );
name = std::string( buf + offset + header.nameOffset );
@ -164,16 +174,17 @@ public:
struct LGB_EOBJ_HEADER : public LGB_ENTRY_HEADER
{
uint32_t eobjId;
uint8_t unknown1[0x10];
uint32_t levelHierachyId;
uint8_t unknown1[0xC];
};
class LGB_EOBJ_ENTRY : public LGB_MODEL_ENTRY
class LGB_EOBJ_ENTRY : public LGB_ENTRY
{
public:
LGB_EOBJ_HEADER header;
std::string name;
LGB_EOBJ_ENTRY( char* buf, uint32_t offset )
LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) : LGB_ENTRY( buf, offset )
{
header = *reinterpret_cast< LGB_EOBJ_HEADER* >( buf + offset );
//std::cout << "\t " << header.eobjId << " " << name << " unknown: " << header.unknown << "\n";
@ -181,6 +192,27 @@ public:
};
};
struct LGB_MAPRANGE_HEADER : public LGB_ENTRY_HEADER
{
uint32_t type;
uint16_t unknown2;
uint16_t unknown3;
uint8_t unknown4[0x10];
};
struct LGB_MAPRANGE_ENTRY : public LGB_ENTRY
{
public:
LGB_MAPRANGE_HEADER header;
std::string name;
LGB_MAPRANGE_ENTRY( char* buf, uint32_t offset ) : LGB_ENTRY( buf, offset )
{
header = *reinterpret_cast< LGB_MAPRANGE_HEADER* >( buf + offset );
name = std::string( buf + offset + header.nameOffset );
};
};
struct LGB_GROUP_HEADER
{
uint32_t unknown;
@ -203,7 +235,7 @@ struct LGB_GROUP
LGB_FILE* parent;
LGB_GROUP_HEADER header;
std::string name;
std::vector< std::shared_ptr< LGB_MODEL_ENTRY > > entries;
std::vector< std::shared_ptr< LGB_ENTRY > > entries;
LGB_GROUP( char* buf, LGB_FILE* parentStruct, uint32_t offset )
{
@ -220,11 +252,12 @@ struct LGB_GROUP
try
{
const auto type = *reinterpret_cast<LgbEntryType*>( buf + entryOffset );
if( type == LgbEntryType::BgParts )
// garbage to skip model loading
if( !ignoreModels && type == LgbEntryType::BgParts )
{
entries.push_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) );
}
else if( type == LgbEntryType::Gimmick )
else if( !ignoreModels && type == LgbEntryType::Gimmick )
{
entries.push_back( std::make_shared< LGB_GIMMICK_ENTRY >( buf, entryOffset ) );
}
@ -236,12 +269,17 @@ struct LGB_GROUP
{
entries.push_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) );
}
else if( type == LgbEntryType::MapRange )
{
entries.push_back( std::make_shared< LGB_MAPRANGE_ENTRY >( buf, entryOffset ) );
}
/*
else
{
//entries[i] = nullptr;
entries[i] = nullptr;
}
*/
}
catch( std::exception& e )
{
@ -268,8 +306,9 @@ struct LGB_FILE
{
LGB_FILE_HEADER header;
std::vector< LGB_GROUP > groups;
std::string name;
LGB_FILE( char* buf )
LGB_FILE( char* buf, const std::string& name )
{
header = *reinterpret_cast< LGB_FILE_HEADER* >( buf );
if( strncmp( &header.magic[0], "LGB1", 4 ) != 0 || strncmp( &header.magic2[0], "LGP1", 4 ) != 0 )

View file

@ -6,6 +6,8 @@
#include <fstream>
#include <regex>
#include <map>
#include <vector>
#include <set>
#include "pcb.h"
#include "lgb.h"
@ -21,8 +23,17 @@
#include <boost/algorithm/string.hpp>
#endif
std::string gamePath("C:\\Program Files (x86)\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv");
// garbage to ignore models
bool ignoreModels = false;
std::string gamePath( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" );
std::unordered_map< uint32_t, std::string > eobjNameMap;
std::unordered_map< uint16_t, std::string > zoneNameMap;
std::unordered_map< uint16_t, std::vector< std::pair< uint16_t, std::string > > > zoneInstanceMap;
uint32_t zoneId;
std::set< std::string > zoneDumpList;
xiv::dat::GameData* data1 = nullptr;
xiv::exd::ExdData* eData = nullptr;
@ -103,8 +114,8 @@ int parseBlockEntry( char* data, std::vector<PCB_BLOCK_ENTRY>& entries, int gOff
void dumpLevelExdEntries( uint32_t zoneId, const std::string& name = std::string() )
{
auto& cat = eData->get_category( "Level" );
auto exd = static_cast< xiv::exd::Exd >( cat.get_data_ln( xiv::exd::Language::none ) );
static auto& cat = eData->get_category( "Level" );
static auto exd = static_cast< xiv::exd::Exd >( cat.get_data_ln( xiv::exd::Language::none ) );
std::string fileName( name + "_" + std::to_string( zoneId ) + "_Level" + ".csv" );
std::ofstream outfile( fileName, std::ios::trunc );
@ -113,8 +124,8 @@ void dumpLevelExdEntries( uint32_t zoneId, const std::string& name = std::string
{
outfile.close();
outfile.open( fileName, std::ios::app );
for( auto& row : exd.get_rows() )
static auto rows = exd.get_rows();
for( auto& row : rows )
{
auto id = row.first;
auto& fields = row.second;
@ -143,7 +154,8 @@ void dumpLevelExdEntries( uint32_t zoneId, const std::string& name = std::string
std::string zoneNameToPath( const std::string& name )
{
std::string path;
uint32_t id;
bool found = false;
#ifdef STANDALONE
auto inFile = std::ifstream( "territorytype.exh.csv" );
if( inFile.good() )
@ -153,22 +165,23 @@ std::string zoneNameToPath( const std::string& name )
while( std::getline( inFile, line ) )
{
std::smatch match;
if( std::regex_match( line, match, re ) )
if( std::regex_match( line, match, re )
{
if( name == match[2].str() )
auto tmpId = std::stoul( match[1].str() );
if( !found && name == match[2].str() )
{
id = match[1].str();
zoneId = tmpId;
path = match[3].str();
break;
found = true;
}
zoneNameMap[tmpId] = match[2].str();
}
}
inFile.close();
}
#else
xiv::dat::GameData dat( gamePath );
xiv::exd::ExdData eData( dat );
auto& cat = eData.get_category( "TerritoryType" );
auto& cat = eData->get_category( "TerritoryType" );
auto exd = static_cast< xiv::exd::Exd >( cat.get_data_ln( xiv::exd::Language::none ) );
for( auto& row : exd.get_rows() )
{
@ -177,16 +190,17 @@ std::string zoneNameToPath( const std::string& name )
if( teriName.empty() )
continue;
auto teriPath = *boost::get< std::string >( &fields.at( static_cast< size_t >( TerritoryTypeExdIndexes::Path ) ) );
id = row.first;
if( boost::iequals( name, teriName ) )
if( !found && boost::iequals( name, teriName ) )
{
path = teriPath;
break;
found = true;
zoneId = row.first;
}
zoneNameMap[row.first] = teriName;
}
#endif
if( !path.empty() )
if( found )
{
//path = path.substr( path.find_first_of( "/" ) + 1, path.size() - path.find_first_of( "/" ));
//path = std::string( "ffxiv/" ) + path;
@ -198,7 +212,7 @@ std::string zoneNameToPath( const std::string& name )
throw std::runtime_error( "Unable to find path for " + name +
".\n\tPlease double check spelling or open 0a0000.win32.index with FFXIV Explorer and extract territorytype.exh as CSV\n\tand copy territorytype.exh.csv into pcb_reader.exe directory if using standalone" );
}
dumpLevelExdEntries( id, name );
return path;
}
@ -215,15 +229,87 @@ void loadEobjNames()
}
}
void writeEobjEntry( std::ofstream& out, LGB_EOBJ_ENTRY* pEobj, const std::string& name )
void writeEobjEntry( std::ofstream& out, LGB_ENTRY* pObj )
{
static std::string mapRangeStr( "\"MapRange\", " );
static std::string eobjStr( "\"EObj\", " );
uint32_t id;
uint32_t unknown = 0, unknown2 = 0;
std::string name;
std::string typeStr;
uint32_t eobjlevelHierachyId = 0;
if( pObj->getType() == LgbEntryType::EventObject )
{
auto pEobj = reinterpret_cast< LGB_EOBJ_ENTRY* >( pObj );
id = pEobj->header.eobjId;
unknown = pEobj->header.unknown;
name = eobjNameMap[id];
typeStr = eobjStr;
eobjlevelHierachyId = pEobj->header.levelHierachyId;
}
else if( pObj->getType() == LgbEntryType::MapRange )
{
auto pMapRange = reinterpret_cast< LGB_MAPRANGE_ENTRY* >( pObj );
id = pMapRange->header.unknown;
unknown = pMapRange->header.unknown2;
unknown2 = pMapRange->header.unknown3;
typeStr = mapRangeStr;
}
std::string outStr(
std::to_string( pEobj->header.eobjId ) + ", \"" + name + "\", " +
std::to_string( pEobj->header.translation.x ) + ", " + std::to_string( pEobj->header.translation.y ) + ", " + std::to_string( pEobj->header.translation.z ) + "\n"
std::to_string( id ) + ", " + typeStr + "\"" + name + "\", " +
std::to_string( pObj->header.translation.x ) + ", " + std::to_string( pObj->header.translation.y ) + ", " + std::to_string( pObj->header.translation.z ) +
", " + std::to_string( eobjlevelHierachyId ) + "\n"
);
out.write( outStr.c_str(), outStr.size() );
}
void loadAllInstanceContentEntries()
{
auto& catInstance = eData->get_category( "InstanceContent" );
auto exdInstance = static_cast< xiv::exd::Exd >( catInstance.get_data_ln( xiv::exd::Language::en ) );
if( zoneNameMap.size() == 0 )
{
zoneNameToPath( "f1d1" );
}
std::ofstream out( "instancecontent.csv", std::ios::trunc );
if( out.good() )
{
out.close();
}
out.open( "instancecontent.csv", std::ios::app );
if( !out.good() )
{
throw std::runtime_error( "Unable to create instancecontent.csv!" );
}
std::cout << "[Info] Writing instancecontent.csv\n";
for( auto& row : exdInstance.get_rows() )
{
auto id = row.first;
auto& fields = row.second;
auto name = *boost::get< std::string >( &fields.at( 3 ) );
if( name.empty() )
continue;
auto teri = *boost::get< uint32_t >( &fields.at( 9 ) );
auto i = 0;
while( ( i = name.find( ' ' ) ) != std::string::npos )
name = name.replace( name.begin() + i, name.begin() + i + 1, { '_' } );
std::string outStr(
std::to_string( id ) + ", \"" + name + "\", \"" + zoneNameMap[teri] + "\"," + std::to_string( teri ) + "\n"
);
out.write( outStr.c_str(), outStr.size() );
//zoneInstanceMap[zoneId].push_back( std::make_pair( id, name ) );
zoneDumpList.emplace( zoneNameMap[teri] );
}
out.close();
}
void readFileToBuffer( const std::string& path, std::vector< char >& buf )
{
auto inFile = std::ifstream( path, std::ios::binary );
@ -245,22 +331,41 @@ void readFileToBuffer( const std::string& path, std::vector< char >& buf )
int main( int argc, char* argv[] )
{
auto startTime = std::chrono::system_clock::now();
auto entryStartTime = std::chrono::system_clock::now();
std::vector< std::string > argVec( argv + 1, argv + argc );
// todo: support expansions
std::string zoneName = "r1f1";
std::string zoneName = "r2t2";
bool dumpInstances = ignoreModels = std::remove_if( argVec.begin(), argVec.end(), []( auto arg ){ return arg == "--instance-dump"; } ) != argVec.end();
if( argc > 1 )
{
zoneName = argv[1];
if( argc > 2 )
{
std::string tmpPath( argv[2] );
if( !tmpPath.empty() )
gamePath = argv[2];
}
}
initExd( gamePath );
if( dumpInstances )
{
loadAllInstanceContentEntries();
}
else
{
zoneDumpList.emplace( zoneName );
}
LABEL_DUMP:
entryStartTime = std::chrono::system_clock::now();
zoneName = *zoneDumpList.begin();
try
{
const auto& zonePath = zoneNameToPath( zoneName );
std::string listPcbPath( zonePath + "/collision/list.pcb" );
std::string bgLgbPath( zonePath + "/level/bg.lgb" );
std::string planmapLgbPath( zonePath + "/level/planmap.lgb" );
@ -270,15 +375,15 @@ int main( int argc, char* argv[] )
std::vector< char > section2;
#ifndef STANDALONE
const xiv::dat::Cat& test = data1->get_category( "bg" );
const xiv::dat::Cat& test = data1->getCategory( "bg" );
auto test_file = data1->get_file( bgLgbPath );
auto test_file = data1->getFile( bgLgbPath );
section = test_file->access_data_sections().at( 0 );
auto planmap_file = data1->get_file( planmapLgbPath );
auto planmap_file = data1->getFile( planmapLgbPath );
section2 = planmap_file->access_data_sections().at( 0 );
auto test_file1 = data1->get_file( listPcbPath );
auto test_file1 = data1->getFile( listPcbPath );
section1 = test_file1->access_data_sections().at( 0 );
#else
{
@ -292,7 +397,8 @@ int main( int argc, char* argv[] )
uint32_t offset1 = 0x20;
loadEobjNames();
std::string eobjFileName( zoneName + "eobj.csv" );
dumpLevelExdEntries( zoneId, zoneName );
std::string eobjFileName( zoneName + "_eobj.csv" );
std::ofstream eobjOut( eobjFileName, std::ios::trunc );
if( !eobjOut.good() )
throw std::string( "Unable to create " + zoneName + "_eobj.csv for eobj entries. Run as admin or check there isnt already a handle on the file." ).c_str();
@ -300,6 +406,11 @@ int main( int argc, char* argv[] )
eobjOut.close();
eobjOut.open( eobjFileName, std::ios::app );
if( !eobjOut.good() )
throw std::string( "Unable to create " + zoneName + "_eobj.csv for eobj entries. Run as admin or check there isnt already a handle on the file." ).c_str();
if( !ignoreModels )
{
for( ; ; )
{
@ -316,21 +427,21 @@ int main( int argc, char* argv[] )
break;
}
}
LGB_FILE bgLgb( &section[0] );
LGB_FILE planmapLgb( &section2[0] );
}
LGB_FILE bgLgb( &section[0], "bg" );
LGB_FILE planmapLgb( &section2[0], "planmap" );
std::vector< LGB_FILE > lgbList { bgLgb, planmapLgb };
uint32_t max_index = 0;
// dont bother if we cant write to a file
auto fp_out = fopen( ( zoneName + ".obj" ).c_str(), "w" );
auto fp_out = ignoreModels ? ( FILE* )nullptr : fopen( ( zoneName + ".obj" ).c_str(), "w" );
if( fp_out )
{
fprintf( fp_out, "\n" );
fclose( fp_out );
}
else
else if( !ignoreModels )
{
std::string errorMessage( "Cannot create " + zoneName + ".obj\n" +
" Check no programs have a handle to file and run as admin.\n" );
@ -339,14 +450,15 @@ int main( int argc, char* argv[] )
return 0;
}
fp_out = fopen( ( zoneName + ".obj" ).c_str(), "ab+" );
if( fp_out )
if( ignoreModels || ( fp_out = fopen( ( zoneName + ".obj" ).c_str(), "ab+" ) ) )
{
std::map< std::string, PCB_FILE > pcbFiles;
std::map< std::string, SGB_FILE > sgbFiles;
std::map< std::string, uint32_t > objCount;
auto loadPcbFile = [&]( const std::string& fileName ) -> bool
{
if( ignoreModels )
return false;
try
{
if( fileName.find( '.' ) == std::string::npos )
@ -357,7 +469,7 @@ int main( int argc, char* argv[] )
char* dataSection = nullptr;
//std::cout << fileName << " ";
#ifndef STANDALONE
auto file = data1->get_file( fileName );
auto file = data1->getFile( fileName );
auto sections = file->get_data_sections();
dataSection = &sections.at( 0 )[0];
#else
@ -409,7 +521,7 @@ int main( int argc, char* argv[] )
char* dataSection = nullptr;
//std::cout << fileName << " ";
#ifndef STANDALONE
auto file = data1->get_file( fileName );
auto file = data1->getFile( fileName );
auto sections = file->get_data_sections();
dataSection = &sections.at( 0 )[0];
#else
@ -434,6 +546,8 @@ int main( int argc, char* argv[] )
const vec3* translation = nullptr,
const SGB_MODEL_ENTRY* pSgbEntry = nullptr)
{
if( ignoreModels )
return;
char name2[0x100];
memset( name2, 0, 0x100 );
sprintf( &name2[0], "%s_%u", &name[0], objCount[name]++ );
@ -511,19 +625,22 @@ int main( int argc, char* argv[] )
}
};
if( !ignoreModels )
{
for( const auto& fileName : stringList )
{
loadPcbFile( fileName );
pushVerts( pcbFiles[fileName], fileName );
}
std::cout << "[Info] " << "Writing obj file " << "\n";
std::cout << "[Info] " << bgLgb.groups.size() << " groups " << "\n";
}
std::cout << "[Info] " << ( ignoreModels ? "Dumping MapRange and EObj" : "Writing obj file " ) << "\n";
uint32_t totalGroups = 0;
uint32_t totalGroupEntries = 0;
for( const auto& lgb : lgbList )
{
for( const auto& group : bgLgb.groups )
for( const auto& group : lgb.groups )
{
//std::cout << "\t" << group.name << " Size " << group.header.entryCount << "\n";
totalGroups++;
@ -531,7 +648,6 @@ int main( int argc, char* argv[] )
{
auto pGimmick = dynamic_cast< LGB_GIMMICK_ENTRY* >( pEntry.get() );
auto pBgParts = dynamic_cast< LGB_BGPARTS_ENTRY* >( pEntry.get() );
auto pEventObj = dynamic_cast< LGB_EOBJ_ENTRY* >( pEntry.get() );
std::string fileName( "" );
fileName.resize( 256 );
@ -591,20 +707,19 @@ int main( int argc, char* argv[] )
}
}
if( pEventObj )
if( pEntry->getType() == LgbEntryType::EventObject || pEntry->getType() == LgbEntryType::MapRange )
{
fileName = pEventObj->name.empty() ? eobjNameMap[pEventObj->header.eobjId] : pEventObj->name;
writeEobjEntry( eobjOut, pEventObj, fileName );
//writeOutput( fileName, &pEventObj->header.scale, &pEventObj->header.rotation, &pEventObj->header.translation );
writeEobjEntry( eobjOut, pEntry.get() );
writeOutput( fileName, &pEntry->header.scale, &pEntry->header.rotation, &pEntry->header.translation );
}
}
}
}
std::cout << "\n[Info] " << "Loaded " << pcbFiles.size() << " PCB Files \n";
std::cout << "[Info] " << "Loaded " << pcbFiles.size() << " PCB Files \n";
std::cout << "[Info] " << "Total Groups " << totalGroups << " Total entries " << totalGroupEntries << "\n";
}
std::cout << "[Success] " << "Finished exporting " << zoneName << " in " <<
std::chrono::duration_cast< std::chrono::seconds >( std::chrono::system_clock::now() - startTime ).count() << " seconds\n";
std::cout << "[Success] " << "Exported " << zoneName << " in " <<
std::chrono::duration_cast< std::chrono::seconds >( std::chrono::system_clock::now() - entryStartTime ).count() << " seconds\n";
}
catch( std::exception& e )
{
@ -613,6 +728,16 @@ int main( int argc, char* argv[] )
std::cout << std::endl;
std::cout << "[Info] " << "Usage: pcb_reader2 territory \"path/to/game/sqpack/ffxiv\" " << std::endl;
}
std::cout << "\n\n\n";
LABEL_NEXT_ZONE_ENTRY:
zoneDumpList.erase( zoneName );
if( !zoneDumpList.empty() )
goto LABEL_DUMP;
std::cout << "\n\n\n[Success] Finished all tasks in " <<
std::chrono::duration_cast< std::chrono::seconds >( std::chrono::system_clock::now() - startTime ).count() << " seconds\n";
getchar();
if( eData )
delete eData;

View file

@ -11,6 +11,9 @@
#include "vec3.h"
// garbage to skip model loading
extern bool ignoreModels;
//
// ported from https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Sgb/SgbDataType.cs
@ -132,7 +135,7 @@ struct SGB_GROUP
if( entryOffset > fileSize )
throw std::runtime_error( "SGB_GROUP entry offset was larger than SGB file size!" );
auto type = *reinterpret_cast< uint32_t* >( buf + entryOffset );
if( type == SgbGroupEntryType::Model )
if( type == SgbGroupEntryType::Model && !ignoreModels )
{
entries.push_back( std::make_shared< SGB_MODEL_ENTRY >( buf, entryOffset ) );
}

View file

@ -299,7 +299,7 @@ int main( int argc, char** argv )
bool unluac = false;
// std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" );
std::string datLocation( "C:/Program Files (x86)/SquareEnix/FINAL FANTASY XIV - A Realm Reborn/game/sqpack/ffxiv" );
std::string datLocation( "C:/Program Files (x86)/SquareEnix/FINAL FANTASY XIV - A Realm Reborn/game/sqpack" );
if ( argc > 1 )
datLocation = std::string( argv[1] );
if ( argc > 2 )
@ -350,11 +350,11 @@ int main( int argc, char** argv )
const xiv::dat::Cat& test = data.get_category( "game_script" );
const xiv::dat::Cat& test = data.getCategory( "game_script" );
const std::string questPath = "game_script/quest/" + folder + "/" + questInfo->name_intern + ".luab";
const auto &test_file = data.get_file( questPath );
const auto &test_file = data.getFile( questPath );
auto &section = test_file->access_data_sections().at( 0 );
int32_t size = *( uint32_t* ) &section[4];