File: chunk.cpp

package info (click to toggle)
postal1 2015.git20250526%2Bds-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid
  • size: 14,024 kB
  • sloc: cpp: 130,877; ansic: 38,942; python: 874; makefile: 351; sh: 61
file content (271 lines) | stat: -rw-r--r-- 7,880 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
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2016 RWS Inc, All Rights Reserved
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of version 2 of the GNU General Public License as published by
// the Free Software Foundation
//
// This program 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 this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
// Chunk.cpp
// Project: Nostril (aka Postal)
// 
// History:
//		05/13/97 JMI	Started.
//
//		05/15/97	JMI	Added alpha'ing of blood on the ground.
//
//		05/22/97	JMI	Changed blood alpha level to 60 (was 70).
//
//		05/22/97	JMI	Can support several types of 'chunks'.
//
//		05/26/97	JMI	Changed bullet casing color to 7 (gray) was 3 
//							(dark yellow).
//
//		06/17/97	JMI	Converted all occurrences of rand() to GetRand() and
//							srand() to SeedRand().
//
//		08/18/97	JMI	Now uses its own internal GetRand() and has randomization
//							arguments to Setup() so the caller can still control the
//							the randomization.
//
//		08/25/97	JMI	Setup() was mod'ing m_dRot before adding in the random
//							sway value causing it to sometimes exceed 359.  Fixed.
//
//		09/08/97	JMI	Added Kevlar type for pieces of kevlar vest that 
//							splatter off of dudes with vest.
//
//		09/08/97	JMI	Took out CHUNK_* macros to verify/make-sure they're not
//							used.
//
//////////////////////////////////////////////////////////////////////////////
//
// This CThing-derived class will represent pieces of bloody yee (or chunks)
// that fly off a recently damaged, complex organism or something.
//
//////////////////////////////////////////////////////////////////////////////
#define CHUNK_CPP

#include "RSPiX.h"
#include "chunk.h"
#include "reality.h"

// This class defines its own GetRand()
#undef GetRand
#undef GetRandom

#define GetRand	CChunk::GetChunkRand
#define GetRandom	CChunk::GetChunkRand

////////////////////////////////////////////////////////////////////////////////
// Macros/types/etc.
////////////////////////////////////////////////////////////////////////////////

// Gets a random between -range / 2 and range / 2.
#define RAND_SWAY(sway)	((CChunk::GetChunkRand() % sway) - sway / 2)


// Level at which to alpha blood on the ground.
#define ALPHA_LEVEL		60

////////////////////////////////////////////////////////////////////////////////
// Variables/data
////////////////////////////////////////////////////////////////////////////////

// Note that this is never reseeded b/c this is just an 'effect'
// that does not and SHOULD not affect game play as it can be
// turned off.
int32_t		CChunk::ms_lGetRandomSeed	= 0;	// Seed for GetRand[om]().

// Chunk info for each type.
CChunk::TypeInfo	CChunk::ms_atiChunks[CChunk::NumTypes]	=
	{	// u8ColorIndex, sLen
		{	1,		4,	},	// Blood.
		{	7,		3,	},	// BulletCasing.
		{	2,		4,	},	// Shell.
		{	7,		4,	},	// Kevlar.
	};

////////////////////////////////////////////////////////////////////////////////
// Suspend object
////////////////////////////////////////////////////////////////////////////////
void CChunk::Suspend(void)
	{
	m_sSuspend++;
	}


////////////////////////////////////////////////////////////////////////////////
// Resume object
////////////////////////////////////////////////////////////////////////////////
void CChunk::Resume(void)
	{
	m_sSuspend--;
	}

