forked from HilariousDeathArtist/DCSSConfigFile
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHDAtravel.txt
540 lines (482 loc) · 20.1 KB
/
HDAtravel.txt
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
-- To use this create a macro with the following function call in game
-- ===HDAtravel
-- This file can be included in your rc file with the following line:
-- include += HDAtravel.rc
# This still has plenty of bugs, submit them at:
# https://github.com/HilariousDeathArtist/DCSSConfigFile
# or find me on crawl.s-z.org
confirm_butcher = never
easy_eat_chunks = true
auto_eat_chunks = true
auto_drop_chunks = yes
easy_eat_contaminated = true
autoinscribe += bread ration:@e1
autoinscribe += meat ration:@e2
autoinscribe += chunk:@w0
autoinscribe += staff of energy:@w1
##################
# HDAtravel #
##################
-- Rests up to at least 75% hp (or missing at least 30hp) and 50% mp (or missing at least 20mp)
-- Eats chunks automatically, handled by auto_eat_chunks interface option
-- Travels to the nearest corpse if we have no chunks and are at Very Hungry or Hungry or using Gourmand and at Full
-- Automatically chops valid corpses if we are standing on them and we have no chunks
-- Will stop autotravel at Near Starving
-- Channels MP if you have staff of energy or worship Sif when you have extra chunks
-- Casts regen out of combat if you have spare chunks and are missing hp
-- TODO: better detection of non-edible corpses before standing on them
-- TODO: Fix up for Vampire, Ghoul, and possibly Spriggan/Mummy
-- NOTE: If you don't have rP you will still chop poisonous corpses, but not pick up their chunks
: function HDAtravel()
: local mp, max_mp = you.mp()
: local hp, max_hp = you.hp()
: local first_monster = next(getMonsterList())
: local already_checked = (no_results() or dont_know_how_to_get_there())
: local you_are_barbed = (have_barbs() and not removed_barbs())
: local is_safe = (first_monster == nil)
: local missing_mp = (mp < max_mp)
: local missing_hp = (hp < max_hp)
: local need_to_recover = should_rest(hp, mp, max_hp, max_mp)
: local have_no_chunks = have_no_chunks()
: local you_are_sif = string.find(you.god(), "Sif")
: local you_are_yred = string.find(you.god(), "Yred")
: local you_are_zin = string.find(you.god(), "Zin")
: local you_are_good = string.find(you.god(), "Shining") or string.find(you.god(), "Elyvilon") or you_are_zin
: local sacrifice_god = you_worship_sacrifice_god()
: local you_are_mummy = string.find(you.race(), "Mummy")
: local you_are_vampire = string.find(you.race(), "Vampire")
: local you_are_bloodless = you.hunger_name() == "bloodless"
: local you_are_ghoul = string.find(you.race(), "Ghoul")
: local you_are_bloodless = you.hunger_name() == "bloodless"
: local you_do_not_eat = string.find(you.race(), "Spriggan") or you_are_mummy
: local lichform = string.find(you.transform(), "lich")
: local bladehands = string.find(you.transform(), "blade")
: local dragonform = string.find(you.transform(), "dragon")
: local melded_weapon = (bladehands or dragonform)
: local you_are_regen = you.regenerating()
: local you_know_sublimation = known_spells["Sublimation of Blood"] and (spells.fail("Sublimation of Blood") < 20) and (mp>3)
: local you_know_animate_skeleton = known_spells["Animate Skeleton"] and (spells.fail("Animate Skeleton") < 20) and (mp>1)
: local you_know_animate_dead = known_spells["Animate Dead"] and (spells.fail("Animate Dead") < 20) and (mp>4)
: local chunks_are_equipped = is_weapon("chunk")
: local distort_weapon = is_weapon("distort")
: local vamp_weapon = is_weapon("vamp") and not chunks_are_equipped
: local have_a_weapon = weapon_in_inventory()
: local gourmand_and_hungry = you_are_gourmand() and not (you_are_very_full() or you_are_engorged() or you_are_ghoul)
: local ghoul_missing_hp = you_are_ghoul and ((hp < (max_hp - 5)) or you.rot() > 0)
: local want_to_eat = (you_are_hungry() or gourmand_and_hungry or ghoul_missing_hp) and not you_do_not_eat
: local have_spare_chunks = not have_no_chunks and not you_are_hungry()
: local you_have_staff_of_energy = is_in_inventory("staff of energy")
: local have_potion_of_blood = is_in_inventory("potion of blood") or is_in_inventory("potions of blood")
: local staff_of_energy_is_equipped = is_weapon("staff of energy")
: local staff_of_power_is_equipped = is_weapon("staff of power")
: local staff_of_energy_letter = find_item_letter("staff of energy")
: local chunks_letter = find_item_letter("chunk")
: local you_are_hungerless = you_are_mummy or lichform
: local no_food_issues = (you_are_hungerless or have_spare_chunks)
: local should_channel_mp = ((max_mp - mp) > 5) and no_food_issues
: local can_cast_regen = known_spells["Regeneration"] and (mp>3) and (spells.fail("Regeneration") < 20)
: local you_have_regen_ring = is_in_inventory("regeneration")
: local regen_ring_letter = find_item_letter("regeneration")
: local regen_ring_is_equipped = is_ring("regeneration")
: local should_regen_hp = (not (you_are_good or you_are_regen or lichform)) and ((hp/max_hp) < 0.80) and (you_have_regen_ring or can_cast_regen) and not you_are_bloodless
: local should_sublimate = (not (you_are_good or lichform)) and ((mp/max_mp) < 0.60) and you_know_sublimation and mp>2 and ((hp/max_hp) > 0.95)
: local should_animate_skeleton = (not you_are_good) and you_know_animate_skeleton and mp>1 and (not can_not_animate())
: local should_animate_dead = (not you_are_good) and you_know_animate_dead and mp>4 and (not can_not_animate())
: local you_want_spare_chunks = (not (have_spare_chunks or you_do_not_eat)) and (can_cast_regen or you_have_staff_of_energy or you_are_sif)
: local you_want_chunks = (not you_are_hungerless and (number_of_chunks() == 0) and (want_to_eat or you_want_spare_chunks)) or you_are_vampire or (you_are_ghoul and number_of_chunks() < 4)
: --crawl.mpr(string.format("you.piety_rank() is: %s", you.piety_rank()))
: --crawl.mpr(string.format("you_want_chunks is: %s", you_want_chunks and "True" or "False"))
: --crawl.mpr(string.format("want_to_eat is: %s", want_to_eat and "True" or "False"))
: --crawl.mpr(string.format("number_of_chunks is: %s", number_of_chunks()))
: --crawl.mpr(string.format("ghoul_missing_hp is: %s", ghoul_missing_hp and "True" or "False"))
: --crawl.mpr(string.format("you.hunger_name() is: %s", you.hunger_name()))
: --crawl.mpr(string.format("have_spare_chunks is: %s", have_spare_chunks and "True" or "False"))
: --crawl.mpr(string.format("can_cast_regen is: %s", can_cast_regen and "True" or "False"))
: --crawl.mpr(string.format("you_are_not_ghoul is: %s", you_are_not_ghoul and "True" or "False"))
: --crawl.mpr(string.format("you_want_spare_chunks is: %s", you_want_spare_chunks and "True" or "False"))
: --crawl.mpr(string.format("you_are_hungerless is: %s", you_are_hungerless and "True" or "False"))
: --crawl.mpr(string.format("have_no_chunks is: %s", have_no_chunks and "True" or "False"))
: if (is_safe) then
: if you_are_barbed then
: rest()
: elseif should_sublimate and not (you_are_vampire or lichform) then
: crawl.mpr("<lightcyan>Autocasting Sublimation of Blood.</lightcyan>")
: sendkeys('zm')
: elseif should_channel_mp and you_are_sif and (you.piety_rank() > 0) then
: crawl.mpr("<lightcyan>Autochanneling using Sif.</lightcyan>")
: sendkeys('aa')
: elseif should_regen_hp and can_cast_regen then
: crawl.mpr("<green>Autocasting Regen.</green>")
: --This assumes casting regen is bound to zr
: sendkeys('zr')
: elseif (not melded_weapon) and (should_channel_mp and you_have_staff_of_energy and no_food_issues) and (not (distort_weapon or vamp_weapon)) and you_are_not_felid() then
: if not staff_of_energy_is_equipped then
: crawl.mpr("<cyan>Switching to staff of energy.</cyan>")
: sendkeys('w1')
: end
: crawl.mpr("<lightcyan>Autochanneling using staff of energy.</lightcyan>")
: sendkeys('v')
: elseif (weapon_in_slot_a() or uses_unarmed()) and (no_weapon() and have_a_weapon) or (staff_of_energy_is_equipped and (not (staff_of_energy_letter == 'a')) or (chunks_are_equipped and (not (chunks_letter == 'a')))) then
: if uses_unarmed() then
: crawl.mpr("<cyan>Switching to unarmed.</cyan>")
: sendkeys('w-')
: else
: crawl.mpr("<cyan>Switching to main weapon.</cyan>")
: sendkeys('wa')
: end
: elseif want_to_eat and number_of_chunks() > 0 then
: crawl.mpr("<cyan>Autoeating chunks.</cyan>")
: sendkeys('e')
: elseif you_want_chunks and on_corpses() and not on_chunks() and (not can_not_butcher()) then
: if should_animate_skeleton then
: crawl.mpr("<cyan>Autocasting Animate Skeleton for chunks.</cyan>")
: sendkeys('zA')
: else
: crawl.mpr("<cyan>Autochopping corpse.</cyan>")
: sendkeys('c')
: end
: elseif you_want_chunks and (not (you_are_zin or need_to_recover or on_chunks() or on_corpses() or already_checked)) then
: crawl.mpr("<yellow>You may need something to eat soon, looking for food.</yellow>")
: find_corpses()
: elseif you_are_starving_or_near() and (number_of_chunks == 0) and (not (on_chunks() or on_corpses())) then
: local have_bread = is_in_inventory("bread ration")
: local have_meat = is_in_inventory("meat ration")
: if have_bread or have_meat then
: local result = crawl.yesnoquit("<cyan>Eat a ration?</cyan>", true, 'e')
: if result == 1 and have_bread then
: sendkeys('e1')
: elseif result == 1 then
: sendkeys('e2')
: elseif result == 0 then
: autoexplore()
: end
: if not (is_in_inventory("bread ration") or is_in_inventory("meat ration")) then
: crawl.mpr("<lightred>That was your last ration! You should go get more.</lightred>")
: end
: else
: crawl.mpr("<red>No rations left! You should look for food.</red>")
: end
: elseif need_to_recover and not you_are_starving() then
: if you_are_bloodless and have_potion_of_blood then
: crawl.mpr("<cyan>Autoquaffing potion of blood.</cyan>")
: sendkeys('q1')
: else
: rest()
: end
: elseif you_are_yred and (you.piety_rank() >= 3) and (item_in_view("corpse") or item_in_view("skeleton") or on_corpses()) and not recently_mass_animated() then
: crawl.mpr("<cyan>Autocasting Mass Animate Remains.</cyan>")
: sendkeys('aa')
: elseif (not sacrifice_god) and (item_in_view("corpse") or item_in_view("skeleton") or on_corpses()) and should_animate_dead and not already_animated() then
: crawl.mpr("<cyan>Autocasting Animate Dead.</cyan>")
: sendkeys('zA')
: elseif (not sacrifice_god) and on_corpses() and should_animate_skeleton then
: crawl.mpr("<cyan>Autocasting Animate Skeleton.</cyan>")
: sendkeys('zA')
: elseif you_are_yred and (you.piety_rank() >= 1) and on_corpses() then
: crawl.mpr("<cyan>Autocasting Animate Remains.</cyan>")
: sendkeys('aa')
: else
: --This does the general travelling
: autoexplore()
: end
: else
: --This will provide the "foo is nearby" message
: autoexplore()
: end
: end
<
function sendkeys(command)
crawl.flush_input()
crawl.sendkeys(command)
coroutine.yield(true)
crawl.flush_input()
end
function should_rest(hp, mp, max_hp, max_mp)
local you_are_mummy = string.find(you.race(), "Mummy")
local you_are_deep_dwarf = string.find(you.race(), "Deep Dwarf")
return (mp < (max_mp*0.50) or ((max_mp-mp) > 20)
or ((hp < (max_hp*0.80)) or ((max_hp-hp) > 30)
and not you_are_deep_dwarf)
or you.slowed()
or you.poisoned()
or you.confused()
or you.exhausted()
or (((hp < max_hp) or (mp < max_mp)) and you_are_mummy))
end
-- Hungry, Very Hungry, Near Starving, Starving
function you_are_hungry()
return not you_are_not_hungry() and ((string.find(you.hunger_name(), "hungry")) or you_are_starving_or_near())
end
-- Normal Satiation
function you_are_not_hungry()
return (string.find(you.hunger_name(), "not hungry"))
end
-- Engorged
function you_are_engorged()
return (string.find(you.hunger_name(), "completely stuffed"))
end
-- Very full
function you_are_very_full()
return (string.find(you.hunger_name(), "very full"))
end
-- Near Starving
function you_are_near_starving()
return (string.find(you.hunger_name(), "near starving"))
end
-- Near Starving, Starving
function you_are_starving_or_near()
return (string.find(you.hunger_name(), "starving"))
end
-- Starving
function you_are_starving()
return you_are_starving_or_near() and not you_are_near_starving()
end
function autoexplore()
sendkeys('o')
end
function have_barbs()
return string.find(crawl.messages(10), escape("The barbed spikes become lodged in your body"))
or string.find(crawl.messages(10), escape("The barbed spikes dig painfully into your body as you move"))
end
function already_animated()
return string.find(crawl.messages(20), escape("Autocasting Animate Dead"))
end
function removed_barbs()
return string.find(crawl.messages(10), escape("You carefully extract the manticore spikes from your body"))
or string.find(crawl.messages(10), escape("The manticore spikes snap loose"))
end
function no_results()
return string.find(crawl.messages(10), escape("Can't find anything matching that"))
or string.find(crawl.messages(10), escape("You may need something to eat soon"))
end
function dont_know_how_to_get_there()
return string.find(crawl.messages(10), escape("know how to get there"))
or string.find(crawl.messages(10), escape("Have to go through"))
end
function can_not_animate()
return string.find(crawl.messages(10), escape("There is nothing here that can be animated"))
end
function can_not_bottle()
return string.find(crawl.messages(10), escape("There isn't anything to bottle here"))
end
function recently_mass_animated()
return string.find(crawl.messages(10), escape("Autocasting Mass Animate Remains"))
end
function can_not_butcher()
return string.find(crawl.messages(10), escape("anything suitable to butcher here"))
end
function can_not_eat_that()
return string.find(crawl.messages(10), escape("You can't eat that"))
--These strings don't seem to show up in messages
--or string.find(crawl.messages(10), escape("Not only inedible but also greatly harmful"))
--or string.find(crawl.messages(10), escape("It is caustic"))
end
function rest()
sendkeys('5')
end
function you_are_gourmand()
return you.gourmand() or (not you_are_not_ghoul()) or (not you_are_not_felid()) or (not you_are_not_troll()) or (string.find(you.race(), "Kobold"))
end
function have_no_chunks()
for it in inventory() do
if string.find(it.name(), "chunk") then
return false
end
end
return true
end
function have_rotten_chunks()
for it in inventory() do
if string.find(it.name(), "chunk") and string.find(it.name(), "rott") then
return false
end
end
return true
end
function number_of_chunks()
for it in inventory() do
--if string.find(it.name(), "chunk") then
--crawl.mpr(it.name() .." is edible: " .. (food.can_eat(it) and "True" or "False") .. " and dangerous: " .. (food.dangerous(it) and "True" or "False"))
--end
if string.find(it.name(), "chunk") and (not string.find(it.name(), "book")) and food.can_eat(it) and not food.dangerous(it) then
return it.quantity
end
end
return 0
end
function is_in_inventory(str)
for it in inventory() do
if string.find(it.name(), str) then
return true
end
end
return false
end
function weapon_in_inventory()
for it in inventory() do
if string.find(it.class(true), "weapon") then
return true
end
end
return false
end
function weapon_in_slot_a()
local it = items.inslot(0)
if it then
return string.find(it.class(true), "weapon")
else
return false
end
end
function find_item_letter(str)
for i = 0,51 do
it = items.inslot(i)
if it then
if string.find(it.name(), str) then
return items.index_to_letter(i)
end
end
end
return false
end
function you_worship_sacrifice_god()
return string.find(you.god(), "Trog")
--or string.find(you.god(), "Oka")
--or string.find(you.god(), "Makhleb")
or string.find(you.god(), "Beogh")
or string.find(you.god(), "Lugonu")
--or string.find(you.god(), "Nemelex")
end
function on_corpses()
local fl = you.floor_items()
for it in iter.invent_iterator:new(fl) do
if string.find(it.name(), "corpse")
and not string.find(it.name(), "rotting")
and not string.find(it.name(), "plague") then
return true
end
end
return false
end
function on_chunks()
for it in floor_items() do
if string.find(it.name(), "chunk") then
return true
else
return false
end
end
end
function you_are_carnivore()
return you.saprovorous()
end
function you_are_not_ghoul()
return not (string.find(you.race(), "Ghoul"))
end
function you_are_not_troll()
return not (string.find(you.race(), "Troll"))
end
function you_are_not_felid()
return not (string.find(you.race(), "Felid"))
end
function you_are_not_octopode()
return not (string.find(you.race(), "Octopode"))
end
function find_corpses()
local race = you.race()
local god = you.god()
local exclude_this = ""
if string.find(god, "Shining") then
exlude_this = race
end
sendkeys(string.char(6) .. "@corpse&&!!rott&&!!skel&&!!sky&&!!necrop&&!!ugly&&!!vampire&&!!corpse rot&&!!&&!!botono" .. exclude_this .. "\ra\r")
end
function inventory()
return iter.invent_iterator:new(items.inventory())
end
function floor_items()
return iter.invent_iterator:new(you.floor_items())
end
function no_weapon()
return (items.equipped_at("Weapon") == nil) and not uses_unarmed()
end
function uses_unarmed()
return not you_are_not_ghoul()
or not you_are_not_troll()
or not you_are_not_felid()
or (you.skill("Unarmed Combat") >= 3)
end
function is_weapon(str)
local weapon = items.equipped_at("Weapon")
if weapon then
return string.find(weapon.name(), str)
else
return false
end
end
function is_ring(str)
local ring1 = items.equipped_at("Left Ring")
local ring2 = items.equipped_at("Right Ring")
if ring1 and ring2 then
return string.find(ring1.name(), str) or string.find(ring2.name(), str)
elseif ring1 then
return string.find(ring1.name(), str)
elseif ring2 then
return string.find(ring2.name(), str)
else
return false
end
end
function item_in_view(str)
local x,y
for x = -8,8 do
for y = -8,8 do
if not (x == 0 and y == 0) then
local pile = items.get_items_at(x,y)
if pile ~= nil then
for it in iter.invent_iterator:new(pile) do
if string.find(it.name(), str) and you.see_cell_no_trans(x,y) then
return true
end
end
end
end
end
end
return false
end
-- Returns a table where the key is the monster description and value is the total number of that mob in your vision
function getMonsterList()
local monsters = {}
for x = -7,7 do
for y = -7,7 do
m = monster.get_monster_at(x, y)
local attitude_hostile = 0
if m and (m:attitude() == attitude_hostile) and not (m:is_firewood()) then
desc = m:desc()
if (monsters[desc] == nil) then
monsters[desc] = 1
else
monsters[desc] = monsters[desc] + 1
end
end
end
end
return monsters
end
--Escapes the special characters in a string for pattern matching
function escape(str)
--Escapes parens and dash "()-"
local escaped = str:gsub('[%(%)%-]','%\%1')
--Removes any coloration parts of the string
return (escaped:gsub('<[^<]*>',''))
end
local function init_spells()
local spell_list = {}
for _, spell_name in ipairs(you.spells()) do
spell_list[spell_name] = true
end
return spell_list
end
known_spells = init_spells()
>