Skip to content

Commit 64ac2e0

Browse files
committed
Added AchievementsManager
1 parent 6f70d20 commit 64ac2e0

11 files changed

Lines changed: 180 additions & 4 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
#ifdef MODAPI_DLL_EXPORT
22
#include <Spore\Pollinator\cAssetMetadata.h>
3+
#include <Spore\Pollinator\AchievementsManager.h>
34

45
namespace Pollinator
56
{
67
namespace Addresses(cAssetMetadata)
78
{
89
DefineAddress(Set, SelectAddress(0x5511D0, 0x551240));
910
}
11+
12+
namespace Addresses(cAchievementsManager)
13+
{
14+
DefineAddress(Get, SelectAddress(0x6755E0, 0x675210));
15+
DefineAddress(Init, SelectAddress(0x676D90, 0x676C40));
16+
DefineAddress(GetAchievementDefinition, SelectAddress(0x676770, 0x676620));
17+
DefineAddress(EvaluateTriggerOp, SelectAddress(0x676800, 0x6766B0));
18+
DefineAddress(EarnAchievement, SelectAddress(0x676820, 0x6766D0));
19+
DefineAddress(AddProgress, SelectAddress(0x676FA0, 0x676E50));
20+
DefineAddress(SetProgressFlags, SelectAddress(0x676FE0, 0x676E90));
21+
}
1022
}
1123
#endif

Spore ModAPI/SourceCode/Pollinator/Pollinator.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
#ifndef MODAPI_DLL_EXPORT
22
#include <Spore\Pollinator\cAssetMetadata.h>
3+
#include <Spore\Pollinator\AchievementsManager.h>
34

45
namespace Pollinator
56
{
7+
//// cAssetMetadata ////
8+
69
auto_METHOD(cAssetMetadata, bool, Set,
710
Args(const ResourceKey& key, const char16_t* pName, const char16_t* pDescription, const char16_t* pTags,
811
const ResourceKey& parentAssetKey, bool isPollinated),
@@ -14,5 +17,19 @@ namespace Pollinator
1417
PARENT_CAST(Resource::ResourceObject);
1518
return nullptr;
1619
}
20+
21+
//// cAchievementsManager ////
22+
23+
auto_STATIC_METHOD_(cAchievementsManager, cAchievementsManager*, Get);
24+
25+
auto_METHOD(cAchievementsManager, cAchievementDefinition*, GetAchievementDefinition, Args(uint32_t aID), Args(aID));
26+
27+
auto_METHOD(cAchievementsManager, bool, EvaluateTriggerOp, Args(uint32_t aID), Args(aID));
28+
29+
auto_METHOD_VOID(cAchievementsManager, AddProgress, Args(uint32_t aID, int delta), Args(aID, delta));
30+
31+
auto_METHOD_VOID(cAchievementsManager, SetProgressFlags, Args(uint32_t aID, int progressFlags, bool value), Args(aID, progressFlags, value));
32+
33+
auto_METHOD(cAchievementsManager, bool, EarnAchievement, Args(uint32_t aID), Args(aID));
1734
}
1835
#endif

Spore ModAPI/Spore ModAPI.vcxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,9 @@
378378
<ClInclude Include="Spore\Palettes\PaletteInfo.h" />
379379
<ClInclude Include="Spore\Palettes\PaletteSubcategoriesUI.h" />
380380
<ClInclude Include="Spore\Palettes\SwatchManager.h" />
381+
<ClInclude Include="Spore\Pollinator\AchievementsManager.h" />
381382
<ClInclude Include="Spore\Pollinator\cAssetMetadata.h" />
383+
<ClInclude Include="Spore\Pollinator\cSPAchievementSerializer.h" />
382384
<ClInclude Include="Spore\RenderWare\IRwResource.h" />
383385
<ClInclude Include="Spore\Resource\DatabaseDirectoryFiles.h" />
384386
<ClInclude Include="Spore\Resource\IRecord.h" />
@@ -425,6 +427,7 @@
425427
<ClInclude Include="Spore\Simulator\cScenarioSimulator.h" />
426428
<ClInclude Include="Spore\Simulator\cScenarioTerraformMode.h" />
427429
<ClInclude Include="Spore\Simulator\cSimPlanetHighLOD.h" />
430+
<ClInclude Include="Spore\Simulator\cSimulatorUniverse.h" />
428431
<ClInclude Include="Spore\Simulator\cSolarHitSphere.h" />
429432
<ClInclude Include="Spore\Simulator\cSpaceNames.h" />
430433
<ClInclude Include="Spore\Simulator\cTimeOfDay.h" />

