Hpl2:Resources:script modules:coordsys

From Frictional Wiki
Jump to navigation Jump to search


Global Coordinate System

To do: What does this do? What was it made for? How to use this code?

The following block of code is a global coordinate system made by Homicide13.

Note icon.png Note: These functions were made using Apjjm's Improved Notepad++ HPS Support, and concequently would be viewed best with this plugin.

Copy and paste the following code either into your .hps file or into some form of .phps or .ihps file for use with the Script Pre-Processer.

This code will also require a certain set of entities to be included with your project. These entities can be downloaded here. Further instructions for instalation and use are provided within the code.

//***************************
//BEGIN GLOBAL COORD SYSTEM *
//***************************
//NOTE: All distances are in meters.

//--------------------
//Begin ADTs
//--------------------

class Pos {

	float x;
	float y;
	float z;
	bool correct;
	string entityName;
};

//--------------------
//End ADTs
//--------------------

//--------------------
//Begin Constants
//--------------------

//The density of the grid used to search for the position of objects.
//Continually dividing this number by 2 should eventually yeild 1, and there should be a sdiv entity for each sub division between and including this value and 1.
//NOTE: setting this number too low can cause lag.
const int GRID_DEN = 64;

//The value that the coordinits returned will be +- to.
//Continually multiplying this number by 2 should eventually yeild 1, and there should be a sdiv entity for each sub division between and including this value and 1.
//NOTE: setting this number too low can cause lag.
const float PRECISION = 0.0625;

//The maximum bounds for the coordinates system.
//(on both sides of the origin - so a MAX_X_POS of 16 would be able to find everything with an x value within -16 to 16)
//NOTE: the max positions should be evenly divisible by the GRID_DEN
//NOTE: setting these numbers too high can cause lag.  They should be tailored to fit your map.
const int MAX_X_POS = 128;
const int MAX_Y_POS = 128;
const int MAX_Z_POS = 128;

//This should be the base name of the octtree subdivision entities.
const string SDIV = "sdiv";

//Constant strings used to calculate things.
//These should only be changed if they conflict with anything else you are doing in the map/script.
const string COORD_NODE = "coord_node";
const string POS_DETCTR = "detector";
const string POS_FNDR = "finder";
const string ENT_ORGN = "origin";

//--------------------
//End Constants
//--------------------

//--------------------
//Begin Private Variables
//The names of these should only be changed if they conflict with anything else you are doing in the map/script.
//--------------------

float _fIterator = 0.0;

//--------------------
//End Private Variables
//--------------------

//--------------------
//Begin Private Functions
//--------------------

bool IsEven(float i){

	if((i % 2) == 0) return true;
	else return false;
}

void FixedAttachPropToProp(string& sAttachTo, string& sAttach, string& sEntityFile, float x, float y, float z){
   
	AddAttachedPropToProp(sAttachTo,sAttach,sEntityFile,x,y,0,z,90,z);
}

