diff --git a/docs/sdk/script/fn/GetLightColor.xml b/docs/sdk/script/fn/GetLightColor.xml
new file mode 100644
index 000000000..5ef268880
--- /dev/null
+++ b/docs/sdk/script/fn/GetLightColor.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ GetLightColor
+ Objects
+ 7.0 OC
+ int
+ Gets the RGB color value of the light that the object emits. The color can be changed with SetLightColor.
+
+ SetLightColor
+ SetLightRange
+
+
+ Marky2015-06
+
diff --git a/docs/sdk/script/fn/SetLightColor.xml b/docs/sdk/script/fn/SetLightColor.xml
new file mode 100644
index 000000000..804b4bb21
--- /dev/null
+++ b/docs/sdk/script/fn/SetLightColor.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+ SetLightColor
+ Objects
+ 7.0 OC
+
+ void
+
+
+ int
+ color
+ New color for the light. The color value (V in HSV notation of the color) determines the intensity of the light. A light color of RGB(128, 0, 0)
has a value/intensity of 50%. This means that it will be weaker than a light withRGB(255, 0, 0)
, but it will cover the same area as that light.
+
+
+
+ Sets the color of the light that is emitted from this object. By default the object emits white light, if it has a light range. See SetLightRange for further details.
+
+
+
+ var candle_shine=CreateObject(EnvPack_Candle_Shine);
+ candle_shine->SetLightRange(30, 20);
+ candle_shine->SetLightColor(RGB(255,163,58));
+
+ Gives a warm shine to a candle shine object.
+
+
+
+ GetLightColor
+ SetLightRange
+
+
+ Marky2015-06
+
diff --git a/docs/sdk/script/fn/SetLightRange.xml b/docs/sdk/script/fn/SetLightRange.xml
index e5f3d2420..01cf6cec1 100644
--- a/docs/sdk/script/fn/SetLightRange.xml
+++ b/docs/sdk/script/fn/SetLightRange.xml
@@ -38,6 +38,7 @@
SetPlrView
SetFoW
+ SetLightColor
diff --git a/planet/Graphics.ocg/LightShader.glsl b/planet/Graphics.ocg/LightShader.glsl
index 8d33ed10a..6eba1e256 100644
--- a/planet/Graphics.ocg/LightShader.glsl
+++ b/planet/Graphics.ocg/LightShader.glsl
@@ -10,24 +10,46 @@ uniform sampler2D lightTex;
// brightness: light strength
//#define LIGHT_DEBUG
+// uncomment the following lines for debugging light color:
+// the light will always come from the front and have a uniform brightness.
+//#define LIGHT_DEBUG_COLOR
+
+// uncomment the following lines to set the light color to pink for all lights for debugging:
+//#define LIGHT_DEBUG_PINK
+
// At what point of light intensity we set the "darkness" point. This
-// is to compensate for the fact that the engien "smoothes" the light
+// is to compensate for the fact that the engine "smooths" the light
// and therefore will often never arrive at 0 light intensity.
const float lightDarknessLevel = 8.0 / 256.0;
slice(texture+5)
{
#ifdef HAVE_LIGHT
+
// Query light texture
- vec4 lightPx = texture2D(lightTex, lightCoord.st);
+ vec2 lightDirCoord = lightCoord.st;
+
+ vec4 lightPx = texture2D(lightTex, lightDirCoord);
float lightBright = max(0.0, lightPx.x-lightDarknessLevel);
- vec3 lightDir = extend_normal(vec2(1.0, 1.0) - lightPx.yz * 3.0);
+ vec3 lightDir = extend_normal(vec2(1.0, 1.0) - lightPx.yz * 3.0);
+
+ // Query light color texture (part of the light texture)
+ vec2 lightColorCoord = lightCoord.st - vec2(0.0, 0.5); // subtract offset for the color texture
+
+ vec4 lightColor = texture2D(lightTex, lightColorCoord.st);
+
+ #ifdef LIGHT_DEBUG_COLOR
+ lightBright = 0.5;
+ lightDir = vec3(0.0, 0.0, 1.0);
+ #endif
#else
// When lighting is disabled, put a light source coming from the camera.
// Note that in most cases this does not actually matter, since in the
// case with lighting disabled, ambient lighting takes fully over.
float lightBright = 0.5;
- vec3 lightDir = vec3(0.0, 0.0, 1.0);
+ vec3 lightDir = vec3(0.0, 0.0, 1.0);
+
+ vec4 lightColor = vec4(1.0, 1.0, 1.0, 1.0);
#endif
}
@@ -41,10 +63,17 @@ slice(light)
slice(color+5)
{
+ // pink shade for debugging!
+ #ifdef LIGHT_DEBUG_PINK
+ lightColor = vec4(1.0, 0.0, 1.0, 1.0);
+ #endif
+
+ lightColor.rgb = sqrt(3.0) * normalize(lightColor.rgb);
+
// Add light
- color = vec4(light * color.rgb, color.a);
+ color = vec4(light * color.rgb * lightColor.rgb, color.a);
#ifdef HAVE_2PX
- color2 = vec4(light2 * color2.rgb, color2.a);
+ color2 = vec4(light2 * color2.rgb * lightColor.rgb, color2.a);
#endif
}
diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Map.bmp b/planet/Tests.ocf/ColorfulLights.ocs/Map.bmp
new file mode 100644
index 000000000..bd9ed8d7d
Binary files /dev/null and b/planet/Tests.ocf/ColorfulLights.ocs/Map.bmp differ
diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/TEXMAP.TXT b/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/TEXMAP.TXT
new file mode 100644
index 000000000..bc470fe44
--- /dev/null
+++ b/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/TEXMAP.TXT
@@ -0,0 +1,53 @@
+# Static Map Material/Texture Table
+# Index +128 for underground materials
+
+1=Vehicle-none
+
+8=Tunnel-brickback3
+9=Tunnel-brickback2
+10=Tunnel-tunnel
+12=Tunnel-brickback
+
+13=BrickSoft-brick1
+
+19=DuroLava-lava_red
+20=Water-water1-water2-water3-water1-water3-water2
+22=Acid-acid
+23=Lava-lava_red
+25=Water-water
+
+28=Earth-earth
+29=Earth-earth_dry
+30=Earth-earth_rough
+31=Earth-earth_topsoil
+32=Earth-earth_midsoil
+33=Ashes-ashes
+35=SandDry-sand_rough
+
+36=Ore-ore
+
+40=Granite-granite
+42=Granite-rock
+
+45=Gold-gold
+
+50=Rock-rock
+51=Rock-rock_cracked
+
+53=Firestone-firestone
+
+54=Coal-coal
+
+55=Sand-sand_rough
+56=Sand-sand_smooth
+
+65=Ice-ice2
+67=Ice-ice3
+
+70=Snow-snow1
+
+73=Brick-brick1
+74=Brick-brick2
+
+OverloadMaterials
+OverloadTextures
diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/brick2.png b/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/brick2.png
new file mode 100644
index 000000000..8ba865d91
Binary files /dev/null and b/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/brick2.png differ
diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/brickback2.png b/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/brickback2.png
new file mode 100644
index 000000000..9da9a48dd
Binary files /dev/null and b/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/brickback2.png differ
diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/brickback2.psd b/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/brickback2.psd
new file mode 100644
index 000000000..9d50fd54f
Binary files /dev/null and b/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/brickback2.psd differ
diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/brickback3.png b/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/brickback3.png
new file mode 100644
index 000000000..3f28fe724
Binary files /dev/null and b/planet/Tests.ocf/ColorfulLights.ocs/Material.ocg/brickback3.png differ
diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Objects.c b/planet/Tests.ocf/ColorfulLights.ocs/Objects.c
new file mode 100644
index 000000000..d26510d8a
--- /dev/null
+++ b/planet/Tests.ocf/ColorfulLights.ocs/Objects.c
@@ -0,0 +1,304 @@
+/* Automatically created objects file */
+
+static g_ruin1, g_ruin2, g_ruin3, g_elev2, g_elev1, g_cannon, g_king, g_farmer, g_cannoneer;
+
+func InitializeObjects()
+{
+ var Grass001 = CreateObjectAbove(Grass, 396, 1149);
+ Grass001->SetClrModulation(0xffa08060);
+ var Grass002 = CreateObjectAbove(Grass, 232, 1181);
+ Grass002->SetClrModulation(0xffa08060);
+ var Grass003 = CreateObjectAbove(Grass, 228, 1180);
+ Grass003->SetClrModulation(0xffa08060);
+
+ var Rule_BaseRespawn001 = CreateObject(Rule_BaseRespawn);
+ Rule_BaseRespawn001->SetInventoryTransfer(true);
+ Rule_BaseRespawn001->SetFreeCrew(true);
+
+ var Tree_Coniferous_Burned001 = CreateObject(Tree_Coniferous_Burned, 17, 1097);
+ Tree_Coniferous_Burned001->SetR(10);
+ var Tree_Coniferous_Burned002 = CreateObject(Tree_Coniferous_Burned, 43, 1246);
+ Tree_Coniferous_Burned002->SetCon(75);
+ Tree_Coniferous_Burned002->SetR(100);
+
+ var Tree_Coniferous001 = CreateObject(Tree_Coniferous, 415, 1117);
+ Tree_Coniferous001->SetR(10);
+ Tree_Coniferous001->SetClrModulation(0xffc08060);
+
+ var Branch001 = CreateObject(Branch, 241, 1176);
+ Branch001->SetR(17);
+
+ var Fern001 = CreateObjectAbove(Fern, 312, 1432);
+ Fern001->SetClrModulation(0xffa08060);
+
+ var LargeCaveMushroom001 = CreateObjectAbove(LargeCaveMushroom, 1355, 1451);
+ LargeCaveMushroom001->SetClrModulation(0xffcddfdf);
+ var LargeCaveMushroom002 = CreateObject(LargeCaveMushroom, 1308, 1384);
+ LargeCaveMushroom002->SetR(180);
+ LargeCaveMushroom002->SetClrModulation(0xffdae7dc);
+ var LargeCaveMushroom003 = CreateObjectAbove(LargeCaveMushroom, 1411, 1447);
+ LargeCaveMushroom003->SetClrModulation(0xffe9d5dd);
+ var LargeCaveMushroom004 = CreateObject(LargeCaveMushroom, 1420, 1374);
+ LargeCaveMushroom004->SetR(160);
+ LargeCaveMushroom004->SetClrModulation(0xffeaedfb);
+
+ var Branch002 = CreateObject(Branch, 1430, 1417);
+ Branch002->SetR(-25);
+
+ var Lichen001 = CreateObjectAbove(Lichen, 1387, 1440);
+ Lichen001->SetAction("Grown");
+ var Lichen002 = CreateObjectAbove(Lichen, 1310, 1456);
+ Lichen002->SetAction("Grown");
+ var Lichen003 = CreateObjectAbove(Lichen, 1466, 1415);
+ Lichen003->SetAction("Grown");
+
+ var Trunk001 = CreateObject(Trunk, 217, 1159);
+ Trunk001->SetR(-10);
+
+ var EnvPack_Bag001 = CreateObjectAbove(EnvPack_Bag, 846, 885);
+ EnvPack_Bag001->SetClrModulation(0xffa0a0a0);
+ CreateObjectAbove(EnvPack_Bag, 840, 888);
+ CreateObjectAbove(EnvPack_Bag, 844, 888);
+
+ CreateObjectAbove(EnvPack_BridgeRustic, 1096, 673);
+ CreateObjectAbove(EnvPack_Candle, 1054, 672);
+ CreateObjectAbove(EnvPack_Candle, 1054, 575);
+ CreateObjectAbove(EnvPack_Candle, 1185, 616);
+ CreateObjectAbove(EnvPack_Candle, 1531, 448);
+ CreateObjectAbove(EnvPack_Candle, 1362, 432);
+ CreateObjectAbove(EnvPack_CandleSmall, 1556, 432);
+ CreateObjectAbove(EnvPack_Crate, 1017, 576);
+
+ CreateObjectAbove(EnvPack_FenceRustic, 1111, 728);
+ CreateObjectAbove(EnvPack_FenceRustic, 1089, 735);
+
+ CreateObjectAbove(EnvPack_Guidepost, 315, 1167);
+
+ CreateObjectAbove(EnvPack_Lantern, 894, 488);
+ CreateObjectAbove(EnvPack_Lantern, 1291, 472);
+ CreateObjectAbove(EnvPack_Painting, 1235, 537);
+
+ CreateObjectAbove(EnvPack_Rail, 1121, 672);
+
+ CreateObjectAbove(EnvPack_Scarecrow, 204, 1185);
+
+ CreateObject(EnvPack_TreeTrunks, 788, 888);
+
+ CreateObjectAbove(EnvPack_WineBarrel, 1438, 552);
+ CreateObjectAbove(EnvPack_WineBarrel, 1455, 553);
+
+ CreateObjectAbove(EnvPack_Candle, 1471, 552);
+
+ CreateObject(Rule_TeamAccount);
+
+ CreateObject(Rule_NoPowerNeed);
+
+ var LargeCaveMushroom005 = CreateObjectAbove(LargeCaveMushroom, 1334, 1459);
+ LargeCaveMushroom005->SetClrModulation(0xffd0dbdf);
+ var LargeCaveMushroom006 = CreateObjectAbove(LargeCaveMushroom, 1396, 1451);
+ LargeCaveMushroom006->SetClrModulation(0xffe7e6f0);
+ var LargeCaveMushroom007 = CreateObjectAbove(LargeCaveMushroom, 1426, 1437);
+ LargeCaveMushroom007->SetClrModulation(0xffcfcbe5);
+
+ var Fern002 = CreateObject(Fern, 276, 1442);
+ Fern002->SetCon(22);
+
+ CreateObjectAbove(Tree_Coniferous, 408, 1167);
+ var Tree_Coniferous002 = CreateObject(Tree_Coniferous, 408, 1191);
+ Tree_Coniferous002->SetCon(47);
+ var Tree_Coniferous003 = CreateObjectAbove(Tree_Coniferous, 217, 1191);
+ Tree_Coniferous003->SetCon(39);
+ var Tree_Coniferous004 = CreateObject(Tree_Coniferous, 392, 1148);
+ Tree_Coniferous004->SetCon(27);
+ var Tree_Coniferous005 = CreateObject(Tree_Coniferous, 410, 1168);
+ Tree_Coniferous005->SetCon(3);
+
+ g_ruin1 = CreateObject(Ruin_WoodenCabin, 97, 1150);
+ g_ruin1->SetR(16);
+ g_ruin1.StaticSaveVar = "g_ruin1";
+
+ g_ruin2 = CreateObjectAbove(Ruin_Windmill, 353, 1145);
+ g_ruin2.StaticSaveVar = "g_ruin2";
+
+ g_ruin3 = CreateObjectAbove(Ruin_ChemicalLab, 267, 1180);
+ g_ruin3.StaticSaveVar = "g_ruin3";
+
+ CreateObjectAbove(Foundry, 238, 1287);
+
+ var Chest002 = CreateObjectAbove(Chest, 1475, 1415);
+ var Chest006 = CreateObjectAbove(Chest, 1574, 583);
+ var Chest005 = CreateObjectAbove(Chest, 823, 887);
+ var Chest001 = CreateObjectAbove(Chest, 856, 887);
+ var Chest003 = CreateObjectAbove(Chest, 1032, 575);
+ var Chest004 = CreateObjectAbove(Chest, 136, 103);
+
+ var StoneDoor001 = CreateObject(StoneDoor, 940, 652);
+ StoneDoor001->SetComDir(COMD_Down);
+ var StoneDoor002 = CreateObject(StoneDoor, 1348, 508);
+ StoneDoor002->SetComDir(COMD_Down);
+ var StoneDoor003 = CreateObject(StoneDoor, 1347, 412);
+ StoneDoor003->SetComDir(COMD_Down);
+
+ var SpinWheel001 = CreateObjectAbove(SpinWheel, 961, 672);
+ SpinWheel001->SetStoneDoor(StoneDoor001);
+ var SpinWheel002 = CreateObjectAbove(SpinWheel, 1367, 527);
+ SpinWheel002->SetStoneDoor(StoneDoor002);
+ var SpinWheel003 = CreateObjectAbove(SpinWheel, 1384, 471);
+ SpinWheel003->SetStoneDoor(StoneDoor003);
+
+ CreateObject(Column, 1197, 551);
+ CreateObject(Column, 1218, 463);
+
+ CreateObjectAbove(Idol, 1080, 575);
+
+ var SteamEngine001 = CreateObjectAbove(SteamEngine, 1529, 585);
+
+ var Flagpole001 = CreateObjectAbove(Flagpole, 135, 1182);
+ Flagpole001->SetNeutral(true);
+
+ g_elev2 = CreateObjectAbove(Elevator, 1366, 614);
+ g_elev2.StaticSaveVar = "g_elev2";
+ g_elev2->CreateShaft(477);
+ g_elev2->SetCasePosition(1079);
+ g_elev1 = CreateObjectAbove(Elevator, 167, 1184);
+ g_elev1.StaticSaveVar = "g_elev1";
+ g_elev1->SetClrModulation(0xffa08060);
+ g_elev1->CreateShaft(95);
+ g_elev1->SetCasePosition(1267);
+ var Catapult001 = CreateObjectAbove(Catapult, 697, 887);
+ Catapult001->SetRDir(-7);
+
+ var Lorry001 = CreateObject(Lorry, 149, 1314);
+ Lorry001->SetR(24);
+ var Lorry002 = CreateObject(Lorry, 1425, 1244);
+ Lorry002->SetR(-36);
+
+ CreateObjectAbove(Airship_Burnt, 38, 1152);
+
+
+ CreateObject(Rock, 879, 1002);
+ CreateObjectAbove(Rock, 262, 1182);
+ CreateObjectAbove(Rock, 140, 1183);
+ CreateObjectAbove(Rock, 48, 1151);
+ CreateObject(Rock, 154, 1205);
+ CreateObject(Rock, 154, 1205);
+ CreateObjectAbove(Rock, 241, 1287);
+ CreateObject(Rock, 338, 1256);
+ CreateObject(Rock, 661, 1392);
+ CreateObjectAbove(Rock, 813, 887);
+ CreateObject(Rock, 893, 1290);
+ CreateObject(Rock, 1248, 1087);
+ CreateObject(Rock, 1334, 1011);
+ CreateObject(Rock, 1268, 932);
+ CreateObject(Rock, 1298, 795);
+ CreateObject(Rock, 1501, 932);
+ CreateObject(Rock, 1473, 675);
+ CreateObject(Rock, 1367, 654);
+ CreateObject(Rock, 1505, 1162);
+ CreateObject(Rock, 1482, 1049);
+ CreateObject(Rock, 1402, 1447);
+ CreateObject(Rock, 1025, 1392);
+ CreateObject(Rock, 742, 1521);
+ CreateObject(Rock, 712, 1350);
+ CreateObject(Rock, 1047, 1206);
+
+ CreateObject(Ore, 227, 1365);
+ CreateObjectAbove(Ore, 64, 1421);
+ CreateObject(Ore, 264, 1453);
+ CreateObject(Ore, 462, 1478);
+ CreateObject(Ore, 77, 1485);
+ CreateObject(Ore, 1481, 1448);
+ CreateObject(Ore, 1438, 1463);
+ CreateObject(Ore, 1566, 1561);
+
+ CreateObject(Nugget, 1079, 1216);
+ CreateObject(Nugget, 1244, 1138);
+ CreateObject(Nugget, 1156, 1163);
+ CreateObject(Nugget, 1127, 1165);
+
+ var GoldBar001 = CreateObject(GoldBar, 1293, 1235);
+ GoldBar001->SetR(22);
+
+ CreateObjectAbove(Airship, 931, 495);
+
+ var Barrel001 = CreateObject(Barrel, 167, 1327);
+ Barrel001->SetR(-13);
+ Barrel001->SetColor(0xff000000);
+ var Barrel002 = Chest002->CreateContents(Barrel);
+ Barrel002->SetColor(0xff000000);
+
+ CreateObjectAbove(Seaweed, 169, 1543);
+ CreateObjectAbove(Seaweed, 815, 1342);
+ CreateObjectAbove(Seaweed, 719, 1078);
+ CreateObjectAbove(Seaweed, 772, 1087);
+ CreateObjectAbove(Seaweed, 1258, 1279);
+ var Seaweed001 = CreateObject(Seaweed, 592, 1425);
+ Seaweed001->SetCon(1);
+ var Seaweed002 = CreateObject(Seaweed, 652, 1304);
+ Seaweed002->SetCon(1);
+ var Seaweed003 = CreateObject(Seaweed, 182, 1575);
+ Seaweed003->SetCon(1);
+ var Seaweed004 = CreateObjectAbove(Seaweed, 353, 1558);
+ Seaweed004->SetCon(1);
+ var Seaweed005 = CreateObject(Seaweed, 435, 1239);
+ Seaweed005->SetCon(1);
+ var Seaweed006 = CreateObject(Seaweed, 461, 1252);
+ Seaweed006->SetCon(1);
+ var Seaweed007 = CreateObject(Seaweed, 490, 1303);
+ Seaweed007->SetCon(1);
+ var Seaweed008 = CreateObject(Seaweed, 515, 1365);
+ Seaweed008->SetCon(1);
+
+ CreateObjectAbove(Mushroom, 126, 1320);
+ CreateObjectAbove(Mushroom, 212, 1288);
+ CreateObjectAbove(Mushroom, 367, 1392);
+ CreateObjectAbove(Mushroom, 268, 1432);
+ CreateObject(Mushroom, 247, 1303);
+ CreateObject(Mushroom, 384, 1419);
+ var Mushroom001 = CreateObject(Mushroom, 184, 1314);
+ Mushroom001->SetCon(98);
+ var Mushroom002 = CreateObject(Mushroom, 195, 1314);
+ Mushroom002->SetCon(95);
+ var Mushroom003 = CreateObject(Mushroom, 215, 1315);
+ Mushroom003->SetCon(92);
+ var Mushroom004 = CreateObject(Mushroom, 205, 1296);
+ Mushroom004->SetCon(46);
+ var Mushroom005 = CreateObject(Mushroom, 409, 1436);
+ Mushroom005->SetCon(33);
+ var Mushroom006 = CreateObject(Mushroom, 396, 1410);
+ Mushroom006->SetCon(13);
+
+ // lava
+ var light01 = CreateObject(Rock, 520, 1210);
+ light01->SetCategory(C4D_StaticBack);
+ light01->SetLightRange(100, 100);
+ light01->SetLightColor(RGB(255,144,16));
+ light01.Visibility = VIS_None;
+
+ // candles
+ for (var candle_shine in FindObjects(Find_ID(EnvPack_Candle_Shine)))
+ {
+ candle_shine->SetLightRange(30, 20);
+ candle_shine->SetLightColor(RGB(255,163,58));
+ }
+
+ // large cave mushroom
+ LargeCaveMushroom003->SetLightRange(80,50);
+ LargeCaveMushroom003->SetLightColor(RGB(0,100,0));
+ Object(17)->SetLightRange(80,50);
+ Object(17)->SetLightColor(RGB(0,100,0));
+
+ // small cave mushrooms
+ for (var mushroom in FindObjects(Find_ID(Mushroom), Find_InRect(160, 1240, 200, 60)))
+ {
+ mushroom->SetLightColor(RGB(100,0,0));
+ mushroom->SetLightRange(50,30);
+ }
+
+ Object(463)->SetLightRange(50,10);
+ Object(463)->SetLightColor(RGB(100,0,200));
+ Object(13)->SetLightRange(50,10);
+ Object(13)->SetLightColor(RGB(100,200,0));
+
+ return true;
+}
diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Scenario.txt b/planet/Tests.ocf/ColorfulLights.ocs/Scenario.txt
new file mode 100644
index 000000000..4ff0c6a17
--- /dev/null
+++ b/planet/Tests.ocf/ColorfulLights.ocs/Scenario.txt
@@ -0,0 +1,37 @@
+[Head]
+Icon=36
+Title=ColorfulLights
+Version=6,0
+Difficulty=45
+NoInitialize=true
+
+[Definitions]
+Definition1=Objects.ocd
+Definition2=Decoration.ocd
+
+[Game]
+Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1;Rule_BaseRespawn=1;
+
+[Player1]
+Knowledge=ToolsWorkshop=1;Foundry=1;Flagpole=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;Sword=1;Metal=1;GoldBar=1;Balloon=1;Boompack=1;GrappleBow=1;JarOfWinds=1;Pipe=1;Pump=1;PowderKeg=1;Ropeladder=1;Bow=1;Arrow=1;Club=1;IronBomb=1;Javelin=1;Shield=1;InventorsLab=1;Sawmill=1;BombArrow=1;FireArrow=1;GrenadeLauncher=1;Torch=1;
+
+[Player2]
+Knowledge=ToolsWorkshop=1;Foundry=1;Flagpole=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;Sword=1;Metal=1;GoldBar=1;Balloon=1;Boompack=1;GrappleBow=1;JarOfWinds=1;Pipe=1;Pump=1;PowderKeg=1;Ropeladder=1;Bow=1;Arrow=1;Club=1;IronBomb=1;Javelin=1;Shield=1;InventorsLab=1;Sawmill=1;BombArrow=1;FireArrow=1;GrenadeLauncher=1;Torch=1;
+
+[Player3]
+Knowledge=ToolsWorkshop=1;Foundry=1;Flagpole=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;Sword=1;Metal=1;GoldBar=1;Balloon=1;Boompack=1;GrappleBow=1;JarOfWinds=1;Pipe=1;Pump=1;PowderKeg=1;Ropeladder=1;Bow=1;Arrow=1;Club=1;IronBomb=1;Javelin=1;Shield=1;InventorsLab=1;Sawmill=1;BombArrow=1;FireArrow=1;GrenadeLauncher=1;Torch=1;
+
+[Player4]
+Knowledge=ToolsWorkshop=1;Foundry=1;Flagpole=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;Sword=1;Metal=1;GoldBar=1;Balloon=1;Boompack=1;GrappleBow=1;JarOfWinds=1;Pipe=1;Pump=1;PowderKeg=1;Ropeladder=1;Bow=1;Arrow=1;Club=1;IronBomb=1;Javelin=1;Shield=1;InventorsLab=1;Sawmill=1;BombArrow=1;FireArrow=1;GrenadeLauncher=1;Torch=1;
+
+[Landscape]
+Sky=Clouds2
+MapWidth=200,0,64,10000
+MapHeight=200,0,40,10000
+NoScan=true
+FlatChunkShapes=0
+
+[Weather]
+Climate=0,10,0,100
+YearSpeed=0,0,0,100
+Wind=0,100,-100,100
diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Script.c b/planet/Tests.ocf/ColorfulLights.ocs/Script.c
new file mode 100644
index 000000000..32e62916b
--- /dev/null
+++ b/planet/Tests.ocf/ColorfulLights.ocs/Script.c
@@ -0,0 +1,65 @@
+/**
+ Evil Castle
+ Desc
+
+ @authors Sven2
+*/
+
+static g_is_initialized;
+
+static g_ruin1, g_ruin2, g_ruin3, g_elev1, g_elev2, g_farmer, g_king;
+static npc_pyrit, g_cannon, g_cannoneer;
+
+func DoInit(int first_player)
+{
+ // Message when first player enters shroom area
+ ScheduleCall(nil, Scenario.ShroomCaveCheck, 21, 0xffffff);
+ // Scorching village
+ g_ruin1->AddScorch(-20,-10, -45, 50, 1500);
+ g_ruin2->AddScorch(-15,42, 90, 50, 1200);
+ g_ruin3->AddScorch(-12,18, 130, 80, 1300);
+ // Update AI stuff
+ var fx;
+ for (var enemy in FindObjects(Find_ID(Clonk), Find_Owner(NO_OWNER)))
+ if (fx = S2AI->GetAI(enemy))
+ {
+ fx.weapon = fx.target = nil;
+ S2AI->BindInventory(enemy);
+ enemy->DoEnergy(10000);
+ enemy->AddEnergyBar();
+ }
+ return true;
+}
+
+func InitializePlayer(int plr)
+{
+ // Players only
+ if (GetPlayerType(plr)!=C4PT_User) return;
+ // Scenario init
+ if (!g_is_initialized) g_is_initialized = DoInit(plr);
+ // Harsh zoom range
+ for (var flag in [PLRZOOM_LimitMax, PLRZOOM_Direct])
+ SetPlayerZoomByViewRange(plr,400,250,flag);
+ SetPlayerViewLock(plr, true);
+ // Initial join
+ var crew = GetCrew(plr);
+ crew->SetPosition(35 + Random(10) , 1140);
+ crew->SetDir(DIR_Right);
+ crew->CreateContents(Shovel);
+ crew->CreateContents(Hammer);
+ crew->CreateContents(Axe);
+ crew->SetLightRange(100, 80);
+ crew->SetLightColor(RGB(0,0,200));
+ return true;
+}
+
+
+/* Mushroom cave encounter */
+
+func ShroomCaveCheck()
+{
+ var intruder = FindObject(Find_InRect(1252,1342,320,138), Find_OCF(OCF_CrewMember));
+ if (!intruder) return true;
+ ClearScheduleCall(nil, Scenario.ShroomCaveCheck);
+ return true;
+}
diff --git a/planet/Tests.ocf/ColorfulLights.ocs/System.ocg/Scorches.c b/planet/Tests.ocf/ColorfulLights.ocs/System.ocg/Scorches.c
new file mode 100644
index 000000000..fac1ce5a2
--- /dev/null
+++ b/planet/Tests.ocf/ColorfulLights.ocs/System.ocg/Scorches.c
@@ -0,0 +1,24 @@
+global func AddScorch(int x, int y, int r, int strength, int duration)
+{
+ var scorch = CreateObjectAbove(Wood, x,y, NO_OWNER);
+ if (!scorch) return nil;
+ scorch->SetObjectLayer(scorch);
+ scorch->SetR(r);
+ scorch->SetClrModulation(0x80804000);
+ scorch->SetCategory(C4D_StaticBack);
+ scorch.Collectible = false; // SetObjectLayer is not enough...
+ scorch.Plane = this.Plane+1;
+ var fx = AddEffect("FireScorching", scorch, 1, 2, scorch);
+ fx.strength = strength;
+ fx.duration = duration;
+ return scorch;
+}
+
+global func FxFireScorchingTimer(object target, proplist effect, int time)
+{
+ if (time >= effect.duration) { RemoveObject(); return FX_Execute_Kill; }
+ // particles
+ var wind = BoundBy(GetWind(), -5, 5);
+ CreateParticle("SmokeDirty", PV_Random(-5, 5), PV_Random(-5, 5), wind, -effect.strength/8, PV_Random(20, 40), Particles_SmokeTrail(), 2);
+ return FX_OK;
+}
diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Teams.txt b/planet/Tests.ocf/ColorfulLights.ocs/Teams.txt
new file mode 100644
index 000000000..e0f02c84a
--- /dev/null
+++ b/planet/Tests.ocf/ColorfulLights.ocs/Teams.txt
@@ -0,0 +1,4 @@
+[Teams]
+Active=false
+Custom=false
+AutoGenerateTeams=true
diff --git a/planet/Tests.ocf/ColorfulLights.ocs/Title.txt b/planet/Tests.ocf/ColorfulLights.ocs/Title.txt
new file mode 100644
index 000000000..a8f207fa2
--- /dev/null
+++ b/planet/Tests.ocf/ColorfulLights.ocs/Title.txt
@@ -0,0 +1,2 @@
+DE:Farbiges Licht
+US:Colorful lights
\ No newline at end of file
diff --git a/src/landscape/fow/C4FoW.cpp b/src/landscape/fow/C4FoW.cpp
index be9019bd8..b24003286 100644
--- a/src/landscape/fow/C4FoW.cpp
+++ b/src/landscape/fow/C4FoW.cpp
@@ -71,9 +71,9 @@ void C4FoW::Add(C4Object *pObj)
if (pLight)
{
- // Update reach
+ // Update reach and light color
pLight->SetReach(pObj->lightRange, pObj->lightFadeoutRange);
-
+ pLight->SetColor(pObj->lightColor);
}
else
{
diff --git a/src/landscape/fow/C4FoWDrawStrategy.cpp b/src/landscape/fow/C4FoWDrawStrategy.cpp
index cc55c0913..9fd89c4cc 100644
--- a/src/landscape/fow/C4FoWDrawStrategy.cpp
+++ b/src/landscape/fow/C4FoWDrawStrategy.cpp
@@ -22,6 +22,13 @@
#include "C4FoWRegion.h"
#include "C4DrawGL.h"
+enum C4DrawPass
+{
+ C4DP_First = 0,
+ C4DP_Second = 1,
+ C4DP_Color = 2,
+ C4DP_Last
+};
void C4FoWDrawLightTextureStrategy::Begin(int32_t passPar)
{
@@ -29,24 +36,40 @@ void C4FoWDrawLightTextureStrategy::Begin(int32_t passPar)
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ float width = region->getSurface()->Wdt;
+ float height = region->getSurface()->Hgt / 2.0;
+
// Set up blend equation, see C4FoWDrawLightTextureStrategy::DrawVertex
// for details.
- if(pass == 0)
+ switch (pass)
{
- glBlendFunc(GL_ONE, GL_ONE);
- glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
- }
- else if(pass == 1)
- {
- glBlendFunc(GL_ONE, GL_ONE);
- glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
+ case C4DP_First:
+ glBlendFunc(GL_ONE, GL_ONE);
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
+ glScissor(0, height, width, height);
+ break;
+ case C4DP_Second:
+ glBlendFunc(GL_ONE, GL_ONE);
+ glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
+ glScissor(0, height, width, height);
+ break;
+ case C4DP_Color:
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendEquation(GL_FUNC_ADD);
+ glScissor(0, 0, width, height);
+ break;
+ default:
+ assert(false);
+ break;
}
+ glEnable(GL_SCISSOR_TEST);
}
void C4FoWDrawLightTextureStrategy::End(int32_t pass)
{
glBlendEquation( GL_FUNC_ADD );
+ glDisable(GL_SCISSOR_TEST);
}
void C4FoWDrawLightTextureStrategy::DrawVertex(float x, float y, bool shadow)
@@ -76,27 +99,58 @@ void C4FoWDrawLightTextureStrategy::DrawVertex(float x, float y, bool shadow)
// G_new = BoundBy(BoundBy(G_old + G / 1.5), 0.0, 1.0) - 0.5 / 1.5, 0.0, 1.0)
// B_new = BoundBy(BoundBy(B_old + B / 1.5), 0.0, 1.0) - 0.5 / 1.5, 0.0, 1.0)
- if (pass > 0)
- glColor3f(0.0f, 0.5f/1.5f, 0.5f/1.5f);
- else if (shadow)
+ float y_offset = 0.0f;
+
+ switch (pass)
{
- float dx = x - light->getX();
- float dy = y - light->getY();
- float dist = sqrt(dx*dx+dy*dy);
- float bright = light->getBrightness();
- float mult = Min(0.5f / light->getNormalSize(), 0.5f / dist);
- float normX = Clamp(0.5f + dx * mult, 0.0f, 1.0f) / 1.5f;
- float normY = Clamp(0.5f + dy * mult, 0.0f, 1.0f) / 1.5f;
- glColor3f(bright, normX, normY);
+ case C4DP_First:
+ if (shadow)
+ {
+ float dx = x - light->getX();
+ float dy = y - light->getY();
+ float dist = sqrt(dx*dx + dy*dy);
+ float bright = light->getBrightness();
+ float mult = Min(0.5f / light->getNormalSize(), 0.5f / dist);
+ float normX = Clamp(0.5f + dx * mult, 0.0f, 1.0f) / 1.5f;
+ float normY = Clamp(0.5f + dy * mult, 0.0f, 1.0f) / 1.5f;
+ glColor4f(bright, normX, normY, 0.0f);
+ }
+ else
+ {
+ glColor4f(0.0f, 0.5f / 1.5f, 0.5f / 1.5f, 0.0f);
+ }
+ break;
+ case C4DP_Second:
+ glColor4f(0.0f, 0.5f / 1.5f, 0.5f / 1.5f, 0.5f);
+ break;
+ case C4DP_Color: // has a block so that alpha is scoped to this block only
+ {
+ y_offset = region->getSurface()->Hgt / 2;
+
+ float alpha; // 0.0 == fully transparent (takes old color), 1.0 == solid color (takes new color)
+
+ if (shadow) // draw the center of the light
+ {
+ alpha = 0.3 + 0.6 * light->getValue() * light->getLightness();
+ }
+ else // draw the edge of the light
+ {
+ alpha = 0.0;
+ }
+
+ glColor4f(light->getR(), light->getG(), light->getB(), alpha);
+ break;
+ }
+ default:
+ glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
+ break;
}
- else
- glColor3f(0.0f, 0.5f/1.5f, 0.5f/1.5f);
// global coords -> region coords
x += -region->getRegion().x;
- y += -region->getRegion().y;
+ y += -region->getRegion().y + y_offset;
- glVertex2f(x,y);
+ glVertex2f(x, y);
}
void C4FoWDrawLightTextureStrategy::DrawDarkVertex(float x, float y)
diff --git a/src/landscape/fow/C4FoWDrawStrategy.h b/src/landscape/fow/C4FoWDrawStrategy.h
index 4743c11fe..a11d09eeb 100644
--- a/src/landscape/fow/C4FoWDrawStrategy.h
+++ b/src/landscape/fow/C4FoWDrawStrategy.h
@@ -85,7 +85,7 @@ class C4FoWDrawLightTextureStrategy : public C4FoWDrawStrategy
public:
C4FoWDrawLightTextureStrategy(const C4FoWLight* light, const C4FoWRegion* region) : light(light), region(region) {};
- virtual int32_t GetRequestedPasses() { return 2; };
+ virtual int32_t GetRequestedPasses() { return 3; };
virtual void DrawLightVertex(float x, float y);
virtual void DrawDarkVertex(float x, float y);
virtual void Begin(int32_t pass);
diff --git a/src/landscape/fow/C4FoWLight.cpp b/src/landscape/fow/C4FoWLight.cpp
index 4e35db91e..8f805632c 100644
--- a/src/landscape/fow/C4FoWLight.cpp
+++ b/src/landscape/fow/C4FoWLight.cpp
@@ -31,7 +31,8 @@ C4FoWLight::C4FoWLight(C4Object *pObj)
iY(fixtoi(pObj->fix_y)),
iReach(pObj->lightRange),
iFadeout(pObj->lightFadeoutRange),
- iSize(20), gBright(0.5),
+ iSize(20), gBright(0.5), colorR(1.0), colorG(1.0), colorB(1.0),
+ colorV(1.0), colorL(1.0),
pNext(NULL),
pObj(pObj),
sections(4)
@@ -77,6 +78,22 @@ void C4FoWLight::SetReach(int32_t iReach2, int32_t iFadeout2)
}
}
+void C4FoWLight::SetColor(uint32_t iValue)
+{
+ colorR = (GetRedValue(iValue) & 255) / 255.0f;
+ colorG = (GetGreenValue(iValue) & 255) / 255.0f;
+ colorB = (GetBlueValue(iValue) & 255) / 255.0f;
+
+ float min = Min(colorR, Min(colorG, colorB));
+ colorV = Max(Max(colorR, Max(colorG, colorB)), 1e-3f); // prevent division by 0
+ colorL = (min + colorV) / 2.0f;
+
+ // maximize color, so that dark colors will not be desaturated after normalization
+ colorR = Min(colorR / colorV, 1.0f);
+ colorG = Min(colorG / colorV, 1.0f);
+ colorB = Min(colorB / colorV, 1.0f);
+}
+
void C4FoWLight::Update(C4Rect Rec)
{
// Update position from object. Clear if we moved in any way
@@ -119,7 +136,7 @@ void C4FoWLight::Render(C4FoWRegion *region, const C4TargetFacet *onScreen)
else pen = new C4FoWDrawLightTextureStrategy(this, region);
for(int pass = 0; pass < pen->GetRequestedPasses(); pass++)
- {
+ {
pen->Begin(pass);
DrawFan(pen, triangles);
@@ -193,7 +210,7 @@ void C4FoWLight::CalculateIntermediateFadeTriangles(TriangleList &triangles) con
// an extra intermediate fade point is only necessary on cliffs
tri.descending = distFanR > distNextFanL;
- if (tri.descending) {
+ if (tri.descending) {
if (distFanR < distNextFadeL)
{
tri.fadeIX = nextTri.fadeLX;
@@ -220,7 +237,6 @@ void C4FoWLight::CalculateIntermediateFadeTriangles(TriangleList &triangles) con
ProjectPointOutward(tri.fadeIX, tri.fadeIY, sqrt(distNextFadeL));
}
}
-
}
}
diff --git a/src/landscape/fow/C4FoWLight.h b/src/landscape/fow/C4FoWLight.h
index 52f0457f9..b9e152b9d 100644
--- a/src/landscape/fow/C4FoWLight.h
+++ b/src/landscape/fow/C4FoWLight.h
@@ -42,7 +42,12 @@ private:
int32_t iReach; // maximum length of beams
int32_t iFadeout; // number of pixels over which beams fade out
int32_t iSize; // size of the light source. Decides smoothness of shadows
- float gBright; // brigtness of the light source. 1.0 is maximum.
+ float gBright; // brightness of the light source. 1.0 is maximum.
+ float colorR; // red color component of the light source. 1.0 is maximum.
+ float colorG; // green color component of the light source. 1.0 is maximum.
+ float colorB; // blue color component of the light source. 1.0 is maximum.
+ float colorV; // color value. 1.0 is maximum.
+ float colorL; // color lightness. 1.0 is maximum.
C4FoWLight *pNext;
C4Object *pObj; // Associated object
@@ -56,13 +61,21 @@ public:
int32_t getTotalReach() const { return iReach + iFadeout; }
int32_t getSize() const { return iSize; }
int32_t getNormalSize() const { return iSize * 2; }
- float getBrightness() const { return gBright; }
+ float getBrightness() const { return colorV * gBright; }
+ float getR() const { return colorR; }
+ float getG() const { return colorG; }
+ float getB() const { return colorB; }
+ float getValue() const { return colorV; }
+ float getLightness() const { return colorL; }
C4FoWLight *getNext() const { return pNext; }
C4Object *getObj() const { return pObj; }
/** Sets the light's size in pixels. The reach is the total radius of the light while the fadeout is the number of
pixels after which the light should dim down */
void SetReach(int32_t iReach, int32_t iFadeout);
+
+ /** Sets the light's color in rgba format. */
+ void SetColor(uint32_t iValue);
/** Triggers the recalculation of all light beams within the given rectangle for this light because the landscape changed. */
void Invalidate(C4Rect r);
diff --git a/src/landscape/fow/C4FoWRegion.cpp b/src/landscape/fow/C4FoWRegion.cpp
index 1df661e1a..0a00a62b2 100644
--- a/src/landscape/fow/C4FoWRegion.cpp
+++ b/src/landscape/fow/C4FoWRegion.cpp
@@ -40,9 +40,9 @@ bool C4FoWRegion::BindFramebuf()
pBackSurface = pSfc;
// Can simply reuse old texture?
- if (!pSurface || pSurface->Wdt < Region.Wdt || pSurface->Hgt < Region.Hgt)
+ if (!pSurface || pSurface->Wdt < Region.Wdt || (pSurface->Hgt / 2) < Region.Hgt)
{
- // Create texture. Round up to next power of two in order to
+ // Determine texture size. Round up to next power of two in order to
// prevent rounding errors, as well as preventing lots of
// re-allocations when region size changes quickly (think zoom).
if (!pSurface)
@@ -50,12 +50,20 @@ bool C4FoWRegion::BindFramebuf()
int iWdt = 1, iHgt = 1;
while (iWdt < Region.Wdt) iWdt *= 2;
while (iHgt < Region.Hgt) iHgt *= 2;
+
+ // Double the texture size. The second half of the texture
+ // will contain the light color information, while the
+ // first half contains the brightness and direction information
+ iHgt *= 2;
+
+ // Create the texture
if (!pSurface->Create(iWdt, iHgt))
return false;
}
// Generate frame buffer object
- if (!hFrameBufDraw) {
+ if (!hFrameBufDraw)
+ {
glGenFramebuffersEXT(1, &hFrameBufDraw);
glGenFramebuffersEXT(1, &hFrameBufRead);
}
@@ -144,16 +152,24 @@ void C4FoWRegion::Render(const C4TargetFacet *pOnScreen)
gluOrtho2D(0, getSurface()->Wdt, getSurface()->Hgt, 0);
// Clear texture contents
- glClearColor(0.0f, 0.5f/1.5f, 0.5f/1.5f, 1.0f);
+ glScissor(0, getSurface()->Hgt / 2.0, getSurface()->Wdt, getSurface()->Hgt / 2.0);
+ glClearColor(0.0f, 0.5f / 1.5f, 0.5f / 1.5f, 1.0f);
+ glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);
+ // clear lower half of texture
+ glScissor(0, 0, getSurface()->Wdt, getSurface()->Hgt / 2.0);
+ glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glDisable(GL_SCISSOR_TEST);
+
// Render FoW to frame buffer object
glBlendFunc(GL_ONE, GL_ONE);
pFoW->Render(this, NULL, pPlayer);
// Copy over the old state
- if (OldRegion.Wdt > 0) {
-
+ if (OldRegion.Wdt > 0)
+ {
// Set up shader. If this one doesn't work, we're really in trouble.
C4Shader *pShader = pFoW->GetFramebufShader();
assert(pShader);
@@ -176,7 +192,8 @@ void C4FoWRegion::Render(const C4TargetFacet *pOnScreen)
int tquad[8] = { sx0, ty0, tx0, ty1, tx1, ty1, tx1, ty0, };
// Transform into texture coordinates
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < 4; i++)
+ {
squad[i*2] = squad[i*2] / getBackSurface()->Wdt;
squad[i*2+1] = 1.0 - squad[i*2+1] / getBackSurface()->Hgt;
}
diff --git a/src/object/C4Object.cpp b/src/object/C4Object.cpp
index f6da7d205..54e939e5b 100644
--- a/src/object/C4Object.cpp
+++ b/src/object/C4Object.cpp
@@ -4129,6 +4129,17 @@ bool C4Object::SetLightRange(int32_t iToRange, int32_t iToFadeoutRange)
}
+bool C4Object::SetLightColor(long iValue)
+{
+ // set new color value
+ lightColor = iValue;
+ // resort into player's FoW-repeller-list
+ UpdateLight();
+ // success
+ return true;
+}
+
+
void C4Object::UpdateLight()
{
if (Landscape.pFoW) Landscape.pFoW->Add(this);
diff --git a/src/object/C4Object.h b/src/object/C4Object.h
index 4063b9a89..a1bbf2a72 100644
--- a/src/object/C4Object.h
+++ b/src/object/C4Object.h
@@ -139,6 +139,7 @@ public:
int32_t Audible, AudiblePan; // NoSave //
int32_t lightRange;
int32_t lightFadeoutRange;
+ long lightColor;
C4Real fix_x,fix_y,fix_r; // SyncClearance-Fix //
C4Real xdir,ydir,rdir;
int32_t iLastAttachMovementFrame; // last frame in which Attach-movement by a SolidMask was done
@@ -321,6 +322,8 @@ public:
int32_t GetValue(C4Object *pInBase, int32_t iForPlayer);
bool SetOwner(int32_t iOwner);
bool SetLightRange(int32_t iToRange, int32_t iToFadeoutRange);
+ long GetLightColor() const { return lightColor; }
+ bool SetLightColor(long iValue);
void SetOnFire(bool OnFire) { this->OnFire = OnFire; SetOCF(); }
bool GetOnFire() const { return OnFire; }
void SetAlive(bool Alive) { this->Alive = Alive; SetOCF(); }
diff --git a/src/object/C4ObjectScript.cpp b/src/object/C4ObjectScript.cpp
index c2bdeb9c3..2f7ad30a7 100644
--- a/src/object/C4ObjectScript.cpp
+++ b/src/object/C4ObjectScript.cpp
@@ -1334,6 +1334,24 @@ static C4Void FnSetLightRange(C4Object *Obj, long iRange, Nillable iFadeou
return C4Void();
}
+static long FnGetLightColor(C4Object *Obj)
+{
+ // get it
+ return Obj->GetLightColor();
+}
+
+
+static C4Void FnSetLightColor(C4Object *Obj, Nillable iValue)
+{
+ if (iValue.IsNil())
+ {
+ iValue = 0;
+ }
+
+ Obj->SetLightColor(iValue);
+ return C4Void();
+}
+
static C4Void FnSetPicture(C4Object *Obj, long iX, long iY, long iWdt, long iHgt)
{
// set new picture rect
@@ -2638,6 +2656,8 @@ void InitObjectFunctionMap(C4AulScriptEngine *pEngine)
AddFunc(pEngine, "GetColor", FnGetColor);
AddFunc(pEngine, "SetColor", FnSetColor);
AddFunc(pEngine, "SetLightRange", FnSetLightRange);
+ AddFunc(pEngine, "GetLightColor", FnGetLightColor);
+ AddFunc(pEngine, "SetLightColor", FnSetLightColor);
AddFunc(pEngine, "SetPicture", FnSetPicture);
AddFunc(pEngine, "GetProcedure", FnGetProcedure);
AddFunc(pEngine, "CanConcatPictureWith", FnCanConcatPictureWith);