cmake_minimum_required(VERSION 3.20)
project(ctw_port CXX C)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(FetchContent)
set(SDL_SHARED OFF CACHE BOOL "" FORCE)
set(SDL_STATIC ON CACHE BOOL "" FORCE)
set(SDL_TEST OFF CACHE BOOL "" FORCE)
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/../third_party/SDL2/CMakeLists.txt" AND NOT FETCHCONTENT_SOURCE_DIR_SDL2)
    # Corresponding-source release archives include the exact SDL2 source used by the build.
    set(FETCHCONTENT_SOURCE_DIR_SDL2 "${CMAKE_CURRENT_LIST_DIR}/../third_party/SDL2" CACHE PATH "Local SDL2 source")
endif()
FetchContent_Declare(SDL2 GIT_REPOSITORY https://github.com/libsdl-org/SDL.git GIT_TAG release-2.30.9 GIT_SHALLOW TRUE)
FetchContent_MakeAvailable(SDL2)

add_library(glad STATIC third_party/glad/src/gl.c)
target_include_directories(glad PUBLIC third_party/glad/include)

# ---- engine: everything shared by the showcase and the game (src/) ----------------------------------------
add_library(ctw_engine STATIC
    src/os/os_sdl.cpp src/os/wad.cpp src/os/gamefs.cpp src/os/dxtbin.cpp src/os/pak.cpp src/os/datafile.cpp
    src/gfx/spriteset.cpp src/gfx/font.cpp src/gfx/model.cpp src/gfx/character.cpp src/gfx/texload.cpp src/gfx/assets.cpp src/gfx/stb_impl.cpp src/gfx/pedsprites.cpp src/gfx/rendertables.cpp
    src/text/gxt.cpp src/audio/audio.cpp
    src/world/worldmap.cpp src/world/timecycle.cpp src/world/worldrenderer.cpp src/world/collision.cpp src/world/collisionsweep.cpp src/world/props.cpp)
target_include_directories(ctw_engine PUBLIC src third_party/stb third_party/minimp3)
target_link_libraries(ctw_engine PUBLIC glad SDL2::SDL2-static)

# ---- showcase: the asset viewer (textures, text, models, audio, fly-through city) ------------------------
add_executable(ctw_showcase showcase/main.cpp showcase/viewer.cpp showcase/modelview.cpp showcase/worldview.cpp)
target_link_libraries(ctw_showcase PRIVATE ctw_engine SDL2::SDL2main)

# ---- the game ----------------------------------------------------------------------------------------------
# GTACTW.exe. Version info (company kryo.to Inc) + the icon, which tools/make_icon.py makes from your own APK
# (data/gtactw.ico). Standalone exports (scripts/export_pc.py) put the icon into the exe themselves.
# -DCTW_RELEASE=ON: no console window (scripts/export_pc.py wants a release build).
option(CTW_RELEASE "release build: windowed, no console" OFF)
set(CTW_VERSION 0.1.0 CACHE STRING "Version written into GTACTW.exe (releases pass the Porter's version)")
set(CTW_ICON_LINE "")
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/data/gtactw.ico)
    configure_file(${CMAKE_CURRENT_LIST_DIR}/data/gtactw.ico ${CMAKE_BINARY_DIR}/gtactw.ico COPYONLY)
    set(CTW_ICON_LINE "1 ICON \"gtactw.ico\"")
endif()
string(REPLACE "." "," CTW_VERSION_COMMAS ${CTW_VERSION})
configure_file(game/res/gtactw.rc.in ${CMAKE_BINARY_DIR}/gtactw.rc @ONLY)
set(CTW_RES "")
if(MINGW)   # windres run from the build folder with relative names (it breaks on include paths with spaces)
    find_program(CTW_WINDRES windres REQUIRED)
    add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/gtactw_res.o
        COMMAND ${CTW_WINDRES} -O coff gtactw.rc gtactw_res.o
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
        DEPENDS ${CMAKE_BINARY_DIR}/gtactw.rc)
    set(CTW_RES ${CMAKE_BINARY_DIR}/gtactw_res.o)
