port: CMapOutdoor + PythonBackground + minimap (1:1 40250)
GameLib map/area/terrain units, PRTerrainLib Terrain/TextureSet, PythonBackground(+Module) and ColorTransitionHelper ported verbatim; pending stand-ins and background module stubs removed. Hand edits: BeginEnvironment's pointer tag via uintptr_t, LoadWaterMap reads the file's 32-bit longs. Terrain draw passes stay platform no-ops (Godot draws the terrain). RecordingDevice gains textures, buffers and render targets; orthographic draws become UI commands so CPythonMiniMap's masked tiles show through minimap_image_filter in python_ui_surface. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b69116992c
commit
2ead95756e
@@ -1,342 +0,0 @@
|
||||
// Stand-in for the 40250 logic unit UserInterface/PythonBackground.cpp, not ported yet: the members the ported units
|
||||
// reference, as platform_stub.py stubs. Delete this file in the commit that ports the unit into port/
|
||||
// (docs/PORT-PLAN.md).
|
||||
#include "UserInterface/StdAfx.h"
|
||||
#include "UserInterface/PythonBackground.h"
|
||||
#include "UserInterface/InstanceBase.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
|
||||
#include "../../PlatformStub.h"
|
||||
|
||||
auto CPythonBackground::Destroy() -> void
|
||||
{
|
||||
CMapManager::Destroy();
|
||||
m_bVisibleGuildArea = FALSE;
|
||||
}
|
||||
|
||||
auto CPythonBackground::Create() -> void
|
||||
{
|
||||
CMapManager::Create();
|
||||
}
|
||||
|
||||
auto CPythonBackground::GlobalPositionToLocalPosition(LONG &x, LONG &y) -> void
|
||||
{
|
||||
x -= m_dwBaseX;
|
||||
y -= m_dwBaseY;
|
||||
}
|
||||
|
||||
auto CPythonBackground::LocalPositionToGlobalPosition(LONG &x, LONG &y) -> void
|
||||
{
|
||||
x += m_dwBaseX;
|
||||
y += m_dwBaseY;
|
||||
}
|
||||
|
||||
auto CPythonBackground::RefreshShadowLevel() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::Update(float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::ClearGuildArea() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RegisterGuildArea(int, int, int, int) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::CreateTargetEffect(DWORD, DWORD) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::CreateTargetEffect(DWORD, long, long) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::DeleteTargetEffect(DWORD) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::Warp(DWORD x, DWORD y) -> void
|
||||
{
|
||||
if (m_kVct_kMapInfo.empty())
|
||||
Initialize();
|
||||
auto found = std::find_if(m_kVct_kMapInfo.begin(), m_kVct_kMapInfo.end(),
|
||||
[x, y](const TMapInfo &info) {
|
||||
return x >= info.m_dwBaseX && x < info.m_dwEndX &&
|
||||
y >= info.m_dwBaseY && y < info.m_dwEndY;
|
||||
});
|
||||
if (found == m_kVct_kMapInfo.end()) {
|
||||
TraceError("NOT_FOUND_GLOBAL_POSITION(%u, %u)", x, y);
|
||||
return;
|
||||
}
|
||||
if (!LoadMap(found->m_strName, float(x - found->m_dwBaseX),
|
||||
float(y - found->m_dwBaseY), 0.0f)) {
|
||||
TraceError("CPythonBackground::Warp map load failed: %s", found->m_strName.c_str());
|
||||
return;
|
||||
}
|
||||
m_dwBaseX = found->m_dwBaseX;
|
||||
m_dwBaseY = found->m_dwBaseY;
|
||||
m_strMapName = found->m_strName;
|
||||
}
|
||||
|
||||
auto CPythonBackground::GetWarpMapName() -> const char *
|
||||
{
|
||||
return m_strMapName.c_str();
|
||||
}
|
||||
|
||||
CPythonBackground::CPythonBackground()
|
||||
{
|
||||
m_eViewDistanceNum=0;
|
||||
m_dwBaseX=0;
|
||||
m_dwBaseY=0;
|
||||
m_bVisibleGuildArea=FALSE;
|
||||
m_iXMasTreeGrade=0;
|
||||
}
|
||||
|
||||
CPythonBackground::~CPythonBackground()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
// 40250 PythonBackground.cpp:547-608, verbatim. No map objects are registered with CCullingManager until
|
||||
// CMapOutdoor is ported, so the checkers see no opponent and advancing is never blocked.
|
||||
struct CollisionChecker
|
||||
{
|
||||
bool isBlocked;
|
||||
CInstanceBase* pInstance;
|
||||
CollisionChecker(CInstanceBase* pInstance) : pInstance(pInstance), isBlocked(false) {}
|
||||
void operator () (CGraphicObjectInstance* pOpponent)
|
||||
{
|
||||
if (isBlocked)
|
||||
return;
|
||||
|
||||
if (!pOpponent)
|
||||
return;
|
||||
|
||||
if (pInstance->IsBlockObject(*pOpponent))
|
||||
isBlocked=true;
|
||||
}
|
||||
};
|
||||
|
||||
struct CollisionAdjustChecker
|
||||
{
|
||||
bool isBlocked;
|
||||
CInstanceBase* pInstance;
|
||||
CollisionAdjustChecker(CInstanceBase* pInstance) : pInstance(pInstance), isBlocked(false) {}
|
||||
void operator () (CGraphicObjectInstance* pOpponent)
|
||||
{
|
||||
if (!pOpponent)
|
||||
return;
|
||||
|
||||
if (pInstance->AvoidObject(*pOpponent))
|
||||
isBlocked=true;
|
||||
}
|
||||
};
|
||||
|
||||
bool CPythonBackground::CheckAdvancing(CInstanceBase * pInstance)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return true;
|
||||
|
||||
Vector3d center;
|
||||
float radius;
|
||||
pInstance->GetGraphicThingInstanceRef().GetBoundingSphere(center,radius);
|
||||
|
||||
CCullingManager & rkCullingMgr = CCullingManager::Instance();
|
||||
|
||||
CollisionAdjustChecker kCollisionAdjustChecker(pInstance);
|
||||
rkCullingMgr.ForInRange(center, radius, &kCollisionAdjustChecker);
|
||||
if (kCollisionAdjustChecker.isBlocked)
|
||||
{
|
||||
CollisionChecker kCollisionChecker(pInstance);
|
||||
rkCullingMgr.ForInRange(center, radius, &kCollisionChecker);
|
||||
if (kCollisionChecker.isBlocked)
|
||||
{
|
||||
pInstance->BlockMovement();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pInstance->NEW_MoveToDestPixelPositionDirection(pInstance->NEW_GetDstPixelPositionRef());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// 40250 CMapOutdoor::__PickTerrainHeight (MapOutdoor.cpp:448), marching the ray against the terrain height.
|
||||
// PORT: CMapOutdoor is not ported; the terrain is the native CMapManager height map, and GetTerrainNum/
|
||||
// GetTerrainPointer become "the map is ready" (GetHeight reads the height tile under the point).
|
||||
bool PickTerrainHeight(CMapManager& rkMap, float& fPos, const D3DXVECTOR3& v3Start, const D3DXVECTOR3& v3End, float fStep,
|
||||
float fRayRange, float fLimitRange, D3DXVECTOR3* pv3Pick)
|
||||
{
|
||||
D3DXVECTOR3 v3CurPos;
|
||||
|
||||
float fRayRangeInv=1.0f/fRayRange;
|
||||
while (fPos < fRayRange && fPos<fLimitRange)
|
||||
{
|
||||
D3DXVec3Lerp(&v3CurPos, &v3Start, &v3End, fPos*fRayRangeInv);
|
||||
float fMultiplier = 1.0f;
|
||||
if (rkMap.IsMapReady())
|
||||
{
|
||||
// PORT: PR_FLOAT_TO_INT is x87 fistp (round to nearest) corrected down, i.e. floor.
|
||||
int ix = int(std::floor(v3CurPos.x)), iy = int(std::floor(fabs(v3CurPos.y)));
|
||||
float fMapHeight = rkMap.GetHeight(float(ix), float(iy));
|
||||
if ( fMapHeight >= v3CurPos.z)
|
||||
{
|
||||
*pv3Pick = v3CurPos;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fMultiplier = fMAX(1.0f, 0.01f * ( v3CurPos.z - fMapHeight ) );
|
||||
}
|
||||
}
|
||||
fPos += fStep * fMultiplier;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 40250 CMapOutdoor::GetPickingPointWithRayOnlyTerrain (MapOutdoor.cpp:549).
|
||||
bool CPythonBackground::GetPickingPointWithRayOnlyTerrain(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt)
|
||||
{
|
||||
bool bTerrainPick = false;
|
||||
D3DXVECTOR3 v3TerrainPick;
|
||||
|
||||
D3DXVECTOR3 v3Start, v3End, v3Dir;
|
||||
float fRayRange;
|
||||
rRay.GetStartPoint(&v3Start);
|
||||
rRay.GetDirection(&v3Dir, &fRayRange);
|
||||
rRay.GetEndPoint(&v3End);
|
||||
|
||||
float fPos = 0.0f;
|
||||
bTerrainPick=true;
|
||||
if (!PickTerrainHeight(*this, fPos, v3Start, v3End, 5.0f, fRayRange, 5000.0f, &v3TerrainPick))
|
||||
if (!PickTerrainHeight(*this, fPos, v3Start, v3End, 10.0f, fRayRange, 10000.0f, &v3TerrainPick))
|
||||
if (!PickTerrainHeight(*this, fPos, v3Start, v3End, 100.0f, fRayRange, 100000.0f, &v3TerrainPick))
|
||||
bTerrainPick=false;
|
||||
|
||||
if (bTerrainPick)
|
||||
{
|
||||
*v3IntersectPt = v3TerrainPick;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 40250 CMapOutdoor::GetPickingPointWithRay (MapOutdoor.cpp:484).
|
||||
// PORT: the object pick (FGetPickingPoint over CCullingManager) needs CMapOutdoor's area objects; only the
|
||||
// terrain half runs until the map is ported.
|
||||
bool CPythonBackground::GetPickingPointWithRay(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt)
|
||||
{
|
||||
return GetPickingPointWithRayOnlyTerrain(rRay, v3IntersectPt);
|
||||
}
|
||||
|
||||
// 40250 PythonBackground.cpp:173 (CPythonApplication::RenderGame's SetPerspective); m_pkMap stays null
|
||||
// until the map is ported, so this is the 50000 far clip.
|
||||
float CPythonBackground::GetFarClip()
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return 50000.0f;
|
||||
|
||||
if (m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip==0.0f)
|
||||
{
|
||||
TraceError("CPythonBackground::GetFarClip m_eViewDistanceNum=%d", m_eViewDistanceNum);
|
||||
m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip=25600.0f;
|
||||
}
|
||||
|
||||
return m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip;
|
||||
}
|
||||
|
||||
auto CPythonBackground::Render() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderAfterLensFlare() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderBeforeLensFlare() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderCharacterShadowToTexture() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderCloud() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderEffect() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderPCBlocker() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderSky() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderSnow() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderWater() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::SetBackgroundDirLight() -> void
|
||||
{
|
||||
if (!IsMapReady() || !mc_pcurEnvironmentData)
|
||||
return;
|
||||
STATEMANAGER.SetLight(0, &mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND]);
|
||||
}
|
||||
|
||||
auto CPythonBackground::SetCharacterDirLight() -> void
|
||||
{
|
||||
if (!IsMapReady() || !mc_pcurEnvironmentData)
|
||||
return;
|
||||
STATEMANAGER.SetLight(0, &mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_CHARACTER]);
|
||||
}
|
||||
|
||||
void CPythonBackground::Initialize()
|
||||
{
|
||||
std::string atlas(LocaleService_GetLocalePath());
|
||||
atlas += "/AtlasInfo.txt";
|
||||
SetAtlasInfoFileName(atlas.c_str());
|
||||
CMapManager::Initialize();
|
||||
}
|
||||
|
||||
// 40250 PythonBackground.cpp:263 → CMapOutdoor::GetPickingPoint (MapOutdoor.cpp:443): the cursor ray.
|
||||
bool CPythonBackground::GetPickingPoint(D3DXVECTOR3 * v3IntersectPt)
|
||||
{
|
||||
return GetPickingPointWithRay(ms_Ray, v3IntersectPt);
|
||||
}
|
||||
@@ -21,3 +21,14 @@ auto CPythonSystem::IsShowDamage() -> bool
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CPythonSystem::GetShadowLevel() -> int
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
}
|
||||
|
||||
auto CPythonSystem::SetSoftwareTiling(bool isEnable) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user