Additional Achievements

Troller0001

I've anxiously awaited your arrival!
Joined
Mar 9, 2016
Messages
755
Location
The Netherlands
So well, title says it all. This mod adds Additional Achievements! (not as if the base game had enough of those already)
These achievements are designed to work in Modded Games though, and allow other mods to add achievements themselves too! (More on that Below)
I have not tested this in multiplayer, though I suspect that it'll be compatible as this is pretty much only an Interface Mod.
Achievement difficulty ranges from easy (Settle your Capital City), to difficult (The Germany Zero City Challenge), to oddly specific (As France, perform a Concert Tour in the lands of a Civilization with whom you ware at war)!

A download (.civ5mod) can be found here. A steam Download Link can be found here


An overview of all the Achievements (A description, icon, if it's unlocked, etc.) can be found in the Achievopedia, which you can open up via the DiploCorner dropdown (similar to how Info Addict or the Demographics are opened up). Achievements can be sorted or hidden, depending on which options were selected.

The Achievopedia:

Spoiler :




Open up the Achievopedia via the DiploCorner dropdown:
Spoiler :




Achievements can be sorted by Name, whether they're unlocked, or ModName. The sorting can be reversed as well by checking the respective checkbox.
Spoiler :



Spoiler :

No Search Results:



Hovering over the 'green plus' or 'blue download' icon in the Achievopedia shows you which mod added an Achievement, and which mods are required to be enabled in order to unlock it. This means that mod A can add an achievement for mod B!
Spoiler :




When an Achievement is unlocked, a custom popup shows up (as of v3). This popup shows the Achievement's icon, it's title, and of course what you actually did to unlock it.
Spoiler :



In v2 and earlier, this was a tad bit different though
Spoiler :

When an Achievement is unlocked, a Notification is provided in the sidepanel as well.
NOTE: This support is dropped as of V3. The old code is still in the files though, so if you're interested feel free to take a look anyways.
A Notification in the Sidepanel
Spoiler :






As of V2, tabs are also included! Tabs allow mods to actually organize their Achievements!
Spoiler :




Achievements work across games/playthroughs, meaning that this mod stores unlocked achievements.

WARNING: Achievement data is stored in the ModUserData, so clearing that will clear your achievement progress! You can copy TRL_Additional_Achievements-1.db to another location on your computer to create a backup though.

Special thanks:
  • Special thanks to Whoward for his excellent UI tutorials! They made this all possible!
  • Special thanks to Salazar (a.k.a. saigon1983) and UltraWorlds for providing the Russian Localization


Adding your own Achievements

See the Tutorial in Post #2

List of Achievements
This post contains a List of Achievements added by this mod. The initial version number is included before each section.

34 Achievements were added in Total.

Suggestions of Achievements can be made here as well. Just comment below ;)
Spoiler :

V1 (21 Total)
  • The start of a Grand Empire: Settle your Capital City
  • The Germany No City Challenge: Using Bismark''s Unique Ability, capture a city by using only converted Barbarian units and your starting units, all while not settling any city yourself
  • In a Parallel Universe: While playing as Mongolia, build the Great Wall and have China delcare War on you.
  • Shouldn''t you go to sleep?: Play 200 turns in a single session
  • Who run the World?: Win a game with only Female Leaders enabled.
  • Masculine Manpower: Win a game with only Male Leaders enabled.
  • City States, Unite!: Win a game with 41 City States on the Map
  • Naturally Wonderful: While playing as Spain, have every Natural Wonder in your Borders.
  • City States can't keep secrets: Receive a Unique Unit normally not available to you from an allied Millitaristic City State
  • Pacifist: Win a game without ever being at war.
  • Rocketman: Have the city with the Pentagon get nuked
  • Together we are Stronger: Win a game with someone else on your team.
  • Constitution Completed: Acquire every Ideological Tenet of a single Ideology in a single Game.
  • GreenPeace: Embargo a Civilization which has more Factories than you.
  • Holiest of All: Construct the Hagia Sophia, Borobudur, the Great Mosque of Djenne, and the Grand Temple in a single city.
  • Mass Prayer: Construct a Monastery, a Mosque, a Cathedral, and a Pagoda in a single city.
  • Sacred City: Found a Religion in another city than your capital.
  • Helping Hand: Buy a Missionary without actually founding a Religion yourself.
  • Liberte, Egalite, Beyonce?: While playing as France, use a Great Musician to perform a Conert Tour in the lands of a Civilization with whom you are at war.
  • Deus Vult! Conquer Jerusalem.
  • Snagged: Use the Great Prophet from the Hagia Sophia to snag away the last Religion.
