Skip to content

Commit

Permalink
Fix: [DB/Scripts] Fixed placeholder-replacement functions (used in sc…
Browse files Browse the repository at this point in the history
…ripts and other elements). Report: BigMac
  • Loading branch information
GWRon committed Dec 4, 2016
1 parent d21ebc3 commit c4993d1
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 43 deletions.
2 changes: 1 addition & 1 deletion res/database/Default/database_scripts.xml
Expand Up @@ -296,7 +296,7 @@
</group>
<date>
<!-- either add the game year (with space!), or nothing -->
<de> %GAMEYEAR%|</de>
<de> %WORLDTIME:YEAR%</de>
</date>
</variables>

Expand Down
2 changes: 1 addition & 1 deletion res/database/Default/user/therob.xml
Expand Up @@ -2615,7 +2615,7 @@
</type>
<groaners>
<de>Gags|Kalauer|Witze|Scherze|Ulk|Zoten|Späßchen</de>
<en>Gags|Laughs|Jests|Yarns</en>
<en>Gags|Laughs|Jests|Yarns|Jokes|Pranks|Frolics</en>
</groaners>
</variables>
<jobs>
Expand Down
9 changes: 7 additions & 2 deletions source/Dig/base.util.string.bmx
Expand Up @@ -105,11 +105,13 @@ Import "external/string_comp.bmx"
Type StringHelper
'extracts and returns all placeholders in a text
'ex.: Hi my name is %NAME%
Function ExtractPlaceholders:string[](text:string, placeHolderChar:string="%")
Function ExtractPlaceholders:string[](text:string, placeHolderChar:string="%", stripPlaceHolderChar:int = False)
local result:string[]
local readingPlaceHolder:int = False
local currentPlaceHolder:string = ""
local char:string
'char for grouping placeholders: "%person:name%"
local splitterChar:int = Asc(":")
For local i:int = 0 until text.length
char = chr(text[i])
'found a potential placeholder start
Expand All @@ -122,14 +124,17 @@ Type StringHelper
If char = placeHolderChar and currentPlaceHolder.find(placeHolderChar) >= 0
readingPlaceHolder = False
result :+ [currentPlaceHolder+char]
if stripPlaceHolderChar
result[result.length-1] = result[result.length-1][1 .. result[result.length-1].length-1]
endif
currentPlaceHolder = ""
'go on with next char
continue
EndIf

'add the placeHolderChar and alphanumeric characters to
'the placeholder value
If IsAlphaNum(Asc(char)) or char = placeHolderChar
If IsAlphaNum(Asc(char)) or char = placeHolderChar or text[i] = splitterChar
currentPlaceHolder :+ char
'found something different
'ex.: a single placeholderChar ("The % of %ALL% is %X%")
Expand Down
91 changes: 56 additions & 35 deletions source/common.misc.templatevariables.bmx
Expand Up @@ -6,6 +6,12 @@ Import "Dig/base.util.string.bmx"
Import "game.gameinformation.base.bmx" 'to access worldtime



'By default templatevariables use the registered variables and placeholders
'but also default ones via GetGameInformation(placeHolder.toLower(), "")
'to fill in the corresponding data.
'so when adding new placeholder-handlers, also check the gameinformation
'system if it is containing them already
Type TTemplateVariables
'Variables are used to replace certain %KEYWORDS% in title or
'description. They are stored as "%KEYWORD%"=>TLocalizedString
Expand Down Expand Up @@ -116,45 +122,60 @@ Type TTemplateVariables

Method ReplacePlaceholders:TLocalizedString(text:TLocalizedString)
local result:TLocalizedString = text.copy()

'do it 3 times, this allows for placeholder definitions within
'placeholders (at least some of them)!
for local i:int = 0 to 2
'for each defined language we check for existent placeholders
'which then get replaced by a random string stored in the
'variable with the same name
For local lang:string = EachIn text.GetLanguageKeys()
'print "ReplacePlaceholders: "+ text.Get()
'for each defined language we check for existent placeholders
'which then get replaced by a random string stored in the
'variable with the same name
For local lang:string = EachIn text.GetLanguageKeys()
'do it 4 times, this allows for placeholder definitions within
'placeholders (at least some of them)!
local replacedPlaceholders:int = 0
for local i:int = 0 to 3
'use result already (to allow recursive-replacement)
local value:string = result.Get(lang)
local placeHolders:string[] = StringHelper.ExtractPlaceholders(value, "%")

