Skip to content

Commit

Permalink
v1.14 changes
Browse files Browse the repository at this point in the history
krawthekrow committed Oct 30, 2022
1 parent be89d87 commit b56cda5
Showing 16 changed files with 305 additions and 106 deletions.
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -9,18 +9,16 @@ Features
========

New features:

- Particle order reloading (shortcut: Shift-F5).
- Subframe animation (shortcut: Shift-Space). Runs the simulation particle-by-particle rather than frame-by-frame.
- Subframe recording (Lua: `tpt.record_subframe(true)`). Starts a recording of particle-by-particle simulation and automatically stops recording at the end of the frame. You can stop the recording with `tpt.record_subframe(false)` without stopping particle-by-particle simulation.
- (v1.1) Stack tool (shortcut: Shift-S). Dragging on a stack of particles unstacks them; selecting multiple particles in different positions stacks them in order of their positions.
- (v1.1) Stack mode (shortcut: Shift-D to toggle). Allows you to draw over existing particles, and makes right-click delete one stacked particle at a time. This helps to make transparent DTEC.
- (v1.7) Config tool (shortcut: C). Sets particle properties in a few clicks. DRAY: Sets tmp, then tmp2. CRAY: Sets tmp2, then tmp. LDTC: Sets life, then tmp. DTEC/TSNS/LSNS: Sets tmp2. FILT: Sets tmp. CONV: Sets tmp (click on another particle with the type you want to set the tmp to).
- (v1.7) Config tool (shortcut: C). Sets particle properties in a few clicks. DRAY: Sets tmp, then tmp2. CRAY: Sets tmp2, then tmp. LDTC: Sets life, then tmp. DTEC/TSNS/LSNS/VSNS: Sets tmp2. FILT: Sets tmp. CONV: Sets tmp (click on another particle with the type you want to set the tmp to).
- (v1.8) Timelapse recording (Lua: `tpt.setrecordinterval(<frames>)`). Changes the interval that frames are captured when recording. Useful when making timelapses.
- (v1.10) Stack edit (shortcut: X, Shift-X, PageUp, PageDown, Home, End). Config tool, property tool, ctype-draw and subframe debugging (Shift-F) target particles at the selected depth. When stack mode is enabled (Shift-D), particles are created and deleted at the selected depth. Note that using the brush with stack edit messes with particle order, so this is best combined with automatic particle order reloading (`tpt.autoreload_enable(1)`).

New features enabled by the Lua command `tpt.autoreload_enable(1)`:

- Automatic particle order reloading: If you use the brush or do a copy-paste and then advance the simulation, the frame is completed and particle order is reloaded automatically.
- Backups: Overwriting a local save "<save>.cps" creates a backup of the file you're overwriting at "<save>.cps.backup". Subframe development is dangerous.

@@ -40,6 +38,7 @@ HUD changes:
- (v1.11) The subframe debugging position is shown in the HUD.
- (v1.11) CRAY FILT mode is shown in the debug HUD.
- (v1.12) CONV's tmp is presented as an element name, to the left of its ctype.
- (v1.14) WALL type is always shown in the top right HUD.

Other quality-of-life changes:
- Alt-F continues updating particles until it encouters an "interesting" update (create\_part, delete\_part or part\_change\_type called), and does not display any log messages until the frame is completed.
@@ -55,9 +54,17 @@ Other quality-of-life changes:
- (v1.12) When pasting or placing stamps, you may use the WASD keys to adjust its position instead of the arrow keys.
- (v1.12) BRAY is visible even when its life is low.
- (v1.13) Paste and stamp previews respect changes to render options, including whether decorations are enabled.
- (v1.14) The ruler tool (enable with `tpt.setdebug(0x4)`, or `tpt.setdebug(0xC)` to use with subframe debug mode) shows dimensions not just for lines, but also for boxes.

Note that the original game already supports the following subframe debugging features (enable with the Lua command `tpt.setdebug(0x8)`):
New Lua interfaces:
- `tpt.autoreload_enable(enable: int)`: Enables autoreload if `enable = 1`, disables autoreload otherwise. Default: `enable = 1`.
- `tpt.record_subframe(start: bool)`: Start or stop subframe recording.
- `tpt.setrecordinterval(num_frames: int)`: Changes the recording interval to once every `num_frames` frames.
- `sim.reloadParticleOrder()`: Reloads particle order.
- (v1.13) `tpt.set_bray_life_brightness_threshold(thres: int)`: Make BRAY visible even when its life is low. `thres` is added to BRAY's alpha value when it is in the non-solid (i.e. `life != 2`) state.
- (v1.14) `event.prehuddraw`: Event that gets fired just before the HUD is rendered. This allows Lua scripts to draw interfaces below the HUD.