(This text allows you to expand this block!)

V2 (13 Total)
  • Nuke the World: Have an AI Gandhi show his true side...
  • I don''t know what I expected: Select ''None'' in the ''Show Mods'' options of the Achievopedia.
  • Are these all your friends?: Open a Tab that contains no Achievements
  • Evil Twin: Win a Duel against the same Civilization
  • World War: On a Standard Map or Bigger, have every Civilization be at War (City States can still be at Peace however)
  • This is for YOUR Protection!: Become Allies with a City State that controls more Cities than you
  • Nobody'll notice, if there is nobody to notice: Control every city on the map, City States included, you damnedest Warmonger!
  • A New Challenger Has Appeared! Have a City State take control over another Civilization''s Capital
  • If only my Car had Wheels: Discover an Ancient or Classical Era Technology while in the Industrial Era or later.
  • MEDIC!: Have Five (or more) Units in your Army with the Medic II Promotion
  • One small Step for Man: As America, win a science victory by 1969
  • Anime for Ameri-kun: As Japan, become Influential over America''s Culture
  • Say Hello to my Little Friend: Have an Allied City State take over a City of someone with whom you are at War.
(This text allows you to expand this block!)



(If you're looking for a Download, it's provided in this resource from now on rather than at the bottom of this post)
 
Last edited:
TUTORIAL: Adding your own Achievements (v4):
Part 1

As briefly mentioned in the introduction, the system was designed in such a way that other mods can add Achievements as well. You can create your more complex Lua-required achievements, or add basic achievements that require no Lua-knowledge whatsoever!

Here's how: First go to the Associations-Tab of your mod's properties, and add a Reference to Additional Achievements (ModID: 432bc547-eb05-4189-9e46-232dbde8f09f). This ensures that Additional Achievement loads first, creating all necessary tables for you.

For those without Lua experience, there are some (very limited) possibilities that need XML/SQL only.
These include:
  • Unlock the achievement when you win as a specific civilization. (RequiredCivWin)
  • Unlock the achievement when you lose as a specific civilization. (RequiredCivLoss)
  • Unlock the achievement when you eliminate a specific civilization from play. That is, take their last city (or destroy their last unit if 'Complete Kills' is turned on). (RequiredCivKill)

