Skip to content

Commit

Permalink
Add auto-created docking ports to stations
Browse files Browse the repository at this point in the history
Also, overlays refer to local screens in GetDockScreen
  • Loading branch information
gmoromisato committed Feb 13, 2020
1 parent 58c9c6e commit 83d761e
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 41 deletions.
4 changes: 3 additions & 1 deletion Mammoth/Include/TSE.h
Expand Up @@ -483,6 +483,7 @@ class CSpaceObject

// Docking

virtual void CreateDefaultDockingPorts (void);
virtual CSpaceObject *GetDockedObj (void) const { return NULL; }
virtual CVector GetDockingPortOffset (int iRotation) { return NullVector; }
virtual void OnDocked (CSpaceObject *pObj) { }
Expand Down Expand Up @@ -1306,6 +1307,7 @@ class CSpaceObject
void PaintEffects (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx);
void PaintHighlight (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx);
void PaintTargetHighlight (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx);
void SetAutoCreatedPorts (bool bValue = true) { m_fAutoCreatedPorts = bValue; }
void SetObjectDestructionHook (void) { m_fHookObjectDestruction = true; }
void SetCannotBeHit (void) { m_fCannotBeHit = true; }
void SetCanBounce (void) { m_fCanBounce = true; }
Expand Down Expand Up @@ -1429,7 +1431,7 @@ class CSpaceObject
DWORD m_fHasDockScreenMaybe:1; // TRUE if object has a dock screen for player (may be stale)
DWORD m_fAutoClearDestinationOnGate:1; // TRUE if we should clear the destination when player gates
DWORD m_f3DExtra:1; // TRUE if object is an optional 3D extra
DWORD m_fSpare7:1;
DWORD m_fAutoCreatedPorts:1; // TRUE if we have auto created some docking ports
DWORD m_fSpare8:1;

DWORD m_dwSpare:16;
Expand Down
3 changes: 2 additions & 1 deletion Mammoth/Include/TSEOverlays.h
Expand Up @@ -71,6 +71,7 @@ class COverlay
void PaintMapAnnotations (CMapViewportCtx &Ctx, CG32bitImage &Dest, int x, int y);
bool Paralyzes (CSpaceObject *pSource) const { return m_pType->Paralyzes(); }
void ReadFromStream (SLoadCtx &Ctx);
void SetActive (CSpaceObject &Source, bool bActive = true);
void SetData (const CString &sAttrib, ICCItem *pData) { m_Data.SetData(sAttrib, pData); }
void SetDevice (int iDev) { m_iDevice = iDev; }
bool SetEffectProperty (const CString &sProperty, ICCItem *pValue);
Expand Down Expand Up @@ -147,7 +148,7 @@ class COverlayList
void AccumulateBounds (CSpaceObject *pSource, int iScale, int iRotation, RECT *ioBounds);
bool Damage (CSpaceObject *pSource, SDamageCtx &Ctx);
CString DebugCrashInfo (void) const;
bool FireGetDockScreen (const CSpaceObject *pSource, CDockScreenSys::SSelector *retSelector = NULL) const;
bool FireGetDockScreen (const CSpaceObject *pSource, CDockScreenSys::SSelector *retSelector = NULL, CDesignType **retpLocalScreens = NULL) const;
void FireOnObjDestroyed (CSpaceObject *pSource, const SDestroyCtx &Ctx) const;
void FireOnObjDocked (CSpaceObject *pSource, CSpaceObject *pShip) const;
const CConditionSet &GetConditions (void) const { return m_Conditions; }
Expand Down
3 changes: 2 additions & 1 deletion Mammoth/Include/TSESpaceObjectsImpl.h
Expand Up @@ -1106,6 +1106,7 @@ class CShip : public TSpaceObjectImpl<OBJID_CSHIP>
virtual bool CanThrust (void) const override { return (GetThrust() > 0.0); }
virtual bool ClassCanAttack (void) override { return true; }
virtual void ConsumeFuel (Metric rFuel, CReactorDesc::EFuelUseTypes iUse = CReactorDesc::fuelConsume) override;
virtual void CreateDefaultDockingPorts (void) override;
virtual void DamageExternalDevice (int iDev, SDamageCtx &Ctx) override;
virtual void DeactivateShields (void) override;
virtual CString DebugCrashInfo (void) override;
Expand Down Expand Up @@ -1407,9 +1408,9 @@ class CShip : public TSpaceObjectImpl<OBJID_CSHIP>
DWORD m_fLRSDisabledByNebula:1; // TRUE if LRS is disabled due to environment
DWORD m_fShipCompartment:1; // TRUE if we're part of another ship (m_pDocked is the root ship)
DWORD m_fHasShipCompartments:1; // TRUE if we have ship compartment objects attached
DWORD m_fAutoCreatedPorts:1; // TRUE if we have auto created some docking ports
DWORD m_fNameBlanked:1; // TRUE if name has been blanked; show generic name
DWORD m_fShowMapLabel:1; // TRUE if we should show a map label
DWORD m_fSpare6:1;
DWORD m_fSpare7:1;
DWORD m_fSpare8:1;

