Implemented functionality for editing, creating, and deleting script object links

This commit is contained in:
parax0
2016-03-06 17:44:51 -07:00
parent 984d9cf3f3
commit 8f82dcbdd9
33 changed files with 805 additions and 219 deletions

View File

@@ -0,0 +1,128 @@
#ifndef CLINK_H
#define CLINK_H
#include "CScriptObject.h"
#include "Core/Resource/CGameArea.h"
#include <Common/TString.h>
#include <Common/types.h>
struct SState
{
u32 ID;
TString Name;
SState() {}
SState(u32 _ID, const TString& rkName) : ID(_ID), Name(rkName) {}
};
struct SMessage
{
u32 ID;
TString Name;
SMessage() {}
SMessage(u32 _ID, const TString& rkName) : ID(_ID), Name(rkName) {}
};
class CLink
{
CGameArea *mpArea;
u32 mStateID;
u32 mMessageID;
u32 mSenderID;
u32 mReceiverID;
public:
CLink(CGameArea *pArea)
: mpArea(pArea)
, mStateID(-1)
, mMessageID(-1)
, mSenderID(-1)
, mReceiverID(-1)
{}
CLink(CGameArea *pArea, u32 StateID, u32 MessageID, u32 SenderID, u32 ReceiverID)
: mpArea(pArea)
, mStateID(StateID)
, mMessageID(MessageID)
, mSenderID(SenderID)
, mReceiverID(ReceiverID)
{}
void SetSender(u32 NewSenderID, u32 Index = -1)
{
u32 OldSenderID = mSenderID;
CScriptObject *pOldSender = mpArea->GetInstanceByID(OldSenderID);
CScriptObject *pNewSender = mpArea->GetInstanceByID(NewSenderID);
mSenderID = NewSenderID;
pOldSender->RemoveLink(eOutgoing, this);
pNewSender->AddLink(eOutgoing, this, Index);
}
void SetReceiver(u32 NewReceiverID, u32 Index = -1)
{
u32 OldReceiverID = mSenderID;
CScriptObject *pOldReceiver = mpArea->GetInstanceByID(OldReceiverID);
CScriptObject *pNewReceiver = mpArea->GetInstanceByID(NewReceiverID);
mReceiverID = NewReceiverID;
pOldReceiver->RemoveLink(eIncoming, this);
pNewReceiver->AddLink(eIncoming, this, Index);
}
u32 SenderIndex() const
{
CScriptObject *pSender = mpArea->GetInstanceByID(mSenderID);
for (u32 iLink = 0; iLink < pSender->NumLinks(eOutgoing); iLink++)
{
if (pSender->Link(eOutgoing, iLink) == this)
return iLink;
}
return -1;
}
u32 ReceiverIndex() const
{
CScriptObject *pReceiver = mpArea->GetInstanceByID(mReceiverID);
for (u32 iLink = 0; iLink < pReceiver->NumLinks(eIncoming); iLink++)
{
if (pReceiver->Link(eIncoming, iLink) == this)
return iLink;
}
return -1;
}
// Operators
bool operator==(const CLink& rkOther)
{
return ( (mpArea == rkOther.mpArea) &&
(mStateID == rkOther.mStateID) &&
(mMessageID == rkOther.mMessageID) &&
(mSenderID == rkOther.mSenderID) &&
(mReceiverID == rkOther.mReceiverID) );
}
bool operator!=(const CLink& rkOther)
{
return (!(*this == rkOther));
}
// Accessors
u32 State() const { return mStateID; }
u32 Message() const { return mMessageID; }
u32 SenderID() const { return mSenderID; }
u32 ReceiverID() const { return mReceiverID; }
CScriptObject* Sender() const { return mpArea->GetInstanceByID(mSenderID); }
CScriptObject* Receiver() const { return mpArea->GetInstanceByID(mReceiverID); }
void SetState(u32 StateID) { mStateID = StateID; }
void SetMessage(u32 MessageID) { mMessageID = MessageID; }
};
#endif // CLINK_H

View File

@@ -2,7 +2,7 @@
#define CMASTERTEMPLATE_H
#include "CScriptTemplate.h"
#include "SLink.h"
#include "CLink.h"
#include "Core/Resource/EGame.h"
#include <Common/types.h>
#include <map>

View File

