Jump to content

[MC 1.16.3] I need help with how Forge works. Implementing new PVP and PVE mechanics.


Recommended Posts

Posted (edited)

 

VERSION I'M USING RIGHT NOW: MINECRAFT 1.16.3

 

Currently I'm developing a mod that changes the pvp and pve mechanics, adding a stamina system with the existir air system, overwriting it.

So far so good, I haven't had so much problems, but I'm sure there will be a lot more problems, because of my not enough knowledge of java and the forge api.

 

First I'm implementing a stamina mechanic which the "air" of the player will play a role here.

I put the max air number "99" to show it forever, even outside the water.

I "use" the air with each action, like jumping or sprinting.

 

My questions:

  • The sword swings, I'm not sure how to implement those, how do I detect a sword swing? Is that an event? I'll try detecting left clicks...
    • Because the approach I tried was, checking the "isSwingInProgress" and checking "swingProgress" but I only want it to happen 1 tick to make the player always waste 80 air in one step, and not 40 air in several random steps (depending on how fast is the swing of the sword, will either deplete much or less oxygen, not a reliable solution...)
  • Using air while charging bow, how? is there an event for that? or checking "holding right click" directly while char is holding a bow? which approach is the best?
  • What is the ideal place to learn about this mod API? if there is none, I just want to know, to not waste my time looking for it and to only focus on downloading examples.



If you have a source of an example mod that changes gameplay and not only adds blocks or items, I'd be really grateful to you.

This is the code of these first features:

 @SubscribeEvent
    public static void onPlayerTick(TickEvent.PlayerTickEvent event){
        if(event.player.isSprinting()){
             event.player.setAir(event.player.getAir() - 3);
        }else if(!event.player.isSprinting() && !event.player.isSneaking()){
            event.player.setAir(event.player.getAir());
        }

        if(event.player.getAir() <= 0){
            event.player.attackEntityFrom(DamageSource.GENERIC, 1.0F);
            if(event.player.getAir() < 0) {
                event.player.setAir(0);
            }
        }else if(event.player.getAir() > event.player.getMaxAir()-1){
            event.player.setAir(event.player.getMaxAir()-1);
        }

        if(event.player.isSwingInProgress && event.player.swingProgressInt == 3
                && event.player.prevSwingProgress != event.player.swingProgressInt){
            event.player.setAir(event.player.getAir()-40);
        }


        if(enhanceLevel ==1){
            ((PlayerEntity) event.player).removePotionEffect(Effects.STRENGTH);
        }else if(enhanceLevel == 2){
            ((PlayerEntity) event.player).addPotionEffect(new EffectInstance(Effects.STRENGTH,9999, 0));
        }else if(enhanceLevel == 3){
            ((PlayerEntity) event.player).addPotionEffect(new EffectInstance(Effects.STRENGTH,9999, 1));
        }
    }

 

This is the code I used, I'm planning to refactor it today. The enhanceLevel is another mechanic but I'll leave it for later until I polish enough the custom breathing system.


I tried reading the documentation and I have seen a lot of times, it's not as documented as I expected. I don't know the reasons why the official documentation is just an introduction and not a whole explanation of each function, class, methods but at least I've read that the autocompletion will give you enough explanation of what is going to happen with each function, classes, methods, events...

 

The event system also has worked, but there are not enough events or maybe they are implemented somewhere else, like how I used "PlayerTickEvent".

 

 

Edited by jkf16m
Posted (edited)

If the official documentation has the whole explanation of every methods, classes, fields... etc, the time taken to update it will be long enough for Vanilla to release another version. If you don't think the doc  contains enough information, you can always make new pr and improve it.

PlayerTickEvent is a type of TickEvent which it is triggered twice a tick, TickEvent.Phase.Start/End, you should check for one of them.

For the swingProgress because it is triggered once a tick so it take away 80 instead of 40

For the bow you can check if player's holding the bow and if the hand is active, see how ItemModelProperties decides "pulling" property for bows.

 

 

Edited by poopoodice
Posted

About the bow, how do I use ItemModelProperties?

 

// see if the player's hand is active (idk what that means) and is holding a bow.
        if(player.isHandActive() && player.getHeldItemMainhand().getTranslationKey() == new ItemStack(Items.BOW).getTranslationKey()){
            Item playersBow = player.getHeldItemMainhand().getItem(); //get player item

            ItemModelsProperties.func_239417_a_(); //?
            ItemModelsProperties.func_239418_a_(); //?

        }

 

which is the variable to make the comparison for this property?

 

This is what I found in the implementation
 

func_239418_a_(Items.BOW, new ResourceLocation("pulling"), (p_239428_0_, p_239428_1_, p_239428_2_) -> {
         return p_239428_2_ != null && p_239428_2_.isHandActive() && p_239428_2_.getActiveItemStack() == p_239428_0_ ? 1.0F : 0.0F;
      });

 

Posted (edited)
Quote

 return p_239428_2_ != null && p_239428_2_.isHandActive() && p_239428_2_.getActiveItemStack() == p_239428_0_

This statement in ItemModelProperties decides whether the player is pulling the bow (what I meant was you can have a look at the class to get an idea of how it does it, instead of directly use the methods in that place), which was one of the thing you were looking for.

On 11/13/2020 at 10:03 PM, jkf16m said:

 

  • Using air while charging bow, how? is there an event for that? or checking "holding right click" directly while char is holding a bow? which approach is the best?

 

Quote

player.getHeldItemMainhand().getTranslationKey() == new ItemStack(Items.BOW).getTranslationKey()

You should not compare the items like this, this is not how you compare strings either (it will never be true, use Object#equals). Since items in vanilla are singletons, you can use == to compare them, for example

stack.getItem() == Items.BOW

 

isHandActive() checks if the player is using something like eating, drinking...etc

Edited by poopoodice

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.