Beispiel #1
0
GameOver::GameOver(Game * _game, float _score) :
	MY_Scene_Base(_game),
	done(false)
{
	std::string pic = "ENDING_";

	if(_score > 300){
		pic += "5";
	}else if(_score > 200){
		pic += "4";
	}else if(_score > 125){
		pic += "3";
	}else if(_score > 50){
		pic += "2";
	}else{
		pic += "1";
	}


	{
	VerticalLinearLayout * vl = new VerticalLinearLayout(uiLayer->world);
	uiLayer->addChild(vl);
	vl->setRationalHeight(1.f, uiLayer);
	vl->setRationalWidth(1.f, uiLayer);
	vl->horizontalAlignment = kCENTER;
	vl->verticalAlignment = kMIDDLE;
	NodeUI * menu = new NodeUI(uiLayer->world);
	vl->addChild(menu);
	menu->setRationalHeight(1.f, vl);
	menu->setSquareWidth(1.f);
	menu->background->mesh->pushTexture2D(MY_ResourceManager::globalAssets->getTexture(pic)->texture);
	menu->background->mesh->setScaleMode(GL_NEAREST);
	}

	Timeout * doneTimeout = new Timeout(0.5f, [this](sweet::Event * _event){
		done = true;
		NodeUI * n = new NodeUI(uiLayer->world);
		n->setRationalHeight(1.f, uiLayer);
		n->setRationalWidth(1.f, uiLayer);
		uiLayer->addChild(n);
		n->background->mesh->pushTexture2D(MY_ResourceManager::globalAssets->getTexture("CLICK")->texture);
		n->background->mesh->setScaleMode(GL_NEAREST);
	});
	doneTimeout->start();
	doneTimeout->name = "done timeout";
	childTransform->addChild(doneTimeout, false);
}
Beispiel #2
0
MY_Scene::MY_Scene(Game * _game) :
	Scene(_game),
	screenSurfaceShader(new Shader("assets/RenderSurface", false, true)),
	screenSurface(new RenderSurface(screenSurfaceShader)),
	screenFBO(new StandardFrameBuffer(true)),
	baseShader(new ComponentShaderBase(true)),
	textShader(new ComponentShaderText(true)),
	uiLayer(0,0,0,0),
	bounds(10),
	bulletWorld(new BulletWorld()),
	score(0),
	accuracy(3.f)
{
	baseShader->addComponent(new ShaderComponentMVP(baseShader));
	//baseShader->addComponent(new ShaderComponentDiffuse(baseShader));
	baseShader->addComponent(new ShaderComponentTexture(baseShader));
	baseShader->compileShader();

	textShader->textComponent->setColor(glm::vec3(0.0f, 64.f/255.f, 165.f/255.f));
	
	screenSurface->setScaleMode(GL_NEAREST);

	// remove initial camera
	childTransform->removeChild(cameras.at(0)->parents.at(0));
	delete cameras.at(0)->parents.at(0);
	cameras.pop_back();
	

	// reference counting for member variables
	++baseShader->referenceCount;
	++textShader->referenceCount;

	++screenSurface->referenceCount;
	++screenSurfaceShader->referenceCount;
	++screenFBO->referenceCount;

	float floorL = 1000, floorW = 1000;

	// create floor/ceiling as static bullet planes
	bulletFloor = new BulletMeshEntity(bulletWorld, MeshFactory::getPlaneMesh(), baseShader);
	bulletFloor->setColliderAsStaticPlane(0, 1, 0, 0);
	bulletFloor->createRigidBody(0);
	bulletFloor->body->setFriction(0);
	childTransform->addChild(bulletFloor);
	bulletFloor->meshTransform->scale(-floorL, floorW, 1.f);
	bulletFloor->meshTransform->rotate(-90, 1, 0, 0, kOBJECT);
	bulletFloor->body->getWorldTransform().setRotation(btQuaternion(btVector3(0, 1, 0), glm::radians(180.f)));
	//bulletFloor->mesh->setScaleMode(GL_NEAREST);
	bulletFloor->mesh->scaleModeMag = GL_NEAREST;
	bulletFloor->mesh->scaleModeMin = GL_LINEAR;
	bulletFloor->mesh->pushTexture2D(MY_ResourceManager::scenario->getTexture("CLOUDS")->texture);
	// adjust UVs so that the texture tiles in squares
	for(Vertex & v : bulletFloor->mesh->vertices){
		v.u *= 30.f;
		v.v *= 30.f;
	}



	// car
	TriMesh * shipMesh = MY_ResourceManager::scenario->getMesh("SHIP")->meshes.at(0);
	ship = new BulletMeshEntity(bulletWorld, shipMesh, baseShader);
	childTransform->addChild(ship);
	ship->mesh->setScaleMode(GL_NEAREST);
	ship->mesh->pushTexture2D(MY_ResourceManager::scenario->getTexture("SHIP")->texture);

	ship->setColliderAsBoundingBox();
	ship->createRigidBody(10);
	
	ship->body->setLinearFactor(btVector3(1, 1, 0));
	ship->body->setAngularFactor(btVector3(0, 0, 0));

	ship->maxVelocity = btVector3(10, 10, 0);

	ship->body->setActivationState(4); // always active
	ship->translatePhysical(glm::vec3(0, 10, 0));
	
	//Set up player camera
	zoom = 3.f;
	playerCam = new PerspectiveCamera();
	cameras.push_back(playerCam);
	ship->meshTransform->addChild(playerCam);
	playerCam->nearClip = 0.01f;
	playerCam->farClip = 1000.f;
	playerCam->childTransform->rotate(90, 0, 1, 0, kWORLD);
	playerCam->firstParent()->translate(0, 1.5f, zoom, false);
	playerCam->yaw = 90.0f;
	playerCam->pitch = -10.0f;
	activeCamera = playerCam;

	shipAngle = 0;

	MeshInterface * sphereMesh = MY_ResourceManager::scenario->getMesh("SPHERE")->meshes.at(0);
	sphereMesh->setScaleMode(GL_NEAREST);
	sphereMesh->pushTexture2D(MY_ResourceManager::scenario->getTexture("TRAIL")->texture);

	MeshInterface * ringMesh = MY_ResourceManager::scenario->getMesh("RING")->meshes.at(0);
	ringMesh->setScaleMode(GL_NEAREST);
	ringMesh->pushTexture2D(MY_ResourceManager::scenario->getTexture("RING")->texture);

	trailTimeout = new Timeout(0.05f, [this, sphereMesh](sweet::Event * _event){
		// add player trail
		BulletMeshEntity * t = new BulletMeshEntity(bulletWorld, sphereMesh, baseShader);
		t->setColliderAsBoundingSphere();
		t->createRigidBody(1, 0, 0);
		childTransform->addChild(t);
		trail.push_back(t);
		t->translatePhysical(ship->meshTransform->getWorldPos(), false);
		t->childTransform->scale(sweet::NumberUtils::randomFloat(1,3));
		t->meshTransform->rotate(sweet::NumberUtils::randomFloat(0, 360), 0, 0, 1, kOBJECT);
		t->body->applyCentralImpulse(btVector3(sweet::NumberUtils::randomFloat(-3,3), sweet::NumberUtils::randomFloat(-3,3), sweet::NumberUtils::randomFloat(-3,3) + 10));
		trailTimeout->restart();
	});
	trailTimeout->start();
	//childTransform->addChild(trailTimeout);

	
	obstacleTimeout = new Timeout(0.5f, [this, ringMesh](sweet::Event * _event){
		// add player trail
		BulletMeshEntity * t = new BulletMeshEntity(bulletWorld, ringMesh, baseShader);
		t->setColliderAsBoundingSphere();
		t->createRigidBody(0, 0, 0);
		childTransform->addChild(t);
		obstacles.push_back(t);
		t->translatePhysical(glm::vec3(sweet::NumberUtils::randomFloat(-bounds,bounds)*0.5, sweet::NumberUtils::randomFloat(bounds*0.2,bounds*0.8), -300), false);
		t->meshTransform->rotate(sweet::NumberUtils::randomFloat(0, 360), 0, 0, 1, kOBJECT);
		t->body->setActivationState(4); // always active
		obstacleTimeout->restart();
	});
	obstacleTimeout->start();
	//childTransform->addChild(obstacleTimeout);

	VerticalLinearLayout * vl = new VerticalLinearLayout(uiLayer.world);
	vl->setRationalHeight(1.0f);
	vl->setRationalWidth(1.f);
	vl->setMarginTop(0.1f);
	vl->setRenderMode(kTEXTURE);
	vl->verticalAlignment = kTOP;


	scoreIndicator = new TextLabel(uiLayer.world, MY_ResourceManager::scenario->getFont("FONT")->font, textShader, 1.f);
	scoreIndicator->horizontalAlignment = kCENTER;
	scoreIndicator->setText("SCORE: 0");
	scoreIndicator->invalidateLayout();

	vl->addChild(scoreIndicator);
	uiLayer.addChild(vl);



	MY_ResourceManager::scenario->getAudio("BGM")->sound->play(true);
}
MY_Scene_Menu::MY_Scene_Menu(Game * _game) :
	MY_Scene_Base(_game)
{
	// Create a linear layout to contain all of our menu items
	// remember that these elements are all going to exist in the uiLayer, so we pass in its physics world in the constructors
	VerticalLinearLayout * layout = new VerticalLinearLayout(uiLayer->world);
	layout->horizontalAlignment = kCENTER;
	layout->verticalAlignment = kMIDDLE;
	// set the layout's size to 100% of its parent
	layout->setRationalHeight(1.f, uiLayer);
	layout->setRationalWidth(1.f, uiLayer);

	// Create some text labels
	TextLabel * label6 = new TextLabel(uiLayer->world, font, textShader);
	TextLabel * label7 = new TextLabel(uiLayer->world, font, textShader);
	TextLabel * label8 = new TextLabel(uiLayer->world, font, textShader);

	// set the text on the labels
	label6->setText("Quit Game");
	label7->setText("Play Game");
	label8->setText("Path Thing");

	// make the labels' background visible (by default both the scene's clear colour and the text colour will be black)
	label6->setBackgroundColour(1,1,1,1);
	label7->setBackgroundColour(1,1,1,1);
	label8->setBackgroundColour(1,1,1,1);

	// make the labels clickable
	label6->setMouseEnabled(true);
	label7->setMouseEnabled(true);
	label8->setMouseEnabled(true);

	// add listeners to each label, making them buttons that take the player to different scenes
	label6->eventManager->addEventListener("click", [&](sweet::Event * _event){
		game->exit();
	});
	label7->eventManager->addEventListener("click", [&](sweet::Event * _event){
		if(game->scenes.count("main") == 0){
			game->scenes["main"] = new MY_Scene_Main(game);
		}
		game->switchScene("main", false);
	});
	label8->eventManager->addEventListener("click", [&](sweet::Event * _event){
		if(game->scenes.count("path") == 0){
			game->scenes["path"] = new MY_Scene_Path(game);
		}
		game->switchScene("path", false);
	});


	// add the labels to the layout
	layout->addChild(label6);
	layout->addChild(label7);
	layout->addChild(label8);

	// add the layout to the uiLayer
	uiLayer->addChild(layout);

	uiLayer->invalidateLayout();

	// add a mouse indicator (AKA a cursor) to the uiLayer so that the user can see what they're doing
	uiLayer->addMouseIndicator();
}
MY_Scene_Main::MY_Scene_Main(Game * _game) :
	MY_Scene_Base(_game),
	bulletWorld(new BulletWorld(glm::vec3(0, -9.8, 0.1))),
	bulletDebugDrawer(new BulletDebugDrawer(bulletWorld->world)),
	indicatorShader(new ComponentShaderBase(true)),
	maskComponentIndicator(nullptr),
	mirrorShader(new ComponentShaderBase(true)),
	vrCam(new StereoCamera()),


	currentTrack(nullptr),
	currentTrackId(-1),

	screenSurfaceShader(new Shader("assets/engine basics/DefaultRenderSurface", false, true)),
	screenSurface(new RenderSurface(screenSurfaceShader, true)),
	screenFBO(new StandardFrameBuffer(true)),
	
	paletteDefIdx(-1),
	
	waitingForInput(false),
	currentHoverTarget(nullptr),
	hoverTime(0),
	targetHoverTime(1.f),

	eventManager(new sweet::EventManager()),
	done(false)
{

	indicatorShader->addComponent(new ShaderComponentMVP(indicatorShader));	
	indicatorShader->addComponent(new ShaderComponentTexture(indicatorShader, 0.1f));
	maskComponentIndicator = new ShaderComponentCircularMask(indicatorShader, 0.1);
	indicatorShader->addComponent(maskComponentIndicator);
	indicatorShader->compileShader();
	indicatorShader->incrementReferenceCount();

	mirrorShader->addComponent(new ShaderComponentMVP(mirrorShader));
	mirrorShader->addComponent(new ShaderComponentTexture(mirrorShader, 0.1f));
	mirrorShader->addComponent(mirrorBlur = new ShaderComponentBlur(mirrorShader));
	mirrorShader->compileShader();
	mirrorShader->incrementReferenceCount();

	// Setup the debug drawer and add it to the scene
	bulletWorld->world->setDebugDrawer(bulletDebugDrawer);
	childTransform->addChild(bulletDebugDrawer, false);
	bulletDebugDrawer->setDebugMode(btIDebugDraw::DBG_NoDebug);


	MeshInterface * chairMesh = MY_ResourceManager::globalAssets->getMesh("chair")->meshes.at(0);
	chairMesh->pushTexture2D(MY_ResourceManager::globalAssets->getTexture("chair")->texture);
	chairMesh->setScaleMode(GL_NEAREST);

	for(signed long int i = -1; i <= 1; ++i){
		MeshEntity * chair = new MeshEntity(chairMesh, baseShader);
		childTransform->addChild(chair)->translate(glm::vec3(i * 3, 0, 0));
	}
	
	
	std::vector<TriMesh *> environmentMeshes = MY_ResourceManager::globalAssets->getMesh("salon-environment")->meshes;
	std::vector<TriMesh *> propMeshes = MY_ResourceManager::globalAssets->getMesh("salon-props")->meshes;
	std::vector<std::string> environmentMeshOrder;
	environmentMeshOrder.push_back("floor");
	environmentMeshOrder.push_back("walls");
	environmentMeshOrder.push_back("ceiling");
	environmentMeshOrder.push_back("storefront");
	environmentMeshOrder.push_back("door");
	environmentMeshOrder.push_back("windows");
	environmentMeshOrder.push_back("road");
	environmentMeshOrder.push_back("buildings");
	environmentMeshOrder.push_back("sidewalk");

	std::vector<glm::vec3> propMeshOrder;
	propMeshOrder.push_back(glm::vec3(1, 0.96, 0));
	propMeshOrder.push_back(glm::vec3(0.8, 0.45, 0.45));
	propMeshOrder.push_back(glm::vec3(0.5, 0.05, 0.2));
	propMeshOrder.push_back(glm::vec3(1,1,1));
	propMeshOrder.push_back(glm::vec3(0.02, 0.6, 0));
	propMeshOrder.push_back(glm::vec3(0.4, 0.9, 0.9));
	
	for(unsigned long int i = 0; i < environmentMeshes.size(); ++i){
		MeshEntity * c = new MeshEntity(environmentMeshes.at(i), baseShader);
		c->mesh->pushTexture2D(MY_ResourceManager::globalAssets->getTexture("salon-" + environmentMeshOrder.at(i))->texture);
		c->mesh->setScaleMode(GL_NEAREST);
		childTransform->addChild(c, false);
	}
	for(unsigned long int i = 0; i < propMeshes.size(); ++i){
		MeshEntity * c = new MeshEntity(propMeshes.at(i), baseShader);
		for(auto & v : c->mesh->vertices){
			v.red = propMeshOrder.at(i).r;
			v.green = propMeshOrder.at(i).g;
			v.blue = propMeshOrder.at(i).b;
		}
		c->mesh->setScaleMode(GL_NEAREST);
		childTransform->addChild(c, false);
	}


	activeCamera = vrCam;
	cameras.push_back(vrCam);
	vrCam->yaw = -90;
	vrCam->nearClip = 0.001f;
	vrCam->fieldOfView = 110;

	avatar = new MY_Avatar(baseShader, vrCam);
	childTransform->addChild(avatar);
	avatar->head->childTransform->addChild(vrCam)->translate(0, 0.5f, 0);

	/*MeshEntity * test = new MeshEntity(Resource::loadMeshFromObj("assets/meshes/buttman.obj", true).at(0), baseShader);
	Texture * tex = new Texture("assets/textures/buttman.png", false, true, true);
	tex->load();
	test->mesh->pushTexture2D(tex);
	childTransform->addChild(test)->translate(0, 3, 2)->rotate(90, 0, 1, 0, kOBJECT);*/
	

	
	/*MY_SelectionTarget * palette = new MY_SelectionTarget(bulletWorld, MY_ResourceManager::globalAssets->getMesh("palette")->meshes.at(0), baseShader);
	palette->mesh->pushTexture2D(MY_ResourceManager::globalAssets->getTexture("palette")->texture);
	childTransform->addChild(palette);
	palette->setColliderAsBoundingBox();
	//palette->setColliderAsSphere(5);
	palette->createRigidBody(0);
	palette->translatePhysical(glm::vec3(0, 3, 2));
	palette->name = "test";*/
	//palette->rotatePhysical(90, 0, 1, 0, kOBJECT);
	
	CameraController * c = new CameraController(vrCam);
	c->movementSpeed = 0.05f;
	vrCam->childTransform->addChild(c, false);

	std::vector<glm::vec2> points;
	std::string json = sweet::FileUtils::readFile("assets/path.json");
	Json::Reader reader;
	Json::Value path;
	bool parsingSuccessful = reader.parse( json, path);
	if(!parsingSuccessful){
		Log::error("JSON parse failed: " + reader.getFormattedErrorMessages());
	}else{		
		glm::vec2 ratio = glm::vec2(ROOM_WIDTH/path["windowSize"][0].asFloat(), ROOM_DEPTH/path["windowSize"][1].asFloat());
		for(auto point : path["points"]) {
			// Reverse co-ordinates because player is facing down z axis
			float x = /*ratio.y * */point[0].asFloat();
			float z = /*ratio.x * */point[1].asFloat() / glm::length(ratio);
			points.push_back(glm::vec2(x, z));	
		}
	}

	// setup the artist
	artist = new MY_MakeupArtist(baseShader, points);
	childTransform->addChild(artist);//->scale(0.9);

	palette = new MY_Palette(bulletWorld, baseShader);
	childTransform->addChild(palette);
	palette->translateComponents(glm::vec3(0, 3, 2));

	

	// parse palettes
	{
		Json::Reader reader;
		Json::Value json;
		bool parsingSuccessful;
	
		parsingSuccessful = reader.parse(sweet::FileUtils::readFile("assets/palettes.json"), json);

		assert(parsingSuccessful);

		for(Json::Value::ArrayIndex i = 0; i < json["palettes"].size(); ++i){
			paletteDefs.push_back(new MY_Palette_Definition(json["palettes"][i].get("name", "NO_NAME").asString(), MY_ResourceManager::globalAssets->getTexture(json["palettes"][i].get("texture", "DEFAULT").asString())->texture));
		}
	}

	Sprite * sprite = new Sprite(MY_ResourceManager::globalAssets->getTexture("indicator")->texture, indicatorShader);

	auto sd = sweet::getWindowDimensions();
	uiLayer->resize(0, sd.x, 0, sd.y);

	VerticalLinearLayout * crosshairLayout = new VerticalLinearLayout(uiLayer->world);
	crosshairLayout->setRationalWidth(1.0f, uiLayer);
	crosshairLayout->setRationalHeight(1.0f, uiLayer);
	crosshairLayout->horizontalAlignment = kCENTER;
	crosshairLayout->verticalAlignment = kMIDDLE;

	NodeUI * crossHair = new NodeUI(uiLayer->world);
	crossHair->setWidth(15);
	crossHair->setHeight(15);
	crossHair->background->mesh->pushTexture2D(MY_ResourceManager::globalAssets->getTexture("crosshair")->texture);
	crossHair->background->mesh->setScaleMode(GL_NEAREST);

	crosshairLayout->addChild(crossHair);

	crossHair->childTransform->addChild(sprite)->scale(100)->translate(7.5f, 7.5f, 0.f);

	uiLayer->addChild(crosshairLayout);

	
	// setup mirror
	mirrorCamera = new PerspectiveCamera();
	childTransform->addChild(mirrorCamera);
	cameras.push_back(mirrorCamera);
	mirrorCamera->firstParent()->translate(-0.5f, 3.25f, 4, false);

	mirrorFBO = new StandardFrameBuffer(true);
	mirrorTex = new FBOTexture(mirrorFBO, true, 0, false);
	mirrorTex->load();
	mirrorSurface = new MeshEntity(MY_ResourceManager::globalAssets->getMesh("salon-mirror")->meshes.at(0), mirrorShader);
	mirrorSurface->mesh->setScaleMode(GL_LINEAR);
	mirrorSurface->mesh->uvEdgeMode = GL_CLAMP_TO_EDGE;
	mirrorSurface->mesh->pushTexture2D(mirrorTex);
	childTransform->addChild(mirrorSurface);
	mirrorFBO->incrementReferenceCount();


	// memory management
	screenSurface->incrementReferenceCount();
	screenSurfaceShader->incrementReferenceCount();
	screenFBO->incrementReferenceCount();



	// load the tracks
	tracks = new Tracks();

	// start the experience
	getNextTrack();
	loadNextPalette();



	fade = new NodeUI(uiLayer->world);
	uiLayer->addChild(fade);
	fade->setRationalHeight(1.f, uiLayer);
	fade->setRationalWidth(1.f, uiLayer);
	fade->setBackgroundColour(0,0,0,1);

	Timeout * fadeIn = new Timeout(1.f, [this](sweet::Event * _event){
		fade->setVisible(false);
	});
	fadeIn->eventManager->addEventListener("progress", [this](sweet::Event * _event){
		float p = _event->getFloatData("progress");
		fade->setBackgroundColour(0,0,0,1.f-p);
	});
	fadeIn->start();
	childTransform->addChild(fadeIn, false);


	// recenter HMD
	ovr_RecenterPose(*sweet::hmd);

	startTime = glfwGetTime();
}
PD_UI_Dialogue::PD_UI_Dialogue(BulletWorld * _world, PD_UI_Bubble * _uiBubble) :
	NodeUI(_world),
	uiBubble(_uiBubble),
	textBubble(new NodeUI_NineSliced(world, dynamic_cast<Texture_NineSliced *>(PD_ResourceManager::scenario->getTexture("NPC-BUBBLE")->texture))),
	text(new TextArea(world, PD_ResourceManager::scenario->getFont("FONT")->font, uiBubble->textShader)),
	currentSpeaker(nullptr),
	speechTimeout(nullptr),
	hadNextDialogue(false)
{
	text->setWrapMode(kWORD);
	setRenderMode(kTEXTURE);
	VerticalLinearLayout * vl = new VerticalLinearLayout(world);
	vl->setRationalWidth(1.f, this);
	vl->setRationalHeight(1.f, this);

	vl->horizontalAlignment = kCENTER;
	vl->verticalAlignment = kTOP;

	VerticalLinearLayout * vl2 = new VerticalLinearLayout(world);

	vl2->horizontalAlignment = kCENTER;
	vl2->verticalAlignment = kMIDDLE;

	addChild(vl);
	vl->addChild(textBubble);
	textBubble->setMargin(15,15,0,15);
	textBubble->setBorder(PD_ResourceManager::scenario->getFont("FONT")->font->getLineHeight());
	textBubble->setRationalWidth(0.9f, vl);
	textBubble->setRationalHeight(0.25f, vl);
	textBubble->addChild(vl2);
	vl2->setRationalWidth(1.f, textBubble);
	vl2->setRationalHeight(1.f, textBubble);
	vl2->addChild(text);
	vl2->setPadding(0.03f, 0.f);
	text->setRationalWidth(1.f, vl2);
	text->verticalAlignment = kMIDDLE;
	background->setVisible(false);

	// disable and hide by default
	setVisible(false);

	speechTimeout = new Timeout(0.15, [this](sweet::Event * _event){
		if(speechBuffer.size() > 0) {
			std::wstring word = speechBuffer.front();
			char fc = tolower(word.at(word.size()/2));
			speechBuffer.pop();
			if(currentSpeaker != nullptr){
				auto sound = currentSpeaker->voice;
				if(sweet::CharacterUtils::isLetter(fc) || sweet::CharacterUtils::isDigit(fc)){
					sound->setPitch((fc-100.f)/100.f+1.0f);
					sound->play();
				}
			}
			speechTimeout->restart();
		}else {
			if(currentSpeaker != nullptr) {
				currentSpeaker->pr->talking = false;
			}
		}
	});
}
PD_UI_Task::PD_UI_Task(BulletWorld * _world, Font * _font, ComponentShaderText * _textShader):
	NodeUI(_world)
{
	setRenderMode(kTEXTURE);
	background->setVisible(false);
	setAlpha(0.f);

	NodeUI * container = new NodeUI(_world);
	addChild(container);
	container->setRationalWidth(1.f, this);
	container->setRationalHeight(1.f, this);
	container->background->setVisible(false);

	VerticalLinearLayout * checkContainer = checkBox = new VerticalLinearLayout(world);
	container->addChild(checkContainer);
	checkContainer->horizontalAlignment = kCENTER;
	checkContainer->verticalAlignment = kMIDDLE;
	checkContainer->setWidth(PD_ResourceManager::scenario->getFont("FONT")->font->getLineHeight());
	checkContainer->setRationalHeight(1.f, container);
	checkContainer->background->setVisible(false);

	checkBox = new VerticalLinearLayout(world);
	checkBox->horizontalAlignment = kCENTER;
	checkBox->verticalAlignment = kMIDDLE;
	checkContainer->addChild(checkBox);
	checkBox->setRationalWidth(0.75f, checkContainer);
	checkBox->setSquareHeight(1.f);
	checkBox->background->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("JOURNAL-CHECK-BOX")->texture);
	checkBox->background->mesh->setScaleMode(GL_NEAREST);
	checkBox->setBackgroundColour(1.f, 1.f, 1.f, 1.f);
	checkBox->background->setVisible(true);

	checkMark = new NodeUI(world);
	checkBox->addChild(checkMark);
	checkMark->setRationalWidth(0.f, checkBox);
	checkMark->setSquareHeight(1.f);
	checkMark->background->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("JOURNAL-CHECK-MARK")->texture);
	checkMark->background->mesh->setScaleMode(GL_NEAREST);
	checkMark->setVisible(false);

	text = new TextArea(world, _font, _textShader);
	text->setWrapMode(kWORD);
	text->verticalAlignment = kMIDDLE;
	container->addChild(text);
	text->setRationalWidth(1.f, container);
	text->setRationalHeight(1.f, container);
	text->marginLeft.setRationalSize(1.f, &checkContainer->width);
	text->background->setVisible(false);

	addTimeout = new Timeout(1.f, [this](sweet::Event * _event){
		setAlpha(1.f);
	});
	addTimeout->eventManager->addEventListener("start", [this](sweet::Event * _event){
		setAlpha(0.f);
	});

	addTimeout->eventManager->addEventListener("progress", [this](sweet::Event * _event){
		float p = _event->getFloatData("progress");
		setAlpha(p);
	});
	childTransform->addChild(addTimeout, false);

	checkTimeout = new Timeout(0.5f, [this](sweet::Event * _event){
		checkMark->setRationalWidth(1.f, checkMark->nodeUIParent);
		invalidateLayout();
		invalidateRenderFrame();
	});
	checkTimeout->eventManager->addEventListener("start", [this](sweet::Event * _event){
		checkMark->setVisible(true);
		invalidateLayout();
		invalidateRenderFrame();
	});
	checkTimeout->eventManager->addEventListener("progress", [this](sweet::Event * _event){
		float p = _event->getFloatData("progress");
		p = Easing::easeOutElastic(p, 0.f, 1.f, checkTimeout->targetSeconds, -1, 4.f);
		checkMark->setRationalWidth(p, checkMark->nodeUIParent);
		invalidateLayout();
		invalidateRenderFrame();
	});
	childTransform->addChild(checkTimeout, false);
}
PD_UI_Tasklist::PD_UI_Tasklist(BulletWorld * _world) :
	NodeUI(_world),
	textShader(new ComponentShaderText(true)),
	crossedTextShader(new ComponentShaderText(true)),
	font(PD_ResourceManager::scenario->getFont("TASKLIST-FONT")->font),
	crossedFont(PD_ResourceManager::scenario->getFont("TASKLIST-FONT-CROSSED")->font),
	unseenTask(false),
	numTasks(0),
	testID(0)
{
	textShader->setColor(1.f, 1.f, 1.f);
	textShader->incrementReferenceCount();
	textShader->name = "PD_UI_Tasklist text shader (normal)";

	crossedTextShader->setColor(0.f, 0.f, 0.f);
	crossedTextShader->incrementReferenceCount();
	crossedTextShader->name = "PD_UI_Tasklist text shader (crossed)";

	background->setVisible(false);

	NodeUI * container = new NodeUI(_world);
	addChild(container);
	container->setRationalWidth(1.f, this);
	container->setRationalHeight(1.f, this);
	container->setMargin(0.f, 0.66f, 0.05f, 0.05f);
	container->marginLeft.setRationalSize(1.f, &container->marginTop);
	container->background->setVisible(false);

	icon = new NodeUI(_world);
	icon->boxSizing = kCONTENT_BOX;
	container->addChild(icon);
	icon->background->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("JOURNAL-OPEN")->texture);
	icon->background->mesh->setScaleMode(GL_NEAREST);
	icon->setHeight(0.05f);
	icon->setSquareWidth(190.f/74.f);
	icon->setMarginBottom(0.95f);

	VerticalLinearLayout * layout = new VerticalLinearLayout(_world);
	container->addChild(layout);
	layout->horizontalAlignment = kLEFT;
	layout->verticalAlignment = kTOP;
	layout->setRationalWidth(1.f, container);
	layout->setRationalHeight(0.95f, container);

	journalLayout = new NodeUI_NineSliced(_world, PD_ResourceManager::scenario->getNineSlicedTexture("MESSAGE-BUBBLE"));
	layout->addChild(journalLayout);
	journalLayout->setScaleMode(GL_NEAREST);
	journalLayout->setBorder(PD_ResourceManager::scenario->getFont("FONT")->font->getLineHeight() * 0.5f);
	journalLayout->setRationalWidth(1.f, layout);
	journalLayout->setAutoresizeHeight();
	journalLayout->setBackgroundColour(1.f, 1.f, 1.f, TASKLIST_OPACITY);

	float lineHeight = PD_ResourceManager::scenario->getFont("FONT")->font->getLineHeight();

	taskLayout = new VerticalLinearLayout(_world);
	taskLayout->boxSizing = kCONTENT_BOX;
	journalLayout->addChild(taskLayout);
	taskLayout->horizontalAlignment = kLEFT;
	taskLayout->verticalAlignment = kTOP;
	taskLayout->setRationalWidth(1.f, journalLayout);
	taskLayout->setAutoresizeHeight();
	taskLayout->setPadding(0.f, lineHeight * 0.5f);

	journalLayout->setVisible(false);
}
PD_UI_DissBattle::PD_UI_DissBattle(BulletWorld* _bulletWorld, Player * _player, Font * _font, Shader * _textShader, Shader * _shader) :
	VerticalLinearLayout(_bulletWorld),
	iteration(0),
	enabled(true),
	canInterject(true),
	basePlayerInsultSpeedMultiplier(1.f),
	playerInsultSpeedMultiplier(basePlayerInsultSpeedMultiplier),
	basePlayerQuestionTimerLength(1.f),
	playerQuestionTimerLength(basePlayerQuestionTimerLength),
	playerQuestionTimer(0),
	basePlayerAnswerTimerLength(1.25f),
	playerAnswerTimerLength(basePlayerAnswerTimerLength),
	playerAnswerTimer(0),
	playerResult(false),
	playerResultEffective(false),
	playerResultTimerLength(1.5f),
	playerResultTimer(0.f),
	enemyCursor(new Sprite(_shader)),
	prevHighlightedPunctuation(nullptr),
	highlightedPunctuation(nullptr),
	punctuationHighlight(new Sprite(_shader)),
	highlightedWordStart(nullptr),
	highlightedWordEnd(nullptr),
	wordHighlight(new Sprite(_shader)),
	complimentBubble(new Sprite(_shader)),
	complimentBubbleTimerBaseLength(1.f),
	complimentBubbleTimerLength(1.f),
	complimentBubbleTimer(0.f),
	complimentBubbleScale(1.f),
	interjectBubble(new Sprite(_shader)),
	interjected(false),
	interjectBubbleTimerBaseLength(1.f),
	interjectBubbleTimerLength(1.f),
	interjectBubbleTimer(0.f),
	shader(_shader),
	baseCursorDelayLength(0.05f),
	baseCursorPunctDelayLength(0.15f),
	cursorDelayLength(0.f),
	cursorDelayDuration(0.f),
	baseGlyphWidth(_font->getGlyphAdvance('m').x),
	glyphIdx(0),
	confidence(50.f),
	isGameOver(false),
	gameOverLength(1.f),
	gameOverDuration(0.f),
	win(false),
	isComplete(false),
	offensiveCorrect(0),
	offensiveWrong(0),
	defensiveCorrect(0),
	defensiveWrong(0),
	punctuationCnt(-1),
	interjectTimer(0),
	damage(10.f),
	playerComboMultiplier(1.f),
	enemyComboMultiplier(1.f),
	keyboard(&Keyboard::getInstance()),
	enemy(nullptr),
	modeOffensive(true),
	player(_player),
	playerAttackMultiplier(1.f),
	enemyAttackMultiplier(1.f),
	insightMultiplier(1.f),
	insightAlpha(1.f),
	sassInsultMultiplier(1.f),
	sassInterjectMultiplier(1.f),
	playerComboIncrement(0),
	enemyComboIncrement(0),
	optionOneShader(new ComponentShaderText(true)),
	optionTwoShader(new ComponentShaderText(true))
{
	verticalAlignment = kTOP;
	horizontalAlignment = kCENTER;
	background->setVisible(false);

	float borderSize = sweet::getWindowHeight() * 0.1f / 2.f;

	healthContainer = new VerticalLinearLayout(_bulletWorld);
	addChild(healthContainer);
	healthContainer->setRationalWidth(1.f, this);
	healthContainer->setRationalHeight(0.15f, this);
	healthContainer->horizontalAlignment = kCENTER;
	healthContainer->verticalAlignment = kMIDDLE;
	//healthContainer->setBackgroundColour(0, 1.f, 0.541f);

	displayContainer = new NodeUI(_bulletWorld);
	addChild(displayContainer);
	displayContainer ->setRationalWidth(1.f, this);
	displayContainer ->setRationalHeight(0.85f, this);
	displayContainer ->background->setVisible(false);

	gameContainer = new NodeUI(_bulletWorld);
	displayContainer->addChild(gameContainer);
	gameContainer->setRationalWidth(1.f, displayContainer);
	gameContainer->setRationalHeight(1.f, displayContainer);
	gameContainer->background->setVisible(false);
	//gameContainer->setBackgroundColour(0, 0.714f, 0.929f);

	// Enemy Cursor
	enemyCursor->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("DISS-BATTLE-CURSOR")->texture);
	enemyCursor->mesh->setScaleMode(GL_NEAREST);
	enemyCursor->childTransform->scale(20.f);
	childTransform->addChild(enemyCursor);

	// move the cusrosr's mesh up so that the origin is aligned with the top
	for (unsigned long int i = 0; i < enemyCursor->mesh->vertices.size(); ++i){
		enemyCursor->mesh->vertices.at(i).y -= 0.5f;
	}

	// Punctuation Highlight
	punctuationHighlight->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("DISS-BATTLE-HIGHLIGHT")->texture);
	punctuationHighlight->mesh->setScaleMode(GL_NEAREST);
	// move the highlight's mesh up so that the origin is aligned with the bottom
	for (unsigned long int i = 0; i < punctuationHighlight->mesh->vertices.size(); ++i){
		punctuationHighlight->mesh->vertices.at(i).x += 0.5f;
		punctuationHighlight->mesh->vertices.at(i).y += 0.5f;
	}
	punctuationHighlight->setVisible(false);

	// Word Highlight
	// move the highlights's mesh up so that the origin is aligned with the bottom and set the colour
	for (unsigned long int i = 0; i < wordHighlight->mesh->vertices.size(); ++i){
		wordHighlight->mesh->vertices.at(i).x += 0.5f;
		wordHighlight->mesh->vertices.at(i).y += 0.5f;

		wordHighlight->mesh->vertices.at(i).red = 0.820f;
		wordHighlight->mesh->vertices.at(i).green = 0.722f;
		wordHighlight->mesh->vertices.at(i).blue = 0.851f;
	}
	wordHighlight->setVisible(false);

	livesContainer = new HorizontalLinearLayout(_bulletWorld);
	healthContainer->addChild(livesContainer);
	//livesContainer->setBackgroundColour(0.5f, 1.f, 0.5f);
	livesContainer->setRationalWidth(1.f, healthContainer);
	livesContainer->setRationalHeight(0.5f, healthContainer);
	livesContainer->horizontalAlignment = kLEFT;
	livesContainer->verticalAlignment = kTOP;

	// healthbar
	confidenceSlider = new SliderControlled(_bulletWorld, &confidence, 0, 100.f);
	healthContainer->addChild(confidenceSlider);
	//confidenceSlider->setBackgroundColour(1.f, 0, 0);
	//confidenceSlider->fill->setBackgroundColour(0, 1.f, 0);
	confidenceSlider->setRationalWidth(0.7f, healthContainer);
	confidenceSlider->setRationalHeight(0.5f, healthContainer);

	//confidenceSlider->thumb->background->meshTransform->scale(2);
	confidenceSlider->thumb->setBackgroundColour(1,1,1,1);
	confidenceSlider->thumb->background->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("DISS-BATTLE-SLIDER-THUMB-HAPPY")->texture);
	confidenceSlider->thumb->background->mesh->setScaleMode(GL_NEAREST);

	confidenceSlider->setBackgroundColour(1,1,1,1);
	confidenceSlider->background->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("DISS-BATTLE-SLIDER-TRACK")->texture);
	confidenceSlider->background->mesh->setScaleMode(GL_NEAREST);

	confidenceSlider->fill->setBackgroundColour(1,1,1,1);
	confidenceSlider->fill->background->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("DISS-BATTLE-SLIDER-FILL")->texture);
	confidenceSlider->fill->background->mesh->setScaleMode(GL_NEAREST);

	enemyBubble = new NodeUI(_bulletWorld);
	gameContainer->addChild(enemyBubble);
	enemyBubble->setRationalWidth(1.f, gameContainer);
	enemyBubble->setRationalHeight(1.f, gameContainer);
	enemyBubble->setMarginTop(0.4f);
	enemyBubble->setMarginBottom(0.3f);
	enemyBubble->background->setVisible(false);
	enemyBubble->setBackgroundColour(0.5, 0.5, 0.5, 1.f);
	enemyBubble->setMarginRight(0.05f);
	enemyBubble->setMarginLeft(0.55f);

	NodeUI_NineSliced * enemyBubbleBubble = new NodeUI_NineSliced(_bulletWorld, PD_ResourceManager::scenario->getNineSlicedTexture("NPC-BUBBLE"));
	enemyBubble->addChild(enemyBubbleBubble);
	enemyBubbleBubble->setBorder(borderSize);
	enemyBubbleBubble->setRationalWidth(1.f, enemyBubble);
	enemyBubbleBubble->setRationalHeight(1.f, enemyBubble);
	enemyBubbleBubble->setMarginLeft(0.15f);
	enemyBubbleBubble->setPadding(0.05f);
	enemyBubbleBubble->setScaleMode(GL_NEAREST);
	//enemyBubbleBubble->setBackgroundColour(0.f, 1.f, 0.f, 0.5f);

	NodeUI * enemyBubbleTextContainer = new NodeUI(_bulletWorld);
	enemyBubbleBubble->addChild(enemyBubbleTextContainer);
	enemyBubbleTextContainer->setRationalWidth(1.f, enemyBubbleTextContainer->nodeUIParent);
	enemyBubbleTextContainer->setRationalHeight(1.f, enemyBubbleTextContainer->nodeUIParent);
	enemyBubbleTextContainer->setBackgroundColour(1.f,0, 0, 0.5);
	enemyBubbleTextContainer->background->setVisible(false);
	enemyBubbleTextContainer->setPadding(0.05f);

	enemyBubbleTextContainer->uiElements->addChild(wordHighlight);
	enemyBubbleTextContainer->uiElements->addChild(punctuationHighlight);

	enemyBubbleText = new TextArea(world, _font, _textShader);
	enemyBubbleText->setRenderMode(kTEXTURE);
	enemyBubbleTextContainer->addChild(enemyBubbleText);
	enemyBubbleText->setWrapMode(kWORD);
	enemyBubbleText->setRationalWidth(1.f, enemyBubbleTextContainer);
	enemyBubbleText->setRationalHeight(1.f, enemyBubbleTextContainer);
	enemyBubbleText->horizontalAlignment = kCENTER;
	enemyBubbleText->verticalAlignment = kMIDDLE;
	enemyBubbleText->background->setVisible(false);
	enemyBubbleText->setBackgroundColour(1, 1, 1, 0.5);

	NodeUI * enemyBubbleTail = new NodeUI(_bulletWorld);
	enemyBubble->addChild(enemyBubbleTail);
	enemyBubbleTail->background->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("DISS-BATTLE-DEFENSE-BUBBLE-TAIL")->texture);
	enemyBubbleTail->setRationalWidth(1.f, enemyBubble);
	enemyBubbleTail->setRationalHeight(1.f, enemyBubble);
	enemyBubbleTail->setMarginRight(0.835f);
	enemyBubbleTail->setMarginTop(0.3f);
	enemyBubbleTail->setMarginBottom(0.3f);
	//enemyBubbleTail->setBackgroundColour(1.f, 0, 0, 0.5f);
	enemyBubbleTail->background->mesh->setScaleMode(GL_NEAREST);

	playerBubble = new NodeUI(_bulletWorld);
	gameContainer->addChild(playerBubble);
	playerBubble->setRationalWidth(1.f, gameContainer);
	playerBubble->setRationalHeight(1.f, gameContainer);
	playerBubble->setMarginTop(0.5f);
	playerBubble->setMarginBottom(0.05f);
	playerBubble->background->setVisible(false);
	playerBubble->setBackgroundColour(1, 0, 0, 0.5f);
	playerBubble->setMarginRight(0.05f);
	playerBubble->setMarginLeft(0.4f);

	playerTimerSlider = new SliderControlled(_bulletWorld, &playerAnswerTimer, 0, playerAnswerTimerLength, true, true);
	playerBubble->addChild(playerTimerSlider);
	playerTimerSlider->boxSizing = kCONTENT_BOX;
	playerTimerSlider->setRationalWidth(0.7f, playerBubble);
	playerTimerSlider->setRationalHeight(0.1f, playerBubble);
	playerTimerSlider->setBackgroundColour(1,1,1,1);
	playerTimerSlider->background->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("SLIDER-TRACK")->texture);
	playerTimerSlider->background->mesh->setScaleMode(GL_NEAREST);
	playerTimerSlider->fill->setBackgroundColour(1,1,1,1);
	playerTimerSlider->fill->background->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("DISS-BATTLE-SLIDER-FILL")->texture);
	playerTimerSlider->fill->background->mesh->setScaleMode(GL_NEAREST);
	playerTimerSlider->thumb->setVisible(false);
	playerTimerSlider->setMarginLeft(0.3f);
	playerTimerSlider->setMarginBottom(1.f);

	// The fancy nine sliced bubble
	NodeUI_NineSliced * playerBubbleBubble = new NodeUI_NineSliced(_bulletWorld, PD_ResourceManager::scenario->getNineSlicedTexture("PLAYER-BUBBLE"));
	playerBubble->addChild(playerBubbleBubble);
	playerBubbleBubble->setBorder(borderSize);
	playerBubbleBubble->setRationalWidth(1.f, playerBubble);
	playerBubbleBubble->setRationalHeight(1.f, playerBubble);
	playerBubbleBubble->setMarginLeft(0.3f);
	playerBubbleBubble->setMarginBottom(0.3f);
	//playerBubbleBubble->setBackgroundColour(0, 0.1f, 0, 0.5f);
	playerBubbleBubble->setScaleMode(GL_NEAREST);

	// The side by side text and button layout
	playerBubbleLayout = new HorizontalLinearLayout(_bulletWorld);
	playerBubbleBubble->addChild(playerBubbleLayout);
	playerBubbleLayout->verticalAlignment = kMIDDLE;
	playerBubbleLayout->horizontalAlignment = kCENTER;
	playerBubbleLayout->setRationalWidth(1.f, playerBubbleBubble);
	playerBubbleLayout->setRationalHeight(1.f, playerBubbleBubble);
	playerBubbleLayout->setPadding(0.05f);
	playerBubbleLayout->background->setVisible(false);
	playerBubbleLayout->setBackgroundColour(1, 1, 1, 0.5f);

	playerBubbleText = new TextArea(world, _font, _textShader);
	playerBubbleText->setRenderMode(kTEXTURE);
	playerBubbleText->setWrapMode(kWORD);
	playerBubbleLayout->addChild(playerBubbleText);
	playerBubbleText->setRationalWidth(PLAYER_TEXT_WIDTH, playerBubbleLayout);
	playerBubbleText->setRationalHeight(1.0f, playerBubbleLayout);
	playerBubbleText->horizontalAlignment = kCENTER;
	playerBubbleText->verticalAlignment = kMIDDLE;
	playerBubbleText->background->setVisible(false);
	playerBubbleText->setBackgroundColour(1.f, 0, 0, 0.5f);

	playerBubbleOptions = new HorizontalLinearLayout(_bulletWorld);
	playerBubbleLayout->addChild(playerBubbleOptions);

	playerBubbleOptions->setRationalWidth(0.5f, playerBubbleLayout);
	playerBubbleOptions->setRationalHeight(1.f, playerBubbleLayout);
	playerBubbleOptions->setBackgroundColour(0, 1.f, 0, 0.5f);
	playerBubbleOptions->background->setVisible(false);
	playerBubbleOptions->horizontalAlignment = kCENTER;
	playerBubbleOptions->verticalAlignment = kMIDDLE;

	Texture * arrowsTex = PD_ResourceManager::scenario->getTexture("DISS-TUTORIAL-ARROWS")->texture;
	NodeUI * playerArrows = new NodeUI(_bulletWorld);
	playerBubbleOptions->addChild(playerArrows);
	playerArrows->background->mesh->pushTexture2D(arrowsTex);
	playerArrows->setRationalWidth(0.2f, playerBubbleOptions);
	playerArrows->setSquareHeight((float)arrowsTex->height/arrowsTex->width);
	playerArrows->background->mesh->setScaleMode(GL_NEAREST);

	VerticalLinearLayout * buttonLayout = new VerticalLinearLayout(_bulletWorld);
	playerBubbleOptions->addChild(buttonLayout);
	buttonLayout->setRationalWidth(0.8f, playerBubbleOptions);
	buttonLayout->setRationalHeight(0.75f, playerBubbleOptions);
	buttonLayout->verticalAlignment = kMIDDLE;
	buttonLayout->setPaddingLeft(0.05f);

	pBubbleBtn1 = new PD_InsultButton(_bulletWorld, _font, optionOneShader);
	buttonLayout->addChild(pBubbleBtn1);
	pBubbleBtn1->setRationalWidth(1.f, buttonLayout);
	pBubbleBtn1->setRationalHeight(0.5f, buttonLayout);
	pBubbleBtn1->setPadding(0.f, 0.1f);
	pBubbleBtn1->setMarginBottom(0.1f);
	pBubbleBtn1->setMouseEnabled(false);

	pBubbleBtn2 = new PD_InsultButton(_bulletWorld, _font, optionTwoShader);
	buttonLayout->addChild(pBubbleBtn2);
	pBubbleBtn2->setRationalWidth(1.f, buttonLayout);
	pBubbleBtn2->setRationalHeight(0.5f, buttonLayout);
	pBubbleBtn2->setPadding(0.f, 0.1f);
	pBubbleBtn2->setMarginTop(0.1f);
	pBubbleBtn2->setMouseEnabled(false);

	NodeUI * playerBubbleTail = new NodeUI(_bulletWorld);
	playerBubble->addChild(playerBubbleTail);
	playerBubbleTail->background->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("DISS-BATTLE-OFFENSE-BUBBLE-TAIL")->texture);
	playerBubbleTail->setRationalWidth(1.f, playerBubble);
	playerBubbleTail->setRationalHeight(1.f, playerBubble);
	playerBubbleTail->setMarginRight(0.69f);
	playerBubbleTail->setMarginTop(0.3f);
	playerBubbleTail->setMarginBottom(0.03f);
	playerBubbleTail->background->mesh->setScaleMode(GL_NEAREST);

	gameOverContainer = new VerticalLinearLayout(_bulletWorld);
	displayContainer->addChild(gameOverContainer);
	gameOverContainer->horizontalAlignment = kCENTER;
	gameOverContainer->verticalAlignment = kMIDDLE;
	gameOverContainer->setRationalHeight(1.f, displayContainer);
	gameOverContainer->setRationalWidth(1.f, displayContainer);
	gameOverContainer->setPadding(0.f, 0.1f);
	gameOverContainer->setVisible(false);

	gameOverImage = new NodeUI(_bulletWorld);
	gameOverContainer->addChild(gameOverImage);
	gameOverImage->setRationalHeight(0.5f, gameOverContainer);
	gameOverImage->setSquareWidth(1.f);
	gameOverImage->background->mesh->setScaleMode(GL_NEAREST);

	complimentBubble->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("DISS-BATTLE-COMPLIMENT1")->texture);
	complimentBubble->mesh->setScaleMode(GL_NEAREST);
	complimentBubble->childTransform->scale(sweet::getWindowHeight() * 0.5, sweet::getWindowHeight() * 0.5, 0);
	complimentBubble->meshTransform->scale(0, 0, 0);
	complimentBubble->childTransform->translate(sweet::getWindowWidth() * 0.2, 0, 0);
	complimentBubble->setVisible(false);

	// move the interject bubble's mesh up so that the origin is aligned with the bottom
	for (unsigned long int i = 0; i < complimentBubble->mesh->vertices.size(); ++i){
		complimentBubble->mesh->vertices.at(i).x += 0.5f;
		complimentBubble->mesh->vertices.at(i).y += 0.5f;
	}
	childTransform->addChild(complimentBubble);

	interjectBubble->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("DISS-BATTLE-INTERJECT")->texture);
	interjectBubble->mesh->setScaleMode(GL_NEAREST);
	interjectBubble->childTransform->scale(sweet::getWindowHeight() * 0.6, sweet::getWindowHeight() * 0.6, 0);
	interjectBubble->meshTransform->scale(0, 0, 0);
	interjectBubble->childTransform->translate(sweet::getWindowWidth() * 0.6, 0, 0);
	interjectBubble->setVisible(false);

	// move the interject bubble's mesh up so that the origin is aligned with the bottom
	for (unsigned long int i = 0; i < interjectBubble->mesh->vertices.size(); ++i){
		interjectBubble->mesh->vertices.at(i).x += 0.5f;
		interjectBubble->mesh->vertices.at(i).y += 0.5f;
	}
	childTransform->addChild(interjectBubble);

	tutorialSpacebar = new HorizontalLinearLayout(_bulletWorld);
	gameContainer->addChild(tutorialSpacebar);
	tutorialSpacebar->setRationalWidth(1.f, gameContainer);
	tutorialSpacebar->setRationalHeight(0.4f, gameContainer);
	tutorialSpacebar->verticalAlignment = kMIDDLE;
	tutorialSpacebar->horizontalAlignment = kCENTER;
	tutorialSpacebar->setMarginLeft(0.6f);
	tutorialSpacebar->setVisible(false);

	tutorialSpacebarImage = new NodeUI(_bulletWorld);
	tutorialSpacebar->addChild(tutorialSpacebarImage);
	tutorialSpacebarImage->setRationalHeight(1.f, tutorialSpacebar);
	tutorialSpacebarImage->setSquareWidth(1.f);
	tutorialSpacebarImage->background->mesh->pushTexture2D(PD_ResourceManager::scenario->getTexture("DISS-TUTORIAL-SPACEBAR")->texture);
	tutorialSpacebarImage->background->mesh->setScaleMode(GL_NEAREST);

	// disable and hide by default
	disable();

	eventManager->addEventListener("wordspoken", [this](sweet::Event * _event){
		// Stuff!!!
	});

	// Init sound vectors
	for(unsigned long int i = 1; i < 11; ++i) {
		missInterjectSounds.push_back(PD_ResourceManager::scenario->getAudio("slap" + std::to_string(i))->sound);
	}

	for(unsigned long int i = 1; i < NUM_SUCCEED_INSULT; ++i) {
		succeedInsultSounds.push_back(PD_ResourceManager::scenario->getAudio(SUCCEED_INSULT + std::to_string(i))->sound);
	}
	
	PD_ResourceManager::scenario->getAudio(TIMER)->sound->setGain(3);

	optionOneShader->incrementReferenceCount();
	optionTwoShader->incrementReferenceCount();
	optionOneShader->name = "PD_UI_DissBattle text shader (option one)";
	optionTwoShader->name = "PD_UI_DissBattle text shader (option two)";


	eventManager->addEventListener("fightStarted", [this](sweet::Event * _event){
		if(modeOffensive){
			playerBubbleText->invalidateLayout();
		}else{
			enemyBubbleText->invalidateLayout();
		}
	});
}