Jump to content
RenCorner Network

Why isn't there a command to flip tanks?!


Recommended Posts

Posted

I was playing Field not too long ago and I got a spy stank an flipped it, I tried getting unstuck for like 10 minutes and I was still stuck sideways. Really annoying that I lost spy simply because I drove off a hill at a bad angle.

Posted (edited)

Dont drink and drive huh, !unstuck is supposed to get you unstuck but not dealing with your shitty driving skills or your lag lol. Just kidding, !unstuck just moves you, but wont "flip" your tank.. there´s no need to try !unstuck then. You need someone who push you.

Edited by rackz
Posted

So it was you who was trolling under the name of OSTKswampdick...

  • Haha 1
Posted

This game already rewards players enough with multiple useful commands

 

!donate

!killme

!stuck

 

We dont need any more, just lowers the skillcap

Posted
29 minutes ago, D4rX said:

So it was you who was trolling under the name of OSTKswampdick...

And yea don't do that

Posted

:wall0:More dumbass smilies FTW(Cool0 section).:stupid0:

P.S. he doesn't have !stuck/!unstuck anyway. 

Posted

You would only find a way to abuse it like you do with everything else 

Posted

Because I believe that this command would need to "recognize" the whole ambient of the map and it takes work.
BC, imagine this, you're stuck and your vehicle ends up at the very side of a wall. You'll use the !flip command and your tank ends up half stuck on the wall because instead of applying physics, the best flip animation would be to respawn your vehicle right at your XYZ coordinates. And probably the !stuck command wouldn't work in this case or in a very specific range of situations. Therefore, the !flip would require a flip and unstuck command all together. That is mostly unlikely to happen.

  • Like 1
Posted

It can definitely be done, I think collisions can be detected, it would have to re position until it found a position where there were no collisions or something

Posted (edited)

I already wrote this almost 8 years ago for unstucking vehicles. It just updates the 3d transform of the vehicle and then using radians detections when the vehicle is no longer flipped over.

Code:

	#include "General.h"
#include "CustomFlipKill.h"
#include "VehicleGameObjDef.h"
#include "HashTemplateClass.h"
#include "HashTemplateIterator.h"
#include "slist.h"
#include "VehicleGameObj.h"
#include "GameObjManager.h"
#include "engine_tt.h"
#include "engine_io.h"
#include "gmgame.h"
	HashTemplateClass<StringClass, int> DontFlipKillPresets; // Contains vehicle presets that won't get flip killed
HashTemplateClass<StringClass, int> RotateUpwardsPresets; // These presets get rotated upwards if they flip
int LastExecuteTime = 0; // Used by OnThink() stores the last time OnThink() was fully called
int CheckInterval = 3; // Used by OnThink
float ScriptCheckingInterval = 1.f; // Used by CustomFlipKill_Script::Create()
int ChecksCount = 4; // Amount of times to check between ScriptCheckingInterval before destroying the vehicle
                    // ^ Used by CustomFlipKill_Script::Timer_Expired()
	CustomFlipKill::CustomFlipKill()
{
    RegisterEvent(EVENT_GLOBAL_INI,this);
    RegisterEvent(EVENT_THINK_HOOK,this);
    RegisterEvent(EVENT_LOAD_LEVEL_HOOK,this);
}
	CustomFlipKill::~CustomFlipKill()
{
    UnregisterEvent(EVENT_GLOBAL_INI,this);
    UnregisterEvent(EVENT_THINK_HOOK,this);
    UnregisterEvent(EVENT_LOAD_LEVEL_HOOK,this);
}
void CustomFlipKill::OnLoadLevel()
{
    LastExecuteTime = 0;
}
        
