diff --git a/Projects/Example Projects/ModCreatorKit/AnimEditorMode.cpp b/Projects/Example Projects/ModCreatorKit/AnimEditorMode.cpp index 9028b90f..94f7bc44 100644 --- a/Projects/Example Projects/ModCreatorKit/AnimEditorMode.cpp +++ b/Projects/Example Projects/ModCreatorKit/AnimEditorMode.cpp @@ -64,6 +64,10 @@ bool AnimEditorMode::Initialize(App::IGameModeManager* pManager) GameModeManager.SetActiveMode(MODE_ID); } else { + if (auto args = line.GetOption("help", 1)) + { + App::ConsolePrintF("Params: -add, -remove, -play [hash], -default, -help, -exit"); + } if (auto args = line.GetOption("remove", 1)) { int index = mpFormatParser->ParseInt(args[0]); @@ -75,7 +79,7 @@ bool AnimEditorMode::Initialize(App::IGameModeManager* pManager) request.shopperID = id("CreatureShopper"); Sporepedia::ShopperRequest::Show(request); } - else if (line.HasFlag("exit")) + else if (line.HasFlag("exit") || line.HasFlag("quit")) { GameModeManager.SetActiveMode(kGGEMode); } diff --git a/Projects/Example Projects/ModCreatorKit/Cheats.cpp b/Projects/Example Projects/ModCreatorKit/Cheats.cpp index 2d40edc2..a3d3a2fc 100644 --- a/Projects/Example Projects/ModCreatorKit/Cheats.cpp +++ b/Projects/Example Projects/ModCreatorKit/Cheats.cpp @@ -23,10 +23,12 @@ #include "AddressCheat.h" #include "AnimLogCheat.h" #include "EffectLogCheat.h" +#include "SFXLogCheat.h" #include "PackageCheat.h" #include "PrintCursorCheat.h" #include "UILogCheat.h" #include "UIInspectCheat.h" +#include "PlaySoundCheat.h" #include #include @@ -49,11 +51,13 @@ void AddCheats() { CheatManager.AddCheat("devContext", new ContextCheat()); CheatManager.AddCheat("devAnimLog", new AnimLogCheat()); + CheatManager.AddCheat("devSFXLog", new SFXLogCheat()); CheatManager.AddCheat("devEffectLog", new EffectLogCheat()); CheatManager.AddCheat("devPackage", new PackageCheat()); CheatManager.AddCheat("devLogUI", new UILogCheat()); CheatManager.AddCheat("devInspectUI", new UIInspectCheat()); CheatManager.AddCheat("devPrintCursor", new PrintCursorCheat()); + CheatManager.AddCheat("devPlaySound", new PlaySoundCheat()); AddressCheat::AddCheat(Address(ModAPI::ChooseAddress(0x1498444, 0x1493E5C)), "devRaid"); AddressCheat::AddCheat(Address(ModAPI::ChooseAddress(0x149845C, 0x1493E74)), "devSpace"); diff --git a/Projects/Example Projects/ModCreatorKit/ModCreatorKit.vcxproj b/Projects/Example Projects/ModCreatorKit/ModCreatorKit.vcxproj index 778effef..8175f68a 100644 --- a/Projects/Example Projects/ModCreatorKit/ModCreatorKit.vcxproj +++ b/Projects/Example Projects/ModCreatorKit/ModCreatorKit.vcxproj @@ -126,10 +126,18 @@ + + + + + + + + @@ -174,10 +182,18 @@ + + + + + + + + Create Create diff --git a/Projects/Example Projects/ModCreatorKit/ModCreatorKit.vcxproj.filters b/Projects/Example Projects/ModCreatorKit/ModCreatorKit.vcxproj.filters index 5658ab39..c18d1f32 100644 --- a/Projects/Example Projects/ModCreatorKit/ModCreatorKit.vcxproj.filters +++ b/Projects/Example Projects/ModCreatorKit/ModCreatorKit.vcxproj.filters @@ -94,6 +94,12 @@ ModCreatorKit\Cheats + + ModCreatorKit\Cheats + + + ModCreatorKit\Cheats + @@ -165,6 +171,12 @@ ModCreatorKit\Cheats + + ModCreatorKit\Cheats + + + ModCreatorKit\Cheats + diff --git a/Projects/Example Projects/ModCreatorKit/PlaySoundCheat.cpp b/Projects/Example Projects/ModCreatorKit/PlaySoundCheat.cpp new file mode 100644 index 00000000..12ad7aae --- /dev/null +++ b/Projects/Example Projects/ModCreatorKit/PlaySoundCheat.cpp @@ -0,0 +1,27 @@ +#include "stdafx.h" +#include "PlaySoundCheat.h" + +PlaySoundCheat::PlaySoundCheat() +{ +} + + +PlaySoundCheat::~PlaySoundCheat() +{ +} + + +void PlaySoundCheat::ParseLine(const ArgScript::Line& line) +{ + mParameter = line.GetArguments(1)[0]; + if (string16(mParameter).find(u"0x") == 0) { + Audio::PlayAudio(mpFormatParser->ParseUInt(mParameter)); + } + + Audio::PlayAudio(id(mParameter)); +} + +const char* PlaySoundCheat::GetDescription(ArgScript::DescriptionMode mode) const +{ + return "Plays an SNR sound file by name or hash."; +} diff --git a/Projects/Example Projects/ModCreatorKit/PlaySoundCheat.h b/Projects/Example Projects/ModCreatorKit/PlaySoundCheat.h new file mode 100644 index 00000000..5dfc7a9f --- /dev/null +++ b/Projects/Example Projects/ModCreatorKit/PlaySoundCheat.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +class PlaySoundCheat + : public ArgScript::ICommand +{ +public: + PlaySoundCheat(); + ~PlaySoundCheat(); + + // Called when the cheat is invoked + void ParseLine(const ArgScript::Line& line) override; + + // Returns a string containing the description. If mode != DescriptionMode::Basic, return a more elaborated description + const char* GetDescription(ArgScript::DescriptionMode mode) const override; +private: + const char* mParameter; +}; + diff --git a/Projects/Example Projects/ModCreatorKit/SFXLogCheat.cpp b/Projects/Example Projects/ModCreatorKit/SFXLogCheat.cpp new file mode 100644 index 00000000..42716d55 --- /dev/null +++ b/Projects/Example Projects/ModCreatorKit/SFXLogCheat.cpp @@ -0,0 +1,31 @@ +#include "stdafx.h" +#include "SFXLogCheat.h" + + +bool SFXLogCheat::IsEnabled = false; + +// Detour the audio playing func +static_detour(PlayAudio_detour, void(uint32_t, Audio::AudioTrack)) { + void detoured(uint32_t soundID, Audio::AudioTrack track) { + original_function(soundID, track); + if (SFXLogCheat::IsEnabled && soundID != 0) + { + App::ConsolePrintF("devSFXLog: playing Audio ID: 0x%x", soundID); + } + } +}; + +void SFXLogCheat::AttachDetour() { + PlayAudio_detour::attach(GetAddress(Audio, PlayAudio)); +} + +void SFXLogCheat::ParseLine(const ArgScript::Line& line) +{ + auto args = line.GetArguments(1); + SFXLogCheat::IsEnabled = mpFormatParser->ParseBool(args[0]); +} + +const char* SFXLogCheat::GetDescription(ArgScript::DescriptionMode mode) const +{ + return "Usage: sfxLog on/off. If enabled, every time a UI sound effect is played it will print its ID. Does not include creature voices or world sounds."; +} diff --git a/Projects/Example Projects/ModCreatorKit/SFXLogCheat.h b/Projects/Example Projects/ModCreatorKit/SFXLogCheat.h new file mode 100644 index 00000000..dd42b25a --- /dev/null +++ b/Projects/Example Projects/ModCreatorKit/SFXLogCheat.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +class SFXLogCheat + : public ArgScript::ICommand +{ +public: + void ParseLine(const ArgScript::Line& line) override; + const char* GetDescription(ArgScript::DescriptionMode mode) const override; + + static bool IsEnabled; + + static void AttachDetour(); +}; + diff --git a/Projects/Example Projects/ModCreatorKit/ThumbnailCaptureScript.cpp b/Projects/Example Projects/ModCreatorKit/ThumbnailCaptureScript.cpp index a0b31734..3fe17d08 100644 --- a/Projects/Example Projects/ModCreatorKit/ThumbnailCaptureScript.cpp +++ b/Projects/Example Projects/ModCreatorKit/ThumbnailCaptureScript.cpp @@ -34,7 +34,7 @@ ThumbnailCaptureScript::ThumbnailCaptureScript() , mItemViewers() , mpItemViewer(nullptr) , mFolderPath() - , mIsEnabled(false) + , mbIsEnabled(false) { } @@ -199,16 +199,20 @@ void ThumbnailCaptureScript::InjectListeners() { // standard editor/planner if (pageUI.page->mStandardItems.size() > 0) { for (StandardItemUIPtr itemUI : pageUI.page->mStandardItems) { - itemUI->field_18->AddWinProc(this); - mItemViewers[itemUI->field_18.get()] = itemUI->mpViewer.get(); + itemUI->mpWindow->AddWinProc(this); + mItemViewers[itemUI->mpWindow.get()] = itemUI->mpViewer.get(); } } // adventure editor /* else { - for (eastl::intrusive_ptr itemUI : pageUI.page->mAdvancedItems) { - itemUI->mpWindow - mItemViewers[itemUI->field_18.get()] = itemUI->mpViewer.get(); + for (IAdvancedItemUIPtr itemUI : pageUI.page->mAdvancedItems) { + auto item = object_cast(itemUI.get()); + if (item && item->mpWindow) { + item->mpWindow->AddWinProc(this); + mItemViewers[item->mpWindow.get()] = itemUI->mpViewer.get(); + } + } }*/ @@ -218,9 +222,11 @@ void ThumbnailCaptureScript::InjectListeners() { // simple category else { for (auto pageUI : catUI->mPageUIs) { - for (StandardItemUIPtr itemUI : pageUI.page->mStandardItems) { - itemUI->field_18->AddWinProc(this); - mItemViewers[itemUI->field_18.get()] = itemUI->mpViewer.get(); + if (pageUI.page->mStandardItems.size() > 0) { + for (StandardItemUIPtr itemUI : pageUI.page->mStandardItems) { + itemUI->mpWindow->AddWinProc(this); + mItemViewers[itemUI->mpWindow.get()] = itemUI->mpViewer.get(); + } } } } @@ -247,14 +253,14 @@ void ThumbnailCaptureScript::RemoveListeners() { // standard editor/planner if (pageUI.page->mStandardItems.size() > 0) { for (StandardItemUIPtr itemUI : pageUI.page->mStandardItems) { - itemUI->field_18->RemoveWinProc(this); + itemUI->mpWindow->RemoveWinProc(this); } } /* // adventure editor else { for (StandardItemUIPtr itemUI : pageUI.page->mpPage->mItems) { - itemUI->field_18->RemoveWinProc(this); + itemUI->mpWindow->RemoveWinProc(this); } } */ @@ -265,8 +271,8 @@ void ThumbnailCaptureScript::RemoveListeners() { else { for (auto pageUI : catUI->mPageUIs) { for (StandardItemUIPtr itemUI : pageUI.page->mStandardItems) { - if (itemUI && itemUI->field_18) { - itemUI->field_18->RemoveWinProc(this); + if (itemUI && itemUI->mpWindow) { + itemUI->mpWindow->RemoveWinProc(this); } } } @@ -279,10 +285,10 @@ void ThumbnailCaptureScript::RemoveListeners() { } void ThumbnailCaptureScript::ParseLine(const ArgScript::Line& line) { - if (mIsEnabled) { + if (mbIsEnabled) { RemoveListeners(); App::ConsolePrintF("Icon capture disabled."); - mIsEnabled = false; + mbIsEnabled = false; return; } @@ -327,7 +333,7 @@ void ThumbnailCaptureScript::ParseLine(const ArgScript::Line& line) { InjectListeners(); App::ConsolePrintF("Icon capture enabled: hover a palette item and wait until it starts rotating to generate the icon."); - mIsEnabled = true; + mbIsEnabled = true; } const char* ThumbnailCaptureScript::GetDescription(ArgScript::DescriptionMode mode) const { diff --git a/Projects/Example Projects/ModCreatorKit/ThumbnailCaptureScript.h b/Projects/Example Projects/ModCreatorKit/ThumbnailCaptureScript.h index f68fcf84..d79e567c 100644 --- a/Projects/Example Projects/ModCreatorKit/ThumbnailCaptureScript.h +++ b/Projects/Example Projects/ModCreatorKit/ThumbnailCaptureScript.h @@ -73,6 +73,6 @@ class ThumbnailCaptureScript ColorRGB mOldColor; ColorRGB mIdentityColor; string16 mFolderPath; - bool mIsEnabled; + bool mbIsEnabled; }; diff --git a/Projects/Example Projects/ModCreatorKit/dllmain.cpp b/Projects/Example Projects/ModCreatorKit/dllmain.cpp index 39d9f68f..be431285 100644 --- a/Projects/Example Projects/ModCreatorKit/dllmain.cpp +++ b/Projects/Example Projects/ModCreatorKit/dllmain.cpp @@ -8,6 +8,8 @@ #include "Cheats.h" #include "ThumbnailCaptureScript.h" #include "AnimLogCheat.h" +#include "EffectLogCheat.h" +#include "SFXLogCheat.h" #include "UILogCheat.h" #include "AnimEditorMode.h" @@ -108,6 +110,8 @@ void AttachDetours() Debugging::AttachDetour(); cEffectsManager_detour::attach(GetAddress(Swarm::cSwarmManager, GetDirectoryAndEffectIndex)); AnimLogCheat::AttachDetour(); + EffectLogCheat::AttachDetour(); + SFXLogCheat::AttachDetour(); UILogCheat::AttachDetour(); ThumbnailCaptureScript::AttachDetour(); } diff --git a/Spore ModAPI/SourceCode/Editors/EditorCamera.cpp b/Spore ModAPI/SourceCode/Editors/EditorCamera.cpp index 03476f6e..c8d36378 100644 --- a/Spore ModAPI/SourceCode/Editors/EditorCamera.cpp +++ b/Spore ModAPI/SourceCode/Editors/EditorCamera.cpp @@ -54,7 +54,7 @@ namespace Editors , mbEditorCameraTurntableStyle() , field_94() , field_98() - , field_9C() + , mbFOVisCurrent() , mInput() , mpViewer(nullptr) { diff --git a/Spore ModAPI/SourceCode/Editors/EditorPalettes.cpp b/Spore ModAPI/SourceCode/Editors/EditorPalettes.cpp index e8bd3837..046b3da1 100644 --- a/Spore ModAPI/SourceCode/Editors/EditorPalettes.cpp +++ b/Spore ModAPI/SourceCode/Editors/EditorPalettes.cpp @@ -226,14 +226,14 @@ namespace Palettes PaletteUI::PaletteUI() : mpLayout(nullptr) , mpCategoryButtonsWindow() - , field_14() - , field_18() - , field_1C() + , mpWindowLeft() + , mpWindowRight() + , mpWindowBehind() , mpAnimatedWindow(nullptr) , mpCategoryContent() , mpPalette(nullptr) , mCategories() - , field_48() + , mCategorySlots() , field_5C() , field_60() , mpActiveCategory() @@ -278,6 +278,13 @@ namespace Palettes return paint; } + void PaletteUI::SetActiveCategory(int categoryIndex) + { + CALL(GetAddress(PaletteUI, SetActiveCategory), void, + Args(PaletteUI*, int), + Args(this, categoryIndex)); + } + auto_METHOD_VOID(PaletteUI, Load, Args(PaletteMain* pPalette, UTFWin::IWindow* pWindow, bool arg_8, PaletteInfo* arg_C), Args(pPalette, pWindow, arg_8, arg_C)); diff --git a/Spore ModAPI/SourceCode/Simulator/cSpatialObject.cpp b/Spore ModAPI/SourceCode/Simulator/cSpatialObject.cpp index c1e4d662..976cf073 100644 --- a/Spore ModAPI/SourceCode/Simulator/cSpatialObject.cpp +++ b/Spore ModAPI/SourceCode/Simulator/cSpatialObject.cpp @@ -29,5 +29,26 @@ namespace Simulator void cLocomotiveObject::SetVelocity(const Vector3& velocity) { this->mVelocity = velocity; } + + Math::Quaternion cSpatialObject::GetOrientationYawTowards(const Vector3& targetpos) + { + Vector3 upVector = GetPosition().Normalized(); // Local up axis + + // Compute direction to the target + Vector3 direction = (targetpos - GetPosition()).Normalized(); + + // Project onto the X-Z plane (perpendicular to upVector) + direction = (direction - upVector * direction.Dot(upVector)).Normalized(); + + // Project forward vector onto the same X-Z plane + Vector3 forward = (GetDirection() - upVector * GetDirection().Dot(upVector)).Normalized(); + + // Compute the yaw rotation needed + Quaternion yawRotation; + yawRotation = yawRotation.GetRotationTo(forward, direction); + + // Apply the yaw rotation while maintaining the original pitch and roll + return (yawRotation * GetOrientation()); + } } #endif diff --git a/Spore ModAPI/SourceCode/UTFWin/Tooltips.cpp b/Spore ModAPI/SourceCode/UTFWin/Tooltips.cpp index 50986be8..2a83e6c6 100644 --- a/Spore ModAPI/SourceCode/UTFWin/Tooltips.cpp +++ b/Spore ModAPI/SourceCode/UTFWin/Tooltips.cpp @@ -33,8 +33,8 @@ namespace UTFWin , mDetailedText() , mOffsetPosition(0, 30.0f) , field_4C() - , field_50() - , field_54() + , mLocaleID() + , mLayoutGroupID() , field_58() , mBehaviour(TooltipBehaviour::Default) , field_60() @@ -58,8 +58,8 @@ namespace UTFWin , mDetailedText(pDetailedText) , mOffsetPosition(offsetPositon) , field_4C() - , field_50() - , field_54() + , mLocaleID() + , mLayoutGroupID() , field_58() , mBehaviour(behaviour) , field_60() diff --git a/Spore ModAPI/Spore/Anim/AnimatedCreature.h b/Spore ModAPI/Spore/Anim/AnimatedCreature.h index cd63aaeb..c3341a2a 100644 --- a/Spore ModAPI/Spore/Anim/AnimatedCreature.h +++ b/Spore ModAPI/Spore/Anim/AnimatedCreature.h @@ -74,7 +74,7 @@ namespace Anim /* 18h */ virtual bool StartAnimation(AnimIndex index) = 0; /* 1Ch */ virtual bool func1Ch(AnimIndex index, float) = 0; - /// Enables or disables looping in this animation, which is repating the animation once it ends playing. + /// Enables or disables looping in this animation, which is repeating the animation once it ends playing. /// SetLoopTimes() must also be called to set how many times /// the animation is looped, setting it to -1 loops it indefinitely. /// @param index Index of the animation diff --git a/Spore ModAPI/Spore/Audio/AudioSystem.h b/Spore ModAPI/Spore/Audio/AudioSystem.h index edc36e0a..09710938 100644 --- a/Spore ModAPI/Spore/Audio/AudioSystem.h +++ b/Spore ModAPI/Spore/Audio/AudioSystem.h @@ -32,7 +32,7 @@ namespace Audio class AudioSystem { - //PLACEHODER we might need to complete this + //PLACEHOLDER we might need to complete this /* 00h */ int func00h(); /* 04h */ int func04h(); diff --git a/Spore ModAPI/Spore/Editors/EditorCamera.h b/Spore ModAPI/Spore/Editors/EditorCamera.h index 95a0c821..51aa8786 100644 --- a/Spore ModAPI/Spore/Editors/EditorCamera.h +++ b/Spore ModAPI/Spore/Editors/EditorCamera.h @@ -1,4 +1,4 @@ -/**************************************************************************** +/**************************************************************************** * Copyright (C) 2019 Eric Mor * * This file is part of Spore ModAPI. @@ -71,16 +71,22 @@ namespace Editors /* 24h */ float field_24; /* 28h */ float mfInitialZoom; // 1.0 /* 2Ch */ bool field_2C; - /* 30h */ float field_30; // cameraInitialHeading + /* 30h */ float field_30; // cameraInitialHeading (unclamped float Camera heading) /* 34h */ float field_34; // cameraInitialPitch /* 38h */ float mfZoom; // 10.0 // cameraInitialZoom - /* 3Ch */ float field_3C; // cameraInitialOffsetX - /* 40h */ float field_40; // cameraInitialOffsetY + /* 3Ch */ float field_3C; // cameraInitialOffsetX (desired) + /* 40h */ float field_40; // cameraInitialOffsetY (desired) + + /// field_44 is Camera heading in positive and negative radians + // range -pi to -0 facing creature front (☻) + // range pi to 0 facing creature back (•) + // +pi/2 creature facing screen right -> + // -pi/2 creature facing screen left <- /* 44h */ float field_44; // cameraInitialHeading /* 48h */ float field_48; // cameraInitialPitch /* 4Ch */ float field_4C; // cameraInitialZoom - /* 50h */ float field_50; // cameraInitialOffsetX - /* 54h */ float field_54; // cameraInitialOffsetY + /* 50h */ float field_50; // cameraInitialOffsetX (current/lerp from?) + /* 54h */ float field_54; // cameraInitialOffsetY (current/lerp from?) /* 58h */ float mfMinZoomDistance; // 5.0 /* 5Ch */ float mfMaxZoomDistance; // 25.0 /* 60h */ float mfMinPitch; @@ -89,12 +95,12 @@ namespace Editors /* 6Ch */ float mfFarClip; // -1 /* 70h */ float mfInitialFOV; // 57.29578 /* 74h */ Vector3 mCameraPosition; - /* 80h */ Vector3 field_80; + /* 80h */ Vector3 field_80; // also camera pos, one is probably current and one is desired... /* 8Ch */ float field_8C; // 1.0 /* 90h */ bool mbEditorCameraTurntableStyle; /* 94h */ float field_94; /* 98h */ float field_98; - /* 9Ch */ bool field_9C; + /* 9Ch */ bool mbFOVisCurrent; // change to false to update camera FOV to mfInitialFOV's value /* A0h */ GameInput mInput; /* E8h */ App::cViewer* mpViewer; }; diff --git a/Spore ModAPI/Spore/Editors/EditorLimits.h b/Spore ModAPI/Spore/Editors/EditorLimits.h index 4bd0aa37..cce2e5fd 100644 --- a/Spore ModAPI/Spore/Editors/EditorLimits.h +++ b/Spore ModAPI/Spore/Editors/EditorLimits.h @@ -38,7 +38,7 @@ namespace Editors /// Limits the value at the given index so that it's not greater than the limit. /* 1Ch */ virtual void EnsureLimit(int index); - /// Adds a certain amount to the value of the given index. The total value will be capped at its limit. + /// Adds a certain amount to the value of the given EditorLimitType index. The total value will be capped at its limit. /// A message of type `0x3150C27` will be sent /* 20h */ virtual void AddValue(int index, int value); /// Sets a certain value of the given index. The total value will be capped at its limit. diff --git a/Spore ModAPI/Spore/Editors/EditorModel.h b/Spore ModAPI/Spore/Editors/EditorModel.h index cac79983..fc6baf4e 100644 --- a/Spore ModAPI/Spore/Editors/EditorModel.h +++ b/Spore ModAPI/Spore/Editors/EditorModel.h @@ -89,9 +89,9 @@ namespace Editors /* 5Ch */ eastl::string16 mName; /* 6Ch */ eastl::string16 mDescription; // message 0x14418C3F ? /* 7Ch */ eastl::string16 mAcceptedName; // the name after removing illegal characters - /* 8Ch */ int mSkinEffectIDs[3]; + /* 8Ch */ uint32_t mSkinEffectIDs[3]; // Skinpaint IDs /* 98h */ int mSkinEffectSeeds[3]; // 1234 - /* A4h */ ColorRGB mColors[3]; + /* A4h */ ColorRGB mColors[3]; // Skinpaint Colors /* C8h */ eastl::vector field_C8; /* DCh */ int mZCorpScore; // not initialized }; diff --git a/Spore ModAPI/Spore/MathUtils.h b/Spore ModAPI/Spore/MathUtils.h index 81406b47..11c01ad0 100644 --- a/Spore ModAPI/Spore/MathUtils.h +++ b/Spore ModAPI/Spore/MathUtils.h @@ -105,6 +105,8 @@ namespace Math /// @param other float Dot(const Vector2& other) const; + Vector2 Lerp(const Vector2& other, float mix) const; + Vector2& operator+=(const Vector2&); Vector2& operator+=(float); Vector2& operator-=(const Vector2&); @@ -158,6 +160,8 @@ namespace Math /// @param orientationAxis static float OrientedAngle(const Vector3& v1, const Vector3& v2, const Vector3& orientationAxis); + Vector3 Lerp(const Vector3& other, float mix) const; + Vector3& operator+=(const Vector3&); Vector3& operator+=(float); Vector3& operator-=(const Vector3&); @@ -196,6 +200,8 @@ namespace Math /// @param other float Dot(const Vector4& other) const; + Vector4 Lerp(const Vector4& other, float mix) const; + Vector4& operator+=(const Vector4&); Vector4& operator+=(float); Vector4& operator-=(const Vector4&); @@ -1197,14 +1203,11 @@ namespace Math return x * other.x + y * other.y + z * other.z + w * other.w; } - - inline Vector3 BoundingBox::GetCenter() const { return (lower + upper) / 2.0f; } - inline bool Vector2::operator==(const Vector2& b) const { return x == b.x && y == b.y; } @@ -1357,6 +1360,21 @@ namespace Math inline ColorRGBA lerp(const ColorRGBA& a, const ColorRGBA& b, float mix) { return { lerp(a.r, b.r, mix), lerp(a.g, b.g, mix), lerp(a.b, b.b, mix), lerp(a.a, b.a, mix) }; } + + // Vector Lerps + + inline Vector2 Vector2::Lerp(const Vector2& other, float mix) const { + return { lerp(x, other.x, mix), lerp(y, other.y, mix) }; + } + + inline Vector3 Vector3::Lerp(const Vector3& other, float mix) const { + return { lerp(x, other.x, mix), lerp(y, other.y, mix), lerp(z, other.z, mix) }; + } + + inline Vector4 Vector4::Lerp(const Vector4& other, float mix) const { + return { lerp(x, other.x, mix), lerp(y, other.y, mix), lerp(z, other.z, mix), lerp(w, other.w, mix) }; + } + } #ifdef SDK_TO_GHIDRA diff --git a/Spore ModAPI/Spore/Palettes/IItemFrameUI.h b/Spore ModAPI/Spore/Palettes/IItemFrameUI.h index 64541022..c0e6e38c 100644 --- a/Spore ModAPI/Spore/Palettes/IItemFrameUI.h +++ b/Spore ModAPI/Spore/Palettes/IItemFrameUI.h @@ -51,6 +51,9 @@ namespace Palettes uint32_t mFrameTypeID; }; +#define IAdvancedItemUIPtr eastl::intrusive_ptr +#define DefaultItemFrameUIPtr eastl::intrusive_ptr + class IAdvancedItemUI : public IItemFrameUI, public UTFWin::IWinProc {}; class DefaultItemFrameUI diff --git a/Spore ModAPI/Spore/Palettes/PaletteCategory.h b/Spore ModAPI/Spore/Palettes/PaletteCategory.h index 44bbcf1f..29536706 100644 --- a/Spore ModAPI/Spore/Palettes/PaletteCategory.h +++ b/Spore ModAPI/Spore/Palettes/PaletteCategory.h @@ -40,7 +40,7 @@ namespace Palettes /// /// Loads the configuration .prop file of this category; this does not load the pages nor the subcategories - /// contained on it. If the groupID of the ResourceKey given is 0, 0x406B0100 will be used as folder instead. + /// contained on it. If the groupID of the ResourceKey given is 0, 0x406B0100 (palette_config~) will be used as folder instead. /// /// @param name The ResourceKey that points to the .prop file. /// @param defaultLayoutID The default instance ID of the layout file that the category will use, if no layout is specified in the .prop file. @@ -64,7 +64,7 @@ namespace Palettes PalettePage* GetPageAt(size_t nIndex); /// - /// Tells whether the given subcategory is a children of this subcategory. + /// Tells whether the given subcategory is a children of this subcategory. /// @param pCategory bool HasCategory(PaletteCategory* pCategory); diff --git a/Spore ModAPI/Spore/Palettes/PalettePageUI.h b/Spore ModAPI/Spore/Palettes/PalettePageUI.h index 97bd624c..2dba08cc 100644 --- a/Spore ModAPI/Spore/Palettes/PalettePageUI.h +++ b/Spore ModAPI/Spore/Palettes/PalettePageUI.h @@ -85,7 +85,7 @@ namespace Palettes /* 18h */ float field_18; /* 1Ch */ float field_1C; /* 20h */ eastl::vector mStandardItems; - /* 34h */ eastl::vector> mAdvancedItems; + /* 34h */ eastl::vector mAdvancedItems; }; ASSERT_SIZE(PalettePageUI, 0x48); diff --git a/Spore ModAPI/Spore/Palettes/PaletteUI.h b/Spore ModAPI/Spore/Palettes/PaletteUI.h index 137c8a2d..d9dac9c1 100644 --- a/Spore ModAPI/Spore/Palettes/PaletteUI.h +++ b/Spore ModAPI/Spore/Palettes/PaletteUI.h @@ -91,11 +91,11 @@ namespace Palettes /// The layout of the palette, loaded using the ID in Palettes::PaletteMain::mLayoutID. /* 0Ch */ UILayoutPtr mpLayout; /// The window that contains the category selection buttons. - /* 10h */ UTFWin::IWindow* mpCategoryButtonsWindow; // 0x72DF4CEE - /* 14h */ UTFWin::IWindow* field_14; // 0xBA83C461 - /* 18h */ UTFWin::IWindow* field_18; // 0x90D4AADC - /* 1Ch */ UTFWin::IWindow* field_1C; // 0x05AEFF7F - /* 20h */ UTFWin::SporeAnimatedIconWin* mpAnimatedWindow; + /* 10h */ UTFWin::IWindow* mpCategoryButtonsWindow; // 0x72DF4CEE Buttons stored in reverse order + /* 14h */ UTFWin::IWindow* mpWindowLeft; // 0xBA83C461 + /* 18h */ UTFWin::IWindow* mpWindowRight; // 0x90D4AADC + /* 1Ch */ UTFWin::IWindow* mpWindowBehind; // 0x05AEFF7F + /* 20h */ UTFWin::SporeAnimatedIconWin* mpAnimatedWindow; // 0x49AFE6A1 highlight tab? /// The window that is used to display the category content (e.g. its pages) /* 24h */ UTFWin::IWindow* mpCategoryContent; // 0x93019DBC /// The main window of the UILayout, with ControlID 0xFFFFFFFF. @@ -105,7 +105,8 @@ namespace Palettes /* 30h */ PaletteInfoPtr mpPaletteInfo; /// The UI objects for all categories contained in the palette. They are in the same order as the PaletteMain::mCategories field. /* 34h */ eastl::vector mCategories; - /* 48h */ eastl::vector field_48; // intrusive_ptrs too, but it's never used? + /// The category SLOTS activated by and behind the category buttons. Must be cleared before reloading palette + /* 48h */ eastl::vector mCategorySlots; // intrusive_ptr to unknown class. /* 5Ch */ int field_5C; /* 60h */ int field_60; /* 64h */ PaletteCategoryUIPtr mpActiveCategory; diff --git a/Spore ModAPI/Spore/Palettes/StandardItemUI.h b/Spore ModAPI/Spore/Palettes/StandardItemUI.h index 1881c513..9fda01e3 100644 --- a/Spore ModAPI/Spore/Palettes/StandardItemUI.h +++ b/Spore ModAPI/Spore/Palettes/StandardItemUI.h @@ -43,9 +43,9 @@ namespace Palettes public: /* 0Ch */ PaletteItemPtr mpItem; - /* 10h */ uint32_t field_10; + /* 10h */ uint32_t field_10; // 0x1CEB6B70 /* 14h */ ItemViewerPtr mpViewer; - /* 18h */ IWindowPtr field_18; + /* 18h */ IWindowPtr mpWindow; // Main window. Holds the icon and detects focus /* 1Ch */ bool field_1C; }; ASSERT_SIZE(StandardItemUI, 0x20); diff --git a/Spore ModAPI/Spore/Simulator/SimulatorEnums.h b/Spore ModAPI/Spore/Simulator/SimulatorEnums.h index 90778478..8c5e978f 100644 --- a/Spore ModAPI/Spore/Simulator/SimulatorEnums.h +++ b/Spore ModAPI/Spore/Simulator/SimulatorEnums.h @@ -749,36 +749,38 @@ namespace Simulator kCitizenActionHeal = 5, - kCitizenActionAttack = 7, - kCitizenActionRaid1 = 8, - kCitizenActionGift1 = 9, - kCitizenActionHunt = 10, + kCitizenActionSleep = 6, // Sends the creature into the main tribe hut + + kCitizenActionAttack = 7, // Attack a citizen + kCitizenActionRaidFood = 8, + kCitizenActionGiftFood = 9, + kCitizenActionHunt = 10, // Attack a wild animal kCitizenActionMate = 11, - kCitizenActionParty = 12, + kCitizenActionParty = 12, // Dance around the game object, actionObject = fire pit or other cTribeTool kCitizenActionCollectEgg = 13, kCitizenActionBundle = 14, - kCitizenActionRaid2 = 15, + kCitizenActionRaidHuts = 15, // Attack huts or tools of this tribe, starting with the actionObject = cTribeHut or cTribeTool kCitizenActionFeedWild = 20, - kCitizenActionGift2 = 21, + kCitizenActionGiftMember = 21, kCitizenActionRepair = 24, // actionObject = cTribeHut or cTribeTool kCitizenActionTame = 25, - kCitizenActionRecruit = 26, + kCitizenActionRecruit = 26, // Begin social minigame kCitizenActionGatherMeat = 27, - kCitizenActionUnk1 = 28, // common ID, actionObject = nullptr + kCitizenActionReturnToTribe = 28, // Sends the creature back to their tribe. actionObject = nullptr }; enum HandheldItem { kHandheldItemNone = 0, - /// trg_hunting_tool1 + /// trg_hunting_tool1 - Allowed in combat kHandheldItemTrgHuntingTool1 = 1, - /// trg_hunting_tool2 + /// trg_hunting_tool2 - Allowed in combat kHandheldItemTrgHuntingTool2 = 2, - /// trg_hunting_tool3 + /// trg_hunting_tool3 - Allowed in combat kHandheldItemTrgHuntingTool3 = 3, /// trg_fishing_tool and related kHandheldItemTrgFishingTool = 4, @@ -806,7 +808,7 @@ namespace Simulator kHandheldItemTrgSocialDidgeridoo = 15, /// trg_gathering_treesmacker kHandheldItemTrgGatheringTreeSmacker = 16, - /// trg_chieftain_staff + /// trg_chieftain_staff - Allowed in combat kHandheldItemTrgChieftainStaff = 17, /// trg_healing_staff kHandheldItemTrgHealingStaff = 18, @@ -814,8 +816,8 @@ namespace Simulator kHandheldItemTrgRepairMallet = 19, /// trg_water_bucket kHandheldItemTrgWaterBucket = 20, - /// 0xA8F747AE, some tribal horn - kHandheldItemUnk21 = 21, + /// trg_wildhorn + kHandheldItemTrgWildHorn = 21, /// trg_firebomb kHandheldItemTrgFireBomb = 22, /// trg_eating_egg diff --git a/Spore ModAPI/Spore/Simulator/cCombatant.h b/Spore ModAPI/Spore/Simulator/cCombatant.h index 3ab4cfa2..91957d67 100644 --- a/Spore ModAPI/Spore/Simulator/cCombatant.h +++ b/Spore ModAPI/Spore/Simulator/cCombatant.h @@ -79,7 +79,7 @@ namespace Simulator /* 14h */ virtual cSpaceToolData* GetWeapon(); /// Called when the combatant is attacked, takes the damage - /* 18h */ virtual int TakeDamage(float damage, uint32_t attackerPoliticalID, int, const Vector3&, cCombatant* pAttacker); // used to substract health? + /* 18h */ virtual int TakeDamage(float damage, uint32_t attackerPoliticalID, int, const Vector3&, cCombatant* pAttacker); // used to substract health /* 1Ch */ virtual void AddHostileUnit(cCombatant* combatant); /* 20h */ virtual Math::Vector3 func20h(); diff --git a/Spore ModAPI/Spore/Simulator/cCommunity.h b/Spore ModAPI/Spore/Simulator/cCommunity.h index e1f790bb..af0b52cf 100644 --- a/Spore ModAPI/Spore/Simulator/cCommunity.h +++ b/Spore ModAPI/Spore/Simulator/cCommunity.h @@ -101,7 +101,7 @@ namespace Simulator /* ACh */ int field_AC; /* B0h */ cGonzagoTimer field_B0; /* D0h */ eastl::vector field_D0; // With release at C0h - /* E4h */ eastl::vector mCommunityMembers; + /* E4h */ eastl::vector mCommunityMembers; /* F8h */ eastl::string16 mName; /* 108h */ eastl::string16 mDescription; /* 118h */ int field_118; // -1 diff --git a/Spore ModAPI/Spore/Simulator/cCommunityLayout.h b/Spore ModAPI/Spore/Simulator/cCommunityLayout.h index 6aff8d2a..13e12601 100644 --- a/Spore ModAPI/Spore/Simulator/cCommunityLayout.h +++ b/Spore ModAPI/Spore/Simulator/cCommunityLayout.h @@ -44,7 +44,7 @@ namespace Simulator /* 20h */ float field_20; /* 24h */ int field_24; // not initialized /* 28h */ bool field_28; - /* 2Ch */ Quaternion field_2C; + /* 2Ch */ Quaternion field_2C; // Orientation? /* 3Ch */ eastl::vector field_3C; /* 50h */ eastl::vector mSlots; }; diff --git a/Spore ModAPI/Spore/Simulator/cCreatureBase.h b/Spore ModAPI/Spore/Simulator/cCreatureBase.h index 5e657d1b..751b7418 100644 --- a/Spore ModAPI/Spore/Simulator/cCreatureBase.h +++ b/Spore ModAPI/Spore/Simulator/cCreatureBase.h @@ -53,7 +53,7 @@ namespace Simulator /* 00h */ bool field_00; /* 01h */ bool field_01; /* 04h */ int field_04; - /* 08h */ ResourceID field_08; + /* 08h */ ResourceID field_08; // Ability resource? }; ASSERT_SIZE(cAbilityState, 0x10); // Maybe used in other places as well? @@ -140,7 +140,7 @@ namespace Simulator /// @param amount void ConsumeEnergy(float amount); - /// Returns the index to the first ability of the craeture that has the specified ability type. + /// Returns the index to the first ability of the creature that has the specified ability type. /// @param abilityType /// @returns Index to ability, or -1 if not found int GetAbilityIndexByType(int abilityType); diff --git a/Spore ModAPI/Spore/Simulator/cCreatureCitizen.h b/Spore ModAPI/Spore/Simulator/cCreatureCitizen.h index d135837f..4b81083b 100644 --- a/Spore ModAPI/Spore/Simulator/cCreatureCitizen.h +++ b/Spore ModAPI/Spore/Simulator/cCreatureCitizen.h @@ -48,7 +48,7 @@ namespace Simulator /* FF0h */ int field_FF0; /* FF4h */ int mSelectionGroup; // -1 /* FF8h */ int field_FF8; // -1 - /* FFCh */ int field_FFC; + /* FFCh */ int mCurrentHandheldItem; // HandheldItem index /* 1000h */ bool mAffectedByRecruiting; /* 1001h */ bool field_1001; // not initialized /* 1002h */ bool field_1002; // true diff --git a/Spore ModAPI/Spore/Simulator/cLocomotiveObject.h b/Spore ModAPI/Spore/Simulator/cLocomotiveObject.h index d1e3f06d..ab6ca4be 100644 --- a/Spore ModAPI/Spore/Simulator/cLocomotiveObject.h +++ b/Spore ModAPI/Spore/Simulator/cLocomotiveObject.h @@ -71,7 +71,8 @@ namespace Simulator /* D8h */ virtual float funcD8h() const; /* DCh */ virtual void funcDCh(int); // some kind of movement request? sets mInTransitTime = 0 // the bool might be "relative" position? - /* E0h */ virtual void MoveTo(const Vector3& dst, float goalStopDistance = 1.0f, float acceptableStopDistance = 2.0f, bool=false); + // setting it to true makes vehicles move properly in straight lines. + /* E0h */ virtual void MoveTo(const Vector3& dst, float goalStopDistance = 1.0f, float acceptableStopDistance = 2.0f, bool unk1 = false); /* E4h */ virtual void funcE4h(const Vector3&, int); /* E8h */ virtual void funcE8h(const Vector3&, float, float); /* ECh */ virtual void StopMovement(); diff --git a/Spore ModAPI/Spore/Simulator/cSpatialObject.h b/Spore ModAPI/Spore/Simulator/cSpatialObject.h index f14f9290..01b5f404 100644 --- a/Spore ModAPI/Spore/Simulator/cSpatialObject.h +++ b/Spore ModAPI/Spore/Simulator/cSpatialObject.h @@ -113,6 +113,9 @@ namespace Simulator /* BCh */ virtual int AddRef() = 0; /* C0h */ virtual int Release() = 0; + // Return a new orientation towards a target pos, preserving the pitch and roll of the current orientation + Math::Quaternion GetOrientationYawTowards(const Math::Vector3& targetpos); + public: /* 04h */ Math::Vector3 mPosition; diff --git a/Spore ModAPI/Spore/Simulator/cTribeInputStrategy.h b/Spore ModAPI/Spore/Simulator/cTribeInputStrategy.h index 1ee73892..a9b9c388 100644 --- a/Spore ModAPI/Spore/Simulator/cTribeInputStrategy.h +++ b/Spore ModAPI/Spore/Simulator/cTribeInputStrategy.h @@ -41,7 +41,7 @@ namespace Simulator /// Sets the current cursor, and maybe shows a rollover, depending on the current object /// pointed at by the mouse cursor. The object will be cGameViewManager::GetHoveredObject() - /// The method will do nothing is IsInEditor() returns true. + /// The method will do nothing if IsInEditor() returns true. void SetHoverObjectCursorAndRollover(); /// Returns true if the player has gone to the creature outfitter editor, false otherwise. diff --git a/Spore ModAPI/Spore/UI/SimulatorRollovers.h b/Spore ModAPI/Spore/UI/SimulatorRollovers.h index a34bf8e5..fe1d1fa2 100644 --- a/Spore ModAPI/Spore/UI/SimulatorRollovers.h +++ b/Spore ModAPI/Spore/UI/SimulatorRollovers.h @@ -8,7 +8,10 @@ namespace UI { enum class SimulatorRolloverID { - + // Invalid / Dead, 0 health no information + Invalid = 0, + /// No rollover + None = 1, /// Rollover_TribeTool TribeTool = 2, /// Rollover_TribeCitizen diff --git a/Spore ModAPI/Spore/UTFWin/Cursors.h b/Spore ModAPI/Spore/UTFWin/Cursors.h index 0c040d74..2dd9289d 100644 --- a/Spore ModAPI/Spore/UTFWin/Cursors.h +++ b/Spore ModAPI/Spore/UTFWin/Cursors.h @@ -116,13 +116,13 @@ namespace UTFWin /// STD_Center-alpha09 StdCenterAlpha09 = 0x1023, + ///------------------- + /// Simulator Cursors + ///------------------- /// cursor-no-opt NoOptions = 0x3a204b0, - /// cursor_goodie-hut - QuestionHut = 0x56e3a22, - // cursor-object-translate Pan = 0x600cd69, @@ -132,6 +132,14 @@ namespace UTFWin /// cursor-ban-mode BanMode = 0x5ecbdffd, + + ///------------------- + /// CRG Cursors + ///------------------- + + /// cur_ClaimNest + ClaimNest = 0x7542cdb5, + /// cursor_skeleton2 UnlockSkeleton = 0x342d221f, @@ -159,6 +167,23 @@ namespace UTFWin /// cursor_friend Friend = 0x755c4eb5, + /// cursor-crg-pickup + Pickup = 0x3b360dc, + + /// cursor-crg-putdown + Putdown = 0x3b360df, + + /// cursor-crg-throw + Throw = 0x3b360e4, + + + ///------------------- + /// TRG Cursors + ///------------------- + + /// cursor-dance + Dance = 0x3febe3d, + /// cursor-trg-domesticate Domesticate = 0xe382f00e, @@ -180,15 +205,6 @@ namespace UTFWin /// cursor-gather Gather = 0x3febe40, - /// cursor-crg-pickup - Pickup = 0x3b360dc, - - /// cursor-crg-putdown - Putdown = 0x3b360df, - - /// cursor-crg-throw - Throw = 0x3b360e4, - /// cursor_pickup-maracas PickupMaracas = 0x63fe8d4, @@ -216,15 +232,21 @@ namespace UTFWin /// cursor_pickup-heal PickupHealing = 0x3febe3b, - /// cursor-dance - Dance = 0x3febe3d, + + ///------------------- + /// CVG Cursors + ///------------------- /// cursor-claim-spicemine ClaimSpice = 0x5d53800, - /// cur_ClaimNest - ClaimNest = 0x7542cdb5, + /// cursor_goodie-hut + QuestionHut = 0x56e3a22, + + ///------------------- + /// SPG Cursors + ///------------------- /// cursor-spg-sculpting-norm SpgSculpting = 0x682102e, @@ -259,6 +281,20 @@ namespace UTFWin /// cursor-spg-atmospheric-norm SpgAtmosphere = 0x6821042, + + ///------------------- + /// EP1 Cursors + ///------------------- + + /// cursor-object-scale + ObjectScale = 0xe84563d4, + + /// cursor-translate-XY + TranslateXY = 0xf728e452, + + /// cursor-translate-Z + TranslateZ = 0x7391920b, + }; } } \ No newline at end of file diff --git a/Spore ModAPI/Spore/UTFWin/GlideEffect.h b/Spore ModAPI/Spore/UTFWin/GlideEffect.h index a193f116..66b7bda2 100644 --- a/Spore ModAPI/Spore/UTFWin/GlideEffect.h +++ b/Spore ModAPI/Spore/UTFWin/GlideEffect.h @@ -25,7 +25,7 @@ namespace UTFWin { - class IGlideEffect : public UTFWinObject + class IGlideEffect : public IBiStateEffect { public: /// diff --git a/Spore ModAPI/Spore/UTFWin/IWindow.h b/Spore ModAPI/Spore/UTFWin/IWindow.h index 18a691f6..1606ba2c 100644 --- a/Spore ModAPI/Spore/UTFWin/IWindow.h +++ b/Spore ModAPI/Spore/UTFWin/IWindow.h @@ -196,7 +196,7 @@ namespace UTFWin /* 58h */ virtual void SetState(int state) = 0; /// - /// Returns the color modulation value. This color acts as a tint: after the window is painted, it gets multiplied by this color. + /// Sets the color modulation value. This color acts as a tint: after the window is painted, it gets multiplied by this color. /// @param color The color to use as the 'shadeColor' property. /// /* 5Ch */ virtual void SetShadeColor(Math::Color color) = 0; @@ -544,20 +544,34 @@ namespace UTFWin } /// - /// Tells whether the window is visible. This is equivalent to GetFlags() & kWinFlagEnabled. + /// Tells whether the window is enabled. This is equivalent to GetFlags() & kWinFlagEnabled. /// inline bool IsEnabled() const { return GetFlags() & kWinFlagEnabled; } /// - /// Switches the visibility of this window. This is equivalent to SetFlag(kWinFlagEnabled, bEnabled). + /// Switches the enabled state of this window. This is equivalent to SetFlag(kWinFlagEnabled, bEnabled). /// inline void SetEnabled(bool bEnabled) { SetFlag(kWinFlagEnabled, bEnabled); } + /// + /// Tells whether the window ignores the mouse. This is equivalent to GetFlags() & kWinFlagIgnoreMouse. + /// + inline bool IsIgnoringMouse() const + { + return GetFlags() & kWinFlagIgnoreMouse; + } + /// + /// Switches whether the window ignores the mouse. This is equivalent to SetFlag(kWinFlagIgnoreMouse, bEnabled). + /// + inline void SetIgnoreMouse(bool bIgnoreMouse) + { + SetFlag(kWinFlagIgnoreMouse, bIgnoreMouse); + } /// /// Sets the given UTFWin::IWindow to fit the entire area of its parent. diff --git a/Spore ModAPI/Spore/UTFWin/Image.h b/Spore ModAPI/Spore/UTFWin/Image.h index 3f2554c9..7e29e84c 100644 --- a/Spore ModAPI/Spore/UTFWin/Image.h +++ b/Spore ModAPI/Spore/UTFWin/Image.h @@ -82,8 +82,6 @@ namespace UTFWin /// /// The method will try to use the existing drawable of the window; if there's no drawable or it's not an StdDrawable or /// an ImageDrawable, one will be created; by default an ImageDrawable will be created, unless an image index is specified. - /// - /// To detour this method, you must use GetAddress(Image, SetBackground_2). /// /// @param pWindow The IWindow whose drawable will change. /// @param imageName The ResourceKey that points to the image file that will be displayed in the window. diff --git a/Spore ModAPI/Spore/UTFWin/ImageDrawable.h b/Spore ModAPI/Spore/UTFWin/ImageDrawable.h index a090bb7a..39f6ecb3 100644 --- a/Spore ModAPI/Spore/UTFWin/ImageDrawable.h +++ b/Spore ModAPI/Spore/UTFWin/ImageDrawable.h @@ -193,6 +193,14 @@ namespace UTFWin virtual void SetAlignmentVertical(AlignmentV alignment) override; virtual AlignmentV GetAlignmentVertical() const override; + inline OutlineFormat GetImageOutline() { + return mImageOutline; + } + + inline OutlineFormat SetImageOutline(OutlineFormat outline) { + mImageOutline = outline; + } + protected: /* 10h */ float mfScale; @@ -238,6 +246,7 @@ namespace UTFWin DeclareAddress(SetImageForWindow); // 0xE2F550 0xE2F590 } + inline ImageDrawable::ImageDrawable() : mfScale(1.0f) , mnFlags() diff --git a/Spore ModAPI/Spore/UTFWin/SporeTooltipWinProc.h b/Spore ModAPI/Spore/UTFWin/SporeTooltipWinProc.h index a1ae890d..2126578a 100644 --- a/Spore ModAPI/Spore/UTFWin/SporeTooltipWinProc.h +++ b/Spore ModAPI/Spore/UTFWin/SporeTooltipWinProc.h @@ -78,8 +78,8 @@ namespace UTFWin /// The offset of the tooltip window relative to the cursor, by default (0, 30). /* 44h */ Math::Point mOffsetPosition; // (0, 30) /* 4Ch */ int field_4C; - /* 50h */ int field_50; - /* 54h */ int field_54; + /* 50h */ uint32_t mLocaleID; + /* 54h */ uint32_t mLayoutGroupID; // 0x40464100 (layouts~) /* 58h */ bool field_58; /// Sets the tooltip display behavior. /* 5Ch */ TooltipBehaviour mBehaviour;