pokemongoiv/PokemonGoIV/0Main.vb

311 lines
7.9 KiB
VB.net
Raw Permalink Normal View History

2017-02-15 17:04:32 +08:00
' Copyright (c) 2016-2017 imacat.
2016-12-07 01:50:28 +08:00
'
' Licensed under the Apache License, Version 2.0 (the "License");
' you may not use this file except in compliance with the License.
' You may obtain a copy of the License at
'
' http://www.apache.org/licenses/LICENSE-2.0
'
' Unless required by applicable law or agreed to in writing, software
' distributed under the License is distributed on an "AS IS" BASIS,
' WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
' See the License for the specific language governing permissions and
' limitations under the License.
' 0Main: The main module for the Pokémon GO IV calculator
2016-11-28 00:18:16 +08:00
' by imacat <imacat@mail.imacat.idv.tw>, 2016-11-27
Option Explicit
2016-12-12 00:55:02 +08:00
' The base stats of a Pokémon.
2016-11-28 00:18:16 +08:00
Type aStats
sNo As String
sPokemonId As String
2016-12-12 00:55:02 +08:00
nStamina As Integer
nAttack As Integer
nDefense As Integer
mEvolved () As String
bIsLastForm As Boolean
2016-12-12 00:55:02 +08:00
End Type
' The individual values of a Pokémon.
Type aIV
2016-11-28 00:18:16 +08:00
fLevel As Double
nStamina As Integer
nAttack As Integer
nDefense As Integer
' For sorting
2016-11-28 00:18:16 +08:00
nTotal As Integer
nMaxCP As Integer
nMaxMaxCP As Integer
2016-11-28 00:18:16 +08:00
End Type
' The parameters to find the individual values.
Type aFindIVParam
sPokemonId As String
sPokemonName As String
2016-11-28 00:18:16 +08:00
nCP As Integer
nHP As Integer
2017-02-16 11:39:23 +08:00
nStardust As Integer
nTrainerLevel As Integer
2016-11-28 00:18:16 +08:00
bIsNew As Boolean
nTotal As Integer
2016-11-28 00:18:16 +08:00
sBest As String
nMax As Integer
bIsCancelled As Boolean
2016-11-28 00:18:16 +08:00
End Type
Private maBaseStats () As New aStats
2017-02-16 11:39:23 +08:00
Private mCPM () As Double, mStardust () As Integer
2016-11-28 00:18:16 +08:00
' subMain: The main program
Sub subMain
2016-12-12 00:55:02 +08:00
Dim aBaseStats As New aStats, maIVs As Variant, nI As Integer
Dim aQuery As New aFindIVParam
2016-11-28 00:18:16 +08:00
aQuery = fnAskParam
If aQuery.bIsCancelled Then
Exit Sub
End If
aBaseStats = fnGetBaseStats (aQuery.sPokemonId)
2016-12-12 00:55:02 +08:00
maIVs = fnFindIV (aBaseStats, aQuery)
If UBound (maIVs) = -1 Then
MsgBox fnGetResString ("ErrorNotFound")
2016-11-28 00:18:16 +08:00
Else
subCreateReport (aBaseStats, aQuery, maIVs)
2016-11-28 00:18:16 +08:00
End If
End Sub
' fnFindIV: Finds the possible individual values of the Pokémon
2016-12-12 00:55:02 +08:00
Function fnFindIV ( _
aBaseStats As aStats, aQuery As aFindIVParam) As Variant
Dim maIV () As New aIV, nN As Integer
2016-11-28 00:18:16 +08:00
Dim fLevel As Double, nStamina As Integer
Dim nAttack As Integer, nDefense As integer
Dim nI As Integer, nJ As Integer, fLevelStep As Double
2016-11-28 00:18:16 +08:00
If aQuery.sPokemonId = "" Then
2016-11-28 00:18:16 +08:00
fnFindIV = maIV
Exit Function
End If
If aQuery.bIsNew Then
fLevelStep = 1
2016-11-28 00:18:16 +08:00
Else
fLevelStep = 0.5
2016-11-28 00:18:16 +08:00
End If
2017-02-16 11:39:23 +08:00
subReadStardust
2016-12-12 00:55:02 +08:00
nN = -1
For fLevel = 1 To UBound (mStardust) Step fLevelStep
2017-02-16 11:39:23 +08:00
If mStardust (CInt (fLevel - 0.5)) = aQuery.nStardust Then
2016-11-28 00:18:16 +08:00
For nStamina = 0 To 15
If fnCalcHP (aBaseStats, fLevel, nStamina) = aQuery.nHP Then
For nAttack = 0 To 15
For nDefense = 0 To 15
If fnCalcCP (aBaseStats, fLevel, nAttack, nDefense, nStamina) = aQuery.nCP _
2016-12-12 00:55:02 +08:00
And Not fnFilterAppraisals (aQuery, nAttack, nDefense, nStamina) Then
nN = nN + 1
ReDim Preserve maIV (nN) As New aIV
With maIV (nN)
2016-11-28 00:18:16 +08:00
.fLevel = fLevel
.nAttack = nAttack
.nDefense = nDefense
.nStamina = nStamina
End With
End If
Next nDefense
Next nAttack
End If
Next nStamina
End If
Next fLevel
2016-11-28 00:18:16 +08:00
fnFindIV = maIV
End Function
' fnFilterAppraisals: Filters the IV by the appraisals.
2016-12-12 00:55:02 +08:00
Function fnFilterAppraisals (aQuery As aFindIVParam, _
nAttack As Integer, nDefense As Integer, _
nStamina As Integer) As Boolean
2016-11-28 00:18:16 +08:00
Dim nTotal As Integer, nMax As Integer, sBest As String
' The stats total.
2016-11-28 00:18:16 +08:00
nTotal = nAttack + nDefense + nStamina
If aQuery.nTotal = 1 And Not (nTotal >= 37) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
If aQuery.nTotal = 2 And Not (nTotal >= 30 And nTotal <= 36) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
If aQuery.nTotal = 3 And Not (nTotal >= 23 And nTotal <= 29) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
If aQuery.nTotal = 4 And Not (nTotal <= 22) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
' The best stats.
nMax = nAttack
If nDefense > nMax Then
nMax = nDefense
End If
If nStamina > nMax Then
nMax = nStamina
End If
If aQuery.sBest <> "" Then
sBest = ""
If nAttack = nMax Then
sBest = sBest & "Atk "
End If
If nDefense = nMax Then
sBest = sBest & "Def "
End If
If nStamina = nMax Then
sBest = sBest & "Sta "
End If
If aQuery.sBest <> sBest Then
fnFilterAppraisals = True
Exit Function
End If
End If
' The max stat value.
If aQuery.nMax = 1 And Not (nMax = 15) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
If aQuery.nMax = 2 And Not (nMax = 13 Or nMax = 14) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
If aQuery.nMax = 3 And Not (nMax >= 8 And nMax <= 12) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
If aQuery.nMax = 4 And Not (nMax <= 7) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
fnFilterAppraisals = False
End Function
' fnCalcCP: Calculates the combat power of the Pokémon
2016-12-12 00:55:02 +08:00
Function fnCalcCP (aBaseStats As aStats, fLevel As Double, _
nAttack As Integer, nDefense As Integer, _
nStamina As Integer) As Integer
Dim nCP As Integer
2016-12-08 07:39:31 +08:00
nCP = fnFloor ((aBaseStats.nAttack + nAttack) _
2016-11-28 00:18:16 +08:00
* ((aBaseStats.nDefense + nDefense) ^ 0.5) _
* ((aBaseStats.nStamina + nStamina) ^ 0.5) _
* (fnGetCPM (fLevel) ^ 2) / 10)
2016-12-08 07:39:31 +08:00
If nCP < 10 Then
2016-12-12 00:55:02 +08:00
nCP = 10
2016-12-08 07:39:31 +08:00
End If
fnCalcCP = nCP
2016-11-28 00:18:16 +08:00
End Function
' fnCalcHP: Calculates the hit points of the Pokémon
2016-12-12 00:55:02 +08:00
Function fnCalcHP (aBaseStats As aStats, _
fLevel As Double, nStamina As Integer) As Integer
2016-12-09 15:30:34 +08:00
Dim nHP As Integer
nHP = fnFloor ((aBaseStats.nStamina + nStamina) _
2016-11-28 00:18:16 +08:00
* fnGetCPM (fLevel))
2016-12-09 15:30:34 +08:00
If nHP < 10 Then
nHP = 10
End If
fnCalcHP = nHP
2016-11-28 00:18:16 +08:00
End Function
' fnGetBaseStats: Returns the base stats of the Pokémon.
Function fnGetBaseStats (sPokemonId As String) As aStats
2016-11-28 00:18:16 +08:00
Dim nI As Integer
subReadBaseStats
For nI = 0 To UBound (maBaseStats)
If maBaseStats (nI).sPokemonId = sPokemonId Then
2016-11-28 00:18:16 +08:00
fnGetBaseStats = maBaseStats (nI)
Exit Function
End If
Next nI
End Function
2016-11-28 00:18:16 +08:00
' fnGetCPM: Returns the combat power multiplier.
Function fnGetCPM (fLevel As Double) As Double
Dim nI As Integer
subReadCPM
If CInt (fLevel) = fLevel Then
fnGetCPM = mCPM (fLevel)
Else
fnGetCPM = ((mCPM (fLevel - 0.5) ^ 2 _
+ mCPM (fLevel + 0.5) ^ 2) / 2) ^ 0.5
End If
End Function
2016-11-28 00:18:16 +08:00
' fnFloor: Returns the floor of the number
Function fnFloor (fNumber As Double) As Integer
fnFloor = CInt (fNumber - 0.5)
End Function
' fnReplace: Replaces all occurrances of a term to another.
Function fnReplace ( _
sText As String, sFrom As String, sTo As String) As String
Dim sResult As String, nPos As Integer
sResult = sText
nPos = InStr (sResult, sFrom)
Do While nPos <> 0
sResult = Left (sResult, nPos - 1) & sTo _
& Right (sResult, Len (sResult) - nPos - Len (sFrom) + 1)
nPos = InStr (nPos + Len (sTo), sResult, sFrom)
Loop
fnReplace = sResult
End Function
2016-11-28 00:18:16 +08:00
' subReadBaseStats: Reads the base stats table.
Sub subReadBaseStats
Dim mData As Variant, nI As Integer, nJ As Integer, nK As Integer
Dim nEvolved As Integer, mEvolved () As Variant
2016-11-28 00:18:16 +08:00
If UBound (maBaseStats) = -1 Then
mData = fnGetBaseStatsData
ReDim Preserve maBaseStats (UBound (mData)) As New aStats
For nI = 0 To UBound (mData)
With maBaseStats (nI)
.sNo = mData (nI) (1)
.sPokemonId = mData (nI) (0)
.nStamina = mData (nI) (2)
.nAttack = mData (nI) (3)
.nDefense = mData (nI) (4)
2016-11-28 00:18:16 +08:00
End With
nEvolved = UBound (mData (nI) (5)) + 1
mEvolved = Array ()
maBaseStats (nI).bIsLastForm = True
If nEvolved > 0 Then
ReDim mEvolved (nEvolved - 1) As Variant
For nJ = 0 To nEvolved - 1
mEvolved (nJ) = mData (nI) (5) (nJ)
Next nJ
maBaseStats (nI).mEvolved = mEvolved
maBaseStats (nI).bIsLastForm = False
End If
Next nI
2016-11-28 00:18:16 +08:00
End If
End Sub
2016-11-28 00:18:16 +08:00
' subReadCPM: Reads the CPM table.
Sub subReadCPM
If UBound (mCPM) = -1 Then
mCPM = fnGetCPMData
2016-11-28 00:18:16 +08:00
End If
End Sub
2016-11-28 00:18:16 +08:00
2017-02-16 11:39:23 +08:00
' subReadStardust: Reads the stardust table.
Sub subReadStardust
If UBound (mStardust) = -1 Then
mStardust = fnGetStardustData
2016-11-28 00:18:16 +08:00
End If
End Sub