VN Others Completed Life With a Slave -Teaching Feeling- [v4.0.6 - v2.5.2] [FreakilyCharming]

4.50 star(s) 119 Votes

TheBlueKnight

Discussion Dynamo
Respected User
Jr. Uploader
Oct 1, 2018
25,468
19,480
For some reason when I try to open the game it’s a black screen and just says loading TyranoScropt...
If you used WinRAR try using 7Zip to extract the prepatched games, 7z files sometimes don't extract properly. Or get the game and a patch separately from przemo's MEGA folder, those are plain zips. Think someone also fix that issue by just installing the patch again to the prepatched game theirselves.
 

maraskanuser

New Member
Mar 23, 2020
2
0
I thought I'd share an ahk script I wrote. It can be used for several things:
  • it can merge several translation files into one, taking translations from lower priority files if they don't exist in the preferred file.
  • it resorts translation files' keys to be in the same order as in the untranslated key dump. The resulting files can more easily be compared in tools like WinMerge etc. They get only written when bCreateDebug=1.
  • it drops keys that aren't part of the clean dump from the translation files (removes translation lines for text that isn't in the game anymore. (just to be sure, a clean dump is what you get when you have an empty RJ162718.json be recreated be setting config.json to update. It contains keys for all lines of japanese text in the game; at least if you haven't installed any patched scene files, that is. The scene files of the patch for some reason are partially translated)
Probably only useful to translators or coders, though ^^;

Code:
#SingleInstance,Force
#NoEnv
SetBatchLines,-1

;###############################################################################################################################

; Path to dump of untranslated lines (by setting update -> file in config.json)

  sKeyDumpRawPath   := "D:\D\5\AHKVNBrowser\RE\r55217\Setup\Dictionaries\Dump_2.5.2.json"

; Omit keys in dump that only contain ascii (no reason to translate ascii). Boolean. 1 = 'true', 0 = 'false'
; Keys in the dump's "graphic" section are never omitted, even though they're all ascii.

  bOmitAsciiKeys := 1

; json files containing translations for various keys in order of prefered usage (sDictionary1 has highest priority)
; if a key has no translation in the dictionary 1, it will check dictionary 2, then 3.

  sDictionary1Path := "D:\D\5\AHKVNBrowser\RE\r55217\Setup\Dictionaries\Dictionary_MINE.json"
  sDictionary2Path := "D:\D\5\AHKVNBrowser\RE\r55217\Setup\Dictionaries\Dictionary_2.5.2_Variant B.json"
  sDictionary3Path := "D:\D\5\AHKVNBrowser\RE\r55217\Setup\Dictionaries\Dictionary_2.5.2_Variant A.json"

; File path to write the new merged dictionary to. Should usually point to the game's ".\data\others\translate\assets\RJ162718.json" file
; This is ordered just like the original dump, so the line order of the game's ks files is conserved
; (important to understand the meaning of multi-line sentences while translating)

  sOutputFile   := "D:\D\5\AHKVNBrowser\RE\r55217\Setup\[patch] TransFix_v5.2_r5.3.1m\Translate Strings\data\others\translate\assets\RJ162718.json"

; Create a couple of other json files in the script's folder for debug and translation comparison purposes. Boolean.
; Useful to compare different translations with tools like WinMerge, since the output is all in the exact same order (the order of the original dump)

  bCreateDebug := 1

;###############################################################################################################################

Dictionary1_obj := ReadDictionary(sDictionary1Path)
Dictionary2_obj := ReadDictionary(sDictionary2Path)
Dictionary3_obj := ReadDictionary(sDictionary3Path)

sOutputString := ProcessKeyDump(sKeyDumpRawPath,Dictionary1_obj,Dictionary2_obj,Dictionary3_obj,bOmitAsciiKeys)

FileDelete,%sOutputFile%
FileAppend,%sOutputString%,*%sOutputFile%,UTF-8-RAW



if (bCreateDebug=1)
  {
  if (sDictionary1Path != "") && (IsObject(Dictionary1_obj))
    {
    sOutputString := ProcessKeyDump(sKeyDumpRawPath,Dictionary1_obj,"","",bOmitAsciiKeys)
    SplitPath,sDictionary1Path,,,FExt,FNameNoExt
    FileDelete,%A_ScriptDir%\[Debug] %FNameNoExt%.%FExt%
    FileAppend,%sOutputString%,*%A_ScriptDir%\[Debug] %FNameNoExt%.%FExt%,UTF-8-RAW
    }

  if (sDictionary2Path != "") && (IsObject(Dictionary2_obj))
    {
    sOutputString := ProcessKeyDump(sKeyDumpRawPath,Dictionary2_obj,"","",bOmitAsciiKeys)
    SplitPath,sDictionary2Path,,,FExt,FNameNoExt
    FileDelete,%A_ScriptDir%\[Debug] %FNameNoExt%.%FExt%
    FileAppend,%sOutputString%,*%A_ScriptDir%\[Debug] %FNameNoExt%.%FExt%,UTF-8-RAW
    }

  if (sDictionary3Path != "") && (IsObject(Dictionary3_obj))
    {
    sOutputString := ProcessKeyDump(sKeyDumpRawPath,Dictionary3_obj,"","",bOmitAsciiKeys)
    SplitPath,sDictionary3Path,,,FExt,FNameNoExt
    FileDelete,%A_ScriptDir%\[Debug] %FNameNoExt%.%FExt%
    FileAppend,%sOutputString%,*%A_ScriptDir%\[Debug] %FNameNoExt%.%FExt%,UTF-8-RAW
    }
  }

ExitApp






;##################################################################################
;##################################################################################
;##################################################################################

ReadDictionary(sFilePath)
  {
  FileRead,sJSON1_old,*P65001 %sFilePath%

  iLevel:=0
  sSection:=""
  iCount:=0
  obj_return := {}

  loop,parse,sJSON1_old,`n,`r
    {
    sText:=Trim(A_LoopField)
    
    if (sText="{")
      {
      iLevel++
      iFoundKey:=0
      iFoundLang:=0
      continue
      }
    else if (sText="},")||(sText="}")
      {
      if (iLevel=3)
        {
        if !IsObject(obj_return[sSection])
          {
          clipboard:=A_Index
          msgbox,,Error A,Section %sSection% not yet part of return object.
          }

        PairObj:={}
        obj_return[sSection][sEntryJP] := sEntryEN
        }

      iLevel--
      continue
      }

    if (iLevel=1)
      {
      if RegExMatch(sText,"^""([a-z]*)"": \[$",sKey)
        {
        iLevel++
        
        if (sKey1!="text")&&(sKey1!="chara")&&(sKey1!="hint")&&(sKey1!="graphic")&&(sKey1!="eval")&&(sKey1!="branch")
          {
          clipboard:=A_Index
          msgbox,,Error B,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
          }

        sSection:=sKey1
        
        if !IsObject(obj_return[sSection])
          obj_return[sSection] := {}
        
        continue
        }
      else
        {
        clipboard:=A_Index
        msgbox,,Error C,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
        }
      }
    else if (iLevel=2)
      {
      if (sText="],")||(sText="]")
        {
        iLevel--
        continue
        }
      else if (sText="")
        {
        }
      else
        {
        clipboard:=A_Index
        msgbox,,Error D,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
        }
      }
    else if (iLevel=3)
      {
      pos1:=instr(sText,"""key"":",0,1)
      pos2:=instr(sText,"""en-US"":",0,1)

      if (pos1=1)
        {
        if (iFoundKey=1)
          {
          clipboard:=A_Index
          msgbox,,Error E,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
          }
        else
          {
          iFoundKey=1
          sVal:=substr(sText,7)
          sVal:=Trim(sVal," ")

          sFirst:=substr(sVal,1,1)
          sLast:=substr(sVal,strlen(sVal),1)
          sPreLast:=substr(sVal,strlen(sVal)-1,1)

          if (iFoundLang=1)  ; language entry "en-US" was first -> this "key" entry is second -> no comma
            {
            if (sFirst!="""")||(sLast!="""")
              {
              clipboard:=A_Index
              msgbox,,Error F,Bad formating in %sText%
              }
            else
              {
              sEntryJP:=substr(sVal,2,strlen(sVal)-2)
              }
            }
          else        ; language entry "en-US" still missing -> this "key" goes first -> has comma
            {
            if (sFirst!="""")||(sPreLast!="""")||(sLast!=",")
              {
              clipboard:=A_Index
              msgbox,,Error G,Bad formating in %sText%
              }
            else
              {
              sEntryJP:=substr(sVal,2,strlen(sVal)-3)
              }
            }
          }
        }
      else if (pos2=1)
        {
        if (iFoundLang=1)
          {
          clipboard:=A_Index
          msgbox,,Error H,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%" 
          }
        else
          {
          iFoundLang=1
          sVal:=substr(sText,9)
          sVal:=Trim(sVal," ")

          sFirst:=substr(sVal,1,1)
          sLast:=substr(sVal,strlen(sVal),1)
          sPreLast:=substr(sVal,strlen(sVal)-1,1)

          if (iFoundKey=0)  ; "key" entry still missing -> this language entry goes first -> has comma
            {
            if (sVal="null,")
              sEntryEN:="null"
            else
              {
              if (sFirst!="""")||(sPreLast!="""")||(sLast!=",")
                {
                clipboard:=A_Index
                msgbox,,Error I,Bad formating in %sText%
                }
              else
                {
                sEntryEN:=substr(sVal,2,strlen(sVal)-3)
                }
              }
            }
          else        ; "key" entry already exists -> this language entry is second -> no comma
            {
            if (sVal="null")
              sEntryEN:=sVal
            else
              {
              if (sFirst!="""")||(sLast!="""")
                {
                clipboard:=A_Index
                msgbox,,Error J,Bad formating in %sText%
                }
              else
                {
                sEntryEN:=substr(sVal,2,strlen(sVal)-2)
                }
              }
            }
          }
        }
      else
        {
        clipboard:=A_Index
        msgbox,,Error K,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
        }
      }
    else
      {
      clipboard:=A_Index
      msgbox,,Error L,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
      }
    }

  return obj_return
  }


ProcessKeyDump(sFilePath,dictobj1,dictobj2,dictobj3,bOmitAsciiKeys)
  {
  if !FileExist(sFilePath)
    {
    msgbox,,Error,ProcessKeyDump() can't find file:`n%sFilePath%
    ExitApp
    }

  FileRead,sJSON1_old,*P65001 %sFilePath%
 
  iLevel:=0
  sSection:=""
  iCount:=0
  obj_return := {}

  sReturn := ""

  loop,parse,sJSON1_old,`n,`r
    {
    sText:=Trim(A_LoopField)
    
    if (sText="{")
      {
      iLevel++
      iFoundKey:=0
      iFoundLang:=0
      
      if (iLevel!=3)
        sReturn .= A_LoopField "`n"
      continue
      }
    else if (sText="},")||(sText="}")
      {
      if (iLevel=3)
        {
        if !IsObject(obj_return[sSection])
          {
          clipboard:=A_Index
          msgbox,,Error A,Section %sSection% not yet part of return object.
          }
        obj_return[sSection][sEntryJP] := sEntryEN

        if (sSection="graphic")
          {
          ; Since this sections contains only ascii image pathes for buttons and ascii translated Tooltip texts, we need to get it this way
          bNonAscii=1
          }
        else
          {
          bNonAscii=0
          if (bOmitAsciiKeys=1)
            {
            loop,parse,sEntryJP
              {
              k_unicode:=asc(A_LoopField)
              if (k_unicode>256)  ;(k_unicode>=0x2000)
                {
                bNonAscii=1
                break
                }
              }
            }
          }

        if (bNonAscii=1)||(bOmitAsciiKeys=0)
          {
          sReturn .= "    {`n      ""key"": """ sEntryJP """,`n"

          ;-----------------------------------------------------
          ; This is where the translations are actually applied

          if IsObject(dictobj1)
            {
            sEntryEN1 := dictobj1[sSection][sEntryJP]
            if (sEntryEN1!="") && (sEntryEN1!="null")
              sEntryEN := sEntryEN1
            }

          if IsObject(dictobj2)
            {
            sEntryEN2 := dictobj2[sSection][sEntryJP]
            if ((sEntryEN="") || (sEntryEN="null")) && (sEntryEN2!="") && (sEntryEN2!="null")
              sEntryEN := sEntryEN2
            }

          if IsObject(dictobj3)
            {
            sEntryEN3 := dictobj3[sSection][sEntryJP]
            if ((sEntryEN="") || (sEntryEN="null")) && (sEntryEN3!="")&&(sEntryEN3!="null")
              sEntryEN := sEntryEN3
            }

          ;-----------------------------------------------------
          ; We could do some formating with string replace at this point if necessary.
          sEntryEN := StrReplace(sEntryEN,  " [p]",  "[p]")
          sEntryEN := StrReplace(sEntryEN,  " [r]",  "[r]")
          sEntryEN := StrReplace(sEntryEN,  " [l]",  "[l]")
          sEntryEN := StrReplace(sEntryEN, " [lr]", "[lr]")
          sEntryEN := StrReplace(sEntryEN," [lr_]","[lr_]")
          ;-----------------------------------------------------
          
          if (sEntryEN="null")
            sReturn .= "      ""en-US"": null`n    " sText "`n"
          else
            sReturn .= "      ""en-US"": """ sEntryEN """`n    " sText "`n"
          }
        }
      else
        sReturn .= A_LoopField "`n"

      iLevel--
      continue
      }

    if (iLevel=1)
      {
      if RegExMatch(sText,"^""([a-z]*)"": \[$",sKey)
        {
        iLevel++
        
        if (sKey1!="text")&&(sKey1!="chara")&&(sKey1!="hint")&&(sKey1!="graphic")&&(sKey1!="eval")&&(sKey1!="branch")
          {
          clipboard:=A_Index
          msgbox,,Error B,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
          }

        sSection:=sKey1
        
        if !IsObject(obj_return[sSection])
          obj_return[sSection] := {}
        
        sReturn .= A_LoopField "`n"
        continue
        }
      else
        {
        clipboard:=A_Index
        msgbox,,Error C,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
        }
      }
    else if (iLevel=2)
      {
      if (sText="],")||(sText="]")
        {
        iLevel--
        sReturn .= A_LoopField "`n"
        continue
        }
      else if (sText="")
        {
        }
      else
        {
        clipboard:=A_Index
        msgbox,,Error D,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n_%sText%_
        }
      }
    else if (iLevel=3)
      {
      pos1:=instr(sText,"""key"":",0,1)
      pos2:=instr(sText,"""en-US"":",0,1)

      if (pos1=1)
        {
        if (iFoundKey=1)
          {
          clipboard:=A_Index
          msgbox,,Error E,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
          }
        else
          {
          iFoundKey=1
          sVal:=substr(sText,7)
          sVal:=Trim(sVal," ")

          sFirst:=substr(sVal,1,1)
          sLast:=substr(sVal,strlen(sVal),1)
          sPreLast:=substr(sVal,strlen(sVal)-1,1)

          if (iFoundLang=1)  ; language entry "en-US" was first -> this "key" entry is second -> no comma
            {
            if (sFirst!="""")||(sLast!="""")
              {
              clipboard:=A_Index
              msgbox,,Error F,Bad formating in %sText%
              }
            else
              {
              sEntryJP:=substr(sVal,2,strlen(sVal)-2)
              }
            }
          else        ; language entry "en-US" still missing -> this "key" goes first -> has comma
            {
            if (sFirst!="""")||(sPreLast!="""")||(sLast!=",")
              {
              clipboard:=A_Index
              msgbox,,Error G,Bad formating in %sText%
              }
            else
              {
              sEntryJP:=substr(sVal,2,strlen(sVal)-3)
              }
            }
          }
        }
      else if (pos2=1)
        {
        if (iFoundLang=1)
          {
          clipboard:=A_Index
          msgbox,,Error H,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%" 
          }
        else
          {
          iFoundLang=1
          sVal:=substr(sText,9)
          sVal:=Trim(sVal," ")

          sFirst:=substr(sVal,1,1)
          sLast:=substr(sVal,strlen(sVal),1)
          sPreLast:=substr(sVal,strlen(sVal)-1,1)

          if (iFoundKey=0)  ; "key" entry still missing -> this language entry goes first -> has comma
            {
            if (sVal="null,")
              sEntryEN:="null"
            else
              {
              if (sFirst!="""")||(sPreLast!="""")||(sLast!=",")
                {
                clipboard:=A_Index
                msgbox,,Error I,Bad formating in %sText%
                }
              else
                {
                sEntryEN:=substr(sVal,2,strlen(sVal)-3)
                }
              }
            }
          else        ; "key" entry already exists -> this language entry is second -> no comma
            {
            if (sVal="null")
              sEntryEN:=sVal
            else
              {
              if (sFirst!="""")||(sLast!="""")
                {
                clipboard:=A_Index
                msgbox,,Error J,Bad formating in %sText%
                }
              else
                {
                sEntryEN:=substr(sVal,2,strlen(sVal)-2)
                }
              }
            }
          }
        }
      else
        {
        clipboard:=A_Index
        msgbox,,Error K,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
        }
      }
    else
      {
      clipboard:=A_Index
      msgbox,,Error L,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
      }
    }

  sReturn:=RTrim(sReturn,"`r`n")
 
  ; Remove unnecessary comma when retransitioning from CJK-> Ascii keys before the end of a section
  sReturn := StrReplace(sReturn,"`n    },`n  ],`n","`n    }`n  ],`n")
 
  return sReturn
  }
 

Slade4576

Newbie
Oct 31, 2018
94
8
Can I move my saves from the non-modded version to the modded version without problems?
And I can't seem to boop her on the nose. Do I have to be at a certain level?
 
Last edited:

TheBlueKnight

Discussion Dynamo
Respected User
Jr. Uploader
Oct 1, 2018
25,468
19,480
Can I move my saves from the non-modded version to the modded version without problems? And I can't seem to boop her on the nose...
Yes only old game versions should have issues, like 2.4 to 2.5. There is a intimacy requirement for booping, but not a lot.
 

przemo10371

Active Member
Modder
Feb 3, 2018
656
939
I thought I'd share an ahk script I wrote. It can be used for several things:
  • it can merge several translation files into one, taking translations from lower priority files if they don't exist in the preferred file.
  • it resorts translation files' keys to be in the same order as in the untranslated key dump. The resulting files can more easily be compared in tools like WinMerge etc. They get only written when bCreateDebug=1.
  • it drops keys that aren't part of the clean dump from the translation files (removes translation lines for text that isn't in the game anymore. (just to be sure, a clean dump is what you get when you have an empty RJ162718.json be recreated be setting config.json to update. It contains keys for all lines of japanese text in the game; at least if you haven't installed any patched scene files, that is. The scene files of the patch for some reason are partially translated)
Probably only useful to translators or coders, though ^^;

Code:
#SingleInstance,Force
#NoEnv
SetBatchLines,-1

;###############################################################################################################################

; Path to dump of untranslated lines (by setting update -> file in config.json)

  sKeyDumpRawPath   := "D:\D\5\AHKVNBrowser\RE\r55217\Setup\Dictionaries\Dump_2.5.2.json"

; Omit keys in dump that only contain ascii (no reason to translate ascii). Boolean. 1 = 'true', 0 = 'false'
; Keys in the dump's "graphic" section are never omitted, even though they're all ascii.

  bOmitAsciiKeys := 1

; json files containing translations for various keys in order of prefered usage (sDictionary1 has highest priority)
; if a key has no translation in the dictionary 1, it will check dictionary 2, then 3.

  sDictionary1Path := "D:\D\5\AHKVNBrowser\RE\r55217\Setup\Dictionaries\Dictionary_MINE.json"
  sDictionary2Path := "D:\D\5\AHKVNBrowser\RE\r55217\Setup\Dictionaries\Dictionary_2.5.2_Variant B.json"
  sDictionary3Path := "D:\D\5\AHKVNBrowser\RE\r55217\Setup\Dictionaries\Dictionary_2.5.2_Variant A.json"

; File path to write the new merged dictionary to. Should usually point to the game's ".\data\others\translate\assets\RJ162718.json" file
; This is ordered just like the original dump, so the line order of the game's ks files is conserved
; (important to understand the meaning of multi-line sentences while translating)

  sOutputFile   := "D:\D\5\AHKVNBrowser\RE\r55217\Setup\[patch] TransFix_v5.2_r5.3.1m\Translate Strings\data\others\translate\assets\RJ162718.json"

; Create a couple of other json files in the script's folder for debug and translation comparison purposes. Boolean.
; Useful to compare different translations with tools like WinMerge, since the output is all in the exact same order (the order of the original dump)

  bCreateDebug := 1

;###############################################################################################################################

Dictionary1_obj := ReadDictionary(sDictionary1Path)
Dictionary2_obj := ReadDictionary(sDictionary2Path)
Dictionary3_obj := ReadDictionary(sDictionary3Path)

sOutputString := ProcessKeyDump(sKeyDumpRawPath,Dictionary1_obj,Dictionary2_obj,Dictionary3_obj,bOmitAsciiKeys)

FileDelete,%sOutputFile%
FileAppend,%sOutputString%,*%sOutputFile%,UTF-8-RAW



if (bCreateDebug=1)
  {
  if (sDictionary1Path != "") && (IsObject(Dictionary1_obj))
    {
    sOutputString := ProcessKeyDump(sKeyDumpRawPath,Dictionary1_obj,"","",bOmitAsciiKeys)
    SplitPath,sDictionary1Path,,,FExt,FNameNoExt
    FileDelete,%A_ScriptDir%\[Debug] %FNameNoExt%.%FExt%
    FileAppend,%sOutputString%,*%A_ScriptDir%\[Debug] %FNameNoExt%.%FExt%,UTF-8-RAW
    }

  if (sDictionary2Path != "") && (IsObject(Dictionary2_obj))
    {
    sOutputString := ProcessKeyDump(sKeyDumpRawPath,Dictionary2_obj,"","",bOmitAsciiKeys)
    SplitPath,sDictionary2Path,,,FExt,FNameNoExt
    FileDelete,%A_ScriptDir%\[Debug] %FNameNoExt%.%FExt%
    FileAppend,%sOutputString%,*%A_ScriptDir%\[Debug] %FNameNoExt%.%FExt%,UTF-8-RAW
    }

  if (sDictionary3Path != "") && (IsObject(Dictionary3_obj))
    {
    sOutputString := ProcessKeyDump(sKeyDumpRawPath,Dictionary3_obj,"","",bOmitAsciiKeys)
    SplitPath,sDictionary3Path,,,FExt,FNameNoExt
    FileDelete,%A_ScriptDir%\[Debug] %FNameNoExt%.%FExt%
    FileAppend,%sOutputString%,*%A_ScriptDir%\[Debug] %FNameNoExt%.%FExt%,UTF-8-RAW
    }
  }

ExitApp






;##################################################################################
;##################################################################################
;##################################################################################

ReadDictionary(sFilePath)
  {
  FileRead,sJSON1_old,*P65001 %sFilePath%

  iLevel:=0
  sSection:=""
  iCount:=0
  obj_return := {}

  loop,parse,sJSON1_old,`n,`r
    {
    sText:=Trim(A_LoopField)
  
    if (sText="{")
      {
      iLevel++
      iFoundKey:=0
      iFoundLang:=0
      continue
      }
    else if (sText="},")||(sText="}")
      {
      if (iLevel=3)
        {
        if !IsObject(obj_return[sSection])
          {
          clipboard:=A_Index
          msgbox,,Error A,Section %sSection% not yet part of return object.
          }

        PairObj:={}
        obj_return[sSection][sEntryJP] := sEntryEN
        }

      iLevel--
      continue
      }

    if (iLevel=1)
      {
      if RegExMatch(sText,"^""([a-z]*)"": \[$",sKey)
        {
        iLevel++
      
        if (sKey1!="text")&&(sKey1!="chara")&&(sKey1!="hint")&&(sKey1!="graphic")&&(sKey1!="eval")&&(sKey1!="branch")
          {
          clipboard:=A_Index
          msgbox,,Error B,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
          }

        sSection:=sKey1
      
        if !IsObject(obj_return[sSection])
          obj_return[sSection] := {}
      
        continue
        }
      else
        {
        clipboard:=A_Index
        msgbox,,Error C,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
        }
      }
    else if (iLevel=2)
      {
      if (sText="],")||(sText="]")
        {
        iLevel--
        continue
        }
      else if (sText="")
        {
        }
      else
        {
        clipboard:=A_Index
        msgbox,,Error D,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
        }
      }
    else if (iLevel=3)
      {
      pos1:=instr(sText,"""key"":",0,1)
      pos2:=instr(sText,"""en-US"":",0,1)

      if (pos1=1)
        {
        if (iFoundKey=1)
          {
          clipboard:=A_Index
          msgbox,,Error E,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
          }
        else
          {
          iFoundKey=1
          sVal:=substr(sText,7)
          sVal:=Trim(sVal," ")

          sFirst:=substr(sVal,1,1)
          sLast:=substr(sVal,strlen(sVal),1)
          sPreLast:=substr(sVal,strlen(sVal)-1,1)

          if (iFoundLang=1)  ; language entry "en-US" was first -> this "key" entry is second -> no comma
            {
            if (sFirst!="""")||(sLast!="""")
              {
              clipboard:=A_Index
              msgbox,,Error F,Bad formating in %sText%
              }
            else
              {
              sEntryJP:=substr(sVal,2,strlen(sVal)-2)
              }
            }
          else        ; language entry "en-US" still missing -> this "key" goes first -> has comma
            {
            if (sFirst!="""")||(sPreLast!="""")||(sLast!=",")
              {
              clipboard:=A_Index
              msgbox,,Error G,Bad formating in %sText%
              }
            else
              {
              sEntryJP:=substr(sVal,2,strlen(sVal)-3)
              }
            }
          }
        }
      else if (pos2=1)
        {
        if (iFoundLang=1)
          {
          clipboard:=A_Index
          msgbox,,Error H,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
          }
        else
          {
          iFoundLang=1
          sVal:=substr(sText,9)
          sVal:=Trim(sVal," ")

          sFirst:=substr(sVal,1,1)
          sLast:=substr(sVal,strlen(sVal),1)
          sPreLast:=substr(sVal,strlen(sVal)-1,1)

          if (iFoundKey=0)  ; "key" entry still missing -> this language entry goes first -> has comma
            {
            if (sVal="null,")
              sEntryEN:="null"
            else
              {
              if (sFirst!="""")||(sPreLast!="""")||(sLast!=",")
                {
                clipboard:=A_Index
                msgbox,,Error I,Bad formating in %sText%
                }
              else
                {
                sEntryEN:=substr(sVal,2,strlen(sVal)-3)
                }
              }
            }
          else        ; "key" entry already exists -> this language entry is second -> no comma
            {
            if (sVal="null")
              sEntryEN:=sVal
            else
              {
              if (sFirst!="""")||(sLast!="""")
                {
                clipboard:=A_Index
                msgbox,,Error J,Bad formating in %sText%
                }
              else
                {
                sEntryEN:=substr(sVal,2,strlen(sVal)-2)
                }
              }
            }
          }
        }
      else
        {
        clipboard:=A_Index
        msgbox,,Error K,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
        }
      }
    else
      {
      clipboard:=A_Index
      msgbox,,Error L,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
      }
    }

  return obj_return
  }


ProcessKeyDump(sFilePath,dictobj1,dictobj2,dictobj3,bOmitAsciiKeys)
  {
  if !FileExist(sFilePath)
    {
    msgbox,,Error,ProcessKeyDump() can't find file:`n%sFilePath%
    ExitApp
    }

  FileRead,sJSON1_old,*P65001 %sFilePath%

  iLevel:=0
  sSection:=""
  iCount:=0
  obj_return := {}

  sReturn := ""

  loop,parse,sJSON1_old,`n,`r
    {
    sText:=Trim(A_LoopField)
  
    if (sText="{")
      {
      iLevel++
      iFoundKey:=0
      iFoundLang:=0
    
      if (iLevel!=3)
        sReturn .= A_LoopField "`n"
      continue
      }
    else if (sText="},")||(sText="}")
      {
      if (iLevel=3)
        {
        if !IsObject(obj_return[sSection])
          {
          clipboard:=A_Index
          msgbox,,Error A,Section %sSection% not yet part of return object.
          }
        obj_return[sSection][sEntryJP] := sEntryEN

        if (sSection="graphic")
          {
          ; Since this sections contains only ascii image pathes for buttons and ascii translated Tooltip texts, we need to get it this way
          bNonAscii=1
          }
        else
          {
          bNonAscii=0
          if (bOmitAsciiKeys=1)
            {
            loop,parse,sEntryJP
              {
              k_unicode:=asc(A_LoopField)
              if (k_unicode>256)  ;(k_unicode>=0x2000)
                {
                bNonAscii=1
                break
                }
              }
            }
          }

        if (bNonAscii=1)||(bOmitAsciiKeys=0)
          {
          sReturn .= "    {`n      ""key"": """ sEntryJP """,`n"

          ;-----------------------------------------------------
          ; This is where the translations are actually applied

          if IsObject(dictobj1)
            {
            sEntryEN1 := dictobj1[sSection][sEntryJP]
            if (sEntryEN1!="") && (sEntryEN1!="null")
              sEntryEN := sEntryEN1
            }

          if IsObject(dictobj2)
            {
            sEntryEN2 := dictobj2[sSection][sEntryJP]
            if ((sEntryEN="") || (sEntryEN="null")) && (sEntryEN2!="") && (sEntryEN2!="null")
              sEntryEN := sEntryEN2
            }

          if IsObject(dictobj3)
            {
            sEntryEN3 := dictobj3[sSection][sEntryJP]
            if ((sEntryEN="") || (sEntryEN="null")) && (sEntryEN3!="")&&(sEntryEN3!="null")
              sEntryEN := sEntryEN3
            }

          ;-----------------------------------------------------
          ; We could do some formating with string replace at this point if necessary.
          sEntryEN := StrReplace(sEntryEN,  " [p]",  "[p]")
          sEntryEN := StrReplace(sEntryEN,  " [r]",  "[r]")
          sEntryEN := StrReplace(sEntryEN,  " [l]",  "[l]")
          sEntryEN := StrReplace(sEntryEN, " [lr]", "[lr]")
          sEntryEN := StrReplace(sEntryEN," [lr_]","[lr_]")
          ;-----------------------------------------------------
        
          if (sEntryEN="null")
            sReturn .= "      ""en-US"": null`n    " sText "`n"
          else
            sReturn .= "      ""en-US"": """ sEntryEN """`n    " sText "`n"
          }
        }
      else
        sReturn .= A_LoopField "`n"

      iLevel--
      continue
      }

    if (iLevel=1)
      {
      if RegExMatch(sText,"^""([a-z]*)"": \[$",sKey)
        {
        iLevel++
      
        if (sKey1!="text")&&(sKey1!="chara")&&(sKey1!="hint")&&(sKey1!="graphic")&&(sKey1!="eval")&&(sKey1!="branch")
          {
          clipboard:=A_Index
          msgbox,,Error B,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
          }

        sSection:=sKey1
      
        if !IsObject(obj_return[sSection])
          obj_return[sSection] := {}
      
        sReturn .= A_LoopField "`n"
        continue
        }
      else
        {
        clipboard:=A_Index
        msgbox,,Error C,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
        }
      }
    else if (iLevel=2)
      {
      if (sText="],")||(sText="]")
        {
        iLevel--
        sReturn .= A_LoopField "`n"
        continue
        }
      else if (sText="")
        {
        }
      else
        {
        clipboard:=A_Index
        msgbox,,Error D,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n_%sText%_
        }
      }
    else if (iLevel=3)
      {
      pos1:=instr(sText,"""key"":",0,1)
      pos2:=instr(sText,"""en-US"":",0,1)

      if (pos1=1)
        {
        if (iFoundKey=1)
          {
          clipboard:=A_Index
          msgbox,,Error E,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
          }
        else
          {
          iFoundKey=1
          sVal:=substr(sText,7)
          sVal:=Trim(sVal," ")

          sFirst:=substr(sVal,1,1)
          sLast:=substr(sVal,strlen(sVal),1)
          sPreLast:=substr(sVal,strlen(sVal)-1,1)

          if (iFoundLang=1)  ; language entry "en-US" was first -> this "key" entry is second -> no comma
            {
            if (sFirst!="""")||(sLast!="""")
              {
              clipboard:=A_Index
              msgbox,,Error F,Bad formating in %sText%
              }
            else
              {
              sEntryJP:=substr(sVal,2,strlen(sVal)-2)
              }
            }
          else        ; language entry "en-US" still missing -> this "key" goes first -> has comma
            {
            if (sFirst!="""")||(sPreLast!="""")||(sLast!=",")
              {
              clipboard:=A_Index
              msgbox,,Error G,Bad formating in %sText%
              }
            else
              {
              sEntryJP:=substr(sVal,2,strlen(sVal)-3)
              }
            }
          }
        }
      else if (pos2=1)
        {
        if (iFoundLang=1)
          {
          clipboard:=A_Index
          msgbox,,Error H,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
          }
        else
          {
          iFoundLang=1
          sVal:=substr(sText,9)
          sVal:=Trim(sVal," ")

          sFirst:=substr(sVal,1,1)
          sLast:=substr(sVal,strlen(sVal),1)
          sPreLast:=substr(sVal,strlen(sVal)-1,1)

          if (iFoundKey=0)  ; "key" entry still missing -> this language entry goes first -> has comma
            {
            if (sVal="null,")
              sEntryEN:="null"
            else
              {
              if (sFirst!="""")||(sPreLast!="""")||(sLast!=",")
                {
                clipboard:=A_Index
                msgbox,,Error I,Bad formating in %sText%
                }
              else
                {
                sEntryEN:=substr(sVal,2,strlen(sVal)-3)
                }
              }
            }
          else        ; "key" entry already exists -> this language entry is second -> no comma
            {
            if (sVal="null")
              sEntryEN:=sVal
            else
              {
              if (sFirst!="""")||(sLast!="""")
                {
                clipboard:=A_Index
                msgbox,,Error J,Bad formating in %sText%
                }
              else
                {
                sEntryEN:=substr(sVal,2,strlen(sVal)-2)
                }
              }
            }
          }
        }
      else
        {
        clipboard:=A_Index
        msgbox,,Error K,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
        }
      }
    else
      {
      clipboard:=A_Index
      msgbox,,Error L,Level %iLevel% / Key %sSection% / Line %A_Index%`n`n"%sText%"
      }
    }

  sReturn:=RTrim(sReturn,"`r`n")

  ; Remove unnecessary comma when retransitioning from CJK-> Ascii keys before the end of a section
  sReturn := StrReplace(sReturn,"`n    },`n  ],`n","`n    }`n  ],`n")

  return sReturn
  }
weren't that already present somewhere ? I remember using it or something like it like 2-4 years ago..
That one i am thinking was written in java or javascript i think
 

maraskanuser

New Member
Mar 23, 2020
2
0
weren't that already present somewhere ? I remember using it or something like it like 2-4 years ago..
That one i am thinking was written in java or javascript i think
No idea. I don't do javascript.

Anybody know what's up with the shibari related commented out lines in both patches?

Like
Code:
;;Custom Clothing
;;[if exp="f.lust>=200" ][button target="*u_shi" graphic="clothe/u_shi.png" x="680" y="165" ][endif]
;;End Custom Clothing
and

Code:
;;Custom Clothing
;;add shibari to purchased clothing
;;*u_shi
;;[cm][call target="*shibari" ](Testing [jump target="*buy" ]

;;Set Shibari Active
;;*shibari
;;[eval exp="f.Du_xc[0]='got'" ]
;;End Custom Clothing
in 'shop_night.ks' ?
 

przemo10371

Active Member
Modder
Feb 3, 2018
656
939
No idea. I don't do javascript.

Anybody know what's up with the shibari related commented out lines in both patches?

Like
Code:
;;Custom Clothing
;;[if exp="f.lust>=200" ][button target="*u_shi" graphic="clothe/u_shi.png" x="680" y="165" ][endif]
;;End Custom Clothing
and

Code:
;;Custom Clothing
;;add shibari to purchased clothing
;;*u_shi
;;[cm][call target="*shibari" ](Testing [jump target="*buy" ]

;;Set Shibari Active
;;*shibari
;;[eval exp="f.Du_xc[0]='got'" ]
;;End Custom Clothing
in 'shop_night.ks' ?
Maybe placeholder for future events/content
 

TheBlueKnight

Discussion Dynamo
Respected User
Jr. Uploader
Oct 1, 2018
25,468
19,480
So what is the requirements for her to walk around nude?
Don't think the precise numbers are anywhere, but keep raising her intimacy and lust and she'll eventually do it. As long as you have the modded transfix.
Is the game being updated by the original developer or is it all modding at this point?
There's going to be a version 3.0.0 eventually, look back here.
 
  • Like
Reactions: Dank Quixote
4.50 star(s) 119 Votes