Compare commits
40 Commits
Author | SHA1 | Date |
---|---|---|
Nicolas Hake | 92ed1537a0 | |
Nicolas Hake | 1a82b164b4 | |
Maikel de Vries | 4b01f51337 | |
Maikel de Vries | 488ec4d318 | |
Maikel de Vries | 46b977e506 | |
Maikel de Vries | 8d63ddfdef | |
Maikel de Vries | c0382ceb7f | |
Sven Eberhardt | bb46dede7a | |
Sven Eberhardt | b4919fb1ec | |
Maikel de Vries | 6978bbe646 | |
Sven Eberhardt | 675740c8dd | |
David Dormagen | 8aec2eadd2 | |
Sven Eberhardt | a52a4335fc | |
Sven Eberhardt | c097c6eb35 | |
Sven Eberhardt | d8f9ab5232 | |
Maikel de Vries | 60c5fb99a2 | |
Maikel de Vries | 79146dac9b | |
David Dormagen | 4c8d4ef18d | |
Maikel de Vries | b49f89d31c | |
Maikel de Vries | e9e06263a8 | |
Maikel de Vries | 2e2450ee77 | |
Clonkonaut | e486712934 | |
Clonkonaut | 47820691d0 | |
David Dormagen | 684b0d0682 | |
David Dormagen | 546ae30928 | |
Nicolas Hake | f35b3f3342 | |
Sven Eberhardt | 0301f610fc | |
Günther Brammer | aa7e2e91db | |
Sven Eberhardt | 1bba764219 | |
Sven Eberhardt | 21390f4c29 | |
Sven Eberhardt | ba82f5c3ac | |
Sven Eberhardt | b0ae8fae84 | |
Sven Eberhardt | 193dd6adf4 | |
Tobias Zwick | 0cf9473280 | |
Philipp Kern | 2f264b1825 | |
Maikel de Vries | 75ab7e0f00 | |
Maikel de Vries | 6d95c83196 | |
Maikel de Vries | 6655fdf8c7 | |
Maikel de Vries | dbc21d8431 | |
Sven Eberhardt | 082373d6e6 |
|
@ -1170,7 +1170,7 @@ endif()
|
|||
|
||||
if(GTK3_FOUND AND GTK3_gtksourceview_FOUND)
|
||||
add_executable(mape ${MAPE_BASE_SOURCES} ${MAPE_SOURCES})
|
||||
set_property(TARGET mape APPEND PROPERTY COMPILE_FLAGS ${GTK3_COMPILE_DEFINITIONS})
|
||||
target_compile_options(mape PRIVATE ${GTK3_COMPILE_DEFINITIONS} ${GTK3_gtksourceview_COMPILE_DEFINITIONS})
|
||||
target_include_directories(mape PRIVATE ${GTK3_INCLUDE_DIRS} ${GTK3_gtksourceview_INCLUDE_DIRS})
|
||||
target_link_libraries(mape
|
||||
${GTK3_LIBRARIES}
|
||||
|
|
|
@ -27,10 +27,10 @@ Martin Strohmeier (K-Pone)
|
|||
Tobias Zwick (Newton)
|
||||
|
||||
<Thanks to our package maintainers>
|
||||
Benedict Etzel (B_E), Phillip Kern (pkern), Kevin Zheng and more
|
||||
Benedict Etzel (B_E), Philipp Kern (pkern), Kevin Zheng and more
|
||||
|
||||
<Special Thanks to Contributors>
|
||||
Martin Adam (Win), Florian Graier (Nachtfalter), Mark Haßelbusch (Marky), Merten Ehmig (pluto), Benjamin Herr (Loriel), Armin Schäfer, Pyrit, Philip Holzmann (Batman), Alexander Semeniuk (AlteredARMOR), Andriel, Peewee, Oliver Schneider (ker), Fabian Pietsch, Manuel Rieke (MrBeast), Felix Riese (Fungiform), Carl-Philip Hänsch (Carli), Sebastian Rühl, Gurkenglas and many more:
|
||||
Luchs, Asmageddon, mizipzor, Tim Blume, Apfelclonk, Sven-Hendrik Haase, Lauri Niskanen (Ape), Daniel Theuke (ST-DDT), Russell, Stan, TomyLobo, Clonkine, Koronis, Johannes Nixdorf (mixi), grgecko, Dominik Bayerl, Misty de Meo, Lorenz Schwittmann, hasufell, Jan Heberer, dylanstrategie, Checkmaty, Faby
|
||||
|
||||
Also, big thanks to Matthes Bender and all those who contributed to previous Clonk titles for the passion they put into the game and for agreeing to make Clonk open source.
|
||||
Also, big thanks to Matthes Bender and all those who contributed to previous Clonk titles for the passion they put into the game and for agreeing to make Clonk open source.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# OpenClonk, http://www.openclonk.org
|
||||
#
|
||||
# Copyright (c) 2011-2013, The OpenClonk Team and contributors
|
||||
# Copyright (c) 2011-2016, The OpenClonk Team and contributors
|
||||
#
|
||||
# Distributed under the terms of the ISC license; see accompanying file
|
||||
# "COPYING" for details.
|
||||
|
@ -26,6 +26,13 @@ ENDIF (READLINE_INCLUDE_DIR)
|
|||
|
||||
FIND_PATH(READLINE_INCLUDE_DIR readline.h PATH_SUFFIXES readline)
|
||||
|
||||
# Unmodified readline depends on symbols from termcap without explicitly
|
||||
# linking to it. Several distributions patch this to make it link against
|
||||
# terminfo from ncurses or another termcap library, but some don't. To avoid
|
||||
# having to run link tests, we'll just look for and use any termcap providing
|
||||
# library.
|
||||
FIND_LIBRARY(TERMCAP_LIBRARY NAMES tinfo termcap ncursesw ncurses cursesw curses)
|
||||
|
||||
SET(READLINE_NAMES readline libreadline)
|
||||
FIND_LIBRARY(READLINE_LIBRARY NAMES ${READLINE_NAMES} )
|
||||
|
||||
|
@ -35,10 +42,13 @@ INCLUDE(FindPackageHandleStandardArgs)
|
|||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(READLINE DEFAULT_MSG READLINE_LIBRARY READLINE_INCLUDE_DIR)
|
||||
|
||||
IF(READLINE_FOUND)
|
||||
SET( READLINE_LIBRARIES ${READLINE_LIBRARY} )
|
||||
if(TERMCAP_LIBRARY)
|
||||
set(READLINE_LIBRARIES ${READLINE_LIBRARY} ${TERMCAP_LIBRARY})
|
||||
else()
|
||||
set(READLINE_LIBRARIES ${READLINE_LIBRARY})
|
||||
endif()
|
||||
ELSE(READLINE_FOUND)
|
||||
SET( READLINE_LIBRARIES )
|
||||
ENDIF(READLINE_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED( READLINE_LIBRARY READLINE_INCLUDE_DIR )
|
||||
|
||||
MARK_AS_ADVANCED( READLINE_LIBRARY TERMINFO_LIBRARY READLINE_INCLUDE_DIR )
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
<row>
|
||||
<literal_col>Exclusive</literal_col>
|
||||
<col>Integer</col>
|
||||
<col>0 or 1. Determines whether the object blocks objects behind it.</col>
|
||||
<col>0 or 1. Determines whether the object blocks objects behind it. Exclusive objects also block the placement of a construction site at an overlapping location.</col>
|
||||
</row>
|
||||
<row>
|
||||
<literal_col>Line</literal_col>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<subcat>OCF</subcat>
|
||||
<version>5.1 OC</version>
|
||||
<syntax><rtype>int</rtype></syntax>
|
||||
<desc>Object character flag: the object blocks (covers) objects behind it and prevents other objects from being built in front. This flag is set by <emlink href="definition/defcore.html">DefCore</emlink> entry "Exclusive".</desc>
|
||||
<desc>Object character flag: the object blocks (covers) objects behind it and prevents construction sites from being built in front of it. This flag is set by <emlink href="definition/defcore.html">DefCore</emlink> entry "Exclusive".</desc>
|
||||
<remark>For more information and examples regarding these constants see <emlink href="definition/ocf.html">object character flags</emlink>.</remark>
|
||||
<related>
|
||||
<funclink>GetOCF</funclink>
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
/**
|
||||
/*
|
||||
Hot Ice
|
||||
Ice islands above a lava lake
|
||||
|
||||
@authors Sven2
|
||||
*/
|
||||
|
||||
static g_player_spawn_positions;
|
||||
static g_map_width;
|
||||
|
||||
// Called be the engine: draw the complete map here.
|
||||
public func InitializeMap(proplist map)
|
||||
{
|
||||
|
@ -12,35 +15,77 @@ public func InitializeMap(proplist map)
|
|||
// Map type 1: Only many small islands
|
||||
var t = SCENPAR_MapType;
|
||||
var w = map.Wdt, h=map.Hgt;
|
||||
g_map_width = w;
|
||||
|
||||
// Bottom lava lake
|
||||
map->Draw("^DuroLava", nil, [0,h*4/5,w,h/5]);
|
||||
|
||||
// Big island
|
||||
if (t == 0)
|
||||
{
|
||||
var island = { Algo=MAPALGO_Polygon, X=[0,w,w*6/8,w*2/8], Y=[h*4/10,h*4/10,h*7/10,h*7/10] };
|
||||
island = { Algo=MAPALGO_Turbulence, Op=island, Amplitude=[0, 8] };
|
||||
map->Draw("^Ice-ice2", island, [w/10,h*13/20,w*8/10,h*3/20]);
|
||||
}
|
||||
|
||||
// Small islands
|
||||
var n_islands = [12,37][t];
|
||||
while(n_islands--)
|
||||
{
|
||||
var y = h*2/10 + Random(h*(3+t*2)/10);
|
||||
var x = w*1/10 + Random(w*8/10);
|
||||
var szx = t*Random(3);
|
||||
var szy = 1+t*Random(Random(2));
|
||||
map->Draw("^Ice-ice2", nil, [x-szx,y,1+2*szx,szy]);
|
||||
}
|
||||
|
||||
// Alternate texctures
|
||||
var icealt_tex = { Algo=MAPALGO_RndChecker, Wdt=2, Hgt=3 };
|
||||
icealt_tex = { Algo=MAPALGO_Turbulence, Op=icealt_tex };
|
||||
icealt_tex = { Algo=MAPALGO_And, Op=[Duplicate("Ice"), icealt_tex]};
|
||||
map->Draw("^Ice-ice3", icealt_tex);
|
||||
|
||||
if (t == 0) DrawBigIslandMap(map);
|
||||
if (t == 1) DrawSmallIslandsMap(map);
|
||||
|
||||
// Alternate texctures
|
||||
var icealt_tex = { Algo=MAPALGO_RndChecker, Wdt=2, Hgt=3 };
|
||||
icealt_tex = { Algo=MAPALGO_Turbulence, Op=icealt_tex };
|
||||
icealt_tex = { Algo=MAPALGO_And, Op=[Duplicate("Ice"), icealt_tex]};
|
||||
map->Draw("^Ice-ice", icealt_tex);
|
||||
|
||||
// Return true to tell the engine a map has been successfully created.
|
||||
return true;
|
||||
}
|
||||
|
||||
func DrawBigIslandMap(proplist map)
|
||||
{
|
||||
var w = map.Wdt, h=map.Hgt;
|
||||
// Draw one big island as the ground and some smaller islands floating above
|
||||
// Big
|
||||
var island = { Algo=MAPALGO_Polygon, X=[0,w,w*6/8,w*2/8], Y=[h*4/10,h*4/10,h*7/10,h*7/10] };
|
||||
island = { Algo=MAPALGO_Turbulence, Op=island, Amplitude=[0, 8] };
|
||||
map->Draw("^Ice-ice2", island, [w/10,h*13/20,w*8/10,h*3/20]);
|
||||
// Make sure one row of inner island is drawn because it's used for player spawns
|
||||
map->Draw("^Ice-ice2", nil, [w*3/10,h*13/20,w*4/10+1,1]);
|
||||
// Smaller floating
|
||||
var n_islands = 12;
|
||||
while(n_islands--)
|
||||
{
|
||||
var x = w*1/10 + Random(w*8/10);
|
||||
var y = h*2/10 + Random(h*3/10);
|
||||
map->Draw("^Ice-ice2", nil, [x,y,1,1]);
|
||||
}
|
||||
// Player spawns simply in middle of big island
|
||||
var plrcnt = GetStartupPlayerCount();
|
||||
g_player_spawn_positions = CreateArray(plrcnt);
|
||||
for (var i = 0; i < plrcnt; ++i)
|
||||
{
|
||||
g_player_spawn_positions[i] = [w*3/10 + i*w*4/10/(plrcnt-1), h*13/20-1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
func DrawSmallIslandsMap(proplist map)
|
||||
{
|
||||
var w = map.Wdt, h=map.Hgt, x, y, szx, szy;
|
||||
// Islands in center of map
|
||||
var n_islands = 35;
|
||||
while(n_islands--)
|
||||
{
|
||||
y = h*3/10 + Random(h*5/10 - 3);
|
||||
var xrange = w * (y)/(h*9/10);
|
||||
x = w/2 - xrange/2 + Random(xrange);
|
||||
szx = Random(3);
|
||||
szy = 1;
|
||||
if (y > h/2) szy += Random(2); // lower islands sometimes taller
|
||||
if (Abs(x-w/2) < w/10) szx += Random(3); // central islands sometimes wider
|
||||
map->Draw("^Ice-ice2", nil, [x-szx,y,1+2*szx,szy]);
|
||||
}
|
||||
// Starting islands for player spawns
|
||||
var spawn_island_count = GetStartupPlayerCount();
|
||||
g_player_spawn_positions = CreateArray(spawn_island_count);
|
||||
for (var i = 0; i < spawn_island_count; ++i)
|
||||
{
|
||||
var x = w*2/10 + i * (w*6/10) / (spawn_island_count - 1);
|
||||
var y = Max(1, h/10) + Abs(x-w/2) * 3*h/10/w;
|
||||
map->Draw("^Ice-ice2", nil, [x,y,1,1]);
|
||||
g_player_spawn_positions[i] = [x, y-1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -5,9 +5,10 @@ func Initialize()
|
|||
// Materials: Chests
|
||||
var i,pos;
|
||||
var ls_wdt = LandscapeWidth(), ls_hgt = LandscapeHeight();
|
||||
var top_area_hgt = ls_hgt*[50,80][SCENPAR_MapType]/100;
|
||||
var chest_area_y = ls_hgt*[0,30][SCENPAR_MapType]/100;
|
||||
var chest_area_hgt = ls_hgt/2;
|
||||
for (i=0; i<6; ++i)
|
||||
if (pos=FindLocation(Loc_InRect(0,0,ls_wdt,top_area_hgt-100), Loc_Wall(CNAT_Bottom))) // Loc_Wall adds us 100 pixels...
|
||||
if (pos=FindLocation(Loc_InRect(0,chest_area_y,ls_wdt,chest_area_hgt-100), Loc_Wall(CNAT_Bottom))) // Loc_Wall adds us 100 pixels...
|
||||
{
|
||||
var chest = CreateObjectAbove(Chest,pos.x,pos.y);
|
||||
if (chest)
|
||||
|
@ -24,27 +25,40 @@ func Initialize()
|
|||
}
|
||||
// Materials: Firestones
|
||||
for (i=0; i<30; ++i)
|
||||
if (pos=FindLocation(Loc_InRect(0,0,ls_wdt,top_area_hgt), Loc_Solid()))
|
||||
if (pos=FindLocation(Loc_InRect(0,chest_area_y,ls_wdt,chest_area_hgt), Loc_Solid()))
|
||||
if (IsFirestoneSpot(pos.x,pos.y))
|
||||
CreateObjectAbove(Firestone,pos.x,pos.y-1);
|
||||
// Some firestones in lower half. For ap type 1, more firestones in lower than upper half.
|
||||
// Some firestones and bombs in lower half. For ap type 1, more firestones in lower than upper half.
|
||||
for (i=0; i<30; ++i)
|
||||
if (pos=FindLocation(Loc_InRect(0,ls_hgt/2,ls_wdt,ls_hgt/3), Loc_Solid()))
|
||||
if (IsFirestoneSpot(pos.x,pos.y))
|
||||
CreateObjectAbove(Firestone,pos.x,pos.y-1);
|
||||
CreateObjectAbove([Firestone,IronBomb][Random(Random(3))],pos.x,pos.y-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
static g_player_spawn_positions, g_map_width, g_player_spawn_index;
|
||||
|
||||
func InitializePlayer(int plr)
|
||||
{
|
||||
// everything visible
|
||||
SetFoW(false, plr);
|
||||
// player positioning. In lower area for both maps becuase starting high is an an advantage.
|
||||
// Player positioning.
|
||||
var ls_wdt = LandscapeWidth(), ls_hgt = LandscapeHeight();
|
||||
var crew = GetCrew(plr);
|
||||
var start_pos = FindLocation(Loc_InRect(ls_wdt/5,ls_hgt/2,ls_wdt*3/5,ls_hgt/3), Loc_Wall(CNAT_Bottom), Loc_Func(Scenario.IsStartSpot));
|
||||
if (!start_pos) start_pos = FindLocation(Loc_InRect(ls_wdt/10,0,ls_wdt*8/10,ls_hgt*4/5), Loc_Wall(CNAT_Bottom), Loc_Func(Scenario.IsStartSpot));
|
||||
if (!start_pos) start_pos = {x=Random(ls_wdt*6/10)+ls_wdt*2/10, y=ls_hgt*58/100};
|
||||
var crew = GetCrew(plr), start_pos;
|
||||
// Position by map type?
|
||||
if (g_player_spawn_positions && g_player_spawn_index < GetLength(g_player_spawn_positions))
|
||||
{
|
||||
start_pos = g_player_spawn_positions[g_player_spawn_index++];
|
||||
var map_zoom = ls_wdt / g_map_width;
|
||||
start_pos = {x=start_pos[0]*map_zoom+map_zoom/2, y=start_pos[1]*map_zoom};
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start positions not defined or exhausted: Spawn in lower area for both maps becuase starting high is an an advantage.
|
||||
start_pos = FindLocation(Loc_InRect(ls_wdt/5,ls_hgt/2,ls_wdt*3/5,ls_hgt/3), Loc_Wall(CNAT_Bottom), Loc_Func(Scenario.IsStartSpot));
|
||||
if (!start_pos) start_pos = FindLocation(Loc_InRect(ls_wdt/10,0,ls_wdt*8/10,ls_hgt*4/5), Loc_Wall(CNAT_Bottom), Loc_Func(Scenario.IsStartSpot));
|
||||
if (!start_pos) start_pos = {x=Random(ls_wdt*6/10)+ls_wdt*2/10, y=ls_hgt*58/100};
|
||||
}
|
||||
crew->SetPosition(start_pos.x, start_pos.y-10);
|
||||
// initial material
|
||||
crew->CreateContents(Shovel);
|
||||
|
|
|
@ -11,4 +11,8 @@ GraphicsPortraitMaleBrownHair.png, MaleBrownHair.jpg,
|
|||
GraphicsPortraitMaleDarkHair.png, MaleDarkHair.jpg,
|
||||
GraphicsPortraitSage.png, Sage.jpg,
|
||||
GraphicsPortraitYoungster.png, Youngster.jpg,
|
||||
GraphicsPortraitYoungsterBlond.png, YoungsterBlond.jpg
|
||||
GraphicsPortraitYoungsterBlond.png, YoungsterBlond.jpg
|
||||
|
||||
The following graphics are created by Clonkonaut and are licensed under CC-BY 3.0 (http://creativecommons.org/licenses/by/3.0/):
|
||||
|
||||
GraphicsPortraitMime.png, Mime.png, MimeOverlay.png
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
@ -0,0 +1,39 @@
|
|||
material Clonk_Mime
|
||||
{
|
||||
receive_shadows on
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
ambient 1.000000 1.000000 1.000000 1.000000
|
||||
diffuse 1.000000 1.000000 1.000000 1.000000
|
||||
specular 0.000000 0.000000 0.000000 1.000000 3.000000
|
||||
emissive 0.000000 0.000000 0.000000 1.000000
|
||||
|
||||
texture_unit Overlay
|
||||
{
|
||||
texture MimeOverlay.png
|
||||
tex_address_mode wrap
|
||||
filtering trilinear
|
||||
colour_op_ex modulate src_texture src_player_colour
|
||||
// take alpha from texture only, ignore player alpha
|
||||
alpha_op_ex source1 src_texture src_player_colour
|
||||
}
|
||||
texture_unit Clonk
|
||||
{
|
||||
texture Mime.png
|
||||
tex_address_mode wrap
|
||||
filtering trilinear
|
||||
colour_op_ex blend_current_alpha src_current src_texture
|
||||
// Don't blend alpha, to make sure we have full intensity at the base/overlay border region
|
||||
alpha_op_ex add src_current src_texture
|
||||
}
|
||||
texture_unit Light
|
||||
{
|
||||
// apply lighting
|
||||
colour_op_ex modulate src_current src_diffuse
|
||||
alpha_op_ex modulate src_current src_diffuse
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 546 KiB After Width: | Height: | Size: 546 KiB |
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
@ -34,6 +34,7 @@ global func SetAlternativeSkin(string skin_name)
|
|||
["MaleBlackHair", 0, 0x4040ff],
|
||||
["MaleBrownHair", 0, 0x2020ff],
|
||||
["MaleDarkHair", 0, 0x406d99],
|
||||
["Mime", 2, 0xffffff],
|
||||
["Sage", 0, 0x813100],
|
||||
["Youngster", 0, 0xba8e37],
|
||||
["YoungsterBlond", 0, 0x151366]
|
||||
|
|
|
@ -284,43 +284,3 @@ material CrashedAirplane
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
material clonkMime
|
||||
{
|
||||
receive_shadows on
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
ambient 1.000000 1.000000 1.000000 1.000000
|
||||
diffuse 1.000000 1.000000 1.000000 1.000000
|
||||
specular 0.000000 0.000000 0.000000 1.000000 3.000000
|
||||
emissive 0.000000 0.000000 0.000000 1.000000
|
||||
|
||||
texture_unit Overlay
|
||||
{
|
||||
texture clonkMimeOverlay.png
|
||||
tex_address_mode wrap
|
||||
filtering trilinear
|
||||
colour_op_ex modulate src_texture src_player_colour
|
||||
// take alpha from texture only, ignore player alpha
|
||||
alpha_op_ex source1 src_texture src_player_colour
|
||||
}
|
||||
texture_unit Clonk
|
||||
{
|
||||
texture clonkMime.png
|
||||
tex_address_mode wrap
|
||||
filtering trilinear
|
||||
colour_op_ex blend_current_alpha src_current src_texture
|
||||
// Don't blend alpha, to make sure we have full intensity at the base/overlay border region
|
||||
alpha_op_ex add src_current src_texture
|
||||
}
|
||||
texture_unit Light
|
||||
{
|
||||
// apply lighting
|
||||
colour_op_ex modulate src_current src_diffuse
|
||||
alpha_op_ex modulate src_current src_diffuse
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -386,9 +386,8 @@ func Statue_Death()
|
|||
while (i--) EliminatePlayer(GetPlayerByIndex(i, C4PT_User));
|
||||
// Statue down :(
|
||||
CastObjects(Nugget, 5, 10);
|
||||
Explode(10);
|
||||
ScheduleCall(nil, Global.GameOver, 50, 1);
|
||||
return true;
|
||||
return Explode(10);
|
||||
}
|
||||
|
||||
/* Developer commands */
|
||||
|
|
Before Width: | Height: | Size: 292 KiB After Width: | Height: | Size: 293 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
@ -28,10 +28,8 @@ func InitializeObjects()
|
|||
|
||||
var Tree_Coniferous2003 = CreateObjectAbove(Tree_Coniferous2, 347, 565);
|
||||
var Tree_Coniferous2004 = CreateObjectAbove(Tree_Coniferous2, 422, 558);
|
||||
CreateObjectAbove(Tree_Coniferous2, 1329, 384);
|
||||
CreateObjectAbove(Tree_Coniferous2, 1364, 364);
|
||||
CreateObjectAbove(Tree_Coniferous2, 1389, 327);
|
||||
CreateObjectAbove(Tree_Coniferous2, 1295, 398);
|
||||
CreateObjectAbove(Tree_Coniferous2, 1404, 390);
|
||||
CreateObjectAbove(Tree_Coniferous2, 1290, 403);
|
||||
|
||||
CreateObject(Fern, 1331, 701);
|
||||
CreateObject(Fern, 1468, 661);
|
||||
|
@ -143,7 +141,7 @@ func InitializeObjects()
|
|||
CreateObject(Loam, 1360, 781);
|
||||
CreateObject(Loam, 1519, 721);
|
||||
CreateObject(Loam, 1348, 718);
|
||||
CreateObject(Loam, 1379, 349);
|
||||
CreateObject(Loam, 1358, 388);
|
||||
CreateObject(Loam, 559, 1120);
|
||||
CreateObject(Loam, 505, 850);
|
||||
CreateObject(Loam, 517, 858);
|
||||
|
|
|
@ -259,8 +259,8 @@ func Intro_Stop()
|
|||
if (plane)
|
||||
{
|
||||
plane->FaceLeft();
|
||||
plane->SetR(-130);
|
||||
plane->SetPosition(1387, 238);
|
||||
plane->SetR(-90);
|
||||
plane->SetPosition(1387, 345);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -17,9 +17,6 @@ func InitializeObjects()
|
|||
|
||||
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);
|
||||
|
@ -118,16 +115,6 @@ func InitializeObjects()
|
|||
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";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
MsgEncounterCave=An intruder tries to steal out gold. Catch him!
|
||||
MsgEncounterCave=An intruder tries to steal our gold. Catch him!
|
||||
MsgEncounterOutpost=Stop, in the name of the king!
|
||||
MsgEncounterKing=Ah, %s. I have been awaiting you.
|
||||
MsgEncounterShrooms=What is this in the cave? Fireworks? Maybe we can use them to get into the castle.
|
||||
|
|
|
@ -352,8 +352,10 @@ func InitializeObjects()
|
|||
Crate001->CreateContents(Hammer);
|
||||
ToolsWorkshop001->CreateContents(Hammer, 2);
|
||||
|
||||
Foundry002->CreateContents(Bucket, 3);
|
||||
CreateObjectAbove(Bucket, 435, 1271);
|
||||
CreateObjectAbove(Bucket, 943, 775);
|
||||
CreateObjectAbove(Bucket, 944, 775);
|
||||
CreateObjectAbove(Bucket, 946, 775);
|
||||
|
||||
CreateObjectAbove(Crate, 2849, 607);
|
||||
CreateObjectAbove(Crate, 444, 1271);
|
||||
|
|
|
@ -114,7 +114,7 @@ Mave7=Wie komme ich über den See?
|
|||
Mave8=Du könntest meinen Hochofen nutzen, um Lehm zu bauen.
|
||||
Mave9=Wie funktioniert das mit dem Lehm?
|
||||
Mave10=Oh, das ist ganz einfach: Fülle einen Eimer{{Bucket}} mit Erde und ein Fass{{Barrel}} mit Wasser, lege beides in den Hochofen und starte die Lehmproduktion.
|
||||
Mave11=Die Werkzeuge im Hochofen kannst du benutzen.
|
||||
Mave11=Die Werkzeuge beim Hochofen kannst du benutzen.
|
||||
Mave12=Wohin führt der Fahrstuhlschacht?
|
||||
Mave13=Das ist der Fahrstuhl zur Kammer mit unseren Ölreserven. Leider ist der Weg von einem Vulkan geflutet. Hm. Vielleicht könnte man das Wasser aus dem See benutzen, um die Lava abzukühlen.
|
||||
MaveBye=Tschüss.
|
||||
|
|
|
@ -114,7 +114,7 @@ Mave7=How do I cross the lake?
|
|||
Mave8=You could use my foundry to build some loam.
|
||||
Mave9=How do I build loam?
|
||||
Mave10=Oh, that is easy: Fill a bucket{{Bucket}} with earth and fill a barrel{{Barrel}} with water. Then put both into the foundry and produce loam.
|
||||
Mave11=You can find the necessary tools in my foundry.
|
||||
Mave11=You can find the necessary tools in and in front of my foundry.
|
||||
Mave12=Where does this elevator shaft lead?
|
||||
Mave13=This elevator leads to the chamber with our oil reserves. Unfortunately, the path got flooded by the volcano. Maybe water from the lake can be used to extinguish the lava?
|
||||
MaveBye=Bye.
|
||||
|
|
|
@ -6,7 +6,6 @@ Width=512
|
|||
Height=350
|
||||
Offset=-256,-175
|
||||
Picture=0,0,220,110
|
||||
Exclusive=1
|
||||
Components=Cloud=1
|
||||
Oversize=1
|
||||
StretchGrowth=1
|
||||
|
|
|
@ -904,6 +904,8 @@ private func OnContentsSelection(symbol, extra_data)
|
|||
for (var obj in to_transfer)
|
||||
{
|
||||
if (!obj) continue;
|
||||
// Our target might have disappeared (e.g. a construction site completing after the first item).
|
||||
if (!other_target) break;
|
||||
|
||||
var handled = false;
|
||||
// Does the object not want to leave the other container anyway?
|
||||
|
@ -924,7 +926,7 @@ private func OnContentsSelection(symbol, extra_data)
|
|||
// More special handling for Stackable items..
|
||||
handled = obj->~TryPutInto(other_target);
|
||||
// Try to normally collect the object otherwise.
|
||||
if (!handled)
|
||||
if (!handled && other_target && obj)
|
||||
handled = other_target->Collect(obj, true);
|
||||
}
|
||||
if (handled)
|
||||
|
|
|
@ -193,8 +193,7 @@ public func StopDialogue()
|
|||
// clear remembered positions
|
||||
dlg_last_opt_sel = nil;
|
||||
// put on wait for a while; then reenable
|
||||
SetDialogueStatus(DLG_Status_Wait);
|
||||
ScheduleCall(this, this.SetDialogueStatus, 30, 1, DLG_Status_Stop);
|
||||
SetDialogueStatus(DLG_Status_Stop);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -245,7 +244,8 @@ public func Interact(object clonk)
|
|||
if (dlg_status == DLG_Status_Stop)
|
||||
{
|
||||
clonk->CloseMenu();
|
||||
dlg_status = DLG_Status_Active;
|
||||
dlg_status = DLG_Status_Wait;
|
||||
ScheduleCall(this, this.SetDialogueStatus, 30, 0, DLG_Status_Active);
|
||||
// Do a call on a closed dialogue as well.
|
||||
var fn_closed = Format("~Dlg_%s_Closed", dlg_name);
|
||||
if (!Call(fn_closed, clonk, dlg_target))
|
||||
|
|
|
@ -52,7 +52,10 @@ func ControlUseStart(object clonk, int ix, int iy)
|
|||
clonk->SetHandAction(1);
|
||||
clonk->UpdateAttach();
|
||||
clonk->PlayAnimation("StrikePickaxe", CLONK_ANIM_SLOT_Arms, Anim_Linear(0, 0, clonk->GetAnimationLength("StrikePickaxe"), Pickaxe_SwingTime, ANIM_Loop), Anim_Const(1000));
|
||||
AddEffect("IntPickaxe", clonk, 1, 1, this);
|
||||
var fx = AddEffect("IntPickaxe", clonk, 1, 1, this);
|
||||
if (!fx) return false;
|
||||
fx.x = ix;
|
||||
fx.y = iy;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -66,13 +69,12 @@ func ControlUseHolding(object clonk, int new_x, int new_y)
|
|||
clonk->PauseUse(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
x = new_x; y = new_y;
|
||||
var fx = GetEffect("IntPickaxe", clonk);
|
||||
if (!fx) return clonk->CancelUse();
|
||||
fx.x = new_x; fx.y = new_y;
|
||||
return true;
|
||||
}
|
||||
|
||||
local x, y;
|
||||
|
||||
func ControlUseStop(object clonk, int ix, int iy)
|
||||
{
|
||||
Reset(clonk);
|
||||
|
@ -181,11 +183,11 @@ public func FxIntPickaxeTimer(object clonk, proplist effect, int time)
|
|||
++swingtime;
|
||||
if(swingtime >= Pickaxe_SwingTime) // Waits three seconds for animation to run (we could have a clonk swing his pick 3 times)
|
||||
{
|
||||
DoSwing(clonk,x,y);
|
||||
DoSwing(clonk,effect.x,effect.y);
|
||||
swingtime = 0;
|
||||
}
|
||||
|
||||
var angle = Angle(0,0,x,y);
|
||||
var angle = Angle(0,0,effect.x,effect.y);
|
||||
var speed = 50;
|
||||
|
||||
var iPosition = swingtime*180/Pickaxe_SwingTime;
|
||||
|
|
|
@ -59,7 +59,7 @@ public func GetConnectedObject(object obj)
|
|||
|
||||
private func LineBreak(bool no_msg)
|
||||
{
|
||||
Sound("LineBreak");
|
||||
Sound("Objects::LineSnap");
|
||||
if (!no_msg)
|
||||
BreakMessage();
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ public func ControlUseStart(object clonk, int x, int y)
|
|||
DigFree(clonk->GetX(), clonk->GetY(), 10);
|
||||
}
|
||||
|
||||
ControlUseHolding(clonk, x, y); // initial coordinate setup
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -137,10 +139,10 @@ public func FxShovelDigTimer(object clonk, effect, int time)
|
|||
var iPosition = clonk->GetAnimationPosition(iAnimation)*180/clonk->GetAnimationLength("Dig");
|
||||
speed = speed*(Cos(iPosition-45, 50)**2)/2500;
|
||||
|
||||
// limit angle
|
||||
DigAngle = BoundBy(DigAngle,65,300);
|
||||
var dig_xdir = Sin(DigAngle,+speed);
|
||||
var dig_ydir = Cos(DigAngle,-speed);
|
||||
// Limit the digging angle: one can dig maximally 30 degrees upwards.
|
||||
DigAngle = BoundBy(DigAngle, 60, 300);
|
||||
var dig_xdir = Sin(DigAngle, speed);
|
||||
var dig_ydir = -Cos(DigAngle, speed);
|
||||
|
||||
// Stuck-check: When player wants to go horizontally while standing on the ground but can't, add a vertical redirect
|
||||
// This helps with Clonks getting "stuck" not moving on certain terrain when dig speed is not sufficient to push him up a slope
|
||||
|
|
|
@ -227,12 +227,12 @@ global func FxTeleGloveReleasedStart(object target, effect)
|
|||
return;
|
||||
}
|
||||
|
||||
global func FxTeleGloveWeightStart(object target, int num)
|
||||
global func FxTeleGloveWeightStart(object target, proplist effect)
|
||||
{
|
||||
target->SetMass(target->GetMass()/2);
|
||||
}
|
||||
|
||||
global func FxTeleGloveWeightStop(object target, int num, int reason, bool temp)
|
||||
global func FxTeleGloveWeightStop(object target, proplist effect, int reason, bool temp)
|
||||
{
|
||||
target->SetMass(target->GetDefCoreVal("Mass", "DefCore"));
|
||||
}
|
||||
|
|
|
@ -9,9 +9,10 @@ static const CONSTRUCTION_STICK_Left = 1;
|
|||
static const CONSTRUCTION_STICK_Right = 2;
|
||||
static const CONSTRUCTION_STICK_Bottom = 4;
|
||||
|
||||
local dimension_x, dimension_y, clonk, structure, direction, stick_to, blocked;
|
||||
local extra_overlay, dimension_x, dimension_y, clonk, structure, direction, stick_to, blocked;
|
||||
local GFX_StructureOverlay = 1;
|
||||
local GFX_CombineIconOverlay = 2;
|
||||
local GFX_PreviewerPictureOverlay = 2;
|
||||
|
||||
public func GetFlipDescription() { return "$TxtFlipDesc$"; }
|
||||
|
||||
|
@ -23,14 +24,19 @@ func Initialize()
|
|||
func Set(id to_construct, object constructing_clonk)
|
||||
{
|
||||
SetGraphics(nil, to_construct, GFX_StructureOverlay, GFXOV_MODE_Base);
|
||||
SetGraphics(nil, to_construct, 3, GFXOV_MODE_Picture, nil, GFX_BLIT_Wireframe);
|
||||
SetGraphics(nil, to_construct, GFX_PreviewerPictureOverlay, GFXOV_MODE_Picture, nil, GFX_BLIT_Wireframe);
|
||||
// Buildings may add something to the preview and can do so on GFX_PreviewerPictureOverlay
|
||||
// This is used by the elevator to preview the case
|
||||
// The definition should return true
|
||||
extra_overlay = to_construct->~ConstructionPreview(this, GFX_PreviewerPictureOverlay, direction);
|
||||
dimension_x = to_construct->GetDefWidth();
|
||||
dimension_y = to_construct->GetDefHeight();
|
||||
|
||||
clonk = constructing_clonk;
|
||||
structure = to_construct;
|
||||
direction = DIR_Left;
|
||||
blocked = true;
|
||||
// Allow the definition to draw an alternative preview.
|
||||
to_construct->~AlternativeConstructionPreview(this, direction);
|
||||
AdjustPreview(structure->~IsBelowSurfaceConstruction());
|
||||
return;
|
||||
}
|
||||
|
@ -60,7 +66,10 @@ public func AdjustPreview(bool below_surface, bool look_up, bool no_call)
|
|||
if (blocked && !no_call)
|
||||
return AdjustPreview(below_surface, !look_up, true);
|
||||
if (blocked)
|
||||
{
|
||||
if (extra_overlay) SetClrModulation(RGBa(255,50,50, 100), GFX_PreviewerPictureOverlay);
|
||||
return SetClrModulation(RGBa(255,50,50, 100), GFX_StructureOverlay);
|
||||
}
|
||||
// Position depends on whether the object should below surface.
|
||||
if (!below_surface)
|
||||
SetPosition(GetX(), GetY() + y);
|
||||
|
@ -80,12 +89,21 @@ public func AdjustPreview(bool below_surface, bool look_up, bool no_call)
|
|||
if(!blocked)
|
||||
{
|
||||
if (!stick_to)
|
||||
{
|
||||
if (extra_overlay) SetClrModulation(RGBa(50,255,50, 100), GFX_PreviewerPictureOverlay);
|
||||
SetClrModulation(RGBa(50,255,50, 100), GFX_StructureOverlay);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (extra_overlay) SetClrModulation(RGBa(255,255,50, 200), GFX_PreviewerPictureOverlay);
|
||||
SetClrModulation(RGBa(255,255,50, 200), GFX_StructureOverlay);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (extra_overlay) SetClrModulation(RGBa(255,50,50, 100), GFX_PreviewerPictureOverlay);
|
||||
SetClrModulation(RGBa(255,50,50, 100), GFX_StructureOverlay);
|
||||
}
|
||||
}
|
||||
|
||||
// Positions the preview according to the mouse cursor, calls AdjustPreview afterwards
|
||||
|
@ -119,6 +137,14 @@ func Reposition(int x, int y)
|
|||
x = other->GetX() + other->GetObjWidth()/2 + dimension_x / 2;
|
||||
if ((stick_dir & CONSTRUCTION_STICK_Bottom))
|
||||
y = other->GetY() + other->GetObjHeight()/2 + dimension_y / 2;
|
||||
// Add an additional offset if needed, for example a basement can be place
|
||||
// only under a part of the structure.
|
||||
var stick_offset = structure->~ConstructionCombineOffset(other);
|
||||
if (stick_offset)
|
||||
{
|
||||
x += stick_offset[0];
|
||||
y += stick_offset[1];
|
||||
}
|
||||
stick_to = other;
|
||||
found = true;
|
||||
}
|
||||
|
@ -134,7 +160,7 @@ func Reposition(int x, int y)
|
|||
stick_to = nil;
|
||||
SetGraphics(nil, nil, GFX_CombineIconOverlay);
|
||||
}
|
||||
else if (stick_to)
|
||||
else if (stick_to)
|
||||
{
|
||||
SetGraphics(nil, ConstructionPreviewer_IconCombine, GFX_CombineIconOverlay, GFXOV_MODE_Base);
|
||||
var dir = 1;
|
||||
|
@ -143,7 +169,10 @@ func Reposition(int x, int y)
|
|||
dir = 0;
|
||||
SetObjDrawTransform(1000, 0, dimension_x/2 * 1000 * dir, 0, 1000, 0, GFX_CombineIconOverlay);
|
||||
}
|
||||
|
||||
// Update the extra overlay possibly added to the preview.
|
||||
extra_overlay = structure->~ConstructionPreview(this, GFX_PreviewerPictureOverlay, direction);
|
||||
// Update alternative preview in the definition to be placed.
|
||||
structure->~AlternativeConstructionPreview(this, direction, stick_to);
|
||||
SetPosition(x, y);
|
||||
AdjustPreview(structure->~IsBelowSurfaceConstruction());
|
||||
}
|
||||
|
@ -162,6 +191,8 @@ func Flip()
|
|||
direction = DIR_Left;
|
||||
SetObjDrawTransform(1000,0,0, 0,1000,0, GFX_StructureOverlay);
|
||||
}
|
||||
if (extra_overlay)
|
||||
structure->~ConstructionPreview(this, GFX_PreviewerPictureOverlay, direction);
|
||||
}
|
||||
|
||||
// UI not saved.
|
||||
|
|
|
@ -133,13 +133,19 @@ public func Set(id def, int dir, object stick)
|
|||
definition = def;
|
||||
direction = dir;
|
||||
stick_to = stick;
|
||||
|
||||
// Set the shape of the construction site.
|
||||
var w = def->~GetSiteWidth(direction, stick_to) ?? def->GetDefWidth();
|
||||
var h = def->~GetSiteHeight(direction, stick_to) ?? def->GetDefHeight();
|
||||
// Height of construction site needs to exceed 12 pixels for the clonk to be able to add materials.
|
||||
var site_h = Max(12, h);
|
||||
SetShape(-w/2, -site_h, w, site_h);
|
||||
// Increase shape for below surface constructions to allow for adding materials.
|
||||
if (definition->~IsBelowSurfaceConstruction())
|
||||
SetShape(-w/2, -2 * site_h, w, 2 * site_h);
|
||||
|
||||
var xw = (1 - dir * 2) * 1000;
|
||||
var w, h;
|
||||
w = def->GetDefWidth();
|
||||
h = def->GetDefHeight();
|
||||
// Draw the building with a wired frame and large alpha unless site graphics is overloaded by definition
|
||||
if (!def->~SetConstructionSiteOverlay(this, direction, stick_to))
|
||||
if (!definition->~SetConstructionSiteOverlay(this, direction, stick_to))
|
||||
{
|
||||
SetGraphics(nil, nil, 0);
|
||||
SetGraphics(nil, def, 1, GFXOV_MODE_Base);
|
||||
|
@ -151,22 +157,14 @@ public func Set(id def, int dir, object stick)
|
|||
SetClrModulation(RGBa(255, 255, 255, 50), 1);
|
||||
SetGraphics(nil, def, 2, GFXOV_MODE_Base, nil, GFX_BLIT_Wireframe);
|
||||
}
|
||||
SetGraphics("", GetID(), 3, GFXOV_MODE_ExtraGraphics);
|
||||
SetObjDrawTransform((1 - dir * 2) * 1000, 0, 0, 0, 1000, -h * 500, 1);
|
||||
SetObjDrawTransform((1 - dir * 2) * 1000, 0, 0, 0, 1000, -h * 500, 2);
|
||||
}
|
||||
SetObjDrawTransform(xw,0,0,0,1000, -h*500,1);
|
||||
SetObjDrawTransform(xw,0,0,0,1000, -h*500,2);
|
||||
// Height of construction site needs to exceed 12 pixels for the clonk to be able to add materials.
|
||||
h = Max(12, h);
|
||||
SetShape(-w/2, -h, w, h);
|
||||
// Increase shape for below surface constructions to allow for adding materials.
|
||||
if (definition->~IsBelowSurfaceConstruction())
|
||||
SetShape(-w/2, -2 * h, w, 2 * h);
|
||||
|
||||
SetName(Format(Translate("TxtConstruction"),def->GetName()));
|
||||
|
||||
this.visibility = VIS_Owner | VIS_Allies;
|
||||
|
||||
|
||||
SetName(Format(Translate("TxtConstruction"), def->GetName()));
|
||||
this.visibility = VIS_Owner | VIS_Allies;
|
||||
ShowMissingComponents();
|
||||
return;
|
||||
}
|
||||
|
||||
// Scenario saving
|
||||
|
|
|
@ -128,14 +128,14 @@ public func IsFulfilled() { return true; }
|
|||
// Overload: return the current description for this goal.
|
||||
public func GetDescription(int plr)
|
||||
{
|
||||
return "WARNING: GetDescription(int plr) not overloaded by goal";
|
||||
return this.Description ?? "WARNING: GetDescription(int plr) not overloaded by goal";
|
||||
}
|
||||
|
||||
protected func Activate(plr)
|
||||
{
|
||||
if (IsFulfilled())
|
||||
return(MessageWindow("$MsgGoalFulfilled$", plr));
|
||||
return MessageWindow(GetProperty("Description"), plr);
|
||||
return MessageWindow(this->GetDescription(plr));
|
||||
}
|
||||
|
||||
// Scenario sacing
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
[DefCore]
|
||||
id=Library_PowerDisplay
|
||||
Version=6,0
|
||||
Category=C4D_StaticBack
|
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
Power Display
|
||||
Include this library into a structure that should display
|
||||
the status of the power network in the interaction menu.
|
||||
|
||||
@author Maikel
|
||||
*/
|
||||
|
||||
|
||||
// This object is a power display.
|
||||
public func IsPowerDisplay() { return true; }
|
||||
|
||||
|
||||
/*-- Interaction Menu --*/
|
||||
|
||||
public func HasInteractionMenu() { return true; }
|
||||
|
||||
public func GetInteractionMenus(object clonk)
|
||||
{
|
||||
var menus = _inherited() ?? [];
|
||||
// Only add a power menu if the structure is a flagpole (Library_Flag).
|
||||
if (this->~IsFlagpole())
|
||||
{
|
||||
var power_menu =
|
||||
{
|
||||
title = "$MsgPowerOverview$",
|
||||
entries_callback = this.GetPowerDisplayMenuEntries,
|
||||
callback_hover = "OnPowerDisplayHover",
|
||||
callback_target = this,
|
||||
BackgroundColor = RGB(0, 50, 50),
|
||||
Priority = 20
|
||||
};
|
||||
PushBack(menus, power_menu);
|
||||
}
|
||||
return menus;
|
||||
}
|
||||
|
||||
public func GetPowerDisplayMenuEntries(object clonk)
|
||||
{
|
||||
var menu_entries = [];
|
||||
// Get the power network for this object.
|
||||
var power_network = this->GetPowerHelper();
|
||||
if (!power_network)
|
||||
return menu_entries;
|
||||
|
||||
// Get all the power data.
|
||||
var power_production_current = power_network->GetActivePowerAvailable(true) / 10;
|
||||
var power_production_capacity = power_network->GetBarePowerAvailable() / 10;
|
||||
var power_consumption_current = power_network->GetPowerConsumption(true) / 10;
|
||||
var power_consumption_need = power_network->GetPowerConsumptionNeed() / 10;
|
||||
var power_stored = power_network->GetStoredPower();
|
||||
var power_stored_capacity = power_network->GetStoredPowerCapacity();
|
||||
|
||||
// Show power production.
|
||||
var entry =
|
||||
{
|
||||
Bottom = "1.1em",
|
||||
BackgroundColor = {Std = 0, OnHover = 0x50ff0000},
|
||||
Priority = 0,
|
||||
text =
|
||||
{
|
||||
Style = GUI_TextVCenter | GUI_TextLeft,
|
||||
Text = Format("$MsgPowerProduction$ %d {{Icon_Lightbulb}} ($MsgPowerProductionCapacity$ %d {{Icon_Lightbulb}})", power_production_current, power_production_capacity)
|
||||
}
|
||||
};
|
||||
PushBack(menu_entries, {symbol = Icon_Lightbulb, extra_data = "production", custom = entry});
|
||||
|
||||
// Show power consumption.
|
||||
var entry =
|
||||
{
|
||||
Bottom = "1.1em",
|
||||
BackgroundColor = {Std = 0, OnHover = 0x50ff0000},
|
||||
Priority = 1,
|
||||
text =
|
||||
{
|
||||
Style = GUI_TextVCenter | GUI_TextLeft,
|
||||
Text = Format("$MsgPowerConsumption$ %d {{Icon_Lightbulb}} ($MsgPowerConsumptionDemand$ %d {{Icon_Lightbulb}})", power_consumption_current, power_consumption_need)
|
||||
}
|
||||
};
|
||||
PushBack(menu_entries, {symbol = Icon_Lightbulb, extra_data = "consumption", custom = entry});
|
||||
|
||||
// Show power storage.
|
||||
var entry =
|
||||
{
|
||||
Bottom = "1.1em",
|
||||
BackgroundColor = {Std = 0, OnHover = 0x50ff0000},
|
||||
Priority = 2,
|
||||
text =
|
||||
{
|
||||
Style = GUI_TextVCenter | GUI_TextLeft,
|
||||
Text = Format("$MsgPowerStored$ %s {{Icon_Lightbulb}} ($MsgPowerStoredCapacity$ %s {{Icon_Lightbulb}})", GetStoredPowerString(power_stored), GetStoredPowerString(power_stored_capacity))
|
||||
}
|
||||
};
|
||||
PushBack(menu_entries, {symbol = Icon_Lightbulb, extra_data = "storage", custom = entry});
|
||||
return menu_entries;
|
||||
}
|
||||
|
||||
// Update the hover info display of the interaction menu.
|
||||
public func OnPowerDisplayHover(id symbol, string extra_data, desc_menu_target, menu_id)
|
||||
{
|
||||
var text = "";
|
||||
// Get the power network for this object.
|
||||
var power_network = this->GetPowerHelper();
|
||||
if (power_network)
|
||||
{
|
||||
// Display the info dependent on which items is hovered.
|
||||
if (extra_data == "production")
|
||||
{
|
||||
var power_production_current = power_network->GetActivePowerAvailable(true) / 10;
|
||||
var power_production_capacity = power_network->GetBarePowerAvailable() / 10;
|
||||
text = Format("$DescPowerProduction$", power_production_capacity, power_production_current);
|
||||
}
|
||||
else if (extra_data == "consumption")
|
||||
{
|
||||
var power_consumption_current = power_network->GetPowerConsumption(true) / 10;
|
||||
var power_consumption_need = power_network->GetPowerConsumptionNeed() / 10;
|
||||
text = Format("$DescPowerConsumption$", power_consumption_need, power_consumption_current);
|
||||
}
|
||||
else if (extra_data == "storage")
|
||||
{
|
||||
var power_stored = GetStoredPowerString(power_network->GetStoredPower());
|
||||
var power_stored_capacity = GetStoredPowerString(power_network->GetStoredPowerCapacity());
|
||||
text = Format("$DescPowerStored$", power_stored, power_stored_capacity, power_stored);
|
||||
}
|
||||
}
|
||||
GuiUpdateText(text, menu_id, 1, desc_menu_target);
|
||||
return;
|
||||
}
|
||||
|
||||
private func GetStoredPowerString(int stored_power)
|
||||
{
|
||||
// Show power per bulb per minute.
|
||||
stored_power /= (36 * 60);
|
||||
var unit = stored_power / 10;
|
||||
var decimal = stored_power % 10;
|
||||
return Format("%d.%d", unit, decimal);
|
||||
}
|
||||
|
||||
// Called when the power balance of this network changed.
|
||||
public func OnPowerBalanceChange(object network)
|
||||
{
|
||||
// Update the interaction menus.
|
||||
UpdateInteractionMenus(this.GetPowerDisplayMenuEntries);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
MsgPowerOverview=Stromübersicht
|
||||
MsgPowerProduction=Stromproduktion:
|
||||
MsgPowerProductionCapacity=gesamte Kapazität
|
||||
MsgPowerConsumption=Stromverbrauch:
|
||||
MsgPowerConsumptionDemand=gesamte Nachfrage
|
||||
MsgPowerStored=Gespeicherter Strom:
|
||||
MsgPowerStoredCapacity=gesamte Kapazität
|
||||
|
||||
DescPowerProduction=All the power producers in this network together have a capacity of producing %d {{Icon_Lightbulb}}, currently %d {{Icon_Lightbulb}} is being produced.
|
||||
DescPowerConsumption=Currently the consumers in this network demand %d {{Icon_Lightbulb}} in total to operate, %d {{Icon_Lightbulb}} is currently being supplied.
|
||||
DescPowerStored=Power storages are currently holding %s {{Icon_Lightbulb}} out of their total capacity of %s {{Icon_Lightbulb}}. This is equivalent of powering a consumer using up one {{Icon_Lightbulb}} for %s minutes.
|
|
@ -0,0 +1,11 @@
|
|||
MsgPowerOverview=Power Overview
|
||||
MsgPowerProduction=Power production:
|
||||
MsgPowerProductionCapacity=total capacity
|
||||
MsgPowerConsumption=Power consumption:
|
||||
MsgPowerConsumptionDemand=total demand
|
||||
MsgPowerStored=Stored power:
|
||||
MsgPowerStoredCapacity=total capacity
|
||||
|
||||
DescPowerProduction=All the power producers in this network together have a capacity of producing %d {{Icon_Lightbulb}}, currently %d {{Icon_Lightbulb}} is being produced.
|
||||
DescPowerConsumption=Currently the consumers in this network demand %d {{Icon_Lightbulb}} in total to operate, %d {{Icon_Lightbulb}} is currently being supplied.
|
||||
DescPowerStored=Power storages are currently holding %s {{Icon_Lightbulb}} out of their total capacity of %s {{Icon_Lightbulb}}. This is equivalent of powering a consumer using up one {{Icon_Lightbulb}} for %s minutes.
|
|
@ -440,6 +440,8 @@ public func CheckPowerBalance()
|
|||
// The producers may be underproducing, however, still producing too much for the
|
||||
// active consumer need. Deactivate producers to correct for this.
|
||||
PostRefreshProducers(GetActivePowerAvailable() - GetPowerConsumption());
|
||||
// Notify other objects depending on the power system the balance has changed.
|
||||
NotifyOnPowerBalanceChange();
|
||||
// Debugging logs.
|
||||
//LogState(Format("balance_end nd_power = %d, av_power = %d", needed_power, GetActivePowerAvailable()));
|
||||
return;
|
||||
|
@ -477,13 +479,13 @@ public func GetBarePowerAvailable()
|
|||
}
|
||||
|
||||
// Returns the total active power available in the network.
|
||||
public func GetActivePowerAvailable()
|
||||
public func GetActivePowerAvailable(bool exclude_storages)
|
||||
{
|
||||
var total = 0;
|
||||
for (var index = GetLength(lib_power.active_producers) - 1; index >= 0; index--)
|
||||
{
|
||||
var link = lib_power.active_producers[index];
|
||||
if (!link)
|
||||
if (!link || (exclude_storages && link.obj->~IsPowerStorage()))
|
||||
continue;
|
||||
total += link.prod_amount;
|
||||
}
|
||||
|
@ -491,14 +493,14 @@ public func GetActivePowerAvailable()
|
|||
}
|
||||
|
||||
// Returns the amount of power the currently active power consumers need.
|
||||
public func GetPowerConsumption()
|
||||
public func GetPowerConsumption(bool exclude_storages)
|
||||
{
|
||||
var total = 0;
|
||||
for (var index = GetLength(lib_power.active_consumers) - 1; index >= 0; index--)
|
||||
{
|
||||
var link = lib_power.active_consumers[index];
|
||||
// If the link does not exist or has no power need, just continue.
|
||||
if (!link || !link.obj->HasPowerNeed())
|
||||
if (!link || !link.obj->HasPowerNeed() || (exclude_storages && link.obj->~IsPowerStorage()))
|
||||
continue;
|
||||
total += link.cons_amount;
|
||||
}
|
||||
|
@ -521,6 +523,34 @@ public func GetPowerConsumptionNeed()
|
|||
return total;
|
||||
}
|
||||
|
||||
// Returns the total stored power of all power storages in the network (in power frames).
|
||||
public func GetStoredPower()
|
||||
{
|
||||
var total = 0;
|
||||
var all_links = GetAllPowerLinks();
|
||||
for (var index = GetLength(all_links) - 1; index >= 0; index--)
|
||||
{
|
||||
var link = all_links[index];
|
||||
if (link && link.obj->~IsPowerStorage())
|
||||
total += link.obj->GetStoredPower();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
// Returns the total capacity for storing power of all power storages in the network (in power frames).
|
||||
public func GetStoredPowerCapacity()
|
||||
{
|
||||
var total = 0;
|
||||
var all_links = GetAllPowerLinks();
|
||||
for (var index = GetLength(all_links) - 1; index >= 0; index--)
|
||||
{
|
||||
var link = all_links[index];
|
||||
if (link && link.obj->~IsPowerStorage())
|
||||
total += link.obj->GetStorageCapacity();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
// Activates producers according to priotrity from all producers in the network until needed power is met.
|
||||
// This function automatically deactivates producers which had a lower priority over newly activated ones.
|
||||
private func RefreshProducers(int power_need)
|
||||
|
@ -731,6 +761,18 @@ private func UpdatePriorities(array link_list, bool for_consumers)
|
|||
return;
|
||||
}
|
||||
|
||||
// Called when the power balance of this network changes: notify other objects depending on this.
|
||||
private func NotifyOnPowerBalanceChange()
|
||||
{
|
||||
// Notify all power display objects a balance change has occured.
|
||||
for (var display_obj in FindObjects(Find_Func("IsPowerDisplay")))
|
||||
{
|
||||
if (Library_Power->GetPowerNetwork(display_obj) == this)
|
||||
display_obj->~OnPowerBalanceChange(this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-- Network State --*/
|
||||
|
||||
|
@ -767,6 +809,29 @@ public func GetConsumerLink(object link)
|
|||
return;
|
||||
}
|
||||
|
||||
// Returns a list of all the power links in this network.
|
||||
public func GetAllPowerLinks()
|
||||
{
|
||||
// Combine producers and consumers into a list of all links.
|
||||
var all_producers = Concatenate(lib_power.idle_producers, lib_power.active_producers);
|
||||
var all_consumers = Concatenate(lib_power.waiting_consumers, lib_power.active_consumers);
|
||||
var all_links = Concatenate(all_producers, all_consumers);
|
||||
// Remove duplicate entries with the same link object.
|
||||
for (var index = GetLength(all_links) - 1; index >= 1; index--)
|
||||
{
|
||||
var obj = all_links[index].obj;
|
||||
for (var test_index = index - 1; test_index >= 0; test_index--)
|
||||
{
|
||||
if (obj == all_links[test_index].obj)
|
||||
{
|
||||
RemoveArrayIndex(all_links, index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return all_links;
|
||||
}
|
||||
|
||||
|
||||
/*-- Logging --*/
|
||||
|
||||
|
|
|
@ -112,14 +112,28 @@ public func GetProductionMenuEntries(object clonk)
|
|||
PushBack(menu_entries, {symbol = product, extra_data = nil, custom = entry});
|
||||
}
|
||||
|
||||
// At the bottom of the menu, we add some helpful information about the additional features.
|
||||
// Below the symbols, we leave some space for a progress bar to indicate the current product progress.
|
||||
var entry =
|
||||
{
|
||||
Style = GUI_TextBottom,
|
||||
Bottom = "2em", BackgroundColor = RGBa(0, 0, 0, 100),
|
||||
Bottom = "1em", BackgroundColor = RGBa(0, 0, 0, 50),
|
||||
Priority = 999998,
|
||||
bar =
|
||||
{
|
||||
BackgroundColor = RGBa(200, 200, 200, 100),
|
||||
Right = "0%"
|
||||
}
|
||||
};
|
||||
var updating_effect = AddEffect("IntUpgradeProductProgressBar", this, 1, 2, this);
|
||||
PushBack(menu_entries, {symbol = nil, extra_data = nil, custom = entry, fx = updating_effect});
|
||||
// At the bottom of the menu, we add some helpful information about the additional features.
|
||||
entry =
|
||||
{
|
||||
Style = GUI_TextBottom | GUI_FitChildren,
|
||||
Bottom = "1em", BackgroundColor = RGBa(0, 0, 0, 100),
|
||||
Priority = 999999,
|
||||
Text = Format("<c 666666>%s + $Click$: $InfiniteProduction$</c>", GetPlayerControlAssignment(clonk->GetOwner(), CON_ModifierMenu1, true))
|
||||
};
|
||||
|
||||
PushBack(menu_entries, {symbol = nil, extra_data = nil, custom = entry});
|
||||
return menu_entries;
|
||||
}
|
||||
|
@ -180,6 +194,43 @@ private func GetCostString(int amount, bool available)
|
|||
return Format("<c ff0000>%dx</c>", amount);
|
||||
}
|
||||
|
||||
public func FxIntUpgradeProductProgressBarOnMenuOpened(object target, effect fx, int main_ID, int entry_ID, proplist menu_target)
|
||||
{
|
||||
fx.main_ID = main_ID;
|
||||
fx.entry_ID = entry_ID;
|
||||
fx.menu_target = menu_target;
|
||||
// Force update on first 'Timer' call.
|
||||
fx.is_showing = true;
|
||||
EffectCall(target, fx, "Timer");
|
||||
}
|
||||
|
||||
public func FxIntUpgradeProductProgressBarTimer(object target, effect fx, int time)
|
||||
{
|
||||
if (fx.menu_target == nil) return FX_OK;
|
||||
// Find (new?) production effect if not already given.
|
||||
if (fx.production_effect == nil)
|
||||
{
|
||||
fx.production_effect = GetEffect("ProcessProduction", this);
|
||||
if (fx.production_effect == nil)
|
||||
{
|
||||
if (fx.is_showing)
|
||||
{
|
||||
fx.is_showing = false;
|
||||
GuiUpdate({Text = "<c 777777>$Producing$: -</c>", bar = {Right = "0%"}}, fx.main_ID, fx.entry_ID, fx.menu_target);
|
||||
}
|
||||
return FX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
fx.is_showing = true;
|
||||
var max = ProductionTime(fx.production_effect.Product);
|
||||
var current = Min(max, fx.production_effect.Duration);
|
||||
var percent = 1000 * current / max;
|
||||
var percent_string = Format("%d.%d%%", percent / 10, percent % 10);
|
||||
GuiUpdate({Text = Format("<c aaaaaa>$Producing$: %s</c>", fx.production_effect.Product->GetName()), bar = {Right = percent_string}}, fx.main_ID, fx.entry_ID, fx.menu_target);
|
||||
return FX_OK;
|
||||
}
|
||||
|
||||
/*-- Production properties --*/
|
||||
|
||||
// This function may be overloaded by the actual producer.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
Production=Produktion
|
||||
Producing=Produziert
|
||||
QueueRemove=Eins weniger produzieren.
|
||||
InfiniteProduction=Endlosproduktion
|
||||
Click=Klick
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
Production=Production
|
||||
Producing=Producing
|
||||
QueueRemove=Produce one less.
|
||||
InfiniteProduction=Infinite production
|
||||
Click=Click
|
||||
|
|
|
@ -122,7 +122,14 @@ private func TransferInventory(object from, object to)
|
|||
while (i--)
|
||||
if (contents = from->Contents(i))
|
||||
if (contents->~IsDroppedOnDeath(from))
|
||||
{
|
||||
contents->Exit();
|
||||
}
|
||||
else
|
||||
{
|
||||
// The new clonk doesn't burn. To be consistent, also extinguish contents
|
||||
contents->Extinguish();
|
||||
}
|
||||
return to->GrabContents(from);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,16 @@ protected func Construction()
|
|||
|
||||
protected func Initialize()
|
||||
{
|
||||
var wdt = BoundBy(GetObjWidth(), 8, 120);
|
||||
var wdt = GetObjWidth();
|
||||
if (parent)
|
||||
wdt = BoundBy(parent->GetObjWidth(), 8, 120);
|
||||
SetWidth(wdt);
|
||||
{
|
||||
wdt = parent->~GetBasementWidth();
|
||||
if (wdt == nil)
|
||||
wdt = parent->GetObjWidth();
|
||||
}
|
||||
SetWidth(BoundBy(wdt, 8, 120));
|
||||
// Move objects out of the basement.
|
||||
MoveOutOfSolidMask();
|
||||
MoveOutOfSolidMask();
|
||||
return _inherited(...);
|
||||
}
|
||||
|
||||
|
@ -54,10 +58,13 @@ public func CombineWith(object stick_to)
|
|||
return;
|
||||
}
|
||||
|
||||
public func SetParent(object to_parent)
|
||||
public func SetParent(object to_parent)
|
||||
{
|
||||
parent = to_parent;
|
||||
SetWidth(BoundBy(parent->GetObjWidth(), 8, 120));
|
||||
var wdt = parent->~GetBasementWidth();
|
||||
if (wdt == nil)
|
||||
wdt = parent->GetObjWidth();
|
||||
SetWidth(BoundBy(wdt, 8, 120));
|
||||
// Notify the parent.
|
||||
parent->~SetBasement(this);
|
||||
return;
|
||||
|
@ -71,9 +78,42 @@ public func IsBelowSurfaceConstruction() { return true; }
|
|||
// Sticking to other structures, at the bottom of that structure.
|
||||
public func ConstructionCombineWith() { return "IsStructureWithoutBasement"; }
|
||||
public func ConstructionCombineDirection() { return CONSTRUCTION_STICK_Bottom; }
|
||||
public func ConstructionCombineOffset(object other)
|
||||
{
|
||||
// Some structures like the elevator require the basement to have an offset.
|
||||
return other->~GetBasementOffset();
|
||||
}
|
||||
|
||||
public func NoConstructionFlip() { return true; }
|
||||
|
||||
public func AlternativeConstructionPreview(object previewer, int direction, object combine_with)
|
||||
{
|
||||
var wdt = GetSiteWidth(direction, combine_with);
|
||||
previewer->SetObjDrawTransform(1000 * wdt / 40, 0, 0, 0, 1000, 0, previewer.GFX_StructureOverlay);
|
||||
return;
|
||||
}
|
||||
|
||||
public func GetSiteWidth(int direction, object combine_with)
|
||||
{
|
||||
var wdt = GetDefWidth();
|
||||
if (combine_with)
|
||||
{
|
||||
wdt = combine_with->~GetBasementWidth();
|
||||
if (wdt == nil)
|
||||
wdt = combine_with->GetObjWidth();
|
||||
}
|
||||
return BoundBy(wdt, 8, 120);
|
||||
}
|
||||
|
||||
public func SetConstructionSiteOverlay(object site, int direction, object combine_with)
|
||||
{
|
||||
var wdt = GetSiteWidth(direction, combine_with);
|
||||
site->SetGraphics(nil, Basement, 1, GFXOV_MODE_Base);
|
||||
site->SetClrModulation(RGBa(255, 255, 255, 128), 1);
|
||||
site->SetObjDrawTransform(1000 * wdt / 40, 0, 0, 0, 1000, -4000, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't stick to itself, so it should not be a structure.
|
||||
public func IsStructure() { return false; }
|
||||
|
||||
|
|
|
@ -214,6 +214,16 @@ private func UpdateTurnSpeed()
|
|||
|
||||
/* Construction preview */
|
||||
|
||||
// Definition call by the construction previewer
|
||||
public func ConstructionPreview(object previewer, int overlay, int dir)
|
||||
{
|
||||
if (GetType(this) != C4V_Def) return;
|
||||
|
||||
previewer->SetGraphics(nil, Elevator_Case_Front, overlay, GFXOV_MODE_Base);
|
||||
previewer->SetObjDrawTransform(1000, 0, -19000 * (dir*2-1), 0, 1000, 17000, overlay);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Sticking to other elevators
|
||||
public func ConstructionCombineWith() { return "IsElevator"; }
|
||||
public func ConstructionCombineDirection() { return CONSTRUCTION_STICK_Left | CONSTRUCTION_STICK_Right; }
|
||||
|
@ -241,6 +251,11 @@ public func CombineWith(object other)
|
|||
partner = other;
|
||||
}
|
||||
|
||||
// Special requirements for the basement of the elevator.
|
||||
public func GetBasementWidth() { return 36; }
|
||||
public func GetBasementOffset() { return [11 * (2 * GetDir() - 1), 0]; }
|
||||
|
||||
|
||||
/* Combination */
|
||||
|
||||
// Called by a new elevator next to this one
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include Library_Structure
|
||||
#include Library_Flag
|
||||
#include Library_Base // Needed for DoBuy...
|
||||
#include Library_PowerDisplay
|
||||
|
||||
local ActMap = {
|
||||
Fly = {
|
||||
|
|
|
@ -16,7 +16,6 @@ ColorByOwner=1
|
|||
Components=Metal=6;Wood=4;
|
||||
Rotate=1
|
||||
Entrance=-12,-12,24,24
|
||||
Exclusive=1
|
||||
RotatedEntrance=1
|
||||
VehicleControl=1
|
||||
NoStabilize=1
|
|
@ -249,7 +249,8 @@ protected func DoFire(object iammo, object clonk, int angle)
|
|||
iammo->SetR(r / angPrec);
|
||||
iammo->SetRDir(-4 + Random(9));
|
||||
iammo->LaunchProjectile(r, 17, Fire_Velocity, 0,0, angPrec);
|
||||
iammo->SetController(clonk->GetController());
|
||||
if (clonk)
|
||||
iammo->SetController(clonk->GetController());
|
||||
iammo->~Fuse();
|
||||
|
||||
//Particles
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
[DefCore]
|
||||
id=DialogueBoomshire
|
||||
Version=7,0
|
||||
Category=C4D_StaticBack
|
||||
Picture=0,0,64,64
|
||||
Width=1
|
||||
Height=1
|
|
@ -19,12 +19,9 @@ private func Initialize()
|
|||
|
||||
var concierge = CreateObjectAbove(Clonk, 70, 1030, NO_OWNER);
|
||||
concierge->SetDir(DIR_Left);
|
||||
concierge->SetSkin(2);
|
||||
concierge->SetMeshMaterial("clonkMime");
|
||||
concierge->SetColor(0xffffff);
|
||||
concierge->SetAlternativeSkin("Mime");
|
||||
concierge->SetObjectLayer(concierge);
|
||||
concierge->SetName("$NameConcierge$");
|
||||
concierge->SetPortrait({ Source = DialogueBoomshire });
|
||||
concierge->SetDialogue("Concierge");
|
||||
concierge->Sound("Circus", false, nil, nil, +1, 100);
|
||||
Dialogue->FindByTarget(concierge)->AddAttention();
|
||||
|
|
|
@ -23,43 +23,36 @@ func SetPaintCol(int idx)
|
|||
}
|
||||
|
||||
// Impact sound
|
||||
func Hit()
|
||||
public func Hit()
|
||||
{
|
||||
Sound("Hits::GeneralHit?");
|
||||
}
|
||||
|
||||
// Item activation
|
||||
func ControlUseStart(object clonk, int x, int y)
|
||||
public func ControlUseStart(object clonk, int x, int y)
|
||||
{
|
||||
if (Distance(0,0,x,y) > max_dist) return true;
|
||||
|
||||
x += GetX(); y += GetY();
|
||||
last_x = x; last_y = y;
|
||||
last_ldx=last_ldy=0;
|
||||
var r = Random(90), wdt = 2;
|
||||
var ldx = Sin(r, wdt), ldy = Cos(r, wdt);
|
||||
DrawMaterialQuad(paint_col, x-ldx,y-ldy, x-ldy,y+ldx, x+ldx,y+ldy, x+ldy,y-ldx, DMQ_Bridge);
|
||||
SetAction("Spraying");
|
||||
return true;
|
||||
return ControlUseHolding(clonk, x, y);
|
||||
}
|
||||
|
||||
func HoldingEnabled() { return true; }
|
||||
public func HoldingEnabled() { return true; }
|
||||
|
||||
func ControlUseHolding(object clonk, int new_x, int new_y)
|
||||
{
|
||||
new_x += GetX(); new_y += GetY();
|
||||
if (new_x==last_x && new_y == last_y) return true;
|
||||
|
||||
if (Distance(GetX(),GetY(),new_x,new_y) > max_dist)
|
||||
public func ControlUseHolding(object clonk, int new_x, int new_y)
|
||||
{
|
||||
// Out of reach? Stop spraying.
|
||||
if (Distance(0,0,new_x,new_y) > max_dist)
|
||||
{
|
||||
last_x = new_x;
|
||||
last_y = new_y;
|
||||
SetAction("Idle");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GetAction() != "Spraying") SetAction("Spraying");
|
||||
// Work in global coordinates
|
||||
new_x += GetX(); new_y += GetY();
|
||||
|
||||
// (re-)start spraying
|
||||
if (GetAction() != "Spraying") StartSpraying(clonk, new_x, new_y);
|
||||
|
||||
// Spray paint if position moved
|
||||
if (new_x==last_x && new_y == last_y) return true;
|
||||
var wdt = 2;
|
||||
var dx=new_x-last_x, dy=new_y-last_y;
|
||||
var d = Distance(dx,dy);
|
||||
|
@ -83,6 +76,19 @@ public func ControlUseCancel(object clonk, int x, int y)
|
|||
return true;
|
||||
}
|
||||
|
||||
private func StartSpraying(object clonk, int x, int y)
|
||||
{
|
||||
// Go into spray mode and place an initial blob
|
||||
last_x = x; last_y = y;
|
||||
last_ldx=last_ldy=0;
|
||||
var r = Random(90), wdt = 2;
|
||||
var ldx = Sin(r, wdt), ldy = Cos(r, wdt);
|
||||
DrawMaterialQuad(paint_col, x-ldx,y-ldy, x-ldy,y+ldx, x+ldx,y+ldy, x+ldy,y-ldx, DMQ_Bridge);
|
||||
SetAction("Spraying");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
local ActMap = {
|
||||
Spraying = {
|
||||
Prototype = Action,
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
Override screenshot functionality
|
||||
--*/
|
||||
|
||||
global func PlayerControl(int plr, int ctrl)
|
||||
global func PlayerControl(int plr, int ctrl, ...)
|
||||
{
|
||||
if (ctrl == CON_TryScreenshot)
|
||||
{
|
||||
CustomMessage(Format("$MsgCheater$", GetTaggedPlayerName(plr)));
|
||||
Sound("Error", true);
|
||||
Sound("UI::Error", true);
|
||||
//var crew = GetCursor(plr); - used for cheating
|
||||
//if (crew) crew->Punch(crew, 50);
|
||||
return true;
|
||||
|
|
|
@ -82,6 +82,7 @@ nicStage - Environemnt/Lightning/Thunder3 (https://www.freesound.org/peop
|
|||
jrosin - Environemnt/Lightning/Thunder4 (https://www.freesound.org/people/jrosin/sounds/329978/ adapted by Maikel)
|
||||
shaka9 - Environemnt/Lightning/Thunder5 (https://www.freesound.org/people/shaka9/sounds/160514/ adapted by Maikel)
|
||||
Harbour11 - UI::Error, UI::Trumpet (both adapted by Sven2; used sound from http://freesound.org/people/Harbour11/sounds/194624/)
|
||||
CosmicEmbers - Objects::LineSnap (cropped/pitch adjusted by Sven2; original from http://freesound.org/people/CosmicEmbers/sounds/161650/)
|
||||
|
||||
The following sounds use two sources:
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// Makes sure the guide message is hidden when starting a dialogue and shown again when closing.
|
||||
|
||||
#appendto Dialogue
|
||||
|
||||
public func Interact(object clonk)
|
||||
{
|
||||
if (!dlg_interact || !dlg_name)
|
||||
return inherited(clonk, ...);
|
||||
var guide = FindObject(Find_ID(TutorialGuide), Find_Owner(clonk->GetOwner()));
|
||||
if (!guide)
|
||||
return inherited(clonk, ...);
|
||||
if (dlg_status == DLG_Status_Stop)
|
||||
{
|
||||
if (this.guide_was_shown)
|
||||
{
|
||||
this.guide_was_shown = false;
|
||||
guide->ShowGuide();
|
||||
}
|
||||
}
|
||||
else if (dlg_status != DLG_Status_Remove && dlg_status != DLG_Status_Wait)
|
||||
{
|
||||
if (!guide->IsHidden())
|
||||
{
|
||||
this.guide_was_shown = true;
|
||||
guide->HideGuide();
|
||||
}
|
||||
}
|
||||
return inherited(clonk, ...);
|
||||
}
|
|
@ -62,6 +62,7 @@ private func InitVillageEntrance()
|
|||
var site = CreateObjectAbove(ConstructionSite, 264, 386);
|
||||
site.MeshTransformation = Trans_Mul(Trans_Rotate(RandomX(-30, 30), 0, 1, 0), Trans_Rotate(RandomX(-10, 10), 1, 0, 0));
|
||||
site->Set(Sawmill);
|
||||
site->MakeUncancellable();
|
||||
site->CreateContents(Wood, 1);
|
||||
site->CreateContents(Rock, 1);
|
||||
|
||||
|
@ -202,7 +203,7 @@ private func InitAI()
|
|||
barrel->SetFilled("Water", 300);
|
||||
npc_fireman->SetObjectLayer(npc_fireman);
|
||||
npc_fireman->SetDir(DIR_Left);
|
||||
npc_fireman->SetDialogue("Fireman", true);
|
||||
npc_fireman->SetDialogue("Fireman", false);
|
||||
npc_fireman->SetAlternativeSkin("MaleDarkHair");
|
||||
|
||||
// A builder which tells you where to place the flagpole.
|
||||
|
@ -211,7 +212,7 @@ private func InitAI()
|
|||
npc_builder->CreateContents(Hammer);
|
||||
npc_builder->SetObjectLayer(npc_builder);
|
||||
npc_builder->SetDir(DIR_Left);
|
||||
npc_builder->SetDialogue("Builder", true);
|
||||
npc_builder->SetDialogue("Builder", false);
|
||||
npc_builder->SetAlternativeSkin("Carpenter");
|
||||
|
||||
// A farmer near the grain field.
|
||||
|
@ -413,7 +414,9 @@ global func FxTutorialSawmillFinishedTimer(object target, proplist effect)
|
|||
// Notify lumberjack the sawmill is done.
|
||||
var dialogue_lumberjack = Dialogue->FindByName("Lumberjack");
|
||||
if (dialogue_lumberjack)
|
||||
dialogue_lumberjack->SetDialogueProgress(5, nil, true);
|
||||
dialogue_lumberjack->SetDialogueProgress(5, nil, false);
|
||||
Dialogue->FindByName("Fireman")->AddAttention();
|
||||
Dialogue->FindByName("Builder")->AddAttention();
|
||||
return FX_Execute_Kill;
|
||||
}
|
||||
return FX_OK;
|
||||
|
@ -456,6 +459,10 @@ global func FxTutorialPlacedFlagpoleTimer(object target, proplist effect)
|
|||
guide->ShowGuideMessage();
|
||||
var new_effect = AddEffect("TutorialTalkedToLumberjack2", nil, 100, 5);
|
||||
new_effect.plr = effect.plr;
|
||||
// Notify lumberjack that player talked to other npc's.
|
||||
var dialogue_lumberjack = Dialogue->FindByName("Lumberjack");
|
||||
if (dialogue_lumberjack)
|
||||
dialogue_lumberjack->SetDialogueProgress(6, nil, true);
|
||||
return FX_Execute_Kill;
|
||||
}
|
||||
return FX_OK;
|
||||
|
|
|
@ -35,27 +35,35 @@ public func Dlg_Lumberjack_4(object clonk)
|
|||
|
||||
public func Dlg_Lumberjack_5(object clonk)
|
||||
{
|
||||
MessageBox("$DlgLumberjackWellDone$", clonk, dlg_target);
|
||||
MessageBox("$DlgLumberjackTalkToOthers$", clonk, dlg_target);
|
||||
StopDialogue();
|
||||
SetDialogueProgress(5);
|
||||
return true;
|
||||
}
|
||||
|
||||
public func Dlg_Lumberjack_6(object clonk)
|
||||
{
|
||||
MessageBox("$DlgLumberjackFavor$", clonk, clonk);
|
||||
MessageBox("$DlgLumberjackWellDone$", clonk, dlg_target);
|
||||
return true;
|
||||
}
|
||||
|
||||
public func Dlg_Lumberjack_7(object clonk)
|
||||
{
|
||||
MessageBox("$DlgLumberjackMines$", clonk, dlg_target);
|
||||
MessageBox("$DlgLumberjackFavor$", clonk, clonk);
|
||||
return true;
|
||||
}
|
||||
|
||||
public func Dlg_Lumberjack_8(object clonk)
|
||||
{
|
||||
MessageBox("$DlgLumberjackMines$", clonk, dlg_target);
|
||||
return true;
|
||||
}
|
||||
|
||||
public func Dlg_Lumberjack_9(object clonk)
|
||||
{
|
||||
MessageBox("$DlgLumberjackLook$", clonk, clonk);
|
||||
StopDialogue();
|
||||
SetDialogueProgress(5);
|
||||
SetDialogueProgress(6);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ DlgLumberjackHello=Hallo, ich bin %s, die Holzfällerin des Dorfes.
|
|||
DlgLumberjackReply=Ich heiße %s. Du schaust traurig aus.
|
||||
DlgLumberjackSawmill=Ja, das stimmt. Mein Sägewerk wurde zerstört und ich finde keine Steine, um es wieder aufzubauen. Kannst du mir helfen?
|
||||
DlgLumberjackRock=Ja, ich werde dir Steine finden.
|
||||
DlgLumberjackTalkToOthers=Danke, vielleicht kannst du jetzt einem der anderen Dorfbewohner helfen.
|
||||
DlgLumberjackWellDone=Danke vielmals, dass du das Sägewerk aufgebaut hast. Kann ich irgendwas für dich tun?
|
||||
DlgLumberjackFavor=Tatsächlich kannst du das, ja. Ich brauche Holz, du hast nicht zufällig eine Axt?
|
||||
DlgLumberjackMines=Nein, leider nicht. Ich habe meine Axt in der Mine fallen gelassen, als ich mich während des Angriffes versteckt habe.
|
||||
|
|
|
@ -3,6 +3,7 @@ DlgLumberjackHello=Hello I am %s, the lumberjack of this small village.
|
|||
DlgLumberjackReply=My name is %s, you seem sad.
|
||||
DlgLumberjackSawmill=Yes, indeed. My sawmill got destroyed and I can't find any rock to rebuild it. Can you help me?
|
||||
DlgLumberjackRock=Yes, I'll find you some rock.
|
||||
DlgLumberjackTalkToOthers=Thank you, maybe you can help one of the other villagers now.
|
||||
DlgLumberjackWellDone=Thanks a lot, for constructing the sawmill. Can I do anything for you?
|
||||
DlgLumberjackFavor=Actually you can, I need wood, do you happen to have an axe?
|
||||
DlgLumberjackMines=No, I don't, but I have dropped my axe in the mines when I was hiding there during the attack.
|
||||
|
|
|
@ -1 +1 @@
|
|||
Sky.jpg adapted from http://commons.wikimedia.org/wiki/File:Berge_mountains.JPG (Steinsplitter CC BY-SA 3.0)
|
||||
Sky.jpg adapted from http://commons.wikimedia.org/wiki/File:Berge_mountains.JPG (Steinsplitter CC BY 3.0)
|
|
@ -1,5 +1,5 @@
|
|||
Clonkomotive
|
||||
|
||||
A once flourishing train route through Clonkomotive Canyon has been disrupted by heavy rockfall. The rockfall destroyed the necessary bridges to connect the cliffs in between the canyons, thereby disconnecting two villages on the route. You are left with the locomotive in one of the villages and now you need to rebuild the route to the other village. Luckily Nature has settled and the rockfall has become less severe.
|
||||
Einst florierte die Eisenbahnstrecke durch den Clonkomotive Canyon, doch hat ein schwerer Steinschlag die Strecke zerstört. Die Brücken über die Schluchten wurden sämtlich vernichtet und die beiden Dörfer an den Enden des Canyons sind nun ohne Verbindung. Du findest dich in einem der Dörfer wieder und stehst vor der Aufgabe, die Strecke wieder herzurichten. Glücklicherweise hat sich der Steinschlag etwas beruhigt und ein Aufbau der Strecke ist überhaupt machbar.
|
||||
|
||||
Goal: Transport the locomotive to the village on the far right.
|
||||
Ziel: Bringe die Lokomotive zum Dorf auf der rechten Seite.
|
|
@ -1,2 +1,2 @@
|
|||
Name=HeavyCrumb
|
||||
Description=Hurts Clonks and buildings!
|
||||
Name=Felsbrocken
|
||||
Description=Verletzt Clonks und beschädigt Gebäude.
|
|
@ -1,2 +1,2 @@
|
|||
Name=HeavyCrumb
|
||||
Description=Hurts Clonks and buildings!
|
||||
Name=Boulder
|
||||
Description=Hurts Clonks and damages buildings.
|
|
@ -1,4 +1,4 @@
|
|||
# Intro sequence messages
|
||||
MsgDriveTrain=We only have to drive this train to the village on the other side of these canyons.
|
||||
MsgOutOfFuel=Are we out of fuel again?!
|
||||
MsgBridgesGone=Yes, and it seems all the bridges over the canyons have been destroyed as well.
|
||||
MsgDriveTrain=Dieser Zug muss zum Dorf auf der anderen Seite des Canyons.
|
||||
MsgOutOfFuel=Ist der Treibstoff etwa wieder alle?
|
||||
MsgBridgesGone=Ja, aber die Brücken über die Schluchten sind sowieso zerstört worden.
|
|
@ -1113,7 +1113,8 @@ C4Object* C4Game::CreateObjectConstruction(C4PropList * PropList,
|
|||
return pObj;
|
||||
}
|
||||
|
||||
C4Object* C4Game::OverlapObject(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, int32_t Plane)
|
||||
// Finds an object (OCF_Exclusive) that blocks a potential construction site in the given rectangle
|
||||
C4Object* C4Game::FindConstuctionSiteBlock(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt)
|
||||
{
|
||||
C4Rect rect1,rect2;
|
||||
rect1.x=tx; rect1.y=ty; rect1.Wdt=wdt; rect1.Hgt=hgt;
|
||||
|
@ -1121,7 +1122,7 @@ C4Object* C4Game::OverlapObject(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt
|
|||
for (C4ObjectList *pObjs = Area.FirstObjectShapes(&pSector); pSector; pObjs = Area.NextObjectShapes(pObjs, &pSector))
|
||||
for (C4Object *cObj : *pObjs)
|
||||
if (cObj->Status && !cObj->Contained)
|
||||
if (cObj->GetPlane() == Plane)
|
||||
if (cObj->OCF & OCF_Exclusive)
|
||||
{
|
||||
rect2=cObj->Shape; rect2.x+=cObj->GetX(); rect2.y+=cObj->GetY();
|
||||
if (rect1.Overlap(rect2)) return cObj;
|
||||
|
|
|
@ -191,7 +191,7 @@ public:
|
|||
int32_t con=1, bool terrain=false);
|
||||
C4Object *CreateInfoObject(C4ObjectInfo *cinf, int32_t owner,
|
||||
int32_t tx=50, int32_t ty=50);
|
||||
C4Object *OverlapObject(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, int32_t Plane);
|
||||
C4Object *FindConstuctionSiteBlock(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt);
|
||||
C4Object *FindObject(C4Def * pDef,
|
||||
int32_t iX=0, int32_t iY=0, int32_t iWdt=0, int32_t iHgt=0,
|
||||
DWORD ocf=OCF_All,
|
||||
|
|
|
@ -219,10 +219,7 @@ static C4ValueArray *FnFindConstructionSite(C4PropList * _this, C4PropList * Pro
|
|||
if (ConstructionCheck(PropList,v1,v2))
|
||||
return NULL;
|
||||
// Search for real
|
||||
bool result = !!FindConSiteSpot(v1, v2,
|
||||
pDef->Shape.Wdt,pDef->Shape.Hgt,
|
||||
pDef->GetPlane(),
|
||||
20);
|
||||
bool result = !!FindConSiteSpot(v1, v2, pDef->Shape.Wdt,pDef->Shape.Hgt, 20);
|
||||
if(!result) return 0;
|
||||
C4ValueArray *pArray = new C4ValueArray(2);
|
||||
pArray->SetItem(0, C4VInt(v1));
|
||||
|
|
|
@ -368,10 +368,8 @@ void CPNGFile::WaitForSaves()
|
|||
first = false;
|
||||
#ifdef HAVE_WINTHREAD
|
||||
Sleep(100);
|
||||
#elif defined (__APPLE__)
|
||||
#else
|
||||
sched_yield();
|
||||
#elif defined(HAVE_PTHREAD)
|
||||
pthread_yield();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2709,8 +2709,7 @@ bool FindLevelGround(int32_t &rx, int32_t &ry, int32_t width, int32_t hrange)
|
|||
|
||||
// Starting from rx/ry, searches for a width of solid level ground with
|
||||
// structure clearance (category). Returns bottom center of surface found.
|
||||
bool FindConSiteSpot(int32_t &rx, int32_t &ry, int32_t wdt, int32_t hgt,
|
||||
int32_t Plane, int32_t hrange)
|
||||
bool FindConSiteSpot(int32_t &rx, int32_t &ry, int32_t wdt, int32_t hgt, int32_t hrange)
|
||||
{
|
||||
bool fFound=false;
|
||||
|
||||
|
@ -2762,10 +2761,10 @@ bool FindConSiteSpot(int32_t &rx, int32_t &ry, int32_t wdt, int32_t hgt,
|
|||
|
||||
// Check runs & object overlap
|
||||
if (rl1>=wdt) if (cx1>0)
|
||||
if (!Game.OverlapObject(cx1,cy1-hgt-10,wdt,hgt+40,Plane))
|
||||
if (!Game.FindConstuctionSiteBlock(cx1,cy1-hgt-10,wdt,hgt+40))
|
||||
{ rx=cx1+wdt/2; ry=cy1; fFound=true; break; }
|
||||
if (rl2>=wdt) if (cx2<GBackWdt)
|
||||
if (!Game.OverlapObject(cx2-wdt,cy2-hgt-10,wdt,hgt+40,Plane))
|
||||
if (!Game.FindConstuctionSiteBlock(cx2-wdt,cy2-hgt-10,wdt,hgt+40))
|
||||
{ rx=cx2-wdt/2; ry=cy2; fFound=true; break; }
|
||||
}
|
||||
|
||||
|
@ -2992,7 +2991,7 @@ bool ConstructionCheck(C4PropList * PropList, int32_t iX, int32_t iY, C4Object *
|
|||
}
|
||||
// Check other structures
|
||||
C4Object *other;
|
||||
if ((other=Game.OverlapObject(rtx,rty,wdt,hgt,ndef->GetPlane())))
|
||||
if ((other=Game.FindConstuctionSiteBlock(rtx,rty,wdt,hgt)))
|
||||
{
|
||||
if (pByObj) GameMsgObjectError(FormatString(LoadResStr("IDS_OBJ_NOOTHER"),other->GetName ()).getData(),pByObj);
|
||||
return false;
|
||||
|
|
|
@ -352,7 +352,7 @@ bool FindLiquid(int32_t &rx, int32_t &ry, int32_t width, int32_t height);
|
|||
bool FindTunnel(int32_t &rx, int32_t &ry, int32_t width, int32_t height);
|
||||
bool FindSurfaceLiquid(int32_t &rx, int32_t &ry, int32_t width, int32_t height);
|
||||
bool FindLevelGround(int32_t &rx, int32_t &ry, int32_t width, int32_t hrange);
|
||||
bool FindConSiteSpot(int32_t &rx, int32_t &ry, int32_t wdt, int32_t hgt, int32_t Plane, int32_t hrange=-1);
|
||||
bool FindConSiteSpot(int32_t &rx, int32_t &ry, int32_t wdt, int32_t hgt, int32_t hrange=-1);
|
||||
bool FindThrowingPosition(int32_t iTx, int32_t iTy, C4Real fXDir, C4Real fYDir, int32_t iHeight, int32_t &rX, int32_t &rY);
|
||||
bool PathFree(int32_t x1, int32_t y1, int32_t x2, int32_t y2);
|
||||
bool PathFree(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t *ix, int32_t *iy);
|
||||
|
|
|
@ -91,22 +91,22 @@ bool C4FoWRegion::BindFramebuf()
|
|||
if (y < pSurface->Hgt / 2 && x < pSurface->Wdt)
|
||||
{
|
||||
// Normals and intensity
|
||||
pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y, pSurface->GetPixDw(x, pSurface->Hgt/2 - y, false));
|
||||
pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y, pBackSurface->GetPixDw(x, pBackSurface->Hgt/2 - y, false));
|
||||
pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y - 1, pSurface->GetPixDw(x, pSurface->Hgt/2 - y - 1, false));
|
||||
pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y - 1, pBackSurface->GetPixDw(x, pBackSurface->Hgt/2 - y - 1, false));
|
||||
|
||||
// Color
|
||||
pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y + iHgt / 2, pSurface->GetPixDw(x, pSurface->Hgt/2 - y + pSurface->Hgt / 2, false));
|
||||
pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y + iHgt / 2, pBackSurface->GetPixDw(x, pBackSurface->Hgt/2 - y + pBackSurface->Hgt / 2, false));
|
||||
pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y + iHgt / 2 - 1, pSurface->GetPixDw(x, pSurface->Hgt/2 - y + pSurface->Hgt / 2 - 1, false));
|
||||
pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y + iHgt / 2 - 1, pBackSurface->GetPixDw(x, pBackSurface->Hgt/2 - y + pBackSurface->Hgt / 2 - 1, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normals and intensity
|
||||
pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y, 0x000000ff);
|
||||
pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y, 0x000000ff);
|
||||
pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y - 1, 0x000000ff);
|
||||
pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y - 1, 0x000000ff);
|
||||
|
||||
// Color
|
||||
pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y + iHgt / 2, 0x000000ff);
|
||||
pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y + iHgt / 2, 0x000000ff);
|
||||
pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y + iHgt / 2 - 1, 0x000000ff);
|
||||
pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y + iHgt / 2 - 1, 0x000000ff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -880,6 +880,7 @@ void StdMeshInstance::AnimationNode::CompileFunc(StdCompiler* pComp, const StdMe
|
|||
const StdMeshBone* bone = Mesh->GetSkeleton().GetBoneByName(bone_name);
|
||||
if(!bone) pComp->excCorrupt("No such bone: \"%s\"", bone_name.getData());
|
||||
Custom.BoneIndex = bone->Index;
|
||||
Custom.Transformation = new StdMeshTransformation;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1222,8 +1222,14 @@ void C4Object::DoDamage(int32_t iChange, int32_t iCausedBy, int32_t iCause)
|
|||
|
||||
void C4Object::DoEnergy(int32_t iChange, bool fExact, int32_t iCause, int32_t iCausedByPlr)
|
||||
{
|
||||
// iChange 100% = Physical 100000
|
||||
if (!fExact) iChange=iChange*C4MaxPhysical/100;
|
||||
if (!fExact)
|
||||
{
|
||||
// Clamp range of change to prevent integer overflow errors
|
||||
// Do not clamp directly to (0...MaxEnergy)-current_energy, because
|
||||
// the change value calculated here may be reduced by effect callbacks
|
||||
int32_t scale = C4MaxPhysical / 100; // iChange 100% = Physical 100000
|
||||
iChange = Clamp<int32_t>(iChange, std::numeric_limits<int32_t>::min()/scale, std::numeric_limits<int32_t>::max()/scale)*scale;
|
||||
}
|
||||
// Was zero?
|
||||
bool fWasZero=(Energy==0);
|
||||
// Mark last damage causing player to trace kills
|
||||
|
|
|
@ -517,7 +517,7 @@ void C4Player::PlaceReadyBase(int32_t &tx, int32_t &ty, C4Object **pFirstBase)
|
|||
{
|
||||
ctx=tx; cty=ty;
|
||||
if (Game.C4S.PlrStart[PlrStartIndex].EnforcePosition
|
||||
|| FindConSiteSpot(ctx,cty,def->Shape.Wdt,def->Shape.Hgt,def->GetPlane(),20))
|
||||
|| FindConSiteSpot(ctx,cty,def->Shape.Wdt,def->Shape.Hgt,20))
|
||||
if ((cbase=Game.CreateObjectConstruction(C4Id2Def(cid),NULL,Number,ctx,cty,FullCon,true)))
|
||||
{
|
||||
// FirstBase
|
||||
|
@ -644,7 +644,7 @@ bool C4Player::ScenarioInit()
|
|||
// Use nearest above-ground...
|
||||
FindSolidGround(ptx,pty,30);
|
||||
// Might have hit a small lake, or similar: Seach a real site spot from here
|
||||
FindConSiteSpot(ptx, pty, 30,50,C4Plane_Structure, 400);
|
||||
FindConSiteSpot(ptx, pty, 30, 50, 400);
|
||||
}
|
||||
|
||||
// Place Readies
|
||||
|
|