Exemplo n.º 1
0
/**
 * Sort some stuff out at actor start-up time.
 */
static void InitialPathChecks(PMOVER pMover, int xpos, int ypos) {
	HPOLYGON hPath;
	int	node;
	int	z;

	pMover->objX = xpos;
	pMover->objY = ypos;

	/*--------------------------------------
	| If Actor is in a follow nodes path,	|
	| position it at the nearest node.	|
	 --------------------------------------*/
	hPath = InPolygon(xpos, ypos, PATH);

	if (hPath != NOPOLY) {
		pMover->hCpath = hPath;
		if (PolySubtype(hPath) == NODE) {
			node = NearestNodeWithin(hPath, xpos, ypos);
			getNpathNode(hPath, node, &pMover->objX, &pMover->objY);
			pMover->hFnpath = hPath;
			pMover->line = node;
			pMover->npstatus = GOING_UP;
		}

		z = GetScale(hPath, pMover->objY);
	} else {
		pMover->bNoPath = true;

		z = GetScale(FirstPathPoly(), pMover->objY);
	}
	SetMoverWalkReel(pMover, FORWARD, z, false);
}
Exemplo n.º 2
0
/**
 * Run appropriate actor or polygon glitter code.
 * If none, and it's a WALKTO event, do a walk.
 */
static void ProcessUserEvent(TINSEL_EVENT uEvent, const Common::Point &coOrds, PLR_EVENT be = PLR_NOEVENT) {
	int	actor;
	int	aniX, aniY;
	HPOLYGON hPoly;

	// Prevent activation of 2 events on the same tick
	if (++g_eCount != 1)
		return;

	if ((actor = GetTaggedActor()) != 0) {
		// Event for a tagged actor
		if (TinselV2)
			ActorEvent(Common::nullContext, actor, uEvent, false, 0);
		else
			ActorEvent(actor, uEvent, be);
	} else if ((hPoly = GetTaggedPoly()) != NOPOLY) {
		// Event for active tagged polygon
		if (!TinselV2)
			RunPolyTinselCode(hPoly, uEvent, be, false);
		else if (uEvent != PROV_WALKTO)
			PolygonEvent(Common::nullContext, hPoly, uEvent, 0, false, 0);

	} else {
		GetCursorXY(&aniX, &aniY, true);

		// There could be a poly involved which has no tag.
		if ((hPoly = InPolygon(aniX, aniY, TAG)) != NOPOLY ||
			(!TinselV2 && ((hPoly = InPolygon(aniX, aniY, EXIT)) != NOPOLY))) {
			if (TinselV2 && (uEvent != PROV_WALKTO))
				PolygonEvent(Common::nullContext, hPoly, uEvent, 0, false, 0);
			else if (!TinselV2)
				RunPolyTinselCode(hPoly, uEvent, be, false);
		} else if ((uEvent == PROV_WALKTO) || (uEvent == WALKTO)) {
			if (TinselV2)
				ProcessedProvisional();
			WalkTo(aniX, aniY);
		}
	}
}
Exemplo n.º 3
0
void Race::HandlePlayerOnPlayerCollisions(){
    for (unsigned i=0; i<Player.size()-1;i++)
    {
        for (unsigned j=i+1; j<Player.size();j++)
        {
            if (Player[i].DeathSwitch==1 || Player[j].DeathSwitch==1)
                continue;
            bool StillCorrecting=1;
            unsigned Attempts=0;
            while (StillCorrecting){
                StillCorrecting=0;
                vector<Vector2d> Bounding1=Player[i].Bounding;
                for (unsigned k=0; k<Bounding1.size();k++)
                {
                    Bounding1[k]=RotateVector(Bounding1[k],Player[i].Rotation);
                    Bounding1[k]+=Player[i].Position;
                }
                vector<Vector2d> Bounding2=Player[j].Bounding;
                for (unsigned k=0; k<Bounding2.size();k++)
                {
                    Bounding2[k]=RotateVector(Bounding2[k],Player[j].Rotation);
                    Bounding2[k]+=Player[j].Position;
                }
                bool CornerPoly=0;
                Vector2u CornerSide=Vector2u();
                Vector2d Direction=Vector2d();
                double Overlap=0;
                bool DoubleFlag=0;
                if(InPolygon(Bounding1, Bounding2, CornerPoly, CornerSide, Direction,Overlap,DoubleFlag))
                {
                    vector<vector<Vector2d>> Bounding={Bounding1,Bounding2};
                    Vector2d CollisionPos=Bounding[CornerPoly][CornerSide.x];
                    HandleSinglePlayerCollision({&Player[i],&Player[j]},Bounding,
                                                CornerPoly,CollisionPos,Direction,Overlap,DoubleFlag,Attempts);
                    Attempts++;
                    StillCorrecting=1;
                }
                if(Attempts>=5)
                {
                    //Player[i].DeathSwitch=1;
                    StillCorrecting=0;
                }
            }
        }
    }
}
Exemplo n.º 4
0
/**
 * Reposition a moving actor.
 */
