Blend Eye Hardcode part 2

- VS_ArenaCenterInit - setting up the boss arena centerpoint
- VS_GetArena - Getting a particular arena
- VS_PredictAroundArena - Predict momentum of object around arena
- VS_RandomPointOnArena - Select random position around arena
This commit is contained in:
toaster 2023-10-29 22:04:50 +00:00
parent 506652c5df
commit 1c12b28498
6 changed files with 197 additions and 0 deletions

View file

@ -129,6 +129,13 @@ void K_DeclareWeakspot(mobj_t *spot, spottype_t spottype, UINT16 color, boolean
boolean K_CheckBossIntro(void);
// Arena objects
boolean VS_ArenaCenterInit(mobj_t *mobj, mapthing_t *mthing);
mobj_t *VS_GetArena(INT32 bossindex);
fixed_t *VS_PredictAroundArena(mobj_t *arena, mobj_t *movingobject, fixed_t magnitude, angle_t mompoint, fixed_t radiussubtract, boolean forcegoaround, fixed_t radiusdeltafactor);
fixed_t *VS_RandomPointOnArena(mobj_t *arena, fixed_t radiussubtract);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -3529,6 +3529,49 @@ static int lib_kDeclareWeakspot(lua_State *L)
return 0;
}
static int lib_vsGetArena(lua_State *L)
{
INT32 bossindex = luaL_checkinteger(L, 1);
//HUDSAFE
LUA_PushUserdata(L, VS_GetArena(bossindex), META_MOBJ);
return 1;
}
static int lib_vsPredictAroundArena(lua_State *L)
{
mobj_t *arena = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *movingobject = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
fixed_t magnitude = luaL_checkfixed(L, 3);
fixed_t mompoint = luaL_checkangle(L, 4);
fixed_t radiussubtract = luaL_checkfixed(L, 5);
boolean forcegoaround = lua_optboolean(L, 6);
fixed_t radiusdeltafactor = luaL_optinteger(L, 7, FRACUNIT); //optfixed?
NOHUD
if (!arena || !movingobject)
return LUA_ErrInvalid(L, "mobj_t");
fixed_t *result = VS_PredictAroundArena(arena, movingobject, magnitude, mompoint, radiussubtract, forcegoaround, radiusdeltafactor);
lua_pushfixed(L, result[0]);
lua_pushfixed(L, result[1]);
return 2;
}
static int lib_vsRandomPointOnArena(lua_State *L)
{
mobj_t *arena = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t radiussubtract = luaL_checkfixed(L, 2);
NOHUD
if (!arena)
return LUA_ErrInvalid(L, "mobj_t");
fixed_t *result = VS_RandomPointOnArena(arena, radiussubtract);
lua_pushfixed(L, result[0]);
lua_pushfixed(L, result[1]);
return 2;
}
static int lib_getTimeMicros(lua_State *L)
{
lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@ -3804,6 +3847,9 @@ static luaL_Reg lib[] = {
{"K_InitBossHealthBar", lib_kInitBossHealthBar},
{"K_UpdateBossHealthBar", lib_kUpdateBossHealthBar},
{"K_DeclareWeakspot", lib_kDeclareWeakspot},
{"VS_GetArena", lib_vsGetArena},
{"VS_PredictAroundArena", lib_vsPredictAroundArena},
{"VS_RandomPointOnArena", lib_vsRandomPointOnArena},
// hu_stuff technically?
{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},

View file

@ -40,3 +40,5 @@ target_sources(SRB2SDL2 PRIVATE
shadow.cpp
ball-switch.cpp
)
add_subdirectory(versus)

View file

@ -0,0 +1,3 @@
target_sources(SRB2SDL2 PRIVATE
arena.c
)

129
src/objects/versus/arena.c Normal file
View file

@ -0,0 +1,129 @@
#include "../../p_local.h"
#include "../../p_setup.h"
#include "../../m_random.h"
#include "../../k_boss.h"
#include "../../r_main.h" // R_PointToAngle2, R_PointToDist2
boolean VS_ArenaCenterInit(mobj_t *mobj, mapthing_t *mthing)
{
INT32 dist1 = mthing->thing_args[1]*FRACUNIT;
INT32 dist2 = mthing->thing_args[2]*FRACUNIT;
if (dist1 || dist2)
{
if (dist1 > dist2)
{
INT32 swap = dist1;
dist1 = dist2;
dist2 = swap;
}
mobj->extravalue1 = dist1;
mobj->extravalue2 = dist2;
return true;
}
CONS_Alert(CONS_ERROR, "Versus arena of index %d has no max radius.", mthing->thing_args[0]);
return false;
}
mobj_t *VS_GetArena(INT32 bossindex)
{
size_t i;
for (i = 0; i < nummapthings; ++i)
{
if (mapthings[i].type != mobjinfo[MT_BOSSARENACENTER].doomednum)
continue;
if (mapthings[i].thing_args[0] != bossindex)
continue;
if (mapthings[i].mobj == NULL)
continue;
return mapthings[i].mobj;
}
CONS_Alert(CONS_ERROR, "No Versus arena of index %d found.", bossindex);
return NULL;
}
fixed_t *VS_PredictAroundArena(mobj_t *arena, mobj_t *movingobject, fixed_t magnitude, angle_t mompoint, fixed_t radiussubtract, boolean forcegoaround, fixed_t radiusdeltafactor)
{
static fixed_t dest[2] = {0, 0};
if (P_MobjWasRemoved(arena) || P_MobjWasRemoved(movingobject))
return dest;
fixed_t radius = FixedHypot(movingobject->x - arena->x, movingobject->y - arena->y);
angle_t basedir = R_PointToAngle2(arena->x, arena->y, movingobject->x, movingobject->y);
fixed_t radiusdelta = 0;
const fixed_t minarena = arena->extravalue1 + radiussubtract;
const fixed_t maxarena = arena->extravalue2 - radiussubtract;
mompoint -= basedir;
if (radiusdeltafactor > 0) // for kneecapping the prediction
{
boolean clipped = false;
// Add radius so we can compare against the arena size.
radiusdelta = radius + P_ReturnThrustX(arena, mompoint, magnitude);
if (radiusdelta > maxarena)
{
radiusdelta = maxarena;
clipped = true;
}
else if (radiusdelta < minarena)
{
radiusdelta = minarena;
clipped = true;
}
if (clipped == true && forcegoaround == true)
{
mompoint = (mompoint < ANGLE_180) ? ANGLE_90 : ANGLE_270;
}
// Subtract the radius so it's usable as a delta!
radiusdelta -= radius;
if (radiusdelta)
radiusdelta = FixedDiv(radiusdelta, radiusdeltafactor);
}
radius += (radiusdelta/2); // average...
if (radius > 0)
{
fixed_t sidecomponent = P_ReturnThrustY(arena, mompoint, magnitude);
// percent*(TAU/100)% of circumference = radians*r, so divide by r to reverse that
fixed_t radians = FixedDiv(sidecomponent, radius);
basedir += FixedAngle(FixedDiv(360*radians, M_TAU_FIXED)); // converting to degrees along the way.
}
radius += (radiusdelta/2); // ...and then finalise!
dest[0] = arena->x + P_ReturnThrustX(arena, basedir, radius);
dest[1] = arena->y + P_ReturnThrustY(arena, basedir, radius);
return dest;
}
fixed_t *VS_RandomPointOnArena(mobj_t *arena, fixed_t radiussubtract)
{
static fixed_t dest[2] = {0, 0};
if (P_MobjWasRemoved(arena))
return dest;
const fixed_t minarena = arena->extravalue1 + radiussubtract;
const fixed_t maxarena = arena->extravalue2 - radiussubtract;
angle_t rand1 = FixedAngle(P_RandomKey(PR_MOVINGTARGET, 360)*FRACUNIT);
fixed_t rand2 = P_RandomRange(PR_MOVINGTARGET, minarena/FRACUNIT, maxarena/FRACUNIT)*FRACUNIT;
dest[0] = arena->x + P_ReturnThrustX(arena, rand1, rand2);
dest[1] = arena->y + P_ReturnThrustY(arena, rand1, rand2);
return dest;
}

View file

@ -38,6 +38,7 @@
// SRB2kart
#include "k_kart.h"
#include "k_boss.h"
#include "k_battle.h"
#include "k_color.h"
#include "k_follower.h"
@ -13417,6 +13418,15 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj)
P_InitSkyboxPoint(mobj, mthing);
break;
}
case MT_BOSSARENACENTER:
{
if (!VS_ArenaCenterInit(mobj, mthing))
{
P_RemoveMobj(mobj);
return false;
}
break;
}
case MT_EGGSTATUE:
if (mthing->thing_args[1])
{