Merge branch 'main' of https://github.com/jyelon/luprex into main

This commit is contained in:
2022-06-07 01:54:13 -04:00
7 changed files with 215 additions and 130 deletions

View File

@@ -9,3 +9,13 @@ function NilIsZero.__newindex(t,k,v)
if v~=nil and v~=0 then rawset(t,k,v) end
end
function seq(a,b,c) return a<=b and b<=c end
function bound(a,b,c)
if b<a then return b elseif b>c then return c else return b end
end
function lerp(a,b,c,d,e)
return d+(e-d)*(a-b)/(c-b)
end

View File

@@ -7,6 +7,6 @@ ut-table.lua
ut-globaldb.lua
ut-tablecmp.lua
basics.lua
uglyglobals.lua
login.lua
horps.lua
spectra.lua

View File

@@ -20,6 +20,7 @@ setmetatable(player,army)
--
-- New Data Structure:
-- Player.Stack={ 1=kind, 2=qty, 3=kind, 4=qty,... }
-- Player.Food[kind]=Number
-- orchard.crop='r'
-- orchard.size=integer -- Max size it can grow to
-- orchard.rate=integer -- How many grow per unit time()
@@ -70,9 +71,10 @@ function player:cb_conjurepaper() self:conjure('p',1) end
function player:cb_conjurescissor() self:conjure('s',1) end
function player:conjure(k,c)
for i=1,#self.stack,2 do if self.stack[i]==k then self.stack[i+1]=self.stack[i+1]+c return end end
for i=1,#self.stack,2 do if self.stack[i]==k then self.stack[i+1]=self.stack[i+1]+c self:cb_map() return end end
self.stack[#self.stack+1]=k
self.stack[#self.stack+1]=c
self:cb_map()
end
@@ -160,6 +162,15 @@ function fight0(ak,ac,dk,dc,tweekdefender) -- returns number of attacker casualt
end
function player:near_iter(rad,kind)
local lis=tangible.near(self,rad,true,true)
local i=1
return function()
while i<=#lis do
i=i+1
if not kind or isa(lis[i-1],kind) then return lis[i-1] end end end
end
function stack_iter(t1)
local i=0
return function()
@@ -191,67 +202,23 @@ function army:counttroops()
end
function army:die()
print("This enemy is dying!!!")
print("You defeat the enemy!")
tangible.delete(self)
print("And now it is dead, so sad")
end
function army:fight(enemy)
print("Fight!!!")
local rval={}
for i=1,math.min(#self.stack,#enemy.stack),2 do
loss1,loss2=fight0(self.stack[i],self.stack[i+1],enemy.stack[i],enemy.stack[i+1])
print("When "..self.stack[i+1].." "..self.stack[i].." fight "..enemy.stack[i+1].." "..enemy.stack[i].." they kill "..loss2.." and suffer "..loss1)
rval[1+#rval]={'fight',self.stack[i],self.stack[i+1],loss1,enemy.stack[i],enemy.stack[i+1],loss2}
self.stack[i+1]=self.stack[i+1]-loss1
enemy.stack[i+1]=enemy.stack[i+1]-loss2
end
compactstack(self.stack)
compactstack(enemy.stack)
if enemy:counttroops()==0 then enemy:die() end
return rval
if enemy:counttroops()==0 then enemy:die() return false
else return true end
end
-- for ak,ac,dk,dc in fight_iter(self.stack,enemy.stack) do
-- loss1,loss2=fight0(ak,ac,dk,dc)
-- print("When "..ac.." "..ak.." fight "..dc.." "..dk.." they kill "..loss2.." and suffer "..loss1)
-- rval[1+#rval]={'fight',ak,ac,loss1,dk,dc,loss2}
-- end
function player:xfight(enemy)
local rval={}
for ak,ac in pairs(self.Count) do -- Should randomize the order
local enemyk, enemyc
local useloss0
local useloss1=-1
local loss0,loss1
local whichdk, whichdc
for dk,dc in pairs(enemy.Count) do
loss0,loss1=army.fight0(ak,ac,dk,dc)
print("When "..ac.." "..ak.." fight "..dc.." "..dk.." they kill "..loss1.." and suffer "..loss0)
if loss1>useloss1 then
enemyk=dk
enemyc=dc
useloss1=loss1
useloss0=loss0
end end
if enemyk then
print("Army of "..ac.." "..ak.." fights "..enemyc.." "..enemyk..", killing "..useloss1.." and suffering "..useloss0)
rval[1+#rval]={'fight',ak,ac,useloss0,enemyk,enemyc,useloss1}
enemy.Count[enemyk]=enemy.Count[enemyk]-useloss1
self.Count[ak]=self.Count[ak]-useloss0
end
end
local enemyleft=0
local playerleft=0
for dk,dc in pairs(enemy.Count) do enemyleft=enemyleft+dc end
for ak,ac in pairs(self.Count) do playerleft=playerleft+ac end
rval.enemyleft=enemyleft
return rval
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
@@ -265,20 +232,23 @@ function player:droparmy(actor,kind)
t.Count[kind]=t.Count[kind]+1
end
function orchard:gather(actor)
actor.food[self.kind]=actor.inventory[self.kind]+self.count
function player:pickfruit(ft)
local kind=ft.crop
local qty=ft:harvest(ft:available())
self.food[kind]=self.food[kind]+qty
print("You harvest "..qty.." "..foodnames[kind])
end
function player:newlocation()
function player:newlocation() -- return false if the player should bounce back, else return true
local lis=tangible.near(self,0,true,true)
local count={} setmetatable(count,NilIsZero)
local count0=0
local result={}
for _,t in ipairs(lis) do if isa(t,army) then
result[1+#result]=self:fight(t)
end end
pprint(result)
return result
local bounce=false
for _,t in ipairs(lis) do
if isa(t,army) then bounce=bounce or self:fight(t)
elseif isa(t,orchard) then self:pickfruit(t) end
end
return bounce
end
function player:printanimstate()
@@ -288,16 +258,8 @@ function player:printanimstate()
function player:walk(dx,dy)
tangible.animate(self,{action='walk',dx=dx,dy=dy})
local result=self:newlocation()
if #result>1 then print("Error: multiple armies at one location")
elseif #result==1 then
tangible.animate(self,{action='walk',dx=-dx,dy=-dy}) end
if self:newlocation() then tangible.animate(self,{action='walk',dx=-dx,dy=-dy}) end
self:cb_map()
if #result==1 then
for i,v in ipairs(result[1]) do
if v[1]=='fight' then print(v[3]..v[2].." attacks "..v[6]..v[5]..", killing "..v[7].." while losing "..v[4]) end
end
end
end
function player:cb_north()
@@ -337,6 +299,7 @@ function where()
print("You are at "..x.." "..y)
end
function mapcelltext(lis)
if lis==nil then return ' ' end
if #lis>1 then return '++++++' end
@@ -348,14 +311,15 @@ function mapcelltext(lis)
for k,c in stack_iter(lis[1].stack) do rval=rval..k..(c>9 and '+' or tostring(c)) end
rval=rval..string.sub(' ',1,6-string.len(rval))
elseif isa(lis[1],orchard) then
rval=rval.." OO "
prefix="\27[32;1m" suffix="\27[0m"
rval=rval..lis[1].crop..string.format("%-5d",lis[1]:available())
end
return prefix..rval..suffix
end
function player.cb_map(actor,place,dialog)
print("\27c\27[38;5;9mMap:\27[0m")
print("\27[s\27[0;0f")
local rad=4
local ax,ay=tangible.xyz(actor)
scratch={}
@@ -378,62 +342,8 @@ function player.cb_map(actor,place,dialog)
lbuf=lbuf..'|'
print(lbuf)
end
print("\27[u")
end
function player.xcb_map(actor,place,dialog)
local rad=4
local ax,ay=tangible.xyz(actor)
local scratch={}
local lis=tangible.near(actor,1.5*rad,true,false)
print("\27c\27[38;5;9mMap:\27[0m")
for _,t in pairs(lis) do
local c=tangible.getclass(t)
local dx,dy=tangible.xyz(t)
local offset=(-dy+ay+rad)*(rad*2+1)+dx-ax+rad
local cl=tangible.getclass(t)
if seq(ax-rad,dx,ax+rad) and seq(ay-rad,dy,ay+rad) and (cl=='player' or cl=='army') then
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
end
-- pprint(scratch)
for dy=-rad,rad do for line=0,1 do
local lbuf="|"
for dx=-rad,rad do
local offset=(dy+rad)*(rad*2+1)+dx+rad
if line==0 then lbuf=lbuf.."----"
elseif line==1 then
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.."-"
end end
print(lbuf)
end end
lbuf=""
for dx=-rad,rad do lbuf=lbuf.."----" end
lbuf=lbuf.."-"
print(lbuf)
-- print("In Player "..tangible.id(actor)..":")
-- 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
-- print("In Army "..tangible.id(v)..":")
-- for k2,v2 in pairs(v.Count) do print(" "..k2.." "..v2) end
-- end
end
function counttoten(p1,p2,p3)
for i=1,10 do print(i) end
end

View File

@@ -17,8 +17,10 @@ function login.cb_seedprng(actor,place,dialog)
function login.cb_becomeplayer(actor, place, dialog)
actor.kind='P'
actor.Count={} setmetatable(actor.Count,NilIsZero)
actor.Food={} setmetatable(actor.Food,NilIsZero)
actor.food={} setmetatable(actor.food,NilIsZero)
actor.spectra={} setmetatable(actor.spectra,NilIsZero)
actor.stack={}
actor.team='red'
tangible.setclass(actor, player)
tangible.animate(actor,{action="warp",plane="main",x=0,y=0,z=0})
end

162
luprex/core/lua/spectra.lua Normal file
View File

@@ -0,0 +1,162 @@
makeclass('player')
makeclass('light')
freqcolor={ azure=152, black=35200, blue=59300, brown=20000, chocolate=1840, cream=8610,
crimson=575, fawn=272, gold=17300, green=34200, grey=17300, lemon=445,
lilac=1020, mauve=719, ochre=132, olive=1910, orange=22500, peach=3860,
pink=27200, purple=13700, red=52200, rose=4310, ruby=994, russet=68,
scarlet=315, silver=13200, violet=3590, white=45100, yellow=24400 }
function player:near_iter(rad,kind1,kind2,kind3)
local lis=tangible.near(self,rad,true,true)
local i=1
return function()
while i<=#lis do
i=i+1
if not kind1 or isa(lis[i-1],kind1,kind2,kind3) then return lis[i-1] end end end
end
function tandist(t1,t2)
local _,t1p,t1x,t1y=tangible.animstate(t1)
local _,t2p,t2x,t2y=tangible.animstate(t2)
return math.sqrt((t1x-t2x)*(t1x-t2x)+(t1y-t2y)*(t1y-t2y))
end
function player:radius_iter(rad,kind)
local lis=tangible.near(self,rad,true,true)
local i=1
return function()
while i<=#lis do
i=i+1
if (not kind or isa(lis[i-1],kind)) and tandist(self,lis[i-1])<=rad then return lis[i-1] end end end
end
function player:interface(place)
gui.menu_item("cb_dir0" ,"Go North")
gui.menu_item("cb_dir180" ,"Go South")
gui.menu_item("cb_dir270" ,"Go West")
gui.menu_item("cb_dir90" ,"Go East")
gui.menu_item("cb_map" ,"Map")
gui.menu_item("cb_spectra" ,"Show Spectra")
end
function player:cb_spectra()
for k,v in pairs(self.spectra) do print(string.format("%-6.6s:%s",k,string.sub('+++++++++++++++++++++++++',1,v))) end
end
function player:cb_dir0() self:move(0) end
function player:cb_dir45() self:move(45) end
function player:cb_dir90() self:move(90) end
function player:cb_dir135() self:move(135) end
function player:cb_dir180() self:move(180) end
function player:cb_dir215() self:move(215) end
function player:cb_dir270() self:move(270) end
function player:cb_dir315() self:move(315) end
function player:power()
local rval=0
for k,v in pairs(self.spectra) do if v>0 then rval=rval+1 end end
return rval
end
function player:respawn()
tangible.animate(self,{action='warp',plane='main',x=math.random(-40,40),y=math.random(-40,40),z=0})
self:cb_map()
print("You just died!") --
end
function player:fight(enemy)
local common={}
for k,v in pairs(self.spectra) do if enemy.spectra[k]>0 then common[k]=1 end end
local p0=self:power()
local p1=enemy:power()
local winner
if p0==p1 then
for k,v in pairs(common) self.spectra[k]=nil enemy.spectra[k]=nil end
else if p0>p1 then
for k,v in pairs(common) enemy.spectra[k]=nil end
else
for k,v in pairs(common) self.spectra[k]=nil end
end
p0=self:power()
p1=enemy:power()
if p1==0 then self.kills =self.kills+1 enemy.deaths=enemy.deaths+1 enemy:respawn() end
if p0==0 then self.deaths=self.deaths+1 enemy.kills =enemy.kills+1 self:respawn() end
end
function player:newlocation()
for lt in self:radius_iter(3.1,light) do self.spectra[lt.color]=25 end
for lt in self:radius_iter(3.1,player) do if self.team==lt.team then
local nspec={} setmetatable(nspec,NilIsZero)
for k,v in pairs(self.spectra) do nspec[k]=v end
for k,v in pairs(lt.spectra) do nspec[k]=math.max(v,nspec[k]) end
for k,v in pairs(nspec) do self.spectra[k]=v lt.spectra[k]=v end
end end
for lt in self:radius_iter(3.1,player) do if self.team~=lt.team then p1:fight(p2) end end
for k,v in pairs(self.spectra) do self.spectra[k]=self.spectra[k]-1 if self.spectra[k]<=0 then self.spectra[k]=nil end end
end
function player:move(degrees)
dx= math.cos((90-degrees)*math.pi/180)
dy=-math.sin((90-degrees)*math.pi/180)
tangible.animate(self,{action='walk',dx=dx,dy=dy})
self:newlocation()
self:map(12)
end
function wrcolor()
local acc=0
local rval
for k,v in pairs(freqcolor) do acc=acc+v if math.random(1,acc)<=v then rval=k end end
return rval
end
function makemap()
for i=1,100 do
local x=math.random(-50,50)
local y=math.random(-50,50)
local nt=tangible.build{class='light',x=x,y=y,z=0,plane='main',graphic='light'}
nt.color=wrcolor()
end
end
function setcell(array,x,y,val)
if not array[y] then array[y]={} end
array[y][x]=val
return array
end
function player:cb_map(place,dialog)
self:map(10)
end
teamcolor={ red='\27[91m', green='\27[92m', yellow='\27[93m', blue='\27[94m', magenta='\27[95m', cyan='\27[96m' }
function player:map(radius)
local radius=10
radius=radius or 10
local cells={}
local px,py=tangible.xyz(tangible.actor())
for lt in self:near_iter(1.5*radius,light,player) do
local lx,ly=tangible.xyz(lt)
lx=lx-px+radius
ly=ly-py+radius
if seq(0,ly,1+2*radius) and seq(0,lx,1+2*radius) then
local celltext
if isa(lt,light) then celltext=string.format("%-6.6s",lt.color)
elseif isa(lt,player) then celltext=teamcolor[lt.team].."Pl:"..string.format("%-3.0f",lt:power()).."\27[0m"
end
setcell(cells,math.floor(0.5+lx),math.floor(0.5+ly),celltext) end
end
setcell(cells,radius,radius,teamcolor[self.team]..string.format("Me:%-3.0f",self:power()).."\27[0m")
for ly=0,1+2*radius do
local line='|'
for lx=0,1+2*radius do
if cells[ly] and cells[ly][lx] then line=line..cells[ly][lx]..'|' else line=line..' |' end
end
print(line)
end
end

View File

@@ -28,12 +28,12 @@ function login.cb_uglytimedaemon()
function time() return ug.get('time') end
function isa(k1,k2)
if k1==k2 then return true end
function isa(k1,k2,k3,k4)
if k1==k2 or k1==k3 or k1==k4 then return true end
if k1==nil then return false end
local mt=getmetatable(k1)
if not mt then return false end
return isa(mt.__index,k2)
return isa(mt.__index,k2,k3,k4)
end
function tabcat(t1,t2)
@@ -41,9 +41,10 @@ function tabcat(t1,t2)
end
-- Example: multistart(function(t) return tangible.id(t)%3==0 end,function() print("Tangible "..tangible.id(tangible.place()).." here") end)
function multistart(filter,closure)
function multistart(fil,closure)
local lis=tangible.scan('nowhere',0,0,100,false)
tabcat(lis,tangible.scan('main',0,0,100,true))
local filter=type(fil)=='function' and fil or function(t) return isa(t,fil) end
for _,t in ipairs(lis) do if filter(t) then tangible.start(t,closure) end end
end

0
luprex/core/lua/util.lua Normal file
View File