/* name : dynparticles - part SERVER date : february 2007 auteur : iri pour I-Maginer (http://www.i-maginer.fr) */ typeof class = S;; struct PART = [ // couleur initcolor : S, // couleur initiale colorcycle : S, // un cycle de couleurs doit-il être activé ("1") ou non ("0") // taille sizemax : S, // taille maximale des particules sizecycle : S, // un cycle de tailles doit-il être activé ("1") ou non ("0") sizetime : S, // valeur de la taille d'une particule en fonction de son âge (format linebuild) // expert life : S, // durée de vie d'une particule maskEmitter : S,// inusité volume : S, // volume utilisé ("VOLUME_SPHERE", "VOLUME_CONE", ...) volA : S, // vecteur A du volume (format linebuild) volB : S, // vecteur B du volume (format linebuild) effect : S, // effet utilisé ("EFFECT_CONSTANT", "EFFECT_ELECTRIC", ...) effectA : S, // vecteur A de l'effet (format linebuild) effectB :S, // vecteur A de l'effet (format linebuild) effectC : S, // vecteur A de l'effet (format linebuild) target : S, // PCL_BILLBOARD randcolor : S, // PCL_RAINBOW mass : S, // masse des particules framerate : S, // nb de particules émises par unité de temps png : S, // path de la texture à utiliser ftrans : S, // transparence de la texture (impact réel ou pas ??) fm3d : S, // fichier supprt m3d fname : S, // nom du mesh décrit par le m3d fAv : S, // le système de particules est lié à l'avatar client ("1") ou non fAvPos : S // si lié à l'avatar client, position par rapport à celui-ci (format linebuild) ] mkPART;; typeof part = PART;; typeof clis = [[CLIENT I] r1];; typeof initON = I;; var cliALL = 0;; // si vaut 1 tous les clients enregistrés auront les modifications en live sinon seul le client admin les verra var editSave = 0;; // si vaut 1, toutes les modifs sont sauvegardés en tant réel sur le *.dms sinon elles sont perdues à la fermeture du serveur /* ************************** FONCTIONS DIVERSES *************************** */ /* supprime un client de la liste l -> [[CLIENT I] r1] : clis cli -> CLIENT : client à supprimer <- [[CLIENT I] r1] : liste à jour */ fun remove_from_clis(l, cli)= if l == nil then l else let hd l -> [c _] in if cli == c then tl l else (hd l) :: remove_from_clis tl l cli;; // Retourne l'état d'un client fun getStateByCli(l, cli)= if l == nil then 0 else let hd l -> [c state] in if cli == c then state else getStateByCli tl l cli;; // Change l'état d'un client fun chgState(l, cli, value)= if l == nil then nil else let hd l -> [c _] in if cli == c then [cli value] :: (tl l) else (hd l) :: chgState tl l cli value;; // Prépare les données à envoyer à un client fun prepareDatas()= strbuild ( "initcolor" :: part.initcolor :: nil ) :: ( "colorcycle" :: part.colorcycle :: nil ) :: ( "sizemax" :: part.sizemax :: nil ) :: ( "sizecycle" :: part.sizecycle :: nil ) :: ( "sizetime" :: part.sizetime :: nil ) :: ( "life" :: part.life :: nil ) :: ( "maskEmitter" :: part.maskEmitter :: nil ) :: ( "volume" :: part.volume :: nil ) :: ( "volA" :: part.volA :: nil ) :: ( "volB" :: part.volB :: nil ) :: ( "effect" :: part.effect :: nil ) :: ( "effectA" :: part.effectA :: nil ) :: ( "effectB" :: part.effectB :: nil ) :: ( "effectC" :: part.effectC :: nil ) :: ( "target" :: part.target :: nil ) :: ( "randcolor" :: part.randcolor :: nil ) :: ( "target" :: part.target :: nil ) :: ( "mass" :: part.mass :: nil ) :: ( "framerate" :: part.framerate :: nil ) :: ( "ftrans" :: part.ftrans :: nil ) :: ( "m3d" :: part.fm3d :: nil ) :: ( "png" :: part.png :: nil ) :: ( "fm3dname" :: part.fname :: nil ) :: ( "m3d_fAv" :: part.fAv :: nil ) :: ( "m3d_fAvPos" :: part.fAvPos :: nil ) :: nil;; /* ***************************** FONCTIONS DE SAUVEGARDE SUR LE DMS ****************************** */ /* Récupération de toutes les infos du bloc ' dat ' du C3D3 dans lequel dynparticles est intégré En effet, si l'admin client décide de sauvegarder les modifications du plugin, il est nécessaire de ne pas perdre les autres informations existantes de ce bloc ! dmi -> DMI : nom du module (ici le C3D3) bloc -> S : nom du bloc (dat, dmi, link, ...) <- [[S r1] r1] : contenu du bloc */ fun getDmsC3D3(dmi, bloc)= _DMSgetDef dmi bloc;; /* Construit un nouveau bloc de définition en lui intégrant les données mises à jour de l'instance bloc -> [[S r1] r1] : ancien bloc inst -> S : nom de l'instance newvalue -> S : nouvelle définition de l'instance <- [[S r1] r1] : bloc mis à jour */ fun updtDmsBloc(bloc, inst, newvalue)= if bloc == nil then nil else let hd hd bloc -> key in // on arrive à une définition d'instance if !strcmp key "instance" then // c'est la bonne instance (son nom correspond) if !strcmp hd tl hd bloc inst then // on remplace par la nouvelle configuration (key :: inst :: class :: "test" :: newvalue :: nil) :: updtDmsBloc tl bloc inst newvalue else (hd bloc) :: updtDmsBloc tl bloc inst newvalue else (hd bloc) :: updtDmsBloc tl bloc inst newvalue;; /* Sauvegarde les données sur le *.dms o -> Ob <- I */ fun saveChgDms(o)= // récupération des données actuelles contenues dans le bloc ' dat ' du c3d3 let getDmsC3D3 this "dat" -> bloc in // construction de la chaine remplaçant l'ancienne let strbuild ( "init" :: ( if initON then "on" else "off" ) :: nil) :: ( "initColor" :: part.initcolor :: nil ) :: ( "initSizes" :: (lineextr part.sizetime) ) :: ( "maxSize" :: part.sizemax :: nil ) :: ( "colorCycle" :: part.colorcycle :: nil ) :: ( "sizeCycle" :: part.sizecycle :: nil ) :: ( "typeFX" :: part.effect :: nil ) :: ( "typeVolEmitter" :: part.volume :: nil ) :: ( "life" :: part.life :: nil ) :: ( "typeParticle" :: part.target :: part.randcolor :: nil ) :: ( "vectorA" :: (lineextr part.volA) ) :: ( "vectorB" :: (lineextr part.volB) ) :: ( "vectorFxA" :: (lineextr part.effectA) ) :: ( "vectorFxB" :: (lineextr part.effectB) ) :: ( "vectorFxC" :: (lineextr part.effectC) ) :: ( "mass" :: part.mass :: nil ) :: ( "framerate" :: part.framerate :: nil ) :: ( "target" :: part.target :: nil ) :: ( "randcolor" :: part.randcolor :: nil ) :: ( "png" :: part.png :: nil ) :: ( "ftrans" :: part.ftrans :: nil ) :: ( "fm3d" :: part.fm3d :: nil ) :: ( "fm3dname" :: part.fname :: nil ) :: ( "m3d_fAv" :: part.fAv :: nil ) :: ( "m3d_fAvPos" :: (lineextr part.fAvPos) ) :: nil -> newbloc in // reconstruit le bloc ' dat ' avec la nouvelle chaine let updtDmsBloc bloc ObName o newbloc -> newdat in // redéfinit le bloc de définition ' dat ' avec le nouveau bloc _DMSupdateDef this "dat" newdat; // sauvegarde sur le fichier *.dms _DEFsave;; /* ***************************** FONCTIONS DE COMMUNICATION AVEC/DEPUIS LES CLIENTS ****************************** */ /* Envoi un message vers les clients enregistrés auprès du serveur l -> [[CLIENT I] r1] : clis : liste des clients enregistrés ui -> UserI action -> S : Nom de l'action à envoyer param -> S : paramètre à envoyer <- I */ fun _broadMsg(l, ui, action, param)= if l == nil then 0 else let hd l -> [cli _] in ( UsendMessage ui cli action param; _broadMsg tl l ui action param );; /* Envoi un message vers un client pour lancer un système de particules ui -> UserI cli -> CLIENT action -> S : nom de l'action a envoyé param -> S : paramètre de cette action <- i */ fun _sendMsgC(cli, ui, action, param)= _broadMsg [cli nil]::nil ui action param;; /* Communications intramodules (cli/srv) Réception des messages provenant des clients ui -> UserI cli -> CLIENT action -> S param -> S p -> [Ob] <- I */ fun cbComm(ui, cli, action, param, o)= // Générales if !strcmp action "register" then ( set clis = [cli 1] :: clis; UsendMessage ui cli "registered" nil; if initON == 1 then UsendMessage ui cli "start" prepareDatas else 0; 0 ) else if !strcmp action "unregister" then ( set clis = remove_from_clis clis cli; UsendMessage ui cli "unregistered" nil; UsendMessage ui cli "stop" nil; 0 ) else if !strcmp action "start" then _broadMsg clis ui "start" prepareDatas else if !strcmp action "started" then ( set clis = chgState clis cli 1; 0 ) // Edition en ligne du client admin : les noms des actions sont suffisamment explicites :) else if !strcmp action "size_newSizeMax" then ( set part.sizemax = param; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "color_cycleColor" then ( set part.colorcycle = param; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "color_chgAlpha" then ( let htoi part.initcolor -> col in let get_rgba col -> [r g b _] in let make_rgba r g b atoi param -> col in set part.initcolor = itoh col; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "color_chgColor" then ( let htoi part.initcolor -> col in let get_rgba col -> [_ _ _ a] in let htoi substr param 0 2 -> r in let htoi substr param 2 2 -> g in let htoi substr param 4 2 -> b in let make_rgba r g b a -> col in set part.initcolor = itoh col; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_infinit" then ( set part.life = param; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_volSphreRadius" then ( let lineextr part.volA -> [a [b [c _]]] in set part.volA = linebuild param :: b :: c :: nil; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_volCone" then ( let lineextr param -> [n [value _]] in let atoi n -> n in let lineextr part.volA -> [a [b [c _]]] in if n then set part.volA = linebuild value :: b :: c :: nil else if n == 2 then set part.volA = linebuild a :: value :: c :: nil else if n == 3 then set part.volA = linebuild a :: b :: value :: nil else nil; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_volPlan" then ( let lineextr param -> [n [value _]] in let atoi n -> n in let lineextr part.volA -> [a [b [c _]]] in if n then set part.volA = linebuild value :: b :: c :: nil else if n == 2 then set part.volA = linebuild a :: value :: c :: nil else nil; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_volLine" then ( let lineextr part.volA -> [a [b [c _]]] in set part.volA = linebuild param :: b :: c :: nil; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_effectNone" then ( set part.effect = nil; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_effectConstant" then ( set part.effect = "EFFECT_CONSTANT"; set part.effectA = param; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_effectElectric" then ( set part.effect = "EFFECT_ELECTRIC"; let lineextr param -> [ax [ay [az [bx _]]]] in ( set part.effectA = linebuild ax :: ay :: az :: nil; set part.effectB = linebuild bx :: "0" :: "0" :: nil; ); if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_effectMagnetic" then ( set part.effect = "EFFECT_MAGNETIC"; let lineextr param -> [ax [ay [az [bx _]]]] in ( set part.effectA = linebuild ax :: ay :: az :: nil; set part.effectB = linebuild bx :: "0" :: "0" :: nil; ); if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_effectChotic0" then ( set part.effect = "EFFECT_CHAOTIC0"; let lineextr param -> [ax [ay [az [bx [by [bz _]]]]]] in ( set part.effectA = linebuild ax :: ay :: az :: nil; set part.effectB = linebuild bx :: by :: bz :: nil; ); if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_effectChotic1" then ( set part.effect = "EFFECT_CHAOTIC1"; let lineextr param -> [ax [ay [az [bx [by [bz _]]]]]] in ( set part.effectA = linebuild ax :: ay :: az :: nil; set part.effectB = linebuild bx :: by :: bz :: nil; ); if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_effectHelicoid" then ( set part.effect = "EFFECT_HELICOID"; let lineextr param -> [ax [ay [az [bx [by [bz _]]]]]] in ( set part.effectA = linebuild ax :: ay :: az :: nil; set part.effectB = linebuild bx :: by :: bz :: nil; ); if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_effectPlancoll" then ( set part.effect = "EFFECT_PLANCOLL"; let lineextr param -> [ax [ay [az [bx [by [bz _]]]]]] in ( set part.effectA = linebuild ax :: ay :: az :: nil; set part.effectB = linebuild bx :: by :: bz :: nil; ); if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_allClients" then ( set cliALL = atoi param ) else if !strcmp action "expert_upload" then ( set editSave = atoi param ) else if !strcmp action "plugin_stop" then ( _broadMsg clis ui "stop" nil ) else if !strcmp action "expert_billboard" then ( set part.target = param; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_rainbow" then ( set part.randcolor = param; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_masse" then ( set part.mass = param; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "size_newSize" then ( set part.sizetime = param; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "expert_rate" then ( set part.framerate = param; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "m3d_texnew" then let lineextr param -> [tex [trans _]] in ( set part.ftrans = trans; _RSunregister this part.png; set part.png = tex; _RSregister this part.png RScontrol+RSfile part.png; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "m3d_m3dnew" then ( set part.fm3d = param; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "m3d_fAv" then ( set part.fAv = param; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) else if !strcmp action "m3d_fAvPos" then ( let lineextr param -> [n [value _]] in let lineextr part.fAvPos -> [oldx [oldy [oldz _]]] in let atoi n -> n in if n == 1 then set part.fAvPos = linebuild value :: oldy :: oldz :: nil else if n == 2 then set part.fAvPos = linebuild oldx :: value :: oldz :: nil else if n == 3 then set part.fAvPos = linebuild oldx :: oldy :: value :: nil else nil; if cliALL then _broadMsg clis ui "start" prepareDatas else _sendMsgC cli ui "start" prepareDatas; if editSave then saveChgDms o else 0 ) // Autres cas else 0;; /* ***************************** FONCTIONS STANDARD DU PLUGIN ****************************** */ /* Un client se déconnecte : il est supprimé de la liste ' clis ' o -> Ob cli -> CLIENT : client déconnecté <- I */ fun out(o, cli)= set clis = remove_from_clis clis cli; 0;; fun newOb(o)= let hd UgetParam ObUi o "init" -> tmp in set initON = if !strcmp tmp "on" then 1 else 0; let hd UgetParam ObUi o "initColor" -> p1 in let linebuild UgetParam ObUi o "initSizes" -> p2 in let hd UgetParam ObUi o "colorCycle" -> p3 in let hd UgetParam ObUi o "sizeCycle" -> p4 in let hd UgetParam ObUi o "maxSize" -> p5 in let hd UgetParam ObUi o "typeFX" -> p6 in let hd UgetParam ObUi o "typeVolEmitter" -> p7 in let hd UgetParam ObUi o "typeMaskEmitter" -> p8 in let hd UgetParam ObUi o "target" -> p9 in let hd UgetParam ObUi o "rainbow" -> p18 in let linebuild UgetParam ObUi o "vectorA" -> p10 in let linebuild UgetParam ObUi o "vectorB" -> p11 in let hd UgetParam ObUi o "life" -> p13 in let hd UgetParam ObUi o "mass" -> p14 in let hd UgetParam ObUi o "framerate" -> p15 in let linebuild UgetParam ObUi o "vectorFxA" -> p12 in let linebuild UgetParam ObUi o "vectorFxB" -> p16 in let linebuild UgetParam ObUi o "vectorFxC" -> p17 in let hd UgetParam ObUi o "png" -> p19 in let hd UgetParam ObUi o "ftrans" -> p20 in let hd UgetParam ObUi o "fm3d" -> p21 in let hd UgetParam ObUi o "fm3dname" -> p22 in let hd UgetParam ObUi o "m3d_fAv" -> p23 in let hd UgetParam ObUi o "m3d_fAvPos" -> p24 in set part = mkPART[ p1 p3 p5 p4 p2 p13 p8 p7 p10 p11 p6 p12 p16 p17 p9 p18 p14 p15 p19 // if p19 == nil then strcat PLUGpath thisplug "flare.png" else p19 if p20 == nil then "128.0" else p20 if p21 == nil then strcat PLUGpath thisplug "particles.m3d" else p21 if p22 == nil then "Topo_Particle" else p22 if p23 == nil then "0" else p23 if p24 == nil then linebuild "0"::"100"::"0"::nil else p24 ]; UcbComm this ObUi o mkfun5 @cbComm o; OB_CBclientDestroyed o @out; 0;; fun IniPlug(file)= set class = getInfo strextr _getpack _checkpack file "name"; PlugRegister class @newOb nil; 0 ;;