void CustomFlipKill::OnLoadGlobalINISettings(INIClass *SSGMIni)
{
    CheckInterval = SSGMIni->Get_Int("CustomFlipKill", "CheckInterval", 2);
    ChecksCount = SSGMIni->Get_Int("CustomFlipKill", "ChecksCount", 4);
    ScriptCheckingInterval =  SSGMIni->Get_Float("CustomFlipKill", "ScriptCheckingInterval", 1.f);
	    int Count = SSGMIni->Entry_Count("CustomFlipKill_DontFlipKillPresets");
    for (int i = 0; i < Count; i++)
    {
        const char *Entry = SSGMIni->Get_Entry("CustomFlipKill_DontFlipKillPresets", i);
        StringClass Insert;
        SSGMIni->Get_String(Insert, "CustomFlipKill_DontFlipKillPresets", Entry);
        DontFlipKillPresets.Insert(Insert, 1);
    }
	    Count = SSGMIni->Entry_Count("CustomFlipKill_RotateUpwardsPresets");
    for (int i = 0; i < Count; i++)
    {
        const char *Entry = SSGMIni->Get_Entry("CustomFlipKill_RotateUpwardsPresets", i);
        StringClass Insert;
        SSGMIni->Get_String(Insert, "CustomFlipKill_RotateUpwardsPresets", Entry);
        RotateUpwardsPresets.Insert(Insert, 1);
    }
}
	void CustomFlipKill::OnThink()
{
    if (!The_Game())
    {
        return;
    }
    
    int CurrentExecuteTime = The_Game()->Get_Game_Duration_S();
    if (CurrentExecuteTime < (LastExecuteTime + CheckInterval)) return;
	    LastExecuteTime = CurrentExecuteTime;
//    Console_Output("LastExecuteTime updated to %d\n", LastExecuteTime); // DEBUG CRAP
    
    SLNode<SmartGameObj> *x = GameObjManager::SmartGameObjList.Head();
    while (x)
    {
        GameObject *o = As_VehicleGameObj(x->Data());
        if (o)
        {
            if (Get_Vehicle_Mode(o) != VEHICLE_TYPE_TURRET)
            {
                Matrix3D Transform = Get_Transform(o);
                float AbsRotationY = fabs(Transform.getRotationY());
	                if (AbsRotationY > 1.3f)
                {
                    if (RotateUpwardsPresets.Get(Commands->Get_Preset_Name(o), 0))
                    {
                        if (!Is_Script_Attached(o, "RotateUpwards_Script"))
                        {
                            Attach_Script_Once(o, "RotateUpwards_Script", "");
                        }
                    }
                    else if (DontFlipKillPresets.Get(Commands->Get_Preset_Name(o), 0) == 0)
                    {
                        if (!Is_Script_Attached(o, "CustomFlipKill_Script"))
                        {
                            Attach_Script_Once(o, "CustomFlipKill_Script", "");
                        }
                    }
                }
            }
        }
        x = x->Next();
    }
}
	void CustomFlipKill_Script::Created(GameObject *obj)
{
    Commands->Start_Timer(obj, this, ScriptCheckingInterval, 1);
}
	void CustomFlipKill_Script::Timer_Expired(GameObject *obj, int number)
{
    if (number == 1)
    {
        Matrix3D Transform = Get_Transform(obj);
        float AbsRotationY = fabs(Transform.getRotationY());
	        if ((AbsRotationY > 1.3f)) // If the vehicle is flipped
        {
            TimesChecked++;
	            if (TimesChecked >= ChecksCount)
            {
                // Destroy vehicle
                Commands->Apply_Damage(obj, 9999.f, "Death", 0);
                return;
            }
            Commands->Start_Timer(obj, this, ScriptCheckingInterval, 1);
        }
        else // During one of our checks the vehicle "unflipped" itself so we can destroy this script
        {
            Destroy_Script();
        }
    }
}
	ScriptRegistrant<CustomFlipKill_Script> CustomFlipKill_Script_Registrant("CustomFlipKill_Script","");
	void RotateUpwards_Script::Created(GameObject *obj)
{
    Commands->Start_Timer(obj, this, 0.5f, 1);
}
	void RotateUpwards_Script::Timer_Expired(GameObject *obj, int number)
{
    if (number == 1)
    {
        Matrix3D Transform = Get_Transform(obj);
        float AbsRotationY = fabs(Transform.getRotationY());
	        if ((AbsRotationY > 1.3f)) // If the vehicle is flipped
        {
            // Rotate our vehicle upwards
            Matrix3D Transform = Get_Transform(obj);
            Transform.Rotate_X(DEG_TO_RADF(25));
            Set_Transform(obj,Transform);
	            // We need to higher the position of our vehicle slightly
            Vector3 Pos = Commands->Get_Position(obj);
            Pos.Z += 3.0f;
            Commands->Set_Position(obj, Pos);
	            Commands->Start_Timer(obj, this, 0.5f, 1);
        }
        else // During one of our checks the vehicle "unflipped" itself so we can destroy this script
        {
            Destroy_Script();
        }
    }
}
	ScriptRegistrant<RotateUpwards_Script> RotateUpwards_Script_Registrant("RotateUpwards_Script","");
	CustomFlipKill customFlipKill;
	extern "C" __declspec(dllexport) Plugin* Plugin_Init()
{
    return &customFlipKill;
}
	

