aboutsummaryrefslogtreecommitdiff
path: root/signals.lua
blob: 8be65e0f1883c3ecff97a9bacd42deed6646e617 (plain)
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
--advtrains by orwell96
--signals.lua
for r,f in pairs({on="off", off="on"}) do

	advtrains.trackplacer.register_tracktype("advtrains:retrosignal", "")
	advtrains.trackplacer.register_tracktype("advtrains:signal", "")

	for rotid, rotation in ipairs({"", "_30", "_45", "_60"}) do
		local crea=1
		if rotid==1 and r=="off" then crea=0 end
		
		minetest.register_node("advtrains:retrosignal_"..r..rotation, {
			drawtype = "mesh",
			paramtype="light",
			paramtype2="facedir",
			walkable = false,
			selection_box = {
				type = "fixed",
				fixed = {-1/4, -1/2, -1/4, 1/4, 2, 1/4},
			},
			mesh = "advtrains_retrosignal_"..r..rotation..".b3d",
			tiles = {"advtrains_retrosignal.png"},
			inventory_image="advtrains_retrosignal_inv.png",
			drop="advtrains:retrosignal_off",
			description="Lampless Signal ("..r..rotation..")",
			on_rightclick=switchfunc,
			sunlight_propagates=true,
			groups = {
				choppy=3,
				not_blocking_trains=1,
				not_in_creative_inventory=crea,
			},
			mesecons = {effector = {
				["action_"..f] = function (pos, node)
					minetest.swap_node(pos, {name = "advtrains:retrosignal_"..f..rotation, param2 = node.param2})
				end
			}},
			on_rightclick=function(pos, node, clicker)
				minetest.swap_node(pos, {name = "advtrains:retrosignal_"..f..rotation, param2 = node.param2})
			end,
		})
		advtrains.trackplacer.add_worked("advtrains:retrosignal", r, rotation, nil)
		minetest.register_node("advtrains:signal_"..r..rotation, {
			drawtype = "mesh",
			paramtype="light",
			paramtype2="facedir",
			walkable = false,
			selection_box = {
				type = "fixed",
				fixed = {-1/4, -1/2, -1/4, 1/4, 2, 1/4},
			},
			mesh = "advtrains_signal"..rotation..".b3d",
			tiles = {"advtrains_signal_"..r..".png"},
			inventory_image="advtrains_signal_inv.png",
			drop="advtrains:signal_off",
			description="Signal ("..r..rotation..")",
			on_rightclick=switchfunc,
			groups = {
				choppy=3,
				not_blocking_trains=1,
				not_in_creative_inventory=crea,
			},
			light_source = 1,
			sunlight_propagates=true,
			mesecons = {effector = {
				["action_"..f] = function (pos, node)
					minetest.swap_node(pos, {name = "advtrains:signal_"..f..rotation, param2 = node.param2})
				end
			}},
			on_rightclick=function(pos, node, clicker)
				minetest.swap_node(pos, {name = "advtrains:signal_"..f..rotation, param2 = node.param2})
			end,
		})
		advtrains.trackplacer.add_worked("advtrains:signal", r, rotation, nil)
	end
