Documentation for ffx.py

Major Warning: This draft documentation was generated from the comments in the source code (using progrutils.documentPyFile()), under the principle that poor documentation is better than no documentation. The only intervention was done to remove code specific to attributes (and yes, the code structure itself is as messy as that :P ). In case of ambiguity, please refer to the code itself.

 


Main FFX code

By Dr Mike 2000
with contributions from C4, CatWhoWalksByHimself, Épiméthée, Kuertee, M25, Shazam, Stumpy, SouperIan and TaskMasterX

 

CONFIGURATION SECTION ########################################




FFX_ABSORBRANGE=5

the range at which various powers kick in

FFX_MIMICRANGE=5

FFX_DRAINRANGE=30

FFX_SHIELDRANGE=30

FFX_EP_SHAPESHIFT=33

EP costs for certain activities

FFX_EP_MIMIC=33

FFX_EP_EXPLODE=33

FFX_EP_LIVINGLASER=33

FFX_EP_GAS=33

FFX_EP_SPIN=33

FFX_EP_ICE=33

FFX_EP_SAND=33

FFX_EP_ABSORB=33

FFX_EP_SCAN=33

FFX_EP_PEACEFIELD=33

FFX_EP_LIFTTK=33

FFX_EP_THROWTK=33

FFX_EP_MOVETK=0

FFX_EP_THROWMAG=33

FFX_EP_EARTHWALL=33

FFX_EP_EARTHSPIKE=33

FFX_EP_ANIMATE=33

FFX_EP_SUSTAIN=0

FFX_EP_MINDSHIELD=33

FFX_EP_PHYSICALSHIELD=66

FFX_RPG_DEPRESSED_CHANCE=5

strength/chance of effects

FFX_PRESENCE_CHANCE=5

FFX_JINX_CHANCE_JAM=10

FFX_JINX_CHANCE_SLIP=10

FFX_PHEREMONE_CHANCE=10

FFX_MAGNET_FORCE=30000

FFX_SCARY_CHANCE=10

CONSTANTS ################################################################

OC_GENERIC=0x400000

not included in FF API, but makes code more readable
Ep. 2006-08-22: made accessible without doing a from ffx import * or prefixing with the ffx. module; added PCSTATE_DEAD; regrouped

js.OC_GENERIC=OC_GENERIC

OC_STANDALONEHERO=0x800 #heroes have this class and the OC_CONTROLLABLE one; however heroes' lures have only OC_STANDALONEHERO (enemies' lures have OC_MINION instead)- Ep. 2006-07-18

js.OC_STANDALONEHERO=OC_STANDALONEHERO

OC_VILLAIN=OC_VILLIAN

js.OC_VILLAIN=OC_VILLAIN

PCSTATE_DEAD=1

js.PCSTATE_DEAD=PCSTATE_DEAD

PCSTATE_EXILE=3 #js.PCSTATE_DIMENSION_SHIFT in FFvsTTR

js.PCSTATE_EXILE=PCSTATE_EXILE

EVENT_POWER_HIT=21

js.EVENT_POWER_HIT=EVENT_POWER_HIT

FFX_CHARACTER=OC_CHARACTER

heroes with AI_DestroyAI applied DONT flag as OC_CHARACTER! using this fixes it!

FFX_POWER_CUSTOM=1073741824

some weird numbers used by the FF engine... (FWIW, this number is also hex 0x40000000 or octal 010000000000 -Ep. 2006-06-15.)

builtinPowerIDs=(536870912,536870944,536870976,536871008,536871040,536871072,536871104,536871136,536871168,536871200)

FFX_GENDER_UNKNOWN=-1

gender

FFX_GENDER_OPPOSITE=0

FFX_GENDER_MALE=1

FFX_GENDER_FEMALE=2

FFX_GENDER_ANIMAL=3

FFX_GENDER_ROBOT=4

FFX_GENDER_ALIEN=5

FFX_GENDER_GOOD=0

FFX_GENDER_EVIL=32

SCSTATE_CRYSTALLISED=65536

FFX secondary states

SCSTATE_SHRUNK=32768

SCSTATE_VERTIGO=16384

SCSTATE_TRANSMUTED=8192

SCSTATE_CAGED=4096

SCSTATE_REINFORCED=2048

SCSTATE_DENSITY=65536

ffxAttribsBase=[]

collection of 'fake' attributes forced by script

ffxAttribs=[]

ffxMeshes=[]

templates=[]

charTemplates=[]

throwObjects=[]

FFX_STATE_GAS=1

FFX_STATE_SAND=2

FFX_STATE_ICE=3

FFX_STATE_SPIN=4

FFX_STATE_ENERGYSHIELD=5

FFX_STATE_SHRUNK=6

FFX_STATE_TRANSMUTED=7

FFX_STATE_PUPPET=800

FFX_STATE_UNINITIALISED=100

FFX_GENDER_GOOD=0

FFX_GENDER_EVIL=32

