From 28e54c36a70915b10264f9b6197ab4def2f89e6a Mon Sep 17 00:00:00 2001 From: Richard Helgeby Date: Thu, 25 Apr 2013 09:50:08 +0200 Subject: [PATCH] Added support for model with multiple skins (model_skin_index class attribute). Compiles, but not tested. --- .../sourcemod/configs/zr/playerclasses.txt | 12 ++++ docs/zr_manual.htm | 21 ++++++- src/zr/playerclasses/apply.inc | 6 ++ src/zr/playerclasses/attributes.inc | 37 ++++++++++++ src/zr/playerclasses/classcommands.inc | 5 ++ src/zr/playerclasses/filtertools.inc | 18 ++++++ src/zr/playerclasses/playerclasses.inc | 57 ++++++++++++------- src/zr/volfeatures/volclassedit.inc | 1 + 8 files changed, 133 insertions(+), 24 deletions(-) diff --git a/cstrike/addons/sourcemod/configs/zr/playerclasses.txt b/cstrike/addons/sourcemod/configs/zr/playerclasses.txt index 2366a1b..4b272af 100644 --- a/cstrike/addons/sourcemod/configs/zr/playerclasses.txt +++ b/cstrike/addons/sourcemod/configs/zr/playerclasses.txt @@ -24,6 +24,7 @@ // name text The class name used in class menu. // description text The class description used in class menu. // model_path text Path to model to use. Relative to cstrike folder. +// model_skin_index number Model skin index to use if model support multiple skins. First skin is 0. // alpha_initial number Initial transparency setting. // alpha_damaged number Transparency when damaged. // alpha_damage number How much damage to do before switching alpha. @@ -79,6 +80,7 @@ // Model "model_path" "models/player/zh/zh_corpse002.mdl" + "model_skin_index" "0" "alpha_initial" "255" "alpha_damaged" "255" "alpha_damage" "0" @@ -124,6 +126,7 @@ // Model "model_path" "models/player/zh/zh_charple001.mdl" + "model_skin_index" "0" "alpha_initial" "255" "alpha_damaged" "255" "alpha_damage" "0" @@ -169,6 +172,7 @@ // Model "model_path" "models/player/zh/zh_zombie003.mdl" + "model_skin_index" "0" "alpha_initial" "255" "alpha_damaged" "255" "alpha_damage" "0" @@ -214,6 +218,7 @@ // Model "model_path" "models/player/ics/hellknight_red/t_guerilla.mdl" + "model_skin_index" "0" "alpha_initial" "255" "alpha_damaged" "255" "alpha_damage" "0" @@ -259,6 +264,7 @@ // Model "model_path" "models/player/zh/zh_zombie003.mdl" + "model_skin_index" "0" "alpha_initial" "255" "alpha_damaged" "255" "alpha_damage" "0" @@ -304,6 +310,7 @@ // Model "model_path" "models/player/zh/zh_charple001.mdl" + "model_skin_index" "0" "alpha_initial" "255" "alpha_damaged" "255" "alpha_damage" "0" @@ -355,6 +362,7 @@ // Model "model_path" "default" + "model_skin_index" "0" "alpha_initial" "255" "alpha_damaged" "255" "alpha_damage" "0" @@ -400,6 +408,7 @@ // Model "model_path" "default" + "model_skin_index" "0" "alpha_initial" "255" "alpha_damaged" "255" "alpha_damage" "0" @@ -445,6 +454,7 @@ // Model "model_path" "default" + "model_skin_index" "0" "alpha_initial" "255" "alpha_damaged" "255" "alpha_damage" "0" @@ -490,6 +500,7 @@ // Model "model_path" "default" + "model_skin_index" "0" "alpha_initial" "255" "alpha_damaged" "255" "alpha_damage" "0" @@ -535,6 +546,7 @@ // Model "model_path" "default" + "model_skin_index" "0" "alpha_initial" "255" "alpha_damaged" "255" "alpha_damage" "0" diff --git a/docs/zr_manual.htm b/docs/zr_manual.htm index 57ade98..2e665bb 100644 --- a/docs/zr_manual.htm +++ b/docs/zr_manual.htm @@ -1138,11 +1138,28 @@ the admin-only flag in the flags attribute.

