News:

Rings of Reznor!

Main Menu

Adding new attributes

Started by DoctorRuina, August 24, 2024, 12:01:45 PM

Previous topic - Next topic

DoctorRuina

Recently, I've been experimenting with adding new attributes. I had a first success adding a variant of the invulnerability attribute that reduces damage by only 1 hp. I then added two variants of the coordinator attribute with a +1 and +2 bonus, instead of +3, to represent lower-ranking leadership (although it's hard to know if they're working well). Does anyone have ideas or suggestions on this? I would like to add more attributes to give more variety to the characters.

oktokels

Is it possible to create attributes for FFX that resist certain types of attacks? The problem with the existing attributes like volcanic, charged, radioactive, etc., is that it's not possible to create combo attributes with them.

spydermann93

Man, I wish!

I've tried finding a way to do it, but I was very unsuccessful.

If anybody does figure it out, I would LOVE to know!

stumpy

I don't think there is a way to only provide resistance to certain damage types. At least if I am recalling correctly, the scripting APU doesn't allow us to see what type of damage was dealt before we "undeal" it.
Courage is knowing it might hurt, and doing it anyway. Stupidity is the same. And that's why life is hard. - Jeremy Goldberg

DoctorRuina

Would it be possible to create an invulnerability that would reduce the damage of a certain type?

DoctorRuina

And, Would it be possible to create an attribute that gives resistance to fear instead of immunity?

stumpy

I don't think the damage-type specific Invulnerability will work, for the reasons mentioned above.

I actually think that there already is an FFX attribute that reduces the chances of a status effect taking hold, though it is something of an imperfect implementation. As I recall, the attribute fired when a status effect took hold and gave some % chance of clearing it. The disadvantage was that the status effect did actually take hold for a very short time and that would be enough to clear the character's action queue. So, not quite as good as Disciplined.
Courage is knowing it might hurt, and doing it anyway. Stupidity is the same. And that's why life is hard. - Jeremy Goldberg

DoctorRuina

#7
Ooooh!! :banghead:
Another question. In the knockoutgas script is mentioned an attribute named nonbreather, but I I haven't found it. Where is it?  It would be good to simulate gas masks and so on.
And I would also like to add a knockout gas that would leave you unconscious for longer or even have a permanent effect.
Finally, I don't know if it would be possible to create a fear effect that would be recognized as a gas, as is the case with the scarecrow's fear gas, or also create a stunning gas. So someone with the nonbreather attribute wouldn't be affected.

Epimethee

#8
Quote from: DoctorRuina on August 27, 2024, 05:59:52 AMAnother question. In the knockoutgas script is mentioned an attribute named nonbreather, but I I haven't found it. Where is it?  It would be good to simulate gas masks and so on.
And I would also like to add a knockout gas that would leave you unconscious for longer or even have a permanent effect.
Finally, I don't know if it would be possible to create a fear effect that would be recognized as a gas, as is the case with the scarecrow's fear gas, or also create a stunning gas. So someone with the nonbreather attribute wouldn't be affected.
I don't think nonbreather was implemented as an attribute (I guess it was there more for modders), but it should be very easy to implement. My guess (not tested and I'm very rusty!) would be that you could just have:
def initnonbreather(char,update=0,remove=0):
    if remove:
        if FFX_ObjectGetAttr(char,'nonbreather'):
            FFX_ObjectSetAttr(char,'nonbreather',0)
        return
    if not FFX_ObjectGetAttr(char,'nonbreather'):
        FFX_ObjectSetAttr(char,'nonbreather',1)
You'd also need to add the attribute in FFEdit.

As for changing the duration, you can play with the last line of the function
def kogasS(event,state,intensity):
    char=event.object
    source=event.string
    if Object_GetSecondaryStates(char)&state:
        Object_SetSecondaryState(char,state,0,REMOVE_STATE)
        knockoutgas(char, source, (intensity * 3) + 3)
e.g., changing (intensity * 3) + 3 to (intensity * 9) + 3 would almost triple the duration.

