add a new market component, fixes #3277

This was SVN commit r18028.
This commit is contained in:
mimo 2016-04-13 19:56:18 +00:00
parent a69da3401f
commit 8f4dffe3f0
7 changed files with 129 additions and 21 deletions

View File

@ -307,11 +307,12 @@ var unitActions =
},
"getActionInfo": function(entState, targetState)
{
if (targetState.foundation || !entState.trader)
if (targetState.foundation || !entState.trader || !targetState.market)
return false;
if (!playerCheck(entState, targetState, ["Player", "Ally"]))
return false;
if (!(hasClass(entState, "Organic") && hasClass(targetState, "Market")) && !(hasClass(entState, "Ship") && hasClass(targetState, "NavalMarket")))
if (!(targetState.market.land && hasClass(entState, "Organic") ||
targetState.market.naval && hasClass(entState, "Ship")))
return false;
var tradingData = {"trader": entState.id, "target": targetState.id};
@ -529,8 +530,8 @@ var unitActions =
data.resourceType = resourceType;
data.resourceTemplate = targetState.template;
}
else if (hasClass(entState, "Market") && hasClass(targetState, "Market") && entState.id != targetState.id &&
(!hasClass(entState, "NavalMarket") || hasClass(targetState, "NavalMarket")) && !playerCheck(entState, targetState, ["Enemy"]))
else if (entState.market && targetState.market && entState.id != targetState.id &&
(!entState.market.naval || targetState.market.naval) && !playerCheck(entState, targetState, ["Enemy"]))
{
// Find a trader (if any) that this building can produce.
var trader;
@ -881,7 +882,7 @@ var g_EntityCommands =
"select-trading-goods": {
"getInfo": function(entState)
{
if (!hasClass(entState, "Market"))
if (!entState.market)
return false;
return {
"tooltip": translate("Select trading goods"),

View File

@ -234,6 +234,7 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
"garrisonHolder": null,
"gate": null,
"guard": null,
"market": null,
"mirage": null,
"pack": null,
"player": -1,
@ -288,6 +289,13 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
if (cmpBuilder)
ret.builder = true;
let cmpMarket = Engine.QueryInterface(ent, IID_Market);
if (cmpMarket)
ret.market = {
"land": cmpMarket.HasType("land"),
"naval": cmpMarket.HasType("naval"),
};
let cmpPack = Engine.QueryInterface(ent, IID_Pack);
if (cmpPack)
ret.pack = {

View File

@ -0,0 +1,71 @@
function Market() {}
Market.prototype.Schema =
"<element name='TradeType' a:help='Specifies the type of possible trade route (land or naval).'>" +
"<list>" +
"<oneOrMore>" +
"<choice>" +
"<value>land</value>" +
"<value>naval</value>" +
"</choice>" +
"</oneOrMore>" +
"</list>" +
"</element>";
Market.prototype.Init = function()
{
this.traders = new Set(); // list of traders with a route on this market
this.tradeType = new Set(this.template.TradeType.split(/\s+/));
};
Market.prototype.AddTrader = function(ent)
{
this.traders.add(ent);
};
Market.prototype.RemoveTrader = function(ent)
{
this.traders.delete(ent);
};
Market.prototype.HasType = function(type)
{
return this.tradeType.has(type);
};
/**
* Check if all traders with a route on this market can still trade
*/
Market.prototype.OnDiplomacyChanged = function(msg)
{
for (let ent of this.traders)
{
let cmpTrader = Engine.QueryInterface(ent, IID_Trader);
if (!cmpTrader)
this.RemoveTrader(ent);
else if (!cmpTrader.CanTrade(this.entity))
{
this.RemoveTrader(ent);
cmpTrader.RemoveMarket(this.entity);
}
}
};
Market.prototype.OnOwnershipChanged = function(msg)
{
for (let ent of this.traders)
{
let cmpTrader = Engine.QueryInterface(ent, IID_Trader);
if (!cmpTrader)
this.RemoveTrader(ent);
else if (msg.to == -1)
cmpTrader.RemoveMarket(this.entity);
else if (!cmpTrader.CanTrade(this.entity))
{
this.RemoveTrader(ent);
cmpTrader.RemoveMarket(this.entity);
}
}
};
Engine.RegisterComponentType(IID_Market, "Market", Market);

View File

@ -69,29 +69,32 @@ Trader.prototype.CalculateGain = function(currentMarket, nextMarket)
// Return true if at least one of markets was changed.
Trader.prototype.SetTargetMarket = function(target, source)
{
// Check that target is a market
var cmpTargetIdentity = Engine.QueryInterface(target, IID_Identity);
if (!cmpTargetIdentity)
return false;
if (!cmpTargetIdentity.HasClass("Market") && !cmpTargetIdentity.HasClass("NavalMarket"))
var cmpTargetMarket = Engine.QueryInterface(target, IID_Market);
if (!cmpTargetMarket)
return false;
if (source)
{
// Establish a trade route with both markets in one go.
cmpTargetIdentity = Engine.QueryInterface(source, IID_Identity);
if (!cmpTargetIdentity)
return false;
if (!cmpTargetIdentity.HasClass("Market") && !cmpTargetIdentity.HasClass("NavalMarket"))
let cmpSourceMarket = Engine.QueryInterface(source, IID_Market);
if (!cmpSourceMarket)
return false;
this.markets = [source];
cmpSourceMarket.AddTrader(this.entity);
}
if (this.markets.length >= 2)
{
// If we already have both markets - drop them
// and use the target as first market
for (let market of this.markets)
{
let cmpMarket = Engine.QueryInterface(market, IID_Market);
if (cmpMarket)
cmpMarket.RemoveTrader(this.entity);
}
this.index = 0;
this.markets = [target];
cmpTargetMarket.AddTrader(this.entity);
}
else if (this.markets.length == 1)
{
@ -103,6 +106,7 @@ Trader.prototype.SetTargetMarket = function(target, source)
{
this.index = 0;
this.markets.push(target);
cmpTargetMarket.AddTrader(this.entity);
this.goods.amount = this.CalculateGain(this.markets[0], this.markets[1]);
}
}
@ -112,6 +116,7 @@ Trader.prototype.SetTargetMarket = function(target, source)
// set the target as first market
this.index = 0;
this.markets = [target];
cmpTargetMarket.AddTrader(this.entity);
}
// Drop carried goods if markets were changed
this.goods.amount = null;
@ -150,16 +155,16 @@ Trader.prototype.SetRequiredGoods = function(requiredGoods)
Trader.prototype.CanTrade = function(target)
{
var cmpTraderIdentity = Engine.QueryInterface(this.entity, IID_Identity);
var cmpTargetIdentity = Engine.QueryInterface(target, IID_Identity);
// Check that the target exists
if (!cmpTargetIdentity)
var cmpTargetMarket = Engine.QueryInterface(target, IID_Market);
if (!cmpTargetMarket)
return false;
// Check that the target is not a foundation
var cmpTargetFoundation = Engine.QueryInterface(target, IID_Foundation);
if (cmpTargetFoundation)
return false;
var landTradingPossible = cmpTraderIdentity.HasClass("Organic") && cmpTargetIdentity.HasClass("Market");
var seaTradingPossible = cmpTraderIdentity.HasClass("Ship") && cmpTargetIdentity.HasClass("NavalMarket");
var landTradingPossible = cmpTraderIdentity.HasClass("Organic") && cmpTargetMarket.HasType("land");
var seaTradingPossible = cmpTraderIdentity.HasClass("Ship") && cmpTargetMarket.HasType("naval");
if (!landTradingPossible && !seaTradingPossible)
return false;
@ -242,8 +247,24 @@ Trader.prototype.GetGoods = function()
return this.goods;
};
/**
* Called when this trader can no longer trade with the market
*/
Trader.prototype.RemoveMarket = function(market)
{
let index = this.markets.indexOf(market);
if (index != -1)
this.markets.splice(index, 1);
};
Trader.prototype.StopTrading = function()
{
for (let market of this.markets)
{
let cmpMarket = Engine.QueryInterface(market, IID_Market);
if (cmpMarket)
cmpMarket.RemoveTrader(this.entity);
}
this.index = -1;
this.markets = [];
// Drop carried goods

View File

@ -0,0 +1 @@
Engine.RegisterInterface("Market");

View File

@ -32,6 +32,9 @@
<stone>25</stone>
<metal>25</metal>
</Loot>
<Market>
<TradeType>land</TradeType>
</Market>
<Obstruction>
<Static width="30.0" depth="26.0"/>
</Obstruction>

View File

@ -34,6 +34,9 @@
<stone>0</stone>
<metal>0</metal>
</Loot>
<Market>
<TradeType>land naval</TradeType>
</Market>
<Obstruction>
<Static width="18.0" depth="18.0"/>
</Obstruction>