Ticket #2062: watersink.patch
File watersink.patch, 6.2 KB (added by , 11 years ago) |
---|
-
binaries/data/mods/public/simulation/components/UnitMotionFlying.js
1 1 // (A serious implementation of this might want to use C++ instead of JS 2 2 // for performance; this is just for fun.) 3 const shortFinal = 2.5; 3 const SHORT_FINAL = 2.5; 4 const SINK_LEVEL = 2; 4 5 function UnitMotionFlying() {} 5 6 6 7 UnitMotionFlying.prototype.Schema = … … 58 59 var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); 59 60 var pos = cmpPosition.GetPosition(); 60 61 var angle = cmpPosition.GetRotation().y; 61 62 var cmpTerrain = Engine.QueryInterface(SYSTEM_ENTITY, IID_Terrain); 63 var ground = cmpTerrain.GetGroundLevel(pos.x, pos.z); 64 var cmpWaterManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_WaterManager); 65 var ground = Math.max(cmpTerrain.GetGroundLevel(pos.x, pos.z), cmpWaterManager.GetWaterLevel(pos.x, pos.z) - SINK_LEVEL); 62 66 var canTurn = true; 63 67 64 if ( !this.landing)68 if (this.landing) 65 69 { 66 // If we haven't reached max speed yet then we're still on the ground;67 // otherwise we're taking off or flying68 // this.onGround in case of a go-around after landing (but not fully stopped)69 var cmpTerrain = Engine.QueryInterface(SYSTEM_ENTITY, IID_Terrain);70 var ground = cmpTerrain.GetGroundLevel(pos.x, pos.z);71 if (this.speed < this.template.TakeoffSpeed && this.onGround)72 {73 // Accelerate forwards74 this.speed = Math.min(this.template.MaxSpeed, this.speed + turnLength * this.template.AccelRate);75 canTurn = false;76 // Clamp to ground if below it, or descend if above77 if (pos.y < ground)78 pos.y = ground;79 else if (pos.y > ground)80 pos.y = Math.max(ground, pos.y - turnLength * this.template.ClimbRate);81 }82 else83 {84 this.onGround = false;85 // Climb/sink to max height above ground86 this.speed = Math.min(this.template.MaxSpeed, this.speed + turnLength * this.template.AccelRate);87 var targetHeight = ground + (+this.template.FlyingHeight);88 if (pos.y < targetHeight)89 pos.y = Math.min(targetHeight, pos.y + turnLength * this.template.ClimbRate);90 else if (pos.y > targetHeight)91 pos.y = Math.max(targetHeight, pos.y - turnLength * this.template.ClimbRate);92 }93 cmpPosition.SetHeightFixed(pos.y);94 }95 else96 {97 70 if (this.speed > 0 && this.onGround) 98 71 { 99 72 // Deaccelerate forwards...at a very reduced pace. 100 73 this.speed = Math.max(0, this.speed - turnLength * this.template.BrakingRate); 101 74 canTurn = false; 102 // Clamp to ground if below it, or descend if above 103 var cmpTerrain = Engine.QueryInterface(SYSTEM_ENTITY, IID_Terrain); 104 var ground = cmpTerrain.GetGroundLevel(pos.x, pos.z); 75 // Clamp to ground if below it, or descend if above 105 76 if (pos.y < ground) 106 77 pos.y = ground; 107 78 else if (pos.y > ground) 108 pos.y = Math.max(ground, pos.y - turnLength * this.template.ClimbRate); 109 cmpPosition.SetHeightFixed(pos.y); 79 pos.y = Math.max(ground, pos.y - turnLength * this.template.ClimbRate); 110 80 } 111 81 else if (this.speed == 0) 112 82 { … … 121 91 // We need to slow down to land! 122 92 this.speed = Math.max(this.template.LandingSpeed, this.speed - turnLength * this.template.SlowingRate); 123 93 canTurn = false; 124 var cmpTerrain = Engine.QueryInterface(SYSTEM_ENTITY, IID_Terrain);125 var ground = cmpTerrain.GetGroundLevel(pos.x, pos.z);126 94 var targetHeight = ground; 127 95 // Steep, then gradual descent. 128 var descentRate = ((pos.y - targetHeight) / this.template.FlyingHeight * this.template.ClimbRate + shortFinal) * shortFinal;96 var descentRate = ((pos.y - targetHeight) / this.template.FlyingHeight * this.template.ClimbRate + SHORT_FINAL) * SHORT_FINAL; 129 97 if (pos.y < targetHeight) 130 98 pos.y = Math.max(targetHeight, pos.y + turnLength * descentRate); 131 99 else if (pos.y > targetHeight) 132 100 pos.y = Math.max(targetHeight, pos.y - turnLength * descentRate); 133 101 if (targetHeight == pos.y) 134 102 this.onGround = true; 135 cmpPosition.SetHeightFixed(pos.y);136 103 } 137 104 } 105 else 106 { 107 // If we haven't reached max speed yet then we're still on the ground; 108 // otherwise we're taking off or flying 109 // this.onGround in case of a go-around after landing (but not fully stopped) 110 if (this.speed < this.template.TakeoffSpeed && this.onGround) 111 { 112 // Accelerate forwards 113 this.speed = Math.min(this.template.MaxSpeed, this.speed + turnLength * this.template.AccelRate); 114 canTurn = false; 115 // Clamp to ground if below it, or descend if above 116 if (pos.y < ground) 117 pos.y = ground; 118 else if (pos.y > ground) 119 pos.y = Math.max(ground, pos.y - turnLength * this.template.ClimbRate); 120 } 121 else 122 { 123 this.onGround = false; 124 // Climb/sink to max height above ground 125 this.speed = Math.min(this.template.MaxSpeed, this.speed + turnLength * this.template.AccelRate); 126 var targetHeight = ground + (+this.template.FlyingHeight); 127 if (pos.y < targetHeight) 128 pos.y = Math.min(targetHeight, pos.y + turnLength * this.template.ClimbRate); 129 else if (pos.y > targetHeight) 130 pos.y = Math.max(targetHeight, pos.y - turnLength * this.template.ClimbRate); 131 } 132 } 138 133 139 134 // If we're in range of the target then tell people that we've reached it 140 135 // (TODO: quantisation breaks this) … … 144 139 this.reachedTarget = true; 145 140 Engine.PostMessage(this.entity, MT_MotionChanged, { "starting": false, "error": false }); 146 141 } 147 148 142 // If we're facing away from the target, and are still fairly close to it, 149 143 // then carry on going straight so we overshoot in a straight line 150 144 var isBehindTarget = ((this.targetX - pos.x) * Math.sin(angle) + (this.targetZ - pos.z) * Math.cos(angle) < 0); 151 145 // Overshoot the target: carry on straight 152 146 if (isBehindTarget && distFromTarget < this.template.MaxSpeed * this.template.OvershootTime) 153 147 canTurn = false; 154 155 148 if (canTurn) 156 149 { 157 150 // Turn towards the target … … 170 163 171 164 pos.x += this.speed * turnLength * Math.sin(angle); 172 165 pos.z += this.speed * turnLength * Math.cos(angle); 173 166 cmpPosition.SetHeightFixed(pos.y); 174 167 cmpPosition.TurnTo(angle); 175 168 cmpPosition.MoveTo(pos.x, pos.z); 176 169 };