Skip to content

Commit

Permalink
add Translation::GenerateName() (fixes #5166)
Browse files Browse the repository at this point in the history
Also available from Lua as "dfhack.generateName(...)"
  • Loading branch information
quietust committed Jan 9, 2025
1 parent 0a8b233 commit 5389ec0
Show file tree
Hide file tree
Showing 7 changed files with 453 additions and 137 deletions.
2 changes: 2 additions & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Template for new versions:
## New Tools

## New Features
- ``Translation::GenerateName``: generates in-game names, reimplemented based on DF's own logic. Also available in Lua as "dfhack.GenerateName".
- `stockpiles`: add simple import/export dialogs to stockpile overlay panel

## Fixes
Expand All @@ -66,6 +67,7 @@ Template for new versions:
## Misc Improvements
- `strangemood`: add ability to choose Stone Cutting and Stone Carving as the mood skill
- `suspendmanager`: add more specific messages for submerged jobsites and those managed by `buildingplan`
- `strangemood`: moved name generation logic into Translation module (and fixed some bugs)

## Documentation
- Added example code for creating plugin RPC endpoints that can be used to extend the DFHack API
Expand Down
4 changes: 4 additions & 0 deletions docs/dev/Lua API.rst
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,10 @@ can be omitted.

Convert a ``df.language_name`` (or only the last name part) to string.

* ``dfhack.GenerateName(name,language,type,major_selector,minor_selector)``

Dynamically generate a name using the same logic the game itself uses.

* ``dfhack.df2utf(string)``

Convert a string from DF's CP437 encoding to UTF-8.
Expand Down
2 changes: 2 additions & 0 deletions library/LuaApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ distribution.
#include "df/job.h"
#include "df/job_item.h"
#include "df/job_material_category.h"
#include "df/language_word_table.h"
#include "df/material.h"
#include "df/map_block.h"
#include "df/nemesis_record.h"
Expand Down Expand Up @@ -1374,6 +1375,7 @@ static const LuaWrapper::FunctionReg dfhack_module[] = {
WRAP(isMapLoaded),
WRAP(isSiteLoaded),
WRAPM(Translation, TranslateName),
WRAPM(Translation, GenerateName),
WRAP(df2utf),
WRAP(utf2df),
WRAP(df2console),
Expand Down
1 change: 1 addition & 0 deletions library/include/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ distribution.

#include "df/general_ref_type.h"
#include "df/specific_ref_type.h"
#include "df/language_name_type.h"

namespace df {
struct building;
Expand Down
3 changes: 3 additions & 0 deletions library/include/modules/Translation.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ distribution.
namespace df {
struct language_name;
struct language_translation;
struct language_word_table;
}

namespace DFHack
Expand All @@ -58,6 +59,8 @@ DFHACK_EXPORT std::string capitalize(const std::string &str, bool all_words = fa
// translate a name using the loaded dictionaries
DFHACK_EXPORT std::string TranslateName (const df::language_name * name, bool inEnglish = false,
bool onlyLastPart = false);

DFHACK_EXPORT void GenerateName(df::language_name *name, int language_index, df::language_name_type nametype, df::language_word_table *major_selector, df::language_word_table *minor_selector);
}
}
#endif
438 changes: 438 additions & 0 deletions library/modules/Translation.cpp

Large diffs are not rendered by default.

140 changes: 3 additions & 137 deletions plugins/strangemood.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "df/item.h"
#include "df/job.h"
#include "df/job_item.h"
#include "df/language_name_category.h"
#include "df/language_word.h"
#include "df/map_block.h"
#include "df/material.h"
Expand Down Expand Up @@ -144,141 +145,6 @@ int getCreatedMetalBars (int32_t idx)
return 0;
}

void selectWord (const df::language_word_table &table, int32_t &word, df::part_of_speech &part, int mode)
{
if (table.parts[mode].size())
{
int offset = rng.df_trandom(table.parts[mode].size());
word = table.words[mode][offset];
part = table.parts[mode][offset];
}
else
{
word = rng.df_trandom(world->raws.language.words.size());
part = (df::part_of_speech)(rng.df_trandom(9));
Core::getInstance().getConsole().printerr("Impoverished Word Selector");
}
}

void generateName(df::language_name &output, int language, const df::language_word_table &table1, const df::language_word_table &table2)
{
for (int i = 0; i < 100; i++)
{
output = df::language_name();
if (language == -1)
language = rng.df_trandom(world->raws.language.translations.size());
output.type = language_name_type::Artifact;
output.language = language;
output.has_name = 1;
if (output.language == -1)
output.language = rng.df_trandom(world->raws.language.translations.size());
int r, r2, r3;
r = rng.df_trandom(3);
if (r == 0 || r == 1)
{
if (rng.df_trandom(2))
{
selectWord(table2, output.words[0], output.parts_of_speech[0], 0);
selectWord(table1, output.words[1], output.parts_of_speech[1], 1);
}
else
{
selectWord(table1, output.words[0], output.parts_of_speech[0], 0);
selectWord(table2, output.words[1], output.parts_of_speech[1], 1);
}
}
if (r == 1 || r == 2)
{
r2 = rng.df_trandom(2);
if (r2)
selectWord(table1, output.words[5], output.parts_of_speech[5], 2);
else
selectWord(table2, output.words[5], output.parts_of_speech[5], 2);
r3 = rng.df_trandom(3);
if (rng.df_trandom(50))
r3 = rng.df_trandom(2);
switch (r3)
{
case 0:
case 2:
if (r3 == 2)
r2 = rng.df_trandom(2);
if (r2)
selectWord(table2, output.words[6], output.parts_of_speech[6], 5);
else
selectWord(table1, output.words[6], output.parts_of_speech[6], 5);
if (r3 == 0)
break;
r2 = -r2;
case 1:
if (r2)
selectWord(table1, output.words[2], output.parts_of_speech[2], 3);
else
selectWord(table2, output.words[2], output.parts_of_speech[2], 3);
if (!(rng.df_trandom(100)))
selectWord(table1, output.words[3], output.parts_of_speech[3], 3);
break;
}
}
if (rng.df_trandom(100))
{
if (rng.df_trandom(2))
selectWord(table1, output.words[4], output.parts_of_speech[4], 4);
else
selectWord(table2, output.words[4], output.parts_of_speech[4], 4);
}
if (output.words[2] != -1 && output.words[3] != -1 &&
world->raws.language.words[output.words[3]]->adj_dist < world->raws.language.words[output.words[2]]->adj_dist)
{
std::swap(output.words[2], output.words[3]);
std::swap(output.parts_of_speech[2], output.parts_of_speech[3]);
}
bool next = false;
if ((output.parts_of_speech[5] == df::part_of_speech::NounPlural) && (output.parts_of_speech[6] == df::part_of_speech::NounPlural))
next = true;
if (output.words[0] != -1)
{
if (output.words[6] == -1) next = true;
if (output.words[4] == -1) next = true;
if (output.words[2] == -1) next = true;
if (output.words[3] == -1) next = true;
if (output.words[5] == -1) next = true;
}
if (output.words[1] != -1)
{
if (output.words[6] == -1) next = true;
if (output.words[4] == -1) next = true;
if (output.words[2] == -1) next = true;
if (output.words[3] == -1) next = true;
if (output.words[5] == -1) next = true;
}
if (output.words[4] != -1)
{
if (output.words[6] == -1) next = true;
if (output.words[2] == -1) next = true;
if (output.words[3] == -1) next = true;
if (output.words[5] == -1) next = true;
}
if (output.words[2] != -1)
{
if (output.words[6] == -1) next = true;
if (output.words[3] == -1) next = true;
if (output.words[5] == -1) next = true;
}
if (output.words[3] != -1)
{
if (output.words[6] == -1) next = true;
if (output.words[5] == -1) next = true;
}
if (output.words[5] != -1)
{
if (output.words[6] == -1) next = true;
}
if (!next)
return;
}
}

command_result df_strangemood (color_ostream &out, vector <string> & parameters)
{
if (!Translation::IsValid())
Expand Down Expand Up @@ -1231,10 +1097,10 @@ command_result df_strangemood (color_ostream &out, vector <string> & parameters)

// Generate the artifact's name
if (type == mood_type::Fell || type == mood_type::Macabre)
generateName(unit->status.artifact_name, unit->name.language, world->raws.language.word_table[0][2], world->raws.language.word_table[1][2]);
Translation::GenerateName(&unit->status.artifact_name, unit->name.language, language_name_type::Artifact, &world->raws.language.word_table[0][language_name_category::ArtifactEvil], &world->raws.language.word_table[1][language_name_category::ArtifactEvil]);
else
{
generateName(unit->status.artifact_name, unit->name.language, world->raws.language.word_table[0][1], world->raws.language.word_table[1][1]);
Translation::GenerateName(&unit->status.artifact_name, unit->name.language, language_name_type::Artifact, &world->raws.language.word_table[0][language_name_category::Artifact], &world->raws.language.word_table[1][language_name_category::Artifact]);
if (!rng.df_trandom(100))
unit->status.artifact_name = unit->name;
}
Expand Down

0 comments on commit 5389ec0

Please sign in to comment.