@@ -21,6 +21,10 @@ CScriptObject::~CScriptObject()
{
if (mpProperties) delete mpProperties;
mpTemplate->RemoveObject(this);
// Note: Incoming links will be deleted by the sender.
for (u32 iLink = 0; iLink < mOutLinks.size(); iLink++)
delete mOutLinks[iLink];
}
// ************ DATA MANIPULATION ************
@@ -94,17 +98,17 @@ bool CScriptObject::HasNearVisibleActivation() const
if (mIsCheckingNearVisibleActivation) return false;
mIsCheckingNearVisibleActivation = true;
for (u32 iLink = 0; iLink < mInConnections.size(); iLink++)
for (u32 iLink = 0; iLink < mInLinks.size(); iLink++)
{
const SLink& rkLink = mInConnections[iLink];
CLink *pLink = mInLinks[iLink];
// Check for trigger activation
if (rkLink.State == 0x49533034 || rkLink.State == 0x49533035 || rkLink.State == 0x49533036) // "IS04", "IS05", or "IS06"
if (pLink->State() == 0x49533034 || pLink->State() == 0x49533035 || pLink->State() == 0x49533036) // "IS04", "IS05", or "IS06"
{
if ( (!IsRelay && rkLink.Message == 0x41435456) || // "ACTV"
(IsRelay && rkLink.Message == 0x4143544E) ) // "ACTN"
if ( (!IsRelay && pLink->Message() == 0x41435456) || // "ACTV"
(IsRelay && pLink->Message() == 0x4143544E) ) // "ACTN"
{
CScriptObject *pObj = mpArea->GetInstanceByID(rkLink.ObjectID);
CScriptObject *pObj = pLink->Sender();
if (pObj->ObjectTypeID() == 0x54524752) // "TRGR"
{
@@ -115,12 +119,12 @@ bool CScriptObject::HasNearVisibleActivation() const
}
// Check for relay activation
else if (rkLink.State == 0x524C4159) // "RLAY"
else if (pLink->State() == 0x524C4159) // "RLAY"
{
if ( (!IsRelay && rkLink.Message == 0x41435456) || // "ACTV"
(IsRelay && rkLink.Message == 0x4143544E) ) // "ACTN"
if ( (!IsRelay && pLink->Message() == 0x41435456) || // "ACTV"
(IsRelay && pLink->Message() == 0x4143544E) ) // "ACTN"
{
CScriptObject *pObj = mpArea->GetInstanceByID(rkLink.ObjectID);
CScriptObject *pObj = pLink->Sender();
if (pObj->ObjectTypeID() == 0x53524C59) // "SRLY"
Relays.push_back(pObj);
@@ -198,24 +202,42 @@ u32 CScriptObject::InstanceID() const
return mInstanceID;
}
u32 CScriptObject::NumInLinks() const
u32 CScriptObject::NumLinks(ELinkType Type) const
{
return mInConnections.size();
return (Type == eIncoming ? mInLinks.size() : mOutLinks.size());
}
u32 CScriptObject::NumOutLinks() const
CLink* CScriptObject::Link(ELinkType Type, u32 Index) const
{
return mOutConnections.size();
return (Type == eIncoming ? mInLinks[Index] : mOutLinks[Index]);
}
const SLink& CScriptObject::InLink(u32 index) const
void CScriptObject::AddLink(ELinkType Type, CLink *pLink, u32 Index /*= -1*/)
{
return mInConnections[index];
std::vector<CLink*> *pLinkVec = (Type == eIncoming ? &mInLinks : &mOutLinks);
if (Index == -1 || Index == pLinkVec->size())
pLinkVec->push_back(pLink);
else
{
auto it = pLinkVec->begin();
std::advance(it, Index);
pLinkVec->insert(it, pLink);
}
}
const SLink& CScriptObject::OutLink(u32 index) const
void CScriptObject::RemoveLink(ELinkType Type, CLink *pLink)
{
return mOutConnections[index];
std::vector<CLink*> *pLinkVec = (Type == eIncoming ? &mInLinks : &mOutLinks);
for (auto it = pLinkVec->begin(); it != pLinkVec->end(); it++)
{
if (*it == pLink)
{
pLinkVec->erase(it);
break;
}
}
}
TString CScriptObject::InstanceName() const

View File

@@ -1,7 +1,6 @@
#ifndef CSCRIPTOBJECT_H
#define CSCRIPTOBJECT_H
#include "SLink.h"
#include "IProperty.h"
#include "IPropertyTemplate.h"
#include "CScriptTemplate.h"
@@ -10,6 +9,13 @@
#include "Core/Resource/CGameArea.h"
class CScriptLayer;
class CLink;
enum ELinkType
{
eIncoming,
eOutgoing
};
class CScriptObject
{
@@ -22,8 +28,8 @@ class CScriptObject
u32 mVersion;
u32 mInstanceID;
std::vector<SLink> mOutConnections;
std::vector<SLink> mInConnections;
std::vector<CLink*> mOutLinks;
std::vector<CLink*> mInLinks;
CPropertyStruct *mpProperties;
TStringProperty *mpInstanceName;
@@ -67,10 +73,11 @@ public:
IProperty* PropertyByIDString(const TIDString& str) const;
u32 ObjectTypeID() const;
u32 InstanceID() const;
u32 NumInLinks() const;
u32 NumOutLinks() const;
const SLink& InLink(u32 index) const;
const SLink& OutLink(u32 index) const;
u32 NumLinks(ELinkType Type) const;
CLink* Link(ELinkType Type, u32 Index) const;
void AddLink(ELinkType Type, CLink *pLink, u32 Index = -1);
void RemoveLink(ELinkType Type, CLink *pLink);
CVector3f Position() const;
CVector3f Rotation() const;

View File

@@ -1,32 +0,0 @@
#ifndef SLINK_H
#define SLINK_H
#include <Common/TString.h>
#include <Common/types.h>
struct SState
{
u32 ID;
TString Name;
SState() {}
SState(u32 _ID, const TString& rkName) : ID(_ID), Name(rkName) {}
};
struct SMessage
{
u32 ID;
TString Name;
SMessage() {}
SMessage(u32 _ID, const TString& rkName) : ID(_ID), Name(rkName) {}
};
struct SLink
{
u32 State;
u32 Message;
u32 ObjectID; // not a pointer because it can refer to objects outside the current area
};
#endif // SLINK_H