Author Topic: [PSX/PC] Alternate Fantasy (v3.2 & v6.0)  (Read 262799 times)

Planes

  • *
  • Posts: 2
    • View Profile
Re: [PSX/PC] Alternate Fantasy (v3.2 & v6.0)
« Reply #475 on: 2024-01-19 17:30:57 »
Hello!

First of all I just made this account because I just found out about FF9 mods and I am immediately invested.

Therefore I started with Moguri and of course Alternate Fantasy (along with a few other smaller ones).

I reached Lindblum however, and I noticed a few problems... It all started when I noticed Cotton Robe still sold for 2000 even though the mod supposedly decreased the price.
Next I checked Zidane's new weapons, specifically The Butterfly Sword and... it still listed its original ability 'What's That'!!
Bear in mind that other of the mod's effects where easily noticeable up to this pointy, like spells causing ailments (Fire -> Heat, Blizzard -> Snow, etc).
I got curious to try out the 'What's That' in battle and as I suspected, it had been turned into the single hit physical attack as it was supposed to... While the menus and the explanation box described the original abilty.

It seems then that this could simply be a visual bug, however the cotton robe issue has me worried that other things are not working as intented.

Has anyone else encountered this? Is there a fix?

Some extra info: here is the memoria.ini mod list:
FolderNames= "FlattenGrowth", "DragonKnightRising", "AlternateFantasy", "PlayableCharacterPack/ZidaneArmor", "PlayableCharacterPack/GarnetHooded", "PlayableCharacterPack", "PSXButtons", "TweakedPortraits", "MoguriFiles", "MoguriSoundtrack", "MoguriVideo"
Priorities = "FlattenGrowth", "DragonKnightRising", "AlternateFantasy", "PlayableCharacterPack", "PSXButtons", "TweakedPortraits", "MoguriFiles", "MoguriSoundtrack", "MoguriVideo"

Tirlititi

  • *
  • Posts: 874
    • View Profile
Re: [PSX/PC] Alternate Fantasy (v3.2 & v6.0)
« Reply #476 on: 2024-01-19 23:56:43 »
Hi.
I'm pretty sure that's the mod Dragon Knight Rising messing with abilities (and surely the items as well, hence the Cotton Robe price). I don't think you can do much about that right now: either you'll have these differences or you need to disable it. Mod compatibility of two mods that both change the gameplay is difficult to maintain unfortunatly.

Planes

  • *
  • Posts: 2
    • View Profile
Re: [PSX/PC] Alternate Fantasy (v3.2 & v6.0)
« Reply #477 on: 2024-01-21 20:50:24 »
Thank you very much for your answer. It was naturally a compatibility problem..

I have now messed with some of the modded files to hopefully retain some of the features from Dragon Knight Rising, while making sure Alternate fantasy is not further affected. Definitely not a proper compatibility patch, otherwise I would share, just some patchwork to suit my needs. Hopefully it will work. as I forsee.

ste459

  • *
  • Posts: 14
    • View Profile
Re: [PSX/PC] Alternate Fantasy (v3.2 & v6.0)
« Reply #478 on: 2024-01-28 08:41:44 »
Hey Tirlititi,
sorry if I ask your help again.
I'm exploring the possibilities offered by Memoria engine and trying to mod Alternate Fantasy to allow summons + normal attacks with ultimate weapons to break the damage limit, using support abilities as described here: https://github.com/Albeoris/Memoria/wiki/Supporting-ability-features

However, in order to keep some balance I would like to reduce the damage exceeding 9999, actually I used this formula to halve damage between 10.000-15.000 and reduce to 1/4 the damage above 15.000:
Code: [Select]
if ((_v.Target.HpDamage > 9999) && (_v.Target.HpDamage < 15001))
_v.Target.HpDamage = 9999 + (_v.Target.HpDamage - 9999) / 2;
if (_v.Target.HpDamage > 15000)
_v.Target.HpDamage = 12500 + (_v.Target.HpDamage - 15000) / 4;

