Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

life.gno

3.82 Kb · 185 lines
  1package fish
  2
  3import (
  4	"chain/runtime"
  5	"crypto/sha256"
  6	"strconv"
  7	"time"
  8
  9	"gno.land/r/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/shoal/shoaltoken"
 10)
 11
 12func Register(cur realm, id int, stake int64) {
 13	caller := requireUser(cur)
 14	body := must(id)
 15	if body.owner != caller {
 16		panic("fish: owner")
 17	}
 18	if body.inMatch {
 19		panic("fish: match")
 20	}
 21	if body.mustHeal {
 22		panic("fish: heal")
 23	}
 24	guardMovable(body)
 25	if tooHurt(body) {
 26		panic("fish: hp")
 27	}
 28	if walletInSea(caller) {
 29		panic("fish: one")
 30	}
 31	if !arenaStake(stake) {
 32		panic("fish: stake")
 33	}
 34	takeExact(stake)
 35	now := time.Now().Unix()
 36	body.pool = stake
 37	body.inMatch = true
 38	body.boutPaid = false
 39	body.startUnix = now
 40	body.endUnix = 0
 41	body.lastCombatMilli = -1
 42	body.nextMoveMilli = 0
 43	body.burstUntil = 0
 44	body.nextBurstAt = 0
 45	body.springBorn = -1
 46	placeSwimmer(body)
 47	clearDamage(id)
 48}
 49
 50func Leave(cur realm, id int) {
 51	caller := requireUser(cur)
 52	takeExact(0)
 53	body := must(id)
 54	if body.owner != caller {
 55		panic("fish: owner")
 56	}
 57	if !body.inMatch {
 58		panic("fish: match")
 59	}
 60	nowMs := time.Now().UnixMilli()
 61	if body.lastCombatMilli >= 0 && nowMs < body.lastCombatMilli+combatLockMs {
 62		panic("fish: stay")
 63	}
 64	returnCheers(body, cur)
 65	stake := body.pool
 66	body.pool = 0
 67	body.inMatch = false
 68	body.boutPaid = false
 69	clearDamage(id)
 70	send(caller, stake, cur)
 71}
 72
 73func SettleMatch(cur realm, id int) {
 74	requireUser(cur)
 75	takeExact(0)
 76	body := must(id)
 77	if !body.inMatch {
 78		panic("fish: match")
 79	}
 80	_ = body
 81	panic("fish: sea")
 82}
 83
 84func CommitLay(cur realm, id int) {
 85	caller := requireUser(cur)
 86	body := must(id)
 87	if body.owner != caller {
 88		panic("fish: owner")
 89	}
 90	guardMovable(body)
 91	left := body.bouts - body.layBoutsUsed
 92	if left < 3 {
 93		panic("fish: bouts")
 94	}
 95	takeExact(layFee)
 96	payMint(layFee, cur)
 97	body.layBoutsUsed = body.bouts
 98	body.layOpen = true
 99	body.layHeight = runtime.ChainHeight()
100}
101
102func SettleLay(cur realm, id int) int {
103	requireUser(cur)
104	takeExact(0)
105	body := must(id)
106	if !body.layOpen {
107		panic("fish: lay")
108	}
109	height := runtime.ChainHeight()
110	if height < body.layHeight+layBlocks {
111		panic("fish: early")
112	}
113	trait := traitFrom(body.id, body.layHeight, height, time.Now().Unix())
114	body.layOpen = false
115	return issue(body.owner, body.name+" fry", body.rarity, body.size, trait)
116}
117
118// Upgrade spends 15 FISH to step two played Common fish to Uncommon.
119// The FISH fee burns. The team takes none of it. No GNOT moves.
120// Higher tiers stay closed until a commit-reveal roll exists.
121func Upgrade(cur realm, keep, food int) int {
122	caller := requireUser(cur)
123	if keep == food {
124		panic("fish: upgrade")
125	}
126	a := must(keep)
127	b := must(food)
128	if a.owner != caller || b.owner != caller {
129		panic("fish: owner")
130	}
131	guardMovable(a)
132	guardMovable(b)
133	if a.rarity != b.rarity || a.size != b.size || a.trait != b.trait {
134		panic("fish: pair")
135	}
136	if a.bouts < 1 || b.bouts < 1 {
137		panic("fish: bouts")
138	}
139	if a.rarity != "common" {
140		panic("fish: roll")
141	}
142	takeExact(0)
143	if !fishTokenReady() {
144		panic("fish: fish")
145	}
146	got := shoaltoken.Draw(cross(cur), caller, burnSink, upgradeFishFee)
147	if got != upgradeFishFee {
148		panic("fish: fish")
149	}
150	name := a.name
151	size := a.size
152	trait := a.trait
153	burnBody(a)
154	burnBody(b)
155	return issue(caller, name, "uncommon", size, trait)
156}
157
158func burnBody(body *fishBody) {
159	burnGRC(body.id)
160	body.burned = true
161	body.owner = address("")
162	body.seller = address("")
163	body.price = 0
164	body.listed = false
165	body.pool = 0
166	body.inMatch = false
167	body.layOpen = false
168}
169
170func traitFrom(id int, commitHeight, settleHeight, unix int64) string {
171	raw := strconv.Itoa(id) + ":" + strconv.FormatInt(commitHeight, 10) + ":" + strconv.FormatInt(settleHeight, 10) + ":" + strconv.FormatInt(unix, 10)
172	sum := sha256.Sum256([]byte(raw))
173	var n int64
174	for i := 0; i < len(sum); i++ {
175		n = (n*256 + int64(sum[i])) % 3
176	}
177	switch n {
178	case 0:
179		return "swift"
180	case 1:
181		return "fang"
182	default:
183		return "hide"
184	}
185}