public class AllEntities {
	public AllProjectiles projectiles;
	AllItems items;
	AllTrees trees;
	public AllMobs mobs;
	AllFurnitures furnitures;
	public static Entity[][] entitymap;
	public static List<int[]> changeList = new ArrayList<int[]>();
	public static int treetype = 1;
	public static int furnituretype = 2;
	public static int mobtype = 3;
	
	
	public AllEntities()
	{
		projectiles = new AllProjectiles();
		mobs = new AllMobs();
		items = GameScreen.items;
		trees = new AllTrees();
		furnitures = new AllFurnitures();
		entitymap = new Entity[Map.instance.width][Map.instance.height];
		/*for(int i = 0; i<itemap.length; i++)
		{
			for(int j = 0; j<itemap[0].length; j++)
			{
				itemap[i][j]=-1;
			}
		}*/
	}
	
	public static int getType(int x,int y)
	{
		Entity e = getEntity(x,y);
		if(e == null)return -1;
		else return e.entitype;
	}
	
	public static Entity getEntity(int x,int y)
	{
		if(x<0)x = entitymap.length+x;
		if(x>entitymap.length-1)x = 0+(x-(entitymap.length));
		if(y<0)y=0;
		if(y>entitymap[0].length)y=entitymap[0].length;
		return entitymap[x][y];
	}
	
	public static void setMap(int x, int y, Entity e)
	{
		if(x<0)x = entitymap.length+x;
		if(x>entitymap.length-1)x = 0+(x-(entitymap.length));
		entitymap[x][y] = e;
		int[] change = {x,y};
		changeList.add(change);
	}
	
	public static void rebootMap()
	{
		for(int i = changeList.size()-1; i>=0; i--)
		{
			entitymap[changeList.get(i)[0]][changeList.get(i)[1]] = null;
			changeList.remove(i);
		}
	}
	
