From 0a567fd83638838b91b3cc903788ebf96305d167 Mon Sep 17 00:00:00 2001 From: Suza Date: Sun, 22 May 2022 11:09:04 +0200 Subject: [PATCH 1/3] Proper way to strip static attributes The only way to maintain attributes such as min_viewmodel_offset is to not remove them in the first place. We have to manually nullify all the default attributes the weapon has. --- scripting/cwx/item_config.sp | 51 +++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/scripting/cwx/item_config.sp b/scripting/cwx/item_config.sp index cb0f97b..a6febb6 100644 --- a/scripting/cwx/item_config.sp +++ b/scripting/cwx/item_config.sp @@ -305,10 +305,53 @@ int EquipCustomItem(int client, const CustomItemDefinition item) { SetEntProp(itemEntity, Prop_Send, "m_iAccountID", accountid); } } - - // TODO: implement a version that nullifies runtime attributes to their defaults - SetEntProp(itemEntity, Prop_Send, "m_bOnlyIterateItemViewAttributes", - !item.bKeepStaticAttributes); + + if(!item.bKeepStaticAttributes) { + TF2Attrib_RemoveAll(itemEntity); + + char valueType[2]; + char valueFormat[64]; + + int staticAttribs[16]; + float staticAttribsValues[16]; + + TF2Attrib_GetStaticAttribs(item.defindex, staticAttribs, staticAttribsValues); + + for(int i = 0; i < 16; i++) + { + if(staticAttribs[i] == 0) + continue; + + // Probably overkill + if(staticAttribs[i] == 796 || staticAttribs[i] == 724 || staticAttribs[i] == 817 || staticAttribs[i] == 834 + || staticAttribs[i] == 745 || staticAttribs[i] == 731 || staticAttribs[i] == 746) + continue; + + // "stored_as_integer" is absent from the attribute schema if its type is "string". + // TF2ED_GetAttributeDefinitionString returns false if it can't find the given string. + if(!TF2Econ_GetAttributeDefinitionString(staticAttribs[i], "stored_as_integer", valueType, sizeof(valueType))) + continue; + + TF2Econ_GetAttributeDefinitionString(staticAttribs[i], "description_format", valueFormat, sizeof(valueFormat)); + + // Since we already know what we're working with and what we're looking for, we can manually handpick + // the most significative chars to check if they match. Eons faster than doing StrEqual or StrContains. + + if(valueFormat[9] == 'a' && valueFormat[10] == 'd') // value_is_additive & value_is_additive_percentage + { + TF2Attrib_SetByDefIndex(itemEntity, staticAttribs[i], 0.0); + } + else if((valueFormat[9] == 'i' && valueFormat[18] == 'p') + || (valueFormat[9] == 'p' && valueFormat[10] == 'e')) // value_is_percentage & value_is_inverted_percentage + { + TF2Attrib_SetByDefIndex(itemEntity, staticAttribs[i], 1.0); + } + else if(valueFormat[9] == 'o' && valueFormat[10] == 'r') // value_is_or + { + TF2Attrib_SetByDefIndex(itemEntity, staticAttribs[i], 0.0); + } + } + } // apply game attributes if (item.nativeAttributes) { From 8fb0d5897635fea8bbc25e18d5d9a29f9bd69d28 Mon Sep 17 00:00:00 2001 From: Suza Date: Sun, 22 May 2022 11:14:02 +0200 Subject: [PATCH 2/3] Follow the codebase's code format rules --- scripting/cwx/item_config.sp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripting/cwx/item_config.sp b/scripting/cwx/item_config.sp index a6febb6..bc38b43 100644 --- a/scripting/cwx/item_config.sp +++ b/scripting/cwx/item_config.sp @@ -319,35 +319,35 @@ int EquipCustomItem(int client, const CustomItemDefinition item) { for(int i = 0; i < 16; i++) { - if(staticAttribs[i] == 0) + if(staticAttribs[i] == 0) { continue; + } // Probably overkill if(staticAttribs[i] == 796 || staticAttribs[i] == 724 || staticAttribs[i] == 817 || staticAttribs[i] == 834 - || staticAttribs[i] == 745 || staticAttribs[i] == 731 || staticAttribs[i] == 746) + || staticAttribs[i] == 745 || staticAttribs[i] == 731 || staticAttribs[i] == 746) { continue; + } // "stored_as_integer" is absent from the attribute schema if its type is "string". // TF2ED_GetAttributeDefinitionString returns false if it can't find the given string. - if(!TF2Econ_GetAttributeDefinitionString(staticAttribs[i], "stored_as_integer", valueType, sizeof(valueType))) + if(!TF2Econ_GetAttributeDefinitionString(staticAttribs[i], "stored_as_integer", valueType, sizeof(valueType))) { continue; + } TF2Econ_GetAttributeDefinitionString(staticAttribs[i], "description_format", valueFormat, sizeof(valueFormat)); // Since we already know what we're working with and what we're looking for, we can manually handpick // the most significative chars to check if they match. Eons faster than doing StrEqual or StrContains. - if(valueFormat[9] == 'a' && valueFormat[10] == 'd') // value_is_additive & value_is_additive_percentage - { + if(valueFormat[9] == 'a' && valueFormat[10] == 'd') { // value_is_additive & value_is_additive_percentage TF2Attrib_SetByDefIndex(itemEntity, staticAttribs[i], 0.0); } else if((valueFormat[9] == 'i' && valueFormat[18] == 'p') - || (valueFormat[9] == 'p' && valueFormat[10] == 'e')) // value_is_percentage & value_is_inverted_percentage - { + || (valueFormat[9] == 'p' && valueFormat[10] == 'e')) { // value_is_percentage & value_is_inverted_percentage TF2Attrib_SetByDefIndex(itemEntity, staticAttribs[i], 1.0); } - else if(valueFormat[9] == 'o' && valueFormat[10] == 'r') // value_is_or - { + else if(valueFormat[9] == 'o' && valueFormat[10] == 'r') { // value_is_or TF2Attrib_SetByDefIndex(itemEntity, staticAttribs[i], 0.0); } } From 514fd9ba3341c4c0ab3aa5335d4b3e2daad218b4 Mon Sep 17 00:00:00 2001 From: Suza Date: Sun, 22 May 2022 14:45:50 +0200 Subject: [PATCH 3/3] Add new keep_static_attrs value; Remove some hardcoded attributes; Iterate based on TF2Attrib_GetStaticAttribs --- scripting/cwx.sp | 2 +- scripting/cwx/item_config.sp | 83 +++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 39 deletions(-) diff --git a/scripting/cwx.sp b/scripting/cwx.sp index 13651b0..a609830 100644 --- a/scripting/cwx.sp +++ b/scripting/cwx.sp @@ -707,7 +707,7 @@ static bool IsCustomItemAllowed(int client, const CustomItemDefinition item) { bMedievalAllowedInSchema = !!StringToInt(configValue); } } - if (!bNativeAttributeOverride && item.bKeepStaticAttributes) { + if (!bNativeAttributeOverride && item.keepStaticAttributes) { // TODO we should cache this... ArrayList attribList = TF2Econ_GetItemStaticAttributes(item.defindex); bMedievalAllowedInSchema = diff --git a/scripting/cwx/item_config.sp b/scripting/cwx/item_config.sp index bc38b43..c3da610 100644 --- a/scripting/cwx/item_config.sp +++ b/scripting/cwx/item_config.sp @@ -19,7 +19,7 @@ enum struct CustomItemDefinition { KeyValues nativeAttributes; KeyValues customAttributes; - bool bKeepStaticAttributes; + KeepStaticType keepStaticAttributes; void Init() { this.defindex = TF_ITEMDEF_DEFAULT; @@ -56,6 +56,12 @@ enum struct CustomItemDefinition { } } +enum KeepStaticType { + KeepStatic_False = 0, + KeepStatic_True, + KeepStatic_Nullify +}; + /** * Holds a uid to CustomItemDefinition mapping. */ @@ -197,7 +203,7 @@ bool CreateItemFromSection(KeyValues config) { config.GetString("item_class", item.className, sizeof(item.className), item.className); - item.bKeepStaticAttributes = !!config.GetNum("keep_static_attrs", true); + item.keepStaticAttributes = view_as(config.GetNum("keep_static_attrs", true)); // allows restricting access to the item config.GetString("access", item.access, sizeof(item.access)); @@ -306,53 +312,54 @@ int EquipCustomItem(int client, const CustomItemDefinition item) { } } - if(!item.bKeepStaticAttributes) { - TF2Attrib_RemoveAll(itemEntity); - - char valueType[2]; - char valueFormat[64]; + switch(item.keepStaticAttributes) { + case KeepStatic_False: { + SetEntProp(itemEntity, Prop_Send, "m_bOnlyIterateItemViewAttributes", true); + } + case KeepStatic_Nullify: { + TF2Attrib_RemoveAll(itemEntity); - int staticAttribs[16]; - float staticAttribsValues[16]; + char valueType[2]; + char valueFormat[64]; - TF2Attrib_GetStaticAttribs(item.defindex, staticAttribs, staticAttribsValues); + int staticAttribs[16]; + float staticAttribsValues[16]; - for(int i = 0; i < 16; i++) - { - if(staticAttribs[i] == 0) { - continue; - } + int staticAttribsNum = TF2Attrib_GetStaticAttribs(item.defindex, staticAttribs, staticAttribsValues); - // Probably overkill - if(staticAttribs[i] == 796 || staticAttribs[i] == 724 || staticAttribs[i] == 817 || staticAttribs[i] == 834 - || staticAttribs[i] == 745 || staticAttribs[i] == 731 || staticAttribs[i] == 746) { - continue; - } + for(int i = 0; i < staticAttribsNum; i++) + { + // We don't want to nullify attributes that bring a "cosmetic" value. + // 834 ( paintkit_proto_def_index ), 745 ( has team color paintkit ) + if(staticAttribs[i] == 834 || staticAttribs[i] == 745) { + continue; + } - // "stored_as_integer" is absent from the attribute schema if its type is "string". - // TF2ED_GetAttributeDefinitionString returns false if it can't find the given string. - if(!TF2Econ_GetAttributeDefinitionString(staticAttribs[i], "stored_as_integer", valueType, sizeof(valueType))) { - continue; - } + // "stored_as_integer" is absent from the attribute schema if its type is "string". + // TF2ED_GetAttributeDefinitionString returns false if it can't find the given string. + if(!TF2Econ_GetAttributeDefinitionString(staticAttribs[i], "stored_as_integer", valueType, sizeof(valueType))) { + continue; + } - TF2Econ_GetAttributeDefinitionString(staticAttribs[i], "description_format", valueFormat, sizeof(valueFormat)); + TF2Econ_GetAttributeDefinitionString(staticAttribs[i], "description_format", valueFormat, sizeof(valueFormat)); - // Since we already know what we're working with and what we're looking for, we can manually handpick - // the most significative chars to check if they match. Eons faster than doing StrEqual or StrContains. + // Since we already know what we're working with and what we're looking for, we can manually handpick + // the most significative chars to check if they match. Eons faster than doing StrEqual or StrContains. - if(valueFormat[9] == 'a' && valueFormat[10] == 'd') { // value_is_additive & value_is_additive_percentage - TF2Attrib_SetByDefIndex(itemEntity, staticAttribs[i], 0.0); - } - else if((valueFormat[9] == 'i' && valueFormat[18] == 'p') - || (valueFormat[9] == 'p' && valueFormat[10] == 'e')) { // value_is_percentage & value_is_inverted_percentage - TF2Attrib_SetByDefIndex(itemEntity, staticAttribs[i], 1.0); - } - else if(valueFormat[9] == 'o' && valueFormat[10] == 'r') { // value_is_or - TF2Attrib_SetByDefIndex(itemEntity, staticAttribs[i], 0.0); + if(valueFormat[9] == 'a' && valueFormat[10] == 'd') { // value_is_additive & value_is_additive_percentage + TF2Attrib_SetByDefIndex(itemEntity, staticAttribs[i], 0.0); + } + else if((valueFormat[9] == 'i' && valueFormat[18] == 'p') + || (valueFormat[9] == 'p' && valueFormat[10] == 'e')) { // value_is_percentage & value_is_inverted_percentage + TF2Attrib_SetByDefIndex(itemEntity, staticAttribs[i], 1.0); + } + else if(valueFormat[9] == 'o' && valueFormat[10] == 'r') { // value_is_or + TF2Attrib_SetByDefIndex(itemEntity, staticAttribs[i], 0.0); + } } } } - + // apply game attributes if (item.nativeAttributes) { if (item.nativeAttributes.GotoFirstSubKey(false)) {