Spore ModAPI/Spore ModAPI.vcxproj.filters

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,15 @@
20972097
<ClInclude Include="Spore\App\Canvas.h">
20982098
<Filter>Header Files</Filter>
20992099
</ClInclude>
2100+
<ClInclude Include="Spore\Simulator\cSimulatorUniverse.h">
2101+
<Filter>Header Files</Filter>
2102+
</ClInclude>
2103+
<ClInclude Include="Spore\Pollinator\AchievementsManager.h">
2104+
<Filter>Header Files</Filter>
2105+
</ClInclude>
2106+
<ClInclude Include="Spore\Pollinator\cSPAchievementSerializer.h">
2107+
<Filter>Header Files</Filter>
2108+
</ClInclude>
21002109
</ItemGroup>
21012110
<ItemGroup>
21022111
<ClCompile Include="SourceCode\Allocator.cpp">

Spore ModAPI/Spore/App/ICheatManager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ namespace App
4545
enum MessageIDs
4646
{
4747
/// A message with no content sent when certain cheats are invoked.
48+
/// This message disables achievements.
4849
kMsgCheatInvoked = 0x4BEF1E3
4950
};
5051

@@ -62,7 +63,7 @@ namespace App
6263
/// function will be called when the cheat is invoked.
6364
/// @param pString The keyword that is used to invoke the cheat. This is case insensitive and it can't contain whitespaces.
6465
/// @param pParser The ArgScript::ICommand that represents this cheat.
65-
/// @param bNotify [Optional] If true, a kMsgCheatInvoked message will be sent when the cheat is invoked.
66+
/// @param bNotify [Optional] If true, a kMsgCheatInvoked message will be sent when the cheat is invoked, which will disable achievements.
6667
///
6768
/* 18h */ virtual void AddCheat(const char* pString, ArgScript::ICommand* pParser, bool bNotify = false) = 0;
6869

Spore ModAPI/Spore/App/cCheatManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ namespace App
7171

7272
/* 08h */ int mnRefCount;
7373
/* 0Ch */ CheatMap_t mCheats;
74+
/// Calling these cheats disable achievements, by posting a ICheatsManager::kMsgCheatInvoked message.
7475
/* 28h */ eastl::set<eastl::string> mNotifyCheats;
7576
/* 44h */ ArgScript::FormatParser* mpArgScript;
7677
/* 48h */ eastl::set<ObjectPtr> field_48; // UIs?

Spore ModAPI/Spore/BasicIncludes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include <Spore\Terrain.h>
3333
#include <Spore\Cell.h>
3434

