Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 43 additions & 3 deletions Mammoth/Include/TSETopology.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class CTopologyNode
CTopologyNode *GetStargateDest (int iIndex, CString *retsEntryPoint = NULL) const;
ICCItemPtr GetStargateProperty (const CString &sName, const CString &sProperty) const;
void GetStargateRouteDesc (int iIndex, SStargateRouteDesc *retRouteDesc) const;
CString GetStargateName (int iIndex) const { return m_NamedGates.GetKey(iIndex); }
CSystem *GetSystem (void) { return m_pSystem; }
DWORD GetSystemID (void) { return m_dwID; }
const CString &GetSystemName (void) const { return m_sName; }
Expand All @@ -127,6 +128,7 @@ class CTopologyNode
bool IsMarked (void) const { return m_bMarked; }
bool IsNull (void) const { return (m_SystemUNID == 0 || IsEndGame()); }
bool IsPositionKnown (void) const { return (m_bKnown || m_bPosKnown); }
bool MatchesStargateAttribs (const CString &sName, const CString &sMatch) const;
void SetCalcDistance (int iDist) const { m_iCalcDistance = iDist; }
void SetCreatorID (const CString &sID) { m_sCreatorID = sID; }
void SetData (const CString &sAttrib, ICCItem *pData) { m_Data.SetData(sAttrib, pData); }
Expand Down Expand Up @@ -189,6 +191,8 @@ class CTopologyNode
mutable CTopologyNode *pDestNode = NULL; // Cached for efficiency (may be NULL)
};

bool MatchesStargateAttribs (const CTopologyNode::SStargateEntry* pGate, const CString &sMatch) const;

