Shop
Before this: Mods, Maps, Per-Player State
A coin counter for every player and two shop buttons. Players earn coins with one button and spend them on items with the others. An item goes straight into the buyer’s inventory.
Contents
You need
- A Button that pays out coins (or a Target: see Change it).
- Two Buttons for the shop, one per item.
button1 "Press Count" -> chip earn
button1 Character -> chip earner
button2 "Press Count" -> chip buy1
button2 Character -> chip buyer1
button3 "Press Count" -> chip buy2
button3 Character -> chip buyer2
Code
const EARN = 1 // coins per press of the earn button
const PRICE_1 = 3 // price of item 1
const PRICE_2 = 10 // price of item 2
const ITEM_1 = $BRItemBase/Weapon_Bandage // item 1
const ITEM_2 = $BRItemBase/Weapon_Pickaxe // item 2
@left in earn: int
@left in earner: character
@left in buy1: int
@left in buyer1: character
@left in buy2: int
@left in buyer2: character
var coins: Map<string, int>
var lastEarn: int = 0
var last1: int = 0
var last2: int = 0
// true when a button's Press Count went up: a new press, not a release
mod pressed(holding: int, prev: *int) -> bool {
let up = holding > prev
prev = holding
return up
}
mod balance(who: character) -> int {
let had = coins.get(who.GetUserId())
return if had.Found then had.Value else 0
}
mod pay(who: character, price: int) -> bool {
let have = balance(who)
if have < price {
who.ShowStatusMessage("You need ${price} coins, you have ${have}")
return false
}
coins.set(who.GetUserId(), have - price)
who.ShowStatusMessage("Bought! ${have - price} coins left")
return true
}
on Change(earn) {
if pressed(earn, lastEarn) {
let now = balance(earner) + EARN
coins.set(earner.GetUserId(), now)
earner.ShowStatusMessage("Coins: ${now}")
}
}
on Change(buy1) {
if pressed(buy1, last1) {
if pay(buyer1, PRICE_1) {
buyer1.AddInventoryItem(ITEM_1)
}
}
}
on Change(buy2) {
if pressed(buy2, last2) {
if pay(buyer2, PRICE_2) {
buyer2.AddInventoryItem(ITEM_2)
}
}
}
Wire it
- Compile the chip and paste it in-game.
- Wire the earn Button’s Press Count to
earnand its Character toearner. - Wire the first shop Button’s Press Count and Character to
buy1andbuyer1, and the second’s tobuy2andbuyer2. - Label the shop buttons with their item and price, on a sign or in each Button’s Prompt Custom Label setting.
Check it in game
- Press the first shop button with no coins: “You need 3 coins, you have 0”, and nothing is added to your inventory.
- Press the earn button three times: “Coins: 1”, “Coins: 2”, “Coins: 3”. Letting go gives nothing.
- Press the first shop button: “Bought! 0 coins left”, and a bandage is in your inventory.
- A second player earns and buys: their coins are their own.
- Hold the earn button down while a second player presses it: they still get their coin.
- Die and respawn: your coins are still there.
Change it
- Sell other items: the editor lists every item name after
$BRItemBase/. ChangeITEM_1andPRICE_1. - Earn coins from a Target instead of a button: make
earnanexecpin, change its handler toon earnwithout thepressedcheck, and wire Just Hit toearnand Character That Just Hit toearner. Or give coins at the end of a course, in a zone’son ZoneEnteredhandler. - Add a third item: two more pins, a
last3var and anon Change(buy3)handler.pressedandpaywork for it unchanged.
How it works
Every player’s coins are one entry in a map
keyed by GetUserId(), so they survive a respawn and are saved with the
bricks. Two mods hold the rules. balance reads a
player’s coins, 0 when they have no entry yet. pay checks the price and
takes the coins, and its -> bool result tells the handler whether to hand
over the item. Each Button’s Character output says who pressed it, so
one button serves every player. A Button’s Press Count is how many
players hold it right now. The handlers run on every Change of it
(Change), and the pressed mod
lets one through only when the count went up since the last change: a new
press, never a release. Each button keeps its own last count (lastEarn,
last1, last2). Held stays on while anyone holds the button, so a
second player’s press during that time would not turn it on again, though
Press Count and Character both change. AddInventoryItem adds an
item to the buyer’s inventory. The item is a constant $BRItemBase/...
asset reference, chosen when the chip is compiled.
Back to Parts.