Skip to content

Commit

Permalink
Added can't be sold to merchants to items, and only accept currency p…
Browse files Browse the repository at this point in the history
…ayment to merchants
  • Loading branch information
Haxxer committed Sep 7, 2022
1 parent 2d0bb22 commit db559a3
Show file tree
Hide file tree
Showing 14 changed files with 275 additions and 57 deletions.
4 changes: 4 additions & 0 deletions languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@
"DisableNormalCostExplanation": "When this is enabled, the item cannot be purchased with the primary currency and must be purchased with one of the purchase options below.",
"PurchaseOptions": "Purchase Options",
"PurchaseOptionsExplanation": "Here you can configure the alternate ways to purchase this item. Each group represents a different way that a character can buy this item from other",
"CantBeSoldToMerchants": "Can't Be Sold To Merchants",
"CantBeSoldToMerchantsExplanation": "When enabled, this item cannot be sold back to merchants, only purchased.",
"AddPurchaseOption": "Add Purchase Option",
"DropMeClickMe": "Click to add an attribute or drag & drop an item to add",
"PricePreset": "Or select an exiting price preset:",
Expand Down Expand Up @@ -365,6 +367,8 @@
"PurchaseOnlyExplanation": "When enabled, characters cannot sell items to this merchant.",
"HideNewItems": "Hide New Items",
"HideNewItemsExplanation": "When enabled, any items sold to this merchant will be hidden.",
"OnyAcceptBasePrice": "Only Accept Base Price",
"OnyAcceptBasePriceExplanation": "When enabled, all items sold to this merchant must use the base price, and not any custom prices.",
"OpenTimes": "Open Times",
"OpenTimesExplanation": "When enabled, the merchant is can only be interacted by players at certain times of the day.",
"PriceModifierTitle": "Buy and Sell Price Modifiers",
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
],
"dependencies": {
"@typhonjs-fvtt/runtime": "^0.0.19",
"@typhonjs-fvtt/svelte-standard": "^0.0.7",
"@typhonjs-fvtt/svelte-standard": "^0.0.9",
"svelte": "^3.49.0"
},
"devDependencies": {
Expand Down
5 changes: 4 additions & 1 deletion src/API/private-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -1349,6 +1349,7 @@ export default class PrivateAPI {
const sellerTransaction = new Transaction(sellingActor);
const sellerFlagData = PileUtilities.getActorFlagData(sellerTransaction);
const sellerInfiniteQuantity = sellerFlagData.enabled && sellerFlagData.merchant && sellerFlagData.infiniteQuantity;
const sellerInfiniteCurrencies = sellerFlagData.enabled && sellerFlagData.merchant && sellerFlagData.infiniteCurrencies;

for (const payment of itemPrices.sellerReceive) {
if (!payment.quantity) continue;
Expand All @@ -1366,7 +1367,9 @@ export default class PrivateAPI {
}

for (const entry of itemPrices.buyerReceive) {
if (!entry.quantity || sellerInfiniteQuantity) continue;
if (!entry.quantity || (sellerInfiniteCurrencies && entry.isCurrency) || (sellerInfiniteQuantity && !entry.isCurrency)) {
continue;
}
if (entry.type === "attribute") {
await sellerTransaction.appendActorChanges([{
path: entry.data.path,
Expand Down
8 changes: 8 additions & 0 deletions src/applications/editors/item-editor/item-editor-shell.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@
<input type="checkbox" bind:checked={itemFlagData.notForSale}/>
</div>

<div class="form-group">
<label style="flex:4;">
{localize("ITEM-PILES.Applications.ItemEditor.CantBeSoldToMerchants")}<br>
<p>{localize("ITEM-PILES.Applications.ItemEditor.CantBeSoldToMerchantsExplanation")}</p>
</label>
<input type="checkbox" bind:checked={itemFlagData.cantBeSoldToMerchants}/>
</div>

<div class="form-group">
<label style="flex:4;">
{localize("ITEM-PILES.Applications.ItemEditor.InfiniteQuantity")}<br>
Expand Down
8 changes: 8 additions & 0 deletions src/applications/item-pile-config/item-pile-config.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,14 @@
<input type="checkbox" bind:checked={pileData.hideNewItems}/>
</div>
<div class="form-group">
<label>
<span>{localize("ITEM-PILES.Applications.ItemPileConfig.Merchant.OnyAcceptBasePrice")}</span>
<p>{localize("ITEM-PILES.Applications.ItemPileConfig.Merchant.OnyAcceptBasePriceExplanation")}</p>
</label>
<input type="checkbox" bind:checked={pileData.onlyAcceptBasePrice}/>
</div>
<div class="form-group slider-group">
<label style="flex:3;">
<span>{localize("ITEM-PILES.Applications.ItemPileConfig.Merchant.PriceModifierTitle")}</span>
Expand Down
66 changes: 66 additions & 0 deletions src/applications/merchant-app/ItemEntry.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<script>
export let item;
const itemName = item.name;
const itemImage = item.img;
const store = item.store;
const pileData = store.pileData;
const displayQuantityStore = item.displayQuantity;
const quantityStore = item.quantity;
const itemFlagDataStore = item.itemFlagData;
$: itemFlagData = $itemFlagDataStore;
$: displayQuantity = $displayQuantityStore;
$: quantity = $quantityStore;
$: editQuantity = $quantityStore;
let showEditQuantity = false;
const displayControlButtons = store.actor.isOwner;
const displayBuyButton = !!store.recipient;
function previewItem(item) {
item = store.actor.items.get(item.id);
if (game.user.isGM || item.data.permission[game.user.id] === 3) {
return item.sheet.render(true);
}
const cls = item._getSheetClass()
const sheet = new cls(item, { editable: false })
return sheet._render(true);
}
</script>


<div class="item-piles-img-container"
class:not-for-sale={itemFlagData.notForSale || !quantity}>
<img class="item-piles-img" src="{$itemImage}"/>
</div>

<div class="item-piles-name item-piles-text">
<div class="item-piles-name-container">
{#if $pileData.canInspectItems || game.user.isGM}
<a class="item-piles-clickable" on:click={previewItem(item)}>{$itemName}</a>
{:else}
{$itemName}
{/if}
{#if displayQuantity}
{#if itemFlagData.infiniteQuantity}
<span class="item-piles-small-text">(∞)</span>
{:else if !showEditQuantity}
<span class="item-piles-small-text" class:item-piles-clickable-link={game.user.isGM}
on:click={() => { if(game.user.isGM) showEditQuantity = true; }}>(x{quantity})</span>
{/if}
{/if}
{#if showEditQuantity}
<div class="item-piles-quantity-container" style="flex:0 1 50px;">
<div class="item-piles-quantity-input-container">
<input class="item-piles-quantity" type="text" bind:value="{editQuantity}" autofocus
on:change={() => { showEditQuantity = false; item.updateQuantity(editQuantity); }}
on:keydown={(evt) => { if(evt.key === "Enter") showEditQuantity = false; }}/>
</div>
</div>
{/if}
</div>
</div>
4 changes: 2 additions & 2 deletions src/applications/merchant-app/MerchantBuyTab.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { localize } from "@typhonjs-fvtt/runtime/svelte/helper";
import { fade } from 'svelte/transition';
import SliderInput from "../components/SliderInput.svelte";
import MerchantItemEntry from "./MerchantItemEntry.svelte";
import MerchantItemBuyEntry from "./MerchantItemBuyEntry.svelte";
export let store;
Expand Down Expand Up @@ -58,7 +58,7 @@

<div class="item-piles-items-list">
{#each $itemsPerCategoryStore[category.type] as item (item.id)}
<MerchantItemEntry {store} {item}/>
<MerchantItemBuyEntry {item}/>
{/each}
</div>
</div>
Expand Down
138 changes: 138 additions & 0 deletions src/applications/merchant-app/MerchantItemBuyEntry.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<script>
import { localize } from '@typhonjs-fvtt/runtime/svelte/helper';
import { fade } from 'svelte/transition';
import ItemEditor from "../editors/item-editor/item-editor.js";
import PriceSelector from "../components/PriceSelector.svelte";
import ItemEntry from "./ItemEntry.svelte";
export let item;
const itemName = item.name;
const itemImage = item.img;
const store = item.store;
const pileData = store.pileData;
const displayQuantityStore = item.displayQuantity;
const quantityStore = item.quantity;
const itemFlagDataStore = item.itemFlagData;
$: itemFlagData = $itemFlagDataStore;
$: displayQuantity = $displayQuantityStore;
$: quantity = $quantityStore;
$: editQuantity = $quantityStore;
let showEditQuantity = false;
const displayControlButtons = store.actor.isOwner;
const displayBuyButton = !!store.recipient;
function previewItem(item) {
item = store.actor.items.get(item.id);
if (game.user.isGM || item.data.permission[game.user.id] === 3) {
return item.sheet.render(true);
}
const cls = item._getSheetClass()
const sheet = new cls(item, { editable: false })
return sheet._render(true);
}
</script>

<div class="item-piles-flexrow item-piles-item-row item-piles-odd-color"
class:merchant-item-hidden={itemFlagData.hidden}
transition:fade|local={{duration: 250}}
style="flex: 1 0 auto;">

<ItemEntry {item}/>

<PriceSelector {item}/>

<div class="item-piles-flexrow sidebar-buttons">
{#if displayControlButtons}
{#if game.user.isGM}
<span class="item-piles-clickable-link" on:click={() => { ItemEditor.show(item.item); }}>
<i class="fas fa-cog"></i>
</span>
{/if}
<span class="item-piles-clickable-link"
on:click={() => { itemFlagData.hidden = !itemFlagData.hidden; item.updateItemFlagData(); }}>
<i class="fas" class:fa-eye={!itemFlagData.hidden} class:fa-eye-slash={itemFlagData.hidden}></i>
</span>
<span class="item-piles-clickable-link"
on:click={() => { itemFlagData.notForSale = !itemFlagData.notForSale; item.updateItemFlagData(); }}>
<i class="fas" class:fa-store={!itemFlagData.notForSale} class:fa-store-slash={itemFlagData.notForSale}></i>
</span>
{/if}
{#if displayBuyButton}
<span
class:item-piles-clickable-link={!itemFlagData.notForSale || game.user.isGM}
class:item-piles-clickable-link-disabled={quantity <= 0 || (itemFlagData.notForSale && !game.user.isGM)}
class:buy-button={displayControlButtons}
on:click={() => {
if(quantity <= 0 || (itemFlagData.notForSale && !game.user.isGM)) return;
store.tradeItem(item)
}}>
<i class="fas fa-shopping-cart"></i>
{#if !displayControlButtons} {localize("ITEM-PILES.Merchant.Buy")}{/if}
</span>
{/if}
</div>

</div>


<style lang="scss">
.item-piles-item-row {
margin: 0;
overflow: visible;
.sidebar-buttons {
flex: 0 1 auto;
align-items: center;
justify-content: flex-end;
text-align: right;
& > span {
flex: 0 1 auto;
margin-right: 0.25rem;
min-width: 17.5px;
}
.buy-button {
padding-left: 0.25rem;
border-left: 1px solid rgba(0, 0, 0, 0.5)
}
.disabled-buy-button {
opacity: 0.5;
}
}
&.merchant-item-hidden {
font-style: italic;
opacity: 0.5;
}
.item-piles-text {
font-size: inherit;
}
.item-piles-img-container {
min-width: 20px;
max-height: 20px;
margin: 2px;
flex: 1 0 auto;
overflow: hidden;
border-radius: 4px;
border: 1px solid black;
align-self: center;
}
.item-piles-name-container {
line-height: 1.6;
}
}
</style>
Loading

0 comments on commit db559a3

Please sign in to comment.