2022-02-03 11:20:28 -05:00
|
|
|
makeclass('player')
|
2022-03-05 19:17:22 -05:00
|
|
|
makeclass('army')
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
|
-- 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-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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
|
-- For each creature type, select the optimal target. Select randomly among identical targets.
|
|
|
|
|
--
|
|
|
|
|
function army.fight0(ak,ac,dk,dc) -- returns number of attacker casualties, defender casualties
|
|
|
|
|
local adv0=advantage[ak][dk]
|
|
|
|
|
local adv1=advantage[dk][ak]
|
|
|
|
|
local rval0=(ac*adv0-dc)/adv0
|
|
|
|
|
if rval0<0 then rval0=0 end
|
|
|
|
|
local rval1=(dc*adv1-rval0)/adv1
|
|
|
|
|
return rval0,rval1
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function army.cb_fight(actor,place,dialog)
|
|
|
|
|
for ak,ac in pairs(actor.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-05 19:17:22 -05:00
|
|
|
for dk,dc in pairs(place.Count) do
|
|
|
|
|
local rem0,rem1=army.fight0(ak,ac,dk,dc)
|
2022-03-16 15:47:46 -04:00
|
|
|
Loss0=ac-rem0
|
|
|
|
|
Loss1=dc-rem1
|
|
|
|
|
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)
|
|
|
|
|
if actor.Count[kind]<=0 then print("No armies of typem "..kind.." available") return end
|
|
|
|
|
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()
|
|
|
|
|
local lis=tangible.near(self,0,false,false)
|
|
|
|
|
print("New Location")
|
|
|
|
|
pprint(lis)
|
|
|
|
|
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})
|
|
|
|
|
self:newlocation()
|
|
|
|
|
end
|
2022-02-03 11:20:28 -05:00
|
|
|
|
2022-03-05 19:17:22 -05:00
|
|
|
function player:cb_south(place, dialog)
|
|
|
|
|
tangible.animate(place, {action="walk", dy=-1})
|
|
|
|
|
self:newlocation()
|
|
|
|
|
end
|
2022-02-03 11:20:28 -05:00
|
|
|
|
|
|
|
|
function player.cb_east(actor, place, dialog)
|
2022-03-05 19:17:22 -05:00
|
|
|
tangible.animate(actor, {action="walk", dx=1})
|
|
|
|
|
self:newlocation()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function player:cb_west(actor, place, dialog)
|
|
|
|
|
tangible.animate(actor, {action="walk", dx=-1})
|
|
|
|
|
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'
|
|
|
|
|
nt.count=1
|
|
|
|
|
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)
|
|
|
|
|
local rad=2
|
2022-03-05 19:17:22 -05:00
|
|
|
scratch={}
|
2022-02-03 16:23:14 -05:00
|
|
|
local lis=tangible.near(actor,rad,true,false)
|
2022-02-03 11:20:28 -05:00
|
|
|
pprint("cb_map ",lis)
|
|
|
|
|
for _,t in pairs(lis) do
|
2022-03-16 15:47:46 -04:00
|
|
|
if t~=actor then print(tangible.getclass(t)) end
|
2022-02-03 11:20:28 -05:00
|
|
|
local graphic,plane,x,y,z,facing = tangible.animstate(t)
|
|
|
|
|
local c=tangible.getclass(t)
|
|
|
|
|
local dx,dy=tangible.xyz(t)
|
|
|
|
|
local offset=(dy+rad)*(rad*2+1)+dx+rad
|
|
|
|
|
local cl=tangible.getclass(t)
|
2022-03-05 19:17:22 -05:00
|
|
|
local kind=t.kind or 'Nil'
|
2022-02-03 11:20:28 -05:00
|
|
|
if not scratch[offset] then scratch[offset]={} end
|
2022-03-05 19:17:22 -05:00
|
|
|
if not scratch[offset].count then scratch[offset].count={} end
|
|
|
|
|
if not scratch[offset].count[kind] then scratch[offset].count[kind]=0 end
|
|
|
|
|
if t.count then scratch[offset].count[kind]=scratch[offset].count[kind]+t.count end
|
2022-02-03 11:20:28 -05:00
|
|
|
end
|
2022-02-03 16:23:14 -05:00
|
|
|
for dy=-rad,rad do for line=0,1 do
|
2022-02-03 11:20:28 -05: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
|
|
|
|
|
local kc=0
|
|
|
|
|
local tc=0
|
|
|
|
|
local kstr=' '
|
2022-03-05 19:17:22 -05:00
|
|
|
if scratch[offset] then for k,c in pairs(scratch[offset].count) do if c>0 then
|
2022-02-03 16:23:14 -05:00
|
|
|
kc=kc+1
|
|
|
|
|
tc=tc+c
|
|
|
|
|
if kc>1 then kstr='M' else kstr=k end
|
2022-03-05 19:17:22 -05:00
|
|
|
end end end
|
|
|
|
|
lbuf=lbuf.."-"..kstr..(tc>0 and num2(tc) or " ")
|
2022-02-03 16:23:14 -05:00
|
|
|
end end
|
|
|
|
|
lbuf=lbuf.."-"
|
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-16 15:47:46 -04:00
|
|
|
print("In Player "..tangible.id(actor)..":")
|
2022-03-05 19:17:22 -05: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-16 15:47:46 -04:00
|
|
|
print("In Army "..tangible.id(v)..":")
|
2022-03-05 19:17:22 -05:00
|
|
|
for k2,v2 in pairs(v.Count) do print(" "..k2.." "..v2) end
|
2022-02-03 16:23:14 -05:00
|
|
|
end
|
2022-02-03 11:20:28 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|