I just recently reinstalled the original :ff: and noticed how good the parkour is in this game with the combined "wall climbing" and "jumper" attribute. After playing with it. I haven't experienced any glitch. My character will just climb when there's a wall in front and jump over any close rooftops under him.
While in :ffvstr: the "jumper" attribute is still fine. But the wall climbing is a bit clunky. Sometimes your character will teleport straight at the top of a building.
If we could combine this into 1 attribute and call it "parkour" or something.
Is there a base script for FFX3 for this 2 attributes so I can edit them for :ffvstr:? Even just the wall climber script. I have looked at the FFX3's ffx.py and ffx2.py and found none.
My recollection is that both of those attributes are hard-coded into the engine. My guess is that combining them with scripting would be a challenge if it's possible, as most path-planning tasks tend to be pretty involved.
I play with those a lot. I usually avert teleport to the top as you say when I want just climbing by pointing at part of the side of the building. I have found glitches though, you might be seeing that. But they are caused by the building nifs themselves typically. Like there is a building for example in the city level to the right of the starting point that if you try and jump on it your character will fall through and no longer be visible, then they will have to work there way out of wherever it is they are getting stuck. I assume that is somewhere at the base of the same building. So short version see if it's the same building or not. It's Bounding Box or another detail in it just might not be set up correctly, I know the actual game devs. made some mistakes like that, the aforementioned building in the city being an example (second up in the first row to the right of the starting point I think?). I mentioned it because I ran into that teleporting effect as you call it but only on specific things.
Scripting in this game isn't my area otherwise, sorry. I take stumpy and Epimethee at there word and know the options for these games are limited. My learning of game dev. stopped at 2d right around when 3d first took off (Quake, Unreal, so on). My mind says then "relative, proximity, checksum, if and else" commands. In this example check if object X (wall of object) is relative distance from character X, if then wall climb, else leap. Or something to the this effect. But I don't know the script for these games nor what type of options are available. If been told relative height for example is not available and sort of understand how that tracks with how terrain and paths are made. And mind you again none of what I'm thinking will actually work if the game object/terrain space doesn't have the proper set up as well which in a few cases they do not. That gets worse with modified maps made from other maps (game building object is set on the wrong type of terrain space for example, doesn't have proper bounding boxes, so on). It's sort of just a common glitch I run into myself and just deal with.
AFAIK, simulating the built-in jumping and climbing through scripting is impossible... Well, at least, I never had any success.
Isn't something like living laser attribute close to jumping attribute?
Would anyone be willing to share their ffx code here? Just so we have something to start from.
Never had any code worth keeping for Climber, IIRC (it has been twenty years or close to!). I think the best idea I had was creating an invisible platform beneath the character when he was again a wall and locking him in a climbing animation. However, we had no way to detect buildings bounding boxes. We now have a workaround, I believe,but I'm not sure it's reliable enough;you may have to fire invisible projectiles, for ex. to detect walls and roofs.
For jumping, the closest I've got is already in FFX, through Limited Jumping, Clumsy Jumper and Jump Travel. Jumping Jack combines the last two with Dr Mike's Super Leaper.
Good luck, would be cool to have someone solve this! :)
Quote from: Miraitto on August 27, 2022, 05:37:53 AM
Would anyone be willing to share their ffx code here? Just so we have something to start from.
what part of the code? i can post it
I honestly have no idea where to start. There is no code for wall climbing only jumping. Something similar to FFX FlyMelee or Grapple maybe? But instead of locking on characters its only for buildings and structures.
I found this:
# TRIGGERFORCE JUMPERS #
Spoiler
Quote###################### TRIGGERFORCE JUMPERS ######################################
# An alternative to the buit-in Jumper attribute and to FFX's super-leaper.
# It looks clumsy, but it works! The HIGH JUMP command is certainly not as easy to use nor as precise
# as the build-in JUMP command. Well, it IS cheaper (and it can be combined with other scripted attributes).
#
# Status: 1.6
# Added 1.4 (FFX 3.0):
# -Updated EP cost to new system
# Added 1.6 FFX 3.2):
# -Changed landing animation method to use dummy power, as Slippery
# -Made compatible with Acrobatic and Acrobatic Amateur.
# -High Jumper, Jump Travel: Reduced initial pos. check frequency.
# -Made removable.
# -Hard-coded Jump Travel EP cost.
# Notes/Bugs
# -What are the actual effects of TF_NO_GRAVITY and TF_NO_COLLISION? TF_NO_DAMPING isn't recognized by the game engine.
# -Very rarely, you may get stuck in an object when landing. Jump again to solve.
# -Your character may be unable to jump again just after landing; just move him a bit to solve.
# -minForce and mass are only partialy compensated, because, hey, there should be some advantage to being lighter! ;)
# (Well, that was the idea, anyway. However, I haven't found how to account for mass; the values below are just trial
# and error. Help!)
# -Fixed?: Character sometimes got stuck in the landing animation. The same happened from time to time with Superleaper and Acrobat,
# if I remember correctly. Found a couple workaround, but - guess what? - Dr. Mike had again found a better one. I can't
# reproduce this intermitent bug anymore, which doesn't imply it doesn't exist anymore, of course. ;/
# EDIT: bug still happened sometimes, apparently. Should be OK now. EDIT 2: Changed the method for FFvsTTR.
# -Corrected a bug in Jump Travel resulting in possible stun if energy wasn't full!
def initffqhighjumper(char, update=0, remove=0):
if remove:
Mission_RemoveCustomAction('CUSTOM_FFQHIGHJUMP',char,char,)
else:
Mission_CustomAction('CUSTOM_FFQHIGHJUMP',char,char,'ffqJumpHigh',1,0)
def initffqlowjumper(char, update=0, remove=0):
if remove:
Mission_RemoveCustomAction('CUSTOM_FFQLOWJUMP',char,char,)
else:
Mission_CustomAction('CUSTOM_FFQLOWJUMP',char,char,'ffqJumpLow',1,0)
def initffqlongjumper(char, update=0, remove=0):
if remove:
Mission_RemoveCustomAction('CUSTOM_FFQFARJUMP',char,char,)
else:
Mission_CustomAction('CUSTOM_FFQFARJUMP',char,char,'ffqJumpFar',1,0)
def ffqJumpHigh(char,dummy):
FFX_ObjectSetAttr(char, 'voluntary_flailing', 1)
AI_Animate(char,'jump_stand','OnFFQjumpHigh',0,1)
def ffqJumpLow(char,dummy):
FFX_ObjectSetAttr(char, 'voluntary_flailing', 1)
AI_Animate(char,'jump_stand','OnFFQjumpLow',0,1)
def ffqJumpFar(char,dummy):
if chargeEP(char, 33)==0:
return
FFX_ObjectSetAttr(char, 'voluntary_flailing', 1)
AI_Animate(char,'jump_stand','OnFFQjumpFar',0,1)
#mass, minForce and strength matter here!
def OnFFQjumpHigh(event):
char=event.object
print "%s is jumping high"%(char)
myMassFactor=Object_GetAttr(char,'mass')
myMassFactor=sqrt(myMassFactor)
magnitude=(Object_GetAttr(char,'strength')*5000 + 15000 + Object_GetAttr(char,'minForce')*0.9) / 9*myMassFactor
Trigger_Force(char,0,-0.2,1,magnitude,TF_NO_ROTATION)
Object_SetAttr(char,'prejumpMinHealth',Object_GetAttr(char,'minHealth'))
Object_SetAttr(char,'minHealth',Object_GetAttr(char,'health'))
pos=Get_ObjectPos(char)
Object_SetAttr(char,'ffqz1',pos[2])
RegTimer('ffqGetMaxHeight',0.3,0,char)
#tries to compensate for mass; ignores minForce and strength
def OnFFQjumpLow(event):
char=event.object
print "%s is jumping low"%(char)
myMassFactor=Object_GetAttr(char,'mass')/100
magnitude=(15000 + (Object_GetAttr(char,'minForce'))) * myMassFactor
Trigger_Force(char,0,-0.2,1,magnitude,TF_NO_ROTATION)
Object_SetAttr(char,'prejumpMinHealth',Object_GetAttr(char,'minHealth'))
Object_SetAttr(char,'minHealth',Object_GetAttr(char,'health'))
pos=Get_ObjectPos(char)
Object_SetAttr(char,'ffqz1',pos[2])
RegTimer('ffqGetMaxHeight',0.1,0,char)
#mass, minForce and strength matter here!
def OnFFQjumpFar(event):
char=event.object
print "%s is jumping far"%(char)
myMassFactor=Object_GetAttr(char,'mass')
myMassFactor=sqrt(myMassFactor)
magnitude=(Object_GetAttr(char,'strength')*5500 + 12000 + Object_GetAttr(char,'minForce')*0.7) / 6 * myMassFactor
Trigger_Force(char,0,-0.9,0.5,magnitude,TF_NO_ROTATION)
Object_SetAttr(char,'prejumpMinHealth',Object_GetAttr(char,'minHealth'))
Object_SetAttr(char,'minHealth',Object_GetAttr(char,'health'))
pos=Get_ObjectPos(char)
Object_SetAttr(char,'ffqz1',pos[2])
RegTimer('ffqGetMaxHeight',0.5,0,char)
def ffqGetMaxHeight(event):
char=event.object
pos=Get_ObjectPos(char)
ffqz2=pos[2]
if (ffqz2 < Object_GetAttr(char,'ffqz1')) | (ffqz2 > 429):
RegTimer('landonfeet', 0.1, 0, char)
Object_SetAttr(char,'minHealth',Object_GetAttr(char,'prejumpMinHealth'))
else:
Object_SetAttr(char,'ffqz1',ffqz2)
RegTimer('ffqGetMaxHeight',0.1,0,char)
and the grapple code (had to remove some parts because it surpassed the forum length capacity):
Spoiler
Quote#################### grapple state swap ########################################################
# Wrestling Hold State Swap that locks the target and attacker in place. Every two seconds the
# target gets a chance to break free or gets dealt damage equal to twice the attacker's strength
# -TaskmasterX
################################################################################################
def grappleStartCheck(char,source,intensity):
if ffx.FFX_ObjectGetAttr(char,'grappled',0)==1:
return
AI_Animate(source,'lock')
mlogreader.regDodgeStart(source,'grappleCancel',0,0,0,char)
ffx.FFX_ObjectSetAttr(source,'grappleIntensity',intensity)
pos1 = Get_ObjectPos(char)
pos2 = Get_ObjectPos(source)
dist = cshelper.distance2D(pos1, pos2)
subtype = m25ai.FindTacticType(char, 'subtype')
if dist > 46:#check if the target moved too far away
if (Object_GetClass(char)&js.OC_VEHICLE)!=1:
if not ('vehicle' in subtype):
AI_Animate(source,'unlock')
AI_Animate(source,'melee_idle')
return
if (ffx.FFX_ObjectGetAttr(char,'grappleMental')==0) & (ffx.FFX_ObjectGetAttr(char,'grappleMystic')==0) & (ffx.FFX_ObjectGetAttr(char,'grappleEnergy')==0):
ffx.FFX_ObjectSetAttr(char,'grapplePhysical',1)
damage_type = m25ai.ai_damage_type['crushing']
damage_mode = m25ai.ai_damage_mode['melee']
if ffx.FFX_ObjectGetAttr(char,'ffactivedefense')==1:
useStr=ffx.getByTemplate(source,FFX_RANGEGRAPPLE_CUSTOM,2)
adHP=ffx.FFX_ObjectGetAttr(char,'ffactivedefenseHP')
grappleDmg=ffx.getByTemplate(source,FFX_RANGEGRAPPLE_CUSTOM,4)
if grappleDmg=='Yes':
if useStr=='Yes':
grappleDmg=Object_GetAttr(source,'strength')+1
else:
grappleDmg=ffx.getByTemplate(source,FFX_RANGEGRAPPLE_CUSTOM,3)
else:
grappleDmg=0
newHP=adHP-grappleDmg
ffx.FFX_ObjectSetAttr(char,'ffactivedefenseHP',newHP)
if ffx.FFX_ObjectGetAttr(char,'ffactivedefenseSelf',0)==0:
FFX_crushTest1a(char,source)
return
power=ffx.getByTemplate(char,FFX_FFACTIVEDEFENSE_CUSTOM,3)
powdata = datfiles.Campaign_ReadPowers()[power]
if powdata['PowerType'] == datfiles.PT_ACTIVE_DEFENCE:
if ( powdata['DamageTypesBlocked'] & damage_type ) and \
( powdata['AttackModesBlocked'] & damage_mode ):
m25getset.GetObjectVar(char, 'defense ' + `damage_type` + '_' + `damage_mode`, 1,nosave=1)
AI_Animate(source,'unlock')
AI_Animate(source,'melee_idle')
return
if ffx.FFX_HasPortrait(char):
if not m25ai.AIInWatch(char):
FFX_crushTest1a(char,source)
return
if m25ai.HasActiveDefenceActive(char,damage_type,damage_mode):
AI_Animate(source,'unlock')
AI_Animate(source,'melee_idle')
return
if ffx.FFX_ObjectGetAttr(char,'phased_out',0)==1:
AI_Animate(source,'unlock')
AI_Animate(source,'melee_idle')
return
makegrappled(char, source)
def FFX_crushTest1a(char,source):
name=ffx.getDummyName()
Object_SpawnAt('ffx_tiggot',Get_ObjectPos(source),name)
Trigger_Power(name,char,'ffx_melee_crush_test','',10)
ffx.FFX_ObjectSetAttr(char,'crushTestA',1)
ffx.FFX_ObjectSetAttr(source,'crushTestA',1)
ffx.RegTimer('ffx.destroyTemp',1,0,name)
ffx.RegCharState(char,PCSTATE_STUNNED,'FFX_crushTest2a',0,0,source)
ffx.RegTimer('FFX_crushTest3a',2,0,char,source)
def FFX_crushTest2a(event):
char=event.object
source=event.string
if ffx.FFX_ObjectGetAttr(char,'crushTestA',0)==1:
if ffx.FFX_ObjectGetAttr(source,'crushTestA',0)==1:
ffx.FFX_ObjectSetAttr(source,'crushTestA',0)
Object_SetPrimaryState(char,PCSTATE_STUNNED,0,REMOVE_STATE)
makegrappled(char,source)
ffx.FFX_ObjectSetAttr(char,'crushTestA',0)
def FFX_crushTest3a(event):
char=event.object
source=event.string
ffx.FFX_ObjectSetAttr(source,'crushTestA',0)
if ffx.FFX_ObjectGetAttr(char,'grappled',0)==0:
AI_Animate(source,'unlock')
AI_Animate(source,'melee_idle')
else:
AI_Animate(char,'pain')
def makegrappled(char,source):
if ffx.FFX_ObjectGetAttr(char,'grappled',0)==1:
return
pos1 = Get_ObjectPos(char)
pos2 = Get_ObjectPos(source)
ffx.FFX_ObjectSetAttr(char,'grappled',1)
ffx.FFX_ObjectSetAttr(source,'grappler',1)
ffx.FFX_ObjectSetAttr(char,'lastY',pos1[1])
ffx.FFX_ObjectSetAttr(char,'lastX',pos1[0])
ffx.FFX_ObjectSetAttr(source,'lastY',pos2[1])
ffx.FFX_ObjectSetAttr(source,'lastX',pos2[0])
ffx.FFX_ObjectSetAttr(source,'gLastHealth',Object_GetAttr(source,'health'))
grappleFX=ffx.getByTemplate(source,FFX_GRAPPLE_CUSTOM,1)
if grappleFX!='':
handle = Object_PlayEffect(char, grappleFX,'',FX_LOOP|FX_TRACK_OBJECT_FULL,0,'centre')
ffx.FFX_ObjectSetAttr(char,'grapple_handle',handle)
ffx.FFX_ObjectSetAttr(source,'grapple_duration',12)
AI_Animate(char,'pain')
hasPortrait=ffx.FFX_HasPortrait(char)
pcAIEnabled=m25ai.AIInWatch(char)
if pcAIEnabled or not hasPortrait:
m25ai.AIDisable(char)
ffx.RegTimer('grappleStart',0.4,0,char,source)
ffx.RegTimer('grappleLock',0.1,0,char,source)
ffx.RegTimer('grappleMoveCheck',0.2,0,source,char)
ffx.RegTimer('grappleEnergy',1,0,char,source)
def grappleCancel(event):
source=event.object
char=event.string
if ffx.FFX_ObjectGetAttr(source,'grappler',0)==0:
AI_Animate(source,'unlock')
AI_Animate(source,'melee_idle')
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
def grappleLock(event):
char=event.object
source=event.string
flailing=mlogreader.MLOG_IsFlailing(char)
flailingS=mlogreader.MLOG_IsFlailing(source)
if flailing:
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
mlogreader.regGetupStop(char,'grappleRecover',0,0,0)
if flailingS:
mlogreader.regGetupStop(source,'grappleRecover',0,0,0)
else:
ffx.RegTimer('grappleRecover',1,0,source)
return
if flailingS:
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
mlogreader.regGetupStop(source,'grappleRecover',0,0,0)
if flailing:
mlogreader.regGetupStop(char,'grappleRecover',0,0,0)
else:
ffx.RegTimer('grappleRecover',1,0,char)
return
if ffx.FFX_ObjectGetAttr(char,'grappled',0)==0:
if ffx.FFX_ObjectGetAttr(char,'grappleBreak',0)==0:
if Object_IsAlive(char)!=0:
Trigger_Force(char,0,0,1,Object_GetAttr(char,'mass')*100,TF_ABSOLUTE)
if ffx.FFX_ObjectGetAttr(char,'acrobatic',0)!=1:
mlogreader.regGetupStop(char,'grappleRecover',0,0,0)
else:
ffx.RegTimer('grappleRecover',1,0,char)
else:
ffx.RegTimer('grappleRecover',1,0,char)
ffx.RegTimer('grappleRecover',1,0,source)
return
if ffx.FFX_ObjectGetAttr(char,'grappled',0)==1:
AI_Animate(char,'pain')
ffx.RegTimer('grappleLock',0.3,0,char,source)
def grappleStart(event):
char=event.object
source=event.string
if ffx.FFX_ObjectGetAttr(char,'grappled',0)==0:
return
if grappleBreakCheck(char,source):
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
ffx.FFX_ObjectSetAttr(char,'grappleBreak',1)
handle=ffx.FFX_ObjectGetAttr(char,'grapple_handle')
Object_StopEffect(char,handle)
return
if Object_GetPrimaryState(char)==ffx.PCSTATE_EXILE:
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
return
grappledAgl=Object_GetAttr(char,'agility')-3
ffx.FFX_ObjectSetAttr(char,'baseAgility',Object_GetAttr(char,'agility'))
ffx.FFX_ObjectSetAttr(source,'baseAgility',Object_GetAttr(source,'agility'))
Object_SetAttr(char,'energy',0)
Object_SetAttr(source,'agility',grappledAgl)
Object_SetAttr(char,'agility',0)
grappleDmg(source,char)
ffx.RegTimer('grappleCheck',3,0,char,source)
def grappleMoveCheck(event):#checks grappler's and target's conditions (movement, damage, Primary State, KOed)
source = event.object
char = event.string
if ffx.FFX_ObjectGetAttr(char,'grappled',0)==0:
return
lasthealth=ffx.FFX_ObjectGetAttr(source,'gLastHealth')
health=Object_GetAttr(source,'health')
if health < lasthealth:
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
return
if (Object_GetPrimaryState(source)!=PCSTATE_NORMAL) | (Object_IsAlive(source)==0) | (ffx.FFX_ObjectGetAttr(source,'grappled',0)==1) | (ffx.FFX_ObjectGetAttr(source,'rangedgrappled',0)==1) | (ffx.FFX_ObjectGetAttr(source,'tangled',0)==1) | (ffx.FFX_ObjectGetAttr(source,'eTangled',0)==1) | (ffx.FFX_ObjectGetAttr(source,'thrownCharacter',0)==1):#if the grappler is koed, blanked, enraged, hexed, etc. cancel the grapple
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
return
if Object_GetPrimaryState(char)==ffx.PCSTATE_EXILE:
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
return
if (Object_IsAlive(char)==0):#if the target is koed, cancel the grapple
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
return
pos=Get_ObjectPos(source)
pos2=Get_ObjectPos(char)
dist=(pos[0]-ffx.FFX_ObjectGetAttr(source,'lastX'),pos[1]-ffx.FFX_ObjectGetAttr(source,'lastY'),0)
dist2=(pos2[0]-ffx.FFX_ObjectGetAttr(char,'lastX'),pos2[1]-ffx.FFX_ObjectGetAttr(char,'lastY'),0)
ffx.FFX_ObjectSetAttr(source,'lastY',pos[1])
ffx.FFX_ObjectSetAttr(source,'lastX',pos[0])
ffx.FFX_ObjectSetAttr(char,'lastY',pos2[1])
ffx.FFX_ObjectSetAttr(char,'lastX',pos2[0])
if (dist[0]*dist[0]+dist[1]*dist[1]) > 10:
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
return
elif (dist2[0]*dist2[0]+dist2[1]*dist2[1]) > 20:
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
return
ffx.FFX_ObjectSetAttr(source,'gLastHealth',health)
flailing=mlogreader.MLOG_IsFlailing(char)
myflailing=mlogreader.MLOG_IsFlailing(source)
if not flailing:
AI_Animate(char,'lock')
if not myflailing:
AI_Animate(source,'lock')
ffx.RegTimer('grappleMoveCheck',0.7,0,source,char)
def grappleBreakCheck(char,source):
#calculate the target's resistance based on the kind of grapple(physical, mental, mystical, cold or energy)
if ffx.FFX_ObjectGetAttr(char,'grappleMental',0)==1:
targetStr=ffx.getMentalResistanceValue(char, passive=0, active=0, attribs=1, states=1, material=1)
elif ffx.FFX_ObjectGetAttr(char,'grappleMystic',0)==1:
targetStr=ffx.getMysticalResistanceValue(char, passive=0, active=0, attribs=1, states=1, material=1)
elif ffx.FFX_ObjectGetAttr(char,'grappleEnergy',0)==1:
targetStr=ffx.getEnergyResistanceValue(char, passive=0, active=0, attribs=1, states=1, material=1)
else:
targetStr=Object_GetAttr(char,'strength')+1
if ffx.FFX_ObjectGetAttr(char,'grappleCold',0)!=1:
if ffx.hasAttribute(char,'wrestler'):
targetStr=ffx.FFX_ObjectGetAttr(char,'wrestler')
#calculate the grappler's hold strength (Strength Stat or Custom Value)
useStr=ffx.getByTemplate(source,FFX_GRAPPLE_CUSTOM,2)
if useStr=='Yes':
holdStr=Object_GetAttr(source,'strength')+1
if ffx.FFX_ObjectGetAttr(char,'grappleCold',0)!=1:
if ffx.hasAttribute(source,'wrestler'):
holdStr=ffx.FFX_ObjectGetAttr(source,'wrestler')
else:
holdStr=ffx.getByTemplate(source,FFX_GRAPPLE_CUSTOM,3)
#calculate the difference in the grappler's and target's strength
if ffx.FFX_ObjectGetAttr(char,'grapplePhysical',0)!=1:
if targetStr==1:
if holdStr < 7:
holdStr=holdStr+2
else:
holdStr=holdStr+1
if targetStr > 1:
holdStr=(holdStr*0.5)+1.5
if targetStr == 0.5:
holdStr=holdStr*1.5
if targetStr == 0.25:
holdStr=holdStr*2.5
chance=holdStr*targetStr
else:
if targetStr>holdStr:
targetStr=targetStr+1
strDiff=targetStr-holdStr
chance=5-strDiff
if targetStr==holdStr:
chance=6
if holdStr>targetStr:
targetStr=targetStr-1
strDiff=holdStr-targetStr
chance=5+strDiff
#calculate the chance to break free
breakFree=randint(1,10)
if breakFree > chance:
return 1
else:
return 0
def grappleDmg(source,char):
#apply damage if hold is successful
if ffx.FFX_ObjectGetAttr(char,'grappleMental',0)==1:
targetStr=ffx.getMentalResistanceValue(char, passive=0, active=0, attribs=1, states=1, material=1)
elif ffx.FFX_ObjectGetAttr(char,'grappleMystic',0)==1:
targetStr=ffx.getMysticalResistanceValue(char, passive=0, active=0, attribs=1, states=1, material=1)
elif ffx.FFX_ObjectGetAttr(char,'grappleEnergy',0)==1:
targetStr=ffx.getEnergyResistanceValue(char, passive=0, active=0, attribs=1, states=1, material=1)
useStr=ffx.getByTemplate(source,FFX_GRAPPLE_CUSTOM,2)
grappleDmg=ffx.getByTemplate(source,FFX_GRAPPLE_CUSTOM,4)
if grappleDmg=='Yes':
if useStr=='Yes':
grappleDmg=Object_GetAttr(source,'strength')+1
else:
grappleDmg=ffx.getByTemplate(source,FFX_GRAPPLE_CUSTOM,3)
else:
grappleDmg=0
if grappleDmg > 0:
baseDmg=grappleDmg*2
if ffx.FFX_ObjectGetAttr(char,'grapplePhysical',0)!=1:
damage=baseDmg*targetStr
else:
if ffx.FFX_ObjectGetAttr(char,'grappleCold',0)==1:
targetStr=ffx.getColdResistanceValue(char,passive=0,active=0,attribs=1,states=1,material=1)
else:
targetStr=ffx.getCrushResistanceValue(char,passive=0,active=0,attribs=1,states=1,material=1)
damage=baseDmg*targetStr
if damage < 1:
damage=1
if (ffx.FFX_ObjectGetAttr(char,'grappleMental')==1) | (ffx.FFX_ObjectGetAttr(char,'grappleMystic')==1):
ffx.FFX_ApplyDamage(char,damage,mental=1)
else:
if damage > 0:
ffx.FFX_ApplyDamage(char,damage,mental=0)
def grappleCheck(event):
char=event.object
source=event.string
if ffx.FFX_ObjectGetAttr(char,'grappled',0)==0:
return
duration=ffx.FFX_ObjectGetAttr(source,'grapple_duration')-3
if duration<=0:
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
return
if Object_GetPrimaryState(char)!=PCSTATE_NORMAL:
ffx.FFX_ObjectSetAttr(source,'grapple_duration',duration)
ffx.RegTimer('grappleCheck',3,0,char,source)
return
if grappleBreakCheck(char,source):
ffx.FFX_ObjectSetAttr(char,'grappled',0)
ffx.FFX_ObjectSetAttr(source,'grappler',0)
ffx.FFX_ObjectSetAttr(char,'grappleBreak',1)
return
ffx.FFX_ObjectSetAttr(source,'grapple_duration',duration)
grappleDmg(source,char)
ffx.RegTimer('grappleCheck',3,0,char,source)
def grappleRecover(event):
char=event.object
if Object_IsAlive(char)==0:
return
flailing=mlogreader.MLOG_IsFlailing(char)
if flailing:
mlogreader.regGetupStop(char,'grappleRecover',0,0,0)
return
agility=ffx.FFX_ObjectGetAttr(char,'baseAgility')
Object_SetAttr(char,'agility',agility)
baseEnergy=ffx.FFX_ObjectGetAttr(char,'baseEnergy')
energy=Object_GetAttr(char,'energy')
if baseEnergy!=energy:
Object_SetAttr(char,'energy',baseEnergy)
AI_Animate(char,'unlock')
hasPortrait=ffx.FFX_HasPortrait(char)
pcAIEnabled=m25ai.AIInWatch(char)
if pcAIEnabled or not hasPortrait:
m25ai.ClearAIStandardOnly(char)
m25ai.AIEnable(char)
m25ai.AIEnableCustom(char)
m25ai.SetBrawler(char)
m25event.SetTimer(1.0, 'm25ai.AIRecoverBroken', char, user=m25ai.GetAITimeStamp(char))
if ffx.FFX_ObjectGetAttr(char,'grappleBreak',0)==1:
if ffx.FFX_ObjectGetAttr(char,'grappleMystic',0)==1:
AI_Animate(char,'recover_from_stun')
elif ffx.FFX_ObjectGetAttr(char,'grappleMental',0)==1:
AI_Animate(char,'recover_from_stun')
else:
AI_Animate(char,'swing_pole')
ffx.FFX_ObjectSetAttr(char,'grappleBreak',0)
else:
AI_Animate(char,'melee_idle')
handle=ffx.FFX_ObjectGetAttr(char,'grapple_handle')
Object_StopEffect(char,handle)
ffx.FFX_ObjectSetAttr(char,'grappleMental',0)
ffx.FFX_ObjectSetAttr(char,'grappleMystic',0)
ffx.FFX_ObjectSetAttr(char,'grappleCold',0)
ffx.FFX_ObjectSetAttr(char,'grappleEnergy',0)
ffx.FFX_ObjectSetAttr(char,'grapplePhysical',0)
ffx.RegTimer('grappleRecover2a',1,0,char)
def grappleRecover2a(event):
char=event.object
if Object_IsAlive(char)==0:
return
pos=Get_ObjectPos(char)
ffx.FFX_ObjectSetAttr(char,'lastY',pos[1])
ffx.FFX_ObjectSetAttr(char,'lastX',pos[0])
ffx.RegTimer('grappleRecover2b',5,0,char)
def grappleRecover2b(event):
char=event.object
if Object_IsAlive(char)==0:
return
flailing=mlogreader.MLOG_IsFlailing(char)
getup=mlogreader.MLOG_IsGettingUp(char)
pos=Get_ObjectPos(char)
dist=(pos[0]-ffx.FFX_ObjectGetAttr(char,'lastX'),pos[1]-ffx.FFX_ObjectGetAttr(char,'lastY'),0)
ffx.FFX_ObjectSetAttr(char,'lastY',pos[1])
ffx.FFX_ObjectSetAttr(char,'lastX',pos[0])
if ffx.FFX_ObjectGetAttr(char,'grappled',0)==1:
return
if ffx.FFX_ObjectGetAttr(char,'grappler',0)==1:
return
if flailing:
mlogreader.regGetupStop(char,'grappleRecover2b',0,0,0)
return
if getup:
mlogreader.regGetupStop(char,'grappleRecover2b',0,0,0)
return
if (dist[0]*dist[0]+dist[1]*dist[1]) > 10:
return
if not m25ai.IsPerformingTactic(char):
AI_Animate(char,'unlock')
hasPortrait=ffx.FFX_HasPortrait(char)
pcAIEnabled=m25ai.AIInWatch(char)
if pcAIEnabled or not hasPortrait:
m25ai.ClearAIStandardOnly(char)
m25ai.AIEnable(char)
m25ai.AIEnableCustom(char)
m25ai.SetBrawler(char)
m25event.SetTimer(1.0, 'm25ai.AIRecoverBroken', char, user=m25ai.GetAITimeStamp(char))
ffx.RegTimer('grappleRecover2b',5,0,char)
Oh my goodness. Didn't expect the codes to be that long. I was expecting a code like ClingToWall or something. But thanks nonetheless. I'll tinker with it.
Oh you do use if, else and relative pos. commands then? Side note if I ever want to learn the coding for this game (likely not but you never know) I'll make sure to go to oktokels for that.
Of course, I did edit the old flying melee. But without any success.
Quote from: SickAlice on August 28, 2022, 05:54:05 PM
Side note if I ever want to learn the coding for this game (likely not but you never know) I'll make sure to go to oktokels for that.
Can't help you that much there, since I'm a begginer too. The ffx code is still unreadable for me, for the most part. It was relatively easy to find the parts requested by miraitto, though, since everything is structured like chapters in a book.
I'm less of a beginner and you actually have the basics down. Like I said I abandoned coding a long time ago. Much of what I'm looking is still familiar though. Looks like anything I used to do for 2d platformers.