#include "scripts/common.txt"
const array<int> BPVillagerDeathAnims = {anim_aiDeathViolent, anim_aiDeathStand, anim_aiDeathRunning, anim_aiGruntDeathViolentAlt, anim_aiGruntDeathStandAlt, anim_aiGruntDeathRunningAlt};		

class BPVillager : ScriptObject {
	bool start = false;
	kActor @self;
	//------------------------------------------------------------------------------------------------------------------------
    BPVillager(kActor @actor) {
        @self = actor;
    }
	//------------------------------------------------------------------------------------------------------------------------
    void OnTick() {
		if (!start) {
			start = true;
			SetModelTextures();
		}
	}
	//------------------------------------------------------------------------------------------------------------------------
    void OnSpawn() {
    }
	//------------------------------------------------------------------------------------------------------------------------
    void OnDamage(kActor @instigator, kDictMem @damageDef, const int damage)
    {
		if (damageDef is null) {
            return;
        }   
		bool bValue;
        if (damageDef.GetBool("bArrow", bValue) && bValue == true) {
			kActor @arrow = TossItem("BP_Arrow");		
			arrow.Scale().Set(0.35f, 0.35f, 0.35f);
			arrow.Pitch() = Math::Deg2Rad(180);
			arrow.RunFxEvent("ArrowPickup_Glow");
        }
    }
	//------------------------------------------------------------------------------------------------------------------------
	kActor@ TossItem(const kStr &in itemName) {
		kActor @item = ActorFactory.Spawn(itemName,
                                          self.Origin().x,
                                          self.Origin().y,
                                          self.Origin().z + 32.0f,
                                          0, self.SectorIndex());
        item.Gravity() = 0.5f;
        item.BounceDamp() = 0.5f;
        item.ClipFlags() = (CF_DROPOFF|CF_CLIPEDGES|CF_NOCLIPACTORS|CF_COLLIDEFLOORS|CF_COLLIDEHEIGHT);
        item.Velocity().x = Math::RandCFloat() * 4.096f;
        item.Velocity().y = Math::RandCFloat() * 4.096f;
        item.Velocity().z = 4.096f + (Math::RandFloat() * 4.096f);
		return item;
	}
	//------------------------------------------------------------------------------------------------------------------------
	void PlayRandomAnimation(const array<int> &anims) {
		int i = Math::RandMax(anims.length());
		PlayAnimation(anims[i]);
    }
	//------------------------------------------------------------------------------------------------------------------------
	void PlayAnimation(int anim) {
        self.AnimState().Blend(anim, 4.0f, 4.0f, ANF_ROOTMOTION);
    }
	//------------------------------------------------------------------------------------------------------------------------
    void OnDeath(kActor @killer, kDictMem @damageDef) {
		PlayRandomAnimation(BPVillagerDeathAnims);
		self.Flags() &= ~AF_SOLID;
		
		if (damageDef is null) {
            return;
        }   
		bool bValue;
        if (damageDef.GetBool("bArrow", bValue) && bValue == true) {
			kActor @arrow = TossItem("BP_Arrow");		
			arrow.Scale().Set(0.35f, 0.35f, 0.35f);
			arrow.Pitch() = Math::Deg2Rad(180);
			arrow.RunFxEvent("ArrowPickup_Glow");
        }
    }
	//------------------------------------------------------------------------------------------------------------------------
    void DeathSound(kActor @instigator, const float w, const float x, const float y, const float z) {
        if (self.ModelVariation() >= GV_CYBORG_PULSE_RIFLE && self.ModelVariation() <= GV_CYBORG_SPEAR) {
            self.PlaySound("sounds/shaders/ancient_warrior_death.ksnd");
            return;
        }
        else if (self.ModelVariation() >= GV_DEMON_AXE && self.ModelVariation() <= GV_DEMON_LORD) {
            switch(Math::RandMax(3)) {
				case 0:
					self.PlaySound("sounds/shaders/demon_death_scream_1.ksnd");
					break;
				case 1:
					self.PlaySound("sounds/shaders/demon_death_scream_2.ksnd");
					break;
				case 2:
					self.PlaySound("sounds/shaders/demon_death_scream_3.ksnd");
					break;
            }
            return;
        }
        
        switch(Math::RandMax(3)) {
			case 0:
				self.PlaySound("sounds/shaders/human_death_scream_1.ksnd");
				break;
			case 1:
				self.PlaySound("sounds/shaders/human_death_scream_2.ksnd");
				break;
			case 2:
				self.PlaySound("sounds/shaders/human_death_scream_3.ksnd");
				break;
        }
    }
	//------------------------------------------------------------------------------------------------------------------------
    void InjurySound(kActor @instigator, const float w, const float x, const float y, const float z) {
        if (self.ModelVariation() >= GV_CYBORG_PULSE_RIFLE && self.ModelVariation() <= GV_CYBORG_SPEAR) {
            self.PlaySound("sounds/shaders/ancient_warrior_death.ksnd");
            return;
        }
        else if (self.ModelVariation() >= GV_DEMON_AXE && self.ModelVariation() <= GV_DEMON_LORD) {
            switch(Math::RandMax(3)) {
				case 0:
					self.PlaySound("sounds/shaders/demon_effort_injury_grunt_1.ksnd");
					break;
				case 1:
					self.PlaySound("sounds/shaders/demon_effort_injury_grunt_2.ksnd");
					break;
				case 2:
					self.PlaySound("sounds/shaders/demon_effort_injury_grunt_3.ksnd");
					break;
            }
            return;
        }
        
        switch(Math::RandMax(3)) {
			case 0:
				self.PlaySound("sounds/shaders/human_effort_injury_grunt_1.ksnd");
				break;
			case 1:
				self.PlaySound("sounds/shaders/human_effort_injury_grunt_2.ksnd");
				break;
			case 2:
				self.PlaySound("sounds/shaders/human_effort_injury_grunt_3.ksnd");
				break;
        }
    }
	//------------------------------------------------------------------------------------------------------------------------
    void ViolentSound(kActor @instigator, const float w, const float x, const float y, const float z) {
        if (self.ModelVariation() >= GV_CYBORG_PULSE_RIFLE && self.ModelVariation() <= GV_CYBORG_SPEAR) {
            self.PlaySound("sounds/shaders/ancient_warrior_death.ksnd");
            return;
        }
        else if (self.ModelVariation() >= GV_DEMON_AXE && self.ModelVariation() <= GV_DEMON_LORD) {
            switch (Math::RandMax(3)) {
				case 0:
					self.PlaySound("sounds/shaders/demon_violent_death_1.ksnd");
					break;
				case 1:
					self.PlaySound("sounds/shaders/demon_violent_death_2.ksnd");
					break;
				case 2:
					self.PlaySound("sounds/shaders/demon_violent_death_3.ksnd");
					break;
            }
            return;
        }
        
        switch (Math::RandMax(3)) {
			case 0:
				self.PlaySound("sounds/shaders/human_violent_death_1.ksnd");
				break;
			case 1:
				self.PlaySound("sounds/shaders/human_violent_death_2.ksnd");
				break;
			case 2:
				self.PlaySound("sounds/shaders/human_violent_death_3.ksnd");
				break;
        }
    }
	//------------------------------------------------------------------------------------------------------------------------
    void SetModelTextures() {
        kRenderModel @model = self.RenderModel();
        if (model !is null) {
			if (self.ModelVariation() >= GV_CYBORG_PULSE_RIFLE && self.ModelVariation() <= GV_CYBORG_SPEAR) {
				self.ImpactType() = IT_METAL;
			}
			
			switch(self.ModelVariation())
			{
				// common soldier
				case GV_GENERIC:
				case GV_GENERIC_AXE:
				case GV_GENERIC_CLUB:
					// face
					model.SetTexture(19, Math::SysRand() % 12);
					break;
				
				// commander
				case GV_COMMANDER_SPEAR:
				case GV_COMMANDER_RIFLE1:
				case GV_COMMANDER_RIFLE2:
				case GV_COMMANDER_RIFLE3:
				case GV_COMMANDER_RIFLE4:
					// chest
					model.SetTexture(0, 1);
					model.SetTexture(9, 1);
					
					// arms
					model.SetTexture(10, 1);
					model.SetTexture(11, 1);
					model.SetTexture(12, 1);
					model.SetTexture(13, 1);
					model.SetTexture(14, 1);
					model.SetTexture(15, 1);
					model.SetTexture(16, 1);
					model.SetTexture(17, 1);
					
					// face
					model.SetTexture(19, Math::SysRand() % 12);
					break;
					
				// poacher
				case GV_POACHER_KNIFE:
				case GV_POACHER_PISTOL1:
				case GV_POACHER_PISTOL2:
				case GV_POACHER_RIFLE:
				case GV_POACHER_SHOTGUN:
					// chest
					model.SetTexture(0, 5);
					model.SetTexture(9, 5);
					
					// legs
					model.SetTexture(1, 2);
					model.SetTexture(3, 2);
					model.SetTexture(4, 2);
					model.SetTexture(5, 2);
					model.SetTexture(7, 2);
					model.SetTexture(8, 2);
					
					// shin
					model.SetTexture(2, 2);
					model.SetTexture(6, 2);
					
					// face
					//model.SetTexture(19, 6);
					model.SetTexture(19, Math::SysRand() % 6);
					//model.SetTexture(19, Math::SysRand() % 12);
					break;
					
				// warrior
				case GV_WARRIOR_BONE:
				case GV_WARRIOR_DART:
				case GV_WARRIOR_SPEAR:
					// hands
					model.SetTexture(17, 2);
					
					// chest
					model.SetTexture(0, 2);
					model.SetTexture(9, 2);
					
					// arms
					model.SetTexture(10, 2);
					model.SetTexture(11, 2);
					model.SetTexture(12, 2);
					model.SetTexture(13, 2);
					model.SetTexture(14, 2);
					model.SetTexture(15, 2);
					model.SetTexture(16, 2);
					
					// neck
					model.SetTexture(18, 1);
					break;
					
				// shaman
				case GV_SHAMAN:
					// chest
					model.SetTexture(0, 3);
					model.SetTexture(9, 3);
					
					// neck
					model.SetTexture(18, 2);
					
					// legs
					model.SetTexture(1, 1);
					model.SetTexture(3, 1);
					model.SetTexture(4, 1);
					model.SetTexture(5, 1);
					model.SetTexture(7, 1);
					model.SetTexture(8, 1);
					
					// shin
					model.SetTexture(2, 1);
					model.SetTexture(6, 1);
					
					// hands
					model.SetTexture(17, 3);
					
					// arms
					model.SetTexture(10, 3);
					model.SetTexture(11, 3);
					model.SetTexture(12, 3);
					model.SetTexture(13, 3);
					model.SetTexture(14, 3);
					model.SetTexture(15, 3);
					model.SetTexture(16, 3);
					break;
					
				// cyborg guard
				case GV_CYBORG_PULSE_RIFLE:
					// legs
					model.SetTexture(1, 1);
					model.SetTexture(3, 1);
					model.SetTexture(4, 1);
					model.SetTexture(5, 1);
					model.SetTexture(7, 1);
					model.SetTexture(8, 1);
					
					// shin
					model.SetTexture(2, 1);
					model.SetTexture(6, 1);
					
					// chest
					model.SetTexture(0, 4);
					model.SetTexture(9, 4);
					
					// arms
					model.SetTexture(10, 4);
					model.SetTexture(11, 4);
					model.SetTexture(12, 4);
					model.SetTexture(13, 4);
					model.SetTexture(14, 4);
					model.SetTexture(15, 4);
					model.SetTexture(16, 4);
					
					// neck
					model.SetTexture(18, 3);
					break;
					
				// demon
				case GV_DEMON_AXE:
				case GV_DEMON_SPEAR:
				case GV_DEMON_HANDS:
					// hands
					model.SetTexture(17, 6);
					model.SetTexture(13, 6);
					
					// legs
					model.SetTexture(1, 2);
					model.SetTexture(3, 2);
					model.SetTexture(4, 2);
					model.SetTexture(5, 2);
					model.SetTexture(7, 2);
					model.SetTexture(8, 2);
					
					// shin
					model.SetTexture(2, 2);
					model.SetTexture(6, 2);
					
					// chest
					model.SetTexture(0, 6);
					model.SetTexture(9, 6);
					
					// arms
					model.SetTexture(10, 6);
					model.SetTexture(11, 6);
					model.SetTexture(12, 6);
					model.SetTexture(13, 6);
					model.SetTexture(14, 6);
					model.SetTexture(15, 6);
					model.SetTexture(16, 6);
					
					// neck
					model.SetTexture(18, 4);
					break;
					
				// demon lord
				case GV_DEMON_LORD:
					// hands
					model.SetTexture(17, 7);
					model.SetTexture(13, 7);
					
					// legs
					model.SetTexture(1, 3);
					model.SetTexture(3, 3);
					model.SetTexture(4, 3);
					model.SetTexture(5, 3);
					model.SetTexture(7, 3);
					model.SetTexture(8, 3);
					
					// shin
					model.SetTexture(2, 3);
					model.SetTexture(6, 3);
					
					// chest
					model.SetTexture(0, 7);
					model.SetTexture(9, 7);
					
					// arms
					model.SetTexture(10, 7);
					model.SetTexture(11, 7);
					model.SetTexture(12, 7);
					model.SetTexture(13, 7);
					model.SetTexture(14, 7);
					model.SetTexture(15, 7);
					model.SetTexture(16, 7);
					
					// neck
					model.SetTexture(18, 5);
					break;
			}
		}
		
	}
	//------------------------------------------------------------------------------------------------------------------------
};
