Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move natures into their own file #7601

Merged
merged 1 commit into from
Oct 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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}`);
}
Comment on lines +802 to +804
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This belongs in test/data I think. The engine itself doesn't require both, does it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either way, I'd rather test this once for free than every time someone uses Dex.getNature.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh mb

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
Loading