Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BugFix]Drive/Jumpjet/Ship/Teleport locomotor did not power on when it is un-piggybacked bugfix #1394

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from

Conversation

NetsuNegi
Copy link
Contributor

this is just a bugfix.

Copy link

github-actions bot commented Sep 25, 2024

Nightly build for this pull request:

This comment is automatic and is meant to allow guests to get latest nightly builds for this pull request without registering. It is updated on every successful build.

@tyuah8
Copy link

tyuah8 commented Sep 25, 2024

Does this fix handle corner cases such as a Magnetron lifting a Chrono Miner out of a Service Depot while the Chrono Miner is being repaired? Does the Chrono Miner still work afterwards?

@NetsuNegi
Copy link
Contributor Author

Does this fix handle corner cases such as a Magnetron lifting a Chrono Miner out of a Service Depot while the Chrono Miner is being repaired? Does the Chrono Miner still work afterwards?

no, but I'll try to fix it

@NetsuNegi
Copy link
Contributor Author

Does this fix handle corner cases such as a Magnetron lifting a Chrono Miner out of a Service Depot while the Chrono Miner is being repaired? Does the Chrono Miner still work afterwards?

Alright, idk how to fix it

@tyuah8
Copy link

tyuah8 commented Sep 25, 2024

The following is code I am using for my own project.

static bool IsOnline ( TechnoClass* This )
{
	if (  This->Deactivated || This->IsUnderEMP() )
		return false;
	if (  auto Building = abstract_cast<BuildingClass*>( This ) )
	if ( !Building->IsPowerOnline() )
		return false;
	return true;
}

static void PowerOnIf ( ILocomotion* Locomotion )
{
	//
	LocomotionClass* Locomotor = static_cast<LocomotionClass*>( Locomotion );
	FootClass* Foot = Locomotor->LinkedTo;
	bool On = IsOnline( Foot );
	//

	if ( On ) Locomotor->Power_On ();
	else      Locomotor->Power_Off();
}

////

DEFINE_HOOK( 0x4AF94D,    DriveLocomotionClass__End_Piggyback__PowerOn, 0x7 )
{
	GET( ILocomotion**, Pointer, EDX );
	PowerOnIf( *Pointer );
	return NULL;
}

DEFINE_HOOK( 0x54DADC,  JumpjetLocomotionClass__End_Piggyback__PowerOn, 0x5 )
{
	GET( ILocomotion**, Pointer, EDI );
	PowerOnIf( *Pointer );
	return NULL;
}

DEFINE_HOOK( 0x69F05D,     ShipLocomotionClass__End_Piggyback__PowerOn, 0x7 )
{
	GET( ILocomotion**, Pointer, EDX );
	PowerOnIf( *Pointer );
	return NULL;
}

DEFINE_HOOK( 0x719F17, TeleportLocomotionClass__End_Piggyback__PowerOn, 0x5 )
{
	GET( ILocomotion**, Pointer, ESI );
	PowerOnIf( *Pointer );
	return NULL;
}

I don't remember if there is anything else that is needed...

...but what the above code is doing is detecting the end of a piggyback, and restoring power to the locomotor that was piggybacked.

By the way, if you do decide to use the code I provided, I don't believe your UnitClass_SetDestination_HarvesterFix is necessary anymore.


Here is an explanation for what the code above is doing:

A Chrono Miner uses the teleport locomotor, but switches to the drive locomotor when it is driving, and switches back when it is stationary. When it switches to the drive locomotor, the teleport locomotor becomes "piggybacked" onto the drive locomotor; and when it switches back to the teleport locomotor, the "piggybacking" ends, and the teleport locomotor is un-piggybacked from the drive locomotor.

When a Magnetron lifts a target, that target switches to the jumpjet locomotor, and whatever locomotor that target was using is "piggybacked" onto the jumpjet locomotor. When the target is dropped and hits the floor, that "piggybacked" locomotor is un-piggybacked and is restored.

You can think of piggybacking as a form of "backing-up" where the game, essentially, backs-up the previous locomotor so that it can be restored later.

The original game code did not power on a locomotor when it is un-piggybacked, so I wrote code to do the power on, which is the code you see above.

@NetsuNegi
Copy link
Contributor Author

The following is code I am using for my own project.

static bool IsOnline ( TechnoClass* This )
{
	if (  This->Deactivated || This->IsUnderEMP() )
		return false;
	if (  auto Building = abstract_cast<BuildingClass*>( This ) )
	if ( !Building->IsPowerOnline() )
		return false;
	return true;
}

static void PowerOnIf ( ILocomotion* Locomotion )
{
	//
	LocomotionClass* Locomotor = static_cast<LocomotionClass*>( Locomotion );
	FootClass* Foot = Locomotor->LinkedTo;
	bool On = IsOnline( Foot );
	//

	if ( On ) Locomotor->Power_On ();
	else      Locomotor->Power_Off();
}

