mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
90 lines
2.3 KiB
C++
90 lines
2.3 KiB
C++
// DR. ROBOTNIK'S RING RACERS
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
|
// Copyright (C) 1999-2020 by Sonic Team Junior.
|
|
// Copyright (C) 2024 by Kart Krew.
|
|
//
|
|
// This program is free software distributed under the
|
|
// terms of the GNU General Public License, version 2.
|
|
// See the 'LICENSE' file for more details.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
#include <set>
|
|
|
|
#include "core/static_vec.hpp"
|
|
|
|
#include "doomstat.h" // mapobjectscale
|
|
#include "info.h"
|
|
#include "m_fixed.h"
|
|
#include "p_local.h" // ONFLOORZ
|
|
#include "p_mobj.h"
|
|
#include "p_slopes.h"
|
|
#include "r_defs.h"
|
|
#include "r_main.h"
|
|
|
|
fixed_t P_GetMobjSpawnHeight(
|
|
const mobjtype_t mobjtype,
|
|
const fixed_t x,
|
|
const fixed_t y,
|
|
const fixed_t dz,
|
|
const fixed_t offset,
|
|
const size_t layer,
|
|
const boolean flip,
|
|
const fixed_t scale
|
|
)
|
|
{
|
|
const fixed_t finalScale = FixedMul(scale, mapobjectscale);
|
|
|
|
const fixed_t finalZOffset = flip
|
|
? -(dz) - FixedMul(finalScale, offset + mobjinfo[mobjtype].height)
|
|
: +(dz) + FixedMul(finalScale, offset);
|
|
|
|
const sector_t* sector = R_PointInSubsector(x, y)->sector;
|
|
|
|
// Axis objects snap to the floor.
|
|
if (mobjtype == MT_AXIS || mobjtype == MT_AXISTRANSFER || mobjtype == MT_AXISTRANSFERLINE)
|
|
return ONFLOORZ;
|
|
|
|
if (layer != 0)
|
|
{
|
|
// multiset is a container that automatically sorts
|
|
// each insertion. It only contains unique values, so
|
|
// two FOFs at the exact same height only count as one
|
|
// layer.
|
|
std::multiset<fixed_t> heights;
|
|
|
|
auto get_height = flip ? P_GetFFloorBottomZAt : P_GetFFloorTopZAt;
|
|
|
|
for (ffloor_t* rover = sector->ffloors; rover; rover = rover->next)
|
|
{
|
|
heights.insert(get_height(rover, x, y));
|
|
}
|
|
|
|
if (!heights.empty())
|
|
{
|
|
auto get_layer = [layer, &heights](auto it)
|
|
{
|
|
std::advance(it, std::min(layer, heights.size()) - 1);
|
|
return *it;
|
|
};
|
|
|
|
if (flip)
|
|
{
|
|
return get_layer(heights.rbegin()) + finalZOffset;
|
|
}
|
|
else
|
|
{
|
|
return get_layer(heights.begin()) + finalZOffset;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Establish height.
|
|
if (flip)
|
|
return P_GetSectorCeilingZAt(sector, x, y) + finalZOffset;
|
|
else
|
|
return P_GetSectorFloorZAt(sector, x, y) + finalZOffset;
|
|
}
|