PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/game/engine/wish.lua

https://bitbucket.org/elcugo/t-engine
Lua | 836 lines | 615 code | 152 blank | 69 comment | 127 complexity | f68f6744ebb465734d84e071378f85bc MD5 | raw file
Possible License(s): GPL-2.0
  1. --------------------------------------------------
  2. --------------------- wish Code -------------------
  3. ---------------------------------------------------
  4. -- NOTE: You can wish for things besides objects, but wishing is
  5. -- mainly used for objects, so it goes in this file. Wishing for
  6. -- monsters or corpses uses functions in engine/monsters.lua
  7. constant("wish", {})
  8. wish.GRANTED = 1
  9. wish.UNGRANTED = 2
  10. wish.DENIED = 3
  11. wish.ONE_ITEM_MSG = "You can only wish for *ONE* item."
  12. wish.NO_ARTS_MSG = "You can't wish for an artifact."
  13. -- Some item kinds might want to do their own parsing of the wish string
  14. new_flag("PARSE_WISH_STR")
  15. -- Some item kinds might want to do their setup of the wish for item.
  16. new_flag("GRANT_WISH")
  17. -- Interpret wish string as a request for a monster, and see if that
  18. -- works
  19. function wish.for_monster(wish_str)
  20. -- NOT IMPLEMENTED
  21. return wish.UNGRANTED
  22. end
  23. -- Interpret wish string as a request for a corpse, and see if
  24. -- that works.
  25. -- NOTE: this is separate from wish.for_item(), since it has
  26. -- to parse monster egos instead of item egos
  27. function wish.for_corpse(wish_str)
  28. local suffixes = {
  29. corpse = SV_CORPSE_CORPSE,
  30. corpses = SV_CORPSE_CORPSE,
  31. skeleton = SV_CORPSE_SKELETON,
  32. skeletons = SV_CORPSE_SKELETON,
  33. ["raw meat"] = SV_CORPSE_MEAT,
  34. ["raw meats"] = SV_CORPSE_MEAT
  35. }
  36. local is_plural = {
  37. corpses = SV_CORPSE_CORPSE,
  38. skeletons = SV_CORPSE_SKELETON,
  39. ["raw meats"] = SV_CORPSE_MEAT
  40. }
  41. local name, suffix
  42. local sval
  43. for k, v in suffixes do
  44. if ends_with(wish_str, " " .. k) then
  45. name = strsub(wish_str, 1, strlen(wish_str) - strlen(k) - 1)
  46. suffix = k
  47. sval = v
  48. break
  49. end
  50. end
  51. if not name then
  52. return wish.UNGRANTED
  53. end
  54. if is_plural[suffix] then
  55. message(wish.ONE_ITEM_MSG)
  56. return wish.DENIED
  57. end
  58. local mon_info = parse_named_monster(name, true)
  59. -- Maybe the user gave the name as "foo's corpse" instead of
  60. -- "foo corpse"?
  61. if not mon_info then
  62. if ends_with(name, "'s") then
  63. name = strsub(name, 1, strlen(name) - 2)
  64. elseif ends_with(name, "'") then
  65. name = strsub(name, 1, strlen(name) - 1)
  66. end
  67. mon_info = parse_named_monster(name)
  68. end
  69. if not mon_info then
  70. return wish.DENIED
  71. end
  72. local race = r_info(mon_info.race_idx)
  73. if race.flags[FLAG_UNIQUE] and not wizard then
  74. message("You may not wish for the corpses of unique monsters.")
  75. return wish.DENIED
  76. end
  77. local m_ptr = monster_type_new()
  78. monster_prep(m_ptr, mon_info.race_idx, mon_info.ego_idx or 0)
  79. local desc = monster_desc(m_ptr, 512 | 256 | 128)
  80. local plural = pluralize(desc)
  81. if sval == SV_CORPSE_CORPSE or sval == SV_CORPSE_MEAT then
  82. if not m_ptr.flags[FLAG_DROP_CORPSE] then
  83. message(strcap(plural) .. " don't leave corpses.")
  84. delete_monster_type(m_ptr, true)
  85. return wish.DENIED
  86. end
  87. elseif sval == SV_CORPSE_SKELETON then
  88. if not m_ptr.flags[FLAG_DROP_SKELETON] then
  89. message(strcap(plural) .. " don't leave skeletons.")
  90. delete_monster_type(m_ptr, true)
  91. return wish.DENIED
  92. end
  93. else
  94. message("ERROR: Unknown corpse sval.")
  95. delete_monster_type(m_ptr, true)
  96. return wish.DENIED
  97. end
  98. local o_ptr = new_object()
  99. object_prep(o_ptr, lookup_kind(TV_CORPSE, sval))
  100. o_ptr.flags[FLAG_MONSTER_OBJ] = m_ptr
  101. local weight = race.weight
  102. if mon_info.ego_idx ~= 0 then
  103. local ego = re_info(mon_info.ego_idx)
  104. weight = weight + ego.weight
  105. end
  106. if sval == SV_CORPSE_SKELETON then
  107. weight = (weight / 4) + (rng(weight) / 40) + 1
  108. elseif sval == SV_CORPSE_CORPSE then
  109. weight = weight + (rng(weight) / 10) + 1
  110. elseif sval == SV_CORPSE_MEAT then
  111. weight = o_ptr.weight
  112. end
  113. o_ptr.weight = weight
  114. o_ptr.found = OBJ_FOUND_WISH
  115. o_ptr.found_aux1 = current_dungeon_idx
  116. o_ptr.found_aux2 = level_or_feat(current_dungeon_idx, dun_level)
  117. hook.process(hook.CORPSE_CREATE_POST, o_ptr, m_ptr)
  118. if (drop_near(o_ptr, -1, player.py, player.px) == 0) then
  119. return wish.UNGRANTED
  120. end
  121. return wish.GRANTED
  122. end -- wish.for_corpse()
  123. -- Check to see if user tried to wish for more than one of an item
  124. function wish.test_multiple_item(wish_str, raw_name)
  125. local plural
  126. if strfind(raw_name, "#~") then
  127. -- How do you detect plurals if the "~" comes right
  128. -- after the "#"???
  129. return nil
  130. end
  131. raw_name = gsub(raw_name, "#", "")
  132. raw_name = gsub(raw_name, "&", "")
  133. raw_name = clean_whitespace(raw_name)
  134. -- Default to pluralizing at the end of the name
  135. if not strfind(raw_name, "~") then
  136. raw_name = raw_name .. "~"
  137. end
  138. plural = gsub(raw_name, "~", "s")
  139. if strfind(wish_str, plural) then
  140. return true
  141. end
  142. plural = gsub(raw_name, "~", "es")
  143. if strfind(wish_str, plural) then
  144. return true
  145. end
  146. -- "Wolf" / "Wolves"
  147. plural = gsub(raw_name, "f~", "ves")
  148. if strfind(wish_str, plural) then
  149. return true
  150. end
  151. -- "Staff" / "Staves"
  152. plural = gsub(raw_name, "ff~", "ves")
  153. if strfind(wish_str, plural) then
  154. return true
  155. end
  156. -- "Knife" / "Knives"
  157. plural = gsub(raw_name, "fe~", "ves")
  158. if strfind(wish_str, plural) then
  159. return true
  160. end
  161. -- "Octopus" / "Octopi"
  162. plural = gsub(raw_name, "us~", "i")
  163. if strfind(wish_str, plural) then
  164. return true
  165. end
  166. return nil
  167. end
  168. -- Interpret wish string as a request for an artifact, and see if
  169. -- that works
  170. function wish.for_artifact(wish_str)
  171. local art_str = nil
  172. local art_idx = nil
  173. if starts_with(wish_str, "the ") == true then
  174. wish_str = strsub(wish_str, 5, strlen(wish_str))
  175. end
  176. local quoted_str = "'" .. wish_str .. "'"
  177. -- Currently, wishing for artifacts is only allowed in wizard
  178. -- mode
  179. for i = 2, max_a_idx do
  180. local item = a_info[i]
  181. local name = item.name
  182. name = gsub(name, "& ", "")
  183. name = gsub(name, "~", "")
  184. -- If user wished for "FOO", and the name ends with
  185. -- "'FOO'", that's probably what the user wants.
  186. if (wish_str == name) or ends_with(name, quoted_str) then
  187. if wizard then
  188. art_str = name
  189. art_idx = i - 1
  190. break
  191. else
  192. message(wish.NO_ARTS_MSG)
  193. return wish.DENIED
  194. end
  195. end
  196. -- Was the user crazy enough to ask for a *plural* of
  197. -- an artifact?
  198. if wish.test_multiple_item(wish_str, item.name) == true then
  199. message(wish.ONE_ITEM_MSG)
  200. return wish.DENIED
  201. end
  202. end
  203. if not art_idx then
  204. return wish.UNGRANTED
  205. end
  206. local obj = create_artifact(art_idx)
  207. set_known(obj)
  208. set_aware(obj)
  209. obj.found = OBJ_FOUND_WISH
  210. obj.found_aux1 = current_dungeon_idx
  211. obj.found_aux2 = level_or_feat(current_dungeon_idx, dun_level)
  212. drop_near(obj, -1, player.py, player.px)
  213. return wish.GRANTED
  214. end
  215. function wish.okay_ego_pair(ego1_idx, ego2_idx, give_message)
  216. local ego1 = e_info(ego1_idx)
  217. local ego2 = e_info(ego2_idx)
  218. local flags = flag_new()
  219. for i = 1, MAX_EGO_FLAG_GROUPS do
  220. if ego1.rar[i] >= 100 then
  221. flag_add(flags, ego1.flags[i])
  222. end
  223. end
  224. flag_add(flags, ego1.need_flags)
  225. if flag_intersects(flags, ego2.forbid_flags) then
  226. if give_message then
  227. message("Egos '" .. ego1.name .. "' and '" .. ego2.name ..
  228. "' can not be combined.")
  229. end
  230. return false
  231. end
  232. flag_free(flags, 0)
  233. ---
  234. flags = flag_new()
  235. for i = 1, MAX_EGO_FLAG_GROUPS do
  236. if ego2.rar[i] >= 100 then
  237. flag_add(flags, ego2.flags[i])
  238. end
  239. end
  240. flag_add(flags, ego2.need_flags)
  241. if flag_intersects(flags, ego1.forbid_flags) then
  242. if give_message then
  243. message("Egos '" .. ego1.name .. "' and '" .. ego2.name ..
  244. "' can not be combined.")
  245. end
  246. return false
  247. end
  248. flag_free(flags, 0)
  249. return true
  250. end
  251. function wish.okay_ego_combo(combo, give_message)
  252. for i = 1, getn(combo) do
  253. for j = i + 1, getn(combo) do
  254. if not wish.okay_ego_pair(combo[i], combo[j], give_message) then
  255. return false
  256. end
  257. end
  258. end
  259. return true
  260. end -- wish.okay_ego_combo()
  261. function wish.get_possible_ego_combos(k_idx, str, is_prefix)
  262. if not str or str == "" then
  263. return {{}}
  264. end
  265. local ok_egos = {}
  266. local bad_pos_match = false
  267. -- Look for egos whose name matches chunks of whole words in the
  268. -- string. Don't use plain strfind(), since that could match
  269. -- for egos whose names are embedded in a larger word in the string
  270. for group, egos_by_k_idx in rand_obj.egos_by_k_idx do
  271. local list = egos_by_k_idx[k_idx + 1]
  272. for i = 1, getn(list) do
  273. local ego = e_info(list[i])
  274. if is_separate_word(strlower(ego.name), str) then
  275. if ego.before == is_prefix then
  276. tinsert(ok_egos, list[i])
  277. else
  278. bad_pos_match = ego.name
  279. end
  280. end
  281. end
  282. end
  283. -- Any matching egos?
  284. if getn(ok_egos) == 0 then
  285. if bad_pos_match then
  286. message("The ego '" .. bad_pos_match .. "' should go " ..
  287. iif(is_prefix, "after", "before") .. " the item name.")
  288. return nil
  289. end
  290. local any_egos = false
  291. for i = 2, max_e_idx do
  292. if is_separate_word(strlower(e_info[i].name), str) then
  293. any_egos = true
  294. break
  295. end
  296. end
  297. if any_egos then
  298. message("'" .. str .. "' can't be combined " ..
  299. "with this item.")
  300. else
  301. message("No egos match '" .. str .. "'.")
  302. end
  303. return nil
  304. end
  305. -- Are all the words in the ego string accounted for?
  306. local words = strsplit(str, " ")
  307. local word_table = {}
  308. for i = 1, getn(words) do
  309. word_table[words[i]] = true
  310. end
  311. for i = 1, getn(ok_egos) do
  312. words = strsplit(strlower(e_info(ok_egos[i]).name), " ")
  313. for j = 1, getn(words) do
  314. word_table[words[j]] = nil
  315. end
  316. end
  317. local unacounted_words = {}
  318. for i, v in word_table do
  319. tinsert(unacounted_words, i)
  320. end
  321. if getn(unacounted_words) > 0 then
  322. local word = unacounted_words[1]
  323. -- Maybe it's in an ego for the other end of the item?
  324. for i = 1, getn(egos_for_k_idx) do
  325. local ego = e_info(egos_for_k_idx[i])
  326. if is_separate_word(word, strlower(ego.name)) and
  327. is_separate_word(strlower(ego.name), str)
  328. then
  329. message("Ego '" .. ego.name .. "' must go " ..
  330. iif(is_prefix, "after", "before") ..
  331. " the item name.")
  332. return nil
  333. end
  334. end -- for i = 1, getn(egos_for_k_idx) do
  335. -- Okay then, is the word found at *all* in any of the egos?
  336. local word_found = false
  337. for i = 2, max_e_idx do
  338. if is_separate_word(word, strlower(e_info[i].name)) then
  339. word_found = true
  340. if is_separate_word(strlower(e_info[i].name), str) then
  341. message("Ego '" .. e_info[i].name .. "' can not " ..
  342. "be combined with this type of item.")
  343. return nil
  344. end
  345. end
  346. end -- for i = 2, max_e_idx do
  347. if word_found then
  348. message("Can't turn '" .. str .. "' into ego, maybe '" ..
  349. word .. "' is the problem?")
  350. else
  351. message("'" .. word .. "' isn't found in any ego name.")
  352. end
  353. return nil
  354. end -- if getn(unacounted_words) > 0 then
  355. -- No unacounted words, now lets get all permuations of the allowed
  356. -- egos and see if any combination can reproduce the input string.
  357. local combos = permutate(ok_egos)
  358. local matches = {}
  359. local sig_table = {}
  360. for i = 1, getn(combos) do
  361. local combo = combos[i]
  362. local match_str = nil
  363. local match_egos = {}
  364. for j = 1, getn(combo) do
  365. tinsert(match_egos, combo[j])
  366. if not match_str then
  367. match_str = strlower(e_info(combo[j]).name)
  368. else
  369. match_str = match_str .. " " .. strlower(e_info(combo[j]).name)
  370. end
  371. local match_signature = strjoin(match_egos, ":")
  372. if sig_table[match_signature] then
  373. -- Already have exact same match
  374. break
  375. end
  376. if match_str == str then
  377. sig_table[match_signature] = true
  378. tinsert(matches, match_egos)
  379. break
  380. end
  381. end -- for j = 1, getn(combo) do
  382. end -- for i = 1, getn(combos) do
  383. if getn(matches) == 0 then
  384. message("Can't figure out '" .. str .. "' as an ego.")
  385. return nil
  386. end
  387. local good_matches = {}
  388. local bad_matches = {}
  389. local too_long = {}
  390. for i = 1, getn(matches) do
  391. if wish.okay_ego_combo(matches[i]) then
  392. if getn(matches[i]) > MAX_EGO_PER_OBJ then
  393. tinsert(too_long, matches[i])
  394. else
  395. tinsert(good_matches, matches[i])
  396. end
  397. else
  398. tinsert(bad_matches, matches[i])
  399. end
  400. end
  401. if getn(good_matches) == 0 then
  402. if getn(too_long) > 0 then
  403. message("Too many egos in '" .. str .. "'.")
  404. return nil
  405. end
  406. -- All solutions have egos that can't go together; inform user.
  407. for i = 1, getn(bad_matches) do
  408. wish.okay_ego_combo(bad_matches[i], true)
  409. end
  410. return nil
  411. end
  412. return(good_matches)
  413. end -- wish.get_possible_ego_combos()
  414. -- MATT XXX
  415. function wish.extract_egos(wish_str, base_str, item, item_idx)
  416. local egos = {}
  417. -- Does this item kind have it's own strange way of parsing a
  418. -- wish string?
  419. if item.flags[FLAG_PARSE_WISH_STR] then
  420. local func = get_func_from_flag(item.flags, FLAG_PARSE_WISH_STR)
  421. local base, success
  422. success, base, egos = func(wish_str, item)
  423. if success ~= wish.GRANTED then
  424. return success
  425. end
  426. if not egos then
  427. egos = {}
  428. end
  429. return wish.GRANTED, egos
  430. end
  431. -- Extract egos normally
  432. local base_pos = strfind(wish_str, base_str, 1, true)
  433. local base_len = strlen(base_str)
  434. local item_len = strlen(wish_str)
  435. local prefix_str, suffix_str = "", ""
  436. if base_pos > 1 then
  437. prefix_str = strsub(wish_str, 1, base_pos - 2)
  438. end
  439. local prefix_combos =
  440. wish.get_possible_ego_combos(item_idx, prefix_str, true)
  441. if not prefix_combos then
  442. return wish.DENIED
  443. end
  444. if base_pos + base_len <= strlen(wish_str) then
  445. suffix_str = strsub(wish_str, base_pos + base_len + 1,
  446. strlen(wish_str))
  447. end
  448. local suffix_combos =
  449. wish.get_possible_ego_combos(item_idx, suffix_str, false)
  450. if not suffix_combos then
  451. return wish.DENIED
  452. end
  453. -- Are there any egos at all?
  454. if getn(suffix_combos[1]) == 0 and getn(prefix_combos[1]) == 0 then
  455. return wish.GRANTED, {}
  456. end
  457. -- Now generate and test cross-product of possible prefix and
  458. -- suffix ego combos
  459. local cross_product = {}
  460. for i = 1, getn(prefix_combos) do
  461. for j = 1, getn(suffix_combos) do
  462. local product = table_copy(prefix_combos[i])
  463. for k = 1, getn(suffix_combos[j]) do
  464. tinsert(product, suffix_combos[j][k])
  465. end
  466. tinsert(cross_product, product)
  467. end
  468. end
  469. local okay = {}
  470. local bad = {}
  471. local too_long = {}
  472. for i = 1, getn(cross_product) do
  473. local product = cross_product[i]
  474. if wish.okay_ego_combo(product) then
  475. if getn(product) > MAX_EGO_PER_OBJ then
  476. tinsert(too_long, product)
  477. else
  478. tinsert(okay, product)
  479. end
  480. else
  481. tinsert(bad, product)
  482. end
  483. end -- for i = 1, getn(cross_product)
  484. if getn(okay) == 0 then
  485. if getn(too_long) > 0 then
  486. message("Too many egos.")
  487. return wish.DENIED
  488. end
  489. -- All solutions have egos that can't go together; inform user.
  490. for i = 1, getn(bad) do
  491. wish.okay_ego_combo(bad[i], true)
  492. end
  493. return wish.DENIED
  494. end
  495. if getn(okay) > 1 then
  496. message("More than one way to interpret egos.")
  497. return wish.DENIED
  498. end
  499. return wish.GRANTED, okay[1]
  500. end -- wish.extract_egos()
  501. -- Interpret wish string as a request for an item, and see if
  502. -- that works
  503. function wish.for_item(wish_str)
  504. local item_str = ""
  505. local item_idx = nil
  506. -- Find item with the longest matching name. We don't want to
  507. -- match on "pear" when the user is asking for "spear", or
  508. -- given them an ordinary cloak when asking for an elven cloak
  509. for i = 1, max_k_idx-1 do
  510. local item = k_info[i+1]
  511. local name = {}
  512. local raw_name
  513. local dbg = false
  514. if object_desc_tvals[item.tval] and not is_artifact(item) then
  515. name.aware = 1
  516. name.known = 1
  517. if item.flags[FLAG_PARSE_WISH_STR] then
  518. -- The item kind might have a weird way of parsing
  519. -- the item description
  520. local func = get_func_from_flag(item.flags,
  521. FLAG_PARSE_WISH_STR)
  522. local success, base = func(wish_str, item)
  523. if success == wish.GRANTED then
  524. name["base"] = base
  525. else
  526. name["base"] = ""
  527. end
  528. elseif tag(object_desc_tvals[item.tval]) == TAG_FUNCTION then
  529. object_desc_tvals[item.tval](item, name, 0)
  530. else
  531. for k, e in object_desc_tvals[item.tval] do
  532. name[k] = e
  533. end
  534. end
  535. if name["base"] then
  536. name = name["base"]
  537. raw_name = name
  538. name = gsub(name, "#", item.name)
  539. else
  540. name = item.name
  541. raw_name = name
  542. end
  543. else
  544. name = item.name
  545. raw_name = name
  546. end -- Extract the object's base description
  547. if raw_name ~= "" and wish.test_multiple_item(wish_str, raw_name) then
  548. message(wish.ONE_ITEM_MSG)
  549. return wish.DENIED
  550. end
  551. name = gsub(name, "& ", "")
  552. name = gsub(name, "~", "")
  553. name = gsub(name, " ?#", "")
  554. -- We have a separate function for getting corpses,
  555. -- raw meats and such
  556. if strfind(wish_str, strlower(name), 1, true) and
  557. item.tval ~= TV_CORPSE then
  558. -- Is the matching name longer than the previously longest
  559. -- matching name?
  560. if strlen(name) > strlen(item_str) then
  561. item_str = strlower(name)
  562. item_idx = i
  563. end
  564. end
  565. end ---- for i = 1, max_k_idx-1 do
  566. if not item_idx then
  567. -- No message, the wish might be for something besides
  568. -- an item
  569. return wish.UNGRANTED
  570. end
  571. -- Now make sure that what we *think* is the item name isn't
  572. -- actually in the middle of a word. A wish for an item should
  573. -- be in the form of "blah ITEM blah", not "blahITEMblah".
  574. -- If the item name is in the middle of a word, it might be a
  575. -- wish for a non-item. For intance, the monster "cloaker"
  576. -- contains "cloak", but we don't want to give the user a
  577. -- cloak when wishing for a cloaker.
  578. if not is_separate_word(item_str, wish_str) then
  579. return wish.UNGRANTED
  580. end -- Is the item string embeded in a word?
  581. local item = k_info[item_idx+1]
  582. local obj, success
  583. if is_artifact(item) and not wizard then
  584. message(wish.NO_ARTS_MSG)
  585. return wish.DENIED
  586. end
  587. if item.flags[FLAG_GRANT_WISH] then
  588. -- This item type has its own way of setting up the object
  589. -- that is to be created. The item's wishing function must
  590. -- attach the egos to the object and call "apply_magic()".
  591. local func = get_func_from_flag(item.flags, FLAG_GRANT_WISH)
  592. local success
  593. success, obj = func(wish_str, item)
  594. if success ~= wish.GRANTED then
  595. return success
  596. end
  597. else
  598. -- We set up the object the normal way, then.
  599. local egos
  600. success, egos = wish.extract_egos(wish_str, item_str, item, item_idx)
  601. if success ~= wish.GRANTED then
  602. return success
  603. end
  604. obj = create_object(item.tval, item.sval)
  605. for i = 1, getn(egos) do
  606. obj.ego_id[i] = egos[i]
  607. end
  608. -- Make it as if it was at created at level 99, since wishes
  609. -- are powerful and should give you something good. Also
  610. -- make it a "good" object, so it won't be randomly cursed.
  611. apply_magic(obj, 99, FALSE, true, FALSE)
  612. end
  613. set_known(obj)
  614. set_aware(obj)
  615. drop_near(obj, -1, player.py, player.px)
  616. obj.found = OBJ_FOUND_WISH
  617. obj.found_aux1 = current_dungeon_idx
  618. obj.found_aux2 = level_or_feat(current_dungeon_idx, dun_level)
  619. return wish.GRANTED
  620. end
  621. -- Attempt to grant what the player's wish
  622. function wish.make()
  623. for i = 1, 10 do
  624. local wish_str
  625. repeat
  626. wish_str = get_string("Wish for what? ")
  627. if not wish_str then
  628. wish_str = ""
  629. end
  630. wish_str = clean_whitespace(wish_str)
  631. if strlen(wish_str) == 0 then
  632. message("To wish for nothing, simply enter " ..
  633. "\"nothing\" (without the quotes)")
  634. end
  635. until wish_str and strlen(wish_str) > 0
  636. wish_str = strlower(wish_str)
  637. if wish_str == "nothing" then
  638. return nil
  639. end
  640. local ret_val
  641. local wish_types = {wish.for_corpse, wish.for_monster,
  642. wish.for_artifact, wish.for_item}
  643. for j = 1, getn(wish_types) do
  644. local func = wish_types[j]
  645. ret_val = func(wish_str)
  646. if ret_val == wish.GRANTED then
  647. return true
  648. end
  649. if ret_val == wish.DENIED then
  650. break
  651. end
  652. end
  653. if ret_val ~= wish.DENIED then
  654. message("Nothing matching '" .. wish_str ..
  655. "' exists in the game")
  656. end
  657. end
  658. message("You took too long to make your wish, and it " ..
  659. "was wasted")
  660. return nil
  661. end
  662. -- vampiric bug-slaying fiery icy rapier of melting of shocking