123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- enum ImpactTypes
- {
- UNKNOWN;
- STOP;
- PENETRATE;
- RICOCHET;
- MELEE;
- }
- class ImpactEffectsData
- {
- Object m_DirectHit;
- int m_ImpactType;
- int m_ComponentIndex;
- bool m_IsDeflected;
- bool m_IsWater;
- string m_Surface;
- string m_AmmoType;
- vector m_InSpeed;
- vector m_OutSpeed;
- vector m_Position;
- vector m_SurfaceNormal;
- vector m_ExitPosition;
- }
- class ImpactMaterials
- {
- ref static map<string, typename> m_ImpactEffect;
- static int m_LastRegisteredMaterial = 0;
-
- //! Map of ammo which will not spawn any impact effect
- ref static map<string, int> m_IgnoredAmmo;
- static int m_LastRegisteredIgnoredAmmo = 0;
-
- /** \name Surface effects
- * Register all hit materials here!
- * When modding, these can be unregistered with 'UnregisterSurface' if so desired
- */
- //@{
- static int PLASTIC = RegisterSurface("Hit_Plastic");
- static int SAND = RegisterSurface("Hit_Sand");
- static int TEXTILE = RegisterSurface("Hit_Textile");
- static int CONCRETE = RegisterSurface("Hit_Concrete");
- static int GRAVEL = RegisterSurface("Hit_Gravel");
- static int DIRT = RegisterSurface("Hit_Dirt");
- static int FOLIAGE = RegisterSurface("Hit_Foliage");
- static int FOLIAGE_GREEN = RegisterSurface("Hit_Foliage_Green");
- static int FOLIAGE_CONIFER = RegisterSurface("Hit_Foliage_Conifer");
- static int GRASS = RegisterSurface("Hit_Grass");
- static int WOOD = RegisterSurface("Hit_Wood");
- static int METAL = RegisterSurface("Hit_Metal");
- static int GLASS = RegisterSurface("Hit_Glass");
- static int GLASS_THIN = RegisterSurface("Hit_Glass_Thin");
- static int WATER = RegisterSurface("Hit_Water");
- static int RUBBER = RegisterSurface("Hit_Rubber");
- static int PLASTER = RegisterSurface("Hit_Plaster");
- static int ICE = RegisterSurface("Hit_Ice");
- static int SNOW = RegisterSurface("Hit_Snow");
- static int MEATBONES = RegisterSurface("Hit_MeatBones");
- static int MEATBONES_SHOVEL = RegisterSurface("Hit_MeatBones_MeleeShovel");
- static int MEATBONES_PIPEWRENCH = RegisterSurface("Hit_MeatBones_MeleePipeWrench");
- static int MEATBONES_WRENCH = RegisterSurface("Hit_MeatBones_MeleeWrench");
- static int MEATBONES_FIST = RegisterSurface("Hit_MeatBones_MeleeFist");
- static int UNDEFINED = RegisterSurface("Hit_Undefined");
- static int ERROR_NO_MATERIAL = RegisterSurface("Hit_ErrorNoMaterial");
- //@}
- /** \name Ignored ammo
- * Register ammo which will not spawn impact effects here
- * When modding, these can be unregistered with 'UnregisterIgnoredAmmo' if so desired
- */
- //@{
- static int FIST = RegisterIgnoredAmmo("MeleeFist");
- static int FIST_HEAVY = RegisterIgnoredAmmo("MeleeFist_Heavy");
- static int SOFT = RegisterIgnoredAmmo("MeleeSoft");
- static int SOFT_HEAVY = RegisterIgnoredAmmo("MeleeSoft_Heavy");
- static int DUMMY = RegisterIgnoredAmmo("Dummy_Light");
- static int DUMMY_HEAVY = RegisterIgnoredAmmo("Dummy_Heavy");
- //@}
-
- static int RegisterSurface(string surface)
- {
- if (!m_ImpactEffect)
- m_ImpactEffect = new map<string, typename>;
-
- m_ImpactEffect.Insert(surface, surface.ToType());
-
- return ++m_LastRegisteredMaterial;
- }
-
- static bool UnregisterSurface(string surface)
- {
- if (m_ImpactEffect)
- {
- m_ImpactEffect.Remove(surface);
- return !m_ImpactEffect.Contains(surface);
- }
-
- return false;
- }
-
- static int RegisterIgnoredAmmo(string ammo)
- {
- if (!m_IgnoredAmmo)
- m_IgnoredAmmo = new map<string, int>;
-
- ++m_LastRegisteredIgnoredAmmo;
-
- m_IgnoredAmmo.Insert(ammo, m_LastRegisteredIgnoredAmmo);
-
- return m_LastRegisteredIgnoredAmmo;
- }
-
- static bool UnregisterIgnoredAmmo(string ammo)
- {
- if (m_IgnoredAmmo)
- {
- m_IgnoredAmmo.Remove(ammo);
- return !m_IgnoredAmmo.Contains(ammo);
- }
-
- return false;
- }
-
- static typename GetImpactEffect(string surface, string ammoType)
- {
- string key = string.Format("%1_%2", surface, ammoType);
-
- typename eff_type = m_ImpactEffect[key];
-
- if (eff_type)
- return eff_type;
- else
- return m_ImpactEffect[surface];
- }
-
- static void EvaluateImpactEffectEx(ImpactEffectsData pData)
- {
- EvaluateImpactEffect(pData.m_DirectHit, pData.m_ComponentIndex, pData.m_Surface, pData.m_Position, pData.m_ImpactType, pData.m_SurfaceNormal, pData.m_ExitPosition, pData.m_InSpeed, pData.m_OutSpeed, pData.m_IsDeflected, pData.m_AmmoType, pData.m_IsWater);
- }
-
- static void EvaluateImpactEffect(Object directHit, int componentIndex, string surface, vector pos, int impact_type, vector surfNormal, vector exitPos, vector inSpeed, vector outSpeed, bool deflected, string ammoType, bool isWater)
- {
- // No impact effects wanted for this ammo
- if (m_IgnoredAmmo.Contains(ammoType))
- return;
-
- if (impact_type == ImpactTypes.UNKNOWN)
- impact_type = ImpactTypes.STOP;
-
- if (deflected)
- impact_type = ImpactTypes.RICOCHET;
- else if (outSpeed)
- impact_type = ImpactTypes.PENETRATE;
-
- if (isWater)
- surface = "Hit_Water";
-
- EffBulletImpactBase eff = EffBulletImpactBase.Cast(GetImpactEffect(surface, ammoType).Spawn());
-
- if ( !eff && surface == "" ) // handle undefined surface
- {
- eff = EffBulletImpactBase.Cast( surface.ToType().Spawn() );
-
- if (eff)
- {
- RegisterSurface(surface);
- ErrorEx(string.Format("Unregistered surface for bullet impact effect (%1). Register this surface in ImpactMaterials (Script) for better performance.", surface), ErrorExSeverity.WARNING);
- }
- else
- {
- if (directHit)
- {
- string object_type = directHit.GetType();
-
- if ( object_type == "" )
- object_type = "OBJECT_WITHOUT_CONFIG_CLASS";
- ErrorEx(string.Format("Object '%1' with model file: %2 has undefined 'Hit_...' material! Cannot play impact effect.", object_type, directHit.GetShapeName()));
- eff = EffBulletImpactBase.Cast(GetImpactEffect("Hit_ErrorNoMaterial", ammoType).Spawn());
- }
- }
- }
-
- if ( !eff && surface != "" )
- {
- ErrorEx(string.Format("Unregistered surface impact material <%1>! Register this surface in ImpactMaterials (Script).", surface));
- eff = EffBulletImpactBase.Cast(GetImpactEffect("Hit_Undefined", ammoType).Spawn());
- }
-
- if (eff)
- {
- eff.EvaluateEffect(directHit, componentIndex, pos, impact_type, surfNormal, exitPos, inSpeed, outSpeed, ammoType);
- eff.SetAutodestroy(true);
- SEffectManager.PlayInWorld(eff, pos);
- }
- }
- }
|