endif()
add_library(ctw_gameplay STATIC game/game.cpp game/followcam.cpp game/player.cpp game/hud.cpp game/plugins.cpp game/vehicle.cpp game/carcam.cpp game/cargens.cpp game/random.cpp game/peds.cpp game/interpolation.cpp game/debughud.cpp game/postfx.cpp game/weather.cpp game/localarea.cpp game/weapons.cpp game/flamethrower.cpp game/fire.cpp game/taser.cpp game/sniper.cpp game/projectiles.cpp game/targeting.cpp game/weaponhud.cpp game/roads.cpp game/aispline.cpp game/traffic.cpp game/particles.cpp game/sound.cpp game/skidmarks.cpp game/lookups.cpp game/watercannon.cpp game/propdynamics.cpp game/rigidbody.cpp game/radio.cpp game/stats.cpp)
target_include_directories(ctw_gameplay PUBLIC game)
target_sources(ctw_gameplay PRIVATE game/radar.cpp game/gamehud.cpp)
target_sources(ctw_gameplay PRIVATE game/gameplayapi.cpp game/cameraobstruction.cpp)
target_sources(ctw_gameplay PRIVATE game/vehicledebris.cpp)
target_sources(ctw_gameplay PRIVATE game/explosions.cpp game/wanted_rating.cpp game/wanted_manager.cpp game/sequence_data.cpp game/sequence_timeline.cpp game/story_intro.cpp game/sequence_camera.cpp game/story_aircraft.cpp)
target_link_libraries(ctw_gameplay PUBLIC ctw_engine)
add_executable(ctw_game game/main.cpp ${CTW_RES})
set_target_properties(ctw_game PROPERTIES OUTPUT_NAME GTACTW)
target_include_directories(ctw_game PRIVATE game)
target_link_libraries(ctw_game PRIVATE ctw_gameplay SDL2::SDL2main)
if(MINGW)
    target_link_options(ctw_game PRIVATE -static -static-libgcc -static-libstdc++)
    if(CTW_RELEASE)
        target_link_options(ctw_game PRIVATE -mwindows)
    endif()
endif()

# ---- tools --------------------------------------------------------------------------------------------------
add_executable(wadtest tools/wadtest.cpp src/os/wad.cpp src/os/datafile.cpp)
target_include_directories(wadtest PRIVATE src)
add_executable(audiotest tools/audiotest.cpp)
target_include_directories(audiotest PRIVATE third_party/minimp3)

