Skip to content

Commit

Permalink
Move natures into their own file (smogon#7601)
Browse files Browse the repository at this point in the history
  • Loading branch information
KrisXV authored and Quanyails committed May 12, 2021
1 parent 2737b9a commit 12386cd
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 61 deletions.
117 changes: 117 additions & 0 deletions data/natures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
export const Natures: {[k: string]: NatureData} = {
adamant: {
name: "Adamant",
plus: 'atk',
minus: 'spa',
},
bashful: {
name: "Bashful",
},
bold: {
name: "Bold",
plus: 'def',
minus: 'atk',
},
brave: {
name: "Brave",
plus: 'atk',
minus: 'spe',
},
calm: {
name: "Calm",
plus: 'spd',
minus: 'atk',
},
careful: {
name: "Careful",
plus: 'spd',
minus: 'spa',
},
docile: {
name: "Docile",
},
gentle: {
name: "Gentle",
plus: 'spd',
minus: 'def',
},
hardy: {
name: "Hardy",
},
hasty: {
name: "Hasty",
plus: 'spe',
minus: 'def',
},
impish: {
name: "Impish",
plus: 'def',
minus: 'spa',
},
jolly: {
name: "Jolly",
plus: 'spe',
minus: 'spa',
},
lax: {
name: "Lax",
plus: 'def',
minus: 'spd',
},
lonely: {
name: "Lonely",
plus: 'atk',
minus: 'def',
},
mild: {
name: "Mild",
plus: 'spa',
minus: 'def',
},
modest: {
name: "Modest",
plus: 'spa',
minus: 'atk',
},
naive: {
name: "Naive",
plus: 'spe',
minus: 'spd',
},
naughty: {
name: "Naughty",
plus: 'atk',
minus: 'spd',
},
quiet: {
name: "Quiet",
plus: 'spa',
minus: 'spe',
},
quirky: {
name: "Quirky",
},
rash: {
name: "Rash",
plus: 'spa',
minus: 'spd',
},
relaxed: {
name: "Relaxed",
plus: 'def',
minus: 'spe',
},
sassy: {
name: "Sassy",
plus: 'spd',
minus: 'spe',
},
serious: {
name: "Serious",
},
timid: {
name: "Timid",
plus: 'spe',
minus: 'atk',
},
};
4 changes: 1 addition & 3 deletions server/chat-plugins/othermetas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,7 @@ export const commands: ChatCommands = {
dex = Dex.mod(format.mod);
}
if (!toID(nature) || !toID(pokemon)) return this.parse(`/help natureswap`);
const natureObj: {
name: string, plus?: string | undefined, minus?: string | undefined, exists?: boolean,
} = dex.getNature(nature);
const natureObj = dex.getNature(nature);
if (dex.gen < 3) return this.errorReply(`Error: Natures don't exist prior to Generation 3.`);
if (!natureObj.exists) return this.errorReply(`Error: Nature ${nature} not found.`);
const species = Utils.deepClone(dex.getSpecies(pokemon));
Expand Down
16 changes: 16 additions & 0 deletions sim/dex-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,22 @@ export class Move extends BasicEffect implements Readonly<BasicEffect & MoveData
}
}

export class Nature extends BasicEffect implements Readonly<BasicEffect & NatureData> {
readonly effectType: 'Nature';
readonly plus?: StatNameExceptHP;
readonly minus?: StatNameExceptHP;
constructor(data: AnyObject, ...moreData: (AnyObject | null)[]) {
super(data, moreData);
data = this;

this.fullname = `nature: ${this.name}`;
this.effectType = 'Nature';
this.gen = 3;
this.plus = data.plus || undefined;
this.minus = data.minus || undefined;
}
}

type TypeInfoEffectType = 'Type' | 'EffectType';