Since all of these follow a similar process to get them to work, I will only give an example of the top one.
Suppose I want to add the following achievement:
Arrrgh! I'm tired of this speech!
which will unlock when you win as The Whomp King (from my Whomp's Fortress Civilization).

It may sound odd, but first you'll need to "define your mod".
You'll need 4 things for that:
  1. A unique identifier. E.g. MOD_TRL_WHOMPS_FORTRESS. A general rule of thumb with any unique identifier is to add your name's abbreviation to the identifier, which for me (Troller0001) is TRL. Doing so lowers the chances of getting duplicate identifiers significantly, which will cause issues.
  2. The name of your mod. Quite self-explanatory if you'd ask me.
  3. The ModID of your mod. Also quite self-explanatory if you'd ask me.
  4. Your name (and the name(s) of other authors), separated by commas. NOTE: Author(s) are not yet used in this version, but might be in the future.
Example using XML (SQL is possible too):
Spoiler :

Code:
<GameData>
    <Language_en_Us>
        <Row Tag="TXT_KEY_MOD_TRL_WHOMPS_FORTRESS_NAME">
            <Text>Whomp's Fortress</Text>
        </Row>
        <Row Tag="TXT_KEY_MOD_TRL_WHOMPS_FORTRESS_MODID">
            <Text>ffffffff-ffff-ffff-ffff-ffffffffffff</Text>
        </Row>
        <Row Tag="TXT_KEY_MOD_TRL_WHOMPS_FORTRESS_AUTHORS">
            <Text>Troller0001, Troller0002, Troller0003</Text>
        </Row>
   </Language_en_Us>
   <AdditionalAchievements_Mods>
        <Row>
            <Type>MOD_TRL_WHOMPS_FORTRESS</Type>
            <ModName>TXT_KEY_MOD_TRL_WHOMPS_FORTRESS_NAME</ModName>
            <ModID>TXT_KEY_MOD_TRL_WHOMPS_FORTRESS_MODID</ModID>
            <Authors>TXT_KEY_MOD_TRL_WHOMPS_FORTRESS_AUTHORS</Authors>
        </Row>
   </AdditionalAchievements_Mods>
</GameData>
As with most other XML-files, this'll need an OnModActivated->UpdateDatabase entry in the Action-tab of your mod's properties.


With that being done, let's actually define the achievement now.
As a bare minimum, we'll need the following things:
  1. A unique identifier for the achievement (remember the rule of thumb!)
  2. The name of the achievement, also known as the 'header text'
  3. A description for the achievement. I.e. a description of how you actually unlock it
  4. An icon-atlas to find the icon for when the achievement is unlocked. The icon atlas should at least contain an icon sheet of 80*80px icons. Even though 256*256px icons are not used in this version, I still advise you to also include those as I might use those as well in a future version.
  5. A portraitIndex, which is the index in the icon atlas where the actual icon can be found. (So exactly the same to how an IconAtlas and PortraitIndex work for units, buildings, techs, civs, leaders, etc.)
  6. The unique identifier of the mod that adds the achievement. (I told you we needed to start by defining your mod! ;))

