Merge branch github/master into master

This commit is contained in:
Kp 2016-11-13 19:56:52 +00:00
commit 117d2f73e0
23 changed files with 432 additions and 353 deletions

View file

@ -917,7 +917,7 @@ int main(int argc,char**argv){(void)argc;(void)argv;
Result('%s: building with %s' % (self.msgprefix, s))
def _result_check_user_setting(self,context,condition,CPPDEFINES,label,int=int,str=str):
if isinstance(CPPDEFINES, str):
context.sconf.Define(CPPDEFINES, int(condition))
self._define_macro(context, CPPDEFINES, int(condition))
elif condition:
self.successful_flags['CPPDEFINES'].extend(CPPDEFINES)
context.Result('%s: checking whether to enable %s...%s' % (self.msgprefix, label, 'yes' if condition else 'no'))
@ -2064,8 +2064,12 @@ where the cast is useless.
def check_getaddrinfo_present(self,context,_successflags={'CPPDEFINES' : ['DXX_HAVE_GETADDRINFO']}):
self.Compile(context, text='''
#ifdef WIN32
#define DXX_WIN32_MINIMUM_WIN32_WINNT 0x0600
#if defined(_WIN32_WINNT) && (_WIN32_WINNT < DXX_WIN32_MINIMUM_WIN32_WINNT)
#undef _WIN32_WINNT
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#define _WIN32_WINNT DXX_WIN32_MINIMUM_WIN32_WINNT
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
@ -2076,8 +2080,15 @@ where the cast is useless.
#endif
''', main='''
addrinfo *res = nullptr;
const addrinfo *hints = nullptr;
int i = getaddrinfo("", "", hints, &res);
addrinfo hints{};
#ifdef AI_NUMERICSERV
/* Test that it is defined to a term that can be used with bit-or */
hints.ai_flags |= AI_NUMERICSERV;
#endif
#if DXX_USE_IPv6
hints.ai_flags |= AI_V4MAPPED | AI_ALL;
#endif
int i = getaddrinfo("", "", &hints, &res);
(void)i;
freeaddrinfo(res);
return 0;
@ -3650,8 +3661,8 @@ class DXXArchive(DXXCommon):
class DXXProgram(DXXCommon):
# version number
VERSION_MAJOR = 0
VERSION_MINOR = 58
VERSION_MICRO = 1
VERSION_MINOR = 59
VERSION_MICRO = 100
static_archive_construction = {}
def _apply_target_name(self,name):
return os.path.join(os.path.dirname(name), '.%s.%s' % (self.target, os.path.splitext(os.path.basename(name))[0]))

View file

@ -161,24 +161,24 @@ window_event_result event_process(void)
return highest_result;
event.type = EVENT_WINDOW_DRAW; // then draw all visible windows
wind = window_get_first();
while (wind != NULL)
for (wind = window_get_first(); wind != nullptr;)
{
window *prev = window_get_prev(*wind);
if (window_is_visible(wind))
{
auto prev = window_get_prev(*wind);
auto result = window_send_event(*wind, event);
highest_result = std::max(result, highest_result);
if (result == window_event_result::deleted)
{
if (!prev) // well there isn't a previous window ...
break; // ... just bail out - we've done everything for this frame we can.
wind = window_get_next(*prev); // the current window seemed to be closed. so take the next one from the previous which should be able to point to the one after the current closed
if (!prev)
{
wind = window_get_first();
continue;
}
wind = prev; // take the previous window and get the next one from that (if prev isn't nullptr)
}
else
wind = window_get_next(*wind);
highest_result = std::max(result, highest_result);
}
wind = window_get_next(*wind);
}
gr_flip();

View file

@ -52,15 +52,15 @@ static inline void con_puts_literal(int level, const char (&str)[len])
}
#define con_puts(A1,S,...) (con_puts(A1,S, _dxx_call_puts_parameter2(1, ## __VA_ARGS__, strlen(S))))
void con_printf(int level, const char *fmt, ...) __attribute_format_printf(2, 3);
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
#define _dxx_con_printf_check_trailing_newline(F) \
(sizeof((F)) > 1 && (F)[sizeof((F)) - 2] == '\n' && \
#ifdef DXX_CONSTANT_TRUE
#define DXX_CON_PRINTF_CHECK_TRAILING_NEWLINE(F) \
(DXX_CONSTANT_TRUE(sizeof((F)) > 1 && (F)[sizeof((F)) - 2] == '\n') && \
(DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_trailing_newline, "trailing literal newline on con_printf"), 0)),
#else
#define _dxx_con_printf_check_trailing_newline(C)
#define DXX_CON_PRINTF_CHECK_TRAILING_NEWLINE(C)
#endif
#define con_printf(A1,F,...) \
_dxx_con_printf_check_trailing_newline(F) \
DXX_CON_PRINTF_CHECK_TRAILING_NEWLINE(F) \
dxx_call_printf_checked(con_printf,con_puts_literal,(A1),(F),##__VA_ARGS__)
void con_showup(void);

View file

@ -14,10 +14,10 @@
#define DXX_CALL_PRINTF_DELETE_COMMA2_(A,...) __VA_ARGS__
#define DXX_CALL_PRINTF_DELETE_COMMA_(A,...) DXX_CALL_PRINTF_DELETE_COMMA2_( A , ## __VA_ARGS__ )
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
#ifdef DXX_CONSTANT_TRUE
#define DXX_PRINTF_CHECK_HAS_NONTRIVIAL_FORMAT_STRING_(V,P,FMT) \
((void)((dxx_builtin_constant_p((FMT)) && (FMT)[0] == '%' && (FMT)[1] == 's' && (FMT)[2] == 0) && \
(DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_trivial_string_specifier_argument_##V, "bare %s argument to " #V "; use " #P " directly"), 0)))
static_cast<void>(DXX_CONSTANT_TRUE((FMT) && (FMT)[0] == '%' && (FMT)[1] == 's' && (FMT)[2] == 0) && \
(DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_trivial_string_specifier_argument_##V, "bare %s argument to " #V "; use " #P " directly"), 0))
#else
#define DXX_PRINTF_CHECK_HAS_NONTRIVIAL_FORMAT_STRING_(V,P,FMT) \
((void)(FMT))

View file

@ -155,7 +155,7 @@ namespace partial_range_detail
template <typename I, std::size_t required_buffer_size>
static inline void check_range_bounds(const char *file, unsigned line, const char *estr, const void *t, const std::size_t o, const std::size_t l, const std::size_t d)
{
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
#ifdef DXX_CONSTANT_TRUE
/*
* If EXPR and d are compile-time constant, and the (EXPR > d)
* branch is optimized out, then the expansion of
@ -176,8 +176,8 @@ static inline void check_range_bounds(const char *file, unsigned line, const cha
* as compile-time constant.
*
* If the compiler cannot optimize based on the result of
* __builtin_constant_p (such as at -O0), then configure tests set
* !DXX_HAVE_BUILTIN_CONSTANT_P and the macro expands to nothing.
* __builtin_constant_p (such as at -O0), then configure tests do
* not define DXX_CONSTANT_TRUE and the macro expands to nothing.
*/
#define PARTIAL_RANGE_COMPILE_CHECK_BOUND(EXPR,S) \
(DXX_CONSTANT_TRUE(EXPR > d) && (DXX_ALWAYS_ERROR_FUNCTION(partial_range_will_always_throw_##S, #S " will always throw"), 0))
@ -237,7 +237,7 @@ template <typename I, std::size_t required_buffer_size>
__attribute_warn_unused_result
static inline partial_range_t<I> (unchecked_partial_range)(const char *file, unsigned line, const char *estr, I range_begin, const std::size_t o, const std::size_t l, std::true_type)
{
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
#ifdef DXX_CONSTANT_TRUE
/* Compile-time only check. Runtime handles (o > l) correctly, and
* it can happen in a correct program. If it is guaranteed to
* happen, then the range is always empty, which likely indicates a

View file

@ -44,7 +44,7 @@
#include "compiler-type_traits.h"
#include "partial_range.h"
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
#ifdef DXX_CONSTANT_TRUE
#define _DXX_PHYSFS_CHECK_SIZE_CONSTANT(S,v) DXX_CONSTANT_TRUE((S) > (v))
#define _DXX_PHYSFS_CHECK_SIZE(S,C,v) _DXX_PHYSFS_CHECK_SIZE_CONSTANT(static_cast<size_t>(S) * static_cast<size_t>(C), v)
#define DXX_PHYSFS_CHECK_READ_SIZE_OBJECT_SIZE(S,C,v) \

View file

@ -361,9 +361,9 @@ public:
}
template <integral_type v>
basic_ptr(const magic_constant<v> &, array_managed_type &a) :
m_ptr(static_cast<std::size_t>(v) < array_size ? &(a[v]) : nullptr)
m_ptr(&a[v])
{
static_assert(allow_nullptr || static_cast<std::size_t>(v) < array_size, "invalid magic index not allowed for this policy");
static_assert(static_cast<std::size_t>(v) < array_size, "valid magic index required when using array");
}
template <typename rpolicy, unsigned ru>
basic_ptr(const basic_ptr<rpolicy, ru> &rhs DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_L_DECL_VARS) :

View file

@ -25,6 +25,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#pragma once
#include "dxxsconf.h"
#include "fwd-player.h"
#include "player-callsign.h"
#include "player-flags.h"
@ -37,10 +38,20 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#include "game.h"
#ifdef _WIN32
#ifdef _WIN32_WINNT
/* Require _WIN32_WINNT >= 0x0501 to enable getaddrinfo
* Require _WIN32_WINNT >= 0x0600 to enable some useful AI_* flags
*/
#ifdef DXX_HAVE_GETADDRINFO
#define DXX_WIN32_MINIMUM_WIN32_WINNT 0x0600
#else
#define DXX_WIN32_MINIMUM_WIN32_WINNT 0x0500
#endif
#if defined(_WIN32_WINNT) && (_WIN32_WINNT < DXX_WIN32_MINIMUM_WIN32_WINNT)
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0501 // for get/freeaddrinfo()
#ifndef _WIN32_WINNT
#define _WIN32_WINNT DXX_WIN32_MINIMUM_WIN32_WINNT
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
@ -94,7 +105,7 @@ extern int multi_protocol; // set and determinate used protocol
#define MULTI_PROTO_UDP 1 // UDP protocol
// What version of the multiplayer protocol is this? Increment each time something drastic changes in Multiplayer without the version number changes. Reset to 0 each time the version of the game changes
#define MULTI_PROTO_VERSION static_cast<uint16_t>(27)
#define MULTI_PROTO_VERSION static_cast<uint16_t>(2)
// PROTOCOL VARIABLES AND DEFINES - END
// limits for Packets (i.e. positional updates) per sec
@ -494,17 +505,20 @@ void multi_do_frame(void);
#ifdef dsx
namespace dsx {
enum class multi_endlevel_type : bool
{
normal,
#if defined(DXX_BUILD_DESCENT_I)
void multi_send_endlevel_start(bool);
secret,
#endif
};
#if defined(DXX_BUILD_DESCENT_I)
void multi_send_endlevel_start(multi_endlevel_type);
#elif defined(DXX_BUILD_DESCENT_II)
void multi_send_endlevel_start();
static inline void multi_send_endlevel_start(bool secret)
static inline void multi_send_endlevel_start(multi_endlevel_type)
{
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
if (!dxx_builtin_constant_p(!!secret) || secret)
DXX_ALWAYS_ERROR_FUNCTION(multi_send_endlevel_start_with_secret, "secret not supported in Descent II");
#endif
(void)secret;
multi_send_endlevel_start();
}
#endif

View file

@ -10,6 +10,7 @@
#include "object.h"
#include "powerup.h"
#include "serial.h"
#include "fwd-player.h"
#define _UNPACK_MULTIPLAYER_SERIAL_MESSAGE(A,...) A, ## __VA_ARGS__
#define DEFINE_MULTIPLAYER_SERIAL_MESSAGE(C,T,V,A) \
@ -32,7 +33,7 @@
VALUE(MULTI_CONTROLCEN , 4) \
VALUE(MULTI_ROBOT_CLAIM , 5) \
VALUE(MULTI_CLOAK , 2) \
VALUE(MULTI_ENDLEVEL_START , 3) \
VALUE(MULTI_ENDLEVEL_START , DXX_MP_SIZE_ENDLEVEL_START) \
VALUE(MULTI_CREATE_EXPLOSION , 2) \
VALUE(MULTI_CONTROLCEN_FIRE , 16) \
VALUE(MULTI_CREATE_POWERUP , 19) \
@ -56,7 +57,7 @@
VALUE(MULTI_SAVE_GAME , 2+24) /* (ubyte slot, uint id, char name[20]) */ \
VALUE(MULTI_RESTORE_GAME , 2+4) /* (ubyte slot, uint id) */ \
VALUE(MULTI_HEARTBEAT , 5) \
VALUE(MULTI_KILLGOALS , 9) \
VALUE(MULTI_KILLGOALS , 1 + MAX_PLAYERS) \
VALUE(MULTI_DO_BOUNTY , 2) \
VALUE(MULTI_TYPING_STATE , 3) \
VALUE(MULTI_GMODE_UPDATE , 3) \
@ -68,12 +69,14 @@
D2X_MP_COMMANDS(VALUE) \
#if defined(DXX_BUILD_DESCENT_I)
#define DXX_MP_SIZE_ENDLEVEL_START 3
#define DXX_MP_SIZE_PLAYER_RELATED 58
#define DXX_MP_SIZE_PLAYER_INVENTORY 15
#define DXX_MP_SIZE_BEGIN_SYNC 37
#define DXX_MP_SIZE_DOOR_OPEN 4
#define D2X_MP_COMMANDS(VALUE)
#elif defined(DXX_BUILD_DESCENT_II)
#define DXX_MP_SIZE_ENDLEVEL_START 2
#define DXX_MP_SIZE_PLAYER_RELATED (97+10)
#define DXX_MP_SIZE_PLAYER_INVENTORY 21
#define DXX_MP_SIZE_BEGIN_SYNC 41

View file

@ -96,6 +96,7 @@ struct player_info
fix homing_object_dist; // Distance of nearest homing object.
#if defined(DXX_BUILD_DESCENT_II)
fix Omega_charge;
fix Omega_recharge_delay;
#endif
player_flags powerup_flags;
objnum_t killer_objnum; // Who killed me.... (-1 if no one)
@ -117,6 +118,9 @@ struct player_info
array<uint8_t, SUPER_WEAPON> Primary_last_was_super;
array<uint8_t, SUPER_WEAPON> Secondary_last_was_super;
#endif
int16_t net_killed_total; // Number of times killed total
int16_t net_kills_total; // Number of net kills total
int16_t KillGoalCount; // Num of players killed this level
union {
struct {
int score; // Current score.

View file

@ -64,9 +64,6 @@ struct player : public prohibit_void_ptr<player>
fix time_total; // Game time played (high word = seconds)
short KillGoalCount; // Num of players killed this level
short net_killed_total; // Number of times killed total
short net_kills_total; // Number of net kills total
short num_kills_level; // Number of kills this level
short num_kills_total; // Number of kills total
short num_robots_level; // Number of initial robots this level

View file

@ -322,7 +322,7 @@ void start_endlevel_sequence()
get_local_plrobj().ctype.player_info.homing_object_dist = -F1_0; // Turn off homing sound.
if (Game_mode & GM_MULTI) {
multi_send_endlevel_start(0);
multi_send_endlevel_start(multi_endlevel_type::normal);
multi_do_protocol_frame(1, 1);
}
@ -412,7 +412,7 @@ void start_endlevel_sequence()
}
if (Game_mode & GM_MULTI) {
multi_send_endlevel_start(0);
multi_send_endlevel_start(multi_endlevel_type::normal);
multi_do_protocol_frame(1, 1);
}
#ifndef NDEBUG

View file

@ -196,9 +196,11 @@ static void show_netplayerinfo()
gr_set_fontcolor(BM_XRGB(prgb.r, prgb.g, prgb.b), -1);
gr_printf(x,y,"%s\n",static_cast<const char *>(Players[i].callsign));
{
auto &plrobj = *vcobjptr(Players[i].objnum);
auto &player_info = plrobj.ctype.player_info;
auto v = ((Game_mode & GM_MULTI_COOP)
? vcobjptr(Players[i].objnum)->ctype.player_info.mission.score
: (gr_printf(x + fspacx8 * 12, y,"%-6d", Players[i].net_killed_total), Players[i].net_kills_total)
? player_info.mission.score
: (gr_printf(x + fspacx8 * 12, y,"%-6d", player_info.net_killed_total), player_info.net_kills_total)
);
gr_printf(x + fspacx8 * 7, y, "%-6d", v);
}

View file

@ -287,18 +287,18 @@ void init_player_stats_game(ubyte pnum)
Players[pnum].time_total = 0;
Players[pnum].hours_level = 0;
Players[pnum].hours_total = 0;
Players[pnum].net_killed_total = 0;
Players[pnum].net_kills_total = 0;
Players[pnum].num_kills_level = 0;
Players[pnum].num_kills_total = 0;
Players[pnum].num_robots_level = 0;
Players[pnum].num_robots_total = 0;
Players[pnum].KillGoalCount = 0;
Players[pnum].hostages_level = 0;
Players[pnum].hostages_total = 0;
const auto &&plobj = vobjptr(Players[pnum].objnum);
auto &player_info = plobj->ctype.player_info;
player_info.powerup_flags = {};
player_info.net_killed_total = 0;
player_info.net_kills_total = 0;
player_info.KillGoalCount = 0;
player_info.mission.score = 0;
player_info.mission.last_score = 0;
player_info.mission.hostages_rescued_total = 0;
@ -429,6 +429,7 @@ void init_player_stats_new_ship(ubyte pnum)
player_info.powerup_flags &= ~(PLAYER_FLAGS_AFTERBURNER | PLAYER_FLAGS_MAP_ALL | PLAYER_FLAGS_CONVERTER | PLAYER_FLAGS_AMMO_RACK | PLAYER_FLAGS_HEADLIGHT | PLAYER_FLAGS_HEADLIGHT_ON | PLAYER_FLAGS_FLAG);
if (granted_primary_weapon_flags & HAS_OMEGA_FLAG)
player_info.Omega_charge = MAX_OMEGA_CHARGE;
player_info.Omega_recharge_delay = 0;
#endif
player_info.powerup_flags |= map_granted_flags_to_player_flags(GrantedItems);
DXX_MAKE_VAR_UNDEFINED(player_info.cloak_time);

View file

@ -670,15 +670,14 @@ static void hud_show_score()
gr_set_curfont( GAME_FONT );
auto &plr = get_local_player();
const char *label;
int value;
auto &player_info = get_local_plrobj().ctype.player_info;
if ( ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP)) ) {
label = TXT_KILLS;
value = plr.net_kills_total;
value = player_info.net_kills_total;
} else {
label = TXT_SCORE;
auto &player_info = get_local_plrobj().ctype.player_info;
value = player_info.mission.score;
}
snprintf(score_str, sizeof(score_str), "%s: %5d", label, value);
@ -769,11 +768,10 @@ static void sb_show_score(const local_multires_gauge_graphic multires_gauge_grap
gr_printf(HUD_SCALE_X(SB_SCORE_LABEL_X), HUD_SCALE_Y(SB_SCORE_Y), "%s:", (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ? TXT_KILLS : TXT_SCORE);
gr_set_curfont( GAME_FONT );
auto &player = get_local_player();
auto &player_info = get_local_plrobj().ctype.player_info;
snprintf(score_str, sizeof(score_str), "%5d",
(Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP)
? player.net_kills_total
? player_info.net_kills_total
: (gr_set_fontcolor(BM_XRGB(0,31,0), -1), player_info.mission.score));
int w, h;
gr_get_string_size(score_str, &w, &h, nullptr);
@ -1608,7 +1606,8 @@ static void hud_show_lives(const local_multires_gauge_graphic multires_gauge_gra
if (Game_mode & GM_MULTI) {
gr_set_curfont( GAME_FONT );
gr_set_fontcolor(BM_XRGB(0,31,0),-1 );
gr_printf(x, FSPACY(1), "%s: %d", TXT_DEATHS, get_local_player().net_killed_total);
auto &player_info = get_local_plrobj().ctype.player_info;
gr_printf(x, FSPACY(1), "%s: %d", TXT_DEATHS, player_info.net_killed_total);
}
else if (get_local_player().lives > 1) {
gr_set_curfont( GAME_FONT );
@ -1637,7 +1636,8 @@ static void sb_show_lives(const local_multires_gauge_graphic multires_gauge_grap
char killed_str[20];
static array<int, 4> last_x{{SB_SCORE_RIGHT_L, SB_SCORE_RIGHT_L, SB_SCORE_RIGHT_H, SB_SCORE_RIGHT_H}};
snprintf(killed_str, sizeof(killed_str), "%5d", get_local_player().net_killed_total);
auto &player_info = get_local_plrobj().ctype.player_info;
snprintf(killed_str, sizeof(killed_str), "%5d", player_info.net_killed_total);
int w, h;
gr_get_string_size(killed_str, &w, &h, nullptr);
const auto x = HUD_SCALE_X(SB_SCORE_RIGHT)-w-FSPACX(1);
@ -2972,6 +2972,7 @@ static void hud_show_kill_list()
player_num = i;
else
player_num = player_list[i];
auto &p = Players[player_num];
color_t fontcolor;
rgb color;
@ -3013,14 +3014,14 @@ static void hud_show_kill_list()
}
gr_string(x0, y, name, sw, sh);
auto &player_info = vcobjptr(p.objnum)->ctype.player_info;
if (Show_kill_list==2)
{
auto &p = Players[player_num];
const int eff = (p.net_killed_total + p.net_kills_total <= 0)
const int eff = (player_info.net_killed_total + player_info.net_kills_total <= 0)
? 0
: static_cast<int>(
static_cast<float>(p.net_kills_total) / (
static_cast<float>(p.net_killed_total) + static_cast<float>(p.net_kills_total)
static_cast<float>(player_info.net_kills_total) / (
static_cast<float>(player_info.net_killed_total) + static_cast<float>(player_info.net_kills_total)
) * 100.0
);
gr_printf(x1, y, "%i%%", eff <= 0 ? 0 : eff);
@ -3030,9 +3031,9 @@ static void hud_show_kill_list()
else if (Game_mode & GM_MULTI_COOP)
gr_printf(x1, y, "%-6d", vcobjptr(Players[player_num].objnum)->ctype.player_info.mission.score);
else if (Netgame.PlayTimeAllowed || Netgame.KillGoal)
gr_printf(x1,y,"%3d(%d)",Players[player_num].net_kills_total,Players[player_num].KillGoalCount);
gr_printf(x1,y,"%3d(%d)", player_info.net_kills_total, player_info.KillGoalCount);
else
gr_printf(x1,y,"%3d",Players[player_num].net_kills_total);
gr_printf(x1,y,"%3d", player_info.net_kills_total);
if (PlayerCfg.MultiPingHud && Show_kill_list != 3)
{

View file

@ -72,7 +72,6 @@ static void kmatrix_redraw_coop();
static void kmatrix_draw_item(int i, playernum_array_t &sorted)
{
int x, y;
char temp[10];
y = FSPACY(50+i*9);
const auto &&fspacx = FSPACX();
@ -105,21 +104,19 @@ static void kmatrix_draw_item(int i, playernum_array_t &sorted)
}
}
{
auto &p = Players[sorted[i]];
const int eff = (p.net_killed_total + p.net_kills_total <= 0)
auto &player_info = vcobjptr(p.objnum)->ctype.player_info;
const int eff = (player_info.net_killed_total + player_info.net_kills_total <= 0)
? 0
: static_cast<int>(
static_cast<float>(p.net_kills_total) / (
static_cast<float>(p.net_killed_total) + static_cast<float>(p.net_kills_total)
static_cast<float>(player_info.net_kills_total) / (
static_cast<float>(player_info.net_killed_total) + static_cast<float>(player_info.net_kills_total)
) * 100.0
);
snprintf(temp, sizeof(temp), "%i%%", eff <= 0 ? 0 : eff);
}
x = fspacx(60 + CENTERING_OFFSET(N_players) + N_players * 25);
gr_set_fontcolor(rgb25, -1);
gr_printf( x ,y,"%4d/%s",Players[sorted[i]].net_kills_total,temp);
gr_printf(x, y, "%4d/%i%%", player_info.net_kills_total, eff <= 0 ? 0 : eff);
}
static void kmatrix_draw_names(playernum_array_t &sorted)
@ -271,7 +268,7 @@ static void kmatrix_redraw_coop()
gr_set_fontcolor(rgb60_40_10, -1);
auto &player_info = vcobjptr(plr.objnum)->ctype.player_info;
gr_printf(x_centerscreen, y, "%d", player_info.mission.score);
gr_printf(x_centerscreen + fspacx50, y, "%d", plr.net_killed_total);
gr_printf(x_centerscreen + fspacx50, y, "%d", player_info.net_killed_total);
}
gr_palette_load(gr_palette);

View file

@ -499,8 +499,6 @@ static void create_omega_blobs(const segptridx_t firing_segnum, const vms_vector
#define OMEGA_CHARGE_SCALE 4
int Last_omega_fire_time=0;
// ---------------------------------------------------------------------------------
// Call this every frame to recharge the Omega Cannon.
void omega_charge_frame(void)
@ -519,10 +517,16 @@ void omega_charge_frame(void)
return;
// Don't charge while firing. Wait 1/3 second after firing before recharging
if (Last_omega_fire_time > GameTime64)
Last_omega_fire_time = GameTime64;
if (Last_omega_fire_time + F1_0/3 > GameTime64)
return;
auto &Omega_recharge_delay = player_info.Omega_recharge_delay;
if (Omega_recharge_delay)
{
if (Omega_recharge_delay > FrameTime)
{
Omega_recharge_delay -= FrameTime;
return;
}
Omega_recharge_delay = 0;
}
if (auto &energy = player_info.energy)
{
@ -556,11 +560,9 @@ static void do_omega_stuff(const vobjptridx_t parent_objp, const vms_vector &fir
{
vms_vector goal_pos;
const auto pnum = get_player_id(parent_objp);
fix fire_frame_overhead = 0;
if (pnum == Player_num) {
// If charge >= min, or (some charge and zero energy), allow to fire.
auto &player_info = get_local_plrobj().ctype.player_info;
auto &player_info = parent_objp->ctype.player_info;
auto &Omega_charge = player_info.Omega_charge;
if (!((Omega_charge >= MIN_OMEGA_CHARGE) || (Omega_charge && !player_info.energy))) {
obj_delete(weapon_objp);
@ -571,12 +573,7 @@ static void do_omega_stuff(const vobjptridx_t parent_objp, const vms_vector &fir
if (Omega_charge < 0)
Omega_charge = 0;
if (GameTime64 - Last_omega_fire_time + OMEGA_BASE_TIME <= FrameTime) // if firing is prolonged by FrameTime overhead, let's try to fix that. Since Next_laser_firing_time is probably changed already (in do_laser_firing_player), we need to calculate the overhead slightly different.
fire_frame_overhead = GameTime64 - Last_omega_fire_time + OMEGA_BASE_TIME;
auto &Next_laser_fire_time = parent_objp->ctype.player_info.Next_laser_fire_time;
Next_laser_fire_time = GameTime64+OMEGA_BASE_TIME-fire_frame_overhead;
Last_omega_fire_time = GameTime64;
player_info.Omega_recharge_delay = F1_0 / 3;
}
weapon_objp->ctype.laser_info.parent_type = OBJ_PLAYER;
@ -1865,10 +1862,17 @@ int do_laser_firing_player(void)
if (GameTime64 - Next_laser_fire_time <= FrameTime) // if firing is prolonged by FrameTime overhead, let's try to fix that.
fire_frame_overhead = GameTime64 - Next_laser_fire_time;
if (!cheats.rapidfire)
Next_laser_fire_time = GameTime64 + Weapon_info[weapon_index].fire_wait - fire_frame_overhead;
else
Next_laser_fire_time = GameTime64 + (F1_0/25) - fire_frame_overhead;
Next_laser_fire_time = GameTime64 - fire_frame_overhead + (unlikely(cheats.rapidfire)
? (F1_0 / 25)
: (
#if defined(DXX_BUILD_DESCENT_II)
weapon_index == weapon_id_type::OMEGA_ID
? OMEGA_BASE_TIME
:
#endif
Weapon_info[weapon_index].fire_wait
)
);
laser_level = player_info.laser_level;
@ -2248,7 +2252,7 @@ static void create_smart_children(const vobjptridx_t objp, const uint_fast32_t n
? objptridx((numobjs == 1)
? objlist[0]
: get_random_different_object())
: objptridx(object_none);
: object_none;
create_homing_missile(objp, sel_objnum, blob_id, (i==0)?1:0);
}
}
@ -2270,10 +2274,6 @@ void create_weapon_smart_children(const vobjptridx_t objp)
create_smart_children(objp, NUM_SMART_CHILDREN, {objp->ctype.laser_info.parent_type, objp->ctype.laser_info.parent_num});
}
}
namespace dsx {
#if defined(DXX_BUILD_DESCENT_II)
void create_robot_smart_children(const vobjptridx_t objp, const uint_fast32_t num_smart_children)
@ -2376,7 +2376,7 @@ void do_missile_firing(int drop_bomb)
if (Game_mode & GM_MULTI)
{
multi_send_fire(weapon+MISSILE_ADJUST, 0, gun_flag, 1, Network_laser_track, weapon_index_is_player_bomb(weapon) ? objnum : objptridx(object_none));
multi_send_fire(weapon+MISSILE_ADJUST, 0, gun_flag, 1, Network_laser_track, weapon_index_is_player_bomb(weapon) ? objnum : object_none);
}
// don't autoselect if dropping prox and prox not current weapon

View file

@ -520,13 +520,15 @@ kmatrix_result multi_endlevel_score()
vobjptr(i.objnum)->ctype.player_info.powerup_flags &= ~(PLAYER_FLAGS_BLUE_KEY | PLAYER_FLAGS_RED_KEY | PLAYER_FLAGS_GOLD_KEY);
}
#if defined(DXX_BUILD_DESCENT_II)
range_for (auto &i, partial_const_range(Players, Netgame.max_numplayers))
vobjptr(i.objnum)->ctype.player_info.powerup_flags &= ~(PLAYER_FLAGS_FLAG); // Clear capture flag
{
auto &obj = *vobjptr(i.objnum);
auto &player_info = obj.ctype.player_info;
#if defined(DXX_BUILD_DESCENT_II)
player_info.powerup_flags &= ~(PLAYER_FLAGS_FLAG); // Clear capture flag
#endif
range_for (auto &i, Players)
i.KillGoalCount=0;
player_info.KillGoalCount = 0;
}
// hide Game_wind again if we brought it up
if (Game_wind && game_wind_visible)
@ -558,9 +560,6 @@ void multi_new_game()
{
sorted_kills[i] = i;
Players[i].connected = CONNECT_DISCONNECTED;
Players[i].net_killed_total = 0;
Players[i].net_kills_total = 0;
Players[i].KillGoalCount=0;
}
multi_sending_message.fill(msgsend_none);
@ -635,29 +634,28 @@ void multi_sort_kill_list()
array<int, MAX_PLAYERS> kills;
for (uint_fast32_t i = 0; i < MAX_PLAYERS; i++)
{
auto &player_info = vcobjptr(Players[i].objnum)->ctype.player_info;
if (Game_mode & GM_MULTI_COOP)
{
auto &player_info = vcobjptr(Players[i].objnum)->ctype.player_info;
kills[i] = player_info.mission.score;
}
#if defined(DXX_BUILD_DESCENT_II)
else
if (Show_kill_list==2)
{
auto &p = Players[i];
const auto kk = p.net_killed_total + p.net_kills_total;
const auto kk = player_info.net_killed_total + player_info.net_kills_total;
// always draw the ones without any ratio last
kills[i] = kk <= 0
? kk - 1
: static_cast<int>(
static_cast<float>(p.net_kills_total) / (
static_cast<float>(p.net_killed_total) + static_cast<float>(p.net_kills_total)
static_cast<float>(player_info.net_kills_total) / (
static_cast<float>(player_info.net_killed_total) + static_cast<float>(player_info.net_kills_total)
) * 100.0
);
}
#endif
else
kills[i] = Players[i].net_kills_total;
kills[i] = player_info.net_kills_total;
}
const auto predicate = [&](unsigned a, unsigned b) {
@ -722,9 +720,9 @@ static void multi_compute_kill(const objptridx_t killer, const vobjptridx_t kill
{
if (Game_mode & GM_TEAM)
-- team_kills[get_team(killed_pnum)];
Players[killed_pnum].net_killed_total++;
Players[killed_pnum].net_kills_total--;
-- Players[killed_pnum].KillGoalCount;
++ killed->ctype.player_info.net_killed_total;
-- killed->ctype.player_info.net_kills_total;
-- killed->ctype.player_info.KillGoalCount;
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_multi_kill(killed_pnum, -1);
@ -761,7 +759,7 @@ static void multi_compute_kill(const objptridx_t killer, const vobjptridx_t kill
else
HUD_init_message(HM_MULTI, "%s %s %s.", killed_name, TXT_WAS, TXT_KILLED_BY_ROBOT );
}
Players[killed_pnum].net_killed_total++;
++ killed->ctype.player_info.net_killed_total;
return;
}
@ -787,9 +785,9 @@ static void multi_compute_kill(const objptridx_t killer, const vobjptridx_t kill
team_kills[get_team(killed_pnum)] -= 1;
}
Players[killed_pnum].net_killed_total += 1;
Players[killed_pnum].net_kills_total -= 1;
-- Players[killed_pnum].KillGoalCount;
++ killed->ctype.player_info.net_killed_total;
-- killed->ctype.player_info.net_kills_total;
-- killed->ctype.player_info.KillGoalCount;
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_multi_kill(killed_pnum, -1);
@ -842,8 +840,8 @@ static void multi_compute_kill(const objptridx_t killer, const vobjptridx_t kill
if (is_team_game)
{
team_kills[killer_team] += adjust;
Players[killer_pnum].net_kills_total += adjust;
Players[killer_pnum].KillGoalCount += adjust;
killer->ctype.player_info.net_kills_total += adjust;
killer->ctype.player_info.KillGoalCount += adjust;
}
else if( Game_mode & GM_BOUNTY )
{
@ -851,8 +849,8 @@ static void multi_compute_kill(const objptridx_t killer, const vobjptridx_t kill
if( killed_pnum == Bounty_target || killer_pnum == Bounty_target )
{
/* Increment kill counts */
Players[killer_pnum].net_kills_total++;
Players[killer_pnum].KillGoalCount++;
++ killer->ctype.player_info.net_kills_total;
++ killer->ctype.player_info.KillGoalCount;
/* If the target died, the new one is set! */
if( killed_pnum == Bounty_target )
@ -861,15 +859,15 @@ static void multi_compute_kill(const objptridx_t killer, const vobjptridx_t kill
}
else
{
Players[killer_pnum].net_kills_total += 1;
Players[killer_pnum].KillGoalCount+=1;
++ killer->ctype.player_info.net_kills_total;
++ killer->ctype.player_info.KillGoalCount;
}
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_multi_kill(killer_pnum, 1);
}
Players[killed_pnum].net_killed_total += 1;
++ killed->ctype.player_info.net_killed_total;
const char *name0, *name1;
if (killer_pnum == Player_num) {
if (Game_mode & GM_MULTI_COOP)
@ -898,7 +896,7 @@ static void multi_compute_kill(const objptridx_t killer, const vobjptridx_t kill
const auto TheGoal = Netgame.KillGoal * 5;
if (((Game_mode & GM_TEAM)
? team_kills[get_team(killer_pnum)]
: Players[killer_pnum].KillGoalCount
: killer->ctype.player_info.KillGoalCount
) >= TheGoal)
{
if (killer_pnum==Player_num)
@ -975,18 +973,22 @@ void multi_do_frame(void)
multi_send_gmode_update();
last_gmode_time = timer_query();
}
// Send out inventory three times per second
if (timer_query() >= last_inventory_time + (F1_0/3))
if (Network_status == NETSTAT_PLAYING)
{
multi_send_player_inventory(0);
last_inventory_time = timer_query();
// Send out inventory three times per second
if (timer_query() >= last_inventory_time + (F1_0/3))
{
multi_send_player_inventory(0);
last_inventory_time = timer_query();
}
// Repopulate the level if necessary
if (timer_query() >= last_repo_time + (F1_0/2))
{
MultiLevelInv_Repopulate((F1_0/2));
last_repo_time = timer_query();
}
}
// Repopulate the level if necessary
if (timer_query() >= last_repo_time + (F1_0/2))
{
MultiLevelInv_Repopulate((F1_0/2));
last_repo_time = timer_query();
}
multi_send_message(); // Send any waiting messages
@ -1929,24 +1931,30 @@ static void multi_do_controlcen_destroy(const ubyte *buf)
static void multi_do_escape(const ubyte *buf)
{
const auto objnum = vobjptridx(Players[buf[1]].objnum);
digi_play_sample(SOUND_HUD_MESSAGE, F1_0);
auto &plr = Players[buf[1]];
const auto &&objnum = vobjptridx(plr.objnum);
#if defined(DXX_BUILD_DESCENT_II)
digi_kill_sound_linked_to_object (objnum);
#endif
if (buf[2] == 0)
const char *txt;
int connected;
#if defined(DXX_BUILD_DESCENT_I)
if (buf[2] == static_cast<uint8_t>(multi_endlevel_type::secret))
{
HUD_init_message(HM_MULTI, "%s %s", static_cast<const char *>(Players[static_cast<int>(buf[1])].callsign), TXT_HAS_ESCAPED);
if (Game_mode & GM_NETWORK)
Players[static_cast<int>(buf[1])].connected = CONNECT_ESCAPE_TUNNEL;
txt = TXT_HAS_FOUND_SECRET;
connected = CONNECT_FOUND_SECRET;
}
else if (buf[2] == 1)
else
#endif
{
HUD_init_message(HM_MULTI, "%s %s", static_cast<const char *>(Players[static_cast<int>(buf[1])].callsign), TXT_HAS_FOUND_SECRET);
if (Game_mode & GM_NETWORK)
Players[static_cast<int>(buf[1])].connected = CONNECT_FOUND_SECRET;
txt = TXT_HAS_ESCAPED;
connected = CONNECT_ESCAPE_TUNNEL;
}
HUD_init_message(HM_MULTI, "%s %s", static_cast<const char *>(plr.callsign), txt);
if (Game_mode & GM_NETWORK)
plr.connected = connected;
create_player_appearance_effect(objnum);
multi_make_player_ghost(buf[1]);
}
@ -2569,18 +2577,18 @@ void multi_send_markers()
#endif
#if defined(DXX_BUILD_DESCENT_I)
void multi_send_endlevel_start(const bool secret)
void multi_send_endlevel_start(const multi_endlevel_type secret)
#elif defined(DXX_BUILD_DESCENT_II)
void multi_send_endlevel_start()
#endif
{
#if defined(DXX_BUILD_DESCENT_II)
const bool secret = false;
array<uint8_t, DXX_MP_SIZE_ENDLEVEL_START> buf;
buf[1] = Player_num;
#if defined(DXX_BUILD_DESCENT_I)
buf[2] = static_cast<uint8_t>(secret);
#endif
multibuf[1] = Player_num;
multibuf[2] = static_cast<char>(secret);
multi_send_data<MULTI_ENDLEVEL_START>(multibuf, 3, 2);
multi_send_data<MULTI_ENDLEVEL_START>(buf.data(), buf.size(), 2);
if (Game_mode & GM_NETWORK)
{
get_local_player().connected = CONNECT_ESCAPE_TUNNEL;
@ -3412,10 +3420,9 @@ int multi_level_sync(void)
namespace dsx {
#if defined(DXX_BUILD_DESCENT_II)
static void apply_segment_goal_texture(const vsegptr_t seg, ubyte team_mask)
static void apply_segment_goal_texture(const vsegptr_t seg, const std::size_t tex)
{
seg->static_light = i2f(100); //make static light bright
std::size_t tex = find_goal_texture(game_mode_hoard() ? TMI_GOAL_HOARD : team_mask);
if (tex < TmapInfo.size())
range_for (auto &s, seg->sides)
{
@ -3427,21 +3434,29 @@ static void apply_segment_goal_texture(const vsegptr_t seg, ubyte team_mask)
void multi_apply_goal_textures()
{
std::size_t tex_blue, tex_red;
if (game_mode_hoard())
tex_blue = tex_red = find_goal_texture(TMI_GOAL_HOARD);
else
{
tex_blue = find_goal_texture(TMI_GOAL_BLUE);
tex_red = find_goal_texture(TMI_GOAL_RED);
}
range_for (const auto &&seg, vsegptr)
{
uint8_t team_mask;
std::size_t tex;
if (seg->special==SEGMENT_IS_GOAL_BLUE)
{
team_mask = TMI_GOAL_BLUE;
tex = tex_blue;
}
else if (seg->special==SEGMENT_IS_GOAL_RED)
{
// Make both textures the same if Hoard mode
team_mask = TMI_GOAL_RED;
tex = tex_red;
}
else
continue;
apply_segment_goal_texture(seg, team_mask);
apply_segment_goal_texture(seg, tex);
}
}
@ -3764,14 +3779,15 @@ static void multi_do_wall_status (const ubyte *buf)
void multi_send_kill_goal_counts()
{
int i,count=1;
int count=1;
for (i=0;i<MAX_PLAYERS;i++)
range_for (auto &i, Players)
{
multibuf[count] = Players[i].KillGoalCount;
auto &obj = *vcobjptr(i.objnum);
auto &player_info = obj.ctype.player_info;
multibuf[count] = player_info.KillGoalCount;
count++;
}
multi_send_data<MULTI_KILLGOALS>(multibuf, count, 2);
}
@ -3781,7 +3797,9 @@ static void multi_do_kill_goal_counts(const ubyte *buf)
range_for (auto &i, Players)
{
i.KillGoalCount = buf[count];
auto &obj = *vobjptr(i.objnum);
auto &player_info = obj.ctype.player_info;
player_info.KillGoalCount = buf[count];
count++;
}
@ -3832,7 +3850,9 @@ void multi_check_for_killgoal_winner ()
int highest_kill_goal_count = 0;
range_for (auto &i, partial_const_range(Players, N_players))
{
const auto KillGoalCount = i.KillGoalCount;
auto &obj = *vcobjptr(i.objnum);
auto &player_info = obj.ctype.player_info;
const auto KillGoalCount = player_info.KillGoalCount;
if (highest_kill_goal_count < KillGoalCount)
{
highest_kill_goal_count = KillGoalCount;
@ -4023,17 +4043,19 @@ void multi_do_capture_bonus(const playernum_t pnum)
: SOUND_HUD_BLUE_GOT_GOAL
), F1_0*2);
vobjptr(Players[pnum].objnum)->ctype.player_info.powerup_flags &= ~(PLAYER_FLAGS_FLAG); // Clear capture flag
team_kills[get_team(pnum)] += 5;
Players[static_cast<int>(pnum)].net_kills_total += 5;
Players[static_cast<int>(pnum)].KillGoalCount+=5;
auto &plr = Players[pnum];
auto &player_info = vobjptr(plr.objnum)->ctype.player_info;
player_info.powerup_flags &= ~PLAYER_FLAGS_FLAG; // Clear capture flag
player_info.net_kills_total += 5;
player_info.KillGoalCount += 5;
if (Netgame.KillGoal>0)
{
TheGoal=Netgame.KillGoal*5;
if (Players[static_cast<int>(pnum)].KillGoalCount>=TheGoal)
if (player_info.KillGoalCount >= TheGoal)
{
if (pnum==Player_num)
{
@ -4093,21 +4115,23 @@ void multi_do_orb_bonus(const playernum_t pnum, const ubyte *buf)
PhallicLimit=bonus;
}
vobjptr(Players[pnum].objnum)->ctype.player_info.powerup_flags &= ~(PLAYER_FLAGS_FLAG); // Clear orb flag
team_kills[get_team(pnum)] += bonus;
Players[static_cast<int>(pnum)].net_kills_total += bonus;
Players[static_cast<int>(pnum)].KillGoalCount+=bonus;
auto &plr = Players[pnum];
auto &player_info = vobjptr(plr.objnum)->ctype.player_info;
player_info.powerup_flags &= ~PLAYER_FLAGS_FLAG; // Clear orb flag
player_info.net_kills_total += bonus;
player_info.KillGoalCount += bonus;
team_kills[get_team(pnum)]%=1000;
Players[static_cast<int>(pnum)].net_kills_total%=1000;
Players[static_cast<int>(pnum)].KillGoalCount%=1000;
player_info.net_kills_total%=1000;
player_info.KillGoalCount %= 1000;
if (Netgame.KillGoal>0)
{
TheGoal=Netgame.KillGoal*5;
if (Players[static_cast<int>(pnum)].KillGoalCount>=TheGoal)
if (player_info.KillGoalCount >= TheGoal)
{
if (pnum==Player_num)
{
@ -5131,7 +5155,7 @@ void MultiLevelInv_Recount()
namespace dsx {
bool MultiLevelInv_AllowSpawn(powerup_type_t powerup_type)
{
if ((Game_mode & GM_MULTI_COOP) || Control_center_destroyed || (Network_status == NETSTAT_ENDLEVEL))
if ((Game_mode & GM_MULTI_COOP) || Control_center_destroyed || (Network_status != NETSTAT_PLAYING))
return 0;
int req_amount = 1; // required amount of item to drop a powerup.
@ -5156,7 +5180,7 @@ bool MultiLevelInv_AllowSpawn(powerup_type_t powerup_type)
// Repopulate the level with missing items.
void MultiLevelInv_Repopulate(fix frequency)
{
if (!multi_i_am_master() || (Game_mode & GM_MULTI_COOP) || Control_center_destroyed || (Network_status == NETSTAT_ENDLEVEL))
if (!multi_i_am_master() || (Game_mode & GM_MULTI_COOP) || Control_center_destroyed)
return;
MultiLevelInv_Recount(); // recount current items

View file

@ -563,7 +563,12 @@ int udp_dns_filladdr_t::apply(sockaddr &addr, socklen_t addrlen, int ai_family,
hints.ai_family = ai_family;
// We are always UDP
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_V4MAPPED | AI_ALL | AI_NUMERICSERV;
#ifdef AI_NUMERICSERV
hints.ai_flags |= AI_NUMERICSERV;
#endif
#if DXX_USE_IPv6
hints.ai_flags |= AI_V4MAPPED | AI_ALL;
#endif
// Numeric address only?
if (numeric_only)
hints.ai_flags |= AI_NUMERICHOST;
@ -1484,14 +1489,14 @@ static void net_udp_new_player(UDP_sequence_packet *const their)
Netgame.players[pnum].rank=their->player.rank;
Players[pnum].connected = CONNECT_PLAYING;
Players[pnum].net_kills_total = 0;
Players[pnum].net_killed_total = 0;
kill_matrix[pnum] = {};
const auto &&objp = vobjptr(Players[pnum].objnum);
auto &player_info = objp->ctype.player_info;
player_info.net_killed_total = 0;
player_info.net_kills_total = 0;
player_info.mission.score = 0;
player_info.powerup_flags = {};
Players[pnum].KillGoalCount=0;
player_info.KillGoalCount = 0;
if (pnum == N_players)
{
@ -1652,7 +1657,9 @@ static void net_udp_welcome_player(UDP_sequence_packet *their)
net_udp_noloss_clear_mdata_trace(player_num);
}
Players[player_num].KillGoalCount=0;
auto &obj = *vobjptr(Players[player_num].objnum);
auto &player_info = obj.ctype.player_info;
player_info.KillGoalCount = 0;
// Send updated Objects data to the new/returning player
@ -2113,10 +2120,10 @@ void net_udp_send_rejoin_sync(int player_num)
Netgame.kills = kill_matrix;
for (int j=0; j<MAX_PLAYERS; j++)
{
Netgame.killed[j] = Players[j].net_killed_total;
Netgame.player_kills[j] = Players[j].net_kills_total;
auto &objp = *vcobjptr(Players[j].objnum);
auto &player_info = objp.ctype.player_info;
Netgame.killed[j] = player_info.net_killed_total;
Netgame.player_kills[j] = player_info.net_kills_total;
Netgame.player_score[j] = player_info.mission.score;
}
@ -2143,10 +2150,10 @@ static void net_udp_resend_sync_due_to_packet_loss()
Netgame.kills = kill_matrix;
for (int j=0; j<MAX_PLAYERS; j++)
{
Netgame.killed[j] = Players[j].net_killed_total;
Netgame.player_kills[j] = Players[j].net_kills_total;
auto &objp = *vcobjptr(Players[j].objnum);
auto &player_info = objp.ctype.player_info;
Netgame.killed[j] = player_info.net_killed_total;
Netgame.player_kills[j] = player_info.net_kills_total;
Netgame.player_score[j] = player_info.mission.score;
}
@ -2177,7 +2184,9 @@ static void net_udp_add_player(UDP_sequence_packet *p)
Netgame.players[N_players].protocol.udp.addr = p->player.protocol.udp.addr;
Netgame.players[N_players].rank=p->player.rank;
Netgame.players[N_players].connected = CONNECT_PLAYING;
Players[N_players].KillGoalCount=0;
auto &obj = *vobjptr(Players[N_players].objnum);
auto &player_info = obj.ctype.player_info;
player_info.KillGoalCount = 0;
Players[N_players].connected = CONNECT_PLAYING;
Netgame.players[N_players].LastPacketTime = timer_query();
N_players++;
@ -2271,10 +2280,10 @@ void net_udp_update_netgame(void)
for (int i = 0; i < MAX_PLAYERS; i++)
{
Netgame.players[i].connected = Players[i].connected;
Netgame.killed[i] = Players[i].net_killed_total;
Netgame.player_kills[i] = Players[i].net_kills_total;
auto &objp = *vcobjptr(Players[i].objnum);
auto &player_info = objp.ctype.player_info;
Netgame.killed[i] = player_info.net_killed_total;
Netgame.player_kills[i] = player_info.net_kills_total;
#if defined(DXX_BUILD_DESCENT_II)
Netgame.player_score[i] = player_info.mission.score;
#endif
@ -2299,8 +2308,12 @@ void net_udp_send_endlevel_packet(void)
range_for (auto &i, Players)
{
buf[len] = i.connected; len++;
PUT_INTEL_SHORT(&buf[len], i.net_kills_total); len += 2;
PUT_INTEL_SHORT(&buf[len], i.net_killed_total); len += 2;
auto &objp = *vcobjptr(i.objnum);
auto &player_info = objp.ctype.player_info;
PUT_INTEL_SHORT(&buf[len], player_info.net_kills_total);
len += 2;
PUT_INTEL_SHORT(&buf[len], player_info.net_killed_total);
len += 2;
}
range_for (auto &i, kill_matrix)
@ -2322,8 +2335,11 @@ void net_udp_send_endlevel_packet(void)
buf[len] = Player_num; len++;
buf[len] = get_local_player().connected; len++;
buf[len] = Countdown_seconds_left; len++;
PUT_INTEL_SHORT(&buf[len], get_local_player().net_kills_total); len += 2;
PUT_INTEL_SHORT(&buf[len], get_local_player().net_killed_total); len += 2;
auto &player_info = get_local_plrobj().ctype.player_info;
PUT_INTEL_SHORT(&buf[len], player_info.net_kills_total);
len += 2;
PUT_INTEL_SHORT(&buf[len], player_info.net_killed_total);
len += 2;
range_for (auto &i, kill_matrix[Player_num])
{
@ -2984,8 +3000,12 @@ void net_udp_read_endlevel_packet(const uint8_t *data, const _sockaddr &sender_a
tmpvar = data[len]; len++;
if ((Network_status != NETSTAT_PLAYING) && (Players[pnum].connected == CONNECT_PLAYING) && (tmpvar < Countdown_seconds_left))
Countdown_seconds_left = tmpvar;
Players[pnum].net_kills_total = GET_INTEL_SHORT(&(data[len])); len += 2;
Players[pnum].net_killed_total = GET_INTEL_SHORT(&(data[len])); len += 2;
auto &objp = *vobjptr(Players[pnum].objnum);
auto &player_info = objp.ctype.player_info;
player_info.net_kills_total = GET_INTEL_SHORT(&data[len]);
len += 2;
player_info.net_killed_total = GET_INTEL_SHORT(&data[len]);
len += 2;
range_for (auto &i, kill_matrix[pnum])
{
@ -3015,9 +3035,13 @@ void net_udp_read_endlevel_packet(const uint8_t *data, const _sockaddr &sender_a
if (static_cast<int>(data[len]) == CONNECT_DISCONNECTED)
multi_disconnect_player(i);
auto &objp = *vobjptr(Players[i].objnum);
auto &player_info = objp.ctype.player_info;
Players[i].connected = data[len]; len++;
Players[i].net_kills_total = GET_INTEL_SHORT(&(data[len])); len += 2;
Players[i].net_killed_total = GET_INTEL_SHORT(&(data[len])); len += 2;
player_info.net_kills_total = GET_INTEL_SHORT(&data[len]);
len += 2;
player_info.net_killed_total = GET_INTEL_SHORT(&data[len]);
len += 2;
if (Players[i].connected)
Netgame.players[i].LastPacketTime = timer_query();
@ -3936,11 +3960,6 @@ void net_udp_read_sync_packet(const uint8_t * data, uint_fast32_t data_len, cons
Player_num = MULTI_PNUM_UNDEF;
range_for (auto &i, Players)
{
i.net_kills_total = 0;
}
for (int i=0; i<N_players; i++ ) {
if (i == Netgame.protocol.udp.your_index && Netgame.players[i].callsign == temp_callsign)
{
@ -3953,10 +3972,10 @@ void net_udp_read_sync_packet(const uint8_t * data, uint_fast32_t data_len, cons
}
Players[i].callsign = Netgame.players[i].callsign;
Players[i].connected = Netgame.players[i].connected;
Players[i].net_kills_total = Netgame.player_kills[i];
Players[i].net_killed_total = Netgame.killed[i];
auto &objp = *vobjptr(Players[i].objnum);
auto &player_info = objp.ctype.player_info;
player_info.net_kills_total = Netgame.player_kills[i];
player_info.net_killed_total = Netgame.killed[i];
if ((Network_rejoined) || (i != Player_num))
player_info.mission.score = Netgame.player_score[i];
}
@ -3969,8 +3988,11 @@ void net_udp_read_sync_packet(const uint8_t * data, uint_fast32_t data_len, cons
}
#if defined(DXX_BUILD_DESCENT_I)
PlayerCfg.NetlifeKills -= get_local_player().net_kills_total;
PlayerCfg.NetlifeKilled -= get_local_player().net_killed_total;
{
auto &player_info = get_local_plrobj().ctype.player_info;
PlayerCfg.NetlifeKills -= player_info.net_kills_total;
PlayerCfg.NetlifeKilled -= player_info.net_killed_total;
}
#endif
if (Network_rejoined)
@ -5855,7 +5877,7 @@ static void udp_tracker_process_ack( ubyte *data, int data_len, const _sockaddr
/* 10 seconds passed since we registered our game. If we have not received all ACK's, yet, tell user about that! */
static void udp_tracker_verify_ack_timeout()
{
if (!Netgame.Tracker || TrackerAckTime + F1_0*10 > timer_query() || TrackerAckStatus == TrackerAckState::TACK_SEQCOMPL)
if (!Netgame.Tracker || !multi_i_am_master() || TrackerAckTime + F1_0*10 > timer_query() || TrackerAckStatus == TrackerAckState::TACK_SEQCOMPL)
return;
if (TrackerAckStatus == TrackerAckState::TACK_NOCONNECTION)
{

View file

@ -1031,11 +1031,12 @@ void newdemo_record_start_demo()
nd_write_string(static_cast<const char *>(i.callsign));
nd_write_byte(i.connected);
auto &pl_info = vcobjptr(i.objnum)->ctype.player_info;
if (Game_mode & GM_MULTI_COOP) {
nd_write_int(vcobjptr(i.objnum)->ctype.player_info.mission.score);
nd_write_int(pl_info.mission.score);
} else {
nd_write_short(i.net_killed_total);
nd_write_short(i.net_kills_total);
nd_write_short(pl_info.net_killed_total);
nd_write_short(pl_info.net_kills_total);
}
}
} else
@ -1450,8 +1451,9 @@ void newdemo_record_multi_connect(int pnum, int new_player, const char *new_call
nd_write_byte(static_cast<int8_t>(new_player));
if (!new_player) {
nd_write_string(static_cast<const char *>(Players[pnum].callsign));
nd_write_int(Players[pnum].net_killed_total);
nd_write_int(Players[pnum].net_kills_total);
auto &player_info = vcobjptr(Players[pnum].objnum)->ctype.player_info;
nd_write_int(player_info.net_killed_total);
nd_write_int(player_info.net_kills_total);
}
nd_write_string(new_callsign);
}
@ -1757,12 +1759,12 @@ static int newdemo_read_demo_start(enum purpose_type purpose)
if (purpose == PURPOSE_REWRITE)
nd_write_int(player_info.mission.score);
} else {
nd_read_short(&i.net_killed_total);
nd_read_short(&i.net_kills_total);
nd_read_short(&player_info.net_killed_total);
nd_read_short(&player_info.net_kills_total);
if (purpose == PURPOSE_REWRITE)
{
nd_write_short(i.net_killed_total);
nd_write_short(i.net_kills_total);
nd_write_short(player_info.net_killed_total);
nd_write_short(player_info.net_kills_total);
}
}
}
@ -2770,10 +2772,11 @@ static int newdemo_read_frame_information(int rewrite)
nd_write_byte(pnum);
break;
}
auto &player_info = vobjptr(Players[pnum].objnum)->ctype.player_info;
if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD))
Players[pnum].net_killed_total--;
player_info.net_killed_total--;
else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD))
Players[pnum].net_killed_total++;
player_info.net_killed_total++;
break;
}
@ -2788,12 +2791,13 @@ static int newdemo_read_frame_information(int rewrite)
nd_write_byte(kill);
break;
}
auto &player_info = vobjptr(Players[pnum].objnum)->ctype.player_info;
if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) {
Players[pnum].net_kills_total -= kill;
player_info.net_kills_total -= kill;
if (Newdemo_game_mode & GM_TEAM)
team_kills[get_team(pnum)] -= kill;
} else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) {
Players[pnum].net_kills_total += kill;
player_info.net_kills_total += kill;
if (Newdemo_game_mode & GM_TEAM)
team_kills[get_team(pnum)] += kill;
}
@ -2828,19 +2832,20 @@ static int newdemo_read_frame_information(int rewrite)
nd_write_string(static_cast<const char *>(new_callsign));
break;
}
auto &player_info = vobjptr(Players[pnum].objnum)->ctype.player_info;
if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) {
Players[pnum].connected = CONNECT_DISCONNECTED;
if (!new_player) {
Players[pnum].callsign = old_callsign;
Players[pnum].net_killed_total = killed_total;
Players[pnum].net_kills_total = kills_total;
player_info.net_killed_total = killed_total;
player_info.net_kills_total = kills_total;
} else {
N_players--;
}
} else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) {
Players[pnum].connected = CONNECT_PLAYING;
Players[pnum].net_kills_total = 0;
Players[pnum].net_killed_total = 0;
player_info.net_kills_total = 0;
player_info.net_killed_total = 0;
Players[pnum].callsign = new_callsign;
if (new_player)
N_players++;
@ -3399,12 +3404,12 @@ void newdemo_goto_end(int to_rewrite)
range_for (auto &i, partial_range(Players, N_players)) {
nd_read_string(i.callsign.buffer());
nd_read_byte(&i.connected);
auto &pl_info = vobjptr(i.objnum)->ctype.player_info;
if (Newdemo_game_mode & GM_MULTI_COOP) {
auto &pl_info = vobjptr(i.objnum)->ctype.player_info;
nd_read_int(&pl_info.mission.score);
} else {
nd_read_short(&i.net_killed_total);
nd_read_short(&i.net_kills_total);
nd_read_short(&pl_info.net_killed_total);
nd_read_short(&pl_info.net_kills_total);
}
}
} else {
@ -3797,13 +3802,13 @@ static void newdemo_write_end()
nd_write_string(static_cast<const char *>(i.callsign));
byte_count += (strlen(static_cast<const char *>(i.callsign)) + 2);
nd_write_byte(i.connected);
auto &pl_info = vcobjptr(i.objnum)->ctype.player_info;
if (Game_mode & GM_MULTI_COOP) {
auto &pl_info = vcobjptr(i.objnum)->ctype.player_info;
nd_write_int(pl_info.mission.score);
byte_count += 5;
} else {
nd_write_short(i.net_killed_total);
nd_write_short(i.net_kills_total);
nd_write_short(pl_info.net_killed_total);
nd_write_short(pl_info.net_kills_total);
byte_count += 5;
}
}

View file

@ -496,10 +496,10 @@ static void state_player_to_player_rw(const fix pl_shields, const player *pl, pl
else
pl_rw->invulnerable_time = pl_info.invulnerable_time - GameTime64;
#if defined(DXX_BUILD_DESCENT_II)
pl_rw->KillGoalCount = pl->KillGoalCount;
pl_rw->KillGoalCount = pl_info.KillGoalCount;
#endif
pl_rw->net_killed_total = pl->net_killed_total;
pl_rw->net_kills_total = pl->net_kills_total;
pl_rw->net_killed_total = pl_info.net_killed_total;
pl_rw->net_kills_total = pl_info.net_kills_total;
pl_rw->num_kills_level = pl->num_kills_level;
pl_rw->num_kills_total = pl->num_kills_total;
pl_rw->num_robots_level = pl->num_robots_level;
@ -541,10 +541,10 @@ static void state_player_rw_to_player(const player_rw *pl_rw, player *pl, player
pl_info.cloak_time = pl_rw->cloak_time;
pl_info.invulnerable_time = pl_rw->invulnerable_time;
#if defined(DXX_BUILD_DESCENT_II)
pl->KillGoalCount = pl_rw->KillGoalCount;
pl_info.KillGoalCount = pl_rw->KillGoalCount;
#endif
pl->net_killed_total = pl_rw->net_killed_total;
pl->net_kills_total = pl_rw->net_kills_total;
pl_info.net_killed_total = pl_rw->net_killed_total;
pl_info.net_kills_total = pl_rw->net_kills_total;
pl->num_kills_level = pl_rw->num_kills_level;
pl->num_kills_total = pl_rw->num_kills_total;
pl->num_robots_level = pl_rw->num_robots_level;
@ -1815,7 +1815,13 @@ int state_restore_all_sub(const char *filename, const secret_restore secret)
{
auto i = PHYSFSX_readSXE32(fp, swap);
if (secret != secret_restore::survived)
{
player_info.Omega_charge = i;
/* The savegame does not record this, so pick a value. Be
* nice to the player: let the cannon recharge immediately.
*/
player_info.Omega_recharge_delay = 0;
}
}
#endif
@ -1910,9 +1916,9 @@ int state_restore_all_sub(const char *filename, const secret_restore secret)
Netgame.level_time = PHYSFSX_readSXE32(fp, swap);
for (playernum_t i = 0; i < MAX_PLAYERS; i++)
{
Netgame.killed[i] = Players[i].net_killed_total;
const auto &&objp = vobjptr(Players[i].objnum);
auto &pi = objp->ctype.player_info;
Netgame.killed[i] = pi.net_killed_total;
Netgame.player_score[i] = pi.mission.score;
Netgame.net_player_flags[i] = pi.powerup_flags;
}

View file

@ -302,7 +302,7 @@ int check_trigger_sub(object &plrobj, const trgnum_t trigger_num, int pnum,int s
Newdemo_state = ND_STATE_PAUSED;
if (Game_mode & GM_MULTI)
multi_send_endlevel_start(1);
multi_send_endlevel_start(multi_endlevel_type::secret);
if (Game_mode & GM_NETWORK)
multi_do_protocol_frame(1, 1);
PlayerFinishedLevel(1); //1 means go to secret level

View file

@ -56,6 +56,33 @@ namespace dsx {
array<cloaking_wall, MAX_CLOAKING_WALLS> CloakingWalls;
unsigned Num_cloaking_walls;
namespace {
struct cwframe
{
wall &w;
array<uvl, 4> &uvls;
cwframe(wall &wr) :
w(wr),
uvls(vsegptr(w.segnum)->sides[w.sidenum].uvls)
{
}
};
struct cwresult
{
bool remove;
bool record;
cwresult() = default;
explicit cwresult(bool r) :
remove(false), record(r)
{
}
};
}
}
#endif
@ -1118,143 +1145,89 @@ void reset_walls()
}
#if defined(DXX_BUILD_DESCENT_II)
static void do_cloaking_wall_frame(int cloaking_wall_num)
static void copy_cloaking_wall_light_to_wall(array<uvl, 4> &back_uvls, array<uvl, 4> &front_uvls, const cloaking_wall &d)
{
cloaking_wall *d;
sbyte old_cloak; // for demo recording
for (uint_fast32_t i = 0; i != 4; ++i)
{
back_uvls[i].l = d.back_ls[i];
front_uvls[i].l = d.front_ls[i];
}
}
if ( Newdemo_state==ND_STATE_PLAYBACK ) return;
static void scale_cloaking_wall_light_to_wall(array<uvl, 4> &back_uvls, array<uvl, 4> &front_uvls, const cloaking_wall &d, const fix light_scale)
{
for (uint_fast32_t i = 0; i != 4; ++i)
{
back_uvls[i].l = fixmul(d.back_ls[i], light_scale);
front_uvls[i].l = fixmul(d.front_ls[i], light_scale);
}
}
d = &CloakingWalls[cloaking_wall_num];
wall *const wfront = vwallptr(d->front_wallnum);
wall *const wback = wallptr(d->back_wallnum);
old_cloak = wfront->cloak_value;
d->time += FrameTime;
if (d->time > CLOAKING_WALL_TIME) {
int i;
wfront->type = WALL_OPEN;
wfront->state = WALL_DOOR_CLOSED; //why closed? why not?
if (wback) {
wback->type = WALL_OPEN;
wback->state = WALL_DOOR_CLOSED; //why closed? why not?
static cwresult do_cloaking_wall_frame(const bool initial, cloaking_wall &d, const cwframe front, const cwframe back)
{
cwresult r(initial);
if (d.time > CLOAKING_WALL_TIME) {
front.w.type = back.w.type = WALL_OPEN;
front.w.state = back.w.state = WALL_DOOR_CLOSED; //why closed? why not?
r.remove = true;
}
else if (d.time > CLOAKING_WALL_TIME/2) {
const int8_t cloak_value = ((d.time - CLOAKING_WALL_TIME / 2) * (GR_FADE_LEVELS - 2)) / (CLOAKING_WALL_TIME / 2);
if (front.w.cloak_value != cloak_value)
{
r.record = true;
front.w.cloak_value = back.w.cloak_value = cloak_value;
}
for (i=cloaking_wall_num;i<Num_cloaking_walls;i++)
CloakingWalls[i] = CloakingWalls[i+1];
Num_cloaking_walls--;
}
else if (d->time > CLOAKING_WALL_TIME/2) {
int old_type=wfront->type;
wfront->cloak_value = ((d->time - CLOAKING_WALL_TIME/2) * (GR_FADE_LEVELS-2)) / (CLOAKING_WALL_TIME/2);
if (wback)
wback->cloak_value = wfront->cloak_value;
if (old_type != WALL_CLOAKED) { //just switched
int i;
wfront->type = WALL_CLOAKED;
if (wback)
wback->type = WALL_CLOAKED;
for (i=0;i<4;i++) {
Segments[wfront->segnum].sides[wfront->sidenum].uvls[i].l = d->front_ls[i];
if (wback)
Segments[wback->segnum].sides[wback->sidenum].uvls[i].l = d->back_ls[i];
}
if (front.w.type != WALL_CLOAKED)
{ //just switched
front.w.type = back.w.type = WALL_CLOAKED;
copy_cloaking_wall_light_to_wall(back.uvls, front.uvls, d);
}
}
else { //fading out
fix light_scale;
int i;
light_scale = fixdiv(CLOAKING_WALL_TIME/2-d->time,CLOAKING_WALL_TIME/2);
for (i=0;i<4;i++) {
Segments[wfront->segnum].sides[wfront->sidenum].uvls[i].l = fixmul(d->front_ls[i],light_scale);
if (wback)
Segments[wback->segnum].sides[wback->sidenum].uvls[i].l = fixmul(d->back_ls[i],light_scale);
}
light_scale = fixdiv(CLOAKING_WALL_TIME / 2 - d.time, CLOAKING_WALL_TIME / 2);
scale_cloaking_wall_light_to_wall(back.uvls, front.uvls, d, light_scale);
}
// check if the actual cloak_value changed in this frame to prevent redundant recordings and wasted bytes
if ( Newdemo_state == ND_STATE_RECORDING && (wfront->cloak_value != old_cloak || d->time == FrameTime) )
newdemo_record_cloaking_wall(d->front_wallnum, d->back_wallnum, wfront->type, wfront->state, wfront->cloak_value, Segments[wfront->segnum].sides[wfront->sidenum].uvls[0].l, Segments[wfront->segnum].sides[wfront->sidenum].uvls[1].l, Segments[wfront->segnum].sides[wfront->sidenum].uvls[2].l, Segments[wfront->segnum].sides[wfront->sidenum].uvls[3].l);
return r;
}
static void do_decloaking_wall_frame(int cloaking_wall_num)
static cwresult do_decloaking_wall_frame(const bool initial, cloaking_wall &d, const cwframe front, const cwframe back)
{
cloaking_wall *d;
sbyte old_cloak; // for demo recording
if ( Newdemo_state==ND_STATE_PLAYBACK ) return;
d = &CloakingWalls[cloaking_wall_num];
wall *const wfront = vwallptr(d->front_wallnum);
wall *const wback = wallptr(d->back_wallnum);
old_cloak = wfront->cloak_value;
d->time += FrameTime;
if (d->time > CLOAKING_WALL_TIME) {
int i;
wfront->state = WALL_DOOR_CLOSED;
if (wback)
wback->state = WALL_DOOR_CLOSED;
for (i=0;i<4;i++) {
Segments[wfront->segnum].sides[wfront->sidenum].uvls[i].l = d->front_ls[i];
if (wback)
Segments[wback->segnum].sides[wback->sidenum].uvls[i].l = d->back_ls[i];
}
for (i=cloaking_wall_num;i<Num_cloaking_walls;i++)
CloakingWalls[i] = CloakingWalls[i+1];
Num_cloaking_walls--;
cwresult r(initial);
if (d.time > CLOAKING_WALL_TIME) {
back.w.state = WALL_DOOR_CLOSED;
front.w.state = WALL_DOOR_CLOSED;
copy_cloaking_wall_light_to_wall(back.uvls, front.uvls, d);
r.remove = true;
}
else if (d->time > CLOAKING_WALL_TIME/2) { //fading in
else if (d.time > CLOAKING_WALL_TIME/2) { //fading in
fix light_scale;
int i;
front.w.type = back.w.type = WALL_CLOSED;
wfront->type = wback->type = WALL_CLOSED;
light_scale = fixdiv(d->time-CLOAKING_WALL_TIME/2,CLOAKING_WALL_TIME/2);
for (i=0;i<4;i++) {
Segments[wfront->segnum].sides[wfront->sidenum].uvls[i].l = fixmul(d->front_ls[i],light_scale);
if (wback)
Segments[wback->segnum].sides[wback->sidenum].uvls[i].l = fixmul(d->back_ls[i],light_scale);
}
light_scale = fixdiv(d.time - CLOAKING_WALL_TIME / 2, CLOAKING_WALL_TIME / 2);
scale_cloaking_wall_light_to_wall(back.uvls, front.uvls, d, light_scale);
}
else { //cloaking in
wfront->cloak_value = ((CLOAKING_WALL_TIME/2 - d->time) * (GR_FADE_LEVELS-2)) / (CLOAKING_WALL_TIME/2);
wfront->type = WALL_CLOAKED;
if (wback) {
wback->cloak_value = wfront->cloak_value;
wback->type = WALL_CLOAKED;
const int8_t cloak_value = ((CLOAKING_WALL_TIME / 2 - d.time) * (GR_FADE_LEVELS - 2)) / (CLOAKING_WALL_TIME / 2);
if (front.w.cloak_value != cloak_value)
{
front.w.cloak_value = back.w.cloak_value = cloak_value;
r.record = true;
}
front.w.type = WALL_CLOAKED;
back.w.type = WALL_CLOAKED;
}
// check if the actual cloak_value changed in this frame to prevent redundant recordings and wasted bytes
if ( Newdemo_state == ND_STATE_RECORDING && (wfront->cloak_value != old_cloak || d->time == FrameTime) )
newdemo_record_cloaking_wall(d->front_wallnum, d->back_wallnum, wfront->type, wfront->state, wfront->cloak_value, Segments[wfront->segnum].sides[wfront->sidenum].uvls[0].l, Segments[wfront->segnum].sides[wfront->sidenum].uvls[1].l, Segments[wfront->segnum].sides[wfront->sidenum].uvls[2].l, Segments[wfront->segnum].sides[wfront->sidenum].uvls[3].l);
return r;
}
#endif
namespace dsx {
void wall_frame_process()
{
int i;
unsigned i;
for (i=0;i<Num_open_doors;i++) {
active_door *d;
@ -1297,20 +1270,39 @@ void wall_frame_process()
}
#if defined(DXX_BUILD_DESCENT_II)
if (Newdemo_state != ND_STATE_PLAYBACK)
for (i=0;i<Num_cloaking_walls;i++) {
cloaking_wall *d;
d = &CloakingWalls[i];
wall *const w = vwallptr(d->front_wallnum);
const auto &&wpback = wallptr(d->back_wallnum);
const cwframe front(*w);
const cwframe back = (wpback ? cwframe(*wpback) : front);
const bool initial = (d->time == 0);
d->time += FrameTime;
cwresult r;
if (w->state == WALL_DOOR_CLOAKING)
do_cloaking_wall_frame(i);
r = do_cloaking_wall_frame(initial, *d, front, back);
else if (w->state == WALL_DOOR_DECLOAKING)
do_decloaking_wall_frame(i);
#ifdef _DEBUG
r = do_decloaking_wall_frame(initial, *d, front, back);
else
{
Int3(); //unexpected wall state
#endif
continue;
}
if (r.record)
{
// check if the actual cloak_value changed in this frame to prevent redundant recordings and wasted bytes
if (Newdemo_state == ND_STATE_RECORDING && r.record)
newdemo_record_cloaking_wall(d->front_wallnum, d->back_wallnum, front.w.type, front.w.state, front.w.cloak_value, front.uvls[0].l, front.uvls[1].l, front.uvls[2].l, front.uvls[3].l);
}
if (r.remove)
{
const auto &&cr = partial_range(CloakingWalls, i, Num_cloaking_walls--);
std::move(std::next(cr.begin()), cr.end(), cr.begin());
}
}
#endif
}