Page 1 of 1

Inappropriate material levels for randarts

Posted: Tue Feb 19, 2013 6:33 pm
by Hachem_Muche
Randarts generated for random bosses are often useless (particularly weapons) because the material level of the item has no bearing on the level of difficulty of the zone (or the boss). This is caused because the filter parameter "ingore_material_restriction=true" allows any material level to be used. I have fixed this in Infinite500 by updating the resolver for calculating randarts to take the level of the actor into account, ensuring that most randarts are of appropriate quality for the boss that drops them.

Changes to modules/tome/resolvers.lua (patch, includes a resolver for power level vs. zone base level):
resolvers.lua.patch.txt
(2.81 KiB) Downloaded 142 times
The corresponding I500 code showing the changes marked by I5 in comments:

Code: Select all

--I5 Resolves material level based on actor level
-- @param base = base value at level = base_level (scales as sqrt)
-- @param spread = number of std deviations (1 usually) in material level
-- @param min, max = material level limits
function resolvers.matlevel(base, base_level, spread, mn, mx)
	return {__resolver="matlevel", base, base_level, spread, mn, mx}
end
function resolvers.calc.matlevel(t, e)
	local mean = math.min(e.level/10+1,t[1] * (e.level/t[2])^.5) -- I5 material level scales up with sqrt of actor level or level/10
	local spread = math.max(t[3],mean/5) -- spread out probabilities at high level
	local mn = t[4] or 1
	local mx = t[5] or 5
	
	local rand = math.floor(rng.normalFloat(mean,spread))
	return util.bound(rand,mn,mx)
end

-- Estimate actor final level for drop calculations (.__resolve_last does not work)
function actor_final_level(e)
	local finlevel = math.max(math.max(e.level,e.start_level),1)
	if game.zone.actor_adjust_level and e.forceLevelup then
		return math.max(finlevel, game.zone:actor_adjust_level(game.level, e) + e:getRankLevelAdjust())
	else
		return math.max(finlevel, game.zone.base_level + e:getRankLevelAdjust())
	end
end

--- Resolves drops creation for an actor; drops a created on the fly randart
function resolvers.drop_randart(t)
	return {__resolver="drop_randart", __resolve_last=true, t}
end
--- Actually resolve the drops creation for an actor
function resolvers.calc.drop_randart(t, e)
	t = t[1]
	local filter = t.filter

	local matresolver = resolvers.matlevel(5,50,1,2) --I5 material level resolver, min material level 2
	
--	game.log("#LIGHT_BLUE#Calculating randart drop for %s (uid %d, est level %d)",e.name,e.uid,actor_final_level(e))
	if not filter then 
--I5		if not matlevel then --I5
--I5			filter = {ingore_material_restriction=true, no_tome_drops=true, ego_filter={keep_egos=true, ego_chance=-1000}, special=function(e) return (not e.unique and e.randart_able) and (not e.material_level or e.material_level >= 2) and true or false
--			end}
--		else-- I5 scale up randart material level with level of actor
		filter = {ingore_material_restriction=true, no_tome_drops=true, ego_filter={keep_egos=true, ego_chance=-1000}, special=function(eq)
--		local afl = actor_final_level(e)
		local matlevel = resolvers.calc.matlevel(matresolver,{level = actor_final_level(e)}) --I5
--		game.log("Checking equipment %s against material level %d for %s (final level %d)",eq.name,matlevel,e.name, actor_final_level(e))
		return (not eq.unique and eq.randart_able) and eq.material_level == matlevel and true or false
		end} --I5
--		end
	end
--	print("Randart Drops resolver")
	local base = nil
	if filter then
		if not filter.defined then
			base = game.zone:makeEntity(game.level, "object", filter, nil, true)
		else
			base = game.zone:makeEntityByName(game.level, "object", filter.defined)
		end
	end

	local o = game.state:generateRandart{base=base, lev=resolvers.current_level}
	if o then
--		print("Zone made us a randart drop according to filter!", o:getName{force_id=true})
		e:addObject(e.INVEN_INVEN, o)
		game.zone:addEntity(game.level, o, "object")

		if t.id then o:identify(t.id) end
	end
	-- Delete the origin field
	return nil
end

Re: Inappropriate material levels for randarts

Posted: Wed Feb 20, 2013 3:17 pm
by MisiuPysiu
Hey,

This change is interesting. How can I integrate it with the main game?

Cheers.

Re: Inappropriate material levels for randarts

Posted: Wed Feb 20, 2013 5:43 pm
by Hachem_Muche
The simplest method is to just install the Infinite500 addon, that includes this among many other changes. Or you can change your game code with the patch file I've provided with a program (SVN client, etc.) that will accept patch files.

Re: Inappropriate material levels for randarts

Posted: Thu Feb 21, 2013 11:58 pm
by darkgod
fixed