Compare commits
6 commits
Author | SHA1 | Date | |
---|---|---|---|
|
5cf1a8fcfc | ||
|
ed6e1e6a47 | ||
|
5e8d7a19e1 | ||
|
fcea7f2e4b | ||
|
7deebcf64c | ||
|
b1b481536e |
117 changed files with 2509 additions and 428 deletions
|
@ -21,7 +21,7 @@ steps:
|
|||
settings:
|
||||
hosts:
|
||||
from_secret: deploy_host
|
||||
target: /var/www/next.erratum.kazhnuz.space
|
||||
target: /var/www/erratum.kazhnuz.space
|
||||
source: _site/*
|
||||
user:
|
||||
from_secret: deploy_user
|
||||
|
|
1
_data/bestiaires.json
Normal file
1
_data/bestiaires.json
Normal file
|
@ -0,0 +1 @@
|
|||
[{"folder":"animaux","list":[{"type":"bête","nom":"Belier","categorie":"biologique","level":0,"rang":"E"},{"type":"bête","nom":"Chien","categorie":"biologique","level":0,"rang":"E"},{"type":"bête","nom":"Petit Chien","categorie":"biologique","level":0,"rang":"E"},{"type":"bête","nom":"Loup","categorie":"biologique","level":2,"rang":"C"},{"type":"bête","nom":"Chef-Loup","categorie":"biologique","level":3,"rang":"B"},{"type":"bête","nom":"Loup Géant","categorie":"biologique","level":4,"rang":"A"},{"type":"bête","nom":"Cheval","categorie":"biologique","level":2,"rang":"C"},{"type":"bête","nom":"Chèvre","categorie":"biologique","level":0,"rang":"E"},{"type":"bête","nom":"Chat","categorie":"biologique","level":0,"rang":"E"},{"type":"bête","nom":"Lynx","categorie":"biologique","level":1,"rang":"D"},{"type":"bête","nom":"Fauve","categorie":"biologique","level":3,"rang":"B"},{"type":"bête","nom":"Lion géant","categorie":"biologique","level":4,"rang":"A"},{"type":"bête","nom":"Ours","categorie":"biologique","level":3,"rang":"B"},{"type":"bête","nom":"Rat","categorie":"biologique","level":0,"rang":"E"},{"type":"aerien","nom":"Chauve souris","categorie":"biologique","level":1,"rang":"D"},{"type":"bête","nom":"Gros rat","categorie":"biologique","level":1,"rang":"D"},{"type":"bête","nom":"Nuée de rats","categorie":"biologique","level":1,"rang":"D"},{"type":"aerien","nom":"Nuée de chauve souris","categorie":"biologique","level":1,"rang":"D"},{"type":"bête","nom":"Rat pestiféré","categorie":"biologique","level":1,"rang":"D"},{"type":"bête","nom":"Rat géant","categorie":"biologique","level":2,"rang":"C"},{"type":"aerien","nom":"Chauve souris vampire","categorie":"biologique","level":2,"rang":"C"},{"type":"bête","nom":"Rat géant pestiféré","categorie":"biologique","level":3,"rang":"B"},{"type":"bête","nom":"Nuée de rats pestiféré","categorie":"biologique","level":3,"rang":"B"},{"type":"aerien","nom":"Nuée de chauve souris vampire","categorie":"biologique","level":3,"rang":"B"},{"type":"bête","nom":"Renard","categorie":"biologique","level":1,"rang":"D"},{"type":"bête","nom":"Vache","categorie":"biologique","level":2,"rang":"C"}],"description":"Des animaux génériques et communs (ou moins communs)","nom":"Animaux"},{"folder":"demons","list":[{"type":"bête","nom":"Chihuahua infernal","categorie":"biologique","level":2,"rang":"C"},{"type":"bête","nom":"Chien des enfers","categorie":"biologique","level":2,"rang":"C"},{"type":"bête","nom":"Loup des enfers","categorie":"biologique","level":3,"rang":"B"},{"type":"bête","nom":"Chef-Loup des enfers","categorie":"biologique","level":4,"rang":"A"},{"type":"bête","nom":"Loup du pandémonium","categorie":"biologique","level":5,"rang":"S"}],"description":"Créatures des enfers et satanistes","nom":"Démons et enfer"}]
|
1
_data/creatures.json
Normal file
1
_data/creatures.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -2,7 +2,7 @@
|
|||
layout: layouts/parent.njk
|
||||
---
|
||||
<div id="core">
|
||||
<main id="skip" class="visible">
|
||||
<main id="skip">
|
||||
<div>
|
||||
{{ content | safe }}
|
||||
</div>
|
||||
|
@ -18,7 +18,7 @@ layout: layouts/parent.njk
|
|||
</div>
|
||||
{%- endif -%}
|
||||
|
||||
<div class="card" id="sommaire">
|
||||
<div class="card">
|
||||
<h2>Sommaire</h2>
|
||||
{{ content | toc | safe }}
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
layout: layouts/parent.njk
|
||||
---
|
||||
<div id="core">
|
||||
<main id="skip" class="visible">
|
||||
<main id="skip">
|
||||
<div>
|
||||
{{ content | safe }}
|
||||
</div>
|
||||
|
@ -18,7 +18,7 @@ layout: layouts/parent.njk
|
|||
</div>
|
||||
{%- endif -%}
|
||||
|
||||
<div class="card" id="sommaire">
|
||||
<div class="card">
|
||||
<h2>Sommaire</h2>
|
||||
{{ content | toc | safe }}
|
||||
</div>
|
||||
|
|
|
@ -31,11 +31,13 @@
|
|||
<nav>
|
||||
<h2 class="visually-hidden">Top level navigation menu</h2>
|
||||
<ul class="nav">
|
||||
<li class="nav-item"><a href="/">Accueil</a></li>
|
||||
<li class="nav-item"><a href="/about/">À propos</a></li>
|
||||
<li class="nav-item"><a href="/tl-dr/">TL; DR</a></li>
|
||||
</ul>
|
||||
<ul class="nav">
|
||||
<li class="nav-item"><a href="/fiches/">Fiches</a></li>
|
||||
<li class="nav-item"><a href="https://git.kobold.cafe/univers/erratum">Code Source</a></li>
|
||||
<li class="nav-item"><a href="/fiches/">Fiches téléchargeables</a></li>
|
||||
<li class="nav-item"><a href="https://git.kobold.cafe/univers/erratum">Code Source</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
@ -54,9 +56,6 @@
|
|||
|
||||
<!-- Current page: {{ page.url | htmlBaseUrl }} -->
|
||||
|
||||
<div class="mobile-buttons"><button id="menu-button">Menu</button><button id="sommaire-button">Sommaire</button></div>
|
||||
<script src="/js/mobile-sidebar.js"></script>
|
||||
|
||||
<script>
|
||||
const myTable = document.querySelector("#dataTable table");
|
||||
|
||||
|
|
1
bestiaire/.gitignore
vendored
Normal file
1
bestiaire/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
build/*.json
|
57
bestiaire/classes/beastfile.lua
Normal file
57
bestiaire/classes/beastfile.lua
Normal file
|
@ -0,0 +1,57 @@
|
|||
local BeastFile = Object:extend()
|
||||
local DataList = require "classes.datalist"
|
||||
|
||||
local parseFile = require "libs.filereader"
|
||||
|
||||
function BeastFile:new(folder, name, forceLevel)
|
||||
self.filepath = folder .. "/" .. name
|
||||
print("Loading " .. self.filepath)
|
||||
self.datas = DataList(forceLevel)
|
||||
|
||||
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:forceName(name)
|
||||
self.datas:forceName(name)
|
||||
end
|
||||
|
||||
function BeastFile:prepareJson(simplercreatures, creatures, parent)
|
||||
assert(simplercreatures ~= nil)
|
||||
assert(creatures ~= nil)
|
||||
self.datas:prepareJson(simplercreatures, creatures, parent)
|
||||
end
|
||||
|
||||
function BeastFile:getRawData()
|
||||
local content = {}
|
||||
self.datas:prepareJson({}, content, "Nothing")
|
||||
return content[1]
|
||||
end
|
||||
|
||||
return BeastFile
|
46
bestiaire/classes/dataholders/armesholder.lua
Normal file
46
bestiaire/classes/dataholders/armesholder.lua
Normal file
|
@ -0,0 +1,46 @@
|
|||
local ArmesHolder = Object:extend()
|
||||
|
||||
local function applyBoost(level, mode, value)
|
||||
return math.floor(value * boosts.getBoost(level, mode))
|
||||
end
|
||||
|
||||
function ArmesHolder:new(key, datas)
|
||||
self.key = key
|
||||
self.datas = datas
|
||||
self.list = {}
|
||||
end
|
||||
|
||||
function ArmesHolder: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 ArmesHolder:reset()
|
||||
self.list = {}
|
||||
end
|
||||
|
||||
function ArmesHolder:add(datas)
|
||||
table.insert(self.list, {nom = datas[1], force = tonumber(datas[2]) or "0"})
|
||||
end
|
||||
|
||||
function ArmesHolder:replace(datas)
|
||||
for index, args in ipairs(self.list) do
|
||||
if (args.nom == datas[1]) then
|
||||
self.list[index] = {nom = datas[1], force = tonumber(datas[2] or "0")}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ArmesHolder:reduce(level, mode)
|
||||
for key, value in pairs(self.list) do
|
||||
value.force = applyBoost(level, mode, value.force)
|
||||
end
|
||||
return self.list
|
||||
end
|
||||
|
||||
return ArmesHolder
|
28
bestiaire/classes/dataholders/armureholder.lua
Normal file
28
bestiaire/classes/dataholders/armureholder.lua
Normal file
|
@ -0,0 +1,28 @@
|
|||
local ArmureHolder = Object:extend()
|
||||
|
||||
function ArmureHolder:new(key, datas)
|
||||
self.key = key
|
||||
self.datas = datas
|
||||
self.commands = {}
|
||||
end
|
||||
|
||||
function ArmureHolder:applyCommand(command, args)
|
||||
self.commands[command] = args
|
||||
end
|
||||
|
||||
function ArmureHolder:reduce(level, mode)
|
||||
local stat = self:getBase(level, mode) + ((self.commands.lvl or 0) * level) + (self.commands.add or 0) + (self.commands.bonus or 0)
|
||||
local modulo = commands.structs[self.key].modulo or 1
|
||||
datas = commands.structs[self.key]
|
||||
stat = math.floor(stat / modulo) * modulo
|
||||
stat = math.min(stat, datas.max or 999999)
|
||||
stat = math.max(stat, datas.min or -99999)
|
||||
|
||||
return stat
|
||||
end
|
||||
|
||||
function ArmureHolder:getBase(level, mode)
|
||||
return math.floor(self.commands.base * boosts.getBoost(level, mode))
|
||||
end
|
||||
|
||||
return ArmureHolder
|
31
bestiaire/classes/dataholders/boostholder.lua
Normal file
31
bestiaire/classes/dataholders/boostholder.lua
Normal file
|
@ -0,0 +1,31 @@
|
|||
local BoostHolder = Object:extend()
|
||||
|
||||
function BoostHolder:new(list)
|
||||
self.parent = list
|
||||
self.table = {}
|
||||
end
|
||||
|
||||
function BoostHolder:add(name, val)
|
||||
if (self.table[name] == nil) then
|
||||
self.table[name] = val
|
||||
else
|
||||
self.table[name] = self.table[name] + val
|
||||
end
|
||||
end
|
||||
|
||||
function BoostHolder:getValue(name, val)
|
||||
if (name == "pv" or name == "pe") then
|
||||
return val * 3
|
||||
else
|
||||
return val * 5
|
||||
end
|
||||
end
|
||||
|
||||
function BoostHolder:apply()
|
||||
for key, value in pairs(self.table) do
|
||||
-- TODO : a changer entièrement
|
||||
self.parent:addToHolder(key, "lvl", self:getValue(key, value * 2))
|
||||
end
|
||||
end
|
||||
|
||||
return BoostHolder
|
59
bestiaire/classes/dataholders/competenceholder.lua
Normal file
59
bestiaire/classes/dataholders/competenceholder.lua
Normal file
|
@ -0,0 +1,59 @@
|
|||
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)
|
||||
local baseValue = self.base + (self.lvl * level) + self.bonus + self.add
|
||||
|
||||
return {
|
||||
name = self.name,
|
||||
value = math.floor(baseValue / 5) * 5
|
||||
}
|
||||
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
bestiaire/classes/dataholders/listholder.lua
Normal file
39
bestiaire/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] = datas
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ListHolder:reduce(level)
|
||||
return self.list
|
||||
end
|
||||
|
||||
return ListHolder
|
17
bestiaire/classes/dataholders/simpleholder.lua
Normal file
17
bestiaire/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
|
23
bestiaire/classes/dataholders/statholder.lua
Normal file
23
bestiaire/classes/dataholders/statholder.lua
Normal file
|
@ -0,0 +1,23 @@
|
|||
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, mode)
|
||||
local stat = self.commands.base + ((self.commands.lvl or 0) * level) + (self.commands.add or 0) + (self.commands.bonus or 0)
|
||||
local modulo = commands.structs[self.key].modulo or 1
|
||||
datas = commands.structs[self.key]
|
||||
stat = math.floor(stat / modulo) * modulo
|
||||
stat = math.min(stat, datas.max or 999999)
|
||||
stat = math.max(stat, datas.min or -99999)
|
||||
return stat
|
||||
end
|
||||
|
||||
return StatHolder
|
20
bestiaire/classes/dataholders/vitaholder.lua
Normal file
20
bestiaire/classes/dataholders/vitaholder.lua
Normal file
|
@ -0,0 +1,20 @@
|
|||
local VitaHolder = Object:extend()
|
||||
|
||||
function VitaHolder:new(key, datas)
|
||||
self.key = key
|
||||
self.datas = datas
|
||||
self.commands = {}
|
||||
end
|
||||
|
||||
function VitaHolder:applyCommand(command, args)
|
||||
self.commands[command] = args
|
||||
end
|
||||
|
||||
function VitaHolder:reduce(level, mode)
|
||||
local stat = (self.commands.base + (self.commands.add or 0))
|
||||
stat = stat * (level+1)
|
||||
stat = stat + (self.commands.bonus or 0)
|
||||
return math.floor(stat)
|
||||
end
|
||||
|
||||
return VitaHolder
|
180
bestiaire/classes/datalist.lua
Normal file
180
bestiaire/classes/datalist.lua
Normal file
|
@ -0,0 +1,180 @@
|
|||
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"
|
||||
local ArmesHolder = require "classes.dataholders.armesholder"
|
||||
local ArmureHolder = require "classes.dataholders.armureholder"
|
||||
local VitaHolder = require "classes.dataholders.vitaholder"
|
||||
|
||||
local BoostHolder = require "classes.dataholders.boostholder"
|
||||
|
||||
local rank = require "levels.ranks"
|
||||
|
||||
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)
|
||||
elseif (value.dataType == "armure") then
|
||||
return ArmureHolder(key, value)
|
||||
elseif (value.dataType == "armes") then
|
||||
return ArmesHolder(key, value)
|
||||
elseif (value.dataType == "vita") then
|
||||
return VitaHolder(key, value)
|
||||
end
|
||||
return SimpleHolder(key, value)
|
||||
end
|
||||
|
||||
function DataList:new(forceLevel)
|
||||
self.forcedLevel = forceLevel
|
||||
self.forcedName = nil
|
||||
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
|
||||
|
||||
self.boosts = BoostHolder(self)
|
||||
end
|
||||
|
||||
function DataList:addLine(line)
|
||||
table.insert(self.list, RawData.fromLine(line))
|
||||
end
|
||||
|
||||
function DataList:forceName(name)
|
||||
self.forcedName = name
|
||||
end
|
||||
|
||||
function DataList:addToHolder(key, command, arguments)
|
||||
self.holders[key]:applyCommand(command, arguments)
|
||||
end
|
||||
|
||||
function DataList:reduce()
|
||||
local level = 0
|
||||
local mode = "creature"
|
||||
for _, rawdata in ipairs(self.list) do
|
||||
if (rawdata.name == "level") then
|
||||
level = rawdata.arguments
|
||||
end
|
||||
if (rawdata.name == "mode") then
|
||||
mode = rawdata.arguments
|
||||
end
|
||||
if (rawdata.name == "boost") then
|
||||
self.boosts:add(rawdata.arguments[1], rawdata.arguments[2])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if (self.forcedLevel ~= nil) then
|
||||
level = self.forcedLevel
|
||||
end
|
||||
|
||||
for _, rawdata in ipairs(self.list) do
|
||||
if (rawdata:canBeUsed(level) and rawdata.name ~= "boost" and rawdata.name ~= "halfboost") then
|
||||
self:addToHolder(rawdata:getKey(), rawdata:getCommand(), rawdata.arguments)
|
||||
end
|
||||
end
|
||||
|
||||
self.boosts:apply()
|
||||
|
||||
for key, holder in pairs(self.holders) do
|
||||
self:addToReducedList(key, holder:reduce(level, mode))
|
||||
end
|
||||
|
||||
if (self.forcedLevel ~= nil) then
|
||||
self.reducedList["level"] = self.forcedLevel
|
||||
end
|
||||
|
||||
if (self.forcedName ~= nil) then
|
||||
self.reducedList["name"] = self.forcedName
|
||||
end
|
||||
|
||||
if (level > 6) then
|
||||
print("[WARNING] Les niveaux au dessus de 6 ne sont pas encore implémentés (" .. self.reducedList["name"] .. ":" .. level .. ")")
|
||||
end
|
||||
|
||||
self.reducedList["rang"] = rank[math.min(level + 1, #rank)]
|
||||
end
|
||||
|
||||
function DataList:addToReducedList(key, data)
|
||||
local to = commands.structs[key].to or key
|
||||
local toSplited = utils.split(to, ".", true)
|
||||
if (#toSplited == 1) then
|
||||
self.reducedList[to] = data
|
||||
else
|
||||
local list = self.reducedList
|
||||
for i, toPart in ipairs(toSplited) do
|
||||
if (i == #toSplited) then
|
||||
list[toPart] = data
|
||||
else
|
||||
if (list[toPart] == nil) then
|
||||
list[toPart] = {}
|
||||
end
|
||||
list = list[toPart]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DataList:prepareJson(simplercreatures, creatures, parent)
|
||||
self:reduce()
|
||||
|
||||
self.reducedList.parent = parent
|
||||
|
||||
table.insert(simplercreatures, {nom = self.reducedList.name, rang = self.reducedList.rang, level = self.reducedList.level, type = self.reducedList.type, categorie = self.reducedList.categorie})
|
||||
table.insert(creatures, self.reducedList)
|
||||
end
|
||||
|
||||
return DataList
|
55
bestiaire/classes/folderloader.lua
Normal file
55
bestiaire/classes/folderloader.lua
Normal file
|
@ -0,0 +1,55 @@
|
|||
local FolderLoader = Object:extend()
|
||||
local BeastFile = require "classes.beastfile"
|
||||
local GroupFile = require "classes.groupfile"
|
||||
|
||||
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))
|
||||
elseif (file[2] == "group") then
|
||||
table.insert(self.files, GroupFile(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
|
64
bestiaire/classes/groupfile.lua
Normal file
64
bestiaire/classes/groupfile.lua
Normal file
|
@ -0,0 +1,64 @@
|
|||
local GroupFile = Object:extend()
|
||||
local BeastFile = require "classes.beastfile"
|
||||
|
||||
local parseFile = require "libs.filereader"
|
||||
|
||||
function GroupFile:new(folder, name, forceLevel)
|
||||
self.filepath = folder .. "/" .. name
|
||||
print("Loading " .. self.filepath)
|
||||
self.datas = {}
|
||||
|
||||
self:readLines()
|
||||
end
|
||||
|
||||
function GroupFile:readLines()
|
||||
self:readAllLines(self.filepath)
|
||||
end
|
||||
|
||||
function GroupFile:readAllLines(path)
|
||||
parseFile(path, function (line) self:addLine(line) end)
|
||||
end
|
||||
|
||||
function GroupFile:addLine(line)
|
||||
if (utils.startswith(line, "beast;") or utils.startswith(line, "beasts;")) then
|
||||
local datas = utils.split(line, ";", true)
|
||||
self:addBeast(datas[2], datas[3], datas[4], self:getMixins(datas))
|
||||
end
|
||||
end
|
||||
|
||||
function GroupFile:getMixins(datas)
|
||||
if (#datas < 4) then
|
||||
return {}
|
||||
else
|
||||
local list = {}
|
||||
for index, value in ipairs(datas) do
|
||||
if (index > 4) then
|
||||
table.insert(list, value)
|
||||
end
|
||||
end
|
||||
return list
|
||||
end
|
||||
end
|
||||
|
||||
function GroupFile:addBeast(name, level, baseFile, mixins)
|
||||
local beast = BeastFile("data", baseFile .. ".beast", tonumber(level))
|
||||
if (#mixins > 0) then
|
||||
for index, mixin in ipairs(mixins) do
|
||||
beast:loadMixin(mixin)
|
||||
end
|
||||
end
|
||||
|
||||
beast:forceName(name)
|
||||
table.insert(self.datas, beast)
|
||||
end
|
||||
|
||||
function GroupFile:prepareJson(simplercreatures, creatures, parent)
|
||||
assert(simplercreatures ~= nil)
|
||||
assert(creatures ~= nil)
|
||||
--self.datas:prepareJson(simplercreatures, creatures, parent)
|
||||
for _, beast in ipairs(self.datas) do
|
||||
beast:prepareJson(simplercreatures, creatures, parent)
|
||||
end
|
||||
end
|
||||
|
||||
return GroupFile
|
5
bestiaire/config.lua
Normal file
5
bestiaire/config.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
return {
|
||||
{nom = "Animaux", folder = "animaux", description = "Des animaux génériques et communs (ou moins communs)", descriptionPage = "Cette page comporte les animaux génériques et communs qu'on peut voir tout les jours, plus quelques animaux plus grand que d'habitude. Ces créatures vont être généralement de niveaux plus faible que d'autres que vous pourrez rencontrer plus tard dans le jeu (apres une vache ça reste dangereux hein)"},
|
||||
{nom = "Démons et enfer", folder = "demons", description = "Créatures des enfers et satanistes", descriptionPage = "Cette page comporte les créatures et base de PNJ lié aux enfers. Cela peut contenir des démons, des satanistes, ou d'autres créatures lié aux enfers. Ces êtres sont souvent lié à l'élément *chaos*."},
|
||||
|
||||
}
|
26
bestiaire/data/animaux/belier.beast
Normal file
26
bestiaire/data/animaux/belier.beast
Normal file
|
@ -0,0 +1,26 @@
|
|||
type;bete
|
||||
mixins;bases/corps/quadripede
|
||||
level;0
|
||||
name;Belier
|
||||
|
||||
// 4 boosts de stats
|
||||
boost;hab;.5
|
||||
boost;rel;1
|
||||
boost;con;.5
|
||||
boost;per;1
|
||||
boost;pv;1
|
||||
|
||||
armurephy.base;3
|
||||
armurepsy.base;0
|
||||
armurespe.base;3
|
||||
|
||||
competence;Charge;10;
|
||||
competence.lvl;Charge;3;
|
||||
competence;Evasion;10;
|
||||
competence.lvl;Evasion;3;
|
||||
|
||||
armes;Corne;3;
|
||||
|
||||
skill;Charge (1 tours de cooldown);Peut charger et envoyer deux dés d'attaque au lieu d'un;
|
||||
skill;Broute; Peut faire une attaque qui fait des dégats mentaux aux végétaux;
|
||||
skill;Laine;+2 armures spéciale de base (scale avec le niveau, déjà présent dans les armures);
|
5
bestiaire/data/animaux/canides.group
Normal file
5
bestiaire/data/animaux/canides.group
Normal file
|
@ -0,0 +1,5 @@
|
|||
beast;Chien;0;generique/canides
|
||||
beast;Petit Chien;0;generique/canides;bases/tailles/petit
|
||||
beast;Loup;2;generique/canides
|
||||
beast;Chef-Loup;3;generique/canides
|
||||
beast;Loup Géant;4;generique/canides;bases/tailles/grand
|
22
bestiaire/data/animaux/cheval.beast
Normal file
22
bestiaire/data/animaux/cheval.beast
Normal file
|
@ -0,0 +1,22 @@
|
|||
type;bete
|
||||
mixins;bases/corps/quadripede
|
||||
mixins;bases/tailles/grand
|
||||
level;2
|
||||
name;Cheval
|
||||
|
||||
// 4 boosts de stats
|
||||
boost;hab;.5
|
||||
boost;rel;.5
|
||||
boost;con;1
|
||||
boost;pv;2
|
||||
|
||||
armurephy.base;3
|
||||
armurepsy.base;0
|
||||
armurespe.base;1
|
||||
|
||||
competence;Charge;10;
|
||||
competence.lvl;Charge;3;
|
||||
|
||||
skill;Galop;Peut faire sa vitesse pur sur sa FOR;
|
||||
skill;Monture;Peut servir de monture, jouera au même tour;
|
||||
skill;Ruade (2 tours de cooldown);Une attaque qui projette l'ennemi et à 1/4 chance de stun;
|
25
bestiaire/data/animaux/chevre.beast
Normal file
25
bestiaire/data/animaux/chevre.beast
Normal file
|
@ -0,0 +1,25 @@
|
|||
type;bete
|
||||
mixins;bases/corps/quadripede
|
||||
level;0
|
||||
name;Chèvre
|
||||
|
||||
// 4 boosts de stats
|
||||
boost;hab;.5
|
||||
boost;rel;.5
|
||||
boost;int;1
|
||||
boost;per;1
|
||||
boost;pv;1
|
||||
|
||||
armurephy.base;3
|
||||
armurepsy.base;0
|
||||
armurespe.base;1
|
||||
|
||||
competence;Charge;10;
|
||||
competence.lvl;Charge;3;
|
||||
competence;Evasion;10;
|
||||
competence.lvl;Evasion;3;
|
||||
|
||||
armes;Corne;3;
|
||||
|
||||
skill;Charge (1 tours de cooldown);Peut charger et envoyer deux dés d'attaque au lieu d'un;
|
||||
skill;Broute; Peut faire une attaque qui fait des dégats mentaux aux végétaux;
|
4
bestiaire/data/animaux/felides.group
Normal file
4
bestiaire/data/animaux/felides.group
Normal file
|
@ -0,0 +1,4 @@
|
|||
beast;Chat;0;generique/felides;bases/tailles/petit
|
||||
beast;Lynx;1;generique/felides
|
||||
beast;Fauve;3;generique/felides
|
||||
beast;Lion géant;4;generique/felides;bases/tailles/grand
|
3
bestiaire/data/animaux/ours.beast
Normal file
3
bestiaire/data/animaux/ours.beast
Normal file
|
@ -0,0 +1,3 @@
|
|||
mixins;generique/ursides
|
||||
level;3
|
||||
name;Ours
|
11
bestiaire/data/animaux/rats.group
Normal file
11
bestiaire/data/animaux/rats.group
Normal file
|
@ -0,0 +1,11 @@
|
|||
beast;Rat;0;generique/rat
|
||||
beast;Chauve souris;1;generique/rat;types/aerien
|
||||
beast;Gros rat;1;generique/rat;bases/tailles/petit
|
||||
beast;Nuée de rats;1;generique/rat;bases/special/nuee
|
||||
beast;Nuée de chauve souris;1;generique/rat;types/aerien
|
||||
beast;Rat pestiféré;1;generique/rat;bases/special/pestilent
|
||||
beast;Rat géant;2;generique/rat
|
||||
beast;Chauve souris vampire;2;generique/rat;types/aerien;bases/special/vampirisme
|
||||
beast;Rat géant pestiféré;3;generique/rat;generique/rat;bases/special/pestilent
|
||||
beast;Nuée de rats pestiféré;3;generique/rat;bases/special/nuee;bases/special/pestilent
|
||||
beast;Nuée de chauve souris vampire;3;generique/rat;types/aerien;bases/special/nuee;bases/special/vampirisme
|
27
bestiaire/data/animaux/renard.beast
Normal file
27
bestiaire/data/animaux/renard.beast
Normal file
|
@ -0,0 +1,27 @@
|
|||
type;bete
|
||||
mixins;bases/corps/quadripede
|
||||
level;1
|
||||
name;Renard
|
||||
|
||||
// 4 boosts de stats
|
||||
boost;int;1
|
||||
boost;hab;1
|
||||
boost;rel;.5
|
||||
boost;atk;.5
|
||||
boost;pv;.5
|
||||
boost;int;.5
|
||||
|
||||
armurephy.base;2
|
||||
armurepsy.base;0
|
||||
armurespe.base;1
|
||||
|
||||
competence;Chasse;10;
|
||||
competence.lvl;Chasse;3;
|
||||
competence;Pistage;10;
|
||||
competence.lvl;Pistage;3;
|
||||
|
||||
armes;Griffe;3;
|
||||
armes;Croc;4;
|
||||
|
||||
skill;Morsure;Une attaque qui utilise les crocs et fait 1 blessure;
|
||||
skill;Griffure;Fait deux attaques à -30% de chance de toucher;
|
24
bestiaire/data/animaux/vache.beast
Normal file
24
bestiaire/data/animaux/vache.beast
Normal file
|
@ -0,0 +1,24 @@
|
|||
type;bete
|
||||
mixins;bases/corps/quadripede
|
||||
mixins;bases/tailles/grand
|
||||
level;2
|
||||
name;Vache
|
||||
|
||||
// 4 boosts de stats
|
||||
boost;atk;.5
|
||||
boost;rel;.5
|
||||
boost;con;1
|
||||
boost;pv;2
|
||||
|
||||
armurephy.base;4
|
||||
armurepsy.base;0
|
||||
armurespe.base;2
|
||||
|
||||
competence;Charge;10;
|
||||
competence.lvl;Charge;3;
|
||||
|
||||
armes;Corne;3;
|
||||
|
||||
skill;Charge (1 tours de cooldown);Peut charger et envoyer deux dés d'attaque au lieu d'un;
|
||||
skill;Monture;Peut servir de monture, jouera au même tour;
|
||||
skill;Empalement (2 tours de cooldown);Attaque qui provoque 1D4 blessure, mais n'a qu'une chance sur 2 de réussir; | 6
|
16
bestiaire/data/bases/corps/bipede.beast
Normal file
16
bestiaire/data/bases/corps/bipede.beast
Normal file
|
@ -0,0 +1,16 @@
|
|||
atk.base;60
|
||||
con.base;50
|
||||
hab.base;50
|
||||
|
||||
int.base;30
|
||||
sag.base;30
|
||||
vol.base;50
|
||||
|
||||
cha.base;50
|
||||
dis.base;50
|
||||
rel.base;60
|
||||
|
||||
per.base;50
|
||||
|
||||
pv.base;12
|
||||
pe.base;12
|
16
bestiaire/data/bases/corps/quadripede.beast
Normal file
16
bestiaire/data/bases/corps/quadripede.beast
Normal file
|
@ -0,0 +1,16 @@
|
|||
atk.base;65
|
||||
con.base;65
|
||||
hab.base;70
|
||||
|
||||
int.base;15
|
||||
sag.base;30
|
||||
vol.base;30
|
||||
|
||||
cha.base;60
|
||||
dis.base;60
|
||||
rel.base;40
|
||||
|
||||
per.base;70
|
||||
|
||||
pv.base;18
|
||||
pe.base;9
|
16
bestiaire/data/bases/corps/serpentin.beast
Normal file
16
bestiaire/data/bases/corps/serpentin.beast
Normal file
|
@ -0,0 +1,16 @@
|
|||
atk.base;60
|
||||
con.base;55
|
||||
hab.base;65
|
||||
|
||||
int.base;15
|
||||
sag.base;30
|
||||
vol.base;30
|
||||
|
||||
cha.base;60
|
||||
dis.base;70
|
||||
rel.base;20
|
||||
|
||||
per.base;70
|
||||
|
||||
pv.base;15
|
||||
pe.base;9
|
16
bestiaire/data/bases/corps/volant.beast
Normal file
16
bestiaire/data/bases/corps/volant.beast
Normal file
|
@ -0,0 +1,16 @@
|
|||
atk.base;60
|
||||
con.base;30
|
||||
hab.base;70
|
||||
|
||||
int.base;15
|
||||
sag.base;30
|
||||
vol.base;30
|
||||
|
||||
cha.base;50
|
||||
dis.base;50
|
||||
rel.base;40
|
||||
|
||||
per.base;65
|
||||
|
||||
pv.base;15
|
||||
pe.base;9
|
2
bestiaire/data/bases/special/demons-betes.beast
Normal file
2
bestiaire/data/bases/special/demons-betes.beast
Normal file
|
@ -0,0 +1,2 @@
|
|||
mixins;bases/special/demons
|
||||
skill;Blessure infernale;besoin de deux soin pour soigner une blessure, les blessures restante après le combat provoque un malus physique sur le long terme;
|
5
bestiaire/data/bases/special/demons.beast
Normal file
5
bestiaire/data/bases/special/demons.beast
Normal file
|
@ -0,0 +1,5 @@
|
|||
faiblesse;ordre
|
||||
resistence;chaos
|
||||
|
||||
skill;Force chaotique;Regagne 1D6 PV - 3 par tour en terrain chaotique;
|
||||
skill;Attaque démoniaque;Attaque avec effet de chaos (L'attaque fait moitié dégats sur le corps et l'esprit.)
|
1
bestiaire/data/bases/special/nuee.beast
Normal file
1
bestiaire/data/bases/special/nuee.beast
Normal file
|
@ -0,0 +1 @@
|
|||
skill;Nuée;PV × 1D8, correspond au nombre de créature. Au max 3 attaque par tour tant qu'il y a assez de créature. Les attaque non de zone font max le nombre de PV de base de la créature. Les soins ne peuvent ramener des membres de la nuée. La nuée perd 10% en hab pour esquiver tant qu'il y a des membres.;
|
1
bestiaire/data/bases/special/pestilent.beast
Normal file
1
bestiaire/data/bases/special/pestilent.beast
Normal file
|
@ -0,0 +1 @@
|
|||
skill;Pestilence;Ses attaques physique font l'effet poison;
|
1
bestiaire/data/bases/special/vampirisme.beast
Normal file
1
bestiaire/data/bases/special/vampirisme.beast
Normal file
|
@ -0,0 +1 @@
|
|||
skill;Vampirisme (1 tour de cooldown);Une attaque au corps à corps qui soigne à l'attaquant 50% des dégats infligés à l'ennemi.;
|
8
bestiaire/data/bases/tailles/grand.beast
Normal file
8
bestiaire/data/bases/tailles/grand.beast
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Créature grande (ours)
|
||||
atk.bonus;15
|
||||
con.bonus;15
|
||||
hab.bonus;-15
|
||||
per.bonus;-15
|
||||
|
||||
pv.bonus;3;
|
||||
armurephy.bonus;1;
|
10
bestiaire/data/bases/tailles/minuscule.beast
Normal file
10
bestiaire/data/bases/tailles/minuscule.beast
Normal file
|
@ -0,0 +1,10 @@
|
|||
// Créature minuscule (insecte)
|
||||
atk.bonus;-30
|
||||
con.bonus;-30
|
||||
hab.bonus;30
|
||||
per.bonus;30
|
||||
|
||||
pv.bonus;0;
|
||||
pv.base;1;
|
||||
pv.lvl;0;
|
||||
armurephy.bonus;-1;
|
8
bestiaire/data/bases/tailles/normal.beast
Normal file
8
bestiaire/data/bases/tailles/normal.beast
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Créature normale
|
||||
atk.bonus;0
|
||||
con.bonus;0
|
||||
hab.bonus;0
|
||||
per.bonus;0
|
||||
|
||||
pv.bonus;0;
|
||||
armurephy.bonus;0;
|
8
bestiaire/data/bases/tailles/petit.beast
Normal file
8
bestiaire/data/bases/tailles/petit.beast
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Créature petite (chat à chien)
|
||||
atk.bonus;-15
|
||||
con.bonus;-15
|
||||
hab.bonus;15
|
||||
per.bonus;15
|
||||
|
||||
pv.bonus;-3;
|
||||
armurephy.bonus;-1;
|
8
bestiaire/data/bases/tailles/tresgrand.beast
Normal file
8
bestiaire/data/bases/tailles/tresgrand.beast
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Créature très grande (rhino / éléphant)
|
||||
atk.bonus;25
|
||||
con.bonus;25
|
||||
hab.bonus;-25
|
||||
per.bonus;-25
|
||||
|
||||
pv.bonus;6;
|
||||
armurephy.bonus;2;
|
8
bestiaire/data/bases/tailles/trespetit.beast
Normal file
8
bestiaire/data/bases/tailles/trespetit.beast
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Créature très petite (rat, etc)
|
||||
atk.bonus;-25
|
||||
con.bonus;-25
|
||||
hab.bonus;25
|
||||
per.bonus;25
|
||||
|
||||
pv.bonus;-6;
|
||||
armurephy.bonus;-1;
|
5
bestiaire/data/demons/canides.group
Normal file
5
bestiaire/data/demons/canides.group
Normal file
|
@ -0,0 +1,5 @@
|
|||
beast;Chihuahua infernal;2;generique/canides;bases/tailles/petit;bases/special/demons-betes
|
||||
beast;Chien des enfers;2;generique/canides
|
||||
beast;Loup des enfers;3;generique/canides;bases/special/demons-betes
|
||||
beast;Chef-Loup des enfers;4;generique/canides;bases/special/demons-betes
|
||||
beast;Loup du pandémonium;5;generique/canides;bases/tailles/grand;bases/special/demons-betes
|
27
bestiaire/data/generique/canides.beast
Normal file
27
bestiaire/data/generique/canides.beast
Normal file
|
@ -0,0 +1,27 @@
|
|||
type;bete
|
||||
mixins;bases/corps/quadripede
|
||||
|
||||
// 4 boosts à rajouter
|
||||
|
||||
boost;atk;1.5
|
||||
boost;pv;1
|
||||
boost;pe;.5
|
||||
boost;hab;.5
|
||||
boost;con;.5
|
||||
|
||||
armurephy.base;2
|
||||
armurepsy.base;0
|
||||
armurespe.base;1
|
||||
|
||||
competence;Chasse;10;
|
||||
competence.lvl;Chasse;3;
|
||||
competence;Pistage;10;
|
||||
competence.lvl;Pistage;3;
|
||||
|
||||
armes;Griffe;3;
|
||||
armes;Croc;4;
|
||||
|
||||
skill;Morsure;Une attaque qui utilise les crocs et fait 1 blessure;
|
||||
skill;Griffure;Fait deux attaques à -30% de chance de toucher;
|
||||
skill;Bêtes de meute;+5% pour toucher des zones difficiles par créature de meute présente;
|
||||
skill;Férocité (trois tour de cooldown);Peut doubler les dégats d'une attaque, mais se prendra 50% des dégats en retour | 6
|
27
bestiaire/data/generique/felides.beast
Normal file
27
bestiaire/data/generique/felides.beast
Normal file
|
@ -0,0 +1,27 @@
|
|||
type;bete
|
||||
mixins;bases/corps/quadripede
|
||||
|
||||
// 4 boosts à rajouter
|
||||
|
||||
boost;atk;1
|
||||
boost;hab;1
|
||||
boost;pv;1
|
||||
boost;int;.5
|
||||
boost;dis;.5
|
||||
|
||||
armurephy.base;1
|
||||
armurepsy.base;0
|
||||
armurespe.base;1
|
||||
|
||||
competence;Chasse;10;
|
||||
competence.lvl;Chasse;2;
|
||||
competence;Pistage;10;
|
||||
competence.lvl;Pistage;2;
|
||||
competence;Grimpette;10;
|
||||
competence.lvl;Pistage;2;
|
||||
|
||||
armes;Griffe;3;
|
||||
armes;Croc;4;
|
||||
|
||||
skill;Morsure;Une attaque qui utilise les crocs et fait 1 blessure;
|
||||
skill;Griffure;Fait deux attaques à -30% de chance de toucher;
|
25
bestiaire/data/generique/rat.beast
Normal file
25
bestiaire/data/generique/rat.beast
Normal file
|
@ -0,0 +1,25 @@
|
|||
type;bete
|
||||
mixins;bases/corps/quadripede
|
||||
mixins;bases/tailles/trespetit
|
||||
level;0
|
||||
name;Rat
|
||||
|
||||
// 4 boosts de stats
|
||||
boost;int;1
|
||||
boost;hab;2
|
||||
boost;dis;1
|
||||
|
||||
armurephy.base;0
|
||||
armurepsy.base;0
|
||||
armurespe.base;0
|
||||
|
||||
competence;Cachette;10;
|
||||
competence.lvl;Cachette;3;
|
||||
competence;Fouille;10;
|
||||
competence.lvl;Fouille;3;
|
||||
|
||||
armes;Griffe;1;
|
||||
armes;Croc;2;
|
||||
|
||||
skill;Morsure;Une attaque qui utilise les crocs et fait 1 blessure;
|
||||
skill;Attaque accrochée;S'accroche et fait 1 dégats / tour;
|
23
bestiaire/data/generique/ursides.beast
Normal file
23
bestiaire/data/generique/ursides.beast
Normal file
|
@ -0,0 +1,23 @@
|
|||
type;bete
|
||||
mixins;bases/corps/quadripede
|
||||
mixins;bases/tailles/grand
|
||||
|
||||
// 4 boost à passer par niveau
|
||||
boost;atk;1
|
||||
boost;con;1
|
||||
boost;pv;2
|
||||
|
||||
armurephy.base;4
|
||||
armurepsy.base;0
|
||||
armurespe.base;2
|
||||
|
||||
competence;Chasse;10;
|
||||
competence.lvl;Chasse;3;
|
||||
competence;Pistage;10;
|
||||
competence.lvl;Pistage;3;
|
||||
|
||||
armes;Griffe;4;
|
||||
armes;Croc;5;
|
||||
|
||||
skill;Morsure;Une attaque qui utilise les crocs et fait 2 blessure;
|
||||
skill;Griffure;Fait deux attaques à -30% de chance de toucher;
|
5
bestiaire/data/types/aerien.beast
Normal file
5
bestiaire/data/types/aerien.beast
Normal file
|
@ -0,0 +1,5 @@
|
|||
nomType;aerien
|
||||
categorie;biologique
|
||||
faiblesse;air
|
||||
resistence;terre
|
||||
skill;Vol;Peut voler, +30% pour esquiver les attaques terrestres
|
5
bestiaire/data/types/aquatique.beast
Normal file
5
bestiaire/data/types/aquatique.beast
Normal file
|
@ -0,0 +1,5 @@
|
|||
nomType;aquatique
|
||||
categorie;biologique
|
||||
faiblesse;foudre
|
||||
resistance;eau
|
||||
skill;Aquatique;N'a pas de malus dans l'eau
|
3
bestiaire/data/types/bete.beast
Normal file
3
bestiaire/data/types/bete.beast
Normal file
|
@ -0,0 +1,3 @@
|
|||
nomType;bête
|
||||
categorie;biologique
|
||||
faiblesse;metal
|
5
bestiaire/data/types/feufolet.beast
Normal file
5
bestiaire/data/types/feufolet.beast
Normal file
|
@ -0,0 +1,5 @@
|
|||
nomType;feufolet
|
||||
categorie;non-biologique
|
||||
faiblesse;eau
|
||||
faiblesse;terre
|
||||
resistance;glace
|
6
bestiaire/data/types/gelatineux.beast
Normal file
6
bestiaire/data/types/gelatineux.beast
Normal file
|
@ -0,0 +1,6 @@
|
|||
nomType;gelatineux
|
||||
categorie;non-biologique
|
||||
faiblesse;metal
|
||||
faiblesse;son
|
||||
resistance;force
|
||||
resistance;eau
|
4
bestiaire/data/types/glace.beast
Normal file
4
bestiaire/data/types/glace.beast
Normal file
|
@ -0,0 +1,4 @@
|
|||
nomType;créature de glace
|
||||
categorie;non-biologique
|
||||
faiblesse;feu
|
||||
resistance;glace
|
2
bestiaire/data/types/humanoide.beast
Normal file
2
bestiaire/data/types/humanoide.beast
Normal file
|
@ -0,0 +1,2 @@
|
|||
nomType;humanoïde
|
||||
categorie;biologique
|
3
bestiaire/data/types/insecte.beast
Normal file
3
bestiaire/data/types/insecte.beast
Normal file
|
@ -0,0 +1,3 @@
|
|||
nomType;insecte
|
||||
categorie;biologique
|
||||
faiblesse;feu
|
5
bestiaire/data/types/machine.beast
Normal file
5
bestiaire/data/types/machine.beast
Normal file
|
@ -0,0 +1,5 @@
|
|||
nomType;machine
|
||||
categorie;non-biologique
|
||||
immunite;poison
|
||||
faiblesse;foudre
|
||||
faiblesse;eau
|
4
bestiaire/data/types/mineraloide.beast
Normal file
4
bestiaire/data/types/mineraloide.beast
Normal file
|
@ -0,0 +1,4 @@
|
|||
nomType;mineraloïde
|
||||
categorie;non-biologique
|
||||
resistance;poison
|
||||
resistance;feu
|
3
bestiaire/data/types/reptile.beast
Normal file
3
bestiaire/data/types/reptile.beast
Normal file
|
@ -0,0 +1,3 @@
|
|||
nomType;reptile
|
||||
categorie;biologique
|
||||
faiblesse;glace
|
4
bestiaire/data/types/vegetal.beast
Normal file
4
bestiaire/data/types/vegetal.beast
Normal file
|
@ -0,0 +1,4 @@
|
|||
nomType;vegetal
|
||||
categorie;biologique
|
||||
faiblesse;feu
|
||||
resistance;vegetal
|
5
bestiaire/data/types/volute.beast
Normal file
5
bestiaire/data/types/volute.beast
Normal file
|
@ -0,0 +1,5 @@
|
|||
nomType;volute
|
||||
categorie;non-biologique
|
||||
faiblesse;air
|
||||
resistance;terre
|
||||
resistance;metal
|
15
bestiaire/levels/beasts.lua
Normal file
15
bestiaire/levels/beasts.lua
Normal file
|
@ -0,0 +1,15 @@
|
|||
local datas = {}
|
||||
|
||||
datas.hp = {1, 1, 2, 3, 4, 5, 6}
|
||||
datas.competences = {10, 30, 30, 50, 50, 70}
|
||||
datas.stats = {
|
||||
[0] = {base = 40, malus = {20, 30, 30}, bonus = {50, 50, 60}},
|
||||
[1] = {base = 50, malus = {20, 30, 40}, bonus = {60, 70, 80}},
|
||||
[2] = {base = 50, malus = {30, 30, 40}, bonus = {70, 80, 80}},
|
||||
[3] = {base = 50, malus = {30, 30, 40}, bonus = {80, 80, 100}}, -- Potentiel
|
||||
[4] = {base = 50, malus = {30, 40, 40}, bonus = {80, 80, 120}},
|
||||
[5] = {base = 50, malus = {30, 40, 40}, bonus = {80, 100, 140}}, -- Potentiel+
|
||||
[6] = {base = 60, malus = {30, 40, 50}, bonus = {80, 120, 150}},
|
||||
[7] = {base = 60, malus = {30, 40, 50}, bonus = {80, 130, 180}}, -- Supérieur au max des joueurs
|
||||
[8] = {base = 60, malus = {40, 40, 50}, bonus = {120, 150, 200}},
|
||||
}
|
15
bestiaire/levels/pnj.lua
Normal file
15
bestiaire/levels/pnj.lua
Normal file
|
@ -0,0 +1,15 @@
|
|||
local datas = {}
|
||||
|
||||
datas.hp = {1, 1, 2, 3, 4, 5, 6}
|
||||
datas.competences = {10, 30, 30, 50, 50, 70}
|
||||
datas.stats = {
|
||||
[0] = {base = 40, malus = {20, 30, 30}, bonus = {50, 50, 60}},
|
||||
[1] = {base = 50, malus = {20, 30, 40}, bonus = {60, 70, 80}},
|
||||
[2] = {base = 50, malus = {30, 30, 40}, bonus = {70, 80, 80}},
|
||||
[3] = {base = 50, malus = {30, 30, 40}, bonus = {80, 80, 100}}, -- Potentiel
|
||||
[4] = {base = 50, malus = {30, 40, 40}, bonus = {80, 80, 120}},
|
||||
[5] = {base = 50, malus = {30, 40, 40}, bonus = {80, 100, 140}}, -- Potentiel+
|
||||
[6] = {base = 60, malus = {30, 40, 50}, bonus = {80, 120, 150}},
|
||||
[7] = {base = 60, malus = {30, 40, 50}, bonus = {80, 130, 180}}, -- Supérieur au max des joueurs
|
||||
[8] = {base = 60, malus = {40, 40, 50}, bonus = {120, 150, 200}},
|
||||
}
|
1
bestiaire/levels/ranks.lua
Normal file
1
bestiaire/levels/ranks.lua
Normal file
|
@ -0,0 +1 @@
|
|||
return {"E", "D", "C", "B", "A", "S", "X", "X²", "X³", "--"}
|
39
bestiaire/libs/boosts.lua
Normal file
39
bestiaire/libs/boosts.lua
Normal file
|
@ -0,0 +1,39 @@
|
|||
local boost = {}
|
||||
|
||||
local BOOST_ARM_CREATURE = {
|
||||
{lvl = 0, value = 1},
|
||||
{lvl = 2, value = 1.5},
|
||||
{lvl = 3, value = 2},
|
||||
{lvl = 5, value = 3},
|
||||
{lvl = 6, value = 3.5},
|
||||
{lvl = 7, value = 4}
|
||||
}
|
||||
|
||||
local BOOST_ARM_PNJ = {
|
||||
{lvl = 0, value = 1},
|
||||
{lvl = 2, value = 1.5},
|
||||
{lvl = 4, value = 2},
|
||||
{lvl = 6, value = 3}
|
||||
}
|
||||
|
||||
|
||||
local function getBoost(level, table)
|
||||
local bestBoost = {lvl = -1, value = 1}
|
||||
for _, boost in ipairs(table) do
|
||||
if (level >= boost.lvl and boost.lvl > bestBoost.lvl) then
|
||||
bestBoost = boost
|
||||
end
|
||||
end
|
||||
return bestBoost.value
|
||||
end
|
||||
|
||||
function boost.getBoost(level, mode)
|
||||
if (mode == "pnj") then
|
||||
return getBoost(level, BOOST_ARM_PNJ)
|
||||
else
|
||||
return getBoost(level, BOOST_ARM_CREATURE)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return boost
|
68
bestiaire/libs/classic.lua
Normal file
68
bestiaire/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
bestiaire/libs/commands.lua
Normal file
71
bestiaire/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, value.lvl or 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" or value.dataType == "armure" or value.dataType == "vita") then
|
||||
addStatCommands(key, value)
|
||||
elseif (value.dataType == "list") then
|
||||
addListCommands(key, value)
|
||||
elseif (value.dataType == "comp" or value.dataType == "armes") 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
bestiaire/libs/filereader.lua
Normal file
34
bestiaire/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;
|
4
bestiaire/libs/init.lua
Normal file
4
bestiaire/libs/init.lua
Normal file
|
@ -0,0 +1,4 @@
|
|||
utils = require "libs.utils"
|
||||
Object = require "libs.classic"
|
||||
commands = require "libs.commands"
|
||||
boosts = require "libs.boosts"
|
388
bestiaire/libs/json.lua
Normal file
388
bestiaire/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
bestiaire/libs/split.lua
Normal file
127
bestiaire/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
bestiaire/libs/utils.lua
Normal file
69
bestiaire/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
bestiaire/main.lua
Normal file
29
bestiaire/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("../_data/bestiaires.json", "w")
|
||||
if (file ~= nil) then
|
||||
file:write(json.encode(bestiaires))
|
||||
end
|
||||
|
||||
local file2 = io.open("../_data/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")
|
31
bestiaire/struct.lua
Normal file
31
bestiaire/struct.lua
Normal file
|
@ -0,0 +1,31 @@
|
|||
return {
|
||||
name={contentType = "string", preParse = true, to="name"},
|
||||
mode={contentType = "string", preParse = true, to="mode", default = "creature"},
|
||||
nomType={contentType = "string", to="type"},
|
||||
categorie={contentType = "string", to="categorie"},
|
||||
faiblesse={contentType = "list", args=1},
|
||||
resistence={contentType = "list", args=1},
|
||||
immunite={contentType = "list", args=1},
|
||||
level={contentType = "number", default = 0, preParse = true},
|
||||
pression={contentType = "number", default = 5},
|
||||
boost={dataType = "boost", args=2},
|
||||
atk= {dataType= "stat", modulo= 5, default= 50, max=255, min=10, to="stats.for"},
|
||||
con= {dataType= "stat", modulo= 5, default= 50, max=255, min=10, to="stats.con"},
|
||||
hab= {dataType= "stat", modulo= 5, default= 50, max=255, min=10, to="stats.hab"},
|
||||
int= {dataType= "stat", modulo= 5, default= 50, max=255, min=10, to="stats.int"},
|
||||
sag= {dataType= "stat", modulo= 5, default= 50, max=255, min=10, to="stats.sag"},
|
||||
vol= {dataType= "stat", modulo= 5, default= 50, max=255, min=10, to="stats.vol"},
|
||||
cha= {dataType= "stat", modulo= 5, default= 50, max=255, min=10, to="stats.cha"},
|
||||
dis= {dataType= "stat", modulo= 5, default= 50, max=255, min=10, to="stats.dis"},
|
||||
rel= {dataType= "stat", modulo= 5, default= 50, max=255, min=10, to="stats.rel"},
|
||||
per= {dataType= "stat", modulo= 5, default= 50, max=255, min=10, to="stats.per"},
|
||||
pv= {dataType= "vita", modulo= 1, default= 12, max=9999999, min=1, to="vita.pv", lvl=1},
|
||||
pe= {dataType= "vita", modulo= 1, default= 12, max=9999999, min=1, to="vita.pe", lvl=1},
|
||||
eclat= {dataType= "stat", modulo= 1, default= 10, max=200, min=1, to="vita.eclat"},
|
||||
armurephy= {dataType= "armure", modulo= 1, default= 0, max=9999999, min=0, to="armure.phy"},
|
||||
armurepsy= {dataType= "armure", modulo= 1, default= 0, max=9999999, min=0, to="armure.psy"},
|
||||
armurespe= {dataType= "armure", modulo= 1, default= 0, max=9999999, min=0, to="armure.spe"},
|
||||
armes= {dataType= "armes", 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},
|
||||
}
|
32
bestiaire/view.lua
Normal file
32
bestiaire/view.lua
Normal file
|
@ -0,0 +1,32 @@
|
|||
require "libs"
|
||||
local config = require "config"
|
||||
local BeastFile = require "classes.beastfile"
|
||||
|
||||
local beast = BeastFile("data", arg[1] .. ".beast", tonumber(arg[2]))
|
||||
|
||||
local creature = beast:getRawData()
|
||||
|
||||
print(creature.name, "Lvl:" .. creature.level, "Pression:" .. creature.pression, creature["type"], creature.categorie)
|
||||
print(" ", "------")
|
||||
print("FOR:" .. creature.stats["for"], "INT:" .. creature.stats.int, "CHA:" .. creature.stats.cha)
|
||||
print("CON:" .. creature.stats.con, "SAG:" .. creature.stats.sag, "DIS:" .. creature.stats.dis)
|
||||
print("HAB:" .. creature.stats.hab, "VOL:" .. creature.stats.vol, "REL:" .. creature.stats.rel)
|
||||
print(" ", "PER:" .. creature.stats.per)
|
||||
print(" ", "------")
|
||||
print("PV:" .. creature.vita.pv, "PE:" .. creature.vita.pe, "Eclat:" .. creature.vita.eclat)
|
||||
print("Armure", "Phy:" .. creature.armure.phy, "Psy:" .. creature.armure.psy, "Spe:" .. creature.armure.spe)
|
||||
print(" ", "------")
|
||||
print("Armes:")
|
||||
for key, value in ipairs(creature.armes) do
|
||||
print(value.nom, value.force)
|
||||
end
|
||||
print(" ", "------")
|
||||
print("Competences:")
|
||||
for key, value in ipairs(creature.competence) do
|
||||
print(value.name, value.value)
|
||||
end
|
||||
print(" ", "------")
|
||||
print("Skills:")
|
||||
for key, value in ipairs(creature.skill) do
|
||||
print(value[1], value[2])
|
||||
end
|
13
changelog.md
13
changelog.md
|
@ -1,18 +1,5 @@
|
|||
# Changelog
|
||||
|
||||
## [2.6.1] - 2024-10-17
|
||||
|
||||
### Ajoutés
|
||||
|
||||
- Ajout des combats de batailles
|
||||
- Ajout d'un robots.txt
|
||||
|
||||
### Modifiés
|
||||
|
||||
- Modifications des tableaux pour utiliser plus souvent des verticaux
|
||||
- Modification du site pour le rendre responsive
|
||||
- Masquage des éléments futurs
|
||||
|
||||
## [2.6.0] - 2024-09-11
|
||||
|
||||
### Refonte DfOS
|
||||
|
|
27
content/about.md
Normal file
27
content/about.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
layout: layouts/home.njk
|
||||
---
|
||||
|
||||
# À propos
|
||||
|
||||
Ce site est un petit site de présentation de mon JDR {{ metadata.title }}. Il a pour but de vous présenter les différents éléments qui le composent, les différentes règles.
|
||||
|
||||
Pourquoi cette page ? Et bien, faisant des parties de ma campagne Erratum avec mes amis, je me suis retrouvé comme beaucoup de MJ avec une situation qui peut être parfois casse-pied... Devoir gérer 300 versions du livre de règles différentes parce que le fichier .odt a été passé à plusieurs personnes, modifié sur le tas, etc. Étant particulièrement fainéant, j'ai commencé à me dire que toute possibilité de moins bosser était la plus belle chose qui pouvait m'arriver. Du coup, voici le site du rulebook ! Un petit eleventy, quelques fichiers markdown sur des branches d'un dépot.
|
||||
|
||||
Cette page vous donne accès au lore de l'univers et aux différents sets de règles que j'ai fais pour mes différentes campagnes.
|
||||
|
||||
## Infos de copyright
|
||||
|
||||
Cet univers et ses JDRs associés sont mis à disposition selon les termes de la [licence Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/). Vous êtes libre d'utiliser cet univers, ainsi que les règles de jeux, comme base pour ce que vous voulez, à condition de repartager dans les mêmes conditions les contenus qui seraient basé sur cet univers. Il est à noter que cette licence ne couvre pas l'inspiration : vous pouvez vous inspirer de certains concepts ou idées sans que ce soit couvert par la licence, dans ce cas vous n'avez pas d'obligation d'utiliser la licence creative commons.
|
||||
|
||||
( À noter qu'utiliser le contenu de ce site pour entrainer une AI n'est pas de l'inspiration #NoAI )
|
||||
|
||||
## Crédits
|
||||
|
||||
- Site généré grâce à [Eleventy](11ty.org)
|
||||
- Icone [Night-Sky](https://game-icons.net/1x1/lorc/night-sky.html) par [Lorc](https://lorcblog.blogspot.com/) sous [CC BY 3.0](https://creativecommons.org/licenses/by/3.0/)
|
||||
- Icone [Pine-Tree](https://game-icons.net/1x1/lorc/pine-tree.html) par [Lorc](https://lorcblog.blogspot.com/) sous [CC BY 3.0](https://creativecommons.org/licenses/by/3.0/)
|
||||
- Icone [Dead wood](https://game-icons.net/1x1/lorc/dead-wood.html) par [Lorc](https://lorcblog.blogspot.com/) sous [CC BY 3.0](https://creativecommons.org/licenses/by/3.0/)
|
||||
- Favicon venant du set de tiles [Castlevania-esque Tilemap](https://opengameart.org/content/castlevania-esque-tilemap-stone-and-bricks) par [Richy Mackro](https://chayed-creates.itch.io/chayed-creates-pixels) sous [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)
|
||||
- Merci à Marcel Dupoignard et mon groupe de JDR pour de nombreux éléments de cet univers
|
||||
- Relecture et illustration de la page d'accueil par Nepeta Sibirica
|
|
@ -1,23 +1,21 @@
|
|||
---
|
||||
layout: layouts/base.njk
|
||||
eleventyNavigation:
|
||||
key: L'expérience
|
||||
key: L'expérience (old)
|
||||
parent: Classes et experiences
|
||||
order: 10
|
||||
---
|
||||
|
||||
# L'expérience
|
||||
|
||||
Les augmentation de niveau de signe faisait avoir obtenir d'un coup toutes les compétences d'un personnages, mais coutait de plus en plus cher, et par niveau (et non par groupe de niveau). Suite des nombres premiers suivant le niveau de difficulté. Lorsque double-signe, la liste devient.
|
||||
> Note: Cette page représente l'ancien système de gestion de l'expérience d'Erratum, pour le nouveau système, voyez la page [**Niveaux**](/classes/niveaux)
|
||||
|
||||
<div class="table-responsive">
|
||||
Dans l'ancien système d'Erratum, les augmentation de niveau de signe faisait avoir obtenir d'un coup toutes les compétences d'un personnages, mais coutait de plus en plus cher, et par niveau (et non par groupe de niveau). Suite des nombres premiers suivant le niveau de difficulté. Lorsque double-signe, la liste devient.
|
||||
|
||||
| Premier Signe ou autre type de classe (naturel) | Deuxième signe (apothéose) | Troisième signe (apothéose²) |
|
||||
|:-----------:|:--:|:--:|
|
||||
| 1-2-3-5-7-11 | 2-3-5-7-11-13 | 3-5-7-11-13-17 |
|
||||
|
||||
</div>
|
||||
|
||||
## Augmentations de stats
|
||||
|
||||
L'augmentation de stats est limitée par la présence ou non de potentiel, de la manière suivante :
|
||||
|
|
|
@ -10,10 +10,14 @@ parent: Les magies
|
|||
|
||||
# Les arts martiaux
|
||||
|
||||
Les arts martiaux sont une magie tirée de la *force martiale*. La force martiale se concentre dans le corps pour transformer les capacités utilisés.
|
||||
Les arts martiaux sont une magie tirée de la force martiale. La force martiale se concentre dans le corps pour transformer les capacités utilisés.
|
||||
|
||||
Les arts martiaux existent en de nombreuses écoles, et peut être apprise avec des maitres martialistes.
|
||||
|
||||
| Sources | Rareté | Stats privilégié |
|
||||
|:--:|:--:|:--:|
|
||||
| La Grande Force Martiale | Peu Commun | FOR |
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -14,6 +14,10 @@ La magie créatrice consiste à maîtriser une matière nommée le sidérale, co
|
|||
|
||||
C'est une des magies les plus rares et difficile à maitriser.
|
||||
|
||||
| Sources | Rareté | Stats privilégié |
|
||||
|:--:|:--:|:--:|
|
||||
| La puissance créatrice | Rare | INT, HAB |
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -14,6 +14,10 @@ La magie élémentaire est une magie se basant sur les pouvoirs des grands élé
|
|||
|
||||
Les utilisateurs font un pacte avec certains nombres d'éléments qui pourront ensuite être utilisé.
|
||||
|
||||
| Sources | Rareté | Stats privilégié |
|
||||
|:--:|:--:|:--:|
|
||||
| Grands élémentaires | Commune | INT, HAB |
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -14,6 +14,10 @@ Les enchantements sont une magie plutôt rare, consistant à appliquer des effet
|
|||
|
||||
Cette magie se fonde sur les circuits de magie existant partout, formé par la circulation naturelle de l'éclat dans tout ce qui existe.
|
||||
|
||||
| Sources | Rareté | Stats privilégié |
|
||||
|:--:|:--:|:--:|
|
||||
| Les circuits magiques naturels | Rare | HAB |
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
layout: layouts/base.njk
|
||||
title: L’herboristerie
|
||||
title: L’herboristerie (old)
|
||||
tags: Magies Communes
|
||||
models:
|
||||
- Magies Communes
|
||||
|
@ -8,10 +8,16 @@ models:
|
|||
parent: Les magies
|
||||
---
|
||||
|
||||
# L’herboristerie
|
||||
# L’herboristerie (ancienne version)
|
||||
|
||||
> **Note** : Cette version de l'herboristerie est dépréciée et sera retirée dans une version future. Cliquez ici pour accéder à [la nouvelle](/classes/magies/herboristerie/).
|
||||
|
||||
L'herboristerie est sans doute la magie la moins magique. Elle tire son pouvoir de plantes particulières, les plantes élémentaires. Ces plantes sont alors mélangées pour créer des effets spéciaux dans des potions.
|
||||
|
||||
| Sources | Rareté | Stats privilégié |
|
||||
|:--:|:--:|:--:|
|
||||
| Les plantes | Commune | INT, HAB |
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
---
|
||||
layout: layouts/base.njk
|
||||
title: L’herboristerie
|
||||
tags: Magies Communes
|
||||
models:
|
||||
- Magies Communes
|
||||
- Magies Rares
|
||||
parent: Les magies
|
||||
---
|
||||
|
||||
# L’herboristerie
|
||||
|
@ -9,6 +14,10 @@ title: L’herboristerie
|
|||
|
||||
L'herboristerie est sans doute la magie la moins magique. Elle tire son pouvoir de plantes particulières, les plantes élémentaires. Ces plantes sont alors mélangées pour créer des effets spéciaux dans des potions.
|
||||
|
||||
| Sources | Rareté | Stats privilégié |
|
||||
|:--:|:--:|:--:|
|
||||
| Les plantes | Commune | INT, HAB |
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -12,6 +12,10 @@ parent: Les magies
|
|||
|
||||
Les invocations sont un type de magie consistant à utiliser son encrage dans le monde physique pour invoquer un démon, une espèce proche des demi-dieux lié au *chaos* possédant un ou plusieurs pouvoirs démoniaques uniques.
|
||||
|
||||
| Sources | Rareté | Stats privilégié |
|
||||
|:--:|:--:|:--:|
|
||||
| Démons | Peu commune | VOL+CHA |
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -12,6 +12,12 @@ parent: Les magies
|
|||
|
||||
La magie naturelle est la magie consistant à utiliser à son avantage les forces de la nature et des animaux. Cette magie est grandement appréciée des gens n'ayant pas forcément de fort pouvoir magique, et peut s'apprendre en autodidacte par un fort contact avec la nature.
|
||||
|
||||
En Neustrie, les mages de la nature les plus réputés sont les *druides*.
|
||||
|
||||
| Sources | Rareté | Stats privilégié |
|
||||
|:--:|:--:|:--:|
|
||||
| Mère nature | Peu commun | REL |
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -12,6 +12,10 @@ parent: Les magies
|
|||
|
||||
La magie spirituelle, ou shamanisme, est la magie consistant à utiliser les pouvoirs des spectres, des êtres entièrement mentaux. Magie proche de la magie élémentaire, mais portant sur la magie métaphysique, et de la magie naturelle, on peut imaginer qu'elle s'est formé par un mélange des deux.
|
||||
|
||||
| Sources | Rareté | Stats privilégié |
|
||||
|:--:|:--:|:--:|
|
||||
| Les spectres et esprits | Peu commune | INT, HAB |
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
---
|
||||
layout: layouts/base.njk
|
||||
eleventyNavigation:
|
||||
key: Les niveaux
|
||||
parent: Classes et experiences
|
||||
order: 1
|
||||
---
|
||||
|
||||
# Les niveaux
|
||||
|
@ -10,8 +14,8 @@ Pour symboliser l'évolution d'un personnage, Erratum utilise un système de niv
|
|||
|
||||
Chaque augmentation de niveau donne :
|
||||
- Des augmentations ou modifications de pouvoirs
|
||||
- Des augmentations de compétences
|
||||
- Des augmentations de statistiques
|
||||
- Des *points de compétences* utilisable pour améliorer ses compétences
|
||||
- Des *points d'entrainement* utilisable pour améliorer ses statistiques
|
||||
|
||||
De plus, certains groupes de niveaux représentent des *rang* qui affecte quel genre de compétences sont disponibles, quels limites de stats sont possibles, etc.
|
||||
|
||||
|
@ -25,26 +29,35 @@ Un personnage peut gagner de niveau quand ces explois sont au delà de ce qu'on
|
|||
|
||||
Dans les cas trouble, il est possible de lancer un D100, et augmenter de niveau suivant un score défini par le MJ. L'augmentation de niveau est à voir par l'idée que le personnage à "atteint un nouveau palier", plus que "il a gagné +1 expérience" : il faut voir ça comme "après ce que vous avez fait, ouais c'est logique que vous soyez niveau 6".
|
||||
|
||||
## Augmentation des pouvoirs
|
||||
|
||||
Votre personnage reçoit pour chaque avancée de niveau *deux points de compétence* à dépenser pour obtenir une compétence, à l'exception des cinq niveaux suivants:
|
||||
|
||||
- Le niveau 8 où il obtient à la place son *pouvoir personnel*.
|
||||
- Le niveau 12 où il obtient à la place une *augmentation de puissance de 5 pouvoirs*.
|
||||
- Le niveau 15 où il améliore son *pouvoir personnel*.
|
||||
- Le niveau 19 où il obtient à la place une *augmentation de puissance de 5 nouveaux pouvoirs*.
|
||||
- Le niveau 20 où il améliore son *pouvoir personnel*.
|
||||
|
||||
Les augmentation de pouvoir permette d'améliorer les effets d'un des pouvoirs que possède le personnage.
|
||||
|
||||
### Pouvoir personnel
|
||||
|
||||
Le pouvoir personnel est une capacité signature que le personnage possède en combat. Cette capacité peut être passive ou active, et sera améliorable deux fois, la deuxième amélioration étant celle du niveau 20.
|
||||
|
||||
Ce pouvoir doit être lié de manière RP/logique au personnage, c'est à dire qu'elle doit être en accord avec ce qu'il fait, ses spécialités, ses traits de personnalités, sa façon de faire et/ou ses classes.
|
||||
|
||||
## Amélioration de compétence et statistiques
|
||||
|
||||
Chaque personnage obtient à chaque niveau *5 points d'entrainement*, qui peuvent être utiliser pour acquérir et augmenter des compétences et/ou des statistiques de la manière suivante :
|
||||
Chaque personnage obtient à chaque niveau *3 points de compétences* et *3 points d'entrainement*, qui peuvent être utiliser pour acquérir et augmenter des compétences et/ou des statistiques.
|
||||
|
||||
- Permet d'ajouter +10% à une compétence
|
||||
- Permet d'ajouter +5% à une statistiques
|
||||
- (Coute 2 point d'exp en supérieur à 100)
|
||||
- Permet d'ajouter +3 PE/PV à un personnage
|
||||
- Permet de diminuer ou augmenter d'un la pression
|
||||
- Permet de gagner un pouvoir d'une classe
|
||||
- Permet d'améliorer ou de personnaliser un pouvoir d'une classe (1/compétence)
|
||||
|
||||
En tout, un personnage utilisera 100 points d'expérience au court de son aventure.
|
||||
- Un point de compétence permet de gagner 10% à une compétence (dans les limites accessible au personnage à son niveau)
|
||||
- Un point d'entrainement permet de gagner soit 5% à une statistique, soit 3 PV ou PE, soit augmenter ou diminuer de 1 la pression du personnage
|
||||
|
||||
## Les rangs
|
||||
|
||||
Les rangs sont des groupes de niveaux débloquant des compétences et des pouvoirs. Il y a en tout six rangs.
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Niveaux | Rang | Niveau classe | Débloque | Max bonus PV/PE | Max compétence |
|
||||
|:-------:|:---:|:-------------:|:--------:|:---------------:|:--------------:|
|
||||
| 1 à 2 | D | Novice (1 et 2) | | +100% | 30% |
|
||||
|
@ -54,8 +67,6 @@ Les rangs sont des groupes de niveaux débloquant des compétences et des pouvoi
|
|||
| 16 à 18 | S | Ultime (6) | Potentiel+ | +500% | 50% |
|
||||
| 19, 20 | X | Ultime (6) | | +600% | 70% |
|
||||
|
||||
</div>
|
||||
|
||||
Les deux premiers rang, *D* et *C* représentent la plupart des "civils", ou personnes n'ayant pas obtenu des compétences incroyables dans leur domaine, ni vécus d'aventures.
|
||||
|
||||
## Classes de départ
|
||||
|
|
|
@ -17,14 +17,10 @@ Les balances tirent leur pouvoir de l'équilibre : que celui-ci soit entre les s
|
|||
|
||||
On rapproche pour ce fait de l'arcane de la justice, avec l'ide de manipuler les gains et les blessures.
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Symb | Autre nom | Arcanes | Alignement | Rareté | Stats privilégié | Couleur |
|
||||
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|
||||
| :libra: | Chien (asie), Maât (égypte) | Guérison et malice (Healer Trickster) | Ordre | Peu commun (05.5%) | SAG et INT | Vert |
|
||||
|
||||
</div>
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -17,14 +17,10 @@ Les béliers tirent leur pouvoir des autres, et des responsabilités qu'iels ont
|
|||
|
||||
Chef ou protecteur de l'ombre, ils sont des gardiens du troupeaux, ceux qui peuvent faire en sorte que c'est tous qui réussissent, et pas juste certains.
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Symb | Autre nom | Arcanes | Alignement | Rareté | Stats privilégié | Couleur |
|
||||
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|
||||
| :aries: | ??? (asie), ??? (égypte) | Protection et Guérison (Tank Soigneur) | Ordre | Peu commun (9.5%) | CON et REL | Or |
|
||||
|
||||
</div>
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -17,14 +17,10 @@ Le signe cancer, signe du phénotype, est un signe rare offrant le pouvoir de co
|
|||
|
||||
Cela dit, cela rend aussi leur soins dangereux pour ceux qui le subissent. Ils peuvent créer des soins particulièrement performant au prix d'effet secondaire redoutable. Il s'agit d'un signe rare et puissant.
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Symb | Autre nom | Arcanes | Alignement | Rareté | Stats privilégié | Couleur |
|
||||
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|
||||
| :cancer: | Rat (asie) | Guérison et Force (Soigneur DPS) | Chaos | Rare (01.2%) | INT et HAB | Gris |
|
||||
|
||||
</div>
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -17,14 +17,10 @@ Les capricornes tirent leur pouvoir des émotions et de leur puissance. En effet
|
|||
|
||||
Leur pouvoir les permet de se sortir de bien des situations, mais aussi d'être les plus à même à attaquer sur l'esprit. Politiciens, espions... Mais ils peuvent aussi être des aides quand ils le veulent. Telle est toute l'ambivalence de ceux qui contrôlent les émotions.
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Symb | Autre nom | Arcanes | Alignement | Rareté | Stats privilégié | Couleur |
|
||||
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|
||||
| :capricorn: | ??? (asie), ??? (égypte) | Malice et Force (Trickster DPS) | Chaos | Peu commun (10.0%) | REL et CHA | Orange |
|
||||
|
||||
</div>
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
@ -56,7 +52,7 @@ Leur pouvoir les permet de se sortir de bien des situations, mais aussi d'être
|
|||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|:---:|:--------:|:-----------------------------------------|
|
||||
| 5 | Nudisme | Créer une émotion provoquant l’effet « Nudisme » à la cible, pour un seul tour. La cible peut ensuite prendre un tour pour les rééquiper. L'action se résiste sur un jet de SAG ou VOL dégressif, à -10/tour. |
|
||||
| 5 | Nudisme | Donne l’effet « Nudisme » à la cible. |
|
||||
| 5 | Nan mais là faut se calmer | Sur un jet de CHA ou REL, peut tenter de stopper l’action d’un autre PJ, même si celle-ci est entamée. Si celui-ci n’a pas agit de son chef, il doit faire un jet de CHA opposé pour resister ou non. S’il a agit de son chef, peut choisir d’écouter la petite voix dans sa tête. (II : L’adversaire à un malus de 30 % pour résister) |
|
||||
| 5 | Émotion+ | Passe les afflictions mentales provoquées au niveau supérieur |
|
||||
|
||||
|
|
|
@ -17,14 +17,10 @@ Les gémeaux sont à la fois un seul être et plusieurs, un corps et un esprit d
|
|||
|
||||
Le dédoublement provoque cependant toujours un effet : l'esprit étant étendu entre deux corps (que ce soit sous la forme d'un ou deux esprits), il a le pouvoir de s'étendre encore plus sur tout ce qui entoure, et d'affecter tout ce qui entoure.
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Symb | Autre nom | Arcanes | Alignement | Rareté | Stats privilégié | Couleur |
|
||||
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|
||||
| :gemini: | ??? (asie), ??? (égypte) | Malice et Guérison (Trickster Healer) | Chaos | Commun (15.0%) | VOL et INT | Indigo |
|
||||
|
||||
</div>
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -21,8 +21,6 @@ Le serpentaire n'a pas de hérault.
|
|||
|
||||
Les 12 **héraults de signes** permettent d'obtenir les pouvoirs de herault de chaque signe.
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Signe | Hérault | Description | Période | Localisation |
|
||||
|:-----:|:-------:|:-----------:|:-------:|:------------:|
|
||||
| Cancer | **Ibn Sina** (Avicenne) | Fondateur de la médecine moderne | 10~11e siècle | Hamadan |
|
||||
|
@ -38,14 +36,10 @@ Les 12 **héraults de signes** permettent d'obtenir les pouvoirs de herault de c
|
|||
| Capricorne | **Médée** | Héroine et sorcière grecque, ayant aidé et été trahie par les Argonaute | 17e siècle avant JC | Méditérannée |
|
||||
| Poisson | **?????** | Hérault inconnu⋅e. On raconte que son temple est entièrement une illusion. | ??? | Partout |
|
||||
|
||||
</div>
|
||||
|
||||
## Hérault d'Arcane
|
||||
|
||||
Les **hérault d'Arcane** ou **Grand-Hérault** sont quatre être ayant maitrisé tout les aspect d'une arcane, et pouvant donc offrir des nouveaux pouvoir à un⋅e manipulateur⋅ice de ladite arcane. Ces quatre êtres sont à la limite entre divinité et humanité. Ils sont aux nombres de 4.
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Arcane | Hérault | Description | Période | Localisation |
|
||||
|:-----:|:-------:|:-----------:|:-------:|:------------:|
|
||||
| Guérison | **Nokomis** (Grand-Mère Feuillage) | Danaïte mythique devenu une avec la nature | Ancestrale | Amérique du Nord |
|
||||
|
@ -53,8 +47,6 @@ Les **hérault d'Arcane** ou **Grand-Hérault** sont quatre être ayant maitris
|
|||
| Protection | **Hervor** | Grande héroïne Skjaldmö ayant pu jusqu'à rivaliser avec les valkyrie | 4e siècle | Scandinavie |
|
||||
| Malice | **Maui** | Grand trickster et protecteur des hommes en polynésies et dans tout le pacifique | -3000 | Polynésie |
|
||||
|
||||
</div>
|
||||
|
||||
### Pouvoirs des Héraults
|
||||
|
||||
| Arcane | Pouvoirs | Effet |
|
||||
|
@ -70,8 +62,6 @@ Les **hérault d'Arcane** ou **Grand-Hérault** sont quatre être ayant maitris
|
|||
|
||||
Les 12 heraults permettent d'obtenir les pouvoirs de herault de chaque signe.
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Signe | Hérault | Description | Période | Localisation |
|
||||
|:-----:|:-------:|:-----------:|:-------:|:------------:|
|
||||
| Cancer | **Ibn Sina** (Avicenne) | Fondateur de la médecine moderne | 10~11e siècle | Hamadan |
|
||||
|
@ -86,5 +76,3 @@ Les 12 heraults permettent d'obtenir les pouvoirs de herault de chaque signe.
|
|||
| Gémeaux | **Xolotl** | Frère jumeaux du dieu Quetzacoatl | 10e siècle | Mexique |
|
||||
| Capricorne | **Socrate** | Philosophe, et un peu un troll aussi | 5e siècle avant JC | Grèce |
|
||||
| Poisson | **?????** | Hérault inconnu⋅e. On raconte que son temple est entièrement une illusion. | ??? | Partout |
|
||||
|
||||
</div>
|
|
@ -19,14 +19,10 @@ Ils sont plus fort quand ils sont en danger, et leur pouvoirs permettent de se b
|
|||
|
||||
Leur herault est Gilgamesh, le roi-héros, aux exploits légendaires qui ont transcendé l'histoire et les légendes, vers -3000.
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Symb | Autre nom | Arcanes | Alignement | Rareté | Stats privilégié | Couleur |
|
||||
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|
||||
| :leo: | Tigre (asie), ??? (égypte) | Force et Protection (DPS Tank) | Ordre | Rare (02.2%) | CHA, FOR et VOL | Rouge |
|
||||
|
||||
</div>
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -17,14 +17,10 @@ Les poissons tirent leur pouvoir des apparences, des mystères et du spectacle.
|
|||
|
||||
Leur pouvoir est celui des illusions. Ils se protègent en n'étant pas présent là où vous attaquez. Ils vous font voir des choses fausses... Mais est-ce forcément offensif ? Ne peuvent-ils pas aussi être les aêdes dont les récit peuples votre imaginaire ?
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Symb | Autre nom | Arcanes | Alignement | Rareté | Stats privilégié | Couleur |
|
||||
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|
||||
| :pisces: | Singe (asie), Seth (égypte) | Malice et Protection (Trickster Tank) | Chaos | Rare (1.9%) | DIS | Pourpre |
|
||||
|
||||
</div>
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -17,14 +17,10 @@ Les sagittaire tirent leur pouvoir du mouvement et de la vitesse. Capable d'effe
|
|||
|
||||
Rapide, précis, cette maitrise les rendent généralement cependant plutôt fragile et ils privilégie un grand nombre d'action de faible puissance comparé à une seule action extrèmement forte.
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Symb | Autre nom | Arcanes | Alignement | Rareté | Stats privilégié | Couleur |
|
||||
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|
||||
| :sagittarius: | ??? (asie), ??? (égypte) | Force et Malice (DPS Trickster) | Ordre | Commun (12.0%) | HAB et PER | Turquoise |
|
||||
|
||||
</div>
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -17,14 +17,10 @@ Les scorpions tirent leurs pouvoirs des poisons. Ils deviennent capables d'en s
|
|||
|
||||
Ils sont aussi bien médecins comme attaquants ; ne dit-on pas que les médecines ne sont que des poisons bien utilisés ?
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Symb | Autre nom | Arcanes | Alignement | Rareté | Stats privilégié | Couleur |
|
||||
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|
||||
| :scorpius: | Serpent (asie), ??? (égypte) | Force et Guérison (DPS Soigneur) | Chaos | Commun (15.0%) | HAB | Violet sombre |
|
||||
|
||||
</div>
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
|
@ -17,14 +17,10 @@ Le serpentaire est le 13 signes, le signe inconnu, celui qui ne devrait pas exis
|
|||
|
||||
Le serpentaire n'est en fait pas un signe. Il est un méta-signe. Il permet de contrôler les flux même de la magie.
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
| Symb | Autre nom | Arcanes | Alignement | Rareté | Stats privilégié | Couleur |
|
||||
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|
||||
| :ophiuchus: | ??? (asie), ??? (égypte) | Hors du système | Éclat | Exceptionnel | SAG et VOL | Toutes/blanc. |
|
||||
|
||||
</div>
|
||||
|
||||
## Pouvoir de base
|
||||
|
||||
| Niv | Pouvoirs | Effet |
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue