PHP код:
// ==========================================================================
// Death Knight Runes
// ==========================================================================
enum rune_type
{
RUNE_TYPE_NONE=0, RUNE_TYPE_BLOOD, RUNE_TYPE_FROST, RUNE_TYPE_UNHOLY, RUNE_TYPE_DEATH, RUNE_TYPE_WASDEATH=8
};
const char *rune_symbols = "!bfu!!";
#define RUNE_TYPE_MASK 3
#define RUNE_SLOT_MAX 6
#define RUNE_GRACE_PERIOD 2.0
#define RUNIC_POWER_REFUND 0.9
#define GET_BLOOD_RUNE_COUNT(x) (((x&0x01) + ((x&0x02)>>1)) )
#define GET_FROST_RUNE_COUNT(x) (((x&0x08) + ((x&0x10)>>1)) >>3)
#define GET_UNHOLY_RUNE_COUNT(x) (((x&0x40) + ((x&0x80)>>1)) >>6)
struct dk_rune_t
{
double cooldown_ready;
int type;
dk_rune_t() : cooldown_ready( 0 ), type( RUNE_TYPE_NONE ) {}
bool is_death( ) SC_CONST { return ( type & RUNE_TYPE_DEATH ) != 0; }
bool is_ready( double current_time ) SC_CONST { return cooldown_ready <= current_time; }
int get_type( ) SC_CONST { return type & RUNE_TYPE_MASK; }
void consume( double current_time, double cooldown, bool convert )
{
assert ( current_time >= cooldown_ready );
// First use triggers full cd, after that it is like this:
// How does ImpUP interact?
// Rune used instantly when it comes back: 10s cd
// Rune used 1s after it comes back: 9s cd
// Rune used 2s after it comes back: 8s cd
// Rune used >2s after it comes back: 8s cd
if ( cooldown_ready == -1 ) // First use
cooldown_ready = current_time + cooldown;
else if ( cooldown_ready + RUNE_GRACE_PERIOD > current_time ) // 10s - 8s cd
cooldown_ready = cooldown_ready + cooldown;
else // >2s rune came back
cooldown_ready = current_time + cooldown - RUNE_GRACE_PERIOD;
type = ( type & RUNE_TYPE_MASK ) | ( ( type << 1 ) & RUNE_TYPE_WASDEATH ) | ( convert ? RUNE_TYPE_DEATH : 0 ) ;
}
void reset() { cooldown_ready = -1; type = type & RUNE_TYPE_MASK; }
double time_til_ready( double current_time )
{
return std::max( 0.0, cooldown_ready - current_time );
}
};