Ticket #1919: pack.patch
File pack.patch, 13.6 KB (added by , 11 years ago) |
---|
-
binaries/data/mods/public/gui/session/unit_commands.js
1136 1136 else 1137 1137 rightUsed = false; 1138 1138 } 1139 else if (entState.pack) 1139 else 1140 rightUsed = false; 1141 1142 if (entState.pack) 1140 1143 { 1141 1144 var items = []; 1142 1145 var packButton = false; … … 1180 1183 else 1181 1184 rightUsed = false; 1182 1185 } 1183 else1184 rightUsed = false;1185 1186 1186 1187 if (!rightUsed) 1187 1188 { -
binaries/data/mods/public/simulation/helpers/Commands.js
476 476 case "pack": 477 477 for each (var ent in entities) 478 478 { 479 var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); 480 if (cmpUnitAI) 479 // figure out whether entity is a unit or a building 480 var cmpEntityAI = Engine.QueryInterface(ent, IID_UnitAI); 481 if (!cmpEntityAI) 482 cmpEntityAI = Engine.QueryInterface(ent, IID_BuildingAI); 483 if (cmpEntityAI) 481 484 { 482 485 if (cmd.pack) 483 cmp UnitAI.Pack(cmd.queued);486 cmpEntityAI.Pack(cmd.queued); 484 487 else 485 cmp UnitAI.Unpack(cmd.queued);488 cmpEntityAI.Unpack(cmd.queued); 486 489 } 487 490 } 488 491 break; … … 490 493 case "cancel-pack": 491 494 for each (var ent in entities) 492 495 { 493 var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); 494 if (cmpUnitAI) 496 // figure out whether entity is a unit or a building 497 var cmpEntityAI = Engine.QueryInterface(ent, IID_UnitAI); 498 if (!cmpEntityAI) 499 cmpEntityAI = Engine.QueryInterface(ent, IID_BuildingAI); 500 if (cmpEntityAI) 495 501 { 496 502 if (cmd.pack) 497 cmp UnitAI.CancelPack(cmd.queued);503 cmpEntityAI.CancelPack(cmd.queued); 498 504 else 499 cmp UnitAI.CancelUnpack(cmd.queued);505 cmpEntityAI.CancelUnpack(cmd.queued); 500 506 } 501 507 } 502 508 break; -
binaries/data/mods/public/simulation/components/BuildingAI.js
252 252 } 253 253 }; 254 254 255 /** 256 * All packing code taken and adapted from UnitAI 257 */ 258 BuildingAI.prototype.Pack = function() 259 { 260 // Check that we can pack 261 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 262 if (cmpPack && this.CanPack()) 263 cmpPack.Pack(); 264 }; 265 266 BuildingAI.prototype.Unpack = function() 267 { 268 // Check that we can unpack 269 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 270 if (cmpPack && this.CanUnpack()) 271 cmpPack.Unpack(); 272 }; 273 274 BuildingAI.prototype.CancelPack = function() 275 { 276 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 277 if (cmpPack && cmpPack.IsPacking() && !cmpPack.IsPacked()) 278 cmpPack.CancelPack(); 279 }; 280 281 BuildingAI.prototype.CancelUnpack = function() 282 { 283 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 284 if (cmpPack && cmpPack.IsPacking() && cmpPack.IsPacked()) 285 cmpPack.CancelUnpack(); 286 }; 287 288 BuildingAI.prototype.CanPack = function() 289 { 290 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 291 return (cmpPack && !cmpPack.IsPacking() && !cmpPack.IsPacked() && cmpPack.CanTransformHere()); 292 }; 293 294 BuildingAI.prototype.CanUnpack = function() 295 { 296 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 297 return (cmpPack && !cmpPack.IsPacking() && cmpPack.IsPacked() && cmpPack.CanTransformHere()); 298 }; 299 300 BuildingAI.prototype.IsPacking = function() 301 { 302 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 303 return (cmpPack && cmpPack.IsPacking()); 304 }; 305 255 306 Engine.RegisterComponentType(IID_BuildingAI, "BuildingAI", BuildingAI); -
binaries/data/mods/public/simulation/components/Pack.js
49 49 return this.packing; 50 50 }; 51 51 52 /** 53 * @return True if the entity to transform into is allowed on the 54 * current terrain/territory. 55 */ 56 Pack.prototype.CanTransformHere = function () 57 { 58 var canTransform = true; 59 // temporarily creating an entity for a check 60 var cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity); 61 var previewEntityTemplate = this.template.Entity; 62 if (cmpIdentity) 63 previewEntityTemplate = previewEntityTemplate.replace(/\{civ\}/g, cmpIdentity.GetCiv()); 64 var previewEntity = Engine.AddEntity(previewEntityTemplate); 65 if (previewEntity == INVALID_ENTITY) 66 canTransform = false; // Error (e.g. invalid template names) 67 else 68 { 69 var cmpBuildRestrictions = Engine.QueryInterface(previewEntity, IID_BuildRestrictions); 70 if (cmpBuildRestrictions) 71 { 72 // Position and ownership needs to be set for placement checks 73 var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); 74 var cmpNewPosition = Engine.QueryInterface(previewEntity, IID_Position); 75 if (cmpPosition.IsInWorld()) 76 { 77 var pos = cmpPosition.GetPosition2D(); 78 var angle = cmpPosition.GetRotation(); 79 cmpNewPosition.JumpTo(pos.x, pos.y); 80 cmpNewPosition.SetYRotation(angle.y); 81 } 82 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 83 var cmpNewOwnership = Engine.QueryInterface(previewEntity, IID_Ownership); 84 cmpNewOwnership.SetOwner(cmpOwnership.GetOwner()); 85 86 var cmpObstruction = Engine.QueryInterface(previewEntity, IID_Obstruction); 87 if (cmpObstruction) 88 cmpObstruction.SetActive(false); // entity is not really obstructing anything 89 90 // TODO: territory checks via CheckPlacement are currently not functional, 91 // since in that function the tileOwner always gives the current playerID 92 // (when calling the same code here, it does give the correct owner...) 93 var checkPlacement = cmpBuildRestrictions.CheckPlacement(); 94 if (checkPlacement && !checkPlacement.success) 95 canTransform = false; 96 // move temporary entity out of world so it won't interfere with additional calls 97 // to this function for this entity on the same sim update. 98 // specifically, CheckPlacement() would incorrectly spot and fail on earlier temp entities 99 // if those are left in the world. 100 cmpNewPosition.MoveOutOfWorld(); 101 } 102 } 103 104 Engine.DestroyEntity(previewEntity); 105 return canTransform; 106 }; 107 52 108 Pack.prototype.Pack = function() 53 109 { 54 110 // Ignore pointless pack command … … 124 180 Engine.PostMessage(this.entity, MT_PackFinished, { packed: this.packed }); 125 181 126 182 // Done un/packing, copy our parameters to the final entity 127 var newEntity = Engine.AddEntity(this.template.Entity); 183 // Replace the "{civ}" codes with this entity's civ ID 184 var cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity); 185 var newEntityTemplate = this.template.Entity; 186 if (cmpIdentity) 187 newEntityTemplate = newEntityTemplate.replace(/\{civ\}/g, cmpIdentity.GetCiv()); 188 var newEntity = Engine.AddEntity(newEntityTemplate); 128 189 if (newEntity == INVALID_ENTITY) 129 190 { 130 191 // Error (e.g. invalid template names) … … 164 225 cmpNewUnitAI.AddOrders(cmpUnitAI.GetOrders()); 165 226 } 166 227 228 // Transfer production queue 229 // note: default behaviour upon destroying an entity is to reset queue, 230 // that case is thus not handled here. 231 var cmpQueue = Engine.QueryInterface(this.entity, IID_ProductionQueue); 232 var cmpNewQueue = Engine.QueryInterface(newEntity, IID_ProductionQueue); 233 if (cmpQueue && cmpNewQueue) 234 { 235 var queue = cmpQueue.GetQueue(true); // with true returns copy, not just summary 236 if (queue.length > 0) 237 { 238 var transferableQueue = []; 239 for (var i = queue.length-1; i >= 0; i--) 240 { 241 var templateName = queue[i].unitTemplate ? queue[i].unitTemplate : queue[i].technologyTemplate; 242 if (cmpNewQueue.CanAcceptTemplate(templateName)) 243 transferableQueue.push( queue.splice(i,1)[0] ); 244 } 245 cmpQueue.SetQueue(queue); // set old queue with untransferable batches 246 cmpNewQueue.SetQueue(transferableQueue); // set new queue with transferable batches 247 } 248 } 249 250 // Transfer garrisoned units if possible, or unload them 251 var cmpGarrison = Engine.QueryInterface(this.entity, IID_GarrisonHolder); 252 var cmpNewGarrison = Engine.QueryInterface(newEntity, IID_GarrisonHolder); 253 if (cmpGarrison && cmpGarrison.GetEntities().length > 0) 254 { 255 if (cmpNewGarrison) 256 { 257 // note: the code cannot rely on the garrisoning entity's indexing 258 // due to removal of elements. This is why a reference to the 259 // garrisoned entity is stored in a temporary variable 260 var garrisonedEntity, // initiated outside for loop to reuse (reduces garbage) 261 garrisonedEntities = cmpGarrison.GetEntities(); 262 for (var j = garrisonedEntities.length-1; j >= 0; j--) 263 { 264 garrisonedEntity = garrisonedEntities[j]; 265 cmpGarrison.Unload(garrisonedEntity, true); // always kick out entity 266 cmpNewGarrison.Garrison(garrisonedEntity); // then try to garrison 267 } 268 } 269 else 270 cmpGarrison.UnloadAll(true); 271 } 272 167 273 Engine.BroadcastMessage(MT_EntityRenamed, { entity: this.entity, newentity: newEntity }); 168 274 169 275 // Play notification sound -
binaries/data/mods/public/simulation/components/UnitAI.js
4380 4380 UnitAI.prototype.CanPack = function() 4381 4381 { 4382 4382 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 4383 return (cmpPack && !cmpPack.IsPacking() && !cmpPack.IsPacked() );4383 return (cmpPack && !cmpPack.IsPacking() && !cmpPack.IsPacked() && cmpPack.CanTransformHere()); 4384 4384 }; 4385 4385 4386 4386 UnitAI.prototype.CanUnpack = function() 4387 4387 { 4388 4388 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 4389 return (cmpPack && !cmpPack.IsPacking() && cmpPack.IsPacked() );4389 return (cmpPack && !cmpPack.IsPacking() && cmpPack.IsPacked() && cmpPack.CanTransformHere()); 4390 4390 }; 4391 4391 4392 4392 UnitAI.prototype.IsPacking = function() -
binaries/data/mods/public/simulation/components/ProductionQueue.js
148 148 return ret; 149 149 }; 150 150 151 /* 152 * Returns true if the given template can be produced by this entity 153 * @param templateName String of the template name 154 */ 155 ProductionQueue.prototype.CanAcceptTemplate = function(templateName) 156 { 157 var unitTemplates = this.GetEntitiesList(); 158 if (unitTemplates.indexOf(templateName) !== -1) 159 return true; 160 161 var techTemplates = this.GetTechnologiesList(); 162 for (var tech in techTemplates) 163 { 164 if (typeof tech === 'string' && tech === templateName) 165 return true; 166 else if (typeof tech === 'object' && (tech.top === templateName || tech.bottom === templateName)) 167 return true; 168 } 169 170 return false; 171 }; 172 151 173 ProductionQueue.prototype.IsTechnologyResearchedOrInProgress = function(tech) 152 174 { 153 175 if (!tech) … … 361 383 362 384 /* 363 385 * Returns basic data from all batches in the production queue. 386 * With complete = true, returns a full copy of the queue. 364 387 */ 365 ProductionQueue.prototype.GetQueue = function( )388 ProductionQueue.prototype.GetQueue = function(complete) 366 389 { 367 390 var out = []; 368 391 for each (var item in this.queue) 369 392 { 370 out.push({ 371 "id": item.id, 372 "unitTemplate": item.unitTemplate, 373 "technologyTemplate": item.technologyTemplate, 374 "count": item.count, 375 "neededSlots": item.neededSlots, 376 "progress": 1-(item.timeRemaining/item.timeTotal), 377 "metadata": item.metadata, 378 }); 393 if (complete) 394 { 395 var batch = { 396 "id": item.id, 397 "player": item.player, 398 "count": item.count, 399 "metadata": item.metadata, 400 "resources": item.resources, // need to copy to avoid serialization problems 401 "population": item.population, 402 "productionStarted": item.productionStarted, 403 "timeTotal": item.timeTotal, 404 "timeRemaining": item.timeRemaining 405 }; 406 if (item.unitTemplate) 407 batch["unitTemplate"] = item.unitTemplate; 408 if (item.technologyTemplate) 409 batch["technologyTemplate"] = item.technologyTemplate; 410 out.push(batch); 411 } 412 else 413 { 414 out.push({ 415 "id": item.id, 416 "unitTemplate": item.unitTemplate, 417 "technologyTemplate": item.technologyTemplate, 418 "count": item.count, 419 "neededSlots": item.neededSlots, 420 "progress": 1-(item.timeRemaining/item.timeTotal), 421 "metadata": item.metadata, 422 }); 423 } 379 424 } 380 425 return out; 381 426 }; … … 394 439 }; 395 440 396 441 /* 442 * Swaps the current queue for a new one. Only use this functionality 443 * to transfer a queue from one entity to another without rechecking validity. 444 * For other uses, please go with the other functions in this Component. 445 * @param queue New queue which replaces the current one. 446 */ 447 ProductionQueue.prototype.SetQueue = function(queue) 448 { 449 if (queue && typeof queue === 'object' && queue.length) // checks for type array 450 { 451 this.queue = queue; 452 Engine.PostMessage(this.entity, MT_ProductionQueueChanged, {}); 453 if (this.queue.length > 0 && !this.timer) // if 0 timer will expire on its own 454 { 455 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 456 this.timer = cmpTimer.SetTimeout(this.entity, IID_ProductionQueue, "ProgressTimeout", g_ProgressInterval, {}); 457 } 458 } 459 }; 460 461 /* 397 462 * Returns batch build time. 398 463 */ 399 464 ProductionQueue.prototype.GetBatchTime = function(batchSize)