forked from DFHack/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
transform-unit.lua
164 lines (140 loc) · 3.47 KB
/
transform-unit.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
-- Transforms a unit into another unit type
--author expwnent
--based on shapechange by Putnam
local usage = [====[
modtools/transform-unit
=======================
Transforms a unit into another unit type, possibly permanently.
Warning: this will crash arena mode if you view the unit on the
same tick that it transforms. If you wait until later, it will be fine.
Arguments::
-clear
clear records of normal races
-unit id
set the target unit
-duration ticks
how long it should last, or "forever"
-setPrevRace
make a record of the previous race so that you can
change it back with -untransform
-keepInventory
move items back into inventory after transformation
-race raceName
-caste casteName
-suppressAnnouncement
don't show the Unit has transformed into a Blah! event
-untransform
turn the unit back into what it was before
]====]
local utils = require 'utils'
normalRace = normalRace or {} --as:{race:number,caste:number}[]
local function transform(unit,race,caste)
unit.enemy.normal_race = race
unit.enemy.normal_caste = caste
unit.enemy.were_race = race
unit.enemy.were_caste = caste
end
local validArgs = utils.invert({
'clear',
'help',
'unit',
'duration',
'setPrevRace',
'keepInventory',
'race',
'caste',
'suppressAnnouncement',
'untransform',
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print(usage)
return
end
if args.clear then
normalRace = {}
end
if not args.unit then
error 'Specify a unit.'
end
if not args.duration then
args.duration = 'forever'
end
local raceIndex
local race
local caste
if args.untransform then
local unit = df.unit.find(tonumber(args.unit))
raceIndex = normalRace[args.unit].race
race = df.creature_raw.find(raceIndex)
caste = normalRace[args.unit].caste
normalRace[args.unit] = nil
else
if not args.race or not args.caste then
error 'Specficy a target form.'
end
--find race
for i,v in ipairs(df.global.world.raws.creatures.all) do
if v.creature_id == args.race then
raceIndex = i
race = v
break
end
end
if not race then
error 'Invalid race.'
end
for i,v in ipairs(race.caste) do
if v.caste_id == args.caste then
caste = i
break
end
end
if not caste then
error 'Invalid caste.'
end
end
local unit = df.unit.find(tonumber(args.unit))
local oldRace = unit.enemy.normal_race
local oldCaste = unit.enemy.normal_caste
if args.setPrevRace then
normalRace[args.unit] = {}
normalRace[args.unit].race = oldRace
normalRace[args.unit].caste = oldCaste
end
transform(unit,raceIndex,caste,args.setPrevRace)
local inventoryItems = {} --as:df.unit_inventory_item[]
local function getInventory()
local result = {}
for _,item in ipairs(unit.inventory) do
table.insert(result, item:new());
end
return result
end
local function restoreInventory()
dfhack.timeout(1, 'ticks', function()
for _,item in ipairs(inventoryItems) do
dfhack.items.moveToInventory(item.item, unit, item.mode, item.body_part_id)
item:delete()
end
inventoryItems = {}
end)
end
if args.keepInventory then
inventoryItems = getInventory()
end
if args.keepInventory then
restoreInventory()
end
if args.duration and args.duration ~= 'forever' then
--when the timeout ticks down, transform them back
dfhack.timeout(tonumber(args.duration), 'ticks', function()
if args.keepInventory then
inventoryItems = getInventory()
end
transform(unit,oldRace,oldCaste)
if args.keepInventory then
restoreInventory()
end
end)
end