Vaporize liquids from barrels, and destroy bin contents in siege engine.

develop
Alexander Gavrilov 2012-09-14 20:22:49 +04:00
parent 24772f4dbc
commit 811c096c0e
3 changed files with 99 additions and 45 deletions

@ -1 +1 @@
Subproject commit 2bc8fbdf71143398817d31e06e169a01cce37c50
Subproject commit ee2b63a8ffdbce66489148ca2a9803db1d0b9090

@ -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<string> &parameters)
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);

@ -10,6 +10,7 @@
#include <modules/World.h>
#include <modules/Units.h>
#include <modules/Job.h>
#include <modules/Materials.h>
#include <LuaTools.h>
#include <TileTypes.h>
#include <vector>
@ -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<df::item_actual>(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));
}
}