Vampirism - Become a vampire!

Vampirism - Become a vampire!

16M Downloads

Make sucking blood take time

maxanier opened this issue ยท 14 comments

commented

Idea by CptAlfr

Instead of instantly sucking out the blood of an entity, make the process take time.

While sucking blood the victim would be frozen.
The sucking process could be interrupted by dealing damage to the vampire.

By varying the duration of the sucking process the vampire could decide how much of the victims blood they would like to take.

Also, cool particles

Main downside: More prone to bugs as this would be a process over several ticks

commented

I think a screen effect would also be fitting. When your blood is being sucked, your screen has a slowly increasing black, or red, vignette. (maybe fade in quickly as black then fade to red the closer you are to having your blood sucked.

commented

Forgot to close this. Feature has been implemented by tcheinen and merged

commented

wouldn't it be easier to give slowness to both the vampire and the vampire's victim instead of making the action itself take a long time?

commented

what about just make it the longer you feed the more blood you get

commented

Definitively (Of course limited by to total amount the victim has)

commented

Would be a lot easier but rather pointless I thin. It would not add much immersion but mostly annoy people

commented

Just noticed there was a similar issue #133 , moving the comment here:

Some vampire mechanics feel a bit off. Mainly the feeding. People have commented on the current feeding system and would like to see some changes, the first being made to the way that a vampire feeds. Rather than being an instant thing, it should be a slow drain over time. Let's say 5 seconds for a full drain that would kill a villager (and/or possibly turn them). Another suggested idea would be a "blood meter" on the side of the screen that would fill if your health and hunger were both full after feeding. This meter will be drained to heal the player and restore their hunger when lost and should last about 20 minutes from full at all levels before it is completely empty. Higher level vampires should still drain hunger faster, but have a larger blood meter and get more blood from feeding to compensate so that at any level one villager death will suffice (as long as they dont need to fight). Vampire abilities should also drain the blood bar to be used. But this should be a fixed value that only changes if the ability is improved somehow. This means that high-level vampires can use their abilites more in between feeding, but still have to suffer the cooldown whereas low-level vampires can only use it once or twice. This would also be a bit more of an encouragement to take blood bottles with
you...

This additionally suggests using the blood in more ways (e.g. for abilities) which is a good idea, however, I would skip the blood meter for now

commented

I've started work on this at https://github.com/Skyshayde/Vampirism. My current implementation functions via a potion effect. Each second it'll bite the victim entity and remove the effect if the entity is dead/you move too far away/its a player. It'll slow down the biting entity as well as in theory the victim entity. I apply slowness 127 to the victim, but I have noted that it doesn't seem to do anything. I've also dropped the blood you get from a single bite of a creature to account for the fact that it now gets called multiple times. The time to kill on a villager is approximately 5 seconds.

commented

Hey, happy to hear that.
The Potion Effect is a good idea for slowing the player. It could also potentially be used to display some GUI overlay etc.

However, I am not sure if it a good idea to "give control" over the feeding mechanism to the potion ( making the potion call biteEntity).
It might be better to implement some sort of feeding "state machine" to the VampirePlayer class.
My current idea (I did not think about it much though) would be to start a timer inside the VampirePlayer object once the player presses the feeding button. Your potion effect would be added to the player (and a separate one to the victim). Once the timer runs out (e.g. 1 second), the blood is transferred (biteEntity), if the button is still pressed and the entity still has blood, the timer is reset and the process restarts. The VampirePlayer object constantly checks (in update()) if the victim is still close enough and alive, if not the feeding is aborted and the potion effects are removed. Same happens if the player releases the feeding key.

commented

I updated my fork and it's more or less that. It definitely does feel cleaner. I did a toggle effect rather than a hold effect because setting it up to work when the key was held looked like a hassle. It should be relatively straightforward to port the current method over though. (toggle on when they key is pressed, toggle off when it goes up?)

commented

๐Ÿ‘ will have a look tomorrow

commented

So, I did think a little bit more about this.
I am very much appreciate that you are interested in helping, but before we continue on this I want to say that this feature will probably take some time. On the one hand I would like it to feel intuitive and to look cool, on the other hand it should be bug/glitch free. At the same time we have to keep in mind the MC concepts (sever/client, ticks, ...).
I do not want you stop, but I want to "warn" you that it will take quite some time to get this right.

Ultimate goal:

  • Transfer blood in small chunks while feeding is in progress
  • Slow down both vampire and victim while feeding
  • Have some kind of HUD icon or overlay while sucking blood
  • Have some kind of HUD icon or overlay while someone is sucking blood from you
  • Have some particle effects (blood flying from victim to vampire) while feeding
  • Stop feeding if button is released
  • Stop feeding if victim is too far away or dies
  • Either lock players viewing angle/crosshair onto victim or cancel feeding if player looks away
  • Make client handle the particle effects and server the potion effect as well as the actual sucking
  • Make sure client and server stay in sync
  • Verify client input on server side
  • Ensure there are no issues if (dis-)connecting or reloading the world
  • Test in multiplayer
  • Ensure NPCs can still suck blood from other NPCs

These are a lot of things, but they can be implemented step by step as long as we keep the big picture in mind.

I hope you are still interested. If so maybe create a [WIP] pull request so we can discuss the implementation over there.

If do not mind all this

commented

About the java.util.Timer:
This is probably not the best tool to do things in Minecraft.
As far as I can tell it runs in the background, so it is not controlled by the game loop. Hence it cannot respect things like paused game, server stopping, reduced tick rate (if the pc cannot keep up) and more.

There are probably several approaches to execute continuous things, but I usually put the implementation into a object that is ticked by the game loop and then use a integer timer variable to count ticks. This way we respect all the things mentioned above. Furthermore we can use the timer to check if it active. If timer > 0 the thing is currently running.
In the ticked method (usually onUpdate) we decrease the timer and execute any necessary code while the thing is active.

commented

Yeah that definitely makes sense. I'll go ahead and make a WIP pr and issues on the fork for all of those to keep track of them after class today.