Achievement system fixes and stackable chanceboxes.

This commit is contained in:
Mari the Deer 2022-01-11 02:18:38 +01:00
commit 35b0ad1b2b
10 changed files with 126 additions and 37 deletions

View file

@ -448,7 +448,6 @@ extend Class SWWMHandler
StatusBar.AttachMessage(m,-1232);
CVar.FindCVar('swwm_oldcheat').SetBool(true);
}
SWWMUtility.MarkAchievement("cheat",players[consoleplayer]);
if ( SWWMUtility.CheatsDisabled(consoleplayer) )
{
kfail = true;

View file

@ -5,8 +5,9 @@ Class SWWMAchievementInfo
int baseindex; // sorting order in the list
String basename; // base name for identifying achievement
TextureID icon; // our icon
int maxval; // maximum value (0: no progress, -1: special scripting needed)
int maxval; // maximum value (0: no progress)
bool hasformat; // achievement description text must be formatted to add maxval
bool bitfield; // progress is tracked as a bitfield
int state, val; // set by other scripts, used to avoid excessive dictionary lookups
}
@ -23,16 +24,35 @@ extend Class SWWMStaticHandler
if ( a.maxval )
{
int prog = achievementprogress.At(a.basename).ToInt();
// special cases
if ( val && (prog < a.maxval) )
// special case for bitfields
if ( a.bitfield )
{
achievementstate.Insert(a.basename,"0");
val = 0;
int pb = 0;
for ( int i=0; i<a.maxval; i++ )
pb += !!(prog&(1<<i));
if ( val && (pb < a.maxval) )
{
achievementstate.Insert(a.basename,"0");
val = 0;
}
else if ( !val && (pb >= a.maxval) )
{
achievementstate.Insert(a.basename,"1");
val = 1;
}
}
else if ( !val && (prog >= a.maxval) )
else
{
achievementstate.Insert(a.basename,"1");
val = 1;
if ( val && (prog < a.maxval) )
{
achievementstate.Insert(a.basename,"0");
val = 0;
}
else if ( !val && (prog >= a.maxval) )
{
achievementstate.Insert(a.basename,"1");
val = 1;
}
}
}
if ( (val == 1) && (gametic > lastachievementnotify) )
@ -118,8 +138,8 @@ extend Class SWWMStaticHandler
// fallback icon if one is not found
if ( !ac.icon.IsValid() ) ac.icon = TexMan.CheckForTexture("graphics/Achievements/DefaultAchievement.png",TexMan.Type_Any);
ac.maxval = ln[1].ToInt();
// special case for maxval
if ( ac.maxval && (ac.basename == "allcoll") )
// special cases for maxval == -1 (currently only one, so this is simplified)
if ( (ac.maxval == -1) && (ac.basename == "allcoll") )
{
int nc = 0;
for ( int i=0; i<AllActorClasses.Size(); i++ )
@ -133,6 +153,12 @@ extend Class SWWMStaticHandler
}
ac.maxval = nc;
}
// bitfield
else if ( ac.maxval < -1 )
{
ac.bitfield = true;
ac.maxval = abs(ac.maxval);
}
ac.hasformat = (ln[2]~=="yes");
achievements.Push(ac);
bidx++;
@ -210,7 +236,7 @@ extend Class SWWMStaticHandler
}
achievementprogress.Insert(keys[i].Left(colon),keys[i].Mid(colon+1));
}
// load achievement info and trim any bogus keys
// load achievement info and trim any bogus keys, as well as adding any new ones that are missing
ParseAchievementList(achievementinfo);
let di = DictionaryIterator.Create(achievementstate);
while ( di.Next() )
@ -223,6 +249,11 @@ extend Class SWWMStaticHandler
deleteme = false;
break;
}
if ( deleteme )
{
if ( developer >= 2 ) Console.Printf("Deleting bogus achievement state %s = %s",key,di.Value());
achievementstate.Remove(key);
}
}
di = DictionaryIterator.Create(achievementprogress);
while ( di.Next() )
@ -236,6 +267,24 @@ extend Class SWWMStaticHandler
deleteme = false;
break;
}
if ( deleteme )
{
if ( developer >= 2 ) Console.Printf("Deleting bogus achievement progress %s = %s",key,di.Value());
achievementprogress.Remove(key);
}
}
for ( int i=0; i<achievementinfo.Size(); i++ )
{
if ( achievementstate.At(achievementinfo[i].basename) == "" )
{
if ( developer >= 2 ) Console.Printf("Adding missing achievement state %s",achievementinfo[i].basename);
achievementstate.Insert(achievementinfo[i].basename,"0");
}
if ( achievementinfo[i].maxval && (achievementprogress.At(achievementinfo[i].basename) == "") )
{
if ( developer >= 2 ) Console.Printf("Adding missing achievement progress %s",achievementinfo[i].basename);
achievementprogress.Insert(achievementinfo[i].basename,"0");
}
}
}