Skip to content

Instantly share code, notes, and snippets.

@warmist
Created September 11, 2015 21:31
Show Gist options
  • Save warmist/84300225dc7ed8e22e12 to your computer and use it in GitHub Desktop.
Save warmist/84300225dc7ed8e22e12 to your computer and use it in GitHub Desktop.
create site for adventurer
--[=[o
site-now name x y site_type civ_id {region{min_x,min_y, max_x,max_y} | [size_x size_y] }
size_x size_y only if with "-a" flag
other flags:
-a | --adventurer : try to figure out stuff from adventurer
does not need "x" and "y" and "civ_id"
-r | --random_name : generate random name for the site
does not need "name"
--o]=]
local args={...}
settings={args={}}
for k,v in ipairs(args) do
if v=="-a" or v=="--adventurer" then
settings.pos_find=true
settings.my_civ=true
elseif v=="-r" or v=="--random_name" then
settings.random_name=true
elseif v=='-q' or v=="--quiet" then
settings.quiet=true
else --unmatches stuff goes here!
table.insert(settings.args,v)
end
end
function find_player_army()
for k,v in ipairs(df.global.world.armies.all) do
if v.flags.player then
return v
end
end
end
function advGlobalPos()
local map=df.global.world.map
local wd=df.global.world.world_data
local adv=df.global.world.units.active[0]
return math.floor(map.region_x+adv.pos.x/48), math.floor(map.region_y+adv.pos.y/48)
end
function find_adventurer()
local army=find_player_army()
if not army then --not traveling, warn and fallback
if not settings.quiet then
print("Warning: falling back to local map coordinates, site might appear only when map is reentered")
end
--[[
local x=math.floor((df.global.world.map.region_x+1)/16) --just having site data, but then you can use min/max ??
local y=math.floor((df.global.world.map.region_y+1)/16)
local lx=(df.global.world.map.region_x+1)%16
local ly=(df.global.world.map.region_y+1)%16
return {glb={x=x,y=y},lcl={x=lx,y=ly}}
]]
local x,y=advGlobalPos()
return {glb={x=math.floor(x/16),y=math.floor(y/16)},lcl={x=x%16,y=y%16}}
else
local x=math.floor(army.pos.x/3) --should divide clearly but, just in case
local y=math.floor(army.pos.y/3)
return {glb={x=math.floor(x/16),y=math.floor(y/16)},lcl={x=x%16,y=y%16}}
end
end
function gen_random_name() --super stupid name generator
local vowels={'a','e','i','o','u'}
local consonants={'b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','z'}
local len=math.random(5,10)
local is_vow=math.random()>0.5
local ret=""
for i=1,len do
if is_vow then
ret=ret..vowels[math.random(1,#vowels)]
else
ret=ret..consonants[math.random(1,#consonants)]
end
if math.random()<0.9 then
is_vow=not is_vow
end
end
return ret
end
local cur_unmatches=1
function pop_unmatched()
local val=settings.args[cur_unmatches]
if val then
cur_unmatches=cur_unmatches+1
end
return val
end
function pop_number()
return tonumber(pop_unmatched())
end
--first try getting name
if settings.random_name then
settings.name=gen_random_name()
else
settings.name=pop_unmatched() or qerror("Name not supplied")
end
--try figureing out the pos
if settings.pos_find then
settings.pos=find_adventurer()
else
settings.pos={glb={x=pop_number(),y=pop_number()}}
end
settings.sitetype=pop_number() or 7 --not sure why 7...
function find_adventurer_nemesis( )
local nem=df.global.world.nemesis.all
for i,v in ipairs(nem) do
if v.flags.ACTIVE_ADVENTURER then
return v
end
end
end
if settings.my_civ then --TODO: my_civ could mean my fort civ, but why then create sites??
if #df.global.world.units.active>0 then
settings.civ_id=df.global.world.units.active[0].civ_id
else
local n=find_adventurer_nemesis()
if n and n.figure then
settings.civ_id=n.figure.civ_id
end
end
else
settings.civ_id=pop_number() or -1
end
--region numbers
local r_x=pop_number()
if settings.pos_find then --TODO: region still need work, might be better to move min(s) so size would be preserved
local size_x=r_x or 0
local size_y=pop_number() or 0
local lp=settings.pos.lcl
settings.region={
min_x=lp.x,
min_y=lp.y,
max_x=lp.x+size_x,
max_y=lp.y+size_y,
}
else
if r_x then
local r_y=pop_number()
settings.region={min_x=r_x,min_y=r_y,max_x=pop_number() or r_x,max_y=pop_number() or r_y} --1x1 if last two not specified
else
qerror("no region specification, failing") --TODO: maybe just do something? random? dunno too tired to think
end
end
function clip_region(r)
r.min_x=math.max(r.min_x,0)
r.min_y=math.max(r.min_y,0)
r.max_x=math.min(r.max_x,15)
r.max_y=math.min(r.max_y,15)
end
clip_region(settings.region)
--FINALLY WE HAVE ENOUGH STUFF TO BUILD THIS
function addSite(pos_global,region,civ_id,name,sitetype)
rgn_min_x=region.min_x
rgn_min_y=region.min_y
rgn_max_x=region.max_x
rgn_max_y=region.max_y
--[=[
<angavrilov> global = pos*16 + rgn
<angavrilov> BUT
<angavrilov> for cities global is usually 17x17, i.e. max size
<angavrilov> while rgn designates a small bit in the middle
<angavrilov> for stuff like forts that formula holds exactly
]=]--
local wd=df.global.world.world_data
local nsite=df.world_site:new()
nsite.name.first_name=name
nsite.name.has_name=true
nsite.pos:assign(pos_global)
nsite.rgn_max_x=rgn_max_x
nsite.rgn_min_x=rgn_min_x
nsite.rgn_min_y=rgn_min_y
nsite.rgn_max_y=rgn_max_y
nsite.global_max_x=nsite.pos.x*16+nsite.rgn_max_x
nsite.global_min_x=nsite.pos.x*16+nsite.rgn_min_x
nsite.global_max_y=nsite.pos.y*16+nsite.rgn_max_y
nsite.global_min_y=nsite.pos.y*16+nsite.rgn_min_y
nsite.id=wd.next_site_id
nsite.civ_id=civ_id or -1
nsite.cur_owner_id=civ_id or -1
nsite.type=sitetype --lair = 7
nsite.flags:resize(23)
--nsite.flags[4]=true
--nsite.flags[5]=true
--nsite.flags[6]=true
nsite.index=#wd.sites+1
wd.sites:insert("#",nsite)
wd.next_site_id=wd.next_site_id+1
--might not be needed...
--[[local unk130=df.world_site_unk130:new()
unk130.index=#wd.site_unk130+1
wd.site_unk130:insert("#",unk130)
--wd.next_site_unk136_id=wd.next_site_unk136_id+1--]]
return nsite
end
addSite(settings.pos.glb,settings.region,settings.civ_id,settings.name,settings.sitetype)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment