pokemongoiv/PokemonGoIV/2Report.vb

384 lines
11 KiB
VB.net

' Copyright (c) 2017 imacat.
'
' 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.
' 2Report: The Pokémon GO IV report generator.
' by imacat <imacat@mail.imacat.idv.tw>, 2017-06-07
Option Explicit
' The base stats of a Pokémon.
Type aStats
sNo As String
sPokemonId As String
nStamina As Integer
nAttack As Integer
nDefense As Integer
mEvolved () As String
End Type
' The individual values of a Pokémon.
Type aIV
fLevel As Double
nStamina As Integer
nAttack As Integer
nDefense As Integer
' For sorting
nTotal As Integer
nMaxCP As Integer
nMaxMaxCP As Integer
End Type
' The parameters to find the individual values.
Type aFindIVParam
sPokemonId As String
sPokemonName As String
nCP As Integer
nHP As Integer
nStardust As Integer
nPlayerLevel As Integer
bIsNew As Boolean
nTotal As Integer
sBest As String
nMax As Integer
bIsCancelled As Boolean
End Type
' subCreateReport: Creates the Pokémon GO IV report.
Sub subCreateReport ( _
aBaseStats As aStats, aQuery As aFindIVParam, maIVs () As aIV)
Dim oDoc As Object, oSheet As Object
Dim oRange As Object, oColumns As Object, oRows As Object
Dim oCell As Object, sFormula As String
Dim nI As Integer, nJ As Integer, nCol As Integer
Dim nLeadCols As Integer, nTotalCols As Integer
Dim nEvolved As Integer, fMaxLevel As Double
Dim sCPM As String, sMaxCPM As String
Dim sColIVAttack As String, sColIVDefense As String
Dim sColIVStamina As String
Dim sPokemonName As String
Dim mData (Ubound (maIVs) + 1) As Variant, mRow () As Variant
Dim maEvBaseStats () As Variant
Dim mProps () As New com.sun.star.beans.PropertyValue
oDoc = StarDesktop.loadComponentFromURL ( _
"private:factory/scalc", "_default", 0, mProps)
oSheet = oDoc.getSheets.getByIndex (0)
nEvolved = UBound (aBaseStats.mEvolved) + 1
If nEvolved > 0 Then
ReDim maEvBaseStats (nEvolved - 1) As Variant
For nJ = 0 To nEvolved - 1
maEvBaseStats (nJ) = fnGetBaseStats (aBaseStats.mEvolved (nJ))
Next nJ
End If
If aQuery.nPlayerLevel <> 0 Then
fMaxLevel = aQuery.nPlayerLevel + 1.5
If fMaxLevel > 40 Then
fMaxLevel = 40
End If
Else
fMaxLevel = 40
End If
sMaxCPM = fnGetCPMFormula (fMaxLevel)
' Sorts the IVs
subSortIVs (aBaseStats, maEvBaseStats, maIVs, fMaxLevel)
' Fills in the report data.
mRow = Array ( _
fnGetResString ("ReportNo"), _
fnGetResString ("ReportPokemon"), _
fnGetResString ("ReportCP"), _
fnGetResString ("ReportHP"), _
fnGetResString ("ReportStardust"), _
fnGetResString ("ReportLevel"), _
fnGetResString ("ReportAttack"), _
fnGetResString ("ReportDefense"), _
fnGetResString ("ReportStamina"), _
fnGetResString ("ReportIVPercent"))
nLeadCols = UBound (mRow) + 1
nTotalCols = nLeadCols
If aBaseStats.bIsLastForm Then
nTotalCols = nTotalCols + 1
End If
For nJ = 0 To nEvolved - 1
nTotalCols = nTotalCols + 1
If maEvBaseStats (nJ).bIsLastForm Then
nTotalCols = nTotalCols + 1
End If
Next nJ
ReDim Preserve mRow (nTotalCols - 1) As Variant
nCol = nLeadCols
If aBaseStats.bIsLastForm Then
mRow (nCol) = fnReplace (fnGetResString ("ReportCPPowerUp"), _
"[Level]", fMaxLevel)
nCol = nCol + 1
End If
For nJ = 0 To nEvolved - 1
sPokemonName = fnGetResString ( _
"Pokemon" & aBaseStats.mEvolved (nJ))
mRow (nCol) = fnReplace (fnGetResString ("ReportCPEvolve"), _
"[Pokémon]", sPokemonName)
nCol = nCol + 1
If maEvBaseStats (nJ).bIsLastForm Then
mRow (nCol) = fnReplace (fnReplace ( _
fnGetResString ("ReportCPEvolvePowerUp"), _
"[Pokémon]", sPokemonName), _
"[Level]", fMaxLevel)
nCol = nCol + 1
End If
Next nJ
mData (0) = mRow
For nI = 0 To UBound (maIVs)
mRow = Array ( _
"", "", "", "", "", _
maIVs (nI).fLevel, maIVs (nI).nAttack, _
maIVs (nI).nDefense, maIVs (nI).nStamina, "")
ReDim Preserve mRow (nTotalCols - 1) As Variant
For nJ = nLeadCols To nEvolved - 1
mRow (nJ) = ""
Next nJ
mData (nI + 1) = mRow
Next nI
' Fills the query information at the first row
mData (1) (0) = aBaseStats.sNo
mData (1) (1) = aQuery.sPokemonName
mData (1) (2) = aQuery.nCP
mData (1) (3) = aQuery.nHP
mData (1) (4) = aQuery.nStardust
oRange = oSheet.getCellRangeByPosition ( _
0, 0, UBound (mData (0)), UBound (mData))
oRange.setDataArray (mData)
oRange.setPropertyValue ("VertJustify", _
com.sun.star.table.CellVertJustify.TOP)
' Fills in the CP calculation.
For nI = 0 To UBound (maIVs)
sCPM = fnGetCPMFormula (maIVs (nI).fLevel)
sColIVAttack = "G" & (nI + 2)
sColIVDefense = "H" & (nI + 2)
sColIVStamina = "I" & (nI + 2)
oCell = oSheet.getCellByPosition (nLeadCols - 1, nI + 1)
sFormula = "=(" & sColIVAttack & "+" & sColIVDefense _
& "+" & sColIVStamina & ")/45"
oCell.setFormula (sFormula)
nCol = nLeadCols
If aBaseStats.bIsLastForm Then
oCell = oSheet.getCellByPosition (nCol, nI + 1)
sFormula = fnGetCPFormula (aBaseStats, _
sColIVAttack, sColIVDefense, sColIVStamina, sMaxCPM)
oCell.setFormula (sFormula)
nCol = nCol + 1
End If
For nJ = 0 To nEvolved - 1
oCell = oSheet.getCellByPosition (nCol, nI + 1)
sFormula = fnGetCPFormula (maEvBaseStats (nJ), _
sColIVAttack, sColIVDefense, sColIVStamina, sCPM)
oCell.setFormula (sFormula)
nCol = nCol + 1
If maEvBaseStats (nJ).bIsLastForm Then
oCell = oSheet.getCellByPosition (nCol, nI + 1)
sFormula = fnGetCPFormula (maEvBaseStats (nJ), _
sColIVAttack, sColIVDefense, sColIVStamina, sMaxCPM)
oCell.setFormula (sFormula)
nCol = nCol + 1
End If
Next nJ
Next nI
oRange = oSheet.getCellRangeByPosition ( _
0, 1, 0, UBound (mData))
oRange.merge (True)
oRange = oSheet.getCellRangeByPosition ( _
1, 1, 1, UBound (mData))
oRange.merge (True)
oRange = oSheet.getCellRangeByPosition ( _
2, 1, 2, UBound (mData))
oRange.merge (True)
oRange = oSheet.getCellRangeByPosition ( _
3, 1, 3, UBound (mData))
oRange.merge (True)
oRange = oSheet.getCellRangeByPosition ( _
4, 1, 4, UBound (mData))
oRange.merge (True)
oRange = oSheet.getCellRangeByPosition ( _
9, 1, 9, UBound (mData))
oRange.setPropertyValue ("NumberFormat", 10)
oRange = oSheet.getCellRangeByPosition ( _
nLeadCols, 0, nTotalCols - 1, 0)
oRange.setPropertyValue ("IsTextWrapped", True)
oColumns = oSheet.getColumns
oColumns.getByIndex (0).setPropertyValue ("Width", 890)
oColumns.getByIndex (1).setPropertyValue ("Width", 2310)
oColumns.getByIndex (2).setPropertyValue ("Width", 890)
oColumns.getByIndex (3).setPropertyValue ("Width", 890)
oColumns.getByIndex (4).setPropertyValue ("Width", 1780)
oColumns.getByIndex (5).setPropertyValue ("Width", 860)
oColumns.getByIndex (6).setPropertyValue ("Width", 860)
oColumns.getByIndex (7).setPropertyValue ("Width", 860)
oColumns.getByIndex (8).setPropertyValue ("Width", 860)
oColumns.getByIndex (9).setPropertyValue ("Width", 1030)
For nJ = nLeadCols To nTotalCols - 1
oColumns.getByIndex (nJ).setPropertyValue ( _
"Width", 2500)
Next nJ
oRows = oSheet.getRows
oRows.getByIndex (0).setPropertyValue ("OptimalHeight", True)
End Sub
' subSortIVs: Sorts the IVs
Sub subSortIVs ( _
aBaseStats As aStats, maEvBaseStats () As aIV, _
maIVs () As aIV, fMaxLevel As Double)
Dim nI As Integer, nJ As Integer
Dim nCP As Integer
' Calculate the sorting keys.
For nI = 0 To UBound (maIVs)
maIVs (nI).nTotal = maIVs (nI).nAttack + maIVs (nI).nDefense _
+ maIVs (nI).nStamina
maIVs (nI).nMaxCP = fnCalcCP (aBaseStats, _
maIVs (nI).fLevel, maIVs (nI).nAttack, _
maIVs (nI).nDefense, maIVs (nI).nStamina)
maIVs (nI).nMaxMaxCP = fnCalcCP (aBaseStats, _
fMaxLevel, maIVs (nI).nAttack, _
maIVs (nI).nDefense, maIVs (nI).nStamina)
For nJ = 0 To UBound (aBaseStats.mEvolved)
nCP = fnCalcCP (maEvBaseStats (nJ), _
maIVs (nI).fLevel, maIVs (nI).nAttack, _
maIVs (nI).nDefense, maIVs (nI).nStamina)
If maIVs (nI).nMaxCP < nCP Then
maIVs (nI).nMaxCP = nCP
End If
nCP = fnCalcCP (maEvBaseStats (nJ), _
fMaxLevel, maIVs (nI).nAttack, _
maIVs (nI).nDefense, maIVs (nI).nStamina)
If maIVs (nI).nMaxMaxCP < nCP Then
maIVs (nI).nMaxMaxCP = nCP
End If
Next nJ
Next nI
' Sort the IVs.
For nI = 0 To UBound (maIVs) - 1
For nJ = nI + 1 To UBound (maIVs)
If fnCompareIV (maIVs (nI), maIVs (nJ)) > 0 Then
' This is an array of data. The data are actually
' allocated in sequences. maIVs (nI) is not a
' reference. They cannot simply be assigned.
subSwapIV (maIVs (nI), maIVs (nJ))
End If
Next nJ
Next nI
End Sub
' fnCompareIV: Compare two IVs for sorting
Function fnCompareIV (aIVa As aIV, aIVb As aIV) As Double
Dim nCPa As Integer, nCPb As Integer, nI As Integer
fnCompareIV = aIVb.nMaxMaxCP - aIVa.nMaxMaxCP
If fnCompareIV <> 0 Then
Exit Function
End If
fnCompareIV = aIVb.nMaxCP - aIVa.nMaxCP
If fnCompareIV <> 0 Then
Exit Function
End If
fnCompareIV = aIVb.nTotal - aIVa.nTotal
If fnCompareIV <> 0 Then
Exit Function
End If
fnCompareIV = aIVb.fLevel - aIVa.fLevel
If fnCompareIV <> 0 Then
Exit Function
End If
fnCompareIV = aIVb.nStamina - aIVa.nStamina
If fnCompareIV <> 0 Then
Exit Function
End If
fnCompareIV = aIVb.nAttack - aIVa.nAttack
If fnCompareIV <> 0 Then
Exit Function
End If
fnCompareIV = aIVb.nDefense - aIVa.nDefense
If fnCompareIV <> 0 Then
Exit Function
End If
End Function
' subSwapIV: Swaps two IVs
Function subSwapIV (aIVa As aIV, aIVb As aIV) As Double
Dim aTempIV As New aIV
With aTempIV
.fLevel = aIVa.fLevel
.nAttack = aIVa.nAttack
.nDefense = aIVa.nDefense
.nStamina = aIVa.nStamina
.nTotal = aIVa.nTotal
.nMaxCP = aIVa.nMaxCP
.nMaxMaxCP = aIVa.nMaxMaxCP
End With
With aIVa
.fLevel = aIVb.fLevel
.nAttack = aIVb.nAttack
.nDefense = aIVb.nDefense
.nStamina = aIVb.nStamina
.nTotal = aIVb.nTotal
.nMaxCP = aIVb.nMaxCP
.nMaxMaxCP = aIVb.nMaxMaxCP
End With
With aIVb
.fLevel = aTempIV.fLevel
.nAttack = aTempIV.nAttack
.nDefense = aTempIV.nDefense
.nStamina = aTempIV.nStamina
.nTotal = aTempIV.nTotal
.nMaxCP = aTempIV.nMaxCP
.nMaxMaxCP = aTempIV.nMaxMaxCP
End With
End Function
' fnGetCPFormula: Obtains the CP formula
Function fnGetCPFormula ( _
aBaseStats As aStats, sColIVAttack As String, _
sColIVDefense As String, sColIVStamina As String, _
sCPM As String) As String
fnGetCPFormula = "=FLOOR(" _
& "(" & aBaseStats.nAttack & "+" & sColIVAttack & ")" _
& "*SQRT(" & aBaseStats.nDefense & "+" & sColIVDefense & ")" _
& "*SQRT(" & aBaseStats.nStamina & "+" & sColIVStamina & ")" _
& "*POWER(" & sCPM & ";2)/10;1)"
End Function
' fnGetCPMFormula: Obtains the CPM
Function fnGetCPMFormula (fLevel As Double) As String
If fLevel = CInt (fLevel) Then
fnGetCPMFormula = "" & mCPM (fLevel)
Else
fnGetCPMFormula = "SQRT((" _
& "POWER(" & mCPM (fLevel - 0.5) & ";2)" _
& "+POWER(" & mCPM (fLevel + 0.5) & ";2))/2)"
End If
End Function