• Welcome to Freedom Reborn Archive.
 

New Attribute: Battle Computer

Started by TaskMasterX, July 05, 2007, 08:38:54 AM

Previous topic - Next topic

TaskMasterX

LOL! I can't stop making this stuff! It's to much fun!
Anyway, here's a new attribute I came up with, called Battle Computer. I took the idea from the Beetle, a villain in Marvel Comics that has frequently battled Spider-Man and Cap. He has a Battle Computer that allows him to study a target's combat manuevers and store them so he can use the data to fight better against that foe.
What I did was allow up to four enemies to be stored in the database at the beginnig of a mission and also allow the character with this attribute to add one target to the database during a mission. When one of these targets get within range, he gets an attack bonus and +2 to agility. When they are out of range the bonuses are canceled. The range is customizable.
When the character with this attribute targets a foe that isn't in the database and selects the command, "Add Target to Battle Computer", it takes 10 seconds for the target to be studied and then loaded into the database. If during these 10 seconds, the target gets out of range, or the character with the Battle Computer uses any powers that cost Energy, OR, gets Stunned, Paniked, Exiled, or any other Primary State, the Computer fails and you have to try again. The Battle Computer needs all the Energy available to study the target, so that's why no Energy can be used during these 10 seconds.
You get messages on-screen telling you that the target is being studied and when it successfully adds the target to the database. You also get messages when the Battle Computer fails and to try again.
So, here's the code for the ffx.py file:
############################## BATTLE COMPUTER ########################################
# Allows the character to have a database of up to 4 characters. When the character
# is within range of one of these characters, they get +2 agility and two new commands
# that appear only on the target and can be used to simulate the character's existing powers
# but with higher accuracy, speed, magnitude, stun, etc.
# The character can also add one target to the database during a mission for a total of
# 5 database entries.
# -TaskmasterX
# Strings.txt Entries:
# ATTRIB_BATTLECOMPUTER_01, battle computer
# ATTRIB_BATTLECOMPUTER_DESC_01, you have a computer capable studying a targets battle tactics and then predicts the targets manuevers, effectively giving you a bonus to damage and agility.
# ADD_TARGET_TO_DATABASE_01, add target to database
# ADD_TARGET_TO_DATABASE_DESC_01, adds the selected target to the battle computer database
#######################################################################################

def initbattlecomputer(char,update):
    print 'battle computer loading...'
    RegTimer('enemyCheck',1,0,char)
    FFX_ObjectSetAttr(char,'computer_on',0)
    FFX_ObjectSetAttr(char,'battleComputer',1)
    objects = Mission_GetObjects()
    for obj in objects:
        if ((Object_GetClass(obj)&FFX_CHARACTER)!=0) & (obj!=char):
            Mission_CustomAction('ADD_TARGET_TO_DATABASE',char,obj,'studyTarget',30,0)

def studyTarget(obj,char):
    dbEntry1=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,1)
    dbEntry2=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,2)
    dbEntry3=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,3)
    dbEntry4=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,4)
    target=getTargetname(obj)
    if (dbEntry1==target) | (dbEntry2==target) | (dbEntry3==target) | (dbEntry4==target):
        Mission_StatusText('target is already in Battle Computer!')
        return
    if FFX_ObjectGetAttr(obj,'addedToDB')!=0:
        FFX_ADD_TARGET_TO_DB = target
        dbEntry5=FFX_ADD_TARGET_TO_DB
        if dbEntry5==target:
            Mission_StatusText('target is already in Battle Computer!')
            return
    Mission_StatusText('adding target to Battle Computer...')
    FFX_ObjectSetAttr(obj,'addingToDB',1)
    RegTimer('checkRangeBC',1,0,char,obj)
    RegTimer('addTargettoDB',10,0,char,obj)
    RegTimer('checkEnergyUseBC',1,0,char,obj)
    RegCharState(char,PCSTATE_BLANK,'battleComputerFail',0,0,obj)
    RegCharState(char,PCSTATE_EXILE,'battleComputerFail',0,0,obj)
    RegCharState(char,PCSTATE_STATIC,'battleComputerFail',0,0,obj)
    RegCharState(char,PCSTATE_ENRAGED,'battleComputerFail',0,0,obj)
    RegCharState(char,PCSTATE_HYPNOTISED,'battleComputerFail',0,0,obj)
    RegCharState(char,PCSTATE_PANICKED,'battleComputerFail',0,0,obj)
    RegCharState(char,PCSTATE_STUNNED,'battleComputerFail',0,0,obj)

