Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

mcl_villager_cheats now includes a "reload trades" button

I was inspired by some recent conversations about an upcoming new Luanti mod about randomizing the trades a villager offers, and I wrote my own implementation! It involved copying the entirety of the villager code from Mineclonia (ContentDB) and adding a small patch. Well, and the logic for changing the trades too.

The concept of rotating trades of a villager can be done in-game, for a villager who has never traded, by removing his job block and replacing it. This button short-circuits that. And my implementation leaves it possible even after the villager has participated in a trade. So yes, it's cheating, but that's in the name of the mod. I don't even have a configuration setting for disabling it if the villager xp > 0 (that is, he has traded at all). I could add it, if anybody is interested.

files/2026/listings/diff-villager.patch (Source)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Date: 2026-08-11
Message: The difference between Mineclonia villager.lua and mcl_villager_cheats villager.lua
Last-Version: 0.123.0
Author: bgstack15
Command: diff -aur ~/.minetest/games/mineclonia/mods/ENTITIES/mobs_mc/villager.lua ~/.minetest/mods/mcl_villager_cheats/villager.lua
--- .minetest/games/mineclonia/mods/ENTITIES/mobs_mc/villager.lua	2026-07-26 14:20:37.152618130 -0400
+++ .minetest/mods/mcl_villager_cheats/villager.lua	                2026-08-11 11:52:24.416485282 -0400
@@ -711,6 +711,12 @@
  list[current_player;main;3.97,7.98;9,1;]
 
 ]]
+-- stackrpms,6
+fs_footer_template = fs_footer_template ..
+	"image_button[4.0,0.2;1.0,1.0;mcl_villager_cheats_reload.png;reload;]" ..
+	"tooltip[reload;Randomize available trades" ..
+	core.colorize("#47f424","\n(" .. core.get_current_modname() .. ")") ..
+	";#000000;#ffffff]"
 
 -- arg 1 = %s = wanted
 -- arg 2 = %s = wanted tooltip
@@ -903,6 +909,15 @@
 
 core.register_on_player_receive_fields (function (player, formname, fields)
 	if formname == "mobs_mc:trading_formspec" then
+		--stackrpms,9
+		if fields.reload then
+			local trader = trading_players[player]
+			if trader and is_valid (trader) then
+				mcl_villager_cheats.reload_trades(trader)
+				local entity = trader:get_luaentity ()
+				entity:reload_trades()
+			end
+		end
 		if fields.quit then
 			return_fields (player)
 			local trader = trading_players[player]
@@ -942,6 +957,11 @@
 		type = "detached",
 		name = inv_name,
 	})
+	-- stackrpms,5 Need to remove the previous inventory, so this new inventory
+	if inv then
+		core.remove_detached_inventory(inv_name)
+		inv = nil
+	end
 	if not inv then
 		inv = core.create_detached_inventory (inv_name, inv_class,
 							  playername)
@@ -6783,4 +6803,5 @@
 -- Villager spawning.
 ------------------------------------------------------------------------
 
-mcl_mobs.register_egg ("mobs_mc:villager", S("Villager"), "#563d33", "#bc8b72", 0)
+-- stackrpms,2 Do not run this again
+--mcl_mobs.register_egg ("mobs_mc:villager", S("Villager"), "#563d33", "#bc8b72", 0)

Comments