I made this work by rewriting a part of Memoria SBattlecalculator.cs in Alternate Fantasy Commonscript.cs to bypass the normal CalcPhysicalHpDamage() function. The result is not very linear (I actually haven't a 100% awareness of what I copy-pasted) but actually seems to work as intended without major bugs:

Code: [Select]
using System;
using Memoria.Data;

namespace Memoria.Scripts.Battle
{
public static class CommonScript
{
public const String InfoMessageColor = "[00FFFF]";
public const String GoodMessageColor = "[00FFFF]";
public const String BadMessageColor = "[FF4040]";
}

public abstract class BaseWeaponScript : IBattleScript
{
private readonly BattleCalculator _v;
private readonly CalcAttackBonus _bonus;
private readonly Boolean _drain;

protected BaseWeaponScript(BattleCalculator v, CalcAttackBonus bonus, Boolean drain = false)
{
_v = v;
_bonus = bonus;
_drain = drain;
}

public virtual void Perform()
{
if (_drain && (!_v.IsCasterNotTarget() || !_v.Target.CanBeAttacked()))
return;

_v.PhysicalAccuracy();
if (!_v.TryPhysicalHit())
return;

if (_bonus != CalcAttackBonus.Level)
_v.WeaponPhysicalParams(_bonus);
else
{
Int32 baseDamage = GameRandom.Next16() % (1 + (_v.Caster.Level + _v.Caster.Strength >> 3));
_v.Context.AttackPower = _v.Caster.WeaponPower;
_v.Target.SetPhysicalDefense();
if (_v.Caster.Weapon == (RegularItem)256)
{
_v.Context.AttackPower += 3 * _v.Caster.Level / 4;
if (_v.Target.IsPlayer && _v.Target.PlayerIndex == CharacterId.Garnet)
_v.Target.Flags |= CalcFlag.HpRecovery;
}
else
{
_v.Context.AttackPower += _v.Caster.Level / 2;
}
_v.Context.Attack = _v.Caster.Strength + baseDamage;
}

if (_v.Caster.IsUnderAnyStatus(BattleStatus.Mini))
_v.Context.Attack = 1;
if (_v.Caster.IsUnderAnyStatus(BattleStatus.Berserk))
++_v.Context.DamageModifierCount;
if (_v.Caster.IsUnderAnyStatus(BattleStatus.Trance))
++_v.Context.DamageModifierCount;
if (_v.Target.IsUnderAnyStatus(BattleStatus.Defend))
--_v.Context.DamageModifierCount;
if (_v.Target.IsUnderAnyStatus(BattleStatus.Protect))
--_v.Context.DamageModifierCount;
if (_v.Target.IsUnderAnyStatus(BattleStatus.Sleep))
++_v.Context.DamageModifierCount;
if (_v.Target.IsUnderAnyStatus(BattleStatus.Mini))
++_v.Context.DamageModifierCount;

if (_drain)
_v.PrepareHpDraining();

if (_v.Caster.Weapon == (RegularItem)15) //I still have to add other final weapons
{
          _v.CalcDamageCommon();

          _v.Target.HpDamage = _v.Context.EnsureAttack * _v.Context.EnsurePowerDifference;

                  if (_v.Target.Flags != 0)
                  {
                    Single modifier_factor = 1.0f;
                    Single modifier_bonus = 0.5f;
                    Byte modifier_index = 0;

                        if (_v.Caster.IsUnderAnyStatus(BattleStatus.Trance) && _v.Caster.PlayerIndex == CharacterId.Steiner)
                            modifier_bonus = 1.0f;
                        while (_v.Context.DamageModifierCount > 0)
                        {
                            modifier_factor += modifier_bonus;
                            modifier_index++;
                            if (modifier_index >= 2)
                            {
                                modifier_bonus *= 0.5f;
                                modifier_index = 0;
                            }
                            --_v.Context.DamageModifierCount;
                        }

                    while (_v.Context.DamageModifierCount < 0)
                    {
                        modifier_factor *= 0.5f;
                        ++_v.Context.DamageModifierCount;
                    }

                     if ((_v.Target.Flags & CalcFlag.HpAlteration) != 0)
                     {
                        _v.Target.HpDamage = (Int32)Math.Round(modifier_factor * _v.Target.HpDamage);

if ((_v.Target.HpDamage > 9999) && (_v.Target.HpDamage < 15001))
_v.Target.HpDamage = 9999 + (_v.Target.HpDamage - 9999) / 2;
if (_v.Target.HpDamage > 15000)
_v.Target.HpDamage = 12500 + (_v.Target.HpDamage - 15000) / 4;

                        if ((_v.Target.Flags & CalcFlag.HpRecovery) != 0)
                        {
                        _v.Target.HpDamage = btl_para.SetRecover(_v.Target, (UInt32)_v.Target.HpDamage);
            _v.Target.FaceTheEnemy();
                        }
                     }
      }
     }
else
{
_v.CalcPhysicalHpDamage();
}
if (_drain)
_v.Caster.HpDamage = _v.Target.HpDamage;
}
}
}


However I couldn't find a way to handle critical strikes, which double the final damage regardless of my efforts.
Commonscript.cs of Alternate fantasy doesn't contain a call for the "_v.TryCriticalHit()" function, unlike vanilla "baseweaponscript.cs", that is only coded in SBattleCalculator.cs and seems to be applied after the damage calculation (if I end my function setting targethpdamage to a fix "100", a critical strike inflicts "200" damage).
What I would like to do is to calculate the *2 damage of critical hits before my damage reduction formula, so that a 5000x2 critical is handled normally but a 10000x2 one deals way lesser damage.

There is any way to do this?
A BIG thank you in advance  :)
« Last Edit: 2024-01-28 08:48:06 by ste459 »

