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 locales = de,en
[config] [config]
source_dir = .. paths = lunit
install = .
maxnmrs = 10 maxnmrs = 10
[editor] [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) function use_seashell(u, amount)
-- Muschelplateau... -- Muschelplateau...
local r = get_region(165,30)
local visit = u.faction.objects:get("embassy_muschel") local visit = u.faction.objects:get("embassy_muschel")
if visit~=nil and u.region~= r then if visit and u.region~= home then
local turns = get_turn() - visit local turns = get_turn() - visit
local msg = message.create("msg_event") 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: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) msg:send_region(u.region)
return 0 return 0
end end
return -4 return -4
end end
function update_embassies() function embassy.init()
-- Muschelplateau home = get_region(165,30)
local r = get_region(165,30) if home==nil then
if r~=nil then eressea.log.error("cannot find embassy region 'Muschelplateau'")
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
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
end end
end end
return embassy

View File

@ -1,10 +1,8 @@
local function create_ents(r, number) local function create_ents(r, number)
local f = get_faction(0) local f = get_faction(666)
if f~=nil and number>0 then if f~=nil and number>0 then
u = add_unit(f, r) u = unit.create(f, r, number)
u.number = number u.name = "Wütende Ents"
u.name = "Wütende Ents"
u:set_skill("perception", 2) u:set_skill("perception", 2)
msg = message.create("entrise") msg = message.create("entrise")
@ -15,7 +13,9 @@ local function create_ents(r, number)
return nil return nil
end end
function spawn_ents() local ents = {}
function ents.update()
local r local r
for r in regions() do for r in regions() do
if r:get_flag(0) then -- RF_CHAOTIC if r:get_flag(0) then -- RF_CHAOTIC
@ -30,3 +30,5 @@ function spawn_ents()
end end
end end
end end
return ents

View File

