Review light.cc
This commit is contained in:
parent
9ee4cb4a26
commit
66955f893a
|
@ -1745,7 +1745,7 @@ static bool aiHaveAmmo(Object* critter, Object* weapon, Object** ammoPtr)
|
|||
}
|
||||
|
||||
if (weapon->pid == PROTO_ID_SOLAR_SCORCHER) {
|
||||
return lightGetLightLevel() > 62259;
|
||||
return lightGetAmbientIntensity() > LIGHT_INTENSITY_MAX * 0.95;
|
||||
}
|
||||
|
||||
int inventoryItemIndex = -1;
|
||||
|
@ -2879,7 +2879,7 @@ static int _ai_try_attack(Object* a1, Object* a2)
|
|||
// 0x42AE90
|
||||
int _cAIPrepWeaponItem(Object* critter, Object* item)
|
||||
{
|
||||
if (item != NULL && critterGetStat(critter, STAT_INTELLIGENCE) >= 3 && item->pid == PROTO_ID_FLARE && lightGetLightLevel() < 55705) {
|
||||
if (item != NULL && critterGetStat(critter, STAT_INTELLIGENCE) >= 3 && item->pid == PROTO_ID_FLARE && lightGetAmbientIntensity() < LIGHT_INTENSITY_MAX * 0.85) {
|
||||
_protinst_use_item(critter, item);
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -343,21 +343,6 @@ static void opGetPcStat(Program* program);
|
|||
// 0x504B0C
|
||||
static char _aCritter[] = "<Critter>";
|
||||
|
||||
// Maps light level to light intensity.
|
||||
//
|
||||
// Middle value is mapped one-to-one which corresponds to 50% light level
|
||||
// (cavern lighting). Light levels above (51-100%) and below (0-49) is
|
||||
// calculated as percentage from two adjacent light values.
|
||||
//
|
||||
// See [opSetLightLevel] for math.
|
||||
//
|
||||
// 0x453F90
|
||||
static const int dword_453F90[3] = {
|
||||
0x4000,
|
||||
0xA000,
|
||||
0x10000,
|
||||
};
|
||||
|
||||
// 0x453FC0
|
||||
static Rect stru_453FC0 = { 0, 0, 640, 480 };
|
||||
|
||||
|
@ -2234,23 +2219,36 @@ static void opCritterHeal(Program* program)
|
|||
// 0x457934
|
||||
static void opSetLightLevel(Program* program)
|
||||
{
|
||||
// Maps light level to light intensity.
|
||||
//
|
||||
// Middle value is mapped one-to-one which corresponds to 50% light level
|
||||
// (cavern lighting). Light levels above (51-100%) and below (0-49%) is
|
||||
// calculated as percentage from two adjacent light values.
|
||||
//
|
||||
// 0x453F90
|
||||
static const int intensities[3] = {
|
||||
LIGHT_INTENSITY_MIN,
|
||||
(LIGHT_INTENSITY_MIN + LIGHT_INTENSITY_MAX) / 2,
|
||||
LIGHT_INTENSITY_MAX,
|
||||
};
|
||||
|
||||
int data = programStackPopInteger(program);
|
||||
|
||||
int lightLevel = data;
|
||||
|
||||
if (data == 50) {
|
||||
lightSetLightLevel(dword_453F90[1], true);
|
||||
lightSetAmbientIntensity(intensities[1], true);
|
||||
return;
|
||||
}
|
||||
|
||||
int lightIntensity;
|
||||
if (data > 50) {
|
||||
lightIntensity = dword_453F90[1] + data * (dword_453F90[2] - dword_453F90[1]) / 100;
|
||||
lightIntensity = intensities[1] + data * (intensities[2] - intensities[1]) / 100;
|
||||
} else {
|
||||
lightIntensity = dword_453F90[0] + data * (dword_453F90[1] - dword_453F90[0]) / 100;
|
||||
lightIntensity = intensities[0] + data * (intensities[1] - intensities[0]) / 100;
|
||||
}
|
||||
|
||||
lightSetLightLevel(lightIntensity, true);
|
||||
lightSetAmbientIntensity(lightIntensity, true);
|
||||
}
|
||||
|
||||
// game_time
|
||||
|
|
|
@ -3315,7 +3315,7 @@ int _invenWieldFunc(Object* critter, Object* item, int a3, bool a4)
|
|||
int lightIntensity;
|
||||
int lightDistance;
|
||||
if (critter == gDude) {
|
||||
lightIntensity = LIGHT_LEVEL_MAX;
|
||||
lightIntensity = LIGHT_INTENSITY_MAX;
|
||||
lightDistance = 4;
|
||||
} else {
|
||||
Proto* proto;
|
||||
|
|
|
@ -1494,7 +1494,7 @@ bool weaponCanBeReloadedWith(Object* weapon, Object* ammo)
|
|||
{
|
||||
if (weapon->pid == PROTO_ID_SOLAR_SCORCHER) {
|
||||
// Check light level to recharge solar scorcher.
|
||||
if (lightGetLightLevel() > 62259) {
|
||||
if (lightGetAmbientIntensity() > LIGHT_INTENSITY_MAX * 0.95) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
67
src/light.cc
67
src/light.cc
|
@ -13,50 +13,55 @@ namespace fallout {
|
|||
#define LIGHT_LEVEL_NIGHT_VISION_BONUS (65536 / 5)
|
||||
|
||||
// 0x51923C
|
||||
static int gLightLevel = LIGHT_LEVEL_MAX;
|
||||
static int gAmbientIntensity = LIGHT_INTENSITY_MAX;
|
||||
|
||||
// light intensity per elevation per tile
|
||||
// 0x59E994
|
||||
static int gLightIntensity[ELEVATION_COUNT][HEX_GRID_SIZE];
|
||||
static int gTileIntensity[ELEVATION_COUNT][HEX_GRID_SIZE];
|
||||
|
||||
// 0x47A8F0
|
||||
int lightInit()
|
||||
{
|
||||
lightResetIntensity();
|
||||
lightResetTileIntensity();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x47A8F8
|
||||
int lightGetLightLevel()
|
||||
// 0x47A8F0
|
||||
void lightReset()
|
||||
{
|
||||
return gLightLevel;
|
||||
lightResetTileIntensity();
|
||||
}
|
||||
|
||||
// 0x47A8F0
|
||||
void lightExit()
|
||||
{
|
||||
lightResetTileIntensity();
|
||||
}
|
||||
|
||||
// 0x47A8F8
|
||||
int lightGetAmbientIntensity()
|
||||
{
|
||||
return gAmbientIntensity;
|
||||
}
|
||||
|
||||
// 0x47A908
|
||||
void lightSetLightLevel(int lightLevel, bool shouldUpdateScreen)
|
||||
void lightSetAmbientIntensity(int intensity, bool shouldUpdateScreen)
|
||||
{
|
||||
int normalizedLightLevel = lightLevel + perkGetRank(gDude, PERK_NIGHT_VISION) * LIGHT_LEVEL_NIGHT_VISION_BONUS;
|
||||
int adjustedIntensity = intensity + perkGetRank(gDude, PERK_NIGHT_VISION) * LIGHT_LEVEL_NIGHT_VISION_BONUS;
|
||||
int normalizedIntensity = std::clamp(adjustedIntensity, LIGHT_INTENSITY_MIN, LIGHT_INTENSITY_MAX);
|
||||
|
||||
if (normalizedLightLevel < LIGHT_LEVEL_MIN) {
|
||||
normalizedLightLevel = LIGHT_LEVEL_MIN;
|
||||
}
|
||||
|
||||
if (normalizedLightLevel > LIGHT_LEVEL_MAX) {
|
||||
normalizedLightLevel = LIGHT_LEVEL_MAX;
|
||||
}
|
||||
|
||||
int oldLightLevel = gLightLevel;
|
||||
gLightLevel = normalizedLightLevel;
|
||||
int oldAmbientIntensity = gAmbientIntensity;
|
||||
gAmbientIntensity = normalizedIntensity;
|
||||
|
||||
if (shouldUpdateScreen) {
|
||||
if (oldLightLevel != normalizedLightLevel) {
|
||||
if (oldAmbientIntensity != normalizedIntensity) {
|
||||
tileWindowRefresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x47A980
|
||||
int _light_get_tile(int elevation, int tile)
|
||||
int lightGetTileIntensity(int elevation, int tile)
|
||||
{
|
||||
if (!elevationIsValid(elevation)) {
|
||||
return 0;
|
||||
|
@ -66,11 +71,11 @@ int _light_get_tile(int elevation, int tile)
|
|||
return 0;
|
||||
}
|
||||
|
||||
return std::min(gLightIntensity[elevation][tile], LIGHT_LEVEL_MAX);
|
||||
return std::min(gTileIntensity[elevation][tile], LIGHT_INTENSITY_MAX);
|
||||
}
|
||||
|
||||
// 0x47A9C4
|
||||
int lightGetIntensity(int elevation, int tile)
|
||||
int lightGetTrueTileIntensity(int elevation, int tile)
|
||||
{
|
||||
if (!elevationIsValid(elevation)) {
|
||||
return 0;
|
||||
|
@ -80,11 +85,11 @@ int lightGetIntensity(int elevation, int tile)
|
|||
return 0;
|
||||
}
|
||||
|
||||
return gLightIntensity[elevation][tile];
|
||||
return gTileIntensity[elevation][tile];
|
||||
}
|
||||
|
||||
// 0x47A9EC
|
||||
void lightSetIntensity(int elevation, int tile, int lightIntensity)
|
||||
void lightSetTileIntensity(int elevation, int tile, int intensity)
|
||||
{
|
||||
if (!elevationIsValid(elevation)) {
|
||||
return;
|
||||
|
@ -94,11 +99,11 @@ void lightSetIntensity(int elevation, int tile, int lightIntensity)
|
|||
return;
|
||||
}
|
||||
|
||||
gLightIntensity[elevation][tile] = lightIntensity;
|
||||
gTileIntensity[elevation][tile] = intensity;
|
||||
}
|
||||
|
||||
// 0x47AA10
|
||||
void lightIncreaseIntensity(int elevation, int tile, int lightIntensity)
|
||||
void lightIncreaseTileIntensity(int elevation, int tile, int intensity)
|
||||
{
|
||||
if (!elevationIsValid(elevation)) {
|
||||
return;
|
||||
|
@ -108,11 +113,11 @@ void lightIncreaseIntensity(int elevation, int tile, int lightIntensity)
|
|||
return;
|
||||
}
|
||||
|
||||
gLightIntensity[elevation][tile] += lightIntensity;
|
||||
gTileIntensity[elevation][tile] += intensity;
|
||||
}
|
||||
|
||||
// 0x47AA48
|
||||
void lightDecreaseIntensity(int elevation, int tile, int lightIntensity)
|
||||
void lightDecreaseTileIntensity(int elevation, int tile, int intensity)
|
||||
{
|
||||
if (!elevationIsValid(elevation)) {
|
||||
return;
|
||||
|
@ -122,15 +127,15 @@ void lightDecreaseIntensity(int elevation, int tile, int lightIntensity)
|
|||
return;
|
||||
}
|
||||
|
||||
gLightIntensity[elevation][tile] -= lightIntensity;
|
||||
gTileIntensity[elevation][tile] -= intensity;
|
||||
}
|
||||
|
||||
// 0x47AA84
|
||||
void lightResetIntensity()
|
||||
void lightResetTileIntensity()
|
||||
{
|
||||
for (int elevation = 0; elevation < ELEVATION_COUNT; elevation++) {
|
||||
for (int tile = 0; tile < HEX_GRID_SIZE; tile++) {
|
||||
gLightIntensity[elevation][tile] = 655;
|
||||
gTileIntensity[elevation][tile] = 655;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
22
src/light.h
22
src/light.h
|
@ -3,20 +3,22 @@
|
|||
|
||||
namespace fallout {
|
||||
|
||||
#define LIGHT_LEVEL_MIN (65536 / 4)
|
||||
#define LIGHT_LEVEL_MAX 65536
|
||||
#define LIGHT_INTENSITY_MIN (65536 / 4)
|
||||
#define LIGHT_INTENSITY_MAX 65536
|
||||
|
||||
typedef void AdjustLightIntensityProc(int elevation, int tile, int intensity);
|
||||
|
||||
int lightInit();
|
||||
int lightGetLightLevel();
|
||||
void lightSetLightLevel(int lightLevel, bool shouldUpdateScreen);
|
||||
int _light_get_tile(int elevation, int tile);
|
||||
int lightGetIntensity(int elevation, int tile);
|
||||
void lightSetIntensity(int elevation, int tile, int intensity);
|
||||
void lightIncreaseIntensity(int elevation, int tile, int intensity);
|
||||
void lightDecreaseIntensity(int elevation, int tile, int intensity);
|
||||
void lightResetIntensity();
|
||||
void lightReset();
|
||||
void lightExit();
|
||||
int lightGetAmbientIntensity();
|
||||
void lightSetAmbientIntensity(int intensity, bool shouldUpdateScreen);
|
||||
int lightGetTileIntensity(int elevation, int tile);
|
||||
int lightGetTrueTileIntensity(int elevation, int tile);
|
||||
void lightSetTileIntensity(int elevation, int tile, int intensity);
|
||||
void lightIncreaseTileIntensity(int elevation, int tile, int intensity);
|
||||
void lightDecreaseTileIntensity(int elevation, int tile, int intensity);
|
||||
void lightResetTileIntensity();
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
|
|
@ -924,7 +924,7 @@ static int mapLoad(File* stream)
|
|||
goto err;
|
||||
}
|
||||
|
||||
lightSetLightLevel(LIGHT_LEVEL_MAX, false);
|
||||
lightSetAmbientIntensity(LIGHT_INTENSITY_MAX, false);
|
||||
objectSetLocation(gDude, gCenterTile, gElevation, NULL);
|
||||
objectSetRotation(gDude, gEnteringRotation, NULL);
|
||||
gMapHeader.field_34 = wmMapMatchNameToIdx(gMapHeader.name);
|
||||
|
|
|
@ -379,7 +379,7 @@ void objectsReset()
|
|||
textObjectsReset();
|
||||
_obj_remove_all();
|
||||
memset(_obj_seen, 0, 5001);
|
||||
lightResetIntensity();
|
||||
lightReset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -396,7 +396,7 @@ void objectsExit()
|
|||
// NOTE: Uninline.
|
||||
_obj_blend_table_exit();
|
||||
|
||||
lightResetIntensity();
|
||||
lightExit();
|
||||
|
||||
// NOTE: Uninline.
|
||||
_obj_render_table_exit();
|
||||
|
@ -763,7 +763,7 @@ void _obj_render_pre_roof(Rect* rect, int elevation)
|
|||
return;
|
||||
}
|
||||
|
||||
int ambientLight = lightGetLightLevel();
|
||||
int ambientIntensity = lightGetAmbientIntensity();
|
||||
int minX = updatedRect.left - 320;
|
||||
int minY = updatedRect.top - 240;
|
||||
int maxX = updatedRect.right + 320;
|
||||
|
@ -804,14 +804,14 @@ void _obj_render_pre_roof(Rect* rect, int elevation)
|
|||
for (int i = 0; i < gObjectsUpdateAreaHexSize; i++) {
|
||||
int offsetIndex = *orders++;
|
||||
if (updateAreaHexHeight > _offsetDivTable[offsetIndex] && updateAreaHexWidth > _offsetModTable[offsetIndex]) {
|
||||
int light;
|
||||
int lightIntensity;
|
||||
|
||||
ObjectListNode* objectListNode = hexGridTileIsValid(topLeftTile + offsets[offsetIndex])
|
||||
? gObjectListHeadByTile[topLeftTile + offsets[offsetIndex]]
|
||||
: NULL;
|
||||
if (objectListNode != NULL) {
|
||||
// NOTE: Calls `_light_get_tile` twice.
|
||||
light = std::max(ambientLight, _light_get_tile(elevation, objectListNode->obj->tile));
|
||||
// NOTE: Calls `lightGetTileIntensity` twice.
|
||||
lightIntensity = std::max(ambientIntensity, lightGetTileIntensity(elevation, objectListNode->obj->tile));
|
||||
}
|
||||
|
||||
while (objectListNode != NULL) {
|
||||
|
@ -825,7 +825,7 @@ void _obj_render_pre_roof(Rect* rect, int elevation)
|
|||
}
|
||||
|
||||
if ((objectListNode->obj->flags & OBJECT_HIDDEN) == 0) {
|
||||
_obj_render_object(objectListNode->obj, &updatedRect, light);
|
||||
_obj_render_object(objectListNode->obj, &updatedRect, lightIntensity);
|
||||
|
||||
if ((objectListNode->obj->outline & OUTLINE_TYPE_MASK) != 0) {
|
||||
if ((objectListNode->obj->outline & OUTLINE_DISABLED) == 0 && _outlineCount < 100) {
|
||||
|
@ -845,12 +845,12 @@ void _obj_render_pre_roof(Rect* rect, int elevation)
|
|||
}
|
||||
|
||||
for (int i = 0; i < renderCount; i++) {
|
||||
int light;
|
||||
int lightIntensity;
|
||||
|
||||
ObjectListNode* objectListNode = _renderTable[i];
|
||||
if (objectListNode != NULL) {
|
||||
// NOTE: Calls `_light_get_tile` twice.
|
||||
light = std::max(ambientLight, _light_get_tile(elevation, objectListNode->obj->tile));
|
||||
// NOTE: Calls `lightGetTileIntensity` twice.
|
||||
lightIntensity = std::max(ambientIntensity, lightGetTileIntensity(elevation, objectListNode->obj->tile));
|
||||
}
|
||||
|
||||
while (objectListNode != NULL) {
|
||||
|
@ -861,7 +861,7 @@ void _obj_render_pre_roof(Rect* rect, int elevation)
|
|||
|
||||
if (elevation == objectListNode->obj->elevation) {
|
||||
if ((objectListNode->obj->flags & OBJECT_HIDDEN) == 0) {
|
||||
_obj_render_object(object, &updatedRect, light);
|
||||
_obj_render_object(object, &updatedRect, lightIntensity);
|
||||
|
||||
if ((objectListNode->obj->outline & OUTLINE_TYPE_MASK) != 0) {
|
||||
if ((objectListNode->obj->outline & OUTLINE_DISABLED) == 0 && _outlineCount < 100) {
|
||||
|
@ -1721,7 +1721,7 @@ int objectRotateCounterClockwise(Object* obj, Rect* dirtyRect)
|
|||
// 0x48AC54
|
||||
void _obj_rebuild_all_light()
|
||||
{
|
||||
lightResetIntensity();
|
||||
lightResetTileIntensity();
|
||||
|
||||
for (int tile = 0; tile < HEX_GRID_SIZE; tile++) {
|
||||
ObjectListNode* objectListNode = gObjectListHeadByTile[tile];
|
||||
|
@ -1762,22 +1762,22 @@ int objectSetLight(Object* obj, int lightDistance, int lightIntensity, Rect* rec
|
|||
// 0x48AD04
|
||||
int objectGetLightIntensity(Object* obj)
|
||||
{
|
||||
int lightLevel = lightGetLightLevel();
|
||||
int lightIntensity = lightGetIntensity(obj->elevation, obj->tile);
|
||||
int ambientIntensity = lightGetAmbientIntensity();
|
||||
int tileIntensity = lightGetTrueTileIntensity(obj->elevation, obj->tile);
|
||||
|
||||
if (obj == gDude) {
|
||||
lightIntensity -= gDude->lightIntensity;
|
||||
tileIntensity -= gDude->lightIntensity;
|
||||
}
|
||||
|
||||
if (lightIntensity >= lightLevel) {
|
||||
if (lightIntensity > 0x10000) {
|
||||
lightIntensity = 0x10000;
|
||||
if (tileIntensity >= ambientIntensity) {
|
||||
if (tileIntensity > LIGHT_INTENSITY_MAX) {
|
||||
tileIntensity = LIGHT_INTENSITY_MAX;
|
||||
}
|
||||
} else {
|
||||
lightIntensity = lightLevel;
|
||||
tileIntensity = ambientIntensity;
|
||||
}
|
||||
|
||||
return lightIntensity;
|
||||
return tileIntensity;
|
||||
}
|
||||
|
||||
// 0x48AD48
|
||||
|
@ -3993,7 +3993,7 @@ static int _obj_adjust_light(Object* obj, int a2, Rect* rect)
|
|||
return -1;
|
||||
}
|
||||
|
||||
AdjustLightIntensityProc* adjustLightIntensity = a2 ? lightDecreaseIntensity : lightIncreaseIntensity;
|
||||
AdjustLightIntensityProc* adjustLightIntensity = a2 ? lightDecreaseTileIntensity : lightIncreaseTileIntensity;
|
||||
adjustLightIntensity(obj->elevation, obj->tile, obj->lightIntensity);
|
||||
|
||||
Rect objectRect;
|
||||
|
|
10
src/tile.cc
10
src/tile.cc
|
@ -1226,7 +1226,7 @@ void tileRenderRoofsInRect(Rect* rect, int elevation)
|
|||
minY = gSquareGridHeight - 1;
|
||||
}
|
||||
|
||||
int light = lightGetLightLevel();
|
||||
int light = lightGetAmbientIntensity();
|
||||
|
||||
int baseSquareTile = gSquareGridWidth * minY;
|
||||
|
||||
|
@ -1449,7 +1449,7 @@ void tileRenderFloorsInRect(Rect* rect, int elevation)
|
|||
minY = gSquareGridHeight - 1;
|
||||
}
|
||||
|
||||
lightGetLightLevel();
|
||||
lightGetAmbientIntensity();
|
||||
|
||||
int baseSquareTile = gSquareGridWidth * minY;
|
||||
|
||||
|
@ -1660,10 +1660,10 @@ static void tileRenderFloor(int fid, int x, int y, Rect* rect)
|
|||
tile = tileFromScreenXY(savedX, savedY + 13, gElevation);
|
||||
if (tile != -1) {
|
||||
int parity = tile & 1;
|
||||
int ambientIntensity = lightGetLightLevel();
|
||||
int ambientIntensity = lightGetAmbientIntensity();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
// NOTE: Calls `_light_get_tile` twice.
|
||||
_verticies[i].intensity = std::max(_light_get_tile(elev, tile + _verticies[i].offsets[parity]), ambientIntensity);
|
||||
// NOTE: Calls `lightGetTileIntensity` twice.
|
||||
_verticies[i].intensity = std::max(lightGetTileIntensity(elev, tile + _verticies[i].offsets[parity]), ambientIntensity);
|
||||
}
|
||||
|
||||
int v23 = 0;
|
||||
|
|
Loading…
Reference in New Issue