def battleComputerFail(event):
    char=event.object
    obj=event.string
    Mission_StatusText('Battle Computer failed! try again')
    print 'battle computer failed! try again!'
    FFX_ObjectSetAttr(obj,'addingToDB',0)
    FFX_ObjectSetAttr(obj,'addingToDBFailed',1)

def checkEnergyUseBC(event):
    char=event.object
    obj=event.string
    if FFX_ObjectGetAttr(obj,'addingToDBFailed')==1:
        return
    if FFX_ObjectGetAttr(obj,'addedToDB')==1:
        return
    if FFX_ObjectGetAttr(char,'battleComputer')==1:
        FFX_ObjectSetAttr(char,'ivlasteng',Object_GetAttr(char,'energyPoints'))
        FFX_ObjectSetAttr(char,'battleComputer',0)
    energy=Object_GetAttr(char,'energyPoints')
    lastenergy = FFX_ObjectGetAttr(char,'ivlasteng')
    if energy<lastenergy:
        print 'energy loss!'
        if FFX_ObjectGetAttr(obj,'addingToDB')!=0:
            Mission_StatusText('you used energy the Battle Computer needs! try again!')
            print 'you used energy the battle computer needs! try again!'
            FFX_ObjectSetAttr(obj,'addingToDB',0)
            FFX_ObjectSetAttr(obj,'addingToDBFailed',1)
    else:
        RegTimer('checkEnergyUseBC',0.1,0,char,obj)
    FFX_ObjectSetAttr(char,'ivlasteng',Object_GetAttr(char,'energyPoints'))

def checkRangeBC(event):
    char=event.object
    obj=event.string
    if FFX_ObjectGetAttr(obj,'addingToDBFailed')==1:
        return
    pos1 = Get_ObjectPos(char)
    pos2 = Get_ObjectPos(obj)
    dist = cshelper.distance2D(pos1, pos2)
    radius=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,5)
    if FFX_ObjectGetAttr(obj,'addedToDB')==1:
        return
    if dist > radius:
        if FFX_ObjectGetAttr(obj,'addingToDB')!=0:
            Mission_StatusText('target is out of range and can not be added to Battle Computer! try again!')
            print 'target is out of range and can not be added to Battle Computer! try again!'
            FFX_ObjectSetAttr(obj,'addingToDB',0)
            FFX_ObjectSetAttr(obj,'addingToDBFailed',1)
    if dist < radius:
        RegTimer('checkRangeBC',1,0,char,obj)

def addTargettoDB(event):
    char=event.object
    obj=event.string
    print 'preparing to load target to Battle Computer'
    if FFX_ObjectGetAttr(obj,'addingToDBFailed')==1:
        FFX_ObjectSetAttr(obj,'addingToDBFailed',0)
        return
    else:
        if FFX_ObjectGetAttr(obj,'addingToDB')!=0:
            FFX_ObjectSetAttr(obj,'addedToDB',1)
            FFX_ADD_TARGET_TO_DB = obj
            Mission_StatusText('successfully added target to Battle Computer!')
            print 'successfully added target to Battle Computer!'
        else:
            print 'target failed to be entered into Battle Computer! try again!'
            Mission_StatusText('target failed to be entered into Battle Computer! try again!')
            FFX_ObjectSetAttr(obj,'addingToDB',0)