Tirlititi

  • *
  • Posts: 874
    • View Profile
Re: [PSX/PC] Alternate Fantasy (v3.2 & v6.0)
« Reply #479 on: 2024-01-28 15:16:30 »
Hi,
Fortunatly, that shouldn't be too hard. You only need to emulate the method "TryCriticalHit" and change the increase formula it uses.
Code: [Select]
// In your "CommonScript.cs"

public static void TryCriticalHitAdjusted(BattleCalculator _v)
{
Int32 quarterWill = _v.Caster.Data.elem.wpr >> 2;
if (quarterWill != 0 && (Comn.random16() % quarterWill) + _v.Caster.Data.critical_rate_deal_bonus + _v.Target.Data.critical_rate_receive_bonus > Comn.random16() % 100)
{
_v.Target.HpDamage = (Int32)(_v.Target.HpDamage / 4f + Math.Min(15000, _v.Target.HpDamage) / 4f + Math.Min(10000, _v.Target.HpDamage) / 2f);
// Do the same for "_v.Target.MpDamage"; apparently you don't use "_v.Context.Attack" in your situation when the critical strike triggers
_v.Target.Flags |= CalcFlag.Critical;
}
}
And then you use "CommonScript.TryCriticalHitAdjusted(_v)" in place of "_v.TryCriticalHit()".
I think the rounding in my formula is correct, but you'd better check how it behaves exactly in practice to be sure about it.

ste459

  • *
  • Posts: 14
    • View Profile
Re: [PSX/PC] Alternate Fantasy (v3.2 & v6.0)
« Reply #480 on: 2024-01-29 08:08:36 »
Thanks for your kind reply.
(and your math expression is written way better than mine ;D )

For some reason I can't made this code to work, I entered it and at the beginning and called it with the line: CommonScript.TryCriticalHitAdjusted(_v); but I always get an error from Compiler because commonscript.cs does not contain a definition for TryCriticalHitAdjusted.

