137 lines
3.4 KiB
Go
137 lines
3.4 KiB
Go
|
package mlp
|
||
|
|
||
|
import (
|
||
|
"math/rand"
|
||
|
|
||
|
"git.fromouter.space/mcg/draft"
|
||
|
)
|
||
|
|
||
|
/*
|
||
|
|
||
|
(This data was taken from the MLP:CCG wikia at mlpccg.fandom.com and confirmed
|
||
|
by people at the MLP:CCG Discord)
|
||
|
|
||
|
Distribution rates for packs is usually 8 commons, 3 uncommons and 1 rare.
|
||
|
|
||
|
No Fixed or Promo cards can be found in packs.
|
||
|
|
||
|
UR distribution depends on set:
|
||
|
- PR has 1/13 chance of UR replacing a common
|
||
|
- CN->AD has 1/11 chance of UR replacing a common
|
||
|
- EO->FF has 1/3 chance of SR/UR replacing a common
|
||
|
|
||
|
SR are twice as common as UR, so that's one more thing to keep in mind.
|
||
|
|
||
|
Lastly, RR can replace another common in the ratio of ~1/2 every 6 boxes, depending
|
||
|
on set. Specifically, this is the RR ratio for each set:
|
||
|
- EO->HM: 1/108
|
||
|
- MT->FF: 1/216
|
||
|
|
||
|
*/
|
||
|
|
||
|
// BoxSchema returns the pack schema from a booster box for a specific set
|
||
|
func (set *Set) BoxSchema() draft.PackSchema {
|
||
|
// Return blank schemas for invalid sets
|
||
|
if set.ID == SetRockNRave || set.ID == SetCelestialSolstice {
|
||
|
return draft.PackSchema{}
|
||
|
}
|
||
|
|
||
|
var rr []draft.AlternateProvider
|
||
|
var srur []draft.AlternateProvider
|
||
|
|
||
|
// Check for RR chances
|
||
|
switch set.ID {
|
||
|
case SetEquestrialOdysseys,
|
||
|
SetHighMagic:
|
||
|
rr = []draft.AlternateProvider{
|
||
|
{
|
||
|
Probability: 1.0 / 108.0,
|
||
|
Provider: set.ProviderByRarity(RarityRoyalRare),
|
||
|
},
|
||
|
}
|
||
|
case SetMarksInTime,
|
||
|
SetDefendersOfEquestria,
|
||
|
SetSeaquestriaBeyond,
|
||
|
SetFriendsForever:
|
||
|
rr = []draft.AlternateProvider{
|
||
|
{
|
||
|
Probability: 1.0 / 216.0,
|
||
|
Provider: set.ProviderByRarity(RarityRoyalRare),
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check for SR/UR chances
|
||
|
switch set.ID {
|
||
|
case SetPremiere:
|
||
|
srur = []draft.AlternateProvider{
|
||
|
{
|
||
|
Probability: 1.0 / 13.0,
|
||
|
Provider: set.ProviderByRarity(RarityUltraRare),
|
||
|
},
|
||
|
}
|
||
|
case SetCanterlotNights,
|
||
|
SetCrystalGames,
|
||
|
SetAbsoluteDiscord:
|
||
|
srur = []draft.AlternateProvider{
|
||
|
{
|
||
|
Probability: 1.0 / 11.0,
|
||
|
Provider: set.ProviderByRarity(RarityUltraRare),
|
||
|
},
|
||
|
}
|
||
|
default:
|
||
|
srur = []draft.AlternateProvider{
|
||
|
{
|
||
|
Probability: (1.0 / 9.0) * 2.0,
|
||
|
Provider: set.ProviderByRarity(RaritySuperRare),
|
||
|
}, {
|
||
|
Probability: 1.0 / 9.0,
|
||
|
Provider: set.ProviderByRarity(RarityUltraRare),
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return draft.PackSchema{
|
||
|
Slots: []draft.PackSlot{
|
||
|
// Fixed common slots
|
||
|
{Amount: 6, Provider: set.ProviderByRarity(RarityCommon)},
|
||
|
// Common slot that can be replaced by RR
|
||
|
{Amount: 1, Provider: set.ProviderByRarity(RarityCommon), Alternate: rr},
|
||
|
// Common slot that can be replaced by SR/UR
|
||
|
{Amount: 1, Provider: set.ProviderByRarity(RarityCommon), Alternate: srur},
|
||
|
// Fixed rare and uncommon slots
|
||
|
{Amount: 1, Provider: set.ProviderByRarity(RarityRare)},
|
||
|
{Amount: 3, Provider: set.ProviderByRarity(RarityUncommon)},
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ProviderByRarity returns a provider for a given rarity level from a given set
|
||
|
func (set *Set) ProviderByRarity(rarity Rarity) draft.CardProvider {
|
||
|
var collection []draft.Card
|
||
|
// RR flow is super easy, just pick one from our hardcoded list
|
||
|
if rarity == RarityRoyalRare {
|
||
|
rr, ok := royalRares[set.ID]
|
||
|
// If asking for RR from a set that doesn't have one, exit early
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
collection = rr
|
||
|
} else {
|
||
|
for _, card := range set.Cards {
|
||
|
if card.Rarity == rarity {
|
||
|
collection = append(collection, draft.Card{ID: card.ID})
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return func(n int) []draft.Card {
|
||
|
out := make([]draft.Card, n)
|
||
|
for n := range out {
|
||
|
// Pick a RR at random
|
||
|
idx := rand.Intn(len(collection))
|
||
|
out[n] = collection[idx]
|
||
|
}
|
||
|
return out
|
||
|
}
|
||
|
}
|