556 lines
19 KiB
C++
556 lines
19 KiB
C++
#include "cbase.h"
|
|
#include "asw_marine_resource.h"
|
|
#include "asw_marine_profile.h"
|
|
#include "asw_player.h"
|
|
#include "asw_marine.h"
|
|
#include "asw_hack_wire_tile.h"
|
|
#include "asw_button_area.h"
|
|
#include "asw_util_shared.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file
|
|
#include "tier0/memdbgon.h"
|
|
|
|
LINK_ENTITY_TO_CLASS( asw_hack_wire_tile, CASW_Hack_Wire_Tile );
|
|
|
|
IMPLEMENT_SERVERCLASS_ST(CASW_Hack_Wire_Tile, DT_ASW_Hack_Wire_Tile)
|
|
SendPropInt (SENDINFO(m_iNumColumns) ),
|
|
SendPropInt (SENDINFO(m_iNumRows) ),
|
|
SendPropInt (SENDINFO(m_iNumWires) ),
|
|
SendPropFloat (SENDINFO(m_fFastFinishTime), 0, SPROP_NOSCALE ),
|
|
SendPropFloat (SENDINFO(m_fFinishedHackTime), 0, SPROP_NOSCALE ),
|
|
|
|
SendPropArray3 ( SENDINFO_ARRAY3(m_iWire1TileLit), SendPropBool( SENDINFO_ARRAY(m_iWire1TileLit) ) ),
|
|
SendPropArray3 ( SENDINFO_ARRAY3(m_iWire2TileLit), SendPropBool( SENDINFO_ARRAY(m_iWire2TileLit) ) ),
|
|
SendPropArray3 ( SENDINFO_ARRAY3(m_iWire3TileLit), SendPropBool( SENDINFO_ARRAY(m_iWire3TileLit) ) ),
|
|
SendPropArray3 ( SENDINFO_ARRAY3(m_iWire4TileLit), SendPropBool( SENDINFO_ARRAY(m_iWire4TileLit) ) ),
|
|
|
|
SendPropArray3 ( SENDINFO_ARRAY3(m_iWire1TileType), SendPropInt( SENDINFO_ARRAY(m_iWire1TileType), ASW_TILE_ARRAY_SIZE, SPROP_UNSIGNED ) ),
|
|
SendPropArray3 ( SENDINFO_ARRAY3(m_iWire2TileType), SendPropInt( SENDINFO_ARRAY(m_iWire2TileType), ASW_TILE_ARRAY_SIZE, SPROP_UNSIGNED ) ),
|
|
SendPropArray3 ( SENDINFO_ARRAY3(m_iWire3TileType), SendPropInt( SENDINFO_ARRAY(m_iWire3TileType), ASW_TILE_ARRAY_SIZE, SPROP_UNSIGNED ) ),
|
|
SendPropArray3 ( SENDINFO_ARRAY3(m_iWire4TileType), SendPropInt( SENDINFO_ARRAY(m_iWire4TileType), ASW_TILE_ARRAY_SIZE, SPROP_UNSIGNED ) ),
|
|
|
|
SendPropArray3 ( SENDINFO_ARRAY3(m_iWire1TilePosition), SendPropInt( SENDINFO_ARRAY(m_iWire1TilePosition), ASW_TILE_ARRAY_SIZE, SPROP_UNSIGNED ) ),
|
|
SendPropArray3 ( SENDINFO_ARRAY3(m_iWire2TilePosition), SendPropInt( SENDINFO_ARRAY(m_iWire2TilePosition), ASW_TILE_ARRAY_SIZE, SPROP_UNSIGNED ) ),
|
|
SendPropArray3 ( SENDINFO_ARRAY3(m_iWire3TilePosition), SendPropInt( SENDINFO_ARRAY(m_iWire3TilePosition), ASW_TILE_ARRAY_SIZE, SPROP_UNSIGNED ) ),
|
|
SendPropArray3 ( SENDINFO_ARRAY3(m_iWire4TilePosition), SendPropInt( SENDINFO_ARRAY(m_iWire4TilePosition), ASW_TILE_ARRAY_SIZE, SPROP_UNSIGNED ) ),
|
|
END_SEND_TABLE()
|
|
|
|
//---------------------------------------------------------
|
|
// Save/Restore
|
|
//---------------------------------------------------------
|
|
BEGIN_DATADESC( CASW_Hack_Wire_Tile )
|
|
DEFINE_FIELD( m_iNumColumns, FIELD_INTEGER ),
|
|
DEFINE_FIELD( m_iNumRows, FIELD_INTEGER ),
|
|
DEFINE_FIELD( m_iNumWires, FIELD_INTEGER ),
|
|
|
|
DEFINE_FIELD( m_bSetupPuzzle, FIELD_BOOLEAN ),
|
|
DEFINE_FIELD( m_fFastFinishTime , FIELD_TIME ),
|
|
|
|
DEFINE_AUTO_ARRAY( m_iWire1TileLit, FIELD_BOOLEAN ),
|
|
DEFINE_AUTO_ARRAY( m_iWire2TileLit, FIELD_BOOLEAN ),
|
|
DEFINE_AUTO_ARRAY( m_iWire3TileLit, FIELD_BOOLEAN ),
|
|
DEFINE_AUTO_ARRAY( m_iWire4TileLit, FIELD_BOOLEAN ),
|
|
|
|
DEFINE_AUTO_ARRAY( m_iWire1TileType, FIELD_INTEGER ),
|
|
DEFINE_AUTO_ARRAY( m_iWire2TileType, FIELD_INTEGER ),
|
|
DEFINE_AUTO_ARRAY( m_iWire3TileType, FIELD_INTEGER ),
|
|
DEFINE_AUTO_ARRAY( m_iWire4TileType, FIELD_INTEGER ),
|
|
|
|
DEFINE_AUTO_ARRAY( m_iWire1TilePosition, FIELD_INTEGER ),
|
|
DEFINE_AUTO_ARRAY( m_iWire2TilePosition, FIELD_INTEGER ),
|
|
DEFINE_AUTO_ARRAY( m_iWire3TilePosition, FIELD_INTEGER ),
|
|
DEFINE_AUTO_ARRAY( m_iWire4TilePosition, FIELD_INTEGER ),
|
|
END_DATADESC()
|
|
|
|
extern ConVar asw_debug_tile_connections;
|
|
ConVar asw_wire_full_random("asw_wire_full_random", "0", FCVAR_CHEAT, "Fully randomize wire hacks");
|
|
|
|
CASW_Hack_Wire_Tile::CASW_Hack_Wire_Tile()
|
|
{
|
|
m_bPlayedTimeOutSound = false;
|
|
m_fFinishedHackTime = 0;
|
|
}
|
|
|
|
|
|
bool CASW_Hack_Wire_Tile::InitHack(CASW_Player* pHackingPlayer, CASW_Marine* pHackingMarine, CBaseEntity* pHackTarget)
|
|
{
|
|
CASW_Button_Area *pButton = dynamic_cast<CASW_Button_Area*>(pHackTarget);
|
|
if (!pHackingPlayer || !pHackingMarine || !pButton || !pHackingMarine->GetMarineResource())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!m_bSetupPuzzle)
|
|
{
|
|
// pull the puzzle settings from the button area, applying defaults if anything is out of range
|
|
m_iNumColumns = pButton->m_iWireColumns;
|
|
if (m_iNumColumns < 3 || m_iNumColumns > ASW_MAX_TILE_COLUMNS)
|
|
m_iNumColumns = 5;
|
|
m_iNumRows = pButton->m_iWireRows;
|
|
if (m_iNumRows <= 0 || m_iNumRows > ASW_MAX_TILE_ROWS)
|
|
m_iNumRows = 2;
|
|
m_iNumWires = pButton->m_iNumWires;
|
|
if (m_iNumWires <= 0 || m_iNumWires > 4)
|
|
m_iNumWires = 3;
|
|
|
|
//m_iNumColumns = 8;
|
|
//m_iNumRows = 1;
|
|
//m_iNumWires = 4;
|
|
|
|
BuildWirePuzzle();
|
|
|
|
for ( int i = 0; i < ASW_NUM_WIRES; i++ )
|
|
{
|
|
UpdateLitTiles( i + 1 );
|
|
m_bWasWireLit[ i ] = IsWireLit( i + 1 );
|
|
}
|
|
m_bSetupPuzzle = true;
|
|
}
|
|
|
|
return BaseClass::InitHack(pHackingPlayer, pHackingMarine, pHackTarget);
|
|
}
|
|
|
|
#define HACK_SPEED_SCALE 4.0f
|
|
//#define INCREASE_HACKING_SPEED_PER_WIRE
|
|
ConVar asw_hacking_fraction( "asw_hacking_fraction", "0.1f" );
|
|
|
|
void CASW_Hack_Wire_Tile::ASWPostThink(CASW_Player *pPlayer, CASW_Marine *pMarine, CUserCmd *ucmd, float fDeltaTime)
|
|
{
|
|
CBaseEntity *pEnt = m_hHackTarget;
|
|
CASW_Button_Area *pButton = dynamic_cast<CASW_Button_Area*>( pEnt );
|
|
if ( !pButton || !pButton->m_bIsInUse )
|
|
return;
|
|
|
|
int iHackLevel = pButton->m_iHackLevel;
|
|
float flBaseIncrease = ( fDeltaTime * ( 1.0f / ( ( float ) iHackLevel ) ) ) * HACK_SPEED_SCALE;
|
|
// boost fTime by the marine's hack skill
|
|
//flBaseIncrease *= MarineSkills()->GetSkillBasedValueByMarine( pMarine, ASW_MARINE_SKILL_HACKING, ASW_MARINE_SUBSKILL_HACKING_SPEED_SCALE );
|
|
|
|
float f = pButton->GetHackProgress();
|
|
|
|
#ifdef INCREASE_HACKING_SPEED_PER_WIRE
|
|
// total time increase is based on how many wires are lit
|
|
float flTimeIncrease = 0;
|
|
for ( int i=0;i<=ASW_NUM_WIRES;i++ )
|
|
{
|
|
if ( IsWireLit( i+1 ) )
|
|
flTimeIncrease += flBaseIncrease;
|
|
}
|
|
int iNumWires = m_iNumWires;
|
|
if ( iNumWires <= 0 )
|
|
iNumWires = 1;
|
|
flTimeIncrease *= ( 1.0f / iNumWires );
|
|
|
|
pButton->SetHackProgress(f + flTimeIncrease, pMarine);
|
|
#else
|
|
int iWiresLit = 0;
|
|
for ( int i = 0; i < ASW_NUM_WIRES; i++ )
|
|
{
|
|
if ( IsWireLit( i + 1 ) )
|
|
{
|
|
iWiresLit++;
|
|
m_bWasWireLit[ i ] = true;
|
|
}
|
|
else
|
|
{
|
|
m_bWasWireLit[ i ] = false;
|
|
}
|
|
}
|
|
|
|
float flGoal = (float) iWiresLit / (float) m_iNumWires.Get();
|
|
float move = ( flGoal - f ) * asw_hacking_fraction.GetFloat() * fDeltaTime;
|
|
move = MAX( move, flBaseIncrease );
|
|
f = MIN( f + move, flGoal );
|
|
|
|
pButton->SetHackProgress( f, pMarine);
|
|
#endif
|
|
|
|
// play a sound if the player has done the hack too slowly?
|
|
if ( !m_bPlayedTimeOutSound && f < 1.0f )
|
|
{
|
|
if ( m_fFastFinishTime.Get() > 0 && gpGlobals->curtime > m_fFastFinishTime.Get() )
|
|
{
|
|
pButton->EmitSound( "ASWComputer.TimeOut" );
|
|
m_bPlayedTimeOutSound = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CASW_Hack_Wire_Tile::BuildWirePuzzle()
|
|
{
|
|
for (int i=1;i<=m_iNumWires;i++)
|
|
{
|
|
BuildWire(i);
|
|
}
|
|
}
|
|
|
|
// uses the current num columns/rows to fill out the array with tiles that link the top left to the bottom right
|
|
void CASW_Hack_Wire_Tile::BuildWire(int iWire)
|
|
{
|
|
if (m_iNumRows == 1)
|
|
{
|
|
// all tiles have to be straight
|
|
for (int i=0;i<m_iNumColumns;i++)
|
|
{
|
|
SetTileType(iWire, i, 0, ASW_WIRE_TILE_HORIZ);
|
|
SetTileRotation(iWire, i, 0, 0);
|
|
}
|
|
}
|
|
else if (m_iNumRows == 2)
|
|
{
|
|
int cur_x = 0;
|
|
int cur_y = 0;
|
|
int last_cur_x = -1;
|
|
int last_cur_y = 0;
|
|
while (cur_x < m_iNumColumns - 1)
|
|
{
|
|
bool bGoStraight = random->RandomFloat() < 0.4f;
|
|
last_cur_x = cur_x;
|
|
last_cur_y = cur_y;
|
|
if (bGoStraight)
|
|
{
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_HORIZ);
|
|
SetTileRotation(iWire, cur_x, cur_y, 0);
|
|
// set our partner as a random piece
|
|
SetTileType(iWire, cur_x, 1 - cur_y, random->RandomInt(0, 2));
|
|
SetTileRotation(iWire, cur_x, 1 - cur_y, 0);
|
|
cur_x++;
|
|
}
|
|
else
|
|
{
|
|
// otherwise, both should be corner pieces
|
|
if (cur_y == 0) // we're at the top, so it has to be an r/l combo
|
|
{
|
|
//Msg("Generating puzzle, column %d, setting top to TILE RIGHT (r=%d), bottom to TILE LEFT (r=%d)\n", cur_x, 1, 2);
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_RIGHT);
|
|
SetTileRotation(iWire, cur_x, cur_y, 1);
|
|
SetTileType(iWire, cur_x, 1 - cur_y, ASW_WIRE_TILE_LEFT);
|
|
SetTileRotation(iWire, cur_x, 1 - cur_y, 2);
|
|
cur_x++;
|
|
cur_y = 1 - cur_y;
|
|
}
|
|
else // otherwise it's an l r combo
|
|
{
|
|
//Msg("Generating puzzle, column %d, setting top to TILE LEFT (r=%d), bottom to TILE RIGHT (r=%d)\n", cur_x, 1, 0);
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_LEFT);
|
|
SetTileRotation(iWire, cur_x, cur_y, 1);
|
|
SetTileType(iWire, cur_x, 1 - cur_y, ASW_WIRE_TILE_RIGHT);
|
|
SetTileRotation(iWire, cur_x, 1 - cur_y, 0);
|
|
cur_x++;
|
|
cur_y = 1 - cur_y;
|
|
}
|
|
}
|
|
}
|
|
// in the last column, we either straight or do two corner pieces, so we can get to the bottom
|
|
if (cur_y == 1)
|
|
{
|
|
// already at the bottom, so go straight
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_HORIZ);
|
|
SetTileRotation(iWire, cur_x, cur_y, 0);
|
|
SetTileType(iWire, cur_x, 1 - cur_y, random->RandomInt(0, 2)); // random piece
|
|
SetTileRotation(iWire, cur_x, 1 - cur_y, 0);
|
|
}
|
|
else
|
|
{
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_RIGHT);
|
|
SetTileRotation(iWire, cur_x, cur_y, 1);
|
|
SetTileType(iWire, cur_x, 1 - cur_y, ASW_WIRE_TILE_LEFT);
|
|
SetTileRotation(iWire, cur_x, 1- cur_y, 2);
|
|
}
|
|
}
|
|
else if (m_iNumRows == 3)
|
|
{
|
|
// first fill them with random junk, so any unset tiles we can leave
|
|
for (int x=0;x<m_iNumColumns;x++)
|
|
{
|
|
for (int y=0;y<m_iNumRows;y++)
|
|
{
|
|
SetTileType(iWire, x, y, random->RandomInt(0, 2));
|
|
SetTileRotation(iWire, x, y, random->RandomInt(0, 3));
|
|
SetTileLit(iWire, x, y, false);
|
|
}
|
|
}
|
|
|
|
int cur_x = 0;
|
|
int cur_y = 0;
|
|
int last_cur_x = -1;
|
|
int last_cur_y = 0;
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1)
|
|
Msg("Starting 3 row generation:\n");
|
|
while (cur_x < m_iNumColumns - 1)
|
|
{
|
|
int tempx = cur_x;
|
|
int tempy = cur_y;
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1)
|
|
Msg(" cur = %d,%d last = %d, %d\n", cur_x, cur_y, last_cur_x, last_cur_y);
|
|
// either go forward or up/down
|
|
bool bGoForward = random->RandomFloat() < 0.33f;
|
|
if (last_cur_x == cur_x && cur_y != 1) // have to go forward if we're on the same row as last time and are at an edge
|
|
bGoForward = true;
|
|
if (bGoForward)
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg(" wants to go forward\n");
|
|
// want to go forward
|
|
if (last_cur_x != cur_x) // if we came from the left, we can just throw in a horiz one
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg(" since we came from the left, putting in a horiz rot 0\n");
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_HORIZ);
|
|
SetTileRotation(iWire, cur_x, cur_y, 0);
|
|
cur_x++;
|
|
}
|
|
else // otherwise, need to figure out where we came from
|
|
{
|
|
if (last_cur_y < cur_y) // if we came from above, need to do a left turn
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg(" since we came from the above, putting in a left turn rot 2\n");
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_LEFT);
|
|
SetTileRotation(iWire, cur_x, cur_y, 2);
|
|
cur_x++;
|
|
}
|
|
else
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg(" since we came from the below, putting in a right turn rot 0\n");
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_RIGHT);
|
|
SetTileRotation(iWire, cur_x, cur_y, 0);
|
|
cur_x++;
|
|
}
|
|
}
|
|
}
|
|
else // want to stay on this column and go up/down
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg(" wants to stay on the column\n");
|
|
bool bGoUp = random->RandomFloat() < 0.5f;
|
|
if (cur_y <= 0 || last_cur_y <= 0)
|
|
bGoUp = false;
|
|
if (cur_y >= 2 || last_cur_y >= 2)
|
|
bGoUp = true;
|
|
if (last_cur_x != cur_x) // if we came from the left, put in the appropriate corner piece
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg(" we came from the left, ");
|
|
if (bGoUp)
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg("and want to go up, so putting in a left rot 1\n");
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_LEFT);
|
|
SetTileRotation(iWire, cur_x, cur_y, 1);
|
|
cur_y--;
|
|
}
|
|
else
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg("and want to go down, so putting in a right rot 1\n");
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_RIGHT);
|
|
SetTileRotation(iWire, cur_x, cur_y, 1);
|
|
cur_y++;
|
|
}
|
|
}
|
|
else // if we're going straight up/down, put in the horiz
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg(" we were already on this column, ");
|
|
if (bGoUp)
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg("and want to go up, so putting in a horiz and moving up rot 2\n");
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_HORIZ);
|
|
SetTileRotation(iWire, cur_x, cur_y, 1);
|
|
cur_y--;
|
|
}
|
|
else
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg("and want to go down, so putting in a horiz and moving down rot 2\n");
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_HORIZ);
|
|
SetTileRotation(iWire, cur_x, cur_y, 1);
|
|
cur_y++;
|
|
}
|
|
}
|
|
}
|
|
last_cur_x = tempx;
|
|
last_cur_y = tempy;
|
|
}
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg("At the last column.\n");
|
|
// in the last column, need to get to the bottom
|
|
if (cur_y == 2)
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg(" at the bottom already, so let's go straight rot 0\n");
|
|
// already at the bottom, so go straight
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_HORIZ);
|
|
SetTileRotation(iWire, cur_x, cur_y, 0);
|
|
}
|
|
else if (cur_y == 1) // came into the last row at the middle
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg(" at the middle so turnign right, then left\n");
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_RIGHT);
|
|
SetTileRotation(iWire, cur_x, cur_y, 1);
|
|
SetTileType(iWire, cur_x, 2, ASW_WIRE_TILE_LEFT);
|
|
SetTileRotation(iWire, cur_x, 2, 2);
|
|
}
|
|
else if (cur_y == 0) // came into the last row at the top
|
|
{
|
|
if (asw_debug_tile_connections.GetBool() && iWire == 1) Msg(" at the top so turnign right, straight, then left\n");
|
|
SetTileType(iWire, cur_x, cur_y, ASW_WIRE_TILE_RIGHT);
|
|
SetTileRotation(iWire, cur_x, cur_y, 1);
|
|
SetTileType(iWire, cur_x, 1, ASW_WIRE_TILE_HORIZ);
|
|
SetTileRotation(iWire, cur_x, 1, 2);
|
|
SetTileType(iWire, cur_x, 2, ASW_WIRE_TILE_LEFT);
|
|
SetTileRotation(iWire, cur_x, 2, 2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// just fill it with random junk as a test
|
|
for (int x=0;x<m_iNumColumns;x++)
|
|
{
|
|
for (int y=0;y<m_iNumRows;y++)
|
|
{
|
|
SetTileType(iWire, x, y, random->RandomInt(0, 2));
|
|
SetTileRotation(iWire, x, y, random->RandomInt(0, 3));
|
|
SetTileLit(iWire, x, y, false);
|
|
}
|
|
}
|
|
}
|
|
JumbleWire(iWire);
|
|
}
|
|
|
|
void CASW_Hack_Wire_Tile::JumbleWire(int iWire)
|
|
{
|
|
if (asw_wire_full_random.GetBool())
|
|
{
|
|
for (int x=0;x<m_iNumColumns;x++)
|
|
{
|
|
for (int y=0;y<m_iNumRows;y++)
|
|
{
|
|
SetTileRotation(iWire, x, y, random->RandomInt(0, 3));
|
|
SetTileLit(iWire, x, y, false);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
// first randomize any non-lit tiles
|
|
UpdateLitTiles(iWire);
|
|
for (int x=0;x<m_iNumColumns;x++)
|
|
{
|
|
for (int y=0;y<m_iNumRows;y++)
|
|
{
|
|
if (!GetTileLit(iWire, x, y))
|
|
{
|
|
SetTileRotation(iWire, x, y, random->RandomInt(0, 3));
|
|
SetTileLit(iWire, x, y, false);
|
|
}
|
|
}
|
|
}
|
|
// now work from the end back, making mistakes on the lit wire
|
|
int iMistakes = 0;
|
|
int k = 0;
|
|
while (iMistakes <= 0 && k <= 10)
|
|
{
|
|
k++;
|
|
for (int x=m_iNumColumns-1;x>=0;x--)
|
|
{
|
|
for (int y=0;y<m_iNumRows;y++)
|
|
{
|
|
//if (x != m_iNumColumns-1)
|
|
//continue;
|
|
// decide if this should be a mistake column or not
|
|
if (random->RandomFloat() < 0.5f)
|
|
{
|
|
if (GetTileLit(iWire, x, y))
|
|
{
|
|
int k=0;
|
|
while (GetTileLit(iWire, x, y) && k < 10)
|
|
{
|
|
SetTileRotation(iWire, x, y, random->RandomInt(0, 3));
|
|
SetTileLit(iWire, x, y, false);
|
|
UpdateLitTiles(iWire);
|
|
k++;
|
|
}
|
|
iMistakes++;
|
|
if (iMistakes >= 5) // don't make more than 5 mistakes per wire (cutting out early and working from the back biases mistakes to the end, but that's cool)
|
|
return;
|
|
|
|
y = m_iNumRows; // don't change any more in this column
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CASW_Hack_Wire_Tile::SetTileType(int iWire, int x, int y, int iType)
|
|
{
|
|
if (x < 0 || x>=m_iNumColumns || y<0 || y >= m_iNumRows)
|
|
{
|
|
Msg("Tile coords out of bounds! %d,%d\n", x, y);
|
|
return;
|
|
}
|
|
SetTileType(iWire, y * m_iNumColumns + x, iType);
|
|
}
|
|
|
|
void CASW_Hack_Wire_Tile::SetTileType(int iWire, int iTileIndex, int iType)
|
|
{
|
|
if (iTileIndex <0 || iTileIndex >= m_iNumColumns*m_iNumRows)
|
|
{
|
|
Msg("Tile index out of bounds! %d\n", iTileIndex);
|
|
return;
|
|
}
|
|
if (iWire == 1)
|
|
m_iWire1TileType.Set(iTileIndex, iType);
|
|
else if (iWire == 2)
|
|
m_iWire2TileType.Set(iTileIndex, iType);
|
|
else if (iWire == 3)
|
|
m_iWire3TileType.Set(iTileIndex, iType);
|
|
else if (iWire == 4)
|
|
m_iWire4TileType.Set(iTileIndex, iType);
|
|
}
|
|
|
|
void CASW_Hack_Wire_Tile::SelectHackOption(int i)
|
|
{
|
|
if (i < 0)
|
|
return;
|
|
int iTiles = m_iNumColumns * m_iNumRows;
|
|
int iWire = -1;
|
|
if (i < iTiles)
|
|
iWire = 1;
|
|
else if (i < iTiles * 2)
|
|
iWire = 2;
|
|
else if (i < iTiles * 3)
|
|
iWire = 3;
|
|
else if (i < iTiles * 4)
|
|
iWire = 4;
|
|
if (iWire != -1)
|
|
{
|
|
i -= (iWire-1)*iTiles;
|
|
int iRot = GetTileRotation(iWire, i);
|
|
iRot++;
|
|
if (iRot >= 4)
|
|
iRot = 0;
|
|
SetTileRotation(iWire, i, iRot);
|
|
|
|
UpdateLitTiles(1);
|
|
UpdateLitTiles(2);
|
|
UpdateLitTiles(3);
|
|
UpdateLitTiles(4);
|
|
|
|
CASW_Button_Area *pButton = dynamic_cast<CASW_Button_Area*>(GetHackTarget());
|
|
if (pButton)
|
|
{
|
|
if (pButton->m_fStartedHackTime == 0)
|
|
{
|
|
pButton->m_fStartedHackTime = gpGlobals->curtime;
|
|
|
|
float fSpeedScale = 1.0f;
|
|
CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(m_hHackingMarine.Get());
|
|
if (pMarine)
|
|
fSpeedScale *= MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_HACKING, ASW_MARINE_SUBSKILL_HACKING_SPEED_SCALE);
|
|
float fTimeTaken = UTIL_ASW_CalcFastDoorHackTime(pButton->m_iWireRows, pButton->m_iWireColumns, pButton->m_iNumWires, pButton->m_iHackLevel, fSpeedScale);
|
|
// notify client of when it should finish, to be a fast hack
|
|
m_fFastFinishTime = gpGlobals->curtime + fTimeTaken;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void CASW_Hack_Wire_Tile::OnHackComplete()
|
|
{
|
|
BaseClass::OnHackComplete();
|
|
|
|
m_fFinishedHackTime = gpGlobals->curtime;
|
|
} |