You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
5.2 KiB
207 lines
5.2 KiB
5 years ago
|
#include "cAutomata.h"
|
||
|
|
||
|
|
||
|
cAuto_Node::cAuto_Node()
|
||
|
{
|
||
|
pos = { 0,0 };
|
||
|
}
|
||
|
|
||
|
cAuto_Node::cAuto_Node(const olc::vf2d &worldpos)
|
||
|
{
|
||
|
pos = worldpos;
|
||
|
}
|
||
|
|
||
|
olc::vf2d cAuto_Track::GetPostion(float t, cAuto_Node *pStart)
|
||
|
{
|
||
|
// pStart indicates the node the automata first encounted this track
|
||
|
if (node[0] == pStart)
|
||
|
{
|
||
|
return node[0]->pos + (node[1]->pos - node[0]->pos) * (t / fTrackLength);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return node[1]->pos + (node[0]->pos - node[1]->pos) * (t / fTrackLength);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
cAuto_Body::cAuto_Body()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
cAuto_Body::~cAuto_Body()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
void cAuto_Body::UpdateAuto(float fElapsedTime)
|
||
|
{
|
||
|
// Work out which node is the target destination
|
||
|
cAuto_Node *pExitNode = pCurrentTrack->node[0];
|
||
|
if (pExitNode == pTrackOriginNode)
|
||
|
pExitNode = pCurrentTrack->node[1];
|
||
|
|
||
|
bool bAutomataCanMove = true;
|
||
|
|
||
|
float fDistanceToAutoInFront = 1.0f;
|
||
|
|
||
|
// First check if the vehicle overlaps with the one in front of it
|
||
|
|
||
|
// Get an iterator for this automata
|
||
|
auto itThisAutomata = std::find(pCurrentTrack->listAutos.begin(), pCurrentTrack->listAutos.end(), this);
|
||
|
|
||
|
// If this automata is at the front of this track segment
|
||
|
if (*itThisAutomata == pCurrentTrack->listAutos.front())
|
||
|
{
|
||
|
// Then check all the following track segments. Take the position of
|
||
|
// each vehicle at the back of the track segments auto list
|
||
|
for (auto &track : pExitNode->listTracks)
|
||
|
{
|
||
|
if (track != pCurrentTrack && !track->listAutos.empty())
|
||
|
{
|
||
|
// Get Auto at back
|
||
|
float fDistanceFromTrackStartToAutoRear = track->listAutos.back()->fAutoPos - track->listAutos.back()->fAutoLength;
|
||
|
|
||
|
if ((*itThisAutomata)->fAutoPos < (pCurrentTrack->fTrackLength + fDistanceFromTrackStartToAutoRear - fAutoLength))
|
||
|
{
|
||
|
// Move Automata along track, as there is space
|
||
|
//bAutomataCanMove = true;
|
||
|
fDistanceToAutoInFront = (pCurrentTrack->fTrackLength + fDistanceFromTrackStartToAutoRear - 0.1f) - (*itThisAutomata)->fAutoPos;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// No space, so do not move automata
|
||
|
bAutomataCanMove = false;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Track in front was empty, node is clear to pass through so
|
||
|
//bAutomataCanMove = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Get the automata in front
|
||
|
auto itAutomataInFront = itThisAutomata;
|
||
|
itAutomataInFront--;
|
||
|
|
||
|
// If the distance between the front of the automata in front and the fornt of this automata
|
||
|
// is greater than the length of the automata in front, then there is space for this automata
|
||
|
// to enter
|
||
|
if (fabs((*itAutomataInFront)->fAutoPos - (*itThisAutomata)->fAutoPos) > ((*itAutomataInFront)->fAutoLength + 0.1f))
|
||
|
{
|
||
|
// Move Automata along track
|
||
|
//bAutomataCanMove = true;
|
||
|
fDistanceToAutoInFront = ((*itAutomataInFront)->fAutoPos - (*itAutomataInFront)->fAutoLength - 0.1f) - (*itThisAutomata)->fAutoPos;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// No space, so do not move automata
|
||
|
bAutomataCanMove = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bAutomataCanMove)
|
||
|
{
|
||
|
if (fDistanceToAutoInFront > pCurrentTrack->fTrackLength) fDistanceToAutoInFront = pCurrentTrack->fTrackLength;
|
||
|
fAutoPos += fElapsedTime * std::max(fDistanceToAutoInFront, 1.0f) * (fAutoLength < 0.1f ? 0.3f : 0.5f);
|
||
|
}
|
||
|
|
||
|
|
||
|
if (fAutoPos >= pCurrentTrack->fTrackLength)
|
||
|
{
|
||
|
// Automata has reached end of current track
|
||
|
|
||
|
// Check if it can transition beyond node
|
||
|
if (!pExitNode->bBlock)
|
||
|
{
|
||
|
// It can, so reset position along track back to start
|
||
|
fAutoPos -= pCurrentTrack->fTrackLength;
|
||
|
|
||
|
// Choose a track from the node not equal to this one, that has an unblocked exit node
|
||
|
|
||
|
// For now choose at random
|
||
|
cAuto_Track *pNewTrack = nullptr;
|
||
|
|
||
|
if (pExitNode->listTracks.size() == 2)
|
||
|
{
|
||
|
// Automata is travelling along straight joined sections, one of the
|
||
|
// tracks is the track its just come in on, the other is the exit, so
|
||
|
// choose the exit.
|
||
|
auto it = pExitNode->listTracks.begin();
|
||
|
pNewTrack = (*it);
|
||
|
if (pCurrentTrack == pNewTrack)
|
||
|
{
|
||
|
++it;
|
||
|
pNewTrack = (*it);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Automata has reached a junction with several exits
|
||
|
while (pNewTrack == nullptr)
|
||
|
{
|
||
|
int i = rand() % pExitNode->listTracks.size();
|
||
|
int j = 0;
|
||
|
for (auto it = pExitNode->listTracks.begin(); it != pExitNode->listTracks.end(); ++it)
|
||
|
{
|
||
|
cAuto_Track* track = (*it);
|
||
|
|
||
|
// Work out which node is the target destination
|
||
|
cAuto_Node *pNewExitNode = track->node[0];
|
||
|
if (pNewExitNode == pExitNode)
|
||
|
pNewExitNode = track->node[1];
|
||
|
|
||
|
if (j == i && track != pCurrentTrack && !pNewExitNode->bBlock /*((*it)->cell != pCurrentTrack->cell)*/)
|
||
|
{
|
||
|
pNewTrack = track;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
j++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// Change to new track, the origin node of the next
|
||
|
// track is the same as the exit node to the current track
|
||
|
pTrackOriginNode = pExitNode;
|
||
|
|
||
|
// Remove the automata from the front of the queue
|
||
|
// on the current track
|
||
|
pCurrentTrack->listAutos.pop_front();
|
||
|
|
||
|
// Switch the automatas track link to the new track
|
||
|
pCurrentTrack = pNewTrack;
|
||
|
|
||
|
// Push the automata onto the back of the new track queue
|
||
|
pCurrentTrack->listAutos.push_back(this);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// It cant pass the node, so clamp automata at this location
|
||
|
fAutoPos = pCurrentTrack->fTrackLength;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Automata is travelling
|
||
|
vAutoPos = pCurrentTrack->GetPostion(fAutoPos, pTrackOriginNode);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|