Stephan Fuchs преди 2 месеца
родител
ревизия
40bb80118d

+ 1 - 1
.gitignore

@@ -45,7 +45,7 @@ glife.7z.tmp
 glife.7z
 
 *.test
-glife.html
+*.html
 
 
 __pycache__/

+ 0 - 8
mods/mod.html

@@ -1,8 +0,0 @@
-<tw-passagedata pid="1680" name="intro_sg_select_char_after" tags="mod modExample" position="1225,20975" size="100,100">&lt;&lt;act &#39;Godess&#39;&gt;&gt;
-    &lt;&lt;gt &#39;modExample_intr_sg_select_godess&#39;&gt;&gt;
-&lt;&lt;/act&gt;&gt;</tw-passagedata>
-<tw-passagedata pid="1681" name="modExample_intr_sg_select_godess" tags="mod modExample" position="100,21100" size="100,100">&lt;h2&gt;Godess&lt;/h2&gt;
-	&lt;&lt;image &quot;system/1_openings/2_sg/nerd_0.jpg&quot;&gt;&gt;
-	&lt;p&gt;
-		Modded start.
-	&lt;/p&gt;</tw-passagedata>

+ 3 - 0
mods/util/BuildModFiles.bat

@@ -0,0 +1,3 @@
+@ECHO off
+
+Python -X utf8 mods/util/BuildModFiles.py

+ 62 - 0
mods/util/BuildModFiles.py

@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+import os
+import fileinput
+import re
+import sys
+
+
+modTag = "mod"
+
+file_path_html = 'glife.html'
+file_path_mod = 'mods/mod.html'
+file_path_localmod = 'mods/glife_local_mod.html'
+file_path_remotemod = 'mods/glife_remote_mod.html'
+
+file_path_modloader = 'mods/util/ModloaderScript.txt'
+
+data = ''
+modData = ''
+scripts = ''
+dataWithoutModStuff = ''
+
+with open(file_path_html, 'r') as file:
+    data = file.read()
+
+dataWithoutModStuff = data
+
+i = 0
+regex = r"""<tw-passagedata pid="(\d+)" name="([\s\w]+)" tags="(.*?)" (?:position="\d+,\d+" )?(?:size="\d+,\d+")?>(.*?)</tw-passagedata>"""
+for match in re.finditer(regex,data,re.S):
+    tags = match.group(3).split()
+
+    if(modTag in tags):
+        modData += match.group(0)+'\n'
+        dataWithoutModStuff = dataWithoutModStuff.replace(match.group(0),'')
+
+    i += 1
+    if(i % 100 == 0):
+        print(i)
+
+regex = r"""/\*\s*Start Mod:\s*"Mod"\s*\*/(.*?)/\*\s*End Mod:\s*"Mod"\s*\*/"""
+for match in re.finditer(regex,data,re.S):
+    scripts += match.group(1)
+    dataWithoutModStuff = dataWithoutModStuff.replace(match.group(0),'')
+
+modData += '<script>'+scripts+'</script>'
+
+with open(file_path_mod, 'w') as file:
+    file.write(modData)
+
+
+data_localmod = dataWithoutModStuff.replace('</tw-storydata>',modData+'</tw-storydata>',1)
+with open(file_path_localmod, 'w') as file:
+    file.write(data_localmod)
+
+
+with open(file_path_modloader, 'r') as file:
+    modloader_data = file.read()
+data_remtotemod = re.sub(r"""(<script id="script-sugarcube" type="text/javascript">)(.*?)(</script>)""",r"""\1"""+modloader_data+r""" \2}\3""",dataWithoutModStuff,1, re.S)
+with open(file_path_remotemod, 'w') as file:
+    file.write(data_remtotemod)
+
+print('Done')

+ 5 - 0
mods/util/MakeMod.py

@@ -12,6 +12,7 @@ file_path_mod = 'mods/mod.html'
 
 data = ''
 modData = ''
+scripts = ''
 
 with open(file_path_html, 'r') as file:
     data = file.read()
@@ -27,7 +28,11 @@ for match in re.finditer(regex,data,re.S):
     if(i % 100 == 0):
         print(i)
 
