daily pastebin goal
45%
SHARE
TWEET

blizzard.cpp

a guest Aug 7th, 2011 279 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**********************************************************************
  2.  *<                            
  3.  
  4.    FILE: Blizzard.CPP
  5.    DESCRIPTION: SuperSpray and Blizzard main code
  6.  
  7.    CREATED BY: Audrey Peterson  
  8.  
  9.    HISTORY: created November 1996
  10.    Instancing Geometry 1/97
  11.    IPC 8/98
  12.  
  13.  *>   Copyright (c) 1996, All Rights Reserved.
  14.  **********************************************************************/
  15. #include <io.h>
  16. #include "SuprPrts.h"
  17. #include "iparamm.h"
  18. #include "interpik.h"
  19. #include "texutil.h"
  20. #include "stdmat.h"
  21. #include "macrorec.h"
  22.  
  23. #include "3dsmaxport.h"
  24.  
  25. // russom - 10/11/01
  26. #if !defined(NO_PARTICLES_BLIZZARD) && !defined(NO_PARTICLES_SUPERSPRAY)
  27.  
  28. #define EPSILON            0.0001f
  29. #define MAX_PATH_LENGTH    257
  30. #define MAX_STRING_LENGTH  256
  31. #define PARTICLE_SEED      0x8d6a65bc
  32.  
  33. #define PBLK         0
  34. #define CUSTNODE     1
  35.  
  36. #define BASER 2
  37.  
  38. typedef struct
  39. {
  40.    float Vsz,Ts,Ts0,LamTs,A,LamA,To;
  41.    float M,Dis,Fo,Mltvar,pvar;
  42.    int themtl,gennum,SpVar;
  43.    TimeValue L,showframe,DL,persist;
  44.    Point3   V,W,RV;
  45. }  CSavePt;
  46.  
  47. typedef struct
  48. {
  49.    float Size,VSz,VSpin,Phase,VPhase,Speed,VSpeed;
  50.    float width,bstr,bstrvar,ToAmp,VToAmp,axisvar;
  51.    float ToPhase,VToPhase,VToPeriod,Av180,Ah180,VAv,VAh,pvar;
  52.    int axisentered;
  53.    Point3 Ve,Axis;
  54.    TimeValue Spin,ToPeriod,Life,Vl,persist;
  55.    BirthPositionSpeed bps;
  56. }  VelDir;
  57.  
  58. static Class_ID SUPRSPRAY_CLASS_ID(0x74f811e3, 0x21fb7b57);
  59. static Class_ID BLIZZARD_CLASS_ID(0x5835054d, 0x564b40ed);
  60.  
  61. class CPickOperand;
  62. class CommonParticle;
  63.  
  64. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  65. //        WARNING - a copy of this class description is in maxscrpt\maxnode.cpp
  66. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  67. class CommonParticleDraw : public CustomParticleDisplay {
  68.    public:
  69.       float tumble,scale;
  70.       BOOL firstpart;
  71.       CommonParticle *obj;
  72.       int disptype,ptype,bb,anifr,anioff;
  73.       boxlst *bboxpt;
  74.       TimeValue t;
  75.       InDirInfo indir;
  76.  
  77.       CommonParticleDraw() {obj=NULL;}
  78.       BOOL DrawParticle(GraphicsWindow *gw,ParticleSys &parts,int i);
  79.    };
  80.  
  81. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  82. //       WARNING - a copy of this class description is in maxscrpt\maxnode.cpp
  83. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  84. class CommonParticle : public SimpleParticle, IParamArray {
  85.    public:
  86.       CommonParticleDraw theSuprSprayDraw;
  87.       static IParamMap *pmapParam;
  88.       static IParamMap *pmapPGen;
  89.       static IParamMap *pmapPType;
  90.       static IParamMap *pmapPSpin;
  91.       static IParamMap *pmapEmitV;
  92.       static IParamMap *pmapSpawn;
  93.       int stepSize,size;
  94.       static int custsettings;
  95.       ULONG dflags;
  96.       Mesh *cmesh, *dispmesh;
  97.       INode *custnode, *cnode;
  98.       TSTR custname;
  99.       DWORD flags;
  100.       BOOL cancelled,wasmulti;
  101.       static BOOL creating;
  102.       static CPickOperand pickCB;
  103.       Mtl *origmtl;
  104.  
  105.       Point3 boxcenter;
  106.       int CustMtls;
  107.       TimeLst times;
  108.       void GetTimes(TimeLst &times,TimeValue t,int anifr,int ltype);
  109.       void TreeDoGroup(INode *node,Matrix3 tspace,Mesh *cmesh,int *numV,int *numF,int *tvnum,int *ismapped,TimeValue t,int subtree,int custmtl);
  110.       void CheckTree(INode *node,Matrix3 tspace,Mesh *cmesh,int *numV,int *numF,int *tvnum,int *ismapped,TimeValue t,int subtree,int custmtl);
  111.       void GetMesh(TimeValue t,int subtree,int custmtl);
  112.       void GetNextBB(INode *node,int subtree,int *count,int *tabmax,Point3 boxcenter,TimeValue t,int tcount,INode *onode);
  113.       void DoGroupBB(INode *node,int subtree,int *count,int *tabmax,Point3 boxcenter,TimeValue t,int tcount,INode *onode);
  114.       void GetallBB(INode *custnode,int subtree,TimeValue t);
  115.  
  116.       Tab<int> nmtls;
  117.       void DoSpawn(int j,int spmult,SpawnVars spvars,TimeValue lvar,BOOL emit);
  118.       void SetUpList();
  119.       void AddToList(INode *newnode,int i,BOOL add);
  120.       void DeleteFromList(int nnum,BOOL all);
  121.       Tab<INode*> nlist;
  122.       Tab<int> llist;
  123.       int deftime;
  124.       int maincount,rseed;
  125.       int NumRefs() {return BASER+nlist.Count();}
  126.       RefTargetHandle GetReference(int i);
  127.       void SetReference(int i, RefTargetHandle rtarg);      
  128.       RefResult NotifyRefChanged( Interval changeInt,RefTargetHandle hTarget,
  129.          PartID& partID, RefMessage message);
  130.       void SetUpLifeList();
  131.       void AddToLifeList(int newlife);
  132.       void DeleteFromLifeList(int nnum);
  133.       void ShowName();
  134.       static AName *NameLst;
  135.       static HWND hParams2,hptype,hgen,hparam,hrot,spawn;
  136.       static ICustEdit *custCtrlEdit;
  137.       void ResetSystem(TimeValue t,BOOL full=TRUE);
  138.  
  139.       void GetWorldBoundBox(TimeValue t, INode *inode, ViewExp* vpt, Box3& box);
  140.       int CountLive();
  141.       int rcounter,vcounter;
  142.       oldipc lc;
  143.       static IObjParam *ip;
  144.       // Animatable methods      
  145.       void DeleteThis() {delete this;}
  146.       void MapKeys(TimeMap *map,DWORD flags);
  147.       int RenderBegin(TimeValue t, ULONG flags);      
  148.       int RenderEnd(TimeValue t);
  149.  
  150.       // From SimpleParticle
  151.       Interval GetValidity(TimeValue t);    
  152.       BOOL EmitterVisible();    
  153.       MarkerType GetMarkerType();  
  154.       CSavePt *sdata;
  155.  
  156.       // From BaseObject
  157.       int IsInstanceDependent() {return 1;}
  158.       Matrix3 TumbleMat(int index,float amount, float scale);
  159.       void GetFilename(TCHAR *filename);
  160.       void SetupTargetList();
  161.       int SaveSettings(int overwrite,TCHAR *newname);
  162.       int GetSettings(int setnum,TCHAR *newname);
  163.       int RemSettings(int setnum,TCHAR *newname);
  164.       IOResult Load(ILoad *iload);
  165.       IOResult Save(ISave *isave);
  166.       void AssignMtl(INode *node,INode *topnode,int subtree,TimeValue t);
  167.       void DoGroupMtls(INode *node,int subtree,int *numsubs,int *numtabs,int *tabmax,TimeValue t);
  168.       void RetrieveMtls(INode *node,int subtree,int *numsubs,int *numtabs,int *tabmax,TimeValue t);
  169.       void GetSubs(INode *node,INode *topnode,int subtree,TimeValue t);
  170.       void CntDoGroupMtls(INode *node,int subtree,int *numsubs,int *numtabs,int *tabmax,TimeValue t);
  171.       void CntRetrieveMtls(INode *node,int subtree,int *numsubs,int *numtabs,int *tabmax,TimeValue t);
  172.       BOOL backpatch;
  173.       Mtllst mttab;
  174.       TimeValue ParticleLife(TimeValue t, int i);
  175.       int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags);
  176.       int HitTest(TimeValue t, INode *inode, int type, int crossing, int flags,
  177.       IPoint2 *p, ViewExp *vpt);
  178.       TimeValue dispt;
  179.    };
  180.  
  181. class SuprSprayParticle : public CommonParticle {
  182.    public:
  183.       SuprSprayParticle();
  184.       ~SuprSprayParticle();
  185.       static IParamMap *pmapBubl;
  186.       static HWND hbubl;
  187.       CreateMouseCallBack* GetCreateMouseCallBack();
  188.  
  189.       TCHAR *GetObjectName();
  190.       void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);    
  191.       void EndEditParams( IObjParam *ip, ULONG flags,Animatable *next);    
  192.       void BuildEmitter(TimeValue t, Mesh& amesh);
  193.       void BirthParticle(INode *node,TimeValue bt,int num,VelDir* ptvel,Matrix3 tmlast);
  194.       BOOL ComputeParticleStart(TimeValue t0,int c);
  195.       // From GeomObject
  196.       Mesh* GetRenderMesh(TimeValue t, INode *inode, View& view, BOOL& needDelete);
  197.       // Animatable methods      
  198.       Class_ID ClassID() {return SUPRSPRAY_CLASS_ID;}
  199.       // From ref
  200.       RefTargetHandle Clone(RemapDir& remap);      
  201.  
  202.       // From Simple Particle
  203.       void UpdateParticles(TimeValue t,INode *node);
  204.       ParamDimension *GetParameterDim(int pbIndex);
  205.       TSTR GetParameterName(int pbIndex);
  206.       void InvalidateUI();
  207.       float ParticleSize(TimeValue t,int i);
  208.       int ParticleCenter(TimeValue t,int i);
  209.       Point3 ParticlePosition(TimeValue t,int i);
  210.       Point3 ParticleVelocity(TimeValue t,int i);    
  211.       void MovePart(int j,TimeValue dt,BOOL fullframe,int tpf);
  212.    };
  213. //--- ClassDescriptor and class vars ---------------------------------
  214.  
  215. class SuprSprayClassDesc:public ClassDesc {
  216.    public:
  217.    int         IsPublic() {return 1;}
  218.    void *         Create(BOOL loading = FALSE) {return new SuprSprayParticle;}
  219.    const TCHAR *  ClassName();
  220.    SClass_ID      SuperClassID() {return GEOMOBJECT_CLASS_ID;}
  221.    Class_ID    ClassID() {return SUPRSPRAY_CLASS_ID;}
  222.    const TCHAR*   Category();
  223.    int         BeginCreate(Interface *i);
  224.    int         EndCreate(Interface *i);
  225.    };
  226.  
  227. static SuprSprayClassDesc SuprSprayDesc;
  228. ClassDesc* GetSuprSprayDesc() {return &SuprSprayDesc;}
  229.  
  230. class CPickOperand :
  231.       public PickModeCallback,
  232.       public PickNodeCallback {
  233.    public:    
  234.       CommonParticle *po;
  235.       int dodist,repi;
  236.  
  237.       CPickOperand() {po=NULL;}
  238.  
  239.       BOOL HitTest(IObjParam *ip,HWND hWnd,ViewExp *vpt,IPoint2 m,int flags);
  240.       BOOL Pick(IObjParam *ip,ViewExp *vpt);
  241.  
  242.       void EnterMode(IObjParam *ip);
  243.       void ExitMode(IObjParam *ip);
  244.  
  245.       BOOL RightClick(IObjParam *ip, ViewExp *vpt) { return TRUE; }
  246.       BOOL Filter(INode *node);
  247.      
  248.       PickNodeCallback *GetFilter() {return this;}
  249.    };
  250. //--- ClassDescriptor and class vars ---------------------------------
  251. IParamMap *CommonParticle::pmapParam;
  252. IParamMap *CommonParticle::pmapPGen;
  253. IParamMap *CommonParticle::pmapPType;
  254. IParamMap *CommonParticle::pmapPSpin;
  255. IParamMap *CommonParticle::pmapEmitV;
  256. IParamMap *CommonParticle::pmapSpawn;
  257. IObjParam *CommonParticle::ip    = NULL;
  258. BOOL CommonParticle::creating    = FALSE;
  259. CPickOperand CommonParticle::pickCB;
  260. ICustEdit *CommonParticle::custCtrlEdit=NULL;
  261. int CommonParticle::custsettings=0;
  262. AName *CommonParticle::NameLst=NULL;
  263. HWND CommonParticle::hParams2;
  264. HWND CommonParticle::hgen;
  265. HWND CommonParticle::hptype;
  266. HWND CommonParticle::hparam;
  267. HWND CommonParticle::hrot;
  268. HWND CommonParticle::spawn;
  269.  
  270. IParamMap *SuprSprayParticle::pmapBubl;
  271. HWND SuprSprayParticle::hbubl;
  272.  
  273. class BlizzardParticle : public CommonParticle {
  274.    public:
  275.       BlizzardParticle();
  276.       ~BlizzardParticle();
  277.       CreateMouseCallBack* GetCreateMouseCallBack();
  278.  
  279.       TCHAR *GetObjectName();
  280.       void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);    
  281.       void EndEditParams( IObjParam *ip, ULONG flags,Animatable *next);    
  282.       void BuildEmitter(TimeValue t, Mesh& amesh);
  283.       void BirthParticle(INode *node,TimeValue bt,int num,VelDir* ptvel,Matrix3 tmlast);
  284.       BOOL ComputeParticleStart(TimeValue t0,int c);
  285.       // From GeomObject
  286.       Mesh* GetRenderMesh(TimeValue t, INode *inode, View& view, BOOL& needDelete);
  287.       // Animatable methods      
  288.       Class_ID ClassID() {return BLIZZARD_CLASS_ID;}
  289.       // From ref
  290.       RefTargetHandle Clone(RemapDir& remap);      
  291.  
  292.       // From Simple Particle
  293.       void UpdateParticles(TimeValue t,INode *node);
  294.       ParamDimension *GetParameterDim(int pbIndex);
  295.       TSTR GetParameterName(int pbIndex);
  296.       void InvalidateUI();
  297.       float ParticleSize(TimeValue t,int i);
  298.       int ParticleCenter(TimeValue t,int i);
  299.       Point3 ParticlePosition(TimeValue t,int i);
  300.       Point3 ParticleVelocity(TimeValue t,int i);    
  301.    };
  302. //--- ClassDescriptor and class vars ---------------------------------
  303.  
  304. class BlizzardClassDesc:public ClassDesc {
  305.    public:
  306.    int         IsPublic() {return 1;}
  307.    void *         Create(BOOL loading = FALSE) {return new BlizzardParticle();}
  308.    const TCHAR *  ClassName();
  309.    SClass_ID      SuperClassID() {return GEOMOBJECT_CLASS_ID;}
  310.    Class_ID    ClassID() {return BLIZZARD_CLASS_ID;}
  311.    const TCHAR*   Category();
  312.    int         BeginCreate(Interface *i);
  313.    int         EndCreate(Interface *i);
  314.    };
  315.  
  316. static BlizzardClassDesc BlizzardDesc;
  317. ClassDesc* GetBlizzardDesc() {return &BlizzardDesc;}
  318.  
  319. #define SIZEFACTOR (float(TIME_TICKSPERSEC)/120.0f)
  320.  
  321. //--- Parameter map/block descriptors -------------------------------
  322.  
  323. #define PB_OFFAXIS            0
  324. #define PB_AXISSPREAD         1
  325. #define PB_OFFPLANE           2
  326. #define PB_PLANESPREAD        3
  327. #define PB_SPEED           4
  328. #define PB_SPEEDVAR           5
  329.  
  330. #define PB_BIRTHMETHOD        6
  331. #define PB_PBIRTHRATE         7
  332. #define PB_PTOTALNUMBER       8
  333. #define PB_EMITSTART       9
  334. #define PB_EMITSTOP           10
  335. #define PB_DISPUNTIL       11
  336. #define PB_LIFE               12
  337. #define PB_LIFEVAR            13
  338. #define PB_SUBFRAMEMOVE       14
  339. #define PB_SUBFRAMETIME       15
  340. #define PB_SIZE               16
  341. #define PB_SIZEVAR            17
  342. #define PB_GROWTIME           18
  343. #define PB_FADETIME           19
  344. #define PB_RNDSEED            20
  345. #define PB_EMITRWID           21
  346. #define PB_EMITRHID           22
  347.  
  348. #define PB_PARTICLECLASS      23
  349. #define PB_PARTICLETYPE       24
  350. #define PB_METATENSION        25
  351. #define PB_METATENSIONVAR     26
  352. #define PB_METACOURSE         27
  353. #define PB_METAAUTOCOARSE     28
  354. #define PB_USESUBTREE         29
  355. #define PB_ANIMATIONOFFSET    30
  356. #define PB_OFFSETAMOUNT       31
  357. #define PB_VIEWPORTSHOWS      32
  358. #define PB_DISPLAYPORTION     33
  359. #define PB_MAPPINGTYPE        34
  360. #define PB_MAPPINGTIME        35
  361. #define PB_MAPPINGDIST        36
  362.                  
  363. #define PB_SPINTIME           37
  364. #define PB_SPINTIMEVAR        38
  365. #define PB_SPINPHASE       39
  366. #define PB_SPINPHASEVAR       40
  367. #define PB_SPINAXISTYPE       41
  368. #define PB_SPINAXISX       42
  369. #define PB_SPINAXISY       43
  370. #define PB_SPINAXISZ       44
  371. #define PB_SPINAXISVAR        45
  372.  
  373. #define PB_EMITVINFL       46
  374. #define PB_EMITVMULT       47
  375. #define PB_EMITVMULTVAR       48
  376.  
  377. #define PB_SPAWNTYPE       49
  378. #define PB_SPAWNGENS       50
  379. #define PB_SPAWNCOUNT         51
  380. #define PB_SPAWNDIRCHAOS      52
  381. #define PB_SPAWNSPEEDCHAOS    53
  382. #define PB_SPAWNSPEEDSIGN     54
  383. #define PB_SPAWNINHERITV      55
  384. #define PB_SPAWNSCALECHAOS    56
  385. #define PB_SPAWNSCALESIGN     57
  386. #define PB_SPAWNLIFEVLUE      58
  387. #define PB_SPAWNSPEEDFIXED    59
  388. #define PB_SPAWNSCALEFIXED    60
  389.  
  390. #define PB_BUBLAMP            61
  391. #define PB_BUBLAMPVAR         62
  392. #define PB_BUBLPER            63
  393. #define PB_BUBLPERVAR         64
  394. #define PB_BUBLPHAS           65
  395. #define PB_BUBLPHASVAR        66
  396.  
  397. #define PB_STRETCH            67
  398. #define PB_CUSTOMMTL       68
  399. #define PB_METACOURSEV        69
  400. #define PB_SUBFRAMEROT        70
  401. #define PB_SPAWNPERCENT       71
  402. #define PB_SPAWNMULTVAR       72
  403. #define PB_SSNOTDRAFT         73
  404. #define PB_SSSPAWNDIEAFTER    74
  405. #define PB_SSSPAWNDIEAFTERVAR 75
  406.  
  407. #define PB_IPCOLLIDE_ON       76
  408. #define PB_IPCOLLIDE_STEPS    77
  409. #define PB_IPCOLLIDE_BOUNCE      78
  410. #define PB_IPCOLLIDE_BOUNCEVAR   79
  411.  
  412. // render types
  413. #define RENDMETA    8
  414. #define RENDGEOM  9
  415.  
  416. // Parameters
  417. #define ISSTD 0
  418. #define METABALLS 1
  419. #define INSTGEOM 2
  420.  
  421. static int countIDs[] = {IDC_SP_GENUSERATE,IDC_SP_GENUSETTL};
  422.  
  423. static int particleclassIDs[] = {IDC_SP_TYPESTD,IDC_SP_TYPEMET,IDC_SP_TYPEINSTANCE};
  424.  
  425. static int particletypeIDs[] = {IDC_SP_TYPETRI,IDC_SP_TYPECUB,IDC_SP_TYPESPC,IDC_SP_TYPEFAC,
  426.                         IDC_SP_TYPEPIX,IDC_SP_TYPETET,IDC_SP_TYPE6PNT,IDC_SP_TYPESPHERE};
  427.  
  428. static int viewportoptionIDs[] = {IDC_SP_VIEWDISPDOT,IDC_SP_VIEWDISPTIK,IDC_SP_VIEWDISPMESH,IDC_SP_VIEWDISPBOX};
  429.  
  430. static int mappingIDs[] = {IDC_SP_MAPTIME,IDC_SP_MAPDIST};
  431.  
  432. static int spindirectionIDs[] = {IDC_AP_PARTICLEDIRRND,IDC_AP_PARTICLEDIRTRAVL,IDC_AP_PARTICLEDIRUSER};
  433. static int bspindirectionIDs[] = {IDC_AP_PARTICLEDIRRND,IDC_AP_PARTICLEDIRUSER};
  434.  
  435. #define DIRTRAVEL 1
  436.  
  437. static int animateoffsetIDs[] = {IDC_AP_NOANIOFF,IDC_AP_ANIOFFBIRTH,IDC_AP_ANIOFFRND};
  438. static int custmtlIDs[] = {IDC_SP_MAPCUSTOMEMIT,IDC_SP_MAPCUSTOMINST};
  439.  
  440. // Dialog Unique to SuperSpray
  441. static ParamUIDesc descParamSuprSpray[] = {
  442.  
  443.    // Particle Off Axis
  444.    ParamUIDesc(
  445.       PB_OFFAXIS,
  446.       EDITTYPE_FLOAT,
  447.       IDC_SP_OFFAXIS,IDC_SP_OFFAXISSPIN,
  448.       -180.0f,180.0f,
  449.       1.0f,
  450.       stdAngleDim),
  451.  
  452.    // Particle Off Axis Spread
  453.    ParamUIDesc(
  454.       PB_AXISSPREAD,
  455.       EDITTYPE_FLOAT,
  456.       IDC_SP_OFFAXISVAR,IDC_SP_OFFAXISVARSPIN,
  457.       0.0f,180.0f,
  458.       1.0f,
  459.       stdAngleDim),
  460.  
  461.    // Particle Off Plane
  462.    ParamUIDesc(
  463.       PB_OFFPLANE,
  464.       EDITTYPE_FLOAT,
  465.       IDC_SP_OFFPLANE,IDC_SP_OFFPLANESPIN,
  466.       -180.0f,180.0f,
  467.       1.0f,
  468.       stdAngleDim),
  469.  
  470.    // Particle Off Plane Spread
  471.    ParamUIDesc(
  472.       PB_PLANESPREAD,
  473.       EDITTYPE_FLOAT,
  474.       IDC_SP_OFFPLANEVAR,IDC_SP_OFFPLANEVARSPIN,
  475.       0.0f,180.0f,
  476.       1.0f,
  477.       stdAngleDim),
  478.  
  479.    // Emitter Width
  480.    ParamUIDesc(
  481.       PB_EMITRWID,
  482.       EDITTYPE_UNIVERSE,
  483.       IDC_SP_EMITWID,IDC_SP_EMITWIDSPIN,
  484.       0.0f,999999999.0f,
  485.       SPIN_AUTOSCALE),  
  486.  
  487.    // Hide Emitter
  488.    ParamUIDesc(PB_EMITRHID,TYPE_SINGLECHEKBOX,IDC_SP_EMITHID),
  489.  
  490.    // Viewport Shows
  491.    ParamUIDesc(PB_VIEWPORTSHOWS,TYPE_RADIO,viewportoptionIDs,4),
  492.  
  493.    // Particle Display Portion
  494.    ParamUIDesc(
  495.       PB_DISPLAYPORTION,
  496.       EDITTYPE_FLOAT,
  497.       IDC_SP_GENDISP,IDC_SP_GENDISPSPIN,
  498.       0.0f,100.0f,
  499.       0.1f,
  500.       stdPercentDim),
  501. };
  502.  
  503. #define PARAMSuprSpray_LENGTH 8
  504.  
  505. // Common Dialog for Particle Generation
  506. static ParamUIDesc descParamPGen[] = {
  507.  
  508.    // Distribution Method
  509.    ParamUIDesc(PB_BIRTHMETHOD,TYPE_RADIO,countIDs,2),
  510.  
  511.    // Particle Birth Rate
  512.    ParamUIDesc(
  513.       PB_PBIRTHRATE,
  514.       EDITTYPE_INT,
  515.       IDC_SP_GENRATE,IDC_SP_GENRATESPIN,
  516.       0.0f,65000.0f,
  517.       1.0f),
  518.  
  519.    // Particle Total Count
  520.    ParamUIDesc(
  521.       PB_PTOTALNUMBER,
  522.       EDITTYPE_INT,
  523.       IDC_SP_GENTTL,IDC_SP_GENTTLSPIN,
  524.       0.0f,65000.0f,
  525.       1.0f),
  526.  
  527.    // Particle Speed
  528.    ParamUIDesc(
  529.       PB_SPEED,
  530.       EDITTYPE_UNIVERSE,
  531.       IDC_SP_SPEED,IDC_SP_SPEEDSPIN,
  532.       0.0f,999999999.0f,
  533.       SPIN_AUTOSCALE),
  534.  
  535.    // Particle Speed Var
  536.    ParamUIDesc(
  537.       PB_SPEEDVAR,
  538.       EDITTYPE_FLOAT,
  539.       IDC_SP_SPEEDVAR2,IDC_SP_SPEEDVARSPIN2,
  540.       0.0f,100.0f,
  541.       SPIN_AUTOSCALE,stdPercentDim),
  542.  
  543.    // Emitter Start Time
  544.    ParamUIDesc(
  545.       PB_EMITSTART,
  546.       EDITTYPE_TIME,
  547.       IDC_SP_GENEMIT1,IDC_SP_GENEMIT1SPIN,
  548.       -999999999.0f,999999999.0f,
  549.       10.0f),
  550.  
  551.    // Emitter Stop Time
  552.    ParamUIDesc(
  553.       PB_EMITSTOP,
  554.       EDITTYPE_TIME,
  555.       IDC_SP_GENEMIT2,IDC_SP_GENEMIT2SPIN,
  556.       -999999999.0f,999999999.0f,
  557.       10.0f),
  558.  
  559.    // Particle Time Limit
  560.    ParamUIDesc(
  561.       PB_DISPUNTIL,
  562.       EDITTYPE_TIME,
  563.       IDC_SP_DISPUNTIL,IDC_SP_DISPUNTILSPIN,
  564.       -999999999.0f,999999999.0f,
  565.       10.0f),
  566.  
  567.    // Particle Life
  568.    ParamUIDesc(
  569.       PB_LIFE,
  570.       EDITTYPE_TIME,
  571.       IDC_SP_GENLIFE,IDC_SP_GENLIFESPIN,
  572.       0.0f,999999999.0f,
  573.       10.0f),
  574.  
  575.    // Particle Life Var
  576.    ParamUIDesc(
  577.       PB_LIFEVAR,
  578.       EDITTYPE_TIME,
  579.       IDC_SP_GENLIFEVAR,IDC_SP_GENLIFEVARSPIN,
  580.       0.0f,999999999.0f,
  581.       10.0f),
  582.  
  583.    // Subframe Time and Motion Sampling
  584.    ParamUIDesc(PB_SUBFRAMEMOVE,TYPE_SINGLECHEKBOX,IDC_SP_GENSMPLMOVE),
  585.    ParamUIDesc(PB_SUBFRAMETIME,TYPE_SINGLECHEKBOX,IDC_SP_GENSMPLTIME),
  586.    ParamUIDesc(PB_SUBFRAMEROT,TYPE_SINGLECHEKBOX,IDC_SP_GENSMPLROT),
  587.  
  588.    // Particle Size
  589.    ParamUIDesc(
  590.       PB_SIZE,
  591.       EDITTYPE_UNIVERSE,
  592.       IDC_SP_GENSIZE,IDC_SP_GENSIZESPIN,
  593.       0.0f,999999999.0f,
  594.       SPIN_AUTOSCALE),
  595.  
  596.    // Particle Size Var
  597.    ParamUIDesc(
  598.       PB_SIZEVAR,
  599.       EDITTYPE_FLOAT,
  600.       IDC_SP_GENSIZEVAR,IDC_SP_GENSIZEVARSPIN,
  601.       0.0f,100.0f,
  602.       SPIN_AUTOSCALE,stdPercentDim),
  603.  
  604.    // Particle Grow Time
  605.    ParamUIDesc(
  606.       PB_GROWTIME,
  607.       EDITTYPE_TIME,
  608.       IDC_SP_GENGRO,IDC_SP_GENGROSPIN,
  609.       0.0f,999999999.0f,
  610.       10.0f),
  611.  
  612.    // Particle Fade Time
  613.    ParamUIDesc(
  614.       PB_FADETIME,
  615.       EDITTYPE_TIME,
  616.       IDC_SP_GENFAD,IDC_SP_GENFADSPIN,
  617.       0.0f,999999999.0f,
  618.       10.0f),
  619.  
  620.    // Random Number Seed
  621.    ParamUIDesc(
  622.       PB_RNDSEED,
  623.       EDITTYPE_INT,
  624.       IDC_SP_GENSEED,IDC_SP_GENSEEDSPIN,
  625.       0.0f,25000.0f,
  626.       1.0f),
  627. };
  628.  
  629. #define PARAMPGEN_LENGTH 18
  630.  
  631. // Particle Type for SuprSpray
  632. static ParamUIDesc descParamPType[] = {
  633.  
  634.    // Particle Class
  635.    ParamUIDesc(PB_PARTICLECLASS,TYPE_RADIO,particleclassIDs,3),
  636.  
  637.    // Particle Type
  638.    ParamUIDesc(PB_PARTICLETYPE,TYPE_RADIO,particletypeIDs,8),
  639.  
  640.    // Metaball Tension
  641.    ParamUIDesc(
  642.       PB_METATENSION,
  643.       EDITTYPE_FLOAT,
  644.       IDC_SP_METTENS,IDC_SP_METTENSSPIN,
  645.       0.1f,10.0f,
  646.       SPIN_AUTOSCALE),
  647.  
  648.    // Metaball Tension Variation
  649.    ParamUIDesc(
  650.       PB_METATENSIONVAR,
  651.       EDITTYPE_FLOAT,
  652.       IDC_SP_METTENSVAR,IDC_SP_METTENSVARSPIN,
  653.       0.0f,100.0f,
  654.       SPIN_AUTOSCALE,stdPercentDim),
  655.  
  656.    // Metaball Courseness
  657.    ParamUIDesc(
  658.       PB_METACOURSE,
  659.       EDITTYPE_UNIVERSE,
  660.       IDC_SP_METCOURSE,IDC_SP_METCOURSESPIN,
  661.       0.0f,999999999.0f,
  662.       SPIN_AUTOSCALE),
  663.  
  664.    // Metaball Courseness ViewPort
  665.    ParamUIDesc(
  666.       PB_METACOURSEV,
  667.       EDITTYPE_UNIVERSE,
  668.       IDC_SP_METCOURSEV,IDC_SP_METCOURSEVSPIN,
  669.       0.0f,999999999.0f,
  670.       SPIN_AUTOSCALE),
  671.  
  672.    // Metaball Auto Coarseness
  673.    ParamUIDesc(PB_METAAUTOCOARSE,TYPE_SINGLECHEKBOX,IDC_SP_AUTOCOARSE),
  674.  
  675.    // Display type
  676.    ParamUIDesc(PB_SSNOTDRAFT,TYPE_SINGLECHEKBOX,IDC_SP_DRAFTMODE),
  677.  
  678.    // Use Subtree Checkbox
  679.    ParamUIDesc(PB_USESUBTREE,TYPE_SINGLECHEKBOX,IDC_AP_USESUBTREE),
  680.  
  681.    // Display type
  682.    ParamUIDesc(PB_ANIMATIONOFFSET,TYPE_RADIO,animateoffsetIDs,3),
  683.  
  684.    // Animation Offset Amount
  685.    ParamUIDesc(
  686.       PB_OFFSETAMOUNT,
  687.       EDITTYPE_TIME,
  688.       IDC_AP_ANIRNDFR,IDC_AP_ANIRNDFRSPIN,
  689.       1.0f,999999999.0f,
  690.       10.0f),
  691.  
  692.    // Mapping Across
  693.    ParamUIDesc(PB_MAPPINGTYPE,TYPE_RADIO,mappingIDs,2),
  694.  
  695.    // Time Mapping Option
  696.    ParamUIDesc(
  697.       PB_MAPPINGTIME,
  698.       EDITTYPE_TIME,
  699.       IDC_SP_MAPTIMEVAL,IDC_SP_MAPTIMEVALSPIN,
  700.       1.0f,999999999.0f,
  701.       10.0f),
  702.  
  703.    // Distance Mapping Option
  704.    ParamUIDesc(
  705.       PB_MAPPINGDIST,
  706.       EDITTYPE_UNIVERSE,
  707.       IDC_SP_MAPDISTVAL,IDC_SP_MAPDISTVALSPIN,
  708.       0.1f,999999999.0f,
  709.       SPIN_AUTOSCALE),
  710.  
  711.    // Use Custom Mtl
  712.    ParamUIDesc(PB_CUSTOMMTL,TYPE_RADIO,custmtlIDs,2),
  713. };
  714.  
  715. #define PARAMPTYPE_LENGTH 15
  716.  
  717. // SS Dialog for Particle Spin
  718. static ParamUIDesc descParamPSpin[] = {
  719.  
  720.    // Spin Time
  721.    ParamUIDesc(
  722.       PB_SPINTIME,
  723.       EDITTYPE_TIME,
  724.       IDC_SP_SPIN,IDC_SP_SPINSPIN,
  725.       0.0f,999999999.0f,
  726.       10.0f),
  727.  
  728.    // Spin Time Var
  729.    ParamUIDesc(
  730.       PB_SPINTIMEVAR,
  731.       EDITTYPE_FLOAT,
  732.       IDC_SP_SPINVAR,IDC_SP_SPINVARSPIN,
  733.       0.0f,100.0f,
  734.       0.01f,
  735.       stdPercentDim),
  736.  
  737.    // Spin Phase
  738.    ParamUIDesc(
  739.       PB_SPINPHASE,
  740.       EDITTYPE_FLOAT,
  741.       IDC_SP_SPINPHA,IDC_SP_SPINPHASPIN,
  742.       -360.0f,360.0f,
  743.       0.01f,
  744.       stdAngleDim),
  745.  
  746.    // Spin Phase Variation
  747.    ParamUIDesc(
  748.       PB_SPINPHASEVAR,
  749.       EDITTYPE_FLOAT,
  750.       IDC_SP_SPINPHAVAR,IDC_SP_SPINPHAVARSPIN,
  751.       0.0f,100.0f,
  752.       0.01f,
  753.       stdPercentDim),
  754.  
  755.    // Enter Axis Control
  756.    ParamUIDesc(PB_SPINAXISTYPE,TYPE_RADIO,spindirectionIDs,3),
  757.  
  758.    // X-Axis
  759.    ParamUIDesc(
  760.       PB_SPINAXISX,
  761.       EDITTYPE_FLOAT,
  762.       IDC_SP_SPINAXISX,IDC_SP_SPINAXISXSPIN,
  763.       -999999999.0f,999999999.0f,
  764.       SPIN_AUTOSCALE),
  765.  
  766.    // Y-Axis
  767.    ParamUIDesc(
  768.       PB_SPINAXISY,
  769.       EDITTYPE_FLOAT,
  770.       IDC_SP_SPINAXISY,IDC_SP_SPINAXISYSPIN,
  771.       -999999999.0f,999999999.0f,
  772.       SPIN_AUTOSCALE),
  773.  
  774.    // Z-Axis
  775.    ParamUIDesc(
  776.       PB_SPINAXISZ,
  777.       EDITTYPE_FLOAT,
  778.       IDC_SP_SPINAXISZ,IDC_SP_SPINAXISZSPIN,
  779.       -999999999.0f,999999999.0f,
  780.       SPIN_AUTOSCALE),
  781.  
  782.    // Spin Direction Variation
  783.    ParamUIDesc(
  784.       PB_SPINAXISVAR,
  785.       EDITTYPE_FLOAT,
  786.       IDC_SP_SPINAXISVAR,IDC_SP_SPINAXISVARSPIN,
  787.       -180.0f,180.0f,
  788.       0.01f,
  789.       stdAngleDim),
  790.  
  791.    // Stretch
  792.    ParamUIDesc(
  793.       PB_STRETCH,
  794.       EDITTYPE_INT,
  795.       IDC_AP_STRETCH,IDC_AP_STRETCHSPIN,
  796.       -1000.0f,1000.0f,
  797.       1.0f),
  798.  
  799.    // IPC Enable
  800.    ParamUIDesc(PB_IPCOLLIDE_ON,TYPE_SINGLECHEKBOX,IDC_INTERP_BOUNCEON),
  801.  
  802.    // IPC Steps
  803.    ParamUIDesc(
  804.       PB_IPCOLLIDE_STEPS,
  805.       EDITTYPE_INT,
  806.       IDC_INTERP_NSTEPS,IDC_INTERP_NSTEPSSPIN,
  807.       1.0f,1000.0f,
  808.       1.0f),
  809.  
  810.    // IPC Bounce
  811.    ParamUIDesc(
  812.       PB_IPCOLLIDE_BOUNCE,
  813.       EDITTYPE_FLOAT,
  814.       IDC_INTERP_BOUNCE,IDC_INTERP_BOUNCESPIN,
  815.       0.0f,10000.0f,
  816.       1.0f,
  817.       stdPercentDim),
  818.  
  819.    // IPC Bounce
  820.    ParamUIDesc(
  821.       PB_IPCOLLIDE_BOUNCEVAR,
  822.       EDITTYPE_FLOAT,
  823.       IDC_INTERP_BOUNCEVAR,IDC_INTERP_BOUNCEVARSPIN,
  824.       0.0f,100.0f,
  825.       1.0f,
  826.       stdPercentDim),
  827.  
  828. };
  829.  
  830. #define PARAMPSPIN_LENGTH 14
  831.  
  832. // Common Dialog for Secondary Motion Data
  833. static ParamUIDesc descParamEmitV[] = {
  834.  
  835.    // Emitter Velocity Inheritance Influence Portion
  836.    ParamUIDesc(
  837.       PB_EMITVINFL,
  838.       EDITTYPE_FLOAT,
  839.       IDC_SP_EMVI,IDC_SP_EMVISPIN,
  840.       0.0f,100.0f,
  841.       0.01f),
  842.  
  843.    // Secondary Motion Multiplier
  844.    ParamUIDesc(
  845.       PB_EMITVMULT,
  846.       EDITTYPE_FLOAT,
  847.       IDC_SP_EMVIMULT,IDC_SP_EMVIMULTSPIN,
  848.       -999999999.0f,999999999.0f,
  849.       SPIN_AUTOSCALE),
  850.  
  851.    // Multiplier Variation
  852.    ParamUIDesc(
  853.       PB_EMITVMULTVAR,
  854.       EDITTYPE_FLOAT,
  855.       IDC_SP_EMVIMULTVAR,IDC_SP_EMVIMULTVARSPIN,
  856.       0.0f,100.0f,
  857.       0.01f,
  858.       stdPercentDim),
  859.    };
  860. #define PARAMEMITV_LENGTH 3
  861.  
  862. // Common Dialog for Bubble Motion
  863. static ParamUIDesc descParamBubl[] = {
  864.  
  865.    // Bubble Amplitude
  866.    ParamUIDesc(
  867.       PB_BUBLAMP,
  868.       EDITTYPE_UNIVERSE,
  869.       IDC_SP_BUBL_AMP,IDC_SP_BUBL_AMPSPIN,
  870.       -.0f,999999999.0f,
  871.       SPIN_AUTOSCALE),
  872.  
  873.    // Bubble Amp Var
  874.    ParamUIDesc(
  875.       PB_BUBLAMPVAR,
  876.       EDITTYPE_FLOAT,
  877.       IDC_SP_BUBL_AMPVAR,IDC_SP_BUBL_AMPVARSPIN,
  878.       0.0f,100.0f,
  879.       0.01f,
  880.       stdPercentDim),
  881.  
  882.    // Bubble Period
  883.    ParamUIDesc(
  884.       PB_BUBLPER,
  885.       EDITTYPE_TIME,
  886.       IDC_SP_BUBL_PER,IDC_SP_BUBL_PERSPIN,
  887.       0.0f,999999999.0f,
  888.       10.0f),
  889.  
  890.    // Bubble Period Var
  891.    ParamUIDesc(
  892.       PB_BUBLPERVAR,
  893.       EDITTYPE_FLOAT,
  894.       IDC_SP_BUBL_PERVAR,IDC_SP_BUBL_PERVARSPIN,
  895.       0.0f,100.0f,
  896.       0.01f,
  897.       stdPercentDim),
  898.  
  899.    // Bubble Phase
  900.    ParamUIDesc(
  901.       PB_BUBLPHAS,
  902.       EDITTYPE_FLOAT,
  903.       IDC_SP_BUBL_PERPHA,IDC_SP_BUBL_PERPHASPIN,
  904.       -360.0f,360.0f,
  905.       0.01f,
  906.       stdAngleDim),
  907.  
  908.    // Bubble Phase Var
  909.    ParamUIDesc(
  910.       PB_BUBLPHASVAR,
  911.       EDITTYPE_FLOAT,
  912.       IDC_SP_BUBL_PERPHAVAR,IDC_SP_BUBL_PERPHAVARSPIN,
  913.       0.0f,100.0f,
  914.       0.01f,
  915.       stdPercentDim),
  916. };
  917. #define PARAMBUBL_LENGTH 6
  918.  
  919.  
  920. static int SpawnTypeIDs[] = {IDC_AP_NOSPAWN,IDC_AP_COLLIDEDIE,IDC_AP_COLLIDESPAWN,IDC_AP_DEATHSPAWN,IDC_AP_SPAWNTRAILS};
  921. static int SpeedChaosIDs[] = {IDC_AP_SPEEDLESS,IDC_AP_SPEEDMORE,IDC_AP_SPEEDBOTH};
  922. static int ScaleChaosIDs[] = {IDC_AP_SCALEDOWN,IDC_AP_SCALEUP,IDC_AP_SCALEBOTH};
  923.  
  924. // Dialog for Particle Spawning
  925. static ParamUIDesc descPSpawning[] = {
  926.    
  927.    // Spawing Effects Type
  928.    ParamUIDesc(PB_SPAWNTYPE,TYPE_RADIO,SpawnTypeIDs,5),
  929.  
  930.    // Die after X
  931.    ParamUIDesc(
  932.       PB_SSSPAWNDIEAFTER,
  933.       EDITTYPE_TIME,
  934.       IDC_AP_MAXSPAWNDIEAFTER,IDC_AP_MAXSPAWNDIEAFTERSPIN,
  935.       0.0f,999999999.0f,
  936.       10.0f),
  937.  
  938.    ParamUIDesc(
  939.       PB_SSSPAWNDIEAFTERVAR,
  940.       EDITTYPE_FLOAT,
  941.       IDC_AP_MAXSPAWNDIEAFTERVAR,IDC_AP_MAXSPAWNDIEAFTERVARSPIN,
  942.       0.0f,100.0f,
  943.       0.01f,
  944.       stdPercentDim),
  945.  
  946.    // Spawn Generations
  947.    ParamUIDesc(
  948.       PB_SPAWNGENS,
  949.       EDITTYPE_INT,
  950.       IDC_AP_MAXSPAWNGENS,IDC_AP_MAXSPAWNGENSSPIN,
  951.       1.0f,65000.0f,
  952.       1.0f),
  953.  
  954.    // Spawn Generations
  955.    ParamUIDesc(
  956.       PB_SPAWNPERCENT,
  957.       EDITTYPE_INT,
  958.       IDC_AP_PARENTPERCENT,IDC_AP_PARENTPERCENTSPIN,
  959.       1.0f,100.0f,
  960.       1.0f),
  961.  
  962.    // Spawn Spawncount
  963.    ParamUIDesc(
  964.       PB_SPAWNCOUNT,
  965.       EDITTYPE_INT,
  966.       IDC_AP_NUMBERVAR,IDC_AP_NUMBERVARSPIN,
  967.       1.0f,65000.0f,
  968.       1.0f),
  969.  
  970.    // Spawn Mult Percent
  971.    ParamUIDesc(
  972.       PB_SPAWNMULTVAR,
  973.       EDITTYPE_FLOAT,
  974.       IDC_AP_NUMBERVARVAR,IDC_AP_NUMBERVARVARSPIN,
  975.       0.0f,100.0f,
  976.       0.1f,stdPercentDim),
  977.  
  978.    // Spawn Direction Chaos
  979.    ParamUIDesc(
  980.       PB_SPAWNDIRCHAOS,
  981.       EDITTYPE_FLOAT,
  982.       IDC_AP_CHAOSANGLE,IDC_AP_CHAOSANGLESPIN,
  983.       0.0f,100.0f,
  984.       0.1f,stdPercentDim),
  985.  
  986.    // Spawn Speed Chaos
  987.    ParamUIDesc(
  988.       PB_SPAWNSPEEDCHAOS,
  989.       EDITTYPE_FLOAT,
  990.       IDC_AP_CHAOSSPEED,IDC_AP_CHAOSSPEEDSPIN,
  991.       0.0f,100.0f,
  992.       0.1f),
  993.  
  994.    // Spawing Speed Sign
  995.    ParamUIDesc(PB_SPAWNSPEEDSIGN,TYPE_RADIO,SpeedChaosIDs,3),
  996.  
  997.    // Spawning Inherit Parent V
  998.    ParamUIDesc(PB_SPAWNINHERITV,TYPE_SINGLECHEKBOX,IDC_AP_SPAWNSUMV),
  999.  
  1000.    // Spawning Speed Fixed
  1001.    ParamUIDesc(PB_SPAWNSPEEDFIXED,TYPE_SINGLECHEKBOX,IDC_AP_SPAWNSPEEDFIXED),
  1002.  
  1003.    // Spawn Scale Chaos
  1004.    ParamUIDesc(
  1005.       PB_SPAWNSCALECHAOS,
  1006.       EDITTYPE_FLOAT,
  1007.       IDC_AP_CHAOSSCALE,IDC_AP_CHAOSSCALESPIN,
  1008.       0.0f,100.0f,
  1009.       0.1f),
  1010.  
  1011.    // Spawning Scale Sign
  1012.    ParamUIDesc(PB_SPAWNSCALESIGN,TYPE_RADIO,ScaleChaosIDs,3),
  1013.  
  1014.    // Spawning Speed Fixed
  1015.    ParamUIDesc(PB_SPAWNSCALEFIXED,TYPE_SINGLECHEKBOX,IDC_AP_SPAWNSCALEFIXED),
  1016.  
  1017.    // Spawn Lifespan Entry Field
  1018.    ParamUIDesc(
  1019.       PB_SPAWNLIFEVLUE,
  1020.       EDITTYPE_INT,
  1021.       IDC_AP_QUEUELIFESPAN,IDC_AP_QUEUELIFESPANSPIN,
  1022.       0.0f,65000.0f,
  1023.       1.0f),
  1024. };
  1025. #define PSPAWNINGPARAMS_LENGTH 16
  1026.  
  1027. static ParamBlockDescID spdescVer0[] = {
  1028.    { TYPE_FLOAT, NULL, TRUE, 0 },    // off axis
  1029.    { TYPE_FLOAT, NULL, TRUE, 1 },    // axis apread
  1030.    { TYPE_FLOAT, NULL, TRUE, 2 },    // off plane
  1031.    { TYPE_FLOAT, NULL, TRUE, 3 },    // plane spread
  1032.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  1033.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  1034.  
  1035.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  1036.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  1037.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  1038.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  1039.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  1040.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  1041.    { TYPE_INT, NULL, TRUE, 12 },  // life
  1042.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  1043.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  1044.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  1045.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  1046.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  1047.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  1048.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  1049.    { TYPE_INT, NULL, FALSE, 20 }, // rnd seed
  1050.    { TYPE_FLOAT, NULL, FALSE, 21 },  // emitter width
  1051.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  1052.  
  1053.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  1054.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  1055.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  1056.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  1057.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  1058.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  1059.     { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  1060.     { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  1061.     { TYPE_INT, NULL, FALSE, 31 }, // offset amount
  1062.  
  1063.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  1064.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  1065.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  1066.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  1067.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  1068.  
  1069.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  1070.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  1071.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  1072.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  1073.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choice
  1074.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  1075.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  1076.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  1077.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  1078.  
  1079.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  1080.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  1081.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  1082.  
  1083.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  1084.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  1085.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  1086.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  1087.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  1088.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  1089.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  1090.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  1091.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  1092.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  1093.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  1094.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  1095.  
  1096.    { TYPE_FLOAT, NULL, TRUE, 61 },  // bubble amp61
  1097.    { TYPE_FLOAT, NULL, TRUE, 62 },  // bubble amp var
  1098.    { TYPE_INT, NULL, TRUE, 63 },  // bubble period
  1099.    { TYPE_FLOAT, NULL, TRUE, 64 },  // bubble period var
  1100.    { TYPE_FLOAT, NULL, TRUE, 65 },  // bubble phase
  1101.    { TYPE_FLOAT, NULL, TRUE, 66 },  // bubble phase var
  1102.  
  1103.    { TYPE_INT, NULL, TRUE, 67 },  // Stretch
  1104.    { TYPE_INT, NULL, FALSE, 68 },  // Custom Mtl
  1105. };
  1106.  
  1107. static ParamBlockDescID spdescVer1[] = {
  1108.    { TYPE_FLOAT, NULL, TRUE, 0 },    // off axis
  1109.    { TYPE_FLOAT, NULL, TRUE, 1 },    // axis apread
  1110.    { TYPE_FLOAT, NULL, TRUE, 2 },    // off plane
  1111.    { TYPE_FLOAT, NULL, TRUE, 3 },    // plane spread
  1112.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  1113.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  1114.  
  1115.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  1116.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  1117.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  1118.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  1119.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  1120.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  1121.    { TYPE_INT, NULL, TRUE, 12 },  // life
  1122.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  1123.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  1124.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  1125.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  1126.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  1127.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  1128.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  1129.    { TYPE_INT, NULL, FALSE, 20 }, // rnd seed
  1130.    { TYPE_FLOAT, NULL, FALSE, 21 },  // emitter width
  1131.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  1132.  
  1133.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  1134.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  1135.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  1136.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  1137.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  1138.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  1139.     { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  1140.     { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  1141.     { TYPE_INT, NULL, FALSE, 31 }, // offset amount
  1142.  
  1143.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  1144.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  1145.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  1146.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  1147.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  1148.  
  1149.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  1150.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  1151.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  1152.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  1153.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choice
  1154.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  1155.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  1156.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  1157.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  1158.  
  1159.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  1160.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  1161.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  1162.  
  1163.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  1164.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  1165.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  1166.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  1167.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  1168.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  1169.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  1170.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  1171.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  1172.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  1173.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  1174.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  1175.  
  1176.    { TYPE_FLOAT, NULL, TRUE, 61 },  // bubble amp61
  1177.    { TYPE_FLOAT, NULL, TRUE, 62 },  // bubble amp var
  1178.    { TYPE_INT, NULL, TRUE, 63 },  // bubble period
  1179.    { TYPE_FLOAT, NULL, TRUE, 64 },  // bubble period var
  1180.    { TYPE_FLOAT, NULL, TRUE, 65 },  // bubble phase
  1181.    { TYPE_FLOAT, NULL, TRUE, 66 },  // bubble phase var
  1182.  
  1183.    { TYPE_INT, NULL, TRUE, 67 },  // Stretch
  1184.    { TYPE_INT, NULL, FALSE, 68 },  // Custom Mtl
  1185.    { TYPE_FLOAT, NULL, FALSE, 69 },  // ViewPort Courseness
  1186. };
  1187.  
  1188. static ParamBlockDescID spdescVer2[] = {
  1189.    { TYPE_FLOAT, NULL, TRUE, 0 },    // off axis
  1190.    { TYPE_FLOAT, NULL, TRUE, 1 },    // axis apread
  1191.    { TYPE_FLOAT, NULL, TRUE, 2 },    // off plane
  1192.    { TYPE_FLOAT, NULL, TRUE, 3 },    // plane spread
  1193.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  1194.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  1195.  
  1196.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  1197.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  1198.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  1199.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  1200.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  1201.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  1202.    { TYPE_INT, NULL, TRUE, 12 },  // life
  1203.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  1204.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  1205.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  1206.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  1207.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  1208.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  1209.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  1210.    { TYPE_INT, NULL, FALSE, 20 }, // rnd seed
  1211.    { TYPE_FLOAT, NULL, FALSE, 21 },  // emitter width
  1212.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  1213.  
  1214.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  1215.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  1216.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  1217.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  1218.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  1219.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  1220.     { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  1221.     { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  1222.     { TYPE_INT, NULL, FALSE, 31 }, // offset amount
  1223.  
  1224.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  1225.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  1226.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  1227.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  1228.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  1229.  
  1230.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  1231.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  1232.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  1233.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  1234.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choice
  1235.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  1236.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  1237.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  1238.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  1239.  
  1240.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  1241.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  1242.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  1243.  
  1244.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  1245.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  1246.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  1247.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  1248.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  1249.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  1250.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  1251.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  1252.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  1253.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  1254.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  1255.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  1256.  
  1257.    { TYPE_FLOAT, NULL, TRUE, 61 },  // bubble amp61
  1258.    { TYPE_FLOAT, NULL, TRUE, 62 },  // bubble amp var
  1259.    { TYPE_INT, NULL, TRUE, 63 },  // bubble period
  1260.    { TYPE_FLOAT, NULL, TRUE, 64 },  // bubble period var
  1261.    { TYPE_FLOAT, NULL, TRUE, 65 },  // bubble phase
  1262.    { TYPE_FLOAT, NULL, TRUE, 66 },  // bubble phase var
  1263.  
  1264.    { TYPE_INT, NULL, TRUE, 67 },  // Stretch
  1265.    { TYPE_INT, NULL, FALSE, 68 },  // Custom Mtl
  1266.    { TYPE_FLOAT, NULL, FALSE, 69 },  // ViewPort Courseness
  1267.    { TYPE_INT, NULL, FALSE, 70 },  // Subframe rot
  1268. };
  1269.  
  1270. static ParamBlockDescID spdescVer3[] = {
  1271.    { TYPE_FLOAT, NULL, TRUE, 0 },    // off axis
  1272.    { TYPE_FLOAT, NULL, TRUE, 1 },    // axis apread
  1273.    { TYPE_FLOAT, NULL, TRUE, 2 },    // off plane
  1274.    { TYPE_FLOAT, NULL, TRUE, 3 },    // plane spread
  1275.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  1276.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  1277.  
  1278.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  1279.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  1280.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  1281.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  1282.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  1283.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  1284.    { TYPE_INT, NULL, TRUE, 12 },  // life
  1285.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  1286.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  1287.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  1288.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  1289.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  1290.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  1291.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  1292.    { TYPE_INT, NULL, FALSE, 20 }, // rnd seed
  1293.    { TYPE_FLOAT, NULL, FALSE, 21 },  // emitter width
  1294.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  1295.  
  1296.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  1297.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  1298.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  1299.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  1300.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  1301.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  1302.     { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  1303.     { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  1304.     { TYPE_INT, NULL, FALSE, 31 }, // offset amount
  1305.  
  1306.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  1307.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  1308.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  1309.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  1310.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  1311.  
  1312.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  1313.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  1314.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  1315.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  1316.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choice
  1317.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  1318.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  1319.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  1320.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  1321.  
  1322.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  1323.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  1324.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  1325.  
  1326.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  1327.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  1328.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  1329.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  1330.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  1331.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  1332.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  1333.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  1334.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  1335.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  1336.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  1337.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  1338.  
  1339.    { TYPE_FLOAT, NULL, TRUE, 61 },  // bubble amp61
  1340.    { TYPE_FLOAT, NULL, TRUE, 62 },  // bubble amp var
  1341.    { TYPE_INT, NULL, TRUE, 63 },  // bubble period
  1342.    { TYPE_FLOAT, NULL, TRUE, 64 },  // bubble period var
  1343.    { TYPE_FLOAT, NULL, TRUE, 65 },  // bubble phase
  1344.    { TYPE_FLOAT, NULL, TRUE, 66 },  // bubble phase var
  1345.  
  1346.    { TYPE_INT, NULL, TRUE, 67 },  // Stretch
  1347.    { TYPE_INT, NULL, FALSE, 68 },  // Custom Mtl
  1348.    { TYPE_FLOAT, NULL, FALSE, 69 },  // ViewPort Courseness
  1349.    { TYPE_INT, NULL, FALSE, 70 },  // Subframe rot
  1350.    { TYPE_INT, NULL, FALSE, 71 },  // Spawn Percent
  1351.    { TYPE_FLOAT, NULL, FALSE, 72 },  // Spawn Mult var
  1352. };
  1353.  
  1354. static ParamBlockDescID spdescVer4[] = {
  1355.    { TYPE_FLOAT, NULL, TRUE, 0 },    // off axis
  1356.    { TYPE_FLOAT, NULL, TRUE, 1 },    // axis apread
  1357.    { TYPE_FLOAT, NULL, TRUE, 2 },    // off plane
  1358.    { TYPE_FLOAT, NULL, TRUE, 3 },    // plane spread
  1359.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  1360.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  1361.  
  1362.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  1363.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  1364.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  1365.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  1366.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  1367.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  1368.    { TYPE_INT, NULL, TRUE, 12 },  // life
  1369.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  1370.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  1371.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  1372.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  1373.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  1374.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  1375.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  1376.    { TYPE_INT, NULL, FALSE, 20 }, // rnd seed
  1377.    { TYPE_FLOAT, NULL, FALSE, 21 },  // emitter width
  1378.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  1379.  
  1380.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  1381.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  1382.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  1383.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  1384.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  1385.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  1386.     { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  1387.     { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  1388.     { TYPE_INT, NULL, FALSE, 31 }, // offset amount
  1389.  
  1390.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  1391.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  1392.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  1393.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  1394.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  1395.  
  1396.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  1397.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  1398.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  1399.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  1400.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choice
  1401.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  1402.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  1403.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  1404.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  1405.  
  1406.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  1407.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  1408.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  1409.  
  1410.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  1411.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  1412.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  1413.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  1414.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  1415.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  1416.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  1417.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  1418.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  1419.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  1420.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  1421.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  1422.  
  1423.    { TYPE_FLOAT, NULL, TRUE, 61 },  // bubble amp61
  1424.    { TYPE_FLOAT, NULL, TRUE, 62 },  // bubble amp var
  1425.    { TYPE_INT, NULL, TRUE, 63 },  // bubble period
  1426.    { TYPE_FLOAT, NULL, TRUE, 64 },  // bubble period var
  1427.    { TYPE_FLOAT, NULL, TRUE, 65 },  // bubble phase
  1428.    { TYPE_FLOAT, NULL, TRUE, 66 },  // bubble phase var
  1429.  
  1430.    { TYPE_INT, NULL, TRUE, 67 },  // Stretch
  1431.    { TYPE_INT, NULL, FALSE, 68 },  // Custom Mtl
  1432.    { TYPE_FLOAT, NULL, FALSE, 69 },  // ViewPort Courseness
  1433.    { TYPE_INT, NULL, FALSE, 70 },  // Subframe rot
  1434.    { TYPE_INT, NULL, FALSE, 71 },  // Spawn Percent
  1435.    { TYPE_FLOAT, NULL, FALSE, 72 },  // Spawn Mult var
  1436.    { TYPE_INT, NULL, FALSE, 73 },  // Surface Tracking
  1437. };
  1438.  
  1439. static ParamBlockDescID spdescVer5[] = {
  1440.    { TYPE_FLOAT, NULL, TRUE, 0 },    // off axis
  1441.    { TYPE_FLOAT, NULL, TRUE, 1 },    // axis apread
  1442.    { TYPE_FLOAT, NULL, TRUE, 2 },    // off plane
  1443.    { TYPE_FLOAT, NULL, TRUE, 3 },    // plane spread
  1444.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  1445.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  1446.  
  1447.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  1448.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  1449.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  1450.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  1451.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  1452.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  1453.    { TYPE_INT, NULL, TRUE, 12 },  // life
  1454.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  1455.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  1456.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  1457.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  1458.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  1459.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  1460.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  1461.    { TYPE_INT, NULL, FALSE, 20 }, // rnd seed
  1462.    { TYPE_FLOAT, NULL, FALSE, 21 },  // emitter width
  1463.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  1464.  
  1465.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  1466.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  1467.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  1468.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  1469.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  1470.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  1471.     { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  1472.     { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  1473.     { TYPE_INT, NULL, FALSE, 31 }, // offset amount
  1474.  
  1475.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  1476.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  1477.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  1478.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  1479.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  1480.  
  1481.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  1482.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  1483.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  1484.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  1485.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choice
  1486.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  1487.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  1488.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  1489.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  1490.  
  1491.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  1492.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  1493.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  1494.  
  1495.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  1496.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  1497.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  1498.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  1499.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  1500.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  1501.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  1502.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  1503.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  1504.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  1505.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  1506.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  1507.  
  1508.    { TYPE_FLOAT, NULL, TRUE, 61 },  // bubble amp61
  1509.    { TYPE_FLOAT, NULL, TRUE, 62 },  // bubble amp var
  1510.    { TYPE_INT, NULL, TRUE, 63 },  // bubble period
  1511.    { TYPE_FLOAT, NULL, TRUE, 64 },  // bubble period var
  1512.    { TYPE_FLOAT, NULL, TRUE, 65 },  // bubble phase
  1513.    { TYPE_FLOAT, NULL, TRUE, 66 },  // bubble phase var
  1514.  
  1515.    { TYPE_INT, NULL, TRUE, 67 },  // Stretch
  1516.    { TYPE_INT, NULL, FALSE, 68 },  // Custom Mtl
  1517.    { TYPE_FLOAT, NULL, FALSE, 69 },  // ViewPort Courseness
  1518.    { TYPE_INT, NULL, FALSE, 70 },  // Subframe rot
  1519.    { TYPE_INT, NULL, FALSE, 71 },  // Spawn Percent
  1520.    { TYPE_FLOAT, NULL, FALSE, 72 },  // Spawn Mult var
  1521.    { TYPE_INT, NULL, FALSE, 73 },  // Surface Tracking
  1522.    { TYPE_INT, NULL, TRUE, 74 },  // dies after X
  1523.    { TYPE_FLOAT, NULL, TRUE, 75 },  // dies after X var
  1524. };
  1525.  
  1526. static ParamBlockDescID spdescVer6[] = {
  1527.    { TYPE_FLOAT, NULL, TRUE, 0 },    // off axis
  1528.    { TYPE_FLOAT, NULL, TRUE, 1 },    // axis apread
  1529.    { TYPE_FLOAT, NULL, TRUE, 2 },    // off plane
  1530.    { TYPE_FLOAT, NULL, TRUE, 3 },    // plane spread
  1531.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  1532.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  1533.  
  1534.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  1535.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  1536.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  1537.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  1538.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  1539.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  1540.    { TYPE_INT, NULL, TRUE, 12 },  // life
  1541.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  1542.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  1543.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  1544.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  1545.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  1546.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  1547.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  1548.    { TYPE_INT, NULL, FALSE, 20 }, // rnd seed
  1549.    { TYPE_FLOAT, NULL, FALSE, 21 },  // emitter width
  1550.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  1551.  
  1552.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  1553.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  1554.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  1555.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  1556.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  1557.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  1558.     { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  1559.     { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  1560.     { TYPE_INT, NULL, FALSE, 31 }, // offset amount
  1561.  
  1562.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  1563.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  1564.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  1565.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  1566.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  1567.  
  1568.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  1569.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  1570.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  1571.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  1572.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choice
  1573.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  1574.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  1575.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  1576.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  1577.  
  1578.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  1579.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  1580.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  1581.  
  1582.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  1583.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  1584.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  1585.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  1586.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  1587.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  1588.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  1589.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  1590.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  1591.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  1592.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  1593.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  1594.  
  1595.    { TYPE_FLOAT, NULL, TRUE, 61 },  // bubble amp61
  1596.    { TYPE_FLOAT, NULL, TRUE, 62 },  // bubble amp var
  1597.    { TYPE_INT, NULL, TRUE, 63 },  // bubble period
  1598.    { TYPE_FLOAT, NULL, TRUE, 64 },  // bubble period var
  1599.    { TYPE_FLOAT, NULL, TRUE, 65 },  // bubble phase
  1600.    { TYPE_FLOAT, NULL, TRUE, 66 },  // bubble phase var
  1601.  
  1602.    { TYPE_INT, NULL, TRUE, 67 },  // Stretch
  1603.    { TYPE_INT, NULL, FALSE, 68 },  // Custom Mtl
  1604.    { TYPE_FLOAT, NULL, FALSE, 69 },  // ViewPort Courseness
  1605.    { TYPE_INT, NULL, FALSE, 70 },  // Subframe rot
  1606.    { TYPE_INT, NULL, FALSE, 71 },  // Spawn Percent
  1607.    { TYPE_FLOAT, NULL, FALSE, 72 },  // Spawn Mult var
  1608.    { TYPE_INT, NULL, FALSE, 73 },  // Surface Tracking
  1609.    { TYPE_INT, NULL, TRUE, 74 },  // dies after X
  1610.    { TYPE_FLOAT, NULL, TRUE, 75 },  // dies after X var
  1611.  
  1612.    { TYPE_INT, NULL, FALSE, 76 },  // IPC Enable
  1613.    { TYPE_INT, NULL, FALSE, 77 },  // IPC Steps
  1614.    { TYPE_FLOAT, NULL, TRUE, 78 },  // IPC Bounce
  1615.    { TYPE_FLOAT, NULL, TRUE, 79 },  // IPC Bounce Var
  1616. };
  1617.  
  1618. #define PBLOCK_LENGTH_SUPRSPRAY 80
  1619.  
  1620. static ParamVersionDesc spversions[] = {
  1621.    ParamVersionDesc(spdescVer0,69,0),
  1622.    ParamVersionDesc(spdescVer1,70,1),
  1623.    ParamVersionDesc(spdescVer2,71,2),
  1624.    ParamVersionDesc(spdescVer3,73,3),
  1625.    ParamVersionDesc(spdescVer4,74,4),
  1626.    ParamVersionDesc(spdescVer5,76,5),
  1627.    };
  1628. #define NUM_OLDVERSIONS 6
  1629.  
  1630. // Current version
  1631. #define CURRENT_VERSION 6
  1632.  
  1633. #define PB_TUMBLE             0
  1634. #define PB_TUMBLERATE            1
  1635. #define PB_EMITMAP               2
  1636. #define PB_EMITRLENGTH           3
  1637. #define PB_CUSTOMMTL2            61
  1638. #define PB_METACOURSEVB          62
  1639. #define PB_SUBFRAMEROT2          63
  1640. #define PB_SPAWNPERCENT2         64
  1641. #define PB_SPAWNMULTVAR2         65
  1642. #define PB_BLNOTDRAFT            66
  1643. #define PB_BLSPAWNDIEAFTER       67
  1644. #define PB_BLSPAWNDIEAFTERVAR    68
  1645. #define PB_BLIPCOLLIDE_ON        69
  1646. #define PB_BLIPCOLLIDE_STEPS     70
  1647. #define PB_BLIPCOLLIDE_BOUNCE    71
  1648. #define PB_BLIPCOLLIDE_BOUNCEVAR 72
  1649.  
  1650. static int bmappingIDs[] = {IDC_SP_MAPTIME,IDC_SP_MAPDIST,IDC_SP_MAPPLANAR};
  1651.  
  1652. // Spin Dialog for Blizzard
  1653. static ParamUIDesc descBParamPSpin[] = {
  1654.  
  1655.    // Spin Time
  1656.    ParamUIDesc(
  1657.       PB_SPINTIME,
  1658.       EDITTYPE_TIME,
  1659.       IDC_SP_SPIN,IDC_SP_SPINSPIN,
  1660.       0.0f,999999999.0f,
  1661.       10.0f),
  1662.  
  1663.    // Spin Time Var
  1664.    ParamUIDesc(
  1665.       PB_SPINTIMEVAR,
  1666.       EDITTYPE_FLOAT,
  1667.       IDC_SP_SPINVAR,IDC_SP_SPINVARSPIN,
  1668.       0.0f,100.0f,
  1669.       0.01f,
  1670.       stdPercentDim),
  1671.  
  1672.    // Spin Phase
  1673.    ParamUIDesc(
  1674.       PB_SPINPHASE,
  1675.       EDITTYPE_FLOAT,
  1676.       IDC_SP_SPINPHA,IDC_SP_SPINPHASPIN,
  1677.       -360.0f,360.0f,
  1678.       0.01f,
  1679.       stdAngleDim),
  1680.  
  1681.    // Spin Phase Variation
  1682.    ParamUIDesc(
  1683.       PB_SPINPHASEVAR,
  1684.       EDITTYPE_FLOAT,
  1685.       IDC_SP_SPINPHAVAR,IDC_SP_SPINPHAVARSPIN,
  1686.       0.0f,100.0f,
  1687.       0.01f,
  1688.       stdPercentDim),
  1689.  
  1690.    // Enter Axis Control
  1691.    ParamUIDesc(PB_SPINAXISTYPE,TYPE_RADIO,bspindirectionIDs,2),
  1692.  
  1693.    // X-Axis
  1694.    ParamUIDesc(
  1695.       PB_SPINAXISX,
  1696.       EDITTYPE_FLOAT,
  1697.       IDC_SP_SPINAXISX,IDC_SP_SPINAXISXSPIN,
  1698.       -999999999.0f,999999999.0f,
  1699.       SPIN_AUTOSCALE),
  1700.  
  1701.    // Y-Axis
  1702.    ParamUIDesc(
  1703.       PB_SPINAXISY,
  1704.       EDITTYPE_FLOAT,
  1705.       IDC_SP_SPINAXISY,IDC_SP_SPINAXISYSPIN,
  1706.       -999999999.0f,999999999.0f,
  1707.       SPIN_AUTOSCALE),
  1708.  
  1709.    // Z-Axis
  1710.    ParamUIDesc(
  1711.       PB_SPINAXISZ,
  1712.       EDITTYPE_FLOAT,
  1713.       IDC_SP_SPINAXISZ,IDC_SP_SPINAXISZSPIN,
  1714.       -999999999.0f,999999999.0f,
  1715.       SPIN_AUTOSCALE),
  1716.  
  1717.    // Spin Direction Variation
  1718.    ParamUIDesc(
  1719.       PB_SPINAXISVAR,
  1720.       EDITTYPE_FLOAT,
  1721.       IDC_SP_SPINAXISVAR,IDC_SP_SPINAXISVARSPIN,
  1722.       -180.0f,180.0f,
  1723.       0.01f,
  1724.       stdAngleDim),
  1725.  
  1726.    // IPC Enable
  1727.    ParamUIDesc(PB_BLIPCOLLIDE_ON,TYPE_SINGLECHEKBOX,IDC_INTERP_BOUNCEON),
  1728.  
  1729.    // IPC Steps
  1730.    ParamUIDesc(
  1731.       PB_BLIPCOLLIDE_STEPS,
  1732.       EDITTYPE_INT,
  1733.       IDC_INTERP_NSTEPS,IDC_INTERP_NSTEPSSPIN,
  1734.       1.0f,1000.0f,
  1735.       1.0f),
  1736.  
  1737.    // IPC Bounce
  1738.    ParamUIDesc(
  1739.       PB_BLIPCOLLIDE_BOUNCE,
  1740.       EDITTYPE_FLOAT,
  1741.       IDC_INTERP_BOUNCE,IDC_INTERP_BOUNCESPIN,
  1742.       0.0f,10000.0f,
  1743.       1.0f,
  1744.       stdPercentDim),
  1745.  
  1746.    // IPC Bounce
  1747.    ParamUIDesc(
  1748.       PB_BLIPCOLLIDE_BOUNCEVAR,
  1749.       EDITTYPE_FLOAT,
  1750.       IDC_INTERP_BOUNCEVAR,IDC_INTERP_BOUNCEVARSPIN,
  1751.       0.0f,100.0f,
  1752.       1.0f,
  1753.       stdPercentDim),
  1754. };
  1755.  
  1756. #define BPARAMPSPIN_LENGTH 13
  1757.  
  1758. static ParamUIDesc BdescParamPType[] = {
  1759.  
  1760.    // Particle Class
  1761.    ParamUIDesc(PB_PARTICLECLASS,TYPE_RADIO,particleclassIDs,3),
  1762.  
  1763.    // Particle Type
  1764.    ParamUIDesc(PB_PARTICLETYPE,TYPE_RADIO,particletypeIDs,8),
  1765.  
  1766.    // Metaball Tension
  1767.    ParamUIDesc(
  1768.       PB_METATENSION,
  1769.       EDITTYPE_UNIVERSE,
  1770.       IDC_SP_METTENS,IDC_SP_METTENSSPIN,
  1771.       0.1f,10.0f,
  1772.       SPIN_AUTOSCALE),
  1773.  
  1774.    // Metaball Tension Variation
  1775.    ParamUIDesc(
  1776.       PB_METATENSIONVAR,
  1777.       EDITTYPE_FLOAT,
  1778.       IDC_SP_METTENSVAR,IDC_SP_METTENSVARSPIN,
  1779.       0.0f,100.0f,
  1780.       SPIN_AUTOSCALE,stdPercentDim),
  1781.  
  1782.    // Metaball Courseness
  1783.    ParamUIDesc(
  1784.       PB_METACOURSE,
  1785.       EDITTYPE_UNIVERSE,
  1786.       IDC_SP_METCOURSE,IDC_SP_METCOURSESPIN,
  1787.       0.0f,999999999.0f,
  1788.       SPIN_AUTOSCALE),
  1789.  
  1790.    // Metaball Courseness ViewPort
  1791.    ParamUIDesc(
  1792.       PB_METACOURSEVB,
  1793.       EDITTYPE_UNIVERSE,
  1794.       IDC_SP_METCOURSEV,IDC_SP_METCOURSEVSPIN,
  1795.       0.0f,999999999.0f,
  1796.       SPIN_AUTOSCALE),
  1797.  
  1798.    // Metaball Auto Coarseness
  1799.    ParamUIDesc(PB_METAAUTOCOARSE,TYPE_SINGLECHEKBOX,IDC_SP_AUTOCOARSE),
  1800.      
  1801.    // Display type
  1802.    ParamUIDesc(PB_BLNOTDRAFT,TYPE_SINGLECHEKBOX,IDC_SP_DRAFTMODE),
  1803.  
  1804.    // Use Subtree Checkbox
  1805.    ParamUIDesc(PB_USESUBTREE,TYPE_SINGLECHEKBOX,IDC_AP_USESUBTREE),
  1806.  
  1807.    // Display type
  1808.    ParamUIDesc(PB_ANIMATIONOFFSET,TYPE_RADIO,animateoffsetIDs,3),
  1809.  
  1810.    // Animation Offset Amount
  1811.    ParamUIDesc(
  1812.       PB_OFFSETAMOUNT,
  1813.       EDITTYPE_TIME,
  1814.       IDC_AP_ANIRNDFR,IDC_AP_ANIRNDFRSPIN,
  1815.       1.0f,999999999.0f,
  1816.       10.0f),
  1817.  
  1818.    // Mapping Across
  1819.    ParamUIDesc(PB_MAPPINGTYPE,TYPE_RADIO,bmappingIDs,3),
  1820.  
  1821.    // Time Mapping Option
  1822.    ParamUIDesc(
  1823.       PB_MAPPINGTIME,
  1824.       EDITTYPE_TIME,
  1825.       IDC_SP_MAPTIMEVAL,IDC_SP_MAPTIMEVALSPIN,
  1826.       1.0f,999999999.0f,
  1827.       10.0f),
  1828.  
  1829.    // Distance Mapping Option
  1830.    ParamUIDesc(
  1831.       PB_MAPPINGDIST,
  1832.       EDITTYPE_UNIVERSE,
  1833.       IDC_SP_MAPDISTVAL,IDC_SP_MAPDISTVALSPIN,
  1834.       0.1f,999999999.0f,
  1835.       SPIN_AUTOSCALE),
  1836.  
  1837.    // Use Custom Mtl
  1838.    ParamUIDesc(PB_CUSTOMMTL2,TYPE_RADIO,custmtlIDs,2),
  1839. };
  1840. #define BPARAMPTYPE_LENGTH 15
  1841.  
  1842. // Dialog Unique to Particle Array
  1843. static ParamUIDesc BdescParam[] = {
  1844.  
  1845.    // Emitter Width
  1846.    ParamUIDesc(
  1847.       PB_EMITRWID,
  1848.       EDITTYPE_UNIVERSE,
  1849.       IDC_SP_EMITWID,IDC_SP_EMITWIDSPIN,
  1850.       0.0f,999999999.0f,
  1851.       SPIN_AUTOSCALE),  
  1852.  
  1853.    // Emitter Length
  1854.    ParamUIDesc(
  1855.       PB_EMITRLENGTH,
  1856.       EDITTYPE_UNIVERSE,
  1857.       IDC_SP_EMITLEN,IDC_SP_EMITLENSPIN,
  1858.       0.0f,999999999.0f,
  1859.       SPIN_AUTOSCALE),  
  1860.  
  1861.    // Hide Emitter
  1862.    ParamUIDesc(PB_EMITRHID,TYPE_SINGLECHEKBOX,IDC_SP_EMITHID),
  1863.  
  1864.    // Animation Offset Type
  1865.    ParamUIDesc(PB_VIEWPORTSHOWS,TYPE_RADIO,viewportoptionIDs,4),
  1866.  
  1867.    // Particle Display Portion
  1868.    ParamUIDesc(
  1869.       PB_DISPLAYPORTION,
  1870.       EDITTYPE_FLOAT,
  1871.       IDC_SP_GENDISP,IDC_SP_GENDISPSPIN,
  1872.       0.0f,100.0f,
  1873.       0.1f,
  1874.       stdPercentDim),
  1875. };
  1876. #define PARAMBLIZZARD_LENGTH 5
  1877.  
  1878. // Common Dialog for Particle Generation
  1879. static ParamUIDesc BdescParamPGen[] = {
  1880.  
  1881.    // Distribution Method
  1882.    ParamUIDesc(PB_BIRTHMETHOD,TYPE_RADIO,countIDs,2),
  1883.  
  1884.    // Particle Birth Rate
  1885.    ParamUIDesc(
  1886.       PB_PBIRTHRATE,
  1887.       EDITTYPE_INT,
  1888.       IDC_SP_GENRATE,IDC_SP_GENRATESPIN,
  1889.       0.0f,65000.0f,
  1890.       1.0f),
  1891.  
  1892.    // Particle Total Count
  1893.    ParamUIDesc(
  1894.       PB_PTOTALNUMBER,
  1895.       EDITTYPE_INT,
  1896.       IDC_SP_GENTTL,IDC_SP_GENTTLSPIN,
  1897.       0.0f,65000.0f,
  1898.       1.0f),
  1899.  
  1900.    // Particle Speed
  1901.    ParamUIDesc(
  1902.       PB_SPEED,
  1903.       EDITTYPE_UNIVERSE,
  1904.       IDC_SP_BLIZSPEED,IDC_SP_BLIZSPEEDSPIN,
  1905.       0.0f,999999999.0f,
  1906.       SPIN_AUTOSCALE),
  1907.  
  1908.    // Particle Speed Var
  1909.    ParamUIDesc(
  1910.       PB_SPEEDVAR,
  1911.       EDITTYPE_FLOAT,
  1912.       IDC_SP_BLIZSPEEDVAR,IDC_SP_BLIZSPEEDVARSPIN,
  1913.       0.0f,100.0f,
  1914.       SPIN_AUTOSCALE,stdPercentDim),
  1915.  
  1916.    // Particle Tumble
  1917.    ParamUIDesc(
  1918.       PB_TUMBLE,
  1919.       EDITTYPE_FLOAT,
  1920.       IDC_SP_BLIZTUMBL,IDC_SP_BLIZTUMBLSPIN,
  1921.       0.0f,1.0f,
  1922.       0.005f),
  1923.  
  1924.    // Particle Tumble Rate
  1925.    ParamUIDesc(
  1926.       PB_TUMBLERATE,
  1927.       EDITTYPE_FLOAT,
  1928.       IDC_SP_BLIZTUMBLRATE,IDC_SP_BLIZTUMBLRATESPIN,
  1929.       0.0f,999999999.0f,
  1930.       0.01f),
  1931.  
  1932.    // Emitter Start Time
  1933.    ParamUIDesc(
  1934.       PB_EMITSTART,
  1935.       EDITTYPE_TIME,
  1936.       IDC_SP_GENEMIT1,IDC_SP_GENEMIT1SPIN,
  1937.       -999999999.0f,999999999.0f,
  1938.       10.0f),
  1939.  
  1940.    // Emitter Stop Time
  1941.    ParamUIDesc(
  1942.       PB_EMITSTOP,
  1943.       EDITTYPE_TIME,
  1944.       IDC_SP_GENEMIT2,IDC_SP_GENEMIT2SPIN,
  1945.       -999999999.0f,999999999.0f,
  1946.       10.0f),
  1947.  
  1948.    // Particle Time Limit
  1949.    ParamUIDesc(
  1950.       PB_DISPUNTIL,
  1951.       EDITTYPE_TIME,
  1952.       IDC_SP_DISPUNTIL,IDC_SP_DISPUNTILSPIN,
  1953.       -999999999.0f,999999999.0f,
  1954.       10.0f),
  1955.  
  1956.    // Particle Life
  1957.    ParamUIDesc(
  1958.       PB_LIFE,
  1959.       EDITTYPE_TIME,
  1960.       IDC_SP_GENLIFE,IDC_SP_GENLIFESPIN,
  1961.       0.0f,999999999.0f,
  1962.       10.0f),
  1963.  
  1964.    // Particle Life Var
  1965.    ParamUIDesc(
  1966.       PB_LIFEVAR,
  1967.       EDITTYPE_TIME,
  1968.       IDC_SP_GENLIFEVAR,IDC_SP_GENLIFEVARSPIN,
  1969.       0.0f,999999999.0f,
  1970.       10.0f),
  1971.  
  1972.    // Subframe Time and Motion Sampling
  1973.    ParamUIDesc(PB_SUBFRAMEMOVE,TYPE_SINGLECHEKBOX,IDC_SP_GENSMPLMOVE),
  1974.    ParamUIDesc(PB_SUBFRAMETIME,TYPE_SINGLECHEKBOX,IDC_SP_GENSMPLTIME),
  1975.    ParamUIDesc(PB_SUBFRAMEROT2,TYPE_SINGLECHEKBOX,IDC_SP_GENSMPLROT),
  1976.  
  1977.    // Particle Size
  1978.    ParamUIDesc(
  1979.       PB_SIZE,
  1980.       EDITTYPE_UNIVERSE,
  1981.       IDC_SP_GENSIZE,IDC_SP_GENSIZESPIN,
  1982.       0.0f,999999999.0f,
  1983.       SPIN_AUTOSCALE),
  1984.  
  1985.    // Particle Size Var
  1986.    ParamUIDesc(
  1987.       PB_SIZEVAR,
  1988.       EDITTYPE_FLOAT,
  1989.       IDC_SP_GENSIZEVAR,IDC_SP_GENSIZEVARSPIN,
  1990.       0.0f,100.0f,
  1991.       SPIN_AUTOSCALE,stdPercentDim),
  1992.  
  1993.    // Particle Grow Time
  1994.    ParamUIDesc(
  1995.       PB_GROWTIME,
  1996.       EDITTYPE_TIME,
  1997.       IDC_SP_GENGRO,IDC_SP_GENGROSPIN,
  1998.       0.0f,999999999.0f,
  1999.       10.0f),
  2000.  
  2001.    // Particle Fade Time
  2002.    ParamUIDesc(
  2003.       PB_FADETIME,
  2004.       EDITTYPE_TIME,
  2005.       IDC_SP_GENFAD,IDC_SP_GENFADSPIN,
  2006.       0.0f,999999999.0f,
  2007.       10.0f),
  2008.  
  2009.    // Random Number Seed
  2010.    ParamUIDesc(
  2011.       PB_RNDSEED,
  2012.       EDITTYPE_INT,
  2013.       IDC_SP_GENSEED,IDC_SP_GENSEEDSPIN,
  2014.       0.0f,25000.0f,
  2015.       1.0f),
  2016.    };
  2017.  
  2018. #define BPARAMPGEN_LENGTH 20
  2019.  
  2020. static ParamUIDesc descBPSpawning[] = {
  2021.    
  2022.    // Spawing Effects Type
  2023.    ParamUIDesc(PB_SPAWNTYPE,TYPE_RADIO,SpawnTypeIDs,5),
  2024.  
  2025.    // Die after X
  2026.    ParamUIDesc(
  2027.       PB_BLSPAWNDIEAFTER,
  2028.       EDITTYPE_TIME,
  2029.       IDC_AP_MAXSPAWNDIEAFTER,IDC_AP_MAXSPAWNDIEAFTERSPIN,
  2030.       0.0f,999999999.0f,
  2031.       10.0f),
  2032.  
  2033.    ParamUIDesc(
  2034.       PB_BLSPAWNDIEAFTERVAR,
  2035.       EDITTYPE_FLOAT,
  2036.       IDC_AP_MAXSPAWNDIEAFTERVAR,IDC_AP_MAXSPAWNDIEAFTERVARSPIN,
  2037.       0.0f,100.0f,
  2038.       0.01f,
  2039.       stdPercentDim),
  2040.  
  2041.    // Spawn Generations
  2042.    ParamUIDesc(
  2043.       PB_SPAWNGENS,
  2044.       EDITTYPE_INT,
  2045.       IDC_AP_MAXSPAWNGENS,IDC_AP_MAXSPAWNGENSSPIN,
  2046.       1.0f,65000.0f,
  2047.       1.0f),
  2048.  
  2049.    // Spawn Generations
  2050.    ParamUIDesc(
  2051.       PB_SPAWNPERCENT2,
  2052.       EDITTYPE_INT,
  2053.       IDC_AP_PARENTPERCENT,IDC_AP_PARENTPERCENTSPIN,
  2054.       1.0f,100.0f,
  2055.       1.0f),
  2056.  
  2057.    // Spawn Spawncount
  2058.    ParamUIDesc(
  2059.       PB_SPAWNCOUNT,
  2060.       EDITTYPE_INT,
  2061.       IDC_AP_NUMBERVAR,IDC_AP_NUMBERVARSPIN,
  2062.       1.0f,65000.0f,
  2063.       1.0f),
  2064.  
  2065.    // Spawn Mult Percent
  2066.    ParamUIDesc(
  2067.       PB_SPAWNMULTVAR2,
  2068.       EDITTYPE_FLOAT,
  2069.       IDC_AP_NUMBERVARVAR,IDC_AP_NUMBERVARVARSPIN,
  2070.       0.0f,100.0f,
  2071.       0.1f,stdPercentDim),
  2072.  
  2073.    // Spawn Direction Chaos
  2074.    ParamUIDesc(
  2075.       PB_SPAWNDIRCHAOS,
  2076.       EDITTYPE_FLOAT,
  2077.       IDC_AP_CHAOSANGLE,IDC_AP_CHAOSANGLESPIN,
  2078.       0.0f,100.0f,
  2079.       0.1f,stdPercentDim),
  2080.  
  2081.    // Spawn Speed Chaos
  2082.    ParamUIDesc(
  2083.       PB_SPAWNSPEEDCHAOS,
  2084.       EDITTYPE_FLOAT,
  2085.       IDC_AP_CHAOSSPEED,IDC_AP_CHAOSSPEEDSPIN,
  2086.       0.0f,100.0f,
  2087.       0.1f),
  2088.  
  2089.    // Spawing Speed Sign
  2090.    ParamUIDesc(PB_SPAWNSPEEDSIGN,TYPE_RADIO,SpeedChaosIDs,3),
  2091.  
  2092.    // Spawning Inherit Parent V
  2093.    ParamUIDesc(PB_SPAWNINHERITV,TYPE_SINGLECHEKBOX,IDC_AP_SPAWNSUMV),
  2094.  
  2095.    // Spawning Speed Fixed
  2096.    ParamUIDesc(PB_SPAWNSPEEDFIXED,TYPE_SINGLECHEKBOX,IDC_AP_SPAWNSPEEDFIXED),
  2097.  
  2098.    // Spawn Scale Chaos
  2099.    ParamUIDesc(
  2100.       PB_SPAWNSCALECHAOS,
  2101.       EDITTYPE_FLOAT,
  2102.       IDC_AP_CHAOSSCALE,IDC_AP_CHAOSSCALESPIN,
  2103.       0.0f,100.0f,
  2104.       0.1f),
  2105.  
  2106.    // Spawning Scale Sign
  2107.    ParamUIDesc(PB_SPAWNSCALESIGN,TYPE_RADIO,ScaleChaosIDs,3),
  2108.  
  2109.    // Spawning Speed Fixed
  2110.    ParamUIDesc(PB_SPAWNSCALEFIXED,TYPE_SINGLECHEKBOX,IDC_AP_SPAWNSCALEFIXED),
  2111.  
  2112.    // Spawn Lifespan Entry Field
  2113.    ParamUIDesc(
  2114.       PB_SPAWNLIFEVLUE,
  2115.       EDITTYPE_INT,
  2116.       IDC_AP_QUEUELIFESPAN,IDC_AP_QUEUELIFESPANSPIN,
  2117.       0.0f,65000.0f,
  2118.       0.1f),
  2119. };
  2120.  
  2121. #define PBSPAWNINGPARAMS_LENGTH 16
  2122.  
  2123. // Particle Type for Blizzard
  2124.  
  2125. static ParamBlockDescID BdescVer0[] = {
  2126.    { TYPE_FLOAT, NULL, TRUE, 0 },    // tumble
  2127.    { TYPE_FLOAT, NULL, TRUE, 1 },    // tumblerate
  2128.    { TYPE_FLOAT, NULL, FALSE, 2 },   // emit map
  2129.    { TYPE_FLOAT, NULL, TRUE, 3 },    // emitter length
  2130.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  2131.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  2132.  
  2133.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  2134.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  2135.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  2136.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  2137.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  2138.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  2139.    { TYPE_INT, NULL, TRUE, 12 },  // life
  2140.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  2141.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  2142.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  2143.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  2144.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  2145.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  2146.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  2147.    { TYPE_INT, NULL, FALSE, 20 },    // rnd seed
  2148.    { TYPE_FLOAT, NULL, TRUE, 21 },  // emitter width
  2149.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  2150.  
  2151.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  2152.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  2153.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  2154.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  2155.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  2156.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  2157.    { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  2158.    { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  2159.    { TYPE_INT, NULL, FALSE, 31 }, // animation offset time
  2160.  
  2161.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  2162.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  2163.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  2164.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  2165.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  2166.  
  2167.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  2168.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  2169.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  2170.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  2171.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choose
  2172.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  2173.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  2174.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  2175.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  2176.  
  2177.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  2178.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  2179.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  2180.  
  2181.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  2182.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  2183.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  2184.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  2185.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  2186.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  2187.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  2188.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  2189.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  2190.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  2191.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  2192.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  2193.  
  2194.    { TYPE_INT, NULL, FALSE, 61 },  // custmlt
  2195. };
  2196.  
  2197. static ParamBlockDescID BdescVer1[] = {
  2198.    { TYPE_FLOAT, NULL, TRUE, 0 },    // tumble
  2199.    { TYPE_FLOAT, NULL, TRUE, 1 },    // tumblerate
  2200.    { TYPE_FLOAT, NULL, FALSE, 2 },   // emit map
  2201.    { TYPE_FLOAT, NULL, TRUE, 3 },    // emitter length
  2202.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  2203.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  2204.  
  2205.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  2206.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  2207.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  2208.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  2209.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  2210.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  2211.    { TYPE_INT, NULL, TRUE, 12 },  // life
  2212.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  2213.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  2214.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  2215.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  2216.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  2217.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  2218.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  2219.    { TYPE_INT, NULL, FALSE, 20 },    // rnd seed
  2220.    { TYPE_FLOAT, NULL, TRUE, 21 },  // emitter width
  2221.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  2222.  
  2223.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  2224.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  2225.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  2226.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  2227.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  2228.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  2229.    { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  2230.    { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  2231.    { TYPE_INT, NULL, FALSE, 31 }, // animation offset time
  2232.  
  2233.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  2234.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  2235.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  2236.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  2237.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  2238.  
  2239.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  2240.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  2241.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  2242.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  2243.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choose
  2244.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  2245.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  2246.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  2247.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  2248.  
  2249.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  2250.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  2251.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  2252.  
  2253.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  2254.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  2255.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  2256.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  2257.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  2258.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  2259.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  2260.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  2261.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  2262.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  2263.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  2264.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  2265.  
  2266.    { TYPE_INT, NULL, FALSE, 61 },  // custmlt
  2267.    { TYPE_FLOAT, NULL, FALSE, 62 }, // meta course Viewport
  2268. };
  2269. static ParamBlockDescID BdescVer2[] = {
  2270.    { TYPE_FLOAT, NULL, TRUE, 0 },    // tumble
  2271.    { TYPE_FLOAT, NULL, TRUE, 1 },    // tumblerate
  2272.    { TYPE_FLOAT, NULL, FALSE, 2 },   // emit map
  2273.    { TYPE_FLOAT, NULL, TRUE, 3 },    // emitter length
  2274.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  2275.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  2276.  
  2277.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  2278.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  2279.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  2280.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  2281.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  2282.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  2283.    { TYPE_INT, NULL, TRUE, 12 },  // life
  2284.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  2285.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  2286.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  2287.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  2288.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  2289.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  2290.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  2291.    { TYPE_INT, NULL, FALSE, 20 },    // rnd seed
  2292.    { TYPE_FLOAT, NULL, TRUE, 21 },  // emitter width
  2293.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  2294.  
  2295.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  2296.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  2297.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  2298.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  2299.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  2300.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  2301.    { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  2302.    { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  2303.    { TYPE_INT, NULL, FALSE, 31 }, // animation offset time
  2304.  
  2305.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  2306.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  2307.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  2308.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  2309.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  2310.  
  2311.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  2312.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  2313.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  2314.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  2315.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choose
  2316.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  2317.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  2318.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  2319.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  2320.  
  2321.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  2322.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  2323.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  2324.  
  2325.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  2326.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  2327.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  2328.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  2329.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  2330.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  2331.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  2332.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  2333.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  2334.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  2335.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  2336.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  2337.  
  2338.    { TYPE_INT, NULL, FALSE, 61 },  // custmlt
  2339.    { TYPE_FLOAT, NULL, FALSE, 62 }, // meta course Viewport
  2340.    { TYPE_INT, NULL, FALSE, 63},  // subframe rot
  2341. };
  2342. static ParamBlockDescID BdescVer3[] = {
  2343.    { TYPE_FLOAT, NULL, TRUE, 0 },    // tumble
  2344.    { TYPE_FLOAT, NULL, TRUE, 1 },    // tumblerate
  2345.    { TYPE_FLOAT, NULL, FALSE, 2 },   // emit map
  2346.    { TYPE_FLOAT, NULL, TRUE, 3 },    // emitter length
  2347.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  2348.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  2349.  
  2350.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  2351.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  2352.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  2353.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  2354.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  2355.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  2356.    { TYPE_INT, NULL, TRUE, 12 },  // life
  2357.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  2358.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  2359.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  2360.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  2361.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  2362.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  2363.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  2364.    { TYPE_INT, NULL, FALSE, 20 },    // rnd seed
  2365.    { TYPE_FLOAT, NULL, TRUE, 21 },  // emitter width
  2366.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  2367.  
  2368.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  2369.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  2370.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  2371.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  2372.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  2373.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  2374.    { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  2375.    { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  2376.    { TYPE_INT, NULL, FALSE, 31 }, // animation offset time
  2377.  
  2378.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  2379.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  2380.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  2381.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  2382.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  2383.  
  2384.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  2385.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  2386.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  2387.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  2388.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choose
  2389.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  2390.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  2391.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  2392.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  2393.  
  2394.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  2395.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  2396.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  2397.  
  2398.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  2399.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  2400.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  2401.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  2402.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  2403.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  2404.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  2405.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  2406.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  2407.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  2408.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  2409.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  2410.  
  2411.    { TYPE_INT, NULL, FALSE, 61 },  // custmlt
  2412.    { TYPE_FLOAT, NULL, FALSE, 62 }, // meta course Viewport
  2413.    { TYPE_INT, NULL, FALSE, 63},  // subframe rot
  2414.    { TYPE_INT, NULL, FALSE, 64 }, // Spawn PErcent
  2415.    { TYPE_FLOAT, NULL, FALSE, 65},  // spawn mult var
  2416. };
  2417. static ParamBlockDescID BdescVer4[] = {
  2418.    { TYPE_FLOAT, NULL, TRUE, 0 },    // tumble
  2419.    { TYPE_FLOAT, NULL, TRUE, 1 },    // tumblerate
  2420.    { TYPE_FLOAT, NULL, FALSE, 2 },   // emit map
  2421.    { TYPE_FLOAT, NULL, TRUE, 3 },    // emitter length
  2422.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  2423.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  2424.  
  2425.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  2426.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  2427.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  2428.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  2429.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  2430.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  2431.    { TYPE_INT, NULL, TRUE, 12 },  // life
  2432.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  2433.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  2434.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  2435.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  2436.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  2437.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  2438.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  2439.    { TYPE_INT, NULL, FALSE, 20 },    // rnd seed
  2440.    { TYPE_FLOAT, NULL, TRUE, 21 },  // emitter width
  2441.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  2442.  
  2443.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  2444.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  2445.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  2446.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  2447.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  2448.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  2449.    { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  2450.    { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  2451.    { TYPE_INT, NULL, FALSE, 31 }, // animation offset time
  2452.  
  2453.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  2454.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  2455.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  2456.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  2457.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  2458.  
  2459.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  2460.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  2461.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  2462.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  2463.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choose
  2464.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  2465.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  2466.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  2467.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  2468.  
  2469.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  2470.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  2471.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  2472.  
  2473.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  2474.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  2475.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  2476.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  2477.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  2478.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  2479.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  2480.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  2481.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  2482.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  2483.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  2484.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  2485.  
  2486.    { TYPE_INT, NULL, FALSE, 61 },  // custmlt
  2487.    { TYPE_FLOAT, NULL, FALSE, 62 }, // meta course Viewport
  2488.    { TYPE_INT, NULL, FALSE, 63},  // subframe rot
  2489.    { TYPE_INT, NULL, FALSE, 64 }, // Spawn PErcent
  2490.    { TYPE_FLOAT, NULL, FALSE, 65},  // spawn mult var
  2491.    { TYPE_INT, NULL, TRUE, 66 }, // Draft
  2492. };
  2493.  
  2494. static ParamBlockDescID BdescVer5[] = {
  2495.    { TYPE_FLOAT, NULL, TRUE, 0 },    // tumble
  2496.    { TYPE_FLOAT, NULL, TRUE, 1 },    // tumblerate
  2497.    { TYPE_FLOAT, NULL, FALSE, 2 },   // emit map
  2498.    { TYPE_FLOAT, NULL, TRUE, 3 },    // emitter length
  2499.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  2500.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  2501.  
  2502.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  2503.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  2504.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  2505.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  2506.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  2507.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  2508.    { TYPE_INT, NULL, TRUE, 12 },  // life
  2509.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  2510.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  2511.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  2512.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  2513.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  2514.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  2515.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  2516.    { TYPE_INT, NULL, FALSE, 20 },    // rnd seed
  2517.    { TYPE_FLOAT, NULL, TRUE, 21 },  // emitter width
  2518.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  2519.  
  2520.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  2521.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  2522.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  2523.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  2524.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  2525.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  2526.    { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  2527.    { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  2528.    { TYPE_INT, NULL, FALSE, 31 }, // animation offset time
  2529.  
  2530.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  2531.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  2532.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  2533.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  2534.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  2535.  
  2536.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  2537.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  2538.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  2539.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  2540.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choose
  2541.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  2542.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  2543.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  2544.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  2545.  
  2546.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  2547.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  2548.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  2549.  
  2550.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  2551.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  2552.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  2553.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  2554.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  2555.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  2556.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  2557.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  2558.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  2559.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  2560.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  2561.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  2562.  
  2563.    { TYPE_INT, NULL, FALSE, 61 },  // custmlt
  2564.    { TYPE_FLOAT, NULL, FALSE, 62 }, // meta course Viewport
  2565.    { TYPE_INT, NULL, FALSE, 63},  // subframe rot
  2566.    { TYPE_INT, NULL, FALSE, 64 }, // Spawn PErcent
  2567.    { TYPE_FLOAT, NULL, FALSE, 65},  // spawn mult var
  2568.    { TYPE_INT, NULL, TRUE, 66 }, // Draft
  2569.    { TYPE_INT, NULL, TRUE, 67 }, // Dies after X
  2570.    { TYPE_FLOAT, NULL, TRUE, 68 }, // Dies after X var
  2571. };
  2572.  
  2573. static ParamBlockDescID BdescVer6[] = {
  2574.    { TYPE_FLOAT, NULL, TRUE, 0 },    // tumble
  2575.    { TYPE_FLOAT, NULL, TRUE, 1 },    // tumblerate
  2576.    { TYPE_FLOAT, NULL, FALSE, 2 },   // emit map
  2577.    { TYPE_FLOAT, NULL, TRUE, 3 },    // emitter length
  2578.    { TYPE_FLOAT, NULL, TRUE, 4 },    // speed
  2579.    { TYPE_FLOAT, NULL, TRUE, 5 },    // speed var
  2580.  
  2581.    { TYPE_INT, NULL, FALSE, 6 },  // Birth method
  2582.    { TYPE_INT, NULL, TRUE, 7 },   // Birth rate
  2583.    { TYPE_INT, NULL, FALSE, 8 },    // total number
  2584.    { TYPE_INT, NULL, FALSE, 9 },  // emit start
  2585.    { TYPE_INT, NULL, FALSE, 10 },   // emit stop
  2586.    { TYPE_INT, NULL, FALSE, 11 },   // display until
  2587.    { TYPE_INT, NULL, TRUE, 12 },  // life
  2588.    { TYPE_INT, NULL, TRUE, 13 },  // life var
  2589.    { TYPE_INT, NULL, FALSE, 14 },    // sub frame move
  2590.    { TYPE_INT, NULL, FALSE, 15 },    // sub frame time
  2591.    { TYPE_FLOAT, NULL, TRUE, 16 },   // size
  2592.    { TYPE_FLOAT, NULL, TRUE, 17 },   // size var
  2593.    { TYPE_INT, NULL, FALSE, 18 },    // grow time
  2594.    { TYPE_INT, NULL, FALSE, 19 },    // fade time
  2595.    { TYPE_INT, NULL, FALSE, 20 },    // rnd seed
  2596.    { TYPE_FLOAT, NULL, TRUE, 21 },  // emitter width
  2597.    { TYPE_INT, NULL, FALSE, 22 },    // emitter hidden
  2598.  
  2599.    { TYPE_INT, NULL, FALSE, 23 },  // particle class
  2600.    { TYPE_INT, NULL, FALSE, 24 },  // particle type
  2601.    { TYPE_FLOAT, NULL, TRUE, 25 },  // meta tension
  2602.    { TYPE_FLOAT, NULL, TRUE, 26 },  // metatension var
  2603.    { TYPE_FLOAT, NULL, FALSE, 27 }, // meta course
  2604.    { TYPE_INT, NULL, FALSE, 28 }, // auto coarseness
  2605.    { TYPE_INT, NULL, FALSE, 29 }, // use subtree
  2606.    { TYPE_INT, NULL, FALSE, 30 }, // animation offset
  2607.    { TYPE_INT, NULL, FALSE, 31 }, // animation offset time
  2608.  
  2609.    { TYPE_INT, NULL, FALSE, 32 },     // viewport shows
  2610.    { TYPE_FLOAT, NULL, FALSE, 33 }, // display portion
  2611.    { TYPE_INT, NULL, FALSE, 34 },     // mapping type
  2612.    { TYPE_INT, NULL, TRUE, 35 },   // mapping time
  2613.    { TYPE_FLOAT, NULL, TRUE, 36 },    // mapping dist
  2614.  
  2615.    { TYPE_INT, NULL, TRUE, 37 }, // spin time
  2616.    { TYPE_FLOAT, NULL, TRUE, 38 },  // spin time var
  2617.    { TYPE_FLOAT, NULL, TRUE, 39 },  // spin phase
  2618.    { TYPE_FLOAT, NULL, TRUE, 40 },  // spin phase var
  2619.    { TYPE_INT, NULL, FALSE, 41 },  // spin axis choose
  2620.    { TYPE_FLOAT, NULL, TRUE, 42 }, // spin axis x
  2621.    { TYPE_FLOAT, NULL, TRUE, 43 }, // spin axis y
  2622.    { TYPE_FLOAT, NULL, TRUE, 44 }, // spin axis z
  2623.    { TYPE_FLOAT, NULL, TRUE, 45 }, // spin axis var
  2624.  
  2625.    { TYPE_FLOAT, NULL, TRUE, 46 },  // emit influence
  2626.    { TYPE_FLOAT, NULL, TRUE, 47 },  // emit multiplier
  2627.    { TYPE_FLOAT, NULL, TRUE, 48 },  // emit mult var
  2628.  
  2629.    { TYPE_INT, NULL, FALSE, 49 }, // spawn type
  2630.    { TYPE_INT, NULL, FALSE, 50 }, // number of gens
  2631.    { TYPE_INT, NULL, FALSE, 51 }, // number of spawns
  2632.    { TYPE_FLOAT, NULL, TRUE, 52 }, // direction chaos
  2633.    { TYPE_FLOAT, NULL, TRUE, 53 }, // speed chaos
  2634.    { TYPE_INT, NULL, FALSE, 54 }, // speed chaos sign
  2635.    { TYPE_INT, NULL, FALSE, 55 }, // inherit old particle velocity
  2636.    { TYPE_FLOAT, NULL, TRUE, 56 }, // scale chaos
  2637.    { TYPE_INT, NULL, FALSE, 57 }, // scale chaos sign
  2638.    { TYPE_INT, NULL, FALSE, 58 }, // lifespan entry field
  2639.    { TYPE_INT, NULL, FALSE, 59 }, // constant spawn speed
  2640.    { TYPE_INT, NULL, FALSE, 60 }, // constant spawn scale
  2641.  
  2642.    { TYPE_INT, NULL, FALSE, 61 },  // custmlt
  2643.    { TYPE_FLOAT, NULL, FALSE, 62 }, // meta course Viewport
  2644.    { TYPE_INT, NULL, FALSE, 63},  // subframe rot
  2645.    { TYPE_INT, NULL, FALSE, 64 }, // Spawn PErcent
  2646.    { TYPE_FLOAT, NULL, FALSE, 65},  // spawn mult var
  2647.    { TYPE_INT, NULL, TRUE, 66 }, // Draft
  2648.    { TYPE_INT, NULL, TRUE, 67 }, // Dies after X
  2649.    { TYPE_FLOAT, NULL, TRUE, 68 }, // Dies after X var
  2650.  
  2651.    { TYPE_INT, NULL, FALSE, 69 }, // IPC Enable
  2652.    { TYPE_INT, NULL, FALSE, 70 }, // IPC Steps
  2653.    { TYPE_FLOAT, NULL, TRUE, 71 }, // IPC Bounce
  2654.    { TYPE_FLOAT, NULL, TRUE, 72 }, // IPC Bounce Var
  2655. };
  2656.  
  2657. static ParamVersionDesc Bversions[] = {
  2658.    ParamVersionDesc(BdescVer0,62,0),
  2659.    ParamVersionDesc(BdescVer1,63,1),
  2660.    ParamVersionDesc(BdescVer2,64,2),
  2661.    ParamVersionDesc(BdescVer3,66,3),
  2662.    ParamVersionDesc(BdescVer4,67,4),
  2663.    ParamVersionDesc(BdescVer5,69,5),
  2664.    };
  2665. #define PBLOCK_LENGTH_BLIZZARD 73
  2666.  
  2667. static ParamVersionDesc curVersionBL(BdescVer6,PBLOCK_LENGTH_BLIZZARD,CURRENT_VERSION);
  2668. static ParamVersionDesc curVersionSp(spdescVer6,PBLOCK_LENGTH_SUPRSPRAY,CURRENT_VERSION);
  2669.  
  2670. //-- ParticleDlgProc ------------------------------------------------
  2671.  
  2672. class CreateSSBlizProc : public MouseCallBack,ReferenceMaker {
  2673.    private:
  2674.       IObjParam *ip;
  2675.       void Init(IObjParam *i) {ip=i;}
  2676.       CreateMouseCallBack *createCB;  
  2677.       INode *CloudNode;
  2678.       CommonParticle *SSBlizObject;
  2679.       int attachedToNode;
  2680.       IObjCreate *createInterface;
  2681.       ClassDesc *cDesc;
  2682.       Matrix3 mat;  // the nodes TM relative to the CP
  2683.       Point3 p0,p1;
  2684.       IPoint2 sp0, sp1;
  2685.       BOOL square;
  2686.  
  2687.       int ignoreSelectionChange;
  2688.  
  2689.       int lastPutCount;
  2690.       void CreateNewObject();
  2691.  
  2692.       int NumRefs() { return 1; }
  2693.       RefTargetHandle GetReference(int i) { return (RefTargetHandle)CloudNode; }
  2694.       void SetReference(int i, RefTargetHandle rtarg) { CloudNode = (INode *)rtarg; }
  2695.  
  2696.       // StdNotifyRefChanged calls this, which can change the partID to new value
  2697.       // If it doesnt depend on the particular message& partID, it should return
  2698.       // REF_DONTCARE
  2699.       BOOL SupportAutoGrid(){return TRUE;}
  2700.        RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
  2701.          PartID& partID,  RefMessage message);
  2702.    public:
  2703.       void Begin( IObjCreate *ioc, ClassDesc *desc );
  2704.       void End();
  2705.      
  2706.       CreateSSBlizProc()
  2707.          {
  2708.          ignoreSelectionChange = FALSE;
  2709.          }
  2710. //    int createmethod(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat);
  2711.       int proc( HWND hwnd, int msg, int point, int flag, IPoint2 m );
  2712.    };
  2713. class ComObjectListRestore : public RestoreObj {
  2714.    public:        
  2715.       CommonParticle *po;
  2716.       Tab<INode*> unodes;
  2717.       Tab<INode*> rnodes;
  2718.       int lnum,lnum2;
  2719.       ComObjectListRestore(CommonParticle *p)
  2720.       {  po=p;
  2721.          unodes=p->nlist;
  2722.       }
  2723.       void Restore(int isUndo)
  2724.       {  if (isUndo) {
  2725.             rnodes = po->nlist;
  2726.             }
  2727.          po->nlist = unodes;
  2728.          po->NotifyDependents(FOREVER,0,REFMSG_CHANGE);
  2729.       }
  2730.       void Redo()
  2731.       {  po->nlist = rnodes;
  2732.          po->NotifyDependents(FOREVER,0,REFMSG_CHANGE);
  2733.       }
  2734.    };
  2735.  
  2736. class LifeListRestore : public RestoreObj {
  2737.    public:        
  2738.       CommonParticle *po;
  2739.       Tab<int> utimes;
  2740.       Tab<int> rtimes;
  2741.       LifeListRestore(CommonParticle *p)
  2742.       { po=p;
  2743.         utimes=p->llist;
  2744.       }
  2745.       void Restore(int isUndo)
  2746.       { if (isUndo) { rtimes = po->llist; }
  2747.         po->llist=utimes;
  2748.         if (po->ip) po->SetUpLifeList();
  2749.       }
  2750.       void Redo()
  2751.       { po->llist = rtimes;
  2752.         if (po->ip) po->SetUpLifeList();
  2753.       }
  2754.    };
  2755.  
  2756. class CreateCPartPickNode : public RestoreObj {
  2757.    public:        
  2758.       CommonParticle *obj;
  2759.       TSTR name,name2;
  2760.       CreateCPartPickNode(CommonParticle *o, TSTR n,TSTR n1) {
  2761.          obj = o; name=TSTR(n);name2=TSTR(n1);
  2762.          }
  2763.       void Restore(int isUndo) {
  2764.          if (obj->custnode)
  2765.           obj->custname = name;
  2766.          else
  2767.            obj->custname=TSTR(_T(""));
  2768.          obj->ShowName();
  2769.          }
  2770.       void Redo()
  2771.       { obj->custname = name2;
  2772.       if (obj->hptype)
  2773.    {TSTR name=TSTR(GetString(IDS_AP_OBJECTSTR)) + (_tcslen(name2)>0? obj->custname : TSTR(GetString(IDS_AP_NONE)));
  2774.    SetWindowText(GetDlgItem(obj->hptype, IDC_AP_INSTANCESRCNAME), name);}
  2775.          }
  2776.       TSTR Description() {return GetString(IDS_AP_COMPICK);}
  2777.    };
  2778. class CreateCPartDelNode : public RestoreObj {
  2779.    public:        
  2780.       CommonParticle *obj;
  2781.       TSTR name;
  2782.       CreateCPartDelNode(CommonParticle *o, TSTR n) {
  2783.          obj = o; name=TSTR(n);
  2784.          }
  2785.       void Restore(int isUndo)
  2786.       {obj->custname = name;
  2787.        obj->ShowName();
  2788.          }
  2789.       void Redo()
  2790.          {  obj->custname=TSTR(_T(""));
  2791.       if (obj->hptype)
  2792.    {TSTR name=TSTR(GetString(IDS_AP_OBJECTSTR)) + TSTR(GetString(IDS_AP_NONE));
  2793.    SetWindowText(GetDlgItem(obj->hptype, IDC_AP_INSTANCESRCNAME), name);}
  2794.          }
  2795.       TSTR Description() {return GetString(IDS_AP_COMPICK);}
  2796.    };
  2797.  
  2798. #define CID_CREATESSBlizMODE  CID_USER +15
  2799.  
  2800. class CreateSSBlizMode : public CommandMode {      
  2801.    public:    
  2802.       CreateSSBlizProc proc;
  2803.       IObjParam *ip;
  2804.       CommonParticle *obj;
  2805.       void Begin( IObjCreate *ioc, ClassDesc *desc ) { proc.Begin( ioc, desc ); }
  2806.       void End() { proc.End(); }
  2807.       void JumpStart(IObjParam *i,CommonParticle*o);
  2808.  
  2809.       int Class() {return CREATE_COMMAND;}
  2810.       int ID() { return CID_CREATESSBlizMODE; }
  2811.       MouseCallBack *MouseProc(int *numPoints) {*numPoints = 10000; return &proc;}
  2812.       ChangeForegroundCallback *ChangeFGProc() {return CHANGE_FG_SELECTED;}
  2813.       BOOL ChangeFG( CommandMode *oldMode ) { return (oldMode->ChangeFGProc() != CHANGE_FG_SELECTED); }
  2814.       void EnterMode()
  2815.       { GetCOREInterface()->PushPrompt(GetString(IDS_AP_CREATEMODE));
  2816.         SetCursor(LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CROSS_HAIR)));
  2817.       }
  2818.       void ExitMode() {GetCOREInterface()->PopPrompt();SetCursor(LoadCursor(NULL, IDC_ARROW));}
  2819.    };
  2820. static CreateSSBlizMode theCreateSSBlizMode;
  2821.  
  2822. RefResult CreateSSBlizProc::NotifyRefChanged(
  2823.    Interval changeInt,
  2824.    RefTargetHandle hTarget,
  2825.    PartID& partID,  
  2826.    RefMessage message)
  2827.    {
  2828.    switch (message) {
  2829.       case REFMSG_PRENOTIFY_PASTE:
  2830.       case REFMSG_TARGET_SELECTIONCHANGE:
  2831.          if ( ignoreSelectionChange ) {
  2832.             break;
  2833.             }
  2834.          if ( SSBlizObject && CloudNode==hTarget ) {
  2835.             // this will set camNode== NULL;
  2836.             theHold.Suspend();
  2837.             DeleteReference(0);
  2838.             theHold.Resume();
  2839.             goto endEdit;
  2840.             }
  2841.          // fall through
  2842.  
  2843.       case REFMSG_TARGET_DELETED:      
  2844.          if (SSBlizObject && CloudNode==hTarget ) {
  2845.             endEdit:
  2846.             if (createInterface->GetCommandMode()->ID() == CID_STDPICK)
  2847.             { if (SSBlizObject->creating)
  2848.                   {  theCreateSSBlizMode.JumpStart(SSBlizObject->ip,SSBlizObject);
  2849.                      createInterface->SetCommandMode(&theCreateSSBlizMode);
  2850.                    }
  2851.               else {createInterface->SetStdCommandMode(CID_OBJMOVE);}
  2852.             }
  2853. #ifdef _OSNAP
  2854.             SSBlizObject->ClearAFlag(A_OBJ_LONG_CREATE);
  2855. #endif
  2856.             SSBlizObject->EndEditParams( (IObjParam*)createInterface, 0, NULL);
  2857.             SSBlizObject  = NULL;            
  2858.             CloudNode    = NULL;
  2859. /*          if (theHold.GetGlobalPutCount()!=lastPutCount)
  2860.                GetSystemSetting(SYSSET_CLEAR_UNDO);*/
  2861.             CreateNewObject();  
  2862.             attachedToNode = FALSE;
  2863.             }
  2864.                  else if (CloudNode==hTarget )
  2865.                          CloudNode    = NULL;
  2866.          break;
  2867.       }
  2868.    return REF_SUCCEED;
  2869.    }
  2870.  
  2871. void CreateSSBlizProc::Begin( IObjCreate *ioc, ClassDesc *desc )
  2872.    {
  2873.    createInterface = ioc;
  2874.    cDesc           = desc;
  2875.    attachedToNode  = FALSE;
  2876.    createCB        = NULL;
  2877.    CloudNode         = NULL;
  2878.    SSBlizObject       = NULL;
  2879.    CreateNewObject();
  2880.    }
  2881. void CreateSSBlizProc::CreateNewObject()
  2882. {
  2883.    SuspendSetKeyMode();
  2884.    createInterface->GetMacroRecorder()->BeginCreate(cDesc);
  2885.    SSBlizObject = (CommonParticle*)cDesc->Create();
  2886.    lastPutCount  = theHold.GetGlobalPutCount();
  2887.    
  2888.    // Start the edit params process
  2889.    if ( SSBlizObject ) {
  2890.       SSBlizObject->BeginEditParams( (IObjParam*)createInterface, BEGIN_EDIT_CREATE, NULL );
  2891. #ifdef _OSNAP
  2892.       SSBlizObject->SetAFlag(A_OBJ_LONG_CREATE);
  2893. #endif
  2894.       }  
  2895.    ResumeSetKeyMode();
  2896.    }
  2897.  
  2898. //LACamCreationManager::~LACamCreationManager
  2899. void CreateSSBlizProc::End()
  2900. { if ( SSBlizObject )
  2901.    {
  2902. #ifdef _OSNAP
  2903.       SSBlizObject->ClearAFlag(A_OBJ_LONG_CREATE);
  2904. #endif
  2905.    
  2906.    SSBlizObject->EndEditParams( (IObjParam*)createInterface,
  2907.                                   END_EDIT_REMOVEUI, NULL);
  2908.       if ( !attachedToNode )
  2909.       {  // RB 4-9-96: Normally the hold isn't holding when this
  2910.          // happens, but it can be in certain situations (like a track view paste)
  2911.          // Things get confused if it ends up with undo...
  2912.          createInterface->GetMacroRecorder()->Cancel();
  2913.          theHold.Suspend();
  2914.                  SSBlizObject->DeleteAllRefsFromMe();
  2915.                  SSBlizObject->DeleteAllRefsToMe();
  2916.                  SSBlizObject->DeleteThis();
  2917.          SSBlizObject = NULL;
  2918.          theHold.Resume();
  2919.          if (theHold.GetGlobalPutCount()!=lastPutCount)
  2920.             GetSystemSetting(SYSSET_CLEAR_UNDO);
  2921.       }  else if ( CloudNode )
  2922.       {  theHold.Suspend();
  2923.          DeleteReference(0);  // sets cloudNode = NULL
  2924.          theHold.Resume();}
  2925.    }
  2926. }
  2927.  
  2928. void CreateSSBlizMode::JumpStart(IObjParam *i,CommonParticle *o)
  2929.    {
  2930.    ip  = i;
  2931.    obj = o;
  2932.    obj->BeginEditParams(i,BEGIN_EDIT_CREATE,NULL);
  2933.    }
  2934.  
  2935. int BlizzardClassDesc::BeginCreate(Interface *i)
  2936.    {  
  2937.    SuspendSetKeyMode();
  2938.    IObjCreate *iob = i->GetIObjCreate();
  2939.    theCreateSSBlizMode.Begin(iob,this);
  2940.    iob->PushCommandMode(&theCreateSSBlizMode);
  2941.    return TRUE;
  2942.    }
  2943.  
  2944. int BlizzardClassDesc::EndCreate(Interface *i)
  2945.    {
  2946.    ResumeSetKeyMode();
  2947.    theCreateSSBlizMode.End();
  2948.    i->RemoveMode(&theCreateSSBlizMode);
  2949.    macroRec->EmitScript();  // 10/00
  2950.    return TRUE;
  2951.    }
  2952. int SuprSprayClassDesc::BeginCreate(Interface *i)
  2953.    {  
  2954.    SuspendSetKeyMode();
  2955.    IObjCreate *iob = i->GetIObjCreate();
  2956.    theCreateSSBlizMode.Begin(iob,this);
  2957.    iob->PushCommandMode(&theCreateSSBlizMode);
  2958.    return TRUE;
  2959.    }
  2960.  
  2961. int SuprSprayClassDesc::EndCreate(Interface *i)
  2962.    {
  2963.    ResumeSetKeyMode();
  2964.    theCreateSSBlizMode.End();
  2965.    i->RemoveMode(&theCreateSSBlizMode);
  2966.    return TRUE;
  2967.    }
  2968.  
  2969. int CreateSSBlizProc::proc(HWND hwnd,int msg,int point,int flag,
  2970.             IPoint2 m )
  2971. {  int res=TRUE;  
  2972.    ViewExp *vpx = createInterface->GetViewport(hwnd);
  2973.    assert( vpx );
  2974.  
  2975.    INode *l_CloudNode = NULL;
  2976.  
  2977. #ifdef _3D_CREATE
  2978.    DWORD snapdim = SNAP_IN_3D;
  2979. #else
  2980.    DWORD snapdim = SNAP_IN_PLANE;
  2981. #endif
  2982.  
  2983.    switch ( msg ) {
  2984.       case MOUSE_POINT:
  2985.          switch ( point ) {
  2986.             case 0:
  2987.                assert( SSBlizObject );            
  2988.                vpx->CommitImplicitGrid(m, flag );
  2989.                if ( createInterface->SetActiveViewport(hwnd) ) {
  2990.                   return FALSE;
  2991.                   }
  2992.  
  2993.                if (createInterface->IsCPEdgeOnInView()) {
  2994.                   res = FALSE;
  2995.                   goto done;
  2996.                   }
  2997.  
  2998.                if ( attachedToNode ) {
  2999.                      // send this one on its way
  3000. #ifdef _OSNAP
  3001.                   SSBlizObject->ClearAFlag(A_OBJ_LONG_CREATE);
  3002. #endif
  3003.                      SSBlizObject->EndEditParams( (IObjParam*)createInterface, 0, NULL);
  3004.               createInterface->GetMacroRecorder()->EmitScript();
  3005.                   // Get rid of the reference.
  3006.                   if (CloudNode) {
  3007.                      theHold.Suspend();
  3008.                      DeleteReference(0);
  3009.                      theHold.Resume();
  3010.                      }
  3011.                   // new object
  3012.                   CreateNewObject();   // creates SSBlizObject
  3013.                   }
  3014.  
  3015.                   theHold.Begin();   // begin hold for undo
  3016.                mat.IdentityMatrix();
  3017.  
  3018.                // link it up
  3019.                l_CloudNode = createInterface->CreateObjectNode( SSBlizObject);
  3020.                attachedToNode = TRUE;
  3021.                assert( l_CloudNode );            
  3022.                createCB = SSBlizObject->GetCreateMouseCallBack();
  3023.                createInterface->SelectNode( l_CloudNode );
  3024.                
  3025.                // Reference the new node so we'll get notifications.
  3026.                theHold.Suspend();
  3027.                ReplaceReference( 0, l_CloudNode);
  3028.                theHold.Resume();
  3029.                mat.IdentityMatrix();
  3030.             default:          
  3031.                if (createCB) {                  
  3032.                   res = createCB->proc(vpx,msg,point,flag,m,mat);
  3033. //                macroRec->Disable();   // 10/00
  3034.                   createInterface->SetNodeTMRelConstPlane(CloudNode,mat);
  3035. //                macroRec->Enable();
  3036.  
  3037.                   if (res==CREATE_ABORT)
  3038.                      goto abort;
  3039.                   if (res==CREATE_STOP)
  3040.                   {
  3041. #ifdef _OSNAP
  3042.                          SSBlizObject->ClearAFlag(A_OBJ_LONG_CREATE);
  3043. #endif
  3044.                    theHold.Accept(GetString(IDS_DS_CREATE));  
  3045.                   }
  3046.                  
  3047.                   createInterface->RedrawViews(createInterface->GetTime());   //DS
  3048.                   }
  3049.  
  3050.                break;
  3051.                
  3052.             }        
  3053.          break;
  3054.  
  3055.       case MOUSE_MOVE:
  3056.          if (createCB) {            
  3057.             res = createCB->proc(vpx,msg,point,flag,m,mat);
  3058. //          macroRec->Disable();   // 10/00
  3059.             createInterface->SetNodeTMRelConstPlane(CloudNode,mat);
  3060. //          macroRec->Enable();
  3061.             if (res==CREATE_ABORT)
  3062.                goto abort;
  3063.             if (res==CREATE_STOP){
  3064. #ifdef _OSNAP
  3065.          SSBlizObject->ClearAFlag(A_OBJ_LONG_CREATE);
  3066. #endif
  3067.                theHold.Accept(GetString(IDS_DS_CREATE)); // TH
  3068.             }
  3069.             createInterface->RedrawViews(createInterface->GetTime(),REDRAW_INTERACTIVE);     //DS    
  3070.             }
  3071.          break;
  3072.  
  3073.    case MOUSE_PROPCLICK:
  3074.       createInterface->SetStdCommandMode(CID_OBJMOVE);
  3075.       break;
  3076.       case MOUSE_ABORT:
  3077.    if (createCB)
  3078.    { res = createCB->proc(vpx,msg,point,flag,m,mat);
  3079.      createInterface->SetNodeTMRelConstPlane(CloudNode, mat);
  3080.      if (res==CREATE_ABORT)
  3081.          goto abort;
  3082.      if (res==CREATE_STOP)
  3083.      {
  3084. #ifdef _OSNAP
  3085.          SSBlizObject->ClearAFlag(A_OBJ_LONG_CREATE);
  3086. #endif
  3087.        theHold.Accept(GetString(IDS_DS_CREATE));  
  3088.      }
  3089.       break;
  3090.    }
  3091.    abort:
  3092.       assert( SSBlizObject );
  3093. #ifdef _OSNAP
  3094.       SSBlizObject->ClearAFlag(A_OBJ_LONG_CREATE);
  3095. #endif
  3096.       SSBlizObject->EndEditParams( (IObjParam*)createInterface,0,NULL);
  3097.       theHold.Cancel();  // deletes both the Cloudera and target.
  3098.       if (theHold.GetGlobalPutCount()!=lastPutCount)
  3099.                GetSystemSetting(SYSSET_CLEAR_UNDO);
  3100.       SSBlizObject=NULL;
  3101.       createInterface->RedrawViews(createInterface->GetTime());
  3102.       CreateNewObject();  
  3103.       attachedToNode = FALSE;
  3104.       res = FALSE;
  3105.       break;
  3106.    
  3107.       case MOUSE_FREEMOVE:
  3108.          SetCursor(LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CROSS_HAIR)));
  3109. #ifdef _OSNAP  //PREVIEW SNAP
  3110.          if (createCB) res =createCB->proc(vpx,msg,point,flag,m,mat);
  3111. #endif
  3112.       vpx->TrackImplicitGrid(m);
  3113.          break;
  3114.    }
  3115.  
  3116.    done:
  3117.    if ((res == CREATE_STOP)||(res==CREATE_ABORT))
  3118.       vpx->ReleaseImplicitGrid();
  3119.    createInterface->ReleaseViewport(vpx);
  3120.    return res;
  3121. }
  3122.  
  3123. void CheckInstButtons(IParamBlock *pblock,HWND hptype)
  3124. { int isinst;
  3125.   pblock->GetValue(PB_PARTICLECLASS,0,isinst,FOREVER);
  3126.   if (isinst==INSTGEOM)
  3127.   { TurnButton(hptype,IDC_AP_OBJECTPICK,TRUE);
  3128.   }
  3129. }
  3130. void CheckLifeButtons(int stype,HWND spawn)
  3131. { int rep;
  3132.   rep = SendMessage(GetDlgItem(spawn,IDC_AP_LIFEQUEUE),LB_GETCURSEL,0,0);
  3133.   TurnButton(spawn,IDC_AP_LIFEQUEUEADD,(stype>1));
  3134.   TurnButton(spawn,IDC_AP_LIFEQUEUEREPL,(stype>1)&&(rep>-1));
  3135.   TurnButton(spawn,IDC_AP_LIFEQUEUEDEL,(stype>1)&&(rep>-1));
  3136. }
  3137.  
  3138. void CheckSpawnButtons(IParamBlock *pblock,HWND spawn,int repi)
  3139. { int stype;
  3140.   pblock->GetValue(PB_SPAWNTYPE,0,stype,FOREVER);
  3141.   EnableWindow(GetDlgItem(spawn,IDC_AP_OBJECTQUEUE),(stype>1));
  3142.   TurnButton(spawn,IDC_AP_OBJECTQUEUEPICK,(stype>1));
  3143.   TurnButton(spawn,IDC_AP_OBJQUEUEREPLACE,(stype>1)&&(repi>-1));
  3144.   TurnButton(spawn,IDC_AP_OBJQUEUEDELETE,(stype>1)&&(repi>-1));
  3145.   CheckLifeButtons(stype,spawn);
  3146. }
  3147.  
  3148. void CheckPickButtons(IParamBlock *pblock,HWND hptype,HWND spawn,int repi)
  3149. { CheckInstButtons(pblock,hptype);
  3150.   CheckSpawnButtons(pblock,spawn,repi);
  3151. }
  3152.  
  3153. class EmitterCreateCallback : public CreateMouseCallBack {
  3154.    public:
  3155.       SuprSprayParticle *po;
  3156.       Point3 p0,p1;
  3157.       IPoint2 sp0, sp1;
  3158.       int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat);
  3159.    };
  3160.  
  3161. int EmitterCreateCallback::proc(
  3162.       ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat)
  3163. {
  3164. #ifdef _3D_CREATE
  3165.    DWORD snapdim = SNAP_IN_3D;
  3166. #else
  3167.    DWORD snapdim = SNAP_IN_PLANE;
  3168. #endif
  3169.  
  3170. #ifdef _OSNAP
  3171.    if (msg == MOUSE_FREEMOVE)
  3172.    { vpt->SnapPreview(m,m,NULL, snapdim);
  3173.    }
  3174. #endif
  3175.    if (msg==MOUSE_POINT||msg==MOUSE_MOVE) {
  3176.       switch(point)  {
  3177.          case 0:
  3178.             // if hidden by category, re-display particles and objects
  3179.             GetCOREInterface()->SetHideByCategoryFlags(
  3180.                   GetCOREInterface()->GetHideByCategoryFlags() & ~(HIDE_OBJECTS|HIDE_PARTICLES));
  3181.             sp0 = m;
  3182.             p0 = vpt->SnapPoint(m,m,NULL,snapdim);
  3183.             mat.SetTrans(p0);
  3184.             po->pblock->SetValue(PB_EMITRWID,0,0.01f);
  3185.             po->pmapParam->Invalidate();
  3186.             break;
  3187.  
  3188.          case 1: {
  3189. //          mat.IdentityMatrix();
  3190.             sp1 = m;
  3191.             p1 = vpt->SnapPoint(m,m,NULL,snapdim);
  3192.             po->pblock->SetValue(PB_EMITRWID,0,Length(p1-p0));
  3193.             po->pmapParam->Invalidate();
  3194.  
  3195.             if (msg==MOUSE_POINT) {
  3196.                if (Length(m-sp0)<3 || Length(p1-p0)<0.1f) {                
  3197.                   return CREATE_ABORT;
  3198.                } else { CheckPickButtons(po->pblock,po->hptype,po->spawn,po->pickCB.repi);
  3199.                   return CREATE_STOP;
  3200.                   }
  3201.                }
  3202.             break;
  3203.             }
  3204.  
  3205.          }
  3206.    } else {
  3207.       if (msg == MOUSE_ABORT)
  3208.          return CREATE_ABORT;
  3209.       }
  3210.    return 1;
  3211.    }
  3212.  
  3213. static EmitterCreateCallback emitterCallback;
  3214.  
  3215. CreateMouseCallBack* SuprSprayParticle::GetCreateMouseCallBack()
  3216.    {
  3217.    emitterCallback.po = this;
  3218.    return &emitterCallback;
  3219.    }
  3220.  
  3221. class SSParticleGenDlgProc : public ParamMapUserDlgProc {
  3222.    public:
  3223.       CommonParticle *po;
  3224.  
  3225.       SSParticleGenDlgProc(CommonParticle *p) {po=p;}
  3226.       INT_PTR DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
  3227.       void Update(TimeValue t);
  3228.       void DeleteThis() {delete this;}
  3229.    };
  3230. void SSParticleGenDlgProc::Update(TimeValue t)
  3231. { if (!po->editOb) return;
  3232.   int birthmeth;
  3233.   po->pblock->GetValue(PB_BIRTHMETHOD,0,birthmeth,FOREVER);
  3234.   if (birthmeth)
  3235.   { SpinnerOff(po->hgen,IDC_SP_GENRATESPIN,IDC_SP_GENRATE);
  3236.     SpinnerOn(po->hgen,IDC_SP_GENTTLSPIN,IDC_SP_GENTTL);
  3237.   }else
  3238.   { SpinnerOn(po->hgen,IDC_SP_GENRATESPIN,IDC_SP_GENRATE);
  3239.     SpinnerOff(po->hgen,IDC_SP_GENTTLSPIN,IDC_SP_GENTTL);
  3240.   }
  3241. }
  3242.  
  3243. INT_PTR SSParticleGenDlgProc::DlgProc(
  3244.       TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
  3245.    {  int acourse;
  3246.        float size;
  3247.       switch (msg)
  3248.      { case WM_INITDIALOG: {
  3249.           Update(t);
  3250.          break;
  3251.          }
  3252.       case WM_COMMAND:
  3253.          switch (LOWORD(wParam))
  3254.          { case IDC_SP_GENUSERATE:
  3255.             { SpinnerOn(hWnd,IDC_SP_GENRATESPIN,IDC_SP_GENRATE);
  3256.               SpinnerOff(hWnd,IDC_SP_GENTTLSPIN,IDC_SP_GENTTL);
  3257.              return TRUE;
  3258.             }
  3259.            case IDC_SP_GENUSETTL:
  3260.             { SpinnerOff(hWnd,IDC_SP_GENRATESPIN,IDC_SP_GENRATE);
  3261.               SpinnerOn(hWnd,IDC_SP_GENTTLSPIN,IDC_SP_GENTTL);
  3262.              return TRUE;
  3263.             }
  3264.          }
  3265.          case CC_SPINNER_CHANGE:
  3266.          switch ( LOWORD(wParam) )
  3267.          { case IDC_SP_GENSIZESPIN:
  3268.                { po->pblock->GetValue(PB_METAAUTOCOARSE,t,acourse,FOREVER);
  3269.                int mpart;
  3270.                 po->pblock->GetValue(PB_PARTICLECLASS,t,mpart,FOREVER);
  3271.                 if ((mpart==METABALLS)&&(acourse) )
  3272.                 { po->pblock->GetValue(PB_SIZE,t,size,FOREVER);
  3273.                   po->pblock->SetValue(PB_METACOURSE,t,size/coursedivider);
  3274.                   BOOL bliz=(po->ClassID()==BLIZZARD_CLASS_ID);
  3275.                   if (bliz) po->pblock->SetValue(PB_METACOURSEVB,t,size/3.0f);
  3276.                   else po->pblock->SetValue(PB_METACOURSEV,t,size/3.0f);
  3277.                   po->pmapPType->Invalidate();
  3278.                 }
  3279.                break;
  3280.                }
  3281.             case IDC_AP_NEWSEED:
  3282.                { srand( (unsigned)time( NULL ) );
  3283.                  int newseed=rand() % 25001;
  3284.                  po->pblock->SetValue(PB_RNDSEED,0,newseed);
  3285.                  po->pmapPGen->Invalidate();
  3286.                }
  3287.                  return TRUE;
  3288.             case IDC_SP_GENEMIT1SPIN:
  3289.             case IDC_SP_GENEMIT2SPIN:
  3290.                { int sstop,sstart;
  3291.                  po->pblock->GetValue(PB_EMITSTOP,t,sstop,FOREVER);
  3292.                  po->pblock->GetValue(PB_EMITSTART,t,sstart,FOREVER);
  3293.                  if (sstop<sstart)
  3294.                     po->pblock->SetValue(PB_EMITSTOP,t,sstart);
  3295.                  return TRUE;
  3296.                }
  3297.          }
  3298.      }
  3299.    return FALSE;
  3300.    }
  3301. void CourseCheck(CommonParticle *po,HWND hWnd,TimeValue t)
  3302. { int acourse;
  3303.   float size;
  3304.   po->pblock->GetValue(PB_METAAUTOCOARSE,t,acourse,FOREVER);
  3305.   BOOL bliz=(po->ClassID()==BLIZZARD_CLASS_ID);
  3306.   if (acourse)
  3307.   { float mc1,mc2,mc,mcv;
  3308.    po->pblock->GetValue(PB_SIZE,t,size,FOREVER);mc=size/coursedivider;mcv=size/3.0f;
  3309.    po->pblock->GetValue(PB_METACOURSE,t,mc1,FOREVER);
  3310.    if (bliz) po->pblock->GetValue(PB_METACOURSEVB,t,mc2,FOREVER);
  3311.    else po->pblock->GetValue(PB_METACOURSEV,t,mc2,FOREVER);
  3312.    if ((mc1!=mc)||(mc2!=mcv))
  3313.    { po->pblock->SetValue(PB_METACOURSE,t,mc);
  3314.      if (bliz) po->pblock->SetValue(PB_METACOURSEVB,t,mcv);
  3315.      else po->pblock->SetValue(PB_METACOURSEV,t,mcv);
  3316.      po->pmapPType->Invalidate();
  3317.    }
  3318.    SpinnerOff(hWnd,IDC_SP_METCOURSESPIN,IDC_SP_METCOURSE);
  3319.    SpinnerOff(hWnd,IDC_SP_METCOURSEVSPIN,IDC_SP_METCOURSEV);
  3320.    EnableWindow(GetDlgItem(hWnd,IDC_SP_COARSENESS_TXT),FALSE);
  3321.    EnableWindow(GetDlgItem(hWnd,IDC_SP_METCOURSE_TXT),FALSE);
  3322.    EnableWindow(GetDlgItem(hWnd,IDC_SP_METCOURSEV_TXT),FALSE);
  3323.   }
  3324.   else
  3325.   { SpinnerOn(hWnd,IDC_SP_METCOURSESPIN,IDC_SP_METCOURSE);
  3326.    SpinnerOn(hWnd,IDC_SP_METCOURSEVSPIN,IDC_SP_METCOURSEV);
  3327.    EnableWindow(GetDlgItem(hWnd,IDC_SP_COARSENESS_TXT),TRUE);
  3328.    EnableWindow(GetDlgItem(hWnd,IDC_SP_METCOURSE_TXT),TRUE);
  3329.    EnableWindow(GetDlgItem(hWnd,IDC_SP_METCOURSEV_TXT),TRUE);
  3330.    }
  3331. };
  3332. void SetMapVals(IParamBlock *pblock,HWND hWnd,TimeValue t)
  3333. { int type,maptype;
  3334.   pblock->GetValue(PB_PARTICLETYPE,t,type,FOREVER);
  3335.   if (type==RENDTET)
  3336.   { SpinnerOff(hWnd,IDC_SP_MAPTIMEVALSPIN,IDC_SP_MAPTIMEVAL);
  3337.    SpinnerOff(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3338.    EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPDIST),FALSE);
  3339.    EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPTIME),FALSE);
  3340.   }
  3341.   else
  3342.   { pblock->GetValue(PB_MAPPINGTYPE,t,maptype,FOREVER);
  3343.     if (maptype==2)
  3344.    { SpinnerOff(hWnd,IDC_SP_MAPTIMEVALSPIN,IDC_SP_MAPTIMEVAL);
  3345.      SpinnerOff(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3346.    }
  3347.     else if (maptype)
  3348.    { SpinnerOff(hWnd,IDC_SP_MAPTIMEVALSPIN,IDC_SP_MAPTIMEVAL);
  3349.      SpinnerOn(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3350.    }
  3351.    else
  3352.    { SpinnerOn(hWnd,IDC_SP_MAPTIMEVALSPIN,IDC_SP_MAPTIMEVAL);
  3353.      SpinnerOff(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3354.    }
  3355.    EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPDIST),TRUE);
  3356.    EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPTIME),TRUE);
  3357.   }
  3358. }
  3359.  
  3360. void MappingStuff(IParamBlock *pblock,HWND hWnd,TimeValue t,BOOL isbliz)
  3361. { int maptype;
  3362.   pblock->GetValue((isbliz?PB_CUSTOMMTL2:PB_CUSTOMMTL),t,maptype,FOREVER);
  3363.   if (isbliz)
  3364.   EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPPLANAR),!maptype);
  3365.   if (maptype)
  3366.   { SpinnerOff(hWnd,IDC_SP_MAPTIMEVALSPIN,IDC_SP_MAPTIMEVAL);
  3367.     SpinnerOff(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3368.     EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPTIME),FALSE);
  3369.     EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPDIST),FALSE);
  3370.   }
  3371.   else SetMapVals(pblock,hWnd,t);
  3372. }
  3373. void CheckStretchBox(HWND hWnd,CommonParticle *po)
  3374. { int enon=0;
  3375.   if (IsStdMtl(po->cnode))
  3376.   { EnableWindow(GetDlgItem(hWnd,IDC_AP_PBLURON),TRUE);
  3377.   } else EnableWindow(GetDlgItem(hWnd,IDC_AP_PBLURON),FALSE);
  3378.   SpinnerOn(hWnd,IDC_AP_STRETCHSPIN,IDC_AP_STRETCH);
  3379.   EnableWindow(GetDlgItem(hWnd,IDC_AP_STRETCH_TXT),TRUE);
  3380.   po->pmapPSpin->Invalidate();
  3381. }
  3382.  
  3383. void StretchStuff(int dir,int isphase,HWND hWnd,CommonParticle *po)
  3384. { if (dir==0)
  3385.   { EnableWindow(GetDlgItem(hWnd,IDC_AP_PBLURON),FALSE);
  3386.    SpinnerOff(hWnd,IDC_AP_STRETCHSPIN,IDC_AP_STRETCH);
  3387.    EnableWindow(GetDlgItem(hWnd,IDC_AP_STRETCH_TXT),FALSE);
  3388.    SpinStuff(hWnd,FALSE,isphase);
  3389.   }
  3390.   else if (dir==1)
  3391.   {   CheckStretchBox(hWnd,po);
  3392.    SpinStuff(hWnd,FALSE,isphase);
  3393.   }  
  3394.   else if (dir==2)
  3395.   {   EnableWindow(GetDlgItem(hWnd,IDC_AP_PBLURON),FALSE);
  3396.    SpinnerOff(hWnd,IDC_AP_STRETCHSPIN,IDC_AP_STRETCH);
  3397.    EnableWindow(GetDlgItem(hWnd,IDC_AP_STRETCH_TXT),FALSE);
  3398.    SpinStuff(hWnd,TRUE,isphase);
  3399.   }
  3400. }
  3401.  
  3402. void AniFr(HWND hWnd,IParamBlock *pblock)
  3403. { int anitype;
  3404.   pblock->GetValue(PB_ANIMATIONOFFSET,0,anitype,FOREVER);
  3405.   if (anitype>1)
  3406.      SpinnerOn(hWnd,IDC_AP_ANIRNDFRSPIN,IDC_AP_ANIRNDFR);
  3407.   else   SpinnerOff(hWnd,IDC_AP_ANIRNDFRSPIN,IDC_AP_ANIRNDFR);
  3408.   EnableWindow(GetDlgItem(hWnd,IDC_AP_ANIRNDFR_TXT),anitype>1);
  3409. }
  3410. void InstIn(CommonParticle *po,HWND hWnd, TimeValue t)
  3411. { int ison;
  3412.   BOOL isbliz;
  3413.   MetaOff(hWnd);
  3414.   StdStuff(hWnd,FALSE);
  3415.   InstStuff(hWnd,TRUE,po->spawn,po->hparam);
  3416.   AniFr(hWnd,po->pblock);
  3417.   TurnButton(hWnd,IDC_AP_OBJECTPICK,TRUE);
  3418.   isbliz=(po->ClassID()==BLIZZARD_CLASS_ID);
  3419.   po->pblock->GetValue(PB_SPINAXISTYPE,0,ison,FOREVER);
  3420.   if (isbliz) SpinStuff(po->hrot,ison,TRUE);
  3421.   else StretchStuff(ison,TRUE,po->hrot,po);
  3422.   SpinMainStuff(po->hrot,TRUE);
  3423.   EnableWindow(GetDlgItem(hWnd,IDC_SP_AUTOCOARSE),FALSE);
  3424.   EnableWindow(GetDlgItem(po->hparam,IDC_SP_VIEWDISPBOX),TRUE);
  3425.   EnableWindow(GetDlgItem(hWnd,IDC_SP_DRAFTMODE),FALSE);
  3426.   MappingStuff(po->pblock,hWnd,t,isbliz);
  3427.   int stype;po->pblock->GetValue(PB_SPAWNTYPE,0,stype,FOREVER);
  3428.   ObjectMutQueOn(stype,po->spawn,po->pickCB.repi);
  3429.   if (!isbliz)
  3430.     EnableWindow(GetDlgItem(po->hrot,IDC_AP_PARTICLEDIRTRAVL),TRUE);
  3431.   po->pmapPSpin->Invalidate();
  3432. }
  3433.  
  3434. void MetaIn(CommonParticle *po,HWND hWnd,TimeValue t)
  3435. { BOOL isbliz;
  3436.   isbliz=(po->ClassID()==BLIZZARD_CLASS_ID);
  3437.   int mon,pname=(isbliz?PB_CUSTOMMTL2:PB_CUSTOMMTL);
  3438.   po->pblock->GetValue(pname,t,mon,FOREVER);
  3439.   if (mon>0) po->pblock->SetValue(pname,t,0);
  3440.   SpinnerOn(hWnd,IDC_SP_METTENSSPIN,IDC_SP_METTENS);
  3441.   SpinnerOn(hWnd,IDC_SP_METTENSVARSPIN,IDC_SP_METTENSVAR);
  3442.   EnableWindow(GetDlgItem(hWnd,IDC_SP_METTENS_TXT),TRUE);
  3443.   EnableWindow(GetDlgItem(hWnd,IDC_SP_METTENSVAR_TXT),TRUE);
  3444.   EnableWindow(GetDlgItem(hWnd,IDC_SP_METTENSVAR_PCNT),TRUE);
  3445.   EnableWindow(GetDlgItem(hWnd,IDC_SP_AUTOCOARSE),TRUE);
  3446.   CourseCheck(po,hWnd,t);
  3447.   if (isbliz) SpinStuff(po->hrot,FALSE,FALSE);
  3448.   else StretchStuff(0,FALSE,po->hrot,po);
  3449.   SpinMainStuff(po->hrot,FALSE);
  3450.   EnableWindow(GetDlgItem(po->hparam,IDC_SP_VIEWDISPMESH),TRUE);
  3451.   int showtype;
  3452.   po->pblock->GetValue(PB_VIEWPORTSHOWS,0,showtype,FOREVER);
  3453.   if (showtype==3) po->pblock->SetValue(PB_VIEWPORTSHOWS,0,0);
  3454.   EnableWindow(GetDlgItem(po->hparam,IDC_SP_VIEWDISPBOX),FALSE);
  3455.   TurnButton(hWnd,IDC_AP_OBJECTPICK,FALSE);
  3456.   StdStuff(hWnd,FALSE);
  3457.   InstStuff(hWnd,FALSE,po->spawn,po->hparam);
  3458.   isbliz=(po->ClassID()==BLIZZARD_CLASS_ID);
  3459.   MappingStuff(po->pblock,hWnd,t,isbliz);
  3460.   ObjectMutQueOff(po->spawn);
  3461.   if (!isbliz) EnableWindow(GetDlgItem(po->hrot,IDC_AP_PARTICLEDIRTRAVL),FALSE);
  3462.   EnableWindow(GetDlgItem(hWnd,IDC_SP_DRAFTMODE),TRUE);
  3463.   int stype;
  3464.   po->pblock->GetValue(PB_SPAWNTYPE,0,stype,FOREVER);
  3465. //  if (stype>1) po->pblock->SetValue(PB_SPAWNTYPE,0,0);  AllSpawnBad(po->spawn,0,FALSE);
  3466.   int ison; po->pblock->GetValue((isbliz?PB_BLIPCOLLIDE_ON:PB_IPCOLLIDE_ON),t,ison,FOREVER);
  3467.   if (ison) stype=0;
  3468.   SpawnStuff(po->spawn,stype);
  3469.   po->pmapPSpin->Invalidate();
  3470. }
  3471.  
  3472. void StdOn(CommonParticle *po,HWND hWnd,TimeValue t)
  3473. { int ison,mon;
  3474.   BOOL isbliz;
  3475.   StdStuff(hWnd,TRUE);
  3476.   isbliz=(po->ClassID()==BLIZZARD_CLASS_ID);
  3477.   int pname=(isbliz?PB_CUSTOMMTL2:PB_CUSTOMMTL);
  3478.   po->pblock->GetValue(pname,t,mon,FOREVER);
  3479.   if (mon>0) po->pblock->SetValue(pname,t,0);
  3480.   po->pblock->GetValue(PB_SPINAXISTYPE,0,ison,FOREVER);
  3481.   if (isbliz) SpinStuff(po->hrot,ison,TRUE);
  3482.   else StretchStuff(ison,TRUE,po->hrot,po);
  3483.   SpinMainStuff(po->hrot,TRUE);
  3484.   int facing;
  3485.   po->pblock->GetValue(PB_PARTICLETYPE,t,facing,FOREVER);
  3486. /*
  3487.    if ((facing==RENDTYPE5)||(facing==RENDTYPE6))
  3488.    {    
  3489.       po->pblock->GetValue(PB_VIEWPORTSHOWS,t,facing,FOREVER);
  3490.       if (facing==2)
  3491.          po->pblock->SetValue(PB_VIEWPORTSHOWS,t,1);
  3492.       EnableWindow(GetDlgItem(po->hparam,IDC_SP_VIEWDISPMESH),FALSE);
  3493.    }
  3494.    else  
  3495.    */
  3496.       EnableWindow(GetDlgItem(po->hparam,IDC_SP_VIEWDISPMESH),TRUE);
  3497.   TurnButton(hWnd,IDC_AP_OBJECTPICK,FALSE);
  3498.   int showtype;
  3499.   po->pblock->GetValue(PB_VIEWPORTSHOWS,0,showtype,FOREVER);
  3500.   if (showtype==3) po->pblock->SetValue(PB_VIEWPORTSHOWS,0,0);
  3501.   EnableWindow(GetDlgItem(po->hparam,IDC_SP_VIEWDISPBOX),FALSE);
  3502.  // SpinnerOn(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3503.   MetaOff(hWnd);
  3504.   InstStuff(hWnd,FALSE,po->spawn,po->hparam);
  3505.   MappingStuff(po->pblock,hWnd,t,isbliz);
  3506.   ObjectMutQueOff(po->spawn);
  3507.   if (!isbliz)
  3508.     EnableWindow(GetDlgItem(po->hrot,IDC_AP_PARTICLEDIRTRAVL),TRUE);
  3509.   po->pmapPSpin->Invalidate();
  3510. }
  3511.  
  3512. class BLParticleDlgProc : public ParamMapUserDlgProc {
  3513.    public:
  3514.       BlizzardParticle *po;
  3515.  
  3516.       BLParticleDlgProc(BlizzardParticle *p) {po=p;}
  3517.       INT_PTR DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
  3518.       void DeleteThis() {delete this;}
  3519.    };
  3520.  
  3521. INT_PTR BLParticleDlgProc::DlgProc(
  3522.       TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
  3523. {  switch (msg) {
  3524.       case WM_INITDIALOG: {
  3525.          break;
  3526.          }
  3527.       case WM_COMMAND:
  3528.          switch (LOWORD(wParam))
  3529.          { case IDC_SP_VIEWDISPMESH:
  3530.               {po->valid=FALSE;
  3531.                int subtree,custmtl;
  3532.                po->pblock->GetValue(PB_CUSTOMMTL2,0,custmtl,FOREVER);
  3533.                po->pblock->GetValue(PB_USESUBTREE,0,subtree,FOREVER);
  3534.                int anioff;
  3535.                po->pblock->GetValue(PB_ANIMATIONOFFSET,0,anioff,FOREVER);
  3536.                po->theSuprSprayDraw.t=t;
  3537.                po->theSuprSprayDraw.anioff=anioff;
  3538.                TimeValue aniend=GetAnimEnd();
  3539.                int anifr;
  3540.                anifr=aniend+GetTicksPerFrame();
  3541.                po->theSuprSprayDraw.anifr=anifr;
  3542.                po->GetTimes(po->times,t,anifr,anioff);
  3543.                 po->GetMesh(t,subtree,custmtl);
  3544.                break;
  3545.               }
  3546.            case IDC_SP_VIEWDISPBOX:        
  3547.               { po->valid=FALSE;
  3548.                int subtree;
  3549.                po->pblock->GetValue(PB_USESUBTREE,0,subtree,FOREVER);
  3550.                int anioff;
  3551.                po->pblock->GetValue(PB_ANIMATIONOFFSET,0,anioff,FOREVER);
  3552.                po->theSuprSprayDraw.t=t;
  3553.                po->theSuprSprayDraw.anioff=anioff;
  3554.                TimeValue aniend=GetAnimEnd();
  3555.                int anifr;
  3556.                anifr=aniend+GetTicksPerFrame();
  3557.                po->theSuprSprayDraw.anifr=anifr;
  3558.                po->GetTimes(po->times,t,anifr,anioff);
  3559.                po->GetallBB(po->custnode,subtree,t);
  3560.               break;
  3561.               }
  3562.          }
  3563.          break;  
  3564.       default:
  3565.          return FALSE;
  3566.       }
  3567.    return TRUE;
  3568.    }
  3569. class SSParticleDlgProc : public ParamMapUserDlgProc {
  3570.    public:
  3571.       SuprSprayParticle *po;
  3572.  
  3573.       SSParticleDlgProc(SuprSprayParticle *p) {po=p;}
  3574.       INT_PTR DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
  3575.       void DeleteThis() {delete this;}
  3576.    };
  3577.  
  3578. INT_PTR SSParticleDlgProc::DlgProc(
  3579.       TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
  3580. {  switch (msg) {
  3581.       case WM_INITDIALOG: {
  3582.          break;
  3583.          }
  3584.       case WM_COMMAND:
  3585.          switch (LOWORD(wParam))
  3586.          { case IDC_SP_VIEWDISPMESH:
  3587.               {po->valid=FALSE;
  3588.                int subtree,custmtl;
  3589.                po->pblock->GetValue(PB_CUSTOMMTL,0,custmtl,FOREVER);
  3590.                po->pblock->GetValue(PB_USESUBTREE,0,subtree,FOREVER);
  3591.                int anioff;
  3592.                po->pblock->GetValue(PB_ANIMATIONOFFSET,0,anioff,FOREVER);
  3593.                po->theSuprSprayDraw.t=t;
  3594.                po->theSuprSprayDraw.anioff=anioff;
  3595.                TimeValue aniend=GetAnimEnd();
  3596.                int anifr;
  3597.                anifr=aniend+GetTicksPerFrame();
  3598.                po->theSuprSprayDraw.anifr=anifr;
  3599.                po->GetTimes(po->times,t,anifr,anioff);
  3600.                 po->GetMesh(t,subtree,custmtl);
  3601.                break;
  3602.               }
  3603.            case IDC_SP_VIEWDISPBOX:        
  3604.               { po->valid=FALSE;
  3605.                int subtree;
  3606.                po->pblock->GetValue(PB_USESUBTREE,0,subtree,FOREVER);
  3607.                int anioff;
  3608.                po->pblock->GetValue(PB_ANIMATIONOFFSET,0,anioff,FOREVER);
  3609.                po->theSuprSprayDraw.t=t;
  3610.                po->theSuprSprayDraw.anioff=anioff;
  3611.                TimeValue aniend=GetAnimEnd();
  3612.                int anifr;
  3613.                anifr=aniend+GetTicksPerFrame();
  3614.                po->theSuprSprayDraw.anifr=anifr;
  3615.                po->GetTimes(po->times,t,anifr,anioff);
  3616.                po->GetallBB(po->custnode,subtree,t);
  3617.               break;
  3618.               }
  3619.          }
  3620.          break;  
  3621.       default:
  3622.          return FALSE;
  3623.       }
  3624.    return TRUE;
  3625.    }
  3626. void AddMtl(CommonParticle *po,TimeValue t,int custmtl)
  3627. { if (po->cnode)
  3628.    { int subtree,frag,submtl=0;
  3629.     po->pblock->GetValue(PB_USESUBTREE,0,subtree,FOREVER);
  3630.     po->pblock->GetValue(PB_PARTICLECLASS,0,frag,FOREVER);
  3631.    if ((po->custnode)&&(frag==INSTGEOM)&& custmtl)
  3632.       po->AssignMtl(po->cnode,po->custnode,subtree,t);
  3633.    po->valid=FALSE;
  3634.    po->NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
  3635.    }
  3636.  }
  3637.  
  3638.  
  3639. class SSParticleDisableDlgProc : public ParamMapUserDlgProc {
  3640.    public:
  3641.       SuprSprayParticle *po;
  3642.       ICustButton *iBut;
  3643.  
  3644.       SSParticleDisableDlgProc(SuprSprayParticle *p) {po=p;}
  3645.       INT_PTR DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
  3646.       void Update(TimeValue t);
  3647.       void DeleteThis() {delete this;}
  3648.    };
  3649. void SSParticleDisableDlgProc::Update(TimeValue t)
  3650. { if (!po->editOb) return;
  3651.   SetMapVals(po->pblock,po->hptype,t);
  3652.   float width;
  3653.   po->pblock->GetValue(PB_EMITRWID,0,width,FOREVER);
  3654.   if (width<0.01f) iBut->Disable();
  3655.   po->ShowName();
  3656.   int chunky;
  3657.   po->pblock->GetValue(PB_PARTICLECLASS,0,chunky,FOREVER);
  3658.   if (chunky==METABALLS) MetaIn(po,po->hptype,t);
  3659.   else if (chunky==ISSTD) StdOn(po,po->hptype,t);
  3660.   else InstIn(po,po->hptype,t);
  3661. }
  3662.  
  3663. INT_PTR SSParticleDisableDlgProc::DlgProc(
  3664.       TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
  3665. {  switch (msg) {
  3666.       case WM_INITDIALOG: {
  3667.          iBut = GetICustButton(GetDlgItem(hWnd,IDC_AP_OBJECTPICK));
  3668.          iBut->SetType(CBT_CHECK);
  3669.          iBut->SetHighlightColor(GREEN_WASH);
  3670.          Update(t);
  3671.          break;
  3672.          }
  3673.       case WM_DESTROY:
  3674.          // Release all our Custom Controls
  3675.          ReleaseICustButton(iBut);
  3676.          return FALSE;
  3677.       case WM_COMMAND:
  3678.          switch (LOWORD(wParam))
  3679.          { case IDC_AP_OBJECTPICK:
  3680.                { po->flags=0;
  3681.                if (po->ip->GetCommandMode()->ID() == CID_STDPICK)
  3682.                { if (po->creating)
  3683.                   {  theCreateSSBlizMode.JumpStart(po->ip,po);
  3684.                      po->ip->SetCommandMode(&theCreateSSBlizMode);
  3685.                   } else {po->ip->SetStdCommandMode(CID_OBJMOVE);}
  3686.                } else
  3687.                   { po->pickCB.po = po;  
  3688.                     po->pickCB.dodist=0;
  3689.                     po->ip->SetPickMode(&po->pickCB);
  3690.                   }
  3691.                break;
  3692.             }
  3693.          case IDC_AP_UPDATEMTL:
  3694.             { int custmtl;
  3695.               po->pblock->GetValue(PB_CUSTOMMTL,0,custmtl,FOREVER);
  3696.               AddMtl(po,t,custmtl);
  3697.               if ((custmtl) &&(po->cnode))
  3698.               { EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPCUSTOMEMIT),FALSE);
  3699.                 po->origmtl=po->cnode->GetMtl();
  3700.               }
  3701.               break;
  3702.             }
  3703.             case IDC_SP_TYPESTD:
  3704.             { StdOn(po,hWnd,t);
  3705.               po->valid=FALSE;
  3706.               if (po->ip->GetCommandMode()->ID() == CID_STDPICK)
  3707.               { if (po->creating)
  3708.                {  theCreateSSBlizMode.JumpStart(po->ip,po);
  3709.                   po->ip->SetCommandMode(&theCreateSSBlizMode);
  3710.                } else {po->ip->SetStdCommandMode(CID_OBJMOVE);}
  3711.               }
  3712.              break;
  3713.             }
  3714.            case IDC_AP_NOANIOFF:
  3715.            case IDC_AP_ANIOFFBIRTH:
  3716.                SpinnerOff(hWnd,IDC_AP_ANIRNDFRSPIN,IDC_AP_ANIRNDFR);
  3717.                EnableWindow(GetDlgItem(hWnd,IDC_AP_ANIRNDFR_TXT),FALSE);
  3718.               break;
  3719.            case IDC_AP_ANIOFFRND:
  3720.               SpinnerOn(hWnd,IDC_AP_ANIRNDFRSPIN,IDC_AP_ANIRNDFR);
  3721.               EnableWindow(GetDlgItem(hWnd,IDC_AP_ANIRNDFR_TXT),TRUE);
  3722.               break;
  3723.            case IDC_SP_TYPEFAC:
  3724.            case IDC_SP_TYPEPIX:
  3725.             { SetMapVals(po->pblock,hWnd,t);
  3726. //            int facing;
  3727. //            po->pblock->GetValue(PB_VIEWPORTSHOWS,t,facing,FOREVER);
  3728. //            if (facing==2) po->pblock->SetValue(PB_VIEWPORTSHOWS,t,1);
  3729. //            EnableWindow(GetDlgItem(po->hparam,IDC_SP_VIEWDISPMESH),FALSE);
  3730.               po->pmapParam->Invalidate();
  3731.               EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPDIST),TRUE);
  3732.               EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPTIME),TRUE);
  3733.              break;
  3734.             }
  3735.            case IDC_SP_TYPETRI:
  3736.            case IDC_SP_TYPECUB:
  3737.            case IDC_SP_TYPESPC:
  3738.            case IDC_SP_TYPE6PNT:
  3739.            case IDC_SP_TYPESPHERE:
  3740.             { SetMapVals(po->pblock,hWnd,t);
  3741.               EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPDIST),TRUE);
  3742.               EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPTIME),TRUE);
  3743.               EnableWindow(GetDlgItem(po->hparam,IDC_SP_VIEWDISPMESH),TRUE);
  3744.              break;
  3745.             }
  3746.            case IDC_SP_TYPETET:
  3747.             { SpinnerOff(hWnd,IDC_SP_MAPTIMEVALSPIN,IDC_SP_MAPTIMEVAL);
  3748.               SpinnerOff(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3749.               EnableWindow(GetDlgItem(po->hparam,IDC_SP_VIEWDISPMESH),TRUE);
  3750.               EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPDIST),FALSE);
  3751.               EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPTIME),FALSE);
  3752.              break;
  3753.             }
  3754.            case IDC_SP_MAPTIME:
  3755.             { SpinnerOn(hWnd,IDC_SP_MAPTIMEVALSPIN,IDC_SP_MAPTIMEVAL);
  3756.               SpinnerOff(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3757.              break;
  3758.             }
  3759.            case IDC_SP_MAPDIST:
  3760.             { SpinnerOff(hWnd,IDC_SP_MAPTIMEVALSPIN,IDC_SP_MAPTIMEVAL);
  3761.               SpinnerOn(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3762.              break;
  3763.             }
  3764.            case IDC_SP_TYPEMET:
  3765.               { MetaIn(po,hWnd,t);
  3766.                 po->valid=FALSE;
  3767.               if (po->ip->GetCommandMode()->ID() == CID_STDPICK)
  3768.               { if (po->creating)
  3769.                {  theCreateSSBlizMode.JumpStart(po->ip,po);
  3770.                   po->ip->SetCommandMode(&theCreateSSBlizMode);
  3771.                } else {po->ip->SetStdCommandMode(CID_OBJMOVE);}
  3772.               }
  3773.               break;
  3774.               }
  3775.            case IDC_SP_MAPCUSTOMEMIT:
  3776.            case IDC_SP_MAPCUSTOMINST:
  3777.             { MappingStuff(po->pblock,hWnd,t,FALSE);
  3778.               int dir;
  3779.               po->pblock->GetValue(PB_SPINAXISTYPE,0,dir,FOREVER);
  3780.               if (dir==1)
  3781.               { int subtree,frag,custmtl=0;
  3782.                 po->pblock->GetValue(PB_CUSTOMMTL,0,custmtl,FOREVER);
  3783.                 po->pblock->GetValue(PB_USESUBTREE,0,subtree,FOREVER);
  3784.                 po->pblock->GetValue(PB_PARTICLECLASS,0,frag,FOREVER);
  3785.                 CheckStretchBox(po->hrot,po);
  3786.               }
  3787.               break;}
  3788.            case IDC_SP_TYPEINSTANCE:
  3789.               { int custmtl,vshow,anioff;
  3790.                po->pblock->GetValue(PB_VIEWPORTSHOWS,0,vshow,FOREVER);
  3791.                 po->pblock->SetValue(PB_CUSTOMMTL,0,1);
  3792.                InstIn(po,hWnd,t);
  3793.                if (vshow>1)
  3794.                {int subtree;
  3795.                 po->pblock->GetValue(PB_USESUBTREE,0,subtree,FOREVER);
  3796.                 po->pblock->GetValue(PB_ANIMATIONOFFSET,0,anioff,FOREVER);
  3797.                 po->theSuprSprayDraw.t=t;
  3798.                 po->theSuprSprayDraw.anioff=anioff;
  3799.                 TimeValue aniend=GetAnimEnd();
  3800.                 int anifr;
  3801.                 anifr=aniend+GetTicksPerFrame();
  3802.                 po->theSuprSprayDraw.anifr=anifr;
  3803.                 po->GetTimes(po->times,t,anifr,anioff);
  3804.                 if (vshow==2)
  3805.                 { po->pblock->GetValue(PB_CUSTOMMTL,0,custmtl,FOREVER);
  3806.                    po->GetMesh(t,subtree,custmtl);
  3807.                 }
  3808.                else po->GetallBB(po->custnode,subtree,t);
  3809.                }
  3810.                 po->valid=FALSE;
  3811.               break;
  3812.               }
  3813.            case IDC_SP_AUTOCOARSE:
  3814.             { int chunky;
  3815.               po->pblock->GetValue(PB_PARTICLECLASS,0,chunky,FOREVER);
  3816.               if (chunky==METABALLS)
  3817.                 CourseCheck(po,hWnd,t);
  3818.               break;
  3819.             }
  3820.          }
  3821.          break;  
  3822.       default:
  3823.          return FALSE;
  3824.       }
  3825.    return TRUE;
  3826.    }
  3827. class BLParticleDisableDlgProc : public ParamMapUserDlgProc {
  3828.    public:
  3829.       BlizzardParticle *po;
  3830.       ICustButton *iBut;
  3831.  
  3832.       BLParticleDisableDlgProc(BlizzardParticle *p) {po=p;}
  3833.       INT_PTR DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
  3834.       void Update(TimeValue t);
  3835.       void DeleteThis() {delete this;}
  3836.    };
  3837. void BLParticleDisableDlgProc::Update(TimeValue t)
  3838. {  if (!po->editOb) return;
  3839.    float width;
  3840.    po->pblock->GetValue(PB_EMITRWID,0,width,FOREVER);
  3841.    int chunky;
  3842.    po->pblock->GetValue(PB_PARTICLECLASS,0,chunky,FOREVER);
  3843.    if (chunky==METABALLS) MetaIn(po,po->hptype,t);
  3844.    else if (chunky==ISSTD) StdOn(po,po->hptype,t);
  3845.    else InstIn(po,po->hptype,t);
  3846.    if (width<0.01f)
  3847.    { iBut->Disable();
  3848.    }
  3849.    po->ShowName();
  3850. }
  3851.  
  3852. INT_PTR BLParticleDisableDlgProc::DlgProc(
  3853.       TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
  3854. {  switch (msg) {
  3855.       case WM_INITDIALOG: {
  3856.          iBut = GetICustButton(GetDlgItem(hWnd,IDC_AP_OBJECTPICK));
  3857.          iBut->SetType(CBT_CHECK);
  3858.          iBut->SetHighlightColor(GREEN_WASH);
  3859.          Update(t);
  3860.          break;
  3861.          }
  3862.       case WM_DESTROY:
  3863.          // Release all our Custom Controls
  3864.          ReleaseICustButton(iBut);
  3865.          return FALSE;
  3866.       case WM_COMMAND:
  3867.          switch (LOWORD(wParam))
  3868.          {  case IDC_AP_OBJECTPICK:
  3869.                { po->flags=0;
  3870.                if (po->ip->GetCommandMode()->ID() == CID_STDPICK)
  3871.                { if (po->creating)
  3872.                   {  theCreateSSBlizMode.JumpStart(po->ip,po);
  3873.                      po->ip->SetCommandMode(&theCreateSSBlizMode);
  3874.                   } else {po->ip->SetStdCommandMode(CID_OBJMOVE);}
  3875.                } else
  3876.                   { po->pickCB.po = po;  
  3877.                      po->pickCB.dodist = 0;
  3878.                     po->ip->SetPickMode(&po->pickCB);
  3879.                   }
  3880.                break;
  3881.             }
  3882.          case IDC_AP_UPDATEMTL:
  3883.             { int custmtl;
  3884.               po->pblock->GetValue(PB_CUSTOMMTL2,0,custmtl,FOREVER);
  3885.               AddMtl(po,t,custmtl);
  3886.               if ((po->cnode)&&(custmtl))
  3887.               { EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPCUSTOMEMIT),FALSE);
  3888.                po->origmtl=po->cnode->GetMtl();
  3889.               }
  3890.               break;
  3891.             }
  3892.            case IDC_AP_NOANIOFF:
  3893.            case IDC_AP_ANIOFFBIRTH:
  3894.                SpinnerOff(hWnd,IDC_AP_ANIRNDFRSPIN,IDC_AP_ANIRNDFR);
  3895.                EnableWindow(GetDlgItem(hWnd,IDC_AP_ANIRNDFR_TXT),FALSE);
  3896.               break;
  3897.            case IDC_AP_ANIOFFRND:
  3898.               SpinnerOn(hWnd,IDC_AP_ANIRNDFRSPIN,IDC_AP_ANIRNDFR);
  3899.               EnableWindow(GetDlgItem(hWnd,IDC_AP_ANIRNDFR_TXT),TRUE);
  3900.               break;
  3901.            case IDC_SP_TYPEFAC:
  3902.            case IDC_SP_TYPEPIX:
  3903.             { SetMapVals(po->pblock,hWnd,t);
  3904. //            int facing;
  3905. //            po->pblock->GetValue(PB_VIEWPORTSHOWS,t,facing,FOREVER);
  3906. //            if (facing==2) po->pblock->SetValue(PB_VIEWPORTSHOWS,t,1);
  3907. //            EnableWindow(GetDlgItem(po->hparam,IDC_SP_VIEWDISPMESH),FALSE);
  3908.               EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPDIST),TRUE);
  3909.               EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPTIME),TRUE);
  3910.               po->pmapParam->Invalidate();
  3911.              break;
  3912.             }
  3913.            case IDC_SP_TYPETRI:
  3914.            case IDC_SP_TYPECUB:
  3915.            case IDC_SP_TYPESPC:
  3916.            case IDC_SP_TYPE6PNT:
  3917.            case IDC_SP_TYPESPHERE:
  3918.             { SetMapVals(po->pblock,hWnd,t);
  3919.               EnableWindow(GetDlgItem(po->hparam,IDC_SP_VIEWDISPMESH),TRUE);
  3920.               EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPDIST),TRUE);
  3921.               EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPTIME),TRUE);
  3922.              break;
  3923.             }
  3924.            case IDC_SP_TYPETET:
  3925.             { SpinnerOff(hWnd,IDC_SP_MAPTIMEVALSPIN,IDC_SP_MAPTIMEVAL);
  3926.               SpinnerOff(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3927.               EnableWindow(GetDlgItem(po->hparam,IDC_SP_VIEWDISPMESH),TRUE);
  3928.               EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPDIST),FALSE);
  3929.               EnableWindow(GetDlgItem(hWnd,IDC_SP_MAPTIME),FALSE);
  3930.              break;
  3931.             }
  3932.            case IDC_SP_MAPTIME:
  3933.             { SpinnerOn(hWnd,IDC_SP_MAPTIMEVALSPIN,IDC_SP_MAPTIMEVAL);
  3934.               SpinnerOff(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3935.              break;
  3936.             }
  3937.            case IDC_SP_MAPDIST:
  3938.             { SpinnerOff(hWnd,IDC_SP_MAPTIMEVALSPIN,IDC_SP_MAPTIMEVAL);
  3939.               SpinnerOn(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3940.              break;
  3941.             }
  3942.            case IDC_SP_MAPPLANAR:
  3943.             { SpinnerOff(hWnd,IDC_SP_MAPTIMEVALSPIN,IDC_SP_MAPTIMEVAL);
  3944.               SpinnerOff(hWnd,IDC_SP_MAPDISTVALSPIN,IDC_SP_MAPDISTVAL);
  3945.              break;
  3946.             }
  3947.             case IDC_SP_TYPESTD:
  3948.             { StdOn(po,hWnd,t);
  3949.               po->valid=FALSE;
  3950.               if (po->ip->GetCommandMode()->ID() == CID_STDPICK)
  3951.               { if (po->creating)
  3952.                {  theCreateSSBlizMode.JumpStart(po->ip,po);
  3953.                   po->ip->SetCommandMode(&theCreateSSBlizMode);
  3954.                } else {po->ip->SetStdCommandMode(CID_OBJMOVE);}
  3955.               }
  3956.              break;
  3957.             }
  3958.            case IDC_SP_TYPEMET:
  3959.               { MetaIn(po,hWnd,t);
  3960.                 po->valid=FALSE;
  3961.               if (po->ip->GetCommandMode()->ID() == CID_STDPICK)
  3962.               { if (po->creating)
  3963.                {  theCreateSSBlizMode.JumpStart(po->ip,po);
  3964.                   po->ip->SetCommandMode(&theCreateSSBlizMode);
  3965.                } else {po->ip->SetStdCommandMode(CID_OBJMOVE);}
  3966.               }
  3967.               break;
  3968.               }
  3969.            case IDC_SP_MAPCUSTOMEMIT:
  3970.            case IDC_SP_MAPCUSTOMINST:
  3971.               MappingStuff(po->pblock,hWnd,t,TRUE);
  3972.               break;
  3973.            case IDC_SP_TYPEINSTANCE:
  3974.               { int custmtl,vshow;
  3975.                  po->pblock->SetValue(PB_CUSTOMMTL2,0,1);
  3976.                 InstIn(po,hWnd,t);
  3977.                po->pblock->GetValue(PB_VIEWPORTSHOWS,0,vshow,FOREVER);
  3978.                if (vshow>1)
  3979.                {int subtree,anioff;
  3980.                 po->pblock->GetValue(PB_USESUBTREE,0,subtree,FOREVER);
  3981.                 po->pblock->GetValue(PB_ANIMATIONOFFSET,0,anioff,FOREVER);
  3982.                 po->theSuprSprayDraw.t=t;
  3983.                 po->theSuprSprayDraw.anioff=anioff;
  3984.                 TimeValue aniend=GetAnimEnd();
  3985.                 int anifr;
  3986.                 anifr=aniend+GetTicksPerFrame();
  3987.                 po->theSuprSprayDraw.anifr=anifr;
  3988.                 po->GetTimes(po->times,t,anifr,anioff);
  3989.                 if (vshow==2)
  3990.                 { po->pblock->GetValue(PB_CUSTOMMTL2,0,custmtl,FOREVER);
  3991.                    po->GetMesh(t,subtree,custmtl);
  3992.                 }
  3993.                else po->GetallBB(po->custnode,subtree,t);
  3994.                }
  3995.                 po->valid=FALSE;
  3996.               break;
  3997.               }
  3998.            case IDC_SP_AUTOCOARSE:
  3999.             { int chunky;
  4000.               po->pblock->GetValue(PB_PARTICLECLASS,0,chunky,FOREVER);
  4001.               if (chunky==METABALLS)
  4002.                 CourseCheck(po,hWnd,t);
  4003.               break;
  4004.             }
  4005.          }
  4006.          break;  
  4007.       default:
  4008.          return FALSE;
  4009.       }
  4010.    return TRUE;
  4011.    }
  4012.  
  4013. void CommonParticle::GetFilename(TCHAR *filename)
  4014. {   _tcscpy(filename,ip->GetDir(APP_PLUGCFG_DIR));
  4015.   int len= static_cast<int>(_tcslen(filename)); // SR DCAST64: Downcast to 2G limit.
  4016.   if (len)
  4017.   {  if (filename[len-1]!=_T('\\'))
  4018.         _tcscat(filename,_T("\\"));
  4019.   }
  4020.   if (ClassID()==BLIZZARD_CLASS_ID)
  4021.     _tcscat(filename,GetString(IDS_AP_BLIZZARDCST));
  4022.   else  _tcscat(filename,GetString(IDS_AP_SSPRAYCST));
  4023. }
  4024.  
  4025. void CommonParticle::SetupTargetList()    
  4026.    {TCHAR filename[MAX_PATH];
  4027.      FILE *f;
  4028.     int vers,i,Namelen,osize;
  4029.    custsettings=i=0; // LAM - 6/9/02 - initialize i so if fileok == false, will display error in onerr.
  4030.     GetFilename(filename);
  4031.    BOOL fileok=TRUE;
  4032.    if ((f = _tfopen(filename, _T("rb"))) == NULL) return;
  4033.    if((ReadInt(&custsettings,f))&&(ReadInt(&vers,f))&&(ReadInt(&osize,f))&&(ReadInt(&Namelen,f)))
  4034.    {if ( ((Namelen!=NLEN)&& (fileok=GenNewNameLen(size,custsettings,f,filename,CURRENT_VERSION)) == TRUE)||
  4035.       ((vers!=CURRENT_VERSION)&&(fileok=GenNewSaveFile(osize,size,custsettings,f,filename,CURRENT_VERSION)) == TRUE))
  4036.       { fileok=((ReadInt(&custsettings,f))&&(ReadInt(&vers,f))&&(ReadInt(&osize,f))&&(ReadInt(&Namelen,f)));
  4037.       }
  4038.    if (fileok&&(vers==CURRENT_VERSION))
  4039.    { NameLst=new AName[custsettings];
  4040.      for (i=0;i<custsettings;i++)
  4041.      if (fread(NameLst[i],NLEN,1,f)==1)
  4042.        fseek(f,size,SEEK_CUR);
  4043.      else goto onerr;
  4044.    }
  4045.    }
  4046.    onerr:if (i<custsettings)
  4047.    { custsettings=0;
  4048.    MessageBox (NULL,GetString(IDS_RB_BADFILE),
  4049.             "", MB_ICONINFORMATION);
  4050.    }
  4051.    if (fileok) fclose(f);
  4052.    UpdatePresetListBox(GetDlgItem(hParams2, IDC_SP_SETLIST), custsettings, NameLst);
  4053.    }
  4054. int CommonParticle::RemSettings(int overwrite,TCHAR *newname)
  4055. { TCHAR filename[MAX_PATH];
  4056.   FILE *f;
  4057.   long startpt;
  4058.   int vers,newsets,baselen=size+NLEN;
  4059.   GetFilename(filename);
  4060.   vers=CURRENT_VERSION;
  4061.   newsets=custsettings-1;
  4062.   if ((f = _tfopen(filename,_T("r+b"))) == NULL)
  4063.   { MessageBox(NULL,GetString(IDS_AP_WRITEPRO),"", MB_ICONINFORMATION);
  4064.    return 0;
  4065.   }
  4066.   if (custsettings==1)
  4067.   {fclose(f);remove(filename);custsettings=0;
  4068.     delete[] NameLst;NameLst=NULL;
  4069.     SendMessage(GetDlgItem(hParams2,IDC_SP_SETLIST),LB_RESETCONTENT,0,0);
  4070.    return (1);}
  4071.  if (!WriteInt(&newsets,f)) {fclose(f);return 0;}
  4072.   startpt=overwrite*(baselen)+HLEN;
  4073.   fseek(f,startpt,SEEK_SET);
  4074.   int i;
  4075.   BYTE *buf;
  4076.   buf=new BYTE[baselen];
  4077.   assert(buf);
  4078.   long cpos=startpt;
  4079.   for (i=overwrite+1;i<custsettings;i++)
  4080.   {   fseek(f,cpos+baselen,SEEK_SET);
  4081.    if (fread(buf,baselen,1,f)!=1) {delete[] buf;fclose(f);return 0;}
  4082.    fseek(f,cpos,SEEK_SET);
  4083.    if (fwrite(buf,baselen,1,f)!=1) {delete[] buf;fclose(f);return 0;}
  4084.    cpos+=baselen;
  4085.   }
  4086.   delete[] buf;
  4087.   _chsize(_fileno(f),ftell(f));
  4088.   fclose(f);                          
  4089.   AName *Tmp=new AName[custsettings-1];
  4090.   int newi=0;
  4091.   for (i=0;i<custsettings;i++)
  4092.   { if (i!=overwrite)
  4093.       _tcscpy(Tmp[newi++],NameLst[i]);}
  4094.   delete []NameLst;NameLst=Tmp;
  4095.   custsettings--;
  4096.   UpdatePresetListBox(GetDlgItem(hParams2, IDC_SP_SETLIST), custsettings, NameLst);
  4097.   return(1);
  4098. }
  4099. int CommonParticle::SaveSettings(int overwrite,TCHAR *newname)
  4100. { TCHAR filename[MAX_PATH];
  4101.   FILE *f;
  4102.   int vers,newsets,Namelen=NLEN;
  4103.  
  4104.   if ((overwrite>-1)&&(MessageBox (NULL,GetString(IDS_AP_SETEXISTS),GetString(IDS_AP_WARNING), MB_ICONQUESTION | MB_YESNO ) == IDNO))
  4105.     return 0;
  4106.   GetFilename(filename);
  4107.   vers=CURRENT_VERSION;
  4108.   newsets=custsettings+1;
  4109.   if ((f = _tfopen(filename,(custsettings==0?_T("wb"):_T("r+b")))) == NULL)
  4110.   { MessageBox(NULL,GetString(IDS_AP_WRITEPRO),"", MB_ICONINFORMATION);
  4111.    return 0;
  4112.   }
  4113.  // longest one
  4114.   ParamBlockDescID *descVer=((ClassID()==BLIZZARD_CLASS_ID)?BdescVer6:spdescVer6);
  4115.   int plength=((ClassID()==BLIZZARD_CLASS_ID)?PBLOCK_LENGTH_BLIZZARD:PBLOCK_LENGTH_SUPRSPRAY);
  4116.   if (custsettings==0)
  4117.   { if (!(WriteInt(&newsets,f)&&WriteInt(&vers,f)&&WriteInt(&size,f)&&WriteInt(&Namelen,f))) goto errend;
  4118.   }
  4119.   else
  4120.   { if (overwrite>=0)
  4121.     { overwrite=overwrite*(size+NLEN)+HLEN;
  4122.       fseek(f,overwrite,SEEK_SET); }
  4123.     else
  4124.    { if (!WriteInt(&newsets,f)) goto errend;
  4125.      fseek(f,0,SEEK_END);
  4126.    }
  4127.   }    
  4128.   int ival,i;
  4129.   float fval;
  4130.   if (fwrite(newname,1,NLEN,f)!=NLEN) goto errend;
  4131.   for (i=0;i<plength;i++)
  4132.   {   if (descVer[i].type==TYPE_INT)
  4133.     { pblock->GetValue(i,0,ival,FOREVER);
  4134.       if (fwrite(&ival,isize,1,f)!=1) goto errend;
  4135.    }
  4136.     else
  4137.     { pblock->GetValue(i,0,fval,FOREVER);
  4138.       if (fwrite(&fval,fsize,1,f)!=1) goto errend;
  4139.    }
  4140.   }
  4141.   fclose(f);
  4142.   if (overwrite<0)
  4143.   { AName *Tmp=new AName[custsettings+1];
  4144.     memcpy(Tmp,NameLst,sizeof(AName)*custsettings);
  4145.    delete []NameLst;NameLst=Tmp;
  4146.     _tcscpy(NameLst[custsettings],newname);
  4147.    custsettings++;
  4148.    UpdatePresetListBox(GetDlgItem(hParams2, IDC_SP_SETLIST), custsettings, NameLst);
  4149.   }  
  4150.   return(1);
  4151. errend: fclose(f);return(0);
  4152. }
  4153. int CommonParticle::GetSettings(int setnum,TCHAR *newname)
  4154. { TCHAR filename[MAX_PATH];
  4155.   FILE *f;
  4156.   GetFilename(filename);
  4157.   if ((f = _tfopen(filename,_T("rb"))) == NULL) return 0;
  4158.   { setnum=setnum*(size+NLEN)+HLEN;
  4159.     fseek(f,setnum,SEEK_SET);
  4160.   }    
  4161.   int ival,i;
  4162.   float fval;
  4163.   // longest one
  4164.   ParamBlockDescID *descVer=((ClassID()==BLIZZARD_CLASS_ID)?BdescVer6:spdescVer6);
  4165.  int plength=((ClassID()==BLIZZARD_CLASS_ID)?PBLOCK_LENGTH_BLIZZARD:PBLOCK_LENGTH_SUPRSPRAY);
  4166.   if (fread(newname,1,NLEN,f)!=NLEN) goto errend;
  4167.   for (i=0;i<plength;i++)
  4168.   {   if (descVer[i].type==TYPE_INT)
  4169.     { if (fread(&ival,isize,1,f)!=1) goto errend;
  4170.      pblock->SetValue(i,0,ival);
  4171.    }
  4172.     else
  4173.     { if (fread(&fval,fsize,1,f)!=1) goto errend;
  4174. //   if (i!=PB_EMITRWID)
  4175.         pblock->SetValue(i,0,fval);
  4176.    }
  4177.   }
  4178.   fclose(f);
  4179.   InvalidateUI();                  
  4180.   return(1);
  4181.   errend: fclose(f);return(0);
  4182. }
  4183. static INT_PTR CALLBACK CustomSettingParamDlgProc(
  4184.       HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  4185. { TCHAR newname[NLEN];
  4186.   int i = 0, save = 0;
  4187.   CommonParticle *po = DLGetWindowLongPtr<CommonParticle*>(hWnd);
  4188.   if (!po && message!=WM_INITDIALOG) return FALSE;
  4189.  
  4190.   switch (message) {
  4191.       case WM_INITDIALOG: {
  4192.          po = (SuprSprayParticle*)lParam;
  4193.          DLSetWindowLongPtr(hWnd, lParam);
  4194.          po->custCtrlEdit = GetICustEdit(GetDlgItem(hWnd,IDC_SP_SETEDIT));
  4195.          po->custCtrlEdit->SetText(_T(""));
  4196.          po->hParams2 = hWnd;
  4197.          po->SetupTargetList();
  4198.          break;
  4199.          }
  4200.       case WM_COMMAND:
  4201.          { switch(LOWORD(wParam)) {
  4202.             case IDC_SP_SETLIST:  
  4203.                if (HIWORD(wParam)==LBN_DBLCLK)
  4204.                  goto doload;
  4205.                break;
  4206.             case IDC_SP_DELETE:  
  4207.                i = SendMessage(GetDlgItem(po->hParams2,IDC_SP_SETLIST),
  4208.                      LB_GETCURSEL,0,0);
  4209.                   if ((i>-1)&&(po->custsettings>0))
  4210.                   { po->custCtrlEdit->GetText(newname,NLEN);
  4211.                    if (_tcscmp(newname,po->NameLst[i])==0)
  4212.                      po->custCtrlEdit->SetText(_T(""));
  4213.                     po->RemSettings(i,po->NameLst[i]);
  4214.                   }
  4215.                break;
  4216.             case IDC_SP_SAVE:
  4217.                save=1;
  4218.             case IDC_SP_LOAD:
  4219.                doload:
  4220.                if (!save)
  4221.                { i = SendMessage(GetDlgItem(po->hParams2,IDC_SP_SETLIST),
  4222.                      LB_GETCURSEL,0,0);
  4223.                   if ((i>-1)&&(po->custsettings>0))
  4224.                     po->custCtrlEdit->SetText(po->NameLst[i]);
  4225.                }
  4226.                 po->custCtrlEdit->GetText(newname,NLEN);
  4227.                if (save)
  4228.                {int tstblk=0,tstlen=static_cast<int>(_tcslen(newname)); // SR DCAST64: Downcast to 2G limit.
  4229.                  while ((tstblk<tstlen)&&(newname[tstblk]==' ')) tstblk++;
  4230.                  if (tstblk>=tstlen)
  4231.                   MessageBox (NULL,GetString(IDS_RB_NONAME),
  4232.             "", MB_ICONINFORMATION);
  4233.                  else
  4234.                  { i=0;
  4235.                    while ((i<po->custsettings)&&(_tcscmp(newname,po->NameLst[i])))
  4236.                     i++;
  4237.                   if (i>=po->custsettings) i=-1;
  4238.                    po->SaveSettings(i,newname);
  4239.                  }
  4240.                }
  4241.                else if ((i>-1)&&(i<po->custsettings))
  4242.                { po->GetSettings(i,newname);
  4243.                  int stype;
  4244.                  po->pblock->GetValue(PB_SPAWNTYPE,0,stype,FOREVER);
  4245.                  int chunky;
  4246.                    po->pblock->GetValue(PB_PARTICLECLASS,0,chunky,FOREVER);
  4247.                  if (chunky==METABALLS) MetaIn(po,po->hptype,po->ip->GetTime());
  4248.                   else
  4249.                  {// AllSpawnBad(po->spawn,stype,TRUE);
  4250.                   int ison; po->pblock->GetValue((po->ClassID()==BLIZZARD_CLASS_ID?PB_BLIPCOLLIDE_ON:PB_IPCOLLIDE_ON),0,ison,FOREVER);
  4251.                   if (ison) stype=0;
  4252.                   SpawnStuff(po->spawn,stype);
  4253.                   if (chunky==ISSTD) StdOn(po,po->hptype,po->ip->GetTime());
  4254.                    else InstIn(po,po->hptype,po->ip->GetTime());
  4255.                  }
  4256.              if (chunky==INSTGEOM)
  4257.              { CheckSpawnButtons(po->pblock,po->spawn,po->pickCB.repi);
  4258.                int onscreen;
  4259.                po->pblock->GetValue(PB_VIEWPORTSHOWS,0,onscreen,FOREVER);
  4260.                if (onscreen>1)
  4261.                {int subtree,anioff;
  4262.                 po->pblock->GetValue(PB_USESUBTREE,0,subtree,FOREVER);
  4263.                 po->pblock->GetValue(PB_ANIMATIONOFFSET,0,anioff,FOREVER);
  4264.                TimeValue t=po->ip->GetTime();
  4265.                 po->theSuprSprayDraw.t=t;
  4266.                 po->theSuprSprayDraw.anioff=anioff;
  4267.                 TimeValue aniend=GetAnimEnd();
  4268.                 int anifr,custmtl;
  4269.                 anifr=aniend+GetTicksPerFrame();
  4270.                 po->theSuprSprayDraw.anifr=anifr;
  4271.                 po->GetTimes(po->times,t,anifr,anioff);
  4272.                 po->pblock->GetValue((po->ClassID()==BLIZZARD_CLASS_ID?PB_CUSTOMMTL2:PB_CUSTOMMTL),0,custmtl,FOREVER);
  4273.                 if (onscreen==2)
  4274.                    po->GetMesh(po->ip->GetTime(),subtree,custmtl);
  4275.                   else po->GetallBB(po->custnode,subtree,po->ip->GetTime());
  4276.                }
  4277.              }
  4278.              else ObjectMutQueOff(po->spawn);
  4279.                  if (stype==EMIT)
  4280.                  {   SpinnerOff(po->spawn,IDC_AP_MAXSPAWNGENSSPIN,IDC_AP_MAXSPAWNGENS);
  4281.                   EnableWindow(GetDlgItem(hWnd,IDC_AP_MAXSPAWNDIEAFTER_TXT),FALSE);
  4282.                  }
  4283.                  po->pmapParam->Invalidate();
  4284.                  po->ip->RedrawViews(po->ip->GetTime());
  4285.                }
  4286.                else MessageBox (NULL,GetString(IDS_RB_BADNAME),
  4287.             "", MB_ICONINFORMATION);
  4288.                break;
  4289.             }
  4290.          break;
  4291.          }
  4292.  
  4293.       case WM_DESTROY:
  4294.          // Release all our Custom Controls
  4295.          ReleaseICustEdit(po->custCtrlEdit);
  4296.          if (po->NameLst) {delete []po->NameLst;po->NameLst=NULL;}
  4297.          return FALSE;
  4298.       case WM_LBUTTONDOWN:
  4299.       case WM_LBUTTONUP:
  4300.       case WM_MOUSEMOVE:
  4301.          po->ip->RollupMouseMessage(hWnd,message,wParam,lParam);
  4302.          return FALSE;
  4303.      
  4304.       default: return FALSE;    
  4305.       }
  4306.    return TRUE;
  4307.    }  
  4308.  
  4309. class ComParticleSpawnDlgProc : public ParamMapUserDlgProc {
  4310.    public:
  4311.       CommonParticle *po;
  4312.       ICustButton *iBut,*iButrep;
  4313.  
  4314.       ComParticleSpawnDlgProc(CommonParticle *p) {po=p;}
  4315.       INT_PTR DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
  4316.       void Update(TimeValue t);
  4317.       void DeleteThis() {delete this;}
  4318.    };
  4319.  
  4320. void ComParticleSpawnDlgProc::Update(TimeValue t)
  4321. { if (!po->editOb) return;
  4322.    po->SetUpList();
  4323.    float width;
  4324.    po->pblock->GetValue(PB_EMITRWID,0,width,FOREVER);
  4325.    if (width<0.01f) iBut->Disable();
  4326.    po->SetUpLifeList();
  4327.    po->pickCB.repi= SendMessage(GetDlgItem(po->spawn,IDC_AP_OBJECTQUEUE),
  4328.                LB_GETCURSEL,0,0);
  4329.    if (width<0.01f) iButrep->Disable();
  4330.    else
  4331.    { if (po->pickCB.repi<0) iButrep->Disable(); else iButrep->Enable();
  4332.    }
  4333.    int chunky,stype;
  4334.    po->pblock->GetValue(PB_PARTICLECLASS,0,chunky,FOREVER);
  4335.    po->pblock->GetValue(PB_SPAWNTYPE,0,stype,FOREVER);
  4336. // AllSpawnBad(po->spawn,stype,chunky!=METABALLS);
  4337.    int ison; po->pblock->GetValue((po->ClassID()==BLIZZARD_CLASS_ID?PB_BLIPCOLLIDE_ON:PB_IPCOLLIDE_ON),t,ison,FOREVER);
  4338.    if (ison) stype=0;
  4339.     SpawnStuff(po->spawn,stype);
  4340.    if (chunky==INSTGEOM)
  4341.           CheckSpawnButtons(po->pblock,po->spawn,po->pickCB.repi);
  4342.    else
  4343.    { ObjectMutQueOff(po->spawn);
  4344.      CheckLifeButtons(stype,po->spawn);
  4345.    }
  4346.    if (stype==EMIT)
  4347.    {  SpinnerOff(po->spawn,IDC_AP_MAXSPAWNGENSSPIN,IDC_AP_MAXSPAWNGENS);
  4348.       EnableWindow(GetDlgItem(po->spawn,IDC_AP_MAXSPAWNDIEAFTER_TXT),FALSE);
  4349.    }
  4350. }
  4351.  
  4352. INT_PTR ComParticleSpawnDlgProc::DlgProc(
  4353.       TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
  4354. { int dtype=2,stype,rep;  
  4355.    switch (msg) {
  4356.       case WM_INITDIALOG:
  4357.       { iBut = GetICustButton(GetDlgItem(hWnd,IDC_AP_OBJECTQUEUEPICK));
  4358.         iBut->SetType(CBT_CHECK);
  4359.         iBut->SetHighlightColor(GREEN_WASH);
  4360.         iButrep = GetICustButton(GetDlgItem(hWnd,IDC_AP_OBJQUEUEREPLACE));
  4361.         iButrep->SetType(CBT_CHECK);
  4362.         iButrep->SetHighlightColor(GREEN_WASH);
  4363.         Update(t);
  4364.         break;
  4365.       }
  4366.       case WM_DESTROY:
  4367.          // Release all our Custom Controls
  4368.          ReleaseICustButton(iBut);
  4369.          ReleaseICustButton(iButrep);
  4370.          return FALSE;
  4371.       case WM_COMMAND:
  4372.          switch (LOWORD(wParam))
  4373.          { case IDC_AP_NOSPAWN:stype=0;goto spawnradio;
  4374.            case IDC_AP_COLLIDEDIE:
  4375.               stype=1;goto spawnradio;
  4376.            case IDC_AP_SPAWNTRAILS:stype=EMIT;goto spawnradio;
  4377.            case IDC_AP_COLLIDESPAWN:
  4378.            case IDC_AP_DEATHSPAWN: stype=2;
  4379.          spawnradio:
  4380.             int chunky;
  4381.          po->pblock->GetValue(PB_PARTICLECLASS,0,chunky,FOREVER);
  4382. //          AllSpawnBad(po->spawn,stype,chunky!=METABALLS);
  4383.             int ison; po->pblock->GetValue((po->ClassID()==BLIZZARD_CLASS_ID?PB_BLIPCOLLIDE_ON:PB_IPCOLLIDE_ON),t,ison,FOREVER);
  4384.             if (ison) stype=0;
  4385.             SpawnStuff(po->spawn,stype);
  4386.              if (chunky==INSTGEOM)
  4387.                 CheckSpawnButtons(po->pblock,hWnd,po->pickCB.repi);
  4388.              else
  4389.              { ObjectMutQueOff(po->spawn);
  4390.                CheckLifeButtons(stype,po->spawn);
  4391.              }
  4392.              if (stype==EMIT)
  4393.              { SpinnerOff(po->spawn,IDC_AP_MAXSPAWNGENSSPIN,IDC_AP_MAXSPAWNGENS);
  4394.                EnableWindow(GetDlgItem(hWnd,IDC_AP_MAXSPAWNDIEAFTER_TXT),FALSE);
  4395.              }
  4396.             break;
  4397.            case IDC_AP_OBJECTQUEUE:
  4398.             { po->pickCB.repi= SendMessage(GetDlgItem(hWnd,IDC_AP_OBJECTQUEUE),
  4399.                      LB_GETCURSEL,0,0);
  4400.              TurnButton(hWnd,IDC_AP_OBJQUEUEREPLACE,po->pickCB.repi>-1);
  4401.              TurnButton(hWnd,IDC_AP_OBJQUEUEDELETE,po->pickCB.repi>-1);
  4402.             break;
  4403.             }
  4404.             case IDC_AP_OBJECTQUEUEPICK:
  4405.                dtype=1;goto dopick;
  4406.             case IDC_AP_OBJQUEUEREPLACE:
  4407.               dtype=2;
  4408.               dopick:
  4409.                {if (po->ip->GetCommandMode()->ID() == CID_STDPICK)
  4410.                { if (po->creating)
  4411.                   {  theCreateSSBlizMode.JumpStart(po->ip,po);
  4412.                      po->ip->SetCommandMode(&theCreateSSBlizMode);
  4413.                   } else {po->ip->SetStdCommandMode(CID_OBJMOVE);}
  4414.                } else
  4415.                   { po->pickCB.po = po;
  4416.                      po->pickCB.dodist=dtype;
  4417.                     po->ip->SetPickMode(&po->pickCB);
  4418.                   }
  4419.                break;
  4420.             }
  4421.             case IDC_AP_OBJQUEUEDELETE:
  4422.             {  int i = SendMessage(GetDlgItem(hWnd,IDC_AP_OBJECTQUEUE),
  4423.                      LB_GETCURSEL,0,0);
  4424.                   TurnButton(hWnd,IDC_AP_OBJQUEUEREPLACE,0);
  4425.                   TurnButton(hWnd,IDC_AP_OBJQUEUEDELETE,0);
  4426.                if ((po->nlist.Count()>0)&&(i>-1))
  4427.                {  theHold.Begin();
  4428.                   po->DeleteFromList(i,0);
  4429.                   theHold.Accept(GetString(IDS_AP_OBJDEL));
  4430.                }
  4431.                po->valid=FALSE;
  4432.                po->NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
  4433.             break;
  4434.             }
  4435.             case IDC_AP_LIFEQUEUEDEL:
  4436.             {  int i = SendMessage(GetDlgItem(hWnd,IDC_AP_LIFEQUEUE),
  4437.                      LB_GETCURSEL,0,0);
  4438.                int Lcnt=po->llist.Count();
  4439.                if ((Lcnt>0)&&(i>-1)&&(i<Lcnt))
  4440.                {  theHold.Begin();
  4441.                   theHold.Put(new LifeListRestore(po));
  4442.                   po->DeleteFromLifeList(i);
  4443.                   TurnButton(hWnd,IDC_AP_LIFEQUEUEREPL,0);
  4444.                   TurnButton(hWnd,IDC_AP_LIFEQUEUEDEL,0);
  4445.                   theHold.Accept(GetString(IDS_AP_LIFEDEL));
  4446.                }
  4447.                po->valid=FALSE;
  4448.                po->NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
  4449.                break;
  4450.             }
  4451.             case IDC_AP_LIFEQUEUEADD:
  4452.             {   int i;
  4453.                po->pblock->GetValue(PB_SPAWNLIFEVLUE,t,i,FOREVER);
  4454.                theHold.Begin();
  4455.                theHold.Put(new LifeListRestore(po));
  4456.                po->AddToLifeList(i);
  4457.                TurnButton(hWnd,IDC_AP_LIFEQUEUEREPL,0);
  4458.                TurnButton(hWnd,IDC_AP_LIFEQUEUEDEL,0);
  4459.                theHold.Accept(GetString(IDS_AP_LIFEADD));
  4460.                po->valid=FALSE;
  4461.                po->NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
  4462.                break;
  4463.             }
  4464.             case IDC_AP_LIFEQUEUE:
  4465.             { rep = SendMessage(GetDlgItem(hWnd,IDC_AP_LIFEQUEUE),LB_GETCURSEL,0,0);
  4466.               TurnButton(hWnd,IDC_AP_LIFEQUEUEREPL,rep>-1);
  4467.               TurnButton(hWnd,IDC_AP_LIFEQUEUEDEL,rep>-1);
  4468.                po->valid=FALSE;
  4469.                po->NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
  4470.               break;
  4471.             }
  4472.             case IDC_AP_LIFEQUEUEREPL:
  4473.             { int i;
  4474.              rep = SendMessage(GetDlgItem(hWnd,IDC_AP_LIFEQUEUE),
  4475.                      LB_GETCURSEL,0,0);
  4476.               if (rep>-1)
  4477.               {   po->pblock->GetValue(PB_SPAWNLIFEVLUE,t,i,FOREVER);
  4478.                theHold.Begin();
  4479.                theHold.Put(new LifeListRestore(po));
  4480.                po->llist[rep]=i;
  4481.                po->SetUpLifeList();
  4482.                TurnButton(hWnd,IDC_AP_LIFEQUEUEREPL,0);
  4483.                TurnButton(hWnd,IDC_AP_LIFEQUEUEDEL,0);
  4484.                theHold.Accept(GetString(IDS_AP_LIFEREP));
  4485.                po->valid=FALSE;
  4486.                po->NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
  4487.               }
  4488.                break;
  4489.             }
  4490.       }
  4491.       default:
  4492.          return FALSE;
  4493.    }
  4494.    return TRUE;
  4495. }
  4496. class BParticleSpinDlgProc : public ParamMapUserDlgProc {
  4497.    public:
  4498.       CommonParticle *po;
  4499.  
  4500.       BParticleSpinDlgProc(CommonParticle *p) {po=p;}
  4501.       INT_PTR DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
  4502.       void Update(TimeValue t);
  4503.       void DeleteThis() {delete this;}
  4504.    };
  4505.  
  4506. void BParticleSpinDlgProc::Update(TimeValue t)
  4507. {   int axis;
  4508.    po->pblock->GetValue(PB_SPINAXISTYPE,t,axis,FOREVER);
  4509.    SpinStuff(po->hrot,axis==1,TRUE);
  4510.    int ison; po->pblock->GetValue(PB_BLIPCOLLIDE_ON,t,ison,FOREVER);
  4511.    int stype; po->pblock->GetValue(PB_SPAWNTYPE,t,stype,FOREVER);
  4512.    IPCControls(po->hrot,po->spawn,stype,ison);
  4513. }
  4514.  
  4515. INT_PTR BParticleSpinDlgProc::DlgProc(
  4516.       TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
  4517. {  switch (msg) {
  4518.       case WM_INITDIALOG:
  4519.       { Update(t);
  4520.         break;
  4521.       }
  4522.       case WM_COMMAND:
  4523.          switch (LOWORD(wParam))
  4524.          { case IDC_AP_PARTICLEDIRRND:
  4525.            { SpinStuff(hWnd,FALSE,TRUE);
  4526.            }
  4527.            break;
  4528.            case IDC_AP_PARTICLEDIRUSER:
  4529.                SpinStuff(hWnd,TRUE,TRUE);
  4530.             break;
  4531.            case IDC_INTERP_BOUNCEON:
  4532.             {  int ison; po->pblock->GetValue(PB_BLIPCOLLIDE_ON,t,ison,FOREVER);
  4533.                int stype; po->pblock->GetValue(PB_SPAWNTYPE,t,stype,FOREVER);
  4534.                IPCControls(hWnd,po->spawn,stype,ison);
  4535.             }
  4536.             break;
  4537.          }
  4538.       default:
  4539.          return FALSE;
  4540.    }
  4541.    return TRUE;
  4542. }
  4543. class SSParticleSpinDlgProc : public ParamMapUserDlgProc {
  4544.    public:
  4545.       CommonParticle *po;
  4546.  
  4547.       SSParticleSpinDlgProc(CommonParticle *p) {po=p;}
  4548.       INT_PTR DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
  4549.       void Update(TimeValue t);
  4550.       void DeleteThis() {delete this;}
  4551.    };
  4552.  
  4553. void SSParticleSpinDlgProc::Update(TimeValue t)
  4554. {   int axis;
  4555.    po->pblock->GetValue(PB_SPINAXISTYPE,t,axis,FOREVER);
  4556.    StretchStuff(axis,TRUE,po->hrot,po);
  4557.    int ison; po->pblock->GetValue(PB_IPCOLLIDE_ON,t,ison,FOREVER);
  4558.    int stype; po->pblock->GetValue(PB_SPAWNTYPE,t,stype,FOREVER);
  4559.    IPCControls(po->hrot,po->spawn,stype,ison);
  4560. }
  4561.  
  4562. INT_PTR SSParticleSpinDlgProc::DlgProc(
  4563.       TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
  4564. {  switch (msg) {
  4565.       case WM_INITDIALOG:
  4566.       { Update(t);
  4567.          break;
  4568.       }
  4569.       case WM_COMMAND:
  4570.          switch (LOWORD(wParam))
  4571.          { case IDC_AP_PARTICLEDIRTRAVL:
  4572.              StretchStuff(1,TRUE,hWnd,po);
  4573.            break;
  4574.            case IDC_AP_PARTICLEDIRRND:
  4575.             StretchStuff(0,TRUE,hWnd,po);
  4576.            break;
  4577.            case IDC_AP_PARTICLEDIRUSER:
  4578.             StretchStuff(2,TRUE,hWnd,po);
  4579.             break;
  4580.            case IDC_INTERP_BOUNCEON:
  4581.             {  int ison; po->pblock->GetValue(PB_IPCOLLIDE_ON,t,ison,FOREVER);
  4582.                int stype; po->pblock->GetValue(PB_SPAWNTYPE,t,stype,FOREVER);
  4583.                IPCControls(hWnd,po->spawn,stype,ison);
  4584.             }
  4585.             break;
  4586.          }
  4587.       default:
  4588.          return FALSE;
  4589.    }
  4590.    return TRUE;
  4591. }
  4592.  
  4593. void CommonParticle::ResetSystem(TimeValue t,BOOL full)
  4594. {  lc.lastmin=-1;lc.lastcollide=-1;
  4595.    rcounter=0;
  4596.    vcounter=0;
  4597.    if (full)
  4598.    { tvalid = t;
  4599.      valid  = TRUE;
  4600.    }
  4601. }
  4602.  
  4603. //--- SuprSprayParticle Methods--------------------------------------------
  4604.  
  4605. SuprSprayParticle::SuprSprayParticle()
  4606. {int FToTick=(int)((float)TIME_TICKSPERSEC/(float)GetFrameRate());
  4607.      int tpf=GetTicksPerFrame();
  4608.  
  4609.    sdata=NULL;
  4610.    cnode=NULL;
  4611.    custnode=NULL;
  4612.    cmesh=NULL;
  4613.    dispmesh=NULL;
  4614.    origmtl=NULL;
  4615.  
  4616.    ReplaceReference(PBLK, CreateParameterBlock(spdescVer6, PBLOCK_LENGTH_SUPRSPRAY, CURRENT_VERSION));
  4617.    pblock->SetValue(PB_SPEED,0,10.0f);
  4618.    pblock->SetValue(PB_SPEEDVAR,0,0.0f);
  4619.    pblock->SetValue(PB_OFFAXIS,0,0.0f);
  4620.    pblock->SetValue(PB_AXISSPREAD,0,0.0f);
  4621.    pblock->SetValue(PB_OFFPLANE,0,0.0f);
  4622.    pblock->SetValue(PB_PLANESPREAD,0,0.0f);
  4623.    pblock->SetValue(PB_PBIRTHRATE,0,10);
  4624.    pblock->SetValue(PB_PTOTALNUMBER,0,100);
  4625.    pblock->SetValue(PB_BIRTHMETHOD,0,0);
  4626.    pblock->SetValue(PB_DISPLAYPORTION,0,0.1f);
  4627.    pblock->SetValue(PB_EMITSTART,0,TimeValue(0));
  4628.    pblock->SetValue(PB_EMITSTOP,0,(TimeValue)30*FToTick);// correct constant?
  4629.    pblock->SetValue(PB_DISPUNTIL,0,100*FToTick);// correct constant?
  4630.    pblock->SetValue(PB_LIFE,0,30*FToTick);// correct constant?
  4631.    pblock->SetValue(PB_LIFEVAR,0,0.0f);
  4632.    pblock->SetValue(PB_SUBFRAMEMOVE,0,1);
  4633.    pblock->SetValue(PB_SUBFRAMETIME,0,1);
  4634.    pblock->SetValue(PB_SUBFRAMEROT,0,0);
  4635.    pblock->SetValue(PB_SIZE,0,1.0f);
  4636.    pblock->SetValue(PB_SIZEVAR,0,0.0f);
  4637.    pblock->SetValue(PB_GROWTIME,0,10*FToTick);
  4638.    pblock->SetValue(PB_FADETIME,0,10*FToTick);
  4639.    pblock->SetValue(PB_RNDSEED,0,12345);
  4640.  
  4641.    pblock->SetValue(PB_PARTICLETYPE,0,0);
  4642.    pblock->SetValue(PB_METATENSION,0,1.0f);
  4643.    pblock->SetValue(PB_METATENSIONVAR,0,0.0f);
  4644.    pblock->SetValue(PB_METAAUTOCOARSE,0,1);
  4645.    pblock->SetValue(PB_METACOURSE,0,0.5f);
  4646.    pblock->SetValue(PB_VIEWPORTSHOWS,0,1);
  4647.    pblock->SetValue(PB_MAPPINGTYPE,0,0);
  4648.    pblock->SetValue(PB_MAPPINGTIME,0,30*FToTick);
  4649.    pblock->SetValue(PB_MAPPINGDIST,0,100.0f);
  4650.  
  4651.    pblock->SetValue(PB_SPINTIME,0,30*FToTick);
  4652.    pblock->SetValue(PB_SPINTIMEVAR,0,0.0f);
  4653.    pblock->SetValue(PB_SPINPHASE,0,0.0f);
  4654.    pblock->SetValue(PB_SPINPHASEVAR,0,0.0f);
  4655.    pblock->SetValue(PB_SPINAXISTYPE,0,0);
  4656.    pblock->SetValue(PB_SPINAXISX,0,1.0f);
  4657.    pblock->SetValue(PB_SPINAXISY,0,0.0f);
  4658.    pblock->SetValue(PB_SPINAXISZ,0,0.0f);
  4659.    pblock->SetValue(PB_SPINAXISVAR,0,0.0f);
  4660.  
  4661.    pblock->SetValue(PB_EMITVINFL,0,100.0f);
  4662.    pblock->SetValue(PB_EMITVMULT,0,1.0f);
  4663.    pblock->SetValue(PB_EMITVMULTVAR,0,0.0f);
  4664.  
  4665.    pblock->SetValue(PB_BUBLAMP,0,0.0f);
  4666.    pblock->SetValue(PB_BUBLAMPVAR,0,0.0f);
  4667.    pblock->SetValue(PB_BUBLPER,0,100000*FToTick);
  4668.    pblock->SetValue(PB_BUBLPERVAR,0,0.0f);
  4669.    pblock->SetValue(PB_BUBLPHAS,0,0.0f);
  4670.    pblock->SetValue(PB_BUBLPHASVAR,0,0.0f);
  4671.  
  4672.    pblock->SetValue(PB_EMITRWID,0,0.0f);
  4673.    pblock->SetValue(PB_EMITRHID,0,0);
  4674.    pblock->SetValue(PB_SPAWNGENS,0,1);
  4675.    pblock->SetValue(PB_SPAWNCOUNT,0,1);
  4676.    pblock->SetValue(PB_METACOURSEV,0,1.0f);
  4677.    pblock->SetValue(PB_SPAWNPERCENT,0,100);
  4678.    pblock->SetValue(PB_SPAWNMULTVAR,0,0.0f);
  4679.    pblock->SetValue(PB_SSNOTDRAFT,0,0);
  4680.    pblock->SetValue(PB_SSSPAWNDIEAFTER,0,0);
  4681.    pblock->SetValue(PB_IPCOLLIDE_ON,0,0);
  4682.    pblock->SetValue(PB_IPCOLLIDE_STEPS,0,2);
  4683.    pblock->SetValue(PB_IPCOLLIDE_BOUNCE,0,1.0f);
  4684.    pblock->SetValue(PB_IPCOLLIDE_BOUNCEVAR,0,0.0f);
  4685.  
  4686.    custname=TSTR(_T(" "));
  4687.    ResetSystem(0,FALSE);
  4688.    size=43*isize+fsize*37;
  4689.    times.tl.SetCount(0);
  4690.    dispt=-99999;
  4691.    theSuprSprayDraw.bboxpt=NULL;
  4692.    nmtls.ZeroCount();
  4693.    deftime=0;
  4694.    parts.points.ZeroCount();
  4695.    maincount=0;
  4696.    cancelled=FALSE;
  4697.    wasmulti=FALSE;
  4698.    nlist.ZeroCount();
  4699.    llist.ZeroCount();
  4700.    dflags=APRTS_ROLLUP_FLAGS;
  4701.    backpatch=TRUE;
  4702.    ClearAFlag(A_NOTREND);
  4703.     stepSize=GetTicksPerFrame();
  4704. }
  4705.  
  4706. SuprSprayParticle::~SuprSprayParticle()
  4707. {  if (sdata) {delete[] sdata;sdata=NULL;}
  4708. // SetFlag(dflags,STDMTL_ROLLUP1_OPEN,ip->IsRollupPanelOpen(hPanelBasic));
  4709.    DeleteAllRefsFromMe();
  4710.    pblock=NULL;
  4711.    parts.FreeAll();
  4712.    times.tl.SetCount(0);
  4713.    times.tl.Shrink();
  4714.    nmtls.ZeroCount();nmtls.Shrink();
  4715.    llist.ZeroCount();llist.Shrink();
  4716.    nlist.ZeroCount();nlist.Shrink();
  4717.    if (cmesh) delete[] cmesh;
  4718.    if (theSuprSprayDraw.bboxpt) delete[] theSuprSprayDraw.bboxpt;
  4719.    if (dispmesh) delete dispmesh;
  4720. }
  4721.  
  4722. Matrix3 CommonParticle::TumbleMat(int index,float amount, float scale)
  4723.    {
  4724.    Matrix3 mat;
  4725.    Quat q;
  4726.    float ang[3];
  4727.  
  4728.    srand(int(PARTICLE_SEED) * Perm(index) + int(PARTICLE_SEED));
  4729.    
  4730.    for (int i=0; i<3; i++) {
  4731.       ang[i] = (float(2*rand())/float(RAND_MAX) - 1.0f);
  4732.       if (amount>0.0f) {
  4733.          float off = 8725.0f*i;
  4734.          ang[i] += noise3((parts[index]+Point3(off,off,off))*scale)*amount;
  4735.          }
  4736.       ang[i] *= TWOPI;
  4737.       }
  4738.    
  4739.    EulerToQuat(ang,q);
  4740.    q.MakeMatrix(mat);
  4741.    return mat;
  4742.    }
  4743.  
  4744. TimeValue CommonParticle::ParticleLife(TimeValue t, int i)
  4745. {   int pcount=parts.Count();
  4746.    if (!(i<pcount)) return 0;
  4747.    return sdata[i].L;
  4748. }
  4749.  
  4750. Point3 BlizzardParticle::ParticlePosition(TimeValue t,int i)
  4751. {  int pcount=parts.points.Count();
  4752.    if (!(i<pcount)) return Zero;
  4753.    Point3 retpt=parts.points[i];
  4754.    return retpt;
  4755. }
  4756.  
  4757. Point3 SuprSprayParticle::ParticlePosition(TimeValue t,int i)
  4758. {  int pcount=parts.points.Count();
  4759.    if (!(i<pcount)) return Zero;
  4760.    Point3 FinalP=parts.points[i];
  4761. // figure out particle class
  4762.    int isinst;
  4763.    pblock->GetValue(PB_PARTICLECLASS,0,isinst,FOREVER);
  4764. // if we have custom geometry, find the center of the bounding box and velocity normal
  4765.    if ((isinst==INSTGEOM)&&(custnode))
  4766.    {  int anioff;
  4767.       float dlgsize;
  4768.       dlgsize=parts.radius[i];
  4769.       float zoffset=0.0f;
  4770.       Point3 OffsetV=Zero;;
  4771.       TimeValue aniend=GetAnimEnd();
  4772.       int anifr=aniend+GetTicksPerFrame();
  4773.       pblock->GetValue(PB_ANIMATIONOFFSET,0,anioff,FOREVER);
  4774.       TimeValue Ctime=(anioff?GetCurTime(sdata[i].showframe,(anioff>1?t:parts.ages[i]),anifr):t);
  4775.       int mnum=TimeFound(times,Ctime,(sdata[i].gennum>nlist.Count()?nlist.Count():sdata[i].gennum));
  4776.       if (mnum>=0) zoffset=cmesh[mnum].getBoundingBox().Center().z;
  4777. // if we're using DoT/MBlur, account for scaling due to stretch
  4778.       int axisentered;
  4779.       pblock->GetValue(PB_SPINAXISTYPE,0,axisentered,FOREVER);
  4780.       if (axisentered==DIRTRAVEL)
  4781.       {  int K;
  4782.          pblock->GetValue(PB_STRETCH,t,K,FOREVER);
  4783.          float strlen=GetLen(parts.vels[i],K);
  4784.          zoffset*=strlen;
  4785.       }
  4786.       float lenV=Length(parts.vels[i]);
  4787.       if (lenV>EPSILON) OffsetV=parts.vels[i]/lenV;
  4788.       FinalP+=zoffset*dlgsize*OffsetV;
  4789.    }
  4790.    return FinalP;
  4791. }
  4792.  
  4793. Point3 SuprSprayParticle::ParticleVelocity(TimeValue t,int i)
  4794. {  Point3 retvel=Zero;
  4795.    int pcount=parts.vels.Count();
  4796.    if (i<pcount)
  4797.       retvel=parts.vels[i];
  4798.    return retvel;
  4799. }
  4800.  
  4801. float SuprSprayParticle::ParticleSize(TimeValue t,int i)
  4802. {  float strlen=1.0f;
  4803.    float boxlen=1.0f;
  4804.    float dlgsize;
  4805.    int pcount=parts.radius.Count();
  4806.    if (!(i<pcount)) return 0.0f;
  4807.    int axisentered,K,isinst,ptype;
  4808. // get the size/scale from the dialog box processed for this particle...
  4809.    dlgsize=parts.radius[i];
  4810. // figure out particle type and class
  4811.    pblock->GetValue(PB_PARTICLETYPE,0,ptype,FOREVER);
  4812.    pblock->GetValue(PB_PARTICLECLASS,0,isinst,FOREVER);
  4813. // if there are custom particles, find bounding box params...
  4814.    if ((isinst==INSTGEOM)&&(custnode))
  4815.    {  int anioff;
  4816.       TimeValue aniend=GetAnimEnd();
  4817.       int anifr=aniend+GetTicksPerFrame();
  4818.       pblock->GetValue(PB_ANIMATIONOFFSET,0,anioff,FOREVER);
  4819.       TimeValue Ctime=(anioff?GetCurTime(sdata[i].showframe,(anioff>1?t:parts.ages[i]),anifr):t);
  4820.       int mnum=TimeFound(times,Ctime,(sdata[i].gennum>nlist.Count()?nlist.Count():sdata[i].gennum));
  4821.       if (mnum>=0) boxlen=cmesh[mnum].getBoundingBox().Width().z;
  4822.    }
  4823. // if we're using MBlur and DoT then account for scaling along DoT
  4824.    pblock->GetValue(PB_SPINAXISTYPE,0,axisentered,FOREVER);
  4825.    if (axisentered==DIRTRAVEL)
  4826.    {  pblock->GetValue(PB_STRETCH,t,K,FOREVER);
  4827.       strlen=GetLen(parts.vels[i],K);
  4828.    }
  4829.    float templen=boxlen*strlen;
  4830.    if ((isinst!=PB_PARTICLECLASS)&&(ptype==RENDTET)) templen*=1.3f;
  4831.    return templen*dlgsize;
  4832. }
  4833.  
  4834. int SuprSprayParticle::ParticleCenter(TimeValue t,int i)
  4835. {  int ptype,isinst;
  4836.    pblock->GetValue(PB_PARTICLECLASS,0,isinst,FOREVER);
  4837.    pblock->GetValue(PB_PARTICLETYPE,0,ptype,FOREVER);
  4838.    if (isinst==INSTGEOM) return PARTCENTER_CENTER;
  4839.    if (ptype==RENDTET) return PARTCENTER_HEAD;
  4840.    return PARTCENTER_CENTER;  
  4841. }
  4842.  
  4843. Point3 BlizzardParticle::ParticleVelocity(TimeValue t,int i)
  4844. {  Point3 retvel=Zero;
  4845.    int pcount=parts.vels.Count();
  4846.    if (i<pcount)
  4847.       retvel=parts.vels[i];
  4848.    return retvel;
  4849. }
  4850.  
  4851. float BlizzardParticle::ParticleSize(TimeValue t,int i)
  4852. {  int isinst;
  4853.    int pcount=parts.radius.Count();
  4854.    if (!(i<pcount)) return 0.0f;
  4855.    float radius=1.0f,size=parts.radius[i];
  4856.    pblock->GetValue(PB_PARTICLECLASS,0,isinst,FOREVER);
  4857.    if ((isinst==INSTGEOM) &&(custnode))
  4858.    {  int anioff;
  4859.       TimeValue aniend=GetAnimEnd();
  4860.       int anifr=aniend+GetTicksPerFrame();
  4861.       pblock->GetValue(PB_ANIMATIONOFFSET,0,anioff,FOREVER);
  4862.       TimeValue Ctime=(anioff?GetCurTime(sdata[i].showframe,(anioff>1?t:parts.ages[i]),anifr):t);
  4863.       int mnum=TimeFound(times,Ctime,(sdata[i].gennum>nlist.Count()?nlist.Count():sdata[i].gennum));
  4864.       if (mnum>=0)
  4865.       radius=(cmesh[mnum].getBoundingBox().Width()).z;
  4866.    }
  4867.    return radius*size;  
  4868. }
  4869.  
  4870. int BlizzardParticle::ParticleCenter(TimeValue t,int i)
  4871. {  return PARTCENTER_CENTER;  
  4872. }
  4873.  
  4874. int CommonParticle::RenderBegin(TimeValue t, ULONG flags)
  4875.    {  SetAFlag(A_RENDER);
  4876.       ParticleInvalid();      
  4877.       NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
  4878.       cancelled=FALSE;
  4879.       int isinst;
  4880.       pblock->GetValue(PB_PARTICLECLASS,0,isinst,FOREVER);
  4881.       if ((isinst==INSTGEOM) &&(custnode))
  4882.          custnode->SetProperty(PROPID_FORCE_RENDER_MESH_COPY,(void *)1);
  4883.    return 0;
  4884.    }
  4885.  
  4886. int CommonParticle::RenderEnd(TimeValue t)
  4887.    {
  4888.       ClearAFlag(A_RENDER);
  4889.       ParticleInvalid();      
  4890.       NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
  4891.       int isinst;
  4892.       pblock->GetValue(PB_PARTICLECLASS,0,isinst,FOREVER);
  4893.       if ((isinst==INSTGEOM) &&(custnode))
  4894.          custnode->SetProperty(PROPID_FORCE_RENDER_MESH_COPY,(void *)0);
  4895.    return 0;
  4896.    }
  4897.  
  4898. void SuprSprayParticle::BeginEditParams(
  4899.       IObjParam *ip, ULONG flags,Animatable *prev)
  4900.    {
  4901.    SimpleParticle::BeginEditParams(ip,flags,prev);
  4902.    editOb = this;
  4903.    this->ip = ip;
  4904.  
  4905.    if (flags&BEGIN_EDIT_CREATE) {
  4906.       creating = TRUE;
  4907.    } else { creating = FALSE; }
  4908.    if (pmapParam && pmapPGen && pmapPType && pmapPSpin && pmapEmitV && pmapBubl && pmapSpawn)
  4909.    {  pmapParam->SetParamBlock(pblock);
  4910.       pmapPGen->SetParamBlock(pblock);
  4911.       pmapPType->SetParamBlock(pblock);
  4912.       pmapPSpin->SetParamBlock(pblock);
  4913.       pmapEmitV->SetParamBlock(pblock);
  4914.       pmapBubl->SetParamBlock(pblock);
  4915.       pmapSpawn->SetParamBlock(pblock);
  4916.       DLSetWindowLongPtr(hParams2, this);
  4917.    } else
  4918.    {  pmapParam = CreateCPParamMap(
  4919.          descParamSuprSpray,PARAMSuprSpray_LENGTH,
  4920.          pblock,
  4921.          ip,
  4922.          hInstance,
  4923.          MAKEINTRESOURCE(IDD_SUPRPRTS_SUPERSPRAY),
  4924.          GetString(IDS_RB_PARAMETERS),
  4925.          dflags&APRTS_ROLLUP1_OPEN?0:APPENDROLL_CLOSED);
  4926.  
  4927.       pmapPGen = CreateCPParamMap(
  4928.          descParamPGen,PARAMPGEN_LENGTH,
  4929.          pblock,
  4930.          ip,
  4931.          hInstance,
  4932.          MAKEINTRESOURCE(IDD_SUPRPRTS_GEN_SS),
  4933.          GetString(IDS_RB_PGEN),
  4934.          dflags&APRTS_ROLLUP2_OPEN?0:APPENDROLL_CLOSED);
  4935.      
  4936.       pmapPType = CreateCPParamMap(
  4937.          descParamPType,PARAMPTYPE_LENGTH,
  4938.          pblock,
  4939.          ip,
  4940.          hInstance,
  4941.          MAKEINTRESOURCE(IDD_SUPRPRTS_PARTTYPE_SS),
  4942.          GetString(IDS_RB_PTYPE),
  4943.          dflags&APRTS_ROLLUP3_OPEN?0:APPENDROLL_CLOSED);    
  4944.    
  4945.       pmapPSpin = CreateCPParamMap(
  4946.          descParamPSpin,PARAMPSPIN_LENGTH,
  4947.          pblock,
  4948.          ip,
  4949.          hInstance,
  4950.          MAKEINTRESOURCE(IDD_SUPRPRTS_ROT),
  4951.          GetString(IDS_RB_SPIN),
  4952.          dflags&APRTS_ROLLUP4_OPEN?0:APPENDROLL_CLOSED);    
  4953.    
  4954.       pmapEmitV = CreateCPParamMap(
  4955.          descParamEmitV,PARAMEMITV_LENGTH,
  4956.          pblock,
  4957.          ip,
  4958.          hInstance,
  4959.          MAKEINTRESOURCE(IDD_SUPRPRTS_EMITV),
  4960.          GetString(IDS_RB_EMITV),
  4961.          dflags&APRTS_ROLLUP5_OPEN?0:APPENDROLL_CLOSED);    
  4962.    
  4963.       pmapBubl = CreateCPParamMap(
  4964.          descParamBubl,PARAMBUBL_LENGTH,
  4965.          pblock,
  4966.          ip,
  4967.          hInstance,
  4968.          MAKEINTRESOURCE(IDD_SUPRPRTS_BUBL),
  4969.          GetString(IDS_RB_BUBL),
  4970.          dflags&APRTS_ROLLUP6_OPEN?0:APPENDROLL_CLOSED);    
  4971.       pmapSpawn = CreateCPParamMap(
  4972.          descPSpawning,PSPAWNINGPARAMS_LENGTH,
  4973.          pblock,
  4974.          ip,
  4975.          hInstance,
  4976.          MAKEINTRESOURCE(IDD_SUPRPRTS_SPAWNING),
  4977.          GetString(IDS_AP_PSPAWN),
  4978.          dflags&APRTS_ROLLUP7_OPEN?0:APPENDROLL_CLOSED);    
  4979.  
  4980.       hParams2 = ip->AddRollupPage(
  4981.             hInstance,
  4982.             MAKEINTRESOURCE(IDD_SUPRPRTS_SAVE),
  4983.             CustomSettingParamDlgProc,
  4984.             GetString(IDS_RB_LOADSAVE),
  4985.             (LPARAM)this,dflags&APRTS_ROLLUP8_OPEN?0:APPENDROLL_CLOSED);      
  4986.       ip->RegisterDlgWnd(hParams2);
  4987.  
  4988.       }
  4989.    spawn=pmapSpawn->GetHWnd();
  4990.    hparam=pmapParam->GetHWnd();
  4991.    hgen=pmapPGen->GetHWnd();
  4992.    hptype=pmapPType->GetHWnd();
  4993.    hrot=pmapPSpin->GetHWnd();
  4994.    hbubl=pmapBubl->GetHWnd();
  4995.    if (pmapPType) pmapPType->SetUserDlgProc(new SSParticleDisableDlgProc(this));
  4996.    if (pmapPGen) pmapPGen->SetUserDlgProc(new SSParticleGenDlgProc(this));
  4997.    if (pmapParam) pmapParam->SetUserDlgProc(new SSParticleDlgProc(this));
  4998.    if (pmapSpawn) pmapSpawn->SetUserDlgProc(new ComParticleSpawnDlgProc(this));
  4999.    if (pmapPSpin) pmapPSpin->SetUserDlgProc(new SSParticleSpinDlgProc(this));
  5000. }  
  5001.  
  5002. void SuprSprayParticle::EndEditParams(
  5003.       IObjParam *ip, ULONG flags,Animatable *next)
  5004.    {TimeValue t0,t2;
  5005.    SetFlag(dflags,APRTS_ROLLUP1_OPEN,IsRollupPanelOpen(hparam));
  5006.    SetFlag(dflags,APRTS_ROLLUP2_OPEN,IsRollupPanelOpen(hgen));
  5007.    SetFlag(dflags,APRTS_ROLLUP3_OPEN,IsRollupPanelOpen(hptype));
  5008.    SetFlag(dflags,APRTS_ROLLUP4_OPEN,IsRollupPanelOpen(hrot));
  5009.    SetFlag(dflags,APRTS_ROLLUP5_OPEN,IsRollupPanelOpen(pmapEmitV->GetHWnd()));
  5010.    SetFlag(dflags,APRTS_ROLLUP6_OPEN,IsRollupPanelOpen(hbubl));
  5011.    SetFlag(dflags,APRTS_ROLLUP7_OPEN,IsRollupPanelOpen(spawn));
  5012.    SetFlag(dflags,APRTS_ROLLUP8_OPEN,IsRollupPanelOpen(hParams2));
  5013.    SimpleParticle::EndEditParams(ip,flags,next);
  5014.  
  5015.    if (flags&END_EDIT_REMOVEUI) {
  5016.       pblock->GetValue(PB_EMITSTART,0,t0,FOREVER);
  5017.       pblock->GetValue(PB_EMITSTOP,0,t2,FOREVER);
  5018.       if (t2<t0) pblock->SetValue(PB_EMITSTOP,0,t0);
  5019.       DestroyCPParamMap(pmapParam);
  5020.       DestroyCPParamMap(pmapPGen);
  5021.       DestroyCPParamMap(pmapPType);
  5022.       DestroyCPParamMap(pmapPSpin);
  5023.       DestroyCPParamMap(pmapEmitV);
  5024.       DestroyCPParamMap(pmapBubl);
  5025.       DestroyCPParamMap(pmapSpawn);
  5026.  
  5027.       ip->UnRegisterDlgWnd(hParams2);
  5028.       ip->DeleteRollupPage(hParams2);
  5029.       hParams2 = NULL;
  5030.  
  5031.       pmapParam  = NULL;
  5032.       pmapPGen = NULL;
  5033.       pmapPType = NULL;
  5034.       pmapPSpin = NULL;
  5035.       pmapEmitV = NULL;
  5036.       pmapBubl = NULL;
  5037.       pmapSpawn = NULL;
  5038.    }else
  5039.       DLSetWindowLongPtr(hParams2, NULL);
  5040.    ip->ClearPickMode();
  5041.    ip= NULL;
  5042.    creating = FALSE;
  5043.    }
  5044.  
  5045. void CommonParticle::MapKeys(TimeMap *map,DWORD flags)
  5046. {  Animatable::MapKeys(map,flags);
  5047.    TimeValue TempTime;
  5048. // remap values
  5049.    pblock->GetValue(PB_EMITSTART,0,TempTime,FOREVER);
  5050.    TempTime=map->map(TempTime);
  5051.    pblock->SetValue(PB_EMITSTART,0,TempTime);
  5052.    pblock->GetValue(PB_EMITSTOP,0,TempTime,FOREVER);
  5053.    TempTime=map->map(TempTime);
  5054.    pblock->SetValue(PB_EMITSTOP,0,TempTime);
  5055.    pblock->GetValue(PB_DISPUNTIL,0,TempTime,FOREVER);
  5056.    TempTime=map->map(TempTime);
  5057.    pblock->SetValue(PB_DISPUNTIL,0,TempTime);
  5058. // scaled values
  5059.    pblock->GetValue(PB_LIFE,0,TempTime,FOREVER);
  5060.    TempTime=map->map(TempTime);
  5061.    pblock->SetValue(PB_LIFE,0,TempTime);
  5062.    pblock->GetValue(PB_LIFEVAR,0,TempTime,FOREVER);
  5063.    TempTime=map->map(TempTime);
  5064.    pblock->SetValue(PB_LIFEVAR,0,TempTime);
  5065.    pblock->GetValue(PB_GROWTIME,0,TempTime,FOREVER);
  5066.    TempTime=map->map(TempTime);
  5067.    pblock->SetValue(PB_GROWTIME,0,TempTime);
  5068.    pblock->GetValue(PB_FADETIME,0,TempTime,FOREVER);
  5069.    TempTime=map->map(TempTime);
  5070.    pblock->SetValue(PB_FADETIME,0,TempTime);
  5071.    pblock->GetValue(PB_MAPPINGTIME,0,TempTime,FOREVER);
  5072.    TempTime=map->map(TempTime);
  5073.    pblock->SetValue(PB_MAPPINGTIME,0,TempTime);
  5074.    pblock->GetValue(PB_SPINTIME,0,TempTime,FOREVER);
  5075.    TempTime=map->map(TempTime);
  5076.    pblock->SetValue(PB_SPINTIME,0,TempTime);
  5077. // pblock->GetValue(PB_OFFSETAMOUNT,0,TempTime,FOREVER);
  5078. // TempTime=map->map(TempTime);
  5079. // pblock->SetValue(PB_OFFSETAMOUNT,0,TempTime);
  5080.    if (ClassID()==SUPRSPRAY_CLASS_ID)
  5081.    {  pblock->GetValue(PB_BUBLPER,0,TempTime,FOREVER);
  5082.       TempTime=map->map(TempTime);
  5083.       pblock->SetValue(PB_BUBLPER,0,TempTime);
  5084.    }
  5085. }  
  5086.  
  5087. Interval CommonParticle::GetValidity(TimeValue t)
  5088.    {
  5089.    // For now...
  5090.    return Interval(t,t);
  5091.    }
  5092.  
  5093. void SuprSprayParticle::BuildEmitter(TimeValue t, Mesh& amesh)
  5094.    {
  5095.    float width,hwidth,u;
  5096.    mvalid = FOREVER;
  5097.    pblock->GetValue(PB_EMITRWID,t,width,mvalid);
  5098. // width  *= 0.5f;
  5099.    hwidth =width*0.5f;
  5100.  
  5101.    mesh.setNumVerts(23);
  5102.    mesh.setNumFaces(18);
  5103.    for (int i=0; i<12; i++) {
  5104.       u = float(i)/12.0f * TWOPI;
  5105.       mesh.setVert(i, Point3((float)cos(u) * width, (float)sin(u) * width, 0.0f));
  5106.    }
  5107.    for (int i=0; i<12; i++)
  5108.    { int i1 = i+1;
  5109.      if (i1==12) i1 = 0;
  5110.      mesh.faces[i].setEdgeVisFlags(1,0,0);
  5111.      mesh.faces[i].setSmGroup(0);
  5112.      mesh.faces[i].setVerts(i,i1,12);
  5113.    }
  5114.    mesh.setVert(12, Point3(0.0f, 0.0f, 0.0f));
  5115.    mesh.setVert(13, Point3(width,0.0f, width));
  5116.    mesh.setVert(14, Point3(0.0f, 0.0f, width));
  5117.    mesh.setVert(15, Point3(-width, 0.0f, width));
  5118.    mesh.setVert(16, Point3( width, 0.0f,-width));
  5119.    mesh.setVert(17, Point3( 0.0f, 0.0f, -width));
  5120.    mesh.setVert(18, Point3(-width, 0.0f, -width));
  5121.    mesh.setVert(19, Point3(hwidth, 0.0f,hwidth));
  5122.    mesh.setVert(20, Point3(-hwidth, 0.0f,hwidth));
  5123.    mesh.setVert(21, Point3(0.0f,hwidth,hwidth));
  5124.    mesh.setVert(22, Point3(0.0f,-hwidth,hwidth));
  5125.  
  5126.    mesh.faces[12].setVerts(13,14,17);
  5127.    mesh.faces[12].setEdgeVisFlags(1,1,0);
  5128.    mesh.faces[12].setSmGroup(0);
  5129.  
  5130.    mesh.faces[13].setEdgeVisFlags(0,1,1);
  5131.    mesh.faces[13].setSmGroup(0);
  5132.    mesh.faces[13].setVerts(13,17,16);
  5133.  
  5134.    mesh.faces[14].setEdgeVisFlags(1,1,0);
  5135.    mesh.faces[14].setSmGroup(0);
  5136.    mesh.faces[14].setVerts(14,15,18);
  5137.  
  5138.    mesh.faces[15].setEdgeVisFlags(0,1,1);
  5139.    mesh.faces[15].setSmGroup(0);
  5140.    mesh.faces[15].setVerts(14,18,17);
  5141.  
  5142.    mesh.faces[16].setEdgeVisFlags(1,1,1);
  5143.    mesh.faces[16].setSmGroup(0);
  5144.    mesh.faces[16].setVerts(19,14,20);
  5145.  
  5146.    mesh.faces[17].setEdgeVisFlags(1,1,1);
  5147.    mesh.faces[17].setSmGroup(0);
  5148.    mesh.faces[17].setVerts(21,14,22);
  5149.  
  5150.    mesh.InvalidateGeomCache();
  5151.    }
  5152.  
  5153. int CommonParticle::CountLive()
  5154. {  int c=0;
  5155.    for (int i=0; i<parts.Count(); i++)
  5156.      {if (parts.Alive(i)) c++;}
  5157.    return c;
  5158. }
  5159.  
  5160. void CommonParticle::RetrieveMtls(INode *node,int subtree,int *numsubs,int *numtabs,int *tabmax,TimeValue t)
  5161. { int nc,i;
  5162.   Mtl *submtl=node->GetMtl();
  5163.   if (subtree)
  5164.   { if ((nc=node->NumberOfChildren())>0)
  5165.    for (i=0;i<nc;i++)
  5166.      RetrieveMtls(node->GetChildNode(i),subtree,numsubs,numtabs,tabmax,t);
  5167.   }
  5168.   if (IsGEOM(node->EvalWorldState(t).obj)!=NULL)
  5169.   { if (*numtabs>=*tabmax)
  5170.    { mttab.Resize((*tabmax)+=256);}
  5171.    if (submtl!=NULL)
  5172.    { mttab[(*numtabs)++]=submtl;
  5173.      int subs;
  5174.      if ((subs=submtl->NumSubMtls())>0)
  5175.        (*numsubs)+=subs;
  5176.      else (*numsubs)++;
  5177.    }
  5178.    else
  5179.    {DWORD tc=node->GetWireColor();
  5180.    StdMat *m = NewDefaultStdMat();
  5181.    m->SetName(TSTR(_T("C"))+node->GetName());
  5182.    Color bcolor(tc);
  5183.    m->SetDiffuse(bcolor,0);
  5184.    mttab[(*numtabs)++]=(Mtl*)m;
  5185.    (*numsubs)++;
  5186.    }
  5187.   }
  5188. }
  5189.  
  5190. void CommonParticle::DoGroupMtls(INode *node,int subtree,int *numsubs,int *numtabs,int *tabmax,TimeValue t)
  5191. { int nc;
  5192.   if ((nc=node->NumberOfChildren())>0)
  5193.    for (int i=0;i<nc;i++)
  5194.    { INode *nxtnode=node->GetChildNode(i);
  5195.      if (nxtnode->IsGroupHead()) DoGroupMtls(nxtnode,subtree,numsubs,numtabs,tabmax,t);
  5196.      else if((subtree)||(nxtnode->IsGroupMember())) RetrieveMtls(nxtnode,subtree,numsubs,numtabs,tabmax,t);
  5197.   }
  5198. }
  5199.  
  5200. void CommonParticle::AssignMtl(INode *node,INode *topnode,int subtree,TimeValue t)
  5201. {  Mtl *submtl;
  5202.    MultiMtl *newmat=NULL;
  5203.    Mtl *nmtl=NULL;
  5204.    TSTR newname;
  5205.    MtlBaseLib glib;
  5206.    int tabmax=256;
  5207.    newname=TSTR(_T("CMat"))+node->GetName();
  5208.    if (_tcslen(newname)>16) newname[16]='\0';
  5209.    int numsubs=0,numtabs=0,nCount=nlist.Count();
  5210.    nmtls.SetCount(nCount);
  5211.     mttab.SetCount(tabmax);
  5212.     submtl=custnode->GetMtl();
  5213.    INode *tmpnode=custnode;
  5214.    backpatch=FALSE;
  5215.    for (int mut=0;mut<=nCount;mut++)
  5216.    { if (tmpnode->IsGroupHead())
  5217.        DoGroupMtls(tmpnode,subtree,&numsubs,&numtabs,&tabmax,t);
  5218.      else
  5219.      RetrieveMtls(tmpnode,subtree,&numsubs,&numtabs,&tabmax,t);
  5220.      if (mut!=nCount)
  5221.      {nmtls[mut]=numsubs;
  5222.       tmpnode=nlist[mut];
  5223.      }
  5224.    }
  5225.    mttab.Shrink();
  5226.    if (!((numtabs==1)&&(submtl!=NULL)))
  5227.    { TSTR oldname=TSTR(_T(" "));
  5228.    nmtl=node->GetMtl();
  5229.      if (nmtl != NULL)
  5230.         oldname=nmtl->GetName();
  5231.      if (_tcscmp(oldname,newname)!=0)
  5232.      { newmat=NewDefaultMultiMtl();
  5233.        newmat->SetName(newname); }
  5234.      else newmat=(MultiMtl*)nmtl;
  5235. //   nmtl->FindMtl(nmtl);
  5236.      newmat->SetNumSubMtls(numsubs);
  5237.      int k=0,nt=0,j;
  5238.      for (int i=0;i<numtabs;i++)
  5239.      {   if ((nt=mttab[i]->NumSubMtls())>0)
  5240.         for (j=0;j<nt;j++)
  5241.        { newmat->SetSubMtl(k,mttab[i]->GetSubMtl(j));
  5242.           k++;
  5243.         }
  5244.         else
  5245.        { newmat->SetSubMtl(k,mttab[i]);
  5246.          k++;
  5247.        }
  5248.      }
  5249.    }
  5250.     mttab.SetCount(0); mttab.Shrink();
  5251.    node->SetMtl(newmat!=NULL?newmat:submtl);  
  5252. }
  5253. void CommonParticle::CntRetrieveMtls(INode *node,int subtree,int *numsubs,int *numtabs,int *tabmax,TimeValue t)
  5254. { int nc,i;
  5255.   Mtl *submtl=node->GetMtl();
  5256.   if (subtree)
  5257.   { if ((nc=node->NumberOfChildren())>0)
  5258.    for (i=0;i<nc;i++)
  5259.      CntRetrieveMtls(node->GetChildNode(i),subtree,numsubs,numtabs,tabmax,t);
  5260.   }
  5261.   if (IsGEOM(node->EvalWorldState(t).obj)!=NULL)
  5262.   { if (submtl!=NULL)
  5263.    { int subs;
  5264.      if ((subs=submtl->NumSubMtls())>0)
  5265.        (*numsubs)+=subs;
  5266.      else (*numsubs)++;
  5267.    }
  5268.    else
  5269.    (*numsubs)++;
  5270.   }
  5271. }
  5272.  
  5273. void CommonParticle::CntDoGroupMtls(INode *node,int subtree,int *numsubs,int *numtabs,int *tabmax,TimeValue t)
  5274. { int nc;
  5275.   if ((nc=node->NumberOfChildren())>0)
  5276.    for (int i=0;i<nc;i++)
  5277.    { INode *nxtnode=node->GetChildNode(i);
  5278.      if (nxtnode->IsGroupHead()) CntDoGroupMtls(nxtnode,subtree,numsubs,numtabs,tabmax,t);
  5279.      else if ((subtree)||(nxtnode->IsGroupMember())) CntRetrieveMtls(nxtnode,subtree,numsubs,numtabs,tabmax,t);
  5280.   }
  5281. }
  5282.  
  5283. void CommonParticle::GetSubs(INode *node,INode *topnode,int subtree,TimeValue t)
  5284. {  Mtl *submtl;
  5285.    int tabmax=256;
  5286.    int numsubs=0,numtabs=0;
  5287.    int mstart=0,mcnt=nlist.Count();INode *onode;
  5288.    onode=custnode;
  5289.    nmtls.SetCount(mcnt);
  5290.     submtl=onode->GetMtl();
  5291.    INode *tmpnode=onode;
  5292.    for (int mut=mstart;mut<=mcnt;mut++)
  5293.    { if (tmpnode->IsGroupHead())
  5294.        CntDoGroupMtls(tmpnode,subtree,&numsubs,&numtabs,&tabmax,t);
  5295.      else
  5296.      CntRetrieveMtls(tmpnode,subtree,&numsubs,&numtabs,&tabmax,t);
  5297.      if (mut!=mcnt)
  5298.      {nmtls[mut]=numsubs;
  5299.       tmpnode=nlist[mut];
  5300.      }
  5301.    }
  5302. }
  5303.  
  5304. void CommonParticle::GetNextBB(INode *node,int subtree,int *count,int *tabmax,Point3 boxcenter,TimeValue t,int tcount,INode *onode)
  5305. {int i,nc;
  5306.    if (subtree)
  5307.   { if ((nc=node->NumberOfChildren())>0)
  5308.    for (i=0;i<nc;i++)
  5309.      GetNextBB(node->GetChildNode(i),subtree,count,tabmax,boxcenter,t,tcount,onode);
  5310.   }
  5311.   Object *cobj=node->EvalWorldState(t).obj;
  5312.   TriObject *triOb=TriIsUseable(cobj,t);
  5313.   if (triOb)
  5314.   {    if (*count>=*tabmax)
  5315.    { theSuprSprayDraw.bboxpt[tcount].bpts.Resize((*tabmax)+=256);}
  5316.     Matrix3 ctm = node->GetObjTMAfterWSM(t);
  5317.    if (node!=custnode)
  5318.   { theSuprSprayDraw.bboxpt[tcount].bpts[*count].Suboffset=Point3(0.0f,0.0f,0.0f)*ctm-boxcenter;
  5319.   }  
  5320.   else theSuprSprayDraw.bboxpt[tcount].bpts[*count].Suboffset=Point3(0.0f,0.0f,0.0f);
  5321.    ctm.NoTrans();
  5322.   Box3 bbox=triOb->GetMesh().getBoundingBox();
  5323.   theSuprSprayDraw.bboxpt[tcount].bpts[*count].pts[0]=Point3(bbox.pmax[0],bbox.pmax[1],bbox.pmax[2])*ctm;
  5324.   theSuprSprayDraw.bboxpt[tcount].bpts[*count].pts[1]=Point3(bbox.pmax[0],bbox.pmax[1],bbox.pmin[2])*ctm;
  5325.   theSuprSprayDraw.bboxpt[tcount].bpts[*count].pts[2]=Point3(bbox.pmax[0],bbox.pmin[1],bbox.pmin[2])*ctm;
  5326.   theSuprSprayDraw.bboxpt[tcount].bpts[*count].pts[3]=Point3(bbox.pmax[0],bbox.pmin[1],bbox.pmax[2])*ctm;
  5327.   theSuprSprayDraw.bboxpt[tcount].bpts[*count].pts[4]=Point3(bbox.pmin[0],bbox.pmax[1],bbox.pmax[2])*ctm;
  5328.   theSuprSprayDraw.bboxpt[tcount].bpts[*count].pts[5]=Point3(bbox.pmin[0],bbox.pmax[1],bbox.pmin[2])*ctm;
  5329.   theSuprSprayDraw.bboxpt[tcount].bpts[*count].pts[6]=Point3(bbox.pmin[0],bbox.pmin[1],bbox.pmin[2])*ctm;
  5330.   theSuprSprayDraw.bboxpt[tcount].bpts[*count].pts[7]=Point3(bbox.pmin[0],bbox.pmin[1],bbox.pmax[2])*ctm;
  5331.   (*count)++;
  5332.   if (triOb!=cobj) triOb->DeleteThis();
  5333.   }
  5334. }
  5335.  
  5336. void CommonParticle::DoGroupBB(INode *node,int subtree,int *count,int *tabmax,Point3 boxcenter,TimeValue t,int tcount,INode *onode)
  5337. { int nc;
  5338.   if ((nc=node->NumberOfChildren())>0)
  5339.    for (int j=0;j<nc;j++)
  5340.    { INode *nxtnode=node->GetChildNode(j);
  5341.      if (nxtnode->IsGroupHead()) DoGroupBB(nxtnode,subtree,count,tabmax,boxcenter,t,tcount,onode);
  5342.      else if ((subtree)||(nxtnode->IsGroupMember())) GetNextBB(nxtnode,subtree,count,tabmax,boxcenter,t,tcount,onode);
  5343.    }
  5344. }
  5345.  
  5346. void CommonParticle::GetallBB(INode *custnode,int subtree,TimeValue t)
  5347. { int tabmax=256;
  5348.   int count=1,ocount=times.tl.Count();
  5349.   if (ocount>0) count=ocount;
  5350.   if (theSuprSprayDraw.bboxpt) delete[] theSuprSprayDraw.bboxpt;
  5351.   theSuprSprayDraw.bboxpt=NULL;
  5352.   INode *tmpnode = NULL;
  5353.   if (custnode!=NULL)
  5354.   { theSuprSprayDraw.bboxpt=new boxlst[count];
  5355.     int cgen;
  5356.     for (int tcount=0;tcount<count;tcount++)
  5357.     { TimeValue tofs=(ocount>0?times.tl[tcount].tl:t);
  5358.      cgen=(times.tl.Count()>0?times.tl[tcount].gennum-1:-1);
  5359.      if ((cgen>-1)&&(cgen<nlist.Count()))
  5360.      { if ((tmpnode=nlist[cgen]) == NULL) tmpnode=custnode;
  5361.      } else tmpnode=custnode;
  5362.      theSuprSprayDraw.bboxpt[tcount].bpts.SetCount(tabmax);
  5363.       theSuprSprayDraw.bboxpt[tcount].numboxes=0;
  5364.       Matrix3 ctm = tmpnode->GetObjTMAfterWSM(tofs);
  5365.       boxcenter=Zero*ctm;
  5366.      if (tmpnode->IsGroupHead())
  5367.        DoGroupBB(tmpnode,subtree,&(theSuprSprayDraw.bboxpt[tcount].numboxes),&tabmax,boxcenter,tofs,tcount,tmpnode);
  5368.      else
  5369.       GetNextBB(tmpnode,subtree,&(theSuprSprayDraw.bboxpt[tcount].numboxes),&tabmax,boxcenter,tofs,tcount,tmpnode);
  5370.      theSuprSprayDraw.bboxpt[tcount].bpts.SetCount(theSuprSprayDraw.bboxpt[tcount].numboxes);
  5371.     theSuprSprayDraw.bboxpt[tcount].bpts.Shrink();
  5372.     }
  5373.   }
  5374. }
  5375.  
  5376. void CommonParticle::CheckTree(INode *node,Matrix3 tspace,Mesh *cmesh,int *numV,int *numF,int *tvnum,int *ismapped,TimeValue t,int subtree,int custmtl)
  5377. { Object *pobj;    
  5378.   TriObject *triOb;
  5379.   Point3 deftex=Point3(0.5f,0.5f,0.0f);
  5380.   TVFace Zerod;
  5381.   Zerod.t[0]=0;Zerod.t[1]=0;Zerod.t[2]=0;
  5382.   int nc,i,j,subv=0,subf=0,subtvnum=0,tface,tvert;
  5383.  
  5384.   if (subtree)
  5385.   { if ((nc=node->NumberOfChildren())>0)
  5386.    for (i=0;i<nc;i++)
  5387.      CheckTree(node->GetChildNode(i),tspace,cmesh,numV,numF,tvnum,ismapped,t,subtree,custmtl);
  5388.   }
  5389.   if ((triOb=TriIsUseable(pobj = node->EvalWorldState(t).obj,t))!=NULL)
  5390.   {   Point3 Suboffset;
  5391.     Matrix3 ctm = node->GetObjTMAfterWSM(t);
  5392. /* if (node!=custnode)
  5393.      Suboffset=Point3(0.0f,0.0f,0.0f)*ctm-boxcenter;
  5394.    else
  5395.       Suboffset=Point3(0.0f,0.0f,0.0f);
  5396.    ctm.NoTrans();*/
  5397.    int submtls=0;
  5398.    Mtl* m=node->GetMtl();
  5399.    if (!((m!=NULL)&&(submtls=m->NumSubMtls()) != 0))
  5400.      submtls=-1;
  5401.    int tottv;
  5402.    subv=triOb->GetMesh().getNumVerts();
  5403.     subf=triOb->GetMesh().getNumFaces();
  5404.     subtvnum=triOb->GetMesh().getNumTVerts();
  5405.     cmesh->setNumFaces(tface=(*numF+subf),(*numF>0