diff --git a/descriptor/writer/factory_writer.cc b/descriptor/writer/factory_writer.cc index f8a0ec969..51f45118f 100644 --- a/descriptor/writer/factory_writer.cc +++ b/descriptor/writer/factory_writer.cc @@ -288,7 +288,7 @@ void factory_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj if( !*obj.get( str_smokeoffset ) ) { dbg->error( "factory_writer_t::write_obj", "%s defined but not %s!", str_smoketile, str_smokeoffset ); } - pos_off[ i ] = obj.get_koord( str_smoketile, koord( 0, 0 ) ); + xy_off[ i ] = obj.get_koord( str_smokeoffset, koord( 0, 0 ) ); num_smoke_offsets++; } } @@ -331,7 +331,7 @@ void factory_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj node.write_sint16(fp, smokeuplift, 76); node.write_sint16(fp, smokelifetime, 78); - // this should ne always at the end + // this should be always at the end sint8 sound_str_len = sound_str.size(); if (sound_str_len > 0) { node.write_sint8 (fp, sound_str_len, 79); diff --git a/obj/wolke.cc b/obj/wolke.cc index 96bad5456..9e70feb95 100644 --- a/obj/wolke.cc +++ b/obj/wolke.cc @@ -47,13 +47,13 @@ void wolke_t::operator delete(void *p) -wolke_t::wolke_t(koord3d pos, sint8 b_x_off, sint16 b_y_off, uint16 lt, uint16 ul, const skin_desc_t* desc ) : +wolke_t::wolke_t(koord3d pos, sint8 b_x_off, sint8 b_y_off, sint16 b_h_off, uint16 lt, uint16 ul, const skin_desc_t* desc ) : obj_no_info_t(pos) { cloud_nr = all_clouds.index_of(desc); - base_y_off = b_y_off; + base_y_off = b_h_off; set_xoff( b_x_off ); - set_yoff( -8 ); + set_yoff( b_y_off ); insta_zeit = 0; lifetime = lt; uplift = ul; @@ -62,7 +62,7 @@ wolke_t::wolke_t(koord3d pos, sint8 b_x_off, sint16 b_y_off, uint16 lt, uint16 u wolke_t::~wolke_t() { - mark_image_dirty( get_image(), 0 ); + mark_image_dirty( get_image(), calc_yoff() ); if( insta_zeit != lifetime ) { welt->sync_way_eyecandy.remove( this ); } @@ -82,6 +82,10 @@ image_id wolke_t::get_front_image() const } +sint16 wolke_t::calc_yoff() const +{ + return tile_raster_scale_y( base_y_off - (((long)insta_zeit * uplift * OBJECT_OFFSET_STEPS) >> 16), get_current_tile_raster_width() ); +} void wolke_t::rdwr(loadsave_t *file) { @@ -109,24 +113,29 @@ sync_result wolke_t::sync_step(uint32 delta_t) { // we query the image twice, since it may have changed (there are sure more efficient ways for that ... const image_id old_img = get_front_image(); - const sint16 old_yoff = base_y_off - (((long)insta_zeit * uplift * OBJECT_OFFSET_STEPS) >> 16); + const sint16 old_yoff = calc_yoff(); insta_zeit += delta_t; if( insta_zeit >= lifetime ) { // delete wolke ... + set_flag( obj_t::dirty ); + mark_image_dirty( old_img, old_yoff ); insta_zeit = lifetime; return SYNC_DELETE; } const image_id new_img = get_front_image(); // move cloud up - const sint16 new_yoff = base_y_off - (((long)insta_zeit * uplift * OBJECT_OFFSET_STEPS) >> 16); + const sint16 new_yoff = calc_yoff(); if( new_img != old_img ) { - // move/change cloud ... (happens much more often than image change => image change will be always done when drawing) + // change cloud set_flag( obj_t::dirty ); mark_image_dirty( old_img, old_yoff ); } if( new_yoff != old_yoff ) { + // move cloud + set_xoff( get_xoff() - sim_async_rand(2)); set_flag( obj_t::dirty ); + mark_image_dirty( old_img, old_yoff ); } return SYNC_OK; } @@ -138,8 +147,7 @@ void wolke_t::display_after( int xpos, int ypos, const sint8 extra_param ) const void wolke_t::display_after( int xpos, int ypos, bool extra_param ) const #endif { - sint16 extra_offset = tile_raster_scale_y( base_y_off - (((long)insta_zeit * uplift * OBJECT_OFFSET_STEPS) >> 16), get_current_tile_raster_width() ); - obj_t::display_after( xpos, ypos + extra_offset, extra_param ); + obj_t::display_after( xpos, ypos + calc_yoff(), extra_param ); } @@ -147,11 +155,13 @@ void wolke_t::display_after( int xpos, int ypos, bool extra_param ) const // called during map rotation void wolke_t::rotate90() { - // most basic: rotate coordinate - obj_t::rotate90(); if( lifetime != DEFAULT_EXHAUSTSMOKE_TIME ) { // since factory smoke comes from wrong tile, remove them on rotation insta_zeit = lifetime; + } else { + // only for vehicles + // most basic: rotate coordinate + obj_t::rotate90(); } } diff --git a/obj/wolke.h b/obj/wolke.h index 982d8d8b6..c5765e2e6 100644 --- a/obj/wolke.h +++ b/obj/wolke.h @@ -29,6 +29,8 @@ private: uint16 uplift; uint8 cloud_nr; + sint16 calc_yoff() const; // calculate the smoke height using uplift and insta_zeit + public: static bool register_desc(const skin_desc_t *desc); @@ -36,7 +38,7 @@ public: void operator delete(void *p); wolke_t(loadsave_t *file); - wolke_t(koord3d pos, sint8 xoff, sint16 yoff, uint16 lifetime, uint16 uplift, const skin_desc_t *cloud ); + wolke_t(koord3d pos, sint8 xoff, sint8 yoff, sint16 hoff, uint16 lifetime, uint16 uplift, const skin_desc_t *cloud ); ~wolke_t(); sync_result sync_step(uint32 delta_t) OVERRIDE; diff --git a/simfab.cc b/simfab.cc index 427295fe6..dc2343a63 100644 --- a/simfab.cc +++ b/simfab.cc @@ -1535,8 +1535,8 @@ void fabrik_t::smoke() const if(rada) { const uint8 rot = (4-rotate)%desc->get_building()->get_all_layouts(); grund_t *gr = welt->lookup_kartenboden(pos_origin.get_2d()+desc->get_smoketile( rot )); - const koord offset = (( desc->get_smokeoffset(rot) + koord(sim_async_rand(7)-3,sim_async_rand(7)-3) )*OBJECT_OFFSET_STEPS)/16; - wolke_t *smoke = new wolke_t(gr->get_pos(), offset.x, offset.y, desc->get_smokelifetime(), desc->get_smokeuplift(), rada->get_images() ); + const koord offset = ( desc->get_smokeoffset(rot)*OBJECT_OFFSET_STEPS)/16; + wolke_t *smoke = new wolke_t(gr->get_pos(), offset.x, -8, offset.y, desc->get_smokelifetime(), desc->get_smokeuplift(), rada->get_images() ); gr->obj_add(smoke); welt->sync_way_eyecandy.add( smoke ); } diff --git a/simutrans/history.txt b/simutrans/history.txt index de687d921..6515beb2b 100644 --- a/simutrans/history.txt +++ b/simutrans/history.txt @@ -6,7 +6,7 @@ ADD: Vehicle list as dialog tool 33 (to see also upcoming vehicles) ADD: goods waiting bar with now configurable: gui_waitingbar_width ADD: button to copy the last 20 messages to the clipboard - CHG: factory smake location now depend on factory. Four parameters smoketile[], smokeoffset[] (koord), and smokeuplift (16) and smokelifetime (2499) + CHG: factory smoke location now depend on factory. Four parameters smoketile[], smokeoffset[] (koord), and smokeuplift (16) and smokelifetime (2499) FIX: several list stored wrong coordinates after map rotation Release of 121.0 (r8870 on 1-Dec-2019): diff --git a/vehicle/simvehicle.cc b/vehicle/simvehicle.cc index bce2ba888..18bcfe8c0 100644 --- a/vehicle/simvehicle.cc +++ b/vehicle/simvehicle.cc @@ -1217,7 +1217,7 @@ void vehicle_t::make_smoke() const if( cnv->get_akt_speed() < (sint32)((cnv->get_speed_limit() * 7u) >> 3) || desc->get_engine_type() == vehicle_desc_t::steam ) { grund_t* const gr = welt->lookup( get_pos() ); if( gr ) { - wolke_t* const abgas = new wolke_t( get_pos(), get_xoff() + ((dx * (sint16)((uint16)steps * OBJECT_OFFSET_STEPS)) >> 8), get_yoff() + ((dy * (sint16)((uint16)steps * OBJECT_OFFSET_STEPS)) >> 8) + get_hoff(), DEFAULT_EXHAUSTSMOKE_TIME, DEFAULT_SMOKE_UPLIFT, desc->get_smoke() ); + wolke_t* const abgas = new wolke_t( get_pos(), get_xoff() + ((dx * (sint16)((uint16)steps * OBJECT_OFFSET_STEPS)) >> 8), get_yoff() + ((dy * (sint16)((uint16)steps * OBJECT_OFFSET_STEPS)) >> 8), get_hoff() - 8, DEFAULT_EXHAUSTSMOKE_TIME, DEFAULT_SMOKE_UPLIFT, desc->get_smoke() ); if( !gr->obj_add( abgas ) ) { abgas->set_flag( obj_t::not_on_map ); delete abgas;