File: GenericContainer.cpp

package info (click to toggle)
jazz2-native 3.5.0-3
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid
  • size: 16,912 kB
  • sloc: cpp: 172,557; xml: 113; python: 36; makefile: 5; sh: 2
file content (104 lines) | stat: -rw-r--r-- 2,969 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
#include "GenericContainer.h"
#include "../Weapons/TNT.h"
#include "../../ILevelHandler.h"
#include "../../Events/EventSpawner.h"
#include "../../Tiles/TileMap.h"
#include "../../../nCine/Base/Random.h"

using namespace Jazz2::Tiles;

namespace Jazz2::Actors::Solid
{
	GenericContainer::GenericContainer()
	{
	}

	bool GenericContainer::CanCauseDamage(ActorBase* collider)
	{
		return _levelHandler->IsReforged() || runtime_cast<Weapons::TNT>(collider);
	}

	bool GenericContainer::OnPerish(ActorBase* collider)
	{
		SpawnContent();

		return SolidObjectBase::OnPerish(collider);
	}

	void GenericContainer::AddContent(EventType eventType, std::int32_t count, const std::uint8_t* eventParams, std::int32_t eventParamsSize)
	{
		if (count > 0) {
			_content.emplace_back(eventType, count, eventParams, eventParamsSize);
		}
	}

	void GenericContainer::SpawnContent()
	{
		if (_content.empty()) {
			return;
		}

		AABBf aabbExtended = AABB;
		aabbExtended.L -= 20.0f;
		aabbExtended.R += 20.0f;
		aabbExtended.T -= 20.0f;
		TileCollisionParams params = { TileDestructType::None, true };
		auto prevState = GetState();
		SetState(ActorState::CollideWithTileset | ActorState::CollideWithSolidObjects | ActorState::SkipPerPixelCollisions, true);
		SetState(ActorState::IsSolidObject | ActorState::CollideWithSolidObjectsBelow, false);
		SetState(prevState);

		std::int32_t maxCount = 0;
		for (auto& item : _content) {
			if (maxCount < item.Count) {
				maxCount = item.Count;
			}
		}

		bool canThrowFar = (maxCount > 1 && _levelHandler->IsPositionEmpty(this, aabbExtended, params));

		for (auto& item : _content) {
			for (std::int32_t j = 0; j < item.Count; j++) {
				float x, y, fx, fy;
				if (item.Count > 1) {
					if (canThrowFar) {
						fx = Random().NextFloat(-6.0f, 6.0f);
						fy = Random().NextFloat(-0.8f, 0.0f);
						x = _pos.X + fx * (2.0f + _content.size() * 0.1f);
						y = _pos.Y + fy * (12.0f + _content.size() * 0.2f);
					} else {
						fx = Random().NextFloat(-4.0f, 4.0f);
						fy = Random().NextFloat(-0.4f, 0.0f);
						x = _pos.X + fx * (1.0f + _content.size() * 0.1f);
						y = _pos.Y + fy * (4.0f + _content.size() * 0.2f);
					}
				} else {
					fx = 0.0f;
					fy = 0.0f;
					x = _pos.X;
					y = _pos.Y;
				}

				std::shared_ptr<ActorBase> actor = _levelHandler->EventSpawner()->SpawnEvent(item.Type, item.EventParams,
					ActorState::None, Vector3i((std::int32_t)x, (std::int32_t)y, _renderer.layer() - 10));
				if (actor != nullptr) {
					actor->AddExternalForce(fx, fy);
					_levelHandler->AddActor(actor);
				}
			}
		}

		_content.clear();
	}

	GenericContainer::ContainerContent::ContainerContent(EventType eventType, std::int32_t count, const std::uint8_t* eventParams, std::int32_t eventParamsSize)
	{
		Type = eventType;
		Count = count;

		std::memcpy(EventParams, eventParams, eventParamsSize);
		if (eventParamsSize < 16) {
			std::memset(EventParams + eventParamsSize, 0, 16 - eventParamsSize);
		}
	}
}