Complete CArtifactDoll

This commit is contained in:
Jack Andersen 2017-05-12 18:57:24 -10:00
parent e13583ff80
commit 9796ba9244
9 changed files with 292 additions and 48 deletions

View File

@ -12,43 +12,47 @@ namespace DNAMP1
enum class EPickupType : atUint32
{
PowerBeam,
IceBeam,
WaveBeam,
PlasmaBeam,
Missile,
ScanVisor,
MorphBallBomb,
PowerBomb,
Flamethrower,
ChargeBeam,
XRayVisor,
IceSpreader,
SpaceJump,
MorphBall,
CombatVisor,
SpiderBall,
PowerSuit,
GravitySuit,
VariaSuit,
PhazonSuit,
EnergyTank,
UnknownItem1,
HealthRefill,
UnknownItem2,
WaveBuster,
Truth,
Strength,
Elder,
Wild,
LifeGiver,
Warrior,
Chozo,
Nature,
Sun,
World,
Spirit,
Newborn
PowerBeam = 0,
IceBeam = 1,
WaveBeam = 2,
PlasmaBeam = 3,
Missile = 4,
ScanVisor = 5,
MorphBallBomb = 6,
PowerBomb = 7,
Flamethrower = 8,
ThermalVisor = 9,
ChargeBeam = 10,
SuperMissile = 11,
GrappleBeam = 12,
XRayVisor = 13,
IceSpreader = 14,
SpaceJump = 15,
MorphBall = 16,
CombatVisor = 17,
BoostBall = 18,
SpiderBall = 19,
PowerSuit = 20,
GravitySuit = 21,
VariaSuit = 22,
PhazonSuit = 23,
EnergyTank = 24,
UnknownItem1 = 25,
HealthRefill = 26,
UnknownItem2 = 27,
WaveBuster = 28,
Truth = 29,
Strength = 30,
Elder = 31,
Wild = 32,
LifeGiver = 33,
Warrior = 34,
Chozo = 35,
Nature = 36,
Sun = 37,
World = 38,
Spirit = 39,
Newborn = 40
};
enum class ESpecialFunctionType : atUint32

View File

@ -148,7 +148,7 @@ public:
EPlayerVisor GetActiveVisor(const CStateManager& stateMgr) const;
void UpdateStaticInterference(CStateManager& stateMgr, const float& dt);
void IncreaseScanTime(u32 time, float val);
void SetScanTime(ResId time, float val);
void SetScanTime(ResId res, float time);
float GetScanTime(ResId time) const;
bool GetIsVisorTransitioning() const;
float GetVisorTransitionFactor() const;

View File

