#pragma once

#include <common/notifications/all.qh>

REGISTRY(Deathtypes, BITS(8))
REGISTER_REGISTRY(Deathtypes)
REGISTRY_CHECK(Deathtypes)

REGISTRY_DEFINE_GET(Deathtypes, NULL)

// .m_name is the deathtype's name
// .message is an extra msg to differentiate types
.entity death_msgself;
.entity death_msgmurder;
.entity death_msg_ent_self;
.entity death_msg_ent_murder;

#define REGISTER_DEATHTYPE(id, msg_death, msg_death_by, msg_death_ent, msg_death_ent_by, extra) \
	REGISTER(Deathtypes, DEATH, id, m_id, new_pure(deathtype)) \
	{ \
		this.m_id += DT_FIRST; \
		this.m_name = #id; \
		this.message = extra; \
		this.death_msgself = msg_death; \
		this.death_msgmurder = msg_death_by; \
		this.death_msg_ent_self = msg_death_ent; \
		this.death_msg_ent_murder = msg_death_ent_by; \
	}

const int DEATH_WEAPONMASK     = BITS(8);
const int HITTYPE_SECONDARY    = BIT(8);
const int HITTYPE_SPLASH       = BIT(9);  ///< automatically set by RadiusDamage
const int HITTYPE_BOUNCE       = BIT(10); ///< set manually after projectile has bounced
const int HITTYPE_ARMORPIERCE  = BIT(11); ///< ignore armor calculations
const int HITTYPE_SOUND        = BIT(12); ///< cause bleeding from ears
const int HITTYPE_SPAM         = BIT(13); ///< set manually after first RadiusDamage, stops effect spam
const int DEATH_HITTYPEMASK = HITTYPE_SECONDARY | HITTYPE_SPLASH | HITTYPE_BOUNCE | HITTYPE_ARMORPIERCE | HITTYPE_SOUND | HITTYPE_SPAM;
// normal deaths begin
const int DT_FIRST             = BIT(14);

#define DEATH_ISSPECIAL(t)      (t >= DT_FIRST)
#define DEATH_IS(t, dt)         (DEATH_ISSPECIAL(t) && (REGISTRY_GET(Deathtypes, t - DT_FIRST)) == dt)
#define DEATH_ENT(t)            (DEATH_ISSPECIAL(t) ?  (REGISTRY_GET(Deathtypes, t - DT_FIRST)) : NULL)
#define DEATH_ISVEHICLE(t)      (DEATH_ISSPECIAL(t) && (REGISTRY_GET(Deathtypes, t - DT_FIRST)).message == "vehicle")
#define DEATH_ISTURRET(t)       (DEATH_ISSPECIAL(t) && (REGISTRY_GET(Deathtypes, t - DT_FIRST)).message == "turret")
#define DEATH_ISMONSTER(t)      (DEATH_ISSPECIAL(t) && (REGISTRY_GET(Deathtypes, t - DT_FIRST)).message == "monster")
#define DEATH_WEAPONOF(t)       (DEATH_ISSPECIAL(t) ? WEP_Null : REGISTRY_GET(Weapons, (t) & DEATH_WEAPONMASK))
#define DEATH_ISWEAPON(t, w)    (DEATH_WEAPONOF(t) == (w))

string Deathtype_Name(int deathtype);

#include "all.inc"
