Inappropriate material levels for randarts

Where bugs go to lie down and rest

Moderator: Moderator

Post Reply
Message
Author
Hachem_Muche
Uruivellas
Posts: 744
Joined: Thu Nov 18, 2010 6:42 pm

Inappropriate material levels for randarts

#1 Post 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
Author of the Infinite 500 and PlenumTooltip addons, and the joys of Scaling in ToME.

MisiuPysiu
Archmage
Posts: 379
Joined: Tue Nov 11, 2003 10:54 am
Location: Wroclaw/Poland

Re: Inappropriate material levels for randarts

#2 Post by MisiuPysiu »

Hey,

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

Cheers.

Hachem_Muche
Uruivellas
Posts: 744
Joined: Thu Nov 18, 2010 6:42 pm

Re: Inappropriate material levels for randarts

#3 Post 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.
Author of the Infinite 500 and PlenumTooltip addons, and the joys of Scaling in ToME.

darkgod
Master of Eyal
Posts: 10750
Joined: Wed Jul 24, 2002 9:26 pm
Location: Angolwen
Contact:

Re: Inappropriate material levels for randarts

#4 Post by darkgod »

fixed
[tome] joylove: You can't just release an expansion like one would release a Kraken XD
--
[tome] phantomfrettchen: your ability not to tease anyone is simply stunning ;)

Post Reply