materialNames = ['flesh',

materials
- Material 11 is neutral and weights the same as flesh (FFvsTTR's other neutral material), hence the repetition of "flesh" here.
- Dark Matter (material 12): hidden material:
- defenseless against crushing, piercing, energy, fire, radiation, electricity, acid and cold
- weak against mental and mystical
- Ectoplasm (material 13): hidden material:
- defenseless against crushing, piercing, energy, electricity and acid
- weak against mental and mystical
- normal against fire, radiation and cold
- Setting Object_SetAttr(char, 'material' x) to a value above 13 tends (?)
to make the character completely immune to these two damage types.

materialFactors=(1.0, #flesh # flesh/neutral is both 0 and 11

 

INITIALISATION AND SYSTEM ###############################################################


isMP()

Mission_SetAttr("FFX_RULES_WHOAMI",FFX_RULES_WHOAMI)
Global_RegisterAttr('team',0) # Ep. 2006-07-21: Obsolete; to be removed
Global_RegisterAttr('brawler',0) # Ep. 2006-08-28: Obsolete; to be removed




SPECIAL OBJECT INITIALISATION ########################################


FFX_OnUseSwitch(target,char)


AddWeaponCommands(char)

weapons:

RemoveWeaponCommands(char)

getWeaponData(template)

addWeaponPowers(weapon,char,update)

removeWeaponPowers(weapon,char)

FFX_OnDropEvent(event)

FFX_OnDropWeapon(target,char)

FFX_OnUseWeapon(target,char)

called when the user picks up a weapon

targetWeapon(event)

OnUseWeapon(target,char,weapon,power='',ammocost=1)

ammoText(ammo)

FFX_OnUseTP(target,char)

INITIALISATION AND UPDATE OF ALL ATTRIBUTES ##########################

hasAttribute(char, attrib, ffxOnly=0)

changed for character-specific attributes such as Latent Mutant
Ep 2006-07-17:
- added detection of built-in attributes; to disable, set ffxOnly=1
- Note that the built-in "fast healing" (for example) and the scripted "fasthealing" aren't considered as one attribute to keep
overhead low, since the attribute is used constantly in the FFX update loops.
Ep. 2006-08-19
- An attribute used to be set for the whole template in parseLogFile; it's now set here at the character level only.
Consequently, the templateOnly parameter has been removed.
Ep. 2006-09-10: Added check to prevent error on non-characters.
For other attribute-related functions, see the CHARACTER ATTRIBUTES MANIPULATION section under FFQ.

 


CHARACTER INITIALISATION


usingM25AI()

FFX_GetTemplate(char, verbose=0)

FFX_GetTemplateMP(char)

def FFX_GetTemplate(char, verbose=0):
if complex>2000:
return ffxSaved[complex-2001][0]

strips off '_mp' at the end

testtemp(char)

storeTemplate(char)

given a name returns a unique integer ID

retrieveTemplate(id)

given an ID form store template, returns the original template name

customTemplates=[]

if complex>2000:
return ffxSaved[complex-2001][0]

makeTemplateForCustom(name)


FFX_Animate(char,anim)

isReal(char)


CLONE COMMAND STUFF ####################################################

if Object_GetPrimaryState(obj)==15:
Object_SetAttr(obj,'health',0)

getPoliceClones(char)

OnCloneTarget(target,char)

OnCloneGather(dummy,char)

SPECIAL CHARACTER STATE CODE ###########################################

FFX_UpdateStates(char)

FFX_GotState(char,state,override=0)

densityaltered(char)

mpFrom=["stun","hypnosis","rage","blind",

mpTo=["crystallise","magnetise","vertigo","firecage","shrink","transmute","gravityincrease","gravityreverse","pull","lifedrain",

 

#############################

COST_EMPATHY=1

COST_CLOAK=4

COST_DISPLACE=3

stateintensity=[COST_EMPATHY,COST_CLOAK,COST_DISPLACE]

relative costs for special powers that trigger an event:
empathy, cloak, displace in that order

COST_HYPNO=10

based on the cost of swappable state attacks ---

mental attacks

COST_RAGE=3.833

COST_BLANK=3.333

COST_PANIC=1

COST_NULL=1

COST_WEAKEN=0.333

COST_STASIS=2.2

mystical attacks

COST_BLIND=1.667

COST_HEX=1

COST_EXILE=0.667

COST_FREEZE=1.333 #cold

other

COST_DENSITY=0.667 #energy

COST_DECREASE=0.3333 #piercing

COST_STUN=1.5

stun carriers - now rarer and more costly than in FF1

COST_RALLY=1.75

non-resistable

COST_ENERGYSURGE=1

COST_INCREASE=0.833

 

isGiant(char)

 

PSYCHIC DAMAGE ###################################

makementaldamaged(char,intensity)

HYPNO: 24-36
NORMAL: 8-24
WEAK: 6-20
STUN: 4-16

ORIGINAL ABSORBER ##############################################################



FFX_ABSORBMAT=[

 

onAbsorbEvent(event)

GetAbsorbMaterial(target)

put overrides in here for more interesting stuff than just metal/stone all the time

MIMIC ###################################

 

makemimic(char,source,intensity)

 

getTransmute(char,target)

template=getTransmute(source,char)
if Object_GetPrimaryState(char)!=PCSTATE_EXILE:
Object_SetPrimaryState(char,PCSTATE_EXILE,4*intensity,0)

getTransmutedionysian(target)

special function for pan's transmutations

 

magnetise #############################

 

metals=[]

getMetals()

 

LIMEYLURE SWAPS ################################

getLure()

 

FFX_DestroyPortrait(name)

removes the portrait but keeps the character ticking as a real live AI

FFX_AdjustPortrait(char,port)

FFX_AddPortrait(name)

FFX_HasPortrait(name)

returns if they have a portrait or not


FFX_SetStrength(char,value,lifting=1)

FFX_SetMassFactor(char,factor)

RegTimer('keepRallied',1,0,char)

RegExtraKB(char)

KBUpdate(event)

print 'setting extra knockback up'

EXTRA_KB_SCALE=10000

OnKBDamage(event)

OnKBDamageOff(event)

OnKB(event)

FFX_ScaleMass(char,scale,duration)

FFX_RestoreMass(event)

FFX_Rand(min,max)



FFX_ApplyDamage(char,damage,mental=0)

FFX_SetDamageAttrs(char,hp)

FFX_FactorHealth(char,factor)

FFX_SetEnergy(char,value)

FFX_GetSpeed(char)


updateStates(event)

setFFXState(char,state)

GENDER DETERMINATION ####################################

getGender(char)

setGender(char,force=0)


given a character's template, find their entry (if any) in customisation array


getByTemplate(char,array,index,isTemplate=0)

getRowByTemplate(char,array)

getTemplateFromRealName(name)

FIND THE TEMPLATES OF ALL PROP OBJECTS ##################################

FFX_TOO_HEAVY=10000000

the tuples stored in here are template, mass and material
if the object isnt throwable, mass gets listed as :

fillTemplateList(): # stumpy 2006-08-26: removed Object_Exists(obj) tes



UPDATE #############################################################



GetAllHeroes()

OnDie(event)

HERO (and non-HERO!) MORPHING ######################################################

getFormName()

makeAttrSafe(char)

new FFvTTR compatrible morph function #################################

name - object name for new form

char - object name of old form
template - template to morph into
proprotional - whether to scale or retain maximum Health
hasPortrait - true if triggered from a custom command, ie the character is controllable

morph(name,char,template,proportional=0,hasPortrait=1)

execTimer(event)

morph2(name,char,template,proportional,hasPortrait)

getMorphFX(char)

getDummyName()


getLastDummyName()

SPECIFIC ATTRIBUTES ################################################

SHAPESHIFTER #######################################################

 

OnForm1(char,dummy)

OnForm2(char,dummy)

OnForm3(char,dummy)

OnForm4(char,dummy)

OnForm5(char,dummy)

OnForm6(char,dummy)

OnChange(char,index)

OnNPCChange(char,template)

forceRevertCheck(event)

OnRevertFromTemp(dummy,char,forced=0)

awaken(char)

FFX_TemplateExists(template)

 

MIMIC ##############################################################

OnMimic(target,char)

OnRevert(char,dummy)

NPCMimic(target,char)

###########################################

 

GetClosestChar2D(obj)

if hasAttribute(char,'butterfingers'):

DISPERSED FORM ############################################

 

bodyPart=('Bip01 Head','Bip01 L Forearm','Bip01 R Forearm','Bip01 L Calf','Bip01 R Calf')

 

RestoreSStates(char,states)

Ep. 2006-07-22: Updated forFFvsTTR new states... Oops - the function was not used at all anyway.

 

#####################################################

 

RegCharState(character, state, fn, persistent = 0, user=0, string='')

Ep. 2006-07-17: added string parameter

########################################

 

restoreSun()

 

powerscan ######################################

 

HUD=[]

OnScanPowers(target,char)

displayHUD(event)

GetCharHUD(char)

attrDesc=[

GetAttrString(att)

powertypes=['','fighting','ranged','explosion','direct','shield','resistance','special']

stumpy 2006-12-30: changed types to powertypes to avoid having a global with the same name as the module types.

subtypes=['','beam','bolts','bomb','cone']

damages=['concussive','piercing','energy','flame','radiation','electrical','acidic','cold','water',

spectypes=['','random','energy-transferring','energy-leeching','','dimension-shifting','molecular-excitation',

pstest()

carriersFrom=[

carriersTo=[

mods=[

GetPowerString(power,char)

 

METABOLIC STRENGTH ####################################

 

bonusStrength(char,bonus)

bonusPower(char,bonus)

bonusSpeed(char,bonus)

bonusAgility(char,bonus)

bonusSpeedAndAgility(char,bonus)

bonusSpeedAndStrength(char,bonus)

bonusEnergy(char,bonus)

bonusEnergyRelease(char,bonus)

bonusAttr(char,bonus,attr)

bonusFX(char,bonus,array,node='')

bonusEnergized(char, bonus)

!Ep 2006-02-05

bonusSuperNocturnal(char,bonus)

!Ep 2006-02-05
Code developped for Apfarmakis - not available through the Control Center; left only as reference for eventual further developments
for use with Dr Mike's Nocturnal attribute
increases strength, health, invulnerability and energy

 

FFX_Unlock(event)

tries to prevent a character from being frozen in a specific animation after using AI_Animate()

###############################

 

FFX_MultiplyAttr(char,attr,factor,stat=0)

 

PLASMA SCULPTOR ########################################

 

GetSpawnPos(target,char,dist=30)

OBJECT CREATION SCHEMES #########################

 

independent(obj,char,cost)

summoned and then free of their own accord

independentCheck(event)

creationDestroy(obj)

SUMMONER ########################################

 

isEvil(char)

initMinionAI(name,team,target='',evil=1)

PRIVATE ARMY ########################################

 

OnSelectArmy(name,char): # stumpy adde

OnTargetArmy(target,char)

OnTargetArmySelected(target,char)

OnPATargetDeath(event)

Clean up PA AI goals if target is KOed. Only called for M25_USE_AI set.

OnGatherArmy(dummy,char)

OnHaltArmy(dummy,char)

OnEnableArmy(dummy,char)

getArmyName(char,index)

getArmyPos(char,index)

####################################

SprintDist(char)

 

 

#############################################

 

GetHeroCount()

 

permaStun(event)

 

FEEDBACK #######################################

 

isMinuteUp(obj,char='')

Ep 2006-09-06 made less verbose

isRandomTimeUp(obj,char='')

Ep 2006-02-05 isMinupeUp() variant on request of apfarmakis

isNever(obj,char='')

isBuilding(obj,char='')

Ep 2006-02-05 Added check for the object existence to the is..() functions below
Kuertee 2006-07-30 added default empty string to char os that these checks don't error when only 1 parameter is sent

isCivilianFB(obj,char='')

isStunned(obj,char='')

isBlank(obj,char='')

isHypnotised(obj,char='')

isPanicked(obj,char='')

isEnraged(obj,char='')

isMindControlled(obj,char='')

isStatic(obj,char='')

isFrozen(obj,char='')

isExiled(obj,char='')

isEnergised(obj,char='')

isIrradiated(obj,char='')

isAcidBurnt(obj,char='')

isPowerNulled(obj,char='')

isHexed(obj,char='')

isBlind(obj,char='')

isOutOfEnergy(obj,char='')

isAtFullEnergy(obj,char='')

isLowOnHealth(obj,char='')

isStone(obj,char='')

isMetal(obj,char='')

isRubber(obj,char='')

isFire(obj,char='')

isEnergy(obj,char='')

isWood(obj,char='')

isIce(obj,char='')

isCloneOf(obj,char='')

isSameMaterial(obj,char='')

isAlienMineral(obj,char='')

isZombie(obj,char='')

isTechnoOrganic(obj,char='')

isNight(obj, char='')

Ep. 2006-09-05

isDay(obj, char='')

Ep. 2006-09-05

isElectricalGrid(obj,char='')

other is...() secondary state functions available under FFQ object identification helpers section

electricalSources=(): moved to ffxextras.py

isNotSpeedster(obj,char='')

isEarlierVersionOf(obj,char='')

Kuertee 2006-07-30 - added "if char != '' and..." so that it doesn't return error when only 1 parameter is sent
stumpy 2007-01-10: added check that health is half that of tested object, so that we only compare with the original.

isCharacter(obj,char='')

isSentient(obj,char='')

Ep. 2006-08-28: changed name from isAlive() to avoid confusion
as this functiondoesn't detect if the object is currently alive;
what it detects is if the object is a living entity (vs. a prop or a dumb machine)

isMachine(obj,char='')

isGoodOrEvil(obj,char='')

isEnergyX(obj,char='')

isEnergyXFeedback(obj,char='')

isMagic(obj,char='')

see the magicBeings customization tuple in ffxextras.py

isMagicOverwhelm(obj,char='')

isNazi(obj,char='')

see the nazis customization tuple in ffxextras.py

isEnemy(obj,char='')

isSymbiote(obj,char='')

Ep 2006-02-05 Symbiote/Parasite customisation additions
returns 1 only if the object has the symbiote attribute and if both the object and the char are the same subtype of symbiote

isParasite(obj,char='')

returns 1 only if the object has the parasite attribute and if both the object and the char are the same subtype of parasite

drawHealth(char,targets,array)

drawEnergy(char,targets,array)

leechHealth(char,targets,array)

leechEnergy(char,targets,array)

drawAttr(char,targets,array,attr,maxAttr,maxRate=1,leeching=0)

gainStrength(char,targets,array)

gainStrengthSU(char,targets,array)

gainInvulnerability(char,targets,array)

gainMass(char,targets,array)

gainAgility(char,targets,array,scale=1)

gainSpeed(char,targets,array,scale=1)

leechEnergyAgilAndSpeed(char,targets,array)

gainMassAndStrength(char,targets,array)

gainStrengthAndInvulnerability(char,targets,array)

gainDamageAura(char,targets,array)

gainStateEnergized(char,targets,array)

!Ep 2006-02-05 used by FFX_SYMBIOTE_CUSTOM

playSynergyFX(char,array)

restoreSynFX(event)

playSynergyFXonTargets(char,targets,array)

restoreSynFX2(event)

antiSpeedAura(char,targets,array)

unpleasant states for vulnerability and dependence ############

loseStrength(char,targets,array,flip=0)

loseInvulnerability(char,targets,array,flip=0)

loseFlightAndSpeed(char,targets,array,flip=0)

losePower(char,targets,array,flip=0)

getWeakened(char,targets,array,flip=0)

getHexed(char,targets,array,flip=0)

getBlind(char,targets,array,flip=0)

loseHealth(char,targets,array,flip=0)

loseEnergy(char,targets,array,flip=0)

theWorks(char,targets,array,flip=0)

loseSanity(char,targets,array,flip=0)

smallStunChance(char,targets,array,flip=0)

getVDPower(targets,flip)

 

 

LIBRARY CODE FOR SCIENTIST etc. ########################

initscientist(char,update=0)

Characters with the attributes in the specialAttribs tuple will have custom commands on special objects
Default is specialAttribs=('scientist','finetk','magnetic','telepathy')
Cf. ffxcustoms.py.

initfinetk(char,update=0)

addAnalyseCommand(target,command='ANALYZE')

removeAnalyseCommand(target,command='ANALYZE')

addManipulateCommand(target,command='MANIPULATE')

removeManipulateCommand(target,command='MANIPULATE')

addMagneticCommand(target,command='SPARK')

removeMagneticCommand(target,command='SPARK')

addSensoryCommand(target,command='SCAN')

removeSensoryCommand(target,command='SCAN')

cmdAttribCheck(event)

getRangeFromString(cmd)

 

##############################################

 

usePower1(target,char)

miracle functions:

usePowerX21(target,char)

usePowerX41(target,char)

usePower2(target,char)

usePowerX22(target,char)

usePowerX42(target,char)

usePower3(target,char)

usePowerX23(target,char)

usePowerX43(target,char)

usePower4(target,char)

usePowerX24(target,char)

usePowerX44(target,char)

usePower5(target,char)

usePowerX25(target,char)

usePowerX45(target,char)

summonAlly1(target,char)

summonAlly2(target,char)

summonAlly(target,char,index)

summonAllyA(event)

boostStrength3(dummy,char)

boostStrength4(dummy,char)

boostStrength5(dummy,char)

boostStrength(dummy,char,index)

unboostStrength(event)

unboostStrength2(event)

restore the command to boost strength (or become unstoppable) again

unstoppable3(dummy,char)

unstoppable4(dummy,char)

unstoppable5(dummy,char)

unstop(dummy,char,index)

ununstop(event)

getHeroPoint503(dummy,char)

gives a character 50% chance of getting an additional hero point once, up to a max of 4 hero points.
added Ep FFX 3.2 alpha 2006-04-27; updated 2006-09-17

getHeroPoint504(dummy,char)

getHeroPoint505(dummy,char)

getHeroPoint50(dummy,char,index)

useHeroPoint(event)

side effects
event.object is the character
event.user is the power index (1 to 5)

zapEnergy(event)

unzapEnergy(event)

zapStrength(event)

zapSpeed(event)

unzapSpeed(event)

takeDamage(event)

takeDamage50(event)

faint10(event)

halfHealth(event)

irradiate50(event)

hex50(event)

makeBlindAndPowerNulled(event)

!Ep 2006-02-05 default state for Speed Force

zapEnergyAndStrength(event)

zapEnergyAndSpeed(event)

zapSpeedAndStrength(event)

PLUGGABLE FUNCTIONS FOR PAIN RESPONSE/LAST RESORT ##################

findEnemy(char)

m25_Disable(char)

lastShot(char,param,intensity)

fires off a last shot

strengthThroughPain(char,param,intensity)

increases strength as damage is taken

decayStrength(event)

energyThroughPain(char,param,intensity)

spawnAllies(char,param,intensity)

spawns a nearby creature on death or in response to damage

spawnallies2(event)

circlepos=((0,10),(0.7,0.7),(10,0),(0.7,-0.7),(0,-10),(-0.7,-0.7),(-10,0),(-0.7,0.7))

spawnBombs(char,param,intensity)

throwBomb(event)

detonateBomb(event)

m25_Enable(event)

randomResponse(char,param,intensity)

createLightningStorm(char,param,intensity)

createHailStorm(char,param,intensity)

createFireStorm(char,param,intensity)

evasiveTeleport(char)

Ep 2006-0-07: teleport multiple times around your initial position, making you harder to hit
Note that this stops previous movement requests.

OnEvasiveTeleport(event)

 

GENERAL UTILITY FUNCTIONS #########################

distanceSq(object1,object2)

distanceSqMO(object1,object2)

fallOver(char,intensity=1)

restoreBalance(event)

chargeEP(char,cost)


deals with hidden heroes in mid shapeshift


getHiddenHeroes()

addHider()

delHider()

Mission_StatusText('hiders=%d'%(Mission_GetAttr('hiders')))

Mission_StatusText('hiders=%d'%(Mission_GetAttr('hiders')))


safe set/get attr functions


FFX_ObjectSetAttr(char,name,value)

FFX_ObjectGetAttr(char,name,default=0)

FFX_TemplateSetAttr(char,name,value)

FFX_TemplateGetAttr(char,name,default=0)

FFX_SetPos(name,pos)

FFX_GetPos(name)


utilities for adding and removing commands to all objects for simulated attack powers


addCommand(command,char,fn,range,update=0)

removeCommand(command,char)

print 'adding command %s to %s'%(command,char)

addCommandChars(command,char,fn,range,update=0,exclude='')

print 'removing command %s from %s'%(command,char)

removeCommandChars(command,char)

print 'adding command %s to %s'%(command,char)

FFX_GetObjects(mask,update)

print 'removing character command %s from %s'%(command,char)

regPowerAgainstChars(char,fn,powerID,update=0)

reg 21 against all characters who havent been done so far

stumpy 2007-01-02: we need to clear the FFX attrib for character
objects when they are destroyed so that they will be re-registered
if the same names are used for another spawned character. We ay do
that sort of re-using of object names in FFX and some campaign
missions definitely do it (e.g. the wraiths and subterrestrials in
the main campaign). (This may also be necessary for non-character
objects, but I am holding off on that to keep regObjectDestroy sinks
low.)

clearCarrierRegistration(event)


get layout prop objects by template


getObjectsByTemplate(template)

Ep. 2006-08-23: Changed to use FFvsTTR's Mission_GetObjects()


get all heroes at start of game and restore using campaign stuff


getBuiltinHeroes()

Note that much of this section is obsolete

Ep. 2006-08-23: Added to replace the hard-coded ffxextras.builtinHeroes tuple
Returns a list of characters in objects.dat with the GAME_OBJ_HERO class.

getHeroID(char)

returns 1 for first hero above, 2 for second etc.
or custom template number for custom recruits

getOriginalTemplate(char)

gets the template which this character started the mission with

getTemplateFromID(id)

takes number above and turns it back into a template

storeHeroes()

addExtraHeroToList(char,index=6)

originalHeroes()


solves the following problems -

hero may be pickled by explosive/laser
hero may be in form_X after shapeshifting/mimicking
STRANGERS SPECIFIC - hero may be penny/alculbus separated

restoreHeroes(event)

removeRings(event)


places custom recruits in base cutscenes at 'custom_1','custom_2', etc.


evTest(id,ofilter='',efilter=0,user=0)

OnInfo(event)

 


MESH MANIPULATION


makeMimicSkin(template)


REPLACEMENT REG- FUNCTIONS FOR CONVENIENCE (NOTE CAPITALISATION)


RegDeath(object, fn, user = 0, string = '', persistent = 0): ###! added string method and persistence (because FFvsTTR resurrection) - Ep. 2006-07-0

RegTimer(fn, time, user = 0, thing1='', thing2='', persistent = 0)

ALERT! DIFFERENT ORDER OF VARIABLES FROM regTimer!

see also RegTimer2 under the STUMPY HELPERS section toward the end of this file ###!

RegAlmostDead(char, fn, health = 1, user = 0, string = '', persistent = 0)

RegPickup(object, fn, character = '', user = 0)

RegDamage(object, fn, user = 0, persistent = 0, string = ''): ###! added string method (pushed back at the end for compatibility

RegShieldDamage(character, fn, user = 0, persistent = 0)

RegPowerUse(character, power, fn, persistent = 0, user = 0)

RegMove(char,fn='OnInfo',filter='',ifilter=0)

This doesn't register the start of a movement, but rather its end
Special movements like speeding bullet don't register.

RegPowerHit(character,target,fn,powerID,user=1,persistent=1)

the mysterious reg-21 triggers when the power specified is used by character on target

destroyTemp(event)

used everywhere for destroying temporary objects

killTemp(event)

used everywhere for destroying temporary objects


SUNLIGHT CODE


FFX_Sun(a1,a2,ambient,direct,color,cosmetic=0)

FFX_UpdateSun(event)

getLightLevels()

MULTIPLAYER MESSAGE SYSTEM #######################################################

MP_CRYSTALLISE=1

MP_VERTIGO=2

MP_GRAVITYINCREASE=3

MP_TELEPORTOTHER=4

MP_TRANSMUTE=5

MP_LIFEDRAIN=6

MP_SHRINK=7

MP_FIRECAGE=8

MP_MAGNETISE=9

MP_SHIELD=10

MP_NORMALISE=11

MP_ACCELERATE=12

MP_LEADERSHIP=20

!

MP_BREACH=21

MP_ROQUE=22

MP_REMOTEEMPATHY=23

mpChars=['non','s1:h0','s1:h1','s1:h2','s1:h3','s2:h0','s2:h1','s2:h2','s2:h3','s3:h0','s3:h1','s3:h2','s3:h3','s4:h0','s4:h1','s4:h2','s4:h3',]

MPStart()

MPSendMessage(type, param1, param2=100, param3=100)

MPReceiveMessage(event)

print 'damage4:%d'%(damage4)
print 'Message broadcast: %d %d %d %d'%(type,param1,param2,param3)

 

ForceTest(mass,force)

ForceTest2(event)

GetForceForDistance(char,dist)

calculate the force required to push a character a certain distance

FFX_Teleport(char,pos)

FFX_TP(char,pos,fn='FFX_TP2',strboost=1)

FFX_TP2(event)

GetTargetPos(char,target)

print 'ffx_tp2:char=%s'%(char)


findCharByID(id)

makeIllusion(char, fly=0)

makes a character physically ineffectual

removeFX(event)

BASE CUTSCENE TRICKS ###########################

FFX_InitBase(max,dupe='')

initilaises a base cutscene

placeCustoms(max,dupe='')

tempCheck(event)

sayOnce(char,tag)

sayOnceFn(char,tag,fn)

findByVoiceID(voice)

returns a custom character by voice ID

hasTrait(char,trait)

determines if a character has a given trait by name

findByTrait(trait)

returns a custom character by voice ID

FFQ code starts here ###########################################

 


INITIALISATION ############################################


FFQ_initialiseExtras(event)

Probably obsolete! everything done automatically on startup should either be here, under the "else:" statement
or called directly outside any function

CHARACTER ATTRIBUTES MANIPULATION ################################


! for attribute identification and manipulation (ex: Latent Mutant)

Functions related to FFX attributes. This section should probably be moved elsewhere in the file
and regrouped with similar functions.

The following removed FFX 3.2.0.1 Ep. 2: Obsolete due to individual attribute setting by default.

addFFXAttrib(char, attrib)

FFX_ATTR_BY_TEMPLATE = [] #lists FFX attributes for each template in the current mission
FFX_ATTR_SPECIAL_CASES = [] #lists additional FFX attributes for those characters who gained attributes not in their template

Used by FFX initialisation for all characters of the templates
def saveFFXAttributesForTemplate(template, attribute):

use this to add an attribute to a specific character AND register it so hasAttribute() returns the true state
ripped from initAttribsForChar()
Changed FFX 3.2 alpha: changed the Latent Mutant specific elements
def initNewAttribForChar(char, newAttrib, update = 0):

For characters gaining attributes during the mission (ex.: Latent Mutant)
def saveFFXAttributesForCharacter(char, attribute):

get the FFX attributes of this character's template
def getFFXAttributesForTemplate(char):

get the FFX attributes specific to this character
attributes need to have been initialized using initNewAttribForChar()
(using simply init[attribute name](char) won't work)
def getFFXAttributesForCharacter(char):

does the character have chacter-specific FFX attributes?
attributes need to have been initialized using initNewAttribForChar()
(using simply init[attribute name](char) won't work)
Added FFX 3.2
def hasFFXAttributesForCharacter(char):

remove attribute from the list for the character
note: this does not disable the attribute, only the indication that the character has it
def removeFFXAttributesForCharacter(char, attribute):

Added FFX 3.2
Attributes which are not part of the template must be initialized with this function instead of being called directly!
Returns whether the attribute was succesfully added or not. If the attribute was already present, the call is considered successful.

addFFXAttrib2(char, attrib)

removeFFXAttrib(char, attrib)

Added FFX 3.2
Attributes must be removed with this function instead of being called directly with the remove parameter!
To know which attributes are removable, use getRemovableAttributes() from the progrutils module.
Returns whether the attribute was succesfully removed or not. If the attribute wasn't found, the call is considered successful.

removeFFXAttrib2(char, attrib)

getAllFFXAttr()

! TO DO: Obsolete since FFX 2.6!
FFX attributes (including simulated built-ins) which SHOULD be safe to add after startup.
Guess what? Not all attributes have been tested. :P
Notes:
-Put in a function to avoid wasting more memory.
-Combos are always considered unsafe.
-Some attributes, while "safe", may wreck the game (ex.: borrowedtime), while others (ex.: groupteleport)
are useless to most characters; these are denoted by a 1 instead of a 2.
-Currently, no attribute is marked as removable.
-The incompatible attribute sublist is basically to avoid initialising an attribute if the character already
has one from this sublist.
-The scripted version of attribute may be assigned to a character already having the original, since
built-in attributes can't be detected.
-May eventually be used (in FFX 2.6 or post FF2) as the basis for a Counter-Measure attribute ;)

getFFXAttrDetails(attrName)

! TO DO: Obsolete since FFX 2.6!
returns the following array:
["attribute name", cost, safe to initialize by in-game script only (0=no, 1=yes, but should be avoided, 2=yes), removable (0=no, 1=yes), ["incompatible attribute1", "incompatible attribute2", "etc."]]

isAttributeSetSafe(char, attrSet)

! TO DO: Obsolete since FFX 2.6!
Check if the attribute within the current set (from getAllFFXAttr()) can be added to the character

getOriginalNameOfAttrib(attrib,reverse=0)

Used with those attributes which are possibly scripted versions of built-ins before using
Mission_StatusText("@ATTRIB_%s"%string.upper(attrib)) to get the display name of the attribute.
Changed FFX 3.2: use reverse=1 to get the ffx name of a scripted attribute form the built-in name

isScriptedAttribute(attr)

Returns true if the attribute name corresponds to a scripted version of a built-in one
Note that for built-in attributes with spaces in the name, it returns false, even if there's a
scripted version, because the scripted name has no spaces. You can use getOriginalNameOfAttrib(attrib,reverse=1)
to get the name without spaces.

getAllScriptedAttributes()

Get a tuple of all scripted attributes
Note that for built-in attributes with spaces in the name, it returns the scripted version's name,
i.e., without the spaces. Use getOriginalNameOfAttrib(attrib) to get the original name
Added FFX 3.2 Please update as needed!

isBuiltinAttribute(attrib)

return true if given attrib is one of the game's built-in character attributes

getAttributes(char, charAttr=1, templateAttr=1, ignoreBought=0)

returns the list of character attributes for this object
charAttr: if set to 1, all FFX attributes for this characterwill be added to the returned list, including
those added with addFFXAttrib() and not present in the template
templateAttr: if set to 1, the default attributes for the template will be added to the returned list
ignoreBought: if set to 0, only already purchased template attributes will be added to the returned list

getCharacterSpecificAttributes(char, ignoreBought=0)

returns the list of character attributes specific to this object and not found in the template.
ignoreBought: if set to 0, unpurchased template attributes will be ignored from the comparison

isAttributeRemovable(attribute)

Detects if an attribute can be removed before adding it.
Syntax example:
myVariable = isAttributeRemovable('heroic')
Note:
-This will generate an ff.log/console error message for attributes which try to access character properties.
This is intentional.
To know which attributes are removable, use getRemovableAttributes() from the progrutils module.

isComboAttributeRemovable(attribute)

Checks if each of the attributes of a combo are removable.

 

addFlight(char)


updateFlightState(event)

 

isBreached(obj,char='')

in FFvsTTR, PowerNull for shields only doesn't work anymore, hence this workaround.

customisation parameters functions ####################################################




---Visual Effects----------------------------

visualEffectRed(char, duration, string = '', float = 0)

Turns the world red
char, string and float are ignored for this function

visualEffectBlue(char, duration, string = '', float = 0)

Turns the world blue
char, string and float are ignored for this function

visualEffectWireframe(char, duration, string = '', float = 0)

Turns the world into colored wireframe
char, string and float are ignored for this function

OnEffectWireframeOff(event)

visualEffectHideWorld(char, duration, string = '', float = 0)

Turns the terrain and non ambiant objects invisibles
char, string and float are ignored for this function

OnEffectHideWorldOff(event)

visualEffectPhysicsBubbles(char, duration, string = '', float = 0)

Shows physics displacement bubbles around moving objects
char, string and float are ignored for this function

OnEffectPhysicsBubblesOff(event)

helper functions ##########################################################





---AI helpers--------------------------------

FFQ_givesAI(char,spawnName)

TEMP! This needs to be replaced with more modern code based on M25 new system.
gives AI to a spawned oc_controllable character
basically a copy of FFX code
v1.4
-made the AI follow the nearest hero when idle
v1.5
-failsafes added for work with skirmish mode time travelers

updateFFQ_AIfollow(event)

used by FFQ_independantAI() and FFQ_givesAI()

FFQ_getNearestHero(char)


cshelper code, modified to find the nearest hero which is NOT the calling character

FFQ_heightDiff(char,target)

finds if the target is on higher ground than the character while not flying
Ep. 2006-08-25: Updated for FFX 3.x



---generic helpers---------------------------

FFQ_excludeFrom(probeList,excludeList)

Note: other generic functions have been moved to the generalutils module

exclude from a first string array any entry of the second array contained in the first
characters of any entry of the first
example:
loadedTemplates=["eve_extra","minute_man_extra","mm_dupe"]
disallowedTemplates=["minute_man"]
allowedTemplates=[]
allowedTemplates=excludeFrom(loadedTemplates,disallowedTemplates)
will give
allowedTemplates=["eve_extra","mm_dupe"]

FFQ_excludeFromName(probeList,excludeList)

same, but more specific and useful: with names of active game objects as targets using templates as excludes

FFQ_selectFrom(probeList,selectList)

instead of excluding, allow only if from list

FFQ_selectFromName(probeList,selectList)

same, but more specific and useful: with names of active game objects as targets using templates as includes

FFQ_tupleToString(value)

Convert a 3-element tuple of numbers to a string and vice-versa, rounded down to one decimal
see also generalutils.sequenceToString() for a less specialized implementation
Updated FFX 3.2: Made faster

FFQ_stringToTuple(value)



---object modification helpers---------------

FFQ_reduceEP(char,amount,minEnergy=0)

Reduce EP by a specified amount and return 1 if the character has no energy left

FFQ_changeHP(char,amount)

Allows to add or remove health safely by checking for minHealth and maxHealth.
Added FFX 2.5

killLater(char, delay = 5.0)

kills a character after x seconds
Added FFX 2.5

OnKillLater(event)

noFade(char, duration = 0)

IMPORTANT!: using the noFade() function is *very* *dangerous*: The game apparently checks if the object state = dead to determine the
character's behaviour and eventually fade him. However, he is considered alive for Object_IsAlive() and possibly both alive and dead
for RegDeath(). If some code checks for dead characters, it will return a false negative on a character under noFade()! If a persistent
RegDeath() is set on character and you call noFade() on him, the game will stall!
Bottom line: Don't use it.
Prevents an already dead civilian, minion or police class character from fading, as the noFade object attribute doesn't work in FFvsTTR
duration: if set to 0: infinite; if set to a positive value, character will start fading a few seconds after the time is up.
To disable, set FFX_ObjectSetAttr(char, 'noFade', 0)
(Note that the original Object_GetAttr(char, 'noFade') is left alone.
Added 3201Ep3

OnNoFade(event)

setSecondaryState(char, state, duration = -1, shield = 0)

Gives the character the selected secondary state.
By default, duration is permanent. ADDED: duration set to 1000 secs, because flag isn't supposed to work,
according to the scripting docs.
To remove state, set duration to 0.
cshelper default duration for states is usually 10.

Updated in FFX 3.0

Notes:
-Irradiate and Acid Burn have a built-in set duration. This function doesn't attempt to work around that.

isUnderSecondaryState(char, state)

dictSecondaryStates(state)

setBuoyantState(char, duration = -1)

Shorthands for the generic function above
Changed FFX 3.0:
-Added FFvsTTR states
-Repaired is...() functions, as they were all broken...
-Removed functions redundants with those done by Dr Mike

isBuoyant(char)

setDeepSensoredState(char, duration = -1)

isDeepSensored(char)

setPossessionState(char, duration = -1)

isPossessed(char)

setSpawnState(char, duration = -1)

isSpawn(char)

setSpeedDecreaseState(char, duration = -1)

isSpeedDecreased(char)

setSpeedIncreaseState(char, duration = -1)

isSpeedIncreased(char)

setWeakenState(char, duration = -1)

isWeakened(char)

the FFvsTTR built-in state, not the FFX one...

setZombieState(char, duration = -1)

setInvisibleState(char, duration = -1)

isInvisible(char)

setPowerNullState(char, duration = -1, shield = 0)

Set shield = 1 to prevent use of an active defence for the duration
Updated FFX 3.0

setDisplaceImageState(char, duration = -1)

removeShield(): see under BREACH section

isBreached(): see under BREACH section

isDisplaced(char)

setIrradiatedState(char, duration = -1)

Notes:
-Irradiate and Acid Burn have a built-in set duration. This function doesn't attempt to work around that.

setBlindState(char, duration = -1)

setHexedState(char, duration = -1)

setAcidBurntState(char, duration = -1)

Notes:
-Irradiate and Acid Burn have a built-in set duration. This function doesn't attempt to work around that.

setEmpathyState(char, duration = -1)

isEmpathic(char)

setEnergizedState(char, duration = -1)

isStunEnergized(char)

setAreaEnergizedState(char, duration = -1)

isAreaEnergized(char)

setGenericState(char, state, duration = -1)

set generic states; can't be detected
cshelper default duration for states is usually 10.
updated Rally (OBJSTATE_ATTACKBONUS) to take into account attackBonus... :P

dictGenericStates(state)

setElectrifiedState(char, duration = -1)

setExcitedState(char, duration = -1)

setAlteredState(char, duration = -1)

setRalliedState(char, duration = -1)

setDensityMaxState(char, duration = -1)

FFQ_minHealthHeroes(state)

make all heroes invulnerable
1 to turn on, 0 to turn off


---mission-related helpers-------------------

FFQ_writeStartingPos()

remember the starting position of your heroes one second after the beginning of the mission
2.0

FFQ_getStartingPos(hero)

returns the starting position tuple of the selected hero. If not found, return the (-1,-1,-1) tuple.

arrowLastBaddie()

def FFQ_getMapSize():
Obsolete! Use Stumpy's datfile.Mission_GetMapExtents(MissionFileName='') for the *exact* map extents



modified from original ArrowBaddie()

arrowLastMinion()

arrowLastTeamMember(team = 2)

getCharDisplayName(char)

Get the character name as displayed to the user (ex: 'el_diablo' for the engine is displayed as 'el diablo')
For use with Mission_StatusText(); won't work correctly for print commands.
Updated FFX 3.0:
-strings.dat lookup now require @ as identifier
Updated FFX 3.2:
-simplified

teamRegDeath(function, team = 2)

since I had some problems with regDeaths(), here's a team-based alternative

FFQ_ObjectGetOrientation(char)

Relative orientation detection/conversion
Added FFX 2.5

Returns character orientation in radians (instead of the FF Object_GetOrientation()'s more esoteric format)
EDIT: Useless! Object_GetOrientation() is broken

ffTypeToRadian(orientation)

accepts one number whose value is between -pi/2 and pi/2
used with Object_GetOrientation(char)[1] or FFQ_ObjectGetOrientation(char)
EDIT: Useless! Object_GetOrientation() is broken

get2DAngleBetweenObjects(char,target)

angles are in radians

getAngleFromCoordinates(obj1,obj2)

getSizesFromCoordinates(obj1,obj2)

getAngleFromWidthAndHeight(size)

distanceSqPos2D(pos1, pos2)

Based on Dr Mike's distanceSq(), but ignores the Z-axis and requires positions instead of objects
Added FFX 3.0

FFQ_LIGHTSOURCES = []

light sources detection
used by stealthy attribute
Added FFX 2.5
Updated FFX 3.05 alpha

setLightSources()

see notes under stealthy attribute

getNearLightSources(char, dist)

returns light-emitting templates whose health is above 14 (light-emitting streetlights break under 15 health)
or any existing bonfire

changeLight(duration = 5, iamb = -1, idir = -1, ircl = 0, igcl = 0, ibcl = 0)

ripped from FFX Telepathic Scan
added FFX 2.5

OnChangeLightUpdate(event)

playRecurringEffect(obj, fxName, frequency = 5, repeat = -1)

play an FX at fixed intervals with full tracking on spine
if repeat is set to a value greater than -1, the effect will repeat only x times after the first
if the Object is a character, effect will stop on death
Added FFX 2.5

OnPlayRecurringEffect(event)

stopRecurringEffect(obj, fxName)

hasStrengthToLift(char, target, bonus = 0)

Can the character lift this object?
"bonus" is a positive or negative integer added to strength for the comparison
The sum of strength and bonus shouldn't be superior to 11. Any value higher will always return true
Changed FFX 3.2: redone to use getMaxMassToLift(), which checks Heavy Lifter. Replaced hard-coded
mass list with getMaxLiftableMasses(), as it's more exhaustive and has more than single-decimal precision.

getMaxLiftableMasses()

list of masses by strength level, ripped from Stumpy's Heavy Lifter code
the following is from testing, accurate to within attribute storage precision
Added FFX 3.2

getRequiredStrengthToLift(object)

What strength is the minimum to lift this object?
Added FFX 3.2

getMaxMassToLift(char, bonus = 0)

What is the maximum mass this character can lift?
Heavy Lifter bonus is calculated.
Added FFX 3.2

spawnTiggot(char, pos)

creates a "tiggot" related to an existing character on a specified position and returns his name
ripped from Telekinetic

Object_IsCustomChar(char)

Replaces the never-implemented command of the same name in the FF scripting manual. (Note that this becomes more important in FFvsTTR,
because we can spawn customs and because they then retain their template name instead of being renamed to 'custom_xxx_nn'.)
Given object name, returns non zero if it is a custom hero, otherwise returns 0.
Added FFX 3.2
stumpy 2006-08-26: easier with direct reference to 'isCustom' key

FFX_ObjectHasAttr(char,name)

Returns 1 if attribute exists (even if its value is zero), 0 otherwise
Added FFX 2.5

teleportToPos(char, pos, heading=0)

Teleport an object (including a character, of course) to a position. The object will conserve its current heading
(i.e., the second number from the Object_GetOrientation(object) tuple), unless you set heading= to a non-zero value.
Added FFX 3.2. This is similar to FFX_Teleport(), except that a single marker is used and that object orientation
is preserved and modifiable.

useMarkerAtPos(pos, heading=0)

Returns the name of a marker which can be reused to avoid creating different markers every time you need one.
Added FFX 3.2

Mission_CustomAction(), Mission_RemoveCustomAction() and Mission_ClearCustomActions() replacements

WRAPPER_REGISTERED_CUSTOM_COMMANDS = missionobjvar.Mission_GetVar('registeredCustomCommands', [])

Rationale: Prevents duplicate custom commands for persistent custom actions and allows to know the existing commands
by checking WRAPPER_REGISTERED_CUSTOM_COMMANDS.

FFQ_MissionCustomAction(actionName, heroFilter, objFilter, funcName, radius, oneShot)

IMPORTANT: setting oneShot=1 prevent checking for duplicates. It is suggested that you use instead oneShot=0 and call
FFQ_MissionRemoveCustomAction() manually in the resulting function. Ex.:
FFQ_MissionCustomAction('CUSTOM_SAYHELLO', char, target, 'sayHelloWorld', 250, 0)
def sayHelloWorld(target, char):
FFQ_MissionRemoveCustomAction(CUSTOM_SAYHELLO', char, target)

FFQ_MissionRemoveCustomAction(actionName, heroFilter, objFilter)

FFQ_MissionClearCustomActions()


---built-in functions wrappers helpers

Improved and moved to functionwrapper.py



---identification helpers--------------------

isCharacter(object)

for the additional character states identification function, see "object modification functions" above

warning! similarly to the cshelper functions, the is[Class] functions don't return 1 if true, but the class number

isVillain(object)

isMinion(object)

isPolice(object)

isCivilian(object)

isClone(obj)

Tries to determine if the character is a clone of either a hero, a villain or a minion class character.
Will not work on clones of same class characters generated by M25 scripted AIs if M25_DOUBLE_CLONE_HP,
exceptif the character has the M25 clone attribute
is set to 1 (which is the default value).
Changed FFX 3.0:
-baseMaxHealth now applies to template, not object
Changed FFX 3.2:
-now checks first if the character has been set as a clone by M25 AI

isEvilClone(obj)

Is the character a clone of a VILLAIN template?
Note that clones of MINIONS won't register here!
modified FFX 2.5; skirmish customs won't cause an unhandled exception anymore

isEvilCloneAlternate(char)

much slower, but works in skirmish; isEvilClone(obj) will automatically use this function in skirmish

isHeroClone(obj)

Is the character a clone of a HERO template?
Note that clones of POLICES won't register here!
added FFX 2.5

isHeroCloneAlternate(char)

much slower, but works in skirmish; isHeroClone(obj) will automatically use this function in skirmish

isLure(obj, char='')

is the character a lure?
added FFX 3.2

isSpecialChar(obj, char='')

is the character a special FFX object?
added FFX 3.2

isPowerup(obj, char='')

is the object a powerup/canister?
added FFX 3.2

FFQ_isSameSide(char,obj)

are the 2 characters on the same side (both good or evil)?

FFQ_isSide(subject)

returns 1 for minions & villains / team 2 or more

FFQ_forceTeam(char)

assigns the character to a team even if not using M25AI
returns the team
Changed FFX 3.05 alpha: new version added back in FFX
! Dr, I hope the new version is kasher with M25 new AI system, because Empathic Friendship depends on this


---get array by type and other get helpers---

getAllCharacters(checkLiving = 1, lures = 0, specialCharacters = 1)

Changed FFX 3.2: added the possibility of ignoring special characters such as tiggots
checkLiving: if at 1, k.o.'ed characters won't be returned
lures: if set to 1, lures will be returned among the characters
specialCharacters: if set to 0, tiggots, etc., won't be returned

getAllVillains(checkLiving = 1, clones = 1)

modified FFX 2.5; you can now choose to ignore clones of villains by setting the argument clones = 0
also corrected a stupid indent error

getAllMinions(checkLiving = 1, clones = 0)

modified FFX 2.5; you can now choose to include clones of villains by setting the argument clones = 1

getAllPolices(checkLiving = 1)

getAllGoodGuys(checkLiving = 1, lures = 0)

Changed FFX 3.2: optimized code; special characters are now ignored

FFQ_getAllCivilians(checkLiving = 1)

same as CSHelper, but checks if alive
changed FFX 3.0: ffq_civilian_disguise template is ignored

FFQ_getAllHeroes(checkLiving = 1, lures = 0)

same as CSHelper, but checks if alive
Changed FFX 3.0: by default, limey lures are ignored

getAllByGender(sex, lures = 0)

get all characters of the corresponding FFX voice-based "gender"
Changed FFX 3.0: by default, limey lures are ignored
parameter needs to be one of:
FFX_GENDER_UNKNOWN=-1
FFX_GENDER_OPPOSITE=0
FFX_GENDER_MALE=1
FFX_GENDER_FEMALE=2
FFX_GENDER_ANIMAL=3
FFX_GENDER_ROBOT=4
FFX_GENDER_ALIEN=5
FFX_GENDER_GOOD=0
FFX_GENDER_EVIL=32

getAllTeamMembers(team = 2, checkLiving = 1, lures = 0)

Changed FFX 3.0: by default, limey lures are ignored IF team tagging is not enabled.
(If team tagging is enabled, lures are part of team 0, like civilians and special objects.)

getAllTeammates(char, checkLiving = 1, lures = 0)

finds all others charaters on the same M25 AI team as the selected character
or, if not using M25 AI, the members of the same side (hero/police vs villain/minion0.
Added FFX 3.2 alpha

getNearestTeammate(char, checkLiving = 1, lures = 0)

hacked from cshelper.getNearestHero()
Changed FFX 3.0:
-by default, limey lures are ignored IF team tagging is not enabled.
(If team tagging is enabled, lures are part of team 0, like civilians and special objects.)
-Patched a few bugs...

getNearestAdversary(char, checkLiving = 1, team = -1, lures = 0)

finds the nearest character from any enemy team; to search for a specific team
(other than the 0 one), set the team = x variable
Changed FFX 3.0: by default, limey lures are ignored IF team tagging is not enabled.
(If team tagging is enabled, lures are part of team 0, like civilians and special objects.)

getNearestVehicle(char)

finds the nearest static or dynamic vehicle; tanks are ignored
Added FFX 2.5

getNearestObject(char)

finds the nearest object or character, projectiles excepted
Added FFX 3.2

getNearestProjectile(char)

finds the nearest projectile
Added FFX 3.2
stumpy 2006-08-26: A couple efficiency tweaks:
1) save some compute time using distance squared, which sorts the same
2) the char's pos doesn't change, so keep it outside the loop and compute
it just once.

getNearProjectiles(object, radius)

finds nearby projectiles
Added FFX 3.2

getMyProbableProjectiles(char, radius='200', deviation = (1.5, 0.09, 0.2))

Among the projectiles near the character, gets the one(s) which might have been fired by him?
Notes:
- This is strictly heuristic (i.e., guess); it might get both false negatives and false positives.
As such, this should be used only on projectiles which have just
been fired before the character has a chance to do another move.
- To be more effective, this would need to add face (of char) to back (of projectile) and parallel
(side-by-side + flying shooter above/ground shooter below) shooting (maybe using comparative getMyProbableProjectiles())
- Hooks in MLOG('ranged') or MLOG('controller') could be combined with it to make that function to make it much more accurate.
Added FFX 3.2

getNearAdversaries(object, radius, checkLiving = 1, team = -1, lures = 0)

finds near characters from any enemy team; to search for a specific team
(other than the 0 one), set the team = x variable
adaptated from cshelper getNearBaddies
Changed FFX 3.0: by default, limey lures are ignored IF team tagging is not enabled.
(If team tagging is enabled, lures are part of team 0, like civilians and special objects.)

getAllAdversaries(char, checkLiving = 1, team = -1, lures = 0)

finds all characters from any enemy team; to search for a specific team
(other than the 0 one), set the team = x variable
Changed FFX 3.0: by default, limey lures are ignored IF team tagging is not enabled.
(If team tagging is enabled, lures are part of team 0, like civilians and special objects.)

getAllAllies(object, checkLiving = 1, removeObject = 1, lures = 0)

finds either all other heroes & polices for heroes & polices classes or all other villains & minions for villains & minions
to include the calling character himself in the list, set removeObject = 0
Changed FFX 3.0: by default, limey lures are ignored

getNearAllies(object, radius, checkLiving = 1, lures = 0)

finds near allies
adaptated from cshelper getNearBaddies
Changed FFX 3.0: by default, limey lures are ignored

getAllEnemies(object, checkLiving = 1, lures = 0)

finds either all other villains & minions for heroes & polices classes or all other heroes & polices for villains & minions
Changed FFX 3.0: by default, limey lures are ignored

getNearEnemies(object, radius, checkLiving = 1, lures = 0)

finds near enemies
adaptated from cshelper getNearBaddies
Changed FFX 3.0: by default, limey lures are ignored

getNearCivilians(object, radius, checkLiving = 1)

finds near civilians, except ffq_civilian_disguise template
added FFX 3.0

guessObjectDest(obj, time)

Tries to guess the 2D position of an object in x seconds.
Can also be used to guess the facing of a MOVING object.
Results can be read after 0.1 sec. by using the following commands:
FFX_ObjectGetAttr(obj,'guessedPos_x')
FFX_ObjectGetAttr(obj,'guessedPos_y'

IMPORTANT:
-there is a 0.1 second delay between the time the function is called and the time a value is returned
-z coordinate isn't given, since future value can't be estimated correctly

Added in FFX 2.5

OnGuessObjectDest(event)

getNearestFromList(obj,listOfTargets)

Returns the nearest object to the reference object from a list or a list-generating function.
If 2 results are nearest ex-aequo, only one is returned.
Added FFX 2.5
Changed FFX 3.2: returns an emplty string if the list is empty instead of throwing an exception.

sortByDistance(obj, listOfTargets)

returns a list re-ordered by distance to an object from a list of targetm objects
Added FFX 3.2

getTypeResistanceValue() and variants ##################



getCrushResistanceValue(char, passive=1, active=1, attribs=1, states=1, material=1)

Get the character's average resistance/weakness to a type of damage from his attributes and material,
plus active and passive defences.
Returns the damage multiplier (i.e. 1.0 if no resistance or weakness, 2.0 if weak, 4.0 if defenceless,
0.0 if completely impervious, 0.75 if somewhat resistant, etc.)
Parameters:
- passive=1 includes passive defences in the calculation
- active=1 includes active defences
- attribs=1 includes both FFX and built-in attributes
- states=1 includes attributes (such as Tough Guy) which protect only against the state alteration part
of some damage types (ex. cold or radiation). This parameter has no effect when checking state
alteration-only damage types.
- material=1 includes the character's material inherent resistances
Notes/bugs:
- This detects only resistance to specific damage types. Attributes which allow to resist to multiple
damage types (such as Temporary Invulnerability or Body Aura) are ignored.
- Adaptative attribute is ignored, since the actual resistances can't be determined.
- Adaptative (active) attribute current resistances are detected correctly.
- Characters suffering from non-Adaptative (active) genetic damage will report incorrect values,
as genetic damage can't be detected.
- For active and passive defences, special attack type is ignored, since there is no in-game UI for
it. The resistance multiplier is based on the sum of each type of attack blocked.
- Since active defences are either on or off, their weight in the overall resistances is arbitrarily based
on duration, energy cost and number of levels purchased, in addition to the types of attacks blocked.
- Only the first active and the first passive defences are detected.
- Some defences may not be detected correctly with older version of chardata.py.
- Powers are accounted only if they are starting attributes or have been purchased.

- material 12: hidden material: dark matter
- defenseless against crushing, piercing, energy, fire, radiaton, electricity, acid and cold
- weak against mental and mystical
- material 13: hidden material: ectoplasm
- defenseless against crushing, piercing, energy, electricity and acid
- weak against mental and mystical
- normal against fire, radiation and cold

getPierceResistanceValue(char, passive=1, active=1, attribs=1, states=1, material=1)

getEnergyResistanceValue(char, passive=1, active=1, attribs=1, states=1, material=1)

getFireResistanceValue(char, passive=1, active=1, attribs=1, states=1, material=1)

getElectricalResistanceValue(char, passive=1, active=1, attribs=1, states=1, material=1)

getRadiationResistanceValue(char, passive=1, active=1, attribs=1, states=1, material=1)

getAcidResistanceValue(char, passive=1, active=1, attribs=1, states=1, material=1)

getColdResistanceValue(char, passive=1, active=1, attribs=1, states=1, material=1)

getMentalResistanceValue(char, passive=1, active=1, attribs=1, states=1, material=1)

getMysticalResistanceValue(char, passive=1, active=1, attribs=1, states=1, material=1)

getTypeResistanceValue(char, passive, active, attribs, states, material, damageType, attribTypes, stateAttribTypes, matTypes)


---Pseudo Event_RegisterSinks helpers using timers

regSecondaryState2(char, state, function, user = 0, string = '', persistent = 0)

Detect secondary state changes
uses FFvsTTR's new EVENT_CHARACTER_SEC_STATE_CHANGED, which has no cshelper wrapper.
Added FFX 3.2

regSecondaryState(char, state, function, time = 0.5, persistent = 0)

Detect secondary state change, because some secondary states don't register.
Note: Please use regSecondaryState2() above instead, as it's faster, less quirky and offers more parameters.
If regSecondaryState2() proves to support correctly all states, regSecondaryState() will be made obsolete.
Added FFX 2.5

OnSecondaryStateCheck(event)

regCondition(char, condition, function, time = 0.5, user = 0,persistent = 0)

Detect if a condition involving a variable or an attribute becomes true

OnConditionCheck(event)

regAcidBurnt(char, function, user = 0, persistent = 0)

Alternative method for prolonged damage states
Advantage:
-doesn't use memory needlessly
-no risk (?) of damage being triggered a second time before the function is called.
Disadvantages:
-slower
-if the prolonged damage state isn't powerful enough to damage, it won't trigger the function;
-also, if the character health gets higher, damage may not register. EDIT: repaired!
Added FFX 2.5

OnRegAcidBurnt(event)

regIrradiated(char, function, user = 0, persistent = 0)

OnRegIrradiated(event)

CHAR_INITIALIZED_EVENT = 504 # some arbitrary value

Pseudo-event registration of new characters. This has a latency of up to 1.0 sec.
Spawned characters' FFX attributes initialisation is started before this event is fired.
Calling regCharacterInitialized() from def OnPostInit() should register characters present at startup.
You should use only one of the three following parameters: object, template and objectClass.
To detect any new character, leave all three parameters
Note that your registered function will still have to check whether the character should be processed or not
(i.e, is it a special hidden object such as a tiggot, disguise, etc.)
Added FFX 3.2
stumpy 2006-09-25: I've renamed the 'spawned' parts of these functions and
variable to initialized, to avoid confusing with the spawn sinks in mlogreader.

regCharacterInitialized(fn, object = '', template = '', objectClass = 0, persistent = 0, float = 0, user = 0, string = '')

code ripped off Stumpy's mlogreader.regAnimation()

cancelCharacterInitializedCallbackSink(fn, object = '', template = '', objectClass = 0)

Cancel a CHAR_INITIALIZED_EVENT sink for a particular callback function and the corresponding object/template/objectClass parameter
code ripped off Stumpy's mlogreader.cancelAnimationCallbackSink()

CharacterInitializedEvent(char)

used by initialiseChar(), which is called each 1.0 sec. by FFX.
code ripped off Stumpy's mlogreader.HandleAnimationCallbacks()

class PseudoInitializeEvent


This is simply a copy of Stumpy's class from mlogreader module
Note: while the format was kept the same for potential compatibility, eventType=FLIGHT_START_EVENT
was changed to eventType=66 (the value of mlogreader.FLIGHT_START_EVENT) to avoid creating two
versions of the same global variable.
stumpy 2006-09-24: modified to make distinct from other pseudo events
Added FFX 3.2

eventeval(fn,event)

This is simply a slightly modified copy of Stumpy's function from mlogreader module


---look, move, speak and other cutscene-related helpers

aliveLook(charactersArray, zoom = 0, heading = 0, time = 0, fn = '')

snaps the camera to the first living character from a list
modified from the original cshelper function look()

aliveLookTo(charactersArray, fn = '', time = 3)

scrolls the camera to the first living character from a list
modified from the original cshelper function lookTo()

turnControllablesTo(target)

ripped off Dr. mike's turnAllTo(), which works on customs only
Changed FFX 3.2.0 alpha :added a random delay to make it look more natural
turn all customs to given point (eg speaker)

OnTurnControllablesTo(event)

moveControllablesTo(target)

ripped off Dr. mike's moveAllTo(), which works on customs only
maybe range should be randomized
move all customs to given point

Mission_SetAttr('exclusiveSpeechPlayed',0)

mutually exclusive dialogue calls; if optional speech returns a result, don't play the next dialogue(s)
used when you want a character to say something if he's in the mission, and if not, use another speech instead
example: Microwave says something if he's in the mission; if he isn't, Liberty Lad speaks instead, if he's there;
if not, use optionalForceSpeak() to have a character in the mission or not (such as Microwave), speak a different line.
if you don't want to force a speech if there is no one, you can use only a succession exclusiveOptionalSpeak() and,
after the last one, add the following line to your cutscene script:

exclusiveOptionalSpeak(template, tag)

call this function first

optionalForceSpeak(object, tag, telepathy = 2)

call this function last if there is another step in the cutscene after

optionalForceSpeakNoCB(object, tag, telepathy = 1)

call this function last if it's the last step of the cutscene




 


Damage Refund Management Callback #########

DamageManagement(event)

Currently used by Invulnerable, Temporary Invulnerability and Tough Guy 2



STUMPY'S HELPERS #########################################

RegTimer2

RegTimer2(fn, time, arglist=(), persistent = 0)

For questions and comments, please go to
http://freedomreborn.net/phpbb/viewtopic.php?t=2579

Allows you to pass as many variables of any type that you want through by packing them into a tuple
and using str() or repr() to convert that tuple into a string. Then just unpack the tuple string in
the callback function using eval().
If you use one or more modules frequently, there might be an efficiency improvement in adding it to
the tryfirst list.

Syntax example:
Energize our valiant spaceman in three seconds
RegTimer2('Object_SetSecondaryState', 3.0, ('spiff',SCSTATE_ENERGIZED,10))

will execute this function with these arguments after the 3 seconds:
Object_SetSecondaryState('spiff',SCSTATE_ENERGIZED,10)

Note:
Python doesn't recognize one-element tuples as such and read directly the element inside, unless there
is a trailing comma. So if you use a single element as parameter in arglist, please add the comma after
or add a dummy variable. (Of course, you could also use the standard RegTimer, either alone, if you know
that there is always only one element in the tuple or, otherwise, with missionobjvar.Mission_SetVar() or
missionobjvar.Object_SetVar().)

Timer2Unwrapper(event)

SetMapLimits / Mission_GetMostObjects


SetMapLimits()

For questions and comments, please go to
http://freedomreborn.net/phpbb/viewtopic.php?t=21640

NOTE:
These two functions try to read the mission.dat file of the current map, which should work with most
mods and Danger Room missions. However, maps from the main FF campaign (either in campaign mode or while
replaying a campaign episode in the Danger Room) usually won't have a readable mission.dat (see details
below). To counter this, both functions will use an alternate method which doesn't rely on reading
mission.dat. As such, the results may vary somewhat.

Reading mission.dat: an explanation
For these functions to work, there must actually be a mission.dat (or base.dat) file in the mission
folder for whatever mission is running. I think that's usually true (at least in all the mods I've
seen), but keep in mind that it is possible to distribute a mod with these files compressed (zipped)
into .ff files that the engine decompresses internally (I assume) without putting the DAT file anywhere
nice. That's what the main campaign does and you have to unzip the missions.ff file manually if you want
to experiment with those missions using these functions.

Related info available in datfiles.py

Get the approximate size of the map by finding the min and max positions of stuff on the map

flytracker(char)

flytrack(event)

OnFlyTrackBeam(event)

Get Base Health

GetBaseHealth(obj)

stumpy: Find the base maximum health the object would have, *before* any FFX modifications

DR MIKE'S FINAL ADDITIONS #####################


NEXUS TEST STUFF ###############################

E=FX, X=Explosion power, D=Dummy Ranged power, C=Command Name


FFX_OVERHEATED_CUSTOM=[
["default","effect_ffx_flames","ffx_overheated"],
["types","EFX","XExplosion"],
]

FFX_ENVCONTROLA_CUSTOM=[
["default","ffx_earth_control2","CUSTOM_MAGMAVENT","ffx_geovent","ffx_firestorm"],
["types","DDummy Power","CCommand","OObject","XExplosion"],
]

FFX_ATTRIBUTES=['OVERHEATED','ENVCONTROLA']

FFX_NEXUS_FX=['effect_ffx_flames','effect_ffx_density','effect_ffx_electricsparks']

FFX_NEXUS_AREA=['ffx_frostbite','ffx_exile_area']

FFX_NEXUS_DUMMY=['ffx_tk_lift','ffx_tk_lift2']

initnexus()

addEntries(name,code)

OnNexusArea(event)

OnNexusDummy(event)

saveNexus()

saveNexusArray(name,f1)

addNexusCommands(char,array,arrayName)

OnChooseObjNameOVERHEATED1(target,char)

TODO - write this out to nexuscmd.py?
comd="def %s(target,char): SetCustomEntryByName(target,char,'%s',%d)"%(fn,arrayName,index)
print comd
exec comd

OnChooseObjNameOVERHEATED2(target,char)

OnChooseObjNameENVCONTROLA1(target,char)

OnChooseObjNameENVCONTROLA4(target,char)

RefreshChar(char)


eg SetCustomEntryByName(char,target,'OVERHEATED',1)


SetCustomEntryByName(char,value,arrayName,index)

SetCustomEntry(char,value,array,arrayName,index)

FFX_Spawn(name,template,obj,anim=1)

spawns, writes out template to log file (even for customs) and aligns with obj

FFX_Spawn2(event)

FFX_alignWithEvent(event)

alignWith(char,obj)

GRENADE TRACKING HEURISTICS ########################

lastMissiles=[]

staticMissiles=[]

projCheck(event)

findMissile(event)

checkForProjEnd(event)

FFX_ObjectSetAttr(res,'_x',set[1][0])
FFX_ObjectSetAttr(res,'_y',set[1][1])
FFX_ObjectSetAttr(res,'_z',set[1][2])
FFX_ObjectSetAttr(res,'_src',Object_GetAttr(char,'ffxID'))
RegTimer('checkForProjEnd',0.1,0,fn,res)
RegTimer('checkForProjEnd',0.01,0,fn,res)

GRENADE SWAPS #########################################

grenadehit(source,target,fn)

def hextocrystalliseG(event):
grenadehit(event.string,event.object,'hextocrystallise')

grenadetomagnetpull(event)

grenadetopull(event)

writeobj()

LIGHTING FIX #########################################

initLightingFixCommands()

updateLF(event)

getMesh(template)

OnLightingFixRetry(event)

OnLightingFix(target,dummy)

MAIN SKIRMISH LOOP #####################

arrowedBadGuy=''

FFX_SkirmishCheck(event)

classTest(mask)

Mission_StatusText('non-existant')
Mission_StatusText('dead')
Mission_StatusText('one of us')
print '%s is a threat'%(obj)
Mission_StatusText('arrowing %s'%(obj))

stores pre-cached power IDs for powers ########

generatePowerIDs()

powerfin(event)

EndLevel(event)

powerTest(powerName,i)

OnPowerTest2(event)

 

 

New option for MegaBlast combining lesser versions of zapStrength and takeDamage ########

zapStrengthAndtakeDamage(event)

New Defense Mechanism Options ##################

resistanceThroughPain(char,param,intensity)

option for increasing invulnerablity for Pain Response (Defense Mechanism)

strengthandResistanceThroughPain(char,param,intensity)

option for increasing strength AND invulnerablity for Pain Response (Defense Mechanism)

decayInv(event)

 

blank25(event)

New Side Effect Option that has a 25% chance of Mental Blanking the User ###