109 lines
2.9 KiB
Go
109 lines
2.9 KiB
Go
package v1
|
|
|
|
import (
|
|
"math/rand/v2"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"jp.wtf/go-fishing/internal/api"
|
|
)
|
|
|
|
var sayings = []string{
|
|
// Near Misses
|
|
"Close but no cigar",
|
|
"Almost only counts in horseshoes and hand grenades",
|
|
"A day late and a dollar short",
|
|
"A miss is as good as a mile",
|
|
"Always a bridesmaid, never a bride",
|
|
"Snatched defeat from the jaws of victory",
|
|
"Fell at the last hurdle",
|
|
"Missed the boat",
|
|
"Missed it by a whisker",
|
|
"So near, and yet so far",
|
|
"A swing and a miss",
|
|
|
|
// Futile Efforts
|
|
"Beating a dead horse",
|
|
"Tilting at windmills",
|
|
"Squeezing blood from a stone",
|
|
"Nailing jelly to a wall",
|
|
"Herding cats",
|
|
"Rearranging deck chairs on the Titanic",
|
|
"Pushing a rope",
|
|
"Spitting in the wind",
|
|
"Putting toothpaste back in the tube",
|
|
"Shoveling snow in a blizzard",
|
|
"Spinning your wheels",
|
|
"Emptying the ocean with a teaspoon",
|
|
"Barking up the wrong tree",
|
|
"A wild goose chase",
|
|
"Catching the wind in a net",
|
|
}
|
|
|
|
func (h *V1Router) Cast(c *gin.Context) {
|
|
angler, err := api.GetAnglerFromSession(c)
|
|
|
|
if err != nil {
|
|
api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, err.Error())
|
|
return
|
|
}
|
|
|
|
is_casting, check_err := h.DB.IsCasting(angler.ID)
|
|
|
|
if check_err != nil {
|
|
api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, "Unable to check for existing cast")
|
|
return
|
|
}
|
|
|
|
if is_casting {
|
|
api.Fail(c, http.StatusBadRequest, api.APIErrorCodeInvalidRequest, "You are already casting! >:|")
|
|
return
|
|
}
|
|
|
|
cast, cast_create_err := h.DB.CreateNewCast(angler.ID)
|
|
|
|
if cast_create_err != nil {
|
|
api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, "Unable to start your cast")
|
|
return
|
|
}
|
|
|
|
// Fishing can take anywhere from 2-5 seconds
|
|
minTime, maxTime := 2, 5
|
|
timeToWait := rand.IntN(maxTime-minTime+1) + minTime
|
|
|
|
select {
|
|
case <-time.After(time.Duration(timeToWait) * time.Second):
|
|
// One we complete fishing we must decide if we caught anything
|
|
chance := 75
|
|
gen := rand.IntN(100)
|
|
caught := gen < chance
|
|
|
|
_, end_cast_err := h.DB.EndCastByID(cast.ID)
|
|
|
|
if end_cast_err != nil {
|
|
api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, "Unable to update your cast — may have left you in a bad state :(")
|
|
return
|
|
}
|
|
|
|
if caught {
|
|
// If so then we must select a fish.
|
|
// Then we must determine a size between the min and max of said fish
|
|
// Finally record the catch and return it
|
|
api.OK(c, "Got one! Nice!")
|
|
} else {
|
|
// Otherwise return. You are left empty handed
|
|
api.Fail(c, http.StatusNotFound, api.APIErrorCodeNotFound, sayings[rand.IntN(len(sayings))])
|
|
}
|
|
case <-c.Done():
|
|
_, end_cast_err := h.DB.EndCastByID(cast.ID)
|
|
|
|
if end_cast_err != nil {
|
|
api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, "Unable to update your cast — may have left you in a bad state :(")
|
|
return
|
|
}
|
|
|
|
api.Fail(c, http.StatusRequestTimeout, api.APIErrorCodeUnknown, "Cast terminiated for unknown reason")
|
|
}
|
|
}
|