My commonscript.cs file looks like that (but I tried to insert the code in different positions with the same result):

Code: [Select]
using System;
using Memoria.Data;

namespace Memoria.Scripts.Battle
{
public static class CommonScript
{
public const String InfoMessageColor = "[00FFFF]";
public const String GoodMessageColor = "[00FFFF]";
public const String BadMessageColor = "[FF4040]";
}


public abstract class BaseWeaponScript : IBattleScript
{
private readonly BattleCalculator _v;
private readonly CalcAttackBonus _bonus;
private readonly Boolean _drain;

public static void TryCriticalHitAdjusted(BattleCalculator _v)
{
Int32 quarterWill = _v.Caster.Data.elem.wpr >> 2;
if (quarterWill != 0 && (GameRandom.Next16() % quarterWill) + _v.Caster.Data.critical_rate_deal_bonus + _v.Target.Data.critical_rate_receive_bonus > GameRandom.Next16() % 100)
{
_v.Target.HpDamage = (Int32)(_v.Target.HpDamage / 4f + Math.Min(15000, _v.Target.HpDamage) / 4f + Math.Min(10000, _v.Target.HpDamage) / 2f);
// Do the same for "_v.Target.MpDamage"; apparently you don't use "_v.Context.Attack" in your situation when the critical strike triggers
_v.Target.Flags |= CalcFlag.Critical;
}
}


protected BaseWeaponScript(BattleCalculator v, CalcAttackBonus bonus, Boolean drain = false)
{
_v = v;
_bonus = bonus;
_drain = drain;
}


public virtual void Perform()
{

if (_drain && (!_v.IsCasterNotTarget() || !_v.Target.CanBeAttacked()))
return;

_v.PhysicalAccuracy();
if (!_v.TryPhysicalHit())
return;

if (_bonus != CalcAttackBonus.Level)
_v.WeaponPhysicalParams(_bonus);
else
{
Int32 baseDamage = GameRandom.Next16() % (1 + (_v.Caster.Level + _v.Caster.Strength >> 3));
_v.Context.AttackPower = _v.Caster.WeaponPower;
_v.Target.SetPhysicalDefense();
if (_v.Caster.Weapon == (RegularItem)256)
{
_v.Context.AttackPower += 3 * _v.Caster.Level / 4;
if (_v.Target.IsPlayer && _v.Target.PlayerIndex == CharacterId.Garnet)
_v.Target.Flags |= CalcFlag.HpRecovery;
}
else
{
_v.Context.AttackPower += _v.Caster.Level / 2;
}
_v.Context.Attack = _v.Caster.Strength + baseDamage;
}

if (_v.Caster.IsUnderAnyStatus(BattleStatus.Mini))
_v.Context.Attack = 1;
if (_v.Caster.IsUnderAnyStatus(BattleStatus.Berserk))
++_v.Context.DamageModifierCount;
if (_v.Caster.IsUnderAnyStatus(BattleStatus.Trance))
++_v.Context.DamageModifierCount;
if (_v.Target.IsUnderAnyStatus(BattleStatus.Defend))
--_v.Context.DamageModifierCount;
if (_v.Target.IsUnderAnyStatus(BattleStatus.Protect))
--_v.Context.DamageModifierCount;
if (_v.Target.IsUnderAnyStatus(BattleStatus.Sleep))
++_v.Context.DamageModifierCount;
if (_v.Target.IsUnderAnyStatus(BattleStatus.Mini))
++_v.Context.DamageModifierCount;

if (_drain)
_v.PrepareHpDraining();

CommonScript.TryCriticalHitAdjusted(_v);

if (_v.Caster.Weapon == (RegularItem)15)
{
          _v.CalcDamageCommon();

          _v.Target.HpDamage = _v.Context.EnsureAttack * _v.Context.EnsurePowerDifference;

                  if (_v.Target.Flags != 0)
                  {
                    Single modifier_factor = 1.0f;
                    Single modifier_bonus = 0.5f;
                    Byte modifier_index = 0;

                        if (_v.Caster.IsUnderAnyStatus(BattleStatus.Trance) && _v.Caster.PlayerIndex == CharacterId.Steiner)
                            modifier_bonus = 1.0f;
                        while (_v.Context.DamageModifierCount > 0)
                        {
                            modifier_factor += modifier_bonus;
                            modifier_index++;
                            if (modifier_index >= 2)
                            {
                                modifier_bonus *= 0.5f;
                                modifier_index = 0;
                            }
                            --_v.Context.DamageModifierCount;
                        }

                    while (_v.Context.DamageModifierCount < 0)
                    {
                        modifier_factor *= 0.5f;
                        ++_v.Context.DamageModifierCount;
                    }

                     if ((_v.Target.Flags & CalcFlag.HpAlteration) != 0)
                     {
                        _v.Target.HpDamage = (Int32)Math.Round(modifier_factor * _v.Target.HpDamage);

if ((_v.Target.HpDamage > 9999) && (_v.Target.HpDamage < 15001))
_v.Target.HpDamage = 9999 + (_v.Target.HpDamage - 9999) / 2;
if (_v.Target.HpDamage > 15000)
_v.Target.HpDamage = 12500 + (_v.Target.HpDamage - 15000) / 4;

                        if ((_v.Target.Flags & CalcFlag.HpRecovery) != 0)
                        {
                        _v.Target.HpDamage = btl_para.SetRecover(_v.Target, (UInt32)_v.Target.HpDamage);
            _v.Target.FaceTheEnemy();
                        }
                     }
      }
     }
else
{
_v.CalcPhysicalHpDamage();
}
if (_drain)
_v.Caster.HpDamage = _v.Target.HpDamage;
}
}
}

