Refactor autoaimTick

This commit is contained in:
Ryan Dwyer 2022-11-12 23:03:57 +10:00
parent aeb09b7afa
commit 848fc2b82e
4 changed files with 173 additions and 173 deletions

View File

@ -66,13 +66,17 @@ bool bmoveIsAutoAimEnabledForCurrentWeapon(void)
{
struct weaponfunc *func = currentPlayerGetWeaponFunction(0);
if (!func) {
return false;
}
if (func) {
if (func->flags & FUNCFLAG_NOAUTOAIM) {
return false;
}
if ((func->type & 0xff) == INVENTORYFUNCTYPE_CLOSE) {
return true;
return false;
}
}

View File

@ -1358,7 +1358,7 @@ struct weaponfunc_shootauto invfunc_cmp150_followlockon = {
0, // ammoindex
&invnoisesettings_loud,
invanim_cmp150_shoot, // fire animation
0, // flags
FUNCFLAG_NOAUTOAIM, // flags
&invrecoilsettings_default,
0, // recoverytime60
1, // damage
@ -3521,7 +3521,7 @@ struct weaponfunc_shootsingle invfunc_farsight_shoot = {
0, // ammoindex
&invnoisesettings_louder,
invanim_farsight_shoot, // fire animation
0, // flags
FUNCFLAG_NOAUTOAIM, // flags
&invrecoilsettings_default,
0, // recoverytime60
100, // damage
@ -3543,7 +3543,7 @@ struct weaponfunc_shootsingle invfunc_farsight_targetlocator = {
0, // ammoindex
&invnoisesettings_louder,
invanim_farsight_shoot, // fire animation
0, // flags
FUNCFLAG_NOAUTOAIM, // flags
&invrecoilsettings_default,
0, // recoverytime60
100, // damage

View File

@ -2216,7 +2216,7 @@ void propsTestForPickup(void)
}
}
f32 func0f06438c(struct prop *prop, struct coord *arg1, f32 *arg2, f32 *arg3, f32 *arg4, bool throughobjects, bool cangangsta, s32 arg7)
f32 func0f06438c(struct prop *prop, struct coord *arg1, f32 *arg2, f32 *arg3, f32 *arg4)
{
f32 spa0[2];
struct coord sp94;
@ -2232,7 +2232,7 @@ f32 func0f06438c(struct prop *prop, struct coord *arg1, f32 *arg2, f32 *arg3, f3
f32 right;
f32 result = -2;
struct weaponfunc *func = currentPlayerGetWeaponFunction(HAND_RIGHT);
bool sp50 = arg7;
bool sp50 = false;
bool sp4c;
f32 sp48;
struct prop *playerprop;
@ -2282,21 +2282,17 @@ f32 func0f06438c(struct prop *prop, struct coord *arg1, f32 *arg2, f32 *arg3, f3
sp8c[0] = floorf(sp8c[0]);
sp84[0] = ceilf(sp84[0]);
if (bmoveIsAutoAimEnabledForCurrentWeapon() || cangangsta) {
if (sp8c[0] <= right && left <= sp84[0]) {
sp48 = (sp84[0] - sp8c[0]) * 1.5f;
if (sp8c[0] <= right && left <= sp84[0]) {
sp48 = (sp84[0] - sp8c[0]) * 1.5f;
if (!g_Vars.normmplayerisrunning) {
sp48 = sp48 * g_AutoAimScale;
}
sp4c = camGetScreenLeft() + 0.5f * camGetScreenWidth() >= (sp8c[0] + sp84[0]) * 0.5f - sp48
&& camGetScreenLeft() + 0.5f * camGetScreenWidth() <= (sp8c[0] + sp84[0]) * 0.5f + sp48
&& left <= spa0[0]
&& right >= spa0[0];
if (!g_Vars.normmplayerisrunning) {
sp48 = sp48 * g_AutoAimScale;
}
} else {
sp4c = sp8c[0] <= sp70 && sp70 <= sp84[0];
sp4c = camGetScreenLeft() + 0.5f * camGetScreenWidth() >= (sp8c[0] + sp84[0]) * 0.5f - sp48
&& camGetScreenLeft() + 0.5f * camGetScreenWidth() <= (sp8c[0] + sp84[0]) * 0.5f + sp48
&& left <= spa0[0]
&& right >= spa0[0];
}
if (sp4c) {
@ -2304,15 +2300,9 @@ f32 func0f06438c(struct prop *prop, struct coord *arg1, f32 *arg2, f32 *arg3, f3
playerSetPerimEnabled(playerprop, false);
if (throughobjects) {
ok = cdTestLos03(&playerprop->pos, playerprop->rooms, &prop->pos,
CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG,
GEOFLAG_BLOCK_SHOOT);
} else {
ok = cdTestLos03(&playerprop->pos, playerprop->rooms, &prop->pos,
CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG,
GEOFLAG_BLOCK_SHOOT);
}
ok = cdTestLos03(&playerprop->pos, playerprop->rooms, &prop->pos,
CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG,
GEOFLAG_BLOCK_SHOOT);
if (ok) {
f32 value = spa0[1];
@ -2325,7 +2315,7 @@ f32 func0f06438c(struct prop *prop, struct coord *arg1, f32 *arg2, f32 *arg3, f3
arg4[1] = value;
if (bmoveIsAutoAimEnabledForCurrentWeapon() || cangangsta) {
{
f32 value = spa0[0];
if (value < left) {
@ -2408,173 +2398,174 @@ void farsightChooseTarget(void)
g_Vars.currentplayer->autoerasertarget = besttarget;
}
void autoaimTick(void)
struct prop *autoaimFindBestCmpProp(f32 aimpos[2])
{
struct prop *bestprop = NULL;
f32 aimpos[2] = {0, 0};
bool isclose = false;
bool cangangsta = weaponHasFlag(bgunGetWeaponNum(HAND_RIGHT), WEAPONFLAG_GANGSTA);
bool iscmpsec = false;
struct weaponfunc *func = currentPlayerGetWeaponFunction(HAND_RIGHT);
s32 i;
if (func && (func->type & 0xff) == INVENTORYFUNCTYPE_CLOSE) {
isclose = true;
}
for (i = 0; i < ARRAYCOUNT(g_Vars.currentplayer->trackedprops); i++) {
struct trackedprop *trackedprop = &g_Vars.currentplayer->trackedprops[i];
if (frIsInTraining()) {
if (!frChooseFarsightTarget()) {
farsightChooseTarget();
}
} else {
farsightChooseTarget();
}
if (trackedprop->prop
&& (trackedprop->x1 >= 0 || trackedprop->x2 >= 0)
&& (trackedprop->y1 >= 0 || trackedprop->y2 >= 0)) {
// Define the aim limits
f32 top = camGetScreenTop() + camGetScreenHeight() * 0.125f;
f32 bottom = camGetScreenTop() + camGetScreenHeight() * 0.875f;
f32 left = camGetScreenLeft() + camGetScreenWidth() * 0.125f;
f32 right = camGetScreenLeft() + camGetScreenWidth() * 0.875f;
struct chrdata *chr = NULL;
if (bgunGetWeaponNum(HAND_RIGHT) == WEAPON_CMP150
&& g_Vars.currentplayer->hands[HAND_RIGHT].gset.weaponfunc == FUNC_SECONDARY) {
iscmpsec = true;
}
bestprop = trackedprop->prop;
if (iscmpsec) {
// For CMP on secondary mode, find the first prop that is within the aim limits
for (i = 0; i < ARRAYCOUNT(g_Vars.currentplayer->trackedprops); i++) {
struct trackedprop *trackedprop = &g_Vars.currentplayer->trackedprops[i];
if (bestprop->type & (PROPTYPE_OBJ | PROPTYPE_WEAPON | PROPTYPE_DOOR)) {
// trackedprop is an object
aimpos[0] = (trackedprop->x2 + trackedprop->x1) / 2;
aimpos[1] = (trackedprop->y2 + trackedprop->y1) / 2;
if (trackedprop->prop
&& (trackedprop->x1 >= 0 || trackedprop->x2 >= 0)
&& (trackedprop->y1 >= 0 || trackedprop->y2 >= 0)) {
// Define the aim limits
f32 top = camGetScreenTop() + camGetScreenHeight() * 0.125f;
f32 bottom = camGetScreenTop() + camGetScreenHeight() * 0.875f;
f32 left = camGetScreenLeft() + camGetScreenWidth() * 0.125f;
f32 right = camGetScreenLeft() + camGetScreenWidth() * 0.875f;
struct chrdata *chr = NULL;
if (bestprop->flags & PROPFLAG_ONTHISSCREENTHISTICK) {
struct defaultobj *obj = bestprop->obj;
Mtxf *mtx = model0001a60c(obj->model);
struct coord spac;
spac.z = mtx->m[3][2];
bestprop = trackedprop->prop;
if (bestprop->type & (PROPTYPE_OBJ | PROPTYPE_WEAPON | PROPTYPE_DOOR)) {
// trackedprop is an object
aimpos[0] = (trackedprop->x2 + trackedprop->x1) / 2;
aimpos[1] = (trackedprop->y2 + trackedprop->y1) / 2;
if (bestprop->flags & PROPFLAG_ONTHISSCREENTHISTICK) {
struct defaultobj *obj = bestprop->obj;
Mtxf *mtx = model0001a60c(obj->model);
struct coord spac;
spac.z = mtx->m[3][2];
if (spac.z < 0) {
spac.x = mtx->m[3][0];
spac.y = mtx->m[3][1];
cam0f0b4d04(&spac, aimpos);
}
}
} else {
// trackedprop is a chr
chr = bestprop->chr;
aimpos[0] = (trackedprop->x2 + trackedprop->x1) / 2;
if (chr && chr->race == RACE_EYESPY) {
aimpos[1] = (trackedprop->y2 + trackedprop->y1) >> 1;
} else {
// Aim 2/3 up the chr, so about their chest
aimpos[1] = (trackedprop->y2 + trackedprop->y1 * 2) / 3;
if (spac.z < 0) {
spac.x = mtx->m[3][0];
spac.y = mtx->m[3][1];
cam0f0b4d04(&spac, aimpos);
}
}
} else {
// trackedprop is a chr
chr = bestprop->chr;
aimpos[0] = (trackedprop->x2 + trackedprop->x1) / 2;
// Constrain aimpos to the aim limits
if (aimpos[0] > right) {
aimpos[0] = right;
}
if (aimpos[0] < left) {
aimpos[0] = left;
}
if (aimpos[1] > bottom) {
aimpos[1] = bottom;
}
if (aimpos[1] < top) {
aimpos[1] = top;
}
// Don't use this prop if it's an undeployed eyespy, or if
// the trackedprop is outside of the aim limits
if (chr && chr->race == RACE_EYESPY) {
struct eyespy *eyespy = chrToEyespy(chr);
aimpos[1] = (trackedprop->y2 + trackedprop->y1) >> 1;
} else {
// Aim 2/3 up the chr, so about their chest
aimpos[1] = (trackedprop->y2 + trackedprop->y1 * 2) / 3;
}
}
if (eyespy == NULL || !eyespy->deployed) {
bestprop = NULL;
aimpos[0] = aimpos[1] = 0;
}
} else if (aimpos[0] > trackedprop->x2
|| aimpos[0] < trackedprop->x1
|| aimpos[1] > trackedprop->y2
|| aimpos[1] < trackedprop->y1) {
// Constrain aimpos to the aim limits
if (aimpos[0] > right) {
aimpos[0] = right;
}
if (aimpos[0] < left) {
aimpos[0] = left;
}
if (aimpos[1] > bottom) {
aimpos[1] = bottom;
}
if (aimpos[1] < top) {
aimpos[1] = top;
}
// Don't use this prop if it's an undeployed eyespy, or if
// the trackedprop is outside of the aim limits
if (chr && chr->race == RACE_EYESPY) {
struct eyespy *eyespy = chrToEyespy(chr);
if (eyespy == NULL || !eyespy->deployed) {
bestprop = NULL;
aimpos[0] = aimpos[1] = 0;
}
}
if (bestprop) {
break;
} else if (aimpos[0] > trackedprop->x2
|| aimpos[0] < trackedprop->x1
|| aimpos[1] > trackedprop->y2
|| aimpos[1] < trackedprop->y1) {
bestprop = NULL;
aimpos[0] = aimpos[1] = 0;
}
}
} else if ((bmoveIsAutoAimEnabledForCurrentWeapon() || cangangsta) && !isclose) {
// Standard auto aim
f32 bestthing = -1;
struct prop *prop;
struct coord sp94;
f32 sp8c[2];
f32 sp84[2];
struct chrdata *chr;
f32 sp78[2];
struct prop **ptr = g_Vars.endonscreenprops - 1;
// Iterate onscreen props near to far
while (ptr >= g_Vars.onscreenprops) {
prop = *ptr;
if (bestprop) {
break;
}
}
if (prop && prop->chr) {
if (prop->type == PROPTYPE_CHR
|| (prop->type == PROPTYPE_PLAYER && playermgrGetPlayerNumByProp(prop) != g_Vars.currentplayernum)) {
chr = prop->chr;
return bestprop;
}
if (!chrCompareTeams(g_Vars.currentplayer->prop->chr, chr, COMPARE_FRIENDS)
&& (chrGetHeldProp(chr, HAND_RIGHT)
|| chrGetHeldProp(chr, HAND_LEFT)
|| (chr->chrflags & CHRCFLAG_FORCEAUTOAIM)
|| chr->gunprop)
&& chrCalculateAutoAim(prop, &sp94, sp8c, sp84)) {
f32 thing = func0f06438c(prop, &sp94, sp8c, sp84, sp78, false, cangangsta, 0);
struct prop *autoaimFindGeneralProp(f32 aimpos[2])
{
struct prop *bestprop = NULL;
f32 bestthing = -1;
struct prop *prop;
struct coord sp94;
f32 sp8c[2];
f32 sp84[2];
struct chrdata *chr;
f32 sp78[2];
struct prop **ptr = g_Vars.endonscreenprops - 1;
if (thing > bestthing) {
bestthing = thing;
aimpos[0] = sp78[0];
aimpos[1] = sp78[1];
bestprop = prop;
// Iterate onscreen props near to far
while (ptr >= g_Vars.onscreenprops) {
prop = *ptr;
if (thing >= 1) {
break;
}
if (prop && prop->chr) {
if (prop->type == PROPTYPE_CHR
|| (prop->type == PROPTYPE_PLAYER && playermgrGetPlayerNumByProp(prop) != g_Vars.currentplayernum)) {
chr = prop->chr;
if (!chrCompareTeams(g_Vars.currentplayer->prop->chr, chr, COMPARE_FRIENDS)
&& (chrGetHeldProp(chr, HAND_RIGHT)
|| chrGetHeldProp(chr, HAND_LEFT)
|| (chr->chrflags & CHRCFLAG_FORCEAUTOAIM)
|| chr->gunprop)
&& chrCalculateAutoAim(prop, &sp94, sp8c, sp84)) {
f32 thing = func0f06438c(prop, &sp94, sp8c, sp84, sp78);
if (thing > bestthing) {
bestthing = thing;
aimpos[0] = sp78[0];
aimpos[1] = sp78[1];
bestprop = prop;
if (thing >= 1) {
break;
}
}
}
}
ptr--;
}
ptr--;
}
if (bestprop) {
if (bmoveIsAutoAimEnabledForCurrentWeapon() || iscmpsec) {
f32 x = (aimpos[0] - camGetScreenLeft()) / (camGetScreenWidth() * 0.5f) - 1;
f32 y = (aimpos[1] - camGetScreenTop()) / (camGetScreenHeight() * 0.5f) - 1;
bmoveUpdateAutoAimProp(bestprop, x, y);
}
return bestprop;
}
if (cangangsta) {
void autoaimSetProp(struct prop *prop, f32 aimpos[2])
{
if (prop) {
f32 x = (aimpos[0] - camGetScreenLeft()) / (camGetScreenWidth() * 0.5f) - 1;
f32 y = (aimpos[1] - camGetScreenTop()) / (camGetScreenHeight() * 0.5f) - 1;
bmoveUpdateAutoAimProp(prop, x, y);
} else {
bmoveUpdateAutoAimProp(NULL, 0, 0);
}
}
void autoaimTick(void)
{
struct prop *bestprop;
f32 aimpos[2] = {0, 0};
s32 weaponnum = bgunGetWeaponNum(HAND_RIGHT);
bool cangangsta = weaponHasFlag(weaponnum, WEAPONFLAG_GANGSTA);
g_Vars.currentplayer->gunctrl.gangsta = false;
if (bmoveIsAutoAimEnabledForCurrentWeapon() || cangangsta) {
// Standard auto aim
bestprop = autoaimFindGeneralProp(aimpos);
autoaimSetProp(bestprop, aimpos);
if (bestprop && cangangsta) {
f32 xdist = g_Vars.currentplayer->bond2.unk10.x - bestprop->pos.x;
f32 ydist = g_Vars.currentplayer->bond2.unk10.y - bestprop->pos.y;
f32 zdist = g_Vars.currentplayer->bond2.unk10.z - bestprop->pos.z;
@ -2582,17 +2573,22 @@ void autoaimTick(void)
if (sqdist < 40000) {
g_Vars.currentplayer->gunctrl.gangsta = true;
} else {
g_Vars.currentplayer->gunctrl.gangsta = false;
}
} else {
g_Vars.currentplayer->gunctrl.gangsta = false;
}
} else {
u32 stack;
bmoveUpdateAutoAimProp(NULL, 0, 0);
} else if (weaponnum == WEAPON_CMP150 && g_Vars.currentplayer->hands[HAND_RIGHT].gset.weaponfunc == FUNC_SECONDARY) {
// For CMP on secondary mode, find the first prop that is within the aim limits
bestprop = autoaimFindBestCmpProp(aimpos);
autoaimSetProp(bestprop, aimpos);
} else if (weaponnum == WEAPON_FARSIGHT) {
if (frIsInTraining()) {
frChooseFarsightTarget();
} else {
farsightChooseTarget();
}
g_Vars.currentplayer->gunctrl.gangsta = false;
bmoveUpdateAutoAimProp(NULL, 0, 0);
} else {
bmoveUpdateAutoAimProp(NULL, 0, 0);
}
}

View File

@ -41,7 +41,7 @@ void propsTickPlayer(bool islastplayer);
void propsTickPadEffects(void);
void propSetPerimEnabled(struct prop *prop, bool enable);
void propsTestForPickup(void);
f32 func0f06438c(struct prop *prop, struct coord *arg1, f32 *arg2, f32 *arg3, f32 *arg4, bool throughobjects, bool cangangsta, s32 arg7);
f32 func0f06438c(struct prop *prop, struct coord *arg1, f32 *arg2, f32 *arg3, f32 *arg4);
void farsightChooseTarget(void);
void autoaimTick(void);
u32 propDoorGetCdTypes(struct prop *prop);