#pragma once

#ifdef GAMEQC
MODEL(ARC_MUZZLEFLASH, "models/flash.md3");
MODEL(ARC_VIEW, W_Model("h_arc.iqm"));
MODEL(ARC_WORLD, W_Model("v_arc.md3"));
MODEL(ARC_ITEM, W_Model("g_arc.md3"));

SOUND(ARC_BOLT_FIRE, W_Sound("electro_fire2"));
SOUND(ARC_BOLT_IMPACT, W_Sound("electro_impact"));
SOUND(ARC_FIRE, W_Sound("arc_fire"));
SOUND(ARC_LOOP, W_Sound("arc_loop"));
SOUND(ARC_LOOP_OVERHEAT, W_Sound("arc_loop_overheat"));
SOUND(ARC_STOP, W_Sound("arc_stop"));
#endif

CLASS(Arc, Weapon)
#ifdef SVQC
/* spawnfunc */ ATTRIB(Arc, m_canonical_spawnfunc, string, "weapon_arc");
/* rating    */ ATTRIB(Arc, bot_pickupbasevalue, float, 8000);
#endif
/* ammotype  */ ATTRIB(Arc, ammo_type, Resource, RES_CELLS);
/* impulse   */ ATTRIB(Arc, impulse, int, 3);
/* flags     */ ATTRIB(Arc, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_TYPE_HITSCAN);
/* color     */ ATTRIB(Arc, m_color, vector, '0.463 0.612 0.886');
#ifdef GAMEQC
/* modelname */ ATTRIB(Arc, mdl, string, "arc");
/* model     */ ATTRIB(Arc, m_model, Model, MDL_ARC_ITEM);
/* flash mdl */ ATTRIB(Arc, m_muzzlemodel, Model, MDL_Null);
/* flash eff */ ATTRIB(Arc, m_muzzleeffect, entity, EFFECT_ARC_MUZZLEFLASH);
#endif
#ifdef CSQC
/* crosshair */ ATTRIB(Arc, w_crosshair, string, "gfx/crosshairhlac");
/* crosshair */ ATTRIB(Arc, w_crosshair_size, float, 0.7);
#endif
/* wepimg    */ ATTRIB(Arc, model2, string, "weaponarc");
/* refname   */ ATTRIB(Arc, netname, string, "arc");
/* wepname   */ ATTRIB(Arc, m_name, string, _("Arc"));

#define X(BEGIN, P, END, class, prefix) \
	BEGIN(class) \
		P(class, prefix, bolt, float, NONE) \
		P(class, prefix, bolt_ammo, float, NONE) \
		P(class, prefix, bolt_bounce_count, float, NONE) \
		P(class, prefix, bolt_bounce_explode, float, NONE) \
		P(class, prefix, bolt_bounce_lifetime, float, NONE) \
		P(class, prefix, bolt_count, float, NONE) \
		P(class, prefix, bolt_damageforcescale, float, NONE) \
		P(class, prefix, bolt_damage, float, NONE) \
		P(class, prefix, bolt_edgedamage, float, NONE) \
		P(class, prefix, bolt_force, float, NONE) \
		P(class, prefix, bolt_health, float, NONE) \
		P(class, prefix, bolt_lifetime, float, NONE) \
		P(class, prefix, bolt_radius, float, NONE) \
		P(class, prefix, bolt_refire, float, NONE) \
		P(class, prefix, bolt_refire2, float, NONE) \
		P(class, prefix, bolt_speed, float, NONE) \
		P(class, prefix, bolt_spread, float, NONE) \
		P(class, prefix, beam_ammo, float, NONE) \
		P(class, prefix, beam_animtime, float, NONE) \
		P(class, prefix, beam_botaimlifetime, float, NONE) \
		P(class, prefix, beam_botaimspeed, float, NONE) \
		P(class, prefix, beam_damage, float, NONE) \
		P(class, prefix, beam_degreespersegment, float, NONE) \
		P(class, prefix, beam_distancepersegment, float, NONE) \
		P(class, prefix, beam_falloff_halflifedist, float, NONE) \
		P(class, prefix, beam_falloff_maxdist, float, NONE) \
		P(class, prefix, beam_falloff_mindist, float, NONE) \
		P(class, prefix, beam_force, float, NONE) \
		P(class, prefix, beam_healing_amax, float, NONE) \
		P(class, prefix, beam_healing_aps, float, NONE) \
		P(class, prefix, beam_healing_hmax, float, NONE) \
		P(class, prefix, beam_healing_hps, float, NONE) \
		P(class, prefix, beam_heat, float, NONE) /* heat increase per second (primary) */ \
		P(class, prefix, beam_maxangle, float, NONE) \
		P(class, prefix, beam_nonplayerdamage, float, NONE) \
		P(class, prefix, beam_range, float, NONE) \
		P(class, prefix, beam_refire, float, NONE) \
		P(class, prefix, beam_returnspeed, float, NONE) \
		P(class, prefix, beam_tightness, float, NONE) \
		P(class, prefix, burst_ammo, float, NONE) \
		P(class, prefix, burst_damage, float, NONE) \
		P(class, prefix, burst_healing_aps, float, NONE) \
		P(class, prefix, burst_healing_hps, float, NONE) \
		P(class, prefix, burst_heat, float, NONE) /* heat increase per second (secondary) */ \
		P(class, prefix, cooldown, float, NONE) /* heat decrease per second when resting */ \
		P(class, prefix, cooldown_release, float, NONE) /* delay weapon re-use when releasing button */ \
		P(class, prefix, overheat_max, float, NONE) /* maximum heat before jamming */ \
		P(class, prefix, overheat_min, float, NONE) /* minimum heat to wait for cooldown */ \
		P(class, prefix, pickup_ammo, float, NONE) \
		P(class, prefix, switchdelay_drop, float, NONE) \
		P(class, prefix, switchdelay_raise, float, NONE) \
		P(class, prefix, weaponreplace, string, NONE) \
		P(class, prefix, weaponstartoverride, float, NONE) \
		P(class, prefix, weaponstart, float, NONE) \
		P(class, prefix, weaponthrowable, float, NONE) \
	END()
	W_PROPS(X, Arc, arc)
