mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-08-13 11:54:04 +02:00
jacksonmj: EMP lag is hereby banished. eeef50c0fcba
EMP destruction loop now happens once per frame instead of once per EMP particle.
This commit is contained in:
55
src/Probability.cpp
Normal file
55
src/Probability.cpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
|
||||||
|
#include <numeric>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include "Probability.h"
|
||||||
|
|
||||||
|
namespace Probability
|
||||||
|
{
|
||||||
|
|
||||||
|
float binomial_gte1(int n, float p)
|
||||||
|
{
|
||||||
|
return 1.0f - std::pow(1.0f-p, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
float randFloat()
|
||||||
|
{
|
||||||
|
return static_cast<float>(rand())/RAND_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallKBinomialGenerator::SmallKBinomialGenerator(unsigned int n, float p, unsigned int maxK_)
|
||||||
|
{
|
||||||
|
maxK = maxK_;
|
||||||
|
cdf = new float[maxK];
|
||||||
|
|
||||||
|
float *pdf = new float[maxK];
|
||||||
|
// initial values, k=0:
|
||||||
|
float pTerm = std::pow(1.0f-p, n); // the p^k * (1-p)^(n-k) term
|
||||||
|
unsigned int coeffN = 1, coeffD = 1; // (N / D) evaluates to the same result as the n!/(k!(n-k)!) term
|
||||||
|
for (unsigned int k=0; k<maxK; k++)
|
||||||
|
{
|
||||||
|
pdf[k] = pTerm * (float(coeffN) / coeffD);
|
||||||
|
pTerm *= p/(1.0f-p);
|
||||||
|
coeffN *= n-k; // Part of the n! will no longer cancelled out by (n-k)!
|
||||||
|
coeffD *= k+1; // k! (k+1 because this is for next k)
|
||||||
|
}
|
||||||
|
|
||||||
|
std::partial_sum(pdf, pdf+maxK, cdf);
|
||||||
|
delete[] pdf;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallKBinomialGenerator::~SmallKBinomialGenerator()
|
||||||
|
{
|
||||||
|
delete[] cdf;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int SmallKBinomialGenerator::calc(float randFloat)
|
||||||
|
{
|
||||||
|
for (unsigned int k=0; k<maxK; k++)
|
||||||
|
{
|
||||||
|
if (randFloat<cdf[k])
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
return maxK;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
45
src/Probability.h
Normal file
45
src/Probability.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef tptmath_h
|
||||||
|
#define tptmath_h
|
||||||
|
|
||||||
|
// This file is used for EMP, to simulate many EMP going off at once at the end of the frame
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace Probability
|
||||||
|
{
|
||||||
|
// X ~ binomial(n,p), returns P(X>=1)
|
||||||
|
// e.g. If a reaction has n chances of occurring, each time with probability p, this returns the probability that it occurs at least once.
|
||||||
|
float binomial_gte1(int n, float p);
|
||||||
|
float randFloat();
|
||||||
|
|
||||||
|
class SmallKBinomialGenerator
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
float *cdf;
|
||||||
|
unsigned int maxK;
|
||||||
|
public:
|
||||||
|
// Class to generate numbers from a binomial distribution, up to a maximum value (maxK).
|
||||||
|
// Results which would have been above maxK return maxK.
|
||||||
|
// Note: maxK must be small, otherwise the method used in this class is inefficient. (n and p can be any valid value)
|
||||||
|
SmallKBinomialGenerator(unsigned int n, float p, unsigned int maxK_);
|
||||||
|
~SmallKBinomialGenerator();
|
||||||
|
unsigned int calc(float randFloat);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -879,9 +879,12 @@ void GameController::Update()
|
|||||||
gameView->SetSample(gameModel->GetSimulation()->GetSample(pos.X, pos.Y));
|
gameView->SetSample(gameModel->GetSimulation()->GetSample(pos.X, pos.Y));
|
||||||
|
|
||||||
Simulation * sim = gameModel->GetSimulation();
|
Simulation * sim = gameModel->GetSimulation();
|
||||||
sim->UpdateSim();
|
sim->BeforeSim();
|
||||||
if (!sim->sys_pause || sim->framerender)
|
if (!sim->sys_pause || sim->framerender)
|
||||||
|
{
|
||||||
sim->UpdateParticles(0, NPART);
|
sim->UpdateParticles(0, NPART);
|
||||||
|
sim->AfterSim();
|
||||||
|
}
|
||||||
|
|
||||||
//if either STKM or STK2 isn't out, reset it's selected element. Defaults to PT_DUST unless right selected is something else
|
//if either STKM or STK2 isn't out, reset it's selected element. Defaults to PT_DUST unless right selected is something else
|
||||||
//This won't run if the stickmen dies in a frame, since it respawns instantly
|
//This won't run if the stickmen dies in a frame, since it respawns instantly
|
||||||
@@ -1459,8 +1462,9 @@ void GameController::ParticleDebug(int mode, int x, int y)
|
|||||||
sim->debug_currentParticle = i+1;
|
sim->debug_currentParticle = i+1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
sim->Aftersim();
|
||||||
sim->framerender = 1;
|
sim->framerender = 1;
|
||||||
sim->UpdateSim();
|
sim->BeforeSim();
|
||||||
sim->framerender = 0;
|
sim->framerender = 0;
|
||||||
sim->debug_currentParticle = 0;
|
sim->debug_currentParticle = 0;
|
||||||
}
|
}
|
||||||
|
@@ -1912,6 +1912,7 @@ void Simulation::create_arc(int sx, int sy, int dx, int dy, int midpoints, int v
|
|||||||
void Simulation::clear_sim(void)
|
void Simulation::clear_sim(void)
|
||||||
{
|
{
|
||||||
emp_decor = 0;
|
emp_decor = 0;
|
||||||
|
emp_trigger_count = 0;
|
||||||
signs.clear();
|
signs.clear();
|
||||||
memset(bmap, 0, sizeof(bmap));
|
memset(bmap, 0, sizeof(bmap));
|
||||||
memset(emap, 0, sizeof(emap));
|
memset(emap, 0, sizeof(emap));
|
||||||
@@ -4783,7 +4784,7 @@ void Simulation::CheckStacking()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//updates pmap, gol, and some other simulation stuff (but not particles)
|
//updates pmap, gol, and some other simulation stuff (but not particles)
|
||||||
void Simulation::UpdateSim()
|
void Simulation::BeforeSim()
|
||||||
{
|
{
|
||||||
int i, x, y, t;
|
int i, x, y, t;
|
||||||
int lastPartUsed = 0;
|
int lastPartUsed = 0;
|
||||||
@@ -5056,6 +5057,15 @@ void Simulation::UpdateSim()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Simulation::AfterSim()
|
||||||
|
{
|
||||||
|
if (emp_trigger_count)
|
||||||
|
{
|
||||||
|
Element_EMP::Trigger(this, emp_trigger_count);
|
||||||
|
emp_trigger_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Simulation::~Simulation()
|
Simulation::~Simulation()
|
||||||
{
|
{
|
||||||
delete[] platent;
|
delete[] platent;
|
||||||
@@ -5072,6 +5082,7 @@ Simulation::Simulation():
|
|||||||
ISWIRE(0),
|
ISWIRE(0),
|
||||||
force_stacking_check(0),
|
force_stacking_check(0),
|
||||||
emp_decor(0),
|
emp_decor(0),
|
||||||
|
emp_trigger_count(0),
|
||||||
lightningRecreate(0),
|
lightningRecreate(0),
|
||||||
gravWallChanged(false),
|
gravWallChanged(false),
|
||||||
CGOL(0),
|
CGOL(0),
|
||||||
|
@@ -62,6 +62,7 @@ public:
|
|||||||
int ISWIRE;
|
int ISWIRE;
|
||||||
int force_stacking_check;
|
int force_stacking_check;
|
||||||
int emp_decor;
|
int emp_decor;
|
||||||
|
int emp_trigger_count;
|
||||||
int lightningRecreate;
|
int lightningRecreate;
|
||||||
//Stickman
|
//Stickman
|
||||||
playerst player;
|
playerst player;
|
||||||
@@ -159,7 +160,8 @@ public:
|
|||||||
void UpdateParticles(int start, int end);
|
void UpdateParticles(int start, int end);
|
||||||
void SimulateGoL();
|
void SimulateGoL();
|
||||||
void CheckStacking();
|
void CheckStacking();
|
||||||
void UpdateSim();
|
void BeforeSim();
|
||||||
|
void AfterSim();
|
||||||
void rotate_area(int area_x, int area_y, int area_w, int area_h, int invert);
|
void rotate_area(int area_x, int area_y, int area_w, int area_h, int invert);
|
||||||
void clear_area(int area_x, int area_y, int area_w, int area_h);
|
void clear_area(int area_x, int area_y, int area_w, int area_h);
|
||||||
|
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
#include "simulation/Elements.h"
|
#include "simulation/Elements.h"
|
||||||
|
#include "Probability.h"
|
||||||
|
|
||||||
//#TPT-Directive ElementClass Element_EMP PT_EMP 134
|
//#TPT-Directive ElementClass Element_EMP PT_EMP 134
|
||||||
Element_EMP::Element_EMP()
|
Element_EMP::Element_EMP()
|
||||||
{
|
{
|
||||||
@@ -45,55 +47,121 @@ Element_EMP::Element_EMP()
|
|||||||
Graphics = &Element_EMP::graphics;
|
Graphics = &Element_EMP::graphics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DeltaTempGenerator
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
float stepSize;
|
||||||
|
unsigned int maxStepCount;
|
||||||
|
Probability::SmallKBinomialGenerator binom;
|
||||||
|
public:
|
||||||
|
DeltaTempGenerator(int n, float p, float tempStep) :
|
||||||
|
stepSize(tempStep),
|
||||||
|
// hardcoded limit of 10, to avoid massive lag if someone adds a few zeroes to MAX_TEMP
|
||||||
|
maxStepCount((MAX_TEMP/stepSize < 10) ? ((unsigned int)(MAX_TEMP/stepSize)+1) : 10),
|
||||||
|
binom(n, p, maxStepCount)
|
||||||
|
{}
|
||||||
|
float getDelta(float randFloat)
|
||||||
|
{
|
||||||
|
// randFloat should be a random float between 0 and 1
|
||||||
|
return binom.calc(randFloat) * stepSize;
|
||||||
|
}
|
||||||
|
void apply(Simulation *sim, Particle &p)
|
||||||
|
{
|
||||||
|
p.temp = restrict_flt(p.temp+getDelta(Probability::randFloat()), MIN_TEMP, MAX_TEMP);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//#TPT-Directive ElementHeader Element_EMP static int update(UPDATE_FUNC_ARGS)
|
//#TPT-Directive ElementHeader Element_EMP static int update(UPDATE_FUNC_ARGS)
|
||||||
int Element_EMP::update(UPDATE_FUNC_ARGS)
|
int Element_EMP::update(UPDATE_FUNC_ARGS)
|
||||||
{
|
{
|
||||||
int r,rx,ry,t,n,nx,ny,ntype;
|
|
||||||
if (parts[i].life)
|
if (parts[i].life)
|
||||||
return 0;
|
return 0;
|
||||||
for (rx=-2; rx<3; rx++)
|
for (int rx =- 2; rx <= 2; rx++)
|
||||||
for (ry=-2; ry<3; ry++)
|
for (int ry = -2; ry <= 2; ry++)
|
||||||
if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry))
|
if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry))
|
||||||
{
|
{
|
||||||
r = pmap[y+ry][x+rx];
|
int r = pmap[y+ry][x+rx];
|
||||||
if (!r)
|
if (!r)
|
||||||
continue;
|
continue;
|
||||||
if ((r&0xFF)==PT_SPRK && parts[r>>8].life>0 && parts[r>>8].life<4)
|
if ((r&0xFF)==PT_SPRK && parts[r>>8].life > 0 && parts[r>>8].life < 4)
|
||||||
goto ok;
|
{
|
||||||
|
sim->emp_trigger_count++;
|
||||||
|
sim->emp_decor += 3;
|
||||||
|
if (sim->emp_decor > 40)
|
||||||
|
sim->emp_decor = 40;
|
||||||
|
parts[i].life = 220;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
ok:
|
}
|
||||||
parts[i].life=220;
|
|
||||||
sim->emp_decor += 3;
|
//#TPT-Directive ElementHeader Element_EMP static int Trigger(Simulation *sim, int triggerCount)
|
||||||
if (sim->emp_decor > 40)
|
int Element_EMP::Trigger(Simulation *sim, int triggerCount)
|
||||||
sim->emp_decor = 40;
|
{
|
||||||
for (r=0; r<=sim->parts_lastActiveIndex; r++)
|
/* Known differences from original one-particle-at-a-time version:
|
||||||
|
* - SPRK that disappears during a frame (such as SPRK with life==0 on that frame) will not cause destruction around it.
|
||||||
|
* - SPRK neighbour effects are calculated assuming the SPRK exists and causes destruction around it for the entire frame (so was not turned into BREL/NTCT partway through). This means mass EMP will be more destructive.
|
||||||
|
* - The chance of a METL particle near sparked semiconductor turning into BRMT within 1 frame is different if triggerCount>2. See comment for prob_breakMETLMore.
|
||||||
|
* - Probability of centre isElec particle breaking is slightly different (1/48 instead of 1-(1-1/80)*(1-1/120) = just under 1/48).
|
||||||
|
*/
|
||||||
|
|
||||||
|
Particle *parts = sim->parts;
|
||||||
|
|
||||||
|
float prob_changeCenter = Probability::binomial_gte1(triggerCount, 1.0f/48);
|
||||||
|
DeltaTempGenerator temp_center(triggerCount, 1.0f/100, 3000.0f);
|
||||||
|
|
||||||
|
float prob_breakMETL = Probability::binomial_gte1(triggerCount, 1.0f/300);
|
||||||
|
float prob_breakBMTL = Probability::binomial_gte1(triggerCount, 1.0f/160);
|
||||||
|
DeltaTempGenerator temp_metal(triggerCount, 1.0f/280, 3000.0f);
|
||||||
|
/* Probability of breaking from BMTL to BRMT, given that the particle has just broken from METL to BMTL. There is no mathematical reasoning for the numbers used, other than:
|
||||||
|
* - larger triggerCount should make this more likely, so it should depend on triggerCount instead of being a constant probability
|
||||||
|
* - triggerCount==1 should make this a chance of 0 (matching previous behaviour)
|
||||||
|
* - triggerCount==2 should make this a chance of 1/160 (matching previous behaviour)
|
||||||
|
*/
|
||||||
|
// TODO: work out in a more mathematical way what this should be?
|
||||||
|
float prob_breakMETLMore = Probability::binomial_gte1(triggerCount/2, 1.0f/160);
|
||||||
|
|
||||||
|
float prob_randWIFI = Probability::binomial_gte1(triggerCount, 1.0f/8);
|
||||||
|
float prob_breakWIFI = Probability::binomial_gte1(triggerCount, 1.0f/16);
|
||||||
|
|
||||||
|
float prob_breakSWCH = Probability::binomial_gte1(triggerCount, 1.0f/100);
|
||||||
|
DeltaTempGenerator temp_SWCH(triggerCount, 1.0f/100, 2000.0f);
|
||||||
|
|
||||||
|
float prob_breakARAY = Probability::binomial_gte1(triggerCount, 1.0f/60);
|
||||||
|
|
||||||
|
float prob_randDLAY = Probability::binomial_gte1(triggerCount, 1.0f/70);
|
||||||
|
|
||||||
|
for (int r = 0; r <=sim->parts_lastActiveIndex; r++)
|
||||||
{
|
{
|
||||||
t=parts[r].type;
|
int t = parts[r].type;
|
||||||
rx=parts[r].x;
|
int rx = parts[r].x;
|
||||||
ry=parts[r].y;
|
int ry = parts[r].y;
|
||||||
if (t==PT_SPRK || (t==PT_SWCH && parts[r].life!=0 && parts[r].life!=10) || (t==PT_WIRE && parts[r].ctype>0))
|
if (t==PT_SPRK || (t==PT_SWCH && parts[r].life!=0 && parts[r].life!=10) || (t==PT_WIRE && parts[r].ctype>0))
|
||||||
{
|
{
|
||||||
int is_elec=0;
|
bool is_elec = false;
|
||||||
if (parts[r].ctype==PT_PSCN || parts[r].ctype==PT_NSCN || parts[r].ctype==PT_PTCT ||
|
if (parts[r].ctype==PT_PSCN || parts[r].ctype==PT_NSCN || parts[r].ctype==PT_PTCT ||
|
||||||
parts[r].ctype==PT_NTCT || parts[r].ctype==PT_INST || parts[r].ctype==PT_SWCH || t==PT_WIRE || t==PT_SWCH)
|
parts[r].ctype==PT_NTCT || parts[r].ctype==PT_INST || parts[r].ctype==PT_SWCH || t==PT_WIRE || t==PT_SWCH)
|
||||||
{
|
{
|
||||||
is_elec=1;
|
is_elec = true;
|
||||||
if (!(rand()%100))
|
temp_center.apply(sim, parts[r]);
|
||||||
parts[r].temp = restrict_flt(parts[r].temp+3000.0f, MIN_TEMP, MAX_TEMP);
|
if (Probability::randFloat() < prob_changeCenter)
|
||||||
if (!(rand()%80))
|
{
|
||||||
sim->part_change_type(r, rx, ry, PT_BREC);
|
if (rand()%5 < 2)
|
||||||
else if (!(rand()%120))
|
sim->part_change_type(r, rx, ry, PT_BREC);
|
||||||
sim->part_change_type(r, rx, ry, PT_NTCT);
|
else if (!(rand()%120))
|
||||||
|
sim->part_change_type(r, rx, ry, PT_NTCT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (nx=-2; nx<3; nx++)
|
for (int nx =-2; nx <= 3; nx++)
|
||||||
for (ny=-2; ny<3; ny++)
|
for (int ny =-2; ny <= 2; ny++)
|
||||||
if (rx+nx>=0 && ry+ny>=0 && rx+nx<XRES && ry+ny<YRES && (rx || ry))
|
if (rx+nx>=0 && ry+ny>=0 && rx+nx<XRES && ry+ny<YRES && (rx || ry))
|
||||||
{
|
{
|
||||||
n = pmap[ry+ny][rx+nx];
|
int n = sim->pmap[ry+ny][rx+nx];
|
||||||
if (!n)
|
if (!n)
|
||||||
continue;
|
continue;
|
||||||
ntype = n&0xFF;
|
int ntype = n&0xFF;
|
||||||
|
n = n >> 8;
|
||||||
//Some elements should only be affected by wire/swch, or by a spark on inst/semiconductor
|
//Some elements should only be affected by wire/swch, or by a spark on inst/semiconductor
|
||||||
//So not affected by spark on metl, watr etc
|
//So not affected by spark on metl, watr etc
|
||||||
if (is_elec)
|
if (is_elec)
|
||||||
@@ -101,30 +169,35 @@ int Element_EMP::update(UPDATE_FUNC_ARGS)
|
|||||||
switch (ntype)
|
switch (ntype)
|
||||||
{
|
{
|
||||||
case PT_METL:
|
case PT_METL:
|
||||||
if (!(rand()%280))
|
temp_metal.apply(sim, parts[n]);
|
||||||
parts[n>>8].temp = restrict_flt(parts[n>>8].temp+3000.0f, MIN_TEMP, MAX_TEMP);
|
if (Probability::randFloat() < prob_breakMETL)
|
||||||
if (!(rand()%300))
|
{
|
||||||
sim->part_change_type(n>>8, rx+nx, ry+ny, PT_BMTL);
|
sim->part_change_type(n, rx+nx, ry+ny, PT_BMTL);
|
||||||
continue;
|
if (Probability::randFloat() < prob_breakMETLMore)
|
||||||
|
{
|
||||||
|
sim->part_change_type(n, rx+nx, ry+ny, PT_BRMT);
|
||||||
|
parts[n].temp = restrict_flt(parts[n].temp+1000.0f, MIN_TEMP, MAX_TEMP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case PT_BMTL:
|
case PT_BMTL:
|
||||||
if (!(rand()%280))
|
temp_metal.apply(sim, parts[n]);
|
||||||
parts[n>>8].temp = restrict_flt(parts[n>>8].temp+3000.0f, MIN_TEMP, MAX_TEMP);
|
if (Probability::randFloat() < prob_breakBMTL)
|
||||||
if (!(rand()%160))
|
|
||||||
{
|
{
|
||||||
sim->part_change_type(n>>8, rx+nx, ry+ny, PT_BRMT);
|
sim->part_change_type(n, rx+nx, ry+ny, PT_BRMT);
|
||||||
parts[n>>8].temp = restrict_flt(parts[n>>8].temp+1000.0f, MIN_TEMP, MAX_TEMP);
|
parts[n].temp = restrict_flt(parts[n].temp+1000.0f, MIN_TEMP, MAX_TEMP);
|
||||||
}
|
}
|
||||||
continue;
|
break;
|
||||||
case PT_WIFI:
|
case PT_WIFI:
|
||||||
if (!(rand()%8))
|
if (Probability::randFloat() < prob_randWIFI)
|
||||||
{
|
{
|
||||||
//Randomise channel
|
// Randomize channel
|
||||||
parts[n>>8].temp = rand()%MAX_TEMP;
|
parts[n].temp = rand()%MAX_TEMP;
|
||||||
}
|
}
|
||||||
if (!(rand()%16))
|
if (Probability::randFloat() < prob_breakWIFI)
|
||||||
{
|
{
|
||||||
sim->create_part(n>>8, rx+nx, ry+ny, PT_BREC);
|
sim->create_part(n, rx+nx, ry+ny, PT_BREC);
|
||||||
parts[n>>8].temp = restrict_flt(parts[n>>8].temp+1000.0f, MIN_TEMP, MAX_TEMP);
|
parts[n].temp = restrict_flt(parts[n].temp+1000.0f, MIN_TEMP, MAX_TEMP);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
@@ -134,23 +207,22 @@ int Element_EMP::update(UPDATE_FUNC_ARGS)
|
|||||||
switch (ntype)
|
switch (ntype)
|
||||||
{
|
{
|
||||||
case PT_SWCH:
|
case PT_SWCH:
|
||||||
if (!(rand()%100))
|
if (Probability::randFloat() < prob_breakSWCH)
|
||||||
sim->part_change_type(n>>8, rx+nx, ry+ny, PT_BREC);
|
sim->part_change_type(n, rx+nx, ry+ny, PT_BREC);
|
||||||
if (!(rand()%100))
|
temp_SWCH.apply(sim, parts[n]);
|
||||||
parts[n>>8].temp = restrict_flt(parts[n>>8].temp+2000.0f, MIN_TEMP, MAX_TEMP);
|
|
||||||
break;
|
break;
|
||||||
case PT_ARAY:
|
case PT_ARAY:
|
||||||
if (!(rand()%60))
|
if (Probability::randFloat() < prob_breakARAY)
|
||||||
{
|
{
|
||||||
sim->create_part(n>>8, rx+nx, ry+ny, PT_BREC);
|
sim->create_part(n, rx+nx, ry+ny, PT_BREC);
|
||||||
parts[n>>8].temp = restrict_flt(parts[n>>8].temp+1000.0f, MIN_TEMP, MAX_TEMP);
|
parts[n].temp = restrict_flt(parts[n].temp+1000.0f, MIN_TEMP, MAX_TEMP);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PT_DLAY:
|
case PT_DLAY:
|
||||||
if (!(rand()%70))
|
if (Probability::randFloat() < prob_randDLAY)
|
||||||
{
|
{
|
||||||
//Randomise delay
|
// Randomize delay
|
||||||
parts[n>>8].temp = (rand()%256) + 273.15f;
|
parts[n].temp = (rand()%256) + 273.15f;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Reference in New Issue
Block a user