Use the RotateUpwards_Scripts in the code tags and attach it to a vehicle after executing a command like !vehunstuck. The plugin is made for custom flip kills (so you disable all flip kills via tt.ini and then use this script and in ssgm.ini you can configure which vehs won't flip kill...it also supports configuring which vehicles will rotate themselves upwards again automatically.

Edited by Iran
Posted

I actually thought about doing this is we leave vehicle flip destruction off. Make it so you have to hold down e for x amount of seconds. ( Prevent the flip if they are killed have to stop pressing e ) and prevent player from entering vehicle while flipped.

Posted

I played around with it and made it a da game feature. Automatic flip or press e on vehicle. Would you know how to make a preset loading bar like ion and nuke @Iran.

 

 

#include "General.h"
#include "scripts.h"
#include "engine.h"
#include "engine_da.h"
#include "da.h"
#include "da_settings.h"
#include "GameObjManager.h"
#include "CustomFlipKill.h"

HashTemplateClass<StringClass, int> DontFlipKillPresets; // Contains vehicle presets that won't get flip killed
HashTemplateClass<StringClass, int> RotateUpwardsPresets; // These presets get rotated upwards if they flip
int LastExecuteTime = 0; // Used by OnThink() stores the last time OnThink() was fully called
int CheckInterval = 3; // Used by OnThink
float ScriptCheckingInterval = 1.f; // Used by CustomFlipKill_Script::Create()
int ChecksCount = 4; // Amount of times to check between ScriptCheckingInterval before destroying the vehicle
					// ^ Used by CustomFlipKill_Script::Timer_Expired()

bool AutomaticFlip; //Disable on think checking
bool VehicleFlippedEnter;

void VehicleFlipGameFeature::Init()
{
	Register_Event(DAEvent::LEVELLOADED);
	Register_Event(DAEvent::SETTINGSLOADED);
	Register_Event(DAEvent::THINK);
	Register_Event(DAEvent::VEHICLEENTRYREQUEST,INT_MAX);
}

VehicleFlipGameFeature::~VehicleFlipGameFeature()
{
}

void VehicleFlipGameFeature::Level_Loaded_Event()
{
	LastExecuteTime = 0;
}

void VehicleFlipGameFeature::Settings_Loaded_Event()
{
	AutomaticFlip =				  DASettingsManager::Get_Bool("EnableAutomaticFlip", false);
	VehicleFlippedEnter =		  DASettingsManager::Get_Bool("VehicleFlippedEnter", false);
	CheckInterval =				  DASettingsManager::Get_Int("CheckInterval", 3);
	ChecksCount =				  DASettingsManager::Get_Int("ChecksCount",4);
	ScriptCheckingInterval =	  DASettingsManager::Get_Float("ScriptCheckingInterval",1.f);

	INISection *Section = DASettingsManager::Get_Section("CustomFlipKill_DontFlipKillPresets");
	if (Section) 
	{
		for (INIEntry *i = Section->EntryList.First();i && i->Is_Valid();i = i->Next()) 
		{
			StringClass Insert;
			DASettingsManager::Get_String(Insert, "CustomFlipKill_DontFlipKillPresets", i->Entry);
			DontFlipKillPresets.Insert(Insert, 1);
		}
	}

	Section = DASettingsManager::Get_Section("CustomFlipKill_RotateUpwardsPresets");
	if (Section) 
	{
		for (INIEntry *i = Section->EntryList.First();i && i->Is_Valid();i = i->Next()) 
		{
			StringClass Insert;
			DASettingsManager::Get_String(Insert, "CustomFlipKill_RotateUpwardsPresets", i->Entry);
			RotateUpwardsPresets.Insert(Insert, 1);
		}
	}
}

bool VehicleFlipGameFeature::Vehicle_Flip_Event(VehicleGameObj *Vehicle) 
{
	//Console_Output("Vehicle Flip Event %s\n", Commands->Get_Preset_Name(Vehicle));
	return false;
}

class CustomFlipKillObserverClass : public DAGameObjObserverClass {
public:

	CustomFlipKillObserverClass() { }

	int TimesChecked;

	 const char *Get_Name() {
		return "CustomFlipKillObserverClass";
	}

	virtual void Init() {
		Start_Timer(1, ScriptCheckingInterval);
	}

	virtual void Destroyed(GameObject *obj) 
	{ 
		Set_Delete_Pending();
	}

	virtual void Timer_Expired(GameObject *obj, int Number)
	{
		if ( Number == 1)
		{
			Matrix3D Transform = Get_Transform(obj);
			float AbsRotationY = fabs(Transform.Get_Y_Rotation());

			if ((AbsRotationY > 1.3f)) // If the vehicle is flipped
			{
				TimesChecked++;
				if (TimesChecked >= ChecksCount)
				{
					// Destroy vehicle
					Commands->Apply_Damage(obj, 9999.f, "Death", 0);
					return;
				}
				Start_Timer(1, ScriptCheckingInterval);
			}
			else // During one of our checks the vehicle "unflipped" itself so we can destroy this script
			{
				Set_Delete_Pending();
			}
		}
	}
};

void  RotateVehicleUpwards(GameObject *obj)
{
	// Rotate our vehicle upwards
	Matrix3D Transform = Get_Transform(obj);
	Transform.Rotate_X(DEG_TO_RADF(25));
	Set_Transform(obj,Transform);
	// We need to higher the position of our vehicle slightly
	Vector3 Pos = Commands->Get_Position(obj);
	Pos.Z += 3.0f;
	Commands->Set_Position(obj, Pos);
}

class RotateUpwardsObserverClass : public DAGameObjObserverClass {
public:

	RotateUpwardsObserverClass() { }

	int TimesChecked;

	 const char *Get_Name() {
		return "RotateUpwardsObserverClass";
	}

	virtual void Init() {
		Start_Timer(1, 0.5f);
	}

	virtual void Destroyed(GameObject *obj) 
	{ 
		Set_Delete_Pending();
	}

	virtual void Timer_Expired(GameObject *obj, int Number)
	{
		if (Number == 1)
		{

			Matrix3D Transform = Get_Transform(obj);
			float AbsRotationY = fabs(Transform.Get_Y_Rotation());
			if ((AbsRotationY > 1.3f)) // If the vehicle is flipped
			{
				RotateVehicleUpwards(obj);
				Start_Timer(1, 0.5f);
			}
			else // During one of our checks the vehicle "unflipped" itself so we can destroy this script
			{
				Set_Delete_Pending();
			}
		}
	}
};

bool VehicleFlipGameFeature::Vehicle_Entry_Request_Event(VehicleGameObj *Vehicle,cPlayer *Player,int &Seat) 
{
	Matrix3D Transform = Get_Transform(Vehicle);
	float AbsRotationY = fabs(Transform.Get_Y_Rotation());
	if ((AbsRotationY > 1.3f)) // If the vehicle is flipped
	{
		if ( !AutomaticFlip )
			RotateVehicleUpwards(Vehicle);
		if ( !VehicleFlippedEnter )
			return false;
		else
			return true;
	}
	return true;
}

void VehicleFlipGameFeature::Think()
{
	if (!The_Game() || !AutomaticFlip )
	{
		return;
	}
	
	int CurrentExecuteTime = The_Game()->Get_Game_Duration_S();
	if (CurrentExecuteTime < (LastExecuteTime + CheckInterval)) return;

	LastExecuteTime = CurrentExecuteTime;
	//Console_Output("LastExecuteTime updated to %d\n", LastExecuteTime); // DEBUG CRAP
	
	SLNode<SmartGameObj> *x = GameObjManager::SmartGameObjList.Head();
	while (x)
	{
		GameObject *o = x->Data()->As_VehicleGameObj();
		if (o)
		{
			if (Get_Vehicle_Mode(o) != VEHICLE_TYPE_TURRET)
			{
				Matrix3D Transform = Get_Transform(o);
				float AbsRotationY = fabs(Transform.Get_Y_Rotation());

				if (AbsRotationY > 1.3f)
				{
					if (RotateUpwardsPresets.Get(Commands->Get_Preset_Name(o), 0))
					{
						if ( !o->Find_Observer("RotateUpwardsObserverClass") ) {
							o->Add_Observer(new RotateUpwardsObserverClass );
						}
					}
					else if (DontFlipKillPresets.Get(Commands->Get_Preset_Name(o), 0) == 0)
					{
						if ( !o->Find_Observer("CustomFlipKillObserverClass") ) {
							o->Add_Observer(new CustomFlipKillObserverClass );
						}
					}
				}
			}
		}
		x = x->Next();
	}
}

Register_Game_Feature(VehicleFlipGameFeature, "Custom Vehicle Flip", "VehicleFlipGameFeature", 0);

 

 

 

 

  • 2 weeks later...
Posted

Hopefully a team mate helps you out(I usually try) to get it flipped back over. Would be nice to have a command to un-flip or something to save your vehicle. Especially if its a vehicle you stole or a GDI stank 😉

Posted

You should've seen the match on Complex last weekend when Nod got GDI ref, and everyone on gdi was in APCs and we kept getting our apcs flipped into the tiberium field because we fail to run over infantries in the middle area lol

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...