File: EffectTiming.cpp

package info (click to toggle)
freespace2 24.2.0%2Brepack-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 43,716 kB
  • sloc: cpp: 595,001; ansic: 21,741; python: 1,174; sh: 457; makefile: 248; xml: 181
file content (122 lines) | stat: -rw-r--r-- 3,482 bytes parent folder | download
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
#include "EffectTiming.h"

namespace particle {
namespace util {


EffectTiming::EffectTiming() : m_duration(Duration::Onetime) {

}

void EffectTiming::applyToSource(ParticleSource* source) const
{
	if (m_duration == Duration::Range || m_duration == Duration::Always) {
		int duration = -1;
		int delay = static_cast<int>(m_delayRange.next() * 1000.f);

		// Make the timestamp invalid if there is no delay
		if (delay == 0) {
			delay = -1;
		}

		if (m_duration == Duration::Range) {
			duration = static_cast<int>(m_durationRange.next() * 1000.f);
		}

		if (delay != -1 && duration != -1) {
			// Need to adjust the duration because setLifetime expects a timestamp for the end
			duration = delay + duration;
		}

		source->getTiming()->setLifetime(timestamp(delay), timestamp(duration));
	}
}

bool EffectTiming::continueProcessing(const ParticleSource* source) const
{
	switch (m_duration) {
		case Duration::Onetime:
			if (source->getProcessingCount() > 0) {
				// Only process on the first frame
				return false;
			}
			break;
		default:
			// Everything else is handled elsewhere
			return true;
	}

	return true;
}

int EffectTiming::shouldCreateEffect(ParticleSource* source, EffectTiming::TimingState& localState) const
{
	if (m_particlesPerSecond.min() < 0.0f) {
		// If this is not specified then on every frame we will create exactly one effect
		if (localState.initial) {
			localState.initial = false;
			return 0;
		} else {
			return -1;
		}
	}

	// We have a valid particles per second value so we use the next creation timestamp in the particle source for
	// deciding if we can create an effect


	if (source->getTiming()->nextCreationTimeExpired())
	{
		// Invert this so we can compute the time difference between effect creations
		auto secondsPerParticle = 1.0f / m_particlesPerSecond.next();
		// we need to clamp this to 1 because a spawn delay of 0 means we try to spawn infinite particles
		auto time_diff_ms = std::max(fl2i(secondsPerParticle * MILLISECONDS_PER_SECOND), 1);
		int creation_time = source->getTiming()->getNextCreationTime();
		source->getTiming()->incrementNextCreationTime(time_diff_ms);

		return timestamp_since(creation_time);
	}

	return -1;
}

EffectTiming EffectTiming::parseTiming() {
	EffectTiming timing;

	if (optional_string("+Duration:")) {
		if (optional_string("Onetime")) {
			timing.m_duration = Duration::Onetime;
		}
		else if (optional_string("Always")) {
			timing.m_duration = Duration::Always;
		}
		else {
			timing.m_duration = Duration::Range;
			timing.m_durationRange = ::util::ParsedRandomFloatRange::parseRandomRange(0.0f);
		}
	}

	if (optional_string("+Delay:")) {
		if (timing.m_duration == Duration::Onetime) {
			error_display(0, "+Delay is not valid for one-time effects!");
		}
		else {
			timing.m_delayRange = ::util::ParsedRandomFloatRange::parseRandomRange(0.0f);
		}
	}

	if (optional_string("+Effects per second:")) {
		timing.m_particlesPerSecond = ::util::ParsedRandomFloatRange::parseRandomRange();
		if (timing.m_particlesPerSecond.min() < 0.001f) {
			error_display(0, "Invalid effects per second minimum %f. Setting was disabled.", timing.m_particlesPerSecond.min());
			timing.m_particlesPerSecond = ::util::UniformFloatRange(-1.f);
		}
		if (timing.m_particlesPerSecond.max() > 1000.0f) {
			error_display(0, "Effects per second maximum %f is above 1000. Delay between effects will be clamped to 1 millisecond.", timing.m_particlesPerSecond.max());
		}
	}

	return timing;
}
}
}