Refactored encounters schema so HG/SS can work.

Conditions are now condition values; condition groups are conditions.
Types are now terrain.  Slots are first-class things.

Encounters' condition values and slots' conditions have been broken off
into their own tables, as HG/SS has several slots affected by multiple
conditions.
This commit is contained in:
Eevee 2009-12-09 14:35:29 -08:00
parent 2e49f953c3
commit e6635b4897
10 changed files with 37131 additions and 20708 deletions

View file

@ -1,5 +0,0 @@
id,name
1,Swarm
2,Time of day
3,PokéRadar
4,Gen 3 game in slot 2
1 id name
2 1 Swarm
3 2 Time of day
4 3 PokéRadar
5 4 Gen 3 game in slot 2

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,14 @@
id,encounter_condition_id,name
1,1,During a swarm
2,2,Morning
3,2,Day
4,2,Night
5,3,Using PokéRadar
6,4,Ruby
7,4,Sapphire
8,4,Emerald
9,4,Fire Red
10,4,Leaf Green
12,1,Not during a swarm
13,3,Not using PokéRadar
14,4,No game in slot 3
1 id encounter_condition_id name
2 1 1 During a swarm
3 2 2 Morning
4 3 2 Day
5 4 2 Night
6 5 3 Using PokéRadar
7 6 4 Ruby
8 7 4 Sapphire
9 8 4 Emerald
10 9 4 Fire Red
11 10 4 Leaf Green
12 12 1 Not during a swarm
13 13 3 Not using PokéRadar
14 14 4 No game in slot 3

View file

@ -1,11 +1,5 @@
id,encounter_condition_group_id,name
1,1,During a swarm
2,2,Morning
3,2,Day
4,2,Night
5,3,Using PokéRadar
6,4,Ruby
7,4,Sapphire
8,4,Emerald
9,4,Fire Red
10,4,Leaf Green
id,name
1,Swarm
2,Time of day
3,PokéRadar
4,Gen 3 game in slot 2

1 id encounter_condition_group_id name
2 1 1 During a swarm Swarm
3 2 2 Morning Time of day
4 3 2 Day PokéRadar
5 4 2 Night Gen 3 game in slot 2
5 3 Using PokéRadar
6 4 Ruby
7 4 Sapphire
8 4 Emerald
9 4 Fire Red
10 4 Leaf Green

View file

@ -0,0 +1,10 @@
encounter_slot_id,encounter_condition_id
1,1
2,2
4,3
5,4
6,3
27,2
28,2
29,2
30,2
1 encounter_slot_id encounter_condition_id
2 1 1
3 2 2
4 4 3
5 5 4
6 6 3
7 27 2
8 28 2
9 29 2
10 30 2

View file

@ -0,0 +1,33 @@
id,encounter_terrain_id,rarity
1,1,20
2,1,10
3,1,10
4,1,5
5,1,4
6,1,1
7,2,60
8,2,30
9,2,5
10,2,4
11,2,1
12,3,60
13,3,30
14,3,5
15,3,4
16,3,1
17,4,60
18,4,30
19,4,5
20,4,4
21,4,1
22,5,60
23,5,30
24,5,5
25,5,4
26,5,1
27,1,20
28,1,5
29,1,4
30,1,1
32,6,51
33,6,49
1 id encounter_terrain_id rarity
2 1 1 20
3 2 1 10
4 3 1 10
5 4 1 5
6 5 1 4
7 6 1 1
8 7 2 60
9 8 2 30
10 9 2 5
11 10 2 4
12 11 2 1
13 12 3 60
14 13 3 30
15 14 3 5
16 15 3 4
17 16 3 1
18 17 4 60
19 18 4 30
20 19 4 5
21 20 4 4
22 21 4 1
23 22 5 60
24 23 5 30
25 24 5 5
26 25 5 4
27 26 5 1
28 27 1 20
29 28 1 5
30 29 1 4
31 30 1 1
32 32 6 51
33 33 6 49

View file