Note that the original game already supports the following subframe debugging features (enable with the Lua command `tpt.setdebug(0x8)`):
- Shift-F updates all particles up to the particle where your mouse is at.
- Alt-F updates a single particle. This behaviour has been modified in this mod to continue updating particles until an "interesting" update occurs.

@@ -170,5 +177,13 @@ v1.13:
- Make stamp previews aware of render settings.

v1.14:
- Fix menu glitch when toggling config tool from deco menu.
- Allow stack tool to unstack to box.
- Extend config tool to VSNS tmp2.
- Extend ruler tool to show box dimensions.
- Put HUD particle info below the zoom window.
- Always show wall type in HUD.
- Show particle IDs in HUD when zoomed.
- Add Lua event that triggers before the HUD is drawn.
- Make BRAY life brightness offset also affect tmp=1 BRAY.
- Fix menu glitch when toggling config tool from deco menu.
- Fix vanilla file brower search query change bug.
16 changes: 11 additions & 5 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
v1.13:
- Fix automatic particle order reloading initialization bug.
- Prevent Alt-F from skipping uninteresting updates.
- Add Lua hook to set BRAY life brightness threshold.
- Make stamp previews aware of render settings.
v1.14:
- Allow stack tool to unstack to box.
- Extend config tool to VSNS tmp2.
- Extend ruler tool to show box dimensions.
- Put HUD particle info below the zoom window.
- Always show wall type in HUD.
- Show particle IDs in HUD when zoomed.
- Add Lua event that triggers before the HUD is drawn.
- Make BRAY life brightness offset also affect tmp=1 BRAY.
- Fix menu glitch when toggling config tool from deco menu.
- Fix vanilla file brower search query change bug.
2 changes: 1 addition & 1 deletion src/debug/DebugLines.cpp
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ void DebugLines::Draw()
{
Graphics * g = view->GetGraphics();

if (view->GetDrawingLine())
if (view->GetDrawingLine() || view->GetDrawingRect())
{
ui::Point drawPoint1 = controller->PointTranslate(view->GetLineStartCoords()), drawPoint2 = controller->PointTranslate(view->GetLineFinishCoords());
if (view->GetDrawSnap())
14 changes: 13 additions & 1 deletion src/gui/filebrowser/FileBrowserActivity.cpp
Original file line number Diff line number Diff line change
@@ -84,6 +84,7 @@ FileBrowserActivity::FileBrowserActivity(ByteString directory, OnSelected onSele
WindowActivity(ui::Point(-1, -1), ui::Point(500, 350)),
onSelected(onSelected_),
directory(directory),
hasQueuedSearch(false),
totalFiles(0)
{

@@ -128,7 +129,12 @@ FileBrowserActivity::FileBrowserActivity(ByteString directory, OnSelected onSele

void FileBrowserActivity::DoSearch(ByteString search)
{
if(!loadFiles)
if (loadFiles)
{
hasQueuedSearch = true;
queuedSearch = search;
}
else
{
loadDirectory(directory, search);
}
@@ -222,6 +228,12 @@ void FileBrowserActivity::NotifyDone(Task * task)
delete components[i];
}
components.clear();

if (hasQueuedSearch)
{
hasQueuedSearch = false;
loadDirectory(directory, queuedSearch);
}
}

void FileBrowserActivity::OnMouseDown(int x, int y, unsigned button)
2 changes: 2 additions & 0 deletions src/gui/filebrowser/FileBrowserActivity.h
Original file line number Diff line number Diff line change
@@ -30,6 +30,8 @@ class FileBrowserActivity: public TaskListener, public WindowActivity
std::vector<ui::Component*> components;
std::vector<ui::Component*> componentsQueue;
ByteString directory;
bool hasQueuedSearch;
ByteString queuedSearch;

ui::ProgressBar * progressBar;

31 changes: 26 additions & 5 deletions src/gui/game/ConfigTool.cpp
Original file line number Diff line number Diff line change
@@ -167,7 +167,8 @@ void ConfigTool::Update(Simulation *sim)
bool allowDiag = !(
configState == ConfigState::dtecTmp2 ||
configState == ConfigState::tsnsTmp2 ||
configState == ConfigState::lsnsTmp2
configState == ConfigState::lsnsTmp2 ||
configState == ConfigState::vsnsTmp2
);
ui::Point proj(0, 0);
if (configState != ConfigState::ready)
@@ -215,6 +216,7 @@ void ConfigTool::Update(Simulation *sim)
case ConfigState::dtecTmp2:
case ConfigState::tsnsTmp2:
case ConfigState::lsnsTmp2:
case ConfigState::vsnsTmp2:
configPart.tmp2 = getDist(proj);
break;
case ConfigState::convTmp:
@@ -262,6 +264,9 @@ void ConfigTool::Click(Simulation *sim, Brush *brush, ui::Point position)
case PT_LSNS:
configState = ConfigState::lsnsTmp2;
break;
case PT_VSNS:
configState = ConfigState::vsnsTmp2;
break;
case PT_CONV:
configState = ConfigState::convTmp;
break;
@@ -305,6 +310,7 @@ void ConfigTool::Click(Simulation *sim, Brush *brush, ui::Point position)
case ConfigState::dtecTmp2:
case ConfigState::tsnsTmp2:
case ConfigState::lsnsTmp2:
case ConfigState::vsnsTmp2:
pConfigPart->tmp2 = configPart.tmp2;
Reset(sim);
break;
@@ -348,9 +354,21 @@ int ConfigTool::GetId()

bool ConfigTool::IsConfigurableType(int type)
{
return type == PT_DRAY || type == PT_CRAY || type == PT_LDTC ||
type == PT_DTEC || type == PT_TSNS || type == PT_LSNS ||
type == PT_CONV || type == PT_FILT;
switch (type)
{
case PT_DRAY:
case PT_CRAY:
case PT_LDTC:
case PT_DTEC:
case PT_TSNS:
case PT_LSNS:
case PT_VSNS:
case PT_CONV:
case PT_FILT:
return true;
default:
return false;
}
}

bool ConfigTool::IsConfiguring()
@@ -382,7 +400,8 @@ bool ConfigTool::IsConfiguringTmp2()
configState == ConfigState::crayTmp2 ||
configState == ConfigState::dtecTmp2 ||
configState == ConfigState::tsnsTmp2 ||
configState == ConfigState::lsnsTmp2;
configState == ConfigState::lsnsTmp2 ||
configState == ConfigState::vsnsTmp2;
}

void ConfigTool::drawRedLine(Renderer *ren, int startx, int starty, int endx, int endy)
@@ -427,6 +446,7 @@ void ConfigTool::DrawHUD(Renderer *ren)
case PT_DTEC:
case PT_TSNS:
case PT_LSNS:
case PT_VSNS:
drawSquareRdBox(ren);
break;
case PT_DRAY:
@@ -485,6 +505,7 @@ void ConfigTool::DrawHUD(Renderer *ren)
case ConfigState::dtecTmp2:
case ConfigState::tsnsTmp2:
case ConfigState::lsnsTmp2:
case ConfigState::vsnsTmp2:
drawSquareRdBox(ren);
break;
case ConfigState::convTmp:
5 changes: 5 additions & 0 deletions src/gui/game/GameController.cpp
Original file line number Diff line number Diff line change
@@ -1883,3 +1883,8 @@ void GameController::RemoveCustomGOLType(const ByteString &identifier)
{
gameModel->RemoveCustomGOLType(identifier);
}

void GameController::TriggerPreHudDraw()
{
commandInterface->OnPreHudDraw();
}
2 changes: 2 additions & 0 deletions src/gui/game/GameController.h
Original file line number Diff line number Diff line change
@@ -212,6 +212,8 @@ class GameController: public ClientListener
bool GetMouseClickRequired();

void RemoveCustomGOLType(const ByteString &identifier);

void TriggerPreHudDraw();
};

#endif // GAMECONTROLLER_H
139 changes: 97 additions & 42 deletions src/gui/game/GameView.cpp
Original file line number Diff line number Diff line change
@@ -2042,12 +2042,13 @@ void GameView::SetSaveButtonTooltips()
saveSimulationButton->SetToolTips("Re-upload the current simulation", "Upload a new simulation. Hold Ctrl to save offline.");
}

void GameView::drawHudParticleText(Graphics *g, StringBuilder sbText, int yoffset, int alpha, int wavelengthGfx, HudParticleTextGlowType glowType)
void GameView::drawHudParticleText(Graphics *g, StringBuilder sbText, int *yoffset, bool alignLeft, int alpha, int wavelengthGfx, int wavelengthGfxOff, HudParticleTextGlowType glowType)
{
String text = sbText.Build();
int textWidth = Graphics::textwidth(text);
int rectr = 0, rectg = 0, rectb = 0;
float alphamod = 1.f;

switch (glowType)
{
case HudParticleTextGlowType::YELLOW:
@@ -2065,13 +2066,27 @@ void GameView::drawHudParticleText(Graphics *g, StringBuilder sbText, int yoffse
default:
break;
}
g->fillrect(XRES-20-textWidth, 12 + yoffset, textWidth+8, 13, rectr, rectg, rectb, int(alpha*alphamod*0.5f));
g->drawtext(XRES-16-textWidth, 15 + yoffset, text, 255, 255, 255, int(alpha*alphamod*0.75f));

int xmargin = 12;
int xpad = 4;
g->fillrect(
alignLeft ? xmargin : (XRES - xmargin - textWidth - xpad * 2),
0 + *yoffset, textWidth + xpad * 2, 13,
rectr, rectg, rectb, int(alpha*alphamod*0.5f)
);
g->drawtext(
alignLeft ? (xmargin + xpad) : (XRES - xmargin - textWidth - xpad),
3 + *yoffset, text, 255, 255, 255, int(alpha*alphamod*0.75f));

#ifndef OGLI
if (wavelengthGfx)
{
int i, cr, cg, cb, j, h = 3, x = XRES-19-textWidth, y = 11+yoffset;
int i, cr, cg, cb, j, h = 3;
int xoff = -3 + wavelengthGfxOff;
int x = alignLeft ?
(xpad + xmargin + xoff) :
(XRES - xmargin - xpad - textWidth + xoff);
int y = -1+*yoffset;
int tmp;
g->fillrect(x, y, 30, h, 64, 64, 64, alpha); // coords -1 size +1 to work around bug in fillrect - TODO: fix fillrect
for (i = 0; i < 30; i++)
@@ -2104,6 +2119,8 @@ void GameView::drawHudParticleText(Graphics *g, StringBuilder sbText, int yoffse
}
}
#endif

*yoffset = *yoffset + 13;
}

void GameView::writeWavelength(StringBuilder *str, int wavelengthGfx)
@@ -2301,6 +2318,8 @@ void GameView::OnDraw()
}
}