local replacement:TLocalizedString
for local placeHolder:string = EachIn placeHolders
'check if there is already a placeholder variable stored
replacement = GetPlaceholderVariableString(placeHolder, "", False)
'check if the variable is defined (this leaves global
'placeholders like %ACTOR% intact even without further
'variable definition)
if not replacement then replacement = GetVariableString(placeHolder, "", False)
'only use ONE option out of the group ("option1|option2|option3")
if replacement
replacement = GetRandomFromLocalizedString( replacement )
'if the parent stores this variable (too) then save
'the placeholder there instead of the children
'so other children could use the same placeholders
'(if there is no parent then "self" is returned)
local parent:TTemplateVariables = GetParentTemplateVariables()
if parent and parent.GetVariableString(placeHolder, "", False)
parent.AddPlaceHolderVariable(placeHolder, replacement)
else
AddPlaceHolderVariable(placeHolder, replacement)
if placeHolders.length > 0
'if lang="de" then print " "+lang+" run "+i
'if lang="de" then print " -> value = " + value
local replacement:TLocalizedString
for local placeHolder:string = EachIn placeHolders
'check if there is already a placeholder variable stored
replacement = GetPlaceholderVariableString(placeHolder, "", False)
'check if the variable is defined (this leaves global
'placeholders like %ACTOR% intact even without further
'variable definition)
if not replacement then replacement = GetVariableString(placeHolder, "", False)
'only use ONE option out of the group ("option1|option2|option3")
if replacement
replacement = GetRandomFromLocalizedString( replacement )

'if the parent stores this variable (too) then save
'the placeholder there instead of the children
'so other children could use the same placeholders
'(if there is no parent then "self" is returned)
local parent:TTemplateVariables = GetParentTemplateVariables()
if parent and parent.GetVariableString(placeHolder, "", False)
parent.AddPlaceHolderVariable(placeHolder, replacement)
else
AddPlaceHolderVariable(placeHolder, replacement)
endif
'store the replacement in the value
value = value.replace(placeHolder, replacement.Get(lang))
'if lang="de" then print " replace: "+placeHolder+" => " + replacement.Get(lang)
replacedPlaceHolders :+ 1
endif
'store the replacement in the value
value = value.replace(placeHolder, replacement.Get(lang))
endif
Next
Next
endif

result.Set(value, lang)
'if placeHolders.length > 0
' if lang="de" then print " <- value = " + value
'endif
'skip further checks (0 placeholders or all possible replaced)
if placeHolders.length = 0 or (placeHolders.length > 0 and replacedPlaceHolders = 0)
exit
endif
Next
Next

Expand All @@ -163,14 +184,14 @@ Type TTemplateVariables
'loop over "text", but replace in "result"
For local lang:string = EachIn text.GetLanguageKeys()
local value:string = result.Get(lang)
local placeHolders:string[] = StringHelper.ExtractPlaceholders(value, "%")
local placeHolders:string[] = StringHelper.ExtractPlaceholders(value, "%", True)
for local placeHolder:string = EachIn placeHolders
local replacement:string = string(GetGameInformation(placeHolder.toLower(), ""))
local replacement:string = string(GetGameInformation(placeHolder.toLower().replace("%", ""), ""))
if replacement = "UNKNOWN_INFORMATION"
replacement = placeHolder
endif

value = value.replace(placeHolder, replacement)
value = value.replace("%"+placeHolder+"%", replacement)
Next

result.Set(value, lang)
Expand Down
3 changes: 2 additions & 1 deletion source/game.database.bmx
Expand Up @@ -1941,7 +1941,8 @@ Type TDatabaseLoader
local localized:TLocalizedString = new TLocalizedString
For local nodeLangEntry:TxmlNode = EachIn TxmlHelper.GetNodeChildElements(node)
local language:String = nodeLangEntry.GetName().ToLower()
local value:String = nodeLangEntry.getContent().Trim()
'do not trim, as this corrupts variables like "<de> %WORLDTIME:YEAR%</de>" (with space!)
local value:String = nodeLangEntry.getContent() '.Trim()

if value <> ""
localized.Set(value, language)
Expand Down
8 changes: 6 additions & 2 deletions source/game.gameinformation.base.bmx
Expand Up @@ -19,7 +19,7 @@ Type TGameInformationCollection


Method AddProvider(providerKey:string, provider:TGameInformationProvider)
providers.Insert(providerKey, provider)
providers.Insert(providerKey.ToUpper(), provider)
End Method


Expand All @@ -32,7 +32,11 @@ Type TGameInformationCollection
if key="" and providerKey.Find(":") >= 0
local p:string[] = providerKey.split(":")
providerKey = p[0]
key = p[1]
if p.length > 1
key = p[1]
else
return "UNKNOWN_INFORMATION"
endif
endif
local provider:TGameInformationProvider = GetProvider(providerKey)
if provider then return provider.Get(key, params)
Expand Down
2 changes: 1 addition & 1 deletion source/game.gameinformation.bmx
Expand Up @@ -316,7 +316,7 @@ Type TWorldTimeInformationProviderBase extends TGameInformationProvider

Method Get:object(key:string, params:object)
Select key.ToLower()
Case "year"
Case "year", "gameyear"
return string( GetWorldTime().GetYear() )
Case "day"
return string( GetWorldTime().GetOnDay() )
Expand Down

0 comments on commit c4993d1

Please sign in to comment.