////

DEFINE_HOOK( 0x4AF94D,    DriveLocomotionClass__End_Piggyback__PowerOn, 0x7 )
{
	GET( ILocomotion**, Pointer, EDX );
	PowerOnIf( *Pointer );
	return NULL;
}

DEFINE_HOOK( 0x54DADC,  JumpjetLocomotionClass__End_Piggyback__PowerOn, 0x5 )
{
	GET( ILocomotion**, Pointer, EDI );
	PowerOnIf( *Pointer );
	return NULL;
}

DEFINE_HOOK( 0x69F05D,     ShipLocomotionClass__End_Piggyback__PowerOn, 0x7 )
{
	GET( ILocomotion**, Pointer, EDX );
	PowerOnIf( *Pointer );
	return NULL;
}

DEFINE_HOOK( 0x719F17, TeleportLocomotionClass__End_Piggyback__PowerOn, 0x5 )
{
	GET( ILocomotion**, Pointer, ESI );
	PowerOnIf( *Pointer );
	return NULL;
}

I don't remember if there is anything else that is needed...

...but what the above code is doing is detecting the end of a piggyback, and restoring power to the locomotor that was piggybacked.

By the way, if you do decide to use the code I provided, I don't believe your UnitClass_SetDestination_HarvesterFix is necessary anymore.

Here is an explanation for what the code above is doing:

A Chrono Miner uses the teleport locomotor, but switches to the drive locomotor when it is driving, and switches back when it is stationary. When it switches to the drive locomotor, the teleport locomotor becomes "piggybacked" onto the drive locomotor; and when it switches back to the teleport locomotor, the "piggybacking" ends, and the teleport locomotor is un-piggybacked from the drive locomotor.

When a Magnetron lifts a target, that target switches to the jumpjet locomotor, and whatever locomotor that target was using is "piggybacked" onto the jumpjet locomotor. When the target is dropped and hits the floor, that "piggybacked" locomotor is un-piggybacked and is restored.

You can think of piggybacking as a form of "backing-up" where the game, essentially, backs-up the previous locomotor so that it can be restored later.

The original game code did not power on a locomotor when it is un-piggybacked, so I wrote code to do the power on, which is the code you see above.

ok, I will test it soon

@NetsuNegi
Copy link
Contributor Author

The following is code I am using for my own project.

static bool IsOnline ( TechnoClass* This )
{
	if (  This->Deactivated || This->IsUnderEMP() )
		return false;
	if (  auto Building = abstract_cast<BuildingClass*>( This ) )
	if ( !Building->IsPowerOnline() )
		return false;
	return true;
}

static void PowerOnIf ( ILocomotion* Locomotion )
{
	//
	LocomotionClass* Locomotor = static_cast<LocomotionClass*>( Locomotion );
	FootClass* Foot = Locomotor->LinkedTo;
	bool On = IsOnline( Foot );
	//

	if ( On ) Locomotor->Power_On ();
	else      Locomotor->Power_Off();
}

////

DEFINE_HOOK( 0x4AF94D,    DriveLocomotionClass__End_Piggyback__PowerOn, 0x7 )
{
	GET( ILocomotion**, Pointer, EDX );
	PowerOnIf( *Pointer );
	return NULL;
}

DEFINE_HOOK( 0x54DADC,  JumpjetLocomotionClass__End_Piggyback__PowerOn, 0x5 )
{
	GET( ILocomotion**, Pointer, EDI );
	PowerOnIf( *Pointer );
	return NULL;
}

DEFINE_HOOK( 0x69F05D,     ShipLocomotionClass__End_Piggyback__PowerOn, 0x7 )
{
	GET( ILocomotion**, Pointer, EDX );
	PowerOnIf( *Pointer );
	return NULL;
}

DEFINE_HOOK( 0x719F17, TeleportLocomotionClass__End_Piggyback__PowerOn, 0x5 )
{
	GET( ILocomotion**, Pointer, ESI );
	PowerOnIf( *Pointer );
	return NULL;
}

I don't remember if there is anything else that is needed...

...but what the above code is doing is detecting the end of a piggyback, and restoring power to the locomotor that was piggybacked.

By the way, if you do decide to use the code I provided, I don't believe your UnitClass_SetDestination_HarvesterFix is necessary anymore.

Here is an explanation for what the code above is doing:

A Chrono Miner uses the teleport locomotor, but switches to the drive locomotor when it is driving, and switches back when it is stationary. When it switches to the drive locomotor, the teleport locomotor becomes "piggybacked" onto the drive locomotor; and when it switches back to the teleport locomotor, the "piggybacking" ends, and the teleport locomotor is un-piggybacked from the drive locomotor.

