Page 1 of 1

PassengerConditions on Cargo not working?

Posted: Wed Oct 18, 2017 4:52 am
by OMnom
I have the following snippet of code to stop rifles from vetting up when they get a kill inside the pillbox:

Code: Select all

    PBOX:
        Cargo:
            PassengerConditions:
                e1: inpillbox 
    E1:
        ExternalCondition@INPILLBOX:
            Condition:inpillbox
        GainsExperienceMultiplier:
            Modifier: 0
            RequiresCondition: inpillbox        
GainsExperienceMultiplier works perfectly fine when you get rid of RequiresCondition. However, I can't get it to detect PassengerConditions at all. I tried using ProximityExternalCondition as a longshot, as well as other various combinations.

A hacky solution I found would be to clone E1 and just have it never gain experience...however, the player can circumvent this just replacing the InitialActor with an actual E1.

Can anyone help me spot my error?

Posted: Wed Oct 18, 2017 10:10 am
by MustaphaTR
As i said on Discord. PassengerConditions give condition to Cargo, not Passenger. There is currently no way to do what you are trying to do.

Posted: Wed Oct 18, 2017 10:30 am
by Sleipnir
It can be done by replacing AttackGarrisoned with something like AttackOmni, and then using PassengerConditions to enable weapons defined on the pillbox itself.

Posted: Thu Oct 19, 2017 7:37 am
by OMnom
Hmm i see. I misread the PassengerConditions trait on Cargo as the condition granted to the passenger rather than the condition granted to Cargo. @MustaphaTR, I made this thread before I went to sleep after getting an answer from Nolt on Discord, which is why this question has been 'double posted' to two separate discussions.

I'm going to make an issue on github requesting someone to grant a condition when Passenger is loaded...my goal wasn't to completely remove GainsExperience from pillboxes, but rather to tone it down to scale it properly with the price of the pillbox...the 0 in the modifier was just for testing purposes. There is a large amount of people supporting the "neat" behavior of pillboxes leveling up, but there is also an equally large amount of people claiming vetted pillboxes are way too strong.

Posted: Mon Oct 23, 2017 1:13 am
by OMnom
This is my first attempt at C# coding to try and create LoadedCondition for when an actor is/isn't loaded into a Cargo actor...I got the Condition to work, but I can't get it to turn on/off.

If anyone has a spare 10 minutes, could you take a look at my fork and see what I'm doing wrong with my code? I have a link to it here on github: https://github.com/Omnomon/OpenRA/blob/ ... ssenger.cs

Posted: Mon Oct 23, 2017 7:29 pm
by abcdefg30
It looks like you never revoke the condition when unloading. You should try using the INotifyAddedToWorld interface for that (which can also replace the revoking in INotifyCreated).

Posted: Mon Oct 23, 2017 11:30 pm
by OMnom
Hmm...still don't know what's going on. Still compiles fine after changing INotifyCreated to INotifyAddedToWorld, but condition still doesn't respond as expected. The flaw in my code is not apparent to me.
My flow goes something like this:
1. If actor exists in the world, LoadedCondition is not null, and the actor is not loaded into anything else, grant LoadedCondition to the actor
2. If actor does not exist in the world and the actor is loaded, revoke LoadedCondition.

I don't know why GrantCondition turns on when the actor is loaded / does not exist in the world, and why RevokeCondition does not turn on when the actor is unloaded / exists in the world.

Code: Select all

      protected override void Created(Actor self)
		{
			conditionManager = self.Trait<ConditionManager>&#40;&#41;;

			base.Created&#40;self&#41;;
		&#125;

		void INotifyRemovedFromWorld.RemovedFromWorld&#40;Actor self&#41; &#123; 

			Unreserve&#40;self&#41;; 
			if &#40;!self.World.Map.Contains&#40;self.Location&#41; && conditionManager != null && loadedToken == ConditionManager.InvalidConditionToken && 
            !string.IsNullOrEmpty&#40;Info.LoadedCondition&#41;&#41;
				loadedToken = conditionManager.GrantCondition&#40;self, Info.LoadedCondition&#41;;
		&#125;

		void INotifyAddedToWorld.AddedToWorld&#40;Actor self&#41;
		&#123;
			if &#40;self.World.Map.Contains&#40;self.Location&#41; && loadedToken != ConditionManager.InvalidConditionToken&#41;
				loadedToken = conditionManager.RevokeCondition&#40;self, loadedToken&#41;;
		&#125;

		public void Unreserve&#40;Actor self&#41;
		&#123;
			if &#40;ReservedCargo == null&#41;
				return;
			ReservedCargo.UnreserveSpace&#40;self&#41;;
			ReservedCargo = null;
		&#125;

Posted: Tue Oct 24, 2017 9:19 am
by abcdefg30
Why do you have that "self.World.Map.Contains(self.Location)" check? It shouldn't be necessary.

Posted: Tue Oct 24, 2017 9:46 am
by Sleipnir
INotifyAddedToWorld and INotifyRemovedFromWorld aren't a good fit here. They are used in many more situations than just loading units into transports.

You should instead add a new INotifyEnteredTransport interface that you call from Cargo's Load and Unload methods. You can then add a new GrantConditionInsideTransport trait that includes a whitelist of transport cargo types that the condition is granted on.

Posted: Wed Oct 25, 2017 1:49 am
by OMnom
hmm...this will take some time for me to learn C# and how the openra flow works..
abcdefg30 wrote: Why do you have that "self.World.Map.Contains(self.Location)" check? It shouldn't be necessary.
it was a noobie attempt at seeing if I could get RevokeCondition to work