From e1ee4c0b6687a86c378c744103b03a1426e34fef Mon Sep 17 00:00:00 2001 From: Quote <94698137+ChronoQuote@users.noreply.github.com> Date: Sun, 28 Aug 2022 04:45:13 -0700 Subject: [PATCH 1/5] Improve save compatibility system + extra changes -Replace CompatibleNumber system with CompareVersions utility function to improve version checking; with the new OldestSupportedVersion global, this also makes it simpler to check whether a save is outdated A save file's CompatibleNumber represented the oldest version whose saves were still compatible with the given save's version *without any modifications to Save.bb*. If an update to the game didn't affect save compatibility, not updating CompatibleNumber allowed devs to update VersionNumber without having to add any checks for the new version in Save.bb. This is because version checks in Save.bb used CompatibleNumber instead of VersionNumber. For example, suppose 1.3.11 added a new byte to the save file. A feasible way to ensure 1.3.10 saves could still be loaded would be to only read the new byte if the save's version is 1.3.11. But if the game were updated to 1.3.12, devs would have to remember to add 1.3.12 as another version to read the new byte on. And if the game were updated all the way to 1.3.20, suddenly there is a cumbersome piece of code in each load game function that checks whether the save's version is one of 10 different values. The solution was to introduce a CompatibleNumber equal to 1.3.11, store it in every save, leave it alone every update, and check the CompatibleNumber instead of the VersionNumber when reading a save. This way, all saves from versions 1.3.11 to 1.3.20 have a CompatibleNumber of 1.3.11, and so only that original check for version 1.3.11 was all that was ever needed. But say 1.3.21 adds yet another new byte to the save file. We now have to update CompatibleNumber to 1.3.21 to accommodate the new byte, which means we now have to check for a CompatibleNumber of either 1.3.11 or 1.3.21 when reading the original new byte. If 1.3.22 adds *yet another* new byte, this becomes a check for a CompatibleNumber equal to 1.3.11, 1.3.21, or 1.3.22. Ideally we'd want to forget about that original new byte already and just read it if the save's VersionNumber is at least 1.3.11. This is exactly what CompareVersions can do. While CompatibleNumber only lets us check whether a save's version falls within a specific period of compatible versions, CompareVersions lets us check any range of versions we want. CompareVersions is based off of the compare functions of other popular languages. -Fix VersionNumber not being stored in save files When CompatibleNumber was introduced, it took the place of VersionNumber in save files because CompatibleNumber was the only version number we wanted to read from them. But saves in the main menu's load game list show their version number, and we want this number to be the version the save is from, not the CompatibleNumber. Luckily, now that CompatibleNumber is gone, adding VersionNumber back into save files doesn't change the save file structure. -Update VersionNumber to "1.3.12dev" to allow us to start fixing compatibility issues with 1.3.11; note that CompareVersions has no issue with letters after a version number! --- Main.bb | 18 +++++++++++++++--- Menu.bb | 6 +++--- Save.bb | 17 ++++++++--------- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Main.bb b/Main.bb index e78b1e714..a1ede9760 100644 --- a/Main.bb +++ b/Main.bb @@ -42,8 +42,8 @@ Global UpdaterFont% Global Font1%, Font2%, Font3%, Font4%, Font5% Global ConsoleFont% -Global VersionNumber$ = "1.3.11" -Global CompatibleNumber$ = "1.3.11" ;Only change this if the version given isn't working with the current build version - ENDSHN +Global VersionNumber$ = "1.3.12dev" +Global OldestSupportedVersion$ = "1.3.10" Global MenuWhite%, MenuBlack% Global ButtonSFX% = LoadSound_Strict("SFX\Interact\Button.ogg") @@ -10647,6 +10647,19 @@ Function UpdateInfect() EndIf End Function +Function CompareVersions%(v1$, v2$) + ;Return -1 if v1 < v2 + ;Return 0 if v1 = v2 + ;Return 1 if v1 > v2 + If v1 = v2 Then Return 0 + While Int(v1) = Int(v2) + If Instr(v1, ".") Then v1 = Right(v1, Len(v1) - Instr(v1, ".")) Else v1 = "" + If Instr(v2, ".") Then v2 = Right(v2, Len(v2) - Instr(v2, ".")) Else v2 = "" + If v1 = "" And v2 = "" Then Return 0 + Wend + If Int(v1) > Int(v2) Then Return 1 Else Return -1 +End Function + ;--------------------------------------- math ------------------------------------------------------- Function GenerateSeedNumber(seed$) @@ -11766,7 +11779,6 @@ Function CatchErrors(location$) errF = WriteFile(ErrorFile) WriteLine errF,"An error occured in SCP - Containment Breach!" WriteLine errF,"Version: "+VersionNumber - WriteLine errF,"Save compatible version: "+CompatibleNumber WriteLine errF,"Date and time: "+CurrentDate()+" at "+CurrentTime() WriteLine errF,"Total video memory (MB): "+TotalVidMem()/1024/1024 WriteLine errF,"Available video memory (MB): "+AvailVidMem()/1024/1024 diff --git a/Menu.bb b/Menu.bb index a4f971f96..7cd311e64 100644 --- a/Menu.bb +++ b/Menu.bb @@ -478,7 +478,7 @@ Function UpdateMainMenu() If i <= SaveGameAmount Then DrawFrame(x,y,540* MenuScale, 70* MenuScale) - If SaveGameVersion(i - 1) <> CompatibleNumber And SaveGameVersion(i - 1) <> "1.3.10" Then + If CompareVersions(SaveGameVersion(i - 1), OldestSupportedVersion) < 0 Then Color 255,0,0 Else Color 255,255,255 @@ -490,7 +490,7 @@ Function UpdateMainMenu() AAText(x + 20 * MenuScale, y + (10+36) * MenuScale, SaveGameVersion(i - 1)) If SaveMSG = "" Then - If SaveGameVersion(i - 1) <> CompatibleNumber And SaveGameVersion(i - 1) <> "1.3.10" Then + If CompareVersions(SaveGameVersion(i - 1), OldestSupportedVersion) < 0 Then DrawFrame(x + 280 * MenuScale, y + 20 * MenuScale, 100 * MenuScale, 30 * MenuScale) Color(255, 0, 0) AAText(x + 330 * MenuScale, y + 34 * MenuScale, "Load", True, True) @@ -512,7 +512,7 @@ Function UpdateMainMenu() EndIf Else DrawFrame(x + 280 * MenuScale, y + 20 * MenuScale, 100 * MenuScale, 30 * MenuScale) - If SaveGameVersion(i - 1) <> CompatibleNumber And SaveGameVersion(i - 1) <> "1.3.10" Then + If CompareVersions(SaveGameVersion(i - 1), OldestSupportedVersion) < 0 Then Color(255, 0, 0) Else Color(100, 100, 100) diff --git a/Save.bb b/Save.bb index de5c818cf..d033d4327 100644 --- a/Save.bb +++ b/Save.bb @@ -34,8 +34,7 @@ Function SaveGame(file$) WriteFloat f, EntityPitch(Collider) WriteFloat f, EntityYaw(Collider) - ;WriteString f, VersionNumber - WriteString f, CompatibleNumber + WriteString f, VersionNumber WriteFloat f, BlinkTimer WriteFloat f, BlinkEffect @@ -505,8 +504,8 @@ Function LoadGame(file$) y = ReadFloat(f) RotateEntity(Collider, x, y, 0, 0) - strtemp = ReadString(f) - version = strtemp + version = ReadString(f) + If CompareVersions(version, OldestSupportedVersion) < 0 Then RuntimeError "Save file version not supported" BlinkTimer = ReadFloat(f) BlinkEffect = ReadFloat(f) @@ -708,7 +707,7 @@ Function LoadGame(file$) room2gw_x = ReadFloat(f) room2gw_z = ReadFloat(f) - If version = CompatibleNumber Then + If CompareVersions(version, "1.3.11") >= 0 Then I_Zone\Transition[0] = ReadByte(f) I_Zone\Transition[1] = ReadByte(f) I_Zone\HasCustomForest = ReadByte(f) @@ -1340,8 +1339,8 @@ Function LoadGameQuick(file$) y = ReadFloat(f) RotateEntity(Collider, x, y, 0, 0) - strtemp = ReadString(f) - version = strtemp + version = ReadString(f) + If CompareVersions(version, OldestSupportedVersion) < 0 Then RuntimeError "Save file version not supported" BlinkTimer = ReadFloat(f) BlinkEffect = ReadFloat(f) @@ -1547,7 +1546,7 @@ Function LoadGameQuick(file$) room2gw_x = ReadFloat(f) room2gw_z = ReadFloat(f) - If version = CompatibleNumber Then + If CompareVersions(version, "1.3.11") >= 0 Then I_Zone\Transition[0] = ReadByte(f) I_Zone\Transition[1] = ReadByte(f) I_Zone\HasCustomForest = ReadByte(f) @@ -2043,7 +2042,7 @@ Function LoadSaveGames() Local f% = ReadFile(SavePath + SaveGames(i - 1) + "\save.txt") SaveGameTime(i - 1) = ReadString(f) SaveGameDate(i - 1) = ReadString(f) - ;Skip all data until the CompatibleVersion number + ;Skip all data until the version number ReadInt(f) For j = 0 To 5 ReadFloat(f) From 34fb78ca425afb7a24d099b4cfb2516ff45c3e82 Mon Sep 17 00:00:00 2001 From: Quote <94698137+ChronoQuote@users.noreply.github.com> Date: Sun, 28 Aug 2022 05:30:48 -0700 Subject: [PATCH 2/5] Fix compatibility with new 066 achievement 1.3.11 saves now load again. --- Save.bb | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/Save.bb b/Save.bb index d033d4327..ad5e8d2db 100644 --- a/Save.bb +++ b/Save.bb @@ -119,6 +119,7 @@ Function SaveGame(file$) WriteByte f, SoundTransmission WriteByte f, Contained106 + WriteByte f, MAXACHIEVEMENTS For i = 0 To MAXACHIEVEMENTS-1 WriteByte f, Achievements(i) Next @@ -581,9 +582,30 @@ Function LoadGame(file$) SoundTransmission = ReadByte(f) Contained106 = ReadByte(f) - For i = 0 To MAXACHIEVEMENTS-1 + If CompareVersions(version, "1.3.12") >= 0 Then + temp = ReadByte(f) + Else + temp = 37 + EndIf + For i = 0 To temp-1 Achievements(i)=ReadByte(f) Next + If CompareVersions(version, "1.3.12") < 0 Then + Achievements(37)=Achievements(36) + Achievements(36)=Achievements(31) + Achievements(31)=Achievements(28) + Achievements(28)=Achievements(34) + Achievements(34)=Achievements(32) + Achievements(32)=Achievements(29) + Achievements(29)=Achievements(35) + Achievements(35)=Achievements(33) + Achievements(33)=Achievements(30) + Achievements(30)=Achievements(27) + For i = 27 To 6 Step -1 + Achievements(i)=Achievements(i-1) + Next + Achievements(5)=False + EndIf RefinedItems = ReadInt(f) MapWidth = ReadInt(f) @@ -1416,9 +1438,30 @@ Function LoadGameQuick(file$) SoundTransmission = ReadByte(f) Contained106 = ReadByte(f) - For i = 0 To MAXACHIEVEMENTS-1 + If CompareVersions(version, "1.3.12") >= 0 Then + temp = ReadByte(f) + Else + temp = 37 + EndIf + For i = 0 To temp-1 Achievements(i)=ReadByte(f) Next + If CompareVersions(version, "1.3.12") < 0 Then + Achievements(37)=Achievements(36) + Achievements(36)=Achievements(31) + Achievements(31)=Achievements(28) + Achievements(28)=Achievements(34) + Achievements(34)=Achievements(32) + Achievements(32)=Achievements(29) + Achievements(29)=Achievements(35) + Achievements(35)=Achievements(33) + Achievements(33)=Achievements(30) + Achievements(30)=Achievements(27) + For i = 27 To 6 Step -1 + Achievements(i)=Achievements(i-1) + Next + Achievements(5)=False + EndIf RefinedItems = ReadInt(f) MapWidth = ReadInt(f) From 6bc59939d6a90e117287081e963e7ffe63be0c1c Mon Sep 17 00:00:00 2001 From: Quote <94698137+ChronoQuote@users.noreply.github.com> Date: Fri, 15 Sep 2023 21:39:01 -0700 Subject: [PATCH 3/5] Revert "Reverted achievement changes because they break compatibility with older save files" This reverts commit accc9600aed0a2ea5398939a3903ef8be08a1b68. --- Achievements.bb | 16 +++--- Data/achievementstrings.ini | 99 +++++++++++++++++++------------------ 2 files changed, 59 insertions(+), 56 deletions(-) diff --git a/Achievements.bb b/Achievements.bb index 7894d924b..9a4d3ff2f 100644 --- a/Achievements.bb +++ b/Achievements.bb @@ -1,17 +1,15 @@ ;achievement menu & messages by InnocentSam -Const MAXACHIEVEMENTS=37 +Const MAXACHIEVEMENTS=38 Dim Achievements%(MAXACHIEVEMENTS) -Const Achv008%=0, Achv012%=1, Achv035%=2, Achv049%=3, Achv055=4, Achv079%=5, Achv096%=6, Achv106%=7, Achv148%=8, Achv205=9 -Const Achv294%=10, Achv372%=11, Achv420%=12, Achv427=13, Achv500%=14, Achv513%=15, Achv714%=16, Achv789%=17, Achv860%=18, Achv895%=19 -Const Achv914%=20, Achv939%=21, Achv966%=22, Achv970=23, Achv1025%=24, Achv1048=25, Achv1123=26 +Const Achv008%=0, Achv012%=1, Achv035%=2, Achv049%=3, Achv055%=4, Achv066%=5, Achv079%=6, Achv096%=7, Achv106%=8, Achv148%=9 +Const Achv205%=10, Achv294%=11, Achv372%=12, Achv420%=13, Achv427%=14, Achv500%=15, Achv513%=16, Achv714%=17, Achv789%=18, Achv860%=19 +Const Achv895%=20, Achv914%=21, Achv939%=22, Achv966%=23, Achv970%=24, Achv1025%=25, Achv1048%=26, Achv1123%=27, Achv1162%=28, Achv1499%=29 -Const AchvMaynard%=27, AchvHarp%=28, AchvSNAV%=29, AchvOmni%=30, AchvConsole%=31, AchvTesla%=32, AchvPD%=33 +Const AchvMaynard%=30, AchvHarp%=31, AchvSNAV%=32, AchvOmni%=33, AchvTesla%=34, AchvPD%=35 -Const Achv1162% = 34, Achv1499% = 35 - -Const AchvKeter% = 36 +Const AchvConsole%=36, AchvKeter%=37 Global UsedConsole @@ -177,5 +175,5 @@ End Function ;~IDEal Editor Parameters: -;~F#31#48 +;~F#2D#44 ;~C#Blitz3D \ No newline at end of file diff --git a/Data/achievementstrings.ini b/Data/achievementstrings.ini index 56034af37..590fe9f49 100644 --- a/Data/achievementstrings.ini +++ b/Data/achievementstrings.ini @@ -16,169 +16,174 @@ AchvDesc=Encountered the Possessive Mask. [s3] string1=Doctor, Doctor image=Achv049 -AchvDesc=Found the cure +AchvDesc=Found the cure. [s4] string1=Anti-Meme image=Achv055 -AchvDesc=Recontained SCP-055 +AchvDesc=Recontained SCP-055. [s5] +string1="Eric?" +image=Achv066 +AchvDesc=Encountered Eric's Toy. + +[s6] string1=Deductive Reasoning image=Achv079 AchvDesc=Encountered the Old AI. -[s6] -string1=Don't Look At Me +[s7] +string1=Don't Look at Me image=Achv096 AchvDesc=Encountered the Shy Guy. -[s7] +[s8] string1=A Decayed March image=Achv106 AchvDesc=Encountered the Old Man. -[s8] +[s9] string1=Dirty Metal image=Achv148 AchvDesc=Acquired the "Telekill Alloy". -[s9] +[s10] string1=Femme Fatale image=Achv205 AchvDesc=Encountered the Shadow Lamps. -[s10] +[s11] string1=OUT OF RANGE image=Achv294 AchvDesc=Obtained a liquid from the Coffee Machine. -[s11] +[s12] string1=The Corner of Your Eye... image=Achv372 AchvDesc=Encountered the Peripheral Jumper. -[s12] +[s13] string1="Reggae, man." image=Achv420 AchvDesc=Smoked some good ass shit. -[s13] +[s14] string1=Light of Life image=Achv427 AchvDesc=Found and equipped the "Lovecraftian Locket". -[s14] +[s15] string1=A Taste of Immortality image=Achv500 AchvDesc=Swallowed a sample of Panacea. -[s15] +[s16] string1=If You Ring It, He Will Come image=Achv513 AchvDesc=Encountered an Old Cowbell. -[s16] +[s17] string1=Mental Exhaustion image=Achv714 AchvDesc=Found a Jaded Ring. -[s17] +[s18] string1="by researcher james, age 11" image=Achv789 AchvDesc=Encountered the Butt Ghost. -[s18] +[s19] string1=Blue Hue image=Achv860 AchvDesc=Found a Blue Key. -[s19] +[s20] string1=Interference image=Achv895 AchvDesc=Encountered an Old Coffin. -[s20] +[s21] string1=Refinery image=Achv914 AchvDesc=Encountered the Clockworks Machine. -[s21] +[s22] string1=Show Yourself image=Achv939 AchvDesc=Encountered the Creatures with Many Voices. -[s22] +[s23] string1=Rapid Eye Movement image=Achv966 AchvDesc=Encountered the Sleep Killers. -[s23] +[s24] string1=Recursive Spacial Phenomenon image=Achv970 AchvDesc=Encountered a Recursive Room. -[s24] +[s25] string1="Potential Bioweapon" image=Achv1025 AchvDesc=Read the Encyclopedia of Common Diseases. -[s25] +[s26] string1=The Architect image=Achv1048 AchvDesc=Encountered the Builder Bear. -[s26] +[s27] string1=The Final Solution image=Achv1123 AchvDesc=Encountered the Atrocity Skull. -[s27] +[s28] +string1=Pieces of the Past +image=Achv1162 +AchvDesc=Encountered the Hole In The Wall. + +[s29] +string1=Screams Of The Present +image=Achv1499 +AchvDesc=Wore a GP-5 Gas Mask. + +[s30] string1=The Containment Breach image=AchvMaynard AchvDesc=Entered Doctor Maynard's office. -[s28] +[s31] string1=World-Ending Scenario image=AchvHarp AchvDesc=Entered Doctor Harp's office. -[s29] +[s32] string1=Technical Accomplishments image=AchvSNAV AchvDesc=Acquired the S-NAV Navigator Ultimate. -[s30] +[s33] string1=Unlimited Access image=AchvOmni AchvDesc=Acquired an Omni-level Keycard. -[s31] -string1=Fair Play -image=AchvConsole -AchvDesc=Didn't use console commands. - -[s32] +[s34] string1=Shell Shocked image=AchvTesla AchvDesc=Lured the Old Man through a Tesla gate. -[s33] +[s35] string1=No Man's Land image=AchvPD AchvDesc=Escaped the Old Man's Pocket Dimension. -[s34] -string1=Pieces of the Past -image=Achv1162 -AchvDesc=Encountered the Hole In The Wall. - -[s35] -string1=Screams Of The Present -image=Achv1499 -AchvDesc=Wore a GP-5 Gas Mask. - [s36] -string1=Survival In a Nightmare +string1=Fair Play +image=AchvConsole +AchvDesc=Didn't use console commands. + +[s37] +string1=Survival in a Nightmare image=AchvKeter -AchvDesc=Beat the game on Keter difficulty. +AchvDesc=Beat the game on Keter difficulty. \ No newline at end of file From c051ff244b6c30a79a0c60e4d6028e0b06c23b03 Mon Sep 17 00:00:00 2001 From: Quote <94698137+ChronoQuote@users.noreply.github.com> Date: Fri, 15 Sep 2023 23:34:55 -0700 Subject: [PATCH 4/5] Change version number to 1.3.12 VersionNumber had to be changed to 1.3.12 sooner or later, and with the new save compatibility system, I think this is a good time. VersionNumber is what appears in the app title and in the corner of the main menu. With the new save compatibility system, it's also the number shown on save files in the load game screen. --- Main.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Main.bb b/Main.bb index a1ede9760..1b0dcab97 100644 --- a/Main.bb +++ b/Main.bb @@ -42,7 +42,7 @@ Global UpdaterFont% Global Font1%, Font2%, Font3%, Font4%, Font5% Global ConsoleFont% -Global VersionNumber$ = "1.3.12dev" +Global VersionNumber$ = "1.3.12" Global OldestSupportedVersion$ = "1.3.10" Global MenuWhite%, MenuBlack% From 4d8dfc371ba8fc2e96539bbddcbdeed763517038 Mon Sep 17 00:00:00 2001 From: Quote <94698137+ChronoQuote@users.noreply.github.com> Date: Mon, 25 Sep 2023 13:23:54 -0700 Subject: [PATCH 5/5] Revert "Removed leftover bits of the SCP-066 achievement (the addition of this new achievements was reverted in accc9600aed, but these changes were accidentally left in). #251" This reverts commit 75eee99feeea9023f54635c50eeaddcf38a727ca. --- GFX/menu/achievements/Achv066.jpg | Bin 0 -> 2649 bytes NPCs.bb | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 GFX/menu/achievements/Achv066.jpg diff --git a/GFX/menu/achievements/Achv066.jpg b/GFX/menu/achievements/Achv066.jpg new file mode 100644 index 0000000000000000000000000000000000000000..149465277dee6520ce2847b7fdd35c28a9f9826b GIT binary patch literal 2649 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 Hu0mjfJ&xQp literal 0 HcmV?d00001 diff --git a/NPCs.bb b/NPCs.bb index fa7877a4d..bce1ccabf 100644 --- a/NPCs.bb +++ b/NPCs.bb @@ -3919,6 +3919,10 @@ Function UpdateNPCs() If Rand(700)=1 Then PlaySound2(LoadTempSound("SFX\SCP\066\Eric"+Rand(1,3)+".ogg"),Camera, n\Collider, 8.0) + If dist < 1.0+n\LastDist Then + GiveAchievement(Achv066) + n\State = Rand(2,3) + EndIf Case 2 ;roll towards the player and make a sound, and then escape If n\Frame < 647 Then angle = CurveAngle(0, (AnimTime(n\obj)-2.0)/1.2445, 5.0)