pokemongoiv/oxt/PokemonGoIV/0Main.xba

314 lines
8.5 KiB
Plaintext
Raw Normal View History

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
2017-02-15 17:04:32 +08:00
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="0Main" script:language="StarBasic">&apos; Copyright (c) 2016-2017 imacat.
2016-12-07 01:50:28 +08:00
&apos;
&apos; Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
&apos; you may not use this file except in compliance with the License.
&apos; You may obtain a copy of the License at
&apos;
&apos; http://www.apache.org/licenses/LICENSE-2.0
&apos;
&apos; Unless required by applicable law or agreed to in writing, software
&apos; distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
&apos; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
&apos; See the License for the specific language governing permissions and
&apos; limitations under the License.
&apos; 0Main: The main module for the Pokémon GO IV calculator
&apos; by imacat &lt;imacat@mail.imacat.idv.tw&gt;, 2016-11-27
2016-11-28 00:18:16 +08:00
Option Explicit
&apos; The base stats of a Pokémon.
2016-11-28 00:18:16 +08:00
Type aStats
sNo As String
sPokemonId As String
nStamina As Integer
nAttack As Integer
nDefense As Integer
mEvolved () As String
bIsLastForm As Boolean
End Type
&apos; 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
&apos; 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
&apos; The parameters to find the individual values.
2016-11-28 00:18:16 +08:00
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
&apos; subMain: The main program
2016-11-28 00:18:16 +08:00
Sub subMain
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)
maIVs = fnFindIV (aBaseStats, aQuery)
If UBound (maIVs) = -1 Then
MsgBox fnGetResString (&quot;ErrorNotFound&quot;)
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
&apos; fnFindIV: Finds the possible individual values of the Pokémon
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 = &quot;&quot; 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
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 _
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
&apos; fnFilterAppraisals: Filters the IV by the appraisals.
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
&apos; The stats total.
2016-11-28 00:18:16 +08:00
nTotal = nAttack + nDefense + nStamina
If aQuery.nTotal = 1 And Not (nTotal &gt;= 37) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
If aQuery.nTotal = 2 And Not (nTotal &gt;= 30 And nTotal &lt;= 36) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
If aQuery.nTotal = 3 And Not (nTotal &gt;= 23 And nTotal &lt;= 29) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
If aQuery.nTotal = 4 And Not (nTotal &lt;= 22) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
&apos; The best stats.
2016-11-28 00:18:16 +08:00
nMax = nAttack
If nDefense &gt; nMax Then
2016-11-28 00:18:16 +08:00
nMax = nDefense
End If
If nStamina &gt; nMax Then
2016-11-28 00:18:16 +08:00
nMax = nStamina
End If
If aQuery.sBest &lt;&gt; &quot;&quot; Then
sBest = &quot;&quot;
2016-11-28 00:18:16 +08:00
If nAttack = nMax Then
sBest = sBest &amp; &quot;Atk &quot;
2016-11-28 00:18:16 +08:00
End If
If nDefense = nMax Then
sBest = sBest &amp; &quot;Def &quot;
2016-11-28 00:18:16 +08:00
End If
If nStamina = nMax Then
sBest = sBest &amp; &quot;Sta &quot;
2016-11-28 00:18:16 +08:00
End If
If aQuery.sBest &lt;&gt; sBest Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
End If
&apos; 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 &gt;= 8 And nMax &lt;= 12) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
If aQuery.nMax = 4 And Not (nMax &lt;= 7) Then
2016-11-28 00:18:16 +08:00
fnFilterAppraisals = True
Exit Function
End If
fnFilterAppraisals = False
End Function
&apos; fnCalcCP: Calculates the combat power of the Pokémon
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 &lt; 10 Then
nCP = 10
2016-12-08 07:39:31 +08:00
End If
fnCalcCP = nCP
2016-11-28 00:18:16 +08:00
End Function
&apos; fnCalcHP: Calculates the hit points of the Pokémon
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 &lt; 10 Then
nHP = 10
End If
fnCalcHP = nHP
2016-11-28 00:18:16 +08:00
End Function
&apos; 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
&apos; fnGetCPM: Returns the combat power multiplier.
2016-11-28 00:18:16 +08:00
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
&apos; fnFloor: Returns the floor of the number
2016-11-28 00:18:16 +08:00
Function fnFloor (fNumber As Double) As Integer
fnFloor = CInt (fNumber - 0.5)
End Function
&apos; 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 &lt;&gt; 0
sResult = Left (sResult, nPos - 1) &amp; sTo _
&amp; Right (sResult, Len (sResult) - nPos - Len (sFrom) + 1)
nPos = InStr (nPos + Len (sTo), sResult, sFrom)
Loop
fnReplace = sResult
End Function
&apos; subReadBaseStats: Reads the base stats table.
2016-11-28 00:18:16 +08:00
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 &gt; 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
&apos; subReadCPM: Reads the CPM table.
2016-11-28 00:18:16 +08:00
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
&apos; 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
</script:module>