Adding scripts that add creature higher level stats

This commit is contained in:
2024-09-01 01:35:31 -04:00
parent 3383cb1323
commit f7e2bf2450
3 changed files with 290 additions and 0 deletions

22
scripts/go.mod Normal file
View File

@@ -0,0 +1,22 @@
module github.com/araxiaonline/mod-mythic-plus
go 1.22.4
require (
git.sr.ht/~sbinet/gg v0.5.0 // indirect
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect
github.com/campoy/embedmd v1.0.0 // indirect
github.com/go-fonts/liberation v0.3.2 // indirect
github.com/go-latex/latex v0.0.0-20231108140139-5c1ce85aa4ea // indirect
github.com/go-pdf/fpdf v0.9.0 // indirect
github.com/goccmack/gocc v0.0.0-20230228185258-2292f9e40198 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
golang.org/x/image v0.14.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.15.0 // indirect
gonum.org/v1/gonum v0.15.0 // indirect
gonum.org/v1/plot v0.14.0 // indirect
)

59
scripts/go.sum Normal file
View File

@@ -0,0 +1,59 @@
git.sr.ht/~sbinet/gg v0.5.0 h1:6V43j30HM623V329xA9Ntq+WJrMjDxRjuAB1LFWF5m8=
git.sr.ht/~sbinet/gg v0.5.0/go.mod h1:G2C0eRESqlKhS7ErsNey6HHrqU1PwsnCQlekFi9Q2Oo=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY=
github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk=
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw=
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM=
github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY=
github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
github.com/go-fonts/liberation v0.3.2 h1:XuwG0vGHFBPRRI8Qwbi5tIvR3cku9LUfZGq/Ar16wlQ=
github.com/go-fonts/liberation v0.3.2/go.mod h1:N0QsDLVUQPy3UYg9XAc3Uh3UDMp2Z7M1o4+X98dXkmI=
github.com/go-latex/latex v0.0.0-20231108140139-5c1ce85aa4ea h1:DfZQkvEbdmOe+JK2TMtBM+0I9GSdzE2y/L1/AmD8xKc=
github.com/go-latex/latex v0.0.0-20231108140139-5c1ce85aa4ea/go.mod h1:Y7Vld91/HRbTBm7JwoI7HejdDB0u+e9AUBO9MB7yuZk=
github.com/go-pdf/fpdf v0.9.0 h1:PPvSaUuo1iMi9KkaAn90NuKi+P4gwMedWPHhj8YlJQw=
github.com/go-pdf/fpdf v0.9.0/go.mod h1:oO8N111TkmKb9D7VvWGLvLJlaZUQVPM+6V42pp3iV4Y=
github.com/goccmack/gocc v0.0.0-20230228185258-2292f9e40198 h1:FSii2UQeSLngl3jFoR4tUKZLprO7qUlh/TKKticc0BM=
github.com/goccmack/gocc v0.0.0-20230228185258-2292f9e40198/go.mod h1:DTh/Y2+NbnOVVoypCCQrovMPDKUGp4yZpSbWg5D0XIM=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ=
gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo=
gonum.org/v1/plot v0.14.0 h1:+LBDVFYwFe4LHhdP8coW6296MBEY4nQ+Y4vuUpJopcE=
gonum.org/v1/plot v0.14.0/go.mod h1:MLdR9424SJed+5VqC6MsouEpig9pZX2VZ57H9ko2bXU=
honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=

209
scripts/main.go Normal file
View File