@ -0,0 +1,190 @@
#include "CArtifactDoll.hpp"
#include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp"
#include "CStateManager.hpp"
#include "Graphics/CBooRenderer.hpp"
namespace urde
{
namespace MP1
{
static const char* ArtifactPieceModels[] =
{
"CMDL_Piece1", // Truth
"CMDL_Piece2", // Strength
"CMDL_Piece3", // Elder
"CMDL_Piece4", // Wild
"CMDL_Piece5", // Lifegiver
"CMDL_Piece6", // Warrior
"CMDL_Piece7", // Chozo
"CMDL_Piece8", // Nature
"CMDL_Piece9", // Sun
"CMDL_Piece10", // World
"CMDL_Piece11", // Spirit
"CMDL_Piece12" // Newborn
};
static const ResId ArtifactHeadScans[] =
{
0x32C9DDCE, // Truth
0xB45DAF60, // Strength
0x7F017CC5, // Elder
0x62044C7D, // Wild
0xA9589FD8, // Lifegiver
0x2FCCED76, // Warrior
0xE4903ED3, // Chozo
0x15C68C06, // Nature
0xDE9A5FA3, // Sun
0xFBBE9D9A, // World
0x30E24E3F, // Spirit
0xB6763C91 // Newborn
};
static const zeus::CColor ArtifactPreColor = {0.4f, 0.68f, 0.88f, 0.8f};
static const zeus::CColor ArtifactPostColor = {1.f, 0.63f, 0.02f, 1.f};
CArtifactDoll::CArtifactDoll()
{
x10_lights.resize(2, CLight::BuildDirectional(zeus::CVector3f::skForward, zeus::CColor::skWhite));
x20_actorLights = std::make_unique<CActorLights>(8, zeus::CVector3f::skZero, 4, 4,
false, false, false, 0.1f);
x28_24_loaded = false;
x0_models.reserve(12);
for (int i=0 ; i<12 ; ++i)
x0_models.push_back(g_SimplePool->GetObj(ArtifactPieceModels[i]));
}
int CArtifactDoll::GetArtifactHeadScanIndex(ResId scanId)
{
ResId orig = g_ResFactory->TranslateNewToOriginal(scanId);
for (int i=0 ; i<12 ; ++i)
if (ArtifactHeadScans[i] == orig)
return i;
return -1;
}
ResId CArtifactDoll::GetArtifactHeadScanFromItemType(CPlayerState::EItemType item)
{
if (item < CPlayerState::EItemType::ArtifactOfTruth || item > CPlayerState::EItemType::ArtifactOfNewborn)
return -1;
return g_ResFactory->TranslateOriginalToNew(ArtifactHeadScans[int(item) - 29]);
}
void CArtifactDoll::UpdateArtifactHeadScan(const CStateManager& mgr, float delta)
{
CPlayerState& playerState = *mgr.GetPlayerState();
for (int i=0 ; i<12 ; ++i)
{
if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType(i + 29)))
{
ResId newId = g_ResFactory->TranslateOriginalToNew(ArtifactHeadScans[i]);
playerState.SetScanTime(newId, std::min(playerState.GetScanTime(newId) + delta, 1.f));
}
}
}
void CArtifactDoll::CompleteArtifactHeadScan(const CStateManager& mgr)
{
UpdateArtifactHeadScan(mgr, 1.f);
}
void CArtifactDoll::Draw(float alpha, const CStateManager& mgr,
bool inArtifactCategory, int selectedArtifact)
{
if (!IsLoaded())
return;
g_Renderer->SetPerspective(55.f, g_Viewport.x8_width, g_Viewport.xc_height, 0.2f, 4096.f);
CGraphics::SetViewPointMatrix(zeus::CTransform::Translate(0.f, -10.f, 0.f));
float angle = CGraphics::GetSecondsMod900() * 2.f * M_PIF * 0.25f;
CGraphics::SetModelMatrix(
zeus::CTransform::RotateX(zeus::degToRad(std::sin(angle) * 8.f)) *
zeus::CTransform::RotateZ(zeus::degToRad(std::cos(angle) * 8.f)) *
zeus::CTransform::RotateX(M_PIF / 2.f) *
zeus::CTransform::Scale(0.2f));
CPlayerState& playerState = *mgr.GetPlayerState();
for (int i=0 ; i<x0_models.size() ; ++i)
{
TLockedToken<CModel>& model = x0_models[i];
zeus::CColor color = ArtifactPreColor;
if (playerState.HasPowerUp(CPlayerState::EItemType(i + 29)))
{
if (ArtifactHeadScans[i] != -1)
{
ResId newId = g_ResFactory->TranslateOriginalToNew(ArtifactHeadScans[i]);
float interp = (playerState.GetScanTime(newId) - 0.5f) * 2.f;
if (interp < 0.5f)
color = zeus::CColor::lerp(ArtifactPreColor, zeus::CColor::skWhite, 2.f * interp);
else
color = zeus::CColor::lerp(zeus::CColor::skWhite, ArtifactPostColor, 2.f * (interp - 0.5f));
}
else
{
color = ArtifactPostColor;
}
}
if (inArtifactCategory && i == selectedArtifact)
{
float interp = (std::sin(CGraphics::GetSecondsMod900() * 2.f * M_PIF) + 1.f) * 0.5f;
color = zeus::CColor::lerp(zeus::CColor::skWhite, color, interp);
color.a *= zeus::clamp(0.f, 1.25f - interp, 1.f);
}
CModelFlags flags(7, 0, 3, zeus::CColor(1.f, 0.f));
flags.m_extendedShader = EExtendedShader::SolidColorFrontfaceCullLEqualAlphaOnly;
x20_actorLights->ActivateLights(model->GetInstance());
model->Draw(flags);
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
model->Draw(flags);
}
}
void CArtifactDoll::UpdateActorLights()
{
x10_lights[0] = CLight::BuildDirectional(
(zeus::CVector3f::skForward + 0.25f * zeus::CVector3f::skRight + 0.1f * zeus::CVector3f::skDown).normalized(),
zeus::CColor::skWhite);
x10_lights[1] = CLight::BuildDirectional(-zeus::CVector3f::skForward, zeus::CColor::skBlack);
x20_actorLights->BuildFakeLightList(x10_lights, zeus::CColor(0.25f, 1.f));
}
void CArtifactDoll::Update(float dt, const CStateManager& mgr)
{
if (!CheckLoadComplete())
return;
x24_fader = std::min(x24_fader + 2.f * dt, 1.f);
if (std::fabs(x24_fader - 1.f) < 0.00001f)
UpdateArtifactHeadScan(mgr, 0.5f * dt * 0.5f);
UpdateActorLights();
}
void CArtifactDoll::Touch()
{
if (!CheckLoadComplete())
return;
for (TLockedToken<CModel>& model : x0_models)
model->Touch(0);
}
bool CArtifactDoll::CheckLoadComplete()
{
if (IsLoaded())
return true;
for (TLockedToken<CModel>& model : x0_models)
if (!model.IsLoaded())
return false;
x28_24_loaded = true;
return true;
}
}
}

