Add boss target assist and finally organize camera options

This commit is contained in:
fickleheart 2019-12-12 00:48:15 -06:00
parent efec52c48a
commit a188cd5db8
7 changed files with 223 additions and 54 deletions

View File

@ -840,6 +840,8 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_cam_turnfacinginput[1]);
CV_RegisterVar(&cv_cam_lockedinput[0]);
CV_RegisterVar(&cv_cam_lockedinput[1]);
CV_RegisterVar(&cv_cam_lockonboss[0]);
CV_RegisterVar(&cv_cam_lockonboss[1]);
// s_sound.c
CV_RegisterVar(&cv_soundvolume);

View File

@ -428,6 +428,11 @@ consvar_t cv_cam_lockedinput[2] = {
{"cam2_lockedinput", "Strafe", CV_SAVE, lockedinput_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
};
consvar_t cv_cam_lockonboss[2] = {
{"cam_lockonboss", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam2_lockonboss", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
};
typedef enum
{
AXISNONE = 0,
@ -1020,6 +1025,7 @@ static fixed_t sidemove[2] = {25<<FRACBITS>>16, 50<<FRACBITS>>16}; // faster!
static fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn
boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player
mobj_t *ticcmd_ztargetfocus[2]; // Locking onto an object?
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
{
boolean forcestrafe = false;
@ -1278,6 +1284,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 0);
*myangle = player->mo->angle;
*myaiming = 0;
if (cv_cam_lockonboss[forplayer].value)
P_SetTarget(&ticcmd_ztargetfocus[forplayer], P_LookForFocusTarget(player, NULL, 0));
}
ticcmd_centerviewdown[forplayer] = true;
@ -1285,11 +1294,44 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
else if (ticcmd_centerviewdown[forplayer])
{
if (abilitydirection)
{
P_SetTarget(&ticcmd_ztargetfocus[forplayer], NULL);
CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 1);
}
ticcmd_centerviewdown[forplayer] = false;
}
if (ticcmd_ztargetfocus[forplayer])
{
if (
P_MobjWasRemoved(ticcmd_ztargetfocus[forplayer]) ||
!ticcmd_ztargetfocus[forplayer]->health ||
(ticcmd_ztargetfocus[forplayer]->flags2 & MF2_FRET) ||
(ticcmd_ztargetfocus[forplayer]->type == MT_EGGMOBILE3 && !ticcmd_ztargetfocus[forplayer]->movecount) // Sea Egg is moving around underground and shouldn't be tracked
)
P_SetTarget(&ticcmd_ztargetfocus[forplayer], NULL);
else
{
if (P_AproxDistance(
player->mo->x - ticcmd_ztargetfocus[forplayer]->x,
player->mo->y - ticcmd_ztargetfocus[forplayer]->y
) > 50*player->mo->scale)
{
INT32 anglediff = R_PointToAngle2(player->mo->x, player->mo->y, ticcmd_ztargetfocus[forplayer]->x, ticcmd_ztargetfocus[forplayer]->y) - *myangle;
const INT32 maxturn = ANG10/2;
anglediff /= 4;
if (anglediff > maxturn)
anglediff = maxturn;
else if (anglediff < -maxturn)
anglediff = -maxturn;
*myangle += anglediff;
}
}
}
if (PLAYERINPUTDOWN(ssplayer, gc_camreset))
{
if (camera.chase && !resetdown[forplayer])

View File

@ -79,7 +79,7 @@ extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_g
// hi here's some new controls
extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacing[2],
cv_cam_turnfacingability[2], cv_cam_turnfacingspindash[2], cv_cam_turnfacinginput[2],
cv_cam_lockedinput[2];
cv_cam_lockedinput[2], cv_cam_lockonboss[2];
// mouseaiming (looking up/down with the mouse or keyboard)
#define KB_LOOKSPEED (1<<25)
@ -90,6 +90,7 @@ extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacin
const char *G_BuildMapName(INT32 map);
extern boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player
extern mobj_t *ticcmd_ztargetfocus[2]; // Locking onto an object?
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer);
// copy ticcmd_t to and fro the normal way

View File

@ -2194,10 +2194,14 @@ void HU_Drawer(void)
return;
// draw the crosshair, not when viewing demos nor with chasecam
if (!automapactive && cv_crosshair.value && !demoplayback && (!camera.chase || (cv_abilitydirection[0].value && ticcmd_centerviewdown[0])) && !players[displayplayer].spectator)
if (!automapactive && cv_crosshair.value && !demoplayback &&
(!camera.chase || (cv_abilitydirection[0].value && ticcmd_centerviewdown[0] && ticcmd_ztargetfocus[0]))
&& !players[displayplayer].spectator)
HU_DrawCrosshair();
if (!automapactive && cv_crosshair2.value && !demoplayback && (!camera2.chase || (cv_abilitydirection[1].value && ticcmd_centerviewdown[1])) && !players[secondarydisplayplayer].spectator)
if (!automapactive && cv_crosshair2.value && !demoplayback &&
(!camera2.chase || (cv_abilitydirection[1].value && ticcmd_centerviewdown[1] && ticcmd_ztargetfocus[1]))
&& !players[secondarydisplayplayer].spectator)
HU_DrawCrosshair2();
// draw desynch text

View File

@ -1182,46 +1182,96 @@ static menuitem_t OP_Mouse2OptionsMenu[] =
static menuitem_t OP_CameraOptionsMenu[] =
{
{IT_HEADER, NULL, "General Toggles", NULL, 0},
{IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 5},
{IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 10},
{IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 15},
{IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 20},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 30},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 35},
{IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 40},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 45},
{IT_HEADER, NULL, "Camera Positioning", NULL, 30},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 35},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 40},
{IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 45},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 50},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[0], 55},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[0], 60},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 65},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[0], 70},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 75},
{IT_STRING | IT_CVAR, NULL, "Locked movement", &cv_cam_lockedinput[0], 80},
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 90},
{IT_HEADER, NULL, "Display Options", NULL, 60},
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 65},
};
static menuitem_t OP_Camera2OptionsMenu[] =
{
{IT_HEADER, NULL, "General Toggles", NULL, 0},
{IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 5},
{IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 10},
{IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 15},
{IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 20},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 30},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 35},
{IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 40},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 45},
{IT_HEADER, NULL, "Camera Positioning", NULL, 30},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 35},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 40},
{IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 45},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 50},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[1], 55},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[1], 60},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 65},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[1], 70},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 75},
{IT_STRING | IT_CVAR, NULL, "Locked movement", &cv_cam_lockedinput[0], 80},
{IT_HEADER, NULL, "Display Options", NULL, 60},
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 65},
};
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 90},
static menuitem_t OP_CameraExtendedOptionsMenu[] =
{
{IT_HEADER, NULL, "General Toggles", NULL, 0},
{IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 5},
{IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 10},
{IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 15},
{IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 20},
{IT_HEADER, NULL, "Camera Positioning", NULL, 30},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 35},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 40},
{IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 45},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 50},
{IT_HEADER, NULL, "Automatic Camera Options", NULL, 60},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[0], 65},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[0], 70},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 75},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[0], 80},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 85},
{IT_HEADER, NULL, "Locked Camera Options", NULL, 95},
{IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[0], 100},
{IT_STRING | IT_CVAR, NULL, "Boss targeting assist", &cv_cam_lockonboss[0], 105},
{IT_HEADER, NULL, "Display Options", NULL, 115},
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 120},
};
static menuitem_t OP_Camera2ExtendedOptionsMenu[] =
{
{IT_HEADER, NULL, "General Toggles", NULL, 0},
{IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 5},
{IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 10},
{IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 15},
{IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 20},
{IT_HEADER, NULL, "Camera Positioning", NULL, 30},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 35},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 40},
{IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 45},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 50},
{IT_HEADER, NULL, "Automatic Camera Options", NULL, 60},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[1], 65},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[1], 70},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 75},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[1], 80},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 85},
{IT_HEADER, NULL, "Locked Camera Options", NULL, 95},
{IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[1], 100},
{IT_STRING | IT_CVAR, NULL, "Boss targeting assist", &cv_cam_lockonboss[1], 105},
{IT_HEADER, NULL, "Display Options", NULL, 115},
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 120},
};
static menuitem_t OP_VideoOptionsMenu[] =
@ -4284,23 +4334,13 @@ static void M_DrawControlsDefMenu(void)
if (opt == 2)
{
OP_CameraOptionsMenu[8].status = IT_STRING|IT_CVAR|IT_CV_SLIDER;
OP_CameraOptionsMenu[9].status = IT_STRING|IT_CVAR|IT_CV_SLIDER;
OP_CameraOptionsMenu[10].status = IT_STRING|IT_CVAR|IT_CV_SLIDER;
OP_CameraOptionsMenu[11].status = IT_STRING|IT_CVAR|IT_CV_SLIDER;
OP_CameraOptionsMenu[12].status = IT_STRING|IT_CVAR|IT_CV_SLIDER;
OP_CameraOptionsMenu[13].status = IT_STRING|IT_CVAR;
OP_CameraOptionsMenu[14].alphaKey = 90;
OP_CameraOptionsDef.menuitems = OP_CameraExtendedOptionsMenu;
OP_CameraOptionsDef.numitems = sizeof (OP_CameraExtendedOptionsMenu) / sizeof (menuitem_t);
}
else
{
OP_CameraOptionsMenu[8].status = IT_DISABLED;
OP_CameraOptionsMenu[9].status = IT_DISABLED;
OP_CameraOptionsMenu[10].status = IT_DISABLED;
OP_CameraOptionsMenu[11].status = IT_DISABLED;
OP_CameraOptionsMenu[12].status = IT_DISABLED;
OP_CameraOptionsMenu[13].status = IT_DISABLED;
OP_CameraOptionsMenu[14].alphaKey = 55;
OP_CameraOptionsDef.menuitems = OP_CameraOptionsMenu;
OP_CameraOptionsDef.numitems = sizeof (OP_CameraOptionsMenu) / sizeof (menuitem_t);
}
}
else
@ -4309,23 +4349,13 @@ static void M_DrawControlsDefMenu(void)
if (opt == 2)
{
OP_Camera2OptionsMenu[8].status = IT_STRING|IT_CVAR|IT_CV_SLIDER;
OP_Camera2OptionsMenu[9].status = IT_STRING|IT_CVAR|IT_CV_SLIDER;
OP_Camera2OptionsMenu[10].status = IT_STRING|IT_CVAR|IT_CV_SLIDER;
OP_Camera2OptionsMenu[11].status = IT_STRING|IT_CVAR|IT_CV_SLIDER;
OP_Camera2OptionsMenu[12].status = IT_STRING|IT_CVAR|IT_CV_SLIDER;
OP_Camera2OptionsMenu[13].status = IT_STRING|IT_CVAR;
OP_Camera2OptionsMenu[14].alphaKey = 90;
OP_Camera2OptionsDef.menuitems = OP_Camera2ExtendedOptionsMenu;
OP_Camera2OptionsDef.numitems = sizeof (OP_Camera2ExtendedOptionsMenu) / sizeof (menuitem_t);
}
else
{
OP_Camera2OptionsMenu[8].status = IT_DISABLED;
OP_Camera2OptionsMenu[9].status = IT_DISABLED;
OP_Camera2OptionsMenu[10].status = IT_DISABLED;
OP_Camera2OptionsMenu[11].status = IT_DISABLED;
OP_Camera2OptionsMenu[12].status = IT_DISABLED;
OP_Camera2OptionsMenu[13].status = IT_DISABLED;
OP_Camera2OptionsMenu[14].alphaKey = 55;
OP_Camera2OptionsDef.menuitems = OP_Camera2OptionsMenu;
OP_Camera2OptionsDef.numitems = sizeof (OP_Camera2OptionsMenu) / sizeof (menuitem_t);
}
}

