Ticket #1919: pack_v2.patch
File pack_v2.patch, 14.2 KB (added by , 11 years ago) |
---|
-
binaries/data/mods/public/gui/session/unit_commands.js
1148 1148 else 1149 1149 rightUsed = false; 1150 1150 } 1151 else if (entState.pack) 1151 else 1152 rightUsed = false; 1153 1154 // An entity can have both trainable actions and pack/unpack commands 1155 if (entState.pack) 1152 1156 { 1153 1157 var items = []; 1154 1158 var packButton = false; … … 1188 1192 items.push({ "packing": true, "packed": true, "tooltip": "Cancel unpacking", "callback": function() { cancelPackUnit(false); } }); 1189 1193 1190 1194 if (items.length) 1195 { 1196 rightUsed = true; // might have gone false before, around line 1152 1191 1197 setupUnitPanel(PACK, usedPanels, entState, playerState, items); 1192 else 1193 rightUsed = false; 1198 } 1194 1199 } 1195 else1196 rightUsed = false;1197 1200 1198 1201 if (!rightUsed) 1199 1202 { -
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
4 4 5 5 function BuildingAI() {} 6 6 7 BuildingAI.prototype.Schema = 7 BuildingAI.prototype.Schema = 8 8 "<element name='DefaultArrowCount'>" + 9 9 "<data type='nonNegativeInteger'/>" + 10 10 "</element>" + … … 329 329 return true; 330 330 }; 331 331 332 /** 333 * All packing code taken and adapted from UnitAI 334 */ 335 BuildingAI.prototype.Pack = function() 336 { 337 // Check that we can pack 338 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 339 if (cmpPack && this.CanPack()) 340 cmpPack.Pack(); 341 }; 342 343 BuildingAI.prototype.Unpack = function() 344 { 345 // Check that we can unpack 346 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 347 if (cmpPack && this.CanUnpack()) 348 cmpPack.Unpack(); 349 }; 350 351 BuildingAI.prototype.CancelPack = function() 352 { 353 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 354 if (cmpPack && cmpPack.IsPacking() && !cmpPack.IsPacked()) 355 cmpPack.CancelPack(); 356 }; 357 358 BuildingAI.prototype.CancelUnpack = function() 359 { 360 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 361 if (cmpPack && cmpPack.IsPacking() && cmpPack.IsPacked()) 362 cmpPack.CancelUnpack(); 363 }; 364 365 BuildingAI.prototype.CanPack = function() 366 { 367 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 368 return (cmpPack && !cmpPack.IsPacking() && !cmpPack.IsPacked() && cmpPack.CanTransformHere()); 369 }; 370 371 BuildingAI.prototype.CanUnpack = function() 372 { 373 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 374 return (cmpPack && !cmpPack.IsPacking() && cmpPack.IsPacked() && cmpPack.CanTransformHere()); 375 }; 376 377 BuildingAI.prototype.IsPacking = function() 378 { 379 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 380 return (cmpPack && cmpPack.IsPacking()); 381 }; 382 332 383 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("preview|"+previewEntityTemplate); 65 66 if (previewEntity == INVALID_ENTITY) 67 return false; // Error (e.g. invalid template name) 68 else 69 { 70 var cmpBuildRestrictions = Engine.QueryInterface(previewEntity, IID_BuildRestrictions); 71 if (cmpBuildRestrictions) 72 { 73 // Position and ownership needs to be set for placement checks 74 var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); 75 var cmpNewPosition = Engine.QueryInterface(previewEntity, IID_Position); 76 if (cmpPosition.IsInWorld()) 77 { 78 var pos = cmpPosition.GetPosition2D(); 79 var angle = cmpPosition.GetRotation(); 80 cmpNewPosition.JumpTo(pos.x, pos.y); 81 cmpNewPosition.SetYRotation(angle.y); 82 } 83 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 84 var cmpNewOwnership = Engine.QueryInterface(previewEntity, IID_Ownership); 85 cmpNewOwnership.SetOwner(cmpOwnership.GetOwner()); 86 87 var checkPlacement = cmpBuildRestrictions.CheckPlacement(); 88 if (checkPlacement && !checkPlacement.success) 89 canTransform = false; print('\n'+JSON.stringify(checkPlacement, null, 2)); 90 // Move preview entity out of world so it won't interfere with additional calls 91 // to this function for this entity on the same sim update. 92 // Specifically, CheckPlacement() would incorrectly spot and fail on earlier preview entities 93 // if those are left in the world. 94 cmpNewPosition.MoveOutOfWorld(); 95 } 96 } 97 98 Engine.DestroyEntity(previewEntity); print('\nCanTransformHere: '+canTransform+'\n'); 99 return canTransform; 100 }; 101 52 102 Pack.prototype.Pack = function() 53 103 { 54 104 // Ignore pointless pack command … … 124 174 Engine.PostMessage(this.entity, MT_PackFinished, { packed: this.packed }); 125 175 126 176 // Done un/packing, copy our parameters to the final entity 127 var newEntity = Engine.AddEntity(this.template.Entity); 177 // Replace the "{civ}" codes with this entity's civ ID 178 var cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity); 179 var newEntityTemplate = this.template.Entity; 180 if (cmpIdentity) 181 newEntityTemplate = newEntityTemplate.replace(/\{civ\}/g, cmpIdentity.GetCiv()); 182 var newEntity = Engine.AddEntity(newEntityTemplate); 128 183 if (newEntity == INVALID_ENTITY) 129 184 { 130 185 // Error (e.g. invalid template names) … … 164 219 cmpNewUnitAI.AddOrders(cmpUnitAI.GetOrders()); 165 220 } 166 221 222 // Transfer production queue 223 // Note: default behaviour upon destroying an entity is to reset queue, 224 // that case is thus not handled here. 225 var cmpQueue = Engine.QueryInterface(this.entity, IID_ProductionQueue); 226 var cmpNewQueue = Engine.QueryInterface(newEntity, IID_ProductionQueue); 227 if (cmpQueue && cmpNewQueue) 228 { 229 var queue = cmpQueue.GetFullQueue(); // fn returns copy, not just summary 230 if (queue.length > 0) 231 { 232 var transferableQueue = []; 233 for (var i = queue.length-1; i >= 0; i--) 234 { 235 var templateName = queue[i].unitTemplate ? queue[i].unitTemplate : queue[i].technologyTemplate; 236 if (cmpNewQueue.CanAcceptTemplate(templateName)) 237 transferableQueue.push( queue.splice(i,1)[0] ); 238 } 239 cmpQueue.SetQueue(queue); // set old queue with untransferable batches 240 cmpNewQueue.SetQueue(transferableQueue); // set new queue with transferable batches 241 } 242 } 243 244 // Transfer garrisoned units if possible, or unload them 245 var cmpGarrison = Engine.QueryInterface(this.entity, IID_GarrisonHolder); 246 var cmpNewGarrison = Engine.QueryInterface(newEntity, IID_GarrisonHolder); 247 if (cmpGarrison && cmpGarrison.GetEntities().length > 0) 248 { 249 if (cmpNewGarrison) 250 { 251 // Note: the code cannot rely on the garrisoning entity's indexing 252 // due to removal of elements. This is why a reference to the 253 // garrisoned entity is stored in a temporary variable. 254 // Also, this is why a counting down for loop is used. 255 var garrisonedEntity, // initiated outside for loop to reuse (reduces garbage) 256 garrisonedEntities = cmpGarrison.GetEntities(); 257 for (var j = garrisonedEntities.length-1; j >= 0; j--) 258 { 259 garrisonedEntity = garrisonedEntities[j]; 260 cmpGarrison.Unload(garrisonedEntity, true); // always kick out entity 261 cmpNewGarrison.Garrison(garrisonedEntity); // then try to garrison 262 } 263 } 264 else 265 cmpGarrison.UnloadAll(true); 266 } 267 167 268 Engine.BroadcastMessage(MT_EntityRenamed, { entity: this.entity, newentity: newEntity }); 168 269 169 270 // Play notification sound -
binaries/data/mods/public/simulation/components/UnitAI.js
4491 4491 UnitAI.prototype.CanPack = function() 4492 4492 { 4493 4493 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 4494 return (cmpPack && !cmpPack.IsPacking() && !cmpPack.IsPacked() );4494 return (cmpPack && !cmpPack.IsPacking() && !cmpPack.IsPacked() && cmpPack.CanTransformHere()); 4495 4495 }; 4496 4496 4497 4497 UnitAI.prototype.CanUnpack = function() 4498 4498 { 4499 4499 var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); 4500 return (cmpPack && !cmpPack.IsPacking() && cmpPack.IsPacked() );4500 return (cmpPack && !cmpPack.IsPacking() && cmpPack.IsPacked() && cmpPack.CanTransformHere()); 4501 4501 }; 4502 4502 4503 4503 UnitAI.prototype.IsPacking = function() -
binaries/data/mods/public/simulation/components/BuildRestrictions.js
185 185 186 186 var pos = cmpPosition.GetPosition2D(); 187 187 var tileOwner = cmpTerritoryManager.GetOwner(pos.x, pos.y); 188 //print('\nTileOwner: '+tileOwner); 189 //print('\nPlayerID: '+cmpPlayer.GetPlayerID()); 188 190 var isOwn = (tileOwner == cmpPlayer.GetPlayerID()); 189 191 var isNeutral = (tileOwner == 0); 190 192 var isAlly = !isOwn && cmpPlayer.IsAlly(tileOwner); -
binaries/data/mods/public/simulation/components/ProductionQueue.js
153 153 return ret; 154 154 }; 155 155 156 /* 157 * Returns true if the given template can be produced by this entity 158 * @param templateName String of the template name 159 */ 160 ProductionQueue.prototype.CanAcceptTemplate = function(templateName) 161 { 162 var unitTemplates = this.GetEntitiesList(); 163 if (unitTemplates.indexOf(templateName) !== -1) 164 return true; 165 166 var techTemplates = this.GetTechnologiesList(); 167 for (var tech in techTemplates) 168 { 169 if (typeof tech === 'string' && tech === templateName) 170 return true; 171 else if (typeof tech === 'object' && (tech.top === templateName || tech.bottom === templateName)) 172 return true; 173 } 174 175 return false; 176 }; 177 156 178 ProductionQueue.prototype.IsTechnologyResearchedOrInProgress = function(tech) 157 179 { 158 180 if (!tech) … … 386 408 }; 387 409 388 410 /* 411 * Returns a copy of the batches in the production queue 412 * Compare with GetQueue function, which returns only basic data. 413 */ 414 ProductionQueue.prototype.GetFullQueue = function() 415 { 416 var out = []; 417 for each (var item in this.queue) 418 { 419 var batch = { 420 "id": item.id, 421 "player": item.player, 422 "count": item.count, 423 "metadata": item.metadata, 424 "resources": item.resources, // need to copy to avoid serialization problems 425 "population": item.population, 426 "productionStarted": item.productionStarted, 427 "timeTotal": item.timeTotal, 428 "timeRemaining": item.timeRemaining 429 }; 430 if (item.unitTemplate) 431 batch["unitTemplate"] = item.unitTemplate; 432 if (item.technologyTemplate) 433 batch["technologyTemplate"] = item.technologyTemplate; 434 out.push(batch); 435 } 436 return out; 437 }; 438 439 /* 389 440 * Removes all existing batches from the queue. 390 441 */ 391 442 ProductionQueue.prototype.ResetQueue = function() … … 399 450 }; 400 451 401 452 /* 453 * Swaps the current queue for a new one. Only use this functionality 454 * to transfer a queue from one entity to another without rechecking validity. 455 * This is useful when swapping one entity for another, e.g. when transforming. 456 * For other uses, please go with the other functions in this Component. 457 * 458 * @param queue New queue which replaces the current one. 459 */ 460 ProductionQueue.prototype.SetQueue = function(queue) 461 { 462 if (queue && typeof queue === 'object' && queue.length) // checks for type array 463 { 464 this.queue = queue; 465 Engine.PostMessage(this.entity, MT_ProductionQueueChanged, {}); 466 if (this.queue.length > 0 && !this.timer) // if 0 timer will expire on its own 467 { 468 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 469 this.timer = cmpTimer.SetTimeout(this.entity, IID_ProductionQueue, "ProgressTimeout", g_ProgressInterval, {}); 470 } 471 } 472 }; 473 474 /* 402 475 * Returns batch build time. 403 476 */ 404 477 ProductionQueue.prototype.GetBatchTime = function(batchSize)