View File

@ -4,6 +4,7 @@
#include "RetroTypes.hpp"
#include "Character/CActorLights.hpp"
#include "CToken.hpp"
#include "CPlayerState.hpp"
namespace urde
{
@ -20,13 +21,16 @@ class CArtifactDoll
bool x28_24_loaded : 1;
void UpdateActorLights();
public:
CGameCubeDoll();
void Update(float dt);
void Draw(float alpha);
CArtifactDoll();
static int GetArtifactHeadScanIndex(ResId scanId);
static ResId GetArtifactHeadScanFromItemType(CPlayerState::EItemType item);
static void UpdateArtifactHeadScan(const CStateManager& mgr, float delta);
static void CompleteArtifactHeadScan(const CStateManager& mgr);
void Draw(float alpha, const CStateManager& mgr, bool inArtifactCategory, int selectedArtifact);
void Update(float dt, const CStateManager& mgr);
void Touch();
bool CheckLoadComplete();
bool IsLoaded() const { return x20_24_loaded; }
bool IsLoaded() const { return x28_24_loaded; }
};
}

View File

@ -1,4 +1,7 @@
#include "CLogBookScreen.hpp"
#include "GuiSys/CGuiModel.hpp"
#include "GuiSys/CGuiTableGroup.hpp"
#include "MP1.hpp"
namespace urde
{
@ -9,7 +12,27 @@ CLogBookScreen::CLogBookScreen(const CStateManager& mgr, CGuiFrame& frame,
const CStringTable& pauseStrg)
: CPauseScreenBase(mgr, frame, pauseStrg)
{
x258_artifactDoll = std::make_unique<CArtifactDoll>();
CMain::EnsureWorldPaksReady();
InitializeLogBook();
}
CLogBookScreen::~CLogBookScreen()
{
CArtifactDoll::CompleteArtifactHeadScan(x4_mgr);
for (CGuiModel* model : x144_model_titles)
model->SetLocalTransform(model->GetTransform());
CMain::EnsureWorldPakReady(g_GameState->CurrentWorldAssetId());
}
void CLogBookScreen::InitializeLogBook()
{
}
bool CLogBookScreen::IsArtifactCategorySelected() const
{
return x70_tablegroup_leftlog->GetUserSelection() == 4;
}
bool CLogBookScreen::VReady() const

View File

@ -3,6 +3,7 @@
#include "CInGameGuiManager.hpp"
#include "CPauseScreenBase.hpp"
#include "CArtifactDoll.hpp"
namespace urde
{
@ -11,8 +12,30 @@ namespace MP1
class CLogBookScreen : public CPauseScreenBase
{
rstl::reserved_vector<std::vector<u32>, 5> x19c_;
std::vector<u32> x1f0_;
rstl::reserved_vector<std::vector<u32>, 5> x200_;
float x254_ = 0.f;
std::unique_ptr<CArtifactDoll> x258_artifactDoll;
u32 x25c_ = 0;
union
{
struct
{
bool x260_24_ : 1;
bool x260_25_ : 1;
bool x260_26_ : 1;
};
s32 _dummy = 0;
};
void InitializeLogBook();
public:
CLogBookScreen(const CStateManager& mgr, CGuiFrame& frame, const CStringTable& pauseStrg);
~CLogBookScreen();
bool IsArtifactCategorySelected() const;
bool VReady() const;
void VActivate();

View File

@ -32,7 +32,7 @@ void COptionsScreen::UpdateOptionView()
if (category.first == 0)
return;
float zOff = x38_hightlightPitch * x1c_rightSel;
float zOff = x38_highlightPitch * x1c_rightSel;
const SGameOption& opt = category.second[x1c_rightSel];
switch (opt.type)
{

View File

@ -52,7 +52,7 @@ void CPauseScreenBase::InitializeFrameGlue()
x194_tablegroup_triple = static_cast<CGuiTableGroup*>(x8_frame.FindWidget("tablegroup_triple"));
x2c_rightTableStart = x84_tablegroup_rightlog->GetWorkerWidget(0)->GetIdlePosition();
x38_hightlightPitch = x84_tablegroup_rightlog->GetWorkerWidget(1)->GetIdlePosition().z - x2c_rightTableStart.z;
x38_highlightPitch = x84_tablegroup_rightlog->GetWorkerWidget(1)->GetIdlePosition().z - x2c_rightTableStart.z;
x3c_sliderStart = x18c_slidergroup_slider->GetIdlePosition();
x48_tableDoubleStart = x190_tablegroup_double->GetIdlePosition();
x54_tableTripleStart = x194_tablegroup_triple->GetIdlePosition();
@ -232,7 +232,7 @@ void CPauseScreenBase::UpdateSideTable(CGuiTableGroup* table)
{
int sel = x1c_rightSel - x18_firstViewRightSel;
x8c_model_righthighlight->SetLocalTransform(
x8c_model_righthighlight->GetTransform() * zeus::CTransform::Translate(0.f, 0.f, x38_hightlightPitch * sel));
x8c_model_righthighlight->GetTransform() * zeus::CTransform::Translate(0.f, 0.f, x38_highlightPitch * sel));
x8c_model_righthighlight->SetVisibility(x10_mode == EMode::RightTable, ETraversalMode::Children);
int selInView = x1c_rightSel % 5;
if (IsRightLogDynamic())
@ -249,7 +249,7 @@ void CPauseScreenBase::UpdateSideTable(CGuiTableGroup* table)
{
int sel = x70_tablegroup_leftlog->GetUserSelection();
x78_model_lefthighlight->SetLocalTransform(
x78_model_lefthighlight->GetTransform() * zeus::CTransform::Translate(0.f, 0.f, x38_hightlightPitch * sel));
x78_model_lefthighlight->GetTransform() * zeus::CTransform::Translate(0.f, 0.f, x38_highlightPitch * sel));
for (int i=0 ; i<xc0_model_categories.size() ; ++i)
xc0_model_categories[i]->SetColor(i == sel ? selColor : deselColor);
}

View File

@ -41,7 +41,7 @@ protected:
int x1c_rightSel = 0;
zeus::CVector3f x20_;
zeus::CVector3f x2c_rightTableStart;
float x38_hightlightPitch = 0.f;
float x38_highlightPitch = 0.f;
zeus::CVector3f x3c_sliderStart;
zeus::CVector3f x48_tableDoubleStart;
zeus::CVector3f x54_tableTripleStart;