summaryrefslogtreecommitdiff
path: root/api.lua
blob: af8e9914fa88f6619d76298ac7c2bde0d3cdad6e (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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
-- AWARDS
-- by Rubenwardy, CC-BY-SA
-------------------------------------------------------
-- this is api function file
-------------------------------------------------------

-- The global award namespace
awards = {}

-- Table Save Load Functions
function awards.save()
	local file = io.open(minetest.get_worldpath().."/awards.txt", "w")
	if file then
		file:write(minetest.serialize(awards.players))
		file:close()
	end
end

function awards.load()
	local file = io.open(minetest.get_worldpath().."/awards.txt", "r")
	if file then
		local table = minetest.deserialize(file:read("*all"))
		if type(table) == "table" then
			return table
		end
	end
	return {}
end

awards.players = awards.load()
function awards.player(name)
	return awards.players[player]
end

-- A table of award definitions
awards.def = {}

function awards.tbv(tb,value,default)
	if not default then
		default = {}
	end
	if not tb or type(tb) ~= "table" then
		if not value then
			value = "[NULL]"
		end
		print("Table '"..value.."' is null, or not a table!")
		return
	end
	if not tb[value] then
		tb[value] = default
	end
end

-- Load files
dofile(minetest.get_modpath("awards").."/triggers.lua")
dofile(minetest.get_modpath("awards").."/config.txt")

-- API Functions
function awards.register_achievement(name,data_table)
	-- see if a trigger is defined in the achievement definition
	if data_table.trigger and data_table.trigger.type then
		if data_table.trigger.type=="dig" then
			local tmp={
				award=name,
			 	node=data_table.trigger.node,
			 	target=data_table.trigger.target,
			}
			table.insert(awards.onDig,tmp)
		elseif data_table.trigger.type=="place" then
			local tmp={
				award=name,
			 	node=data_table.trigger.node,
			 	target=data_table.trigger.target,
			}
			table.insert(awards.onPlace,tmp)
		elseif data_table.trigger.type=="death" then
			local tmp={
				award=name,
			 	target=data_table.trigger.target,
			}
			table.insert(awards.onDeath,tmp)
		end
	end

	-- check icon, background and custom_announce data
	if data_table.icon == nil or data_table.icon == "" then
		data_table.icon = "unknown.png"
	end
	if data_table.background == nil or data_table.background == "" then
		data_table.background = "bg_default.png"
	end
	if data_table.custom_announce == nil or data_table.custom_announce == "" then
		data_table.custom_announce = "Achievement Unlocked:"
	end
	
	-- add the achievement to the definition table
	awards.def[name] = data_table
end

-- this function adds a trigger function or table to the ondig table
function awards.register_onDig(func)
	table.insert(awards.onDig,func);
end

-- this function adds a trigger function or table to the ondig table
function awards.register_onPlace(func)
	table.insert(awards.onPlace,func);
end

-- this function adds a trigger function or table to the ondeath table
function awards.register_onDeath(func)
	table.insert(awards.onDeath,func);
end

-- This function is called whenever a target condition is met.
-- It checks if a player already has that achievement, and if they do not,
-- it gives it to them
----------------------------------------------
--awards.give_achievement(name,award)
-- name - the name of the player
-- award - the name of the award to give
function awards.give_achievement(name,award)
	-- Access Player Data
	local data=awards.players[name]
	
	-- Perform checks
	if not data then
		return
	end
	if not awards.def[award] then
			return
	end
	awards.tbv(data,"unlocked")

	-- check to see if the player does not already have that achievement
	if not data.unlocked[award] or data.unlocked[award]~=award then
		-- Set award flag
		data.unlocked[award]=award

		-- Get data from definition tables
		local title = award
		local desc = ""
		local background = ""
		local icon = ""
		local custom_announce = ""
		if awards.def[award].title then
			title = awards.def[award].title
		end
		if awards.def[award].custom_announce then
			custom_announce = awards.def[award].custom_announce
		end
		if awards.def[award].background then
			background = awards.def[award].background
		end
		if awards.def[award].icon then
			icon = awards.def[award].icon
		end
		if awards.def[award] and awards.def[award].description then
			desc = awards.def[award].description
		end

		-- send the won award message to the player
		if Use_Formspec == true then
			-- use a formspec to send it
			minetest.show_formspec(name, "achievements:unlocked", "size[4,2]"..
					"image_button_exit[0,0;4,2;"..background..";close1; ]"..
					"image_button_exit[0.2,0.8;1,1;"..icon..";close2; ]"..
					"label[1.1,1;"..title.."]"..
					"label[0.3,0.1;"..custom_announce.."]")
		else
			-- use the chat console to send it
			minetest.chat_send_player(name, "Achievement Unlocked: "..title)
			if desc~="" then
				minetest.chat_send_player(name, desc)
			end
		end
	
		-- record this in the log	
		print(name.." Has unlocked"..title..".")
		
		-- save playertable
		awards.save()
	end
end

-- List a player's achievements
minetest.register_chatcommand("list_awards", {
	params = "",
	description = "list_awards: list your awards",
	func = function(name, param)
		if not awards.players[name] or not awards.players[name].unlocked  then
			minetest.chat_send_player(name, "You do not have any awards")
			return
		end

		minetest.chat_send_player(name, name.."'s awards:")

		for _, str in pairs(awards.players[name].unlocked) do
			minetest.chat_send_player(name, str);
		end
	end,
})