File: DamageArray.cpp

package info (click to toggle)
spring 106.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 55,316 kB
  • sloc: cpp: 543,954; ansic: 44,800; python: 12,575; java: 12,201; awk: 5,889; sh: 1,796; asm: 1,546; xml: 655; perl: 405; php: 211; objc: 194; makefile: 76; sed: 2
file content (147 lines) | stat: -rw-r--r-- 3,394 bytes parent folder | download | duplicates (3)
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
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#include "DamageArray.h"
#include "DamageArrayHandler.h"

#include "System/float3.h"

#include <cassert>

CR_BIND(DamageArray, )

CR_REG_METADATA(DamageArray, (
	CR_MEMBER(paralyzeDamageTime),
	CR_MEMBER(impulseFactor),
	CR_MEMBER(impulseBoost),
	CR_MEMBER(craterMult),
	CR_MEMBER(craterBoost),
	CR_MEMBER(damages)
))

void DamageArray::SetDefaultDamage(float damage)
{
	damages.clear();
	damages.resize(std::max(1, damageArrayHandler.GetNumTypes()), damage);
}


CR_BIND_DERIVED(DynDamageArray, DamageArray, )

CR_REG_METADATA(DynDamageArray, (
	CR_MEMBER(dynDamageExp),
	CR_MEMBER(dynDamageMin),
	CR_MEMBER(dynDamageRange),
	CR_MEMBER(dynDamageInverted),
	CR_MEMBER(craterAreaOfEffect),
	CR_MEMBER(damageAreaOfEffect),
	CR_MEMBER(edgeEffectiveness),
	CR_MEMBER(explosionSpeed),
	CR_MEMBER(refCount),
	CR_MEMBER(fromDef),

	CR_POSTLOAD(PostLoad)
))

DynDamageArray::DynDamageArray(float damage)
	: DamageArray(damage)
	, dynDamageExp(0.0f)
	, dynDamageMin(0.0f)
	, dynDamageRange(0.0f)
	, dynDamageInverted(false)
	, craterAreaOfEffect(4.0f)
	, damageAreaOfEffect(4.0f)
	, edgeEffectiveness(0.0f)
	, explosionSpeed(1.0f) // always overwritten
	, refCount(1)
	, fromDef(false)
{ }

DynDamageArray::~DynDamageArray()
{
	assert(refCount == 1);
}

void DynDamageArray::PostLoad()
{
	// weapondefs aren't serialized but if their damages tables are in use
	// these pointers will be serialized.
	// so during loading, a duplicate of the damages table is created
	// with a wrong refCount (it still counts the ref in the weaponDef).
	// that's why we need to decrement it and mark that we aren't a def table
	if (fromDef) {
		--refCount;
		fromDef = false;
	}
	assert(refCount > 0);
}

DamageArray DynDamageArray::GetDynamicDamages(const float3& startPos, const float3& curPos) const
{
	DamageArray dynDamages(*this);

	if (dynDamageExp <= 0.0f)
		return dynDamages;


	const float travDist  = std::min(dynDamageRange, curPos.distance2D(startPos));
	const float damageMod = 1.0f - math::pow(1.0f / dynDamageRange * travDist, dynDamageExp);
	const float ddmod     = dynDamageMin / damages[0]; // get damage mod from first damage type

	if (dynDamageInverted) {
		for (int i = 0; i < damageArrayHandler.GetNumTypes(); ++i) {
			float d = damages[i] - damageMod * damages[i];

			if (dynDamageMin > 0.0f)
				d = std::max(damages[i] * ddmod, d);

			// to prevent div by 0
			d = std::max(0.0001f, d);
			dynDamages.Set(i, d);
		}
	} else {
		for (int i = 0; i < damageArrayHandler.GetNumTypes(); ++i) {
			float d = damageMod * damages[i];

			if (dynDamageMin > 0.0f)
				d = std::max(damages[i] * ddmod, d);

			// div by 0
			d = std::max(0.0001f, d);
			dynDamages.Set(i, d);
		}
	}

	return dynDamages;
}


const DynDamageArray* DynDamageArray::IncRef(const DynDamageArray* dda)
{
	++dda->refCount;
	return dda;
}


void DynDamageArray::DecRef(const DynDamageArray* dda)
{
	if (dda->refCount == 1) {
		delete const_cast<DynDamageArray*>(dda);
	} else {
		--dda->refCount;
	}
}

DynDamageArray* DynDamageArray::GetMutable(const DynDamageArray*& dda)
{
	if (dda != nullptr) {
		if (dda->refCount == 1)
			return const_cast<DynDamageArray*>(dda);

		//We're still in use by someone, so copy and replace
		//pointer
		DecRef(dda);
	}

	DynDamageArray* newDDA = new DynDamageArray(*dda);
	dda = newDDA;
	return newDDA;
}