From 5250151f920b7c0e9d800ea651929791d392af6a Mon Sep 17 00:00:00 2001 From: FaceDeer Date: Sun, 8 Jan 2023 23:06:18 -0700 Subject: [PATCH] add random name generators for goblin and under markets --- autotranslate.py | 133 +++++++++++++++++++++++++++ goblin_markets.cfg | 12 +++ locale/commoditymarket_fantasy.ru.tr | 7 ++ locale/template.txt | 5 + mapgen_dungeon_markets.lua | 77 +++++++++++++++- mod.conf | 2 +- settingtypes.txt | 12 +++ under_markets.cfg | 13 +++ 8 files changed, 258 insertions(+), 3 deletions(-) create mode 100644 autotranslate.py create mode 100644 goblin_markets.cfg create mode 100644 under_markets.cfg diff --git a/autotranslate.py b/autotranslate.py new file mode 100644 index 0000000..583d8d6 --- /dev/null +++ b/autotranslate.py @@ -0,0 +1,133 @@ +# A quick-and-dirty script to run untranslated text through Google Translate's API. +# The result will likely include comical errors a native speaker will laugh at you for +# or that will puzzle them, and some manual correction of escaped codes such as @1 and @= may be +# required, but hopefully it will serve as a start to something useful + +# Copyright (C) 2020 FaceDeer +# LGPLv2.1+ + +# See https://github.com/minetest-tools/update_translations for +# potential future updates to this script. + +from googletrans import Translator, LANGUAGES +import os, re, shutil + +pattern_tr_filename = re.compile(r'\.tr$') +pattern_tr_id = re.compile(r'\.([^.]*)\.tr$') +pattern_line_to_translate = re.compile(r'^([^#].*[^@])=$') #finds lines that don't have a translation + +translator = Translator() + +def translate(tr_filename): + lang_id = pattern_tr_id.search(tr_filename) + if not lang_id: + print("Could not find language ID in tr filename " + tr_filename) + return + + lang_id = lang_id.group(1) + + if not lang_id in LANGUAGES: + print("language ID " + lang_id + " is not supported by Google Translate's API") + return + + lines_to_translate = [] # this list of strings will ultimately be sent to Google for translation + with open(tr_filename, "r", encoding="utf-8") as tr_file_handle: + for line in tr_file_handle: + # Look for lines that end in "=", ie, that don't have a valid translation added to them + line_lacking_translation = pattern_line_to_translate.search(line) + if line_lacking_translation: + #break the line up at @n markers, this is not ideal for Google + #as it may remove some context but it's necessary to allow the + #@n markers to be preserved in the output later + lines_to_translate = lines_to_translate + line_lacking_translation.group(1).split("@n") + + # Remove duplicates, and the empty string (a common artefact of splitting) + line_set = set(lines_to_translate) + line_set.discard("") + lines_to_translate = list(line_set) + + # Only do more work if there are lines in need of translation + if lines_to_translate: + print("Calling Google API for " + tr_filename) + output = translator.translate(lines_to_translate, src="en", dest=lang_id) + + #convert the output translations into a dictionary for easy substitution later + translation_dictionary = dict() + for out_line in output: + #Google's API sometimes seems to fail to translate a line for no apparent reason + #Don't put them in the dictionary, we can leave those untranslated and maybe try again + if out_line.origin != out_line.text: + translation_dictionary[out_line.origin] = out_line.text + + translation_dictionary["@n"] = "@n" #These are to be left unchanged + + tr_file_handle.seek(0) + with open(tr_filename + ".temp", "w", encoding="utf-8") as tr_file_new: + for line in tr_file_handle: + line_lacking_translation = pattern_line_to_translate.search(line) + if line_lacking_translation: + line = line.rstrip('\n') #remove trailing newline so we can add the translated string to the same line + line_split = re.split("(@n)", line[:-1]) #slice to leave off the "=" that's the last character of the line + translated_line = "" + + #After splitting the line up on @n again, as was done before, we should have + #line segments that match the strings that were sent to Google. + for line_piece in line_split: + if line_piece in translation_dictionary: + translated_line = translated_line + translation_dictionary[line_piece] + else: + print("Google returned string unchanged in file " + tr_filename + ":") + print(line_piece) + translated_line = None + break + + if translated_line: + tr_file_new.write("#WARNING: AUTOTRANSLATED BY GOOGLE TRANSLATE\n") + tr_file_new.write(line) + tr_file_new.write(translated_line) + tr_file_new.write("\n") + else: + tr_file_new.write(line) + tr_file_new.write("\n") + else: + tr_file_new.write(line) + shutil.move(tr_filename + ".temp", tr_filename) # Overwrite the original file with the new one + +pattern_domain = re.compile(r'^# textdomain: (.+)$') + +def create_tr_files_from_template(folder, lang_id): + if not lang_id in LANGUAGES: + print("language ID " + lang_id + " is not supported by Google Translate's API") + return + for root, dirs, files in os.walk(folder): + if root == "." or os.path.split(root)[1] == "locale": + for name in files: + if name == "template.txt": + template_filename = os.path.join(root,name) + with open(template_filename, "r", encoding="utf-8") as template_file: + first_line = template_file.readline() + domain = pattern_domain.search(first_line) + if domain: + translation_filename = domain.group(1) + "." + lang_id + ".tr" + translation_filename = os.path.join(root,translation_filename) + if not os.path.isfile(translation_filename): + print("Copying template.txt to " + translation_filename) + shutil.copy(template_filename, translation_filename) + else: + print(translation_filename + " already exists") + +#If there are already .tr files in /locale, returns a list of their names +def get_existing_tr_files(folder): + out = [] + for root, dirs, files in os.walk(folder): + for name in files: + if pattern_tr_filename.search(name): + out.append(os.path.join(root,name)) + return out + +#create_tr_files_from_template(".", "de") +#create_tr_files_from_template(".", "it") + +tr_files = get_existing_tr_files(".") +for tr_file in tr_files: + translate(tr_file) diff --git a/goblin_markets.cfg b/goblin_markets.cfg new file mode 100644 index 0000000..aba7565 --- /dev/null +++ b/goblin_markets.cfg @@ -0,0 +1,12 @@ +name "goblin_markets" { + + customGroupA = "Ach Adz Ak Ark Az Balg Bilg Blid Blig Blok Blot Bolg Boor Bot Bug Burk Chu Dokh Drik Driz Drub Duf Flug Gaw Gad Gag Gah Gak Gar Gat Gaz Ghag Ghak Ghor Git Glag Glak Glat Glig Gliz Glok Gnat Gog Grak Grat Guk Hig Irk Kak Kav Khad Krig Lag Lak Lig Likk Loz Luk Lun Mak Maz Miz Mog Mub Mur Nad Nag Naz Nig Nikk Nogg Nok Nukk Nur Pog Rag Rak Rat Rok Ronk Rot Shrig Shuk Skrag Skug Slai Slig Slog Sna Snag Snark Snat Snig Snik Snit Sog Spik Stogg Tog Unk Urf Vark Vog Yad Yagg Yak Yark Yarp Yig Yip Zat Zib Zit Ziz Zob Zord" + + customGroupB = "ach adz ak ark awg az balg bilg blid blig blok blot bolg bot bug burk bus dokh drik driz duf ffy flug g ga gad gag gah gak gar gat gaz ghag ghak git glag glak glat glig gliz glok gnat gog grak grat gub guk hig irk kak khad krig lag lak lig likk loz luk mak maz miz mub murch nad nag naz nig nikk nogg nok nukk og plus rag rak rat rkus rok shrig shuk skrag skug slai slig slog sna snag snark snat snig snik snit sog spik stogg thus tog un urf us vark yad yagg yak yark yarp yig yip zat zib zit ziz" + + customGroupC = "Exchange Shop Post Dump Stash Emporium Outlet Stall Stand Lot Stockpile Stock Lode Cache Pile Wares Hoard Heap" + + syllablesPost = "ah, ay, e, ee, gah, ghy, y, ya" + + rules = "%50$A$90B$10B's_$C, %35$A$p's_$C, %15$A$B$p's_$C" +} \ No newline at end of file diff --git a/locale/commoditymarket_fantasy.ru.tr b/locale/commoditymarket_fantasy.ru.tr index 354f868..cc24189 100644 --- a/locale/commoditymarket_fantasy.ru.tr +++ b/locale/commoditymarket_fantasy.ru.tr @@ -42,6 +42,13 @@ Gold coins can be deposited and withdrawn from markets that accept them as curre Right-click on this to open the market interface.=Кликните правой кнопкой мыши на это, чтобы открыть рыночный интерфейс. +### mapgen_dungeon_markets.lua ### + +#WARNING: AUTOTRANSLATED BY GOOGLE TRANSLATE +A Goblin Exchange=Обмен гоблинов +#WARNING: AUTOTRANSLATED BY GOOGLE TRANSLATE +An Undermarket=Подрынок + ### village_markets.lua ### At this time of day the King's Market is closed.=В это время дня Королевский рынок закрыт. diff --git a/locale/template.txt b/locale/template.txt index 1de10e7..6f2e770 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -41,6 +41,11 @@ Gold coins can be deposited and withdrawn from markets that accept them as curre Right-click on this to open the market interface.= +### mapgen_dungeon_markets.lua ### + +A Goblin Exchange= +An Undermarket= + ### village_markets.lua ### At this time of day the King's Market is closed.= diff --git a/mapgen_dungeon_markets.lua b/mapgen_dungeon_markets.lua index fb766f2..643498e 100644 --- a/mapgen_dungeon_markets.lua +++ b/mapgen_dungeon_markets.lua @@ -1,5 +1,8 @@ -local goblin_enabled = minetest.settings:get_bool("commoditymarket_enable_goblin_market") -local under_enabled = minetest.settings:get_bool("commoditymarket_enable_under_market") +local S = commoditymarket_fantasy.S +local modpath = minetest.get_modpath(minetest.get_current_modname()) + +local goblin_enabled = minetest.settings:get_bool("commoditymarket_enable_goblin_market", true) +local under_enabled = minetest.settings:get_bool("commoditymarket_enable_under_market", true) local goblin_prob = tonumber(minetest.settings:get("commoditymarket_goblin_market_dungeon_prob")) or 0.25 local under_prob = tonumber(minetest.settings:get("commoditymarket_under_market_dungeon_prob")) or 0.1 @@ -25,7 +28,61 @@ if not (gen_goblin or gen_under) then return end +------------------------------------------------------------- +-- Names and waypoints +local named_waypoints_modpath = minetest.get_modpath("named_waypoints") +local name_generator_modpath = minetest.get_modpath("name_generator") + +local goblin_named = minetest.settings:get_bool("commoditymarket_name_goblin_markets", true) and named_waypoints_modpath +local under_named = minetest.settings:get_bool("commoditymarket_name_under_markets", true) and named_waypoints_modpath + +local item_required = nil +if minetest.settings:get_bool("commoditymarket_hud_requires_item", true) then + item_required = minetest.settings:get("commoditymarket_hud_item_required") + if item_required == nil or item_required == "" then + item_required = "map:mapping_kit" + end +end + +if goblin_named then + local goblin_waypoint_def = { + default_name = S("A Goblin Exchange"), + default_color = 0x00A86B, -- jade green + discovery_volume_radius = 5, + visibility_requires_item = item_required, + } + if minetest.settings:get_bool("commoditymarket_show_goblin_markets_in_hud", true) then + goblin_waypoint_def.visibility_volume_radius = tonumber(minetest.settings:get("commoditymarket_hud_visibility_range")) or 250 + goblin_waypoint_def.on_discovery = named_waypoints.default_discovery_popup + end + + named_waypoints.register_named_waypoints("goblin_markets", goblin_waypoint_def) + + if name_generator_modpath then + name_generator.parse_lines(io.lines(modpath.."/goblin_markets.cfg")) + end +end + +if under_named then + local under_waypoint_def = { + default_name = S("An Undermarket"), + default_color = 0xB33000, -- darkened orangered + discovery_volume_radius = 5, + visibility_requires_item = item_required, + } + if minetest.settings:get_bool("commoditymarket_show_under_markets_in_hud", true) then + under_waypoint_def.visibility_volume_radius = tonumber(minetest.settings:get("commoditymarket_hud_visibility_range")) or 250 + under_waypoint_def.on_discovery = named_waypoints.default_discovery_popup + end + + named_waypoints.register_named_waypoints("under_markets", under_waypoint_def) + + if name_generator_modpath then + name_generator.parse_lines(io.lines(modpath.."/under_markets.cfg")) + end + +end ------------------------------------------------------- -- The following is shamelessly copied from dungeon_loot and tweaked for placing markets instead of chests --Licensed under the MIT License (MIT) Copyright (C) 2017 sfan5 @@ -125,6 +182,14 @@ minetest.register_on_generated(function(minp, maxp, blockseed) if minetest.get_node(under_loc).name == "air" and is_wall(vector.subtract(under_loc, {x=0, y=1, z=0})) then minetest.add_node(under_loc, {name="commoditymarket:under_market"}) + + local name = nil + if under_named then + if name_generator_modpath then + name = name_generator.generate("under_markets") + end + named_waypoints.add_waypoint("under_markets", under_loc, {name=name}) + end end end @@ -148,6 +213,14 @@ minetest.register_on_generated(function(minp, maxp, blockseed) -- make it face inwards to the room local facedir = minetest.dir_to_facedir(vector.multiply(wall.facing, -1)) minetest.add_node(marketpos, {name = "commoditymarket:goblin_market", param2 = facedir}) + + local name = nil + if goblin_named then + if name_generator_modpath then + name = name_generator.generate("goblin_markets") + end + named_waypoints.add_waypoint("goblin_markets", marketpos, {name=name}) + end end end end) \ No newline at end of file diff --git a/mod.conf b/mod.conf index cc3abde..7e0a05e 100644 --- a/mod.conf +++ b/mod.conf @@ -1,4 +1,4 @@ name = commoditymarket_fantasy description = Adds a number of fantasy-themed marketplaces depends = commoditymarket -optional_depends = doc, lorebooks, default, mcl_core, mcl_sounds, mcl_chests, mesecons_wires \ No newline at end of file +optional_depends = doc, lorebooks, default, mcl_core, mcl_sounds, mcl_chests, mesecons_wires, named_waypoints, name_generator \ No newline at end of file diff --git a/settingtypes.txt b/settingtypes.txt index 8fb49e0..2c84062 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -22,3 +22,15 @@ commoditymarket_goblin_market_dungeon_min (Lower y limit of goblin markets) int commoditymarket_under_market_dungeon_prob (Undermarket probability per dungeon mapblock) float 0.1 0 1 commoditymarket_under_market_dungeon_max (Upper y limit of undermarkets) int -500 commoditymarket_under_market_dungeon_min (Lower y limit of undermarkets) int -31000 + +[Dungeon market HUD markers] +commoditymarket_name_goblin_markets (Give names to goblin markets) bool true +commoditymarket_name_under_markets (Give names to undermarkets) bool true +commoditymarket_show_goblin_markets_in_hud (Show Goblin markets in HUD) bool true +commoditymarket_show_under_markets_in_hud (Show Undermarkets in HUD) bool true +commoditymarket_hud_requires_item (Require an item to view waypoints) bool true +#Players can still discover the locations of markets without this, but waypoints +#will only be visible in their hud if they have this item in their inventory. You can also +#specify "group:groupname" here. Leave it blank to default to map:mapping_kit. +commoditymarket_hud_item_required (Specify the item or group required) string map:mapping_kit +commoditymarket_hud_visibility_range (Dungeon market HUD visibility range) int 250 \ No newline at end of file diff --git a/under_markets.cfg b/under_markets.cfg new file mode 100644 index 0000000..f0f8257 --- /dev/null +++ b/under_markets.cfg @@ -0,0 +1,13 @@ +name "under_markets" { + + customGroupA = "Ach Akk Ash Azt Bahor Bar Bas Brax Charn Dak Hrax Lach Lazt Mat Nam Nazt Ralk Rhast Sark Slarv Tash Thak Thalur Thalk Vach Vap Dek Ech Fesh Gek Hrek Lech Met Ner Ter Blik Gith Igm Inax Irsch Kir Lis Lisk Lith Nilv Nirr Tlizit Bor Chon Goch Gor Goth Hoth Khor Kos Loch Lok Loth Moch Moth Noc Och Oth Rolk Roth Sot Soth Vrok Dun Gur Hun Luth Muth Nur Rutt Sut Sutt Szut Tur Urt Utuk Uzt Krych Nyth Slyth Gaan Xaas Boak Ruaak Yalm Haerx Iex Draum Gaur Glaur Rauk Saur Duum Nuur Ruun" + + customGroupB = "ach akk ash azt bahor bar bas brax charn dak hrax lach lazt mat nam nazt ralk rhast sark slarv tash thak thalur thalk vach vap dek ech fesh gek hrek lech met ner ter blik gith igm inax irsch kir lis lisk lith nilv nirr tlizit bor chon goch gor goth hoth khor kos loch lok loth moch moth noc och oth rolk roth sot soth vrok dun gur hun luth muth nur rutt sut sutt szut tur urt utuk uzt krych nyth slyth gaan xaas boak ruaak yalm haerx iex draum gaur glaur rauk saur duum nuur ruun" + + customGroupC = "Ruin Exchange Well Arch Altar Crucible Temple House Shrine Font Prison Cell Compact Station Bond Pact Contract Mise" + + phonemesVocals = "u u u o o i i a a e" + phonemesConsonants = "z y v r l j" + + rules = "The_$C_of_$A$v$c$B, The_$C_of_$A$c$v$B, The_$C_of_$A-$v$c$B, The_$C_of_$A-$c$v$B, $A$v$c$B's_$C, $A$c$v$B's_$C, $A-$v$c$B's_$C, $A-$c$v$B's_$C" +} \ No newline at end of file