function Create(self) self.defaultMeleeKeyNum = 26; self.meleeKey = nil; for particle in MovableMan.Particles do if particle.PresetName == "DarkStorm Melee Key" then self.meleeKey = particle; end end if not(MovableMan:ValidMO(self.meleeKey)) then self.meleeKey = CreateMOPixel("DarkStorm Melee Key"); self.meleeKey.Pos = Vector(self.Pos.X, -10); MovableMan:AddParticle(self.meleeKey); print('Melee Key Activated. Currently set to: ' .. self.meleeKey.Mass .. '. Input this line to change key, replacing the * mark with the desired key number: for particle in MovableMan.Particles do if particle.PresetName == "DarkStorm Melee Key" then particle.Mass = *; end end'); end self.healTimer = Timer(); self.healTime = 2000; self.maxHealth = 100; self.stabSpeed = 50; self.stab = nil; self.stabGraphic = nil; self.stabOffset = Vector(0, -3); self.stabStartDist = 10; self.stabDist = 40; self.referenceMass = 30; self.maxDamage = 500; self.baseHealth = 100; self.checkWidth = 20; self.checkHeight = 10; self.clingPos = Vector(0,0); self.clingOffset = 10; self.minClingAltitude = 40; self.cling = false; self.phase = 0; self.gravTester = CreateMOPixel("D2Shinobi Grav Tester"); self.gravTester.Pos = Vector(self.Pos.X, self.Pos.Y - 3); self.gravTester.Vel = Vector(0,0); MovableMan:AddParticle(self.gravTester); self.gravAcc = 0; self.activeCamo = false; self.maxCamoEnergy = 500; self.curCamoEnergy = self.maxCamoEnergy; self.camoSwitchTimer = Timer(); self.camoSwitchTime = 250; self.meterOffset = Vector(6, -26); self.meter = nil; self.noMeter = CreateMOSParticle("D2Shinobi No Camo Meter"); self.noMeter.Pos = self.Pos + self.meterOffset; self.noMeter.Frame = self.noMeter.FrameCount - 1; MovableMan:AddParticle(self.noMeter); end function Update(self) if not(self:IsDead()) then if self.gravAcc == 0 then if self.gravTester.Vel.Y > 0 then self.gravAcc = self.gravTester.Vel.Y; end end local ownCont = self:GetController(); local meleeKeyNum = self.defaultMeleeKeyNum; if MovableMan:ValidMO(self.meleeKey) then meleeKeyNum = self.meleeKey.Mass; end if self.healTimer:IsPastSimMS(self.healTime) then self.Health = self.Health + 1; if self.Health > self.maxHealth then self.Health = self.maxHealth; end self.healTimer = Timer(); end if ownCont:IsState(Controller.PRESS_DOWN) then if self.camoSwitchTimer:IsPastSimMS(self.camoSwitchTime) then self.camoSwitchTimer = Timer(); else if self.activeCamo then self.activeCamo = false; i = 1; while i < MovableMan:GetMOIDCount() do if MovableMan:GetMOFromID(i).RootID == self.ID then MovableMan:GetMOFromID(i).Scale = 1 end i = i + 1 end if MovableMan:ValidMO(self.meter) then self.meter.Lifetime = 1; end self.noMeter = CreateMOSParticle("D2Shinobi No Camo Meter"); self.noMeter.Pos = self.Pos + self.meterOffset; self.noMeter.Frame = (self.curCamoEnergy / self.maxCamoEnergy) * (self.noMeter.FrameCount - 1); MovableMan:AddParticle(self.noMeter); local offSound = CreateAEmitter("D2Shinobi Camo Off Sound Emitter"); offSound.Pos = self.Pos; MovableMan:AddParticle(offSound); else self.activeCamo = true; i = 1; while i < MovableMan:GetMOIDCount() do if MovableMan:GetMOFromID(i).RootID == self.ID then MovableMan:GetMOFromID(i).Scale = 0 end i = i + 1 end if MovableMan:ValidMO(self.noMeter) then self.noMeter.Lifetime = 1; end self.meter = CreateMOSParticle("D2Shinobi Camo Meter"); self.meter.Pos = self.Pos + self.meterOffset; self.meter.Frame = (self.curCamoEnergy / self.maxCamoEnergy) * (self.meter.FrameCount - 1); MovableMan:AddParticle(self.meter); local onSound = CreateAEmitter("D2Shinobi Camo On Sound Emitter"); onSound.Pos = self.Pos; MovableMan:AddParticle(onSound); end end end if self.activeCamo then if MovableMan:ValidMO(self.meter) then self.meter.Pos = self.Pos + self.meterOffset; self.meter.Frame = (self.curCamoEnergy / self.maxCamoEnergy) * (self.meter.FrameCount - 1); self.meter:NotResting(); self.meter.Age = 0; self.meter.ToSettle = false; self.meter.ToDelete = false; end self.curCamoEnergy = self.curCamoEnergy - 1; if self.curCamoEnergy <= 0 then self.curCamoEnergy = 0; self.activeCamo = false; i = 1; while i < MovableMan:GetMOIDCount() do if MovableMan:GetMOFromID(i).RootID == self.ID then MovableMan:GetMOFromID(i).Scale = 1 end i = i + 1 end if MovableMan:ValidMO(self.meter) then self.meter.Lifetime = 1; end self.noMeter = CreateMOSParticle("D2Shinobi No Camo Meter"); self.noMeter.Pos = self.Pos + self.meterOffset; self.noMeter.Frame = (self.curCamoEnergy / self.maxCamoEnergy) * (self.noMeter.FrameCount - 1); MovableMan:AddParticle(self.noMeter); local offSound = CreateAEmitter("D2Shinobi Camo Off Sound Emitter"); offSound.Pos = self.Pos; MovableMan:AddParticle(offSound); end else if MovableMan:ValidMO(self.noMeter) then self.noMeter.Pos = self.Pos + self.meterOffset; self.noMeter.Frame = (self.curCamoEnergy / self.maxCamoEnergy) * (self.noMeter.FrameCount - 1); self.noMeter:NotResting(); self.noMeter.Age = 0; self.noMeter.ToSettle = false; self.noMeter.ToDelete = false; end self.curCamoEnergy = self.curCamoEnergy + 1; if self.curCamoEnergy > self.maxCamoEnergy then self.curCamoEnergy = self.maxCamoEnergy; end end if self.phase == 0 then if UInputMan:KeyPressed(meleeKeyNum) and ownCont.Player ~= -1 and not(ownCont:IsState(Controller.WEAPON_RELOAD)) then local checkVect = Vector(math.cos(self:GetAimAngle(true)) * self.stabDist, -math.sin(self:GetAimAngle(true)) * self.stabDist); local checkPos = self.Pos + self.stabOffset; local targetID = SceneMan:CastMORay(checkPos, checkVect, self.ID, 0, false, 0); local target = MovableMan:GetMOFromID(MovableMan:GetRootMOID(targetID)); if targetID ~= 255 and target.GetsHitByMOs then local grounded = false; local foundVector = Vector(0,0); for i=target.Pos.X - self.checkWidth, target.Pos.X + self.checkWidth do local checkPoint = SceneMan:MovePointToGround(Vector(i, target.Pos.Y), 0, 1); grounded = SceneMan:CastFindMORay(checkPoint, Vector(0, -self.checkHeight), target.ID, foundVector, -1, true, 0); if grounded then break; end end if grounded then local damage = 0; if target.Mass ~= 0 then damage = (self.referenceMass/math.abs(target.Mass)) * self.baseHealth; else damage = self.maxDamage; end if damage > self.maxDamage then damage = self.maxDamage; end for actor in MovableMan.Actors do if actor.ID == target.ID then actor.Health = actor.Health - damage; end end local shock = CreateMOPixel("D94CombatKnife Shock"); shock.Pos = target.Pos; MovableMan:AddParticle(shock); end elseif self:GetAltitude(0,0) > self.minClingAltitude then local impactLocation = Vector(0,0); if SceneMan:CastStrengthRay(checkPos, checkVect, 0, impactLocation, 0, 0, true) then local diffVect = self.Pos - impactLocation; local diffAngle = math.atan2(-diffVect.Y, diffVect.X); local offsetVect = Vector(math.cos(diffAngle) * self.clingOffset, -math.sin(diffAngle) * self.clingOffset); self.Pos = impactLocation + offsetVect; self.Vel = Vector(0,-self.gravAcc); self.cling = true; local sound = CreateAEmitter("D94CombatKnife Cling Sound Emitter"); sound.Pos = impactLocation; MovableMan:AddParticle(sound); end end if self.cling then self.phase = 2; else self.stab = CreateMOPixel("D94CombatKnife Stab"); local forwardOffset = Vector(math.cos(self:GetAimAngle(true)) * self.stabStartDist, -math.sin(self:GetAimAngle(true)) * self.stabStartDist); self.stab.Pos = self.Pos + self.stabOffset + forwardOffset; self.stab.Vel = Vector(math.cos(self:GetAimAngle(true)) * self.stabSpeed, -math.sin(self:GetAimAngle(true)) * self.stabSpeed) + self.Vel; self.stab:SetWhichMOToNotHit(self, -1); MovableMan:AddParticle(self.stab); self.stabGraphic = CreateMOSRotating("D94CombatKnife Stab Graphic"); self.stabGraphic.RotAngle = self:GetAimAngle(true); local forwardOffset = Vector(math.cos(self.stabGraphic.RotAngle) * self.stabStartDist, -math.sin(self.stabGraphic.RotAngle) * self.stabStartDist); self.stabGraphic.Pos = self.Pos + self.stabOffset + forwardOffset; self.stabGraphic.Vel = Vector(math.cos(self.stabGraphic.RotAngle) * self.stabSpeed, -math.sin(self.stabGraphic.RotAngle) * self.stabSpeed) + self.Vel; self.stabGraphic:SetWhichMOToNotHit(self, -1); MovableMan:AddParticle(self.stabGraphic); local sound = CreateAEmitter("D94CombatKnife Stab Sound Emitter"); sound.Pos = self.stab.Pos; MovableMan:AddParticle(sound); self.phase = 1; end end elseif self.phase == 1 then if not(MovableMan:ValidMO(self.stabGraphic)) then self.phase = 0; else ownCont:SetState(Controller.WEAPON_FIRE, false); end elseif self.phase == 2 then if (UInputMan:KeyPressed(meleeKeyNum) and ownCont.Player ~= -1) or ownCont:IsState(Controller.BODY_JUMP) or ownCont:IsState(Controller.WEAPON_RELOAD) then self.cling = false; self.phase = 0; else self.Vel = Vector(0,-self.gravAcc); end end if self.phase ~= 0 then ownCont:SetState(Controller.MOVE_LEFT, false); ownCont:SetState(Controller.MOVE_RIGHT, false); end else if MovableMan:ValidMO(self.stab) then self.stab.Lifetime = 1; end if MovableMan:ValidMO(self.stabGraphic) then self.stabGraphic.Lifetime = 1; end if MovableMan:ValidMO(self.meter) then self.meter.Lifetime = 1; end if MovableMan:ValidMO(self.noMeter) then self.noMeter.Lifetime = 1; end end end function Destroy(self) if MovableMan:ValidMO(self.stab) then self.stab.Lifetime = 1; end if MovableMan:ValidMO(self.stabGraphic) then self.stabGraphic.Lifetime = 1; end if MovableMan:ValidMO(self.meter) then self.meter.Lifetime = 1; end if MovableMan:ValidMO(self.noMeter) then self.noMeter.Lifetime = 1; end end