//===========================================================================//
// File:	damage.cpp                                                          //
// Project: MUNGA           Brick: Entity Manager                            //
// Contents: Damage Details                                                  //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 05/01/95  JM   Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc.                //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#include <munga.hpp>
#pragma hdrstop

#if !defined(SEGMENT_HPP)
#	include <segment.hpp>
#endif

#if !defined(EXPTBL_HPP)
#	include <exptbl.hpp>
#endif

#if !defined(FILEUTIL_HPP)
#	include <fileutil.hpp>
#endif

#if !defined(JMOVER_HPP)
#	include <jmover.hpp>
#endif

#if !defined(SCHAIN_HPP)
#	include <schain.hpp>
#endif

#if !defined(NOTATION_HPP)
#	include <notation.hpp>
#endif

#if !defined(NAMELIST_HPP)
#	include <namelist.hpp>
#endif

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MaterialList::MaterialList() :
	materialList(NULL)
{
	listIterator = new CStringSocketIterator(materialList);
	Register_Object(listIterator);
	Check_Fpu();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MaterialList::~MaterialList()
{
	DeletePlugs();

	Unregister_Object(listIterator);
	delete listIterator;
	Check_Fpu();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Damage::Damage()
{
	damageAmount = 0.0f;
	damageForce = Vector3D::Identity;
	surfaceNormal.x = 0.0f;
	surfaceNormal.y = 1.0f;
	surfaceNormal.z = 0.0f;
	impactPoint = Point3D::Identity;
	burstCount = 1.0f;
	Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

EntitySegment*
	DamageZone::GetCurrentEffectSite(Enumeration	effect_site_type) 
{
	Check(this);
	EntitySegment *return_segment;
	switch(effect_site_type)
	{
Return_Default_Effect:
   	case DefaultEffectSite:
		default:
		{
			SChainIteratorOf<EntitySegment*> iterator(defaultEffectSiteChain);
			Check(iterator.GetCurrent());
			return iterator.GetCurrent();
		}
		case InternalVideoEffectSite:
		{
			SChainIteratorOf<EntitySegment*> iterator(internalVideoEffectSiteChain);
			return_segment =  iterator.GetCurrent();
			if (return_segment)
			{
				Check(return_segment);
				return return_segment;
			}
			else
			{
				goto Return_Default_Effect;
			}
		}
		case ExternalVideoEffectSite:
		{
			SChainIteratorOf<EntitySegment*> iterator(externalVideoEffectSiteChain);
			return_segment =  iterator.GetCurrent();
			if (return_segment)
			{
				Check(return_segment);
				return return_segment;
			}
			else
			{
				goto Return_Default_Effect;
			}
		}
		case InternalAudioEffectSite:
		{
			SChainIteratorOf<EntitySegment*> iterator(internalAudioEffectSiteChain);
			return_segment =  iterator.GetCurrent();
			if (return_segment)
			{
				Check(return_segment);
				return return_segment;
			}
			else
			{
				goto Return_Default_Effect;
			}
		}
		case ExternalAudioEffectSite:
      {
			SChainIteratorOf<EntitySegment*> iterator(externalAudioEffectSiteChain);
			return_segment =  iterator.GetCurrent();
			if (return_segment)
			{
				Check(return_segment);
				return return_segment;
			}
			else
			{
				goto Return_Default_Effect;
			}
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	DamageZone::Reset(Logical )
{
	SetDamageZoneState(DefaultState);
	damageZoneGraphicState.SetState(ExistsGraphicState);
	damageLevel = 0.0f;
	Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	DamageZone::WriteUpdateRecord(UpdateRecord *update_record)
{
	Check(this);
	Check_Pointer(update_record);
	update_record->damageLevel = damageLevel;
	update_record->damageZoneState = damageZoneState.GetState();
	update_record->damageZoneGraphicState = damageZoneGraphicState.GetState();
	update_record->damageZoneIndex = damageZoneIndex;
   update_record->changedFlags = changedFlags;
	update_record->recordLength = sizeof(*update_record);
	//
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Clear Flags here for MasterInstance DamageZones!
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//
	ResetChangedFlags();
	Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	DamageZone::ReadUpdateRecord(UpdateRecord *update_record)
{
	Check(this);
	Check_Pointer(update_record);
	Verify(damageZoneIndex == update_record->damageZoneIndex);

	damageLevel = update_record->damageLevel;
	damageZoneState.SetState(update_record->damageZoneState);
	damageZoneGraphicState.SetState(update_record->damageZoneGraphicState);
   changedFlags = update_record->changedFlags;
	Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DamageZone::DamageZone(Simulation *owner, int damage_zone_index) :
	Node(DamageZoneClassID),
	materialTable(NULL, False),
	damageZoneState(DamageStateCount),
	damageZoneGraphicState(GraphicStateCount),
	defaultEffectSiteChain(NULL),
	internalVideoEffectSiteChain(NULL),
	externalVideoEffectSiteChain(NULL),
	internalAudioEffectSiteChain(NULL),
	externalAudioEffectSiteChain(NULL)
{
	Check(owner);
	damageZoneIndex = damage_zone_index;
	owningSimulation = owner;
	damageLevel = 0.0f;
	explosionTable = NULL;
	for(int ii=0;ii<Damage::DamageTypeCount;ii++)
	{
	  damageScale[ii] = 0.0f;
	}

	damageZoneName = "TrivialDamageZone_Name";

	changedFlags = 0;
   Reset();
	Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DamageZone::DamageZone(
	Simulation	*owning_simulation,
	int	damage_zone_index,
	MemoryStream *stream
) :
	Node(DamageZoneClassID),
	materialTable(NULL, False),
	damageZoneState(DamageStateCount),
	damageZoneGraphicState(GraphicStateCount),
	defaultEffectSiteChain(NULL),
	internalVideoEffectSiteChain(NULL),
	externalVideoEffectSiteChain(NULL),
	internalAudioEffectSiteChain(NULL),
	externalAudioEffectSiteChain(NULL)
{
	Check(owning_simulation);
	Check(stream);

	owningSimulation = owning_simulation;
	damageZoneIndex = damage_zone_index;
	damageLevel = 0.0f;
	explosionTable = NULL;
   Reset();

	*stream >> damageZoneName;

	if (owningSimulation->IsDerivedFrom(JointedMover::ClassDerivations))
	{
		JointedMover *jointed_mover = Cast_Object(
			JointedMover*,
			owningSimulation
		);
		//
		//~~~~~~~~~~~~~~~~~~~~~~~~~
		// Read in all Effect Sites
		//~~~~~~~~~~~~~~~~~~~~~~~~~
		//
		int effect_site_count;
		int effect_site_index;
		EntitySegment *effect_site_segment;
		//
		//~~~~~~~~~~~~~~~~~~~~~~~
		// Read in External Video
		//~~~~~~~~~~~~~~~~~~~~~~~
		//
		for (int jj=0;jj<EffectSiteCount;++jj)
		{
			*stream >> effect_site_count;
			for(int ii=0;ii<effect_site_count;++ii)
			{
				//
				//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				// Get the Site Segment From the Index
				//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				//
				*stream >> effect_site_index;
				effect_site_segment = jointed_mover->GetSegment(effect_site_index);
				Check(effect_site_segment);
				//
				//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				// Add the Segment to the Appropriate Chain
				//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				//
				switch (jj)
				{
					case DefaultEffectSite:
						defaultEffectSiteChain.Add(effect_site_segment);
					break;
					case ExternalVideoEffectSite :
						externalVideoEffectSiteChain.Add(effect_site_segment);
					break;
					case InternalVideoEffectSite :
						internalVideoEffectSiteChain.Add(effect_site_segment);
					break;
					case ExternalAudioEffectSite :
						externalAudioEffectSiteChain.Add(effect_site_segment);
					break;
					case InternalAudioEffectSite :
						internalAudioEffectSiteChain.Add(effect_site_segment);
					break;

				}
			}
		}
	}
	else
	{
		//
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// Read in these for consistancy
		// and for later improvements for
		// not Jointed Mover Objects!
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		//
		int filler_int;
		for (int jj=0;jj<EffectSiteCount;++jj)
		{
			*stream >> filler_int;
		}
	}

	*stream >> defaultArmorPoints;

	int ii;
	for (ii=0; ii<Damage::DamageTypeCount; ii++)
	{
		*stream >> damageScale[ii];
	}

	int skeleton_count;
	EntitySegment::SkeletonType skl_type;

	*stream >> skeleton_count;

	for(ii=0;ii<skeleton_count;++ii)
	{
		*stream >> skl_type;

		int material_count;
		*stream >> material_count;
		if(!material_count)
		{
			continue;
		}
		MaterialList *material_list = new MaterialList;
		Register_Object(material_list);
		for(int jj=0;jj<material_count;++jj)
		{
			CString new_material;
			*stream >> new_material;
			MaterialList::CStringPlug *new_plug =
				new MaterialList::CStringPlug(new_material);
			Register_Object(new_plug);
			material_list->Add(new_plug);
		}
		material_list->First();
		materialTable.AddValue(material_list, skl_type);
	}

	changedFlags = 0;
	Check_Fpu();
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DamageZone::~DamageZone()
{
	MaterialTableIterator iterator(materialTable);
	iterator.DeletePlugs();

	if (explosionTable)
	{
		Unregister_Object(explosionTable);
		delete explosionTable;
	}
	Check_Fpu();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ExplosionTable*
	DamageZone::CreateExplosionTable(MemoryStream *explosion_stream)
{
	Check(this);
	explosionTable = new ExplosionTable(explosion_stream);
	Register_Object(explosionTable);
	Check_Fpu();
	return explosionTable;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	DamageZone::TakeDamage(Damage &damage)
{
	Check(this);
	Check_Pointer(&damage);

	damageLevel += damage.damageAmount * damageScale[damage.damageType];
	Clamp(damageLevel, 0.0f, 1.0f);
   SetDamageLevelChangedFlag();
	if (damageLevel >= 1.0f)
	{
		SetDamageZoneState(BurningState);
		SetGraphicState(DestroyedGraphicState);
		SetGraphicStateChangedFlag();
	}
	Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Logical
	DamageZone::TestInstance() const
{
	return True;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Logical
	DamageZone::CreateStreamedDamageZone(
		NotationFile					*model_file,
		const char						*,
		NotationFile					*skl_file,
		CString						   damage_zone_name,
		MemoryStream					*damage_zone_stream,
		NotationFile					*dmg_file,
		const ResourceDirectories	*directories
	)
{
	Check_Pointer(damage_zone_name);
	Check_Pointer(&damage_zone_stream);
	Check_Pointer(directories);
	Check(dmg_file);

	*damage_zone_stream << damage_zone_name;

	//
	// Find dzone name in .dmg file
	//
	if(!dmg_file->PageExists(damage_zone_name))
	{
		cerr << damage_zone_name <<" listed in .skl, does not exist in .dmg file"<<endl;
		Check_Fpu();
		return -1;
	}
	if (skl_file)
	{
		//
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// Read and Write All The Effect Sites
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		//
		WriteEffectSegmentIndicies(
			damage_zone_stream,
			damage_zone_name,
			dmg_file,
			skl_file,
			"DefaultEffectSiteName"
		);
		WriteEffectSegmentIndicies(
			damage_zone_stream,
			damage_zone_name,
			dmg_file,
			skl_file,
			"ExternalVideoEffectSiteName"
		);
		WriteEffectSegmentIndicies(
			damage_zone_stream,
			damage_zone_name,
			dmg_file,
			skl_file,
			"InternalVideoEffectSiteName"
		);
		WriteEffectSegmentIndicies(
			damage_zone_stream,
			damage_zone_name,
			dmg_file,
			skl_file,
			"ExternalAudioEffectSiteName"
		);
		WriteEffectSegmentIndicies(
			damage_zone_stream,
			damage_zone_name,
			dmg_file,
			skl_file,
			"InternalAudioEffectSiteName"
		);
	}
	else
	{
		int zero_int(0);
		for(int ii=0;ii<EffectSiteCount;++ii)
		{
			*damage_zone_stream << zero_int;
		}
	}

	Scalar default_points;
	if(!dmg_file->GetEntry(
		damage_zone_name,
		"WeaponDamagePoints",
		&default_points
		)
	)
	{
			cerr<<damage_zone_name<<" Must have a WeaponDamagePoints"<<endl;
			return False;
	}
	if (!default_points)
	{
		cerr<<"DefaultDamagePoints must have a non-zero value !"<<endl;
		Check_Fpu();
		return False;
	}
	//
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Write default armor values
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//
	*damage_zone_stream << default_points;

	//
	// Read the damage Points values
	//
	float point_data;
	Scalar modified_armor;

	if(!dmg_file->GetEntry(
		damage_zone_name,
		"CollisionDamagePoints",
		&point_data
		)
	)
	{
		modified_armor = 1.0f/default_points;
	}
	else
	{
		if (point_data == 0.0f)
		{
			modified_armor = 1.0f/default_points;
		}
		else
		{
			modified_armor = 1.0f/point_data;
		}
		Check_Fpu();
	}
	*damage_zone_stream << modified_armor;

	if(!dmg_file->GetEntry(
		damage_zone_name,
		"BallisticDamagePoints",
		&point_data
		)
	)
	{
		modified_armor  = 1.0f/default_points;
	}
	else
	{
		modified_armor = 1.0f/point_data;
	}
	*damage_zone_stream << modified_armor;

	if(!dmg_file->GetEntry(
		damage_zone_name,
		"ExplosiveDamagePoints",
		&point_data
		)
	)
	{
		modified_armor = 1.0f/default_points;
	}
	else
	{
		modified_armor = 1.0f/point_data;
	}
	*damage_zone_stream << modified_armor;

	if(!dmg_file->GetEntry(
		damage_zone_name,
		"LaserDamagePoints",
		&point_data
		)
	)
	{
		modified_armor = 1.0f/default_points;
	}
	else
	{
		modified_armor =	1.0f/point_data;
	}
	*damage_zone_stream << modified_armor;

	if(!dmg_file->GetEntry(
		damage_zone_name,
		"EnergyDamagePoints",
		&point_data
		)
	)
	{
		modified_armor = 1.0f/default_points;
	}
	else
	{
		modified_armor = 1.0f/point_data;
	}
	*damage_zone_stream << modified_armor;

	//
	//~~~~~~~~~~~~~~~~~~~~~~~~~~
	//    Get dzm filename
	//~~~~~~~~~~~~~~~~~~~~~~~~~~
	//
	NameList *dzm_namelist = model_file->MakeEntryList("video","dzm");
	if(!dzm_namelist)
	{
			int zero_scalar(0.0f);
			*damage_zone_stream << zero_scalar;
			return True;
	}
	Register_Object(dzm_namelist);
	int dzm_filecount;
	dzm_filecount = dzm_namelist->EntryCount();
	*damage_zone_stream << dzm_filecount;

	if(dzm_filecount)
	{
		NameList::Entry *dzm_fileentry = dzm_namelist->GetFirstEntry();
		while(dzm_fileentry)
		{
			//
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			// write out the skeleton type of the material
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			//
			//
			CString dzm_entry_name;
			dzm_entry_name = dzm_fileentry->GetName();

			EntitySegment::SkeletonType skeleton_type;
			if (! dzm_entry_name.Compare("dzm") )
			{
				skeleton_type = EntitySegment::SkeletonType_N;
			}
			else if (! dzm_entry_name.Compare("dzms") )
			{
				skeleton_type = EntitySegment::SkeletonType_S;
			}
			else if (! dzm_entry_name.Compare("dzmt") )
			{
				skeleton_type = EntitySegment::SkeletonType_T;
			}
			else if (! dzm_entry_name.Compare("dzmo") )
			{
				skeleton_type = EntitySegment::SkeletonType_O;
			}
			else if (! dzm_entry_name.Compare("dzma") )
			{
				skeleton_type = EntitySegment::SkeletonType_A;
			}
			else if (! dzm_entry_name.Compare("dzmb") )
			{
				skeleton_type = EntitySegment::SkeletonType_B;
			}
			else if (! dzm_entry_name.Compare("dzmc") )
			{
				skeleton_type = EntitySegment::SkeletonType_C;
			}
			else if (! dzm_entry_name.Compare("dzmd") )
			{
				skeleton_type = EntitySegment::SkeletonType_D;
			}
			*damage_zone_stream << skeleton_type;

			//
			// Get the name of the dzm File
			//
			char *filename = MakePathedFilename(
				directories->videoDirectory,
				dzm_fileentry->GetChar()
			);
			Register_Pointer(filename);
			//
			//              Create a Notation file from the dzm ASCII File
			//
			NotationFile *dzm_file = new NotationFile(filename);
			Register_Object(dzm_file);

			NameList  *material_list;
			material_list = dzm_file->MakeEntryList(damage_zone_name, "material");
			int entry_count(0);
			if(material_list)
			{
         	
				Register_Object(material_list);
				//
				//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				// Write out how many materials
				//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				//
				entry_count = material_list->EntryCount();
				*damage_zone_stream << entry_count;
				if(entry_count)
				{
					NameList::Entry *dzm_entry;
					dzm_entry = material_list->GetFirstEntry();
					Check(dzm_entry);
					CString	material_name;
					while(dzm_entry)
					{
						material_name = dzm_entry->GetChar();
						//
						//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						// Write out the material name
						//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
						//
						*damage_zone_stream << material_name;
						dzm_entry = dzm_entry->GetNextEntry();
					}
				}
				Unregister_Object(material_list);
				delete material_list;
			}
         else
			{
				*damage_zone_stream << entry_count;
			}
			dzm_fileentry = dzm_fileentry->GetNextEntry();
			Unregister_Pointer(filename);
			delete filename;
			Unregister_Object(dzm_file);
			delete dzm_file;
		}
	}
	Unregister_Object(dzm_namelist);
	delete dzm_namelist;

	Check_Fpu();
	return True;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	DamageZone::WriteEffectSegmentIndicies(
		MemoryStream	*damage_zone_stream,
		const char 		*damage_zone_name,
		NotationFile	*dmg_file,
		NotationFile	*skl_file,
		const char		*effect_type
	)
{
	Check(dmg_file);
	Check(skl_file);
	Check_Pointer(damage_zone_name);
	//
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Make an Entry list for this type of effect Site
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//
	int effect_count(0);
	NameList::Entry *effect_entry;
	NameList *effect_namelist = dmg_file->MakeEntryList(damage_zone_name, effect_type);
	if (!effect_namelist)
	{
		//
		//~~~~~~~~~~~
		// No Entries
		//~~~~~~~~~~~
		//
		*damage_zone_stream << effect_count;
		Check_Fpu();
		return 1;
	}
	else
	{
		Register_Object(effect_namelist);
		//
		//~~~~~~~~~~~~~~~~~~~~~~~~~~
		// Write Out number of sites
		//~~~~~~~~~~~~~~~~~~~~~~~~~~
		//
		effect_count = effect_namelist->EntryCount();
		*damage_zone_stream << effect_count;
		effect_entry = effect_namelist->GetFirstEntry();
		CString site_page_name;
		int effect_site_index;
		while(effect_entry)
		{
			site_page_name = effect_entry->GetChar();
			//
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			// Get SegmentIndex for this effect site Name
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			//
			effect_site_index =
				JointedMover::GetSegmentIndex(site_page_name, skl_file);
			if (effect_site_index == -1)
			{
				cerr<<site_page_name<<" not found in skl file !"<<endl;
				Unregister_Object(effect_namelist);
				delete effect_namelist;
				return -1;
			}
			//
			//~~~~~~~~~~~~~~~~~~~~
			// Write Out the Index
			//~~~~~~~~~~~~~~~~~~~~
			//
			*damage_zone_stream << effect_site_index;
			effect_entry = effect_entry->GetNextEntry();
		}
		Unregister_Object(effect_namelist);
		delete effect_namelist;
	}
	Check_Fpu();
	return 1;
}
