cardid
This commit is contained in:
parent
4a460e1dce
commit
a5f78f4d9d
@ -1,18 +1,79 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"git.tuxpa.in/a/card_id/common/game"
|
||||
"git.tuxpa.in/a/card_id/common/game/card"
|
||||
)
|
||||
|
||||
func main() {
|
||||
g, err := game.New().ReadFromRoot(os.Getenv("CARD_DATA_DIR"))
|
||||
deal, err := card.NewDealer().ReadFromRoot(os.Getenv("CARD_DATA_DIR"))
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
log.Println(g.RandomLevel().RandomTable().RandomResult())
|
||||
g := game.Game{Dealer: deal, Lives: 3}
|
||||
|
||||
trial := g.CreateTrial(3, 1)
|
||||
for {
|
||||
if trial != nil {
|
||||
if trial.CheckSelection() {
|
||||
fmt.Print("\n match found!!!")
|
||||
}
|
||||
}
|
||||
fmt.Printf("\ncardid > ")
|
||||
var args [4]string
|
||||
alen, _ := fmt.Scanln(&args[0], &args[1], &args[2], &args[3])
|
||||
if alen < 0 {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(args[0], "c") {
|
||||
args[1] = string(strip([]byte(args[0])))
|
||||
args[0] = "c"
|
||||
alen = 2
|
||||
}
|
||||
switch args[0] {
|
||||
case "help":
|
||||
fmt.Printf("show, select, update")
|
||||
case "show":
|
||||
fmt.Printf("current hand:\n %+v", trial.Show())
|
||||
case "select", "sel", "c":
|
||||
if alen > 1 {
|
||||
num, _ := strconv.Atoi(args[1])
|
||||
cd, err := trial.SelectCard(num)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if cd.Id > 0 {
|
||||
msg := fmt.Sprintf(`
|
||||
card %d was %s | lives: %d
|
||||
current hand:
|
||||
%s`, num, cd.Name, trial.Lives, trial.ShowString())
|
||||
fmt.Printf(msg)
|
||||
}
|
||||
} else {
|
||||
trial.SelectCard(0)
|
||||
}
|
||||
case "debug":
|
||||
fmt.Println(trial)
|
||||
case "exit", "quit", "q":
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
func strip(s []byte) []byte {
|
||||
n := 0
|
||||
for _, b := range s {
|
||||
if ('0' <= b && b <= '9') ||
|
||||
b == ' ' {
|
||||
s[n] = b
|
||||
n++
|
||||
}
|
||||
}
|
||||
return s[:n]
|
||||
}
|
||||
|
@ -9,9 +9,9 @@ import (
|
||||
type Results []Result
|
||||
|
||||
type Result struct {
|
||||
Itemid int `yaml:"Itemid"`
|
||||
Name string `yaml:"Name"`
|
||||
Rate float64 `yaml:"Rate"`
|
||||
Id int `yaml:"Itemid"`
|
||||
Name string `yaml:"Name"`
|
||||
Rate float64 `yaml:"Rate"`
|
||||
}
|
||||
|
||||
func NewResultsFromFile(path string) (Results, error) {
|
||||
|
26
common/errs/errors.go
Normal file
26
common/errs/errors.go
Normal file
@ -0,0 +1,26 @@
|
||||
package errs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func e(prefix string, f string, args ...any) error {
|
||||
return fmt.Errorf("%s: "+f, prefix, args)
|
||||
}
|
||||
|
||||
func Logic(f string, a ...any) error {
|
||||
return e("logic", f, a)
|
||||
}
|
||||
|
||||
func IsLogic(err error) bool {
|
||||
return strings.HasPrefix("logic", err.Error())
|
||||
}
|
||||
|
||||
func Invalid(f string, a ...any) error {
|
||||
return e("invalid", f, a)
|
||||
}
|
||||
|
||||
func IsInvalid(err error) bool {
|
||||
return strings.HasPrefix("invalid", err.Error())
|
||||
}
|
24
common/game/card/brand.go
Normal file
24
common/game/card/brand.go
Normal file
@ -0,0 +1,24 @@
|
||||
package card
|
||||
|
||||
import (
|
||||
"lukechampine.com/frand"
|
||||
)
|
||||
|
||||
type Brand struct {
|
||||
Name string
|
||||
|
||||
SelectionWeight float64
|
||||
RewardDeck *Deck
|
||||
SpecialDeck *Deck
|
||||
SpecialChance float64
|
||||
}
|
||||
|
||||
func (l *Brand) GetDeck() *Deck {
|
||||
if l.SpecialChance == 0 {
|
||||
return l.RewardDeck
|
||||
}
|
||||
if l.SpecialChance > (frand.Float64() * 100) {
|
||||
return l.SpecialDeck
|
||||
}
|
||||
return l.RewardDeck
|
||||
}
|
16
common/game/card/card.go
Normal file
16
common/game/card/card.go
Normal file
@ -0,0 +1,16 @@
|
||||
package card
|
||||
|
||||
import "git.tuxpa.in/a/card_id/common/data"
|
||||
|
||||
type Card struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Rate float64 `json:"rate"`
|
||||
}
|
||||
|
||||
func (c *Card) FromResult(d data.Result) Card {
|
||||
c.Id = d.Id
|
||||
c.Name = d.Name
|
||||
c.Rate = d.Rate
|
||||
return *c
|
||||
}
|
70
common/game/card/dealer.go
Normal file
70
common/game/card/dealer.go
Normal file
@ -0,0 +1,70 @@
|
||||
package card
|
||||
|
||||
import (
|
||||
"log"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
"git.tuxpa.in/a/card_id/common/data"
|
||||
"lukechampine.com/frand"
|
||||
)
|
||||
|
||||
type Dealer struct {
|
||||
Brands map[string]*Brand
|
||||
TotalProbability float64
|
||||
}
|
||||
|
||||
func NewDealer() *Dealer {
|
||||
return &Dealer{
|
||||
Brands: make(map[string]*Brand, 12),
|
||||
TotalProbability: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Dealer) ReadFromRoot(datadir string) (*Dealer, error) {
|
||||
if datadir == "" {
|
||||
datadir = "./data"
|
||||
}
|
||||
grades, err := data.NewGradesFromFile(path.Join(datadir, "GradeInfo.yaml"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range grades {
|
||||
lvl := &Brand{}
|
||||
lvl.Name = strconv.Itoa(v.Grade)
|
||||
g.Brands[lvl.Name] = lvl
|
||||
lvl.SelectionWeight = v.Rate
|
||||
g.TotalProbability = g.TotalProbability + v.Rate
|
||||
|
||||
rres, err := data.NewResultsFromFile(path.Join(datadir, "ResultTable", lvl.Name+".yaml"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lvl.RewardDeck = NewDeck(rres)
|
||||
if v.SpecialRate > 0 {
|
||||
lvl.SpecialChance = v.SpecialRate
|
||||
sres, err := data.NewResultsFromFile(path.Join(datadir, "SpecialTable", lvl.Name+".yaml"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lvl.SpecialDeck = NewDeck(sres)
|
||||
}
|
||||
}
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func (g *Dealer) GetBrand() *Brand {
|
||||
selector := frand.Float64() * g.TotalProbability
|
||||
sofar := 0.0
|
||||
if len(g.Brands) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, v := range g.Brands {
|
||||
sofar = sofar + v.SelectionWeight
|
||||
if sofar >= selector-0.000000001 {
|
||||
return v
|
||||
}
|
||||
}
|
||||
log.Println("BAD BAD BAD BAD BAD BAD PLEASE REPORT OH NO OH NO OH FISJAFIJNSAF")
|
||||
return g.GetBrand()
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package table
|
||||
package card
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -9,33 +9,33 @@ import (
|
||||
|
||||
// a table is a collection of results
|
||||
|
||||
type Table struct {
|
||||
raw data.Results
|
||||
type Deck struct {
|
||||
Cards []Card
|
||||
|
||||
TotalProbability float64
|
||||
}
|
||||
|
||||
func New(r data.Results) *Table {
|
||||
out := &Table{}
|
||||
out.raw = r
|
||||
|
||||
for _, v := range out.raw {
|
||||
func NewDeck(r data.Results) *Deck {
|
||||
out := &Deck{}
|
||||
out.Cards = make([]Card, 0, len(r))
|
||||
for _, v := range r {
|
||||
out.Cards = append(out.Cards, new(Card).FromResult(v))
|
||||
out.TotalProbability = out.TotalProbability + v.Rate
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (t *Table) RandomResult() data.Result {
|
||||
func (t *Deck) Draw() Card {
|
||||
selector := frand.Float64() * t.TotalProbability
|
||||
sofar := 0.0
|
||||
for _, v := range t.raw {
|
||||
for _, v := range t.Cards {
|
||||
sofar = sofar + v.Rate
|
||||
if sofar >= selector-0.000000001 {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return data.Result{
|
||||
return Card{
|
||||
Id: 0,
|
||||
Name: fmt.Sprintf("please report this bug: %v", selector),
|
||||
Rate: selector,
|
||||
}
|
@ -1,72 +1,45 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"log"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
"git.tuxpa.in/a/card_id/common/data"
|
||||
"git.tuxpa.in/a/card_id/common/game/level"
|
||||
"git.tuxpa.in/a/card_id/common/game/table"
|
||||
"git.tuxpa.in/a/card_id/common/game/card"
|
||||
"lukechampine.com/frand"
|
||||
)
|
||||
|
||||
type Game struct {
|
||||
Levels map[string]*level.Level
|
||||
TotalProbability float64
|
||||
Lives int
|
||||
Dealer *card.Dealer
|
||||
}
|
||||
|
||||
func New() *Game {
|
||||
return &Game{
|
||||
Levels: make(map[string]*level.Level, 12),
|
||||
TotalProbability: 0,
|
||||
func (g *Game) CreateTrial(pairs int, extra int) *Trial {
|
||||
if pairs > 10 {
|
||||
pairs = 10
|
||||
}
|
||||
}
|
||||
cards := make([]card.Card, 0, pairs*2+extra)
|
||||
ids := map[int]struct{}{}
|
||||
deck := g.Dealer.GetBrand().GetDeck()
|
||||
|
||||
func (g *Game) ReadFromRoot(datadir string) (*Game, error) {
|
||||
if datadir == "" {
|
||||
datadir = "./data"
|
||||
}
|
||||
grades, err := data.NewGradesFromFile(path.Join(datadir, "GradeInfo.yaml"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range grades {
|
||||
lvl := &level.Level{}
|
||||
lvl.Name = strconv.Itoa(v.Grade)
|
||||
g.Levels[lvl.Name] = lvl
|
||||
lvl.SelectionWeight = v.Rate
|
||||
g.TotalProbability = g.TotalProbability + v.Rate
|
||||
|
||||
rres, err := data.NewResultsFromFile(path.Join(datadir, "ResultTable", lvl.Name+".yaml"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lvl.RewardTable = table.New(rres)
|
||||
if v.SpecialRate > 0 {
|
||||
lvl.SpecialChance = v.SpecialRate
|
||||
sres, err := data.NewResultsFromFile(path.Join(datadir, "SpecialTable", lvl.Name+".yaml"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lvl.SpecialTable = table.New(sres)
|
||||
for i := 0; i < pairs; {
|
||||
card := deck.Draw()
|
||||
if _, ok := ids[card.Id]; !ok {
|
||||
ids[card.Id] = struct{}{}
|
||||
cards = append(cards, card, card)
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func (g *Game) RandomLevel() *level.Level {
|
||||
selector := frand.Float64() * g.TotalProbability
|
||||
sofar := 0.0
|
||||
if len(g.Levels) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, v := range g.Levels {
|
||||
sofar = sofar + v.SelectionWeight
|
||||
if sofar >= selector-0.000000001 {
|
||||
return v
|
||||
for i := 0; i < extra; {
|
||||
card := deck.Draw()
|
||||
if _, ok := ids[card.Id]; !ok {
|
||||
ids[card.Id] = struct{}{}
|
||||
cards = append(cards, card)
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
log.Println("BAD BAD BAD BAD BAD BAD PLEASE REPORT OH NO OH NO OH FISJAFIJNSAF")
|
||||
return g.RandomLevel()
|
||||
|
||||
frand.Shuffle(len(cards), func(i, j int) { cards[i], cards[j] = cards[j], cards[i] })
|
||||
trial := NewTrial(g.Lives)
|
||||
for k, v := range cards {
|
||||
trial.Cards[k+1] = v
|
||||
}
|
||||
return trial
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
package level
|
||||
|
||||
import (
|
||||
"git.tuxpa.in/a/card_id/common/game/table"
|
||||
"lukechampine.com/frand"
|
||||
)
|
||||
|
||||
type Level struct {
|
||||
Name string
|
||||
|
||||
SelectionWeight float64
|
||||
RewardTable *table.Table
|
||||
SpecialTable *table.Table
|
||||
SpecialChance float64
|
||||
}
|
||||
|
||||
func (l *Level) RandomTable() *table.Table {
|
||||
if l.SpecialChance == 0 {
|
||||
return l.RewardTable
|
||||
}
|
||||
if l.SpecialChance > (frand.Float64() * 100) {
|
||||
return l.SpecialTable
|
||||
}
|
||||
return l.RewardTable
|
||||
}
|
124
common/game/trial.go
Normal file
124
common/game/trial.go
Normal file
@ -0,0 +1,124 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"git.tuxpa.in/a/card_id/common/errs"
|
||||
"git.tuxpa.in/a/card_id/common/game/card"
|
||||
"git.tuxpa.in/a/card_id/common/util"
|
||||
)
|
||||
|
||||
type Trial struct {
|
||||
Cards map[int]card.Card
|
||||
Lives int
|
||||
|
||||
SelectionState int
|
||||
PendingSelection [2]int
|
||||
|
||||
Shown map[int]card.Card
|
||||
History [][2]int
|
||||
}
|
||||
|
||||
func NewTrial(lives int) *Trial {
|
||||
return &Trial{
|
||||
Lives: lives,
|
||||
Cards: make(map[int]card.Card, 7),
|
||||
Shown: make(map[int]card.Card, 7),
|
||||
PendingSelection: [2]int{-1, -1},
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Trial) SelectCard(id int) (card.Card, error) {
|
||||
if id > len(t.Cards) {
|
||||
return card.Card{}, errs.Invalid("index out of bounds")
|
||||
}
|
||||
if t.Lives == 0 {
|
||||
return card.Card{}, errs.Logic("game over")
|
||||
}
|
||||
switch t.SelectionState {
|
||||
case 0: // start selection
|
||||
t.SelectionState = 1
|
||||
t.PendingSelection[0] = id
|
||||
return t.Cards[id], nil
|
||||
case 1: // complete selection
|
||||
t.SelectionState = 2
|
||||
t.PendingSelection[1] = id
|
||||
return t.Cards[id], nil
|
||||
default:
|
||||
return card.Card{}, errs.Logic("bad game state")
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Trial) CheckSelection() bool {
|
||||
switch t.SelectionState {
|
||||
case 0, 1:
|
||||
return false
|
||||
default:
|
||||
}
|
||||
|
||||
defer func() {
|
||||
t.SelectionState = 0
|
||||
}()
|
||||
|
||||
c1, ok := t.Cards[t.PendingSelection[0]]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
c2, ok := t.Cards[t.PendingSelection[1]]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if c1.Id == c2.Id {
|
||||
if c1.Name == c2.Name {
|
||||
t.Shown[t.PendingSelection[0]] = c1
|
||||
t.Shown[t.PendingSelection[1]] = c2
|
||||
return true
|
||||
}
|
||||
}
|
||||
t.History = append(t.History, t.PendingSelection)
|
||||
t.PendingSelection = [2]int{-1, -1}
|
||||
t.Lives = t.Lives - 1
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *Trial) Show() map[int]card.Card {
|
||||
out := util.CopyMap(t.Shown)
|
||||
for _, v := range t.PendingSelection {
|
||||
if v > 0 {
|
||||
out[v] = t.Cards[v]
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (t *Trial) ShowString() string {
|
||||
out := util.CopyMap(t.Shown)
|
||||
for _, v := range t.PendingSelection {
|
||||
if v > 0 {
|
||||
out[v] = t.Cards[v]
|
||||
}
|
||||
}
|
||||
|
||||
outs := ""
|
||||
for _, k := range t.CardKeys() {
|
||||
piece := "[???]"
|
||||
if v, ok := out[k]; ok {
|
||||
piece = fmt.Sprintf("[%s]", v.Name)
|
||||
}
|
||||
outs = outs + piece + " "
|
||||
}
|
||||
return strings.TrimSpace(outs)
|
||||
}
|
||||
|
||||
func (t *Trial) CardKeys() []int {
|
||||
keys := make([]int, 0, len(t.Cards))
|
||||
for k := range t.Cards {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Slice(keys, func(i, j int) bool {
|
||||
return keys[i] < keys[j]
|
||||
})
|
||||
return keys
|
||||
}
|
9
common/util/mapcopy.go
Normal file
9
common/util/mapcopy.go
Normal file
@ -0,0 +1,9 @@
|
||||
package util
|
||||
|
||||
func CopyMap[T comparable, V any](m map[T]V) map[T]V {
|
||||
cp := make(map[T]V, len(m))
|
||||
for k, v := range m {
|
||||
cp[k] = v
|
||||
}
|
||||
return cp
|
||||
}
|
@ -1,127 +1,127 @@
|
||||
---
|
||||
- ItemID: 2027
|
||||
- Itemid: 2027
|
||||
Name: Light pink potion
|
||||
Rate: 5.000000
|
||||
- ItemID: 2227
|
||||
- Itemid: 2227
|
||||
Name: Light blue potion
|
||||
Rate: 5.000000
|
||||
- ItemID: 8331
|
||||
- Itemid: 8331
|
||||
Name: Universal Drill 8
|
||||
Rate: 5.000000
|
||||
- ItemID: 8332
|
||||
- Itemid: 8332
|
||||
Name: Sand Drill 8
|
||||
Rate: 5.000000
|
||||
- ItemID: 8333
|
||||
- Itemid: 8333
|
||||
Name: Sea Drill 8
|
||||
Rate: 5.000000
|
||||
- ItemID: 8334
|
||||
- Itemid: 8334
|
||||
Name: Land Drill 8
|
||||
Rate: 5.000000
|
||||
- ItemID: 8335
|
||||
- Itemid: 8335
|
||||
Name: Stone 8
|
||||
Rate: 5.000000
|
||||
- ItemID: 8336
|
||||
- Itemid: 8336
|
||||
Name: I do not know how to do this
|
||||
Rate: 5.000000
|
||||
- ItemID: 8369
|
||||
- Itemid: 8369
|
||||
Name: Neo Sand Drill 8
|
||||
Rate: 2.000000
|
||||
- ItemID: 8371
|
||||
- Itemid: 8371
|
||||
Name: Neo Land Drill 8
|
||||
Rate: 2.000000
|
||||
- ItemID: 8372
|
||||
- Itemid: 8372
|
||||
Name: Neo Dull 8
|
||||
Rate: 2.000000
|
||||
- ItemID: 8370
|
||||
- Itemid: 8370
|
||||
Name: Neo Sea Drill 8
|
||||
Rate: 2.000000
|
||||
- ItemID: 61850
|
||||
- Itemid: 61850
|
||||
Name: Card Pack of Stars No.7
|
||||
Rate: 5.000000
|
||||
- ItemID: 1008
|
||||
- Itemid: 1008
|
||||
Name: Diamond
|
||||
Rate: 2.000000
|
||||
- ItemID: 60403
|
||||
- Itemid: 60403
|
||||
Name: Stone of detection 380
|
||||
Rate: 10.000000
|
||||
- ItemID: 60416
|
||||
- Itemid: 60416
|
||||
Name: stone of attack power 380
|
||||
Rate: 10.000000
|
||||
- ItemID: 60429
|
||||
- Itemid: 60429
|
||||
Name: Mana stone 380
|
||||
Rate: 10.000000
|
||||
- ItemID: 60442
|
||||
- Itemid: 60442
|
||||
Name: Stone of Magic Defense 380
|
||||
Rate: 10.000000
|
||||
- ItemID: 60455
|
||||
- Itemid: 60455
|
||||
Name: Stone of the Master 380
|
||||
Rate: 10.000000
|
||||
- ItemID: 60468
|
||||
- Itemid: 60468
|
||||
Name: Stone of hit rate 380
|
||||
Rate: 10.000000
|
||||
- ItemID: 60481
|
||||
- Itemid: 60481
|
||||
Name: Stone of weight 380
|
||||
Rate: 10.000000
|
||||
- ItemID: 60494
|
||||
- Itemid: 60494
|
||||
Name: Stone of Agile 380
|
||||
Rate: 10.000000
|
||||
- ItemID: 60507
|
||||
- Itemid: 60507
|
||||
Name: stone of defense 380
|
||||
Rate: 10.000000
|
||||
- ItemID: 60520
|
||||
- Itemid: 60520
|
||||
Name: Stone of Luck 380
|
||||
Rate: 10.000000
|
||||
- ItemID: 60533
|
||||
- Itemid: 60533
|
||||
Name: Stone of Stamina 380
|
||||
Rate: 10.000000
|
||||
- ItemID: 60546
|
||||
- Itemid: 60546
|
||||
Name: Avoided stone 380
|
||||
Rate: 10.000000
|
||||
- ItemID: 60404
|
||||
- Itemid: 60404
|
||||
Name: Stone of detection 395
|
||||
Rate: 10.000000
|
||||
- ItemID: 60417
|
||||
- Itemid: 60417
|
||||
Name: Stone of ATK 395
|
||||
Rate: 10.000000
|
||||
- ItemID: 60430
|
||||
- Itemid: 60430
|
||||
Name: Mana 395
|
||||
Rate: 10.000000
|
||||
- ItemID: 60443
|
||||
- Itemid: 60443
|
||||
Name: Stone of Magic Defense 395
|
||||
Rate: 10.000000
|
||||
- ItemID: 60456
|
||||
- Itemid: 60456
|
||||
Name: Stone of the Master 395
|
||||
Rate: 10.000000
|
||||
- ItemID: 60469
|
||||
- Itemid: 60469
|
||||
Name: Stone of hit rate 395
|
||||
Rate: 10.000000
|
||||
- ItemID: 60482
|
||||
- Itemid: 60482
|
||||
Name: Stone of weight 395
|
||||
Rate: 10.000000
|
||||
- ItemID: 60495
|
||||
- Itemid: 60495
|
||||
Name: Stone of Agile 395
|
||||
Rate: 10.000000
|
||||
- ItemID: 60508
|
||||
- Itemid: 60508
|
||||
Name: stone of defense 395
|
||||
Rate: 10.000000
|
||||
- ItemID: 60521
|
||||
- Itemid: 60521
|
||||
Name: Stone of Luck 395
|
||||
Rate: 10.000000
|
||||
- ItemID: 60534
|
||||
- Itemid: 60534
|
||||
Name: Stone of Stamina 395
|
||||
Rate: 10.000000
|
||||
- ItemID: 60547
|
||||
- Itemid: 60547
|
||||
Name: Avoidance Stone 395
|
||||
Rate: 10.000000
|
||||
- ItemID: 2003
|
||||
- Itemid: 2003
|
||||
Name: Hanbang Punction
|
||||
Rate: 30.000000
|
||||
- ItemID: 2203
|
||||
- Itemid: 2203
|
||||
Name: Gold Pearment Potion
|
||||
Rate: 30.000000
|
||||
- ItemID: 2004
|
||||
- Itemid: 2004
|
||||
Name: 천 엑 스
|
||||
Rate: 15.000000
|
||||
- ItemID: 2204
|
||||
- Itemid: 2204
|
||||
Name: Jewelry Potion
|
||||
Rate: 15.000000
|
||||
|
@ -5,110 +5,110 @@
|
||||
- Itemid: 2203
|
||||
Name: Gold Pearment Potion
|
||||
Rate: 30.000000
|
||||
- ItemID: 8308
|
||||
- Itemid: 8308
|
||||
Name: Universal Drill No. 3
|
||||
Rate: 5.000000
|
||||
- ItemID: 8309
|
||||
- Itemid: 8309
|
||||
Name: sand drill 3
|
||||
Rate: 5.000000
|
||||
- ItemID: 8310
|
||||
- Itemid: 8310
|
||||
Name: ground drill 3
|
||||
Rate: 5.000000
|
||||
- ItemID: 8311
|
||||
- Itemid: 8311
|
||||
Name: Stone 3
|
||||
Rate: 5.000000
|
||||
- ItemID: 8346
|
||||
- Itemid: 8346
|
||||
Name: Neo Sand Drill No. 3
|
||||
Rate: 2.000000
|
||||
- ItemID: 8347
|
||||
- Itemid: 8347
|
||||
Name: Neo Land Drill No. 3
|
||||
Rate: 2.000000
|
||||
- ItemID: 8348
|
||||
- Itemid: 8348
|
||||
Name: Neo Dry L Deal 3
|
||||
Rate: 2.000000
|
||||
- ItemID: 61758
|
||||
- Itemid: 61758
|
||||
Name: Card Pack of Stars No.3
|
||||
Rate: 5.000000
|
||||
- ItemID: 1004
|
||||
- Itemid: 1004
|
||||
Name: Topaz
|
||||
Rate: 10.000000
|
||||
- ItemID: 1005
|
||||
- Itemid: 1005
|
||||
Name: Emerald
|
||||
Rate: 8.000000
|
||||
- ItemID: 60011
|
||||
- Itemid: 60011
|
||||
Name: Stone of detection 170
|
||||
Rate: 10.000000
|
||||
- ItemID: 60025
|
||||
- Itemid: 60025
|
||||
Name: Stone of ATK 170
|
||||
Rate: 10.000000
|
||||
- ItemID: 60039
|
||||
- Itemid: 60039
|
||||
Name: Mana's stone 170
|
||||
Rate: 10.000000
|
||||
- ItemID: 60053
|
||||
- Itemid: 60053
|
||||
Name: Magic defense stone 170
|
||||
Rate: 10.000000
|
||||
- ItemID: 60067
|
||||
- Itemid: 60067
|
||||
Name: Stone of the magic power 170
|
||||
Rate: 10.000000
|
||||
- ItemID: 60081
|
||||
- Itemid: 60081
|
||||
Name: Stone of hit rate 170
|
||||
Rate: 10.000000
|
||||
- ItemID: 60095
|
||||
- Itemid: 60095
|
||||
Name: Stone of weight 170
|
||||
Rate: 10.000000
|
||||
- ItemID: 60109
|
||||
- Itemid: 60109
|
||||
Name: Stone of Agile Stone 170
|
||||
Rate: 10.000000
|
||||
- ItemID: 60123
|
||||
- Itemid: 60123
|
||||
Name: Stone of defense 170
|
||||
Rate: 10.000000
|
||||
- ItemID: 60137
|
||||
- Itemid: 60137
|
||||
Name: Stone of Luck 170
|
||||
Rate: 10.000000
|
||||
- ItemID: 60151
|
||||
- Itemid: 60151
|
||||
Name: Stone of Stamina 170
|
||||
Rate: 10.000000
|
||||
- ItemID: 60165
|
||||
- Itemid: 60165
|
||||
Name: Avoided stone 170
|
||||
Rate: 10.000000
|
||||
- ItemID: 60012
|
||||
- Itemid: 60012
|
||||
Name: Stone of detection 185
|
||||
Rate: 10.000000
|
||||
- ItemID: 60026
|
||||
- Itemid: 60026
|
||||
Name: Stone of ATK 185
|
||||
Rate: 10.000000
|
||||
- ItemID: 60040
|
||||
- Itemid: 60040
|
||||
Name: Mana's stone 185
|
||||
Rate: 10.000000
|
||||
- ItemID: 60054
|
||||
- Itemid: 60054
|
||||
Name: Stone of Magic Defense 185
|
||||
Rate: 10.000000
|
||||
- ItemID: 60068
|
||||
- Itemid: 60068
|
||||
Name: Stone of the Master 185
|
||||
Rate: 10.000000
|
||||
- ItemID: 60082
|
||||
- Itemid: 60082
|
||||
Name: Stone of hit rate 185
|
||||
Rate: 10.000000
|
||||
- ItemID: 60096
|
||||
- Itemid: 60096
|
||||
Name: Stone of Weight 185
|
||||
Rate: 10.000000
|
||||
- ItemID: 60110
|
||||
- Itemid: 60110
|
||||
Name: Stone of Agile 185
|
||||
Rate: 10.000000
|
||||
- ItemID: 60124
|
||||
- Itemid: 60124
|
||||
Name: 185 defense stone 185
|
||||
Rate: 10.000000
|
||||
- ItemID: 60138
|
||||
- Itemid: 60138
|
||||
Name: Stone of Luck 185
|
||||
Rate: 10.000000
|
||||
- ItemID: 60152
|
||||
- Itemid: 60152
|
||||
Name: Stone of Stamina 185
|
||||
Rate: 10.000000
|
||||
- ItemID: 60166
|
||||
- Itemid: 60166
|
||||
Name: Avoidance of stone 185
|
||||
Rate: 10.000000
|
||||
- Itemid: 2004
|
||||
Name: 천 엑 스
|
||||
Name: Thousand extract
|
||||
Rate: 15.000000
|
||||
- Itemid: 2204
|
||||
Name: Jewelry Potion
|
||||
|
Loading…
Reference in New Issue
Block a user