Expand Down
5 changes: 4 additions & 1 deletion Mammoth/Include/TSEVersions.h
Expand Up @@ -7,7 +7,7 @@

constexpr DWORD API_VERSION = 48;
constexpr DWORD UNIVERSE_SAVE_VERSION = 38;
constexpr DWORD SYSTEM_SAVE_VERSION = 184;
constexpr DWORD SYSTEM_SAVE_VERSION = 185;

// Uncomment out the following define when building a stable release

Expand Down Expand Up @@ -674,3 +674,6 @@ constexpr DWORD SYSTEM_SAVE_VERSION = 184;
//
// 184: 1.9 Beta 1
// Add m_iHitPoints to COverlay
//
// 185: 1.9 Beta 1
// Move m_fAutoCreatedPorts to CSpaceObject (from CShip)
28 changes: 24 additions & 4 deletions Mammoth/TSE/COverlay.cpp
Expand Up @@ -300,7 +300,7 @@ void COverlay::CreateFromType (COverlayType &Type,
// must excavate it).

if (Type.IsUnderground() && pField->m_iHitPoints > 0)
pField->m_fInactive = true;
pField->SetActive(Source);

// Create painters

Expand Down Expand Up @@ -1354,6 +1354,28 @@ void COverlay::ReadFromStream (SLoadCtx &Ctx)
m_fInactive = ((dwFlags & 0x00000004) ? true : false);
}

void COverlay::SetActive (CSpaceObject &Source, bool bActive)

// SetActive
//
// Set active or inactive

{
if (bActive != !m_fInactive)
{
m_fInactive = !bActive;

// Activating may enable dock screens, so we need to refresh various
// cached flags on the object.

Source.SetEventFlags();

// Refresh bounds, since the overlay may need to be shown.

Source.RefreshBounds();
}
}

bool COverlay::SetCustomProperty (CSpaceObject &SourceObj, const CString &sProperty, ICCItem *pValue)

// SetCustomProperty
Expand Down Expand Up @@ -1422,8 +1444,7 @@ bool COverlay::SetProperty (CSpaceObject &Source, const CString &sName, ICCItem

if (strEquals(sName, PROPERTY_ACTIVE))
{
m_fInactive = pValue->IsNil();
Source.RefreshBounds();
SetActive(Source, !pValue->IsNil());
}
else if (strEquals(sName, PROPERTY_COUNTER))
{
Expand Down Expand Up @@ -1627,4 +1648,3 @@ void COverlay::WriteToStream (IWriteStream *pStream)
dwFlags |= (m_fInactive ? 0x00000004 : 0);
pStream->Write(dwFlags);
}

9 changes: 8 additions & 1 deletion Mammoth/TSE/COverlayList.cpp
Expand Up @@ -300,14 +300,15 @@ COverlay *COverlayList::FindField (DWORD dwID)
return NULL;
}

bool COverlayList::FireGetDockScreen (const CSpaceObject *pSource, CDockScreenSys::SSelector *retSelector) const
bool COverlayList::FireGetDockScreen (const CSpaceObject *pSource, CDockScreenSys::SSelector *retSelector, CDesignType **retpLocalScreens) const

// FireGetDockScreen
//
// Fires <GetDockScreen> event for overlay. If we return TRUE, the caller must
// discard retpData.

{
CDesignType *pBestLocalScreens = NULL;
CDockScreenSys::SSelector BestScreen;
BestScreen.iPriority = -1;

Expand All @@ -328,7 +329,10 @@ bool COverlayList::FireGetDockScreen (const CSpaceObject *pSource, CDockScreenSy
// See if this is better than previous.

else if (OverlayScreen.iPriority > BestScreen.iPriority)
{
BestScreen = OverlayScreen;
pBestLocalScreens = pField->GetType();
}
}
}

Expand All @@ -341,6 +345,9 @@ bool COverlayList::FireGetDockScreen (const CSpaceObject *pSource, CDockScreenSy
if (retSelector)
*retSelector = BestScreen;

if (retpLocalScreens)
*retpLocalScreens = pBestLocalScreens;

return true;
}

Expand Down
51 changes: 22 additions & 29 deletions Mammoth/TSE/CShip.cpp
Expand Up @@ -1283,6 +1283,21 @@ void CShip::ConsumeFuel (Metric rFuel, CReactorDesc::EFuelUseTypes iUse)
}
}

