Go to file
Tai @ Flex bc8b642deb use deep copy of table 2016-09-23 10:59:21 +01:00
.gitignore ignore 2016-09-14 22:55:22 +01:00
LICENSE change format 2016-09-16 12:27:50 +01:00
README.md updated for table assignment and cloning 2016-09-22 23:08:09 +01:00
api.lua use deep copy of table 2016-09-23 10:59:21 +01:00
depends.txt release state 2016-09-16 11:17:06 +01:00
example.lua generalize to Lua entities overriding 2016-09-16 12:17:03 +01:00
init.lua rename mod 2016-09-17 19:14:35 +01:00
mod.conf Rename mod 2016-09-17 19:14:09 +01:00

README.md

Minetest: Entity Override

Override behaviour of Lua entities.

Why this mod?

This mod is intended to provide a small framework to redefine Lua entities without touching the original mods' Lua files directly - instead, the properties are changed at runtime, during load.

This goes some ways to reduce technical debt - a state where every update to the original or supporting code causes you to need to maintain/reapply your changes.

This way, you can keep up to date with regularly changing mods without having to untangle merge conflicts from your customizations.

Its main use will be to override mob behaviours, but can be used for any entity in the minetest.registered_entities list.

How to use this mod

  1. Create a new mod for your customizations
  2. Add a dependency on this mod, as well as the mods you want to override
  3. Create your Lua files using the API structure

API

To override a Lua entity, call the override:rewrite(name,definition) function , where the parameters are

  • name - the itemstring of the entity
  • definition - a table providing new value rules for the entity

The definition is simple a table, whose keys are the names of the properties in the original definition.

Straight subsitution

The values can be straight values (string, number, boolean, function) or a table representing the substitution rules.

For example

local newdef = {
		-- imperative substitution
		hp_max = 40,
		on_rightclick = function(self,clicker) minetest.chat_send_player(clicker:get_player_name(),"You cannot tame "..self.name) end, -- just substitute the function
	}
override:rewrite("dmobs:ogre", newdef)
override:rewrite("dmobs:orc", newdef)

This modifies two mobs so that they react when right-clicked, but no more, as well as providing them with a new maximum HP.

Tables, and Conditional substitution

The substition can also be done on a conditional basis per property, where a checking function is provided. Return the boolean true from the checking function to go ahead with the substitution; any other value (including the string "true") will cause the original property's value to be left alone.

override:rewrite("dmobs:hedgehog",{
	hp_max = {
		check = function(oldval)
			return oldval < 10
		end,
		value = 15
	}
})

This assigns a new max HP to a mob only if its normal HP is less than 10, otherwise the HP is left at whatever value it had normally.

Note that to assign tables, you need to write a conditional substitution - but you can leave out the checking function:

override:rewrite("mobs_slimes:slime_small",{
	textures = {
		tableorder = "append", -- or "prepend", this parameter is optional in case the order will be important
		value = {"newtexture_front.png","newtexture_side.png"} -- the actual table that will be assigned
	}
})

Function chaining

You can add a function before or after the function currently in place by providing a table defining the fchain_type (whether it runs before or after the original function), and the fchain_func as the function to run.

In the case of a "before" type, where your custom function runs before the original, you must return either a boolean true or boolean false. True will allow the original function to run; false will cause the original function to be skipped.

override:rewrite("mobs_animal:sheep",{
	on_rightclick = {
		fchain_type = "before",
		fchain_func = function (self,clicker)
			if self.tame ~= true
			  or clicker:get_wielded_item() == self.follows
			  then
				return true -- run original handler
			end

			-- get wool, at the cost of the animal's health
			minetest.add_entity(self.getpos(),"default:wool" )
			self.health = self.health-1
			return false -- do not run the original handler
		end
	}
})

This will add funcitonality before the normal right-click routine (presuming mobs_redo is in use, it would be the feeding and taming functionality), passing control to the original handler if the animal is generally not tamed, or if the item in hand is what the animal follows; in any other case, some custom code is run and the original handler is skipped.

Mob Cloning

You can clone an existing mob as your own and give it extra definitions. For example, say your mod is mydmobs, and you want an extra hedgehog, for battle purposes. You could do:

override.clone("dmobs:hedgehog","mydmobs:battlehedgehog")

override.rewrite("mydmobs:battlehedgehog",{
	type = "npc",
	hp_max = 20,
	hp_min = 18,
	armor = 100,
	attack_mosters = true,
	attack_type = "dogfight",
})

Now in addition to the regular dmobs hedgehogs, you also have your own mod's hedgehog clones ready to defend you!