2016-03-01 15:47:10 +00:00
/*
* * thingdef_data . cpp
* *
* * DECORATE data tables
* *
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* * Copyright 2002 - 2008 Christoph Oelckers
* * Copyright 2004 - 2008 Randy Heit
* * All rights reserved .
* *
* * Redistribution and use in source and binary forms , with or without
* * modification , are permitted provided that the following conditions
* * are met :
* *
* * 1. Redistributions of source code must retain the above copyright
* * notice , this list of conditions and the following disclaimer .
* * 2. Redistributions in binary form must reproduce the above copyright
* * notice , this list of conditions and the following disclaimer in the
* * documentation and / or other materials provided with the distribution .
* * 3. The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission .
* * 4. When not used as part of ZDoom or a ZDoom derivative , this code will be
* * covered by the terms of the GNU General Public License as published by
* * the Free Software Foundation ; either version 2 of the License , or ( at
* * your option ) any later version .
* *
* * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* * IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* * INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* * NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* * DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* * THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* * THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* *
*/
# include "thingdef.h"
# include "actor.h"
# include "d_player.h"
# include "p_effect.h"
# include "autosegs.h"
static TArray < FPropertyInfo * > properties ;
static TArray < AFuncDesc > AFTable ;
//==========================================================================
//
// List of all flags
//
//==========================================================================
// [RH] Keep GCC quiet by not using offsetof on Actor types.
2016-10-25 07:55:13 +00:00
# define DEFINE_FLAG(prefix, name, type, variable) { (unsigned int)prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native }
2016-11-08 10:12:56 +00:00
# define DEFINE_PROTECTED_FLAG(prefix, name, type, variable) { (unsigned int)prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_ReadOnly|VARF_InternalAccess }
2016-10-25 07:55:13 +00:00
# define DEFINE_FLAG2(symbol, name, type, variable) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native }
# define DEFINE_FLAG2_DEPRECATED(symbol, name, type, variable) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_Deprecated }
2016-10-24 15:18:20 +00:00
# define DEFINE_DEPRECATED_FLAG(name) { DEPF_##name, #name, -1, 0, true }
2016-10-25 07:55:13 +00:00
# define DEFINE_DUMMY_FLAG(name, deprec) { DEPF_UNUSED, #name, -1, 0, deprec? VARF_Deprecated:0 }
2016-03-01 15:47:10 +00:00
2016-10-31 16:02:47 +00:00
// internal flags. These do not get exposed to actor definitions but scripts need to be able to access them as variables.
2016-11-03 23:19:36 +00:00
FFlagDef InternalActorFlagDefs [ ] =
2016-10-31 16:02:47 +00:00
{
DEFINE_FLAG ( MF , INCHASE , AActor , flags ) ,
DEFINE_FLAG ( MF , UNMORPHED , AActor , flags ) ,
DEFINE_FLAG ( MF2 , FLY , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , ONMOBJ , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , ARGSDEFINED , AActor , flags2 ) ,
DEFINE_FLAG ( MF3 , NOSIGHTCHECK , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , CRASHED , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , WARNBOT , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , HUNTPLAYERS , AActor , flags3 ) ,
DEFINE_FLAG ( MF4 , NOHATEPLAYERS , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , SCROLLMOVE , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , VFRICTION , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , BOSSSPAWNED , AActor , flags4 ) ,
DEFINE_FLAG ( MF5 , AVOIDINGDROPOFF , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , CHASEGOAL , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , INCONVERSATION , AActor , flags5 ) ,
DEFINE_FLAG ( MF6 , ARMED , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , FALLING , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , LINEDONE , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , SHATTERING , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , KILLED , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , BOSSCUBE , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , INTRYMOVE , AActor , flags6 ) ,
DEFINE_FLAG ( MF7 , HANDLENODELAY , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , FLYCHEAT , AActor , flags7 ) ,
2016-11-03 23:19:36 +00:00
{ 0xffffffff }
2016-10-31 16:02:47 +00:00
} ;
2016-11-03 23:19:36 +00:00
FFlagDef ActorFlagDefs [ ] =
2016-03-01 15:47:10 +00:00
{
DEFINE_FLAG ( MF , PICKUP , APlayerPawn , flags ) ,
DEFINE_FLAG ( MF , SPECIAL , APlayerPawn , flags ) ,
DEFINE_FLAG ( MF , SOLID , AActor , flags ) ,
DEFINE_FLAG ( MF , SHOOTABLE , AActor , flags ) ,
2016-11-08 10:12:56 +00:00
DEFINE_PROTECTED_FLAG ( MF , NOSECTOR , AActor , flags ) ,
DEFINE_PROTECTED_FLAG ( MF , NOBLOCKMAP , AActor , flags ) ,
2016-03-01 15:47:10 +00:00
DEFINE_FLAG ( MF , AMBUSH , AActor , flags ) ,
DEFINE_FLAG ( MF , JUSTHIT , AActor , flags ) ,
DEFINE_FLAG ( MF , JUSTATTACKED , AActor , flags ) ,
DEFINE_FLAG ( MF , SPAWNCEILING , AActor , flags ) ,
DEFINE_FLAG ( MF , NOGRAVITY , AActor , flags ) ,
DEFINE_FLAG ( MF , DROPOFF , AActor , flags ) ,
DEFINE_FLAG ( MF , NOCLIP , AActor , flags ) ,
DEFINE_FLAG ( MF , FLOAT , AActor , flags ) ,
DEFINE_FLAG ( MF , TELEPORT , AActor , flags ) ,
DEFINE_FLAG ( MF , MISSILE , AActor , flags ) ,
DEFINE_FLAG ( MF , DROPPED , AActor , flags ) ,
DEFINE_FLAG ( MF , SHADOW , AActor , flags ) ,
DEFINE_FLAG ( MF , NOBLOOD , AActor , flags ) ,
DEFINE_FLAG ( MF , CORPSE , AActor , flags ) ,
DEFINE_FLAG ( MF , INFLOAT , AActor , flags ) ,
2016-10-27 13:53:53 +00:00
DEFINE_FLAG ( MF , COUNTKILL , AActor , flags ) ,
DEFINE_FLAG ( MF , COUNTITEM , AActor , flags ) ,
2016-03-01 15:47:10 +00:00
DEFINE_FLAG ( MF , SKULLFLY , AActor , flags ) ,
DEFINE_FLAG ( MF , NOTDMATCH , AActor , flags ) ,
DEFINE_FLAG ( MF , SPAWNSOUNDSOURCE , AActor , flags ) ,
DEFINE_FLAG ( MF , FRIENDLY , AActor , flags ) ,
DEFINE_FLAG ( MF , NOLIFTDROP , AActor , flags ) ,
DEFINE_FLAG ( MF , STEALTH , AActor , flags ) ,
DEFINE_FLAG ( MF , ICECORPSE , AActor , flags ) ,
DEFINE_FLAG ( MF2 , DONTREFLECT , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , WINDTHRUST , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , DONTSEEKINVISIBLE , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , BLASTED , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , FLOORCLIP , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , SPAWNFLOAT , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , NOTELEPORT , AActor , flags2 ) ,
DEFINE_FLAG2 ( MF2_RIP , RIPPER , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , PUSHABLE , AActor , flags2 ) ,
DEFINE_FLAG2 ( MF2_SLIDE , SLIDESONWALLS , AActor , flags2 ) ,
DEFINE_FLAG2 ( MF2_PASSMOBJ , CANPASS , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , CANNOTPUSH , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , THRUGHOST , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , BOSS , AActor , flags2 ) ,
DEFINE_FLAG2 ( MF2_NODMGTHRUST , NODAMAGETHRUST , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , DONTTRANSLATE , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , TELESTOMP , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , FLOATBOB , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , THRUACTORS , AActor , flags2 ) ,
DEFINE_FLAG2 ( MF2_IMPACT , ACTIVATEIMPACT , AActor , flags2 ) ,
DEFINE_FLAG2 ( MF2_PUSHWALL , CANPUSHWALLS , AActor , flags2 ) ,
DEFINE_FLAG2 ( MF2_MCROSS , ACTIVATEMCROSS , AActor , flags2 ) ,
DEFINE_FLAG2 ( MF2_PCROSS , ACTIVATEPCROSS , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , CANTLEAVEFLOORPIC , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , NONSHOOTABLE , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , INVULNERABLE , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , DORMANT , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , SEEKERMISSILE , AActor , flags2 ) ,
DEFINE_FLAG ( MF2 , REFLECTIVE , AActor , flags2 ) ,
DEFINE_FLAG ( MF3 , FLOORHUGGER , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , CEILINGHUGGER , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , NORADIUSDMG , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , GHOST , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , SPECIALFLOORCLIP , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , ALWAYSPUFF , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , DONTSPLASH , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , DONTOVERLAP , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , DONTMORPH , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , DONTSQUASH , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , EXPLOCOUNT , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , FULLVOLACTIVE , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , ISMONSTER , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , SKYEXPLODE , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , STAYMORPHED , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , DONTBLAST , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , CANBLAST , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , NOTARGET , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , DONTGIB , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , NOBLOCKMONST , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , FULLVOLDEATH , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , AVOIDMELEE , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , SCREENSEEKER , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , FOILINVUL , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , NOTELEOTHER , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , BLOODLESSIMPACT , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , NOEXPLODEFLOOR , AActor , flags3 ) ,
DEFINE_FLAG ( MF3 , PUFFONACTORS , AActor , flags3 ) ,
DEFINE_FLAG ( MF4 , QUICKTORETALIATE , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , NOICEDEATH , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , RANDOMIZE , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , FIXMAPTHINGPOS , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , ACTLIKEBRIDGE , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , STRIFEDAMAGE , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , CANUSEWALLS , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , MISSILEMORE , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , MISSILEEVENMORE , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , FORCERADIUSDMG , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , DONTFALL , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , SEESDAGGERS , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , INCOMBAT , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , LOOKALLAROUND , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , STANDSTILL , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , SPECTRAL , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , NOSPLASHALERT , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , SYNCHRONIZED , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , NOTARGETSWITCH , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , DONTHARMCLASS , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , SHIELDREFLECT , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , DEFLECT , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , ALLOWPARTICLES , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , EXTREMEDEATH , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , NOEXTREMEDEATH , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , FRIGHTENED , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , NOSKIN , AActor , flags4 ) ,
DEFINE_FLAG ( MF4 , BOSSDEATH , AActor , flags4 ) ,
DEFINE_FLAG ( MF5 , DONTDRAIN , AActor , flags5 ) ,
2016-09-04 13:53:20 +00:00
DEFINE_FLAG ( MF5 , GETOWNER , AActor , flags5 ) ,
2016-03-01 15:47:10 +00:00
DEFINE_FLAG ( MF5 , NODROPOFF , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , NOFORWARDFALL , AActor , flags5 ) ,
2016-10-27 13:53:53 +00:00
DEFINE_FLAG ( MF5 , COUNTSECRET , AActor , flags5 ) ,
2016-03-01 15:47:10 +00:00
DEFINE_FLAG ( MF5 , NODAMAGE , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , BLOODSPLATTER , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , OLDRADIUSDMG , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , DEHEXPLOSION , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , PIERCEARMOR , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , NOBLOODDECALS , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , USESPECIAL , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , NOPAIN , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , ALWAYSFAST , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , NEVERFAST , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , ALWAYSRESPAWN , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , NEVERRESPAWN , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , DONTRIP , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , NOINFIGHTING , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , NOINTERACTION , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , NOTIMEFREEZE , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , PUFFGETSOWNER , AActor , flags5 ) , // [BB] added PUFFGETSOWNER
DEFINE_FLAG ( MF5 , SPECIALFIREDAMAGE , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , SUMMONEDMONSTER , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , NOVERTICALMELEERANGE , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , BRIGHT , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , CANTSEEK , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , PAINLESS , AActor , flags5 ) ,
DEFINE_FLAG ( MF5 , MOVEWITHSECTOR , AActor , flags5 ) ,
DEFINE_FLAG ( MF6 , NOBOSSRIP , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , THRUSPECIES , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , MTHRUSPECIES , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , FORCEPAIN , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , NOFEAR , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , BUMPSPECIAL , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , DONTHARMSPECIES , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , STEPMISSILE , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , NOTELEFRAG , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , TOUCHY , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , CANJUMP , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , JUMPDOWN , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , VULNERABLE , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , NOTRIGGER , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , ADDITIVEPOISONDAMAGE , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , ADDITIVEPOISONDURATION , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , BLOCKEDBYSOLIDACTORS , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , NOMENU , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , SEEINVISIBLE , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , DONTCORPSE , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , DOHARMSPECIES , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , POISONALWAYS , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , NOTAUTOAIMED , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , NOTONAUTOMAP , AActor , flags6 ) ,
DEFINE_FLAG ( MF6 , RELATIVETOFLOOR , AActor , flags6 ) ,
DEFINE_FLAG ( MF7 , NEVERTARGET , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , NOTELESTOMP , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , ALWAYSTELEFRAG , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , WEAPONSPAWN , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , HARMFRIENDS , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , BUDDHA , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , FOILBUDDHA , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , DONTTHRUST , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , ALLOWPAIN , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , CAUSEPAIN , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , THRUREFLECT , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , MIRRORREFLECT , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , AIMREFLECT , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , HITTARGET , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , HITMASTER , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , HITTRACER , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , NODECAL , AActor , flags7 ) , // [ZK] Decal flags
DEFINE_FLAG ( MF7 , FORCEDECAL , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , LAXTELEFRAGDMG , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , ICESHATTER , AActor , flags7 ) ,
2016-04-23 15:16:37 +00:00
DEFINE_FLAG ( MF7 , ALLOWTHRUFLAGS , AActor , flags7 ) ,
2016-07-23 08:21:04 +00:00
DEFINE_FLAG ( MF7 , USEKILLSCRIPTS , AActor , flags7 ) ,
DEFINE_FLAG ( MF7 , NOKILLSCRIPTS , AActor , flags7 ) ,
2016-07-28 20:52:20 +00:00
DEFINE_FLAG ( MF7 , SPRITEANGLE , AActor , flags7 ) ,
2016-03-01 15:47:10 +00:00
// Effect flags
DEFINE_FLAG ( FX , VISIBILITYPULSE , AActor , effects ) ,
DEFINE_FLAG2 ( FX_ROCKET , ROCKETTRAIL , AActor , effects ) ,
DEFINE_FLAG2 ( FX_GRENADE , GRENADETRAIL , AActor , effects ) ,
DEFINE_FLAG ( RF , INVISIBLE , AActor , renderflags ) ,
DEFINE_FLAG ( RF , FORCEYBILLBOARD , AActor , renderflags ) ,
DEFINE_FLAG ( RF , FORCEXYBILLBOARD , AActor , renderflags ) ,
2016-05-01 13:45:50 +00:00
DEFINE_FLAG ( RF , ROLLSPRITE , AActor , renderflags ) , // [marrub] roll the sprite billboard
// [fgsfds] Flat sprites
DEFINE_FLAG ( RF , FLATSPRITE , AActor , renderflags ) ,
DEFINE_FLAG ( RF , WALLSPRITE , AActor , renderflags ) ,
2016-06-05 20:21:19 +00:00
DEFINE_FLAG ( RF , DONTFLIP , AActor , renderflags ) ,
2016-07-04 18:58:49 +00:00
DEFINE_FLAG ( RF , ROLLCENTER , AActor , renderflags ) ,
2016-09-18 20:07:08 +00:00
DEFINE_FLAG ( RF , MASKROTATION , AActor , renderflags ) ,
DEFINE_FLAG ( RF , ABSMASKANGLE , AActor , renderflags ) ,
DEFINE_FLAG ( RF , ABSMASKPITCH , AActor , renderflags ) ,
2016-03-01 15:47:10 +00:00
// Bounce flags
DEFINE_FLAG2 ( BOUNCE_Walls , BOUNCEONWALLS , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_Floors , BOUNCEONFLOORS , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_Ceilings , BOUNCEONCEILINGS , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_Actors , ALLOWBOUNCEONACTORS , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_AutoOff , BOUNCEAUTOOFF , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_HereticType , BOUNCELIKEHERETIC , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_CanBounceWater , CANBOUNCEWATER , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_NoWallSound , NOWALLBOUNCESND , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_Quiet , NOBOUNCESOUND , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_AllActors , BOUNCEONACTORS , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_ExplodeOnWater , EXPLODEONWATER , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_MBF , MBFBOUNCER , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_AutoOffFloorOnly , BOUNCEAUTOOFFFLOORONLY , AActor , BounceFlags ) ,
DEFINE_FLAG2 ( BOUNCE_UseBounceState , USEBOUNCESTATE , AActor , BounceFlags ) ,
2016-11-03 23:19:36 +00:00
{ 0xffffffff }
2016-10-25 11:29:58 +00:00
} ;
// These won't be accessible through bitfield variables
static FFlagDef MoreFlagDefs [ ] =
{
2016-03-01 15:47:10 +00:00
// Deprecated flags. Handling must be performed in HandleDeprecatedFlags
DEFINE_DEPRECATED_FLAG ( FIREDAMAGE ) ,
DEFINE_DEPRECATED_FLAG ( ICEDAMAGE ) ,
DEFINE_DEPRECATED_FLAG ( LOWGRAVITY ) ,
DEFINE_DEPRECATED_FLAG ( SHORTMISSILERANGE ) ,
DEFINE_DEPRECATED_FLAG ( LONGMELEERANGE ) ,
DEFINE_DEPRECATED_FLAG ( QUARTERGRAVITY ) ,
DEFINE_DEPRECATED_FLAG ( FIRERESIST ) ,
DEFINE_DEPRECATED_FLAG ( HERETICBOUNCE ) ,
DEFINE_DEPRECATED_FLAG ( HEXENBOUNCE ) ,
DEFINE_DEPRECATED_FLAG ( DOOMBOUNCE ) ,
// Deprecated flags with no more existing functionality.
2016-10-24 15:18:20 +00:00
DEFINE_DUMMY_FLAG ( FASTER , true ) , // obsolete, replaced by 'Fast' state flag
DEFINE_DUMMY_FLAG ( FASTMELEE , true ) , // obsolete, replaced by 'Fast' state flag
2016-03-01 15:47:10 +00:00
// Various Skulltag flags that are quite irrelevant to ZDoom
2016-10-24 15:18:20 +00:00
DEFINE_DUMMY_FLAG ( NONETID , false ) , // netcode-based
DEFINE_DUMMY_FLAG ( ALLOWCLIENTSPAWN , false ) , // netcode-based
DEFINE_DUMMY_FLAG ( CLIENTSIDEONLY , false ) , // netcode-based
DEFINE_DUMMY_FLAG ( SERVERSIDEONLY , false ) , // netcode-based
DEFINE_DUMMY_FLAG ( EXPLODEONDEATH , true ) , // seems useless
DEFINE_FLAG2_DEPRECATED ( MF4_DONTHARMCLASS , DONTHURTSPECIES , AActor , flags4 ) , // Deprecated name as an alias
2016-03-01 15:47:10 +00:00
} ;
static FFlagDef InventoryFlagDefs [ ] =
{
// Inventory flags
DEFINE_FLAG ( IF , QUIET , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , AUTOACTIVATE , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , UNDROPPABLE , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , INVBAR , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , HUBPOWER , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , UNTOSSABLE , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , ADDITIVETIME , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , ALWAYSPICKUP , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , FANCYPICKUPSOUND , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , BIGPOWERUP , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , KEEPDEPLETED , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , IGNORESKILL , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , NOATTENPICKUPSOUND , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , PERSISTENTPOWER , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , RESTRICTABSOLUTELY , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , NEVERRESPAWN , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , NOSCREENFLASH , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , TOSSED , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , ALWAYSRESPAWN , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , TRANSFER , AInventory , ItemFlags ) ,
DEFINE_FLAG ( IF , NOTELEPORTFREEZE , AInventory , ItemFlags ) ,
DEFINE_DEPRECATED_FLAG ( PICKUPFLASH ) ,
DEFINE_DEPRECATED_FLAG ( INTERHUBSTRIP ) ,
2016-11-19 08:24:54 +00:00
{ 0xffffffff }
2016-03-01 15:47:10 +00:00
} ;
2016-11-19 00:23:56 +00:00
FFlagDef WeaponFlagDefs [ ] =
2016-03-01 15:47:10 +00:00
{
// Weapon flags
DEFINE_FLAG ( WIF , NOAUTOFIRE , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , READYSNDHALF , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , DONTBOB , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , AXEBLOOD , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , NOALERT , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , AMMO_OPTIONAL , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , ALT_AMMO_OPTIONAL , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , PRIMARY_USES_BOTH , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , WIMPY_WEAPON , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , POWERED_UP , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , STAFF2_KICKBACK , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF_BOT , EXPLOSIVE , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , MELEEWEAPON , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF_BOT , BFG , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , CHEATNOTWEAPON , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , NO_AUTO_SWITCH , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , AMMO_CHECKBOTH , AWeapon , WeaponFlags ) ,
DEFINE_FLAG ( WIF , NOAUTOAIM , AWeapon , WeaponFlags ) ,
2016-07-22 14:37:32 +00:00
DEFINE_FLAG ( WIF , NODEATHDESELECT , AWeapon , WeaponFlags ) ,
2016-07-01 21:43:30 +00:00
DEFINE_FLAG ( WIF , NODEATHINPUT , AWeapon , WeaponFlags ) ,
2016-03-01 15:47:10 +00:00
DEFINE_FLAG ( WIF , ALT_USES_BOTH , AWeapon , WeaponFlags ) ,
2016-11-19 00:23:56 +00:00
DEFINE_DUMMY_FLAG ( NOLMS , false ) ,
2016-10-24 15:18:20 +00:00
DEFINE_DUMMY_FLAG ( ALLOW_WITH_RESPAWN_INVUL , false ) ,
2016-11-19 08:24:54 +00:00
{ 0xffffffff }
2016-03-01 15:47:10 +00:00
} ;
2016-11-19 00:23:56 +00:00
2016-03-01 15:47:10 +00:00
static FFlagDef PlayerPawnFlagDefs [ ] =
{
// PlayerPawn flags
DEFINE_FLAG ( PPF , NOTHRUSTWHENINVUL , APlayerPawn , PlayerFlags ) ,
DEFINE_FLAG ( PPF , CANSUPERMORPH , APlayerPawn , PlayerFlags ) ,
DEFINE_FLAG ( PPF , CROUCHABLEMORPH , APlayerPawn , PlayerFlags ) ,
2016-11-19 08:24:54 +00:00
{ 0xffffffff }
2016-03-01 15:47:10 +00:00
} ;
static FFlagDef PowerSpeedFlagDefs [ ] =
{
// PowerSpeed flags
DEFINE_FLAG ( PSF , NOTRAIL , APowerSpeed , SpeedFlags ) ,
2016-11-19 08:24:54 +00:00
{ 0xffffffff }
2016-03-01 15:47:10 +00:00
} ;
static const struct FFlagList { const PClass * const * Type ; FFlagDef * Defs ; int NumDefs ; } FlagLists [ ] =
{
2016-11-03 23:19:36 +00:00
{ & RUNTIME_CLASS_CASTLESS ( AActor ) , ActorFlagDefs , countof ( ActorFlagDefs ) - 1 } , // -1 to account for the terminator
2016-10-24 15:18:20 +00:00
{ & RUNTIME_CLASS_CASTLESS ( AActor ) , MoreFlagDefs , countof ( MoreFlagDefs ) } ,
2016-11-19 08:24:54 +00:00
{ & RUNTIME_CLASS_CASTLESS ( AInventory ) , InventoryFlagDefs , countof ( InventoryFlagDefs ) - 1 } ,
{ & RUNTIME_CLASS_CASTLESS ( AWeapon ) , WeaponFlagDefs , countof ( WeaponFlagDefs ) - 1 } ,
{ & RUNTIME_CLASS_CASTLESS ( APlayerPawn ) , PlayerPawnFlagDefs , countof ( PlayerPawnFlagDefs ) - 1 } ,
{ & RUNTIME_CLASS_CASTLESS ( APowerSpeed ) , PowerSpeedFlagDefs , countof ( PowerSpeedFlagDefs ) - 1 } ,
2016-03-01 15:47:10 +00:00
} ;
# define NUM_FLAG_LISTS (countof(FlagLists))
//==========================================================================
//
// Find a flag by name using a binary search
//
//==========================================================================
static FFlagDef * FindFlag ( FFlagDef * flags , int numflags , const char * flag )
{
int min = 0 , max = numflags - 1 ;
while ( min < = max )
{
int mid = ( min + max ) / 2 ;
int lexval = stricmp ( flag , flags [ mid ] . name ) ;
if ( lexval = = 0 )
{
return & flags [ mid ] ;
}
else if ( lexval > 0 )
{
min = mid + 1 ;
}
else
{
max = mid - 1 ;
}
}
return NULL ;
}
//==========================================================================
//
// Finds a flag that may have a qualified name
//
//==========================================================================
2016-10-10 22:56:47 +00:00
FFlagDef * FindFlag ( const PClass * type , const char * part1 , const char * part2 , bool strict )
2016-03-01 15:47:10 +00:00
{
FFlagDef * def ;
if ( part2 = = NULL )
{ // Search all lists
2016-10-24 15:18:20 +00:00
int max = strict ? 2 : NUM_FLAG_LISTS ;
2016-10-27 22:32:52 +00:00
for ( int i = 0 ; i < max ; + + i )
2016-03-01 15:47:10 +00:00
{
if ( type - > IsDescendantOf ( * FlagLists [ i ] . Type ) )
{
def = FindFlag ( FlagLists [ i ] . Defs , FlagLists [ i ] . NumDefs , part1 ) ;
if ( def ! = NULL )
{
return def ;
}
}
}
}
else
{ // Search just the named list
2016-10-27 22:32:52 +00:00
for ( size_t i = 0 ; i < NUM_FLAG_LISTS ; + + i )
2016-03-01 15:47:10 +00:00
{
if ( stricmp ( ( * FlagLists [ i ] . Type ) - > TypeName . GetChars ( ) , part1 ) = = 0 )
{
if ( type - > IsDescendantOf ( * FlagLists [ i ] . Type ) )
{
return FindFlag ( FlagLists [ i ] . Defs , FlagLists [ i ] . NumDefs , part2 ) ;
}
else
{
return NULL ;
}
}
}
}
return NULL ;
}
//==========================================================================
//
// Gets the name of an actor flag
//
//==========================================================================
const char * GetFlagName ( unsigned int flagnum , int flagoffset )
{
for ( size_t i = 0 ; i < countof ( ActorFlagDefs ) ; i + + )
{
if ( ActorFlagDefs [ i ] . flagbit = = flagnum & & ActorFlagDefs [ i ] . structoffset = = flagoffset )
{
return ActorFlagDefs [ i ] . name ;
}
}
return " (unknown) " ; // return something printable
}
//==========================================================================
//
// Find a property by name using a binary search
//
//==========================================================================
FPropertyInfo * FindProperty ( const char * string )
{
int min = 0 , max = properties . Size ( ) - 1 ;
while ( min < = max )
{
int mid = ( min + max ) / 2 ;
int lexval = stricmp ( string , properties [ mid ] - > name ) ;
if ( lexval = = 0 )
{
return properties [ mid ] ;
}
else if ( lexval > 0 )
{
min = mid + 1 ;
}
else
{
max = mid - 1 ;
}
}
return NULL ;
}
//==========================================================================
//
// Find a function by name using a binary search
//
//==========================================================================
2016-11-19 11:12:29 +00:00
AFuncDesc * FindFunction ( PStruct * cls , const char * string )
2016-03-01 15:47:10 +00:00
{
2016-11-16 00:36:21 +00:00
for ( int i = 0 ; i < 2 ; i + + )
2016-03-01 15:47:10 +00:00
{
2016-11-21 18:09:58 +00:00
// Since many functions have been declared with Actor as owning class, despite being members of something else, let's hack around this until they have been fixed or exported.
2016-11-19 11:12:29 +00:00
// Since most of these are expected to be scriptified anyway, there's no point fixing them all before they get exported.
2016-11-21 18:09:58 +00:00
if ( i = = 1 )
{
if ( ! cls - > IsKindOf ( RUNTIME_CLASS ( PClassActor ) ) ) break ;
cls = RUNTIME_CLASS ( AActor ) ;
}
2016-11-19 11:12:29 +00:00
2016-11-16 00:36:21 +00:00
int min = 0 , max = AFTable . Size ( ) - 1 ;
while ( min < = max )
2016-03-01 15:47:10 +00:00
{
2016-11-16 00:36:21 +00:00
int mid = ( min + max ) / 2 ;
2016-11-21 18:09:58 +00:00
int lexval = stricmp ( cls - > TypeName . GetChars ( ) , AFTable [ mid ] . ClassName + 1 ) ;
if ( lexval = = 0 ) lexval = stricmp ( string , AFTable [ mid ] . FuncName ) ;
2016-11-16 00:36:21 +00:00
if ( lexval = = 0 )
{
return & AFTable [ mid ] ;
}
else if ( lexval > 0 )
{
min = mid + 1 ;
}
else
{
max = mid - 1 ;
}
2016-03-01 15:47:10 +00:00
}
}
2016-11-16 00:36:21 +00:00
return nullptr ;
2016-03-01 15:47:10 +00:00
}
//==========================================================================
//
// Find an action function in AActor's table
//
//==========================================================================
2016-11-06 10:36:12 +00:00
VMFunction * FindVMFunction ( PClass * cls , const char * name )
2016-03-01 15:47:10 +00:00
{
2016-11-06 10:36:12 +00:00
auto f = dyn_cast < PFunction > ( cls - > Symbols . FindSymbol ( name , true ) ) ;
return f = = nullptr ? nullptr : f - > Variants [ 0 ] . Implementation ;
2016-03-01 15:47:10 +00:00
}
//==========================================================================
//
// Sorting helpers
//
//==========================================================================
2016-04-11 08:46:30 +00:00
static int flagcmp ( const void * a , const void * b )
2016-03-01 15:47:10 +00:00
{
return stricmp ( ( ( FFlagDef * ) a ) - > name , ( ( FFlagDef * ) b ) - > name ) ;
}
2016-04-11 08:46:30 +00:00
static int propcmp ( const void * a , const void * b )
2016-03-01 15:47:10 +00:00
{
return stricmp ( ( * ( FPropertyInfo * * ) a ) - > name , ( * ( FPropertyInfo * * ) b ) - > name ) ;
}
2016-04-11 08:46:30 +00:00
static int funccmp ( const void * a , const void * b )
2016-03-01 15:47:10 +00:00
{
2016-11-21 18:09:58 +00:00
// +1 to get past the prefix letter of the native class name, which gets omitted by the FName for the class.
int res = stricmp ( ( ( AFuncDesc * ) a ) - > ClassName + 1 , ( ( AFuncDesc * ) b ) - > ClassName + 1 ) ;
if ( res = = 0 ) res = stricmp ( ( ( AFuncDesc * ) a ) - > FuncName , ( ( AFuncDesc * ) b ) - > FuncName ) ;
return res ;
2016-03-01 15:47:10 +00:00
}
//==========================================================================
//
// Initialization
//
//==========================================================================
2016-11-03 23:19:36 +00:00
void G_InitLevelLocalsForScript ( ) ;
2016-11-17 23:42:04 +00:00
void P_InitPlayerForScript ( ) ;
2016-03-01 15:47:10 +00:00
void InitThingdef ( )
{
2016-11-19 08:24:54 +00:00
PType * TypeActor = NewPointer ( RUNTIME_CLASS ( AActor ) ) ;
PStruct * sstruct = NewStruct ( " Sector " , nullptr ) ;
auto sptr = NewPointer ( sstruct ) ;
sstruct - > AddNativeField ( " soundtarget " , TypeActor , myoffsetof ( sector_t , SoundTarget ) ) ;
G_InitLevelLocalsForScript ( ) ;
P_InitPlayerForScript ( ) ;
FAutoSegIterator probe ( CRegHead , CRegTail ) ;
while ( * + + probe ! = NULL )
{
if ( ( ( ClassReg * ) * probe ) - > InitNatives )
( ( ClassReg * ) * probe ) - > InitNatives ( ) ;
}
2016-03-01 15:47:10 +00:00
// Sort the flag lists
for ( size_t i = 0 ; i < NUM_FLAG_LISTS ; + + i )
{
qsort ( FlagLists [ i ] . Defs , FlagLists [ i ] . NumDefs , sizeof ( FFlagDef ) , flagcmp ) ;
}
// Create a sorted list of properties
if ( properties . Size ( ) = = 0 )
{
FAutoSegIterator probe ( GRegHead , GRegTail ) ;
while ( * + + probe ! = NULL )
{
properties . Push ( ( FPropertyInfo * ) * probe ) ;
}
properties . ShrinkToFit ( ) ;
qsort ( & properties [ 0 ] , properties . Size ( ) , sizeof ( properties [ 0 ] ) , propcmp ) ;
}
// Create a sorted list of native action functions
AFTable . Clear ( ) ;
if ( AFTable . Size ( ) = = 0 )
{
FAutoSegIterator probe ( ARegHead , ARegTail ) ;
while ( * + + probe ! = NULL )
{
AFuncDesc * afunc = ( AFuncDesc * ) * probe ;
assert ( afunc - > VMPointer ! = NULL ) ;
2016-11-21 18:09:58 +00:00
* ( afunc - > VMPointer ) = new VMNativeFunction ( afunc - > Function , afunc - > FuncName ) ;
( * ( afunc - > VMPointer ) ) - > PrintableName . Format ( " %s.%s [Native] " , afunc - > ClassName + 1 , afunc - > FuncName ) ;
2016-03-01 15:47:10 +00:00
AFTable . Push ( * afunc ) ;
}
AFTable . ShrinkToFit ( ) ;
qsort ( & AFTable [ 0 ] , AFTable . Size ( ) , sizeof ( AFTable [ 0 ] ) , funccmp ) ;
}
}