But the following things can also be added (though are advised to be omitted if you're using the default values):
  1. The version of your mod in which the achievement was added. By leaving this out it will not be displayed.
  2. An unlock-sound of your achievement. It defaults to the 'Ancient Ruins found'-sound.
  3. The duration (in ms) of the popup when the achievement is unlocked. It defaults to -1, meaning that the user needs to dismiss the popup manually by Right-clicking it. Using a value of 0 prevents the popup from showing.
  4. Whether the icon's border should be hidden. In some cases the icon looks better if the border is omitted.
There are some more options, but those are not really that useful. They are however documented in Achievements.sql in the mod's files, so feel free to check them out there.

We'll also need to define when we unlock the achievement. I.e. with which win as a specific civilization.
This'll simply be the civilizationType of that civ.

Example (XML):
Spoiler :

Code:
<GameData>
    <Language_en_Us>
        <Row Tag="TXT_KEY_AA_TRL_TIRED_OF_THIS_SPEECH_HEADER">
            <Text>Arrrgh! I'm tired of this speech!</Text>
        </Row>
        <Row Tag="TXT_KEY_AA_TRL_TIRED_OF_THIS_SPEECH_TEXT">
            <Text>Win as the Whomp King</Text>
        </Row>
   </Language_en_Us>
   <AdditionalAchievements>
        <Row>
            <Type>AA_TRL_TIRED_OF_THIS_SPEECH</Type>
            <Header>TXT_KEY_AA_TRL_TIRED_OF_THIS_SPEECH_HEADER</Header>
            <Achievopedia>TXT_KEY_AA_TRL_TIRED_OF_THIS_SPEECH_TEXT</Achievopedia>
            <IconAtlas>EXTENDED_RESOURCE_ATLAS</IconAtlas> <!--We're using the stone resource icon here-->
            <PortaitIndex>0</PortraitIndex>
            <ModType>MOD_TRL_WHOMPS_FORTRESS</ModType>
            <ModVersion>2</ModVersion>
            <RequiredCivWin>CIVILIZATION_TRL_WHOMPS_FORTRESS</RequiredCivWin>
        </Row>
   </AdditionalAchievements>
</GameData>
As with most other XML-files, this'll need an OnModActivated->UpdateDatabase entry in the Action-tab of your mod's properties.

And that is everything for the bare minimum. There are however two additional tables that you may wish to populate, which are explained in part 2 of this tutorial.

-------------------------
Part 2
The first extra table you may wish add data contains which mods are required to unlock the achievement you just added. This is not useful at all if you can only unlock the achievement if the mod that adds it is enabled, but if you're adding achievements that can only be unlocked when another mod is active too this can prove to be quite useful!
Therefore, see the example below (XML):
Spoiler :

Code:
<GameData>
   <AdditionalAchievements_ModsRequired>
        <Row>
            <AchievementType>AA_TRL_HITLER_BEFRIEND_KING_BOB_OMB</AchievementType> <!-- achievement that requires the mod -->
            <ModType>MOD_TRL_BOB_OMB_BATTLEFIELD</ModType> <!-- The unique identifier for a mod that is required -->
            <ModMinVersion>1</ModMinVersion> <!--column can be omitted-->
            <ModMaxVersion>3</ModMaxVersion> <!--column can be omitted-->
        </Row>
        <Row>
            <AchievementType>AA_TRL_HITLER_BEFRIEND_KING_BOB_OMB</AchievementType> <!-- achievement that requires the mod -->
            <ModType>MOD_JFD_HITLER</ModType>
        </Row>
   </AdditionalAchievements_ModsRequired>
</GameData>
As with most other XML-files, this'll need an OnModActivated->UpdateDatabase entry in the Action-tab of your mod's properties.
With the above, the achievement 'AA_TRL_HITLER_BEFRIEND_KING_BOB_OMB' requires the "Bob-omb Battlefield"-mod and JFD's Hitler mod to be active


If you're adding a lot of achievements, it may also be useful to organize them all in a single place: a tab!
You'll need to define 3 things for a tab:
  1. A unique identifier (wow, we're using a lot of these)
  2. The tab's name
  3. The tab's description.
(There are some more things you could use, but those are not important and are documented in Achievements.sql anyways)

Example (XML):
Spoiler :

Code:
<GameData>
    <Language_en_Us>
        <Row Tag="TXT_KEY_TAB_TRL_SUPER_MARIO_64_ACHIEVEMENTS_HEADER">
            <Text>Super Mario 64 Achievements</Text>
        </Row>
        <Row Tag="TXT_KEY_TAB_TRL_SUPER_MARIO_64_ACHIEVEMENTS_DESCRIPTION">
            <Text>Achievements based around Civilizations from Super Mario 64</Text>
        </Row>
   </Language_en_Us>
   <Achievopedia_Tabs>
        <Row>
            <Type>TAB_TRL_SUPER_MARIO_64_ACHIEVEMENTS</Type>
            <Header>TXT_KEY_TAB_TRL_SUPER_MARIO_64_ACHIEVEMENTS_HEADER</Header>
            <Description>TXT_KEY_TAB_TRL_SUPER_MARIO_64_ACHIEVEMENTS_DESCRIPTION</Description>
        </Row>
   </Achievopedia_Tabs>
</GameData>
As with most other XML-files, this'll need an OnModActivated->UpdateDatabase entry in the Action-tab of your mod's properties.


And to get our achievement to show up in our newly created tab, we only need the Achievement and the Tab!

Example (XML):
Spoiler :

Code:
<GameData>
   <AdditionalAchievements_Tabs>
        <Row>
            <AchievementType>AA_TRL_TIRED_OF_THIS_SPEECH</AchievementType>
            <TabType>TAB_TRL_SUPER_MARIO_64_ACHIEVEMENTS</TabType>
        </Row>
   </AdditionalAchievements_Tabs>
</GameData>
As with most other XML-files, this'll need an OnModActivated->UpdateDatabase entry in the Action-tab of your mod's properties.

Your achievement can appear in as many tabs as you like, but if you assign it to no tab at all then it will automatically appear in the 'other'-tab!

And that's pretty much all the basics there are, good luck!

----------------------------------------------------
Part 3
And now for part 3, the actual cool stuff: way more specific and unique achievements, as far as your imagination* reaches!

*or well, the modded DLL

Note that this part requires you to understand part 1 and 2 of this tutorial, and that you have some Lua knowledge.

Suppose we want to add the following achievement:
C'mon and slam
which unlocks when you train the "Whomp", a unique unit for Whomp's Fortress.

First we'll need to add the Utility file that does all the difficult stuff for us such as syncing with other mods, providing functions, etc. (and at the same time ensures that you can't simply break the system with a single typo ;))
Copy the text in the spoiler below, and add it to a new Lua file with VFS=true and NO InGameUIAddin. Ensure that the file is named "AdditionalAchievementsUtility.lua"!
Spoiler :
Code:
-- AdditionalAchievementsLua
-- Author: Troller0001
-- DateCreated: 11/11/2016 9:06:24 PM
--------------------------------------------------------------
print("AdditionalAchievementsUtility.lua was included into VFS by a file!");