void GetPosIter(Pos& entityPos, float x, float y, float z, string &in sEntOrgn){
	
	for(float i = GRID_DEN/2; i>= PRECISION; i=i/2){
		
		string sItDetector = _fIterator+entityPos.entityName+i; //This makes sure every entity created for the octtree subdivisions has a unique name.
		float sdivCenterDist = i/2; //This is the distance between the center of each subdivision and the center of the previous correct subdivision (or in the case of the first iteration, the position detector.
		
		//These functions attach a subdivision in the correct location from the givin center point.
		//I proabablly could have come up with some kind of "for" routine to do it so that it looks a bit better, but I'm too lazy.
		FixedAttachPropToProp(COORD_NODE, sItDetector+1, SDIV+i+".ent",x+sdivCenterDist,y+sdivCenterDist,z+sdivCenterDist);
		FixedAttachPropToProp(COORD_NODE, sItDetector+2, SDIV+i+".ent",x-sdivCenterDist,y+sdivCenterDist,z+sdivCenterDist);
		FixedAttachPropToProp(COORD_NODE, sItDetector+3, SDIV+i+".ent",x+sdivCenterDist,y-sdivCenterDist,z+sdivCenterDist);
		FixedAttachPropToProp(COORD_NODE, sItDetector+4, SDIV+i+".ent",x-sdivCenterDist,y-sdivCenterDist,z+sdivCenterDist);
		FixedAttachPropToProp(COORD_NODE, sItDetector+5, SDIV+i+".ent",x+sdivCenterDist,y+sdivCenterDist,z-sdivCenterDist);
		FixedAttachPropToProp(COORD_NODE, sItDetector+6, SDIV+i+".ent",x-sdivCenterDist,y+sdivCenterDist,z-sdivCenterDist);
		FixedAttachPropToProp(COORD_NODE, sItDetector+7, SDIV+i+".ent",x+sdivCenterDist,y-sdivCenterDist,z-sdivCenterDist);
		FixedAttachPropToProp(COORD_NODE, sItDetector+8, SDIV+i+".ent",x-sdivCenterDist,y-sdivCenterDist,z-sdivCenterDist);
		
		     if(GetEntitiesCollide(sEntOrgn,sItDetector+1)) { x+=sdivCenterDist; y+=sdivCenterDist; z+=sdivCenterDist; }
		else if(GetEntitiesCollide(sEntOrgn,sItDetector+2)) { x-=sdivCenterDist; y+=sdivCenterDist; z+=sdivCenterDist; }
		else if(GetEntitiesCollide(sEntOrgn,sItDetector+3)) { x+=sdivCenterDist; y-=sdivCenterDist; z+=sdivCenterDist; }
		else if(GetEntitiesCollide(sEntOrgn,sItDetector+4)) { x-=sdivCenterDist; y-=sdivCenterDist; z+=sdivCenterDist; }
		else if(GetEntitiesCollide(sEntOrgn,sItDetector+5)) { x+=sdivCenterDist; y+=sdivCenterDist; z-=sdivCenterDist; }
		else if(GetEntitiesCollide(sEntOrgn,sItDetector+6)) { x-=sdivCenterDist; y+=sdivCenterDist; z-=sdivCenterDist; }
		else if(GetEntitiesCollide(sEntOrgn,sItDetector+7)) { x+=sdivCenterDist; y-=sdivCenterDist; z-=sdivCenterDist; }
		else if(GetEntitiesCollide(sEntOrgn,sItDetector+8)) { x-=sdivCenterDist; y-=sdivCenterDist; z-=sdivCenterDist; }
		
		for(int j = 1;j <= 8; j++) RemoveAttachedPropFromProp(COORD_NODE,sItDetector+j);
		
	}
	
	entityPos.x = x;
	entityPos.y = y;
	entityPos.z = z;
}

//--------------------
//End Private Functions
//--------------------

//--------------------
//Begin Public Functions
//--------------------

Pos GetPos(string& sEntity) {
//Finds the position of THE CENTER OF an entity and stores it in a Pos variable.
//This function can NOT find the origin of "Player".
	_fIterator += 0.0001;
	string sEntOrgn = _fIterator+sEntity+ENT_ORGN; //The name of the origin of the entity.  This ensures that each time an origin is created, it is unique.
	
	Pos entityPos;
	entityPos.entityName = sEntity;
	FixedAttachPropToProp(sEntity, sEntOrgn, SDIV+PRECISION+".ent", 0, 0, 0);
	
	for(int x = -(MAX_X_POS/(GRID_DEN/2)); x <= MAX_X_POS/(GRID_DEN/2); x++){
	for(int y = -(MAX_Y_POS/(GRID_DEN/2)); y <= MAX_Y_POS/(GRID_DEN/2); y++){
	for(int z = -(MAX_Z_POS/(GRID_DEN/2)); z <= MAX_Z_POS/(GRID_DEN/2); z++){
	
		if(IsEven(x) || IsEven(y) || IsEven(z)) continue; //This just prevents detection from an even spacing distance.  This is nessacary, otherwise the Max Positions would not be correct!
		
		string sPos_Detctr = POS_DETCTR+_fIterator+x+y+z; //The name of the detector entity.  This ensures that each time a detector, it is unique.
		
		FixedAttachPropToProp(COORD_NODE, sPos_Detctr, SDIV+GRID_DEN+".ent", x*(GRID_DEN/2), y*(GRID_DEN/2), z*(GRID_DEN/2));
		
		if(GetEntitiesCollide(sPos_Detctr,sEntOrgn)){
		
			GetPosIter(entityPos,x*(GRID_DEN/2),y*(GRID_DEN/2),z*(GRID_DEN/2),sEntOrgn);
			RemoveAttachedPropFromProp(COORD_NODE,sPos_Detctr);
			
			entityPos.correct = true;
			return entityPos;
		}
		else {
		
			RemoveAttachedPropFromProp(COORD_NODE,sPos_Detctr);
		}
	} } }
	
	RemoveAttachedPropFromProp(sEntity,sEntOrgn);
	entityPos.correct = false;
	entityPos.x = 0;
	entityPos.y = 0;
	entityPos.z = 0;
	return entityPos;
}

