Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---Player Skill Constants affecting flight model-----
- SKY_CAPTAIN_LEVEL=0
- SPACE_CAPTAIN_LEVEL=0
- ---------TARGET PRIORITIZATION---------
- function CalculateFriendlyValue(FriendlyInfo, SelfInfo)
- --[[returns the friendly unit's value for friendly prioritization purposes.
- you may want to change this to change which units to prioritize,
- for example, by increasing the priority of a specific blueprint.
- Think of this as a more advanced target prioritization AI card.
- This is also the reason this function is on the beginning of the script.
- I probably did an awful job at setting proper prioritization here.
- NO. SERIOUSLY. IF YOU SEE DERPY BEHAVIOR, BLAME THIS FUNCTION.]]
- --we only want valid targets.
- if not FriendlyInfo.IsValid then return -999999999 end --9 zeros here, shouldn't be looked at all
- if (FriendlyInfo.CenterOfMass-SelfInfo.CenterOfMass).magnitude<3 then return -99999999 end --8 here
- -----ALGORITHM CONSTANTS-----
- --value to add per m of distance to the target(calculated by center of mass)
- local DistanceValue=-2
- *(FriendlyInfo.CenterOfMass-SelfInfo.CenterOfMass).Magnitude
- --value to add for damage
- --this function prioritizes larger vessels assuming they need more repairs. maybe too much.
- local HealthValue=(FriendlyInfo.PositiveSize+FriendlyInfo.NegativeSize).sqrMagnitude
- *(1.02-FriendlyInfo.HealthFraction) --the .02 helps it stick close to flagships
- --value per m/s of velocity in world coordinates
- local WorldVelocityValue = -2
- *FriendlyInfo.Velocity.magnitude
- --value per m/s of velocity in coordinates relative to the repair drone.
- --should be somewhat high to avoid unnecessary target switching.
- --closure rate formula help by /u/Alkalannar on /r/homeworkhelp. Thanks Reddit!
- local RelativeVelocityValue = 30
- *(Vector3.Scale(FriendlyInfo.Position-SelfInfo.Position,FriendlyInfo.Velocity-SelfInfo.Velocity)
- /(FriendlyInfo.Position-SelfInfo.Position).magnitude).magnitude
- --value per meter of altitude the target has from sea level.
- --intentionally low to discourage healing unreachable targets in space.
- --Also low for underwater targets to reduce likelyness of moving underwater.
- local AltitudeValue=0
- local TargetAltitude = FriendlyInfo.CenterOfMass.y
- if TargetAltitude<-50 then AltitudeValue=TargetAltitude * 30+500
- elseif TargetAltitude<300 then AltitudeValue=TargetAltitude *-10
- elseif TargetAltitude<600 then AltitudeValue=TargetAltitude *-50+3000
- else AltitudeValue=TargetAltitude *-250
- end
- return DistanceValue+HealthValue+VelocityValue+AltitudeValue
- end
- --------------------ACTUAL MAIN FUNCTION--------------------
- function Update(I)
- -- put your code here
- end
- --------END MAIN FUNCTION, HELPER FUNCTIONS GO HERE---------
- function GetSelfInfo(I)
- --attempts to assemble a FriendlyInfo-like object based on self-awareness info
- local Info={}
- --this may look ugly, but i'm not using _G.
- Info.Rotation = nil --screw quaternions.
- Info.ReferencePosition=I:GetConstructPosition()
- Info.PositiveSize = I:GetConstructMaxDimensions()
- Info.NegativeSize=I:GetConstructMinDimensions()
- Info.CenterOfMass=I:GetConstructCenterOfMass()
- Info.UpVector=I:GetConstructUpVector()
- Info.ForwardVector=I:GetConstructForwardVector()
- Info.RightVector=I:GetConstructRightVector()
- Info.HealthFraction=I:GetHealthFraction()
- Info.SparesFraction=I:GetSparesFraction()
- Info.AmmoFraction=I:GetAmmoFraction()
- Info.FuelFraction=I:GetFuelFraction()
- --too lazy to calculate AABBs
- Info.AxisAlignedBoundingBoxMinimum=nil
- Info.AxisAlignedBoundingBoxMaximum=nil
- Info.IsValid=-1 --it's neither valid or invalid. That's the most fitting thing i can think of!
- return Info
- end
- function GetRotationMatrix(...)
- --returns a rotation matrix with the right-up-forward vectors of a FriendlyInfo object.
- --alternatively, can be overloaded with 3 vectors.
- --if so, it's already expecting them to be unit vectors and won't try to normalize them.
- --late feature: also accepts quaternion input(passed to another function)
- local M={}
- local args={...}
- if #args==1 and args[1].w==nil then
- M.x=Info.RightVector
- M.y=Info.UpVector
- M.z=Info.ForwardVector
- return M
- elseif args[1].w then return QuaternionToRotationMatrix(...)
- else
- M.x=args[1]
- M.y=args[2]
- M.z=args[3]
- return M
- end
- end
- function ThrustGlobally(I,Force) --Vector3
- --Attempts to apply a specific force(kN) on the global reference frame using the dediblades.
- --Doesn't account for damage affecting force output.
- --Also doesn't try to use vertical force components.
- --Behavior if the system can't achieve the inserted power is undefined.
- -- this function could be made much smaller, but i'm too lazy for it right now.
- --still writing it. may be reaching critical mass
- -- lists spinner IDs for a side
- local RightSpinners, LeftSpinners, UpSpinners, DownSpinners, ForwardSpinners, BackSpinners={}
- local UndefinedSpinners={} -- i'm probably going to trigger this at some point.
- local SpinnerCount=I:GetSpinnerCount()
- for n=0, SpinnerCount-1 do
- SpinnerInfo=I:GetSpinnerInfo(n)
- local SpinnerLocalUpVector=GetRotationMatrix(SpinnerInfo.LocalRotation).y
- --WHY DONT WE HAVE SWITCH-CASE DAMNIT!? <-totally not an interrobang
- if SpinnerLocalUpVector==Vector3.up then table.insert(UpSpinners, n)
- elseif SpinnerLocalUpVector==Vector3.down then table.insert(DownSpinners,n)
- elseif SpinnerLocalUpVector==Vector3.left then table.insert(LeftSpinners,n)
- elseif SpinnerLocalUpVector==Vector3.right then table.insert(RightSpinners,n)
- elseif SpinnerLocalUpVector==Vector3.forward then table.insert(ForwardSpinners,n)
- elseif SpinnerLocalUpVector==Vector3.back then table.insert(BackSpinners,n)
- else table.insert(UndefinedSpinners,n)
- end
- end
- local RotorMass=0.09 --dediblade motor+4 blades
- local AtmosphericDensity=GetAtmosphericDensity()
- local MotorDrive=0 --no engine
- --kN thrust per rad/s of a dediblade, see fromthedepths.gamepedia.com/Air#Dedicated_heliblades
- HelibladeForce=10*RotorMass*AtmosphericDensity*(1+MotorDrive)*(1+(0.02*SKY_CAPTAIN_LEVEL))
- local SpinnerCount=Vector3(#LeftSpinners+#RightSpinners,
- #UpSpinners+#DownSpinners,#ForwardSpinners+#BackSpinners)
- local ForceProducedPerRad=SpinnerCount*HelibladeForce --output of all of a side's blades/rad/s
- Local RadsNeeded=Vector3InvScale(SpinnerCount, ForceNeededPerRad)--RPM for force if orthogonal
- for k,v in pairs(RightSpinners) do
- local SpinnerAngle=GetRotationMatrix(I:GetSpinnerInfo[v].Rotation).y
- I:SetSpinnerContinousSpeed(v,TaxicabMagnitude(Vector3.Scale() --UPLOADED WHILE WRITING THIS PART
- end
- end
- function GetAtmosphericDensity(Input)
- --why don't we have this ingame already?
- --this is a kludge. don't say i didn't warn you. Also, it only works for Neterlike planets
- if Input==nil then return GetAtmosphericDensity(SelfInfo.CenterOfMass.y or 0)
- elseif type(Input)=="number" then
- if Input<300 then return 1
- elseif Input<500+(10*SPACE_CAPTAIN_LEVEL) then
- local dx= 1/(200+(10*SPACE_CAPTAIN_LEVEL)) --% atmos density lost per m of altitude
- return 1-(dx*(Input-300))
- else return 0
- end
- else return GetAtmosphericDensity(Input.CenterOfMass.y or Input.Position.y
- or Input.ReferencePosition.y)
- end
- end
- function QuaternionToRotationMatrix(Q)
- --returns the right/up/forward rotation matrix from a quaternion
- local M={}
- local XSquared=Q.x*Q.x
- local YSquared=Q.y*Q.y
- local ZSquared=Q.z*Q.z
- --local WSquared=Q.w*Q.w
- local XY=Q.x*Q.y
- local XZ=Q.x*Q.z
- local XW=Q.x*Q.w
- local YZ=Q.y*Q.z
- local YW=Q.y*Q.w
- local ZW=Q.z*Q.w
- --I have absolutely no idea how any of this works. If the AI fails to move properly, this is why.
- --Evil4Zerggin linked me to a formula on wikipedia i tried to optimize.
- --I'm probably doing a mistake.
- M.x = (Vector3(-YSquared-ZSquared, XY-ZW, XZ+YW)*2)+Vector3.right
- M.y = (Vector3(XY+ZW, -XSquared-ZSquared, YZ-XW)*2)+Vector3.up
- M.z = (Vector3(XZ-YW, YZ+XW, -XSquared-YSquared)*2)+Vector3.forward
- return M
- end
- function Vector3InvScale(A,B)
- return Vector3.Scale(A,Vector3(1/B.x, 1/B.y, 1/B.z))
- end
- function TaxicabMagnitude(Vec3)
- --returns the taxicab magnitude of a Vector3
- return math.abs(Vec3.x)+math.abs(Vec3.y)+math.abs(Vec3.z)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement