ascension 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|