c->TriggerPreHudDraw();

if (recording)
{
String sampleInfo = String::Build("#", screenshotIndex, " ", String(0xE00E), " REC");
@@ -2317,7 +2336,16 @@ void GameView::OnDraw()
alpha = 255-toolTipPresence*3;
if (alpha < 50)
alpha = 50;
int yoffset = 0;
int zoomWindowBottom =
ren->zoomWindowPosition.Y + ren->zoomScopeSize * ren->ZFACTOR;
int zoomWindowLeft = ren->zoomWindowPosition.X;
int zoomWindowRight =
ren->zoomWindowPosition.X + ren->zoomScopeSize * ren->ZFACTOR;
int yoffset = 12;
int yoffsetBelowZoom = zoomWindowBottom + 3;
int *partsYoffsetPtr = zoomEnabled ? &yoffsetBelowZoom : &yoffset;
bool isZoomWindowOnLeft = zoomWindowLeft < XRES - zoomWindowRight;
bool alignLeft = zoomEnabled && isZoomWindowOnLeft;

bool omitBegin = sample.StackIndexBegin != 0;
bool omitEnd = sample.StackIndexEnd != sample.SParticleCount;
@@ -2332,8 +2360,7 @@ void GameView::OnDraw()
if (excessParts != 1)
infoStr << "s";
infoStr << " omitted ...";
drawHudParticleText(g, infoStr, yoffset, alpha);
yoffset += 13;
drawHudParticleText(g, infoStr, partsYoffsetPtr, alignLeft, alpha);
}