export class TypeInfo implements Readonly<TypeData> {
Expand Down
83 changes: 29 additions & 54 deletions sim/dex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,6 @@ const DATA_FILES = {

const nullEffect: Condition = new Data.Condition({name: '', exists: false});

export interface Nature {
name: string;
plus?: StatNameExceptHP;
minus?: StatNameExceptHP;
[k: string]: any;
}

interface DexTableData {
Abilities: DexTable<Ability>;
Aliases: {[id: string]: string};
Expand All @@ -84,7 +77,7 @@ interface DexTableData {
Items: DexTable<Item>;
Learnsets: DexTable<LearnsetData>;
Moves: DexTable<Move>;
Natures: DexTable<Nature>;
Natures: DexTable<NatureData>;
Pokedex: DexTable<Species>;
Scripts: DexTable<AnyObject>;
Conditions: DexTable<EffectData>;
Expand All @@ -98,33 +91,6 @@ interface TextTableData {
Default: AnyObject;
}

const Natures: {[k: string]: Nature} = {
adamant: {name: "Adamant", plus: 'atk', minus: 'spa'},
bashful: {name: "Bashful"},
bold: {name: "Bold", plus: 'def', minus: 'atk'},
brave: {name: "Brave", plus: 'atk', minus: 'spe'},
calm: {name: "Calm", plus: 'spd', minus: 'atk'},
careful: {name: "Careful", plus: 'spd', minus: 'spa'},
docile: {name: "Docile"},
gentle: {name: "Gentle", plus: 'spd', minus: 'def'},
hardy: {name: "Hardy"},
hasty: {name: "Hasty", plus: 'spe', minus: 'def'},
impish: {name: "Impish", plus: 'def', minus: 'spa'},
jolly: {name: "Jolly", plus: 'spe', minus: 'spa'},
lax: {name: "Lax", plus: 'def', minus: 'spd'},
lonely: {name: "Lonely", plus: 'atk', minus: 'def'},
mild: {name: "Mild", plus: 'spa', minus: 'def'},
modest: {name: "Modest", plus: 'spa', minus: 'atk'},
naive: {name: "Naive", plus: 'spe', minus: 'spd'},
naughty: {name: "Naughty", plus: 'atk', minus: 'spd'},
quiet: {name: "Quiet", plus: 'spa', minus: 'spe'},
quirky: {name: "Quirky"},
rash: {name: "Rash", plus: 'spa', minus: 'spd'},
relaxed: {name: "Relaxed", plus: 'def', minus: 'spe'},
sassy: {name: "Sassy", plus: 'spd', minus: 'spe'},
serious: {name: "Serious"},
timid: {name: "Timid", plus: 'spe', minus: 'atk'},
};
export const toID = Data.toID;

// function for merging the two lists
Expand Down Expand Up @@ -199,6 +165,7 @@ export class ModdedDex {
readonly learnsetCache: Map<ID, LearnsetData>;
readonly moveCache: Map<ID, Move>;
readonly speciesCache: Map<ID, Species>;
readonly natureCache: Map<ID, Nature>;
readonly typeCache: Map<string, TypeInfo>;

gen: number;
Expand Down Expand Up @@ -227,6 +194,7 @@ export class ModdedDex {
this.moveCache = new Map();
this.learnsetCache = new Map();
this.speciesCache = new Map();
this.natureCache = new Map();
this.typeCache = new Map();

this.gen = 0;
Expand Down Expand Up @@ -813,19 +781,29 @@ export class ModdedDex {

name = (name || '').trim();
const id = toID(name);
let nature: Nature = {} as Nature;
if (id && id !== 'constructor' && this.data.Natures[id]) {
nature = this.data.Natures[id];
if (nature.cached) return nature;
nature.cached = true;
nature.exists = true;
}
if (!nature.id) nature.id = id;
if (!nature.name) nature.name = name;
nature.toString = this.effectToString;
if (!nature.effectType) nature.effectType = 'Nature';
if (!nature.gen) nature.gen = 3;
let nature = this.natureCache.get(id);
if (nature) return nature;
if (this.data.Aliases.hasOwnProperty(id)) {
nature = this.getNature(this.data.Aliases[id]);
if (nature.exists) {
this.natureCache.set(id, nature);
}
return nature;
}
if (id && this.data.Natures.hasOwnProperty(id)) {
const natureData = this.data.Natures[id];
nature = new Data.Nature(natureData);
if (nature.gen > this.gen) nature.isNonstandard = 'Future';
} else {
nature = new Data.Nature({id, name, exists: false});
}

if (nature.exists) {
if (!!nature.plus !== !!nature.minus) {
throw new Error(`Nature with a '${nature.plus ? 'plus' : 'minus'}' property but no '${nature.plus ? 'minus' : 'plus'}' property: ${nature.name}`);
}
this.natureCache.set(id, nature);
}
return nature;
}

Expand Down Expand Up @@ -1046,7 +1024,7 @@ export class ModdedDex {
if (id === 'unreleased') return 'unreleased';
if (id === 'nonexistent') return 'nonexistent';
const matches = [];
let matchTypes = ['pokemon', 'move', 'ability', 'item', 'pokemontag'];
let matchTypes = ['pokemon', 'move', 'ability', 'item', 'nature', 'pokemontag'];
for (const matchType of matchTypes) {
if (rule.startsWith(`${matchType}:`)) {
matchTypes = [matchType];
Expand All @@ -1063,6 +1041,7 @@ export class ModdedDex {
case 'move': table = this.data.Moves; break;
case 'item': table = this.data.Items; break;
case 'ability': table = this.data.Abilities; break;
case 'nature': table = this.data.Natures; break;
case 'pokemontag':
// valid pokemontags
const validTags = [
Expand All @@ -1075,7 +1054,7 @@ export class ModdedDex {
// illegal/nonstandard reasons
'past', 'future', 'unobtainable', 'lgpe', 'custom',
// all
'allpokemon', 'allitems', 'allmoves', 'allabilities',
'allpokemon', 'allitems', 'allmoves', 'allabilities', 'allnatures',
];
if (validTags.includes(ruleid)) matches.push('pokemontag:' + ruleid);
continue;
Expand Down Expand Up @@ -1144,7 +1123,7 @@ export class ModdedDex {
searchResults.push({
isInexact,
searchType: searchTypes[table],
name: res.species ? res.species : res.name,
name: res.name,
});
}
}
Expand Down Expand Up @@ -1511,10 +1490,6 @@ export class ModdedDex {
}

for (const dataType of DATA_TYPES.concat('Aliases')) {
if (dataType === 'Natures' && this.isBase) {
dataCache[dataType] = Natures;
continue;
}
const BattleData = this.loadDataFile(basePath, dataType);
if (BattleData !== dataCache[dataType]) dataCache[dataType] = Object.assign(BattleData, dataCache[dataType]);
if (dataType === 'Formats' && !parentDex) Object.assign(BattleData, this.formats);
Expand Down
12 changes: 11 additions & 1 deletion sim/global-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ type ModdedEffectData = EffectData | Partial<EffectData> & {inherit: true};

type EffectType =
'Condition' | 'Pokemon' | 'Move' | 'Item' | 'Ability' | 'Format' |
'Ruleset' | 'Weather' | 'Status' | 'Rule' | 'ValidatorRule';
'Nature' | 'Ruleset' | 'Weather' | 'Status' | 'Rule' | 'ValidatorRule';

interface BasicEffect extends EffectData {
id: ID;
Expand Down Expand Up @@ -1181,6 +1181,16 @@ type ModdedLearnsetData = LearnsetData & {inherit?: true};

type Species = import('./dex-data').Species;

interface NatureData {
name: string;
plus?: StatNameExceptHP;
minus?: StatNameExceptHP;
}

type ModdedNatureData = NatureData | Partial<Omit<NatureData, 'name'>> & {inherit: true};

type Nature = import('./dex-data').Nature;

type GameType = 'singles' | 'doubles' | 'triples' | 'rotation' | 'multi' | 'free-for-all';
type SideID = 'p1' | 'p2' | 'p3' | 'p4';

Expand Down

0 comments on commit 12386cd

Please sign in to comment.