Keiko.lua
From Pocket Rumble Wiki
keiko.lua[edit]
local catWidth = 12 * gameLogicMult; local catXOffset = 4 * gameLogicMult; Keiko = { moves = { standA = { attackbox = {pushback=189 * gameLogicMult, hitStun=12, width=17 * gameLogicMult, height=11 * gameLogicMult, dmg=1, relativeY=8 * gameLogicMult, explosionX = 3 * gameLogicMult, priority = 4}; { frames = {1,2,2,1,3,1}; custom = function(self) self:executeSound('lightWhiff', {"sfx", "whiff"}) end }; { type = "active"; frames = {4,2,5,2}; custom = function(self) self:executeEffect("standAEffect") end }; { type = "recovery"; frames = {6,2,7,1}; }; }; lowA = { special=true; attackbox = {pushback=133 * gameLogicMult, hitStun=16, width=24 * gameLogicMult, height=11 * gameLogicMult, dmg=1, relativeY=25 * gameLogicMult, explosionX = -6, explosionY = 2, priority = 4}; { frames = {1,2,2,2,3,1}; custom = function(self) self:executeSound('mediumWhiff', {"sfx", "whiff"}) end }; { type = "active"; frames = {4,2,5,2,6,2,7,3}; custom = function(self) self:executeEffect("lowAEffect") end }; { type = "recovery"; frames = {9,2,10,2}; }; }; standB = { special=true; attackbox = {pushback=220 * gameLogicMult, hitStun=18, width=25 * gameLogicMult, height=14 * gameLogicMult, relativeY = 12 * gameLogicMult, dmg=1, explosionX = -4 * gameLogicMult, explosionY = -1 * gameLogicMult, priority = 3}; { --hitStun=16 pushback=220 frames = {1,2,2,2,3,2,4,1}; --1,4,2,2,3,2 1,3,2,2,3,2 custom = function(self) self:executeSound('mediumWhiff', {"sfx", "whiff"}) end }; { type = "active"; frames = {6,2,7,2,6,2,7,2,8,2,9,2}; --12 custom = function(self) self:executeEffect("standBEffect") end }; { type = "recovery"; frames = {10,2,12,2}; --5,1,6,2,7,2,8,2,9,1,10,1,11,3 }; }; lowB = { special=true; attackbox = {pushUp = 130*gameLogicMult,pushback=60 * gameLogicMult, hitStun=17, width=30 * gameLogicMult, height=12 * gameLogicMult, dmg=1, relativeY=26 * gameLogicMult, explosionX = -8 - (4 * gameLogicMult), explosionY = 2, priority = 3}; { frames = {1,1,2,2,3,2,4,1}; --6 custom = function(self) self:executeSound('heavyWhiff', {"sfx", "whiff"}) end }; { type = "active"; frames = {5,2,6,2,7,2,8,2,9,2,10,2,11,2,12,2}; --18 custom = function(self) self:executeEffect("lowBEffect") end }; { type = "recovery"; frames = {13,2,14,4,15,4}; --8,3,9,3,10,3,11,3,12,3,13,3,14,3,15,3 }; }; jumpA = { attackbox = {pushback=145 * gameLogicMult, hitStun=14, width=22 * gameLogicMult, height=11 * gameLogicMult, dmg=1, relativeY=22 * gameLogicMult, explosionX = -10 + (5 * gameLogicMult), priority = 4, ignoreCornerPush=true}; --hitstun=16,pushback=145 { frames = {2,1,3,2,4,2,5,2}; --7 custom = function(self) self.ABTimer = 0 self:executeSound('mediumWhiff', {"sfx", "whiff"}) end }; { type = "active"; frames = {6,2,7,2,8,2,9,2,6,2,7,1}; --11 custom = function(self) self:executeEffect("jumpAEffect") end }; { type = "recovery"; frames = {10,2,11,3,12,2}; --7 }; endWith = function(self) self:executeAnimation("jumpA", { frames={1,15}; }); end }; jumpB = { attackbox = {pushback=44 * gameLogicMult, hitStun=20, width=11 * gameLogicMult, height=20 * gameLogicMult, dmg=1, relativeX= (-16 * gameLogicMult), relativeY=22 * gameLogicMult, explosionX = -4 * gameLogicMult,explosionY = 20, priority = 3, ignoreCornerPush=true}; --pushback=66 * gameLogicMult hitstun=23 { --hitstun=22 frames = {2,2,4,3,5,2,6,2};--9 custom = function(self) self.ABTimer = 0 self:executeSound('mediumWhiff', {"sfx", "whiff"}) end }; { type = "active"; frames = {7,2,8,2,9,2,10,2,11,2,12,2,13,1}; --4,5,5,5,4,5,5,5,4,5 custom = function(self) self:executeEffect("jumpBEffect") end }; { type = "recovery"; frames = {19,3,20,2,21,2}; }; endWith = function(self) self:executeAnimation("jumpUp", { frames={5,4,6,4,7,4,8,4,9,10}; }); end }; -- neutralAB = { -- attackbox = {pushUp=200*gameLogicMult,pushback=44 * gameLogicMult, hitStun=20, width=70 * gameLogicMult, height=80 * gameLogicMult, dmg=0, relativeX= (-45 * gameLogicMult), -- relativeY=-20 * gameLogicMult, explosionX = -4 * gameLogicMult,explosionY = 20, priority = 3, ignoreCornerPush=true, resetY=false}; -- { -- frames = {5,4}; -- custom = function(self) -- self.ySpeed = -1000; -- end -- }; -- { -- type = "active"; -- frames = {5,5}; -- custom = function(self) -- self.ignoreGravity = true -- self.ySpeed = 0 -- end -- }; -- { -- type = "recovery"; -- frames = {5,20,5,10}; -- custom = function(self) -- self.ignoreGravity = false -- -- self.ySpeed = 100 -- end -- }; -- }; }; animations = { idle = { --frames = {1,4,2,4,3,4,4,4,5,4,6,4,7,4,8,4,9,4,10,4,11,4,12,4,13,4,14,4,15,4,16,4,17,4,18,4,19,4,20,4,21,4,22,4,23,4,24,4,25,4,26,4,27,4,28,4,29,4,30,4,31,4,32,4}; frames = {1,4,2,3,3,4,4,4,5,4,6,4,7,4,8,4,9,4,10,3,11,4,12,4,13,4,14,4,15,4,16,4}; }; crouch = { frames = {1,3,2,3,3,3,4,3,5,3,6,3,7,3,8,3,9,3,10,3,11,6,12,6,13,3,14,3,15,3,16,3,17,6,18,3,19,3}; }; turn = { frames = {1,4}; }; crouchTurn = { frames = {1,4}; }; walkBack = { frames = {2,4,3,3,4,4,5,3,6,4,7,3,8,4,9,3,10,4,11,3,12,4,13,3,14,4,15,3,16,4,1,3}; }; walkForward = { frames = {1,3,2,3,3,3,4,4,5,4,6,3,7,3,8,3,9,3,10,3,11,3,12,4,13,4,14,3,15,3,16,3}; }; jumpUp = { endWith = "nothing"; frames={2,4,3,4,4,4,5,4,6,4,7,4,8,4,9,10}; }; jumpForward = { endWith = "nothing"; spriteName = "jumpUp"; frames={2,4,3,4,4,4,5,4,6,4,7,4,8,4,9,10}; }; jumpBack = { endWith = "nothing"; spriteName = "jumpUp"; frames={2,4,3,4,4,4,5,4,6,4,7,4,8,4,9,10}; }; land = { spriteName = "jumpUp"; frames = {10,2,11,4,12,2}; }; standTransition = { frames={1,2,2,2}; }; crouchTransition = { frames={1,2,2,2}; }; airHurt = { endWith = "nothing"; { frames = {1,1,2,3,3,3}; }; { spriteName = "jumpUp"; frames = {5,4,6,4,7,4,8,4,9,10}; }; }; knockdown = { endWith = "nothing"; frames = {1,2,2,3,3,3,4,3,5,2}; }; impact = { spriteName = "knockdown"; frames = {6,1,7,2} }; startGroundBounce = { spriteName = "knockdown"; frames = {8,2,9,2,10,2,11,7} }; stopGroundBounce = { spriteName = "knockdown"; frames = {12,2,13,10} }; wakeup = { spriteName = "knockdown"; frames = {14,3,15,3,16,4} }; death = { spriteName = "knockdown"; endWith = "nothing"; frames = {13,1} }; preBlock={ spriteName="blockStand"; endWith = "nothing"; frames = {1,1,2,1,3,1}; }; preBlockReverse={ spriteName="blockStand"; frames = {2,1,1,2}; }; preBlockCrouch={ endWith = "nothing"; spriteName="blockCrouch"; frames={1,2,2,1}; }; preBlockCrouchReverse={ spriteName="blockCrouch"; frames={1,2}; }; chipDeath = { endWith = "nothing"; { frames={1,3,2,3}; custom=function(self) self.enemy:drawFirst() end }; { frames={3,3,4,3,5,3,6,3}; custom = function(self) self:executeSound("chipDeath", {"sfx"}) end }; { frames={7,3}; custom = function(self) self:executeSound("chipDeath", {"sfx"}) end }; { frames={8,1}; custom = function(self) koFinish = true end }; }; yay = { frames = {1,16,2,3,3,3,4,3,5,3,6,3,7,3,8,3,9,3,10,4,11,4,12,5,13,5,14,5,15,5,16,5,17,5,18,5,19,5,20,5,}; endWith = function(self) self:executeAnimation("yayLoop") end }; yayLoop = { spriteName = "yay"; frames = {21,5,22,5,23,5,24,10,25,10,26,5,27,5,28,5,29,5,30,5,31,5,32,5,33,5}; }; boo = { frames = {1,16,2,3,3,3,4,3,5,3,6,3,7,3,8,3,9,3,10,3,11,3,12,3,13,3,14,3,15,15}; endWith = function(self) self:executeAnimation("booLoop") end }; booLoop = { spriteName = "boo"; frames = {16,6,17,30,18,6,19,30,20,6,21,3,22,3,23,3,24,6,25,3,26,3,27,3,28,6,16,6,15,30}; custom = function(self) self:executeEffect("rain") end }; win = { frames = {1,4,2,4,3,4,4,4, 5,5,6,4,7,5,8,4, 5,5,6,4,7,5,8,4, 5,5,6,4,7,5,8,4, 5,5,6,4,7,5,8,4, 5,5,6,4,7,5,8,4, 5,5,6,4,7,5,8,4, 5,5,6,4,7,5,8,4, 5,5,6,4,7,5,8,4, 5,5,6,4,7,5,8,4, 5,5,6,4,7,5,8,4, 5,5,6,4,7,5,8,4}; }; }; throw = { enemyFrames = { {5,27,-5}, --f1 {6,20,-5}, --f2 {7,19,-5}, --f3 {8,20,-5}, --f4 {10,20,-8}, --f5 {9,21,-7}, --f6 {8,21,-5}, --f7 {10,27,-8}, --f8 {0,0,0}, --f9 {0,0,0}, --f10 {0,0,0}, --f11 {0,0,0}, --f12 {0,0,0}, --f13 {0,0,0}, --f14 {0,0,0}, --f15 {8,21,-5}, --f16 {8,24,-5}, --f17 {8,25,-5}, --f18 {8,25,-6}, --f19 {9,22,-7}, --f20 {9,20,-7}, --f21 {9,16,-7}, --f22 {1,9,-12}, --f23 {4,-13,-11}, --f24 {0,0,0}, --f25 {0,0,0}, --f26 {0,0,0}, --f27 {0,0,0}, --f28 {0,0,0}, --f29 {0,0,0}, --f30 {0,0,0}, --f31 {0,0,0}, --f32 {0,0,0}, --f33 {0,0,0}, --f34 {0,0,0}, --f35 }; start = { {frames = {1,3,2,3,3,3,4,3}}; --5,2,6,4 --1,4,2,4,3,4,4,2,5,1,6,1 }; forward = { { frames = {5,3,6,3}; --8,4,9,4,10,4,11,4 custom = function(self) self:executeEffect("throwEffect1") self:throwHitstop(6, 24, 14) cameraJitterX = 2 self.combo = self.combo + 1 self.enemy:changeHealth(1) self:executeSound(self.hitSpecialSFX, "sfx") end }; { frames = {7,20,8,2}; --11,4,13,2,14,2,15,2 -- data = {dmg = 1, hitstop = 9, explosionX= 101, explosionY = 101, changeLocation = 90, changeSpeed = 350, changeYSpeed = -600}; }; { frames = {9,3,10,3,11,3,12,10,13,3,14,3}; custom = function(self) self:executeEffect("throwEffect2") self.combo = self.combo + 1 self.enemy:changeHealth(1) self:executeSound(self.hitSpecialSFX, "sfx") self:throwHitstop(8, 30, 20) cameraJitterX = 2 self.enemy:changeLocation(30) self.enemy:changeSpeed(300) self.enemy.ySpeed = -250 self.enemy.y = self.enemy.y + 20 self.enemy.ignoreGravity = false self.enemy:knockFall() self.ignoreFloor = false self.enemy.ignoreFloor = false end }; }; backward = { { frames = {5,3,6,3}; --8,4,9,4,10,4,11,4 custom = function(self) self:executeEffect("throwEffect1") self:throwHitstop(6, 24, 14) cameraJitterX = 2 self.combo = self.combo + 1 self.enemy:changeHealth(1) self:executeSound(self.hitSpecialSFX, "sfx") end }; { frames = {16,2,17,2,18,2,19,2,20,2,21,2,22,2}; --21,4,22,4,23,4 data = {dmg = 1, changeLocation = 10, changeSpeed = 500, changeYSpeed = -600}; }; { frames = {23,2,24,2}; --21,4,22,4,23,4 custom = function(self) self:reverseDrawOrder() end }; { frames = {25,3,26,3,27,3,28,3,29,3,30,3,31,3,32,2,33,2,34,2}; custom = function(self) self.combo = self.combo + 1 self.enemy:changeHealth(1) self:executeSound('grab', "sfx") self.enemy:changeSpeed(-400) self.enemy.ySpeed = -200 self.enemy.y = self.enemy.y + 20 self.enemy.ignoreGravity = false self.ignoreCollision = false self.enemy:knockFall() self.enemy.animation:gotoFrame(5) self.faceRight = not self.faceRight self.ignoreFloor = false self.enemy.ignoreFloor = false end }; { custom = function(self) self:changeLocation(-4) end }; }; }; effects = { hitEffect = { frames = {1,2,2,2,3,2,4,1,5,1,6,1,7,2,8,2,9,2,10,1,11,2,12,1,13,1,0,1,13,1}; }; standAEffect = { frames = {1,3,2,3,3,3,4,3}; relativeX = 16 * gameLogicMult; relativeY = -11 * gameLogicMult; followPlayer = true; ignoreParry = true; destroyWhenPlayerHurt = true; }; standBEffect = { frames = {3,2,4,2,1,2,2,2,3,2,4,2,5,3,6,3}; relativeX = 24 * gameLogicMult; relativeY = -2 * gameLogicMult; followPlayer = true; ignoreParry = true; destroyWhenPlayerHurt = true; }; lowAEffect = { frames = {1,3,2,3,3,3,4,3,5,3}; relativeX = 16 * gameLogicMult; relativeY = 13 * gameLogicMult; followPlayer = true; ignoreParry = true; destroyWhenPlayerHurt = true; }; lowBEffect = { frames = {1,3,2,3,3,3,4,3,5,3,6,3,8,3,9,3}; relativeX = 18 * gameLogicMult; relativeY = 15 * gameLogicMult; followPlayer = true; ignoreParry = true; destroyWhenPlayerHurt = true; }; jumpAEffect = { frames = {1,2,2,2,3,2,4,2,1,2,2,2,5,2}; relativeX = 21 * gameLogicMult; relativeY = 20 * gameLogicMult; followPlayer = true; ignoreParry = true; destroyWhenPlayerHurt = true; destroyWhenPlayerLand = true; }; jumpBEffect = { spriteName = "standBEffect"; frames = {3,2,4,2,1,2,2,2,3,2,4,2,1,1,5,3,6,3}; relativeX = -6 * gameLogicMult; relativeY = 18 * gameLogicMult; followPlayer = true; ignoreParry = true; destroyWhenPlayerHurt = true; destroyWhenPlayerLand = true; }; catDownBackB = { layer = "bottom"; relativeY = -36 * gameLogicMult; relativeX = (-36 + 17) * gameLogicMult; { frames = {4,2,5,2,6,2,7,2,8,2,9,2,10,3,11,3,12,3,13,3,14,3,15,3,16,2,17,2,18,2,19,2,20,2,21,2,22,2,23,2,24,2} }; { custom = function(self) self.exists = false end }; }; catDownForwardB = { --layer = "bottom"; relativeY = -16 * gameLogicMult; relativeX = (-36 + 17) * gameLogicMult; { frames = {1,2,2,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2,14,2,15,2,16,2,17,2,18,2,19,2,20,2,21,2,22,2,23,2,24,2,25,2,26,2,27,2,28,2,29,2,30,2,31,2,32,2,33,2}; }; { custom = function(self) self.exists = false end }; }; catDownForwardA = { relativeY = -30 *gameLogicMult; relativeX = -25 * gameLogicMult; { frames = {1,2,2,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2,14,2,15,2}; }; { custom = function(self) self.exists = false end }; }; catIdle = { frames = {1,4,2,4,3,3,4,3,5,3,6,3,7,6,8,3,9,3,10,3,11,3,12,3,13,3,14,12}; relativeX = -20; relativeY = -6; layer = "bottom"; }; catTurn = { frames = {1,3}; relativeX = -20; relativeY = -6; layer = "bottom"; }; catHurt = { relativeX = -28; relativeY = -18; layer = "bottom"; { frames = {1,2,2,2,3,2,4,2}; }; { frames = {5,2,6,2,7,2,8,2}; --Cat is spinning in a ball in this part, can loop if necessary to fill out arc of flying through the air }; { frames = {9,2,10,2,11,2,12,2}; --16 --Frame 9 is impact with the ground, frame 13 is death/laying there frame }; -- { -- frames = {14,2,15,2}; -- }; { custom = function(self) self.exists = false end }; }; catWakeup = { spriteName = "catHurt"; relativeX = -28; relativeY = -18 - 8*gameLogicMult; layer = "bottom"; { frames = {13,56}; --This whole thing is a wakeup animation where the cat like shakes off a bit, we can maybe recycle most of this for the special move recovery }; { custom = function(self) self.exists = false end }; }; catWakeupTwo = { spriteName = "catHurt"; relativeX = -28; relativeY = -18; layer = "bottom"; { frames = {14,2,15,2,16,2,17,2,18,2,19,2,20,2,21,2,22,2,23,2,24,2,25,2}; --This whole thing is a wakeup animation where the cat like shakes off a bit, we can maybe recycle most of this for the special move recovery }; { custom = function(self) self.exists = false end }; }; catDeath = { endWith = "nothing"; spriteName = "catHurt"; relativeX = -28; relativeY = -18; layer = "bottom"; { frames = {1,2,2,2,3,2,4,2}; }; { frames = {5,2,6,2,7,2,8,2}; --Cat is spinning in a ball in this part, can loop if necessary to fill out arc of flying through the air }; { frames = {13,2,26,2,27,2,28,1}; --Frame 9 is impact with the ground, frame 13 is death/laying there frame }; }; catStartup = { relativeX = -20; relativeY = -6; frames = {1,4,2,4,3,4,5,4,6,4,7,4}; }; catRecovery = { { frames = {1,1,2,1,3,2,4,3,5,3,6,3,7,3,8,3,9,3,10,3,11,3,12,3,13,3,14,2,15,2,16,2,17,2,18,1,19,2}; --354 }; { custom = function(self) self.exists = false end }; relativeX = -20; relativeY = -12; layer = "bottom"; }; hitEffectCat = { layer = "hit"; frames = {1,3,2,3,3,2,4,2,2,1}; }; catDash = { relativeY = -8*gameLogicMult; relativeX = -9*gameLogicMult; { frames = {1,2,2,2,3,2,4,2,5,6,6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2}; --26 }; { custom = function(self) self.exists = false end }; }; catDashStart = { spriteName = "catDash"; relativeY = -8*gameLogicMult; relativeX = -9*gameLogicMult; { frames = {1,10,2,2,3,2,4,2,5,6,6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2}; --26 }; { custom = function(self) self.exists = false end }; }; catDashBack = { relativeY = -8*gameLogicMult; relativeX = -4*gameLogicMult; { frames = {1,2,2,2,3,2,4,2,5,2,6,2,7,6,8,2,9,2,10,2,11,2,12,2,13,2}; --26 }; { custom = function(self) self.exists = false end }; }; catNeutralAB = { relativeY = -28 *gameLogicMult; relativeX = -19 * gameLogicMult; { frames = {1,2,2,2,3,2,4,2,5,2,6,2,7,2,8,3,9,3,10,3,11,3,12,3,13,3}; }; { custom = function(self) self.exists = false end }; }; catDownBackA = { layer = "bottom"; relativeX = -12*gameLogicMult; relativeY = -15*gameLogicMult; { frames = {1,2,2,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2,14,2,15,2,16,2,17,2,18,2,19,2,20,2}; }; { custom = function(self) self.exists = false end }; }; throwEffect1 = { spriteName = "throwEffects"; relativeX = -30*gameLogicMult; frames = {1,2,2,2,3,2,4,2,5,2}; }; throwEffect2 = { spriteName = "throwEffects"; relativeX = -30*gameLogicMult; frames = {6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2,14,2}; }; rain = { frames = {1,2,2,2,3,2,4,2}; relativeX = -11 * gameLogicMult; relativeY = -11 * gameLogicMult; endWith = "loop"; flicker = true; }; }; nameplate = { frames = {1,5,2,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2,14,2,15,2,16,2,17,2,18,2,19,2,20,2,21,2,22,2,23,2,24,2,25,2,26,2,27,2,28,2,29,2,30,2,31,2,32,2,33,2,34,2,35,2,36,2,37,2,38,2,39,2,40,2,41,2,42,2,43,2,44,2,45,2,46,2}; custom = function(self, host) if host.player1 == true then host:executeSound("nameplate", {"sfx", "nameplate1"}, -1) else host:executeSound("nameplate", {"sfx", "nameplate2"}, 1) end end; }; projectiles = { catDownBackBStartup = { sfx = "launch"; effect = "catStartup"; lifetime = 10; noAttackbox = false; stayOnScreen = true; width = catWidth; height = 6 * gameLogicMult; relativeX = 0 * gameLogicMult; relativeY = 0 * gameLogicMult; ignoreProjectileCollision = true; priority = 4; onDestroy = function(self, host) if self.exists then if self.lifetime == 0 then self.liveEffect.exists = false self.exists = false host:newCatProjectile(self, "catDownBackB") end end end }; catDownBackAStartup = { sfx = "launch"; effect = "catStartup"; lifetime = 10; noAttackbox = false; stayOnScreen = true; width = catWidth; height = 6 * gameLogicMult; relativeX = 0 * gameLogicMult; relativeY = 0 * gameLogicMult; ignoreProjectileCollision = true; priority = 4; onDestroy = function(self, host) if self.exists then if self.lifetime == 0 then self.liveEffect.exists = false self.exists = false host:newCatProjectile(self, "catDownBackA") end end end }; catDownForwardBStartup = { sfx = "launch"; effect = "catStartup"; lifetime = 10; noAttackbox = false; stayOnScreen = true; width = catWidth; height = 6 * gameLogicMult; relativeX = 0 * gameLogicMult; relativeY = 0 * gameLogicMult; ignoreProjectileCollision = true; priority = 4; onDestroy = function(self, host) if self.exists then if self.lifetime == 0 then self.liveEffect.exists = false self.exists = false host:newCatProjectile(self, "catDownForwardB") end end end }; catDownForwardAStartup = { sfx = "launch"; effect = "catStartup"; lifetime = 10; noAttackbox = false; stayOnScreen = true; width = catWidth; height = 6 * gameLogicMult; relativeX = 0 * gameLogicMult; relativeY = 0 * gameLogicMult; ignoreProjectileCollision = true; priority = 4; onDestroy = function(self, host) if self.exists then if self.lifetime == 0 then self.liveEffect.exists = false self.exists = false host:newCatProjectile(self, "catDownForwardA") end end end }; catIdle = { xSpeed = 0; --default 350 relativeX = -100 *gameLogicMult; --29*gameLogicMult relativeY = 30 *gameLogicMult; width = catWidth; height = 14 * gameLogicMult; noAttackbox = true; updateDuringHitstop = true; stayOnScreen = true; onSpawn = function(self, host) if (self.host.enemy.x + self.host.enemy.width/2) < (self.x + self.width/2) then if self.flip ~= -1 then if self.host.enemy.x >= stageWidth - self.host.enemy.width - (12 * gameLogicMult) then return end self.flip = -1 self.liveEffect.flip = -1 self:placeProjectileEffect("catIdle") end else if self.flip ~= 1 then if self.host.enemy.x <= (12 * gameLogicMult) then return end self.flip = 1 self.liveEffect.flip = 1 self:placeProjectileEffect("catIdle") end end end; onUpdate = function(self) if (self.host.enemy.x + self.host.enemy.width/2) < (self.x + self.width/2) then if self.flip ~= -1 then if self.host.enemy.x >= stageWidth - self.host.enemy.width - (12 * gameLogicMult) then return end self.flip = -1 self.liveEffect.flip = -1 self:placeProjectileEffect("catIdle") end else if self.flip ~= 1 then if self.host.enemy.x <= (12 * gameLogicMult) then return end self.flip = 1 self.liveEffect.flip = 1 self:placeProjectileEffect("catIdle") end end end; onEnemyAttackboxCollide = function(self, host, enemyFlip) host:changeMeter(-1) self.exists = false if host.meterAmount > 0 then host:newCatProjectile(self, "catHurt", nil, nil,-enemyFlip) else host:newCatProjectile(self, "catDeath",nil, nil, -enemyFlip) end end; }; catDeath = { relativeX = 0; relativeY = 0; noAttackbox = true; width = catWidth; height = 6 * gameLogicMult; xSpeed = -400; decay = 25; stayOnScreen = true; updateDuringHitstop = true; }; catHurt = { sfx = "lightAttack"; xSpeed = -400; --default 350 -- ySpeed = -200; decay = 25; relativeX = 0; relativeY = 0; lifetime = 65 - 24 + 4 + 30 - 50; width = catWidth; height = 6 * gameLogicMult; noAttackbox = true; updateDuringHitstop = true; stayOnScreen = true; onDestroy = function(self, host) if self.exists and self.lifetime == 0 then self.exists = false host:newCatProjectile(self, "catWakeup", self.x, self.y + 8*gameLogicMult) end end; }; catWakeup = { -- xSpeed = -400; --default 350 -- ySpeed = -200; -- decay = 25; relativeX = 0; relativeY = 0; lifetime = 56; --20+50 width = catWidth; height = 6 * gameLogicMult; noAttackbox = true; updateDuringHitstop = true; stayOnScreen = true; onDestroy = function(self, host) if self.exists and self.lifetime == 0 then self.exists = false host:newCatProjectile(self, "catWakeupTwo", self.x, self.y - 8*gameLogicMult) end end; onEnemyAttackboxCollide = function(self, host, enemyFlip) host:changeMeter(-1) self.exists = false self.liveEffect.exists = false if host.meterAmount > 0 then host:newCatProjectile(self, "catHurt", nil, self.y - 8*gameLogicMult,-enemyFlip) else host:newCatProjectile(self, "catDeath",nil, self.y - 8*gameLogicMult, -enemyFlip) end end; }; catWakeupTwo = { relativeX = 0; relativeY = 0; lifetime = 20+50-46; width = catWidth; height = 14 * gameLogicMult; noAttackbox = true; updateDuringHitstop = true; stayOnScreen = true; onDestroy = function(self, host) if self.exists and self.lifetime == 0 then self.exists = false host:newCatProjectile(self, "catIdle", self.x, self.y) end end; onEnemyAttackboxCollide = function(self, host, enemyFlip) host:changeMeter(-1) self.exists = false self.liveEffect.exists = false if host.meterAmount > 0 then host:newCatProjectile(self, "catHurt", nil, self.y,-enemyFlip) else host:newCatProjectile(self, "catDeath",nil, nil, -enemyFlip) end end; }; catRecovery = { sfx = "jump"; lifetime = 45; relativeX = 0; relativeY = 0; width = catWidth; height = 14 * gameLogicMult; noAttackbox = true; stayOnScreen = true; onDestroy = function(self, host) if self.exists then self.exists = false self.host:newCatProjectile(self, "catIdle", self.x, self.y) end end; onEnemyAttackboxCollide = function(self, host, enemyFlip) host:changeMeter(-1) self.exists = false self.liveEffect.exists = false if host.meterAmount > 0 then host:newCatProjectile(self, "catHurt", nil, nil,-enemyFlip) else host:newCatProjectile(self, "catDeath",nil, nil, -enemyFlip) end end; }; catDash = { sfx = "jump"; xSpeed = 800; --default 350 decay = 50; relativeX = 0; relativeY = 0; lifetime = 30; width = catWidth; height = 14 * gameLogicMult; noAttackbox = true; updateDuringHitstop = true; stayOnScreen = true; onDestroy = function(self, host) if self.exists and self.lifetime == 0 then self.exists = false host:newCatProjectile(self, "catIdle", self.x, self.y) end end; onEnemyAttackboxCollide = function(self, host, enemyFlip) host:changeMeter(-1) self.exists = false self.liveEffect.exists = false if host.meterAmount > 0 then host:newCatProjectile(self, "catHurt", nil, nil,-enemyFlip) else host:newCatProjectile(self, "catDeath",nil, nil, -enemyFlip) end end; }; catDashStart = { effect = "catDashStart"; xSpeed = 1200; --default 350 decay = 50; relativeX = 0; relativeY = 0; lifetime = 38; width = catWidth; height = 6 * gameLogicMult; noAttackbox = true; updateDuringHitstop = true; -- stayOnScreen = true; onDestroy = function(self, host) if self.exists and self.lifetime == 0 then self.exists = false host:newCatProjectile(self, "catIdle", self.x, self.y) end end; onLeaveScreen = function(self) --nothing end }; catDownBackB = { sfx = "heavyRush"; lifetime = 48; dontKillEffect = true; xSpeed = 0; relativeX = -12 *gameLogicMult; --doesn't matter relativeY = -54 *gameLogicMult; pushUp = 280 * gameLogicMult; width = 40 * gameLogicMult; --32 height = 60 * gameLogicMult; updateDuringHitstop = true; ignoreProjectileCollision = true; priority = 4; customEffect = "hitEffectCat"; -- noAttackbox = true; onUpdate = function(self) if self.lifetime == 48 then self.hitStun = 16; --this activates the projectile as an attack elseif self.lifetime == 10 then self.hitStun = nil; end end; onDestroy = function(self, host) if self.exists then self.noAttackbox = true if self.lifetime == 0 then self.exists = false if self.flip == -1 then host:newCatProjectile(self, "catRecovery", self.x + self.width/2 - catXOffset, self.y + 54 * gameLogicMult) else host:newCatProjectile(self, "catRecovery", self.x + self.width/2 - catWidth + catXOffset, self.y + 54 * gameLogicMult) end end end end; onLeaveScreen = function(self) --don't do anything (if this didn't exist, the projectile would die) end }; catNeutralAB = { sfx = "naomiDP"; dontKillSFX = true; lifetime = 25; relativeX = -31 * gameLogicMult; relativeY = -40 * gameLogicMult; width = 80 * gameLogicMult; height = 60 * gameLogicMult; pushUp = 300 * gameLogicMult; hitStun = 8; customEffect = "hitEffectCat"; dontKillEffect = true; onUpdate = function(self, host) if self.lifetime == 25 then self.host:changeMeter(-8) end end; }; catDownBackA = { sfx = "downBackA"; lifetime = 30; dontKillEffect = true; -- xSpeed = 250; relativeX = -50 *gameLogicMult; --doesn't matter relativeY = 8 *gameLogicMult; pushUp = 140 * gameLogicMult; explosionX = -50 * gameLogicMult; width = 100 * gameLogicMult; height = 6 * gameLogicMult; attacktype = attackTypes.low; updateDuringHitstop = true; ignoreProjectileCollision = true; priority = 4; customEffect = "hitEffectCat"; onUpdate = function(self) if self.lifetime == 16 then --10 self.hitStun = 16; end end; onDestroy = function(self, host) if self.exists then self.noAttackbox = true if self.lifetime == 0 then self.exists = false if self.flip == -1 then host:newCatProjectile(self, "catRecovery", self.x + self.width/2 - 16 - catXOffset, self.y - 8*gameLogicMult) else host:newCatProjectile(self, "catRecovery", self.x + self.width/2 - catWidth + 16 + catXOffset, self.y - 8*gameLogicMult) end end end end; onLeaveScreen = function(self) --don't do anything (if this didn't exist, the projectile would die) end }; catDownForwardA = { sfx = "rush"; lifetime = 30; dontKillEffect = true; xSpeed = 250; relativeX = -30 *gameLogicMult; --doesn't matter relativeY = -17 *gameLogicMult; -- -54 pushUp = 200 * gameLogicMult; pushback = 250; width = (8+42) * gameLogicMult; height = 30 * gameLogicMult; hitStun = 16; updateDuringHitstop = true; forceProjectileForward = true; -- noAttackbox = true; stayOnScreen = true; ignoreProjectileCollision = true; priority = 4; customEffect = "hitEffectCat"; onUpdate = function(self) if self.lifetime == 8 then self.hitStun = nil; -- self.noAttackbox = false end end; onDestroy = function(self, host) if self.exists then self.noAttackbox = true if self.lifetime == 0 then self.exists = false if self.flip == -1 then host:newCatProjectile(self, "catRecovery", self.x + self.width/2 - catXOffset, self.y + 17 * gameLogicMult) else host:newCatProjectile(self, "catRecovery", self.x + self.width/2 - catWidth + catXOffset, self.y + 17 * gameLogicMult) end end end end; }; catDownForwardB = { sfx = "downForwardB"; lifetime = 60; dontKillEffect = true; -- xSpeed = 20; noAttackbox = true; attacktype = attackTypes.high; relativeX = -44 *gameLogicMult; --doesn't matter relativeY = -40 *gameLogicMult; pushUp = -300 * gameLogicMult; width = 105 * gameLogicMult; height = 54 * gameLogicMult; -- hitStun = 16; updateDuringHitstop = true; -- noAttackbox = true; -- stayOnScreen = true; -- forceForward = true; forceProjectileForward = true; -- ySpeed = -700; -- decay = 10 * gameLogicMult; ignoreProjectileCollision = true; priority = 4; customEffect = "hitEffectCat"; onUpdate = function(self) -- if self.lifetime == 20 then -- self.noAttackbox = false -- self.ySpeed = 400; -- self.decay = 0; -- end if self.lifetime == 26 then self.noAttackbox = false elseif self.lifetime == 13 then self.hitStun = 16; --this activates the projectile as an attack elseif self.lifetime == 6 then self.hitStun = nil; end end; onDestroy = function(self, host) if self.exists then self.noAttackbox = true if self.lifetime == 0 then self.exists = false if self.flip == -1 then host:newCatProjectile(self, "catRecovery", self.x + self.width/2 - catXOffset, 122 + 30 *gameLogicMult) else host:newCatProjectile(self, "catRecovery", self.x + self.width/2 - catWidth + catXOffset, 122 + 30 *gameLogicMult) end end end end; onLeaveScreen = function(self) --don't do anything (if this didn't exist, the projectile would die) end }; catRunLeft = { xSpeed = -200; --default 350 relativeX = 0 *gameLogicMult; --29*gameLogicMult relativeY = 0 *gameLogicMult; width = catWidth; height = 6 * gameLogicMult; noAttackbox = true; updateDuringHitstop = true; -- stayOnScreen = true; onUpdate = function(self) if math.floor(self.host.x - self.x) >= 30 then self.host:newCatProjectile(self, "catIdle", self.x, self.y) end end; onLeaveScreen = function(self) --don't do anything (if this didn't exist, the projectile would die) end }; catRunRight = { xSpeed = 200; --default 350 relativeX = 0 *gameLogicMult; --29*gameLogicMult relativeY = 0 *gameLogicMult; width = catWidth; height = 6 * gameLogicMult; noAttackbox = true; updateDuringHitstop = true; -- stayOnScreen = true; onUpdate = function(self) if math.floor(self.host.x - self.x) <= 30 then self.host:newCatProjectile(self, "catIdle", self.x, self.y) end end; onLeaveScreen = function(self) --don't do anything (if this didn't exist, the projectile would die) end }; }; colors = { default = { sprite = { {255,201,255}; --DRESS and sparkle lighter {255,169,183}; --sparkle darker {248,245,248}; --cat fur {255,192,255}; --cat shading {0,221,155}; --cat eyes {0,53,70}; --normal tentacle shadow {0,84,100}; -- normal tentacle {0,33,38}; -- down back B darkest {29,159,165}; -- sucker rim {7,193,138}; -- sucker inside {4,116,83}; -- sucker inside shadow }; effects = { {255,169,183}; --sparkle darker {255,201,255}; --sparkle lighter {248,245,248}; --cat fur {255,192,255}; --cat shading {0,221,155}; --cat eyes {0,53,70}; --normal tentacle shadow {0,84,100}; -- normal tentacle {0,33,38}; -- down back B darkest {29,159,165}; -- sucker rim {7,193,138}; -- sucker inside {4,116,83}; -- sucker inside shadow }; hit = { {255,43,106}; --hot pink {255,119,180}; --medium pink {255,169,183}; --lightest pink {0,220,161}; --cat }; meterIcon = { {0,221,155}; -- eyes {169,255,173}; --shadow {0,103,83}; -- health background }; meterChunk = { {0,255,178}; --drain color }; --generalAssets dust = {255,100,146}; block = {255,100,146}; mainUI = {149,0,52}; health = {255,100,146}; }; alt1 = { sprite = { {255,76,76}; --DRESS and sparkle lighter {255,121,126}; --sparkle darker {255,198,198}; --cat fur {255,150,150}; --cat shading {25,124,255}; --cat eyes {20,38,88}; --normal tentacle shadow {0,80,116}; -- normal tentacle {3,16,42}; -- down back B darkest {5,117,255}; -- sucker rim {56,162,255}; -- sucker inside {34,83,143}; -- sucker inside shadow }; effects = { {255,121,126}; --sparkle darker {255,76,76}; --sparkle lighter {255,198,198}; --cat fur {255,150,150}; --cat shading {25,124,255}; --cat eyes {20,38,88}; --normal tentacle shadow {0,80,116}; -- normal tentacle {3,16,42}; -- down back B darkest {5,117,255}; -- sucker rim {56,162,255}; -- sucker inside {34,83,143}; -- sucker inside shadow }; hit = { {255,34,30}; --hot pink {255,0,0}; --medium pink {255,121,126}; --lightest pink {0,99,231}; --cat }; meterIcon = { {25,124,255}; -- eyes {169,223,255}; --shadow {0,55,102}; -- health background }; meterChunk = { {0,99,231}; --drain color }; --generalAssets dust = {255,64,64}; block = {255,0,0}; mainUI = {113, 0, 0}; health = {255,0,0}; }; alt2 = { sprite = { {255,177,107}; --DRESS and sparkle lighter {255,119,84}; --sparkle darker {255,247,243}; --cat fur {255,207,148}; --cat shading {229,230,0}; --cat eyes {118,98,0}; --normal tentacle shadow {184,165,0}; -- normal tentacle {67,61,19}; -- down back B darkest {235,230,35}; -- sucker rim {255,218,19}; -- sucker inside {202,151,46}; -- sucker inside shadow }; effects = { {255,119,84}; --sparkle darker {255,177,107}; --sparkle lighter {255,247,243}; --cat fur {255,207,148}; --cat shading {229,230,0}; --cat eyes {118,98,0}; --normal tentacle shadow {184,165,0}; -- normal tentacle {67,61,19}; -- down back B darkest {235,230,35}; -- sucker rim {255,218,19}; -- sucker inside {202,151,46}; -- sucker inside shadow }; hit = { {255,74,0}; --hot pink {255,106,46}; --medium pink {255,119,84}; --lightest pink {255,255,0}; --cat }; meterIcon = { {229,230,0}; -- eyes {255,255,73}; --shadow {102,87,0}; -- health background }; meterChunk = { {229,230,0}; --drain color }; --generalAssets dust = {255,164,42}; mainUI = {187,72,0}; health = {255,102,7}; }; alt3 = { sprite = { {248,244,64}; --DRESS and sparkle lighter {255,239,169}; --sparkle darker {255,255,192}; --cat fur {255,248,76}; --cat shading {255,30,106}; --cat eyes {70,0,32}; --normal tentacle shadow {100,0,62}; -- normal tentacle {57,0,37}; -- down back B darkest {194,0,60}; -- sucker rim {204,51,136}; -- sucker inside {132,34,71}; -- sucker inside shadow }; effects = { {255,239,169}; --sparkle darker {248,244,64}; --sparkle lighter {255,255,192}; --cat fur {255,248,76}; --cat shading {255,30,106}; --cat eyes {70,0,32}; --normal tentacle shadow {100,0,62}; -- normal tentacle {57,0,37}; -- down back B darkest {194,0,60}; -- sucker rim {204,51,136}; -- sucker inside {132,34,71}; -- sucker inside shadow }; hit = { {255,255,0}; --hot pink {255,221,90}; --medium pink {255,239,169}; --lightest pink {255,30,106}; --cat }; meterIcon = { {255,30,106}; -- eyes {255,169,186}; --shadow {102,0,47}; -- health background }; meterChunk = { {255,30,106}; --drain color }; --generalAssets dust = {255,255,0}; block = {255,255,0}; mainUI = {113, 113, 0}; health = {215,215,0}; }; alt4 = { sprite = { {172,226,68}; --DRESS and sparkle lighter {103,210,57}; --sparkle darker {226,255,226}; --cat fur {179,220,99}; --cat shading {169,23,255}; --cat eyes {65,0,70}; --normal tentacle shadow {114,0,135}; -- normal tentacle {47,0,57}; -- down back B darkest {195,0,255}; -- sucker rim {255,0,255}; -- sucker inside {168,9,123}; -- sucker inside shadow }; effects = { {103,210,57}; --sparkle darker {172,226,68}; --sparkle lighter {226,255,226}; --cat fur {179,220,99}; --cat shading {169,23,255}; --cat eyes {65,0,70}; --normal tentacle shadow {114,0,135}; -- normal tentacle {47,0,57}; -- down back B darkest {195,0,255}; -- sucker rim {255,0,255}; -- sucker inside {168,9,123}; -- sucker inside shadow }; hit = { {0,255,0}; --hot pink {65,193,67}; --medium pink {103,210,57}; --lightest pink {153,85,193}; --cat }; meterIcon = { {169,23,255}; -- eyes {208,122,255}; --shadow {70,0,102}; -- health background }; meterChunk = { {169,23,255}; --drain color }; --generalAssets dust = {0,255,0}; mainUI = {0, 113, 0}; health = {0,255,0} }; alt5 = { sprite = { {128,183,192}; --DRESS and sparkle lighter {126,218,233}; --sparkle darker {202,214,255}; --cat fur {137,171,255}; --cat shading {247,0,0}; --cat eyes {87,0,0}; --normal tentacle shadow {117,27,34}; -- normal tentacle {64,0,4}; -- down back B darkest {194,11,0}; -- sucker rim {246,0,43}; -- sucker inside {154,11,0}; -- sucker inside shadow }; effects = { {126,218,233}; --sparkle darker {128,183,192}; --sparkle lighter {202,214,255}; --cat fur {137,171,255}; --cat shading {247,0,0}; --cat eyes {87,0,0}; --normal tentacle shadow {117,27,34}; -- normal tentacle {64,0,4}; -- down back B darkest {194,11,0}; -- sucker rim {246,0,43}; -- sucker inside {154,11,0}; -- sucker inside shadow }; hit = { {0,216,255}; --hot pink {101,196,255}; --medium pink {126,218,233}; --lightest pink {255,0,0}; --cat }; meterIcon = { {247,0,0}; -- eyes {255,145,145}; --shadow {102,0,0}; -- health background }; meterChunk = { {255,0,0}; --drain color }; --generalAssets dust = {128,183,192}; mainUI = {0,75,88}; --UIcolor health = {0,216,255}; }; alt6 = { sprite = { {202,202,208}; --DRESS and sparkle lighter {155,155,167}; --sparkle darker {227,227,227}; --cat fur {179,179,179}; --cat shading {235,138,167}; --cat eyes {144,0,153}; --normal tentacle shadow {209,30,182}; -- normal tentacle {101,0,111}; -- down back B darkest {243,56,255}; -- sucker rim {251,15,219}; -- sucker inside {220,9,181}; -- sucker inside shadow }; effects = { {155,155,167}; --sparkle darker {202,202,208}; --sparkle lighter {227,227,227}; --cat fur {179,179,179}; --cat shading {235,138,167}; --cat eyes {144,0,153}; --normal tentacle shadow {209,30,182}; -- normal tentacle {101,0,111}; -- down back B darkest {243,56,255}; -- sucker rim {251,15,219}; -- sucker inside {220,9,181}; -- sucker inside shadow }; hit = { {113,117,125}; --hot pink {120,126,138}; --medium pink {155,155,167}; --lightest pink {240,128,240}; --cat }; meterIcon = { {235,138,167}; -- eyes {236,169,255}; --shadow {98,0,86}; -- health background }; meterChunk = { {235,138,167}; --drain color }; --generalAssets dust = {155,155,167}; mainUI = {64,64,64}; --UIcolor health = {155,155,167}; }; alt7 = { sprite = { {213,134,208}; --DRESS and sparkle lighter {127,79,139}; --sparkle darker {210,167,255}; --cat fur {202,98,255}; --cat shading {0,197,0}; --cat eyes {0,99,67}; --normal tentacle shadow {31,161,0}; -- normal tentacle {0,57,47}; -- down back B darkest {0,255,0}; -- sucker rim {149,255,32}; -- sucker inside {107,224,0}; -- sucker inside shadow }; effects = { {127,79,139}; --sparkle darker {213,134,208}; --sparkle lighter {210,167,255}; --cat fur {202,98,255}; --cat shading {0,197,0}; --cat eyes {0,99,67}; --normal tentacle shadow {31,161,0}; -- normal tentacle {0,57,47}; -- down back B darkest {0,255,0}; -- sucker rim {149,255,32}; -- sucker inside {107,224,0}; -- sucker inside shadow }; hit = { {136,17,149}; --hot pink {184,15,255}; --medium pink {127,79,139}; --lightest pink {0,255,0}; --cat }; meterIcon = { {0,197,0}; -- eyes {193,255,84}; --shadow {0,103,12}; -- health background }; meterChunk = { {0,255,0}; --drain color }; --generalAssets dust = {171,43,200}; block = {171,43,200}; mainUI = {71,42,69}; health = {171,43,200}; }; }; }; function Keiko:newCatProjectile(currentProjectile, newProjectileString, overloadX, overloadY, overloadFlip) print("newCatProjectile Incoming:" .. newProjectileString) local relativeY = currentProjectile.y + self.projectiles[newProjectileString].relativeY if overloadY then relativeY = overloadY end local relativeX = self.projectiles[newProjectileString].relativeX if currentProjectile.flip == 1 then relativeX = currentProjectile.x + relativeX else relativeX = currentProjectile.x + currentProjectile.width - relativeX - self.projectiles[newProjectileString].width end if overloadX then relativeX = overloadX end if overloadFlip then currentProjectile.flip = overloadFlip end self:executeProjectile(newProjectileString, relativeX, relativeY, currentProjectile.flip) currentProjectile.liveEffect.exists = false currentProjectile.exists = false currentProjectile:destroy() if newProjectileString == "catDownBackAStartup" then self:setFDB({{type="startup", frameCount=9+14}, {type="active", frameCount=16}, {type="recovery", frameCount=41-5+10}}) elseif newProjectileString == "catDownBackBStartup" then self:setFDB({{type="startup", frameCount=9+8}, {type="active", frameCount=30}, {type="recovery", frameCount=41+10-5+10}}) elseif newProjectileString == "catDownForwardAStartup" then self:setFDB({{type="startup", frameCount=9}, {type="active", frameCount=22}, {type="recovery", frameCount=41+6-5+10+2}}) elseif newProjectileString == "catDownForwardBStartup" then self:setFDB({{type="startup", frameCount=9+47}, {type="active", frameCount=13-6}, {type="recovery", frameCount=41-5+10+6}}) elseif newProjectileString == "catHurt" then self:setFDB({{type="knockdown", frameCount=45+30-50+10}, {type="recovery", frameCount=20+50}}) elseif newProjectileString == "catDash" then self:setFDB(Template:Type="recovery", frameCount=30) end end function Keiko:dashOverride(left, right) local catIdle = self:getProjectile("catIdle") if catIdle and not p.superStop and not q.superStop and not roundIntro then if left then self:newCatProjectile(catIdle, "catDash", nil, nil, -1) elseif right then self:newCatProjectile(catIdle, "catDash", nil, nil, 1) end self.dashInputLeft = 0 self.dashInputRight = 0 self.flagDashRight = false self.flagDashLeft = false end end function Keiko:controlUpdate(left, right, up, down, buttonA, buttonB, tapA, tapB, specialA, specialB) if not p.superStop and not q.superStop and not roundIntro then local catAnimation = self:getProjectile("catHurt") if not catAnimation then catAnimation = self:getProjectile("catWakeup") if not catAnimation then catAnimation = self:getProjectile("catRecovery") if not catAnimation then catAnimation = self:getProjectile("catDash") if not catAnimation then catAnimation = self:getProjectile("catWakeupTwo") end end end end if catAnimation then if self.ABTimer <= 1 and buttonA and buttonB then if not self:onFloor() then self:executeAnimation("jumpUp") else if not (down and right) and not (down and left) then self:executeAnimation("idle") end end self.noInput = false self.ABTimer = 2 self.repeatA = true self.repeatB = true self:flushBar() if catAnimation == self:getProjectile("catWakeup") then self:newCatProjectile(catAnimation, "catNeutralAB", nil, catAnimation.y-48*gameLogicMult) else self:newCatProjectile(catAnimation, "catNeutralAB") end elseif buttonA and buttonB and not self.repeatA and not self.repeatB then self.repeatA = true self.repeatB = true if catAnimation == self:getProjectile("catWakeup") then self:newCatProjectile(catAnimation, "catNeutralAB", nil, catAnimation.y-48*gameLogicMult) else self:newCatProjectile(catAnimation, "catNeutralAB") end end end local catIdle = self:getProjectile("catIdle") if catIdle then -- if left and not self.lastFrameLeft then -- if self.dashInputLeft > 0 then -- self:newCatProjectile(catIdle, "catDash", nil, nil, -1) -- end -- elseif right and not self.lastFrameRight then -- if self.dashInputRight > 0 then -- self:newCatProjectile(catIdle, "catDash", nil, nil, 1) -- end if self.ABTimer <= 1 and buttonA and buttonB then if not self:onFloor() then self:executeAnimation("jumpUp") else if not (down and right) and not (down and left) then self:executeAnimation("idle") end end self.noInput = false self.ABTimer = 2 self.repeatA = true self.repeatB = true self:flushBar() self:newCatProjectile(catIdle, "catNeutralAB") elseif buttonA and buttonB and not self.repeatA and not self.repeatB then self.repeatA = true self.repeatB = true self:newCatProjectile(catIdle, "catNeutralAB") elseif buttonA and self.inputFrame >= 6 then if down and right and not left then -- if catIdle.flip == 1 then if (self.flip == 1 and self.move ~= "getThrown") or (self.move == "getThrown" and self.flip == -1) then self:newCatProjectile(catIdle, "catDownForwardAStartup") else self:newCatProjectile(catIdle, "catDownBackAStartup") end self.repeatA = true self.inputFrame = 0 elseif down and left and not right then -- if catIdle.flip == 1 then if (self.flip == 1 and self.move ~= "getThrown") or (self.move == "getThrown" and self.flip == -1) then self:newCatProjectile(catIdle, "catDownBackAStartup") else self:newCatProjectile(catIdle, "catDownForwardAStartup") end self.repeatA = true self.inputFrame = 0 end elseif buttonB and self.inputFrame >= 6 then if down and right and not left then -- if catIdle.flip == 1 then if (self.flip == 1 and self.move ~= "getThrown") or (self.move == "getThrown" and self.flip == -1) then self:newCatProjectile(catIdle, "catDownForwardBStartup") else self:newCatProjectile(catIdle, "catDownBackBStartup") end self.repeatB = true self.inputFrame = 0 elseif down and left and not right then -- if catIdle.flip == 1 then if (self.flip == 1 and self.move ~= "getThrown") or (self.move == "getThrown" and self.flip == -1) then self:newCatProjectile(catIdle, "catDownBackBStartup") else self:newCatProjectile(catIdle, "catDownForwardBStartup") end self.repeatB = true self.inputFrame = 0 end end end end self:_controlUpdate(left, right, up, down, buttonA, buttonB, tapA, tapB, specialA, specialB) end function Keiko:reset() self:_reset() self.catFDB = {} self.catFDBPhantom = {} for i=1, 200 do self.catFDB[i] = 0 self.catFDBPhantom[i] = 0 end self.meterAmount = 8 if not selecting then if self.flip == 1 then self:executeProjectile("catDashStart", self.x - 300, self.y + 30 * gameLogicMult) else self:executeProjectile("catDashStart", self.x + self.width + 300 - (catWidth), self.y + 30 * gameLogicMult) end end end function Keiko:changeMeter(amount) self.meterAmount = self.meterAmount + amount if amount > 0 then if self.meterAmount == 1 then if self.playerNum == 1 then self:executeSound('fullMeter', "sfx", -1) else self:executeSound('fullMeter', "sfx", 1) end end if self.meterAmount >= 8 then self.meterJitter = 5 self.meterAmount = 8 else self.meterJitter = 2 end self.meterAnimate = anim8.newAnimation(self.sprites.meter.grid(repeatNum(1,1)), frameTime, 'pauseAtEnd') for i=1, 8 do self.meterChunkArray[i] = anim8.newAnimation(self.sprites.meterChunk.grid(repeatNum(1,1,7,2,2,1,3,1,7,2,4,2,7,2,5,2,7,3,6,3,-1,1)), frameTime, 'pauseAtEnd') --6,1,1,2,2,2,3,2,4,2,5,1 end else if self.meterAmount < 0 then self.meterAmount = 0 end if self.meterAmount == 0 then self.meterAnimate = anim8.newAnimation(self.sprites.meter.grid(repeatNum(4,2,5,1)), frameTime, 'pauseAtEnd') if self.meterAmount < 0 then self.meterAmount = 0 end -- self.neutralABRequirement = false end -- for i=1,8 do -- self.meterChunkArray[i] = anim8.newAnimation(self.sprites.meterChunk.grid(repeatNum(1,1,2,3,3,3,4,3,5,3,6,3,7,3,8,1)), frameTime, 'pauseAtEnd') -- end self.meterJitter = 5 end end function Keiko:initiate() self:_initiate() self.hitLightSFX = "lightAttack" self.hitHeavySFX = "heavyAttack" self.hitLowSFX = "lowAttack" self.hitSpecialSFX = "special" end function Keiko:resetMeter() self.meterChunkArray = {} for i=1, 8 do self.meterChunkArray[i] = anim8.newAnimation(self.sprites.meterChunk.grid(repeatNum(1,1,7,2,2,1,3,1,7,2,4,2,7,2,5,2,7,3,6,3,-1,1)), frameTime, 'pauseAtEnd') --6,1,1,2,2,2,3,2,4,2,5,1 end self:_resetMeter() end function Keiko:meterAnimation() love.graphics.setShader() -- self:catFDBDraw(true) self:meterBackDraw() self:catFDBDraw() love.graphics.setShader(self.shaders.meterIcon) if self.player1 then self.meterAnimate:draw(self.sprites.meter.sheet, self.meterX, self.meterY + self.meterJitter, 0, gameLogicMult, gameLogicMult, 0, 0) love.graphics.setShader(self.shaders.meterChunk) for i=1, 8 do local d = i-1 self.meterChunkArray[i]:draw(self.sprites.meterChunk.sheet, (self.meterX + 126) - (d * 12), self.meterY + 10 + self.meterJitter, 0, gameLogicMult, gameLogicMult, 0, 0) end else self.meterAnimate:draw(self.sprites.meter.sheet, self.meterX, self.meterY + self.meterJitter, 0, -gameLogicMult, gameLogicMult, 0, 0) love.graphics.setShader(self.shaders.meterChunk) for i=1, 8 do local d = i-1 self.meterChunkArray[i]:draw(self.sprites.meterChunk.sheet, (self.meterX - 126) + (d * 12), self.meterY + 10 + self.meterJitter, 0, -gameLogicMult, gameLogicMult, 0, 0) end end love.graphics.setShader() end function Keiko:meterOverload() if self.meterChunkArray then for i=8, self.meterAmount+1,-1 do self.meterChunkArray[i]:update(frameTime) end end end function Keiko:setFDB(frameDataTable) if not frameDataTable then return end local tableSize = 0 local frameData = {} tableSize = #frameDataTable frameData = frameDataTable if tableSize <= 0 then return end local frameType = 0 local frameCount = 0 local currentLocation = 0 self:catFlushBar() for i=tableSize, 1, -1 do frameCount = frameData[i].frameCount frameType = frameData[i].type for j=0, frameCount-1 do self.catFDB[currentLocation + j] = frameType end -- self.catFDB[frameType] = self.catFDB[frameType] + frameCount currentLocation = currentLocation + frameCount end self.catFDBPhantom = deepcopy(self.catFDB) end function Keiko:alwaysUpdate(dt) self:_alwaysUpdate(dt) self:catFDBUpdate() end function Keiko:catFlushBar() self.framePosition = 0 local ending = 0 while ending <= 79 and self.catFDB[ending] ~= 0 do self.catFDB[ending] = 0 ending = ending + 1 end -- self.catFDB.startup = 0 -- self.catFDB.active = 0 -- self.catFDB.recovery = 0 -- self.catFDB.blockstun = 0 -- self.catFDB.hitstun = 0 -- self.catFDB.cancel = 0 if not ignorePhantom then self.catFDBPhantom = deepcopy(self.catFDB) end end function Keiko:catFDBUpdate() local ending = 0 while self.catFDB[ending] ~= 0 do ending = ending + 1 end self.catFDB[ending - 1] = 0 end function Keiko:catFDBDraw(phantom) local ending = 0 local frameBar = self.catFDB local alpha = 255 if phantom then frameBar = self.catFDBPhantom alpha = 255 end while ending <= 47 do if frameBar[ending] == "recovery" then love.graphics.setColor(100, 255, 100, alpha) if phantom then love.graphics.setColor(35, 75, 35, alpha) end elseif frameBar[ending] == "active" then love.graphics.setColor(255,46,46, alpha) if phantom then love.graphics.setColor(74, 20, 20, alpha) end elseif frameBar[ending] == "startup" then love.graphics.setColor(255,255,100, alpha) if phantom then love.graphics.setColor(75, 75, 35, alpha) end elseif frameBar[ending] == "blockstun" then love.graphics.setColor(66,214,247, alpha) if phantom then love.graphics.setColor(26, 64, 72, alpha) end elseif frameBar[ending] == "hitstun" then love.graphics.setColor(255,169,0, alpha) if phantom then love.graphics.setColor(73, 51, 7, alpha) end elseif frameBar[ending] == "cancel" then love.graphics.setColor(255,255,255, alpha) elseif frameBar[ending] == "knockdown" then love.graphics.setColor(255,118,192, alpha) if phantom then love.graphics.setColor(76, 41, 60, alpha) end else love.graphics.setColor(0,0,0,0) end if self.playerNum == 1 then love.graphics.rectangle("fill", 52 + (2 * ending) + (7 * gameLogicMult), 234 + self.meterJitter, gameLogicMult,gameLogicMult) love.graphics.rectangle("fill", 50 + (2 * ending) + (7 * gameLogicMult), 232 + self.meterJitter, gameLogicMult,gameLogicMult) else love.graphics.rectangle("fill", screenWidth - 52 - (2 * ending) - (7 * gameLogicMult), 234 + self.meterJitter, gameLogicMult,gameLogicMult) love.graphics.rectangle("fill", screenWidth - 50 - (2 * ending) - (7 * gameLogicMult), 232 + self.meterJitter, gameLogicMult,gameLogicMult) end ending = ending + 1 end love.graphics.setColor(255,255,255) end function Keiko:meterBackDraw() if self.colorNum == 8 then love.graphics.setColor(0,103,83) elseif self.colorNum == 1 then love.graphics.setColor(0,55,102) elseif self.colorNum == 2 then love.graphics.setColor(102,87,0) elseif self.colorNum == 3 then love.graphics.setColor(102,0,47) elseif self.colorNum == 4 then love.graphics.setColor(70,0,102) elseif self.colorNum == 5 then love.graphics.setColor(102,0,0) elseif self.colorNum == 6 then love.graphics.setColor(98,0,86) else love.graphics.setColor(0,103,12) end if self.playerNum == 1 then love.graphics.rectangle("fill", 50 + (7 * gameLogicMult), 232 + self.meterJitter, gameLogicMult*50,gameLogicMult*2) else love.graphics.rectangle("fill", screenWidth - 150 - (7 * gameLogicMult), 232 + self.meterJitter, gameLogicMult*50,gameLogicMult*2) end love.graphics.setColor(255,255,255) end function Keiko:fullMeter() if self.meterAmount < 8 then self.meterAmount = 0 self:changeMeter(8) end if self:noProjectiles() and self.move.name == "idle" and self.height == standHeight and ((rootState.training and trainingOptions.infiniteMeter) or (rootState.mode == "lesson" and rootState.eventQueue[rootState.currentEvent.stage].infiniteMeter)) then if self.flip == 1 then self:executeProjectile("catDashStart", self.x - 300, self.y + 30 * gameLogicMult) else self:executeProjectile("catDashStart", self.x + self.width + 300 - (catWidth), self.y + 30 * gameLogicMult) end elseif self.projectileTable[1].name == "catDeath" then self.projectileTable[1].exists = false if self.flip == 1 then self:executeProjectile("catDashStart", self.x - 300, self.y + 30 * gameLogicMult) else self:executeProjectile("catDashStart", self.x + self.width + 300 - (catWidth), self.y + 30 * gameLogicMult) end end end