Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: 0ad/0ad
base: 430979a090
...
head fork: 0ad/0ad
compare: ff96131ebf
Checking mergeability… Don't worry, you can still create the pull request.
  • 10 commits
  • 27 files changed
  • 0 commit comments
  • 5 contributors
Commits on May 01, 2012
philip Fix vector allocator types
git-svn-id: http://svn.wildfiregames.com/public/ps/trunk@11708 3db68df2-c116-0410-a063-a993310a9797
17d6434
Pureon Stockbreeding tech for the corral
git-svn-id: http://svn.wildfiregames.com/public/ps/trunk@11709 3db68df2-c116-0410-a063-a993310a9797
6a52530
leper Add Preferred and RestrictedClasses, based on patch by Zsol. Fixes #1…
…144.

git-svn-id: http://svn.wildfiregames.com/public/ps/trunk@11710 3db68df2-c116-0410-a063-a993310a9797
5b53f3e
ben Implements TerritoryInfluence/Radius tech modification. Adds C++ inte…
…rface for TechnologyManager. Renames its message to MT_TechnologyModification defined in TypeList.h. Refs #1357.

git-svn-id: http://svn.wildfiregames.com/public/ps/trunk@11711 3db68df2-c116-0410-a063-a993310a9797
b2d76a1
ben git-svn-id: http://svn.wildfiregames.com/public/ps/trunk@11712 3db68d…
…f2-c116-0410-a063-a993310a9797
7d87448
ben git-svn-id: http://svn.wildfiregames.com/public/ps/trunk@11713 3db68d…
…f2-c116-0410-a063-a993310a9797
6ed7776
ben ...
git-svn-id: http://svn.wildfiregames.com/public/ps/trunk@11714 3db68df2-c116-0410-a063-a993310a9797
8d3e314
Pureon Trade convoys tech for the market
git-svn-id: http://svn.wildfiregames.com/public/ps/trunk@11715 3db68df2-c116-0410-a063-a993310a9797
0b2659a
leper Check if we have a postition.
git-svn-id: http://svn.wildfiregames.com/public/ps/trunk@11716 3db68df2-c116-0410-a063-a993310a9797
4a634cb
@KieranP KieranP Merge remote-tracking branch 'remotes/trunk' ff96131
Showing with 398 additions and 41 deletions.
  1. +1 −1  binaries/data/mods/public/gui/session/input.js
  2. +4 −3 binaries/data/mods/public/simulation/ai/qbot/economy.js
  3. +140 −7 binaries/data/mods/public/simulation/components/Attack.js
  4. +13 −4 binaries/data/mods/public/simulation/components/GuiInterface.js
  5. +1 −1  binaries/data/mods/public/simulation/components/TechnologyManager.js
  6. +28 −7 binaries/data/mods/public/simulation/components/UnitAI.js
  7. +0 −5 binaries/data/mods/public/simulation/components/interfaces/TechnologyManager.js
  8. +3 −0  binaries/data/mods/public/simulation/components/tests/test_UnitAI.js
  9. +14 −0 binaries/data/mods/public/simulation/data/technologies/armor_trade_convoys.json
  10. +12 −0 binaries/data/mods/public/simulation/data/technologies/gather_animals_stockbreeding.json
  11. +5 −0 binaries/data/mods/public/simulation/templates/template_structure_economic_market.xml
  12. +3 −0  binaries/data/mods/public/simulation/templates/template_structure_resource_corral.xml
  13. +1 −0  binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_aggressive.xml
  14. +1 −0  binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_violent.xml
  15. +1 −0  binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_aggressive.xml
  16. +1 −0  binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_violent.xml
  17. +1 −0  binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_fishing.xml
  18. +4 −0 binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_ram.xml
  19. +1 −0  binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml
  20. +3 −3 source/renderer/PatchRData.cpp
  21. +22 −4 source/simulation2/MessageTypes.h
  22. +5 −1 source/simulation2/TypeList.h
  23. +22 −2 source/simulation2/components/CCmpTerritoryInfluence.cpp
  24. +8 −0 source/simulation2/components/CCmpTerritoryManager.cpp
  25. +44 −0 source/simulation2/components/ICmpTechnologyManager.cpp
  26. +39 −0 source/simulation2/components/ICmpTechnologyManager.h
  27. +21 −3 source/simulation2/scripting/MessageTypeConversions.cpp
