diff --git a/library/xml b/library/xml index 2bc8fbdf7..ee2b63a8f 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 2bc8fbdf71143398817d31e06e169a01cce37c50 +Subproject commit ee2b63a8ffdbce66489148ca2a9803db1d0b9090 diff --git a/plugins/devel/dumpmats.cpp b/plugins/devel/dumpmats.cpp index ba888e7cf..0af1fce50 100644 --- a/plugins/devel/dumpmats.cpp +++ b/plugins/devel/dumpmats.cpp @@ -11,6 +11,7 @@ #include "df/matter_state.h" #include "df/descriptor_color.h" #include "df/item_type.h" +#include "df/strain_type.h" using std::string; using std::vector; @@ -195,47 +196,17 @@ command_result df_dumpmats (color_ostream &out, vector ¶meters) if (mat->molar_mass != 0xFBBC7818) out.print("\t[MOLAR_MASS:%i]\n", mat->molar_mass); - if (mat->strength.impact_yield != 10000) - out.print("\t[IMPACT_YIELD:%i]\n", mat->strength.impact_yield); - if (mat->strength.impact_fracture != 10000) - out.print("\t[IMPACT_FRACTURE:%i]\n", mat->strength.impact_fracture); - if (mat->strength.impact_strain_at_yield != 0) - out.print("\t[IMPACT_STRAIN_AT_YIELD:%i]\n", mat->strength.impact_strain_at_yield); - - if (mat->strength.compressive_yield != 10000) - out.print("\t[COMPRESSIVE_YIELD:%i]\n", mat->strength.compressive_yield); - if (mat->strength.compressive_fracture != 10000) - out.print("\t[COMPRESSIVE_FRACTURE:%i]\n", mat->strength.compressive_fracture); - if (mat->strength.compressive_strain_at_yield != 0) - out.print("\t[COMPRESSIVE_STRAIN_AT_YIELD:%i]\n", mat->strength.compressive_strain_at_yield); - - if (mat->strength.tensile_yield != 10000) - out.print("\t[TENSILE_YIELD:%i]\n", mat->strength.tensile_yield); - if (mat->strength.tensile_fracture != 10000) - out.print("\t[TENSILE_FRACTURE:%i]\n", mat->strength.tensile_fracture); - if (mat->strength.tensile_strain_at_yield != 0) - out.print("\t[TENSILE_STRAIN_AT_YIELD:%i]\n", mat->strength.tensile_strain_at_yield); - - if (mat->strength.torsion_yield != 10000) - out.print("\t[TORSION_YIELD:%i]\n", mat->strength.torsion_yield); - if (mat->strength.torsion_fracture != 10000) - out.print("\t[TORSION_FRACTURE:%i]\n", mat->strength.torsion_fracture); - if (mat->strength.torsion_strain_at_yield != 0) - out.print("\t[TORSION_STRAIN_AT_YIELD:%i]\n", mat->strength.torsion_strain_at_yield); - - if (mat->strength.shear_yield != 10000) - out.print("\t[SHEAR_YIELD:%i]\n", mat->strength.shear_yield); - if (mat->strength.shear_fracture != 10000) - out.print("\t[SHEAR_FRACTURE:%i]\n", mat->strength.shear_fracture); - if (mat->strength.shear_strain_at_yield != 0) - out.print("\t[SHEAR_STRAIN_AT_YIELD:%i]\n", mat->strength.shear_strain_at_yield); - - if (mat->strength.bending_yield != 10000) - out.print("\t[BENDING_YIELD:%i]\n", mat->strength.bending_yield); - if (mat->strength.bending_fracture != 10000) - out.print("\t[BENDING_FRACTURE:%i]\n", mat->strength.bending_fracture); - if (mat->strength.bending_strain_at_yield != 0) - out.print("\t[BENDING_STRAIN_AT_YIELD:%i]\n", mat->strength.bending_strain_at_yield); + FOR_ENUM_ITEMS(strain_type, strain) + { + auto name = ENUM_KEY_STR(strain_type,strain); + + if (mat->strength.yield[strain] != 10000) + out.print("\t[%s_YIELD:%i]\n", name.c_str(), mat->strength.yield[strain]); + if (mat->strength.fracture[strain] != 10000) + out.print("\t[%s_FRACTURE:%i]\n", name.c_str(), mat->strength.fracture[strain]); + if (mat->strength.strain_at_yield[strain] != 0) + out.print("\t[%s_STRAIN_AT_YIELD:%i]\n", name.c_str(), mat->strength.strain_at_yield[strain]); + } if (mat->strength.max_edge != 0) out.print("\t[MAX_EDGE:%i]\n", mat->strength.max_edge); diff --git a/plugins/devel/siege-engine.cpp b/plugins/devel/siege-engine.cpp index a41bfe5f7..d1e34ced9 100644 --- a/plugins/devel/siege-engine.cpp +++ b/plugins/devel/siege-engine.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -45,11 +46,14 @@ #include "df/unit_misc_trait.h" #include "df/job.h" #include "df/job_item.h" -#include "df/item.h" +#include "df/item_actual.h" #include "df/items_other_id.h" #include "df/building_stockpilest.h" #include "df/stockpile_links.h" #include "df/workshop_profile.h" +#include "df/strain_type.h" +#include "df/material.h" +#include "df/flow_type.h" #include "MiscUtils.h" @@ -162,6 +166,63 @@ static void random_direction(float &x, float &y, float &z) z = 1.0f - 2.0f*d; } +static const int WEAR_TICKS = 806400; + +static bool apply_impact_damage(df::item *item, int minv, int maxv) +{ + MaterialInfo info(item); + if (!info.isValid()) + { + item->setWear(3); + return false; + } + + auto &strength = info.material->strength; + + // Use random strain type excluding COMPRESSIVE (conveniently last) + int type = random_int(strain_type::COMPRESSIVE); + int power = minv + random_int(maxv-minv+1); + + // High elasticity materials just bend + if (strength.strain_at_yield[type] >= 5000) + return true; + + // Instant fracture? + int fracture = strength.fracture[type]; + if (fracture <= power) + { + item->setWear(3); + return false; + } + + // Impact within elastic strain range? + int yield = strength.yield[type]; + if (yield > power) + return true; + + // Can wear? + auto actual = virtual_cast(item); + if (!actual) + return false; + + // Transform plastic deformation to wear + int max_wear = WEAR_TICKS * 4; + int cur_wear = WEAR_TICKS * actual->wear + actual->wear_timer; + cur_wear += int64_t(power - yield)*max_wear/(fracture - yield); + + if (cur_wear >= max_wear) + { + actual->wear = 3; + return false; + } + else + { + actual->wear = cur_wear / WEAR_TICKS; + actual->wear_timer = cur_wear % WEAR_TICKS; + return true; + } +} + /* * Configuration object */ @@ -1363,6 +1424,10 @@ struct projectile_hook : df::proj_itemst { float speed = 100000.0f / (fall_delay + 1); int min_zspeed = (fall_delay+1)*4900; + float bonus = 1.0f + 0.1f*(origin_pos.z -cur_pos.z); + bonus *= 1.0f + (distance_flown - 60) / 200.0f; + speed *= bonus; + // Flight direction vector df::coord dist = target_pos - origin_pos; float vx = dist.x, vy = dist.y, vz = fabs(dist.z); @@ -1383,10 +1448,28 @@ struct projectile_hook : df::proj_itemst { for (size_t i = 0; i < contents.size(); i++) { auto child = contents[i]; + + // Liquids are vaporized so that they cover nearby units + if (child->isLiquid()) + { + auto flow = Maps::spawnFlow( + cur_pos, + flow_type::MaterialVapor, + child->getMaterial(), child->getMaterialIndex(), + 100 + ); + + // should it leave a puddle too?.. + if (flow && Items::remove(mc, child)) + continue; + } + auto proj = Items::makeProjectile(mc, child); if (!proj) continue; - proj->flags.bits.no_impact_destroy = true; + bool keep = apply_impact_damage(child, 50000, int(250000*bonus)); + + proj->flags.bits.no_impact_destroy = keep; //proj->flags.bits.bouncing = true; proj->flags.bits.piercing = true; proj->flags.bits.parabolic = true; @@ -1403,7 +1486,7 @@ struct projectile_hook : df::proj_itemst { proj->speed_x = int(speed * sx); proj->speed_y = int(speed * sy); - proj->speed_z = int(speed * sz); + proj->speed_z = std::max(min_zspeed, int(speed * sz)); } }