Skip to content

Commit bb553a0

Browse files
committed
update moddable-gods
1 parent fdd597e commit bb553a0

3 files changed

Lines changed: 163 additions & 92 deletions

File tree

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Template for new versions:
2929
# Future
3030

3131
## New Tools
32+
- `modtools/moddable-gods`: (reinstated) create new deities from scratch
3233

3334
## New Features
3435
- `gui/mod-manager`: when run in a loaded world, shows a list of active mods -- click to export the list to the clipboard for easy sharing or posting

docs/modtools/moddable-gods.rst

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,47 @@ modtools/moddable-gods
33

44
.. dfhack-tool::
55
:summary: Create deities.
6-
:tags: unavailable
7-
8-
This is a standardized version of Putnam's moddableGods script. It allows you
9-
to create gods on the command-line.
10-
11-
Arguments::
12-
13-
-name godName
14-
sets the name of the god to godName
15-
if there's already a god of that name, the script halts
16-
-spheres [ sphereList ]
17-
define a space-separated list of spheres of influence of the god
18-
-gender male|female|neuter
19-
sets the gender of the god
20-
-depictedAs str
21-
often depicted as a str
22-
-verbose
23-
if specified, prints details about the created god
6+
:tags: dev
7+
8+
This script allows you to create new gods in an existing world.
9+
10+
Usage
11+
-----
12+
13+
::
14+
15+
moddable-gods --name <name> --spheres <sphereList> [<options>]
16+
17+
Examples
18+
--------
19+
20+
``modtools/moddable-gods --name "Slarty Bog" --spheres FATE,WEATHER``
21+
Create a new god named "Slarty Bog" with spheres of influence of FATE and
22+
WEATHER. The god will have a random gender and will be depicted as a dwarf.
23+
24+
``modtools/moddable-gods -n Og -s SPEECH,SALT,SACRIFICE -g neuter -d emu``
25+
Create a new god named "Og" with spheres of influence of SPEECH, SALT, and
26+
SACRIFICE. The god will be genderless and will be depicted as an emu.
27+
28+
Options
29+
-------
30+
31+
``-n``, ``--name <name>``
32+
The name of the god to create. This is a required argument. The name must
33+
be unique in the world. If the name is already taken, the script will exit
34+
without action.
35+
``-s``, ``--spheres <sphereList>``
36+
A comma-separated list of spheres of influence for the god. This is a
37+
required argument. To see the available spheres, run this command::
38+
39+
lua @df.sphere_type
40+
41+
``-g``, ``--gender (male|female|neuter)``
42+
The gender of the god. If not specified, a random gender will be chosen.
43+
``-d``, ``--depicted-as <str or race ID>``
44+
When the deity is referenced in-game, it will be described as "often
45+
depicted as a <str>". The string must match the token ID or descriptive
46+
name of a race that exists in the world. You can also specify a numeric
47+
race ID. If not specified, it defaults to "dwarf".
48+
``-q``, ``--quiet``
49+
If specified, suppresses all non-error output.

modtools/moddable-gods.lua

Lines changed: 118 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,136 @@
1-
local utils = require('utils')
2-
3-
local validArgs = utils.invert{
4-
'help',
5-
'name',
6-
'spheres',
7-
'gender',
8-
'depictedAs',
9-
'verbose',
10-
-- 'entities',
11-
}
12-
local args = utils.processArgs({...}, validArgs)
1+
local argparse = require('argparse')
2+
3+
local function get_spheres(arg)
4+
local spheres = {}
5+
for _, sphere in ipairs(argparse.stringList(arg, 'spheres')) do
6+
local sphereType = df.sphere_type[sphere]
7+
if not sphereType then
8+
qerror('invalid sphere: ' .. sphere)
9+
end
10+
table.insert(spheres, sphereType)
11+
end
12+
return spheres
13+
end
1314

14-
if args.help then
15-
print(dfhack.script_help())
16-
return
15+
local function get_gender(arg)
16+
if arg == 'male' then
17+
return df.pronoun_type.he
18+
elseif arg == 'female' then
19+
return df.pronoun_type.she
20+
elseif arg == 'neuter' then
21+
return df.pronoun_type.it
22+
else
23+
qerror('invalid gender: ' .. arg)
24+
end
1725
end
1826

