📄 map.cpp
字号:
later[laterCount].creature = creature; later[laterCount].projectile = NULL; later[laterCount].effect = NULL; later[laterCount].name = name; laterCount++; } }}void Map::drawDraggedItem() { if(scourge->getMovingItem()) { // glDisable(GL_DEPTH_TEST); // glDepthMask(GL_FALSE); glPushMatrix(); glLoadIdentity(); glTranslatef( scourge->getSDLHandler()->mouseX, scourge->getSDLHandler()->mouseY, 500); glRotatef( xrot, 0.0f, 1.0f, 0.0f ); glRotatef( yrot, 1.0f, 0.0f, 0.0f ); glRotatef( zrot, 0.0f, 0.0f, 1.0f ); doDrawShape(0, 0, 0, scourge->getMovingItem()->getShape(), 0); glPopMatrix(); // glEnable(GL_DEPTH_TEST); //glDepthMask(GL_TRUE); } /* float xpos2, ypos2, zpos2; Shape *shape = NULL; if(selX >= getX() && selX < getX() + MAP_VIEW_WIDTH && selY >= getY() && selY < getY() + MAP_VIEW_DEPTH && selZ < MAP_VIEW_HEIGHT && scourge->getMovingItem()) { shape = scourge->getMovingItem()->getShape(); int newz = selZ; Location *dropLoc = isBlocked(selX, selY, selZ, -1, -1, -1, shape, &newz); selZ = newz; // only let drop on other creatures and containers // unfortunately I have to call isWallBetween(), so objects aren't dragged behind walls // this makes moving items slow if(dropLoc || (oldLocatorSelX < MAP_WIDTH && isWallBetween(selX, selY, selZ, oldLocatorSelX, oldLocatorSelY, oldLocatorSelZ))) { selX = oldLocatorSelX; selY = oldLocatorSelY; selZ = oldLocatorSelZ; } xpos2 = ((float)(selX - getX()) / GLShape::DIV); ypos2 = (((float)(selY - getY() - 1) - (float)shape->getDepth()) / GLShape::DIV); zpos2 = (float)(selZ) / GLShape::DIV; doDrawShape(xpos2, ypos2, zpos2, shape, 0); oldLocatorSelX = selX; oldLocatorSelY = selY; oldLocatorSelZ = selZ; } */}void Map::draw() { if(zoomIn) { if(zoom <= 0.5f) { zoomOut = false; } else { zoom /= ZOOM_DELTA; xpos = (int)((float)scourge->getSDLHandler()->getScreen()->w / zoom / 2.0f); ypos = (int)((float)scourge->getSDLHandler()->getScreen()->h / zoom / 2.0f); } } else if(zoomOut) { if(zoom >= 2.8f) { zoomOut = false; } else { zoom *= ZOOM_DELTA; xpos = (int)((float)scourge->getSDLHandler()->getScreen()->w / zoom / 2.0f); ypos = (int)((float)scourge->getSDLHandler()->getScreen()->h / zoom / 2.0f); } } // remove area effects vector<EffectLocation*>::iterator e=currentEffects.begin(); for(int i = 0; i < (int)currentEffects.size(); i++) { EffectLocation *effectLocation = currentEffects[i]; if(effectLocation && !effectLocation->isEffectOn()) { currentEffects.erase(e); e = currentEffects.begin(); removeEffect(effectLocation->x, effectLocation->y, effectLocation->z); mapChanged = true; i--; } } float oldrot; oldrot = yrot; if(yRotating != 0) yrot+=yRotating; if(yrot >= 55 || yrot < 0) yrot = oldrot; oldrot = zrot; if(zRotating != 0) zrot+=zRotating; if(zrot >= 360) zrot -= 360; if(zrot < 0) zrot = 360 + zrot; initMapView(); if(lightMapChanged) configureLightMap(); // populate the shape arrays if(mapChanged) setupShapes(false); if(selectMode) { for(int i = 0; i < otherCount; i++) doDrawShape(&other[i]); } else { #ifdef DEBUG_MOUSE_POS // debugging mouse position if(debugX < MAP_WIDTH && debugX >= 0) { DrawLater later2; later2.shape = scourge->getShapePalette()->findShapeByName("LAMP_BASE"); later2.xpos = ((float)(debugX - getX()) / GLShape::DIV); later2.ypos = (((float)(debugY - getY() - 1) - (float)((later2.shape)->getDepth())) / GLShape::DIV); later2.zpos = (float)(debugZ) / GLShape::DIV; later2.item = NULL; later2.creature = NULL; later2.projectile = NULL; later2.name = 0; doDrawShape(&later2); }#endif // draw the creatures/objects/doors/etc. for(int i = 0; i < otherCount; i++) { if(selectedDropTarget && ((selectedDropTarget->creature && selectedDropTarget->creature == other[i].creature) || (selectedDropTarget->item && selectedDropTarget->item == other[i].item))) { colorAlreadySet = true; glColor4f(0, 1, 1, 1); } doDrawShape(&other[i]); } if(scourge->getUserConfiguration()->getStencilbuf() && scourge->getUserConfiguration()->getStencilBufInitialized()) { // create a stencil for the walls glDisable(GL_DEPTH_TEST); glColorMask(0,0,0,0); glEnable(GL_STENCIL_TEST); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); glStencilFunc(GL_ALWAYS, 1, 0xffffffff); for(int i = 0; i < stencilCount; i++) doDrawShape(&stencil[i]); // Use the stencil to draw glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glEnable(GL_DEPTH_TEST); // decr where the floor is (results in a number = 1) glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, 0, 0xffffffff); // draw if stencil=0 // draw the ground setupShapes(true); // shadows if(scourge->getUserConfiguration()->getShadows() >= Constants::OBJECT_SHADOWS) { glStencilFunc(GL_EQUAL, 0, 0xffffffff); // draw if stencil=0 // GL_INCR makes sure to only draw shadow once glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); glDisable(GL_TEXTURE_2D); glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); useShadow = true; if(scourge->getUserConfiguration()->getShadows() == Constants::ALL_SHADOWS) { for(int i = 0; i < stencilCount; i++) { doDrawShape(&stencil[i]); } } for(int i = 0; i < otherCount; i++) { doDrawShape(&other[i]); } useShadow = false; glDisable(GL_BLEND); glEnable(GL_TEXTURE_2D); glDepthMask(GL_TRUE); } glDisable(GL_STENCIL_TEST); // draw the blended walls glEnable(GL_BLEND); glDepthMask(GL_FALSE); //glDisable(GL_LIGHTING); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); for(int i = 0; i < stencilCount; i++) doDrawShape(&stencil[i]); //glEnable(GL_LIGHTING); glDepthMask(GL_TRUE); glDisable(GL_BLEND); } else { // draw the walls for(int i = 0; i < stencilCount; i++) doDrawShape(&stencil[i]); // draw the ground setupShapes(true); } // draw the effects glEnable(GL_BLEND); glDepthMask(GL_FALSE); // glDisable(GL_LIGHTING); for(int i = 0; i < laterCount; i++) { later[i].shape->setupBlending(); doDrawShape(&later[i]); later[i].shape->endBlending(); } glBlendFunc(GL_SRC_ALPHA, GL_ONE); for(int i = 0; i < damageCount; i++) { doDrawShape(&damage[i], 1); } drawShade(); // glEnable(GL_LIGHTING); glDepthMask(GL_TRUE); glDisable(GL_BLEND); // draw the projectiles DrawLater dl; vector<Projectile*> removedProjectiles; map<Projectile*, Creature*> battleProjectiles; map<Creature *, vector<Projectile*>*> *proj = Projectile::getProjectileMap(); for(map<Creature *, vector<Projectile*>*>::iterator i=proj->begin(); i!=proj->end(); ++i) { //Creature *creature = i->first; vector<Projectile*> *p = i->second; for(vector<Projectile*>::iterator e=p->begin(); e!=p->end(); ++e) { Projectile *proj = *e; // draw it dl.xpos = ((proj->getX() - (float)getX()) / GLShape::DIV); // dl.ypos = (((float)(proj->getY() - getY() - 1) - (float)((later2.shape)->getDepth())) / GLShape::DIV); dl.ypos = ((proj->getY() - (float)getY() - 1.0f) / GLShape::DIV); dl.zpos = (float)(7) / GLShape::DIV; dl.shape = proj->getShape(); dl.creature = NULL; dl.item = NULL; dl.projectile = proj; dl.name = 0; if(proj->getSpell()) { glEnable(GL_BLEND); glDepthMask(GL_FALSE); proj->getShape()->setupBlending(); } doDrawShape(&dl); if(proj->getSpell()) { proj->getShape()->endBlending(); glDisable(GL_BLEND); glDepthMask(GL_TRUE); } // collision detection bool blocked = false; Location *loc = getLocation((int)proj->getX(), (int)proj->getY(), 0); if(loc && proj->doesStopOnImpact()) { if(loc->creature && proj->getCreature()->isMonster() != loc->creature->isMonster()) { // attack monster //Battle::projectileHitTurn(scourge, proj, loc->creature); battleProjectiles[proj] = loc->creature; blocked = true; } else if((loc->item && loc->item->getShape()->getHeight() >= 6) || (!loc->creature && !loc->item && loc->shape && loc->shape->getHeight() >= 6)) { // hit something blocked = true; } if(blocked) { removedProjectiles.push_back(proj); } } } } // fight battles for(map<Projectile*, Creature*>::iterator i=battleProjectiles.begin(); i!=battleProjectiles.end(); ++i) { Projectile *proj = i->first; Creature *creature = i->second; Battle::projectileHitTurn(scourge, proj, creature); } // remove projectiles for(vector<Projectile*>::iterator e=removedProjectiles.begin(); e!=removedProjectiles.end(); ++e) { Projectile::removeProjectile(*e); } if(scourge->getTargetSelectionFor()) { glPushMatrix(); glLoadIdentity(); glDisable(GL_DEPTH_TEST); //glDepthMask(GL_FALSE); glColor3f( 1, 1, 0.15f ); scourge->getSDLHandler()->texPrint( 10, scourge->getSDLHandler()->getScreen()->h - 10, "Select a target for %s.", scourge->getTargetSelectionFor()->getName() ); glEnable(GL_DEPTH_TEST); //glDepthMask(GL_TRUE); glPopMatrix(); } //drawDraggedItem(); }}void Map::drawShade() { glPushMatrix(); glLoadIdentity(); // glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); //glDisable( GL_TEXTURE_2D ); glBlendFunc(GL_DST_COLOR, GL_ZERO); //scourge->setBlendFunc(); glColor4f( 1, 1, 1, 0.5f); glBindTexture( GL_TEXTURE_2D, overlay_tex ); glBegin( GL_QUADS ); // glNormal3f(0.0f, 1.0f, 0.0f); glTexCoord2f( 0.0f, 0.0f ); glVertex3f(0, 0, 0); glTexCoord2f( 0.0f, 1.0f ); glVertex3f(0, scourge->getSDLHandler()->getScreen()->h, 0); glTexCoord2f( 1.0f, 1.0f ); glVertex3f(scourge->getSDLHandler()->getScreen()->w, scourge->getSDLHandler()->getScreen()->h, 0); glTexCoord2f( 1.0f, 0.0f ); glVertex3f(scourge->getSDLHandler()->getScreen()->w, 0, 0); glEnd(); //glEnable( GL_TEXTURE_2D ); glEnable(GL_DEPTH_TEST); glPopMatrix();}void Map::createOverlayTexture() { // create the dark texture unsigned int i, j; glGenTextures(1, (GLuint*)&overlay_tex);// float tmp = 0.7f; for(i = 0; i < OVERLAY_SIZE; i++) { for(j = 0; j < OVERLAY_SIZE; j++) { float half = ((float)OVERLAY_SIZE - 0.5f) / 2.0f; float id = (float)i - half; float jd = (float)j - half; float dd = 255.0f - ((255.0f / (half * half / 1.2f)) * (id * id + jd * jd)); if(dd < 0.0f) dd = 0.0f; if(dd > 255.0f) dd = 255.0f; unsigned char d = (unsigned char)dd; overlay_data[i * OVERLAY_SIZE * 3 + j * 3 + 0] = d; overlay_data[i * OVERLAY_SIZE * 3 + j * 3 + 1] = d; overlay_data[i * OVERLAY_SIZE * 3 + j * 3 + 2] = d; } } glBindTexture(GL_TEXTURE_2D, overlay_tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexImage2D(GL_TEXTURE_2D, 0, 3, OVERLAY_SIZE, OVERLAY_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, overlay_data);}void Map::doDrawShape(DrawLater *later, int effect) { doDrawShape(later->xpos, later->ypos, later->zpos, later->shape, later->name, effect, later);}void Map::doDrawShape(float xpos2, float ypos2, float zpos2, Shape *shape, GLuint name, int effect, DrawLater *later) { glPushMatrix(); if(useShadow) { // put shadow above the floor a little glTranslatef( xpos2, ypos2, 0.26f / GLShape::DIV); glMultMatrixf(shadowTransformMatrix); glColor4f( 0, 0, 0, 0.5f ); // FIXME: this is a nicer shadow color, but it draws outside the walls too. // need to fix the stencil ops to restrict shadow drawing to the floor. //glColor4f( 0.04f, 0, 0.07f, 0.6f ); ((GLShape*)shape)->useShadow = true; } else { glTranslatef( xpos2, ypos2, zpos2); if(colorAlreadySet) { colorAlreadySet = false; } else { glColor4f(0.72f, 0.65f, 0.55f, 0.5f); } } // encode this shape's map location in its name glPushName( name ); //glPushName( (GLuint)((GLShape*)shape)->getShapePalIndex() ); if(shape) { ((GLShape*)shape)->setCameraRot(xrot, yrot, zrot); ((GLShape*)shape)->setCameraPos(xpos, ypos, zpos, xpos2, ypos2, zpos2); } if(effect && later) { if(later->creature) { later->creature->getEffect()->draw(later->creature->getEffectType(), later->creature->getDamageEffect()); } else if(later->effect) { later->effect->getEffect()->draw(later->effect->getEffectType(), later->effect->getDamageEffect()); } } else if(later && later->projectile) { // orient and draw the projectile float f = later->projectile->getAngle() + 90; if(f < 0) f += 360; if(f >= 360) f -= 360; glRotatef( f, 0, 0, 1 ); // for projectiles, set the correct camera angle if(later->projectile->getAngle() < 90) { ((GLShape*)shape)->setCameraRot(xrot, yrot, zrot + later->projectile->getAngle() + 90); } else if(later->projectile->getAngle() < 180) { ((GLShape*)shape)->setCameraRot(xrot, yrot, zrot - later->projectile->getAngle()); } later->projectile->getShape()->draw(); } else { shape->draw(); } if(shape) ((GLShape*)shape)->useShadow = false; glPopName(); glPopMatrix();} void Map::showInfoAtMapPos(Uint16 mapx, Uint16 mapy, Uint16 mapz, char *message) { float xpos2 = ((float)(mapx - getX()) / GLShape::DIV); float ypos2 = ((float)(mapy - getY()) / GLShape::DIV); float zpos2 = (float)(mapz) / GLShape::DIV; glTranslatef( xpos2, ypos2, zpos2 + 100); //glColor4f(1.0f, 1.0f, 1.0f, 1.0f); //glRasterPos2f( 0, 0 ); scourge->getSDLHandler()->texPrint(0, 0, "%s", message); glTranslatef( -xpos2, -ypos2, -(zpos2 + 100));}void Map::showCreatureInfo(Creature *creature, bool player, bool selected, bool groupMode) { glPushMatrix(); //showInfoAtMapPos(creature->getX(), creature->getY(), creature->getZ(), creature->getName()); glEnable( GL_DEPTH_TEST ); glDepthMask(GL_FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -