Skip to content

Instantly share code, notes, and snippets.

@pilihp64
Created August 15, 2012 23:47
Show Gist options
  • Save pilihp64/3364791 to your computer and use it in GitHub Desktop.
Save pilihp64/3364791 to your computer and use it in GitHub Desktop.
TPT Multiplayer script
--Cracker64's Lua Multiplayer Script
--See forum post http://powdertoy.co.uk/Discussions/Thread/View.html?Thread=14352 for more info
--VER 1.2 UPDATE http://pastebin.com/raw.php?i=33mxQcvW
--Version 1.2
--TODO's
--COMPLETELY REDO EVERYTHING, except base tpt functions
--Something really screwed up inserting text into small strings in input box, later text gets cut off way too early
-------------------------------------------------------
-- = key, pressure/velocity reset
--CAPS_MODE, replace mode (for build 185+)
--Line tool is still off slightly
--These features are impossible (in v81), don't suggest them, even though they would be great
--load a save/stamp simultaneously
--sync view mode, gravity/wind modes
--signs, STKM controls
--AIR/VAC , WIND, PGRV/NGRV. no pressure,velocity,gravity get functions
--Deco editor (script doesn't run there)
--CHANGES:
--Basic inputbox
--Basic chat box, moving window
--Cleared everything
local issocket,socket = pcall(require,"socket")
if MANAGER_EXISTS then using_manager=true end
local PORT = 3000 --Change 3000 to your desired port
local KEYBOARD = 1 --only change if you have issues. Only other option right now is 2(finnish).
local tptversion = tpt.version.build
local ZSIZE = 16
local ZFACTOR = math.floor(256/ZSIZE)
local zoom_en = 0
local zoom_x = math.floor((612-ZSIZE)/2)
local zoom_y = math.floor((384-ZSIZE)/2)
local zoom_wx = 0
local zoom_wy = 0
local zoom_trig = 0
local GoLrule = {{0,0,0,0,0,0,0,0,0,2},{0,0,1,3,0,0,0,0,0,2},{0,0,1,3,0,0,2,0,0,2},{0,0,0,2,3,3,1,1,0,2},{0,1,1,2,0,1,2,0,0,2},{0,0,0,3,1,0,3,3,3,2},{0,1,0,3,0,3,0,2,1,2},{0,0,1,2,1,1,2,0,2,2},{0,0,1,3,0,2,0,2,1,2},{0,0,0,2,0,3,3,3,3,2},{0,0,0,3,3,0,0,0,0,2},{0,0,0,2,2,3,0,0,0,2},{0,0,1,3,0,1,3,3,3,2},{0,0,2,0,0,0,0,0,0,2},{0,1,1,3,1,1,0,0,0,2},{0,0,1,3,0,1,1,3,3,2},{0,0,1,1,3,3,2,2,2,2},{0,3,0,0,0,0,0,0,0,2},{0,3,0,3,0,3,0,3,0,2},{1,0,0,2,2,3,1,1,3,2},{0,0,0,3,1,1,0,2,1,4},{0,1,1,2,1,0,0,0,0,3},{0,0,2,1,1,1,1,2,2,6},{0,1,1,2,2,0,0,0,0,3},{0,0,2,0,2,0,3,0,0,3}}
--get different lists for other language keyboards
local keyboardshift = { {before=" qwertyuiopasdfghjklzxcvbnm1234567890-=.,/`|;'[]\\",after=" QWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_+><?~\\:\"{}|",},{before=" qwertyuiopasdfghjklzxcvbnm1234567890+,.-'´¨<",after=" QWERTYUIOPASDFGHJKLZXCVBNM!\"#¤%&/()=?;:_*`^>",} }
local keyboardaltrg = { {nil},{before=" qwertyuiopasdfghjklzxcvbnm1234567890+,.-'¨<",after=" qwertyuiopasdfghjklzxcvbnm1@£$€6{[]}\\,.-'~|",},}
local function shift(s)
if keyboardshift[KEYBOARD]~=nil then
return (s:gsub("(.)",function(c)return keyboardshift[KEYBOARD]["after"]:sub(keyboardshift[KEYBOARD]["before"]:find(c,1,true))end))
else return s end
end
local function altgr(s)
if keyboardaltgr[KEYBOARD]~=nil then
return (s:gsub("(.)",function(c)return keyboardaltgr[KEYBOARD]["after"]:sub(keyboardaltgr[KEYBOARD]["before"]:find(c,1,true))end))
else return s end
end
local ui_base local ui_box local ui_text local ui_button local ui_scrollbar local ui_inputbox local ui_chatbox
ui_base = {
new = function()
local b={}
b.drawlist = {}
function b:drawadd(f)
table.insert(self.drawlist,f)
end
function b:draw(...)
for _,f in ipairs(self.drawlist) do
if type(f)=="function" then
f(self,unpack(arg))
end
end
end
b.movelist = {}
function b:moveadd(f)
table.insert(self.movelist,f)
end
function b:onmove(x,y)
for _,f in ipairs(self.movelist) do
if type(f)=="function" then
f(self,x,y)
end
end
end
return b
end
}
ui_box = {
new = function(x,y,w,h,r,g,b)
local box=ui_base.new()
box.x=x box.y=y box.w=w box.h=h box.x2=x+w box.y2=y+h
box.r=r or 255 box.g=g or 255 box.b=b or 255
function box:setcolor(r,g,b) self.r=r self.g=g self.b=b end
box.drawbox=true
box:drawadd(function(self) if self.drawbox then tpt.drawrect(self.x,self.y,self.w,self.h,self.r,self.g,self.b) end end)
box:moveadd(function(self,x,y)
if x then self.x=self.x+x self.x2=self.x2+x end
if y then self.y=self.y+y self.y2=self.y2+y end
end)
return box
end
}
ui_text = {
new = function(text,x,y,r,g,b)
local txt = ui_base.new()
txt.text = text
txt.x=x or 0 txt.y=y or 0 txt.r=r or 255 txt.g=g or 255 txt.b=b or 255
function txt:setcolor(r,g,b) self.r=r self.g=g self.b=b end
txt:drawadd(function(self,x,y) tpt.drawtext(x or self.x,y or self.y,self.text,self.r,self.g,self.b) end)
txt:moveadd(function(self,x,y)
if x then self.x=self.x+x end
if y then self.y=self.y+y end
end)
function txt:process() return false end
return txt
end,
--Scrolls while holding mouse over
newscroll = function(text,x,y,vis,force,r,g,b)
local txt = ui_text.new(text,x,y,r,g,b)
if not force and tpt.textwidth(text)<vis then return txt end
txt.visible=vis
txt.length=string.len(text)
txt.start=1
local last=2
while tpt.textwidth(text:sub(1,last))<vis and last<=txt.length do
last=last+1
end
txt.last=last-1
txt.minlast=last-1
txt.ppl=((txt.visible-6)/(txt.length-txt.minlast+1))
function txt:update(text,pos)
if text then
self.text=text
self.length=string.len(text)
local last=2
while tpt.textwidth(text:sub(1,last))<self.visible and last<=self.length do
last=last+1
end
self.minlast=last-1
self.ppl=((self.visible-6)/(self.length-self.minlast+1))
if not pos then self.last=self.minlast end
end
if pos then
if pos>=self.last and pos<=self.length then --more than current visible
local newlast = pos
local newstart=1
while tpt.textwidth(self.text:sub(newstart,newlast))>= self.visible do
newstart=newstart+1
end
self.start=newstart self.last=newlast
elseif pos<self.start and pos>0 then --position less than current visible
local newstart=pos
local newlast=pos+1
while tpt.textwidth(self.text:sub(newstart,newlast))<self.visible and newlast<=self.length do
newlast=newlast+1
end
self.start=newstart self.last=newlast-1
end
--keep strings as long as possible (pulls from left)
local newlast=self.last
if newlast<self.minlast then newlast=self.minlast end
local newstart=1
while tpt.textwidth(self.text:sub(newstart,newlast))>= self.visible do
newstart=newstart+1
end
self.start=newstart
end
end
txt.drawlist={} --reset draw
txt:drawadd(function(self,x,y)
tpt.drawtext(x or self.x,y or self.y, self.text:sub(self.start,self.last) ,self.r,self.g,self.b)
end)
function txt:process(mx,my,button,event,wheel)
if event==3 then
local newlast = math.floor((mx-self.x)/self.ppl)+self.minlast
if newlast<self.minlast then newlast=self.minlast end
if newlast>0 and newlast~=self.last then
local newstart=1
while tpt.textwidth(self.text:sub(newstart,newlast))>= self.visible do
newstart=newstart+1
end
self.start=newstart self.last=newlast
end
end
end
return txt
end
}
ui_inputbox = {
new=function(x,y,w,h)
local intext=ui_box.new(x,y,w,h)
intext.cursor=0
intext.focus=false
intext.t=ui_text.newscroll("",x+2,y+2,w-2,true)
intext:drawadd(function(self)
local cursoradjust=tpt.textwidth(self.t.text:sub(self.t.start,self.cursor))+2
tpt.drawline(self.x+cursoradjust,self.y,self.x+cursoradjust,self.y+10,255,255,255)
self.t:draw()
end)
intext:moveadd(function(self,x,y) self.t:onmove(x,y) end)
function intext:setfocus(focus)
self.focus=focus
if focus then tpt.set_shortcuts(0) self:setcolor(255,255,0)
else tpt.set_shortcuts(1) self:setcolor(255,255,255) end
end
function intext:movecursor(amt)
self.cursor = self.cursor+amt
if self.cursor>self.t.length then self.cursor = self.t.length end
if self.cursor<0 then self.cursor = 0 return end
end
function intext:textprocess(key,nkey,modifier,event)
local modi = (modifier%1024)
if not self.focus or event~=1 then return end
if nkey==13 then local text=self.t.text self.cursor=0 self.t.text="" return text end
local newstr
if nkey==275 then self:movecursor(1) self.t:update(nil,self.cursor) return end
if nkey==276 then self:movecursor(-1) self.t:update(nil,self.cursor) return end
if nkey==8 then newstr=self.t.text:sub(1,self.cursor-1) .. self.t.text:sub(self.cursor+1) self:movecursor(-1)
elseif nkey==127 then newstr=self.t.text:sub(1,self.cursor) .. self.t.text:sub(self.cursor+2)
else
if nkey<32 or nkey>=127 then return end
local addkey = (modi==1 or modi==2) and shift(key) or key
if (math.floor(modi/512))==1 then addkey=altgr(key) end
newstr = self.t.text:sub(1,self.cursor) .. addkey .. self.t.text:sub(self.cursor+1)
self.t:update(newstr,self.cursor+1)
self:movecursor(1)
return
end
if newstr then
self.t:update(newstr,self.cursor)
end
--some actual text processing, lol
end
return intext
end
}
ui_scrollbar = {
new = function(x,y,h,t,m)
local bar = ui_base.new() --use line object as base?
bar.x=x bar.y=y bar.h=h
bar.total=t
bar.numshown=m
bar.pos=0
bar.length=math.floor((1/math.ceil(bar.total-bar.numshown+1))*bar.h)
bar.soffset=math.floor(bar.pos*((bar.h-bar.length)/(bar.total-bar.numshown)))
function bar:update(total,shown,pos)
self.pos=pos or 0
if self.pos<0 then self.pos=0 end
self.total=total
self.numshown=shown
self.length= math.floor((1/math.ceil(self.total-self.numshown+1))*self.h)
self.soffset= math.floor(self.pos*((self.h-self.length)/(self.total-self.numshown)))
end
function bar:move(wheel)
self.pos = self.pos-wheel
if self.pos < 0 then self.pos=0 end
if self.pos > (self.total-self.numshown) then self.pos=(self.total-self.numshown) end
self.soffset= math.floor(self.pos*((self.h-self.length)/(self.total-self.numshown)))
end
bar:drawadd(function(self)
if self.total > self.numshown then
tpt.drawline(self.x,self.y+self.soffset,self.x,self.y+self.soffset+self.length)
end
end)
bar:moveadd(function(self,x,y)
if x then self.x=self.x+x end
if y then self.y=self.y+y end
end)
function bar:process(mx,my,button,event,wheel)
if wheel~=0 and not hidden_mode then
if self.total > self.numshown then
local previous = self.pos
self:move(wheel)
if self.pos~=previous then
return wheel
end
end
end
--possibly click the bar and drag?
return false
end
return bar
end
}
ui_button = {
new = function(x,y,w,h,f,text)
local b = ui_box.new(x,y,w,h)
b.f=f
b.t=ui_text.new(text,x+2,y+2)
b.drawbox=false
b.almostselected=false
b.invert=true
b:drawadd(function(self)
if self.invert and self.almostselected then
self.almostselected=false
tpt.fillrect(self.x,self.y,self.w,self.h)
local tr=self.t.r local tg=self.t.g local tb=self.t.b
b.t:setcolor(0,0,0)
b.t:draw()
b.t:setcolor(tr,tg,tb)
else
b.t:draw()
end
end)
b:moveadd(function(self,x,y)
self.t:onmove(x,y)
end)
function b:process(mx,my,button,event,wheel)
if mx<self.x or mx>self.x2 or my<self.y or my>self.y2 then return false end
if event==3 then self.almostselected=true end
if event==2 then self:f() end
return true
end
return b
end
}
ui_chatbox = {
new=function(x,y,w,h)
local chat=ui_box.new(x,y,w,h)
chat.moving=false
chat.lastx=0
chat.lasty=0
chat.relx=0
chat.rely=0
chat.shown_lines=math.floor(chat.h/10)-1 --one line for top, one for chat
chat.max_width=chat.w-4
chat.max_lines=200
chat.lines = {}
chat.scrollbar = ui_scrollbar.new(chat.x2-2,chat.y+11,chat.h-22,0,chat.shown_lines)
chat.inputbox = ui_inputbox.new(x,chat.y2-10,w,10)
chat:drawadd(function(self)
tpt.drawtext(self.x+50,self.y+2,"Chat Box")
tpt.drawline(self.x+1,self.y+10,self.x2-1,self.y+10,120,120,120)
self.scrollbar:draw()
local count=0
for i,line in ipairs(self.lines) do
if i>self.scrollbar.pos and i<= self.scrollbar.pos+self.shown_lines-1 then
line:draw(self.x+3,self.y+12+(count*10))
count = count+1
end
end
self.inputbox:draw()
end)
chat:moveadd(function(self,x,y)
for i,line in ipairs(self.lines) do
line:onmove(x,y)
end
self.scrollbar:onmove(x,y)
self.inputbox:onmove(x,y)
end)
function chat:addline(line,r,g,b)
if not line or line=="" then return end --No blank lines
table.insert(self.lines,ui_text.newscroll(line,self.x,0,self.max_width,false,r,g,b))
if #self.lines>self.max_lines then table.remove(self.lines,1) end
self.scrollbar:update(#self.lines,self.shown_lines,#self.lines-self.shown_lines)
end
function chat:process(mx,my,button,event,wheel)
if self.moving and event==3 then
local newx,newy = mx-self.relx,my-self.rely
local ax,ay = 0,0
if newx<0 then ax = newx end
if newy<0 then ay = newy end
if (newx+self.w)>=612 then ax = newx+self.w-612 end
if (newy+self.h)>=384 then ay = newy+self.h-384 end
self:onmove(mx-self.lastx-ax,my-self.lasty-ay)
self.lastx=mx-ax
self.lasty=my-ay
return true
end
if self.moving and event==2 then self.moving=false return true end
if mx<self.x or mx>self.x2 or my<self.y or my>self.y2 then self.inputbox:setfocus(false) return false end
self.scrollbar:process(mx,my,button,event,wheel)
local which = math.floor((my-self.y)/10)
if event==1 and which==0 then self.moving=true self.lastx=mx self.lasty=my self.relx=mx-self.x self.rely=my-self.y return true end
if which==self.shown_lines then self.inputbox:setfocus(true) return true else self.inputbox:setfocus(false) end --trigger input_box
if which>0 and which<self.shown_lines and self.lines[which+self.scrollbar.pos] then self.lines[which+self.scrollbar.pos]:process(mx,my,button,event,wheel) end
return true
end
function chat:textprocess(key,nkey,modifier,event)
local text = self.inputbox:textprocess(key,nkey,modifier,event)
if text then self:addline(text) end
--self:addline("Key:"..tostring(nkey))
end
return chat
end
}
chatwindow = ui_chatbox.new(100,100,150,200)
local energytypes = { [18]=true, [31]=true, [136]=true, }
local validwalls = { [222]=true, [223]=true, [224]=true, [225]=true, [227]=true, [228]=true, [229]=true, [230]=true, [231]=true, [232]=true, [233]=true, [234]=true, [235]=true, [240]=true, [242]=true, [245]=true, }
local tools = { [236]=true, [237]=true, [238]=true, [239]=true, }
local disabled = { [226]=true,[236]=true,[239]=true,[241]=true,[243]=true,[244]=true,[246]=true,}
local setctype = { [9]=true,[74]=true,[83]=true,[85]=true,[93]=true,[153]=true,}
local function onstartup()
end
local datahandlers = {
b = function(words) otherbrx=tonumber(words[2]) otherbry=tonumber(words[3]) if words[4]~=nil then otherbrushmode=tonumber(words[4]) end end,
d = function(words) --draw left click
local n = tonumber(words[2])
x = n%1024
y = math.floor(n/1024)
if tonumber(words[3])~=nil then
drawstuff(x,y,otherbrx,otherbry,sleft,true,otherbrushmode)
else
create_line(lastmx,lastmy,x,y,otherbrx,otherbry,sleft,otherbrushmode)
end
lastmx = x
lastmy = y end,
r = function(words)
local n = tonumber(words[2])
x = n%1024
y = math.floor(n/1024)
if tonumber(words[3])~=nil then
drawstuff(x,y,otherbrx,otherbry,sright,true,otherbrushmode)
else
create_line(lastmx,lastmy,x,y,otherbrx,otherbry,sright,otherbrushmode)
end
lastmx = x
lastmy = y end,
l = function(words) --line left
create_line(tonumber(words[2]),tonumber(words[3]),tonumber(words[4]),tonumber(words[5]),otherbrx,otherbry,sleft,otherbrushmode) end,
lr = function(words) --line right
create_line(tonumber(words[2]),tonumber(words[3]),tonumber(words[4]),tonumber(words[5]),otherbrx,otherbry,sright,otherbrushmode) end,
bo = function(words) --box left
create_box(tonumber(words[2]),tonumber(words[3]),tonumber(words[4]),tonumber(words[5]),sleft) end,
br = function(words) --box right
create_box(tonumber(words[2]),tonumber(words[3]),tonumber(words[4]),tonumber(words[5]),sright) end,
s = function(words) --selected elements
sleft = tonumber(words[2])
sright = tonumber(words[3]) end,
clear = function(words)
clearsim()
infotext = otheruser .. " cleared the screen"
infoalpha = 255 end,
pause = function(words)
if words[2] ~= nil then
tpt.set_pause(tonumber(words[2]))
else
tpt.toggle_pause()
end
infotext = otheruser .. " toggled pause"
infoalpha = 255 end,
n = function(words) --username
otheruser = words[2]
statustext = "Connected with " .. otheruser end,
fps = function(words) --fps sync
otherfps = tonumber(words[2])
--if otherfps<myfps then fpscapped=true tpt.setfpscap(math.max(math.min(otherfps+1,60),3)) --fpscap sync fails epicly
--elseif fpscapped then if otherfps>=59 then fpscapped=false end tpt.setfpscap(math.max(math.min(otherfps+1,60),3)) end
sendbuffer = math.min(1/otherfps,0.1) end,
f = function(words) --framestep, syncs pause as well
pausenextframe = true
tpt.set_pause(0) end,
ch = function(words) --chat
table.insert(chatbox_messages, "o:".. command:sub(4))
if chatbox_hidden then chatbox_newmessage = true end end,
ping = function(words)
send("pong") end,
pong = function(words)
pingtext = "Ping: " .. math.ceil((os.clock()-lastping)*1000) end,
ver = function(words)
otherversion = tonumber(words[2])
if otherversion>version then statustext = otheruser.." has a newer version" end end,
ff = function(words)
x= tonumber(words[2]) y=tonumber(words[3]) c=tonumber(words[4])
floodparts(x,y,c,-1,-1) end,
}
--function that you can call from other scripts to recieve new packets and run functions
function newdatahandler(mess,func)
datahandlers[mess]=func
end
--newdatahandler("waffle",function(words) tpt.create(200,200,1) end)
local function readdata(data)
lastsent = data
lastpacket = os.clock()
local i = string.find(data,"|")
--go through all commands from the line
--infotext=lastsent infoalpha=255
while data~=nil do
if i~=nil then
command = string.sub(data,1,i-1)
--cut the first command off
data = string.sub(data,i+1)
i = string.find(data,"|")
else command=data data=nil --no data left
end
local words = {}
for word in string.gmatch(command, "%w+") do table.insert(words,word) end
--switch table for reading data, yay!
if type(datahandlers[words[1]])=="function" then datahandlers[words[1]](words) end
end
end
--Functions that do stuff in powdertoy
local function create(x,y,c,small)
local t = c%256
local v = math.floor(c/256)
if t==237 or t==238 then --heat and cool!
local temp = tpt.get_property("type",x,y)>0 and tpt.get_property("temp",x,y) or nil
if t==237 and temp~=nil and temp<9999 then
local heatchange = 4 --implement more temp changes later (ctrl-shift)
tpt.set_property("temp",math.min(temp+heatchange,9999),x,y)
elseif t==238 and temp~=nil and temp>0 then
local heatchange = 4
tpt.set_property("temp",math.max(temp-heatchange,0),x,y)
end
return
end
if small then --set ctype for CLNE types if smallish brush
if not setctype[c] then
local cm = tpt.get_property("type",x,y)
if setctype[cm] then
if (cm==74 or cm==153) and (c==35 or c==36) then return end --don't give PCLN ctypes of PSCN or NSCN
tpt.set_property("ctype",c,x,y)
return
end
end
end
if t==0 then
tpt.delete(x,y)
else
local i = tpt.create(x,y,t)
--special case for GoL creation
if t==78 and i>=0 then tpt.set_property("ctype",v,i) tpt.set_property("tmp",GoLrule[(v+2)][10],i) end
end
end
local function create_line(x1,y1,x2,y2,rx,ry,c,brush)
if c == 87 or c == 158 then return end --never do lines of FIGH and LIGH
local cp = math.abs(y2-y1)>math.abs(x2-x1)
local x = 0 local y = 0 local dx = 0 local dy = 0 local sy = 0 local e = 0.0 local de = 0.0 local first = true
if cp then y = x1 x1 = y1 y1 = y y = x2 x2 = y2 y2 = y end
if x1 > x2 then y = x1 x1 = x2 x2 = y y = y1 y1 = y2 y2 = y end
dx = x2 - x1 dy = math.abs(y2 - y1) if dx ~= 0 then de = dy/dx end
y = y1 if y1 < y2 then sy = 1 else sy = -1 end
for x = x1, x2 do
if cp then
drawstuff(y,x,rx,ry,c,first,brush)
else
drawstuff(x,y,rx,ry,c,first,brush)
end
first = false
e = e + de
if e >= 0.5 then
y = y + sy
e = e - 1
if y1<y2 then
if y>y2 then return end
elseif y<y2 then return end
if (rx+ry)==0 or c>=222 then
if cp then
drawstuff(y,x,rx,ry,c,first,brush)
else
drawstuff(x,y,rx,ry,c,first,brush)
end
end
end
end
end
local function create_box(x1,y1,x2,y2,c)
local i = 0 local j = 0
if x1>x2 then i=x2 x2=x1 x1=i end
if y1>y2 then j=y2 y2=y1 y1=j end
for j=y1, y2 do
for i=x1, x2 do
create(i,j,c)
end
end
end
local function incurrentbrush(i,j,rx,ry,brush)
if brush==0 then
return (math.pow(i,2)*math.pow(ry,2)+math.pow(j,2)*math.pow(rx,2)<=math.pow(rx,2)*math.pow(ry,2))
elseif brush==1 then
return (math.abs(i)<=rx and math.abs(j)<=ry)
elseif brush==2 then
return ((math.abs((rx+2*i)*ry+rx*j) + math.abs(2*rx*(j-ry)) + math.abs((rx-2*i)*ry+rx*j))<=(4*rx*ry))
else
return false
end
end
local function drawstuff(x,y,rx,ry,c,fill,brush)
local energycheck = energytypes[c]
local small = (rx+ry)<=16
if c == 87 or c == 158 then create(x,y,c) return end --only draw one pixel of FIGH and LIGH
--walls!
local dw = false local b = 0
if validwalls[c] then
dw = true
if c~=230 then b = c-100 end
end
if tools[c] then fill = true end
if dw then
local r=math.floor(rx/4)
local wx = math.floor(x/4)- math.floor(r/2)
local wy = math.floor(y/4)- math.floor(r/2)
if b==125 then
wx = wx + math.floor(r/2)
wy = wy + math.floor(r/2)
for v=-1,1 do
for u=-1,1 do
if (wx+u>=0 and wx+u<153 and wy+v>=0 and wy+v<96 and tpt.get_wallmap(wx+u,wy+v)==125) then
return
end end end
tpt.set_wallmap(wx,wy,b)
return
end
tpt.set_wallmap(wx,wy,r+1,r+1,b)
return
end
if rx<=0 then--0 radius loop prevention
for j=y-ry,y+ry do
if valid(x,j,energycheck,c) then
create(x,j,c,small) end
end
return
end
local tempy = y local oldy = y
if brush==2 then tempy=y+ry end
for i = x - rx, x do
oldy = tempy
local check = incurrentbrush(i-x,tempy-y,rx,ry,brush)
if check then
while check do
tempy = tempy - 1
check = incurrentbrush(i-x,tempy-y,rx,ry,brush)
end
tempy = tempy + 1
if fill then
local jmax = 2*y - tempy
if brush == 2 then jmax=y+ry end
for j = tempy, jmax do
if valid(i,j,energycheck,c) then
create(i,j,c,small) end
if i~=x and valid(x+x-i,j,energycheck,c) then
create(x+x-i,j,c,small) end
end
else
if (oldy ~= tempy and brush~=1) or i==x-rx then oldy = oldy - 1 end
for j = tempy, oldy+1 do
local i2=2*x-i local j2 = 2*y-j
if brush==2 then j2=y+ry end
if valid(i,j,energycheck,c) then
create(i,j,c,small) end
if i2~=i and valid(i2,j,energycheck,c) then
create(i2,j,c,small) end
if j2~=j and valid(i,j2,energycheck,c) then
create(i,j2,c,small) end
if i2~=i and j2~=j and valid(i2,j2,energycheck,c) then
create(i2,j2,c,small) end
end
end
end
end
end
local function valid(x,y,energycheck,c)
if x >= 0 and x < 612 and y >= 0 and y < 384 then
if energycheck then
if energytypes[tpt.get_property("type",x,y)] then return false end
end
return true end
end
local function floodparts(x,y,c,cm,bm)
local x1=x local x2=x
if cm==-1 then
if c==0 then
cm = tpt.get_property("type",x,y)
if cm==0 then return false end
else
cm = 0
end
end
--wall check here
while x1>=4 do
if (tpt.get_property("type",x1-1,y)~=cm) then break end
x1 = x1-1
end
while x2<=608 do
if (tpt.get_property("type",x2+1,y)~=cm) then break end
x2 = x2+1
end
for x=x1, x2 do
if c==0 then tpt.delete(x,y) end
if c>0 and c<222 then create(x,y,c) end
end
if y>=5 then
for x=x1,x2 do
if tpt.get_property("type",x,y-1)==cm then
if not floodparts(x,y-1,c,cm,bm) then
return false
end end end
end
if y<379 then
for x=x1,x2 do
if tpt.get_property("type",x,y+1)==cm then
if not floodparts(x,y+1,c,cm,bm) then
return false
end end end
end
return true
end
local function clearsim()
tpt.start_getPartIndex()
while tpt.next_getPartIndex() do
local index = tpt.getPartIndex()
tpt.set_property("type",0,index)
end
tpt.reset_velocity(0,0,153,96)
tpt.set_pressure(0,0,153,96,0)
tpt.set_wallmap(0,0,153,96,0)
end
local function mouse_coords_window_to_sim(window_x,window_y)
if (zoom_en>0 and window_x>=zoom_wx and window_y>=zoom_wy and window_x<(zoom_wx+ZFACTOR*ZSIZE) and window_y<(zoom_wy+ZFACTOR*ZSIZE)) then
return (math.floor((window_x-zoom_wx)/ZFACTOR)+zoom_x) , (math.floor((window_y-zoom_wy)/ZFACTOR)+zoom_y)
else
return window_x,window_y
end
end
local function step()
chatwindow:draw()
end
local function mouseclicky(mousex,mousey,button,event,wheel)
if chatwindow:process(mousex,mousey,button,event,wheel) then return false end
end
local function keyclicky(key,nkey,modifier,event)
chatwindow:textprocess(key,nkey,modifier,event)
end
tpt.register_keypress(keyclicky)
tpt.register_mouseclick(mouseclicky)
tpt.register_step(step)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment