From 8b1a8bee3437f5d8f865e77e27ae15ad4c690f10 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Wed, 13 Feb 2013 19:22:08 +0000 Subject: [PATCH] Added HOOK_WEATHER_CHANGING. http://www.mc-server.org/support/index.php?do=details&task_id=299 git-svn-id: http://mc-server.googlecode.com/svn/trunk@1210 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- MCServer/Plugins/HookNotify/HookNotify.lua | 15 +- source/Bindings.cpp | 65 +++++++- source/Bindings.h | 2 +- source/BlockArea.cpp | 12 ++ source/BlockArea.h | 6 + source/Plugin.cpp | 14 +- source/Plugin.h | 3 +- source/PluginManager.cpp | 23 ++- source/PluginManager.h | 7 +- source/Plugin_NewLua.cpp | 36 ++++- source/Plugin_NewLua.h | 3 +- source/World.cpp | 168 +++++++++------------ source/World.h | 17 ++- 13 files changed, 251 insertions(+), 120 deletions(-) diff --git a/MCServer/Plugins/HookNotify/HookNotify.lua b/MCServer/Plugins/HookNotify/HookNotify.lua index efb96fec5..92cc2e059 100644 --- a/MCServer/Plugins/HookNotify/HookNotify.lua +++ b/MCServer/Plugins/HookNotify/HookNotify.lua @@ -9,10 +9,10 @@ PLUGIN = {} -- Reference to own plugin object function Initialize(Plugin) PLUGIN = Plugin - Plugin:SetName("HookNotify") - Plugin:SetVersion(1) + Plugin:SetName("HookNotify"); + Plugin:SetVersion(1); - PluginManager = cRoot:Get():GetPluginManager() + PluginManager = cPluginManager:Get(); PluginManager:AddHook(Plugin, cPluginManager.HOOK_BLOCK_TO_PICKUPS); PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHAT); PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_AVAILABLE); @@ -48,6 +48,7 @@ function Initialize(Plugin) PluginManager:AddHook(Plugin, cPluginManager.HOOK_UPDATED_SIGN); PluginManager:AddHook(Plugin, cPluginManager.HOOK_UPDATING_SIGN); PluginManager:AddHook(Plugin, cPluginManager.HOOK_WEATHER_CHANGED); + PluginManager:AddHook(Plugin, cPluginManager.HOOK_WEATHER_CHANGING); LOGINFO("HookNotify plugin is installed, beware, the log output may be quite large!"); LOGINFO("You want this plugin enabled only when developing another plugin, not for regular gameplay."); @@ -365,6 +366,14 @@ end +function OnWeatherChanging(...) + LogHook("OnWeatherChanging", unpack(arg)); +end + + + + + ------------------------------------------------------------------ -- Special handling for OnTakeDamage to print the contents of TDI: diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 12e16a628..3cdee41a9 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 02/11/13 09:47:05. +** Generated automatically by tolua++-1.0.92 on 02/13/13 19:08:23. */ #ifndef __cplusplus @@ -11323,12 +11323,12 @@ static int tolua_AllToLua_cWorld_SetWeather00(lua_State* tolua_S) #endif { cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - eWeather a_Weather = ((eWeather) (int) tolua_tonumber(tolua_S,2,0)); + eWeather a_NewWeather = ((eWeather) (int) tolua_tonumber(tolua_S,2,0)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetWeather'", NULL); #endif { - self->SetWeather(a_Weather); + self->SetWeather(a_NewWeather); } } return 0; @@ -11378,14 +11378,14 @@ static int tolua_AllToLua_cWorld_GetWeather00(lua_State* tolua_S) #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || !tolua_isnoobj(tolua_S,2,&tolua_err) ) goto tolua_lerror; else #endif { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWeather'", NULL); #endif @@ -18324,6 +18324,59 @@ static int tolua_AllToLua_cBlockArea_FillRelCuboid00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: RelLine of class cBlockArea */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_RelLine00 +static int tolua_AllToLua_cBlockArea_RelLine00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBlockArea",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnumber(tolua_S,7,0,&tolua_err) || + !tolua_isnumber(tolua_S,8,0,&tolua_err) || + !tolua_isnumber(tolua_S,9,0,&tolua_err) || + !tolua_isnumber(tolua_S,10,1,&tolua_err) || + !tolua_isnumber(tolua_S,11,1,&tolua_err) || + !tolua_isnumber(tolua_S,12,1,&tolua_err) || + !tolua_isnoobj(tolua_S,13,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cBlockArea* self = (cBlockArea*) tolua_tousertype(tolua_S,1,0); + int a_RelX1 = ((int) tolua_tonumber(tolua_S,2,0)); + int a_RelY1 = ((int) tolua_tonumber(tolua_S,3,0)); + int a_RelZ1 = ((int) tolua_tonumber(tolua_S,4,0)); + int a_RelX2 = ((int) tolua_tonumber(tolua_S,5,0)); + int a_RelY2 = ((int) tolua_tonumber(tolua_S,6,0)); + int a_RelZ2 = ((int) tolua_tonumber(tolua_S,7,0)); + int a_DataTypes = ((int) tolua_tonumber(tolua_S,8,0)); + unsigned char a_BlockType = (( unsigned char) tolua_tonumber(tolua_S,9,0)); + unsigned char a_BlockMeta = (( unsigned char) tolua_tonumber(tolua_S,10,0)); + unsigned char a_BlockLight = (( unsigned char) tolua_tonumber(tolua_S,11,0)); + unsigned char a_BlockSkyLight = (( unsigned char) tolua_tonumber(tolua_S,12,0x0f)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RelLine'", NULL); +#endif + { + self->RelLine(a_RelX1,a_RelY1,a_RelZ1,a_RelX2,a_RelY2,a_RelZ2,a_DataTypes,a_BlockType,a_BlockMeta,a_BlockLight,a_BlockSkyLight); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'RelLine'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: SetRelBlockType of class cBlockArea */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_SetRelBlockType00 static int tolua_AllToLua_cBlockArea_SetRelBlockType00(lua_State* tolua_S) @@ -22036,6 +22089,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"HOOK_UPDATED_SIGN",cPluginManager::HOOK_UPDATED_SIGN); tolua_constant(tolua_S,"HOOK_UPDATING_SIGN",cPluginManager::HOOK_UPDATING_SIGN); tolua_constant(tolua_S,"HOOK_WEATHER_CHANGED",cPluginManager::HOOK_WEATHER_CHANGED); + tolua_constant(tolua_S,"HOOK_WEATHER_CHANGING",cPluginManager::HOOK_WEATHER_CHANGING); tolua_function(tolua_S,"Get",tolua_AllToLua_cPluginManager_Get00); tolua_function(tolua_S,"GetPlugin",tolua_AllToLua_cPluginManager_GetPlugin00); tolua_function(tolua_S,"FindPlugins",tolua_AllToLua_cPluginManager_FindPlugins00); @@ -22464,6 +22518,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"Merge",tolua_AllToLua_cBlockArea_Merge00); tolua_function(tolua_S,"Fill",tolua_AllToLua_cBlockArea_Fill00); tolua_function(tolua_S,"FillRelCuboid",tolua_AllToLua_cBlockArea_FillRelCuboid00); + tolua_function(tolua_S,"RelLine",tolua_AllToLua_cBlockArea_RelLine00); tolua_function(tolua_S,"SetRelBlockType",tolua_AllToLua_cBlockArea_SetRelBlockType00); tolua_function(tolua_S,"SetBlockType",tolua_AllToLua_cBlockArea_SetBlockType00); tolua_function(tolua_S,"SetRelBlockMeta",tolua_AllToLua_cBlockArea_SetRelBlockMeta00); diff --git a/source/Bindings.h b/source/Bindings.h index d8b6c1c7e..fd5d2ccb0 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 02/11/13 09:47:06. +** Generated automatically by tolua++-1.0.92 on 02/13/13 19:08:24. */ /* Exported function */ diff --git a/source/BlockArea.cpp b/source/BlockArea.cpp index 0386a74a5..8ec77944e 100644 --- a/source/BlockArea.cpp +++ b/source/BlockArea.cpp @@ -722,6 +722,18 @@ void cBlockArea::FillRelCuboid(int a_MinRelX, int a_MaxRelX, int a_MinRelY, int +void cBlockArea::RelLine(int a_RelX1, int a_RelY1, int a_RelZ1, int a_RelX2, int a_RelY2, int a_RelZ2, + int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, + NIBBLETYPE a_BlockLight, NIBBLETYPE a_BlockSkyLight +) +{ + // TODO +} + + + + + void cBlockArea::SetRelBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType) { if (m_BlockTypes == NULL) diff --git a/source/BlockArea.h b/source/BlockArea.h index 04c4a7d36..5cb19b416 100644 --- a/source/BlockArea.h +++ b/source/BlockArea.h @@ -124,6 +124,12 @@ public: NIBBLETYPE a_BlockLight = 0, NIBBLETYPE a_BlockSkyLight = 0x0f ); + /// Draws a line from between two points with the specified data + void RelLine(int a_RelX1, int a_RelY1, int a_RelZ1, int a_RelX2, int a_RelY2, int a_RelZ2, + int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta = 0, + NIBBLETYPE a_BlockLight = 0, NIBBLETYPE a_BlockSkyLight = 0x0f + ); + // Setters: void SetRelBlockType (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType); void SetBlockType (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType); diff --git a/source/Plugin.cpp b/source/Plugin.cpp index 736460e87..968f8c1f6 100644 --- a/source/Plugin.cpp +++ b/source/Plugin.cpp @@ -4,6 +4,7 @@ #include "Plugin.h" #include "Pawn.h" #include "Player.h" +#include "World.h" @@ -502,7 +503,7 @@ bool cPlugin::OnUpdatingSign(cWorld * a_World, int a_BlockX, int a_BlockY, int a -bool cPlugin::OnWeatherChanged(cWorld * a_World) +bool cPlugin::OnWeatherChanged(cWorld & a_World) { UNUSED(a_World); return false; @@ -512,6 +513,17 @@ bool cPlugin::OnWeatherChanged(cWorld * a_World) +bool cPlugin::OnWeatherChanging(cWorld & a_World, eWeather & a_Weather) +{ + UNUSED(a_World); + UNUSED(a_Weather); + return false; +} + + + + + bool cPlugin::HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) { UNUSED(a_Split); diff --git a/source/Plugin.h b/source/Plugin.h index 256e30c99..e787c3239 100644 --- a/source/Plugin.h +++ b/source/Plugin.h @@ -82,7 +82,8 @@ public: virtual bool OnTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TakeDamageInfo); virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player); virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player); - virtual bool OnWeatherChanged (cWorld * a_World); + virtual bool OnWeatherChanged (cWorld & a_World); + virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather); /// Handles the command split into a_Split, issued by player a_Player. Command permissions have already been checked. virtual bool HandleCommand(const AStringVector & a_Split, cPlayer * a_Player); diff --git a/source/PluginManager.cpp b/source/PluginManager.cpp index 8ff4f4e8f..c80c512a0 100644 --- a/source/PluginManager.cpp +++ b/source/PluginManager.cpp @@ -905,7 +905,7 @@ bool cPluginManager::CallHookUpdatedSign(cWorld * a_World, int a_BlockX, int a_B -bool cPluginManager::CallHookWeatherChanged(cWorld * a_World) +bool cPluginManager::CallHookWeatherChanged(cWorld & a_World) { HookMap::iterator Plugins = m_Hooks.find(HOOK_WEATHER_CHANGED); if (Plugins == m_Hooks.end()) @@ -926,6 +926,27 @@ bool cPluginManager::CallHookWeatherChanged(cWorld * a_World) +bool cPluginManager::CallHookWeatherChanging(cWorld & a_World, eWeather & a_NewWeather) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_WEATHER_CHANGING); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnWeatherChanging(a_World, a_NewWeather)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions) { ASSERT(a_Player != NULL); diff --git a/source/PluginManager.h b/source/PluginManager.h index 743d6f26a..653f0c432 100644 --- a/source/PluginManager.h +++ b/source/PluginManager.h @@ -75,8 +75,10 @@ public: // tolua_export HOOK_UPDATED_SIGN, HOOK_UPDATING_SIGN, HOOK_WEATHER_CHANGED, + HOOK_WEATHER_CHANGING, - // Note that if a hook type is added, it may need processing in cPlugin::CanAddHook() descendants! + // Note that if a hook type is added, it may need processing in cPlugin::CanAddHook() descendants, + // and it definitely needs adding in cPlugin_NewLua::GetHookFnName() ! } ; // tolua_end @@ -136,7 +138,8 @@ public: // tolua_export bool CallHookTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TDI); bool CallHookUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player); bool CallHookUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player); - bool CallHookWeatherChanged (cWorld * a_World); + bool CallHookWeatherChanged (cWorld & a_World); + bool CallHookWeatherChanging (cWorld & a_World, eWeather & a_NewWeather); bool DisablePlugin(const AString & a_PluginName); // tolua_export bool LoadPlugin (const AString & a_PluginName); // tolua_export diff --git a/source/Plugin_NewLua.cpp b/source/Plugin_NewLua.cpp index d83a88f96..249c9fafd 100644 --- a/source/Plugin_NewLua.cpp +++ b/source/Plugin_NewLua.cpp @@ -1210,7 +1210,7 @@ bool cPlugin_NewLua::OnUpdatingSign( -bool cPlugin_NewLua::OnWeatherChanged(cWorld * a_World) +bool cPlugin_NewLua::OnWeatherChanged(cWorld & a_World) { cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_WEATHER_CHANGED); @@ -1220,7 +1220,7 @@ bool cPlugin_NewLua::OnWeatherChanged(cWorld * a_World) return false; } - tolua_pushusertype(m_LuaState, (void *)a_World, "cWorld"); + tolua_pushusertype(m_LuaState, &a_World, "cWorld"); if (!CallFunction(1, 1, FnName)) { @@ -1236,6 +1236,37 @@ bool cPlugin_NewLua::OnWeatherChanged(cWorld * a_World) +bool cPlugin_NewLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather) +{ + cCSLock Lock(m_CriticalSection); + const char * FnName = GetHookFnName(cPluginManager::HOOK_WEATHER_CHANGED); + ASSERT(FnName != NULL); + if (!PushFunction(FnName)) + { + return false; + } + + tolua_pushusertype(m_LuaState, &a_World, "cWorld"); + tolua_pushnumber (m_LuaState, a_NewWeather); + + if (!CallFunction(2, 2, FnName)) + { + return false; + } + + bool bRetVal = (tolua_toboolean(m_LuaState, -1, 0) > 0); + if (lua_isnumber(m_LuaState, -2)) + { + a_NewWeather = (eWeather)lua_tointeger(m_LuaState, -2); + } + lua_pop(m_LuaState, 1); + return bRetVal; +} + + + + + bool cPlugin_NewLua::HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) { ASSERT(!a_Split.empty()); @@ -1395,6 +1426,7 @@ const char * cPlugin_NewLua::GetHookFnName(cPluginManager::PluginHook a_Hook) case cPluginManager::HOOK_UPDATED_SIGN: return "OnUpdatedSign"; case cPluginManager::HOOK_UPDATING_SIGN: return "OnUpdatingSign"; case cPluginManager::HOOK_WEATHER_CHANGED: return "OnWeatherChanged"; + case cPluginManager::HOOK_WEATHER_CHANGING: return "OnWeatherChanging"; default: return NULL; } // switch (a_Hook) } diff --git a/source/Plugin_NewLua.h b/source/Plugin_NewLua.h index 045ad9858..529f0e0eb 100644 --- a/source/Plugin_NewLua.h +++ b/source/Plugin_NewLua.h @@ -67,7 +67,8 @@ public: virtual bool OnTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TakeDamageInfo) override; virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) override; virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) override; - virtual bool OnWeatherChanged (cWorld * a_World) override; + virtual bool OnWeatherChanged (cWorld & a_World) override; + virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) override; virtual bool HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) override; diff --git a/source/World.cpp b/source/World.cpp index e5e8977bd..2c31371d2 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -307,34 +307,49 @@ cWorld::~cWorld() -void cWorld::SetWeather(eWeather a_Weather) +void cWorld::CastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) { - switch (a_Weather) - { - case eWeather_Sunny: - case eWeather_Rain: - case eWeather_ThunderStorm: - { - m_Weather = a_Weather; - BroadcastWeather(a_Weather); - break; - } - - default: - { - LOGWARN("Trying to set unknown weather %d", a_Weather); - break; - } - } + BroadcastThunderbolt(a_BlockX, a_BlockY, a_BlockZ); } -void cWorld::CastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) +void cWorld::SetWeather(eWeather a_NewWeather) { - BroadcastThunderbolt(a_BlockX, a_BlockY, a_BlockZ); + // Do the plugins agree? Do they want a different weather? + cRoot::Get()->GetPluginManager()->CallHookWeatherChanging(*this, a_NewWeather); + + // Set new period for the selected weather: + switch (a_NewWeather) + { + case eWeather_Sunny: m_WeatherInterval = 14400 + (m_TickRand.randInt() % 4800); break; // 12 - 16 minutes + case eWeather_Rain: m_WeatherInterval = 9600 + (m_TickRand.randInt() % 7200); break; // 8 - 14 minutes + case eWeather_ThunderStorm: m_WeatherInterval = 2400 + (m_TickRand.randInt() % 4800); break; // 2 - 6 minutes + default: + { + LOGWARNING("Requested unknown weather %d, setting sunny for a minute instead.", a_NewWeather); + a_NewWeather = eWeather_Sunny; + m_WeatherInterval = 1200; + break; + } + } // switch (NewWeather) + m_Weather = a_NewWeather; + BroadcastWeather(m_Weather); + + // Let the plugins know about the change: + cPluginManager::Get()->CallHookWeatherChanged(*this); +} + + + + + +void cWorld::ChangeWeather(void) +{ + // In the next tick the weather will be changed + m_WeatherInterval = 0; } @@ -533,92 +548,47 @@ void cWorld::Tick(float a_Dt) -void cWorld::ChangeWeather() -{ - unsigned randWeather = (m_TickRand.randInt() % 99); - - if (GetWeather() == eWeather_Sunny) - { - if (randWeather < 20) - { - LOG("Starting rainstorm!"); - SetWeather( eWeather_Rain ); - } - } - - else if (GetWeather() == eWeather_Rain) - { - if (randWeather < 5) - { - LOG("Thunderstorm!"); - SetWeather( eWeather_ThunderStorm ); - } - - else if (randWeather < 60) - { - LOG("Back to sunshine"); - SetWeather( eWeather_Sunny ); - } - } - - else if (GetWeather() == eWeather_ThunderStorm) - { - if (randWeather < 70) - { - SetWeather(eWeather_Sunny); - LOG("Thunder ended abruptly, returning to lovely sunshine"); - } - else if (randWeather < 85) - { - SetWeather(eWeather_Rain); - LOG("Thunder ended, but rain persists."); - } - else - { - return; - } - } -} - - - - - void cWorld::TickWeather(float a_Dt) { - if (m_WeatherInterval == 0) - { - ChangeWeather(); - - cRoot::Get()->GetPluginManager()->CallHookWeatherChanged(this); - - switch (GetWeather()) - { - case eWeather_Sunny: - m_WeatherInterval = 14400 + (m_TickRand.randInt() % 4800); // 12 - 16 minutes - break; - case eWeather_Rain: - m_WeatherInterval = 9600 + (m_TickRand.randInt() % 7200); // 8 - 14 minutes - break; - case eWeather_ThunderStorm: - m_WeatherInterval = 2400 + (m_TickRand.randInt() % 4800); // 2 - 6 minutes - break; - default: - LOG("Unknown weather occurred"); - break; - } - } - - else + if (m_WeatherInterval > 0) { + // Not yet, wait for the weather period to end m_WeatherInterval--; } - - if ( GetWeather() == 2 ) // if thunderstorm + else { - if (m_TickRand.randInt() % 199 == 0) // 0.5% chance per tick of thunderbolt + // Change weather: + + // Pick a new weather. Only reasonable transitions allowed: + eWeather NewWeather = m_Weather; + switch (m_Weather) { - CastThunderbolt ( 0, 0, 0 ); // TODO: find random possitions near players to cast thunderbolts. + case eWeather_Sunny: NewWeather = eWeather_Rain; break; + case eWeather_ThunderStorm: NewWeather = eWeather_Rain; break; + case eWeather_Rain: + { + // 1/8 chance of turning into a thunderstorm + NewWeather = ((m_TickRand.randInt() % 256) < 32) ? eWeather_ThunderStorm : eWeather_Sunny; + break; + } + + default: + { + LOGWARNING("Unknown current weather: %d. Setting sunny.", m_Weather); + ASSERT(!"Unknown weather"); + NewWeather = eWeather_Sunny; + } + } + + SetWeather(NewWeather); + } // else (m_WeatherInterval > 0) + + if (m_Weather == eWeather_ThunderStorm) + { + // 0.5% chance per tick of thunderbolt + if (m_TickRand.randInt() % 199 == 0) + { + CastThunderbolt(0, 0, 0); // TODO: find random possitions near players to cast thunderbolts. } } } diff --git a/source/World.h b/source/World.h index 61817d18a..b744a66c1 100644 --- a/source/World.h +++ b/source/World.h @@ -419,10 +419,19 @@ public: void QueueBlockForTick(int a_BlockX, int a_BlockY, int a_BlockZ, float a_TimeToWait); // tolua_export - void CastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export - void SetWeather ( eWeather a_Weather ); // tolua_export - void ChangeWeather(); // tolua_export - eWeather GetWeather() { return m_Weather; }; // tolua_export + // tolua_begin + /// Casts a thunderbolt at the specified coords + void CastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ); + + /// Sets the specified weather; resets weather interval; asks and notifies plugins of the change + void SetWeather (eWeather a_NewWeather); + + /// Forces a weather change in the next game tick + void ChangeWeather (void); + + /// Returns the current weather + eWeather GetWeather (void) const { return m_Weather; }; + // tolua_end cChunkGenerator & GetGenerator(void) { return m_Generator; } cWorldStorage & GetStorage (void) { return m_Storage; }