Compare commits

...
Author SHA1 Message Date
Fabian Woltermann 4b2c2d6ef2 Fix for cf_create_directory (#687)
Changes cf_create_directory so that it can actually do what its comment says it does, namely create directories recursively.
2016-07-24 09:24:59 -07:00
m!m 3e1cd6c02f Merge pull request #686 from The-E/screenshot_fix
Fixes issue with the screenshot code where the screenshot directory w…
2016-07-23 12:05:07 +02:00
Fabian 72c2d7af38 Fixes issue with the screenshot code where the screenshot directory was not created if necessary. 2016-07-23 10:00:38 +02:00
Fabian Woltermann 959226e087 Merge pull request #683 from MageKing17/cleanup/weapon-objects
Various cleanup related to weapon objects.
2016-07-22 14:13:42 +02:00
MageKing17 92e4b5b259 Merge pull request #684 from DahBlount/share_fire_dir_update
Avoid setting flags when using the share fire direction flag
2016-07-21 19:30:39 -07:00
DahBlount 8201f0ef1c Avoid setting flags when using the share fire direction flag
Originally, "share fire dir" forced the "salvo mode" flag. This
interfered with the "use multiple guns" flag. In order to avoid this, I
instead made "share fire dir" if either "salvo mode" or "use multiple
guns" is not found, as those are the only two flags that, coupled with
"share fire dir" give the desired results.
2016-07-21 17:44:08 -06:00
MageKing17 df1d84fe6e Greatly simplify scoring for weapon kills.
Bombs can give points for being shot down. This was being handled by a full-blown pair of damage_ship/damage_ship_id arrays, just like ships have for scoring purposes. This is ridiculous overkill when most bombs are shot down with a single pull of the trigger and means we were storing a couple hundred bytes of data that would be completely unused for the vast majority of projectiles. Now, whoever shoots down a bomb gets the points for it; period. Simple, and we can remove all scoring data from the weapon struct.
2016-07-21 14:44:24 -07:00
MageKing17 9b2e83ed3b Minor cleanup of weapon/weapon collision code.
Lots of references to Weapons[A->instance] and Weapons[B->instance], despite having created pointers for them earlier in the function. Also, I have no idea what was up with the override conditional.
2016-07-21 14:44:24 -07:00
MageKing17 f7591078b9 Change collisionInfo from an mc_info object to an mc_info* pointer.
This seems preferable to storing an entire mc_info object on every weapon, when the vast majority of projectiles (by the very nature of the fact that they still exist) won't have collided with anything.

On the other hand, I'm not wild about allocating and freeing memory every time a weapon collides with a ship or debris. If anyone has a better solution, I'm all ears.
2016-07-21 14:44:24 -07:00
Fabian Woltermann 9a6e939f3d Merge pull request #682 from MageKing17/cleanup/gun-convergence
Remove redundant code branch in gun convergence code.
2016-07-21 22:53:32 +02:00
MageKing17 eb6b77dba0 Remove redundant code branch in gun convergence code.
"If a or b else a" should never ever execute the "else a" branch; this appears to be an artifact left over from Wanderer's reorganization of the autoaim/convergence code in 7bb10d8, before which standard convergence and automatic convergence were handled in separate conditionals.
2016-07-21 12:28:25 -07:00
12 changed files with 97 additions and 325 deletions

No files matched your search

+26 -8
View File
@@ -86,7 +86,7 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
{ CF_TYPE_CBANIMS, "data" DIR_SEPARATOR_STR "cbanims", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA },
{ CF_TYPE_INTEL_ANIMS, "data" DIR_SEPARATOR_STR "intelanims", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA },
{ CF_TYPE_SCRIPTS, "data" DIR_SEPARATOR_STR "scripts", ".lua .lc", CF_TYPE_DATA },
{ CF_TYPE_FICTION, "data" DIR_SEPARATOR_STR "fiction", ".txt", CF_TYPE_DATA },
{ CF_TYPE_FICTION, "data" DIR_SEPARATOR_STR "fiction", ".txt", CF_TYPE_DATA },
};
@@ -593,6 +593,28 @@ int cf_rename(const char *old_name, const char *name, int dir_type)
}
// This takes a path (e.g. "C:\Games\FreeSpace2\Lots\More\Directories") and creates it in its entirety.
// Do note that this requires the path to have normalized directory separators as defined by DIR_SEPARATOR_CHAR
static void mkdir_recursive(const char *path) {
size_t pre = 0, pos;
SCP_string tmp(path);
SCP_string dir;
if (tmp[tmp.size() - 1] != DIR_SEPARATOR_CHAR) {
// force trailing / so we can handle everything in loop
tmp += DIR_SEPARATOR_CHAR;
}
while ((pos = tmp.find_first_of(DIR_SEPARATOR_CHAR, pre)) != std::string::npos) {
dir = tmp.substr(0, pos++);
pre = pos;
if (dir.size() == 0) continue; // if leading / first time is 0 length
_mkdir(dir.c_str());
}
}
// Creates the directory path if it doesn't exist. Even creates all its
// parent paths.
void cf_create_directory( int dir_type )
@@ -601,7 +623,7 @@ void cf_create_directory( int dir_type )
int dir_tree[CF_MAX_PATH_TYPES];
char longname[MAX_PATH_LEN];
Assert( CF_TYPE_SPECIFIED(dir_type) );
Assertion( CF_TYPE_SPECIFIED(dir_type), "Invalid dir_type passed to cf_create_directory." );
int current_dir = dir_type;
@@ -618,13 +640,9 @@ void cf_create_directory( int dir_type )
for (i=num_dirs-1; i>=0; i-- ) {
cf_create_default_path_string( longname, sizeof(longname)-1, dir_tree[i], NULL );
if ( _mkdir(longname)==0 ) {
mprintf(( "CFILE: Created new directory '%s'\n", longname ));
}
mprintf(( "CFILE: Creating new directory '%s'\n", longname ));
mkdir_recursive(longname);
}
}
+1
View File
@@ -128,6 +128,7 @@ char *cf_add_ext(const char *filename, const char *ext);
// return CF_TYPE (directory location type) of a CFILE you called cfopen() successfully on.
int cf_get_dir_type(CFILE *cfile);
// Opens the file. If no path is given, use the extension to look into the
// default path. If mode is NULL, delete the file.
CFILE *_cfopen(const char* source_file, int line, const char *filename, const char *mode,
+2 -2
View File
@@ -779,8 +779,8 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
}
weapon *wp = &Weapons[other_obj->instance];
wp->collisionOccured = true;
memcpy(&wp->collisionInfo, &mc, sizeof(mc_info));
wp->collisionInfo = new mc_info; // The weapon will free this memory later
memcpy(wp->collisionInfo, &mc, sizeof(mc_info));
return mc.num_hits;
}
+2
View File
@@ -362,6 +362,8 @@ void gr_opengl_print_screen(const char *filename)
// save to a "screenshots" directory and tack on the filename
snprintf(tmp, MAX_PATH_LEN-1, "screenshots/%s.tga", filename);
_mkdir(os_get_config_path("screenshots").c_str());
FILE *fout = fopen(os_get_config_path(tmp).c_str(), "wb");
+2 -2
View File
@@ -410,8 +410,8 @@ int ship_weapon_check_collision(object *ship_objp, object *weapon_objp, float ti
if ( valid_hit_occurred )
{
wp->collisionOccured = true;
memcpy(&wp->collisionInfo, &mc, sizeof(mc_info));
wp->collisionInfo = new mc_info; // The weapon will free this memory later
memcpy(wp->collisionInfo, &mc, sizeof(mc_info));
Script_system.SetHookObjects(4, "Ship", ship_objp, "Weapon", weapon_objp, "Self",ship_objp, "Object", weapon_objp);
bool ship_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, ship_objp);
+24 -20
View File
@@ -102,10 +102,10 @@ int collide_weapon_weapon( obj_pair * pair )
if (wipA->weapon_hitpoints > 0) {
if (wipB->weapon_hitpoints > 0) { // Two bombs collide, detonate both.
if ((wipA->wi_flags & WIF_BOMB) && (wipB->wi_flags & WIF_BOMB)) {
Weapons[A->instance].lifeleft = 0.01f;
Weapons[B->instance].lifeleft = 0.01f;
Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
wpA->lifeleft = 0.01f;
wpB->lifeleft = 0.01f;
wpA->weapon_flags |= WF_DESTROYED_BY_WEAPON;
wpB->weapon_flags |= WF_DESTROYED_BY_WEAPON;
} else {
A->hull_strength -= bDamage;
B->hull_strength -= aDamage;
@@ -120,46 +120,50 @@ int collide_weapon_weapon( obj_pair * pair )
}
if (A->hull_strength < 0.0f) {
Weapons[A->instance].lifeleft = 0.01f;
Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
wpA->lifeleft = 0.01f;
wpA->weapon_flags |= WF_DESTROYED_BY_WEAPON;
}
if (B->hull_strength < 0.0f) {
Weapons[B->instance].lifeleft = 0.01f;
Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
wpB->lifeleft = 0.01f;
wpB->weapon_flags |= WF_DESTROYED_BY_WEAPON;
}
}
} else {
A->hull_strength -= bDamage;
Weapons[B->instance].lifeleft = 0.01f;
Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
wpB->lifeleft = 0.01f;
wpB->weapon_flags |= WF_DESTROYED_BY_WEAPON;
if (A->hull_strength < 0.0f) {
Weapons[A->instance].lifeleft = 0.01f;
Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
wpA->lifeleft = 0.01f;
wpA->weapon_flags |= WF_DESTROYED_BY_WEAPON;
}
}
} else if (wipB->weapon_hitpoints > 0) {
B->hull_strength -= aDamage;
Weapons[A->instance].lifeleft = 0.01f;
Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
wpA->lifeleft = 0.01f;
wpA->weapon_flags |= WF_DESTROYED_BY_WEAPON;
if (B->hull_strength < 0.0f) {
Weapons[B->instance].lifeleft = 0.01f;
Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
wpB->lifeleft = 0.01f;
wpB->weapon_flags |= WF_DESTROYED_BY_WEAPON;
}
}
// single player and multiplayer masters evaluate the scoring and kill stuff
if (!MULTIPLAYER_CLIENT) {
//Save damage for bomb so we can do scoring once it's destroyed. -Halleck
// If bomb was destroyed, do scoring
if (wipA->wi_flags & WIF_BOMB) {
scoring_add_damage_to_weapon(A, B, wipB->damage);
//Update stats. -Halleck
scoring_eval_hit(A, B, 0);
if (wpA->weapon_flags & WF_DESTROYED_BY_WEAPON) {
scoring_eval_kill_on_weapon(A, B);
}
}
if (wipB->wi_flags & WIF_BOMB) {
scoring_add_damage_to_weapon(B, A, wipA->damage);
//Update stats. -Halleck
scoring_eval_hit(B, A, 0);
if (wpB->weapon_flags & WF_DESTROYED_BY_WEAPON) {
scoring_eval_kill_on_weapon(B, A);
}
}
}
}
@@ -169,7 +173,7 @@ int collide_weapon_weapon( obj_pair * pair )
Script_system.SetHookObjects(4, "Weapon", A, "WeaponB", B, "Self",A, "Object", B);
Script_system.RunCondition(CHA_COLLIDEWEAPON, '\0', NULL, A, wpA->weapon_info_index);
}
if((b_override && !a_override) || (!b_override && !a_override))
else
{
//Should be reversed
Script_system.SetHookObjects(4, "Weapon", B, "WeaponB", A, "Self",B, "Object", A);
+2 -2
View File
@@ -10966,8 +10966,8 @@ ADE_FUNC(getCollisionInformation, l_Weapon, NULL, "Returns the collision informa
weapon *wp = &Weapons[oh->objp->instance];
if (wp->collisionOccured)
return ade_set_args(L, "o", l_ColInfo.Set(mc_info_h(new mc_info(wp->collisionInfo))));
if (wp->collisionInfo != nullptr)
return ade_set_args(L, "o", l_ColInfo.Set(mc_info_h(new mc_info(*(wp->collisionInfo)))));
else
return ade_set_args(L, "o", l_ColInfo.Set(mc_info_h()));
}
+3 -22
View File
@@ -6471,10 +6471,10 @@ int subsys_set(int objnum, int ignore_subsys_info)
Warning (LOCATION, "\"fixed firingpoint\" flag used with turret which has less weapons defined for it than it has firingpoints\nsubsystem '%s' on ship type '%s'.\nsome of the firingpoints will be left unused\n", model_system->subobj_name, sinfo->name );
}
if ((ship_system->system_info->flags2 & MSS_FLAG2_SHARE_FIRE_DIRECTION) && !(ship_system->system_info->flags & MSS_FLAG_TURRET_SALVO))
if ((ship_system->system_info->flags2 & MSS_FLAG2_SHARE_FIRE_DIRECTION) && (!(ship_system->system_info->flags & MSS_FLAG_TURRET_SALVO) || !(ship_system->system_info->flags & MSS_FLAG_USE_MULTIPLE_GUNS)))
{
Warning(LOCATION, "\"share fire direction\" flag used with turret which does not have the \"salvo mode\" flag set\nsubsystem '%s' on ship type '%s'.\nsetting the \"salvo mode\" flag\n", model_system->subobj_name, sinfo->name);
ship_system->system_info->flags |= MSS_FLAG_TURRET_SALVO;
Warning(LOCATION, "\"share fire direction\" flag used with turret which does not have the \"salvo mode\" or \"use multiple guns\" flag set\nsubsystem '%s' on ship type '%s'.\n\"share fire direction\" flag is ignored\n", model_system->subobj_name, sinfo->name);
ship_system->system_info->flags &= (~MSS_FLAG2_SHARE_FIRE_DIRECTION);
}
for (k=0; k<ship_system->weapons.num_secondary_banks; k++) {
@@ -11017,25 +11017,6 @@ int ship_fire_primary(object * obj, int stream_weapons, int force)
vm_vec_add2(&target_vec, &obj->pos);
vm_vec_sub(&firing_vec, &target_vec, &firing_pos);
// set orientation
vm_vector_2_matrix(&firing_orient, &firing_vec, NULL, NULL);
} else if (sip->aiming_flags & AIM_FLAG_STD_CONVERGENCE) {
// fixed distance convergence
vec3d target_vec, firing_vec, convergence_offset;
// make sure vector is of the set length
vm_vec_copy_normalize(&target_vec, &player_forward_vec);
vm_vec_scale(&target_vec, sip->convergence_distance);
// if there is convergence offset then make use of it)
if (sip->aiming_flags & AIM_FLAG_CONVERGENCE_OFFSET) {
vm_vec_unrotate(&convergence_offset, &sip->convergence_offset, &obj->orient);
vm_vec_add2(&target_vec, &convergence_offset);
}
vm_vec_add2(&target_vec, &obj->pos);
vm_vec_sub(&firing_vec, &target_vec, &firing_pos);
// set orientation
vm_vector_2_matrix(&firing_orient, &firing_vec, NULL, NULL);
} else if (sip->flags2 & SIF2_GUN_CONVERGENCE) {
+28 -245
View File
@@ -856,83 +856,38 @@ int scoring_eval_kill(object *ship_objp)
//evaluate a kill on a weapon, right now this is only called on bombs. -Halleck
int scoring_eval_kill_on_weapon(object *weapon_obj, object *other_obj) {
float max_damage_pct; // the pct% of total damage the max damage object did
int max_damage_index; // the index into the dying ship's damage_ship[] array corresponding the greatest amount of damage
int killer_sig; // signature of the guy getting credit for the kill (or -1 if none)
int idx,net_player_num;
int net_player_num;
player *plr; // pointer to a player struct if it was a player who got the kill
net_player *net_plr = NULL;
net_player *dead_plr = NULL;
float scoring_scale_by_damage = 1; // percentage to scale the killer's score by if we score based on the amount of damage caused
int kill_score;
weapon *dead_wp; // the weapon that was killed
weapon_info *dead_wip; // info on the weapon that was killed
if((weapon_obj->instance < 0) || (weapon_obj->instance >= MAX_WEAPONS)){
return -1;
}
dead_wp = &Weapons[weapon_obj->instance]; //assign the dead weapon
dead_wip = &Weapon_info[dead_wp->weapon_info_index];
// multiplayer clients bail here
if(MULTIPLAYER_CLIENT){
return -1;
}
// we don't evaluate kills on anything except weapons
if(weapon_obj->type != OBJ_WEAPON){
return -1;
// also make sure there was a killer, and that it was a ship
if((weapon_obj->type != OBJ_WEAPON) || (weapon_obj->instance < 0) || (weapon_obj->instance >= MAX_WEAPONS)
|| (other_obj == nullptr) || (other_obj->type != OBJ_WEAPON) || (other_obj->instance < 0) || (other_obj->instance >= MAX_WEAPONS)
|| (other_obj->parent == -1) || (Objects[other_obj->parent].type != OBJ_SHIP)) {
return -1;
}
weapon *dead_wp = &Weapons[weapon_obj->instance]; // the weapon that was killed
weapon_info *dead_wip = &Weapon_info[dead_wp->weapon_info_index]; // info on the weapon that was killed
// we don't evaluate kills on anything except bombs, currently. -Halleck
if(!(dead_wip->wi_flags & WIF_BOMB)) {
return -1;
}
// clear out invalid damager ships
for(idx=0; idx<MAX_DAMAGE_SLOTS; idx++){
if((dead_wp->damage_ship_id[idx] >= 0) && (ship_get_by_signature(dead_wp->damage_ship_id[idx]) < 0)){
dead_wp->damage_ship[idx] = 0.0f;
dead_wp->damage_ship_id[idx] = -1;
}
}
// determine which object did the most damage to the dying object, and how much damage that was
max_damage_index = -1;
for(idx=0;idx<MAX_DAMAGE_SLOTS;idx++){
// bogus ship
if(dead_wp->damage_ship_id[idx] < 0){
continue;
}
// if this slot did more damage then the next highest slot
if((max_damage_index == -1) || (dead_wp->damage_ship[idx] > dead_wp->damage_ship[max_damage_index])){
max_damage_index = idx;
}
}
// doh
if((max_damage_index < 0) || (max_damage_index >= MAX_DAMAGE_SLOTS)){
return -1;
}
// the pct of total damage applied to this ship
max_damage_pct = dead_wp->damage_ship[max_damage_index] / dead_wp->total_damage_received;
CLAMP(max_damage_pct, 0.0f, 1.0f);
// only evaluate if the max damage % is high enough to record a kill and it was done by a valid object
if((max_damage_pct >= Kill_percentage) && (dead_wp->damage_ship_id[max_damage_index] >= 0)){
// set killer_sig for this ship to the signature of the guy who gets credit for the kill
killer_sig = dead_wp->damage_ship_id[max_damage_index];
// set the scale value if we only award 100% score for 100% damage
if (The_mission.ai_profile->flags & AIPF_KILL_SCORING_SCALES_WITH_DAMAGE) {
scoring_scale_by_damage = max_damage_pct;
}
// set killer_sig for this weapon to the signature of the guy who gets credit for the kill
killer_sig = Objects[other_obj->parent].signature;
// only evaluate if the kill was done by a valid object
if(killer_sig >= 0) {
// null this out for now
plr = NULL;
net_plr = NULL;
@@ -950,22 +905,16 @@ int scoring_eval_kill_on_weapon(object *weapon_obj, object *other_obj) {
if(Objects[Player->objnum].signature == killer_sig){
plr = Player;
}
}
}
// if we found a valid player, evaluate some kill details
if(plr != NULL){
//int si_index;
// bogus
if((plr->objnum < 0) || (plr->objnum >= MAX_OBJECTS)){
return -1;
}
}
// get the ship info index of the ship type of this kill. we need to take ship
// copies into account here.
//si_index = dead_wp->weapon_info_index;
// if he killed a guy on his own team increment his bonehead kills
// if he killed a bomb on his own team increment his bonehead kills
if((Ships[Objects[plr->objnum].instance].team == dead_wp->team) && !MULTI_DOGFIGHT ){
if (!(The_mission.flags & MISSION_FLAG_NO_TRAITOR)) {
plr->stats.m_bonehead_kills++;
@@ -984,15 +933,15 @@ int scoring_eval_kill_on_weapon(object *weapon_obj, object *other_obj) {
// don't add a kill for dogfight kills on non-players
} else {
// bombs don't scale with difficulty at the moment. If we change this we want to *scoring_get_scale_factor() too
kill_score = (int)(dead_wip->score * scoring_scale_by_damage);
// bombs don't scale with difficulty at the moment. If we change this we want to *scoring_get_scale_factor()
kill_score = dead_wip->score;
plr->stats.m_score += kill_score;
hud_gauge_popup_start(HUD_KILLS_GAUGE);
#ifdef SCORING_DEBUG
char kill_score_text[1024] = "";
sprintf(kill_score_text, "SCORING : %s killed a ship worth %i points and gets %i pts for the kill", plr->callsign, dead_wip->score, kill_score);
sprintf(kill_score_text, "SCORING : %s killed a bomb worth %i points and gets %i pts for the kill", plr->callsign, dead_wip->score, kill_score);
if (MULTIPLAYER_MASTER) {
send_game_chat_packet(Net_player, kill_score_text, MULTI_MSG_ALL);
}
@@ -1003,100 +952,30 @@ int scoring_eval_kill_on_weapon(object *weapon_obj, object *other_obj) {
// multiplayer
if(net_plr != NULL){
multi_team_maybe_add_score(dead_wip->score , net_plr->p_info.team);
// award teammates % of score value for big ship kills
// not in dogfight tho
// and not if there is no assist threshold (as otherwise assists could get higher scores than kills)
/* Below is N/A. -Halleck
if (!(Netgame.type_flags & NG_TYPE_DOGFIGHT) && (Ship_info[dead_wp->ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))) {
for (idx=0; idx<MAX_PLAYERS; idx++) {
if (MULTI_CONNECTED(Net_players[idx]) && (Net_players[idx].p_info.team == net_plr->p_info.team) && (&Net_players[idx] != net_plr)) {
assist_score = (int)(dead_wip->score * The_mission.ai_profile->assist_award_percentage_scale[Game_skill_level]);
Net_players[idx].m_player->stats.m_score += assist_score;
#ifdef SCORING_DEBUG
// DEBUG CODE TO TEST NEW SCORING
char score_text[1024] = "";
sprintf(score_text, "SCORING : All team mates get %d pts for helping kill the capship", assist_score);
send_game_chat_packet(Net_player, score_text, MULTI_MSG_ALL);
HUD_printf(score_text);
mprintf((score_text));
#endif
}
}
}
*/
// death message
if((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_AM_MASTER) && (net_plr != NULL) && (dead_plr != NULL) && (net_plr->m_player != NULL) && (dead_plr->m_player != NULL)){
char dead_text[1024] = "";
sprintf(dead_text, "%s gets the kill for %s", net_plr->m_player->callsign, dead_plr->m_player->callsign);
send_game_chat_packet(Net_player, dead_text, MULTI_MSG_ALL, NULL, NULL, 2);
HUD_printf(dead_text);
}
}
}
}
// increment his all-encompassing kills
/*Not really a kill. -Halleck
plr->stats.m_kills[si_index]++;
plr->stats.m_kill_count++;
// update everyone on this guy's kills if this is multiplayer
if(MULTIPLAYER_MASTER && (net_player_num != -1)){
// send appropriate stats
if(Netgame.type_flags & NG_TYPE_DOGFIGHT){
// evaluate dogfight kills
multi_df_eval_kill(&Net_players[net_player_num], weapon_obj);
// update stats
send_player_stats_block_packet(&Net_players[net_player_num], STATS_DOGFIGHT_KILLS);
} else {
send_player_stats_block_packet(&Net_players[net_player_num], STATS_MISSION_KILLS);
}
}
*/
}
} else {
// set killer_sig for this ship to -1, indicating no one got the kill for it
killer_sig = -1;
}
// pass in the guy who got the credit for the kill (if any), so that he doesn't also
// get credit for an assist
/* TODO: ADD ASSIST CALC BACK IN. -Halleck
scoring_eval_assists(dead_wp,killer_sig, is_enemy_player);
*/
}
#ifdef SCORING_DEBUG
if (Game_mode & GM_MULTIPLAYER) {
char buf[256];
sprintf(Scoring_debug_text, "SCORING : %s killed.\nDamage by ship:\n\n", dead_wip->name);
sprintf(Scoring_debug_text, "SCORING : %s killed.\nKilled by player:\n", dead_wip->name);
// show damage done by player
for (int i=0; i<MAX_DAMAGE_SLOTS; i++) {
int net_player_num = multi_find_player_by_signature(dead_wp->damage_ship_id[i]);
if (net_player_num != -1) {
plr = Net_players[net_player_num].m_player;
sprintf(buf, "%s: %f", plr->callsign, dead_wp->damage_ship[i]);
int net_player_num = multi_find_player_by_signature(killer_sig);
if (net_player_num != -1) {
plr = Net_players[net_player_num].m_player;
char buf[256];
sprintf(buf, " %s\n", plr->callsign);
if (dead_wp->damage_ship_id[i] == killer_sig ) {
strcat_s(buf, " KILLER\n");
} else {
strcat_s(buf, "\n");
}
strcat_s(Scoring_debug_text, buf);
}
strcat_s(Scoring_debug_text, buf);
}
mprintf ((Scoring_debug_text));
}
#endif
return max_damage_index;
return killer_sig;
}
// kill_id is the object signature of the guy who got the credit for the kill (may be -1, if no one got it)
@@ -1347,102 +1226,6 @@ void scoring_eval_hit(object *hit_obj, object *other_obj,int from_blast)
}
}
// STATS damage, assists recording stuff
void scoring_add_damage_to_weapon(object *weapon_obj,object *other_obj,float damage)
{
int found_slot, signature;
int lowest_index,idx;
object *use_obj;
weapon *wp;
// multiplayer clients bail here
if(MULTIPLAYER_CLIENT){
return;
}
// if we have no other object, bail
if(other_obj == NULL){
return;
}
// for player kill/assist evaluation, we have to know exactly how much damage really mattered. For example, if
// a ship had 1 hit point left, and the player hit it with a nuke, it doesn't matter that it did 10,000,000
// points of damage, only that 1 point would count
float actual_damage = 0.0f;
// other_obj might not always be the parent of other_obj (in the case of debug code for sure). See
// if the other_obj has a parent, and if so, use the parent. If no parent, see if other_obj is a ship
// and if so, use that ship.
if ( other_obj->parent != -1 ){
use_obj = &Objects[other_obj->parent];
signature = use_obj->signature;
} else {
signature = other_obj->signature;
use_obj = other_obj;
}
// don't count damage done to a ship by himself
if(use_obj == weapon_obj){
return;
}
// get a pointer to the ship and add the actual amount of damage done to it
// get the ship object, and determine the _actual_ amount of damage done
wp = &Weapons[weapon_obj->instance];
// see comments at beginning of function
if(weapon_obj->hull_strength < 0.0f){
actual_damage = damage + weapon_obj->hull_strength;
} else {
actual_damage = damage;
}
if(actual_damage < 0.0f){
actual_damage = 0.0f;
}
wp->total_damage_received += actual_damage;
// go through and clear out all old damagers
for(idx=0; idx<MAX_DAMAGE_SLOTS; idx++){
if((wp->damage_ship_id[idx] >= 0) && (ship_get_by_signature(wp->damage_ship_id[idx]) < 0)){
wp->damage_ship_id[idx] = -1;
wp->damage_ship[idx] = 0;
}
}
// only evaluate possible kill/assist numbers if the hitting object (use_obj) is a piloted ship (ie, ignore asteroids, etc)
// don't store damage a ship may do to himself
if((weapon_obj->type == OBJ_WEAPON) && (use_obj->type == OBJ_SHIP)){
found_slot = 0;
// try and find an open slot
for(idx=0;idx<MAX_DAMAGE_SLOTS;idx++){
// if this ship object doesn't exist anymore, use the slot
if((wp->damage_ship_id[idx] == -1) || (ship_get_by_signature(wp->damage_ship_id[idx]) < 0) || (wp->damage_ship_id[idx] == signature) ){
found_slot = 1;
break;
}
}
// if not found (implying all slots are taken), then find the slot with the lowest damage % and use that
if(!found_slot){
lowest_index = 0;
for(idx=0;idx<MAX_DAMAGE_SLOTS;idx++){
if(wp->damage_ship[idx] < wp->damage_ship[lowest_index]){
lowest_index = idx;
}
}
} else {
lowest_index = idx;
}
// fill in the slot damage and damager-index
if(found_slot){
wp->damage_ship[lowest_index] += actual_damage;
} else {
wp->damage_ship[lowest_index] = actual_damage;
}
wp->damage_ship_id[lowest_index] = signature;
}
}
// get a scaling factor for adding/subtracting from mission score
float scoring_get_scale_factor()
{
-1
View File
@@ -145,7 +145,6 @@ void scoring_do_accept( scoring_struct *score );
void scoring_check_medal(scoring_struct *sc);
void scoring_add_damage(object *ship_obj,object *other_obj,float damage);
void scoring_add_damage_to_weapon(object *weapon_obj,object *other_obj,float damage);
int scoring_eval_kill(object *ship_obj);
int scoring_eval_kill_on_weapon(object *weapon_obj, object *other_obj);
void scoring_eval_assists(ship *sp,int killer_sig, bool enemy_player = false);
+1 -6
View File
@@ -227,12 +227,7 @@ typedef struct weapon {
float launch_speed; // the initial forward speed (can vary due to additive velocity or acceleration)
// currently only gets set when weapon_info->acceleration_time is used
bool collisionOccured;
mc_info collisionInfo; // The last collision of this weapon or NULL if it had none
//Scoring stuff
float total_damage_received; // total damage received (for scoring purposes)
float damage_ship[MAX_WEP_DAMAGE_SLOTS]; // damage applied from each player
int damage_ship_id[MAX_WEP_DAMAGE_SLOTS]; // signature of the damager (corresponds to each entry in damage_ship)
mc_info* collisionInfo; // The last collision of this weapon or NULL if it had none
int hud_in_flight_snd_sig; // Signature of the sound played while the weapon is in flight
} weapon;
+6 -17
View File
@@ -3669,6 +3669,11 @@ void weapon_delete(object *obj)
wp->cmeasure_ignore_list = nullptr;
}
if (wp->collisionInfo != nullptr) {
delete wp->collisionInfo;
wp->collisionInfo = nullptr;
}
wp->objnum = -1;
Num_weapons--;
Assert(Num_weapons >= 0);
@@ -5453,19 +5458,11 @@ int weapon_create( vec3d * pos, matrix * porient, int weapon_type, int parent_ob
wp->alpha_current = -1.0f;
wp->alpha_backward = 0;
wp->collisionOccured = false;
wp->collisionInfo = nullptr;
wp->hud_in_flight_snd_sig = -1;
Num_weapons++;
// reset the damage record fields (for scoring purposes)
wp->total_damage_received = 0.0f;
for(int i=0;i<MAX_WEP_DAMAGE_SLOTS;i++)
{
wp->damage_ship[i] = 0.0f;
wp->damage_ship_id[i] = -1;
}
if (Weapons_inherit_parent_collision_group) {
Objects[objnum].collision_group_id = Objects[parent_objnum].collision_group_id;
}
@@ -6203,14 +6200,6 @@ void weapon_hit( object * weapon_obj, object * other_obj, vec3d * hitpos, int qu
}
}
// single player and multiplayer masters evaluate the scoring and kill stuff
if (!MULTIPLAYER_CLIENT) {
//If this is a bomb, set it up for scoring. -Halleck
if (wip->wi_flags & WIF_BOMB) {
scoring_eval_kill_on_weapon(weapon_obj, other_obj);
}
}
weapon_obj->flags |= OF_SHOULD_BE_DEAD;
//Set shockwaves flag