--Opens the ModUserData of Additional Achievements
function OpenAAModUserData()
    --print("Mod user data opened up")
    local iModVersion = 1;
    local sModID = "TRL_Additional_Achievements";
    --global
    modUserData = Modding.OpenUserData(sModID, iModVersion);
end

--===========================================================================

--store the achievements in a lua table so we dont have to check the database each time (prevents lag!)
tAchievements = {}

--Initializes the Achievements Table
--Loops through the database and ModUserData and stores all achievements in the table.
function InitializeAchievementsTable()
    --Open the ModUserData
    OpenAAModUserData();
    --Loop through the Achievements-table
    for row in GameInfo.AdditionalAchievements() do
        --Check the ModUserData and copy the value from there
        tAchievements[row.Type] = modUserData.GetValue(row.Type);
        --if there is nothing to copy (I.e. nil), then we set tAchievements[row.Type] = 0. I.e. the Achievement is still locked
        if tAchievements[row.Type] == nil then
            tAchievements[row.Type] = 0;
            --print((row.Type).." was not yet unlocked");
        end
        --print((row.Type).." has been added to the Lua-table! (Unlocked: "..(tAchievements[row.Type])..")");
    end
end
InitializeAchievementsTable()


--Returns true if a given Achievement is unlocked, returns false otherwise
function IsAAUnlocked(iAchievement)
    if iAchievement ~= nil then
        if tAchievements[iAchievement] == 1 then
            return true;
        end
    else
        print("ERROR: iAchievement in IsAAUnlocked(iAchievement) cannot be nil!");
    end
    return false;
end

--==============================================================================================
--The following functions are related to synching the Achievement-tables between different mods

--[[
The LuaEvents below can be subscribed to (LuaEvent.whatever.Add(function name)) just
like GameEvents (E.g. GameEvents.PlayerDoTurn.Add(function name)).

No idea why you would want to do this, but it's there if you feel like it

Summary of the LuaEvents:
- LuaEvents.EventResetAllAA();                                    Fires whenever a mod resets all achievements
- LuaEvents.EventResetModAA(sModID);                                Fires whenever a mod resets all achievements from a specific mod
- LuaEvents.EventUnlockAA(iAchievement);                            Fires whenever a mod unlocks an achievement
- LuaEvents.EventLockAA(iAchievement);                            Fires whenever a mod locks an achievement
- LuaEvents.EventAchievementTableUpdated(tUpdatedTable);            Fires whenever any of the above happens.

See the code below for more specific details.
--]]

--resets all achievements. WARNING: This CANNOT be undone!
--use the lockachievement function to lock a specific achievement
function ResetAllAA()
    print("Resetting all achievements...");
    for iAchievement,bUnlocked in pairs(tAchievements) do
        if bUnlocked==1 then
            modUserData.SetValue(iAchievement,0);
            print((GameInfo.AdditionalAchievements[iAchievement].Type).." reset in the ModUserData");
        end
    end
    print("Every achievement has been reset!");

    --A mod has reset all achievements, so all other mods need to know this as well (to stay synced!)
    LuaEvents.EventResetAllAA();
    LuaEvents.EventAchievementTableUpdated(tAchievements);
end

--Executes whenever any mod resets all achievements
--Note to Modders: Never call this function; it's called automatically. (Never call ANY SyncSomething function)
function SyncResetAllAA()
    --print("Another mod is resetting all achievements...");
    for iAchievement,bUnlocked in pairs(tAchievements) do
        --only lock it if we had already unlocked it
        if bUnlocked==1 then
            tAchievements[iAchievement] = 0;
            print((GameInfo.AdditionalAchievements[iAchievement].Type).." reset");
        end
    end
    --print("A mod has reset all achievements!");