include(CTest)
if(BUILD_TESTING)
    add_executable(radartest ../tests/radar_test.cpp game/radar.cpp)
    target_include_directories(radartest PRIVATE game)
    add_test(NAME radar_map COMMAND radartest)
    add_executable(hudrendertest ../tests/hud_render_test.cpp)
    target_link_libraries(hudrendertest PRIVATE ctw_gameplay)
    add_test(NAME gameplay_hud_rendering COMMAND hudrendertest)
    set_tests_properties(gameplay_hud_rendering PROPERTIES SKIP_RETURN_CODE 77)
    add_executable(fonttest ../tests/font_render_test.cpp)
    target_link_libraries(fonttest PRIVATE ctw_engine)
    add_test(NAME font_rendering COMMAND fonttest)
    set_tests_properties(font_rendering PROPERTIES SKIP_RETURN_CODE 77)
    add_executable(weaponhudrendertest ../tests/weaponhud_render_test.cpp)
    target_link_libraries(weaponhudrendertest PRIVATE ctw_gameplay)
    add_test(NAME weapon_hud_rendering COMMAND weaponhudrendertest)
    set_tests_properties(weapon_hud_rendering PROPERTIES SKIP_RETURN_CODE 77)
    add_executable(charactertest ../tests/character_test.cpp)
    target_link_libraries(charactertest PRIVATE ctw_engine)
    add_test(NAME character_models COMMAND charactertest)
    add_executable(gameplaytest ../tests/gameplay_test.cpp)
    target_include_directories(gameplaytest PRIVATE game)
    target_link_libraries(gameplaytest PRIVATE ctw_gameplay)
    add_test(NAME gameplay COMMAND gameplaytest)
    add_executable(lookuptest ../tests/lookup_test.cpp game/lookups.cpp src/gfx/rendertables.cpp src/os/datafile.cpp)
    target_include_directories(lookuptest PRIVATE game src)
    add_test(NAME lookups COMMAND lookuptest)
    add_executable(portregressiontest ../tests/port_regression_test.cpp)
    target_link_libraries(portregressiontest PRIVATE ctw_gameplay)
    add_test(NAME port_regressions COMMAND portregressiontest)
    add_executable(radiorendertest ../tests/radio_render_test.cpp)
    target_link_libraries(radiorendertest PRIVATE ctw_gameplay)
    add_test(NAME radio_rendering COMMAND radiorendertest)
    set_tests_properties(radio_rendering PROPERTIES SKIP_RETURN_CODE 77)
    add_executable(particlerendertest ../tests/particle_render_test.cpp)
    target_link_libraries(particlerendertest PRIVATE ctw_gameplay)
    add_test(NAME particle_rendering COMMAND particlerendertest)
    set_tests_properties(particle_rendering PROPERTIES SKIP_RETURN_CODE 77)
    add_executable(gameplayapitest ../tests/gameplay_api_test.cpp)
    target_link_libraries(gameplayapitest PRIVATE ctw_gameplay)
    add_test(NAME gameplay_api COMMAND gameplayapitest)
    add_executable(pedstest ../tests/peds_test.cpp)
    target_link_libraries(pedstest PRIVATE ctw_gameplay)
    add_test(NAME pedestrians COMMAND pedstest)
    add_executable(weaponstest ../tests/weapons_test.cpp)
    target_link_libraries(weaponstest PRIVATE ctw_gameplay)
    add_test(NAME weapons COMMAND weaponstest)
    add_executable(armourtest ../tests/armour_test.cpp)
    target_link_libraries(armourtest PRIVATE ctw_gameplay)
    add_test(NAME armour COMMAND armourtest)
    add_executable(statstest ../tests/stats_test.cpp)
    target_link_libraries(statstest PRIVATE ctw_gameplay)
    add_test(NAME stats COMMAND statstest)
    add_executable(weaponparitytest ../tests/weapon_parity_test.cpp)
    target_link_libraries(weaponparitytest PRIVATE ctw_gameplay)
    add_test(NAME weapon_parity COMMAND weaponparitytest)
    add_executable(explosiontest ../tests/explosion_test.cpp)
    target_link_libraries(explosiontest PRIVATE ctw_gameplay)
    add_test(NAME explosions COMMAND explosiontest)
endif()

if(BUILD_TESTING)
    add_executable(wantedratingtest ../tests/test_wanted_rating.cpp game/wanted_rating.cpp)
    target_include_directories(wantedratingtest PRIVATE game)
    add_test(NAME wanted_rating COMMAND wantedratingtest)
    add_executable(webcheckpointtest ../tests/web_checkpoint_test.cpp ../web/checkpoint.cpp)
    target_include_directories(webcheckpointtest PRIVATE ../web)
    if(MSVC)
        target_compile_options(webcheckpointtest PRIVATE /UNDEBUG)
    else()
        target_compile_options(webcheckpointtest PRIVATE -UNDEBUG)
    endif()
    add_test(NAME web_checkpoint COMMAND webcheckpointtest)
    add_executable(checkpointweaponstest ../tests/checkpoint_weapons_test.cpp ../web/checkpoint_weapons.cpp)
    target_include_directories(checkpointweaponstest PRIVATE ../web)
    target_link_libraries(checkpointweaponstest PRIVATE ctw_gameplay)
    add_test(NAME checkpoint_weapons COMMAND checkpointweaponstest)
    add_executable(wantedmanagertest ../tests/test_wanted_manager.cpp game/wanted_manager.cpp game/wanted_rating.cpp)
    target_include_directories(wantedmanagertest PRIVATE game)
    add_test(NAME wanted_manager COMMAND wantedmanagertest)
    add_executable(sequencedatatest ../tests/sequence_data_test.cpp game/sequence_data.cpp)
    target_include_directories(sequencedatatest PRIVATE game)
    add_test(NAME sequence_data COMMAND sequencedatatest)
    add_executable(sequencetimelinetest ../tests/sequence_timeline_test.cpp game/sequence_timeline.cpp game/sequence_data.cpp)
    target_include_directories(sequencetimelinetest PRIVATE game)
    add_test(NAME sequence_timeline COMMAND sequencetimelinetest)
    if(MSVC)
        target_compile_options(sequencedatatest PRIVATE /UNDEBUG)
        target_compile_options(sequencetimelinetest PRIVATE /UNDEBUG)
    else()
        target_compile_options(sequencedatatest PRIVATE -UNDEBUG)
        target_compile_options(sequencetimelinetest PRIVATE -UNDEBUG)
    endif()

