File: modWP_Events.lua

package info (click to toggle)
freedroidrpg 1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid
  • size: 273,532 kB
  • sloc: ansic: 66,191; cpp: 2,033; sh: 766; makefile: 627; python: 322; xml: 94; perl: 87
file content (315 lines) | stat: -rw-r--r-- 13,123 bytes parent folder | download
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
--[[

	Copyright (c) 2014 Scott Furry

	This file is part of Freedroid

	Freedroid is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	Freedroid 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with Freedroid; see the file COPYING. If not, write to the
	Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
	MA  02111-1307  USA

]]--
--	Lua module to parse FDRPG Character information into wiki page
local modWP_Events = {}
--	modWPCommon reference
modWP_Events.modcommon = {}
--	Variable will contained all parsed information after completion of ProcessNPCData()
modWP_Events.AllEventData = {}
--	ReturnOfTux.droid file parsed line-by-line into table
modWP_Events.EventFileData = {}
--	table of FDRPG filepaths used for parsing ReturnOfTux.Droids information
modWP_Events.files = {
	events=""
}
--	"struct" of event information
--	for teleport event - special variant of a "label" event
--	- events.dat form
--	--	Level x				-> level number where event occurs
--	--	teleport("29from0")	-> numberA		- "29"
--							-> level_action	- "from"
--							-> numberB		- "0"
--	--	use two out of levelnumber and { numberA, numberB }
--	--	and set teleport = {lvlA, lvlB } values
modWP_Events.eventItem = {
	level = -1,
	trigger = "",					-- ["label"|"teleport"|"change"|"obstacle"|"death"]
	name = "",
	label = "",
	silent = false,
	eventlabel = { teleported = false },				-- or nil if not a label event
	eventdeath = { lvl = -1, dialog=""},				-- or nil if not a death event
	eventchange = { levelexit = -1, levelenter = -1 }, -- or nil if not a change event
	teleport = {lvlA = -1, lvlB = -1 },				-- or nil if not a transport event
	code = {},								  -- all lines between <LuaCode></LuaCode>
	content = {},										  -- raw content of event data
}
-- markers deliniating code in file data
modWP_Events.codemarkstart = "<LuaCode>"
modWP_Events.codemarkend = "</LuaCode>"
--	text for Event presentation/parsing - break up file data into sections
--	id) key, srchPatn) text/pattern to use to find data	extrctPatn) how to extract found data
modWP_Events.EventSection = {
	{ id = "triggerStart", srchPatn = "New event trigger",      extrctPatn="[TEXT]" },
	{ id = "triggerEnd",   srchPatn = "End of trigger",         extrctPatn="[TEXT]" },
	{ id = "atlevel",      srchPatn = "##%s+Level%s+%d+%s+##",  extrctPatn="[%d]+" },
	{ id = "npcdeaths",    srchPatn = "##%s+NPC%s+Deaths%s+##", extrctPatn="[TEXT]" },
}
--	text for Event presentation/parsing - parsing each event section
--	id) key, srchPatn) text/pattern to use to find data	extrctPatn) how to extract found data
modWP_Events.Triggers = {
	{ id = "label",      srchPatn = "Trigger at label=(%b\"\")",  extrctPatn="[MATCH]" },
	{ id = "death",      srchPatn = "Trigger on enemy death",     extrctPatn="[TEXT]"  },
	{ id = "change",     srchPatn = "Trigger changing level",     extrctPatn="[TEXT]"  },
	{ id = "obstacle",   srchPatn = "Trigger on obstacle",        extrctPatn="[TEXT]"  },
	{ id = "name",       srchPatn = "Name=_*(%b\"\")",            extrctPatn="[MATCH]" },
	{ id = "silent",     srchPatn = "Silent=[%d]+",               extrctPatn="[%d]+"   },
	{ id = "teleported", srchPatn = "Teleported=[%d]+",           extrctPatn="[%d]+"   },
	{ id = "obslabel",   srchPatn = "Obstacle label=(%b\"\")",    extrctPatn="[MATCH]" },
	{ id = "enemylvl",   srchPatn = "Enemy level=[%d]+",          extrctPatn="[%d]+"   },
	{ id = "enemydgl",   srchPatn = "Enemy dialog name=(%b\"\")", extrctPatn="[MATCH]" },
	{ id = "chgtolvl",   srchPatn = "Entering level=[%d]+",       extrctPatn="[%d]+"   },
	{ id = "chgfrmlvl",  srchPatn = "Exiting level=[%d]+",        extrctPatn="[%d]+"   },
	{ id = "codeStart",  srchPatn = modWP_Events.codemarkstart,   extrctPatn="[TEXT]"  },
	{ id = "codeEnd",    srchPatn = modWP_Events.codemarkend,     extrctPatn="[TEXT]"  },
}
--	text patterns used to locate teleport code lines
modWP_Events.patternTeleport = { srchPatn = "teleport%((%b\"\")%)", extrctPatn = "[MATCH]" }