end
LuaEvents.EventResetAllAA.Add(SyncResetAllAA);


--Resets all achievements from a given modID.
--Note to Modders: You can use this function to debug if you add your own achievements, without interfering with your own achievement-data
--WARNING: This cannot be undone
function ResetModAA(sModID)
    print("Resetting all achievements from the mod with ID="..sModID.."...");
    for iAchievement,bUnlocked in pairs(tAchievements) do
        if bUnlocked==1 and GameInfo.AdditionalAchievements[iAchievement].ModID == sModID then
            modUserData.SetValue(iAchievement,0);
            print((GameInfo.AdditionalAchievements[iAchievement].Type).." reset in the ModUserData");
        end
    end
    print("Reset all achievements from the mod with ID="..sModID.."!");
 
    --A mod has reset all events from a specific mod, so all other mods need to know this as well (to stay synced!)
    LuaEvents.EventResetModAA(sModID);
    LuaEvents.EventAchievementTableUpdated(tAchievements);
end

--Fires whenever any mod resets all achievement from a specific mod
--Note to Modders: Never call this function; it's called automatically. (Never call ANY SyncSomething function)
function SyncResetModAA(sModID)
    --print("A mod is resetting all achievements from the mod with ID="..sModID.."...");
    for iAchievement,bUnlocked in pairs(tAchievements) do
        --only lock it if we had already unlocked it
        if bUnlocked==1 and GameInfo.AdditionalAchievements[iAchievement].ModID == sModID then
            tAchievements[iAchievement] = 0;
            print((GameInfo.AdditionalAchievements[iAchievement].Type).." reset");
        end
    end
    --print("A mod has reset all achievements from the mod with ID="..sModID.."!");
end
LuaEvents.EventResetModAA.Add(SyncResetModAA);

--Unlocks a given achievement
--returns false if error or already unlocked, returns true otherwise
function UnlockAA(iAchievement)
    if iAchievement then
        if GameInfo.AdditionalAchievements[iAchievement] == nil then
            print("ERROR: "..iAchievement.." does not exist within Achievements!");
            return false;
        else
            if not IsAAUnlocked(iAchievement) then
                print((GameInfo.AdditionalAchievements[iAchievement].Type).." has been unlocked!");
                modUserData.SetValue(iAchievement,1);
                LuaEvents.EventUnlockAA(iAchievement);
                LuaEvents.EventAchievementTableUpdated(tAchievements);
                return true;
            end
            print((GameInfo.AdditionalAchievements[iAchievement].Type).." was already unlocked!");
            return false;
        end
    end
    print("ERROR: iAchievement in UnlockAA( function(iAchievement)...) may not be nil!");
    return false;
end

--Fires whenever an achievement is unlocked TODO: multiplayer: LuaEvent fires for every player -> need ActivePlayer-check????
--Note to Modders: Never call this function; it's called automatically. (Never call ANY SyncSomething function)
function SyncUnlockAA(iAchievement)
    --print("A mod Unlocked "..iAchievement);
    tAchievements[iAchievement] = 1;
end
LuaEvents.EventUnlockAA.Add(SyncUnlockAA);


--Locks a given achievement;
--returns false if error or already locked, returns true otherwise
function LockAA(iAchievement)
    if iAchievement then
        if GameInfo.AdditionalAchievements[iAchievement] == nil then
            print("ERROR: "..iAchievement.." does not exist within Achievements!");
            return false
        else
            print((GameInfo.AdditionalAchievements[iAchievement].Type).." has been Locked!");
            modUserData.SetValue(iAchievement,0);
            LuaEvents.EventLockAA(iAchievement);
            LuaEvents.EventAchievementTableUpdated(tAchievements);
            return true
        end
    end
    print("ERROR: iAchievement in LockAA( function(iAchievement)...) may not be nil!");
    return false
end

--Fires whenever an achievement is locked
--Note to Modders: Never call this function; it's called automatically. (Never call ANY SyncSomething function)
function SyncLockAA(iAchievement)
    --print("A mod Locked "..iAchievement);
    tAchievements[iAchievement] = 0;
end
LuaEvents.EventLockAA.Add(SyncLockAA);