+regex = r"""/\*\s*Start Mod:\s*"Mod"\s*\*/(.*?)/\*\s*End Mod:\s*"Mod"\s*\*/"""
+for match in re.finditer(regex,data,re.S):
+    scripts += match.group(1)
 
+modData += '<script>'+scripts+'</script>'
 
 with open(file_path_mod, 'w') as file:
     file.write(modData)

+ 25 - 0
mods/util/ModloaderScript.txt

@@ -0,0 +1,25 @@
+let modSettings = JSON.parse(localStorage.getItem("glife_mods") || "{}")
+let modsToBeLoadedCount = 0;
+let modsToBeLoadedPaths = [];
+
+for (const [modId, modData] of Object.entries(modSettings)) {
+    if(modData.enabled){
+        modsToBeLoadedCount += 1;
+        modsToBeLoadedPaths.push(modData.path);
+    }
+}
+
+if(modsToBeLoadedCount == 0)
+    executeDefaultSC()
+else{
+    for(let modsToBeLoadedPath of modsToBeLoadedPaths){
+        $.ajax({  url: modsToBeLoadedPath,  cache: false}).done(function( html ) {
+            $( "tw-storydata" ).append( html );
+            modsToBeLoadedCount -= 1;
+            if(modsToBeLoadedCount <= 0)
+                executeDefaultSC();
+        });
+    }
+}
+
+function executeDefaultSC(){

+ 3 - 5
sugarcube/src/PassageFooter.tw

@@ -1,10 +1,8 @@
 :: PassageFooter
-
-<<if Story.has($here+'_after')>>
+/*<<if Story.has($here+'_after')>>
 	<<include `$here+'_after'`>>
-<</if>>
-<<set _afterPassages = Story.lookup("tags", $here+'_after')>>
-<<for _afterPassage range _afterPassages>>
+<</if>>*/
+<<for _afterPassage range Story.lookup("tags", $here+'_after')>>
 	<<include _afterPassage.title>>
 <</for>>
 

+ 16 - 4
sugarcube/src/PassageHeader.tw

@@ -6,6 +6,18 @@
 <<set $callStackIndent = 0>>
 <<set $callStack = [[passage(),$callStackIndent]]>>
 
+<<if window.modsLoading>>
+    <<set window.modsLoaded ??= []>>
+    <<for _mod range window.modsLoading>>
+        <<if !window.modsLoaded.includes(_mod.id)>>
+            <<if !$modVars[_mod.id]>><<set $modVars[_mod.id] = {}>><</if>>
+            <<run _mod.onLoad(State.variables)>>
+            <<run window.modsLoaded.push(_mod.id)>>
+        <</if>>
+    <</for>>
+    <<set window.modsLoading = null>>
+<</if>>
+
 <!-- This might be overwritten in case we return from an event in PassageDone -->
 <<set _thisMainPassage = passage()>>
 <<set _tags = tags()>>
@@ -20,11 +32,11 @@
 <<include 'PassageHeaderAll'>>
 
 
-<<if Story.has($here+'_before')>>
-    <<include `$here+'_before'`>>
-<</if>>
+<<for _beforePassage range Story.lookup("tags", $here+'_before')>>
+	<<include _beforePassage.title>>
+<</for>>
 
-:: PassageHeaderAll
+:: PassageHeaderAll[include]
 <!-- Also exists for subpassages and if CLA was called -->
 <div id="connectedLocations"></div>
 <div id="messagesContainter">

+ 37 - 0
sugarcube/src/_myMod/myMod.tw

@@ -0,0 +1,37 @@
+:: mod_cheats_scripts[script]
+/* Start Mod: "Mod" */
+
+window.modsLoading ??= [];
+window.modsLoading.push({id:'cheats',onLoad:(variables) => {
+    console.warn('Mod Loading: Cheatmenu');
+
+
+    /*Object.defineProperty(PlayerCharacter.prototype, 'pcs_energy_raw',	Object.getOwnPropertyDescriptor(PlayerCharacter.prototype, 'pcs_energy'));
+    //Object.defineProperty(PlayerCharacter.prototype, 'pcs_hydra_raw',	Object.getOwnPropertyDescriptor(PlayerCharacter.prototype, 'pcs_hydra'));
+
+    Object.defineProperty(PlayerCharacter.prototype, 'pcs_energy', {
+        get() {return State?.variables.modVars.cheatmenu.cheatHunger ? 100 : this.pcs_energy_raw;},
+        set(v){this.pcs_energy_raw = v;}});
+    console.warn(PlayerCharacter.prototype.pcs_energy);*/
+}});
+
+/* End Mod: "Mod" */
+
+:: mod_cheats_menu_after[mod Menu_after]
+<<act 'Cheat Menu'>>
+    <<gt 'mod_cheats_menu_menu'>>
+<</act>>
+:: mod_cheats_menu_menu[mod menu]
+<<act 'Confirm'>>
+    <<gs 'mod_cheats_stat_15minutes_changes_after'>>
+    <<gt 'Menu'>>
+<</act>>
+<h2>Cheats</h2>
+<p><<checkbox "$modVars.cheats.cheatHunger" false true autocheck>> Disable Hunger</p>
+<p><<checkbox "$modVars.cheats.cheatThirst" false true autocheck>> Disable Thirst</p>
+<p><<checkbox "$modVars.cheats.cheatSleep" false true autocheck>> Disable Sleep (don't forget to set your alarm clock or you will sleep for a very long time)</p>
+
+:: mod_cheats_stat_15minutes_changes_after[mod stat_15minutes_changes_after]
+<<if $modVars.cheats.cheatHunger>><<set $pc.pcs_energy = 100>><</if>>
+<<if $modVars.cheats.cheatThirst>><<set $pc.pcs_hydra = 100>><</if>>
+<<if $modVars.cheats.cheatSleep>><<set $pc.pcs_sleep = 50>><</if>>

+ 5 - 0
sugarcube/src/autogenerated/Stats/stat.tw

@@ -1232,5 +1232,10 @@
 			<<set $bimbolevel = 0>>
 
 		<</if>>
+
+	<<for _afterPassage range Story.lookup("tags", 'stat_15minutes_changes_after')>>
+		<<include _afterPassage.title>>
+	<</for>>
+	
 <!-- END: stat_15minutes_changes -->
  */

+ 26 - 0
sugarcube/src/start/index.tw

@@ -64,6 +64,10 @@
 		<<gt 'ImageSetting'>>
 	<</act>>
 
+	<<act 'Mod Manager'>>
+		<<gt 'ModManager'>>
+	<</act>>
+
 </center>
 <!-- ! WD: Set variable to store Image needed HTML code-->
 <<set $ImageNeededPlacholder = '<center>IMAGE MISSING</center>'>>
@@ -97,3 +101,25 @@
 <p><b style="color:red;">If you see an image below your settings are correct.</b></p>
 <<image "system/1_openings/splashes/splash#.jpg" 1 14>>
 
+:: ModManager[menu]
+	<<set _existingMods = {cheatmenu:{'label':'CheatMenu','description':'Adds a cheat menu. You can reach it ingame via the menu-button ingame.','path':'mod_cm.html'}}>>
+
+	<<set _currentModSettings = JSON.parse(localStorage.getItem("glife_mods") || "{}")>>
+	<<run console.log("CurrentModSettings",_currentModSettings)>>
+
+	<<for _modId,_modData range _existingMods>>
+		<<set _existingMods[_modId].enabled = (_currentModSettings[_modId]?.enabled === true)>>
+		<p><<checkbox `"_existingMods['"+_modId+"'].enabled"` false true autocheck>>_modData.label : _modData.description</p>
+	<</for>>
+
+
+	<<button 'Confirm'>>
+		<<set _enabledMods = {}>>
+		<<for _modId,_modData range _existingMods>>
+			<<if _modData.enabled>>
+				<<set _enabledMods[_modId] = {enabled: true, path: _modData.path}>>
+			<</if>>
+		<</for>>
+		<<run localStorage.setItem("glife_mods",JSON.stringify(_enabledMods))>>
+		<<run location.reload(true)>>
+	<</button>>