In particular, it only activates after all hits in a multi-hit move are performed, and
it won't activate if the move is boosted by Sheer Force.
This commit also implements the interactions of Emergency Exit
with Eject Button and Red Card, and adds tests.
This makes gen 7 the default mod, updates the tests to match, and fixes
the corresponding build error.
Note that this only changes the default Tools mod, the default Formats
mod is now gen6. gen7 must be specified by name in a format, for that
format to be a gen 7 format.
Sometimes mods would mess up if they were loaded in the wrong order.
Specifically, some autogenerated properties of e.g. moves need to be
recalculated for mods.
Anyway, the entire cache system is replaced with a newer, faster,
slightly-more-memory-intensive-but-only-slightly cache system, which
no longer has these kinds of loading order issues.
Battle is now an ES6 class... mostly... it's complicated.
Battle's inheritance system has always been a mess. I tried to redo it
in a sensible way but it caused nondeterministic test failures. Not
even kidding; different things would fail each time I ran tests, even
without code changes. I'll investigate closer later, but this refactor
makes it use ES6 classes with only a small amount of hacking, which is
good enough. It is, at the very least, simpler than the previous mess.
BattleEngine.Battle.construct has been renamed BattleEngine.construct.
Tools will be renamed to Dex soon, which is why the code inside Tools
is calling itself "Dex" now, but right now we're just refactoring its
internal code and not officially renaming it yet.
In the meantime, Tools is now an ES6 Class.
A long-standing bug in learnset loading order (the one
test/chat-plugins/datasearch.js tests for) has finally been fixed, so
Tools.includeMods() is no longer necessary to accurately access modded
data.
Tools.mod has been split into Tools.mod(modid) and
Tools.format(format). The issue of Tools.mod being ambiguous about
whether it's passed a mod or a format hasn't been a _bug_ for a while,
but this is still more readable.
Other renames include:
Tools#isLoaded -> Tools#dataLoaded
Tools.includeMods() -> Tools.includeModData()
Tools.preloadMods() -> Tools.includeMods()
Tools.preloadedMods -> Tools.modsLoaded
Tools.moddedTools -> Tools.dexes
Do not just rename your calls of Tools.includeMods() to
Tools.includeModData(). With the learnset loading bug fixed, there's
no reason to use it unless you need direct access to
Tools.dexes[...].data for some reason (you don't, just use
Tools.mod(...).data)
simulator.js doesn't actually contain the simulator, but is really just
an implementation of battles in the RoomGame interface.
Renames:
`Simulator.Battle` -> `Rooms.RoomBattle`
`Simulator.BattlePlayer` -> `Rooms.RoomBattlePlayer`
`Simulator.SimulatorManager` -> `Rooms.SimulatorManager`
`Simulator.SimulatorProcess` -> `Rooms.SimulatorProcess`
`Simulator.create` -> no longer exists, use `new Rooms.RoomBattle(...)`
Replacing direct references to the arguments object of functions with rest
parametres prevents the function from being deoptimized while still allowing
use of arbitrary arguments. This may also fix some minor memory leaks related
to mishandling the arguments object.
We had a lot of discussion in Dev and a somewhat-close poll, but in
the end "Chat" was a better name than "Messages", and also has the
advantage of being shorter (which is nice for Chat.html and
Chat.plural which should be short).
The following functions have been renamed:
- Tools.html to CommandParser.html
- Tools.plural to CommandParser.plural
- Tools.escapeHTML to CommandParser.escapeHTML
- Tools.toDurationString to CommandParser.toDurationString
- Tools.toTimeStamp to CommandParser.toTimestamp
(notice the lowercase 's')
This is in preparation for a rename of Tools to Dex (by removing the
non-dex-related functions) and a rename of CommandParser to either
Messages or Chat.
Before, an options object containing properties and values to be used
was how decorated instances of the class would be created. This meant
the constructor could assign anything you feel like to `this`. Rather
than that, the constructor now assigns a strict set of values, and
methods are redefined in subclasses.
Basic unit tests were added to test if they could be written for after
the final refactor to fix the other memory leak here.
User#games no longer retains games; it instead gets them from
Rooms(roomid).game.
The Trivia tests needed to be fixed for fidelity to continue passing.
Connection#rooms, previously a null-prototype roomid:room Object,
is now Connection#inRooms, a roomid Set.
This, incidentally, makes it stop retaining rooms, which may make the
GC's job easier and may also lead to unexpected bugs if we get
inconsistent state (we often do get inconsistent state, so look
forward to that!)
The rename is mostly to put it in line with the new User#inRooms,
and for ease of greppability without running into Rooms.rooms.
Part 1 of the rewrite for the entire plugin
This is the rewrite of the classes and commands that handle running
trivia games. Several bugs that happened when running trivia games were
fixed, and unit tests were added to help keep them gone.
Updated remaining Primal Weathers to the new APIs.
Updated misleading test cases relating to base power of moves in
Desolate Land / Primordial Sea.
Increased coverage on weather tests.
- Implements `skip` choice, which acts as a placeholder in the player
choices. This is relevant to double-KOs, since in-game you are allowed
to specify switch-ins in any order.
Among the added tests, are included:
- A skipped test for an edge case in which usage of Reflect Type
causes a typing information leak via the presence/absence of the
"maybe-trapped" warning and cancel prevention.
- Two skipped tests related to partial decisions functionality.
- Basically, support is added only for `move` requests here, and
behind a flag (`battle.supportsPartialDecision`).
- Switching is mostly supported, except for the multiple-KOs case.
- Team Preview needs a rework in order to enable this feature.
Among the newly added rules, there are quite a few intended to enforce
compliance of CONTRIBUTING.md-blessed idioms, as well as ensure
safe usage of classes and constant bindings.
We are also now enforcing usage of early return in commands.js,
which has 100% compliance as of fd2c45c.
This fixes its interaction with Clear Smog because Hit handlers for
moves always activate before all other global event handlers.
Removed the Hit event from the list of events stopped by Mold Breaker
variants as there are no abilities that would be negated by it that
use that handler.
The ModifyMove singleEvent for moves always runs before the
larger event that triggers an ability's event handler and
take precedence over Normalize, so we code exceptions in
Normalize to not change the type in those situations.
Conveniently, all the moves that change type right now are
defaulted to Normal-type, and since Normalize technically
won't change the type of any Normal-type move, we're using
that as the guideline for our exception.
BattlePokemon#runImmunity is now two functions, runImmunity and
runStatusImmunity.
The split is helpful because: 1. NegateImmunity only applies to type
immunities, and 2. Immunity only applies to status immunities and
Ground immunities.
Ground immunities are now entirely handled hardcoded in isGrounded.
This overall doesn't have a noticeable impact on performance, but
it makes certain things behave more predictably, and correctly
shows the ability activation for Levitate, so I assume that means it's
a net positive. I hope I at least improved readability...
The unwieldy system that is typesData is now removed, and is replaced by
the array `types` and the string `addedType`, which track the same amount
of information in a much more efficient way. (Roost is now hardcoded, but
let's not talk about that.)
Incidentally, this now roughly matches client, which tracks typechange
and typeadd as volatiles.
This allows us to remove ModifyPokemon, which overall provides a 10%
performance increase. I was hoping it'd be more substantial, but oh well.
Now that nodejs/node#3072 is mostly fixed, we can finally start using
Node 4+ features.
This refactor:
- uses arrow functions where appropriate
Note that arrow functions still aren't used in Mocha, where `this`
is sometimes meaningful.
This also removes the need for .bind() nearly everywhere, as well
as the `self = this` trick.
- refactors Validator and Connection into ES6 classes
- no longer uses Array#forEach for iterating arrays
We strongly prefer for (let i = 0; i < arr.length; i++) because of
performance reasons. Most forEaches have been replaced with for..of,
though, which is 5x slower than the long-form loop but 2x faster
than forEach, which is good enough outside of most inner loops.
The only exception is tournaments, which is due for a more invasive
refactor soon anyway.
Curse now correctly updates what target it asks for when the user
changes type.
The only remaining targeting issue is when the user changes to
Ghost-type mid-turn in Doubles.
In-game, you can see your opponent's pokemon represented as balls, with
statused pokemon being dark balls. Because of this, light balls are
clearly not statused, which allows you to know when a pokemon has
Natural Cure.
The only exception is in Doubles/Triples, where multiple pokemon that
are statused but could have Natural Cure switch out at the same time,
but not all of them have Natural Cure: it's not possible to know which
pokemon had Natural Cure.
This exception is now handled correctly.
Fixes#1452
Previously, include('./sockets.js') and include('./app.js') would
automatically spawn listener processes.
Now, you have to actually use .listen() to spawn listener processes.
This makes the testing framework simpler, since it no longer needs an
ugly hack to suppress spawning socket processes, and also makes it
easier for the ./pokemon-showdown "binary" to pass a port to app.js.
./pokemon-showdown will now also install dependencies if necessary.