galaxy 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/encodings.xml +5 -0
- data/.idea/galaxy.iml +10 -0
- data/.idea/misc.xml +14 -0
- data/.idea/modules.xml +9 -0
- data/.idea/vcs.xml +8 -0
- data/.idea/workspace.xml +486 -0
- data/LICENSE +20 -0
- data/README.rdoc +36 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/doc/plan.txt +5 -0
- data/doc/pseudo.txt +43 -0
- data/features/galaxy.feature +9 -0
- data/features/step_definitions/galaxy_steps.rb +0 -0
- data/features/support/env.rb +4 -0
- data/galaxy.gemspec +95 -0
- data/galaxy/.loadpath +5 -0
- data/galaxy/.project +17 -0
- data/galaxy/.settings/org.eclipse.mylyn.tasks.ui.prefs +4 -0
- data/galaxy/.settings/org.eclipse.wst.sse.core.prefs +5 -0
- data/galaxy/experiments.rb +26 -0
- data/lib/galaxy.rb +8 -0
- data/lib/galaxy/models/bombing.rb +64 -0
- data/lib/galaxy/models/fleet.rb +62 -0
- data/lib/galaxy/models/group.rb +178 -0
- data/lib/galaxy/models/models.rb +16 -0
- data/lib/galaxy/models/planet.rb +181 -0
- data/lib/galaxy/models/product.rb +84 -0
- data/lib/galaxy/models/race.rb +112 -0
- data/lib/galaxy/models/route.rb +60 -0
- data/lib/galaxy/order.rb +24 -0
- data/lib/galaxy/report.rb +176 -0
- data/lib/galaxy/section.rb +226 -0
- data/lib/galaxy/utils.rb +109 -0
- data/lib/galaxy/virtual_base.rb +165 -0
- data/spec/spec_helper.rb +9 -0
- data/test/test_helper.rb +4 -0
- data/test/unit/models_test.rb +1469 -0
- data/test/unit/report_test.rb +187 -0
- data/test/unit/utils_test.rb +421 -0
- data/test/unit/virtual_base_test.rb +224 -0
- metadata +123 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'galaxy/models/models'
|
2
|
+
|
3
|
+
class Group < ActiveRecord::Base
|
4
|
+
virtual
|
5
|
+
tableless :columns => [
|
6
|
+
[:num, :integer],
|
7
|
+
[:xx, :float],
|
8
|
+
[:yy, :float],
|
9
|
+
[:num_ships, :integer ],
|
10
|
+
[:num_before, :integer], # Number of ships BEFORE battle (for Battle Groups only)
|
11
|
+
[:drive, :float],
|
12
|
+
[:weapons, :float],
|
13
|
+
[:shields, :float],
|
14
|
+
[:cargo, :float],
|
15
|
+
[:cargo_type, :string],
|
16
|
+
[:qty, :float],
|
17
|
+
[:range, :float],
|
18
|
+
[:speed, :float],
|
19
|
+
[:mass, :float],
|
20
|
+
[:status, :string] # May cause problems with AR?
|
21
|
+
]
|
22
|
+
belongs_to :race
|
23
|
+
belongs_to :product
|
24
|
+
belongs_to :planet
|
25
|
+
belongs_to :fleet
|
26
|
+
belongs_to :from, :class_name => 'Planet'
|
27
|
+
|
28
|
+
attr_accessor :battles
|
29
|
+
|
30
|
+
def initialize match, state
|
31
|
+
super()
|
32
|
+
update_group match, state
|
33
|
+
end
|
34
|
+
|
35
|
+
# Update information on this Group (based on match size and state hash given)
|
36
|
+
def update_group match, state
|
37
|
+
race = product = planet = from = fleet = nil
|
38
|
+
# Make attributes hash based on match size (many constructors)
|
39
|
+
hash = case match.size
|
40
|
+
when 16 # Your Group
|
41
|
+
race = state[:race]
|
42
|
+
p 'No planet!', match, state unless planet = Planet.lookup(match[9])
|
43
|
+
p 'No from!', match, state unless from = Planet.lookup(match[10]) unless match[10] == '-'
|
44
|
+
p 'No fleet!', match, state unless fleet = Fleet.lookup(race.name + '.' + match[14]) unless match[14] == '-'
|
45
|
+
product = Product.lookup(race.name + '.' + match[2])
|
46
|
+
product = Product.lookup(race.name + '.' + match[2])
|
47
|
+
{:num=>match[0].to_i, :num_ships=>match[1].to_i, :drive=>match[3].to_f, :weapons=>match[4].to_f,
|
48
|
+
:shields=>match[5].to_f, :cargo=>match[6].to_f, :cargo_type=>match[7], :qty=>match[8].to_f,
|
49
|
+
:range=>match[11].to_f, :speed=>match[12].to_f, :mass=>match[13].to_f, :status=>match[15]}
|
50
|
+
|
51
|
+
when 11 # (known) * Group
|
52
|
+
race = state[:race]
|
53
|
+
p 'No planet!', match, state unless planet = Planet.lookup(match[8])
|
54
|
+
p 'No product!', match, state unless product = Product.lookup(race.name + '.' + match[1])
|
55
|
+
{:num_ships=>match[0].to_i, :drive=>match[2].to_f, :weapons=>match[3].to_f, :shields=>match[4].to_f,
|
56
|
+
:cargo=>match[5].to_f, :cargo_type=>match[6], :qty=>match[7].to_f, :speed=>match[9].to_f, :mass=>match[10].to_f}
|
57
|
+
|
58
|
+
when 10 # Battle Group
|
59
|
+
race = state[:race]
|
60
|
+
planet = state[:planet]
|
61
|
+
product = Product.lookup(race.name + '.' + match[1])
|
62
|
+
@battles = state[:battles]
|
63
|
+
{:num_before=>match[0].to_i, :drive=>match[2].to_f, :weapons=>match[3].to_f,
|
64
|
+
:shields=>match[4].to_f, :cargo=>match[5].to_f, :cargo_type=>match[6], :qty=>match[7].to_f,
|
65
|
+
:num_ships=>match[8].to_i, :status=>match[9]}
|
66
|
+
|
67
|
+
when 5 # Incoming Group
|
68
|
+
planet = Planet.new [match[1]], state.merge({:race=>nil,:product=>nil,:created_by=>self}) unless planet = Planet.lookup(match[1])
|
69
|
+
from = Planet.new [match[0]], state.merge({:race=>nil,:product=>nil,:created_by=>self}) unless from = Planet.lookup(match[0])
|
70
|
+
{:range=>match[2].to_f, :speed=>match[3].to_f, :mass=>match[4].to_f}
|
71
|
+
|
72
|
+
when 2 # Unidentified Group - TODO implement track calculation
|
73
|
+
{:xx=>match[0].to_f, :yy=>match[1].to_f}
|
74
|
+
|
75
|
+
when 0 # All init data given in a state hash
|
76
|
+
state
|
77
|
+
else {}
|
78
|
+
end
|
79
|
+
# Set all the attributes given in hash
|
80
|
+
hash.each do |key, value|
|
81
|
+
setter = key.to_s.concat('=').to_sym
|
82
|
+
if self.respond_to? setter then self.send setter, value else raise ArgumentError end
|
83
|
+
end
|
84
|
+
# Add this Group to appropriate collections it belongs to
|
85
|
+
# auto-delete from previous collection should be handled by Owner class through collection callbacks
|
86
|
+
race.groups << self if race
|
87
|
+
product.groups << self if product
|
88
|
+
planet.groups << self if planet
|
89
|
+
fleet.groups << self if fleet
|
90
|
+
from.sent_groups << self if from
|
91
|
+
add if self.class.dataset # Add instantiated model to dataset if it is established
|
92
|
+
end
|
93
|
+
|
94
|
+
# Accessor methods
|
95
|
+
def eta ; from ? range/speed : 0 end
|
96
|
+
|
97
|
+
def x
|
98
|
+
return xx if xx
|
99
|
+
return planet.x if planet and !from
|
100
|
+
return 0 if planet and from # game.geometry.group_pos(self)[0]
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def y
|
105
|
+
return yy if yy
|
106
|
+
return planet.y if planet and !from
|
107
|
+
return 0 if planet and from # game.geometry.group_pos(self)[0]
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
|
111
|
+
def destination ; planet end
|
112
|
+
|
113
|
+
def origin ; from end
|
114
|
+
alias source origin
|
115
|
+
|
116
|
+
def key
|
117
|
+
if num # Your Group or other known race from additional reports
|
118
|
+
race.name + '.' + num.to_s
|
119
|
+
else # Impossible to define primary key (no combination of parameters is unique)
|
120
|
+
nil
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def distance planet
|
125
|
+
#game.geometry.distance (self, planet2)
|
126
|
+
0
|
127
|
+
end
|
128
|
+
|
129
|
+
# Boolean tests on Groups
|
130
|
+
def from_battle? ; @battles and @battles > 0 end # This Group is known from Battle
|
131
|
+
|
132
|
+
def incoming? ; !your? and from and planet and planet.your? end
|
133
|
+
|
134
|
+
def unidentified? ; !race end
|
135
|
+
alias unknown? unidentified?
|
136
|
+
|
137
|
+
def active?
|
138
|
+
return true unless from_battle? # All Groups are "real", unless they are known only from Battle
|
139
|
+
!your? and num_ships > 0 and planet.unknown? and planet.battles == self.battles # Not killed Groups from LAST Battle on UNKNOWN PLanet are "real" too
|
140
|
+
end
|
141
|
+
alias real? active?
|
142
|
+
|
143
|
+
def your_active? ; active? and your? end # Only includes your "active" (NOT from_battle) groups
|
144
|
+
|
145
|
+
def drone? ; (product and product.drone?) or (incoming? and mass == 1) end
|
146
|
+
|
147
|
+
def <=>(other) # Default comparable is num_ships
|
148
|
+
case other
|
149
|
+
when nil then 1
|
150
|
+
when Group then # key <=> other.key
|
151
|
+
return 0 if key and self.key == other.key
|
152
|
+
if num_ships and other.num_ships then num_ships <=> other.num_ships else -1 end
|
153
|
+
# Meaningful comparison only possible for groups with known num_ships
|
154
|
+
when Race then race ? race <=> other : -1
|
155
|
+
when Planet then
|
156
|
+
return 0 if from and from == other
|
157
|
+
planet ? planet <=> other : -1
|
158
|
+
when Product then product ? product <=> other : -1
|
159
|
+
when Fleet then fleet ? fleet <=> other : -1
|
160
|
+
when Integer then num_ships ? num_ships <=> other : -1
|
161
|
+
when String then self <=> other.downcase.to_sym
|
162
|
+
when Symbol then
|
163
|
+
return active? ? 0 : 1 if other == :active or other == :real or other == :alive
|
164
|
+
return from_battle? ? 0 : 1 if other == :from_battle or other == :battle
|
165
|
+
return incoming? ? 0 : 1 if other == :incoming
|
166
|
+
return unidentified? ? 0 : 1 if other == :unidentified or other == :unknown
|
167
|
+
return 0 if race and race == other
|
168
|
+
return 0 if product and product == other
|
169
|
+
return 0 if planet and planet == other
|
170
|
+
return 0 if from and from == other
|
171
|
+
return 0 if fleet and fleet == other
|
172
|
+
return 0 if status and status.downcase.include? other.to_s
|
173
|
+
return 0 if key and key.downcase.include? other.to_s
|
174
|
+
-1
|
175
|
+
else raise ArgumentError, 'Comparison with a wrong type'
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end #Group
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# First, 'models.rb' serves as 'super-class-equivalent' for Models, activating all the
|
2
|
+
# VirtualBase enhancements that can be used in Model classes (macros, class methods, instance methods)
|
3
|
+
require 'rubygems'
|
4
|
+
require 'active_record'
|
5
|
+
require 'galaxy/virtual_base.rb'
|
6
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ":memory:", :timeout => 500)
|
7
|
+
ActiveRecord::Base.send(:include, ActiveRecord::VirtualBase)
|
8
|
+
|
9
|
+
# Second, 'models.rb' serves as collector, allowing clients to require 'models.rb' instead of individual Model files
|
10
|
+
require 'galaxy/models/race'
|
11
|
+
require 'galaxy/models/product'
|
12
|
+
require 'galaxy/models/planet'
|
13
|
+
require 'galaxy/models/bombing'
|
14
|
+
require 'galaxy/models/route'
|
15
|
+
require 'galaxy/models/fleet'
|
16
|
+
require 'galaxy/models/group'
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'galaxy/models/models'
|
2
|
+
|
3
|
+
class Planet < ActiveRecord::Base
|
4
|
+
virtual
|
5
|
+
tableless :columns => [
|
6
|
+
[ :num, :integer],
|
7
|
+
[ :x, :float ],
|
8
|
+
[ :y, :float ],
|
9
|
+
[ :name, :string ],
|
10
|
+
[ :size, :float ],
|
11
|
+
[ :pop, :float ],
|
12
|
+
[ :ind, :float ],
|
13
|
+
[ :res, :float ],
|
14
|
+
[ :cap, :float ],
|
15
|
+
[ :mat, :float ],
|
16
|
+
[ :col, :float ],
|
17
|
+
[ :l, :float ]
|
18
|
+
]
|
19
|
+
belongs_to :race
|
20
|
+
belongs_to :product
|
21
|
+
has_many_linked :bombings
|
22
|
+
has_many_linked :fleets
|
23
|
+
has_many_linked :groups
|
24
|
+
has_many_linked :sent_fleets, :class_name => 'Fleet', :foreign_key => 'from_id'
|
25
|
+
has_many_linked :sent_groups, :class_name => 'Group', :foreign_key => 'from_id'
|
26
|
+
has_many_linked :routes, :before_add => :add_route, :after_remove => :remove_route #, after_remove => :remove_hmt
|
27
|
+
has_many_linked :incoming_routes, :foreign_key => 'target_id', :class_name => 'Route', :after_remove => :remove_route #, :after_remove => :remove_hmt
|
28
|
+
|
29
|
+
attr_accessor :battles, :progress, :created_by
|
30
|
+
|
31
|
+
def add_route(route)
|
32
|
+
# Find if target Route of this cargo type already exist, remove previous Route if found
|
33
|
+
routes.each do |r|
|
34
|
+
remove_route r if r == route.cargo
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def remove_route(route)
|
39
|
+
route.kill
|
40
|
+
end
|
41
|
+
|
42
|
+
def targets
|
43
|
+
routes.map {|r| r.target}
|
44
|
+
end
|
45
|
+
|
46
|
+
def suppliers
|
47
|
+
incoming_routes.map {|r| r.planet}
|
48
|
+
end
|
49
|
+
|
50
|
+
def Planet.new_or_update match, state
|
51
|
+
# Lookup by both num and name is necessary since Routes/Fleets/Bombings create planets by name only
|
52
|
+
num = match[0][0,1] == '#' ? match[0] : '#' + match[0].to_s
|
53
|
+
name = match[3]
|
54
|
+
planet = Planet.lookup(num)
|
55
|
+
planet ||= Planet.lookup(name) if name
|
56
|
+
if planet
|
57
|
+
planet.update_planet match, state
|
58
|
+
else
|
59
|
+
new match, state
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize match, state
|
64
|
+
super()
|
65
|
+
update_planet match, state
|
66
|
+
end
|
67
|
+
|
68
|
+
# Update information on Planet (based on match size and state hash given)
|
69
|
+
def update_planet match, state
|
70
|
+
# Make attributes hash based on match size (4 possible constructors
|
71
|
+
hash = case match.size
|
72
|
+
when 13 # Your Planet/ * Planet
|
73
|
+
prod_name = match[8]
|
74
|
+
prod_key = state[:race] ? state[:race].name + '.' + prod_name : nil
|
75
|
+
product = Product.lookup(prod_name)
|
76
|
+
product ||= Product.lookup(prod_key) if prod_key
|
77
|
+
product.planets << self if product
|
78
|
+
{:num=>match[0].to_i, :x=>match[1].to_f, :y=>match[2].to_f, :name=>match[3], :size=>match[4].to_f,
|
79
|
+
:pop=>match[5].to_f, :ind=>match[6].to_f, :res=>match[7].to_f, :cap=>match[9].to_f,
|
80
|
+
:mat=>match[10].to_f, :col=>match[11].to_f, :l=>match[12].to_f}
|
81
|
+
|
82
|
+
when 8 # Uninhabited Planet
|
83
|
+
{:num=>match[0].to_i, :x=>match[1].to_f, :y=>match[2].to_f, :name=>match[3], :size=>match[4].to_f,
|
84
|
+
:res=>match[5].to_f, :cap=>match[6].to_f, :mat=>match[7].to_f}
|
85
|
+
|
86
|
+
when 6 # Ships In Production
|
87
|
+
total_mass = match[3].to_f / 10 # Mass values given in "Material units", divide by 10
|
88
|
+
produced_mass = match[4].to_f / 10
|
89
|
+
percentage = produced_mass/total_mass # Calculate ship production progress
|
90
|
+
{:progress=>percentage}
|
91
|
+
|
92
|
+
when 3 # Unidentified Planet
|
93
|
+
{:num=>match[0].to_i, :x=>match[1].to_f, :y=>match[2].to_f}
|
94
|
+
|
95
|
+
when 2 # Battle/Bombing generated Planet (known num and name)
|
96
|
+
if state[:section] = 'Battle_planets'
|
97
|
+
self.battles = state[:battles] = self.battles ? self.battles + 1 : 1
|
98
|
+
state[:planet] = self
|
99
|
+
end
|
100
|
+
{:num=>match[0].to_i, :name=>match[1]}
|
101
|
+
|
102
|
+
when 1 # Route/Fleet/Bombing generated Planet (given EITHER #num or name)
|
103
|
+
match[0][0,1] == '#' ?
|
104
|
+
{:num=>match[0][1..-1].to_s} :
|
105
|
+
{:name=>match[0]}
|
106
|
+
|
107
|
+
when 0 # All init data given in a state hash
|
108
|
+
state
|
109
|
+
else {}
|
110
|
+
end
|
111
|
+
# Set all the attributes given in hash
|
112
|
+
hash.each do |key, value|
|
113
|
+
setter = key.to_s.concat('=').to_sym
|
114
|
+
if self.respond_to? setter then self.send setter, value else raise ArgumentError end
|
115
|
+
end
|
116
|
+
state[:race].planets << self if state[:race]
|
117
|
+
num ? add(numkey) : add if self.class.dataset # Add instantiated/updated model to dataset if dataset established
|
118
|
+
@created_by = state[:created_by]
|
119
|
+
self
|
120
|
+
end
|
121
|
+
|
122
|
+
def key ; name ? name : numkey end
|
123
|
+
def numkey ; num ? '#' + num.to_s : nil end
|
124
|
+
|
125
|
+
def distance planet
|
126
|
+
#game.geometry.distance (planet1, planet2)
|
127
|
+
0
|
128
|
+
end
|
129
|
+
|
130
|
+
def produced_full_mat
|
131
|
+
@progress end
|
132
|
+
|
133
|
+
def produced_by_mat
|
134
|
+
return nil unless self.product and self.product.ship?
|
135
|
+
produced_mass = @progress*self.product.mass
|
136
|
+
available_mass = self.mat/10
|
137
|
+
missing_mass = self.product.mass - produced_mass - available_mass
|
138
|
+
if missing_mass < 0
|
139
|
+
@progress
|
140
|
+
else
|
141
|
+
missing_l = (1/self.res+10)*missing_mass #
|
142
|
+
return 1-(available_mass + missing_l/10)/(produced_mass+available_mass+missing_l/10)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
alias produced produced_by_mat
|
146
|
+
|
147
|
+
# Boolean tests on Planets
|
148
|
+
def aster? ; size and size < 1 end
|
149
|
+
|
150
|
+
def max_size? ; size and size == 2500 end
|
151
|
+
|
152
|
+
def uninhabited? ; !race and size end
|
153
|
+
alias free? uninhabited?
|
154
|
+
|
155
|
+
def unidentified? ; !race and !size end
|
156
|
+
alias unknown? unidentified?
|
157
|
+
|
158
|
+
def <=>(other)
|
159
|
+
case other
|
160
|
+
when nil then 1
|
161
|
+
when Planet then num <=> other.num
|
162
|
+
when Race then race ? race <=> other : -1
|
163
|
+
when Product then product ? product <=> other : -1
|
164
|
+
when Bombing then bombings.any? {|r| r == other} ? 0 : 1 #Planet is bigger than Bombing
|
165
|
+
when Fleet then fleets.any? {|r| r == other} ? 0 : sent_fleets.any? {|r| r == other} ? 0 : 1 #Planet is bigger than Fleet
|
166
|
+
when Route then routes.any? {|r| r == other} ? 0 : incoming_routes.any? {|r| r == other}? 0 : 1 #Planet is bigger than Route
|
167
|
+
when Integer then num <=> other
|
168
|
+
when String then self <=> other.downcase.to_sym
|
169
|
+
when Symbol then
|
170
|
+
return aster? ? 0 : 1 if other == :aster or other == :asteroid or other == :min
|
171
|
+
return max_size? ? 0 : 1 if other == :max_size or other == :max
|
172
|
+
return uninhabited? ? 0 : 1 if other == :uninhabited or other == :free or other == :empty
|
173
|
+
return unidentified? ? 0 : 1 if other == :unidentified or other == :unid or other == :unknown
|
174
|
+
return 0 if name and name.downcase.to_sym == other
|
175
|
+
return 0 if race and race == other
|
176
|
+
return 0 if product and product == other
|
177
|
+
key <=> other.to_s
|
178
|
+
else raise ArgumentError, 'Comparison with a wrong type'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end #Planet
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'galaxy/models/models'
|
2
|
+
|
3
|
+
class Product < ActiveRecord::Base
|
4
|
+
virtual
|
5
|
+
tableless :columns => [
|
6
|
+
[:name, :string],
|
7
|
+
[:drive, :float],
|
8
|
+
[:weapons, :float],
|
9
|
+
[:shields, :float],
|
10
|
+
[:cargo, :float],
|
11
|
+
[:guns, :integer],
|
12
|
+
[:mass, :float],
|
13
|
+
[:prod_type, :string]
|
14
|
+
]
|
15
|
+
belongs_to :race
|
16
|
+
has_many_linked :bombings
|
17
|
+
has_many_linked :groups
|
18
|
+
has_many_linked :planets
|
19
|
+
|
20
|
+
def initialize match, state
|
21
|
+
case match.size
|
22
|
+
when 7 then # This is a ship design
|
23
|
+
super({:name=>match[0], :drive=>match[1].to_f, :guns=>match[2].to_i, :weapons=>match[3].to_f,
|
24
|
+
:shields=>match[4].to_f, :cargo=>match[5].to_f, :mass=>match[6].to_f, :prod_type=>'ship'})
|
25
|
+
|
26
|
+
when 5 then # This is a science
|
27
|
+
super({:name=>match[0], :drive=>match[1].to_f, :weapons=>match[2].to_f, :shields=>match[3].to_f,
|
28
|
+
:cargo=>match[4].to_f, :prod_type=>'research'})
|
29
|
+
|
30
|
+
when 0 then # This is Cap/Mat/Col/Drive/Weapon/Shields/Cargo init, all init data given in a hash
|
31
|
+
super state # :name=>state[:name], :prod_type=>state[:prod_type]
|
32
|
+
end
|
33
|
+
# Add this Product to appropriate Race collections it belongs to
|
34
|
+
# auto-delete from previous collection should be handled by Race class through collection callbacks
|
35
|
+
state[:race].products << self if state[:race]
|
36
|
+
add if self.class.dataset # Add instantiated model to dataset if it is defined
|
37
|
+
end
|
38
|
+
|
39
|
+
def key
|
40
|
+
full_name = research? ? name + '_Research' : name
|
41
|
+
full_name = race.name + '.' + full_name if race
|
42
|
+
full_name
|
43
|
+
end
|
44
|
+
|
45
|
+
# Boolean tests on Products
|
46
|
+
def cap? ; prod_type == 'cap' end
|
47
|
+
|
48
|
+
def mat? ; prod_type == 'mat' end
|
49
|
+
|
50
|
+
def terraforming? ; research? and name == '_TerraForming' end
|
51
|
+
|
52
|
+
def moving? ; name[0..3].downcase == 'move' end
|
53
|
+
|
54
|
+
def ship? ; mass != nil end
|
55
|
+
|
56
|
+
def drone? ; drive == 1 and mass == 1 end
|
57
|
+
|
58
|
+
def research? ; prod_type == 'research' end
|
59
|
+
|
60
|
+
def in_use? ; !bombings.empty? or !planets.empty? or !groups.empty? end
|
61
|
+
alias science? research?
|
62
|
+
|
63
|
+
def <=>(other)
|
64
|
+
case other
|
65
|
+
when nil then 1
|
66
|
+
when Race then race ? race <=> other : -1
|
67
|
+
when Product then (ship? and mass != other.mass) ? mass <=> other.mass : key <=> other.key
|
68
|
+
when Bombing then bombings.any? {|r| r == other} ? 0 : 1 #Product is bigger than Bombing
|
69
|
+
when Planet then planets.any? {|r| r == other} ? 0 : 1 #Product is bigger than Planet
|
70
|
+
when Integer then ship? ? mass <=> other : 1 #Science is bigger than anything
|
71
|
+
when Float then ship? ? mass <=> other : 1 #Science is bigger than anything
|
72
|
+
when String then self <=> other.downcase.to_sym
|
73
|
+
when Symbol then
|
74
|
+
return drone? ? 0 : 1 if other == :drone or other == :dron
|
75
|
+
return research? ? 0 : 1 if other == :research or other == :science or other == :tech
|
76
|
+
return moving? ? 0 : 1 if other == :move or other == :moving
|
77
|
+
return terraforming? ? 0 : 1 if other == :terraform or other == :terraforming
|
78
|
+
return 0 if prod_type.downcase.to_sym == other
|
79
|
+
return 0 if key.downcase.include? other.to_s
|
80
|
+
key <=> other.to_s
|
81
|
+
else raise ArgumentError, 'Comparison with a wrong type'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|