[v0.2.1] Stupid Achievements

Post your example zscripts/ACS scripts/etc here.
Forum rules
The Projects forums are only for projects. If you are asking questions about a project, either find that project's thread, or start a thread in the General section instead.

Got a cool project idea but nothing else? Put it in the project ideas thread instead!

Projects for any Doom-based engine (especially 3DGE) are perfectly acceptable here too.

Please read the full rules for more details.
f7cjo
Posts: 5
Joined: Thu Jul 02, 2020 8:42 am
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support
Location: poland

Re: [v0.1] Stupid Achievements

Post by f7cjo »

I can't PM, as my account is too young, here is my achievement:

Code: Select all

class ni_departure : sa_Achievement
{
  Default
  {
    sa_Achievement.name "Early Departure";
    sa_Achievement.description "Decide it's not worth it";
    sa_Achievement.borderColor 0xA30000;
    sa_Achievement.boxColor    0xff0000;
  }
}
just a small test achievment.
Here is the ACS line that causes the crash:

Code: Select all

ScriptCall("sa_Achiever", "achieve", "ni_departure");
I load the pk3 file with my achievement after the stupid achievements library. The achievements menu in the settings works fine.
User avatar
m8f
 
 
Posts: 1394
Joined: Fri Dec 29, 2017 4:15 am
Discord: m8f#0629
Github ID: mmaulwurff
Operating System: Other Linux 64-bit
Location: Siberia (UTC+7)

Re: [v0.1] Stupid Achievements

Post by m8f »

Hmm. What if you change sa_Achiever.achieve signature so it looks like this:

Code: Select all

  static
  void achieve(String achievementClass)
  {
    achievePrivate(achievementClass);
  }
in zscript/StupidAchievement.zs.

One more thing: please replace "sa_" namespace with your own.
f7cjo
Posts: 5
Joined: Thu Jul 02, 2020 8:42 am
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support
Location: poland

Re: [v0.1] Stupid Achievements

Post by f7cjo »

It works now, thank you for the help.
User avatar
m8f
 
 
Posts: 1394
Joined: Fri Dec 29, 2017 4:15 am
Discord: m8f#0629
Github ID: mmaulwurff
Operating System: Other Linux 64-bit
Location: Siberia (UTC+7)

Re: [v0.1] Stupid Achievements

Post by m8f »

Version 0.1.1 is up.
Changelog:
- fixed access to achievements from ACS.
User avatar
Laskow
Posts: 54
Joined: Tue Feb 16, 2021 7:35 am

Re: [v0.1.1] Stupid Achievements

Post by Laskow »

Can you teach me how to replace Imp by monsters? I expected it's very easy if I can use bIsMonster but it didn't work.
User avatar
m8f
 
 
Posts: 1394
Joined: Fri Dec 29, 2017 4:15 am
Discord: m8f#0629
Github ID: mmaulwurff
Operating System: Other Linux 64-bit
Location: Siberia (UTC+7)

Re: [v0.1.1] Stupid Achievements

Post by m8f »

Do you mean how to make achievements for other monsters?

You have to add checks for monster classes. Impness is checked here. This function does the following:
1. Check if something has replaced the original imp.
2. Check if this is an imp or it's inherited from imp. ZScript has this handy construction a is "DoomImp", where a is a tested actor, and the class is after is.
3. If any of above is true, consider this thing an Imp.

When you have similar functions for other monsters (or even generalized function which takes checked monster class as a string parameter), you can use them in event functions in EventHandler (the ones with override) and give the corresponding achievements.
User avatar
Laskow
Posts: 54
Joined: Tue Feb 16, 2021 7:35 am

Re: [v0.1.1] Stupid Achievements

Post by Laskow »

Yes, and for all actors who used the flag "monster".

Thankfully, other monsters achievements works fine now! However, I think it's not going well actually because this code doesn't work by 2 errors:

Unknown class name 'Cultist' of type 'Actor'
Unknown identifier 'isReplacingCultist'

Code: Select all

  private
  bool isCultist(Actor a)
  {
    bool isReplacingCultist = ("Cultist" == Actor.getReplacee(a.getClass())); 
    bool isBasedOnCultist = (a is "Cultist"); 
    return (isReplacingCultist || isBasedOnCultist); 
  }

But this one works without a hitch.

Code: Select all

  private
  bool isCultist(Actor a)
  {
    bool isBasedOnCultist = (a is "Cultist");
    return (isBasedOnCultist); 
  }

Note that the actor "Cultist" is the custom one.
User avatar
m8f
 
 
Posts: 1394
Joined: Fri Dec 29, 2017 4:15 am
Discord: m8f#0629
Github ID: mmaulwurff
Operating System: Other Linux 64-bit
Location: Siberia (UTC+7)

Re: [v0.1.1] Stupid Achievements

Post by m8f »

To check for custom classes, which may or not be loaded, you need a trick: put class in a string constant, like this:

