Compare commits
16 commits
065f03a940
...
d7e721f49a
Author | SHA1 | Date | |
---|---|---|---|
|
d7e721f49a | ||
|
9b1d92449e | ||
|
7a972d4726 | ||
|
3001301a31 | ||
|
8006a7789b | ||
|
e816551eab | ||
|
e9d05ebd30 | ||
|
df05425b8a | ||
|
ee31689f9e | ||
|
83f6cc6ef4 | ||
|
09581b436d | ||
|
3687f5297f | ||
|
5daa5034a2 | ||
|
4f5e789dc3 | ||
|
03f4145270 | ||
|
b342a1ea48 |
20 changed files with 1165 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
build/*.json
|
0
build/.gitkeep
Normal file
0
build/.gitkeep
Normal file
47
classes/beastfile.lua
Normal file
47
classes/beastfile.lua
Normal file
|
@ -0,0 +1,47 @@
|
|||
local BeastFile = Object:extend()
|
||||
local DataList = require "classes.datalist"
|
||||
|
||||
local parseFile = require "libs.filereader"
|
||||
|
||||
function BeastFile:new(folder, name)
|
||||
self.filepath = folder .. "/" .. name
|
||||
print("Loading " .. self.filepath)
|
||||
self.datas = DataList()
|
||||
|
||||
self:readLines()
|
||||
end
|
||||
|
||||
function BeastFile:readLines()
|
||||
self:readAllLines(self.filepath)
|
||||
end
|
||||
|
||||
function BeastFile:readAllLines(path)
|
||||
parseFile(path, function (line) self:addLine(line) end)
|
||||
end
|
||||
|
||||
function BeastFile:addLine(line)
|
||||
if (utils.startswith(line, "mixin;") or utils.startswith(line, "mixins;")) then
|
||||
local mixin = utils.split(line, ";", true)[2]
|
||||
self:loadMixin(mixin)
|
||||
elseif (utils.startswith(line, "type;") or utils.startswith(line, "types;")) then
|
||||
local mixin = utils.split(line, ";", true)[2]
|
||||
self:loadMixin("types/" .. mixin)
|
||||
else
|
||||
self.datas:addLine(line)
|
||||
end
|
||||
end
|
||||
|
||||
function BeastFile:loadMixin(mixin)
|
||||
local testpath = "data/" .. utils.trim(mixin) .. ".beast"
|
||||
if (testpath ~= nil) then
|
||||
self:readAllLines(testpath)
|
||||
end
|
||||
end
|
||||
|
||||
function BeastFile:prepareJson(simplercreatures, creatures, parent)
|
||||
assert(simplercreatures ~= nil)
|
||||
assert(creatures ~= nil)
|
||||
self.datas:prepareJson(simplercreatures, creatures, parent)
|
||||
end
|
||||
|
||||
return BeastFile
|
57
classes/dataholders/competenceholder.lua
Normal file
57
classes/dataholders/competenceholder.lua
Normal file
|
@ -0,0 +1,57 @@
|
|||
local CompetenceHolder = Object:extend()
|
||||
local Competence = Object:extend()
|
||||
|
||||
function Competence:new(name)
|
||||
self.name = name;
|
||||
self.base = 0;
|
||||
self.lvl = 0;
|
||||
self.bonus = 0;
|
||||
self.add = 0;
|
||||
end
|
||||
|
||||
function Competence:reduce(level)
|
||||
return {
|
||||
name = self.name,
|
||||
value = self.base + (self.lvl * level) + self.bonus + self.add
|
||||
}
|
||||
end
|
||||
|
||||
function CompetenceHolder:new(key, datas)
|
||||
self.key = key
|
||||
self.datas = datas
|
||||
self.list = {}
|
||||
end
|
||||
|
||||
function CompetenceHolder:applyCommand(command, args)
|
||||
if (command == "reset") then
|
||||
self.list = {}
|
||||
return
|
||||
end
|
||||
local competence = self:getCompetence(args[1])
|
||||
if (command == "") then
|
||||
competence.base = tonumber(args[2]) or 0
|
||||
elseif (command == "add") then
|
||||
competence.add = tonumber(args[2]) or 0
|
||||
elseif (command == "bonus") then
|
||||
competence.bonus = tonumber(args[2]) or 0
|
||||
elseif (command == "lvl") then
|
||||
competence.lvl = tonumber(args[2]) or 0
|
||||
end
|
||||
end
|
||||
|
||||
function CompetenceHolder:getCompetence(name)
|
||||
if self.list[name] == nil then
|
||||
self.list[name] = Competence(name)
|
||||
end
|
||||
return self.list[name]
|
||||
end
|
||||
|
||||
function CompetenceHolder:reduce(level)
|
||||
local list = {}
|
||||
for key, value in pairs(self.list) do
|
||||
table.insert(list, value:reduce(level))
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
return CompetenceHolder
|
39
classes/dataholders/listholder.lua
Normal file
39
classes/dataholders/listholder.lua
Normal file
|
@ -0,0 +1,39 @@
|
|||
local ListHolder = Object:extend()
|
||||
|
||||
function ListHolder:new(key, datas)
|
||||
self.key = key
|
||||
self.datas = datas
|
||||
self.list = {}
|
||||
end
|
||||
|
||||
function ListHolder:applyCommand(command, args)
|
||||
if (command == "") then
|
||||
self:add(args)
|
||||
elseif (command == "reset") then
|
||||
self:reset()
|
||||
elseif (command == "replace") then
|
||||
self:replace(args)
|
||||
end
|
||||
end
|
||||
|
||||
function ListHolder:reset()
|
||||
self.list = {}
|
||||
end
|
||||
|
||||
function ListHolder:add(datas)
|
||||
table.insert(self.list, datas)
|
||||
end
|
||||
|
||||
function ListHolder:replace(datas)
|
||||
for index, args in ipairs(self.list) do
|
||||
if (args[1] == datas[1]) then
|
||||
self.list[index] = args
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ListHolder:reduce(level)
|
||||
return self.list
|
||||
end
|
||||
|
||||
return ListHolder
|
17
classes/dataholders/simpleholder.lua
Normal file
17
classes/dataholders/simpleholder.lua
Normal file
|
@ -0,0 +1,17 @@
|
|||
local SimpleHolder = Object:extend()
|
||||
|
||||
function SimpleHolder:new(key, datas)
|
||||
self.key = key
|
||||
self.datas = datas
|
||||
self.value = nil
|
||||
end
|
||||
|
||||
function SimpleHolder:applyCommand(command, args)
|
||||
self.value = args
|
||||
end
|
||||
|
||||
function SimpleHolder:reduce(level)
|
||||
return self.value
|
||||
end
|
||||
|
||||
return SimpleHolder
|
17
classes/dataholders/statholder.lua
Normal file
17
classes/dataholders/statholder.lua
Normal file
|
@ -0,0 +1,17 @@
|
|||
local StatHolder = Object:extend()
|
||||
|
||||
function StatHolder:new(key, datas)
|
||||
self.key = key
|
||||
self.datas = datas
|
||||
self.commands = {}
|
||||
end
|
||||
|
||||
function StatHolder:applyCommand(command, args)
|
||||
self.commands[command] = args
|
||||
end
|
||||
|
||||
function StatHolder:reduce(level)
|
||||
return self.commands.base + ((self.commands.lvl or 0) * level) + (self.commands.add or 0) + (self.commands.bonus or 0)
|
||||
end
|
||||
|
||||
return StatHolder
|
109
classes/datalist.lua
Normal file
109
classes/datalist.lua
Normal file
|
@ -0,0 +1,109 @@
|
|||
local RawData = Object:extend()
|
||||
local DataList = Object:extend()
|
||||
|
||||
local ListHolder = require "classes.dataholders.listholder"
|
||||
local SimpleHolder = require "classes.dataholders.simpleholder"
|
||||
local StatHolder = require "classes.dataholders.statholder"
|
||||
local CompetenceHolder = require "classes.dataholders.competenceholder"
|
||||
|
||||
function RawData.fromLine(line)
|
||||
line = utils.removeComment(line)
|
||||
if (#line == 0) then
|
||||
return nil
|
||||
end
|
||||
local command = utils.split(line, "|")
|
||||
local datas = utils.split(utils.trim(command[1]), ";")
|
||||
local args = {}
|
||||
name = utils.trim(datas[1])
|
||||
for i, v in ipairs(datas) do
|
||||
if (i > 1) then
|
||||
local str = utils.trim(v)
|
||||
if ((str ~= nil and str ~= "") or i < #datas) then
|
||||
table.insert(args, str)
|
||||
end
|
||||
end
|
||||
end
|
||||
local level = 0
|
||||
if (command[2] ~= nil) then
|
||||
levelString = utils.trim(command[2]);
|
||||
level = tonumber(levelString) or 0
|
||||
end
|
||||
return RawData(name, commands.clean(args, name), level)
|
||||
end
|
||||
|
||||
function RawData:new(name, arguments, level)
|
||||
self.name = name
|
||||
self.arguments = arguments
|
||||
self.level = level
|
||||
end
|
||||
|
||||
function RawData:canBeUsed(level)
|
||||
return level >= self.level
|
||||
end
|
||||
|
||||
function RawData:getKey()
|
||||
return utils.split(self.name, ".", true)[1]
|
||||
end
|
||||
|
||||
function RawData:getCommand()
|
||||
return utils.split(self.name, ".", true)[2] or ""
|
||||
end
|
||||
|
||||
function DataList.getHolder(key, value)
|
||||
if (value.dataType == "list") then
|
||||
return ListHolder(key, value)
|
||||
elseif (value.dataType == "comp") then
|
||||
return CompetenceHolder(key, value)
|
||||
elseif (value.dataType == "stat") then
|
||||
return StatHolder(key, value)
|
||||
end
|
||||
return SimpleHolder(key, value)
|
||||
end
|
||||
|
||||
function DataList:new()
|
||||
self.list = {}
|
||||
self.holders = {}
|
||||
self.reducedList = {}
|
||||
for key, value in pairs(commands.getDefaults()) do
|
||||
table.insert(self.list, RawData(key, value, 0))
|
||||
end
|
||||
for key, struct in pairs(commands.structs) do
|
||||
self.holders[key] = DataList.getHolder(key, struct)
|
||||
end
|
||||
end
|
||||
|
||||
function DataList:addLine(line)
|
||||
table.insert(self.list, RawData.fromLine(line))
|
||||
end
|
||||
|
||||
function DataList:reduce()
|
||||
local level = 0
|
||||
for _, rawdata in ipairs(self.list) do
|
||||
if (rawdata.name == "level") then
|
||||
level = rawdata.arguments
|
||||
end
|
||||
end
|
||||
|
||||
for _, rawdata in ipairs(self.list) do
|
||||
if (rawdata:canBeUsed(level)) then
|
||||
self.holders[rawdata:getKey()]:applyCommand(rawdata:getCommand(), rawdata.arguments)
|
||||
end
|
||||
end
|
||||
|
||||
for key, holder in pairs(self.holders) do
|
||||
self.reducedList[key] = holder:reduce(level)
|
||||
end
|
||||
|
||||
--TODO
|
||||
end
|
||||
|
||||
function DataList:prepareJson(simplercreatures, creatures, parent)
|
||||
self:reduce()
|
||||
|
||||
self.reducedList.parent = parent
|
||||
|
||||
table.insert(simplercreatures, {nom = self.reducedList.name, level = self.reducedList.level, nomType = self.reducedList.nomType, categorie = self.reducedList.categorie})
|
||||
table.insert(creatures, self.reducedList)
|
||||
end
|
||||
|
||||
return DataList
|
52
classes/folderloader.lua
Normal file
52
classes/folderloader.lua
Normal file
|
@ -0,0 +1,52 @@
|
|||
local FolderLoader = Object:extend()
|
||||
local BeastFile = require "classes.beastfile"
|
||||
|
||||
function FolderLoader.getAllDatas(value, bestiaires, creatures)
|
||||
local folderLoader = FolderLoader(value)
|
||||
folderLoader:getDatas(bestiaires, creatures)
|
||||
end
|
||||
|
||||
function FolderLoader:new(value)
|
||||
self.folder = "data/" .. value.folder
|
||||
|
||||
self.data = {}
|
||||
self.data.nom = value.nom
|
||||
self.data.description = value.description
|
||||
self.data.folder = value.folder
|
||||
self.data.list = {}
|
||||
|
||||
self.files = {}
|
||||
|
||||
for _, filename in ipairs(utils.scandir(self.folder)) do
|
||||
local file = utils.split(filename, ".", true)
|
||||
if (file[2] == "beast") then
|
||||
table.insert(self.files, BeastFile(self.folder, filename))
|
||||
else
|
||||
print("[WARNING] Unknown extension " .. file[2] .. " for " .. filename)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function FolderLoader:prepareJson(simplercreatures, creatures)
|
||||
for _, file in ipairs(self.files) do
|
||||
file:prepareJson(simplercreatures, creatures, self.data.nom)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function FolderLoader:getDatas(bestiaires, creatures)
|
||||
local simplercreatures = {}
|
||||
self:prepareJson(simplercreatures, creatures)
|
||||
|
||||
|
||||
local bestiaire = {
|
||||
nom = self.data.nom,
|
||||
description = self.data.description,
|
||||
folder = self.data.folder,
|
||||
list = simplercreatures
|
||||
}
|
||||
|
||||
table.insert(bestiaires, bestiaire)
|
||||
end
|
||||
|
||||
return FolderLoader
|
3
config.lua
Normal file
3
config.lua
Normal file
|
@ -0,0 +1,3 @@
|
|||
return {
|
||||
{nom = "Animaux", folder = "animaux", description = "Des animaux génériques et communs (ou moins communs)"}
|
||||
}
|
5
data/animaux/loup.beast
Normal file
5
data/animaux/loup.beast
Normal file
|
@ -0,0 +1,5 @@
|
|||
name;Loup
|
||||
atk.base;60
|
||||
competence;morsure
|
||||
competence;griffure
|
||||
competence;dechirement | 10
|
68
libs/classic.lua
Normal file
68
libs/classic.lua
Normal file
|
@ -0,0 +1,68 @@
|
|||
--
|
||||
-- classic
|
||||
--
|
||||
-- Copyright (c) 2014, rxi
|
||||
--
|
||||
-- This module is free software; you can redistribute it and/or modify it under
|
||||
-- the terms of the MIT license. See LICENSE for details.
|
||||
--
|
||||
|
||||
|
||||
local Object = {}
|
||||
Object.__index = Object
|
||||
|
||||
|
||||
function Object:new()
|
||||
end
|
||||
|
||||
|
||||
function Object:extend()
|
||||
local cls = {}
|
||||
for k, v in pairs(self) do
|
||||
if k:find("__") == 1 then
|
||||
cls[k] = v
|
||||
end
|
||||
end
|
||||
cls.__index = cls
|
||||
cls.super = self
|
||||
setmetatable(cls, self)
|
||||
return cls
|
||||
end
|
||||
|
||||
|
||||
function Object:implement(...)
|
||||
for _, cls in pairs({...}) do
|
||||
for k, v in pairs(cls) do
|
||||
if self[k] == nil and type(v) == "function" then
|
||||
self[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Object:is(T)
|
||||
local mt = getmetatable(self)
|
||||
while mt do
|
||||
if mt == T then
|
||||
return true
|
||||
end
|
||||
mt = getmetatable(mt)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function Object:__tostring()
|
||||
return "Object"
|
||||
end
|
||||
|
||||
|
||||
function Object:__call(...)
|
||||
local obj = setmetatable({}, self)
|
||||
obj:new(...)
|
||||
return obj
|
||||
end
|
||||
|
||||
|
||||
return Object
|
71
libs/commands.lua
Normal file
71
libs/commands.lua
Normal file
|
@ -0,0 +1,71 @@
|
|||
local struct = require "struct"
|
||||
local commands = {}
|
||||
local defaults = {}
|
||||
|
||||
local functions = {}
|
||||
|
||||
print("Compilation des commandes")
|
||||
|
||||
local function addCommands(command, parent, default)
|
||||
commands[command] = parent
|
||||
if (default ~= nil) then
|
||||
defaults[command] = default
|
||||
end
|
||||
end
|
||||
|
||||
local function addStatCommands(name, value)
|
||||
addCommands(name .. ".base", name, value.default)
|
||||
addCommands(name .. ".lvl", name, 0)
|
||||
addCommands(name .. ".add", name, 0)
|
||||
addCommands(name .. ".bonus", name, 0)
|
||||
end
|
||||
|
||||
local function addCompCommands(name, value)
|
||||
addCommands(name, name)
|
||||
addCommands(name .. ".reset", name)
|
||||
addCommands(name .. ".lvl", name)
|
||||
addCommands(name .. ".add", name)
|
||||
addCommands(name .. ".bonus", name)
|
||||
end
|
||||
|
||||
local function addListCommands(name, value)
|
||||
addCommands(name, name)
|
||||
addCommands(name .. ".replace", name)
|
||||
addCommands(name .. ".reset", name)
|
||||
end
|
||||
|
||||
for key, value in pairs(struct) do
|
||||
if (value.dataType == "stat") then
|
||||
addStatCommands(key, value)
|
||||
elseif (value.dataType == "list") then
|
||||
addListCommands(key, value)
|
||||
elseif (value.dataType == "comp") then
|
||||
addCompCommands(key, value)
|
||||
else
|
||||
addCommands(key, key, value.default)
|
||||
end
|
||||
end
|
||||
|
||||
function functions.getDefaults()
|
||||
return defaults
|
||||
end
|
||||
|
||||
function functions.clean(args, command)
|
||||
local baseCommand = commands[command]
|
||||
if (baseCommand == nil) then
|
||||
error("Command " .. command .. " doesn't exists")
|
||||
end
|
||||
local commandData = struct[baseCommand]
|
||||
if (commandData.args == nil or commandData.args == 1) then
|
||||
local arg = args[1]
|
||||
if (commandData.contentType == "number") then
|
||||
arg = tonumber(arg)
|
||||
end
|
||||
return arg
|
||||
end
|
||||
return args
|
||||
end
|
||||
|
||||
functions.structs = struct
|
||||
|
||||
return functions
|
34
libs/filereader.lua
Normal file
34
libs/filereader.lua
Normal file
|
@ -0,0 +1,34 @@
|
|||
-- http://lua-users.org/wiki/FileInputOutput
|
||||
|
||||
local utils = require "libs.utils"
|
||||
|
||||
-- see if the file exists
|
||||
local function file_exists(file)
|
||||
local f = io.open(file, "rb")
|
||||
if f then f:close() end
|
||||
return f ~= nil
|
||||
end
|
||||
|
||||
-- get all lines from a file, returns an empty
|
||||
-- list/table if the file does not exist
|
||||
local function lines_from(file)
|
||||
if not file_exists(file) then error(file) end
|
||||
local lines = {}
|
||||
for line in io.lines(file) do
|
||||
lines[#lines + 1] = line
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
local function parseFile(file, func)
|
||||
local lines = lines_from(file)
|
||||
for k,v in pairs(lines) do
|
||||
local line = utils.trim(v)
|
||||
line = utils.trim(utils.split(line, "//", true)[1])
|
||||
if (line ~= "") then
|
||||
func(line)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return parseFile;
|
3
libs/init.lua
Normal file
3
libs/init.lua
Normal file
|
@ -0,0 +1,3 @@
|
|||
utils = require "libs.utils"
|
||||
Object = require "libs.classic"
|
||||
commands = require "libs.commands"
|
388
libs/json.lua
Normal file
388
libs/json.lua
Normal file
|
@ -0,0 +1,388 @@
|
|||
--
|
||||
-- json.lua
|
||||
--
|
||||
-- Copyright (c) 2020 rxi
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
-- this software and associated documentation files (the "Software"), to deal in
|
||||
-- the Software without restriction, including without limitation the rights to
|
||||
-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
-- of the Software, and to permit persons to whom the Software is furnished to do
|
||||
-- so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in all
|
||||
-- copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
-- SOFTWARE.
|
||||
--
|
||||
|
||||
local json = { _version = "0.1.2" }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Encode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local encode
|
||||
|
||||
local escape_char_map = {
|
||||
[ "\\" ] = "\\",
|
||||
[ "\"" ] = "\"",
|
||||
[ "\b" ] = "b",
|
||||
[ "\f" ] = "f",
|
||||
[ "\n" ] = "n",
|
||||
[ "\r" ] = "r",
|
||||
[ "\t" ] = "t",
|
||||
}
|
||||
|
||||
local escape_char_map_inv = { [ "/" ] = "/" }
|
||||
for k, v in pairs(escape_char_map) do
|
||||
escape_char_map_inv[v] = k
|
||||
end
|
||||
|
||||
|
||||
local function escape_char(c)
|
||||
return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte()))
|
||||
end
|
||||
|
||||
|
||||
local function encode_nil(val)
|
||||
return "null"
|
||||
end
|
||||
|
||||
|
||||
local function encode_table(val, stack)
|
||||
local res = {}
|
||||
stack = stack or {}
|
||||
|
||||
-- Circular reference?
|
||||
if stack[val] then error("circular reference") end
|
||||
|
||||
stack[val] = true
|
||||
|
||||
if rawget(val, 1) ~= nil or next(val) == nil then
|
||||
-- Treat as array -- check keys are valid and it is not sparse
|
||||
local n = 0
|
||||
for k in pairs(val) do
|
||||
if type(k) ~= "number" then
|
||||
error("invalid table: mixed or invalid key types")
|
||||
end
|
||||
n = n + 1
|
||||
end
|
||||
if n ~= #val then
|
||||
error("invalid table: sparse array")
|
||||
end
|
||||
-- Encode
|
||||
for i, v in ipairs(val) do
|
||||
table.insert(res, encode(v, stack))
|
||||
end
|
||||
stack[val] = nil
|
||||
return "[" .. table.concat(res, ",") .. "]"
|
||||
|
||||
else
|
||||
-- Treat as an object
|
||||
for k, v in pairs(val) do
|
||||
if type(k) ~= "string" then
|
||||
error("invalid table: mixed or invalid key types")
|
||||
end
|
||||
table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
|
||||
end
|
||||
stack[val] = nil
|
||||
return "{" .. table.concat(res, ",") .. "}"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function encode_string(val)
|
||||
return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
|
||||
end
|
||||
|
||||
|
||||
local function encode_number(val)
|
||||
-- Check for NaN, -inf and inf
|
||||
if val ~= val or val <= -math.huge or val >= math.huge then
|
||||
error("unexpected number value '" .. tostring(val) .. "'")
|
||||
end
|
||||
return string.format("%.14g", val)
|
||||
end
|
||||
|
||||
|
||||
local type_func_map = {
|
||||
[ "nil" ] = encode_nil,
|
||||
[ "table" ] = encode_table,
|
||||
[ "string" ] = encode_string,
|
||||
[ "number" ] = encode_number,
|
||||
[ "boolean" ] = tostring,
|
||||
}
|
||||
|
||||
|
||||
encode = function(val, stack)
|
||||
local t = type(val)
|
||||
local f = type_func_map[t]
|
||||
if f then
|
||||
return f(val, stack)
|
||||
end
|
||||
error("unexpected type '" .. t .. "'")
|
||||
end
|
||||
|
||||
|
||||
function json.encode(val)
|
||||
return ( encode(val) )
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Decode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local parse
|
||||
|
||||
local function create_set(...)
|
||||
local res = {}
|
||||
for i = 1, select("#", ...) do
|
||||
res[ select(i, ...) ] = true
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
local space_chars = create_set(" ", "\t", "\r", "\n")
|
||||
local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",")
|
||||
local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u")
|
||||
local literals = create_set("true", "false", "null")
|
||||
|
||||
local literal_map = {
|
||||
[ "true" ] = true,
|
||||
[ "false" ] = false,
|
||||
[ "null" ] = nil,
|
||||
}
|
||||
|
||||
|
||||
local function next_char(str, idx, set, negate)
|
||||
for i = idx, #str do
|
||||
if set[str:sub(i, i)] ~= negate then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return #str + 1
|
||||
end
|
||||
|
||||
|
||||
local function decode_error(str, idx, msg)
|
||||
local line_count = 1
|
||||
local col_count = 1
|
||||
for i = 1, idx - 1 do
|
||||
col_count = col_count + 1
|
||||
if str:sub(i, i) == "\n" then
|
||||
line_count = line_count + 1
|
||||
col_count = 1
|
||||
end
|
||||
end
|
||||
error( string.format("%s at line %d col %d", msg, line_count, col_count) )
|
||||
end
|
||||
|
||||
|
||||
local function codepoint_to_utf8(n)
|
||||
-- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
|
||||
local f = math.floor
|
||||
if n <= 0x7f then
|
||||
return string.char(n)
|
||||
elseif n <= 0x7ff then
|
||||
return string.char(f(n / 64) + 192, n % 64 + 128)
|
||||
elseif n <= 0xffff then
|
||||
return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128)
|
||||
elseif n <= 0x10ffff then
|
||||
return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128,
|
||||
f(n % 4096 / 64) + 128, n % 64 + 128)
|
||||
end
|
||||
error( string.format("invalid unicode codepoint '%x'", n) )
|
||||
end
|
||||
|
||||
|
||||
local function parse_unicode_escape(s)
|
||||
local n1 = tonumber( s:sub(1, 4), 16 )
|
||||
local n2 = tonumber( s:sub(7, 10), 16 )
|
||||
-- Surrogate pair?
|
||||
if n2 then
|
||||
return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
|
||||
else
|
||||
return codepoint_to_utf8(n1)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function parse_string(str, i)
|
||||
local res = ""
|
||||
local j = i + 1
|
||||
local k = j
|
||||
|
||||
while j <= #str do
|
||||
local x = str:byte(j)
|
||||
|
||||
if x < 32 then
|
||||
decode_error(str, j, "control character in string")
|
||||
|
||||
elseif x == 92 then -- `\`: Escape
|
||||
res = res .. str:sub(k, j - 1)
|
||||
j = j + 1
|
||||
local c = str:sub(j, j)
|
||||
if c == "u" then
|
||||
local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1)
|
||||
or str:match("^%x%x%x%x", j + 1)
|
||||
or decode_error(str, j - 1, "invalid unicode escape in string")
|
||||
res = res .. parse_unicode_escape(hex)
|
||||
j = j + #hex
|
||||
else
|
||||
if not escape_chars[c] then
|
||||
decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string")
|
||||
end
|
||||
res = res .. escape_char_map_inv[c]
|
||||
end
|
||||
k = j + 1
|
||||
|
||||
elseif x == 34 then -- `"`: End of string
|
||||
res = res .. str:sub(k, j - 1)
|
||||
return res, j + 1
|
||||
end
|
||||
|
||||
j = j + 1
|
||||
end
|
||||
|
||||
decode_error(str, i, "expected closing quote for string")
|
||||
end
|
||||
|
||||
|
||||
local function parse_number(str, i)
|
||||
local x = next_char(str, i, delim_chars)
|
||||
local s = str:sub(i, x - 1)
|
||||
local n = tonumber(s)
|
||||
if not n then
|
||||
decode_error(str, i, "invalid number '" .. s .. "'")
|
||||
end
|
||||
return n, x
|
||||
end
|
||||
|
||||
|
||||
local function parse_literal(str, i)
|
||||
local x = next_char(str, i, delim_chars)
|
||||
local word = str:sub(i, x - 1)
|
||||
if not literals[word] then
|
||||
decode_error(str, i, "invalid literal '" .. word .. "'")
|
||||
end
|
||||
return literal_map[word], x
|
||||
end
|
||||
|
||||
|
||||
local function parse_array(str, i)
|
||||
local res = {}
|
||||
local n = 1
|
||||
i = i + 1
|
||||
while 1 do
|
||||
local x
|
||||
i = next_char(str, i, space_chars, true)
|
||||
-- Empty / end of array?
|
||||
if str:sub(i, i) == "]" then
|
||||
i = i + 1
|
||||
break
|
||||
end
|
||||
-- Read token
|
||||
x, i = parse(str, i)
|
||||
res[n] = x
|
||||
n = n + 1
|
||||
-- Next token
|
||||
i = next_char(str, i, space_chars, true)
|
||||
local chr = str:sub(i, i)
|
||||
i = i + 1
|
||||
if chr == "]" then break end
|
||||
if chr ~= "," then decode_error(str, i, "expected ']' or ','") end
|
||||
end
|
||||
return res, i
|
||||
end
|
||||
|
||||
|
||||
local function parse_object(str, i)
|
||||
local res = {}
|
||||
i = i + 1
|
||||
while 1 do
|
||||
local key, val
|
||||
i = next_char(str, i, space_chars, true)
|
||||
-- Empty / end of object?
|
||||
if str:sub(i, i) == "}" then
|
||||
i = i + 1
|
||||
break
|
||||
end
|
||||
-- Read key
|
||||
if str:sub(i, i) ~= '"' then
|
||||
decode_error(str, i, "expected string for key")
|
||||
end
|
||||
key, i = parse(str, i)
|
||||
-- Read ':' delimiter
|
||||
i = next_char(str, i, space_chars, true)
|
||||
if str:sub(i, i) ~= ":" then
|
||||
decode_error(str, i, "expected ':' after key")
|
||||
end
|
||||
i = next_char(str, i + 1, space_chars, true)
|
||||
-- Read value
|
||||
val, i = parse(str, i)
|
||||
-- Set
|
||||
res[key] = val
|
||||
-- Next token
|
||||
i = next_char(str, i, space_chars, true)
|
||||
local chr = str:sub(i, i)
|
||||
i = i + 1
|
||||
if chr == "}" then break end
|
||||
if chr ~= "," then decode_error(str, i, "expected '}' or ','") end
|
||||
end
|
||||
return res, i
|
||||
end
|
||||
|
||||
|
||||
local char_func_map = {
|
||||
[ '"' ] = parse_string,
|
||||
[ "0" ] = parse_number,
|
||||
[ "1" ] = parse_number,
|
||||
[ "2" ] = parse_number,
|
||||
[ "3" ] = parse_number,
|
||||
[ "4" ] = parse_number,
|
||||
[ "5" ] = parse_number,
|
||||
[ "6" ] = parse_number,
|
||||
[ "7" ] = parse_number,
|
||||
[ "8" ] = parse_number,
|
||||
[ "9" ] = parse_number,
|
||||
[ "-" ] = parse_number,
|
||||
[ "t" ] = parse_literal,
|
||||
[ "f" ] = parse_literal,
|
||||
[ "n" ] = parse_literal,
|
||||
[ "[" ] = parse_array,
|
||||
[ "{" ] = parse_object,
|
||||
}
|
||||
|
||||
|
||||
parse = function(str, idx)
|
||||
local chr = str:sub(idx, idx)
|
||||
local f = char_func_map[chr]
|
||||
if f then
|
||||
return f(str, idx)
|
||||
end
|
||||
decode_error(str, idx, "unexpected character '" .. chr .. "'")
|
||||
end
|
||||
|
||||
|
||||
function json.decode(str)
|
||||
if type(str) ~= "string" then
|
||||
error("expected argument of type string, got " .. type(str))
|
||||
end
|
||||
local res, idx = parse(str, next_char(str, 1, space_chars, true))
|
||||
idx = next_char(str, idx, space_chars, true)
|
||||
if idx <= #str then
|
||||
decode_error(str, idx, "trailing garbage")
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
|
||||
return json
|
127
libs/split.lua
Normal file
127
libs/split.lua
Normal file
|
@ -0,0 +1,127 @@
|
|||
------------------------------------------------------------------
|
||||
--
|
||||
-- Author: Alexey Melnichuk <alexeymelnichuck@gmail.com>
|
||||
--
|
||||
-- Copyright (C) 2016 Alexey Melnichuk <alexeymelnichuck@gmail.com>
|
||||
--
|
||||
-- Licensed according to the included 'LICENSE' document
|
||||
--
|
||||
-- This file is part of lua-split library.
|
||||
--
|
||||
------------------------------------------------------------------
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- split = require "split"
|
||||
-- lines = split(str, '\r?\n')
|
||||
-- key, val = split.first(str, '=', true)
|
||||
-- a,b,c,d = split.unpack(str, ':', true)
|
||||
|
||||
local unpack = unpack or table.unpack
|
||||
|
||||
local function is_match_empty(pat, plain)
|
||||
return not not string.find('', pat, nil, plain)
|
||||
end
|
||||
|
||||
local function split(str, sep, plain)
|
||||
local b, res = 0, {}
|
||||
sep = sep or '%s+'
|
||||
|
||||
assert(type(sep) == 'string')
|
||||
assert(type(str) == 'string')
|
||||
|
||||
if #sep == 0 then
|
||||
for i = 1, #str do
|
||||
res[#res + 1] = string.sub(str, i, i)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
assert(not is_match_empty(sep, plain), 'delimiter can not match empty string')
|
||||
|
||||
while b <= #str do
|
||||
local e, e2 = string.find(str, sep, b, plain)
|
||||
if e then
|
||||
res[#res + 1] = string.sub(str, b, e-1)
|
||||
b = e2 + 1
|
||||
if b > #str then res[#res + 1] = "" end
|
||||
else
|
||||
res[#res + 1] = string.sub(str, b)
|
||||
break
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
local function split_iter(str, sep, plain)
|
||||
sep = sep or '%s+'
|
||||
|
||||
assert(type(sep) == 'string')
|
||||
assert(type(str) == 'string')
|
||||
|
||||
if #sep == 0 then
|
||||
local i = 0
|
||||
return function()
|
||||
i = i + 1
|
||||
if i > #str then return end
|
||||
return (string.sub(str, i, i))
|
||||
end
|
||||
end
|
||||
|
||||
assert(not is_match_empty(sep, plain), 'delimiter can not match empty string')
|
||||
|
||||
local b, eol = 0
|
||||
return function()
|
||||
if b > #str then
|
||||
if eol then
|
||||
eol = nil
|
||||
return ""
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local e, e2 = string.find(str, sep, b, plain)
|
||||
if e then
|
||||
local s = string.sub(str, b, e-1)
|
||||
b = e2 + 1
|
||||
if b > #str then eol = true end
|
||||
return s
|
||||
end
|
||||
|
||||
local s = string.sub(str, b)
|
||||
b = #str + 1
|
||||
return s
|
||||
end
|
||||
end
|
||||
|
||||
local function usplit(...) return unpack(split(...)) end
|
||||
|
||||
local function split_first(str, sep, plain)
|
||||
sep = sep or '%s+'
|
||||
|
||||
assert(type(sep) == 'string')
|
||||
assert(type(str) == 'string')
|
||||
|
||||
if #sep == 0 then
|
||||
return string.sub(str, 1, 1), string.sub(str, 2)
|
||||
end
|
||||
|
||||
assert(not is_match_empty(sep, plain), 'delimiter can not match empty string')
|
||||
|
||||
local e, e2 = string.find(str, sep, nil, plain)
|
||||
if e then
|
||||
return string.sub(str, 1, e - 1), string.sub(str, e2 + 1)
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
return setmetatable({
|
||||
split = split;
|
||||
unpack = usplit;
|
||||
first = split_first;
|
||||
each = split_iter;
|
||||
},{
|
||||
__call = function(_, ...)
|
||||
return split(...)
|
||||
end
|
||||
})
|
69
libs/utils.lua
Normal file
69
libs/utils.lua
Normal file
|
@ -0,0 +1,69 @@
|
|||
local utils = {}
|
||||
|
||||
utils.split = require "libs.split"
|
||||
|
||||
function utils.trim(s)
|
||||
return s:match "^%s*(.-)%s*$"
|
||||
end
|
||||
|
||||
function utils.startswith(string, start)
|
||||
return string:sub(1, #start) == start
|
||||
end
|
||||
|
||||
function utils.endswith(string, ending)
|
||||
return ending == "" or string:sub(-#ending) == ending
|
||||
end
|
||||
|
||||
function utils.removeComment(line)
|
||||
return utils.trim(utils.split(utils.trim(line), '/', true)[1])
|
||||
end
|
||||
|
||||
function utils.scandir(directory)
|
||||
local i, t, popen = 0, {}, io.popen
|
||||
local pfile = popen('ls -a "'..directory..'"')
|
||||
for filename in pfile:lines() do
|
||||
if (filename ~= "." and filename ~= "..") then
|
||||
i = i + 1
|
||||
t[i] = filename
|
||||
end
|
||||
end
|
||||
pfile:close()
|
||||
return t
|
||||
end
|
||||
|
||||
function utils.contains(list, value)
|
||||
if list == nil then
|
||||
return false
|
||||
end
|
||||
for _, listValue in pairs(list) do
|
||||
if (listValue == value) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function utils.size(tableToTest)
|
||||
if (tableToTest == nil) then
|
||||
return 0
|
||||
end
|
||||
return #tableToTest
|
||||
end
|
||||
|
||||
function utils.slitWithoutWhiteSpace(str, sep, plain)
|
||||
local strs = utils.split(str, sep, plain)
|
||||
local strsWithoutWhitespace = {}
|
||||
|
||||
for key, value in pairs(strs) do
|
||||
table.insert(strsWithoutWhitespace, utils.trim(value))
|
||||
end
|
||||
|
||||
return strsWithoutWhitespace
|
||||
end
|
||||
|
||||
function utils.fileExists(name)
|
||||
local f=io.open(name,"r")
|
||||
if f~=nil then io.close(f) return true else return false end
|
||||
end
|
||||
|
||||
return utils
|
29
main.lua
Normal file
29
main.lua
Normal file
|
@ -0,0 +1,29 @@
|
|||
require "libs"
|
||||
local config = require "config"
|
||||
local FolderLoader = require "classes.folderloader"
|
||||
|
||||
local json = require "libs.json"
|
||||
|
||||
print("Début de génération des fichiers .json")
|
||||
clock = os.clock()
|
||||
|
||||
local bestiaires = {}
|
||||
local creatures = {}
|
||||
|
||||
for _, value in ipairs(config) do
|
||||
print("Charagement de la catégorie " .. value.nom)
|
||||
FolderLoader.getAllDatas(value, bestiaires, creatures)
|
||||
end
|
||||
|
||||
local file = io.open("build/bestiaires.json", "w")
|
||||
if (file ~= nil) then
|
||||
file:write(json.encode(bestiaires))
|
||||
end
|
||||
|
||||
local file2 = io.open("build/creatures.json", "w")
|
||||
if (file2 ~= nil) then
|
||||
file2:write(json.encode(creatures))
|
||||
end
|
||||
|
||||
clock = os.clock() - clock
|
||||
print("Génération du fichier .json en " .. clock .. " seconds")
|
29
struct.lua
Normal file
29
struct.lua
Normal file
|
@ -0,0 +1,29 @@
|
|||
return {
|
||||
name={contentType = "string", preParse = true},
|
||||
nomType={contentType = "string"},
|
||||
categorie={contentType = "string"},
|
||||
faiblesses={contentType = "string"},
|
||||
resistences={contentType = "string"},
|
||||
immunites={contentType = "string"},
|
||||
level={contentType = "number", default = 0, preParse = true},
|
||||
atk= {dataType= "stat", modulo= 5, default= 50, max=255, min=10},
|
||||
con= {dataType= "stat", modulo= 5, default= 50, max=255, min=10},
|
||||
hab= {dataType= "stat", modulo= 5, default= 50, max=255, min=10},
|
||||
int= {dataType= "stat", modulo= 5, default= 50, max=255, min=10},
|
||||
sag= {dataType= "stat", modulo= 5, default= 50, max=255, min=10},
|
||||
vol= {dataType= "stat", modulo= 5, default= 50, max=255, min=10},
|
||||
cha= {dataType= "stat", modulo= 5, default= 50, max=255, min=10},
|
||||
dis= {dataType= "stat", modulo= 5, default= 50, max=255, min=10},
|
||||
rel= {dataType= "stat", modulo= 5, default= 50, max=255, min=10},
|
||||
per= {dataType= "stat", modulo= 5, default= 50, max=255, min=10},
|
||||
pv= {dataType= "stat", modulo= 1, default= 12, max=9999999, min=1},
|
||||
pe= {dataType= "stat", modulo= 1, default= 12, max=9999999, min=1},
|
||||
eclat= {dataType= "stat", modulo= 1, default= 10, max=200, min=1},
|
||||
armurephy= {dataType= "stat", modulo= 1, default= 0, max=9999999, min=0},
|
||||
armurepsy= {dataType= "stat", modulo= 1, default= 0, max=9999999, min=0},
|
||||
armurespe= {dataType= "stat", modulo= 1, default= 0, max=9999999, min=0},
|
||||
armes= {dataType= "list", args=2},
|
||||
competence= {dataType= "comp", args=3}, -- on va le gérer différemment comme du code lol sinon c'est trop relou
|
||||
skill= {dataType= "list", args=2}, -- on va le gérer différemment comme du code lol sinon c'est trop relou
|
||||
armes= {dataType= "list", args=1},
|
||||
}
|
Loading…
Reference in a new issue