1function game_load(suspended) 2 scrollfactor = 0 3 backgroundcolor = {} 4 backgroundcolor[1] = {92, 148, 252} 5 backgroundcolor[2] = {0, 0, 0} 6 backgroundcolor[3] = {32, 56, 236} 7 love.graphics.setBackgroundColor(backgroundcolor[1]) 8 9 scrollingstart = 12 --when the scrolling begins to set in (Both of these take the player who is the farthest on the left) 10 scrollingcomplete = 10 --when the scrolling will be as fast as mario can run 11 scrollingleftstart = 6 --See above, but for scrolling left, and it takes the player on the right-estest. 12 scrollingleftcomplete = 4 13 superscroll = 100 14 15 --LINK STUFF 16 17 mariocoincount = 0 18 marioscore = 0 19 20 --get mariolives 21 mariolivecount = 3 22 if love.filesystem.exists("mappacks/" .. mappack .. "/settings.txt") then 23 local s = love.filesystem.read( "mappacks/" .. mappack .. "/settings.txt" ) 24 local s1 = s:split("\n") 25 for j = 1, #s1 do 26 local s2 = s1[j]:split("=") 27 if s2[1] == "lives" then 28 mariolivecount = tonumber(s2[2]) 29 end 30 end 31 end 32 33 if mariolivecount == 0 then 34 mariolivecount = false 35 end 36 37 mariolives = {} 38 for i = 1, players do 39 mariolives[i] = mariolivecount 40 end 41 42 mariosizes = {} 43 for i = 1, players do 44 mariosizes[i] = 1 45 end 46 47 autoscroll = true 48 49 inputs = { "door", "groundlight", "wallindicator", "cubedispenser", "walltimer", "notgate", "laser", "lightbridge"} 50 inputsi = {28, 29, 30, 43, 44, 45, 46, 47, 48, 67, 74, 84, 52, 53, 54, 55, 36, 37, 38, 39} 51 52 outputs = { "button", "laserdetector", "box", "pushbutton", "walltimer", "notgate"} 53 outputsi = {40, 56, 57, 58, 59, 20, 68, 69, 74, 84} 54 55 enemies = { "goomba", "koopa", "hammerbro", "plant", "lakito", "bowser", "cheep", "squid", "flyingfish", "goombahalf", "koopahalf", "cheepwhite", "cheepred", "koopared", "kooparedhalf", "koopa", "kooparedflying", "beetle", "beetlehalf", "spikey", "spikeyhalf"} 56 57 jumpitems = { "mushroom", "oneup" } 58 59 marioworld = 1 60 mariolevel = 1 61 mariosublevel = 0 62 respawnsublevel = 0 63 64 objects = nil 65 if suspended == true then 66 continuegame() 67 elseif suspended then 68 marioworld = suspended 69 end 70 71 --remove custom sprites 72 for i = smbtilecount+portaltilecount+1, #tilequads do 73 tilequads[i] = nil 74 end 75 76 for i = smbtilecount+portaltilecount+1, #rgblist do 77 rgblist[i] = nil 78 end 79 80 --add custom tiles 81 local bla = love.timer.getTime() 82 if love.filesystem.exists("mappacks/" .. mappack .. "/tiles.png") then 83 customtiles = true 84 customtilesimg = love.graphics.newImage("mappacks/" .. mappack .. "/tiles.png") 85 local imgwidth, imgheight = customtilesimg:getWidth(), customtilesimg:getHeight() 86 local width = math.floor(imgwidth/17) 87 local height = math.floor(imgheight/17) 88 local imgdata = love.image.newImageData("mappacks/" .. mappack .. "/tiles.png") 89 90 for y = 1, height do 91 for x = 1, width do 92 table.insert(tilequads, quad:new(customtilesimg, imgdata, x, y, imgwidth, imgheight)) 93 local r, g, b = getaveragecolor(imgdata, x, y) 94 table.insert(rgblist, {r, g, b}) 95 end 96 end 97 customtilecount = width*height 98 else 99 customtiles = false 100 customtilecount = 0 101 end 102 print("Custom tileset loaded in: " .. round(love.timer.getTime()-bla, 5)) 103 104 smbspritebatch = {} 105 portalspritebatch = {} 106 customspritebatch = {} 107 spritebatchX = {} 108 for i = 1, players do 109 smbspritebatch[i] = love.graphics.newSpriteBatch( smbtilesimg, 1000 ) 110 portalspritebatch[i] = love.graphics.newSpriteBatch( portaltilesimg, 1000 ) 111 if customtiles then 112 customspritebatch[i] = love.graphics.newSpriteBatch( customtilesimg, 1000 ) 113 end 114 spritebatchX[i] = 0 115 end 116 117 custommusic = false 118 if love.filesystem.exists("mappacks/" .. mappack .. "/music.ogg") then 119 custommusic = "mappacks/" .. mappack .. "/music.ogg" 120 music:load(custommusic) 121 elseif love.filesystem.exists("mappacks/" .. mappack .. "/music.mp3") then 122 custommusic = "mappacks/" .. mappack .. "/music.mp3" 123 music:load(custommusic) 124 end 125 print(custommusic) 126 127 --FINALLY LOAD THE DAMN LEVEL 128 levelscreen_load("initial") 129end 130 131function game_update(dt) 132 133 -------- 134 --GAME-- 135 -------- 136 137 --earthquake reset 138 if earthquake > 0 then 139 earthquake = math.max(0, earthquake-dt*earthquake*2-0.001) 140 sunrot = sunrot + dt 141 end 142 143 --pausemenu 144 if pausemenuopen then 145 return 146 end 147 148 --coinanimation 149 coinanimation = coinanimation + dt*6.75 150 while coinanimation > 6 do 151 coinanimation = coinanimation - 5 152 end 153 154 if math.floor(coinanimation) == 4 then 155 coinframe = 2 156 elseif math.floor(coinanimation) == 5 then 157 coinframe = 1 158 else 159 coinframe = math.floor(coinanimation) 160 end 161 162 --SCROLLING SCORES 163 local delete = {} 164 165 for i, v in pairs(scrollingscores) do 166 if scrollingscores[i]:update(dt) == true then 167 table.insert(delete, i) 168 end 169 end 170 171 table.sort(delete, function(a,b) return a>b end) 172 173 for i, v in pairs(delete) do 174 table.remove(scrollingscores, v) --remove 175 end 176 177 --If everyone's dead, just update the players and coinblock timer. 178 if everyonedead then 179 for i, v in pairs(objects["player"]) do 180 v:update(dt) 181 end 182 183 return 184 end 185 186 --timer 187 if editormode == false then 188 --get if any player has their controls disabled 189 local notime = false 190 for i = 1, players do 191 if (objects["player"][i].controlsenabled == false and objects["player"][i].dead == false) then 192 notime = true 193 end 194 end 195 196 if notime == false and infinitetime == false and mariotime ~= 0 then 197 mariotime = mariotime - 2.5*dt 198 199 if mariotime > 0 and mariotime + 2.5*dt >= 99 and mariotime < 99 then 200 love.audio.stop() 201 playsound(lowtime) 202 end 203 204 if mariotime > 0 and mariotime + 2.5*dt >= 99-7.5 and mariotime < 99-7.5 then 205 local star = false 206 for i = 1, players do 207 if objects["player"][i].starred then 208 star = true 209 end 210 end 211 212 if not star then 213 playmusic() 214 else 215 music:play("starmusic") 216 end 217 end 218 219 if mariotime <= 0 then 220 mariotime = 0 221 for i, v in pairs(objects["player"]) do 222 v:die("time") 223 end 224 end 225 end 226 end 227 228 --check if updates are blocked for whatever reason 229 if noupdate then 230 for i, v in pairs(objects["player"]) do 231 v:update(dt) 232 end 233 return 234 end 235 236 --portalgundelay 237 for i = 1, players do 238 if portaldelay[i] > 0 then 239 portaldelay[i] = math.max(0, portaldelay[i] - dt/speed) 240 end 241 end 242 243 --coinblockanimation 244 local delete = {} 245 246 for i, v in pairs(coinblockanimations) do 247 if coinblockanimations[i]:update(dt) == true then 248 table.insert(delete, i) 249 end 250 end 251 252 table.sort(delete, function(a,b) return a>b end) 253 254 for i, v in pairs(delete) do 255 table.remove(coinblockanimations, v) --remove 256 end 257 258 --nothing to see here 259 local delete = {} 260 261 for i, v in pairs(rainbooms) do 262 if v:update(dt) == true then 263 table.insert(delete, i) 264 end 265 end 266 267 table.sort(delete, function(a,b) return a>b end) 268 269 for i, v in pairs(delete) do 270 table.remove(rainbooms, v) --remove 271 end 272 273 --userects 274 local delete = {} 275 276 for i, v in pairs(userects) do 277 if v.delete == true then 278 table.insert(delete, i) 279 end 280 end 281 282 table.sort(delete, function(a,b) return a>b end) 283 284 for i, v in pairs(delete) do 285 table.remove(userects, v) --remove 286 end 287 288 --blockbounce 289 local delete = {} 290 291 for i, v in pairs(blockbouncetimer) do 292 if blockbouncetimer[i] < blockbouncetime then 293 blockbouncetimer[i] = blockbouncetimer[i] + dt 294 if blockbouncetimer[i] > blockbouncetime then 295 blockbouncetimer[i] = blockbouncetime 296 if blockbouncecontent then 297 item(blockbouncecontent[i], blockbouncex[i], blockbouncey[i], blockbouncecontent2[i]) 298 end 299 table.insert(delete, i) 300 end 301 end 302 end 303 304 table.sort(delete, function(a,b) return a>b end) 305 306 for i, v in pairs(delete) do 307 table.remove(blockbouncetimer, v) 308 table.remove(blockbouncex, v) 309 table.remove(blockbouncey, v) 310 table.remove(blockbouncecontent, v) 311 table.remove(blockbouncecontent2, v) 312 end 313 314 if #delete >= 1 then 315 generatespritebatch() 316 end 317 318 --coinblocktimer things 319 for i, v in pairs(coinblocktimers) do 320 if v[3] > 0 then 321 v[3] = v[3] - dt 322 end 323 end 324 325 --blockdebris 326 local delete = {} 327 328 for i, v in pairs(blockdebristable) do 329 if v:update(dt) == true then 330 table.insert(delete, i) 331 end 332 end 333 334 table.sort(delete, function(a,b) return a>b end) 335 336 for i, v in pairs(delete) do 337 table.remove(blockdebristable, v) --remove 338 end 339 340 --gelcannon 341 if objects["player"][mouseowner] and playertype == "gelcannon" and objects["player"][mouseowner].controlsenabled then 342 if gelcannontimer > 0 then 343 gelcannontimer = gelcannontimer - dt 344 if gelcannontimer < 0 then 345 gelcannontimer = 0 346 end 347 else 348 if love.mouse.isDown("l") then 349 gelcannontimer = gelcannondelay 350 objects["player"][mouseowner]:shootgel(1) 351 elseif love.mouse.isDown("r") then 352 gelcannontimer = gelcannondelay 353 objects["player"][mouseowner]:shootgel(2) 354 end 355 end 356 end 357 358 --seesaws 359 for i, v in pairs(seesaws) do 360 v:update(dt) 361 end 362 363 --platformspawners 364 for i, v in pairs(platformspawners) do 365 v:update(dt) 366 end 367 368 --Bubbles 369 local delete = {} 370 371 for i, v in pairs(bubbles) do 372 if v:update(dt) == true then 373 table.insert(delete, i) 374 end 375 end 376 377 table.sort(delete, function(a,b) return a>b end) 378 379 for i, v in pairs(delete) do 380 table.remove(bubbles, v) --remove 381 end 382 383 --Miniblocks 384 local delete = {} 385 386 for i, v in pairs(miniblocks) do 387 if v:update(dt) == true then 388 table.insert(delete, i) 389 end 390 end 391 392 table.sort(delete, function(a,b) return a>b end) 393 394 for i, v in pairs(delete) do 395 table.remove(miniblocks, v) --remove 396 end 397 398 --Fireworks 399 local delete = {} 400 401 for i, v in pairs(fireworks) do 402 if v:update(dt) == true then 403 table.insert(delete, i) 404 end 405 end 406 407 table.sort(delete, function(a,b) return a>b end) 408 409 for i, v in pairs(delete) do 410 table.remove(fireworks, v) --remove 411 end 412 413 --EMANCIPATION GRILLS 414 local delete = {} 415 for i, v in pairs(emancipationgrills) do 416 if v:update(dt) then 417 table.insert(delete, i) 418 end 419 end 420 421 table.sort(delete, function(a,b) return a>b end) 422 423 for i, v in pairs(delete) do 424 table.remove(emancipationgrills, v) 425 end 426 427 --BULLET BILL LAUNCHERS 428 local delete = {} 429 for i, v in pairs(rocketlaunchers) do 430 if v:update(dt) then 431 table.insert(delete, i) 432 end 433 end 434 435 table.sort(delete, function(a,b) return a>b end) 436 437 for i, v in pairs(delete) do 438 table.remove(rocketlaunchers, v) 439 end 440 441 --UPDATE OBJECTS 442 for i, v in pairs(objects) do 443 if i ~= "tile" and i ~= "portalwall" and i ~= "screenboundary" then 444 delete = {} 445 446 for j, w in pairs(v) do 447 if w.update and w:update(dt) then 448 table.insert(delete, j) 449 elseif w.autodelete then 450 if w.x < xscroll - width or w.y > 16 then 451 table.insert(delete,j) 452 end 453 end 454 end 455 456 if #delete > 0 then 457 table.sort(delete, function(a,b) return a>b end) 458 459 for j, w in pairs(delete) do 460 table.remove(v, w) 461 end 462 end 463 end 464 end 465 466 local oldscroll = splitxscroll[1] 467 468 if autoscroll and minimapdragging == false then 469 local splitwidth = width/#splitscreen 470 for split = 1, #splitscreen do 471 local oldscroll = splitxscroll[split] 472 --scrolling 473 --LEFT 474 local i = 1 475 while i <= players and objects["player"][i].dead do 476 i = i + 1 477 end 478 local fastestplayer = objects["player"][i] 479 480 if fastestplayer then 481 for i = 1, players do 482 if not objects["player"][i].dead and objects["player"][i].x > fastestplayer.x then 483 fastestplayer = objects["player"][i] 484 end 485 end 486 487 local oldscroll = splitxscroll[split] 488 489 if fastestplayer.x < splitxscroll[split] + scrollingleftstart and splitxscroll[split] > 0 then 490 491 if fastestplayer.x < splitxscroll[split] + scrollingleftstart and fastestplayer.speedx < 0 then 492 if fastestplayer.speedx < -scrollrate then 493 splitxscroll[split] = splitxscroll[split] - scrollrate*dt 494 else 495 splitxscroll[split] = splitxscroll[split] + fastestplayer.speedx*dt 496 end 497 end 498 499 if fastestplayer.x < splitxscroll[split] + scrollingleftcomplete then 500 if fastestplayer.x > splitxscroll[split] + scrollingleftcomplete - 1/16 then 501 splitxscroll[split] = splitxscroll[split] - scrollrate*dt 502 else 503 splitxscroll[split] = splitxscroll[split] - superscrollrate*dt 504 end 505 end 506 507 if splitxscroll[split] < 0 then 508 splitxscroll[split] = 0 509 end 510 end 511 512 --RIGHT 513 514 if fastestplayer.x > splitxscroll[split] + width - scrollingstart and splitxscroll[split] < mapwidth - width then 515 if fastestplayer.x > splitxscroll[split] + width - scrollingstart and fastestplayer.speedx > 0.3 then 516 if fastestplayer.speedx > scrollrate then 517 splitxscroll[split] = splitxscroll[split] + scrollrate*dt 518 else 519 splitxscroll[split] = splitxscroll[split] + fastestplayer.speedx*dt 520 end 521 end 522 523 if fastestplayer.x > splitxscroll[split] + width - scrollingcomplete then 524 if fastestplayer.x > splitxscroll[split] + width - scrollingcomplete then 525 splitxscroll[split] = splitxscroll[split] + scrollrate*dt 526 if splitxscroll[split] > fastestplayer.x - (width - scrollingcomplete) then 527 splitxscroll[split] = fastestplayer.x - (width - scrollingcomplete) 528 end 529 else 530 splitxscroll[split] = fastestplayer.x - (width - scrollingcomplete) 531 end 532 end 533 end 534 535 --just force that shit 536 if not levelfinished then 537 if fastestplayer.x > splitxscroll[split] + width - scrollingcomplete then 538 splitxscroll[split] = splitxscroll[split] + superscroll*dt 539 if fastestplayer.x < splitxscroll[split] + width - scrollingcomplete then 540 splitxscroll[split] = fastestplayer.x - width + scrollingcomplete 541 end 542 --splitxscroll[split] = fastestplayer.x + width - scrollingcomplete - width 543 end 544 end 545 546 if splitxscroll[split] > mapwidth-width then 547 splitxscroll[split] = math.max(0, mapwidth-width) 548 hitrightside() 549 end 550 551 if (axex and splitxscroll[split] > axex-width and axex >= width) then 552 splitxscroll[split] = axex-width 553 hitrightside() 554 end 555 end 556 end 557 558 end 559 560 if players == 2 then 561 --updatesplitscreen() 562 end 563 564 --SPRITEBATCH UPDATE and CASTLEREPEATS 565 if math.floor(splitxscroll[1]) ~= spritebatchX[1] then 566 if not editormode then 567 for currentx = lastrepeat+1, math.floor(splitxscroll[1])+2 do 568 lastrepeat = math.floor(currentx) 569 --castlerepeat? 570 --get mazei 571 local mazei = 0 572 573 for j = 1, #mazeends do 574 if mazeends[j] < currentx+width then 575 mazei = j 576 end 577 end 578 579 --check if maze was solved! 580 for i = 1, players do 581 if objects["player"][i].mazevar == mazegates[mazei] then 582 local actualmaze = 0 583 for j = 1, #mazestarts do 584 if objects["player"][i].x > mazestarts[j] then 585 actualmaze = j 586 end 587 end 588 mazesolved[actualmaze] = true 589 for j = 1, players do 590 objects["player"][j].mazevar = 0 591 end 592 break 593 end 594 end 595 596 if not mazesolved[mazei] or mazeinprogress then --get if inside maze 597 if not mazesolved[mazei] then 598 mazeinprogress = true 599 end 600 601 local x = math.ceil(currentx)+width 602 603 if repeatX == 0 then 604 repeatX = mazestarts[mazei] 605 end 606 607 table.insert(map, x, {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}}) 608 for y = 1, 15 do 609 for j = 1, #map[repeatX][y] do 610 map[x][y][j] = map[repeatX][y][j] 611 end 612 map[x][y]["gels"] = {} 613 614 for cox = mapwidth, x, -1 do 615 --move objects 616 if objects["tile"][cox .. "-" .. y] then 617 objects["tile"][cox + 1 .. "-" .. y] = tile:new(cox, y-1, 1, 1, true) 618 objects["tile"][cox .. "-" .. y] = nil 619 end 620 end 621 622 --create object for block 623 if tilequads[map[repeatX][y][1]].collision == true then 624 objects["tile"][x .. "-" .. y] = tile:new(x-1, y-1, 1, 1, true) 625 end 626 end 627 mapwidth = mapwidth + 1 628 repeatX = repeatX + 1 629 if flagx then 630 flagx = flagx + 1 631 flagimgx = flagimgx + 1 632 objects["screenboundary"]["flag"].x = objects["screenboundary"]["flag"].x + 1 633 end 634 635 if axex then 636 axex = axex + 1 637 objects["screenboundary"]["axe"].x = objects["screenboundary"]["axe"].x + 1 638 end 639 640 if firestartx then 641 firestartx = firestartx + 1 642 end 643 644 objects["screenboundary"]["right"].x = objects["screenboundary"]["right"].x + 1 645 646 --move mazestarts and ends 647 for i = 1, #mazestarts do 648 mazestarts[i] = mazestarts[i]+1 649 mazeends[i] = mazeends[i]+1 650 end 651 652 --check for endblock 653 local x = math.ceil(currentx)+width 654 for y = 1, 15 do 655 if map[x][y][2] and entityquads[map[x][y][2]].t == "mazeend" then 656 if mazesolved[mazei] then 657 repeatX = mazestarts[mazei+1] 658 end 659 mazeinprogress = false 660 end 661 end 662 663 --reset thingie 664 665 local x = math.ceil(currentx)+width-1 666 for y = 1, 15 do 667 if map[x][y][2] and entityquads[map[x][y][2]].t == "mazeend" then 668 for j = 1, players do 669 objects["player"][j].mazevar = 0 670 end 671 end 672 end 673 end 674 end 675 end 676 677 generatespritebatch() 678 spritebatchX[1] = math.floor(splitxscroll[1]) 679 680 if editormode == false and splitxscroll[1] < mapwidth-width then 681 for x = math.ceil(oldscroll)+width+1, math.floor(splitxscroll[1])+width+1 do 682 for y = 1, 15 do 683 spawnenemy(x, y) 684 end 685 if goombaattack then 686 local randomtable = {} 687 for y = 1, 15 do 688 table.insert(randomtable, y) 689 end 690 while #randomtable > 0 do 691 local rand = math.random(#randomtable) 692 if tilequads[map[x][randomtable[rand]][1]].collision then 693 table.remove(randomtable, rand) 694 else 695 table.insert(objects["goomba"], goomba:new(x-.5, math.random(13))) 696 break 697 end 698 end 699 end 700 end 701 end 702 end 703 704 --portal animation 705 portalanimationtimer = portalanimationtimer + dt 706 while portalanimationtimer > portalanimationdelay do 707 portalanimationtimer = 0 708 portalanimation = portalanimation + 1 709 if portalanimation > portalanimationcount then 710 portalanimation = 1 711 end 712 end 713 714 --portal particles 715 portalparticletimer = portalparticletimer + dt 716 while portalparticletimer > portalparticletime do 717 portalparticletimer = portalparticletimer - portalparticletime 718 719 for i, v in pairs(objects["player"]) do 720 if v.portal1facing ~= nil then 721 local x1, y1 722 723 if v.portal1facing == "up" then 724 x1 = v.portal1X + math.random(1, 30)/16 -1 725 y1 = v.portal1Y-1 726 elseif v.portal1facing == "down" then 727 x1 = v.portal1X + math.random(1, 30)/16-2 728 y1 = v.portal1Y 729 elseif v.portal1facing == "left" then 730 x1 = v.portal1X-1 731 y1 = v.portal1Y + math.random(1, 30)/16-2 732 elseif v.portal1facing == "right" then 733 x1 = v.portal1X 734 y1 = v.portal1Y + math.random(1, 30)/16-1 735 end 736 737 local color 738 if players == 1 then 739 color = {157, 222, 254} 740 else 741 color = v.portal1color 742 end 743 744 table.insert(portalparticles, portalparticle:new(x1, y1, color, v.portal1facing)) 745 end 746 747 if v.portal2facing ~= nil then 748 local x2, y2 749 750 if v.portal2facing == "up" then 751 x2 = v.portal2X + math.random(1, 30)/16 -1 752 y2 = v.portal2Y-1 753 elseif v.portal2facing == "down" then 754 x2 = v.portal2X + math.random(1, 30)/16-2 755 y2 = v.portal2Y 756 elseif v.portal2facing == "left" then 757 x2 = v.portal2X-1 758 y2 = v.portal2Y + math.random(1, 30)/16-2 759 elseif v.portal2facing == "right" then 760 x2 = v.portal2X 761 y2 = v.portal2Y + math.random(1, 30)/16-1 762 end 763 764 local color 765 if players == 1 then 766 color = {255, 122, 66} 767 else 768 color = v.portal2color 769 end 770 771 table.insert(portalparticles, portalparticle:new(x2, y2, color, v.portal2facing)) 772 end 773 end 774 end 775 776 delete = {} 777 778 for i, v in pairs(portalparticles) do 779 if v:update(dt) == true then 780 table.insert(delete, i) 781 end 782 end 783 784 table.sort(delete, function(a,b) return a>b end) 785 786 for i, v in pairs(delete) do 787 table.remove(portalparticles, v) --remove 788 end 789 790 --PORTAL PROJECTILES 791 delete = {} 792 793 for i, v in pairs(portalprojectiles) do 794 if v:update(dt) == true then 795 table.insert(delete, i) 796 end 797 end 798 799 table.sort(delete, function(a,b) return a>b end) 800 801 for i, v in pairs(delete) do 802 table.remove(portalprojectiles, v) --remove 803 end 804 805 --FIRE SPAWNING 806 if not levelfinished and firestarted and (not objects["bowser"][1] or (objects["bowser"][1].backwards == false and objects["bowser"][1].shot == false and objects["bowser"][1].fall == false)) then 807 firetimer = firetimer + dt 808 while firetimer > firedelay do 809 firetimer = firetimer - firedelay 810 firedelay = math.random(4) 811 table.insert(objects["fire"], fire:new(splitxscroll[1] + width, math.random(3)+7)) 812 end 813 end 814 815 --FLYING FISH 816 if not levelfinished and flyingfishstarted then 817 flyingfishtimer = flyingfishtimer + dt 818 while flyingfishtimer > flyingfishdelay do 819 flyingfishtimer = flyingfishtimer - flyingfishdelay 820 flyingfishdelay = math.random(6, 20)/10 821 table.insert(objects["flyingfish"], flyingfish:new()) 822 end 823 end 824 825 --BULLET BILL 826 if not levelfinished and bulletbillstarted then 827 bulletbilltimer = bulletbilltimer + dt 828 while bulletbilltimer > bulletbilldelay do 829 bulletbilltimer = bulletbilltimer - bulletbilldelay 830 bulletbilldelay = math.random(5, 40)/10 831 table.insert(objects["bulletbill"], bulletbill:new(splitxscroll[1]+width+2, math.random(4, 12), "left")) 832 end 833 end 834 835 --minecraft stuff 836 if breakingblockX then 837 breakingblockprogress = breakingblockprogress + dt 838 if breakingblockprogress > minecraftbreaktime then 839 breakblock(breakingblockX, breakingblockY) 840 breakingblockX = nil 841 end 842 end 843 844 --Editor 845 if editormode then 846 editor_update(dt) 847 end 848 849 --PHYSICS 850 physicsupdate(dt) 851end 852 853function game_draw() 854 for split = 1, #splitscreen do 855 love.graphics.translate((split-1)*width*16*scale/#splitscreen, yoffset*scale) 856 857 --This is just silly 858 if earthquake > 0 then 859 local colortable = {{242, 111, 51}, {251, 244, 174}, {95, 186, 76}, {29, 151, 212}, {101, 45, 135}, {238, 64, 68}} 860 for i = 1, backgroundstripes do 861 local r, g, b = unpack(colortable[math.mod(i-1, 6)+1]) 862 local a = earthquake/rainboomearthquake*255 863 864 love.graphics.setColor(r, g, b, a) 865 866 local alpha = math.rad((i/backgroundstripes + math.mod(sunrot/5, 1)) * 360) 867 local point1 = {width*8*scale+300*scale*math.cos(alpha), 112*scale+300*scale*math.sin(alpha)} 868 869 local alpha = math.rad(((i+1)/backgroundstripes + math.mod(sunrot/5, 1)) * 360) 870 local point2 = {width*8*scale+300*scale*math.cos(alpha), 112*scale+300*scale*math.sin(alpha)} 871 872 love.graphics.polygon("fill", width*8*scale, 112*scale, point1[1], point1[2], point2[1], point2[2]) 873 end 874 end 875 876 love.graphics.setColor(255, 255, 255, 255) 877 --tremoooor! 878 if earthquake > 0 then 879 tremorx = (math.random()-.5)*2*earthquake 880 tremory = (math.random()-.5)*2*earthquake 881 882 love.graphics.translate(round(tremorx), round(tremory)) 883 end 884 885 local currentscissor = {(split-1)*width*16*scale/#splitscreen, 0, width*16*scale/#splitscreen, 15*16*scale} 886 love.graphics.setScissor(unpack(currentscissor)) 887 xscroll = splitxscroll[split] 888 889 love.graphics.setColor(255, 255, 255, 255) 890 891 local xtodraw 892 if mapwidth < width+1 then 893 xtodraw = math.ceil(mapwidth/#splitscreen) 894 else 895 if mapwidth > width and xscroll < mapwidth-width then 896 xtodraw = width+1 897 else 898 xtodraw = width 899 end 900 end 901 902 --custom background 903 if custombackground then 904 for i = #custombackgroundimg, 1, -1 do 905 local xscroll = xscroll / (i * scrollfactor + 1) 906 if reversescrollfactor() == 1 then 907 xscroll = 0 908 end 909 for y = 1, math.ceil(15/custombackgroundheight[i]) do 910 for x = 1, math.ceil(width/custombackgroundwidth[i])+1 do 911 love.graphics.draw(custombackgroundimg[i], math.floor(((x-1)*custombackgroundwidth[i])*16*scale) - math.floor(math.mod(xscroll, custombackgroundwidth[i])*16*scale), (y-1)*custombackgroundheight[i]*16*scale, 0, scale, scale) 912 end 913 end 914 end 915 end 916 917 --Mushroom under tiles 918 for j, w in pairs(objects["mushroom"]) do 919 w:draw() 920 end 921 922 --Flowers under tiles 923 for j, w in pairs(objects["flower"]) do 924 w:draw() 925 end 926 927 --Oneupunder tiles 928 for j, w in pairs(objects["oneup"]) do 929 w:draw() 930 end 931 932 --star tiles 933 for j, w in pairs(objects["star"]) do 934 w:draw() 935 end 936 937 --castleflag 938 if levelfinished and levelfinishtype == "flag" and not custombackground then 939 love.graphics.draw(castleflagimg, math.floor((flagx+6-xscroll)*16*scale), 106*scale+castleflagy*16*scale, 0, scale, scale) 940 end 941 942 --TILES 943 love.graphics.draw(smbspritebatch[split], math.floor(-math.mod(xscroll, 1)*16*scale), 0) 944 love.graphics.draw(portalspritebatch[split], math.floor(-math.mod(xscroll, 1)*16*scale), 0) 945 if customtiles then 946 love.graphics.draw(customspritebatch[split], math.floor(-math.mod(xscroll, 1)*16*scale), 0) 947 end 948 949 local lmap = map 950 951 for y = 1, 15 do 952 for x = 1, xtodraw do 953 local bounceyoffset = 0 954 for i, v in pairs(blockbouncex) do 955 if blockbouncex[i] == math.floor(xscroll)+x and blockbouncey[i] == y then 956 if blockbouncetimer[i] < blockbouncetime/2 then 957 bounceyoffset = blockbouncetimer[i] / (blockbouncetime/2) * blockbounceheight 958 else 959 bounceyoffset = (2 - blockbouncetimer[i] / (blockbouncetime/2)) * blockbounceheight 960 end 961 end 962 end 963 964 local t = lmap[math.floor(xscroll)+x][y] 965 966 local tilenumber = t[1] 967 if tilequads[tilenumber].coinblock and tilequads[tilenumber].invisible == false then --coinblock 968 love.graphics.drawq(coinblockimage, coinblockquads[spriteset][coinframe], math.floor((x-1-math.mod(xscroll, 1))*16*scale), ((y-1-bounceyoffset)*16-8)*scale, 0, scale, scale) 969 elseif tilequads[tilenumber].coin then --coin 970 love.graphics.drawq(coinimage, coinquads[spriteset][coinframe], math.floor((x-1-math.mod(xscroll, 1))*16*scale), ((y-1-bounceyoffset)*16-8)*scale, 0, scale, scale) 971 elseif bounceyoffset ~= 0 then 972 if tilequads[tilenumber].invisible == false or editormode then 973 love.graphics.drawq(tilequads[tilenumber].image, tilequads[tilenumber].quad, math.floor((x-1-math.mod(xscroll, 1))*16*scale), ((y-1-bounceyoffset)*16-8)*scale, 0, scale, scale) 974 end 975 end 976 977 --Gel overlays! 978 if t["gels"] then 979 for i = 1, 4 do 980 local dir = "top" 981 local r = 0 982 if i == 2 then 983 dir = "right" 984 r = math.pi/2 985 elseif i == 3 then 986 dir = "bottom" 987 r = math.pi 988 elseif i == 4 then 989 dir = "left" 990 r = math.pi*1.5 991 end 992 993 if t["gels"][dir] == 1 then 994 love.graphics.draw(gel1ground, math.floor((x-.5-math.mod(xscroll, 1))*16*scale), ((y-1-bounceyoffset)*16)*scale, r, scale, scale, 8, 8) 995 elseif t["gels"][dir] == 2 then 996 love.graphics.draw(gel2ground, math.floor((x-.5-math.mod(xscroll, 1))*16*scale), ((y-1-bounceyoffset)*16)*scale, r, scale, scale, 8, 8) 997 elseif t["gels"][dir] == 3 then 998 love.graphics.draw(gel3ground, math.floor((x-.5-math.mod(xscroll, 1))*16*scale), ((y-1-bounceyoffset)*16)*scale, r, scale, scale, 8, 8) 999 end 1000 end 1001 end 1002 1003 if editormode then 1004 if tilequads[t[1]].invisible and t[1] ~= 1 then 1005 love.graphics.drawq(tilequads[t[1]].image, tilequads[t[1]].quad, math.floor((x-1-math.mod(xscroll, 1))*16*scale), ((y-1)*16-8)*scale, 0, scale, scale) 1006 end 1007 1008 if #t > 1 and t[2] ~= "link" then 1009 tilenumber = t[2] 1010 love.graphics.setColor(255, 255, 255, 150) 1011 love.graphics.drawq(entityquads[tilenumber].image, entityquads[tilenumber].quad, math.floor((x-1-math.mod(xscroll, 1))*16*scale), ((y-1)*16-8)*scale, 0, scale, scale) 1012 love.graphics.setColor(255, 255, 255, 255) 1013 end 1014 end 1015 end 1016 end 1017 1018 ---UI 1019 love.graphics.setColor(255, 255, 255) 1020 love.graphics.translate(0, -yoffset*scale) 1021 if yoffset < 0 then 1022 love.graphics.translate(0, yoffset*scale) 1023 end 1024 1025 properprint("mario", uispace*.5 - 24*scale, 8*scale) 1026 properprint(addzeros(marioscore, 6), uispace*0.5-24*scale, 16*scale) 1027 1028 properprint("*", uispace*1.5-8*scale, 16*scale) 1029 1030 love.graphics.drawq(coinanimationimage, coinanimationquads[spriteset][coinframe], uispace*1.5-16*scale, 16*scale, 0, scale, scale) 1031 properprint(addzeros(mariocoincount, 2), uispace*1.5-0*scale, 16*scale) 1032 1033 properprint("world", uispace*2.5 - 20*scale, 8*scale) 1034 properprint(marioworld .. "-" .. mariolevel, uispace*2.5 - 12*scale, 16*scale) 1035 1036 properprint("time", uispace*3.5 - 16*scale, 8*scale) 1037 if editormode then 1038 if linktool then 1039 properprint("link", uispace*3.5 - 16*scale, 16*scale) 1040 else 1041 properprint("edit", uispace*3.5 - 16*scale, 16*scale) 1042 end 1043 else 1044 properprint(addzeros(math.ceil(mariotime), 3), uispace*3.5-8*scale, 16*scale) 1045 end 1046 1047 if players > 1 then 1048 for i = 1, players do 1049 local x = (width*16)/players/2 + (width*16)/players*(i-1) 1050 if mariolivecount ~= false then 1051 properprint("p" .. i .. " * " .. mariolives[i], (x-string.len("p" .. i .. " * " .. mariolives[i])*4+4)*scale, 25*scale) 1052 love.graphics.setColor(mariocolors[i][1]) 1053 love.graphics.rectangle("fill", (x-string.len("p" .. i .. " * " .. mariolives[i])*4-3)*scale, 25*scale, 7*scale, 7*scale) 1054 love.graphics.setColor(255, 255, 255, 255) 1055 end 1056 end 1057 end 1058 1059 love.graphics.setColor(255, 255, 255) 1060 --vines 1061 for j, w in pairs(objects["vine"]) do 1062 w:draw() 1063 end 1064 1065 love.graphics.setColor(255, 255, 255) 1066 --warpzonetext 1067 if displaywarpzonetext then 1068 properprint("welcome to warp zone!", (mapwidth-14-1/16-xscroll)*16*scale, 88*scale) 1069 for i, v in pairs(warpzonenumbers) do 1070 properprint(v[3], math.floor((v[1]-xscroll-1-9/16)*16*scale), (v[2]-3)*16*scale) 1071 end 1072 end 1073 1074 love.graphics.setColor(255, 255, 255) 1075 --platforms 1076 for j, w in pairs(objects["platform"]) do 1077 w:draw() 1078 end 1079 1080 love.graphics.setColor(255, 255, 255) 1081 --platforms 1082 for j, w in pairs(objects["seesawplatform"]) do 1083 w:draw() 1084 end 1085 1086 love.graphics.setColor(255, 255, 255) 1087 --seesaws 1088 for j, w in pairs(seesaws) do 1089 w:draw() 1090 end 1091 1092 love.graphics.setColor(255, 255, 255) 1093 --springs 1094 for j, w in pairs(objects["spring"]) do 1095 w:draw() 1096 end 1097 1098 love.graphics.setColor(255, 255, 255) 1099 --flag 1100 if flagx then 1101 love.graphics.draw(flagimg, math.floor((flagimgx-1-xscroll)*16*scale), ((flagimgy)*16-8)*scale, 0, scale, scale) 1102 if levelfinishtype == "flag" then 1103 properprint2(flagscore, math.floor((flagimgx+4/16-xscroll)*16*scale), ((14-flagimgy)*16-8)*scale, 0, scale, scale) 1104 end 1105 end 1106 1107 love.graphics.setColor(255, 255, 255) 1108 --axe 1109 if axex then 1110 love.graphics.drawq(axeimg, axequads[coinframe], math.floor((axex-1-xscroll)*16*scale), (axey-1.5)*16*scale, 0, scale, scale) 1111 1112 if marioworld ~= 8 then 1113 love.graphics.draw(toadimg, math.floor((mapwidth-7-xscroll)*16*scale), 177*scale, 0, scale, scale) 1114 else 1115 love.graphics.draw(peachimg, math.floor((mapwidth-7-xscroll)*16*scale), 177*scale, 0, scale, scale) 1116 end 1117 end 1118 1119 love.graphics.setColor(255, 255, 255) 1120 --levelfinish text and toad 1121 if levelfinished and levelfinishtype == "castle" then 1122 if levelfinishedmisc2 == 1 then 1123 if levelfinishedmisc >= 1 then 1124 properprint("thank you mario!", math.floor(((mapwidth-12-xscroll)*16-1)*scale), 72*scale) 1125 end 1126 if levelfinishedmisc == 2 then 1127 properprint("but our princess is in", math.floor(((mapwidth-13.5-xscroll)*16-1)*scale), 104*scale) --say what 1128 properprint("another castle!", math.floor(((mapwidth-13.5-xscroll)*16-1)*scale), 120*scale) --bummer. 1129 end 1130 else 1131 if levelfinishedmisc >= 1 then 1132 properprint("thank you mario!", math.floor(((mapwidth-12-xscroll)*16-1)*scale), 72*scale) 1133 end 1134 if levelfinishedmisc >= 2 then 1135 properprint("your quest is over.", math.floor(((mapwidth-12.5-xscroll)*16-1)*scale), 96*scale) 1136 end 1137 if levelfinishedmisc >= 3 then 1138 properprint("we present you a new quest.", math.floor(((mapwidth-14.5-xscroll)*16-1)*scale), 112*scale) 1139 end 1140 if levelfinishedmisc >= 4 then 1141 properprint("push button b", math.floor(((mapwidth-11-xscroll)*16-1)*scale), 136*scale) 1142 end 1143 if levelfinishedmisc == 5 then 1144 properprint("to play as steve", math.floor(((mapwidth-12-xscroll)*16-1)*scale), 152*scale) 1145 end 1146 end 1147 1148 if marioworld ~= 8 then 1149 love.graphics.draw(toadimg, math.floor((mapwidth-7-xscroll)*16*scale), 177*scale, 0, scale, scale) 1150 else 1151 love.graphics.draw(peachimg, math.floor((mapwidth-7-xscroll)*16*scale), 177*scale, 0, scale, scale) 1152 end 1153 end 1154 1155 love.graphics.setColor(255, 255, 255) 1156 --Fireworks 1157 for j, w in pairs(fireworks) do 1158 w:draw() 1159 end 1160 1161 love.graphics.setColor(255, 255, 255) 1162 --Buttons 1163 for j, w in pairs(objects["button"]) do 1164 w:draw() 1165 end 1166 1167 love.graphics.setColor(255, 255, 255) 1168 --Upfires 1169 for j, w in pairs(objects["upfire"]) do 1170 w:draw() 1171 end 1172 1173 love.graphics.setColor(255, 255, 255) 1174 --Pushbuttons 1175 for j, w in pairs(objects["pushbutton"]) do 1176 w:draw() 1177 end 1178 1179 love.graphics.setColor(255, 255, 255) 1180 --hardlight bridges 1181 for j, w in pairs(objects["lightbridgebody"]) do 1182 w:draw() 1183 end 1184 1185 love.graphics.setColor(255, 255, 255) 1186 --laser 1187 for j, w in pairs(objects["laser"]) do 1188 w:draw() 1189 end 1190 1191 love.graphics.setColor(255, 255, 255) 1192 --laserdetector 1193 for j, w in pairs(objects["laserdetector"]) do 1194 w:draw() 1195 end 1196 1197 love.graphics.setColor(255, 255, 255) 1198 --lightbridge 1199 1200 for j, w in pairs(objects["lightbridge"]) do 1201 w:draw() 1202 end 1203 1204 love.graphics.setColor(255, 255, 255) 1205 --Groundlights 1206 for j, w in pairs(objects["groundlight"]) do 1207 w:draw() 1208 end 1209 1210 love.graphics.setColor(255, 255, 255) 1211 --Faithplates 1212 for j, w in pairs(objects["faithplate"]) do 1213 w:draw() 1214 end 1215 1216 love.graphics.setColor(255, 255, 255) 1217 --Bubbles 1218 for j, w in pairs(bubbles) do 1219 w:draw() 1220 end 1221 1222 love.graphics.setColor(255, 255, 255) 1223 --miniblocks 1224 for i, v in pairs(miniblocks) do 1225 v:draw() 1226 end 1227 1228 --OBJECTS 1229 for j, w in pairs(objects) do 1230 if j ~= "tile" then 1231 for i, v in pairs(w) do 1232 if v.drawable then 1233 love.graphics.setColor(255, 255, 255) 1234 local dirscale 1235 1236 if j == "player" then 1237 if v.pointingangle > 0 then 1238 dirscale = -scale 1239 else 1240 dirscale = scale 1241 end 1242 if bigmario then 1243 dirscale = dirscale * scalefactor 1244 end 1245 else 1246 if v.animationdirection == "left" then 1247 dirscale = -scale 1248 else 1249 dirscale = scale 1250 end 1251 end 1252 1253 local horscale = scale 1254 if v.shot then 1255 horscale = -scale 1256 end 1257 1258 if j == "player" and bigmario then 1259 horscale = horscale * scalefactor 1260 end 1261 1262 local ply, portaly = insideportal(v.x, v.y, v.width, v.height) 1263 local entryX, entryY, entryfacing, exitX, exitY, exitfacing 1264 1265 --SCISSOR FOR ENTRY 1266 if v.static then 1267 if v.customscissor then 1268 love.graphics.setScissor(math.floor((v.customscissor[1]-xscroll)*16*scale), math.floor((v.customscissor[2]-.5)*16*scale), v.customscissor[3]*16*scale, v.customscissor[4]*16*scale) 1269 end 1270 end 1271 1272 if v.static == false and v.portalable ~= false then 1273 if v.customscissor then 1274 love.graphics.setScissor(math.floor((v.customscissor[1]-xscroll)*16*scale), math.floor((v.customscissor[2]-.5)*16*scale), v.customscissor[3]*16*scale, v.customscissor[4]*16*scale) 1275 elseif ply ~= false and (v.active or v.portaloverride) then 1276 if portaly == 1 then 1277 entryX, entryY, entryfacing = objects["player"][ply].portal1X, objects["player"][ply].portal1Y, objects["player"][ply].portal1facing 1278 exitX, exitY, exitfacing = objects["player"][ply].portal2X, objects["player"][ply].portal2Y, objects["player"][ply].portal2facing 1279 else 1280 entryX, entryY, entryfacing = objects["player"][ply].portal2X, objects["player"][ply].portal2Y, objects["player"][ply].portal2facing 1281 exitX, exitY, exitfacing = objects["player"][ply].portal1X, objects["player"][ply].portal1Y, objects["player"][ply].portal1facing 1282 end 1283 1284 if entryfacing == "right" then 1285 love.graphics.setScissor(math.floor((entryX-xscroll)*16*scale), math.floor(((entryY-3.5)*16)*scale), 64*scale, 96*scale) 1286 elseif entryfacing == "left" then 1287 love.graphics.setScissor(math.floor((entryX-xscroll-5)*16*scale), math.floor(((entryY-4.5)*16)*scale), 64*scale, 96*scale) 1288 elseif entryfacing == "up" then 1289 love.graphics.setScissor(math.floor((entryX-xscroll-3)*16*scale), math.floor(((entryY-5.5)*16)*scale), 96*scale, 64*scale) 1290 elseif entryfacing == "down" then 1291 love.graphics.setScissor(math.floor((entryX-xscroll-4)*16*scale), math.floor(((entryY-0.5)*16)*scale), 96*scale, 64*scale) 1292 end 1293 end 1294 end 1295 1296 if type(v.graphic) == "table" then 1297 for k = 1, #v.graphic do 1298 if v.colors[k] then 1299 love.graphics.setColor(v.colors[k]) 1300 else 1301 love.graphics.setColor(255, 255, 255) 1302 end 1303 love.graphics.drawq(v.graphic[k], v.quad, math.floor(((v.x-xscroll)*16+v.offsetX)*scale), math.floor((v.y*16-v.offsetY)*scale), v.rotation, dirscale, horscale, v.quadcenterX, v.quadcenterY) 1304 end 1305 1306 if v.drawhat and hatoffsets[v.animationstate] then 1307 local offsets = {} 1308 if v.graphic == v.biggraphic or v.animationstate == "grow" then 1309 if v.animationstate == "grow" then 1310 offsets = hatoffsets["grow"] 1311 elseif v.fireanimationtimer < fireanimationtime then 1312 offsets = bighatoffsets["fire"] 1313 elseif underwater and (v.animationstate == "jumping" or v.animationstate == "falling") then 1314 offsets = bighatoffsets["swimming"][v.swimframe] 1315 elseif v.ducking then 1316 offsets = bighatoffsets["ducking"] 1317 elseif v.animationstate == "running" or v.animationstate == "falling" then 1318 offsets = bighatoffsets["running"][v.runframe] 1319 elseif v.animationstate == "climbing" then 1320 offsets = bighatoffsets["climbing"][v.climbframe] 1321 else 1322 offsets = bighatoffsets[v.animationstate] 1323 end 1324 else 1325 if underwater and (v.animationstate == "jumping" or v.animationstate == "falling") then 1326 offsets = hatoffsets["swimming"][v.swimframe] 1327 elseif v.animationstate == "running" or v.animationstate == "falling" then 1328 offsets = hatoffsets["running"][v.runframe] 1329 elseif v.animationstate == "climbing" then 1330 offsets = hatoffsets["climbing"][v.climbframe] 1331 else 1332 offsets = hatoffsets[v.animationstate] 1333 end 1334 end 1335 1336 if #v.hats > 0 then 1337 local yadd = 0 1338 for i = 1, #v.hats do 1339 if v.hats[i] == 1 then 1340 love.graphics.setColor(v.colors[1]) 1341 else 1342 love.graphics.setColor(255, 255, 255) 1343 end 1344 if v.graphic == v.biggraphic or v.animationstate == "grow" then 1345 love.graphics.draw(bighat[v.hats[i]].graphic, math.floor(((v.x-xscroll)*16+v.offsetX)*scale), math.floor(((v.y)*16-v.offsetY)*scale), v.rotation, dirscale, horscale, v.quadcenterX - bighat[v.hats[i]].x + offsets[1], v.quadcenterY - bighat[v.hats[i]].y + offsets[2] + yadd) 1346 yadd = yadd + bighat[v.hats[i]].height 1347 else 1348 love.graphics.draw(hat[v.hats[i]].graphic, math.floor(((v.x-xscroll)*16+v.offsetX)*scale), math.floor(((v.y)*16-v.offsetY)*scale), v.rotation, dirscale, horscale, v.quadcenterX - hat[v.hats[i]].x + offsets[1], v.quadcenterY - hat[v.hats[i]].y + offsets[2] + yadd) 1349 yadd = yadd + hat[v.hats[i]].height 1350 end 1351 end 1352 end 1353 end 1354 1355 if v.graphic[0] then 1356 love.graphics.setColor(255, 255, 255) 1357 love.graphics.drawq(v.graphic[0], v.quad, math.floor(((v.x-xscroll)*16+v.offsetX)*scale), math.floor((v.y*16-v.offsetY)*scale), v.rotation, dirscale, horscale, v.quadcenterX, v.quadcenterY) 1358 end 1359 else 1360 if v.graphic and v.quad then 1361 love.graphics.drawq(v.graphic, v.quad, math.floor(((v.x-xscroll)*16+v.offsetX)*scale), math.floor((v.y*16-v.offsetY)*scale), v.rotation, dirscale, horscale, v.quadcenterX, v.quadcenterY) 1362 end 1363 end 1364 1365 --portal duplication 1366 if v.static == false and (v.active or v.portaloverride) and v.portalable ~= false then 1367 if v.customscissor then 1368 1369 elseif ply ~= false then 1370 love.graphics.setScissor(unpack(currentscissor)) 1371 local px, py, pw, ph, pr, pad = v.x, v.y, v.width, v.height, v.rotation, v.animationdirection 1372 px, py, d, d, pr, pad = portalcoords(px, py, 0, 0, pw, ph, pr, pad, entryX, entryY, entryfacing, exitX, exitY, exitfacing) 1373 1374 if pad ~= v.animationdirection then 1375 dirscale = -dirscale 1376 end 1377 1378 horscale = scale 1379 if v.shot then 1380 horscale = -scale 1381 end 1382 1383 if exitfacing == "right" then 1384 love.graphics.setScissor(math.floor((exitX-xscroll)*16*scale), math.floor(((exitY-3.5)*16)*scale), 64*scale, 96*scale) 1385 elseif exitfacing == "left" then 1386 love.graphics.setScissor(math.floor((exitX-xscroll-5)*16*scale), math.floor(((exitY-4.5)*16)*scale), 64*scale, 96*scale) 1387 elseif exitfacing == "up" then 1388 love.graphics.setScissor(math.floor((exitX-xscroll-3)*16*scale), math.floor(((exitY-5.5)*16)*scale), 96*scale, 64*scale) 1389 elseif exitfacing == "down" then 1390 love.graphics.setScissor(math.floor((exitX-xscroll-4)*16*scale), math.floor(((exitY-0.5)*16)*scale), 96*scale, 64*scale) 1391 end 1392 1393 if type(v.graphic) == "table" then 1394 for k = 1, #v.graphic do 1395 if v.colors[k] then 1396 love.graphics.setColor(v.colors[k]) 1397 else 1398 love.graphics.setColor(255, 255, 255) 1399 end 1400 love.graphics.drawq(v.graphic[k], v.quad, math.ceil(((px-xscroll)*16+v.offsetX)*scale), math.ceil((py*16-v.offsetY)*scale), pr, dirscale, horscale, v.quadcenterX, v.quadcenterY) 1401 end 1402 1403 if v.drawhat and hatoffsets[v.animationstate] then 1404 local offsets = {} 1405 if v.graphic == v.biggraphic or v.animationstate == "grow" then 1406 if v.animationstate == "grow" then 1407 offsets = hatoffsets["grow"] 1408 elseif v.fireanimationtimer < fireanimationtime then 1409 offsets = bighatoffsets["fire"] 1410 elseif underwater and (v.animationstate == "jumping" or v.animationstate == "falling") then 1411 offsets = bighatoffsets["swimming"][v.swimframe] 1412 elseif v.ducking then 1413 offsets = bighatoffsets["ducking"] 1414 elseif v.animationstate == "running" or v.animationstate == "falling" then 1415 offsets = bighatoffsets["running"][v.runframe] 1416 elseif v.animationstate == "climbing" then 1417 offsets = bighatoffsets["climbing"][v.climbframe] 1418 else 1419 offsets = bighatoffsets[v.animationstate] 1420 end 1421 else 1422 if underwater and (v.animationstate == "jumping" or v.animationstate == "falling") then 1423 offsets = hatoffsets["swimming"][v.swimframe] 1424 elseif v.animationstate == "running" or v.animationstate == "falling" then 1425 offsets = hatoffsets["running"][v.runframe] 1426 elseif v.animationstate == "climbing" then 1427 offsets = hatoffsets["climbing"][v.climbframe] 1428 else 1429 offsets = hatoffsets[v.animationstate] 1430 end 1431 end 1432 1433 if #v.hats > 0 then 1434 local yadd = 0 1435 for i = 1, #v.hats do 1436 if v.hats[i] == 1 then 1437 love.graphics.setColor(v.colors[1]) 1438 else 1439 love.graphics.setColor(255, 255, 255) 1440 end 1441 if v.graphic == v.biggraphic or v.animationstate == "grow" then 1442 love.graphics.draw(bighat[v.hats[i]].graphic, math.floor(((px-xscroll)*16+v.offsetX)*scale), math.floor(((py)*16-v.offsetY)*scale), pr, dirscale, horscale, v.quadcenterX - bighat[v.hats[i]].x + offsets[1], v.quadcenterY - bighat[v.hats[i]].y + offsets[2] + yadd) 1443 yadd = yadd + bighat[v.hats[i]].height 1444 else 1445 love.graphics.draw(hat[v.hats[i]].graphic, math.floor(((px-xscroll)*16+v.offsetX)*scale), math.floor(((py)*16-v.offsetY)*scale), pr, dirscale, horscale, v.quadcenterX - hat[v.hats[i]].x + offsets[1], v.quadcenterY - hat[v.hats[i]].y + offsets[2] + yadd) 1446 yadd = yadd + hat[v.hats[i]].height 1447 end 1448 end 1449 end 1450 end 1451 1452 if v.graphic[0] then 1453 love.graphics.setColor(255, 255, 255) 1454 love.graphics.drawq(v.graphic[0], v.quad, math.floor(((px-xscroll)*16+v.offsetX)*scale), math.floor((py*16-v.offsetY)*scale), pr, dirscale, horscale, v.quadcenterX, v.quadcenterY) 1455 end 1456 else 1457 love.graphics.drawq(v.graphic, v.quad, math.ceil(((px-xscroll)*16+v.offsetX)*scale), math.ceil((py*16-v.offsetY)*scale), pr, dirscale, horscale, v.quadcenterX, v.quadcenterY) 1458 end 1459 end 1460 end 1461 love.graphics.setScissor(unpack(currentscissor)) 1462 end 1463 end 1464 end 1465 end 1466 1467 love.graphics.setColor(255, 255, 255) 1468 1469 --bowser 1470 for j, w in pairs(objects["bowser"]) do 1471 w:draw() 1472 end 1473 1474 --lakito 1475 for j, w in pairs(objects["lakito"]) do 1476 w:draw() 1477 end 1478 1479 --Geldispensers 1480 for j, w in pairs(objects["geldispenser"]) do 1481 w:draw() 1482 end 1483 1484 --Cubedispensers 1485 for j, w in pairs(objects["cubedispenser"]) do 1486 w:draw() 1487 end 1488 1489 --Emancipationgrills 1490 for j, w in pairs(emancipationgrills) do 1491 w:draw() 1492 end 1493 1494 --Doors 1495 for j, w in pairs(objects["door"]) do 1496 w:draw() 1497 end 1498 1499 --Wallindicators 1500 for j, w in pairs(objects["wallindicator"]) do 1501 w:draw() 1502 end 1503 1504 --Walltimers 1505 for j, w in pairs(objects["walltimer"]) do 1506 w:draw() 1507 end 1508 1509 --Notgates 1510 for j, w in pairs(objects["notgate"]) do 1511 w:draw() 1512 end 1513 1514 --particles 1515 for j, w in pairs(portalparticles) do 1516 w:draw() 1517 end 1518 1519 --portals 1520 for i = 1, players do 1521 if objects["player"][i].portal1X ~= false then 1522 local rotation = 0 1523 local offsetx, offsety = 8, -3 1524 if objects["player"][i].portal1facing == "right" then 1525 rotation = math.pi/2 1526 offsetx, offsety = 11, 0 1527 elseif objects["player"][i].portal1facing == "down" then 1528 rotation = math.pi 1529 offsety = 3 1530 elseif objects["player"][i].portal1facing == "left" then 1531 rotation = math.pi*1.5 1532 offsetx, offsety = 5, 0 1533 end 1534 1535 local portalframe = portalanimation 1536 local glowalpha = 100 1537 if objects["player"][i].portal2X == false then 1538 1539 else 1540 love.graphics.setColor(255, 255, 255, 80 - math.abs(portalframe-3)*10) 1541 love.graphics.draw(portalglow, math.floor(((objects["player"][i].portal1X-1-xscroll)*16+offsetx)*scale), math.floor(((objects["player"][i].portal1Y-1)*16+offsety)*scale), rotation, scale, scale, 8, 20) 1542 love.graphics.setColor(255, 255, 255, 255) 1543 end 1544 1545 love.graphics.setColor(unpack(objects["player"][i].portal1color)) 1546 love.graphics.drawq(portalimage, portal1quad[portalframe], math.floor(((objects["player"][i].portal1X-1-xscroll)*16+offsetx)*scale), math.floor(((objects["player"][i].portal1Y-1)*16+offsety)*scale), rotation, scale, scale, 8, 8) 1547 end 1548 1549 if objects["player"][i].portal2X ~= false then 1550 rotation = 0 1551 offsetx, offsety = 8, -3 1552 if objects["player"][i].portal2facing == "right" then 1553 rotation = math.pi/2 1554 offsetx, offsety = 11, 0 1555 elseif objects["player"][i].portal2facing == "down" then 1556 rotation = math.pi 1557 offsety = 3 1558 elseif objects["player"][i].portal2facing == "left" then 1559 rotation = math.pi*1.5 1560 offsetx, offsety = 5, 0 1561 end 1562 1563 local portalframe = portalanimation 1564 if objects["player"][i].portal1X == false then 1565 1566 else 1567 love.graphics.setColor(255, 255, 255, 80 - math.abs(portalframe-3)*10) 1568 love.graphics.draw(portalglow, math.floor(((objects["player"][i].portal2X-1-xscroll)*16+offsetx)*scale), math.floor(((objects["player"][i].portal2Y-1)*16+offsety)*scale), rotation, scale, scale, 8, 20) 1569 love.graphics.setColor(255, 255, 255, 255) 1570 end 1571 1572 love.graphics.setColor(unpack(objects["player"][i].portal2color)) 1573 love.graphics.drawq(portalimage, portal2quad[portalframe], math.floor(((objects["player"][i].portal2X-1-xscroll)*16+offsetx)*scale), math.floor(((objects["player"][i].portal2Y-1)*16+offsety)*scale), rotation, scale, scale, 8, 8) 1574 end 1575 end 1576 1577 love.graphics.setColor(255, 255, 255) 1578 1579 --COINBLOCKANIMATION 1580 for i, v in pairs(coinblockanimations) do 1581 love.graphics.drawq(coinblockanimationimage, coinblockanimationquads[coinblockanimations[i].frame], math.floor((coinblockanimations[i].x - xscroll)*16*scale), math.floor((coinblockanimations[i].y*16-8)*scale), 0, scale, scale, 4, 54) 1582 end 1583 1584 --SCROLLING SCORE 1585 for i, v in pairs(scrollingscores) do 1586 if type(scrollingscores[i].i) == "number" then 1587 properprint2(scrollingscores[i].i, math.floor((scrollingscores[i].x-0.4)*16*scale), math.floor((scrollingscores[i].y-1.5-scrollingscoreheight*(scrollingscores[i].timer/scrollingscoretime))*16*scale)) 1588 elseif scrollingscores[i].i == "1up" then 1589 love.graphics.draw(oneuptextimage, math.floor((scrollingscores[i].x)*16*scale), math.floor((scrollingscores[i].y-1.5-scrollingscoreheight*(scrollingscores[i].timer/scrollingscoretime))*16*scale), 0, scale, scale) 1590 end 1591 end 1592 1593 --BLOCK DEBRIS 1594 for i, v in pairs(blockdebristable) do 1595 v:draw() 1596 end 1597 1598 local minex, miney, minecox, minecoy 1599 1600 --PORTAL UI STUFF 1601 if levelfinished == false then 1602 for pl = 1, players do 1603 if objects["player"][pl].controlsenabled and objects["player"][pl].t == "portal" and objects["player"][pl].vine == false then 1604 local sourcex, sourcey = objects["player"][pl].x+6/16, objects["player"][pl].y+6/16 1605 local cox, coy, side, tend, x, y = traceline(sourcex, sourcey, objects["player"][pl].pointingangle) 1606 1607 local portalpossible = true 1608 if cox == false or getportalposition(1, cox, coy, side, tend) == false then 1609 portalpossible = false 1610 end 1611 1612 love.graphics.setColor(255, 255, 255, 255) 1613 1614 local dist = math.sqrt(((x-xscroll)*16*scale - (sourcex-xscroll)*16*scale)^2 + ((y-.5)*16*scale - (sourcey-.5)*16*scale)^2)/16/scale 1615 1616 for i = 1, dist/portaldotsdistance+1 do 1617 if((i-1+objects["player"][pl].portaldotstimer/portaldotstime)/(dist/portaldotsdistance)) < 1 then 1618 local xplus = ((x-xscroll)*16*scale - (sourcex-xscroll)*16*scale)*((i-1+objects["player"][pl].portaldotstimer/portaldotstime)/(dist/portaldotsdistance)) 1619 local yplus = ((y-.5)*16*scale - (sourcey-.5)*16*scale)*((i-1+objects["player"][pl].portaldotstimer/portaldotstime)/(dist/portaldotsdistance)) 1620 1621 local dotx = (sourcex-xscroll)*16*scale + xplus 1622 local doty = (sourcey-.5)*16*scale + yplus 1623 1624 local radius = math.sqrt(xplus^2 + yplus^2)/scale 1625 1626 local alpha = 255 1627 if radius < portaldotsouter then 1628 alpha = (radius-portaldotsinner) * (255/(portaldotsouter-portaldotsinner)) 1629 if alpha < 0 then 1630 alpha = 0 1631 end 1632 end 1633 1634 1635 if portalpossible == false then 1636 love.graphics.setColor(255, 0, 0, alpha) 1637 else 1638 love.graphics.setColor(0, 255, 0, alpha) 1639 end 1640 1641 love.graphics.draw(portaldotimg, math.floor(dotx-0.25*scale), math.floor(doty-0.25*scale), 0, scale, scale) 1642 end 1643 end 1644 1645 love.graphics.setColor(255, 255, 255, 255) 1646 1647 if cox ~= false then 1648 if portalpossible == false then 1649 love.graphics.setColor(255, 0, 0) 1650 else 1651 love.graphics.setColor(0, 255, 0) 1652 end 1653 1654 local rotation = 0 1655 if side == "right" then 1656 rotation = math.pi/2 1657 elseif side == "down" then 1658 rotation = math.pi 1659 elseif side == "left" then 1660 rotation = math.pi/2*3 1661 end 1662 love.graphics.draw(portalcrosshairimg, math.floor((x-xscroll)*16*scale), math.floor((y-.5)*16*scale), rotation, scale, scale, 4, 8) 1663 end 1664 end 1665 end 1666 end 1667 1668 --Portal projectile 1669 for i, v in pairs(portalprojectiles) do 1670 v:draw() 1671 end 1672 1673 love.graphics.setColor(255, 255, 255) 1674 1675 --nothing to see here 1676 for i, v in pairs(rainbooms) do 1677 v:draw() 1678 end 1679 1680 --Minecraft 1681 --black border 1682 if objects["player"][mouseowner] and playertype == "minecraft" and not levelfinished then 1683 local v = objects["player"][mouseowner] 1684 local sourcex, sourcey = v.x+6/16, v.y+6/16 1685 local cox, coy, side, tend, x, y = traceline(sourcex, sourcey, v.pointingangle) 1686 1687 if cox then 1688 local dist = math.sqrt((v.x+v.width/2 - x)^2 + (v.y+v.height/2 - y)^2) 1689 if dist <= minecraftrange then 1690 love.graphics.setColor(0, 0, 0, 170) 1691 love.graphics.rectangle("line", math.floor((cox-1-xscroll)*16*scale)-.5, (coy-1-.5)*16*scale-.5, 16*scale, 16*scale) 1692 1693 if breakingblockX and (cox ~= breakingblockX or coy ~= breakingblockY) then 1694 breakingblockX = cox 1695 breakingblockY = coy 1696 breakingblockprogress = 0 1697 elseif not breakingblockX and love.mouse.isDown("l") then 1698 breakingblockX = cox 1699 breakingblockY = coy 1700 breakingblockprogress = 0 1701 end 1702 elseif love.mouse.isDown("l") then 1703 breakingblockX = cox 1704 breakingblockY = coy 1705 breakingblockprogress = 0 1706 end 1707 else 1708 breakingblockX = nil 1709 end 1710 --break animation 1711 if breakingblockX then 1712 love.graphics.setColor(255, 255, 255, 255) 1713 local frame = math.ceil((breakingblockprogress/minecraftbreaktime)*10) 1714 if frame ~= 0 then 1715 love.graphics.drawq(minecraftbreakimg, minecraftbreakquad[frame], (breakingblockX-1-xscroll)*16*scale, (breakingblockY-1.5)*16*scale, 0, scale, scale) 1716 end 1717 end 1718 love.graphics.setColor(255, 255, 255, 255) 1719 1720 --gui 1721 love.graphics.draw(minecraftgui, (width*8-91)*scale, 202*scale, 0, scale, scale) 1722 1723 love.graphics.setColor(255, 255, 255, 200) 1724 for i = 1, 9 do 1725 local t = inventory[i].t 1726 1727 if t ~= nil then 1728 local img = customtilesimg 1729 if t <= smbtilecount then 1730 img = smbtilesimg 1731 elseif t <= smbtilecount+portaltilecount then 1732 img = portaltilesimg 1733 end 1734 love.graphics.drawq(img, tilequads[t].quad, (width*8-88+(i-1)*20)*scale, 205*scale, 0, scale, scale) 1735 end 1736 end 1737 1738 love.graphics.setColor(255, 255, 255, 255) 1739 love.graphics.draw(minecraftselected, (width*8-92+(mccurrentblock-1)*20)*scale, 201*scale, 0, scale, scale) 1740 1741 for i = 1, 9 do 1742 if inventory[i].t ~= nil then 1743 local count = inventory[i].count 1744 properprint(count, (width*8-72+(i-1)*20-string.len(count)*8)*scale, 205*scale) 1745 end 1746 end 1747 end 1748 1749 love.graphics.translate(-(split-1)*width*16*scale/#splitscreen, 0) 1750 end 1751 love.graphics.setScissor() 1752 1753 if earthquake > 0 then 1754 love.graphics.translate(-round(tremorx), -round(tremory)) 1755 end 1756 1757 for i = 2, #splitscreen do 1758 love.graphics.line((i-1)*width*16*scale/#splitscreen, 0, (i-1)*width*16*scale/#splitscreen, 15*16*scale) 1759 end 1760 1761 if editormode then 1762 editor_draw() 1763 end 1764 1765 --speed gradient 1766 if speed < 1 then 1767 love.graphics.setColor(255, 255, 255, 255-255*speed) 1768 love.graphics.draw(gradientimg, 0, 0, 0, scale, scale) 1769 end 1770 1771 if yoffset < 0 then 1772 love.graphics.translate(0, -yoffset*scale) 1773 end 1774 love.graphics.translate(0, yoffset*scale) 1775 1776 if testlevel then 1777 love.graphics.setColor(255, 0, 0) 1778 properprint("testing level - press esc to return to editor", 0, 0) 1779 end 1780 1781 --pause menu 1782 if pausemenuopen then 1783 love.graphics.setColor(0, 0, 0, 100) 1784 love.graphics.rectangle("fill", 0, 0, width*16*scale, 224*scale) 1785 1786 love.graphics.setColor(0, 0, 0) 1787 love.graphics.rectangle("fill", (width*8*scale)-50*scale, (112*scale)-75*scale, 100*scale, 150*scale) 1788 love.graphics.setColor(255, 255, 255) 1789 drawrectangle(width*8-49, 112-74, 98, 148) 1790 1791 for i = 1, #pausemenuoptions do 1792 love.graphics.setColor(100, 100, 100, 255) 1793 if pausemenuselected == i and not menuprompt and not desktopprompt then 1794 love.graphics.setColor(255, 255, 255, 255) 1795 properprint(">", (width*8*scale)-45*scale, (112*scale)-60*scale+(i-1)*25*scale) 1796 end 1797 properprint(pausemenuoptions[i], (width*8*scale)-35*scale, (112*scale)-60*scale+(i-1)*25*scale) 1798 properprint(pausemenuoptions2[i], (width*8*scale)-35*scale, (112*scale)-50*scale+(i-1)*25*scale) 1799 1800 if pausemenuoptions[i] == "volume" then 1801 drawrectangle((width*8)-34, 68+(i-1)*25, 74, 1) 1802 drawrectangle((width*8)-34, 65+(i-1)*25, 1, 7) 1803 drawrectangle((width*8)+40, 65+(i-1)*25, 1, 7) 1804 love.graphics.draw(volumesliderimg, math.floor(((width*8)-35+74*volume)*scale), (112*scale)-47*scale+(i-1)*25*scale, 0, scale, scale) 1805 end 1806 end 1807 1808 if menuprompt then 1809 love.graphics.setColor(0, 0, 0, 255) 1810 love.graphics.rectangle("fill", (width*8*scale)-100*scale, (112*scale)-25*scale, 200*scale, 50*scale) 1811 love.graphics.setColor(255, 255, 255, 255) 1812 drawrectangle((width*8)-99, 112-24, 198, 48) 1813 properprint("quit to menu?", (width*8*scale)-string.len("quit to menu?")*4*scale, (112*scale)-10*scale) 1814 if pausemenuselected2 == 1 then 1815 properprint(">", (width*8*scale)-51*scale, (112*scale)+4*scale) 1816 love.graphics.setColor(255, 255, 255, 255) 1817 properprint("yes", (width*8*scale)-44*scale, (112*scale)+4*scale) 1818 love.graphics.setColor(100, 100, 100, 255) 1819 properprint("no", (width*8*scale)+28*scale, (112*scale)+4*scale) 1820 else 1821 properprint(">", (width*8*scale)+20*scale, (112*scale)+4*scale) 1822 love.graphics.setColor(100, 100, 100, 255) 1823 properprint("yes", (width*8*scale)-44*scale, (112*scale)+4*scale) 1824 love.graphics.setColor(255, 255, 255, 255) 1825 properprint("no", (width*8*scale)+28*scale, (112*scale)+4*scale) 1826 end 1827 end 1828 1829 if desktopprompt then 1830 love.graphics.setColor(0, 0, 0, 255) 1831 love.graphics.rectangle("fill", (width*8*scale)-100*scale, (112*scale)-25*scale, 200*scale, 50*scale) 1832 love.graphics.setColor(255, 255, 255, 255) 1833 drawrectangle((width*8)-99, 112-24, 198, 48) 1834 properprint("quit to desktop?", (width*8*scale)-string.len("quit to desktop?")*4*scale, (112*scale)-10*scale) 1835 if pausemenuselected2 == 1 then 1836 properprint(">", (width*8*scale)-51*scale, (112*scale)+4*scale) 1837 love.graphics.setColor(255, 255, 255, 255) 1838 properprint("yes", (width*8*scale)-44*scale, (112*scale)+4*scale) 1839 love.graphics.setColor(100, 100, 100, 255) 1840 properprint("no", (width*8*scale)+28*scale, (112*scale)+4*scale) 1841 else 1842 properprint(">", (width*8*scale)+20*scale, (112*scale)+4*scale) 1843 love.graphics.setColor(100, 100, 100, 255) 1844 properprint("yes", (width*8*scale)-44*scale, (112*scale)+4*scale) 1845 love.graphics.setColor(255, 255, 255, 255) 1846 properprint("no", (width*8*scale)+28*scale, (112*scale)+4*scale) 1847 end 1848 end 1849 1850 if suspendprompt then 1851 love.graphics.setColor(0, 0, 0, 255) 1852 love.graphics.rectangle("fill", (width*8*scale)-100*scale, (112*scale)-25*scale, 200*scale, 50*scale) 1853 love.graphics.setColor(255, 255, 255, 255) 1854 drawrectangle((width*8)-99, 112-24, 198, 48) 1855 properprint("suspend game? this can", (width*8*scale)-string.len("suspend game? this can")*4*scale, (112*scale)-20*scale) 1856 properprint("only be loaded once!", (width*8*scale)-string.len("only be loaded once!")*4*scale, (112*scale)-10*scale) 1857 if pausemenuselected2 == 1 then 1858 properprint(">", (width*8*scale)-51*scale, (112*scale)+4*scale) 1859 love.graphics.setColor(255, 255, 255, 255) 1860 properprint("yes", (width*8*scale)-44*scale, (112*scale)+4*scale) 1861 love.graphics.setColor(100, 100, 100, 255) 1862 properprint("no", (width*8*scale)+28*scale, (112*scale)+4*scale) 1863 else 1864 properprint(">", (width*8*scale)+20*scale, (112*scale)+4*scale) 1865 love.graphics.setColor(100, 100, 100, 255) 1866 properprint("yes", (width*8*scale)-44*scale, (112*scale)+4*scale) 1867 love.graphics.setColor(255, 255, 255, 255) 1868 properprint("no", (width*8*scale)+28*scale, (112*scale)+4*scale) 1869 end 1870 end 1871 end 1872end 1873 1874function updatesplitscreen() 1875 if players == 2 and netplay == false then 1876 if #splitscreen == 1 then 1877 if math.abs(objects["player"][1].x - objects["player"][2].x) > width - scrollingstart - scrollingleftstart then 1878 if objects["player"][1].x < objects["player"][2].x then 1879 splitscreen = {{1}, {2}} 1880 else 1881 splitscreen = {{2}, {1}} 1882 end 1883 1884 splitxscroll = {xscroll, xscroll+width/2} 1885 generatespritebatch() 1886 end 1887 else 1888 if splitxscroll[2] <= splitxscroll[1]+width/2 then 1889 splitscreen = {{1, 2}} 1890 1891 xscroll = splitxscroll[1] 1892 generatespritebatch() 1893 end 1894 end 1895 end 1896end 1897 1898function startlevel(level) 1899 skipupdate = true 1900 love.audio.stop() 1901 1902 local sublevel = false 1903 if type(level) == "number" then 1904 sublevel = true 1905 end 1906 1907 if sublevel then 1908 prevsublevel = mariosublevel 1909 mariosublevel = level 1910 if level ~= 0 then 1911 level = marioworld .. "-" .. mariolevel .. "_" .. level 1912 else 1913 level = marioworld .. "-" .. mariolevel 1914 end 1915 else 1916 mariosublevel = 0 1917 prevsublevel = false 1918 mariotime = 400 1919 end 1920 1921 --MISC VARS 1922 everyonedead = false 1923 levelfinished = false 1924 coinanimation = 1 1925 flagx = false 1926 levelfinishtype = nil 1927 firestartx = false 1928 firestarted = false 1929 firedelay = math.random(4) 1930 flyingfishdelay = 1 1931 flyingfishstarted = false 1932 flyingfishstartx = false 1933 flyingfishendx = false 1934 bulletbilldelay = 1 1935 bulletbillstarted = false 1936 bulletbillstartx = false 1937 bulletbillendx = false 1938 firetimer = firedelay 1939 flyingfishtimer = flyingfishdelay 1940 bulletbilltimer = bulletbilldelay 1941 axex = false 1942 axey = false 1943 lakitoendx = false 1944 lakitoend = false 1945 noupdate = false 1946 xscroll = 0 1947 splitscreen = {{}} 1948 checkpoints = {} 1949 checkpointpoints = {} 1950 repeatX = 0 1951 lastrepeat = 0 1952 displaywarpzonetext = false 1953 for i = 1, players do 1954 table.insert(splitscreen[1], i) 1955 end 1956 checkpointi = 0 1957 mazestarts = {} 1958 mazeends = {} 1959 mazesolved = {} 1960 mazesolved[0] = true 1961 mazeinprogress = false 1962 earthquake = 0 1963 sunrot = 0 1964 gelcannontimer = 0 1965 pausemenuselected = 1 1966 coinblocktimers = {} 1967 1968 portaldelay = {} 1969 for i = 1, players do 1970 portaldelay[i] = 0 1971 end 1972 1973 --Minecraft 1974 breakingblockX = false 1975 breakingblockY = false 1976 breakingblockprogress = 0 1977 1978 --class tables 1979 coinblockanimations = {} 1980 scrollingscores = {} 1981 portalparticles = {} 1982 portalprojectiles = {} 1983 emancipationgrills = {} 1984 platformspawners = {} 1985 rocketlaunchers = {} 1986 userects = {} 1987 blockdebristable = {} 1988 fireworks = {} 1989 seesaws = {} 1990 bubbles = {} 1991 rainbooms = {} 1992 miniblocks = {} 1993 inventory = {} 1994 for i = 1, 9 do 1995 inventory[i] = {} 1996 end 1997 mccurrentblock = 1 1998 1999 blockbouncetimer = {} 2000 blockbouncex = {} 2001 blockbouncey = {} 2002 blockbouncecontent = {} 2003 blockbouncecontent2 = {} 2004 warpzonenumbers = {} 2005 2006 objects = {} 2007 objects["player"] = {} 2008 objects["portalwall"] = {} 2009 objects["tile"] = {} 2010 objects["goomba"] = {} 2011 objects["koopa"] = {} 2012 objects["mushroom"] = {} 2013 objects["flower"] = {} 2014 objects["oneup"] = {} 2015 objects["star"] = {} 2016 objects["vine"] = {} 2017 objects["box"] = {} 2018 objects["door"] = {} 2019 objects["button"] = {} 2020 objects["groundlight"] = {} 2021 objects["wallindicator"] = {} 2022 objects["walltimer"] = {} 2023 objects["notgate"] = {} 2024 objects["lightbridge"] = {} 2025 objects["lightbridgebody"] = {} 2026 objects["faithplate"] = {} 2027 objects["laser"] = {} 2028 objects["laserdetector"] = {} 2029 objects["gel"] = {} 2030 objects["geldispenser"] = {} 2031 objects["cubedispenser"] = {} 2032 objects["pushbutton"] = {} 2033 objects["bulletbill"] = {} 2034 objects["hammerbro"] = {} 2035 objects["hammer"] = {} 2036 objects["fireball"] = {} 2037 objects["platform"] = {} 2038 objects["platformspawner"] = {} 2039 objects["plant"] = {} 2040 objects["castlefire"] = {} 2041 objects["castlefirefire"] = {} 2042 objects["fire"] = {} 2043 objects["bowser"] = {} 2044 objects["spring"] = {} 2045 objects["cheep"] = {} 2046 objects["flyingfish"] = {} 2047 objects["upfire"] = {} 2048 objects["seesawplatform"] = {} 2049 objects["lakito"] = {} 2050 objects["squid"] = {} 2051 2052 objects["screenboundary"] = {} 2053 objects["screenboundary"]["left"] = screenboundary:new(0) 2054 2055 splitxscroll = {0} 2056 2057 startx = 3 2058 starty = 13 2059 pipestartx = nil 2060 pipestarty = nil 2061 animation = nil 2062 2063 enemiesspawned = {} 2064 2065 intermission = false 2066 haswarpzone = false 2067 underwater = false 2068 bonusstage = false 2069 custombackground = false 2070 mariotimelimit = 400 2071 spriteset = 1 2072 --LOAD THE MAP 2073 if loadmap(level) == false then --make one up 2074 mapwidth = width 2075 map = {} 2076 for x = 1, width do 2077 map[x] = {} 2078 for y = 1, 15 do 2079 if y > 13 then 2080 map[x][y] = {2} 2081 objects["tile"][x .. "-" .. y] = tile:new(x-1, y-1, 1, 1, true) 2082 map[x][y]["gels"] = {} 2083 else 2084 map[x][y] = {1} 2085 map[x][y]["gels"] = {} 2086 end 2087 end 2088 end 2089 else 2090 if sublevel == false and mariosublevel ~= 0 then 2091 level = marioworld .. "-" .. mariolevel 2092 mariosublevel = 0 2093 loadmap(level) 2094 end 2095 end 2096 2097 objects["screenboundary"]["right"] = screenboundary:new(mapwidth) 2098 2099 if flagx then 2100 objects["screenboundary"]["flag"] = screenboundary:new(flagx+6/16) 2101 end 2102 2103 if axex then 2104 objects["screenboundary"]["axe"] = screenboundary:new(axex+1) 2105 end 2106 2107 if intermission then 2108 animation = "intermission" 2109 end 2110 2111 if not sublevel then 2112 mariotime = mariotimelimit 2113 end 2114 2115 --Maze setup 2116 --check every block between every start/end pair to see how many gates it contains 2117 if #mazestarts == #mazeends then 2118 mazegates = {} 2119 for i = 1, #mazestarts do 2120 local maxgate = 1 2121 for x = mazestarts[i], mazeends[i] do 2122 for y = 1, 15 do 2123 if map[x][y][2] and entityquads[map[x][y][2]].t == "mazegate" then 2124 if tonumber(map[x][y][3]) > maxgate then 2125 maxgate = tonumber(map[x][y][3]) 2126 end 2127 end 2128 end 2129 end 2130 mazegates[i] = maxgate 2131 end 2132 else 2133 print("Mazenumber doesn't fit!") 2134 end 2135 2136 --background 2137 love.graphics.setBackgroundColor(backgroundcolor[background]) 2138 2139 --check if it's a bonusstage (boooooooonus!) 2140 if bonusstage then 2141 animation = "vinestart" 2142 end 2143 2144 --set startx to checkpoint 2145 if checkpointx and checkcheckpoint then 2146 startx = checkpointx 2147 starty = checkpointpoints[checkpointx] or 13 2148 2149 --clear enemies from spawning near 2150 for y = 1, 15 do 2151 for x = startx-8, startx+8 do 2152 if inmap(x, y) and #map[x][y] > 1 then 2153 if tablecontains(enemies, entityquads[map[x][y][2]].t) then 2154 table.insert(enemiesspawned, {x, y}) 2155 end 2156 end 2157 end 2158 end 2159 2160 --find which i it is 2161 for i = 1, #checkpoints do 2162 if checkpointx == checkpoints[i] then 2163 checkpointi = i 2164 end 2165 end 2166 end 2167 2168 --set startx to pipestart 2169 if pipestartx then 2170 startx = pipestartx-1 2171 starty = pipestarty 2172 --check if startpos is a colliding block 2173 if tilequads[map[startx][starty][1]].collision then 2174 animation = "pipeup" 2175 end 2176 end 2177 2178 splitxscroll = {startx-scrollingleftcomplete-2} 2179 if splitxscroll[1] > mapwidth - width then 2180 splitxscroll[1] = mapwidth - width 2181 end 2182 2183 if splitxscroll[1] < 0 then 2184 splitxscroll[1] = 0 2185 end 2186 2187 --ADD ENEMIES ON START SCREEN 2188 if editormode == false then 2189 local xtodo = width+1 2190 if mapwidth < width+1 then 2191 xtodo = mapwidth 2192 end 2193 2194 for x = math.floor(splitxscroll[1]), math.floor(splitxscroll[1])+xtodo do 2195 for y = 1, 15 do 2196 spawnenemy(x, y) 2197 end 2198 end 2199 end 2200 2201 --add the players 2202 local mul = 0.5 2203 if mariosublevel ~= 0 or prevsublevel ~= false then 2204 mul = 2/16 2205 end 2206 2207 objects["player"] = {} 2208 for i = 1, players do 2209 if startx then 2210 objects["player"][i] = mario:new(startx + (i-1)*mul-6/16, starty-1, i, animation, mariosizes[i], playertype) 2211 else 2212 objects["player"][i] = mario:new(1.5 + (i-1)*mul-6/16+1.5, 13, i, animation, mariosizes[i], playertype) 2213 end 2214 end 2215 2216 --PLAY BGM 2217 if intermission == false then 2218 playmusic() 2219 else 2220 playsound(intermissionsound) 2221 end 2222 2223 --load editor 2224 editor_load() 2225 2226 --Do stuff 2227 for i, v in pairs(objects["laser"]) do 2228 v:updaterange() 2229 end 2230 for i, v in pairs(objects["lightbridge"]) do 2231 v:updaterange() 2232 end 2233 2234 generatespritebatch() 2235end 2236 2237function loadmap(filename) 2238 print("Loading " .. "mappacks/" .. mappack .. "/" .. filename .. ".txt") 2239 if love.filesystem.exists("mappacks/" .. mappack .. "/" .. filename .. ".txt") == false then 2240 print("mappacks/" .. mappack .. "/" .. filename .. ".txt not found!") 2241 return false 2242 end 2243 local s = love.filesystem.read( "mappacks/" .. mappack .. "/" .. filename .. ".txt" ) 2244 local s2 = s:split(";") 2245 2246 --MAP ITSELF 2247 local t = s2[1]:split(",") 2248 2249 if math.mod(#t, 15) ~= 0 then 2250 print("Incorrect number of entries: " .. #t) 2251 return false 2252 end 2253 2254 mapwidth = #t/15 2255 2256 map = {} 2257 unstatics = {} 2258 2259 for x = 1, #t/15 do 2260 map[x] = {} 2261 for y = 1, 15 do 2262 map[x][y] = {} 2263 map[x][y]["gels"] = {} 2264 2265 local r = tostring(t[(y-1)*(#t/15)+x]):split("-") 2266 2267 if tonumber(r[1]) > smbtilecount+portaltilecount+customtilecount then 2268 r[1] = 1 2269 end 2270 2271 for i = 1, #r do 2272 if r[i] ~= "link" then 2273 map[x][y][i] = tonumber(r[i]) 2274 else 2275 map[x][y][i] = r[i] 2276 end 2277 end 2278 2279 --create object for block 2280 if tilequads[tonumber(r[1])].collision == true then 2281 objects["tile"][x .. "-" .. y] = tile:new(x-1, y-1, 1, 1, true) 2282 end 2283 end 2284 end 2285 2286 for y = 1, 15 do 2287 for x = 1, #t/15 do 2288 local r = map[x][y] 2289 if #r > 1 then 2290 local t = entityquads[r[2]].t 2291 if t == "spawn" then 2292 startx = x 2293 starty = y 2294 2295 elseif not editormode then 2296 if t == "warppipe" then 2297 table.insert(warpzonenumbers, {x, y, r[3]}) 2298 2299 elseif t == "manycoins" then 2300 map[x][y][3] = 7 2301 2302 elseif t == "flag" then 2303 flagx = x-1 2304 flagy = y 2305 2306 elseif t == "pipespawn" and (prevsublevel == r[3] or (mariosublevel == r[3] and blacktime == sublevelscreentime)) then 2307 pipestartx = x 2308 pipestarty = y 2309 2310 elseif t == "emancehor" then 2311 table.insert(emancipationgrills, emancipationgrill:new(x, y, "hor")) 2312 elseif t == "emancever" then 2313 table.insert(emancipationgrills, emancipationgrill:new(x, y, "ver")) 2314 2315 elseif t == "doorver" then 2316 table.insert(objects["door"], door:new(x, y, r, "ver")) 2317 elseif t == "doorhor" then 2318 table.insert(objects["door"], door:new(x, y, r, "hor")) 2319 2320 elseif t == "button" then 2321 table.insert(objects["button"], button:new(x, y)) 2322 2323 elseif t == "pushbuttonleft" then 2324 table.insert(objects["pushbutton"], pushbutton:new(x, y, "left")) 2325 elseif t == "pushbuttonright" then 2326 table.insert(objects["pushbutton"], pushbutton:new(x, y, "right")) 2327 2328 elseif t == "wallindicator" then 2329 table.insert(objects["wallindicator"], wallindicator:new(x, y, r)) 2330 2331 elseif t == "groundlightver" then 2332 table.insert(objects["groundlight"], groundlight:new(x, y, 1, r)) 2333 elseif t == "groundlighthor" then 2334 table.insert(objects["groundlight"], groundlight:new(x, y, 2, r)) 2335 elseif t == "groundlightupright" then 2336 table.insert(objects["groundlight"], groundlight:new(x, y, 3, r)) 2337 elseif t == "groundlightrightdown" then 2338 table.insert(objects["groundlight"], groundlight:new(x, y, 4, r)) 2339 elseif t == "groundlightdownleft" then 2340 table.insert(objects["groundlight"], groundlight:new(x, y, 5, r)) 2341 elseif t == "groundlightleftup" then 2342 table.insert(objects["groundlight"], groundlight:new(x, y, 6, r)) 2343 2344 elseif t == "faithplateup" then 2345 table.insert(objects["faithplate"], faithplate:new(x, y, "up")) 2346 elseif t == "faithplateright" then 2347 table.insert(objects["faithplate"], faithplate:new(x, y, "right")) 2348 elseif t == "faithplateleft" then 2349 table.insert(objects["faithplate"], faithplate:new(x, y, "left")) 2350 2351 elseif t == "laserright" then 2352 table.insert(objects["laser"], laser:new(x, y, "right", r)) 2353 elseif t == "laserdown" then 2354 table.insert(objects["laser"], laser:new(x, y, "down", r)) 2355 elseif t == "laserleft" then 2356 table.insert(objects["laser"], laser:new(x, y, "left", r)) 2357 elseif t == "laserup" then 2358 table.insert(objects["laser"], laser:new(x, y, "up", r)) 2359 2360 elseif t == "lightbridgeright" then 2361 table.insert(objects["lightbridge"], lightbridge:new(x, y, "right", r)) 2362 elseif t == "lightbridgeleft" then 2363 table.insert(objects["lightbridge"], lightbridge:new(x, y, "left", r)) 2364 elseif t == "lightbridgedown" then 2365 table.insert(objects["lightbridge"], lightbridge:new(x, y, "down", r)) 2366 elseif t == "lightbridgeup" then 2367 table.insert(objects["lightbridge"], lightbridge:new(x, y, "up", r)) 2368 2369 elseif t == "laserdetectorright" then 2370 table.insert(objects["laserdetector"], laserdetector:new(x, y, "right")) 2371 elseif t == "laserdetectordown" then 2372 table.insert(objects["laserdetector"], laserdetector:new(x, y, "down")) 2373 elseif t == "laserdetectorleft" then 2374 table.insert(objects["laserdetector"], laserdetector:new(x, y, "left")) 2375 elseif t == "laserdetectorup" then 2376 table.insert(objects["laserdetector"], laserdetector:new(x, y, "up")) 2377 2378 elseif t == "boxtube" then 2379 table.insert(objects["cubedispenser"], cubedispenser:new(x, y, r)) 2380 2381 elseif t == "timer" then 2382 table.insert(objects["walltimer"], walltimer:new(x, y, r[3], r)) 2383 elseif t == "notgate" then 2384 table.insert(objects["notgate"], notgate:new(x, y, r)) 2385 2386 elseif t == "platformspawnerup" then 2387 table.insert(platformspawners, platformspawner:new(x, y, "up", r[3])) 2388 elseif t == "platformspawnerdown" then 2389 table.insert(platformspawners, platformspawner:new(x, y, "down", r[3])) 2390 2391 elseif t == "box" then 2392 table.insert(objects["box"], box:new(x, y)) 2393 2394 elseif t == "firestart" then 2395 firestartx = x 2396 2397 elseif t == "flyingfishstart" then 2398 flyingfishstartx = x 2399 elseif t == "flyingfishend" then 2400 flyingfishendx = x 2401 2402 elseif t == "bulletbillstart" then 2403 bulletbillstartx = x 2404 elseif t == "bulletbillend" then 2405 bulletbillendx = x 2406 2407 elseif t == "axe" then 2408 axex = x 2409 axey = y 2410 2411 elseif t == "lakitoend" then 2412 lakitoendx = x 2413 2414 elseif t == "spring" then 2415 table.insert(objects["spring"], spring:new(x, y)) 2416 2417 elseif t == "seesaw" then 2418 table.insert(seesaws, seesaw:new(x, y, r[3])) 2419 2420 elseif t == "checkpoint" then 2421 if not tablecontains(checkpoints, x) then 2422 table.insert(checkpoints, x) 2423 checkpointpoints[x] = y 2424 end 2425 elseif t == "mazestart" then 2426 if not tablecontains(mazestarts, x) then 2427 table.insert(mazestarts, x) 2428 end 2429 2430 elseif t == "mazeend" then 2431 if not tablecontains(mazeends, x) then 2432 table.insert(mazeends, x) 2433 end 2434 2435 elseif t == "geltop" then 2436 if tilequads[map[x][y][1]].collision then 2437 map[x][y]["gels"]["top"] = r[3] 2438 end 2439 elseif t == "gelleft" then 2440 if tilequads[map[x][y][1]].collision then 2441 map[x][y]["gels"]["left"] = r[3] 2442 end 2443 elseif t == "gelbottom" then 2444 if tilequads[map[x][y][1]].collision then 2445 map[x][y]["gels"]["bottom"] = r[3] 2446 end 2447 elseif t == "gelright" then 2448 if tilequads[map[x][y][1]].collision then 2449 map[x][y]["gels"]["right"] = r[3] 2450 end 2451 end 2452 end 2453 end 2454 end 2455 end 2456 2457 --sort checkpoints 2458 table.sort(checkpoints) 2459 2460 --Add links 2461 for i, v in pairs(objects) do 2462 for j, w in pairs(v) do 2463 if w.link then 2464 w:link() 2465 end 2466 end 2467 end 2468 2469 if flagx then 2470 flagimgx = flagx+8/16 2471 flagimgy = 3+1/16 2472 end 2473 2474 for x = 0, -30, -1 do 2475 map[x] = {} 2476 for y = 1, 13 do 2477 map[x][y] = {1} 2478 end 2479 2480 for y = 14, 15 do 2481 map[x][y] = {2} 2482 objects["tile"][x .. "-" .. y] = tile:new(x-1, y-1, 1, 1, true) 2483 end 2484 end 2485 2486 --MORE STUFF 2487 for i = 2, #s2 do 2488 s3 = s2[i]:split("=") 2489 if s3[1] == "background" then 2490 background = tonumber(s3[2]) 2491 elseif s3[1] == "spriteset" then 2492 spriteset = tonumber(s3[2]) 2493 elseif s3[1] == "intermission" then 2494 intermission = true 2495 elseif s3[1] == "haswarpzone" then 2496 haswarpzone = true 2497 elseif s3[1] == "underwater" then 2498 underwater = true 2499 elseif s3[1] == "music" then 2500 musici = tonumber(s3[2]) 2501 elseif s3[1] == "bonusstage" then 2502 bonusstage = true 2503 elseif s3[1] == "custombackground" or s3[1] == "portalbackground" then 2504 custombackground = true 2505 elseif s3[1] == "timelimit" then 2506 mariotimelimit = tonumber(s3[2]) 2507 elseif s3[1] == "scrollfactor" then 2508 scrollfactor = tonumber(s3[2]) 2509 end 2510 end 2511 2512 if custombackground then 2513 loadcustombackground() 2514 end 2515 2516 return true 2517end 2518 2519function changemapwidth(width) 2520 if width > mapwidth then 2521 for x = mapwidth+1, width do 2522 map[x] = {} 2523 for y = 1, 13 do 2524 map[x][y] = {1} 2525 map[x][y]["gels"] = {} 2526 end 2527 2528 for y = 14, 15 do 2529 map[x][y] = {2} 2530 objects["tile"][x .. "-" .. y] = tile:new(x-1, y-1, 1, 1, true) 2531 map[x][y]["gels"] = {} 2532 end 2533 end 2534 end 2535 2536 mapwidth = width 2537 objects["screenboundary"]["right"].x = mapwidth 2538 2539 if objects["player"][1].x > mapwidth then 2540 objects["player"][1].x = mapwidth-1 2541 end 2542end 2543 2544function generatespritebatch() 2545 for split = 1, #splitscreen do 2546 local smbmsb = smbspritebatch[split] 2547 local portalmsb = portalspritebatch[split] 2548 local custommsb 2549 if customtiles then 2550 custommsb = customspritebatch[split] 2551 end 2552 smbmsb:clear() 2553 portalmsb:clear() 2554 if customtiles then 2555 custommsb:clear() 2556 end 2557 2558 local xtodraw 2559 if mapwidth < width+1 then 2560 xtodraw = math.ceil(mapwidth/#splitscreen) 2561 else 2562 if mapwidth > width and splitxscroll[split] < mapwidth-width then 2563 xtodraw = width+1 2564 else 2565 xtodraw = width 2566 end 2567 end 2568 2569 local lmap = map 2570 2571 for y = 1, 15 do 2572 for x = 1, xtodraw do 2573 local bounceyoffset = 0 2574 2575 local draw = true 2576 for i, v in pairs(blockbouncex) do 2577 if blockbouncex[i] == math.floor(splitxscroll[split])+x and blockbouncey[i] == y then 2578 draw = false 2579 end 2580 end 2581 if draw == true then 2582 local t = lmap[math.floor(splitxscroll[split])+x][y] 2583 2584 local tilenumber = t[1] 2585 if tilenumber ~= 0 and tilequads[tilenumber].invisible == false and tilequads[tilenumber].coinblock == false and tilequads[tilenumber].coin == false then 2586 if tilenumber <= smbtilecount then 2587 smbmsb:addq( tilequads[tilenumber].quad, (x-1)*16*scale, ((y-1)*16-8)*scale, 0, scale, scale ) 2588 elseif tilenumber <= smbtilecount+portaltilecount then 2589 portalmsb:addq( tilequads[tilenumber].quad, (x-1)*16*scale, ((y-1)*16-8)*scale, 0, scale, scale ) 2590 elseif tilenumber <= smbtilecount+portaltilecount+customtilecount then 2591 custommsb:addq( tilequads[tilenumber].quad, (x-1)*16*scale, ((y-1)*16-8)*scale, 0, scale, scale ) 2592 end 2593 end 2594 end 2595 end 2596 end 2597 end 2598end 2599 2600function game_keypressed(key, unicode) 2601 if pausemenuopen then 2602 if menuprompt then 2603 if (key == "left" or key == "a") then 2604 pausemenuselected2 = 1 2605 elseif (key == "right" or key == "d") then 2606 pausemenuselected2 = 2 2607 elseif (key == "return" or key == "enter" or key == "kpenter" or key == " ") then 2608 if pausemenuselected2 == 1 then 2609 love.audio.stop() 2610 pausemenuopen = false 2611 menuprompt = false 2612 menu_load() 2613 else 2614 menuprompt = false 2615 end 2616 elseif key == "escape" then 2617 menuprompt = false 2618 end 2619 return 2620 elseif desktopprompt then 2621 if (key == "left" or key == "a") then 2622 pausemenuselected2 = 1 2623 elseif (key == "right" or key == "d") then 2624 pausemenuselected2 = 2 2625 elseif (key == "return" or key == "enter" or key == "kpenter" or key == " ") then 2626 if pausemenuselected2 == 1 then 2627 love.audio.stop() 2628 love.event.quit() 2629 else 2630 desktopprompt = false 2631 end 2632 elseif key == "escape" then 2633 desktopprompt = false 2634 end 2635 return 2636 elseif suspendprompt then 2637 if (key == "left" or key == "a") then 2638 pausemenuselected2 = 1 2639 elseif (key == "right" or key == "d") then 2640 pausemenuselected2 = 2 2641 elseif (key == "return" or key == "enter" or key == "kpenter" or key == " ") then 2642 if pausemenuselected2 == 1 then 2643 love.audio.stop() 2644 suspendgame() 2645 suspendprompt = false 2646 pausemenuopen = false 2647 else 2648 suspendprompt = false 2649 end 2650 elseif key == "escape" then 2651 suspendprompt = false 2652 end 2653 return 2654 end 2655 if (key == "down" or key == "s") then 2656 if pausemenuselected < #pausemenuoptions then 2657 pausemenuselected = pausemenuselected + 1 2658 end 2659 elseif (key == "up" or key == "w") then 2660 if pausemenuselected > 1 then 2661 pausemenuselected = pausemenuselected - 1 2662 end 2663 elseif (key == "return" or key == "enter" or key == "kpenter" or key == " ") then 2664 if pausemenuoptions[pausemenuselected] == "resume" then 2665 pausemenuopen = false 2666 love.audio.resume() 2667 elseif pausemenuoptions[pausemenuselected] == "suspend" then 2668 suspendprompt = true 2669 pausemenuselected2 = 1 2670 elseif pausemenuoptions2[pausemenuselected] == "menu" then 2671 menuprompt = true 2672 pausemenuselected2 = 1 2673 elseif pausemenuoptions2[pausemenuselected] == "desktop" then 2674 desktopprompt = true 2675 pausemenuselected2 = 1 2676 end 2677 elseif key == "escape" then 2678 pausemenuopen = false 2679 love.audio.resume() 2680 elseif (key == "right" or key == "d") then 2681 if pausemenuoptions[pausemenuselected] == "volume" then 2682 if volume < 1 then 2683 volume = volume + 0.1 2684 love.audio.setVolume( volume ) 2685 soundenabled = true 2686 playsound(coinsound) 2687 end 2688 end 2689 2690 elseif (key == "left" or key == "a") then 2691 if pausemenuoptions[pausemenuselected] == "volume" then 2692 volume = math.max(volume - 0.1, 0) 2693 love.audio.setVolume( volume ) 2694 if volume == 0 then 2695 soundenabled = false 2696 end 2697 playsound(coinsound) 2698 end 2699 end 2700 2701 return 2702 end 2703 2704 if endpressbutton then 2705 endpressbutton = false 2706 endgame() 2707 return 2708 end 2709 2710 for i = 1, players do 2711 if controls[i]["jump"][1] == key then 2712 objects["player"][i]:jump() 2713 elseif controls[i]["run"][1] == key then 2714 objects["player"][i]:fire() 2715 elseif controls[i]["reload"][1] == key then 2716 objects["player"][i]:removeportals() 2717 elseif controls[i]["use"][1] == key then 2718 objects["player"][i]:use() 2719 elseif controls[i]["left"][1] == key then 2720 objects["player"][i]:leftkey() 2721 elseif controls[i]["right"][1] == key then 2722 objects["player"][i]:rightkey() 2723 end 2724 2725 if controls[i]["portal1"][i] == key then 2726 shootportal(i, 1, objects["player"][i].x+6/16, objects["player"][i].y+6/16, objects["player"][i].pointingangle) 2727 return 2728 end 2729 2730 if controls[i]["portal2"][i] == key then 2731 shootportal(i, 2, objects["player"][i].x+6/16, objects["player"][i].y+6/16, objects["player"][i].pointingangle) 2732 return 2733 end 2734 end 2735 2736 if key == "escape" then 2737 if not editormode and testlevel then 2738 marioworld = testlevelworld 2739 mariolevel = testlevellevel 2740 testlevel = false 2741 editormode = true 2742 startlevel(marioworld .. "-" .. mariolevel) 2743 return 2744 elseif not editormode and not everyonedead then 2745 pausemenuopen = true 2746 love.audio.pause() 2747 playsound(pausesound) 2748 end 2749 end 2750 2751 if editormode then 2752 editor_keypressed(key) 2753 end 2754end 2755 2756function game_keyreleased(key, unicode) 2757 for i = 1, players do 2758 if controls[i]["jump"][1] == key then 2759 objects["player"][i]:stopjump() 2760 end 2761 end 2762end 2763 2764function createportal(plnumber, i, cox, coy, side, tendency, x, y) 2765 if cox ~= false then 2766 local otheri = 1 2767 if i == 1 then 2768 otheri = 2 2769 end 2770 2771 moveoutportal(i) 2772 2773 --remove the portal temporarily so that it doesn't obstruct itself 2774 local oldx, oldy, oldfacing 2775 if i == 1 then 2776 oldx, oldy, oldfacing = objects["player"][plnumber].portal1X, objects["player"][plnumber].portal1Y, objects["player"][plnumber].portal1facing 2777 objects["player"][plnumber].portal1X, objects["player"][plnumber].portal1Y = false, false 2778 else 2779 oldx, oldy, oldfacing = objects["player"][plnumber].portal2X, objects["player"][plnumber].portal2Y, objects["player"][plnumber].portal2facing 2780 objects["player"][plnumber].portal2X, objects["player"][plnumber].portal2Y = false, false 2781 end 2782 2783 local newx, newy = getportalposition(i, cox, coy, side, tendency) 2784 2785 if newx and (newx ~= oldx or newy ~= oldy or side ~= oldfacing) then 2786 if i == 1 then 2787 objects["player"][plnumber].portal1X = newx 2788 objects["player"][plnumber].portal1Y = newy 2789 objects["player"][plnumber].portal1facing = side 2790 else 2791 objects["player"][plnumber].portal2X = newx 2792 objects["player"][plnumber].portal2Y = newy 2793 objects["player"][plnumber].portal2facing = side 2794 end 2795 2796 --physics 2797 --Recreate old hole 2798 if oldfacing == "up" then 2799 modifyportaltiles(oldx, oldy, 1, 0, plnumber, i, "add") 2800 elseif oldfacing == "down" then 2801 modifyportaltiles(oldx, oldy, -1, 0, plnumber, i, "add") 2802 elseif oldfacing == "left" then 2803 modifyportaltiles(oldx, oldy, 0, -1, plnumber, i, "add") 2804 elseif oldfacing == "right" then 2805 modifyportaltiles(oldx, oldy, 0, 1, plnumber, i, "add") 2806 end 2807 2808 --Create and remove new stuff 2809 if side == "up" then 2810 objects["portalwall"][plnumber .. "-" .. i .. "-1"] = portalwall:new(newx-1, newy, 2, 0, true) 2811 objects["portalwall"][plnumber .. "-" .. i .. "-2"] = portalwall:new(newx-1, newy-1, 0, 1, true) 2812 objects["portalwall"][plnumber .. "-" .. i .. "-3"] = portalwall:new(newx+1, newy-1, 0, 1, true) 2813 2814 modifyportaltiles(newx, newy, 1, 0, plnumber, i, "remove") 2815 elseif side == "down" then 2816 objects["portalwall"][plnumber .. "-" .. i .. "-1"] = portalwall:new(newx-2, newy-1, 2, 0, true) 2817 objects["portalwall"][plnumber .. "-" .. i .. "-2"] = portalwall:new(newx-2, newy-1, 0, 1, true) 2818 objects["portalwall"][plnumber .. "-" .. i .. "-3"] = portalwall:new(newx, newy-1, 0, 1, true) 2819 2820 modifyportaltiles(newx, newy, -1, 0, plnumber, i, "remove") 2821 elseif side == "left" then 2822 objects["portalwall"][plnumber .. "-" .. i .. "-1"] = portalwall:new(newx, newy-2, 0, 2, true) 2823 objects["portalwall"][plnumber .. "-" .. i .. "-2"] = portalwall:new(newx-1, newy-2, 1, 0, true) 2824 objects["portalwall"][plnumber .. "-" .. i .. "-3"] = portalwall:new(newx-1, newy, 1, 0, true) 2825 2826 modifyportaltiles(newx, newy, 0, -1, plnumber, i, "remove") 2827 elseif side == "right" then 2828 objects["portalwall"][plnumber .. "-" .. i .. "-1"] = portalwall:new(newx-1, newy-1, 0, 2, true) 2829 objects["portalwall"][plnumber .. "-" .. i .. "-2"] = portalwall:new(newx-1, newy-1, 1, 0, true) 2830 objects["portalwall"][plnumber .. "-" .. i .. "-3"] = portalwall:new(newx-1, newy+1, 1, 0, true) 2831 2832 modifyportaltiles(newx, newy, 0, 1, plnumber, i, "remove") 2833 end 2834 2835 if oldx == false then --Remove blocks from other portal 2836 local x, y, side 2837 if otheri == 1 then 2838 side = objects["player"][plnumber].portal1facing 2839 x, y = objects["player"][plnumber].portal1X, objects["player"][plnumber].portal1Y 2840 else 2841 side = objects["player"][plnumber].portal2facing 2842 x, y = objects["player"][plnumber].portal2X, objects["player"][plnumber].portal2Y 2843 end 2844 2845 if side == "up" then 2846 modifyportaltiles(x, y, 1, 0, plnumber, otheri, "remove") 2847 elseif side == "down" then 2848 modifyportaltiles(x, y, -1, 0, plnumber, otheri, "remove") 2849 elseif side == "left" then 2850 modifyportaltiles(x, y, 0, -1, plnumber, otheri, "remove") 2851 elseif side == "right" then 2852 modifyportaltiles(x, y, 0, 1, plnumber, otheri, "remove") 2853 end 2854 end 2855 2856 objects["player"][plnumber].lastportal = i 2857 2858 if i == 1 then 2859 playsound(portal1opensound) 2860 else 2861 playsound(portal2opensound) 2862 end 2863 2864 2865 for i, v in pairs(objects["lightbridge"]) do 2866 v:updaterange() 2867 end 2868 2869 for i, v in pairs(objects["laser"]) do 2870 v:updaterange() 2871 end 2872 else 2873 --recreate the temporarily removed portal 2874 if i == 1 then 2875 objects["player"][plnumber].portal1X, objects["player"][plnumber].portal1Y = oldx, oldy 2876 else 2877 objects["player"][plnumber].portal2X, objects["player"][plnumber].portal2Y = oldx, oldy 2878 end 2879 end 2880 end 2881end 2882 2883function shootportal(plnumber, i, sourcex, sourcey, direction) 2884 --box 2885 if objects["player"][plnumber].pickup then 2886 return 2887 end 2888 --portalgun delay 2889 if portaldelay[plnumber] > 0 then 2890 return 2891 else 2892 portaldelay[plnumber] = portalgundelay 2893 end 2894 2895 local otheri = 1 2896 local color = objects["player"][plnumber].portal2color 2897 if i == 1 then 2898 otheri = 2 2899 color = objects["player"][plnumber].portal1color 2900 end 2901 2902 local cox, coy, side, tendency, x, y = traceline(sourcex, sourcey, direction) 2903 table.insert(portalprojectiles, portalprojectile:new(sourcex, sourcey, x, y, color, true, {plnumber, i, cox, coy, side, tendency, x, y})) 2904end 2905 2906function game_mousepressed(x, y, button) 2907 if pausemenuopen then 2908 return 2909 end 2910 if editormode and editorstate ~= "portalgun" then 2911 editor_mousepressed(x, y, button) 2912 else 2913 if editormode then 2914 editor_mousepressed(x, y, button) 2915 end 2916 2917 if not noupdate and objects["player"][mouseowner] and objects["player"][mouseowner].controlsenabled and objects["player"][mouseowner].vine == false then 2918 2919 if button == "l" or button == "r" and objects["player"][mouseowner] then 2920 --knockback 2921 if portalknockback then 2922 local xadd = math.sin(objects["player"][mouseowner].pointingangle)*30 2923 local yadd = math.cos(objects["player"][mouseowner].pointingangle)*30 2924 objects["player"][mouseowner].speedx = objects["player"][mouseowner].speedx + xadd 2925 objects["player"][mouseowner].speedy = objects["player"][mouseowner].speedy + yadd 2926 objects["player"][mouseowner].falling = true 2927 objects["player"][mouseowner].animationstate = "falling" 2928 objects["player"][mouseowner]:setquad() 2929 end 2930 end 2931 2932 if button == "l" then 2933 if playertype == "portal" then 2934 local sourcex = objects["player"][mouseowner].x+6/16 2935 local sourcey = objects["player"][mouseowner].y+6/16 2936 local direction = objects["player"][mouseowner].pointingangle 2937 2938 shootportal(mouseowner, 1, sourcex, sourcey, direction) 2939 elseif playertype == "minecraft" then 2940 local v = objects["player"][mouseowner] 2941 local sourcex, sourcey = v.x+6/16, v.y+6/16 2942 local cox, coy, side, tend, x, y = traceline(sourcex, sourcey, v.pointingangle) 2943 2944 if cox then 2945 local dist = math.sqrt((v.x+v.width/2 - x)^2 + (v.y+v.height/2 - y)^2) 2946 if dist <= minecraftrange then 2947 breakingblockX = cox 2948 breakingblockY = coy 2949 breakingblockprogress = 0 2950 end 2951 end 2952 end 2953 2954 elseif button == "r" then 2955 if playertype == "portal" then 2956 local sourcex = objects["player"][mouseowner].x+6/16 2957 local sourcey = objects["player"][mouseowner].y+6/16 2958 local direction = objects["player"][mouseowner].pointingangle 2959 2960 shootportal(mouseowner, 2, sourcex, sourcey, direction) 2961 elseif playertype == "minecraft" then 2962 local v = objects["player"][mouseowner] 2963 local sourcex, sourcey = v.x+6/16, v.y+6/16 2964 local cox, coy, side, tend, x, y = traceline(sourcex, sourcey, v.pointingangle) 2965 2966 if cox then 2967 local dist = math.sqrt((v.x+v.width/2 - x)^2 + (v.y+v.height/2 - y)^2) 2968 if dist <= minecraftrange then 2969 placeblock(cox, coy, side) 2970 end 2971 end 2972 end 2973 end 2974 end 2975 2976 if button == "wd" then 2977 if playertype == "minecraft" then 2978 mccurrentblock = mccurrentblock + 1 2979 if mccurrentblock >= 10 then 2980 mccurrentblock = 1 2981 end 2982 elseif bullettime then 2983 speedtarget = speedtarget - 0.1 2984 if speedtarget < 0.1 then 2985 speedtarget = 0.1 2986 end 2987 end 2988 elseif button == "wu" then 2989 if playertype == "minecraft" then 2990 mccurrentblock = mccurrentblock - 1 2991 if mccurrentblock <= 0 then 2992 mccurrentblock = 9 2993 end 2994 elseif bullettime then 2995 speedtarget = speedtarget + 0.1 2996 if speedtarget > 1 then 2997 speedtarget = 1 2998 end 2999 end 3000 end 3001 end 3002end 3003 3004function modifyportalwalls() 3005 --Create and remove new stuff 3006 if side == "up" then 3007 if getTile(newx-1, newy, nil, true, side) == false then 3008 objects["portalwall"][plnumber .. "-" .. i .. "-1"] = portalwall:new(newx-1, newy-1, 0, 1, true) 3009 end 3010 if getTile(newx, newy+1, nil, true, side) == false then 3011 objects["portalwall"][plnumber .. "-" .. i .. "-2"] = portalwall:new(newx-1, newy, 1, 0, true) 3012 end 3013 if getTile(newx+1, newy+1, nil, true, side) == false then 3014 objects["portalwall"][plnumber .. "-" .. i .. "-3"] = portalwall:new(newx, newy, 1, 0, true) 3015 end 3016 if getTile(newx+2, newy, nil, true, side) == false then 3017 objects["portalwall"][plnumber .. "-" .. i .. "-4"] = portalwall:new(newx+1, newy-1, 0, 1, true) 3018 end 3019 3020 modifyportaltiles(newx, newy, 1, 0, plnumber, i, "remove") 3021 elseif side == "down" then 3022 objects["portalwall"][plnumber .. "-" .. i .. "-1"] = portalwall:new(newx-2, newy-1, 2, 0, true) 3023 objects["portalwall"][plnumber .. "-" .. i .. "-2"] = portalwall:new(newx-2, newy-1, 0, 1, true) 3024 objects["portalwall"][plnumber .. "-" .. i .. "-3"] = portalwall:new(newx, newy-1, 0, 1, true) 3025 3026 modifyportaltiles(newx, newy, -1, 0, plnumber, i, "remove") 3027 elseif side == "left" then 3028 objects["portalwall"][plnumber .. "-" .. i .. "-1"] = portalwall:new(newx, newy-2, 0, 2, true) 3029 objects["portalwall"][plnumber .. "-" .. i .. "-2"] = portalwall:new(newx-1, newy-2, 1, 0, true) 3030 objects["portalwall"][plnumber .. "-" .. i .. "-3"] = portalwall:new(newx-1, newy, 1, 0, true) 3031 3032 modifyportaltiles(newx, newy, 0, -1, plnumber, i, "remove") 3033 elseif side == "right" then 3034 objects["portalwall"][plnumber .. "-" .. i .. "-1"] = portalwall:new(newx-1, newy-1, 0, 2, true) 3035 objects["portalwall"][plnumber .. "-" .. i .. "-2"] = portalwall:new(newx-1, newy-1, 1, 0, true) 3036 objects["portalwall"][plnumber .. "-" .. i .. "-3"] = portalwall:new(newx-1, newy+1, 1, 0, true) 3037 3038 modifyportaltiles(newx, newy, 0, 1, plnumber, i, "remove") 3039 end 3040end 3041 3042function modifyportaltiles(x, y, xplus, yplus, plnumber, i, mode) 3043 if i == 1 then 3044 if objects["player"][plnumber].portal2facing ~= nil then 3045 if mode == "add" then 3046 objects["tile"][x .. "-" .. y] = tile:new(x-1, y-1, 1, 1, true) 3047 objects["tile"][x+xplus .. "-" .. y+yplus] = tile:new(x-1+xplus, y-1+yplus, 1, 1, true) 3048 else 3049 objects["tile"][x .. "-" .. y] = nil 3050 objects["tile"][x+xplus .. "-" .. y+yplus] = nil 3051 end 3052 end 3053 else 3054 if objects["player"][plnumber].portal1facing ~= nil then 3055 if mode == "add" then 3056 objects["tile"][x .. "-" .. y] = tile:new(x-1, y-1, 1, 1, true) 3057 objects["tile"][x+xplus .. "-" .. y+yplus] = tile:new(x-1+xplus, y-1+yplus, 1, 1, true) 3058 else 3059 objects["tile"][x .. "-" .. y] = nil 3060 objects["tile"][x+xplus .. "-" .. y+yplus] = nil 3061 end 3062 end 3063 end 3064end 3065 3066function getportalposition(i, x, y, side, tendency) --returns the "optimal" position according to the parsed arguments (or false if no possible position was found) 3067 local xplus, yplus = 0, 0 3068 if side == "up" then 3069 yplus = -1 3070 elseif side == "right" then 3071 xplus = 1 3072 elseif side == "down" then 3073 yplus = 1 3074 elseif side == "left" then 3075 xplus = -1 3076 end 3077 3078 if side == "up" or side == "down" then 3079 if tendency == -1 then 3080 if getTile(x-1, y, true, true, side) == true and getTile(x, y, true, true, side) == true and getTile(x-1, y+yplus, nil, false, side) == false and getTile(x, y+yplus, nil, false, side) == false then 3081 if side == "up" then 3082 return x-1, y 3083 else 3084 return x, y 3085 end 3086 elseif getTile(x, y, true, true, side) == true and getTile(x+1, y, true, true, side) == true and getTile(x, y+yplus, nil, false, side) == false and getTile(x+1, y+yplus, nil, false, side) == false then 3087 if side == "up" then 3088 return x, y 3089 else 3090 return x+1, y 3091 end 3092 end 3093 else 3094 if getTile(x, y, true, true, side) == true and getTile(x+1, y, true, true, side) == true and getTile(x, y+yplus, nil, false, side) == false and getTile(x+1, y+yplus, nil, false, side) == false then 3095 if side == "up" then 3096 return x, y 3097 else 3098 return x+1, y 3099 end 3100 elseif getTile(x-1, y, true, true, side) == true and getTile(x, y, true, true, side) == true and getTile(x-1, y+yplus, nil, false, side) == false and getTile(x, y+yplus, nil, false, side) == false then 3101 if side == "up" then 3102 return x-1, y 3103 else 3104 return x, y 3105 end 3106 end 3107 end 3108 else 3109 if tendency == -1 then 3110 if getTile(x, y-1, true, true, side) == true and getTile(x, y, true, true, side) == true and getTile(x+xplus, y-1, nil, false, side) == false and getTile(x+xplus, y, nil, false, side) == false then 3111 if side == "right" then 3112 return x, y-1 3113 else 3114 return x, y 3115 end 3116 elseif getTile(x, y, true, true, side) == true and getTile(x, y+1, true, true, side) == true and getTile(x+xplus, y, nil, false, side) == false and getTile(x+xplus, y+1, nil, false, side) == false then 3117 if side == "right" then 3118 return x, y 3119 else 3120 return x, y+1 3121 end 3122 end 3123 else 3124 if getTile(x, y, true, true, side) == true and getTile(x, y+1, true, true, side) == true and getTile(x+xplus, y, nil, false, side) == false and getTile(x+xplus, y+1, nil, false, side) == false then 3125 if side == "right" then 3126 return x, y 3127 else 3128 return x, y+1 3129 end 3130 elseif getTile(x, y-1, true, true, side) == true and getTile(x, y, true, true, side) == true and getTile(x+xplus, y-1, nil, false, side) == false and getTile(x+xplus, y, nil, false, side) == false then 3131 if side == "right" then 3132 return x, y-1 3133 else 3134 return x, y 3135 end 3136 end 3137 end 3138 end 3139 3140 return false 3141end 3142 3143function getTile(x, y, portalable, portalcheck, facing) --returns masktable value of block (As well as the ID itself as second return parameter) also includes a portalcheck and returns false if a portal is on that spot. 3144 --Portal on same tile doesn't work so well yet (collision code, of course), so: 3145 --facing = nil 3146 3147 if portalcheck then 3148 for i, v in pairs(objects["player"]) do 3149 --Get the extra block of each portal 3150 local portal1xplus, portal1yplus, portal2xplus, portal2yplus = 0, 0, 0, 0 3151 if v.portal1facing == "up" then 3152 portal1xplus = 1 3153 elseif v.portal1facing == "right" then 3154 portal1yplus = 1 3155 elseif v.portal1facing == "down" then 3156 portal1xplus = -1 3157 elseif v.portal1facing == "left" then 3158 portal1yplus = -1 3159 end 3160 3161 if v.portal2facing == "up" then 3162 portal2xplus = 1 3163 elseif v.portal2facing == "right" then 3164 portal2yplus = 1 3165 elseif v.portal2facing == "down" then 3166 portal2xplus = -1 3167 elseif v.portal2facing == "left" then 3168 portal2yplus = -1 3169 end 3170 3171 if v.portal1X ~= false then 3172 if (x == v.portal1X or x == v.portal1X+portal1xplus) and (y == v.portal1Y or y == v.portal1Y+portal1yplus) then--and (facing == nil or v.portal1facing == facing) then 3173 return false 3174 end 3175 end 3176 3177 if v.portal2X ~= false then 3178 if (x == v.portal2X or x == v.portal2X+portal2xplus) and (y == v.portal2Y or y == v.portal2Y+portal2yplus) then--and (facing == nil or v.portal2facing == facing) then 3179 return false 3180 end 3181 end 3182 end 3183 end 3184 3185 --check for tubes 3186 for i, v in pairs(objects["geldispenser"]) do 3187 if (x == v.cox or x == v.cox+1) and (y == v.coy or y == v.coy+1) then 3188 if portalcheck then 3189 return false 3190 else 3191 return true 3192 end 3193 end 3194 end 3195 3196 for i, v in pairs(objects["cubedispenser"]) do 3197 if (x == v.cox or x == v.cox+1) and (y == v.coy or y == v.coy+1) then 3198 if portalcheck then 3199 return false 3200 else 3201 return true 3202 end 3203 end 3204 end 3205 3206 --bonusstage thing for keeping it from fucking up. 3207 if bonusstage then 3208 if y == 15 and (x == 4 or x == 6) then 3209 if portalcheck then 3210 return false 3211 else 3212 return true 3213 end 3214 end 3215 end 3216 3217 if x <= 0 or y <= 0 or y >= 16 or x > mapwidth then 3218 return false, 1 3219 end 3220 3221 if tilequads[map[x][y][1]].invisible then 3222 return false 3223 end 3224 3225 if portalcheck then 3226 local side 3227 if facing == "up" then 3228 side = "top" 3229 elseif facing == "right" then 3230 side = "right" 3231 elseif facing == "down" then 3232 side = "bottom" 3233 elseif facing == "left" then 3234 side = "left" 3235 end 3236 3237 --To stop people from portalling under the vine, which caused problems, but was fixed elsewhere (and betterer) 3238 --[[for i, v in pairs(objects["vine"]) do 3239 if x == v.cox and y == v.coy and side == "top" then 3240 return false, 1 3241 end 3242 end--]] 3243 3244 3245 if map[x][y]["gels"][side] == 3 then 3246 return true, map[x][y][1] 3247 else 3248 return tilequads[map[x][y][1]].collision and tilequads[map[x][y][1]].portalable, map[x][y][1] 3249 end 3250 else 3251 return tilequads[map[x][y][1]].collision, map[x][y][1] 3252 end 3253end 3254 3255function getPortal(x, y) --returns the block where you'd come out when you'd go in the argument's block 3256 for i, v in pairs(objects["player"]) do 3257 if v.portal1X ~= false and v.portal2X ~= false then 3258 --Get the extra block of each portal 3259 local portal1xplus, portal1yplus, portal2xplus, portal2yplus = 0, 0, 0, 0 3260 if v.portal1facing == "up" then 3261 portal1xplus = 1 3262 elseif v.portal1facing == "right" then 3263 portal1yplus = 1 3264 elseif v.portal1facing == "down" then 3265 portal1xplus = -1 3266 elseif v.portal1facing == "left" then 3267 portal1yplus = -1 3268 end 3269 3270 if v.portal2facing == "up" then 3271 portal2xplus = 1 3272 elseif v.portal2facing == "right" then 3273 portal2yplus = 1 3274 elseif v.portal2facing == "down" then 3275 portal2xplus = -1 3276 elseif v.portal2facing == "left" then 3277 portal2yplus = -1 3278 end 3279 3280 if v.portal1X ~= false then 3281 if (x == v.portal1X or x == v.portal1X+portal1xplus) and (y == v.portal1Y or y == v.portal1Y+portal1yplus) and (facing == nil or v.portal1facing == facing) then 3282 if v.portal1facing ~= v.portal2facing then 3283 local xplus, yplus = 0, 0 3284 if v.portal1facing == "left" or v.portal1facing == "right" then 3285 if y == v.portal1Y then 3286 if v.portal2facing == "left" or v.portal2facing == "right" then 3287 yplus = portal2yplus 3288 else 3289 xplus = portal2xplus 3290 end 3291 end 3292 3293 return v.portal2X+xplus, v.portal2Y+yplus, v.portal2facing, v.portal1facing 3294 else 3295 if x == v.portal1X then 3296 if v.portal2facing == "left" or v.portal2facing == "right" then 3297 yplus = portal2yplus 3298 else 3299 xplus = portal2xplus 3300 end 3301 end 3302 3303 return v.portal2X+xplus, v.portal2Y+yplus, v.portal2facing, v.portal1facing 3304 end 3305 else 3306 return v.portal2X+(x-v.portal1X), v.portal2Y+(y-v.portal1Y), v.portal2facing, v.portal1facing 3307 end 3308 end 3309 end 3310 3311 if v.portal2X ~= false then 3312 if (x == v.portal2X or x == v.portal2X+portal2xplus) and (y == v.portal2Y or y == v.portal2Y+portal2yplus) and (facing == nil or v.portal2facing == facing) then 3313 if v.portal1facing ~= v.portal2facing then 3314 local xplus, yplus = 0, 0 3315 if v.portal2facing == "left" or v.portal2facing == "right" then 3316 if y == v.portal2Y then 3317 if v.portal1facing == "left" or v.portal1facing == "right" then 3318 yplus = portal1yplus 3319 else 3320 xplus = portal1xplus 3321 end 3322 end 3323 3324 return v.portal1X+xplus, v.portal1Y+yplus, v.portal1facing, v.portal2facing 3325 else 3326 if x == v.portal2X then 3327 if v.portal1facing == "left" or v.portal1facing == "right" then 3328 yplus = portal1yplus 3329 else 3330 xplus = portal1xplus 3331 end 3332 end 3333 3334 return v.portal1X+xplus, v.portal1Y+yplus, v.portal1facing, v.portal2facing 3335 end 3336 else 3337 return v.portal1X+(x-v.portal2X), v.portal1Y+(y-v.portal2Y), v.portal1facing, v.portal2facing 3338 end 3339 end 3340 end 3341 end 3342 end 3343 3344 return false 3345end 3346 3347function insideportal(x, y, width, height) --returns whether an object is in, and which, portal. 3348 if width == nil then 3349 width = 12/16 3350 end 3351 if height == nil then 3352 height = 12/16 3353 end 3354 for i, v in pairs(objects["player"]) do 3355 if v.portal1X ~= false and v.portal2X ~= false then 3356 for j = 1, 2 do 3357 local portalx, portaly, portalfacing 3358 if j == 1 then 3359 portalx = v.portal1X 3360 portaly = v.portal1Y 3361 portalfacing = v.portal1facing 3362 else 3363 portalx = v.portal2X 3364 portaly = v.portal2Y 3365 portalfacing = v.portal2facing 3366 end 3367 3368 if portalfacing == "up" then 3369 xplus = 1 3370 elseif portalfacing == "down" then 3371 xplus = -1 3372 elseif portalfacing == "left" then 3373 yplus = -1 3374 end 3375 3376 if portalfacing == "right" then 3377 if (math.floor(y) == portaly or math.floor(y) == portaly-1) and inrange(x, portalx-width, portalx, false) then 3378 return i, j 3379 end 3380 elseif portalfacing == "left" then 3381 if (math.floor(y) == portaly-1 or math.floor(y) == portaly-2) and inrange(x, portalx-1-width, portalx-1, false) then 3382 return i, j 3383 end 3384 elseif portalfacing == "up" then 3385 if inrange(y, portaly-height-1, portaly-1, false) and inrange(x, portalx-1.5-.2, portalx+.5+.2, true) then 3386 return i, j 3387 end 3388 elseif portalfacing == "down" then 3389 if inrange(y, portaly-height, portaly, false) and inrange(x, portalx-2, portalx-.5, true) then 3390 return i, j 3391 end 3392 end 3393 3394 --widen rect by 3 pixels? 3395 3396 end 3397 end 3398 end 3399 3400 return false 3401end 3402 3403function moveoutportal(p0) --pushes objects out of the portal i in. 3404 for i, v in pairs(objects) do 3405 if i ~= "tile" and i ~= "portalwall" then 3406 for j, w in pairs(v) do 3407 if w.active and w.static == false then 3408 local p1, p2 = insideportal(w.x, w.y, w.width, w.height) 3409 3410 if p1 ~= false and p2 == p0 then 3411 local portalfacing, portalx, portaly 3412 if p2 == 1 then 3413 portalfacing = objects["player"][p1].portal1facing 3414 portalx = objects["player"][p1].portal1X 3415 portaly = objects["player"][p1].portal1Y 3416 else 3417 portalfacing = objects["player"][p1].portal2facing 3418 portalx = objects["player"][p1].portal2X 3419 portaly = objects["player"][p1].portal2Y 3420 end 3421 3422 if portalfacing == "right" then 3423 w.x = portalx 3424 elseif portalfacing == "left" then 3425 w.x = portalx - 1 - w.width 3426 elseif portalfacing == "up" then 3427 w.y = portaly - 1 - w.height 3428 elseif portalfacing == "down" then 3429 w.y = portaly 3430 end 3431 end 3432 end 3433 end 3434 end 3435 end 3436end 3437 3438function nextlevel() 3439 love.audio.stop() 3440 mariolevel = mariolevel + 1 3441 if mariolevel > 4 then 3442 mariolevel = 1 3443 marioworld = marioworld + 1 3444 end 3445 levelscreen_load("next") 3446end 3447 3448function warpzone(i) 3449 love.audio.stop() 3450 mariolevel = 1 3451 marioworld = i 3452 mariosublevel = 0 3453 prevsublevel = false 3454 3455 -- minus 1 world glitch just because I can. 3456 if not displaywarpzonetext and i == 4 then 3457 marioworld = "M" 3458 end 3459 3460 levelscreen_load("next") 3461end 3462 3463function game_mousereleased(x, y, button) 3464 if button == "l" then 3465 if playertype == "minecraft" then 3466 breakingblockX = false 3467 end 3468 end 3469 3470 if editormode then 3471 editor_mousereleased(x, y, button) 3472 end 3473end 3474 3475function getMouseTile(x, y) 3476 local xout = math.floor((x+xscroll*16*scale)/(16*scale))+1 3477 local yout = math.floor((y-yoffset*scale)/(16*scale))+1 3478 return xout, yout 3479end 3480 3481function savemap(filename) 3482 local s = "" 3483 for y = 1, 15 do 3484 for x = 1, mapwidth do 3485 if y ~= 15 or x ~= mapwidth then 3486 for i = 1, #map[x][y] do 3487 s = s .. tostring(map[x][y][i]) 3488 if i ~= #map[x][y] then 3489 s = s .. "-" 3490 end 3491 end 3492 s = s .. "," 3493 else 3494 for i = 1, #map[x][y] do 3495 s = s .. tostring(map[x][y][i]) 3496 if i ~= #map[x][y] then 3497 s = s .. "-" 3498 end 3499 end 3500 end 3501 end 3502 end 3503 3504 --options 3505 s = s .. ";background=" .. background 3506 s = s .. ";spriteset=" .. spriteset 3507 s = s .. ";music=" .. musici 3508 if intermission then 3509 s = s .. ";intermission" 3510 end 3511 if bonusstage then 3512 s = s .. ";bonusstage" 3513 end 3514 if haswarpzone then 3515 s = s .. ";haswarpzone" 3516 end 3517 if underwater then 3518 s = s .. ";underwater" 3519 end 3520 if custombackground then 3521 s = s .. ";custombackground" 3522 end 3523 s = s .. ";timelimit=" .. mariotimelimit 3524 s = s .. ";scrollfactor=" .. scrollfactor 3525 3526 --tileset 3527 3528 love.filesystem.mkdir( "mappacks" ) 3529 love.filesystem.mkdir( "mappacks/" .. mappack ) 3530 3531 love.filesystem.write("mappacks/" .. mappack .. "/" .. filename .. ".txt", s) 3532 print("Map saved as " .. "mappacks/" .. filename .. ".txt") 3533end 3534 3535function savelevel() 3536 if mariosublevel == 0 then 3537 savemap(marioworld .. "-" .. mariolevel) 3538 else 3539 savemap(marioworld .. "-" .. mariolevel .. "_" .. mariosublevel) 3540 end 3541end 3542 3543function traceline(sourcex, sourcey, radians) 3544 local currentblock = {} 3545 local x, y = sourcex, sourcey 3546 currentblock[1] = math.floor(x) 3547 currentblock[2] = math.floor(y+1) 3548 3549 local emancecollide = false 3550 for i, v in pairs(emancipationgrills) do 3551 if v:getTileInvolved(currentblock[1]+1, currentblock[2]) then 3552 emancecollide = true 3553 end 3554 end 3555 3556 local doorcollide = false 3557 for i, v in pairs(objects["door"]) do 3558 if v.dir == "hor" then 3559 if v.open == false and (v.cox == currentblock[1] or v.cox == currentblock[1]+1) and v.coy == currentblock[2] then 3560 doorcollide = true 3561 end 3562 else 3563 if v.open == false and v.cox == currentblock[1]+1 and (v.coy == currentblock[2] or v.coy == currentblock[2]+1) then 3564 doorcollide = true 3565 end 3566 end 3567 end 3568 3569 if emancecollide or doorcollide then 3570 return false, false, false, false, x, y 3571 end 3572 3573 local side 3574 3575 while currentblock[1]+1 > 0 and currentblock[1]+1 <= mapwidth and (flagx == false or currentblock[1]+1 <= flagx) and (axex == false or currentblock[1]+1 <= axex) and (currentblock[2] > 0 or currentblock[2] >= math.floor(sourcey+0.5)) and currentblock[2] < 16 do --while in map range 3576 local oldy = y 3577 local oldx = x 3578 3579 --calculate X and Y diff.. 3580 local ydiff, xdiff 3581 local side1, side2 3582 3583 if inrange(radians, -math.pi/2, math.pi/2, true) then --up 3584 ydiff = (y-(currentblock[2]-1)) / math.cos(radians) 3585 y = currentblock[2]-1 3586 side1 = "down" 3587 else 3588 ydiff = (y-(currentblock[2])) / math.cos(radians) 3589 y = currentblock[2] 3590 side1 = "up" 3591 end 3592 3593 if inrange(radians, 0, math.pi, true) then --left 3594 xdiff = (x-(currentblock[1])) / math.sin(radians) 3595 x = currentblock[1] 3596 side2 = "right" 3597 else 3598 xdiff = (x-(currentblock[1]+1)) / math.sin(radians) 3599 x = currentblock[1]+1 3600 side2 = "left" 3601 end 3602 3603 --smaller diff wins 3604 3605 if xdiff < ydiff then 3606 y = oldy - math.cos(radians)*xdiff 3607 side = side2 3608 else 3609 x = oldx - math.sin(radians)*ydiff 3610 side = side1 3611 end 3612 3613 if side == "down" then 3614 currentblock[2] = currentblock[2]-1 3615 elseif side == "up" then 3616 currentblock[2] = currentblock[2]+1 3617 elseif side == "left" then 3618 currentblock[1] = currentblock[1]+1 3619 elseif side == "right" then 3620 currentblock[1] = currentblock[1]-1 3621 end 3622 3623 local collide, tileno = getTile(currentblock[1]+1, currentblock[2]) 3624 local emancecollide = false 3625 for i, v in pairs(emancipationgrills) do 3626 if v:getTileInvolved(currentblock[1]+1, currentblock[2]) then 3627 emancecollide = true 3628 end 3629 end 3630 3631 local doorcollide = false 3632 for i, v in pairs(objects["door"]) do 3633 if v.dir == "hor" then 3634 if v.open == false and (v.cox == currentblock[1] or v.cox == currentblock[1]+1) and v.coy == currentblock[2] then 3635 doorcollide = true 3636 end 3637 else 3638 if v.open == false and v.cox == currentblock[1]+1 and (v.coy == currentblock[2] or v.coy == currentblock[2]+1) then 3639 doorcollide = true 3640 end 3641 end 3642 end 3643 3644 if collide == true then 3645 break 3646 elseif emancecollide or doorcollide then 3647 return false, false, false, false, x, y 3648 elseif x > xscroll + width or x < xscroll then 3649 return false, false, false, false, x, y 3650 end 3651 end 3652 3653 if currentblock[1]+1 > 0 and currentblock[1]+1 <= mapwidth and (currentblock[2] > 0 or currentblock[2] >= math.floor(sourcey+0.5)) and currentblock[2] < 16 and currentblock[1] ~= nil then 3654 local tendency 3655 3656 --get tendency 3657 if side == "down" or side == "up" then 3658 if math.mod(x, 1) > 0.5 then 3659 tendency = 1 3660 else 3661 tendency = -1 3662 end 3663 elseif side == "left" or side == "right" then 3664 if math.mod(y, 1) > 0.5 then 3665 tendency = 1 3666 else 3667 tendency = -1 3668 end 3669 end 3670 3671 return currentblock[1]+1, currentblock[2], side, tendency, x, y 3672 else 3673 return false, false, false, false, x, y 3674 end 3675end 3676 3677function spawnenemy(x, y) 3678 if not inmap(x, y) then 3679 return 3680 end 3681 3682 for i = 1, #enemiesspawned do 3683 if x == enemiesspawned[i][1] and y == enemiesspawned[i][2] then 3684 return 3685 end 3686 end 3687 3688 local t = map[x][y] 3689 if #t > 1 then 3690 local enemy = true 3691 local i = entityquads[t[2]].t 3692 if i == "goomba" then 3693 table.insert(objects["goomba"], goomba:new(x-0.5, y-1/16)) 3694 elseif i == "goombahalf" then 3695 table.insert(objects["goomba"], goomba:new(x, y-1/16)) 3696 elseif i == "koopa" then 3697 table.insert(objects["koopa"], koopa:new(x-0.5, y-1/16)) 3698 elseif i == "koopahalf" then 3699 table.insert(objects["koopa"], koopa:new(x, y-1/16)) 3700 elseif i == "koopared" then 3701 table.insert(objects["koopa"], koopa:new(x-0.5, y-1/16, "red")) 3702 elseif i == "kooparedhalf" then 3703 table.insert(objects["koopa"], koopa:new(x, y-1/16, "red")) 3704 elseif i == "beetle" then 3705 table.insert(objects["koopa"], koopa:new(x-0.5, y-1/16, "beetle")) 3706 elseif i == "beetlehalf" then 3707 table.insert(objects["koopa"], koopa:new(x, y-1/16, "beetle")) 3708 elseif i == "kooparedflying" then 3709 table.insert(objects["koopa"], koopa:new(x-.5, y-1/16, "redflying")) 3710 elseif i == "koopaflying" then 3711 table.insert(objects["koopa"], koopa:new(x-.5, y-1/16, "flying")) 3712 elseif i == "bowser" then 3713 objects["bowser"][1] = bowser:new(x, y-1/16) 3714 elseif i == "cheepred" then 3715 table.insert(objects["cheep"], cheepcheep:new(x-.5, y-1/16, 1)) 3716 elseif i == "cheepwhite" then 3717 table.insert(objects["cheep"], cheepcheep:new(x-.5, y-1/16, 2)) 3718 elseif i == "spikey" then 3719 table.insert(objects["goomba"], goomba:new(x-0.5, y-1/16, "spikey")) 3720 elseif i == "spikeyhalf" then 3721 table.insert(objects["goomba"], goomba:new(x, y-1/16, "spikey")) 3722 elseif i == "lakito" then 3723 table.insert(objects["lakito"], lakito:new(x, y-1/16)) 3724 elseif i == "squid" then 3725 table.insert(objects["squid"], squid:new(x, y-1/16)) 3726 3727 elseif i == "platformup" then 3728 table.insert(objects["platform"], platform:new(x, y, "up", t[3])) --Platform right 3729 elseif i == "platformright" then 3730 table.insert(objects["platform"], platform:new(x, y, "right", t[3])) --Platform up 3731 3732 elseif i == "platformfall" then 3733 table.insert(objects["platform"], platform:new(x, y, "fall", t[3])) --Platform up 3734 3735 elseif i == "platformbonus" then 3736 table.insert(objects["platform"], platform:new(x, y, "justright", 3)) 3737 3738 elseif i == "plant" then 3739 table.insert(objects["plant"], plant:new(x, y)) 3740 3741 elseif i == "castlefirecw" then 3742 table.insert(objects["castlefire"], castlefire:new(x, y, tonumber(t[3]), "cw")) 3743 3744 elseif i == "castlefireccw" then 3745 table.insert(objects["castlefire"], castlefire:new(x, y, tonumber(t[3]), "ccw")) 3746 3747 elseif i == "hammerbro" then 3748 table.insert(objects["hammerbro"], hammerbro:new(x, y)) 3749 3750 elseif i == "whitegeldown" then 3751 table.insert(objects["geldispenser"], geldispenser:new(x, y, 3, "down")) 3752 elseif i == "whitegelright" then 3753 table.insert(objects["geldispenser"], geldispenser:new(x, y, 3, "right")) 3754 elseif i == "whitegelleft" then 3755 table.insert(objects["geldispenser"], geldispenser:new(x, y, 3, "left")) 3756 3757 elseif i == "bulletbill" then 3758 table.insert(rocketlaunchers, rocketlauncher:new(x, y)) 3759 3760 elseif i == "bluegeldown" then 3761 table.insert(objects["geldispenser"], geldispenser:new(x, y, 1, "down")) 3762 elseif i == "bluegelright" then 3763 table.insert(objects["geldispenser"], geldispenser:new(x, y, 1, "right")) 3764 elseif i == "bluegelleft" then 3765 table.insert(objects["geldispenser"], geldispenser:new(x, y, 1, "left")) 3766 3767 elseif i == "orangegeldown" then 3768 table.insert(objects["geldispenser"], geldispenser:new(x, y, 2, "down")) 3769 elseif i == "orangegelright" then 3770 table.insert(objects["geldispenser"], geldispenser:new(x, y, 2, "right")) 3771 elseif i == "orangegelleft" then 3772 table.insert(objects["geldispenser"], geldispenser:new(x, y, 2, "left")) 3773 3774 elseif i == "upfire" then 3775 table.insert(objects["upfire"], upfire:new(x, y)) 3776 else 3777 3778 enemy = false 3779 end 3780 3781 if enemy then 3782 table.insert(enemiesspawned, {x, y}) 3783 3784 --spawn enemies in 5x1 line so they spawn as a unit and not alone. 3785 spawnenemy(x-2, y) 3786 spawnenemy(x-1, y) 3787 spawnenemy(x+1, y) 3788 spawnenemy(x+2, y) 3789 end 3790 end 3791end 3792 3793function item(i, x, y, size) 3794 if i == "mushroom" then 3795 if size and size > 1 then 3796 table.insert(objects["flower"], flower:new(x-0.5, y-2/16)) 3797 else 3798 table.insert(objects["mushroom"], mushroom:new(x-0.5, y-2/16)) 3799 end 3800 3801 elseif i == "oneup" then 3802 table.insert(objects["oneup"], oneup:new(x-0.5, y-2/16)) 3803 elseif i == "star" then 3804 table.insert(objects["star"], star:new(x-0.5, y-2/16)) 3805 elseif i == "vine" then 3806 table.insert(objects["vine"], vine:new(x, y)) 3807 end 3808end 3809 3810function addpoints(i, x, y) 3811 if i > 0 then 3812 marioscore = marioscore + i 3813 if x ~= nil and y ~= nil then 3814 table.insert(scrollingscores, scrollingscore:new(i, x, y)) 3815 end 3816 else 3817 table.insert(scrollingscores, scrollingscore:new(-i, x, y)) 3818 end 3819end 3820 3821function addzeros(s, i) 3822 for j = string.len(s)+1, i do 3823 s = "0" .. s 3824 end 3825 return s 3826end 3827 3828function properprint2(s, x, y) 3829 for i = 1, string.len(tostring(s)) do 3830 if fontquads[string.sub(s, i, i)] then 3831 love.graphics.drawq(fontimage2, font2quads[string.sub(s, i, i)], x+((i-1)*4)*scale, y, 0, scale, scale) 3832 end 3833 end 3834end 3835 3836function playsound(sound) 3837 if soundenabled then 3838 sound:stop() 3839 sound:rewind() 3840 sound:play() 3841 end 3842end 3843 3844function runkey(i) 3845 local s = controls[i]["run"] 3846 return checkkey(s) 3847end 3848 3849function rightkey(i) 3850 local s = controls[i]["right"] 3851 return checkkey(s) 3852end 3853 3854function leftkey(i) 3855 local s = controls[i]["left"] 3856 return checkkey(s) 3857end 3858 3859function downkey(i) 3860 local s = controls[i]["down"] 3861 return checkkey(s) 3862end 3863 3864function upkey(i) 3865 local s = controls[i]["up"] 3866 return checkkey(s) 3867end 3868 3869function checkkey(s) 3870 if s[1] == "joy" then 3871 if s[3] == "hat" then 3872 if love.joystick.getHat(s[2], s[4]) == s[5] then 3873 return true 3874 else 3875 return false 3876 end 3877 elseif s[3] == "but" then 3878 if love.joystick.isDown(s[2], s[4]) then 3879 return true 3880 else 3881 return false 3882 end 3883 elseif s[3] == "axe" then 3884 if s[5] == "pos" then 3885 if love.joystick.getAxis(s[2], s[4]) > joystickdeadzone then 3886 return true 3887 else 3888 return false 3889 end 3890 else 3891 if love.joystick.getAxis(s[2], s[4]) < -joystickdeadzone then 3892 return true 3893 else 3894 return false 3895 end 3896 end 3897 end 3898 else 3899 if love.keyboard.isDown(s[1]) then 3900 return true 3901 else 3902 return false 3903 end 3904 end 3905end 3906 3907function game_joystickpressed( joystick, button ) 3908 if pausemenuopen then 3909 return 3910 end 3911 if endpressbutton then 3912 endgame() 3913 return 3914 end 3915 3916 for i = 1, players do 3917 if not noupdate and objects["player"][i].controlsenabled and not objects["player"][i].vine then 3918 local s1 = controls[i]["jump"] 3919 local s2 = controls[i]["run"] 3920 local s3 = controls[i]["reload"] 3921 local s4 = controls[i]["use"] 3922 local s5 = controls[i]["left"] 3923 local s6 = controls[i]["right"] 3924 if s1[1] == "joy" and joystick == tonumber(s1[2]) and s1[3] == "but" and button == tonumber(s1[4]) then 3925 objects["player"][i]:jump() 3926 return 3927 elseif s2[1] == "joy" and joystick == s2[2] and s2[3] == "but" and button == s2[4] then 3928 objects["player"][i]:fire() 3929 return 3930 elseif s3[1] == "joy" and joystick == s3[2] and s3[3] == "but" and button == s3[4] then 3931 objects["player"][i]:removeportals() 3932 return 3933 elseif s4[1] == "joy" and joystick == s4[2] and s4[3] == "but" and button == s4[4] then 3934 objects["player"][i]:use() 3935 return 3936 elseif s5[1] == "joy" and joystick == s5[2] and s5[3] == "but" and button == s5[4] then 3937 objects["player"][i]:leftkey() 3938 return 3939 elseif s6[1] == "joy" and joystick == s6[2] and s6[3] == "but" and button == s6[4] then 3940 objects["player"][i]:rightkey() 3941 return 3942 end 3943 3944 local s = controls[i]["portal1"] 3945 if s and s[1] == "joy" then 3946 if s[3] == "but" then 3947 if joystick == s[2] and button == s[4] then 3948 shootportal(i, 1, objects["player"][i].x+6/16, objects["player"][i].y+6/16, objects["player"][i].pointingangle) 3949 return 3950 end 3951 end 3952 end 3953 3954 local s = controls[i]["portal2"] 3955 if s and s[1] == "joy" then 3956 if s[3] == "but" then 3957 if joystick == tonumber(s[2]) and button == tonumber(s[4]) then 3958 shootportal(i, 2, objects["player"][i].x+6/16, objects["player"][i].y+6/16, objects["player"][i].pointingangle) 3959 return 3960 end 3961 end 3962 end 3963 end 3964 end 3965end 3966 3967function game_joystickreleased( joystick, button ) 3968 for i = 1, players do 3969 local s = controls[i]["jump"] 3970 if s[1] == "joy" then 3971 if s[3] == "but" then 3972 if joystick == tonumber(s[2]) and button == tonumber(s[4]) then 3973 objects["player"][i]:stopjump() 3974 return 3975 end 3976 end 3977 end 3978 end 3979end 3980 3981function inrange(i, a, b, include) 3982 if a > b then 3983 b, a = a, b 3984 end 3985 3986 if include then 3987 if i >= a and i <= b then 3988 return true 3989 else 3990 return false 3991 end 3992 else 3993 if i > a and i < b then 3994 return true 3995 else 3996 return false 3997 end 3998 end 3999end 4000 4001function adduserect(x, y, width, height, callback) 4002 local t = {} 4003 t.x = x 4004 t.y = y 4005 t.width = width 4006 t.height = height 4007 t.callback = callback 4008 t.delete = false 4009 4010 table.insert(userects, t) 4011 return t 4012end 4013 4014function userect(x, y, width, height) 4015 local outtable = {} 4016 4017 for i, v in pairs(userects) do 4018 if aabb(x, y, width, height, v.x, v.y, v.width, v.height) then 4019 table.insert(outtable, v.callback) 4020 end 4021 end 4022 4023 return outtable 4024end 4025 4026function drawrectangle(x, y, width, height) 4027 love.graphics.rectangle("fill", x*scale, y*scale, width*scale, scale) 4028 love.graphics.rectangle("fill", x*scale, y*scale, scale, height*scale) 4029 love.graphics.rectangle("fill", x*scale, (y+height-1)*scale, width*scale, scale) 4030 love.graphics.rectangle("fill", (x+width-1)*scale, y*scale, scale, height*scale) 4031end 4032 4033function inmap(x, y) 4034 if not x or not y then 4035 return false 4036 end 4037 if x >= 1 and x <= mapwidth and y >= 1 and y <= 15 then 4038 return true 4039 else 4040 return false 4041 end 4042end 4043 4044function playmusic() 4045 if musici == 7 and custommusic then 4046 music:play(custommusic) 4047 elseif musici ~= 1 then 4048 if mariotime < 100 and mariotime > 0 then 4049 music:playIndex(musici-1, true) 4050 else 4051 music:playIndex(musici-1) 4052 end 4053 end 4054end 4055 4056function stopmusic() 4057 if musici ~= 1 then 4058 if mariotime < 100 and mariotime > 0 then 4059 music:stopIndex(musici-1, true) 4060 else 4061 music:stopIndex(musici-1) 4062 end 4063 end 4064end 4065 4066function updatesizes() 4067 mariosizes = {} 4068 if not objects then 4069 for i = 1, players do 4070 mariosizes[i] = 1 4071 end 4072 else 4073 for i = 1, players do 4074 mariosizes[i] = objects["player"][i].size 4075 end 4076 end 4077end 4078 4079function hitrightside() 4080 if haswarpzone then 4081 objects["plant"] = {} 4082 displaywarpzonetext = true 4083 end 4084end 4085 4086function getclosestplayer(x) 4087 closestplayer = 1 4088 for i = 2, players do 4089 if math.abs(objects["player"][closestplayer].x+6/16-x) < math.abs(objects["player"][i].x+6/16-x) then 4090 closestplayer = i 4091 end 4092 end 4093 4094 return closestplayer 4095end 4096 4097function endgame() 4098 love.audio.stop() 4099 playertype = "minecraft" 4100 playertypei = 2 4101 gamefinished = true 4102 saveconfig() 4103 menu_load() 4104end 4105 4106--Minecraft stuff 4107 4108function placeblock(x, y, side) 4109 if side == "up" then 4110 y = y - 1 4111 elseif side == "down" then 4112 y = y + 1 4113 elseif side == "left" then 4114 x = x - 1 4115 elseif side == "right" then 4116 x = x + 1 4117 end 4118 4119 if not inmap(x, y) then 4120 return false 4121 end 4122 4123 --get block 4124 local tileno 4125 if inventory[mccurrentblock].t ~= nil then 4126 tileno = inventory[mccurrentblock].t 4127 else 4128 return false 4129 end 4130 4131 if #checkrect(x-1, y-1, 1, 1, "all") == 0 then 4132 map[x][y][1] = tileno 4133 objects["tile"][x .. "-" .. y] = tile:new(x-1, y-1, 1, 1, true) 4134 generatespritebatch() 4135 4136 inventory[mccurrentblock].count = inventory[mccurrentblock].count - 1 4137 4138 if inventory[mccurrentblock].count == 0 then 4139 inventory[mccurrentblock].t = nil 4140 end 4141 4142 return true 4143 else 4144 return false 4145 end 4146end 4147 4148function collectblock(i) 4149 local success = false 4150 for j = 1, 9 do 4151 if inventory[j].t == i and inventory[j].count < 64 then 4152 inventory[j].count = inventory[j].count+1 4153 success = true 4154 break 4155 end 4156 end 4157 4158 if not success then 4159 for j = 1, 9 do 4160 if inventory[j].t == nil then 4161 inventory[j].count = 1 4162 inventory[j].t = i 4163 success = true 4164 break 4165 end 4166 end 4167 end 4168 4169 return success 4170end 4171 4172function breakblock(x, y) 4173 --create a cute block 4174 table.insert(miniblocks, miniblock:new(x-.5, y-.2, map[x][y][1])) 4175 4176 map[x][y][1] = 1 4177 map[x][y]["gels"] = {} 4178 objects["tile"][x .. "-" .. y] = nil 4179 4180 generatespritebatch() 4181end 4182 4183function respawnplayers() 4184 if mariolivecount == false then 4185 return 4186 end 4187 for i = 1, players do 4188 if mariolives[i] == 1 and objects["player"].dead then 4189 objects["player"][i]:respawn() 4190 end 4191 end 4192end 4193