add_executable(firstmissiontest "${CMAKE_SOURCE_DIR}/tests/first_mission_test.cpp" game/first_mission.cpp)
target_include_directories(firstmissiontest PRIVATE game)
target_compile_features(firstmissiontest PRIVATE cxx_std_17)
add_test(NAME firstmissiontest COMMAND firstmissiontest)

add_executable(sequencecameratest "${CMAKE_SOURCE_DIR}/tests/sequence_camera_test.cpp" game/sequence_camera.cpp)
target_include_directories(sequencecameratest PRIVATE game)
target_compile_features(sequencecameratest PRIVATE cxx_std_17)
add_test(NAME sequencecameratest COMMAND sequencecameratest)
add_executable(introcloudtest "${CMAKE_SOURCE_DIR}/tests/intro_cloud_test.cpp")
target_link_libraries(introcloudtest PRIVATE ctw_gameplay)
add_test(NAME introcloudtest COMMAND introcloudtest)
foreach(test_target sequencecameratest introcloudtest)
  if(MSVC)
    target_compile_options(${test_target} PRIVATE /UNDEBUG)
  else()
    target_compile_options(${test_target} PRIVATE -UNDEBUG)
  endif()
endforeach()

add_executable(wantedintegrationtest ../tests/wanted_integration_test.cpp)
target_link_libraries(wantedintegrationtest PRIVATE ctw_gameplay)
add_test(NAME wanted_integration COMMAND wantedintegrationtest)

add_executable(sinkingcartest ../tests/sinking_car_test.cpp game/sinking_car.cpp)
target_include_directories(sinkingcartest PRIVATE game)
add_test(NAME sinking_car COMMAND sinkingcartest)

add_executable(audiomutetest ../tests/audio_mute_test.cpp)
target_link_libraries(audiomutetest PRIVATE ctw_engine)
add_test(NAME audio_master_mute COMMAND audiomutetest)

endif()

# Live first-mission task and scene hosts.
target_sources(ctw_gameplay PRIVATE
    game/second_mission.cpp game/second_mission_runtime.cpp game/story_scene.cpp
    game/pursuit_mission_runtime.cpp game/pursuit_scenes.cpp
    game/first_mission.cpp game/first_mission_water.cpp game/first_mission_runtime.cpp game/hotwire_view.cpp
    game/first_mission_door.cpp game/first_mission_scenes_clock.cpp game/first_mission_scenes.cpp
    game/sequence_artwork.cpp game/sinking_car.cpp game/sinking_car_view.cpp)
if(BUILD_TESTING)
    add_executable(swimmingtest ../tests/swimming_test.cpp)
    target_link_libraries(swimmingtest PRIVATE ctw_gameplay)
    add_test(NAME swimming COMMAND swimmingtest)
    add_executable(firstmissionwatertest ../tests/first_mission_water_test.cpp game/first_mission_water.cpp)
    add_executable(firstmissionscenetest ../tests/first_mission_scene_test.cpp game/first_mission_scenes_clock.cpp game/sequence_timeline.cpp game/sequence_data.cpp)
    add_executable(firstmissiondoortest ../tests/first_mission_door_test.cpp game/first_mission_door.cpp)
    foreach(target firstmissionwatertest firstmissionscenetest firstmissiondoortest)
        target_include_directories(${target} PRIVATE game)
        if(MSVC)
            target_compile_options(${target} PRIVATE /UNDEBUG)
        else()
            target_compile_options(${target} PRIVATE -UNDEBUG)
        endif()
    endforeach()
    add_test(NAME first_mission_water COMMAND firstmissionwatertest)
    add_test(NAME first_mission_scene COMMAND firstmissionscenetest)
    add_test(NAME first_mission_door COMMAND firstmissiondoortest)
endif()

