void Robot::update(int deltaTime) { Vector3 v = velocity * float(deltaTime); translate(v); if (!checkCollision()) { translate(-v); setRandDirection(); } if (shotCooldown) { shotTimer += deltaTime; if (shotTimer >= shotTimerMax) { shotTimer = 0; shotCooldown = false; } } Room * playerRoom = Game::instance->roomAt(Game::instance->player->getWorldPos()); Room * room = Game::instance->roomAt(getWorldPos()); if (playerRoom == room) { Vector3 dir = Game::instance->player->getWorldPos() - getWorldPos(); float ang = atan2f(dir.z, dir.x); ang *= (1.0f / DEG2RAD); setRotation(Vector3(0, -ang + 90, 0)); if (!shotCooldown) { spawnBullet(); shotCooldown = true; } } }
bool GFrame::onMouseMsg( MouseMsg const& msg ) { BaseClass::onMouseMsg( msg ); static int x , y; static bool needMove = false; if ( msg.onLeftDown() ) { setTop(); if ( msg.getPos().y > getWorldPos().y && msg.getPos().y < getWorldPos().y + TopSideHeight ) { x = msg.x(); y = msg.y(); getManager()->captureMouse( this ); needMove = true; } } else if ( msg.onRightDown() ) { if ( msg.getPos().y > getWorldPos().y && msg.getPos().y < getWorldPos().y + TopSideHeight ) { mbMiniSize = !mbMiniSize; if ( mbMiniSize ) { mPrevSize = getSize(); setSize( Vec2i( mPrevSize.x , TopSideHeight ) ); mClipEnable = true; } else { setSize( mPrevSize ); mClipEnable = false; } } } else if ( msg.onLeftUp() ) { needMove = false; getManager()->releaseMouse(); } if ( needMove ) { if ( msg.isLeftDown() && msg.isDraging() ) { Vec2i pos = getPos() +Vec2i( msg.x() - x , msg.y() - y ); setPos( pos ); x = msg.x(); y = msg.y(); } } return false; }
void Robot::spawnBullet() { Bullet * bullet = new Bullet(); bullet->shotByPlayer = false; bullet->moveSpeed /= 3.0f; bullet->setPosition(getWorldPos()); Vector3 forwardDir = Game::instance->player->getWorldPos() - getWorldPos(); forwardDir.Normalize(); bullet->setVelocity(forwardDir); game->bullets.push_back(bullet); }
Room* Room::SpawnRoom(Direction dir) { if (rooms[int(dir)] != nullptr) return rooms[int(dir)]; CubeMesh* wall1 = new CubeMesh(Textures::TILES01); CubeMesh* wall2 = new CubeMesh(Textures::TILES01); float doorWidth = .25; float ratio = randZeroToOne(); auto pos = Vector3(dir); auto straight = (dir == FORWARD || dir == BACK) ? Vector3(FORWARD) : Vector3(RIGHT); auto unit = (dir == UP || dir == DOWN) ? Vector3(FORWARD) : Vector3(UP); auto edge = (dir == FORWARD || dir == BACK) ? Vector3(RIGHT) : Vector3(FORWARD); float leeway = (1 - doorWidth); addChild(wall1); addChild(wall2); wall1->setPosition(pos/2 + edge * (-.5f + (leeway * ratio /2))); wall2->setPosition(pos/2 + edge * (.5f - (leeway * (1 - ratio) /2))); wall1->setScale( unit + edge * (leeway * ratio) + straight * 0.05f); wall2->setScale(unit + edge * (leeway * (1 - ratio)) + straight * 0.05f); Game::instance->cubes.push_back(wall1);//Ughhhhh. Game::instance->cubes.push_back(wall2);//Ughhhhh. rooms[int(dir)] = new Room(getWorldPos() + pos.ElementWiseProduct(getScale()), getScale()); rooms[int(dir)]->rooms[int(Opposite(dir))] = this; return rooms[int(dir)]; }
// ********************************************************************************************************* const NLMISC::CMatrix &CDisplayerVisualShape::getInvertedMatrix() const { //H_AUTO(R2_CDisplayerVisualShape_getInvertedMatrix) // no rot part for now _InvertedMatrix.setPos(- getWorldPos().asVector()); return _InvertedMatrix; }
void Robot::translate(Vector3 diff) { CubeMesh::translate(diff); Vector3 p = getWorldPos(); p.y = -2.0f; //translate(Vector3(0, -1.0f, 0)); }
void GFrame::onRender() { Vec2i pos = getWorldPos(); Vec2i size = getSize(); //TIJELO PROZORA glEnable(GL_BLEND); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glColor4f(0.0, 0.25, 0.0 , 0.4 ); drawRect( pos , size ); glDisable(GL_BLEND); //NASLOVNICA (TRAKA) glBegin(GL_QUADS); glColor3f(0.0, 1.0, 0.0); glVertex2f(pos.x, pos.y); glColor3f(0.0, 1.0, 0.0); glVertex2f(pos.x+size.x, pos.y); glColor3f(0.0, 0.0, 0.0); glVertex2f(pos.x+size.x, pos.y+TopSideHeight); glColor3f(0.0, 0.0, 0.0); glVertex2f(pos.x, pos.y+TopSideHeight); glEnd(); glColor3f(1.0, 1.0, 1.0); if ( mTile ) { getRenderSystem()->drawText( mTile , pos + Vec2i( 10 , 0 ) , TEXT_SIDE_LEFT | TEXT_SIDE_TOP ); } }
bool Robot::checkCollision(bool pointBased) { for (auto& bullet : Game::instance->bullets) { BBox other = bullet->getBBox(); if (!bullet->shotByPlayer) continue; if (other.Intersects(getBBox()) && !(pointBased && !other.Contains(getWorldPos()))) { bullet->flaggedForRemoval = true; if (--health <= 0) { if (!flaggedForRemoval) { Game::instance->kills++; } flaggedForRemoval = true; return true; } break; } } for (auto& robot : Game::instance->robots) { BBox other = robot->getBBox(); if (robot != this && other.Intersects(getBBox()) && !(pointBased && !other.Contains(getWorldPos()))) { return false; } } return CubeMesh::checkCollision(pointBased); }
void Bullet::update(Step* _step) { firstParent()->translate(0.f, dir * 2.f, 0.f); glm::vec3 worldPos = getWorldPos(); bbox.x = worldPos.x; bbox.y = worldPos.y; MeshEntity::update(_step); }
void Slider::update(Step * _step){ // update the slider's value based on the mouse's position when it is being pressed if(isDown){ float v; if(horizontal){ v = (mouse->mouseX() - getWorldPos().x)/getWidth(true, false); }else{ v = (mouse->mouseY() - getWorldPos().y)/getHeight(true, false); } if(flipped){ v = 1.f - v; } v *= (valueMax - valueMin) + valueMin + valueStep*0.5f; setValue(v); } NodeUI::update(_step); }
void Renderer::draw() { //int dw = al_get_display_width(dpy_); //int dh = al_get_display_height(dpy_); ALLEGRO_TRANSFORM trans; al_identity_transform(&trans); al_compose_transform(&trans, &camera_transform_); al_rotate_transform_3d(&trans, 1.0, 0.0, 0.0, rx_look); setupProjection(&trans); al_identity_transform(&trans); al_use_transform(&trans); getWorldPos(camera_pos_); al_copy_transform(&cur3d_transform_, al_get_current_transform()); glEnable(GL_DEPTH_TEST); // Accept fragment if it closer to the camera than the former one glDepthFunc(GL_LEQUAL); glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); glEnable(GL_ALPHA_TEST); if(!setShader(SHADER_DEFAULT)) { NBT_Debug("failed to set default shader"); } glBindVertexArray(vao_); resManager_->setAtlasUniforms(); for(auto &it: chunkData_) { ChunkData *cd = it.second; ALLEGRO_TRANSFORM ctrans; al_identity_transform(&ctrans); al_translate_transform_3d(&ctrans, cd->x()*15.0, 0.0, cd->z()*15.0); al_use_transform(&ctrans); cd->draw(&ctrans); } glBindVertexArray(0); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); //drawSelection(); resManager_->unsetAtlasUniforms(); }
void GImageButton::onRender() { if( getButtonState() == BS_HIGHLIGHT ) glColor3f(0.25, 0.25, 0.25); else glColor3f(1.0, 1.0, 1.0); Vec2f pos; pos.x = getWorldPos().x; pos.y = getWorldPos().y; Vec2f size; size.x = getSize().x; size.y = getSize().y; drawSprite( pos , size ,texImag ); glColor3f(1.0, 1.0, 1.0); }
void GPanel::onRender() { Vec2i pos = getWorldPos(); Vec2i size = getSize(); //TIJELO PROZORA glEnable(GL_BLEND); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glColor4f( 0.0 , 0.25, 0.0 , 0.8 ); drawRect( pos , size ); glDisable(GL_BLEND); }
//----------------------------------------------------------------------- void DynamicBlockObject::refreshWorldBlockTriangle(StrutureMeshs* strutureMeshs) { UInt triCount = strutureMeshs->mTriangle3DList.size(); if ( triCount > 0 ) { if ( strutureMeshs->mWorldTriangle3DList.size() != triCount ) { strutureMeshs->mWorldTriangle3DList.resize( triCount ); } for (UInt i = 0; i < triCount; i++) { Triangle3D& tri = strutureMeshs->mTriangle3DList[i]; Triangle3D& wTri = strutureMeshs->mWorldTriangle3DList[i]; wTri.t0 = getWorldPos(tri.t0); wTri.t1 = getWorldPos(tri.t1); wTri.t2 = getWorldPos(tri.t2); } } }
bool Room::Contains(BBox* box, bool pointbased) const { bool res = ((box->min.x >= bounds.min.x || rooms[LEFT] != nullptr) && (box->min.y >= bounds.min.y) && (box->min.z >= bounds.min.z || rooms[FORWARD] != nullptr) && (box->max.x <= bounds.max.x || rooms[RIGHT] != nullptr) && (box->max.y <= bounds.max.y) && (box->max.z <= bounds.max.z || rooms[BACK] != nullptr)); res = (res || (pointbased && bounds.Contains(getWorldPos()))); return res; }
void eCamera::activate(const eMatrix4x4 &modelMtx) const { static eConstBufferDx11<ShaderConsts, eST_VS> cb; cb.data.viewMtx = m_viewMtx; cb.data.projMtx = m_projMtx; cb.data.mvpMtx = modelMtx*m_viewMtx*m_projMtx; cb.data.itViewMtx = m_itViewMtx; cb.data.camWorldPos = getWorldPos(); cb.data.clearCol = m_clearCol; eRenderState &rs = eGfx->getRenderState(); rs.constBufs[eCBI_CAMERA] = &cb; eGfx->setMatrices(modelMtx, m_viewMtx, m_projMtx); }
// ********************************************************************************************************* void CDisplayerVisual::evalIconInScenePos(NLMISC::CVector &dest) const { //H_AUTO(R2_CDisplayerVisual_evalIconInScenePos) NLMISC::CAABBox selectBox = getSelectBox(); float radius = std::max(selectBox.getHalfSize().x, selectBox.getHalfSize().y); // use middle front of bbox for icon pos NLMISC::CVector result = getWorldPos().asVector() - radius * MainCam.getMatrix().getJ() + selectBox.getHalfSize().z * CVector::K; static volatile bool wantAssert = true; if (!isValidDouble(result.x) || !isValidDouble(result.y) ||!isValidDouble(result.z)) { nlassert(!wantAssert); return; } dest = result; }
void GTextButton::onRender() { Vec2i const& pos = getWorldPos(); Vec2i const& size = getSize(); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); if( isEnable() ) { if( getButtonState() == BS_HIGHLIGHT ) glColor3f(0.0, 0.5, 0.0); else glColor3f(0.0, 0.25, 0.0); } else { glColor3f(0.05, 0.05, 0.05); } drawRect( pos , size ); if( isEnable() ) { if( getButtonState() == BS_HIGHLIGHT ) glColor3f(0.0, 1.0, 0.0); else glColor3f(0.0, 0.5, 0.0); } else { glColor3f(0.1, 0.1, 0.1); } drawRectLine( pos , size ); glColor3f(1.0, 1.0, 1.0); glDisable(GL_BLEND); if( isEnable() ) text->setColor(Color(50,255,50)); else text->setColor(Color(150,150,150)); getRenderSystem()->drawText( text , pos + size / 2 ); }
void GChoice::onRender() { Vec2i pos = getWorldPos(); Vec2i size = getSize(); glEnable(GL_BLEND); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glColor4f( 0.1, 0.1 , 0.1 , 0.8f ); drawRect( pos , size ); glColor3f( 1,1,1); glDisable(GL_BLEND); if ( mCurSelect != -1 ) { Item& item = mItemList[ mCurSelect ]; getRenderSystem()->drawText( item.text , pos + size / 2 ); } }
void PropFrame::onRender() { BaseClass::onRender(); Vec2i pos = getWorldPos(); int i = 0; for( PropInfoVec::iterator iter= mPorps.begin() , itEnd = mPorps.end(); iter != itEnd ; ++iter ) { PropInfo& data = *iter; getRenderSystem()->drawText( data.name , pos + Vec2i( 5 , TopSideHeight + 5 + i * ( getWidgetSize().y + 5 ) + getWidgetSize().y / 2 ) , TEXT_SIDE_LEFT ); ++i; } }
void GTextCtrl::onRender() { Vec2i pos = getWorldPos(); Vec2i size = getSize(); glEnable(GL_BLEND); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glColor4f( 0.1, 0.1 , 0.1 , 0.8f ); drawRect( pos , size ); glColor3f( 1,1,1); glDisable(GL_BLEND); if( isFocus() ) text->setColor(Color(50,255,50)); else text->setColor(Color(150,150,150)); getRenderSystem()->drawText( text , pos + size / 2 ); }
void GWidget::doRenderAll() { if ( mClipEnable ) { Vec2i pos = getWorldPos(); Vec2i size = getSize(); pos.y = getGame()->getScreenSize().y - ( pos.y + size.y ); gClipStack.push( pos , size , true ); } TUICore< GWidget >::doRenderAll(); GWidget* ui = getChild(); while( ui ) { ui->onRenderSiblingsEnd(); ui = nextChild( ui ); } if ( mClipEnable ) { gClipStack.pop(); } }
// ********************************************************************************************************* void CDisplayerVisualShape::snapToGround() { //H_AUTO(R2_CDisplayerVisualShape_snapToGround) if (!GR) { return; } NLPACS::UGlobalPosition gpos = GR->retrievePosition(getWorldPos()); if (gpos.InstanceId != -1) { CVector snappedPos = GR->getGlobalPosition(gpos); // locally modify the z _WorldPos.z = snappedPos.z; //setDisplayFlag(FlagBadPos, false); } else { //setDisplayFlag(FlagBadPos, true); } visualSnapToGround(); _Touched = true; }
//********************************************************************************************************* void CInstanceMapDeco::onPreRender(CGroupMap &groupMap) { //H_AUTO(R2_CInstanceMapDeco_onPreRender) if (!_Active) return; nlassert(_Instance); if (_GlowStarActive) { if (_GlowStar[0]) { // draw glowing stars on the edge to signal position well for(uint k = 0; k < 2; ++k) { _GlowStar[k]->setActive(true); _GlowStar[k]->setQuad(_GlowStarPos, CV_MapGlowStarSize.get(), (float) (CV_MapGlowStarSpeed[k].get() * 0.001 * (double) T1)); _GlowStar[k]->updateCoords(); } } } // if (_Orient) { bool closeView = groupMap.getMeterPerPixel() < CV_MapEntityCloseDist.get(); CDisplayerVisual *vd = _Instance->getDisplayerVisual(); if (vd) { if (_LastCloseView!= closeView) { _OrientBlendFactor = closeView ? 0.5f : 0.f; } if (vd->getRotateInProgress()) { _OrientBlendFactor = 1.f; } else { // fade to default alpha NLMISC::incrementalBlend(_OrientBlendFactor, closeView ? 0.5f : 0.f, DT * 1000.f / favoid0(CV_MapEntityOrientBlendTimeInMs.get())); } } else { _OrientBlendFactor = 0.f; } if (_OrientBlendFactor == 0.f) { _Orient->setActive(false); } else { _Orient->setActive(true); _Orient->setColorRGBA(CRGBA(255, 255, 255, (uint8) (255 * _OrientBlendFactor))); CVector2f worldPos = getWorldPos(); sint32 x; sint32 y; groupMap.worldToWindowSnapped(x, y, getWorldPos()); _Orient->setQuad(CV_MapEntityOrientTexture.get(), CVector((float) x, (float) y, 0.f), vd->getAngle(), closeView ? CV_MapEntityOrientOriginDist.get() : CV_MapEntityOrientOriginDistSmall.get()); _Orient->updateCoords(); } _LastCloseView = closeView; } if (_OverInvalid->getActive()) { _OverInvalid->setColorRGBA(CTool::getInvalidPosColor()); } }
void Actor::draw() { for (Common::List<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); ++i) { Costume *c = *i; c->setupTextures(); } if (!g_driver->isHardwareAccelerated() && g_grim->getFlagRefreshShadowMask()) { for (int l = 0; l < MAX_SHADOWS; l++) { if (!_shadowArray[l].active) continue; g_driver->setShadow(&_shadowArray[l]); g_driver->drawShadowPlanes(); g_driver->setShadow(NULL); } } // FIXME: if isAttached(), factor in the joint & actor rotation as well. Math::Vector3d absPos = getWorldPos(); if (!_costumeStack.empty()) { g_grim->getCurrSet()->setupLights(absPos); Costume *costume = _costumeStack.back(); for (int l = 0; l < MAX_SHADOWS; l++) { if (!shouldDrawShadow(l)) continue; g_driver->setShadow(&_shadowArray[l]); g_driver->setShadowMode(); if (g_driver->isHardwareAccelerated()) g_driver->drawShadowPlanes(); g_driver->startActorDraw(absPos, _scale, _yaw, _pitch, _roll, _inOverworld, _alphaMode != AlphaOff ? _globalAlpha : 1.f); costume->draw(); g_driver->finishActorDraw(); g_driver->clearShadowMode(); g_driver->setShadow(NULL); } bool isShadowCostume = costume->getFilename().equals("fx/dumbshadow.cos"); if (!isShadowCostume || _shadowActive) { // normal draw actor g_driver->startActorDraw(absPos, _scale, _yaw, _pitch, _roll, _inOverworld, _alphaMode != AlphaOff ? _globalAlpha : 1.f); costume->draw(); g_driver->finishActorDraw(); } } if (_mustPlaceText) { int x1, y1, x2, y2; x1 = y1 = 1000; x2 = y2 = -1000; if (!_costumeStack.empty()) { g_driver->startActorDraw(absPos, _scale, _yaw, _pitch, _roll, _inOverworld, 1.f); _costumeStack.back()->getBoundingBox(&x1, &y1, &x2, &y2); g_driver->finishActorDraw(); } TextObject *textObject = TextObject::getPool().getObject(_sayLineText); if (textObject) { if (x1 == 1000 || x2 == -1000 || y2 == -1000) { textObject->setX(640 / 2); textObject->setY(463); } else { textObject->setX((x1 + x2) / 2); textObject->setY(y1); } textObject->reset(); } _mustPlaceText = false; } }
Fire::Fire(int _typeID,Entity* _owner,unsigned int _uniqueId) { setOwner(_owner); setWorldPos(getOwner()->getPosition()); setUniqueID(_uniqueId); setWorldPos(_owner->getPosition()); setVelocity(Vector2(300,300)); setTypeID(_typeID); setDestoryed(false); if(_owner->getTypeID() == Player_User) { switch(_owner->returnDirection()) { case Attack_Animation_East: setVelocity(Vector2(300,0)); break; case Attack_Animation_West: setVelocity(Vector2(-300,0)); break; case Attack_Animation_North: setVelocity(Vector2(0,-300)); break; case Attack_Animation_South: setVelocity(Vector2(0,300)); break; case Attack_Animation_NorthWest: setVelocity(Vector2(-300,-300)); break; case Attack_Animation_NorthEast: setVelocity(Vector2(300,-300)); break; case Attack_Animation_SouthWest: setVelocity(Vector2(-300,300)); break; case Attack_Animation_SouthEast: setVelocity(Vector2(300,300)); break; } } if(_typeID == Spell_Fireball) { setDamage(5); setDamageOverTime(1); setDamageTime(3); setAOEDamage(0); setAOERange(0); setManaCost(2); setRange(800); setCollsionRect(Rect2(getWorldPos().X,getWorldPos().Y,32,32)); #ifdef CLIENT Emitter * spellTemp = new Emitter(*Emitter::emittersBluePrint[Particle_Fireball]); setSpellEffect(spellTemp); #endif } else if(_typeID == Spell_Phoenix) { setDamage(8); setDamageOverTime(1); setDamageTime(5); setAOEDamage(3); setAOERange(100); setManaCost(4); setRange(800); setCollsionRect(Rect2(getWorldPos().X-16,getWorldPos().Y-16,32,32)); #ifdef CLIENT Emitter * spellTemp = new Emitter(*Emitter::emittersBluePrint[Particle_FireDestroyed]); setSpellEffect(spellTemp); #endif } else if(_typeID == Spell_Diablo) { setDamage(12); setDamageOverTime(2); setDamageTime(5); setAOEDamage(7); setAOERange(200); setManaCost(8); setRange(800); setLevel(3); setCollsionRect(Rect2(getWorldPos().X-32,getWorldPos().Y-32,64,64)); #ifdef CLIENT Emitter * spellTemp = new Emitter(*Emitter::emittersBluePrint[Particle_FireDestroyed]); setSpellEffect(spellTemp); #endif } }
// ********************************************************************************************************* void CDisplayerVisualShape::onPreRender() { //H_AUTO(R2_CDisplayerVisualShape_onPreRender) if (SkipFrame != 0) { // a tp was done -> invalidate visual collision entity deleteVisualCollisionEntity(); } if (!_Instance.empty()) { bool inIsland = false; CIslandCollision &col = getEditor().getIslandCollision(); R2::CScenarioEntryPoints::CCompleteIsland *currIsland = col.getCurrIslandDesc(); if (currIsland) { inIsland = currIsland->isIn(getWorldPos2f()); } if (getActualVisibility() && inIsland) { _Instance.show(); if (_WorldMapDisplay && !_MapDeco.getActive()) { _MapDeco.setActive(true); _Touched = true; } } else { _Instance.hide(); _MapDeco.setActive(false); } } if (!getActualVisibility()) return; if (_BadShapeName) return; if (_Active) { if (testNeedZEval()) _VisualSnapToGroundDone = false; if (!_VisualSnapToGroundDone && SkipFrame == 0) { snapToGround(); // force visual snap to ground if not already done + icon update } } if (!_Touched) { if (!_Instance.empty()) _BBoxMatrix = _Instance.getMatrix(); else _BBoxMatrix = CMatrix::Identity; return; } if (_Active) { updateMapDeco(); if (_Instance.empty()) { sint64 startTime = 0; static volatile bool bench = false; if (bench) { startTime = CTime::getPerformanceTime(); } _Instance = Scene->createInstance(_ShapeName); if (bench) { sint64 endTime = CTime::getPerformanceTime(); nlwarning("clip time = %.2f ms", 1000.f * CTime::ticksToSecond(endTime - startTime)); } if (_Instance.empty()) { _BadShapeName = true; return; } _Instance.setTransformMode(NL3D::UTransform::DirectMatrix); _Instance.enableCastShadowMap(true); } CMatrix instanceMat; instanceMat.setScale(_Scale); instanceMat.setPos(getWorldPos().asVector()); _Instance.setMatrix(instanceMat); _VisualSnapToGroundDone = false; visualSnapToGround(); // force visual snap to ground if not already done } else { if (!_Instance.empty()) { Scene->deleteInstance(_Instance); } } if (!_Instance.empty()) { _BBoxMatrix = _Instance.getMatrix(); // ensure that bbox and shape displayed at same pos // (events that modify the instance pos may be received after the display of this frame) } _MapDeco.setInvalidPosFlag(getDisplayFlag(FlagBadPos)); _Touched = false; }
//********************************************************************************************************* void CInstanceMapDeco::onUpdate(CGroupMap &groupMap) { //H_AUTO(R2_CInstanceMapDeco_onUpdate) if (!_Active) return; nlassert(_Instance); _GlowStarActive = false; if (!_Main || !_Over || !_OverInvalid) return; sint32 x; sint32 y; CVector2f worldPos = getWorldPos(); // if not in current map then don't disply anything CIslandCollision &col = getEditor().getIslandCollision(); R2::CScenarioEntryPoints::CCompleteIsland *currIsland = col.getCurrIslandDesc(); if (currIsland) { if (!currIsland->isIn(worldPos)) { setActive(false); return; } } groupMap.worldToWindowSnapped(x, y, getWorldPos()); _Main->setX(x); _Main->setY(y); CDisplayerVisual *vd = _Instance->getDisplayerVisual(); if (!vd) { _Over->setActive(false); _OverInvalid->setActive(false); return; } // bool closeView = _CloseTexture.empty() ? false : groupMap.getMeterPerPixel() < CV_MapEntityCloseDist.get(); // bool selected = vd->getDisplayFlag(CDisplayerVisual::FlagSelected); bool hasFocus = vd->getDisplayFlag(CDisplayerVisual::FlagHasFocus); // setTextureAndFit(closeView ? _CloseTexture : CV_MapEntitySmallTexture.get()); _Main->setColor((selected && ! closeView) ? CV_MapEntitySelectColor.get() : vd->getDisplayModeColorInMap()); // if small icon, then change the icon color directly, because no over will be displayed // if (selected || hasFocus) { // if the selection is out of the window, then draw an arrow to locate it const CVector2f &wmin = groupMap.getVisibleWorldMin(); const CVector2f &wmax = groupMap.getVisibleWorldMax(); if (worldPos.x < wmin.x || worldPos.x > wmax.x || worldPos.y < wmin.y || worldPos.y > wmax.y) { // OUT OF VISIBLE REGION CASE _Over->setActive(true); _Over->setColorRGBA(selected ? CV_MapEntitySelectColor.get() : CV_MapEntityHighlightColor.get()); // out of the visible portion, so draw an arrow instead _Over->setTexture(CV_MapEntityFarTexture.get()); // snap position to inner visible world rect CVector2f m = 0.5f * (wmin + wmax); CVector2f dir = worldPos - m; CVector2f inter; float d0; float d1; if (dir.x > 0.f) { d0 = (wmax.x - m.x) / dir.x; if (dir.y > 0.f) { d1 = (wmax.y - m.y) / dir.y; inter = m + std::min(d0, d1) * dir; } else if (dir.y < 0.f) { d1 = (wmin.y - m.y) / dir.y; inter = m + std::min(d0, d1) * dir; } else { inter.set(wmax.x, m.y); } } else if (dir.x < 0.f) { d0 = (wmin.x - m.x) / dir.x; if (dir.y > 0.f) { d1 = (wmax.y - m.y) / dir.y; inter = m + std::min(d0, d1) * dir; } else if (dir.y < 0.f) { d1 = (wmin.y - m.y) / dir.y; inter = m + std::min(d0, d1) * dir; } else { inter.set(wmin.x, m.y); } } else { if (dir.y > 0.f) { inter.set(m.x, wmax.y); } else if (dir.y < 0.f) { inter.set(m.x, wmin.y); } else { inter = m; } } float size = CV_MapEntityFarArrowSize.get(); // TMP TMP size = size; float bias = 1.f; dir.normalize(); CVector2f winInter; groupMap.worldToWindow(winInter, inter); _Over->setRenderLayer(3); _Over->setQuad(winInter - (size + bias) * dir, winInter - bias * dir, 0.5f * size); // if (_GlowStar[0]) { sint32 screenInterX, screenInterY; groupMap.windowToScreen(screenInterX, screenInterY, (sint32) winInter.x, (sint32) winInter.y); sint32 refCornerX, refCornerY; _GlowStar[0]->getParent()->getCorner(refCornerX, refCornerY, Hotspot_BL); _GlowStarPos.set((float) (screenInterX - refCornerX), (float) (screenInterY - refCornerY), 0.f); _GlowStarActive = true; } } else { // VISIBLE CASE _GlowStar[0]->setActive(false); _GlowStar[1]->setActive(false); if (closeView || hasFocus) { _Over->setActive(true); if (!closeView) { _Over->setColorRGBA(CV_MapEntitySelectColor.get()); } else { _Over->setColorRGBA(selected ? CV_MapEntitySelectColor.get() : CV_MapEntityHighlightColor.get()); } const std::string &tex = closeView ? CV_MapEntitySelectTexture.get() : CV_MapEntitySmallHighlightTexture.get(); _Over->setTexture(tex); _Over->setRenderLayer(2); _Over->setQuad(tex, CVector((float) x, (float) y, 0.f)); } else { _Over->setActive(false); } } } else { // no focus _Over->setActive(false); _GlowStar[0]->setActive(false); _GlowStar[1]->setActive(false); } // update 'quad that signal invalid pos' if (_OverInvalid->getActive()) { const std::string &tex = closeView ? CV_MapEntityInvalidTexture.get() : CV_MapEntityInvalidTextureSmall.get(); _OverInvalid->setTexture(tex); _OverInvalid->setQuad(tex, CVector((float) x, (float) y, 0.f)); } }