View
2  binaries/data/mods/public/gui/session/input.js
@@ -344,7 +344,7 @@ function getActionInfo(action, target)
break;
case "attack":
if (entState.attack && targetState.hitpoints && enemyOwned)
- return {"possible": true};
+ return {"possible": Engine.GuiInterfaceCall("CanAttack", {"entity": entState.id, "target": target})};
break;
}
}
View
7 binaries/data/mods/public/simulation/ai/qbot/economy.js
@@ -233,9 +233,10 @@ EconomyManager.prototype.updateResourceMaps = function(gameState, events){
if (e.type === "Destroy") {
if (e.msg.entityObj){
var ent = e.msg.entityObj;
- if (ent && ent.resourceSupplyType() && ent.resourceSupplyType().generic === resource){
- var x = Math.round(ent.position()[0] / gameState.cellSize);
- var z = Math.round(ent.position()[1] / gameState.cellSize);
+ var pos;
+ if (ent && (pos = ent.position()) && ent.resourceSupplyType() && ent.resourceSupplyType().generic === resource){
+ var x = Math.round(pos[0] / gameState.cellSize);
+ var z = Math.round(pos[1] / gameState.cellSize);
var strength = Math.round(ent.resourceSupplyMax()/decreaseFactor[resource]);
this.resourceMaps[resource].addInfluence(x, z, radius[resource], -1*strength);
}
View
147 binaries/data/mods/public/simulation/components/Attack.js
@@ -18,6 +18,26 @@ var bonusesSchema =
"</element>" +
"</optional>";
+var preferredClassesSchema =
+ "<optional>" +
+ "<element name='PreferredClasses' a:help='Space delimited list of classes preferred for attacking. If an entity has any of theses classes, it is preferred. The classes are in decending order of preference.'>" +
+ "<attribute name='datatype'>" +
+ "<value>tokens</value>" +
+ "</attribute>" +
+ "<text/>" +
+ "</element>" +
+ "</optional>";
+
+var restrictedClassesSchema =
+ "<optional>" +
+ "<element name='RestrictedClasses' a:help='Space delimited list of classes that cannot be attacked by this entity. If target entity has any of these classes, it cannot be attacked'>" +
+ "<attribute name='datatype'>" +
+ "<value>tokens</value>" +
+ "</attribute>" +
+ "<text/>" +
+ "</element>" +
+ "</optional>";
+
Attack.prototype.Schema =
"<a:help>Controls the attack abilities and strengths of the unit.</a:help>" +
"<a:example>" +
@@ -38,6 +58,8 @@ Attack.prototype.Schema =
"<Multiplier>1.5</Multiplier>" +
"</BonusCavMelee>" +
"</Bonuses>" +
+ "<RestrictedClasses datatype=\"tokens\">Champion</RestrictedClasses>" +
+ "<PreferredClasses datatype=\"tokens\">Cavalry Infantry</PreferredClasses>" +
"</Melee>" +
"<Ranged>" +
"<Hack>0.0</Hack>" +
@@ -54,6 +76,7 @@ Attack.prototype.Schema =
"<Multiplier>2</Multiplier>" +
"</Bonus1>" +
"</Bonuses>" +
+ "<RestrictedClasses datatype=\"tokens\">Champion</RestrictedClasses>" +
"</Ranged>" +
"<Charge>" +
"<Hack>10.0</Hack>" +
@@ -74,6 +97,8 @@ Attack.prototype.Schema =
"<data type='positiveInteger'/>" +
"</element>" +
bonusesSchema +
+ preferredClassesSchema +
+ restrictedClassesSchema +
"</interleave>" +
"</element>" +
"</optional>" +
@@ -95,6 +120,8 @@ Attack.prototype.Schema =
"<ref name='nonNegativeDecimal'/>" +
"</element>" +
bonusesSchema +
+ preferredClassesSchema +
+ restrictedClassesSchema +
"</interleave>" +
"</element>" +
"</optional>" +
@@ -107,6 +134,8 @@ Attack.prototype.Schema =
"<element name='MaxRange'><ref name='nonNegativeDecimal'/></element>" + // TODO: how do these work?
"<element name='MinRange'><ref name='nonNegativeDecimal'/></element>" +
bonusesSchema +
+ preferredClassesSchema +
+ restrictedClassesSchema +
"</interleave>" +
"</element>" +
"</optional>";
@@ -117,6 +146,89 @@ Attack.prototype.Init = function()
Attack.prototype.Serialize = null; // we have no dynamic state to save
+Attack.prototype.GetAttackTypes = function()
+{
+ var ret = [];
+ if (this.template.Charge) ret.push("Charge");
+ if (this.template.Melee) ret.push("Melee");
+ if (this.template.Ranged) ret.push("Ranged");
+ return ret;
+};
+
+Attack.prototype.GetPreferredClasses = function(type)
+{
+ if (this.template[type] && this.template[type].PreferredClasses)
+ {
+ return this.template[type].PreferredClasses._string.split(/\s+/);
+ }
+ return [];
+};
+
+Attack.prototype.GetRestrictedClasses = function(type)
+{
+ if (this.template[type] && this.template[type].RestrictedClasses)
+ {
+ return this.template[type].RestrictedClasses._string.split(/\s+/);
+ }
+ return [];
+};
+
+Attack.prototype.CanAttack = function(target)
+{
+ const cmpIdentity = Engine.QueryInterface(target, IID_Identity);
+ if (!cmpIdentity)
+ return undefined;
+
+ const targetClasses = cmpIdentity.GetClassesList();
+
+ for each (var type in this.GetAttackTypes())
+ {
+ var canAttack = true;
+ var restrictedClasses = this.GetRestrictedClasses(type);
+
+ for each (var targetClass in targetClasses)
+ {
+ if (restrictedClasses.indexOf(targetClass) != -1)
+ {
+ canAttack = false;
+ break;
+ }
+ }
+ if (canAttack)
+ {
+ return true;
+ }
+ }
+
+ return false;
+};
+
+/**
+ * Returns null if we have no preference or the lowest index of a preferred class.
+ */
+Attack.prototype.GetPreference = function(target)
+{
+ const cmpIdentity = Engine.QueryInterface(target, IID_Identity);
+ if (!cmpIdentity)
+ return undefined;
+
+ const targetClasses = cmpIdentity.GetClassesList();
+
+ var minPref = null;
+ for each (var type in this.GetAttackTypes())
+ {
+ for each (var targetClass in targetClasses)
+ {
+ var pref = this.GetPreferredClasses(type).indexOf(targetClass);
+ if (pref != -1 && (minPref === null || minPref > pref))
+ {
+ minPref = pref;
+ }
+ }
+ }
+ return minPref;
+};
+
/**
* Return the type of the best attack.
* TODO: this should probably depend on range, target, etc,
@@ -124,14 +236,35 @@ Attack.prototype.Serialize = null; // we have no dynamic state to save
*/
Attack.prototype.GetBestAttack = function()
{
- if (this.template.Ranged)
- return "Ranged";
- else if (this.template.Melee)
- return "Melee";
- else if (this.template.Charge)
- return "Charge";
- else
+ return this.GetAttackTypes().pop();
+};
+
+Attack.prototype.GetBestAttackAgainst = function(target)
+{
+ const cmpIdentity = Engine.QueryInterface(target, IID_Identity);
+ if (!cmpIdentity)
return undefined;
+
+ const targetClasses = cmpIdentity.GetClassesList();
+ const isTargetClass = function (value, i, a) { return targetClasses.indexOf(value) != -1; };
+ const types = this.GetAttackTypes();
+ const attack = this;
+ const isAllowed = function (value, i, a) { return !attack.GetRestrictedClasses(value).some(isTargetClass); }
+ const isPreferred = function (value, i, a) { return attack.GetPreferredClasses(value).some(isTargetClass); }
+ const byPreference = function (a, b) { return (types.indexOf(a) + (isPreferred(a) ? types.length : 0) ) - (types.indexOf(b) + (isPreferred(b) ? types.length : 0) ); }
+
+ return types.filter(isAllowed).sort(byPreference).pop();
+};
+
+Attack.prototype.CompareEntitiesByPreference = function(a, b)
+{
+ var aPreference = this.GetPreference(a);
+ var bPreference = this.GetPreference(b);
+
+ if (aPreference === null && bPreference === null) return 0;
+ if (aPreference === null) return 1;
+ if (bPreference === null) return -1;
+ return aPreference - bPreference;
};
Attack.prototype.GetTimers = function(type)
View
17 binaries/data/mods/public/simulation/components/GuiInterface.js
@@ -171,7 +171,7 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
var cmpAttack = Engine.QueryInterface(ent, IID_Attack);
if (cmpAttack)
{
- var type = cmpAttack.GetBestAttack(); // TODO: how should we decide which attack to show?
+ var type = cmpAttack.GetBestAttack(); // TODO: how should we decide which attack to show? show all?
ret.attack = cmpAttack.GetAttackStrengths(type);
}
@@ -273,9 +273,8 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
if (cmpUnitAI)
{
ret.unitAI = {
- // TODO: reading properties directly is kind of violating abstraction
- "state": cmpUnitAI.fsmStateName,
- "orders": cmpUnitAI.orderQueue,
+ "state": cmpUnitAI.GetCurrentState(),
+ "orders": cmpUnitAI.GetOrders(),
};
}
@@ -838,6 +837,15 @@ GuiInterface.prototype.GetTradingDetails = function(player, data)
return result;
};
+GuiInterface.prototype.CanAttack = function(player, data)
+{
+ var cmpAttack = Engine.QueryInterface(data.entity, IID_Attack);
+ if (!cmpAttack)
+ return false;
+
+ return cmpAttack.CanAttack(data.target);
+};
+
GuiInterface.prototype.SetPathfinderDebugOverlay = function(player, enabled)
{
var cmpPathfinder = Engine.QueryInterface(SYSTEM_ENTITY, IID_Pathfinder);
@@ -902,6 +910,7 @@ var exposedFunctions = {
"PlaySound": 1,
"FindIdleUnit": 1,
"GetTradingDetails": 1,
+ "CanAttack": 1,
"SetPathfinderDebugOverlay": 1,
"SetObstructionDebugOverlay": 1,
View
2  binaries/data/mods/public/simulation/components/TechnologyManager.js
@@ -266,7 +266,7 @@ TechnologyManager.prototype.ResearchTechnology = function (tech)
var player = cmpPlayer.GetPlayerID();
for (var component in modifiedComponents)
- Engine.BroadcastMessage(MT_TechnologyModificationChange, { "component": component, "player": player });
+ Engine.BroadcastMessage(MT_TechnologyModification, { "component": component, "player": player });
this.UpdateAutoResearch();
};
View
35 binaries/data/mods/public/simulation/components/UnitAI.js
@@ -249,7 +249,7 @@ var UnitFsmSpec = {
}
// Work out how to attack the given target
- var type = this.GetBestAttack();
+ var type = this.GetBestAttackAgainst(this.order.data.target);
if (!type)
{
// Oops, we can't attack at all
@@ -336,7 +336,7 @@ var UnitFsmSpec = {
if (this.MustKillGatherTarget(this.order.data.target) && this.CheckTargetVisible(this.order.data.target))
{
// Make sure we can attack the target, else we'll get very stuck
- if (!this.GetBestAttack())
+ if (!this.GetBestAttackAgainst(this.order.data.target))
{
// Oops, we can't attack at all - give up
// TODO: should do something so the player knows why this failed
@@ -644,10 +644,10 @@ var UnitFsmSpec = {
if (this.GetStance().targetVisibleEnemies)
{
// Start attacking one of the newly-seen enemy (if any)
- this.RespondToTargetedEntities(msg.data.added);
+ this.RespondToTargetedEntities(this.GetAttackableEntitiesByPreference(msg.data.added));
}
},
-
+
"LosHealRangeUpdate": function(msg) {
this.RespondToHealableEntities(msg.data.added);
},
@@ -2437,6 +2437,14 @@ UnitAI.prototype.GetBestAttack = function()
return cmpAttack.GetBestAttack();
};
+UnitAI.prototype.GetBestAttackAgainst = function(target)
+{
+ var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
+ if (!cmpAttack)
+ return undefined;
+ return cmpAttack.GetBestAttackAgainst(target);
+};
+
/**
* Try to find one of the given entities which can be attacked,
* and start attacking it.
@@ -2462,9 +2470,9 @@ UnitAI.prototype.AttackVisibleEntity = function(ents)
*/
UnitAI.prototype.AttackEntityInZone = function(ents)
{
- var type = this.GetBestAttack();
for each (var target in ents)
{
+ var type = this.GetBestAttackAgainst(target);
if (this.CanAttack(target) && this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, type))
{
this.PushOrderFront("Attack", { "target": target, "force": false });
@@ -2928,8 +2936,7 @@ UnitAI.prototype.FindNewTargets = function()
if (!this.GetStance().targetVisibleEnemies)
return false;
- SortEntitiesByPriority(ents);
- return this.RespondToTargetedEntities(ents);
+ return this.RespondToTargetedEntities(this.GetAttackableEntitiesByPreference(ents));
};
/**
@@ -3023,6 +3030,9 @@ UnitAI.prototype.CanAttack = function(target)
// Verify that we're able to respond to Attack commands
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
if (!cmpAttack)
+ return false;
+
+ if (!cmpAttack.CanAttack(target))
return false;
// Verify that the target is alive
@@ -3266,4 +3276,15 @@ UnitAI.prototype.WalkToHeldPosition = function()
return false;
};
+UnitAI.prototype.GetAttackableEntitiesByPreference = function(ents)
+{
+ var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
+ if (!cmpAttack)
+ return [];
+
+ return ents
+ .filter(function (v, i, a) { return cmpAttack.CanAttack(v); })
+ .sort(function (a, b) { return cmpAttack.CompareEntitiesByPreference(a, b); });
+};
+
Engine.RegisterComponentType(IID_UnitAI, "UnitAI", UnitAI);
View
5 binaries/data/mods/public/simulation/components/interfaces/TechnologyManager.js
@@ -1,5 +0,0 @@
-Engine.RegisterInterface("TechnologyManager");
-
-// Message of the form { "component": "Attack", "player": 3 }
-// Sent when a new technology is researched which modifies a component
-Engine.RegisterMessageType("TechnologyModificationChange");
View
3  binaries/data/mods/public/simulation/components/tests/test_UnitAI.js
@@ -85,7 +85,10 @@ function TestFormationExiting(mode)
AddMock(unit, IID_Attack, {
GetRange: function() { return 10; },
GetBestAttack: function() { return "melee"; },
+ GetBestAttackAgainst: function(t) { return "melee"; },
GetTimers: function() { return { "prepare": 500, "repeat": 1000 }; },
+ CanAttack: function(v) { return true; },
+ CompareEntitiesByPreference: function(a, b) { return 0; },
});
unitAI.OnCreate();
View
14 binaries/data/mods/public/simulation/data/technologies/armor_trade_convoys.json
@@ -0,0 +1,14 @@
+{
+ "genericName": "Trade convoys",
+ "description": "Increases defensive capability of traders.",
+ "cost": {"food": 0, "wood": 0, "stone": 0, "metal": 200},
+ "requirements": {"tech": "phase_town"},
+ "requirementsTooltip": "Unlocked in City Phase.",
+ "icon": "wheel.png",
+ "researchTime": 30,
+ "tooltip": "Traders +2 Hack and Pierce Armour",
+ "modifications": [
+ {"value": "Armour/Hack", "add": 2.0},
+ {"value": "Armour/Pierce", "add": 2.0}],
+ "affects": ["Trader"]
+}
View
12 binaries/data/mods/public/simulation/data/technologies/gather_animals_stockbreeding.json
@@ -0,0 +1,12 @@
+{
+ "genericName": "Stockbreeding",
+ "description": "Breeding livestock for food.",
+ "cost": {"food": 50, "wood": 200, "stone": 50, "metal": 0},
+ "requirements": {"tech": "phase_town"},
+ "requirementsTooltip": "Unlocked in Town Phase.",
+ "icon": "meat.png",
+ "researchTime": 30,
+ "tooltip": "+25% meat gathering rate for all workers.",
+ "modifications": [{"value": "ResourceGatherer/Rates/food.meat", "multiplier": 1.25}],
+ "affects": ["Worker"]
+}
View
5 binaries/data/mods/public/simulation/templates/template_structure_economic_market.xml
@@ -38,6 +38,11 @@
<Obstruction>
<Static width="17.0" depth="17.0"/>
</Obstruction>
+ <ProductionQueue>
+ <Technologies datatype="tokens">
+ armor_trade_convoys
+ </Technologies>
+ </ProductionQueue>
<Sound>
<SoundGroups>
<select>interface/select/building/sel_market.xml</select>
View
3  binaries/data/mods/public/simulation/templates/template_structure_resource_corral.xml
@@ -45,6 +45,9 @@
<Entities datatype="tokens">
gaia/fauna_sheep
</Entities>
+ <Technologies datatype="tokens">
+ gather_animals_stockbreeding
+ </Technologies>
</ProductionQueue>
<RallyPoint disable=""/>
<ResourceSupply>
View
1  binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_aggressive.xml
@@ -7,6 +7,7 @@
<Crush>0.0</Crush>
<MaxRange>4.0</MaxRange>
<RepeatTime>1000</RepeatTime>
+ <RestrictedClasses datatype="tokens">Structure</RestrictedClasses>
</Melee>
</Attack>
<Identity>
View
1  binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_violent.xml
@@ -7,6 +7,7 @@
<Crush>0.0</Crush>
<MaxRange>4.0</MaxRange>
<RepeatTime>1000</RepeatTime>
+ <RestrictedClasses datatype="tokens">Structure</RestrictedClasses>
</Melee>
</Attack>
<Identity>
View
1  binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_aggressive.xml
@@ -7,6 +7,7 @@
<Crush>0.0</Crush>
<MaxRange>4.0</MaxRange>
<RepeatTime>1000</RepeatTime>
+ <RestrictedClasses datatype="tokens">Structure</RestrictedClasses>
</Melee>
</Attack>
<Identity>
View
1  binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_violent.xml
@@ -7,6 +7,7 @@
<Crush>0.0</Crush>
<MaxRange>4.0</MaxRange>
<RepeatTime>1000</RepeatTime>
+ <RestrictedClasses datatype="tokens">Structure</RestrictedClasses>
</Melee>
</Attack>
<Identity>
View
1  binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_fishing.xml
@@ -12,6 +12,7 @@
<Crush>0.0</Crush>
<MaxRange>5.0</MaxRange>
<RepeatTime>1000</RepeatTime>
+ <RestrictedClasses datatype="tokens">Ship</RestrictedClasses>
</Melee>
</Attack>
<Footprint>
View
4 binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_ram.xml
@@ -21,6 +21,8 @@
<Multiplier>3.0</Multiplier>
</BonusGates>
</Bonuses>
+ <RestrictedClasses datatype="tokens">Organic</RestrictedClasses>
+ <PreferredClasses datatype="tokens">Gates Structure</PreferredClasses>
</Melee>
<Charge>
<Hack>0.0</Hack>
@@ -38,6 +40,8 @@
<Multiplier>3.0</Multiplier>
</BonusGates>
</Bonuses>
+ <RestrictedClasses datatype="tokens">Organic</RestrictedClasses>
+ <PreferredClasses datatype="tokens">Gates Structure</PreferredClasses>
</Charge>
</Attack>
<Cost>
View
1  binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml
@@ -12,6 +12,7 @@
<Crush>0.0</Crush>
<MaxRange>4.0</MaxRange>
<RepeatTime>1000</RepeatTime>
+ <RestrictedClasses datatype="tokens">Infantry Cavalry Champion CitizenSoldier</RestrictedClasses>
</Melee>
</Attack>
<Auras>
View
6 source/renderer/PatchRData.cpp
@@ -836,7 +836,7 @@ struct SBlendStackItem
{
}
- typedef std::vector<CPatchRData::SSplat, ProxyAllocator<CPatchRData::SSplat*, Allocators::Arena<> > > SplatStack;
+ typedef std::vector<CPatchRData::SSplat, ProxyAllocator<CPatchRData::SSplat, Allocators::Arena<> > > SplatStack;
CVertexBuffer::VBChunk* vertices;
CVertexBuffer::VBChunk* indices;
SplatStack splats;
@@ -846,7 +846,7 @@ void CPatchRData::RenderBlends(const std::vector<CPatchRData*>& patches, const C
{
Allocators::Arena<> arena(ARENA_SIZE);
- typedef std::vector<SBlendBatch, ProxyAllocator<SBlendBatch*, Allocators::Arena<> > > BatchesStack;
+ typedef std::vector<SBlendBatch, ProxyAllocator<SBlendBatch, Allocators::Arena<> > > BatchesStack;
BatchesStack batches((BatchesStack::allocator_type(arena)));
PROFILE_START("compute batches");
@@ -855,7 +855,7 @@ void CPatchRData::RenderBlends(const std::vector<CPatchRData*>& patches, const C
// to avoid heavy reallocations
batches.reserve(256);
- typedef std::vector<SBlendStackItem, ProxyAllocator<SBlendStackItem*, Allocators::Arena<> > > BlendStacks;
+ typedef std::vector<SBlendStackItem, ProxyAllocator<SBlendStackItem, Allocators::Arena<> > > BlendStacks;
BlendStacks blendStacks((BlendStacks::allocator_type(arena)));
blendStacks.reserve(patches.size());
View
26 source/simulation2/MessageTypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2010 Wildfire Games.
+/* Copyright (C) 2012 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -22,6 +22,7 @@
#include "simulation2/system/Entity.h"
#include "simulation2/system/Message.h"
+#include "simulation2/helpers/Player.h"
#include "simulation2/helpers/Position.h"
#include "simulation2/components/ICmpPathfinder.h"
@@ -220,14 +221,14 @@ class CMessageOwnershipChanged : public CMessage
public:
DEFAULT_MESSAGE_IMPL(OwnershipChanged)
- CMessageOwnershipChanged(entity_id_t entity, int32_t from, int32_t to) :
+ CMessageOwnershipChanged(entity_id_t entity, player_id_t from, player_id_t to) :
entity(entity), from(from), to(to)
{
}
entity_id_t entity;
- int32_t from;
- int32_t to;
+ player_id_t from;
+ player_id_t to;
};
/**
@@ -357,4 +358,21 @@ class CMessagePathResult : public CMessage
ICmpPathfinder::Path path;
};
+/**
+ * Sent by technology manager when a technology is researched that modifies a component.
+ */
+class CMessageTechnologyModification : public CMessage
+{
+public:
+ DEFAULT_MESSAGE_IMPL(TechnologyModification)
+
+ CMessageTechnologyModification(std::wstring component, player_id_t player) :
+ component(component), player(player)
+ {
+ }
+
+ std::wstring component;
+ player_id_t player;
+};
+
#endif // INCLUDED_MESSAGETYPES
View
6 source/simulation2/TypeList.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011 Wildfire Games.
+/* Copyright (C) 2012 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -47,6 +47,7 @@ MESSAGE(RangeUpdate)
MESSAGE(TerrainChanged)
MESSAGE(TerritoriesChanged)
MESSAGE(PathResult)
+MESSAGE(TechnologyModification)
// TemplateManager must come before all other (non-test) components,
// so that it is the first to be (de)serialized
@@ -133,6 +134,9 @@ COMPONENT(SettlementScripted)
INTERFACE(SoundManager)
COMPONENT(SoundManager)
+INTERFACE(TechnologyManager)
+COMPONENT(TechnologyManagerScripted)
+
INTERFACE(Terrain)
COMPONENT(Terrain)
View
24 source/simulation2/components/CCmpTerritoryInfluence.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011 Wildfire Games.
+/* Copyright (C) 2012 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -20,6 +20,10 @@
#include "simulation2/system/Component.h"
#include "ICmpTerritoryInfluence.h"
+#include "simulation2/components/ICmpOwnership.h"
+#include "simulation2/components/ICmpPlayerManager.h"
+#include "simulation2/components/ICmpTechnologyManager.h"
+
class CCmpTerritoryInfluence : public ICmpTerritoryInfluence
{
public:
@@ -97,7 +101,23 @@ class CCmpTerritoryInfluence : public ICmpTerritoryInfluence
virtual u32 GetRadius()
{
- return m_Radius;
+ u32 newRadius = m_Radius;
+
+ CmpPtr<ICmpOwnership> cmpOwnership(GetSimContext(), GetEntityId());
+ if (cmpOwnership && cmpOwnership->GetOwner() != INVALID_PLAYER)
+ {
+ CmpPtr<ICmpPlayerManager> cmpPlayerManager(GetSimContext(), SYSTEM_ENTITY);
+ entity_id_t playerEnt = cmpPlayerManager->GetPlayerByID(cmpOwnership->GetOwner());
+
+ if (playerEnt != INVALID_ENTITY)
+ {
+ CmpPtr<ICmpTechnologyManager> cmpTechnologyManager(GetSimContext(), playerEnt);
+ if (cmpTechnologyManager)
+ newRadius = cmpTechnologyManager->ApplyModifications(L"TerritoryInfluence/Radius", m_Radius, GetEntityId());
+ }
+ }
+
+ return newRadius;
}
};
View
8 source/simulation2/components/CCmpTerritoryManager.cpp
@@ -66,6 +66,7 @@ class CCmpTerritoryManager : public ICmpTerritoryManager
{
componentManager.SubscribeGloballyToMessageType(MT_OwnershipChanged);
componentManager.SubscribeGloballyToMessageType(MT_PositionChanged);
+ componentManager.SubscribeGloballyToMessageType(MT_TechnologyModification);
componentManager.SubscribeToMessageType(MT_TerrainChanged);
componentManager.SubscribeToMessageType(MT_Update);
componentManager.SubscribeToMessageType(MT_Interpolate);
@@ -164,6 +165,13 @@ class CCmpTerritoryManager : public ICmpTerritoryManager
MakeDirtyIfRelevantEntity(msgData.entity);
break;
}
+ case MT_TechnologyModification:
+ {
+ const CMessageTechnologyModification& msgData = static_cast<const CMessageTechnologyModification&> (msg);
+ if (msgData.component == L"TerritoryInfluence")
+ MakeDirty();
+ break;
+ }
case MT_TerrainChanged:
{
MakeDirty();
View
44 source/simulation2/components/ICmpTechnologyManager.cpp
@@ -0,0 +1,44 @@
+/* Copyright (C) 2012 Wildfire Games.
+ * This file is part of 0 A.D.
+ *
+ * 0 A.D. is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 0 A.D. is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "precompiled.h"
+
+#include "ICmpTechnologyManager.h"
+
+#include "simulation2/system/InterfaceScripted.h"
+#include "simulation2/scripting/ScriptComponent.h"
+
+BEGIN_INTERFACE_WRAPPER(TechnologyManager)
+END_INTERFACE_WRAPPER(TechnologyManager)
+
+class CCmpTechnologyManagerScripted : public ICmpTechnologyManager
+{
+public:
+ DEFAULT_SCRIPT_WRAPPER(TechnologyManagerScripted)
+
+ virtual fixed ApplyModifications(std::wstring valueName, fixed currentValue, entity_id_t entity)
+ {
+ return m_Script.Call<fixed>("ApplyModifications", valueName, currentValue, entity);
+ }
+
+ virtual u32 ApplyModifications(std::wstring valueName, u32 currentValue, entity_id_t entity)
+ {
+ return m_Script.Call<u32>("ApplyModifications", valueName, currentValue, entity);
+ }
+};
+
+REGISTER_COMPONENT_SCRIPT_WRAPPER(TechnologyManagerScripted)
View
39 source/simulation2/components/ICmpTechnologyManager.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2012 Wildfire Games.
+ * This file is part of 0 A.D.
+ *
+ * 0 A.D. is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 0 A.D. is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INCLUDED_ICMPTECHNOLOGYMANAGER
+#define INCLUDED_ICMPTECHNOLOGYMANAGER
+
+#include "simulation2/system/Interface.h"
+
+#include "maths/Fixed.h"
+
+/**
+ * Technology manager interface.
+ * (This interface only includes the functions needed by native code for accessing
+ * technology modification data, the associated logic is handled in scripts)
+ */
+class ICmpTechnologyManager : public IComponent
+{
+public:
+ virtual fixed ApplyModifications(std::wstring valueName, fixed currentValue, entity_id_t entity) = 0;
+ virtual u32 ApplyModifications(std::wstring valueName, u32 currentValue, entity_id_t entity) = 0;
+
+ DECLARE_INTERFACE_TYPE(TechnologyManager)
+};
+
+#endif // INCLUDED_ICMPTECHNOLOGYMANAGER
View
24 source/simulation2/scripting/MessageTypeConversions.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011 Wildfire Games.
+/* Copyright (C) 2012 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -183,8 +183,8 @@ CMessage* CMessageOwnershipChanged::FromJSVal(ScriptInterface& scriptInterface,
{
FROMJSVAL_SETUP();
GET_MSG_PROPERTY(entity_id_t, entity);
- GET_MSG_PROPERTY(int32_t, from);
- GET_MSG_PROPERTY(int32_t, to);
+ GET_MSG_PROPERTY(player_id_t, from);
+ GET_MSG_PROPERTY(player_id_t, to);
return new CMessageOwnershipChanged(entity, from, to);
}
@@ -296,6 +296,24 @@ CMessage* CMessagePathResult::FromJSVal(ScriptInterface& UNUSED(scriptInterface)
return NULL;
}
+////////////////////////////////
+
+jsval CMessageTechnologyModification::ToJSVal(ScriptInterface& scriptInterface) const
+{
+ TOJSVAL_SETUP();
+ SET_MSG_PROPERTY(component);
+ SET_MSG_PROPERTY(player);
+ return OBJECT_TO_JSVAL(obj);
+}
+
+CMessage* CMessageTechnologyModification::FromJSVal(ScriptInterface& scriptInterface, jsval val)
+{
+ FROMJSVAL_SETUP();
+ GET_MSG_PROPERTY(std::wstring, component);
+ GET_MSG_PROPERTY(player_id_t, player);
+ return new CMessageTechnologyModification(component, player);
+}
+
////////////////////////////////////////////////////////////////
CMessage* CMessageFromJSVal(int mtid, ScriptInterface& scriptingInterface, jsval val)

No commit comments for this range

Something went wrong with that request. Please try again.