target_sources(ctw_gameplay PRIVATE game/pursuit.cpp game/driving_ai.cpp)
if(BUILD_TESTING)
  add_executable(drivingaitest ../tests/driving_ai_test.cpp game/driving_ai.cpp)
  target_include_directories(drivingaitest PRIVATE game)
  add_test(NAME driving_ai COMMAND drivingaitest)
  add_executable(pursuittest ../tests/pursuit_test.cpp game/pursuit.cpp src/os/datafile.cpp)
  target_include_directories(pursuittest PRIVATE game src)
  add_test(NAME pursuit COMMAND pursuittest)
  add_executable(pursuitintegrationtest ../tests/pursuit_integration_test.cpp)
  target_link_libraries(pursuitintegrationtest PRIVATE ctw_gameplay)
  add_test(NAME pursuit_integration COMMAND pursuitintegrationtest)
  add_executable(takedowncollisiontest ../tests/takedown_collision_test.cpp)
  target_link_libraries(takedowncollisiontest PRIVATE ctw_gameplay)
  add_test(NAME takedown_collision COMMAND takedowncollisiontest)
  set_tests_properties(takedown_collision PROPERTIES SKIP_RETURN_CODE 77)
  add_executable(vehicledamagepercenttest ../tests/vehicle_damage_percent_test.cpp)
  target_include_directories(vehicledamagepercenttest PRIVATE game)
  add_test(NAME vehicle_damage_percent COMMAND vehicledamagepercenttest)
  add_executable(vehicledamagepercentintegrationtest ../tests/vehicle_damage_percent_integration_test.cpp)
  target_link_libraries(vehicledamagepercentintegrationtest PRIVATE ctw_gameplay)
  add_test(NAME vehicle_damage_percent_integration COMMAND vehicledamagepercentintegrationtest)
  set_tests_properties(vehicle_damage_percent_integration PROPERTIES SKIP_RETURN_CODE 77)
endif()

if(BUILD_TESTING)
    add_executable(sequenceartworktest ../tests/sequence_artwork_test.cpp)
    target_link_libraries(sequenceartworktest PRIVATE ctw_gameplay)
    add_test(NAME sequence_artwork COMMAND sequenceartworktest)
endif()

target_sources(ctw_gameplay PRIVATE game/script_garage.cpp game/script_garage_prop.cpp game/script_door.cpp game/script_door_render.cpp)
if(BUILD_TESTING)
    foreach(pair "scriptgaragetest;script_garage_test" "scriptgarageproptest;script_garage_prop_test" "scriptdoortest;script_door_test" "swimminggameticktest;swimming_game_tick_test")
        list(GET pair 0 target)
        list(GET pair 1 source)
        add_executable(${target} ../tests/${source}.cpp)
        target_link_libraries(${target} PRIVATE ctw_gameplay)
        if(MSVC)
            target_compile_options(${target} PRIVATE /UNDEBUG)
        else()
            target_compile_options(${target} PRIVATE -UNDEBUG)
        endif()
        add_test(NAME ${source} COMMAND ${target})
    endforeach()
endif()

if(BUILD_TESTING)
    add_executable(sinkingcarviewporttest ../tests/sinking_car_viewport_test.cpp)
    target_link_libraries(sinkingcarviewporttest PRIVATE ctw_gameplay)
    if(MSVC)
        target_compile_options(sinkingcarviewporttest PRIVATE /UNDEBUG)
        target_compile_options(sequenceartworktest PRIVATE /UNDEBUG)
    else()
        target_compile_options(sinkingcarviewporttest PRIVATE -UNDEBUG)
        target_compile_options(sequenceartworktest PRIVATE -UNDEBUG)
    endif()
    add_test(NAME sinking_car_viewport COMMAND sinkingcarviewporttest)
endif()

if(BUILD_TESTING)
    add_executable(hotwiretest ../tests/hotwire_test.cpp)
    target_include_directories(hotwiretest PRIVATE game)
    add_executable(firstmissionvehicletest ../tests/first_mission_vehicle_test.cpp)
    target_link_libraries(firstmissionvehicletest PRIVATE ctw_gameplay)
    foreach(target hotwiretest firstmissionvehicletest)
        if(MSVC)
            target_compile_options(${target} PRIVATE /UNDEBUG)
        else()
            target_compile_options(${target} PRIVATE -UNDEBUG)
        endif()
    endforeach()
    add_test(NAME hotwire COMMAND hotwiretest)
    add_test(NAME first_mission_vehicle COMMAND firstmissionvehicletest)