void CShip::CreateDefaultDockingPorts (void)

// CreateDefaultDockingPorts
//
// Called to create docking ports on objects that don't already have them. This
// can be overridden by subclasses to control port position, etc.

{
if (m_DockingPorts.GetPortCount())
return;

m_DockingPorts.InitPorts(this, 4, 48.0 * g_KlicksPerPixel);
m_DockingPorts.SetMaxDockingDist(3);
}

void CShip::CreateExplosion (SDestroyCtx &Ctx)

// CreateExplosion
Expand Down Expand Up @@ -1499,7 +1514,6 @@ ALERROR CShip::CreateFromClass (CSystem &System,
pShip->m_fLRSDisabledByNebula = false;
pShip->m_fShipCompartment = false;
pShip->m_fHasShipCompartments = false;
pShip->m_fAutoCreatedPorts = false;
pShip->m_fNameBlanked = false;
pShip->m_fShowMapLabel = pClass->ShowsMapLabel();

Expand Down Expand Up @@ -5525,7 +5539,12 @@ void CShip::OnReadFromStream (SLoadCtx &Ctx)

bool bBit01 = ((dwLoad & 0x00000001) ? true : false);
m_fRadioactive = ((dwLoad & 0x00000002) ? true : false);
m_fAutoCreatedPorts = ((dwLoad & 0x00000004) ? true : false) && (Ctx.dwVersion >= 155);
if (Ctx.dwVersion >= 155 && Ctx.dwVersion < 185)
{
if (dwLoad & 0x00000004)
SetAutoCreatedPorts(true);
}
// 0x00000004 Unused as of version 185
m_fDestroyInGate = ((dwLoad & 0x00000008) ? true : false);
m_fHalfSpeed = ((dwLoad & 0x00000010) ? true : false);
m_fNameBlanked = ((dwLoad & 0x00000020) ? true : false) && (Ctx.dwVersion >= 155);
Expand Down Expand Up @@ -5947,32 +5966,6 @@ void CShip::OnSetEventFlags (void)
SetHasOnOrderChangedEvent(FindEventHandler(CONSTLIT("OnOrderChanged")));
SetHasOnOrdersCompletedEvent(FindEventHandler(CONSTLIT("OnOrdersCompleted")));
SetHasOnSubordinateAttackedEvent(FindEventHandler(CONSTLIT("OnSubordinateAttacked")));

// See if we have a handler for dock screens.

bool bHasGetDockScreen = HasDockScreen();

// If we have an event for a dock screen, but we don't have docking ports
// then we create some default ports. This is useful for when overlays or
// event handlers create dock screens.

if (bHasGetDockScreen && m_DockingPorts.GetPortCount() == 0)
{
// LATER: Create docking ports based on image size.

m_DockingPorts.InitPorts(this, 4, 48.0 * g_KlicksPerPixel);
m_DockingPorts.SetMaxDockingDist(3);
m_fAutoCreatedPorts = true;
}

// If we DON'T have dock screens and we auto-created some docking ports,
// then we need to remove them.

else if (!bHasGetDockScreen && m_fAutoCreatedPorts)
{
m_DockingPorts.DeleteAll(this);
m_fAutoCreatedPorts = false;
}
}

void CShip::OnStationDestroyed (const SDestroyCtx &Ctx)
Expand Down Expand Up @@ -6096,7 +6089,7 @@ void CShip::OnWriteToStream (IWriteStream *pStream)
dwSave = 0;
dwSave |= (m_fLRSDisabledByNebula ? 0x00000001 : 0);
dwSave |= (m_fRadioactive ? 0x00000002 : 0);
dwSave |= (m_fAutoCreatedPorts ? 0x00000004 : 0);
// 0x00000004 Unused as of 185
dwSave |= (m_fDestroyInGate ? 0x00000008 : 0);
dwSave |= (m_fHalfSpeed ? 0x00000010 : 0);
dwSave |= (m_fNameBlanked ? 0x00000020 : 0);
Expand Down
64 changes: 61 additions & 3 deletions Mammoth/TSE/CSpaceObject.cpp
Expand Up @@ -227,7 +227,8 @@ CSpaceObject::CSpaceObject (CUniverse &Universe) :
m_fCollisionTestNeeded(false),
m_fHasDockScreenMaybe(false),
m_fAutoClearDestinationOnGate(false),
m_f3DExtra(false)
m_f3DExtra(false),
m_fAutoCreatedPorts(false)

// CSpaceObject constructor

Expand Down Expand Up @@ -1103,6 +1104,26 @@ void CSpaceObject::CopyDataFromObj (CSpaceObject *pSource)
m_Data.Copy(pSource->m_Data, Options);
}