35+
#include <Spore\Pollinator\AchievementsManager.h>
36+
3537
#include <Spore\Editors\Editor.h>
3638
#include <Spore\Editors\EditorRequest.h>
3739
#include <Spore\Editors\EditorMessages.h>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#pragma once
2+
3+
#include <Spore\App\IMessageListener.h>
4+
#include <Spore\Pollinator\cSPAchievementSerializer.h>
5+
#include <EASTL\hash_map.h>
6+
#include <EASTL\vector_map.h>
7+
8+
#define AchievementsManager (*Pollinator::cAchievementsManager::Get())
9+
10+
namespace Pollinator
11+
{
12+
/// Manages the achievements of the game.
13+
/// This manager listens to the App::IMessageManager::kMsgCheatInvoked message,
14+
/// and will disable achievements when it receives the message, as you will be considered a cheater.
15+
/// Example code:
16+
/// ```cpp
17+
/// AchievementsManager.AddProgress(id("ADV-MyHero"), 20);
18+
/// ```
19+
class cAchievementsManager
20+
: public App::IUnmanagedMessageListener
21+
{
22+
public:
23+
enum Messages
24+
{
25+
kMsgSaveAchievements = 0x212D3E7
26+
};
27+
28+
static cAchievementsManager* Get();
29+
30+
cAchievementDefinition* GetAchievementDefinition(uint32_t achievementID);
31+
32+
/// Evaluates whether the current achievement progress exceeds the trigger,
33+
/// which means the achievement should be earned.
34+
/// @param achievementID
35+
/// @returns
36+
bool EvaluateTriggerOp(uint32_t achievementID);
37+
38+
/// Increases or decreases the progress of an achievement. If the achievement is automatic,
39+
/// this will call EvaluateTriggerOp() afterwards, and earn the achievement if it returns true.
40+
/// @param achievementID
41+
/// @param deltaProgress
42+
void AddProgress(uint32_t achievementID, int deltaProgress);
43+
44+
/// Treats the progress as flags, and enables or disables some of them. If the achievement is automatic,
45+
/// this will call EvaluateTriggerOp() afterwards, and earn the achievement if it returns true.
46+
/// @param achievementID
47+
/// @param progressFlags
48+
/// @param value
49+
void SetProgressFlags(uint32_t achievementID, int progressFlags, bool value);
50+
51+
/// Earns an achievement.
52+
/// @param achievementID
53+
/// @returns True if it was earned successfully
54+
bool EarnAchievement(uint32_t achievementID);
55+
56+
public:
57+
/* 04h */ int mpAchievementNotifierUI;
58+
/* 08h */ cSPAchievementSerializerPtr mpSerializer;
59+
/* 0Ch */ eastl::vector_map<uint32_t, cAchievementDefinition> mAchievements;
60+
/// If true, achievements are disabled.
61+
/* 24h */ bool mIsCheater;
62+
/* 28h */ cSPAchievementSerializer::CrossGameData mCrossGameData;
63+
};
64+
ASSERT_SIZE(cAchievementsManager, 0xA8);
65+
66+
namespace Addresses(cAchievementsManager)
67+
{
68+
DeclareAddress(Get); // 0x6755E0 0x675210
69+
DeclareAddress(Init); // 0x676D90 0x676C40
70+
DeclareAddress(GetAchievementDefinition); // 0x676770 0x676620
71+
DeclareAddress(EvaluateTriggerOp); // 0x676800 0x6766B0
72+
DeclareAddress(EarnAchievement); // 0x676820 0x6766D0
73+
DeclareAddress(AddProgress); // 0x676FA0 0x676E50
74+
DeclareAddress(SetProgressFlags); // 0x676FE0 0x676E90
75+
}
76+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#pragma once
2+
3+
#include <Spore\Simulator\ISimulatorSerializable.h>
4+
#include <EASTL\vector.h>
5+
#include <EASTL\vector_map.h>
6+
#include <EASTL\hash_set.h>
7+
8+
#define cSPAchievementSerializerPtr eastl::intrusive_ptr<Pollinator::cSPAchievementSerializer>
9+
10+
namespace Pollinator
11+
{
12+
struct cAchievementDefinition
13+
{
14+
enum Flags
15+
{
16+
/// If present, the achievement will be granted automatically upon adding progress if it exceeds the trigger
17+
kFlagAutomatic = 1,
18+
kFlagGameScope = 2,
19+
20+
kTriggerOpGreaterEqual = 0x000,
21+
kTriggerOpGreater = 0x100,
22+
kTriggerOpEqual = 0x200,
23+
kTriggerOpLess = 0x300,
24+
kTriggerOpLessEqual = 0x400,
25+
kTriggerOpNotEqual = 0x500,
26+
kTriggerOpMask = 0x700,
27+
};
28+
29+
/// Flags
30+
/* 00h */ int mFlags;
31+
/* 04h */ int mProgress;
32+
/* 08h */ int mTriggerValue;
33+
};
34+
ASSERT_SIZE(cAchievementDefinition, 0xC);
35+
36+
class cSPAchievementSerializer
37+
: public Simulator::ISimulatorSerializable
38+
, public RefCountTemplate
39+
{
40+
public:
41+
struct CrossGameData
42+
{
43+
/* 00h */ eastl::hash_set<uint32_t> mCellGameIDs;
44+
/* 20h */ eastl::hash_set<uint32_t> mEncounteredCreatures;
45+
/* 40h */ eastl::hash_set<uint32_t> mEatenCreatures;
46+
/* 60h */ eastl::hash_set<uint32_t> mTribeGamesCompleted;
47+
};
48+
ASSERT_SIZE(CrossGameData, 0x80);
49+
50+
/* 0Ch */ eastl::vector_map<uint32_t, cAchievementDefinition> mAchievements;
51+
/* 24h */ eastl::vector<int> mAchievementSet;
52+
/* 38h */ int field_38; // not initialized
53+
/* 3Ch */ CrossGameData mCrossGameData;
54+
};
55+
ASSERT_SIZE(cSPAchievementSerializer, 0xBC);
56+
}

Spore ModAPI/Spore/Resource/Paths.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ namespace Resource
3636
Plants = 0x90368EA0,
3737
Adventures = 0x86CA01C9,
3838
CityMusic = 0x500EFC6,
39+
/// Pollination.package
3940
Cache = 0x11AC19C,
4041
Server = 0x11AC19D,
4142
Planets = 0x31389B5,

0 commit comments

Comments
 (0)