void PositionMover(PMOVER pMover, int x, int y) {
	int	z;
	int	node;
	HPOLYGON hPath;

	assert(pMover); // Moving null moving actor
	assert(pMover->actorObj);

	pMover->objX = x;
	pMover->objY = y;
	MultiSetAniXY(pMover->actorObj, x, y);

	hPath = InPolygon(x, y, PATH);
	if (hPath != NOPOLY) {
		pMover->hCpath = hPath;
		if (PolySubtype(hPath) == NODE) {
			node = NearestNodeWithin(hPath, x, y);
			getNpathNode(hPath, node, &pMover->objX, &pMover->objY);
			pMover->hFnpath = hPath;
			pMover->line = node;
			pMover->npstatus = GOING_UP;
		} else {
			pMover->hFnpath = NOPOLY;
			pMover->npstatus = NOT_IN;
		}

		z = GetScale(hPath, pMover->objY);
		pMover->scale = z;
		SetMoverStanding(pMover);
	} else {
		pMover->bNoPath = true;

		pMover->hFnpath = NOPOLY;	// Ain't in one
		pMover->npstatus = NOT_IN;

		// Ensure legal reel and scale
		if (pMover->direction < 0 || pMover->direction > 3)
			pMover->direction = FORWARD;
		if (pMover->scale < 0 || pMover->scale > TOTAL_SCALES)
			pMover->scale = 1;
	}
}
Exemplo n.º 5
0
/**
 * Called from scroll process - Scrolls the image as appropriate.
 */