players. +

Warning: If specifying a model path here, remember to add a + matching model entry in the model config file (models.txt), or you will get an error + about model was not precached. In worst case the server will crash.

- alpha_spawn + model_skin_index + number + 0 - last skin index + + + +

The model skin index to use if the model support multiple skins. First skin is 0.

+

Warning: Zombie:Reloaded doesn't know how many skins a model has, + make sure you use a valid index if modifying it. An invalid value might in worst case + crash the server/client.

+ + + + + alpha_initial number 0 - 255 @@ -1462,7 +1479,7 @@ the admin-only flag in the flags attribute.

Formula for converting LMV speed into a prop speed offset:

-
prop speed offset = ((lmv speed / 300) * 250) - 250
+
prop speed offset = ((lmv speed / 300) * 250) - 250

This calculation can be done directly on a calculator, without any use of parentheses (they aren't needed in this one anyways).

diff --git a/src/zr/playerclasses/apply.inc b/src/zr/playerclasses/apply.inc index 1849c87..71cacad 100644 --- a/src/zr/playerclasses/apply.inc +++ b/src/zr/playerclasses/apply.inc @@ -88,6 +88,7 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER) new ModelTeam:team; new access; new model; + new skinIndex = 0; // Get correct index according to cache type. if (cachetype == ZR_CLASS_CACHE_PLAYER) @@ -102,6 +103,9 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER) // Get the model path from the specified cache. ClassGetModelPath(index, modelpath, sizeof(modelpath), cachetype); + // Get model skin index. + skinIndex = ClassGetModelSkinIndex(index, cachetype); + // Get model team setting from the specified cache. team = ModelsTeamIdToTeam(ClassGetTeamID(index, cachetype)); @@ -185,6 +189,8 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER) } SetEntityModel(client, modelpath); + SetEntProp(client, Prop_Send, "m_nSkin", skinIndex); + return true; } diff --git a/src/zr/playerclasses/attributes.inc b/src/zr/playerclasses/attributes.inc index 69dca98..0a0b075 100644 --- a/src/zr/playerclasses/attributes.inc +++ b/src/zr/playerclasses/attributes.inc @@ -347,6 +347,38 @@ stock ClassGetModelPath(index, String:buffer[], maxlen, cachetype = ZR_CLASS_CAC return -1; } +/** + * Gets the model skin index from the specified class. + * + * @param index Index of the class in a class cache or a client index, + * depending on the cache type specified. + * @param cachetype Optional. Specifies what class cache to read from. Options: + * ZR_CLASS_CACHE_ORIGINAL - Unchanced class data. + * ZR_CLASS_CACHE_MODIFIED - Changed/newest class data. + * ZR_CLASS_CACHE_PLAYER (default) - Player cache. If this one + * is used, index will be used as a client index. + * @return The model skin index in the specified class. -1 on error. + */ +stock ClassGetModelSkinIndex(index, cachetype = ZR_CLASS_CACHE_PLAYER) +{ + switch (cachetype) + { + case ZR_CLASS_CACHE_ORIGINAL: + { + return ClassData[index][Class_ModelSkinIndex]; + } + case ZR_CLASS_CACHE_MODIFIED: + { + return ClassDataCache[index][Class_ModelSkinIndex]; + } + case ZR_CLASS_CACHE_PLAYER: + { + return ClassPlayerCache[index][Class_ModelSkinIndex]; + } + } + return -1; +} + /** * Gets the initial alpha value from the specified class. * @@ -1137,6 +1169,10 @@ stock ClassAttributeNameToFlag(const String:attributename[]) { return ZR_CLASS_MODEL_PATH; } + else if (StrEqual(attributename, "model_skin_index", false)) + { + return ZR_CLASS_MODEL_SKIN_INDEX; + } else if (StrEqual(attributename, "alpha_initial", false)) { return ZR_CLASS_ALPHA_INITIAL; @@ -1299,6 +1335,7 @@ stock ClassDataTypes:ClassGetAttributeType(attributeflag) // Integer. case ZR_CLASS_FLAGS, + ZR_CLASS_MODEL_SKIN_INDEX, ZR_CLASS_ALPHA_INITIAL, ZR_CLASS_ALPHA_DAMAGED, ZR_CLASS_ALPHA_DAMAGE, diff --git a/src/zr/playerclasses/classcommands.inc b/src/zr/playerclasses/classcommands.inc index 7ae818e..5b861a7 100644 --- a/src/zr/playerclasses/classcommands.inc +++ b/src/zr/playerclasses/classcommands.inc @@ -702,6 +702,11 @@ stock ClassModifyInteger(classindex, attributeflag, value, Float:multiplier = 0. ClassDataCache[classindex][Class_Flags] = value; return true; } + case ZR_CLASS_MODEL_SKIN_INDEX: + { + ClassDataCache[classindex][Class_ModelSkinIndex] = value; + return true; + } case ZR_CLASS_ALPHA_INITIAL: { if (ismultiplier) diff --git a/src/zr/playerclasses/filtertools.inc b/src/zr/playerclasses/filtertools.inc index 95718f2..2a89c27 100644 --- a/src/zr/playerclasses/filtertools.inc +++ b/src/zr/playerclasses/filtertools.inc @@ -213,6 +213,17 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false) } } + // Model skin index. + new model_skin_index = ClassData[classindex][Class_ModelSkinIndex]; + if (model_skin_index < ZR_CLASS_MODEL_SKIN_INDEX_MIN) + { + flags += ZR_CLASS_MODEL_SKIN_INDEX; + if (logErrors) + { + LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid model_skin_index at index %d: %d", classindex, model_skin_index); + } + } + // Alpha, initial. new alpha_initial = ClassData[classindex][Class_AlphaInitial]; if (!(alpha_initial >= ZR_CLASS_ALPHA_INITIAL_MIN && alpha_initial <= ZR_CLASS_ALPHA_INITIAL_MAX)) @@ -446,6 +457,13 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes]) { new flags; + // Model skin index. + new model_skin_index = attributes[ClassEdit_ModelSkinIndex]; + if (model_skin_index < ZR_CLASS_MODEL_SKIN_INDEX_MIN) + { + flags += ZR_CLASS_MODEL_SKIN_INDEX; + } + // Alpha initial. new alphaInitial = attributes[ClassEdit_AlphaInitial]; if (alphaInitial >= 0) diff --git a/src/zr/playerclasses/playerclasses.inc b/src/zr/playerclasses/playerclasses.inc index 7b27b37..5c2d139 100644 --- a/src/zr/playerclasses/playerclasses.inc +++ b/src/zr/playerclasses/playerclasses.inc @@ -107,6 +107,7 @@ #define ZR_CLASS_DEFAULT_NAME "classic" #define ZR_CLASS_DEFAULT_DESCRIPTION "Need brains!!! Arrrrggghh!" #define ZR_CLASS_DEFAULT_MODEL_PATH "models/player/zh/zh_zombie003.mdl" +#define ZR_CLASS_DEFAULT_MODEL_SKIN_INDEX 0 #define ZR_CLASS_DEFAULT_ALPHA_INITIAL 255 #define ZR_CLASS_DEFAULT_ALPHA_DAMAGED 255 #define ZR_CLASS_DEFAULT_ALPHA_DAMAGE 0 @@ -142,6 +143,7 @@ #define ZR_CLASS_NAME_MIN 1 #define ZR_CLASS_DESCRIPTION_MIN 1 /** Model path is checked for existance. */ +#define ZR_CLASS_MODEL_SKIN_INDEX_MIN 0 #define ZR_CLASS_ALPHA_INITIAL_MIN 0 #define ZR_CLASS_ALPHA_INITIAL_MAX 255 #define ZR_CLASS_ALPHA_DAMAGED_MIN 0 @@ -191,27 +193,28 @@ #define ZR_CLASS_NAME (1<<5) #define ZR_CLASS_DESCRIPTION (1<<6) #define ZR_CLASS_MODEL_PATH (1<<7) -#define ZR_CLASS_ALPHA_INITIAL (1<<8) -#define ZR_CLASS_ALPHA_DAMAGED (1<<9) -#define ZR_CLASS_ALPHA_DAMAGE (1<<10) -#define ZR_CLASS_OVERLAY_PATH (1<<11) -#define ZR_CLASS_NVGS (1<<12) -#define ZR_CLASS_FOV (1<<13) -#define ZR_CLASS_HAS_NAPALM (1<<14) -#define ZR_CLASS_NAPALM_TIME (1<<15) -#define ZR_CLASS_IMMUNITY_MODE (1<<16) -#define ZR_CLASS_IMMUNITY_AMOUNT (1<<17) -#define ZR_CLASS_IMMUNITY_COOLDOWN (1<<18) -#define ZR_CLASS_NO_FALL_DAMAGE (1<<19) -#define ZR_CLASS_HEALTH (1<<20) -#define ZR_CLASS_HEALTH_REGEN_INTERVAL (1<<21) -#define ZR_CLASS_HEALTH_REGEN_AMOUNT (1<<22) -#define ZR_CLASS_HEALTH_INFECT_GAIN (1<<23) -#define ZR_CLASS_KILL_BONUS (1<<24) -#define ZR_CLASS_SPEED (1<<25) -#define ZR_CLASS_KNOCKBACK (1<<26) -#define ZR_CLASS_JUMP_HEIGHT (1<<27) -#define ZR_CLASS_JUMP_DISTANCE (1<<28) +#define ZR_CLASS_MODEL_SKIN_INDEX (1<<8) +#define ZR_CLASS_ALPHA_INITIAL (1<<9) +#define ZR_CLASS_ALPHA_DAMAGED (1<<10) +#define ZR_CLASS_ALPHA_DAMAGE (1<<11) +#define ZR_CLASS_OVERLAY_PATH (1<<12) +#define ZR_CLASS_NVGS (1<<13) +#define ZR_CLASS_FOV (1<<14) +#define ZR_CLASS_HAS_NAPALM (1<<15) +#define ZR_CLASS_NAPALM_TIME (1<<16) +#define ZR_CLASS_IMMUNITY_MODE (1<<17) +#define ZR_CLASS_IMMUNITY_AMOUNT (1<<18) +#define ZR_CLASS_IMMUNITY_COOLDOWN (1<<19) +#define ZR_CLASS_NO_FALL_DAMAGE (1<<20) +#define ZR_CLASS_HEALTH (1<<21) +#define ZR_CLASS_HEALTH_REGEN_INTERVAL (1<<22) +#define ZR_CLASS_HEALTH_REGEN_AMOUNT (1<<23) +#define ZR_CLASS_HEALTH_INFECT_GAIN (1<<24) +#define ZR_CLASS_KILL_BONUS (1<<25) +#define ZR_CLASS_SPEED (1<<26) +#define ZR_CLASS_KNOCKBACK (1<<27) +#define ZR_CLASS_JUMP_HEIGHT (1<<28) +#define ZR_CLASS_JUMP_DISTANCE (1<<29) /** * @endsection */ @@ -232,6 +235,7 @@ * ClassGetAttributeType * ClassValidateAttributes * ClassModify* in classcommands.inc + * VolEmptyAttributes * Update docs with detailed attribute description */ enum ClassAttributes @@ -248,6 +252,7 @@ enum ClassAttributes /* Model */ String:Class_ModelPath[PLATFORM_MAX_PATH], + Class_ModelSkinIndex, Class_AlphaInitial, Class_AlphaDamaged, Class_AlphaDamage, @@ -292,7 +297,8 @@ enum ClassAttributes enum ClassEditableAttributes { /* Model */ - ClassEdit_AlphaInitial = 0, + ClassEdit_ModelSkinIndex = 0, + ClassEdit_AlphaInitial, ClassEdit_AlphaDamaged, ClassEdit_AlphaDamage, @@ -593,6 +599,7 @@ ClassLoad() KvGetString(kvClassData, "model_path", model_path, sizeof(model_path), ZR_CLASS_DEFAULT_MODEL_PATH); strcopy(ClassData[ClassCount][Class_ModelPath], PLATFORM_MAX_PATH, model_path); + ClassData[ClassCount][Class_ModelSkinIndex] = KvGetNum(kvClassData, "model_skin_index", ZR_CLASS_DEFAULT_MODEL_SKIN_INDEX); ClassData[ClassCount][Class_AlphaInitial] = KvGetNum(kvClassData, "alpha_initial", ZR_CLASS_DEFAULT_ALPHA_INITIAL); ClassData[ClassCount][Class_AlphaDamaged] = KvGetNum(kvClassData, "alpha_damaged", ZR_CLASS_DEFAULT_ALPHA_DAMAGED); ClassData[ClassCount][Class_AlphaDamage] = KvGetNum(kvClassData, "alpha_damage", ZR_CLASS_DEFAULT_ALPHA_DAMAGE); @@ -744,6 +751,7 @@ bool:ClassReloadDataCache() /* Model */ strcopy(ClassDataCache[classindex][Class_ModelPath], PLATFORM_MAX_PATH, ClassData[classindex][Class_ModelPath]); + ClassDataCache[classindex][Class_ModelSkinIndex] = ClassData[classindex][Class_ModelSkinIndex]; ClassDataCache[classindex][Class_AlphaInitial] = ClassData[classindex][Class_AlphaInitial]; ClassDataCache[classindex][Class_AlphaDamaged] = ClassData[classindex][Class_AlphaDamaged]; ClassDataCache[classindex][Class_AlphaDamage] = ClassData[classindex][Class_AlphaDamage]; @@ -810,6 +818,7 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF /* Model */ strcopy(ClassPlayerCache[client][Class_ModelPath], PLATFORM_MAX_PATH, ClassData[classindex][Class_ModelPath]); + ClassPlayerCache[client][Class_ModelSkinIndex] = ClassData[classindex][Class_ModelSkinIndex]; ClassPlayerCache[client][Class_AlphaInitial] = ClassData[classindex][Class_AlphaInitial]; ClassPlayerCache[client][Class_AlphaDamaged] = ClassData[classindex][Class_AlphaDamaged]; ClassPlayerCache[client][Class_AlphaDamage] = ClassData[classindex][Class_AlphaDamage]; @@ -851,6 +860,7 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF /* Model */ strcopy(ClassPlayerCache[client][Class_ModelPath], PLATFORM_MAX_PATH, ClassDataCache[classindex][Class_ModelPath]); + ClassPlayerCache[client][Class_ModelSkinIndex] = ClassDataCache[classindex][Class_ModelSkinIndex]; ClassPlayerCache[client][Class_AlphaInitial] = ClassDataCache[classindex][Class_AlphaInitial]; ClassPlayerCache[client][Class_AlphaDamaged] = ClassDataCache[classindex][Class_AlphaDamaged]; ClassPlayerCache[client][Class_AlphaDamage] = ClassDataCache[classindex][Class_AlphaDamage]; @@ -1355,6 +1365,9 @@ ClassDumpData(index, cachetype, String:buffer[], maxlen) Format(attribute, sizeof(attribute), "model_path: \"%s\"\n", format_buffer); cellcount += StrCat(buffer, maxlen, attribute); + Format(attribute, sizeof(attribute), "model_skin_index: \"%d\"\n", ClassGetModelSkinIndex(index, cachetype)); + cellcount += StrCat(buffer, maxlen, attribute); + Format(attribute, sizeof(attribute), "alpha_initial: \"%d\"\n", ClassGetAlphaInitial(index, cachetype)); cellcount += StrCat(buffer, maxlen, attribute); diff --git a/src/zr/volfeatures/volclassedit.inc b/src/zr/volfeatures/volclassedit.inc index 69ad686..ec9d0e7 100644 --- a/src/zr/volfeatures/volclassedit.inc +++ b/src/zr/volfeatures/volclassedit.inc @@ -31,6 +31,7 @@ * Empty attribute structure with all settings set to be ignored. */ new VolEmptyAttributes[ClassEditableAttributes] = { + -1, /** ModelSkinIndex */ -1, /** AlphaInitial */ -1, /** AlphaDamaged */ -1, /** AlphaDamage */