@ -1,18 +1,36 @@
require "gates" -- DEPRECATED
local function eternath_exchange(b1, b2, size) -- implements parts of a quest in E2
local units1 = gate_units(b1, size) -- this module is deprecated, because it puts functions in the global environment for at_building_action
local units2 = gate_units(b2, size)
gate_travel(b2, units1) local gates = require('eressea.gates')
gate_travel(b1, units2)
end local b1 = nil
local b2 = nil
function eternathgate_action(b) function eternathgate_action(b)
if eternathgate == nil then if b1 == nil then
eternathgate = b b1 = b
elseif b2 == nil then
b2 = b
else else
eternath_exchange(eternathgate, b, 10) eressea.log.error("data contains more than two Ethernath gates")
end end
return 1 return 1
end 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) local ponnuki = {}
jokes = {
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.", "Ein Bummerang ist, wenn man ihn wegwirft und er kommt nicht wieder, dann war's keiner.",
"Merke: Mit Schwabenwitzen soll man ganz sparsam sein.", "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 Katzen und Elfen kreuzt? Elfen ohne Rheuma.",
"Was bekommt man, wenn man Insekten und Katzen kreuzt? Tiger, die Crisan benutzen." "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)) 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) local d = math.random(6)
r = u.region:next(d-1) local r = u.region:next(d-1)
u:clear_orders() u:clear_orders()
directions = { "NW", "NO", "O", "SO", "SW", "W" }
u:add_order("NACH " .. directions[d]) u:add_order("NACH " .. directions[d])
end end
local function init_ponnuki(home) function ponnuki.init()
local f = get_faction(0) -- initialize other scripts
local u = get_unit(atoi36("ponn")) local u = get_unit(atoi36("ponn"))
if u == nil then 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 = add_unit(f, home)
u.id = atoi36("ponn") u.id = atoi36("ponn")
u.name = "Ponnuki" u.name = "Ponnuki"
u.info = "Go, Ponnuki, Go!" u.info = "Go, Ponnuki, Go!"
u.race = "illusion" u.race = "illusion"
u:set_racename("Ritter von Go") u:set_racename("Ritter von Go")
else
eressea.log.error("Ponnuki cannot find Magrathea")
end end
if u.faction==f then end
set_unit_brain(u, ponnuki_brain) if u then
ponnuki_brain(u)
end end
end end
-- initialize other scripts return ponnuki
local magrathea = get_region(-67, -5)
if magrathea~=nil and init_ponnuki~=nil then
init_ponnuki(magrathea)
return
end

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 function tunnel_travelers(b)
local units = nil local units = nil
for u in b.units do for u in b.units do
@ -9,28 +14,8 @@ local function tunnel_travelers(b)
return units return units
end end
targets = nil
ntargets = 0
local function get_target(param) local function get_target(param)
-- print("finding targets: " .. param) local ntargets = table.maxn(targets)
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
end
end
if ntargets==0 then if ntargets==0 then
return nil return nil
end end
@ -38,15 +23,14 @@ local function get_target(param)
return targets[rn] return targets[rn]
end end
-- export, will be called from lc_age() local function tunnel_action(b, param)
function tunnel_action(b, param)
local r = nil local r = nil
if tonumber(param)~=nil then if tonumber(param)~=nil then
r = get_region_by_id(tonumber(param)) r = get_region_by_id(tonumber(param))
end end
local units = tunnel_travelers(b) local units = tunnel_travelers(b)
if units~=nil then 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 for key, u in pairs(units) do
local rto = r local rto = r
if r==nil then if r==nil then
@ -54,9 +38,39 @@ function tunnel_action(b, param)
end end
if rto~=nil then if rto~=nil then
u.region = rto u.region = rto
print(" - teleported " .. tostring(u) .. " to " .. tostring(rto)) eressea.log.debug("teleported " .. tostring(u) .. " to " .. tostring(rto))
end end
end end
end end
return 1 -- return 0 to destroy return 1 -- return 0 to destroy
end 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 return -4
end end
function xmas2004() local self = {}
if get_gamename() == "Eressea" then
function self.update()
if not get_key("xm04") then if not get_key("xm04") then
print("Es weihnachtet sehr (2004)") eressea.log.debug("Es weihnachtet sehr (2004)")
set_key("xm04", true) set_key("xm04", true)
for f in factions() do for f in factions() do
f:add_item("speedsail", 1) f:add_item("speedsail", 1)
f:add_notice("santa2004") f:add_notice("santa2004")
end end
end end
end
end end
-- xmas2004() return self

View File

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

View File

@ -8,11 +8,13 @@ function use_xmastree(u, amount)
return 0 return 0
end end
function update_xmas2006() local self = {}
function self.update()
local turn = get_turn() local turn = get_turn()
local season = get_season(turn) local season = get_season(turn)
if season == "calendar::winter" then 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") local msg = message.create("xmastree_effect")
for r in regions() do for r in regions() do
if r:get_key("xm06") then if r:get_key("xm06") then
@ -38,8 +40,7 @@ function update_xmas2006()
end end
end end
function xmas2006() function self.init()
if get_gamename() == "Eressea" then
if not get_key("xm06") then if not get_key("xm06") then
print("Es weihnachtet sehr (2006)") print("Es weihnachtet sehr (2006)")
set_key("xm06", true) set_key("xm06", true)
@ -48,7 +49,6 @@ function xmas2006()
f:add_notice("santa2006") f:add_notice("santa2006")
end end
end 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 -- create a fixed path to a specific region
local function create_path(from, to) local function create_path(from, to)
local param = tostring(to.uid) local param = tostring(to.uid)

View File

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

View File

@ -38,17 +38,6 @@ int tolua_buildinglist_next(lua_State * L)
return 0; /* no more values to return */ 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) static int tolua_building_get_objects(lua_State * L)
{ {
building *self = (building *) tolua_tousertype(L, 1, 0); building *self = (building *) tolua_tousertype(L, 1, 0);
@ -253,7 +242,6 @@ void tolua_building_open(lua_State * L)
tolua_building_set_region); tolua_building_set_region);
tolua_variable(L, TOLUA_CAST "size", tolua_building_get_size, tolua_variable(L, TOLUA_CAST "size", tolua_building_get_size,
tolua_building_set_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); tolua_function(L, TOLUA_CAST "get_typename", tolua_building_get_typename);
#ifdef TODO #ifdef TODO
.property("type", &building_gettype) .property("type", &building_gettype)

View File

@ -1222,6 +1222,12 @@ int eressea_run(lua_State *L, const char *luafile)
global.vm_state = L; global.vm_state = L;
/* run the main script */ /* run the main script */
if (luafile) { 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); log_debug("executing script %s\n", luafile);
lua_getglobal(L, "debug"); 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/bsdstring.h>
#include <util/functions.h> #include <util/functions.h>
#include <util/log.h> #include <util/log.h>
#include <util/resolve.h>
#include <kernel/config.h> #include <kernel/config.h>
#include <kernel/equipment.h> #include <kernel/equipment.h>
@ -28,12 +29,16 @@ without prior permission by the authors of Eressea.
#include <kernel/building.h> #include <kernel/building.h>
#include <kernel/item.h> #include <kernel/item.h>
#include <kernel/region.h> #include <kernel/region.h>
#include <kernel/version.h>
#include <storage.h>
#include <tolua.h> #include <tolua.h>
#include <lua.h> #include <lua.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
static int static int
lua_giveitem(unit * s, unit * d, const item_type * itype, int n, struct order *ord) 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) static void push_param(lua_State * L, char c, spllprm * param)
{ {
if (c == 'u') if (c == 'u')
@ -571,7 +541,7 @@ int tolua_toid(lua_State * L, int idx, int def)
void register_tolua_helpers(void) void register_tolua_helpers(void)
{ {
at_building_action.age = lc_age; at_register(&at_building_action);
register_function((pf_generic) & lua_building_protection, register_function((pf_generic) & lua_building_protection,
TOLUA_CAST "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 */ /* attributes includes */
#include <attributes/matmod.h> #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 { typedef struct building_typelist {
struct building_typelist *next; struct building_typelist *next;
building_type *type; building_type *type;
@ -702,17 +634,6 @@ void building_setname(building * self, const char *name)
self->name = NULL; 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) region *building_getregion(const building * b)
{ {
return b->region; return b->region;

View File

@ -158,19 +158,11 @@ extern "C" {
extern void building_update_owner(struct building * bld); extern void building_update_owner(struct building * bld);
extern struct attrib_type at_building_action; extern struct attrib_type at_building_action;
void building_addaction(struct building *b, const char *fname,
const char *param);
#ifdef WDW_PYRAMID #ifdef WDW_PYRAMID
extern int wdw_pyramid_level(const struct building *b); extern int wdw_pyramid_level(const struct building *b);
#endif #endif
typedef struct building_action {
building *b;
char *fname;
char *param;
} building_action;
extern const char *buildingname(const struct building *b); extern const char *buildingname(const struct building *b);
extern const char *building_getname(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_deprecate("xontormiaexpress", a_readint); /* required for old datafiles */
at_register(&at_speedup); at_register(&at_speedup);
at_register(&at_building_action);
} }
void kernel_init(void) 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 <attributes/otherfaction.h>
#include <iniparser.h>
/* libc includes */ /* libc includes */
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
@ -4796,16 +4797,29 @@ const char *confpath = 0;
int init_data(const char *filename, const char *catalog) 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]; char filepath[MAX_PATH], catpath[MAX_PATH];
int l; 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) { if (filename) {
_snprintf(filepath, sizeof(filepath), "%s/%s", confpath, filename); strncat(filepath, filename, sizeof(filepath));
filename = filepath; filename = filepath;
} }
if (catalog) { if (catalog) {
_snprintf(catpath, sizeof(catpath), "%s/%s", confpath, catalog); strncat(catpath, catalog, sizeof(catpath));
catalog = catpath; catalog = catpath;
} }
} }

View File

@ -3,6 +3,7 @@ $#include <util/log.h>
module eressea { module eressea {
module log { module log {
void log_error @ error(const char *message); void log_error @ error(const char *message);
void log_debug @ debug(const char *message);
void log_warning @ warning(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 #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 */ /* Open lib function */
LUALIB_API int luaopen_log (lua_State* tolua_S) 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_beginmodule(tolua_S,"log");
tolua_function(tolua_S,"error",tolua_log_eressea_log_error00); tolua_function(tolua_S,"error",tolua_log_eressea_log_error00);
tolua_function(tolua_S,"warning",tolua_log_eressea_log_warning00); 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); 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 This program may not be used, modified or distributed
without prior permission by the authors of Eressea. without prior permission by the authors of Eressea.
*/ */
#include <platform.h> #include <platform.h>
#include "xml.h" #include "xml.h"
@ -62,7 +62,8 @@ bool xml_bvalue(xmlNodePtr node, const char *name, bool dflt)
else if (strcmp((const char *)propValue, "1") == 0) { else if (strcmp((const char *)propValue, "1") == 0) {
log_warning("bool value is '1': %s::%s\n", node->name, name); log_warning("bool value is '1': %s::%s\n", node->name, name);
result = true; result = true;
} else if (strcmp((const char *)propValue, "0") == 0) { }
else if (strcmp((const char *)propValue, "0") == 0) {
log_warning("bool value is '0': %s::%s\n", node->name, name); log_warning("bool value is '0': %s::%s\n", node->name, name);
result = false; result = false;
} }
@ -97,7 +98,7 @@ static xml_reader *xmlReaders;
void xml_register_callback(xml_callback callback) void xml_register_callback(xml_callback callback)
{ {
xml_reader *reader = (xml_reader *) malloc(sizeof(xml_reader)); xml_reader *reader = (xml_reader *)malloc(sizeof(xml_reader));
xml_reader **insert = &xmlReaders; xml_reader **insert = &xmlReaders;
reader->callback = callback; reader->callback = callback;
reader->next = NULL; reader->next = NULL;