--MISSION ADJUSTED d2kA.lua clone ActorRegister={} ReinforcementSquads = { {"vet_light_inf","vet_light_inf","vet_light_inf","vet_trooper","vet_trooper"}, {"quad","quad","mpsardaukar", "mpsardaukar"}, {"trooper","trooper","trooper","trooper", "trooper"} } WorldLoaded = function() --set up mission initializeMission() end Tick = function() --do activities neccessary for the mission missionTick() --check register for new actors and only call act.Type=="whatever" when neccessary since it is expensive local new_actors = ActorsAddedToWorld(Map.ActorsInWorld,ActorRegister) for _,act in pairs(new_actors) do --ACTOR TYPE CHECKS local T=act.Type --needed for airdrop powers if (T=="waypoint_dummy_a" or T=="waypoint_dummy_h" or T=="waypoint_dummy_o") then dropAirReinforcements(act.Location,act) --...handle silo replacement on silo upgrade elseif T=="upgrade.silo" then replace_silos(act.Owner) end end end function ActorsAddedToWorld(newlist,register) local new_actor_list={} for key,act in pairs(newlist) do if not register[tostring(act)] then register[tostring(act)]=true table.insert(new_actor_list,act) end end return new_actor_list end function replace_silos(player) local res = player.Resources for _, actor in pairs(player.GetActorsByType("silo")) do local loc=actor.Location actor.Destroy() Actor.Create("advanced_silo", true, { Owner = player, Location = loc }) end --give the game time to contemplate consequences of rapid player.ResourceCapacity changes, then correct. Trigger.AfterDelay(DateTime.Seconds(0.1), function() player.Resources = res end ) end function dropAirReinforcements(location,dummy) local squad if dummy.Type=="waypoint_dummy_a" then squad=1 elseif dummy.Type=="waypoint_dummy_h" then squad=2 elseif dummy.Type=="waypoint_dummy_o" then squad=3 end --Carryall reinforcements local base = dummy.Owner.GetActorsByType("outpost")[1] local edge = getMapEdge(base.Location, location) local path = {edge,location} local units = Reinforcements.ReinforceWithTransport(dummy.Owner, "carryall.controllable", ReinforcementSquads[squad], path, {path[2], path[1]}) local carryall = units[1] Trigger.OnPassengerExited(carryall, function(carry, pass) if not carry.HasPassengers then carry.Move(path[1]) carry.Destroy() end end ) end function getMapEdge(posB,posA) local bnds = {} bnds.Top=(Map.TopLeft.Y)/1024 bnds.Bottom=(Map.BottomRight.Y+1)/1024 bnds.Left=(Map.TopLeft.X)/1024 bnds.Right=(Map.BottomRight.X+1)/1024 --catch zero devision errors if posB.X-posA.X == 0 then if posB.Y<posA.Y then return CPos.New(posA.X,bnds.Top) else return CPos.New(posA.X,bnds.Bottom) end elseif posB.Y-posA.Y == 0 then if posB.X<posA.X then return CPos.New(bnds.Left,posA.Y) else return CPos.New(bnds.Right,posA.Y) end end --compute all boundary intersections local slope = (posB.Y-posA.Y)/(posB.X-posA.X) local topX = posA.X - (posA.Y-bnds.Top)/slope local bottomX= posA.X + (bnds.Bottom-posA.Y)/slope local rightY = posA.Y + (bnds.Right-posA.X)*slope local leftY = posA.Y - (posA.X-bnds.Left)*slope local top = CPos.New(math.floor(topX),bnds.Top) local bottom = CPos.New(math.floor(bottomX),bnds.Bottom) local right = CPos.New(bnds.Right, math.floor(rightY)) local left = CPos.New(bnds.Left, math.floor(leftY)) --decide which of them is reasonable local positiveDelX = 0 < (posB.X-posA.X) local positiveSlope= 0 < slope if positiveDelX and positiveSlope then if bottom.X<=bnds.Right then return bottom else return right end elseif positiveDelX and not positiveSlope then if top.X<=bnds.Right then return top else return right end elseif not positiveDelX and positiveSlope then if top.X>=bnds.Left then return top else return left end elseif not positiveDelX and not positiveSlope then if bottom.X>=bnds.Left then return bottom else return left end end Media.DisplayMessage(" in Function getMapEdge, no Edge matched, returning default. (0,0)","Error") return CPos.New(0,0) end