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

WorldThingGoalReached Virtual #2823

Closed
wants to merge 2 commits into from

Conversation

MajorCooke
Copy link
Contributor

@MajorCooke MajorCooke commented Nov 19, 2024

Added WorldThingGoalReached(WorldEvent e).

Called whenever an actor chasing a goal reaches it, only by A_DoChase.

  • Thing: actor that reached the goal
  • Inflictor: The previous goal it just reached.
  • The new goal is stored in actor's goal.

Called whenever an actor chasing a goal reaches it.
- `Thing`: actor that reached the goal
- `Inflictor`: The previous goal it just reached.
- The new goal is stored in actor's `goal`.
@MajorCooke MajorCooke marked this pull request as draft November 19, 2024 22:11
@MajorCooke MajorCooke marked this pull request as ready for review November 20, 2024 01:22
@RicardoLuis0
Copy link
Collaborator

RicardoLuis0 commented Nov 20, 2024

can't you just, in a mod, save the old goal and check if the pointer changed and if the distance is close? what's the need for an actual event?

@MajorCooke
Copy link
Contributor Author

Doing that to many, many monsters at once isn't healthy.

@RicardoLuis0
Copy link
Collaborator

RicardoLuis0 commented Nov 20, 2024

if you run the checks from an inventory item (DoEffect) instead of from an event handler it should be fine

@MajorCooke
Copy link
Contributor Author

MajorCooke commented Nov 20, 2024

That'd triple the number of tick-like function calls, and double the amount of thinkers - for my purposes specifically, it's about giving all the monsters some sort of path to follow within the map. No monster is excluded.

@RicardoLuis0
Copy link
Collaborator

would this be used in maps where thinker count is a bottleneck? for most maps rendering visible actors is way slower than ticking all actors

@MajorCooke
Copy link
Contributor Author

Yes.

@RicardoLuis0
Copy link
Collaborator

still not convinced this is needed, but what's the difference in performance between using this event and going the inventory item route?

@MrRaveYard
Copy link
Contributor

MrRaveYard commented Nov 20, 2024

The idea itself seems fine, imo.
My only counterpoint would be that the performance difference between "actively checking" vs "event listening" would only rear its head at a point where you'd have so many actors that it is already unplayable for other reasons.

Positive use for this would be to have a cross-mod compatibility so that each mod doesn't have to make its own active listener (imagine having 10 mods which each attach one inventory just to do the same check for their own purposes).

@MajorCooke
Copy link
Contributor Author

MajorCooke commented Nov 20, 2024

Rave nailed it. Especially for slaughter maps, and ones that are highly detailed like Sunder. And they have a lot of ACS stuff going on, which can also slow things down.

@Boondorl
Copy link
Contributor

Boondorl commented Nov 20, 2024

Existing maps are rarely ever going to use the goal system and from the sounds of it this might not even be desired behavior. Keep in mind that any UDMF map that has a monster using a path will also trigger this event with zero way to validate if it's a map monster doing its thing or your own custom behavior. If you're going to check against custom nodes, you might as well program that behavior into the node handling itself.

Goals already have the ability to activate specials on arrival. If you're doing this for a universal mod it really sounds like you're just making your own goals anyway, so spawn a goal special as well and have that execute a script of your choosing. I don't think this is conceptually a bad idea, but there's already ways to handle this and frankly, any mod mixing and matching goal handling is already going to be fighting against each other and, arguably worse, the mapper.

self->Level->localEventManager->WorldThingGoalReached(self, oldgoal);
}

DEFINE_ACTION_FUNCTION(AActor, GoalReached)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be native
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GoalReached, GoalReached)

@@ -2370,6 +2371,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look2)
return 0;
}

void GoalReached(AActor* self, AActor* oldgoal)
{
if (self && self->Level)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self doesn't need to be nulled checked since the VM ensures that this won't happen

@@ -2592,6 +2608,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
}
actor->flags7 &= ~MF7_INCHASE;
actor->goal = newgoal;
GoalReached(actor, savedgoal);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing destruction check before calling this since a goal special could delete it.
if (!(actor->ObjectFlags & OF_EuthanizeMe))

@madame-rachelle
Copy link
Collaborator

I, likewise, am not convinced that this is needed. The engine gets a constant barrage of features that have very niche use and in this case you can accomplish the same thing with a +NOBLOCKMAP goal actor that detects when it is bumped with for example CollidedWith.

@MajorCooke
Copy link
Contributor Author

MajorCooke commented Nov 21, 2024

I, likewise, am not convinced that this is needed. The engine gets a constant barrage of features that have very niche use and in this case you can accomplish the same thing with a +NOBLOCKMAP goal actor that detects when it is bumped with for example CollidedWith.

Last I tried that, it requires bMISSILE which opens up a whole different can of problems.It was a while ago, but if it works now then that would solve my problem. I'll try that again and see if results are different this time.

@madame-rachelle
Copy link
Collaborator

If it doesn't work you can also try an actor like this:

class pathinggoal : actor
{
	default
	{
		+INVISIBLE;
	}
	states
	{
	Spawn:
		TNT1 A -1;
		loop;
	}
	override bool CanCollideWith(actor other, bool passive)
	{
		if (passive)
		{
			// actor 'other' entered my area, do stuff here, keep this as short as possible because this will be called a lot
		}
		return false;
	}
}

@MajorCooke
Copy link
Contributor Author

I'll come back to this after I do a bit more testing. Closing this for now.

@MajorCooke MajorCooke closed this Nov 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.

5 participants