Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <limits.h>
- /*
- quick facts:
- compatibility: 0-255. saved over the life of your yojimbo
- starts at 128(P) 50(U)
- change:
- Y uses Z (Zanmato) +4
- Y uses WA / !W (Wakizashi vs all) +3
- Y uses WO / W (Wakizashi vs one) +1
- Y uses K (Kozuka) +0
- Y uses D (Diagoro) -1
- Y is dismissed on first turn -3
- Y is KOed -10
- Y gets paid 0g -20
- dismiss on any other turn is ok, no change
- so always dismiss rather than let him die
- never pay 0g under any circumstance
- gil: 0-999M
- money you pay him. program only allows 1+ because 0 is autodismiss
- only pay in powers of 2; extra gold before next power of 2 is useless
- giltotal: 0-999M
- total money you had before pay. with option 1, you get increase
- relative to option 2 for >=50% of g paid, and decrease for <=50%.
- option: 1-3
- what you said when you hired yojimbo for the first time
- 1 "To train as a summoner."
- 2 "To gain the power to destroy fiends."
- 3 "To defeat the most powerful enemies."
- Compared to 2, 1 is better when you spend over half your gold on
- a single payment, and worse otherwise. Never choose 1.
- Compared to 2, 3 is slightly worse for generating one hit kos against lvl 1 mobs
- and much better for one hit kos against lv 2-6 mobs. 2 is always slightly better
- at generating good non-OHKO attacks (ie WA/WO) against any mob
- If playing NA, and only interested in non-boss mobs or no OHKOS, option 2 is best,
- otherwise option 3. Considering the massive difficulty of generating OHKOS, and
- the "cheapness" of them, maybe the small regular bonus on option 2 is best.
- If playing EU, always choose option 3; you won't need the slighty bonus on non
- bosses.
- zlvl: 1-6
- Target's zanmoto level
- 1: almost all regular mobs
- 2: a handful (<12) of special mobs
- 3: anima and adamantoise
- 4: almost all normal bosses
- 5: all monster arena creations, and all final boss fight
- 6: dark aeons (&penance???) (EU only extras)
- od: 0-1
- if Y's overdrive bar is active, he gets a bonus to motivation. Using him seriously
- in NA you will need to keep overdrive full all the time. Perhaps the same in EU,
- but it's so easy there that you may be able to do without.
- pal: 0-1
- if 1, EU version. if 0, NA version. NA version is buttfuckingly difficult; against
- regular mobs with max OD, compat, best option (2) you must pay 4096 gold to eliminate
- the possibility of dog attack. EU version is retardedly easy; against any boss, with
- option 3, od filled, but out of the box compat, paying 1 gold gives zero dog attacks
- and 1/4 of paid attacks Z-killer. Good bye penance?
- Attack stats:
- Diagoro: Pow 10 Pierce Can Crit
- Kozuka: Pow 13 Pierce Can Crit
- Wakizashi: Pow 18 Pierce Can Crit
- Wakizashi+:Pow 18 Pierce Can Crit All
- Zanmato: OHKO (no overkill) All
- */
- typedef struct
- {
- int compat; // compatibility: 0-255
- int gil; // gil paid: 1-999M
- int giltotal; // total gil before payment: 1-999M
- int option; // cave selection: 1-3
- int zlvl; // target's Zlvl: 1-6
- int od; // overdrive: 0-1
- int pal; // international: 0-1
- } input_t;
- typedef struct
- {
- int freeattack; // chance of free attack: parts in 4096
- // assuming free attack occurs:
- int freeZ; // chance of free Z: parts in 4096
- int freeWA;
- int freeWO;
- int freeK;
- int freeD;
- // assuming free attack doesn't occur
- int Z; // still parts in 4096
- int WA;
- int WO;
- int K;
- int D;
- } output_t;
- // checks for invalid numbers in input
- #define RANGEJA(a,b,c)\
- if ((a) < (b)) \
- (a) = (b); \
- if ((a) > (c)) \
- (a) = (c)
- void sanatize_input (input_t *in)
- {
- RANGEJA (in->compat, 0, 255);
- RANGEJA (in->gil, 1, 999999999);
- RANGEJA (in->giltotal, in->gil, 999999999);
- RANGEJA (in->option, 1, 3);
- RANGEJA (in->zlvl, 1, 6);
- RANGEJA (in->od, 0, 1);
- RANGEJA (in->pal, 0, 1);
- }
- #undef RANGEJA
- #ifndef MAX
- #define MAX(a,b) ((a)>(b)?(a):(b))
- #endif
- #ifndef MIN
- #define MIN(a,b) ((a)<(b)?(a):(b))
- #endif
- // return number of intersections of [a,b] with [c,d]
- int intersect (a, b, c, d)
- {
- int i = MAX (a, c);
- int j = MIN (b, d);
- return MAX (j - i + 1, 0);
- }
- // make a calculation
- void do_yojimbo (const input_t *in, output_t *out)
- {
- int i, j, k, m, m2;
- // constants of north america vs pal
- int GIL_MULT = in->pal ? 4 : 2;
- int COMPAT_DIV = in->pal ? 4 : 30;
- int OD_BONUS = in->pal ? 20 : 2;
- // do that shit
- if (1)
- {
- // free attack: c/1024, parts of 4096
- out->freeattack = in->compat * 4;
- // free attack: [c/4] + 0..63
- i = in->compat / 4;
- j = i + 63;
- out->freeD = intersect (i, j, 0, 31) * 64;
- out->freeK = intersect (i, j, 32, 47) * 64;
- out->freeWO = intersect (i, j, 48, 63) * 64;
- out->freeWA = intersect (i, j, 64, 79) * 64;
- //freeZ: only happens with lvl 1 mobs
- k = intersect (i, j, 80, 999) * 64;
- if (in->zlvl == 1)
- {
- out->freeZ = k;
- }
- else
- {
- out->freeZ = 0;
- out->freeWA += k;
- }
- // step 1: payment
- k = in->gil;
- m = -2;
- while (k)
- {
- k /= 2;
- m += 1;
- }
- // special case: 1 gil gives m = 0
- if (m < 0)
- m = 0;
- m *= GIL_MULT;
- // step 2: motivation
- m += in->compat / COMPAT_DIV;
- // step 3: "poor person" option 1
- if (in->option == 1)
- m *= 0.75 + (in->gil * 0.5 / in->giltotal);
- // step 4: z lvl
- // also calculate step 2 zlvl
- if (in->option == 3)
- {
- m2 = m * 4 / 5;
- if (in->zlvl <= 3)
- m = m * 4 / 5;
- else
- m = m * 2 / 5;
- }
- else
- {
- m2 = m;
- m /= in->zlvl;
- }
- // step 5: overdrive
- if (in->od)
- {
- m += OD_BONUS;
- m2 += OD_BONUS;
- }
- // step 6: add random number and choose attack
- // chance of Z:
- k = intersect (m, m + 63, 80, 999);
- out->Z = k * 64;
- // other options are only if Z fails
- k = 64 - k;
- i = m2;
- j = m2 + 63;
- out->D = intersect (i, j, 0, 31) * k;
- out->K = intersect (i, j, 32, 47) * k;
- out->WO = intersect (i, j, 48, 63) * k;
- out->WA = intersect (i, j, 64, 999) * k;
- }
- }
- int main (int argc, char **argv)
- {
- printf ("use: compat ___gil___ _giltotal option zlvl od pal\n");
- if (argc != 8)
- {
- printf ("oops?\n");
- return 0;
- }
- input_t i;
- output_t o;
- i.compat = atoi (argv[1]);
- i.gil = atoi (argv[2]);
- i.giltotal = atoi (argv[3]);
- i.option = atoi (argv[4]);
- i.zlvl = atoi (argv[5]);
- i.od = atoi (argv[6]);
- i.pal = atoi (argv[7]);
- sanatize_input (&i);
- printf (" %6i %9i %9i %6i %4i %2i %3i\n", i.compat, i.gil, i.giltotal, i.option,
- i.zlvl, i.od, i.pal);
- do_yojimbo (&i, &o);
- printf ("Free attack: %5.2f%%\n", o.freeattack / 40.96);
- printf (" Z: %5.2f%%\n", o.freeZ / 40.96);
- printf (" !W: %5.2f%%\n", o.freeWA / 40.96);
- printf (" W: %5.2f%%\n", o.freeWO / 40.96);
- printf (" K: %5.2f%%\n", o.freeK / 40.96);
- printf (" D: %5.2f%%\n", o.freeD / 40.96);
- printf ("Paid attack: %5.2f%%\n", 100.0 - o.freeattack / 40.96);
- printf (" Z: %5.2f%%\n", o.Z / 40.96);
- printf (" !W: %5.2f%%\n", o.WA / 40.96);
- printf (" W: %5.2f%%\n", o.WO / 40.96);
- printf (" K: %5.2f%%\n", o.K / 40.96);
- printf (" D: %5.2f%%\n", o.D / 40.96);
- printf ("Combined attack chance:\n");
- double d1, d2;
- double f1 = o.freeattack / 4096.0;
- double f2 = 1.0 - f1;
- d2 = 0.0;
- d1 = o.freeZ * f1 + o.Z * f2;
- d2 += d1 * 4.0;
- printf (" Z: %5.2f%%\n", d1 / 40.96);
- d1 = o.freeWA * f1 + o.WA * f2;
- d2 += d1 * 3.0;
- printf (" !W: %5.2f%%\n", d1 / 40.96);
- d1 = o.freeWO * f1 + o.WO * f2;
- d2 += d1 * 1.0;
- printf (" W: %5.2f%%\n", d1 / 40.96);
- d1 = o.freeK * f1 + o.K * f2;
- d2 += d1 * 0.0;
- printf (" K: %5.2f%%\n", d1 / 40.96);
- d1 = o.freeD * f1 + o.D * f2;
- d2 -= d1 * 1.0;
- printf (" D: %5.2f%%\n", d1 / 40.96);
- printf ("Average compat change: %4.1f", d2 / 4096.0);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement