class BleedingSourcesManagerBase { ref map m_BleedingSources = new map; ref map m_BleedingSourceZone = new map; ref map m_BleedingSourcesByLocation = new map; static ref map m_BleedingSourcesZonesMaskByLocation = new map;//for each inventory location, keep a bitmask where a bit is set to 1 for each bleeding source zone that belongs to that location static ref set m_BleedingSourcesLocationsList = new set; ItemBase m_Item;//item used to remove the bleeding source PlayerBase m_Player; //ref map m_FireGeomToBit = new map; ref map m_BitToFireGeom = new map; protected int m_Bit; int m_BitOffset = 0; void BleedingSourcesManagerBase( PlayerBase player ) { m_Player = player; Init(); } protected void Init() { //dmgZone_head RegisterBleedingZoneEx("Head",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "95 90 0" , "0.15 -0.08 0.00", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_HIGH, "BleedingSourceEffect",InventorySlots.MASK); //dmgZone_torso RegisterBleedingZoneEx("Neck", PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL,"", "-130 70 0" , "0.02 -0.05 0.05", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_HIGH, "BleedingSourceEffect",InventorySlots.HEADGEAR); RegisterBleedingZoneEx("Pelvis",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 -135 0" , "0 0.12 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_HIGH, "BleedingSourceEffect",InventorySlots.BODY); RegisterBleedingZoneEx("Spine",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 55 0" , "0 -0.1 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_HIGH, "BleedingSourceEffect",InventorySlots.BODY); RegisterBleedingZoneEx("Spine1",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 155 0" , "0 -0.1 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_HIGH, "BleedingSourceEffect",InventorySlots.BODY); RegisterBleedingZoneEx("Spine2",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 55 0" , "0 -0.07 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_HIGH, "BleedingSourceEffect",InventorySlots.BODY); RegisterBleedingZoneEx("Spine3",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 90 0" , "0 -0.05 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_HIGH, "BleedingSourceEffect",InventorySlots.BODY); //dmgZone_leftArm RegisterBleedingZoneEx("LeftShoulder",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 -90 0" , "0 0.07 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect", InventorySlots.BODY); RegisterBleedingZoneEx("LeftArm", PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "","0 90 90" , "0 -0.05 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.BODY); RegisterBleedingZoneEx("LeftArmRoll",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 90 0" , "0 -0.05 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.BODY); RegisterBleedingZoneEx("LeftForeArm",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 90 0" , "0 -0.05 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.BODY); //dmgZone_rightArm RegisterBleedingZoneEx("RightShoulder",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 90 0" , "0 -0.07 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.BODY); RegisterBleedingZoneEx("RightArm", PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL,"", "0 -90 0" , "0 0.05 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.BODY); RegisterBleedingZoneEx("RightArmRoll",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 -90 0" , "0 0.05 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.BODY); RegisterBleedingZoneEx("RightForeArm",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 -90 0" , "0 0.05 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.BODY); //dmgZone_leftHand RegisterBleedingZoneEx("LeftForeArmRoll",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 90 0" , "0.1 0 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_LOW, "BleedingSourceEffectLight", InventorySlots.GLOVES); //dmgZone_rightHand RegisterBleedingZoneEx("RightForeArmRoll",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 90 0" , "-0.1 0 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_LOW, "BleedingSourceEffectLight", InventorySlots.GLOVES); //dmgZone_leftLeg RegisterBleedingZoneEx("LeftLeg",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 90 0" , "0 -0.07 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.LEGS); RegisterBleedingZoneEx("LeftLegRoll",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 90 0" , "0 -0.07 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.LEGS); RegisterBleedingZoneEx("LeftUpLeg",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 90 0" , "0 -0.12 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.LEGS); RegisterBleedingZoneEx("LeftUpLegRoll",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 -90 0" , "0 0.1 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM , "BleedingSourceEffect",InventorySlots.LEGS); //dmgZone_rightLeg RegisterBleedingZoneEx("RightLeg",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 -90 0" , "0 0.06 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.LEGS); RegisterBleedingZoneEx("RightLegRoll",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 -90 0" , "0 0 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.LEGS); RegisterBleedingZoneEx("RightUpLeg",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 -90 0" , "0 0.12 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.LEGS); RegisterBleedingZoneEx("RightUpLegRoll",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 90 0" , "0 -0.1 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_MEDIUM, "BleedingSourceEffect",InventorySlots.LEGS); //dmgZone_leftFoot RegisterBleedingZoneEx("LeftFoot",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 180 0" , "0 0 0.035", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_LOW, "BleedingSourceEffectLight", InventorySlots.LEGS); RegisterBleedingZoneEx("LeftToeBase",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 -90 0" , "0 0.07 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_LOW, "BleedingSourceEffect",InventorySlots.FEET); //dmgZone_rightFoot RegisterBleedingZoneEx("RightFoot",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 0 0" , "0 0 -0.035", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_LOW, "BleedingSourceEffectLight", InventorySlots.LEGS); RegisterBleedingZoneEx("RightToeBase",PlayerConstants.BLEEDING_SOURCE_DURATION_NORMAL, "", "0 90 0" , "0 -0.07 0", PlayerConstants.BLEEDING_SOURCE_FLOW_MODIFIER_LOW, "BleedingSourceEffect", InventorySlots.FEET); } protected void SetItem(ItemBase item) { m_Item = item; } set GetBleedingSourcesLocations() { return m_BleedingSourcesLocationsList; } //for inventory location, get the active bits int GetBleedingSourceBitsByInvLocation(int inv_location) { if (m_BleedingSourcesByLocation.Contains(inv_location)) { return m_BleedingSourcesByLocation.Get(inv_location); } return 0; } //for inventory location, get the active bits int GetFreeBleedingSourceBitsByInvLocation(int inv_location) { if (m_BleedingSourcesZonesMaskByLocation.Contains(inv_location)) { return (~m_BleedingSourcesZonesMaskByLocation.Get(inv_location) & GetBleedingSourceBitsByInvLocation(inv_location)) | (m_BleedingSourcesZonesMaskByLocation.Get(inv_location) & ~GetBleedingSourceBitsByInvLocation(inv_location));//xor } return 0; } bool IsBleedingSourceActive(string name) { name.ToLower(); int bit = GetBitFromSelectionName(name); return m_Player.GetBleedingBits() & bit; } protected int GetBitFromSelectionID(int id) { CachedObjectsArrays.ARRAY_STRING.Clear(); m_Player.GetActionComponentNameList(id, CachedObjectsArrays.ARRAY_STRING, "fire"); for (int i = 0; i < CachedObjectsArrays.ARRAY_STRING.Count(); i++) { /* string name = CachedObjectsArrays.ARRAY_STRING.Get(i); PrintString(name); */ int bit = GetBitFromSelectionName(CachedObjectsArrays.ARRAY_STRING.Get(i)); if ( bit !=0 ) { return bit; } } return 0; } protected BleedingSourceZone GetBleedingSourceMeta(int bit) { return m_BleedingSourceZone.Get(GetSelectionNameFromBit(bit)); } int GetRegisteredSourcesCount() { return m_BitOffset; } protected void RegisterBleedingZoneEx(string name, int max_time, string bone = "", vector orientation = "0 0 0", vector offset = "0 0 0", float flow_modifier = 1, string particle_name = "BleedingSourceEffect", int inv_location = 0) { if ( m_BitOffset == BIT_INT_SIZE) { Error("Too many bleeding sources, max is "+BIT_INT_SIZE.ToString()); } else { name.ToLower(); //PrintString(name); //int bit = Math.Pow(2, m_BitOffset); m_Bit = 1 << m_BitOffset; //PrintString(bit.ToString()); string bone_name = bone; if (bone_name == "") { bone_name = name; } m_BleedingSourceZone.Insert(name, new BleedingSourceZone(name, m_Bit, offset, orientation, bone_name, max_time, flow_modifier, particle_name)); m_BleedingSourceZone.Get(name).SetInvLocation(inv_location); m_BitToFireGeom.Insert(m_Bit, name); m_BleedingSourcesZonesMaskByLocation.Set( inv_location, m_BleedingSourcesZonesMaskByLocation.Get(inv_location) | m_Bit);//set a bit to 1 to already existing bitmask for that location m_BleedingSourcesLocationsList.Insert(inv_location); m_BitOffset++; } } protected void RegisterBleedingZone(string name, int max_time, string bone = "", vector orientation = "0 0 0", vector offset = "0 0 0", float flow_modifier = 1, string particle_name = "BleedingSourceEffect") { RegisterBleedingZoneEx(name, max_time, bone, orientation, offset, flow_modifier, particle_name); } void RemoveAllSources() { //int count = m_BleedingSources.Count(); while (m_BleedingSources.Count() > 0 ) { int bit = m_BleedingSources.GetKey(0); RemoveBleedingSource(bit); } } protected int GetBitFromSelectionName(string name) { if (!m_BleedingSourceZone.Get(name)) { return 0; } return m_BleedingSourceZone.Get(name).GetBit(); } protected string GetSelectionNameFromBit(int bit) { return m_BitToFireGeom.Get(bit); } bool AttemptAddBleedingSource(int component) { int bit = GetBitFromSelectionID(component); if ( bit == 0 ) { return false; } if ( CanAddBleedingSource(bit) ) { AddBleedingSource(bit); return true; } return false; } bool AttemptAddBleedingSourceBySelection(string selection_name) { selection_name.ToLower(); int bit = GetBitFromSelectionName(selection_name); if ( bit == 0 ) { return false; } if ( CanAddBleedingSource(bit) ) { AddBleedingSource(bit); return true; } return false; } bool AttemptAddBleedingSourceDirectly(int bit, eBleedingSourceType type = eBleedingSourceType.NORMAL, int context = 0) { if(CanAddBleedingSource(bit)) { AddBleedingSourceEx(bit, type, context); return true; } return false; } protected bool CanAddBleedingSource(int bit) { if (!GetBleedingSourceMeta(bit)) { return false; } if ((m_Player.GetBleedingBits() & bit) == 0) { return true; } return false; } protected void AddBleedingSourceEx(int bit, eBleedingSourceType type = eBleedingSourceType.NORMAL, int context = 0) { AddBleedingSource(bit); m_BleedingSources.Get(bit).SetType(type); } protected void AddBleedingSource(int bit) { BleedingSourceZone bsz = GetBleedingSourceMeta(bit); vector orientation = bsz.GetOrientation(); vector offset = bsz.GetOffset(); string bone_name = bsz.GetBoneName(); float flow_modifier = bsz.GetFlowModifier(); int max_time = bsz.GetMaxTime(); string particle_name = bsz.GetParticleName(); int inventory_loc = bsz.GetInvLocation(); m_BleedingSourcesByLocation.Set(inventory_loc, (m_BleedingSourcesByLocation.Get(inventory_loc) | bit)); m_BleedingSources.Insert(bit, new BleedingSource(m_Player, bit,bone_name, orientation, offset, max_time, flow_modifier, particle_name) ); } int GetBleedingSourceActiveTime(int bit) { int time = -1; if (m_BleedingSources.Contains(bit)) { time = m_BleedingSources.Get(bit).GetActiveTime(); } return time; } void SetBleedingSourceActiveTime(int bit, int time) { if (m_BleedingSources.Contains(bit)) { m_BleedingSources.Get(bit).SetActiveTime(time); } } void SetBleedingSourceType(int bit, eBleedingSourceType type) { if (m_BleedingSources.Contains(bit)) { m_BleedingSources.Get(bit).SetType(type); } } eBleedingSourceType GetBleedingSourceType(int bit) { if (m_BleedingSources.Contains(bit)) { return m_BleedingSources.Get(bit).GetType(); } return -1; } protected bool RemoveBleedingSource(int bit) { if (m_BleedingSources.Contains(bit)) { BleedingSourceZone bsz = GetBleedingSourceMeta(bit); int inventory_loc = bsz.GetInvLocation(); m_BleedingSourcesByLocation.Set(inventory_loc, (m_BleedingSourcesByLocation.Get(inventory_loc) & ~bit));//deactivate the bit m_BleedingSources.Remove(bit); return true; } return false; } int GetBleedingSourcesCount() { return m_BleedingSources.Count(); } /*void ChangeBleedingIndicatorVisibility(bool visible) { int count = m_BleedingSources.Count(); for (int i = 0; i < count; i++) { m_BleedingSources.GetElement(i).ToggleSourceBleedingIndication(visible); } }*/ }