Ticket #2067: mustang.patch
File mustang.patch, 12.5 KB (added by , 11 years ago) |
---|
-
binaries/data/mods/public/simulation/components/GarrisonHolder.js
32 32 this.entities = []; 33 33 this.spaceOccupied = 0; 34 34 this.timer = undefined; 35 this.allowGarrisoning = {}; 35 36 }; 36 37 37 38 /** … … 85 86 } 86 87 87 88 /** 89 * Set this entity to allow or disallow garrisoning in 90 * Every component calling this function should do it with its own ID, and as long as one 91 * component doesn't allow this entity to garrison, it can't be garrisoned 92 * When this entity already contains garrisoned soldiers, 93 * these will not be able to ungarrison until the flag is set to true again. 94 * 95 * This more usefull in modern-day features. Like you can't garrison in or ungarrison out 96 * of a driving vehicle or plane. 97 */ 98 GarrisonHolder.prototype.AllowGarrisoning = function(allow, callerID) 99 { 100 this.allowGarrisoning[callerID] = allow; 101 } 102 103 /** 104 * Check if no component of this entity blocks garrisoning 105 * (f.e. because the vehicle is moving too fast) 106 */ 107 GarrisonHolder.prototype.IsGarrisoningAllowed = function() 108 { 109 var allow = true; 110 for each (var b in this.allowGarrisoning) 111 allow = allow && b; 112 return allow; 113 } 114 115 /** 88 116 * Get number of garrisoned units capable of shooting arrows 89 117 * Not necessarily archers 90 118 */ … … 107 135 */ 108 136 GarrisonHolder.prototype.AllowedToGarrison = function(entity) 109 137 { 138 if (!this.IsGarrisoningAllowed()) 139 return false; 140 110 141 var allowedClasses = this.GetAllowedClassesList(); 111 142 var entityClasses = (Engine.QueryInterface(entity, IID_Identity)).GetClassesList(); 112 143 // Check if the unit is allowed to be garrisoned inside the building … … 167 198 */ 168 199 GarrisonHolder.prototype.Eject = function(entity, forced) 169 200 { 201 170 202 var entityIndex = this.entities.indexOf(entity); 203 // Error: invalid entity ID, usually it's already been ejected 171 204 if (entityIndex == -1) 172 { // Error: invalid entity ID, usually it's already been ejected173 205 return false; // Fail 174 }175 206 176 207 // Find spawning location 177 208 var cmpFootprint = Engine.QueryInterface(this.entity, IID_Footprint); … … 237 268 */ 238 269 GarrisonHolder.prototype.PerformEject = function(entities, forced) 239 270 { 271 if (!this.IsGarrisoningAllowed() && !forced) 272 return false 240 273 var ejectedEntities = []; 241 274 var success = true; 242 275 for each (var entity in entities) -
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 4 function UnitMotionFlying() {} 5 5 6 6 UnitMotionFlying.prototype.Schema = … … 33 33 "</element>" + 34 34 "<element name='ClimbRate'>" + 35 35 "<ref name='nonNegativeDecimal'/>" + 36 "</element>" + 37 "<element name='DiesInWater'>" + 38 "<data type='boolean'/>" + 36 39 "</element>"; 37 40 38 41 UnitMotionFlying.prototype.Init = function() … … 46 49 this.speed = 0; 47 50 this.landing = false; 48 51 this.onGround = true; 52 this.pitch = 0; 53 this.roll = 0; 54 this.waterDeath = false; 49 55 }; 50 56 51 57 UnitMotionFlying.prototype.OnUpdate = function(msg) 52 58 { 53 59 var turnLength = msg.turnLength; 54 55 60 if (!this.hasTarget) 56 61 return; 57 62 var cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder); 63 var cmpHealth = Engine.QueryInterface(this.entity, IID_Health); 58 64 var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); 59 65 var pos = cmpPosition.GetPosition(); 60 var angle = cmpPosition.GetRotation().y; 61 66 var angle = cmpPosition.GetRotation().y; 67 var cmpTerrain = Engine.QueryInterface(SYSTEM_ENTITY, IID_Terrain); 68 var cmpWaterManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_WaterManager); 69 var ground = Math.max(cmpTerrain.GetGroundLevel(pos.x, pos.z), cmpWaterManager.GetWaterLevel(pos.x, pos.z)); 70 var newangle = angle; 62 71 var canTurn = true; 63 64 if (!this.landing) 72 if (this.landing) 65 73 { 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 74 if (this.speed > 0 && this.onGround) 98 { 75 { 76 this.pitch = 0; 99 77 // Deaccelerate forwards...at a very reduced pace. 100 this.speed = Math.max(0, this.speed - turnLength * this.template.BrakingRate); 78 if (this.waterDeath) 79 this.speed = Math.max(0, this.speed - turnLength * this.template.BrakingRate * 10); 80 else 81 this.speed = Math.max(0, this.speed - turnLength * this.template.BrakingRate); 101 82 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); 83 // Clamp to ground if below it, or descend if above 105 84 if (pos.y < ground) 106 85 pos.y = ground; 107 86 else if (pos.y > ground) 108 pos.y = Math.max(ground, pos.y - turnLength * this.template.ClimbRate); 109 cmpPosition.SetHeightFixed(pos.y); 87 pos.y = Math.max(ground, pos.y - turnLength * this.template.ClimbRate); 110 88 } 111 else if (this.speed == 0 )89 else if (this.speed == 0 && this.onGround) 112 90 { 91 if (this.waterDeath) 92 cmpHealth.Kill(); 93 this.pitch = 0; 113 94 // We've stopped. 95 cmpGarrisonHolder.AllowGarrisoning(true,"UnitMotionFlying") 114 96 canTurn = false; 115 97 this.hasTarget = false; 116 98 this.landing = false; … … 120 102 // Final Approach 121 103 // We need to slow down to land! 122 104 this.speed = Math.max(this.template.LandingSpeed, this.speed - turnLength * this.template.SlowingRate); 123 canTurn = false; 124 var cmpTerrain = Engine.QueryInterface(SYSTEM_ENTITY, IID_Terrain); 125 var ground = cmpTerrain.GetGroundLevel(pos.x, pos.z); 105 canTurn = false; 126 106 var targetHeight = ground; 127 107 // Steep, then gradual descent. 128 var descentRate = ((pos.y - targetHeight) / this.template.FlyingHeight * this.template.ClimbRate + shortFinal) * shortFinal; 108 if ((pos.y - targetHeight) / this.template.FlyingHeight > 1 / SHORT_FINAL) 109 this.pitch = - Math.PI / 18; 110 else 111 this.pitch = Math.PI / 18; 112 var descentRate = ((pos.y - targetHeight) / this.template.FlyingHeight * this.template.ClimbRate + SHORT_FINAL) * SHORT_FINAL; 129 113 if (pos.y < targetHeight) 130 114 pos.y = Math.max(targetHeight, pos.y + turnLength * descentRate); 131 115 else if (pos.y > targetHeight) 132 116 pos.y = Math.max(targetHeight, pos.y - turnLength * descentRate); 133 117 if (targetHeight == pos.y) 134 this.onGround = true; 135 cmpPosition.SetHeightFixed(pos.y); 118 { 119 this.onGround = true; 120 if (targetHeight == cmpWaterManager.GetWaterLevel(pos.x, pos.z) && this.template.DiesInWater) 121 this.waterDeath = true; 122 } 136 123 } 137 124 } 125 else 126 { 127 // If we haven't reached max speed yet then we're still on the ground; 128 // otherwise we're taking off or flying 129 // this.onGround in case of a go-around after landing (but not fully stopped) 138 130 131 if (this.speed < this.template.TakeoffSpeed && this.onGround) 132 { 133 cmpGarrisonHolder.AllowGarrisoning(false,"UnitMotionFlying") 134 this.pitch = 0; 135 // Accelerate forwards 136 this.speed = Math.min(this.template.MaxSpeed, this.speed + turnLength * this.template.AccelRate); 137 canTurn = false; 138 // Clamp to ground if below it, or descend if above 139 if (pos.y < ground) 140 pos.y = ground; 141 else if (pos.y > ground) 142 pos.y = Math.max(ground, pos.y - turnLength * this.template.ClimbRate); 143 } 144 else 145 { 146 this.onGround = false; 147 // Climb/sink to max height above ground 148 this.speed = Math.min(this.template.MaxSpeed, this.speed + turnLength * this.template.AccelRate); 149 var targetHeight = ground + (+this.template.FlyingHeight); 150 if (Math.abs(pos.y-targetHeight) > this.template.FlyingHeight/5) 151 { 152 this.pitch = Math.PI / 9; 153 canTurn = false; 154 } 155 else 156 this.pitch = 0; 157 if (pos.y < targetHeight) 158 pos.y = Math.min(targetHeight, pos.y + turnLength * this.template.ClimbRate); 159 else if (pos.y > targetHeight) 160 { 161 pos.y = Math.max(targetHeight, pos.y - turnLength * this.template.ClimbRate); 162 this.pitch = -1 * this.pitch; 163 } 164 } 165 } 166 139 167 // If we're in range of the target then tell people that we've reached it 140 168 // (TODO: quantisation breaks this) 141 169 var distFromTarget = Math.sqrt(Math.pow(this.targetX - pos.x, 2) + Math.pow(this.targetZ - pos.z, 2)); … … 165 193 var deltaClamped = Math.min(Math.max(delta, -this.template.TurnRate * turnLength), this.template.TurnRate * turnLength); 166 194 // Calculate new orientation, in a peculiar way in order to make sure the 167 195 // result gets close to targetAngle (rather than being n*2*pi out) 168 angle = targetAngle + deltaClamped - delta; 196 newangle = targetAngle + deltaClamped - delta; 197 if (newangle - angle > Math.PI / 18) 198 this.roll = Math.PI / 9; 199 else if (newangle - angle < -Math.PI / 18) 200 this.roll = - Math.PI / 9; 201 else 202 this.roll = newangle - angle; 169 203 } 204 else 205 this.roll = 0; 170 206 171 207 pos.x += this.speed * turnLength * Math.sin(angle); 172 208 pos.z += this.speed * turnLength * Math.cos(angle); 173 174 cmpPosition.TurnTo(angle); 209 cmpPosition.SetHeightFixed(pos.y); 210 cmpPosition.TurnTo(newangle); 211 cmpPosition.SetXZRotation(this.pitch, this.roll); 175 212 cmpPosition.MoveTo(pos.x, pos.z); 176 213 }; 177 214 … … 251 288 UnitMotionFlying.prototype.StopMoving = function() 252 289 { 253 290 //Invert 254 this.landing = !this.landing; 291 if (!this.waterDeath) 292 this.landing = !this.landing; 293 255 294 }; 256 295 257 296 UnitMotionFlying.prototype.SetDebugOverlay = function(enabled) -
binaries/data/mods/public/simulation/templates/other/plane.xml
13 13 <Spread>1.5</Spread> 14 14 </Ranged> 15 15 </Attack> 16 <BuildingAI> 17 <DefaultArrowCount>3</DefaultArrowCount> 18 <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier> 19 <GarrisonArrowClasses>Infantry</GarrisonArrowClasses> 20 </BuildingAI> 21 <GarrisonHolder> 22 <Max>1</Max> 23 <EjectHealth>0</EjectHealth> 24 <List datatype="tokens">Support Infantry</List> 25 <BuffHeal>1</BuffHeal> 26 <LoadingRange>5</LoadingRange> 27 <EjectEntitiesOnDestroy>false</EjectEntitiesOnDestroy> 28 </GarrisonHolder> 29 <Decay> 30 <Inactive/> 31 <SinkingAnim/> 32 <DelayTime>0.0</DelayTime> 33 <SinkRate>3.0</SinkRate> 34 <SinkAccel>7.0</SinkAccel> 35 </Decay> 16 36 <Identity> 17 37 <Civ>hele</Civ> 18 38 <SpecificName>P-51 Mustang</SpecificName> … … 21 41 <Icon>units/global_mustang.png</Icon> 22 42 <Formations datatype="tokens" replace=""/> 23 43 </Identity> 44 <Health> 45 <Max>100</Max> 46 <Unhealable>true</Unhealable> 47 <Repairable>true</Repairable> 48 </Health> 24 49 <Obstruction disable=""/> 25 50 <Position> 26 51 <TurnRate>1.0</TurnRate> 52 <Floating>true</Floating> 27 53 </Position> 28 54 <UnitMotion disable=""/> 29 55 <UnitMotionFlying> … … 36 62 <TurnRate>1.0</TurnRate> 37 63 <OvershootTime>2.0</OvershootTime> 38 64 <FlyingHeight>50.0</FlyingHeight> 39 <ClimbRate>5.0</ClimbRate> 65 <ClimbRate>15.0</ClimbRate> 66 <DiesInWater>true</DiesInWater> 40 67 </UnitMotionFlying> 41 68 <Vision> 42 69 <Range>100</Range>