////////////////////////////////////////////////////////////////////////////////
// Update object
////////////////////////////////////////////////////////////////////////////////
void CChunk::Update(void)
	{
	int32_t	lCurTime		= m_pRealm->m_time.GetGameTime();

	double	dSeconds	= (lCurTime - m_lPrevTime) / 1000.0;
	m_lPrevTime			= lCurTime;

	double	dDist		= m_dVel	* dSeconds;

	m_dX					+= COSQ[(int16_t)m_dRot] * dDist;
	m_dZ					-= SINQ[(int16_t)m_dRot] * dDist;

	double dVertDeltaVel	= g_dAccelerationDueToGravity * dSeconds;
	m_dVertVel			+= dVertDeltaVel;

	m_dY					+= (m_dVertVel - dVertDeltaVel / 2) * dSeconds;

	// If we have hit terrain . . .
	if (m_pRealm->GetHeight(m_dX, m_dZ) >= m_dY)
		{
		int16_t	sX2d, sY2d;
		// Map from 3d to 2d coords.
		Map3Dto2D(m_dX, m_dY, m_dZ, &sX2d, &sY2d);

		switch (m_type)
			{
			case Blood:
				{
				RImage*	pim	= m_pRealm->m_phood->m_pimBackground;

				if (	sX2d >= 0 && sY2d >= 0 
					&&	sX2d < pim->m_sWidth
					&& sY2d < pim->m_sHeight)
					{
					// Pixel.  8bpp only!
					U8*	pu8Dst	= pim->m_pData + sX2d + sY2d * pim->m_lPitch;
					
					*pu8Dst	= rspBlendColor(						// Alpha color/index.
						ALPHA_LEVEL,									// Alpha level.
						m_pRealm->m_phood->m_pmaTransparency,	// Multialpha.
						m_sprite.m_u8Color,							// Src color/index to blend.
						*pu8Dst);										// Dst color/index to blend.
					}
				
				break;
				}
			
			case BulletCasing:
			case Shell:
#if 0	// Looks bad.
				rspPlot(
					(U8)251,
					m_pRealm->m_phood->m_pimBackground,
					sX2d, 
					sY2d);

				rspLine(
					m_sprite.m_u8Color,
					m_pRealm->m_phood->m_pimBackground,
					sX2d, 
					sY2d,
					sX2d + RAND_SWAY(BLOOD_SWAY),
					sY2d + RAND_SWAY(BLOOD_SWAY),
					NULL);
#endif
				break;
			}

		// We're done.
		delete this;
		}
	}

////////////////////////////////////////////////////////////////////////////////
// Render object
////////////////////////////////////////////////////////////////////////////////
void CChunk::Render(void)
	{
	// Map from 3d to 2d coords
	Map3Dto2D(m_dX, m_dY, m_dZ, &m_sprite.m_sX2, &m_sprite.m_sY2);
	
	m_sprite.m_sX2End	= m_sprite.m_sX2 + RAND_SWAY(m_sLen);
	m_sprite.m_sY2End	= m_sprite.m_sY2 + RAND_SWAY(m_sLen);

	// Priority is based on bottom edge of sprite on X/Z plane.
	m_sprite.m_sPriority = m_dZ;
	
	// Layer should be based on info we get from attribute map.
	m_sprite.m_sLayer = CRealm::GetLayerViaAttrib(m_pRealm->GetLayer((int16_t) m_dX, (int16_t) m_dZ));

	// Update sprite in scene
	m_pRealm->m_scene.UpdateSprite(&m_sprite);
	}


////////////////////////////////////////////////////////////////////////////////
// Setup object.
////////////////////////////////////////////////////////////////////////////////
int16_t CChunk::Setup(			// Returns 0 if successfull, non-zero otherwise
	int16_t sX,					// In: New x coord
	int16_t sY,					// In: New y coord
	int16_t sZ,					// In: New z coord
	double dRot,				// In: Initial direction.
	int16_t	sRandRotSway,		// In:  Random sway on rotation or zero.
	double dVel,				// In:  Initial velocity.
	int16_t	sRandVelSway,		// In:  Random sway on velocity or zero.
	double dVertVel,			// In:  Initial vertical velocity.
	int16_t	sRandVertVelSway,	// In:  Random sway on velocity or zero.
	Type	type)					// In:  Type of chunk.
	{
	int16_t sResult = 0;
	
	// Use specified position
	m_dX = (double)sX;
	m_dY = (double)sY;
	m_dZ = (double)sZ;

	m_dVel		= dVel;
	m_dVertVel	= dVertVel;

	// Apply randomizations.
	if (sRandRotSway)
		{
		m_dRot	= rspMod360(dRot + RAND_SWAY(sRandRotSway) );
		}
	else
		{
		m_dRot		= rspMod360(dRot);
		}

	if (sRandVelSway)
		{
		m_dVel	+= RAND_SWAY(sRandVelSway);
		}

	if (sRandVertVelSway)
		{
		m_dVertVel	+= RAND_SWAY(sRandVertVelSway);
		}

	m_lPrevTime	= m_pRealm->m_time.GetGameTime();

	m_type		= type;

	ASSERT(type < NumTypes);
	m_sprite.m_u8Color	= ms_atiChunks[type].u8ColorIndex;
	m_sLen					= ms_atiChunks[type].sLen;

	return sResult;
	}


////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////