static void ScrollImage() {
	int OldLoffset = 0, OldToffset = 0;	// Used when keeping cursor on a tag
	int Loffset, Toffset;
	int curX, curY;

	// get background offsets
	PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);

	/*
	 * Keeping cursor on a tag?
	 */
	if (g_ScrollCursor) {
		GetCursorXYNoWait(&curX, &curY, true);
		if (InPolygon(curX, curY, TAG) != NOPOLY || InPolygon(curX, curY, EXIT) != NOPOLY) {
			OldLoffset = Loffset;
			OldToffset = Toffset;
		} else
			g_ScrollCursor = false;
	}

	/*
	 * Horizontal scrolling
	 */
	if (g_LeftScroll > 0) {
		g_LeftScroll -= g_scrollPixelsX;
		if (g_LeftScroll < 0) {
			Loffset += g_LeftScroll;
			g_LeftScroll = 0;
		}
		Loffset += g_scrollPixelsX;		// Move right
		if (Loffset > g_ImageW - SCREEN_WIDTH)
			Loffset = g_ImageW - SCREEN_WIDTH;// Now at extreme right

		/*** New feature to prop up rickety scroll boundaries ***/
		if (TinselV2 && SysVar(SV_MaximumXoffset) &&  (Loffset > SysVar(SV_MaximumXoffset)))
			Loffset = SysVar(SV_MaximumXoffset);

	} else if (g_LeftScroll < 0) {
		g_LeftScroll += g_scrollPixelsX;
		if (g_LeftScroll > 0) {
			Loffset += g_LeftScroll;
			g_LeftScroll = 0;
		}
		Loffset -= g_scrollPixelsX;	// Move left
		if (Loffset < 0)
			Loffset = 0;		// Now at extreme left

		/*** New feature to prop up rickety scroll boundaries ***/
		if (TinselV2 && SysVar(SV_MinimumXoffset) &&  (Loffset < SysVar(SV_MinimumXoffset)))
			Loffset = SysVar(SV_MinimumXoffset);
	}

	/*
	 * Vertical scrolling
	 */
	if (g_DownScroll > 0) {
		g_DownScroll -= g_scrollPixelsY;
		if (g_DownScroll < 0) {
			Toffset += g_DownScroll;
			g_DownScroll = 0;
		}
		Toffset += g_scrollPixelsY;		// Move down

		if (Toffset > g_ImageH - SCREEN_HEIGHT)
			Toffset = g_ImageH - SCREEN_HEIGHT;// Now at extreme bottom

		/*** New feature to prop up rickety scroll boundaries ***/
		if (TinselV2 && SysVar(SV_MaximumYoffset) &&  Toffset > SysVar(SV_MaximumYoffset))
			Toffset = SysVar(SV_MaximumYoffset);

	} else if (g_DownScroll < 0) {
		g_DownScroll += g_scrollPixelsY;
		if (g_DownScroll > 0) {
			Toffset += g_DownScroll;
			g_DownScroll = 0;
		}
		Toffset -= g_scrollPixelsY;		// Move up

		if (Toffset < 0)
			Toffset = 0;			// Now at extreme top

		/*** New feature to prop up rickety scroll boundaries ***/
		if (TinselV2 && SysVar(SV_MinimumYoffset) &&  Toffset < SysVar(SV_MinimumYoffset))
			Toffset = SysVar(SV_MinimumYoffset);
	}

	/*
	 * Move cursor if keeping cursor on a tag.
	 */
	if (g_ScrollCursor)
		AdjustCursorXY(OldLoffset - Loffset, OldToffset - Toffset);

	PlayfieldSetPos(FIELD_WORLD, Loffset, Toffset);
}
Exemplo n.º 6
0
Vector2u Race::getNearestValidSquare(unsigned PlayerNumber){
    Vector2u Dim=track.getDim();
    vector<double> norm(Dim.x*Dim.y,0);
    Vector2d Position=Player[PlayerNumber].PositionBeforeDeath;

    for (unsigned k=0; k<Dim.x*Dim.y;++k)
    {
        unsigned k1= k % Dim.x;
        unsigned k2= k / Dim.x;
        norm[k]=sqrt(pow(k1+0.5-Position.x,2)+pow(k2+0.5-Position.y,2));
    }
    vector<int> index(norm.size(), 0);
    for (unsigned i = 0 ; i != index.size() ; i++) {
        index[i] = i;
    }

    sort(index.begin(), index.end(),[&](const int& a, const int& b) {return (norm[a] < norm[b]);});

    unsigned j=0;
    bool SquareValid=false;
    bool CarCollision=false;
    vector<PROPERTIES> InvalidTiles={FALL,WALL};
    while (SquareValid==false || CarCollision==true)
    {
        CarCollision=false;
        SquareValid=true;
        unsigned k1=index[j]%Dim.x;
        unsigned k2=index[j]/Dim.x;
        Tile* CurrentTile=track.getTile(k1,k2);
        Detect Detection=CurrentTile->Detection;
        for (unsigned i=0; i<InvalidTiles.size(); i++)
        {
            if (Detection.x.count(InvalidTiles[i])==1)
            {
                SquareValid=0;
            }
        }
        if(CurrentTile->isSquare==0)
        {
            SquareValid=0;
        }

        Player[PlayerNumber].Position=Vector2d(k1+0.5, k2+0.5);
        for (unsigned i=0; i< Player.size();++i)
        {
            Car *Car1,*Car2;
            if(i==PlayerNumber)
            {
                continue;
            }
            Car1=&Player[PlayerNumber];
            Car2=&Player[i];

            vector<Vector2d> Bounding1=Car1->Bounding;
            for (unsigned k=0; k<Bounding1.size();k++)
            {
                Bounding1[k]=RotateVector(Bounding1[k],Player[PlayerNumber].Rotation);
                Bounding1[k]+=Player[PlayerNumber].Position;
            }
            Vector2d Center1=accumulate(Bounding1.begin(),Bounding1.end(),Vector2d(0,0))/static_cast<double>(Bounding1.size());

            vector<Vector2d> Bounding2=Car2->Bounding;
            for (unsigned k=0; k<Bounding2.size();k++)
            {
                Bounding2[k]=RotateVector(Bounding2[k],Player[i].Rotation);
                Bounding2[k]+=Player[i].Position;
            }
            Vector2d Center2=accumulate(Bounding2.begin(),Bounding2.end(),Vector2d(0,0))/static_cast<double>(Bounding2.size());

            if( InPolygon(Bounding1,Bounding2) || InPolygon(Center1,Bounding2) || InPolygon(Center2,Bounding1) )
            {
                CarCollision=1;
            }
        }
        j++;
        if (j==Dim.x*Dim.y)
        {
            cerr<<"Failed to Find Valid Square!!"<<endl;
        }
    }
    return Vector2u(index[j-1]%Dim.x,index[j-1]/Dim.x);
}
Exemplo n.º 7
0
void Race::HandleWallCollisions(){
    int trackwidth=track.getDim().x, trackheight=track.getDim().y;
    for (unsigned i=0; i<Player.size();i++)
    {
        bool StillCorrecting=1;
        unsigned Attempts=0;
        while (StillCorrecting){
            StillCorrecting=0;
            vector<Vector2d> Bounding=Player[i].Bounding;
            for (unsigned j=0; j<4;j++)
            {
                Bounding[j]=RotateVector(Bounding[j],Player[i].Rotation);
                Bounding[j]+=Player[i].Position;
            }
            Vector2u CurrentSquare=Player[i].getGridPosition();
            for (int j=0; j<9;j++)
            {
                bool TestCollision=0;
                vector<Vector2d> BoundingTile;
                int index1=(j%3)-1, index2=(j/3)-1;

                index1+=CurrentSquare.x; index2+=CurrentSquare.y;
                if (index1>=0 && index1<trackwidth && index2>=0 && index2<trackheight)
                {
                    Tile* CurrentTile=track.getTile(index1,index2);
                    Detect Detection=CurrentTile->Detection;
                    if(CurrentTile->isSquare && Detection.x.find(WALL)!=Detection.x.end())
                    {
                        BoundingTile={Vector2d(index1,index2),Vector2d(index1,index2+1),
                        Vector2d(index1+1,index2+1),Vector2d(index1+1,index2)};
                        TestCollision=1;
                    }
                    if(CurrentTile->isSquare==0 && Detection.y.find(WALL)!=Detection.y.end())
                    {
                        if(CurrentTile->Orientation==1)
                        {
                            BoundingTile={Vector2d(index1,index2),Vector2d(index1,index2+1),Vector2d(index1+1,index2)};
                        }
                        else{
                            BoundingTile={Vector2d(index1,index2),Vector2d(index1+1,index2+1),Vector2d(index1+1,index2)};
                        }
                        TestCollision=1;
                    }
                    if(CurrentTile->isSquare==0 && Detection.x.find(WALL)!=Detection.x.end())
                    {
                        if(CurrentTile->Orientation==1)
                        {
                            BoundingTile={Vector2d(index1,index2+1),Vector2d(index1+1,index2+1),Vector2d(index1+1,index2)};
                        }
                        else{
                            BoundingTile={Vector2d(index1,index2),Vector2d(index1,index2+1),Vector2d(index1+1,index2+1)};
                        }
                        TestCollision=1;
                    }
                }
                else{
                    BoundingTile={Vector2d(index1,index2),Vector2d(index1,index2+1),
                    Vector2d(index1+1,index2+1),Vector2d(index1+1,index2)};
                    TestCollision=1;
                }
                if(TestCollision==1)
                {
                    bool CornerPoly=0;
                    Vector2u CornerSide=Vector2u();
                    Vector2d Direction=Vector2d();
                    double Overlap=0;
                    bool DoubleFlag=0;
                    if(InPolygon(BoundingTile, Bounding, CornerPoly, CornerSide, Direction,Overlap,DoubleFlag))
                    {
                        if(CornerPoly==1)
                        {
                            Direction=Vector2d(-Direction.x,-Direction.y);
                        }
                        if (DoubleFlag==1)
                        {
                            Vector2d TileAverage=accumulate(BoundingTile.begin(),BoundingTile.end(),Vector2d(0,0));
                            TileAverage=TileAverage/static_cast<double>(BoundingTile.size());
                            Vector2d Average=accumulate(Bounding.begin(),Bounding.end(),Vector2d(0,0));
                            Average=Average/static_cast<double>(Bounding.size());
                            Vector2d AltVelocity=Average-TileAverage;
                            AltVelocity=AltVelocity/(sqrt(DotProduct(AltVelocity,AltVelocity)));
                            HandleSingleWallCollision(Player[i], Direction, Overlap,Attempts,AltVelocity);
                        }
                        else{
                            HandleSingleWallCollision(Player[i], Direction, Overlap,Attempts);
                        }
                        StillCorrecting=1;
                        Attempts++;
                    }
                }
                if(Attempts>=20)
                {
                    Player[i].DeathSwitch=1;
                    StillCorrecting=0;
                }
            }
        }
    }
}