Been playing Anime Fighers Simulator a lot lately and wanted to make a calculator to work out the cost for overnight afk opening.
The Game “Anime Fighters Simulator” is a roblox game similar to a clicker game like cookie clicker but based on Anime and has some extra playability as it is not purely based on clicking. I have played this game for over 6000 hours so far and the competative streak in me has me playing way more than I should. One of the thing that I saw people asking regularily in streams was how much would it cost to AFK open in world x. This sounded like a fun thing to work on so I started making it as a web page using jquery and css bootstrap.
The first thing I did was create all the inputs needed to work out how many stars(fighters) you can open. This consists of the amount of stars you can open at once, the game passes you own and the game badges you have for a world. Since different players can open different amount this needs to be editable.
Next I needed to be able to set how much it costs to open so I added the inputs for costs. As with most clicker type games the number go up exponentially and are denoted by characters such as B for billion and Q for quadrillion. To handle this I created an array with all the denoted characters
modLetters = " KMBTQEZYXWVU" // modifiers for currency
With the inputs set for teh stars and the costs i needed a way for users to set the world they want to open. I then created the following table with each world and their costs for stars:
World | Name | Star Cost | Token Cost |
---|---|---|---|
Super Island | 80 | 21 | |
Ninja Village | 300 | 53 | |
Crazy Town | 2.5k | 227 | |
Fruits Island | 10k | 593 | |
Hero University | 50k | 1.8k | |
Walled City | 250k | 5.51k | |
Slayer Army | 800k | 12.3k | |
Ghoul Town | 3m | 30.8k | |
Chimera Jungle | 10m | 71.1k | |
Virtual Castle | 40m | 185k | |
Empty Dimension | 150m | 464k | |
Cursed High | 500m | 1.07m | |
XYZ Metropolis | 1.5b | 2.29m | |
9 Crimes island | 5b | 5.28m | |
Destiny Island | 20b | 13.8m | |
Lucky Kingdom | 80b | 36m | |
Land Of Alchemy | 250b | 79.5m | |
Slimey Island | 780b | 174m | |
Flame City | 2t | 336m | |
Divine Colosseum | 7t | 800m | |
Kingdom Of Four | 20t | 1.65b | |
Icy Wastes | 65t | 3.75b | |
The Underworld | 200t | 8.17b | |
Psychic City | 650t | 18.5b | |
The Hole | 2q | 40.3b | |
Ninja City | 6q | 86.4b | |
Time Travel Tokyo | 20q | 199b | |
Orca Road Prison | 66q | 455b | |
World Of Games | 220q | 1.04t | |
30 | TBC | 0 | 0 |
The max open tokens are added here as well as the max open will be used in our results too.
With all this set I created some code to work out the costs for the values enterd in the input fields:
defaultOpenPerHour = 1200 // how many opens an be done in an hour defaultMaxOpensPerHour = 40 // how many max opens can be done in a hour defaultSellRate = 0.25 // value returned for sell (avg) timeEventMod = 1 // stores modifier for time event modLetters = " KMBTQEZYXWVU" // modifiers for currency // useful functions function getCostOfSingleOpen(cps, opens) { return cps * opens; } function getCostOfSingleMaxOpen(cps, invSpace) { return cps * invSpace * 0.5; } function getCostOfHourOpens(cps, opens, gpass, fiftyk, fuseSell, vip) { if (vip == 2) { cps = cps * 0.75 // 25% discount for VIP } fc = cps * opens * defaultOpenPerHour * gpass * fiftyk if (fuseSell == 2) { fc = fc * (1 - defaultSellRate) } return fc } function getCostOfHourMaxOpen(cps, invSpace, fuseSell, vip) { if (vip == 2) { cps = cps * 0.75 // 25% discount for VIP } fc = cps * (defaultMaxOpensPerHour * timeEventMod) * invSpace sellprice = 0 if (fuseSell == 2) { sellprice = fc * defaultSellRate } return (fc * 0.5) - sellprice } function convertToFormatted(value, mod) { cmodpos = modLetters.indexOf(mod.toUpperCase()) while (Math.ceil(Math.log10(value + 1)) > 3) { cmodpos += 1 // move to next modifier value = value * 0.001// divide val by 1000 to mve 3 places down } return parseFloat(value.toFixed(2)) + modLetters[cmodpos] //return value.toPrecision(3) + modLetters[cmodpos]; } function populateCost(stringVal, maxStringVal) { cost = costModConvert(stringVal) maxcost = costModConvert(maxStringVal) $("#inpcost").val(cost[0]) $("#inpmod").val(cost[1]) $("#inpMaxcost").val(maxcost[0]) $("#maxmod").val(maxcost[1]) } function costModConvert(stringVal) { lastChar = stringVal.slice(stringVal.length - 1) if ($.isNumeric(lastChar)) { return [stringVal, ""] } else { return [stringVal.slice(0, stringVal.length - 1), lastChar] } } function getOneHourMaxToken(cpmo) { return cpmo * 40 } // respond to Clicks $("#getres").click(function (e) { cost = $("#inpcost").val() mod = $("#inpmod").val() mcost = $("#inpMaxcost").val() mmod = $("#maxmod").val() openCount = $("#opensCount").val() invSpace = $("#invSpace").val() fuseSell = $("#inputGroupSelect01").val() // 1 = fuse | 2 = Sell gPass = $("#inputGroupSelect02").val() // 1 = None | 2 = Owned fiftyk = $("#inputGroupSelect03").val() // 1 = None | 2 = Owned doMax = $("#inputGroupSelect04").val() // 1 = Yes | 2 = No vip = $("#inputGroupSelect05").val() // 1 = No | 2 = Yes res = getCostOfHourOpens(cost, openCount, gPass, fiftyk, fuseSell, vip) mres = 0 if (doMax == 1) { res += getCostOfHourMaxOpen(cost, invSpace, fuseSell) mres = getOneHourMaxToken(mcost) } hour1 = convertToFormatted(res, mod) hour2 = convertToFormatted(res * 2, mod) hour3 = convertToFormatted(res * 3, mod) hour4 = convertToFormatted(res * 4, mod) hour5 = convertToFormatted(res * 5, mod) hour6 = convertToFormatted(res * 6, mod) hour7 = convertToFormatted(res * 7, mod) hour8 = convertToFormatted(res * 8, mod) hour24 = convertToFormatted(res * 24, mod) hourM1 = convertToFormatted(mres, mmod) hourM2 = convertToFormatted(mres * 2, mmod) hourM3 = convertToFormatted(mres * 3, mmod) hourM4 = convertToFormatted(mres * 4, mmod) hourM5 = convertToFormatted(mres * 5, mmod) hourM6 = convertToFormatted(mres * 6, mmod) hourM7 = convertToFormatted(mres * 7, mmod) hourM8 = convertToFormatted(mres * 8, mmod) hourM24 = convertToFormatted(mres * 24, mod) $("#resdisplay").html(hour1 + " for 1 hour (" + hourM1 + " tokens)") $("#res2display").html(hour2 + " for 2 hours (" + hourM2 + " tokens)") $("#res3display").html(hour3 + " for 3 hours (" + hourM3 + " tokens)") $("#res4display").html(hour4 + " for 4 hours (" + hourM4 + " tokens)") $("#resd5isplay").html(hour5 + " for 5 hours (" + hourM5 + " tokens)") $("#res6display").html(hour6 + " for 6 hours (" + hourM6 + " tokens)") $("#res7display").html(hour7 + " for 7 hours (" + hourM7 + " tokens)") $("#res8display").html(hour8 + " for 8 hours (" + hourM8 + " tokens)") $("#res24display").html(hour24 + " for 24 hours (" + hourM24 + " tokens)") }); $(".trworld").click(function () { ffs = $(this) costtd = ffs.find("td.costtd").html() costMaxtd = ffs.find("td.costMaxtd").html() worldName = ffs.find("td.worldName").html() $("#info").html(worldName) populateCost(costtd, costMaxtd) }); $(".badgeBut").click(function () { switch ($(this).attr("info")) { case "test1": if ($("#inputGroupSelect05").val() == "1") { $("#inputGroupSelect05").val("2") } else { $("#inputGroupSelect05").val("1") } break; case "test2": if ($("#inputGroupSelect02").val() == "1") { $("#inputGroupSelect02").val("2") } else { $("#inputGroupSelect02").val("1") } break; case "test3": break; case "test4": break; case "test5": break; case "test6": break; case "test7": turnOffAllTimeEventHighlights($(this)) if (timeEventMod == 2) { timeEventMod = 1 $(this).find(".clh").toggle() } else { timeEventMod = 2 } break; case "test8": turnOffAllTimeEventHighlights($(this)) if (timeEventMod == 3) { timeEventMod = 1 $(this).find(".clh").toggle() } else { timeEventMod = 3 } break; case "test9": turnOffAllTimeEventHighlights($(this)) if (timeEventMod == 4) { timeEventMod = 1 $(this).find(".clh").toggle() } else { timeEventMod = 4 } break; case "test10": turnOffAllTimeEventHighlights($(this)) if (timeEventMod == 5) { timeEventMod = 1 $(this).find(".clh").toggle() } else { timeEventMod = 5 } break; } $(this).find(".clh").toggle() }); function turnOffAllTimeEventHighlights(object) { badgebar = object.closest(".badgebar") badgebar.find(".timeMod").toggle(false) }
This code is available on github here incase you want to make this yourself on your server. Credit is appreciated but not required
The post Making an AFK Calculator for Anime Fighters Simulator – Roblox Game appeared first on Game Development.