Namespace BattleSystem
'''
''' Provides an interface to load additional GameMode moves.
'''
Public Class GameModeAttackLoader
'The default relative path to load moves from (Content folder).
Const PATH As String = "Data\Moves\"
'List of loaded moves.
Shared LoadedMoves As New List(Of Attack)
'''
''' Load the attack list for the loaded GameMode.
'''
''' The game won't try to load the list if the default GameMode is selected.
Public Shared Sub Load()
LoadedMoves.Clear()
If GameModeManager.ActiveGameMode.IsDefaultGamemode = False Then
If System.IO.Directory.Exists(GameController.GamePath & "\" & GameModeManager.ActiveGameMode.ContentPath & "\" & PATH) = True Then
For Each file As String In System.IO.Directory.GetFiles(GameController.GamePath & "\" & GameModeManager.ActiveGameMode.ContentPath & PATH, "*.dat")
LoadMove(file)
Next
End If
End If
If LoadedMoves.Count > 0 Then
Logger.Debug("Loaded " & LoadedMoves.Count.ToString() & " GameMode move(s).")
End If
End Sub
'''
''' Loads a move from a file.
'''
''' The file to load the move from.
Private Shared Sub LoadMove(ByVal file As String)
Dim move As New Attack() 'Load the default Pound move.
move.IsGameModeMove = True
Dim content() As String = System.IO.File.ReadAllLines(file)
Dim key As String = ""
Dim value As String = ""
Dim setID As Boolean = False 'Controls if the move sets its ID.
Dim nonCommentLines As Integer = 0
Try
'Go through lines of the file and set the properties depending on the content.
'Lines starting with # are comments.
For Each l As String In content
If l.Contains("|") = True And l.StartsWith("#") = False Then
nonCommentLines += 1
key = l.Remove(l.IndexOf("|"))
value = l.Remove(0, l.IndexOf("|") + 1)
Select Case key.ToLower()
Case "copymove"
If nonCommentLines = 1 Then
move.gmCopyMove = CInt(value)
Dim _attack As Attack = Attack.GetAttackByID(move.gmCopyMove)
move.Power = _attack.Power
move.Accuracy = _attack.Accuracy
move.Name = _attack.Name
move.OriginalPP = _attack.OriginalPP
move.CurrentPP = _attack.CurrentPP
move.MaxPP = _attack.MaxPP
move.Category = _attack.Category
move.ContestCategory = _attack.ContestCategory
move.Description = _attack.Description
move.CriticalChance = _attack.CriticalChance
move.IsHMMove = _attack.IsHMMove
move.Target = _attack.Target
move.Priority = _attack.Priority
move.TimesToAttack = _attack.TimesToAttack
move.EffectChances = _attack.EffectChances
move.MakesContact = _attack.MakesContact
move.HasSecondaryEffect = _attack.HasSecondaryEffect
move.IsHealingMove = _attack.IsHealingMove
move.IsDamagingMove = _attack.IsDamagingMove
move.IsProtectMove = _attack.IsProtectMove
move.IsOneHitKOMove = _attack.IsOneHitKOMove
move.IsRecoilMove = _attack.IsRecoilMove
move.IsTrappingMove = _attack.IsTrappingMove
move.RemovesOwnFrozen = _attack.RemovesOwnFrozen
move.RemovesOppFrozen = _attack.RemovesOppFrozen
move.SwapsOutOwnPokemon = _attack.SwapsOutOwnPokemon
move.SwapsOutOppPokemon = _attack.SwapsOutOppPokemon
move.ProtectAffected = _attack.ProtectAffected
move.MagicCoatAffected = _attack.MagicCoatAffected
move.SnatchAffected = _attack.SnatchAffected
move.MirrorMoveAffected = _attack.MirrorMoveAffected
move.KingsrockAffected = _attack.KingsrockAffected
move.CounterAffected = _attack.CounterAffected
move.IsAffectedBySubstitute = _attack.IsAffectedBySubstitute
move.ImmunityAffected = _attack.ImmunityAffected
move.IsWonderGuardAffected = _attack.IsWonderGuardAffected
move.DisabledWhileGravity = _attack.DisabledWhileGravity
move.UseEffectiveness = _attack.UseEffectiveness
move.UseAccEvasion = _attack.UseAccEvasion
move.CanHitInMidAir = _attack.CanHitInMidAir
move.CanHitUnderground = _attack.CanHitUnderground
move.CanHitUnderwater = _attack.CanHitUnderwater
move.CanHitSleeping = _attack.CanHitSleeping
move.CanGainSTAB = _attack.CanGainSTAB
move.UseOppDefense = _attack.UseOppDefense
move.UseOppEvasion = _attack.UseOppEvasion
move.IsPulseMove = _attack.IsPulseMove
move.IsBulletMove = _attack.IsBulletMove
move.IsJawMove = _attack.IsJawMove
move.IsDanceMove = _attack.IsDanceMove
move.IsExplosiveMove = _attack.IsExplosiveMove
move.IsPowderMove = _attack.IsPowderMove
move.IsPunchingMove = _attack.IsPunchingMove
move.IsSlicingMove = _attack.IsSlicingMove
move.IsSoundMove = _attack.IsSoundMove
move.IsWindMove = _attack.IsWindMove
move.FocusOppPokemon = _attack.FocusOppPokemon
move.Disabled = _attack.Disabled
move.AIField1 = _attack.AIField1
move.AIField2 = _attack.AIField2
move.AIField3 = _attack.AIField3
Else
Logger.Log(Logger.LogTypes.ErrorMessage, "GameModeAttackLoader.vb: The CopyMove property should be the first property set in the move definition file. It is currently property number " & nonCommentLines.ToString & ".")
End If
Case "id"
move.ID = CInt(value)
move.OriginalID = CInt(value)
setID = True
Case "pp"
move.CurrentPP = CInt(value)
move.MaxPP = CInt(value)
move.OriginalPP = CInt(value)
Case "function", "movehits"
If move.GameModeFunction = "" Then
move.GameModeFunction = value
Else
Dim OldFunctionList = move.GameModeFunction
move.GameModeFunction = OldFunctionList & "|" & value
End If
Case "multiplier", "getbasepower"
If move.GameModeBasePower = "" Then
move.GameModeBasePower = value
Else
Dim OldBasePowerCalculationList = move.GameModeBasePower
move.GameModeBasePower = OldBasePowerCalculationList & "|" & value
End If
Case "power", "basepower"
move.Power = CInt(value)
Case "accuracy", "acc"
move.Accuracy = CInt(value)
Case "type"
If StringHelper.IsNumeric(value) = False Then
move.Type = GameModeElementLoader.GetElementByName(value)
Else
move.Type = GameModeElementLoader.GetElementByID(CInt(value))
End If
Case "category"
Select Case value.ToLower()
Case "physical"
move.Category = Attack.Categories.Physical
Case "special"
move.Category = Attack.Categories.Special
Case "status"
move.Category = Attack.Categories.Status
End Select
Case "contestcategory"
Select Case value.ToLower()
Case "tough"
move.ContestCategory = Attack.ContestCategories.Tough
Case "smart"
move.ContestCategory = Attack.ContestCategories.Smart
Case "beauty"
move.ContestCategory = Attack.ContestCategories.Beauty
Case "cool"
move.ContestCategory = Attack.ContestCategories.Cool
Case "cute"
move.ContestCategory = Attack.ContestCategories.Cute
End Select
Case "name"
move.Name = value
Case "description"
move.Description = value
Case "criticalchance", "critical"
move.CriticalChance = CInt(value)
Case "hmmove", "ishmmove"
move.IsHMMove = CBool(value)
Case "priority"
move.Priority = CInt(value)
Case "timestoattack", "tta"
move.gmTimesToAttack = value
Case "makescontact", "contact"
move.MakesContact = CBool(value)
Case "protectaffected"
move.ProtectAffected = CBool(value)
Case "magiccoataffected"
move.MagicCoatAffected = CBool(value)
Case "snatchaffected"
move.SnatchAffected = CBool(value)
Case "mirrormoveaffected"
move.MirrorMoveAffected = CBool(value)
Case "kingsrockaffected"
move.KingsrockAffected = CBool(value)
Case "counteraffected"
move.CounterAffected = CBool(value)
Case "disabledduringgravity", "disabledwhilegravity"
move.DisabledWhileGravity = CBool(value)
Case "useeffectiveness"
move.UseEffectiveness = CBool(value)
Case "ishealingmove"
move.IsHealingMove = CBool(value)
Case "removesownfrozen", "removesfrozen"
move.RemovesOwnFrozen = CBool(value)
Case "removesoppfrozen"
move.RemovesOppFrozen = CBool(value)
Case "isrecoilmove"
move.IsRecoilMove = CBool(value)
Case "ispunchingmove"
move.IsPunchingMove = CBool(value)
Case "immunityaffected"
move.ImmunityAffected = CBool(value)
Case "isdamagingmove"
move.IsDamagingMove = CBool(value)
Case "isprotectmove"
move.IsProtectMove = CBool(value)
Case "issoundmove"
move.IsSoundMove = CBool(value)
Case "isaffectedbysubstitute"
move.IsAffectedBySubstitute = CBool(value)
Case "isonehitkomove"
move.IsOneHitKOMove = CBool(value)
Case "iswonderguardaffected"
move.IsWonderGuardAffected = CBool(value)
Case "useaccevasion"
move.UseAccEvasion = CBool(value)
Case "canhitinmidair"
move.CanHitInMidAir = CBool(value)
Case "canhitunderground"
move.CanHitUnderground = CBool(value)
Case "canhitunderwater"
move.CanHitUnderwater = CBool(value)
Case "canhitsleeping"
move.CanHitSleeping = CBool(value)
Case "cangainstab"
move.CanGainSTAB = CBool(value)
Case "ispowdermove"
move.IsPowderMove = CBool(value)
Case "istrappingmove"
move.IsTrappingMove = CBool(value)
Case "ispulsemove"
move.IsPulseMove = CBool(value)
Case "isbulletmove"
move.IsBulletMove = CBool(value)
Case "isjawmove"
move.IsJawMove = CBool(value)
Case "useoppdefense"
move.UseOppDefense = CBool(value)
Case "useoppevasion"
move.UseOppEvasion = CBool(value)
Case "deductpp"
move.gmDeductPP = CBool(value)
Case "aifield1", "aifield2", "aifield3"
Dim AIFieldType As Attack.AIField = Attack.AIField.Nothing
Select Case value
Case "damage"
AIFieldType = Attack.AIField.Damage
Case "poison"
AIFieldType = Attack.AIField.Poison
Case "burn"
AIFieldType = Attack.AIField.Burn
Case "paralysis"
AIFieldType = Attack.AIField.Paralysis
Case "sleep"
AIFieldType = Attack.AIField.Sleep
Case "freeze"
AIFieldType = Attack.AIField.Freeze
Case "confusion"
AIFieldType = Attack.AIField.Confusion
Case "confuseown"
AIFieldType = Attack.AIField.ConfuseOwn
Case "canpoison"
AIFieldType = Attack.AIField.CanPoison
Case "canburn"
AIFieldType = Attack.AIField.CanBurn
Case "canparalyze"
AIFieldType = Attack.AIField.CanParalyze
Case "cansleep"
AIFieldType = Attack.AIField.CanSleep
Case "canfreeze"
AIFieldType = Attack.AIField.CanFreeze
Case "canconfuse"
AIFieldType = Attack.AIField.CanConfuse
Case "raiseattack"
AIFieldType = Attack.AIField.RaiseAttack
Case "raisedefense"
AIFieldType = Attack.AIField.RaiseDefense
Case "raisespattack"
AIFieldType = Attack.AIField.RaiseSpAttack
Case "raisespdefense"
AIFieldType = Attack.AIField.RaiseSpDefense
Case "raisespeed"
AIFieldType = Attack.AIField.RaiseSpeed
Case "raiseaccuracy"
AIFieldType = Attack.AIField.RaiseAccuracy
Case "raiseevasion"
AIFieldType = Attack.AIField.RaiseEvasion
Case "lowerattack"
AIFieldType = Attack.AIField.LowerAttack
Case "lowerdefense"
AIFieldType = Attack.AIField.LowerDefense
Case "lowerspattack"
AIFieldType = Attack.AIField.LowerSpAttack
Case "lowerspdefense"
AIFieldType = Attack.AIField.LowerSpDefense
Case "lowerspeed"
AIFieldType = Attack.AIField.LowerSpeed
Case "loweraccuracy"
AIFieldType = Attack.AIField.LowerAccuracy
Case "lowerevasion"
AIFieldType = Attack.AIField.LowerEvasion
Case "canraiseattack"
AIFieldType = Attack.AIField.CanRaiseAttack
Case "canraisedefense"
AIFieldType = Attack.AIField.CanRaiseDefense
Case "canraisespattack"
AIFieldType = Attack.AIField.CanRaiseSpAttack
Case "canraisespdefense"
AIFieldType = Attack.AIField.CanRaiseSpDefense
Case "canraisespeed"
AIFieldType = Attack.AIField.CanRaiseSpeed
Case "canraiseaccuracy"
AIFieldType = Attack.AIField.CanRaiseAccuracy
Case "canrauseevasion"
AIFieldType = Attack.AIField.CanRauseEvasion
Case "canlowerattack"
AIFieldType = Attack.AIField.CanLowerAttack
Case "canlowerdefense"
AIFieldType = Attack.AIField.CanLowerDefense
Case "canlowerspattack"
AIFieldType = Attack.AIField.CanLowerSpAttack
Case "canlowerspdefense"
AIFieldType = Attack.AIField.CanLowerSpDefense
Case "canlowerspeed"
AIFieldType = Attack.AIField.CanLowerSpeed
Case "canloweraccuracy"
AIFieldType = Attack.AIField.CanLowerAccuracy
Case "canlowerevasion"
AIFieldType = Attack.AIField.CanLowerEvasion
Case "flinch"
AIFieldType = Attack.AIField.Flinch
Case "canflinch"
AIFieldType = Attack.AIField.CanFlinch
Case "infatuation"
AIFieldType = Attack.AIField.Infatuation
Case "trap"
AIFieldType = Attack.AIField.Trap
Case "ohko"
AIFieldType = Attack.AIField.OHKO
Case "multiturn"
AIFieldType = Attack.AIField.MultiTurn
Case "recoil"
AIFieldType = Attack.AIField.Recoil
Case "healing"
AIFieldType = Attack.AIField.Healing
Case "curestatus"
AIFieldType = Attack.AIField.CureStatus
Case "support"
AIFieldType = Attack.AIField.Support
Case "recharge"
AIFieldType = Attack.AIField.Recharge
Case "highpriority"
AIFieldType = Attack.AIField.HighPriority
Case "absorbing"
AIFieldType = Attack.AIField.Absorbing
Case "selfdestruct"
AIFieldType = Attack.AIField.Selfdestruct
Case "thrawout"
AIFieldType = Attack.AIField.ThrawOut
Case "cannotmiss"
AIFieldType = Attack.AIField.CannotMiss
Case "removereflectlightscreen"
AIFieldType = Attack.AIField.RemoveReflectLightscreen
End Select
If AIFieldType <> Attack.AIField.Nothing Then
If key.EndsWith("1") Then
move.AIField1 = AIFieldType
ElseIf key.EndsWith("2") Then
move.AIField2 = AIFieldType
ElseIf key.EndsWith("3") Then
move.AIField3 = AIFieldType
End If
End If
Case "usemoveanims"
move.gmUseMoveAnims = Attack.GetAttackByID(CInt(value))
End Select
End If
Next
Catch ex As Exception
'If an error occurs loading a move, log the error.
Logger.Log(Logger.LogTypes.ErrorMessage, "GameModeAttackLoader.vb: Error loading GameMode move from file """ & file & """: " & ex.Message & "; Last Key/Value pair successfully loaded: " & key & "|" & value)
End Try
If nonCommentLines > 0 Then
If setID = True Then
If move.ID >= 1000 Then
Dim testMove As Attack = Attack.GetAttackByID(move.ID)
If testMove.IsDefaultMove = True Then
If Localization.TokenExists("move_name_" & move.ID.ToString) = True Then
move.Name = Localization.GetString("move_name_" & move.ID.ToString)
End If
LoadedMoves.Add(move) 'Add the move.
Else
Logger.Log(Logger.LogTypes.ErrorMessage, "GameModeAttackLoader.vb: User defined moves are not allowed to have an ID of an already existing move or an ID below 1000. The ID for the move loaded from """ & file & """ has the ID " & move.ID.ToString() & ", which is the ID of an already existing move (" & testMove.Name & ").")
End If
Else
Logger.Log(Logger.LogTypes.ErrorMessage, "GameModeAttackLoader.vb: User defined moves are not allowed to have an ID of an already existing move or an ID below 1000. The ID for the move loaded from """ & file & """ has the ID " & move.ID.ToString() & ", which is smaller than 1000.")
End If
Else
Logger.Log(Logger.LogTypes.ErrorMessage, "GameModeAttackLoader.vb: User defined moves must set their ID through the ""ID"" property, however the move loaded from """ & file & """ has no ID set so it will be ignored.")
End If
Else
Debug.Print("GameModeAttackLoader.vb: The move loaded from """ & file & """ has no valid lines so it will be ignored.")
End If
End Sub
'''
''' Returns a custom move based on its ID.
'''
''' The ID of the custom move.
''' Returns a move or nothing.
Public Shared Function GetAttackByID(ByVal ID As Integer) As Attack
For Each m As Attack In LoadedMoves
If m.ID = ID Then
Return m
End If
Next
Return Nothing
End Function
End Class
End Namespace