end
his program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef CRAFTDEF_HEADER #define CRAFTDEF_HEADER #include <string> #include <iostream> #include <vector> #include <utility> #include "gamedef.h" #include "inventory.h" /* Crafting methods. The crafting method depends on the inventory list that the crafting input comes from. */ enum CraftMethod { // Crafting grid CRAFT_METHOD_NORMAL, // Cooking something in a furnace CRAFT_METHOD_COOKING, // Using something as fuel for a furnace CRAFT_METHOD_FUEL, }; /* The type a hash can be. The earlier a type is mentioned in this enum, the earlier it is tried at crafting, and the less likely is a collision. Changing order causes changes in behaviour, so know what you do. */ enum CraftHashType { // Hashes the normalized names of the recipe's elements. // Only recipes without group usage can be found here, // because groups can't be guessed efficiently. CRAFT_HASH_TYPE_ITEM_NAMES, // Counts the non-empty slots. CRAFT_HASH_TYPE_COUNT, // This layer both spares an extra variable, and helps to retain (albeit rarely used) functionality. Maps to 0. // Before hashes are "initialized", all hashes reside here, after initialisation, none are. CRAFT_HASH_TYPE_UNHASHED }; const int craft_hash_type_max = (int) CRAFT_HASH_TYPE_UNHASHED; /* Input: The contents of the crafting slots, arranged in matrix form */ struct CraftInput { CraftMethod method; unsigned int width; std::vector<ItemStack> items; CraftInput(): method(CRAFT_METHOD_NORMAL), width(0), items() {} CraftInput(CraftMethod method_, unsigned int width_, const std::vector<ItemStack> &items_): method(method_), width(width_), items(items_) {} std::string dump() const; }; /* Output: Result of crafting operation */ struct CraftOutput { // Used for normal crafting and cooking, itemstring std::string item; // Used for cooking (cook time) and fuel (burn time), seconds float time; CraftOutput(): item(""), time(0) {} CraftOutput(std::string item_, float time_): item(item_), time(time_) {} std::string dump() const; }; /* A list of replacements. A replacement indicates that a specific input item should not be deleted (when crafting) but replaced with a different item. Each replacements is a pair (itemstring to remove, itemstring to replace with) Example: If ("bucket:bucket_water", "bucket:bucket_empty") is a replacement pair, the crafting input slot that contained a water bucket will contain an empty bucket after crafting. Note: replacements only work correctly when stack_max of the item to be replaced is 1. It is up to the mod writer to ensure this. */ struct CraftReplacements { // List of replacements std::vector<std::pair<std::string, std::string> > pairs; CraftReplacements(): pairs() {} CraftReplacements(std::vector<std::pair<std::string, std::string> > pairs_): pairs(pairs_) {} std::string dump() const; }; /* Crafting definition base class */ class CraftDefinition { public: CraftDefinition(){} virtual ~CraftDefinition(){} // Returns type of crafting definition virtual std::string getName() const=0; // Checks whether the recipe is applicable virtual bool check(const CraftInput &input, IGameDef *gamedef) const=0; // Returns the output structure, meaning depends on crafting method // The implementation can assume that check(input) returns true virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const=0; // the inverse of the above virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const=0; // Decreases count of every input item virtual void decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const=0; virtual CraftHashType getHashType() const = 0; virtual u64 getHash(CraftHashType type) const = 0; // to be called after all mods are loaded, so that we catch all aliases virtual void initHash(IGameDef *gamedef) = 0; virtual std::string dump() const=0; }; /* A plain-jane (shaped) crafting definition Supported crafting method: CRAFT_METHOD_NORMAL. Requires the input items to be arranged exactly like in the recipe. */ class CraftDefinitionShaped: public CraftDefinition { public: CraftDefinitionShaped(): output(""), width(1), recipe(), hash_inited(false), replacements() {} CraftDefinitionShaped( const std::string &output_, unsigned int width_, const std::vector<std::string> &recipe_, const CraftReplacements &replacements_): output(output_), width(width_), recipe(recipe_), hash_inited(false), replacements(replacements_) {} virtual ~CraftDefinitionShaped(){} virtual std::string getName() const; virtual bool check(const CraftInput &input, IGameDef *gamedef) const; virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const; virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const; virtual void decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const; virtual CraftHashType getHashType() const; virtual u64 getHash(CraftHashType type) const; virtual void initHash(IGameDef *gamedef); virtual std::string dump() const; private: // Output itemstring std::string output; // Width of recipe unsigned int width; // Recipe matrix (itemstrings) std::vector<std::string> recipe; // Recipe matrix (item names) std::vector<std::string> recipe_names; // bool indicating if initHash has been called already bool hash_inited; // Replacement items for decrementInput() CraftReplacements replacements; }; /* A shapeless crafting definition Supported crafting method: CRAFT_METHOD_NORMAL. Input items can arranged in any way. */ class CraftDefinitionShapeless: public CraftDefinition { public: CraftDefinitionShapeless(): output(""), recipe(), hash_inited(false), replacements() {} CraftDefinitionShapeless( const std::string &output_, const std::vector<std::string> &recipe_, const CraftReplacements &replacements_): output(output_), recipe(recipe_), hash_inited(false), replacements(replacements_) {} virtual ~CraftDefinitionShapeless(){} virtual std::string getName() const; virtual bool check(const CraftInput &input, IGameDef *gamedef) const; virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const; virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const; virtual void decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const; virtual CraftHashType getHashType() const; virtual u64 getHash(CraftHashType type) const; virtual void initHash(IGameDef *gamedef); virtual std::string dump() const; private: // Output itemstring std::string output; // Recipe list (itemstrings) std::vector<std::string> recipe; // Recipe list (item names) std::vector<std::string> recipe_names; // bool indicating if initHash has been called already bool hash_inited; // Replacement items for decrementInput() CraftReplacements replacements; }; /* Tool repair crafting definition Supported crafting method: CRAFT_METHOD_NORMAL. Put two damaged tools into the crafting grid, get one tool back. There should only be one crafting definition of this type. */ class CraftDefinitionToolRepair: public CraftDefinition { public: CraftDefinitionToolRepair(): additional_wear(0) {} CraftDefinitionToolRepair(float additional_wear_): additional_wear(additional_wear_) {} virtual ~CraftDefinitionToolRepair(){} virtual std::string getName() const; virtual bool check(const CraftInput &input, IGameDef *gamedef) const; virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const; virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const; virtual void decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const; virtual CraftHashType getHashType() const { return CRAFT_HASH_TYPE_COUNT; } virtual u64 getHash(CraftHashType type) const { return 2; } virtual void initHash(IGameDef *gamedef) {} virtual std::string dump() const; private: // This is a constant that is added to the wear of the result. // May be positive or negative, allowed range [-1,1]. // 1 = new tool is completely broken // 0 = simply add remaining uses of both input tools // -1 = new tool is completely pristine float additional_wear; }; /* A cooking (in furnace) definition Supported crafting method: CRAFT_METHOD_COOKING. */ class CraftDefinitionCooking: public CraftDefinition { public: CraftDefinitionCooking(): output(""), recipe(""), hash_inited(false), cooktime() {} CraftDefinitionCooking( const std::string &output_, const std::string &recipe_, float cooktime_, const CraftReplacements &replacements_): output(output_), recipe(recipe_), hash_inited(false), cooktime(cooktime_), replacements(replacements_) {} virtual ~CraftDefinitionCooking(){} virtual std::string getName() const; virtual bool check(const CraftInput &input, IGameDef *gamedef) const; virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const; virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const; virtual void decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const; virtual CraftHashType getHashType() const; virtual u64 getHash(CraftHashType type) const; virtual void initHash(IGameDef *gamedef); virtual std::string dump() const; private: // Output itemstring std::string output; // Recipe itemstring std::string recipe; // Recipe item name std::string recipe_name; // bool indicating if initHash has been called already bool hash_inited; // Time in seconds float cooktime; // Replacement items for decrementInput() CraftReplacements replacements; }; /* A fuel (for furnace) definition Supported crafting method: CRAFT_METHOD_FUEL. */ class CraftDefinitionFuel: public CraftDefinition { public: CraftDefinitionFuel(): recipe(""), hash_inited(false), burntime() {} CraftDefinitionFuel(std::string recipe_, float burntime_, const CraftReplacements &replacements_): recipe(recipe_), hash_inited(false), burntime(burntime_), replacements(replacements_) {} virtual ~CraftDefinitionFuel(){} virtual std::string getName() const; virtual bool check(const CraftInput &input, IGameDef *gamedef) const; virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const; virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const; virtual void decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const; virtual CraftHashType getHashType() const; virtual u64 getHash(CraftHashType type) const; virtual void initHash(IGameDef *gamedef); virtual std::string dump() const; private: // Recipe itemstring std::string recipe; // Recipe item name std::string recipe_name; // bool indicating if initHash has been called already bool hash_inited; // Time in seconds float burntime; // Replacement items for decrementInput() CraftReplacements replacements; }; /* Crafting definition manager */ class ICraftDefManager { public: ICraftDefManager(){} virtual ~ICraftDefManager(){} // The main crafting function virtual bool getCraftResult(CraftInput &input, CraftOutput &output, std::vector<ItemStack> &output_replacements, bool decrementInput, IGameDef *gamedef) const=0; virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output, IGameDef *gamedef, unsigned limit=0) const=0; // Print crafting recipes for debugging virtual std::string dump() const=0; }; class IWritableCraftDefManager : public ICraftDefManager { public: IWritableCraftDefManager(){} virtual ~IWritableCraftDefManager(){} // The main crafting function virtual bool getCraftResult(CraftInput &input, CraftOutput &output, std::vector<ItemStack> &output_replacements, bool decrementInput, IGameDef *gamedef) const=0; virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output, IGameDef *gamedef, unsigned limit=0) const=0; virtual bool clearCraftRecipesByOutput(const CraftOutput &output, IGameDef *gamedef) = 0; virtual bool clearCraftRecipesByInput(CraftMethod craft_method, unsigned int craft_grid_width, const std::vector<std::string> &recipe, IGameDef *gamedef) = 0; // Print crafting recipes for debugging virtual std::string dump() const=0; // Add a crafting definition. // After calling this, the pointer belongs to the manager. virtual void registerCraft(CraftDefinition *def, IGameDef *gamedef) = 0; // Delete all crafting definitions virtual void clear()=0; // To be called after all mods are loaded, so that we catch all aliases virtual void initHashes(IGameDef *gamedef) = 0; }; IWritableCraftDefManager* createCraftDefManager(); #endif