nntrn / save

https://nntrn.github.io/save/
2 stars 0 forks source link

Lua for rooms.xyz #49

Open nntrn opened 4 months ago

nntrn commented 4 months ago

Hide walls and floor

getThing("NORTH_WALL"):setPosition(0, 100000, 0)
getThing("EAST_WALL"):setPosition(0, 100000, 0)
getThing("FLOOR"):setPosition(0, 100000, 0)

Movement

-- time when moving and waiting 
moveTime = 1

function moveSouth()
  -- Move 20 units south
  startMoveBy(0, 0, -20, moveTime)
  wait(moveTime, moveWest)
end

function moveWest()
  -- Turn body
  setRotation(0,-90,0)
  -- Move 20 units west
  startMoveBy(-20, 0, 0, moveTime)
  wait(moveTime, sayDone)
end

function sayLocation()
  say(string.format("%.1f %.1f %.1f", getPosition()))
end

function sayDone()
  sayLocation()
end

function onStart()
  sayLocation()
  wait(moveTime,moveSouth)
end

Get comments

function inspectComments(tbl)
  for j,r in ipairs(tbl) do
    for i,v in pairs(r) do
      print(string.format("[%d]%s: %s",j,i,v))
    end
    print(string.rep("-",10))
  end
end

function cb(cmt, cont) 
  --inspectComments(cmt)
  setMedia(cmt[1].photo)
  setText("@"..cmt[1].author)
  if cont ~= nil then
    cb(cmt,cont)
  end
end
nntrn commented 4 months ago

Debug

Print current location without using ..

print(string.format("%.1f/%.1f/%.1f", getPosition()))

local x,y,z = getPosition()
print(string.format("%.1f/%.1f/%.1f",x,y,z))
nntrn commented 4 months ago

Utils

-- https://stackoverflow.com/a/1407187
function listvalues(s)
    local t = { }
    for k,v in ipairs(s) do
        t[#t+1] = tostring(v)
    end
    return table.concat(t,"\n")
end

Print environment variable names

for key, value in pairs(_G) do 
  print(key, type(value))
end

function inspectTable(tbl)
  for i,v in pairs(tbl) do
    print(string.format("%s: %s",i,v))
  end
end
nntrn commented 4 months ago

Time

-- Converting `Seconds` to `Hours`;
function getHour(t)
  return (math.floor( t * (1/60) * (1/60) % 12 )) +1
end

-- returns array with hour, min, and seconds
function getTime(t)
  t = t or unixTime()
  --math.floor(unix_time / 3600 % 24)
  return    math.floor(t / 3600 % 12) +1
     , math.floor(t / 60 % 60)
     , math.floor(t % 60)
end

Set clock hands

function setHour(h)
  if h > 12 then h = h - 12 end
  local degree = round((h/12) * 360) * -1
  hourHand:setLocalRotation(0,0,degree)
end

function setMinutes(m)
  local degree = round((m/60) * 360) * -1
  minHand:setLocalRotation(0,0,degree)
end

Analog clock by alex

hourHand = getThing("A-Hour Hand")
minuteHand = getThing("A-Minute Hand")
secondHand = getThing("A-Second Hand")

function onStart()
  playSound("clockTick.mp3", true, 0.1)
  outputCurrentTime()
  moveHands()
end

function outputCurrentTime()
  hour, minute, second = formatTime(dateTime():sub(12, 19))

  local hourAngle = (hour % 12) * 30 + minute / 2
  local minuteAngle = minute * 6
  local secondAngle = second * 6

  hourHand:setRotation(0, 0, -hourAngle)
  minuteHand:setRotation(0, 0, -minuteAngle)
  secondHand:setRotation(0, 0, -secondAngle)
end

function formatTime(dateTimeString)
  local hour, minute, second = dateTimeString:match("(%d+):(%d+):(%d+)")
  hour, minute, second = tonumber(hour), tonumber(minute), tonumber(second)

  if hour > 12 then hour = hour - 12 end -- non-military time

  return hour, minute, second
end

function moveHands()
  hourHand:startSpin(-30/60/60,nil,"Z")
  minuteHand:startSpin(-360/60/60,nil,"Z")
  secondHand:startSpin(-360/60,nil,"Z")
end
dt = "01:09:23"
hour, minute, second = dt:match("(%d+):(%d+):(%d+)")
nntrn commented 4 months ago

Comments

function inspectComments(tbl)
  for j,r in ipairs(tbl) do
    for i,v in pairs(r) do
      print(string.format("[%d]%s: %s",j,i,v))
    end
    print(string.rep("-",10))
  end
end

function cb(cmt, cont) 
  --inspectComments(cmt)
  --setMedia(cmt[1].photo)
  --setText("@"..cmt[1].author)
  if cont ~= nil then
    cb(cont)
  end
end

function onStart()
  fetchComments(cb)
end
nntrn commented 3 months ago

Queues

Although we can implement queues trivially using insert and remove (from the table library), this implementation can be too slow for large structures. A more efficient implementation uses two indices, one for the first and another for the last element:

function ListNew ()
  return {first = 0, last = -1}
end

To avoid polluting the global space, we will define all list operations inside a table, properly called List. Therefore, we rewrite our last example like this:

List = {}

function List.new ()
  return {first = 0, last = -1}
end

-- Now, we can insert or remove an element at both ends in constant time:

function List.pushleft (list, value)
  local first = list.first - 1
  list.first = first
  list[first] = value
end

function List.pushright (list, value)
  local last = list.last + 1
  list.last = last
  list[last] = value
end

function List.popleft (list)
  local first = list.first
  if first > list.last then error("list is empty") end
  local value = list[first]
  list[first] = nil        -- to allow garbage collection
  list.first = first + 1
  return value
end

function List.popright (list)
  local last = list.last
  if list.first > last then error("list is empty") end
  local value = list[last]
  list[last] = nil         -- to allow garbage collection
  list.last = last - 1
  return value
end

https://www.lua.org/pil/11.4.html

nntrn commented 3 months ago

Color

-- source: urdad69

function rgbToHex(r, g, b)
  hex = string.format("#%02X%02X%02X", r, g, b)
end

function setColor()
  r = randomBetween(0, 255)
  g = randomBetween(0, 255)
  b = randomBetween(0, 255)
  rgbToHex(r, g, b)
  setTint(hex)
  setText(hex)
end

function hsvToRgb(h, s, v)
    local c = v * s
    local x = c * (1 - math.abs((h / 60) % 2 - 1))
    local m = v - c
    local r, g, b

    if h < 60 then
        r, g, b = c, x, 0
    elseif h < 120 then
        r, g, b = x, c, 0
    elseif h < 180 then
        r, g, b = 0, c, x
    elseif h < 240 then
        r, g, b = 0, x, c
    elseif h < 300 then
        r, g, b = x, 0, c
    else
        r, g, b = c, 0, x
    end

    r = (r + m) * 255
    g = (g + m) * 255
    b = (b + m) * 255

    return string.format("#%02X%02X%02X", math.floor(r), math.floor(g), math.floor(b))
end
-- source: suslike
HEX = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}