for (int i = stackShowEnd - 1; i >= stackShowBegin; i--)
@@ -2342,21 +2369,46 @@ void GameView::OnDraw()
sampleInfo << Format::Precision(2);

int stacki = i - sample.StackIndexBegin;
String configCursColor = String::Build("\x0F\x01\x01\xEE");
String stackCursColor = String::Build("\x0F\xFF\xEE\x01");
String plainColor = String::Build("\x0F\xFF\xFF\xFF");
int sparticleId = sample.SParticleIDs[stacki];
bool isConfigToolTarget =
configTool && configTool->GetId() == sample.SParticleIDs[stacki];
configTool && configTool->GetId() == sparticleId;
Particle sparticle = isConfigToolTarget ?
configTool->GetPart() : sample.SParticles[stacki];
bool isStackEditTarget =
c->GetStackEditDepth() >= 0 && i == sample.EffectiveStackEditDepth;
int wavelengthGfx = 0;
int wavelengthGfxOff = 0;
int type = sparticle.type;
int ctype = sparticle.ctype;

HudParticleTextGlowType glowType = HudParticleTextGlowType::NONE;
if (isConfigToolTarget)
{
glowType = HudParticleTextGlowType::BLUE;
}

if (alignLeft)
{
if (isStackEditTarget)
{
sampleInfo << stackCursColor << ">" << plainColor << " ";
}
if (isConfigToolTarget)
{
sampleInfo << configCursColor << ">" << plainColor << " ";
}
wavelengthGfxOff += Graphics::textwidth(sampleInfo.Build());
}