endif()

target_sources(ctw_gameplay PRIVATE game/weapon_pickups.cpp)
if(BUILD_TESTING)
 add_executable(weaponpickupstest ../tests/weapon_pickups_test.cpp)
 target_link_libraries(weaponpickupstest PRIVATE ctw_gameplay)
 if(MSVC)
  target_compile_options(weaponpickupstest PRIVATE /UNDEBUG)
 else()
  target_compile_options(weaponpickupstest PRIVATE -UNDEBUG)
 endif()
 add_test(NAME weapon_pickups COMMAND weaponpickupstest)
endif()

target_sources(ctw_gameplay PRIVATE game/npc_weapons.cpp)
if(BUILD_TESTING)
 add_executable(npccombattest ../tests/npc_combat_test.cpp)
 target_link_libraries(npccombattest PRIVATE ctw_gameplay)
 add_test(NAME npc_combat COMMAND npccombattest)
endif()

if(BUILD_TESTING)
 add_executable(vehicleentrytest ../tests/vehicle_entry_test.cpp)
 target_link_libraries(vehicleentrytest PRIVATE ctw_gameplay)
 if(MSVC)
  target_compile_options(vehicleentrytest PRIVATE /UNDEBUG)
 else()
  target_compile_options(vehicleentrytest PRIVATE -UNDEBUG)
 endif()
 add_test(NAME vehicle_entry COMMAND vehicleentrytest)
 add_test(NAME vehicle_entry_wall COMMAND vehicleentrytest --wall)
 add_test(NAME vehicle_entry_neighbor COMMAND vehicleentrytest --neighbor)
 add_test(NAME vehicle_entry_blocked COMMAND vehicleentrytest --blocked)
endif()

if(BUILD_TESTING)
    add_executable(pursuitmissiontest ../tests/pursuit_mission_test.cpp)
    target_include_directories(pursuitmissiontest PRIVATE game)
    add_executable(secondmissiontest ../tests/second_mission_test.cpp game/second_mission.cpp)
    target_include_directories(secondmissiontest PRIVATE game)
    add_executable(scriptactortest ../tests/script_actor_test.cpp)
    target_link_libraries(scriptactortest PRIVATE ctw_gameplay)
    foreach(target pursuitmissiontest secondmissiontest scriptactortest)
        if(MSVC)
            target_compile_options(${target} PRIVATE /UNDEBUG)
        else()
            target_compile_options(${target} PRIVATE -UNDEBUG)
        endif()
    endforeach()
    add_test(NAME pursuit_mission COMMAND pursuitmissiontest)
    add_test(NAME second_mission COMMAND secondmissiontest)
    add_test(NAME script_actors COMMAND scriptactortest)
endif()

if(BUILD_TESTING)
    add_executable(meleecombotest ../tests/melee_combo_test.cpp)
    target_include_directories(meleecombotest PRIVATE game)
    add_test(NAME melee_combo COMMAND meleecombotest)
    add_executable(meleecombattest ../tests/melee_combat_test.cpp)
    target_link_libraries(meleecombattest PRIVATE ctw_gameplay)
    add_test(NAME melee_contact_classification COMMAND meleecombattest)
    add_executable(trainingdummycontacttest ../tests/training_dummy_contact_test.cpp)
    target_link_libraries(trainingdummycontacttest PRIVATE ctw_gameplay)
    add_test(NAME training_dummy_physical_contact COMMAND trainingdummycontacttest)
    set_tests_properties(training_dummy_physical_contact PROPERTIES SKIP_RETURN_CODE 77)
    set_tests_properties(melee_contact_classification PROPERTIES SKIP_RETURN_CODE 77)
endif()

