ascension 0.1.0

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