diff --git a/data/json/items/tool/deployable.json b/data/json/items/tool/deployable.json
index 8b6694d82acf..67257f0326b7 100644
--- a/data/json/items/tool/deployable.json
+++ b/data/json/items/tool/deployable.json
@@ -140,6 +140,29 @@
},
"flags": [ "ALLOWS_REMOTE_USE" ]
},
+ {
+ "id": "folding_skateboard",
+ "type": "TOOL",
+ "category": "tools",
+ "name": { "str": "skateboard" },
+ "description": "This is a skateboard.",
+ "weight": "2898 g",
+ "volume": "3750 ml",
+ "price": "350 USD",
+ "price_postapoc": "20 USD",
+ "to_hit": -5,
+ "bashing": 10,
+ "material": "aluminum",
+ "symbol": "0",
+ "color": "light_gray",
+ "use_action": {
+ "type": "unfold_vehicle",
+ "vehicle_name": "skateboard",
+ "unfold_msg": "You lay the skateboard down on the ground.",
+ "moves": 0
+ },
+ "flags": [ "ALLOWS_REMOTE_USE" ]
+ },
{
"id": "generic_folded_vehicle",
"type": "TOOL",
diff --git a/data/json/items/vehicle/frames.json b/data/json/items/vehicle/frames.json
index f2d6b5a4d098..b3bd9f841b78 100644
--- a/data/json/items/vehicle/frames.json
+++ b/data/json/items/vehicle/frames.json
@@ -120,5 +120,20 @@
"price": "35 USD",
"price_postapoc": "1 USD",
"copy-from": "foldframe"
+ },
+ {
+ "type": "GENERIC",
+ "id": "frame_wood_deck",
+ "name": { "str": "skateboard deck" },
+ "symbol": "]",
+ "description": "A small skateboard frame made of thin layers of wood glued together.",
+ "weight": "1500 g",
+ "to_hit": -5,
+ "color": "brown",
+ "material": [ "wood" ],
+ "volume": "8750 ml",
+ "price": 1000,
+ "price_postapoc": 50,
+ "copy-from": "foldframe"
}
]
diff --git a/data/json/items/vehicle/wheel.json b/data/json/items/vehicle/wheel.json
index 73ed6a0096fe..54ef015e25ef 100644
--- a/data/json/items/vehicle/wheel.json
+++ b/data/json/items/vehicle/wheel.json
@@ -160,6 +160,39 @@
"diameter": 4,
"width": 1
},
+ {
+ "id": "wheel_skateboard",
+ "category": "veh_parts",
+ "type": "WHEEL",
+ "name": { "str": "set of skateboard wheels", "str_pl": "sets of skateboard wheels" },
+ "description": "A set of skateboard wheels.",
+ "weight": "1500 g",
+ "volume": "1250 ml",
+ "price": "20 USD",
+ "price_postapoc": "1 USD",
+ "bashing": 6,
+ "to_hit": -1,
+ "material": [ "steel", "plastic" ],
+ "symbol": "]",
+ "color": "dark_gray",
+ "diameter": 2,
+ "width": 1
+ },
+ {
+ "id": "wheel_mount_skateboard",
+ "type": "GENERIC",
+ "category": "veh_parts",
+ "name": { "str": "pair of skateboard trucks", "str_pl": "pairs of skateboard trucks" },
+ "description": "A pair metal skateboard trucks, for attaching wheels to.",
+ "weight": "600 g",
+ "volume": "250 ml",
+ "price": 200,
+ "price_postapoc": 20,
+ "to_hit": -2,
+ "material": [ "steel" ],
+ "symbol": "]",
+ "color": "dark_gray"
+ },
{
"id": "wheel_10",
"category": "veh_parts",
diff --git a/data/json/mapgen/park_skate.json b/data/json/mapgen/park_skate.json
index 6e09e0ce6c51..9a4a2a35cc20 100644
--- a/data/json/mapgen/park_skate.json
+++ b/data/json/mapgen/park_skate.json
@@ -59,7 +59,9 @@
{ "vehicle": "bicycle", "x": 10, "y": 7, "chance": 3, "status": 0, "rotation": 270 },
{ "vehicle": "bicycle", "x": 17, "y": 8, "chance": 2, "status": 0, "rotation": 180 },
{ "vehicle": "scooter", "x": 16, "y": 12, "chance": 5 },
- { "vehicle": "bicycle", "x": 16, "y": 19, "chance": 7 }
+ { "vehicle": "bicycle", "x": 16, "y": 19, "chance": 7 },
+ { "vehicle": "skateboard", "x": 12, "y": 6, "chance": 3, "status": 0 },
+ { "vehicle": "skateboard", "x": 19, "y": 10, "chance": 2, "status": 0 }
]
}
}
diff --git a/data/json/professions.json b/data/json/professions.json
index abedb1e131bb..8e16b6e0c428 100644
--- a/data/json/professions.json
+++ b/data/json/professions.json
@@ -4320,10 +4320,10 @@
{
"type": "profession",
"id": "skaterkid",
- "name": { "male": "Skater Boy", "female": "Skater Girl" },
+ "name": { "male": "Skater Boy (Rollerblades)", "female": "Skater Girl (Rollerblades)" },
"description": "You love to skate! At least now the grown-ups aren't telling you where you can't roll.",
"points": 1,
- "skills": [ { "level": 1, "name": "dodge" } ],
+ "skills": [ { "level": 1, "name": "dodge" }, { "level": 2, "name": "swimming" } ],
"traits": [ "PROF_SKATER" ],
"items": {
"both": {
@@ -4346,6 +4346,35 @@
"female": [ "boy_shorts" ]
}
},
+ {
+ "type": "profession",
+ "id": "skaterkid_board",
+ "name": { "male": "Skater Boy (Skateboard)", "female": "Skater Girl (Skateboard)" },
+ "description": "You love to skate! You've probably spent more time on a skateboard than off. Things have gotten pretty bad, but at least the grown-ups aren't telling you where you can't roll.",
+ "points": 1,
+ "skills": [ { "level": 2, "name": "driving" }, { "level": 2, "name": "swimming" } ],
+ "traits": [ "PROF_SKATER" ],
+ "items": {
+ "both": {
+ "items": [
+ "hoodie",
+ "jeans",
+ "socks",
+ "elbow_pads",
+ "knee_pads",
+ "gloves_fingerless",
+ "helmet_skid",
+ "sneakers",
+ "folding_skateboard",
+ "wristwatch",
+ "smart_phone",
+ "sports_drink"
+ ]
+ },
+ "male": [ "briefs" ],
+ "female": [ "boy_shorts" ]
+ }
+ },
{
"type": "profession",
"id": "jdelinquent",
diff --git a/data/json/vehicleparts/frames.json b/data/json/vehicleparts/frames.json
index 0c1b318f43cf..0767823bfa76 100644
--- a/data/json/vehicleparts/frames.json
+++ b/data/json/vehicleparts/frames.json
@@ -173,6 +173,40 @@
"flags": [ "MOUNTABLE" ],
"damage_reduction": { "all": 84 }
},
+ {
+ "id": "frame_wood_deck",
+ "type": "vehicle_part",
+ "name": { "str": "skateboard deck" },
+ "copy-from": "frame_wood_light",
+ "item": "frame_wood_deck",
+ "symbol": "]",
+ "looks_like": "frame_wood",
+ "durability": 100,
+ "fuel_type": "muscle",
+ "power": 140,
+ "muscle_power_factor": 30,
+ "m2c": 45,
+ "description": "A light wooden skateboard deck. Other skateboard components can be mounted on it.",
+ "breaks_into": [ { "item": "splinter", "count": [ 3, 5 ] } ],
+ "requirements": {
+ "install": { "skills": [ [ "fabrication", 0 ] ], "time": "0 m" },
+ "removal": { "skills": [ [ "fabrication", 0 ] ], "time": "0 m" },
+ "repair": { "skills": [ [ "fabrication", 0 ] ], "time": "5 m", "using": [ [ "adhesive", 1 ] ] }
+ },
+ "flags": [
+ "MOUNTABLE",
+ "INITIAL_PART",
+ "SEAT",
+ "ENGINE",
+ "E_STARTS_INSTANTLY",
+ "NONBELTABLE",
+ "MUSCLE_LEGS",
+ "SEAT_REQUIRES_BALANCE",
+ "BOARDABLE",
+ "CONTROLS"
+ ],
+ "damage_reduction": { "all": 2 }
+ },
{
"id": "frame_cover",
"copy-from": "frame",
diff --git a/data/json/vehicleparts/vp_flags.json b/data/json/vehicleparts/vp_flags.json
index 862bb3d10e55..812766f64022 100644
--- a/data/json/vehicleparts/vp_flags.json
+++ b/data/json/vehicleparts/vp_flags.json
@@ -240,5 +240,21 @@
"type": "json_flag",
"context": [ "vehicle_part" ],
"requires_flag": "ROOF"
+ },
+ {
+ "id": "SEAT_REQUIRES_BALANCE",
+ "context": [ "vehicle_part" ],
+ "type": "json_flag"
+ },
+ {
+ "id": "WHEEL_MOUNT_SKATEBOARD",
+ "context": [ "vehicle_part" ],
+ "type": "json_flag"
+ },
+ {
+ "id": "NEEDS_WHEEL_MOUNT_SKATEBOARD",
+ "context": [ "vehicle_part" ],
+ "type": "json_flag",
+ "requires_flag": "WHEEL_MOUNT_SKATEBOARD"
}
]
diff --git a/data/json/vehicleparts/wheel.json b/data/json/vehicleparts/wheel.json
index b3da1945e44c..d03c9a7b8b5a 100644
--- a/data/json/vehicleparts/wheel.json
+++ b/data/json/vehicleparts/wheel.json
@@ -350,6 +350,55 @@
},
"flags": [ "WHEEL", "NEEDS_JACKING", "STABLE", "FOLDABLE", "STEERABLE" ]
},
+ {
+ "id": "wheel_skateboard",
+ "type": "vehicle_part",
+ "name": { "str": "skateboard wheels" },
+ "item": "wheel_skateboard",
+ "location": "under",
+ "color": "dark_gray",
+ "symbol": "o",
+ "broken_symbol": "x",
+ "durability": 70,
+ "description": "A set of four small wheels, for a skateboard.",
+ "damage_modifier": 50,
+ "folded_volume": "1250 ml",
+ "wheel_type": "standard",
+ "contact_area": 4,
+ "requirements": {
+ "removal": { "skills": [ [ "mechanics", 0 ] ], "time": "1 m", "qualities": [ { "id": "WRENCH", "level": 2 } ] },
+ "install": { "skills": [ [ "mechanics", 0 ] ], "time": "1 m", "qualities": [ { "id": "WRENCH", "level": 2 } ] }
+ },
+ "flags": [ "WHEEL", "NEEDS_WHEEL_MOUNT_SKATEBOARD", "STABLE", "STEERABLE" ]
+ },
+ {
+ "id": "wheel_mount_skateboard",
+ "type": "vehicle_part",
+ "name": { "str": "skateboard trucks" },
+ "item": "wheel_mount_skateboard",
+ "location": "axle",
+ "symbol": "-",
+ "broken_symbol": "x",
+ "damage_modifier": 80,
+ "folded_volume": "200 ml",
+ "durability": 120,
+ "description": "A pair of skateboard trucks, for attaching wheels to.",
+ "flags": [ "WHEEL_MOUNT_SKATEBOARD" ],
+ "requirements": {
+ "removal": {
+ "skills": [ [ "mechanics", 0 ] ],
+ "time": "3 m",
+ "qualities": [ { "id": "WRENCH", "level": 2 }, { "id": "SCREW", "level": 1 } ]
+ },
+ "install": {
+ "skills": [ [ "mechanics", 0 ] ],
+ "time": "3 m",
+ "qualities": [ { "id": "WRENCH", "level": 2 }, { "id": "SCREW", "level": 1 } ]
+ }
+ },
+ "breaks_into": [ { "item": "scrap", "count": [ 0, 1 ] } ],
+ "damage_reduction": { "all": 10 }
+ },
{
"id": "wheel_10",
"type": "vehicle_part",
diff --git a/data/json/vehicles/bikes.json b/data/json/vehicles/bikes.json
index 45bbd13d7a5d..0b2d4532a552 100644
--- a/data/json/vehicles/bikes.json
+++ b/data/json/vehicles/bikes.json
@@ -292,5 +292,12 @@
"parts": [ "frame_carbon_vertical", "wheel_mount_light", "wheel_bicycle_rear", "basketsm_bike_rear" ]
}
]
+ },
+ {
+ "id": "skateboard",
+ "type": "vehicle",
+ "name": "Skateboard",
+ "blueprint": [ "$" ],
+ "parts": [ { "x": 0, "y": 0, "parts": [ "frame_wood_deck", "wheel_mount_skateboard", "wheel_skateboard" ] } ]
}
]
diff --git a/data/json/vehicles/carts.json b/data/json/vehicles/carts.json
index 55ff473e455d..4df91d6fdf67 100644
--- a/data/json/vehicles/carts.json
+++ b/data/json/vehicles/carts.json
@@ -296,7 +296,7 @@
{
"id": "wheelchair",
"type": "vehicle",
- "name": "Foldable wheelchair",
+ "name": "Wheelchair",
"blueprint": [ "#" ],
"parts": [
{ "x": 0, "y": 0, "part": "folding_frame" },
diff --git a/msvc-full-features/Cataclysm-lib-vcpkg-static.vcxproj b/msvc-full-features/Cataclysm-lib-vcpkg-static.vcxproj
index 7730f8fd07b0..b03081f6c2aa 100644
--- a/msvc-full-features/Cataclysm-lib-vcpkg-static.vcxproj
+++ b/msvc-full-features/Cataclysm-lib-vcpkg-static.vcxproj
@@ -39,10 +39,9 @@
--clean-after-build
-
StaticLibrary
- v142
+ v143
MultiByte
@@ -52,7 +51,6 @@
false
false
-
@@ -134,15 +132,17 @@
NotUsing
-
+
+
NotUsing
-
+
+
-
+
@@ -154,4 +154,4 @@
-
+
\ No newline at end of file
diff --git a/msvc-full-features/Cataclysm-test-vcpkg-static.vcxproj b/msvc-full-features/Cataclysm-test-vcpkg-static.vcxproj
index 8eebabe990f9..e69fcb4e48e4 100644
--- a/msvc-full-features/Cataclysm-test-vcpkg-static.vcxproj
+++ b/msvc-full-features/Cataclysm-test-vcpkg-static.vcxproj
@@ -41,7 +41,7 @@
Application
- v142
+ v143
MultiByte
@@ -148,4 +148,4 @@
-
+
\ No newline at end of file
diff --git a/msvc-full-features/Cataclysm-vcpkg-static.vcxproj b/msvc-full-features/Cataclysm-vcpkg-static.vcxproj
index bfdabb88cc81..56b8caf0ac8a 100644
--- a/msvc-full-features/Cataclysm-vcpkg-static.vcxproj
+++ b/msvc-full-features/Cataclysm-vcpkg-static.vcxproj
@@ -41,7 +41,7 @@
Application
- v142
+ v143
MultiByte
@@ -165,4 +165,4 @@
-
+
\ No newline at end of file
diff --git a/msvc-full-features/JsonFormatter-vcpkg-static.vcxproj b/msvc-full-features/JsonFormatter-vcpkg-static.vcxproj
index aeacba199e97..b3c8b1511e89 100644
--- a/msvc-full-features/JsonFormatter-vcpkg-static.vcxproj
+++ b/msvc-full-features/JsonFormatter-vcpkg-static.vcxproj
@@ -41,7 +41,7 @@
Application
- v142
+ v143
MultiByte
@@ -161,4 +161,4 @@
-
+
\ No newline at end of file
diff --git a/src/character.cpp b/src/character.cpp
index 8a9a6eceafde..f6e70a23604d 100644
--- a/src/character.cpp
+++ b/src/character.cpp
@@ -8742,26 +8742,46 @@ void Character::on_hit( Creature *source, bodypart_id bp_hit,
source->add_effect( effect_blind, 2_turns );
}
}
- if( worn_with_flag( flag_REQUIRES_BALANCE ) && !has_effect( effect_downed ) ) {
+
+ map &here = get_map();
+ const optional_vpart_position veh_part = here.veh_at( pos() );
+ bool in_skater_vehicle = in_vehicle && veh_part.part_with_feature( "SEAT_REQUIRES_BALANCE", false );
+
+ if( ( worn_with_flag( flag_REQUIRES_BALANCE ) || in_skater_vehicle ) && !is_on_ground() ) {
int rolls = 4;
- if( worn_with_flag( flag_ROLLER_ONE ) ) {
- rolls += 2;
- }
- if( has_trait( trait_PROF_SKATER ) ) {
- rolls--;
- }
- if( has_trait( trait_DEFT ) ) {
- rolls--;
- }
+ if( worn_with_flag( flag_ROLLER_ONE ) && !in_skater_vehicle ) {
+ if( worn_with_flag( flag_REQUIRES_BALANCE ) && !has_effect( effect_downed ) ) {
+ int rolls = 4;
+ if( worn_with_flag( flag_ROLLER_ONE ) ) {
+ rolls += 2;
+ }
+ if( has_trait( trait_PROF_SKATER ) ) {
+ rolls--;
+ }
+ if( has_trait( trait_DEFT ) ) {
+ rolls--;
+ }
- if( stability_roll() < dice( rolls, 10 ) ) {
- if( !is_player() ) {
- if( u_see ) {
- add_msg( _( "%1$s loses their balance while being hit!" ), name );
+ if( stability_roll() < dice( rolls, 10 ) ) {
+ if( !is_player() ) {
+ if( u_see ) {
+ add_msg( _( "%1$s loses their balance while being hit!" ), name );
+ }
+ } else {
+ add_msg( m_bad, _( "You lose your balance while being hit!" ) );
+ }
+ if( in_skater_vehicle ) {
+ g->fling_creature( this, rng_float( 0_degrees, 360_degrees ), 10 );
+ }
+ // This kind of downing is not subject to immunity.
+ add_effect( effect_downed, 2_turns, bodypart_str_id::NULL_ID(), 0, true );
}
} else {
add_msg( m_bad, _( "You lose your balance while being hit!" ) );
}
+ if( in_skater_vehicle ) {
+ g->fling_creature( this, rng_float( 0_degrees, 360_degrees ), 10 );
+ }
// This kind of downing is not subject to immunity.
add_effect( effect_downed, 2_turns, bodypart_str_id::NULL_ID(), 0, true );
}
diff --git a/src/vehicle_move.cpp b/src/vehicle_move.cpp
index 137e84a38ba7..72c24f6f70ce 100644
--- a/src/vehicle_move.cpp
+++ b/src/vehicle_move.cpp
@@ -51,6 +51,11 @@ static const itype_id fuel_type_battery( "battery" );
static const skill_id skill_driving( "driving" );
+static const trait_id trait_DEFT("DEFT");
+static const trait_id trait_PROF_SKATER("PROF_SKATER");
+static const trait_id trait_DEFT( "DEFT" );
+static const trait_id trait_PROF_SKATER( "PROF_SKATER" );
+
static const efftype_id effect_harnessed( "harnessed" );
static const efftype_id effect_pet( "pet" );
static const efftype_id effect_stunned( "stunned" );
@@ -1687,6 +1692,18 @@ units::angle map::shake_vehicle( vehicle &veh, const int velocity_before,
if( psg ) {
///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
move_resist = psg->str_cur * 150 + 500;
+ if( veh.part( ps ).info().has_flag( "SEAT_REQUIRES_BALANCE" ) ) {
+ // Much harder to resist being thrown on a skateboard-like vehicle.
+ // Penalty mitigated by Deft and Skater.
+ int resist_penalty = 500;
+ if( psg->has_trait( trait_PROF_SKATER ) ) {
+ resist_penalty -= 150;
+ }
+ if( psg->has_trait( trait_DEFT ) ) {
+ resist_penalty -= 150;
+ }
+ move_resist -= resist_penalty;
+ }
} else {
int pet_resist = 0;
if( pet != nullptr ) {
diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp
index 150c5e28af83..bd7eb8151986 100644
--- a/src/vehicle_use.cpp
+++ b/src/vehicle_use.cpp
@@ -887,6 +887,7 @@ void vehicle::use_controls( const tripoint &pos )
bool vehicle::fold_up()
{
const bool can_be_folded = is_foldable();
+
const bool is_convertible = ( tags.contains( "convertible" ) );
if( !( can_be_folded || is_convertible ) ) {
debugmsg( _( "Tried to fold non-folding vehicle %s" ), name );
@@ -912,7 +913,8 @@ bool vehicle::fold_up()
add_msg( _( "You let go of %s as you fold it." ), name );
}
- std::string itype_id = "folding_bicycle";
+ std::string itype_id = "generic_folded_vehicle";
+ // Determine the item type from tags
for( const auto &elem : tags ) {
if( elem.compare( 0, 12, "convertible:" ) == 0 ) {
itype_id = elem.substr( 12 );
@@ -920,10 +922,16 @@ bool vehicle::fold_up()
}
}
- // create a folding [non]bicycle item
- detached_ptr- bicycle = item::spawn( can_be_folded ? "generic_folded_vehicle" :
- "folding_bicycle",
- calendar::turn );
+ // Decide the spawn type based on item and folding state
+ std::string spawn_type;
+ if( itype_id == "folding_bicycle" || itype_id == "folding_skateboard" ) {
+ spawn_type = itype_id;
+ } else {
+ spawn_type = "generic_folded_vehicle"; // Handle unexpected cases
+ }
+
+ // Create the item
+ detached_ptr
- bicycle = item::spawn( spawn_type, calendar::turn );
// Drop stuff in containers on ground
for( const vpart_reference &vp : get_any_parts( "CARGO" ) ) {
@@ -949,13 +957,19 @@ bool vehicle::fold_up()
debugmsg( "Error storing vehicle: %s", e.c_str() );
}
- if( can_be_folded ) {
+ // i dont understand what the can_be_folded check was for here.
+ // seems to only evaluate true if vehicle has a part with FOLDING tag.
+ // the folding bicycle does not? instead the item itself seems to turn the vehicle into folding
+ if( spawn_type == "generic_folded_vehicle" ) {
bicycle->set_var( "weight", to_milligram( total_mass() ) );
bicycle->set_var( "volume", total_folded_volume() / units::legacy_volume_factor );
- bicycle->set_var( "name", string_format( _( "folded %s" ), name ) );
+ // remove "folded" from name to allow for more flexibility with folded vehicle names. also lowers first character
+ bicycle->set_var( "name", string_format( _( "%s" ), ( name.empty() ? name : std::string( 1,
+ std::tolower( name[0] ) ) + name.substr( 1 ) ) ) );
bicycle->set_var( "vehicle_name", name );
// TODO: a better description?
- bicycle->set_var( "description", string_format( _( "A folded %s." ), name ) );
+ bicycle->set_var( "description", string_format( _( "A folded %s." ),
+ ( name.empty() ? name : std::string( 1, std::tolower( name[0] ) ) + name.substr( 1 ) ) ) );
}
g->m.add_item_or_charges( global_part_pos3( 0 ), std::move( bicycle ) );