@ -1,33 +0,0 @@
id,encounter_type_id,encounter_condition_group_id,rarity
1,1,1,20
2,1,2,10
3,1,,10
4,1,3,5
5,1,4,4
6,1,3,1
7,2,,60
8,2,,30
9,2,,5
10,2,,4
11,2,,1
12,3,,60
13,3,,30
14,3,,5
15,3,,4
16,3,,1
17,4,,60
18,4,,30
19,4,,5
20,4,,4
21,4,,1
22,5,,60
23,5,,30
24,5,,5
25,5,,4
26,5,,1
27,1,2,20
28,1,2,5
29,1,2,4
30,1,2,1
32,6,,51
33,6,,49
1 id encounter_type_id encounter_condition_group_id rarity
2 1 1 1 20
3 2 1 2 10
4 3 1 10
5 4 1 3 5
6 5 1 4 4
7 6 1 3 1
8 7 2 60
9 8 2 30
10 9 2 5
11 10 2 4
12 11 2 1
13 12 3 60
14 13 3 30
15 14 3 5
16 15 3 4
17 16 3 1
18 17 4 60
19 18 4 30
20 19 4 5
21 20 4 4
22 21 4 1
23 22 5 60
24 23 5 30
25 24 5 5
26 25 5 4
27 26 5 1
28 27 1 2 20
29 28 1 2 5
30 29 1 2 4
31 30 1 2 1
32 32 6 51
33 33 6 49

File diff suppressed because it is too large Load diff

View file