Sorry if I bother you again, I have no programming experience and maybe I got lost in a trivial problem.

Another question, does this code replaces the "standard" critical hit function? I already tried before to emulate the critical hit function (in a much more basic manner) and I ended with 2 different kind of criticals, one triggered by my function plus the standard *2 one

Thanks again!!
« Last Edit: 2024-01-29 08:10:36 by ste459 »

htcsau5

  • *
  • Posts: 2
    • View Profile
Re: [PSX/PC] Alternate Fantasy (v3.2 & v6.0)
« Reply #481 on: 2024-02-12 16:36:03 »
i had removed my original post, as i decided to venture on and give it a full shot. i think it has been okay, but i do want to reiterate some of my removed points as feedback.

*SPOILERS*

i am currently escaping alexandria, at the freya/steiner/x and zidane/garnet/vivi split.

i firmly believe that item spamming is not a beneficial method of difficulty scaling. it just isn't that fun. i am going through potions and phoenix downs like crazy. i've never had to buy phoenix downs in a final fantasy before, that i can recall. there's several reasons why i am having to:

1. i just don't know all the modifications. before, i could go up to an enemy and know 'okay, i need to use one zidane attack, a vivi spell, and freya hit, then quina can eat it.' 'okay, we need to steal three pieces of gear from this boss. oh shit, they only have two and i just died because zidane wasted a turn.' now, it is all brand new to me. so, things throw me off. and that's totally fine, that's the entire point! it is a learning experience. i happily embrace that. i read the entire first post, and then completely forgot pinions are meant to remove doom. a certain... boss fight or two left me blowing through phoenix downs and just barely hanging on, with multiple attempts. then, about the third time, i just happened to have my <select> button info while i hovered over pinions, and i realized.

