| 05-16-2009, 05:40 PM | #1 |
AmbienceTester creates a multiboard per player enabling control over several ambience aspects of your map. This script is mainly supposed to be a testing and debugging tool to figure out the perfect mix of sky model, weather effect, fog and water color for your terrain without having to save and test your map hundreds of time. In a nutshell it's a tool for perfectionist terrainers. The implementation is pretty easy. Copy the script to your map and some time after (!) the map initialisation use call EnableAmbienceTester(<player p>, <boolean show>). A multiboard is shown to the given player who is then able to change the ambience aspects via arrow keys. All aspects are changed locally EXCEPT for the weather for various reasons so each player can have his own ambience setting. If you're planning on keeping this script in the release version of your map make sure that your desired ambience settings are stored in the script's constants. The attached demo map shows the script in action. JASS:library AmbienceTester initializer Init requires ArrowKeys //**************************************************************** // AmbienceTester by Opossum // AmbienceTester is a script that adds a controlable multiboard // to your map that enables altering many aspects of the map's // ambience like sky, weather or fog in real-time. Activate the // multiboard using // call EnableAmbienceTester(<player>, <boolean show>) // Note that this does NOT work on map initialization. // The multiboard's values can be altered by using arrow keys // but only if the multiboard is shown. //**************************************************************** globals //**************************************************************** // Constants and Default Values: private constant integer DEFAULT_SKY = 5 private constant integer DEFAULT_WEATHER = 0 private constant integer DEFAULT_FOG_STYLE = 0 private constant real DEFAULT_FOG_ZSTART = 0 private constant real DEFAULT_FOG_ZEND = 10000 private constant real DEFAULT_FOG_DENSITY = 0 private constant real DEFAULT_FOG_RED = 0 private constant real DEFAULT_FOG_GREEN = 0 private constant real DEFAULT_FOG_BLUE = 0 private constant integer DEFAULT_WATER_RED = 255 private constant integer DEFAULT_WATER_GREEN = 255 private constant integer DEFAULT_WATER_BLUE = 255 private constant integer DEFAULT_WATER_ALPHA = 255 private constant integer DEFAULT_ROW = 1 private constant integer MAX_SKY = 15 private constant integer MAX_WEATHER = 21 private constant real REPETITION_SPEED = 0.05 private constant real TIME_TO_REPETITION = 0.5 // //**************************************************************** //**************************************************************** // Don't change anything below: // --Player arrays private integer array Sky private integer Weather = DEFAULT_WEATHER private integer array FogStyle private real array FogZStart private real array FogZEnd private real array FogDensity private real array FogRed private real array FogGreen private real array FogBlue private integer array WaterRed private integer array WaterGreen private integer array WaterBlue private integer array WaterAlpha private weathereffect WeatherEffect = null private integer array ActiveRow private integer array PressedKey private real array TimeSincePressed private multiboard array ControlPanel private boolean array CPDisplayed // -- Other arrays private string array SkyPath private string array SkyName private integer array WeatherId private string array WeatherName private multiboarditem array CPItem [12][64] private integer array C [4][16] private timer Pressed = CreateTimer() // //**************************************************************** endglobals //**************************************************************** // Public Function: function EnableAmbienceTester takes player p, boolean show returns nothing set CPDisplayed[GetPlayerId(p)] = show if GetLocalPlayer() == p then call MultiboardDisplay(ControlPanel[GetPlayerId(p)], show) endif endfunction // //**************************************************************** //**************************************************************** // Misc functions: private function CappedReal takes real r, real lowBound, real highBound returns real if r > highBound then return lowBound elseif r < lowBound then return highBound endif return r endfunction private function CappedInt takes integer i, integer lowBound, integer highBound returns integer if i > highBound then return lowBound elseif i < lowBound then return highBound endif return i endfunction // //**************************************************************** //**************************************************************** // Keyboard Actions: private function UpdateValue takes integer whichKey, integer p returns nothing local integer i local string s if not CPDisplayed[p] then return endif if whichKey == 2 or whichKey == 3 then set i = 1 else set i = -1 endif if whichKey == 3 or whichKey == 4 then call MultiboardSetItemStyle(CPItem[p][C[1][ActiveRow[p]]], false, false) call MultiboardSetItemStyle(CPItem[p][C[3][ActiveRow[p]]], false, false) set ActiveRow[p] = CappedInt(ActiveRow[p] + i, 1, C.height-1) if ActiveRow[p] == 3 or ActiveRow[p] == 11 then set ActiveRow[p] = ActiveRow[p] + i endif call MultiboardSetItemStyle(CPItem[p][C[1][ActiveRow[p]]], true, false) call MultiboardSetItemStyle(CPItem[p][C[3][ActiveRow[p]]], true, false) endif if whichKey == 1 or whichKey == 2 then if ActiveRow[p] == 1 then set Sky[p] = CappedInt(Sky[p]+i, 0, MAX_SKY-1) if GetLocalPlayer() == Player(p) then call SetSkyModel(SkyPath[Sky[p]]) endif set s = SkyName[Sky[p]] elseif ActiveRow[p] == 2 then if Weather != 0 then call RemoveWeatherEffect(WeatherEffect) endif set Weather = CappedInt(Weather+i, 0, MAX_WEATHER-1) if Weather != 0 then set WeatherEffect = AddWeatherEffect(GetWorldBounds(), WeatherId[Weather]) call EnableWeatherEffect(WeatherEffect, true) endif set s = WeatherName[Weather] set i = 0 loop exitwhen i == bj_MAX_PLAYERS call MultiboardSetItemValue(CPItem[i][C[2][2]], s) set i = i+1 endloop return elseif ActiveRow[p] == 4 then set FogStyle[p] = CappedInt(FogStyle[p]+i, 0, 2) set s = I2S(FogStyle[p]) elseif ActiveRow[p] == 5 then set FogZStart[p] = FogZStart[p]+50*i set s = R2SW(FogZStart[p], 0, 0) elseif ActiveRow[p] == 6 then set FogZEnd[p] = FogZEnd[p]+50*i set s = R2SW(FogZEnd[p], 0, 0) elseif ActiveRow[p] == 7 then set FogDensity[p] = CappedReal(FogDensity[p]+0.01*i, 0, 1) set s = R2SW(FogDensity[p]*100, 0, 0)+"%" elseif ActiveRow[p] == 8 then set FogRed[p] = CappedReal(FogRed[p]+0.01*i, 0, 1) set s = R2SW(FogRed[p]*100, 0, 0)+"%" elseif ActiveRow[p] == 9 then set FogGreen[p] = CappedReal(FogGreen[p]+0.01*i, 0, 1) set s = R2SW(FogGreen[p]*100, 0, 0)+"%" elseif ActiveRow[p] == 10 then set FogBlue[p] = CappedReal(FogBlue[p]+0.01*i, 0, 1) set s = R2SW(FogBlue[p]*100, 0, 0)+"%" elseif ActiveRow[p] == 12 then set WaterRed[p] = CappedInt(WaterRed[p]+i, 0, 255) set s = I2S(WaterRed[p]) elseif ActiveRow[p] == 13 then set WaterGreen[p] = CappedInt(WaterGreen[p]+i, 0, 255) set s = I2S(WaterGreen[p]) elseif ActiveRow[p] == 14 then set WaterBlue[p] = CappedInt(WaterBlue[p]+i, 0, 255) set s = I2S(WaterBlue[p]) elseif ActiveRow[p] == 15 then set WaterAlpha[p] = CappedInt(WaterAlpha[p]+i, 0, 255) set s = I2S(WaterAlpha[p]) endif if GetLocalPlayer() == Player(p) then call SetTerrainFogEx(FogStyle[p], FogZStart[p], FogZEnd[p], FogDensity[p], FogRed[p], FogGreen[p], FogBlue[p]) call SetWaterBaseColor(WaterRed[p], WaterGreen[p], WaterBlue[p], WaterAlpha[p]) endif call MultiboardSetItemValue(CPItem[p][C[2][ActiveRow[p]]], s) endif endfunction private function KeyRepetition takes nothing returns nothing local integer i = 0 loop exitwhen i == bj_MAX_PLAYERS if PressedKey[i] != 0 then if TimeSincePressed[i] < TIME_TO_REPETITION then set TimeSincePressed[i] = TimeSincePressed[i] + REPETITION_SPEED else call UpdateValue(PressedKey[i], i) endif endif set i = i+1 endloop endfunction private function Keys takes player whichPlayer, integer whichKey, boolean pressed returns nothing local integer p = GetPlayerId(whichPlayer) local integer i if pressed then set PressedKey[p] = whichKey set TimeSincePressed[p] = 0 call UpdateValue(PressedKey[p], p) else set PressedKey[p] = 0 endif endfunction // //**************************************************************** //**************************************************************** // Multiboard Setup: private function SetupCP takes nothing returns nothing local integer i = 0 local integer h local integer w loop exitwhen i == bj_MAX_PLAYERS set ControlPanel[i] = CreateMultiboard() call MultiboardSetItemsStyle(ControlPanel[i], true, false) call MultiboardSetRowCount(ControlPanel[i], C.height) call MultiboardSetColumnCount(ControlPanel[i], C.width) call MultiboardSetTitleText(ControlPanel[i], "AtmoUtils") set h = 0 loop exitwhen h == C.height set w = 0 loop exitwhen w == C.width set CPItem[i][C[w][h]] = MultiboardGetItem(ControlPanel[i], h, w) set w = w+1 endloop // Width call MultiboardSetItemWidth(CPItem[i][C[0][h]], 0.05) call MultiboardSetItemWidth(CPItem[i][C[1][h]], 0.02) call MultiboardSetItemWidth(CPItem[i][C[2][h]], 0.15) call MultiboardSetItemWidth(CPItem[i][C[3][h]], 0.02) // Column 1 call MultiboardSetItemValue(CPItem[i][C[1][h]], "<=") call MultiboardSetItemStyle(CPItem[i][C[1][h]], false, false) // Column 3 call MultiboardSetItemValue(CPItem[i][C[3][h]], "=>") call MultiboardSetItemStyle(CPItem[i][C[3][h]], false, false) set h = h+1 endloop // Grey rows call MultiboardSetItemValueColor(CPItem[i][C[0][0]], 100, 100, 100, 255) call MultiboardSetItemValueColor(CPItem[i][C[0][3]], 100, 100, 100, 255) call MultiboardSetItemValueColor(CPItem[i][C[0][11]], 100, 100, 100, 255) // Column 0 call MultiboardSetItemValue(CPItem[i][C[0][0]], "Aerial") call MultiboardSetItemValue(CPItem[i][C[0][1]], "Sky") call MultiboardSetItemValue(CPItem[i][C[0][2]], "Weather") call MultiboardSetItemValue(CPItem[i][C[0][3]], "Fog") call MultiboardSetItemValue(CPItem[i][C[0][4]], "Style") call MultiboardSetItemValue(CPItem[i][C[0][5]], "Z Start") call MultiboardSetItemValue(CPItem[i][C[0][6]], "Z End") call MultiboardSetItemValue(CPItem[i][C[0][7]], "Density") call MultiboardSetItemValue(CPItem[i][C[0][8]], "Red") call MultiboardSetItemValue(CPItem[i][C[0][9]], "Green") call MultiboardSetItemValue(CPItem[i][C[0][10]], "Blue") call MultiboardSetItemValue(CPItem[i][C[0][11]], "Water") call MultiboardSetItemValue(CPItem[i][C[0][12]], "Red") call MultiboardSetItemValue(CPItem[i][C[0][13]], "Green") call MultiboardSetItemValue(CPItem[i][C[0][14]], "Blue") call MultiboardSetItemValue(CPItem[i][C[0][15]], "Alpha") // Column 2 call MultiboardSetItemValue(CPItem[i][C[2][1]], SkyName[DEFAULT_SKY]) call MultiboardSetItemValue(CPItem[i][C[2][2]], WeatherName[DEFAULT_WEATHER]) call MultiboardSetItemValue(CPItem[i][C[2][4]], I2S(DEFAULT_FOG_STYLE)) call MultiboardSetItemValue(CPItem[i][C[2][5]], R2SW(DEFAULT_FOG_ZSTART, 0, 0)) call MultiboardSetItemValue(CPItem[i][C[2][6]], R2SW(DEFAULT_FOG_ZEND, 0, 0)) call MultiboardSetItemValue(CPItem[i][C[2][7]], R2SW(DEFAULT_FOG_DENSITY*100, 0, 0)+"%") call MultiboardSetItemValue(CPItem[i][C[2][8]], R2SW(DEFAULT_FOG_RED*100, 0, 0)+"%") call MultiboardSetItemValue(CPItem[i][C[2][9]], R2SW(DEFAULT_FOG_GREEN*100, 0, 0)+"%") call MultiboardSetItemValue(CPItem[i][C[2][10]], R2SW(DEFAULT_FOG_BLUE*100, 0, 0)+"%") call MultiboardSetItemValue(CPItem[i][C[2][12]], I2S(DEFAULT_WATER_RED)) call MultiboardSetItemValue(CPItem[i][C[2][13]], I2S(DEFAULT_WATER_GREEN)) call MultiboardSetItemValue(CPItem[i][C[2][14]], I2S(DEFAULT_WATER_BLUE)) call MultiboardSetItemValue(CPItem[i][C[2][15]], I2S(DEFAULT_WATER_ALPHA)) // Cursors call MultiboardSetItemStyle(CPItem[i][C[1][DEFAULT_ROW]], true, false) call MultiboardSetItemStyle(CPItem[i][C[3][DEFAULT_ROW]], true, false) set i = i+1 endloop endfunction // //**************************************************************** //**************************************************************** // Init private function Init takes nothing returns nothing local trigger trig = CreateTrigger() local integer i = 0 local integer h = 0 local integer w set SkyPath[0] = "" set SkyPath[1] = "Environment\\Sky\\BlizzardSky\\BlizzardSky.mdl" set SkyPath[2] = "Environment\\Sky\\DalaranSky\\DalaranSky.mdl" set SkyPath[3] = "Environment\\Sky\\FelwoodSky\\FelwoodSky.mdl" set SkyPath[4] = "Environment\\Sky\\FoggedSky\\FoggedSky.mdl" set SkyPath[5] = "Environment\\Sky\\Sky\\SkyLight.mdl" set SkyPath[6] = "Environment\\Sky\\LordaeronFallSky\\LordaeronFallSky.mdl" set SkyPath[7] = "Environment\\Sky\\LordaeronSummerSky\\LordaeronSummerSky.mdl" set SkyPath[8] = "Environment\\Sky\\LordaeronWinterSky\\LordaeronWinterSky.mdl" set SkyPath[9] = "Environment\\Sky\\LordaeronWinterSkyBrightGreen\\LordaeronWinterSkyBrightGreen.mdl" set SkyPath[10] = "Environment\\Sky\\LordaeronWinterSkyPink\\LordaeronWinterSkyPink.mdl" set SkyPath[11] = "Environment\\Sky\\LordaeronWinterSkyPurple\\LordaeronWinterSkyPurple.mdl" set SkyPath[12] = "Environment\\Sky\\LordaeronWinterSkyRed\\LordaeronWinterSkyRed.mdl" set SkyPath[13] = "Environment\\Sky\\LordaeronWinterSkyYellow\\LordaeronWinterSkyYellow.mdl" set SkyPath[14] = "Environment\\Sky\\Outland_Sky\\Outland_Sky.mdl" set SkyName[0] = "None" set SkyName[1] = "Blizzard Sky" set SkyName[2] = "Dalaran Sky" set SkyName[3] = "Felwood Sky" set SkyName[4] = "Fogged Sky" set SkyName[5] = "Light Sky" set SkyName[6] = "Lordaeron Fall Sky" set SkyName[7] = "Lordaeron Summer Sky" set SkyName[8] = "Lordaeron Winter Sky" set SkyName[9] = "Lordaeron Winter Sky Green" set SkyName[10] = "Lordaeron Winter Sky Pink" set SkyName[11] = "Lordaeron Winter Sky Purple" set SkyName[12] = "Lordaeron Winter Sky Red" set SkyName[13] = "Lordaeron Winter Sky Yellow" set SkyName[14] = "Outland Sky" set WeatherId[0] = 0 set WeatherId[1] = 'RAhr' set WeatherId[2] = 'RAlr' set WeatherId[3] = 'MEds' set WeatherId[4] = 'FDbh' set WeatherId[5] = 'FDbl' set WeatherId[6] = 'FDgh' set WeatherId[7] = 'FDgl' set WeatherId[8] = 'FDrh' set WeatherId[9] = 'FDrl' set WeatherId[10] = 'FDwh' set WeatherId[11] = 'FDwl' set WeatherId[12] = 'RLhr' set WeatherId[13] = 'RLlr' set WeatherId[14] = 'SNbs' set WeatherId[15] = 'SNhs' set WeatherId[16] = 'SNls' set WeatherId[17] = 'WOcw' set WeatherId[18] = 'WOlw' set WeatherId[19] = 'LRaa' set WeatherId[20] = 'LRma' set WeatherId[21] = 'WNcw' set WeatherName[0] = "None" set WeatherName[1] = "Ashenvale Rain (Heavy)" set WeatherName[2] = "Ashenvale Rain (Light)" set WeatherName[3] = "Dalaran Shield" set WeatherName[4] = "Dungeon Fog Blue (Heavy)" set WeatherName[5] = "Dungeon Fog Blue (Light)" set WeatherName[6] = "Dungeon Fog Green (Heavy)" set WeatherName[7] = "Dungeon Fog Green (Light)" set WeatherName[8] = "Dungeon Fog Red (Heavy)" set WeatherName[9] = "Dungeon Fog Red (Light)" set WeatherName[10] = "Dungeon Fog White (Heavy)" set WeatherName[11] = "Dungeon Fog White (Light)" set WeatherName[12] = "Lordaeron Rain (Heavy)" set WeatherName[13] = "Lordaeron Rain (Light)" set WeatherName[14] = "Northrend Blizzard" set WeatherName[15] = "Northrend Snow (Heavy)" set WeatherName[16] = "Northrend Snow (Light)" set WeatherName[17] = "Outland Wind (Heavy)" set WeatherName[18] = "Outland Wind (Light)" set WeatherName[19] = "Rays of Light" set WeatherName[20] = "Rays of Moonlight" set WeatherName[21] = "Wind (Heavy)" call TriggerRegisterTimerEvent(trig, 0.01, false) call TriggerAddAction(trig, function SetupCP) call TimerStart(Pressed, REPETITION_SPEED, true, function KeyRepetition) set ArrowKeys_pressLeft = ArrowKeys_Event.Keys set ArrowKeys_releaseLeft = ArrowKeys_Event.Keys set ArrowKeys_pressRight = ArrowKeys_Event.Keys set ArrowKeys_releaseRight = ArrowKeys_Event.Keys set ArrowKeys_pressUp = ArrowKeys_Event.Keys set ArrowKeys_releaseUp = ArrowKeys_Event.Keys set ArrowKeys_pressDown = ArrowKeys_Event.Keys set ArrowKeys_releaseDown = ArrowKeys_Event.Keys loop exitwhen i == bj_MAX_PLAYERS set Sky[i] = DEFAULT_SKY set FogStyle[i] = DEFAULT_FOG_STYLE set FogZStart[i] = DEFAULT_FOG_ZSTART set FogZEnd[i] = DEFAULT_FOG_ZEND set FogDensity[i] = DEFAULT_FOG_DENSITY set FogRed[i] = DEFAULT_FOG_RED set FogGreen[i] = DEFAULT_FOG_GREEN set FogBlue[i] = DEFAULT_FOG_BLUE set WaterRed[i] = DEFAULT_WATER_RED set WaterGreen[i] = DEFAULT_WATER_GREEN set WaterBlue[i] = DEFAULT_WATER_BLUE set WaterAlpha[i] = DEFAULT_WATER_ALPHA set ActiveRow[i] = DEFAULT_ROW set i = i+1 endloop if Weather != 0 then set WeatherEffect = AddWeatherEffect(GetWorldBounds(), WeatherId[Weather]) call EnableWeatherEffect(WeatherEffect, true) endif loop exitwhen h == C.height set w = 0 loop exitwhen w == C.width set C[w][h] = h*C.width+w set w = w+1 endloop set h = h+1 endloop call SetTerrainFogEx(DEFAULT_FOG_STYLE, DEFAULT_FOG_ZSTART, DEFAULT_FOG_ZEND, DEFAULT_FOG_DENSITY, DEFAULT_FOG_RED, DEFAULT_FOG_GREEN, DEFAULT_FOG_BLUE) call SetWaterBaseColor(DEFAULT_WATER_RED, DEFAULT_WATER_GREEN, DEFAULT_WATER_BLUE, DEFAULT_WATER_ALPHA) call SetSkyModel(SkyPath[DEFAULT_SKY]) set trig = null endfunction // //**************************************************************** endlibrary Requirements:
|
| 05-16-2009, 06:17 PM | #2 |
Looks awesome! |
| 05-16-2009, 06:33 PM | #3 |
Please post the code. I suspect by your naming for the functions that you're using public function prefixes, which sucks. I also don't think AtmoUtils really says a lot. Just call the thing AtmosphereTester or AtmosphereDebug or something, since that is the intended purpose. |
| 05-16-2009, 06:42 PM | #4 |
The code's too long - exceeding character limit. That's why I attached it as a text file. And yep I'm using public function prefixes but I don't really see what's wrong with it. Just a matter of taste I guess. It's just one single function anyway. The name... well hmm. What about OppiAtmosphere? Hawr hawr. I'll think about it. |
| 05-16-2009, 07:02 PM | #5 |
so in other words, it isnt a system to be used in a live games, its basically a tool |
| 05-16-2009, 07:28 PM | #6 | |||
Quote:
Quote:
Quote:
|
| 05-16-2009, 07:48 PM | #7 |
Actually even the required (and approved!) library ArrowKeys by Anitarf uses public prefixes. I've been using them for OppiCam and no one has critisized that either. I mean I don't mind removing the prefix but it's just pretty new to me that public functions aren't up to the standards here. Considering the name I guess I'll just go for AmbienceTester or something like that though. But does that mean I'll have to rename OppiCam too? Say no to opossum hate! |
| 05-16-2009, 09:46 PM | #8 | ||||
Quote:
EDIT: I just looked at ArrowKeys, and its usage is very different from this. Like, he has event responses and uses the keywords "up," "down," "left," "right," which due to their very generic form is okay to use the public prefix on. Just "up" would probably have collisions with other things in other parts of the maps using it. It doesn't seem to use public functions per se. Quote:
Quote:
Quote:
|
| 05-16-2009, 10:17 PM | #9 |
Alright I changed the name and removed the public prefix. Gonna fix OppiCam now. |
| 06-15-2009, 12:52 PM | #10 | |
Quote:
Anyway, this is a useful tool (I guess I'll move it under systems), very neat implementation, the user interface is superb. Approved. By the way, I think the charlimit for posts has been extended recently so you can try posting the code in the post now. |
| 06-15-2009, 02:28 PM | #11 | |
Yeehaw! Thanks! Quote:
|
| 07-17-2010, 10:16 AM | #12 |
I know this is a bit late, but I was reading through your various reasons link, and I saw that you used GetWorldBounds() in a GetLocalPlayer() block -- could that be the cause of the desync, since it returns a new rect each call? |
| 07-18-2010, 04:24 PM | #13 | |
Quote:
You can't create weather effects locally BUT you can enable them locally - which would be totally fine if it weren't for that one-effect-rule I posted about in that thread. |