@ -40,23 +40,23 @@ class EggGroup(TableBase):
name = Column(Unicode(16), nullable=False)
class Encounter(TableBase):
"""Rows in this table represent encounters with wild Pokémon.
"""Rows in this table represent encounters with wild Pokémon. Bear with
me, here.
Within a given area in a given game, encounters are differentiated by the
slot they are in and a world condition.
"slot" they are in and the state of the game world.
Groups of slots belong to encounter types; these are what the player is
doing to get an encounter, such as surfing or walking through tall grass.
What the player is doing to get an encounter, such as surfing or walking
through tall grass, is called terrain. Each terrain has its own set of
encounter slots.
Within an encounter type, slots are defined primarily by rarity. Each slot
can also be affected by a world condition; for example, the 20% slot for
walking in tall grass is affected by whether a swarm is in effect in the
areas. "There is a swarm" and "there is not a swarm" are conditions, and
together they make a condition group. However, since "not a swarm" is a
base state rather than any sort of new state, it is omitted and instead
referred to by a NULL.
Within a terrain, slots are defined primarily by rarity. Each slot can
also be affected by world conditions; for example, the 20% slot for walking
in tall grass is affected by whether a swarm is in effect in that area.
"Is there a swarm?" is a condition; "there is a swarm" and "there is not a
swarm" are the possible values of this condition.
A slot (20% walking in grass) and single world condition (NULL, i.e. no
A slot (20% walking in grass) and any appropriate world conditions (no
swarm) are thus enough to define a specific encounter.
Well, okay, almost: each slot actually appears twice.
@ -66,57 +66,66 @@ class Encounter(TableBase):
id = Column(Integer, primary_key=True, nullable=False)
version_id = Column(Integer, ForeignKey('versions.id'), nullable=False, autoincrement=False)
location_area_id = Column(Integer, ForeignKey('location_areas.id'), nullable=False, autoincrement=False)
encounter_type_slot_id = Column(Integer, ForeignKey('encounter_type_slots.id'), nullable=False, autoincrement=False)
encounter_condition_id = Column(Integer, ForeignKey('encounter_conditions.id'), nullable=True, autoincrement=False)
encounter_slot_id = Column(Integer, ForeignKey('encounter_slots.id'), nullable=False, autoincrement=False)
pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False, autoincrement=False)
min_level = Column(Integer, nullable=False, autoincrement=False)
max_level = Column(Integer, nullable=False, autoincrement=False)
class EncounterCondition(TableBase):
"""Rows in this table represent something different about the world that
can affect what Pokémon are encountered.
"""Rows in this table represent varying conditions in the game world, such
as time of day.
"""
__tablename__ = 'encounter_conditions'
id = Column(Integer, primary_key=True, nullable=False)
encounter_condition_group_id = Column(Integer, ForeignKey('encounter_condition_groups.id'), primary_key=False, nullable=False, autoincrement=False)
name = Column(Unicode(64), nullable=False)
class EncounterConditionGroup(TableBase):
"""Rows in this table represent a group of mutually exclusive conditions,
such as morning/day/night. "Conditions" that are part of the default state
of the world, such as "not during a swarm" or "not using the PokéRadar",
are not included in this table and are referred to by NULLs in other
tables.
class EncounterConditionValue(TableBase):
"""Rows in this table represent possible states for a condition; for
example, the state of 'swarm' could be 'swarm' or 'no swarm'.
"""
__tablename__ = 'encounter_condition_groups'
__tablename__ = 'encounter_condition_values'
id = Column(Integer, primary_key=True, nullable=False)
encounter_condition_id = Column(Integer, ForeignKey('encounter_conditions.id'), primary_key=False, nullable=False, autoincrement=False)
name = Column(Unicode(64), nullable=False)
class EncounterConditionValueMap(TableBase):
"""Maps encounters to the specific conditions under which they occur."""
__tablename__ = 'encounter_condition_value_map'
encounter_id = Column(Integer, ForeignKey('encounters.id'), primary_key=True, nullable=False, autoincrement=False)
encounter_condition_value_id = Column(Integer, ForeignKey('encounter_condition_values.id'), primary_key=True, nullable=False, autoincrement=False)
class EncounterTerrain(TableBase):
"""Rows in this table represent ways the player can enter a wild encounter,
e.g., surfing, fishing, or walking through tall grass.
"""
__tablename__ = 'encounter_terrain'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(64), nullable=False)
class EncounterType(TableBase):
"""Rows in this table represent ways the player can enter a wild encounter;
i.e. surfing, fishing, or walking through tall grass.
"""
__tablename__ = 'encounter_types'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(64), nullable=False)
class EncounterTypeSlot(TableBase):
"""Rows in this table represent an abstract "slot" within an encounter
type, associated with both a condition group and a rarity.
class EncounterSlot(TableBase):
"""Rows in this table represent an abstract "slot" within a terrain,
associated with both some set of conditions and a rarity.
Note that there are two encounters per slot, so the rarities will only add
up to 50.
"""
__tablename__ = 'encounter_type_slots'
__tablename__ = 'encounter_slots'
id = Column(Integer, primary_key=True, nullable=False)
encounter_type_id = Column(Integer, ForeignKey('encounter_types.id'), primary_key=False, nullable=False, autoincrement=False)
encounter_condition_group_id = Column(Integer, ForeignKey('encounter_condition_groups.id'), primary_key=False, nullable=True, autoincrement=False)
encounter_terrain_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=False, nullable=False, autoincrement=False)
rarity = Column(Integer, nullable=False, autoincrement=False)
class EncounterSlotCondition(TableBase):
"""Lists all conditions that affect each slot."""
__tablename__ = 'encounter_slot_conditions'
encounter_slot_id = Column(Integer, ForeignKey('encounter_slots.id'), primary_key=True, nullable=False, autoincrement=False)
encounter_condition_id = Column(Integer, ForeignKey('encounter_conditions.id'), primary_key=True, nullable=False, autoincrement=False)
class EvolutionChain(TableBase):
__tablename__ = 'evolution_chains'
id = Column(Integer, primary_key=True, nullable=False)
@ -172,7 +181,7 @@ class LocationArea(TableBase):
class LocationAreaEncounterRate(TableBase):
__tablename__ = 'location_area_encounter_rates'
location_area_id = Column(Integer, ForeignKey('location_areas.id'), primary_key=True, nullable=False, autoincrement=False)
encounter_type_id = Column(Integer, ForeignKey('encounter_types.id'), primary_key=True, nullable=False, autoincrement=False)
encounter_type_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=True, nullable=False, autoincrement=False)
rate = Column(Integer, nullable=True)
class Machine(TableBase):
@ -448,16 +457,24 @@ ContestCombo.first = relation(Move, primaryjoin=ContestCombo.first_move_id==Move
ContestCombo.second = relation(Move, primaryjoin=ContestCombo.second_move_id==Move.id,
backref='contest_combo_second')
Encounter.location_area = relation(LocationArea, backref='encounters')
Encounter.pokemon = relation(Pokemon, backref='encounters')
Encounter.version = relation(Version, backref='encounters')
Encounter.location_area = relation(LocationArea, backref='encounters')
Encounter.slot = relation(EncounterTypeSlot, backref='encounters')
Encounter.condition = relation(EncounterCondition, backref='encounters')
Encounter.slot = relation(EncounterSlot, backref='encounters')
EncounterCondition.group = relation(EncounterConditionGroup,
backref='conditions')
EncounterConditionValue.condition = relation(EncounterCondition, backref='values')
EncounterTypeSlot.type = relation(EncounterType, backref='slots')
Encounter.condition_value_map = relation(EncounterConditionValueMap, backref='encounter')
Encounter.condition_values = association_proxy('condition_value_map', 'condition_value')
EncounterConditionValueMap.condition_value = relation(EncounterConditionValue,
backref='encounter_map')
EncounterSlot.terrain = relation(EncounterTerrain, backref='slots')
EncounterSlot.condition_map = relation(EncounterSlotCondition, backref='slot')
EncounterSlot.conditions = association_proxy('condition_map', 'condition')
EncounterSlotCondition.condition = relation(EncounterCondition,
backref='slot_map')
EvolutionChain.growth_rate = relation(GrowthRate, backref='evolution_chains')