{$CLEO} // Improvement of trams traffic (by Den_spb) var 0@: Integer 1@: Integer // 2-14 переменные для одноразовых значений 15@: Integer 16@: Integer 17@: Integer 18@: Float 19@: Float 20@: Integer 21@: Float 22@: Integer 23@: Integer end const TRAM = 0@ TRAM_STRUCT = 1@ FLAGS = 15@ PASSENGER_0 = 16@ PASSENGER_1 = 17@ LAST_0BJECT_X = 18@ LAST_0BJECT_Y = 19@ 0BJECT = 20@ Y_DIMENSION = 21@ MAR_KER = 22@ STOPS_C0UNT = 23@ // BIT FLAGS: MANY_CARRIAGES = 0 AUTODRIVE_OFF = 1 TRAM_IS_STOPPING = 2 CJ_IS_PASSENGER = 3 end TRAM = -1 0A8C: write_memory 0x6F7863 size 2 value 0 virtual_protect 1 // при создании трамваев создавать и водителей для них LAST_0BJECT_X = 50000.0 LAST_0BJECT_Y = 50000.0 while true wait 0 if or not player.Defined($PLAYER_CHAR) $ONMISSION <> 0 then continue end if 856E: not car TRAM defined then if 8154: not actor $PLAYER_ACTOR in_zone 'SF' // San Fierro then continue end if gosub @SEARCH_TRAM then marker.CreateAboveCar(MAR_KER TRAM) 07E0: set_marker MAR_KER type_to 1 018B: set_marker MAR_KER radar_mode 2 FLAGS = 0 0A97: TRAM_STRUCT = car TRAM struct TRAM_STRUCT += 0x5D4 0A8D: TRAM_STRUCT = read_memory TRAM_STRUCT size 4 virtual_protect 0 07E4: get_model 449 dimensions_cornerA_to 2@ 3@ 4@ dimensions_cornerB_to 5@ Y_DIMENSION 7@ if TRAM_STRUCT > 0 then Y_DIMENSION += 16.0 08BD: set FLAGS bit MANY_CARRIAGES else Y_DIMENSION += 12.0 end { 0209: 8@ = random_int_in_ranges 0 2 if 8@ == 0 then 0561: PASSENGER_0 = create_passenger_in_car TRAM seat 0 actor.RemoveReferences(PASSENGER_0) else 0561: PASSENGER_1 = create_passenger_in_car TRAM seat 1 actor.RemoveReferences(PASSENGER_1) end } end else // tram defined 0AB5: store_actor $PLAYER_ACTOR closest_vehicle_to 2@ closest_ped_to 3@ if and // посадка игрока в трамвай в качестве водителя или пассажира при нажатии клавиш 003B: 2@ == TRAM // (int) $ONMISSION == 0 not actor.Driving($PLAYER_ACTOR) then if 0AB0: key_pressed 219 // [ then 05CB: AS_actor $PLAYER_ACTOR enter_car TRAM as_driver -1 ms { else if 0AB0: key_pressed 221 // ] then if 0431: car TRAM passenger_seat_free 0 then 05CA: AS_actor $PLAYER_ACTOR enter_car TRAM passenger_seat 0 -1 ms else if 0431: car TRAM passenger_seat_free 1 then 05CA: AS_actor $PLAYER_ACTOR enter_car TRAM passenger_seat 1 -1 ms end end end } end end // cj entering tram 046C: 2@ = car TRAM driver if 856D: not actor 2@ defined then 08BD: set FLAGS bit AUTODRIVE_OFF 06DD: set_train TRAM speed 0.0 end if // выполнение действий при произведённой посадке игрока в трамвай actor.InCar($PLAYER_ACTOR TRAM) then if 003C: $PLAYER_ACTOR == 2@ // (int) then 08BD: set FLAGS bit AUTODRIVE_OFF 06DD: set_train TRAM speed 0.0 else if 88B7: not test FLAGS bit CJ_IS_PASSENGER then 08BD: set FLAGS bit CJ_IS_PASSENGER 0109: player $PLAYER_CHAR money += -5 end end else 08C3: clear FLAGS bit CJ_IS_PASSENGER end // cj not in tram if 88B7: not test FLAGS bit AUTODRIVE_OFF // автоведение включено then if 88B7: not test FLAGS bit TRAM_IS_STOPPING // если не включён процесс остановки перед знаком остановки then if gosub @CHECK_OBSTACLES then 06DD: set_train TRAM speed 0.0 { Car.StorePos(TRAM 2@ 3@ 10@) /////////////////////////////////////////////////////////////////////////////////////////// 10@ += 3.0 024F: create_corona_with_radius 1.0 type 2 lensflares 0 with_color 255 255 0 at 2@ 3@ 10@ ///////////////////// } else Car.StorePos(TRAM 2@ 3@ 10@) 0407: store_coords_to 5@ 6@ 4@ from_car TRAM with_offset 0.0 -1.0 0.0 0407: store_coords_to 7@ 8@ 4@ from_car TRAM with_offset 0.0 1.0 0.0 0509: 4@ = distance_between_XY LAST_0BJECT_X LAST_0BJECT_Y and_XY 5@ 6@ 0509: 9@ = distance_between_XY LAST_0BJECT_X LAST_0BJECT_Y and_XY 7@ 8@ if 0025: 9@ > 4@ // (float) then 0407: store_coords_to LAST_0BJECT_X LAST_0BJECT_Y 4@ from_car TRAM with_offset 0.0 -50000.0 0.0 end if gosub @SEARCH_OBJECTS then object.StorePos(0BJECT LAST_0BJECT_X LAST_0BJECT_Y 12@) 06DD: set_train TRAM speed 0.0 { 12@ += 2.0 /////////////////////////////////////////////////////////////////////////////////////////////////////////// 024F: create_corona_with_radius 1.0 type 2 lensflares 0 with_color 0 0 255 at LAST_0BJECT_X LAST_0BJECT_Y 12@ /////// } else 06DD: set_train TRAM speed 11.11 end end else if 01C1: car TRAM stopped then if 32@ < -5000 then 32@ = -5000 { if and 0431: car TRAM passenger_seat_free 0 0431: car TRAM passenger_seat_free 1 then car.StorePos(TRAM 2@ 3@ 4@) if gosub @SEARCH_PASSENGERS then 0209: 8@ = random_int_in_ranges 0 2 if 8@ == 0 then 05CA: AS_actor 5@ enter_car TRAM passenger_seat 0 -1 ms else 05CA: AS_actor 5@ enter_car TRAM passenger_seat 1 -1 ms end end else if STOPS_C0UNT >= 2 then 0432: PASSENGER_0 = get_actor_handle_from_car TRAM passenger_seat 0 if and PASSENGER_0 > 0 // 056D: actor PASSENGER_0 defined 803C: not $PLAYER_ACTOR == PASSENGER_0 // (int) then // marker.CreateAboveActor(31@ PASSENGER_0) // 0165: set_marker 31@ color_to 3 0633: AS_actor PASSENGER_0 exit_car else 0432: PASSENGER_1 = get_actor_handle_from_car TRAM passenger_seat 1 if and PASSENGER_1 > 0 // 056D: actor PASSENGER_1 defined 803C: not $PLAYER_ACTOR == PASSENGER_1 // (int) then // marker.CreateAboveActor(31@ PASSENGER_1) // 0165: set_marker 31@ color_to 3 0633: AS_actor PASSENGER_1 exit_car end end STOPS_C0UNT = 0 else STOPS_C0UNT += 1 end end } else if 32@ >= 0 then 08C3: clear FLAGS bit TRAM_IS_STOPPING 06DD: set_train TRAM speed 11.11 end end end end // tram is stopping end // cj is not driver end // tram defined end :SEARCH_TRAM // ищем трамвай if 0AE2: TRAM = random_vehicle_near_point 0.0 0.0 0.0 in_radius 6000.0 find_next 0 pass_wrecked 1 //IF and SET then repeat if 0137: car TRAM model == 449 then 0A97: TRAM_STRUCT = car TRAM struct TRAM_STRUCT += 0x5D0 0A8D: TRAM_STRUCT = read_memory TRAM_STRUCT size 4 virtual_protect 0 if TRAM_STRUCT == 0 // предыдущий вагон отсутствует (данный вагон является нулевым) then 0485: return_true return end end until 8AE2: not TRAM = random_vehicle_near_point 0.0 0.0 0.0 in_radius 6000.0 find_next 1 pass_wrecked 1 //IF and SET end TRAM = -1 8485: return_false return :CHECK_OBSTACLES // ищем препятствия перед трамваем 07E4: get_model 449 dimensions_cornerA_to 2@ 3@ 4@ dimensions_cornerB_to 5@ 8@ 7@ 2@ -= 0.1 5@ += 0.1 repeat 0407: store_coords_to 9@ 10@ 11@ from_car TRAM with_offset 2@ 0.0 4@ //1 0407: store_coords_to 12@ 13@ 14@ from_car TRAM with_offset 2@ Y_DIMENSION 4@ if 86BD: not no_obstacles_between 9@ 10@ 11@ and 12@ 13@ 14@ solid 0 car 1 actor 1 object 0 particle 0 then 0485: return_true return end 0407: store_coords_to 9@ 10@ 11@ from_car TRAM with_offset 2@ Y_DIMENSION 4@ //2 0407: store_coords_to 12@ 13@ 14@ from_car TRAM with_offset 5@ Y_DIMENSION 4@ if 86BD: not no_obstacles_between 9@ 10@ 11@ and 12@ 13@ 14@ solid 0 car 1 actor 1 object 0 particle 0 then 0485: return_true return end 0407: store_coords_to 9@ 10@ 11@ from_car TRAM with_offset 5@ 0.0 4@ //3 0407: store_coords_to 12@ 13@ 14@ from_car TRAM with_offset 5@ Y_DIMENSION 4@ if 86BD: not no_obstacles_between 9@ 10@ 11@ and 12@ 13@ 14@ solid 0 car 1 actor 1 object 0 particle 0 then 0485: return_true return end 0407: store_coords_to 9@ 10@ 11@ from_car TRAM with_offset 2@ 8@ 4@ //6 0407: store_coords_to 12@ 13@ 14@ from_car TRAM with_offset 5@ 8@ 4@ if 86BD: not no_obstacles_between 9@ 10@ 11@ and 12@ 13@ 14@ solid 0 car 1 actor 1 object 0 particle 0 then 0485: return_true return end 0087: 3@ = 2@ // (float) repeat 0407: store_coords_to 9@ 10@ 11@ from_car TRAM with_offset 3@ 8@ 4@ //поперечн. 0407: store_coords_to 12@ 13@ 14@ from_car TRAM with_offset 3@ Y_DIMENSION 4@ if 86BD: not no_obstacles_between 9@ 10@ 11@ and 12@ 13@ 14@ solid 0 car 1 actor 1 object 0 particle 0 then 0485: return_true return end 3@ += 0.4 // старое значение 0.2 until 0025: 3@ > 5@ // (float) 4@ += 1.0 // старое значение 0.5 until 0025: 4@ > 7@ // (float) 8485: return_false return :SEARCH_PASSENGERS // ищем пассажиров, желающих прокатиться на трамвае if 0AE1: 5@ = random_actor_near_point 2@ 3@ 4@ in_radius 20.0 find_next 0 pass_deads 1 //IF and SET then repeat 089F: get_actor 5@ pedtype_to 6@ if or 6@ == 4 6@ == 5 then 080E: get_actor 5@ ped_event_to 6@ if and 6@ == 13 803B: not 5@ == $PLAYER_ACTOR // (int) then 0485: return_true return end end until 8AE1: not 5@ = random_actor_near_point 2@ 3@ 4@ in_radius 20.0 find_next 1 pass_deads 1 //IF and SET end 8485: return_false return :SEARCH_OBJECTS // ищем попутный светофор с запрещающим сигналом или знак трамвайной остановки if 0AE3: 0BJECT = random_object_near_point 2@ 3@ 10@ in_radius Y_DIMENSION find_next 0 then repeat if and // проверяем модель объекта 89CC: not object 0BJECT model_is 3855 // GAY_TRAFFIC_LIGHT + 89CC: not object 0BJECT model_is 1315 // TRAFFICLIGHT1 + 89CC: not object 0BJECT model_is 1352 // CJ_TRAFFIC_LIGHT3 + 89CC: not object 0BJECT model_is 1350 // CJ_TRAFFIC_LIGHT4 + 89CC: not object 0BJECT model_is 1351 // CJ_TRAFFIC_LIGHT5 + 89CC: not object 0BJECT model_is 3516 // VGSSTRIPTLIGHTS1 + 89CC: not object 0BJECT model_is 1283 // MTRAFFIC1 + then if and 89CC: not object 0BJECT model_is 1284 // MTRAFFIC2 + 89CC: not object 0BJECT model_is 1375 // TRAMSTOP_SF + then continue end end object.StorePos(0BJECT 4@ 9@ 12@) 12@ += 1.0 0509: 14@ = distance_between_XY 2@ 3@ and_XY 4@ 9@ 0509: 13@ = distance_between_XY 2@ 3@ and_XY LAST_0BJECT_X LAST_0BJECT_Y if or // находится ли новый объект ближе к трамваю, чем старый найденный объект и нет ли препятствий между трамваем и объектом 0025: 14@ > 13@ // (float) 86BD: not no_obstacles_between 2@ 3@ 10@ and 4@ 9@ 12@ solid 1 car 0 actor 0 object 0 particle 0 then continue end 0509: 12@ = distance_between_XY 4@ 9@ and_XY 5@ 6@ 0509: 13@ = distance_between_XY 4@ 9@ and_XY 7@ 8@ if // находится ли новый объект перед трамваем 0035: 13@ >= 12@ // (float) then continue end if // проверки угла и цвета светофора (если это светофор) 09CC: object 0BJECT model_is 1375 // TRAMSTOP_SF + then if and 8045: not 4@ == LAST_0BJECT_X // (float) 8045: not 9@ == LAST_0BJECT_Y // (float) then 32@ = -900000 08BD: set FLAGS bit TRAM_IS_STOPPING 0485: return_true return end else // объект является светофором 0174: 6@ = car TRAM Z_angle ////////////////////////////////////////////////////////////////////////////////////////////////// 0176: 8@ = object 0BJECT Z_angle 0063: 8@ -= 6@ // (float) 0656: get_angle 8@ absolute_degrees_to 8@ if gosub @CHECK_TRAFFICLIGHT_ANGLE then 0176: 8@ = object 0BJECT Z_angle if and 8@ >= 60.0 8@ <= 150.0 then 0AA7: call_function 0x49D3A0 num_params 0 pop 0 9@ // тип светофора 2 WE else if and 8@ >= 240.0 8@ <= 330.0 then 0AA7: call_function 0x49D3A0 num_params 0 pop 0 9@ // тип светофора 2 WE else 0AA7: call_function 0x49D350 num_params 0 pop 0 9@ // тип светофора 1 NS end end for 8@ = 8 to 31 08C3: clear 9@ bit 8@ end // значения функций: 0 - зелёный, 1 - желтый, 2 - красный if 9@ <> 0 then 0485: return_true return end end end until 8AE3: not 0BJECT = random_object_near_point 2@ 3@ 10@ in_radius Y_DIMENSION find_next 1 end 8485: return_false return :CHECK_TRAFFICLIGHT_ANGLE // проверяем, является ли светофор попутным трамваю if or 8@ > 315.0 8@ < 45.0 then 0485: return_true return end if or 09CC: object 0BJECT model_is 1283 09CC: object 0BJECT model_is 1284 then if and 8@ > 135.0 8@ < 225.0 then 0485: return_true return end end 8485: return_false return