On to the actual coding! Create a new Lua file with VFS=false and an InGameUIAddin, and add the following to it
Code:
print("MyLua.lua has been loaded!");
--This file is a great example on how to do the Lua for modsupport of Additional Achievements.

--this loads the utility file, and allows us to use its functionality:
include("AdditionalAchievementsUtility");

In the same way you can code Uniques for a civilization using Lua hooks, you can also code in achievements.
E.g. using the GameEvents.CityTrained that fires whenever a new unit is trained in a city
Apart from that, the Utility file provided us with useful functions, such as:
Code:
IsAAUnlocked('AA_TRL_CMON_AND_SLAM') --returns true if 'AA_TRL_CMON_AND_SLAM' is unlocked. Returns false otherwise.
UnlockAA('AA_TRL_CMON_AND_SLAM')     --Unlocks 'AA_TRL_CMON_AND_SLAM'
LockAA('AA_TRL_CMON_AND_SLAM')       --Locks 'AA_TRL_CMON_AND_SLAM' (useful for debugging)
ResetModAA(ModID)                    --Locks all achievements provided by ModID (useful for debugging)
ResetAllAA()                         --Locks all achievements. Avoid using this, as you'll reset your own progress as well!
You generally only need the top two to get your achievement to work though. The others are pretty useful for debugging though!

By combining the above knowledge, we use the following to code the achievement:
Spoiler :
Code:
print("MyLua.lua has been loaded!");
--This file is a great example on how to do the Lua for modsupport of Additional Achievements.

--this loads the utility file, and allows us to use its functionality:
include("AdditionalAchievementsUtility");


--====================================================
--Additional Achievements mod-support.

local iWhomp = GameInfoTypes.UNIT_TRL_WHOMP;

function checkWhompTrain(iPlayer, _, iUnit)
    --if the achievement is not unlocked, and the active player is the player who trained the unit
    if not IsAAUnlocked('AA_TRL_CMON_AND_SLAM') and iPlayer == Game.GetActivePlayer() then
        --we only need to check for the active player, which is the human player.
        local pPlayer = Players[iPlayer];
        local pUnit = pPlayer:GetUnitByID(iUnit);
        if pUnit:GetUnitType() == iWhomp then
            UnlockAA('AA_TRL_CMON_AND_SLAM');
        end
    end
end

--C'mon and slam: Train a Whomp Unique Unit.
if not IsAAUnlocked('AA_TRL_CMON_AND_SLAM') then
    GameEvents.CityTrained.Add(checkWhompTrain);
end
And that's pretty much all there is to it! Pretty easy right?

There are many more examples in the actual mod itself though! Literally every achievement you can get is coded in some similar way to this!
So well, Good Luck with adding your own achievements. I hope this tutorial has been of use!

If anything was unclear, then don't hesitate and ask a question in the comments below!


Changelog


V1
(6-11-17)
  • Initial Release to CivFanatics and the Steam Workshop
  • 21 Achievements were added (see the list above)