CTopology &m_Topology; // Topology that we're a part of
CString m_sID; // ID of node
CString m_sCreatorID; // ID of topology desc, if created by a fragment, etc.
Expand Down Expand Up @@ -385,6 +389,7 @@ class CTopology
{
public:
static const int UNKNOWN_DISTANCE = -1;
static const int BLOCKED_DISTANCE = -2;

struct SNodeCreateCtx
{
Expand Down Expand Up @@ -427,11 +432,46 @@ class CTopology
const CTopologyNode *FindTopologyNode (const CString &sID) const;
CTopologyNode *FindTopologyNode (const CString &sID);
CString GenerateUniquePrefix (const CString &sPrefix, const CString &sTestNodeID);
int GetDistance (const CTopologyNode *pSrc, const CTopologyNode *pTarget) const;
int GetDistance (const CString &sSourceID, const CString &sDestID) const;
int GetDistance (
const CTopologyNode *pSrc,
const CTopologyNode *pTarget,
const CString &sGateCriteria = NULL_STR,
const TArray<CString> &aUseNodes = TArray<CString>(),
const TArray<CString> &aBlockNodes = TArray<CString>(),
bool bIgnoreOneWay = true,
bool bAllowUseNodeBacktrack = true) const;
int GetDistance (
const CString &sSourceID,
const CString &sDestID,
const CString &sGateCriteria = NULL_STR,
const TArray<CString> &aUseNodes = TArray<CString>(),
const TArray<CString> &aBlockNodes = TArray<CString>(),
bool bIgnoreOneWay = true,
bool bAllowUseNodeBacktrack = true) const;
int GetDistanceToCriteria (const CTopologyNode *pSrc, const CTopologyAttributeCriteria &Criteria) const;
int GetDistanceToCriteriaNoMatch (const CTopologyNode *pSrc, const CTopologyAttributeCriteria &Criteria) const;
const CTopologyNode *GetNextNodeTo (const CTopologyNode &From, const CTopologyNode &To) const;
const CTopologyNode *GetNextNodeTo (
const CTopologyNode &From,
const CTopologyNode &To,
const CString &sGateCriteria = NULL_STR,
const TArray<CString> &aUseNodes = TArray<CString>(),
const TArray<CString> &aBlockNodes = TArray<CString>(),
bool bIgnoreOneWay = true,
bool bAllowUseNodeBacktrack = true) const;
const TArray<const CTopologyNode*> GetPathTo (
const CTopologyNode *pSrc,
const CTopologyNode *pTarget,
const CString &sGateCriteria = NULL_STR,
const TArray<CString> &aUseNodes = TArray<CString>(),
const TArray<CString> &aBlockNodes = TArray<CString>(),
bool bIgnoreOneWay = true,
bool bAllowUseNodeBacktrack = true) const;
const TArray<const CTopologyNode*> GetPathTo (
const CTopologyNode *pSrc,
const CTopologyNode *pTarget,
const CString &sGateCriteria = NULL_STR,
const TArray<CString> &aBlockNodes = TArray<CString>(),
bool bIgnoreOneWay = true) const;
CTopologyNodeList &GetTopologyNodeList (void) { return m_Topology; }
CTopologyNode *GetTopologyNode (int iIndex) { return &m_Topology[iIndex]; }
const CTopologyNode *GetTopologyNode (int iIndex) const { return &m_Topology[iIndex]; }
Expand Down
13 changes: 13 additions & 0 deletions Mammoth/Include/TSEVersions.h
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,19 @@ constexpr DWORD SYSTEM_SAVE_VERSION = 215;
// Returns a list of static datakeys for the given obj type
// (scr@Keys type)
// Returns a list of all instance property and custom global property keys for the given obj
// (sysGetNextNodeTo [srcNode] destNode [options])
// Accepts an options struct now
// options:
// blockNodes (list): do not path through these nodes
// respectOneWayGates (bool): if pathing must obey the directionality of one way gates (default: false)
// gateCriteria (string): criteria to match against stargate topology attributes (not the stations)
// useNodes (list): these nodes must be pathed through
// (sysGetPathTo [srcNode] destNode [options])
// options:
// blockNodes (list): do not path through these nodes
// respectOneWayGates (bool): if pathing must obey the directionality of one way gates (default: false)
// gateCriteria (string): criteria to match against stargate topology attributes (not the stations)
// useNodes (list): these nodes must be pathed through
// <ItemType>
// <Weapon>
// damage: (str: damage desc)
Expand Down
126 changes: 118 additions & 8 deletions Mammoth/TSE/CCExtensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ ICCItem *fnSystemAddStationTimerEvent (CEvalContext *pEvalCtx, ICCItem *pArgs, D
#define FN_SYS_ADD_STARGATE_TOPOLOGY_COLORED 44
#define FN_SYS_STARGATE_HAS_ATTRIBUTE 45
#define FN_SYS_GET_DATA_KEYS 46
#define FN_SYS_PATH_TO 47

#define OPT_SYS_ADD_STARGATE_TOPOLOGY_COLOR CONSTLIT("color")
#define OPT_SYS_ADD_STARGATE_ATTRIBUTES CONSTLIT("attributes")
Expand Down Expand Up @@ -3377,8 +3378,16 @@ static PRIMITIVEPROCDEF g_Extensions[] =
"iiii", 0, },

{ "sysGetNextNodeTo", fnSystemGet, FN_SYS_NEXT_NODE_TO,
"(sysGetNextNodeTo [fromNodeID] toNodeID) -> nodeID",
"*s", 0, },
"(sysGetNextNodeTo [fromNodeID] toNodeID [options]) -> nodeID\n\n"

"options (struct):\n\n"

" respectOneWayGates: Respects directionality of one-way gates when pathing through them. Does not respect one-way gates by default.\n"
" gateCriteria: Only gates that match criteria can be used for the path calculations\n"
" useNodes: A list of nodes that must be included in the path calculations\n"
" blockNodes: A list of nodes that cannot be included in the path calculations\n",

"*", 0, },

{ "sysGetNode", fnSystemGet, FN_SYS_NODE,
"(sysGetNode) -> nodeID",
Expand All @@ -3400,6 +3409,18 @@ static PRIMITIVEPROCDEF g_Extensions[] =
"(sysGetObjectByName [source] name) -> obj",
"*s", 0, },

{ "sysGetPathTo", fnSystemGet, FN_SYS_PATH_TO,
"(sysGetPathTo [fromNodeID] toNodeID [options]) -> nodeID\n\n"

"options (struct):\n\n"

" respectOneWayGates: Respects directionality of one-way gates when pathing through them. Does not respect one-way gates by default.\n"
" gateCriteria: Only gates that match criteria can be used for the path calculations\n"
" useNodes: A list of nodes that must be included in the path calculations\n"
" blockNodes: A list of nodes that cannot be included in the path calculations\n",

"*", 0, },

{ "sys@", fnSystemGet, FN_SYS_GET_PROPERTY,
"(sys@ [nodeID] property) -> value\n\n"

Expand Down Expand Up @@ -14559,20 +14580,26 @@ ICCItem *fnSystemGet (CEvalContext *pEvalCtx, ICCItem *pArgs, DWORD dwData)
return pCC->CreateInteger(iFreq);
}

case FN_SYS_PATH_TO:
case FN_SYS_NEXT_NODE_TO:
{
int iArg = 0;

// If we have more than 1 args, then the first arg is the fromID
// If we have 2 args and the last is not the option structs,
// or we have 3 args, then the first arg is the fromID

const CTopologyNode *pFromNode;
if (pArgs->GetCount() > 1 && pArgs->GetElement(0)->IsIdentifier())
if ((pArgs->GetCount() == 2 && pArgs->GetElement(0)->IsIdentifier() && !pArgs->GetElement(1)->IsSymbolTable())
|| pArgs->GetCount() == 3)
{
pFromNode = pCtx->GetUniverse().FindTopologyNode(pArgs->GetElement(iArg++)->GetStringValue());
if (pFromNode == NULL)
return pCC->CreateError(CONSTLIT("Invalid nodeID"), pArgs->GetElement(0));
}

else if (pArgs->GetCount() > 3)
return pCC->CreateError(CONSTLIT("Too many args"), pArgs);

// Otherwise, we assume the current system.

else
Expand All @@ -14592,13 +14619,96 @@ ICCItem *fnSystemGet (CEvalContext *pEvalCtx, ICCItem *pArgs, DWORD dwData)
if (pToNode == NULL)
return pCC->CreateError(CONSTLIT("Invalid nodeID"), pArgs->GetElement(iArg - 1));

// Check if there is an options arg

ICCItem *pOptions = pArgs->GetElement(iArg++);

TArray<CString> aUseNodes;
TArray<CString> aBlockNodes;
CString sGateCriteria;
bool bRespectOneWayGates;

if (pOptions)
{
// We only accept a struct for options

if (pOptions->IsSymbolTable())
{
// By default we do not respect one way gates (this is legacy behavior)

bRespectOneWayGates = pOptions->GetBooleanAt(CONSTLIT("respectOneWayGates"));

// Empty gate criteria is ignored

sGateCriteria = pOptions->GetStringAt(CONSTLIT("gateCriteria"));

// list of node IDs to use

ICCItem* pUseNodes = pOptions->GetElement(CONSTLIT("useNodes"));
if (pUseNodes)
{
if (pUseNodes->IsList())
{
aUseNodes.InsertEmpty(pUseNodes->GetCount());

for (int i = 0; i < pUseNodes->GetCount(); i++)
aUseNodes[i] = pUseNodes->GetElement(i)->GetStringValue();
}

// otherwise we assume its just one node name

else
aUseNodes.Insert(pUseNodes->GetStringValue());
}

// list of node IDs to avoid

ICCItem* pBlockNodes = pOptions->GetElement(CONSTLIT("blockNodes"));
if (pBlockNodes)
{
if (pBlockNodes->IsList())
{
aBlockNodes.InsertEmpty(pBlockNodes->GetCount());

for (int i = 0; i < pBlockNodes->GetCount(); i++)
aBlockNodes[i] = pBlockNodes->GetElement(i)->GetStringValue();
}

// otherwise we assume its just one node name

else
aBlockNodes.Insert(pBlockNodes->GetStringValue());
}
}

// Otherwise this is invalid

else
return pCC->CreateError(CONSTLIT("Invalid options, must be a struct"), pOptions);
}

// Compute

const CTopologyNode *pNextNode = pCtx->GetUniverse().GetTopology().GetNextNodeTo(*pFromNode, *pToNode);
if (!pNextNode)
return pCC->CreateNil();
if (dwData == FN_SYS_NEXT_NODE_TO)
{
const CTopologyNode *pNextNode = pCtx->GetUniverse().GetTopology().GetNextNodeTo(*pFromNode, *pToNode, sGateCriteria, aUseNodes, aBlockNodes, !bRespectOneWayGates);
if (!pNextNode)
return pCC->CreateNil();

return pCC->CreateString(pNextNode->GetID());
return pCC->CreateString(pNextNode->GetID());
}
else
{
ICCItem *pList = pCC->CreateLinkedList();

TArray<const CTopologyNode *> aPath;
aPath = pCtx->GetUniverse().GetTopology().GetPathTo(pFromNode, pToNode, sGateCriteria, aUseNodes, aBlockNodes, !bRespectOneWayGates);

for (int i = 0; i < aPath.GetCount(); i++)
pList->AppendString(aPath[i]->GetID());

return pList;
}
}

case FN_SYS_LOCATIONS:
Expand Down
Loading