Created
August 15, 2012 23:47
-
-
Save Pilihp64/3364791 to your computer and use it in GitHub Desktop.
TPT Multiplayer script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--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