#include "std.zh"
//Global settings
const int SNAP_SENSITIVITY = 2; //Distance within which panning viewport snaps to destination is multiplied by this value (values < 2 may be buggy)
//enums
enum
{
MV_Vx, MV_Vy, MV_Ax, MV_Ay, MV_INTERNAL_X, MV_INTERNAL_Y, MV_Delay, OG_X, OG_Y, DEST_X, DEST_Y, DELAY_TIMER,
ENUM_MAX
};
//FFC Script
@InitD0("Viewport Mode"),
@InitDHelp0("0 = absolute X/Y, 1 = offset X/Y, 2 = absolute X/Y (pan), 3 = offset X/Y (pan)"),
@InitD1("Move When Triggered"),
@InitDHelp1("If in offset mode, 1 = will not apply this FFC's Vx/Vy/Ax/Ay/A. Delay until the script is triggered"),
@InitD2("X"),
@InitD3("Y"),
@InitD4("Counter ID"),
@InitDHelp4("Counter with this ID will toggle controlled viewport when >= 1 (on) or = 0 (off)"),
@InitD5("Pan Speed 1"),
@InitDHelp5("How fast in px/frame to pan to the destination"),
@InitD6("Pan Speed 2"),
@InitDHelp6("How fast in px/frame to pan back to the hero"),
@InitD7("Allow Out-of-Bounds"),
@InitDHelp7("0 = viewport will not go out-of-bounds, 1 = no restrictions")
ffc script Viewport_Combo
{
void run(int ViewportMode, bool TrigMove, int ParamX, int ParamY, int TriggerCounter, int PanSpeed, int PanSpeed2, bool OOB)
{
//Error messages for out-of-range parameters
if (ViewportMode < 0 || ViewportMode > 3)
{
printf("Mode is out-of-range (0-3)! Ending Viewport_Combo script!");
this->Script = -1;
}
else
if (TriggerCounter < 0 || TriggerCounter > 106)
{
printf("Counter ID is out-of-range (0-106)! Ending Viewport_Combo script!");
this->Script = -1;
}
bool StoredViewMode = false;
dmapdata DMap = Game->LoadDMapData(Game->CurDMap);
ViewportMode DefaultViewMode;
OOB = !OOB;
//Store and reset FFC movement values
if (TrigMove)
{
this->Misc[MV_Vx] = this->Vx;
this->Misc[MV_Vy] = this->Vy;
this->Misc[MV_Ax] = this->Ax;
this->Misc[MV_Ay] = this->Ay;
this->Misc[MV_Delay] = this->Delay;
this->Misc[DELAY_TIMER] = this->Delay;
this->Vx = 0;
this->Vy = 0;
this->Ax = 0;
this->Ay = 0;
this->Delay = 0;
}
while (true)
{
if (Game->Counter[TriggerCounter])
{
//this->Misc[DELAY_TIMER] for Move Delay
if (this->Misc[DELAY_TIMER])
--this->Misc[DELAY_TIMER];
else
{
if (!StoredViewMode)
{
//Store current view mode
DefaultViewMode = Viewport->Mode;
StoredViewMode = true;
//Restore movement values if moving when triggered
if (TrigMove && (ViewportMode == 1 || ViewportMode == 3))
{
this->Vx = this->Misc[MV_Vx];
this->Vy = this->Misc[MV_Vy];
this->Ax = this->Misc[MV_Ax];
this->Ay = this->Misc[MV_Ay];
}
//Store current viewport position if panning
if (ViewportMode > 1)
{
this->Misc[OG_X] = Viewport->X;
this->Misc[OG_Y] = Viewport->Y;
this->Misc[MV_INTERNAL_X] = Viewport->X;
this->Misc[MV_INTERNAL_Y] = Viewport->Y;
}
//Store destination if absolute
if (!ViewportMode || ViewportMode == 2)
{
this->Misc[DEST_X] = ParamX;
this->Misc[DEST_Y] = ParamY;
}
//Clamp the above to bounds
if (OOB)
{
this->Misc[DEST_X] = Clamp(this->Misc[DEST_X], 0, Region->Width-256);
this->Misc[DEST_Y] = Clamp(this->Misc[DEST_Y], 0, Region->Height-176-(DMap->Flagset[22] ? 56 : 0));
this->Misc[OG_X] = Clamp(this->Misc[OG_X], 0, Region->Width-256);
this->Misc[OG_Y] = Clamp(this->Misc[OG_Y], 0, Region->Height-176-(DMap->Flagset[22] ? 56 : 0));
}
}
Viewport->Mode = VIEW_MODE_SCRIPT;
//If offset, update destination to FFC's current position + offset
if (ViewportMode == 1 || ViewportMode == 3)
{
this->Misc[DEST_X] = OOB ? Clamp(this->X+ParamX, 0, Region->Width-256) : this->X+ParamX;
this->Misc[DEST_Y] = OOB ? Clamp(this->Y+ParamY, 0, Region->Height-176-(DMap->Flagset[22] ? 56 : 0))
: this->Y+ParamY;
}
//Pan to destination
if (ViewportMode > 1 && Distance(this->Misc[MV_INTERNAL_X], this->Misc[MV_INTERNAL_Y],
this->Misc[DEST_X], this->Misc[DEST_Y]) > PanSpeed*SNAP_SENSITIVITY)
PanViewport(this->Misc[DEST_X], this->Misc[DEST_Y], PanSpeed, this);
else
{
//Or instantly snap to the FFC + offset
Viewport->X = OOB ? Clamp(this->Misc[DEST_X], 0, Region->Width-256) : this->Misc[DEST_X];
Viewport->Y = OOB ? Clamp(this->Misc[DEST_Y], 0, Region->Height-176-(DMap->Flagset[22] ? 56 : 0))
: this->Misc[DEST_Y];
}
}
}
else
{
if (ViewportMode > 1 && Viewport->Mode == VIEW_MODE_SCRIPT)
{
//Pan back to original position
if (Distance(this->Misc[MV_INTERNAL_X], this->Misc[MV_INTERNAL_Y], this->Misc[OG_X],
this->Misc[OG_Y]) > PanSpeed2*SNAP_SENSITIVITY)
PanViewport(this->Misc[OG_X], this->Misc[OG_Y], PanSpeed2, this);
else
{
//Restore original viewport mode and reset Move Delay
Viewport->Mode = DefaultViewMode;
StoredViewMode = false;
this->Misc[DELAY_TIMER] = this->Misc[MV_Delay];
}
}
else
{
//^
Viewport->Mode = DefaultViewMode;
StoredViewMode = false;
this->Misc[DELAY_TIMER] = this->Misc[MV_Delay];
}
}
Waitframe();
}
}
}
//Function to pan viewport from X/Y to DX/DY
void PanViewport(int DX, int DY, int speed, ffc this)
{
int angle = Angle(this->Misc[MV_INTERNAL_X], this->Misc[MV_INTERNAL_Y], DX, DY), cangle = Cos(angle), sangle = Sin(angle);
this->Misc[MV_INTERNAL_X] += cangle*speed;
this->Misc[MV_INTERNAL_Y] += sangle*speed;
Viewport->X = this->Misc[MV_INTERNAL_X];
Viewport->Y = this->Misc[MV_INTERNAL_Y];
}