#undef X

ENDCLASS(Arc)
REGISTER_WEAPON(ARC, NEW(Arc));

SPAWNFUNC_WEAPON(weapon_arc, WEP_ARC)

#ifdef GAMEQC
const float ARC_MAX_SEGMENTS = 20;
vector arc_shotorigin[4];
.vector beam_start;
.vector beam_dir;
.vector beam_wantdir;
.int beam_type;

const int ARC_BT_MISS =        0x00;
const int ARC_BT_WALL =        0x01;
const int ARC_BT_HEAL =        0x02;
const int ARC_BT_HIT =         0x03;
const int ARC_BT_BURST_MISS =  0x10;
const int ARC_BT_BURST_WALL =  0x11;
const int ARC_BT_BURST_HEAL =  0x12;
const int ARC_BT_BURST_HIT =   0x13;
const int ARC_BT_BURSTMASK =   0x10;

const int ARC_SF_UPDATE =      BIT(0);
const int ARC_SF_START =       BIT(1);
const int ARC_SF_WANTDIR =     BIT(2);
const int ARC_SF_BEAMDIR =     BIT(3);
const int ARC_SF_BEAMTYPE =    BIT(4);
const int ARC_SF_LOCALMASK =   ARC_SF_START | ARC_SF_WANTDIR | ARC_SF_BEAMDIR;
#endif
#ifdef SVQC
.entity arc_beam;
.bool arc_BUTTON_ATCK_prev; // for better animation control
.float beam_prev;
.bool beam_initialized;
.bool beam_bursting;
.float beam_teleporttime;
.float beam_heat; // (beam) amount of heat produced
.float arc_overheat; // (dropped arc/player) time during which it's too hot
.float arc_cooldown; // (dropped arc/player) cooling speed
.float arc_heat_percent;
.bool arc_smoke_sound;
#endif
#ifdef CSQC

.vector beam_color;
.float beam_alpha;
.float beam_thickness;
.entity beam_traileffect;
.entity beam_hiteffect;
.float beam_hitlight[4]; // 0: radius, 123: rgb
.entity beam_muzzleeffect;
.float beam_muzzlelight[4]; // 0: radius, 123: rgb
.string beam_image;

.entity beam_muzzleentity;

.float beam_usevieworigin;
.bool beam_initialized;
.vector beam_shotorigin;

entity Draw_ArcBeam_callback_entity;
float Draw_ArcBeam_callback_last_thickness;
vector Draw_ArcBeam_callback_last_top; // NOTE: in same coordinate system as player.
vector Draw_ArcBeam_callback_last_bottom; // NOTE: in same coordinate system as player.
#endif
