Gotta git gud

This commit is contained in:
Deukhoofd 2016-02-20 00:54:42 +01:00
parent 19558607f3
commit 1114909caf
32 changed files with 401 additions and 121 deletions

View File

@ -26,7 +26,6 @@ $ ->
Conditions.SPECIES_CLAUSE
Conditions.OHKO_CLAUSE
Conditions.PRANKSTER_SWAGGER_CLAUSE
Conditions.UNRELEASED_BAN
Conditions.TIMED_BATTLE
]

View File

@ -14,7 +14,6 @@ HiddenPower = (if module? then require('../../../../shared/hidden_power') else w
[ all, pokemonLine, gender, item ] = line.match(pokemonRegex)
pokemon = {}
team.push(pokemon)
if pokemonLine.match(/(.*?)\s*\((.*)\)/)
pokemon.name = RegExp.$1
pokemonLine = RegExp.$2
@ -30,7 +29,7 @@ HiddenPower = (if module? then require('../../../../shared/hidden_power') else w
if pokemon.ability is oldability
pokemon.ability = newability
else if line.match(/^Level:\s+(.*)$/i)
pokemon.level = Number(RegExp.$1) || 100
pokemon.level = Number(RegExp.$1) || 120
else if line.match(/^Happiness:\s+(.*)$/i)
pokemon.happiness = Number(RegExp.$1) || 0
else if line.match(/^Shiny: Yes$/i)
@ -105,7 +104,7 @@ HiddenPower = (if module? then require('../../../../shared/hidden_power') else w
s.push("#{pokemon.nature} nature") if pokemon.nature
# Level
s.push("Level: #{pokemon.level}") if pokemon.level && pokemon.level != 100
s.push("Level: #{pokemon.level}") if pokemon.level && pokemon.level != 120
# Shiny
s.push("Shiny: Yes") if pokemon.shiny

View File

@ -45,7 +45,7 @@ class @Pokemon extends Backbone.Model
@set('ivs', ivs, silent: true)
@set('ability', @getAbilities()[0]) unless attributes.ability
@set('level', 100) unless attributes.level
@set('level', @getGeneration.maxLevel) unless attributes.level
@set('happiness', 100) if isNaN(attributes.happiness)
@set('nature', 'Hardy') unless attributes.nature
hiddenPowerType = HiddenPower.BW.type(@get('ivs')).toLowerCase()
@ -66,7 +66,6 @@ class @Pokemon extends Backbone.Model
speed: 0
accuracy: 0
evasion: 0
normalizeStats: (hash, defaultValue) ->
stats = [ "hp", "attack", "defense", "specialAttack",
"specialDefense", "speed"]
@ -180,7 +179,7 @@ class @Pokemon extends Backbone.Model
stat: (key) ->
base = @base(key)
return 1 if base == 1 # For Shedinja. key doesn't have to be hp.
level = @get('level') || 100
level = @get('level') || @getGeneration.maxLevel
iv = @iv(key)
ev = Math.floor(@ev(key) / 4)
total = if key == 'hp'

View File

@ -165,7 +165,14 @@ class @PokemonEditView extends Backbone.View
changeItem: (e) =>
$list = $(e.currentTarget)
@pokemon.set("item", $list.val())
item = $list.val()
{ItemData} = @generation
itemdata = ItemData[item]
@pokemon.set("item", item)
if typeof itemdata.itemForme != 'undefined' and itemdata.itemForme[0] is @pokemon.get('species')
@pokemon.set('forme', itemdata.itemForme[1])
else if typeof @pokemon.getForme().isItemBased != 'undefined' and @pokemon.getForme().isItemBased
@pokemon.set('forme', 'default')
changeGender: (e) =>
$list = $(e.currentTarget)
@ -174,7 +181,7 @@ class @PokemonEditView extends Backbone.View
changeLevel: (e) =>
$input = $(e.currentTarget)
value = parseInt($input.val(), 10)
value = 1120 if isNaN(value) || value > 120
value = @generation.maxLevel if isNaN(value) || value > @generation.maxLevel
value = 1 if value < 1
$input.val(value)
@pokemon.set("level", value)

View File

@ -22,7 +22,7 @@ html
li
a(href="../") Simulator
li
a(href="//91.121.152.74/", target="_blank") Forums
a(href="//forums.p-insurgence.com/", target="_blank") Forums
li
a(href="../leaderboard", target="_blank") Leaderboard
#sub-nav

View File

@ -10,10 +10,9 @@ a.sprite.preload(href=pokemon.getPokedexUrl(), target='_blank', data-species = p
span.gender.gender_female &#9792;
else if pokemon.get('gender') === 'M'
span.gender.gender_male &#9794;
if pokemon.get('level') != 120
span.pokemon-level
span.pokemon-level-text Lv.
= pokemon.get('level')
span.pokemon-level
span.pokemon-level-text Lv.
= pokemon.get('level')
.hp-text #{percent}%
.hp(style = greenStyle)
.hp-gradient

View File

@ -36,7 +36,7 @@ mixin displayPokemon(pokemon, i)
.gender.gender_female &#9792;
else if pokemon.get('gender') === 'M'
.gender.gender_male &#9794;
if pokemon.get('level') != 100
if pokemon.get('level') != 120
.level Lv.#{pokemon.get('level')}
.battle_teams

View File

@ -10,7 +10,7 @@ ul.nav
a(href="/replays", target="_blank").nav_item Your Replays
a(href="/leaderboard/", target="_blank").nav_item Leaderboard
a(href="//bitbucket.org/PInsurgence/battle-simulator/issues?status=new&status=open", target="_blank").nav_item Bug Reports
a(href="//91.121.152.74/c/battle-simulator/feature-requests", target="_blank").nav_item Feature Requests
a(href="//forums.p-insurgence.com/c/battle-simulator/feature-requests", target="_blank").nav_item Feature Requests
ul.nav.nav_battles.hidden

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -754,7 +754,7 @@
looper = loopLearnsets.bind(null, Generations, pokemon, generation);
pokemonSpecies = pokemon.species;
pokemonForme = pokemon.forme || "default";
pokemonLevel = pokemon.level || 100;
pokemonLevel = pokemon.level || generation.maxLevel;
FormeData = Generations[getGenerationFromInt(generation)].FormeData;
forme = FormeData[pokemonSpecies][pokemonForme];
if (generation === 4) {
@ -877,7 +877,7 @@
checkMove = function(looper, pokemon, move) {
var checksOut, level;
level = pokemon.level;
level || (level = 100);
level || (level = 120);
checksOut = looper(function(learnset) {
var _ref1, _ref2, _ref3, _ref4;
if (((_ref1 = learnset["level-up"]) != null ? _ref1[move] : void 0) <= level || ((_ref2 = learnset["machine"]) != null ? _ref2[move] : void 0) <= level || ((_ref3 = learnset["tutor"]) != null ? _ref3[move] : void 0) <= level) {
@ -993,7 +993,8 @@
}).call(this);
(function() {
var Tiers, actualtiers, conditions, self, _, _base, _ref;
var Tiers, actualtiers, conditions, self, _, _base, _ref,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
self = (typeof window !== "undefined" && window !== null ? (_base = window.PokeBattle).Tier != null ? _base.Tier : _base.Tier = {} : this);
@ -1093,6 +1094,9 @@
forme = megaForme;
}
}
if (species === "Rayquaza" && (pokemon.moves != null) && __indexOf.call(pokemon.moves, "Dragon Ascent") >= 0) {
forme = "mega";
}
tier = (speciesData != null ? (_ref2 = speciesData[forme]) != null ? _ref2.tier[0] : void 0 : void 0) || 'Unsorted';
tierdata = actualtiers[tier];
if (typeof tierdata === 'undefined') {
@ -1523,7 +1527,7 @@
this.set('ability', this.getAbilities()[0]);
}
if (!attributes.level) {
this.set('level', 100);
this.set('level', this.getGeneration.maxLevel);
}
if (isNaN(attributes.happiness)) {
this.set('happiness', 100);
@ -1738,7 +1742,7 @@
if (base === 1) {
return 1;
}
level = this.get('level') || 100;
level = this.get('level') || this.getGeneration.maxLevel;
iv = this.iv(key);
ev = Math.floor(this.ev(key) / 4);
return total = key === 'hp' ? Math.floor((2 * base + iv + ev) * (level / 100) + level + 10) : Math.floor(((2 * base + iv + ev) * (level / 100) + 5) * this.natureBoost(key));
@ -5717,9 +5721,17 @@
};
PokemonEditView.prototype.changeItem = function(e) {
var $list;
var $list, ItemData, item, itemdata;
$list = $(e.currentTarget);
return this.pokemon.set("item", $list.val());
item = $list.val();
ItemData = this.generation.ItemData;
itemdata = ItemData[item];
this.pokemon.set("item", item);
if (typeof itemdata.itemForme !== 'undefined' && itemdata.itemForme[0] === this.pokemon.get('species')) {
return this.pokemon.set('forme', itemdata.itemForme[1]);
} else if (typeof this.pokemon.getForme().isItemBased !== 'undefined' && this.pokemon.getForme().isItemBased) {
return this.pokemon.set('forme', 'default');
}
};
PokemonEditView.prototype.changeGender = function(e) {
@ -5732,8 +5744,8 @@
var $input, value;
$input = $(e.currentTarget);
value = parseInt($input.val(), 10);
if (isNaN(value) || value > 120) {
value = 1120;
if (isNaN(value) || value > this.generation.maxLevel) {
value = this.generation.maxLevel;
}
if (value < 1) {
value = 1;
@ -10279,7 +10291,7 @@
}
}
} else if (line.match(/^Level:\s+(.*)$/i)) {
pokemon.level = Number(RegExp.$1) || 100;
pokemon.level = Number(RegExp.$1) || 120;
} else if (line.match(/^Happiness:\s+(.*)$/i)) {
pokemon.happiness = Number(RegExp.$1) || 0;
} else if (line.match(/^Shiny: Yes$/i)) {
@ -10394,7 +10406,7 @@
if (pokemon.nature) {
s.push("" + pokemon.nature + " nature");
}
if (pokemon.level && pokemon.level !== 100) {
if (pokemon.level && pokemon.level !== 120) {
s.push("Level: " + pokemon.level);
}
if (pokemon.shiny) {
@ -11273,7 +11285,7 @@
createChallengeButton({
eventName: "findBattleunranked",
button: $mainButtons.find('.find_battle_non_ranked'),
clauses: [Conditions.SLEEP_CLAUSE, Conditions.EVASION_CLAUSE, Conditions.SPECIES_CLAUSE, Conditions.OHKO_CLAUSE, Conditions.PRANKSTER_SWAGGER_CLAUSE, Conditions.UNRELEASED_BAN, Conditions.TIMED_BATTLE]
clauses: [Conditions.SLEEP_CLAUSE, Conditions.EVASION_CLAUSE, Conditions.SPECIES_CLAUSE, Conditions.OHKO_CLAUSE, Conditions.PRANKSTER_SWAGGER_CLAUSE, Conditions.TIMED_BATTLE]
});
createChallengePaneNew({
populate: $mainButtons.find('.find_battle_select_team')

File diff suppressed because one or more lines are too long

View File

@ -754,7 +754,7 @@
looper = loopLearnsets.bind(null, Generations, pokemon, generation);
pokemonSpecies = pokemon.species;
pokemonForme = pokemon.forme || "default";
pokemonLevel = pokemon.level || 100;
pokemonLevel = pokemon.level || generation.maxLevel;
FormeData = Generations[getGenerationFromInt(generation)].FormeData;
forme = FormeData[pokemonSpecies][pokemonForme];
if (generation === 4) {
@ -877,7 +877,7 @@
checkMove = function(looper, pokemon, move) {
var checksOut, level;
level = pokemon.level;
level || (level = 100);
level || (level = 120);
checksOut = looper(function(learnset) {
var _ref1, _ref2, _ref3, _ref4;
if (((_ref1 = learnset["level-up"]) != null ? _ref1[move] : void 0) <= level || ((_ref2 = learnset["machine"]) != null ? _ref2[move] : void 0) <= level || ((_ref3 = learnset["tutor"]) != null ? _ref3[move] : void 0) <= level) {
@ -993,7 +993,8 @@
}).call(this);
(function() {
var Tiers, actualtiers, conditions, self, _, _base, _ref;
var Tiers, actualtiers, conditions, self, _, _base, _ref,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
self = (typeof window !== "undefined" && window !== null ? (_base = window.PokeBattle).Tier != null ? _base.Tier : _base.Tier = {} : this);
@ -1093,6 +1094,9 @@
forme = megaForme;
}
}
if (species === "Rayquaza" && (pokemon.moves != null) && __indexOf.call(pokemon.moves, "Dragon Ascent") >= 0) {
forme = "mega";
}
tier = (speciesData != null ? (_ref2 = speciesData[forme]) != null ? _ref2.tier[0] : void 0 : void 0) || 'Unsorted';
tierdata = actualtiers[tier];
if (typeof tierdata === 'undefined') {
@ -1523,7 +1527,7 @@
this.set('ability', this.getAbilities()[0]);
}
if (!attributes.level) {
this.set('level', 100);
this.set('level', this.getGeneration.maxLevel);
}
if (isNaN(attributes.happiness)) {
this.set('happiness', 100);
@ -1738,7 +1742,7 @@
if (base === 1) {
return 1;
}
level = this.get('level') || 100;
level = this.get('level') || this.getGeneration.maxLevel;
iv = this.iv(key);
ev = Math.floor(this.ev(key) / 4);
return total = key === 'hp' ? Math.floor((2 * base + iv + ev) * (level / 100) + level + 10) : Math.floor(((2 * base + iv + ev) * (level / 100) + 5) * this.natureBoost(key));
@ -8011,7 +8015,7 @@
}
}
} else if (line.match(/^Level:\s+(.*)$/i)) {
pokemon.level = Number(RegExp.$1) || 100;
pokemon.level = Number(RegExp.$1) || 120;
} else if (line.match(/^Happiness:\s+(.*)$/i)) {
pokemon.happiness = Number(RegExp.$1) || 0;
} else if (line.match(/^Shiny: Yes$/i)) {
@ -8126,7 +8130,7 @@
if (pokemon.nature) {
s.push("" + pokemon.nature + " nature");
}
if (pokemon.level && pokemon.level !== 100) {
if (pokemon.level && pokemon.level !== 120) {
s.push("Level: " + pokemon.level);
}
if (pokemon.shiny) {

View File

@ -281,11 +281,7 @@ else if ( pokemon.get('gender') === 'M')
{
buf.push("<span class=\"gender gender_male\"> &#9794;</span>");
}
if ( pokemon.get('level') != 120)
{
buf.push("<span class=\"pokemon-level\"><span class=\"pokemon-level-text\"> Lv.</span>" + (jade.escape(null == (jade.interp = pokemon.get('level')) ? "" : jade.interp)) + "</span>");
}
buf.push("</span><div class=\"hp-text\">" + (jade.escape((jade.interp = percent) == null ? '' : jade.interp)) + "%</div><div" + (jade.attrs({ 'style':(greenStyle), "class": [('hp')] }, {"style":true})) + "></div><div class=\"hp-gradient\"></div><div class=\"pokemon-effects\"></div></div>");;return buf.join("");
buf.push("<span class=\"pokemon-level\"><span class=\"pokemon-level-text\"> Lv.</span>" + (jade.escape(null == (jade.interp = pokemon.get('level')) ? "" : jade.interp)) + "</span></span><div class=\"hp-text\">" + (jade.escape((jade.interp = percent) == null ? '' : jade.interp)) + "%</div><div" + (jade.attrs({ 'style':(greenStyle), "class": [('hp')] }, {"style":true})) + "></div><div class=\"hp-gradient\"></div><div class=\"pokemon-effects\"></div></div>");;return buf.join("");
};
this["JST"]["battle_team_preview"] = function anonymous(locals
@ -347,7 +343,7 @@ else if ( pokemon.get('gender') === 'M')
{
buf.push("<div class=\"gender gender_male\">&#9794;</div>");
}
if ( pokemon.get('level') != 100)
if ( pokemon.get('level') != 120)
{
buf.push("<div class=\"level\">Lv." + (jade.escape((jade.interp = pokemon.get('level')) == null ? '' : jade.interp)) + "</div>");
}
@ -624,7 +620,7 @@ buf.push("<p><strong>Description:</strong> " + (jade.escape((jade.interp = move.
this["JST"]["navigation"] = function anonymous(locals
/**/) {
var buf = [];
buf.push("<p class=\"logo\"></p><h2>Chat</h2><ul class=\"nav nav_rooms\"><li class=\"nav_item fake_link\">Lobby</li></ul><h2>Other links</h2><ul class=\"nav\"><li class=\"nav_item fake_link nav_teambuilder\">Teambuilder</li><li class=\"nav_item fake_link nav_battle_list\">Battle List</li><a href=\"/replays\" target=\"_blank\" class=\"nav_item\">Your Replays</a><a href=\"/leaderboard/\" target=\"_blank\" class=\"nav_item\">Leaderboard</a><a href=\"//bitbucket.org/PInsurgence/battle-simulator/issues?status=new&amp;status=open\" target=\"_blank\" class=\"nav_item\">Bug Reports</a><a href=\"//91.121.152.74/c/battle-simulator/feature-requests\" target=\"_blank\" class=\"nav_item\">Feature Requests</a></ul><ul class=\"nav nav_battles hidden\"></ul><h2 class=\"header_messages hidden\">Messages</h2><ul class=\"nav nav_messages hidden\"></ul>");;return buf.join("");
buf.push("<p class=\"logo\"></p><h2>Chat</h2><ul class=\"nav nav_rooms\"><li class=\"nav_item fake_link\">Lobby</li></ul><h2>Other links</h2><ul class=\"nav\"><li class=\"nav_item fake_link nav_teambuilder\">Teambuilder</li><li class=\"nav_item fake_link nav_battle_list\">Battle List</li><a href=\"/replays\" target=\"_blank\" class=\"nav_item\">Your Replays</a><a href=\"/leaderboard/\" target=\"_blank\" class=\"nav_item\">Leaderboard</a><a href=\"//bitbucket.org/PInsurgence/battle-simulator/issues?status=new&amp;status=open\" target=\"_blank\" class=\"nav_item\">Bug Reports</a><a href=\"//forums.p-insurgence.com/c/battle-simulator/feature-requests\" target=\"_blank\" class=\"nav_item\">Feature Requests</a></ul><ul class=\"nav nav_battles hidden\"></ul><h2 class=\"header_messages hidden\">Messages</h2><ul class=\"nav nav_messages hidden\"></ul>");;return buf.join("");
};
this["JST"]["new_battle"] = function anonymous(locals

View File

@ -17,7 +17,7 @@ AUTH_KEY = "auth"
BANS_KEY = "bans"
MUTE_KEY = "mute"
return_sso_url="http://91.121.152.74:8000/"
return_sso_url="./"
secretstring = config.SECRET_KEY
loggedin = false
@ -53,12 +53,13 @@ exports.middleware = -> (req, res, next) ->
parameters = getparameters(req)
nonce = new Date().getTime() + '' + new Date().getMilliseconds();
cookies.set("nonce", nonce)
return_sso_url="http://91.121.152.74:8000" + req.url
console.log(req.headers.host)
return_sso_url="http://" + req.headers.host + req.url
payload = "nonce=" + nonce + "&return_sso_url=" + return_sso_url
base64payload = new Buffer(payload).toString('base64')
urlencoded = encodeURIComponent(base64payload)
crypted = crypto.createHmac('SHA256', secretstring).update(base64payload).digest('hex')
return res.redirect("http://91.121.152.74/session/sso_provider?sso=" + urlencoded + "&sig=" + crypted)
return res.redirect("http://forums.p-insurgence.com/session/sso_provider?sso=" + urlencoded + "&sig=" + crypted)
exports.matchToken = (req, id, token, next) ->
hmac = crypto.createHmac('sha256', config.SECRET_KEY)
@ -89,7 +90,8 @@ setdatabasedata = (req, cookies, object, next) ->
req.user.token = cookies.get("nonce")
req.user.id = id
req.user.name = username
if username == "Deukhoofd" && admin == "true"
OWNERUSERNAMES = ["Deukhoofd", "thesuzerain"]
if username in OWNERUSERNAMES && admin == "true"
exports.setAuth username, exports.levels.OWNER
else if admin == "true"
exports.setAuth username, exports.levels.ADMIN

View File

@ -141,17 +141,31 @@ class @Battle extends Room
@emit('beforeStart')
else
for id in @playerIds
console.log(id)
team = @teams[id]
allpokemon = team.all()
for pokemon in allpokemon
if pokemon.hasAbility('Illusion')
alivemons = team.getAlivePokemon()
lastalivemon = alivemons[alivemons.length-1]
pokemon.attach(Attachment.Illusion, lastalivemon)
pokemon.attach(Attachment.Illusion, lastalivemon)
@startBattle()
startBattle: ->
@emit('start')
for playerId in @playerIds
team = @teams[playerId]
allpokemon = team.all()
for pokemon in allpokemon
if pokemon.getForme().isItemBased
[ species, forme ] = pokemon.item.itemForme
if pokemon.species != species
pokemon.changeForme("default")
if typeof pokemon.item != 'undefined' and typeof pokemon.item.itemForme != 'undefined'
[ species, forme ] = pokemon.item.itemForme
if species is pokemon.species
pokemon.changeForme(forme)
@tell(Protocol.START_BATTLE)
# TODO: Merge this with performReplacements?
for playerId in @playerIds

View File

@ -275,7 +275,6 @@ makePinchBerry 'Custap Berry', 'afterTurnOrder', (battle, eater) ->
battle.bump(eater)
makeWeatherItem 'Damp Rock', Weather.RAIN
makeWeatherItem 'Dark Rock', Weather.MOON
makeGemItem 'Dark Gem', 'Dark'
makeTypeBoostItem 'Dragon Fang', 'Dragon'
makeGemItem 'Dragon Gem', 'Dragon'

View File

@ -18,7 +18,7 @@ class @Pokemon
@species = attributes.species || "Missingno"
@name = attributes.name || @species
@forme = attributes.forme || "default"
@level = attributes.level || 120
@level = attributes.level || @getMaxLevel()
@gender = attributes.gender || "Genderless"
@shiny = attributes.shiny
@nfe = (SpeciesData[@species]?.evolvesInto?.length > 0)
@ -88,6 +88,10 @@ class @Pokemon
@resetForme()
return true
getMaxLevel: ->
level = 100
level
resetForme: ->
forme = @getForme() || {}
@baseStats = _.clone(forme.stats) || {}
@ -533,6 +537,7 @@ class @Pokemon
shouldBlockExecution: (move, user) ->
Query.untilTrue('shouldBlockExecution', @attachments.all(), move, user)
update: ->
Query('update', @attachments.all())

View File

@ -18,6 +18,9 @@ class @Team
@faintedLastTurn = false
@faintedThisTurn = false
hasMegaEvolved = false
hasPrimalEvolved = false
arrange: (arrangement) ->
@pokemon = (@pokemon[index] for index in arrangement)
@ -45,6 +48,11 @@ class @Team
get: (attachmentName) ->
@attachments.get(attachmentName)
megaEvolve: ->
@hasMegaEvolved = true
primalEvolve: ->
@hasPrimalEvolved = true
attach: (attachment, options={}) ->
options = _.clone(options)
attachment = @attachments.push(attachment, options, battle: @battle, team: this)

View File

@ -48,6 +48,11 @@ for gen, i in @ALL_GENERATIONS
AbilityMap = {}
TypeMap = {}
if gen is 'in'
maxLevel = 120
else
maxLevel = 100
for pokemonName, pokemonData of FormeData
for formeName, formeData of pokemonData
# Add types
@ -82,6 +87,7 @@ for gen, i in @ALL_GENERATIONS
MoveMap : MoveMap
AbilityMap : AbilityMap
TypeMap : TypeMap
maxLevel : maxLevel
# Now add moves for every generation
for gen in @ALL_GENERATIONS

View File

@ -19,6 +19,9 @@ eval(coffee.compile(require('fs').readFileSync(path, 'utf8'), bare: true))
[ species, forme ] = pokemon.item.mega
pokemon.changeForme(forme)
pokemon.getTeam().megaEvolve() if forme is "mega"
pokemon.getTeam().primalEvolve() if forme is "primal"
ability = @FormeData[species][forme]["abilities"][0]
ability = Ability[ability.replace(/\s+/g, '')]
pokemon.copyAbility(ability, reveal: false)

View File

@ -18843,7 +18843,7 @@
"isBattleOnly": true,
"weight": 65,
"pokeBattleValue": 190,
"tier": [ "OU" ]
"tier": [ "OU" ]
},
"mega-fairy": {
"types": [
@ -21808,6 +21808,29 @@
"weight": 820,
"pokeBattleValue": 1001,
"tier": [ "Uber" ]
},
"armor": {
"types": [
"Ground",
"Dragon"
],
"stats": {
"attack": 100,
"defense": 103,
"hp": 80,
"specialAttack": 80,
"specialDefense": 103,
"speed": 100
},
"abilities": [
"Levitate"
],
"hiddenAbility": "Unnerve",
"isBattleOnly": true,
"isItemBased": true,
"weight": 820,
"pokeBattleValue": 190,
"tier": [ "OU" ]
}
},
"Foongus": {
@ -26588,7 +26611,8 @@
"Mud Shot": 1,
"Rest": 30,
"Scary Face": 5,
"SolarBeam": 80
"SolarBeam": 80,
"Precipice Blades": 45
},
"machine": {
"Aerial Ace": 0,
@ -32511,7 +32535,8 @@
"Scary Face": 5,
"Sheer Cold": 75,
"Water Pulse": 1,
"Water Spout": 50
"Water Spout": 50,
"Origin Pulse": 45
},
"machine": {
"Blizzard": 0,
@ -33973,6 +33998,30 @@
"weight": 205,
"pokeBattleValue": 125,
"tier": [ "UU" ]
},
"armor": {
"types": [
"Bug",
"Grass"
],
"stats": {
"attack": 103,
"defense": 112,
"hp": 75,
"specialAttack": 70,
"specialDefense": 98,
"speed": 92
},
"abilities": [
"Swarm",
"Chlorophyll"
],
"hiddenAbility": "Overcoat",
"isBattleOnly": true,
"isItemBased": true,
"weight": 205,
"pokeBattleValue": 190,
"tier": [ "OU" ]
}
},
"Ledian": {
@ -62593,7 +62642,30 @@
"isBattleOnly": true,
"weight": 2550,
"pokeBattleValue": 190,
"tier": [ "OU" ]
"tier": [ "OU" ]
},
"armor": {
"types": [
"Rock",
"Dark"
],
"stats": {
"attack": 134,
"defense": 143,
"hp": 100,
"specialAttack": 95,
"specialDefense": 130,
"speed": 61
},
"abilities": [
"Sand Stream"
],
"hiddenAbility": "Unnerve",
"isBattleOnly": true,
"isItemBased": true,
"weight": 2020,
"pokeBattleValue": 190,
"tier": [ "OU" ]
}
},
"Tyrantrum": {
@ -67346,7 +67418,8 @@
],
"weight": 526,
"pokeBattleValue": 155,
"tier": [ "OU" ]
"tier": [ "OU" ],
"unreleased": true
}
},
"Zebstrika": {
@ -67538,6 +67611,28 @@
"weight": 3450,
"pokeBattleValue": 1001,
"tier": [ "Uber" ]
},
"armor": {
"types": [
"Dragon",
"Electric"
],
"stats": {
"attack": 150,
"defense": 156,
"hp": 100,
"specialAttack": 120,
"specialDefense": 130,
"speed": 90
},
"abilities": [
"Teravolt"
],
"isBattleOnly": true,
"isItemBased": true,
"weight": 3450,
"pokeBattleValue": 190,
"tier": [ "Uber" ]
}
},
"Zigzagoon": {

View File

@ -1,4 +1,44 @@
{
"Tyranitar Armor": {
"description": "Increases the Defense and Special Defense stats of Tyranitar by 25% when held.",
"flingPower": 80,
"itemForme": [
"Tyranitar",
"armor"
],
"spriteId": 404,
"type": "megastone"
},
"Flygon Armor": {
"description": "Increases the Defense and Special Defense stats of Flygon by 25% when held.",
"flingPower": 80,
"itemForme": [
"Flygon",
"armor"
],
"spriteId": 404,
"type": "megastone"
},
"Leavanny Armor": {
"description": "Increases the Defense and Special Defense stats of Leavanny by 25% when held.",
"flingPower": 80,
"itemForme": [
"Leavanny",
"armor"
],
"spriteId": 404,
"type": "megastone"
},
"Zekrom Armor": {
"description": "Increases the Defense and Special Defense stats of Zekrom by 25% when held.",
"flingPower": 80,
"itemForme": [
"Zekrom",
"armor"
],
"spriteId": 404,
"type": "megastone"
},
"Ability Capsule": {
"description": "Allows a Pokemon with one of its two standard Abilities to change to the other when used.",
"flingPower": 0,
@ -23,7 +63,7 @@
"mega"
],
"spriteId": 407,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Absorb Bulb": {
@ -56,7 +96,7 @@
"mega"
],
"spriteId": 397,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Aguav Berry": {
@ -83,7 +123,7 @@
"mega"
],
"spriteId": 409,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Amaze Mulch": {
@ -196,7 +236,7 @@
"mega"
],
"spriteId": 398,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
@ -209,8 +249,9 @@
],
"spriteId": 404,
"type": "megastone",
"unreleased": true
}, "Belue Berry": {
"unreleased": true
},
"Belue Berry": {
"description": "No competitive use.",
"flingPower": 10,
"naturalGift": {
@ -265,9 +306,10 @@
"mega"
],
"spriteId": 404,
"unreleased": true,
"unreleased": true,
"type": "megastone"
}, "Black Belt": {
},
"Black Belt": {
"description": "The holder's Fighting-type attacks have their power multiplied by 1.2.",
"flingPower": 30,
"spriteId": 224,
@ -337,7 +379,7 @@
"primal"
],
"spriteId": 407,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Bluk Berry": {
@ -414,7 +456,8 @@
"flingPower": 30,
"spriteId": 19,
"type": "medicine"
}, "Cacturnite": {
},
"Cacturnite": {
"description": "If the holder is a Cacturne, this item allows it to Mega Evolve into Mega Cacturne in battle.",
"flingPower": 80,
"mega": [
@ -429,7 +472,8 @@
"flingPower": 30,
"spriteId": 49,
"type": "medicine"
}, "Cameruptite": {
},
"Cameruptite": {
"description": "If the holder is a Camerupt, this item allows it to Mega Evolve into Mega Camerupt in battle.",
"flingPower": 80,
"mega": [
@ -472,7 +516,7 @@
"mega-x"
],
"spriteId": 390,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Charizardite Y": {
@ -624,7 +668,8 @@
"flingPower": 100,
"spriteId": 356,
"type": "misc"
}, "Crawdite": {
},
"Crawdite": {
"description": "If the holder is a Crawdaunt, this item allows it to Mega Evolve into Mega Crawdaunt in battle.",
"flingPower": 80,
"mega": [
@ -685,7 +730,8 @@
"flingPower": 90,
"spriteId": 209,
"type": "misc"
}, "Delta Bisharpite": {
},
"Delta Bisharpite": {
"description": "If the holder is a Delta Bisharp, this item allows it to Mega Evolve into Mega Delta Bisharp in battle.",
"flingPower": 80,
"mega": [
@ -694,7 +740,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Delta Blastoisinite": {
},
"Delta Blastoisinite": {
"description": "If the holder is a Delta Blastoise, this item allows it to Mega Evolve into Mega Delta Blastoise in battle.",
"flingPower": 80,
"mega": [
@ -703,7 +750,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Delta Charizardite": {
},
"Delta Charizardite": {
"description": "If the holder is a Delta Charizard, this item allows it to Mega Evolve into Mega Delta Charizard in battle.",
"flingPower": 80,
"mega": [
@ -712,7 +760,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Delta Galladite": {
},
"Delta Galladite": {
"description": "If the holder is a Delta Gallade, this item allows it to Mega Evolve into Mega Delta Gallade in battle.",
"flingPower": 80,
"mega": [
@ -721,7 +770,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Delta Gardevoirite": {
},
"Delta Gardevoirite": {
"description": "If the holder is a Delta Gardevoir, this item allows it to Mega Evolve into Mega Delta Gardevoir in battle.",
"flingPower": 80,
"mega": [
@ -730,7 +780,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Delta Scizorite": {
},
"Delta Scizorite": {
"description": "If the holder is a Delta Scizor, this item allows it to Mega Evolve into Mega Delta scizor in battle.",
"flingPower": 80,
"mega": [
@ -739,7 +790,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Delta Venusaurite": {
},
"Delta Venusaurite": {
"description": "If the holder is a Delta Venusaur, this item allows it to Mega Evolve into Mega Delta Venusaur in battle.",
"flingPower": 80,
"mega": [
@ -798,9 +850,10 @@
"mega"
],
"spriteId": 404,
"unreleased": true,
"unreleased": true,
"type": "megastone"
}, "Douse Drive": {
},
"Douse Drive": {
"description": "The holder's Techno Blast is Water type.",
"flingPower": 70,
"spriteId": 113,
@ -990,7 +1043,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Fighting Gem": {
},
"Fighting Gem": {
"description": "The holder's first successful Fighting-type attack has its power multiplied by 1.3. Single use.",
"flingPower": 0,
"spriteId": 337,
@ -1047,7 +1101,8 @@
"flingPower": 30,
"spriteId": 64,
"type": "misc"
}, "Flygonite": {
},
"Flygonite": {
"description": "If the holder is a Flygon, this item allows it to Mega Evolve into Mega Flygon in battle.",
"flingPower": 80,
"mega": [
@ -1113,7 +1168,7 @@
"mega"
],
"spriteId": 404,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Ganlon Berry": {
@ -1134,7 +1189,7 @@
"mega"
],
"spriteId": 413,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Gardevoirite": {
@ -1145,7 +1200,7 @@
"mega"
],
"spriteId": 387,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Gengarite": {
@ -1179,7 +1234,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Glalitite": {
},
"Glalitite": {
"description": "If the holder is a Glalie, this item allows it to Mega Evolve into Mega Glalie in battle.",
"flingPower": 80,
"mega": [
@ -1194,7 +1250,8 @@
"flingPower": 30,
"spriteId": 98,
"type": "misc"
}, "Gothitite": {
},
"Gothitite": {
"description": "If the holder is a Gothitelle, this item allows it to Mega Evolve into Mega Gothitelle in battle.",
"flingPower": 80,
"mega": [
@ -1283,7 +1340,7 @@
"mega"
],
"spriteId": 406,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"HP Up": {
@ -1384,7 +1441,7 @@
"mega"
],
"spriteId": 396,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Hyper Potion": {
@ -1483,7 +1540,7 @@
"mega"
],
"spriteId": 405,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Kasib Berry": {
@ -1659,7 +1716,7 @@
"mega"
],
"spriteId": 404,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Love Ball": {
@ -1676,7 +1733,7 @@
"mega"
],
"spriteId": 403,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Luck Incense": {
@ -1752,11 +1809,12 @@
],
"spriteId": 404,
"type": "megastone"
}, "Magmarizer": {
},
"Magmarizer": {
"description": "No competitive use. Evolves Magmar into Magmortar when traded.",
"flingPower": 80,
"spriteId": 306,
"unreleased": true,
"unreleased": true,
"type": "misc"
},
"Magnet": {
@ -1793,7 +1851,7 @@
"mega"
],
"spriteId": 412,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Maranga Berry": {
@ -1876,9 +1934,10 @@
"mega"
],
"spriteId": 395,
"unreleased": true,
"unreleased": true,
"type": "megastone"
}, "Meganiumite": {
},
"Meganiumite": {
"description": "If the holder is a Meganium, this item allows it to Mega Evolve into Mega Meganium in battle.",
"flingPower": 80,
"mega": [
@ -1886,7 +1945,7 @@
"mega"
],
"spriteId": 404,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Mental Herb": {
@ -1905,7 +1964,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Metal Coat": {
},
"Metal Coat": {
"description": "The holder's Steel-type attacks have their power multiplied by 1.2. Evolves Onix into Steelix and Scyther into Scizor when traded.",
"flingPower": 30,
"spriteId": 216,
@ -1952,7 +2012,8 @@
},
"spriteId": 192,
"type": "berries"
}, "Milotite": {
},
"Milotite": {
"description": "If the holder is a Milotic, this item allows it to Mega Evolve into Mega Milotic in battle.",
"flingPower": 80,
"mega": [
@ -1962,7 +2023,8 @@
"unreleased": true,
"spriteId": 404,
"type": "megastone"
}, "Miltankite": {
},
"Miltankite": {
"description": "If the holder is a Miltank, this item allows it to Mega Evolve into Mega Miltank in battle.",
"flingPower": 80,
"mega": [
@ -2256,7 +2318,7 @@
"mega"
],
"spriteId": 401,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Pixie Plate": {
@ -2534,7 +2596,7 @@
"primal"
],
"spriteId": 407,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Relic Band": {
@ -2613,7 +2675,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Revival Herb": {
},
"Revival Herb": {
"description": "No competitive use. The selected Pokemon is revived from fainting and has all of its HP restored, but has its Happiness lowered.",
"flingPower": 30,
"spriteId": 37,
@ -2768,7 +2831,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Scizorite": {
},
"Scizorite": {
"description": "If the holder is a Scizor, this item allows it to Mega Evolve into Mega Scizor in battle.",
"flingPower": 80,
"mega": [
@ -2776,7 +2840,7 @@
"mega"
],
"spriteId": 400,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Scope Lens": {
@ -2812,7 +2876,7 @@
"mega"
],
"spriteId": 404,
"unreleased": true,
"unreleased": true,
"type": "megastone"
},
"Shed Shell": {
@ -2826,7 +2890,8 @@
"flingPower": 30,
"spriteId": 236,
"type": "misc"
}, "Shiftrite": {
},
"Shiftrite": {
"description": "If the holder is a Shiftry, this item allows it to Mega Evolve into Mega Shiftry in battle.",
"flingPower": 80,
"mega": [
@ -2914,7 +2979,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Smoke Ball": {
},
"Smoke Ball": {
"description": "No competitive use. The holder can always run from wild battles.",
"flingPower": 30,
"spriteId": 211,
@ -2978,7 +3044,8 @@
"flingPower": 90,
"spriteId": 282,
"type": "misc"
}, "Spiritombite": {
},
"Spiritombite": {
"description": "If the holder is a Spiritomb, this item allows it to Mega Evolve into Mega Spiritomb in battle.",
"flingPower": 80,
"mega": [
@ -3087,7 +3154,8 @@
],
"spriteId": 404,
"type": "megastone"
}, "Sun Stone": {
},
"Sun Stone": {
"description": "No competitive use. An evolutionary item to be used on certain Pokemon.",
"flingPower": 30,
"spriteId": 80,
@ -3201,7 +3269,8 @@
"flingPower": 30,
"spriteId": 231,
"type": "misc"
}, "Typhlosionite": {
},
"Typhlosionite": {
"description": "If the holder is a Typhlosion, this item allows it to Mega Evolve into Mega Typhlosion in battle.",
"flingPower": 80,
"mega": [
@ -3406,7 +3475,8 @@
"flingPower": 90,
"spriteId": 283,
"type": "misc"
}, "Zebstrikite": {
},
"Zebstrikite": {
"description": "If the holder is a Zebstrika, this item allows it to Mega Evolve into Mega Zebstrika in battle.",
"flingPower": 80,
"mega": [
@ -3427,7 +3497,8 @@
"flingPower": 10,
"spriteId": 259,
"type": "misc"
}, "Zoronite": {
},
"Zoronite": {
"description": "If the holder is a Zoroark, this item allows it to Mega Evolve into Mega Zoroark in battle.",
"flingPower": 80,
"mega": [

View File

@ -1,4 +1,42 @@
{
"Precipice Blades": {
"accuracy": 85,
"ailmentChance": 0,
"ailmentId": "none",
"damage": "physical",
"description": "The user attacks opposing Pokémon by manifesting the power of the land in fearsome blades of stone.",
"flags": [
"protect"
],
"flinchChance": 0,
"maxHits": 1,
"minHits": 1,
"power": 120,
"pp": 10,
"priority": 0,
"recoil": 0,
"target": "all-other-pokemon",
"type": "Ground"
},
"Origin Pulse": {
"accuracy": 85,
"ailmentChance": 0,
"ailmentId": "none",
"damage": "special",
"description": "The user attacks opposing Pokémon with countless beams of light that glow a deep and brilliant blue.",
"flags": [
"protect"
],
"flinchChance": 0,
"maxHits": 1,
"minHits": 1,
"power": 110,
"pp": 10,
"priority": 0,
"recoil": 0,
"target": "all-other-pokemon",
"type": "Water"
},
"Ancient Roar": {
"accuracy": 100,
"ailmentChance": 0,
@ -2816,7 +2854,7 @@
"target": "selected-pokemon",
"type": "Dragon"
},
"Dragon Ascent": {
"Dragon Ascent": {
"accuracy": 100,
"ailmentChance": 0,
"ailmentId": "none",

View File

@ -50,3 +50,5 @@ makeItem "Weakness Policy", ->
move.typeEffectiveness(@battle, user, @pokemon) > 1
@pokemon.boost(attack: 2, specialAttack: 2)
@pokemon.useItem()
makeWeatherItem 'Dark Rock', Weather.MOON

View File

@ -12,7 +12,8 @@ eval(coffee.compile(require('fs').readFileSync(path, 'utf8'), bare: true))
return false if @item.type != 'megastone'
[ species, forme ] = @item.mega
return false if @species != species || @forme != 'default'
return false if @team?.filter((p) -> /^mega/.test(p.forme)).length > 0
return false if @team.hasMegaEvolved and forme is "mega"
return false if @team.hasPrimalEvolved and forme is "primal"
return true
oldBlockSwitch = @Pokemon::blockSwitch
@ -39,3 +40,10 @@ oldShouldBlockExecution = @Pokemon::shouldBlockExecution
oldHasChangeableAbility = @Pokemon::hasChangeableAbility
@Pokemon::hasChangeableAbility = ->
!@hasAbility("Stance Change") && oldHasChangeableAbility.call(this)
oldgetMaxLevel = @Pokemon::getMaxLevel
@Pokemon::getMaxLevel = ->
oldgetMaxLevel.apply(this, arguments)
level = 120
console.log(level)
level

View File

@ -36,7 +36,6 @@ FIND_BATTLE_CONDITIONS_UNRANKED = [
Conditions.SPECIES_CLAUSE
Conditions.PRANKSTER_SWAGGER_CLAUSE
Conditions.OHKO_CLAUSE
Conditions.UNRELEASED_BAN
]
MAX_NICKNAME_LENGTH = 16
@ -385,6 +384,8 @@ class @BattleServer
room.announce("warning", message)
userMessage: (user, room, message) ->
isAllowed = @checkMessage(message)
return if !isAllowed
@runIfUnmuted user, room.name, ->
room.userMessage(user, message)
@ -395,6 +396,15 @@ class @BattleServer
else
user.announce(roomId, 'warning', "You are muted for another #{ttl} seconds!")
checkMessage: (message) ->
#No links, unless within p-insurgence domain
if message.match(/.*p-insurgence\.com.*/)
return true
if message.match(/[a-zA-Z0-9]{1,100}\.[a-zA-Z0-9]{1,100}/)
return false
else
return true
setAuthority: (user, newAuthority) ->
user = @users.get(user) if user not instanceof User
user.authority = newAuthority if user
@ -463,7 +473,7 @@ class @BattleServer
err.push("#{prefix}: Invalid forme: #{pokemon.forme}.")
return err
if forme.isBattleOnly
if forme.isBattleOnly and !forme.isItemBased
err.push("#{prefix}: #{pokemon.forme} forme is battle-only.")
return err
@ -483,8 +493,8 @@ class @BattleServer
if isNaN(pokemon.level)
err.push("#{prefix}: Invalid level: #{pokemon.level}.")
# TODO: 100 is a magic constant
else if !(1 <= pokemon.level <= 120)
err.push("#{prefix}: Level must be between 1 and 120.")
else if !(1 <= pokemon.level <= genData.maxLevel)
err.push("#{prefix}: Level must be between 1 and #{genData.maxLevel}.")
if pokemon.gender not in [ "M", "F", "Genderless" ]
err.push("#{prefix}: Invalid gender: #{pokemon.gender}.")
@ -524,7 +534,7 @@ class @BattleServer
# Normalizes a Pokemon by setting default values where applicable.
# Assumes that the Pokemon is a real Pokemon (i.e. its species/forme is valid)
normalizePokemon: (pokemon, generation = gen.DEFAULT_GENERATION) ->
{SpeciesData, FormeData} = gen.GenerationJSON[generation.toUpperCase()]
{maxLevel, SpeciesData, FormeData} = gen.GenerationJSON[generation.toUpperCase()]
pokemon.forme ?= "default"
pokemon.name ?= pokemon.species
pokemon.ability ?= FormeData[pokemon.species][pokemon.forme]?["abilities"][0]
@ -535,6 +545,6 @@ class @BattleServer
else pokemon.gender = "M"
pokemon.evs ?= {}
pokemon.ivs ?= {}
pokemon.level ?= 100
pokemon.level ?= maxLevel
pokemon.level = Math.floor(pokemon.level)
return pokemon

View File

@ -132,7 +132,7 @@ self.checkMoveset = (Generations, pokemon, generation, moves) ->
looper = loopLearnsets.bind(null, Generations, pokemon, generation)
pokemonSpecies = pokemon.species
pokemonForme = pokemon.forme || "default"
pokemonLevel = (pokemon.level || 100)
pokemonLevel = (pokemon.level || generation.maxLevel)
{FormeData} = Generations[getGenerationFromInt(generation)]
forme = FormeData[pokemonSpecies][pokemonForme]
@ -206,7 +206,7 @@ self.checkMoveset = (Generations, pokemon, generation, moves) ->
# tutors, machines, Sketch, or pre-evolutions.
checkMove = (looper, pokemon, move) ->
{level} = pokemon
level ||= 100
level ||= 120
checksOut = looper (learnset) ->
# Check level-up, TM/HM, and tutors.

View File

@ -81,6 +81,10 @@ self.determineTier = (genData, pokemonArray) ->
if species == megaSpecies
forme = megaForme
# Handle Mega Rayquaza
if species is "Rayquaza" and pokemon.moves? and "Dragon Ascent" in pokemon.moves
forme = "mega"
# Get PBV of the Pokemon's forme
tier = speciesData?[forme]?.tier[0] || 'Unsorted'
tierdata = actualtiers[tier]