mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-11-25 06:02:06 +00:00
Merge pull request #559 from Laupetin/modman-zone-details
feat: modman zone details
This commit is contained in:
26
src/Common/Game/CommonAsset.cpp
Normal file
26
src/Common/Game/CommonAsset.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "CommonAsset.h"
|
||||
|
||||
#include "IW3/CommonAssetIW3.h"
|
||||
#include "IW4/CommonAssetIW4.h"
|
||||
#include "IW5/CommonAssetIW5.h"
|
||||
#include "T5/CommonAssetT5.h"
|
||||
#include "T6/CommonAssetT6.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
ICommonAssetTypeMapper* ICommonAssetTypeMapper::GetCommonAssetMapperByGame(GameId gameId)
|
||||
{
|
||||
static ICommonAssetTypeMapper* assetTypeMappers[static_cast<unsigned>(GameId::COUNT)]{
|
||||
new IW3::CommonAssetTypeMapper(),
|
||||
new IW4::CommonAssetTypeMapper(),
|
||||
new IW5::CommonAssetTypeMapper(),
|
||||
new T5::CommonAssetTypeMapper(),
|
||||
new T6::CommonAssetTypeMapper(),
|
||||
};
|
||||
|
||||
assert(static_cast<unsigned>(gameId) < static_cast<unsigned>(GameId::COUNT));
|
||||
auto* result = assetTypeMappers[static_cast<unsigned>(gameId)];
|
||||
assert(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
181
src/Common/Game/CommonAsset.h
Normal file
181
src/Common/Game/CommonAsset.h
Normal file
@@ -0,0 +1,181 @@
|
||||
#pragma once
|
||||
|
||||
#include "IGame.h"
|
||||
#include "Zone/ZoneTypes.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
enum class CommonAssetType : std::uint8_t
|
||||
{
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
PHYS_PRESET,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
XANIM,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
XMODEL,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
MATERIAL,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
TECHNIQUE_SET,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
IMAGE,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
SOUND,
|
||||
// IW3, IW4, IW5
|
||||
SOUND_CURVE,
|
||||
// IW3, IW4, IW5
|
||||
LOADED_SOUND,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
CLIP_MAP,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
COM_WORLD,
|
||||
// IW3, IW4, T5, T6
|
||||
GAME_WORLD_SP,
|
||||
// IW3, IW4, T5, T6
|
||||
GAME_WORLD_MP,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
MAP_ENTS,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
GFX_WORLD,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
LIGHT_DEF,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
UI_MAP,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
FONT,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
MENU_LIST,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
MENU,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
LOCALIZE_ENTRY,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
WEAPON,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
SOUND_DRIVER_GLOBALS,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
FX,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
IMPACT_FX,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
AI_TYPE,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
MP_TYPE,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
CHARACTER,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
XMODEL_ALIAS,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
RAW_FILE,
|
||||
// IW3, IW4, IW5, T5, T6
|
||||
STRING_TABLE,
|
||||
|
||||
// IW3, T5, T6
|
||||
XMODEL_PIECES,
|
||||
|
||||
// IW4, IW5
|
||||
PHYS_COLL_MAP,
|
||||
// IW4, IW5
|
||||
XMODEL_SURFS,
|
||||
// IW4, IW5
|
||||
PIXEL_SHADER,
|
||||
// IW4, IW5
|
||||
VERTEX_SHADER,
|
||||
// IW4, IW5
|
||||
VERTEX_DECL,
|
||||
// IW4, IW5
|
||||
FX_WORLD,
|
||||
// IW4, IW5, T6
|
||||
LEADERBOARD,
|
||||
// IW4, IW5
|
||||
STRUCTURED_DATA_DEF,
|
||||
// IW4, IW5, T6
|
||||
TRACER,
|
||||
// IW4, IW5, T6
|
||||
VEHICLE,
|
||||
// IW4, IW5, T6
|
||||
ADDON_MAP_ENTS,
|
||||
|
||||
// IW5
|
||||
GLASS_WORLD,
|
||||
// IW5
|
||||
PATH_DATA,
|
||||
// IW5
|
||||
VEHICLE_TRACK,
|
||||
// IW5, T6
|
||||
ATTACHMENT,
|
||||
// IW5
|
||||
SURFACE_FX,
|
||||
// IW5, T6
|
||||
SCRIPT,
|
||||
|
||||
// T5, T6
|
||||
PHYS_CONSTRAINTS,
|
||||
// T5, T6
|
||||
DESTRUCTIBLE_DEF,
|
||||
// T5, T6
|
||||
SOUND_PATCH,
|
||||
// T5, T6
|
||||
WEAPON_DEF,
|
||||
// T5, T6
|
||||
WEAPON_VARIANT,
|
||||
// T5, T6
|
||||
MP_BODY,
|
||||
// T5, T6
|
||||
MP_HEAD,
|
||||
// T5
|
||||
PACK_INDEX,
|
||||
// T5, T6
|
||||
XGLOBALS,
|
||||
// T5, T6
|
||||
DDL,
|
||||
// T5, T6
|
||||
GLASSES,
|
||||
// T5, T6
|
||||
EMBLEM_SET,
|
||||
|
||||
// T6
|
||||
FONT_ICON,
|
||||
// T6
|
||||
WEAPON_FULL,
|
||||
// T6
|
||||
ATTACHMENT_UNIQUE,
|
||||
// T6
|
||||
WEAPON_CAMO,
|
||||
// T6
|
||||
KEY_VALUE_PAIRS,
|
||||
// T6
|
||||
MEMORY_BLOCK,
|
||||
// T6
|
||||
SKINNED_VERTS,
|
||||
// T6
|
||||
QDB,
|
||||
// T6
|
||||
SLUG,
|
||||
// T6
|
||||
FOOTSTEP_TABLE,
|
||||
// T6
|
||||
FOOTSTEP_FX_TABLE,
|
||||
// T6
|
||||
ZBARRIER,
|
||||
|
||||
COUNT,
|
||||
};
|
||||
|
||||
class ICommonAssetTypeMapper
|
||||
{
|
||||
public:
|
||||
[[nodiscard]] virtual CommonAssetType GameToCommonAssetType(asset_type_t gameAssetType) const = 0;
|
||||
[[nodiscard]] virtual std::optional<asset_type_t> CommonToGameAssetType(CommonAssetType commonAssetType) const = 0;
|
||||
|
||||
static ICommonAssetTypeMapper* GetCommonAssetMapperByGame(GameId gameId);
|
||||
|
||||
protected:
|
||||
ICommonAssetTypeMapper() = default;
|
||||
virtual ~ICommonAssetTypeMapper() = default;
|
||||
ICommonAssetTypeMapper(const ICommonAssetTypeMapper& other) = default;
|
||||
ICommonAssetTypeMapper(ICommonAssetTypeMapper&& other) noexcept = default;
|
||||
ICommonAssetTypeMapper& operator=(const ICommonAssetTypeMapper& other) = default;
|
||||
ICommonAssetTypeMapper& operator=(ICommonAssetTypeMapper&& other) noexcept = default;
|
||||
};
|
||||
100
src/Common/Game/IW3/CommonAssetIW3.cpp
Normal file
100
src/Common/Game/IW3/CommonAssetIW3.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "CommonAssetIW3.h"
|
||||
|
||||
#include "IW3.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace IW3
|
||||
{
|
||||
CommonAssetTypeMapper::CommonAssetTypeMapper() = default;
|
||||
|
||||
CommonAssetType CommonAssetTypeMapper::GameToCommonAssetType(const asset_type_t gameAssetType) const
|
||||
{
|
||||
static CommonAssetType lookupTable[static_cast<unsigned>(ASSET_TYPE_COUNT)]{
|
||||
CommonAssetType::XMODEL_PIECES, // ASSET_TYPE_XMODELPIECES
|
||||
CommonAssetType::PHYS_PRESET, // ASSET_TYPE_PHYSPRESET
|
||||
CommonAssetType::XANIM, // ASSET_TYPE_XANIMPARTS
|
||||
CommonAssetType::XMODEL, // ASSET_TYPE_XMODEL
|
||||
CommonAssetType::MATERIAL, // ASSET_TYPE_MATERIAL
|
||||
CommonAssetType::TECHNIQUE_SET, // ASSET_TYPE_TECHNIQUE_SET
|
||||
CommonAssetType::IMAGE, // ASSET_TYPE_IMAGE
|
||||
CommonAssetType::SOUND, // ASSET_TYPE_SOUND
|
||||
CommonAssetType::SOUND_CURVE, // ASSET_TYPE_SOUND_CURVE
|
||||
CommonAssetType::LOADED_SOUND, // ASSET_TYPE_LOADED_SOUND
|
||||
CommonAssetType::CLIP_MAP, // ASSET_TYPE_CLIPMAP
|
||||
CommonAssetType::CLIP_MAP, // ASSET_TYPE_CLIPMAP_PVS
|
||||
CommonAssetType::COM_WORLD, // ASSET_TYPE_COMWORLD
|
||||
CommonAssetType::GAME_WORLD_SP, // ASSET_TYPE_GAMEWORLD_SP
|
||||
CommonAssetType::GAME_WORLD_MP, // ASSET_TYPE_GAMEWORLD_MP
|
||||
CommonAssetType::MAP_ENTS, // ASSET_TYPE_MAP_ENTS
|
||||
CommonAssetType::GFX_WORLD, // ASSET_TYPE_GFXWORLD
|
||||
CommonAssetType::LIGHT_DEF, // ASSET_TYPE_LIGHT_DEF
|
||||
CommonAssetType::UI_MAP, // ASSET_TYPE_UI_MAP
|
||||
CommonAssetType::FONT, // ASSET_TYPE_FONT
|
||||
CommonAssetType::MENU_LIST, // ASSET_TYPE_MENULIST
|
||||
CommonAssetType::MENU, // ASSET_TYPE_MENU
|
||||
CommonAssetType::LOCALIZE_ENTRY, // ASSET_TYPE_LOCALIZE_ENTRY
|
||||
CommonAssetType::WEAPON, // ASSET_TYPE_WEAPON
|
||||
CommonAssetType::SOUND_DRIVER_GLOBALS, // ASSET_TYPE_SNDDRIVER_GLOBALS
|
||||
CommonAssetType::FX, // ASSET_TYPE_FX
|
||||
CommonAssetType::IMPACT_FX, // ASSET_TYPE_IMPACT_FX
|
||||
CommonAssetType::AI_TYPE, // ASSET_TYPE_AITYPE
|
||||
CommonAssetType::MP_TYPE, // ASSET_TYPE_MPTYPE
|
||||
CommonAssetType::CHARACTER, // ASSET_TYPE_CHARACTER
|
||||
CommonAssetType::XMODEL_ALIAS, // ASSET_TYPE_XMODELALIAS
|
||||
CommonAssetType::RAW_FILE, // ASSET_TYPE_RAWFILE
|
||||
CommonAssetType::STRING_TABLE, // ASSET_TYPE_STRINGTABLE
|
||||
};
|
||||
|
||||
assert(gameAssetType < ASSET_TYPE_COUNT);
|
||||
return lookupTable[gameAssetType];
|
||||
}
|
||||
|
||||
std::optional<asset_type_t> CommonAssetTypeMapper::CommonToGameAssetType(const CommonAssetType commonAssetType) const
|
||||
{
|
||||
#define MAP_COMMON(common, game) \
|
||||
case common: \
|
||||
return game;
|
||||
|
||||
switch (commonAssetType)
|
||||
{
|
||||
MAP_COMMON(CommonAssetType::XMODEL_PIECES, ASSET_TYPE_XMODELPIECES)
|
||||
MAP_COMMON(CommonAssetType::PHYS_PRESET, ASSET_TYPE_PHYSPRESET)
|
||||
MAP_COMMON(CommonAssetType::XANIM, ASSET_TYPE_XANIMPARTS)
|
||||
MAP_COMMON(CommonAssetType::XMODEL, ASSET_TYPE_XMODEL)
|
||||
MAP_COMMON(CommonAssetType::MATERIAL, ASSET_TYPE_MATERIAL)
|
||||
MAP_COMMON(CommonAssetType::TECHNIQUE_SET, ASSET_TYPE_TECHNIQUE_SET)
|
||||
MAP_COMMON(CommonAssetType::IMAGE, ASSET_TYPE_IMAGE)
|
||||
MAP_COMMON(CommonAssetType::SOUND, ASSET_TYPE_SOUND)
|
||||
MAP_COMMON(CommonAssetType::SOUND_CURVE, ASSET_TYPE_SOUND_CURVE)
|
||||
MAP_COMMON(CommonAssetType::LOADED_SOUND, ASSET_TYPE_LOADED_SOUND)
|
||||
MAP_COMMON(CommonAssetType::CLIP_MAP, ASSET_TYPE_CLIPMAP_PVS)
|
||||
MAP_COMMON(CommonAssetType::COM_WORLD, ASSET_TYPE_COMWORLD)
|
||||
MAP_COMMON(CommonAssetType::GAME_WORLD_SP, ASSET_TYPE_GAMEWORLD_SP)
|
||||
MAP_COMMON(CommonAssetType::GAME_WORLD_MP, ASSET_TYPE_GAMEWORLD_MP)
|
||||
MAP_COMMON(CommonAssetType::MAP_ENTS, ASSET_TYPE_MAP_ENTS)
|
||||
MAP_COMMON(CommonAssetType::GFX_WORLD, ASSET_TYPE_GFXWORLD)
|
||||
MAP_COMMON(CommonAssetType::LIGHT_DEF, ASSET_TYPE_LIGHT_DEF)
|
||||
MAP_COMMON(CommonAssetType::UI_MAP, ASSET_TYPE_UI_MAP)
|
||||
MAP_COMMON(CommonAssetType::FONT, ASSET_TYPE_FONT)
|
||||
MAP_COMMON(CommonAssetType::MENU_LIST, ASSET_TYPE_MENULIST)
|
||||
MAP_COMMON(CommonAssetType::MENU, ASSET_TYPE_MENU)
|
||||
MAP_COMMON(CommonAssetType::LOCALIZE_ENTRY, ASSET_TYPE_LOCALIZE_ENTRY)
|
||||
MAP_COMMON(CommonAssetType::WEAPON, ASSET_TYPE_WEAPON)
|
||||
MAP_COMMON(CommonAssetType::SOUND_DRIVER_GLOBALS, ASSET_TYPE_SNDDRIVER_GLOBALS)
|
||||
MAP_COMMON(CommonAssetType::FX, ASSET_TYPE_FX)
|
||||
MAP_COMMON(CommonAssetType::IMPACT_FX, ASSET_TYPE_IMPACT_FX)
|
||||
MAP_COMMON(CommonAssetType::AI_TYPE, ASSET_TYPE_AITYPE)
|
||||
MAP_COMMON(CommonAssetType::MP_TYPE, ASSET_TYPE_MPTYPE)
|
||||
MAP_COMMON(CommonAssetType::CHARACTER, ASSET_TYPE_CHARACTER)
|
||||
MAP_COMMON(CommonAssetType::XMODEL_ALIAS, ASSET_TYPE_XMODELALIAS)
|
||||
MAP_COMMON(CommonAssetType::RAW_FILE, ASSET_TYPE_RAWFILE)
|
||||
MAP_COMMON(CommonAssetType::STRING_TABLE, ASSET_TYPE_STRINGTABLE)
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
#undef MAP_COMMON
|
||||
}
|
||||
} // namespace IW3
|
||||
15
src/Common/Game/IW3/CommonAssetIW3.h
Normal file
15
src/Common/Game/IW3/CommonAssetIW3.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/CommonAsset.h"
|
||||
|
||||
namespace IW3
|
||||
{
|
||||
class CommonAssetTypeMapper final : public ICommonAssetTypeMapper
|
||||
{
|
||||
public:
|
||||
CommonAssetTypeMapper();
|
||||
|
||||
[[nodiscard]] CommonAssetType GameToCommonAssetType(asset_type_t gameAssetType) const override;
|
||||
[[nodiscard]] std::optional<asset_type_t> CommonToGameAssetType(CommonAssetType commonAssetType) const override;
|
||||
};
|
||||
} // namespace IW3
|
||||
120
src/Common/Game/IW4/CommonAssetIW4.cpp
Normal file
120
src/Common/Game/IW4/CommonAssetIW4.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#include "CommonAssetIW4.h"
|
||||
|
||||
#include "IW4.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
CommonAssetTypeMapper::CommonAssetTypeMapper() = default;
|
||||
|
||||
CommonAssetType CommonAssetTypeMapper::GameToCommonAssetType(const asset_type_t gameAssetType) const
|
||||
{
|
||||
static CommonAssetType lookupTable[static_cast<unsigned>(ASSET_TYPE_COUNT)]{
|
||||
CommonAssetType::PHYS_PRESET, // ASSET_TYPE_PHYSPRESET
|
||||
CommonAssetType::PHYS_COLL_MAP, // ASSET_TYPE_PHYSCOLLMAP
|
||||
CommonAssetType::XANIM, // ASSET_TYPE_XANIMPARTS
|
||||
CommonAssetType::XMODEL_SURFS, // ASSET_TYPE_XMODEL_SURFS
|
||||
CommonAssetType::XMODEL, // ASSET_TYPE_XMODEL
|
||||
CommonAssetType::MATERIAL, // ASSET_TYPE_MATERIAL
|
||||
CommonAssetType::PIXEL_SHADER, // ASSET_TYPE_PIXELSHADER
|
||||
CommonAssetType::VERTEX_SHADER, // ASSET_TYPE_VERTEXSHADER
|
||||
CommonAssetType::VERTEX_DECL, // ASSET_TYPE_VERTEXDECL
|
||||
CommonAssetType::TECHNIQUE_SET, // ASSET_TYPE_TECHNIQUE_SET
|
||||
CommonAssetType::IMAGE, // ASSET_TYPE_IMAGE
|
||||
CommonAssetType::SOUND, // ASSET_TYPE_SOUND
|
||||
CommonAssetType::SOUND_CURVE, // ASSET_TYPE_SOUND_CURVE
|
||||
CommonAssetType::LOADED_SOUND, // ASSET_TYPE_LOADED_SOUND
|
||||
CommonAssetType::CLIP_MAP, // ASSET_TYPE_CLIPMAP_SP
|
||||
CommonAssetType::CLIP_MAP, // ASSET_TYPE_CLIPMAP_MP
|
||||
CommonAssetType::COM_WORLD, // ASSET_TYPE_COMWORLD
|
||||
CommonAssetType::GAME_WORLD_SP, // ASSET_TYPE_GAMEWORLD_SP
|
||||
CommonAssetType::GAME_WORLD_MP, // ASSET_TYPE_GAMEWORLD_MP
|
||||
CommonAssetType::MAP_ENTS, // ASSET_TYPE_MAP_ENTS
|
||||
CommonAssetType::FX_WORLD, // ASSET_TYPE_FXWORLD
|
||||
CommonAssetType::GFX_WORLD, // ASSET_TYPE_GFXWORLD
|
||||
CommonAssetType::LIGHT_DEF, // ASSET_TYPE_LIGHT_DEF
|
||||
CommonAssetType::UI_MAP, // ASSET_TYPE_UI_MAP
|
||||
CommonAssetType::FONT, // ASSET_TYPE_FONT
|
||||
CommonAssetType::MENU_LIST, // ASSET_TYPE_MENULIST
|
||||
CommonAssetType::MENU, // ASSET_TYPE_MENU
|
||||
CommonAssetType::LOCALIZE_ENTRY, // ASSET_TYPE_LOCALIZE_ENTRY
|
||||
CommonAssetType::WEAPON, // ASSET_TYPE_WEAPON
|
||||
CommonAssetType::SOUND_DRIVER_GLOBALS, // ASSET_TYPE_SNDDRIVER_GLOBALS
|
||||
CommonAssetType::FX, // ASSET_TYPE_FX
|
||||
CommonAssetType::IMPACT_FX, // ASSET_TYPE_IMPACT_FX
|
||||
CommonAssetType::AI_TYPE, // ASSET_TYPE_AITYPE
|
||||
CommonAssetType::MP_TYPE, // ASSET_TYPE_MPTYPE
|
||||
CommonAssetType::CHARACTER, // ASSET_TYPE_CHARACTER
|
||||
CommonAssetType::XMODEL_ALIAS, // ASSET_TYPE_XMODELALIAS
|
||||
CommonAssetType::RAW_FILE, // ASSET_TYPE_RAWFILE
|
||||
CommonAssetType::STRING_TABLE, // ASSET_TYPE_STRINGTABLE
|
||||
CommonAssetType::LEADERBOARD, // ASSET_TYPE_LEADERBOARD
|
||||
CommonAssetType::STRUCTURED_DATA_DEF, // ASSET_TYPE_STRUCTURED_DATA_DEF
|
||||
CommonAssetType::TRACER, // ASSET_TYPE_TRACER
|
||||
CommonAssetType::VEHICLE, // ASSET_TYPE_VEHICLE
|
||||
CommonAssetType::ADDON_MAP_ENTS, // ASSET_TYPE_ADDON_MAP_ENTS
|
||||
};
|
||||
|
||||
assert(gameAssetType < ASSET_TYPE_COUNT);
|
||||
return lookupTable[gameAssetType];
|
||||
}
|
||||
|
||||
std::optional<asset_type_t> CommonAssetTypeMapper::CommonToGameAssetType(const CommonAssetType commonAssetType) const
|
||||
{
|
||||
#define MAP_COMMON(common, game) \
|
||||
case common: \
|
||||
return game;
|
||||
|
||||
switch (commonAssetType)
|
||||
{
|
||||
MAP_COMMON(CommonAssetType::PHYS_PRESET, ASSET_TYPE_PHYSPRESET)
|
||||
MAP_COMMON(CommonAssetType::PHYS_COLL_MAP, ASSET_TYPE_PHYSCOLLMAP)
|
||||
MAP_COMMON(CommonAssetType::XANIM, ASSET_TYPE_XANIMPARTS)
|
||||
MAP_COMMON(CommonAssetType::XMODEL_SURFS, ASSET_TYPE_XMODEL_SURFS)
|
||||
MAP_COMMON(CommonAssetType::XMODEL, ASSET_TYPE_XMODEL)
|
||||
MAP_COMMON(CommonAssetType::MATERIAL, ASSET_TYPE_MATERIAL)
|
||||
MAP_COMMON(CommonAssetType::PIXEL_SHADER, ASSET_TYPE_PIXELSHADER)
|
||||
MAP_COMMON(CommonAssetType::VERTEX_SHADER, ASSET_TYPE_VERTEXSHADER)
|
||||
MAP_COMMON(CommonAssetType::VERTEX_DECL, ASSET_TYPE_VERTEXDECL)
|
||||
MAP_COMMON(CommonAssetType::TECHNIQUE_SET, ASSET_TYPE_TECHNIQUE_SET)
|
||||
MAP_COMMON(CommonAssetType::IMAGE, ASSET_TYPE_IMAGE)
|
||||
MAP_COMMON(CommonAssetType::SOUND, ASSET_TYPE_SOUND)
|
||||
MAP_COMMON(CommonAssetType::SOUND_CURVE, ASSET_TYPE_SOUND_CURVE)
|
||||
MAP_COMMON(CommonAssetType::LOADED_SOUND, ASSET_TYPE_LOADED_SOUND)
|
||||
MAP_COMMON(CommonAssetType::CLIP_MAP, ASSET_TYPE_CLIPMAP_MP)
|
||||
MAP_COMMON(CommonAssetType::COM_WORLD, ASSET_TYPE_COMWORLD)
|
||||
MAP_COMMON(CommonAssetType::GAME_WORLD_SP, ASSET_TYPE_GAMEWORLD_SP)
|
||||
MAP_COMMON(CommonAssetType::GAME_WORLD_MP, ASSET_TYPE_GAMEWORLD_MP)
|
||||
MAP_COMMON(CommonAssetType::MAP_ENTS, ASSET_TYPE_MAP_ENTS)
|
||||
MAP_COMMON(CommonAssetType::FX_WORLD, ASSET_TYPE_FXWORLD)
|
||||
MAP_COMMON(CommonAssetType::GFX_WORLD, ASSET_TYPE_GFXWORLD)
|
||||
MAP_COMMON(CommonAssetType::LIGHT_DEF, ASSET_TYPE_LIGHT_DEF)
|
||||
MAP_COMMON(CommonAssetType::UI_MAP, ASSET_TYPE_UI_MAP)
|
||||
MAP_COMMON(CommonAssetType::FONT, ASSET_TYPE_FONT)
|
||||
MAP_COMMON(CommonAssetType::MENU_LIST, ASSET_TYPE_MENULIST)
|
||||
MAP_COMMON(CommonAssetType::MENU, ASSET_TYPE_MENU)
|
||||
MAP_COMMON(CommonAssetType::LOCALIZE_ENTRY, ASSET_TYPE_LOCALIZE_ENTRY)
|
||||
MAP_COMMON(CommonAssetType::WEAPON, ASSET_TYPE_WEAPON)
|
||||
MAP_COMMON(CommonAssetType::SOUND_DRIVER_GLOBALS, ASSET_TYPE_SNDDRIVER_GLOBALS)
|
||||
MAP_COMMON(CommonAssetType::FX, ASSET_TYPE_FX)
|
||||
MAP_COMMON(CommonAssetType::IMPACT_FX, ASSET_TYPE_IMPACT_FX)
|
||||
MAP_COMMON(CommonAssetType::AI_TYPE, ASSET_TYPE_AITYPE)
|
||||
MAP_COMMON(CommonAssetType::MP_TYPE, ASSET_TYPE_MPTYPE)
|
||||
MAP_COMMON(CommonAssetType::CHARACTER, ASSET_TYPE_CHARACTER)
|
||||
MAP_COMMON(CommonAssetType::XMODEL_ALIAS, ASSET_TYPE_XMODELALIAS)
|
||||
MAP_COMMON(CommonAssetType::RAW_FILE, ASSET_TYPE_RAWFILE)
|
||||
MAP_COMMON(CommonAssetType::STRING_TABLE, ASSET_TYPE_STRINGTABLE)
|
||||
MAP_COMMON(CommonAssetType::LEADERBOARD, ASSET_TYPE_LEADERBOARD)
|
||||
MAP_COMMON(CommonAssetType::STRUCTURED_DATA_DEF, ASSET_TYPE_STRUCTURED_DATA_DEF)
|
||||
MAP_COMMON(CommonAssetType::TRACER, ASSET_TYPE_TRACER)
|
||||
MAP_COMMON(CommonAssetType::VEHICLE, ASSET_TYPE_VEHICLE)
|
||||
MAP_COMMON(CommonAssetType::ADDON_MAP_ENTS, ASSET_TYPE_ADDON_MAP_ENTS)
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
#undef MAP_COMMON
|
||||
}
|
||||
} // namespace IW4
|
||||
15
src/Common/Game/IW4/CommonAssetIW4.h
Normal file
15
src/Common/Game/IW4/CommonAssetIW4.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/CommonAsset.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class CommonAssetTypeMapper final : public ICommonAssetTypeMapper
|
||||
{
|
||||
public:
|
||||
CommonAssetTypeMapper();
|
||||
|
||||
[[nodiscard]] CommonAssetType GameToCommonAssetType(asset_type_t gameAssetType) const override;
|
||||
[[nodiscard]] std::optional<asset_type_t> CommonToGameAssetType(CommonAssetType commonAssetType) const override;
|
||||
};
|
||||
} // namespace IW4
|
||||
127
src/Common/Game/IW5/CommonAssetIW5.cpp
Normal file
127
src/Common/Game/IW5/CommonAssetIW5.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
#include "CommonAssetIW5.h"
|
||||
|
||||
#include "IW5.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
CommonAssetTypeMapper::CommonAssetTypeMapper() = default;
|
||||
|
||||
CommonAssetType CommonAssetTypeMapper::GameToCommonAssetType(const asset_type_t gameAssetType) const
|
||||
{
|
||||
static CommonAssetType lookupTable[static_cast<unsigned>(ASSET_TYPE_COUNT)]{
|
||||
CommonAssetType::PHYS_PRESET, // ASSET_TYPE_PHYSPRESET
|
||||
CommonAssetType::PHYS_COLL_MAP, // ASSET_TYPE_PHYSCOLLMAP
|
||||
CommonAssetType::XANIM, // ASSET_TYPE_XANIMPARTS
|
||||
CommonAssetType::XMODEL_SURFS, // ASSET_TYPE_XMODEL_SURFS
|
||||
CommonAssetType::XMODEL, // ASSET_TYPE_XMODEL
|
||||
CommonAssetType::MATERIAL, // ASSET_TYPE_MATERIAL
|
||||
CommonAssetType::PIXEL_SHADER, // ASSET_TYPE_PIXELSHADER
|
||||
CommonAssetType::VERTEX_SHADER, // ASSET_TYPE_VERTEXSHADER
|
||||
CommonAssetType::VERTEX_DECL, // ASSET_TYPE_VERTEXDECL
|
||||
CommonAssetType::TECHNIQUE_SET, // ASSET_TYPE_TECHNIQUE_SET
|
||||
CommonAssetType::IMAGE, // ASSET_TYPE_IMAGE
|
||||
CommonAssetType::SOUND, // ASSET_TYPE_SOUND
|
||||
CommonAssetType::SOUND_CURVE, // ASSET_TYPE_SOUND_CURVE
|
||||
CommonAssetType::LOADED_SOUND, // ASSET_TYPE_LOADED_SOUND
|
||||
CommonAssetType::CLIP_MAP, // ASSET_TYPE_CLIPMAP
|
||||
CommonAssetType::COM_WORLD, // ASSET_TYPE_COMWORLD
|
||||
CommonAssetType::GLASS_WORLD, // ASSET_TYPE_GLASSWORLD
|
||||
CommonAssetType::PATH_DATA, // ASSET_TYPE_PATHDATA
|
||||
CommonAssetType::VEHICLE_TRACK, // ASSET_TYPE_VEHICLE_TRACK
|
||||
CommonAssetType::MAP_ENTS, // ASSET_TYPE_MAP_ENTS
|
||||
CommonAssetType::FX_WORLD, // ASSET_TYPE_FXWORLD
|
||||
CommonAssetType::GFX_WORLD, // ASSET_TYPE_GFXWORLD
|
||||
CommonAssetType::LIGHT_DEF, // ASSET_TYPE_LIGHT_DEF
|
||||
CommonAssetType::UI_MAP, // ASSET_TYPE_UI_MAP
|
||||
CommonAssetType::FONT, // ASSET_TYPE_FONT
|
||||
CommonAssetType::MENU_LIST, // ASSET_TYPE_MENULIST
|
||||
CommonAssetType::MENU, // ASSET_TYPE_MENU
|
||||
CommonAssetType::LOCALIZE_ENTRY, // ASSET_TYPE_LOCALIZE_ENTRY
|
||||
CommonAssetType::ATTACHMENT, // ASSET_TYPE_ATTACHMENT
|
||||
CommonAssetType::WEAPON, // ASSET_TYPE_WEAPON
|
||||
CommonAssetType::SOUND_DRIVER_GLOBALS, // ASSET_TYPE_SNDDRIVER_GLOBALS
|
||||
CommonAssetType::FX, // ASSET_TYPE_FX
|
||||
CommonAssetType::IMPACT_FX, // ASSET_TYPE_IMPACT_FX
|
||||
CommonAssetType::SURFACE_FX, // ASSET_TYPE_SURFACE_FX
|
||||
CommonAssetType::AI_TYPE, // ASSET_TYPE_AITYPE
|
||||
CommonAssetType::MP_TYPE, // ASSET_TYPE_MPTYPE
|
||||
CommonAssetType::CHARACTER, // ASSET_TYPE_CHARACTER
|
||||
CommonAssetType::XMODEL_ALIAS, // ASSET_TYPE_XMODELALIAS
|
||||
CommonAssetType::RAW_FILE, // ASSET_TYPE_RAWFILE
|
||||
CommonAssetType::SCRIPT, // ASSET_TYPE_SCRIPTFILE
|
||||
CommonAssetType::STRING_TABLE, // ASSET_TYPE_STRINGTABLE
|
||||
CommonAssetType::LEADERBOARD, // ASSET_TYPE_LEADERBOARD
|
||||
CommonAssetType::STRUCTURED_DATA_DEF, // ASSET_TYPE_STRUCTURED_DATA_DEF
|
||||
CommonAssetType::TRACER, // ASSET_TYPE_TRACER
|
||||
CommonAssetType::VEHICLE, // ASSET_TYPE_VEHICLE
|
||||
CommonAssetType::ADDON_MAP_ENTS, // ASSET_TYPE_ADDON_MAP_ENTS
|
||||
};
|
||||
|
||||
assert(gameAssetType < ASSET_TYPE_COUNT);
|
||||
return lookupTable[gameAssetType];
|
||||
}
|
||||
|
||||
std::optional<asset_type_t> CommonAssetTypeMapper::CommonToGameAssetType(const CommonAssetType commonAssetType) const
|
||||
{
|
||||
#define MAP_COMMON(common, game) \
|
||||
case common: \
|
||||
return game;
|
||||
|
||||
switch (commonAssetType)
|
||||
{
|
||||
MAP_COMMON(CommonAssetType::PHYS_PRESET, ASSET_TYPE_PHYSPRESET)
|
||||
MAP_COMMON(CommonAssetType::PHYS_COLL_MAP, ASSET_TYPE_PHYSCOLLMAP)
|
||||
MAP_COMMON(CommonAssetType::XANIM, ASSET_TYPE_XANIMPARTS)
|
||||
MAP_COMMON(CommonAssetType::XMODEL_SURFS, ASSET_TYPE_XMODEL_SURFS)
|
||||
MAP_COMMON(CommonAssetType::XMODEL, ASSET_TYPE_XMODEL)
|
||||
MAP_COMMON(CommonAssetType::MATERIAL, ASSET_TYPE_MATERIAL)
|
||||
MAP_COMMON(CommonAssetType::PIXEL_SHADER, ASSET_TYPE_PIXELSHADER)
|
||||
MAP_COMMON(CommonAssetType::VERTEX_SHADER, ASSET_TYPE_VERTEXSHADER)
|
||||
MAP_COMMON(CommonAssetType::VERTEX_DECL, ASSET_TYPE_VERTEXDECL)
|
||||
MAP_COMMON(CommonAssetType::TECHNIQUE_SET, ASSET_TYPE_TECHNIQUE_SET)
|
||||
MAP_COMMON(CommonAssetType::IMAGE, ASSET_TYPE_IMAGE)
|
||||
MAP_COMMON(CommonAssetType::SOUND, ASSET_TYPE_SOUND)
|
||||
MAP_COMMON(CommonAssetType::SOUND_CURVE, ASSET_TYPE_SOUND_CURVE)
|
||||
MAP_COMMON(CommonAssetType::LOADED_SOUND, ASSET_TYPE_LOADED_SOUND)
|
||||
MAP_COMMON(CommonAssetType::CLIP_MAP, ASSET_TYPE_CLIPMAP)
|
||||
MAP_COMMON(CommonAssetType::COM_WORLD, ASSET_TYPE_COMWORLD)
|
||||
MAP_COMMON(CommonAssetType::GLASS_WORLD, ASSET_TYPE_GLASSWORLD)
|
||||
MAP_COMMON(CommonAssetType::PATH_DATA, ASSET_TYPE_PATHDATA)
|
||||
MAP_COMMON(CommonAssetType::VEHICLE_TRACK, ASSET_TYPE_VEHICLE_TRACK)
|
||||
MAP_COMMON(CommonAssetType::MAP_ENTS, ASSET_TYPE_MAP_ENTS)
|
||||
MAP_COMMON(CommonAssetType::FX_WORLD, ASSET_TYPE_FXWORLD)
|
||||
MAP_COMMON(CommonAssetType::GFX_WORLD, ASSET_TYPE_GFXWORLD)
|
||||
MAP_COMMON(CommonAssetType::LIGHT_DEF, ASSET_TYPE_LIGHT_DEF)
|
||||
MAP_COMMON(CommonAssetType::UI_MAP, ASSET_TYPE_UI_MAP)
|
||||
MAP_COMMON(CommonAssetType::FONT, ASSET_TYPE_FONT)
|
||||
MAP_COMMON(CommonAssetType::MENU_LIST, ASSET_TYPE_MENULIST)
|
||||
MAP_COMMON(CommonAssetType::MENU, ASSET_TYPE_MENU)
|
||||
MAP_COMMON(CommonAssetType::LOCALIZE_ENTRY, ASSET_TYPE_LOCALIZE_ENTRY)
|
||||
MAP_COMMON(CommonAssetType::ATTACHMENT, ASSET_TYPE_ATTACHMENT)
|
||||
MAP_COMMON(CommonAssetType::WEAPON, ASSET_TYPE_WEAPON)
|
||||
MAP_COMMON(CommonAssetType::SOUND_DRIVER_GLOBALS, ASSET_TYPE_SNDDRIVER_GLOBALS)
|
||||
MAP_COMMON(CommonAssetType::FX, ASSET_TYPE_FX)
|
||||
MAP_COMMON(CommonAssetType::IMPACT_FX, ASSET_TYPE_IMPACT_FX)
|
||||
MAP_COMMON(CommonAssetType::SURFACE_FX, ASSET_TYPE_SURFACE_FX)
|
||||
MAP_COMMON(CommonAssetType::AI_TYPE, ASSET_TYPE_AITYPE)
|
||||
MAP_COMMON(CommonAssetType::MP_TYPE, ASSET_TYPE_MPTYPE)
|
||||
MAP_COMMON(CommonAssetType::CHARACTER, ASSET_TYPE_CHARACTER)
|
||||
MAP_COMMON(CommonAssetType::XMODEL_ALIAS, ASSET_TYPE_XMODELALIAS)
|
||||
MAP_COMMON(CommonAssetType::RAW_FILE, ASSET_TYPE_RAWFILE)
|
||||
MAP_COMMON(CommonAssetType::SCRIPT, ASSET_TYPE_SCRIPTFILE)
|
||||
MAP_COMMON(CommonAssetType::STRING_TABLE, ASSET_TYPE_STRINGTABLE)
|
||||
MAP_COMMON(CommonAssetType::LEADERBOARD, ASSET_TYPE_LEADERBOARD)
|
||||
MAP_COMMON(CommonAssetType::STRUCTURED_DATA_DEF, ASSET_TYPE_STRUCTURED_DATA_DEF)
|
||||
MAP_COMMON(CommonAssetType::TRACER, ASSET_TYPE_TRACER)
|
||||
MAP_COMMON(CommonAssetType::VEHICLE, ASSET_TYPE_VEHICLE)
|
||||
MAP_COMMON(CommonAssetType::ADDON_MAP_ENTS, ASSET_TYPE_ADDON_MAP_ENTS)
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
#undef MAP_COMMON
|
||||
}
|
||||
} // namespace IW5
|
||||
15
src/Common/Game/IW5/CommonAssetIW5.h
Normal file
15
src/Common/Game/IW5/CommonAssetIW5.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/CommonAsset.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class CommonAssetTypeMapper final : public ICommonAssetTypeMapper
|
||||
{
|
||||
public:
|
||||
CommonAssetTypeMapper();
|
||||
|
||||
[[nodiscard]] CommonAssetType GameToCommonAssetType(asset_type_t gameAssetType) const override;
|
||||
[[nodiscard]] std::optional<asset_type_t> CommonToGameAssetType(CommonAssetType commonAssetType) const override;
|
||||
};
|
||||
} // namespace IW5
|
||||
120
src/Common/Game/T5/CommonAssetT5.cpp
Normal file
120
src/Common/Game/T5/CommonAssetT5.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#include "CommonAssetT5.h"
|
||||
|
||||
#include "T5.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace T5
|
||||
{
|
||||
CommonAssetTypeMapper::CommonAssetTypeMapper() = default;
|
||||
|
||||
CommonAssetType CommonAssetTypeMapper::GameToCommonAssetType(const asset_type_t gameAssetType) const
|
||||
{
|
||||
static CommonAssetType lookupTable[static_cast<unsigned>(ASSET_TYPE_COUNT)]{
|
||||
CommonAssetType::XMODEL_PIECES, // ASSET_TYPE_XMODELPIECES
|
||||
CommonAssetType::PHYS_PRESET, // ASSET_TYPE_PHYSPRESET
|
||||
CommonAssetType::PHYS_CONSTRAINTS, // ASSET_TYPE_PHYSCONSTRAINTS
|
||||
CommonAssetType::DESTRUCTIBLE_DEF, // ASSET_TYPE_DESTRUCTIBLEDEF
|
||||
CommonAssetType::XANIM, // ASSET_TYPE_XANIMPARTS
|
||||
CommonAssetType::XMODEL, // ASSET_TYPE_XMODEL
|
||||
CommonAssetType::MATERIAL, // ASSET_TYPE_MATERIAL
|
||||
CommonAssetType::TECHNIQUE_SET, // ASSET_TYPE_TECHNIQUE_SET
|
||||
CommonAssetType::IMAGE, // ASSET_TYPE_IMAGE
|
||||
CommonAssetType::SOUND, // ASSET_TYPE_SOUND
|
||||
CommonAssetType::SOUND_PATCH, // ASSET_TYPE_SOUND_PATCH
|
||||
CommonAssetType::CLIP_MAP, // ASSET_TYPE_CLIPMAP
|
||||
CommonAssetType::CLIP_MAP, // ASSET_TYPE_CLIPMAP_PVS
|
||||
CommonAssetType::COM_WORLD, // ASSET_TYPE_COMWORLD
|
||||
CommonAssetType::GAME_WORLD_SP, // ASSET_TYPE_GAMEWORLD_SP
|
||||
CommonAssetType::GAME_WORLD_MP, // ASSET_TYPE_GAMEWORLD_MP
|
||||
CommonAssetType::MAP_ENTS, // ASSET_TYPE_MAP_ENTS
|
||||
CommonAssetType::GFX_WORLD, // ASSET_TYPE_GFXWORLD
|
||||
CommonAssetType::LIGHT_DEF, // ASSET_TYPE_LIGHT_DEF
|
||||
CommonAssetType::UI_MAP, // ASSET_TYPE_UI_MAP
|
||||
CommonAssetType::FONT, // ASSET_TYPE_FONT
|
||||
CommonAssetType::MENU_LIST, // ASSET_TYPE_MENULIST
|
||||
CommonAssetType::MENU, // ASSET_TYPE_MENU
|
||||
CommonAssetType::LOCALIZE_ENTRY, // ASSET_TYPE_LOCALIZE_ENTRY
|
||||
CommonAssetType::WEAPON, // ASSET_TYPE_WEAPON
|
||||
CommonAssetType::WEAPON_DEF, // ASSET_TYPE_WEAPONDEF
|
||||
CommonAssetType::WEAPON_VARIANT, // ASSET_TYPE_WEAPON_VARIANT
|
||||
CommonAssetType::SOUND_DRIVER_GLOBALS, // ASSET_TYPE_SNDDRIVER_GLOBALS
|
||||
CommonAssetType::FX, // ASSET_TYPE_FX
|
||||
CommonAssetType::IMPACT_FX, // ASSET_TYPE_IMPACT_FX
|
||||
CommonAssetType::AI_TYPE, // ASSET_TYPE_AITYPE
|
||||
CommonAssetType::MP_TYPE, // ASSET_TYPE_MPTYPE
|
||||
CommonAssetType::MP_BODY, // ASSET_TYPE_MPBODY
|
||||
CommonAssetType::MP_HEAD, // ASSET_TYPE_MPHEAD
|
||||
CommonAssetType::CHARACTER, // ASSET_TYPE_CHARACTER
|
||||
CommonAssetType::XMODEL_ALIAS, // ASSET_TYPE_XMODELALIAS
|
||||
CommonAssetType::RAW_FILE, // ASSET_TYPE_RAWFILE
|
||||
CommonAssetType::STRING_TABLE, // ASSET_TYPE_STRINGTABLE
|
||||
CommonAssetType::PACK_INDEX, // ASSET_TYPE_PACK_INDEX
|
||||
CommonAssetType::XGLOBALS, // ASSET_TYPE_XGLOBALS
|
||||
CommonAssetType::DDL, // ASSET_TYPE_DDL
|
||||
CommonAssetType::GLASSES, // ASSET_TYPE_GLASSES
|
||||
CommonAssetType::EMBLEM_SET, // ASSET_TYPE_EMBLEMSET
|
||||
};
|
||||
|
||||
assert(gameAssetType < ASSET_TYPE_COUNT);
|
||||
return lookupTable[gameAssetType];
|
||||
}
|
||||
|
||||
std::optional<asset_type_t> CommonAssetTypeMapper::CommonToGameAssetType(const CommonAssetType commonAssetType) const
|
||||
{
|
||||
#define MAP_COMMON(common, game) \
|
||||
case common: \
|
||||
return game;
|
||||
|
||||
switch (commonAssetType)
|
||||
{
|
||||
MAP_COMMON(CommonAssetType::XMODEL_PIECES, ASSET_TYPE_XMODELPIECES)
|
||||
MAP_COMMON(CommonAssetType::PHYS_PRESET, ASSET_TYPE_PHYSPRESET)
|
||||
MAP_COMMON(CommonAssetType::PHYS_CONSTRAINTS, ASSET_TYPE_PHYSCONSTRAINTS)
|
||||
MAP_COMMON(CommonAssetType::DESTRUCTIBLE_DEF, ASSET_TYPE_DESTRUCTIBLEDEF)
|
||||
MAP_COMMON(CommonAssetType::XANIM, ASSET_TYPE_XANIMPARTS)
|
||||
MAP_COMMON(CommonAssetType::XMODEL, ASSET_TYPE_XMODEL)
|
||||
MAP_COMMON(CommonAssetType::MATERIAL, ASSET_TYPE_MATERIAL)
|
||||
MAP_COMMON(CommonAssetType::TECHNIQUE_SET, ASSET_TYPE_TECHNIQUE_SET)
|
||||
MAP_COMMON(CommonAssetType::IMAGE, ASSET_TYPE_IMAGE)
|
||||
MAP_COMMON(CommonAssetType::SOUND, ASSET_TYPE_SOUND)
|
||||
MAP_COMMON(CommonAssetType::SOUND_PATCH, ASSET_TYPE_SOUND_PATCH)
|
||||
MAP_COMMON(CommonAssetType::CLIP_MAP, ASSET_TYPE_CLIPMAP_PVS)
|
||||
MAP_COMMON(CommonAssetType::COM_WORLD, ASSET_TYPE_COMWORLD)
|
||||
MAP_COMMON(CommonAssetType::GAME_WORLD_SP, ASSET_TYPE_GAMEWORLD_SP)
|
||||
MAP_COMMON(CommonAssetType::GAME_WORLD_MP, ASSET_TYPE_GAMEWORLD_MP)
|
||||
MAP_COMMON(CommonAssetType::MAP_ENTS, ASSET_TYPE_MAP_ENTS)
|
||||
MAP_COMMON(CommonAssetType::GFX_WORLD, ASSET_TYPE_GFXWORLD)
|
||||
MAP_COMMON(CommonAssetType::LIGHT_DEF, ASSET_TYPE_LIGHT_DEF)
|
||||
MAP_COMMON(CommonAssetType::UI_MAP, ASSET_TYPE_UI_MAP)
|
||||
MAP_COMMON(CommonAssetType::FONT, ASSET_TYPE_FONT)
|
||||
MAP_COMMON(CommonAssetType::MENU_LIST, ASSET_TYPE_MENULIST)
|
||||
MAP_COMMON(CommonAssetType::MENU, ASSET_TYPE_MENU)
|
||||
MAP_COMMON(CommonAssetType::LOCALIZE_ENTRY, ASSET_TYPE_LOCALIZE_ENTRY)
|
||||
MAP_COMMON(CommonAssetType::WEAPON, ASSET_TYPE_WEAPON)
|
||||
MAP_COMMON(CommonAssetType::WEAPON_DEF, ASSET_TYPE_WEAPONDEF)
|
||||
MAP_COMMON(CommonAssetType::WEAPON_VARIANT, ASSET_TYPE_WEAPON_VARIANT)
|
||||
MAP_COMMON(CommonAssetType::SOUND_DRIVER_GLOBALS, ASSET_TYPE_SNDDRIVER_GLOBALS)
|
||||
MAP_COMMON(CommonAssetType::FX, ASSET_TYPE_FX)
|
||||
MAP_COMMON(CommonAssetType::IMPACT_FX, ASSET_TYPE_IMPACT_FX)
|
||||
MAP_COMMON(CommonAssetType::AI_TYPE, ASSET_TYPE_AITYPE)
|
||||
MAP_COMMON(CommonAssetType::MP_TYPE, ASSET_TYPE_MPTYPE)
|
||||
MAP_COMMON(CommonAssetType::MP_BODY, ASSET_TYPE_MPBODY)
|
||||
MAP_COMMON(CommonAssetType::MP_HEAD, ASSET_TYPE_MPHEAD)
|
||||
MAP_COMMON(CommonAssetType::CHARACTER, ASSET_TYPE_CHARACTER)
|
||||
MAP_COMMON(CommonAssetType::XMODEL_ALIAS, ASSET_TYPE_XMODELALIAS)
|
||||
MAP_COMMON(CommonAssetType::RAW_FILE, ASSET_TYPE_RAWFILE)
|
||||
MAP_COMMON(CommonAssetType::STRING_TABLE, ASSET_TYPE_STRINGTABLE)
|
||||
MAP_COMMON(CommonAssetType::PACK_INDEX, ASSET_TYPE_PACK_INDEX)
|
||||
MAP_COMMON(CommonAssetType::XGLOBALS, ASSET_TYPE_XGLOBALS)
|
||||
MAP_COMMON(CommonAssetType::DDL, ASSET_TYPE_DDL)
|
||||
MAP_COMMON(CommonAssetType::GLASSES, ASSET_TYPE_GLASSES)
|
||||
MAP_COMMON(CommonAssetType::EMBLEM_SET, ASSET_TYPE_EMBLEMSET)
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
#undef MAP_COMMON
|
||||
}
|
||||
} // namespace T5
|
||||
15
src/Common/Game/T5/CommonAssetT5.h
Normal file
15
src/Common/Game/T5/CommonAssetT5.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/CommonAsset.h"
|
||||
|
||||
namespace T5
|
||||
{
|
||||
class CommonAssetTypeMapper final : public ICommonAssetTypeMapper
|
||||
{
|
||||
public:
|
||||
CommonAssetTypeMapper();
|
||||
|
||||
[[nodiscard]] CommonAssetType GameToCommonAssetType(asset_type_t gameAssetType) const override;
|
||||
[[nodiscard]] std::optional<asset_type_t> CommonToGameAssetType(CommonAssetType commonAssetType) const override;
|
||||
};
|
||||
} // namespace T5
|
||||
154
src/Common/Game/T6/CommonAssetT6.cpp
Normal file
154
src/Common/Game/T6/CommonAssetT6.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
#include "CommonAssetT6.h"
|
||||
|
||||
#include "T6.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace T6
|
||||
{
|
||||
CommonAssetTypeMapper::CommonAssetTypeMapper() = default;
|
||||
|
||||
CommonAssetType CommonAssetTypeMapper::GameToCommonAssetType(const asset_type_t gameAssetType) const
|
||||
{
|
||||
static CommonAssetType lookupTable[static_cast<unsigned>(ASSET_TYPE_COUNT)]{
|
||||
CommonAssetType::XMODEL_PIECES, // ASSET_TYPE_XMODELPIECES
|
||||
CommonAssetType::PHYS_PRESET, // ASSET_TYPE_PHYSPRESET
|
||||
CommonAssetType::PHYS_CONSTRAINTS, // ASSET_TYPE_PHYSCONSTRAINTS
|
||||
CommonAssetType::DESTRUCTIBLE_DEF, // ASSET_TYPE_DESTRUCTIBLEDEF
|
||||
CommonAssetType::XANIM, // ASSET_TYPE_XANIMPARTS
|
||||
CommonAssetType::XMODEL, // ASSET_TYPE_XMODEL
|
||||
CommonAssetType::MATERIAL, // ASSET_TYPE_MATERIAL
|
||||
CommonAssetType::TECHNIQUE_SET, // ASSET_TYPE_TECHNIQUE_SET
|
||||
CommonAssetType::IMAGE, // ASSET_TYPE_IMAGE
|
||||
CommonAssetType::SOUND, // ASSET_TYPE_SOUND
|
||||
CommonAssetType::SOUND_PATCH, // ASSET_TYPE_SOUND_PATCH
|
||||
CommonAssetType::CLIP_MAP, // ASSET_TYPE_CLIPMAP
|
||||
CommonAssetType::CLIP_MAP, // ASSET_TYPE_CLIPMAP_PVS
|
||||
CommonAssetType::COM_WORLD, // ASSET_TYPE_COMWORLD
|
||||
CommonAssetType::GAME_WORLD_SP, // ASSET_TYPE_GAMEWORLD_SP
|
||||
CommonAssetType::GAME_WORLD_MP, // ASSET_TYPE_GAMEWORLD_MP
|
||||
CommonAssetType::MAP_ENTS, // ASSET_TYPE_MAP_ENTS
|
||||
CommonAssetType::GFX_WORLD, // ASSET_TYPE_GFXWORLD
|
||||
CommonAssetType::LIGHT_DEF, // ASSET_TYPE_LIGHT_DEF
|
||||
CommonAssetType::UI_MAP, // ASSET_TYPE_UI_MAP
|
||||
CommonAssetType::FONT, // ASSET_TYPE_FONT
|
||||
CommonAssetType::FONT_ICON, // ASSET_TYPE_FONTICON
|
||||
CommonAssetType::MENU_LIST, // ASSET_TYPE_MENULIST
|
||||
CommonAssetType::MENU, // ASSET_TYPE_MENU
|
||||
CommonAssetType::LOCALIZE_ENTRY, // ASSET_TYPE_LOCALIZE_ENTRY
|
||||
CommonAssetType::WEAPON, // ASSET_TYPE_WEAPON
|
||||
CommonAssetType::WEAPON_DEF, // ASSET_TYPE_WEAPONDEF
|
||||
CommonAssetType::WEAPON_VARIANT, // ASSET_TYPE_WEAPON_VARIANT
|
||||
CommonAssetType::WEAPON_FULL, // ASSET_TYPE_WEAPON_FULL
|
||||
CommonAssetType::ATTACHMENT, // ASSET_TYPE_ATTACHMENT
|
||||
CommonAssetType::ATTACHMENT_UNIQUE, // ASSET_TYPE_ATTACHMENT_UNIQUE
|
||||
CommonAssetType::WEAPON_CAMO, // ASSET_TYPE_WEAPON_CAMO
|
||||
CommonAssetType::SOUND_DRIVER_GLOBALS, // ASSET_TYPE_SNDDRIVER_GLOBALS
|
||||
CommonAssetType::FX, // ASSET_TYPE_FX
|
||||
CommonAssetType::IMPACT_FX, // ASSET_TYPE_IMPACT_FX
|
||||
CommonAssetType::AI_TYPE, // ASSET_TYPE_AITYPE
|
||||
CommonAssetType::MP_TYPE, // ASSET_TYPE_MPTYPE
|
||||
CommonAssetType::MP_BODY, // ASSET_TYPE_MPBODY
|
||||
CommonAssetType::MP_HEAD, // ASSET_TYPE_MPHEAD
|
||||
CommonAssetType::CHARACTER, // ASSET_TYPE_CHARACTER
|
||||
CommonAssetType::XMODEL_ALIAS, // ASSET_TYPE_XMODELALIAS
|
||||
CommonAssetType::RAW_FILE, // ASSET_TYPE_RAWFILE
|
||||
CommonAssetType::STRING_TABLE, // ASSET_TYPE_STRINGTABLE
|
||||
CommonAssetType::LEADERBOARD, // ASSET_TYPE_LEADERBOARD
|
||||
CommonAssetType::XGLOBALS, // ASSET_TYPE_XGLOBALS
|
||||
CommonAssetType::DDL, // ASSET_TYPE_DDL
|
||||
CommonAssetType::GLASSES, // ASSET_TYPE_GLASSES
|
||||
CommonAssetType::EMBLEM_SET, // ASSET_TYPE_EMBLEMSET
|
||||
CommonAssetType::SCRIPT, // ASSET_TYPE_SCRIPTPARSETREE
|
||||
CommonAssetType::KEY_VALUE_PAIRS, // ASSET_TYPE_KEYVALUEPAIRS
|
||||
CommonAssetType::VEHICLE, // ASSET_TYPE_VEHICLEDEF
|
||||
CommonAssetType::MEMORY_BLOCK, // ASSET_TYPE_MEMORYBLOCK
|
||||
CommonAssetType::ADDON_MAP_ENTS, // ASSET_TYPE_ADDON_MAP_ENTS
|
||||
CommonAssetType::TRACER, // ASSET_TYPE_TRACER
|
||||
CommonAssetType::SKINNED_VERTS, // ASSET_TYPE_SKINNEDVERTS
|
||||
CommonAssetType::QDB, // ASSET_TYPE_QDB
|
||||
CommonAssetType::SLUG, // ASSET_TYPE_SLUG
|
||||
CommonAssetType::FOOTSTEP_TABLE, // ASSET_TYPE_FOOTSTEP_TABLE
|
||||
CommonAssetType::FOOTSTEP_FX_TABLE, // ASSET_TYPE_FOOTSTEPFX_TABLE
|
||||
CommonAssetType::ZBARRIER, // ASSET_TYPE_ZBARRIER
|
||||
};
|
||||
|
||||
assert(gameAssetType < ASSET_TYPE_COUNT);
|
||||
return lookupTable[gameAssetType];
|
||||
}
|
||||
|
||||
std::optional<asset_type_t> CommonAssetTypeMapper::CommonToGameAssetType(const CommonAssetType commonAssetType) const
|
||||
{
|
||||
#define MAP_COMMON(common, game) \
|
||||
case common: \
|
||||
return game;
|
||||
|
||||
switch (commonAssetType)
|
||||
{
|
||||
MAP_COMMON(CommonAssetType::XMODEL_PIECES, ASSET_TYPE_XMODELPIECES)
|
||||
MAP_COMMON(CommonAssetType::PHYS_PRESET, ASSET_TYPE_PHYSPRESET)
|
||||
MAP_COMMON(CommonAssetType::PHYS_CONSTRAINTS, ASSET_TYPE_PHYSCONSTRAINTS)
|
||||
MAP_COMMON(CommonAssetType::DESTRUCTIBLE_DEF, ASSET_TYPE_DESTRUCTIBLEDEF)
|
||||
MAP_COMMON(CommonAssetType::XANIM, ASSET_TYPE_XANIMPARTS)
|
||||
MAP_COMMON(CommonAssetType::XMODEL, ASSET_TYPE_XMODEL)
|
||||
MAP_COMMON(CommonAssetType::MATERIAL, ASSET_TYPE_MATERIAL)
|
||||
MAP_COMMON(CommonAssetType::TECHNIQUE_SET, ASSET_TYPE_TECHNIQUE_SET)
|
||||
MAP_COMMON(CommonAssetType::IMAGE, ASSET_TYPE_IMAGE)
|
||||
MAP_COMMON(CommonAssetType::SOUND, ASSET_TYPE_SOUND)
|
||||
MAP_COMMON(CommonAssetType::SOUND_PATCH, ASSET_TYPE_SOUND_PATCH)
|
||||
MAP_COMMON(CommonAssetType::CLIP_MAP, ASSET_TYPE_CLIPMAP_PVS)
|
||||
MAP_COMMON(CommonAssetType::COM_WORLD, ASSET_TYPE_COMWORLD)
|
||||
MAP_COMMON(CommonAssetType::GAME_WORLD_SP, ASSET_TYPE_GAMEWORLD_SP)
|
||||
MAP_COMMON(CommonAssetType::GAME_WORLD_MP, ASSET_TYPE_GAMEWORLD_MP)
|
||||
MAP_COMMON(CommonAssetType::MAP_ENTS, ASSET_TYPE_MAP_ENTS)
|
||||
MAP_COMMON(CommonAssetType::GFX_WORLD, ASSET_TYPE_GFXWORLD)
|
||||
MAP_COMMON(CommonAssetType::LIGHT_DEF, ASSET_TYPE_LIGHT_DEF)
|
||||
MAP_COMMON(CommonAssetType::UI_MAP, ASSET_TYPE_UI_MAP)
|
||||
MAP_COMMON(CommonAssetType::FONT, ASSET_TYPE_FONT)
|
||||
MAP_COMMON(CommonAssetType::FONT_ICON, ASSET_TYPE_FONTICON)
|
||||
MAP_COMMON(CommonAssetType::MENU_LIST, ASSET_TYPE_MENULIST)
|
||||
MAP_COMMON(CommonAssetType::MENU, ASSET_TYPE_MENU)
|
||||
MAP_COMMON(CommonAssetType::LOCALIZE_ENTRY, ASSET_TYPE_LOCALIZE_ENTRY)
|
||||
MAP_COMMON(CommonAssetType::WEAPON, ASSET_TYPE_WEAPON)
|
||||
MAP_COMMON(CommonAssetType::WEAPON_DEF, ASSET_TYPE_WEAPONDEF)
|
||||
MAP_COMMON(CommonAssetType::WEAPON_VARIANT, ASSET_TYPE_WEAPON_VARIANT)
|
||||
MAP_COMMON(CommonAssetType::WEAPON_FULL, ASSET_TYPE_WEAPON_FULL)
|
||||
MAP_COMMON(CommonAssetType::ATTACHMENT, ASSET_TYPE_ATTACHMENT)
|
||||
MAP_COMMON(CommonAssetType::ATTACHMENT_UNIQUE, ASSET_TYPE_ATTACHMENT_UNIQUE)
|
||||
MAP_COMMON(CommonAssetType::WEAPON_CAMO, ASSET_TYPE_WEAPON_CAMO)
|
||||
MAP_COMMON(CommonAssetType::SOUND_DRIVER_GLOBALS, ASSET_TYPE_SNDDRIVER_GLOBALS)
|
||||
MAP_COMMON(CommonAssetType::FX, ASSET_TYPE_FX)
|
||||
MAP_COMMON(CommonAssetType::IMPACT_FX, ASSET_TYPE_IMPACT_FX)
|
||||
MAP_COMMON(CommonAssetType::AI_TYPE, ASSET_TYPE_AITYPE)
|
||||
MAP_COMMON(CommonAssetType::MP_TYPE, ASSET_TYPE_MPTYPE)
|
||||
MAP_COMMON(CommonAssetType::MP_BODY, ASSET_TYPE_MPBODY)
|
||||
MAP_COMMON(CommonAssetType::MP_HEAD, ASSET_TYPE_MPHEAD)
|
||||
MAP_COMMON(CommonAssetType::CHARACTER, ASSET_TYPE_CHARACTER)
|
||||
MAP_COMMON(CommonAssetType::XMODEL_ALIAS, ASSET_TYPE_XMODELALIAS)
|
||||
MAP_COMMON(CommonAssetType::RAW_FILE, ASSET_TYPE_RAWFILE)
|
||||
MAP_COMMON(CommonAssetType::STRING_TABLE, ASSET_TYPE_STRINGTABLE)
|
||||
MAP_COMMON(CommonAssetType::LEADERBOARD, ASSET_TYPE_LEADERBOARD)
|
||||
MAP_COMMON(CommonAssetType::XGLOBALS, ASSET_TYPE_XGLOBALS)
|
||||
MAP_COMMON(CommonAssetType::DDL, ASSET_TYPE_DDL)
|
||||
MAP_COMMON(CommonAssetType::GLASSES, ASSET_TYPE_GLASSES)
|
||||
MAP_COMMON(CommonAssetType::EMBLEM_SET, ASSET_TYPE_EMBLEMSET)
|
||||
MAP_COMMON(CommonAssetType::SCRIPT, ASSET_TYPE_SCRIPTPARSETREE)
|
||||
MAP_COMMON(CommonAssetType::KEY_VALUE_PAIRS, ASSET_TYPE_KEYVALUEPAIRS)
|
||||
MAP_COMMON(CommonAssetType::VEHICLE, ASSET_TYPE_VEHICLEDEF)
|
||||
MAP_COMMON(CommonAssetType::MEMORY_BLOCK, ASSET_TYPE_MEMORYBLOCK)
|
||||
MAP_COMMON(CommonAssetType::ADDON_MAP_ENTS, ASSET_TYPE_ADDON_MAP_ENTS)
|
||||
MAP_COMMON(CommonAssetType::TRACER, ASSET_TYPE_TRACER)
|
||||
MAP_COMMON(CommonAssetType::SKINNED_VERTS, ASSET_TYPE_SKINNEDVERTS)
|
||||
MAP_COMMON(CommonAssetType::QDB, ASSET_TYPE_QDB)
|
||||
MAP_COMMON(CommonAssetType::SLUG, ASSET_TYPE_SLUG)
|
||||
MAP_COMMON(CommonAssetType::FOOTSTEP_TABLE, ASSET_TYPE_FOOTSTEP_TABLE)
|
||||
MAP_COMMON(CommonAssetType::FOOTSTEP_FX_TABLE, ASSET_TYPE_FOOTSTEPFX_TABLE)
|
||||
MAP_COMMON(CommonAssetType::ZBARRIER, ASSET_TYPE_ZBARRIER)
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
#undef MAP_COMMON
|
||||
}
|
||||
} // namespace T6
|
||||
15
src/Common/Game/T6/CommonAssetT6.h
Normal file
15
src/Common/Game/T6/CommonAssetT6.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/CommonAsset.h"
|
||||
|
||||
namespace T6
|
||||
{
|
||||
class CommonAssetTypeMapper final : public ICommonAssetTypeMapper
|
||||
{
|
||||
public:
|
||||
CommonAssetTypeMapper();
|
||||
|
||||
[[nodiscard]] CommonAssetType GameToCommonAssetType(asset_type_t gameAssetType) const override;
|
||||
[[nodiscard]] std::optional<asset_type_t> CommonToGameAssetType(CommonAssetType commonAssetType) const override;
|
||||
};
|
||||
} // namespace T6
|
||||
@@ -11,7 +11,7 @@ namespace
|
||||
{
|
||||
std::unique_ptr<Zone> CreateZone(const ZoneCreationContext& context, const GameId gameId)
|
||||
{
|
||||
return std::make_unique<Zone>(context.m_definition->m_name, 0, gameId);
|
||||
return std::make_unique<Zone>(context.m_definition->m_name, 0, gameId, GamePlatform::PC);
|
||||
}
|
||||
|
||||
std::vector<Gdt*> CreateGdtList(const ZoneCreationContext& context)
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace fs = std::filesystem;
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr double MIN_PROGRESS_TO_REPORT = 0.005;
|
||||
constexpr double MIN_PROGRESS_TO_REPORT = 0.5;
|
||||
|
||||
class LoadingEventProgressReporter : public ProgressCallback
|
||||
{
|
||||
@@ -23,7 +23,7 @@ namespace
|
||||
|
||||
void OnProgress(const size_t current, const size_t total) override
|
||||
{
|
||||
const double percentage = static_cast<double>(current) / static_cast<double>(total);
|
||||
const double percentage = static_cast<double>(current) / static_cast<double>(total) * 100.0;
|
||||
|
||||
if (percentage - m_last_progress >= MIN_PROGRESS_TO_REPORT)
|
||||
{
|
||||
@@ -38,38 +38,53 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
LoadedZone::LoadedZone(std::unique_ptr<Zone> zone, std::string filePath)
|
||||
: m_zone(std::move(zone)),
|
||||
m_file_path(std::move(filePath))
|
||||
{
|
||||
}
|
||||
|
||||
void FastFileContext::Destroy()
|
||||
{
|
||||
// Unload all zones
|
||||
m_loaded_zones.clear();
|
||||
}
|
||||
|
||||
result::Expected<Zone*, std::string> FastFileContext::LoadFastFile(const std::string& path)
|
||||
result::Expected<LoadedZone*, std::string> FastFileContext::LoadFastFile(const std::string& path)
|
||||
{
|
||||
auto zone = ZoneLoading::LoadZone(path, std::make_unique<LoadingEventProgressReporter>(fs::path(path).filename().replace_extension().string()));
|
||||
if (!zone)
|
||||
return result::Unexpected(std::move(zone.error()));
|
||||
|
||||
auto* result = m_loaded_zones.emplace_back(std::move(*zone)).get();
|
||||
auto loadedZone = std::make_unique<LoadedZone>(std::move(*zone), path);
|
||||
|
||||
ui::NotifyZoneLoaded(result->m_name, path);
|
||||
LoadedZone* result;
|
||||
{
|
||||
std::lock_guard lock(m_zone_lock);
|
||||
result = m_loaded_zones.emplace_back(std::move(loadedZone)).get();
|
||||
}
|
||||
|
||||
ui::NotifyZoneLoaded(*result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
result::Expected<NoResult, std::string> FastFileContext::UnloadZone(const std::string& zoneName)
|
||||
{
|
||||
const auto existingZone = std::ranges::find_if(m_loaded_zones,
|
||||
[&zoneName](const std::unique_ptr<Zone>& zone)
|
||||
{
|
||||
return zone->m_name == zoneName;
|
||||
});
|
||||
|
||||
if (existingZone != m_loaded_zones.end())
|
||||
{
|
||||
m_loaded_zones.erase(existingZone);
|
||||
ui::NotifyZoneUnloaded(zoneName);
|
||||
return NoResult();
|
||||
std::lock_guard lock(m_zone_lock);
|
||||
const auto existingZone = std::ranges::find_if(m_loaded_zones,
|
||||
[&zoneName](const std::unique_ptr<LoadedZone>& loadedZone)
|
||||
{
|
||||
return loadedZone->m_zone->m_name == zoneName;
|
||||
});
|
||||
|
||||
if (existingZone != m_loaded_zones.end())
|
||||
{
|
||||
m_loaded_zones.erase(existingZone);
|
||||
ui::NotifyZoneUnloaded(zoneName);
|
||||
return NoResult();
|
||||
}
|
||||
}
|
||||
|
||||
return result::Unexpected(std::format("No zone with name {} loaded", zoneName));
|
||||
|
||||
@@ -4,15 +4,26 @@
|
||||
#include "Zone/Zone.h"
|
||||
|
||||
#include <memory>
|
||||
#include <shared_mutex>
|
||||
#include <vector>
|
||||
|
||||
class LoadedZone
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<Zone> m_zone;
|
||||
std::string m_file_path;
|
||||
|
||||
LoadedZone(std::unique_ptr<Zone> zone, std::string filePath);
|
||||
};
|
||||
|
||||
class FastFileContext
|
||||
{
|
||||
public:
|
||||
void Destroy();
|
||||
|
||||
result::Expected<Zone*, std::string> LoadFastFile(const std::string& path);
|
||||
result::Expected<LoadedZone*, std::string> LoadFastFile(const std::string& path);
|
||||
result::Expected<NoResult, std::string> UnloadZone(const std::string& zoneName);
|
||||
|
||||
std::vector<std::unique_ptr<Zone>> m_loaded_zones;
|
||||
std::vector<std::unique_ptr<LoadedZone>> m_loaded_zones;
|
||||
std::shared_mutex m_zone_lock;
|
||||
};
|
||||
|
||||
174
src/ModMan/Web/Binds/AssetBinds.cpp
Normal file
174
src/ModMan/Web/Binds/AssetBinds.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
#include "AssetBinds.h"
|
||||
|
||||
#include "Context/ModManContext.h"
|
||||
#include "Game/CommonAsset.h"
|
||||
#include "Web/UiCommunication.h"
|
||||
|
||||
#include "Json/JsonExtension.h"
|
||||
#include <cstdint>
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(CommonAssetType,
|
||||
{
|
||||
{CommonAssetType::PHYS_PRESET, "PHYS_PRESET" },
|
||||
{CommonAssetType::XANIM, "XANIM" },
|
||||
{CommonAssetType::XMODEL, "XMODEL" },
|
||||
{CommonAssetType::MATERIAL, "MATERIAL" },
|
||||
{CommonAssetType::TECHNIQUE_SET, "TECHNIQUE_SET" },
|
||||
{CommonAssetType::IMAGE, "IMAGE" },
|
||||
{CommonAssetType::SOUND, "SOUND" },
|
||||
{CommonAssetType::SOUND_CURVE, "SOUND_CURVE" },
|
||||
{CommonAssetType::LOADED_SOUND, "LOADED_SOUND" },
|
||||
{CommonAssetType::CLIP_MAP, "CLIP_MAP" },
|
||||
{CommonAssetType::COM_WORLD, "COM_WORLD" },
|
||||
{CommonAssetType::GAME_WORLD_SP, "GAME_WORLD_SP" },
|
||||
{CommonAssetType::GAME_WORLD_MP, "GAME_WORLD_MP" },
|
||||
{CommonAssetType::MAP_ENTS, "MAP_ENTS" },
|
||||
{CommonAssetType::GFX_WORLD, "GFX_WORLD" },
|
||||
{CommonAssetType::LIGHT_DEF, "LIGHT_DEF" },
|
||||
{CommonAssetType::UI_MAP, "UI_MAP" },
|
||||
{CommonAssetType::FONT, "FONT" },
|
||||
{CommonAssetType::MENU_LIST, "MENU_LIST" },
|
||||
{CommonAssetType::MENU, "MENU" },
|
||||
{CommonAssetType::LOCALIZE_ENTRY, "LOCALIZE_ENTRY" },
|
||||
{CommonAssetType::WEAPON, "WEAPON" },
|
||||
{CommonAssetType::SOUND_DRIVER_GLOBALS, "SOUND_DRIVER_GLOBALS"},
|
||||
{CommonAssetType::FX, "FX" },
|
||||
{CommonAssetType::IMPACT_FX, "IMPACT_FX" },
|
||||
{CommonAssetType::AI_TYPE, "AI_TYPE" },
|
||||
{CommonAssetType::MP_TYPE, "MP_TYPE" },
|
||||
{CommonAssetType::CHARACTER, "CHARACTER" },
|
||||
{CommonAssetType::XMODEL_ALIAS, "XMODEL_ALIAS" },
|
||||
{CommonAssetType::RAW_FILE, "RAW_FILE" },
|
||||
{CommonAssetType::STRING_TABLE, "STRING_TABLE" },
|
||||
{CommonAssetType::XMODEL_PIECES, "XMODEL_PIECES" },
|
||||
{CommonAssetType::PHYS_COLL_MAP, "PHYS_COLL_MAP" },
|
||||
{CommonAssetType::XMODEL_SURFS, "XMODEL_SURFS" },
|
||||
{CommonAssetType::PIXEL_SHADER, "PIXEL_SHADER" },
|
||||
{CommonAssetType::VERTEX_SHADER, "VERTEX_SHADER" },
|
||||
{CommonAssetType::VERTEX_DECL, "VERTEX_DECL" },
|
||||
{CommonAssetType::FX_WORLD, "FX_WORLD" },
|
||||
{CommonAssetType::LEADERBOARD, "LEADERBOARD" },
|
||||
{CommonAssetType::STRUCTURED_DATA_DEF, "STRUCTURED_DATA_DEF" },
|
||||
{CommonAssetType::TRACER, "TRACER" },
|
||||
{CommonAssetType::VEHICLE, "VEHICLE" },
|
||||
{CommonAssetType::ADDON_MAP_ENTS, "ADDON_MAP_ENTS" },
|
||||
{CommonAssetType::GLASS_WORLD, "GLASS_WORLD" },
|
||||
{CommonAssetType::PATH_DATA, "PATH_DATA" },
|
||||
{CommonAssetType::VEHICLE_TRACK, "VEHICLE_TRACK" },
|
||||
{CommonAssetType::ATTACHMENT, "ATTACHMENT" },
|
||||
{CommonAssetType::SURFACE_FX, "SURFACE_FX" },
|
||||
{CommonAssetType::SCRIPT, "SCRIPT" },
|
||||
{CommonAssetType::PHYS_CONSTRAINTS, "PHYS_CONSTRAINTS" },
|
||||
{CommonAssetType::DESTRUCTIBLE_DEF, "DESTRUCTIBLE_DEF" },
|
||||
{CommonAssetType::SOUND_PATCH, "SOUND_PATCH" },
|
||||
{CommonAssetType::WEAPON_DEF, "WEAPON_DEF" },
|
||||
{CommonAssetType::WEAPON_VARIANT, "WEAPON_VARIANT" },
|
||||
{CommonAssetType::MP_BODY, "MP_BODY" },
|
||||
{CommonAssetType::MP_HEAD, "MP_HEAD" },
|
||||
{CommonAssetType::PACK_INDEX, "PACK_INDEX" },
|
||||
{CommonAssetType::XGLOBALS, "XGLOBALS" },
|
||||
{CommonAssetType::DDL, "DDL" },
|
||||
{CommonAssetType::GLASSES, "GLASSES" },
|
||||
{CommonAssetType::EMBLEM_SET, "EMBLEM_SET" },
|
||||
{CommonAssetType::FONT_ICON, "FONT_ICON" },
|
||||
{CommonAssetType::WEAPON_FULL, "WEAPON_FULL" },
|
||||
{CommonAssetType::ATTACHMENT_UNIQUE, "ATTACHMENT_UNIQUE" },
|
||||
{CommonAssetType::WEAPON_CAMO, "WEAPON_CAMO" },
|
||||
{CommonAssetType::KEY_VALUE_PAIRS, "KEY_VALUE_PAIRS" },
|
||||
{CommonAssetType::MEMORY_BLOCK, "MEMORY_BLOCK" },
|
||||
{CommonAssetType::SKINNED_VERTS, "SKINNED_VERTS" },
|
||||
{CommonAssetType::QDB, "QDB" },
|
||||
{CommonAssetType::SLUG, "SLUG" },
|
||||
{CommonAssetType::FOOTSTEP_TABLE, "FOOTSTEP_TABLE" },
|
||||
{CommonAssetType::FOOTSTEP_FX_TABLE, "FOOTSTEP_FX_TABLE" },
|
||||
{CommonAssetType::ZBARRIER, "ZBARRIER" },
|
||||
});
|
||||
|
||||
namespace
|
||||
{
|
||||
class AssetDto
|
||||
{
|
||||
public:
|
||||
CommonAssetType type;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_EXTENSION(AssetDto, type, name);
|
||||
|
||||
class ZoneAssetsDto
|
||||
{
|
||||
public:
|
||||
std::vector<AssetDto> assets;
|
||||
std::vector<AssetDto> references;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneAssetsDto, assets, references);
|
||||
|
||||
ZoneAssetsDto CreateZoneAssetsDto(const Zone& zone)
|
||||
{
|
||||
std::vector<AssetDto> assets;
|
||||
std::vector<AssetDto> references;
|
||||
|
||||
// Reserve some entries already. Numbers are arbitrary.
|
||||
const auto assetCount = zone.m_pools->GetTotalAssetCount();
|
||||
assets.reserve(assetCount / 2);
|
||||
references.reserve(assetCount / 8);
|
||||
|
||||
const auto& assetTypeMapper = *ICommonAssetTypeMapper::GetCommonAssetMapperByGame(zone.m_game_id);
|
||||
for (const auto& asset : *zone.m_pools)
|
||||
{
|
||||
if (asset->IsReference())
|
||||
{
|
||||
references.emplace_back(AssetDto{
|
||||
.type = assetTypeMapper.GameToCommonAssetType(asset->m_type),
|
||||
.name = asset->ReferencedAssetName(),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
assets.emplace_back(AssetDto{
|
||||
.type = assetTypeMapper.GameToCommonAssetType(asset->m_type),
|
||||
.name = asset->m_name,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return ZoneAssetsDto{
|
||||
.assets = std::move(assets),
|
||||
.references = std::move(references),
|
||||
};
|
||||
}
|
||||
|
||||
std::optional<ZoneAssetsDto> GetZonesForZone(const std::string& zoneName)
|
||||
{
|
||||
auto& context = ModManContext::Get().m_fast_file;
|
||||
|
||||
ZoneAssetsDto result;
|
||||
|
||||
{
|
||||
std::shared_lock lock(context.m_zone_lock);
|
||||
|
||||
for (const auto& loadedZone : context.m_loaded_zones)
|
||||
{
|
||||
const auto& zone = *loadedZone->m_zone;
|
||||
if (zone.m_name == zoneName)
|
||||
return CreateZoneAssetsDto(zone);
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace ui
|
||||
{
|
||||
void RegisterAssetBinds(webview::webview& wv)
|
||||
{
|
||||
Bind<std::string, std::optional<ZoneAssetsDto>>(wv,
|
||||
"getAssetsForZone",
|
||||
[](const std::string& zoneName)
|
||||
{
|
||||
return GetZonesForZone(zoneName);
|
||||
});
|
||||
}
|
||||
} // namespace ui
|
||||
8
src/ModMan/Web/Binds/AssetBinds.h
Normal file
8
src/ModMan/Web/Binds/AssetBinds.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Web/WebViewLib.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
void RegisterAssetBinds(webview::webview& wv);
|
||||
} // namespace ui
|
||||
@@ -1,13 +1,15 @@
|
||||
#include "Binds.h"
|
||||
|
||||
#include "AssetBinds.h"
|
||||
#include "DialogBinds.h"
|
||||
#include "UnlinkingBinds.h"
|
||||
#include "Web/Binds/DialogBinds.h"
|
||||
#include "ZoneBinds.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
void RegisterAllBinds(webview::webview& wv)
|
||||
{
|
||||
RegisterAssetBinds(wv);
|
||||
RegisterDialogHandlerBinds(wv);
|
||||
RegisterUnlinkingBinds(wv);
|
||||
RegisterZoneBinds(wv);
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneUnlinkProgressDto, zoneName, percentage);
|
||||
|
||||
constexpr double MIN_PROGRESS_TO_REPORT = 0.005;
|
||||
constexpr double MIN_PROGRESS_TO_REPORT = 0.5;
|
||||
|
||||
class UnlinkingEventProgressReporter : public ProgressCallback
|
||||
{
|
||||
@@ -36,7 +36,7 @@ namespace
|
||||
|
||||
void OnProgress(const size_t current, const size_t total) override
|
||||
{
|
||||
const double percentage = static_cast<double>(current) / static_cast<double>(total);
|
||||
const double percentage = static_cast<double>(current) / static_cast<double>(total) * 100.0;
|
||||
|
||||
if (percentage - m_last_progress >= MIN_PROGRESS_TO_REPORT)
|
||||
{
|
||||
@@ -54,17 +54,17 @@ namespace
|
||||
{
|
||||
const auto& context = ModManContext::Get().m_fast_file;
|
||||
const auto existingZone = std::ranges::find_if(context.m_loaded_zones,
|
||||
[&zoneName](const std::unique_ptr<Zone>& zone)
|
||||
[&zoneName](const std::unique_ptr<LoadedZone>& loadedZone)
|
||||
{
|
||||
return zone->m_name == zoneName;
|
||||
return loadedZone->m_zone->m_name == zoneName;
|
||||
});
|
||||
|
||||
if (existingZone == context.m_loaded_zones.end())
|
||||
return result::Unexpected(std::format("No zone with name {} loaded", zoneName));
|
||||
|
||||
const auto& zone = *existingZone->get();
|
||||
const auto& loadedZone = *existingZone->get();
|
||||
|
||||
const auto* objWriter = IObjWriter::GetObjWriterForGame(zone.m_game_id);
|
||||
const auto* objWriter = IObjWriter::GetObjWriterForGame(loadedZone.m_zone->m_game_id);
|
||||
|
||||
const auto outputFolderPath = fs::path(utils::GetExecutablePath()).parent_path() / "zone_dump" / zoneName;
|
||||
const auto outputFolderPathStr = outputFolderPath.string();
|
||||
@@ -72,7 +72,7 @@ namespace
|
||||
OutputPathFilesystem outputFolderOutputPath(outputFolderPath);
|
||||
SearchPaths searchPaths;
|
||||
AssetDumpingContext dumpingContext(
|
||||
zone, outputFolderPathStr, outputFolderOutputPath, searchPaths, std::make_unique<UnlinkingEventProgressReporter>(zoneName));
|
||||
*loadedZone.m_zone, outputFolderPathStr, outputFolderOutputPath, searchPaths, std::make_unique<UnlinkingEventProgressReporter>(zoneName));
|
||||
objWriter->DumpZone(dumpingContext);
|
||||
|
||||
return NoResult();
|
||||
|
||||
@@ -5,8 +5,35 @@
|
||||
|
||||
#include "Json/JsonExtension.h"
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(GameId,
|
||||
{
|
||||
{GameId::IW3, "IW3"},
|
||||
{GameId::IW4, "IW4"},
|
||||
{GameId::IW5, "IW5"},
|
||||
{GameId::T5, "T5" },
|
||||
{GameId::T6, "T6" },
|
||||
});
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(GamePlatform,
|
||||
{
|
||||
{GamePlatform::PC, "PC" },
|
||||
{GamePlatform::XBOX, "XBOX"},
|
||||
{GamePlatform::PS3, "PS3" },
|
||||
});
|
||||
|
||||
namespace
|
||||
{
|
||||
class ZoneDto
|
||||
{
|
||||
public:
|
||||
std::string name;
|
||||
std::string filePath;
|
||||
GameId game;
|
||||
GamePlatform platform;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneDto, name, filePath, game, platform);
|
||||
|
||||
class ZoneLoadProgressDto
|
||||
{
|
||||
public:
|
||||
@@ -19,11 +46,10 @@ namespace
|
||||
class ZoneLoadedDto
|
||||
{
|
||||
public:
|
||||
std::string zoneName;
|
||||
std::string filePath;
|
||||
ZoneDto zone;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneLoadedDto, zoneName, filePath);
|
||||
NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneLoadedDto, zone);
|
||||
|
||||
class ZoneUnloadedDto
|
||||
{
|
||||
@@ -33,6 +59,35 @@ namespace
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneUnloadedDto, zoneName);
|
||||
|
||||
ZoneDto CreateZoneDto(const LoadedZone& loadedZone)
|
||||
{
|
||||
return ZoneDto{
|
||||
.name = loadedZone.m_zone->m_name,
|
||||
.filePath = loadedZone.m_file_path,
|
||||
.game = loadedZone.m_zone->m_game_id,
|
||||
.platform = loadedZone.m_zone->m_platform,
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<ZoneDto> GetLoadedZones()
|
||||
{
|
||||
auto& context = ModManContext::Get().m_fast_file;
|
||||
|
||||
std::vector<ZoneDto> result;
|
||||
|
||||
{
|
||||
std::shared_lock lock(context.m_zone_lock);
|
||||
result.reserve(context.m_loaded_zones.size());
|
||||
|
||||
for (const auto& loadedZone : context.m_loaded_zones)
|
||||
{
|
||||
result.emplace_back(CreateZoneDto(*loadedZone));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void LoadFastFile(webview::webview& wv, std::string id, std::string path) // NOLINT(performance-unnecessary-value-param) Copy is made for thread safety
|
||||
{
|
||||
ModManContext::Get().m_db_thread.Dispatch(
|
||||
@@ -45,10 +100,9 @@ namespace
|
||||
ui::PromiseResolve(wv,
|
||||
id,
|
||||
ZoneLoadedDto{
|
||||
.zoneName = maybeZone.value()->m_name,
|
||||
.filePath = path,
|
||||
.zone = CreateZoneDto(*maybeZone.value()),
|
||||
});
|
||||
con::debug("Loaded zone \"{}\"", maybeZone.value()->m_name);
|
||||
con::debug("Loaded zone \"{}\"", maybeZone.value()->m_zone->m_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -89,11 +143,10 @@ namespace ui
|
||||
Notify(*ModManContext::Get().m_main_webview, "zoneLoadProgress", dto);
|
||||
}
|
||||
|
||||
void NotifyZoneLoaded(std::string zoneName, std::string fastFilePath)
|
||||
void NotifyZoneLoaded(const LoadedZone& loadedZone)
|
||||
{
|
||||
const ZoneLoadedDto dto{
|
||||
.zoneName = std::move(zoneName),
|
||||
.filePath = std::move(fastFilePath),
|
||||
.zone = CreateZoneDto(loadedZone),
|
||||
};
|
||||
Notify(*ModManContext::Get().m_main_webview, "zoneLoaded", dto);
|
||||
}
|
||||
@@ -108,6 +161,13 @@ namespace ui
|
||||
|
||||
void RegisterZoneBinds(webview::webview& wv)
|
||||
{
|
||||
BindRetOnly<std::vector<ZoneDto>>(wv,
|
||||
"getZones",
|
||||
[]
|
||||
{
|
||||
return GetLoadedZones();
|
||||
});
|
||||
|
||||
BindAsync<std::string>(wv,
|
||||
"loadFastFile",
|
||||
[&wv](const std::string& id, std::string path)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Context/FastFileContext.h"
|
||||
#include "Web/WebViewLib.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
void NotifyZoneLoadProgress(std::string zoneName, double percentage);
|
||||
void NotifyZoneLoaded(std::string zoneName, std::string fastFilePath);
|
||||
void NotifyZoneLoaded(const LoadedZone& loadedZone);
|
||||
void NotifyZoneUnloaded(std::string zoneName);
|
||||
|
||||
void RegisterZoneBinds(webview::webview& wv);
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace
|
||||
|
||||
newWindow.set_title("OpenAssetTools ModMan");
|
||||
newWindow.set_size(1280, 640, WEBVIEW_HINT_NONE);
|
||||
newWindow.set_size(480, 320, WEBVIEW_HINT_MIN);
|
||||
newWindow.set_size(640, 480, WEBVIEW_HINT_MIN);
|
||||
|
||||
InstallAssetHandler(newWindow);
|
||||
ui::RegisterAllBinds(newWindow);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Plugin } from "vite";
|
||||
import type { Plugin, UserConfig } from "vite";
|
||||
import type { OutputAsset, OutputChunk } from "rollup";
|
||||
import path from "node:path";
|
||||
import fs from "node:fs";
|
||||
@@ -7,8 +7,35 @@ type MinimalOutputAsset = Pick<OutputAsset, "type" | "fileName" | "source">;
|
||||
type MinimalOutputChunk = Pick<OutputChunk, "type" | "fileName" | "code">;
|
||||
type MinimalOutputBundle = Record<string, MinimalOutputAsset | MinimalOutputChunk>;
|
||||
|
||||
interface PublicDirFile {
|
||||
fullPath: string;
|
||||
relativePath: string;
|
||||
}
|
||||
|
||||
function getPublicDirFiles(publicDir?: string): PublicDirFile[] {
|
||||
if (!publicDir) return [];
|
||||
|
||||
const result: PublicDirFile[] = [];
|
||||
const files = fs.readdirSync(publicDir, { recursive: true, withFileTypes: true });
|
||||
for (const file of files) {
|
||||
if (!file.isFile()) continue;
|
||||
const fullPath = path.join(file.parentPath, file.name);
|
||||
let relativePath = path.relative(publicDir, fullPath).replaceAll(/\\/g, "/");
|
||||
if (relativePath.startsWith("./")) {
|
||||
relativePath = relativePath.substring(2);
|
||||
}
|
||||
|
||||
result.push({
|
||||
fullPath,
|
||||
relativePath,
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createVarName(fileName: string) {
|
||||
return fileName.replaceAll(".", "_").toUpperCase();
|
||||
return fileName.replaceAll(/[\\/]/g, "__").replaceAll(/[\.-]/g, "_").toUpperCase();
|
||||
}
|
||||
|
||||
function transformAsset(asset: MinimalOutputAsset) {
|
||||
@@ -33,10 +60,19 @@ function transformChunk(chunk: MinimalOutputChunk) {
|
||||
`;
|
||||
}
|
||||
|
||||
function transformPublicFile(publicFile: PublicDirFile) {
|
||||
const varName = createVarName(publicFile.relativePath);
|
||||
const bytes = [...fs.readFileSync(publicFile.fullPath)].map((v) => String(v)).join(",");
|
||||
|
||||
return `constexpr const unsigned char ${varName}[] {${bytes}};
|
||||
`;
|
||||
}
|
||||
|
||||
function writeHeader(
|
||||
bundle: MinimalOutputBundle,
|
||||
outputDir?: string,
|
||||
options?: HeaderTransformationPluginOptions,
|
||||
publicDir?: string,
|
||||
devServerPort?: number,
|
||||
) {
|
||||
const outputPath = options?.outputPath ?? path.join(outputDir ?? "dist", "ViteAssets.h");
|
||||
@@ -71,12 +107,18 @@ constexpr auto VITE_DEV_SERVER_PORT = ${devServerPort ? String(devServerPort) :
|
||||
`,
|
||||
);
|
||||
|
||||
const fileNames: string[] = [];
|
||||
for (const curBundle of Object.values(bundle)) {
|
||||
if (curBundle.type === "asset") {
|
||||
fs.writeSync(fd, transformAsset(curBundle));
|
||||
} else {
|
||||
fs.writeSync(fd, transformChunk(curBundle));
|
||||
}
|
||||
fileNames.push(curBundle.fileName);
|
||||
}
|
||||
for (const publicDirFile of getPublicDirFiles(publicDir)) {
|
||||
fs.writeSync(fd, transformPublicFile(publicDirFile));
|
||||
fileNames.push(publicDirFile.relativePath);
|
||||
}
|
||||
|
||||
if (includeFileEnumeration) {
|
||||
@@ -95,8 +137,7 @@ static inline const UiFile MOD_MAN_UI_FILES[] {
|
||||
);
|
||||
|
||||
let index = 0;
|
||||
for (const curBundle of Object.values(bundle)) {
|
||||
const fileName = curBundle.fileName;
|
||||
for (const fileName of fileNames) {
|
||||
const varName = createVarName(fileName);
|
||||
|
||||
let prefix = " ";
|
||||
@@ -133,16 +174,21 @@ export default function headerTransformationPlugin(
|
||||
): Plugin {
|
||||
let writeServerActive = false;
|
||||
let writeBundleActive = false;
|
||||
let publicDir: string | undefined = undefined;
|
||||
|
||||
return {
|
||||
name: "vite-plugin-header-transformation",
|
||||
enforce: "post",
|
||||
config(_userOptions, env) {
|
||||
config(userOptions: UserConfig, env) {
|
||||
if (env.command === "serve") {
|
||||
writeServerActive = true;
|
||||
} else {
|
||||
writeBundleActive = true;
|
||||
}
|
||||
|
||||
if (typeof userOptions.publicDir === "string") {
|
||||
publicDir = userOptions.publicDir;
|
||||
}
|
||||
},
|
||||
configureServer(server) {
|
||||
if (!writeServerActive) {
|
||||
@@ -156,6 +202,7 @@ export default function headerTransformationPlugin(
|
||||
},
|
||||
server.config.build.outDir,
|
||||
options,
|
||||
publicDir,
|
||||
server.config.server.port,
|
||||
);
|
||||
});
|
||||
@@ -165,7 +212,7 @@ export default function headerTransformationPlugin(
|
||||
return;
|
||||
}
|
||||
|
||||
writeHeader(bundle, outputOptions.dir, options);
|
||||
writeHeader(bundle, outputOptions.dir, options, publicDir);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="512x512 256x256 128x128 64x64" />
|
||||
<link rel="icon" href="/logo_circle.svg" sizes="any" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Tauri + Vue + Typescript App</title>
|
||||
<title>OpenAssetTools ModMan</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
120
src/ModManUi/package-lock.json
generated
120
src/ModManUi/package-lock.json
generated
@@ -8,8 +8,12 @@
|
||||
"name": "openassettools",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@fontsource/inter": "^5.2.8",
|
||||
"@primeuix/themes": "^1.2.5",
|
||||
"pinia": "3.0.3",
|
||||
"vue": "3.5.22"
|
||||
"primevue": "^4.4.1",
|
||||
"vue": "3.5.22",
|
||||
"vue-router": "4.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node22": "^22.0.2",
|
||||
@@ -1324,6 +1328,15 @@
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fontsource/inter": {
|
||||
"version": "5.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.2.8.tgz",
|
||||
"integrity": "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg==",
|
||||
"license": "OFL-1.1",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ayuhito"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanfs/core": {
|
||||
"version": "0.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
|
||||
@@ -1829,6 +1842,74 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@primeuix/styled": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@primeuix/styled/-/styled-0.7.4.tgz",
|
||||
"integrity": "sha512-QSO/NpOQg8e9BONWRBx9y8VGMCMYz0J/uKfNJEya/RGEu7ARx0oYW0ugI1N3/KB1AAvyGxzKBzGImbwg0KUiOQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@primeuix/utils": "^0.6.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@primeuix/styles": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@primeuix/styles/-/styles-1.2.5.tgz",
|
||||
"integrity": "sha512-nypFRct/oaaBZqP4jinT0puW8ZIfs4u+l/vqUFmJEPU332fl5ePj6DoOpQgTLzo3OfmvSmz5a5/5b4OJJmmi7Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@primeuix/styled": "^0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@primeuix/themes": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@primeuix/themes/-/themes-1.2.5.tgz",
|
||||
"integrity": "sha512-n3YkwJrHQaEESc/D/A/iD815sxp8cKnmzscA6a8Tm8YvMtYU32eCahwLLe6h5rywghVwxASWuG36XBgISYOIjQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@primeuix/styled": "^0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@primeuix/utils": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.6.1.tgz",
|
||||
"integrity": "sha512-tQL/ZOPgCdD+NTimlUmhyD0ey8J1XmpZE4hDHM+/fnuBicVVmlKOd5HpS748LcOVRUKbWjmEPdHX4hi5XZoC1Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@primevue/core": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@primevue/core/-/core-4.4.1.tgz",
|
||||
"integrity": "sha512-RG56iDKIJT//EtntjQzOiWOHZZJczw/qWWtdL5vFvw8/QDS9DPKn8HLpXK7N5Le6KK1MLXUsxoiGTZK+poUFUg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@primeuix/styled": "^0.7.4",
|
||||
"@primeuix/utils": "^0.6.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.11.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@primevue/icons": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@primevue/icons/-/icons-4.4.1.tgz",
|
||||
"integrity": "sha512-UfDimrIjVdY6EziwieyV4zPKzW6mnKHKhy4Dgyjv2oI6pNeuim+onbJo1ce22PEGXW78vfblG/3/JIzVHFweqQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@primeuix/utils": "^0.6.1",
|
||||
"@primevue/core": "4.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/pluginutils": {
|
||||
"version": "1.0.0-beta.29",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.29.tgz",
|
||||
@@ -5369,6 +5450,22 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/primevue": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/primevue/-/primevue-4.4.1.tgz",
|
||||
"integrity": "sha512-JbHBa5k30pZ7mn/z4vYBOnyt5GrR15eM3X0wa3VanonxnFLYkTEx8OMh33aU6ndWeOfi7Ef57dOL3bTH+3f4hQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@primeuix/styled": "^0.7.4",
|
||||
"@primeuix/styles": "^1.2.5",
|
||||
"@primeuix/utils": "^0.6.1",
|
||||
"@primevue/core": "4.4.1",
|
||||
"@primevue/icons": "4.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/proto-list": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
|
||||
@@ -6553,6 +6650,27 @@
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-router": {
|
||||
"version": "4.6.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.3.tgz",
|
||||
"integrity": "sha512-ARBedLm9YlbvQomnmq91Os7ck6efydTSpRP3nuOKCvgJOHNrhRoJDSKtee8kcL1Vf7nz6U+PMBL+hTvR3bTVQg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^6.6.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/posva"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-router/node_modules/@vue/devtools-api": {
|
||||
"version": "6.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
|
||||
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vue-tsc": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.1.2.tgz",
|
||||
|
||||
@@ -13,8 +13,12 @@
|
||||
"format": "prettier --write **/*.{js,ts,vue,html,json,yml,yaml,md}"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/inter": "^5.2.8",
|
||||
"@primeuix/themes": "^1.2.5",
|
||||
"pinia": "3.0.3",
|
||||
"vue": "3.5.22"
|
||||
"primevue": "^4.4.1",
|
||||
"vue": "3.5.22",
|
||||
"vue-router": "4.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node22": "^22.0.2",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 130 KiB |
77
src/ModManUi/public/logo_circle.svg
Normal file
77
src/ModManUi/public/logo_circle.svg
Normal file
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="300mm"
|
||||
height="300mm"
|
||||
viewBox="0 0 300 300"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
|
||||
sodipodi:docname="oat_circle.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#999999"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="0.55748644"
|
||||
inkscape:cx="452.02893"
|
||||
inkscape:cy="637.68367"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1129"
|
||||
inkscape:window-x="1672"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" /><defs
|
||||
id="defs1"><filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter19"
|
||||
x="-0.16704432"
|
||||
y="-0.08986926"
|
||||
width="1.3601893"
|
||||
height="1.1937806"><feFlood
|
||||
result="flood"
|
||||
in="SourceGraphic"
|
||||
flood-opacity="0.403922"
|
||||
flood-color="rgb(0,0,0)"
|
||||
id="feFlood18" /><feGaussianBlur
|
||||
result="blur"
|
||||
in="SourceGraphic"
|
||||
stdDeviation="8.000000"
|
||||
id="feGaussianBlur18" /><feOffset
|
||||
result="offset"
|
||||
in="blur"
|
||||
dx="3.000000"
|
||||
dy="3.000000"
|
||||
id="feOffset18" /><feComposite
|
||||
result="comp1"
|
||||
operator="in"
|
||||
in="flood"
|
||||
in2="offset"
|
||||
id="feComposite18" /><feComposite
|
||||
result="comp2"
|
||||
operator="over"
|
||||
in="SourceGraphic"
|
||||
in2="comp1"
|
||||
id="feComposite19" /></filter></defs><g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"><circle
|
||||
style="fill:#ca893d;stroke-width:0.264583;fill-opacity:1"
|
||||
id="path2"
|
||||
cx="149.73645"
|
||||
cy="151.63484"
|
||||
r="128" /><path
|
||||
style="fill:#ffffff;stroke:none;stroke-width:0.724;fill-opacity:1;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter19)"
|
||||
d="m 157.15533,40.658523 c -7.16528,10.302747 -12.51327,22.617436 -16.6111,34.458658 -2.54917,7.366211 -4.77329,15.607101 -4.02076,23.482935 0.33817,3.539174 1.30988,7.672094 3.18904,10.720474 0.97925,1.58854 3.26203,2.91006 3.81397,4.59843 0.92967,2.84378 0.74731,6.23647 0.87645,9.18503 0.18554,4.23723 0.42148,8.50748 0.23514,12.76248 -0.30007,6.85199 -2.86584,14.43633 -5.6082,20.67519 -1.68147,3.82534 -4.42564,7.76492 -4.84697,11.99672 h -0.25525 c -0.30662,-7.14028 -1.15672,-13.81779 -4.08399,-20.41995 8.36198,-3.90966 7.24983,-15.18254 4.89917,-22.46194 -4.29583,-13.3031 -14.22445,-24.31606 -23.76379,-34.193176 -3.48045,-3.603683 -6.90971,-8.097499 -10.999551,-10.985956 0.986581,12.07896 2.622311,24.405512 5.251911,36.245412 1.24134,5.58915 2.55471,11.99777 5.22415,17.1017 2.58771,4.94766 5.31606,9.73231 10.19914,12.74592 1.43929,0.88826 2.9245,1.43029 4.59448,1.69122 0.9658,0.15091 2.16541,-0.0811 2.89736,0.70371 0.96354,1.03323 1.26089,2.94912 1.69713,4.2581 1.39158,4.17553 1.97461,8.38492 2.2744,12.76246 1.2066,17.61936 -5.6512,33.88753 -11.62428,50.02887 -1.81237,4.89764 -1.57442,10.20759 -3.63514,15.05971 -1.97356,4.64688 -4.14099,8.76759 -6.87617,13.01397 -1.95003,3.02741 -4.3974,6.00391 -4.89799,9.70322 2.02855,-0.15628 2.49496,-2.32202 3.60382,-3.75586 3.20156,-4.13988 6.3358,-8.3512 8.59123,-13.0906 2.73623,-5.74976 3.07562,-12.18903 5.18474,-18.12269 2.31458,-6.51166 6.40216,-12.47781 8.29107,-19.14371 1.96809,-6.94523 2.59545,-15.58781 6.73339,-21.68733 1.20177,-1.77146 5.24937,0.88445 7.15939,1.15809 5.04845,0.72321 10.70726,-0.88082 15.0597,-3.41613 12.21808,-7.11703 21.95698,-18.17281 30.34514,-29.37889 2.98928,-3.99351 6.48878,-7.93184 8.96326,-12.27481 -14.38224,4.6782 -29.79304,6.53244 -43.13713,13.95008 -6.39539,3.55503 -13.16101,8.2226 -16.65797,14.89309 -2.10395,4.01331 -3.43865,9.81381 -4.01723,14.29396 h -0.25524 c 0.50501,-6.34574 3.0145,-14.93411 6.77553,-20.12136 3.07929,-4.24698 7.25737,-7.62116 10.75375,-11.50671 1.94533,-2.16185 4.00931,-4.21297 5.91938,-6.40782 1.02315,-1.17568 2.09515,-2.89626 3.60777,-3.49746 0.98879,-0.393 2.11738,0.39715 3.06298,0.65289 1.52673,0.4129 3.27852,0.39838 4.84974,0.27199 4.6473,-0.37383 9.54534,-3.67807 13.00767,-6.56341 6.74442,-5.62047 11.67306,-14.04755 15.64624,-21.74543 4.64046,-8.990734 9.24016,-18.310406 12.69648,-27.822182 -6.07512,2.546043 -11.99754,6.635251 -17.6122,10.092786 -11.19017,6.890952 -23.12624,14.591936 -30.0038,26.152626 -1.81972,3.05881 -3.46108,6.64757 -3.90458,10.20997 -0.26495,2.12833 0.60659,5.94362 -0.46067,7.65728 -4.32991,6.95238 -12.89408,11.33384 -16.68082,18.6334 h -0.25524 c 2.92582,-7.9652 4.54429,-16.23824 4.33549,-24.75919 -0.0764,-3.12012 -0.19346,-6.34209 -0.57942,-9.44422 -0.17134,-1.37703 -0.87961,-3.43476 -0.46619,-4.79164 0.36474,-1.19717 4.30109,-2.11927 5.38859,-2.98795 3.08532,-2.46452 5.37666,-6.17729 6.78243,-9.83261 3.74161,-9.72902 3.6403,-20.912802 2.93989,-31.140425 -0.67532,-9.861296 -1.19822,-19.875516 -3.08584,-29.608922 h -0.5105 M 110.44471,144.0345 c -3.75903,11.55249 -8.14701,22.91376 -11.097041,34.71391 -1.534837,6.13935 -3.100637,12.50907 -3.015727,18.88845 0.0736,5.52842 0.41629,11.16231 3.261717,16.07972 0.917211,1.58511 2.191701,2.95005 3.704061,3.97665 0.86062,0.58419 2.09474,1.23975 1.85628,2.44889 -1.65212,8.37718 -6.089111,17.15329 -6.194528,25.73687 -0.0257,2.09216 -0.15445,4.03486 -0.007,6.12597 0.0519,0.73659 0.0476,2.07414 1.056448,2.15781 1.85965,0.15424 1.41636,-6.42184 1.50865,-7.77329 0.58862,-8.61903 3.54759,-17.30601 5.13276,-25.77544 0.33859,-1.80907 4.17634,-2.90995 5.57136,-4.04146 3.02114,-2.45045 5.08063,-5.89062 6.45548,-9.4915 5.74688,-15.05154 1.24022,-33.42794 -3.19868,-48.24212 -0.92396,-3.08358 -1.99799,-6.1122 -2.9391,-9.18897 -0.56904,-1.86034 -0.90105,-4.03706 -2.0944,-5.61549 m 56.15486,37.01115 c -5.76022,4.69086 -11.15297,9.97993 -16.59121,15.03687 -10.80773,10.04991 -24.26466,21.75848 -25.44202,37.54449 -0.19124,2.56417 0.42114,5.79387 1.38655,8.16798 0.44584,1.0964 1.53285,2.14209 1.69181,3.31824 0.41267,3.05318 -2.88452,5.79996 -1.88503,9.18898 h 0.25525 c 1.3389,-2.30487 2.3407,-5.50659 2.5525,-8.16798 2.19882,0.32473 4.09594,1.02573 6.38123,0.68894 6.47079,-0.95364 11.28708,-7.14598 14.68157,-12.17516 7.17889,-10.63603 10.7098,-23.84247 13.50438,-36.2454 0.93663,-4.15697 1.96349,-8.31019 2.72048,-12.50722 0.26038,-1.44356 1.17447,-3.43379 0.74449,-4.84974 z"
|
||||
id="path1" /></g></svg>
|
||||
|
After Width: | Height: | Size: 6.7 KiB |
@@ -1,163 +1,56 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from "vue";
|
||||
import { webviewAddEventListener, webviewBinds } from "@/native";
|
||||
import { useZoneStore } from "@/stores/ZoneStore";
|
||||
import SpinningLoader from "@/components/SpinningLoader.vue";
|
||||
|
||||
const zoneStore = useZoneStore();
|
||||
const loadingFastFile = ref(false);
|
||||
const unlinkingFastFile = ref(false);
|
||||
const lastPercentage = ref<number>(0);
|
||||
|
||||
const performingAction = computed<boolean>(() => loadingFastFile.value || unlinkingFastFile.value);
|
||||
const progressBarWidth = computed<string>(() => `${lastPercentage.value * 100}%`);
|
||||
|
||||
async function openFastFileSelect() {
|
||||
return await webviewBinds.openFileDialog({ filters: [{ name: "Fastfiles", filter: "*.ff" }] });
|
||||
}
|
||||
|
||||
async function onOpenFastFileClick() {
|
||||
if (performingAction.value) return;
|
||||
|
||||
const fastFilePath = await openFastFileSelect();
|
||||
if (!fastFilePath) return;
|
||||
|
||||
loadingFastFile.value = true;
|
||||
lastPercentage.value = 0;
|
||||
|
||||
webviewBinds
|
||||
.loadFastFile(fastFilePath)
|
||||
.catch((e: string) => {
|
||||
console.error("Failed to load fastfile:", e);
|
||||
})
|
||||
.finally(() => {
|
||||
loadingFastFile.value = false;
|
||||
lastPercentage.value = 1;
|
||||
});
|
||||
}
|
||||
|
||||
async function onUnlinkFastFileClick() {
|
||||
if (performingAction.value) return;
|
||||
|
||||
const fastFilePath = await openFastFileSelect();
|
||||
if (!fastFilePath) return;
|
||||
|
||||
try {
|
||||
unlinkingFastFile.value = true;
|
||||
|
||||
let loadedZoneName: string;
|
||||
try {
|
||||
lastPercentage.value = 0;
|
||||
loadedZoneName = (await webviewBinds.loadFastFile(fastFilePath)).zoneName;
|
||||
} catch (e: unknown) {
|
||||
console.error("Failed to load fastfile:", e as string);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
lastPercentage.value = 0;
|
||||
await webviewBinds.unlinkZone(loadedZoneName);
|
||||
} catch (e: unknown) {
|
||||
console.error("Failed to unlink fastfile:", e as string);
|
||||
return;
|
||||
} finally {
|
||||
webviewBinds.unloadZone(loadedZoneName);
|
||||
}
|
||||
} finally {
|
||||
unlinkingFastFile.value = false;
|
||||
lastPercentage.value = 1;
|
||||
}
|
||||
}
|
||||
|
||||
function onUnloadClicked(zoneName: string) {
|
||||
webviewBinds.unloadZone(zoneName).catch((e: string) => {
|
||||
console.error("Failed to unload zone:", e);
|
||||
});
|
||||
}
|
||||
|
||||
webviewAddEventListener("zoneLoadProgress", (dto) => {
|
||||
lastPercentage.value = dto.percentage;
|
||||
});
|
||||
|
||||
webviewAddEventListener("zoneUnlinkProgress", (dto) => {
|
||||
lastPercentage.value = dto.percentage;
|
||||
});
|
||||
import ModManHeader from "./components/header/ModManHeader.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="container">
|
||||
<h1>Welcome to ModMan</h1>
|
||||
<small>Nothing to see here yet, this is mainly for testing</small>
|
||||
<ModManHeader />
|
||||
|
||||
<div class="actions">
|
||||
<button :disabled="performingAction" @click="onOpenFastFileClick">
|
||||
<SpinningLoader v-if="loadingFastFile" class="loading" />
|
||||
<span>Load fastfile</span>
|
||||
</button>
|
||||
<button :disabled="performingAction" @click="onUnlinkFastFileClick">
|
||||
<SpinningLoader v-if="unlinkingFastFile" class="loading" />
|
||||
<span>Unlink fastfile</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>Loaded zones:</h3>
|
||||
<div class="zone-list">
|
||||
<div v-for="zone in zoneStore.loadedZones" :key="zone" class="zone">
|
||||
<span>{{ zone }}</span>
|
||||
<button :disabled="performingAction" @click="onUnloadClicked(zone)">Unload</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="progressbar-wrapper">
|
||||
<div
|
||||
class="progressbar"
|
||||
:class="{ visible: performingAction }"
|
||||
:style="{ width: progressBarWidth }"
|
||||
></div>
|
||||
<div class="router-wrapper">
|
||||
<RouterView v-slot="{ Component, route }">
|
||||
<Transition name="blend">
|
||||
<div class="router-rewrapper" :key="route.name">
|
||||
<component :is="Component" />
|
||||
</div>
|
||||
</Transition>
|
||||
</RouterView>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
column-gap: 0.5em;
|
||||
}
|
||||
@use "@style/variables";
|
||||
|
||||
.loading {
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
|
||||
.zone-list {
|
||||
.container {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
row-gap: 0.5em;
|
||||
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.zone > button {
|
||||
margin-left: 0.5em;
|
||||
.router-wrapper {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.progressbar-wrapper {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 0.35rem 0.4rem;
|
||||
.router-rewrapper {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.progressbar {
|
||||
.blend-enter-from,
|
||||
.blend-leave-to {
|
||||
opacity: 0;
|
||||
height: 0.4rem;
|
||||
border-radius: 2.5rem;
|
||||
background-color: #b9772c;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
&.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
.blend-enter-active,
|
||||
.blend-leave-active {
|
||||
transition: opacity 0.25s ease-in-out;
|
||||
}
|
||||
|
||||
.blend-leave-active {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
51
src/ModManUi/src/PrimeVue.ts
Normal file
51
src/ModManUi/src/PrimeVue.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import type { App } from "vue";
|
||||
import PrimeVue from "primevue/config";
|
||||
import Aura from "@primeuix/themes/aura";
|
||||
import { definePreset } from "@primeuix/themes";
|
||||
import type { ColorScale } from "@primeuix/styled";
|
||||
|
||||
const ModManTheme = definePreset(Aura, {
|
||||
primitive: {
|
||||
brand: {
|
||||
50: "var(--color-brand-50)",
|
||||
100: "var(--color-brand-100)",
|
||||
200: "var(--color-brand-200)",
|
||||
300: "var(--color-brand-300)",
|
||||
400: "var(--color-brand-400)",
|
||||
500: "var(--color-brand-500)",
|
||||
600: "var(--color-brand-600)",
|
||||
700: "var(--color-brand-700)",
|
||||
800: "var(--color-brand-800)",
|
||||
900: "var(--color-brand-900)",
|
||||
950: "var(--color-brand-950)",
|
||||
} satisfies ColorScale,
|
||||
},
|
||||
semantic: {
|
||||
primary: {
|
||||
50: "{orange.50}",
|
||||
100: "{orange.100}",
|
||||
200: "{orange.200}",
|
||||
300: "{orange.300}",
|
||||
400: "{orange.400}",
|
||||
500: "{orange.500}",
|
||||
600: "{orange.600}",
|
||||
700: "{orange.700}",
|
||||
800: "{orange.800}",
|
||||
900: "{orange.900}",
|
||||
950: "{orange.950}",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export function configurePrimeVue(app: App) {
|
||||
app.use(PrimeVue, {
|
||||
theme: {
|
||||
preset: ModManTheme,
|
||||
options: {
|
||||
darkModeSelector: ".dark",
|
||||
},
|
||||
},
|
||||
});
|
||||
// Always make dark mode for now
|
||||
document.documentElement.classList.add("dark");
|
||||
}
|
||||
78
src/ModManUi/src/components/header/ModManHeader.vue
Normal file
78
src/ModManUi/src/components/header/ModManHeader.vue
Normal file
@@ -0,0 +1,78 @@
|
||||
<script setup lang="ts">
|
||||
import Button from "primevue/button";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import IconArrowLeft from "../icons/IconArrowLeft.vue";
|
||||
import IconGear from "../icons/IconGear.vue";
|
||||
import { useRouteMeta } from "@/router/RouteMeta.ts";
|
||||
|
||||
const route = useRoute();
|
||||
const { headerTitle, routeNavigateBackTo } = useRouteMeta();
|
||||
const router = useRouter();
|
||||
|
||||
function onClickBack() {
|
||||
if (!routeNavigateBackTo.value) return;
|
||||
|
||||
router.push({ name: routeNavigateBackTo.value });
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header class="header">
|
||||
<div class="header-section left">
|
||||
<Button
|
||||
v-if="routeNavigateBackTo"
|
||||
variant="text"
|
||||
severity="secondary"
|
||||
aria-label="Back"
|
||||
@click="onClickBack"
|
||||
>
|
||||
<template #icon>
|
||||
<IconArrowLeft class="icon" />
|
||||
</template>
|
||||
</Button>
|
||||
</div>
|
||||
<h1 class="title">
|
||||
<span v-if="typeof headerTitle === 'string'">{{ headerTitle }}</span>
|
||||
<component v-else :is="headerTitle" v-bind="route.params" />
|
||||
</h1>
|
||||
<div class="header-section right">
|
||||
<Button variant="text" severity="secondary" aria-label="Settings">
|
||||
<template #icon>
|
||||
<IconGear class="icon" />
|
||||
</template>
|
||||
</Button>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@style/colors";
|
||||
|
||||
.header {
|
||||
background-color: colors.$color-content-background;
|
||||
text-align: center;
|
||||
|
||||
padding: 0.25rem 0.25rem;
|
||||
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
border-bottom: 1px solid colors.$color-content-border;
|
||||
}
|
||||
|
||||
.header-section {
|
||||
width: 12em;
|
||||
|
||||
&.left {
|
||||
text-align: left;
|
||||
}
|
||||
&.right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1rem;
|
||||
line-height: 1;
|
||||
}
|
||||
</style>
|
||||
9
src/ModManUi/src/components/icons/IconArrowLeft.vue
Normal file
9
src/ModManUi/src/components/icons/IconArrowLeft.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640">
|
||||
<!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
||||
<path
|
||||
d="M73.4 297.4C60.9 309.9 60.9 330.2 73.4 342.7L233.4 502.7C245.9 515.2 266.2 515.2 278.7 502.7C291.2 490.2 291.2 469.9 278.7 457.4L173.3 352L544 352C561.7 352 576 337.7 576 320C576 302.3 561.7 288 544 288L173.3 288L278.7 182.6C291.2 170.1 291.2 149.8 278.7 137.3C266.2 124.8 245.9 124.8 233.4 137.3L73.4 297.3z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
9
src/ModManUi/src/components/icons/IconGear.vue
Normal file
9
src/ModManUi/src/components/icons/IconGear.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640">
|
||||
<!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
||||
<path
|
||||
d="M259.1 73.5C262.1 58.7 275.2 48 290.4 48L350.2 48C365.4 48 378.5 58.7 381.5 73.5L396 143.5C410.1 149.5 423.3 157.2 435.3 166.3L503.1 143.8C517.5 139 533.3 145 540.9 158.2L570.8 210C578.4 223.2 575.7 239.8 564.3 249.9L511 297.3C511.9 304.7 512.3 312.3 512.3 320C512.3 327.7 511.8 335.3 511 342.7L564.4 390.2C575.8 400.3 578.4 417 570.9 430.1L541 481.9C533.4 495 517.6 501.1 503.2 496.3L435.4 473.8C423.3 482.9 410.1 490.5 396.1 496.6L381.7 566.5C378.6 581.4 365.5 592 350.4 592L290.6 592C275.4 592 262.3 581.3 259.3 566.5L244.9 496.6C230.8 490.6 217.7 482.9 205.6 473.8L137.5 496.3C123.1 501.1 107.3 495.1 99.7 481.9L69.8 430.1C62.2 416.9 64.9 400.3 76.3 390.2L129.7 342.7C128.8 335.3 128.4 327.7 128.4 320C128.4 312.3 128.9 304.7 129.7 297.3L76.3 249.8C64.9 239.7 62.3 223 69.8 209.9L99.7 158.1C107.3 144.9 123.1 138.9 137.5 143.7L205.3 166.2C217.4 157.1 230.6 149.5 244.6 143.4L259.1 73.5zM320.3 400C364.5 399.8 400.2 363.9 400 319.7C399.8 275.5 363.9 239.8 319.7 240C275.5 240.2 239.8 276.1 240 320.3C240.2 364.5 276.1 400.2 320.3 400z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
@@ -1,124 +0,0 @@
|
||||
:root {
|
||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 400;
|
||||
|
||||
color: #0f0f0f;
|
||||
background-color: #f6f6f6;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 0;
|
||||
padding-top: 10vh;
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
justify-content: start;
|
||||
text-align: center;
|
||||
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: 0.75s;
|
||||
}
|
||||
|
||||
.logo.tauri:hover {
|
||||
filter: drop-shadow(0 0 2em #24c8db);
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input,
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
color: #0f0f0f;
|
||||
background-color: #ffffff;
|
||||
transition: border-color 0.25s;
|
||||
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:not(:disabled):hover {
|
||||
border-color: #396cd8;
|
||||
}
|
||||
button:not(:disabled):active {
|
||||
border-color: #396cd8;
|
||||
background-color: #e8e8e8;
|
||||
}
|
||||
button:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
input,
|
||||
button {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#greet-input {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
color: #f6f6f6;
|
||||
background-color: #2f2f2f;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #24c8db;
|
||||
}
|
||||
|
||||
input,
|
||||
button {
|
||||
color: #ffffff;
|
||||
background-color: #0f0f0f98;
|
||||
}
|
||||
button:not(:disabled):active {
|
||||
background-color: #0f0f0f69;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
import "../public/favicon.ico";
|
||||
import "./main.scss";
|
||||
import "@style/main.scss";
|
||||
|
||||
import { createApp } from "vue";
|
||||
import { createPinia } from "pinia";
|
||||
import { configurePrimeVue } from "./PrimeVue.ts";
|
||||
|
||||
import App from "./App.vue";
|
||||
import { createModManRouter } from "./router/Router.ts";
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
app.use(createPinia());
|
||||
app.use(createModManRouter());
|
||||
|
||||
configurePrimeVue(app);
|
||||
|
||||
app.mount("#app");
|
||||
|
||||
89
src/ModManUi/src/native/AssetBinds.ts
Normal file
89
src/ModManUi/src/native/AssetBinds.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
export enum CommonAssetType {
|
||||
PHYS_PRESET = "PHYS_PRESET",
|
||||
XANIM = "XANIM",
|
||||
XMODEL = "XMODEL",
|
||||
MATERIAL = "MATERIAL",
|
||||
TECHNIQUE_SET = "TECHNIQUE_SET",
|
||||
IMAGE = "IMAGE",
|
||||
SOUND = "SOUND",
|
||||
SOUND_CURVE = "SOUND_CURVE",
|
||||
LOADED_SOUND = "LOADED_SOUND",
|
||||
CLIP_MAP = "CLIP_MAP",
|
||||
COM_WORLD = "COM_WORLD",
|
||||
GAME_WORLD_SP = "GAME_WORLD_SP",
|
||||
GAME_WORLD_MP = "GAME_WORLD_MP",
|
||||
MAP_ENTS = "MAP_ENTS",
|
||||
GFX_WORLD = "GFX_WORLD",
|
||||
LIGHT_DEF = "LIGHT_DEF",
|
||||
UI_MAP = "UI_MAP",
|
||||
FONT = "FONT",
|
||||
MENU_LIST = "MENU_LIST",
|
||||
MENU = "MENU",
|
||||
LOCALIZE_ENTRY = "LOCALIZE_ENTRY",
|
||||
WEAPON = "WEAPON",
|
||||
SOUND_DRIVER_GLOBALS = "SOUND_DRIVER_GLOBALS",
|
||||
FX = "FX",
|
||||
IMPACT_FX = "IMPACT_FX",
|
||||
AI_TYPE = "AI_TYPE",
|
||||
MP_TYPE = "MP_TYPE",
|
||||
CHARACTER = "CHARACTER",
|
||||
XMODEL_ALIAS = "XMODEL_ALIAS",
|
||||
RAW_FILE = "RAW_FILE",
|
||||
STRING_TABLE = "STRING_TABLE",
|
||||
XMODEL_PIECES = "XMODEL_PIECES",
|
||||
PHYS_COLL_MAP = "PHYS_COLL_MAP",
|
||||
XMODEL_SURFS = "XMODEL_SURFS",
|
||||
PIXEL_SHADER = "PIXEL_SHADER",
|
||||
VERTEX_SHADER = "VERTEX_SHADER",
|
||||
VERTEX_DECL = "VERTEX_DECL",
|
||||
FX_WORLD = "FX_WORLD",
|
||||
LEADERBOARD = "LEADERBOARD",
|
||||
STRUCTURED_DATA_DEF = "STRUCTURED_DATA_DEF",
|
||||
TRACER = "TRACER",
|
||||
VEHICLE = "VEHICLE",
|
||||
ADDON_MAP_ENTS = "ADDON_MAP_ENTS",
|
||||
GLASS_WORLD = "GLASS_WORLD",
|
||||
PATH_DATA = "PATH_DATA",
|
||||
VEHICLE_TRACK = "VEHICLE_TRACK",
|
||||
ATTACHMENT = "ATTACHMENT",
|
||||
SURFACE_FX = "SURFACE_FX",
|
||||
SCRIPT = "SCRIPT",
|
||||
PHYS_CONSTRAINTS = "PHYS_CONSTRAINTS",
|
||||
DESTRUCTIBLE_DEF = "DESTRUCTIBLE_DEF",
|
||||
SOUND_PATCH = "SOUND_PATCH",
|
||||
WEAPON_DEF = "WEAPON_DEF",
|
||||
WEAPON_VARIANT = "WEAPON_VARIANT",
|
||||
MP_BODY = "MP_BODY",
|
||||
MP_HEAD = "MP_HEAD",
|
||||
PACK_INDEX = "PACK_INDEX",
|
||||
XGLOBALS = "XGLOBALS",
|
||||
DDL = "DDL",
|
||||
GLASSES = "GLASSES",
|
||||
EMBLEM_SET = "EMBLEM_SET",
|
||||
FONT_ICON = "FONT_ICON",
|
||||
WEAPON_FULL = "WEAPON_FULL",
|
||||
ATTACHMENT_UNIQUE = "ATTACHMENT_UNIQUE",
|
||||
WEAPON_CAMO = "WEAPON_CAMO",
|
||||
KEY_VALUE_PAIRS = "KEY_VALUE_PAIRS",
|
||||
MEMORY_BLOCK = "MEMORY_BLOCK",
|
||||
SKINNED_VERTS = "SKINNED_VERTS",
|
||||
QDB = "QDB",
|
||||
SLUG = "SLUG",
|
||||
FOOTSTEP_TABLE = "FOOTSTEP_TABLE",
|
||||
FOOTSTEP_FX_TABLE = "FOOTSTEP_FX_TABLE",
|
||||
ZBARRIER = "ZBARRIER",
|
||||
}
|
||||
|
||||
export interface AssetDto {
|
||||
type: CommonAssetType;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ZoneAssetsDto {
|
||||
assets: AssetDto[];
|
||||
references: AssetDto[];
|
||||
}
|
||||
|
||||
export interface AssetBinds {
|
||||
getAssetsForZone(zoneName: string): Promise<ZoneAssetsDto | null>;
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
export interface ZoneUnlinkProgressDto {
|
||||
zoneName: string;
|
||||
/**
|
||||
* Between 0-100
|
||||
*/
|
||||
percentage: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,34 @@
|
||||
export enum GameId {
|
||||
IW3 = "IW3",
|
||||
IW4 = "IW4",
|
||||
IW5 = "IW5",
|
||||
T5 = "T5",
|
||||
T6 = "T6",
|
||||
}
|
||||
|
||||
export enum GamePlatform {
|
||||
PC = "PC",
|
||||
XBOX = "XBOX",
|
||||
PS3 = "PS3",
|
||||
}
|
||||
|
||||
export interface ZoneDto {
|
||||
name: string;
|
||||
filePath: string;
|
||||
game: GameId;
|
||||
platform: GamePlatform;
|
||||
}
|
||||
|
||||
export interface ZoneLoadProgressDto {
|
||||
zoneName: string;
|
||||
/**
|
||||
* Between 0-100
|
||||
*/
|
||||
percentage: number;
|
||||
}
|
||||
|
||||
export interface ZoneLoadedDto {
|
||||
zoneName: string;
|
||||
filePath: string;
|
||||
zone: ZoneDto;
|
||||
}
|
||||
|
||||
export interface ZoneUnloadedDto {
|
||||
@@ -13,6 +36,7 @@ export interface ZoneUnloadedDto {
|
||||
}
|
||||
|
||||
export interface ZoneBinds {
|
||||
getZones(): Promise<ZoneDto[]>;
|
||||
loadFastFile(path: string): Promise<ZoneLoadedDto>;
|
||||
unloadZone(zoneName: string): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { AssetBinds } from "./AssetBinds";
|
||||
import type { DialogBinds } from "./DialogBinds";
|
||||
import type { UnlinkingBinds, UnlinkingEventMap } from "./UnlinkingBinds";
|
||||
import type { ZoneBinds, ZoneEventMap } from "./ZoneBinds";
|
||||
|
||||
export type NativeMethods = DialogBinds & UnlinkingBinds & ZoneBinds;
|
||||
export type NativeMethods = AssetBinds & DialogBinds & UnlinkingBinds & ZoneBinds;
|
||||
|
||||
type NativeEventMap = UnlinkingEventMap & ZoneEventMap;
|
||||
|
||||
|
||||
8
src/ModManUi/src/router/Page.ts
Normal file
8
src/ModManUi/src/router/Page.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export const PAGE = {
|
||||
HOME: "Home",
|
||||
INSPECT: {
|
||||
SELECT_ZONE: "Inspect zone",
|
||||
ZONE_DETAILS: "Zone details",
|
||||
},
|
||||
OPTIONS: "Options",
|
||||
};
|
||||
30
src/ModManUi/src/router/RouteMeta.ts
Normal file
30
src/ModManUi/src/router/RouteMeta.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { type Component, computed } from "vue";
|
||||
import { useRoute, type RouteLocationNormalizedGeneric } from "vue-router";
|
||||
|
||||
type HeaderTitleFunc = (route: RouteLocationNormalizedGeneric) => string;
|
||||
export interface TypedRouteMeta {
|
||||
backTo?: string;
|
||||
headerTitleFunc?: HeaderTitleFunc;
|
||||
headerTitleComponent?: Component;
|
||||
}
|
||||
|
||||
export type RouteMeta = TypedRouteMeta & Record<string, unknown>;
|
||||
|
||||
export function useRouteMeta() {
|
||||
const route = useRoute();
|
||||
const meta = computed<RouteMeta>(() => route.meta as RouteMeta);
|
||||
|
||||
const headerTitle = computed<string | Component>(() => {
|
||||
if (meta.value.headerTitleFunc) {
|
||||
return meta.value.headerTitleFunc(route);
|
||||
} else if (meta.value.headerTitleComponent) {
|
||||
return meta.value.headerTitleComponent;
|
||||
}
|
||||
|
||||
return String(route.name);
|
||||
});
|
||||
|
||||
const routeNavigateBackTo = computed<string | null>(() => meta.value.backTo ?? null);
|
||||
|
||||
return { headerTitle, routeNavigateBackTo };
|
||||
}
|
||||
36
src/ModManUi/src/router/Router.ts
Normal file
36
src/ModManUi/src/router/Router.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { createRouter, createWebHashHistory, type RouteRecordRaw } from "vue-router";
|
||||
import { PAGE } from "./Page";
|
||||
import ZoneInspector from "@/view/inspect/ZoneInspector.vue";
|
||||
import InspectDetails from "@/view/inspect_details/InspectDetails.vue";
|
||||
import type { RouteMeta } from "./RouteMeta";
|
||||
import InspectDetailsHeader from "@/view/inspect_details/InspectDetailsHeader.vue";
|
||||
|
||||
const ROUTES: RouteRecordRaw[] = [
|
||||
{
|
||||
path: "/",
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: PAGE.INSPECT.SELECT_ZONE,
|
||||
component: ZoneInspector,
|
||||
},
|
||||
{
|
||||
path: ":zoneName",
|
||||
name: PAGE.INSPECT.ZONE_DETAILS,
|
||||
component: InspectDetails,
|
||||
meta: {
|
||||
backTo: PAGE.INSPECT.SELECT_ZONE,
|
||||
headerTitleComponent: InspectDetailsHeader,
|
||||
} satisfies RouteMeta,
|
||||
props: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export function createModManRouter() {
|
||||
return createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes: ROUTES,
|
||||
});
|
||||
}
|
||||
32
src/ModManUi/src/stores/AssetStore.ts
Normal file
32
src/ModManUi/src/stores/AssetStore.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { computed, ref } from "vue";
|
||||
import { defineStore } from "pinia";
|
||||
import type { ZoneAssetsDto } from "@/native/AssetBinds";
|
||||
import { webviewBinds } from "@/native";
|
||||
|
||||
export const useAssetStore = defineStore("asset", () => {
|
||||
const zoneName = ref<string | null>(null);
|
||||
const assetsOfZone = ref<ZoneAssetsDto | null>(null);
|
||||
|
||||
const isLoading = computed(() => Boolean(assetsOfZone.value));
|
||||
const assetCount = computed(() => assetsOfZone.value?.assets.length ?? 0);
|
||||
const referenceCount = computed(() => assetsOfZone.value?.references.length ?? 0);
|
||||
|
||||
function loadAssetsForZone(newZoneName: string | null) {
|
||||
// Skip if assets are already loaded
|
||||
if (newZoneName === zoneName.value) return;
|
||||
|
||||
// Reset current state
|
||||
zoneName.value = newZoneName;
|
||||
assetsOfZone.value = null;
|
||||
|
||||
// Only load assets when there is a new zone name specified
|
||||
if (!newZoneName) return;
|
||||
webviewBinds.getAssetsForZone(newZoneName).then((res) => {
|
||||
if (zoneName.value === newZoneName) {
|
||||
assetsOfZone.value = res;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return { zoneName, isLoading, assetsOfZone, assetCount, referenceCount, loadAssetsForZone };
|
||||
});
|
||||
31
src/ModManUi/src/stores/UnlinkingStore.ts
Normal file
31
src/ModManUi/src/stores/UnlinkingStore.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { ref } from "vue";
|
||||
import { defineStore } from "pinia";
|
||||
import { webviewAddEventListener, webviewBinds } from "@/native";
|
||||
|
||||
export const useUnlinkingStore = defineStore("unlinking", () => {
|
||||
const isUnlinking = ref(false);
|
||||
const lastPercentage = ref<number>(0);
|
||||
const failureMessage = ref<string | null>(null);
|
||||
|
||||
function unlinkZone(zoneName: string) {
|
||||
isUnlinking.value = true;
|
||||
lastPercentage.value = 0;
|
||||
failureMessage.value = null;
|
||||
return webviewBinds
|
||||
.unlinkZone(zoneName)
|
||||
.catch((e: string) => {
|
||||
console.error("Failed to unlink fastfile:", e);
|
||||
failureMessage.value = e;
|
||||
})
|
||||
.finally(() => {
|
||||
isUnlinking.value = false;
|
||||
lastPercentage.value = 100;
|
||||
});
|
||||
}
|
||||
|
||||
webviewAddEventListener("zoneUnlinkProgress", (dto) => {
|
||||
lastPercentage.value = dto.percentage;
|
||||
});
|
||||
|
||||
return { isUnlinking, lastPercentage, unlinkZone };
|
||||
});
|
||||
@@ -1,20 +1,77 @@
|
||||
import { readonly, ref } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { defineStore } from "pinia";
|
||||
import { webviewAddEventListener } from "@/native";
|
||||
import { webviewAddEventListener, webviewBinds } from "@/native";
|
||||
import type { ZoneDto, ZoneLoadedDto } from "@/native/ZoneBinds";
|
||||
|
||||
export const useZoneStore = defineStore("zone", () => {
|
||||
const loadedZones = ref<string[]>([]);
|
||||
const loadedZones = ref<ZoneDto[]>([]);
|
||||
const zonesCurrentlyBeingLoaded = ref<string[]>([]);
|
||||
const lastPercentageByZoneName = ref<Record<string, number>>({});
|
||||
|
||||
const isLoadingZone = computed(() => zonesCurrentlyBeingLoaded.value.length > 0);
|
||||
|
||||
function loadFastFile(fastFilePath: string): Promise<ZoneLoadedDto> {
|
||||
const lastDirectorySeparator = fastFilePath.replace(/\\/g, "/").lastIndexOf("/");
|
||||
const lastDot = fastFilePath.lastIndexOf(".");
|
||||
const expectedZoneName = fastFilePath.substring(
|
||||
lastDirectorySeparator >= 0 ? lastDirectorySeparator + 1 : 0,
|
||||
lastDot > lastDirectorySeparator ? lastDot : fastFilePath.length,
|
||||
);
|
||||
|
||||
zonesCurrentlyBeingLoaded.value.push(expectedZoneName);
|
||||
lastPercentageByZoneName.value[expectedZoneName] = 0;
|
||||
|
||||
return webviewBinds
|
||||
.loadFastFile(fastFilePath)
|
||||
.catch((e: string) => {
|
||||
console.error("Failed to load fastfile:", e);
|
||||
})
|
||||
.finally(() => {
|
||||
zonesCurrentlyBeingLoaded.value.splice(
|
||||
zonesCurrentlyBeingLoaded.value.indexOf(expectedZoneName),
|
||||
1,
|
||||
);
|
||||
delete lastPercentageByZoneName.value[expectedZoneName];
|
||||
}) as Promise<ZoneLoadedDto>;
|
||||
}
|
||||
|
||||
function getPercentageForZoneBeingLoaded(zoneName: string) {
|
||||
return lastPercentageByZoneName.value[zoneName] ?? 100;
|
||||
}
|
||||
|
||||
function getLoadedZoneByName(zoneName: string) {
|
||||
return loadedZones.value.find((zone) => zone.name === zoneName) ?? null;
|
||||
}
|
||||
|
||||
// Initially get all loaded zones
|
||||
webviewBinds.getZones().then((allZones) => {
|
||||
loadedZones.value = allZones;
|
||||
});
|
||||
|
||||
webviewAddEventListener("zoneLoadProgress", (dto) => {
|
||||
if (lastPercentageByZoneName.value[dto.zoneName] !== undefined) {
|
||||
lastPercentageByZoneName.value[dto.zoneName] = dto.percentage;
|
||||
}
|
||||
});
|
||||
|
||||
webviewAddEventListener("zoneLoaded", (dto) => {
|
||||
loadedZones.value.push(dto.zoneName);
|
||||
loadedZones.value.push(dto.zone);
|
||||
});
|
||||
|
||||
webviewAddEventListener("zoneUnloaded", (dto) => {
|
||||
const index = loadedZones.value.indexOf(dto.zoneName);
|
||||
const index = loadedZones.value.findIndex((zone) => zone.name === dto.zoneName);
|
||||
if (index >= 0) {
|
||||
loadedZones.value.splice(index, 1);
|
||||
}
|
||||
});
|
||||
|
||||
return { loadedZones: readonly(loadedZones) };
|
||||
return {
|
||||
loadedZones,
|
||||
zonesCurrentlyBeingLoaded,
|
||||
isLoadingZone,
|
||||
lastPercentageByZoneName,
|
||||
loadFastFile,
|
||||
getPercentageForZoneBeingLoaded,
|
||||
getLoadedZoneByName,
|
||||
};
|
||||
});
|
||||
|
||||
5
src/ModManUi/src/style/_colors.scss
Normal file
5
src/ModManUi/src/style/_colors.scss
Normal file
@@ -0,0 +1,5 @@
|
||||
@use "colors_primitive";
|
||||
@forward "colors_primitive";
|
||||
|
||||
@use "colors_semantic";
|
||||
@forward "colors_semantic";
|
||||
278
src/ModManUi/src/style/_colors_primitive.scss
Normal file
278
src/ModManUi/src/style/_colors_primitive.scss
Normal file
@@ -0,0 +1,278 @@
|
||||
// Primitive colors are colors that have literal values and they do not change depending on the context.
|
||||
$color-brand-50: #f7ebdf;
|
||||
$color-brand-100: #f1dfca;
|
||||
$color-brand-200: #eaceae;
|
||||
$color-brand-300: #e0b685;
|
||||
$color-brand-400: #d59d5d;
|
||||
$color-brand-500: #cc8838;
|
||||
$color-brand-600: #b9772c;
|
||||
$color-brand-700: #784818;
|
||||
$color-brand-800: #573816;
|
||||
$color-brand-900: #3d2810;
|
||||
$color-brand-950: #291b0a;
|
||||
$color-brand: $color-brand-500;
|
||||
|
||||
// These colors are taken from PrimeVue Aura theme
|
||||
$color-emerald-50: var(--p-emerald-50);
|
||||
$color-emerald-100: var(--p-emerald-100);
|
||||
$color-emerald-200: var(--p-emerald-200);
|
||||
$color-emerald-300: var(--p-emerald-300);
|
||||
$color-emerald-400: var(--p-emerald-400);
|
||||
$color-emerald-500: var(--p-emerald-500);
|
||||
$color-emerald-600: var(--p-emerald-600);
|
||||
$color-emerald-700: var(--p-emerald-700);
|
||||
$color-emerald-800: var(--p-emerald-800);
|
||||
$color-emerald-900: var(--p-emerald-900);
|
||||
$color-emerald-950: var(--p-emerald-950);
|
||||
|
||||
$color-green-50: var(--p-green-50);
|
||||
$color-green-100: var(--p-green-100);
|
||||
$color-green-200: var(--p-green-200);
|
||||
$color-green-300: var(--p-green-300);
|
||||
$color-green-400: var(--p-green-400);
|
||||
$color-green-500: var(--p-green-500);
|
||||
$color-green-600: var(--p-green-600);
|
||||
$color-green-700: var(--p-green-700);
|
||||
$color-green-800: var(--p-green-800);
|
||||
$color-green-900: var(--p-green-900);
|
||||
$color-green-950: var(--p-green-950);
|
||||
|
||||
$color-lime-50: var(--p-lime-50);
|
||||
$color-lime-100: var(--p-lime-100);
|
||||
$color-lime-200: var(--p-lime-200);
|
||||
$color-lime-300: var(--p-lime-300);
|
||||
$color-lime-400: var(--p-lime-400);
|
||||
$color-lime-500: var(--p-lime-500);
|
||||
$color-lime-600: var(--p-lime-600);
|
||||
$color-lime-700: var(--p-lime-700);
|
||||
$color-lime-800: var(--p-lime-800);
|
||||
$color-lime-900: var(--p-lime-900);
|
||||
$color-lime-950: var(--p-lime-950);
|
||||
|
||||
$color-red-50: var(--p-red-50);
|
||||
$color-red-100: var(--p-red-100);
|
||||
$color-red-200: var(--p-red-200);
|
||||
$color-red-300: var(--p-red-300);
|
||||
$color-red-400: var(--p-red-400);
|
||||
$color-red-500: var(--p-red-500);
|
||||
$color-red-600: var(--p-red-600);
|
||||
$color-red-700: var(--p-red-700);
|
||||
$color-red-800: var(--p-red-800);
|
||||
$color-red-900: var(--p-red-900);
|
||||
$color-red-950: var(--p-red-950);
|
||||
|
||||
$color-orange-50: var(--p-orange-50);
|
||||
$color-orange-100: var(--p-orange-100);
|
||||
$color-orange-200: var(--p-orange-200);
|
||||
$color-orange-300: var(--p-orange-300);
|
||||
$color-orange-400: var(--p-orange-400);
|
||||
$color-orange-500: var(--p-orange-500);
|
||||
$color-orange-600: var(--p-orange-600);
|
||||
$color-orange-700: var(--p-orange-700);
|
||||
$color-orange-800: var(--p-orange-800);
|
||||
$color-orange-900: var(--p-orange-900);
|
||||
$color-orange-950: var(--p-orange-950);
|
||||
|
||||
$color-amber-50: var(--p-amber-50);
|
||||
$color-amber-100: var(--p-amber-100);
|
||||
$color-amber-200: var(--p-amber-200);
|
||||
$color-amber-300: var(--p-amber-300);
|
||||
$color-amber-400: var(--p-amber-400);
|
||||
$color-amber-500: var(--p-amber-500);
|
||||
$color-amber-600: var(--p-amber-600);
|
||||
$color-amber-700: var(--p-amber-700);
|
||||
$color-amber-800: var(--p-amber-800);
|
||||
$color-amber-900: var(--p-amber-900);
|
||||
$color-amber-950: var(--p-amber-950);
|
||||
|
||||
$color-yellow-50: var(--p-yellow-50);
|
||||
$color-yellow-100: var(--p-yellow-100);
|
||||
$color-yellow-200: var(--p-yellow-200);
|
||||
$color-yellow-300: var(--p-yellow-300);
|
||||
$color-yellow-400: var(--p-yellow-400);
|
||||
$color-yellow-500: var(--p-yellow-500);
|
||||
$color-yellow-600: var(--p-yellow-600);
|
||||
$color-yellow-700: var(--p-yellow-700);
|
||||
$color-yellow-800: var(--p-yellow-800);
|
||||
$color-yellow-900: var(--p-yellow-900);
|
||||
$color-yellow-950: var(--p-yellow-950);
|
||||
|
||||
$color-teal-50: var(--p-teal-50);
|
||||
$color-teal-100: var(--p-teal-100);
|
||||
$color-teal-200: var(--p-teal-200);
|
||||
$color-teal-300: var(--p-teal-300);
|
||||
$color-teal-400: var(--p-teal-400);
|
||||
$color-teal-500: var(--p-teal-500);
|
||||
$color-teal-600: var(--p-teal-600);
|
||||
$color-teal-700: var(--p-teal-700);
|
||||
$color-teal-800: var(--p-teal-800);
|
||||
$color-teal-900: var(--p-teal-900);
|
||||
$color-teal-950: var(--p-teal-950);
|
||||
|
||||
$color-cyan-50: var(--p-cyan-50);
|
||||
$color-cyan-100: var(--p-cyan-100);
|
||||
$color-cyan-200: var(--p-cyan-200);
|
||||
$color-cyan-300: var(--p-cyan-300);
|
||||
$color-cyan-400: var(--p-cyan-400);
|
||||
$color-cyan-500: var(--p-cyan-500);
|
||||
$color-cyan-600: var(--p-cyan-600);
|
||||
$color-cyan-700: var(--p-cyan-700);
|
||||
$color-cyan-800: var(--p-cyan-800);
|
||||
$color-cyan-900: var(--p-cyan-900);
|
||||
$color-cyan-950: var(--p-cyan-950);
|
||||
|
||||
$color-sky-50: var(--p-sky-50);
|
||||
$color-sky-100: var(--p-sky-100);
|
||||
$color-sky-200: var(--p-sky-200);
|
||||
$color-sky-300: var(--p-sky-300);
|
||||
$color-sky-400: var(--p-sky-400);
|
||||
$color-sky-500: var(--p-sky-500);
|
||||
$color-sky-600: var(--p-sky-600);
|
||||
$color-sky-700: var(--p-sky-700);
|
||||
$color-sky-800: var(--p-sky-800);
|
||||
$color-sky-900: var(--p-sky-900);
|
||||
$color-sky-950: var(--p-sky-950);
|
||||
|
||||
$color-blue-50: var(--p-blue-50);
|
||||
$color-blue-100: var(--p-blue-100);
|
||||
$color-blue-200: var(--p-blue-200);
|
||||
$color-blue-300: var(--p-blue-300);
|
||||
$color-blue-400: var(--p-blue-400);
|
||||
$color-blue-500: var(--p-blue-500);
|
||||
$color-blue-600: var(--p-blue-600);
|
||||
$color-blue-700: var(--p-blue-700);
|
||||
$color-blue-800: var(--p-blue-800);
|
||||
$color-blue-900: var(--p-blue-900);
|
||||
$color-blue-950: var(--p-blue-950);
|
||||
|
||||
$color-indigo-50: var(--p-indigo-50);
|
||||
$color-indigo-100: var(--p-indigo-100);
|
||||
$color-indigo-200: var(--p-indigo-200);
|
||||
$color-indigo-300: var(--p-indigo-300);
|
||||
$color-indigo-400: var(--p-indigo-400);
|
||||
$color-indigo-500: var(--p-indigo-500);
|
||||
$color-indigo-600: var(--p-indigo-600);
|
||||
$color-indigo-700: var(--p-indigo-700);
|
||||
$color-indigo-800: var(--p-indigo-800);
|
||||
$color-indigo-900: var(--p-indigo-900);
|
||||
$color-indigo-950: var(--p-indigo-950);
|
||||
|
||||
$color-violet-50: var(--p-violet-50);
|
||||
$color-violet-100: var(--p-violet-100);
|
||||
$color-violet-200: var(--p-violet-200);
|
||||
$color-violet-300: var(--p-violet-300);
|
||||
$color-violet-400: var(--p-violet-400);
|
||||
$color-violet-500: var(--p-violet-500);
|
||||
$color-violet-600: var(--p-violet-600);
|
||||
$color-violet-700: var(--p-violet-700);
|
||||
$color-violet-800: var(--p-violet-800);
|
||||
$color-violet-900: var(--p-violet-900);
|
||||
$color-violet-950: var(--p-violet-950);
|
||||
|
||||
$color-purple-50: var(--p-purple-50);
|
||||
$color-purple-100: var(--p-purple-100);
|
||||
$color-purple-200: var(--p-purple-200);
|
||||
$color-purple-300: var(--p-purple-300);
|
||||
$color-purple-400: var(--p-purple-400);
|
||||
$color-purple-500: var(--p-purple-500);
|
||||
$color-purple-600: var(--p-purple-600);
|
||||
$color-purple-700: var(--p-purple-700);
|
||||
$color-purple-800: var(--p-purple-800);
|
||||
$color-purple-900: var(--p-purple-900);
|
||||
$color-purple-950: var(--p-purple-950);
|
||||
|
||||
$color-fuchsia-50: var(--p-fuchsia-50);
|
||||
$color-fuchsia-100: var(--p-fuchsia-100);
|
||||
$color-fuchsia-200: var(--p-fuchsia-200);
|
||||
$color-fuchsia-300: var(--p-fuchsia-300);
|
||||
$color-fuchsia-400: var(--p-fuchsia-400);
|
||||
$color-fuchsia-500: var(--p-fuchsia-500);
|
||||
$color-fuchsia-600: var(--p-fuchsia-600);
|
||||
$color-fuchsia-700: var(--p-fuchsia-700);
|
||||
$color-fuchsia-800: var(--p-fuchsia-800);
|
||||
$color-fuchsia-900: var(--p-fuchsia-900);
|
||||
$color-fuchsia-950: var(--p-fuchsia-950);
|
||||
|
||||
$color-pink-50: var(--p-pink-50);
|
||||
$color-pink-100: var(--p-pink-100);
|
||||
$color-pink-200: var(--p-pink-200);
|
||||
$color-pink-300: var(--p-pink-300);
|
||||
$color-pink-400: var(--p-pink-400);
|
||||
$color-pink-500: var(--p-pink-500);
|
||||
$color-pink-600: var(--p-pink-600);
|
||||
$color-pink-700: var(--p-pink-700);
|
||||
$color-pink-800: var(--p-pink-800);
|
||||
$color-pink-900: var(--p-pink-900);
|
||||
$color-pink-950: var(--p-pink-950);
|
||||
|
||||
$color-rose-50: var(--p-rose-50);
|
||||
$color-rose-100: var(--p-rose-100);
|
||||
$color-rose-200: var(--p-rose-200);
|
||||
$color-rose-300: var(--p-rose-300);
|
||||
$color-rose-400: var(--p-rose-400);
|
||||
$color-rose-500: var(--p-rose-500);
|
||||
$color-rose-600: var(--p-rose-600);
|
||||
$color-rose-700: var(--p-rose-700);
|
||||
$color-rose-800: var(--p-rose-800);
|
||||
$color-rose-900: var(--p-rose-900);
|
||||
$color-rose-950: var(--p-rose-950);
|
||||
|
||||
$color-slate-50: var(--p-slate-50);
|
||||
$color-slate-100: var(--p-slate-100);
|
||||
$color-slate-200: var(--p-slate-200);
|
||||
$color-slate-300: var(--p-slate-300);
|
||||
$color-slate-400: var(--p-slate-400);
|
||||
$color-slate-500: var(--p-slate-500);
|
||||
$color-slate-600: var(--p-slate-600);
|
||||
$color-slate-700: var(--p-slate-700);
|
||||
$color-slate-800: var(--p-slate-800);
|
||||
$color-slate-900: var(--p-slate-900);
|
||||
$color-slate-950: var(--p-slate-950);
|
||||
|
||||
$color-gray-50: var(--p-gray-50);
|
||||
$color-gray-100: var(--p-gray-100);
|
||||
$color-gray-200: var(--p-gray-200);
|
||||
$color-gray-300: var(--p-gray-300);
|
||||
$color-gray-400: var(--p-gray-400);
|
||||
$color-gray-500: var(--p-gray-500);
|
||||
$color-gray-600: var(--p-gray-600);
|
||||
$color-gray-700: var(--p-gray-700);
|
||||
$color-gray-800: var(--p-gray-800);
|
||||
$color-gray-900: var(--p-gray-900);
|
||||
$color-gray-950: var(--p-gray-950);
|
||||
|
||||
$color-zinc-50: var(--p-zinc-50);
|
||||
$color-zinc-100: var(--p-zinc-100);
|
||||
$color-zinc-200: var(--p-zinc-200);
|
||||
$color-zinc-300: var(--p-zinc-300);
|
||||
$color-zinc-400: var(--p-zinc-400);
|
||||
$color-zinc-500: var(--p-zinc-500);
|
||||
$color-zinc-600: var(--p-zinc-600);
|
||||
$color-zinc-700: var(--p-zinc-700);
|
||||
$color-zinc-800: var(--p-zinc-800);
|
||||
$color-zinc-900: var(--p-zinc-900);
|
||||
$color-zinc-950: var(--p-zinc-950);
|
||||
|
||||
$color-neutral-50: var(--p-neutral-50);
|
||||
$color-neutral-100: var(--p-neutral-100);
|
||||
$color-neutral-200: var(--p-neutral-200);
|
||||
$color-neutral-300: var(--p-neutral-300);
|
||||
$color-neutral-400: var(--p-neutral-400);
|
||||
$color-neutral-500: var(--p-neutral-500);
|
||||
$color-neutral-600: var(--p-neutral-600);
|
||||
$color-neutral-700: var(--p-neutral-700);
|
||||
$color-neutral-800: var(--p-neutral-800);
|
||||
$color-neutral-900: var(--p-neutral-900);
|
||||
$color-neutral-950: var(--p-neutral-950);
|
||||
|
||||
$color-stone-50: var(--p-stone-50);
|
||||
$color-stone-100: var(--p-stone-100);
|
||||
$color-stone-200: var(--p-stone-200);
|
||||
$color-stone-300: var(--p-stone-300);
|
||||
$color-stone-400: var(--p-stone-400);
|
||||
$color-stone-500: var(--p-stone-500);
|
||||
$color-stone-600: var(--p-stone-600);
|
||||
$color-stone-700: var(--p-stone-700);
|
||||
$color-stone-800: var(--p-stone-800);
|
||||
$color-stone-900: var(--p-stone-900);
|
||||
$color-stone-950: var(--p-stone-950);
|
||||
28
src/ModManUi/src/style/_colors_semantic.scss
Normal file
28
src/ModManUi/src/style/_colors_semantic.scss
Normal file
@@ -0,0 +1,28 @@
|
||||
// Semantic colors are colors that may be different depending on the context.
|
||||
// They have to be used via CSS variables (which is what the SASS variables access).
|
||||
$color-surface-0: var(--color-surface-0);
|
||||
$color-surface-50: var(--color-surface-50);
|
||||
$color-surface-100: var(--color-surface-100);
|
||||
$color-surface-200: var(--color-surface-200);
|
||||
$color-surface-300: var(--color-surface-300);
|
||||
$color-surface-400: var(--color-surface-400);
|
||||
$color-surface-500: var(--color-surface-500);
|
||||
$color-surface-600: var(--color-surface-600);
|
||||
$color-surface-700: var(--color-surface-700);
|
||||
$color-surface-800: var(--color-surface-800);
|
||||
$color-surface-900: var(--color-surface-900);
|
||||
$color-surface-950: var(--color-surface-950);
|
||||
|
||||
$color-primary: var(--color-primary);
|
||||
$color-primary-contrast: var(--color-primary-contrast);
|
||||
$color-primary-hover: var(--color-primary-hover);
|
||||
$color-primary-active: var(--color-primary-active);
|
||||
|
||||
$color-content-background: var(--color-content-background);
|
||||
$color-content-hover-background: var(--color-content-hover-background);
|
||||
$color-content-border: var(--color-content-border);
|
||||
|
||||
$color-text: var(--color-text);
|
||||
$color-text-hover: var(--color-text-hover);
|
||||
$color-text-muted: var(--color-text-muted);
|
||||
$color-text-hover-muted: var(--color-text-hover-muted);
|
||||
7
src/ModManUi/src/style/_variables.scss
Normal file
7
src/ModManUi/src/style/_variables.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
$border-radius-xs: 0.125rem;
|
||||
$border-radius-sm: 0.25rem;
|
||||
$border-radius-md: 0.375rem;
|
||||
$border-radius-lg: 0.5rem;
|
||||
$border-radius-xl: 0.75rem;
|
||||
|
||||
$transition-duration: 0.2s;
|
||||
68
src/ModManUi/src/style/css_vars.scss
Normal file
68
src/ModManUi/src/style/css_vars.scss
Normal file
@@ -0,0 +1,68 @@
|
||||
@use "colors";
|
||||
@use "colors_primitive";
|
||||
@use "sass:meta";
|
||||
@use "sass:string";
|
||||
|
||||
:root {
|
||||
@each $name, $value in meta.module-variables(colors_primitive) {
|
||||
--#{string.to-lower-case($name)}: #{$value};
|
||||
}
|
||||
}
|
||||
|
||||
:root:not(.dark) {
|
||||
--color-surface-0: #ffffff;
|
||||
--color-surface-50: #{colors.$color-slate-50};
|
||||
--color-surface-100: #{colors.$color-slate-100};
|
||||
--color-surface-200: #{colors.$color-slate-200};
|
||||
--color-surface-300: #{colors.$color-slate-300};
|
||||
--color-surface-400: #{colors.$color-slate-400};
|
||||
--color-surface-500: #{colors.$color-slate-500};
|
||||
--color-surface-600: #{colors.$color-slate-600};
|
||||
--color-surface-700: #{colors.$color-slate-700};
|
||||
--color-surface-800: #{colors.$color-slate-800};
|
||||
--color-surface-900: #{colors.$color-slate-900};
|
||||
--color-surface-950: #{colors.$color-slate-950};
|
||||
|
||||
--color-primary: #{colors.$color-brand-500};
|
||||
--color-primary-contrast: #ffffff;
|
||||
--color-primary-hover: var(--color-brand-600);
|
||||
--color-primary-active: var(--color-brand-700);
|
||||
|
||||
--color-content-background: var(--color-surface-0);
|
||||
--color-content-hover-background: var(--color-surface-100);
|
||||
--color-content-border: var(--color-surface-200);
|
||||
|
||||
--color-text: var(--color-surface-700);
|
||||
--color-text-hover: var(--color-surface-800);
|
||||
--color-text-muted: var(--color-surface-500);
|
||||
--color-text-hover-muted: var(--color-surface-600);
|
||||
}
|
||||
|
||||
:root.dark {
|
||||
--color-surface-0: #ffffff;
|
||||
--color-surface-50: #{colors.$color-zinc-50};
|
||||
--color-surface-100: #{colors.$color-zinc-100};
|
||||
--color-surface-200: #{colors.$color-zinc-200};
|
||||
--color-surface-300: #{colors.$color-zinc-300};
|
||||
--color-surface-400: #{colors.$color-zinc-400};
|
||||
--color-surface-500: #{colors.$color-zinc-500};
|
||||
--color-surface-600: #{colors.$color-zinc-600};
|
||||
--color-surface-700: #{colors.$color-zinc-700};
|
||||
--color-surface-800: #{colors.$color-zinc-800};
|
||||
--color-surface-900: #{colors.$color-zinc-900};
|
||||
--color-surface-950: #{colors.$color-zinc-950};
|
||||
|
||||
--color-primary: #{colors.$color-brand-400};
|
||||
--color-primary-contrast: var(--color-surface-900);
|
||||
--color-primary-hover: var(--color-brand-300);
|
||||
--color-primary-active: var(--color-brand-200);
|
||||
|
||||
--color-content-background: var(--color-surface-900);
|
||||
--color-content-hover-background: var(--color-surface-800);
|
||||
--color-content-border: var(--color-surface-700);
|
||||
|
||||
--color-text: var(--color-surface-0);
|
||||
--color-text-hover: var(--color-surface-0);
|
||||
--color-text-muted: var(--color-surface-400);
|
||||
--color-text-hover-muted: var(--color-surface-300);
|
||||
}
|
||||
36
src/ModManUi/src/style/main.scss
Normal file
36
src/ModManUi/src/style/main.scss
Normal file
@@ -0,0 +1,36 @@
|
||||
@use "colors";
|
||||
@use "css_vars";
|
||||
@use "utils.scss";
|
||||
|
||||
@import "@fontsource/inter/latin-300.css";
|
||||
@import "@fontsource/inter/latin-300-italic.css";
|
||||
@import "@fontsource/inter/latin-400.css";
|
||||
@import "@fontsource/inter/latin-400-italic.css";
|
||||
@import "@fontsource/inter/latin-600.css";
|
||||
@import "@fontsource/inter/latin-600-italic.css";
|
||||
@import "@fontsource/inter/latin-700.css";
|
||||
@import "@fontsource/inter/latin-700-italic.css";
|
||||
|
||||
:root {
|
||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 400;
|
||||
|
||||
color: colors.$color-text;
|
||||
background-color: colors.$color-content-background;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
3
src/ModManUi/src/style/utils.scss
Normal file
3
src/ModManUi/src/style/utils.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.icon {
|
||||
height: 1lh;
|
||||
}
|
||||
85
src/ModManUi/src/utils/AssetTypeName.ts
Normal file
85
src/ModManUi/src/utils/AssetTypeName.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { CommonAssetType } from "@/native/AssetBinds";
|
||||
|
||||
const LOOKUP_CAPITALIZED: Record<CommonAssetType, string> = {
|
||||
[CommonAssetType.PHYS_PRESET]: "Phys preset",
|
||||
[CommonAssetType.XANIM]: "XAnim",
|
||||
[CommonAssetType.XMODEL]: "XModel",
|
||||
[CommonAssetType.MATERIAL]: "Material",
|
||||
[CommonAssetType.TECHNIQUE_SET]: "Technique set",
|
||||
[CommonAssetType.IMAGE]: "Image",
|
||||
[CommonAssetType.SOUND]: "Sound",
|
||||
[CommonAssetType.SOUND_CURVE]: "Sound curve",
|
||||
[CommonAssetType.LOADED_SOUND]: "Loaded sound",
|
||||
[CommonAssetType.CLIP_MAP]: "Clip map",
|
||||
[CommonAssetType.COM_WORLD]: "Com world",
|
||||
[CommonAssetType.GAME_WORLD_SP]: "Game world SP",
|
||||
[CommonAssetType.GAME_WORLD_MP]: "Game world MP",
|
||||
[CommonAssetType.MAP_ENTS]: "Map ents",
|
||||
[CommonAssetType.GFX_WORLD]: "Gfx world",
|
||||
[CommonAssetType.LIGHT_DEF]: "Light def",
|
||||
[CommonAssetType.UI_MAP]: "UI map",
|
||||
[CommonAssetType.FONT]: "Font",
|
||||
[CommonAssetType.MENU_LIST]: "Menu list",
|
||||
[CommonAssetType.MENU]: "Menu",
|
||||
[CommonAssetType.LOCALIZE_ENTRY]: "Localize entry",
|
||||
[CommonAssetType.WEAPON]: "Weapon",
|
||||
[CommonAssetType.SOUND_DRIVER_GLOBALS]: "Sound driver globals",
|
||||
[CommonAssetType.FX]: "FX",
|
||||
[CommonAssetType.IMPACT_FX]: "Impact FX",
|
||||
[CommonAssetType.AI_TYPE]: "AI type",
|
||||
[CommonAssetType.MP_TYPE]: "MP type",
|
||||
[CommonAssetType.CHARACTER]: "Character",
|
||||
[CommonAssetType.XMODEL_ALIAS]: "XModel alias",
|
||||
[CommonAssetType.RAW_FILE]: "Raw file",
|
||||
[CommonAssetType.STRING_TABLE]: "String table",
|
||||
[CommonAssetType.XMODEL_PIECES]: "XModel pieces",
|
||||
[CommonAssetType.PHYS_COLL_MAP]: "Phys coll map",
|
||||
[CommonAssetType.XMODEL_SURFS]: "XModel surfs",
|
||||
[CommonAssetType.PIXEL_SHADER]: "Pixel shader",
|
||||
[CommonAssetType.VERTEX_SHADER]: "Vertex shader",
|
||||
[CommonAssetType.VERTEX_DECL]: "Vertex decl",
|
||||
[CommonAssetType.FX_WORLD]: "FX world",
|
||||
[CommonAssetType.LEADERBOARD]: "Leaderboard",
|
||||
[CommonAssetType.STRUCTURED_DATA_DEF]: "Structured data def",
|
||||
[CommonAssetType.TRACER]: "Tracer",
|
||||
[CommonAssetType.VEHICLE]: "Vehicle",
|
||||
[CommonAssetType.ADDON_MAP_ENTS]: "Addon map ents",
|
||||
[CommonAssetType.GLASS_WORLD]: "Glass world",
|
||||
[CommonAssetType.PATH_DATA]: "Path data",
|
||||
[CommonAssetType.VEHICLE_TRACK]: "Vehicle track",
|
||||
[CommonAssetType.ATTACHMENT]: "Attachment",
|
||||
[CommonAssetType.SURFACE_FX]: "Surface FX",
|
||||
[CommonAssetType.SCRIPT]: "Script",
|
||||
[CommonAssetType.PHYS_CONSTRAINTS]: "Phys constraints",
|
||||
[CommonAssetType.DESTRUCTIBLE_DEF]: "Destructible def",
|
||||
[CommonAssetType.SOUND_PATCH]: "Sound patch",
|
||||
[CommonAssetType.WEAPON_DEF]: "Weapon def",
|
||||
[CommonAssetType.WEAPON_VARIANT]: "Weapon variant",
|
||||
[CommonAssetType.MP_BODY]: "MP body",
|
||||
[CommonAssetType.MP_HEAD]: "MP head",
|
||||
[CommonAssetType.PACK_INDEX]: "Pack index",
|
||||
[CommonAssetType.XGLOBALS]: "XGlobals",
|
||||
[CommonAssetType.DDL]: "DDL",
|
||||
[CommonAssetType.GLASSES]: "Glasses",
|
||||
[CommonAssetType.EMBLEM_SET]: "Emblem set",
|
||||
[CommonAssetType.FONT_ICON]: "Font icon",
|
||||
[CommonAssetType.WEAPON_FULL]: "Weapon full",
|
||||
[CommonAssetType.ATTACHMENT_UNIQUE]: "Attachment unique",
|
||||
[CommonAssetType.WEAPON_CAMO]: "Weapon camo",
|
||||
[CommonAssetType.KEY_VALUE_PAIRS]: "Key value pairs",
|
||||
[CommonAssetType.MEMORY_BLOCK]: "Memory block",
|
||||
[CommonAssetType.SKINNED_VERTS]: "Skinned verts",
|
||||
[CommonAssetType.QDB]: "Qdb",
|
||||
[CommonAssetType.SLUG]: "Slug",
|
||||
[CommonAssetType.FOOTSTEP_TABLE]: "Footstep table",
|
||||
[CommonAssetType.FOOTSTEP_FX_TABLE]: "Footstep FX table",
|
||||
[CommonAssetType.ZBARRIER]: "ZBarrier",
|
||||
};
|
||||
|
||||
export function getAssetTypeNameCapitalized(assetType: CommonAssetType): string {
|
||||
return LOOKUP_CAPITALIZED[assetType];
|
||||
}
|
||||
|
||||
export function getAssetTypeNameLower(assetType: CommonAssetType): string {
|
||||
return getAssetTypeNameCapitalized(assetType).toLocaleLowerCase();
|
||||
}
|
||||
52
src/ModManUi/src/view/inspect/ZoneInspector.vue
Normal file
52
src/ModManUi/src/view/inspect/ZoneInspector.vue
Normal file
@@ -0,0 +1,52 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { useZoneStore } from "@/stores/ZoneStore";
|
||||
import ZoneInspectorDetails from "./ZoneInspectorDetails.vue";
|
||||
import ZoneInspectorZoneList from "./ZoneInspectorZoneList.vue";
|
||||
import { useAssetStore } from "@/stores/AssetStore";
|
||||
|
||||
const assetStore = useAssetStore();
|
||||
const zoneStore = useZoneStore();
|
||||
|
||||
const selectedZone = ref<string | null>(null);
|
||||
|
||||
// Make sure we preselect the zone that was last loaded assets for
|
||||
// if there is one
|
||||
if (
|
||||
assetStore.zoneName &&
|
||||
zoneStore.loadedZones.findIndex((zone) => zone.name === assetStore.zoneName) >= 0
|
||||
) {
|
||||
selectedZone.value = assetStore.zoneName;
|
||||
}
|
||||
|
||||
watch(
|
||||
() => zoneStore.loadedZones,
|
||||
(newValue) => {
|
||||
// Reset selection if unloaded
|
||||
if (!selectedZone.value) return;
|
||||
if (newValue.findIndex((loadedZone) => loadedZone.name === selectedZone.value) >= 0) return;
|
||||
selectedZone.value = null;
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="zone-inspector">
|
||||
<ZoneInspectorZoneList v-model:selected-zone="selectedZone" />
|
||||
<ZoneInspectorDetails :selected-zone="selectedZone" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.zone-inspector {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
|
||||
& > * {
|
||||
width: 50%;
|
||||
padding: 1rem 2rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
151
src/ModManUi/src/view/inspect/ZoneInspectorDetails.vue
Normal file
151
src/ModManUi/src/view/inspect/ZoneInspectorDetails.vue
Normal file
@@ -0,0 +1,151 @@
|
||||
<script setup lang="ts">
|
||||
import Button from "primevue/button";
|
||||
import Tag from "primevue/tag";
|
||||
import MeterGroup, { type MeterItem } from "primevue/metergroup";
|
||||
import Skeleton from "primevue/skeleton";
|
||||
import { dt } from "@primeuix/themes";
|
||||
import type { ZoneDto } from "@/native/ZoneBinds";
|
||||
import { useZoneStore } from "@/stores/ZoneStore";
|
||||
import { computed, watch } from "vue";
|
||||
import type { CommonAssetType } from "@/native/AssetBinds";
|
||||
import { getAssetTypeNameCapitalized } from "@/utils/AssetTypeName";
|
||||
import { useRouter } from "vue-router";
|
||||
import { PAGE } from "@/router/Page";
|
||||
import { useAssetStore } from "@/stores/AssetStore";
|
||||
import { storeToRefs } from "pinia";
|
||||
|
||||
const assetStore = useAssetStore();
|
||||
const zoneStore = useZoneStore();
|
||||
|
||||
const { assetsOfZone, assetCount, referenceCount } = storeToRefs(assetStore);
|
||||
|
||||
const props = defineProps<{
|
||||
selectedZone: string | null;
|
||||
}>();
|
||||
|
||||
const METER_COLORS = [
|
||||
dt("blue.600"),
|
||||
dt("red.600"),
|
||||
dt("yellow.600"),
|
||||
dt("green.600"),
|
||||
dt("purple.600"),
|
||||
dt("orange.600"),
|
||||
dt("teal.600"),
|
||||
dt("lime.600"),
|
||||
dt("pink.600"),
|
||||
];
|
||||
const meterItems = computed<MeterItem[]>(() => {
|
||||
const assetTypeCounts: Partial<Record<CommonAssetType, number>> = {};
|
||||
|
||||
for (const asset of assetsOfZone.value?.assets ?? []) {
|
||||
if (!assetTypeCounts[asset.type]) {
|
||||
assetTypeCounts[asset.type] = 1;
|
||||
} else {
|
||||
assetTypeCounts[asset.type]!++;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not display asset types with under 3 percent representation
|
||||
const minItemCountForDisplay = Math.floor(assetCount.value * 0.03);
|
||||
|
||||
const assetMeterItems: MeterItem[] = Object.entries(assetTypeCounts)
|
||||
.filter((entry) => entry[1] > minItemCountForDisplay)
|
||||
.sort((e0, e1) => e1[1] - e0[1])
|
||||
.map((entry) => ({
|
||||
label: getAssetTypeNameCapitalized(entry[0] as CommonAssetType),
|
||||
value: Math.round((entry[1] / assetCount.value) * 100),
|
||||
}));
|
||||
|
||||
// Since the PrimeVue component rounds to percent we want to fill up the bar completely
|
||||
const otherCount = 100 - assetMeterItems.reduce((val, entry) => val + entry.value, 0);
|
||||
|
||||
if (otherCount > 0) {
|
||||
assetMeterItems.push({
|
||||
label: "Other",
|
||||
value: otherCount,
|
||||
});
|
||||
}
|
||||
|
||||
return assetMeterItems.map(
|
||||
(item, index) =>
|
||||
({
|
||||
...item,
|
||||
color: METER_COLORS[index % METER_COLORS.length],
|
||||
}) satisfies MeterItem,
|
||||
);
|
||||
});
|
||||
|
||||
const selectedZoneDetails = computed<ZoneDto | null>(() =>
|
||||
props.selectedZone ? zoneStore.getLoadedZoneByName(props.selectedZone) : null,
|
||||
);
|
||||
|
||||
const router = useRouter();
|
||||
function onClickShowAssets() {
|
||||
if (!props.selectedZone) return;
|
||||
|
||||
router.push({
|
||||
name: PAGE.INSPECT.ZONE_DETAILS,
|
||||
params: {
|
||||
zoneName: props.selectedZone,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.selectedZone,
|
||||
(newValue) => {
|
||||
assetStore.loadAssetsForZone(newValue);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="zone-details">
|
||||
<h2>{{ selectedZone ?? "No zone selected" }}</h2>
|
||||
<Button label="Show assets" :disabled="!selectedZone" @click="onClickShowAssets" />
|
||||
<div v-if="selectedZoneDetails" class="zone-tags">
|
||||
<Tag :value="selectedZoneDetails.game" />
|
||||
<Tag :value="selectedZoneDetails.platform" />
|
||||
</div>
|
||||
<div class="zone-assets">
|
||||
<template v-if="assetsOfZone">
|
||||
<div>{{ assetCount }} assets</div>
|
||||
<div>{{ referenceCount }} references</div>
|
||||
<MeterGroup class="asset-meter" :value="meterItems" />
|
||||
</template>
|
||||
<template v-else-if="selectedZone">
|
||||
<Skeleton class="count-skeleton" width="10em" />
|
||||
<Skeleton class="count-skeleton" width="10em" />
|
||||
<Skeleton class="count-skeleton" height="0.5lh" />
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.zone-tags {
|
||||
display: flex;
|
||||
margin-top: 0.5em;
|
||||
column-gap: 0.5em;
|
||||
row-gap: 0.5em;
|
||||
}
|
||||
|
||||
.zone-assets {
|
||||
margin-top: 0.5em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.asset-meter {
|
||||
padding-top: 0.5em;
|
||||
font-size: 0.8em;
|
||||
line-height: 1.25;
|
||||
--p-metergroup-gap: 1em;
|
||||
--p-metergroup-label-list-horizontal-gap: 0.8em;
|
||||
}
|
||||
|
||||
.count-skeleton {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
</style>
|
||||
111
src/ModManUi/src/view/inspect/ZoneInspectorZoneList.vue
Normal file
111
src/ModManUi/src/view/inspect/ZoneInspectorZoneList.vue
Normal file
@@ -0,0 +1,111 @@
|
||||
<script setup lang="ts">
|
||||
import Button from "primevue/button";
|
||||
import ProgressBar from "primevue/progressbar";
|
||||
import Listbox from "primevue/listbox";
|
||||
import { computed } from "vue";
|
||||
import { useZoneStore } from "@/stores/ZoneStore";
|
||||
import { webviewBinds } from "@/native";
|
||||
|
||||
interface SelectableZone {
|
||||
isLoading: boolean;
|
||||
zoneName: string;
|
||||
}
|
||||
|
||||
const zoneStore = useZoneStore();
|
||||
const selectedZone = defineModel<string | null>("selectedZone");
|
||||
|
||||
async function openFastFileSelect() {
|
||||
return await webviewBinds.openFileDialog({ filters: [{ name: "Fastfiles", filter: "*.ff" }] });
|
||||
}
|
||||
|
||||
async function onOpenFastFileClick() {
|
||||
const fastFilePath = await openFastFileSelect();
|
||||
if (!fastFilePath) return;
|
||||
|
||||
zoneStore.loadFastFile(fastFilePath);
|
||||
}
|
||||
|
||||
const availableZones = computed<SelectableZone[]>(() => {
|
||||
const result = [
|
||||
...zoneStore.zonesCurrentlyBeingLoaded.map(
|
||||
(zoneBeingLoaded) =>
|
||||
({
|
||||
isLoading: true,
|
||||
zoneName: zoneBeingLoaded,
|
||||
}) satisfies SelectableZone,
|
||||
),
|
||||
...zoneStore.loadedZones.map(
|
||||
(loadedZone) =>
|
||||
({
|
||||
isLoading: false,
|
||||
zoneName: loadedZone.name,
|
||||
}) satisfies SelectableZone,
|
||||
),
|
||||
];
|
||||
|
||||
result.sort((a, b) => a.zoneName.localeCompare(b.zoneName));
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
function onUnloadClicked() {
|
||||
if (!selectedZone.value) return;
|
||||
|
||||
webviewBinds.unloadZone(selectedZone.value).catch((e: string) => {
|
||||
console.error("Failed to unload zone:", e);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="zone-list">
|
||||
<div class="zone-list-actions">
|
||||
<Button label="Load fastfile" @click="onOpenFastFileClick" />
|
||||
<Button label="Unload" :disabled="!selectedZone" @click="onUnloadClicked" />
|
||||
</div>
|
||||
<Listbox
|
||||
v-model="selectedZone"
|
||||
:options="availableZones"
|
||||
option-disabled="isLoading"
|
||||
option-value="zoneName"
|
||||
data-key="zoneName"
|
||||
emptyMessage="No zones loaded"
|
||||
class="zone"
|
||||
>
|
||||
<template #option="{ option }: { option: SelectableZone }">
|
||||
<div class="selectable-zone">
|
||||
<span>{{ option.zoneName }}</span>
|
||||
<ProgressBar
|
||||
v-if="option.isLoading"
|
||||
class="zone-progressbar"
|
||||
:value="zoneStore.getPercentageForZoneBeingLoaded(option.zoneName)"
|
||||
:show-value="false"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</Listbox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.zone-list-actions {
|
||||
display: flex;
|
||||
column-gap: 0.25em;
|
||||
row-gap: 0.25em;
|
||||
padding: 0.25em 0;
|
||||
}
|
||||
|
||||
.selectable-zone {
|
||||
position: relative;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.zone-progressbar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 0.2em;
|
||||
}
|
||||
</style>
|
||||
87
src/ModManUi/src/view/inspect_details/InspectDetails.vue
Normal file
87
src/ModManUi/src/view/inspect_details/InspectDetails.vue
Normal file
@@ -0,0 +1,87 @@
|
||||
<script setup lang="ts">
|
||||
import Skeleton from "primevue/skeleton";
|
||||
import { useAssetStore } from "@/stores/AssetStore";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { ref, watch } from "vue";
|
||||
import InspectPreview from "./components/InspectPreview.vue";
|
||||
import InspectAssetDetails from "./components/InspectAssetDetails.vue";
|
||||
import InspectZoneAssets from "./components/InspectZoneAssets.vue";
|
||||
import type { AssetDto } from "@/native/AssetBinds.ts";
|
||||
|
||||
const assetStore = useAssetStore();
|
||||
|
||||
const { assetsOfZone } = storeToRefs(assetStore);
|
||||
|
||||
const props = defineProps<{
|
||||
zoneName: string;
|
||||
}>();
|
||||
|
||||
const selectedAsset = ref<AssetDto | null>(null);
|
||||
|
||||
watch(
|
||||
() => props.zoneName,
|
||||
(newValue) => {
|
||||
assetStore.loadAssetsForZone(newValue);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="inspect-details">
|
||||
<template v-if="assetsOfZone">
|
||||
<InspectPreview class="inspect-area-preview" />
|
||||
<InspectAssetDetails :selected-asset="selectedAsset" class="inspect-area-details" />
|
||||
<InspectZoneAssets
|
||||
v-model:selected-asset="selectedAsset"
|
||||
:assets="assetsOfZone.assets"
|
||||
class="inspect-area-assets"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="skeleton-wrapper">
|
||||
<Skeleton class="count-skeleton" width="100%" height="100%" />
|
||||
</div>
|
||||
<div class="skeleton-wrapper">
|
||||
<Skeleton class="count-skeleton" width="100%" height="100%" />
|
||||
</div>
|
||||
<div class="skeleton-wrapper list">
|
||||
<Skeleton v-for="i in 3" :key="i" class="count-skeleton" width="80%" height="1em" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.inspect-details {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 30% 1fr;
|
||||
grid-template-rows: 30% 1fr;
|
||||
grid-template-areas:
|
||||
"preview details"
|
||||
"assets details";
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.inspect-area-preview {
|
||||
grid-area: preview;
|
||||
}
|
||||
|
||||
.inspect-area-details {
|
||||
grid-area: details;
|
||||
}
|
||||
|
||||
.inspect-area-assets {
|
||||
grid-area: assets;
|
||||
}
|
||||
|
||||
.skeleton-wrapper {
|
||||
&.list > *:not(:first-child) {
|
||||
margin-top: calc(1lh - 1em);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,31 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import type { ZoneDto } from "@/native/ZoneBinds.ts";
|
||||
import { useZoneStore } from "@/stores/ZoneStore.ts";
|
||||
import Tag from "primevue/tag";
|
||||
|
||||
const zoneStore = useZoneStore();
|
||||
const props = defineProps<{
|
||||
zoneName: string;
|
||||
}>();
|
||||
|
||||
const zoneDetails = computed<ZoneDto | null>(() =>
|
||||
props.zoneName ? zoneStore.getLoadedZoneByName(props.zoneName) : null,
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span>
|
||||
<span>Inspect zone: {{ zoneName }}</span>
|
||||
<template v-if="zoneDetails">
|
||||
<Tag class="zone-header-tag" :value="zoneDetails.game" severity="secondary" />
|
||||
<Tag class="zone-header-tag" :value="zoneDetails.platform" severity="secondary" />
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.zone-header-tag {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import type { AssetDto } from "@/native/AssetBinds.ts";
|
||||
import { getAssetTypeNameCapitalized } from "@/utils/AssetTypeName.ts";
|
||||
|
||||
defineProps<{
|
||||
asset: AssetDto;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="asset-option">
|
||||
<span class="asset-type">{{ getAssetTypeNameCapitalized(asset.type) }}</span>
|
||||
<span class="asset-name">{{ asset.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@style/colors";
|
||||
|
||||
.asset-option {
|
||||
font-size: 0.95rem;
|
||||
max-width: 100%;
|
||||
overflow-x: clip;
|
||||
white-space: nowrap;
|
||||
padding: 0 0.2em;
|
||||
}
|
||||
|
||||
.asset-type {
|
||||
display: inline-block;
|
||||
color: colors.$color-text-muted;
|
||||
min-width: 8em;
|
||||
}
|
||||
|
||||
.asset-name {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
import type { AssetDto } from "@/native/AssetBinds.ts";
|
||||
import Tag from "primevue/tag";
|
||||
import { getAssetTypeNameCapitalized } from "@/utils/AssetTypeName.ts";
|
||||
import { computed } from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
selectedAsset: AssetDto | null;
|
||||
}>();
|
||||
|
||||
const assetTypeName = computed(() =>
|
||||
props.selectedAsset ? getAssetTypeNameCapitalized(props.selectedAsset.type) : "",
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="selectedAsset">
|
||||
<h2 class="asset-header">
|
||||
<span>{{ selectedAsset.name }}</span>
|
||||
<Tag class="asset-type" :value="assetTypeName" />
|
||||
</h2>
|
||||
<div>No details available</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div>No asset selected</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.asset-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 0 0.5em 0;
|
||||
}
|
||||
|
||||
.asset-type {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,23 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<div class="preview">
|
||||
<span>No preview available</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use "@style/colors";
|
||||
@use "@style/variables";
|
||||
|
||||
.preview {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
background-color: colors.$color-content-hover-background;
|
||||
border-radius: variables.$border-radius-md;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,44 @@
|
||||
<script setup lang="ts">
|
||||
import Listbox from "primevue/listbox";
|
||||
import type { AssetDto } from "@/native/AssetBinds.ts";
|
||||
import AssetListOption from "@/view/inspect_details/components/AssetListOption.vue";
|
||||
|
||||
const selectedAsset = defineModel<AssetDto | null>("selectedAsset");
|
||||
defineProps<{
|
||||
assets: AssetDto[];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Listbox
|
||||
v-model="selectedAsset"
|
||||
class="asset-list"
|
||||
:options="assets"
|
||||
option-label="name"
|
||||
scroll-height="100%"
|
||||
:virtual-scroller-options="{ itemSize: 24 }"
|
||||
>
|
||||
<template #option="{ option }: { option: AssetDto }">
|
||||
<AssetListOption :asset="option" />
|
||||
</template>
|
||||
</Listbox>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.asset-list {
|
||||
--p-listbox-option-padding: 0;
|
||||
}
|
||||
|
||||
:deep(.p-virtualscroller) {
|
||||
overflow-x: hidden;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
:deep(.p-listbox-list) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
:deep(.p-listbox-list-container) {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -6,7 +6,8 @@
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
"@/*": ["./src/*"],
|
||||
"@style/*": ["./src/style/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import headerTransformationPlugin from "./build/HeaderTransformationPlugin";
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
build: {
|
||||
copyPublicDir: false,
|
||||
emptyOutDir: true,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
@@ -18,6 +17,7 @@ export default defineConfig({
|
||||
},
|
||||
},
|
||||
},
|
||||
publicDir: fileURLToPath(new URL("./public", import.meta.url)),
|
||||
plugins: [
|
||||
vue(),
|
||||
vueDevTools(),
|
||||
@@ -30,6 +30,7 @@ export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": fileURLToPath(new URL("./src", import.meta.url)),
|
||||
"@style": fileURLToPath(new URL("./src/style", import.meta.url)),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -98,6 +98,11 @@ bool XAssetInfoGeneric::IsReference() const
|
||||
return !m_name.empty() && m_name[0] == ',';
|
||||
}
|
||||
|
||||
std::string XAssetInfoGeneric::ReferencedAssetName() const
|
||||
{
|
||||
return m_name.substr(1);
|
||||
}
|
||||
|
||||
std::string XAssetInfoGeneric::NormalizeAssetName(std::string input)
|
||||
{
|
||||
utils::MakeStringLowerCase(input);
|
||||
|
||||
@@ -55,6 +55,7 @@ public:
|
||||
XAssetInfoGeneric& operator=(XAssetInfoGeneric&& other) noexcept = default;
|
||||
|
||||
[[nodiscard]] bool IsReference() const;
|
||||
[[nodiscard]] std::string ReferencedAssetName() const;
|
||||
|
||||
static std::string NormalizeAssetName(std::string input);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "Utils/ClassUtils.h"
|
||||
|
||||
#include "XAssetInfo.h"
|
||||
#include "Zone/Zone.h"
|
||||
#include "Zone/ZoneTypes.h"
|
||||
@@ -33,16 +33,16 @@ public:
|
||||
std::vector<XAssetInfoGeneric*> dependencies,
|
||||
std::vector<scr_string_t> usedScriptStrings,
|
||||
std::vector<IndirectAssetReference> indirectAssetReferences);
|
||||
_NODISCARD virtual XAssetInfoGeneric* GetAsset(asset_type_t type, const std::string& name) const = 0;
|
||||
_NODISCARD virtual XAssetInfoGeneric* GetAssetOrAssetReference(asset_type_t type, const std::string& name) const;
|
||||
[[nodiscard]] virtual XAssetInfoGeneric* GetAsset(asset_type_t type, const std::string& name) const = 0;
|
||||
[[nodiscard]] virtual XAssetInfoGeneric* GetAssetOrAssetReference(asset_type_t type, const std::string& name) const;
|
||||
|
||||
_NODISCARD virtual asset_type_t GetAssetTypeCount() const = 0;
|
||||
_NODISCARD virtual std::optional<const char*> GetAssetTypeName(asset_type_t assetType) const = 0;
|
||||
[[nodiscard]] virtual asset_type_t GetAssetTypeCount() const = 0;
|
||||
[[nodiscard]] virtual std::optional<const char*> GetAssetTypeName(asset_type_t assetType) const = 0;
|
||||
|
||||
_NODISCARD size_t GetTotalAssetCount() const;
|
||||
[[nodiscard]] size_t GetTotalAssetCount() const;
|
||||
|
||||
_NODISCARD iterator begin() const;
|
||||
_NODISCARD iterator end() const;
|
||||
[[nodiscard]] iterator begin() const;
|
||||
[[nodiscard]] iterator end() const;
|
||||
|
||||
static std::unique_ptr<ZoneAssetPools> CreateForGame(GameId game, Zone* zone, zone_priority_t priority);
|
||||
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
#include "ZoneRegistry.h"
|
||||
|
||||
Zone::Zone(std::string name, const zone_priority_t priority, GameId gameId)
|
||||
Zone::Zone(std::string name, const zone_priority_t priority, const GameId gameId, const GamePlatform platform)
|
||||
: m_name(std::move(name)),
|
||||
m_priority(priority),
|
||||
m_language(GameLanguage::LANGUAGE_NONE),
|
||||
m_game_id(gameId),
|
||||
m_platform(platform),
|
||||
m_pools(ZoneAssetPools::CreateForGame(gameId, this, priority)),
|
||||
m_memory(std::make_unique<ZoneMemory>()),
|
||||
m_registered(false)
|
||||
|
||||
@@ -15,7 +15,7 @@ class ZoneAssetPools;
|
||||
class Zone
|
||||
{
|
||||
public:
|
||||
Zone(std::string name, zone_priority_t priority, GameId gameId);
|
||||
Zone(std::string name, zone_priority_t priority, GameId gameId, GamePlatform platform);
|
||||
~Zone();
|
||||
Zone(const Zone& other) = delete;
|
||||
Zone(Zone&& other) noexcept = default;
|
||||
@@ -30,6 +30,7 @@ public:
|
||||
zone_priority_t m_priority;
|
||||
GameLanguage m_language;
|
||||
GameId m_game_id;
|
||||
GamePlatform m_platform;
|
||||
ZoneScriptStrings m_script_strings;
|
||||
std::unique_ptr<ZoneAssetPools> m_pools;
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(const ZoneH
|
||||
return nullptr;
|
||||
|
||||
// Create new zone
|
||||
auto zone = std::make_unique<Zone>(fileName, 0, GameId::IW3);
|
||||
auto zone = std::make_unique<Zone>(fileName, 0, GameId::IW3, inspectResult->m_platform);
|
||||
auto* zonePtr = zone.get();
|
||||
zone->m_pools = std::make_unique<GameAssetPoolIW3>(zonePtr, 0);
|
||||
zone->m_language = GameLanguage::LANGUAGE_NONE;
|
||||
|
||||
@@ -211,7 +211,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(const ZoneH
|
||||
return nullptr;
|
||||
|
||||
// Create new zone
|
||||
auto zone = std::make_unique<Zone>(fileName, 0, GameId::IW4);
|
||||
auto zone = std::make_unique<Zone>(fileName, 0, GameId::IW4, inspectResult->m_generic_result.m_platform);
|
||||
auto* zonePtr = zone.get();
|
||||
zone->m_pools = std::make_unique<GameAssetPoolIW4>(zonePtr, 0);
|
||||
zone->m_language = GameLanguage::LANGUAGE_NONE;
|
||||
|
||||
@@ -165,7 +165,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(const ZoneH
|
||||
return nullptr;
|
||||
|
||||
// Create new zone
|
||||
auto zone = std::make_unique<Zone>(fileName, 0, GameId::IW5);
|
||||
auto zone = std::make_unique<Zone>(fileName, 0, GameId::IW5, inspectResult->m_platform);
|
||||
auto* zonePtr = zone.get();
|
||||
zone->m_pools = std::make_unique<GameAssetPoolIW5>(zonePtr, 0);
|
||||
zone->m_language = GameLanguage::LANGUAGE_NONE;
|
||||
|
||||
@@ -68,7 +68,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(const ZoneH
|
||||
return nullptr;
|
||||
|
||||
// Create new zone
|
||||
auto zone = std::make_unique<Zone>(fileName, 0, GameId::T5);
|
||||
auto zone = std::make_unique<Zone>(fileName, 0, GameId::T5, inspectResult->m_platform);
|
||||
auto* zonePtr = zone.get();
|
||||
zone->m_pools = std::make_unique<GameAssetPoolT5>(zonePtr, 0);
|
||||
zone->m_language = GameLanguage::LANGUAGE_NONE;
|
||||
|
||||
@@ -284,7 +284,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(const ZoneH
|
||||
return nullptr;
|
||||
|
||||
// Create new zone
|
||||
auto zone = std::make_unique<Zone>(fileName, 0, GameId::T6);
|
||||
auto zone = std::make_unique<Zone>(fileName, 0, GameId::T6, inspectResult->m_generic_result.m_platform);
|
||||
auto* zonePtr = zone.get();
|
||||
zone->m_pools = std::make_unique<GameAssetPoolT6>(zonePtr, 0);
|
||||
zone->m_language = GetZoneLanguage(fileName);
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace
|
||||
public:
|
||||
TestContext()
|
||||
: m_memory(),
|
||||
m_zone("test", 0, GameId::T6),
|
||||
m_zone("test", 0, GameId::T6, GamePlatform::PC),
|
||||
m_zone_definition(),
|
||||
m_zone_states(m_zone),
|
||||
m_creators(m_zone),
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace
|
||||
{
|
||||
public:
|
||||
TestContext()
|
||||
: m_zone("test", 0, GameId::T6),
|
||||
: m_zone("test", 0, GameId::T6, GamePlatform::PC),
|
||||
m_zone_states(m_zone),
|
||||
m_out_dir()
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace
|
||||
{
|
||||
public:
|
||||
TestContext()
|
||||
: m_zone("test", 0, GameId::T6),
|
||||
: m_zone("test", 0, GameId::T6, GamePlatform::PC),
|
||||
m_zone_definition(),
|
||||
m_zone_definition_context(m_zone_definition),
|
||||
m_zone_states(m_zone),
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace
|
||||
{
|
||||
public:
|
||||
TestContext()
|
||||
: m_zone("test", 0, GameId::T6),
|
||||
: m_zone("test", 0, GameId::T6, GamePlatform::PC),
|
||||
m_zone_definition(),
|
||||
m_zone_definition_context(m_zone_definition),
|
||||
m_zone_states(m_zone),
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace
|
||||
{
|
||||
public:
|
||||
TestContext()
|
||||
: m_zone("test", 0, GameId::T6),
|
||||
: m_zone("test", 0, GameId::T6, GamePlatform::PC),
|
||||
m_zone_states(m_zone),
|
||||
m_out_dir()
|
||||
{
|
||||
|
||||
@@ -274,7 +274,7 @@ namespace
|
||||
]
|
||||
})MATERIAL");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::IW3);
|
||||
Zone zone("MockZone", 0, GameId::IW3, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
AssetCreatorCollection creatorCollection(zone);
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace
|
||||
"test,data,lol\n"
|
||||
"lorem,ipsum");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::IW3);
|
||||
Zone zone("MockZone", 0, GameId::IW3, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
AssetCreatorCollection creatorCollection(zone);
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace
|
||||
"test,data,lol\n"
|
||||
"lorem,ipsum");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::IW4);
|
||||
Zone zone("MockZone", 0, GameId::IW4, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
AssetCreatorCollection creatorCollection(zone);
|
||||
|
||||
@@ -277,7 +277,7 @@ namespace
|
||||
]
|
||||
})MATERIAL");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::IW4);
|
||||
Zone zone("MockZone", 0, GameId::IW4, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
AssetCreatorCollection creatorCollection(zone);
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace test::game::iw4::menu::parsing::it
|
||||
|
||||
public:
|
||||
MenuParsingItHelper()
|
||||
: m_zone("MockZone", 0, GameId::IW4),
|
||||
: m_zone("MockZone", 0, GameId::IW4, GamePlatform::PC),
|
||||
m_creator_collection(m_zone),
|
||||
m_ignored_asset_lookup(),
|
||||
m_context(m_zone, &m_creator_collection, &m_ignored_asset_lookup)
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace
|
||||
"test,data,lol\n"
|
||||
"lorem,ipsum");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::IW5);
|
||||
Zone zone("MockZone", 0, GameId::IW5, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
AssetCreatorCollection creatorCollection(zone);
|
||||
|
||||
@@ -301,7 +301,7 @@ namespace
|
||||
]
|
||||
})MATERIAL");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::IW5);
|
||||
Zone zone("MockZone", 0, GameId::IW5, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
AssetCreatorCollection creatorCollection(zone);
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace
|
||||
"test,data,lol\n"
|
||||
"lorem,ipsum");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::T5);
|
||||
Zone zone("MockZone", 0, GameId::T5, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
AssetCreatorCollection creatorCollection(zone);
|
||||
|
||||
@@ -358,7 +358,7 @@ namespace
|
||||
]
|
||||
})MATERIAL");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::T5);
|
||||
Zone zone("MockZone", 0, GameId::T5, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
AssetCreatorCollection creatorCollection(zone);
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace
|
||||
"test,data,lol\n"
|
||||
"lorem,ipsum");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::T6);
|
||||
Zone zone("MockZone", 0, GameId::T6, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
AssetCreatorCollection creatorCollection(zone);
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace
|
||||
]
|
||||
})FONT_ICON");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::T6);
|
||||
Zone zone("MockZone", 0, GameId::T6, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
AssetCreatorCollection creatorCollection(zone);
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace
|
||||
]
|
||||
})MATERIAL");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::T6);
|
||||
Zone zone("MockZone", 0, GameId::T6, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
AssetCreatorCollection creatorCollection(zone);
|
||||
|
||||
@@ -551,7 +551,7 @@ namespace
|
||||
]
|
||||
})MATERIAL");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::IW3);
|
||||
Zone zone("MockZone", 0, GameId::IW3, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
MockSearchPath mockObjPath;
|
||||
|
||||
@@ -532,7 +532,7 @@ namespace
|
||||
]
|
||||
})MATERIAL");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::IW4);
|
||||
Zone zone("MockZone", 0, GameId::IW4, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
MockSearchPath mockObjPath;
|
||||
|
||||
@@ -585,7 +585,7 @@ namespace
|
||||
]
|
||||
})MATERIAL");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::IW5);
|
||||
Zone zone("MockZone", 0, GameId::IW5, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
MockSearchPath mockObjPath;
|
||||
|
||||
@@ -614,7 +614,7 @@ namespace
|
||||
]
|
||||
})MATERIAL");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::T5);
|
||||
Zone zone("MockZone", 0, GameId::T5, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
MockSearchPath mockObjPath;
|
||||
|
||||
@@ -141,7 +141,7 @@ namespace
|
||||
]
|
||||
})FONT_ICON");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::T6);
|
||||
Zone zone("MockZone", 0, GameId::T6, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
MockSearchPath mockObjPath;
|
||||
|
||||
@@ -462,7 +462,7 @@ namespace
|
||||
]
|
||||
})MATERIAL");
|
||||
|
||||
Zone zone("MockZone", 0, GameId::T6);
|
||||
Zone zone("MockZone", 0, GameId::T6, GamePlatform::PC);
|
||||
|
||||
MemoryManager memory;
|
||||
MockSearchPath mockObjPath;
|
||||
|
||||
Reference in New Issue
Block a user