local randomshit={}
randomshit.times={34.6,35.08,35.56,36.04,36.52,37.0,37.48,37.98,38.46,38.92,39.4,39.88,40.36,40.84,41.32,41.8,42.28,42.76,43.24,43.72,44.2,44.68,45.16,45.64,46.12,46.6,47.08,47.56,48.04,48.54,49.0,49.48,49.96,50.44,50.92,51.4,51.88,52.36,52.84,53.34,53.8,54.28,54.76,55.24,55.72,56.2,56.68,57.16,57.64,58.12,58.6,59.08,59.56,60.04,60.52,61.0,61.48,61.96,62.44,62.94,63.88,64.82,84.52,85.02,85.5,85.98,86.46,86.92,87.42,87.9,88.38,88.86,89.34,89.8,90.34,90.78,91.26,91.72,92.2,92.46,92.7,92.92,93.23,93.42,93.66,93.9,94.14,94.38,94.6,94.86,95.1,95.32,95.58,95.8,96.06,96.18,96.3,96.4,96.54,96.66,96.78,96.88,97.02,97.15,97.26,97.38,97.5,97.6,97.72,97.86}
randomshit.scaleMap={["BeastBoyBastard-DoomGuy.png"]=4.0,["BeastBoyBastard-DoomSymbolNerkz.png"]=4.0,["BeastBoyBastard-NerkzConverseblack.png"]=4.0,["BeastBoyBastard-TudorRose.png"]=4.0,["randomshit-01.png"]=4.0,["randomshit-02.png"]=4.0,["randomshit-03.png"]=4.0,["randomshit-04.png"]=4.0,["randomshit-05.png"]=4.0,["randomshit-06.png"]=4.0,["randomshit-07.png"]=4.0,["randomshit-08.png"]=4.0,["randomshit-09.png"]=4.0,["randomshit-10.png"]=4.0,["randomshit-11.png"]=4.0,["randomshit-12.png"]=4.0,["randomshit-13.png"]=4.0,["randomshit-14.png"]=4.0,["randomshit-15.png"]=4.0,["randomshit-16.png"]=4.0,["randomshit-17.png"]=4.0,["randomshit-18.png"]=4.0,["randomshit-19.png"]=4.0,["randomshit-20.png"]=4.0,["randomshit-21.png"]=4.0,["randomshit-22.png"]=4.0,["randomshit-23.png"]=4.0,["randomshit-24.png"]=4.0,["randomshit-25.png"]=4.0,["randomshit-26.png"]=4.0,["randomshit-27.png"]=4.0,["randomshit-28.png"]=4.0,["randomshit-29.png"]=4.0,["randomshit-30.png"]=4.0,["randomshit-31.png"]=4.0,["randomshit-32.png"]=4.0,["randomshit-33.png"]=4.0,["randomshit-34.png"]=4.0,["randomshit-35.png"]=4.0,["randomshit-36.png"]=4.0,["randomshit-37.png"]=4.0,["randomshit-38.png"]=4.0,["randomshit-39.png"]=4.0}
local _images={}
local _active={}
local _haveAll=true
local _missingList={}
local _nextIdx=1
local _lastT=0
local _elapsed=0
local _spawnQueue=nil
local _spawnIdx=1
local spawnAt,computeBounds
local buildFairSpawnQueue,fisherYatesShuffle,fixAdjacentDuplicates
local function currentTargetSize()
local c=love.graphics.getCanvas()
if c then return c:getWidth(),c:getHeight() end
return love.graphics.getWidth(),love.graphics.getHeight() end
function randomshit.load()
_images={}
_active={}
_haveAll=true
_missingList={}
if love.math and love.math.setRandomSeed then love.math.setRandomSeed(os.time()%100000) end
for _,fname in ipairs({"BeastBoyBastard-DoomGuy.png","BeastBoyBastard-DoomSymbolNerkz.png","BeastBoyBastard-NerkzConverseblack.png","BeastBoyBastard-TudorRose.png","randomshit-01.png","randomshit-02.png","randomshit-03.png","randomshit-04.png","randomshit-05.png","randomshit-06.png","randomshit-07.png","randomshit-08.png","randomshit-09.png","randomshit-10.png","randomshit-11.png","randomshit-12.png","randomshit-13.png","randomshit-14.png","randomshit-15.png","randomshit-16.png","randomshit-17.png","randomshit-18.png","randomshit-19.png","randomshit-20.png","randomshit-21.png","randomshit-22.png","randomshit-23.png","randomshit-24.png","randomshit-25.png","randomshit-26.png","randomshit-27.png","randomshit-28.png","randomshit-29.png","randomshit-30.png","randomshit-31.png","randomshit-32.png","randomshit-33.png","randomshit-34.png","randomshit-35.png","randomshit-36.png","randomshit-37.png","randomshit-38.png","randomshit-39.png"}) do
local ok,img=pcall(love.graphics.newImage,fname)
if ok and img then
img:setFilter("nearest","nearest")
table.insert(_images,{name=fname,img=img,w=img:getWidth(),h=img:getHeight()})
else
_haveAll=false
table.insert(_missingList,fname) end end
_nextIdx=1
_lastT=0
_elapsed=0
_spawnQueue=buildFairSpawnQueue(#randomshit.times)
_spawnIdx=1 end
function randomshit.setTimes(tlist)
randomshit.times=tlist or {}
table.sort(randomshit.times)
_nextIdx=1
_spawnQueue=buildFairSpawnQueue(#randomshit.times)
_spawnIdx=1 end
function randomshit.addTime(t)
if type(t)=="number" then
table.insert(randomshit.times,t)
table.sort(randomshit.times)
_spawnQueue=buildFairSpawnQueue(#randomshit.times)
_spawnIdx=1 end end
function randomshit.setScale(name,scale)
if type(name)=="string" and type(scale)=="number" then randomshit.scaleMap[name]=scale end end
function randomshit.setScaleMap(map)
if type(map)=="table" then randomshit.scaleMap=map end end
function randomshit.start(atTime)
_active={}
_elapsed=atTime or 0
_nextIdx=1
local times=randomshit.times
for i=1,#times do
if times[i]>=(_elapsed or 0) then
_nextIdx=i
break end
if i==#times then _nextIdx=#times+1 end end
_spawnQueue=buildFairSpawnQueue(#randomshit.times)
_spawnIdx=1 end
function randomshit.update(dt,t)
local curT
if type(t)=="number" then
curT=t
if curT+0.001<_lastT then randomshit.start(curT) end
else
_elapsed=_elapsed+dt
curT=_elapsed end
_lastT=curT
local times=randomshit.times
while _nextIdx<=#times and curT>=times[_nextIdx] do
spawnAt(curT)
_nextIdx=_nextIdx+1 end
local fade=0.67
for i=#_active,1,-1 do
local s=_active[i]
s.age=s.age+dt
s.alpha=math.max(0,1.0-(s.age/fade))
if s.alpha<=0 then table.remove(_active,i) end end end
function randomshit.draw()
if not _haveAll then
local w,h=currentTargetSize()
love.graphics.setColor(0.95,0.25,0.25,0.92)
local line="Some randomshit images are missing ("..tostring(#_missingList)..")."
local pad=8
local tw=math.min(w-20,520)
love.graphics.rectangle("fill",10,10,tw,36,6,6)
love.graphics.setColor(1,1,1,1)
love.graphics.print(line,16,18) end
for i=1,#_active do
local s=_active[i]
love.graphics.setColor(1,1,1,s.alpha)
love.graphics.draw(s.img,s.x,s.y,s.rot,s.scale,s.scale,s.ox,s.oy) end
love.graphics.setColor(1,1,1,1) end
buildFairSpawnQueue=function(totalSpawns)
local n=#_images
if n==0 or totalSpawns<=0 then return {} end
if n==1 then
local only=_images[1]
local q={}
for i=1,totalSpawns do q[i]=only end
return q end
local base=math.floor(totalSpawns/n)
local rem=totalSpawns%n
local idxOrder={}
for i=1,n do idxOrder[i]=i end
fisherYatesShuffle(idxOrder)
local counts={}
for i=1,n do counts[i]=base+((i<=rem) and 1 or 0) end
local realCounts={}
for pos=1,n do
local imgIndex=idxOrder[pos]
realCounts[imgIndex]=counts[pos] end
local bag={}
for i=1,n do
for k=1,realCounts[i] do
bag[#bag+1]=_images[i] end end
fisherYatesShuffle(bag)
fixAdjacentDuplicates(bag,32)
return bag end
fisherYatesShuffle=function(arr)
if(not arr)or(#arr<=1)then return end
local rand=(love.math and love.math.random)or math.random
for i=#arr,2,-1 do
local j=rand(1,i)
arr[i],arr[j]=arr[j],arr[i] end end
fixAdjacentDuplicates=function(arr,passes)
passes=passes or 16
local rand=(love.math and love.math.random)or math.random
local len=#arr
if len<=2 then return end
for i=1,passes do
local fixed=true
for i2=2,len do
if arr[i2].name==arr[i2-1].name then
fixed=false
local swapIdx=nil
for attempt=1,24 do
local j=rand(1,len)
if j~=i2 then
local a=arr[j]
local okPrev=(j==1)or(arr[j-1].name~=arr[i2].name)
local okNext=(j==len)or(arr[j+1].name~=arr[i2].name)
local okNeighborsForI=((i2==2)or(arr[i2-2].name~=a.name))and((i2==len)or(arr[i2+1].name~=a.name))
if okPrev and okNext and okNeighborsForI then
swapIdx=j
break end end end
if swapIdx then
arr[i2],arr[swapIdx]=arr[swapIdx],arr[i2]
else
local j=rand(1,len)
if j~=i2 then arr[i2],arr[j]=arr[j],arr[i2] end end end end
if fixed then break end end end
computeBounds=function(imgW,imgH,scale)
local w,h=currentTargetSize()
local halfW=(imgW*scale)*0.5
local halfH=(imgH*scale)*0.5
local margin=100
local minX=margin+halfW
local maxX=w-(margin+halfW)
local minY=margin+halfH
local maxY=h-(margin+halfH)
if minX>maxX then minX,maxX=w*0.5,w*0.5 end
if minY>maxY then minY,maxY=h*0.5,h*0.5 end
local rx=(love.math and love.math.random)and love.math.random()or math.random()
local ry=(love.math and love.math.random)and love.math.random()or math.random()
local x=minX+(maxX-minX)*rx
local y=minY+(maxY-minY)*ry
return x,y end
spawnAt=function(t)
if not _spawnQueue or #_spawnQueue==0 then return end
if _spawnIdx>#_spawnQueue then
_spawnQueue=buildFairSpawnQueue(#randomshit.times)
_spawnIdx=1 end
local entry=_spawnQueue[_spawnIdx]
_spawnIdx=_spawnIdx+1
if not entry then return end
local name=entry.name
local img=entry.img
local w,h=entry.w,entry.h
local scale=randomshit.scaleMap[name] or 1.0
local maxDeg=27
local rmin,rmax=-maxDeg,maxDeg
local rdeg
if love.math and love.math.random then
rdeg=love.math.random()*(rmax-rmin)+rmin
else
rdeg=math.random()*(rmax-rmin)+rmin end
local rot=rdeg*math.pi/180.0
local x,y=computeBounds(w,h,scale)
table.insert(_active,{img=img,name=name,x=x,y=y,rot=rot,scale=scale,ox=w*0.5,oy=h*0.5,age=0.0,alpha=1.0}) end
return randomshit