if (type == PT_PHOT || type == PT_BIZR || type == PT_BIZRG || type == PT_BIZRS || type == PT_FILT || type == PT_BRAY || type == PT_C5)
wavelengthGfx = (ctype&0x3FFFFFFF);

if (showDebug || configTool)
{
String highlightColor = String::Build("\x0F\xFF\x77\x77"),
plainColor = String::Build("\x0F\xFF\xFF\xFF"),
noneString = String::Build("");

bool isConfiguring = isConfigToolTarget &&
@@ -2481,6 +2533,11 @@ void GameView::OnDraw()
"Tmp2: " << sparticle.tmp2 <<
(isConfiguringTmp2 ? highlightColor : noneString);
}

if (zoomEnabled)
{
sampleInfo << ", #" << sparticleId;
}
}
else
{
@@ -2489,18 +2546,19 @@ void GameView::OnDraw()
sampleInfo << ", Pressure: " << sample.AirPressure;
}

HudParticleTextGlowType glowType = HudParticleTextGlowType::NONE;
if (isConfigToolTarget)
{
sampleInfo << " \x0F\x01\x01\xEE<";
glowType = HudParticleTextGlowType::BLUE;
}
if (c->GetStackEditDepth() >= 0 && i == sample.EffectiveStackEditDepth)
if (!alignLeft)
{
sampleInfo << " \x0F\xFF\xEE\x01<";
if (isConfigToolTarget)
{
sampleInfo << " " << configCursColor << "<";
}
if (isStackEditTarget)
{
sampleInfo << " " << stackCursColor << "<";
}
}
drawHudParticleText(g, sampleInfo, yoffset, alpha, wavelengthGfx, glowType);
yoffset += 13;

drawHudParticleText(g, sampleInfo, partsYoffsetPtr, alignLeft, alpha, wavelengthGfx, wavelengthGfxOff, glowType);
}

if (showDebug && omitBegin)
@@ -2511,11 +2569,9 @@ void GameView::OnDraw()
if (excessParts != 1)
infoStr << "s";
infoStr << " omitted ...";
drawHudParticleText(g, infoStr, yoffset, alpha);
yoffset += 13;
drawHudParticleText(g, infoStr, partsYoffsetPtr, alignLeft, alpha);
}

if (!sample.SParticleCount)
{
StringBuilder sampleInfo;
sampleInfo << Format::Precision(2);
@@ -2524,35 +2580,34 @@ void GameView::OnDraw()
{
sampleInfo << c->WallName(sample.WallType);
}
else if (sample.particle.type)
{
int type = sample.particle.type;
int ctype = sample.particle.ctype;
sampleInfo << c->ElementResolve(type, ctype);
}
else
{
sampleInfo << "Empty";
}

drawHudParticleText(g, sampleInfo, yoffset, alpha);
yoffset += 13;
}


