This is a huge refactor that consolidates many different places event,
DW, and VC moves are validated, so that they're now validated in the
single place Validator#validateEvent. DW and VC moves are now treated
as special cases of events.
Validator#checkLearnset now does zero validation of event, DW, and VC
moves; it now simply passes the list of possible sources back to
Validator#validateSet, and it's validateSet's job to determine if the
Pokemon meets the requirements for any of those sources.
(In addition to simplifying checkLearnset, this also means more
useful error messages if you fail to meet the requirements for an
event move or DW move.)
validateSet should also be a decent margin simpler, due to a lot of
its code being folded into validateEvent.
Changed "/scavenge <em>guess</em>" to "/scavenge _______" in the /scavengerhelp command. Especially considering UGM is beginning effective today-ish, helps make the command more clear to new users and get them acclimatized to the room. There has been recurring issue for a long time of new users believing that they need to type "/scavenge guess [their answer]" instead of "/scavenge [their answer]," the latter of which is correct.
Virtual Console validation wasn't happening for Pokemon who learn a
move from Virtual Console from multiple Pokemon in its evo family.
This is most relevant for No Guard Fissure Machamp, which shouldn't
be legal.
This adds validator support for Gen 1 Virtual Console moves.
Fixes#3208
If anyone wants the quick-and-dirty eval script I used to update
Learnsets:
```
Object.entries(Tools.mod('gen1').data.Learnsets).forEach(([speciesid, lset]) => {
Object.entries(lset.learnset).forEach(([moveid, sources]) => {
if (sources.some(s => s.startsWith('1L') || s.startsWith('1M'))) {
let newLset = Tools.data.Learnsets[speciesid].learnset;
if (!newLset[moveid]) newLset[moveid] = [];
let i = 0;
while (i < newLset[moveid].length && newLset[moveid][i].startsWith('7')) i++;
newLset[moveid].splice(i, 0, '7V');
}
})
})
```
No one has reported its brokenness in ever! I guess I'm the only one
who scripts learnset changes with /eval...
Coming up next: A learnset change scripted using /eval!
This enables battles in tests to reset their RNG to what it originally
was when they were created. A number of tests do this already by
breaking encapsulating and modifying the prng variable directly. This
should fix that.
We also remove createBattleWithPRNG and min/maxSeed properties.
Firstly, the tests that were still using the maxSeed property were
setting it to Battle.seed which has no effect since the PRNG class does
not look at this property any more - so these were no-ops.
After removing this property from tests, maxRollSeed was never used, so
I removed it and renamed minRollSeed to DEFAULT_ROLL_SEED (since it's
constant).
The places that were still using minRollSeed also were no-ops or were
using createBattleWithPRNG. Since every single instance was actually
just using the same code, I removed createBattleWithPRNG and made
createBattle default to giving you a seed with DEFAULT_ROLL_SEED and
removed the minRollSeed property too.
This makes tests much simpler and reduces the usage surface of
TestTools; now, you must define your *own* seed if you're making a PRNG
for a test, or you use one that TestTools gives you; you may not use a
public property that TestTools gives you.
We also remove the code that removes a listener in the Battle Engine.
This was rendered obsolete by f6a7c4b (see more info [in the discussion
on github][disc]
[disc]:
https://github.com/Zarel/Pokemon-Showdown/pull/3272#discussion_r102414795
This removes the 'deterministic test' tools by preventing action at a
distance (namely, preventing the modification of the `init` method in
`Battle` during tests). This action at a distance is incredibly
confusing.
All this action at a distance did was discard any parameters that were
passed to `Battle` that weren't the first three (which was probably a
mistake by the original author) and also hard code `this.seed` and
`this.startingSeed` in `Battle`.
This functionality has now been moved to the `PRNG` class, so instead
users should pass a `PRNG` to `Battle` as the 5th constructor argument.
Users can also pass one as the third argument to `common.createBattle`
or use `common.createBattleWithPRNG` with the PRNG as the first
argument.
The PRNG is just an encapsulation of the pseudo-random algorithm in a
class. It is stateful, so make sure to take a `clone()` of the PRNG if
you want to re-use it.
Now that we now store Hidden Power type separately from IVs, we can
make some major changes to how Hidden Power is validated.
Instead of Hidden Power type being calculated from the IVs, it's now
sent separately as part of the set. This allows us to warn in the
validator if the Hidden Power type specified by the moveset is
different from the one calculated from the IVs, and give a validation
error if so.
This also allows us to validate the Hidden Power type (pre-bottle-cap
IVs) separately from the set IVs (post-bottle-cap IVs) when doing
event validation, which fixes some validation issues relating to
Hidden Power.
Hidden Power was previously in BattlePokemon's constructor, but it's
been moved to Tools where the calculation can be accessed externally
(relevant for team-validator).
We now add split limits to the uses of String#split in fastUnpackTeam.
This helps slightly improve performance in certain weird scenarios, but
mostly isn't particularly consequential.
Previously, "requirePentagon" meant "only allow current-gen Pokemon".
Now, "requirePentagon" means "allow Gen 6 Pokemon and later", and
"requirePlus" means "allow Gen 7 Pokemon and later".