commit - e7e9d307e65bdad02bdebb24a13ecc353f2960a2
commit + a34134918ad5eb64192e6d33828d433aa9db2f8c
blob - 0024603ad7d5f2b0b2cad4074fd940da7aabe2b8
blob + 07f1032f49506cc12acc1cb6965600965a419a27
--- include/globals.h
+++ include/globals.h
uint8_t y;
short z;
// Lower 5 bits: health
- // Upper 3 bits: reserved (?)
+ // Middle 1 bit: reserved for future use
+ // Upper 2 bits: panic timer
uint8_t data;
} MobData;
blob - c55ed204967a6502778b85701cf8034408461658
blob + a680c06915a613fe98831970c443aa7bf9a5e598
--- src/procedures.c
+++ src/procedures.c
// Don't continue if the mob is already dead
if (mob_health == 0) return;
+ // Set the mob's panic timer
+ mob->data |= (3 << 6);
+
// Process health change on the server
if (mob_health <= damage) {
mob_data[i].type == 95 || // Pig
mob_data[i].type == 106 // Sheep
);
+ // Mob "panic" timer, set to 3 after being hit
+ // Currently has no effect on hostile mobs
+ uint8_t panic = (mob_data[i].data >> 6) & 3;
// Burn hostile mobs if above ground during sunlight
if (!passive && (world_time < 13000 || world_time > 23460) && mob_data[i].y > 48) {
uint32_t r = fast_rand();
if (passive) {
- // Update passive mobs once per 4 seconds on average
- if (r % (4 * (unsigned int)TICKS_PER_SECOND) != 0) continue;
+ if (panic) {
+ // If panicking, move randomly at up to 4 times per second
+ if (TICKS_PER_SECOND >= 4) {
+ uint32_t ticks_per_panic = (uint32_t)(TICKS_PER_SECOND / 4);
+ if (server_ticks % ticks_per_panic != 0) continue;
+ }
+ // Reset panic state after timer runs out
+ // Each panic timer tick takes one second
+ if (server_ticks % (uint32_t)TICKS_PER_SECOND == 0) {
+ mob_data[i].data -= (1 << 6);
+ }
+ } else {
+ // When not panicking, move idly once per 4 seconds on average
+ if (r % (4 * (unsigned int)TICKS_PER_SECOND) != 0) continue;
+ }
} else {
// Update hostile mobs once per second
if (server_ticks % (uint32_t)TICKS_PER_SECOND != 0) continue;