V2 (19-11-17)
  • Tabs are added to the Achievopedia. Achievements can be added to one or more tabs, allowing other mods to organize their achievements better.
  • Russian localization has been added. (Provided by Salazar a.k.a. saigon1983, special thanks to him!
  • 13 More Achievements were added, though they lack custom icons as of now. (See the list above to see which ones were added)

V3 (9-8-18)
Changelog:
  • -Achievements now have a custom popup (with a sound and duration), and do not appear in the SidePanel anymore.
  • It's no longer possible to sort based on ModID (which nobody ever used anyway)
  • Improved sorting.
  • Added icons for achievements added in v2.
  • Added more achievements (and their respective icons), including the first JFDLC achievement: A Chrisymas Miracle!
  • Versions for required mods are now visible.
  • Some achievements now do not show the standard icon border such that their icons look less awful.
Modder's Updates:
  • A 'hidden' column was added. Hidden achievements don't show up in the Achievopedia, even when unlocked.
  • A minor update to the Utility file was released to reduce the number of 'prints' that show up in Lua.log
  • A minor update to the Database-columns was made. It reduces repetition and adds some additional info.
  • Achievement's icon frames can be hidden by setting 'hiddenBorder' to 1.

Buxfixes:
  • 'Contitution Complete'-Achievement can now also be unlocked when adopting all policies in Autocracy or Order, rather than in Freedom only
  • Fixed a typo on 'Nobody'll notice, if there's nobody to notice'
  • 'Are these all your friends?' renamed to 'Error 404: Achievements not found'
  • Fixed an issue where sorting by "Unlocked Achievements first" threw an error
  • Fixed an issue where sorting by "Unlocked Achievements first", "ModName", or "ModID" did not sort completely correctly.
  • Fixed an issue where UPPERCASE had priority over lowercase when sorting.
  • Fixed an issue where "Required Mods to Unlock this Achievement:" was displayed, even if there were no required mods
  • The SQL-file containing the Russian Localization is now encoded using UTF-8, such that the translations are no longer replaced by something along the lines of: '???'

Known Bugs:
  • There is some Russian Localization missing, but a small patch will follow soon.

V4 (Current Version) (29-8-18)
UI Updates:
  • "Required Mods" are no longer shown on a tooltip when hovering over an Achievement. Instead, hovering over a separate icon reveals this information.
  • UI Options are now shown on the right instead of the UI-banner.
  • The Achievopedia can now be closed using <Esc>
  • The Achievopedia no longer opens on Game Start or Game Load. (This can be re-enabled in the Achievopedia)
  • On Game Start/Game Load, a Notification is displayed in the SidePanel, explaining how to open the Achievopedia. (This can be disabled in the Achievopedia)
  • The Achievopedia is now wider (allowing for longer Achievement titles and descriptions too) - The Tabs-list on the left has been updated slightly.
  • More UI options were added: Open Achievopedia on Game Start/Load, and Show Notification in Sidepanel on Game Start/Load
Miscellaneous:
  • Screenshots on the CFC-thread and Steam Workshop page updated to reflect the latest additions.
  • Steam Workshop Icon updated and finalized
  • Added missing Russian localization (special thanks to UltraWorlds for providing it)
Bugfixes:
  • A Chrisymas Miracle is now only unlocked when playing with JFDLC, as opposed to having any mod installed whatsoever.
  • 'JFDLC' is no longer referenced, allowing 'JFDLC' to load after 'Additional Achievements' if it's referenced there.
 
Last edited:
Hello! Intresting mod!
And this is russian localization (by me "Salazar aka saigon1983"):
Small issue: need tag fo "Reverse sortig", because in is hardcoded in Achievopedia.xml and appears in english in russian game too
Thanks for the localization and thanks for pointing that issue out! I'll be adding your Localization in the next version, alongside a textkey for the Reversed Sorting! (will be coded as TXT_KEY_AA_REVERSE_SORTING).
I'll be sure to mention you in the credits! :goodjob:
 
You were at the verge of winning the game with a Science Victory, but then you saw it, popping up right there in the NotificationPanel: Achievement Unlocked: Nuke the World. At this point you knew it was lost, Gandhi had unleashed his inner beast, there was no way to stop him now. You could hear him laughing from your chair, that evil, disturbing laugh. All was lost now, that was for sure. But hey, at least you got an Achievement for it!
---

I'm happy to announce that V2 of Additional Achievements has just been released! :D
This version includes: Tabs, Russian Localization, and 13 more achievements! For more info view the changelog above!
Special thanks to Salazar for the Russian Localization, and special thanks to those who suggested achievements! :D
 
Last edited:
v3 of Additional Achievements is now Up and Running! This update drops support for the notification Panel, and now instead utilizes a whole new custom popup to show the achievement you just unlocked.
Apart from improved sorting, many bugfixes, and some significant Database and display updates, this version also adds the first JFDLC-achievement: A chrisymas Miracle!
You can view the change Notes in the first or second post of this thread (some of which are related to adding your own achievements).

Plans for v4:
- Add a bunch JFDLC Achievements
- Update some of the v1 and v2 achievement icons.
 
Last edited:
v4 has been released! This update includes quite a significant UI-update (everything is more polished now), as well as some bugfixes and 'Quality of Life' changes. Head over to the Change Notes for a full and complete list.

There are no concrete plans for v5.
 
Top Bottom