From 56dd0abb806009675da03156345c8001af677484 Mon Sep 17 00:00:00 2001 From: dwachs Date: Sun, 19 Mar 2017 12:13:17 +0100 Subject: [PATCH 2/3] CHG pedestrian movement, new dat parameter offset --- simutrans/trunk/descriptor/pedestrian_desc.h | 3 + .../trunk/descriptor/reader/pedestrian_reader.cc | 1 + .../trunk/descriptor/writer/pedestrian_writer.cc | 5 +- simutrans/trunk/simutrans/history.txt | 2 + simutrans/trunk/vehicle/simpeople.cc | 90 +++++++++++++++++++--- simutrans/trunk/vehicle/simpeople.h | 6 ++ 6 files changed, 95 insertions(+), 12 deletions(-) diff --git a/simutrans/trunk/descriptor/pedestrian_desc.h b/simutrans/trunk/descriptor/pedestrian_desc.h index 07c5f99..4dba2e8 100644 --- a/simutrans/trunk/descriptor/pedestrian_desc.h +++ b/simutrans/trunk/descriptor/pedestrian_desc.h @@ -30,6 +30,7 @@ class pedestrian_desc_t : public obj_named_desc_t { uint16 distribution_weight; uint16 steps_per_frame; + uint16 offset; public: image_id get_image_id(ribi_t::dir dir, uint16 phase=0) const @@ -58,6 +59,8 @@ public: chk->input(distribution_weight); } + // images are offset steps away from boundary + uint16 get_offset() const { return offset; } }; #endif diff --git a/simutrans/trunk/descriptor/reader/pedestrian_reader.cc b/simutrans/trunk/descriptor/reader/pedestrian_reader.cc index 0e1ad48..77db198 100644 --- a/simutrans/trunk/descriptor/reader/pedestrian_reader.cc +++ b/simutrans/trunk/descriptor/reader/pedestrian_reader.cc @@ -67,6 +67,7 @@ obj_desc_t * pedestrian_reader_t::read_node(FILE *fp, obj_node_info_t &node) else if (version == 1) { desc->distribution_weight = decode_uint16(p); desc->steps_per_frame = decode_uint16(p); + desc->offset = decode_uint16(p); } DBG_DEBUG("pedestrian_reader_t::read_node()", "version=%i, chance=%i", version, desc->distribution_weight); return desc; diff --git a/simutrans/trunk/descriptor/writer/pedestrian_writer.cc b/simutrans/trunk/descriptor/writer/pedestrian_writer.cc index dd732e8..4fe7728 100644 --- a/simutrans/trunk/descriptor/writer/pedestrian_writer.cc +++ b/simutrans/trunk/descriptor/writer/pedestrian_writer.cc @@ -11,7 +11,7 @@ void pedestrian_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& { int i; - obj_node_t node(this, 6, &parent); + obj_node_t node(this, 8, &parent); write_head(fp, node, obj); @@ -63,6 +63,8 @@ void pedestrian_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& imagelist_writer_t::instance()->write_obj(fp, node, keys); } + uint16 offset = obj.get_int("offset", 16); + // Hajo: Version needs high bit set as trigger -> this is required // as marker because formerly nodes were unversionend @@ -70,6 +72,7 @@ void pedestrian_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& node.write_uint16(fp, version, 0); node.write_uint16(fp, distribution_weight, 2); node.write_uint16(fp, steps_per_frame, 4); + node.write_uint16(fp, offset, 6); node.write(fp); } diff --git a/simutrans/trunk/simutrans/history.txt b/simutrans/trunk/simutrans/history.txt index fdeb58d..29cd9d9 100644 --- a/simutrans/trunk/simutrans/history.txt +++ b/simutrans/trunk/simutrans/history.txt @@ -6,6 +6,8 @@ ADD: animated pedestrians, parameters: steps_per_frame (internal steps per frame, straight movement across tile is 256 steps) image[dir][a] (dir - direction, a - animation counter, a=0,1,..) + CHG: pedestrian movement, new dat parameter: + offset (of pedestrian image relative to right tile boundary, 0..255, default 16, 0 = on the right edge of tile, 128 = on center line of tile) Release of 120.2.2: (r8163 on 31-3-2017): ADD: Name filter in depot window diff --git a/simutrans/trunk/vehicle/simpeople.cc b/simutrans/trunk/vehicle/simpeople.cc index 15168ff..3996a3a 100644 --- a/simutrans/trunk/vehicle/simpeople.cc +++ b/simutrans/trunk/vehicle/simpeople.cc @@ -65,9 +65,12 @@ pedestrian_t::pedestrian_t(loadsave_t *file) : road_user_t() { animation_steps = 0; + on_left = false; + steps_offset = 0; rdwr(file); if(desc) { welt->sync.add(this); + ped_offset = desc->get_offset(); } } @@ -77,7 +80,10 @@ pedestrian_t::pedestrian_t(grund_t *gr) : desc(pick_any_weighted(list)) { animation_steps = 0; + on_left = simrand(2) > 0; + steps_offset = 0; time_to_life = pick_any(strecke); + ped_offset = desc->get_offset(); calc_image(); } @@ -131,6 +137,11 @@ void pedestrian_t::rdwr(loadsave_t *file) if(file->get_version()<89004) { time_to_life = pick_any(strecke); } + + if (file->get_version() > 120005) { + file->rdwr_short(steps_offset); + file->rdwr_bool(on_left); + } } @@ -209,43 +220,73 @@ grund_t* pedestrian_t::hop_check() void pedestrian_t::hop(grund_t *gr) { + koord3d from = get_pos(); + + // hop leave_tile(); set_pos(gr->get_pos()); // no need to call enter_tile(); gr->obj_add(this); + // determine pos_next const weg_t *weg = gr->get_weg(road_wt); // new target grund_t *to = NULL; + // current single direction + ribi_t::ribi current_direction = get_direction(); + if (!ribi_t::is_single(current_direction)) { + current_direction = ribi_type(from, get_pos()); + } // ribi opposite to current direction - ribi_t::ribi reverse_direction = ribi_t::backward( get_direction() ); + ribi_t::ribi reverse_direction = ribi_t::reverse_single( current_direction ); // all possible directions ribi_t::ribi ribi = weg->get_ribi_unmasked() & (~reverse_direction); // randomized offset const uint8 offset = (ribi > 0 && ribi_t::is_single(ribi)) ? 0 : simrand(4); + ribi_t::ribi new_direction; for(uint r = 0; r < 4; r++) { - ribi_t::ribi const test_ribi = ribi_t::nsew[ (r+offset) & 3]; + new_direction = ribi_t::nsew[ (r+offset) & 3]; - if( (ribi & test_ribi)!=0 && gr->get_neighbour(to, road_wt, test_ribi) ) { + if( (ribi & new_direction)!=0 && gr->get_neighbour(to, road_wt, new_direction) ) { // this is our next target break; } } + steps_offset = 0; if (to) { pos_next = to->get_pos(); - direction = calc_set_direction(get_pos(), pos_next); + + if (new_direction == current_direction) { + // going straight + direction = calc_set_direction(get_pos(), pos_next); + } + else { + ribi_t::ribi turn_ribi = on_left ? ribi_t::rotate90l(current_direction) : ribi_t::rotate90(current_direction); + + if (turn_ribi == new_direction) { + // short diagonal (turn but do not cross street) + direction = calc_set_direction(from, pos_next); + steps_next = (ped_offset*181) / 128; // * sqrt(2) + steps_offset = 0; + } + else { + // do not cross street diagonally, change side + on_left = !on_left; + direction = calc_set_direction(get_pos(), pos_next); + } + } } else { - // turn around - direction = reverse_direction; - dx = -dx; - dy = -dy; - pos_next = get_pos(); - // .. but this looks ugly, so disappear - time_to_life = 0; + // dead end, turn + pos_next = from; + direction = calc_set_direction(get_pos(), pos_next); + steps_offset = VEHICLE_STEPS_PER_TILE - ped_offset; + steps_next = ped_offset; + on_left = !on_left; } + // carry over remainder to next tile for continuous animation during straight movement uint16 steps_per_animation = desc->get_steps_per_frame() * desc->get_animation_count(ribi_t::get_dir(direction)); if (steps_per_animation > 0) { @@ -257,3 +298,30 @@ void pedestrian_t::hop(grund_t *gr) calc_image(); } + +void pedestrian_t::get_screen_offset( int &xoff, int &yoff, const sint16 raster_width ) const +{ + // vehicles needs finer steps to appear smoother + sint32 display_steps = (uint32)(steps + steps_offset)*(uint16)raster_width; + if(dx*dy) { + display_steps &= 0xFFFFFC00; + } + else { + display_steps = (display_steps*diagonal_multiplier)>>10; + } + xoff += (display_steps*dx) >> 10; + yoff += ((display_steps*dy) >> 10) + (get_hoff(raster_width))/(4*16); + + if (on_left) { + sint32 left_off_steps = ( (VEHICLE_STEPS_PER_TILE - 2*ped_offset)*(uint16)raster_width ) & 0xFFFFFC00; + + if (dx*dy==0) { + // diagonal + left_off_steps /= 2; + } + // turn left (dx,dy) increments + xoff += (left_off_steps*2*dy) >> 10; + yoff -= (left_off_steps*dx) >> (10+1); + } +} + diff --git a/simutrans/trunk/vehicle/simpeople.h b/simutrans/trunk/vehicle/simpeople.h index e6e3ca1..a77ab88 100644 --- a/simutrans/trunk/vehicle/simpeople.h +++ b/simutrans/trunk/vehicle/simpeople.h @@ -20,6 +20,10 @@ private: const pedestrian_desc_t *desc; uint16 animation_steps; + uint16 steps_offset; + uint16 ped_offset; + bool on_left; + protected: void rdwr(loadsave_t *file); @@ -46,6 +50,8 @@ public: // overloaded to enable animations virtual image_id get_image() const; + virtual void get_screen_offset( int &xoff, int &yoff, const sint16 raster_width ) const; + virtual grund_t* hop_check(); virtual void hop(grund_t* gr); -- 1.8.4.5