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.
Very cool!
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?
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.
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.
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. ^_^