Skip to content

Commit

Permalink
Merge pull request #2593 from sylvainpolletvillard/human-synergy-rework
Browse files Browse the repository at this point in the history
Human synergy rework
  • Loading branch information
sylvainpolletvillard authored Dec 18, 2024
2 parents 59b978a + de62a03 commit 19db196
Show file tree
Hide file tree
Showing 169 changed files with 878 additions and 203 deletions.
342 changes: 296 additions & 46 deletions app/core/abilities/abilities.ts

Large diffs are not rendered by default.

37 changes: 24 additions & 13 deletions app/core/evolution-rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Player from "../models/colyseus-models/player"
import { Pokemon, PokemonClasses } from "../models/colyseus-models/pokemon"
import PokemonFactory from "../models/pokemon-factory"
import { EvolutionTime } from "../types/Config"
import { Ability } from "../types/enum/Ability"
import { PokemonActionState } from "../types/enum/Game"
import { ItemComponents, Item, ShinyItems } from "../types/enum/Item"
import { Passive } from "../types/enum/Passive"
Expand Down Expand Up @@ -147,7 +148,7 @@ export class CountEvolutionRule extends EvolutionRule {
)

carryOverPermanentStats(pokemonEvolved, pokemonsBeforeEvolution)

if (pokemon.onEvolve) {
pokemon.onEvolve({ pokemonEvolved, pokemonsBeforeEvolution, player })
}
Expand Down Expand Up @@ -308,19 +309,29 @@ export class ConditionBasedEvolutionRule extends EvolutionRule {
return pokemonEvolved
}
}
function carryOverPermanentStats(pokemonEvolved: Pokemon, pokemonsBeforeEvolution: Pokemon[]) {
// carry over the permanent stat buffs
const permanentBuffStats = ["hp", "atk", "def", "speDef"] as const
for (const stat of permanentBuffStats) {
const statStacked = sum(
pokemonsBeforeEvolution.map(
(p) => p[stat] - new PokemonClasses[p.name]()[stat]
)
function carryOverPermanentStats(
pokemonEvolved: Pokemon,
pokemonsBeforeEvolution: Pokemon[]
) {
// carry over the permanent stat buffs
const permanentBuffStats = ["hp", "atk", "def", "speDef"] as const
for (const stat of permanentBuffStats) {
const statStacked = sum(
pokemonsBeforeEvolution.map(
(p) => p[stat] - new PokemonClasses[p.name]()[stat]
)
if (statStacked > 0) {
pokemonEvolved[stat] += statStacked
}
)
if (statStacked > 0) {
pokemonEvolved[stat] += statStacked
}
}

// carry over TM
const existingTms = pokemonsBeforeEvolution
.map((p) => p.tm)
.filter<Ability>((tm): tm is Ability => tm != null)
if (existingTms.length > 0) {
pokemonEvolved.tm = pickRandomIn(existingTms)
pokemonEvolved.skill = pokemonEvolved.tm
}
}

6 changes: 3 additions & 3 deletions app/core/pokemon-entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1123,9 +1123,9 @@ export class PokemonEntity extends Schema implements IPokemonEntity {
if (this.hasSynergyEffect(Synergy.HUMAN)) {
let lifesteal = 0
if (this.effects.has(Effect.MEDITATE)) {
lifesteal = 0.15
lifesteal = 0.25
} else if (this.effects.has(Effect.FOCUS_ENERGY)) {
lifesteal = 0.3
lifesteal = 0.4
} else if (this.effects.has(Effect.CALM_MIND)) {
lifesteal = 0.6
}
Expand Down Expand Up @@ -1179,7 +1179,7 @@ export class PokemonEntity extends Schema implements IPokemonEntity {
) {
const cells = board.getAdjacentCells(this.positionX, this.positionY)
cells.forEach((cell) => {
board.addBoardEffect(cell.x, cell.y, Effect.GAS, this.simulation)
board.addBoardEffect(cell.x, cell.y, Effect.SMOKE, this.simulation)
if (cell.value && cell.value.team !== this.team) {
cell.value.status.triggerParalysis(3000, cell.value, this)
}
Expand Down
2 changes: 1 addition & 1 deletion app/core/pokemon-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export default abstract class PokemonState {

let isAttackSuccessful = true
let dodgeChance = target.dodge
if (pokemon.effects.has(Effect.GAS)) {
if (pokemon.status.blinded) {
dodgeChance += 0.5
}
dodgeChance = max(0.9)(dodgeChance)
Expand Down
10 changes: 3 additions & 7 deletions app/core/simulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1023,15 +1023,11 @@ export default class Simulation extends Schema implements ISimulation {
break

case Effect.MEDITATE:
pokemon.effects.add(Effect.MEDITATE)
break

case Effect.FOCUS_ENERGY:
pokemon.effects.add(Effect.FOCUS_ENERGY)
break

case Effect.CALM_MIND:
pokemon.effects.add(Effect.CALM_MIND)
if (types.has(Synergy.HUMAN)) {
pokemon.effects.add(effect)
}
break

case Effect.TAILWIND:
Expand Down
35 changes: 35 additions & 0 deletions app/models/colyseus-models/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import { BattleResult, Rarity, Team } from "../../types/enum/Game"
import {
ArtificialItems,
Berries,
HMs,
Item,
ItemComponents,
SynergyGivenByItem,
TMs,
WeatherRocks
} from "../../types/enum/Item"
import {
Expand Down Expand Up @@ -104,6 +106,7 @@ export default class Player extends Schema implements IPlayer {
opponents: Map<string, number> = new Map<string, number>()
titles: Set<Title> = new Set<Title>()
artificialItems: Item[] = pickNRandomIn(ArtificialItems, 3)
tms: (Item | null)[] = pickRandomTMs()
weatherRocks: Item[] = []
randomComponentsGiven: Item[] = []
randomEggsGiven: Pkm[] = []
Expand Down Expand Up @@ -306,8 +309,10 @@ export default class Player extends Schema implements IPlayer {

if (lightChanged) this.onLightChange()

/* NOTE: should be optimized to update only when the corresponding synergy has changed */
this.updateFishingRods()
this.updateWeatherRocks()
this.updateTms()
this.updateWildChance()
this.effects.update(this.synergies, this.board)
}
Expand Down Expand Up @@ -402,6 +407,29 @@ export default class Player extends Schema implements IPlayer {
}
}

updateTms() {
const nbTMs = SynergyTriggers[Synergy.HUMAN].filter(
(n) => (this.synergies.get(Synergy.HUMAN) ?? 0) >= n
).length

let tmInInventory
do {
tmInInventory = this.items.findIndex(
(item, index) => TMs.includes(item) || HMs.includes(item)
)
if (tmInInventory != -1) {
this.items.splice(tmInInventory, 1)
}
} while (tmInInventory != -1)

if (nbTMs > 0) {
const tmsCollected = this.tms
.slice(0, nbTMs)
.filter<Item>((tm): tm is Item => tm != null)
this.items.push(...tmsCollected)
}
}

updateFishingRods() {
const fishingLevel = SynergyTriggers[Synergy.WATER].filter(
(n) => (this.synergies.get(Synergy.WATER) ?? 0) >= n
Expand Down Expand Up @@ -473,3 +501,10 @@ export default class Player extends Schema implements IPlayer {
})
}
}

function pickRandomTMs() {
const firstTM = pickRandomIn(TMs)
const secondTM = pickRandomIn(TMs.filter((tm) => tm !== firstTM))
const hm = pickRandomIn(HMs)
return [firstTM, secondTM, hm]
}
7 changes: 4 additions & 3 deletions app/models/colyseus-models/pokemon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export class Pokemon extends Schema implements IPokemon {
regional = false
canHoldItems = true
stages?: number
tm: Ability | null = null

constructor(shiny = false, emotion = Emotion.NORMAL) {
super()
Expand Down Expand Up @@ -5942,7 +5943,7 @@ export class RotomDrone extends Pokemon {
speDef = 4
maxPP = 50
range = 3
skill = Ability.CAMERA_FLASH
skill = Ability.FLASH
attackSprite = AttackSprite.GHOST_RANGE
}

Expand Down Expand Up @@ -6738,7 +6739,7 @@ export class Anorith extends Pokemon {
speDef = 1
maxPP = 80
range = 1
skill = Ability.ROCK_SMASH
skill = Ability.HARDEN
additional = true
attackSprite = AttackSprite.ROCK_MELEE
}
Expand All @@ -6753,7 +6754,7 @@ export class Armaldo extends Pokemon {
speDef = 2
maxPP = 80
range = 1
skill = Ability.ROCK_SMASH
skill = Ability.HARDEN
additional = true
attackSprite = AttackSprite.ROCK_MELEE
}
Expand Down
58 changes: 54 additions & 4 deletions app/models/colyseus-models/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export default class Status extends Schema implements IStatus {
@type("boolean") paralysis = false
@type("boolean") pokerus = false
@type("boolean") locked = false
@type("boolean") blinded = false
@type("boolean") armorReduction = false
@type("boolean") runeProtect = false
@type("boolean") charm = false
Expand Down Expand Up @@ -75,6 +76,7 @@ export default class Status extends Schema implements IStatus {
runeProtectCooldown = 0
charmCooldown = 0
flinchCooldown = 0
enrageCooldown = 0
spikeArmorCooldown = 0
magicBounceCooldown = 0
synchroCooldown = 3000
Expand All @@ -87,6 +89,7 @@ export default class Status extends Schema implements IStatus {
curseCooldown = 0
pokerusCooldown = 2000
lockedCooldown = 0
blindCooldown = 0
enrageDelay = 35000
darkHarvest = false
darkHarvestCooldown = 0
Expand All @@ -111,6 +114,8 @@ export default class Status extends Schema implements IStatus {
this.curseCooldown = 0
this.curse = false
this.lockedCooldown = 0
this.enrageCooldown = 0
this.blindCooldown = 0
}

hasNegativeStatus() {
Expand All @@ -128,7 +133,8 @@ export default class Status extends Schema implements IStatus {
this.flinch ||
this.armorReduction ||
this.curse ||
this.locked
this.locked ||
this.blinded
)
}

Expand All @@ -137,6 +143,10 @@ export default class Status extends Schema implements IStatus {
this.triggerPoison(1500, pokemon, undefined)
}

if (pokemon.effects.has(Effect.SMOKE) && !this.blinded) {
this.triggerBlinded(1000, pokemon)
}

if (pokemon.effects.has(Effect.STICKY_WEB) && !this.paralysis) {
this.triggerParalysis(2000, pokemon, null)
}
Expand Down Expand Up @@ -197,6 +207,10 @@ export default class Status extends Schema implements IStatus {
this.updateLocked(dt, pokemon)
}

if (this.blinded) {
this.updateBlinded(dt)
}

if (this.pokerus) {
this.updatePokerus(dt, pokemon, board)
}
Expand Down Expand Up @@ -327,14 +341,29 @@ export default class Status extends Schema implements IStatus {
}
}

triggerRage(duration: number, pokemon: PokemonEntity) {
this.enraged = true
this.protect = false
duration = this.applyAquaticReduction(duration, pokemon)
this.enrageCooldown = Math.round(duration)
pokemon.addAttackSpeed(100, pokemon, 0, false)
}

updateRage(dt: number, pokemon: PokemonEntity) {
if (this.enrageDelay - dt <= 0 && !pokemon.simulation.finished) {
if (
!this.enraged &&
this.enrageDelay - dt <= 0 &&
!pokemon.simulation.finished
) {
this.enraged = true
this.protect = false
pokemon.addAttackSpeed(100, pokemon, 0, false)
} else {
this.enrageDelay -= dt
} else if (this.enrageCooldown - dt <= 0 && this.enrageDelay - dt > 0) {
this.enraged = false
pokemon.addAttackSpeed(-100, pokemon, 0, false)
}

this.enrageDelay -= dt
}

triggerClearWing(timer: number) {
Expand Down Expand Up @@ -1130,6 +1159,27 @@ export default class Status extends Schema implements IStatus {
}
}

triggerBlinded(duration: number, pkm: PokemonEntity) {
if (!this.blinded && !this.runeProtect) {
if (pkm.status.enraged) {
duration = duration / 2
}

duration = this.applyAquaticReduction(duration, pkm)

this.blinded = true
this.blindCooldown = Math.round(duration)
}
}

updateBlinded(dt: number) {
if (this.blindCooldown - dt <= 0) {
this.blinded = false
} else {
this.blindCooldown -= dt
}
}

private applyAquaticReduction(duration: number, pkm: IPokemonEntity): number {
if (pkm.effects.has(Effect.SWIFT_SWIM)) {
duration = Math.round(duration * 0.7)
Expand Down
2 changes: 1 addition & 1 deletion app/models/precomputed/credits.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/models/precomputed/emotions-per-pokemon-index.json

Large diffs are not rendered by default.

Loading

0 comments on commit 19db196

Please sign in to comment.