function Create(self) self.checkTimer = Timer() self.homingTimer = Timer() self.fireTimer = Timer() self.fireThreshold = 1000 * 60 / self.RateOfFire; -- time in milliseconds to recharge from firing -- MS/sec * sec/min * min/round self.missileCounter = 1; -- makes sure that the missiles don't overwrite each other self.missile = {} -- array to store the missiles self.missileLastVel = {} end function Update(self) if self.ID == self.RootID then return end if MovableMan:ValidMO(self.parent) then -- Search our LOS both for terrain and actors local checkSuccess = false, checkPos; if self.checkTimer:IsPastRealMS(83) then for i = 1, 100 do checkPos = self.MuzzlePos + Vector((i/100)*1000,0):RadRotate(self.parent:GetAimAngle(true)) if SceneMan.SceneWrapsX == true then if checkPos.X > SceneMan.SceneWidth then checkPos = Vector(checkPos.X - SceneMan.SceneWidth,checkPos.Y) elseif checkPos.X < 0 then checkPos = Vector(SceneMan.SceneWidth + checkPos.X,checkPos.Y) end end local terrCheck = SceneMan:GetTerrMatter(checkPos.X,checkPos.Y) if terrCheck == 0 then local moCheck = SceneMan:GetMOIDPixel(checkPos.X,checkPos.Y) if moCheck ~= rte.NoMOID then checkSuccess = true; break end else checkSuccess = true; break end end end local targetSet = false for i=1, 5 do if self.missile[i] then if MovableMan:ValidMO(self.missile[i]) then -- print("Valid missile "..i.." starting now") if self.checkTimer:IsPastRealMS(83) and not targetSet then self.checkTimer:Reset() self.lastTarget = self.targetPos self.targetPos = self.MuzzlePos + Vector(SceneMan:ShortestDistance(self.missile[i].Pos,self.MuzzlePos,SceneMan.SceneWrapsX).Magnitude+200,0):RadRotate(self.parent:GetAimAngle(true)) if SceneMan.SceneWrapsX == true then if self.targetPos.X > SceneMan.SceneWidth then self.targetPos = Vector(self.targetPos.X - SceneMan.SceneWidth,self.targetPos.Y) elseif self.targetPos.X < 0 then self.targetPos = Vector(SceneMan.SceneWidth + self.targetPos.X,self.targetPos.Y) end end if checkSuccess then self.targetPos = checkPos end local laserPar = CreateMOPixel("Coalition RPG Laser Particle", "Coalition.rte") laserPar.Pos = self.targetPos MovableMan:AddParticle(laserPar) local drawVector = SceneMan:ShortestDistance(self.lastTarget,self.targetPos,false) local drawLine = math.ceil(drawVector.Magnitude/5) for j = 1, drawLine do local laserPar = CreateMOPixel("Coalition RPG Laser Particle 2", "Coalition.rte") laserPar.Pos = self.lastTarget + Vector(j*5,0):RadRotate(drawVector.AbsRadAngle) MovableMan:AddParticle(laserPar) end targetSet = true; end -- Find the velocity vector that will take the missile to the target if self.homingTimer:IsPastSimMS(250) then local FutureVel = self.missile[i].Vel + (self.missile[i].Vel-self.missileLastVel[i])-- * 4 local OptimalVel = SceneMan:ShortestDistance(self.missile[i].Pos, self.targetPos, false).Normalized local angError = math.asin(OptimalVel:Cross(FutureVel.Normalized)) -- The angle between FutureVel and OptimalVel self.missile[i].RotAngle = self.missile[i].RotAngle + math.min(math.max(angError, -0.14), 0.14) -- Gradually turn towards the optimal velocity vector if not self.Magazine or (self.Magazine and self.Magazine.RoundCount < 1) then self.parent:GetController():SetState(Controller.WEAPON_RELOAD, true) end end self.missileLastVel[i] = self.missileLastVel[i] * 0.3 + self.missile[i].Vel * 0.7 -- Filter the velocity to reduce noise else self.missile[i] = nil end end end end if self:IsActivated() and self.Magazine then -- not self.missile and if self.Magazine.RoundCount > 0 then --and self.Magazine.PresetName == "Magazine Coalition Missile Launcher" then if self.fireTimer.ElapsedSimTimeMS >= self.fireThreshold then self.fireTimer:Reset() self.missile[self.missileCounter] = CreateAEmitter("Particle AT Ogris", "Warframe.rte") if self.missile[self.missileCounter] then self.Magazine.RoundCount = self.Magazine.RoundCount-1; self.parent = MovableMan:GetMOFromID(self.RootID) if MovableMan:IsActor(self.parent) then self.parent = ToActor(self.parent) self.missile[self.missileCounter].Team = self.parent.Team self.missile[self.missileCounter].IgnoresTeamHits = true self.targetPos = self.parent.ViewPoint -- Launch the missile slightly upwards, but a bit more for the AI self.missile[self.missileCounter].Vel = self:RotateOffset(Vector(20, 0))--15, 0)) -- if self.parent:IsPlayerControlled() then -- self.missile[self.missileCounter].Vel.Y = self.missile[self.missileCounter].Vel.Y - 4 -- else -- self.missile[self.missileCounter].Vel.Y = self.missile[self.missileCounter].Vel.Y - 6 -- end self.missile[self.missileCounter].Vel = self.missile[self.missileCounter].Vel + self.Vel else self.parent = nil end self.missile[self.missileCounter].RotAngle = self.missile[self.missileCounter].Vel.AbsRadAngle self.missile[self.missileCounter].Pos = self.MuzzlePos MovableMan:AddParticle(self.missile[self.missileCounter]) self.missileLastVel[self.missileCounter] = Vector(self.missile[self.missileCounter].Vel.X, self.missile[self.missileCounter].Vel.Y) self.missileCounter = (self.missileCounter+1)%5+1; -- iterate the missileCounter end end end end end