if (showDebug)
{
StringBuilder sampleInfo;
sampleInfo << Format::Precision(2);

if (sample.particle.type)
sampleInfo << "#" << sample.ParticleID << ", ";
if (showDebug)
{
if (!zoomEnabled && sample.particle.type)
sampleInfo << ", #" << sample.ParticleID;

sampleInfo << "(" << sample.PositionX << " " << sample.PositionY << ")";
sampleInfo << ", (" << sample.PositionX << " " << sample.PositionY << ")";

if (sample.Gravity)
sampleInfo << ", GX: " << sample.GravityVelocityX << " GY: " << sample.GravityVelocityY;
if (sample.Gravity)
sampleInfo << ", GX: " << sample.GravityVelocityX << " GY: " << sample.GravityVelocityY;

if (c->GetAHeatEnable())
sampleInfo << ", AHeat: " << sample.AirTemperature - 273.15f << " C";
if (sample.isMouseInSim)
sampleInfo << ", " << sample.AirPressure << " Pa";
if (c->GetAHeatEnable())
sampleInfo << ", AHeat: " << sample.AirTemperature - 273.15f << " C";
if (sample.isMouseInSim)
sampleInfo << ", " << sample.AirPressure << " Pa";
}

drawHudParticleText(g, sampleInfo, yoffset, alpha);
drawHudParticleText(g, sampleInfo, &yoffset, false, alpha);
}
}

3 changes: 2 additions & 1 deletion src/gui/game/GameView.h
Original file line number Diff line number Diff line change
@@ -131,7 +131,7 @@ class GameView: public ui::Window

void screenshot();

void drawHudParticleText(Graphics *g, StringBuilder text, int yoffset, int alpha, int wavelengthGfx = 0, HudParticleTextGlowType glowType = HudParticleTextGlowType::NONE);
void drawHudParticleText(Graphics *g, StringBuilder text, int *yoffset, bool alignLeft, int alpha, int wavelengthGfx = 0, int wavelengthGfxOff = 0, HudParticleTextGlowType glowType = HudParticleTextGlowType::NONE);

