/* Location based fog system by Obsttorte (08.05.2013) oc=old_color od=old_density ... The fading between the settings of two neighboured locations is linear The density is the reziprok of the shaderParm3 value multiplied with houndret. The shaderParm3 value determines, at which distance in doom units the fog becomes completely opaque to the player, this distance I call opacity border Examples: fog_density | opacity border ############################ 1 | 100 0.1 | 1000 0.02 | 5000 ############################ Usage: Place a info_locationsettings entity in the map. If you already have one for the zone sstem, create a NEW one. Add the spawnarg "scriptobject" "fog_system" on it. By adding the spawnargs "update_period" and "fog_fade_time" on it you can control how smooth the fog fades and how long it takes to fade. To control the fog zone-wise, add the following spawnargs on the info_location entities belonging to the respective zones: ############## fog_color - determines the color of the fog fog_density - determines the density of the fog, a value of 0 turns the fog off */ object fog_system { float m_updatePeriod; string m_nameOfOldZone; float m_fadeTime; entity m_fog; void init(); void fogUpdateLoop(); void fadeFog(vector oc,float od,vector nc,float nd); void fadeOutFog(vector oc,float od); void fadeInFog(vector nc,float nd); void createFog(); }; void fog_system::init() { m_updatePeriod=getFloatKey("update_period"); if (!m_updatePeriod) m_updatePeriod=0.1; m_fadeTime=getFloatKey("fog_fade_time"); if (!m_fadeTime) m_fadeTime=5; /* m_fog=sys.spawn("light"); m_fog.setLightParms(0,0,0,100000); m_fog.Off(); m_fog.setLightOrigin($ambient_world.getLightOrigin()); */ vector lr; lr=$ambient_world.getVectorKey("light_radius"); //m_fog.setRadiusXYZ(lr_x,lr_y,lr_z); //m_fog.setShader("fogs/delta1_fog"); fogUpdateLoop(); } void fog_system::createFog() { m_fog=sys.spawn("light"); m_fog.setLightParms(0,0,0,100000); m_fog.Off(); m_fog.setLightOrigin($ambient_world.getLightOrigin()); vector lr; lr=$ambient_world.getVectorKey("light_radius"); m_fog.setRadiusXYZ(lr_x,lr_y,lr_z); m_fog.setShader("fogs/delta1_fog"); } void fog_system::fogUpdateLoop() { vector oldColor; vector newColor; float oldDensity; float newDensity; oldDensity=0; while(1) { entity locEnt; locEnt=$player1.getLocation(); //invalid location if (locEnt==$null_entity) { wait(m_updatePeriod); continue; } //no zone change if (locEnt.getName()==m_nameOfOldZone) { wait(m_updatePeriod); continue; } //the zone is valid and it's a new one oldColor=m_fog.getColor(); oldDensity=m_fog.getShaderParm(3); //fog_color not set, keep old color if (!sys.strLength(locEnt.getKey("fog_color"))) { newColor=oldColor; } else { newColor=locEnt.getVectorKey("fog_color"); } //fog_density not set, keep old density if (!sys.strLength(locEnt.getKey("fog_density"))) { newDensity=oldDensity; } else { newDensity=locEnt.getFloatKey("fog_density"); } //from nofog zone to nofog sone, do nothing if (!newDensity && !oldDensity) { wait(m_updatePeriod); continue; } //from fog zone to nofog zone, fade out else if (!newDensity) { fadeOutFog(oldColor,oldDensity); } //from nofog zone to fog zone, fade in else if (!oldDensity) { //transform density into shaderParm3 value newDensity=100/newDensity; fadeInFog(newColor,newDensity); } //from fog zone to fog zone, fade else { //transform density into shaderParm3 value newDensity=100/newDensity; fadeFog(oldColor,oldDensity,newColor,newDensity); } oldColor=newColor; oldDensity=newDensity; m_nameOfOldZone=locEnt.getName(); wait(m_updatePeriod); } } //fades from old fog to new one void fog_system::fadeFog(vector oc,float od,vector nc,float nd) { float t=0; float id; vector ic; while (t<=m_fadeTime) { ic_x=nc_x*t/m_fadeTime+oc_x*(1-t/m_fadeTime); ic_y=nc_y*t/m_fadeTime+oc_y*(1-t/m_fadeTime); ic_z=nc_z*t/m_fadeTime+oc_z*(1-t/m_fadeTime); id=nd*t/m_fadeTime+od*(1-t/m_fadeTime); m_fog.setLightParms(ic_x,ic_y,ic_z,id); wait(m_updatePeriod); t+=m_updatePeriod; } m_fog.setLightParms(nc_x,nc_y,nc_z,nd); } //fades the fog out and disables it void fog_system::fadeOutFog(vector oc,float od) { float t=0; float id; float nd=100000; while (t<=m_fadeTime) { id=nd*t/m_fadeTime+od*(1-t/m_fadeTime); m_fog.setLightParms(oc_x,oc_y,oc_z,id); wait(m_updatePeriod); t+=m_updatePeriod; } m_fog.remove(); } //enables the fog and fades it in void fog_system::fadeInFog(vector nc,float nd) { float t=0; float id; float od=100000; createFog(); m_fog.On(); while (t<=m_fadeTime) { id=nd*t/m_fadeTime+od*(1-t/m_fadeTime);; m_fog.setLightParms(nc_x,nc_y,nc_z,id); wait(m_updatePeriod); t+=m_updatePeriod; } m_fog.setLightParms(nc_x,nc_y,nc_z,nd); }