View File

@ -181,6 +181,8 @@ fixed_t P_ReturnThrustX(mobj_t *mo, angle_t angle, fixed_t move);
fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move);
void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move);
mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction);
mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet);
void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius);
boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user

View File

@ -9135,6 +9135,94 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
}
}
//
// P_LookForFocusTarget
// Looks for a target for a player to focus on, for Z-targeting etc.
// exclude would be the current focus target, to ignore.
// direction, if set, requires the target to be to the left (1) or right (-1) of the angle
// mobjflags can be used to limit the flags of objects that can be focused
//
mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction)
{
mobj_t *mo;
thinker_t *think;
mobj_t *closestmo = NULL;
const fixed_t maxdist = 2560*player->mo->scale;
const angle_t span = ANGLE_45;
fixed_t dist, closestdist = 0;
angle_t dangle, closestdangle = 0;
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
{
if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
continue;
mo = (mobj_t *)think;
if (mo->flags & MF_NOCLIPTHING)
continue;
if (mo->health <= 0) // dead
continue;
if (!(mo->flags & MF_BOSS && (mo->flags & MF_SHOOTABLE)) == !(mo->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag
continue; // not a valid target
if (mo == player->mo)
continue;
if (mo->flags2 & MF2_FRET)
continue;
if (mo->type == MT_DETON) // Don't be STUPID, Sonic!
continue;
{
fixed_t zdist = (player->mo->z + player->mo->height/2) - (mo->z + mo->height/2);
dist = P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y);
if (abs(zdist) > dist)
continue; // Don't home outside of desired angle!
dist = P_AproxDistance(dist, zdist);
if (dist > maxdist)
continue; // out of range
}
if ((twodlevel || player->mo->flags2 & MF2_TWOD)
&& abs(player->mo->y-mo->y) > player->mo->radius)
continue; // not in your 2d plane
if (mo->type == MT_PLAYER) // Don't chase after other players!
continue;
dangle = R_PointToAngle2(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius), mo->x, mo->y) - player->mo->angle;
if ((dangle + span) > span*2)
continue; // behind back
if (direction)
{
if (direction == 1 && dangle > ANGLE_180)
continue; // To the right of the player
if (direction == -1 && dangle < ANGLE_180)
continue; // To the left of the player
}
if (closestmo && (exclude ? (dangle > closestdangle) : (dist > closestdist)))
continue;
if (!P_CheckSight(player->mo, mo))
continue; // out of sight
closestmo = mo;
closestdist = dist;
closestdangle = dangle;
}
return closestmo;
}
//
// P_LookForEnemies
// Looks for something you can hit - Used for homing attack