void enableShiftBehaviour();
void disableShiftBehaviour();
@@ -174,6 +174,7 @@ class GameView: public ui::Window
//all of these are only here for one debug lines
bool GetMouseDown() { return isMouseDown; }
bool GetDrawingLine() { return drawMode == DrawLine && isMouseDown; }
bool GetDrawingRect() { return drawMode == DrawRect && isMouseDown; }
bool GetDrawSnap() { return drawSnap; }
ui::Point GetLineStartCoords() { return drawPoint1; }
ui::Point GetLineFinishCoords() { return currentMouse; }
144 changes: 100 additions & 44 deletions src/gui/game/StackTool.cpp
Original file line number Diff line number Diff line change
@@ -25,8 +25,8 @@ static bool compareParts(Particle a, Particle b)
void StackTool::ProcessParts(Simulation *sim, std::vector<int> &parts, ui::Point position, ui::Point position2)
{
if (parts.empty()) return;
int partx = sim->parts[parts[0]].x;
int party = sim->parts[parts[0]].y;
int partx = (int)(sim->parts[parts[0]].x + 0.5f);
int party = (int)(sim->parts[parts[0]].y + 0.5f);
bool samePos = true;
ui::Point stackPos(partx, party);
for (size_t i = 1; i < parts.size(); i++)
@@ -43,53 +43,109 @@ void StackTool::ProcessParts(Simulation *sim, std::vector<int> &parts, ui::Point
}
if (samePos)
{
ui::Point unstackDir(0, 1);
if (position2.X == position.X) {
if (position2.Y < position.Y)
unstackDir = ui::Point(0, -1);
if (position2.Y > position.Y)
unstackDir = ui::Point(0, 1);
}
if (position2.Y == position.Y) {
if (position2.X < position.X)
unstackDir = ui::Point(-1, 0);
if (position2.X > position.X)
unstackDir = ui::Point(1, 0);
ui::Point dp = position2 - position;
if (
dp.X != 0 && dp.Y != 0 &&
position.X == partx && position.Y == party
)
{
// unstack to rectangle
int minX = (dp.X >= 0) ? position.X : position2.X;
int maxX = (dp.X >= 0) ? position2.X : position.X;
int minY = (dp.Y >= 0) ? position.Y : position2.Y;
int currX = minX, currY = minY;
bool blocked = false;
sim->pmap[party][partx] = 0;
sim->photons[party][partx] = 0;
for (size_t i = 0; i < parts.size(); i++){
int partID = parts[i];
Particle *part = &sim->parts[partID];
part->x += currX - partx;
part->y += currY - party;

int t = part->type;
if (sim->elements[t].Properties & TYPE_ENERGY)
sim->photons[currY][currX] = PMAP(partID, t);
else
sim->pmap[currY][currX] = PMAP(partID, t);

if (!blocked)
{
int nx = currX + 1;
int ny = currY;
if (nx > maxX)
{
nx = minX;
ny++;
}

if (nx < 0 || nx >= XRES || ny < 0 || ny >= YRES ||
sim->pmap[ny][nx] || sim->photons[ny][nx])
{
gameModel->Log("Warning: Not enough space to unstack fully.", false);
blocked = true;
}
else
{
currX = nx;
currY = ny;
}
}
}
}
unsigned int unstackLimit = parts.size();
for (size_t i = 1; i < parts.size(); i++){
int nx = partx + i * unstackDir.X, ny = party + i * unstackDir.Y;
if (nx < 0 || nx >= XRES || ny < 0 || ny >= YRES ||
sim->pmap[ny][nx] || sim->photons[ny][nx])
else
{
// unstack to line
ui::Point unstackDir(0, 1);
if (dp.X == 0)
{
if (dp.Y < 0)
unstackDir = ui::Point(0, -1);
if (dp.Y > 0)
unstackDir = ui::Point(0, 1);
}
if (dp.Y == 0)
{
unstackLimit = i;
if (!sim->stackToolNotifShown || !(
sim->stackToolNotifShownX == position.X &&
sim->stackToolNotifShownY == position.Y
))
if (dp.X < 0)
unstackDir = ui::Point(-1, 0);
if (dp.X > 0)
unstackDir = ui::Point(1, 0);
}
unsigned int unstackLimit = parts.size();
for (size_t i = 1; i < parts.size(); i++){
int nx = partx + i * unstackDir.X, ny = party + i * unstackDir.Y;
if (nx < 0 || nx >= XRES || ny < 0 || ny >= YRES ||
sim->pmap[ny][nx] || sim->photons[ny][nx])
{
gameModel->Log("Warning: Not enough space to unstack fully.", false);
sim->stackToolNotifShown = true;
sim->stackToolNotifShownX = position.X;
sim->stackToolNotifShownY = position.Y;
unstackLimit = i;
if (!sim->stackToolNotifShown || !(
sim->stackToolNotifShownX == position.X &&
sim->stackToolNotifShownY == position.Y
))
{
gameModel->Log("Warning: Not enough space to unstack fully.", false);
sim->stackToolNotifShown = true;
sim->stackToolNotifShownX = position.X;
sim->stackToolNotifShownY = position.Y;
}
break;
}
break;
}
}
bool reverseOrder = unstackDir.X < 0 || unstackDir.Y < 0;
for (size_t i = 0; i < unstackLimit; i++){
int partidx = reverseOrder ?
(unstackLimit - i - 1) : (parts.size() - unstackLimit + i);
int partID = parts[partidx];
Particle *part = &sim->parts[partID];
part->x += (int)i * unstackDir.X;
part->y += (int)i * unstackDir.Y;
int nx = (int)(part->x + 0.5f), ny = (int)(part->y + 0.5f);
int t = part->type;
if (sim->elements[t].Properties & TYPE_ENERGY)
sim->photons[ny][nx] = PMAP(partID, t);
else
sim->pmap[ny][nx] = PMAP(partID, t);
bool reverseOrder = unstackDir.X < 0 || unstackDir.Y < 0;
for (size_t i = 0; i < unstackLimit; i++){
int partidx = reverseOrder ?
(unstackLimit - i - 1) : (parts.size() - unstackLimit + i);
int partID = parts[partidx];
Particle *part = &sim->parts[partID];
part->x += (int)i * unstackDir.X;
part->y += (int)i * unstackDir.Y;
int nx = (int)(part->x + 0.5f), ny = (int)(part->y + 0.5f);
int t = part->type;
if (sim->elements[t].Properties & TYPE_ENERGY)
sim->photons[ny][nx] = PMAP(partID, t);
else
sim->pmap[ny][nx] = PMAP(partID, t);
}
}
}
else
3 changes: 2 additions & 1 deletion src/gui/game/Tool.h
Original file line number Diff line number Diff line change
@@ -132,9 +132,10 @@ class ConfigTool: public Tool
dtecTmp2,
tsnsTmp2,
lsnsTmp2,
vsnsTmp2,
convTmp,
ldtcTmp,
ldtcLife
ldtcLife,
};
GameModel * gameModel;
int configPartId;
1 change: 1 addition & 0 deletions src/lua/CommandInterface.h
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ class CommandInterface
//void AttachGameModel(GameModel * m);

virtual void OnTick() { }
virtual void OnPreHudDraw() { }

virtual bool HandleEvent(LuaEvents::EventTypes eventType, Event * event) { return true; }

7 changes: 7 additions & 0 deletions src/lua/LuaEvents.h
Original file line number Diff line number Diff line change
@@ -110,6 +110,12 @@ class TickEvent: public Event
int PushToStack(lua_State *l) override { return 0; }
};

class PreHudDrawEvent: public Event
{
public:
int PushToStack(lua_State *l) override { return 0; }
};

class BlurEvent: public Event
{
public:
@@ -135,6 +141,7 @@ class LuaEvents
mousemove,
mousewheel,
tick,
prehuddraw,
blur,
close
};
15 changes: 14 additions & 1 deletion src/lua/LuaScriptInterface.cpp
Original file line number Diff line number Diff line change
@@ -3863,6 +3863,7 @@ void LuaScriptInterface::initEventAPI()
lua_pushinteger(l, LuaEvents::mousemove); lua_setfield(l, -2, "mousemove");
lua_pushinteger(l, LuaEvents::mousewheel); lua_setfield(l, -2, "mousewheel");
lua_pushinteger(l, LuaEvents::tick); lua_setfield(l, -2, "tick");
lua_pushinteger(l, LuaEvents::prehuddraw); lua_setfield(l, -2, "prehuddraw");
lua_pushinteger(l, LuaEvents::blur); lua_setfield(l, -2, "blur");
lua_pushinteger(l, LuaEvents::close); lua_setfield(l, -2, "close");
}
@@ -4103,7 +4104,7 @@ bool LuaScriptInterface::HandleEvent(LuaEvents::EventTypes eventType, Event * ev
return LuaEvents::HandleEvent(this, event, ByteString::Build("tptevents-", eventType));
}

