/* =========================================================================== Copyright (C) 2015 the OpenMoHAA team This file is part of OpenMoHAA source code. OpenMoHAA source code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. OpenMoHAA source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenMoHAA source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ // scripttimer.cpp: Scripted Timer & Fader // #include "scripttimer.h" #include "level.h" #if defined(GAME_DLL) # include "archive.h" #endif Event EV_ScriptTimer_Think ( "scripttimer_think", EV_CODEONLY, NULL, NULL, "Internal event", EV_NORMAL ); Container m_scriptTimers; /*void ScriptTimer::HandleTimer( float frametime ) { ScriptTimer *timer; for( int i = 0; i < m_scriptTimers.NumObjects(); i++ ) { timer = m_scriptTimers[ i ]; if( timer->isEnabled() && timer->GetTime() > 0.0f ) { timer->Think( frametime ); } } }*/ ScriptTimer::ScriptTimer(timertype_e type) { Reset(); bEnabled = false; setType(type); m_scriptTimers.AddObject(this); } ScriptTimer::~ScriptTimer() { Disable(); if (m_scriptTimers.IndexOfObject(this)) { m_scriptTimers.RemoveObject(this); } } void ScriptTimer::Archive(Archiver& arc) { Listener::Archive(arc); #ifdef CGAME_DLL arc.ArchiveFloat(&targetTime); arc.ArchiveFloat(¤tTime); arc.ArchiveFloat(&realTime); arc.ArchiveFloat(&glideRatio); arc.ArchiveInteger((int *)&timerType); arc.ArchiveBool(&bEnabled); if (arc.Loading() && bEnabled) { Enable(); } #endif } void ScriptTimer::GlideRefresh() { if (timerType != TIMER_GLIDE) { return; } if (targetTime <= 0.0f) { return; } float r = realTime / (targetTime * 0.5f); if (r > 1.0f) { glideRatio = 2.0f - 2.0f * (r - 1.0f); if (glideRatio < 0.0f) { glideRatio = 0.0f; } } else { glideRatio = 2.0f * r; if (glideRatio > 2.0f) { glideRatio = 2.0f; } } } void ScriptTimer::Think(Event *ev) { if (!bEnabled) { return; } #ifdef CGAME_DLL float frametime = (float)cg->frametime; #else float frametime = level.frametime; #endif GlideRefresh(); if (currentTime < targetTime) { realTime += frametime; if (timerType == TIMER_GLIDE) { currentTime += frametime * glideRatio; } else { currentTime += frametime; } } else { currentTime = targetTime; realTime = targetTime; bEnabled = false; CancelEventsOfType(&EV_ScriptTimer_Think); return; } CancelEventsOfType(&EV_ScriptTimer_Think); PostEvent(EV_ScriptTimer_Think, level.frametime); } void ScriptTimer::Disable() { bEnabled = false; CancelEventsOfType(&EV_ScriptTimer_Think); } void ScriptTimer::Enable() { bEnabled = true; CancelEventsOfType(EV_ScriptTimer_Think); ProcessEvent(EV_ScriptTimer_Think); } qboolean ScriptTimer::Done() { return (currentTime >= targetTime); } float ScriptTimer::GetCurrentTime() { return realTime; } float ScriptTimer::GetRatio() { float ratio; if (targetTime <= 0.0f) { return 1.0f; } ratio = (currentTime / targetTime); // ratio must not go below 0.0 and above 1.0 return (ratio < 0.0f ? 0.0f : ratio > 1.0f ? 1.0f : ratio); } float ScriptTimer::GetTime() { return targetTime; } float ScriptTimer::LerpValue(float start, float end) { return start + (end - start) * GetRatio(); } Vector ScriptTimer::LerpValue(Vector start, Vector end) { return start + (end - start) * GetRatio(); } void ScriptTimer::Reset() { currentTime = 0.f; realTime = 0.f; glideRatio = 0.f; } void ScriptTimer::SetCurrentTime(float time) { realTime = time * 1000.0f; if (timerType == TIMER_GLIDE) { GlideRefresh(); currentTime = time * 1000.0f * glideRatio; } else { currentTime = time * 1000.0f; } } void ScriptTimer::SetPhase(float phase) { float t = targetTime * (phase / 2.0f) / 1000.0f; SetCurrentTime(t); } void ScriptTimer::SetTime(float time) { Reset(); targetTime = time * 1000.0f; } bool ScriptTimer::isEnabled() { return bEnabled; } void ScriptTimer::setType(timertype_e type) { timerType = type; } CLASS_DECLARATION(Listener, ScriptTimer, NULL) { {&EV_ScriptTimer_Think, &ScriptTimer::Think}, {NULL, NULL } };