OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
vob.cpp
Go to the documentation of this file.
1#include "vob.h"
2
3#include <Tempest/Log>
4#include <Tempest/Vec>
5
22#include "world/worldlight.h"
23#include "world/world.h"
24#include "game/serialize.h"
25
26using namespace Tempest;
27
29 : world(owner) {
30 }
31
32Vob::Vob(Vob* parent, World& owner, const zenkit::VirtualObject& vob, Flags flags)
33 : world(owner), vobType(vob.type), vobObjectID(vob.id), parent(parent) {
34 pos = Tempest::Matrix4x4(vob.rotation.columns[0].x, vob.rotation.columns[1].x, vob.rotation.columns[2].x, vob.position.x,
35 vob.rotation.columns[0].y, vob.rotation.columns[1].y, vob.rotation.columns[2].y, vob.position.y,
36 vob.rotation.columns[0].z, vob.rotation.columns[1].z, vob.rotation.columns[2].z, vob.position.z,
37 0, 0, 0, 1);
38 local = pos;
39
40 if(parent!=nullptr) {
41 auto m = parent->transform();
42 m.inverse();
43 m.mul(local);
44 local = m;
45 }
46
47 for(auto& i:vob.children) {
48 auto p = Vob::load(this,owner,*i,flags);
49 if(p!=nullptr)
50 child.emplace_back(std::move(p));
51 }
52 }
53
55 }
56
57Vec3 Vob::position() const {
58 return Vec3(pos.at(3,0),pos.at(3,1),pos.at(3,2));
59 }
60
61void Vob::setGlobalTransform(const Matrix4x4& p) {
62 pos = p;
63 local = pos;
64
65 if(parent!=nullptr) {
66 auto m = parent->transform();
67 m.inverse();
68 m.mul(local);
69 local = m;
70 }
71 }
72
73void Vob::setLocalTransform(const Matrix4x4& p) {
74 local = p;
75 recalculateTransform();
76 }
77
78bool Vob::setMobState(std::string_view scheme, int32_t st) {
79 bool ret = true;
80 for(auto& i:child)
81 ret &= i->setMobState(scheme,st);
82 return ret;
83 }
84
86 }
87
88bool Vob::isDynamic() const {
89 return false;
90 }
91
93 return 0;
94 }
95
96void Vob::recalculateTransform() {
97 auto old = position();
98 if(parent!=nullptr) {
99 pos = parent->transform();
100 pos.mul(local);
101 } else {
102 pos = local;
103 }
104 if(old!=position() && !isDynamic()) {
105 switch(vobType) {
106 case zenkit::VirtualObjectType::oCMOB:
107 case zenkit::VirtualObjectType::oCMobBed:
108 case zenkit::VirtualObjectType::oCMobDoor:
109 case zenkit::VirtualObjectType::oCMobInter:
110 case zenkit::VirtualObjectType::oCMobContainer:
111 case zenkit::VirtualObjectType::oCMobSwitch:
112 case zenkit::VirtualObjectType::oCMobLadder:
113 case zenkit::VirtualObjectType::oCMobWheel:
115 break;
116 default:
117 break;
118 }
119 }
120 moveEvent();
121 for(auto& i:child) {
122 i->recalculateTransform();
123 }
124 }
125
126
127std::unique_ptr<Vob> Vob::load(Vob* parent, World& world, const zenkit::VirtualObject& vob, Flags flags) {
128 switch(vob.type) {
129 case zenkit::VirtualObjectType::UNKNOWN:
130 return nullptr;
131 case zenkit::VirtualObjectType::zCVob:
132 case zenkit::VirtualObjectType::zCVobStair:
133 return std::unique_ptr<Vob>(new StaticObj(parent,world,vob,flags));
134 case zenkit::VirtualObjectType::zCVobAnimate:
135 // NOTE: engine animates all objects anyway
136 return std::unique_ptr<Vob>(new StaticObj(parent,world,vob,flags));
137 case zenkit::VirtualObjectType::zCVobLevelCompo:
138 return std::unique_ptr<Vob>(new Vob(parent,world,vob,flags));
139 case zenkit::VirtualObjectType::oCMobFire:
140 return std::unique_ptr<Vob>(new FirePlace(parent,world,reinterpret_cast<const zenkit::VFire&>(vob),flags));
141 case zenkit::VirtualObjectType::oCMOB:
142 // Irdotar bow-triggers
143 // focusOverride=true
144 return std::unique_ptr<Vob>(new Interactive(parent,world,reinterpret_cast<const zenkit::VMovableObject&>(vob),flags));
145 case zenkit::VirtualObjectType::oCMobInter:
146 case zenkit::VirtualObjectType::oCMobBed:
147 case zenkit::VirtualObjectType::oCMobDoor:
148 case zenkit::VirtualObjectType::oCMobContainer:
149 case zenkit::VirtualObjectType::oCMobSwitch:
150 case zenkit::VirtualObjectType::oCMobLadder:
151 case zenkit::VirtualObjectType::oCMobWheel:
152 return std::unique_ptr<Vob>(new Interactive(parent,world,reinterpret_cast<const zenkit::VMovableObject&>(vob),flags));
153
154 case zenkit::VirtualObjectType::zCMover:
155 return std::unique_ptr<Vob>(new MoveTrigger(parent,world,reinterpret_cast<const zenkit::VMover&>(vob),flags));
156 case zenkit::VirtualObjectType::zCCodeMaster:
157 return std::unique_ptr<Vob>(new CodeMaster(parent,world,reinterpret_cast<const zenkit::VCodeMaster&>(vob),flags));
158 case zenkit::VirtualObjectType::zCTriggerList:
159 return std::unique_ptr<Vob>(new TriggerList(parent,world,reinterpret_cast<const zenkit::VTriggerList&>(vob),flags));
160 case zenkit::VirtualObjectType::oCTriggerScript:
161 return std::unique_ptr<Vob>(new TriggerScript(parent,world,reinterpret_cast<const zenkit::VTriggerScript&>(vob),flags));
162 case zenkit::VirtualObjectType::zCTriggerWorldStart:
163 return std::unique_ptr<Vob>(new TriggerWorldStart(parent,world,reinterpret_cast<const zenkit::VTriggerWorldStart&>(vob),flags));
164 case zenkit::VirtualObjectType::oCTriggerChangeLevel:
165 return std::unique_ptr<Vob>(new ZoneTrigger(parent,world,reinterpret_cast<const zenkit::VTriggerChangeLevel&>(vob),flags));
166 case zenkit::VirtualObjectType::zCTrigger:
167 return std::unique_ptr<Vob>(new Trigger(parent,world,vob,flags));
168 case zenkit::VirtualObjectType::zCMessageFilter:
169 return std::unique_ptr<Vob>(new MessageFilter(parent,world,reinterpret_cast<const zenkit::VMessageFilter&>(vob),flags));
170 case zenkit::VirtualObjectType::zCPFXController:
171 return std::unique_ptr<Vob>(new PfxController(parent,world,reinterpret_cast<const zenkit::VParticleEffectController&>(vob),flags));
172 case zenkit::VirtualObjectType::oCTouchDamage:
173 return std::unique_ptr<Vob>(new TouchDamage(parent,world,reinterpret_cast<const zenkit::VTouchDamage&>(vob),flags));
174 case zenkit::VirtualObjectType::zCTriggerUntouch:
175 return std::unique_ptr<Vob>(new Vob(parent,world,vob,flags));
176 case zenkit::VirtualObjectType::zCMoverController:
177 return std::unique_ptr<Vob>(new MoverControler(parent,world,reinterpret_cast<const zenkit::VMoverController&>(vob),flags));
178 case zenkit::VirtualObjectType::zCEarthquake:
179 return std::unique_ptr<Vob>(new Earthquake(parent,world,reinterpret_cast<const zenkit::VEarthquake&>(vob),flags));
180 case zenkit::VirtualObjectType::zCVobStartpoint: {
181 float dx = vob.rotation[2].x;
182 float dy = vob.rotation[2].y;
183 float dz = vob.rotation[2].z;
184 world.addStartPoint(Vec3(vob.position.x,vob.position.y,vob.position.z),Vec3(dx,dy,dz),vob.vob_name);
185 // FIXME
186 return std::unique_ptr<Vob>(new Vob(parent,world,vob,flags));
187 }
188 case zenkit::VirtualObjectType::zCVobSpot: {
189 float dx = vob.rotation[2].x;
190 float dy = vob.rotation[2].y;
191 float dz = vob.rotation[2].z;
192 world.addFreePoint(Vec3(vob.position.x,vob.position.y,vob.position.z),Vec3(dx,dy,dz),vob.vob_name);
193 // FIXME
194 return std::unique_ptr<Vob>(new Vob(parent,world,vob,flags));
195 }
196 case zenkit::VirtualObjectType::oCItem: {
197 if(flags)
198 world.addItem(reinterpret_cast<const zenkit::VItem&>(vob));
199 // FIXME
200 return std::unique_ptr<Vob>(new Vob(parent,world,vob,flags));
201 }
202
203 case zenkit::VirtualObjectType::zCVobSound:
204 case zenkit::VirtualObjectType::zCVobSoundDaytime:
205 case zenkit::VirtualObjectType::oCZoneMusic:
206 case zenkit::VirtualObjectType::oCZoneMusicDefault: {
207 world.addSound(vob);
208 // FIXME
209 return std::unique_ptr<Vob>(new Vob(parent,world,vob,flags));
210 }
211 case zenkit::VirtualObjectType::zCVobLight: {
212 return std::unique_ptr<Vob>(new WorldLight(parent,world,reinterpret_cast<const zenkit::VLight&>(vob),flags));
213 }
214 case zenkit::VirtualObjectType::zCCSCamera:
215 return std::unique_ptr<Vob>(new CsCamera(parent,world,reinterpret_cast<const zenkit::VCutsceneCamera&>(vob),flags));
216 case zenkit::VirtualObjectType::zCCamTrj_KeyFrame:
217 break;
218 case zenkit::VirtualObjectType::zCZoneZFog:
219 case zenkit::VirtualObjectType::zCZoneZFogDefault:
220 break;
221 case zenkit::VirtualObjectType::zCZoneVobFarPlane:
222 case zenkit::VirtualObjectType::zCZoneVobFarPlaneDefault:
223 // wont do: no distance culling in any plans
224 break;
225 case zenkit::VirtualObjectType::zCVobLensFlare:
226 case zenkit::VirtualObjectType::zCVobScreenFX:
227 break;
228 case zenkit::VirtualObjectType::oCNpc:
229 case zenkit::VirtualObjectType::oCCSTrigger:
230 break;
231 }
232
233 return std::unique_ptr<Vob>(new Vob(parent,world,vob,flags));
234 }
235
236void Vob::saveVobTree(Serialize& fin) const {
237 for(auto& i:child)
238 i->saveVobTree(fin);
239 if(vobType==zenkit::VirtualObjectType::zCVob)
240 return;
241 if(vobObjectID!=uint32_t(-1))
242 save(fin);
243 }
244
246 if(fin.version()<43) {
247 if(vobType==zenkit::VirtualObjectType::zCEarthquake ||
248 vobType==zenkit::VirtualObjectType::zCCSCamera)
249 return;
250 }
251
252 for(auto& i:child)
253 i->loadVobTree(fin);
254 if(vobObjectID!=uint32_t(-1) && vobType!=zenkit::VirtualObjectType::zCVob)
255 load(fin);
256 }
257
258void Vob::save(Serialize& fout) const {
259 fout.setEntry("worlds/",fout.worldName(),"/mobsi/",vobObjectID,"/data");
260 fout.write(uint8_t(vobType),pos,local);
261 }
262
264 if(!fin.setEntry("worlds/",fin.worldName(),"/mobsi/",vobObjectID,"/data"))
265 return;
266 auto type = uint8_t(vobType);
267 uint8_t savValue;
268 fin.read(savValue,pos,local);
269
270 if(fin.version() > 41) {
271 if(savValue!=type)
272 throw std::logic_error("inconsistent *.sav vs world");
273 }
274 moveEvent();
275 }
void write(const Arg &... a)
Definition serialize.h:76
bool setEntry(const Args &... args)
Definition serialize.h:57
uint16_t version() const
Definition serialize.h:51
void read(Arg &... a)
Definition serialize.h:81
std::string_view worldName() const
Definition serialize.cpp:87
Definition vob.h:11
virtual void save(Serialize &fout) const
Definition vob.cpp:258
virtual bool setMobState(std::string_view scheme, int32_t st)
Definition vob.cpp:78
uint32_t vobObjectID
Definition vob.h:47
void loadVobTree(Serialize &fin)
Definition vob.cpp:245
virtual bool isDynamic() const
Definition vob.cpp:88
virtual void moveEvent()
Definition vob.cpp:85
zenkit::VirtualObjectType vobType
Definition vob.h:46
Flags
Definition vob.h:13
virtual ~Vob()
Definition vob.cpp:54
World & world
Definition vob.h:45
void setGlobalTransform(const Tempest::Matrix4x4 &p)
Definition vob.cpp:61
void setLocalTransform(const Tempest::Matrix4x4 &p)
Definition vob.cpp:73
static std::unique_ptr< Vob > load(Vob *parent, World &world, const zenkit::VirtualObject &vob, Flags flags)
Definition vob.cpp:127
void saveVobTree(Serialize &fin) const
Definition vob.cpp:236
Vob(World &owner)
Definition vob.cpp:28
auto transform() const -> const Tempest::Matrix4x4 &
Definition vob.h:34
Tempest::Vec3 position() const
Definition vob.cpp:57
virtual float extendedSearchRadius() const
Definition vob.cpp:92
Definition world.h:31
void invalidateVobIndex()
Definition world.cpp:832
Item * addItem(size_t itemInstance, std::string_view at)
Definition world.cpp:609
void addSound(const zenkit::VirtualObject &vob)
Definition world.cpp:820
void addFreePoint(const Tempest::Vec3 &pos, const Tempest::Vec3 &dir, std::string_view name)
Definition world.cpp:816
void addStartPoint(const Tempest::Vec3 &pos, const Tempest::Vec3 &dir, std::string_view name)
Definition world.cpp:812