Watch missiles when available
This commit is contained in:
parent
004e1371d6
commit
32b9202e1f
|
@ -59,6 +59,9 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
|||
#include "args.h"
|
||||
#include "object.h"
|
||||
|
||||
#include "compiler-range_for.h"
|
||||
#include "highest_valid.h"
|
||||
|
||||
#ifdef OGL
|
||||
#include "ogl_init.h"
|
||||
#endif
|
||||
|
@ -423,6 +426,102 @@ static const char *get_missile_name(const unsigned laser_type)
|
|||
}
|
||||
}
|
||||
|
||||
static void set_missile_viewer(vobjptridx_t o)
|
||||
{
|
||||
Missile_viewer = o;
|
||||
Missile_viewer_sig = o->signature;
|
||||
}
|
||||
|
||||
static void clear_missile_viewer()
|
||||
{
|
||||
Missile_viewer = nullptr;
|
||||
}
|
||||
|
||||
__attribute_warn_unused_result
|
||||
static bool is_viewable_missile(weapon_type_t laser_type)
|
||||
{
|
||||
return laser_type == CONCUSSION_ID ||
|
||||
laser_type == HOMING_ID ||
|
||||
laser_type == SMART_ID ||
|
||||
laser_type == MEGA_ID ||
|
||||
laser_type == FLASH_ID ||
|
||||
laser_type == GUIDEDMISS_ID ||
|
||||
laser_type == MERCURY_ID ||
|
||||
laser_type == EARTHSHAKER_ID;
|
||||
}
|
||||
|
||||
static bool choose_missile_viewer()
|
||||
{
|
||||
if (unlikely(!PlayerCfg.MissileViewEnabled))
|
||||
return false;
|
||||
const auto need_new_missile_viewer = []{
|
||||
if (!Missile_viewer)
|
||||
return true;
|
||||
if (Missile_viewer->type != OBJ_WEAPON)
|
||||
return true;
|
||||
if (Missile_viewer->signature != Missile_viewer_sig)
|
||||
return true;
|
||||
/* No check on parent here. Missile_viewer is cleared if needed
|
||||
* when a missile is fired.
|
||||
*/
|
||||
return false;
|
||||
};
|
||||
if (likely(!need_new_missile_viewer()))
|
||||
/* Valid viewer already set */
|
||||
return true;
|
||||
const auto better_match = [](cobjptridx_t a, vcobjptridx_t b) {
|
||||
if (a == object_none)
|
||||
return true;
|
||||
const vcobjptridx_t va{a};
|
||||
return va->lifeleft < b->lifeleft;
|
||||
};
|
||||
/* Find new missile */
|
||||
objptridx_t local_player_missile = object_none, other_player_missile = object_none;
|
||||
const auto game_mode = Game_mode;
|
||||
range_for (const auto i, highest_valid(Objects))
|
||||
{
|
||||
const auto o = vobjptridx(i);
|
||||
if (o->type != OBJ_WEAPON)
|
||||
continue;
|
||||
if (o->ctype.laser_info.parent_type != OBJ_PLAYER)
|
||||
continue;
|
||||
const auto laser_type = get_weapon_id(o);
|
||||
if (!is_viewable_missile(laser_type))
|
||||
continue;
|
||||
if (o->ctype.laser_info.parent_num == Players[Player_num].objnum)
|
||||
{
|
||||
if (!better_match(local_player_missile, o))
|
||||
continue;
|
||||
local_player_missile = o;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!better_match(other_player_missile, o))
|
||||
continue;
|
||||
if (game_mode & GM_MULTI_COOP)
|
||||
{
|
||||
/* Always allow missiles of other players */
|
||||
}
|
||||
else if (game_mode & GM_TEAM)
|
||||
{
|
||||
/* Allow missiles from same team */
|
||||
if (get_team(Player_num) != get_team(Objects[o->ctype.laser_info.parent_num].id));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
other_player_missile = o;
|
||||
}
|
||||
}
|
||||
if (local_player_missile != object_none)
|
||||
set_missile_viewer(local_player_missile);
|
||||
else if (other_player_missile != object_none)
|
||||
set_missile_viewer(other_player_missile);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void show_one_extra_view(const int w);
|
||||
static void show_extra_views()
|
||||
{
|
||||
|
@ -483,23 +582,18 @@ static void show_extra_views()
|
|||
do_cockpit_window_view(1,0,WBU_STATIC,NULL);
|
||||
Guided_missile[Player_num] = NULL;
|
||||
}
|
||||
|
||||
if (Missile_viewer) //do missile view
|
||||
{
|
||||
if (Missile_viewer_sig == -1)
|
||||
Missile_viewer_sig = Missile_viewer->signature;
|
||||
if (PlayerCfg.MissileViewEnabled && Missile_viewer->type!=OBJ_NONE && Missile_viewer->signature == Missile_viewer_sig) {
|
||||
if (choose_missile_viewer())
|
||||
//do missile view
|
||||
{
|
||||
RenderingType=2+(1<<4);
|
||||
do_cockpit_window_view(1,Missile_viewer,0,WBU_MISSILE,get_missile_name(Missile_viewer->id));
|
||||
did_missile_view=1;
|
||||
}
|
||||
else {
|
||||
Missile_viewer = NULL;
|
||||
Missile_viewer_sig = -1;
|
||||
clear_missile_viewer();
|
||||
RenderingType=255;
|
||||
do_cockpit_window_view(1,0,WBU_STATIC,NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int w=0;w<2;w++) {
|
||||
|
|
|
@ -1308,8 +1308,36 @@ static objptridx_t Laser_player_fire_spread_delay(const vobjptridx_t obj, enum w
|
|||
//laser_type == SUPERPROX_ID ||
|
||||
laser_type == MERCURY_ID ||
|
||||
laser_type == EARTHSHAKER_ID)
|
||||
if (Missile_viewer == NULL && obj->id==Player_num)
|
||||
{
|
||||
const auto need_new_missile_viewer = [obj]{
|
||||
if (!Missile_viewer)
|
||||
return true;
|
||||
if (Missile_viewer->type != OBJ_WEAPON)
|
||||
return true;
|
||||
if (Missile_viewer->signature != Missile_viewer_sig)
|
||||
return true;
|
||||
if (obj->id == Player_num && Missile_viewer->ctype.laser_info.parent_num != Players[Player_num].objnum)
|
||||
/* New missile fired-by local player &&
|
||||
* currently viewing missile not-fired-by local player
|
||||
*/
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
const auto can_view_missile = [obj]{
|
||||
if (obj->id == Player_num)
|
||||
return true;
|
||||
if (Game_mode & GM_MULTI_COOP)
|
||||
return true;
|
||||
if (Game_mode & GM_TEAM)
|
||||
return get_team(Player_num) == get_team(obj->id);
|
||||
return false;
|
||||
};
|
||||
if (need_new_missile_viewer() && can_view_missile())
|
||||
{
|
||||
Missile_viewer = objnum;
|
||||
Missile_viewer_sig = objnum->signature;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If this weapon is supposed to be silent, set that bit!
|
||||
|
|
Loading…
Reference in a new issue