function onStart()
  setTint("" .. randomPick(HEX) .. randomPick(HEX) .. randomPick(HEX) .. randomPick(HEX) .. randomPick(HEX) .. randomPick(HEX))
end
-- source: btco
local COLOR_PER_TIER = {
  -- Tier 1
  {1.00, 1.00, 1.00},
  -- Tier 2
  {0.97, 1.00, 0.50},
  -- Tier 3
  {1.00, 0.65, 0.13},
  -- Tier 4
  {1.00, 0.40, 0.16}
}

function updateTint()
  if pinned then
    setTint(0, 1, 0)
  else
    -- Get the color from the COLOR_PER_TIER table, and
    -- pass it as R, G, B parameters to setTint.
    setTint(table.unpack(COLOR_PER_TIER[tier]))  
  end
end

Sources:

nntrn commented 3 months ago

The next example collects all pairs key=value from the given string into a table:

-- https://cyevgeniy.github.io/luadocs/06_standard_lib/ch04.html#string-manipulation

t = {}
s = "from=world, to=Lua"

for k, v in string.gmatch(s, "(%w+)=(%w+)") do
  t[k] = v
end
f()                -- adjusted to 0 results

g(f(), x)          -- f() is adjusted to 1 result

g(x, f())          -- g gets x plus all results from f()

a,b,c = f(), x     -- f() is adjusted to 1 result (c gets nil)

a,b = ...          -- a gets the first vararg argument, b gets the second (both a and b can get nil if there is no corresponding vararg argument)

a,b,c = x, f()     -- f() is adjusted to 2 results

a,b,c = f()        -- f() is adjusted to 3 results

return f()         -- returns all results from f()

return ...         -- returns all received vararg arguments

return x,y,f()     -- returns x, y, and all results from f()

{f()}              -- creates a list with all results from f()

{...}              -- creates a list with all vararg arguments

{f(), nil}         -- f() is adjusted to 1 result
total=0
function sum(n)
  total=total+(tonumber(n) or 0) 
end

string.gsub("1 2 5.3 7", "(%g+)", sum)
print(total)    -- returns 15.3

How to round to decimal

y=14.518239974976
print(math.floor(y*100)/100)   -- => 14.52
print(math.floor(y*1000)/1000) -- => 14.519
print(3 & 5)  -- bitwise and
print(3 | 5)  -- bitwise or
print(3 ~ 5)  -- bitwise xor
print(7 >> 1) -- bitwise right shift
print(7 << 1) -- bitwise left shift
print(~7)     -- bitwise not
1
7
6
3
14
-8
nntrn commented 3 months ago

Local Values

local score = 0
function onScore(args)
  score = score + (args.pts or 1)
  setText(score)
end
 -- to all text things with onScore()
broadcast("Score",{pts=5})

-- to single thing
send(getThing("thing name"),"Score",{pts=5})

Set Tint

function onStart()
  tint=getThing("FLOOR"):getTint()
  all=getParent():getChildren()
  getThing("NORTH_WALL"):setTint(tint)
  getThing("EAST_WALL"):setTint(tint)

  for k,v in ipairs(all) do
    if v:getTint() == "#ffffff" then
      v:setTint(tint)
    end
   -- print(v:getName())
  end
end

Prompt

-- source: rooms.xyz/jing/barchart
function onClick()
  prompt("Enter label", EditLabel)
end

function EditLabel(input)
  setText(input)
end

Tumbly Clone

-- from btco/clone
force = 30

function onClick()
  setPhysicsType("tumbly")
  playSound("ball.wav")
  applyForce(force, 150, force)
  particles("puff", getPosition())
  requestClone()
end

Resources