For the Scarecrow (and copycats like Mr. Fear... and most certainly for Dr. Manbot's Wicked Pisser), you could create a new fear gas power, using the knockout gas power as a base, but removing most of the code, as you simply want to apply the built-in panic effect, but with robots and other non-breathers resisting it. Obviously, this is trickier to code than the previous cases, but should be doable with patience.  ^_^



BTW, confirming what Stumpy said (err, sorry, wrote – I'm pretty sure this gentleman doesn't speak aloud when typing) regarding specific resistances, as neither the provided API nor the hacks through the various debug logging system provide any hook.

In some cases, when creating FFX attributes and power that seems undoable due to game-engine limitations, a workaround might be doable for a specific character using heuristics, say by checking the log for the animation and effect names, but that's not going to work for other characters using the same attribute and might get triggered if a character uses the same animation or effect for something else. Thus, it's strictly a mod-specific solution.
FFX add-on for FFvsTTR at ffx.freedomforceforever.com

DoctorRuina

Thanks a lot, Epimethee  :thumbup:. I'm going to try these scripts right away.
But I've read on the forum that there is a maximum number of lines in the ffx.py file. Is there such a limit?

Epimethee

Yes, there is such a limit. IIRC, if you put the Non-Breather attribute initialization function in ffx2.py instead, it should work from there (as always, back up first). In theory the code should be okay to run from there without changes as every function is imported transparently, but if you get errors telling you that a function isn't found, you could prefix the imported functions by adding the file they're imported from (you can do this even if there's no error too, as there is no downside to do so*), i.e. "ffx.":

def initnonbreather(char,update=0,remove=0):
    if remove:
        if ffx.FFX_ObjectGetAttr(char,'nonbreather'):
            ffx.FFX_ObjectSetAttr(char,'nonbreather',0)
        return
    if not ffx.FFX_ObjectGetAttr(char,'nonbreather'):
        ffx.FFX_ObjectSetAttr(char,'nonbreather',1)

*That's how we should have done it everywhere. Blame a mix of unfamiliarity with Python, a the time an obscure new language (or in my case, unfamiliarity with any sort of programming) and very limited IDEs (code editors) at the time, with no auto-suggests and no refactoring tools.
FFX add-on for FFvsTTR at ffx.freedomforceforever.com

DoctorRuina

#11
Thanks I will put it in ffx2 then.
Yes, python is very difficult for me. It was easier to program with nwscript in neverwinter.
By the way, I have added the coordinator variants in ffx, but honestly, I don't know if they are working well or not. But invulnerable 1hp it is working.

Epimethee

#12
Quote from: DoctorRuina on August 31, 2024, 04:26:53 PMYes, python is very difficult for me. It was easier to program with nwscript in neverwinter.
Yeah, a full-fledged programming language is always going to be harder than a game-specific scripting language. However, it's going to be more powerful and the skill more transferable.

If you do a few basic Python tutorials first and play with the FF console, you should get the hang of it progressively more easily, as Python is a great language for learning programming, a key reason why the language is now one of the 2-3 most popular. Caveat emptor, FF uses Python 1.5, which dates from way back when the language was brand new; some of the syntax, best practices, etc. have changed. If you get stuck, you could try to use AI for help; it's sometimes going to give you wrong answers, but it should still be an amazing help. (Sample ChatGPT 4-o prompt: "You're a Python developer and teacher. I'm a beginner and have no formal programming training. All your examples need to target Python 1.5.3, not Python 2 or 3.")

Honestly, Python has spoiled programming for me: By comparison, I found the other languages too ugly (hey, I'm a designer) to ever really learn them. It's still been hugely useful to learn for my work, mind you.

Quote from: DoctorRuina on August 31, 2024, 04:26:53 PMBy the way, I have added the coordinator variants in ffx, but honestly, I don't know if they are working well or not.
You could add a print statement and check script.log to see if the value is indeed changed:
def addAgility(char,bonus):
    Object_SetAttr(char,'agility',Object_GetAttr(char,'templateAgility')+bonus)
    print "Coordinator %s agility set to %i" % (char, Object_GetAttr(char, 'agility'))
FFX add-on for FFvsTTR at ffx.freedomforceforever.com

DoctorRuina

well, the nonbreather attribute didn't work when i wrote it in ffx2, but it works fine in ffx :thumbup: . About the gas fear, I still don't know very well how to do it. I will continue investigating...

oktokels

could it be possible to make an attribute that makes the hero resistant to blindness?
I've been using Danger Sense for this effect, but this also makes the character immune to attacks from the back.

spydermann93

the best would be kind of like how Fearless or FFX's Disciplined/Unbeliever works: when a character has blind on them, the attribute will randomly decide to remove it.

DoctorRuina

I'm also interested in an attribute that makes the hero resistant to blindness.

DoctorRuina

FEARLESS ##########################################

def initfearless(char,update=0):
    RegCharState(char,PCSTATE_PANICKED,'clearMindFear')

######################## DISPASSIONATE ######################################

def initdispassionate(char,update=0):
    RegCharState(char,PCSTATE_ENRAGED,'clearMindRage')


Would work replacing it with PCSTATE_BLINDED,'clearMindBlind' ?

spydermann93

I think the PCSTATE_BLINDED is right, but I'm not sure if "clearMindBlind" is right. You could try it and see, though. If it's not right, I think the Unbeliever trait might have the right call in it.

DoctorRuina

I have experimented with SCSTATE_BLIND, PCSTATE_BLIND, ClearBlind, PrimaryState, SecondaryState... and have not had success.

Epimethee

#20
Please post your code and script.log. :)

There is no SCSTATE_BLIND; Blind is a Primary Character State, as those states are mutually exclusive, contrarily to secondary states. When in doubt, you may refer to the FF scripting manual Word document which should be in your Help folder.
FFX add-on for FFvsTTR at ffx.freedomforceforever.com

DoctorRuina

#21
Thanks Epimethee!
In ffx I've found lines with SCSTATE_BLIND...

I've been experimenting with this. I was really hoping it might work. :wacko: 

######################## BLIND INMUNITY ######################################

def initblindinmunity(char,update=0):
    RegCharState(char,PCSTATE_BLIND,'clearBlind')

def clearBlind(event):
    char=event.object
    Object_SetPrimaryState(char,PCSTATE_BLIND,0,REMOVE_STATE)
    RegCharState(char,PCSTATE_BLIND,'clearBlind')

mac402

I was trying to do this too a long time ago. Here is a working code if you want to use:
######################## INFRAVISION ##########################################

def initinfravision(char,update=0,remove=0):
    if remove:
        FFX_ObjectSetAttr(char, 'infravision', 0)
        return
    FFX_ObjectSetAttr(char,'infravision',1)
    RegTimer('clearBlind',1,0,char)

def clearBlind(event):
    char=event.object
    if FFX_ObjectGetAttr(char,'infravision')==1:
        RegTimer('clearBlind',5,1,char)
        Object_SetSecondaryState(event.object, SCSTATE_BLIND, 0, REMOVE_STATE)
    else:
        return

It seems running a timer is necessary to make it work.