From bddce58943604a7d1fc7836b79fc9935776f6c23 Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Fri, 21 Sep 2018 15:44:03 +0530 Subject: [PATCH 01/13] add versioned object and updateInit method --- battleground/versioned.go | 31 +++++++++++++++ battleground/zombie_battleground.go | 62 ++++++++++++++++++++++++++--- types/zb/zb.proto | 9 +++++ 3 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 battleground/versioned.go diff --git a/battleground/versioned.go b/battleground/versioned.go new file mode 100644 index 00000000..07f43f9f --- /dev/null +++ b/battleground/versioned.go @@ -0,0 +1,31 @@ +package battleground + +import ( + "fmt" + + "github.com/loomnetwork/go-loom/util" +) + +type Versioned interface { + GetVersion() string + MakeKey([]byte) []byte +} + +type V1 struct { + KeyPrefix string +} + +func (v *V1) GetVersion() string { + return "v1" +} + +func (v *V1) MakeKey(key []byte) []byte { + return util.PrefixKey([]byte(v.GetVersion()), key) +} + +func getVersionedObject(version string) (Versioned, error) { + if version == "v1" { + return &V1{}, nil + } + return nil, fmt.Errorf("version not found") +} diff --git a/battleground/zombie_battleground.go b/battleground/zombie_battleground.go index dc3004ed..409807fe 100644 --- a/battleground/zombie_battleground.go +++ b/battleground/zombie_battleground.go @@ -22,25 +22,77 @@ func (z *ZombieBattleground) Meta() (plugin.Meta, error) { } func (z *ZombieBattleground) Init(ctx contract.Context, req *zb.InitRequest) error { + v, err := getVersionedObject(req.Version) + if err != nil { + return err + } + + // initialize card library + cardList := zb.CardList{ + Cards: req.Cards, + } + if err := ctx.Set(v.MakeKey(cardListKey), &cardList); err != nil { + return err + } + // initialize heros + heroList := zb.HeroList{ + Heroes: req.Heroes, + } + if err := ctx.Set(v.MakeKey(heroListKey), &heroList); err != nil { + return err + } + + cardCollectionList := zb.CardCollectionList{ + Cards: req.DefaultCollection, + } + if err := ctx.Set(v.MakeKey(defaultCollectionKey), &cardCollectionList); err != nil { + return err + } + + // initialize default deck + deckList := zb.DeckList{ + Decks: req.DefaultDecks, + } + if err := ctx.Set(v.MakeKey(defaultDeckKey), &deckList); err != nil { + return err + } + + defaultHeroList := zb.HeroList{ + Heroes: req.Heroes, + } + if err := ctx.Set(v.MakeKey(defaultHeroesKey), &defaultHeroList); err != nil { + return err + } + + return nil +} + +func (z *ZombieBattleground) UpdateInit(ctx contract.Context, req *zb.UpdateInitRequest) error { + v, err := getVersionedObject(req.Version) + if err != nil { + return err + } + // initialize card library cardList := zb.CardList{ Cards: req.Cards, } - if err := ctx.Set(cardListKey, &cardList); err != nil { + if err := ctx.Set(v.MakeKey(cardListKey), &cardList); err != nil { return err } + // initialize heros heroList := zb.HeroList{ Heroes: req.Heroes, } - if err := ctx.Set(heroListKey, &heroList); err != nil { + if err := ctx.Set(v.MakeKey(heroListKey), &heroList); err != nil { return err } cardCollectionList := zb.CardCollectionList{ Cards: req.DefaultCollection, } - if err := ctx.Set(defaultCollectionKey, &cardCollectionList); err != nil { + if err := ctx.Set(v.MakeKey(defaultCollectionKey), &cardCollectionList); err != nil { return err } @@ -48,14 +100,14 @@ func (z *ZombieBattleground) Init(ctx contract.Context, req *zb.InitRequest) err deckList := zb.DeckList{ Decks: req.DefaultDecks, } - if err := ctx.Set(defaultDeckKey, &deckList); err != nil { + if err := ctx.Set(v.MakeKey(defaultDeckKey), &deckList); err != nil { return err } defaultHeroList := zb.HeroList{ Heroes: req.Heroes, } - if err := ctx.Set(defaultHeroesKey, &defaultHeroList); err != nil { + if err := ctx.Set(v.MakeKey(defaultHeroesKey), &defaultHeroList); err != nil { return err } diff --git a/types/zb/zb.proto b/types/zb/zb.proto index da9c15f7..8aa2293c 100644 --- a/types/zb/zb.proto +++ b/types/zb/zb.proto @@ -204,6 +204,15 @@ message InitRequest { repeated CardCollection default_collection = 2; repeated Card cards = 3; repeated Hero heroes = 4; + string version = 5; +} + +message UpdateInitRequest { + repeated Deck default_decks = 1; + repeated CardCollection default_collection = 2; + repeated Card cards = 3; + repeated Hero heroes = 4; + string version = 5; } message UpsertAccountRequest { From 4586e91ca5cef7858b510836fb7c50ff43d47ebf Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Fri, 21 Sep 2018 16:26:39 +0530 Subject: [PATCH 02/13] add cmd to cli --- cli/cmd/update_init.go | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 cli/cmd/update_init.go diff --git a/cli/cmd/update_init.go b/cli/cmd/update_init.go new file mode 100644 index 00000000..eca8150f --- /dev/null +++ b/cli/cmd/update_init.go @@ -0,0 +1,45 @@ +package cmd + +import ( + "encoding/json" + "fmt" + + "github.com/loomnetwork/go-loom/auth" + "github.com/spf13/cobra" + + "github.com/loomnetwork/zombie_battleground/types/zb" +) + +var updateInitCmdArgs struct { + version string + data string +} + +var updateInitCmd = &cobra.Command{ + Use: "update_init", + Short: "updates the init data for zombiebattleground", + RunE: func(cmd *cobra.Command, args []string) error { + signer := auth.NewEd25519Signer(commonTxObjs.privateKey) + var updateInitData zb.UpdateInitRequest + + if err := json.Unmarshal([]byte(updateInitCmdArgs.data), &updateInitData); err != nil { + return fmt.Errorf("invalid JSON passed in data field. Error: %s", err.Error()) + } + + updateInitData.Version = updateInitCmdArgs.version + _, err := commonTxObjs.contract.Call("UpdateInit", &updateInitData, signer, nil) + if err != nil { + return fmt.Errorf("error encountered while calling UpdateInit: %s", err.Error()) + } + fmt.Printf("Data updated successfully\n") + + return nil + }, +} + +func init() { + rootCmd.AddCommand(updateInitCmd) + + updateInitCmd.Flags().StringVarP(&updateInitCmdArgs.version, "version", "v", "1", "UserId of account") + updateInitCmd.Flags().StringVarP(&updateInitCmdArgs.data, "data", "d", "{}", "Init data to be updated in serialized json format") +} From 60d753ce86dcfdce53cb88fec29d7af07136f8fd Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Fri, 21 Sep 2018 18:09:50 +0530 Subject: [PATCH 03/13] start writing test for update init --- battleground/zombie_battleground_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/battleground/zombie_battleground_test.go b/battleground/zombie_battleground_test.go index f11e417f..1331620e 100644 --- a/battleground/zombie_battleground_test.go +++ b/battleground/zombie_battleground_test.go @@ -668,3 +668,7 @@ func TestHeroOperations(t *testing.T) { }) } + +func TestUpdateInitDataOperations(t *testing.T) { + +} From 793243e5ff90b4fca1221061fc594660b74abaa8 Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Fri, 21 Sep 2018 18:24:00 +0530 Subject: [PATCH 04/13] change v.MakeKey to MakeVersionedKey --- battleground/storage.go | 4 ++++ battleground/versioned.go | 31 ----------------------------- battleground/zombie_battleground.go | 31 +++++++++++------------------ 3 files changed, 16 insertions(+), 50 deletions(-) delete mode 100644 battleground/versioned.go diff --git a/battleground/storage.go b/battleground/storage.go index 3573f700..8f1c6450 100644 --- a/battleground/storage.go +++ b/battleground/storage.go @@ -69,6 +69,10 @@ func UserMatchKey(userID string) []byte { return []byte("user:" + userID + ":match") } +func MakeVersionedKey(version string, key []byte) []byte { + return util.PrefixKey([]byte(version), key) +} + // func userAccountKey(id string) []byte { // return util.PrefixKey(userPreifx, []byte(id)) // } diff --git a/battleground/versioned.go b/battleground/versioned.go deleted file mode 100644 index 07f43f9f..00000000 --- a/battleground/versioned.go +++ /dev/null @@ -1,31 +0,0 @@ -package battleground - -import ( - "fmt" - - "github.com/loomnetwork/go-loom/util" -) - -type Versioned interface { - GetVersion() string - MakeKey([]byte) []byte -} - -type V1 struct { - KeyPrefix string -} - -func (v *V1) GetVersion() string { - return "v1" -} - -func (v *V1) MakeKey(key []byte) []byte { - return util.PrefixKey([]byte(v.GetVersion()), key) -} - -func getVersionedObject(version string) (Versioned, error) { - if version == "v1" { - return &V1{}, nil - } - return nil, fmt.Errorf("version not found") -} diff --git a/battleground/zombie_battleground.go b/battleground/zombie_battleground.go index 409807fe..d0148300 100644 --- a/battleground/zombie_battleground.go +++ b/battleground/zombie_battleground.go @@ -22,30 +22,27 @@ func (z *ZombieBattleground) Meta() (plugin.Meta, error) { } func (z *ZombieBattleground) Init(ctx contract.Context, req *zb.InitRequest) error { - v, err := getVersionedObject(req.Version) - if err != nil { - return err - } + version := req.Version // initialize card library cardList := zb.CardList{ Cards: req.Cards, } - if err := ctx.Set(v.MakeKey(cardListKey), &cardList); err != nil { + if err := ctx.Set(MakeVersionedKey(version, cardListKey), &cardList); err != nil { return err } // initialize heros heroList := zb.HeroList{ Heroes: req.Heroes, } - if err := ctx.Set(v.MakeKey(heroListKey), &heroList); err != nil { + if err := ctx.Set(MakeVersionedKey(version, heroListKey), &heroList); err != nil { return err } cardCollectionList := zb.CardCollectionList{ Cards: req.DefaultCollection, } - if err := ctx.Set(v.MakeKey(defaultCollectionKey), &cardCollectionList); err != nil { + if err := ctx.Set(MakeVersionedKey(version, defaultCollectionKey), &cardCollectionList); err != nil { return err } @@ -53,14 +50,14 @@ func (z *ZombieBattleground) Init(ctx contract.Context, req *zb.InitRequest) err deckList := zb.DeckList{ Decks: req.DefaultDecks, } - if err := ctx.Set(v.MakeKey(defaultDeckKey), &deckList); err != nil { + if err := ctx.Set(MakeVersionedKey(version, defaultDeckKey), &deckList); err != nil { return err } defaultHeroList := zb.HeroList{ Heroes: req.Heroes, } - if err := ctx.Set(v.MakeKey(defaultHeroesKey), &defaultHeroList); err != nil { + if err := ctx.Set(MakeVersionedKey(version, defaultHeroesKey), &defaultHeroList); err != nil { return err } @@ -68,31 +65,27 @@ func (z *ZombieBattleground) Init(ctx contract.Context, req *zb.InitRequest) err } func (z *ZombieBattleground) UpdateInit(ctx contract.Context, req *zb.UpdateInitRequest) error { - v, err := getVersionedObject(req.Version) - if err != nil { - return err - } + version := req.Version // initialize card library cardList := zb.CardList{ Cards: req.Cards, } - if err := ctx.Set(v.MakeKey(cardListKey), &cardList); err != nil { + if err := ctx.Set(MakeVersionedKey(version, cardListKey), &cardList); err != nil { return err } - // initialize heros heroList := zb.HeroList{ Heroes: req.Heroes, } - if err := ctx.Set(v.MakeKey(heroListKey), &heroList); err != nil { + if err := ctx.Set(MakeVersionedKey(version, heroListKey), &heroList); err != nil { return err } cardCollectionList := zb.CardCollectionList{ Cards: req.DefaultCollection, } - if err := ctx.Set(v.MakeKey(defaultCollectionKey), &cardCollectionList); err != nil { + if err := ctx.Set(MakeVersionedKey(version, defaultCollectionKey), &cardCollectionList); err != nil { return err } @@ -100,14 +93,14 @@ func (z *ZombieBattleground) UpdateInit(ctx contract.Context, req *zb.UpdateInit deckList := zb.DeckList{ Decks: req.DefaultDecks, } - if err := ctx.Set(v.MakeKey(defaultDeckKey), &deckList); err != nil { + if err := ctx.Set(MakeVersionedKey(version, defaultDeckKey), &deckList); err != nil { return err } defaultHeroList := zb.HeroList{ Heroes: req.Heroes, } - if err := ctx.Set(v.MakeKey(defaultHeroesKey), &defaultHeroList); err != nil { + if err := ctx.Set(MakeVersionedKey(version, defaultHeroesKey), &defaultHeroList); err != nil { return err } From 60a34e2b010eff74730206756c791e5ac491f178 Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Mon, 24 Sep 2018 11:26:11 +0530 Subject: [PATCH 05/13] get data from file instead of cmd --- cli/cmd/update_init.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/cli/cmd/update_init.go b/cli/cmd/update_init.go index eca8150f..179b7b06 100644 --- a/cli/cmd/update_init.go +++ b/cli/cmd/update_init.go @@ -3,6 +3,7 @@ package cmd import ( "encoding/json" "fmt" + "io/ioutil" "github.com/loomnetwork/go-loom/auth" "github.com/spf13/cobra" @@ -12,7 +13,7 @@ import ( var updateInitCmdArgs struct { version string - data string + file string } var updateInitCmd = &cobra.Command{ @@ -22,12 +23,21 @@ var updateInitCmd = &cobra.Command{ signer := auth.NewEd25519Signer(commonTxObjs.privateKey) var updateInitData zb.UpdateInitRequest - if err := json.Unmarshal([]byte(updateInitCmdArgs.data), &updateInitData); err != nil { + if updateInitCmdArgs.file == "" { + return fmt.Errorf("file name not provided") + } + + f, err := ioutil.ReadFile(updateInitCmdArgs.file) + if err != nil { + return fmt.Errorf("error reading file: %s", err.Error()) + } + + if err := json.Unmarshal(f, &updateInitData); err != nil { return fmt.Errorf("invalid JSON passed in data field. Error: %s", err.Error()) } updateInitData.Version = updateInitCmdArgs.version - _, err := commonTxObjs.contract.Call("UpdateInit", &updateInitData, signer, nil) + _, err = commonTxObjs.contract.Call("UpdateInit", &updateInitData, signer, nil) if err != nil { return fmt.Errorf("error encountered while calling UpdateInit: %s", err.Error()) } @@ -41,5 +51,5 @@ func init() { rootCmd.AddCommand(updateInitCmd) updateInitCmd.Flags().StringVarP(&updateInitCmdArgs.version, "version", "v", "1", "UserId of account") - updateInitCmd.Flags().StringVarP(&updateInitCmdArgs.data, "data", "d", "{}", "Init data to be updated in serialized json format") + updateInitCmd.Flags().StringVarP(&updateInitCmdArgs.file, "file", "f", "", "File of init data to be updated in serialized json format") } From 42399d94b7094d99b05195e4f5b96f954944f12b Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Mon, 24 Sep 2018 12:49:21 +0530 Subject: [PATCH 06/13] add version to list cards and persistent version flag --- battleground/zombie_battleground.go | 3 ++- cli/cmd/list_card.go | 7 +++++++ cli/cmd/root.go | 2 ++ cli/cmd/update_init.go | 10 ++++++---- types/zb/zb.proto | 1 + 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/battleground/zombie_battleground.go b/battleground/zombie_battleground.go index d0148300..73724db8 100644 --- a/battleground/zombie_battleground.go +++ b/battleground/zombie_battleground.go @@ -370,9 +370,10 @@ func (z *ZombieBattleground) GetCollection(ctx contract.StaticContext, req *zb.G // ListCardLibrary list all the card library data func (z *ZombieBattleground) ListCardLibrary(ctx contract.StaticContext, req *zb.ListCardLibraryRequest) (*zb.ListCardLibraryResponse, error) { var cardList zb.CardList - if err := ctx.Get(cardListKey, &cardList); err != nil { + if err := ctx.Get(MakeVersionedKey(req.Version, cardListKey), &cardList); err != nil { return nil, err } + // convert to card list to card library view grouped by set var category = make(map[string][]*zb.Card) for _, card := range cardList.Cards { diff --git a/cli/cmd/list_card.go b/cli/cmd/list_card.go index 0557b99f..8d870a41 100644 --- a/cli/cmd/list_card.go +++ b/cli/cmd/list_card.go @@ -13,6 +13,11 @@ var listCardCmd = &cobra.Command{ Use: "list_card", Short: "list card", RunE: func(cmd *cobra.Command, args []string) error { + + if rootCmdArgs.version == "" { + return fmt.Errorf("version not specified") + } + signer := auth.NewEd25519Signer(commonTxObjs.privateKey) callerAddr := loom.Address{ ChainID: commonTxObjs.rpcClient.GetChainID(), @@ -22,6 +27,8 @@ var listCardCmd = &cobra.Command{ req := zb.ListCardLibraryRequest{} result := zb.ListCardLibraryResponse{} + req.Version = rootCmdArgs.version + _, err := commonTxObjs.contract.StaticCall("ListCardLibrary", &req, callerAddr, &result) if err != nil { return err diff --git a/cli/cmd/root.go b/cli/cmd/root.go index bc3dd2f8..1c1e8688 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -13,6 +13,7 @@ var rootCmdArgs struct { privateKeyFilePath string readURI string writeURI string + version string } var commonTxObjs struct { @@ -77,6 +78,7 @@ func Execute() error { rootCmd.PersistentFlags().StringVarP(&rootCmdArgs.privateKeyFilePath, "key", "k", "priv.key", "Private key file path") rootCmd.PersistentFlags().StringVarP(&rootCmdArgs.readURI, "readURI", "r", "http://localhost:46658/query", "Read URI for rpc") rootCmd.PersistentFlags().StringVarP(&rootCmdArgs.writeURI, "writeURI", "w", "http://localhost:46658/rpc", "Write URI for rpc") + rootCmd.PersistentFlags().StringVarP(&rootCmdArgs.version, "version", "v", "", "Version") return rootCmd.Execute() } diff --git a/cli/cmd/update_init.go b/cli/cmd/update_init.go index 179b7b06..05211650 100644 --- a/cli/cmd/update_init.go +++ b/cli/cmd/update_init.go @@ -12,8 +12,7 @@ import ( ) var updateInitCmdArgs struct { - version string - file string + file string } var updateInitCmd = &cobra.Command{ @@ -36,7 +35,11 @@ var updateInitCmd = &cobra.Command{ return fmt.Errorf("invalid JSON passed in data field. Error: %s", err.Error()) } - updateInitData.Version = updateInitCmdArgs.version + if rootCmdArgs.version == "" { + return fmt.Errorf("version not specified") + } + + updateInitData.Version = rootCmdArgs.version _, err = commonTxObjs.contract.Call("UpdateInit", &updateInitData, signer, nil) if err != nil { return fmt.Errorf("error encountered while calling UpdateInit: %s", err.Error()) @@ -50,6 +53,5 @@ var updateInitCmd = &cobra.Command{ func init() { rootCmd.AddCommand(updateInitCmd) - updateInitCmd.Flags().StringVarP(&updateInitCmdArgs.version, "version", "v", "1", "UserId of account") updateInitCmd.Flags().StringVarP(&updateInitCmdArgs.file, "file", "f", "", "File of init data to be updated in serialized json format") } diff --git a/types/zb/zb.proto b/types/zb/zb.proto index 8aa2293c..ffe42c79 100644 --- a/types/zb/zb.proto +++ b/types/zb/zb.proto @@ -277,6 +277,7 @@ message ListDecksResponse { } message ListCardLibraryRequest { + string version = 1; } message ListCardLibraryResponse { From a4d542faf290fadd21ae2d5dc96ff82c07338170 Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Mon, 24 Sep 2018 14:05:36 +0530 Subject: [PATCH 07/13] add test for UpdateInit --- battleground/update-init-test.json | 3846 ++++++++++++++++++++++ battleground/zombie_battleground_test.go | 219 +- zb.genesis.json | 1 + 3 files changed, 4065 insertions(+), 1 deletion(-) create mode 100644 battleground/update-init-test.json diff --git a/battleground/update-init-test.json b/battleground/update-init-test.json new file mode 100644 index 00000000..a1683cb1 --- /dev/null +++ b/battleground/update-init-test.json @@ -0,0 +1,3846 @@ +{ + "default_collection": [ + { + "card_name": "Pyromaz", + "amount": 4 + }, + { + "card_name": "Quazi", + "amount": 4 + }, + { + "card_name": "Burrrnn", + "amount": 4 + }, + { + "card_name": "Cynderman", + "amount": 4 + }, + { + "card_name": "Werezomb", + "amount": 4 + }, + { + "card_name": "Modo", + "amount": 4 + }, + { + "card_name": "Fire-Maw", + "amount": 4 + }, + { + "card_name": "Zhampion", + "amount": 4 + }, + { + "card_name": "Gargantua", + "amount": 4 + }, + { + "card_name": "Cerberus", + "amount": 4 + }, + { + "card_name": "Izze", + "amount": 4 + }, + { + "card_name": "Znowman", + "amount": 4 + }, + { + "card_name": "Ozmoziz", + "amount": 4 + }, + { + "card_name": "Jetter", + "amount": 4 + }, + { + "card_name": "Freezzee", + "amount": 4 + }, + { + "card_name": "Geyzer", + "amount": 4 + }, + { + "card_name": "Blizzard", + "amount": 4 + }, + { + "card_name": "Froztbite", + "amount": 4 + }, + { + "card_name": "Zhatterer", + "amount": 4 + }, + { + "card_name": "Maelstrom", + "amount": 4 + }, + { + "card_name": "Tzunamy", + "amount": 4 + }, + { + "card_name": "Rockky", + "amount": 4 + }, + { + "card_name": "Bolderr", + "amount": 4 + }, + { + "card_name": "Blocker", + "amount": 4 + }, + { + "card_name": "Slab", + "amount": 4 + }, + { + "card_name": "Pit", + "amount": 4 + }, + { + "card_name": "Golem", + "amount": 4 + }, + { + "card_name": "Walley", + "amount": 4 + }, + { + "card_name": "Tiny", + "amount": 4 + }, + { + "card_name": "Spiker", + "amount": 4 + }, + { + "card_name": "Crater", + "amount": 4 + }, + { + "card_name": "Earthshaker", + "amount": 4 + }, + { + "card_name": "IgneouZ", + "amount": 4 + }, + { + "card_name": "Pyrite", + "amount": 4 + }, + { + "card_name": "Mountain", + "amount": 4 + }, + { + "card_name": "Gaea", + "amount": 4 + }, + { + "card_name": "Whizpar", + "amount": 4 + }, + { + "card_name": "Wheezy", + "amount": 4 + }, + { + "card_name": "Soothsayer", + "amount": 4 + }, + { + "card_name": "Fumez", + "amount": 4 + }, + { + "card_name": "Pushhh", + "amount": 4 + }, + { + "card_name": "Ztormmcaller", + "amount": 4 + }, + { + "card_name": "Bouncer", + "amount": 4 + }, + { + "card_name": "Gaz", + "amount": 4 + }, + { + "card_name": "Draft", + "amount": 4 + }, + { + "card_name": "MonZoon", + "amount": 4 + }, + { + "card_name": "Zeuz", + "amount": 4 + }, + { + "card_name": "Azuraz", + "amount": 4 + }, + { + "card_name": "Bloomer", + "amount": 4 + }, + { + "card_name": "Zap", + "amount": 4 + }, + { + "card_name": "Shroom", + "amount": 4 + }, + { + "card_name": "Vindrom", + "amount": 4 + }, + { + "card_name": "Puffer", + "amount": 4 + }, + { + "card_name": "Sapper", + "amount": 4 + }, + { + "card_name": "Keeper", + "amount": 4 + }, + { + "card_name": "Cactuz", + "amount": 4 + }, + { + "card_name": "Shammann", + "amount": 4 + }, + { + "card_name": "Z-Virus", + "amount": 4 + }, + { + "card_name": "Yggdrazil", + "amount": 4 + }, + { + "card_name": "Poizom", + "amount": 4 + }, + { + "card_name": "Hazmaz", + "amount": 4 + }, + { + "card_name": "Zpitter", + "amount": 4 + }, + { + "card_name": "Zeptic", + "amount": 4 + }, + { + "card_name": "Ghoul", + "amount": 4 + }, + { + "card_name": "Zeeter", + "amount": 4 + }, + { + "card_name": "Hazzard", + "amount": 4 + }, + { + "card_name": "Zludge", + "amount": 4 + }, + { + "card_name": "Ectoplasm", + "amount": 4 + }, + { + "card_name": "Cherno-bill", + "amount": 4 + }, + { + "card_name": "GooZilla", + "amount": 4 + }, + { + "card_name": "Chainsaw", + "amount": 4 + }, + { + "card_name": "Goo Beaker", + "amount": 4 + }, + { + "card_name": "Stapler", + "amount": 4 + }, + { + "card_name": "Nail Bomb", + "amount": 4 + }, + { + "card_name": "Goo Bottle", + "amount": 4 + }, + { + "card_name": "Fresh Meat", + "amount": 4 + }, + { + "card_name": "Zombie 1/1", + "amount": 4 + }, + { + "card_name": "Zombie 2/2", + "amount": 4 + }, + { + "card_name": "Zombie Feral", + "amount": 4 + }, + { + "card_name": "Armageddon", + "amount": 4 + }, + { + "card_name": "Tainted Goo", + "amount": 4 + }, + { + "card_name": "Corrupted Goo", + "amount": 4 + } + ], + "default_decks": [ + { + "id": 0, + "hero_id": 4, + "name": "Default", + "cards": [ + { + "card_name": "Poizom", + "amount": 4 + }, + { + "card_name": "Hazmaz", + "amount": 2 + }, + { + "card_name": "Zeeter", + "amount": 1 + }, + { + "card_name": "Zhatterer", + "amount": 4 + }, + { + "card_name": "Zludge", + "amount": 1 + }, + { + "card_name": "Znowman", + "amount": 4 + }, + { + "card_name": "Cerberus", + "amount": 1 + }, + { + "card_name": "Gargantua", + "amount": 1 + }, + { + "card_name": "Zhampion", + "amount": 1 + }, + { + "card_name": "Fire-Maw", + "amount": 1 + }, + { + "card_name": "Modo", + "amount": 1 + }, + { + "card_name": "Ghoul", + "amount": 1 + }, + { + "card_name": "Hazzard", + "amount": 1 + }, + { + "card_name": "Ectoplasm", + "amount": 1 + }, + { + "card_name": "Bouncer", + "amount": 2 + }, + { + "card_name": "Stapler", + "amount": 1 + }, + { + "card_name": "Goo Bottles", + "amount": 1 + }, + { + "card_name": "Chainsaw", + "amount": 2 + } + ] + } + ], + "heroes": [ + { + "hero_id": 0, + "icon": "icon", + "name": "Brakuus", + "short_description": "The Guardian", + "long_description": "", + "element": "EARTH", + "experience": 0, + "level": 0, + "skills": [ + { + "title": "Harden", + "skill": "HARDEN", + "icon_path": "overlordability_earth", + "description": "Give +2 Def to your Overlord", + "skill_targets": "", + "cooldown": 3, + "initial_cooldown": 3, + "value": 2 + }, + { + "title": "Stoneskin", + "skill": "STONE_SKIN", + "icon_path": "overlordability_earth_stone_skin", + "description": "Give an ally Earth zombie +1 Def", + "skill_targets": "PLAYER_CARD", + "element_targets": "EARTH", + "cooldown": 4, + "initial_cooldown": 4, + "value": 1 + } + ], + "primary_skill": 0, + "secondary_skill": 1 + }, + { + "hero_id": 1, + "icon": "icon", + "name": "Razu", + "short_description": "The Fire Daemon", + "long_description": "", + "element": "FIRE", + "experience": 0, + "level": 0, + "skills": [ + { + "title": "Fire Bolt", + "skill": "FIRE_BOLT", + "icon_path": "overlordability_fire", + "description": "Deal 1 damage to target", + "skill_targets": "OPPONENT_CARD|PLAYER_CARD|PLAYER|OPPONENT", + "cooldown": 3, + "initial_cooldown": 3, + "value": 1 + }, + { + "title": "Rabies", + "skill": "RABIES", + "icon_path": "overlordability_fire_rabies", + "description": "Give an ally Fire zombie Feral", + "skill_targets": "PLAYER_CARD", + "element_targets": "FIRE", + "cooldown": 4, + "initial_cooldown": 4, + "value": 1 + } + ], + "primary_skill": 0, + "secondary_skill": 1 + }, + { + "hero_id": 2, + "icon": "icon", + "name": "Vash'Kala", + "short_description": "The Ancient One", + "long_description": "", + "element": "WATER", + "experience": 0, + "level": 0, + "skills": [ + { + "title": "Freeze", + "skill": "FREEZE", + "icon_path": "overlordability_water", + "description": "Freeze a zombie", + "skill_targets": "OPPONENT_CARD|PLAYER_CARD", + "cooldown": 3, + "initial_cooldown": 3, + "value": 1 + }, + { + "title": "Ice Bolt", + "skill": "ICE_BOLT", + "icon_path": "overlordability_water_ice_bolt", + "description": "Deal 2 damage to a target zombie. If it survives, Freeze it", + "skill_targets": "OPPONENT_CARD|PLAYER_CARD", + "cooldown": 4, + "initial_cooldown": 4, + "value": 2 + } + ], + "primary_skill": 0, + "secondary_skill": 1 + }, + { + "hero_id": 3, + "icon": "icon", + "name": "Kalile", + "short_description": "Tempest of Storms", + "long_description": "", + "element": "AIR", + "experience": 0, + "level": 0, + "skills": [ + { + "title": "Push", + "skill": "PUSH", + "icon_path": "overlordability_air_push", + "description": "Return an ally Air zombie to your hand", + "skill_targets": "PLAYER_CARD", + "element_targets": "AIR", + "cooldown": 6, + "initial_cooldown": 5, + "value": 0 + }, + { + "title": "Draw", + "skill": "DRAW", + "icon_path": "overlordability_air_draw", + "description": "Draw a card", + "skill_targets": "", + "cooldown": 4, + "initial_cooldown": 4, + "value": 0 + } + ], + "primary_skill": 0, + "secondary_skill": 1 + }, + { + "hero_id": 4, + "icon": "icon", + "name": "Mhalik", + "short_description": "Lord of Pestilence", + "long_description": "", + "element": "TOXIC", + "experience": 0, + "level": 0, + "skills": [ + { + "title": "Poison Dart", + "skill": "POISON_DART", + "icon_path": "overlordability_toxic", + "description": "Deal 1 damage to an enemy", + "skill_targets": "OPPONENT_CARD|OPPONENT", + "cooldown": 3, + "initial_cooldown": 3, + "value": 1 + }, + { + "title": "Toxic Power", + "skill": "TOXIC_POWER", + "icon_path": "overlordability_toxic_toxic_power", + "description": "Deal 1 damage to an ally Toxic zombie and give it +1 Atk", + "skill_targets": "PLAYER_CARD", + "element_targets": "TOXIC", + "cooldown": 4, + "initial_cooldown": 4, + "value": 1, + "attack": 1 + } + ], + "primary_skill": 0, + "secondary_skill": 1 + }, + { + "hero_id": 5, + "icon": "icon", + "name": "Valash", + "short_description": "Nature's Warden", + "long_description": "", + "element": "LIFE", + "experience": 0, + "level": 0, + "skills": [ + { + "title": "Healing Touch", + "skill": "HEALING_TOUCH", + "icon_path": "overlordability_life", + "description": "Restore 2 Def to an ally zombie", + "skill_targets": "PLAYER_CARD", + "cooldown": 3, + "initial_cooldown": 3, + "value": 2 + }, + { + "title": "Mend", + "skill": "MEND", + "icon_path": "overlordability_life_mend", + "description": "Restore 2 Def to your Overlord", + "skill_targets": "PLAYER", + "cooldown": 4, + "initial_cooldown": 4, + "value": 2 + } + ], + "primary_skill": 0, + "secondary_skill": 1 + } + ], + "cards": [ + { + "set": "Fire", + "id": 0, + "kind": "CREATURE", + "name": "Pyromaz", + "cost": 1, + "description": "Attack: +1 damage to Toxic zombies", + "flavor_text": "Really into that old Prodigy song... Firestarter...", + "picture": "Pyromaz", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "MODIFICATOR_STATS", + "activity_type": "passive", + "call_type": "permanent", + "target_type": "none", + "stat_type": "damage", + "set_type": "toxic", + "value": 1, + "buff_type": "ATTACK" + } + ], + "card_view_info": { + "position": { + "x": -0.05, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Fire", + "id": 10000, + "kind": "CREATURE", + "name": "NewCard", + "cost": 1, + "description": "Attack: +1 damage to Toxic zombies", + "flavor_text": "Really into that old Prodigy song... Firestarter...", + "picture": "Pyromaz", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "MODIFICATOR_STATS", + "activity_type": "passive", + "call_type": "permanent", + "target_type": "none", + "stat_type": "damage", + "set_type": "toxic", + "value": 1, + "buff_type": "ATTACK" + } + ], + "card_view_info": { + "position": { + "x": -0.05, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + + { + "set": "Fire", + "id": 0, + "kind": "CREATURE", + "name": "Quazi", + "cost": 1, + "description": "Feral, Overflow 2, End: 2 damage to this and adjacent zombies", + "flavor_text": "Has a great fascination with church bells...", + "picture": "Quazi", + "damage": 0, + "health": 1, + "type": "FERAL", + "rank": "MINION", + "abilities": [ + { + "type": "OVERFLOW_GOO", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 2, + "buff_type": "OVERFLOW" + }, + { + "type": "DEAL_DAMAGE_TO_THIS_AND_ADJACENT_UNITS", + "activity_type": "passive", + "call_type": "END", + "value": 2, + "buff_type": "END" + } + ], + "card_view_info": { + "position": { + "x": -0.15, + "y": 0.2, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Fire", + "id": 1, + "kind": "CREATURE", + "name": "Burrrnn", + "cost": 3, + "description": "Feral", + "flavor_text": "So he likes all the pretty bright colors, can you blame him?", + "picture": "Burrrnn", + "damage": 2, + "health": 2, + "type": "FERAL", + "rank": "OFFICER", + "card_view_info": { + "position": { + "x": -0.3, + "y": 0.1, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Fire", + "id": 3, + "kind": "CREATURE", + "name": "Cynderman", + "cost": 4, + "description": "Entry: 2 damage to a zombie", + "flavor_text": "Hot, so very hot - all the time!", + "picture": "cynderman", + "damage": 2, + "health": 3, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "DAMAGE_TARGET", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "player_card|opponent_card", + "value": 2, + "effect_type": "TARGET_FIRE", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Fire", + "id": 2, + "kind": "CREATURE", + "name": "Werezomb", + "cost": 3, + "description": "Entry: random ally zombie gets Feral", + "flavor_text": "Stop, stop, stop, shh-shh, you'll cause a howel", + "picture": "Werezomb", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "TAKE_UNIT_TYPE_TO_ALLY_UNIT", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "player_card", + "unit_type": "FERAL", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Fire", + "id": 3, + "kind": "CREATURE", + "name": "Modo", + "cost": 3, + "description": "Feral, Overflow 5, End: 4 damage to this and adjacent zombies", + "flavor_text": "JuuuZZZt WaNt a LiTtlE hUgGG...", + "picture": "modo", + "damage": 2, + "health": 2, + "type": "FERAL", + "rank": "OFFICER", + "abilities": [ + { + "type": "OVERFLOW_GOO", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 5, + "buff_type": "OVERFLOW" + }, + { + "type": "DEAL_DAMAGE_TO_THIS_AND_ADJACENT_UNITS", + "activity_type": "passive", + "call_type": "END", + "value": 4, + "buff_type": "END" + } + ], + "card_view_info": { + "position": { + "x": -0.15, + "y": 0.2, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Fire", + "id": 5, + "kind": "CREATURE", + "name": "Fire-Maw", + "cost": 5, + "description": "Feral, Flash", + "flavor_text": "There's always an aftershock, duck twice", + "picture": "fire-maw", + "damage": 3, + "health": 3, + "type": "FERAL", + "rank": "COMMANDER", + "abilities": [ + { + "type": "ATTACK_NUMBER_OF_TIMES_PER_TURN", + "activity_type": "passive", + "call_type": "PERMANENT", + "target_type": "player_card", + "value": 2, + "attack_info": "ANY", + "buff_type": "FLASH" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Fire", + "id": 4, + "kind": "CREATURE", + "name": "Zhampion", + "cost": 5, + "description": "Feral, Entry: Summon two 1/1 enemy Pyromaz zombies", + "flavor_text": "I AM THE CHAMPION - my friend!! ME - ONLY ME!!!", + "picture": "Zhampion", + "damage": 5, + "health": 2, + "type": "FERAL", + "rank": "COMMANDER", + "abilities": [ + { + "type": "SUMMON", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "opponent", + "count": 2, + "name": "Pyromaz", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0.05, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Fire", + "id": 7, + "kind": "CREATURE", + "name": "Gargantua", + "cost": 11, + "description": "Entry: 2 damage to all enemies", + "flavor_text": "(sing) Under pressure... coming down on you...", + "picture": "Gargantua", + "damage": 6, + "health": 8, + "type": "HEAVY", + "rank": "GENERAL", + "abilities": [ + { + "type": "MASSIVE_DAMAGE", + "activity_type": "PASSIVE", + "call_type": "ENTRY", + "target_type": "OPPONENT_ALL_CARDS|opponent", + "value": 2, + "effect_type": "MASSIVE_FIRE", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.55, + "y": 0.55, + "z": 0.55 + } + } + }, + { + "set": "Fire", + "id": 6, + "kind": "CREATURE", + "name": "Cerberus", + "cost": 12, + "description": "Attack: Deal damage before receiving damage", + "flavor_text": "Its ALWAYS a party of three", + "picture": "Cerberus", + "damage": 7, + "health": 8, + "type": "WALKER", + "rank": "GENERAL", + "abilities": [ + { + "type": "PRIORITY_ATTACK", + "activity_type": "passive", + "call_type": "ENTRY", + "buff_type": "ATTACK" + } + ], + "card_view_info": { + "position": { + "x": -0.2, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Water", + "id": 9, + "kind": "CREATURE", + "name": "Izze", + "cost": 1, + "description": "Attack: +1 damage to Fire zombies", + "flavor_text": "It would be a-lot Izzier if you just stay put!", + "picture": "Izze", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "MODIFICATOR_STATS", + "activity_type": "passive", + "call_type": "permanent", + "target_type": "none", + "stat_type": "damage", + "set_type": "fire", + "value": 1, + "buff_type": "ATTACK" + } + ], + "card_view_info": { + "position": { + "x": 0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Water", + "id": 10, + "kind": "CREATURE", + "name": "Znowman", + "cost": 4, + "description": "Heavy, Enemies that attack this become Frozen", + "flavor_text": "Maybe the snow does have some magical power?! But not yellow snow...", + "picture": "Znowman", + "damage": 0, + "health": 5, + "type": "HEAVY", + "rank": "MINION", + "abilities": [ + { + "type": "ENEMY_THAT_ATTACKS_BECOME_FROZEN", + "activity_type": "passive", + "call_type": "AT_DEFENCE", + "buff_type": "FREEZE" + } + ], + "card_view_info": { + "position": { + "x": 0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Water", + "id": 10, + "kind": "CREATURE", + "name": "Ozmoziz", + "cost": 2, + "description": "Entry: Freeze a random ally, add Tainted Goo to your Hand", + "flavor_text": "He always loved to tell a goo story", + "picture": "Ozmoziz", + "damage": 1, + "health": 2, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "FREEZE_NUMBER_OF_RANDOM_ALLY", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 1, + "turns": 1, + "buff_type": "ENTRY" + }, + { + "type": "ADD_CARD_BY_NAME_TO_HAND", + "activity_type": "passive", + "call_type": "ENTRY", + "name": "Tainted Goo", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0.3, + "y": -0.08, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Water", + "id": 11, + "kind": "CREATURE", + "name": "Jetter", + "cost": 4, + "description": "Entry: 1 damage to a zombie.", + "flavor_text": "Most welcomed during hot summer days on the busy city streets", + "picture": "Jetter", + "damage": 3, + "health": 4, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "DAMAGE_TARGET", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "player_card|opponent_card", + "value": 1, + "effect_type": "TARGET_WATER", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.4, + "y": 0.1, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Water", + "id": 14, + "kind": "CREATURE", + "name": "Freezzee", + "cost": 4, + "description": "Entry: Freeze zombie and adjacent zombies, 2 damage if Frozen", + "flavor_text": "How he loves decorating with ice sculptures... Everywhere!", + "picture": "Freezzee", + "damage": 2, + "health": 2, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "STUN_OR_DAMAGE_ADJUSTMENTS", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "opponent_card", + "value": 2, + "effect_type": "STUN_OR_DAMAGE_FREEZES", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.15, + "y": 0.1, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Water", + "id": 14, + "kind": "CREATURE", + "name": "Geyzer", + "cost": 4, + "description": "Entry: Freeze 2 random allies, add Corrupted Goo to your Hand", + "flavor_text": "Not in the mood for dancing...", + "picture": "geyzer", + "damage": 2, + "health": 3, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "FREEZE_NUMBER_OF_RANDOM_ALLY", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 2, + "turns": 1, + "buff_type": "ENTRY" + }, + { + "type": "ADD_CARD_BY_NAME_TO_HAND", + "activity_type": "passive", + "call_type": "ENTRY", + "name": "Corrupted Goo", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Water", + "id": 12, + "kind": "CREATURE", + "name": "Blizzard", + "cost": 6, + "description": "Entry: Freeze all enemy zombies", + "flavor_text": "If you can't join them, FREEZE them!", + "picture": "Blizzard", + "damage": 3, + "health": 4, + "type": "WALKER", + "rank": "COMMANDER", + "abilities": [ + { + "type": "FREEZE_UNITS", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "opponent_card", + "value": 1, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0.05, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Water", + "id": 13, + "kind": "CREATURE", + "name": "Froztbite", + "cost": 4, + "description": "Delayed 2: +6 Atk", + "flavor_text": "He's been trying to get out for a millennia - thank you global warming!!", + "picture": "Froztbite", + "damage": 0, + "health": 6, + "type": "WALKER", + "rank": "COMMANDER", + "abilities": [ + { + "type": "DELAYED_GAIN_ATTACK", + "activity_type": "passive", + "call_type": "TURN", + "value": 6, + "delay": 2, + "buff_type": "DELAYED" + } + ], + "card_view_info": { + "position": { + "x": -0.3, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Water", + "id": 8, + "kind": "CREATURE", + "name": "Zhatterer", + "cost": 3, + "description": "Entry: Destroy a Frozen zombie", + "flavor_text": "So the other day Gargantua asked for a toothpick.. and it needs to be really cold to actually work...", + "picture": "Zhatterer", + "damage": 1, + "health": 2, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "DESTROY_FROZEN_UNIT", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "OPPONENT_CARD", + "unit_status": "FROZEN", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Water", + "id": 15, + "kind": "CREATURE", + "name": "Maelstrom", + "cost": 8, + "description": "Entry: Return all zombies to their owners' Hands", + "flavor_text": "Sometimes pukes a little in his mouth from all the spinning, but keeps a scary face!", + "picture": "Maelstrom", + "damage": 5, + "health": 5, + "type": "WALKER", + "rank": "COMMANDER", + "abilities": [ + { + "type": "RETURN_UNITS_ON_BOARD_TO_OWNERS_HANDS", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "opponent_all_cards|player_all_cards", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Water", + "id": 16, + "kind": "CREATURE", + "name": "Tzunamy", + "cost": 11, + "description": "Entry: 2 damage to all enemies, then Freeze them", + "flavor_text": "Bringing a nice, big shower, cleaning an entire city at a time.", + "picture": "Tzunamy", + "damage": 6, + "health": 6, + "type": "WALKER", + "rank": "GENERAL", + "abilities": [ + { + "type": "DAMAGE_ENEMY_UNITS_AND_FREEZE_THEM", + "activity_type": "PASSIVE", + "call_type": "ENTRY", + "target_type": "OPPONENT_ALL_CARDS | OPPONENT", + "value": 2, + "effect_type": "MASSIVE_WATER_WAVE", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0.11, + "y": -0.16, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Earth", + "id": 19, + "kind": "CREATURE", + "name": "Rockky", + "cost": 1, + "description": "Attack: +1 damage to Air zombies", + "flavor_text": "Addriaaannn!!! Addriaaaaaannnnn!!!", + "picture": "Rockky", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "MODIFICATOR_STATS", + "activity_type": "passive", + "call_type": "permanent", + "target_type": "none", + "stat_type": "damage", + "set_type": "air", + "value": 1, + "buff_type": "ATTACK" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Earth", + "id": 23, + "kind": "CREATURE", + "name": "Bolderr", + "cost": 3, + "description": "Entry: 1 damage to a zombie", + "flavor_text": "One more step, just one more step!", + "picture": "Bolderr", + "damage": 1, + "health": 2, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "DAMAGE_TARGET", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "player_card|opponent_card", + "value": 1, + "effect_type": "TARGET_ROCK", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Earth", + "id": 17, + "kind": "CREATURE", + "name": "Blocker", + "cost": 1, + "description": "Heavy", + "flavor_text": "Just a few more moments...", + "picture": "Blocker", + "damage": 0, + "health": 3, + "type": "HEAVY", + "rank": "MINION", + "card_view_info": { + "position": { + "x": -0.6, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Earth", + "id": 18, + "kind": "CREATURE", + "name": "Slab", + "cost": 3, + "description": "", + "flavor_text": "Supressing all those emotions does have it's price...", + "picture": "Slab", + "damage": 3, + "health": 4, + "type": "WALKER", + "rank": "MINION", + "card_view_info": { + "position": { + "x": 0, + "y": 0.1, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Earth", + "id": 22, + "kind": "CREATURE", + "name": "Pit", + "cost": 1, + "description": "Heavy, Entry: Add a Tainted Goo to your Hand", + "flavor_text": "Hard to save every drop with all the spillage", + "picture": "pit", + "damage": 0, + "health": 2, + "type": "HEAVY", + "rank": "MINION", + "abilities": [ + { + "type": "ADD_CARD_BY_NAME_TO_HAND", + "activity_type": "passive", + "call_type": "ENTRY", + "name": "Tainted Goo", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.07, + "y": 0.1, + "z": 0 + }, + "scale": { + "x": 0.55, + "y": 0.55, + "z": 0.55 + } + } + }, + { + "set": "Earth", + "id": 22, + "kind": "CREATURE", + "name": "Golem", + "cost": 4, + "description": "Heavy", + "flavor_text": "mmMMWhaaaaat?", + "picture": "Golem", + "damage": 2, + "health": 6, + "type": "HEAVY", + "rank": "OFFICER", + "card_view_info": { + "position": { + "x": -0.62, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.55, + "y": 0.55, + "z": 0.55 + } + } + }, + { + "set": "Earth", + "id": 20, + "kind": "CREATURE", + "name": "Walley", + "cost": 4, + "description": "Entry: Adjacent zombies get Heavy", + "flavor_text": "Eeeeeeva", + "picture": "Walley", + "damage": 2, + "health": 2, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "ADJACENT_UNITS_GET_HEAVY", + "activity_type": "passive", + "call_type": "ENTRY", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Earth", + "id": 21, + "kind": "CREATURE", + "name": "Tiny", + "cost": 4, + "description": "Heavy", + "flavor_text": "Cooookie... just one more cooookie...", + "picture": "Tiny", + "damage": 0, + "health": 7, + "type": "HEAVY", + "rank": "OFFICER", + "card_view_info": { + "position": { + "x": -0.15, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Earth", + "id": 22, + "kind": "CREATURE", + "name": "Spiker", + "cost": 3, + "description": "Heavy, Attack: +1 damage to Heavy zombies", + "flavor_text": "Standing really still... maybe they won't notice", + "picture": "Spiker", + "damage": 2, + "health": 3, + "type": "HEAVY", + "rank": "OFFICER", + "abilities": [ + { + "type": "ADDITIONAL_DAMAGE_TO_HEAVY_IN_ATTACK", + "activity_type": "passive", + "call_type": "permanent", + "value": 1, + "buff_type": "ATTACK" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Earth", + "id": 17, + "kind": "CREATURE", + "name": "Crater", + "cost": 3, + "description": "Heavy, Entry: Add a Corrupted Goo to your Hand", + "flavor_text": "Try to veer from his major crater issues... it may goo deeeeep", + "picture": "Crater", + "damage": 1, + "health": 4, + "type": "HEAVY", + "rank": "OFFICER", + "abilities": [ + { + "type": "ADD_CARD_BY_NAME_TO_HAND", + "activity_type": "passive", + "call_type": "ENTRY", + "name": "Corrupted Goo", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Earth", + "id": 24, + "kind": "CREATURE", + "name": "Earthshaker", + "cost": 5, + "description": "Entry: Destroy a Heavy zombie", + "flavor_text": "Will break ALL your WALLS!!", + "picture": "Earthshaker", + "damage": 4, + "health": 4, + "type": "WALKER", + "rank": "COMMANDER", + "abilities": [ + { + "type": "DESTROY_UNIT_BY_TYPE", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "opponent_card|player_card", + "card_type": "HEAVY", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Earth", + "id": 24, + "kind": "CREATURE", + "name": "IgneouZ", + "cost": 4, + "description": "Heavy, Entry: If your Overlord has 10 Def or less, this gets +2 Def", + "flavor_text": "Mmmm, nothing like the smell of fresh cinder and ash in the morning", + "picture": "IgneouZ", + "damage": 3, + "health": 3, + "type": "HEAVY", + "rank": "COMMANDER", + "abilities": [ + { + "type": "TAKE_DEFENSE_IF_OVERLORD_HAS_LESS_DEFENSE_THAN", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 2, + "health": 10, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Earth", + "id": 25, + "kind": "CREATURE", + "name": "Pyrite", + "cost": 5, + "description": "Heavy, Delayed 2: This loses Heavy but gains +4 Atk", + "flavor_text": "Angry enough to go though a WALL!", + "picture": "Pyrite", + "damage": 0, + "health": 8, + "type": "HEAVY", + "rank": "COMMANDER", + "abilities": [ + { + "type": "DELAYED_LOSE_HEAVY_GAIN_ATTACK", + "activity_type": "passive", + "call_type": "TURN", + "value": 4, + "delay": 2, + "buff_type": "DELAYED" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": -0.25, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Earth", + "id": 27, + "kind": "CREATURE", + "name": "Mountain", + "cost": 11, + "description": "Heavy, Swing 4", + "flavor_text": "When the mountain comes to you... you'll run!", + "picture": "Mountain", + "damage": 6, + "health": 8, + "type": "HEAVY", + "rank": "GENERAL", + "abilities": [ + { + "type": "SWING", + "activity_type": "passive", + "call_type": "ATTACK", + "value": 4, + "buff_type": "SWING" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.55, + "y": 0.55, + "z": 0.55 + } + } + }, + { + "set": "Earth", + "id": 26, + "kind": "CREATURE", + "name": "Gaea", + "cost": 11, + "description": "Entry: All ally Earth zombies in play get +1 Atk", + "flavor_text": "Either super charismatic, or super scary... or both", + "picture": "Gaea", + "damage": 4, + "health": 7, + "type": "WALKER", + "rank": "GENERAL", + "abilities": [ + { + "type": "ALLY_UNITS_OF_TYPE_IN_PLAY_GET_STATS", + "activity_type": "passive", + "call_type": "ENTRY", + "set_type": "EARTH", + "health": 0, + "damage": 1, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Air", + "id": 17, + "kind": "CREATURE", + "name": "Whizpar", + "cost": 1, + "description": "Attack: +1 damage to Water zombies", + "flavor_text": "The unfriendly ghost...", + "picture": "Whizpar", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "MODIFICATOR_STATS", + "activity_type": "passive", + "call_type": "permanent", + "target_type": "none", + "stat_type": "damage", + "set_type": "water", + "value": 1, + "buff_type": "ATTACK" + } + ], + "card_view_info": { + "position": { + "x": -0.3, + "y": 0.2, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Air", + "id": 18, + "kind": "CREATURE", + "name": "Wheezy", + "cost": 2, + "description": "Entry: A random card in your Hand gets -1 cost", + "flavor_text": "Ommmmmmmmmmm", + "picture": "Wheezy", + "damage": 1, + "health": 2, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "LOWER_COST_OF_CARD_IN_HAND", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "player_card", + "buff_type": "ENTRY", + "value": -1 + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.7, + "y": 0.7, + "z": 0.7 + } + } + }, + { + "set": "Air", + "id": 19, + "kind": "CREATURE", + "name": "Soothsayer", + "cost": 2, + "description": "Entry: Draw a card", + "flavor_text": "Almost as good as a fortune cookie... minus the cookie", + "picture": "Soothsayer", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "DRAW_CARD", + "activity_type": "passive", + "call_type": "ENTRY", + "set_type": "none", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.62, + "y": 0.62, + "z": 0.62 + } + } + }, + { + "set": "Air", + "id": 17, + "kind": "CREATURE", + "name": "Fumez", + "cost": 2, + "description": "Entry: Add a Tainted Goo to your Hand", + "flavor_text": "RAZENGAAAAAAAA!!!", + "picture": "Fumez", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "ADD_CARD_BY_NAME_TO_HAND", + "activity_type": "passive", + "call_type": "ENTRY", + "name": "Tainted Goo", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Air", + "id": 20, + "kind": "CREATURE", + "name": "Pushhh", + "cost": 3, + "description": "Entry: Return a zombie to its owner's hand", + "flavor_text": "Like any adolescent child that wishes you to leave him be... so GO AWAY!!", + "picture": "Pushhh", + "damage": 3, + "health": 3, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "CARD_RETURN", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "player_card|opponent_card", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.075, + "y": -0.05, + "z": 0 + }, + "scale": { + "x": 0.62, + "y": 0.62, + "z": 0.62 + } + } + }, + { + "set": "Air", + "id": 21, + "kind": "CREATURE", + "name": "Ztormmcaller", + "cost": 5, + "description": "Entry: 1 damage to a zombie, Swing 1", + "flavor_text": "Thor's best student just got a little angrier...", + "picture": "ztormmcaller", + "damage": 3, + "health": 3, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "SWING", + "activity_type": "passive", + "call_type": "ATTACK", + "value": 1, + "buff_type": "SWING" + }, + { + "type": "DAMAGE_TARGET", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "player_card|opponent_card|player|opponent", + "value": 1, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0.075, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Air", + "id": 17, + "kind": "CREATURE", + "name": "Bouncer", + "cost": 4, + "description": "Heavy", + "flavor_text": "From a young age he just loves to bounce things - especially rocks... on other rocks... ", + "picture": "Bouncer", + "damage": 2, + "health": 3, + "type": "HEAVY", + "rank": "OFFICER", + "card_view_info": { + "position": { + "x": -0.45, + "y": -0.12, + "z": 0 + }, + "scale": { + "x": 0.62, + "y": 0.62, + "z": 0.62 + } + } + }, + { + "set": "Air", + "id": 19, + "kind": "CREATURE", + "name": "Gaz", + "cost": 4, + "description": "Guard, Entry: Add a Corrupted Goo to your Hand", + "flavor_text": "No, no, no no, not a hamster, not a hamster ball....", + "picture": "gaz", + "damage": 2, + "health": 2, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "GUARD", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "none", + "buff_type": "GUARD" + }, + { + "type": "ADD_CARD_BY_NAME_TO_HAND", + "activity_type": "passive", + "call_type": "ENTRY", + "name": "Corrupted Goo", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.62, + "y": 0.62, + "z": 0.62 + } + } + }, + { + "set": "Air", + "id": 20, + "kind": "CREATURE", + "name": "Draft", + "cost": 5, + "description": "Entry: Draw a card from the enemy deck", + "flavor_text": "Not your father... hopefully", + "picture": "Draft", + "damage": 4, + "health": 5, + "type": "WALKER", + "rank": "COMMANDER", + "abilities": [ + { + "type": "DRAW_CARD", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "OPPONENT", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.075, + "y": -0.05, + "z": 0 + }, + "scale": { + "x": 0.62, + "y": 0.62, + "z": 0.62 + } + } + }, + { + "set": "Air", + "id": 20, + "kind": "CREATURE", + "name": "MonZoon", + "cost": 9, + "description": "Costs 1 less for each other Air zombie in your hand", + "flavor_text": "Shock therapy does work wonders", + "picture": "MonZoon", + "damage": 6, + "health": 6, + "type": "WALKER", + "rank": "COMMANDER", + "abilities": [ + { + "type": "COSTS_LESS_IF_CARD_TYPE_IN_HAND", + "activity_type": "passive", + "call_type": "IN_HAND", + "target_type": "player", + "set_type": "air", + "buff_type": "PERMANENT", + "value": -1 + } + ], + "card_view_info": { + "position": { + "x": -0.075, + "y": -0.05, + "z": 0 + }, + "scale": { + "x": 0.62, + "y": 0.62, + "z": 0.62 + } + } + }, + { + "set": "Air", + "id": 22, + "kind": "CREATURE", + "name": "Zeuz", + "cost": 11, + "description": "Entry: 3 damage to all enemies", + "flavor_text": "From mount Zolimpus in the sky - fear Ze-might of ZeuZ!", + "picture": "Zeuz", + "damage": 5, + "health": 6, + "type": "WALKER", + "rank": "GENERAL", + "abilities": [ + { + "type": "MASSIVE_DAMAGE", + "activity_type": "PASSIVE", + "call_type": "ENTRY", + "target_type": "OPPONENT_ALL_CARDS | OPPONENT", + "value": 3, + "effect_type": "MASSIVE_LIGHTNING", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0.1, + "y": -0.27, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Air", + "id": 34, + "kind": "CREATURE", + "name": "Ztorm Shield", + "cost": 6, + "description": "Guard, Entry: Give adjacent zombies Guard", + "flavor_text": "A zombie doing ninja hand signs to produce a sphere of wind around it, to protect it from various projectives coming at it.", + "picture": "ZtormShield", + "damage": 4, + "health": 4, + "type": "WALKER", + "rank": "COMMANDER", + "abilities": [ + { + "type": "GUARD", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "none", + "buff_type": "GUARD" + }, + { + "type": "ADJACENT_UNITS_GET_HEAVY", + "activity_type": "passive", + "call_type": "ENTRY", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0.4, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Life", + "id": 23, + "kind": "CREATURE", + "name": "Azuraz", + "cost": 1, + "description": "Attack: +1 damage to Earth zombies", + "flavor_text": "Beeee yourself!", + "picture": "Azuraz", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "MODIFICATOR_STATS", + "activity_type": "passive", + "call_type": "permanent", + "target_type": "none", + "stat_type": "damage", + "set_type": "earth", + "value": 1, + "buff_type": "ATTACK" + } + ], + "card_view_info": { + "position": { + "x": -0.2, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Life", + "id": 24, + "kind": "CREATURE", + "name": "Bloomer", + "cost": 2, + "description": "Entry: Draw a card if you have a Life zombie in play", + "flavor_text": "Fertilizing the flowers on an hourly basis", + "picture": "Bloomer", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "DRAW_CARD", + "activity_type": "passive", + "call_type": "ENTRY", + "set_type": "life", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Life", + "id": 24, + "kind": "CREATURE", + "name": "Zap", + "cost": 2, + "description": "Overflow 3, Entry: Summon a 1/1 enemy zombie minion", + "flavor_text": "Can't get enough of that goo, ever", + "picture": "zap", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "OVERFLOW_GOO", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 3, + "buff_type": "OVERFLOW" + }, + { + "type": "SUMMON", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "opponent", + "count": 1, + "name": "Zombie 1/1", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Life", + "id": 25, + "kind": "CREATURE", + "name": "Shroom", + "cost": 4, + "description": "Entry: 2 damage to a zombie", + "flavor_text": "Some like to grow flowers, others grow hallucinogenic poison mushrooms...", + "picture": "Shroom", + "damage": 4, + "health": 2, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "DAMAGE_TARGET", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "player_card|opponent_card", + "value": 2, + "effect_type": "TARGET_LIFE", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0.35, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Life", + "id": 27, + "kind": "CREATURE", + "name": "Vindrom", + "cost": 4, + "description": "Attack: Freeze zombie", + "flavor_text": "BDSM much?!", + "picture": "Vindrom", + "damage": 2, + "health": 3, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "STUN", + "activity_type": "passive", + "call_type": "ATTACK", + "target_type": "opponent_card|opponent", + "value": 1, + "buff_type": "ATTACK" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0.1, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Life", + "id": 26, + "kind": "CREATURE", + "name": "Puffer", + "cost": 3, + "description": "Entry: +1 Atk to all Life zombies in play", + "flavor_text": "All the pretty pretty flowers", + "picture": "Puffer", + "damage": 2, + "health": 2, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "CHANGE_STAT_OF_CREATURES_BY_TYPE", + "activity_type": "passive", + "call_type": "PERMANENT", + "target_type": "player_card", + "value": 1, + "stat_type": "DAMAGE", + "set_type": "LIFE", + "effect_type": "TARGET_LIFE", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Life", + "id": 27, + "kind": "CREATURE", + "name": "Sapper", + "cost": 4, + "description": "Attack: Restore 1 Def for each damage this deals.", + "flavor_text": "Hungry, always so very hungry", + "picture": "Sapper", + "damage": 2, + "health": 4, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "GAIN_NUMBER_OF_LIFE_FOR_EACH_DAMAGE_THIS_DEALS", + "activity_type": "passive", + "call_type": "ATTACK", + "value": 1, + "buff_type": "ATTACK" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Life", + "id": 27, + "kind": "CREATURE", + "name": "Keeper", + "cost": 3, + "description": "Entry: Summon a 1/1 Feral zombie minion", + "flavor_text": "They are usually such lovely beasts...", + "picture": "Keeper", + "damage": 1, + "health": 3, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "SUMMON", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "player", + "count": 1, + "name": "Zombie Feral", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Life", + "id": 27, + "kind": "CREATURE", + "name": "Cactuz", + "cost": 4, + "description": "Overflow 6, Entry: Summon a 2/2 enemy zombie", + "flavor_text": "And so he walked the desert for 40 years, only to find he's been walking in circles....", + "picture": "Cactuz", + "damage": 2, + "health": 2, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "OVERFLOW_GOO", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 6, + "buff_type": "OVERFLOW" + }, + { + "type": "SUMMON", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "opponent", + "count": 1, + "name": "Zombie 2/2", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Life", + "id": 28, + "kind": "CREATURE", + "name": "Shammann", + "cost": 11, + "description": "Turn: Summon a 1/1 zombie", + "flavor_text": "Dancing around a fire alone is a hoot, but bringing all your dead friends to join is a party!", + "picture": "Shammann", + "damage": 5, + "health": 6, + "type": "WALKER", + "rank": "GENERAL", + "abilities": [ + { + "type": "SUMMON", + "activity_type": "passive", + "call_type": "TURN", + "target_type": "player", + "count": 1, + "name": "Zombie 1/1", + "buff_type": "TURN" + } + ], + "card_view_info": { + "position": { + "x": -0.05, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Life", + "id": 29, + "kind": "CREATURE", + "name": "Z-Virus", + "cost": 12, + "description": "Devour all ally zombies, gain their Atk and Def", + "flavor_text": "There ain't no party like a Z-Virus party!", + "picture": "Z-Virus", + "damage": 0, + "health": 0, + "type": "WALKER", + "rank": "GENERAL", + "abilities": [ + { + "type": "DEVOUR_ZOMBIES_AND_COMBINE_STATS", + "activity_type": "active", + "call_type": "ENTRY", + "value": -1, + "buff_type": "DEVOUR" + } + ], + "card_view_info": { + "position": { + "x": -0.05, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Life", + "id": 27, + "kind": "CREATURE", + "name": "Yggdrazil", + "cost": 11, + "description": "Entry: Reanimate all Life zombies that died this match", + "flavor_text": "In this case, lots of strings attached!!", + "picture": "Yggdrazil", + "damage": 4, + "health": 5, + "type": "WALKER", + "rank": "GENERAL", + "abilities": [ + { + "type": "REVIVE_DIED_UNITS_OF_TYPE_FROM_MATCH", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "opponent_card|player_card", + "set_type": "LIFE", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Toxic", + "id": 30, + "kind": "CREATURE", + "name": "Poizom", + "cost": 1, + "description": "Attack: +1 damage to Life zombies", + "flavor_text": "Just like any frat boy, after the Friday night bash - bloated, gassy, puking and generally unpleasant to be around...", + "picture": "Poizom", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "MODIFICATOR_STATS", + "activity_type": "passive", + "call_type": "permanent", + "target_type": "none", + "stat_type": "damage", + "set_type": "life", + "value": 1, + "buff_type": "ATTACK" + } + ], + "card_view_info": { + "position": { + "x": 0.15, + "y": 0.1, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Toxic", + "id": 32, + "kind": "CREATURE", + "name": "Hazmaz", + "cost": 2, + "description": "Feral", + "flavor_text": "Being cooped up inside a plastic suit is no fun - now time this by a 1,000 with all the extra gases, something's gotta give...", + "picture": "Hazmaz", + "damage": 1, + "health": 2, + "type": "FERAL", + "rank": "MINION", + "abilities": [], + "card_view_info": { + "position": { + "x": -0.4, + "y": 0.125, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Toxic", + "id": 30, + "kind": "CREATURE", + "name": "Zpitter", + "cost": 3, + "description": "Entry: 1 damage to a random enemy", + "flavor_text": "Lamma in my living room... bam ba balalam babam ba ba...", + "picture": "Zpitter", + "damage": 2, + "health": 2, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "TAKE_DAMAGE_RANDOM_ENEMY", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "OPPONENT_CARD|OPPONENT", + "value": 1, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Toxic", + "id": 30, + "kind": "CREATURE", + "name": "Zeptic", + "cost": 1, + "description": "Overflow 2, Deal 2 damage to your Overlord", + "flavor_text": "After four steps he gave up on the straight light and started puking", + "picture": "Zeptic", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "OVERFLOW_GOO", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 2, + "buff_type": "OVERFLOW" + }, + { + "type": "ATTACK_OVERLORD", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "player", + "value": 2, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Toxic", + "id": 31, + "kind": "CREATURE", + "name": "Ghoul", + "cost": 2, + "description": "Attack: -1 Atk", + "flavor_text": "Being dead has its perks, but in this case time and humidity has not been kind - the rotting flesh is literally sapping off the bone on this one", + "picture": "Ghoul", + "damage": 3, + "health": 2, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "CHANGE_STAT", + "activity_type": "passive", + "call_type": "ATTACK", + "target_type": "none", + "stat_type": "damage", + "value": -1, + "buff_type": "ATTACK" + } + ], + "card_view_info": { + "position": { + "x": -0.2, + "y": 0.1, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Toxic", + "id": 32, + "kind": "CREATURE", + "name": "Zeeter", + "cost": 5, + "description": "Entry: Devour Atk/Def an ally zombie", + "flavor_text": "Nam, naam nam nam namm nam...", + "picture": "Zeeter", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "DEVOUR_ZOMBIES_AND_COMBINE_STATS", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "PLAYER_CARD", + "value": 1, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.4, + "y": 0.125, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Toxic", + "id": 32, + "kind": "CREATURE", + "name": "Hazzard", + "cost": 5, + "description": "Overflow 7, Deal 4 damage to your Overlord", + "flavor_text": "Almost reached the Goo-Anonymous meeting - almost...", + "picture": "Hazzard", + "damage": 4, + "health": 4, + "type": "WALKER", + "rank": "OFFICER", + "abilities": [ + { + "type": "OVERFLOW_GOO", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 7, + "buff_type": "OVERFLOW" + }, + { + "type": "ATTACK_OVERLORD", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "player", + "value": 4, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Toxic", + "id": 32, + "kind": "CREATURE", + "name": "Zludge", + "cost": 5, + "description": "Rage: +2 Atk", + "flavor_text": "Bring it, bring It, BRING IT ON!!!", + "picture": "Zludge", + "damage": 4, + "health": 4, + "type": "WALKER", + "rank": "COMMANDER", + "abilities": [ + { + "type": "RAGE", + "activity_type": "passive", + "call_type": "GOT_DAMAGE", + "value": 2, + "buff_type": "RAGE" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Toxic", + "id": 30, + "kind": "CREATURE", + "name": "Ectoplasm", + "cost": 1, + "description": "Entry: Lose 1 goo bottle", + "flavor_text": "Wha'ch yu lookin at' ?! ", + "picture": "Ectoplasm", + "damage": 2, + "health": 2, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "LOSE_GOO", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 1, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0, + "y": 0.1, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Toxic", + "id": 33, + "kind": "CREATURE", + "name": "Cherno-bill", + "cost": 11, + "description": "Heavy, Death: 3 damage to all zombies", + "flavor_text": "Lumbering around in a world made of butter gets old real fast, maybe that's why he's sooo angry!", + "picture": "Cherno-bill", + "damage": 7, + "health": 9, + "type": "HEAVY", + "rank": "GENERAL", + "abilities": [ + { + "type": "MASSIVE_DAMAGE", + "activity_type": "PASSIVE", + "call_type": "DEATH", + "target_type": "PLAYER_ALL_CARDS|OPPONENT_ALL_CARDS", + "value": 3, + "effect_type": "MASSIVE_TOXIC_ALL", + "buff_type": "DEATH" + } + ], + "card_view_info": { + "position": { + "x": -0.1, + "y": -0.2, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Toxic", + "id": 33, + "kind": "CREATURE", + "name": "GooZilla", + "cost": 8, + "description": "Entry: Return 4 goo, and use all your goo for 2X Atk/Def", + "flavor_text": "More, more, MORE GOO! Bring me ALL the GOO", + "picture": "GooZilla", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "GENERAL", + "abilities": [ + { + "type": "OVERFLOW_GOO", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 4, + "buff_type": "ENTRY" + }, + { + "type": "USE_ALL_GOO_TO_INCREASE_STATS", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 2, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0.4, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Toxic", + "id": 34, + "kind": "CREATURE", + "name": "Zlopper", + "cost": 7, + "description": "+1 Atk to all ally Toxic zombies", + "flavor_text": "A frail zombie with one massive arm that he's dragging on the floor.", + "picture": "Zlopper", + "damage": 3, + "health": 5, + "type": "WALKER", + "rank": "COMMANDER", + "abilities": [ + { + "type": "CHANGE_STAT_OF_CREATURES_BY_TYPE", + "activity_type": "passive", + "call_type": "PERMANENT", + "target_type": "player_card", + "value": 1, + "stat_type": "DAMAGE", + "set_type": "TOXIC", + "effect_type": "TARGET_TOXIC", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0.4, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Item", + "id": 30, + "kind": "SPELL", + "name": "Chainsaw", + "cost": 4, + "description": "+4 Attack to zombie; End: 4 damage to this zombie", + "flavor_text": "Cutting through flesh, bone and even steel, it's easy to see why this is a fan-favorite!", + "picture": "Chainsaw", + "damage": 0, + "health": 0, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "UNIT_WEAPON", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "player_card|opponent_card", + "value": 4, + "damage": 4, + "buff_type": "END" + } + ], + "card_view_info": { + "position": { + "x": -0.2, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.55, + "y": 0.55, + "z": 0.55 + } + } + }, + { + "set": "Item", + "id": 30, + "kind": "SPELL", + "name": "Goo Beaker", + "cost": 2, + "description": "Get 1 empty goo vial", + "flavor_text": "So much goo, so little space", + "picture": "goobeaker", + "damage": 0, + "health": 0, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "ADD_GOO_VIAL", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "none", + "value": 1, + "buff_type": "ENTRY", + "count": 1 + } + ], + "card_view_info": { + "position": { + "x": -0.2, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.55, + "y": 0.55, + "z": 0.55 + } + } + }, + { + "set": "Item", + "id": 34, + "kind": "SPELL", + "name": "Stapler", + "cost": 4, + "description": "Restore 4 Def to a zombie", + "flavor_text": "No pain, no gain.", + "picture": "Stapler", + "damage": 0, + "health": 0, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "heal", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "player_card|opponent_card", + "value": 4, + "effect_type": "HEAL", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.2, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.55, + "y": 0.55, + "z": 0.55 + } + } + }, + { + "set": "Item", + "id": 35, + "kind": "SPELL", + "name": "Nail Bomb", + "cost": 4, + "description": "Deal 4 damage to zombie and adjacent zombies", + "flavor_text": "When you really want to nail it!", + "picture": "NailBomb", + "damage": 0, + "health": 0, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "DAMAGE_TARGET_ADJUSTMENTS", + "activity_type": "active", + "call_type": "ENTRY", + "target_type": "player_card|opponent_card", + "value": 4, + "effect_type": "TARGET_ADJUSTMENTS_BOMB", + "buff_type": "SWING" + } + ], + "card_view_info": { + "position": { + "x": -0.2, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.55, + "y": 0.55, + "z": 0.55 + } + } + }, + { + "set": "Item", + "id": 36, + "kind": "SPELL", + "name": "Goo Bottles", + "cost": 4, + "description": "Get 2 empty goo vials", + "flavor_text": "Adding more goo to an already overly-goo-ed party is just too goo-d!", + "picture": "goobottles", + "damage": 0, + "health": 0, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "ADD_GOO_VIAL", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "none", + "value": 2, + "buff_type": "ENTRY", + "count": 2 + } + ], + "card_view_info": { + "position": { + "x": -0.2, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.55, + "y": 0.55, + "z": 0.55 + } + } + }, + { + "set": "Item", + "id": 30, + "kind": "SPELL", + "name": "Fresh Meat", + "cost": 5, + "description": "Entry: All enemy zombies get -3 Atk until the end of turn", + "flavor_text": "As if they died again and went to zombie heaven", + "picture": "FreshMeat", + "damage": 0, + "health": 0, + "type": "WALKER", + "rank": "MINION", + "abilities": [ + { + "type": "CHANGE_STAT_UNTILL_END_OF_TURN", + "activity_type": "passive", + "call_type": "ENTRY", + "target_type": "opponent_all_cards", + "damage": -3, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.2, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.55, + "y": 0.55, + "z": 0.55 + } + } + }, + { + "set": "Others", + "id": 100, + "kind": "CREATURE", + "name": "Zombie 1/1", + "cost": 1, + "description": "", + "picture": "Zombie", + "damage": 1, + "health": 1, + "type": "WALKER", + "rank": "MINION", + "card_view_info": { + "position": { + "x": -0.45, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Others", + "id": 101, + "kind": "CREATURE", + "name": "Zombie 2/2", + "cost": 1, + "description": "", + "picture": "Zombie", + "damage": 2, + "health": 2, + "type": "WALKER", + "rank": "MINION", + "card_view_info": { + "position": { + "x": -0.45, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Others", + "id": 102, + "kind": "CREATURE", + "name": "Zombie Feral", + "cost": 1, + "description": "", + "picture": "Zombie", + "damage": 1, + "health": 1, + "type": "FERAL", + "rank": "MINION", + "card_view_info": { + "position": { + "x": -0.45, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Others", + "id": 30, + "kind": "SPELL", + "name": "Tainted Goo", + "cost": 2, + "description": "Overflow 3, disables 1 goo vial for next turn", + "flavor_text": "Smells kinda funny, but what a rush!", + "picture": "taintedgoo", + "damage": 0, + "health": 0, + "type": "WALKER", + "rank": "MINION", + "frame": "frame_item_minion", + "abilities": [ + { + "type": "OVERFLOW_GOO", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 3, + "buff_type": "OVERFLOW" + }, + { + "type": "DISABLE_NEXT_TURN_GOO", + "activity_type": "passive", + "call_type": "ENTRY", + "value": -1, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.2, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.55, + "y": 0.55, + "z": 0.55 + } + } + }, + { + "set": "Others", + "id": 30, + "kind": "SPELL", + "name": "Corrupted Goo", + "cost": 4, + "description": "Overflow 6, disables 2 goo vials for next turn", + "flavor_text": "Hooooweeee, better than all the moonshine!", + "picture": "corruptedgoo", + "damage": 0, + "health": 0, + "type": "WALKER", + "rank": "MINION", + "frame": "frame_item_minion", + "abilities": [ + { + "type": "OVERFLOW_GOO", + "activity_type": "passive", + "call_type": "ENTRY", + "value": 6, + "buff_type": "OVERFLOW" + }, + { + "type": "DISABLE_NEXT_TURN_GOO", + "activity_type": "passive", + "call_type": "ENTRY", + "value": -2, + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": -0.2, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.55, + "y": 0.55, + "z": 0.55 + } + } + }, + { + "set": "Others", + "id": 34, + "kind": "CREATURE", + "name": "Rainz", + "cost": 6, + "description": "Entry: Restore 10 Def randomly split among allies", + "flavor_text": "A zombie wearing the typical yellow raincoat, looking up to the sky, with its hands outstretched to the sky, and goo is raining around it. Use a worm's eye view angle to show the goo falling from the sky more clearly.", + "picture": "Rainz", + "damage": 3, + "health": 4, + "type": "WALKER", + "rank": "COMMANDER", + "abilities": [ + { + "type": "REPLACE_UNITS_WITH_TYPE_ON_STRONGER_ONES", + "activity_type": "PASSIVE", + "call_type": "ENTRY", + "target_type": "PLAYER_CARD", + "set_type": "WATER", + "effect_type": "MASSIVE_WATER_WAVE", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0.4, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Others", + "id": 34, + "kind": "CREATURE", + "name": "Blight", + "cost": 6, + "description": "Delayed 3: Place two 4/4 copies of this zombie in play then Destroy this", + "flavor_text": "Show a bunch of plants, with blooming flowers, dripping with goo. 2 flowers however have not yet bloomed. They are still closed and inside the buds you can see a transulcent pod containing a life zombie embryo.", + "picture": "Blight", + "damage": 5, + "health": 4, + "type": "WALKER", + "rank": "COMMANDER", + "abilities": [], + "card_view_info": { + "position": { + "x": 0.4, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Others", + "id": 34, + "kind": "CREATURE", + "name": "Zteroid", + "cost": 6, + "description": "Death: All ally zombies in play get +2 Atk until end of turn", + "flavor_text": "A muscular zombie with a hump on its back. A transparent membrane on the hump shows that it's full of goo. (like a camel)", + "picture": "Zteroid", + "damage": 5, + "health": 4, + "type": "WALKER", + "rank": "COMMANDER", + "abilities": [], + "card_view_info": { + "position": { + "x": 0.4, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Others", + "id": 34, + "kind": "CREATURE", + "name": "BurZt", + "cost": 3, + "description": "Feral, Entry: Cannot attack the enemy Overlord", + "flavor_text": "A zombie holidng the head of another zombie from behind with both hands. The zombie in front is set ablaze, and screams in agony.", + "picture": "BurZt", + "damage": 4, + "health": 1, + "type": "FERAL", + "rank": "MINION", + "abilities": [], + "card_view_info": { + "position": { + "x": 0.4, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Others", + "id": 34, + "kind": "CREATURE", + "name": "Vortex", + "cost": 11, + "description": "Entry: Replace ally water zombies in play with stronger ones", + "flavor_text": "A water zombie carrying another zombie over its head, lion king style, about to throw it into a violent whirlpool.", + "picture": "Vortex", + "damage": 6, + "health": 7, + "type": "WALKER", + "rank": "GENERAL", + "abilities": [ + { + "type": "REPLACE_UNITS_WITH_TYPE_ON_STRONGER_ONES", + "activity_type": "PASSIVE", + "call_type": "ENTRY", + "target_type": "PLAYER_CARD", + "set_type": "WATER", + "effect_type": "MASSIVE_WATER_WAVE", + "buff_type": "ENTRY" + } + ], + "card_view_info": { + "position": { + "x": 0.4, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + }, + { + "set": "Others", + "id": 34, + "kind": "CREATURE", + "name": "Defender", + "cost": 8, + "description": "Entry: Give ally Earth zombies that cost 2 or less Heavy", + "flavor_text": "A rock zombie using itself as a human shield to protect another zombie from that looks like fireballs being flung at them.", + "picture": "Defender", + "damage": 4, + "health": 6, + "type": "WALKER", + "rank": "MINION", + "abilities": [], + "card_view_info": { + "position": { + "x": 0.4, + "y": 0, + "z": 0 + }, + "scale": { + "x": 0.6, + "y": 0.6, + "z": 0.6 + } + } + } + ] + } \ No newline at end of file diff --git a/battleground/zombie_battleground_test.go b/battleground/zombie_battleground_test.go index 1331620e..77f47d16 100644 --- a/battleground/zombie_battleground_test.go +++ b/battleground/zombie_battleground_test.go @@ -196,6 +196,210 @@ var initRequest = zb.InitRequest{ }, } +var updateInitRequest = zb.UpdateInitRequest{ + Version: "v2", + DefaultCollection: []*zb.CardCollection{ + { + CardName: "Banshee", + Amount: 4, + }, + { + CardName: "Breezee", + Amount: 3, + }, + { + CardName: "Buffer", + Amount: 5, + }, + { + CardName: "Soothsayer", + Amount: 4, + }, + { + CardName: "Wheezy", + Amount: 3, + }, + { + CardName: "Whiffer", + Amount: 5, + }, + { + CardName: "Whizpar", + Amount: 4, + }, + { + CardName: "Zhocker", + Amount: 3, + }, + { + CardName: "Bouncer", + Amount: 5, + }, + { + CardName: "Dragger", + Amount: 4, + }, + { + CardName: "Guzt", + Amount: 3, + }, + { + CardName: "Pushhh", + Amount: 5, + }, + }, + Heroes: []*zb.Hero{ + { + HeroId: 0, + Experience: 0, + Level: 1, + Skills: []*zb.Skill{{ + Title: "Attack", + Skill: "Skill0", + SkillTargets: "zb.Skill_ALL_CARDS|zb.Skill_PLAYER_CARD", + Value: 1, + }}, + }, + { + HeroId: 1, + Experience: 0, + Level: 2, + Skills: []*zb.Skill{{ + Title: "Deffence", + Skill: "Skill1", + SkillTargets: "zb.Skill_PLAYER|zb.Skill_OPPONENT_CARD", + Value: 2, + }}, + }, + }, + Cards: []*zb.Card{ + { + Id: 1, + Set: "Air", + Name: "Banshee", + Rank: "Minion", + Type: "Feral", + Damage: 2, + Health: 1, + Cost: 2, + Ability: "Feral", + Effects: []*zb.Effect{ + { + Trigger: "entry", + Effect: "feral", + Duration: "permanent", + Target: "self", + }, + }, + CardViewInfo: &zb.CardViewInfo{ + Position: &zb.Coordinates{ + X: 1.5, + Y: 2.5, + Z: 3.5, + }, + Scale: &zb.Coordinates{ + X: 0.5, + Y: 0.5, + Z: 0.5, + }, + }, + }, + { + Id: 2, + Set: "Air", + Name: "Breezee", + Rank: "Minion", + Type: "Walker", + Damage: 1, + Health: 1, + Cost: 1, + Ability: "-", + Effects: []*zb.Effect{ + { + Trigger: "death", + Effect: "attack_strength_buff", + Target: "friendly_selectable", + }, + }, + }, + { + Id: 3, + Set: "Air", + Name: "NewCard", + Rank: "Minion", + Type: "Walker", + Damage: 1, + Health: 1, + Cost: 1, + Ability: "-", + Effects: []*zb.Effect{ + { + Trigger: "death", + Effect: "attack_strength_buff", + Target: "friendly_selectable", + }, + }, + }, + }, + DefaultDecks: []*zb.Deck{ + { + Id: 0, + HeroId: 2, + Name: "Default", + Cards: []*zb.CardCollection{ + { + CardName: "Banshee", + Amount: 2, + }, + { + CardName: "Breezee", + Amount: 2, + }, + { + CardName: "Buffer", + Amount: 2, + }, + { + CardName: "Soothsayer", + Amount: 2, + }, + { + CardName: "Wheezy", + Amount: 2, + }, + { + CardName: "Whiffer", + Amount: 2, + }, + { + CardName: "Whizpar", + Amount: 1, + }, + { + CardName: "Zhocker", + Amount: 1, + }, + { + CardName: "Bouncer", + Amount: 1, + }, + { + CardName: "Dragger", + Amount: 1, + }, + { + CardName: "Guzt", + Amount: 1, + }, + { + CardName: "Pushhh", + Amount: 1, + }, + }, + }, + }, +} + func setup(c *ZombieBattleground, pubKeyHex string, addr *loom.Address, ctx *contract.Context, t *testing.T) { c = &ZombieBattleground{} @@ -563,7 +767,9 @@ func TestCardOperations(t *testing.T) { setup(c, pubKeyHexString, &addr, &ctx, t) t.Run("ListCard", func(t *testing.T) { - cardResponse, err := c.ListCardLibrary(ctx, &zb.ListCardLibraryRequest{}) + cardResponse, err := c.ListCardLibrary(ctx, &zb.ListCardLibraryRequest{ + Version: "v1", + }) assert.Nil(t, err) assert.Equal(t, 2, len(cardResponse.Sets[0].Cards)) @@ -670,5 +876,16 @@ func TestHeroOperations(t *testing.T) { } func TestUpdateInitDataOperations(t *testing.T) { + var c *ZombieBattleground + var pubKeyHexString = "3866f776276246e4f9998aa90632931d89b0d3a5930e804e02299533f55b39e1" + var addr loom.Address + var ctx contract.Context + + setup(c, pubKeyHexString, &addr, &ctx, t) + t.Run("UpdateInit", func(t *testing.T) { + err := c.UpdateInit(ctx, &updateInitRequest) + + assert.Nil(t, err) + }) } diff --git a/zb.genesis.json b/zb.genesis.json index 171d213c..2b16091e 100644 --- a/zb.genesis.json +++ b/zb.genesis.json @@ -6,6 +6,7 @@ "name": "ZombieBattleground", "location": "zombiebattleground:1.0.0", "init": { + "version" : "v1", "default_collection": [ { "card_name": "Pyromaz", From 8329d4b068b02cef0a055fc73513d89d8bae49fd Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Mon, 24 Sep 2018 14:14:31 +0530 Subject: [PATCH 08/13] add version to list hero library --- battleground/zombie_battleground.go | 2 +- battleground/zombie_battleground_test.go | 3 +++ cli/cmd/list_hero.go | 4 ++++ types/zb/zb.proto | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/battleground/zombie_battleground.go b/battleground/zombie_battleground.go index 73724db8..274e6b37 100644 --- a/battleground/zombie_battleground.go +++ b/battleground/zombie_battleground.go @@ -407,7 +407,7 @@ func (z *ZombieBattleground) ListCardLibrary(ctx contract.StaticContext, req *zb func (z *ZombieBattleground) ListHeroLibrary(ctx contract.StaticContext, req *zb.ListHeroLibraryRequest) (*zb.ListHeroLibraryResponse, error) { var heroList zb.HeroList - if err := ctx.Get(heroListKey, &heroList); err != nil { + if err := ctx.Get(MakeVersionedKey(req.Version, heroListKey), &heroList); err != nil { return nil, err } return &zb.ListHeroLibraryResponse{Heroes: heroList.Heroes}, nil diff --git a/battleground/zombie_battleground_test.go b/battleground/zombie_battleground_test.go index 77f47d16..094a37db 100644 --- a/battleground/zombie_battleground_test.go +++ b/battleground/zombie_battleground_test.go @@ -888,4 +888,7 @@ func TestUpdateInitDataOperations(t *testing.T) { assert.Nil(t, err) }) + + // ??: test with list cards also? + } diff --git a/cli/cmd/list_hero.go b/cli/cmd/list_hero.go index 8ad7eb9a..5c98059b 100644 --- a/cli/cmd/list_hero.go +++ b/cli/cmd/list_hero.go @@ -17,6 +17,10 @@ var listHeroForUserCmd = &cobra.Command{ Use: "list_hero", Short: "list hero for user", RunE: func(cmd *cobra.Command, args []string) error { + if rootCmdArgs.version == "" { + return fmt.Errorf("version not specified") + } + signer := auth.NewEd25519Signer(commonTxObjs.privateKey) callerAddr := loom.Address{ ChainID: commonTxObjs.rpcClient.GetChainID(), diff --git a/types/zb/zb.proto b/types/zb/zb.proto index ffe42c79..4c554d72 100644 --- a/types/zb/zb.proto +++ b/types/zb/zb.proto @@ -285,6 +285,7 @@ message ListCardLibraryResponse { } message ListHeroLibraryRequest { + string version = 1; } message ListHeroLibraryResponse { From 916559a8bad099c956e09720f0fefaad405aca1c Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Mon, 24 Sep 2018 15:18:40 +0530 Subject: [PATCH 09/13] add version to specific commands and some minor changes --- battleground/zombie_battleground.go | 28 +++++++++++++--------------- cli/cmd/create_account.go | 12 ++++++++++-- cli/cmd/list_card.go | 9 +++++++-- cli/cmd/list_hero.go | 4 ---- cli/cmd/root.go | 2 -- cli/cmd/update_init.go | 8 +++++--- types/zb/zb.proto | 1 + 7 files changed, 36 insertions(+), 28 deletions(-) diff --git a/battleground/zombie_battleground.go b/battleground/zombie_battleground.go index 274e6b37..4c0d3d63 100644 --- a/battleground/zombie_battleground.go +++ b/battleground/zombie_battleground.go @@ -22,27 +22,26 @@ func (z *ZombieBattleground) Meta() (plugin.Meta, error) { } func (z *ZombieBattleground) Init(ctx contract.Context, req *zb.InitRequest) error { - version := req.Version // initialize card library cardList := zb.CardList{ Cards: req.Cards, } - if err := ctx.Set(MakeVersionedKey(version, cardListKey), &cardList); err != nil { + if err := ctx.Set(MakeVersionedKey(req.Version, cardListKey), &cardList); err != nil { return err } // initialize heros heroList := zb.HeroList{ Heroes: req.Heroes, } - if err := ctx.Set(MakeVersionedKey(version, heroListKey), &heroList); err != nil { + if err := ctx.Set(MakeVersionedKey(req.Version, heroListKey), &heroList); err != nil { return err } cardCollectionList := zb.CardCollectionList{ Cards: req.DefaultCollection, } - if err := ctx.Set(MakeVersionedKey(version, defaultCollectionKey), &cardCollectionList); err != nil { + if err := ctx.Set(MakeVersionedKey(req.Version, defaultCollectionKey), &cardCollectionList); err != nil { return err } @@ -50,14 +49,14 @@ func (z *ZombieBattleground) Init(ctx contract.Context, req *zb.InitRequest) err deckList := zb.DeckList{ Decks: req.DefaultDecks, } - if err := ctx.Set(MakeVersionedKey(version, defaultDeckKey), &deckList); err != nil { + if err := ctx.Set(MakeVersionedKey(req.Version, defaultDeckKey), &deckList); err != nil { return err } defaultHeroList := zb.HeroList{ Heroes: req.Heroes, } - if err := ctx.Set(MakeVersionedKey(version, defaultHeroesKey), &defaultHeroList); err != nil { + if err := ctx.Set(MakeVersionedKey(req.Version, defaultHeroesKey), &defaultHeroList); err != nil { return err } @@ -65,27 +64,26 @@ func (z *ZombieBattleground) Init(ctx contract.Context, req *zb.InitRequest) err } func (z *ZombieBattleground) UpdateInit(ctx contract.Context, req *zb.UpdateInitRequest) error { - version := req.Version // initialize card library cardList := zb.CardList{ Cards: req.Cards, } - if err := ctx.Set(MakeVersionedKey(version, cardListKey), &cardList); err != nil { + if err := ctx.Set(MakeVersionedKey(req.Version, cardListKey), &cardList); err != nil { return err } // initialize heros heroList := zb.HeroList{ Heroes: req.Heroes, } - if err := ctx.Set(MakeVersionedKey(version, heroListKey), &heroList); err != nil { + if err := ctx.Set(MakeVersionedKey(req.Version, heroListKey), &heroList); err != nil { return err } cardCollectionList := zb.CardCollectionList{ Cards: req.DefaultCollection, } - if err := ctx.Set(MakeVersionedKey(version, defaultCollectionKey), &cardCollectionList); err != nil { + if err := ctx.Set(MakeVersionedKey(req.Version, defaultCollectionKey), &cardCollectionList); err != nil { return err } @@ -93,14 +91,14 @@ func (z *ZombieBattleground) UpdateInit(ctx contract.Context, req *zb.UpdateInit deckList := zb.DeckList{ Decks: req.DefaultDecks, } - if err := ctx.Set(MakeVersionedKey(version, defaultDeckKey), &deckList); err != nil { + if err := ctx.Set(MakeVersionedKey(req.Version, defaultDeckKey), &deckList); err != nil { return err } defaultHeroList := zb.HeroList{ Heroes: req.Heroes, } - if err := ctx.Set(MakeVersionedKey(version, defaultHeroesKey), &defaultHeroList); err != nil { + if err := ctx.Set(MakeVersionedKey(req.Version, defaultHeroesKey), &defaultHeroList); err != nil { return err } @@ -159,7 +157,7 @@ func (z *ZombieBattleground) CreateAccount(ctx contract.Context, req *zb.UpsertA // add default collection list var collectionList zb.CardCollectionList - if err := ctx.Get(defaultCollectionKey, &collectionList); err != nil { + if err := ctx.Get(MakeVersionedKey(req.Version, defaultCollectionKey), &collectionList); err != nil { return errors.Wrapf(err, "unable to get default collectionlist") } if err := ctx.Set(CardCollectionKey(req.UserId), &collectionList); err != nil { @@ -167,7 +165,7 @@ func (z *ZombieBattleground) CreateAccount(ctx contract.Context, req *zb.UpsertA } var deckList zb.DeckList - if err := ctx.Get(defaultDeckKey, &deckList); err != nil { + if err := ctx.Get(MakeVersionedKey(req.Version, defaultDeckKey), &deckList); err != nil { return errors.Wrapf(err, "unable to get default decks") } // update default deck with none-zero id @@ -179,7 +177,7 @@ func (z *ZombieBattleground) CreateAccount(ctx contract.Context, req *zb.UpsertA } var heroes zb.HeroList - if err := ctx.Get(defaultHeroesKey, &heroes); err != nil { + if err := ctx.Get(MakeVersionedKey(req.Version, defaultHeroesKey), &heroes); err != nil { return errors.Wrapf(err, "unable to get default hero") } if err := ctx.Set(HeroesKey(req.UserId), &heroes); err != nil { diff --git a/cli/cmd/create_account.go b/cli/cmd/create_account.go index e87618a0..75b977f3 100644 --- a/cli/cmd/create_account.go +++ b/cli/cmd/create_account.go @@ -10,8 +10,9 @@ import ( ) var createAccCmdArgs struct { - userID string - value string + userID string + value string + version string } var createAccountCmd = &cobra.Command{ @@ -21,11 +22,16 @@ var createAccountCmd = &cobra.Command{ signer := auth.NewEd25519Signer(commonTxObjs.privateKey) var accountData zb.UpsertAccountRequest + if createAccCmdArgs.version == "" { + return fmt.Errorf("version not specified") + } + if err := json.Unmarshal([]byte(createAccCmdArgs.value), &accountData); err != nil { return fmt.Errorf("invalid JSON passed in value field. Error: %s", err.Error()) } accountData.UserId = createAccCmdArgs.userID + accountData.Version = createAccCmdArgs.version _, err := commonTxObjs.contract.Call("CreateAccount", &accountData, signer, nil) if err != nil { @@ -42,4 +48,6 @@ func init() { createAccountCmd.Flags().StringVarP(&createAccCmdArgs.userID, "userId", "u", "loom", "UserId of account") createAccountCmd.Flags().StringVarP(&createAccCmdArgs.value, "value", "v", "{\"image\":\"Image\", \"game_membership_tier\": 1}", "Account data in serialized json format") + createAccountCmd.Flags().StringVarP(&createAccCmdArgs.version, "version", "v", "", "Version") + } diff --git a/cli/cmd/list_card.go b/cli/cmd/list_card.go index 8d870a41..aeacdc50 100644 --- a/cli/cmd/list_card.go +++ b/cli/cmd/list_card.go @@ -9,12 +9,16 @@ import ( "github.com/spf13/cobra" ) +var listCardCmdArgs struct { + version string +} + var listCardCmd = &cobra.Command{ Use: "list_card", Short: "list card", RunE: func(cmd *cobra.Command, args []string) error { - if rootCmdArgs.version == "" { + if listCardCmdArgs.version == "" { return fmt.Errorf("version not specified") } @@ -27,7 +31,7 @@ var listCardCmd = &cobra.Command{ req := zb.ListCardLibraryRequest{} result := zb.ListCardLibraryResponse{} - req.Version = rootCmdArgs.version + req.Version = listCardCmdArgs.version _, err := commonTxObjs.contract.StaticCall("ListCardLibrary", &req, callerAddr, &result) if err != nil { @@ -45,4 +49,5 @@ var listCardCmd = &cobra.Command{ func init() { rootCmd.AddCommand(listCardCmd) + listCardCmd.Flags().StringVarP(&listCardCmdArgs.version, "version", "v", "", "Version") } diff --git a/cli/cmd/list_hero.go b/cli/cmd/list_hero.go index 5c98059b..8ad7eb9a 100644 --- a/cli/cmd/list_hero.go +++ b/cli/cmd/list_hero.go @@ -17,10 +17,6 @@ var listHeroForUserCmd = &cobra.Command{ Use: "list_hero", Short: "list hero for user", RunE: func(cmd *cobra.Command, args []string) error { - if rootCmdArgs.version == "" { - return fmt.Errorf("version not specified") - } - signer := auth.NewEd25519Signer(commonTxObjs.privateKey) callerAddr := loom.Address{ ChainID: commonTxObjs.rpcClient.GetChainID(), diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 1c1e8688..bc3dd2f8 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -13,7 +13,6 @@ var rootCmdArgs struct { privateKeyFilePath string readURI string writeURI string - version string } var commonTxObjs struct { @@ -78,7 +77,6 @@ func Execute() error { rootCmd.PersistentFlags().StringVarP(&rootCmdArgs.privateKeyFilePath, "key", "k", "priv.key", "Private key file path") rootCmd.PersistentFlags().StringVarP(&rootCmdArgs.readURI, "readURI", "r", "http://localhost:46658/query", "Read URI for rpc") rootCmd.PersistentFlags().StringVarP(&rootCmdArgs.writeURI, "writeURI", "w", "http://localhost:46658/rpc", "Write URI for rpc") - rootCmd.PersistentFlags().StringVarP(&rootCmdArgs.version, "version", "v", "", "Version") return rootCmd.Execute() } diff --git a/cli/cmd/update_init.go b/cli/cmd/update_init.go index 05211650..54bd86cb 100644 --- a/cli/cmd/update_init.go +++ b/cli/cmd/update_init.go @@ -12,7 +12,8 @@ import ( ) var updateInitCmdArgs struct { - file string + version string + file string } var updateInitCmd = &cobra.Command{ @@ -35,11 +36,11 @@ var updateInitCmd = &cobra.Command{ return fmt.Errorf("invalid JSON passed in data field. Error: %s", err.Error()) } - if rootCmdArgs.version == "" { + if updateInitCmdArgs.version == "" { return fmt.Errorf("version not specified") } - updateInitData.Version = rootCmdArgs.version + updateInitData.Version = updateInitCmdArgs.version _, err = commonTxObjs.contract.Call("UpdateInit", &updateInitData, signer, nil) if err != nil { return fmt.Errorf("error encountered while calling UpdateInit: %s", err.Error()) @@ -53,5 +54,6 @@ var updateInitCmd = &cobra.Command{ func init() { rootCmd.AddCommand(updateInitCmd) + updateInitCmd.Flags().StringVarP(&updateInitCmdArgs.version, "version", "v", "", "UserId of account") updateInitCmd.Flags().StringVarP(&updateInitCmdArgs.file, "file", "f", "", "File of init data to be updated in serialized json format") } diff --git a/types/zb/zb.proto b/types/zb/zb.proto index 4c554d72..ce4a90ff 100644 --- a/types/zb/zb.proto +++ b/types/zb/zb.proto @@ -225,6 +225,7 @@ message UpsertAccountRequest { int64 elo_score = 7; int32 current_tier = 8; int32 game_membership_tier = 9; + string version = 10; } message GetAccountRequest { From 287b311d78a06a54b687d49db72af61b02e3919b Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Mon, 24 Sep 2018 15:37:01 +0530 Subject: [PATCH 10/13] add version to create account test --- battleground/storage.go | 4 ++-- battleground/zombie_battleground_test.go | 20 +++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/battleground/storage.go b/battleground/storage.go index 8f1c6450..da7c4b1b 100644 --- a/battleground/storage.go +++ b/battleground/storage.go @@ -102,9 +102,9 @@ func saveCardList(ctx contract.Context, cardList *zb.CardList) error { return nil } -func loadCardList(ctx contract.StaticContext) (*zb.CardList, error) { +func loadCardList(ctx contract.StaticContext, version string) (*zb.CardList, error) { var cl zb.CardList - err := ctx.Get(cardListKey, &cl) + err := ctx.Get(MakeVersionedKey(version, cardListKey), &cl) if err != nil { return nil, err } diff --git a/battleground/zombie_battleground_test.go b/battleground/zombie_battleground_test.go index 094a37db..e24a1b3d 100644 --- a/battleground/zombie_battleground_test.go +++ b/battleground/zombie_battleground_test.go @@ -12,6 +12,7 @@ import ( ) var initRequest = zb.InitRequest{ + Version: "v1", DefaultCollection: []*zb.CardCollection{ { CardName: "Banshee", @@ -430,8 +431,9 @@ func TestAccountOperations(t *testing.T) { setup(c, pubKeyHexString, &addr, &ctx, t) setupAccount(c, ctx, &zb.UpsertAccountRequest{ - UserId: "AccountUser", - Image: "PathToImage", + UserId: "AccountUser", + Image: "PathToImage", + Version: "v1", }, t) t.Run("UpdateAccount", func(t *testing.T) { @@ -463,8 +465,9 @@ func TestCardCollectionOperations(t *testing.T) { setup(c, pubKeyHexString, &addr, &ctx, t) setupAccount(c, ctx, &zb.UpsertAccountRequest{ - UserId: "CardUser", - Image: "PathToImage", + UserId: "CardUser", + Image: "PathToImage", + Version: "v1", }, t) cardCollection, err := c.GetCollection(ctx, &zb.GetCollectionRequest{ @@ -483,8 +486,9 @@ func TestDeckOperations(t *testing.T) { setup(c, pubKeyHexString, &addr, &ctx, t) setupAccount(c, ctx, &zb.UpsertAccountRequest{ - UserId: "DeckUser", - Image: "PathToImage", + UserId: "DeckUser", + Image: "PathToImage", + Version: "v1", }, t) t.Run("ListDecks", func(t *testing.T) { @@ -776,7 +780,9 @@ func TestCardOperations(t *testing.T) { }) t.Run("ListHeroLibrary", func(t *testing.T) { - heroResponse, err := c.ListHeroLibrary(ctx, &zb.ListHeroLibraryRequest{}) + heroResponse, err := c.ListHeroLibrary(ctx, &zb.ListHeroLibraryRequest{ + Version: "v1", + }) assert.Nil(t, err) assert.Equal(t, 2, len(heroResponse.Heroes)) From 5f29dd570e1823e2b720419478c23c0c04b6c6cc Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Mon, 24 Sep 2018 16:23:59 +0530 Subject: [PATCH 11/13] fix test --- battleground/zombie_battleground_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/battleground/zombie_battleground_test.go b/battleground/zombie_battleground_test.go index e24a1b3d..e92bf1b2 100644 --- a/battleground/zombie_battleground_test.go +++ b/battleground/zombie_battleground_test.go @@ -797,8 +797,9 @@ func TestHeroOperations(t *testing.T) { setup(c, pubKeyHexString, &addr, &ctx, t) setupAccount(c, ctx, &zb.UpsertAccountRequest{ - UserId: "HeroUser", - Image: "PathToImage", + UserId: "HeroUser", + Image: "PathToImage", + Version: "v1", }, t) t.Run("ListHeroes", func(t *testing.T) { From 4d00ee8643212fe35e6529f8826da68955eb1b9c Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Mon, 24 Sep 2018 16:39:22 +0530 Subject: [PATCH 12/13] update e2e tests to use version --- cli/cmd/update_init.go | 2 +- e2e/test_account.toml | 2 +- e2e/test_deck.toml | 2 +- e2e/test_hero.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/cmd/update_init.go b/cli/cmd/update_init.go index 54bd86cb..5b51f950 100644 --- a/cli/cmd/update_init.go +++ b/cli/cmd/update_init.go @@ -33,7 +33,7 @@ var updateInitCmd = &cobra.Command{ } if err := json.Unmarshal(f, &updateInitData); err != nil { - return fmt.Errorf("invalid JSON passed in data field. Error: %s", err.Error()) + return fmt.Errorf("error parsing JSON file: %s", err.Error()) } if updateInitCmdArgs.version == "" { diff --git a/e2e/test_account.toml b/e2e/test_account.toml index 13da2f44..a77f7f2b 100644 --- a/e2e/test_account.toml +++ b/e2e/test_account.toml @@ -1,5 +1,5 @@ [[TestCases]] - RunCmd = "zb-cli create_account -k {{index $.AccountPrivKeyPathList 0}} -u loom" + RunCmd = "zb-cli create_account -k {{index $.AccountPrivKeyPathList 0}} -u loom -v v1" Condition = "contains" Expected = ["created successfully"] diff --git a/e2e/test_deck.toml b/e2e/test_deck.toml index 5e4159d1..0d5776bb 100644 --- a/e2e/test_deck.toml +++ b/e2e/test_deck.toml @@ -1,5 +1,5 @@ [[TestCases]] - RunCmd = "zb-cli create_account -k {{index $.AccountPrivKeyPathList 0}} -u loom" + RunCmd = "zb-cli create_account -k {{index $.AccountPrivKeyPathList 0}} -u loom -v v1" Condition = "contains" Expected = ["created successfully"] diff --git a/e2e/test_hero.toml b/e2e/test_hero.toml index 611ea32f..1fb049f3 100644 --- a/e2e/test_hero.toml +++ b/e2e/test_hero.toml @@ -1,5 +1,5 @@ [[TestCases]] - RunCmd = "zb-cli create_account -k {{index $.AccountPrivKeyPathList 0}} -u loom" + RunCmd = "zb-cli create_account -k {{index $.AccountPrivKeyPathList 0}} -u loom -v v1" Condition = "contains" Expected = ["created successfully"] From 14eb7a57c96982020e6843d626b77b397f8ef1b5 Mon Sep 17 00:00:00 2001 From: Siddhant Mutha Date: Mon, 24 Sep 2018 16:54:08 +0530 Subject: [PATCH 13/13] change `value` to `data` in create_account --- cli/cmd/create_account.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/cmd/create_account.go b/cli/cmd/create_account.go index 75b977f3..fe4a5c23 100644 --- a/cli/cmd/create_account.go +++ b/cli/cmd/create_account.go @@ -11,7 +11,7 @@ import ( var createAccCmdArgs struct { userID string - value string + data string version string } @@ -26,8 +26,8 @@ var createAccountCmd = &cobra.Command{ return fmt.Errorf("version not specified") } - if err := json.Unmarshal([]byte(createAccCmdArgs.value), &accountData); err != nil { - return fmt.Errorf("invalid JSON passed in value field. Error: %s", err.Error()) + if err := json.Unmarshal([]byte(createAccCmdArgs.data), &accountData); err != nil { + return fmt.Errorf("invalid JSON passed in data field. Error: %s", err.Error()) } accountData.UserId = createAccCmdArgs.userID @@ -47,7 +47,7 @@ func init() { rootCmd.AddCommand(createAccountCmd) createAccountCmd.Flags().StringVarP(&createAccCmdArgs.userID, "userId", "u", "loom", "UserId of account") - createAccountCmd.Flags().StringVarP(&createAccCmdArgs.value, "value", "v", "{\"image\":\"Image\", \"game_membership_tier\": 1}", "Account data in serialized json format") + createAccountCmd.Flags().StringVarP(&createAccCmdArgs.data, "data", "d", "{\"image\":\"Image\", \"game_membership_tier\": 1}", "Account data in serialized json format") createAccountCmd.Flags().StringVarP(&createAccCmdArgs.version, "version", "v", "", "Version") }