1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
/*
* PROPRIETARY INFORMATION. This software is proprietary to POWDER
* Development, and is not to be reproduced, transmitted, or disclosed
* in any way without written permission.
*
* Produced by: Jeff Lait
*
* POWDER Development
*
* NAME: speed.cpp ( POWDER Library, C++ )
*
* COMMENTS:
* Implementation of the speed system.
*
* Speed is INTENTIONALLY round based. The goal is to allow
* predictable movement, rather than the tendency to floating
* point speed systems that have confused (IMO) later roguelikes.
*
* As such, there are three speed modifiers: Fast (F), Quick (Q),
* and Slow (S). There are also 4 types of phases: Fast (F),
* Quick (Q), Slow (S), and Normal (N).
*
* doHeartbeat style functions execute only on N & S phases.
*
* doAI movement operates on the phases according to the following
* chart:
*
* F N S Q N Speed
* N x x x 100%
* F x x x x 133%
* Q x x x x 133%
* FQ x x x x x 167%
* S x x 67%
* FS x x x 100%
* QS x x x 100%
* FQS x x x x 133%
*/
#include "speed.h"
#include "sramstream.h"
#include "assert.h"
int glbGameMoves = 0;
int glbHeartbeatCount = 0;
// We cache this so speed_getphase is fast.
PHASE_NAMES glbCurPhase;
#define PHASE_SEQ_LEN 5
// This is the prebuilt table of phases. We use it to determine
// our current phase given our time tick.
const PHASE_NAMES glbPhaseOrder[PHASE_SEQ_LEN] =
{
PHASE_FAST,
PHASE_NORMAL,
PHASE_SLOW,
PHASE_QUICK,
PHASE_NORMAL
};
void
speed_init()
{
glbGameMoves = 0;
glbHeartbeatCount = 0;
// Initial tick to initialize glbCurPhase.
speed_ticktime();
}
void
speed_reset()
{
glbGameMoves = 0;
glbHeartbeatCount = 0;
speed_ticktime();
}
void
speed_ticktime()
{
glbGameMoves++;
glbCurPhase = glbPhaseOrder[glbGameMoves % PHASE_SEQ_LEN];
if (speed_isheartbeatphase())
glbHeartbeatCount++;
}
int
speed_gettime()
{
return glbGameMoves;
}
PHASE_NAMES
speed_getphase()
{
return glbCurPhase;
}
bool
speed_isheartbeatphase()
{
// Determine if we are in a proper phase.
switch (speed_getphase())
{
case PHASE_FAST:
case PHASE_QUICK:
// Do not hearbeat on these phases.
return false;
case PHASE_NORMAL:
case PHASE_SLOW:
// we want a heartbeat.
return true;
case NUM_PHASES:
UT_ASSERT(!"Invalid phase!");
break;
}
// Should not go here.
return true;
}
bool
speed_matchheartbeat(int modulus)
{
if (modulus < 2)
return true;
// Avoid division where possible.
switch (modulus)
{
case 2:
if (glbHeartbeatCount & 1)
return false;
return true;
case 4:
if (glbHeartbeatCount & 3)
return false;
return true;
case 8:
if (glbHeartbeatCount & 7)
return false;
return true;
}
if (glbHeartbeatCount % modulus)
return false;
return true;
}
void
speed_save(SRAMSTREAM &os)
{
os.write(glbGameMoves, 32);
os.write(glbHeartbeatCount, 32);
}
void
speed_load(SRAMSTREAM &is)
{
is.read(glbGameMoves, 32);
is.read(glbHeartbeatCount, 32);
}
|