/***************************************************************/ /* */ /* IDCLIENT.PKG */ /* */ /* plugin ItemsDistribution */ /* client */ /* */ /* by Loïc Berthelot, CryoNetworks, fev 2001 */ /* */ /***************************************************************/ /********************************************************************************/ /********************************************************************************/ /** **/ /** D A T A **/ /** **/ /********************************************************************************/ /********************************************************************************/ typeof class = S;; /* item structure */ struct ItemD = [ /* instance */ o_ITMD : Ob, /* 1 if activated, 0 if not */ stateFlag_ITMD : I, /* name of m3d file */ filename_ITMD : S, /* H3d handler */ obj_ITMD : H3d, /* item name in m3d file */ objInitialName_ITMD : S, /* item after modification */ objCurrentName_ITMD : S, /* scale object parameter */ scale_ITMD : I, /* last rotation action */ lastTickcount_ITMD : I, /* delay before next rotation step */ timeRotation_ITMD : I, /* angle of rotation on each step */ angleRotation_ITMD : I, /* current item position */ currentPos_ITMD : [I I I], /* distance from the object to take it */ actionDistance_ITMD : I, /* avatar H3d handler */ avatarRef_ITMD : H3d, /* 1 is avatar is on item position, 0 if not */ avatarItemFlag_ITMD : I ] mkItemD;; /********************************************************************************/ /********************************************************************************/ /** **/ /** B O D Y **/ /** **/ /********************************************************************************/ /********************************************************************************/ /**********************************************/ /* itd_anim [o ItemD] I */ /* */ /* pre-render callback : */ /* - make the item do a rotation step */ /* - check if the avatar takes the item */ /* */ /**********************************************/ fun itd_anim (o, item) = if (item.stateFlag_ITMD) then ( let _tickcount -> newTickcount in /* if the delay before next rotation step is over */ if ((newTickcount - item.lastTickcount_ITMD) > item.timeRotation_ITMD) then ( /* make it rotate */ set item.lastTickcount_ITMD = newTickcount; M3rotateObjExt session item.obj_ITMD [item.angleRotation_ITMD 0 0]; 1; ) else nil; /* avatar position */ let M3getObjVec session M3getFather session (ObGetMain owner) -> [avX avY avZ] in /* item current position */ let item.currentPos_ITMD -> [cX cY cZ] in if ( (avX != nil) && (avY != nil) && (avZ != nil) && ((abs (cX - avX)) < item.actionDistance_ITMD) && ((abs (cY - (avY+140))) < item.actionDistance_ITMD) && ((abs (cZ - avZ)) < item.actionDistance_ITMD) ) then if (item.avatarItemFlag_ITMD) then nil else ( /* avoid event loop */ set item.avatarItemFlag_ITMD = 1; /* ask the server to authorize avatar to pick the item */ UsendMessage ObUi o "indicate" item.objInitialName_ITMD; 1; ) else ( if (item.avatarItemFlag_ITMD) then set item.avatarItemFlag_ITMD = 0 else nil; 0; ); ) else nil; 1;; /**********************************************/ /* itd_hide [UserI S S ItemD] I */ /* */ /* item is taken, make it disappear from */ /* the scene. */ /* */ /**********************************************/ fun itd_hide (ui, action, param, item) = set item.stateFlag_ITMD = 0; M3unLink session item.obj_ITMD; M3delObj session item.obj_ITMD; set item.obj_ITMD = nil; set item.currentPos_ITMD = nil; 1;; /**********************************************/ /* itd_active [UserI S S ItemD] I */ /* */ /* activate the item : make it appear on a */ /* new position, which is included in the */ /* parameter. */ /* */ /**********************************************/ fun itd_active (ui, action, param, item) = if (item.stateFlag_ITMD) then nil else ( set item.stateFlag_ITMD = 1; /* load the M3d ojbect */ M3load session item.filename_ITMD nil; set item.obj_ITMD = M3getObj session item.objInitialName_ITMD; M3recursFillMatObj session item.obj_ITMD; M3renameObj session item.obj_ITMD item.objCurrentName_ITMD; M3link session item.obj_ITMD shell; M3setObjScale session item.obj_ITMD item.scale_ITMD; /* get the new position from the parameter */ let strextr param -> [ [posName _] [ [xStr _] [ [yStr _] [ [zStr _] _]]]] in let atoi xStr -> x in let atoi yStr -> y in let atoi zStr -> z in ( set item.currentPos_ITMD = [x y z]; ); /* move the object on the new position */ M3setObjVec session item.obj_ITMD item.currentPos_ITMD; /* set the pre-render callback */ ObCbAnim item.o_ITMD mkfun2 @itd_anim item; ); 1;; /**********************************************/ /* itd_sendPosList [Ob [Anchor r1]] I */ /* */ /* instance transmits its positions list to */ /* server. positions are contained in anchors */ /* */ /**********************************************/ fun itd_sendPosList (o, anchors) = if (anchors == nil) then ( /* no more position, transmit "nil" */ UsendMessage ObUi o "addPos" nil; 1; ) else ( match (hd anchors) with (objAnchor _ -> nil) | ( posAnchor [posName [x y z] _] -> let (posName::nil)::((itoa x)::nil)::((itoa y)::nil)::((itoa z)::nil)::nil -> pos in /* send position to server */ UsendMessage ObUi o "addPos" (strbuild pos) ); /* process next position */ itd_sendPosList o (tl anchors); );; /**********************************************/ /* itd_addPos [UserI S S ItemD] I */ /* */ /* server asks client to give him the */ /* list of positions of this instance */ /* */ /**********************************************/ fun itd_addPos (ui, action, param, item) = itd_sendPosList item.o_ITMD (ObAnchor item.o_ITMD); 1;; /**********************************************/ /* itd_endDownload [S [I Ob ItemD]] I */ /* */ /* client has downloaded a ressource */ /* */ /**********************************************/ fun itd_endDownload (fln, tuple) = let tuple -> [p item] in if (p == 1) then ( /* item m3d file */ set item.filename_ITMD = fln; 1; ) else ( /* end of download : */ /* make the client register */ UsendMessage (ObUi item.o_ITMD) "register" nil; 1; ); 1;; /**********************************************/ /* newOb [Ob] I */ /* */ /* instance entry */ /* */ /**********************************************/ fun newOb (o) = /* get instance parameters */ let 0 -> stateFlag in let hd UgetParam ObUi o "itemDFilename" -> filename in let hd UgetParam ObUi o "itemDTextureFilename" -> textureFilename in let hd UgetParam ObUi o "itemDObjName" -> objName in let atoi hd UgetParam ObUi o "itemDScale" -> scale in let atoi hd UgetParam ObUi o "itemDTimeRotation" -> timeRotation in let atoi hd UgetParam ObUi o "itemDAngleRotation" -> angleRotation in let atoi hd UgetParam ObUi o "itemDActionDistance" -> actionDistance in /* get the client's avatar handler */ let M3getFather session (ObGetMain owner) -> avatarRef in /* constr. item structure */ let mkItemD [o stateFlag filename nil objName (strcat objName "_ItemsDistribution") scale 0 timeRotation angleRotation nil actionDistance avatarRef 0] -> newItem in ( UcbMessage ObUi o ["active" mkfun4 @itd_active newItem]:: ["addPos" mkfun4 @itd_addPos newItem]:: ["hide" mkfun4 @itd_hide newItem]::nil; /* download ressources : m3d file and texture */ _RSCdownloadP this filename filename (mknode @itd_endDownload [1 newItem]) nil 1; _RSCdownloadP this textureFilename textureFilename (mknode @itd_endDownload [2 newItem]) nil 2; 1; );; /**********************************************/ /* */ /* INITIALISATION */ /* */ /**********************************************/ fun IniPlug(file) = srand time; set class=getInfo strextr _getpack _checkpack file "name"; PlugRegister class @newOb nil; 0;;