	public void DrawAll(SpriteBatch batch)
	{
		projectiles.DrawMagic(batch);
	}
} public class Entity {
	
	public float offx = 0;
	public boolean isTurned = false;
	public boolean isDead = false;
	public boolean detach = true;
	public boolean attach = true;
	public float width = 0;
	public float height = 0;
	
	public int entitype = 0;
	
	public float getX()
	{
		return 0;
	}
	
	public float getY()
	{
		return 0;
	}
	
	public void setX(float xii)
	{
	}
	
	public void setY(float xii)
	{
	}
	
	public void draw(SpriteBatch batch)
	{
		tpOtherSide();
	}
	
	public void tpOtherSide()
	{
		if(getX()<2000 && GameScreen.player.PNJ.x>(Map.instance.width)*8)
		{
			setX((Map.instance.width)*16+(getX()));
		}
		if(getX()>=(Map.instance.width)*16-2000 && GameScreen.player.PNJ.x<(Map.instance.width)*8)
		{
			setX((getX()-(Map.instance.width)*16));
		}
	}
} public class GameScreen implements Screen 
{	
	public SpriteBatch batch;
	
	
	public static boolean isLeftClicked = false;
	public static boolean isItemTransit = false;
	public static boolean noLimit = true;
	public static float gameZoom = 1;
	
	public static OrthographicCamera camera;
	public static AllItems items;
	public static HParticleEmmiter emmiter;
	public static Selector select;
	public static AllEntities entities;
	public static Rain rain;
	public static Inventory inventory;
	public static Player player;
	public static Flashes flashes;
	public static ShapeRenderer shapeRenderer;
	public static MiniLoading saver;
	public static LifeBar lifeBar;
	public static Paralax paralax;
	
	public static Vector2 camiddle = new Vector2();
	
	public static Joystick joy;
	
	static Vector3 camvec = new Vector3();
	
	int CurFPS;
	static Vector3 camPos = new Vector3();
	static boolean UI = false;
	
	public boolean chatEnabled = false;

	Chat chat;
	
	private void Clear()
	{
		Gdx.gl.glClearColor(0,0,0,0f);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
	}
	
	public GameScreen() 
	{
		chat = new Chat();
		
		items = new AllItems();
		entities = new AllEntities();
		rain = new Rain();
	}

	@Override
	public void render(float delta) 
	{	
		NetworkManager.instance.modifications.applyModifications();
		NetworkManager.instance.update();
		
		Clear();
		TeleportPlayerOtherSide();
		if(Parameters.i.HQ >3)
		{
			Parameters.i.fullBright = true;
			Parameters.i.shader = true;
		}
		else
		{
			Parameters.i.fullBright = false;
			Parameters.i.shader = false;
		}
		
		if(Parameters.i.noShadow)
		{
			Parameters.i.fullBright = true;
			Parameters.i.shader = false;
		}
		
		UpdateCamera();
		
		if(!Parameters.i.fullBright || Parameters.i.shader)Map.instance.lights.UpdateLight();
		if(Parameters.i.shader && Parameters.i.fullBright)Shaders.instance.updateShadows();
		
		UpdateAndDrawRenderer();
		
		if(!Main.pause && (!player.transformed || Parameters.i.currentTransform != 4))MouseInputs();
		//TODO
		SwapCam();
		
		if(CurFPS!=Gdx.graphics.getFramesPerSecond())
		{
		Gdx.graphics.setTitle(String.valueOf(Gdx.graphics.getFramesPerSecond())); 
		CurFPS = Gdx.graphics.getFramesPerSecond();
		}
	}
	
	@Override
	public void resize(int width, int height)
	{
		Main.inputMultiplexer.removeProcessor(chat.scene);
		chat.scene = new Stage();
		chat.scene.addActor(chat.inputField);
		Main.inputMultiplexer.addProcessor(chat.scene);
		
		if(!Parameters.i.zoomLock)
		{
			camera.viewportWidth = width;
			camera.viewportHeight = height;
		}
		else
		{
			camera.viewportWidth = 1280;
			camera.viewportHeight = ((float)height/(float)width)*1280;
		}
		
	}
	
	public static void manualResize()
	{
		if(!Parameters.i.zoomLock)
		{
			camera.viewportWidth = Gdx.graphics.getWidth();
			camera.viewportHeight = Gdx.graphics.getHeight();
		}
		else
		{
			camera.viewportWidth = 1280;
			camera.viewportHeight = ((float)Gdx.graphics.getHeight()/(float)Gdx.graphics.getWidth())*1280;
		}
		resetCamera();
	}

	@Override
	public void show() 
	{
		if(!Shaders.instance.shadow.isCompiled())Parameters.i.HQ = 3;
		if(Main.mobile)Parameters.i.HQ = 1;
		if(Main.mobile)Parameters.i.fullBright = false;
		paralax = new Paralax();
		saver = new MiniLoading();
		camera = new OrthographicCamera(1280,720);
		batch = Main.batch;
		items = entities.items;
		emmiter = new HParticleEmmiter();
		emmiter.veloBase = new Vector2(64,64);
		emmiter.automatic = false;
		emmiter.additive = false;
		emmiter.randomRot = true;
		emmiter.baselife = 0.5f;
		emmiter.rotvar = 90;
		emmiter.baseSize = 0.7f;
		emmiter.sizevar = 0.2f;
		emmiter.gravity = 400;

		select = new Selector();
		inventory = new Inventory();
		flashes = new Flashes();
		shapeRenderer = new ShapeRenderer();
		lifeBar = new LifeBar();
		
		InitializePlayerAndCamera();
		Map.instance.lights.UpdateLight();
	}

	@Override
	public void hide() 
	{

	}

	@Override
	public void pause() 
	{

	}

	@Override
	public void resume() 
	{

	}

	@Override
	public void dispose() 
	{
		shapeRenderer.dispose();
	}
	
	public static void updatePauseClick()
	{
		SwapUI();
		if(Tools.isClicked(PauseMenu.instance.pb, 10))
		{
			Main.pause = !Main.pause;
		}
		SwapCam();
	}
	
	public static void PutOneItem(boolean isLeft)
	{
		SwapUI();
		if(Tools.isClicked(inventory.invButtonSprite, 10))
		{
		inventory.ToggleHide();
		}
		if(!inventory.hidden && isLeft == isLeftClicked)
		{
			if(isItemTransit) 
			{
				boolean isFinished = false;
				for(int i = 0; i<inventory.invItemsArray.length;i++)
				{
					if(!isFinished && Tools.isClicked(select.Selectors[i].image, Constants.invof))
					{
						isFinished = true;
						inventory.layOneItem(i,0);
						select.refreshSelector();
					}
					for(int j = 1; j<inventory.invItemsArray[i].length;j++)
					{	
						if(!isFinished && Tools.isClicked(inventory.invItemsArray[i][j].image, Constants.invof))
						{
							isFinished = true;
							inventory.layOneItem(i,j);
							select.refreshSelector();
						}
					}
				}
			}
		}
		SwapCam();
	}
	
	private void InitializePlayerAndCamera()
	{
		//TODO
		inventory.PutItem(1001);
		inventory.PutItem(1003);
		inventory.PutItem(1004);
		inventory.PutItem(1005);
		inventory.PutItem(1006);
		inventory.PutItem(1007);
		inventory.PutItem(1010);
		inventory.PutItem(1011);
		inventory.PutItem(1012);
		inventory.PutItem(1013);
		inventory.PutItem(1014);
		inventory.PutItem(1016);
		inventory.PutItem(1017);
		inventory.PutItem(1021);
		inventory.PutItem(1022);
		inventory.PutItem(1023);
		inventory.PutItem(1024);
		inventory.PutItem(1025);
		inventory.PutItem(1026);
		inventory.PutItem(1027);
		inventory.PutItem(1028);
		inventory.PutItem(1029);
		inventory.PutItem(1031);
		inventory.PutItem(1032);
		inventory.PutItem(1033);
		
		for(int i = 0; i<999; i++)
		{
			inventory.PutItem(1002);
			inventory.PutItem(1015);
			inventory.PutItem(1018);
			inventory.PutItem(1019);
			inventory.PutItem(1020);
			inventory.PutItem(1030);
			for(int j = 0; j<AllBlocTypes.instance.TileSetNumber; j++)inventory.PutItem(j);
		}
		
		
		/*for(int i = 0; i<999; i++)
		inventory.PutItem(AllBlocTypes.instance.IronBlockId);
		
		for(int i = 0; i<999; i++)
		inventory.PutItem(AllBlocTypes.instance.StoneBricksId);
		for(int i = 0; i<4000; i++)
		inventory.PutItem(AllBlocTypes.instance.TorchId);
		for(int i = 0; i<999; i++)
		inventory.PutItem(AllBlocTypes.instance.CobbleId);
		for(int i = 0; i<999; i++)
		inventory.PutItem(AllBlocTypes.instance.WoodId);
		for(int i = 0; i<999; i++)
		inventory.PutItem(AllBlocTypes.instance.DirtId);
		for(int i = 0; i<999; i++)
		inventory.PutItem(AllBlocTypes.instance.IronId);
		for(int i = 0; i<999; i++)
		inventory.PutItem(AllBlocTypes.instance.GlassId);
		for(int i = 0; i<999; i++)
		inventory.PutItem(AllBlocTypes.instance.IceId);*/
		/*
		constructions.addPortal(TiledMap2Layer.portalInitialPos.x-17, TiledMap2Layer.portalInitialPos.y+10);
		
		constructions.addPortal(AllConstructions.exteriorPos[0].x, AllConstructions.exteriorPos[0].y);
		constructions.addHouse(AllConstructions.exteriorPos[1].x, AllConstructions.exteriorPos[1].y, 1);
		constructions.addHouse(AllConstructions.exteriorPos[2].x, AllConstructions.exteriorPos[2].y, 2);
		constructions.addHouse(AllConstructions.exteriorPos[3].x, AllConstructions.exteriorPos[3].y, 3);
		
		constructions.addDoor(AllConstructions.interiorPos[1].x, AllConstructions.interiorPos[1].y, 1);
		constructions.addDoor(AllConstructions.interiorPos[2].x, AllConstructions.interiorPos[2].y, 2);
		constructions.addDoor(AllConstructions.interiorPos[3].x, AllConstructions.interiorPos[3].y, 3);
		
		
		selectBatch = new SpriteBatch();*/
		
		player = new Player();
		player.setPosition(player.initialPos.x, player.initialPos.y);
		//TODO
		
		
		
		Tools.checkItems();
		
		camera.zoom = gameZoom;
		camera.position.set(player.PNJ.x+player.PNJ.middle.x/2, player.PNJ.y+player.PNJ.middle.y/2, camera.position.z);	
	}

	static void SwapCam()
	{
		manualResize();
		camera.zoom = gameZoom;
		if(UI)camera.position.set(camPos);
		resetCamera();
		UI = false;
	}
	
	static void SwapUI()
	{
		camera.viewportWidth = Math.max(1280,Main.windowWidth);
		camera.viewportHeight = ((float)Gdx.graphics.getHeight()/(float)Gdx.graphics.getWidth())*camera.viewportWidth;
		UI = true;
		camera.zoom = 2f;
		camPos.x = camera.position.x;
		camPos.y = camera.position.y;
		camera.position.set(0,0,camera.position.z);
		resetCamera();
	}
	
	private void UpdateCamera()
	{
		if(Main.mobile)gameZoom = Main.zoom/2;
		else gameZoom = Main.zoom;
		
		float demiCamy = camera.viewportHeight*camera.zoom/2;
		float demiCamx = camera.viewportWidth*camera.zoom/2;
		
		if(isVillage())noLimit = false;
		else noLimit = true;
		
		Vector3 newpos = Tools.Lerp(camera.position,new Vector3((player.PNJ.x+player.PNJ.width/2), (player.PNJ.y+player.PNJ.height/2), (int)10));
		//newpos.x = Math.round(newpos.x/2)*2;
		//newpos.y = Math.round(newpos.y/2)*2;
		
		camera.position.set(newpos);
		
		
		if(!noLimit)
		{
			if(camera.position.x<demiCamx+2+16*2)camera.position.x = demiCamx+2+16*2;
			if(camera.position.x>Map.instance.width*16 - demiCamx-2)camera.position.x = Map.instance.width*16 - demiCamx-2;
		}
		
		if(camera.position.y<demiCamy+2+16*2)camera.position.y = demiCamy+2+16*2;
		if(camera.position.y>Map.instance.height*16 - demiCamy-2-16*2)camera.position.y = Map.instance.height*16 - demiCamy-2-16*2;
		
		
		if(!noLimit)
		{
			if(camera.position.y<(Map.instance.randomHeight+30)*16 + demiCamy)camera.position.y = (Map.instance.randomHeight+30)*16 + demiCamy;
			
			if(camera.position.x>Map.villageWidth*16 - demiCamx-2-32)camera.position.x = Map.villageWidth*16 - demiCamx-2-32;
		}
		else
		{
			if(camera.position.y>Map.instance.randomHeight*16 - demiCamy && !isVillage())camera.position.y = Map.instance.randomHeight*16 - demiCamy;
		}
		resetCamera();
		camiddle.x = camera.position.x;
		camiddle.y = camera.position.y;
	}

	public static void resetCamera()
	{
		//camvec.set(camera.position);
		//camera.position.set((Math.round((camera.position.x-camera.viewportWidth/2)/2)+camera.viewportWidth/4)*2, (Math.round(camera.position.y/2-camera.viewportHeight/4)+camera.viewportHeight/4)*2, 10);
		camera.update();
		//camera.position.set(camvec);
		Tools.computeAbsoluteMouse();
	}

	private void TeleportPlayerOtherSide()
	{
		if(noLimit)
		{
			if(camiddle.x<0)
			{
				
				float x = (Map.instance.width)*16+(player.PNJ.x);
				player.setPosition(x,player.PNJ.y);
				camera.position.set(camera.position.x+(Map.instance.width)*16, camera.position.y, camera.position.z);
				player.PNJ.hook.tpOtherSide();
				for(int l = DeforMeshes.instance.implist.size()-1; l>=0; l--)
				{
					DeforMeshes.instance.implist.get(l).x+=(Map.instance.width)*16;
				}
				
				player.PNJ.calculateShoulder();
				player.PNJ.calculateVectors();
				
			}
			if(camiddle.x>=(Map.instance.width)*16)
			{
				
				float x = 0+(player.PNJ.x-(Map.instance.width)*16);
				player.setPosition(x,player.PNJ.y);
				camera.position.set(camera.position.x-(Map.instance.width)*16, camera.position.y, camera.position.z);
				player.PNJ.hook.tpOtherSide();
				
				for(int l = DeforMeshes.instance.implist.size()-1; l>=0; l--)
				{
					DeforMeshes.instance.implist.get(l).x-=(Map.instance.width)*16;
				}
			}
			
			player.PNJ.calculateShoulder();
			player.PNJ.calculateVectors();
			
			resetCamera();
		}
	}
	
	private void UpdateAndDrawRenderer(){
		
		
		batch.setColor(Color.WHITE);
		batch.setProjectionMatrix(camera.combined);
		
		batch.begin();
		
		if(Parameters.i.FBORender)
		{
		Main.fbo.begin();
		Clear();
		batch.setBlendFunction(-1, -1);
		Gdx.gl20.glBlendFuncSeparate(GL20.GL_SRC_ALPHA,GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE,GL20.GL_ONE);
		}
		
		if(Parameters.i.background)
		{
			paralax.DrawBack(batch);
			batch.setColor( Parameters.i.daylight, Parameters.i.daylight, Parameters.i.daylight, 1);
			paralax.DrawAll(batch);
			batch.setColor( 1, 1, 1, 1);
		}
		batch.end();
		
		Shaders.instance.setShadowShader();
		
			batch.begin();
			
				if(Parameters.i.fullBright && Parameters.i.shader)batch.setColor( 0.25f, 0.25f, 0.25f, 1);
				else batch.setColor( 0.45f, 0.45f, 0.45f, 1);
				Map.instance.DrawBack((SpriteBatch) batch);
				batch.setColor( 0.45f, 0.45f, 0.45f, 1);
				Map.instance.backLayer.draw(batch);
				
				batch.setColor(1,1,1,1);
				AllEntities.rebootMap();
				
				entities.furnitures.checkPoints();
				entities.mobs.checkPoints();
				
				entities.trees.DrawAll(batch);
				entities.furnitures.DrawAll(batch);
				
				entities.projectiles.UpdateGrapples(batch);
				player.Update();
				entities.projectiles.DrawGrapples(batch);
				entities.projectiles.DrawProjectiles(batch);
				
				
				if(!Main.noUI)player.draw(batch);
				
				entities.mobs.DrawAll(batch);
				entities.DrawAll(batch);
				
				items.DrawAll(batch);
				
				rain.draw(batch);
				Map.instance.mainLayer.draw(batch);
				
				drawBlockShadow(batch);
				
				drawCursorShadow(batch);
				
				emmiter.update(Main.delta);
				emmiter.draw(batch);
				
				//MouseInputs();
			
			batch.end();
			
		if(Parameters.i.FBORender)
		{
			batch.setBlendFunction(-1, -1);
			Gdx.gl20.glBlendFuncSeparate(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA,GL20.GL_ONE, GL20.GL_DST_ALPHA);
			
			Main.fbo.end();
			
			Shaders.instance.setShadowShaderFBO();
			batch.setProjectionMatrix(Main.defaultMatrix);
			
			Texture rtex = Main.fbo.getColorBufferTexture();
			rtex.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
			
			batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
			
			Gdx.gl20.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
	        Gdx.gl20.glEnable(GL20.GL_TEXTURE_2D);
	        Gdx.gl20.glEnable(GL20.GL_BLEND);
	        Gdx.gl20.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
			
	        rtex.bind();
			
			Shaders.instance.meshader.begin();
			Shaders.instance.meshader.setUniformMatrix("u_projTrans", batch.getProjectionMatrix());
			Shaders.instance.meshader.setUniformi("u_texture", 0);

			DeforMeshes.instance.createFullScreenQuad();
			
			Main.mesh.render(Shaders.instance.meshader, GL20.GL_TRIANGLES);
			
			Shaders.instance.meshader.end();
		}

		Shaders.instance.setDefaultShader();
		
		SwapUI();
		batch.setProjectionMatrix(camera.combined);
		
		batch.begin();
		
			if(!Main.noUI)
			{
				select.setPosition(camera.position.x,camera.position.y+camera.viewportHeight, Main.delta);
				select.selectorBackGround.draw(batch);
				for(int i = 0; i<select.backSelectorSprites.length;i++)
				{
					select.backSelectorSprites[i].draw(batch);
				}
				for(int i = 0; i<select.Selectors.length;i++)
				{
					select.Selectors[i].drawAll(batch);
				}
				select.torchSprite.draw(batch);
				
				inventory.invButtonSprite.setPosition(camera.viewportWidth-inventory.invButtonSprite.getWidth()*4,camera.viewportHeight-inventory.invButtonSprite.getHeight()-200);
				inventory.invButtonSprite.draw(batch);
				
				PauseMenu.instance.drawPauseButton(batch);
		
				inventory.setPosition(camera.position.x,camera.position.y+camera.viewportHeight);
				inventory.drawAll(batch);
		
				lifeBar.DrawAll(-camera.viewportWidth+200,camera.viewportHeight-70,batch);
				saver.DrawAll(batch);
				
				if(Parameters.i.fullBright && !Parameters.i.shader)FontManager.instance.font.draw(batch, "Shadows: None", camera.viewportWidth-500, camera.viewportHeight-25);
				else FontManager.instance.font.draw(batch, "Shadows: "+Constants.qualities[Parameters.i.HQ], camera.viewportWidth-500, camera.viewportHeight-25);
				
				if(Main.mobile)
				{
					Color coltemp = batch.getColor();
					batch.setColor(Color.WHITE);
					joy.draw(batch);
					batch.setColor(coltemp);
				}
				
				if(Main.pause)PauseMenu.instance.draw(batch,Tools.getAbsoluteMouse().x,Tools.getAbsoluteMouse().y);
				
				
			}
			
		batch.end();
		
		
		SwapCam();
		batch.setProjectionMatrix(camera.combined);
		
		chat.drawMessages(camera.position.x-camera.viewportWidth/2, camera.position.y - camera.viewportHeight/2);
		if(chatEnabled)chat.draw();
		
		flashes.DrawAll();
		
		if(player.isDead)
		{
			flashes.FlashDead();
			player.isDead = false;
		}
		else if(player.hurt)
		{
			flashes.FlashHurt();
			player.hurt = false;
		}
		
	}
	
	public void drawCursorShadow(SpriteBatch batch)
	{
		if(inventory.hidden && !Main.pause)
		{
			boolean axe = (GameScreen.player.currentCellID>999 && AllTools.instance.getType(GameScreen.player.currentCellID).type == AllTools.instance.Axe);
			boolean hand = (GameScreen.player.currentCellID==0);
			
			if(axe || hand)
			{
				Color col = batch.getColor();
				float range;
				
				Vector2 mous = Tools.getAbsoluteMouse();
				int px = Tools.floor(mous.x/16);
				int py = Tools.floor(mous.y/16);
				
				if(Inputs.instance.shift)
				{

					Vector2 defaultVec = new Vector2(mous).sub(GameScreen.player.PNJ.shoulderPos);
					
					Vector2 faster = new Vector2(1000000,1000000);
					Vector2 bestaimed = new Vector2(-1,-1);
					float limitlen = new Vector2(px*16+8 - GameScreen.player.PNJ.middle.x,py*16+8 - GameScreen.player.PNJ.middle.y).len();
					
					for(int i = 0; i<7; i++)
					{
						Vector2 aimed = new Vector2(Tools.raycastVec(GameScreen.player.PNJ.middle.x, GameScreen.player.PNJ.middle.y-22+9*(i), defaultVec.x, defaultVec.y, 4));
						
						
						if(aimed.y>=0)
						{
							Vector2 testvec = new Vector2(aimed.x*16+8 - GameScreen.player.PNJ.middle.x,aimed.y*16+8 - GameScreen.player.PNJ.middle.y);

							if(faster.len()>testvec.len() && limitlen>testvec.len())
							{
								faster = testvec;
								bestaimed = aimed;
							}
						}
					}
					
					if(bestaimed.y>=0)
					{
						px = Tools.floor(bestaimed.x+0.1f);
						py = Tools.floor(bestaimed.y+0.1f);
					}
				}
				
				if(axe)range = AllTools.instance.getType(GameScreen.player.currentCellID).range;
				else range = ModifyTerrain.range;
				
				ModifyTerrain.instance.distToMiddleVec.x = px*16+8-GameScreen.player.PNJ.shoulderPos.x;
				ModifyTerrain.instance.distToMiddleVec.y = py*16+8-GameScreen.player.PNJ.shoulderPos.y;
				float distToMiddle = ModifyTerrain.instance.distToMiddleVec.len();
					
				if(distToMiddle>range)
				{
					batch.setColor(1,1/4, 1/4, 0.4f);
				}
				else
				{
					batch.setColor(1,0.85f, 0.6f, 0.4f);
				}
			
				
				batch.draw(TextureManager.instance.cadre, px*16-3, py*16-3, 22, 22);

				batch.setColor(col);
				
			}
		}
	}
	
	public void drawBlockShadow(SpriteBatch batch)
	{
		if(inventory.hidden && !Main.pause)
		{
			boolean furniture = (GameScreen.player.currentCellID>999 && AllTools.instance.getType(GameScreen.player.currentCellID).type == AllTools.instance.Furniture);
			boolean block = (GameScreen.player.currentCellID<999 && GameScreen.player.currentCellID>0);
			boolean tree = (GameScreen.player.currentCellID>999 && AllTools.instance.getType(GameScreen.player.currentCellID).type == AllTools.instance.Tree);
			
			
			if(tree || furniture || block)
			{
				TextureRegion tex;
				Color col = batch.getColor();
				float range;
				
				Vector2 mous = Tools.getAbsoluteMouse();
				int px = Tools.floor(mous.x/16);
				int py = Tools.floor(mous.y/16);
				
				int w = 16;
				int h = 16;
				
				ModifyTerrain.instance.distToMiddleVec.x = px*16+8-GameScreen.player.PNJ.middle.x;
				ModifyTerrain.instance.distToMiddleVec.y = py*16+8-GameScreen.player.PNJ.middle.y;
				float distToMiddle = ModifyTerrain.instance.distToMiddleVec.len();
				
				boolean ok = true;
				
				
				if(furniture)
				{	
					range = AllTools.instance.getType(GameScreen.player.currentCellID).range;
					if(!ModifyTerrain.instance.furnitureCollision(GameScreen.player.currentCellID,px,py))ok = false;
					tex = AllTools.instance.getType(GameScreen.player.currentCellID).tex;
					w = AllTools.instance.getType(GameScreen.player.currentCellID).furnitureWidth*16;
					h = AllTools.instance.getType(GameScreen.player.currentCellID).furnitureHeight*16;
				}
				else if(block)
				{
					range = ModifyTerrain.range;
					if(AllBlocTypes.instance.getType(GameScreen.player.currentCellID).oldTexture)
					{
						tex = TextureManager.instance.TextureRegions[GameScreen.player.currentCellID][AllBlocTypes.instance.Alone];
					}
					else
					{
						tex = TextureManager.instance.TextureRegions[GameScreen.player.currentCellID][AllBlocTypes.instance.Nosides%10];
					}
					
					if(!ModifyTerrain.instance.justone(Map.instance.mainLayer, px, py, GameScreen.player.currentCellID))ok = false;
					else if(Map.instance.mainLayer.getBloc(px, py).Id != 0)ok = false;
					else if(AllEntities.getEntity(px, py) != null)ok = false;
					else if(AllBlocTypes.instance.getType(GameScreen.player.currentCellID).needBack &&  !Map.instance.backLayer.getBloc(px, py).collide)ok = false;
				}
				else
				{
					range = AllTools.instance.getType(GameScreen.player.currentCellID).range;
					tex = GameScreen.items.getTextureById(GameScreen.player.currentCellID);
					w = 32;
					h = 32;
					if(ModifyTerrain.instance.treeCollision(px,py))ok = false;
				}
				
				
				
				if(!ok)
				{
					batch.setColor(1,1/4, 1/4, 0.7f);
				}
				else if(distToMiddle>range)
				{
					batch.setColor(1,1/1.5f, 1/4, 0.7f);
				}
				else
				{
					batch.setColor(1/4,1, 1/4, 0.7f);
				}
							
				
				int offy = -2;
				if(block)offy = 0;
				if(tree)offy = -6;
				if(!player.currentForm.isTurned || (!furniture))batch.draw(tex, px*16, py*16+offy, w, h);
				else batch.draw(tex, px*16+w, py*16+offy, -w, h);

				batch.setColor(col);
			}
			
		}
	}

	public void MouseInputs()
	{
		
		SwapUI();
		boolean abort = false;
		for(int i = 0; i<select.backSelectorSprites.length; i++)
		{
			if(Tools.isClicked(select.backSelectorSprites[i], Constants.invof))abort = true;
		}
		SwapCam();
		
		if(Main.mobile)
		{
			if(joy.isTouching || joy.isClicked(Tools.getAbsoluteMouseUI(Gdx.input.getX(),Gdx.input.getY())))abort = true;
		}
		
		if(Inputs.instance.leftpress)
		{
			//PUTCELL
			if(!abort && inventory.hidden && !player.transformed)ModifyTerrain.instance.PutCell( player.currentCellID,player.currentCellState, Map.instance.mainLayer,Main.time,true);
		}
		else if(Inputs.instance.rightpress)
		{
			//PUTCELL
			boolean backPlaced;
			if(player.currentCellID>999)
				backPlaced = false;
			else
				backPlaced = AllBlocTypes.instance.getType(player.currentCellID).needBack;
			
			if(!abort && inventory.hidden && !backPlaced && !player.transformed)ModifyTerrain.instance.PutCell(player.currentCellID,player.currentCellState, Map.instance.backLayer,Main.time,false);
		}
	}
	
	
	
	public static boolean isVillage()
	{
		if(Main.mobile)return false;
		if(player.PNJ.x<Map.villageWidth*16 && player.PNJ.y>Map.instance.height*16-Map.villageHeight*16)
		{
			return true;
		}
		return false;
	}
} public class HitBox {
	Vector2[] col;
	ArrayList<Vector2> colDown = new ArrayList<Vector2>();
	ArrayList<Vector2> colUp = new ArrayList<Vector2>();

	ArrayList<Vector2> colOrigin = new ArrayList<Vector2>();
	ArrayList<Vector2> colEnd = new ArrayList<Vector2>();
	
	int size = 0;
	
	public float x = 0;
	public float y = 0;
	public float offx = 0;
	public float offy = 0;
	public float min = 0;
	public int offh = 20;
	public float turnoffx = 0;
	public boolean isTurned = false;
	public Vector2 maxFloor;
	public Vector2 minFloor;
	public boolean noturn = false;
	
	public HitBox(Rectangle rec,Rectangle rec2, float offfx)
	{
		ArrayList<Rectangle> list = new ArrayList<Rectangle>();
		list.add(rec);
		list.add(rec2);
		init(list,offfx);
	}
	
	public HitBox(Rectangle rec, float offfx)
	{
		ArrayList<Rectangle> list = new ArrayList<Rectangle>();
		list.add(rec);
		init(list,offfx);
	}
	
	public HitBox(ArrayList<Rectangle> rec, float offfx)
	{
		init(rec,offfx);
	}
	
	public void init(ArrayList<Rectangle> rec, float offfx)
	{
		turnoffx = offfx;
		
		min = rec.get(0).y;
		for(int j = 0; j<rec.size(); j++)
		{
			if(rec.get(j).y<min)
			{
				min = rec.get(j).y;
			}
		}
		for(int j = 0; j<rec.size(); j++)
		{
			if(Math.abs(rec.get(j).y - min)<0.1f)
			{
				if(maxFloor!= null && minFloor!= null)
				{
					if(maxFloor.x<rec.get(j).x+rec.get(j).width)
					{
						maxFloor.x = rec.get(j).x+rec.get(j).width;
						maxFloor.y = rec.get(j).y;
					}
					else if(minFloor.x>rec.get(j).x)
					{
						maxFloor.x = rec.get(j).x;
						maxFloor.y = rec.get(j).y;
					}
				}
				else
				{
					minFloor = new Vector2(rec.get(j).x, rec.get(j).y);
					maxFloor = new Vector2(rec.get(j).x+rec.get(j).width, rec.get(j).y);
				}
			}
		}
		
		size = rec.size(); 
		
		for(int i = 0; i<rec.size(); i++)
		{
			colOrigin.add(new Vector2(rec.get(i).x, rec.get(i).y));
			colEnd.add(new Vector2(rec.get(i).x+rec.get(i).width, rec.get(i).y+rec.get(i).height));
		}
		
	}
	
	public void update(float x, float y)
	{
		this.x = x;
		this.y = y;
	}
	
	public boolean stableFloor()
	{
		if(tileCollide(maxFloor.x, maxFloor.y-8) && tileCollide(minFloor.x, minFloor.y-8))return true;
		return false;
	}
	
	public boolean upHitOffset(float x, float y)
	{
		for(int i = 0; i<size; i++)
		{
			float originy = Math.max(min+offh, colOrigin.get(i).y);
			float endy = Math.max(min+offh, colEnd.get(i).y);
			
			if(originy!=endy)
			{
				if(isCollide(colOrigin.get(i).x+x, originy+y, colEnd.get(i).x+x, endy+y))return true;
			}
		}
		return false;
	}
	
	public boolean downHitOffset(float x, float y)
	{
		for(int i = 0; i<size; i++)
		{
			float originy = Math.min(min+offh, colOrigin.get(i).y);
			float endy = Math.min(min+offh, colEnd.get(i).y);
			
			if(originy!=endy)
			{
				if(isCollide(colOrigin.get(i).x+x, originy+y, colEnd.get(i).x+x, endy+y))return true;
			}
		}
		return false;
	}
	
	public boolean hitOffset(float x, float y)
	{
		for(int i = 0; i<size; i++)
		{
			if(isCollide(colOrigin.get(i).x+x, colOrigin.get(i).y+y, colEnd.get(i).x+x, colEnd.get(i).y+y))return true;
		}
		return false;
	}
	
	public boolean TestCollisionsAll()
	{
		for(int i = 0; i<size; i++)
		{
			if(isCollide(colOrigin.get(i).x, colOrigin.get(i).y, colEnd.get(i).x, colEnd.get(i).y))return true;
		}
		return false;
	}
	
	public boolean TestCollisions(boolean up)
	{
		if(up)
		{
			if(upHitOffset(0, 0))return true;
		}
		else
		{
			if(downHitOffset(0, 0))return true;
		}
		return false;
	}

	public boolean TestCollisionsHigh()
	{
		return hitOffset(0,16);
	}

	public boolean TestCollisionsDown()
	{
		return hitOffset(0,-4);
	}
	
	private boolean isCollide(float px, float py, float epx, float epy)
	{
		if(isTurned && !noturn)
		{
			float tepx = epx;
			epx = -px+turnoffx;
			px = -tepx+turnoffx;
		}
		
		int minx = Tools.floor((px+x)/16);
		int miny = Tools.floor((py+y)/16);
		int maxx = Tools.floor((epx+x)/16);
		int maxy = Tools.floor((epy+y)/16);
		for(int i = minx; i<=maxx; i++)
		{
			for(int j = miny; j<=maxy; j++)
			{
				if(Map.instance.mainLayer.getBloc(i,j).collide)return true;
			}
		}
		return false;
	}
	
	private boolean tileCollide(float x, float y)
	{
		return Map.instance.mainLayer.getBloc(Tools.floor((x+this.x)/16),Tools.floor((y+this.y)/16)).collide;
	}
	
	public void drawHitBox()
	{
		Main.batch.setColor(0, 1, 0, 0.6f);
		for(int i = 0; i<size; i++)
		{
			if(isTurned && !noturn)Tools.drawRect(x-colOrigin.get(i).x+turnoffx, colOrigin.get(i).y+y, colOrigin.get(i).x-colEnd.get(i).x, colEnd.get(i).y-colOrigin.get(i).y);
			else Tools.drawRect(colOrigin.get(i).x+x, colOrigin.get(i).y+y, colEnd.get(i).x-colOrigin.get(i).x, colEnd.get(i).y-colOrigin.get(i).y);
		}
	}
} public class HitRect {
	public ArrayList<Rectangle> normal;
	public ArrayList<Rectangle> flipped;
	public float turnoffx = 0;
	public boolean noturn = false;
	
	public HitRect(float offx)
	{
		turnoffx = offx;
		normal = new ArrayList<Rectangle>();
		flipped = new ArrayList<Rectangle>();
	}
	
	public void add(Rectangle rec)
	{
		Rectangle rec2 = new Rectangle(turnoffx-rec.x-rec.width, rec.y, rec.width, rec.height);
		normal.add(rec);
		flipped.add(rec2);
	}
	
	public ArrayList<Rectangle> getRects(boolean turned)
	{
		if(!turned || noturn)
		{
			return normal;
		}
		else
		{
			return flipped;
		}
	}
} public class Main extends Game {
	
	public static Main instance;
	
	public static boolean devtest = true;
	public static boolean mobile = false;
	
	public static int windowWidth = 1280;
	public static int windowHeight = 720;
	
	public static boolean noUI = false;
	
	public static boolean enableCheats = true;
	public static boolean backtom;
	
	public static boolean multiplayer = false;
	public static boolean host = false;
	
	public static String defaultWelcomeMessage = "This is a development version - Multiplayer port: 25565";
	public static String welcomeMessage = "This is a development version - Multiplayer port: 25565";
	public static Color welcomeColor = Color.WHITE;
	
	public static float delta;
	public static float time;
	public static boolean pause;
	
	public static NetworkManager network;
	
	public static float zoom;
	
	public static GameScreen game;
	public static CharEditorScreen charedit;
	public static SettingsScreen settings;
	public static MenuScreen menu;
	public static LoadingScreen loading;
	public static boolean loaded;
	public static SpriteBatch batch;
	public static SpriteBatch secondBatch;
	public static SaveManager saveMan;
	public static boolean ingame;
	public static Thread secondThread;
	
	public static Matrix4 defaultMatrix;
	public static OrthographicCamera matrixCam;
	
	public static FrameBuffer fbo;
	public static Random random;
	
	public static Mesh mesh;

	public static InputMultiplexer inputMultiplexer;
	static Joystick joy;
	
	public static boolean allLoaded;
	
	public static void sCreate()
	{
		allLoaded = false;
		noUI = false;
		multiplayer = false;
		host = false;
		ingame = false;
		time = 0;
		pause = false;
		loaded = false;
		zoom = 1;
		backtom = false;
		
		inputMultiplexer = new InputMultiplexer();
		
		if(NetworkManager.instance != null && NetworkManager.instance.server != null)NetworkManager.instance.server.stop();
		network= new NetworkManager();
		//if(multiplayer)network.connectLocal();
		
		Parameters.i = new Parameters();
		DeforMeshes.instance = new DeforMeshes(32, 18);
		
		windowWidth = Gdx.graphics.getWidth();
		windowHeight = Gdx.graphics.getHeight();
		
		matrixCam = new OrthographicCamera();
		defaultMatrix = new Matrix4();
		
		//new HNoise(0).generateGradient(200, 200, 10, 10);
		random = new Random();
		
		saveMan = new SaveManager();
		menu = new MenuScreen();
		
		charedit = new CharEditorScreen();
		settings = new SettingsScreen();
		
		SaveManager.instance.LoadParams();
		updateResolution();
		sResize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
		Gdx.graphics.setVSync(Parameters.i.vsync);
		
		Parameters.i.disableCheats();
		
		inputMultiplexer.addProcessor(Inputs.instance);
		
		Gdx.input.setInputProcessor(inputMultiplexer);
		
		SoundManager.instance.updateVolume();
		HKeys.setKeyboard(Parameters.i.keyboard);
	}
	
	@Override
	public void create () 
	{
		instance = this;
		Shaders.instance = new Shaders();
		batch = new SpriteBatch();
		batch.setShader(Shaders.instance.basic);
		
		secondBatch = new SpriteBatch();
		secondBatch.setShader(Shaders.instance.basic);
		
		SaveManager.instance = new SaveManager();
		SoundManager.instance = new SoundManager();
		FontManager.instance = new FontManager();
		AllBlocTypes.instance = new AllBlocTypes();
		TextureManager.instance = new TextureManager();
		AllTools.instance = new AllTools();
		AllCrafts.instance = new AllCrafts();
		PauseMenu.instance = new PauseMenu();
		
		if(Main.mobile)
		{
			joy = new Joystick();
			inputMultiplexer.addProcessor(joy);
		}
		
		Inputs.instance = new Inputs();
		
		sCreate();
		
	}
	
	public static void updateMatrix()
	{
		matrixCam.viewportWidth = windowWidth;
		matrixCam.viewportHeight =  windowHeight;
		matrixCam.position.set(windowWidth/2, windowHeight/2,0);
		matrixCam.update();
		defaultMatrix.set(matrixCam.combined);
		
		fbo = new FrameBuffer(Format.RGBA8888 ,windowWidth, windowHeight,false);
	}
	
	public static void updateResolution()
	{
		float ratio = 3f/4f;
		if(Parameters.i.ratio)ratio = 9f/16f;
		updateResolution(Constants.resolutions[Parameters.i.resolution], (int)(Constants.resolutions[Parameters.i.resolution]*ratio));
	}
	
	public static void updateResolution(int wx, int hy)
	{
		//Gdx.graphics.setDisplayMode(wx, hy, Parameters.i.fullscreen);
		Gdx.graphics.setWindowedMode(wx, hy);
	}
	
	@Override
	public void resize (int width, int height) {
		super.resize(width, height);
		sResize(width,height);
	}
	
	public static void sResize(int width, int height)
	{
		if((float)width/(float)height>18f/9f)updateResolution(width, (int) (width*9f/16f)-1);
		else if((float)width/(float)height<16f/13f)updateResolution((int) (height*16f/9f)+1, height);
		windowWidth = Gdx.graphics.getWidth();
		windowHeight = Gdx.graphics.getHeight();
		updateMatrix();
		DeforMeshes.instance.ComputeFloats();
	}
	
	@Override
	public void pause () {
		super.pause();
	}
	
	@Override
	public void resume () {
		super.resume();
	}

	@Override
	public void dispose () 
	{
		SaveManager.SaveParam();

		if(loaded && allLoaded)
		{
			try {
				SaveManager.Save();
				Map.instance.Save();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		if(host)
		{
			NetworkManager.instance.server.server.stop();
		}
		
		super.dispose();
	}
	
	
	@Override
	public void render () {

		if(backtom)sCreate();
		
		//if(NetworkManager.instance.server == null)System.out.println("koj");
		
		delta = Gdx.graphics.getDeltaTime();
		if(ingame)
		{
			if(!pause && !SoundManager.instance.ambiance[SoundManager.instance.playOrder[SoundManager.instance.oldPlay]].isPlaying())SoundManager.instance.ambiance[SoundManager.instance.playOrder[SoundManager.instance.oldPlay]].play();
			if(pause && SoundManager.instance.ambiance[SoundManager.instance.playOrder[SoundManager.instance.oldPlay]].isPlaying())SoundManager.instance.ambiance[SoundManager.instance.playOrder[SoundManager.instance.oldPlay]].pause();
			delta *= Parameters.i.deltaMultiplier;
		}
		
		Inputs.instance.update();
		
		if(GameScreen.camera != null)Tools.computeAbsoluteMouse();
		
		if(pause && !NetworkManager.instance.online)delta = Float.MIN_VALUE;
		if(!PauseMenu.instance.clear && !pause && ingame)PauseMenu.instance.rebootMenu();
		if(delta>0.03f)delta = 0.03f;
		
		time+=delta;
		
		Shaders.instance.update();
		
		//if(devtest)menu.play = true;
		
		if(!menu.play)
		{
			if(!menu.begin)
			{
				setScreen(menu);
				if(!SoundManager.instance.menuTheme.isPlaying())SoundManager.instance.menuTheme.play();
			}
			
		}
		else
		{
			if(!loaded)
			{
				loaded = true;
				MapChecker.instance = new MapChecker();
				if(!mobile)
				{
					Map.instance = null;
					System.gc();
					if(!devtest)Map.instance = new Map("calmap2",5000,2000);
					else Map.instance = new Map("calmap2",2000,1500);
				}
				else
				{
					//MOBILE
					Map.instance = new Map("calmap",2000,1000);
				}
				MapGenerator.instance = new MapGenerator((int)(Math.random()*5000000));
				ModifyTerrain.instance = new ModifyTerrain();
				if(game != null)Main.inputMultiplexer.removeProcessor(game.chat.scene);
				game = new GameScreen();
				
				if(Map.instance.random)loading = new LoadingScreen(true);
				else loading = new LoadingScreen(false);
				setScreen(loading);
				
			}
			if(loading.mapLoaded && !allLoaded)
			{
				setScreen(game);
				ingame = true;
				if(SoundManager.instance.menuTheme.isPlaying())SoundManager.instance.menuTheme.coolStop();
				SoundManager.instance.playAmbiance();
				if(!mobile)SaveManager.instance.Load();
				allLoaded = true;
				Main.inputMultiplexer.addProcessor(game.chat.scene);
			}
		}
		
		super.render();
		Inputs.instance.updateLate();
	}
	
	public static void backToMenu(String str, Color c)
	{
		
		if(!backtom)
		{
			SaveManager.SaveParam();
			if(ingame)
			{
				if(SoundManager.instance.ambiance[SoundManager.instance.playOrder[SoundManager.instance.oldPlay]].isPlaying())SoundManager.instance.ambiance[SoundManager.instance.playOrder[SoundManager.instance.oldPlay]].pause();
				try {
					SaveManager.Save();
					Map.instance.Save();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			welcomeMessage = str;
			welcomeColor = c;
			backtom = true;
		}
		if(NetworkManager.instance.online)
		{
			NetworkManager.instance.client.close();
			NetworkManager.instance.online = false;
		} 
	}
} public class Parameters {
	public static Parameters i;
	
	public boolean fullBright = false;
	public boolean noShadow = false;
	public boolean shader = true;
	public int HQ = 5;
	public boolean RGB = true;
	public float daylight = 1.0f;
	public boolean cheatMagic = false;
	public int lightSpeed = 120;
	public int resolution = 2;
	public boolean fullscreen = false;
	public boolean superman = false;
	public boolean ultrarate = false;
	public boolean multithread = false;//TODO
	public float deltaMultiplier = 1;
	public boolean vsync = false;
	public boolean details = true;
	public boolean drawhitbox = false;
	public boolean ultrarange = false;
	public boolean godmode = false;
	public boolean rain = false;
	public boolean background = true;
	public boolean oldtransition = false;
	public int currentTransform = 0;
	public boolean goodmagic = true;
	public int lightDistance = 2;
	public boolean FBORender = false;
	public boolean zoomLock = false;
	public boolean ratio = true;
	public String name = "John";
	
	public int head = 0;
	public int body = 0;
	public int arms = 0;
	public int legs = 0;
	public int eyes = 0;
	public int hair = 0;
	
	public int volume = 10;
	public int volumeMusic = 10;
	public int volumeFX = 10;
	
	public int keyboard = HKeys.QWERTY;
	
	Parameters()
	{
		
	}
	
	public void disableCheats()
	{
		drawhitbox = false;
		deltaMultiplier = 1;
		cheatMagic = false;
		rain = false;
		godmode = false;
		ultrarange = false;
		ultrarate = false;
		noShadow = false;
		superman = false;
		fullBright = false;
		cheatMagic = false;
	}

	public void SwitchQuality()
	{
		HQ++;
		if(HQ>=Constants.qualities.length)HQ = 1;
	}
	
} public class Shaders {
	public static Shaders instance;
	//public SpriteBatch shaderBatch;
	public ShaderProgram shadow;
	public ShaderProgram shadow2;
	public ShaderProgram meshader;
	public ShaderProgram red;
	public ShaderProgram white;
	public ShaderProgram outline;
	public ShaderProgram basic;
	public int minX;
	public int maxX;
	public int minY;
	public int maxY;
	public int size;
	public int size2;
	public Vector2 offset = new Vector2();
	FrameBuffer fbo;
	Texture lightmap;
	Pixmap pixmap;
	public Shaders()
	{
		pixmap = new Pixmap(128,128,Pixmap.Format.RGB888);
		Pixmap.setBlending(Blending.None);
		ShaderProgram.pedantic = false;
		basic = new ShaderProgram(Gdx.files.internal("shaders/passthrough.vsh"),Gdx.files.internal("shaders/passthrough.fsh"));
		meshader = new ShaderProgram(Gdx.files.internal("shaders/image.vsh"),Gdx.files.internal("shaders/image.fsh"));
		shadow = new ShaderProgram(Gdx.files.internal("shaders/shadow2.vsh"),Gdx.files.internal("shaders/shadow2.fsh"));
		shadow2 = new ShaderProgram(Gdx.files.internal("shaders/shadow2.vsh"),Gdx.files.internal("shaders/shadow3.fsh"));
		red = new ShaderProgram(Gdx.files.internal("shaders/shadow2.vsh"),Gdx.files.internal("shaders/red.fsh"));
		white = new ShaderProgram(Gdx.files.internal("shaders/shadow2.vsh"),Gdx.files.internal("shaders/white.fsh"));
		outline = new ShaderProgram(Gdx.files.internal("shaders/shadow2.vsh"),Gdx.files.internal("shaders/textoutline.fsh"));
		
		
		if(!basic.isCompiled())
		{
			System.out.println(basic.getLog());
			basic = new ShaderProgram(Gdx.files.internal("shaders/passthrough.vsh"),Gdx.files.internal("shaders/passthrough2.fsh"));
		}
		if(!shadow.isCompiled())System.out.println("shadow : "+shadow.getLog());
		if(!shadow2.isCompiled())System.out.println("shadow2 : "+shadow2.getLog());
		if(!red.isCompiled())System.out.println("red : "+red.getLog());
		if(!white.isCompiled())System.out.println("white : "+white.getLog());
		if(!meshader.isCompiled())System.out.println("meshader : "+meshader.getLog());
		if(!outline.isCompiled())System.out.println("outline : "+outline.getLog());
	}
	
	public void setShadowShader()
	{
		if(Parameters.i.fullBright && Parameters.i.shader)
		{
			if(Parameters.i.HQ == 4)
				Main.batch.setShader(Shaders.instance.shadow);
			else
				Main.batch.setShader(Shaders.instance.shadow2);
		}
		else setDefaultShader();
	}
	
	public void setShadowShaderFBO()
	{
		if(Parameters.i.fullBright && Parameters.i.shader)
		{
			if(Parameters.i.HQ == 4)
				Main.batch.setShader(Shaders.instance.shadow);
			else
				Main.batch.setShader(Shaders.instance.shadow2);
		}
		else setDefaultShader();
	}
	
	public void setDefaultShader()
	{
		Main.batch.setShader(Shaders.instance.basic);
	}
	
	public void setRedShader()
	{
		Main.batch.setShader(Shaders.instance.red);
	}
	
	public void setWhiteShader()
	{
		Main.batch.setShader(Shaders.instance.white);
	}
	
	public void setOutlineShader()
	{
		Main.batch.setShader(Shaders.instance.outline);
	}
	
	public void update()
	{
		
	}
	
	public void updateOutline(float w, float h, float r, float g, float b)
	{
		outline.setUniformf("u_invScreenSize", 1f/w, 1f/h);
		outline.setUniformf("u_color", r, g, b);
		
	}
	
	public void updateShadows()
	{
		computeBounds();
		//fbo.getColorBufferTexture().bind(2000);
		ShaderProgram current = shadow;
		if(Parameters.i.HQ == 5)
		{
			current = shadow2;
		}
		current.begin();
		lightmap.bind(1);
		current.setUniformi("u_lights", 1);
		current.setUniformf("u_lightOffset", offset);
		int RGB = 0;
		if(Parameters.i.RGB)RGB = 1;
		current.setUniformi("u_RGB", RGB);
		current.setUniformf("u_lightArrayDim",size,size2);
		current.setUniformf("u_camSize", GameScreen.camera.viewportWidth,GameScreen.camera.viewportHeight);
		current.setUniformf("u_screenSize", Main.windowWidth,Main.windowHeight);
		current.end();
		Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0);
	}
	
	public void computeBounds()
	{
		minX = Tools.floor((GameScreen.camera.position.x - GameScreen.camera.zoom*GameScreen.camera.viewportWidth/2 - 32)/16);
		minY = Tools.floor((GameScreen.camera.position.y - GameScreen.camera.zoom*GameScreen.camera.viewportHeight/2 - 32)/16);
		maxX = Tools.floor((GameScreen.camera.position.x + GameScreen.camera.zoom*GameScreen.camera.viewportWidth/2 + 32)/16);
		maxY = Tools.floor((GameScreen.camera.position.y + GameScreen.camera.zoom*GameScreen.camera.viewportHeight/2 + 32)/16);
		
		if(!GameScreen.noLimit)
		{
			if(minX<0)minX = 0;
			if(maxX>Map.instance.width-1)maxX = Map.instance.width-1;
		}
		
		if(minY<1)minY = 1;
		if(maxY>Map.instance.height-2)maxY = Map.instance.height-2;
		size = (maxX-minX);
		size2 = (maxY-minY);
		
		
		if(Parameters.i.RGB)
		{
			if(pixmap == null || pixmap.getFormat() != Pixmap.Format.RGB888 || pixmap.getWidth() != size || pixmap.getHeight() != size2)
			{
				pixmap.dispose();
				pixmap = new Pixmap(size,size2,Pixmap.Format.RGB888);
			}
		}
		else
		{
			if(pixmap == null || pixmap.getFormat() != Pixmap.Format.Alpha || pixmap.getWidth() != size || pixmap.getHeight() != size2)
			{
				pixmap.dispose();
				pixmap = new Pixmap(size,size2,Pixmap.Format.Alpha);
			}
		}
		if(Parameters.i.RGB)
		{
			for(int i = 0; i<size; i++)
			{
				for(int j = 0; j<size2; j++)
				{
					Vector3 color = Map.instance.lights.getLight(i+minX,j+minY);
					//Color col = new Color();
					//Color.rgba8888ToColor(col, pixmap.getPixel(i, j));
					//if(color.x != col.r && color.y != col.g && color.z != col.b)
					pixmap.drawPixel(i,j,Color.rgba8888(color.x/4,color.z/4,color.y/4,1));
				}
			}
		}
		else
		{
			for(int i = 0; i<size; i++)
			{
				for(int j = 0; j<size2; j++)
				{
					float color = Map.instance.lights.getLight(i+minX,j+minY,0);
					//Color col = new Color();
					//Color.rgba8888ToColor(col, pixmap.getPixel(i, j));
					//if(color != col.a)
					pixmap.drawPixel(i,j,Color.alpha(color/4));
				}
			}
		}
				/*float c = Map.instance.lights.getLight(i+minX,j+minY);
				float r = Map.instance.lights.getLight(i+minX+1,j+minY);
				float l = Map.instance.lights.getLight(i+minX-1,j+minY);
				float u = Map.instance.lights.getLight(i+minX,j+minY+1);
				float d = Map.instance.lights.getLight(i+minX,j+minY-1);
				pixmap.drawPixel(i*2,j*2,Color.rgba8888(1,1,1,(c*2+l+d)/4));
				pixmap.drawPixel(i*2+1,j*2,Color.rgba8888(1,1,1,(c*2+r+d)/4));
				pixmap.drawPixel(i*2,j*2+1,Color.rgba8888(1,1,1,(c*2+l+u)/4));
				pixmap.drawPixel(i*2+1,j*2+1,Color.rgba8888(1,1,1,(c*2+r+u)/4));*/
		
		
		offset = Tools.getScreenPos(minX*16, minY*16);
		if(lightmap != null)lightmap.dispose();
		lightmap = new Texture(pixmap);	
		/*fbo.begin();
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		shaderBatch.begin();
		shaderBatch.draw(new Texture(pixmap),0,0,1024,1024);
		shaderBatch.end();
		fbo.end();*/
	}
} public class TextureManager {
	
	public static TextureManager instance;
	
	public int PNJNumber = 3;
	public int PNJArmorNumber = 20;

	int sX = 3;
	int sY = 2;
	
	int bX = 9;
	int bY = 6;
	
	public ArrayList<TextureRegion> packedTextures = new ArrayList<TextureRegion>();
	
	PixmapPacker packer = new PixmapPacker(2048,2048,Pixmap.Format.RGBA8888,2,true);
	
	TextureAtlas atlas;
	
	public TextureRegion[][] TextureRegions = new TextureRegion[AllBlocTypes.instance.TileSetNumber][bX*bY];
	public Coordinates[] CoordinatesBlocs = new Coordinates[AllBlocTypes.instance.TileSetNumber];
	public TextureRegion[] ParticleBlocs = new TextureRegion[AllBlocTypes.instance.TileSetNumber];
	
	public TextureRegion empty;
	public TextureRegion rain;
	public TextureRegion[] rains = new TextureRegion[4];
	
	public TextureRegion item;
	public TextureRegion tool;
	public TextureRegion badwolf;
	public TextureRegion hornet;
	public TextureRegion dinorouge;
	public TextureRegion biginsecte;
	public TextureRegion[] veswings = new TextureRegion[2];
	public TextureRegion[] vesbody = new TextureRegion[4];
	
	public TextureRegion[] wolf = new TextureRegion[10];
	public TextureRegion[] hor = new TextureRegion[2];
	
	public TextureRegion bonhommeWeapon;
	public TextureRegion greenSceptre;
	public TextureRegion redSceptre;
	public TextureRegion purpleSceptre;
	public TextureRegion blueSceptre;
	public TextureRegion blackSceptre;
	public TextureRegion woodStick;
	public TextureRegion woodStickAndStone;
	
	public TextureRegion Ttroncs;
	public TextureRegion TbranchesD;
	public TextureRegion TbranchesG;
	public TextureRegion Tcimes;
	public TextureRegion backText;
	public TextureRegion selectDefault;
	public TextureRegion backTrashTexture;
	public TextureRegion invButtonTexture;
	public TextureRegion craftNew;
	public TextureRegion craftButton;
	public TextureRegion backLBText;
	public TextureRegion LBText;
	public TextureRegion redLBText;
	public TextureRegion greenLBText;
	public Texture loadingJ;
	public TextureRegion loadingV;
	public TextureRegion loadingShadow;
	public Texture cad1;
	public Texture cad2;
	public Texture cad3;
	public Texture cad4;
	public Texture cad5;
	public Texture cad6;
	public Texture cad7;
	public Texture cad8;
	public Texture backGround;
	public Texture backGroundChar;
	public Texture roue1;
	public Texture roue2;
	public Texture back;
	public Texture backn;
	public Texture layer1;
	public Texture layer2;
	public Texture layer3;
	public Texture layer4;
	public Texture layer5;
	
	public TextureRegion particle;
	public TextureRegion armTextureOld;
	public TextureRegion selecbacktext;
	public TextureRegion torchText;
	public TextureRegion cadre;
	
	public TextureRegion portalTexture;
	public TextureRegion forgeTexture;
	public TextureRegion armorForgeTexture;
	public TextureRegion fleuristeTexture;
	
	public TextureRegion doorForgeTexture;
	public TextureRegion doorArmorForgeTexture;
	public TextureRegion doorFleuristeTexture;
	
	public TextureRegion chatBehind;
	public TextureRegion playButton;
	public TextureRegion hostButton;
	public TextureRegion joinButton;
	public TextureRegion settingsButton;
	public TextureRegion charEditButton;
	public TextureRegion ipButton;
	public TextureRegion textBoxSurline;
	public TextureRegion textBoxCursor;
	
	public TextureRegion sGraphicsButton;
	public TextureRegion sAudioButton;
	public TextureRegion sKeyboardButton;
	public TextureRegion sDisplayButton;
	public TextureRegion sButtonHolder;
	
	public TextureRegion casque1;
	public TextureRegion armor1;
	public TextureRegion arms1;
	public TextureRegion leggins1;
	public TextureRegion[] legginsArray1;
	
	public TextureRegion[] PNJeye = new TextureRegion[PNJNumber];
	public TextureRegion[] PNJhairs = new TextureRegion[PNJNumber];
	public TextureRegion[] PNJhead = new TextureRegion[PNJNumber];
	public TextureRegion[] PNJlegList = new TextureRegion[PNJNumber];
	public TextureRegion[] PNJbody = new TextureRegion[PNJNumber];
	public TextureRegion[][] PNJlegs = new TextureRegion[PNJNumber][];
	public TextureRegion[][] PNJeyes = new TextureRegion[PNJNumber][];
	
	public TextureRegion[] PNJarmTexture = new TextureRegion[PNJNumber];
	
	
	
	public Texture PNJAtlas;
	
	public TextureRegion[] PNJHelmet = new TextureRegion[PNJArmorNumber];
	public TextureRegion[] PNJArmor = new TextureRegion[PNJArmorNumber];
	public TextureRegion[] PNJGlove = new TextureRegion[PNJArmorNumber];
	public TextureRegion[] PNJLegginsList = new TextureRegion[PNJArmorNumber];
	public TextureRegion[][] PNJLeggins = new TextureRegion[PNJArmorNumber][];
	
	
	
	public TextureRegion miningHelmet;
	public TextureRegion bow;
	public TextureRegion grapple;
	public TextureRegion grappleGreen;
	public TextureRegion arrow;
	public TextureRegion vespic;
	public ArrayList<TextureRegion> swords = new ArrayList<TextureRegion>();
	public TextureRegion bigsword;
	
	public TextureRegion joy;
	
	public TextureRegion blank;
	
	public Texture materials;

	Coordinates DirtCoordinates = new Coordinates(270,0);	
	Coordinates UnbreakCoordinates = new Coordinates(30,0);	
	Coordinates CobbleCoordinates = new Coordinates(0,100);	
	Coordinates GrassCoordinates = new Coordinates(60,0);
	Coordinates IronCoordinates = new Coordinates(90,0);
	Coordinates GoldCoordinates = new Coordinates(120,0);
	Coordinates MachaliumCoordinates = new Coordinates(150,0);
	Coordinates DragoniumCoordinates = new Coordinates(180,0);
	Coordinates CarbaiumCoordinates = new Coordinates(210,0);
	Coordinates EltaliumCoordinates = new Coordinates(240,0);
	Coordinates WoodCoordinates = new Coordinates(180,100);
	Coordinates StoneBricksCoordinates = new Coordinates(90,100);
	Coordinates GlassCoordinates = new Coordinates(90,160);
	Coordinates IronBlockCoordinates = new Coordinates(0,160);
	Coordinates IceCoordinates = new Coordinates(360,100);
	Coordinates LogCoordinates = new Coordinates(270,100);
	Coordinates FossileCoordinates = new Coordinates(420,0);
	Coordinates CrystalPurpleCoordinates = new Coordinates(360,160);
	Coordinates CrystalGreenCoordinates = new Coordinates(270,160);
	Coordinates CrystalRedCoordinates = new Coordinates(180,160);
	Coordinates CrystalBlueCoordinates = new Coordinates(90,220);
	Coordinates CrystalDarkCoordinates = new Coordinates(0,220);
	Coordinates TorchCoordinates = new Coordinates(90,20);
	Coordinates CrystalFireCoordinates1 = new Coordinates(120,20);
	Coordinates CrystalFireCoordinates2 = new Coordinates(150,20);
	Coordinates CrystalFireCoordinates3 = new Coordinates(180,20);
	Coordinates CrystalFireCoordinates4 = new Coordinates(150,20);
	Coordinates TorchCoordinates2 = new Coordinates(210,20);
	Coordinates TorchCoordinates3= new Coordinates(240,20);
	Coordinates TorchCoordinates4 = new Coordinates(270,20);
	Coordinates TorchCoordinates5 = new Coordinates(300,20);
	Coordinates MudCoordinates = new Coordinates(300,0);
	
	TextureRegion occlusion;
	TextureRegion occlusionl;
	TextureRegion occlusionr;
	TextureRegion occlusionu;
	TextureRegion occlusiond;
	TextureRegion occlusionlr;
	TextureRegion occlusionlu;
	TextureRegion occlusionld;
	TextureRegion occlusionru;
	TextureRegion occlusionrd;
	TextureRegion occlusionud;
	TextureRegion occlusionlru;
	TextureRegion occlusionlrd;
	TextureRegion occlusionlud;
	TextureRegion occlusionrud;
	TextureRegion occlusionlrud;
	
	TextureRegion[] grass =  new TextureRegion[4];
	TextureRegion[] dirtBorder =  new TextureRegion[4];
	TextureRegion[] dirtBorderHor =  new TextureRegion[4];
	
	TextureRegion pause;
	TextureRegion pauseexit;
	TextureRegion pauseresume;
	TextureRegion pausesettings;
	TextureRegion pauseback;
	TextureRegion pauseArrowL;
	TextureRegion pauseArrowR;
	TextureRegion pausecheat;
	TextureRegion pauseButton;
	
	TextureRegion chest;
	TextureRegion bed;
	TextureRegion chair;
	TextureRegion anvil;
	
	Texture rope;
	Texture ropeGreen;
	
	public TextureRegion newTexture(FileHandle file)
	{
		TextureRegion r = new TextureRegion(new Texture(file));
		packedTextures.add(r);
		return r;
	}
	public TextureRegion newTexture(String file)
	{
		TextureRegion r = new TextureRegion(new Texture(Gdx.files.internal(file)));
		packedTextures.add(r);
		return r;
	}
	
	public TextureManager() 
	{
		
		Pixmap pm = new Pixmap(Gdx.files.internal("others/mouse.png"));
		Gdx.graphics.setCursor(Gdx.graphics.newCursor(pm, 0, 0));
		pm.dispose();
		
		//TEXTURES
		rope = new Texture("weapons/Hooks/rope2.png");
		rope.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
		
		ropeGreen = new Texture("weapons/Hooks/rope.png");
		ropeGreen.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
		
		materials = new Texture("materials/materials.png");
		
		PNJAtlas = new Texture("players/PNJAtlas.png");
		
		empty = newTexture(Gdx.files.internal("others/empty.png"));

		item = newTexture(Gdx.files.internal("icones/items.png"));
		tool = newTexture(Gdx.files.internal("icones/tools.png"));
		
		badwolf = newTexture("mobs/loupmechant.png");
		hornet = newTexture("mobs/insectehor.png");
		dinorouge = newTexture("mobs/dinorouge.png");
		biginsecte = newTexture("mobs/biginsecte.png");
		
		bonhommeWeapon = newTexture("weapons/PickAxes/pickaxe1.png");
		greenSceptre = newTexture("weapons/Magic/sceptreGreen.png");
		redSceptre = newTexture("weapons/Magic/sceptreRed.png");
		purpleSceptre = newTexture("weapons/Magic/sceptrePurple.png");
		blueSceptre = newTexture("weapons/Magic/sceptreBlue.png");
		blackSceptre = newTexture("weapons/Magic/sceptreDark.png");
		bow = newTexture("weapons/Bows/bow.png");
		grapple = newTexture("weapons/Hooks/grapple2.png");
		grappleGreen = newTexture("weapons/Hooks/grapple.png");
		
		bigsword = newTexture("weapons/Swords/greatsword.png");
		arrow = newTexture("weapons/Ammos/arrow.png");
		vespic = newTexture("weapons/Ammos/vespic.png");
		woodStick = newTexture("weapons/Swords/woodstick.png");
		woodStickAndStone = newTexture("weapons/Swords/woodstickandrock.png");
		
		Ttroncs = newTexture("trees/troncs.png");
		TbranchesD = newTexture("trees/branchesgauches.png");
		TbranchesG = newTexture("trees/branchesdroites.png");
		Tcimes = newTexture("trees/cimes.png");
		
		backText = newTexture(Gdx.files.internal("inventory/pancarte-grande.png"));
		selectDefault = newTexture(Gdx.files.internal("inventory/sele.png"));
		backTrashTexture = newTexture(Gdx.files.internal("inventory/TrashPanel.png"));
		invButtonTexture = newTexture(Gdx.files.internal("inventory/OpenInvPanell.png"));
		pauseButton = newTexture(Gdx.files.internal("menu/pausebutton.png"));
		craftNew = newTexture("inventory/craftnew.png");
		craftButton = newTexture("inventory/craftbutton.png");
		
		backLBText = newTexture(Gdx.files.internal("inventory/behindLifePanel.png"));
		LBText = newTexture(Gdx.files.internal("inventory/LifePanel.png"));
		redLBText = newTexture(Gdx.files.internal("inventory/redLifePanel.png"));
		greenLBText = newTexture(Gdx.files.internal("inventory/greenLifePanel.png"));
		
		loadingV = newTexture("loading/loadingvide.png");
		loadingShadow = newTexture("loading/ombreloading.png");
		
		loadingJ = new Texture("loading/loadingjauge.png");
		cad1 = new Texture("loading/cad1.png");
		cad2 = new Texture("loading/cad2.png");
		cad3 = new Texture("loading/cad3.png");
		cad4 = new Texture("loading/cad4.png");
		cad5 = new Texture("loading/cad5.png");
		cad6 = new Texture("loading/cad6.png");
		cad7 = new Texture("loading/cad7.png");
		backGround = new Texture("loading/bgloading.png");
		backGroundChar = new Texture("loading/charloading.png");
		roue1 = new Texture("loading/roue1.png");
		roue2 = new Texture("loading/roue2.png");
		
		backn = new Texture("background/backNight.png");
		back = new Texture("background/back.png");
		layer1 = new Texture("background/1.png");
		layer2 = new Texture("background/layer2.png");
		layer3 = new Texture("background/layer3.png");
		layer4 = new Texture("background/layer4.png");
		layer5 = new Texture("background/layer5.png");
		
		
		
		armTextureOld = newTexture(Gdx.files.internal("players/arm1old.png"));
		
		rain = newTexture(Gdx.files.internal("others/raindrop.png"));
		
		particle = newTexture(Gdx.files.internal("particles/particle1.png"));
		
		selecbacktext = newTexture("inventory/woodSelector.png");
		torchText = newTexture(Gdx.files.internal("inventory/torch.png"));
		cadre = newTexture(Gdx.files.internal("others/cadre.png"));
		
		portalTexture = newTexture(Gdx.files.internal("decors/portail.png"));
		doorForgeTexture = newTexture(Gdx.files.internal("decors/doorArmes.png"));
		doorArmorForgeTexture = newTexture(Gdx.files.internal("decors/doorArmure.png"));
		doorFleuristeTexture = newTexture(Gdx.files.internal("decors/doorFleuriste.png"));
		
		forgeTexture = newTexture(Gdx.files.internal("decors/forge-armes.png"));
		armorForgeTexture = newTexture(Gdx.files.internal("decors/forge-armures.png"));
		fleuristeTexture = newTexture(Gdx.files.internal("decors/fleuriste.png"));
		
		sGraphicsButton = newTexture(Gdx.files.internal("menu/sGraphicsButton.png"));
		sAudioButton = newTexture(Gdx.files.internal("menu/sAudioButton.png"));
		sKeyboardButton = newTexture(Gdx.files.internal("menu/sKeyboardButton.png"));
		sDisplayButton = newTexture(Gdx.files.internal("menu/sDisplayButton.png"));
		sButtonHolder = newTexture(Gdx.files.internal("menu/sButtonHolder.png"));
		
		chatBehind = newTexture(Gdx.files.internal("menu/chatbehind.png"));
		playButton = newTexture(Gdx.files.internal("menu/playButton.png"));
		hostButton = newTexture(Gdx.files.internal("menu/hostButton.png"));
		joinButton = newTexture(Gdx.files.internal("menu/joinButton.png"));
		settingsButton = newTexture(Gdx.files.internal("menu/settingsButton.png"));
		charEditButton = newTexture(Gdx.files.internal("menu/charEditButton.png"));
		ipButton = newTexture(Gdx.files.internal("menu/ipButton.png"));
		textBoxSurline = newTexture(Gdx.files.internal("menu/textBoxSurline.png"));
		textBoxCursor = newTexture(Gdx.files.internal("menu/textBoxCursor.png"));
		casque1 = newTexture(Gdx.files.internal("armors/casque1.png"));
		miningHelmet = newTexture(Gdx.files.internal("armors/casquelight.png"));
		armor1 = newTexture(Gdx.files.internal("armors/armor1.png"));
		arms1 = newTexture(Gdx.files.internal("armors/arms1.png"));
		leggins1 = newTexture(Gdx.files.internal("armors/leggins1.png"));
		
		for(int i = 0; i<PNJNumber; i++)
		{
			PNJeye[i] = new TextureRegion(PNJAtlas,468,i*26,52,26);
			PNJhead[i] = new TextureRegion(PNJAtlas,416,i*26,26,26);
			PNJhairs[i] = new TextureRegion(PNJAtlas,442,i*26,26,26);
			PNJlegList[i] = new TextureRegion(PNJAtlas,520,i*26,312,26);
			PNJbody[i] = new TextureRegion(PNJAtlas,390,i*26,26,26);
			PNJarmTexture[i] = new TextureRegion(PNJAtlas,832,i*26,26,26);
		}
		
		for(int i = 0; i<PNJArmorNumber; i++)
		{
			PNJArmor[i] = new TextureRegion(PNJAtlas,0,i*26,26,26);
			PNJHelmet[i] = new TextureRegion(PNJAtlas,26,i*26,26,26);
			PNJLegginsList[i] = new TextureRegion(PNJAtlas,2*26,i*26,312,26);
			PNJGlove[i] = new TextureRegion(PNJAtlas,14*26,i*26,26,26);
		}
		
		joy = newTexture(Gdx.files.internal("menu/joystick.png"));
		blank = newTexture(Gdx.files.internal("others/blank.png"));
		
		pause = newTexture(Gdx.files.internal("menu/pause.png"));
		
		chest = newTexture(Gdx.files.internal("furnitures/chest.png"));
		bed = newTexture(Gdx.files.internal("furnitures/bed.png"));
		chair = newTexture(Gdx.files.internal("furnitures/chaise1.png"));
		anvil = newTexture(Gdx.files.internal("furnitures/anvil.png"));
		
		swords.add(newTexture("weapons/Swords/sword.png"));
		swords.add(newTexture("weapons/Swords/sword1.png"));
		swords.add(newTexture("weapons/Swords/sword2.png"));
		swords.add(newTexture("weapons/Swords/sword3.png"));
		swords.add(newTexture("weapons/Swords/sword4.png"));
		swords.add(newTexture("weapons/Swords/sword5.png"));
		swords.add(newTexture("weapons/Swords/sword6.png"));
		swords.add(newTexture("weapons/Swords/sword7.png"));
		swords.add(newTexture("weapons/Swords/sword8.png"));
		swords.add(newTexture("weapons/Swords/sword9.png"));
		//TODO
		
		
		
		//PACKING
		for(int i = 0; i<packedTextures.size(); i++)
		{
			packedTextures.get(i).getTexture().getTextureData().prepare();
			packer.pack(String.valueOf(i), packedTextures.get(i).getTexture().getTextureData().consumePixmap());
			packedTextures.get(i).getTexture().getTextureData().disposePixmap();
			packedTextures.get(i).getTexture().dispose();
		}
		
		atlas = packer.generateTextureAtlas(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest, false);
		
		/*PixmapPackerIO pl = new PixmapPackerIO();
		try {
			pl.save(Gdx.files.local("truc.pack"), packer);
		} catch (IOException e) {
			e.printStackTrace();
		}*/
		
		packer.dispose();
		
		for(int i = packedTextures.size()-1; i>=0; i--)
		{
			TextureRegion reg = atlas.findRegion(String.valueOf(i));
			reg.setRegion(reg.getRegionX()+packedTextures.get(i).getRegionX(), reg.getRegionY()+packedTextures.get(i).getRegionY(), packedTextures.get(i).getRegionWidth(), packedTextures.get(i).getRegionHeight());
			packedTextures.get(i).setRegion(reg);
		}
		
		for(int i = 0; i<PNJNumber; i++)
		{
			PNJlegs[i] = PNJlegList[i].split(PNJlegList[i].getRegionWidth()/12, PNJlegList[i].getRegionHeight())[0];
			PNJeyes[i] = PNJeye[i].split(PNJeye[i].getRegionWidth()/2, PNJeye[i].getRegionHeight())[0];
		}
		
		for(int i = 0; i<PNJArmorNumber; i++)
		{
			PNJLeggins[i] = PNJLegginsList[i].split(PNJLegginsList[i].getRegionWidth()/12, PNJLegginsList[i].getRegionHeight())[0];
		}
		
		
		wolf[0] = new TextureRegion(badwolf, 0, 0, 41, 22);
		wolf[1] = new TextureRegion(badwolf, 41, 0, 41, 22);
		wolf[2] = new TextureRegion(badwolf, 164/2, 0, 41, 22);
		wolf[3] = new TextureRegion(badwolf, 246/2, 0, 41, 22);
		wolf[4] = new TextureRegion(badwolf, 328/2, 0, 41, 22);
		wolf[5] = new TextureRegion(badwolf, 410/2, 0, 41, 22);
		wolf[6] = new TextureRegion(badwolf, 492/2, 0, 41, 22);
		wolf[7] = new TextureRegion(badwolf, 574/2, 0, 41, 22);
		wolf[8] = new TextureRegion(badwolf, 656/2, 0, 41, 22);
		wolf[9] = new TextureRegion(badwolf, 738/2, 0, 41, 22);
		
		hor[0] = new TextureRegion(hornet, 0, 0, 32, 17);
		hor[1] = new TextureRegion(hornet, 32, 0, 32, 17);
		
		veswings[0] = new TextureRegion(biginsecte, 0, 0, 100, 96);
		veswings[1] = new TextureRegion(biginsecte, 102, 0, 100, 96);
		
		vesbody[0] = new TextureRegion(biginsecte, 204, 0, 100, 96);
		vesbody[1] = new TextureRegion(biginsecte, 0, 96, 100, 96);
		vesbody[2] = new TextureRegion(biginsecte, 102, 96, 100, 96);
		vesbody[3] = new TextureRegion(biginsecte, 204, 96, 100, 96);
		
		rains[0] = new TextureRegion(rain,0,0,16,16);
		rains[1] = new TextureRegion(rain,16,0,16,16);
		rains[2] = new TextureRegion(rain,32,0,16,16);
		rains[3] = new TextureRegion(rain,48,0,16,16);
		
		legginsArray1 = leggins1.split(leggins1.getRegionWidth()/12, leggins1.getRegionHeight())[0];
		
		
		pauseresume = new TextureRegion(pause,0,0,122,44);
		pauseexit = new TextureRegion(pause,0,46,122,44);
		pausesettings = new TextureRegion(pause,0,92,122,44);
		pauseArrowL = new TextureRegion(pause,0,138,22,22);
		pauseArrowR = new TextureRegion(pause,22,138,22,22);
		pauseback = new TextureRegion(pause,0,162,122,44);
		pausecheat = new TextureRegion(pause,0,208,122,44);
		
		CoordinatesBlocs[1] = DirtCoordinates;
		CoordinatesBlocs[2] = UnbreakCoordinates;
		CoordinatesBlocs[3] = CobbleCoordinates;
		CoordinatesBlocs[4] = GrassCoordinates;
		CoordinatesBlocs[5] = IronCoordinates;
		CoordinatesBlocs[6] = GoldCoordinates;
		CoordinatesBlocs[7] = MachaliumCoordinates;
		CoordinatesBlocs[8] = DragoniumCoordinates;
		CoordinatesBlocs[9] = CarbaiumCoordinates;
		CoordinatesBlocs[10] = EltaliumCoordinates;
		CoordinatesBlocs[11] = WoodCoordinates;
		CoordinatesBlocs[12] = StoneBricksCoordinates;
		CoordinatesBlocs[13] = GlassCoordinates;
		CoordinatesBlocs[14] = IronBlockCoordinates;
		CoordinatesBlocs[15] = IceCoordinates;
		CoordinatesBlocs[16] = LogCoordinates;
		CoordinatesBlocs[17] = FossileCoordinates;
		CoordinatesBlocs[18] = CrystalPurpleCoordinates;
		CoordinatesBlocs[19] = CrystalGreenCoordinates;
		CoordinatesBlocs[20] = CrystalRedCoordinates;
		CoordinatesBlocs[21] = CrystalBlueCoordinates;
		CoordinatesBlocs[22] = CrystalDarkCoordinates;
		CoordinatesBlocs[23] = TorchCoordinates;
		CoordinatesBlocs[24] = CrystalFireCoordinates1;
		CoordinatesBlocs[25] = CrystalFireCoordinates2;
		CoordinatesBlocs[26] = CrystalFireCoordinates3;
		CoordinatesBlocs[27] = CrystalFireCoordinates4;
		CoordinatesBlocs[28] = TorchCoordinates2;
		CoordinatesBlocs[29] = TorchCoordinates3;
		CoordinatesBlocs[30] = TorchCoordinates4;
		CoordinatesBlocs[31] = TorchCoordinates5;
		CoordinatesBlocs[32] = MudCoordinates;
		
		for(int i = 0; i<ParticleBlocs.length; i++)
		{
			if(CoordinatesBlocs[i]!=null)ParticleBlocs[i] = new TextureRegion(materials, CoordinatesBlocs[i].x+2, CoordinatesBlocs[i].y+2, 4, 4);
		}
		
		TextureRegion[][][] tempAll = new TextureRegion[AllBlocTypes.instance.TileSetNumber][sY][sX];
		TextureRegion[][][] tempAllOld = new TextureRegion[AllBlocTypes.instance.TileSetNumber][bY][bX];
		
		
		occlusion = new TextureRegion(materials,4,4,8,8);
		occlusionl = new TextureRegion(materials,0,4,12,8);
		occlusionr = new TextureRegion(materials,4,4,12,8);
		occlusionu = new TextureRegion(materials,4,0,8,12);
		occlusiond = new TextureRegion(materials,4,4,8,12);
		occlusionlr = new TextureRegion(materials,0,4,16,8);
		occlusionlu = new TextureRegion(materials,0,0,12,12);
		occlusionld = new TextureRegion(materials,0,4,12,12);
		occlusionru = new TextureRegion(materials,4,0,12,12);
		occlusionrd = new TextureRegion(materials,4,4,12,12);
		occlusionud = new TextureRegion(materials,4,0,8,16);
		occlusionlru = new TextureRegion(materials,0,0,16,12);
		occlusionlrd = new TextureRegion(materials,0,4,16,12);
		occlusionlud = new TextureRegion(materials,0,0,12,16);
		occlusionrud = new TextureRegion(materials,4,0,12,16);
		occlusionlrud = new TextureRegion(materials,0,0,16,16);

		grass[0] = new TextureRegion(materials,0,19,8,16);
		grass[1] = new TextureRegion(materials,8,19,8,16);
		grass[2] = new TextureRegion(materials,16,19,8,16);
		grass[3] = new TextureRegion(materials,24,19,8,16);
		
		dirtBorder[0] = new TextureRegion(materials,1,40,2,8);
		dirtBorderHor[0] = new TextureRegion(materials,5,40,8,2);
		dirtBorder[1] = new TextureRegion(materials,15,40,2,8);
		dirtBorderHor[1] = new TextureRegion(materials,19,40,8,2);
		
		
		
		for(int i = 1; i<CoordinatesBlocs.length; i++)
		{
			TextureRegion tempTex;
			if(CoordinatesBlocs[i].y>=100)tempTex = new TextureRegion(materials, CoordinatesBlocs[i].x, CoordinatesBlocs[i].y, 90, 60);
			else tempTex = new TextureRegion(materials, CoordinatesBlocs[i].x, CoordinatesBlocs[i].y, 30, 20);
			
			
			if(tempTex.getRegionWidth()<32)tempAll[i] = tempTex.split(tempTex.getRegionWidth()/sX, tempTex.getRegionHeight()/sY);
			else tempAllOld[i] = tempTex.split(tempTex.getRegionWidth()/bX, tempTex.getRegionHeight()/bY);
		}
		
		for(int i = 1; i<tempAll.length; i++)
		{
			if(tempAll[i][0][0] != null)
			{
				for(int j = 0; j<tempAll[i].length; j++)
				{
					for(int h = 0; h<tempAll[i][j].length; h++)
					{
						tempAll[i][j][h].setRegion(tempAll[i][j][h].getRegionX(), tempAll[i][j][h].getRegionY(), 8, 8);
						TextureRegions[i][j*sX+h] = tempAll[i][j][h];
					}
				}
			}
			else
			{
				for(int j = 0; j<tempAllOld[i].length; j++)
				{
					for(int h = 0; h<tempAllOld[i][j].length; h++)
					{
						tempAllOld[i][j][h].setRegion(tempAllOld[i][j][h].getRegionX(), tempAllOld[i][j][h].getRegionY(), 8, 8);
						TextureRegions[i][j*bX+h] = tempAllOld[i][j][h];
					}
				}
			}
		}
	}
} public class ToolType {
public boolean isUseLess;
public int id;
public float efficiency;
public float damage;
public boolean isShake;
public boolean obstacleProof;
public boolean canCutTrees;
public boolean canAttack;
public int weaponTexture;
public boolean stackable;
public int type = 1;
public float launcherDistance;
public float launcherAngle;
public String name;
public String description;
public int sceptreType;
public float rate;
public boolean armor;
public boolean helmet;
public boolean arms;
public boolean legs;

public boolean helmetHair;

public int armorId = -1;
public int helmetId = -1;
public int armsId = -1;
public int legsId = -1;

public float armorDefense = 0;
public float armorSpeed = 0;
public float armorJump = 0;
public float armorPower = 0;

public boolean equipment;
public float angle;
public int arrowType = 0;
public float uptime = 30;
public float downtime = 30;
public int furnitureType = 0;
public int furnitureWidth = 1;
public int furnitureHeight = 1;
public boolean turnable = false;
public boolean magicprojectile;
public boolean magiclight;
public float range;
public int torchangle = 40;
ColorString rarity;
TextureRegion tex;
public boolean grapple;
public float grappleDistance;
public TextureRegion grappleTex;
public Texture grappleTexRope;
public boolean invisible;
public boolean furnitureContainer = false;
public boolean helmetLight = false;

	public ToolType() 
	{
		invisible = false;
		grappleDistance = 1500;
		grappleTex = TextureManager.instance.grapple;
		grappleTexRope = TextureManager.instance.rope;
		grapple = false;
		magiclight = false;
		rarity = Constants.rarity1;
		magicprojectile = false;
		equipment = false;
		armorDefense = 0;
		armorSpeed = 0;
		armorJump = 0;
		angle = 0;
		armor = false;
		canCutTrees = false;
		canAttack = false;
		obstacleProof = false;
		stackable = true;
		rate = 0.1f;
		sceptreType = 0;
		launcherDistance = 63;
		launcherAngle = -18;
		name = "No name";
		description ="No description available";
		efficiency = 0;
		damage = 0;
		weaponTexture = 0;
		isShake = true;
		isUseLess = false;
		range = ModifyTerrain.range;
	}

} public class Tools {
	
	public static Vector3 color = new Vector3();
	
	public static Vector2 raycastvec = new Vector2();
	public static Vector2 raycastvec2 = new Vector2();
	
	public static Vector2 abpos = new Vector2();
	public static Vector3 worldCoord = new Vector3();
	
	public static Vector2 absMouse = new Vector2();

	public static final int LAST_BYTE = 0x000000FF;
	
	static boolean isDifferentEnough(float a, float b, float c, float d, float e)
	{
		if(Math.abs(a-b)>0.02f)return true;
		if(Math.abs(a-c)>0.02f)return true;
		if(Math.abs(a-d)>0.02f)return true;
		if(Math.abs(a-e)>0.02f)return true;
		return false;
	}
	
	static boolean isFull(BlocType b, int x)
	{
		if(b.artificial)return true;
		if(b.oldTexture)return (x >= AllBlocTypes.instance.oldFull && x < AllBlocTypes.instance.oldFull+3);
		else return (x%10 == AllBlocTypes.instance.full);
	}
	
	public static final <T> void swap (T[] a, int i, int j) 
	{	
		  T t = a[i];
		  a[i] = a[j];
		  a[j] = t;
	}
	
	public static int getIndex(int i, int max)
	{
		if(i<0)i=max+i;
		else if(i>=max)i=i-max;
		return i;
	}
	
	public static final <T> void swap (T[][] a, int i, int j, int k) 
	{
		  
		  T t = a[i][k];
		  a[i][k] = a[j][k];
		  a[j][k] = t;
	}
	
	public static void drawLine(Color col, float w, float x, float y, float x2, float y2)
	{
		Vector2 vec = new Vector2(x2-x,y2-y);
		Color col2 = Main.batch.getColor();
		
		Main.batch.setColor(col);
		Main.batch.draw(TextureManager.instance.blank, x-w/2, y, w/2, 0, w, vec.len(), 1, 1, vec.angle()-90);
		Main.batch.setColor(col2);
	}
	
	public static void drawLine(Texture tex,float x, float y, float x2, float y2,int bonus)
	{
		Vector2 vec = new Vector2(x2-x,y2-y);
		
		 Sprite sprite = new Sprite(tex, 0, 0, tex.getWidth(), (int) vec.len()+bonus);
		 sprite.setColor(Main.batch.getColor());
	     sprite.setOrigin(tex.getWidth()/2, 0);
	     sprite.setPosition(x-tex.getWidth()/2, y);
	     sprite.setRotation( vec.angle()-90);
	     sprite.draw(Main.batch);
		
		//Main.batch.draw(tex, x-w/2, y, w/2, 0, w, vec.len(), 1, 1, vec.angle()-90, 0, 0, tex.getWidth(), (int) vec.len(), false, false);
	}
	
	public static void drawLine(Texture tex,float x, float y, float x2, float y2)
	{
		drawLine(tex,x,y,x2,y2,0);
	}
	
	public static String enabldis(boolean b)
	{
		if(!b) return "Disabling ";
		else return "Enabling ";
	}
	
	public static boolean isIPAdress(String str)
	{
		String[] numbers = str.split("[.]");
		
		if(numbers.length!=4)return false;
		
		for(int i = 0; i<numbers.length; i++)
		{
			try
			{
				int b=Integer.parseInt(numbers[i]);
				if(b>256 ||b<0)return false;
			}
			catch(java.lang.NumberFormatException e)
			{
				return false;
			}
		}
		
		return true;
	}
	
	public static void computeAbsoluteMouse()
	{
		absMouse.set(getAbsolutePos(Gdx.input.getX(),Gdx.input.getY()));	
	}
	
	public static float angleCrop(float angle) 
	{
	    while(angle<0)angle+=360;
	    while(angle>360)angle-=360;

	    return angle;
	}
	
	public static Vector2 getAbsoluteMouse()
	{
		return absMouse;	
	}
	
	public static Vector2 getAbsolutePos(float x, float y)
	{
		worldCoord.x = x;
		worldCoord.y = y;
		worldCoord.z = 0;
		GameScreen.camera.unproject(worldCoord);
		abpos.x = worldCoord.x;
		abpos.y = worldCoord.y;
		return abpos;
	}
	
	public static Vector2 getScreenPos(float x, float y)
	{
		Vector3 worldCoord = new Vector3(x,y, 0);	
		GameScreen.camera.project(worldCoord);
		return new Vector2(worldCoord.x, worldCoord.y);
	}
	
	public static Vector2 getAbsoluteMouseUI(float x, float y)
	{
		GameScreen.SwapUI();
		Vector3 worldCoord = new Vector3(x,y, 0);	
		GameScreen.camera.unproject(worldCoord);
		GameScreen.SwapCam();
		return new Vector2(worldCoord.x, worldCoord.y);
	}
	
	public static boolean isClicked(Sprite spr, float degre)
	{
		Vector2 coord = getAbsoluteMouse();
		if((coord.x > spr.getX()-degre && coord.x < spr.getX()+spr.getScaleX()*spr.getWidth()+degre) && (coord.y > spr.getY()-degre && coord.y < spr.getY()+spr.getHeight()*spr.getScaleY()+degre))return true;
		else return false;
	}
	
	public static Vector2 raycast(float x, float y, float xf, float yf, float step)
	{
		boolean end = false;
		raycastvec.x = xf-x;
		raycastvec.y = yf-y;
		
		raycastvec2.x = raycastvec.x;
		raycastvec2.y = raycastvec.y;
		
		for(float i = step; !end; i+=step)
		{
			if(i>=raycastvec.len())
			{
				i = raycastvec.len();
				end = true;
			}
			raycastvec2.clamp(i, i);
			if(Map.instance.mainLayer.getBloc((int)((raycastvec2.x+x)/16), (int)((raycastvec2.y+y)/16)).collide)
			{
				raycastvec.x = (int)((raycastvec2.x+x)/16);
				raycastvec.y = (int)((raycastvec2.y+y)/16);
				return raycastvec;
			}
		}
		raycastvec.x = -1;
		raycastvec.y = -1;
		return raycastvec;
	}
	
	public static Vector2 raycastVec(float x, float y, float xf, float yf, float step)
	{

		
		boolean end = false;
		raycastvec.x = xf;
		raycastvec.y = yf;
		
		raycastvec2.x = raycastvec.x;
		raycastvec2.y = raycastvec.y;
		
		for(float i = step; !end; i+=step)
		{
			if(i>=raycastvec.len())
			{
				i = raycastvec.len();
				end = true;
			}
			raycastvec2.clamp(i, i);
			if(Map.instance.mainLayer.getBloc((int)((raycastvec2.x+x)/16), (int)((raycastvec2.y+y)/16)).collide)
			{
				raycastvec.x = (int)((raycastvec2.x+x)/16);
				raycastvec.y = (int)((raycastvec2.y+y)/16);
				
				//drawLine(Color.WHITE, 3, x, y, raycastvec.x*16+8, raycastvec.y*16+8);
				
				return raycastvec;
			}
		}
		raycastvec.x = -1;
		raycastvec.y = -1;
		
		return raycastvec;
	}
	
	public static Vector2 raycastAngle(float x, float y, float l, float angle, float step)
	{
		raycastvec.x = l;
		raycastvec.y = 0;
		
		raycastvec.setAngle(angle);
		
		return raycast(x,y,x+raycastvec.x,y+raycastvec.y,step);
	}
	
	public static int floor(float f)
	{
		if(f>=0)return (int)f;
		else return (int)f-1;
	}
	
	public static int getMapBounded(int x)
	{
		if(x<0)x = Map.instance.width+x;
		else if(x>Map.instance.width-1)x = 0+(x-(Map.instance.width));
		return x;
	}
	
	public static int getBounded(int x, int mmm)
	{
		if(x<0)x = mmm+x;
		else if(x>mmm-1)x = 0+(x-mmm);
		return x;
	}
	
	public static void checkItems()
	{
		GameScreen.inventory.refreshItemsinv();
		if(GameScreen.inventory.chestopen)
		{
			Furniture chest = GameScreen.inventory.chest;
			for(int i = 0; i<chest.itemsids.length; i++)
			{
				int xs = (int)(i/6);
				int ys = i%6+7;
				chest.itemsids[i] = GameScreen.inventory.invItemsArray[xs][ys].id;
				chest.itemsnumbers[i] = GameScreen.inventory.invItemsArray[xs][ys].number;
			}
		}
		GameScreen.select.refreshSelector();
		GameScreen.player.refreshSelect();
	}
	
	public static Vector3 Lerp(Vector3 vecFrom, Vector3 vecTo)
	{
		if(vecFrom.x-vecTo.x>1000 || vecFrom.x-vecTo.x<-1000 || vecFrom.y-vecTo.y>1000 || vecFrom.y-vecTo.y<-1000)
			return vecTo;
		float speedfactorx = GameScreen.player.PNJ.baseSpeedx/    Math.max(GameScreen.player.PNJ.baseSpeedx, Math.abs(GameScreen.player.PNJ.vx));
		float speedfactory = GameScreen.player.PNJ.baseSpeedy/ Math.max(GameScreen.player.PNJ.baseSpeedy, Math.abs(GameScreen.player.PNJ.vy));
		return new Vector3(vecFrom.x+((vecTo.x-vecFrom.x)/((speedfactorx)*7+2))*Main.delta*60,vecFrom.y+((vecTo.y-vecFrom.y)/((speedfactory)*7+2))*Main.delta*60,0);
	}
	
	public static void drawRect(float x, float y, float w, float h)
	{
		Main.batch.draw(TextureManager.instance.blank, x, y, w, h);
	}
	
	public static Vector3 getShadowColor(int x, int y)
	{
		
		if(!Parameters.i.fullBright)
		{
			if(Parameters.i.RGB)color = Map.instance.lights.getLight(x,y);
			else
			{
				float lum = Map.instance.lights.getLight(x,y,0);
				color.x = lum; color.y = lum; color.z = lum;
			}
			color.x = Math.min(color.x, 1);
			color.y = Math.min(color.y, 1);
			color.z = Math.min(color.z, 1);
		}
		else
		{
			color.x = 1;
			color.y = 1;
			color.z = 1;
		}
		
		return color;
	}
	
	public static String booltoyes(boolean b)
	{
		if(b)return "Yes";
		else return "No";
	}
	
	public static float fLerpAngle(float x, float y, float speed)
	{
		if(y-x>180)y-=360;
		if(x-y>180)x-=360;
		float t = (y-x)*speed*Main.delta;
		if(t<-40*speed*Main.delta)t=-40*speed*Main.delta;
		if(t>40*speed*Main.delta)t=40*speed*Main.delta;
		float result = x+t;
		while(result>360)result-=360;
		while(result<0)result+=360;
		return result;
	}
	
	public static float fLerpAngle(float x, float y, float speed, boolean sens)
	{
		while(sens && y<x)
		{
			y+=360;
		}
		while(!sens && y>x)
		{
			y-=360;
		}
		
		if(Math.abs(x-y)<0.3f)return y;
		
		float result;
		
		float t = (y-x)*speed*Main.delta;
		if(t<-40*speed*Main.delta)
		{
			t=-40*speed*Main.delta;
		}
		else if(t>40*speed*Main.delta)
		{
			t=40*speed*Main.delta;
		}

		result = x+t;
		
		while(result>360)result-=360;
		while(result<0)result+=360;
		return result;
	}
	
	 static void shuffleArray(int[] ar)
	  {
	    Random rnd = new Random();
	    for (int i = ar.length - 1; i > 0; i--)
	    {
	      int index = rnd.nextInt(i + 1);
	      int a = ar[index];
	      ar[index] = ar[i];
	      ar[i] = a;
	    }
	  }
	
}
import java.util.ArrayList;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.hexabeast.sandbox.AllEntities;
import com.hexabeast.sandbox.Entity;
import com.hexabeast.sandbox.GameScreen;
import com.hexabeast.sandbox.HitBox;
import com.hexabeast.sandbox.HitRect;
import com.hexabeast.sandbox.Main;
import com.hexabeast.sandbox.Parameters;
import com.hexabeast.sandbox.Shaders;
import com.hexabeast.sandbox.TextureManager;
import com.hexabeast.sandbox.ToolType;
import com.hexabeast.sandbox.Tools;
			attacked = true;
			
			GameScreen.emmiter.addnewText((int)d, x, y);
		}
	}
	
	public void checkRect(Rectangle rec)
	{
		for(int i = Tools.floor((x+rec.x)/16); i<=Tools.floor((x+rec.x+rec.width)/16); i++)
		{
			for(int j = Tools.floor((y+rec.y)/16); j<=Tools.floor((y+rec.y+rec.height)/16); j++)
			{
				AllEntities.setMap(i,j,this);
			}
		}
	}
	
	public boolean turnTest()
	{
		hitbox.isTurned = !isTurned;
		if(hitbox.TestCollisions(true) || (hitbox.TestCollisions(false)))
		{
			hitbox.isTurned = isTurned;
			return false;
		}
		return true;
	}
	
	public void move()
	{
		float oldX= x;
		float oldY = y;
		
		y+=vy*Main.delta;

		hitbox.update(x,y);
		
		canJump = false;
		if(hitbox.TestCollisions(true) || (hitbox.TestCollisions(false) && vy<=0))
		{
			y = oldY;
			vy = 0;
		}		
		if(hitbox.TestCollisionsDown() || hitbox.TestCollisions(false))
		{
			canJump = true;
		}
		
		hitbox.update(x,y);
		
		boolean hiking = false;
		if(hitbox.TestCollisions(false))hiking = true;
		
		x+=vx*Main.delta;
		hitbox.update(x,y);
		
		if(hitbox.TestCollisions(true) || (hitbox.TestCollisionsHigh() && !hiking && hitbox.TestCollisions(false)))
		{
			x = oldX;
			vx = 0;
		}
		else if(hitbox.TestCollisions(false))
		{
			oldY = y;
			y+=Math.abs(speedx)*2.4f*Main.delta;
			hitbox.update(x,y);	
			if(hitbox.TestCollisions(true))
			{
				y = oldY;
				y+=speedx*0.2f*Main.delta;
				hitbox.update(x,y);	
				if(hitbox.TestCollisions(true))
				{
					y = oldY;
				}
			}
			
		}
		hitbox.update(x,y);
	}
	
	public void visual(){}
	
	public void premove(){}
	public void preinput(){}
	
	public void graphicDraw(SpriteBatch batch)
	{
		for(int i = 0; i<tex.size(); i++)
		{
			if(!isTurned)batch.draw(tex.get(i), x, y, width, height);
			else batch.draw(tex.get(i), x+width+offx, y, -width, height);
		}
	}
	
	public void update()
	{
		if(!manual)IA();
		visual();
		
		hitbox.isTurned = isTurned;
		
		premove();
		move();
		
		if(damaged && Main.time>lastdamaged+damagerate)
		{
			damaged = false;
		}
		
		if(attacked && Main.time>lastred+redrate)attacked = false;
	}
	
	@Override
	public void draw(SpriteBatch batch)
	{
		
		Vector3 color = Tools.getShadowColor(Tools.floor(x/16)+Tools.floor(casesX/2),Tools.floor(y/16)+Tools.floor(casesY/2));
		if(attacked)
		{
			Shaders.instance.setRedShader();