2. a lot of unique encounters seem scripted. *SPOILERS AGAIN* zorn and thorn don't seem to care if you mitigate their power, one of them can inflict blind on everyone but i think vivi. the other uses its spell and does like trouble or something. and you're left spamming eye drops with vivi since i think it is scripted to not apply to him, or maybe it is scripted to apply to 3/4 of the party. both attempts, i had to item spam with vivi. i finished with just zidane and steiner alive.

   another example, the first or second freya/x bandersnatch battle. x gets instantly confused, and kills themself. i did not have to do this more than once, but i am 100% sure that is always going to happen, every single time. maybe the attack can miss? i suppose i understand that it is a challenge mod, but when i can smell the contrived nature, i just don't know... what if i had run out of phoenix downs and pinions at this point? i think i would have to reload all the way to the beginning of cleyra. were that the case, thank heavens i use a new save almost every moogle, but it would still be a pretty big buzzkill.



it seems like random encounter rate is increased. using 60 fps, my previous playthrough i could go screen after screen without any fights. now, it seems even on 60 fps it is more akin to the psx version. perhaps that is fair, i have just turned off random battles when i'm not trying to eat with quina. i don't try to avoid every single bit of exp i can, but i do try to keep it minimal til i grab better spirit gear.

quina's changes are interesting. i still think she feels awkward early on, but it's fun to try. giving her shapeshift is really cool, and the animation is pretty dope. i don't recognize it, personally.

i wish zidane's thievery was still in the mod. i've back row'ed him the whole playthrough, and think this is the perfect atmosphere to actually rely on him as an item thief in all battles, knowingly or unknowingly boosting his ultimate skill. i was stealing every normal fight until i realized there's no thievery. that being said, his access to some damage and additional utility early on is a great addition.

i think you buffed chocographs in hot and cold? i seemed to get the first eight really fast. like, 12-15 attempts. i'm curious to see how much of the treasure has changed. i think i'm missing bio from oak staff?? which is somewhat noticeable, since it was kinda broken in vanilla as early as you could get it. i actually had to use blizzara in cleyra haha. i think this is cool and i embrace that re-balance. the vivi attack-command alteration from memoria seems to only use blizzard, regardless of weakness. might be a discrepancy between the codes, or just to try and hit the new freeze added effect. not sure, but he's doing some weak numbers with it. it is nice for trying to time quina eats, since they are relatively weak.

abilities as a whole seem like a welcome change. i do want to mention, again, the contrived nature of having zero bright eyes access and having that altered zorn and thorn mechanic. you should allow the player even the slightest opportunity to prepare themself. i know i have every item available in the game thus far, besides any tantarion drop, and there are no opportunities to learn that ability.



my ultimate analysis so far is there are some really good QoL changes outside of battle, and perhaps even in random battles. my jury is still out on some of your boss changes. once there's a stable white mage, i'll revisit this. i don't like an item spam meta, but i do respect that there's a limited number of ways to adjust battle in this game and make it unique.

one thing i've really learned to do, using the memoria 3 battle speed, is to always open a secondary window and just await queued inputs. it almost begs for you to use the ffx style turn-based system available in memoria, but i haven't committed to that yet. but, opening and closing and a target or skill window definitely helps your ability to react on the fly. every command can matter, from what i've seen.

i know this took a ton of time and i thank you, and i'm gonna continue to the end, see what else lies in store.

« Last Edit: 2024-02-14 17:22:55 by htcsau5 »

Sohnii

  • *
  • Posts: 1
    • View Profile
Re: [PSX/PC] Alternate Fantasy (v3.2 & v6.0)
« Reply #482 on: 2024-02-13 00:01:21 »
Is the Beatrix only Mod still available to play? or is it only the 1 main alternate Fantasy mod now? I'm a little confused on this?

htcsau5

  • *
  • Posts: 2
    • View Profile
Re: [PSX/PC] Alternate Fantasy (v3.2 & v6.0)
« Reply #483 on: 2024-02-13 09:55:22 »
Is the Beatrix only Mod still available to play? or is it only the 1 main alternate Fantasy mod now? I'm a little confused on this?


Beatrix Mod is available as a standalone. You can install it from the Memoria Mod Manager.