--	text patterns used to locate special transport events data in events file
modWP_Events.patterns_teleport = {
	{ id = "value",   srchPatn = "(%d+)(%l+)(%d+)%a?", extrctPatn = "[TEXT]" },
	{ id = "special", srchPatn = "(%d+)(%l+)%u%d+%a?", extrctPatn = "[TEXT]" }
}
--	Parse events.dat
--	Find all Start/End Events copying information to ["contents"] table
function modWP_Events.ParseFile()
	local currentlevel = -1
	local inTrigger = false
	local processed = false
	local section = {}
	local key, line = next(modWP_Events.EventFileData, nil)
	repeat
		local subkey, trigItem = next(modWP_Events.EventSection, nil)
		repeat
			local data = modWP_Events.modcommon.Extract.SearchText( line, trigItem.srchPatn, trigItem.extrctPatn )
			if (( data == nil ) or ( not data )) then goto PARSE_FILE_NEXT_SECTION end
			if ( trigItem.id == "atlevel" ) then
				currentlevel = data
				processed = true
			elseif ( trigItem.id == "npcdeaths" ) then
				currentlevel = -1
				processed = true
			elseif ( trigItem.id == "triggerEnd" ) then
				inTrigger = false
				processed = true
				modWP_Events.AllEventData[#modWP_Events.AllEventData + 1] = section
			elseif ( trigItem.id == "triggerStart" ) then
				inTrigger = true
				processed = true
				section = modWP_Events.modcommon.Extract.TblDeepCopy(modWP_Events.eventItem)
				section.level = currentlevel
			end
::PARSE_FILE_NEXT_SECTION::
			subkey, trigItem = next(modWP_Events.EventSection, subkey)
		until ( subkey == nil )
		if ( not processed and inTrigger ) then
			section.content[#section.content + 1] = line
		end
		processed = false
		key, line = next(modWP_Events.EventFileData, key)
	until ( key == nil )
end

-- Parse ["contents"] table
-- Process each found event's contents for more details about the trigger
function modWP_Events.ParseContents()
	local modC = modWP_Events.modcommon
	local in_code = false
	local key, section = next(modWP_Events.AllEventData, nil)
	repeat
		for subkey, line in pairs(section.content) do
			local dataItem = {}
			if ( in_code ) then
				dataItem = modWP_Events.modcommon.Extract.SearchText( line, modWP_Events.codemarkend, "[TEXT]" )
				if ( dataItem == nil ) then
					section.code[#section.code + 1] = line
				else
					in_code = false
					break
				end
			else
				for sub, trigItem in pairs(modWP_Events.Triggers) do
					dataItem = modWP_Events.modcommon.Extract.SearchText( line, trigItem.srchPatn, trigItem.extrctPatn )
					if (( dataItem == nil ) or ( not dataItem )) then goto PROCESS_EVENT_NEXT_TRIGGER end
					if ( trigItem.id == "obslabel" ) then
						section["label"] = dataItem
						break
					elseif ( trigItem.id == "name" ) then
						section[trigItem.id] = dataItem
						break
					elseif ( trigItem.id == "silent" ) then
						section[trigItem.id] = (dataItem ~= 0)
						break
					elseif ( trigItem.id == "teleported" ) then
						section.eventlabel[trigItem.id] = (dataItem ~= 0)
						break
					elseif ( trigItem.id == "enemylvl" ) then
						-- if ## NPC Deaths ## then level = level_enemy
						section.eventdeath["lvl"] = dataItem
						section.level = section.eventdeath["lvl"]
						break
					elseif ( trigItem.id == "enemydgl" ) then
						section.eventdeath["dialog"] = dataItem
						break
					elseif ( trigItem.id == "chgtolvl" ) then
						section.eventchange["levelenter"] = dataItem
						break
					elseif ( trigItem.id == "chgfrmlvl" ) then
						section.eventchange["levelexit"] = dataItem
						break
					elseif ( trigItem.id == "label" ) then
						section["trigger"] = "label"
						section["label"] = dataItem
						section["eventdeath"] = nil
						section["eventchange"] = nil
						break
					elseif ( trigItem.id == "death" ) then
						section["trigger"] = trigItem.id
						section["label"] = "enemy death"
						section["eventlabel"] = nil
						section["eventchange"] = nil
						section["teleport"] = nil
						break
					elseif ( trigItem.id == "change" ) then
						section["trigger"] = trigItem.id
						section["label"] = "change level"
						section["eventlabel"] = nil
						section["eventdeath"] = nil
						section["teleport"] = nil
						break
					elseif ( trigItem.id == "obstacle" ) then
						section["trigger"] = trigItem.id
						section["label"] = "obstacle"
						section["eventlabel"] = nil
						section["eventdeath"] = nil
						section["eventchange"] = nil
						section["teleport"] = nil
						break
					elseif ( trigItem.id == "codeStart" ) then
						local data = modWP_Events.modcommon.Extract.SearchText(	line, modWP_Events.codemarkend, "[TEXT]" )
						if ( data ~= nil ) then
							in_code = false
							section.code[#section.code + 1] = line:sub((modWP_Events.codemarkstart:len() + 1), (#line - modWP_Events.codemarkend:len()))
						else
							in_code = true
						end
						break
					elseif ( trigItem.id == "codeEnd" ) then
						in_code = false
						break
					end
::PROCESS_EVENT_NEXT_TRIGGER::
				end	--	determine trigger type
			end	--	copy code contents
		end	--	loop through each line of text in section
		modWP_Events.AllEventData[key]["content"] = nil
		key, section = next(modWP_Events.AllEventData, key)
	until ( key == nil )

end

--	Process all label events - mark up those that are "teleport" events
--	(i.e. labels that move character between levels)
--	modWP_Events.AllEventData is populated, processed and ready for usage at end of function
function modWP_Events.ProcessLabelEvents()
	local level_a, level_action, level_b = "","",""
	local key, event = next(modWP_Events.AllEventData, nil)
	local srchTeleport = modWP_Events.patternTeleport
	repeat
		local processed = false
		if ( event.trigger ~= "label" ) then goto PROCESS_NEXT_LABEL_EVENT end
		for subkey, codeline in pairs( event.code ) do
			local isteleport = modWP_Events.modcommon.Extract.SearchText( codeline, srchTeleport.srchPatn, srchTeleport.extrctPatn )
			if (( isteleport == nil ) or ( not isteleport )) then goto PROCESS_NEXT_LABEL_CODELINE end
			event.trigger = "teleport"
			-- have teleport code line
			for subsubkey, pattern in pairs( modWP_Events.patterns_teleport ) do
				local value = modWP_Events.modcommon.Extract.SearchText( codeline, pattern.srchPatn, pattern.extrctPatn )
				if (( value == nil ) or ( not value )) then	goto PROCESS_NEXT_LABEL_TELEPORTPATTERN end
				local numberA, numberB = -1, -1
				level_a, level_action, level_b = value:match( pattern.srchPatn )
				if ( pattern.id == "value" ) then
					numberA = assert(tonumber(level_a))
					numberB = assert(tonumber(level_b))
					-- value b is valid - but is it useful?
					if ( level_action:gsub("%a", string.lower) == "from" ) then
						if ( numberA == event.level ) then
							event.teleport.lvlA = event.level
							event.teleport.lvlB = numberB
						elseif ( numberB == event.level ) then
							event.teleport.lvlA = event.level
							event.teleport.lvlB = numberA
						else
							local errstr = "\"modWP_Events.ProcessLabelEvents\""
										.. " - bad case - values are not numbers\n"
							io.stderr:write(errstr)
						end
						processed = true
					end
				elseif ( pattern.id == "special" ) then
					-- value b is invalid
					event.teleport.lvlA = event.level
					event.teleport.lvlB = assert(tonumber(level_a))
					processed = true
				end
::PROCESS_NEXT_LABEL_TELEPORTPATTERN::
			end
::PROCESS_NEXT_LABEL_CODELINE::
		end
		if ( processed == false ) then
			event["teleport"] = nil
		end
::PROCESS_NEXT_LABEL_EVENT::
	key, event = next(modWP_Events.AllEventData, key)
	until ( key == nil )
end

--	Read in FDRPG ReturnOfTux.droid data file
--	All droid information is saved into lua table.
function modWP_Events.ProcessData()
	modWP_Events.modcommon = require("modWPCommon")
	--	test for presence of source data files
	modWP_Events.files.events = tostring(modWP_Events.modcommon.paths.srcData .. modWP_Events.modcommon.datafiles["events"])
	modWP_Events.modcommon.Test.Files(modWP_Events.files)
	-- read file and process into table objects
	modWP_Events.EventFileData = modWP_Events.modcommon.Process.FileToLines( modWP_Events.files["events"] )
	modWP_Events.ParseFile()
	modWP_Events.ParseContents()
	modWP_Events.ProcessLabelEvents()
end

--	Print out NPC information based on selected verbosity.
function modWP_Events.Verbosity()
	if ((modWP_Events.modcommon.verbose) or (modWP_Events.modcommon.doubleverbose)) then
		io.stdout:write(modWP_Events.modcommon.VerboseHeader)
		io.stdout:write("modWP_Events\n")
		io.stdout:write("number of Events: " .. #modWP_Events.AllEventData .. "\n")
		io.stdout:write(modWP_Events.modcommon.VerboseHeader)
		if (modWP_Events.modcommon.doubleverbose) then
			modWP_Events.modcommon.Process.TblPrint( modWP_Events.AllEventData, nil, nil, "All Event Data" )
		end
	end
end

return modWP_Events