Code: Select all

  bool isCultist(Actor a)
  {
    string cultistClass = "Cultist";
    bool isReplacingCultist = (cultistClass == Actor.getReplacee(a.getClass()));
    bool isBasedOnCultist = (a is cultistClass);
    return (isReplacingCultist || isBasedOnCultist);
  }
Again, it would be even better to move classes to function parameters entirely to prevent code duplication, like this:

Code: Select all

  bool isMonsterClass(Actor a, string checkClass)
  {
    bool isReplacing = (checkClass == Actor.getReplacee(a.getClass()));
    bool isBasedOn = (a is checkClass);
    return (isReplacing || isBasedOn);
  }
User avatar
Laskow
Posts: 54
Joined: Tue Feb 16, 2021 7:35 am

Re: [v0.1.1] Stupid Achievements

Post by Laskow »

Finally it works fine.
Thank you so much for your help! I'm not an expert of ZScript so that was so helpful.
User avatar
m8f
 
 
Posts: 1394
Joined: Fri Dec 29, 2017 4:15 am
Discord: m8f#0629
Github ID: mmaulwurff
Operating System: Other Linux 64-bit
Location: Siberia (UTC+7)

Re: [v0.2.0] Stupid Achievements

Post by m8f »

Stupid Achievements updated to v0.2.0. New version has icon support (thanks to Laskow!).
User avatar
Laskow
Posts: 54
Joined: Tue Feb 16, 2021 7:35 am

Re: [v0.2.0] Stupid Achievements

Post by Laskow »

Screenshot_Doom_20211015_013525.jpg
I made some icons for the Imp achievements. Place these icons in a graphics folder and rewrite a few lines of "ImpAchievements.zs" like this:

Code: Select all

    sa_Achievement.lockedIcon "graphics/sa_Limp1kill.png";
    sa_Achievement.unlockedIcon "graphics/sa_Uimp1kill.png";
ImpAchievements_Icons.zip
Enjoy!

I'll delete this file if there are any problems.
You do not have the required permissions to view the files attached to this post.
User avatar
IdiotBitz
Posts: 138
Joined: Fri Apr 18, 2014 8:58 pm
Discord: catoidi#0001

Re: [v0.2.0] Stupid Achievements

Post by IdiotBitz »

Thanks for making this mod. It is pretty nifty, not gonna lie. I really like the new icon support as well. This will be very handy for a project im working on.

There is this one bug I found, though: If you try to save your game while an achievement notification is playing, the save will fail and it will display this message:
"Attempt to save pointer to unhandled type NativeStruct<Font>"

Here's a screenshot of the bug in action:


I was able to fix the bug on my end by doing this:
Spoiler:
User avatar
m8f
 
 
Posts: 1394
Joined: Fri Dec 29, 2017 4:15 am
Discord: m8f#0629
Github ID: mmaulwurff
Operating System: Other Linux 64-bit
Location: Siberia (UTC+7)

Re: [v0.2.1] Stupid Achievements

Post by m8f »

Thanks for the heads up!

Stupid Achievements updated to v0.2.1.

Changelog:
- fixed saving and loading while achievement is on screen;
- fixed minor icon misalignment.
XLightningStormL
Posts: 373
Joined: Mon May 09, 2016 1:38 am
Twitch ID: XLightmingStormL

Re: [v0.2.1] Stupid Achievements

Post by XLightningStormL »

Is there a way I can get only one achievement to reset? As in, say a pacifist episode run, if the first level progresses the achievement by one, but in the next level the player kills an enemy the progress of that achievement will reset back to zero.
User avatar
m8f
 
 
Posts: 1394
Joined: Fri Dec 29, 2017 4:15 am
Discord: m8f#0629
Github ID: mmaulwurff
Operating System: Other Linux 64-bit
Location: Siberia (UTC+7)

Re: [v0.2.1] Stupid Achievements

Post by m8f »

You will have to edit the code.
  1. In sa_Achiever.updateAchievementState, add function parameter isReset:

    Code: Select all

      int, int updateAchievementState(readonly<sa_Achievement> achievement, bool isReset)
  2. In sa_Achiever.updateAchievementState, add conditional counter reset: instead of

    Code: Select all

        ++count;
    Make it

    Code: Select all

        if (isReset)
        {
          count = 0;
        }
        else
        {
          ++count;
        }
  3. In sa_Achiever.achievePrivate, add function parameter:

    Code: Select all

      void achievePrivate(Class<sa_Achievement> achievementClass, bool isReset = false)
  4. In sa_Achiever.achievePrivate, pass this parameter to updateAchievementState.

    Code: Select all

        [count, state] = updateAchievementState(achievement, isReset);
  5. Add public function sa_Achiever.reset:

    Code: Select all

      static
      void reset(String achievementClass)
      {
        achievePrivate(achievementClass, true);
      }

Return to “Script Library”