void Block::DrawPixel(int drawx, int drawy) { ALLEGRO_COLOR temp; if( tileShapeBasic==tiletype_shape_basic::Floor || tileShapeBasic==tiletype_shape_basic::Wall || tileShapeBasic==tiletype_shape_basic::Ramp || tileShapeBasic==tiletype_shape_basic::Stair ) { al_put_pixel(drawx, drawy, lookupMaterialColor(this->material.type, this->material.index)); } if(this->water.index) { if(this->water.type == 0) //water al_draw_pixel(drawx, drawy, al_map_rgba_f(0.6f, 0.85f, 0.92f, (float)water.index / 7.0f)); else al_draw_pixel(drawx, drawy, al_map_rgba_f(1.0f, 0.5f, 0.15f, (float)water.index / 7.0f)); } //Grass if(grasslevel > 0 && ( (tileMaterial == tiletype_material::GRASS_DARK) || (tileMaterial == tiletype_material::GRASS_DARK) || (tileMaterial == tiletype_material::GRASS_DRY) || (tileMaterial == tiletype_material::GRASS_DEAD))) { temp = lookupMaterialColor(WOOD, grassmat); al_draw_pixel(drawx, drawy, al_map_rgba_f(temp.r,temp.g, temp.b, (float)grasslevel/100.0f)); } }
ALLEGRO_COLOR getSpriteColor(t_SpriteWithOffset &sprite, t_matglossPair material, t_matglossPair layerMaterial, t_matglossPair veinMaterial) { int matFore = lookupMaterialFore(material.type, material.index); int matBright = lookupMaterialBright(material.type, material.index); int matBack = lookupMaterialBack(material.type, material.index); int layerFore = lookupMaterialFore(material.type, layerMaterial.index); int layerBright = lookupMaterialBright(material.type, layerMaterial.index); int layerBack = lookupMaterialBack(material.type, layerMaterial.index); int veinFore = lookupMaterialFore(material.type, veinMaterial.index); int veinBright = lookupMaterialBright(material.type, veinMaterial.index); int veinBack = lookupMaterialBack(material.type, veinMaterial.index); switch(sprite.shadeBy) { case ShadeNone: return al_map_rgb(255, 255, 255); case ShadeXml: return sprite.shadeColor; case ShadeMat: return lookupMaterialColor(material.type, material.index); case ShadeLayer: return lookupMaterialColor(layerMaterial.type, layerMaterial.index); case ShadeVein: return lookupMaterialColor(veinMaterial.type, veinMaterial.index); case ShadeMatFore: return getDfColor(matFore, matBright); case ShadeMatBack: return getDfColor(matBack); case ShadeLayerFore: return getDfColor(layerFore, layerBright); case ShadeLayerBack: return getDfColor(layerBack); case ShadeVeinFore: return getDfColor(veinFore, veinBright); case ShadeVeinBack: return getDfColor(veinBack); default: return al_map_rgb(255, 255, 255); } ; }
/** * Reads the spatter types and colors from the DF vector 'splatter' at local * position 'lx','ly' into the stonesense Tile 'b'. */ void readSpatterToTile(Tile * b, uint32_t lx, uint32_t ly, const vector <df::block_square_event_material_spatterst * > & splatter) { b->mudlevel = 0; b->snowlevel = 0; b->bloodlevel = 0; if(ssConfig.bloodcutoff < UCHAR_MAX) { long red=0; long green=0; long blue=0; long blood=0; long snow=0; for(int i = 0; i < splatter.size(); i++) { if(!splatter[i]->amount[lx][ly]) { continue; } uint8_t level = (uint8_t)splatter[i]->amount[lx][ly]; ALLEGRO_COLOR tempBlood = al_map_rgb(255,255,255); //try to get the blood/snow tint MaterialInfo mat; switch(splatter[i]->mat_type){ case MUD: break; case ICE: //ice and snow are white (default), water is blue if(splatter[i]->mat_state != df::matter_state::Powder && splatter[i]->mat_state != df::matter_state::Solid ) { tempBlood = lookupMaterialColor(splatter[i]->mat_type, -1); } break; case VOMIT: tempBlood = lookupMaterialColor(splatter[i]->mat_type, -1); break; default: tempBlood = lookupMaterialColor(splatter[i]->mat_type, splatter[i]->mat_index, al_map_rgb(128,128,128)); } if(splatter[i]->mat_type != MUD) { red += (tempBlood.r * 255 * level); green += (tempBlood.g * 255 * level); blue += (tempBlood.b * 255 * level); } //use the state information to determine if we should be incrementing the snow or the blood int16_t state = splatter[i]->mat_state; state = splatter[i]->mat_type == MUD ? INVALID_INDEX : state; state = splatter[i]->mat_type == VOMIT ? df::matter_state::Paste : state; //change vomit from dust to paste - gross switch(state) { case INVALID_INDEX: b->mudlevel = level; break; case df::matter_state::Powder: case df::matter_state::Solid: snow += level; break; default: blood += level; } } blood = blood<0 ? 0-blood : blood; snow = snow<0 ? 0-snow : snow; int total = blood + snow; if(blood || snow) { if(snow > blood) { b->bloodcolor = al_map_rgb(red/total, green/total, blue/total); } else { b->bloodcolor = al_map_rgba(red/total, green/total, blue/total, (total > ssConfig.bloodcutoff) ? 255 : total*255/ssConfig.bloodcutoff); } b->snowlevel = snow>UCHAR_MAX ? UCHAR_MAX : snow; b->bloodlevel = blood>UCHAR_MAX ? UCHAR_MAX : blood; } else { b->bloodcolor = al_map_rgba(0,0,0,0); } } else { b->bloodcolor = al_map_rgb(150, 0, 24); } }
void Block::Draw() { if(!visible) return; if((material.type == INORGANIC) && (material.index == -1)) { material.index = 0; } if((!(this->designation.bits.hidden) || config.show_hidden_blocks) && config.block_count) { config.tilecount ++; } bool defaultSnow = 1; t_SpriteWithOffset sprite; c_sprite* spriteobject; /*if(config.hide_outer_blocks){ if(x == ownerSegment->x || x == ownerSegment->x + ownerSegment->sizex - 1) return; if(y == ownerSegment->y || y == ownerSegment->y + ownerSegment->sizey - 1) return; }*/ drawx = x; drawy = y; drawz = z; //- ownerSegment->sizez + 1; correctBlockForSegmetOffset( drawx, drawy, drawz); correctBlockForRotation( drawx, drawy, drawz, ownerSegment->rotation); pointToScreen((int*)&drawx, (int*)&drawy, drawz); drawx -= (TILEWIDTH>>1)*config.scale; if(((drawx + TILEWIDTH*config.scale) < 0) || (drawx > al_get_bitmap_width(al_get_target_bitmap())) || ((drawy + (TILEHEIGHT + FLOORHEIGHT)*config.scale) < 0) || (drawy - WALLHEIGHT*config.scale > al_get_bitmap_height(al_get_target_bitmap()))) return; bool chopThisBlock = 0; if(config.truncate_walls == 1) chopThisBlock = 1; else if(config.truncate_walls == 2 && obscuringCreature == 1) chopThisBlock = 1; else if(config.truncate_walls == 3 && (obscuringCreature == 1 || obscuringBuilding == 1)) chopThisBlock = 1; else if(config.truncate_walls == 4 && obscuringBuilding == 1) chopThisBlock = 1; if(building.info.type == BUILDINGTYPE_BLACKBOX) { DrawSpriteFromSheet( SPRITEOBJECT_BLACK, IMGObjectSheet, al_map_rgb(255,255,255), drawx, drawy+FLOORHEIGHT*config.scale, this); DrawSpriteFromSheet( SPRITEOBJECT_BLACK, IMGObjectSheet, al_map_rgb(255,255,255), drawx, drawy, this); return; } ALLEGRO_COLOR tileBorderColor = al_map_rgb(85,85,85); int rando = randomCube[x%RANDOM_CUBE][y%RANDOM_CUBE][z%RANDOM_CUBE]; //Draw Floor if( tileShapeBasic==tiletype_shape_basic::Floor || tileShapeBasic==tiletype_shape_basic::Wall || tileShapeBasic==tiletype_shape_basic::Ramp || tileShapeBasic==tiletype_shape_basic::Stair ) { //If tile has no floor, look for a Filler Floor from it's wall if (tileShapeBasic==tiletype_shape_basic::Floor) { spriteobject = GetFloorSpriteMap(tileType, this->material, consForm); } else if (tileShapeBasic==tiletype_shape_basic::Wall) { spriteobject = GetFloorSpriteMap(tileType, this->material, consForm); } else if (tileShapeBasic==tiletype_shape_basic::Ramp) { spriteobject = GetFloorSpriteMap(tileType, this->material, consForm); } else if (tileShapeBasic==tiletype_shape_basic::Stair) { spriteobject = GetFloorSpriteMap(tileType, this->material, consForm); } if(spriteobject->get_sheetindex() != INVALID_INDEX) { ////if floor is muddy, override regular floor //if( mudlevel && water.index == 0) //{ // sprite.sheetIndex = SPRITEFLOOR_WATERFLOOR; // sprite.fileIndex = INVALID_INDEX; //} ////if floor is snowed down, override regular floor //if( snowlevel ) //{ // sprite.sheetIndex = SPRITEFLOOR_SNOW; // sprite.fileIndex = INVALID_INDEX; // spriteOffset = 0; // al_set_separate_blender(op, src, dst, alpha_op, alpha_src, alpha_dst, color); //} if (spriteobject->get_sheetindex() == UNCONFIGURED_INDEX) { spriteobject->set_sheetindex(SPRITEOBJECT_FLOOR_NA); spriteobject->set_fileindex(INVALID_INDEX); spriteobject->set_offset(0, WALLHEIGHT); spriteobject->draw_world(x, y, z, this); } else spriteobject->draw_world(x, y, z, this); } } //Floor Engravings if((tileShapeBasic==tiletype_shape_basic::Floor) && engraving_character && engraving_flags.bits.floor) { DrawSpriteFromSheet( engraving_character, IMGEngFloorSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } //draw surf //fixme: needs to be scaled if(Eff_SeaFoam.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_SeaFoam.matt.type, Eff_SeaFoam.matt.index); tint.a*=Eff_SeaFoam.density/100.0f; al_draw_tinted_bitmap(sprite_oceanwave,tint, drawx, drawy - (WALLHEIGHT), 0); } //Draw Ramp if(tileShapeBasic==tiletype_shape_basic::Ramp){ spriteobject = GetBlockSpriteMap(tileType, material, consForm); if (spriteobject->get_sheetindex() == UNCONFIGURED_INDEX) { spriteobject->set_sheetindex(0); spriteobject->set_fileindex(INVALID_INDEX); spriteobject->set_defaultsheet(IMGRampSheet); } if (spriteobject->get_sheetindex() != INVALID_INDEX) { spriteobject->set_size(SPRITEWIDTH, SPRITEHEIGHT); spriteobject->set_tile_layout(RAMPBOTTOMTILE); spriteobject->draw_world(x, y, z, this, (chopThisBlock && this->z == ownerSegment->z + ownerSegment->sizez -2)); } spriteobject->set_tile_layout(BLOCKTILE); } drawFloorBlood ( this, drawx, drawy ); //first part of snow if(tileShapeBasic!=tiletype_shape_basic::Ramp && tileShapeBasic!=tiletype_shape_basic::Wall && tileShapeBasic!=tiletype_shape_basic::Stair && defaultSnow) { if(snowlevel > 75) { DrawSpriteFromSheet( 20, IMGObjectSheet, al_map_rgb(255,255,255), drawx, drawy, this); } else if(snowlevel > 50) { DrawSpriteFromSheet( 21, IMGObjectSheet, al_map_rgb(255,255,255), drawx, drawy, this ); } else if(snowlevel > 25) { DrawSpriteFromSheet( 22, IMGObjectSheet, al_map_rgb(255,255,255), drawx, drawy, this ); } else if(snowlevel > 0) { DrawSpriteFromSheet( 23, IMGObjectSheet, al_map_rgb(255,255,255), drawx, drawy, this ); } } ////vegetation //if(tree.index > 0 || tree.type > 0){ // c_sprite * vegetationsprite = 0; // vegetationsprite = GetSpriteVegetation( (TileClass) getVegetationType( this->floorType ), tree.index ); // if(vegetationsprite) // vegetationsprite->draw_world(x, y, z); //} //items if(Item.item.type >= 0) { if( contentLoader->itemConfigs[Item.item.type] && (Item.item.type < contentLoader->itemConfigs[Item.item.type]->subItems.size()) && contentLoader->itemConfigs[Item.item.type]->subItems[Item.item.type]) { contentLoader->itemConfigs[Item.item.type]->subItems[Item.item.type]->sprite.draw_world(x, y, z, this); } else if ( contentLoader->itemConfigs[Item.item.type] && contentLoader->itemConfigs[Item.item.type]->configured) { contentLoader->itemConfigs[Item.item.type]->default_sprite.draw_world(x, y, z, this); } else DrawSpriteFromSheet( 350, IMGObjectSheet, lookupMaterialColor(Item.matt.type, Item.matt.index, Item.dyed), drawx, (tileShapeBasic==tiletype_shape_basic::Ramp)?(drawy - ((WALLHEIGHT/2)*config.scale)):drawy , this); } //shadow if (shadow > 0) { DrawSpriteFromSheet( BASE_SHADOW_TILE + shadow - 1, IMGObjectSheet, al_map_rgb(255,255,255), drawx, (tileShapeBasic==tiletype_shape_basic::Ramp)?(drawy - ((WALLHEIGHT/2)*config.scale)):drawy , this); } //Building bool skipBuilding = (building.info.type == building_type::Civzone && !config.show_stockpiles) || (building.info.type == building_type::Stockpile && !config.show_zones); if(building.info.type != BUILDINGTYPE_NA && !skipBuilding) { for(uint32_t i=0; i < building.sprites.size(); i++) { spriteobject = &building.sprites[i]; if(building.parent) spriteobject->draw_world(x, y, z, building.parent); else spriteobject->draw_world(x, y, z, this); } } //Draw Stairs if(tileShapeBasic==tiletype_shape_basic::Stair) { bool mirrored = false; if(findWallCloseTo(ownerSegment, this) == eSimpleW) mirrored = true; //down part spriteobject = GetFloorSpriteMap(tileType, material, consForm); if(spriteobject->get_sheetindex() != INVALID_INDEX && spriteobject->get_sheetindex() != UNCONFIGURED_INDEX) { if (mirrored) spriteobject->draw_world_offset(x, y, z, this, 1); else spriteobject->draw_world(x, y, z, this); } //up part spriteobject = GetBlockSpriteMap(tileType, material, consForm); if(spriteobject->get_sheetindex() != INVALID_INDEX && spriteobject->get_sheetindex() != UNCONFIGURED_INDEX) { if (mirrored) spriteobject->draw_world_offset(x, y, z, this, 1); else spriteobject->draw_world(x, y, z, this); } } if(tileShapeBasic==tiletype_shape_basic::Wall) { //draw wall spriteobject = GetBlockSpriteMap(tileType, material, consForm); int spriteOffset = 0; if (spriteobject->get_sheetindex() == UNCONFIGURED_INDEX) { spriteobject->set_sheetindex(SPRITEOBJECT_WALL_NA); spriteobject->set_fileindex(INVALID_INDEX); spriteobject->set_tile_layout(BLOCKTILE); spriteobject->set_defaultsheet(IMGObjectSheet); } if (spriteobject->get_sheetindex() == INVALID_INDEX) { //skip } else { spriteobject->draw_world(x, y, z, this, (chopThisBlock && this->z == ownerSegment->z + ownerSegment->sizez -2)); } } //Wall Engravings if((tileShapeBasic==tiletype_shape_basic::Wall) && engraving_character) { if(ownerSegment->rotation == 0) { if(engraving_flags.bits.east) DrawSpriteFromSheet( engraving_character, IMGEngRightSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); if(engraving_flags.bits.south) DrawSpriteFromSheet( engraving_character, IMGEngLeftSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } if(ownerSegment->rotation == 1) { if(engraving_flags.bits.north) DrawSpriteFromSheet( engraving_character, IMGEngRightSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); if(engraving_flags.bits.east) DrawSpriteFromSheet( engraving_character, IMGEngLeftSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } if(ownerSegment->rotation == 2) { if(engraving_flags.bits.west) DrawSpriteFromSheet( engraving_character, IMGEngRightSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); if(engraving_flags.bits.north) DrawSpriteFromSheet( engraving_character, IMGEngLeftSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } if(ownerSegment->rotation == 3) { if(engraving_flags.bits.south) DrawSpriteFromSheet( engraving_character, IMGEngRightSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); if(engraving_flags.bits.west) DrawSpriteFromSheet( engraving_character, IMGEngLeftSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } } if(water.index > 0) { //if(waterlevel == 7) waterlevel--; if(water.type == 0) { contentLoader->water[water.index-1].sprite.draw_world(x, y, z, this, (chopThisBlock && this->z == ownerSegment->z + ownerSegment->sizez -2)); } else { contentLoader->lava[water.index-1].sprite.draw_world(x, y, z, this, (chopThisBlock && this->z == ownerSegment->z + ownerSegment->sizez -2)); } } // creature // ensure there is *some* creature according to the map data // (no guarantee it is the right one) if(creaturePresent && (config.show_hidden_blocks || !designation.bits.hidden)) { DrawCreature(drawx, drawy, creature, this); } //second part of snow if(tileShapeBasic!=tiletype_shape_basic::Wall && tileShapeBasic!=tiletype_shape_basic::Stair && defaultSnow) { if(snowlevel > 75) { DrawSpriteFromSheet( 24, IMGObjectSheet, al_map_rgb(255,255,255), drawx, drawy, this ); } else if(snowlevel > 50) { DrawSpriteFromSheet( 25, IMGObjectSheet, al_map_rgb(255,255,255), drawx, drawy, this ); } else if(snowlevel > 25) { DrawSpriteFromSheet( 26, IMGObjectSheet, al_map_rgb(255,255,255), drawx, drawy, this ); } } if(Eff_Web.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_Web.matt.type, Eff_Web.matt.index); tint.a*=Eff_Web.density/100.0f; DrawSpriteFromSheet(rando%5, sprite_webing, tint, drawx, drawy, this, 4.0f); //al_draw_tinted_bitmap(sprite_webing,tint, drawx, drawy - (WALLHEIGHT), 0); } if(Eff_Miasma.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_Miasma.matt.type, Eff_Miasma.matt.index); draw_particle_cloud(Eff_Miasma.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_miasma, tint); } if(Eff_Steam.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_Steam.matt.type, Eff_Steam.matt.index); draw_particle_cloud(Eff_Steam.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_water, tint); } if(Eff_Mist.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_Mist.matt.type, Eff_Mist.matt.index); draw_particle_cloud(Eff_Mist.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_water2, tint); } if(Eff_MaterialDust.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_MaterialDust.matt.type, Eff_MaterialDust.matt.index); draw_particle_cloud(Eff_MaterialDust.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_dust, tint); } if(Eff_MagmaMist.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_MagmaMist.matt.type, Eff_MagmaMist.matt.index); draw_particle_cloud(Eff_MagmaMist.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_magma, tint); } if(Eff_Smoke.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_Smoke.matt.type, Eff_Smoke.matt.index); draw_particle_cloud(Eff_Smoke.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_smoke, tint); } if(Eff_Dragonfire.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_Dragonfire.matt.type, Eff_Dragonfire.matt.index); tint.a*=Eff_Dragonfire.density/100.0f; tint.g*=Eff_Dragonfire.density/100.0f; tint.b*=Eff_Dragonfire.density/100.0f; int size = 3 - ((Eff_Dragonfire.density-1)/25); DrawSpriteFromSheet((((currentFrameLong+rando)%8)*20+size), sprite_dragonfire, tint, drawx, drawy, this, 2.0f); //ALLEGRO_COLOR tint = lookupMaterialColor(Eff_Dragonfire.matt.type, Eff_Dragonfire.matt.index); //draw_particle_cloud(Eff_Dragonfire.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_dragonfire, tint); } if(Eff_Fire.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_Fire.matt.type, Eff_Fire.matt.index); tint.a*=Eff_Fire.density/100.0f; tint.g*=Eff_Fire.density/100.0f; tint.b*=Eff_Fire.density/100.0f; int size = 3 - ((Eff_Fire.density-1)/25); DrawSpriteFromSheet((((currentFrameLong+rando)%8)*20+size), sprite_dragonfire, tint, drawx, drawy, this, 2.0f); //ALLEGRO_COLOR tint = lookupMaterialColor(Eff_Fire.matt.type, Eff_Fire.matt.index); //draw_particle_cloud(Eff_Fire.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_fire, tint); } if(Eff_MaterialGas.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_MaterialGas.matt.type, Eff_MaterialGas.matt.index); draw_particle_cloud(Eff_MaterialGas.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_boiling, tint); } if(Eff_MaterialVapor.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_MaterialVapor.matt.type, Eff_MaterialVapor.matt.index); draw_particle_cloud(Eff_MaterialVapor.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_boiling, tint); } if(Eff_OceanWave.density > 0) { ALLEGRO_COLOR tint = lookupMaterialColor(Eff_OceanWave.matt.type, Eff_OceanWave.matt.index); draw_particle_cloud(Eff_OceanWave.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_water, tint); } }
void Tile::AssembleTile( void ) { if(!visible) { return; } if((material.type == INORGANIC) && (material.index == -1)) { material.index = 0; } bool defaultSnow = 1; t_SpriteWithOffset sprite; c_sprite* spriteobject = 0; int32_t drawx = 0; int32_t drawy = 0; GetDrawLocation(drawx, drawy); //TODO the following check should get incorporated into segment beautification if(((drawx + TILEWIDTH*ssConfig.scale) < 0) || (drawx > ssState.ScreenW) || ((drawy + (TILETOPHEIGHT + FLOORHEIGHT)*ssConfig.scale) < 0) || (drawy - WALLHEIGHT*ssConfig.scale > ssState.ScreenH)) { visible = false; return; } bool chopThisTile = 0; if(ssConfig.truncate_walls == 1) { chopThisTile = 1; } else if(ssConfig.truncate_walls == 2 && obscuringCreature == 1) { chopThisTile = 1; } else if(ssConfig.truncate_walls == 3 && (obscuringCreature == 1 || obscuringBuilding == 1)) { chopThisTile = 1; } else if(ssConfig.truncate_walls == 4 && obscuringBuilding == 1) { chopThisTile = 1; } if(building.type == BUILDINGTYPE_BLACKBOX) { AssembleSpriteFromSheet( SPRITEOBJECT_BLACK, IMGObjectSheet, al_map_rgb(255,255,255), drawx, drawy+FLOORHEIGHT*ssConfig.scale); AssembleSpriteFromSheet( SPRITEOBJECT_BLACK, IMGObjectSheet, al_map_rgb(255,255,255), drawx, drawy); return; } ALLEGRO_COLOR plateBorderColor = al_map_rgb(85,85,85); int rando = randomCube[x%RANDOM_CUBE][y%RANDOM_CUBE][z%RANDOM_CUBE]; DrawGrowth(spriteobject, false); //Draw Ramp Tops if(tileType == tiletype::RampTop){ Tile * b = this->ownerSegment->getTile(this->x, this->y, this->z - 1); if ( b && b->building.type != BUILDINGTYPE_BLACKBOX && b->tileShapeBasic() == tiletype_shape_basic::Ramp ) { spriteobject = GetTileSpriteMap(b->tileType, b->material, b->consForm); if (spriteobject->get_sheetindex() == UNCONFIGURED_INDEX) { spriteobject->set_sheetindex(0); spriteobject->set_fileindex(INVALID_INDEX); spriteobject->set_defaultsheet(IMGRampSheet); } if (spriteobject->get_sheetindex() != INVALID_INDEX) { spriteobject->set_size(SPRITEWIDTH, TILETOPHEIGHT); spriteobject->set_plate_layout(RAMPTOPPLATE); spriteobject->set_offset(0, WALLHEIGHT); spriteobject->assemble_world_offset(x, y, z, 0, b); spriteobject->set_offset(0, 0); } spriteobject->set_plate_layout(TILEPLATE); } else { return; } } //Draw Floor if( tileShapeBasic()==tiletype_shape_basic::Floor || tileShapeBasic()==tiletype_shape_basic::Wall || tileShapeBasic()==tiletype_shape_basic::Ramp || tileShapeBasic()==tiletype_shape_basic::Stair || tileShape()==RemoteFortressReader::TWIG) { //If plate has no floor, look for a Filler Floor from it's wall if (tileShapeBasic() == tiletype_shape_basic::Floor || tileShape() == RemoteFortressReader::TWIG) { spriteobject = GetFloorSpriteMap(tileType, this->material, consForm); } else if (tileShapeBasic()==tiletype_shape_basic::Wall) { spriteobject = GetFloorSpriteMap(tileType, this->material, consForm); } else if (tileShapeBasic()==tiletype_shape_basic::Ramp) { spriteobject = GetFloorSpriteMap(tileType, this->material, consForm); } else if (tileShapeBasic()==tiletype_shape_basic::Stair) { spriteobject = GetFloorSpriteMap(tileType, this->material, consForm); } if(spriteobject->get_sheetindex() != INVALID_INDEX) { if (spriteobject->get_sheetindex() == UNCONFIGURED_INDEX) { spriteobject->set_sheetindex(SPRITEOBJECT_FLOOR_NA); spriteobject->set_fileindex(INVALID_INDEX); spriteobject->set_offset(0, WALLHEIGHT); spriteobject->assemble_world(x, y, z, this); } else { spriteobject->assemble_world(x, y, z, this); } } } //Floor Engravings if((tileShapeBasic()==tiletype_shape_basic::Floor) && engraving_character && engraving_flags.bits.floor) { AssembleSpriteFromSheet( engraving_character, IMGEngFloorSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } //Draw Ramp if(tileShapeBasic()==tiletype_shape_basic::Ramp) { spriteobject = GetTileSpriteMap(tileType, material, consForm); if (spriteobject->get_sheetindex() == UNCONFIGURED_INDEX) { spriteobject->set_sheetindex(0); spriteobject->set_fileindex(INVALID_INDEX); spriteobject->set_defaultsheet(IMGRampSheet); } if (spriteobject->get_sheetindex() != INVALID_INDEX) { spriteobject->set_size(SPRITEWIDTH, SPRITEHEIGHT); spriteobject->set_plate_layout(RAMPBOTTOMPLATE); spriteobject->assemble_world_offset(x, y, z, 0, this, (chopThisTile && this->z == ownerSegment->segState.Position.z + ownerSegment->segState.Size.z -2)); } spriteobject->set_plate_layout(TILEPLATE); } if(snowlevel <= bloodlevel) { AssembleFloorBlood ( drawx, drawy ); } //first part of snow if(tileShapeBasic()!=tiletype_shape_basic::Ramp && tileShapeBasic()!=tiletype_shape_basic::Wall && tileShapeBasic()!=tiletype_shape_basic::Stair && defaultSnow && snowlevel>bloodlevel) { if(snowlevel > 75) { AssembleSpriteFromSheet( 20, IMGObjectSheet, bloodcolor, drawx, drawy, this); } else if(snowlevel > 50) { AssembleSpriteFromSheet( 21, IMGObjectSheet, bloodcolor, drawx, drawy, this ); } else if(snowlevel > 25) { AssembleSpriteFromSheet( 22, IMGObjectSheet, bloodcolor, drawx, drawy, this ); } else if(snowlevel > 0) { AssembleSpriteFromSheet( 23, IMGObjectSheet, bloodcolor, drawx, drawy, this ); } } ////vegetation //if(tree.index > 0 || tree.type > 0){ // c_sprite * vegetationsprite = 0; // vegetationsprite = GetSpriteVegetation( (TileClass) getVegetationType( this->floorType ), tree.index ); // if(vegetationsprite) // vegetationsprite->assemble_world(x, y, z); //} //items if(Item.item.type >= 0) { if( contentLoader->itemConfigs[Item.item.type] && (Item.item.index < contentLoader->itemConfigs[Item.item.type]->subItems.size()) && contentLoader->itemConfigs[Item.item.type]->subItems[Item.item.index]) { contentLoader->itemConfigs[Item.item.type]->subItems[Item.item.index]->sprite.assemble_world(x, y, z, this); } else if ( contentLoader->itemConfigs[Item.item.type] && contentLoader->itemConfigs[Item.item.type]->configured) { contentLoader->itemConfigs[Item.item.type]->default_sprite.assemble_world(x, y, z, this); } else { AssembleSpriteFromSheet( 350, IMGObjectSheet, lookupMaterialColor(Item.matt, Item.dyematt), drawx, (tileShapeBasic()==tiletype_shape_basic::Ramp)?(drawy - ((WALLHEIGHT/2)*ssConfig.scale)):drawy , this); } } //shadow if (shadow > 0) { AssembleSpriteFromSheet( BASE_SHADOW_PLATE + shadow - 1, IMGObjectSheet, al_map_rgb(255,255,255), drawx, (tileShapeBasic()==tiletype_shape_basic::Ramp)?(drawy - ((WALLHEIGHT/2)*ssConfig.scale)):drawy , this); } //Building bool skipBuilding = (building.type == building_type::Civzone && !ssConfig.show_zones) || (building.type == building_type::Stockpile && !ssConfig.show_stockpiles); if(building.type != BUILDINGTYPE_NA && !skipBuilding) { for(uint32_t i=0; i < building.sprites.size(); i++) { spriteobject = &building.sprites[i]; if(building.parent) { spriteobject->assemble_world(x, y, z, building.parent); } else { spriteobject->assemble_world(x, y, z, this); } } } //Draw Stairs if(tileShapeBasic()==tiletype_shape_basic::Stair) { bool mirrored = false; if(findWallCloseTo(ownerSegment, this) == eSimpleW) { mirrored = true; } //down part spriteobject = GetFloorSpriteMap(tileType, material, consForm); if(spriteobject->get_sheetindex() != INVALID_INDEX && spriteobject->get_sheetindex() != UNCONFIGURED_INDEX) { if (mirrored) { spriteobject->assemble_world_offset(x, y, z, 1, this); } else { spriteobject->assemble_world(x, y, z, this); } } //up part spriteobject = GetTileSpriteMap(tileType, material, consForm); if(spriteobject->get_sheetindex() != INVALID_INDEX && spriteobject->get_sheetindex() != UNCONFIGURED_INDEX) { if (mirrored) { spriteobject->assemble_world_offset(x, y, z, 1, this); } else { spriteobject->assemble_world(x, y, z, this); } } } if(tileShapeBasic()==tiletype_shape_basic::Floor || tileShapeBasic()==tiletype_shape_basic::Wall) { //draw wall spriteobject = GetTileSpriteMap(tileType, material, consForm); int spriteOffset = 0; if (spriteobject->get_sheetindex() == UNCONFIGURED_INDEX) { if(tileShapeBasic()==tiletype_shape_basic::Wall){ spriteobject->set_sheetindex(SPRITEOBJECT_WALL_NA); spriteobject->set_fileindex(INVALID_INDEX); spriteobject->set_plate_layout(TILEPLATE); spriteobject->set_defaultsheet(IMGObjectSheet); } else { //unconfigured non-walls are not valid spriteobject->set_sheetindex(INVALID_INDEX); } } if (spriteobject->get_sheetindex() == INVALID_INDEX ) { //skip } else { spriteobject->assemble_world(x, y, z, this, (chopThisTile && this->z == ownerSegment->segState.Position.z + ownerSegment->segState.Size.z -2)); } } //Wall Engravings if((tileShapeBasic()==tiletype_shape_basic::Wall) && engraving_character) { if(ownerSegment->segState.Rotation == 0) { if(engraving_flags.bits.east) { AssembleSpriteFromSheet( engraving_character, IMGEngRightSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } if(engraving_flags.bits.south) { AssembleSpriteFromSheet( engraving_character, IMGEngLeftSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } } if(ownerSegment->segState.Rotation == 1) { if(engraving_flags.bits.north) { AssembleSpriteFromSheet( engraving_character, IMGEngRightSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } if(engraving_flags.bits.east) { AssembleSpriteFromSheet( engraving_character, IMGEngLeftSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } } if(ownerSegment->segState.Rotation == 2) { if(engraving_flags.bits.west) { AssembleSpriteFromSheet( engraving_character, IMGEngRightSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } if(engraving_flags.bits.north) { AssembleSpriteFromSheet( engraving_character, IMGEngLeftSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } } if(ownerSegment->segState.Rotation == 3) { if(engraving_flags.bits.south) { AssembleSpriteFromSheet( engraving_character, IMGEngRightSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } if(engraving_flags.bits.west) { AssembleSpriteFromSheet( engraving_character, IMGEngLeftSheet, al_map_rgba_f(1.0,1.0,1.0,((engraving_quality + 5.0f) / 10.0f)), drawx, drawy, this ); } } } DrawGrowth(spriteobject, true); if(designation.bits.flow_size > 0) { //if(waterlevel == 7) waterlevel--; uint32_t waterlevel = designation.bits.flow_size + (deepwater ? 1 : 0); if(designation.bits.liquid_type == 0) { contentLoader->water[waterlevel-1].sprite.assemble_world(x, y, z, this, (chopThisTile && this->z == ownerSegment->segState.Position.z + ownerSegment->segState.Size.z -2)); } else { contentLoader->lava[waterlevel-1].sprite.assemble_world(x, y, z, this, (chopThisTile && this->z == ownerSegment->segState.Position.z + ownerSegment->segState.Size.z -2)); } } // creature if(occ.bits.unit && creature && (ssConfig.show_hidden_tiles || !designation.bits.hidden)) { AssembleCreature(drawx, drawy, creature, this); } //second part of snow if(tileShapeBasic()!=tiletype_shape_basic::Wall && tileShapeBasic()!=tiletype_shape_basic::Stair && defaultSnow && snowlevel>bloodlevel) { if(snowlevel > 75) { AssembleSpriteFromSheet( 24, IMGObjectSheet, bloodcolor, drawx, drawy, this ); } else if(snowlevel > 50) { AssembleSpriteFromSheet( 25, IMGObjectSheet, bloodcolor, drawx, drawy, this ); } else if(snowlevel > 25) { AssembleSpriteFromSheet( 26, IMGObjectSheet, bloodcolor, drawx, drawy, this ); } } if(tileeffect.density>0) { ALLEGRO_COLOR tint = lookupMaterialColor(tileeffect.matt); int size = 0; switch(tileeffect.type){ case df::flow_type::Miasma: AssembleParticleCloud(tileeffect.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_miasma, tint); break; case df::flow_type::Steam: AssembleParticleCloud(tileeffect.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_water, tint); break; case df::flow_type::Mist: AssembleParticleCloud(tileeffect.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_water2, tint); break; case df::flow_type::MaterialDust: AssembleParticleCloud(tileeffect.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_dust, tint); break; case df::flow_type::MagmaMist: AssembleParticleCloud(tileeffect.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_magma, tint); break; case df::flow_type::Smoke: AssembleParticleCloud(tileeffect.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_smoke, tint); break; case df::flow_type::Dragonfire: tint.a*=tileeffect.density/100.0f; tint.g*=tileeffect.density/100.0f; tint.b*=tileeffect.density/100.0f; size = 3 - ((tileeffect.density-1)/25); AssembleSpriteFromSheet((((currentFrameLong+rando)%8)*20+size), sprite_dragonfire, tint, drawx, drawy, this, 2.0f); //ALLEGRO_COLOR tint = lookupMaterialColor(Eff_Dragonfire.matt.type, Eff_Dragonfire.matt.index); //draw_particle_cloud(Eff_Dragonfire.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_dragonfire, tint); break; case df::flow_type::Fire: tint.a*=tileeffect.density/100.0f; tint.g*=tileeffect.density/100.0f; tint.b*=tileeffect.density/100.0f; size = 3 - ((tileeffect.density-1)/25); AssembleSpriteFromSheet((((currentFrameLong+rando)%8)*20+size), sprite_dragonfire, tint, drawx, drawy, this, 2.0f); //ALLEGRO_COLOR tint = lookupMaterialColor(Eff_Fire.matt.type, Eff_Fire.matt.index); //draw_particle_cloud(Eff_Fire.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_fire, tint); break; case df::flow_type::Web: tint.a*=tileeffect.density/100.0f; AssembleSpriteFromSheet(rando%5, sprite_webing, tint, drawx, drawy, this, 4.0f); //al_draw_tinted_bitmap(sprite_webing,tint, drawx, drawy - (WALLHEIGHT), 0); break; case df::flow_type::MaterialGas: AssembleParticleCloud(tileeffect.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_boiling, tint); break; case df::flow_type::MaterialVapor: AssembleParticleCloud(tileeffect.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_boiling, tint); break; case df::flow_type::SeaFoam: tint.a*=tileeffect.density/100.0f; AssembleSprite(sprite_oceanwave, tint, 0, 0, al_get_bitmap_width(sprite_oceanwave), al_get_bitmap_height(sprite_oceanwave), drawx, drawy - (WALLHEIGHT)*ssConfig.scale, SPRITEWIDTH*ssConfig.scale, SPRITEHEIGHT*ssConfig.scale, 0); break; case df::flow_type::OceanWave: AssembleParticleCloud(tileeffect.density, drawx, drawy - (SPRITEHEIGHT/2), SPRITEWIDTH, SPRITEHEIGHT, sprite_water, tint); break; } } // Creature Names / Info if(occ.bits.unit && creature && (ssConfig.show_hidden_tiles || !designation.bits.hidden)) { AssembleCreatureText(drawx, drawy, creature, ownerSegment); } }
void Tile::DrawGrowth(c_sprite * spriteobject, bool top=true) { //Draw Growths that appear over branches if (tileMaterial() == RemoteFortressReader::ROOT || tileMaterial() == RemoteFortressReader::TREE_MATERIAL || tileMaterial() == RemoteFortressReader::MUSHROOM) { df::plant_raw* plantRaw = df::global::world->raws.plants.all[tree.index]; for (int i = 0; i < plantRaw->growths.size(); i++) { df::plant_growth * growth = plantRaw->growths[i]; if (!growth->locations.whole) continue; //we need at least one location. int32_t time = *df::global::cur_year_tick; if (growth->timing_1 >= 0 && growth->timing_1 > time) continue; if (growth->timing_2 >= 0 && growth->timing_2 < time) continue; growth_locations loca = LOCATION_NONE; if (growth->locations.bits.cap && tileMaterial() == RemoteFortressReader::MUSHROOM) loca = LOCATION_CAP; if (growth->locations.bits.heavy_branches && (tileSpecial() == RemoteFortressReader::BRANCH && tileType != df::tiletype::TreeBranches)) loca = LOCATION_HEAVY_BRANCHES; if (growth->locations.bits.roots && tileMaterial() == RemoteFortressReader::ROOT) loca = LOCATION_ROOTS; if (growth->locations.bits.light_branches && tileType == df::tiletype::TreeBranches) loca = LOCATION_LIGHT_BRANCHES; if (growth->locations.bits.sapling && tileMaterial() == RemoteFortressReader::SAPLING) loca = LOCATION_SAPLING; if (growth->locations.bits.trunk && tileShape() == RemoteFortressReader::WALL) loca = LOCATION_TRUNK; if (growth->locations.bits.twigs && tileShape() == RemoteFortressReader::TWIG) loca = LOCATION_TWIGS; if (loca == LOCATION_NONE) continue; DFHack::t_matglossPair fakeMat; fakeMat.index = tree.index; fakeMat.type = i * 10 + loca; if (top) spriteobject = contentLoader->growthTopConfigs.get(fakeMat); else spriteobject = contentLoader->growthBottomConfigs.get(fakeMat); if (spriteobject) { DFHack::t_matglossPair growthMat; growthMat.index = growth->mat_index; growthMat.type = growth->mat_type; ALLEGRO_COLOR growCol = lookupMaterialColor(growthMat); if (growth->prints.size() > 1) { df::plant_growth_print * basePrint = growth->prints[0]; df::plant_growth_print * currentPrint = basePrint; for (int k = 0; k < growth->prints.size(); k++) { if (growth->prints[k]->timing_start >= 0 && growth->prints[k]->timing_start > time) continue; if (growth->prints[k]->timing_end >= 0 && growth->prints[k]->timing_end < time) continue; currentPrint = growth->prints[k]; } growCol = morph_color(growCol, ssConfig.colors.getDfColor(basePrint->color[0], basePrint->color[2], ssConfig.useDfColors), ssConfig.colors.getDfColor(currentPrint->color[0], currentPrint->color[2], ssConfig.useDfColors)); } spriteobject->set_growthColor(growCol); spriteobject->assemble_world(x, y, z, this); } } } }