battle logic
This commit is contained in:
		
							parent
							
								
									f257bd594b
								
							
						
					
					
						commit
						c41c5dca7c
					
				
							
								
								
									
										269
									
								
								src/battle.ts
									
									
									
									
									
								
							
							
						
						
									
										269
									
								
								src/battle.ts
									
									
									
									
									
								
							| @ -1,4 +1,5 @@ | |||||||
| import { Message, TextBasedChannel } from "discord.js"; | import { Message, TextBasedChannel, TextChannel } from "discord.js"; | ||||||
|  | import { CBClient } from "./cbclient"; | ||||||
| import { Character, CHARACTERS, Effect, PotencyStatus, Target } from "./characters"; | import { Character, CHARACTERS, Effect, PotencyStatus, Target } from "./characters"; | ||||||
| import { Player } from "./models/player"; | import { Player } from "./models/player"; | ||||||
| import { Unit } from "./models/unit"; | import { Unit } from "./models/unit"; | ||||||
| @ -9,24 +10,32 @@ export enum BattleState { | |||||||
|     Team2Win |     Team2Win | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | enum EffectType { | ||||||
|  |     Resistance = 'resistance', | ||||||
|  |     Accuracy = 'accuracy', | ||||||
|  |     Speed = 'speed', | ||||||
|  |     Damage = 'damage' | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | interface PotencyEffect { | ||||||
|  |     type: EffectType | ||||||
|  |     duration: number | ||||||
|  |     potency: number | ||||||
|  | } | ||||||
|  | 
 | ||||||
| interface StatusEffects { | interface StatusEffects { | ||||||
|     poison: number |     poison: number | ||||||
|     regeneration: number |     regeneration: number | ||||||
|     burn: number |     burn: number | ||||||
|     confusion: number |     confusion: number | ||||||
|     stun: number |     stun: number | ||||||
| } |     taunt: number | ||||||
| 
 |  | ||||||
| interface PotencyEffects { |  | ||||||
|     resistanceChange: PotencyStatus[] |  | ||||||
|     accuracyChange: PotencyStatus[] |  | ||||||
|     speedChange: PotencyStatus[] |  | ||||||
|     damageChange: PotencyStatus[] |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class BattleUnit { | class BattleUnit { | ||||||
|     constructor (unit: Unit) { |     constructor (unit: Unit, battle: Battle) { | ||||||
|         this.unit = unit; |         this.unit = unit; | ||||||
|  |         this.battle = battle; | ||||||
|         this.defaultHealth = unit.health; |         this.defaultHealth = unit.health; | ||||||
|         this.health = unit.health; |         this.health = unit.health; | ||||||
|         this.speed = unit.speed; |         this.speed = unit.speed; | ||||||
| @ -34,6 +43,7 @@ class BattleUnit { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     unit: Unit |     unit: Unit | ||||||
|  |     battle: Battle | ||||||
|     defaultHealth: number |     defaultHealth: number | ||||||
|     health: number |     health: number | ||||||
|     speed: number |     speed: number | ||||||
| @ -43,40 +53,41 @@ class BattleUnit { | |||||||
|         regeneration: 0, |         regeneration: 0, | ||||||
|         burn: 0, |         burn: 0, | ||||||
|         confusion: 0, |         confusion: 0, | ||||||
|         stun: 0 |         stun: 0, | ||||||
|     } |         taunt: 0 | ||||||
|     potencyEffects: PotencyEffects = { |  | ||||||
|         resistanceChange: [], |  | ||||||
|         accuracyChange: [], |  | ||||||
|         speedChange: [], |  | ||||||
|         damageChange: [] |  | ||||||
|     } |     } | ||||||
|  |     potencyEffects: PotencyEffect[] = [] | ||||||
|     active = true |     active = true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export class Battle { | export class Battle { | ||||||
|     constructor (channel: TextBasedChannel, player1: Player, player2: Player, team1: [Unit, Unit, Unit], team2: [Unit, Unit, Unit]) { |     constructor (client: CBClient, channel: TextBasedChannel, player1: Player, player2: Player, team1: [Unit, Unit, Unit], team2: [Unit, Unit, Unit]) { | ||||||
|  |         this.client = client; | ||||||
|         this.channel = channel; |         this.channel = channel; | ||||||
|         this.player1 = player1; |         this.player1 = player1; | ||||||
|         this.player2 = player2; |         this.player2 = player2; | ||||||
|         this.team1 = team1.map(unit => {return new BattleUnit(unit)}) as [BattleUnit, BattleUnit, BattleUnit]; |         this.team1 = team1.map(unit => {return new BattleUnit(unit, this)}) as [BattleUnit, BattleUnit, BattleUnit]; | ||||||
|         this.team2 = team2.map(unit => {return new BattleUnit(unit)}) as [BattleUnit, BattleUnit, BattleUnit]; |         this.team2 = team2.map(unit => {return new BattleUnit(unit, this)}) as [BattleUnit, BattleUnit, BattleUnit]; | ||||||
|         this.units = this.team1.concat(this.team2) as [BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit]; |         this.units = this.team1.concat(this.team2) as [BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     simulateRound (): BattleState { |     simulateRound (): BattleState { | ||||||
|  |         //reset log each round
 | ||||||
|         this.log = ''; |         this.log = ''; | ||||||
|         this.tickStatuses(this.units); |         this.tickStatuses(this.units); | ||||||
|         this.checkAlive(this.units); |         this.checkAlive(this.units); | ||||||
|         this.useSkills(this.units); |         this.useSkills(this.units); | ||||||
| 
 | 
 | ||||||
|  |         //check to see if a team has no active units
 | ||||||
|         if (!this.team1.filter(e => {return e.active})[0]) return BattleState.Team2Win; |         if (!this.team1.filter(e => {return e.active})[0]) return BattleState.Team2Win; | ||||||
|         else if (!this.team2.filter(e => {return e.active})[0]) return BattleState.Team1Win; |         else if (!this.team2.filter(e => {return e.active})[0]) return BattleState.Team1Win; | ||||||
|  |         //let repeating rounds be handled by the invoker
 | ||||||
|         else return BattleState.Ongoing; |         else return BattleState.Ongoing; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     tickStatuses (units: BattleUnit[]) { |     tickStatuses (units: BattleUnit[]) { | ||||||
|         for (const unit of units) { |         for (const unit of units) { | ||||||
|  |             //dead touhous tell no tales
 | ||||||
|             if (!unit.active) continue; |             if (!unit.active) continue; | ||||||
| 
 | 
 | ||||||
|             if (unit.statusEffects.poison > 0) { |             if (unit.statusEffects.poison > 0) { | ||||||
| @ -85,21 +96,26 @@ export class Battle { | |||||||
|                 unit.health -= change; |                 unit.health -= change; | ||||||
|                 this.appendLog(`${unit.character.nameShort} took ${change} poison damage!`); |                 this.appendLog(`${unit.character.nameShort} took ${change} poison damage!`); | ||||||
|             } |             } | ||||||
|             this.log += '\n'; |  | ||||||
|             if (unit.statusEffects.regeneration > 0) { |             if (unit.statusEffects.regeneration > 0) { | ||||||
|                 unit.statusEffects.regeneration-- |                 unit.statusEffects.regeneration-- | ||||||
|                 const change = Math.floor(unit.defaultHealth/10) |                 const change = Math.floor(unit.defaultHealth/10) | ||||||
|                 unit.health += change; |                 unit.health += change; | ||||||
|                 this.appendLog(`${unit.character.nameShort} regenerated ${change} health!`); |                 this.appendLog(`${unit.character.nameShort} regenerated ${change} health!`); | ||||||
|             } |             } | ||||||
|             this.log += '\n'; |  | ||||||
|             if (unit.statusEffects.burn > 0) { |             if (unit.statusEffects.burn > 0) { | ||||||
|                 unit.statusEffects.burn-- |                 unit.statusEffects.burn-- | ||||||
|                 unit.health -= 5; |                 unit.health -= 5; | ||||||
|                 this.appendLog(`${unit.character.nameShort} took 5 burn damage!`); |                 this.appendLog(`${unit.character.nameShort} took 5 burn damage!`); | ||||||
|             } |             } | ||||||
|             this.log += '\n'; |             if (unit.statusEffects.confusion > 0) unit.statusEffects.confusion--; | ||||||
|  |             if (unit.statusEffects.stun > 0) unit.statusEffects.stun--; | ||||||
|  |             if (unit.statusEffects.taunt > 0) unit.statusEffects.taunt--; | ||||||
|  |             for (const status of unit.potencyEffects) { | ||||||
|  |                 status.duration--; | ||||||
|  |             } | ||||||
|  |             unit.potencyEffects.filter(Battle.buffIsActive); | ||||||
|         } |         } | ||||||
|  |         this.appendLog(''); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     useSkills (units: BattleUnit[]) { |     useSkills (units: BattleUnit[]) { | ||||||
| @ -107,75 +123,175 @@ export class Battle { | |||||||
| 
 | 
 | ||||||
|         for (let i = 0; i < units.length; i++) { |         for (let i = 0; i < units.length; i++) { | ||||||
|             const rolls = [] |             const rolls = [] | ||||||
|             let modifiedSpeed = units[i].speed |             //modify speed by speedChange effects
 | ||||||
|             for (const change of units[i].potencyEffects.speedChange) { |             const affectedSpeed = units[i].speed  | ||||||
|                 modifiedSpeed -= change.potency; |                 + units[i].potencyEffects | ||||||
|             } |                 .filter(status => {return status.type === 'speed'}) | ||||||
|             for (let o = 0; o < modifiedSpeed; o++) { |                 .reduce((a, b) => a + b.potency, 0); | ||||||
|  |             //roll n
 | ||||||
|  |             for (let o = 0; o < affectedSpeed; o++) { | ||||||
|                 rolls.push(Math.random()); |                 rolls.push(Math.random()); | ||||||
|             } |             } | ||||||
|  |             //pick max
 | ||||||
|             const initiative = Math.max(...rolls); |             const initiative = Math.max(...rolls); | ||||||
|             order.push([i, initiative]); |             order.push([i, initiative]); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         //sort turn order
 | ||||||
|         order.sort((a, b) => {return b[1] - a[1]}); |         order.sort((a, b) => {return b[1] - a[1]}); | ||||||
| 
 | 
 | ||||||
|         console.debug(order); |         console.debug(order); | ||||||
| 
 | 
 | ||||||
|         for (const initiative of order) { |         for (const initiative of order) { | ||||||
|  |             //unit is self
 | ||||||
|             const unit = units[initiative[0]]; |             const unit = units[initiative[0]]; | ||||||
|  |             //dead touhous tell no tales
 | ||||||
|             if (!unit.active) continue; |             if (!unit.active) continue; | ||||||
| 
 | 
 | ||||||
|  |             //pick random skill
 | ||||||
|             const skill = unit.character.skills[Math.floor(Math.random()*unit.character.skills.length)]; |             const skill = unit.character.skills[Math.floor(Math.random()*unit.character.skills.length)]; | ||||||
|             const team = initiative[0] < 3 ? 1 : 2 |             const team = initiative[0] < 3 ? this.team1 : this.team2; | ||||||
|             const target = team === 1 ? this.team2[Math.floor(Math.random()*this.team2.length)] : this.team1[Math.floor(Math.random()*this.team1.length)]; |             const opponentTeam = initiative[0] < 3 ? this.team2 : this.team1; | ||||||
|             const allyTarget = team === 1 ? this.team1[Math.floor(Math.random()*this.team1.length)] : this.team2[Math.floor(Math.random()*this.team2.length)]; |             //targets are chosen randomly between the units with the most taunt
 | ||||||
|  |             const opponentTargets = opponentTeam.filter(unit => { | ||||||
|  |                 return unit.statusEffects.taunt >= Math.max(...opponentTeam.map(unit => {return unit.statusEffects.taunt})); | ||||||
|  |             }); | ||||||
|  |             //pick random targets
 | ||||||
|  |             const target = opponentTargets[Math.floor(Math.random()*opponentTargets.length)]; | ||||||
|  |             const allyTarget = team[Math.floor(Math.random()*team.length)]; | ||||||
|  |             //modify accuracy by accuracyChange effects
 | ||||||
|  |             const affectedAccuracy = (skill.accuracy || 100) | ||||||
|  |                 + unit.potencyEffects | ||||||
|  |                 .filter(status => {return status.type === 'accuracy'}) | ||||||
|  |                 .reduce((a, b) => a + b.potency, 0); | ||||||
| 
 | 
 | ||||||
|             if (skill.accuracy && Math.random()*100 > skill.accuracy) { |             //chance to stun
 | ||||||
|  |             if (unit.statusEffects.stun) this.appendLog(`${unit.character.nameShort} is stunned!`); | ||||||
|  |             //chance to confused
 | ||||||
|  |             else if (unit.statusEffects.confusion && Math.random()*100 > 75) { | ||||||
|  |                 unit.health -= 5; | ||||||
|  |                 this.appendLog(`${unit.character.nameShort} hit herself in confusion!`); | ||||||
|  |             } | ||||||
|  |             //chance to miss
 | ||||||
|  |             else if (Math.random()*100 > affectedAccuracy) { | ||||||
|                 this.appendLog(`${unit.character.nameShort} used ${skill.name}, but missed!`); |                 this.appendLog(`${unit.character.nameShort} used ${skill.name}, but missed!`); | ||||||
|             } |             } | ||||||
| 
 |             else { | ||||||
|             this.appendLog(`${unit.character.nameShort} used ${skill.name}!`); |                 this.appendLog(`${unit.character.nameShort} used ${skill.name}!`); | ||||||
|             for (const effect of skill.effects) { |                 for (const effect of skill.effects) { | ||||||
|                 switch (effect.target){ |                     switch (effect.target){ | ||||||
|                     case Target.Self: |                         case Target.Self: | ||||||
|                     this.runEffect(effect, unit, [unit]); |                         this.runEffect(effect, unit, [unit]); | ||||||
|                     break; |                         break; | ||||||
|                     case Target.Team: |                         case Target.Team: | ||||||
|                     this.runEffect(effect, unit, team === 1 ? this.team1 : this.team2); |                         this.runEffect(effect, unit, team); | ||||||
|                     break; |                         break; | ||||||
|                     case Target.OneTeammate: |                         case Target.OneTeammate: | ||||||
|                     this.runEffect(effect, unit, [allyTarget]); |                         this.runEffect(effect, unit, [allyTarget]); | ||||||
|                     break; |                         break; | ||||||
|                     case Target.OneOpponent: |                         case Target.TrueRandomTeammate: | ||||||
|                     this.runEffect(effect, unit, [target]); |                         this.runEffect(effect, unit, [team[Math.floor(Math.random()*team.length)]]); | ||||||
|                     break; |                         break; | ||||||
|                     case Target.AllOpponents: |                         case Target.OneOpponent: | ||||||
|                     this.runEffect(effect, unit, team === 1 ? this.team2 : this.team1); |                         this.runEffect(effect, unit, [target]); | ||||||
|                     break; |                         break; | ||||||
|                     case Target.TrueRandomOpponent: |                         case Target.AllOpponents: | ||||||
|                     this.runEffect(effect, unit, [team === 1 ? this.team2[Math.floor(Math.random()*this.team2.length)] : this.team1[Math.floor(Math.random()*this.team1.length)]]); |                         this.runEffect(effect, unit, opponentTeam); | ||||||
|                     break; |                         break; | ||||||
|  |                         case Target.TrueRandomOpponent: | ||||||
|  |                         this.runEffect(effect, unit, [opponentTeam[Math.floor(Math.random()*opponentTeam.length)]]); | ||||||
|  |                         break; | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |              | ||||||
|             this.checkAlive(this.units); |             this.checkAlive(this.units); | ||||||
|  |             this.appendLog(''); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     runEffect (effect: Effect, self: BattleUnit, targets: BattleUnit[]) { |     runEffect (effect: Effect, self: BattleUnit, targets: BattleUnit[]) { | ||||||
|         if (effect.damage) { |         for (const target of targets) { | ||||||
|             for (const target of targets) { |             //chance to miss
 | ||||||
|  |             if (effect.accuracy && Math.random()*100 > effect.accuracy) { | ||||||
|  |                 this.appendLog(`${target.character.nameShort} avoided the attack!`); | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (effect.damage) { | ||||||
|                 let damage = effect.damage; |                 let damage = effect.damage; | ||||||
|                 for (const statChange of self.potencyEffects.damageChange) { |                 //multiply by damageChange sum
 | ||||||
|                     Math.round(damage *= 1+(statChange.potency/100)); |                 damage *= self.potencyEffects | ||||||
|                 } |                     .filter(status => {return status.type === 'damage'}) | ||||||
|                 for (const statChange of target.potencyEffects.resistanceChange) { |                     .reduce((a, b) => a + (b.potency/100), 1); | ||||||
|                     Math.round(damage *= 1-(statChange.potency/100)); |                 //multiply by resistanceChange sum
 | ||||||
|                 } |                 damage *= self.potencyEffects | ||||||
|  |                     .filter(status => {return status.type === 'resistance'}) | ||||||
|  |                     .reduce((a, b) => a - (b.potency/100), 1); | ||||||
|  |                 damage = Math.round(damage) | ||||||
| 
 | 
 | ||||||
|                 this.appendLog(`${target.character.nameShort} took ${damage} damage!`); |                 this.appendLog(`${target.character.nameShort} took ${damage} damage!`); | ||||||
|                 target.health -= damage; |                 target.health -= damage; | ||||||
|             } |             } | ||||||
|  |             if (effect.heal) { | ||||||
|  |                 this.appendLog(`${target.character.nameShort} restored ${effect.heal} health!`); | ||||||
|  |                 target.health += effect.heal; | ||||||
|  |             } | ||||||
|  |             if (effect.cure) { | ||||||
|  |                 this.appendLog(`${target.character.nameShort} was cured of ailments!`); | ||||||
|  |                 target.statusEffects.burn = 0; | ||||||
|  |                 target.statusEffects.confusion = 0; | ||||||
|  |                 target.statusEffects.stun = 0; | ||||||
|  |                 target.statusEffects.poison = 0; | ||||||
|  |                 target.statusEffects.taunt = 0; | ||||||
|  |                 target.potencyEffects.filter(Battle.isBuff); | ||||||
|  |             } | ||||||
|  |             if (effect.dispel) { | ||||||
|  |                 this.appendLog(`${target.character.nameShort} was dispelled of buffs!`); | ||||||
|  |                 target.statusEffects.regeneration = 0; | ||||||
|  |                 target.potencyEffects.filter(Battle.isDebuff); | ||||||
|  |             } | ||||||
|  |             if (effect.poison) { | ||||||
|  |                 target.statusEffects.poison = Math.max(target.statusEffects.poison, effect.poison); | ||||||
|  |                 this.appendLog(`${target.character.nameShort} was poisoned!`); | ||||||
|  |             } | ||||||
|  |             if (effect.regeneration) { | ||||||
|  |                 target.statusEffects.regeneration = Math.max(target.statusEffects.regeneration, effect.regeneration); | ||||||
|  |                 this.appendLog(`${target.character.nameShort} began recovering!`); | ||||||
|  |             } | ||||||
|  |             if (effect.burn) { | ||||||
|  |                 target.statusEffects.burn = Math.max(target.statusEffects.burn, effect.burn); | ||||||
|  |                 this.appendLog(`${target.character.nameShort} caught fire!`); | ||||||
|  |             } | ||||||
|  |             if (effect.confusion) { | ||||||
|  |                 target.statusEffects.confusion = Math.max(target.statusEffects.confusion, effect.confusion); | ||||||
|  |                 this.appendLog(`${target.character.nameShort} was confused!`); | ||||||
|  |             } | ||||||
|  |             if (effect.stun) { | ||||||
|  |                 target.statusEffects.stun = Math.max(target.statusEffects.stun, effect.stun); | ||||||
|  |                 this.appendLog(`${target.character.nameShort} was stunned!`); | ||||||
|  |             } | ||||||
|  |             if (effect.taunt) { | ||||||
|  |                 target.statusEffects.taunt = Math.max(target.statusEffects.taunt, effect.taunt); | ||||||
|  |                 this.appendLog(`${target.character.nameShort} started drawing aggression!`); | ||||||
|  |             } | ||||||
|  |             if (effect.resistanceChange) { | ||||||
|  |                 target.potencyEffects.push(Battle.createPotencyEffect(effect.resistanceChange, EffectType.Resistance)); | ||||||
|  |                 this.appendLog(`${target.character.nameShort} ${effect.resistanceChange.potency >= 0 ? 'gained' : 'lost'} ${effect.resistanceChange.potency}% resistance!`); | ||||||
|  |             } | ||||||
|  |             if (effect.accuracyChange) { | ||||||
|  |                 target.potencyEffects.push(Battle.createPotencyEffect(effect.accuracyChange, EffectType.Accuracy)); | ||||||
|  |                 this.appendLog(`${target.character.nameShort} ${effect.accuracyChange.potency >= 0 ? 'gained' : 'lost'} ${effect.accuracyChange.potency}% accuracy!`); | ||||||
|  |             } | ||||||
|  |             if (effect.speedChange) { | ||||||
|  |                 target.potencyEffects.push(Battle.createPotencyEffect(effect.speedChange, EffectType.Speed)); | ||||||
|  |                 this.appendLog(`${target.character.nameShort} ${effect.speedChange.potency >= 0 ? 'gained' : 'lost'} ${effect.speedChange.potency} speed!`); | ||||||
|  |             } | ||||||
|  |             if (effect.damageChange) { | ||||||
|  |                 target.potencyEffects.push(Battle.createPotencyEffect(effect.damageChange, EffectType.Damage)); | ||||||
|  |                 this.appendLog(`${target.character.nameShort} ${effect.damageChange.potency >= 0 ? 'gained' : 'lost'} ${effect.damageChange.potency}% damage!`); | ||||||
|  |             } | ||||||
|  |             if (effect.function) Battle.skillFunctions[effect.function](target, this); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -196,13 +312,44 @@ export class Battle { | |||||||
|         return this.log; |         return this.log; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     static isBuff (status: PotencyStatus) { | ||||||
|  |         return status.potency >= 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static isDebuff (status: PotencyStatus) { | ||||||
|  |         return status.potency < 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static buffIsActive (status: PotencyStatus) { | ||||||
|  |         return status.duration > 0; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     static createPotencyEffect (status: PotencyStatus, type: EffectType): PotencyEffect { | ||||||
|  |         return { | ||||||
|  |             type: type, | ||||||
|  |             duration: status.duration, | ||||||
|  |             potency: status.potency | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     message?: Message |     message?: Message | ||||||
|     log = "" |     log = "" | ||||||
| 
 | 
 | ||||||
|  |     client: CBClient | ||||||
|     channel: TextBasedChannel |     channel: TextBasedChannel | ||||||
|     player1: Player |     player1: Player | ||||||
|     player2: Player |     player2: Player | ||||||
|     team1: [BattleUnit, BattleUnit, BattleUnit] |     team1: [BattleUnit, BattleUnit, BattleUnit] | ||||||
|     team2: [BattleUnit, BattleUnit, BattleUnit] |     team2: [BattleUnit, BattleUnit, BattleUnit] | ||||||
|     units: [BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit] |     units: [BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit, BattleUnit] | ||||||
|  | 
 | ||||||
|  |     static skillFunctions: { [key: string]: (target: BattleUnit, battle: Battle) => void; } = { | ||||||
|  |         bruh: (target: BattleUnit, battle: Battle) => { | ||||||
|  |             if (!(battle.channel instanceof TextChannel)) return; | ||||||
|  |             const targetMember = battle.channel.guild.members.resolve(target.unit.user_id); | ||||||
|  |             if (!targetMember) return; | ||||||
|  |             targetMember.kick('april fools').catch(err => console.error); | ||||||
|  |             battle.appendLog(`${targetMember} was kicked by <@208460737180467200>!`); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -6,6 +6,7 @@ export enum Target { | |||||||
|     Self = "self", |     Self = "self", | ||||||
|     Team = "team", |     Team = "team", | ||||||
|     OneTeammate = "oneTeammate", |     OneTeammate = "oneTeammate", | ||||||
|  |     TrueRandomTeammate = "trueRandomTeammate", | ||||||
|     OneOpponent = "oneOpponent", |     OneOpponent = "oneOpponent", | ||||||
|     AllOpponents = "allOpponents", |     AllOpponents = "allOpponents", | ||||||
|     TrueRandomOpponent = "trueRandomOpponent" |     TrueRandomOpponent = "trueRandomOpponent" | ||||||
| @ -26,11 +27,13 @@ const Effect = z.object({ | |||||||
|     damage: z.optional(z.number().int()), |     damage: z.optional(z.number().int()), | ||||||
|     heal: z.optional(z.number().int()), |     heal: z.optional(z.number().int()), | ||||||
|     cure: z.optional(z.boolean()), |     cure: z.optional(z.boolean()), | ||||||
|  |     dispel: z.optional(z.boolean()), | ||||||
|     poison: z.optional(z.number().int()), |     poison: z.optional(z.number().int()), | ||||||
|     regeneration: z.optional(z.number().int()), |     regeneration: z.optional(z.number().int()), | ||||||
|     burn: z.optional(z.number().int()), |     burn: z.optional(z.number().int()), | ||||||
|     confusion: z.optional(z.number().int()), |     confusion: z.optional(z.number().int()), | ||||||
|     stun: z.optional(z.number().int()), |     stun: z.optional(z.number().int()), | ||||||
|  |     taunt: z.optional(z.number().int()), | ||||||
|     resistanceChange: z.optional(PotencyStatus), |     resistanceChange: z.optional(PotencyStatus), | ||||||
|     accuracyChange: z.optional(PotencyStatus), |     accuracyChange: z.optional(PotencyStatus), | ||||||
|     speedChange: z.optional(PotencyStatus), |     speedChange: z.optional(PotencyStatus), | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ export class BattleTestCommand implements SlashCommand { | |||||||
|         const client = int.client as CBClient; |         const client = int.client as CBClient; | ||||||
|         const you = await client.findOrCreatePlayer(int.user.id); |         const you = await client.findOrCreatePlayer(int.user.id); | ||||||
|         const units = (await Unit.findAll()); |         const units = (await Unit.findAll()); | ||||||
|         const battle = new Battle(int.channel!, you, you, units.slice(0, 3) as [Unit, Unit, Unit], units.slice(3, 6) as [Unit, Unit, Unit]); |         const battle = new Battle(client, int.channel!, you, you, units.slice(0, 3) as [Unit, Unit, Unit], units.slice(3, 6) as [Unit, Unit, Unit]); | ||||||
| 
 | 
 | ||||||
|         await int.reply({ |         await int.reply({ | ||||||
|             content: 'gottem' |             content: 'gottem' | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user