@@ -0,0 +1,209 @@
package main
import (
"fmt"
"log"
"math"
"gonum.org/v1/gonum/mat"
)
// Data structure to hold the input data
type Data struct {
Level float64
Class int
BaseHP0 float64
BaseHP1 float64
BaseHP2 float64
BaseMana float64
BaseArmor float64
AttackPower float64
RangedAttackPower float64
DamageBase float64
DamageExp1 float64
DamageExp2 float64
Comment *string
}
func main() {
// Input data (levels 68 to 80 for each class)
data := []Data{
{68, 1, 3834, 6542, 6986, 0, 6126, 292, 41, 39.2381, 94.4934, 104.527, nil},
{68, 2, 3067, 5233, 6986, 2991, 6116, 276, 31, 36.3244, 87.2677, 104.527, nil},
{68, 4, 3834, 6542, 6986, 0, 5527, 292, 41, 39.2381, 94.4934, 104.527, nil},
{68, 8, 2684, 4580, 5588, 6882, 4928, 130, 27, 33.3048, 80.1061, 96.6868, nil},
{69, 1, 3942, 6761, 7984, 0, 6423, 298, 43, 39.9047, 99.5328, 114.153, nil},
{69, 2, 3153, 5409, 7984, 3080, 6412, 282, 32, 36.974, 91.8916, 114.153, nil},
{69, 4, 3942, 6761, 7984, 0, 5795, 298, 43, 39.9047, 99.5328, 114.153, nil},
{69, 8, 2759, 4733, 6387, 7031, 5167, 133, 28, 33.8695, 84.2722, 105.591, nil},
{70, 1, 4050, 6986, 8982, 0, 6719, 304, 44, 40.5714, 104.527, 123.779, nil},
{70, 2, 3240, 5589, 8982, 3155, 6708, 286, 33, 37.6361, 96.7364, 123.779, nil},
{70, 4, 4050, 6986, 8982, 0, 6062, 304, 44, 40.5714, 104.527, 123.779, nil},
{70, 8, 2835, 4890, 7185, 7196, 5404, 135, 28, 34.4369, 88.3402, 114.496, nil},
{71, 1, 4163, 7181, 9291, 0, 7018, 308, 48, 41.2381, 106.357, 127.382, nil},
{71, 2, 3330, 5744, 9291, 3231, 7007, 290, 37, 38.2899, 98.3977, 127.383, nil},
{71, 4, 4163, 7181, 9291, 0, 6332, 308, 48, 41.2381, 106.357, 127.382, nil},
{71, 8, 2914, 5027, 7432, 7332, 5645, 137, 31, 35.0025, 92.4034, 117.829, nil},
{72, 1, 4278, 7380, 9610, 0, 7318, 314, 53, 41.9047, 108.071, 131.091, nil},
{72, 2, 3422, 5903, 9610, 3309, 7305, 296, 40, 38.9492, 99.8571, 131.092, nil},
{72, 4, 4278, 7380, 9610, 0, 6602, 314, 53, 41.9047, 108.071, 131.091, nil},
{72, 8, 2995, 5166, 7688, 7500, 5886, 140, 34, 35.5693, 96.5068, 121.259, nil},
{73, 1, 4399, 7588, 9940, 0, 7618, 320, 58, 42.5714, 118.643, 134.908, nil},
{73, 2, 3519, 6070, 9940, 3387, 7604, 302, 44, 39.6048, 101.451, 134.908, nil},
{73, 4, 4399, 7580, 9940, 0, 6872, 320, 58, 42.5714, 118.643, 134.908, nil},
{73, 8, 3098, 5311, 7952, 7654, 6126, 143, 37, 36.1353, 100.617, 124.79, nil},
{74, 1, 4524, 7804, 10282, 0, 7918, 354, 63, 43.2381, 120.434, 138.836, nil},
{74, 2, 3619, 6243, 10282, 3466, 7903, 334, 48, 40.2629, 102.955, 138.836, nil},
{74, 4, 4524, 1, 10282, 0, 7143, 354, 63, 43.2381, 120.434, 138.836, nil},
{74, 8, 3186, 1, 8225, 7809, 6368, 158, 41, 36.7018, 104.723, 128.423, nil},
{75, 1, 4652, 8025, 10635, 0, 8219, 392, 68, 43.9047, 122.226, 142.878, nil},
{75, 2, 3722, 6420, 10635, 3561, 8204, 370, 53, 40.9193, 104.52, 142.878, nil},
{75, 4, 4652, 1, 10635, 0, 7415, 392, 68, 43.9047, 122.226, 142.878, nil},
{75, 8, 3256, 5617, 8508, 7981, 6610, 175, 45, 37.268, 108.832, 132.162, nil},
{76, 1, 4781, 8247, 11001, 0, 8520, 432, 74, 44.5713, 124.018, 147.038, nil},
{76, 2, 3825, 6602, 11001, 3643, 8503, 408, 57, 41.5757, 106.085, 147.038, nil},
{76, 4, 4781, 1, 11001, 0, 7686, 432, 74, 44.5713, 124.018, 147.038, nil},
{76, 8, 3367, 1, 8800, 8139, 6851, 193, 49, 37.8342, 112.941, 136.01, nil},
{77, 1, 4916, 8480, 11379, 0, 8822, 478, 81, 45.2379, 125.81, 151.319, nil},
{77, 2, 3933, 6784, 11379, 3725, 8803, 452, 62, 42.2321, 107.65, 151.319, nil},
{77, 4, 4916, 1, 11379, 0, 7958, 478, 81, 45.2379, 125.81, 151.319, nil},
{77, 8, 3462, 1, 9103, 8313, 7094, 214, 54, 38.4004, 117.05, 139.97, nil},
{78, 1, 5052, 8715, 11770, 0, 9124, 528, 88, 45.9045, 127.602, 155.724, nil},
{78, 2, 4042, 6972, 11770, 3809, 9104, 500, 68, 42.8885, 109.215, 155.724, nil},
{78, 4, 5052, 1, 11770, 0, 8230, 528, 88, 45.9045, 127.602, 155.724, nil},
{78, 8, 3558, 1, 9416, 8459, 7335, 236, 58, 38.9666, 121.159, 144.045, nil},
{79, 1, 5194, 8960, 12175, 0, 9426, 582, 95, 46.5711, 129.394, 160.258, nil},
{79, 2, 4155, 7167, 12175, 3893, 9405, 550, 74, 43.5449, 110.78, 160.258, nil},
{79, 4, 5194, 1, 12175, 0, 8503, 582, 95, 46.5711, 129.394, 160.258, nil},
{79, 8, 3658, 1, 9740, 8636, 7579, 260, 64, 39.5328, 125.268, 148.239, nil},
{80, 1, 5342, 9215, 12600, 0, 9729, 642, 103, 47.2377, 131.186, 164.924, nil},
{80, 2, 4274, 7373, 12600, 3994, 9706, 608, 80, 44.2013, 112.345, 164.924, nil},
{80, 4, 5342, 1, 12600, 0, 8776, 642, 103, 47.2377, 131.186, 164.924, nil},
{80, 8, 3739, 1, 10080, 8814, 7822, 287, 69, 40.099, 129.377, 152.555, nil},
}
// Classes to process
classes := []int{1, 2, 4, 8}
// Columns to process
columns := []string{"BaseHP0", "BaseHP1", "BaseHP2", "BaseMana", "BaseArmor", "AttackPower", "RangedAttackPower", "DamageBase", "DamageExp1", "DamageExp2"}
// Fit polynomials for each class and each attribute
classCoefficients := make(map[int]map[string][]float64)
for _, class := range classes {
classData := filterDataByClass(data, class)
// Store coefficients for each column for this class
coefficients := make(map[string][]float64)
for _, column := range columns {
levels := make([]float64, 0)
values := make([]float64, 0)
for _, d := range classData {
var value float64
switch column {
case "BaseHP0":
value = d.BaseHP0
case "BaseHP1":
value = d.BaseHP1
case "BaseHP2":
value = d.BaseHP2
case "BaseMana":
value = d.BaseMana
case "BaseArmor":
value = d.BaseArmor
case "AttackPower":
value = d.AttackPower
case "RangedAttackPower":
value = d.RangedAttackPower
case "DamageBase":
value = d.DamageBase
case "DamageExp1":
value = d.DamageExp1
case "DamageExp2":
value = d.DamageExp2
}
if value > 1 {
levels = append(levels, d.Level)
values = append(values, value)
}
}
if len(levels) == 0 || len(values) == 0 {
continue // skip if no valid data
}
// Perform polynomial regression (degree 2)
coeffs, err := polyFit(levels, values, 2)
if err != nil {
log.Fatalf("Failed to calculate polynomial fit for class %d, %s: %v", class, column, err)
}
coefficients[column] = coeffs
}
classCoefficients[class] = coefficients
}
// Generate SQL insert statements for levels 81 to 100
fmt.Println("INSERT INTO mythicplus_classlevelstats (class, level, basehp0, basehp1, basehp2, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2) VALUES")
for _, class := range classes {
for level := 81.0; level <= 100; level++ {
predictedValues := calculateScaledValues(level, classCoefficients[class])
fmt.Printf("(%d, %.0f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.4f, %.4f, %.4f),\n",
class, level,
predictedValues["BaseHP0"], predictedValues["BaseHP1"], predictedValues["BaseHP2"], predictedValues["BaseMana"],
predictedValues["BaseArmor"], predictedValues["AttackPower"], predictedValues["RangedAttackPower"],
predictedValues["DamageBase"], predictedValues["DamageExp1"], predictedValues["DamageExp2"])
}
}
}
// filterDataByClass filters the dataset by class
func filterDataByClass(data []Data, class int) []Data {
var filtered []Data
for _, d := range data {
if d.Class == class {
filtered = append(filtered, d)
}
}
return filtered
}
// polyFit performs a polynomial fit of the given degree on the data.
func polyFit(x, y []float64, degree int) ([]float64, error) {
// Create the Vandermonde matrix
n := len(x)
vander := mat.NewDense(n, degree+1, nil)
for i := range x {
for j := 0; j <= degree; j++ {
vander.Set(i, j, math.Pow(x[i], float64(j)))
}
}
// Create a vector for the output values
yVec := mat.NewVecDense(len(y), y)
// Solve the least squares problem
var coeffs mat.VecDense
err := coeffs.SolveVec(vander, yVec)
if err != nil {
return nil, err
}
return coeffs.RawVector().Data, nil
}
// calculateScaledValues takes a level and coefficient map to return scaled values
func calculateScaledValues(level float64, coeffs map[string][]float64) map[string]float64 {
values := make(map[string]float64)
for column, c := range coeffs {
// Use the polynomial formula: ax^2 + bx + c
values[column] = c[2]*math.Pow(level, 2) + c[1]*level + c[0]
}
return values
}