Ticket #599: fogging.diff
File fogging.diff, 37.5 KB (added by , 10 years ago) |
---|
-
binaries/data/mods/public/gui/session/selection.js
diff --git binaries/data/mods/public/gui/session/selection.js binaries/data/mods/public/gui/session/selection.js index c678873..fd19fd6 100644
EntitySelection.prototype.getTemplateNames = function() 235 235 */ 236 236 EntitySelection.prototype.update = function() 237 237 { 238 var changed = false;239 238 this.checkRenamedEntities(); 239 240 var miraged = {}; 241 var changed = false; 240 242 for each (var ent in this.selected) 241 243 { 242 244 var entState = GetEntityState(ent); … … EntitySelection.prototype.update = function() 250 252 continue; 251 253 } 252 254 255 // Manually replace newly miraged entities by their mirages 256 if (entState.fogging && entState.fogging.mirage) 257 { 258 miraged[ent] = entState.fogging.mirage; 259 continue; 260 } 261 253 262 // Remove non-visible units (e.g. moved back into fog-of-war) 254 263 if (entState.visibility == "hidden") 255 264 { … … EntitySelection.prototype.update = function() 264 273 continue; 265 274 } 266 275 } 276 277 this.rebuildSelection(miraged); 278 267 279 if (changed) 268 280 this.onChange(); 269 281 }; -
binaries/data/mods/public/gui/session/selection_details.js
diff --git binaries/data/mods/public/gui/session/selection_details.js binaries/data/mods/public/gui/session/selection_details.js index 4d8a347..baa4d90 100644
function displaySingle(entState, template) 164 164 Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = sprintf(translate("Gain: %(amount)s"), { amount: getTradingTooltip(entState.trader.goods.amount) }); 165 165 } 166 166 // And for number of workers 167 else if (entState.foundation )167 else if (entState.foundation && !entState.mirage) 168 168 { 169 169 Engine.GetGUIObjectByName("resourceCarryingIcon").hidden = false; 170 170 Engine.GetGUIObjectByName("resourceCarryingText").hidden = false; … … function displaySingle(entState, template) 172 172 Engine.GetGUIObjectByName("resourceCarryingText").caption = entState.foundation.numBuilders + " "; 173 173 Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = sprintf(translate("Number of builders.\nTasking another to this foundation would speed construction up by %(numb)s%%"), { numb : Math.round((Math.pow((entState.foundation.numBuilders+1)/entState.foundation.numBuilders, 0.7) - 1.0)*100) }); 174 174 } 175 else if (entState.resourceSupply && (!entState.resourceSupply.killBeforeGather || !entState.hitpoints) )175 else if (entState.resourceSupply && (!entState.resourceSupply.killBeforeGather || !entState.hitpoints) && !entState.mirage) 176 176 { 177 177 Engine.GetGUIObjectByName("resourceCarryingIcon").hidden = false; 178 178 Engine.GetGUIObjectByName("resourceCarryingText").hidden = false; -
binaries/data/mods/public/gui/session/unit_actions.js
diff --git binaries/data/mods/public/gui/session/unit_actions.js binaries/data/mods/public/gui/session/unit_actions.js index 4c14055..1dab22c 100644
var g_EntityCommands = 656 656 "delete": { 657 657 "getInfo": function(entState) 658 658 { 659 if (entState.mirage) 660 return { 661 "tooltip": translate("You cannot destroy this entity because it is in the fog-of-war"), 662 "icon": "kill_small.png" 663 }; 664 659 665 return { 660 666 "tooltip": translate("Delete"), 661 667 "icon": "kill_small.png" … … var g_EntityCommands = 663 669 }, 664 670 "execute": function(entState) 665 671 { 672 if (entState.mirage) 673 return; 674 666 675 var selection = g_Selection.toList(); 667 676 if (selection.length < 1) 668 677 return; -
binaries/data/mods/public/simulation/components/BuildingAI.js
diff --git binaries/data/mods/public/simulation/components/BuildingAI.js binaries/data/mods/public/simulation/components/BuildingAI.js index 4eef15b..ef124d9 100644
BuildingAI.prototype.CheckTargetVisible = function(target) 335 335 336 336 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 337 337 338 // Entities that are hidden and miraged are considered visible 339 var cmpFogging = Engine.QueryInterface(target, IID_Fogging); 340 if (cmpFogging && cmpFogging.IsMiraged(cmpOwnership.GetOwner())) 341 return true; 342 338 343 if (cmpRangeManager.GetLosVisibility(target, cmpOwnership.GetOwner(), false) == "hidden") 339 344 return false; 340 345 -
new file inaries/data/mods/public/simulation/components/Fogging.js
diff --git binaries/data/mods/public/simulation/components/Fogging.js binaries/data/mods/public/simulation/components/Fogging.js new file mode 100644 index 0000000..87e6907
- + 1 const VIS_HIDDEN = 0; 2 const VIS_FOGGED = 1; 3 const VIS_VISIBLE = 2; 4 5 function Fogging() {} 6 7 Fogging.prototype.Schema = 8 "<a:help>Allows this entity to be replaced by mirages entities in the fog-of-war.</a:help>" + 9 "<empty/>"; 10 11 Fogging.prototype.Init = function() 12 { 13 this.mirages = []; 14 this.seen = []; 15 16 var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 17 for (var player = 0; player < cmpPlayerManager.GetNumPlayers(); ++player) 18 { 19 this.mirages.push(INVALID_ENTITY); 20 this.seen.push(false); 21 } 22 }; 23 24 Fogging.prototype.LoadMirage = function(player) 25 { 26 var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 27 var templateName = "mirage|" + cmpTemplateManager.GetCurrentTemplateName(this.entity); 28 29 // If this is an entity without visibility (e.g. a foundation), it should be 30 // marked as seen for its owner 31 var cmpParentOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 32 if (cmpParentOwnership && cmpParentOwnership.GetOwner() == player) 33 this.seen[player] = true; 34 35 if (!this.seen[player] || this.mirages[player] != INVALID_ENTITY) 36 return; 37 38 this.mirages[player] = Engine.AddEntity(templateName); 39 var cmpMirage = Engine.QueryInterface(this.mirages[player], IID_Mirage); 40 if (!cmpMirage) 41 { 42 error("Failed to load mirage entity for template " + templateName); 43 this.mirages[player] = INVALID_ENTITY; 44 return; 45 } 46 47 // Setup basic mirage properties 48 cmpMirage.SetPlayer(player); 49 cmpMirage.SetParent(this.entity); 50 51 // Copy cmpOwnership data 52 var cmpMirageOwnership = Engine.QueryInterface(this.mirages[player], IID_Ownership); 53 if (!cmpParentOwnership || !cmpMirageOwnership) 54 { 55 error("Failed to setup the ownership data of the fogged entity " + templateName); 56 return; 57 } 58 cmpMirageOwnership.SetOwner(cmpParentOwnership.GetOwner()); 59 60 // Copy cmpPosition data 61 var cmpParentPosition = Engine.QueryInterface(this.entity, IID_Position); 62 var cmpMiragePosition = Engine.QueryInterface(this.mirages[player], IID_Position); 63 if (!cmpParentPosition || !cmpMiragePosition) 64 { 65 error("Failed to setup the position data of the fogged entity " + templateName); 66 return; 67 } 68 if (!cmpParentPosition.IsInWorld()) 69 return; 70 var pos = cmpParentPosition.GetPosition(); 71 cmpMiragePosition.JumpTo(pos.x, pos.z); 72 var rot = cmpParentPosition.GetRotation(); 73 cmpMiragePosition.SetYRotation(rot.y); 74 cmpMiragePosition.SetXZRotation(rot.x, rot.z); 75 76 // Copy cmpVisualActor data 77 var cmpParentVisualActor = Engine.QueryInterface(this.entity, IID_Visual); 78 var cmpMirageVisualActor = Engine.QueryInterface(this.mirages[player], IID_Visual); 79 if (!cmpParentVisualActor || !cmpMirageVisualActor) 80 { 81 error("Failed to setup the visual data of the fogged entity " + templateName); 82 return; 83 } 84 cmpMirageVisualActor.SetActorSeed(cmpParentVisualActor.GetActorSeed()); 85 86 // Store valuable information into the mirage component (especially for the GUI) 87 var cmpFoundation = Engine.QueryInterface(this.entity, IID_Foundation); 88 if (cmpFoundation) 89 cmpMirage.AddFoundation(cmpFoundation.GetBuildPercentage()); 90 91 var cmpHealth = Engine.QueryInterface(this.entity, IID_Health); 92 if (cmpHealth) 93 cmpMirage.AddHealth( 94 cmpHealth.GetMaxHitpoints(), 95 cmpHealth.GetHitpoints(), 96 cmpHealth.IsRepairable() && (cmpHealth.GetHitpoints() < cmpHealth.GetMaxHitpoints()) 97 ); 98 99 var cmpResourceSupply = Engine.QueryInterface(this.entity, IID_ResourceSupply); 100 if (cmpResourceSupply) 101 cmpMirage.AddResourceSupply( 102 cmpResourceSupply.GetMaxAmount(), 103 cmpResourceSupply.GetCurrentAmount(), 104 cmpResourceSupply.GetType(), 105 cmpResourceSupply.IsInfinite() 106 ); 107 }; 108 109 Fogging.prototype.IsMiraged = function(player) 110 { 111 if (player >= this.mirages.length) 112 return false; 113 114 return this.mirages[player] != INVALID_ENTITY; 115 }; 116 117 Fogging.prototype.GetMirage = function(player) 118 { 119 if (player >= this.mirages.length) 120 return INVALID_ENTITY; 121 122 return this.mirages[player]; 123 }; 124 125 Fogging.prototype.WasSeen = function(player) 126 { 127 if (player >= this.seen.length) 128 return false; 129 130 return this.seen[player]; 131 }; 132 133 Fogging.prototype.OnVisibilityChanged = function(msg) 134 { 135 if (msg.player >= this.mirages.length) 136 return; 137 138 if (msg.newVisibility == VIS_VISIBLE) 139 { 140 this.seen[msg.player] = true; 141 142 // Destroy mirages when we get back into LoS 143 if (this.mirages[msg.player] != INVALID_ENTITY) 144 { 145 Engine.DestroyEntity(this.mirages[msg.player]); 146 this.mirages[msg.player] = INVALID_ENTITY; 147 } 148 } 149 150 // Intermediate LoS state, meaning we must create a mirage 151 if (msg.newVisibility == VIS_FOGGED) 152 this.LoadMirage(msg.player); 153 }; 154 155 Fogging.prototype.OnDestroy = function(msg) 156 { 157 for (var player = 0; player < this.mirages.length; ++player) 158 { 159 var cmpMirage = Engine.QueryInterface(this.mirages[player], IID_Mirage); 160 if (cmpMirage) 161 cmpMirage.SetParent(INVALID_ENTITY); 162 } 163 }; 164 165 Engine.RegisterComponentType(IID_Fogging, "Fogging", Fogging); -
binaries/data/mods/public/simulation/components/GuiInterface.js
diff --git binaries/data/mods/public/simulation/components/GuiInterface.js binaries/data/mods/public/simulation/components/GuiInterface.js index cfca3af..06196ab 100644
GuiInterface.prototype.GetEntityState = function(player, ent) 175 175 "alertRaiser": null, 176 176 "buildEntities": null, 177 177 "identity": null, 178 "fogging": null, 178 179 "foundation": null, 179 180 "garrisonHolder": null, 180 181 "gate": null, … … GuiInterface.prototype.GetEntityState = function(player, ent) 190 191 "visibility": null, 191 192 }; 192 193 194 // Used for several components 195 var cmpMirage = Engine.QueryInterface(ent, IID_Mirage); 196 193 197 var cmpIdentity = Engine.QueryInterface(ent, IID_Identity); 194 198 if (cmpIdentity) 195 199 { … … GuiInterface.prototype.GetEntityState = function(player, ent) 216 220 ret.needsRepair = cmpHealth.IsRepairable() && (cmpHealth.GetHitpoints() < cmpHealth.GetMaxHitpoints()); 217 221 ret.needsHeal = !cmpHealth.IsUnhealable(); 218 222 } 223 if (cmpMirage && cmpMirage.Health()) 224 { 225 ret.hitpoints = cmpMirage.GetHitpoints(); 226 ret.maxHitpoints = cmpMirage.GetMaxHitpoints(); 227 ret.needsRepair = cmpMirage.NeedsRepair(); 228 } 219 229 220 230 var cmpBuilder = Engine.QueryInterface(ent, IID_Builder); 221 231 if (cmpBuilder) … … GuiInterface.prototype.GetEntityState = function(player, ent) 251 261 }; 252 262 } 253 263 264 var cmpFogging = Engine.QueryInterface(ent, IID_Fogging); 265 if (cmpFogging) 266 { 267 if (cmpFogging.IsMiraged(player)) 268 ret.fogging = {"mirage": cmpFogging.GetMirage(player)}; 269 else 270 ret.fogging = {"mirage": null}; 271 } 272 254 273 var cmpFoundation = Engine.QueryInterface(ent, IID_Foundation); 255 274 if (cmpFoundation) 256 275 { … … GuiInterface.prototype.GetEntityState = function(player, ent) 259 278 "numBuilders": cmpFoundation.GetNumBuilders() 260 279 }; 261 280 } 281 if (cmpMirage && cmpMirage.Foundation()) 282 { 283 ret.foundation = { 284 "progress": cmpMirage.GetBuildPercentage() 285 }; 286 } 262 287 263 288 var cmpOwnership = Engine.QueryInterface(ent, IID_Ownership); 264 289 if (cmpOwnership) … … GuiInterface.prototype.GetExtendedEntityState = function(player, ent) 342 367 "barterMarket": null, 343 368 "buildingAI": null, 344 369 "healer": null, 370 "mirage": null, 345 371 "obstruction": null, 346 372 "turretParent":null, 347 373 "promotion": null, … … GuiInterface.prototype.GetExtendedEntityState = function(player, ent) 351 377 "resourceSupply": null, 352 378 }; 353 379 380 var cmpMirage = Engine.QueryInterface(ent, IID_Mirage); 381 if (cmpMirage) 382 ret.mirage = true; 383 354 384 var cmpIdentity = Engine.QueryInterface(ent, IID_Identity); 355 385 356 386 var cmpAttack = Engine.QueryInterface(ent, IID_Attack); … … GuiInterface.prototype.GetExtendedEntityState = function(player, ent) 445 475 "gatherers": cmpResourceSupply.GetGatherers() 446 476 }; 447 477 } 478 if (cmpMirage && cmpMirage.ResourceSupply()) 479 { 480 ret.resourceSupply = { 481 "max": cmpMirage.GetMaxAmount(), 482 "amount": cmpMirage.GetAmount(), 483 "type": cmpMirage.GetType(), 484 "isInfinite": cmpMirage.IsInfinite() 485 }; 486 } 448 487 449 488 var cmpResourceGatherer = Engine.QueryInterface(ent, IID_ResourceGatherer); 450 489 if (cmpResourceGatherer) -
new file inaries/data/mods/public/simulation/components/Mirage.js
diff --git binaries/data/mods/public/simulation/components/Mirage.js binaries/data/mods/public/simulation/components/Mirage.js new file mode 100644 index 0000000..9306149
- + 1 const VIS_HIDDEN = 0; 2 const VIS_FOGGED = 1; 3 const VIS_VISIBLE = 2; 4 5 function Mirage() {} 6 7 Mirage.prototype.Schema = 8 "<a:help>Mirage entities replace real entities in the fog-of-war.</a:help>" + 9 "<empty/>"; 10 11 Mirage.prototype.Init = function() 12 { 13 this.player = null; 14 this.parent = INVALID_ENTITY; 15 16 this.foundation = false; 17 this.buildPercentage = null; 18 19 this.health = false; 20 this.maxHitpoints = null; 21 this.hitpoints = null; 22 this.needsRepair = null; 23 24 this.resourceSupply = false; 25 this.maxAmount = null; 26 this.amount = null; 27 this.type = null; 28 this.isInfinite = null; 29 }; 30 31 Mirage.prototype.SetParent = function(ent) 32 { 33 this.parent = ent; 34 }; 35 36 Mirage.prototype.GetPlayer = function() 37 { 38 return this.player; 39 }; 40 41 Mirage.prototype.SetPlayer = function(player) 42 { 43 this.player = player; 44 }; 45 46 // ============================ 47 // Parent entity data 48 49 // Foundation data 50 51 Mirage.prototype.AddFoundation = function(buildPercentage) 52 { 53 this.foundation = true; 54 this.buildPercentage = buildPercentage; 55 }; 56 57 Mirage.prototype.Foundation = function() 58 { 59 return this.foundation; 60 }; 61 62 Mirage.prototype.GetBuildPercentage = function() 63 { 64 return this.buildPercentage; 65 }; 66 67 // Health data 68 69 Mirage.prototype.AddHealth = function(maxHitpoints, hitpoints, needsRepair) 70 { 71 this.health = true; 72 this.maxHitpoints = maxHitpoints; 73 this.hitpoints = Math.ceil(hitpoints); 74 this.needsRepair = needsRepair; 75 }; 76 77 Mirage.prototype.Health = function() 78 { 79 return this.health; 80 }; 81 82 Mirage.prototype.GetMaxHitpoints = function() 83 { 84 return this.maxHitpoints; 85 }; 86 87 Mirage.prototype.GetHitpoints = function() 88 { 89 return this.hitpoints; 90 }; 91 92 Mirage.prototype.NeedsRepair = function() 93 { 94 return this.needsRepair; 95 }; 96 97 // ResourceSupply data 98 99 Mirage.prototype.AddResourceSupply = function(maxAmount, amount, type, isInfinite) 100 { 101 this.resourceSupply = true; 102 this.maxAmount = maxAmount; 103 this.amount = amount; 104 this.type = type; 105 this.isInfinite = isInfinite; 106 }; 107 108 Mirage.prototype.ResourceSupply = function() 109 { 110 return this.resourceSupply; 111 }; 112 113 Mirage.prototype.GetMaxAmount = function() 114 { 115 return this.maxAmount; 116 }; 117 118 Mirage.prototype.GetAmount = function() 119 { 120 return this.amount; 121 }; 122 123 Mirage.prototype.GetType = function() 124 { 125 return this.type; 126 }; 127 128 Mirage.prototype.IsInfinite = function() 129 { 130 return this.isInfinite; 131 }; 132 133 // ============================ 134 135 Mirage.prototype.OnVisibilityChanged = function(msg) 136 { 137 if (msg.player == this.player && msg.newVisibility == VIS_VISIBLE && this.parent == INVALID_ENTITY) 138 Engine.DestroyEntity(this.entity); 139 }; 140 141 Mirage.prototype.OnDestroy = function(msg) 142 { 143 if (this.parent == INVALID_ENTITY) 144 return; 145 146 Engine.BroadcastMessage(MT_EntityRenamed, { entity: this.entity, newentity: this.parent }); 147 }; 148 149 Engine.RegisterComponentType(IID_Mirage, "Mirage", Mirage); -
binaries/data/mods/public/simulation/components/ResourceGatherer.js
diff --git binaries/data/mods/public/simulation/components/ResourceGatherer.js binaries/data/mods/public/simulation/components/ResourceGatherer.js index 201eb67..2d5fc4c 100644
ResourceGatherer.prototype.GetTargetGatherRate = function(target) 243 243 { 244 244 var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); 245 245 246 var type; 246 247 var cmpResourceSupply = Engine.QueryInterface(target, IID_ResourceSupply); 247 if (!cmpResourceSupply) 248 var cmpMirage = Engine.QueryInterface(target, IID_Mirage); 249 if (cmpResourceSupply) 250 type = cmpResourceSupply.GetType(); 251 else if (cmpMirage && cmpMirage.ResourceSupply()) 252 type = cmpMirage.GetType(); 253 else 248 254 return 0; 249 255 250 var type = cmpResourceSupply.GetType();251 252 256 var rates = this.GetGatherRates(); 253 257 254 258 var rate; … … ResourceGatherer.prototype.GetTargetGatherRate = function(target) 261 265 rate = rates[type.generic] / cmpPlayer.GetCheatTimeMultiplier(); 262 266 } 263 267 268 if (cmpMirage) 269 return rate || 0; 270 264 271 // Apply diminishing returns with more gatherers, for e.g. infinite farms. For most resources this has no effect. (GetDiminishingReturns will return null.) 272 // We can assume that for resources that are miraged this is the case. (else just add the diminishing returns data to the mirage data and remove the 273 // early return above) 265 274 // Note to people looking to change <DiminishingReturns> in a template: This is a bit complicated. Basically, the lower that number is 266 275 // the steeper diminishing returns will be. I suggest playing around with Wolfram Alpha or a graphing calculator a bit. 267 276 // In each of the following links, replace 0.65 with the gather rate of your worker for the resource with diminishing returns and -
binaries/data/mods/public/simulation/components/UnitAI.js
diff --git binaries/data/mods/public/simulation/components/UnitAI.js binaries/data/mods/public/simulation/components/UnitAI.js index 8aa0c0a..22e1190 100644
UnitAI.prototype.UnitFsmSpec = { 1987 1987 // check that we can gather from the resource we're supposed to gather from. 1988 1988 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 1989 1989 var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); 1990 if (!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)) 1990 var cmpMirage = Engine.QueryInterface(this.gatheringTarget, IID_Mirage); 1991 if ((!cmpMirage || !cmpMirage.ResourceSupply()) && 1992 (!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity))) 1991 1993 { 1992 1994 // Save the current order's data in case we need it later 1993 1995 var oldType = this.order.data.type; … … UnitAI.prototype.TargetIsAlive = function(ent) 3896 3898 if (cmpFormation) 3897 3899 return true; 3898 3900 3901 var cmpMirage = Engine.QueryInterface(ent, IID_Mirage); 3902 if (cmpMirage) 3903 return true; 3904 3899 3905 var cmpHealth = Engine.QueryInterface(ent, IID_Health); 3900 3906 if (!cmpHealth) 3901 3907 return false; … … UnitAI.prototype.CheckTargetVisible = function(target) 4386 4392 if (!cmpRangeManager) 4387 4393 return false; 4388 4394 4395 // Entities that are hidden and miraged are considered visible 4396 var cmpFogging = Engine.QueryInterface(target, IID_Fogging); 4397 if (cmpFogging && cmpFogging.IsMiraged(cmpOwnership.GetOwner())) 4398 return true; 4399 4389 4400 if (cmpRangeManager.GetLosVisibility(target, cmpOwnership.GetOwner(), false) == "hidden") 4390 4401 return false; 4391 4402 … … UnitAI.prototype.PerformGather = function(target, queued, force) 5007 5018 // Save the resource type now, so if the resource gets destroyed 5008 5019 // before we process the order then we still know what resource 5009 5020 // type to look for more of 5021 var type; 5010 5022 var cmpResourceSupply = Engine.QueryInterface(target, IID_ResourceSupply); 5011 var type = cmpResourceSupply.GetType(); 5023 var cmpMirage = Engine.QueryInterface(target, IID_Mirage); 5024 if (cmpResourceSupply) 5025 type = cmpResourceSupply.GetType(); 5026 else if (cmpMirage && cmpMirage.ResourceSupply()) 5027 type = cmpMirage.GetType(); 5028 else 5029 error("CanGather allowed gathering from invalid entity"); 5012 5030 5013 5031 // Also save the target entity's template, so that if it's an animal, 5014 5032 // we won't go from hunting slow safe animals to dangerous fast ones … … UnitAI.prototype.CanGather = function(target) 5552 5570 { 5553 5571 if (this.IsTurret()) 5554 5572 return false; 5555 // The target must be a valid resource supply .5573 // The target must be a valid resource supply, or the mirage of one. 5556 5574 var cmpResourceSupply = Engine.QueryInterface(target, IID_ResourceSupply); 5557 if (!cmpResourceSupply) 5575 var cmpMirage = Engine.QueryInterface(target, IID_Mirage); 5576 if (!cmpResourceSupply && !(cmpMirage && cmpMirage.ResourceSupply())) 5558 5577 return false; 5559 5578 5560 5579 // Formation controllers should always respond to commands -
binaries/data/mods/public/simulation/components/interfaces/Messages.js
diff --git binaries/data/mods/public/simulation/components/interfaces/Messages.js binaries/data/mods/public/simulation/components/interfaces/Messages.js index c4f6c6f..ae3d8fc 100644
1 1 /** 2 2 * Broadcast message 3 3 * sent when one entity is changed to other: 4 * from Foundation component when building constuction is done 5 * and from Promotion component when unit is promoted 4 * - from Foundation component when building construction is done 5 * - from Promotion component when unit is promoted 6 * - from Mirage component when a fogged entity is re-discovered 6 7 * Data: { entity: <integer>, newentity: <integer> } 7 8 */ 8 9 Engine.RegisterMessageType("EntityRenamed"); -
binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js
diff --git binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js index 0ae49bc..197785d 100644
TS_ASSERT_UNEVAL_EQUALS(cmp.GetEntityState(-1, 10), { 398 398 visibleClasses: ["class3", "class4"], 399 399 selectionGroupName: "Selection Group Name", 400 400 }, 401 fogging: null, 401 402 foundation: null, 402 403 garrisonHolder: null, 403 404 gate: null, … … TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedEntityState(-1, 10), { 425 426 }, 426 427 buildingAI: null, 427 428 healer: null, 429 mirage: null, 428 430 obstruction: null, 429 431 turretParent: null, 430 432 promotion: null, -
binaries/data/mods/public/simulation/helpers/Commands.js
diff --git binaries/data/mods/public/simulation/helpers/Commands.js binaries/data/mods/public/simulation/helpers/Commands.js index 6cc67a3..90e28c5 100644
function TryConstructBuilding(player, cmpPlayer, controlAllUnits, cmd) 974 974 "queued": cmd.queued 975 975 }); 976 976 } 977 978 // Load a mirage for the owner of this new entity 979 var cmpFogging = Engine.QueryInterface(ent, IID_Fogging) 980 if (cmpFogging) 981 cmpFogging.LoadMirage(player); 977 982 978 983 return ent; 979 984 } -
binaries/data/mods/public/simulation/templates/template_gaia.xml
diff --git binaries/data/mods/public/simulation/templates/template_gaia.xml binaries/data/mods/public/simulation/templates/template_gaia.xml index 27744da..7a5f54b 100644
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 <Entity parent="template_entity_quasi"> 3 <Fogging/> 3 4 <Identity> 4 5 <Civ>gaia</Civ> 5 6 <GenericName>Gaia</GenericName> -
binaries/data/mods/public/simulation/templates/template_structure.xml
diff --git binaries/data/mods/public/simulation/templates/template_structure.xml binaries/data/mods/public/simulation/templates/template_structure.xml index 6272e33..47cc0ef 100644
37 37 <SinkRate>3.0</SinkRate> 38 38 <SinkAccel>9.8</SinkAccel> 39 39 </Decay> 40 <Fogging/> 40 41 <Health> 41 42 <DeathType>corpse</DeathType> 42 43 <RegenRate>0</RegenRate> -
source/ps/TemplateLoader.cpp
diff --git source/ps/TemplateLoader.cpp source/ps/TemplateLoader.cpp index 4ef7374..3c985fc 100644
bool CTemplateLoader::LoadTemplateFile(const std::string& templateName, int dept 80 80 return true; 81 81 } 82 82 83 // Handle special case "mirage|foo" 84 if (templateName.find("mirage|") == 0) 85 { 86 // Load the base entity template, if it wasn't already loaded 87 std::string baseName = templateName.substr(7); 88 if (!LoadTemplateFile(baseName, depth+1)) 89 { 90 LOGERROR(L"Failed to load entity template '%hs'", baseName.c_str()); 91 return false; 92 } 93 // Copy a subset to the requested template 94 CopyMirageSubset(m_TemplateFileData[templateName], m_TemplateFileData[baseName]); 95 return true; 96 } 97 83 98 // Handle special case "foundation|foo" 84 99 if (templateName.find("foundation|") == 0) 85 100 { … … void CTemplateLoader::CopyPreviewSubset(CParamNode& out, const CParamNode& in, b 383 398 } 384 399 } 385 400 401 void CTemplateLoader::CopyMirageSubset(CParamNode& out, const CParamNode& in) 402 { 403 // Currently used for mirage entities replacing real ones in fog-of-war 404 405 std::set<std::string> permittedComponentTypes; 406 permittedComponentTypes.insert("Footprint"); 407 permittedComponentTypes.insert("Minimap"); 408 permittedComponentTypes.insert("Ownership"); 409 permittedComponentTypes.insert("Position"); 410 permittedComponentTypes.insert("Selectable"); 411 permittedComponentTypes.insert("VisualActor"); 412 413 CParamNode::LoadXMLString(out, "<Entity/>"); 414 out.CopyFilteredChildrenOfChild(in, "Entity", permittedComponentTypes); 415 416 // Select a subset of identity data. We don't want to have, for example, a CC mirage 417 // that has also the CC class and then prevents construction of other CCs 418 std::set<std::string> identitySubset; 419 identitySubset.insert("Civ"); 420 identitySubset.insert("GenericName"); 421 identitySubset.insert("SpecificName"); 422 identitySubset.insert("Tooltip"); 423 identitySubset.insert("History"); 424 identitySubset.insert("Icon"); 425 CParamNode identity; 426 CParamNode::LoadXMLString(identity, "<Identity/>"); 427 identity.CopyFilteredChildrenOfChild(in.GetChild("Entity"), "Identity", identitySubset); 428 CParamNode::LoadXMLString(out, ("<Entity>"+utf8_from_wstring(identity.ToXML())+"</Entity>").c_str()); 429 430 // Set the entity as mirage entity 431 CParamNode::LoadXMLString(out, "<Entity><Mirage/></Entity>"); 432 CParamNode::LoadXMLString(out, "<Entity><Vision><Range>0</Range><RetainInFog>true</RetainInFog><AlwaysVisible>false</AlwaysVisible></Vision></Entity>"); 433 } 434 386 435 void CTemplateLoader::CopyFoundationSubset(CParamNode& out, const CParamNode& in) 387 436 { 388 437 // TODO: this is all kind of yucky and hard-coded; it'd be nice to have a more generic … … void CTemplateLoader::CopyFoundationSubset(CParamNode& out, const CParamNode& in 397 446 permittedComponentTypes.insert("Obstruction"); 398 447 permittedComponentTypes.insert("Selectable"); 399 448 permittedComponentTypes.insert("Footprint"); 449 permittedComponentTypes.insert("Fogging"); 400 450 permittedComponentTypes.insert("Armour"); 401 451 permittedComponentTypes.insert("Health"); 402 452 permittedComponentTypes.insert("StatusBars"); -
source/ps/TemplateLoader.h
diff --git source/ps/TemplateLoader.h source/ps/TemplateLoader.h index 7217b69..30888b6 100644
private: 79 79 void CopyPreviewSubset(CParamNode& out, const CParamNode& in, bool corpse); 80 80 81 81 /** 82 * Copy the components of an entity template necessary for a fogged "mirage" 83 * entity (position, actor) into a new entity template 84 */ 85 void CopyMirageSubset(CParamNode& out, const CParamNode& in); 86 87 /** 82 88 * Copy the components of an entity template necessary for a construction foundation 83 89 * (position, actor, armour, health, etc) into a new entity template 84 90 */ -
source/simulation2/TypeList.h
diff --git source/simulation2/TypeList.h source/simulation2/TypeList.h index 8525a1c..eb5ac6a 100644
COMPONENT(CommandQueue) 81 81 INTERFACE(Decay) 82 82 COMPONENT(Decay) 83 83 84 INTERFACE(Fogging) 85 COMPONENT(FoggingScripted) 86 84 87 // Note: The VisualActor component relies on this component being initialized before itself, in order to support using 85 88 // an entity's footprint shape for the selection boxes. This dependency is not strictly necessary, but it does avoid 86 89 // some extra plumbing code to set up on-demand initialization. If you find yourself forced to break this dependency, … … COMPONENT(IdentityScripted) 97 100 INTERFACE(Minimap) 98 101 COMPONENT(Minimap) 99 102 103 INTERFACE(Mirage) 104 COMPONENT(MirageScripted) 105 100 106 INTERFACE(Motion) 101 107 COMPONENT(MotionBall) 102 108 COMPONENT(MotionScripted) -
source/simulation2/components/CCmpRangeManager.cpp
diff --git source/simulation2/components/CCmpRangeManager.cpp source/simulation2/components/CCmpRangeManager.cpp index 4fca628..f61deab 100644
23 23 #include "ICmpTerrain.h" 24 24 #include "simulation2/system/EntityMap.h" 25 25 #include "simulation2/MessageTypes.h" 26 #include "simulation2/components/ICmpFogging.h" 27 #include "simulation2/components/ICmpMirage.h" 28 #include "simulation2/components/ICmpOwnership.h" 26 29 #include "simulation2/components/ICmpPosition.h" 27 30 #include "simulation2/components/ICmpTerritoryManager.h" 28 31 #include "simulation2/components/ICmpVision.h" … … public: 564 567 case MT_Update: 565 568 { 566 569 m_DebugOverlayDirty = true; 567 UpdateTerritoriesLos();568 570 ExecuteActiveQueries(); 569 571 UpdateVisibilityData(); 570 572 break; … … public: 1401 1403 return VIS_VISIBLE; 1402 1404 } 1403 1405 1406 // Mirage entities, whatever their position, are visible for one specific player 1407 CmpPtr<ICmpMirage> cmpMirage(ent); 1408 if (cmpMirage && cmpMirage->GetPlayer() != player) 1409 return VIS_HIDDEN; 1410 1404 1411 // Visible if within a visible region 1405 1412 CLosQuerier los(GetSharedLosMask(player), m_LosState, m_TerrainVerticesPerSide); 1406 1413 1407 1414 if (los.IsVisible(i, j)) 1408 1415 return VIS_VISIBLE; 1409 1416 1417 if (!los.IsExplored(i, j)) 1418 return VIS_HIDDEN; 1419 1410 1420 // Fogged if the 'retain in fog' flag is set, and in a non-visible explored region 1411 if (los.IsExplored(i, j)) 1421 CmpPtr<ICmpVision> cmpVision(ent); 1422 if (!forceRetainInFog && !(cmpVision && cmpVision->GetRetainInFog())) 1423 return VIS_HIDDEN; 1424 1425 if (cmpMirage && cmpMirage->GetPlayer() == player) 1426 return VIS_FOGGED; 1427 1428 CmpPtr<ICmpOwnership> cmpOwnership(ent); 1429 if (!cmpOwnership) 1430 return VIS_VISIBLE; 1431 1432 if (cmpOwnership->GetOwner() == player) 1412 1433 { 1413 CmpPtr<ICmpVision> cmpVision(ent); 1414 if (forceRetainInFog || (cmpVision && cmpVision->GetRetainInFog())) 1434 CmpPtr<ICmpFogging> cmpFogging(ent); 1435 if (!cmpFogging) 1436 return VIS_VISIBLE; 1437 1438 // Fogged entities must not disappear while the mirage is not ready 1439 if (!cmpFogging->IsMiraged(player)) 1415 1440 return VIS_FOGGED; 1416 }1417 1441 1418 // Otherwise not visible 1442 return VIS_HIDDEN; 1443 } 1444 1445 // Fogged entities must not disappear while the mirage is not ready 1446 CmpPtr<ICmpFogging> cmpFogging(ent); 1447 if (cmpFogging && cmpFogging->WasSeen(player) && !cmpFogging->IsMiraged(player)) 1448 return VIS_FOGGED; 1449 1419 1450 return VIS_HIDDEN; 1420 1451 } 1421 1452 … … public: 1487 1518 EntityMap<EntityData>::iterator itEnts = m_EntityData.find(ent); 1488 1519 if (itEnts == m_EntityData.end()) 1489 1520 return; 1521 1522 std::vector<u8> oldVisibilities; 1523 std::vector<u8> newVisibilities; 1490 1524 1491 for (player_id_t player = 1; player < = MAX_LOS_PLAYER_ID; ++player)1525 for (player_id_t player = 1; player < MAX_LOS_PLAYER_ID+1; ++player) 1492 1526 { 1493 1527 u8 oldVis = (itEnts->second.visibilities >> (2*(player-1))) & 0x3; 1494 1528 u8 newVis = GetLosVisibility(itEnts->first, player, false); 1529 1530 oldVisibilities.push_back(oldVis); 1531 newVisibilities.push_back(newVis); 1495 1532 1496 1533 if (oldVis != newVis) 1497 {1498 CMessageVisibilityChanged msg(player, ent, oldVis, newVis);1499 GetSimContext().GetComponentManager().PostMessage(ent, msg);1500 1534 itEnts->second.visibilities = (itEnts->second.visibilities & ~(0x3 << 2*(player-1))) | (newVis << 2*(player-1)); 1501 } 1535 } 1536 1537 for (player_id_t player = 1; player < MAX_LOS_PLAYER_ID+1; ++player) 1538 { 1539 if (oldVisibilities[player-1] == newVisibilities[player-1]) 1540 continue; 1541 1542 CMessageVisibilityChanged msg(player, ent, oldVisibilities[player-1], newVisibilities[player-1]); 1543 GetSimContext().GetComponentManager().PostMessage(ent, msg); 1502 1544 } 1503 1545 } 1504 1546 -
new file source/simulation2/components/ICmpFogging.cpp
diff --git source/simulation2/components/ICmpFogging.cpp source/simulation2/components/ICmpFogging.cpp new file mode 100644 index 0000000..a981adb
- + 1 /* Copyright (C) 2014 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "precompiled.h" 19 20 #include "ICmpFogging.h" 21 22 #include "simulation2/scripting/ScriptComponent.h" 23 #include "simulation2/system/InterfaceScripted.h" 24 25 BEGIN_INTERFACE_WRAPPER(Fogging) 26 END_INTERFACE_WRAPPER(Fogging) 27 28 class CCmpFoggingScripted : public ICmpFogging 29 { 30 public: 31 DEFAULT_SCRIPT_WRAPPER(FoggingScripted) 32 33 virtual bool WasSeen(player_id_t player) 34 { 35 return m_Script.Call<bool>("WasSeen", player); 36 } 37 38 virtual bool IsMiraged(player_id_t player) 39 { 40 return m_Script.Call<bool>("IsMiraged", player); 41 } 42 }; 43 44 REGISTER_COMPONENT_SCRIPT_WRAPPER(FoggingScripted) -
new file source/simulation2/components/ICmpFogging.h
diff --git source/simulation2/components/ICmpFogging.h source/simulation2/components/ICmpFogging.h new file mode 100644 index 0000000..cd759f6
- + 1 /* Copyright (C) 2014 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef INCLUDED_ICMPFOGGING 19 #define INCLUDED_ICMPFOGGING 20 21 #include "simulation2/system/Interface.h" 22 23 #include "simulation2/helpers/Player.h" 24 25 /** 26 * Handles the fogging of out-of-sight enemy entities, by creating mirage 27 * entities. 28 * This allows hiding changes, especially destruction status or health. 29 */ 30 class ICmpFogging : public IComponent 31 { 32 public: 33 virtual bool WasSeen(player_id_t player) = 0; 34 virtual bool IsMiraged(player_id_t player) = 0; 35 36 DECLARE_INTERFACE_TYPE(Fogging) 37 }; 38 39 #endif // INCLUDED_ICMPFOGGING -
new file source/simulation2/components/ICmpMirage.cpp
diff --git source/simulation2/components/ICmpMirage.cpp source/simulation2/components/ICmpMirage.cpp new file mode 100644 index 0000000..80ceaca
- + 1 /* Copyright (C) 2014 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "precompiled.h" 19 20 #include "ICmpMirage.h" 21 22 #include "simulation2/scripting/ScriptComponent.h" 23 #include "simulation2/system/InterfaceScripted.h" 24 25 BEGIN_INTERFACE_WRAPPER(Mirage) 26 END_INTERFACE_WRAPPER(Mirage) 27 28 class CCmpMirageScripted : public ICmpMirage 29 { 30 public: 31 DEFAULT_SCRIPT_WRAPPER(MirageScripted) 32 33 virtual player_id_t GetPlayer() 34 { 35 return m_Script.Call<player_id_t>("GetPlayer"); 36 } 37 }; 38 39 REGISTER_COMPONENT_SCRIPT_WRAPPER(MirageScripted) -
new file source/simulation2/components/ICmpMirage.h
diff --git source/simulation2/components/ICmpMirage.h source/simulation2/components/ICmpMirage.h new file mode 100644 index 0000000..5edb227
- + 1 /* Copyright (C) 2014 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef INCLUDED_ICMPMIRAGE 19 #define INCLUDED_ICMPMIRAGE 20 21 #include "simulation2/system/Interface.h" 22 23 #include "simulation2/helpers/Player.h" 24 25 /** 26 * Component allowing mirage entities to communicate with their parent entity. 27 * See ICmpFogging. 28 */ 29 class ICmpMirage : public IComponent 30 { 31 public: 32 virtual player_id_t GetPlayer() = 0; 33 34 DECLARE_INTERFACE_TYPE(Mirage) 35 }; 36 37 #endif // INCLUDED_ICMPMIRAGE