19-
if not args.name or not args.depictedAs or not args.spheres or not args.gender then
20-
error('All arguments must be specified.')
27+
local function get_race(arg)
28+
local int_arg = tonumber(arg)
29+
if int_arg then
30+
local raw = df.creature_raw.find(int_arg)
31+
if not raw then
32+
qerror('race id ' .. int_arg .. ' does not exist')
33+
end
34+
return int_arg
35+
end
36+
for k, raw in ipairs(df.global.world.raws.creatures.all) do
37+
if raw.creature_id == arg or raw.name[0] == arg then
38+
return k
39+
end
40+
end
41+
qerror('race ' .. arg .. ' does not exist')
42+
end
43+
44+
local function do_god(opts)
45+
local godFig = df.historical_figure:new()
46+
godFig.race = opts.race
47+
godFig.caste = 0
48+
godFig.sex = opts.gender
49+
50+
godFig.appeared_year = -1
51+
godFig.born_year = -1
52+
godFig.born_seconds = -1
53+
godFig.curse_year = -1
54+
godFig.curse_seconds = -1
55+
godFig.old_year = -1
56+
godFig.old_seconds = -1
57+
godFig.died_year = -1
58+
godFig.died_seconds = -1
59+
60+
godFig.name.has_name = true
61+
godFig.name.first_name = opts.name
62+
63+
godFig.breed_id = -1
64+
godFig.flags.deity = true
65+
godFig.flags.brag_on_kill = true
66+
godFig.flags.kill_quest = true
67+
godFig.flags.chatworthy = true
68+
godFig.flags.flashes = true
69+
godFig.flags.never_cull = true
70+
71+
godFig.info = df.historical_figure_info:new()
72+
godFig.info.metaphysical = {new=true}
73+
godFig.info.known_info = {new=true}
74+
for _,sphere in ipairs(opts.spheres) do
75+
godFig.info.metaphysical.spheres:insert('#', sphere)
76+
end
77+
78+
godFig.pool_id = -1 -- will get a pool_id when game is saved and reloaded
79+
godFig.id = df.global.hist_figure_next_id
80+
df.global.hist_figure_next_id = 1 + df.global.hist_figure_next_id
81+
df.global.world.history.figures:insert('#', godFig)
82+
83+
return godFig
2184
end
2285

23-
local templateGod
24-
for _,fig in ipairs(df.global.world.history.figures) do
25-
if fig.flags.deity then
26-
templateGod = fig
27-
break
28-
end
86+
if not dfhack.isWorldLoaded() then
87+
qerror('This script requires a loaded world.')
2988
end
30-
if not templateGod then
31-
error 'Could not find template god.'
89+
90+
local opts = {
91+
name=nil,
92+
spheres=nil,
93+
gender=nil,
94+
race=nil,
95+
quiet=false,
96+
help=false,
97+
}
98+
99+
local _ = argparse.processArgsGetopt({ ... }, {
100+
{'n', 'name', hasArg=true, handler=function(arg) opts.name = arg end},
101+
{'s', 'spheres', hasArg=true, handler=function(arg) opts.spheres = get_spheres(arg) end},
102+
{'g', 'gender', hasArg=true, handler=function(arg) opts.gender = get_gender(arg) end},
103+
{'d', 'depicted-as', hasArg=true, handler=function(arg) opts.race = get_race(arg) end},
104+
{'h', 'help', handler=function() opts.help = true end},
105+
{'q', 'quiet', handler=function() opts.quiet = true end},
106+
})
107+
108+
if opts.help then
109+
print(dfhack.script_help())
110+
return
32111
end
33112

34-
local gender
35-
if args.gender == 'male' then
36-
gender = 1
37-
elseif args.gender == 'female' then
38-
gender = 0
39-
elseif args.gender == "neuter" then
40-
gender = -1
41-
else
42-
error 'invalid gender'
113+
if not opts.name or not opts.spheres or #opts.name == 0 or #opts.spheres == 0 then
114+
qerror('name and spheres must be specified.')
43115
end
44116

45-
local race
46-
for k,v in ipairs(df.global.world.raws.creatures.all) do
47-
if v.creature_id == args.depictedAs or v.name[0] == args.depictedAs then
48-
race = k
49-
break
117+
for _, fig in ipairs(df.global.world.history.figures) do
118+
if fig.name.first_name == opts.name then
119+
print('god "' .. opts.name .. '" already exists.')
120+
return
50121
end
51122
end
52-
if not race then
53-
error('invalid race: ' .. args.depictedAs)
54-
end
55123

56-
for _,fig in ipairs(df.global.world.history.figures) do
57-
if fig.name.first_name == args.name then
58-
print('god ' .. args.name .. ' already exists. Skipping')
59-
return
60-
end
124+
if not opts.gender then
125+
opts.gender = math.random(-1, 1)
61126
end
62127

63-
local godFig = df.historical_figure:new()
64-
godFig.appeared_year = -1
65-
godFig.born_year = -1
66-
godFig.born_seconds = -1
67-
godFig.curse_year = -1
68-
godFig.curse_seconds = -1
69-
godFig.old_year = -1
70-
godFig.old_seconds = -1
71-
godFig.died_year = -1
72-
godFig.died_seconds = -1
73-
godFig.name.has_name = true
74-
godFig.breed_id = -1
75-
godFig.flags:assign(templateGod.flags)
76-
godFig.id = df.global.hist_figure_next_id
77-
df.global.hist_figure_next_id = 1+df.global.hist_figure_next_id
78-
godFig.info = df.historical_figure_info:new()
79-
godFig.info.spheres = {new=true}
80-
godFig.info.known_info = df.knowledge_profilest:new()
81-
godFig.race = race
82-
godFig.caste = 0
83-
godFig.sex = gender
84-
godFig.name.first_name = args.name
85-
for _,sphere in ipairs(args.spheres) do
86-
godFig.info.metaphysical.spheres:insert('#',df.sphere_type[sphere])
128+
if not opts.race then
129+
opts.race = get_race('dwarf')
87130
end
88-
df.global.world.history.figures:insert('#',godFig)
89131

90-
if args.verbose then
91-
print(godFig.name.first_name .. " created as historical figure " .. tostring(godFig.id))
132+
local godFig = do_god(opts)
133+
134+
if not opts.quiet then
135+
print(godFig.name.first_name .. " created as historical figure " .. tostring(godFig.id))
92136
end

0 commit comments

Comments
 (0)