void CSpaceObject::CreateDefaultDockingPorts (void)

// CreateDefaultDockingPorts
//
// Called to create docking ports on objects that don't already have them. This
// can be overridden by subclasses to control port position, etc.

{
if (CDockingPorts *pDockingPorts = GetDockingPorts())
{
if (pDockingPorts->GetPortCount() == 0)
{
constexpr int PORT_COUNT = 4;
int iRadius = GetHitSizePixels() / 2;

pDockingPorts->InitPorts(this, PORT_COUNT, iRadius * g_KlicksPerPixel);
}
}
}

CSpaceObject *CSpaceObject::CreateFromClassID (CUniverse &Universe, DWORD dwClass)

// CreateFromClassID
Expand Down Expand Up @@ -1312,6 +1333,7 @@ void CSpaceObject::CreateFromStream (SLoadCtx &Ctx, CSpaceObject **retpObj)
pObj->m_fHasOnOrderChangedEvent = ((dwLoad & 0x00000008) ? true : false);
pObj->m_fManualAnchor = ((dwLoad & 0x00000010) ? true : false);
pObj->m_f3DExtra = ((dwLoad & 0x00000020) ? true : false);
pObj->m_fAutoCreatedPorts = ((dwLoad & 0x00000040) ? true : false);

// No need to save the following

Expand Down Expand Up @@ -3825,6 +3847,8 @@ CDesignType *CSpaceObject::GetFirstDockScreen (CString *retsScreen, ICCItemPtr *
// NOTE: Caller must discard *retpData.

{
CDesignType *pLocalScreens = GetType();

// First see if any global types override this

CDockScreenSys::SSelector Screen;
Expand All @@ -3837,24 +3861,31 @@ CDesignType *CSpaceObject::GetFirstDockScreen (CString *retsScreen, ICCItemPtr *
if (pOverlays = GetOverlays())
{
CDockScreenSys::SSelector OverlayScreen;
if (pOverlays->FireGetDockScreen(this, &OverlayScreen)
CDesignType *pOverlayLocalScreens;
if (pOverlays->FireGetDockScreen(this, &OverlayScreen, &pOverlayLocalScreens)
&& OverlayScreen.iPriority > Screen.iPriority)
{
Screen = OverlayScreen;
pLocalScreens = pOverlayLocalScreens;
}
}

// Next see if we have an event that handles this

CDockScreenSys::SSelector CustomScreen;
if (FireGetDockScreen(&CustomScreen)
&& CustomScreen.iPriority > Screen.iPriority)
{
Screen = CustomScreen;
pLocalScreens = GetType();
}

// If an event has overridden the dock screen, then resolve
// the screen now.

if (Screen.iPriority != -1)
{
CDesignType *pScreen = GetDesign().ResolveDockScreen(GetType(), Screen.sScreen, retsScreen);
CDesignType *pScreen = GetDesign().ResolveDockScreen(pLocalScreens, Screen.sScreen, retsScreen);
if (pScreen)
{
if (retpData)
Expand Down Expand Up @@ -7014,6 +7045,32 @@ void CSpaceObject::SetEventFlags (void)
SetHasOnDamageEvent(FindEventHandler(CONSTLIT("OnDamage")));
SetHasOnObjDockedEvent(FindEventHandler(CONSTLIT("OnObjDocked")));

// See if we have a handler for dock screens.

if (CDockingPorts *pDockingPorts = GetDockingPorts())
{
bool bHasGetDockScreen = HasDockScreen();

// If we have an event for a dock screen, but we don't have docking ports
// then we create some default ports. This is useful for when overlays or
// event handlers create dock screens.

if (bHasGetDockScreen && pDockingPorts->GetPortCount() == 0)
{
CreateDefaultDockingPorts();
m_fAutoCreatedPorts = true;
}

// If we DON'T have dock screens and we auto-created some docking ports,
// then we need to remove them.

else if (!bHasGetDockScreen && m_fAutoCreatedPorts)
{
pDockingPorts->DeleteAll(this);
m_fAutoCreatedPorts = false;
}
}

// Let subclasses do their bit

OnSetEventFlags();
Expand Down Expand Up @@ -7566,6 +7623,7 @@ void CSpaceObject::WriteToStream (IWriteStream *pStream)
dwSave |= (m_fHasOnOrderChangedEvent ? 0x00000008 : 0);
dwSave |= (m_fManualAnchor ? 0x00000010 : 0);
dwSave |= (m_f3DExtra ? 0x00000020 : 0);
dwSave |= (m_fAutoCreatedPorts ? 0x00000040 : 0);
pStream->Write((char *)&dwSave, sizeof(DWORD));

// Write out the opaque data
Expand Down

0 comments on commit 83d761e

Please sign in to comment.