Merge branch github/master into master
This commit is contained in:
commit
117d2f73e0
23
SConstruct
23
SConstruct
|
@ -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]))
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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) :
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue