Skip to content

Commit

Permalink
Merge branch 'develop' into adv-beta
Browse files Browse the repository at this point in the history
  • Loading branch information
myk002 committed Jan 10, 2025
2 parents 852a101 + ce07870 commit 9efec6e
Show file tree
Hide file tree
Showing 11 changed files with 483 additions and 147 deletions.
4 changes: 4 additions & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ Template for new versions:
- `preserve-rooms`: handle case where unit records are culled by DF immediately after a unit leaves the map
- `preserve-tombs`: properly re-enable after loading a game that had the tool enabled
- `zone`: assign animal to cage/restraint dialog now allows you to unassign a pet from the cage or restraint if the pet is already somehow assigned (e.g. war dog was in cage and was subsequently assigned to a dwarf)
- `stockpiles`: don't set ``use_links_only`` flag to a random value when the flag is not set to anything in the settings that are being imported
- `strangemood`: ensure generated names for artifacts match what the game itself would generate

## Misc Improvements
- `strangemood`: add ability to choose Stone Cutting and Stone Carving as the mood skill
Expand All @@ -72,10 +74,12 @@ Template for new versions:
## API
- ``Units::isUnitInBox``, ``Units::getUnitsInBox``: add versions accepting pos arguments
- ``Units::getVisibleName``: when acting on a unit without an impersonated identity, returns the unit's name structure instead of the associated histfig's name structure
- ``Translation::GenerateName``: generates in-game names, reimplemented based on DF's own logic

## Lua
- ``dfhack.units.isUnitInBox``, ``dfhack.units.getUnitsInBox``: add versions accepting pos arguments
- ``widgets.FilteredList``: search keys for list items can now be functions that return a string
- ``dfhack.GenerateName``: Lua API for ``Translation::GenerateName``

## Removed

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
25 changes: 22 additions & 3 deletions library/include/DataFuncs.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,28 @@ namespace df {
template<typename RT>
concept isPrimitive = identity_traits<RT>::is_primitive || std::is_enum_v<RT> || std::is_void_v<RT>;

template<typename T>
T get_from_lua_state(lua_State* L, int idx) {
T val;
// handle call-by-reference function arguments by converting pointers to a reference
// will throw if lua code tries to pass a null pointer
template<typename T> requires std::is_reference_v<T>
T get_from_lua_state(lua_State* L, int idx)
{
using DFHack::LuaWrapper::field_error;
using Ptr = std::add_pointer_t<std::remove_reference_t<T>>;
Ptr ptr{};
df::identity_traits<Ptr>::get()->lua_write(L, UPVAL_METHOD_NAME, &ptr, idx);
if (ptr == nullptr)
{
field_error(L, UPVAL_METHOD_NAME, "cannot convert null pointer to reference", "call");
}
return *ptr;
}

// handle call-by-value function arguments. only semi-regular types are allowed
// (semi-regular covers copyable and default-constructible)
template<std::semiregular T>
T get_from_lua_state(lua_State* L, int idx)
{
T val{};
df::identity_traits<T>::get()->lua_write(L, UPVAL_METHOD_NAME, &val, idx);
return val;
}
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.

2 changes: 1 addition & 1 deletion plugins/cursecheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ command_result cursecheck (color_ostream &out, vector <string> & parameters)

if (giveDetails)
{
out << (Units::getReadableName(unit));
out << DF2CONSOLE(Units::getReadableName(unit));

auto death = df::incident::find(unit->counters.death_id);
out.print(", born in %d, cursed in %d to be a %s. (%s%s)\n",
Expand Down
9 changes: 4 additions & 5 deletions plugins/stockpiles/StockpileSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -904,11 +904,10 @@ void StockpileSettingsSerializer::read_general(color_ostream& out, DeserializeMo

void StockpileSerializer::read_general(color_ostream& out, DeserializeMode mode) {
StockpileSettingsSerializer::read_general(out, mode);
bool use_links_only;
read_elem<bool, bool>(out, "use_links_only", mode,
std::bind(&StockpileSettings::has_use_links_only, mBuffer),
std::bind(&StockpileSettings::use_links_only, mBuffer),
use_links_only);
if (!mBuffer.has_use_links_only())
return;
bool use_links_only = mBuffer.use_links_only();
DEBUG(log, out).print("setting use_links_only to %d\n", use_links_only);
mPile->stockpile_flag.bits.use_links_only = use_links_only;
}

Expand Down
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
2 changes: 1 addition & 1 deletion scripts

0 comments on commit 9efec6e

Please sign in to comment.