Thread: Bugfixes
View Single Post
  #7  
Old 11-07-2012, 05:00 PM
Bhruic Bhruic is offline
Approved Member
 
Join Date: Oct 2012
Posts: 233
Default

This is (hopefully) a fix for the Highterant egg-laying issue. As it's a rather large piece of code (I wrote a specific AI routine to handle it - go me! ), I'm placing the code here rather than in the first post. Also, I'm not including pre- and post-code changes, everything in red text was added by me. The aim of this routine is to try and find the square that is farthest away from any enemy (and within movement range) and lay the egg there - presumably with the best chance of survival.

In arena.lua, line 2718:
Code:
local maxc, maxtarget
if mover.name == "highterrant" then
	local maxdist = 0
	for i = 0, ecells.n do
		local c = ecells[i]
		if c == nil then  -- проверяем также клетку, где мы стоим - вдруг идти никуда и не нужно - и здесь хорошо
			c = mover
			c.distance = 0
		end
		if c.distance < mover.ap then
			local near_enemy = false
			for dir = 0, 5 do
				local c2 = Attack.cell_adjacent(c, dir)
				if Attack.act_enemy(c2) then
					near_enemy = true
					break
				end
			end
			if not near_enemy then
				local dist = 0
				for k = 0, ecells.n do
					local c2 = ecells[k]
					if c2 == nil then  -- проверяем также клетку где стоим, т.к. с нее можем уйти
						c2 = mover
					end
					if Attack.cell_dist(c, c2) == 1 then
						local mindist = 1e8
						for j, act in ipairs(actors) do
							if Attack.act_enemy(act) then
								dist = Attack.cell_dist(c2, act)
								if dist < mindist then
									mindist = dist
								end
							end
						end
						if mindist > maxdist then
							maxdist = mindist
							maxc = c
							maxtarget = c2
						end
					end
				end
			end
		end
	end
else
	if offence and not mover.thrower and (mover.par('dismove') == 0) and (mover.ap > 1) then -- при наступательной тактике не-стрелки способные перемещаться бегут к вражеским лучникам
		-- здесь могут оказаться : demon, dryad, highterrant, thorn_warrior
		local mindist = 1e8
		local nneed_corpse = true
		if mover.name == "thorn" or mover.name == "thorn_warrior" then -- тернии призывают на гексы с трупами
			nneed_corpse = false
		end
		for i = 0, ecells.n do
			local c = ecells[i]
			if c == nil then  -- проверяем также клетку, где мы стоим - вдруг идти никуда и не нужно - и здесь хорошо
				c = mover
				c.distance = 0
			end
			if c.distance < mover.ap then
				local dist = 0
				for j, act in ipairs(actors) do
					if Attack.act_enemy(act) then
						if act.thrower then
							dist = dist + Attack.cell_dist(c, act)*0.5
						else
							dist = dist + Attack.cell_dist(c, act)
						end
					end
				end
				if dist < mindist then
					for j = 0, ecells.n do
						local c2 = ecells[j]
						if c2 == nil then  -- проверяем также клетку где стоим, т.к. с нее можем уйти
							c2 = mover
						end
						if Attack.cell_dist(c, c2) == 1 then
							if nneed_corpse or Attack.cell_has_ally_corpse(c2) or Attack.cell_has_enemy_corpse(c2) then
								mindist = dist
								maxc = c
								break
							end
						end
					end
				end
			end
		end
		if maxc ~= nil then
			local mindist2 = 1e8
			for i = 0, ecells.n do
				local c2 = ecells[i]
				if c2 == nil then  -- проверяем также клетку где стоим, т.к. с нее можем уйти
					c2 = mover
				end
				if Attack.cell_dist(maxc, c2) == 1 then
					if nneed_corpse or Attack.cell_has_ally_corpse(c2) or Attack.cell_has_enemy_corpse(c2) then
						local dist2 = 0
						for j, act in ipairs(enemies) do -- как далеко до врагов
							if act.thrower then
								dist2 = dist2 + Attack.cell_dist(c2, act)*0.5
							else
								dist2 = dist2 + Attack.cell_dist(c2, act)
							end
						end
						if dist2 < mindist2 then
							mindist2 = dist2
							maxtarget = c2
						end
					end
				end
			end
		end
	end
	if maxc == nil then
		-- здесь гарантированно окажутся : chosha, demonologist, druid, ingeneer, kingthorn, thorn
		local mindist2 = 1e8
		for i = 1, atk.cells.n do
			local c2 = atk.cells[i]
			local dist2 = 0
			for j, act in ipairs(enemies) do -- как далеко до врагов
				if act.thrower then
					dist2 = dist2 + Attack.cell_dist(c2, act)*0.5
				else
					dist2 = dist2 + Attack.cell_dist(c2, act)
				end
			end
			if dist2 < mindist2 then
				mindist2 = dist2
				maxtarget = c2
			end
		end
	end
end

Last edited by Bhruic; 11-07-2012 at 05:09 PM.
Reply With Quote