if(BUILD_TESTING)
 add_executable(missionweaponloantest ../tests/mission_weapon_loan_test.cpp)
 target_link_libraries(missionweaponloantest PRIVATE ctw_gameplay)
 add_test(NAME mission_weapon_loan COMMAND missionweaponloantest)
 add_executable(pursuitscenegatetest ../tests/pursuit_scene_gate_test.cpp)
 target_include_directories(pursuitscenegatetest PRIVATE game)
 add_test(NAME pursuit_scene_gate COMMAND pursuitscenegatetest)
 add_executable(pursuitscenecleanuptest ../tests/pursuit_scene_cleanup_test.cpp)
 target_link_libraries(pursuitscenecleanuptest PRIVATE ctw_gameplay)
 add_test(NAME pursuit_scene_cleanup COMMAND pursuitscenecleanuptest)
 foreach(target missionweaponloantest pursuitscenegatetest pursuitscenecleanuptest meleecombotest meleecombattest)
  if(MSVC)
   target_compile_options(${target} PRIVATE /UNDEBUG)
  else()
   target_compile_options(${target} PRIVATE -UNDEBUG)
  endif()
 endforeach()
endif()

if(BUILD_TESTING)
 add_executable(sequenceworldoverlaytest ../tests/sequence_world_overlay_test.cpp)
 target_link_libraries(sequenceworldoverlaytest PRIVATE ctw_gameplay)
 target_compile_options(sequenceworldoverlaytest PRIVATE $<$<CXX_COMPILER_ID:GNU,Clang,AppleClang>:-UNDEBUG>)
 add_test(NAME sequence_world_overlay COMMAND sequenceworldoverlaytest)
endif()

# Original wanted population quotas and real traffic generation.
target_sources(ctw_gameplay PRIVATE game/wanted_population.cpp)
if(BUILD_TESTING)
 add_executable(wantedpopulationtest ../tests/wanted_population_test.cpp game/wanted_population.cpp src/os/datafile.cpp)
 target_include_directories(wantedpopulationtest PRIVATE game src)
 add_test(NAME wanted_population COMMAND wantedpopulationtest)
 add_executable(wantedpopulationintegrationtest ../tests/wanted_population_integration_test.cpp)
 target_link_libraries(wantedpopulationintegrationtest PRIVATE ctw_gameplay)
 add_test(NAME wanted_population_integration COMMAND wantedpopulationintegrationtest)
 set_tests_properties(wanted_population_integration PROPERTIES SKIP_RETURN_CODE 77)
endif()

# Original dumpster artwork and explicit pickup interaction.
target_sources(ctw_gameplay PRIVATE game/dumpster_view.cpp)
if(BUILD_TESTING)
 add_executable(dumpstertest ../tests/dumpster_test.cpp)
 target_link_libraries(dumpstertest PRIVATE ctw_gameplay)
 add_test(NAME dumpster COMMAND dumpstertest)
 add_executable(dumpsterviewtest ../tests/dumpster_view_test.cpp)
 target_link_libraries(dumpsterviewtest PRIVATE ctw_gameplay)
 add_test(NAME dumpster_original_art COMMAND dumpsterviewtest)
 set_tests_properties(dumpster_original_art PROPERTIES SKIP_RETURN_CODE 77)
 foreach(target dumpstertest dumpsterviewtest)
  if(MSVC)
   target_compile_options(${target} PRIVATE /UNDEBUG)
  else()
   target_compile_options(${target} PRIVATE -UNDEBUG)
  endif()
 endforeach()
endif()

# Append to port/CMakeLists.txt; do not replace that shared file.
target_sources(ctw_gameplay PRIVATE game/second_rescue.cpp)
if(BUILD_TESTING)
 add_executable(secondrescuerulestest ../tests/second_rescue_rules_test.cpp)
 target_include_directories(secondrescuerulestest PRIVATE game)
 add_test(NAME second_rescue_rules COMMAND secondrescuerulestest)
 add_executable(scriptpedtest ../tests/script_ped_test.cpp)
 target_link_libraries(scriptpedtest PRIVATE ctw_gameplay)
 add_test(NAME script_ped_behavior COMMAND scriptpedtest)
 add_executable(secondrescuetest ../tests/second_rescue_test.cpp)
 target_link_libraries(secondrescuetest PRIVATE ctw_gameplay)
 add_test(NAME second_rescue_scene COMMAND secondrescuetest)
 set_tests_properties(script_ped_behavior second_rescue_scene PROPERTIES SKIP_RETURN_CODE 77)
 foreach(target secondrescuerulestest scriptpedtest secondrescuetest)
  target_compile_options(${target} PRIVATE $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-UNDEBUG>)
 endforeach()
endif()
