ascension 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.lre +1 -0
- data/.rspec +1 -0
- data/Gemfile +37 -0
- data/Gemfile.lock +128 -0
- data/Guardfile +27 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +75 -0
- data/VERSION +1 -0
- data/ascension.gemspec +129 -0
- data/lib/ascension.rb +209 -0
- data/lib/ascension/Ascension-statistics_v1.csv +49 -0
- data/lib/ascension/ability.rb +222 -0
- data/lib/ascension/card.rb +133 -0
- data/lib/ascension/cards.csv +49 -0
- data/lib/ascension/cards.rb +206 -0
- data/lib/ascension/cards2.csv +49 -0
- data/lib/ascension/events.rb +73 -0
- data/lib/ascension/parse.rb +283 -0
- data/lib/ascension/pool.rb +49 -0
- data/lib/ascension/run.rb +27 -0
- data/lib/ascension/setup_rchoice.rb +11 -0
- data/lib/ascension/to_json.rb +74 -0
- data/lib/ascension/turn_manager.rb +14 -0
- data/notes.txt +2 -0
- data/spec/card_spec.rb +87 -0
- data/spec/center_spec.rb +25 -0
- data/spec/choice_instance_spec.rb +97 -0
- data/spec/main_spec.rb +413 -0
- data/spec/parse_spec.rb +225 -0
- data/spec/spec_helper.rb +73 -0
- data/vol/dmp.json +556 -0
- data/vol/dmp2.json +1 -0
- data/vol/find_by_id.rb +22 -0
- data/vol/game.json +1 -0
- data/vol/game_pp.json +614 -0
- data/vol/test_persist.rb +44 -0
- data/web/main.rb +83 -0
- metadata +377 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
module Card
|
2
|
+
module HonorEarned
|
3
|
+
attr_accessor :honor_earned
|
4
|
+
def honor_earned=(h)
|
5
|
+
@honor_earned = h
|
6
|
+
self.abilities << Ability::EarnHonor.new(:honor => h)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def dummy
|
12
|
+
Base.new(:name => "Dummy")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Base
|
17
|
+
include FromHash
|
18
|
+
include HonorEarned
|
19
|
+
|
20
|
+
setup_mongo_persist :realm, :name, :card_id
|
21
|
+
|
22
|
+
attr_accessor :realm
|
23
|
+
|
24
|
+
# abilities are things that happen when a card is put into play or defeated
|
25
|
+
# abilities can be conditional on whether other things have already happened
|
26
|
+
fattr(:abilities) { [] }
|
27
|
+
|
28
|
+
# triggers are things than happen when external events occur.
|
29
|
+
fattr(:triggers) { [] }
|
30
|
+
|
31
|
+
fattr(:card_id) { rand(10000000000000) }
|
32
|
+
|
33
|
+
attr_accessor :name
|
34
|
+
def apply_abilities(side)
|
35
|
+
if playing_on_command_line?
|
36
|
+
abilities.each { |a| a.call(side) }
|
37
|
+
else
|
38
|
+
abilities.each do |a|
|
39
|
+
if a.respond_to?(:choice_instance)
|
40
|
+
a.choice_instance(side).save!
|
41
|
+
else
|
42
|
+
a.call(side)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
def apply_triggers(event, side)
|
48
|
+
triggers.each { |a| a.call(event, side) }
|
49
|
+
end
|
50
|
+
|
51
|
+
def monster?; kind_of?(Monster); end
|
52
|
+
def hero?; kind_of?(Hero); end
|
53
|
+
def construct?; kind_of?(Construct); end
|
54
|
+
|
55
|
+
def to_s
|
56
|
+
name
|
57
|
+
end
|
58
|
+
|
59
|
+
def basic_card?
|
60
|
+
["Heavy Infantry","Mystic","Cultist","Apprentice","Militia","Standin"].include?(name)
|
61
|
+
end
|
62
|
+
|
63
|
+
def hydrated
|
64
|
+
return self if basic_card?
|
65
|
+
res = Parse.get(name).clone
|
66
|
+
res.card_id = card_id
|
67
|
+
res
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
class Purchaseable < Base
|
74
|
+
setup_mongo_persist :realm, :name, :runes, :power, :rune_cost, :card_id
|
75
|
+
|
76
|
+
fattr(:runes) { 0 }
|
77
|
+
fattr(:power) { 0 }
|
78
|
+
attr_accessor :rune_cost
|
79
|
+
def mechana?
|
80
|
+
realm == :mechana
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class Hero < Purchaseable
|
85
|
+
class << self
|
86
|
+
def apprentice
|
87
|
+
new(:runes => 1, :name => "Apprentice")
|
88
|
+
end
|
89
|
+
def mystic
|
90
|
+
new(:runes => 2, :name => 'Mystic', :rune_cost => 3)
|
91
|
+
end
|
92
|
+
def militia
|
93
|
+
new(:power => 1, :name => 'Militia')
|
94
|
+
end
|
95
|
+
def heavy_infantry
|
96
|
+
new(:power => 2, :name => "Heavy Infantry", :rune_cost => 2)
|
97
|
+
end
|
98
|
+
def standin
|
99
|
+
new(:rune_cost => 2, :name => "Standin")
|
100
|
+
end
|
101
|
+
def arha
|
102
|
+
new(:rune_cost => 1, :name => "Arha Initiate").tap do |h|
|
103
|
+
h.abilities << Ability::Draw.new
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class Construct < Purchaseable
|
110
|
+
class << self
|
111
|
+
def shadow_star
|
112
|
+
new(:power => 1)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class Monster < Base
|
118
|
+
attr_accessor :power_cost
|
119
|
+
setup_mongo_persist :realm, :name, :power_cost, :card_id
|
120
|
+
fattr(:runes) { 0 }
|
121
|
+
class << self
|
122
|
+
def cultist
|
123
|
+
new(:power_cost => 2, :name => "Cultist", :honor_earned => 1)
|
124
|
+
end
|
125
|
+
def cultist_standin
|
126
|
+
new(:power_cost => 2, :name => "Cultist Standin", :honor_earned => 1)
|
127
|
+
end
|
128
|
+
def cultist_standin2
|
129
|
+
new(:power_cost => 2, :name => "Cultist Standin2", :honor_earned => 1)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
"Realm Short","Card Type","Name","count","rune_cost","power_cost","honor","runes","honor","power","+C","draw","banish_center","banish_hand","banish_discard","banish_hand_discard","discard_from_hand","special_abilities","triggerable_ability","undefined"
|
2
|
+
"V","H","Void Initiate",3,1,,1,1,,,1,,,,,"o1",,,,
|
3
|
+
"V","H","Spike Vixen",2,2,,1,,,1,1,1,,,,,,,,
|
4
|
+
"V","H","Shade ot Black Watch",3,3,,1,,,2,1,,,,,"o1",,,,
|
5
|
+
"V","C","Shadow Star",2,3,,2,,,1,,,,,,,,,,
|
6
|
+
"V","H","Arbiter of the Precipice",2,4,,1,,,,02/01/11,2,,1,,,,,,
|
7
|
+
"V","H","Demon Slayer",2,4,,2,,,3,,,,,,,,,,
|
8
|
+
"V","C","Void Thirster",2,5,,3,,"1 on first_center_monster_killed",1,,,,,,,,,,
|
9
|
+
"V","H","Emeri One with the Void",1,6,,3,,,4,,,,,,,,,,
|
10
|
+
"V","C","Muramasa",1,7,,4,,,3,,,,,,,,,,
|
11
|
+
"E","H","Arha Initiate",3,1,,1,,,,1,1,,,,,,,,
|
12
|
+
"E","H","Temple Librarian",3,2,,1,,,,-2,2,,,,,1,,,
|
13
|
+
"E","H","Seer of the Forked Path",3,2,,1,,,,1,1,"o1",,,,,,,
|
14
|
+
"E","H","Twofold Askara",1,4,,2,,,,,,,,,,,"copy_hero",,
|
15
|
+
"E","H","Arha Templar",2,4,,3,,,,,,,,,,,"kill_monster_4",,
|
16
|
+
"E","H","Ascetic of the Lidless Eye",2,5,,2,,,,2,2,,,,,,,,
|
17
|
+
"E","C","Tablet of Times Dawn",1,5,,2,,,,,,,,,,,,,
|
18
|
+
"E","C","The All Seeing Eye",1,6,,2,,,,1,,,,,,,,"draw_1",
|
19
|
+
"E","H","Oziah the Peerless",1,6,,3,,,,,,,,,,,"kill_monster_6",,
|
20
|
+
"E","H","Master Dhartha",1,7,,3,,,,3,3,,,,,,,,
|
21
|
+
"L","H","Lifeblood Initiate",3,1,,1,1,1,,,,,,,,,,,
|
22
|
+
"L","H","Wolf Shaman",3,3,,1,1,,,1,1,,,,,,,,
|
23
|
+
"L","H","Runic Lycanthrope",2,3,,1,2,,"2 if lifebound_hero_played",,,,,,,,,,
|
24
|
+
"L","C","Yggdrasil Staff",2,4,,2,,,1,,,,,,,,,"4_rune_to_3_honor",
|
25
|
+
"L","H","Druids ot Stone Circle",2,4,,3,,,,,,,,,,,"acquire_hero_3",,
|
26
|
+
"L","C","Snapdragon",2,5,,2,1,"1 on first_lifebound_hero_played",,,,,,,,,,,
|
27
|
+
"L","H","Flytrap Witch",2,5,,2,,2,,1,1,,,,,,,,
|
28
|
+
"L","H","Landtalker",1,6,,3,3,,,,,,,,,,,,
|
29
|
+
"L","H","Cetra Weaver ot Stars",1,7,,4,,,,,,,,,,,"acquire_hero_10",,
|
30
|
+
"M","H","Mechana Initiate",3,1,,1,,,,,,,,,,,"power_or_rune_1",,
|
31
|
+
"M","H","Kor the Ferromancer",1,3,,2,,,2,-1,"1 if 2_or_more_constructs",,,,,,,,
|
32
|
+
"M","C","Burrower Mk II",2,3,,3,,,,-1,"1 on mechana_construct_played",,,,,,,,
|
33
|
+
"M","H","Avatar Golem",2,4,,2,,"1 foreach type_of_construct",2,,,,,,,,,,
|
34
|
+
"M","H","Reactor Monk",2,4,,2,"2, 1 for construct",,,,,,,,,,,,
|
35
|
+
"M","C","Rocket Courier X-99",2,4,,4,,,,,,,,,,,,,"something"
|
36
|
+
"M","C","Watchmaker Altar",2,5,,5,"1 for mechana",,,,,,,,,,,,
|
37
|
+
"M","C","The Grand Design",2,6,,6,"2 for mechana",,,,,,,,,,,,
|
38
|
+
"M","C","Hedron Link Device",1,7,,7,,,,,,,,,,,,,"all_mechana"
|
39
|
+
"M","C","Hedron Cannon",1,8,,8,,,,,,,,,,,,"power_for_mechana",
|
40
|
+
"S","M","Samael's Trickster",4,,3,,1,1,,,,,,,,,,,
|
41
|
+
"S","M","Tormented Soul",3,,3,,,1,,1,,,,,,,,,
|
42
|
+
"S","M","Mephit",3,,3,,,2,,,,"o1",,,,,,,
|
43
|
+
"S","M","Corrosive Widow",4,,4,,,3,,,,,,,,,"discard_construct",,
|
44
|
+
"S","M","Mistake of Creation",4,,4,,,4,,1,,"o1",,"o1",,,,,
|
45
|
+
"S","M","Wind Tyrant",3,,5,,3,3,,,,,,,,,,,
|
46
|
+
"S","M","Sea Tyrant",3,,5,,,5,,,,,,,,,"discard_all_but_one_construct",,
|
47
|
+
"S","M","Earth Tyrant",2,,6,,,5,,2,2,,,,,,,,
|
48
|
+
"S","M","Xeron Duke of Lies",1,,6,,,3,,,,,,,,,"take_opponents_card",,
|
49
|
+
"S","M","Avatar ot Fallen",1,,7,,,4,,,,,,,,,"acquire_center",,
|
@@ -0,0 +1,206 @@
|
|
1
|
+
class Cards
|
2
|
+
include FromHash
|
3
|
+
include Enumerable
|
4
|
+
setup_mongo_persist :cards
|
5
|
+
attr_accessor :side, :game
|
6
|
+
fattr(:game) { side.game }
|
7
|
+
fattr(:cards) { [] }
|
8
|
+
def <<(c)
|
9
|
+
cards << c
|
10
|
+
end
|
11
|
+
def remove(c)
|
12
|
+
raise "#{c} not here" unless cards.include?(c)
|
13
|
+
self.cards -= [c]
|
14
|
+
end
|
15
|
+
def each(&b)
|
16
|
+
cards.each(&b)
|
17
|
+
end
|
18
|
+
def shuffle!
|
19
|
+
self.cards = cards.sort_by { |x| rand() }
|
20
|
+
end
|
21
|
+
def empty?
|
22
|
+
size == 0
|
23
|
+
end
|
24
|
+
def size
|
25
|
+
cards.size
|
26
|
+
end
|
27
|
+
def first
|
28
|
+
cards.first
|
29
|
+
end
|
30
|
+
def pop
|
31
|
+
cards.pop
|
32
|
+
end
|
33
|
+
def index(obj)
|
34
|
+
cards.index(obj)
|
35
|
+
end
|
36
|
+
def clear!
|
37
|
+
self.cards = []
|
38
|
+
end
|
39
|
+
def include?(c)
|
40
|
+
cards.include?(c)
|
41
|
+
end
|
42
|
+
def banish(card)
|
43
|
+
remove(card)
|
44
|
+
game.void << card
|
45
|
+
end
|
46
|
+
def []=(i,card)
|
47
|
+
cards[i] = card
|
48
|
+
end
|
49
|
+
def [](i)
|
50
|
+
cards[i]
|
51
|
+
end
|
52
|
+
def to_s_cards
|
53
|
+
map { |x| x.name }.join(" | ")
|
54
|
+
end
|
55
|
+
def get_one(name)
|
56
|
+
res = find { |x| x.name == name }
|
57
|
+
raise "couldn't find #{name}" unless res
|
58
|
+
self.cards -= [res]
|
59
|
+
res
|
60
|
+
end
|
61
|
+
def hydrate!
|
62
|
+
self.cards = map { |x| x.hydrated }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Discard < Cards; end
|
67
|
+
|
68
|
+
class PlayerDeck < Cards
|
69
|
+
def draw_one
|
70
|
+
fill_from_discard! if empty?
|
71
|
+
cards.pop
|
72
|
+
end
|
73
|
+
def fill_from_discard!
|
74
|
+
self.cards = side.discard.cards
|
75
|
+
side.discard.cards = []
|
76
|
+
shuffle!
|
77
|
+
end
|
78
|
+
def self.starting(ops={})
|
79
|
+
res = new(ops)
|
80
|
+
8.times { res << Card::Hero.apprentice }
|
81
|
+
2.times { res << Card::Hero.militia }
|
82
|
+
res.shuffle!
|
83
|
+
res
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class Hand < Cards
|
88
|
+
def play_all!
|
89
|
+
while size > 0
|
90
|
+
side.play(first)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
def discard!
|
94
|
+
each { |c| side.discard << c }
|
95
|
+
clear!
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class Played < Cards
|
100
|
+
setup_mongo_persist :cards, :pool
|
101
|
+
fattr(:pool) { Pool.new }
|
102
|
+
def apply(card)
|
103
|
+
pool.runes += card.runes
|
104
|
+
pool.power += card.power
|
105
|
+
card.apply_abilities(side)
|
106
|
+
end
|
107
|
+
def <<(card)
|
108
|
+
super
|
109
|
+
apply(card)
|
110
|
+
|
111
|
+
side.fire_event(Event::CardPlayed.new(:card => card))
|
112
|
+
|
113
|
+
if card.kind_of?(Card::Construct)
|
114
|
+
remove(card)
|
115
|
+
side.constructs << card
|
116
|
+
end
|
117
|
+
end
|
118
|
+
def discard!
|
119
|
+
each { |c| side.discard << c }
|
120
|
+
clear!
|
121
|
+
self.pool!
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class Void < Cards; end
|
126
|
+
|
127
|
+
module Selectable
|
128
|
+
def engageable_cards(side)
|
129
|
+
select { |x| can?(x,side) }
|
130
|
+
end
|
131
|
+
def can?(card,side)
|
132
|
+
if card.monster?
|
133
|
+
raise card.name unless card.power_cost
|
134
|
+
side.played.pool.power >= card.power_cost
|
135
|
+
else
|
136
|
+
side.played.pool.can_purchase?(card)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class Center < Cards
|
142
|
+
def fill!
|
143
|
+
(0...size).each do |i|
|
144
|
+
if self[i].name == 'Dummy'
|
145
|
+
self[i] = game.deck.pop
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
while size < 6
|
150
|
+
self << game.deck.pop
|
151
|
+
end
|
152
|
+
end
|
153
|
+
def remove(c)
|
154
|
+
raise "#{c} not here" unless include?(c)
|
155
|
+
i = index(c)
|
156
|
+
self[i] = Card.dummy
|
157
|
+
fill!
|
158
|
+
end
|
159
|
+
def banish(card)
|
160
|
+
super
|
161
|
+
fill!
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
class CenterWithConstants < Cards
|
166
|
+
attr_accessor :game
|
167
|
+
include FromHash
|
168
|
+
include Selectable
|
169
|
+
fattr(:constant_cards) do
|
170
|
+
[Card::Hero.mystic,Card::Hero.heavy_infantry,Card::Monster.cultist]
|
171
|
+
end
|
172
|
+
def cards
|
173
|
+
game.center.cards + constant_cards
|
174
|
+
end
|
175
|
+
def size
|
176
|
+
cards.size
|
177
|
+
end
|
178
|
+
def remove(card)
|
179
|
+
return nil if constant_cards.map { |x| x.name }.include?(card.name)
|
180
|
+
game.center.remove(card)
|
181
|
+
end
|
182
|
+
def method_missing(sym,*args,&b)
|
183
|
+
game.center.send(sym,*args,&b)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
class CenterDeck < Cards
|
188
|
+
class << self
|
189
|
+
def starting
|
190
|
+
res = new
|
191
|
+
Parse::InputFile.new.cards.each { |c| res << c }
|
192
|
+
res.shuffle!
|
193
|
+
res
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
class Constructs < Cards
|
199
|
+
def apply!
|
200
|
+
each { |c| side.played.apply(c) }
|
201
|
+
end
|
202
|
+
def discard(card)
|
203
|
+
remove(card)
|
204
|
+
side.discard << card
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
"Realm Short","Card Type","Name","count","rune_cost","honor","runes","honor","power","+C","draw","banish_center","banish_hand","banish_discard","banish_hand_discard","discard_from_hand","special_ability","triggerable_ability","undefined"
|
2
|
+
"V","H","Void Initiate",3,1,1,1,,,"(-1)",,,,,"o1",,,,
|
3
|
+
"V","H","Spike Vixen",2,2,1,,,1,1,1,,,,,,,,
|
4
|
+
"V","H","Shade ot Black Watch",3,3,1,,,2,"(-1)",,,,,"o1",,,,
|
5
|
+
"V","C","Shadow Star",2,3,2,,,1,,,,,,,,,,
|
6
|
+
"V","H","Arbiter ot Precipice",2,4,1,,,,"2-1",2,,1,,,,,,
|
7
|
+
"V","H","Demon Slayer",2,4,2,,,3,,,,,,,,,,
|
8
|
+
"V","C","Void Thirster",2,5,3,,"1 on first_center_monster_killed","1",,,,,,,,,,
|
9
|
+
"V","H","Emeri One with the Void",1,6,3,,,4,,,,,,,,,,
|
10
|
+
"V","C","Muramasa",1,7,4,,,3,,,,,,,,,,
|
11
|
+
"E","H","Arha Initiate",3,1,1,,,,1,1,,,,,,,,
|
12
|
+
"E","H","Temple Librarian",3,2,1,,,,"(2)",2,,,,,1,,,
|
13
|
+
"E","H","Seer ot Forked Path",3,2,1,,,,1,1,"o1",,,,,,,
|
14
|
+
"E","H","Twofold Askara",1,4,2,,,,,,,,,,,"copy_hero",,
|
15
|
+
"E","H","Arha Templar",2,4,3,,,,,,,,,,,"kill_monster_4",,
|
16
|
+
"E","H","Ascetic ot Lidless Eye",2,5,2,,,,2,2,,,,,,,,
|
17
|
+
"E","C","Tablet of Times Dawn",1,5,2,,,,,,,,,,,,,
|
18
|
+
"E","C","The All Seeing Eye",1,6,2,,,,1,,,,,,,,"draw_1",
|
19
|
+
"E","H","Oziah the Peerless",1,6,3,,,,,,,,,,,"kill_monster_6",,
|
20
|
+
"E","H","Master Dhartha",1,7,3,,,,3,3,,,,,,,,
|
21
|
+
"L","H","Lifeblood Initiate",3,1,1,1,1,,,,,,,,,,,
|
22
|
+
"L","H","Wolf Shaman",3,3,1,1,,,1,1,,,,,,,,
|
23
|
+
"L","H","Runic Lycanthrope",2,3,1,2,,"2 if lifebound_hero_played",,,,,,,,,,
|
24
|
+
"L","C","Yggdrasil Staff",2,4,2,,,"1",,,,,,,,,"4_rune_to_3_honor",
|
25
|
+
"L","H","Druids ot Stone Circle",2,4,3,,,,,,,,,,,"acquire_hero_3",,
|
26
|
+
"L","C","Snapdragon",2,5,2,1,"1 on first_lifebound_hero_played",,,,,,,,,,,
|
27
|
+
"L","H","Flytrap Witch",2,5,2,,2,,1,1,,,,,,,,
|
28
|
+
"L","H","Landtalker",1,6,3,3,,,,,,,,,,,,
|
29
|
+
"L","H","Cetra Weaver ot Stars",1,7,4,,,,,,,,,,,"acquire_hero_10",,
|
30
|
+
"M","H","Mechana Initiate",3,1,1,,,,,,,,,,,"power_or_rune_1",,
|
31
|
+
"M","H","Kor the Ferromancer",1,3,2,,,2,"(1)","1 if 2_or_more_constructs",,,,,,,,
|
32
|
+
"M","C","Burrower Mk II",2,3,3,,,,"(1)","1 on mechana_construct_played",,,,,,,,
|
33
|
+
"M","H","Avatar Golem",2,4,2,,"1 foreach type_of_construct","2",,,,,,,,,,
|
34
|
+
"M","H","Reactor Monk",2,4,2,"2, 1 for construct",,,,,,,,,,,,
|
35
|
+
"M","C","Rocket Courier X-99",2,4,4,,,,,,,,,,,,,"something"
|
36
|
+
"M","C","Watchmaker Altar",2,5,5,"1 for mechana",,,,,,,,,,,,
|
37
|
+
"M","C","The Grand Deisgn",2,6,6,"2 for mechana",,,,,,,,,,,,
|
38
|
+
"M","C","Hedron Link Device",1,7,7,,,,,,,,,,,,,"all_mechana"
|
39
|
+
"M","C","Hedron Cannon",1,8,8,,,,,,,,,,,,"power_for_mechana",
|
40
|
+
"S","M","Samael's Trickster",4,"3P","-",1,1,,,,,,,,,,,
|
41
|
+
"S","M","Tormented Soul",3,"3P","-",,1,,1,,,,,,,,,
|
42
|
+
"S","M","Mephit",3,"3P","-",,2,,,,"o1",,,,,,,
|
43
|
+
"S","M","Corrosive Widow",4,"4P","-",,3,,,,,,,,,"discard_construct",,
|
44
|
+
"S","M","Mistake of Creation",4,"4P","-",,4,,"(-1)",,"o1",,"o1",,,,,
|
45
|
+
"S","M","Wind Tyrant",3,"5P","-",3,3,,,,,,,,,,,
|
46
|
+
"S","M","Sea Tyrant",3,"5P","-",,5,,,,,,,,,"discard_all_but_one_construct",,
|
47
|
+
"S","M","Earth Tyrant",2,"6P","-",,5,,2,2,,,,,,,,
|
48
|
+
"S","M","Xeron Duke of Lies",1,"6P","-",,3,,,,,,,,,"take_opponents_card",,
|
49
|
+
"S","M","Avatar ot Fallen",1,"7P","-",,4,,,,,,,,,"acquire_center",,
|
@@ -0,0 +1,73 @@
|
|
1
|
+
events = <<EOF
|
2
|
+
hero played
|
3
|
+
construct played
|
4
|
+
monster defeated
|
5
|
+
EOF
|
6
|
+
|
7
|
+
module Event
|
8
|
+
class Events
|
9
|
+
include FromHash
|
10
|
+
attr_accessor :side
|
11
|
+
fattr(:events) { [] }
|
12
|
+
def <<(event)
|
13
|
+
event.first = true if first?(event)
|
14
|
+
self.events << event
|
15
|
+
propagate(event)
|
16
|
+
end
|
17
|
+
def propagate(event)
|
18
|
+
side.constructs.each { |c| c.apply_triggers(event,side) } if side
|
19
|
+
end
|
20
|
+
def first?(event)
|
21
|
+
events.select { |x| x.key == event.key && x.class == event.class }.empty?#.tap { |x| puts "first? #{x}" }
|
22
|
+
end
|
23
|
+
def [](i)
|
24
|
+
events[i]
|
25
|
+
end
|
26
|
+
def cond?(&b)
|
27
|
+
events.any?(&b)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Base
|
32
|
+
include FromHash
|
33
|
+
fattr(:first) { false }
|
34
|
+
end
|
35
|
+
|
36
|
+
class CardPlayed < Base
|
37
|
+
attr_accessor :card
|
38
|
+
def realm
|
39
|
+
card.realm
|
40
|
+
end
|
41
|
+
def card_type
|
42
|
+
card.class
|
43
|
+
end
|
44
|
+
def key
|
45
|
+
[realm,card_type]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class MonsterKilled < Base
|
50
|
+
attr_accessor :card
|
51
|
+
fattr(:center) { false }
|
52
|
+
def key
|
53
|
+
[center]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class CardPurchased < Base
|
58
|
+
attr_accessor :card
|
59
|
+
def realm
|
60
|
+
card.realm
|
61
|
+
end
|
62
|
+
def card_type
|
63
|
+
card.class
|
64
|
+
end
|
65
|
+
def key
|
66
|
+
[realm,card_type]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Trigger
|
72
|
+
|
73
|
+
end
|