void LuaScriptInterface::OnTick()
void LuaScriptInterface::initNumPartsVar()
{
lua_getglobal(l, "simulation");
if (lua_istable(l, -1))
@@ -4112,10 +4113,22 @@ void LuaScriptInterface::OnTick()
lua_setfield(l, -2, "NUM_PARTS");
}
lua_pop(l, 1);
}

void LuaScriptInterface::OnTick()
{
initNumPartsVar();
TickEvent ev;
HandleEvent(LuaEvents::tick, &ev);
}

void LuaScriptInterface::OnPreHudDraw()
{
initNumPartsVar();
PreHudDrawEvent ev;
HandleEvent(LuaEvents::prehuddraw, &ev);
}

int LuaScriptInterface::Command(String command)
{
if (command[0] == '!')
2 changes: 2 additions & 0 deletions src/lua/LuaScriptInterface.h
Original file line number Diff line number Diff line change
@@ -198,6 +198,7 @@ class LuaScriptInterface: public CommandInterface
std::vector<LuaSmartRef> lua_el_func_v, lua_gr_func_v, lua_cd_func_v;
std::vector<int> lua_el_mode_v;

void initNumPartsVar();
public:
int tpt_index(lua_State *l);
int tpt_newIndex(lua_State *l);
@@ -214,6 +215,7 @@ class LuaScriptInterface: public CommandInterface
void custom_init_can_move();

void OnTick() override;
void OnPreHudDraw() override;
bool HandleEvent(LuaEvents::EventTypes eventType, Event * event) override;

void Init();

0 comments on commit b56cda5

Please sign in to comment.