Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor|libhexen: Moved LightningAnimator to new source files
- Loading branch information
1 parent
e4c7649
commit 37d15b9
Showing
4 changed files
with
306 additions
and
228 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/** @file lightninganimator.h Animator for map-wide lightning effects. | ||
* | ||
* @authors Copyright © 2004-2014 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
* @authors Copyright © 2005-2014 Daniel Swanson <danij@dengine.net> | ||
* @authors Copyright © 1999 Activision | ||
* | ||
* @par License | ||
* GPL: http://www.gnu.org/licenses/gpl.html | ||
* | ||
* <small>This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. This program is distributed in the hope that it | ||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty | ||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
* Public License for more details. You should have received a copy of the GNU | ||
* General Public License along with this program; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA</small> | ||
*/ | ||
|
||
#ifndef LIBHEXEN_PLAY_LIGHTNINGANIMATOR_H | ||
#define LIBHEXEN_PLAY_LIGHTNINGANIMATOR_H | ||
|
||
#include "jhexen.h" | ||
|
||
/** | ||
* Animator for the map-wide lightning effects. | ||
*/ | ||
class LightningAnimator | ||
{ | ||
public: | ||
LightningAnimator(); | ||
|
||
/** | ||
* Determines whether lightning is enabled for the current map. | ||
*/ | ||
bool enabled() const; | ||
|
||
/** | ||
* Manually trigger a lightning flash which will begin animating on the next game tic. | ||
* Can be used to trigger a flash at specific times. | ||
*/ | ||
void triggerFlash(); | ||
|
||
/** | ||
* Animate lightning for the current map. To be called once per GAMETIC. | ||
*/ | ||
void advanceTime(); | ||
|
||
/** | ||
* Initialize the lightning animator for the current map. | ||
* | ||
* @return @c true, if lightning is enabled for the current map, for caller convenience. | ||
*/ | ||
bool initForMap(); | ||
|
||
private: | ||
DENG2_PRIVATE(d) | ||
}; | ||
|
||
#endif // LIBHEXEN_PLAY_LIGHTNINGANIMATOR_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,241 @@ | ||
/** @file lightninganimator.cpp Animator for map-wide lightning effects. | ||
* | ||
* @authors Copyright © 2003-2014 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
* @authors Copyright © 2005-2014 Daniel Swanson <danij@dengine.net> | ||
* @authors Copyright © 1999 Activision | ||
* | ||
* @par License | ||
* GPL: http://www.gnu.org/licenses/gpl.html | ||
* | ||
* <small>This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. This program is distributed in the hope that it | ||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty | ||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
* Public License for more details. You should have received a copy of the GNU | ||
* General Public License along with this program; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA</small> | ||
*/ | ||
|
||
#include "jhexen.h" | ||
#include "lightninganimator.h" | ||
|
||
#include "dmu_lib.h" | ||
#include "gamesession.h" | ||
|
||
using namespace de; | ||
|
||
#define LIGHTNING_SPECIAL 198 | ||
#define LIGHTNING_SPECIAL2 199 | ||
|
||
static bool isLightningSector(Sector *sec) | ||
{ | ||
xsector_t *xsec = P_ToXSector(sec); | ||
|
||
if(xsec->special == LIGHTNING_SPECIAL || xsec->special == LIGHTNING_SPECIAL2) | ||
return true; | ||
|
||
if(P_GetIntp(P_GetPtrp(sec, DMU_CEILING_MATERIAL), | ||
DMU_FLAGS) & MATF_SKYMASK) | ||
return true; | ||
|
||
if(P_GetIntp(P_GetPtrp(sec, DMU_FLOOR_MATERIAL), | ||
DMU_FLAGS) & MATF_SKYMASK) | ||
return true; | ||
|
||
return false; | ||
} | ||
|
||
DENG2_PIMPL_NOREF(LightningAnimator) | ||
{ | ||
int flash = 0; | ||
int nextFlash = 0; | ||
float *sectorLightLevels = 0; ///< Ambient light levels for each sector (if enabled). | ||
}; | ||
|
||
LightningAnimator::LightningAnimator() : d(new Instance) | ||
{} | ||
|
||
bool LightningAnimator::enabled() const | ||
{ | ||
return d->sectorLightLevels != 0; | ||
} | ||
|
||
void LightningAnimator::triggerFlash() | ||
{ | ||
if(!enabled()) return; | ||
d->nextFlash = 0; | ||
} | ||
|
||
void LightningAnimator::advanceTime() | ||
{ | ||
if(!enabled()) return; | ||
|
||
// Is it time for a lightning state change? | ||
if(!(!d->nextFlash || d->flash)) | ||
{ | ||
d->nextFlash--; | ||
return; | ||
} | ||
|
||
if(d->flash) | ||
{ | ||
d->flash--; | ||
float *tempLight = d->sectorLightLevels; | ||
|
||
if(d->flash) | ||
{ | ||
for(int i = 0; i < numsectors; ++i) | ||
{ | ||
Sector *sec = (Sector *)P_ToPtr(DMU_SECTOR, i); | ||
if(!isLightningSector(sec)) continue; | ||
|
||
float lightLevel = P_GetFloat(DMU_SECTOR, i, DMU_LIGHT_LEVEL); | ||
if(*tempLight < lightLevel - (4.f / 255)) | ||
{ | ||
P_SetFloat(DMU_SECTOR, i, DMU_LIGHT_LEVEL, lightLevel - (1.f / 255) * 4); | ||
} | ||
tempLight++; | ||
} | ||
} | ||
else | ||
{ | ||
// Remove the alternate lightning flash special. | ||
for(int i = 0; i < numsectors; ++i) | ||
{ | ||
Sector *sec = (Sector *)P_ToPtr(DMU_SECTOR, i); | ||
if(!isLightningSector(sec)) continue; | ||
|
||
P_SetFloatp(sec, DMU_LIGHT_LEVEL, *tempLight); | ||
tempLight++; | ||
} | ||
|
||
if(!IS_DEDICATED) | ||
{ | ||
R_SkyParams(1, DD_DISABLE, nullptr); | ||
R_SkyParams(0, DD_ENABLE, nullptr); | ||
} | ||
} | ||
|
||
return; | ||
} | ||
|
||
d->flash = (P_Random() & 7) + 8; | ||
|
||
float const flashLight = (float) (200 + (P_Random() & 31)) / 255.0f; | ||
float *tempLight = d->sectorLightLevels; | ||
bool foundSec = false; | ||
for(int i = 0; i < numsectors; ++i) | ||
{ | ||
Sector *sec = (Sector *)P_ToPtr(DMU_SECTOR, i); | ||
if(!isLightningSector(sec)) continue; | ||
|
||
xsector_t *xsec = P_ToXSector(sec); | ||
float newLevel = P_GetFloatp(sec, DMU_LIGHT_LEVEL); | ||
|
||
*tempLight = newLevel; | ||
|
||
if(xsec->special == LIGHTNING_SPECIAL) | ||
{ | ||
newLevel += .25f; | ||
if(newLevel > flashLight) | ||
newLevel = flashLight; | ||
} | ||
else if(xsec->special == LIGHTNING_SPECIAL2) | ||
{ | ||
newLevel += .125f; | ||
if(newLevel > flashLight) | ||
newLevel = flashLight; | ||
} | ||
else | ||
{ | ||
newLevel = flashLight; | ||
} | ||
|
||
if(newLevel < *tempLight) | ||
newLevel = *tempLight; | ||
|
||
P_SetFloatp(sec, DMU_LIGHT_LEVEL, newLevel); | ||
tempLight++; | ||
foundSec = true; | ||
} | ||
|
||
if(foundSec) | ||
{ | ||
mobj_t *plrmo = ::players[DISPLAYPLAYER].plr->mo; | ||
mobj_t *clapSource = 0; | ||
|
||
if(!IS_DEDICATED) | ||
{ | ||
// Set the alternate (lightning) sky. | ||
R_SkyParams(0, DD_DISABLE, nullptr); | ||
R_SkyParams(1, DD_ENABLE, nullptr); | ||
} | ||
|
||
// If 3D sounds are active, position the clap somewhere above the player. | ||
if(::cfg.snd3D && plrmo && !IS_NETGAME) | ||
{ | ||
coord_t clapOrigin[] = { | ||
plrmo->origin[VX] + (16 * (M_Random() - 127) << FRACBITS), | ||
plrmo->origin[VY] + (16 * (M_Random() - 127) << FRACBITS), | ||
plrmo->origin[VZ] + (4000 << FRACBITS) | ||
}; | ||
clapSource = P_SpawnMobj(MT_CAMERA, clapOrigin, 0, 0); | ||
if(clapSource) | ||
{ | ||
clapSource->tics = 5 * TICSPERSEC; // Five seconds will do. | ||
} | ||
} | ||
|
||
// Make it loud! | ||
S_StartSound(SFX_THUNDER_CRASH | DDSF_NO_ATTENUATION, clapSource); | ||
} | ||
|
||
// Calculate the next lighting flash. | ||
if(!d->nextFlash) | ||
{ | ||
if(P_Random() < 50) // Immediate, quick flash. | ||
{ | ||
d->nextFlash = (P_Random() & 15) + 16; | ||
} | ||
else if(P_Random() < 128 && !(mapTime & 32)) | ||
{ | ||
d->nextFlash = ((P_Random() & 7) + 2) * TICSPERSEC; | ||
} | ||
else | ||
{ | ||
d->nextFlash = ((P_Random() & 15) + 5) * TICSPERSEC; | ||
} | ||
} | ||
} | ||
|
||
bool LightningAnimator::initForMap() | ||
{ | ||
d->flash = 0; | ||
d->nextFlash = 0; | ||
Z_Free(d->sectorLightLevels); d->sectorLightLevels = 0; | ||
|
||
Record const *mapInfo = COMMON_GAMESESSION->mapInfo(); | ||
if(mapInfo && !mapInfo->getb("lightning")) | ||
{ | ||
int numLightningSectors = 0; | ||
for(int i = 0; i < numsectors; ++i) | ||
{ | ||
if(isLightningSector((Sector *)P_ToPtr(DMU_SECTOR, i))) | ||
{ | ||
numLightningSectors++; | ||
} | ||
} | ||
if(numLightningSectors > 0) | ||
{ | ||
d->sectorLightLevels = (float *)Z_Malloc(numLightningSectors * sizeof(*d->sectorLightLevels), PU_MAP, nullptr); | ||
|
||
// Don't flash immediately on entering the map. | ||
d->nextFlash = ((P_Random() & 15) + 5) * TICSPERSEC; | ||
} | ||
} | ||
|
||
return enabled(); | ||
} |
Oops, something went wrong.