def enemyCheck(event):
    char=event.object
    if Object_Exists(char)==0:
        return
    if Object_IsAlive(char)==0:
        return
    radius=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,5)
    radius2=radius*radius
    print 'battle computer scanning map for targets...'
    RegTimer('enemyCheck',3,0,char)
    if FFX_ObjectGetAttr(char,'computer_on')!=0:
        print 'battle computer already locked onto a target!'
        return
    else:
        for obj in Mission_GetDynamicObjects():
            if ((Object_GetClass(obj)&FFX_CHARACTER!=0)) & (obj!=char) & ((Object_GetClass(obj)&js.OC_TERRAIN)==0) & ((Object_GetClass(obj)&js.OC_VEHICLE)==0) & ((Object_GetClass(obj)&js.OC_BUILDING)==0) & ((Object_GetClass(obj)&js.OC_GENERIC)==0):
                d=distanceSq(obj,char)
                print 'battle computer looking for targets in range...'
                if d<radius2:
                    print 'battle computer found targets in range...'
                    target=getTargetname(obj)
                    lookupTargetinBattleComputer(char,target,obj)
                else:
                    print 'battle computer did not find targets in range...'
            else:
                print 'battle computer did not any find targets!'

def lookupTargetinBattleComputer(char,target,obj):
    dbEntry1=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,1)
    dbEntry2=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,2)
    dbEntry3=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,3)
    dbEntry4=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,4)
    if FFX_ObjectGetAttr(obj,'addedToDB')!=0:
        FFX_ADD_TARGET_TO_DB = target
        dbEntry5=FFX_ADD_TARGET_TO_DB
        print 'new database entry=%s'%(dbEntry5)
        if dbEntry5==target:
            Object_SetGenericState(char,OBJSTATE_ATTACKBONUS,10000,0)
            FFX_ObjectSetAttr(char,'computer_on',1)
            agility=Object_GetAttr(char,'templateAgility')
            newAgility=Object_GetAttr(char,'templateAgility')+2
            Object_SetAttr(char,'agility',newAgility)
            agl=Object_GetAttr(char,'agility')
            Mission_StatusText('battle computer detected known enemy in range')
            print 'battle computer match found to new DB Entry!'
            RegTimer('trackTarget',1,0,char,obj)
            return
    print 'battle computer matching target to database...'
    print 'target=%s'%(target)
    print 'database entry1=%s'%(dbEntry1)
    print 'database entry2=%s'%(dbEntry2)
    print 'database entry3=%s'%(dbEntry3)
    print 'database entry4=%s'%(dbEntry4)
    print 'computer_on=%d'%(FFX_ObjectGetAttr(char,'computer_on'))
    if (dbEntry1==target) | (dbEntry2==target) | (dbEntry3==target) | (dbEntry4==target):
        cmd1=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,6)
        cmd2=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,8)
        Mission_CustomAction(cmd1,char,obj,'bcPower1',30,0)
        Mission_CustomAction(cmd2,char,obj,'bcPower2',30,0)
        FFX_ObjectSetAttr(char,'computer_on',1)
        agility=Object_GetAttr(char,'templateAgility')
        newAgility=Object_GetAttr(char,'templateAgility')+2
        Object_SetAttr(char,'agility',newAgility)
        agl=Object_GetAttr(char,'agility')
        Mission_StatusText('battle computer detected known enemy in range!')
        print 'battle computer match found to existing DB Entry!'
        print agl
        print cmd1
        print cmd2
        RegTimer('trackTarget',1,0,char,obj)
        return
    else:
        print 'battle computer match NOT found!'

def bcPower1(target,char):
    pwr1=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,7)
    Trigger_Power(char,target,pwr1,'')

def bcPower2(target,char):
    pwr2=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,9)
    Trigger_Power(char,target,pwr2,'')

def trackTarget(event):
    char=event.object
    obj=event.string
    dbEntry1=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,1)
    dbEntry2=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,2)
    dbEntry3=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,3)
    dbEntry4=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,4)
    print 'battle computer tracking target!'
    pos1 = Get_ObjectPos(char)
    pos2 = Get_ObjectPos(obj)
    dist = cshelper.distance2D(pos1, pos2)
    radius=getByTemplate(char,FFX_BATTLECOMPUTER_CUSTOM,5)
    if dist > radius:
        Mission_StatusText('enemy out of range of battle computer!')
        removeBCBonus(char)
    if dist < radius:
        print 'battle computer target still in range'
        RegTimer('trackTarget',1,0,char,obj)

