Page 1 of 1

Confirm cast dialog and autocast abilities

Posted: Mon Mar 25, 2013 3:14 am
by Darkmere
Sorry if this has been posted before, but I skimmed the first 2 pages and didn't see anything that sounded like this error.

If you have an ability set to auto-use while exploring, and set to provide a dialog before auto-using said skill, auto-explore will continue uninterrupted while scores of confirmation dialog boxes pop up. When autoexplore is interrupted, you can confirm every dialog box to spam that ability as much as you want, bypassing cooldown.

Tested with Earth's Eyes on a Thalore Summoner. I'm sure there are... more amusing applications as well.

Re: Confirm cast dialog and autocast abilities

Posted: Mon Mar 25, 2013 4:30 am
by Crim, The Red Thunder
Hmmmm... Autocasting glacial vapors (normal autocast, not 'when no enemies in view') prompts for a dialog box asking if you want to hit yourself... Could one, perhaps, trip this with say... a different (much stronger) attack? Hmmmmm.... Excuse me while I go nail a farportal boss or Athamthon with a few dozen soul rots in a single turn....

Kudos Darkmere, on breaking the game. I'll raise a toast in your honor!

Re: Confirm cast dialog and autocast abilities

Posted: Mon Mar 25, 2013 7:02 am
by R_D
I just tried this with the Blastwave skill from the wildfire tree. ...it worked. You're limited by turns and mana--cooldown was no object; I just spammed blastwave after blastwave one after another. This should probably be fixed asap... While you're at it, make it so the dang dialogue box doesn't pop up ad infinitum while resting/auto-exploring!

Re: Confirm cast dialog and autocast abilities

Posted: Mon Mar 25, 2013 6:56 pm
by Hachem_Muche
A related problem was reported at http://forums.te4.org/viewtopic.php?f=42&t=36998

The problems are corrected by stopping autoexplore, running, and extra popup confirmation windows whenever a confirmation dialog is already pending. In the (rare) case that 2 or more auto-use/auto-confirm talents are triggered in the same turn, one will ask for confirmation as normal while the others will not be triggered (They may be activated manually as normal or may be triggered the next turn.).

Patch:

Code: Select all

Index: game/engines/default/engine/interface/ActorTalents.lua
===================================================================
--- game/engines/default/engine/interface/ActorTalents.lua	(revision 6589)
+++ game/engines/default/engine/interface/ActorTalents.lua	(working copy)
@@ -156,13 +156,15 @@
 			if not ignore_cd then self:startTalentCooldown(ab) end
 		end)
 		local success, err
-		if not no_confirm and self:isTalentConfirmable(ab) then
+		if not no_confirm and not game.dialog_pending and self:isTalentConfirmable(ab) then
 			local abname = game:getGenericTextTiles(ab)..ab.name
+			game.dialog_pending = true
 			require "engine.ui.Dialog":yesnoPopup("Talent Use Confirmation", ("Use %s?"):format(abname),
 			function(quit)
 				if quit ~= false then
 					cancel = true
 				end
+				game.dialog_pending = nil
 				success, err = coroutine.resume(co)
 			end,
 			"Cancel","Continue")
@@ -212,14 +214,16 @@
 			end
 		end)
 		local success, err
-		if not no_confirm and self:isTalentConfirmable(ab) then
+		if not no_confirm and not game.dialog_pending and self:isTalentConfirmable(ab) then
 			local abname = game:getGenericTextTiles(ab)..ab.name
+			game.dialog_pending = true
 			require "engine.ui.Dialog":yesnoPopup("Talent Use Confirmation", ("%s %s?"):
 			format(self:isTalentActive(ab.id) and "Deactivate" or "Activate",abname),
 			function(quit)
 				if quit ~= false then
 					cancel = true
 				end
+				game.dialog_pending = nil
 				success, err = coroutine.resume(co)
 			end,
 			"Cancel","Continue")
Index: game/modules/tome/class/Game.lua
===================================================================
--- game/modules/tome/class/Game.lua	(revision 6589)
+++ game/modules/tome/class/Game.lua	(working copy)
@@ -1368,6 +1368,8 @@
 					for _, node in ipairs(seen) do
 						node.actor:addParticles(engine.Particles.new("notice_enemy", 1))
 					end
+				elseif game.dialog_pending then
+					self.log("Autoexplore stopped for player input.")
 				elseif not self.player:autoExplore() then
 					self.log("There is nowhere left to explore.")
 				end
Index: game/modules/tome/class/interface/PlayerExplore.lua
===================================================================
--- game/modules/tome/class/interface/PlayerExplore.lua	(revision 6589)
+++ game/modules/tome/class/interface/PlayerExplore.lua	(working copy)
@@ -2540,7 +2540,7 @@
 end
 
 function _M:checkAutoExplore()
-	if not self.running or not self.running.explore then return false end
+	if not self.running or not self.running.explore or game.dialog_pending then return false end
 
 	-- We can open a door and explore if the player initiated auto-explore directly adjacent to the target door.
 	-- If not, though, then stop, because the player *must* choose to open the door (except for "safe" doors)
Index: game/modules/tome/class/Player.lua
===================================================================
--- game/modules/tome/class/Player.lua	(revision 6589)
+++ game/modules/tome/class/Player.lua	(working copy)
@@ -685,9 +685,10 @@
 -- This should be called in your actors "act()" method
 function _M:automaticTalents()
 	for tid, c in pairs(self.talents_auto) do
 		local t = self.talents_def[tid]
 		local spotted = spotHostiles(self)
-		if (t.mode ~= "sustained" or not self.sustain_talents[tid]) and not self.talents_cd[tid] and self:preUseTalent(t, true, true) and (not t.auto_use_check or t.auto_use_check(self, t)) then
+		if not(game.dialog_pending and self:isTalentConfirmable(tid)) and (t.mode ~= "sustained" or not self.sustain_talents[tid]) and not self.talents_cd[tid] and self:preUseTalent(t, true, true) and (not t.auto_use_check or t.auto_use_check(self, t)) then
 			if (c == 1) or (c == 2 and #spotted <= 0) or (c == 3 and #spotted > 0) then
 				if c ~= 2 then
 					self:useTalent(tid)
@@ -824,6 +825,7 @@
 -- Known traps aren't interesting.  We let the engine run around traps, or stop if it can't.
 -- 'ignore_memory' is only used when checking for paths around traps.  This ensures we don't remember items "obj_seen" that we aren't supposed to
 function _M:runCheck(ignore_memory)
+	if game.dialog_pending then return false, "awaiting player input" end
 	local spotted = spotHostiles(self)
 	if #spotted > 0 then
 		local dir = game.level.map:compassDirection(spotted[1].x - self.x, spotted[1].y - self.y)