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

Create add attribute for Replace-Item Action #1254

Closed

Conversation

CoWinkKeyDinkInc
Copy link
Contributor

This PR adds a simple add attribute to the <replace-item> Action. This enables the Action to add or take away a certain number of items instead of giving the same amount back to the player. The keep-amount attribute must be set to true to use add, which takes positive or negative numbers. This lets the map maker do something like redeeming items to buy a kit.

Example

<actions>
    <action id="switch-wolf" scope="player">
        <kit id="wolf"/>
        <!-- Gives player 1 emerald if they had 4, etc -->
        <replace-item amount="[3, 64]" add="-3" keep-amount="true">
             <find material="emerald"/>
             <replace material="emerald"/>
        </replace-item>
    </action>
    <trigger filter="redeem-wolf" action="switch-wolf" scope="player"/>
</actions>
<filters>
    <all id="redeem-wolf">
        <region id="wolf-portal"/>
        <carrying>
            <item material="emerald" amount="3"/>
        </carrying>
    </all>
</filters>

In this example from my XML adaptation of Hoodoo, players of the Invaders team receive emeralds that they can use to buy a class. After entering the portal with 3 or more emeralds, they are applied the wolf kit, 3 emeralds are removed from the player and they are teleported. All extra emeralds they have are given back to the player.

@Pablete1234
Copy link
Member

I don't believe this to be the proper solution to what's intended.
Replace-item is a way to replace item stacks in the inventory, not to give items (kits) or to take away items (clear).

The whole adding behavior can be done by simply using a carrying filter, and a kit, the only thing this brings is removing items, which can be done by replacing with air (if you want to take away the whole stack), or via shops or redeemables.

What's the actual use-case for this?

@Pablete1234
Copy link
Member

Pablete1234 commented Oct 12, 2023

My suggestion to implement this type of behavior: a take-payment action, syntax somewhat inspired by shops:

<take-payment>
  <!-- This is syntax taken from the shops, you can define multiple items required as payment, but can be simpler for single-item payments -->
  <payment material="diamond" price="5"/>
  <payment material="emerald" price="5"/>
  <payment price="1">
      <!-- Item name is shown under the cost lore instead of the raw material name -->
      <item name="`bEnchanted Diamond" material="diamond">
          <enchantment level="2">sharpness</enchantment>
      </item>
  </payment>
  <success-action>
    <message><text>Success!</text></message>
    <kit>
        <chestplate material="diamond chestplate"/>
    </kit>
  </success-action>
  <fail-action>
    <message><text>You can't afford this!</text></message>
  </fail-action>
</take-payment>

When using attributes and not needing complicated prices (single item cost) it can be simplified:

<take-payment id="buy-chestplate" currency="diamond" price="5" success-action="success" fail-action="too-poor"/>

<action id="success">
  <message><text>Success!</text></message>
  <kit>
      <chestplate material="diamond chestplate"/>
  </kit>
</action>
<message id="too-poor"><text>You can't afford this!</text></message>

@CoWinkKeyDinkInc
Copy link
Contributor Author

CoWinkKeyDinkInc commented Oct 14, 2023

I understand that the shops would be a more easier and simpler way to do this. I wanted to preserve the original design of Cubist's 2013 a/d vanilla map Hoodoo, where the attackers bought kits with XP levels (I replaced this with emeralds) by walking into portals.

the only thing this brings is removing items, which can be done by replacing with air (if you want to take away the whole stack), or via shops or redeemables.

Redeemables would take away all of an item, not a specific amount of an item. It wouldn't work for applying kits or doing other actions I need to do anyway.

Outside of applying kits, there is a portal that can be unlocked for the whole Invaders team by spending 5 emeralds with walking over the portal exit, and as far as I know there isn't another way to do this already in PGM with the spending aspect intact.

<action id="enable-invader-shortcut" scope="player">
    <replace-item amount="[5, 64]" add="-5" keep-amount="true">
        <find material="emerald"/>
        <replace material="emerald"/>
    </replace-item>
    <switch-scope outer="player" inner="team">
        <message text="`e`lInvader shortcut has been unlocked!"/>
        <set var="shortcut_enabled" value="1"/>
    </switch-scope>
</action>
<trigger filter="redeem-invader-shortcut" action="enable-invader-shortcut" scope="player"/>
<filters>
    <all id="redeem-invader-shortcut">
        <region id="invaders-shortcut-exit"/>
        <team>invaders</team>
        <carrying>
            <item material="emerald" amount="5"/>
        </carrying>
        <variable var="shortcut_enabled">0</variable>
    </all>
    <all id="enter-invader-shortcut">
        <team>invaders</team>
        <variable var="shortcut_enabled">1</variable>
    </all>
</filters>
<portals>
    <portal x="@34.5" y="@60" z="@113.5" yaw="@-90" filter="enter-invader-shortcut">
        <region><cuboid min="20,25,20" max="19,27,21"/></region>
    </portal>
</portals>

Applying the kits using Actions instead of the Shop also allows me to set player variables, so I can disable fall damage specifically for the Eagle kit.

<action id="switch-eagle" scope="player">
    <kit id="eagle"/>
    <replace-item amount="[1, 64]" add="-1" keep-amount="true">
        <find material="emerald"/>
        <replace material="emerald"/>
    </replace-item>
    <set var="is_eagle" value="1"/>
</action>
<damage>
    <deny>
        <!-- Disable fall damage to all eagle players -->
        <all>
            <variable var="is_eagle">1</variable>
            <cause>fall</cause>
        </all>
    </deny>
</damage>

The XML is otherwise complete and finished other than this minor spending thing that needs to be added.

@Pablete1234
Copy link
Member

The issue is your approach doesn't properly work in some scenarios, replace-item works on item stacks, so does the filter for carrying. That means if you have 2 stacks of 5 emeralds, both of them will be subtracted from, or if you have 2 stacks of 2 and 3 emeralds, the filter won't let you in saying you don't have the required 5 emeralds.

There's a reason i'm suggesting reusing the logic in the shops in a new action like take-payment, because payment is properly implemented in shops to scan the whole inventory and add-up everything, which should be a minimal working requirement for this to be working as intended.

Copy link
Member

@Pablete1234 Pablete1234 left a comment

Choose a reason for hiding this comment

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

Please read my last comment, i think this has inherent flaws in how it's been designed and should instead opt for a different action that properly addresses the desired behavior

@CoWinkKeyDinkInc
Copy link
Contributor Author

I agree there is a lot of oversights. A lot of things have been going on lately so I haven't been able to fix this up yet. I'll be working on it soon.

@Pablete1234
Copy link
Member

Superceeded by #1305

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants