diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/ai2.c d2x-rebirth_v0.58.1-src/main/ai2.c --- ../osrc/d2x-rebirth_v0.58.1-src/main/ai2.c 2013-08-02 14:47:33.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/ai2.c 2018-12-30 13:31:29.207531300 +0100 @@ -1803,6 +1803,7 @@ Players[Player_num].num_robots_level++; Players[Player_num].num_robots_total++; + Players[Player_num].num_robots_level_spawn++; return objp-Objects; } diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/cntrlcen.c d2x-rebirth_v0.58.1-src/main/cntrlcen.c --- ../osrc/d2x-rebirth_v0.58.1-src/main/cntrlcen.c 2013-08-03 01:40:27.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/cntrlcen.c 2018-12-31 01:02:56.373980600 +0100 @@ -57,6 +57,9 @@ int Control_center_next_fire_time; int Control_center_present; +int Final_target_object_num; +fix Final_target_strength; + void do_countdown_frame(); // ----------------------------------------------------------------------------- @@ -264,6 +267,8 @@ return; Dead_controlcen_object_num = objp-Objects; + + Final_target_object_num = -1; } fix64 Last_time_cc_vis_check = 0; @@ -456,6 +461,7 @@ Objects[cntrlcen_objnum].render_type = RT_NONE; Control_center_present = 0; } + Final_target_object_num = boss_objnum; } else if (cntrlcen_objnum != -1) { // Compute all gun positions. objp = &Objects[cntrlcen_objnum]; @@ -474,8 +480,9 @@ else { objp->shields = i2f(Reactor_strength); } - - } + Final_target_object_num = cntrlcen_objnum; + } else + Final_target_object_num = -1; // Say the control center has not yet been hit. Control_center_been_hit = 0; @@ -483,6 +490,9 @@ Control_center_next_fire_time = 0; Dead_controlcen_object_num = -1; + + Final_target_strength = Final_target_object_num == -1 ? 0 : + Objects[Final_target_object_num].shields; } void special_reactor_stuff(void) diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/cntrlcen.h d2x-rebirth_v0.58.1-src/main/cntrlcen.h --- ../osrc/d2x-rebirth_v0.58.1-src/main/cntrlcen.h 2013-08-03 12:46:14.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/cntrlcen.h 2018-12-30 14:52:39.381939200 +0100 @@ -112,4 +112,7 @@ extern int control_center_triggers_write(control_center_triggers *cct, PHYSFS_file *fp); +extern int Final_target_object_num; +extern fix Final_target_strength; + #endif /* _CNTRLCEN_H */ diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/collide.c d2x-rebirth_v0.58.1-src/main/collide.c --- ../osrc/d2x-rebirth_v0.58.1-src/main/collide.c 2013-04-22 12:36:14.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/collide.c 2019-01-23 19:36:12.386754300 +0100 @@ -1034,8 +1034,11 @@ ai_do_cloak_stuff(); } - if ( controlcen->shields >= 0 ) + if ( controlcen->shields >= 0 ) { controlcen->shields -= damage; + //if (Newdemo_state == ND_STATE_RECORDING) + // newdemo_record_final_target_shields(controlcen->shields, Final_target_strength); + } if ( (controlcen->shields < 0) && !(controlcen->flags&(OF_EXPLODING|OF_DESTROYED)) ) { @@ -1296,7 +1299,10 @@ robot->shields -= damage; // Do unspeakable hacks to make sure player doesn't die after killing boss. Or before, sort of. - if (Robot_info[robot->id].boss_flag) + if (Robot_info[robot->id].boss_flag) { + if (Newdemo_state == ND_STATE_RECORDING) + newdemo_record_final_target_shields(robot->shields, Final_target_strength); + if (PLAYING_BUILTIN_MISSION && Current_level_num == Last_level) if (robot->shields < 0) { @@ -1321,6 +1327,7 @@ do_final_boss_hacks(); } } + } if (robot->shields < 0) { #ifdef NETWORK @@ -1355,9 +1362,15 @@ Players[Player_num].num_kills_level++; Players[Player_num].num_kills_total++; + if (robot->matcen_creator) // spawned by matcen or dropped by robot? + Players[Player_num].num_kills_level_spawn++; + if (Newdemo_state == ND_STATE_RECORDING) + newdemo_record_num_kills(Players[Player_num].num_kills_level, Players[Player_num].num_kills_total, + Players[Player_num].num_kills_level_spawn); if (Robot_info[robot->id].boss_flag) { start_boss_death_sequence(robot); //do_controlcen_destroyed_stuff(NULL); + Final_target_object_num = -1; } else if (Robot_info[robot->id].death_roll) { start_robot_death_sequence(robot); //do_controlcen_destroyed_stuff(NULL); } else { diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/fireball.c d2x-rebirth_v0.58.1-src/main/fireball.c --- ../osrc/d2x-rebirth_v0.58.1-src/main/fireball.c 2013-07-18 12:33:35.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/fireball.c 2018-12-30 13:29:09.303074700 +0100 @@ -924,6 +924,8 @@ obj->ctype.ai_info.CURRENT_STATE = AIS_LOCK; obj->ctype.ai_info.GOAL_STATE = AIS_LOCK; obj->ctype.ai_info.REMOTE_OWNER = -1; + + obj->matcen_creator = ROBOT_DROP_MATCEN_NUM; } // At JasenW's request, robots which contain robots diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/fireball.h d2x-rebirth_v0.58.1-src/main/fireball.h --- ../osrc/d2x-rebirth_v0.58.1-src/main/fireball.h 2013-04-22 12:36:14.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/fireball.h 2018-12-30 13:28:06.911856500 +0100 @@ -26,6 +26,8 @@ #define ET_MULTI_START 1 //first part of multi-part explosion #define ET_MULTI_SECOND 2 //second part of multi-part explosion +#define ROBOT_DROP_MATCEN_NUM -2 + // data for exploding walls (such as hostage door) typedef struct expl_wall { int segnum,sidenum; diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/fuelcen.c d2x-rebirth_v0.58.1-src/main/fuelcen.c --- ../osrc/d2x-rebirth_v0.58.1-src/main/fuelcen.c 2013-07-18 12:33:35.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/fuelcen.c 2018-12-30 13:31:55.298352900 +0100 @@ -322,6 +322,7 @@ Players[Player_num].num_robots_level++; Players[Player_num].num_robots_total++; + Players[Player_num].num_robots_level_spawn++; objnum = obj_create(OBJ_ROBOT, object_id, segp-Segments, object_pos, &vmd_identity_matrix, Polygon_models[Robot_info[object_id].model_num].rad, diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/gamerend.c d2x-rebirth_v0.58.1-src/main/gamerend.c --- ../osrc/d2x-rebirth_v0.58.1-src/main/gamerend.c 2013-07-18 12:33:35.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/gamerend.c 2018-12-30 13:22:53.829880200 +0100 @@ -90,15 +90,8 @@ } #endif -void show_framerate() -{ - static int fps_count = 0, fps_rate = 0; +static int lower_text_y_pos() { int y = GHEIGHT; - static fix64 fps_time = 0; - - gr_set_curfont(GAME_FONT); - gr_set_fontcolor(BM_XRGB(0,31,0),-1); - if (PlayerCfg.CockpitMode[1] == CM_FULL_SCREEN) { if ((Game_mode & GM_MULTI) || (Newdemo_state == ND_STATE_PLAYBACK && Newdemo_game_mode & GM_MULTI)) y -= LINE_SPACING * 10; @@ -115,6 +108,16 @@ else y -= LINE_SPACING * 2; } + return y; +} + +void show_framerate() +{ + static int fps_count = 0, fps_rate = 0; + static fix64 fps_time = 0; + + gr_set_curfont(GAME_FONT); + gr_set_fontcolor(BM_XRGB(0,31,0),-1); fps_count++; if (timer_query() >= fps_time + F1_0) @@ -123,7 +126,20 @@ fps_count = 0; fps_time = timer_query(); } - gr_printf(SWIDTH-(GameArg.SysMaxFPS>999?FSPACX(43):FSPACX(37)),y,"FPS: %i",fps_rate); + gr_printf(SWIDTH-(GameArg.SysMaxFPS>999?FSPACX(43):FSPACX(37)),lower_text_y_pos(),"FPS: %i",fps_rate); +} + +void show_robot_kills() +{ + if ( ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP)) ) + return; + + gr_set_curfont(GAME_FONT); + gr_set_fontcolor(BM_XRGB(0,31,0),-1); + + gr_printf(FSPACX(1),lower_text_y_pos(),"Kills: %i+%i", + Players[Player_num].num_kills_level - Players[Player_num].num_kills_level_spawn, + Players[Player_num].num_kills_level_spawn); } #ifdef NETWORK @@ -371,6 +387,8 @@ if (GameCfg.FPSIndicator && PlayerCfg.CockpitMode[1] != CM_REAR_VIEW) show_framerate(); + show_robot_kills(); + if (Newdemo_state == ND_STATE_PLAYBACK) Game_mode = Newdemo_game_mode; diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/gamesave.c d2x-rebirth_v0.58.1-src/main/gamesave.c --- ../osrc/d2x-rebirth_v0.58.1-src/main/gamesave.c 2013-07-18 12:33:35.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/gamesave.c 2018-12-30 13:25:09.841084000 +0100 @@ -342,6 +342,7 @@ //reads one object of the given version from the given file void read_object(object *obj,PHYSFS_file *f,int version) { + memset(obj, 0, sizeof(*obj)); obj->type = PHYSFSX_readByte(f); obj->id = PHYSFSX_readByte(f); diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/gameseq.c d2x-rebirth_v0.58.1-src/main/gameseq.c --- ../osrc/d2x-rebirth_v0.58.1-src/main/gameseq.c 2013-06-10 23:55:26.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/gameseq.c 2018-12-30 22:09:39.000000000 +0100 @@ -274,8 +274,10 @@ Players[pnum].net_kills_total = 0; Players[pnum].num_kills_level = 0; Players[pnum].num_kills_total = 0; + Players[pnum].num_kills_level_spawn = 0; Players[pnum].num_robots_level = 0; Players[pnum].num_robots_total = 0; + Players[pnum].num_robots_level_spawn = 0; Players[pnum].KillGoalCount = 0; Players[pnum].hostages_rescued_total = 0; Players[pnum].hostages_level = 0; @@ -330,8 +332,14 @@ Players[Player_num].killer_objnum = -1; Players[Player_num].num_kills_level = 0; + Players[Player_num].num_kills_level_spawn = 0; + if (Newdemo_state == ND_STATE_RECORDING) + newdemo_record_num_kills(Players[Player_num].num_kills_level, Players[Player_num].num_kills_total, + Players[Player_num].num_kills_level_spawn); + Players[Player_num].num_robots_level = count_number_of_robots(); Players[Player_num].num_robots_total += Players[Player_num].num_robots_level; + Players[Player_num].num_robots_level_spawn = 0; Players[Player_num].hostages_level = count_number_of_hostages(); Players[Player_num].hostages_total += Players[Player_num].hostages_level; diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/gameseq.h d2x-rebirth_v0.58.1-src/main/gameseq.h --- ../osrc/d2x-rebirth_v0.58.1-src/main/gameseq.h 2013-04-22 12:36:14.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/gameseq.h 2018-12-30 22:11:55.000000000 +0100 @@ -106,4 +106,6 @@ void bash_to_shield(int, char *); +int count_number_of_robots(); + #endif /* _GAMESEQ_H */ diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/gauges.c d2x-rebirth_v0.58.1-src/main/gauges.c --- ../osrc/d2x-rebirth_v0.58.1-src/main/gauges.c 2013-07-18 12:33:35.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/gauges.c 2019-01-23 19:36:59.617074400 +0100 @@ -1412,6 +1412,31 @@ } +void show_final_target_shields() { + fix shields = Newdemo_state > ND_STATE_RECORDING ? + Newdemo_final_target_shields : + Final_target_object_num == -1 || Objects[Final_target_object_num].type != OBJ_ROBOT ? -1 : + Objects[Final_target_object_num].shields; + if (shields < 0 || !Final_target_strength) + return; + int width = shields / (Final_target_strength / 32); + if (width >= 32) // don't show until hit + return; + int x = PlayerCfg.CockpitMode[1] == CM_FULL_COCKPIT ? FSPACX(12) : FSPACX(1); + int y = PlayerCfg.CockpitMode[1] == CM_FULL_COCKPIT ? FSPACY(12) : + PlayerCfg.CockpitMode[1] == CM_STATUS_BAR ? FSPACY(1) : FSPACY(24); + /* + gr_setcolor(BM_XRGB(5,0,0)); + gr_rect(x,y,x+FSPACX(32),y+FSPACY(4)); + gr_setcolor(BM_XRGB(20,0,0)); + gr_rect(x,y,x+FSPACX(width),y+FSPACY(4)); + */ + gr_set_curfont(GAME_FONT); + gr_set_fontcolor(BM_XRGB(0,31,0),-1); + + gr_printf(x, y, "Boss: %i", (shields + 32767) >> 16); +} + void sb_show_lives() { int x,y; @@ -2758,6 +2783,8 @@ gr_set_fontcolor(BM_XRGB(0,31,0),-1 ); gr_string(0x8000,GHEIGHT-LINE_SPACING,TXT_REAR_VIEW); } + + show_final_target_shields(); } //print out some player statistics diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/newdemo.c d2x-rebirth_v0.58.1-src/main/newdemo.c --- ../osrc/d2x-rebirth_v0.58.1-src/main/newdemo.c 2013-06-30 20:41:27.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/newdemo.c 2018-12-31 01:04:08.554501200 +0100 @@ -140,6 +140,8 @@ #define ND_EVENT_SECRET_THINGY 48 // 0/1 = secret exit functional/non-functional #define ND_EVENT_LINK_SOUND_TO_OBJ 49 // record digi_link_sound_to_object3 #define ND_EVENT_KILL_SOUND_TO_OBJ 50 // record digi_kill_sound_linked_to_object +#define ND_EVENT_NUM_KILLS 51 // sized, with old level, old total, new level, new total +#define ND_EVENT_FINAL_TARGET_SHIELDS 52 // sized, with old shields, new shields, old strength, new strength #define NORMAL_PLAYBACK 0 @@ -149,6 +151,7 @@ #define DEMO_VERSION 15 // last D1 version was 13 #define DEMO_GAME_TYPE 3 // 1 was shareware, 2 registered +#define DEMO_HAS_SIZED 4 // added to game-type to indicate sized extensions #define DEMO_FILENAME DEMO_DIR "tmpdemo.dem" @@ -167,6 +170,7 @@ int Newdemo_num_written; ubyte DemoDoRight=0,DemoDoLeft=0; object DemoRightExtra,DemoLeftExtra; +fix Newdemo_final_target_shields=-1; // local var used for swapping endian demos static int swap_endian = 0; @@ -204,6 +208,11 @@ static fix nd_record_v_homing_distance = -1; static int nd_record_v_primary_ammo = -1; static int nd_record_v_secondary_ammo = -1; +static int nd_record_v_num_kills_level = -1; +static int nd_record_v_num_kills_total = -1; +static int nd_record_v_num_kills_level_spawn = -1; +static int nd_record_v_final_target_shields = -1; +static int nd_record_v_final_target_strength = -1; void newdemo_record_oneframeevent_update(); extern int digi_link_sound_to_object3( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance, int loop_start, int loop_end ); @@ -847,7 +856,7 @@ stop_time(); nd_write_byte(ND_EVENT_START_DEMO); nd_write_byte(DEMO_VERSION); - nd_write_byte(DEMO_GAME_TYPE); + nd_write_byte(DEMO_GAME_TYPE | DEMO_HAS_SIZED); nd_write_fix(0); // NOTE: This is supposed to write GameTime (in fix). Since our GameTime64 is fix64 and the demos do not NEED this time actually, just write 0. #ifdef NETWORK @@ -888,6 +897,11 @@ nd_record_v_homing_distance = -1; nd_record_v_primary_ammo = -1; nd_record_v_secondary_ammo = -1; + nd_record_v_num_kills_level = -1; + nd_record_v_num_kills_total = -1; + nd_record_v_num_kills_level_spawn = -1; + nd_record_v_final_target_shields = -1; + nd_record_v_final_target_strength = -1; for (i = 0; i < MAX_PRIMARY_WEAPONS; i++) nd_write_short((short)Players[Player_num].primary_ammo[i]); @@ -912,6 +926,11 @@ nd_write_byte((sbyte)Secondary_weapon); nd_record_v_start_frame = nd_record_v_frame_number = 0; nd_record_v_juststarted=1; + newdemo_record_num_kills(Players[Player_num].num_kills_level, Players[Player_num].num_kills_total, + Players[Player_num].num_kills_level_spawn); + if (Final_target_object_num != -1) + newdemo_record_final_target_shields(Objects[Final_target_object_num].shields, + Final_target_strength); newdemo_set_new_level(Current_level_num); newdemo_record_oneframeevent_update(); start_time(); @@ -1453,6 +1472,43 @@ start_time(); } +void newdemo_record_num_kills(int num_kills_level, int num_kills_total, int num_kills_level_spawn) +{ + stop_time(); + nd_write_byte(ND_EVENT_NUM_KILLS); + nd_write_short(6 * 4); + nd_write_int(nd_record_v_num_kills_level < 0 ? num_kills_level : nd_record_v_num_kills_level); + nd_write_int(nd_record_v_num_kills_total < 0 ? num_kills_total : nd_record_v_num_kills_total); + nd_write_int(num_kills_level); + nd_write_int(num_kills_total); + nd_record_v_num_kills_level = num_kills_level; + nd_record_v_num_kills_total = num_kills_total; + + nd_write_int(nd_record_v_num_kills_level_spawn < 0 ? num_kills_level_spawn : nd_record_v_num_kills_level_spawn); + nd_write_int(num_kills_level_spawn); + nd_record_v_num_kills_level_spawn = num_kills_level_spawn; + + start_time(); +} + +void newdemo_record_final_target_shields(fix shields, fix strength) +{ + if (nd_record_v_final_target_shields == shields && + nd_record_v_final_target_strength == strength) + return; + stop_time(); + nd_write_byte(ND_EVENT_FINAL_TARGET_SHIELDS); + nd_write_short(2 * 4); + nd_write_fix(nd_record_v_final_target_shields == -1 ? shields : nd_record_v_final_target_shields); + nd_write_fix(shields); + nd_write_fix(nd_record_v_final_target_strength == -1 ? strength : nd_record_v_final_target_strength); + nd_write_fix(strength); + nd_record_v_final_target_shields = shields; + nd_record_v_final_target_strength = strength; + start_time(); +} + + void newdemo_set_new_level(int level_num) { int i; @@ -1535,6 +1591,7 @@ if (purpose == PURPOSE_REWRITE) nd_write_byte(version); nd_read_byte(&game_type); + game_type &= ~DEMO_HAS_SIZED; if (purpose == PURPOSE_REWRITE) nd_write_byte(game_type); if (game_type < DEMO_GAME_TYPE) { @@ -2738,6 +2795,78 @@ break; } + case ND_EVENT_NUM_KILLS: { + int old_level, old_total, new_level, new_total, old_spawn, new_spawn; + short size; + + nd_read_short(&size); + nd_read_int(&old_level); + nd_read_int(&old_total); + nd_read_int(&new_level); + nd_read_int(&new_total); + if (size >= 6 * 4) + { + nd_read_int(&old_spawn); + nd_read_int(&new_spawn); + } + else + { + old_spawn = new_spawn = 0; + } + if (rewrite) + { + nd_write_short(size); + nd_write_int(old_level); + nd_write_int(old_total); + nd_write_int(new_level); + nd_write_int(new_total); + if (size >= 6 * 4) + { + nd_write_int(old_spawn); + nd_write_int(new_spawn); + } + break; + } + if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { + Players[Player_num].num_kills_level = old_level; + Players[Player_num].num_kills_total = old_total; + Players[Player_num].num_kills_level_spawn = old_spawn; + } else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { + Players[Player_num].num_kills_level = new_level; + Players[Player_num].num_kills_total = new_total; + Players[Player_num].num_kills_level_spawn = new_spawn; + } + break; + } + + case ND_EVENT_FINAL_TARGET_SHIELDS: { + fix old_shields, new_shields, old_strength, new_strength; + short size; + + nd_read_short(&size); + nd_read_fix(&old_shields); + nd_read_fix(&new_shields); + nd_read_fix(&old_strength); + nd_read_fix(&new_strength); + if (rewrite) + { + nd_write_short(4 * 4); + nd_write_fix(old_shields); + nd_write_fix(new_shields); + nd_write_fix(old_strength); + nd_write_fix(new_strength); + break; + } + if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { + Newdemo_final_target_shields = old_shields; + Final_target_strength = old_strength; + } else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { + Newdemo_final_target_shields = new_shields; + Final_target_strength = new_strength; + } + break; + } + case ND_EVENT_NEW_LEVEL: { sbyte new_level, old_level, loaded_level; @@ -2841,9 +2970,15 @@ break; } - default: + default: { + short size; + sbyte x; + nd_read_short(&size); + while (size--) + nd_read_byte(&x); Int3(); } + } } // Now set up cockpit and views according to what we read out. Note that the demo itself cannot determinate the right views since it does not use a good portion of the real game code. @@ -3594,6 +3729,8 @@ nd_playback_v_dead = nd_playback_v_rear = nd_playback_v_guided = 0; PlayerCfg.Cockpit3DView[0] = PlayerCfg.Cockpit3DView[1] = CV_NONE; //turn off 3d views on cockpit DemoDoLeft = DemoDoRight = 0; + Newdemo_final_target_shields = -1; + Final_target_strength = 0; HUD_clear_messages(); if (!Game_wind) hide_menus(); diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/newdemo.h d2x-rebirth_v0.58.1-src/main/newdemo.h --- ../osrc/d2x-rebirth_v0.58.1-src/main/newdemo.h 2013-07-18 12:33:36.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/newdemo.h 2018-12-31 00:32:29.663267000 +0100 @@ -52,6 +52,8 @@ struct morph_data; +extern fix Newdemo_final_target_shields; + // Functions called during recording process... extern void newdemo_record_start_demo(); extern void newdemo_record_start_frame(fix frame_time ); @@ -84,6 +86,8 @@ extern void newdemo_record_wall_set_tmap_num2(short seg,ubyte side,short cseg,ubyte cside,short tmap); extern void newdemo_record_multi_cloak(int pnum); extern void newdemo_record_multi_decloak(int pnum); +extern void newdemo_record_num_kills(int num_kills_level, int num_kills_total, int num_kills_level_spawn); +extern void newdemo_record_final_target_shields(fix shields, fix strength); extern void newdemo_set_new_level(int level_num); extern void newdemo_record_restore_rearview(void); diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/player.h d2x-rebirth_v0.58.1-src/main/player.h --- ../osrc/d2x-rebirth_v0.58.1-src/main/player.h 2013-07-18 12:33:36.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/player.h 2018-12-30 13:23:30.712827000 +0100 @@ -122,6 +122,8 @@ fix homing_object_dist; // Distance of nearest homing object. sbyte hours_level; // Hours played (since time_total can only go up to 9 hours) sbyte hours_total; // Hours played (since time_total can only go up to 9 hours) + short num_kills_level_spawn; // Number of kills this level of spawned robots + short num_robots_level_spawn; // Number of spawned robots this level } __pack__ player; // Same as above but structure how Savegames expect diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/state.c d2x-rebirth_v0.58.1-src/main/state.c --- ../osrc/d2x-rebirth_v0.58.1-src/main/state.c 2013-08-03 13:30:13.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/state.c 2018-12-30 22:28:57.009538700 +0100 @@ -1238,6 +1238,7 @@ fix64 old_gametime = GameTime64; short TempTmapNum[MAX_SEGMENTS][MAX_SIDES_PER_SEGMENT]; short TempTmapNum2[MAX_SEGMENTS][MAX_SIDES_PER_SEGMENT]; + int orig_robot_count = 0; #ifndef NDEBUG if (GameArg.SysUsePlayersDir && strncmp(filename, "Players/", 8)) @@ -1339,6 +1340,7 @@ { StartNewLevelSub(current_level, 1, secret_restore); + orig_robot_count = count_number_of_robots(); if (secret_restore) { player dummy_player; @@ -1716,6 +1718,27 @@ window_set_visible(Game_wind, 1); reset_time(); + // infer spawned robot kills + int cur_robot_spawn_count = 0, cur_robot_count = 0; + for (i = 0; i <= Highest_object_index; i++) + if (Objects[i].type == OBJ_ROBOT && + !(Objects[i].flags & (OF_EXPLODING | OF_SHOULD_BE_DEAD | OF_DESTROYED))) { + if (Objects[i].matcen_creator) + cur_robot_spawn_count++; + cur_robot_count++; + } + int non_spawn_kills = orig_robot_count - (cur_robot_count - cur_robot_spawn_count); + Players[Player_num].num_kills_level_spawn = Players[Player_num].num_kills_level - non_spawn_kills; + Players[Player_num].num_robots_level_spawn = Players[Player_num].num_kills_level_spawn + cur_robot_spawn_count; + + // controlcen / boss already dead? + if (Final_target_object_num != -1 && + ((Objects[Final_target_object_num].type != OBJ_ROBOT && + Objects[Final_target_object_num].type != OBJ_CNTRLCEN) || + (Objects[Final_target_object_num].flags & + (OF_EXPLODING | OF_SHOULD_BE_DEAD | OF_DESTROYED)))) + Final_target_object_num = -1; + return 1; } diff -ur ../osrc/d2x-rebirth_v0.58.1-src/main/vers_id.h d2x-rebirth_v0.58.1-src/main/vers_id.h --- ../osrc/d2x-rebirth_v0.58.1-src/main/vers_id.h 2013-07-18 12:33:36.000000000 +0200 +++ d2x-rebirth_v0.58.1-src/main/vers_id.h 2019-01-23 19:47:24.583125900 +0100 @@ -9,9 +9,10 @@ #define D2XMAJOR __stringize(DXX_VERSION_MAJORi) #define D2XMINOR __stringize(DXX_VERSION_MINORi) #define D2XMICRO __stringize(DXX_VERSION_MICROi) +#define D2XREVISION "-ar2" #define BASED_VERSION "Full Version v1.2" -#define VERSION D2XMAJOR "." D2XMINOR "." D2XMICRO +#define VERSION D2XMAJOR "." D2XMINOR "." D2XMICRO D2XREVISION #define DESCENT_VERSION g_descent_version extern const char g_descent_version[40];