//--------------------
//End Public Functions
//--------------------

//*************************
//END GLOBAL COORD SYSTEM *
//*************************

//////////////////////////////////////////////////
//
//	Global Coordinates System by Homicide13
//
//	--------------------------------------------------
//
//	Installation:
//	If you plan on using this system you should include in your files all of the nessicary sub division entities (all of the general ones are provided),
//	and an entity named "coord_node" must be placed so that its center is at the (0,0,0) location of your map (an entity for this is provided as well).
//	This script should then be pasted at the beginning of your map file and the constants should be adjusted according to yoru needs (see below).
//
//	--------------------------------------------------
//
//	This system provides a new data type - the "Pos" class.
//      Pos has 5 member variables:
//
//	float x               - This is the x value of the position.
//	float y               - This is the y value of the position.
//	float z               - This is the z value of the position.
//	bool correct          - This is a flag that reflects whether the position has been accruately calculated - more about this later.
//	string entityName     - This is the name of the object whos position the data type represents.
//
//	--------------------------------------------------
//
//	This system also provides a new function: Pos GetPos(string& sEntity);
//
//	This function calculates the position of an entity (sEntity) and returns a "Pos" variable.
//	If the entity given to it could not be found (either it is not on the map, or it is not within the system bounds),
//		this function sets the x y and z values of the Pos it creates to 0, and sets the correct bool to false.
//	Unfortunatly, this function cannot be used to find the position of the player ("Player").
//
//	NOTE: This function calculates the location of the CENTER of the entity, not the origin.  Therefore the scaling of an entity will effect its loaction.
//
//	NOTE: This function only provides information on the location of the entity at the EXACT MOMENT the function is called.
//		The returned Pos variable will NOT continue to re-update if the entity is moved.
//
//	NOTE: This function can only be performed accuratly about 3.402823466e+42 times (estimate) in a single level.
//		However, if the level is reloaed (ie the player saves and quits and then re-loads the level, or leaves the level and enters again), this number will be reset.
//
//	--------------------------------------------------
//
//	GLOBAL CONSTANTS:
//	(All values listed here are the default values.)
//	(I highly suggest that you modify the GRID_DEN, PRECISION, AND MAX__POS variables to fit your map - otherwise this system can cause lag.)
//
//	The density of the grid used to search for the position of objects.
//	Continually dividing this number by 2 should eventually yeild 1, and there should be a sdiv entity for each sub division between and including this value and 1.
//	NOTE: setting this number too low can cause lag.
//		const int GRID_DEN = 64;
//
//	The value that the coordinits returned will be +- to.
//	Continually multiplying this number by 2 should eventually yeild 1, and there should be a sdiv entity for each sub division between and including this value and 1.
//	NOTE: setting this number too low can cause lag.
//		const float PRECISION = 0.0625;
//
//	The maximum bounds for the coordinates system.
//	(on both sides of the origin - so a MAX_X_POS of 16 would be able to find everything with an x value within -16 to 16)
//	NOTE: the max positions should be evenly divisible by the GRID_DEN
//	NOTE: setting these numbers too high can cause lag.  They should be tailored to fit your map.
//		const int MAX_X_POS = 128;
//		const int MAX_Y_POS = 128;
//		const int MAX_Z_POS = 128;
//
//	This should be the base name of the octtree subdivision entities.
//		const string SDIV = "sdiv";
//
//	Constant strings used to calculate things.
//	These should only be changed if they conflict with anything else you are doing in the map/script.
//		const string COORD_NODE = "coord_node";
//		const string POS_DETCTR = "detector";
//		const string POS_FNDR = "finder";
//		const string ENT_ORGN = "origin";
//
//////////////////////////////////////////////////