Mobs, who die without food

Hello!

I want to create a simulation, where a human-looking mob (e. g. villager) collects food and if it fails to collect enough fast enough, dies of hunger.

My plugin will be implement the food collection algorithm. I’d like to reuse the health management code (i. e. ideally I won’t implement the code, which decides, whether the mob died from hunger or not).

Are there any mobs (preferably human-looking), which

a) die, if they don’t get enough food in time and
b) which I can re-use in my Sponge plugins

?

Thanks

Dmitri

b) You can reuse every entity for your plugin(human looking: villager, fake player, zombie, zombie pigman, witch)
a) You have probably played Minecraft, so you know there aren’t NPCs that even have a hunger bar.

2 Likes

Well, villagers won’t reproduce without enough food, and have an inventory that can be filled with food items. They even collect crops and share food by themselves. But they won’t die.

1 Like

@RandomByte @VcSaJen Thanks for your help!

As far as I know, no mobs or players die from hunger (unless hardcore got harder recently). So no matter what you’ll need to do some kind of health management.

See: http://minecraft.gamepedia.com/Hunger
On Easy mode, starvation damage will not lower you below half your maximum health, while on Normal mode, it can reduce you to a single hit point. On Hard mode, starvation can kill. Interestingly, the Protection enchantment on armor reduces starvation damage.

1 Like

Hello!

Since there are no existing mobs, which may die of hunger, I need

  1. to create my own mob (e. g. villager) and
  2. then regularly check, how much time has passed his last meal (and if he didn’t eat for 30 days, he dies).

Question 1: Is this approach correct?

Let’s assume it is. I’ve created a simple plugin project to get an understanding of how to do it.

You can find the source code here.

In my plugin class (Bitbucket) I create a command, which spawns a villager:

class AlmaEconSimPlugin {
    @Inject private var logger: Logger? = null
    @Inject private var game: Game? = null

    @Listener
    fun onPreInit(event: GamePreInitializationEvent) {
        val gm = game
        if (gm == null) {
            return;
        }
        [...]
        gm.commandManager.register(
                this,
                createSpawnMortal(),
                "spm"
        )
    }
    [...]
	private fun createSpawnMortal(): CommandCallable? {
        return CommandSpec
                .builder()
                .description(Text.of("Spawns a villager, which dies of hunger, if he or she doesn't eat enough"))
                .executor(SpawnMortalCommand()).build()
    }
    [...]
}

The command (Bitbucket) creates a villager according to the official tutorial (https://docs.spongepowered.org/master/en-GB/plugin/entities/spawning.html):

class SpawnMortalCommand : CommandExecutor {
    override fun execute(src: CommandSource?, ctx: CommandContext?): CommandResult? {
        if (src is Player) {
            val location = src.location
            val extent = location.extent
            val optional = extent.createEntity(EntityTypes.VILLAGER, location.position)
            if (optional.isPresent) {
                val villager = optional.get()
                extent.spawnEntity(
                        villager,
                        Cause.of(NamedCause.source(EntitySpawnCause.builder()
                                .entity(villager).type(SpawnTypes.PLUGIN).build()))
                )
            }
        }
        return CommandResult.success()
    }
}

Question 2: Where do I go from here?

Specifically - how do I set up a timer, which will call a method, whenever a day passes in Minecraft?

In that method I’ll implement the check whether the mob lives further (has eaten at least once during the last 30 days) or dies.

Thanks

Dmitri

Every tick, check what time it is. If it’s 00:00, do your calculation. Use a repeating task for this.

2 Likes

The plugin must watch out time set ... which might skip 00:00.

You are the first one who I encountered who also uses Kotlin for plugin development. :grinning: :thumbsup:

Btw: Like here you can use lateinit to get rid of Logger?, so it’s only Logger. Then the null check can be avoided.

1 Like

@RandomByte Thanks for the lateinit tip!

How can I execute some piece of code, whenever the user enters time set ... ?

Because there is no ChangeTimeEvent(which would be fired every tick except the gamerule doDaylightCircle is disabled) I would use SendCommandEvent. However there can be other plugins that change the time automatically. Don’t know how to catch these. You could compare every tick the current time with one tick before, but that doesn’t seen to be good IMO.

1 Like

Are there any other ways to change the time in a plugin apart from issuing time set ... programmatically?

I couldn’t find documentation about the alternatives.

world.getProperties().setWorldTime(time)

You can also use getWorldTime store the time, and periodically check the current value against the stored value. You will be able to detect the change of day this way.

1 Like