1
0

Lots of fixes to trading

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-03-03 17:48:24 -08:00
parent 3ed87d270e
commit 589187db38
3 changed files with 88 additions and 38 deletions

View File

@ -135,12 +135,7 @@
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
.Trade .TradeLine .TradeText > div {
display: flex;
align-items: center;
flex-wrap: wrap;
}
/*
.Trade .TradeLine > div {

View File

@ -1,4 +1,4 @@
import React, { useState, useCallback } from "react";
import React, { useState, useCallback, useEffect } from "react";
import "./Trade.css";
import { getPlayerName } from './Common.js';
import PlayerColor from './PlayerColor.js';
@ -65,6 +65,19 @@ const Trade = ({table}) => {
</div>;
}, [ gives, gets, transfer, player]);
useEffect(useCallback(() => {
if (table.game && table.game.player && table.game.player.gives) {
const _gives = {};
table.game.player.gives.forEach(give => _gives[give.type] = give.count);
setGives(Object.assign({}, empty, _gives));
}
if (table.game && table.game.player && table.game.player.gets) {
const _gets = {};
table.game.player.gets.forEach(get => _gets[get.type] = get.count);
setGets(Object.assign({}, empty, _gets));
}
}), [ setGets, setGives, table.game ]);
const agreeClicked = useCallback((offer) => {
const trade = {
gives: offer.gets.slice(),
@ -84,7 +97,7 @@ const Trade = ({table}) => {
transfers = [ 'brick', 'wood', 'wheat', 'sheep', 'stone' ].map(resource => { return createTransfer(resource); });
if (!table.game || !player) {
if (!table.game || !player || !table.game.player) {
return <></>;
}
@ -218,7 +231,9 @@ const Trade = ({table}) => {
trade.gives.push({ type, count: gets[type]});
}
}
const isOfferSubmitted = isCompatibleOffer(table.game.player, trade),
isNegiatorSubmitted = table.game.turn && table.game.turn.offer && isCompatibleOffer(table.game.player, table.game.turn.offer),
isOfferValid = trade.gives.length && trade.gets.length;
if (isTurn && table.game.player && table.game.player.banks) {
@ -244,7 +259,7 @@ const Trade = ({table}) => {
if (table.game.turn.offer) {
if (isTurn) {
players.forEach(trade => trade.valid = isCompatibleOffer(table.game.turn.offer, trade));
players.forEach(trade => trade.valid = canMeetOffer(player, trade));
} else {
const found = players.find(item => item.name === table.game.turn.name);
if (found) {
@ -269,45 +284,58 @@ const Trade = ({table}) => {
youRejectedOffer = player.offerRejected;
}
const _gets = item.gets.length ? item.gets.map((get, index) => <div key={`get-${get.type}-${index}`}>
let isNewOffer = item.self && !isOfferSubmitted;
console.log(`Trade from ${item.name} is new self: ${item.self}, new offer: ${isNewOffer}`);
let source;
if (item.self) {
/* Order direction is reversed for self */
source = {
gets: trade.gives,
gives: trade.gets
};
} else {
source = item;
}
const _gets = source.gets.length ? source.gets.map((get, index) => <div key={`get-${get.type}-${index}`}>
{ get.type === 'bank' && <div key={`get-bank-${index}`}><b>4</b> of any resource</div>}
{ get.type !== 'bank' && <Resource key={`get-${get.type}-${index}`} disabled label type={get.type} count={get.count}/> }
</div>) : undefined,
_gives = item.gives.length ? item.gives.map((give, index) => <div key={`give-${give.type}-${index}`}>
</div>) : 'nothing',
_gives = source.gives.length ? source.gives.map((give, index) => <div key={`give-${give.type}-${index}`}>
{ give.type === '*' && <><b>1</b> of any resource</>}
{ give.type !== '*' && <Resource disabled label type={give.type} count={give.count}/> }
</div>) : undefined
</div>) : 'nothing';
return (
<div className="TradeLine" key={`player-${item.name}-${index}`}>
<PlayerColor color={item.color}/>
<div className="TradeText">
{ item.self && <div>
{ youWereRejected && <>Your offer to give {_gets} in exchange for {_gives} was rejected.</> }
{ !youWereRejected && _gets && _gives && <>You want {_gets} and will give {_gives}.</> }
{ !youWereRejected && (_gets === undefined || _gives === undefined) && <>
You have not submitted a trade offer.
{ item.self && <>
{ youWereRejected && !isNewOffer && <>Your offer was rejected.&nbsp;</> }
{ (!youWereRejected || isNewOffer) && (_gets !== 'nothing' || _gives !== 'nothing') && <>
You want {_gets} and will give {_gives}.&nbsp;
</> }
{ !youWereRejected && _gets === 'nothing' && _gives === 'nothing' && <>
You have not started a trade offer.&nbsp;
</>}
</> }
</div> }
{ !item.self && <>
<div>
{ !youRejectedOffer && _gets && _gives && <>
{item.name} wants {_gets} and will give {_gives}.
{ !youRejectedOffer && _gets !== 'nothing' && _gives !== 'nothing' && <>
{item.name} wants {_gets} and will give {_gives}.&nbsp;
</> }
{ (_gets === undefined || _gives === undefined) &&
<>{item.name} has not submitted a trade offer.</>
{ (_gets === 'nothing' || _gives === 'nothing') &&
<>{item.name} has not submitted a trade offer.&nbsp;</>
}
{ youRejectedOffer && <>
You rejected {item.name}'s offer to receive {_gets} in exchange for {_gives}.
You rejected {item.name}'s offer.&nbsp;
</> }
</div>
{ youWereRejected && <div>
{item.name} rejected your offer.
</div>}
{ youWereRejected && <>
{item.name} rejected your offer.&nbsp;
</>}
</>}
</div>
@ -318,7 +346,7 @@ const Trade = ({table}) => {
}
{ !isTurn && item.color === table.game.turn.color &&
<Button disabled={!item.valid}
<Button disabled={!item.valid || isNegiatorSubmitted}
onClick={() => agreeClicked(item)}>agree</Button>
}

View File

@ -1296,6 +1296,16 @@ const getValidRoads = (game, color) => {
return limits;
}
const canMeetOffer = (player, offer) => {
for (let i = 0; i < offer.gets.length; i++) {
const get = offer.gets[i];
if (player[get.type] < get.count) {
return false;
}
}
return true;
};
const isCompatibleOffer = (game, player, offer) => {
const isBank = offer.name === 'The bank';
let valid = player.gets.length === offer.gives.length &&
@ -1370,9 +1380,10 @@ const isSameOffer = (player, offer) => {
/* Verifies player can make the offer */
const checkPlayerOffer = (game, player, offer) => {
let error = undefined;
const name = getPlayerName(game, player);
console.log({
name: getPlayerName(game, player),
name: name,
gets: offer.gets,
gives: offer.gives,
sheep: player.sheep,
@ -1393,12 +1404,12 @@ const checkPlayerOffer = (game, player, offer) => {
}
if (player[give.type] < give.count) {
error = `You do not have ${give.count} ${give.type}!`;
error = `${name} does do not have ${give.count} ${give.type}!`;
return;
}
if (offer.gets.find(get => give.type === get.type)) {
error = `You can not give and get the same resource type!`;
error = `${name} can not give and get the same resource type!`;
return;
}
});
@ -1408,7 +1419,7 @@ const checkPlayerOffer = (game, player, offer) => {
return;
}
if (offer.gives.find(give => get.type === give.type)) {
error = `You can not give and get the same resource type!`;
error = `${name} can not give and get the same resource type!`;
};
})
@ -1600,7 +1611,9 @@ router.put("/:id/:action/:value?", async (req, res) => {
session.player.gives = offer.gives;
session.player.gets = offer.gets;
delete session.player.offerRejected;
/* This offer is new for the negotiator, but don't clear the flag indicating
* if this player regected the negotiator's offer */
/* delete session.player.offerRejected; */
delete session.player.negotiatorRejectedOffer;
if (game.turn.name === name) {
@ -1647,6 +1660,8 @@ router.put("/:id/:action/:value?", async (req, res) => {
const offer = req.body;
let target;
console.log(offer);
error = checkPlayerOffer(game, session.player, offer);
if (error) {
break;
@ -1671,31 +1686,43 @@ router.put("/:id/:action/:value?", async (req, res) => {
mismatch = true;
}
});
if (mismatch) {
error = `Unfortunately, trades were re-negotiated in transit and the deal is invalid!`;
break;
}
error = checkPlayerOffer(game, target, offer);
if (error) {
break;
}
if (!canMeetOffer(target, player)) {
error = `${playerNameFromColor(game, offer.color)} cannot meet the terms.`;
break;
}
} else {
target = offer;
}
/* Verify the requesting offer wasn't jacked --\
* make sure the target.gives === player.gets and target.gives === player.gets */
if (!isCompatibleOffer(game, player, target)) {
error = `The requested offer does not match the negotiated terms!`;
if (!canMeetOffer(player, target)) {
error = `You cannot meet these terms!`;
break;
}
debugChat(game, 'Before trade');
/* Transfer goods */
player.gets.forEach(item => {
target.gives.forEach(item => {
if (target.name !== 'The bank') {
target[item.type] -= item.count;
}
player[item.type] += item.count;
});
player.gives.forEach(item => {
target.gets.forEach(item => {
if (target.name !== 'The bank') {
target[item.type] += item.count;
}