Skip to content

Commit f01c9db

Browse files
Allow ending relations while over diplomatic capacity. (#101)
A zero-cost break was compared to free capacity, so a nation already over the cap could not release a subject or drop an alliance. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent cb3462d commit f01c9db

4 files changed

Lines changed: 215 additions & 65 deletions

File tree

‎src/main/java/net/tfminecraft/simplefactions/managers/RelationManager.java‎

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,53 @@ public static double getDiplomaticCost(Faction from, Faction to, Attitude a) {
8989
return cost * prestigeCostScale(prestigeOf(to));
9090
}
9191

92+
/**
93+
* True when this change spends more capacity than {@code available}.
94+
* Ending or cheapening a relation is allowed even if the faction is already over capacity.
95+
*/
96+
public static boolean lacksCapacityForChange(double available, double newCost, double oldCost) {
97+
double increase = newCost - oldCost;
98+
return increase > 0.0 && available < increase;
99+
}
100+
101+
/** The type the other faction will hold after {@code origin} sets {@code next} toward {@code target}. */
102+
public static RelationType partnerRelationAfter(Faction target, Faction origin, RelationType next) {
103+
if (next == null || target == null || origin == null) {
104+
return null;
105+
}
106+
if (reverseChange(target, origin, next) || next.willReset()) {
107+
return next.getLink();
108+
}
109+
return target.getRelation(origin.getId()).getType();
110+
}
111+
112+
public static boolean actorLacksCapacity(Faction actor, Faction other, RelationType next, RelationType current) {
113+
if (actor == null || other == null || (next != null && next.equals(current))) {
114+
return false;
115+
}
116+
return lacksCapacityForChange(
117+
actor.getDiplomacyHandler().getAvailableCapacity(),
118+
getDiplomaticCost(actor, other, next),
119+
getDiplomaticCost(actor, other, current));
120+
}
121+
122+
public static boolean partnerLacksRelationCapacity(Faction origin, Faction target, RelationType next) {
123+
if (origin == null || target == null) {
124+
return false;
125+
}
126+
RelationType theirCurrent = target.getRelation(origin.getId()).getType();
127+
return actorLacksCapacity(target, origin, partnerRelationAfter(target, origin, next), theirCurrent);
128+
}
129+
130+
/** Trade and treaty overlays. A non-mutual type leaves the partner's overlay unchanged. */
131+
public static boolean partnerLacksOverlayCapacity(Faction origin, Faction target, RelationType next, RelationType theirCurrent) {
132+
if (origin == null || target == null || next == null) {
133+
return false;
134+
}
135+
RelationType theirNext = next.isMutual() ? next.getLink() : theirCurrent;
136+
return actorLacksCapacity(target, origin, theirNext, theirCurrent);
137+
}
138+
92139
/** Keeps existing costs through 100 prestige, then applies diminishing returns. */
93140
private static double prestigeCostScale(double prestige) {
94141
double nonNegativePrestige = Math.max(0, prestige);
@@ -533,7 +580,7 @@ public static boolean setAttitude(Player p, Attitude a, Faction target, Faction
533580
}
534581
double oldCost = getDiplomaticCost(origin, target, current);
535582
double newCost = getDiplomaticCost(origin, target, a);
536-
if (origin.getDiplomacyHandler().getAvailableCapacity() < newCost - oldCost) {
583+
if (lacksCapacityForChange(origin.getDiplomacyHandler().getAvailableCapacity(), newCost, oldCost)) {
537584
p.sendMessage("§cYou lack diplomatic capacity for this attitude!");
538585
return false;
539586
}

‎src/main/java/net/tfminecraft/simplefactions/managers/inventory/RelationCreator.java‎

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ public ItemStack createAttitudeItem(Attitude a, Faction origin, Faction target,
235235
boolean same = current != null && current.getId().equalsIgnoreCase(a.getId());
236236
double oldCost = RelationManager.getDiplomaticCost(origin, target, current);
237237
double newCost = RelationManager.getDiplomaticCost(origin, target, a);
238-
if (!same && origin.getDiplomacyHandler().getAvailableCapacity() < newCost - oldCost) {
238+
if (!same && RelationManager.lacksCapacityForChange(origin.getDiplomacyHandler().getAvailableCapacity(), newCost, oldCost)) {
239239
lore.add(StringFormatter.formatHex("#d4bb98You lack diplomatic capacity for this attitude!"));
240240
lore.add(" ");
241241
lore.add(StringFormatter.formatHex("#ba3439Unavailable"));
@@ -325,10 +325,10 @@ public ItemStack createRelationTypeItem(RelationType t, Faction target, Faction
325325
lore.add(StringFormatter.formatHex(wartime));
326326
lore.add(" ");
327327
lore.add(StringFormatter.formatHex("#ba3439Unavailable"));
328-
} else if(origin.getDiplomacyHandler().getAvailableCapacity() < ourCost && !current.equals(t) || target.getDiplomacyHandler().getAvailableCapacity() < theirCost && !current.equals(t.getLink())) {
329-
if(origin.getDiplomacyHandler().getAvailableCapacity() < ourCost && !current.equals(t))
328+
} else if(RelationManager.actorLacksCapacity(origin, target, t, current) || RelationManager.partnerLacksRelationCapacity(origin, target, t)) {
329+
if(RelationManager.actorLacksCapacity(origin, target, t, current))
330330
lore.add(StringFormatter.formatHex("#d4bb98You lack diplomatic capacity for this relation!"));
331-
if(target.getDiplomacyHandler().getAvailableCapacity() < theirCost && !current.equals(t.getLink()))
331+
if(RelationManager.partnerLacksRelationCapacity(origin, target, t))
332332
lore.add(StringFormatter.formatHex("#d4bb98They lack diplomatic capacity for this relation!"));
333333
lore.add(" ");
334334
lore.add(StringFormatter.formatHex("#ba3439Unavailable"));
@@ -437,40 +437,32 @@ public ItemStack createTradeAgreementTypeItem(Player p, RelationType t, Faction
437437
lore.add(" ");
438438
if(full) {
439439
RelationType current = origin.getDiplomacyHandler().getTradeRelation(target.getId());
440+
RelationType theirCurrent = target.getDiplomacyHandler().getTradeRelation(origin.getId());
441+
boolean weLack = RelationManager.actorLacksCapacity(origin, target, t, current);
442+
boolean theyLack = RelationManager.partnerLacksOverlayCapacity(origin, target, t, theirCurrent);
440443
if(current != null && current.hasLock()) {
441444
lore.add(StringFormatter.formatHex("#d4bb98You have the agreement "+current.getName()+"#d4bb98, which binds you and cannot be changed by you alone."));
442445
lore.add(" ");
443446
lore.add(StringFormatter.formatHex("#ba3439Unavailable"));
444-
} else if(current != null && (origin.getDiplomacyHandler().getAvailableCapacity() < ourCost && !current.equals(t) || target.getDiplomacyHandler().getAvailableCapacity() < theirCost && !current.equals(t.getLink()))) {
445-
if(origin.getDiplomacyHandler().getAvailableCapacity() < ourCost && !current.equals(t))
447+
} else if(weLack || theyLack) {
448+
if(weLack)
446449
lore.add(StringFormatter.formatHex("#d4bb98You lack diplomatic capacity for this relation!"));
447-
if(target.getDiplomacyHandler().getAvailableCapacity() < theirCost && !current.equals(t.getLink()))
450+
if(theyLack)
448451
lore.add(StringFormatter.formatHex("#d4bb98They lack diplomatic capacity for this relation!"));
449452
lore.add(" ");
450453
lore.add(StringFormatter.formatHex("#ba3439Unavailable"));
454+
} else if(current != null && current.equals(t)) {
455+
lore.add(StringFormatter.formatHex("#28ed70Current"));
456+
lore.add(StringFormatter.formatHex("#28ed70Click to end agreement"));
457+
m.addItemFlags(ItemFlag.HIDE_ENCHANTS);
458+
m.addEnchant(Enchantment.UNBREAKING, 1, true);
459+
if(full) EconomicImpact.applyTradeAgreementChange(lore, p, origin, target, null, false, m, false);
460+
} else if(t.isMutual()) {
461+
lore.add(StringFormatter.formatHex("#28ed70Click to request agreement"));
462+
if(full) EconomicImpact.applyTradeAgreementChange(lore, p, origin, target, t, false, m, false);
451463
} else {
452-
if(current != null && current.equals(t)) {
453-
lore.add(StringFormatter.formatHex("#28ed70Current"));
454-
lore.add(StringFormatter.formatHex("#28ed70Click to end agreement"));
455-
m.addItemFlags(ItemFlag.HIDE_ENCHANTS);
456-
m.addEnchant(Enchantment.UNBREAKING, 1, true);
457-
if(full) EconomicImpact.applyTradeAgreementChange(lore, p, origin, target, null, false, m, false);
458-
} else if(origin.getDiplomacyHandler().getAvailableCapacity() > ourCost && target.getDiplomacyHandler().getAvailableCapacity() > theirCost) {
459-
if(t.isMutual()) {
460-
lore.add(StringFormatter.formatHex("#28ed70Click to request agreement"));
461-
if(full) EconomicImpact.applyTradeAgreementChange(lore, p, origin, target, t, false, m, false);
462-
} else {
463-
lore.add(StringFormatter.formatHex("#28ed70Click to set"));
464-
if(full) EconomicImpact.applyTradeAgreementChange(lore, p, origin, target, t, false, m, false);
465-
}
466-
} else {
467-
if(origin.getDiplomacyHandler().getAvailableCapacity() < ourCost)
468-
lore.add(StringFormatter.formatHex("#d4bb98You lack diplomatic capacity for this relation!"));
469-
if(target.getDiplomacyHandler().getAvailableCapacity() < theirCost)
470-
lore.add(StringFormatter.formatHex("#d4bb98They lack diplomatic capacity for this relation!"));
471-
lore.add(" ");
472-
lore.add(StringFormatter.formatHex("#ba3439Unavailable"));
473-
}
464+
lore.add(StringFormatter.formatHex("#28ed70Click to set"));
465+
if(full) EconomicImpact.applyTradeAgreementChange(lore, p, origin, target, t, false, m, false);
474466
}
475467
} else {
476468
lore.add(StringFormatter.formatHex("#28ed70Click for more information"));
@@ -540,14 +532,17 @@ public ItemStack createTreatyTypeItem(Player p, RelationType t, Faction target,
540532
lore.add(" ");
541533
if(full) {
542534
RelationType current = origin.getDiplomacyHandler().getTreatyRelation(target.getId());
535+
RelationType theirCurrent = target.getDiplomacyHandler().getTreatyRelation(origin.getId());
536+
boolean weLack = !t.isClearTreaty() && RelationManager.actorLacksCapacity(origin, target, t, current);
537+
boolean theyLack = !t.isClearTreaty() && RelationManager.partnerLacksOverlayCapacity(origin, target, t, theirCurrent);
543538
if(current != null && current.hasLock()) {
544539
lore.add(StringFormatter.formatHex("#d4bb98You have the treaty "+current.getName()+"#d4bb98, which binds you and cannot be changed by you alone."));
545540
lore.add(" ");
546541
lore.add(StringFormatter.formatHex("#ba3439Unavailable"));
547-
} else if(!t.isClearTreaty() && current != null && (origin.getDiplomacyHandler().getAvailableCapacity() < ourCost && !current.equals(t) || target.getDiplomacyHandler().getAvailableCapacity() < theirCost && !current.equals(t.getLink()))) {
548-
if(origin.getDiplomacyHandler().getAvailableCapacity() < ourCost && !current.equals(t))
542+
} else if(weLack || theyLack) {
543+
if(weLack)
549544
lore.add(StringFormatter.formatHex("#d4bb98You lack diplomatic capacity for this relation!"));
550-
if(target.getDiplomacyHandler().getAvailableCapacity() < theirCost && !current.equals(t.getLink()))
545+
if(theyLack)
551546
lore.add(StringFormatter.formatHex("#d4bb98They lack diplomatic capacity for this relation!"));
552547
lore.add(" ");
553548
lore.add(StringFormatter.formatHex("#ba3439Unavailable"));
@@ -561,19 +556,10 @@ public ItemStack createTreatyTypeItem(Player p, RelationType t, Faction target,
561556
lore.add(StringFormatter.formatHex("#28ed70Current"));
562557
m.addItemFlags(ItemFlag.HIDE_ENCHANTS);
563558
m.addEnchant(Enchantment.UNBREAKING, 1, true);
564-
} else if(origin.getDiplomacyHandler().getAvailableCapacity() >= ourCost && target.getDiplomacyHandler().getAvailableCapacity() >= theirCost) {
565-
if(t.isMutual()) {
566-
lore.add(StringFormatter.formatHex("#28ed70Click to request"));
567-
} else {
568-
lore.add(StringFormatter.formatHex("#28ed70Click to set"));
569-
}
559+
} else if(t.isMutual()) {
560+
lore.add(StringFormatter.formatHex("#28ed70Click to request"));
570561
} else {
571-
if(origin.getDiplomacyHandler().getAvailableCapacity() < ourCost)
572-
lore.add(StringFormatter.formatHex("#d4bb98You lack diplomatic capacity for this relation!"));
573-
if(target.getDiplomacyHandler().getAvailableCapacity() < theirCost)
574-
lore.add(StringFormatter.formatHex("#d4bb98They lack diplomatic capacity for this relation!"));
575-
lore.add(" ");
576-
lore.add(StringFormatter.formatHex("#ba3439Unavailable"));
562+
lore.add(StringFormatter.formatHex("#28ed70Click to set"));
577563
}
578564
} else {
579565
lore.add(StringFormatter.formatHex("#28ed70Click for more information"));

‎src/main/java/net/tfminecraft/simplefactions/managers/inventory/RelationView.java‎

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -362,12 +362,11 @@ public void click(InventoryClickEvent e, Inventory inventory, Player p) {
362362
return;
363363
}
364364

365-
double ourCost = RelationManager.getDiplomaticCost(origin, f, r);
366-
double theirCost = r.hasLink() ? RelationManager.getDiplomaticCost(f, origin, r.getLink()) : 0;
367-
if(origin.getDiplomacyHandler().getAvailableCapacity() < ourCost && !origin.getRelation(f.getId()).getType().equals(r) || f.getDiplomacyHandler().getAvailableCapacity() < theirCost && !f.getRelation(origin.getId()).getType().equals(r.getLink())) {
368-
if(origin.getDiplomacyHandler().getAvailableCapacity() < ourCost && !origin.getRelation(f.getId()).getType().equals(r))
365+
RelationType currentRelation = origin.getRelation(f.getId()).getType();
366+
if(RelationManager.actorLacksCapacity(origin, f, r, currentRelation) || RelationManager.partnerLacksRelationCapacity(origin, f, r)) {
367+
if(RelationManager.actorLacksCapacity(origin, f, r, currentRelation))
369368
p.sendMessage("§cYou lack diplomatic capacity for this relation!");
370-
if(f.getDiplomacyHandler().getAvailableCapacity() < theirCost && !f.getRelation(origin.getId()).getType().equals(r.getLink()))
369+
if(RelationManager.partnerLacksRelationCapacity(origin, f, r))
371370
p.sendMessage("§cThey lack diplomatic capacity for this relation!");
372371
return;
373372
}
@@ -392,12 +391,10 @@ public void click(InventoryClickEvent e, Inventory inventory, Player p) {
392391
return;
393392
}
394393

395-
double ourCost = RelationManager.getDiplomaticCost(origin, f, r);
396-
double theirCost = r.hasLink() ? RelationManager.getDiplomaticCost(f, origin, r.getLink()) : 0;
397-
if(origin.getDiplomacyHandler().getAvailableCapacity() < ourCost && (current == null || !current.equals(r)) || f.getDiplomacyHandler().getAvailableCapacity() < theirCost && (theirCurrent == null || !theirCurrent.equals(r.getLink()))) {
398-
if(origin.getDiplomacyHandler().getAvailableCapacity() < ourCost && (current == null || !current.equals(r)))
394+
if(RelationManager.actorLacksCapacity(origin, f, r, current) || RelationManager.partnerLacksOverlayCapacity(origin, f, r, theirCurrent)) {
395+
if(RelationManager.actorLacksCapacity(origin, f, r, current))
399396
p.sendMessage("§cYou lack diplomatic capacity for this relation!");
400-
if(f.getDiplomacyHandler().getAvailableCapacity() < theirCost && (theirCurrent == null || !theirCurrent.equals(r.getLink())))
397+
if(RelationManager.partnerLacksOverlayCapacity(origin, f, r, theirCurrent))
401398
p.sendMessage("§cThey lack diplomatic capacity for this relation!");
402399
return;
403400
}
@@ -422,16 +419,12 @@ public void click(InventoryClickEvent e, Inventory inventory, Player p) {
422419
return;
423420
}
424421

425-
if(!r.isClearTreaty()) {
426-
double ourCost = RelationManager.getDiplomaticCost(origin, f, r);
427-
double theirCost = r.hasLink() ? RelationManager.getDiplomaticCost(f, origin, r.getLink()) : 0;
428-
if(origin.getDiplomacyHandler().getAvailableCapacity() < ourCost && (current == null || !current.equals(r)) || f.getDiplomacyHandler().getAvailableCapacity() < theirCost && (theirCurrent == null || !theirCurrent.equals(r.getLink()))) {
429-
if(origin.getDiplomacyHandler().getAvailableCapacity() < ourCost && (current == null || !current.equals(r)))
430-
p.sendMessage("§cYou lack diplomatic capacity for this relation!");
431-
if(f.getDiplomacyHandler().getAvailableCapacity() < theirCost && (theirCurrent == null || !theirCurrent.equals(r.getLink())))
432-
p.sendMessage("§cThey lack diplomatic capacity for this relation!");
433-
return;
434-
}
422+
if(!r.isClearTreaty() && (RelationManager.actorLacksCapacity(origin, f, r, current) || RelationManager.partnerLacksOverlayCapacity(origin, f, r, theirCurrent))) {
423+
if(RelationManager.actorLacksCapacity(origin, f, r, current))
424+
p.sendMessage("§cYou lack diplomatic capacity for this relation!");
425+
if(RelationManager.partnerLacksOverlayCapacity(origin, f, r, theirCurrent))
426+
p.sendMessage("§cThey lack diplomatic capacity for this relation!");
427+
return;
435428
}
436429

437430
RelationManager.setTreatyRelation(p, r, f, origin, true);

0 commit comments

Comments
 (0)