2016-11-08 16:43:57 +00:00
using System ;
2017-02-27 02:23:29 +00:00
using System.Collections.Generic ;
2017-02-12 17:52:26 +00:00
using System.Linq ;
2016-11-08 16:43:57 +00:00
2017-01-08 07:54:09 +00:00
namespace PKHeX.Core
2016-11-08 16:43:57 +00:00
{
2017-10-24 06:12:58 +00:00
/// <summary>
/// Represents an Area where <see cref="PKM"/> can be encountered, which contains a Location ID and <see cref="EncounterSlot"/> data.
/// </summary>
2016-11-08 16:43:57 +00:00
public class EncounterArea
{
public int Location ;
public EncounterSlot [ ] Slots ;
2017-10-24 06:12:58 +00:00
/// <summary>
/// Creates an empty encounter area ready for initialization.
/// </summary>
2016-11-08 16:43:57 +00:00
public EncounterArea ( ) { }
2017-10-24 06:12:58 +00:00
/// <summary>
/// Creates an array of encounter data with a specified location ID.
/// </summary>
/// <param name="data">Encounter data</param>
/// <remarks>
/// Encounter Data is stored in the following format: (u16 Location, n*[u16 Species/Form, u8 Min, u8 Max])
/// </remarks>
2016-11-08 16:43:57 +00:00
private EncounterArea ( byte [ ] data )
{
Location = BitConverter . ToUInt16 ( data , 0 ) ;
Slots = new EncounterSlot [ ( data . Length - 2 ) / 4 ] ;
for ( int i = 0 ; i < Slots . Length ; i + + )
{
ushort SpecForm = BitConverter . ToUInt16 ( data , 2 + i * 4 ) ;
Slots [ i ] = new EncounterSlot
{
Species = SpecForm & 0x7FF ,
Form = SpecForm > > 11 ,
LevelMin = data [ 4 + i * 4 ] ,
LevelMax = data [ 5 + i * 4 ] ,
} ;
}
}
2017-02-12 17:52:26 +00:00
2017-03-19 15:44:36 +00:00
public EncounterArea Clone ( int location )
{
2017-03-19 19:27:58 +00:00
EncounterArea Areas = new EncounterArea
{
Location = location ,
Slots = new EncounterSlot [ Slots . Length ]
} ;
2017-03-19 15:44:36 +00:00
for ( int i = 0 ; i < Slots . Length ; i + + )
{
Areas . Slots [ i ] = Slots [ i ] . Clone ( ) ;
}
return Areas ;
}
public EncounterArea [ ] Clone ( int [ ] locations )
{
EncounterArea [ ] Areas = new EncounterArea [ locations . Length ] ;
2017-03-19 19:27:58 +00:00
for ( int i = 0 ; i < locations . Length ; i + + )
Areas [ i ] = Clone ( locations [ i ] ) ;
2017-03-19 15:44:36 +00:00
return Areas ;
}
2017-10-24 06:12:58 +00:00
private static IEnumerable < EncounterSlot1 > GetSlots1_GW ( byte [ ] data , ref int ofs , SlotType t )
2017-02-12 17:52:26 +00:00
{
int rate = data [ ofs + + ] ;
2017-10-24 06:12:58 +00:00
return rate = = 0 ? Enumerable . Empty < EncounterSlot1 > ( ) : ReadSlots ( data , ref ofs , 10 , t , rate ) ;
2017-02-12 17:52:26 +00:00
}
2017-06-18 01:37:19 +00:00
private static EncounterSlot1 [ ] GetSlots1_F ( byte [ ] data , ref int ofs )
2017-02-12 17:52:26 +00:00
{
int count = data [ ofs + + ] ;
2017-06-18 01:37:19 +00:00
return ReadSlots ( data , ref ofs , count , SlotType . Super_Rod , - 1 ) ;
2017-02-12 17:52:26 +00:00
}
2017-02-27 02:23:29 +00:00
2017-06-18 01:37:19 +00:00
private static EncounterSlot1 [ ] GetSlots2_GW ( byte [ ] data , ref int ofs , SlotType t , int slotSets , int slotCount )
2017-02-27 02:23:29 +00:00
{
byte [ ] rates = new byte [ slotSets ] ;
for ( int i = 0 ; i < rates . Length ; i + + )
rates [ i ] = data [ ofs + + ] ;
2017-06-18 01:37:19 +00:00
var slots = ReadSlots ( data , ref ofs , slotSets * slotCount , t , rates [ 0 ] ) ;
2017-07-06 23:03:41 +00:00
for ( int i = 0 ; i < slotCount ; i + + )
{
slots [ i ] . Time = EncounterTime . Morning ;
}
2017-02-27 02:23:29 +00:00
for ( int r = 1 ; r < slotSets ; r + + )
{
for ( int i = 0 ; i < slotCount ; i + + )
{
int index = i + r * slotCount ;
slots [ index ] . Rate = rates [ r ] ;
slots [ index ] . SlotNumber = i ;
2017-07-07 11:53:21 +00:00
slots [ index ] . Time = r = = 1 ? EncounterTime . Day : EncounterTime . Night ;
2017-02-27 02:23:29 +00:00
}
}
return slots ;
}
2017-10-24 06:12:58 +00:00
private static List < EncounterSlot1 > GetSlots2_F ( byte [ ] data , ref int ofs , SlotType t )
2017-02-27 05:46:00 +00:00
{
// slot set ends in 0xFF 0x** 0x**
var slots = new List < EncounterSlot1 > ( ) ;
2017-06-16 05:21:02 +00:00
int ctr = 0 ;
2017-02-27 05:46:00 +00:00
while ( true )
{
int rate = data [ ofs + + ] ;
int species = data [ ofs + + ] ;
int level = data [ ofs + + ] ;
slots . Add ( new EncounterSlot1
{
Rate = rate ,
Species = species ,
LevelMin = level ,
LevelMax = level ,
2017-06-16 05:21:02 +00:00
SlotNumber = ctr + + ,
2017-02-27 05:46:00 +00:00
Type = species = = 0 ? SlotType . Special : t // day/night specific
} ) ;
if ( rate = = 0xFF )
break ;
}
2017-10-24 06:12:58 +00:00
return slots ;
2017-02-27 05:46:00 +00:00
}
2017-06-18 01:37:19 +00:00
private static EncounterSlot1 [ ] GetSlots2_H ( byte [ ] data , ref int ofs , SlotType t )
2017-03-03 02:24:50 +00:00
{
// slot set ends in 0xFF
var slots = new List < EncounterSlot1 > ( ) ;
int tableCount = t = = SlotType . Headbutt ? 2 : 1 ;
2017-07-06 23:03:41 +00:00
SlotType slottype = t ;
2017-03-03 02:24:50 +00:00
while ( tableCount ! = 0 )
{
2017-07-06 23:03:41 +00:00
if ( t = = SlotType . Headbutt )
slottype = tableCount = = 2 ? SlotType . Headbutt_Special : SlotType . Headbutt ;
2017-03-03 02:24:50 +00:00
int rate = data [ ofs + + ] ;
if ( rate = = 0xFF ) // end of table
{
tableCount - - ;
continue ;
}
int species = data [ ofs + + ] ;
int level = data [ ofs + + ] ;
slots . Add ( new EncounterSlot1
{
Rate = rate ,
Species = species ,
LevelMin = level ,
LevelMax = level ,
2017-07-06 23:03:41 +00:00
Type = slottype
2017-03-03 02:24:50 +00:00
} ) ;
}
return slots . ToArray ( ) ;
}
2017-02-27 05:46:00 +00:00
2017-06-18 01:37:19 +00:00
private static IEnumerable < EncounterArea > GetAreas2 ( byte [ ] data , ref int ofs , SlotType t , int slotSets , int slotCount )
2017-02-27 02:23:29 +00:00
{
var areas = new List < EncounterArea > ( ) ;
while ( data [ ofs ] ! = 0xFF ) // end
{
areas . Add ( new EncounterArea
{
2017-07-07 11:53:21 +00:00
Location = data [ ofs + + ] < < 8 | data [ ofs + + ] ,
2017-06-18 01:37:19 +00:00
Slots = GetSlots2_GW ( data , ref ofs , t , slotSets , slotCount ) ,
2017-02-27 02:23:29 +00:00
} ) ;
}
2017-03-08 07:13:46 +00:00
ofs + + ;
2017-02-27 02:23:29 +00:00
return areas ;
}
2017-06-18 01:37:19 +00:00
private static List < EncounterArea > GetAreas2_F ( byte [ ] data , ref int ofs )
2017-02-27 05:46:00 +00:00
{
var areas = new List < EncounterArea > ( ) ;
var types = new [ ] { SlotType . Old_Rod , SlotType . Good_Rod , SlotType . Super_Rod } ;
2017-06-12 23:54:39 +00:00
while ( ofs ! = 0x18C )
2017-02-27 05:46:00 +00:00
{
2017-06-12 23:54:39 +00:00
areas . Add ( new EncounterArea {
2017-06-18 01:37:19 +00:00
Slots = GetSlots2_F ( data , ref ofs , types [ 0 ] )
. Concat ( GetSlots2_F ( data , ref ofs , types [ 1 ] ) )
. Concat ( GetSlots2_F ( data , ref ofs , types [ 2 ] ) ) . ToArray ( ) } ) ;
2017-02-27 05:46:00 +00:00
}
2017-06-12 23:54:39 +00:00
2017-02-27 05:46:00 +00:00
// Read TimeFishGroups
var dl = new List < DexLevel > ( ) ;
2017-06-12 23:54:39 +00:00
while ( ofs < data . Length )
2017-02-27 05:46:00 +00:00
dl . Add ( new DexLevel { Species = data [ ofs + + ] , Level = data [ ofs + + ] } ) ;
// Add TimeSlots
foreach ( var area in areas )
{
var slots = area . Slots ;
for ( int i = 0 ; i < slots . Length ; i + + )
{
var slot = slots [ i ] ;
if ( slot . Type ! = SlotType . Special )
continue ;
Array . Resize ( ref slots , slots . Length + 1 ) ;
2017-06-12 23:54:39 +00:00
Array . Copy ( slots , i , slots , i + 1 , slots . Length - i - 1 ) ; // shift slots down
2017-02-27 05:46:00 +00:00
slots [ i + 1 ] = slot . Clone ( ) ; // differentiate copied slot
int index = slot . LevelMin * 2 ;
for ( int j = 0 ; j < 2 ; j + + ) // load special slot info
{
2017-07-06 23:03:41 +00:00
var s = slots [ i + j ] as EncounterSlot1 ;
2017-02-27 05:46:00 +00:00
s . Species = dl [ index + j ] . Species ;
2017-06-16 05:21:02 +00:00
s . LevelMin = s . LevelMax = dl [ index + j ] . Level ;
s . Type = slots [ i - 1 ] . Type ; // special slots are never first in a set, so copy previous type
2017-07-06 23:03:41 +00:00
s . Time = j = = 0 ? EncounterTime . MorningDay : EncounterTime . Night ;
2017-02-27 05:46:00 +00:00
}
}
2017-06-16 05:21:02 +00:00
area . Slots = slots ;
2017-02-27 05:46:00 +00:00
}
return areas ;
}
2017-06-18 01:37:19 +00:00
private static IEnumerable < EncounterArea > GetAreas2_H ( byte [ ] data , ref int ofs )
2017-03-03 02:24:50 +00:00
{
// Read Location Table
var head = new List < EncounterArea > ( ) ;
var headID = new List < int > ( ) ;
while ( data [ ofs ] ! = 0xFF )
{
head . Add ( new EncounterArea
{
Location = ( data [ ofs + + ] < < 8 ) | data [ ofs + + ] ,
Slots = null , // later
} ) ;
headID . Add ( data [ ofs + + ] ) ;
}
ofs + + ;
var rock = new List < EncounterArea > ( ) ;
var rockID = new List < int > ( ) ;
while ( data [ ofs ] ! = 0xFF )
{
rock . Add ( new EncounterArea
{
Location = ( data [ ofs + + ] < < 8 ) | data [ ofs + + ] ,
Slots = null , // later
} ) ;
rockID . Add ( data [ ofs + + ] ) ;
}
ofs + + ;
ofs + = 0x16 ; // jump over GetTreeMons
// Read ptr table
int [ ] ptr = new int [ data . Length = = 0x109 ? 6 : 9 ] ; // GS : C
for ( int i = 0 ; i < ptr . Length ; i + + )
ptr [ i ] = data [ ofs + + ] | ( data [ ofs + + ] < < 8 ) ;
int baseOffset = ptr . Min ( ) - ofs ;
// Read Tables
for ( int i = 0 ; i < head . Count ; i + + )
{
int o = ptr [ headID [ i ] ] - baseOffset ;
2017-06-18 01:37:19 +00:00
head [ i ] . Slots = GetSlots2_H ( data , ref o , SlotType . Headbutt ) ;
2017-03-03 02:24:50 +00:00
}
for ( int i = 0 ; i < rock . Count ; i + + )
{
int o = ptr [ rockID [ i ] ] - baseOffset ;
2017-06-18 01:37:19 +00:00
rock [ i ] . Slots = GetSlots2_H ( data , ref o , SlotType . Rock_Smash ) ;
2017-03-03 02:24:50 +00:00
}
return head . Concat ( rock ) ;
}
2017-02-12 17:52:26 +00:00
2017-06-18 01:37:19 +00:00
private static IEnumerable < EncounterSlot > GetSlots3 ( byte [ ] data , ref int ofs , int numslots , SlotType t )
2017-03-19 12:19:45 +00:00
{
var slots = new List < EncounterSlot > ( ) ;
int Ratio = data [ ofs ] ;
//1 byte padding
if ( Ratio > 0 )
{
for ( int i = 0 ; i < numslots ; i + + )
{
2017-03-19 19:44:59 +00:00
int Species = BitConverter . ToInt16 ( data , ofs + 4 + i * 4 ) ;
2017-03-19 19:27:58 +00:00
if ( Species < = 0 )
continue ;
slots . Add ( new EncounterSlot
{
LevelMin = data [ ofs + 2 + i * 4 ] ,
LevelMax = data [ ofs + 3 + i * 4 ] ,
Species = Species ,
SlotNumber = i ,
Type = t
} ) ;
2017-03-19 12:19:45 +00:00
}
}
ofs + = 2 + numslots * 4 ;
return slots ;
}
2017-06-18 01:37:19 +00:00
private static IEnumerable < EncounterSlot > GetSlots3_F ( byte [ ] data , ref int ofs , int numslots )
2017-03-19 12:19:45 +00:00
{
var slots = new List < EncounterSlot > ( ) ;
int Ratio = data [ ofs ] ;
//1 byte padding
if ( Ratio > 0 )
{
for ( int i = 0 ; i < numslots ; i + + )
{
2017-03-19 19:44:59 +00:00
int Species = BitConverter . ToInt16 ( data , ofs + 4 + i * 4 ) ;
2017-03-19 19:27:58 +00:00
if ( Species < = 0 )
continue ;
var slot = new EncounterSlot
{
LevelMin = data [ ofs + 2 + i * 4 ] ,
LevelMax = data [ ofs + 3 + i * 4 ] ,
Species = Species ,
} ;
if ( i < 2 )
{
slot . Type = SlotType . Old_Rod ;
slot . SlotNumber = i ; // 0,1
}
else if ( i < 5 )
{
slot . Type = SlotType . Good_Rod ;
slot . SlotNumber = i - 2 ; // 0,1,2
}
else
{
slot . Type = SlotType . Super_Rod ;
slot . SlotNumber = i - 5 ; // 0,1,2,3,4
}
slots . Add ( slot ) ;
2017-03-19 12:19:45 +00:00
}
}
ofs + = 2 + numslots * 4 ;
return slots ;
}
2017-06-18 01:37:19 +00:00
private static EncounterSlot [ ] GetSlots4_DPPt_G ( byte [ ] data , int ofs , int numslots , SlotType t )
2017-03-19 12:19:45 +00:00
{
var slots = new EncounterSlot [ numslots ] ;
for ( int i = 0 ; i < numslots ; i + + )
{
2017-03-26 05:23:36 +00:00
int level = data [ ofs + i * 8 ] ;
int species = BitConverter . ToInt32 ( data , ofs + i * 8 + 4 ) ;
2017-03-19 17:44:46 +00:00
slots [ i ] = new EncounterSlot
2017-03-19 12:19:45 +00:00
{
LevelMax = level ,
LevelMin = level ,
Species = species ,
2017-03-19 19:27:58 +00:00
SlotNumber = i ,
2017-03-19 14:10:28 +00:00
Type = t
2017-03-19 12:19:45 +00:00
} ;
}
return slots ;
}
2017-06-18 01:37:19 +00:00
private static EncounterSlot [ ] GetSlots4_HGSS_G ( byte [ ] data , int ofs , int numslots , SlotType t )
2017-03-19 12:19:45 +00:00
{
var slots = new EncounterSlot [ numslots * 3 ] ;
// First 36 slots are morning, day and night grass slots
// The order is 12 level values, 12 morning species, 12 day species and 12 night species
for ( int i = 0 ; i < numslots ; i + + )
{
int level = data [ ofs + i ] ;
2017-05-28 04:17:53 +00:00
int species = BitConverter . ToUInt16 ( data , ofs + numslots + i * 2 ) ;
2017-03-19 17:44:46 +00:00
slots [ i ] = new EncounterSlot
2017-03-19 12:19:45 +00:00
{
LevelMin = level ,
LevelMax = level ,
Species = species ,
2017-03-19 19:27:58 +00:00
SlotNumber = i ,
2017-03-19 14:10:28 +00:00
Type = t
2017-03-19 12:19:45 +00:00
} ;
slots [ numslots + i ] = slots [ i ] . Clone ( ) ;
2017-03-19 17:44:46 +00:00
slots [ numslots + i ] . Species = BitConverter . ToUInt16 ( data , ofs + numslots * 3 + i * 2 ) ;
2017-03-19 14:10:28 +00:00
slots [ numslots + i ] . Type = t ;
2017-03-19 12:19:45 +00:00
slots [ numslots * 2 + i ] = slots [ i ] . Clone ( ) ;
2017-03-19 17:44:46 +00:00
slots [ numslots * 2 + i ] . Species = BitConverter . ToUInt16 ( data , ofs + numslots * 5 + i * 2 ) ;
2017-03-19 14:10:28 +00:00
slots [ numslots * 2 + i ] . Type = t ;
2017-03-19 12:19:45 +00:00
}
return slots ;
}
2017-06-18 01:37:19 +00:00
private static IEnumerable < EncounterSlot > GetSlots4_G_Replace ( byte [ ] data , int ofs , int slotSize , EncounterSlot [ ] ReplacedSlots , int [ ] slotnums , SlotType t = SlotType . Grass )
2017-03-19 12:19:45 +00:00
{
2017-03-20 14:49:05 +00:00
//Special slots like GBA Dual Slot. Those slot only contain the info of species id, the level is copied from one of the first grass slots
2017-03-26 11:14:00 +00:00
//for dppt slotSize = 4, for hgss slotSize = 2
2017-03-19 12:19:45 +00:00
var slots = new List < EncounterSlot > ( ) ;
2017-03-19 19:27:58 +00:00
int numslots = slotnums . Length ;
2017-03-19 12:19:45 +00:00
for ( int i = 0 ; i < numslots ; i + + )
{
2017-03-19 19:27:58 +00:00
var baseSlot = ReplacedSlots [ slotnums [ i ] ] ;
if ( baseSlot . LevelMin < = 0 )
continue ;
2017-03-19 12:19:45 +00:00
2017-03-26 11:14:00 +00:00
int species = BitConverter . ToUInt16 ( data , ofs + i / ( 4 / slotSize ) * slotSize ) ;
2017-04-07 04:18:02 +00:00
if ( species < = 0 | | baseSlot . Species = = species ) // Empty or duplicate
2017-03-19 19:27:58 +00:00
continue ;
2017-03-19 13:38:30 +00:00
2017-03-19 19:27:58 +00:00
var slot = baseSlot . Clone ( ) ;
slot . Species = species ;
slot . Type = t ;
slots . Add ( slot ) ;
2017-03-19 13:38:30 +00:00
}
return slots ;
}
2017-06-18 01:37:19 +00:00
private static IEnumerable < EncounterSlot > GetSlots4DPPt_WFR ( byte [ ] data , int ofs , int numslots , SlotType t )
2017-03-19 12:19:45 +00:00
{
var slots = new List < EncounterSlot > ( ) ;
for ( int i = 0 ; i < numslots ; i + + )
{
2017-03-30 00:43:17 +00:00
// max, min, unused, unused, [32bit species]
2017-03-19 19:27:58 +00:00
int Species = BitConverter . ToInt32 ( data , ofs + 4 + i * 8 ) ;
if ( Species < = 0 )
continue ;
2017-03-20 14:49:05 +00:00
// fishing and surf slots with species = 0 are not added
// DPPt does not have fishing or surf swarms
2017-03-19 19:27:58 +00:00
slots . Add ( new EncounterSlot
{
2017-03-30 00:43:17 +00:00
LevelMax = data [ ofs + 0 + i * 8 ] ,
LevelMin = data [ ofs + 1 + i * 8 ] ,
2017-03-19 19:27:58 +00:00
Species = Species ,
Type = t
} ) ;
2017-03-19 12:19:45 +00:00
}
return slots ;
}
2017-06-18 01:37:19 +00:00
private static IEnumerable < EncounterSlot > GetSlots4HGSS_WFR ( byte [ ] data , int ofs , int numslots , SlotType t )
2017-03-19 13:38:30 +00:00
{
var slots = new List < EncounterSlot > ( ) ;
for ( int i = 0 ; i < numslots ; i + + )
{
2017-03-19 19:27:58 +00:00
// min, max, [16bit species]
int Species = BitConverter . ToInt16 ( data , ofs + 2 + i * 4 ) ;
2017-03-20 14:49:05 +00:00
if ( t = = SlotType . Rock_Smash & & Species < = 0 )
2017-03-19 19:27:58 +00:00
continue ;
2017-03-20 14:49:05 +00:00
// fishing and surf slots with species = 0 are added too, it is needed for the swarm encounters,
// it will be deleted after add swarm slots
2017-03-19 13:38:30 +00:00
2017-03-19 19:27:58 +00:00
slots . Add ( new EncounterSlot
{
LevelMin = data [ ofs + 0 + i * 4 ] ,
LevelMax = data [ ofs + 1 + i * 4 ] ,
Species = Species ,
Type = t
} ) ;
2017-03-19 13:38:30 +00:00
}
return slots ;
}
2017-03-19 12:19:45 +00:00
2017-06-18 01:37:19 +00:00
private static EncounterArea GetArea3 ( byte [ ] data )
2017-03-19 12:19:45 +00:00
{
EncounterArea Area3 = new EncounterArea ( ) ;
2017-03-19 17:44:46 +00:00
2017-03-19 12:19:45 +00:00
if ( data . Length < 6 )
{ Area3 . Location = 0 ; Area3 . Slots = new EncounterSlot [ 0 ] ; return Area3 ; }
Area3 . Location = data [ 0 ] ;
2017-03-19 17:44:46 +00:00
var HaveGrassSlots = data [ 1 ] = = 1 ;
var HaveSurfSlots = data [ 2 ] = = 1 ;
var HaveRockSmashSlots = data [ 3 ] = = 1 ;
var HaveFishingSlots = data [ 4 ] = = 1 ;
2017-03-19 12:19:45 +00:00
int offset = 5 ;
var slots = new List < EncounterSlot > ( ) ;
if ( HaveGrassSlots )
2017-06-18 01:37:19 +00:00
slots . AddRange ( GetSlots3 ( data , ref offset , 12 , SlotType . Grass ) ) ;
2017-03-19 12:19:45 +00:00
if ( HaveSurfSlots )
2017-06-18 01:37:19 +00:00
slots . AddRange ( GetSlots3 ( data , ref offset , 5 , SlotType . Surf ) ) ;
2017-03-19 12:19:45 +00:00
if ( HaveRockSmashSlots )
2017-06-18 01:37:19 +00:00
slots . AddRange ( GetSlots3 ( data , ref offset , 5 , SlotType . Rock_Smash ) ) ;
2017-03-19 12:19:45 +00:00
if ( HaveFishingSlots )
2017-06-18 01:37:19 +00:00
slots . AddRange ( GetSlots3_F ( data , ref offset , 10 ) ) ;
2017-03-19 12:19:45 +00:00
Area3 . Slots = slots . ToArray ( ) ;
return Area3 ;
}
2017-06-18 01:37:19 +00:00
private static EncounterArea GetArea4DPPt ( byte [ ] data )
2017-03-19 12:19:45 +00:00
{
EncounterArea Area4 = new EncounterArea ( ) ;
2017-04-07 04:18:02 +00:00
if ( data . Length ! = 0x1AA ) // 426 Bytes
2017-03-19 12:19:45 +00:00
{ Area4 . Location = 0 ; Area4 . Slots = new EncounterSlot [ 0 ] ; return Area4 ; }
var Slots = new List < EncounterSlot > ( ) ;
2017-04-07 04:18:02 +00:00
Area4 . Location = BitConverter . ToUInt16 ( data , 0x00 ) ;
2017-03-19 12:19:45 +00:00
2017-04-07 04:18:02 +00:00
var GrassRatio = BitConverter . ToInt32 ( data , 0x02 ) ;
2017-03-19 12:19:45 +00:00
if ( GrassRatio > 0 )
{
2017-06-18 01:37:19 +00:00
EncounterSlot [ ] GrassSlots = GetSlots4_DPPt_G ( data , 0x06 , 12 , SlotType . Grass ) ;
2017-04-07 05:37:40 +00:00
Slots . AddRange ( GrassSlots ) ;
2017-04-07 04:18:02 +00:00
//Swarming slots replace slots 0 and 1
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4_G_Replace ( data , 0x66 , 4 , GrassSlots , Legal . Slot4_Swarm , SlotType . Swarm ) ) ;
2017-04-07 04:18:02 +00:00
//Morning and Night slots replace slots 2 and 3
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4_G_Replace ( data , 0x6E , 4 , GrassSlots , Legal . Slot4_Time ) ) ; // Morning
Slots . AddRange ( GetSlots4_G_Replace ( data , 0x76 , 4 , GrassSlots , Legal . Slot4_Time ) ) ; // Night
2017-04-07 04:18:02 +00:00
//Pokéradar slots replace slots 4,5,10 and 11
2017-03-20 14:49:05 +00:00
//Pokéradar is marked with different slot type because it have different PID-IV generationn
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4_G_Replace ( data , 0x7E , 4 , GrassSlots , Legal . Slot4_Radar , SlotType . Pokeradar ) ) ;
2017-04-07 04:18:02 +00:00
//24 bytes padding
2017-03-19 12:19:45 +00:00
//Dual Slots replace slots 8 and 9
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4_G_Replace ( data , 0xA6 , 4 , GrassSlots , Legal . Slot4_Dual ) ) ; // Ruby
Slots . AddRange ( GetSlots4_G_Replace ( data , 0xAE , 4 , GrassSlots , Legal . Slot4_Dual ) ) ; // Sapphire
Slots . AddRange ( GetSlots4_G_Replace ( data , 0xB6 , 4 , GrassSlots , Legal . Slot4_Dual ) ) ; // Emerald
Slots . AddRange ( GetSlots4_G_Replace ( data , 0xBE , 4 , GrassSlots , Legal . Slot4_Dual ) ) ; // FireRed
Slots . AddRange ( GetSlots4_G_Replace ( data , 0xC6 , 4 , GrassSlots , Legal . Slot4_Dual ) ) ; // LeafGreen
2017-03-19 12:19:45 +00:00
}
2017-04-07 04:18:02 +00:00
var SurfRatio = BitConverter . ToInt32 ( data , 0xCE ) ;
2017-03-19 12:19:45 +00:00
if ( SurfRatio > 0 )
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4DPPt_WFR ( data , 0xD2 , 5 , SlotType . Surf ) ) ;
2017-04-07 04:18:02 +00:00
//44 bytes padding
2017-03-19 12:19:45 +00:00
2017-04-07 04:18:02 +00:00
var OldRodRatio = BitConverter . ToInt32 ( data , 0x126 ) ;
2017-03-19 12:19:45 +00:00
if ( OldRodRatio > 0 )
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4DPPt_WFR ( data , 0x12A , 5 , SlotType . Old_Rod ) ) ;
2017-03-19 12:19:45 +00:00
2017-04-07 04:18:02 +00:00
var GoodRodRatio = BitConverter . ToInt32 ( data , 0x152 ) ;
2017-03-19 12:19:45 +00:00
if ( GoodRodRatio > 0 )
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4DPPt_WFR ( data , 0x156 , 5 , SlotType . Good_Rod ) ) ;
2017-03-19 12:19:45 +00:00
2017-04-07 04:18:02 +00:00
var SuperRodRatio = BitConverter . ToInt32 ( data , 0x17E ) ;
2017-03-19 12:19:45 +00:00
if ( SuperRodRatio > 0 )
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4DPPt_WFR ( data , 0x182 , 5 , SlotType . Super_Rod ) ) ;
2017-03-19 12:19:45 +00:00
Area4 . Slots = Slots . ToArray ( ) ;
return Area4 ;
}
2017-06-18 01:37:19 +00:00
private static EncounterArea GetArea4HGSS ( byte [ ] data )
2017-03-19 12:19:45 +00:00
{
EncounterArea Area4 = new EncounterArea ( ) ;
2017-04-07 04:18:02 +00:00
if ( data . Length ! = 0xC6 )
2017-03-19 12:19:45 +00:00
{ Area4 . Location = 0 ; Area4 . Slots = new EncounterSlot [ 0 ] ; return Area4 ; }
var Slots = new List < EncounterSlot > ( ) ;
2017-04-07 04:18:02 +00:00
Area4 . Location = BitConverter . ToUInt16 ( data , 0x00 ) ;
var GrassRatio = data [ 0x02 ] ;
var SurfRatio = data [ 0x03 ] ;
var RockSmashRatio = data [ 0x04 ] ;
var OldRodRatio = data [ 0x05 ] ;
var GoodRodRatio = data [ 0x06 ] ;
var SuperRodRatio = data [ 0x07 ] ;
2017-03-19 12:19:45 +00:00
// 2 bytes padding
if ( GrassRatio > 0 )
{
// First 36 slots are morning, day and night grass slots
// The order is 12 level values, 12 morning species, 12 day species and 12 night species
2017-06-18 01:37:19 +00:00
var GrassSlots = GetSlots4_HGSS_G ( data , 0x0A , 12 , SlotType . Grass ) ;
2017-03-20 14:49:05 +00:00
//Grass slots with species = 0 are added too, it is needed for the swarm encounters, it will be deleted after add swarms
Slots . AddRange ( GrassSlots ) ;
2017-03-19 19:27:58 +00:00
// Hoenn Sound and Sinnoh Sound replace slots 4 and 5
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4_G_Replace ( data , 0x5E , 2 , GrassSlots , Legal . Slot4_Sound ) ) ; // Hoenn
Slots . AddRange ( GetSlots4_G_Replace ( data , 0x62 , 2 , GrassSlots , Legal . Slot4_Sound ) ) ; // Sinnoh
2017-03-19 12:19:45 +00:00
}
if ( SurfRatio > 0 )
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4HGSS_WFR ( data , 0x66 , 5 , SlotType . Surf ) ) ;
2017-03-19 12:19:45 +00:00
if ( RockSmashRatio > 0 )
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4HGSS_WFR ( data , 0x7A , 2 , SlotType . Rock_Smash ) ) ;
2017-03-19 12:19:45 +00:00
if ( OldRodRatio > 0 )
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4HGSS_WFR ( data , 0x82 , 5 , SlotType . Old_Rod ) ) ;
2017-03-19 12:19:45 +00:00
if ( GoodRodRatio > 0 )
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4HGSS_WFR ( data , 0x96 , 5 , SlotType . Good_Rod ) ) ;
2017-03-19 12:19:45 +00:00
if ( SuperRodRatio > 0 )
2017-06-18 01:37:19 +00:00
Slots . AddRange ( GetSlots4HGSS_WFR ( data , 0xAA , 5 , SlotType . Super_Rod ) ) ;
2017-03-19 13:38:30 +00:00
2017-04-07 04:18:02 +00:00
// Last 6 bytes only have species ID info
if ( data [ 0xC2 ] = = 120 ) // Location = 182, 127, 130, 132, 167, 188, 210
2017-04-04 03:02:40 +00:00
Slots . AddRange ( SlotsHGSS_Staryu ) ;
2017-03-19 12:19:45 +00:00
Area4 . Slots = Slots . ToArray ( ) ;
return Area4 ;
}
2017-04-04 03:02:40 +00:00
private static readonly EncounterSlot [ ] SlotsHGSS_Staryu =
{
new EncounterSlot { Species = 120 , LevelMin = 20 , LevelMax = 20 , Type = SlotType . Good_Rod } ,
new EncounterSlot { Species = 120 , LevelMin = 40 , LevelMax = 40 , Type = SlotType . Super_Rod } ,
} ;
2017-03-19 12:19:45 +00:00
2017-06-18 01:37:19 +00:00
private static EncounterArea GetArea4HGSS_Headbutt ( byte [ ] data )
2017-03-19 15:23:46 +00:00
{
if ( data . Length < 78 )
2017-03-19 19:27:58 +00:00
return new EncounterArea ( ) ; // bad data
//2 byte location ID (defer to end)
2017-03-19 15:23:46 +00:00
//4 bytes padding
var Slots = new List < EncounterSlot > ( ) ;
// 00-11 Normal trees
// 12-17 Special trees
for ( int i = 0 ; i < 18 ; i + + )
{
2017-03-19 19:27:58 +00:00
int Species = BitConverter . ToInt16 ( data , 6 + i * 4 ) ;
if ( Species < = 0 )
continue ;
Slots . Add ( new EncounterSlot
2017-03-19 15:23:46 +00:00
{
2017-03-19 19:27:58 +00:00
Species = Species ,
LevelMin = data [ 8 + i * 4 ] ,
LevelMax = data [ 9 + i * 4 ] ,
Encounter Type fix and detection of pokemon that should have evolve on trade (#1105)
* Detect encounter trades that evolve on trade and have not been evolved
Detect generation 1 pokemon with special catch rates : krabby trade and Pokemon Stadium
Detect generation 1 pokemon that evolve on trade and have been traded but not evolved
Detect pokemon with tradeback status any but with only encounters from the other GB generation, that means they are WasTradeback
Detect pokemon with moves from the other GB generation, change tradebackstatus to WasTradeback
* Fix dppt surfing and fishing encounter type, is is surfing because the battle background is the same as other surfingfishing encounters
Fix headbutt encounter type, the encounter type depends on the battle background used when battle a pokemon, for headbutt it changes with the player tile, is the player is in a city it will be building encounter, in a grass tile tall grass, in water it is surfingfishing and cave inside a cave. Some locations have more than one possible encounter type, for example routes with trees near the grass, near the water and near non-combat tiles.
Also added slot type headbutt special for the special trees, those trees are all in routes and are only adjacent to non-combat tiles
* Fix encounter type for missing areas with multiple grass encounters types: Mt Coronet, Mt Silver Cave and Stark Mountain (Issue # 1095)
* Fixes and typos
* Check for non-japanese e-reader pokemon, is unreleased
2017-05-01 15:07:20 +00:00
Type = i < = 11 ? SlotType . Headbutt : SlotType . Headbutt_Special
2017-03-19 19:27:58 +00:00
} ) ;
2017-03-19 15:23:46 +00:00
}
2017-03-19 19:27:58 +00:00
return new EncounterArea
{
Location = BitConverter . ToUInt16 ( data , 0 ) ,
Slots = Slots . ToArray ( )
} ;
2017-03-19 15:23:46 +00:00
}
2017-02-12 17:52:26 +00:00
/// <summary>
/// RBY Format Slot Getter from data.
/// </summary>
/// <param name="data">Byte array containing complete slot data table.</param>
/// <param name="ofs">Offset to start reading from.</param>
/// <param name="count">Amount of slots to read.</param>
/// <param name="t">Type of encounter slot.</param>
/// <param name="rate">Slot type encounter rate.</param>
/// <returns>Array of encounter slots.</returns>
2017-06-18 01:37:19 +00:00
private static EncounterSlot1 [ ] ReadSlots ( byte [ ] data , ref int ofs , int count , SlotType t , int rate )
2017-02-12 17:52:26 +00:00
{
EncounterSlot1 [ ] slots = new EncounterSlot1 [ count ] ;
for ( int i = 0 ; i < count ; i + + )
{
int lvl = data [ ofs + + ] ;
int spec = data [ ofs + + ] ;
slots [ i ] = new EncounterSlot1
{
2017-06-16 05:42:43 +00:00
LevelMax = t = = SlotType . Surf ? lvl + 4 : lvl ,
2017-02-12 17:52:26 +00:00
LevelMin = lvl ,
Species = spec ,
Type = t ,
Rate = rate ,
2017-02-27 02:23:29 +00:00
SlotNumber = i ,
2017-02-12 17:52:26 +00:00
} ;
}
return slots ;
}
2017-02-27 02:23:29 +00:00
2017-06-18 01:37:19 +00:00
private static EncounterSlot1 [ ] ReadSlots_FY ( byte [ ] data , ref int ofs , int count , SlotType t , int rate )
2017-04-10 08:02:40 +00:00
{
// Convert byte to actual number
int [ ] Levelbytelist = { 0xFF , 0x15 , 0x67 , 0x1D , 0x3B , 0x5C , 0x72 , 0x16 , 0x71 , 0x18 , 0x00 , 0x6D , 0x80 , } ;
int [ ] dexbytelist = { 0x47 , 0x6E , 0x18 , 0x9B , 0x17 , 0x4E , 0x8A , 0x5C , 0x5D , 0x9D , 0x9E , 0x1B , 0x85 , 0x16 , 0x58 , 0x59 , } ;
int [ ] specieslist = { 060 , 061 , 072 , 073 , 090 , 098 , 099 , 116 , 117 , 118 , 119 , 120 , 129 , 130 , 147 , 148 , } ;
EncounterSlot1 [ ] slots = new EncounterSlot1 [ count ] ;
for ( int i = 0 ; i < count ; i + + )
{
int spec = specieslist [ Array . IndexOf ( dexbytelist , data [ ofs + + ] ) ] ;
int lvl = Array . IndexOf ( Levelbytelist , data [ ofs + + ] ) * 5 ;
slots [ i ] = new EncounterSlot1
{
LevelMax = lvl ,
LevelMin = lvl ,
Species = spec ,
Type = t ,
Rate = rate ,
SlotNumber = i ,
} ;
}
return slots ;
}
2017-02-27 02:23:29 +00:00
/// <summary>
/// Gets the encounter areas with <see cref="EncounterSlot"/> information from Generation 1 Grass/Water data.
/// </summary>
/// <param name="data">Input raw data.</param>
/// <returns>Array of encounter areas.</returns>
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetArray1_GW ( byte [ ] data )
2017-02-12 17:52:26 +00:00
{
// RBY Format
var ptr = new int [ 255 ] ;
int count = 0 ;
for ( int i = 0 ; i < ptr . Length ; i + + )
{
ptr [ i ] = BitConverter . ToInt16 ( data , i * 2 ) ;
if ( ptr [ i ] ! = - 1 )
continue ;
count = i ;
break ;
}
EncounterArea [ ] areas = new EncounterArea [ count ] ;
for ( int i = 0 ; i < areas . Length ; i + + )
{
2017-06-18 01:37:19 +00:00
var grass = GetSlots1_GW ( data , ref ptr [ i ] , SlotType . Grass ) ;
var water = GetSlots1_GW ( data , ref ptr [ i ] , SlotType . Surf ) ;
2017-02-12 17:52:26 +00:00
areas [ i ] = new EncounterArea
{
Location = i ,
Slots = grass . Concat ( water ) . ToArray ( )
} ;
}
return areas . Where ( area = > area . Slots . Any ( ) ) . ToArray ( ) ;
}
2017-02-27 02:23:29 +00:00
/// <summary>
/// Gets the encounter areas with <see cref="EncounterSlot"/> information from Pokémon Yellow (Generation 1) Fishing data.
/// </summary>
/// <param name="data">Input raw data.</param>
/// <returns>Array of encounter areas.</returns>
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetArray1_FY ( byte [ ] data )
2017-02-12 17:52:26 +00:00
{
const int size = 9 ;
int count = data . Length / size ;
EncounterArea [ ] areas = new EncounterArea [ count ] ;
for ( int i = 0 ; i < count ; i + + )
{
int ofs = i * size + 1 ;
areas [ i ] = new EncounterArea
{
Location = data [ i * size + 0 ] ,
2017-06-18 01:37:19 +00:00
Slots = ReadSlots_FY ( data , ref ofs , 4 , SlotType . Super_Rod , - 1 )
2017-02-12 17:52:26 +00:00
} ;
}
return areas ;
}
2017-02-27 02:23:29 +00:00
/// <summary>
/// Gets the encounter areas with <see cref="EncounterSlot"/> information from Generation 1 Fishing data.
/// </summary>
/// <param name="data">Input raw data.</param>
/// <returns>Array of encounter areas.</returns>
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetArray1_F ( byte [ ] data )
2017-02-12 17:52:26 +00:00
{
var ptr = new int [ 255 ] ;
var map = new int [ 255 ] ;
int count = 0 ;
for ( int i = 0 ; i < ptr . Length ; i + + )
{
map [ i ] = data [ i * 3 + 0 ] ;
if ( map [ i ] = = 0xFF )
{
count = i ;
break ;
}
ptr [ i ] = BitConverter . ToInt16 ( data , i * 3 + 1 ) ;
}
EncounterArea [ ] areas = new EncounterArea [ count ] ;
for ( int i = 0 ; i < areas . Length ; i + + )
{
areas [ i ] = new EncounterArea
{
Location = map [ i ] ,
2017-06-18 01:37:19 +00:00
Slots = GetSlots1_F ( data , ref ptr [ i ] )
2017-02-12 17:52:26 +00:00
} ;
}
return areas ;
}
2017-02-27 02:23:29 +00:00
/// <summary>
/// Gets the encounter areas with <see cref="EncounterSlot"/> information from Generation 2 Grass/Water data.
/// </summary>
/// <param name="data">Input raw data.</param>
/// <returns>Array of encounter areas.</returns>
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetArray2_GW ( byte [ ] data )
2017-02-27 02:23:29 +00:00
{
int ofs = 0 ;
var areas = new List < EncounterArea > ( ) ;
2017-06-18 01:37:19 +00:00
areas . AddRange ( GetAreas2 ( data , ref ofs , SlotType . Grass , 3 , 7 ) ) ; // Johto Grass
areas . AddRange ( GetAreas2 ( data , ref ofs , SlotType . Surf , 1 , 3 ) ) ; // Johto Water
areas . AddRange ( GetAreas2 ( data , ref ofs , SlotType . Grass , 3 , 7 ) ) ; // Kanto Grass
areas . AddRange ( GetAreas2 ( data , ref ofs , SlotType . Surf , 1 , 3 ) ) ; // Kanto Water
areas . AddRange ( GetAreas2 ( data , ref ofs , SlotType . Swarm , 3 , 7 ) ) ; // Swarm
areas . AddRange ( GetAreas2 ( data , ref ofs , SlotType . Special , 1 , 3 ) ) ; // Union Cave
2017-02-27 02:23:29 +00:00
return areas . ToArray ( ) ;
}
2017-02-27 05:46:00 +00:00
/// <summary>
/// Gets the encounter areas with <see cref="EncounterSlot"/> information from Generation 2 Grass/Water data.
/// </summary>
/// <param name="data">Input raw data.</param>
/// <returns>Array of encounter areas.</returns>
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetArray2_F ( byte [ ] data )
2017-02-27 05:46:00 +00:00
{
int ofs = 0 ;
2017-06-18 01:37:19 +00:00
var f = GetAreas2_F ( data , ref ofs ) ;
2017-06-12 23:54:39 +00:00
// Fishing Tables are not associated to a single map; a map picks a table to use.
// For all maps that use a table, create a new EncounterArea with reference to the table's slots.
sbyte [ ] convMapIDtoFishLocationID =
{
- 1 , 1 , - 1 , 0 , 3 , 3 , 3 , - 1 , 10 , 3 , 2 , - 1 , - 1 , 2 , 3 , 0 ,
- 1 , - 1 , 3 , - 1 , - 1 , - 1 , 3 , - 1 , - 1 , - 1 , - 1 , 0 , - 1 , - 1 , 0 , 9 ,
1 , 0 , 2 , 2 , - 1 , 3 , 7 , 3 , - 1 , 3 , 4 , 8 , 2 , - 1 , 2 , 1 ,
- 1 , 3 , - 1 , - 1 , - 1 , - 1 , - 1 , 0 , 2 , 2 , - 1 , - 1 , 3 , 1 , - 1 , - 1 ,
- 1 , 2 , - 1 , 2 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 11 , 11 , 0 , - 1 , - 1 , - 1 ,
- 1 , 7 , 0 , 1 , - 1 , 1 , 1 , 3 , - 1 , - 1 , - 1 , 1 , 1 , 2 , 3 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
} ;
var areas = new List < EncounterArea > ( ) ;
for ( int i = 0 ; i < convMapIDtoFishLocationID . Length ; i + + )
{
var loc = convMapIDtoFishLocationID [ i ] ;
if ( convMapIDtoFishLocationID [ i ] = = - 1 ) // no table for map
continue ;
areas . Add ( new EncounterArea { Location = i , Slots = f [ loc ] . Slots } ) ;
}
// Some maps have two tables. Fortunately, there's only two. Add the second table.
areas . Add ( new EncounterArea { Location = 0x1B , Slots = f [ 1 ] . Slots } ) ; // Olivine City (0: Harbor, 1: City)
areas . Add ( new EncounterArea { Location = 0x2E , Slots = f [ 3 ] . Slots } ) ; // Silver Cave (2: Inside, 3: Outside)
return areas . ToArray ( ) ;
2017-03-03 02:24:50 +00:00
}
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetArray2_H ( byte [ ] data )
2017-03-03 02:24:50 +00:00
{
int ofs = 0 ;
2017-06-18 01:37:19 +00:00
return GetAreas2_H ( data , ref ofs ) . ToArray ( ) ;
2017-02-27 05:46:00 +00:00
}
2017-03-19 12:19:45 +00:00
/// <summary>
/// Gets the encounter areas with <see cref="EncounterSlot"/> information from Generation 3 data.
/// </summary>
/// <param name="entries">Raw data, one byte array per encounter area</param>
/// <returns>Array of encounter areas.</returns>
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetArray3 ( byte [ ] [ ] entries )
2017-03-19 12:19:45 +00:00
{
if ( entries = = null )
return null ;
var Areas = new List < EncounterArea > ( ) ;
2017-03-19 17:44:46 +00:00
foreach ( byte [ ] t in entries )
2017-03-19 12:19:45 +00:00
{
2017-06-18 01:37:19 +00:00
EncounterArea Area = GetArea3 ( t ) ;
2017-03-19 12:19:45 +00:00
if ( Area . Slots . Any ( ) )
Areas . Add ( Area ) ;
}
return Areas . ToArray ( ) ;
}
/// <summary>
/// Gets the encounter areas with <see cref="EncounterSlot"/> information from Generation 4 Diamond, Pearl and Platinum data.
/// </summary>
/// <param name="entries">Raw data, one byte array per encounter area</param>
/// <returns>Array of encounter areas.</returns>
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetArray4DPPt ( byte [ ] [ ] entries )
2017-03-19 12:19:45 +00:00
{
2017-06-18 01:37:19 +00:00
return entries ? . Select ( GetArea4DPPt ) . Where ( Area = > Area . Slots . Any ( ) ) . ToArray ( ) ;
2017-03-19 12:19:45 +00:00
}
/// <summary>
/// Gets the encounter areas with <see cref="EncounterSlot"/> information from Generation 4 Hearth Gold and Soul Silver data.
/// </summary>
/// <param name="entries">Raw data, one byte array per encounter area</param>
/// <returns>Array of encounter areas.</returns>
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetArray4HGSS ( byte [ ] [ ] entries )
2017-03-19 12:19:45 +00:00
{
2017-06-18 01:37:19 +00:00
return entries ? . Select ( GetArea4HGSS ) . Where ( Area = > Area . Slots . Any ( ) ) . ToArray ( ) ;
2017-03-19 12:19:45 +00:00
}
2017-03-19 15:23:46 +00:00
/// <summary>
/// Gets the encounter areas with <see cref="EncounterSlot"/> information from Generation 4 Hearth Gold and Soul Silver Headbutt tree data.
/// </summary>
/// <param name="entries">Raw data, one byte array per encounter area</param>
/// <returns>Array of encounter areas.</returns>
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetArray4HGSS_Headbutt ( byte [ ] [ ] entries )
2017-03-19 15:23:46 +00:00
{
2017-06-18 01:37:19 +00:00
return entries ? . Select ( GetArea4HGSS_Headbutt ) . Where ( Area = > Area . Slots . Any ( ) ) . ToArray ( ) ;
2017-03-19 15:23:46 +00:00
}
2017-03-26 08:25:21 +00:00
/// <summary>
/// Gets the encounter areas for the Trophy Garden
/// </summary>
/// <param name="species">List of special species that can exist in the garden.</param>
/// <param name="lvls">Levels of the two encounter slots they can replace. <see cref="GameVersion.DP"/> differs from <see cref="GameVersion.Pt"/></param>
/// <returns></returns>
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetTrophyArea ( IEnumerable < int > species , int [ ] lvls )
2017-03-26 08:25:21 +00:00
{
int [ ] slotnums = { 6 , 7 } ;
var l = new List < EncounterSlot > ( ) ;
foreach ( var s in species )
{
for ( int i = 0 ; i < 2 ; i + + )
{
l . Add ( new EncounterSlot
{
LevelMax = lvls [ i ] ,
LevelMin = lvls [ i ] ,
Species = s ,
SlotNumber = slotnums [ i ] ,
Type = SlotType . Grass
} ) ;
}
}
return new [ ] { new EncounterArea { Location = 68 , Slots = l . ToArray ( ) } } ;
}
2017-03-27 03:23:45 +00:00
/// <summary>
/// Gets the encounter areas for species with same level range and same slottype at same location
/// </summary>
/// <param name="species">List of species that exist in the Area.</param>
/// <param name="lvls">Paired LevelMins and LevelMaxs of the encounter slots.</param>
/// <param name="location">Location index of the encounter area.</param>
/// <param name="t">Encounter slot type of the encounter area.</param>
/// <returns></returns>
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetSimpleEncounterArea ( IEnumerable < int > species , int [ ] lvls , int location , SlotType t )
2017-03-27 03:23:45 +00:00
{
var l = new List < EncounterSlot > ( ) ;
// levels data not paired
if ( ( lvls . Length & 1 ) = = 1 )
return new [ ] { new EncounterArea { Location = location , Slots = l . ToArray ( ) } } ;
foreach ( var s in species )
{
for ( int i = 0 ; i < lvls . Length ; )
{
l . Add ( new EncounterSlot
{
LevelMin = lvls [ i + + ] ,
LevelMax = lvls [ i + + ] ,
Species = s ,
Type = t
} ) ;
}
}
return new [ ] { new EncounterArea { Location = location , Slots = l . ToArray ( ) } } ;
}
2017-10-24 06:12:58 +00:00
/// <summary>
/// Gets an array of areas from an array of raw area data
/// </summary>
/// <param name="entries">Simplified raw format of an Area</param>
/// <returns>Array of areas</returns>
2017-06-18 01:37:19 +00:00
public static EncounterArea [ ] GetArray ( byte [ ] [ ] entries )
2016-11-08 16:43:57 +00:00
{
if ( entries = = null )
return null ;
EncounterArea [ ] data = new EncounterArea [ entries . Length ] ;
for ( int i = 0 ; i < data . Length ; i + + )
data [ i ] = new EncounterArea ( entries [ i ] ) ;
return data ;
}
}
}