1mario = class:new() 2 3function mario:init(x, y, i, animation, size, t) 4 self.playernumber = i or 1 5 if bigmario then 6 self.size = 1 7 else 8 self.size = size or 1 9 end 10 self.t = t or "portal" 11 12 --PHYSICS STUFF 13 self.speedx = 0 14 self.speedy = 0 15 self.x = x 16 self.width = 12/16 17 self.height = 12/16 18 19 if bigmario then 20 self.width = self.width*scalefactor 21 self.height = self.height*scalefactor 22 end 23 24 self.y = y+1-self.height 25 self.static = false 26 self.active = true 27 self.category = 3 28 self.mask = { true, 29 false, true, false, false, false, 30 false, true, false, false, false, 31 false, true, false, false, false, 32 false, false, false, false, false, 33 false, false, false, false, false, 34 false, false, false, false, false} 35 36 if playercollisions then 37 self.mask[3] = false 38 end 39 40 self.emancipatecheck = true 41 42 --IMAGE STUFF 43 self.smallgraphic = {} 44 if playertype == "minecraft" then 45 for j = 0, 3 do 46 self.smallgraphic[j] = minecraftanimations[j] 47 end 48 else 49 for j = 0, 3 do 50 self.smallgraphic[j] = marioanimations[j] 51 end 52 end 53 54 self.biggraphic = {} 55 if playertype == "minecraft" then 56 for j = 0, 3 do 57 self.biggraphic[j] = bigminecraftanimations[j] 58 end 59 else 60 for j = 0, 3 do 61 self.biggraphic[j] = bigmarioanimations[j] 62 end 63 end 64 65 self.drawable = true 66 self.quad = marioidle[3] 67 self.colors = mariocolors[self.playernumber] 68 if self.size == 1 then 69 self.offsetX = 6 70 self.offsetY = 3 71 self.quadcenterX = 11 72 self.quadcenterY = 10 73 74 self.graphic = self.smallgraphic 75 else 76 self.graphic = self.biggraphic 77 78 self.quadcenterY = 20 79 self.quadcenterX = 9 80 self.offsetY = -3 81 self.offsetX = 6 82 83 self.y = self.y - 12/16 84 self.height = 24/16 85 86 if self.size == 3 then 87 self.colors = flowercolor 88 end 89 end 90 91 if bigmario then 92 self.offsetX = self.offsetX*scalefactor 93 self.offsetY = self.offsetY*-scalefactor 94 end 95 96 --hat 97 self.hats = mariohats[self.playernumber] 98 self.drawhat = true 99 100 --Change height according to hats 101 102 --for i = 1, #self.hats do 103 --self.height = self.height + (hat[self.hats[i]].height/16) 104 --self.y = self.y - (hat[self.hats[i]].height/16) 105 --self.offsetY = self.offsetY - hat[self.hats[i]].height 106 --end 107 108 self.customscissor = nil 109 110 111 if players == 1 then 112 self.portal1color = {60, 188, 252} 113 self.portal2color = {232, 130, 30} 114 else 115 self.portal1color = portalcolor[self.playernumber][1] 116 self.portal2color = portalcolor[self.playernumber][2] 117 end 118 119 --OTHER STUFF! 120 self.controlsenabled = true 121 122 self.runframe = 3 123 self.swimframe = 1 124 self.climbframe = 1 125 self.runanimationprogress = 1 126 self.swimanimationprogress = 1 127 self.animationstate = "idle" --idle, running, jumping, falling, swimming, sliding, climbing, dead 128 self.animationdirection = "right" --left, right. duh 129 self.platform = false 130 self.combo = 1 131 self.portal1X = false 132 self.portal1Y = false 133 self.portal2X = false 134 self.portal2Y = false 135 self.portal1facing = nil 136 self.portal2facing = nil 137 self.rotation = 0 --for portals 138 self.portaldotstimer = 0 139 self.pointingangle = -math.pi/2 140 self.passivemoved = false 141 self.ducking = false 142 self.invincible = false 143 self.rainboomallowed = true 144 145 self.animation = animation --pipedown, piperight, pipeup, flag, vine, intermission 146 self.animationx = nil 147 self.animationy = nil 148 self.animationtimer = 0 149 150 self.falling = false 151 self.jumping = false 152 self.starred = false 153 self.dead = false 154 self.vine = false 155 self.spring = false 156 self.startimer = mariostarduration 157 self.starblinktimer = mariostarblinkrate 158 self.starcolori = 1 159 self.fireballcount = 0 160 self.fireanimationtimer = fireanimationtime 161 162 self.mazevar = 0 163 164 self.bubbletimer = 0 165 self.bubbletime = bubblestime[math.random(#bubblestime)] 166 167 if underwater then 168 self.gravity = uwgravity 169 end 170 171 self.controlsoverwrite = {} 172 173 if self.animation == "intermission" and editormode then 174 self.animation = nil 175 end 176 177 if mariolivecount ~= false and mariolives[self.playernumber] <= 0 then 178 self.dead = true 179 self.drawable = false 180 self.active = false 181 self.static = true 182 self.controlsenabled = false 183 self.animation = nil 184 end 185 186 if self.animation == "pipeup" then 187 self.controlsenabled = false 188 self.active = false 189 self.animationx = x 190 self.animationy = y 191 self.customscissor = {x-2.5, y-4, 6, 4} 192 self.y = self.animationy + 20/16 193 194 self.animationstate = "idle" 195 self:setquad() 196 197 if self.size > 1 then 198 self.animationy = y - 12/16 199 end 200 elseif self.animation == "intermission" then 201 self.controlsenabled = false 202 self.active = true 203 self.gravity = mariogravity 204 self.animationstate = "running" 205 self.speedx = 2.61 206 self.pointingangle = -math.pi/2 207 elseif self.animation == "vinestart" then 208 self.controlsenabled = false 209 self.active = false 210 self.pointingangle = -math.pi/2 211 self.climbframe = 2 212 self.animationstate = "climbing" 213 self:setquad() 214 self.x = 4-3/16 215 self.y = 15+0.4*(self.playernumber-1) 216 self.vineanimationclimb = false 217 self.vineanimationdropoff = false 218 self.vinemovetimer = 0 219 playsound(vinesound) 220 221 if #objects["vine"] == 0 then 222 table.insert(objects["vine"], vine:new(5, 16, "start")) 223 end 224 end 225 226 self:setquad() 227end 228 229function mario:update(dt) 230 self.passivemoved = false 231 --rotate back to 0 (portals) 232 self.rotation = math.mod(self.rotation, math.pi*2) 233 234 if self.rotation < -math.pi then 235 self.rotation = self.rotation + math.pi*2 236 elseif self.rotation > math.pi then 237 self.rotation = self.rotation - math.pi*2 238 end 239 240 if self.rotation > 0 then 241 self.rotation = self.rotation - portalrotationalignmentspeed*dt 242 if self.rotation < 0 then 243 self.rotation = 0 244 end 245 elseif self.rotation < 0 then 246 self.rotation = self.rotation + portalrotationalignmentspeed*dt 247 if self.rotation > 0 then 248 self.rotation = 0 249 end 250 end 251 252 if self.startimer < mariostarduration and not self.dead then 253 self.startimer = self.startimer + dt 254 self.starblinktimer = self.starblinktimer + dt 255 256 local lmariostarblinkrate = mariostarblinkrate 257 if self.startimer >= mariostarduration-mariostarrunout then 258 lmariostarblinkrate = mariostarblinkrateslow 259 end 260 261 while self.starblinktimer > lmariostarblinkrate do 262 self.starcolori = self.starcolori + 1 263 if self.starcolori > 4 then 264 self.starcolori = self.starcolori - 4 265 end 266 self.colors = starcolors[self.starcolori] 267 268 self.starblinktimer = self.starblinktimer - lmariostarblinkrate 269 end 270 271 if self.startimer >= mariostarduration-mariostarrunout and self.startimer-dt < mariostarduration-mariostarrunout then 272 --check if another starman is playing 273 local starstill = false 274 for i = 1, players do 275 if i ~= self.playernumber and objects["player"][i].starred then 276 starstill = true 277 end 278 end 279 280 if not starstill and not levelfinished then 281 playmusic() 282 music:stop("starmusic") 283 end 284 end 285 286 if self.startimer >= mariostarduration then 287 if self.size == 3 then --flower colors 288 self.colors = flowercolor 289 else 290 self.colors = mariocolors[self.playernumber] 291 end 292 self.starred = false 293 self.startimer = mariostarduration 294 end 295 end 296 297 --ANIMATIONS 298 if self.animation == "pipedown" then 299 self.animationtimer = self.animationtimer + dt 300 if self.animationtimer < pipeanimationtime then 301 self.y = self.animationy - 28/16 + self.animationtimer/pipeanimationtime*pipeanimationdistancedown 302 else 303 self.y = self.animationy - 28/16 + pipeanimationdistancedown 304 305 if self.animationtimer >= pipeanimationtime+pipeanimationdelay then 306 updatesizes() 307 if type(self.animationmisc) == "number" then --sublevel 308 levelscreen_load("sublevel", self.animationmisc) 309 else --warpzone 310 warpzone(tonumber(string.sub(self.animationmisc, 5, 5))) 311 end 312 end 313 end 314 return 315 elseif self.animation == "pipeup" then 316 self.animationtimer = self.animationtimer + dt 317 if self.animationtimer < pipeupdelay then 318 319 elseif self.animationtimer < pipeanimationtime+pipeupdelay then 320 self.y = self.animationy + 20/16 - (self.animationtimer-pipeupdelay)/pipeanimationtime*pipeanimationdistancedown 321 else 322 self.y = self.animationy + 20/16 - pipeanimationdistancedown 323 324 if self.animationtimer >= pipeanimationtime then 325 self.active = true 326 self.controlsenabled = true 327 self.animation = nil 328 self.customscissor = nil 329 end 330 end 331 return 332 elseif self.animation == "piperight" then 333 self.animationtimer = self.animationtimer + dt 334 if self.animationtimer < pipeanimationtime then 335 self.x = self.animationx - 28/16 + self.animationtimer/pipeanimationtime*pipeanimationdistanceright 336 337 --Run animation 338 if self.animationstate == "running" then 339 self.runanimationprogress = self.runanimationprogress + (math.abs(pipeanimationrunspeed)+4)/5*dt*7 340 while self.runanimationprogress >= 4 do 341 self.runanimationprogress = self.runanimationprogress - 3 342 end 343 self.runframe = math.floor(self.runanimationprogress) 344 self:setquad() 345 end 346 else 347 self.x = self.animationx - 28/16 + pipeanimationdistanceright 348 349 if self.animationtimer >= pipeanimationtime+pipeanimationdelay then 350 updatesizes() 351 if type(self.animationmisc) == "number" then --sublevel 352 levelscreen_load("sublevel", self.animationmisc) 353 else --warpzone 354 warpzone(tonumber(string.sub(self.animationmisc, 5, 5))) 355 end 356 end 357 end 358 return 359 elseif self.animation == "flag" then 360 if self.animationtimer < flagdescendtime then 361 flagimgy = 49/16 + flagydistance * (self.animationtimer/flagdescendtime) 362 self.y = self.y + flagydistance/flagdescendtime * dt 363 364 self.animationtimer = self.animationtimer + dt 365 366 if self.y > 68/16 + flagydistance-self.height then 367 self.y = 68/16 + flagydistance-self.height 368 self.climbframe = 2 369 else 370 if math.mod(self.animationtimer, flagclimbframedelay*2) >= flagclimbframedelay then 371 self.climbframe = 1 372 else 373 self.climbframe = 2 374 end 375 end 376 377 self.animationstate = "climbing" 378 self:setquad() 379 380 if self.animationtimer >= flagdescendtime then 381 flagimgy = 49/16 + flagydistance 382 self.pointingangle = math.pi/2 383 self.x = flagx + 6/16 384 end 385 return 386 elseif self.animationtimer < flagdescendtime+flaganimationdelay then 387 self.animationtimer = self.animationtimer + dt 388 389 if self.animationtimer >= flagdescendtime+flaganimationdelay then 390 self.active = true 391 self.gravity = mariogravity 392 self.animationstate = "running" 393 self.speedx = 4.27 394 self.pointingangle = -math.pi/2 395 end 396 else 397 self.animationtimer = self.animationtimer + dt 398 end 399 400 local add = 6 401 402 if self.x >= flagx + add and self.active then 403 self.drawable = false 404 self.active = false 405 if mariotime > 0 then 406 playsound(scoreringsound) 407 subtractscore = true 408 subtracttimer = 0 409 else 410 castleflagmove = true 411 end 412 end 413 414 if subtractscore == true and mariotime >= 0 then 415 subtracttimer = subtracttimer + dt 416 while subtracttimer > scoresubtractspeed do 417 subtracttimer = subtracttimer - scoresubtractspeed 418 if mariotime > 0 then 419 mariotime = math.ceil(mariotime - 1) 420 marioscore = marioscore + 50 421 end 422 423 if mariotime <= 0 then 424 subtractscore = false 425 scoreringsound:stop() 426 castleflagmove = true 427 mariotime = 0 428 end 429 end 430 end 431 432 if castleflagmove then 433 if self.animationtimer < castlemintime then 434 castleflagtime = self.animationtimer 435 return 436 end 437 castleflagy = castleflagy - castleflagspeed*dt 438 439 if castleflagy <= 0 then 440 castleflagy = 0 441 castleflagmove = false 442 firework = true 443 castleflagtime = self.animationtimer 444 end 445 end 446 447 if firework then 448 local timedelta = self.animationtimer - castleflagtime 449 for i = 1, fireworkcount do 450 local fireworktime = i*fireworkdelay 451 if timedelta >= fireworktime and timedelta - dt < fireworktime then 452 table.insert(fireworks, fireworkboom:new(flagx+6)) 453 end 454 end 455 456 if timedelta > fireworkcount*fireworkdelay+endtime then 457 nextlevel() 458 return 459 end 460 end 461 462 --500 points per firework, appear at 1 3 and 6 (Who came up with this?) 463 464 --Run animation 465 if self.animationstate == "running" then 466 self.runanimationprogress = self.runanimationprogress + (math.abs(self.speedx)+4)/5*dt*runanimationspeed 467 while self.runanimationprogress >= 4 do 468 self.runanimationprogress = self.runanimationprogress - 3 469 end 470 self.runframe = math.floor(self.runanimationprogress) 471 472 self:setquad() 473 end 474 return 475 476 elseif self.animation == "axe" then 477 self.animationtimer = self.animationtimer + dt 478 479 if not bowserfall and self.animationtimer - dt < castleanimationchaindisappear and self.animationtimer >= castleanimationchaindisappear then 480 bridgedisappear = true 481 end 482 483 if bridgedisappear then 484 local v = objects["bowser"][1] 485 if v then 486 v.walkframe = round(math.mod(self.animationtimer, castleanimationbowserframedelay*2)*(1/(castleanimationbowserframedelay*2)))+1 487 end 488 self.animationtimer2 = self.animationtimer2 + dt 489 while self.animationtimer2 > castleanimationbridgedisappeardelay do 490 self.animationtimer2 = self.animationtimer2 - castleanimationbridgedisappeardelay 491 if inmap(self.animationbridgex, self.animationbridgey) and map[self.animationbridgex][self.animationbridgey][1] == 11 then 492 map[self.animationbridgex][self.animationbridgey][1] = 1 493 objects["tile"][self.animationbridgex .. "-" .. self.animationbridgey] = nil 494 if map[self.animationbridgex][self.animationbridgey-1][1] == 10 then 495 map[self.animationbridgex][self.animationbridgey-1][1] = 1 496 end 497 generatespritebatch() 498 playsound(bridgebreaksound) 499 self.animationbridgex = self.animationbridgex - 1 500 else 501 bowserfall = true 502 bridgedisappear = false 503 end 504 end 505 end 506 507 if bowserfall then 508 local v = objects["bowser"][1] 509 if v and not v.fall then 510 v.fall = true 511 v.speedx = 0 512 v.speedy = 0 513 v.active = true 514 v.gravity = 27.5 515 playsound(bowserfallsound) 516 self.animationtimer = 0 517 return 518 end 519 end 520 521 if bowserfall and self.animationtimer - dt < castleanimationmariomove and self.animationtimer >= castleanimationmariomove then 522 self.active = true 523 self.gravity = mariogravity 524 self.animationstate = "running" 525 self.speedx = 4.27 526 self.pointingangle = -math.pi/2 527 528 love.audio.stop() 529 playsound(castleendsound) 530 end 531 532 if self.speedx > 0 and self.x >= mapwidth - 8 then 533 self.x = mapwidth - 8 534 self.animationstate = "idle" 535 self:setquad() 536 self.speedx = 0 537 end 538 539 if levelfinishedmisc2 == 1 then 540 if self.animationtimer - dt < castleanimationtextfirstline and self.animationtimer >= castleanimationtextfirstline then 541 levelfinishedmisc = 1 542 end 543 544 if self.animationtimer - dt < castleanimationtextsecondline and self.animationtimer >= castleanimationtextsecondline then 545 levelfinishedmisc = 2 546 end 547 548 if self.animationtimer - dt < castleanimationnextlevel and self.animationtimer >= castleanimationnextlevel then 549 nextlevel() 550 end 551 else 552 if self.animationtimer - dt < endanimationtextfirstline and self.animationtimer >= endanimationtextfirstline then 553 levelfinishedmisc = 1 554 end 555 556 if self.animationtimer - dt < endanimationtextsecondline and self.animationtimer >= endanimationtextsecondline then 557 levelfinishedmisc = 2 558 love.audio.stop() 559 music:play("princessmusic") 560 end 561 562 if self.animationtimer - dt < endanimationtextthirdline and self.animationtimer >= endanimationtextthirdline then 563 levelfinishedmisc = 3 564 end 565 566 if self.animationtimer - dt < endanimationtextfourthline and self.animationtimer >= endanimationtextfourthline then 567 levelfinishedmisc = 4 568 end 569 570 if self.animationtimer - dt < endanimationtextfifthline and self.animationtimer >= endanimationtextfifthline then 571 levelfinishedmisc = 5 572 end 573 574 if self.animationtimer - dt < endanimationend and self.animationtimer >= endanimationend then 575 endpressbutton = true 576 end 577 end 578 579 --Run animation 580 if self.animationstate == "running" and self.animationtimer >= castleanimationmariomove then 581 self.runanimationprogress = self.runanimationprogress + (math.abs(self.speedx)+4)/5*dt*runanimationspeed 582 while self.runanimationprogress >= 4 do 583 self.runanimationprogress = self.runanimationprogress - 3 584 end 585 self.runframe = math.floor(self.runanimationprogress) 586 587 self:setquad() 588 end 589 return 590 591 elseif self.animation == "death" or self.animation == "deathpit" then 592 self.animationtimer = self.animationtimer + dt 593 self.animationstate = "dead" 594 self:setquad() 595 596 if self.animation == "death" then 597 if self.animationtimer > deathanimationjumptime then 598 if self.animationtimer - dt < deathanimationjumptime then 599 self.speedy = -deathanimationjumpforce 600 end 601 self.speedy = self.speedy + deathgravity*dt 602 self.y = self.y + self.speedy*dt 603 end 604 end 605 606 if self.animationtimer > deathtotaltime then 607 if self.animationmisc == "everyonedead" then 608 levelscreen_load("death") 609 elseif not everyonedead then 610 self:respawn() 611 end 612 end 613 614 return 615 elseif self.animation == "intermission" then 616 --Run animation 617 if self.animationstate == "running" then 618 self.runanimationprogress = self.runanimationprogress + (math.abs(pipeanimationrunspeed)+4)/5*dt*7 619 while self.runanimationprogress >= 4 do 620 self.runanimationprogress = self.runanimationprogress - 3 621 end 622 self.runframe = math.floor(self.runanimationprogress) 623 self:setquad() 624 end 625 626 return 627 628 elseif self.animation == "vine" then 629 self.y = self.y - vinemovespeed*dt 630 631 self.vinemovetimer = self.vinemovetimer + dt 632 633 self.climbframe = math.ceil(math.mod(self.vinemovetimer, vineframedelay*2)/vineframedelay) 634 self.climbframe = math.max(self.climbframe, 1) 635 self:setquad() 636 637 if self.y < -4 then 638 levelscreen_load("vine", self.animationmisc) 639 end 640 return 641 elseif self.animation == "vinestart" then 642 self.animationtimer = self.animationtimer + dt 643 if self.vineanimationdropoff == false and self.animationtimer - dt <= vineanimationmariostart and self.animationtimer > vineanimationmariostart then 644 self.vineanimationclimb = true 645 end 646 647 if self.vineanimationclimb then 648 self.vinemovetimer = self.vinemovetimer + dt 649 650 self.climbframe = math.ceil(math.mod(self.vinemovetimer, vineframedelay*2)/vineframedelay) 651 self.climbframe = math.max(self.climbframe, 1) 652 653 self.y = self.y - vinemovespeed*dt 654 if self.y <= 15-vineanimationgrowheight+vineanimationstop+0.4*(self.playernumber-1) then 655 self.vineanimationclimb = false 656 self.vineanimationdropoff = true 657 self.animationtimer = 0 658 self.y = 15-vineanimationgrowheight+vineanimationstop+0.4*(self.playernumber-1) 659 self.climbframe = 2 660 self.pointingangle = math.pi/2 661 self.x = self.x+9/16 662 end 663 self:setquad() 664 end 665 666 if self.vineanimationdropoff and self.animationtimer - dt <= vineanimationdropdelay and self.animationtimer > vineanimationdropdelay then 667 self.active = true 668 self.controlsenabled = true 669 self.x = self.x + 7/16 670 self.animation = false 671 end 672 673 return 674 675 elseif self.animation == "shrink" then 676 self.animationtimer = self.animationtimer + dt 677 --set frame lol 678 local frame = math.ceil(math.mod(self.animationtimer, growframedelay*3)/shrinkframedelay) 679 self:updateangle() 680 681 if frame == 1 then 682 self.graphic = self.biggraphic 683 self:setquad("idle", 2) 684 self.quadcenterY = 32 685 self.quadcenterX = 9 686 self.offsetY = -3 687 self.animationstate = "idle" 688 else 689 self.graphic = self.smallgraphic 690 self.quadcenterX = 11 691 self.offsetY = 3 692 if frame == 2 then 693 self.animationstate = "grow" 694 self:setquad("grow") 695 self.quadcenterY = 16 696 else 697 self.animationstate = "idle" 698 self:setquad() 699 self.quadcenterY = 10 700 end 701 end 702 703 local invis = math.ceil(math.mod(self.animationtimer, invicibleblinktime*2)/invicibleblinktime) 704 705 if invis == 1 then 706 self.drawable = true 707 else 708 self.drawable = false 709 end 710 711 if self.animationtimer - dt < shrinktime and self.animationtimer > shrinktime then 712 self.animationstate = self.animationmisc 713 self.animation = "invincible" 714 self.invincible = true 715 noupdate = false 716 self.quadcenterY = 10 717 self.graphic = self.smallgraphic 718 self.animationtimer = 0 719 self.quadcenterX = 11 720 self.offsetY = 3 721 self.drawable = true 722 end 723 return 724 elseif self.animation == "invincible" then 725 self.animationtimer = self.animationtimer + dt 726 727 local invis = math.ceil(math.mod(self.animationtimer, invicibleblinktime*2)/invicibleblinktime) 728 729 if invis == 1 then 730 self.drawable = true 731 else 732 self.drawable = false 733 end 734 735 if self.animationtimer - dt < invincibletime and self.animationtimer > invincibletime then 736 self.animation = false 737 self.invincible = false 738 self.drawable = true 739 end 740 741 elseif self.animation == "grow1" then 742 self.animationtimer = self.animationtimer + dt 743 --set frame lol 744 local frame = math.ceil(math.mod(self.animationtimer, growframedelay*3)/growframedelay) 745 self:updateangle() 746 747 if frame == 3 then 748 self.animationstate = "idle" 749 self.graphic = self.biggraphic 750 self:setquad("idle") 751 self.quadcenterY = 20 752 self.quadcenterX = 9 753 self.offsetY = -3 754 else 755 self.graphic = self.smallgraphic 756 self.quadcenterX = 11 757 self.offsetY = 3 758 if frame == 2 then 759 self.animationstate = "grow" 760 self:setquad("grow", 1) 761 self.quadcenterY = 4 762 else 763 self.animationstate = "idle" 764 self:setquad(nil, 1) 765 self.quadcenterY = -2 766 end 767 end 768 769 if self.animationtimer - dt < growtime and self.animationtimer > growtime then 770 self.animationstate = self.animationmisc 771 self.animation = false 772 noupdate = false 773 self.quadcenterY = 20 774 self.graphic = self.biggraphic 775 self.animationtimer = 0 776 self.quadcenterX = 9 777 self.offsetY = -3 778 end 779 return 780 781 elseif self.animation == "grow2" then 782 self.animationtimer = self.animationtimer + dt 783 --set frame lol 784 local frame = math.ceil(math.mod(self.animationtimer, growframedelay*3)/growframedelay) 785 self:updateangle() 786 787 self.colors = starcolors[frame] 788 789 if self.animationtimer - dt < growtime and self.animationtimer > growtime then 790 self.animation = false 791 noupdate = false 792 self.animationtimer = 0 793 end 794 return 795 end 796 797 if noupdate then 798 return 799 end 800 801 if self.fireanimationtimer < fireanimationtime then 802 self.fireanimationtimer = self.fireanimationtimer + dt 803 if self.fireanimationtimer > fireanimationtime then 804 self.fireanimationtimer = fireanimationtime 805 end 806 end 807 808 --vine controls and shit 809 if self.vine then 810 811 self.animationstate = "climbing" 812 if upkey(self.playernumber) then 813 self.vinemovetimer = self.vinemovetimer + dt 814 815 self.climbframe = math.ceil(math.mod(self.vinemovetimer, vineframedelay*2)/vineframedelay) 816 self.climbframe = math.max(self.climbframe, 1) 817 818 self.y = self.y-vinemovespeed*dt 819 820 local t = checkrect(self.x, self.y, self.width, self.height, {"tile", "portalwall"}) 821 if #t ~= 0 then 822 self.y = objects[t[1]][t[2]].y + objects[t[1]][t[2]].height 823 self.climbframe = 2 824 end 825 elseif downkey(self.playernumber) then 826 self.vinemovetimer = self.vinemovetimer + dt 827 828 self.climbframe = math.ceil(math.mod(self.vinemovetimer, vineframedelaydown*2)/vineframedelaydown) 829 self.climbframe = math.max(self.climbframe, 1) 830 831 checkportalHOR(self, self.y+vinemovedownspeed*dt) 832 833 self.y = self.y+vinemovedownspeed*dt 834 835 local t = checkrect(self.x, self.y, self.width, self.height, {"tile", "portalwall"}) 836 if #t ~= 0 then 837 self.y = objects[t[1]][t[2]].y - self.height 838 self.climbframe = 2 839 end 840 else 841 self.climbframe = 2 842 self.vinemovetimer = 0 843 end 844 845 if self.y+self.height <= vineanimationstart then 846 self:vineanimation() 847 end 848 849 --check if still on vine 850 local t = checkrect(self.x, self.y, self.width, self.height, {"vine"}) 851 if #t == 0 then 852 self:dropvine(self.vineside) 853 end 854 855 self:setquad() 856 return 857 end 858 859 --springs 860 if self.spring then 861 self.x = self.springx 862 self.springtimer = self.springtimer + dt 863 self.y = self.springy - self.height - 31/16 + springytable[self.springb.frame] 864 if self.springtimer > springtime then 865 self:leavespring() 866 end 867 return 868 end 869 870 --coins 871 if not editormode then 872 local x = math.floor(self.x+self.width/2)+1 873 local y = math.floor(self.y+self.height)+1 874 if inmap(x, y) and tilequads[map[x][y][1]].coin then 875 collectcoin(x, y) 876 end 877 local y = math.floor(self.y+self.height/2)+1 878 if inmap(x, y) and tilequads[map[x][y][1]].coin then 879 collectcoin(x, y) 880 end 881 if self.size > 1 then 882 if inmap(x, y-1) and tilequads[map[x][y-1][1]].coin then 883 collectcoin(x, y-1) 884 end 885 end 886 end 887 888 --mazegate 889 local x = math.floor(self.x+self.width/2)+1 890 local y = math.floor(self.y+self.height/2)+1 891 if inmap(x, y) and map[x][y][2] and entityquads[map[x][y][2]].t == "mazegate" then 892 if map[x][y][3] == self.mazevar + 1 then 893 self.mazevar = self.mazevar + 1 894 elseif map[x][y][3] == self.mazevar then 895 896 else 897 self.mazevar = 0 898 end 899 end 900 901 --axe 902 local x = math.floor(self.x+self.width/2)+1 903 local y = math.floor(self.y+self.height/2)+1 904 905 if axex and x == axex and y == axey then 906 self:axe() 907 end 908 909 if self.controlsenabled then 910 if self.jumping then 911 if underwater then 912 self.gravity = uwyaccelerationjumping 913 else 914 self.gravity = yaccelerationjumping 915 end 916 917 if self.speedy > 0 then 918 self.jumping = false 919 self.falling = true 920 end 921 else 922 if underwater then 923 self.gravity = uwyacceleration 924 else 925 self.gravity = yacceleration 926 end 927 end 928 929 --check for pipe pipe pipe� 930 if inmap(math.floor(self.x+30/16), math.floor(self.y+self.height+20/16)) and downkey(self.playernumber) and self.falling == false and self.jumping == false then 931 local t2 = map[math.floor(self.x+30/16)][math.floor(self.y+self.height+20/16)][2] 932 if t2 and entityquads[t2].t == "pipe" then 933 self:pipe(math.floor(self.x+30/16), math.floor(self.y+self.height+20/16), "down", tonumber(map[math.floor(self.x+30/16)][math.floor(self.y+self.height+20/16)][3])) 934 return 935 elseif t2 and entityquads[t2].t == "warppipe" then 936 self:pipe(math.floor(self.x+30/16), math.floor(self.y+self.height+20/16), "down", "pipe" .. map[math.floor(self.x+30/16)][math.floor(self.y+self.height+20/16)][3]) 937 return 938 end 939 end 940 941 self:updateangle() 942 943 --Portaldots 944 self.portaldotstimer = self.portaldotstimer + dt 945 while self.portaldotstimer > portaldotstime do 946 self.portaldotstimer = self.portaldotstimer - portaldotstime 947 end 948 949 if self.falling == false and self.jumping == false and self.size > 1 then 950 if downkey(self.playernumber) then 951 if self.ducking == false then 952 self:duck(true) 953 end 954 else 955 if self.ducking then 956 self:duck(false) 957 end 958 end 959 end 960 961 if not underwater then 962 self:movement(dt) 963 else 964 self:underwatermovement(dt) 965 end 966 967 if self.y >= 15 then 968 self:die("pit") 969 elseif flagx and self.x+self.width >= flagx+6/16 and self.y > 2.2 then 970 self:flag() 971 end 972 973 if firestartx and self.x >= firestartx - 1 then 974 firestarted = true 975 end 976 977 if flyingfishstartx and self.x >= flyingfishstartx - 1 then 978 flyingfishstarted = true 979 end 980 981 if flyingfishendx and self.x >= flyingfishendx - 1 then 982 flyingfishstarted = false 983 end 984 985 if bulletbillstartx and self.x >= bulletbillstartx - 1 then 986 bulletbillstarted = true 987 end 988 989 if bulletbillendx and self.x >= bulletbillendx - 1 then 990 bulletbillstarted = false 991 end 992 993 if lakitoendx and self.x >= lakitoendx then 994 lakitoend = true 995 end 996 end 997 998 --checkpoints 999 local checkx = checkpoints[checkpointi+1] 1000 if checkx then 1001 if self.x > checkx then 1002 checkpointi = checkpointi + 1 1003 checkpointx = checkpoints[checkpointi] 1004 end 1005 end 1006 1007 --drains 1008 local x = math.floor(self.x+self.width/2)+1 1009 1010 if inmap(x, 15) and #map[x][15] > 1 and entityquads[map[x][15][2]].t == "drain" then 1011 if self.speedy < drainmax then 1012 self.speedy = math.min( drainmax, self.speedy + drainspeed*dt) 1013 end 1014 end 1015 1016 self:setquad() 1017end 1018 1019function mario:updateangle() 1020 --UPDATE THE PLAYER ANGLE 1021 if self.playernumber == mouseowner then 1022 local scale = scale 1023 if shaders and shaders.scale then scale = shaders.scale end 1024 self.pointingangle = math.atan2(self.x+6/16-xscroll-(love.mouse.getX()/16/scale), (self.y+6/16-.5)-(love.mouse.getY()/16/scale)) 1025 elseif #controls[self.playernumber]["aimx"] > 0 then 1026 local x, y 1027 1028 local s = controls[self.playernumber]["aimx"] 1029 if s[1] == "joy" then 1030 x = -love.joystick.getAxis(s[2], s[4]) 1031 if s[5] == "neg" then 1032 x = -x 1033 end 1034 end 1035 1036 s = controls[self.playernumber]["aimy"] 1037 if s[1] == "joy" then 1038 y = -love.joystick.getAxis(s[2], s[4]) 1039 if s[5] == "neg" then 1040 y = -y 1041 end 1042 end 1043 1044 if not x or not y then 1045 return 1046 end 1047 1048 if math.abs(x) > joystickaimdeadzone or math.abs(y) > joystickaimdeadzone then 1049 self.pointingangle = math.atan2(x, y) 1050 if self.pointingangle == 0 then 1051 self.pointingangle = 0 --this is really silly, but will crash the game if I don't do this. It's because it's -0 or something. I'm not good with computers. 1052 end 1053 end 1054 end 1055end 1056 1057function mario:movement(dt) 1058 local maxrunspeed = maxrunspeed 1059 local maxwalkspeed = maxwalkspeed 1060 local runacceleration = runacceleration 1061 local walkacceleration = walkacceleration 1062 --Orange gel 1063 --not in air 1064 if self.falling == false and self.jumping == false then 1065 --bottom on grid 1066 if math.mod(self.y+self.height, 1) == 0 then 1067 local x = round(self.x+self.width/2+.5) 1068 local y = self.y+self.height+1 1069 --x and y in map 1070 if inmap(x, y) then 1071 --top of block orange 1072 if map[x][y]["gels"]["top"] == 2 then 1073 maxrunspeed = gelmaxrunspeed 1074 maxwalkspeed = gelmaxwalkspeed 1075 runacceleration = gelrunacceleration 1076 walkacceleration = gelwalkacceleration 1077 end 1078 end 1079 end 1080 end 1081 1082 --Run animation 1083 if self.animationstate == "running" then 1084 self.runanimationprogress = self.runanimationprogress + (math.abs(self.speedx)+4)/5*dt*runanimationspeed 1085 while self.runanimationprogress >= 4 do 1086 self.runanimationprogress = self.runanimationprogress - 3 1087 end 1088 self.runframe = math.floor(self.runanimationprogress) 1089 end 1090 1091 --HORIZONTAL MOVEMENT 1092 if runkey(self.playernumber) then --RUNNING 1093 if rightkey(self.playernumber) then --MOVEMENT RIGHT 1094 if self.jumping or self.falling then --IN AIR 1095 if self.speedx < maxwalkspeed then 1096 if self.speedx < 0 then 1097 self.speedx = self.speedx + runaccelerationair*dt*airslidefactor 1098 else 1099 self.speedx = self.speedx + runaccelerationair*dt 1100 end 1101 1102 if self.speedx > maxwalkspeed then 1103 self.speedx = maxwalkspeed 1104 end 1105 elseif self.speedx > maxwalkspeed and self.speedx < maxrunspeed then 1106 if self.speedx < 0 then 1107 self.speedx = self.speedx + runaccelerationair*dt*airslidefactor 1108 else 1109 self.speedx = self.speedx + runaccelerationair*dt 1110 end 1111 1112 if self.speedx > maxrunspeed then 1113 self.speedx = maxrunspeed 1114 end 1115 end 1116 1117 elseif self.ducking == false then --ON GROUND 1118 if self.speedx < 0 then 1119 if self.speedx > maxrunspeed then 1120 self.speedx = self.speedx + superfriction*dt + runacceleration*dt 1121 else 1122 self.speedx = self.speedx + friction*dt + runacceleration*dt 1123 end 1124 self.animationstate = "sliding" 1125 self.animationdirection = "right" 1126 else 1127 self.speedx = self.speedx + runacceleration*dt 1128 self.animationstate = "running" 1129 self.animationdirection = "right" 1130 end 1131 1132 if self.speedx > maxrunspeed then 1133 self.speedx = maxrunspeed 1134 end 1135 end 1136 1137 elseif leftkey(self.playernumber) then --MOVEMENT LEFT 1138 if self.jumping or self.falling then --IN AIR 1139 if self.speedx > -maxwalkspeed then 1140 if self.speedx > 0 then 1141 self.speedx = self.speedx - runaccelerationair*dt*airslidefactor 1142 else 1143 self.speedx = self.speedx - runaccelerationair*dt 1144 end 1145 1146 if self.speedx < -maxwalkspeed then 1147 self.speedx = -maxwalkspeed 1148 end 1149 elseif self.speedx < -maxwalkspeed and self.speedx > -maxrunspeed then 1150 if self.speedx > 0 then 1151 self.speedx = self.speedx - runaccelerationair*dt*airslidefactor 1152 else 1153 self.speedx = self.speedx - runaccelerationair*dt 1154 end 1155 1156 if self.speedx < -maxrunspeed then 1157 self.speedx = -maxrunspeed 1158 end 1159 end 1160 1161 elseif self.ducking == false then --ON GROUND 1162 if self.speedx > 0 then 1163 if self.speedx < -maxrunspeed then 1164 self.speedx = self.speedx - superfriction*dt - runacceleration*dt 1165 else 1166 self.speedx = self.speedx - friction*dt - runacceleration*dt 1167 end 1168 self.animationstate = "sliding" 1169 self.animationdirection = "left" 1170 else 1171 self.speedx = self.speedx - runacceleration*dt 1172 self.animationstate = "running" 1173 self.animationdirection = "left" 1174 end 1175 1176 if self.speedx < -maxrunspeed then 1177 self.speedx = -maxrunspeed 1178 end 1179 end 1180 1181 end 1182 if (not rightkey(self.playernumber) and not leftkey(self.playernumber)) or (self.ducking and self.falling == false and self.jumping == false) then --NO MOVEMENT 1183 if self.jumping or self.falling then 1184 if self.speedx > 0 then 1185 self.speedx = self.speedx - frictionair*dt 1186 if self.speedx < minspeed then 1187 self.speedx = 0 1188 self.runframe = 1 1189 end 1190 else 1191 self.speedx = self.speedx + frictionair*dt 1192 if self.speedx > -minspeed then 1193 self.speedx = 0 1194 self.runframe = 1 1195 end 1196 end 1197 else 1198 if self.speedx > 0 then 1199 if self.speedx > maxrunspeed then 1200 self.speedx = self.speedx - superfriction*dt 1201 else 1202 self.speedx = self.speedx - friction*dt 1203 end 1204 if self.speedx < minspeed then 1205 self.speedx = 0 1206 self.runframe = 1 1207 self.animationstate = "idle" 1208 end 1209 else 1210 if self.speedx < -maxrunspeed then 1211 self.speedx = self.speedx + superfriction*dt 1212 else 1213 self.speedx = self.speedx + friction*dt 1214 end 1215 if self.speedx > -minspeed then 1216 self.speedx = 0 1217 self.runframe = 1 1218 self.animationstate = "idle" 1219 end 1220 end 1221 end 1222 end 1223 1224 else --WALKING 1225 1226 if rightkey(self.playernumber) then --MOVEMENT RIGHT 1227 if self.jumping or self.falling then --IN AIR 1228 if self.speedx < maxwalkspeed then 1229 if self.speedx < 0 then 1230 self.speedx = self.speedx + walkaccelerationair*dt*airslidefactor 1231 else 1232 self.speedx = self.speedx + walkaccelerationair*dt 1233 end 1234 1235 if self.speedx > maxwalkspeed then 1236 self.speedx = maxwalkspeed 1237 end 1238 end 1239 elseif self.ducking == false then --ON GROUND 1240 if self.speedx < maxwalkspeed then 1241 if self.speedx < 0 then 1242 if self.speedx < -maxrunspeed then 1243 self.speedx = self.speedx + superfriction*dt + runacceleration*dt 1244 else 1245 self.speedx = self.speedx + friction*dt + runacceleration*dt 1246 end 1247 self.animationstate = "sliding" 1248 self.animationdirection = "right" 1249 else 1250 self.speedx = self.speedx + walkacceleration*dt 1251 self.animationstate = "running" 1252 self.animationdirection = "right" 1253 end 1254 1255 if self.speedx > maxwalkspeed then 1256 self.speedx = maxwalkspeed 1257 end 1258 else 1259 self.speedx = self.speedx - friction*dt 1260 if self.speedx < maxwalkspeed then 1261 self.speedx = maxwalkspeed 1262 end 1263 end 1264 end 1265 1266 elseif leftkey(self.playernumber) then --MOVEMENT LEFT 1267 if self.jumping or self.falling then --IN AIR 1268 if self.speedx > -maxwalkspeed then 1269 if self.speedx > 0 then 1270 self.speedx = self.speedx - walkaccelerationair*dt*airslidefactor 1271 else 1272 self.speedx = self.speedx - walkaccelerationair*dt 1273 end 1274 1275 if self.speedx < -maxwalkspeed then 1276 self.speedx = -maxwalkspeed 1277 end 1278 end 1279 elseif self.ducking == false then --ON GROUND 1280 if self.speedx > -maxwalkspeed then 1281 if self.speedx > 0 then 1282 if self.speedx > maxrunspeed then 1283 self.speedx = self.speedx - superfriction*dt - runacceleration*dt 1284 else 1285 self.speedx = self.speedx - friction*dt - runacceleration*dt 1286 end 1287 self.animationstate = "sliding" 1288 self.animationdirection = "left" 1289 else 1290 self.speedx = self.speedx - walkacceleration*dt 1291 self.animationstate = "running" 1292 self.animationdirection = "left" 1293 end 1294 1295 if self.speedx < -maxwalkspeed then 1296 self.speedx = -maxwalkspeed 1297 end 1298 else 1299 self.speedx = self.speedx + friction*dt 1300 if self.speedx > -maxwalkspeed then 1301 self.speedx = -maxwalkspeed 1302 end 1303 end 1304 end 1305 1306 end 1307 if (not rightkey(self.playernumber) and not leftkey(self.playernumber)) or (self.ducking and self.falling == false and self.jumping == false) then --no movement 1308 if self.jumping or self.falling then 1309 if self.speedx > 0 then 1310 self.speedx = self.speedx - frictionair*dt 1311 if self.speedx < 0 then 1312 self.speedx = 0 1313 self.runframe = 1 1314 end 1315 else 1316 self.speedx = self.speedx + frictionair*dt 1317 if self.speedx > 0 then 1318 self.speedx = 0 1319 self.runframe = 1 1320 end 1321 end 1322 else 1323 if self.speedx > 0 then 1324 if self.speedx > maxrunspeed then 1325 self.speedx = self.speedx - superfriction*dt 1326 else 1327 self.speedx = self.speedx - friction*dt 1328 end 1329 if self.speedx < 0 then 1330 self.speedx = 0 1331 self.runframe = 1 1332 self.animationstate = "idle" 1333 end 1334 else 1335 if self.speedx < -maxrunspeed then 1336 self.speedx = self.speedx + superfriction*dt 1337 else 1338 self.speedx = self.speedx + friction*dt 1339 end 1340 if self.speedx > 0 then 1341 self.speedx = 0 1342 self.runframe = 1 1343 self.animationstate = "idle" 1344 end 1345 end 1346 end 1347 end 1348 end 1349end 1350 1351function mario:underwatermovement(dt) 1352 if self.jumping or self.falling then 1353 --Swim animation 1354 if self.animationstate == "jumping" or self.animationstate == "falling" then 1355 self.swimanimationprogress = self.swimanimationprogress + runanimationspeed*dt 1356 while self.swimanimationprogress >= 3 do 1357 self.swimanimationprogress = self.swimanimationprogress - 2 1358 end 1359 self.swimframe = math.floor(self.swimanimationprogress) 1360 end 1361 else 1362 --Run animation 1363 if self.animationstate == "running" then 1364 self.runanimationprogress = self.runanimationprogress + (math.abs(self.speedx)+4)/5*dt*runanimationspeed 1365 while self.runanimationprogress >= 4 do 1366 self.runanimationprogress = self.runanimationprogress - 3 1367 end 1368 self.runframe = math.floor(self.runanimationprogress) 1369 end 1370 end 1371 1372 --bubbles 1373 self.bubbletimer = self.bubbletimer + dt 1374 while self.bubbletimer > self.bubbletime do 1375 self.bubbletimer = self.bubbletimer - self.bubbletime 1376 self.bubbletime = bubblestime[math.random(#bubblestime)] 1377 table.insert(bubbles, bubble:new(self.x+8/12, self.y+2/12)) 1378 end 1379 1380 --HORIZONTAL MOVEMENT 1381 if rightkey(self.playernumber) then --MOVEMENT RIGHT 1382 if self.jumping or self.falling then --IN AIR 1383 if self.speedx < uwmaxairwalkspeed then 1384 if self.speedx < 0 then 1385 self.speedx = self.speedx + uwwalkaccelerationair*dt*uwairslidefactor 1386 else 1387 self.speedx = self.speedx + uwwalkaccelerationair*dt 1388 end 1389 1390 if self.speedx > uwmaxairwalkspeed then 1391 self.speedx = uwmaxairwalkspeed 1392 end 1393 end 1394 elseif self.ducking == false then --ON GROUND 1395 if self.speedx < uwmaxwalkspeed then 1396 if self.speedx < 0 then 1397 if self.speedx < -uwmaxrunspeed then 1398 self.speedx = self.speedx + uwsuperfriction*dt + uwrunacceleration*dt 1399 else 1400 self.speedx = self.speedx + uwfriction*dt + uwrunacceleration*dt 1401 end 1402 self.animationstate = "sliding" 1403 self.animationdirection = "right" 1404 else 1405 self.speedx = self.speedx + uwwalkacceleration*dt 1406 self.animationstate = "running" 1407 self.animationdirection = "right" 1408 end 1409 1410 if self.speedx > uwmaxwalkspeed then 1411 self.speedx = uwmaxwalkspeed 1412 end 1413 else 1414 self.speedx = self.speedx - uwfriction*dt 1415 if self.speedx < uwmaxwalkspeed then 1416 self.speedx = uwmaxwalkspeed 1417 end 1418 end 1419 end 1420 1421 elseif leftkey(self.playernumber) then --MOVEMENT LEFT 1422 if self.jumping or self.falling then --IN AIR 1423 if self.speedx > -uwmaxairwalkspeed then 1424 if self.speedx > 0 then 1425 self.speedx = self.speedx - uwwalkaccelerationair*dt*uwairslidefactor 1426 else 1427 self.speedx = self.speedx - uwwalkaccelerationair*dt 1428 end 1429 1430 if self.speedx < -uwmaxairwalkspeed then 1431 self.speedx = -uwmaxairwalkspeed 1432 end 1433 end 1434 elseif self.ducking == false then --ON GROUND 1435 if self.speedx > -uwmaxwalkspeed then 1436 if self.speedx > 0 then 1437 if self.speedx > uwmaxrunspeed then 1438 self.speedx = self.speedx - uwsuperfriction*dt - uwrunacceleration*dt 1439 else 1440 self.speedx = self.speedx - uwfriction*dt - uwrunacceleration*dt 1441 end 1442 self.animationstate = "sliding" 1443 self.animationdirection = "left" 1444 else 1445 self.speedx = self.speedx - uwwalkacceleration*dt 1446 self.animationstate = "running" 1447 self.animationdirection = "left" 1448 end 1449 1450 if self.speedx < -uwmaxwalkspeed then 1451 self.speedx = -uwmaxwalkspeed 1452 end 1453 else 1454 self.speedx = self.speedx + uwfriction*dt 1455 if self.speedx > -uwmaxwalkspeed then 1456 self.speedx = -uwmaxwalkspeed 1457 end 1458 end 1459 end 1460 1461 else --NO MOVEMENT 1462 if self.jumping or self.falling then 1463 if self.speedx > 0 then 1464 self.speedx = self.speedx - uwfrictionair*dt 1465 if self.speedx < 0 then 1466 self.speedx = 0 1467 self.runframe = 1 1468 end 1469 else 1470 self.speedx = self.speedx + uwfrictionair*dt 1471 if self.speedx > 0 then 1472 self.speedx = 0 1473 self.runframe = 1 1474 end 1475 end 1476 else 1477 if self.speedx > 0 then 1478 if self.speedx > uwmaxrunspeed then 1479 self.speedx = self.speedx - uwsuperfriction*dt 1480 else 1481 self.speedx = self.speedx - uwfriction*dt 1482 end 1483 if self.speedx < 0 then 1484 self.speedx = 0 1485 self.runframe = 1 1486 self.animationstate = "idle" 1487 end 1488 else 1489 if self.speedx < -uwmaxrunspeed then 1490 self.speedx = self.speedx + uwsuperfriction*dt 1491 else 1492 self.speedx = self.speedx + uwfriction*dt 1493 end 1494 if self.speedx > 0 then 1495 self.speedx = 0 1496 self.runframe = 1 1497 self.animationstate = "idle" 1498 end 1499 end 1500 end 1501 end 1502 1503 if self.y+self.height < uwmaxheight then 1504 self.speedy = uwpushdownspeed 1505 end 1506end 1507 1508function mario:setquad(anim, s) 1509 local angleframe = getAngleFrame(self.pointingangle+self.rotation) 1510 1511 local animationstate = anim or self.animationstate 1512 local size = s or self.size 1513 1514 if size == 1 then 1515 if underwater and (self.animationstate == "jumping" or self.animationstate == "falling") then 1516 self.quad = marioswim[angleframe][self.swimframe] 1517 elseif animationstate == "running" or animationstate == "falling" then 1518 self.quad = mariorun[angleframe][self.runframe] 1519 elseif animationstate == "idle" then 1520 self.quad = marioidle[angleframe] 1521 elseif animationstate == "sliding" then 1522 self.quad = marioslide[angleframe] 1523 elseif animationstate == "jumping" then 1524 self.quad = mariojump[angleframe] 1525 elseif animationstate == "climbing" then 1526 self.quad = marioclimb[angleframe][self.climbframe] 1527 elseif animationstate == "dead" then 1528 self.quad = mariodie[angleframe] 1529 elseif animationstate == "grow" then 1530 self.quad = mariogrow[angleframe] 1531 end 1532 elseif size > 1 then 1533 if underwater and (self.animationstate == "jumping" or self.animationstate == "falling") then 1534 self.quad = bigmarioswim[angleframe][self.swimframe] 1535 elseif self.ducking then 1536 self.quad = bigmarioduck[angleframe] 1537 elseif self.fireanimationtimer < fireanimationtime then 1538 self.quad = bigmariofire[angleframe] 1539 else 1540 if animationstate == "running" or animationstate == "falling" then 1541 self.quad = bigmariorun[angleframe][self.runframe] 1542 elseif animationstate == "idle" then 1543 self.quad = bigmarioidle[angleframe] 1544 elseif animationstate == "sliding" then 1545 self.quad = bigmarioslide[angleframe] 1546 elseif animationstate == "climbing" then 1547 self.quad = bigmarioclimb[angleframe][self.climbframe] 1548 elseif animationstate == "jumping" then 1549 self.quad = bigmariojump[angleframe] 1550 end 1551 end 1552 end 1553end 1554 1555function mario:jump() 1556 if not noupdate and self.controlsenabled then 1557 if not underwater then 1558 if self.spring then 1559 self.springhigh = true 1560 return 1561 end 1562 1563 if self.falling == false then 1564 if self.size == 1 then 1565 playsound(jumpsound) 1566 else 1567 playsound(jumpbigsound) 1568 end 1569 1570 local force = -jumpforce - (math.abs(self.speedx) / maxrunspeed)*jumpforceadd 1571 force = math.max(-jumpforce - jumpforceadd, force) 1572 1573 self.speedy = force 1574 self.jumping = true 1575 self.animationstate = "jumping" 1576 self:setquad() 1577 end 1578 else 1579 if self.ducking then 1580 self:duck(false) 1581 end 1582 playsound(swimsound) 1583 1584 self.speedy = -uwjumpforce - (math.abs(self.speedx) / maxrunspeed)*uwjumpforceadd 1585 self.jumping = true 1586 self.animationstate = "jumping" 1587 self:setquad() 1588 end 1589 end 1590end 1591 1592function mario:stopjump() 1593 if self.controlsenabled then 1594 if self.jumping == true then 1595 self.jumping = false 1596 self.falling = true 1597 end 1598 end 1599end 1600 1601function mario:rightkey() 1602 if self.controlsenabled and self.vine then 1603 if self.vineside == "left" then 1604 self.x = self.x + 8/16 1605 self.pointingangle = math.pi/2 1606 self.vineside = "right" 1607 else 1608 self:dropvine("right") 1609 end 1610 end 1611end 1612 1613function mario:leftkey() 1614 if self.controlsenabled and self.vine then 1615 if self.vineside == "right" then 1616 self.x = self.x - 8/16 1617 self.pointingangle = -math.pi/2 1618 self.vineside = "left" 1619 else 1620 self:dropvine("left") 1621 end 1622 end 1623end 1624 1625function mario:grow() 1626 self.animationmisc = self.animationstate 1627 if self.animation and self.animation ~= "invincible" then 1628 return 1629 end 1630 addpoints(1000, self.x+self.width/2, self.y) 1631 playsound(mushroomeatsound) 1632 1633 if bigmario then 1634 return 1635 end 1636 1637 if self.size > 2 then 1638 1639 else 1640 self.size = self.size + 1 1641 if self.size == 2 then 1642 self.y = self.y - 12/16 1643 self.height = 24/16 1644 elseif self.size == 3 then 1645 self.colors = flowercolor 1646 end 1647 1648 if self.size == 2 then 1649 self.animation = "grow1" 1650 else 1651 self.animation = "grow2" 1652 end 1653 1654 self.drawable = true 1655 self.invincible = false 1656 self.animationtimer = 0 1657 noupdate = true 1658 end 1659end 1660 1661function mario:shrink() 1662 self.animationmisc = self.animationstate 1663 if self.animation then 1664 return 1665 end 1666 if self.ducking then 1667 self:duck(false) 1668 end 1669 playsound(shrinksound) 1670 1671 self.size = 1 1672 1673 self.colors = mariocolors[self.playernumber] 1674 1675 self.animation = "shrink" 1676 self.drawable = true 1677 self.invincible = true 1678 self.animationtimer = 0 1679 1680 self.y = self.y + 12/16 1681 self.height = 12/16 1682 1683 noupdate = true 1684end 1685 1686function mario:floorcollide(a, b) 1687 self.rainboomallowed = true 1688 if self.jumping and (a == "platform" or a == "seesawplatform") and self.speedy < -jumpforce + 0.1 then 1689 return false 1690 end 1691 1692 local anim = self.animationstate 1693 local jump = self.jumping 1694 local fall = self.falling 1695 1696 if self:globalcollide(a, b) then 1697 return false 1698 end 1699 1700 if a == "spring" then 1701 self:hitspring(b) 1702 return false 1703 end 1704 1705 if self.speedx == 0 then 1706 self.animationstate = "idle" 1707 else 1708 if self.animationstate ~= "sliding" then 1709 self.animationstate = "running" 1710 end 1711 end 1712 self:setquad() 1713 1714 if a == "tile" then 1715 local x, y = b.cox, b.coy 1716 if bigmario and self.speedy > 2 then 1717 destroyblock(x, y) 1718 self.speedy = self.speedy/10 1719 end 1720 1721 --check for invisible block 1722 if tilequads[map[x][y][1]].invisible then 1723 self.jumping = jump 1724 self.falling = fall 1725 self.animationstate = anim 1726 return false 1727 end 1728 end 1729 1730 --star logic 1731 if self.starred or bigmario then 1732 if self:starcollide(a, b) then 1733 return false 1734 end 1735 end 1736 1737 self.falling = false 1738 self.jumping = false 1739 1740 --Make mario snap to runspeed if at walkspeed. 1741 --[[if leftkey(self.playernumber) then 1742 if runkey(self.playernumber) then 1743 if self.speedx <= -maxwalkspeed then 1744 self.speedx = -maxrunspeed 1745 self.animationdirection = "left" 1746 end 1747 end 1748 elseif rightkey(self.playernumber) then 1749 if runkey(self.playernumber) then 1750 if self.speedx >= maxwalkspeed then 1751 self.speedx = maxrunspeed 1752 self.animationdirection = "right" 1753 end 1754 end 1755 end--]] 1756 1757 if a == "mushroom" or a == "oneup" or a == "star" or a == "flower" then 1758 self.falling = true 1759 return false 1760 elseif (a == "goomba" and b.t == "goomba") or a == "bulletbill" or a == "flyingfish" or a == "lakito" or a == "hammerbro" or a == "koopa" then 1761 self:stompenemy(a, b) 1762 return false 1763 elseif a == "tile" then 1764 local x, y = b.cox, b.coy 1765 1766 if map[x][y]["gels"] then 1767 if downkey(self.playernumber) == false and map[x][y]["gels"]["top"] == 1 and self.speedy > gdt*yacceleration*10 then 1768 self.speedy = -self.speedy 1769 self.falling = true 1770 self.animationstate = "jumping" 1771 self:setquad() 1772 self.speedy = self.speedy + self.gravity*gdt 1773 1774 return false 1775 end 1776 end 1777 elseif a == "plant" or a == "bowser" or a == "cheep" or a == "upfire" or (a == "goomba" and b.t ~= "goomba") or a == "squid" or a == "hammer" then --KILL 1778 if self.invincible then 1779 self.jumping = jump 1780 self.falling = fall 1781 self.animationstate = anim 1782 return false 1783 else 1784 self:die("Enemy (floorcollide)") 1785 return false 1786 end 1787 elseif a == "castlefirefire" or a == "fire" then 1788 if self.invincible then 1789 self.jumping = jump 1790 self.falling = fall 1791 self.animationstate = anim 1792 return false 1793 else 1794 self:die("castlefirefire") 1795 return false 1796 end 1797 end 1798 1799 self.combo = 1 1800end 1801 1802function mario:stompenemy(a, b) 1803 local bounce = false 1804 if a == "koopa" then 1805 if b.small then 1806 playsound(shotsound) 1807 if b.speedx == 0 then 1808 addpoints(500, b.x, b.y) 1809 self.combo = 1 1810 end 1811 else 1812 playsound(stompsound) 1813 end 1814 1815 b:stomp(self.x, self) 1816 1817 if b.speedx == 0 or ((b.t == "redflying" or b.t == "flying") and b.small == false) then 1818 addpoints(mariocombo[self.combo], self.x, self.y) 1819 if self.combo < #mariocombo then 1820 self.combo = self.combo + 1 1821 end 1822 1823 local grav = self.gravity or yacceleration 1824 1825 local bouncespeed = math.sqrt(2*grav*bounceheight) 1826 1827 self.speedy = -bouncespeed 1828 1829 self.falling = true 1830 self.animationstate = "jumping" 1831 self:setquad() 1832 self.y = b.y - self.height-1/16 1833 elseif b.x > self.x then 1834 b.x = self.x + b.width + self.speedx*gdt + 0.05 1835 local col = checkrect(b.x, b.y, b.width, b.height, {"tile"}) 1836 if #col > 1 then 1837 b.x = objects[col[1]][col[2]].x-b.width 1838 bounce = true 1839 end 1840 else 1841 b.x = self.x - b.width + self.speedx*gdt - 0.05 1842 local col = checkrect(b.x, b.y, b.width, b.height, {"tile"}) 1843 if #col > 1 then 1844 b.x = objects[col[1]][col[2]].x+1 1845 bounce = true 1846 end 1847 end 1848 else 1849 b:stomp() 1850 if self.combo < #mariocombo then 1851 addpoints(mariocombo[self.combo], self.x, self.y) 1852 if a ~= "bulletbill" then 1853 self.combo = self.combo + 1 1854 end 1855 else 1856 if mariolivecount ~= false then 1857 mariolives[self.playernumber] = mariolives[self.playernumber]+1 1858 end 1859 table.insert(scrollingscores, scrollingscore:new("1up", self.x, self.y)) 1860 playsound(oneupsound) 1861 end 1862 playsound(stompsound) 1863 1864 bounce = true 1865 end 1866 1867 if bounce then 1868 local grav = self.gravity or yacceleration 1869 1870 local bouncespeed = math.sqrt(2*grav*bounceheight) 1871 1872 self.animationstate = "jumping" 1873 self.falling = true 1874 self:setquad() 1875 self.speedy = -bouncespeed 1876 end 1877end 1878 1879function mario:rightcollide(a, b) 1880 if self:globalcollide(a, b) then 1881 return false 1882 end 1883 1884 --star logic 1885 if self.starred or bigmario then 1886 if self:starcollide(a, b) then 1887 return false 1888 end 1889 end 1890 1891 if a == "mushroom" or a == "oneup" or a == "star" or a == "flower" or (a == "platform" and (b.dir == "right" or b.dir == "justright")) then 1892 return false 1893 elseif self.speedy > 2 and ((a == "goomba" and b.t == "goomba") or a == "bulletbill" or a == "flyingfish" or a == "lakito" or a == "hammerbro" or a == "koopa") then 1894 self:stompenemy(a, b) 1895 return false 1896 elseif a == "castlefirefire" or a == "fire" or a == "koopa" or a == "goomba" or a == "bulletbill" or a == "plant" or a == "bowser" or a == "cheep" or a == "flyingfish" or a == "upfire" or a == "lakito" or a == "squid" or a == "hammer" or a == "hammerbro" then --KILLS 1897 if self.invincible then 1898 if a == "koopa" and b.small and b.speedx == 0 then 1899 b:stomp(self.x) 1900 playsound(shotsound) 1901 addpoints(500, b.x, b.y) 1902 end 1903 return false 1904 else 1905 if a == "koopa" and b.small and b.speedx == 0 then 1906 b:stomp(self.x) 1907 playsound(shotsound) 1908 addpoints(500, b.x, b.y) 1909 return false 1910 end 1911 1912 self:die("Enemy (rightcollide)") 1913 return false 1914 end 1915 elseif a == "tile" then 1916 local x, y = b.cox, b.coy 1917 1918 if map[x][y]["gels"] then 1919 if downkey(self.playernumber) == false and map[x][y]["gels"]["left"] == 1 and (self.falling or self.jumping) then 1920 if self.speedx > horbounceminspeedx then 1921 self.speedx = math.min(-horbouncemaxspeedx, -self.speedx*horbouncemul) 1922 self.speedy = math.min(self.speedy, -horbouncespeedy) 1923 1924 return false 1925 end 1926 end 1927 end 1928 1929 --check for invisible block 1930 if tilequads[map[x][y][1]].invisible then 1931 return false 1932 end 1933 1934 --Check if it's a pipe with pipe pipe. 1935 if self.falling == false and self.jumping == false and (rightkey(self.playernumber) or intermission) then --but only on ground and rightkey 1936 local t2 = map[x][y][2] 1937 if t2 and entityquads[t2].t == "pipe" then 1938 self:pipe(x, y, "right", tonumber(map[x][y][3])) 1939 return 1940 else 1941 if inmap(x, y+1) then 1942 t2 = map[x][y+1][2] 1943 if t2 and entityquads[t2].t == "pipe" then 1944 self:pipe(x, y+1, "right", tonumber(map[x][y+1][3])) 1945 return 1946 end 1947 end 1948 end 1949 end 1950 1951 --Check if mario should run across a gap. 1952 if inmap(x, y-1) and tilequads[map[x][y-1][1]].collision == false and self.speedy > 0 and self.y+self.height+1 < y+spacerunroom then 1953 self.y = b.y - self.height 1954 self.speedy = 0 1955 self.x = b.x-self.width+0.0001 1956 self.falling = false 1957 self.animationstate = "running" 1958 self:setquad() 1959 return false 1960 end 1961 1962 if bigmario then 1963 destroyblock(x, y) 1964 return false 1965 end 1966 elseif a == "box" then 1967 if self.speedx > maxwalkspeed/2 then 1968 self.speedx = self.speedx - self.speedx * 6 * gdt 1969 end 1970 1971 --check if box can even move 1972 local out = checkrect(b.x+self.speedx*gdt, b.y, b.width, b.height, {"exclude", b}, true) 1973 if #out == 0 then 1974 b.speedx = self.speedx 1975 return false 1976 end 1977 elseif a == "button" then 1978 self.y = b.y - self.height 1979 self.x = b.x - self.width+0.001 1980 if self.speedy > 0 then 1981 self.speedy = 0 1982 end 1983 return false 1984 end 1985 1986 if self.falling == false and self.jumping == false then 1987 self.animationstate = "idle" 1988 self:setquad() 1989 end 1990end 1991 1992function mario:leftcollide(a, b) 1993 if self:globalcollide(a, b) then 1994 return false 1995 end 1996 1997 --star logic 1998 if self.starred or bigmario then 1999 if self:starcollide(a, b) then 2000 return false 2001 end 2002 end 2003 2004 if a == "mushroom" or a == "oneup" or a == "star" or a == "flower" or (a == "platform" and (b.dir == "right" or b.dir == "justright")) then --NOTHING 2005 return false 2006 elseif self.speedy > 2 and ((a == "goomba" and b.t == "goomba") or a == "bulletbill" or a == "flyingfish" or a == "lakito" or a == "hammerbro" or a == "koopa") then 2007 self:stompenemy(a, b) 2008 return false 2009 elseif a == "castlefirefire" or a == "fire" or a == "koopa" or a == "goomba" or a == "bulletbill" or a == "plant" or a == "bowser" or a == "cheep" or a == "flyingfish" or a == "upfire" or a == "lakito" or a == "squid" or a == "hammer" or a == "hammerbro" then --KILLS 2010 if self.invincible then 2011 if a == "koopa" and b.small and b.speedx == 0 then 2012 b:stomp(self.x) 2013 playsound(shotsound) 2014 addpoints(500, b.x, b.y) 2015 end 2016 return false 2017 else 2018 if a == "koopa" and b.small and b.speedx == 0 then 2019 b:stomp(self.x) 2020 playsound(shotsound) 2021 addpoints(500, b.x, b.y) 2022 return false 2023 end 2024 2025 self:die("Enemy (leftcollide)") 2026 return false 2027 end 2028 elseif a == "tile" then 2029 local x, y = b.cox, b.coy 2030 2031 if map[x][y]["gels"] then 2032 if downkey(self.playernumber) == false and map[x][y]["gels"]["right"] == 1 and (self.falling or self.jumping) then 2033 if self.speedx < -horbounceminspeedx then 2034 self.speedx = math.min(horbouncemaxspeedx, -self.speedx*horbouncemul) 2035 self.speedy = math.min(self.speedy, -horbouncespeedy) 2036 2037 return false 2038 end 2039 end 2040 end 2041 2042 --check for invisible block 2043 if tilequads[map[x][y][1]].invisible then 2044 return false 2045 end 2046 2047 if inmap(x, y-1) and tilequads[map[x][y-1][1]].collision == false and self.speedy > 0 and self.y+1+self.height < y+spacerunroom then 2048 self.y = b.y - self.height 2049 self.speedy = 0 2050 self.x = b.x+1-0.0001 2051 self.falling = false 2052 self.animationstate = "running" 2053 self:setquad() 2054 return false 2055 end 2056 2057 if bigmario then 2058 destroyblock(x, y) 2059 return false 2060 end 2061 elseif a == "box" then 2062 if self.speedx < -maxwalkspeed/2 then 2063 self.speedx = self.speedx - self.speedx * 6 * gdt 2064 end 2065 2066 --check if box can even move 2067 local out = checkrect(b.x+self.speedx*gdt, b.y, b.width, b.height, {"exclude", b}, true) 2068 if #out == 0 then 2069 b.speedx = self.speedx 2070 return false 2071 end 2072 elseif a == "button" then 2073 self.y = b.y - self.height 2074 self.x = b.x + b.width - 0.001 2075 if self.speedy > 0 then 2076 self.speedy = 0 2077 end 2078 return false 2079 end 2080 2081 if self.falling == false and self.jumping == false then 2082 self.animationstate = "idle" 2083 self:setquad() 2084 end 2085end 2086 2087function mario:ceilcollide(a, b) 2088 if self:globalcollide(a, b) then 2089 return false 2090 end 2091 2092 --star logic 2093 if self.starred or bigmario then 2094 if self:starcollide(a, b) then 2095 return false 2096 end 2097 end 2098 2099 if a == "mushroom" or a == "oneup" or a == "star" or a == "flower" then --STUFF THAT SHOULDN'T DO SHIT 2100 return false 2101 elseif a == "castlefirefire" or a == "fire" or a == "plant" or a == "goomba" or a == "koopa" or a == "bulletbill" or a == "bowser" or a == "cheep" or a == "flyingfish" or a == "upfire" or a == "lakito" or a == "squid" or a == "hammer" or a == "hammerbro" then --STUFF THAT KILLS 2102 if self.invincible then 2103 return false 2104 else 2105 self:die("Enemy (Ceilcollided)") 2106 return false 2107 end 2108 elseif a == "tile" then 2109 local x, y = b.cox, b.coy 2110 local r = map[x][y] 2111 2112 --check if it's an invisible block 2113 if tilequads[map[x][y][1]].invisible then 2114 if self.y-self.speedy <= y-1 then 2115 return false 2116 end 2117 else 2118 if bigmario then 2119 destroyblock(x, y) 2120 return false 2121 end 2122 2123 --Check if it should bounce the block next to it, or push mario instead (Hello, devin hitch!) 2124 2125 if self.x < x-22/16 then 2126 --check if block left of it is a better fit 2127 if x > 1 and tilequads[map[x-1][y][1]].collision == true then 2128 x = x - 1 2129 else 2130 local col = checkrect(x-28/16, self.y, self.width, self.height, {"exclude", self}, true) 2131 if #col == 0 then 2132 self.x = x-28/16 2133 if self.speedx > 0 then 2134 self.speedx = 0 2135 end 2136 return false 2137 end 2138 end 2139 elseif self.x > x-6/16 then 2140 --check if block right of it is a better fit 2141 if x < mapwidth and tilequads[map[x+1][y][1]].collision == true then 2142 x = x + 1 2143 else 2144 local col = checkrect(x, self.y, self.width, self.height, {"exclude", self}, true) 2145 if #col == 0 then 2146 self.x = x 2147 if self.speedx < 0 then 2148 self.speedx = 0 2149 end 2150 return false 2151 end 2152 end 2153 end 2154 end 2155 2156 hitblock(x, y, self) 2157 end 2158 2159 self.jumping = false 2160 self.falling = true 2161 self.speedy = headforce 2162end 2163 2164function mario:globalcollide(a, b) 2165 if a == "screenboundary" then 2166 if self.x+self.width/2 > b.x then 2167 self.x = b.x 2168 else 2169 self.x = b.x-self.width 2170 end 2171 self.speedx = 0 2172 return true 2173 elseif a == "vine" then 2174 if self.vine == false then 2175 self:grabvine(b) 2176 end 2177 2178 return true 2179 end 2180end 2181 2182function mario:passivecollide(a, b) 2183 if self:globalcollide(a, b) then 2184 return false 2185 end 2186 2187 if a == "platform" or a == "seesawplatform" or a == "portalwall" then 2188 return false 2189 elseif a == "box" then 2190 if self.speedx < 0 then 2191 if self.speedx < -maxwalkspeed/2 then 2192 self.speedx = self.speedx - self.speedx * 0.1 2193 end 2194 2195 --check if box can even move 2196 local out = checkrect(b.x+self.speedx*gdt, b.y, b.width, b.height, {"exclude", b}) 2197 if #out == 0 then 2198 b.speedx = self.speedx 2199 return false 2200 end 2201 else 2202 if self.speedx > maxwalkspeed/2 then 2203 self.speedx = self.speedx - self.speedx * 6 * gdt 2204 end 2205 2206 --check if box can even move 2207 local out = checkrect(b.x+self.speedx*gdt, b.y, b.width, b.height, {"exclude", b}) 2208 if #out == 0 then 2209 b.speedx = self.speedx 2210 return false 2211 end 2212 end 2213 end 2214 if self.passivemoved == false then 2215 self.passivemoved = true 2216 if a == "tile" then 2217 local x, y = b.cox, b.coy 2218 2219 --check for invisible block 2220 if inmap(x, y) and tilequads[map[x][y][1]].invisible then 2221 return false 2222 end 2223 2224 if self.pointingangle < 0 then 2225 self.x = self.x - passivespeed*gdt 2226 else 2227 self.x = self.x + passivespeed*gdt 2228 end 2229 self.speedx = 0 2230 else 2231 --nothing, lol. 2232 end 2233 end 2234 2235 2236 self:rightcollide(a, b) 2237end 2238 2239function mario:starcollide(a, b) 2240 --enemies that die 2241 if a == "goomba" or a == "koopa" or a == "plant" or a == "bowser" or a == "squid" or a == "cheep" or a == "hammerbro" or a == "lakito" or a == "bulletbill" or a == "flyingfish" then 2242 b:shotted("right") 2243 if a ~= "bowser" then 2244 addpoints(firepoints[a], self.x, self.y) 2245 end 2246 return true 2247 --enemies (and stuff) that don't do shit 2248 elseif a == "upfire" or a == "fire" or a == "hammer" or a == "fireball" or a == "castlefirefire" then 2249 return true 2250 end 2251end 2252 2253function mario:hitspring(b) 2254 b:hit() 2255 self.springb = b 2256 self.springx = self.x 2257 self.springy = b.coy 2258 self.speedy = 0 2259 self.spring = true 2260 self.springhigh = false 2261 self.springtimer = 0 2262 self.gravity = 0 2263 self.mask[19] = true 2264 self.animationstate = "idle" 2265 self:setquad() 2266end 2267 2268function mario:leavespring() 2269 self.y = self.springy - self.height-31/16 2270 if self.springhigh then 2271 self.speedy = -springhighforce 2272 else 2273 self.speedy = -springforce 2274 end 2275 self.animationstate = "falling" 2276 self:setquad() 2277 self.gravity = yacceleration 2278 self.falling = true 2279 self.spring = false 2280 self.mask[19] = false 2281end 2282 2283function mario:dropvine(dir) 2284 if dir == "right" then 2285 self.x = self.x + 7/16 2286 else 2287 self.x = self.x - 7/16 2288 end 2289 self.animationstate = "falling" 2290 self:setquad() 2291 self.gravity = mariogravity 2292 self.vine = false 2293 self.mask[18] = false 2294end 2295 2296function mario:grabvine(b) 2297 self.ducking = false 2298 if insideportal(self.x, self.y, self.width, self.height) then 2299 return 2300 end 2301 self.mask[18] = true 2302 self.vine = true 2303 self.gravity = 0 2304 self.speedx = 0 2305 self.speedy = 0 2306 self.animationstate = "climbing" 2307 self.climbframe = 2 2308 self.vinemovetimer = 0 2309 self:setquad() 2310 self.vinex = b.cox 2311 self.viney = b.coy 2312 if b.x > self.x then --left of vine 2313 self.x = b.x+b.width/2-self.width+2/16 2314 self.pointingangle = -math.pi/2 2315 self.vineside = "left" 2316 else --right 2317 self.x = b.x+b.width/2 - 2/16 2318 self.pointingangle = math.pi/2 2319 self.vineside = "right" 2320 end 2321end 2322 2323function hitblock(x, y, t) 2324 for i = 1, players do 2325 local x1 = objects["player"][i].portal1X 2326 local y1 = objects["player"][i].portal1Y 2327 2328 local x2 = objects["player"][i].portal2X 2329 local y2 = objects["player"][i].portal2Y 2330 2331 local x3 = x1 2332 local y3 = y1 2333 2334 if objects["player"][i].portal1facing == "up" then 2335 x3 = x3+1 2336 elseif objects["player"][i].portal1facing == "right" then 2337 y3 = y3+1 2338 elseif objects["player"][i].portal1facing == "down" then 2339 x3 = x3-1 2340 elseif objects["player"][i].portal1facing == "left" then 2341 y3 = y3-1 2342 end 2343 2344 local x4 = x2 2345 local y4 = y2 2346 2347 if objects["player"][i].portal2facing == "up" then 2348 y4 = y4-1 2349 elseif objects["player"][i].portal2facing == "right" then 2350 x4 = x4+1 2351 elseif objects["player"][i].portal2facing == "down" then 2352 y4 = y4+1 2353 elseif objects["player"][i].portal2facing == "left" then 2354 x4 = x4-1 2355 end 2356 2357 if (x == x1 and y == y1) or (x == x2 and y == y2) or (x == x3 and y == y3) or (x == x4 and y == y4) then 2358 return 2359 end 2360 end 2361 2362 2363 if editormode then 2364 return 2365 end 2366 2367 if not inmap(x, y) then 2368 return 2369 end 2370 2371 local r = map[x][y] 2372 playsound(blockhitsound) 2373 2374 if tilequads[r[1]].breakable == true or tilequads[r[1]].coinblock == true then --Block should bounce! 2375 table.insert(blockbouncetimer, 0.000000001) --yeah it's a cheap solution to a problem but screw it. 2376 table.insert(blockbouncex, x) 2377 table.insert(blockbouncey, y) 2378 generatespritebatch() 2379 if #r > 1 and entityquads[r[2]].t ~= "manycoins" then --block contained something! 2380 table.insert(blockbouncecontent, entityquads[r[2]].t) 2381 table.insert(blockbouncecontent2, t.size) 2382 if tilequads[r[1]].invisible then 2383 if spriteset == 1 then 2384 map[x][y][1] = 113 2385 elseif spriteset == 2 then 2386 map[x][y][1] = 118 2387 else 2388 map[x][y][1] = 112 2389 end 2390 else 2391 if spriteset == 1 then 2392 map[x][y][1] = 113 2393 elseif spriteset == 2 then 2394 map[x][y][1] = 114 2395 else 2396 map[x][y][1] = 117 2397 end 2398 end 2399 if entityquads[r[2]].t == "vine" then 2400 playsound(vinesound) 2401 else 2402 playsound(mushroomappearsound) 2403 end 2404 else 2405 table.insert(blockbouncecontent, false) 2406 table.insert(blockbouncecontent2, t.size) 2407 2408 if t and t.size > 1 and tilequads[r[1]].coinblock == false and (#r == 1 or entityquads[r[2]].t ~= "manycoins") then --destroy block! 2409 destroyblock(x, y) 2410 end 2411 end 2412 2413 if #r == 1 and tilequads[r[1]].coinblock then --coinblock 2414 playsound(coinsound) 2415 if tilequads[r[1]].invisible then 2416 if spriteset == 1 then 2417 map[x][y][1] = 113 2418 elseif spriteset == 2 then 2419 map[x][y][1] = 118 2420 else 2421 map[x][y][1] = 112 2422 end 2423 else 2424 if spriteset == 1 then 2425 map[x][y][1] = 113 2426 elseif spriteset == 2 then 2427 map[x][y][1] = 114 2428 else 2429 map[x][y][1] = 117 2430 end 2431 end 2432 if #r == 1 then 2433 table.insert(coinblockanimations, coinblockanimation:new(x-0.5, y-1)) 2434 mariocoincount = mariocoincount + 1 2435 if mariocoincount == 100 then 2436 if mariolivecount ~= false then 2437 for i = 1, players do 2438 mariolives[i] = mariolives[i] + 1 2439 respawnplayers() 2440 end 2441 end 2442 mariocoincount = 0 2443 playsound(oneupsound) 2444 end 2445 addpoints(200) 2446 end 2447 end 2448 2449 if #r > 1 and entityquads[r[2]].t == "manycoins" then --block with many coins inside! yay $_$ 2450 playsound(coinsound) 2451 table.insert(coinblockanimations, coinblockanimation:new(x-0.5, y-1)) 2452 mariocoincount = mariocoincount + 1 2453 2454 if mariocoincount == 100 then 2455 if mariolivecount ~= false then 2456 for i = 1, players do 2457 mariolives[i] = mariolives[i] + 1 2458 respawnplayers() 2459 end 2460 end 2461 mariocoincount = 0 2462 playsound(oneupsound) 2463 end 2464 addpoints(200) 2465 2466 local exists = false 2467 for i = 1, #coinblocktimers do 2468 if x == coinblocktimers[i][1] and y == coinblocktimers[i][2] then 2469 exists = i 2470 end 2471 end 2472 2473 if not exists then 2474 table.insert(coinblocktimers, {x, y, coinblocktime}) 2475 elseif coinblocktimers[exists][3] <= 0 then 2476 if spriteset == 1 then 2477 map[x][y][1] = 113 2478 elseif spriteset == 2 then 2479 map[x][y][1] = 114 2480 else 2481 map[x][y][1] = 117 2482 end 2483 end 2484 end 2485 2486 --kill enemies on top 2487 for i, v in pairs(enemies) do 2488 if objects[v] then 2489 for j, w in pairs(objects[v]) do 2490 local centerX = w.x + w.width/2 2491 if inrange(centerX, x-1, x, true) and y-1 == w.y+w.height then 2492 --get dir 2493 local dir = "right" 2494 if w.x+w.width/2 < x-0.5 then 2495 dir = "left" 2496 end 2497 2498 if w.shotted then 2499 w:shotted(dir) 2500 addpoints(100, w.x+w.width/2, w.y) 2501 end 2502 end 2503 end 2504 end 2505 end 2506 2507 --make items jump 2508 for i, v in pairs(jumpitems) do 2509 for j, w in pairs(objects[v]) do 2510 local centerX = w.x + w.width/2 2511 if inrange(centerX, x-1, x, true) and y-1 == w.y+w.height then 2512 if w.jump then 2513 w:jump(x) 2514 end 2515 end 2516 end 2517 end 2518 2519 --check for coin on top 2520 if inmap(x, y-1) and tilequads[map[x][y-1][1]].coin then 2521 collectcoin(x, y-1) 2522 table.insert(coinblockanimations, coinblockanimation:new(x-0.5, y-1)) 2523 end 2524 end 2525end 2526 2527function destroyblock(x, y) 2528 for i = 1, players do 2529 local x1 = objects["player"][i].portal1X 2530 local y1 = objects["player"][i].portal1Y 2531 2532 local x2 = objects["player"][i].portal2X 2533 local y2 = objects["player"][i].portal2Y 2534 2535 local x3 = x1 2536 local y3 = y1 2537 2538 if objects["player"][i].portal1facing == "up" then 2539 x3 = x3+1 2540 elseif objects["player"][i].portal1facing == "right" then 2541 y3 = y3+1 2542 elseif objects["player"][i].portal1facing == "down" then 2543 x3 = x3-1 2544 elseif objects["player"][i].portal1facing == "left" then 2545 y3 = y3-1 2546 end 2547 2548 local x4 = x2 2549 local y4 = y2 2550 2551 if objects["player"][i].portal2facing == "up" then 2552 y4 = y4-1 2553 elseif objects["player"][i].portal2facing == "right" then 2554 x4 = x4+1 2555 elseif objects["player"][i].portal2facing == "down" then 2556 y4 = y4+1 2557 elseif objects["player"][i].portal2facing == "left" then 2558 x4 = x4-1 2559 end 2560 2561 if (x == x1 and y == y1) or (x == x2 and y == y2) or (x == x3 and y == y3) or (x == x4 and y == y4) then 2562 return 2563 end 2564 end 2565 2566 map[x][y][1] = 1 2567 objects["tile"][x .. "-" .. y] = nil 2568 map[x][y]["gels"] = {} 2569 playsound(blockbreaksound) 2570 addpoints(50) 2571 2572 table.insert(blockdebristable, blockdebris:new(x-.5, y-.5, 3.5, -23)) 2573 table.insert(blockdebristable, blockdebris:new(x-.5, y-.5, -3.5, -23)) 2574 table.insert(blockdebristable, blockdebris:new(x-.5, y-.5, 3.5, -14)) 2575 table.insert(blockdebristable, blockdebris:new(x-.5, y-.5, -3.5, -14)) 2576 2577 generatespritebatch() 2578end 2579 2580function mario:faithplate(dir) 2581 self.animationstate = "jumping" 2582 self.falling = true 2583 self:setquad() 2584end 2585 2586function mario:startfall() 2587 if self.falling == false then 2588 self.falling = true 2589 self.animationstate = "falling" 2590 self:setquad() 2591 end 2592end 2593 2594function mario:die(how) 2595 print("Death cause: " .. how) 2596 2597 if how ~= "pit" and how ~= "time" then 2598 if self.size > 1 then 2599 self:shrink() 2600 return 2601 end 2602 elseif how ~= "time" then 2603 if bonusstage then 2604 levelscreen_load("sublevel", 0) 2605 return 2606 end 2607 end 2608 2609 if editormode then 2610 self.y = 0 2611 self.speedy = 0 2612 return 2613 end 2614 self.dead = true 2615 2616 everyonedead = true 2617 for i = 1, players do 2618 if not objects["player"][i].dead then 2619 everyonedead = false 2620 end 2621 end 2622 2623 self.animationmisc = nil 2624 if everyonedead then 2625 self.animationmisc = "everyonedead" 2626 love.audio.stop() 2627 end 2628 2629 playsound(deathsound) 2630 2631 if how == "time" then 2632 noupdate = false 2633 self.quadcenterY = 10 2634 self.graphic = self.smallgraphic 2635 self.size = 1 2636 self.quadcenterX = 11 2637 self.offsetY = 3 2638 self.drawable = true 2639 end 2640 2641 if how == "pit" then 2642 self.animation = "deathpit" 2643 self.size = 1 2644 self.drawable = false 2645 self.invincible = false 2646 else 2647 self.animation = "death" 2648 self.drawable = true 2649 self.invincible = false 2650 self.animationstate = "dead" 2651 self:setquad() 2652 self.speedy = 0 2653 end 2654 2655 self.y = self.y - 1/16 2656 2657 self.animationx = self.x 2658 self.animationy = self.y 2659 self.animationtimer = 0 2660 self.controlsenabled = false 2661 self.active = false 2662 prevsublevel = nil 2663 2664 if not levelfinished and not testlevel and not infinitelives and mariolivecount ~= false then 2665 mariolives[self.playernumber] = mariolives[self.playernumber] - 1 2666 end 2667 2668 return 2669end 2670 2671function mario:laser(dir) 2672 if self.pickup then 2673 if dir == "right" and self.pointingangle < 0 then 2674 return 2675 elseif dir == "left" and self.pointingangle > 0 then 2676 return 2677 elseif dir == "up" and self.pointingangle > -math.pi/2 and self.pointingangle < math.pi/2 then 2678 return 2679 elseif dir == "down" and (self.pointingangle > math.pi/2 or self.pointingangle < -math.pi/2) then 2680 return 2681 end 2682 end 2683 self:die("Laser") 2684end 2685 2686function getAngleFrame(angle) 2687 local mouseabs = math.abs(angle) 2688 local angleframe 2689 2690 if mouseabs < math.pi/8 then 2691 angleframe = 1 2692 elseif mouseabs >= math.pi/8 and mouseabs < math.pi/8*3 then 2693 angleframe = 2 2694 elseif mouseabs >= math.pi/8*3 and mouseabs < math.pi/8*5 then 2695 angleframe = 3 2696 elseif mouseabs >= math.pi/8*5 and mouseabs < math.pi/8*7 then 2697 angleframe = 4 2698 elseif mouseabs >= math.pi/8*7 then 2699 angleframe = 4 2700 end 2701 2702 return angleframe 2703end 2704 2705function mario:emancipate(a) 2706 self:removeportals() 2707 2708 local delete = {} 2709 2710 for i, v in pairs(portalprojectiles) do 2711 if v.payload[1] == self.playernumber then 2712 table.insert(delete, i) 2713 end 2714 end 2715 2716 table.sort(delete, function(a,b) return a>b end) 2717 2718 for i, v in pairs(delete) do 2719 table.remove(portalprojectiles, v) --remove 2720 end 2721end 2722 2723function mario:removeportals(i) 2724 if self.portal1X or self.portal2X then 2725 playsound(portalfizzlesound) 2726 end 2727 2728 moveoutportal(1) 2729 moveoutportal(2) 2730 2731 if i ~= 2 then 2732 2733 if self.portal1facing == "up" then 2734 modifyportaltiles(self.portal1X, self.portal1Y, 1, 0, self.playernumber, 1, "add") 2735 elseif self.portal1facing == "down" then 2736 modifyportaltiles(self.portal1X, self.portal1Y, -1, 0, self.playernumber, 1, "add") 2737 elseif self.portal1facing == "left" then 2738 modifyportaltiles(self.portal1X, self.portal1Y, 0, -1, self.playernumber, 1, "add") 2739 elseif self.portal1facing == "right" then 2740 modifyportaltiles(self.portal1X, self.portal1Y, 0, 1, self.playernumber, 1, "add") 2741 end 2742 self.portal1X, self.portal1Y = false, false 2743 2744 objects["portalwall"][self.playernumber .. "-1-1"] = nil 2745 objects["portalwall"][self.playernumber .. "-1-2"] = nil 2746 objects["portalwall"][self.playernumber .. "-1-3"] = nil 2747 end 2748 2749 if i ~= 1 then 2750 2751 if self.portal2facing == "up" then 2752 modifyportaltiles(self.portal2X, self.portal2Y, 1, 0, self.playernumber, 2, "add") 2753 elseif self.portal2facing == "down" then 2754 modifyportaltiles(self.portal2X, self.portal2Y, -1, 0, self.playernumber, 2, "add") 2755 elseif self.portal2facing == "left" then 2756 modifyportaltiles(self.portal2X, self.portal2Y, 0, -1, self.playernumber, 2, "add") 2757 elseif self.portal2facing == "right" then 2758 modifyportaltiles(self.portal2X, self.portal2Y, 0, 1, self.playernumber, 2, "add") 2759 end 2760 self.portal2X, self.portal2Y = false, false 2761 2762 objects["portalwall"][self.playernumber .. "-2-1"] = nil 2763 objects["portalwall"][self.playernumber .. "-2-2"] = nil 2764 objects["portalwall"][self.playernumber .. "-2-3"] = nil 2765 end 2766 2767 if i ~= 2 then 2768 self.portal1facing = nil 2769 end 2770 if i ~= 1 then 2771 self.portal2facing = nil 2772 end 2773 2774 for i, v in pairs(objects["lightbridge"]) do 2775 v:updaterange() 2776 end 2777 2778 for i, v in pairs(objects["laser"]) do 2779 v:updaterange() 2780 end 2781end 2782 2783function mario:use() 2784 if self.pickup then 2785 if self.pickup.destroying then 2786 self.pickup = false 2787 else 2788 self:dropbox() 2789 return 2790 end 2791 end 2792 local xcenter = self.x + 6/16 - math.sin(self.pointingangle)*userange 2793 local ycenter = self.y + 6/16 - math.cos(self.pointingangle)*userange 2794 2795 local col = userect(xcenter-usesquaresize/2, ycenter-usesquaresize/2, usesquaresize, usesquaresize) 2796 if #col > 0 then 2797 col[1]:used(self.playernumber) 2798 end 2799end 2800 2801function mario:pickupbox(box) 2802 self.pickup = box 2803end 2804 2805function mario:dropbox() 2806 self.pickup:dropped() 2807 2808 local set = false 2809 2810 local boxx = self.x+math.sin(-self.pointingangle)*0.3 2811 local boxy = self.y-math.cos(-self.pointingangle)*0.3 2812 2813 if self.pointingangle < 0 then 2814 if #checkrect(self.x+self.width, self.y+self.height-12/16, 12/16, 12/16, {"exclude", self.pickup}, true) == 0 then 2815 self.pickup.x = self.x+self.width 2816 self.pickup.y = self.y+self.height-12/16 2817 set = true 2818 end 2819 else 2820 if #checkrect(self.x-12/16, self.y+self.height-12/16, 12/16, 12/16, {"exclude", self.pickup}, true) == 0 then 2821 self.pickup.x = self.x-12/16 2822 self.pickup.y = self.y+self.height-12/16 2823 set = true 2824 end 2825 end 2826 2827 if set == false then 2828 if #checkrect(self.x+self.width, self.y+self.height-12/16, 12/16, 12/16, {"exclude", self.pickup}, true) == 0 then 2829 self.pickup.x = self.x+self.width 2830 self.pickup.y = self.y+self.height-12/16 2831 elseif #checkrect(self.x-12/16, self.y+self.height-12/16, 12/16, 12/16, {"exclude", self.pickup}, true) == 0 then 2832 self.pickup.x = self.x-12/16 2833 self.pickup.y = self.y+self.height-12/16 2834 elseif #checkrect(self.x, self.y+self.height, 12/16, 12/16, {"exclude", self.pickup}, true) == 0 then 2835 self.pickup.x = self.x 2836 self.pickup.y = self.y+self.height 2837 elseif #checkrect(self.x, self.y-12/16, 12/16, 12/16, {"exclude", self.pickup}, true) == 0 then 2838 self.pickup.x = self.x 2839 self.pickup.y = self.y-12/16 2840 else 2841 self.pickup.x = self.x 2842 self.pickup.y = self.y 2843 end 2844 end 2845 2846 for h, u in pairs(emancipationgrills) do 2847 if u.dir == "hor" then 2848 if inrange(self.pickup.x+6/16, u.startx-1, u.endx, true) and inrange(u.y-14/16, boxy, self.pickup.y, true) then 2849 self.pickup:emancipate(h) 2850 end 2851 else 2852 if inrange(self.pickup.y+6/16, u.starty-1, u.endy, true) and inrange(u.x-14/16, boxx, self.pickup.x, true) then 2853 self.pickup:emancipate(h) 2854 end 2855 end 2856 end 2857 self.pickup = nil 2858end 2859 2860function mario:cubeemancipate() 2861 self.pickup = nil 2862end 2863 2864function mario:duck(ducking) --goose 2865 self.ducking = ducking 2866 if self.ducking then 2867 self.y = self.y + 12/16 2868 self.height = 12/16 2869 self.quadcenterY = 22 2870 self.offsetY = 7 2871 else 2872 self.y = self.y - 12/16 2873 self.height = 24/16 2874 self.quadcenterY = 20 2875 self.offsetY = -3 2876 end 2877end 2878 2879function mario:pipe(x, y, dir, i) 2880 self.active = false 2881 self.animation = "pipe" .. dir 2882 self.invincible = false 2883 self.drawable = true 2884 self.animationx = x 2885 self.animationy = y 2886 self.animationtimer = 0 2887 self.animationmisc = i 2888 self.controlsenabled = false 2889 playsound(pipesound) 2890 2891 if intermission then 2892 respawnsublevel = i 2893 end 2894 2895 if dir == "down" then 2896 if self.size > 1 then 2897 self.animationy = y - self.height + 12/16 2898 end 2899 self.animationstate = "idle" 2900 self.customscissor = {x-2, y-3, 2, 2} 2901 else 2902 if self.size == 1 then 2903 self.y = self.animationy-1/16 - self.height 2904 else 2905 self.y = self.animationy-1/16 - self.height 2906 end 2907 self.animationstate = "running" 2908 self.customscissor = {x-2, y-3, 1, 4} 2909 end 2910 2911 self:setquad() 2912end 2913 2914function mario:flag() 2915 if levelfinished then 2916 return 2917 end 2918 self.ducking = false 2919 self.animation = "flag" 2920 self.invincible = false 2921 self.drawable = true 2922 self.controlsenabled = false 2923 self.animationstate = "climbing" 2924 self.pointingangle = -math.pi/2 2925 self.animationtimer = 0 2926 self.speedx = 0 2927 self.speedy = 0 2928 self.x = flagx-2/16 2929 self.gravity = 0 2930 self.climbframe = 2 2931 self.active = false 2932 self:setquad() 2933 levelfinished = true 2934 levelfinishtype = "flag" 2935 subtractscore = false 2936 firework = false 2937 castleflagy = castleflagstarty 2938 objects["screenboundary"]["flag"].active = false 2939 2940 --get score 2941 flagscore = flagscores[1] 2942 for i = 1, #flagvalues do 2943 if self.y < flagvalues[i] then 2944 flagscore = flagscores[i+1] 2945 else 2946 break 2947 end 2948 end 2949 2950 addpoints(flagscore) 2951 2952 --get firework count 2953 fireworkcount = tonumber(string.sub(math.ceil(mariotime), -1, -1)) 2954 if fireworkcount ~= 1 and fireworkcount ~= 3 and fireworkcount ~= 6 then 2955 fireworkcount = 0 2956 end 2957 2958 if portalbackground then 2959 fireworkcount = 0 2960 end 2961 2962 love.audio.stop() 2963 2964 2965 playsound(levelendsound) 2966end 2967 2968function mario:axe() 2969 if levelfinished then 2970 return 2971 end 2972 self.ducking = false 2973 for i = 1, players do 2974 objects["player"][i]:removeportals() 2975 end 2976 2977 for i, v in pairs(objects["platform"]) do 2978 objects["platform"][i] = nil 2979 end 2980 2981 self.animation = "axe" 2982 self.invincible = false 2983 self.drawable = true 2984 self.animationx = axex 2985 self.animationy = axey 2986 self.animationbridgex = axex-1 2987 self.animationbridgey = axey+2 2988 self.controlsenabled = false 2989 self.animationtimer = 0 2990 self.speedx = 0 2991 self.speedy = 0 2992 self.gravity = 0 2993 self.active = false 2994 levelfinished = true 2995 levelfinishtype = "castle" 2996 levelfinishedmisc = 0 2997 levelfinishedmisc2 = 1 2998 if marioworld == 8 then 2999 levelfinishedmisc2 = 2 3000 end 3001 bridgedisappear = false 3002 self.animationtimer2 = castleanimationbridgedisappeardelay 3003 bowserfall = false 3004 objects["screenboundary"]["axe"] = nil 3005 3006 if objects["bowser"][1] and not objects["bowser"][1].shot then 3007 local v = objects["bowser"][1] 3008 v.speedx = 0 3009 v.speedy = 0 3010 v.active = false 3011 v.gravity = 0 3012 v.category = 1 3013 else 3014 self.animationtimer = castleanimationmariomove 3015 self.active = true 3016 self.gravity = mariogravity 3017 self.animationstate = "running" 3018 self.speedx = 4.27 3019 self.pointingangle = -math.pi/2 3020 3021 love.audio.stop() 3022 playsound(castleendsound) 3023 end 3024 3025 axex = false 3026 axey = false 3027end 3028 3029function mario:vineanimation() 3030 self.animation = "vine" 3031 self.invincible = false 3032 self.drawable = true 3033 self.controlsenabled = false 3034 self.animationx = self.x 3035 self.animationy = vineanimationstart 3036 self.animationmisc = map[self.vinex][self.viney][3] 3037 self.active = false 3038 self.vine = false 3039end 3040 3041function mario:star() 3042 addpoints(1000) 3043 self.startimer = 0 3044 self.colors = starcolors[1] 3045 self.starred = true 3046 stopmusic() 3047 music:play("starmusic") 3048end 3049 3050function mario:fire() 3051 if not noupdate and self.controlsenabled and self.size == 3 and self.ducking == false then 3052 if self.fireballcount < maxfireballs then 3053 local dir = "right" 3054 if self.pointingangle > 0 then 3055 dir = "left" 3056 end 3057 table.insert(objects["fireball"], fireball:new(self.x+.5, self.y, dir, self)) 3058 self.fireballcount = self.fireballcount + 1 3059 self.fireanimationtimer = 0 3060 self:setquad() 3061 playsound(fireballsound) 3062 end 3063 end 3064end 3065 3066function mario:fireballcallback() 3067 self.fireballcount = self.fireballcount - 1 3068end 3069 3070function collectcoin(x, y) 3071 map[x][y][1] = 1 3072 addpoints(200) 3073 playsound(coinsound) 3074 mariocoincount = mariocoincount + 1 3075 if mariocoincount == 100 then 3076 if mariolivecount ~= false then 3077 for i = 1, players do 3078 mariolives[i] = mariolives[i] + 1 3079 respawnplayers() 3080 end 3081 end 3082 mariocoincount = 0 3083 playsound(oneupsound) 3084 end 3085end 3086 3087function mario:portaled(dir) 3088 if self.pickup then 3089 self.pickup:portaled() 3090 end 3091 if not sonicrainboom or not self.rainboomallowed then 3092 return 3093 end 3094 3095 local didrainboom = false 3096 3097 if dir == "up" then 3098 if self.speedy < -rainboomspeed then 3099 didrainboom = true 3100 end 3101 elseif dir == "left" then 3102 if self.speedx < -rainboomspeed then 3103 didrainboom = true 3104 end 3105 elseif dir == "right" then 3106 if self.speedx > rainboomspeed then 3107 didrainboom = true 3108 end 3109 end 3110 3111 if didrainboom then 3112 table.insert(rainbooms, rainboom:new(self.x+self.width/2, self.y+self.height/2, dir)) 3113 earthquake = rainboomearthquake 3114 self.rainboomallowed = false 3115 playsound(rainboomsound) 3116 3117 for i, v in pairs(enemies) do 3118 if objects[v] then 3119 for j, w in pairs(objects[v]) do 3120 w:shotted() 3121 if v ~= "bowser" then 3122 addpoints(firepoints[v], w.x, w.y) 3123 else 3124 for i = 1, 6 do 3125 w:shotted() 3126 end 3127 end 3128 end 3129 end 3130 end 3131 3132 self.hats = {33} 3133 end 3134end 3135 3136function mario:shootgel(i) 3137 table.insert(objects["gel"], gel:new(self.x+self.width/2+8/16, self.y+self.height/2+6/16, i)) 3138 3139 local xspeed = math.cos(-self.pointingangle-math.pi/2)*gelcannonspeed 3140 local yspeed = math.sin(-self.pointingangle-math.pi/2)*gelcannonspeed 3141 3142 objects["gel"][#objects["gel"]].speedy = yspeed 3143 objects["gel"][#objects["gel"]].speedx = xspeed 3144end 3145 3146function mario:respawn() 3147 if mariolivecount ~= false and (mariolives[self.playernumber] == 0 or levelfinished) then 3148 return 3149 end 3150 3151 local i = 1 3152 while i <= players and (objects["player"][i].dead or self.playernumber == i) do 3153 i = i + 1 3154 end 3155 3156 fastestplayer = objects["player"][i] 3157 3158 for i = 2, players do 3159 if objects["player"][i].x > fastestplayer.x and not objects["player"][i].dead then 3160 fastestplayer = objects["player"][i] 3161 end 3162 end 3163 3164 self.colors = mariocolors[self.playernumber] 3165 self.speedy = 0 3166 self.speedx = 0 3167 self.dead = false 3168 self.quadcenterY = 10 3169 self.height = 12/16 3170 self.graphic = self.smallgraphic 3171 self.size = 1 3172 self.quadcenterX = 11 3173 self.offsetY = 3 3174 self.drawable = true 3175 self.animationstate = "idle" 3176 self:setquad() 3177 3178 self.animation = "invincible" 3179 self.invincible = true 3180 self.animationtimer = 0 3181 3182 self.y = fastestplayer.y + fastestplayer.height-12/16 3183 self.x = fastestplayer.x 3184 3185 self.jumping = false 3186 self.falling = true 3187 3188 self.controlsenabled = true 3189 self.active = true 3190end 3191