# this is only needed for data visualization - can be safely removed
#library(ggplot2)
# config
#should weapon loadouts be permuted?
PERMUTE_WEAPON_LOADOUTS <- 1
#read or generate lookuptable
GENERATE_LOOKUP_TABLE <- 1
#number of weapons per ship
WEAPON_COUNT <- 8
#constants
#engagementrange
RANGE <- 1000
#fudge factor
ERROR_SD <- 0.05
#the fudge factor should be a function of range (more error in
#position at greater range), but not a function of weapon
#firing angle, and be expressed in terms of pixels
ERROR <- ERROR_SD * RANGE
#default distribution of damage to armor cells
ARMOR_DAMAGE_DISTRIBUTION <- matrix(0,nrow=5,ncol=5)
ARMOR_DAMAGE_DISTRIBUTION[1:5,2:4] <- 1/30
ARMOR_DAMAGE_DISTRIBUTION[2:4,1:5] <- 1/30
ARMOR_DAMAGE_DISTRIBUTION[2:4,2:4] <- 1/15
ARMOR_DAMAGE_DISTRIBUTION[1,1] <- 0
ARMOR_DAMAGE_DISTRIBUTION[1,5] <- 0
ARMOR_DAMAGE_DISTRIBUTION[5,1] <- 0
ARMOR_DAMAGE_DISTRIBUTION[5,5] <- 0
#divide armor rating by this number to obtain armor per cell
ARMOR_FRACTION = 15
#least amount of protection armor affords
MINIMUM_ARMOR_PROTECTION = 0.05
#calculation constant
MINIMUM_CELL_PROTECTION = ARMOR_FRACTION * MINIMUM_ARMOR_PROTECTION
#note: a sample size of 1000 or 10000 would likely be spreadeptable
#in practice, reducing distribution computation time meaningfully.
#I just wanted to go big.
SHOTS <- 100000
#classes
#Holds the data weapon calculations need
Weapon <- setRefClass(
"Weapon",
fields = list(
damage = "numeric",
shieldDamageFactor = "numeric",
min_spread = "numeric",
max_spread = "numeric",
spread_per_shot = "numeric",
ticks = "list"
)
)
#Holds the data ship calculations need
Ship <- setRefClass(
"Ship",
fields = list(
id = "character",
hull = "numeric",
shieldEfficiency = "numeric",
shieldUpkeep = "numeric"
fluxDissipation = "numeric",
maxFlux = "numeric",
armorRating = "numeric",
widthInPixels = "numeric",
)
getArmorGrid <- function() {
armorPerCell <- .self$armorRating / ARMOR_FRACTION
return(matrix(armorPerCell, 5, .self$widthInPixels + 4))
}
)
#functions
getShieldDamageFactor <- function(damageTypeName) {
if (damageTypeName == "KINETIC") return(2)
else if (damageTypeName == "HIGH_EXPLOSIVE") return(0.5)
else if (damageTypeName == "ENERGY") return(1)
else if (damageTypeName == "FRAGMENATION") return(0.25)
}
#Return a list of the integer shot counts expected
#in each one second interval of one firing cycle.
#
#TODO: Define firing cycle
getTicks <- function(chargeUp,
chargeDown,
refireDelay,
burstDelay,
burstSize)
{
#TODO: Implement
}
#Return a list of all Weapon class instances for a dataframe
getWeapons <- function(weaponData) {
index <- 1
weapons <- list()
for (id in weaponData["id"]) {
row <- subset(weaponData, name = id)
weapons[index + 1] <- Weapon(
damage = as.numeric(row["damage/shot"]),
shieldDamageFactor = getShieldDamageFactor(as.numeric(
row["type"])),
min_spread = as.numeric(row["min spread"])
max_spread = as.numeric(row["max spread"])
spread_per_shot = as.numeric(row["spread/shot"])
)
index <- 1
}
return(weapons)
}
#Return a list of all Ship class instances for a dataframe
getShips <- function(shipData) {
index <- 1
ships <- list()
for (shipId in shipData["id"]) {
row <- subset(weaponData, name = shipId)
weapons[index + 1] <- Ship(
id = shipId,
hull = as.numeric(row["hitpoints"]),
shieldEfficiency = as.numeric(row["shield efficiency"]),
shieldUpkeep = as.numeric(row["shield upkeep"])
fluxDissipation = as.numeric(row["flux dissipation"]),
maxFlux = as.numeric(row["max flux"),
armorRating = as.numeric("armor rating"),
widthInPixels = #TODO: Implement
)
index <- 1
}
return(ships)
}
#where does one shot hit within the weapon's arc of fire, in
#pixel difference from the target? get a random angle in
#degrees spreadording to a uniform distribution, then consider
#that the circumference is 2 pi * range pixels, so the hit
#coordinates in pixels are
getShotAngles <- function(spread) {
return(runif(SHOTS, -spread / 2, spread / 2) * 180 / pi)
}
#now add a random positional error to the coordinates of the hit
getShotErrors <- function() {
return(rnorm(SHOTS, 0, ERROR))
}
#so which box was hit?
isCellHit <- function(angle, intervalBounds, ship) {
if (angle < intervalBounds[1]) return(1)
if (angle > tail(1, intervalBounds)) return(ship[6] + 2)
left <- 1
right <- length(intervalBounds)
while(TRUE) {
index <- floor((left + right) / 2)
if (angle <= bounds[index]) right <- index
else if (angle > bounds[index + 1]) left <- index
else return(index + 1)
}
}
#generates the shot distribution per shot
getDistribution <- function(spread) {
distribution <- vector(mode = "double", length = ship[6] + 2)
hitLocations <- isCellHit(getShotAngles(spread) + getShotErrors())
distribution[hitLocations] <- distribution[hitLocations] + 1
return(distribution / sum(distribution))
}
#generates a sum of matrices multiplied by the distribution
getHitMatrix <- function(spread){
hits <- matrix(0, 5, ship[6] + 4)
distribution <- getDistribution(spread)
for (i in 1:ship[6])
hits[,i:(i + 4)] <- (hits[,i:(i + 4)]
+ ARMOR_DAMAGE_DISTRIBUTION
* distribution[i + 1])
return(hits)
}
getHitChance <- function(spread){
chance <- 0
distribution <- getDistribution(spread)
chance <- 1 - distribution[1] + distribution[ship[6]]
return(chance)
}
#for weapons with damage changing over time we need a sequence of matrices
getHitMatrixSequence <- function(spreadvector){
hitmatrixsequence <- list()
for (i in 1:length(spreadvector))
hitmatrixsequence[] <- getHitMatrix(spreadvector)
return(hitmatrixsequence)
}
# we do not actually use this function in practice
getArmorDamage <- function(damage, armor, armorRating) {
factor <- damage / (damage + max(MINIMUM_ARMOR_PROTECTION * armorRating, armor))
return(damage * (max(0.15, factor)))
}
#this atrociously named function contains a logical switch,
#which probably degrades performance, but also ensures we
#never divide by 0
getArmorDamageSelectiveReduction <- function(damage, armor, armorRating) {
useMinimumArmor <- 0
if (armor < MINIMUM_ARMOR_PROTECTION * armorRating / ARMOR_FRACTION) useMinimumArmor <- 1
if (useMinimumArmor == 0) {
if(armor == 0) return (damage)
return(damage * (max(0.15, damage / (damage + armor))))
}
factor <- damage / (damage + armorRating * MINIMUM_CELL_PROTECTION)
return(damage * (max(0.15, )))
}
#how many unique weapon loadouts are there?
#get names of weapons from a choices list x
getWeaponNames <- function(x){
vector <- vector(mode="character")
for (i in 1:length(x)) vector <- cbind(vector, x[][[4]])
return(vector)
}
#convert the names back to numbers when we are done based on a weapon choices list y
convertWeaponNames <- function(x, y){
vector <- vector(mode="integer")
for (j in 1:length(x))
for (i in 1:length(y))
if(x[j] == y[][[4]]) vector <- cbind(vector, i)
return(vector)
}
#generates a table of all unique loadouts that we can create
#using the weapon choices available
permuteWeaponLoadouts <- function(weaponChoices) {
#enumerate weapon choices as integers
perms <- list()
for (i in 1:WEAPON_COUNT)
perms[i + length(perms)] <- seq(1, length(weaponChoices), 1)
#create a matrix of all combinations
perm1x2 <- expand.grid(perms[1],perms[2])
#sort, then only keep unique rows
perm1x2 <- unique(t(apply(perm1x2, 1, sort)))
perm3x4 <- expand.grid(perms[3],perms[4])
perm3x4 <- unique(t(apply(perm3x4, 1, sort)))
perm5x6 <- expand.grid(perms[5],perms[6])
perm5x6 <- unique(t(apply(perm5x6, 1, sort)))
perm7x8 <- expand.grid(perms[7],perms[8])
perm7x8 <- unique(t(apply(perm7x8, 1, sort)))
#now that we have all unique combinations of all two weapons,
#create a matrix containing all combinations of these
#unique combinations
allPerms <- matrix(0, 0, (length(perm1x2[1,])
+ length(perm3x4[1,])
+ length(perm5x6[1,])
+ length(perm7x8[1,])))
for(i in 1:length(perm1x2[,1]))
for(j in 1:length(perm3x4[,1]))
for(k in 1:length(perm5x6[,1]))
for(l in 1:length(perm7x8[,1]))
allPerms <- rbind(allPerms, c(perm1x2[i,], perm3x4[j,],
perm5x6[k,], perm7x8[l,])
)
#we save this so we don't have to compute it again
saveRDS(allPerms, file="allPerms.RData")
}
#now compute a main lookuptable to save on computing time
#the lookuptable should be a list of lists, so that
#lookuptable[[ship]][[weapon]][[1]] returns hit chance vector and
#lookuptable[[ship]][[weapon]][[2]] returns hit probability matrix
#time for some black R magic
#note: the lookuptable will be formulated such that there is a
#running index of weapons rather than sub-lists, so all weapons
#will be indexed consecutively so we have lookuptable
#[[1]][[1]] = [[ship1]][[weaponchoices1_choice1]], etc.
#So that is what the below section does.
fillLookupTableRow <- function(ship, index) {
#how much is the visual arc of the ship in rad?
shipAngle <- ship[5] / (2 * pi * range)
#how much is the visual arc of a single cell of armor in rad?
cellAngle <- shipAngle / ship[6]
#now assume the weapon is targeting the center of the ship's
#visual arc and that the ship is in the center of the weapon's
#firing arc, which cell will the shot hit, or will it miss?
#call the cells (MISS, cell1, cell2, ... ,celli, MISS) and
#get a vector giving the (maximum for negative / minimum for
#positive) angles for hitting each
angleRange <- vector(mode = "double", length = ship[6] + 1)
angleRange[1] <- -shipAngle / 2
for (i in 1:(length(angleRange)-1))
angleRange[i + 1] <- angleRange + cellAngle
#now convert it to pixels
angleRange <- angleRange * 2 * pi * range
weaponIndexMax <- 0
for (i in 1:WEAPON_COUNT)
weaponIndexMax <- weaponIndexMax + length(weaponChoices)
for (i in 1:weaponIndexMax)
for (j in 1:WEAPON_COUNT) {
a <- 0
b <- 0
for (k in 1:j) a <- a + length(weaponChoices[k])
if (j > 1) b <- a - length(weaponChoices[j - 1])
if (i > a & i <= b) next
weapon <- weaponChoices[j]
if (weapon[4] == "") next
hitChanceVector <- vector(mode = "double",
length = length(weapon[[5]]))
for (i in 1:length(weapon[[5]]))
hitChanceVector <- getHitChance(weapon[[5]])
table[[index]][] <<- list()
table[[index]][][[1]] <<- hitChanceVector
table[[index]][][[2]] <<- getHitMatrixSequence(weapon[[5]])
}
}
generateLookupTable <- function() {
table <- list()
for (i in 1:length(ships)) {
ship <- ships[]
ship <- as.double(ship[1:6])
table[] <- getLookupTableEntry(ship)
}
# save this so we don't have to re-compute it
saveRDS(table, file="lookuptable.RData")
}
lookup <- function(ship, weapon, var, table) {
return(table[[ship]][[weapon]][[var]])
}
#calculate shield damage
#time %% length ... etc. section returns how many shots that
#weapon will fire at that point of it's cycle
#(ie. vector index = time modulo vector index maximum)
shieldgetDamageAtTime <- function(weapon, time) {
nohits <- weapon[[3]][(time %% (length(weapon[[3]]))) + 1]
if (nohits == 0) return(0)
else return(weapon[[1]] * nohits)
}
getDamageAtTime <- function(weapon, time, armor, armorRating, x, y, shots) {
#vectors in R are indexed starting from 1
#hits[x,y] returns the damage allocation to that cell
hits <- weapon[[7]][[min(shots, length(weapon[[7]]))]]
nohits <- weapon[[3]][(time %% (length(weapon[[3]])))+1]
if (nohits == 0) return(0)
damagesum <- 0
for (i in 1:nohits) {
damagesum <- damagesum + getArmorDamageSelectiveReduction(
as.double(weapon[[1]] * hits[hitx,hity]), armor,
armorRating)
shots <- shots + 1
hits <- weapon[[7]][[min(shots, length(weapon[[7]]))]]
}
return(damagesum)
}
applyDamage <- function(weapon, factor, shots, shield, armorGrid, hull) {
factor <- unlist(weapon[2])
if (shield > getDamageAtTime(weapon, time) * factor){
shield <- (shield
- getDamageAtTime(weapon, time)
* factor
* weapon[[6]][min(shots, length(weapon[[6]]))])
shield <- max(shield, 0)
if(getDamageAtTime(weapon, time) > 0)
shieldBlock <- 1
} else {
#if you did not use shield to block, regenerate flux <- applied later
#2. armor and hull
if (unlist(weapon[2]) == 0.25) { factor = 0.25 }
else { factor = 1 / unlist(weapon[2]) }
#2.1. damage armor and hull
hulldamage <- 0
for (j in 1:length(armorGrid[1,])) {
for (i in 1:length(armorGrid[,1])) {
#this monster of a line does the following:
#hull damage is maximum of: 0, or (weapon damage to armor
#cell, with multiplier - armor cell hp)/weapon multiplier
shotDamage <- factor * getDamageAtTime(weapon, time,
armorGrid[i, j], armorRating, i, j, shots)
hulldamage <- hulldamage + max(0, shotDamage - armorGrid[i, j])
#new armor hp at cell [i,j] is maximum of: 0, or (armor cell
#health - weapon damage to that section of armor at that
#time, multiplied by overall hit probability to hit ship
#--- note: the damage distribution matrix is calculated such
#that it is NOT inclusive of hit chance, but hit chance is
#added separately here
armorDamage <- shotDamage * weapon[[6]][min(shots,
length(weapon[[6]]))]
armorGrid[i, j] <<- max(0, armorGrid[i, j] - armorDamage)
}
}
#reduce hull by hull damage times probability to hit ship
hull <<- hull - hulldamage * weapon[[6]][min(shots,length(weapon[[6]]))]
hull <<- max(hull, 0)
}
}
getShotCountIncrease <- function(weapon) {
weapon[[3]][(time %% (length(weapon[[3]]) + 1))]
}
getTimeSeries <- function(time,
shield,
armorHP,
hull,
shieldRegen,
shieldMax,
armorRating,
armorGrid)
{
weaponspread <- 0
shieldBlock <- 0 #are we using shield to block?
hulldamage <- 0
if (hull > 0) {} else { shield <- 0 }
for (i in 1:WEAPON_COUNT) {
applyDamage(weapons, shotCounts, damageFactors,
shield, armorGrid, hull)
shotCounts <- shotCounts + getShotCountIncrease(weapons)
}
if (hull == 0) armorHP <- 0
armorHP <- sum(armorGrid) * ARMOR_FRACTION / ((ship[[6]] + 4) * 5)
if (hull == 0) armorHP <- 0
if (shieldBlock == 0) shield <- min(shieldMax, shield + shieldRegen)
return(list(time, shield, armorHP, hull, shieldRegen,
shieldMax, armorRating, armorGrid))
}
testLoadouts <- function(ship) {
#format ship data types appropriately
timeSeries <- data.frame(matrix(ncol = 7, nrow = 0))
timeToKill = 0
shieldBlock <- 0
totalTime = 500
hull <- ship$hull
shieldMax <- ship$shieldEfficiency * ship$maxFlux
shield <- shieldMax
shieldRegen <- ship$shieldEfficiency
* (ship$shieldUpkeep - ship$fluxDissipation)
armorHP <- ship$armorRating
armorRating <- ship$armorRating
armorGrid <- ship$getArmorGrid()
shotCounts <- list(0, 0, 0, 0, 0, 0, 0, 0)
#go through all the permutations using he running index,
#which is i+j+k+l+m+n+o+p for weapons 8
for (z in 1:length(allperms[,1])) {
weapons <- list()
for (i in 1:WEAPON_COUNT)
weapons[i + length(weapons)] <- weaponChoices[[allperms[z,i]]]
for (i in 1:WEAPON_COUNT) {
if (weapons[4] == "") next
index <- 0
for (j in 1:WEAPON_COUNT) index <- index + allperms[z,j]
weapons[6] <- lookup(f, index, 1)
weapons[7] <- lookup(f, index, 2)
}
#time series - run time series at point t, save it to state,
#update values spreadording to state, re-run time series,
#break if ship dies
for (time in 1:totalTime){
state <- getTimeSeries(time, shield, armorHP, hull, shieldRegen,
shieldMax, armorRating, armorGrid)
shieldHP <- state[[2]]
armorHP <- state[[3]]
hull <- state[[4]]
flux <- shieldMax - shield
armor <- state[[8]]
if(hull == 0) {
flux <- 0
if (timeToKill == 0){
timeToKill <- time
break
}
}
}
if (timeToKill ==0) timeToKill <- NA
tobind <- c(timeToKill, unlist(weapons[1][4]), unlist(weapons[2][4]),
unlist(weapons[3][4]), unlist(weapons[4][4]),
unlist(weapons[5][4]), unlist(weapons[6][4]),
unlist(weapons[7][4]), unlist(weapons[8][4]))
timeSeries <- rbind(timeSeries,tobind)
hull <- ship$hull
armorHP <- ship$armorRating
armorGrid <- ship$getArmorGrid
shield <- shieldMax
shotCounts <- list(0, 0, 0, 0, 0, 0, 0, 0)
timeToKill <- 0
}
colnames(timeSeries) <- c("Timetokill", "Weapon1", "Weapon2",
"Weapon3", "Weapon4", "Weapon5", "Weapon6", "Weapon7", "Weapon8")
sortbytime <- timeSeries[order(as.integer(timeSeries$Timetokill)),]
write.table(sortbytime, file = paste("optimizeweaponsbytime", ship$id,
"allweaponswithspread.txt", sep = ""),
row.names = FALSE, sep = "\t")
}
main <- function() {
config <- read.csv("config")
weaponData <- read.csv("weapon_data.csv")
shipData <- read.csv("ship_data.csv")
ships <- list(glimmer, brawlerlp, vanguard, tempest, medusa, hammerhead,
enforcer, dominator, fulgent, brilliant, radiant, onslaught,
aurora, paragon, conquest, champion)
#which weapons are we studying?
mediumGuns <- list(arbalest, hac, hvd, heavymauler, needler, mortar)
largeGuns <- list(gauss, markix, mjolnir, hellbore, hephaestus, stormneedler)
mediumMissiles <- list(harpoon, sabot)
largeMissiles <- list(squall, locust, hurricane)
weaponChoices <- list(
mediumGuns,
mediumGuns,
largeGuns,
largeGuns,
mediumMissiles,
mediumMissiles,
largeMissiles,
largeMissiles
)
if (PERMUTE_WEAPON_LOADOUTS == 1) permuteWeaponLoadouts(weaponChoices)
else allPerms <- readRDS("lookuptable.RData")
if (GENERATE_LOOKUP_TABLE == 1) generateLookupTable()
else table <- readRDS("lookuptable.RData")
#go through all ships
for (f in 1:length(ships)) testLoadouts(ships[f])
}
main()
#use computationally inexpensive functions to manage
shipnames <- c("glimmer","brawlerlp","vanguard","tempest","medusa",
"hammerhead","enforcer","dominator","fulgent","brilliant",
"radiant","onslaught","aurora","paragon","conquest",
"champion")
#get a filename
filename <- function(x) {
paste("optimizeweaponsbytime",
shipnames
"allweaponswithacc.txt",
sep = "")
}
#read a file
readfile <- function(filename) {
read.csv(filename, sep = "\t")
}
#methods to get data tables
getFormattedTTKTable <- function(table) {
table <- cbind(table, (1 / (table$Time / mean(table$Time)) - 1))
table[,3] <- sprintf("%0.1f%%", table[,3] * 100)
table <- table[order(table$Time),]
table[,2] <- round(table[,2], digits=1)
return(table)
}
getTTKTable <- function(dataFrame, time, label) {
table <- aggregate(time, data = dataFrame, FUN = mean, na.rm = TRUE)
table <- getFormattedTTKTable(table)
colnames(table) <- c(label, "Avg. time to kill", "TTK speed score")
return(table)
}
getGunAndLargeMissileTable <- function(dataFrameSorted) {
table <- aggregate(Time ~ Largemissiles + Largeguns + Mediumguns,
data = dataFrameSorted,
FUN = mean,
na.rm = TRUE)
table <- getFormattedTTKTable(table)
colnames(table) <- c("Large missiles",
"Large guns",
"Medium guns",
"Avg. time to kill",
"TTK speed score")
return(table)
}
#method to write data tables to the screen
writeTable <- function(table, filename) {
write.table(table, file = filename, row.names = FALSE, sep = "/t")
}
getDataFrame <- function(data) {
dataFrame <- data.frame()
for (i in 1:length(shipnames)) {
shipnamecolumn <- matrix(data = shipnames
, ncol = 1, nrow = 7938)
mainDataFrame <- rbind(dataFrame,
cbind(shipnamecolumn, readfile(filename(i))))
}
colnames(dataFrame) <- c("Ship",
"Time",
"Largemissile1",
"Largemissile2",
"Mediummissile1",
"Mediummissile2",
"Largegun1",
"Largegun2",
"Mediumgun1",
"Mediumgun2")
return(dataFrame)
}
getDataFrameSorted <- function(data, dataFrame) {
dataFrameSorted <- data.frame()
#order large missiles, medium missiles, and large guns
#alphabetically by row and merge cells
for (i in 1:length(dataFrame[,1])){
largeMissiles <- paste(t(apply(dataFrame[i,3:4], 1, sort))[2],
t(apply(dataFrame[i,3:4], 1, sort))[1],
sep = " ")
mediummissiles <- paste(t(apply(maindataframe[i,5:6], 1, sort))[2],
t(apply(maindataframe[i,5:6], 1, sort))[1],
sep = " ")
largeGuns <- paste(t(apply(dataFrame[i,7:8], 1, sort))[1],
t(apply(dataFrame[i,7:8], 1, sort))[2], sep = " ")
mediumGuns <- paste(t(apply(dataFrame[i,9:10], 1, sort))[1],
t(apply(dataFrame[i,9:10], 1, sort))[2], sep = " ")
toBind <- c(dataFrame[i,1], dataFrame[i,2], largeMissiles, largeGuns,
mediumMissiles, mediumGuns)
dataFrameSorted <- rbind(dataFrameSorted, toBind)
}
colnames(dataFrameSorted) <- c("Ship",
"Time",
"Largemissiles",
"Largeguns",
"Mediumguns")
dataFrameSorted$Time <- as.double(dataFrameSorted$Time)
return(dataFrameSorted)
}
#analysis with large missiles set at squallx
#(squall,locust,hurricane), large guns, and medium guns
analyze <- function(data) {
#range with itu + bm + gi
#(+85 total for ballistic & energy, +0 for missiles)
gunsRangeMult <- 1.85
mediumGuns <- read.csv("medium_guns.csv")
largeGuns <- read.csv("large_guns.csv")
mediumMissiles <- read.csv("medium_missiles.csv")
largeMissiles <- read.csv("large_missiles.csv")
dataFrame <- getDataFrame(data)
dataFrameSorted <- getDataFrameSorted(data, dataFrame)
#assemble tables
shipTable <- getTKKTable(dataFrameSorted, Time ~ Ship, "Ship")
mediumGunTable <- getTTKTable(dataFrame, Time ~ mediumGuns, "Medium Gun")
largeGunTable <- getTTKTable(dataFrame, Time ~ largeGuns, "Large Gun")
mediumMissileTable <- getTTKTable(dataFrame, Time ~ mediumMissile,
"Medium Missile")
largeMissileTable <- getTTKTable(dataFrame, Time ~ largeMissile,
"Large Missile")
gunAndLargeMissilesTable <- getGunAndLargeMissileTable(dataFrameSorted)
return(list(shipTable, "shipTable.txt",
mediumGunTable, "mediumGunTable3.txt",
largeGunTable, "largeGunTable3.txt",
mediumMissileTable, "mediumMissileTable3.txt",
largeMissileTable, "largeMissileTable3.txt",
gunAndLargeMissilesTable, "gunAndLargeMissileTable.txt"))
}
main <- function() {
tablesAndNames <- analyze(data)
for (i in seq(1,tablesAndNames.length,2))
writeTable(tablesAndNames, tablesAndNames[i+1])
}
main()
#Weapon
#id,min spread,max spread,spread per shot
"squall",0,0,0
"locust",0,0,0
"hurricane",0,0,0
"harpoon",0,0,0
"sabot",0,0,0
"gauss",0,0,0
"hephaestus",0,10,2
"markix",0,15,2
"mjolnir",0,5,1
"hellbore",10,10,0
"stormneedler",10,10,0
"arbalest",0,5,10
"heavymaul",0,5,1
"hac",0,18,3
"hvd",0,0,0
"needler",1,10,0.5
"mortar",0,20,5
#tics - generate this from ammo, burst size, burst delay, and refire delay
"squall",2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0
"locust",10,10,10,10,0,0,0,0,0
"hurricane",9,0,0,0,0,0,0,0,0,0,0,0,0,0,0
"harpoon",4,0,0,0,0,0,0,0,0
"sabot",10,0,0,0,0,0,0,0,0
"gauss",1,0
"hephaestus",4
"markix",4,0,0,4,0,0,4,0,0,4,0,0,0,4,0,0,0
"mjolnir",1,1,2,1,2,1,2,1,1
"hellbore",1,0,0,0
"stormneedler",10
"arbalest",1,1,1,0,1,1
"heavymauler",3,0,0,0,0,0,3,0,0,0,0,3,0,0,0,0,3,0,0,0,0,3,0,0,0,0,0
"hac",3,0,3,3,0,3,3,0
"hvd",1,0,0
"needler",20,10,0,0,0,0
"mortar",2,2,0,2,2,2,2,0,2,2,2,0,2
#damage per shot,damage type (2=kinetic,0.5=he,0.25=frag,1=energy)
"arbalest",200,2,
"heavymauler",200,0.5,
"hac",100,2,
"hvd",275,2,
"needler",50,2,
"mortar",110,0.5,
"squall",250,2,
"locust",200,0.25,
"hurricane",500,0.5,
"harpoon",750,0.5,
"sabot",200,2,
"gauss",700,2,
"hephaestus",120,0.5,
"markix",200,2,
"mjolnir",400,1,
"hellbore",750,0.5,
"stormneedler",50,2
#ships -
#ship, hullhp, shieldRegen, shieldMax, startingArmor, widthinpixels, armorcells, name
glimmer <- c(1500,250/0.6,2500/0.6,200,78,5,"glimmer")
brawlerlp <- c(2000,500/0.8,3000/0.8,450,110,floor(110/15),"brawlerlp")
vanguard <- c(3000,150,2000,600,104,floor(104/15),"vanguard")
tempest <- c(1250,225/0.6,2500/0.6,200,64,floor(64/15),"tempest")
medusa <- c(3000,400/0.6,6000/0.6,300,134,floor(134/15),"medusa")
hammerhead <- c(5000,250/0.8,4200/0.8,500,108,floor(108/16.4),"hammerhead")
enforcer <- c(4000,200,4000,900,136,floor(136/15), "enforcer")
dominator <- c(14000,500,10000,1500,220,12,"dominator")
fulgent <- c(5000,300/0.6,5000/0.6,450,160,floor(160/15), "fulgent")
brilliant <- c(8000,600/0.6,10000/0.6,900,160,floor(160/20),"brilliant")
radiant <- c(20000,1500/0.6,25000/0.6,1500,316,floor(316/30),"radiant")
onslaught <- c(20000,600,17000,1750,288,floor(288/30),"onslaught")
aurora <- c(8000,800/0.8,11000/0.8,800,128,floor(128/28), "aurora")
paragon <- c(18000,1250/0.6,25000/0.6,1500,330,floor(330/30),"paragon")
conquest <- c(12000,1200/1.4,20000/1.4,1200,190,floor(190/30),"conquest")
champion <- c(10000,550/0.8,10000/0.8,1250,180,floor(180/24),"champion")