When a Magnetron lifts a target, that target switches to the jumpjet locomotor, and whatever locomotor that target was using is "piggybacked" onto the jumpjet locomotor. When the target is dropped and hits the floor, that "piggybacked" locomotor is un-piggybacked and is restored.

You can think of piggybacking as a form of "backing-up" where the game, essentially, backs-up the previous locomotor so that it can be restored later.

The original game code did not power on a locomotor when it is un-piggybacked, so I wrote code to do the power on, which is the code you see above.

works very better than my code

@NetsuNegi
Copy link
Contributor Author

NetsuNegi commented Sep 25, 2024

The following is code I am using for my own project.

static bool IsOnline ( TechnoClass* This )
{
	if (  This->Deactivated || This->IsUnderEMP() )
		return false;
	if (  auto Building = abstract_cast<BuildingClass*>( This ) )
	if ( !Building->IsPowerOnline() )
		return false;
	return true;
}

static void PowerOnIf ( ILocomotion* Locomotion )
{
	//
	LocomotionClass* Locomotor = static_cast<LocomotionClass*>( Locomotion );
	FootClass* Foot = Locomotor->LinkedTo;
	bool On = IsOnline( Foot );
	//

	if ( On ) Locomotor->Power_On ();
	else      Locomotor->Power_Off();
}

////

DEFINE_HOOK( 0x4AF94D,    DriveLocomotionClass__End_Piggyback__PowerOn, 0x7 )
{
	GET( ILocomotion**, Pointer, EDX );
	PowerOnIf( *Pointer );
	return NULL;
}

DEFINE_HOOK( 0x54DADC,  JumpjetLocomotionClass__End_Piggyback__PowerOn, 0x5 )
{
	GET( ILocomotion**, Pointer, EDI );
	PowerOnIf( *Pointer );
	return NULL;
}

DEFINE_HOOK( 0x69F05D,     ShipLocomotionClass__End_Piggyback__PowerOn, 0x7 )
{
	GET( ILocomotion**, Pointer, EDX );
	PowerOnIf( *Pointer );
	return NULL;
}

DEFINE_HOOK( 0x719F17, TeleportLocomotionClass__End_Piggyback__PowerOn, 0x5 )
{
	GET( ILocomotion**, Pointer, ESI );
	PowerOnIf( *Pointer );
	return NULL;
}

I don't remember if there is anything else that is needed...

...but what the above code is doing is detecting the end of a piggyback, and restoring power to the locomotor that was piggybacked.

By the way, if you do decide to use the code I provided, I don't believe your UnitClass_SetDestination_HarvesterFix is necessary anymore.

Here is an explanation for what the code above is doing:

A Chrono Miner uses the teleport locomotor, but switches to the drive locomotor when it is driving, and switches back when it is stationary. When it switches to the drive locomotor, the teleport locomotor becomes "piggybacked" onto the drive locomotor; and when it switches back to the teleport locomotor, the "piggybacking" ends, and the teleport locomotor is un-piggybacked from the drive locomotor.

When a Magnetron lifts a target, that target switches to the jumpjet locomotor, and whatever locomotor that target was using is "piggybacked" onto the jumpjet locomotor. When the target is dropped and hits the floor, that "piggybacked" locomotor is un-piggybacked and is restored.

You can think of piggybacking as a form of "backing-up" where the game, essentially, backs-up the previous locomotor so that it can be restored later.

The original game code did not power on a locomotor when it is un-piggybacked, so I wrote code to do the power on, which is the code you see above.

How should I describe your bugfix and what is your signature?

@tyuah8
Copy link

tyuah8 commented Sep 25, 2024

My... signature? You can just reference my username, which is tyuah8.

I explain the bug fix and why it works in my previous post. Basically the bug fix works by powering on locomotors when "piggybacking" ends (when we switch back to the piggybacked locomotor), and is needed because the Service Depot powered off the teleport locomotor.

You are free to mention my explanation as well as the reason for the fix and that is to get the Chrono Miner to work after using the Service Depot.

@NetsuNegi
Copy link
Contributor Author

My... signature? You can just reference my username, which is tyuah8.

I explain the bug fix and why it works in my previous post. Basically the bug fix works by powering on locomotors when "piggybacking" ends (when we switch back to the piggybacked locomotor), and is needed because the Service Depot powered off the teleport locomotor.

You are free to mention my explanation as well as the reason for the fix and that is to get the Chrono Miner to work after using the Service Depot.

ok

@NetsuNegi NetsuNegi changed the title [BugFix]Chrono harvester cannot teleport again after repaired in repair bay bugfix [BugFix]Drive/Jumpjet/Ship/Teleport locomotor did not power on when it is un-piggybacked bugfix Sep 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants