rewrite of the Lua module system.

At this time, only E2 is working.
Fixing a lot of old code (monster is no longer id 0).
package.paths configured from eressea.ini
install directory configured from eressea.ini
moving building_action into a seaprate module (it's deprecated)
This commit is contained in:
Enno Rehling 2014-07-26 22:52:25 +02:00
parent 44327d91f6
commit d9457a2488
37 changed files with 727 additions and 739 deletions

View File

@ -8,7 +8,8 @@ memcheck = 0
locales = de,en
[config]
source_dir = ..
paths = lunit
install = .
maxnmrs = 10
[editor]

View File

@ -1,50 +0,0 @@
-- Enno was here
require "multis"
function process(orders)
local confirmed_multis = { }
local suspected_multis = { }
if open_game(get_turn())~=0 then
print("could not read game")
return -1
end
init_summary()
-- kill multi-players (external script)
kill_multis(confirmed_multis, false)
mark_multis(suspected_multis, false)
-- run the turn:
if read_orders(orders) ~= 0 then
print("could not read " .. orders)
return -1
end
-- plan_monsters()
if nmr_check(config.maxnmrs or 80)~=0 then
return -1
end
process_orders()
-- create new monsters:
spawn_braineaters(0.25)
-- post-turn updates:
update_guards()
update_scores()
local localechange = { de = { "ii" } }
change_locales(localechange)
write_files(config.locales)
file = "" .. get_turn() .. ".dat"
if write_game(file, "binary")~=0 then
print("could not write game")
return -1
end
return 0
end

View File

@ -1,12 +0,0 @@
require "spells"
require "arda.rules"
local srcpath = config.source_dir
tests = {
-- srcpath .. '/eressea/scripts/tests/bson.lua',
srcpath .. '/eressea/scripts/tests/spells.lua',
srcpath .. '/eressea/scripts/tests/common.lua',
srcpath .. '/eressea/scripts/tests/orders.lua',
srcpath .. '/eressea/scripts/tests/bindings.lua',
srcpath .. '/scripts/tests/rules.lua',
}

View File

@ -1,8 +0,0 @@
function item_canuse(u, iname)
local race = u.race
if iname=="greatbow" then
-- only elves use greatbow
return race=="elf"
end
return true
end

View File

@ -1,37 +0,0 @@
require "callbacks"
require "dumptable"
local function trigger_alp_destroyed(alp, event)
m = message.create("alp_destroyed")
m:set_region("region", alp.region)
m:send_faction(alp.faction)
end
local function trigger_alp_dissolve(u, event, attr)
local alp = attr.alp
attr.alp.number = 0 -- kills the alp
end
local function init_alp(attr)
-- dumptable(attr)
eventbus.register(attr.alp, "destroy", trigger_alp_destroyed)
eventbus.register(attr.mage, "destroy", trigger_alp_dissolve, attr)
eventbus.register(attr.target, "destroy", trigger_alp_dissolve, attr)
end
callbacks["init_alp"] = init_alp
-- Spell: summon alp
function summon_alp(r, mage, level, force, params)
local alp = unit.create(mage.faction, r, 1, "alp")
local target = params[1]
alp:set_skill("stealth", 7)
alp.status = 5 -- FLEE
attr = attrib.create(alp, { ['name'] = 'alp', ['target'] = target, ['alp'] = alp, ['mage'] = mage })
init_alp(attr)
msg = message.create("summon_alp_effect")
m:set_unit("mage", mage)
m:set_unit("alp", alp)
m:set_unit("target", target)
m:send_faction(mage.faction)
end

View File

@ -1,30 +1,41 @@
-- Muschelplateau
local embassy = {}
local home = nil
-- global exports (use item)
function use_seashell(u, amount)
-- Muschelplateau...
local r = get_region(165,30)
local visit = u.faction.objects:get("embassy_muschel")
if visit~=nil and u.region~= r then
local turns = get_turn() - visit
local msg = message.create("msg_event")
msg:set_string("string", u.name .. "(" .. itoa36(u.id) .. ") erzählt den Bewohnern von " .. u.region.name .. " von Muschelplateau, das die Partei " .. u.faction.name .. " vor " .. turns .. " Wochen besucht hat." )
msg:send_region(u.region)
return 0
end
return -4
end
function update_embassies()
-- Muschelplateau
local r = get_region(165,30)
if r~=nil then
local u
for u in r.units do
if u.faction.objects:get("embassy_muschel")==nil then
if (u.faction:add_item("seashell", 1)>0) then
print(u.faction)
u.faction.objects:set("embassy_muschel", get_turn())
end
end
local visit = u.faction.objects:get("embassy_muschel")
if visit and u.region~= home then
local turns = get_turn() - visit
local msg = message.create('msg_event')
msg:set_string("string", u.name .. "(" .. itoa36(u.id) .. ") erzählt den Bewohnern von " .. u.region.name .. " von Muschelplateau, das die Partei " .. u.faction.name .. " vor " .. turns .. " Wochen besucht hat." )
msg:send_region(u.region)
return 0
end
end
return -4
end
function embassy.init()
home = get_region(165,30)
if home==nil then
eressea.log.error("cannot find embassy region 'Muschelplateau'")
end
end
function embassy.update()
-- Muschelplateau
eressea.log.debug("updating embassies in " .. tostring(home))
local u
for u in home.units do
if u.faction.objects:get('embassy_muschel')==nil then
if (u.faction:add_item('seashell', 1)>0) then
eressea.log.debug("new seashell for " .. tostring(u.faction))
u.faction.objects:set('embassy_muschel', get_turn())
end
end
end
end
return embassy

View File

@ -1,32 +1,34 @@
local function create_ents(r, number)
local f = get_faction(0)
if f~=nil and number>0 then
u = add_unit(f, r)
u.number = number
u.name = "Wütende Ents"
u:set_skill("perception", 2)
msg = message.create("entrise")
msg:set_region("region", r)
msg:send_region(r)
return u
end
return nil
local f = get_faction(666)
if f~=nil and number>0 then
u = unit.create(f, r, number)
u.name = "Wütende Ents"
u:set_skill("perception", 2)
msg = message.create("entrise")
msg:set_region("region", r)
msg:send_region(r)
return u
end
return nil
end
function spawn_ents()
local r
for r in regions() do
if r:get_flag(0) then -- RF_CHAOTIC
if r.terrain == "plain" and r:get_resource("tree")==0 then
if math.random(3)==1 then
u = create_ents(r, math.random(30))
if u ~= nil then
r:set_resource("tree", u.number)
end
local ents = {}
function ents.update()
local r
for r in regions() do
if r:get_flag(0) then -- RF_CHAOTIC
if r.terrain == "plain" and r:get_resource("tree")==0 then
if math.random(3)==1 then
u = create_ents(r, math.random(30))
if u ~= nil then
r:set_resource("tree", u.number)
end
end
end
end
end
end
end
end
return ents

View File

@ -1,18 +1,36 @@
require "gates"
-- DEPRECATED
local function eternath_exchange(b1, b2, size)
local units1 = gate_units(b1, size)
local units2 = gate_units(b2, size)
-- implements parts of a quest in E2
-- this module is deprecated, because it puts functions in the global environment for at_building_action
gate_travel(b2, units1)
gate_travel(b1, units2)
end
local gates = require('eressea.gates')
local b1 = nil
local b2 = nil
function eternathgate_action(b)
if eternathgate == nil then
eternathgate = b
if b1 == nil then
b1 = b
elseif b2 == nil then
b2 = b
else
eternath_exchange(eternathgate, b, 10)
eressea.log.error("data contains more than two Ethernath gates")
end
return 1
end
local eternath = {}
function eternath.update()
if b1 and b2 then
local units1 = gates.units(b1, size)
local units2 = gates.units(b2, size)
gates.travel(b2, units1)
gates.travel(b1, units2)
else
eressea.log.error("data contains fewer than two Ethernath gates")
end
end
return eternath

View File

@ -1,59 +0,0 @@
function teleport_all(map, grave)
print("- teleporting all quest members to the grave")
local index
local r
for index, r in pairs(map) do
local u
for u in r.units do
u.region = grave
print (" .teleported " .. u.name)
grave:add_notice("Ein Portal öffnet sich, und " .. u.name .. " erscheint in " .. grave.name)
end
end
end
function wyrm()
print("- running the wyrm quest")
local grave = get_region(-9995,4)
local plane = get_plane_id("arena")
local map = {}
local mapsize = 0
local r
for r in regions() do
if r.plane_id==plane then
mapsize=mapsize+1
map[mapsize] = r
end
end
local u
for u in grave.units do
if u.faction.id~=atoi36("rr") then
teleport_all(map, grave)
break
end
end
local index
local r
for index, r in pairs(map) do
if r~=grave then
if (math.fmod(r.x,2)==math.fmod(get_turn(),2)) then
r:add_notice("Eine Botschaft von Igjarjuk, Herr der Wyrme: 'Die Zeit des Wartens ist beinahe vorrüber. Euer Fürst kehrt aus dem Grabe zurück.'")
else
r:add_notice("Eine Botschaft von Gwaewar, Herr der Greife: 'Das Ende naht. Igjarjuk ist aus seinem Grab auferstanden. Eilt, noch ist die Welt zu retten!'")
end
end
end
local gryph=get_unit(atoi36("gfd4"))
local igjar=get_unit(atoi36("igjr"))
if grave~=nil and gryph~=nil and igjar~=nil then
gryph.region=grave
igjar.region=grave
grave:add_notice("Eine Botschaft von Gwaewar, Herr der Greife: 'Ihr, die Ihr die Strapazen der letzten Jahre überstanden habt: Lasst nicht zu, dass Igjarjuk wieder in die Welt der Lebenden zurückkehrt. Vernichtet das Auge - jetzt und hier!'")
grave:add_notice("Eine Botschaft von Igjarjuk, Herr der Wyrme: 'Gwaewar, Du wirst dereinst an Deinem Glauben an das Gute in den Sterblichen verrecken... So wie ich es einst tat. Der Krieg ist die einzige Sprache die sie verstehen, und derjenige, der mir hilft, wird ihn gewinnen.'")
end
end

View File

@ -1,19 +0,0 @@
function use_ring_of_levitation(u, amount)
if u.ship~=nil and amount>0 then
local mallorn = 0
for u2 in u.region.units do
if u2.ship==u.ship then
local i = u2:get_item("mallornseed")
if i>0 then
u2:use_pooled("mallornseed", i)
u2:use_pooled("seed", i)
mallorn = mallorn + i
end
end
end
if mallorn>0 then
levitate_ship(u.ship, u, mallorn, 2)
end
end
return 0
end

View File

@ -1,63 +0,0 @@
require "multis"
function apply_fixes()
local turn = get_turn()
if config.rules=="eressea" and turn>654 and turn<662 then
print("Fixing familiars")
fix_familiars()
end
end
function process(orders)
local confirmed_multis = { }
local suspected_multis = { }
if open_game(get_turn())~=0 then
print("could not read game")
return -1
end
apply_fixes()
init_summary()
-- kill multi-players (external script)
kill_multis(confirmed_multis, false)
mark_multis(suspected_multis, false)
-- run the turn:
if read_orders(orders) ~= 0 then
print("could not read " .. orders)
return -1
end
plan_monsters()
if nmr_check(config.maxnmrs or 80)~=0 then
return -1
end
process_orders()
-- create new monsters:
spawn_dragons()
spawn_undead()
spawn_braineaters(0.25)
spawn_ents()
-- post-turn updates:
update_xmas2006()
update_embassies()
update_guards()
update_scores()
local localechange = { de = { "ii" } }
change_locales(localechange)
write_files(config.locales)
file = "" .. get_turn() .. ".dat"
if eressea.write_game(file)~=0 then
print("could not write game")
return -1
end
return 0
end

View File

@ -1,25 +0,0 @@
require "spells"
require "gates"
require "eressea.alp"
require "eressea.eternath"
require "eressea.wedding-jadee"
require "eressea.ponnuki"
require "eressea.items"
require "eressea.rules"
-- require "eressea.10years"
require "eressea.xmas2004"
require "eressea.xmas2005"
require "eressea.xmas2006"
require "eressea.embassy"
require "eressea.tunnels"
require "eressea.ents"
local srcpath = config.source_dir
tests = {
srcpath .. '/core/scripts/tests/common.lua',
srcpath .. '/core/scripts/tests/spells.lua',
-- srcpath .. '/eressea/scripts/tests/bson.lua',
srcpath .. '/scripts/tests/spells.lua',
srcpath .. '/scripts/tests/spells-e2.lua',
srcpath .. '/scripts/tests/eressea.lua',
}

View File

@ -1,42 +1,43 @@
function ponnuki_brain(u)
jokes = {
local ponnuki = {}
local directions = { "NW", "NO", "O", "SO", "SW", "W" }
local jokes = {
"Ein Bummerang ist, wenn man ihn wegwirft und er kommt nicht wieder, dann war's keiner.",
"Merke: Mit Schwabenwitzen soll man ganz sparsam sein.",
"Was bekommt man, wenn man Katzen und Elfen kreuzt? Elfen ohne Rheuma.",
"Was bekommt man, wenn man Insekten und Katzen kreuzt? Tiger, die Crisan benutzen."
}
}
local function ponnuki_brain(u)
local i = math.random(table.getn(jokes))
u.region:add_notice(jokes[i])
u:add_notice("Eine Botschaft von " .. tostring(u) .. ": " ..jokes[i])
local d = math.random(6)
r = u.region:next(d-1)
local r = u.region:next(d-1)
u:clear_orders()
directions = { "NW", "NO", "O", "SO", "SW", "W" }
u:add_order("NACH " .. directions[d])
end
local function init_ponnuki(home)
local f = get_faction(0)
local u = get_unit(atoi36("ponn"))
if u == nil then
u = add_unit(f, home)
u.id = atoi36("ponn")
u.name = "Ponnuki"
u.info = "Go, Ponnuki, Go!"
u.race = "illusion"
u:set_racename("Ritter von Go")
end
if u.faction==f then
set_unit_brain(u, ponnuki_brain)
end
end
-- initialize other scripts
local magrathea = get_region(-67, -5)
if magrathea~=nil and init_ponnuki~=nil then
init_ponnuki(magrathea)
return
function ponnuki.init()
-- initialize other scripts
local u = get_unit(atoi36("ponn"))
if not u then
eressea.log.error("Ponnuki is missing, will re-create")
local home = get_region(-67, -5)
local f = get_faction(666)
if home and f then
u = add_unit(f, home)
u.id = atoi36("ponn")
u.name = "Ponnuki"
u.info = "Go, Ponnuki, Go!"
u.race = "illusion"
u:set_racename("Ritter von Go")
else
eressea.log.error("Ponnuki cannot find Magrathea")
end
end
if u then
ponnuki_brain(u)
end
end
return ponnuki

View File

@ -1,8 +0,0 @@
function item_canuse(u, iname)
-- local race = u.race
-- if iname=="greatbow" then
-- -- only elves use greatbow
-- return race=="elf"
-- end
return true
end

View File

@ -1,3 +1,8 @@
local tunnels = {}
local buildings = {}
local targets = {}
local function tunnel_travelers(b)
local units = nil
for u in b.units do
@ -9,44 +14,23 @@ local function tunnel_travelers(b)
return units
end
targets = nil
ntargets = 0
local function get_target(param)
-- print("finding targets: " .. param)
if targets == nil then
targets = {}
local r
for r in regions() do
if r:get_key(param) then
if (r:get_flag(0)) then
r:set_flag(0, false)
end
if (r.terrain=="ocean") then
r = region.create(r.x, r.y, "plain")
end
targets[ntargets] = r
ntargets = ntargets + 1
-- print("target: " .. tostring(r))
end
local ntargets = table.maxn(targets)
if ntargets==0 then
return nil
end
end
if ntargets==0 then
return nil
end
local rn = math.fmod(rng_int(), ntargets)
return targets[rn]
local rn = math.fmod(rng_int(), ntargets)
return targets[rn]
end
-- export, will be called from lc_age()
function tunnel_action(b, param)
local function tunnel_action(b, param)
local r = nil
if tonumber(param)~=nil then
r = get_region_by_id(tonumber(param))
end
local units = tunnel_travelers(b)
if units~=nil then
print("Tunnel from " .. tostring(b) .. " [" .. param .. "]")
eressea.log.debug("Tunnel from " .. tostring(b) .. " [" .. param .. "]")
for key, u in pairs(units) do
local rto = r
if r==nil then
@ -54,9 +38,39 @@ function tunnel_action(b, param)
end
if rto~=nil then
u.region = rto
print(" - teleported " .. tostring(u) .. " to " .. tostring(rto))
eressea.log.debug("teleported " .. tostring(u) .. " to " .. tostring(rto))
end
end
end
return 1 -- return 0 to destroy
end
function tunnels.init()
local r, b
for r in regions() do
if r:get_key('tnnL') then
targets[table.maxn(targets)+1] = r
if (r:get_flag(0)) then
-- target region is chaotic? nope.
r:set_flag(0, false)
end
if (r.terrain=="ocean") then
eressea.log.warning("tunnel target at " .. r.x .. "," .. r.y .. " is an ocean, terraforming")
r = region.create(r.x, r.y, "plain")
end
end
for b in r.buildings do
if b.type == 'portal' then
buildings[table.maxn(buildings)+1] = b
end
end
end
end
function tunnels.update()
for i, b in ipairs(buildings) do
tunnel_action(b, 'tnnL')
end
end
return tunnels

View File

@ -1,47 +0,0 @@
-- this script contains the action functions for the two portals
-- used on the jadee/wildente wedding island. the two _action functions
-- are used as age() functions for a building_action with b:addaction("name")
if gate_travel==nil then
loadscript("gates.lua")
end
hellgate = nil
peacegate = nil
local function wedding_travellers(b)
local units = {}
for u in b.units do
if u:get_flag("wdgt") then
units[u] = u
end
end
return units
end
local function wedding_exchange(b1, b2)
local units1 = wedding_travellers(b1)
local units2 = wedding_travellers(b2)
gate_travel(b2, units1)
gate_travel(b1, units2)
end
function hellgate_action(b)
if hellgate == nil then
hellgate = b
else
wedding_exchange(hellgate, b)
end
return 1
end
function peacegate_action(b)
if peacegate == nil then
peacegate = b
else
wedding_exchange(peacegate, b)
end
return 1
end

View File

@ -9,17 +9,17 @@ function use_snowman(u, amount)
return -4
end
function xmas2004()
if get_gamename() == "Eressea" then
local self = {}
function self.update()
if not get_key("xm04") then
print("Es weihnachtet sehr (2004)")
set_key("xm04", true)
for f in factions() do
f:add_item("speedsail", 1)
f:add_notice("santa2004")
end
eressea.log.debug("Es weihnachtet sehr (2004)")
set_key("xm04", true)
for f in factions() do
f:add_item("speedsail", 1)
f:add_notice("santa2004")
end
end
end
end
-- xmas2004()
return self

View File

@ -15,17 +15,17 @@ function use_stardust(u, amount)
return 0
end
function xmas2005()
if get_gamename() == "Eressea" then
if not get_flag("xm05") then
print("Es weihnachtet sehr (2005)")
set_flag("xm05", true)
for f in factions() do
f:add_item("stardust", 1)
f:add_notice("santa2005")
end
local self = {}
function self.update()
if not get_key("xm05") then
print("Es weihnachtet sehr (2005)")
set_key("xm05", true)
for f in factions() do
f:add_item("stardust", 1)
f:add_notice("santa2005")
end
end
end
end
-- xmas2005()
return self

View File

@ -8,11 +8,13 @@ function use_xmastree(u, amount)
return 0
end
function update_xmas2006()
local self = {}
function self.update()
local turn = get_turn()
local season = get_season(turn)
if season == "calendar::winter" then
print("it is " .. season .. ", the christmas trees do their magic")
eressea.log.debug("it is " .. season .. ", the christmas trees do their magic")
local msg = message.create("xmastree_effect")
for r in regions() do
if r:get_key("xm06") then
@ -38,17 +40,15 @@ function update_xmas2006()
end
end
function xmas2006()
if get_gamename() == "Eressea" then
function self.init()
if not get_key("xm06") then
print("Es weihnachtet sehr (2006)")
set_key("xm06", true)
for f in factions() do
f:add_item("xmastree", 1)
f:add_notice("santa2006")
end
print("Es weihnachtet sehr (2006)")
set_key("xm06", true)
for f in factions() do
f:add_item("xmastree", 1)
f:add_notice("santa2006")
end
end
end
end
-- xmas2006()
return self

15
scripts/run-tests.lua Normal file
View File

@ -0,0 +1,15 @@
-- new tests 2014-06-11
path = 'scripts'
if config.source_dir ~= nil then
path = config.source_dir .. '\\' .. path
end
package.path = package.path .. ';' .. path .. '\\?.lua;' .. path .. '\\?\\init.lua'
-- require 'eressea.tests'
if config.rules ~= nil then
require ('eressea.' .. config.rules .. '.tests')
end
require 'lunit'
lunit.main()

193
scripts/run-turn.lua Normal file
View File

@ -0,0 +1,193 @@
function nmr_check(maxnmrs)
local nmrs = get_nmrs(1)
if nmrs >= maxnmrs then
eressea.log.error("Shit. More than " .. maxnmrs .. " factions with 1 NMR (" .. nmrs .. ")")
write_summary()
eressea.write_game("aborted.dat")
return -1
end
print (nmrs .. " Factions with 1 NMR")
return 0
end
function open_game(turn)
file = "" .. get_turn()
return eressea.read_game(file .. ".dat")
end
function callbacks(rules, name, ...)
for k, v in pairs(rules) do
if 'table' == type(v) then
cb = v[name]
if 'function' == type(cb) then
cb(...)
end
end
end
end
local function change_locales(localechange)
for loc, flist in pairs(localechange) do
for index, name in pairs(flist) do
f = get_faction(atoi36(name))
if f ~= nil and f.locale ~= loc then
f.locale = loc
print("LOCALECHANGE ", f, loc)
end
end
end
end
local function dbupdate()
update_scores()
edb = db.open(config.basepath.."/eressea.db")
if edb~=nil then
edb:update_factions()
edb:update_scores()
else
eressea.log.error("could not open "..config.basepath.."/eressea.db")
end
end
local function write_emails(locales)
local files = {}
local key
local locale
local file
for key, locale in pairs(locales) do
files[locale] = io.open(config.basepath .. "/emails." .. locale, "w")
end
local faction
for faction in factions() do
if faction.email~="" then
files[faction.locale]:write(faction.email .. "\n")
end
end
for key, file in pairs(files) do
file:close()
end
end
local function write_addresses()
local file
local faction
file = io.open(config.basepath .. "/adressen", "w")
for faction in factions() do
-- print(faction.id .. " - " .. faction.locale)
file:write(tostring(faction) .. ":" .. faction.email .. ":" .. faction.info .. "\n")
end
file:close()
end
local function write_aliases()
local file
local faction
file = io.open(config.basepath .. "/aliases", "w")
for faction in factions() do
local unit
if faction.email ~= "" then
file:write("partei-" .. itoa36(faction.id) .. ": " .. faction.email .. "\n")
for unit in faction.units do
file:write("einheit-" .. itoa36(unit.id) .. ": " .. faction.email .. "\n")
end
end
end
file:close()
end
local function write_files(locales)
write_passwords()
write_reports()
write_summary()
end
local function write_scores()
local scores = {}
for r in regions() do
f = r.owner
if f~=nil then
value = scores[f.id]
if value==nil then value=0 end
value = value + r:get_resource("money")/100
scores[f.id] = value
end
end
for f in factions() do
score=scores[f.id]
if score==nil then score=0 end
print(math.floor(score)..":"..f.name..":"..itoa36(f.id))
end
end
function process(rules, orders)
local confirmed_multis = { }
local suspected_multis = { }
if open_game(get_turn())~=0 then
eressea.log.error("could not read game")
return -1
end
callbacks(rules, 'init')
init_summary()
-- run the turn:
if read_orders(orders) ~= 0 then
print("could not read " .. orders)
return -1
end
plan_monsters()
if nmr_check(config.maxnmrs or 80)~=0 then
return -1
end
process_orders()
callbacks(rules, 'update')
local localechange = { de = { 'ii' } }
change_locales(localechange)
write_files(config.locales)
file = '' .. get_turn() .. '.dat'
if eressea.write_game(file)~=0 then
eressea.log.error("could not write game")
return -1
end
return 0
end
function run_turn(rules)
local turn = get_turn()
if turn<0 then
turn = read_turn()
set_turn(turn)
end
orderfile = orderfile or config.basepath .. '/orders.' .. turn
eressea.log.debug("executing turn " .. get_turn() .. " with " .. orderfile .. " with rules=" .. config.rules)
local result = process(rules, orderfile)
if result==0 then
dbupdate()
end
return result
end
path = 'scripts'
if config.source_dir ~= nil then
path = config.source_dir .. '\\' .. path
end
package.path = package.path .. ';' .. path .. '\\?.lua;' .. path .. '\\?\\init.lua'
rules = require('eressea.' .. config.rules)
read_xml()
run_turn(rules)

View File

@ -1,6 +0,0 @@
-- new tests 2014-06-11
require "lunit"
require "tests"
lunit.main()

View File

@ -1,15 +0,0 @@
local srcpath = config.source_dir
local respath = srcpath .. '/res'
local paths = {
'scripts/?.lua',
'core/scripts/?.lua',
'lunit/?.lua'
}
for idx, path in pairs(paths) do
package.path = srcpath .. '/' .. path .. ';' .. package.path
end
read_xml()
require "init"

View File

@ -0,0 +1,25 @@
-- adamant gifts and setup for tunnels
-- use only once to hand out some items to existing factions
function adamant_gifts()
for f in factions() do
local i = math.fmod(test.rng_int(), 2)
if i==0 then
f:add_item("adamantium", 1)
f:add_item("adamantiumplate", 1)
else
f:add_item("adamantium", 3)
f:add_item("adamantiumaxe", 1)
end
end
end
function adamant_seeds()
for r in regions() do
if r:get_key("tnnL") then
print("1 ", r:get_resource("adamantium"), r)
test.adamantium_island(r)
print("2 ", r:get_resource("adamantium"))
end
end
end

View File

@ -1,29 +1,3 @@
-- adamant gifts and setup for tunnels
-- use only once to hand out some items to existing factions
function adamant_gifts()
for f in factions() do
local i = math.fmod(test.rng_int(), 2)
if i==0 then
f:add_item("adamantium", 1)
f:add_item("adamantiumplate", 1)
else
f:add_item("adamantium", 3)
f:add_item("adamantiumaxe", 1)
end
end
end
function adamant_seeds()
for r in regions() do
if r:get_key("tnnL") then
print("1 ", r:get_resource("adamantium"), r)
test.adamantium_island(r)
print("2 ", r:get_resource("adamantium"))
end
end
end
-- create a fixed path to a specific region
local function create_path(from, to)
local param = tostring(to.uid)

View File

@ -90,6 +90,7 @@ set (ERESSEA_SRC
set(SERVER_SRC
main.c
building_action.c
console.c
helpers.c
config.pkg.c

View File

@ -38,17 +38,6 @@ int tolua_buildinglist_next(lua_State * L)
return 0; /* no more values to return */
}
static int tolua_building_addaction(lua_State * L)
{
building *self = (building *) tolua_tousertype(L, 1, 0);
const char *fname = tolua_tostring(L, 2, 0);
const char *param = tolua_tostring(L, 3, 0);
building_addaction(self, fname, param);
return 0;
}
static int tolua_building_get_objects(lua_State * L)
{
building *self = (building *) tolua_tousertype(L, 1, 0);
@ -253,7 +242,6 @@ void tolua_building_open(lua_State * L)
tolua_building_set_region);
tolua_variable(L, TOLUA_CAST "size", tolua_building_get_size,
tolua_building_set_size);
tolua_function(L, TOLUA_CAST "add_action", tolua_building_addaction);
tolua_function(L, TOLUA_CAST "get_typename", tolua_building_get_typename);
#ifdef TODO
.property("type", &building_gettype)

View File

@ -1222,6 +1222,12 @@ int eressea_run(lua_State *L, const char *luafile)
global.vm_state = L;
/* run the main script */
if (luafile) {
const char * install = iniparser_getstring(global.inifile, "eressea:install", 0);
char path[MAX_PATH];
if (install) {
_snprintf(path, sizeof(path), "%s/%s", install, luafile);
luafile = path;
}
log_debug("executing script %s\n", luafile);
lua_getglobal(L, "debug");

163
src/building_action.c Normal file
View File

@ -0,0 +1,163 @@
/* vi: set ts=2:
+-------------------+
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
| | Henning Peters <faroul@beyond.kn-bremen.de>
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#include <platform.h>
#include <kernel/config.h>
#include <kernel/building.h>
#include <kernel/version.h>
#include <util/attrib.h>
#include <util/log.h>
#include <util/resolve.h>
#include <storage.h>
#include <tolua.h>
#include <lua.h>
#include <assert.h>
#include <stdlib.h>
typedef struct building_action {
struct building *b;
char *fname;
char *param;
} building_action;
static int lc_age(struct attrib *a)
{
building_action *data = (building_action *) a->data.v;
const char *fname = data->fname;
const char *fparam = data->param;
building *b = data->b;
int result = -1;
assert(b != NULL);
if (fname != NULL) {
lua_State *L = (lua_State *) global.vm_state;
lua_getglobal(L, fname);
if (lua_isfunction(L, -1)) {
tolua_pushusertype(L, (void *)b, TOLUA_CAST "building");
if (fparam) {
tolua_pushstring(L, fparam);
}
if (lua_pcall(L, fparam ? 2 : 1, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error("lc_age(%s) calling '%s': %s.\n", buildingname(b), fname, error);
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_error("lc_age(%s) calling '%s': not a function.\n", buildingname(b), fname);
lua_pop(L, 1);
}
}
return (result != 0) ? AT_AGE_KEEP : AT_AGE_REMOVE;
}
static const char *NULLSTRING = "(null)";
static void lc_init(struct attrib *a)
{
a->data.v = calloc(1, sizeof(building_action));
}
static void lc_done(struct attrib *a)
{
building_action *data = (building_action *)a->data.v;
if (data->fname)
free(data->fname);
if (data->param)
free(data->param);
free(data);
}
static void
lc_write(const struct attrib *a, const void *owner, struct storage *store)
{
building_action *data = (building_action *)a->data.v;
const char *fname = data->fname;
const char *fparam = data->param;
building *b = data->b;
write_building_reference(b, store);
WRITE_TOK(store, fname);
WRITE_TOK(store, fparam ? fparam : NULLSTRING);
}
static int lc_read(struct attrib *a, void *owner, struct storage *store)
{
char name[NAMESIZE];
building_action *data = (building_action *)a->data.v;
int result =
read_reference(&data->b, store, read_building_reference, resolve_building);
if (global.data_version < UNICODE_VERSION) {
READ_STR(store, name, sizeof(name));
}
else {
READ_TOK(store, name, sizeof(name));
}
if (strcmp(name, "tunnel_action") == 0) {
/* E2: Weltentor has a new module, doesn't need this any longer */
result = 0;
data->b = 0;
}
else {
data->fname = _strdup(name);
}
if (global.data_version >= BACTION_VERSION) {
if (global.data_version < UNICODE_VERSION) {
READ_STR(store, name, sizeof(name));
}
else {
READ_TOK(store, name, sizeof(name));
if (strcmp(name, "tnnL") == 0) {
/* tunnel_action was the old Weltentore, their code has changed. ignore this object */
result = 0;
data->b = 0;
}
}
if (strcmp(name, NULLSTRING) == 0)
data->param = 0;
else {
data->param = _strdup(name);
}
}
else {
data->param = 0;
}
if (result == 0 && !data->b) {
return AT_READ_FAIL;
}
return AT_READ_OK;
}
attrib_type at_building_action = {
"lcbuilding",
lc_init, lc_done,
lc_age,
lc_write, lc_read
};
void building_addaction(building * b, const char *fname, const char *param)
{
attrib *a = a_add(&b->attribs, a_new(&at_building_action));
building_action *data = (building_action *)a->data.v;
data->b = b;
data->fname = _strdup(fname);
if (param) {
data->param = _strdup(param);
}
}

View File

@ -18,6 +18,7 @@ without prior permission by the authors of Eressea.
#include <util/bsdstring.h>
#include <util/functions.h>
#include <util/log.h>
#include <util/resolve.h>
#include <kernel/config.h>
#include <kernel/equipment.h>
@ -28,12 +29,16 @@ without prior permission by the authors of Eressea.
#include <kernel/building.h>
#include <kernel/item.h>
#include <kernel/region.h>
#include <kernel/version.h>
#include <storage.h>
#include <tolua.h>
#include <lua.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
static int
lua_giveitem(unit * s, unit * d, const item_type * itype, int n, struct order *ord)
@ -124,41 +129,6 @@ produce_resource(region * r, const resource_type * rtype, int norders)
}
}
static int lc_age(struct attrib *a)
{
building_action *data = (building_action *) a->data.v;
const char *fname = data->fname;
const char *fparam = data->param;
building *b = data->b;
int result = -1;
assert(b != NULL);
if (fname != NULL) {
lua_State *L = (lua_State *) global.vm_state;
lua_getglobal(L, fname);
if (lua_isfunction(L, -1)) {
tolua_pushusertype(L, (void *)b, TOLUA_CAST "building");
if (fparam) {
tolua_pushstring(L, fparam);
}
if (lua_pcall(L, fparam ? 2 : 1, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error("lc_age(%s) calling '%s': %s.\n", buildingname(b), fname, error);
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_error("lc_age(%s) calling '%s': not a function.\n", buildingname(b), fname);
lua_pop(L, 1);
}
}
return (result != 0) ? AT_AGE_KEEP : AT_AGE_REMOVE;
}
static void push_param(lua_State * L, char c, spllprm * param)
{
if (c == 'u')
@ -571,7 +541,7 @@ int tolua_toid(lua_State * L, int idx, int def)
void register_tolua_helpers(void)
{
at_building_action.age = lc_age;
at_register(&at_building_action);
register_function((pf_generic) & lua_building_protection,
TOLUA_CAST "lua_building_protection");

View File

@ -56,74 +56,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* attributes includes */
#include <attributes/matmod.h>
static const char *NULLSTRING = "(null)";
static void lc_init(struct attrib *a)
{
a->data.v = calloc(1, sizeof(building_action));
}
static void lc_done(struct attrib *a)
{
building_action *data = (building_action *) a->data.v;
if (data->fname)
free(data->fname);
if (data->param)
free(data->param);
free(data);
}
static void
lc_write(const struct attrib *a, const void *owner, struct storage *store)
{
building_action *data = (building_action *) a->data.v;
const char *fname = data->fname;
const char *fparam = data->param;
building *b = data->b;
write_building_reference(b, store);
WRITE_TOK(store, fname);
WRITE_TOK(store, fparam ? fparam : NULLSTRING);
}
static int lc_read(struct attrib *a, void *owner, struct storage *store)
{
char name[NAMESIZE];
building_action *data = (building_action *) a->data.v;
int result =
read_reference(&data->b, store, read_building_reference, resolve_building);
if (global.data_version < UNICODE_VERSION) {
READ_STR(store, name, sizeof(name));
} else {
READ_TOK(store, name, sizeof(name));
}
data->fname = _strdup(name);
if (global.data_version >= BACTION_VERSION) {
if (global.data_version < UNICODE_VERSION) {
READ_STR(store, name, sizeof(name));
} else {
READ_TOK(store, name, sizeof(name));
}
if (strcmp(name, NULLSTRING) == 0)
data->param = 0;
else
data->param = _strdup(name);
} else {
data->param = 0;
}
if (result == 0 && !data->b) {
return AT_READ_FAIL;
}
return AT_READ_OK;
}
attrib_type at_building_action = {
"lcbuilding",
lc_init, lc_done,
NULL,
lc_write, lc_read
};
typedef struct building_typelist {
struct building_typelist *next;
building_type *type;
@ -702,17 +634,6 @@ void building_setname(building * self, const char *name)
self->name = NULL;
}
void building_addaction(building * b, const char *fname, const char *param)
{
attrib *a = a_add(&b->attribs, a_new(&at_building_action));
building_action *data = (building_action *) a->data.v;
data->b = b;
data->fname = _strdup(fname);
if (param) {
data->param = _strdup(param);
}
}
region *building_getregion(const building * b)
{
return b->region;

View File

@ -158,19 +158,11 @@ extern "C" {
extern void building_update_owner(struct building * bld);
extern struct attrib_type at_building_action;
void building_addaction(struct building *b, const char *fname,
const char *param);
#ifdef WDW_PYRAMID
extern int wdw_pyramid_level(const struct building *b);
#endif
typedef struct building_action {
building *b;
char *fname;
char *param;
} building_action;
extern const char *buildingname(const struct building *b);
extern const char *building_getname(const struct building *b);

View File

@ -2802,7 +2802,6 @@ void attrib_init(void)
at_deprecate("xontormiaexpress", a_readint); /* required for old datafiles */
at_register(&at_speedup);
at_register(&at_building_action);
}
void kernel_init(void)

View File

@ -86,6 +86,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <attributes/otherfaction.h>
#include <iniparser.h>
/* libc includes */
#include <assert.h>
#include <stdio.h>
@ -4796,16 +4797,29 @@ const char *confpath = 0;
int init_data(const char *filename, const char *catalog)
{
const char * install = iniparser_getstring(global.inifile, "eressea:install", 0);
char filepath[MAX_PATH], catpath[MAX_PATH];
int l;
if (confpath) {
if (install || confpath) {
if (install && confpath) {
_snprintf(filepath, sizeof(filepath), "%s/%s/", install, confpath);
_snprintf(catpath, sizeof(catpath), "%s/%s/", install, confpath);
}
else if (confpath) {
_snprintf(filepath, sizeof(filepath), "%s/", confpath);
_snprintf(catpath, sizeof(catpath), "%s/", confpath);
}
else if (install) {
_snprintf(filepath, sizeof(filepath), "%s/", install);
_snprintf(catpath, sizeof(catpath), "%s/", install);
}
if (filename) {
_snprintf(filepath, sizeof(filepath), "%s/%s", confpath, filename);
strncat(filepath, filename, sizeof(filepath));
filename = filepath;
}
if (catalog) {
_snprintf(catpath, sizeof(catpath), "%s/%s", confpath, catalog);
strncat(catpath, catalog, sizeof(catpath));
catalog = catpath;
}
}

View File

@ -3,6 +3,7 @@ $#include <util/log.h>
module eressea {
module log {
void log_error @ error(const char *message);
void log_debug @ debug(const char *message);
void log_warning @ warning(const char *message);
}
}

View File

@ -77,6 +77,32 @@ static int tolua_log_eressea_log_warning00(lua_State* tolua_S)
#endif
}
/* function: log_debug */
static int tolua_log_eressea_log_debug00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isstring(tolua_S,1,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const char* message = ((const char*) tolua_tostring(tolua_S,1,0));
{
log_debug(message);
}
}
return 0;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'debug'.",&tolua_err);
return 0;
#endif
}
/* Open lib function */
LUALIB_API int luaopen_log (lua_State* tolua_S)
{
@ -90,6 +116,7 @@ LUALIB_API int luaopen_log (lua_State* tolua_S)
tolua_beginmodule(tolua_S,"log");
tolua_function(tolua_S,"error",tolua_log_eressea_log_error00);
tolua_function(tolua_S,"warning",tolua_log_eressea_log_warning00);
tolua_function(tolua_S,"debug",tolua_log_eressea_log_debug00);
tolua_endmodule(tolua_S);
tolua_endmodule(tolua_S);
tolua_endmodule(tolua_S);

View File

@ -8,7 +8,7 @@
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
*/
#include <platform.h>
#include "xml.h"
@ -30,56 +30,57 @@
#ifdef USE_LIBXML2
const xmlChar *xml_i(double number)
{
static char buffer[128];
_snprintf(buffer, sizeof(buffer), "%.0f", number);
return (const xmlChar *)buffer;
static char buffer[128];
_snprintf(buffer, sizeof(buffer), "%.0f", number);
return (const xmlChar *)buffer;
}
int xml_ivalue(xmlNodePtr node, const char *name, int dflt)
{
int i = dflt;
xmlChar *propValue = xmlGetProp(node, BAD_CAST name);
if (propValue != NULL) {
i = atoi((const char *)propValue);
xmlFree(propValue);
}
return i;
int i = dflt;
xmlChar *propValue = xmlGetProp(node, BAD_CAST name);
if (propValue != NULL) {
i = atoi((const char *)propValue);
xmlFree(propValue);
}
return i;
}
bool xml_bvalue(xmlNodePtr node, const char *name, bool dflt)
{
bool result = dflt;
xmlChar *propValue = xmlGetProp(node, BAD_CAST name);
if (propValue != NULL) {
if (strcmp((const char *)propValue, "no") == 0)
result = false;
else if (strcmp((const char *)propValue, "yes") == 0)
result = true;
else if (strcmp((const char *)propValue, "false") == 0)
result = false;
else if (strcmp((const char *)propValue, "true") == 0)
result = true;
else if (strcmp((const char *)propValue, "1") == 0) {
log_warning("bool value is '1': %s::%s\n", node->name, name);
result = true;
} else if (strcmp((const char *)propValue, "0") == 0) {
log_warning("bool value is '0': %s::%s\n", node->name, name);
result = false;
bool result = dflt;
xmlChar *propValue = xmlGetProp(node, BAD_CAST name);
if (propValue != NULL) {
if (strcmp((const char *)propValue, "no") == 0)
result = false;
else if (strcmp((const char *)propValue, "yes") == 0)
result = true;
else if (strcmp((const char *)propValue, "false") == 0)
result = false;
else if (strcmp((const char *)propValue, "true") == 0)
result = true;
else if (strcmp((const char *)propValue, "1") == 0) {
log_warning("bool value is '1': %s::%s\n", node->name, name);
result = true;
}
else if (strcmp((const char *)propValue, "0") == 0) {
log_warning("bool value is '0': %s::%s\n", node->name, name);
result = false;
}
xmlFree(propValue);
}
xmlFree(propValue);
}
return result;
return result;
}
double xml_fvalue(xmlNodePtr node, const char *name, double dflt)
{
double result = dflt;
xmlChar *propValue = xmlGetProp(node, BAD_CAST name);
if (propValue != NULL) {
result = atof((const char *)propValue);
xmlFree(propValue);
}
return result;
double result = dflt;
xmlChar *propValue = xmlGetProp(node, BAD_CAST name);
if (propValue != NULL) {
result = atof((const char *)propValue);
xmlFree(propValue);
}
return result;
}
/* new xml functions */
@ -89,54 +90,54 @@ double xml_fvalue(xmlNodePtr node, const char *name, double dflt)
#include <libxml/xinclude.h>
typedef struct xml_reader {
struct xml_reader *next;
xml_callback callback;
struct xml_reader *next;
xml_callback callback;
} xml_reader;
static xml_reader *xmlReaders;
void xml_register_callback(xml_callback callback)
{
xml_reader *reader = (xml_reader *) malloc(sizeof(xml_reader));
xml_reader **insert = &xmlReaders;
reader->callback = callback;
reader->next = NULL;
xml_reader *reader = (xml_reader *)malloc(sizeof(xml_reader));
xml_reader **insert = &xmlReaders;
reader->callback = callback;
reader->next = NULL;
while (*insert)
insert = &(*insert)->next;
*insert = reader;
while (*insert)
insert = &(*insert)->next;
*insert = reader;
}
#endif
int read_xml(const char *filename, const char *catalog)
{
#ifdef USE_LIBXML2
xml_reader *reader = xmlReaders;
xmlDocPtr doc;
int result;
xml_reader *reader = xmlReaders;
xmlDocPtr doc;
int result;
if (catalog) {
xmlLoadCatalog(catalog);
}
doc = xmlReadFile(filename, NULL, XML_PARSE_XINCLUDE | XML_PARSE_NONET | XML_PARSE_PEDANTIC | XML_PARSE_COMPACT);
if (doc == NULL) {
log_error("could not open '%s'\n", filename);
return -1;
}
if (catalog) {
xmlLoadCatalog(catalog);
}
doc = xmlReadFile(filename, NULL, XML_PARSE_XINCLUDE | XML_PARSE_NONET | XML_PARSE_PEDANTIC | XML_PARSE_COMPACT);
if (doc == NULL) {
log_error("could not open '%s'\n", filename);
return -1;
}
result = xmlXIncludeProcessFlags(doc, XML_PARSE_XINCLUDE | XML_PARSE_NONET | XML_PARSE_PEDANTIC | XML_PARSE_COMPACT);
if (result >= 0) {
while (reader != NULL) {
int i = reader->callback(doc);
if (i != 0) {
return i;
}
reader = reader->next;
}
result = 0;
}
xmlFreeDoc(doc);
return result;
result = xmlXIncludeProcessFlags(doc, XML_PARSE_XINCLUDE | XML_PARSE_NONET | XML_PARSE_PEDANTIC | XML_PARSE_COMPACT);
if (result >= 0) {
while (reader != NULL) {
int i = reader->callback(doc);
if (i != 0) {
return i;
}
reader = reader->next;
}
result = 0;
}
xmlFreeDoc(doc);
return result;
#else
log_error("LIBXML2 disabled, cannot read %s.\n", filename);
return -1;