def removeBCBonus(char):
    Object_SetGenericState(char,OBJSTATE_ATTACKBONUS,0,REMOVE_STATE)
    FFX_ObjectSetAttr(char,'computer_on',0)
    agility=Object_GetAttr(char,'templateAgility')
    Object_SetAttr(char,'agility',agility)
    print 'battle computer lost target!'

def getTargetname(obj):
    temp=FFX_GetTemplate(obj)
    name=GetRootName(temp)
    print 'battle computer scanning target...'
    print 'target name=%s'%(name)
    return name


And to make it customizable, you'll need to add this to the ffxcustom2.py file:
### Battle Computer
FFX_BATTLECOMPUTER_CUSTOM=[
["default","","","","",300,"","","",""],
["types","UDatabase Entry1","UDatabase Entry2","UDatabase Entry3","UDatabase Entry4","iRadius","CCommand1","sPower1","CCommand2","sPower2"],
["beetle","avengers captain america REN","iron man","spider-man","daredevil",300,"ELECTRO_BITE","beetle_electrobite","FAST_PUNCH","beetle_fastpunch"],
]

The line that begins with "beetle" is an example. You create another line below that one with the name of the character with the Battle Computer attribute and follow it with the names of the hero files you want to already be in the database at the beginning of the mission and the number is the range at which the Battle Computer can detect the target. Remember that you'll need to add an entry for "battlecomputer" in FFEdit under the Attributes tab and give it a cost and add the strings entries in the strings.txt file for the attribute and command descriptions. I provided example string entries at the top of the ffx.py code (Don't forget to remove the # at the beginning of the lines when adding them to the strings.txt!)

I should mention this will only work with FFX 3.2 or FFX 3.2.1.

Epimethee


stumpy

How do you keep the attack and agility bonuses from helping the character against everyone the attribute possessor fights when the target is in range? In other words, let's say I have a guy with this attribute and he has studied the Human Torch. If the whole Fantastic Four shows up, won't he have his bonuses against all of them (and anyone else present) as long as Johnny is there, even if he hasn't studied anyone else?

Lunarman

Stumpy is right although I think this is intentional.

Wouldn't there be a way to make the enhancements only to things affect the Human Torch?  As in, when your char is melee attacked by the human torch you add the agility bonus then? I don't know if there's a way to track who does what damage though.

the other way to do it would be make the Human Torch weak against damage X (like the toxic attribute) and then make it so the char does damage X for all his attacks. That way the rest of the foes won't be affected but human torch will take extra damage from him.

TaskMasterX

Quote from: stumpy on July 06, 2007, 12:46:43 AM
How do you keep the attack and agility bonuses from helping the character against everyone the attribute possessor fights when the target is in range? In other words, let's say I have a guy with this attribute and he has studied the Human Torch. If the whole Fantastic Four shows up, won't he have his bonuses against all of them (and anyone else present) as long as Johnny is there, even if he hasn't studied anyone else?
Unfortunately, I didn't see a way to do this. Like Lunarman said, I'd need a way to determine where the attack came from and then apply the +2 to Agility if the attack came from the target and I'd have to know the attack from the target was against the character with the Battle Computer Attribute. Applying the Attack Bonus to only the target might be feasible, but I'm not sure. It'd be easy to create another custom command that would only be on the target that was studied and the command would trigger a power that does more damage.
Any ideas on improving it would be greatly welcomed.

TaskMasterX

Okay, I updated this. Instead of getting an attack bonus, two customizable commands appear only on targets that are in the computer. These commands are linked with powers you can make in FFEdit to simulate the character's existing powers, but with a higher accuracy, swiftness, stun, magnitude, etc. Use the example I have for beetle in my 1st post for the code you place in ffxcustom2.py. First is the name of the character with this attribute ('beetle'). The next four things are the names of the characters that are already in the database. You can leave some quotes empty if you don't want them to have four. Next is the range. Following the range is the command of the 1st power, followed by the actual name of the power in FFEdit that command uses. And finally the 2nd command and power name.

As for the +2 Agility, I don't see any way to make that effective only against the target that's in the computer. So either I remove that part, or I just imagine that since the character with the Battle Computer is using different tactics to counter those of the target and so is behaving in a way that he normally doesn't and therefore is harder to hit for everyone. ^_^