forked from Mirrors/openclonk
Colored lights
The color of object lights can now be changed. This includes the following changes: - added light test scenario, based on DarkCastle, with some lights, - new functions SetLightColor() and GetLightColor() with C4Script documentation, - third drawing pass for rendering the light color, the drawing passes are now referenced by enum, - the blending of light from multiple colored light sources works correctly with alpha blending, - light color value affects the intensity of the light, - alpha blending of the light depends on color value and lightness. This means that brighter (= more value) and lighter (= more whiteish) light will be preferred in blending over other lights, - the object light color is rendered to the lower half of the fow light texture now, - the shader accesses the brightness/direction information and color information correctly, The patch was created from the following commits: dab898a SetLightColor() f57286e Color texture experiment d0702f5 Dynamic color fa14cdf Light test scenario f99203d Alternate lights 474bade Bugfixes 3113698 Brightness handled better 516fb21 GetLightColor 1d91ec9 Improvements 3cfbf6c Documentation 95ec185 Improvements: Light Shader a63bffc Scope of alpha 20c7ca0 Improvement: C4FoWLight 17d9123 Undo code style d79411b Cleaner code (cherry picked from commit 36dec610e36860b88417e91ce727250673bc2ec2) Conflicts: src/landscape/fow/C4FoWRegion.cpp, mergedControls
parent
1021c51fe8
commit
02fd798631
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<!DOCTYPE funcs
|
||||||
|
SYSTEM '../../../clonk.dtd'>
|
||||||
|
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
|
||||||
|
<funcs>
|
||||||
|
<func>
|
||||||
|
<title>GetLightColor</title>
|
||||||
|
<category>Objects</category>
|
||||||
|
<version>7.0 OC</version>
|
||||||
|
<syntax><rtype>int</rtype></syntax>
|
||||||
|
<desc>Gets the RGB color value of the light that the object emits. The color can be changed with <funclink>SetLightColor</funclink>.</desc>
|
||||||
|
<related>
|
||||||
|
<funclink>SetLightColor</funclink>
|
||||||
|
<funclink>SetLightRange</funclink>
|
||||||
|
</related>
|
||||||
|
</func>
|
||||||
|
<author>Marky</author><date>2015-06</date>
|
||||||
|
</funcs>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<!DOCTYPE funcs
|
||||||
|
SYSTEM '../../../clonk.dtd'>
|
||||||
|
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
|
||||||
|
<funcs>
|
||||||
|
<func>
|
||||||
|
<title>SetLightColor</title>
|
||||||
|
<category>Objects</category>
|
||||||
|
<version>7.0 OC</version>
|
||||||
|
<syntax>
|
||||||
|
<rtype>void</rtype>
|
||||||
|
<params>
|
||||||
|
<param>
|
||||||
|
<type>int</type>
|
||||||
|
<name>color</name>
|
||||||
|
<desc>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 <code><funclink>RGB</funclink>(128, 0, 0)</code> has a value/intensity of 50%. This means that it will be weaker than a light with<code><funclink>RGB</funclink>(255, 0, 0)</code>, but it will cover the same area as that light.</desc>
|
||||||
|
</param>
|
||||||
|
</params>
|
||||||
|
</syntax>
|
||||||
|
<desc>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 <funclink>SetLightRange</funclink> for further details.</desc>
|
||||||
|
<examples>
|
||||||
|
<example>
|
||||||
|
<code>
|
||||||
|
var candle_shine=<funclink>CreateObject</funclink>(EnvPack_Candle_Shine);
|
||||||
|
candle_shine-><funclink>SetLightRange</funclink>(30, 20);
|
||||||
|
candle_shine->SetLightColor(RGB(255,163,58));
|
||||||
|
</code>
|
||||||
|
<text>Gives a warm shine to a candle shine object.</text>
|
||||||
|
</example>
|
||||||
|
</examples>
|
||||||
|
<related>
|
||||||
|
<funclink>GetLightColor</funclink>
|
||||||
|
<funclink>SetLightRange</funclink>
|
||||||
|
</related>
|
||||||
|
</func>
|
||||||
|
<author>Marky</author><date>2015-06</date>
|
||||||
|
</funcs>
|
|
@ -38,6 +38,7 @@
|
||||||
<related>
|
<related>
|
||||||
<funclink>SetPlrView</funclink>
|
<funclink>SetPlrView</funclink>
|
||||||
<funclink>SetFoW</funclink>
|
<funclink>SetFoW</funclink>
|
||||||
|
<funclink>SetLightColor</funclink>
|
||||||
</related>
|
</related>
|
||||||
</func>
|
</func>
|
||||||
</funcs>
|
</funcs>
|
||||||
|
|
|
@ -10,24 +10,46 @@ uniform sampler2D lightTex;
|
||||||
// brightness: light strength
|
// brightness: light strength
|
||||||
//#define LIGHT_DEBUG
|
//#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
|
// 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.
|
// and therefore will often never arrive at 0 light intensity.
|
||||||
const float lightDarknessLevel = 8.0 / 256.0;
|
const float lightDarknessLevel = 8.0 / 256.0;
|
||||||
|
|
||||||
slice(texture+5)
|
slice(texture+5)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIGHT
|
#ifdef HAVE_LIGHT
|
||||||
|
|
||||||
// Query light texture
|
// 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);
|
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
|
#else
|
||||||
// When lighting is disabled, put a light source coming from the camera.
|
// 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
|
// Note that in most cases this does not actually matter, since in the
|
||||||
// case with lighting disabled, ambient lighting takes fully over.
|
// case with lighting disabled, ambient lighting takes fully over.
|
||||||
float lightBright = 0.5;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,10 +63,17 @@ slice(light)
|
||||||
|
|
||||||
slice(color+5)
|
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
|
// Add light
|
||||||
color = vec4(light * color.rgb, color.a);
|
color = vec4(light * color.rgb * lightColor.rgb, color.a);
|
||||||
#ifdef HAVE_2PX
|
#ifdef HAVE_2PX
|
||||||
color2 = vec4(light2 * color2.rgb, color2.a);
|
color2 = vec4(light2 * color2.rgb * lightColor.rgb, color2.a);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
|
@ -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
|
Binary file not shown.
After Width: | Height: | Size: 540 KiB |
Binary file not shown.
After Width: | Height: | Size: 489 KiB |
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 425 KiB |
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
[Teams]
|
||||||
|
Active=false
|
||||||
|
Custom=false
|
||||||
|
AutoGenerateTeams=true
|
|
@ -0,0 +1,2 @@
|
||||||
|
DE:Farbiges Licht
|
||||||
|
US:Colorful lights
|
|
@ -71,9 +71,9 @@ void C4FoW::Add(C4Object *pObj)
|
||||||
if (pLight)
|
if (pLight)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Update reach
|
// Update reach and light color
|
||||||
pLight->SetReach(pObj->lightRange, pObj->lightFadeoutRange);
|
pLight->SetReach(pObj->lightRange, pObj->lightFadeoutRange);
|
||||||
|
pLight->SetColor(pObj->lightColor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,6 +22,13 @@
|
||||||
#include "C4FoWRegion.h"
|
#include "C4FoWRegion.h"
|
||||||
#include "C4DrawGL.h"
|
#include "C4DrawGL.h"
|
||||||
|
|
||||||
|
enum C4DrawPass
|
||||||
|
{
|
||||||
|
C4DP_First = 0,
|
||||||
|
C4DP_Second = 1,
|
||||||
|
C4DP_Color = 2,
|
||||||
|
C4DP_Last
|
||||||
|
};
|
||||||
|
|
||||||
void C4FoWDrawLightTextureStrategy::Begin(int32_t passPar)
|
void C4FoWDrawLightTextureStrategy::Begin(int32_t passPar)
|
||||||
{
|
{
|
||||||
|
@ -29,24 +36,40 @@ void C4FoWDrawLightTextureStrategy::Begin(int32_t passPar)
|
||||||
|
|
||||||
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
|
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
|
// Set up blend equation, see C4FoWDrawLightTextureStrategy::DrawVertex
|
||||||
// for details.
|
// for details.
|
||||||
if(pass == 0)
|
switch (pass)
|
||||||
{
|
{
|
||||||
glBlendFunc(GL_ONE, GL_ONE);
|
case C4DP_First:
|
||||||
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
glBlendFunc(GL_ONE, GL_ONE);
|
||||||
}
|
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
||||||
else if(pass == 1)
|
glScissor(0, height, width, height);
|
||||||
{
|
break;
|
||||||
glBlendFunc(GL_ONE, GL_ONE);
|
case C4DP_Second:
|
||||||
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
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)
|
void C4FoWDrawLightTextureStrategy::End(int32_t pass)
|
||||||
{
|
{
|
||||||
glBlendEquation( GL_FUNC_ADD );
|
glBlendEquation( GL_FUNC_ADD );
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4FoWDrawLightTextureStrategy::DrawVertex(float x, float y, bool shadow)
|
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)
|
// 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)
|
// B_new = BoundBy(BoundBy(B_old + B / 1.5), 0.0, 1.0) - 0.5 / 1.5, 0.0, 1.0)
|
||||||
|
|
||||||
if (pass > 0)
|
float y_offset = 0.0f;
|
||||||
glColor3f(0.0f, 0.5f/1.5f, 0.5f/1.5f);
|
|
||||||
else if (shadow)
|
switch (pass)
|
||||||
{
|
{
|
||||||
float dx = x - light->getX();
|
case C4DP_First:
|
||||||
float dy = y - light->getY();
|
if (shadow)
|
||||||
float dist = sqrt(dx*dx+dy*dy);
|
{
|
||||||
float bright = light->getBrightness();
|
float dx = x - light->getX();
|
||||||
float mult = Min(0.5f / light->getNormalSize(), 0.5f / dist);
|
float dy = y - light->getY();
|
||||||
float normX = Clamp(0.5f + dx * mult, 0.0f, 1.0f) / 1.5f;
|
float dist = sqrt(dx*dx + dy*dy);
|
||||||
float normY = Clamp(0.5f + dy * mult, 0.0f, 1.0f) / 1.5f;
|
float bright = light->getBrightness();
|
||||||
glColor3f(bright, normX, normY);
|
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
|
// global coords -> region coords
|
||||||
x += -region->getRegion().x;
|
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)
|
void C4FoWDrawLightTextureStrategy::DrawDarkVertex(float x, float y)
|
||||||
|
|
|
@ -85,7 +85,7 @@ class C4FoWDrawLightTextureStrategy : public C4FoWDrawStrategy
|
||||||
public:
|
public:
|
||||||
C4FoWDrawLightTextureStrategy(const C4FoWLight* light, const C4FoWRegion* region) : light(light), region(region) {};
|
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 DrawLightVertex(float x, float y);
|
||||||
virtual void DrawDarkVertex(float x, float y);
|
virtual void DrawDarkVertex(float x, float y);
|
||||||
virtual void Begin(int32_t pass);
|
virtual void Begin(int32_t pass);
|
||||||
|
|
|
@ -31,7 +31,8 @@ C4FoWLight::C4FoWLight(C4Object *pObj)
|
||||||
iY(fixtoi(pObj->fix_y)),
|
iY(fixtoi(pObj->fix_y)),
|
||||||
iReach(pObj->lightRange),
|
iReach(pObj->lightRange),
|
||||||
iFadeout(pObj->lightFadeoutRange),
|
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),
|
pNext(NULL),
|
||||||
pObj(pObj),
|
pObj(pObj),
|
||||||
sections(4)
|
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)
|
void C4FoWLight::Update(C4Rect Rec)
|
||||||
{
|
{
|
||||||
// Update position from object. Clear if we moved in any way
|
// 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);
|
else pen = new C4FoWDrawLightTextureStrategy(this, region);
|
||||||
|
|
||||||
for(int pass = 0; pass < pen->GetRequestedPasses(); pass++)
|
for(int pass = 0; pass < pen->GetRequestedPasses(); pass++)
|
||||||
{
|
{
|
||||||
pen->Begin(pass);
|
pen->Begin(pass);
|
||||||
|
|
||||||
DrawFan(pen, triangles);
|
DrawFan(pen, triangles);
|
||||||
|
@ -193,7 +210,7 @@ void C4FoWLight::CalculateIntermediateFadeTriangles(TriangleList &triangles) con
|
||||||
|
|
||||||
// an extra intermediate fade point is only necessary on cliffs
|
// an extra intermediate fade point is only necessary on cliffs
|
||||||
tri.descending = distFanR > distNextFanL;
|
tri.descending = distFanR > distNextFanL;
|
||||||
if (tri.descending) {
|
if (tri.descending) {
|
||||||
if (distFanR < distNextFadeL)
|
if (distFanR < distNextFadeL)
|
||||||
{
|
{
|
||||||
tri.fadeIX = nextTri.fadeLX;
|
tri.fadeIX = nextTri.fadeLX;
|
||||||
|
@ -220,7 +237,6 @@ void C4FoWLight::CalculateIntermediateFadeTriangles(TriangleList &triangles) con
|
||||||
ProjectPointOutward(tri.fadeIX, tri.fadeIY, sqrt(distNextFadeL));
|
ProjectPointOutward(tri.fadeIX, tri.fadeIY, sqrt(distNextFadeL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,12 @@ private:
|
||||||
int32_t iReach; // maximum length of beams
|
int32_t iReach; // maximum length of beams
|
||||||
int32_t iFadeout; // number of pixels over which beams fade out
|
int32_t iFadeout; // number of pixels over which beams fade out
|
||||||
int32_t iSize; // size of the light source. Decides smoothness of shadows
|
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;
|
C4FoWLight *pNext;
|
||||||
C4Object *pObj; // Associated object
|
C4Object *pObj; // Associated object
|
||||||
|
|
||||||
|
@ -56,13 +61,21 @@ public:
|
||||||
int32_t getTotalReach() const { return iReach + iFadeout; }
|
int32_t getTotalReach() const { return iReach + iFadeout; }
|
||||||
int32_t getSize() const { return iSize; }
|
int32_t getSize() const { return iSize; }
|
||||||
int32_t getNormalSize() const { return iSize * 2; }
|
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; }
|
C4FoWLight *getNext() const { return pNext; }
|
||||||
C4Object *getObj() const { return pObj; }
|
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
|
/** 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 */
|
pixels after which the light should dim down */
|
||||||
void SetReach(int32_t iReach, int32_t iFadeout);
|
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. */
|
/** Triggers the recalculation of all light beams within the given rectangle for this light because the landscape changed. */
|
||||||
void Invalidate(C4Rect r);
|
void Invalidate(C4Rect r);
|
||||||
|
|
|
@ -40,9 +40,9 @@ bool C4FoWRegion::BindFramebuf()
|
||||||
pBackSurface = pSfc;
|
pBackSurface = pSfc;
|
||||||
|
|
||||||
// Can simply reuse old texture?
|
// 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
|
// prevent rounding errors, as well as preventing lots of
|
||||||
// re-allocations when region size changes quickly (think zoom).
|
// re-allocations when region size changes quickly (think zoom).
|
||||||
if (!pSurface)
|
if (!pSurface)
|
||||||
|
@ -50,12 +50,20 @@ bool C4FoWRegion::BindFramebuf()
|
||||||
int iWdt = 1, iHgt = 1;
|
int iWdt = 1, iHgt = 1;
|
||||||
while (iWdt < Region.Wdt) iWdt *= 2;
|
while (iWdt < Region.Wdt) iWdt *= 2;
|
||||||
while (iHgt < Region.Hgt) iHgt *= 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))
|
if (!pSurface->Create(iWdt, iHgt))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate frame buffer object
|
// Generate frame buffer object
|
||||||
if (!hFrameBufDraw) {
|
if (!hFrameBufDraw)
|
||||||
|
{
|
||||||
glGenFramebuffersEXT(1, &hFrameBufDraw);
|
glGenFramebuffersEXT(1, &hFrameBufDraw);
|
||||||
glGenFramebuffersEXT(1, &hFrameBufRead);
|
glGenFramebuffersEXT(1, &hFrameBufRead);
|
||||||
}
|
}
|
||||||
|
@ -144,16 +152,24 @@ void C4FoWRegion::Render(const C4TargetFacet *pOnScreen)
|
||||||
gluOrtho2D(0, getSurface()->Wdt, getSurface()->Hgt, 0);
|
gluOrtho2D(0, getSurface()->Wdt, getSurface()->Hgt, 0);
|
||||||
|
|
||||||
// Clear texture contents
|
// 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);
|
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
|
// Render FoW to frame buffer object
|
||||||
glBlendFunc(GL_ONE, GL_ONE);
|
glBlendFunc(GL_ONE, GL_ONE);
|
||||||
pFoW->Render(this, NULL, pPlayer);
|
pFoW->Render(this, NULL, pPlayer);
|
||||||
|
|
||||||
// Copy over the old state
|
// 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.
|
// Set up shader. If this one doesn't work, we're really in trouble.
|
||||||
C4Shader *pShader = pFoW->GetFramebufShader();
|
C4Shader *pShader = pFoW->GetFramebufShader();
|
||||||
assert(pShader);
|
assert(pShader);
|
||||||
|
@ -176,7 +192,8 @@ void C4FoWRegion::Render(const C4TargetFacet *pOnScreen)
|
||||||
int tquad[8] = { sx0, ty0, tx0, ty1, tx1, ty1, tx1, ty0, };
|
int tquad[8] = { sx0, ty0, tx0, ty1, tx1, ty1, tx1, ty0, };
|
||||||
|
|
||||||
// Transform into texture coordinates
|
// 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] = squad[i*2] / getBackSurface()->Wdt;
|
||||||
squad[i*2+1] = 1.0 - squad[i*2+1] / getBackSurface()->Hgt;
|
squad[i*2+1] = 1.0 - squad[i*2+1] / getBackSurface()->Hgt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
void C4Object::UpdateLight()
|
||||||
{
|
{
|
||||||
if (Landscape.pFoW) Landscape.pFoW->Add(this);
|
if (Landscape.pFoW) Landscape.pFoW->Add(this);
|
||||||
|
|
|
@ -139,6 +139,7 @@ public:
|
||||||
int32_t Audible, AudiblePan; // NoSave //
|
int32_t Audible, AudiblePan; // NoSave //
|
||||||
int32_t lightRange;
|
int32_t lightRange;
|
||||||
int32_t lightFadeoutRange;
|
int32_t lightFadeoutRange;
|
||||||
|
long lightColor;
|
||||||
C4Real fix_x,fix_y,fix_r; // SyncClearance-Fix //
|
C4Real fix_x,fix_y,fix_r; // SyncClearance-Fix //
|
||||||
C4Real xdir,ydir,rdir;
|
C4Real xdir,ydir,rdir;
|
||||||
int32_t iLastAttachMovementFrame; // last frame in which Attach-movement by a SolidMask was done
|
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);
|
int32_t GetValue(C4Object *pInBase, int32_t iForPlayer);
|
||||||
bool SetOwner(int32_t iOwner);
|
bool SetOwner(int32_t iOwner);
|
||||||
bool SetLightRange(int32_t iToRange, int32_t iToFadeoutRange);
|
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(); }
|
void SetOnFire(bool OnFire) { this->OnFire = OnFire; SetOCF(); }
|
||||||
bool GetOnFire() const { return OnFire; }
|
bool GetOnFire() const { return OnFire; }
|
||||||
void SetAlive(bool Alive) { this->Alive = Alive; SetOCF(); }
|
void SetAlive(bool Alive) { this->Alive = Alive; SetOCF(); }
|
||||||
|
|
|
@ -1334,6 +1334,24 @@ static C4Void FnSetLightRange(C4Object *Obj, long iRange, Nillable<long> iFadeou
|
||||||
return C4Void();
|
return C4Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long FnGetLightColor(C4Object *Obj)
|
||||||
|
{
|
||||||
|
// get it
|
||||||
|
return Obj->GetLightColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static C4Void FnSetLightColor(C4Object *Obj, Nillable<long> iValue)
|
||||||
|
{
|
||||||
|
if (iValue.IsNil())
|
||||||
|
{
|
||||||
|
iValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Obj->SetLightColor(iValue);
|
||||||
|
return C4Void();
|
||||||
|
}
|
||||||
|
|
||||||
static C4Void FnSetPicture(C4Object *Obj, long iX, long iY, long iWdt, long iHgt)
|
static C4Void FnSetPicture(C4Object *Obj, long iX, long iY, long iWdt, long iHgt)
|
||||||
{
|
{
|
||||||
// set new picture rect
|
// set new picture rect
|
||||||
|
@ -2638,6 +2656,8 @@ void InitObjectFunctionMap(C4AulScriptEngine *pEngine)
|
||||||
AddFunc(pEngine, "GetColor", FnGetColor);
|
AddFunc(pEngine, "GetColor", FnGetColor);
|
||||||
AddFunc(pEngine, "SetColor", FnSetColor);
|
AddFunc(pEngine, "SetColor", FnSetColor);
|
||||||
AddFunc(pEngine, "SetLightRange", FnSetLightRange);
|
AddFunc(pEngine, "SetLightRange", FnSetLightRange);
|
||||||
|
AddFunc(pEngine, "GetLightColor", FnGetLightColor);
|
||||||
|
AddFunc(pEngine, "SetLightColor", FnSetLightColor);
|
||||||
AddFunc(pEngine, "SetPicture", FnSetPicture);
|
AddFunc(pEngine, "SetPicture", FnSetPicture);
|
||||||
AddFunc(pEngine, "GetProcedure", FnGetProcedure);
|
AddFunc(pEngine, "GetProcedure", FnGetProcedure);
|
||||||
AddFunc(pEngine, "CanConcatPictureWith", FnCanConcatPictureWith);
|
AddFunc(pEngine, "CanConcatPictureWith", FnCanConcatPictureWith);
|
||||||
|
|
Loading…
Reference in New Issue