Files
integration/luprex/core/lua/horps.lua

288 lines
8.5 KiB
Lua
Raw Normal View History

2022-02-03 11:20:28 -05:00
makeclass('player')
2022-03-05 19:17:22 -05:00
makeclass('army')
2022-03-31 14:41:19 -04:00
2022-03-05 19:17:22 -05:00
--
-- HORPS game: Walk around the board collecting armies and buffs
-- Captured armies eat each turn
-- Attacking armies select order (random by default)
-- Defending armies are stronger
-- Command: Tame Creature Stack
-- Command: Free Creature Stack
--
2022-02-03 11:20:28 -05:00
2022-02-03 16:23:14 -05:00
--
-- Data Structure
2022-03-05 19:17:22 -05:00
-- Army.Count[kind]=number Where kind is r,p,s
2022-03-23 17:03:07 -04:00
-- Player.Count[kind]=number Where kind is r,p,s
2022-02-03 16:23:14 -05:00
--
2022-02-03 11:20:28 -05:00
function player.interface(actor, place)
2022-03-05 19:17:22 -05:00
gui.menu_item("cb_north" ,"Go North")
gui.menu_item("cb_south" ,"Go South")
gui.menu_item("cb_east" ,"Go East")
gui.menu_item("cb_west" ,"Go West")
gui.menu_item("cb_map" ,"Show the Map")
gui.menu_item("cb_conjurerock" ,"Conjure Rock")
gui.menu_item("cb_conjurepaper" ,"Conjure Paper")
gui.menu_item("cb_conjurescissor" ,"Conjure Scissor")
gui.menu_item("cb_droprock" ,"Drop Rock")
gui.menu_item("cb_droppaper" ,"Drop Paper")
gui.menu_item("cb_dropscissor" ,"Drop Scissor")
end
2022-03-16 15:47:46 -04:00
2022-03-05 19:17:22 -05:00
function player:cb_conjurerock() self.Count['r']=self.Count['r']+1 end
function player:cb_conjurepaper() self.Count['p']=self.Count['p']+1 end
function player:cb_conjurescissor() self.Count['s']=self.Count['s']+1 end
function army.interface(actor,place)
if place.owner==actor then gui_menu_item("cb_recruit","Recruit");
2022-03-16 15:47:46 -04:00
else gui.menu_item("cb_fight" ,"Fight");
2022-03-05 19:17:22 -05:00
end end
-- Rock dulls Scissors 3
-- Rock cripples Lizard 2
-- Paper disproves Spock 3
-- Paper covers Rock 2
-- Scissors decapitates Lizard 3
-- Scissors cuts Paper 2
-- Lizard eats Paper 3
-- Lizard poisons Spock 2
-- Spock vaporizes Rock 3
-- Spock dismantles Scissors 2
armytypes={'r','p','s'}
armynames={r="Rock Golem",p="Paper Dragon",s="Scissor Beast",l="Fire Lizzard",v="Mr. Spock"}
--advantage={ r={ r=1, p=1/2, s=3, l=2, v=1/3 },
-- p={ r=2, p=1, s=1/2, l=1/3, v=3 },
2022-03-16 15:47:46 -04:00
-- s={ r=1/3, p=2, s=1, l=3, v=1/2 },
-- l={ r=1/2, p=3, s=1/3, l=1, v=2 },
-- v={ r=3, p=1/3, s=2, l=1/2, v=1 } }
2022-03-05 19:17:22 -05:00
advantage={ r={ r=1, p=1/2, s=2 },
p={ r=2, p=1, s=1/2 },
s={ r=1/2, p=2, s=1 } }
function shuffle(t)
local s={}
for i=1, #t do s[i]=t[i] end
for i=#t,2,-1 do
local j=math.random(i)
s[i],s[j]=s[j],s[i]
end
return s
end
2022-03-31 14:41:19 -04:00
function qbuildarmy(x,y)
t={class='army',x=x,y=y,z=0,plane='main',graphic='army'}
local nt=tangible.build(t)
nt.Count={}
setmetatable(nt.Count,NilIsZero)
nt.Count['r']=1
return nt
end
function MakeMap2()
for i=-2,2 do
qbuildarmy( i, 3)
qbuildarmy( i,-3)
qbuildarmy(-3, i)
qbuildarmy( 3, i)
end
qbuildarmy(-3, 3)
qbuildarmy( 3,-3)
qbuildarmy(-3,-3)
qbuildarmy( 3, 3)
end
2022-03-23 17:03:07 -04:00
function MakeMap()
2022-03-29 15:47:44 -04:00
local rad=6
for x=-rad,rad do for y=-rad,rad do if math.random(1,5)==1 then
2022-03-23 17:03:07 -04:00
t={class='army',x=x,y=y,z=0,plane='main',graphic='army'}
2022-03-31 14:41:19 -04:00
-- print("Building an army:")
2022-03-29 16:37:32 -04:00
-- pprint(t)
2022-03-23 17:03:07 -04:00
local nt=tangible.build(t)
nt.Count={}
setmetatable(nt.Count,NilIsZero)
for i=1,#armytypes do if math.random(1,2)==1 then
local type=armytypes[math.random(1,#armytypes)]
nt.Count[type]=nt.Count[type]+math.random(1,3)
end end
2022-03-31 14:41:19 -04:00
-- print("Here's what was built:")
2022-03-29 16:37:32 -04:00
-- pprint(nt)
2022-03-29 15:47:44 -04:00
end end end
2022-03-23 17:03:07 -04:00
end
2022-03-05 19:17:22 -05:00
--
-- For each creature type, select the optimal target. Select randomly among identical targets.
--
2022-03-23 17:03:07 -04:00
function army.fight0(ak,ac,dk,dc,rules) -- returns number of attacker casualties, defender casualties
2022-03-31 14:41:19 -04:00
if not rules then rules={} end
2022-03-05 19:17:22 -05:00
local adv0=advantage[ak][dk]
local adv1=advantage[dk][ak]
2022-03-23 17:03:07 -04:00
if rules.counterattack=='one' then adv1=1
elseif rules.counterattack=='best' then adv1=adv1<1 and 1 or 1
end
2022-03-05 19:17:22 -05:00
local rval0=(ac*adv0-dc)/adv0
if rval0<0 then rval0=0 end
local rval1=(dc*adv1-rval0)/adv1
return rval0,rval1
end
2022-03-31 14:41:19 -04:00
function player:fight(enemy)
for ak,ac in pairs(self.Count) do -- Should randomize the order
2022-03-16 15:47:46 -04:00
local enemyk, enemyc
2022-03-05 19:17:22 -05:00
local acas
local maxcas=-1
2022-03-16 15:47:46 -04:00
local Loss0,Loss1
local whichdk, whichdc
2022-03-31 14:41:19 -04:00
for dk,dc in pairs(enemy.Count) do
Loss0,Loss1=army.fight0(ak,ac,dk,dc)
2022-03-16 15:47:46 -04:00
print("When "..ac.." "..ak.." fight "..dc.." "..dk.." they kill "..Loss1.." and suffer "..Loss0)
2022-03-05 19:17:22 -05:00
if Loss1>maxcas then
2022-03-16 15:47:46 -04:00
enemyk=dk
enemyc=dc
2022-03-05 19:17:22 -05:00
maxcas=Loss1
acas=Loss1
end end
2022-03-16 15:47:46 -04:00
if enemyk then
print("Army of "..ac.." "..ak.." fights "..enemyc.." "..enemyk..", killing "..Loss1.." and suffering "..Loss0)
2022-03-05 19:17:22 -05:00
end
end
end
function player:cb_droprock(actor) player:droparmy(actor,'r') end
function player:cb_droppaper(actor) player:droparmy(actor,'p') end
function player:cb_dropscissor(actor) player:droparmy(actor,'s') end
function player:droparmy(actor,kind)
2022-03-23 17:03:07 -04:00
if actor.Count[kind]<=0 then print("No armies of type "..kind.." available") return end
2022-03-05 19:17:22 -05:00
local lis=tangible.near(actor,0,true,true)
if #lis>1 then print("Multiple Tangibles Nearby") return end
local t=lis[1]
if t==nil then t=player:buildarmy(actor) end
t.Count[kind]=t.Count[kind]+1
pprint(t)
end
function player:newlocation()
2022-03-31 14:41:19 -04:00
local lis=tangible.near(self,0,true,true)
for _,t in ipairs(lis) do self:fight(t) end
2022-03-05 19:17:22 -05:00
end
2022-02-03 11:20:28 -05:00
function player:printanimstate()
2022-03-05 19:17:22 -05:00
local graphic,plane,x,y,z,facing = tangible.animstate(self)
print("Resulting state: ", graphic, plane, x, y, z, facing)
end
2022-02-03 11:20:28 -05:00
2022-03-05 19:17:22 -05:00
function player:cb_north()
tangible.animate(self, {action="walk", dy=1})
2022-03-31 14:41:19 -04:00
self:cb_map()
2022-03-05 19:17:22 -05:00
self:newlocation()
end
2022-02-03 11:20:28 -05:00
2022-03-31 14:41:19 -04:00
function player:cb_south()
tangible.animate(self, {action="walk", dy=-1})
self:cb_map()
2022-03-05 19:17:22 -05:00
self:newlocation()
end
2022-02-03 11:20:28 -05:00
2022-03-31 14:41:19 -04:00
function player:cb_east()
tangible.animate(self, {action="walk", dx=1})
self:cb_map()
2022-03-05 19:17:22 -05:00
self:newlocation()
end
2022-03-31 14:41:19 -04:00
function player:cb_west()
tangible.animate(self, {action="walk", dx=-1})
self:cb_map()
2022-03-05 19:17:22 -05:00
self:newlocation()
end
function player:buildarmy(actor)
local _,pl,ax,ay=tangible.animstate(actor)
t={class='army',x=ax,y=ay,z=0,plane=pl,graphic='army'}
local nt=tangible.build(t)
nt.Count={}
setmetatable(nt.Count,{__index=function(t,k) return 0 end,__newindex=function(t,k,v) if v~=nil and v~=0 then rawset(t,k,v) end end})
return nt
end
2022-02-03 11:20:28 -05:00
function player.cb_emit_army(actor,place,dialog)
2022-03-05 19:17:22 -05:00
local _,pl,ax,ay=tangible.animstate(actor)
t={class='army',x=ax,y=ay,z=0,plane=pl,graphic='army'}
pprint("building ",t)
local nt=tangible.build(t)
setmetatable(nt,{r=0,p=0,s=0})
nt.kind='r'
2022-03-23 17:03:07 -04:00
nt.Count=1
2022-03-05 19:17:22 -05:00
end
2022-02-03 11:20:28 -05:00
function player.cb_emit_buff(actor,place,dialog)
2022-03-05 19:17:22 -05:00
local _,pl,ax,ay=tangible.animstate(actor)
t={class='army',x=ax,y=ay,z=0,plane=pl,graphic='buff'}
pprint("building ",t)
tangible.build(t)
end
2022-02-03 11:20:28 -05:00
makeclass('army')
makeclass('buff')
function seq(a,b,c) return a<=b and b<=c or false end
2022-03-05 19:17:22 -05:00
function num2(a) if a<=9 then return " "..a else return a end end
2022-02-03 11:20:28 -05:00
function player.cb_map(actor,place,dialog)
2022-03-29 15:47:44 -04:00
local rad=4
2022-03-31 14:41:19 -04:00
local ax,ay=tangible.xyz(actor)
local scratch={}
2022-03-23 17:03:07 -04:00
local lis=tangible.near(actor,1.5*rad,true,false)
2022-03-31 14:41:19 -04:00
print("\27c\27[38;5;9mMap:\27[0m")
2022-02-03 11:20:28 -05:00
for _,t in pairs(lis) do
2022-03-31 14:41:19 -04:00
-- local graphic,plane,x,y,z,facing = tangible.animstate(t)
2022-02-03 11:20:28 -05:00
local c=tangible.getclass(t)
local dx,dy=tangible.xyz(t)
2022-03-31 14:41:19 -04:00
local offset=(-dy+ay+rad)*(rad*2+1)+dx-ax+rad
2022-02-03 11:20:28 -05:00
local cl=tangible.getclass(t)
2022-03-31 14:41:19 -04:00
if seq(ax-rad,dx,ax+rad) and seq(ay-rad,dy,ay+rad) and (cl=='player' or cl=='army') then
2022-03-23 17:03:07 -04:00
if not scratch[offset] then scratch[offset]={} scratch[offset].Count={} setmetatable(scratch[offset].Count,NilIsZero) end
if t.Count then
for i,k in ipairs(armytypes) do
local a0=scratch[offset]
local a1=a0.Count
local a2=a1[i]
local a3=t.Count
local a4=a3[k]
if not a4 then print("a4 is nil") pprint(t) end
scratch[offset].Count[i]=a2+a4
end end
end
2022-02-03 11:20:28 -05:00
end
2022-03-29 16:37:32 -04:00
-- pprint(scratch)
2022-02-03 16:23:14 -05:00
for dy=-rad,rad do for line=0,1 do
2022-03-31 14:41:19 -04:00
local lbuf="|"
2022-02-03 16:23:14 -05:00
for dx=-rad,rad do
2022-03-05 19:17:22 -05:00
local offset=(dy+rad)*(rad*2+1)+dx+rad
if line==0 then lbuf=lbuf.."----"
2022-02-03 16:23:14 -05:00
elseif line==1 then
2022-03-23 17:03:07 -04:00
if scratch[offset] then for i,k in ipairs(armytypes) do lbuf=lbuf..scratch[offset].Count[i] end
else for i=1,#armytypes do lbuf=lbuf..' ' end end
lbuf=lbuf.."-"
2022-02-03 16:23:14 -05:00
end end
2022-02-03 11:20:28 -05:00
print(lbuf)
end end
2022-03-05 19:17:22 -05:00
lbuf=""
for dx=-rad,rad do lbuf=lbuf.."----" end
lbuf=lbuf.."-"
print(lbuf)
2022-03-29 16:37:32 -04:00
-- print("In Player "..tangible.id(actor)..":")
2022-03-31 14:41:19 -04:00
-- for k,v in pairs(actor.Count) do print(" "..k.." "..v) end
-- local lis=tangible.near(actor,0,true,true)
-- for k,v in pairs(lis) do
2022-03-29 16:37:32 -04:00
-- print("In Army "..tangible.id(v)..":")
2022-03-31 14:41:19 -04:00
-- for k2,v2 in pairs(v.Count) do print(" "..k2.." "..v2) end
-- end
2022-02-03 11:20:28 -05:00
end