|
std::shared_ptr<Object> ReadArchive::read_object(GameVersion version) { |
|
ArchiveObject obj; |
|
if (!this->read_object_begin(obj)) { |
|
ZKLOGE("ReadArchive", "Expected object, got entry."); |
|
return nullptr; |
|
} |
|
|
|
if (obj.class_name == "\xA7") { |
|
if (!this->read_object_end()) { |
|
ZKLOGE("ReadArchive", "Invalid reference object: has children"); |
|
this->skip_object(true); |
|
} |
|
|
|
auto cached = _m_cache.find(obj.index); |
|
if (cached == _m_cache.end()) { |
|
ZKLOGW("ReadArchive", "Unresolved reference: %d", obj.index); |
|
return nullptr; |
|
} |
|
|
|
return cached->second; |
|
} |
|
|
|
if (obj.class_name == "%") { |
|
// This object is marked as "Empty" |
|
this->skip_object(true); |
|
return nullptr; |
|
} |
|
|
|
auto it = OBJECTS.find(obj.class_name); |
|
auto type = ObjectType::unknown; |
|
if (it != OBJECTS.end()) { |
|
type = it->second; |
|
} |
|
|
|
std::shared_ptr<Object> syn; |
|
switch (type) { |
|
case ObjectType::oCNpcTalent: |
|
syn = std::make_shared<VNpc::Talent>(); |
|
break; |
|
case ObjectType::zCEventManager: |
|
syn = std::make_shared<EventManager>(); |
|
break; |
|
case ObjectType::zCDecal: |
|
syn = std::make_shared<VisualDecal>(); |
|
break; |
|
case ObjectType::zCMesh: |
|
syn = std::make_shared<VisualMesh>(); |
|
break; |
|
case ObjectType::zCProgMeshProto: |
|
syn = std::make_shared<VisualMultiResolutionMesh>(); |
|
break; |
|
case ObjectType::zCParticleFX: |
|
syn = std::make_shared<VisualParticleEffect>(); |
|
break; |
|
case ObjectType::zCAICamera: |
|
syn = std::make_shared<VisualCamera>(); |
|
break; |
|
case ObjectType::zCModel: |
|
syn = std::make_shared<VisualModel>(); |
|
break; |
|
case ObjectType::zCMorphMesh: |
|
syn = std::make_shared<VisualMorphMesh>(); |
|
break; |
|
case ObjectType::oCAIHuman: |
|
syn = std::make_shared<AiHuman>(); |
|
break; |
|
case ObjectType::oCAIVobMove: |
|
syn = std::make_shared<AiMove>(); |
|
break; |
|
case ObjectType::zCSkyControler_Outdoor: |
|
syn = std::make_shared<SkyController>(); |
|
break; |
|
case ObjectType::oCCSPlayer: |
|
syn = std::make_shared<CutscenePlayer>(); |
|
break; |
|
case ObjectType::zCVobLevelCompo: |
|
syn = std::make_shared<VLevel>(); |
|
break; |
|
case ObjectType::zCVobStartpoint: |
|
syn = std::make_shared<VStartPoint>(); |
|
break; |
|
case ObjectType::zCVobStair: |
|
syn = std::make_shared<VStair>(); |
|
break; |
|
case ObjectType::zCVobSpot: |
|
syn = std::make_shared<VSpot>(); |
|
break; |
|
case ObjectType::zCVob: |
|
syn = std::make_shared<VirtualObject>(); |
|
break; |
|
case ObjectType::zCVobScreenFX: |
|
syn = std::make_shared<VScreenEffect>(); |
|
break; |
|
case ObjectType::zCCSCamera: |
|
syn = std::make_shared<VCutsceneCamera>(); |
|
break; |
|
case ObjectType::zCCamTrj_KeyFrame: |
|
syn = std::make_shared<VCameraTrajectoryFrame>(); |
|
break; |
|
case ObjectType::zCVobAnimate: |
|
syn = std::make_shared<VAnimate>(); |
|
break; |
|
case ObjectType::zCZoneVobFarPlane: |
|
syn = std::make_shared<VZoneFarPlane>(); |
|
break; |
|
case ObjectType::zCZoneVobFarPlaneDefault: |
|
syn = std::make_shared<VZoneFarPlaneDefault>(); |
|
break; |
|
case ObjectType::zCZoneZFogDefault: |
|
syn = std::make_shared<VZoneFogDefault>(); |
|
break; |
|
case ObjectType::zCZoneZFog: |
|
syn = std::make_shared<VZoneFog>(); |
|
break; |
|
case ObjectType::zCVobLensFlare: |
|
syn = std::make_shared<VLensFlare>(); |
|
break; |
|
case ObjectType::oCItem: |
|
syn = std::make_shared<VItem>(); |
|
break; |
|
case ObjectType::zCTrigger: |
|
syn = std::make_shared<VTrigger>(); |
|
break; |
|
case ObjectType::oCCSTrigger: |
|
syn = std::make_shared<VCutsceneTrigger>(); |
|
break; |
|
case ObjectType::oCMOB: |
|
syn = std::make_shared<VMovableObject>(); |
|
break; |
|
case ObjectType::oCMobInter: |
|
syn = std::make_shared<VInteractiveObject>(); |
|
break; |
|
case ObjectType::oCMobLadder: |
|
syn = std::make_shared<VLadder>(); |
|
break; |
|
case ObjectType::oCMobSwitch: |
|
syn = std::make_shared<VSwitch>(); |
|
break; |
|
case ObjectType::oCMobWheel: |
|
syn = std::make_shared<VWheel>(); |
|
break; |
|
case ObjectType::oCMobBed: |
|
syn = std::make_shared<VBed>(); |
|
break; |
|
case ObjectType::oCMobFire: |
|
syn = std::make_shared<VFire>(); |
|
break; |
|
case ObjectType::oCMobContainer: |
|
syn = std::make_shared<VContainer>(); |
|
break; |
|
case ObjectType::oCMobDoor: |
|
syn = std::make_shared<VDoor>(); |
|
break; |
|
case ObjectType::zCPFXController: |
|
syn = std::make_shared<VParticleEffectController>(); |
|
break; |
|
case ObjectType::zCVobLight: |
|
syn = std::make_shared<VLight>(); |
|
break; |
|
case ObjectType::zCVobSound: |
|
syn = std::make_shared<VSound>(); |
|
break; |
|
case ObjectType::zCVobSoundDaytime: |
|
syn = std::make_shared<VSoundDaytime>(); |
|
break; |
|
case ObjectType::oCZoneMusic: |
|
syn = std::make_shared<VZoneMusic>(); |
|
break; |
|
case ObjectType::oCZoneMusicDefault: |
|
syn = std::make_shared<VZoneMusicDefault>(); |
|
break; |
|
case ObjectType::zCMessageFilter: |
|
syn = std::make_shared<VMessageFilter>(); |
|
break; |
|
case ObjectType::zCCodeMaster: |
|
syn = std::make_shared<VCodeMaster>(); |
|
break; |
|
case ObjectType::zCTriggerList: |
|
syn = std::make_shared<VTriggerList>(); |
|
break; |
|
case ObjectType::oCTriggerScript: |
|
syn = std::make_shared<VTriggerScript>(); |
|
break; |
|
case ObjectType::zCMover: |
|
syn = std::make_shared<VMover>(); |
|
break; |
|
case ObjectType::oCTriggerChangeLevel: |
|
syn = std::make_shared<VTriggerChangeLevel>(); |
|
break; |
|
case ObjectType::zCTriggerWorldStart: |
|
syn = std::make_shared<VTriggerWorldStart>(); |
|
break; |
|
case ObjectType::oCTouchDamage: |
|
syn = std::make_shared<VTouchDamage>(); |
|
break; |
|
case ObjectType::zCTriggerUntouch: |
|
syn = std::make_shared<VTriggerUntouch>(); |
|
break; |
|
case ObjectType::zCEarthquake: |
|
syn = std::make_shared<VEarthquake>(); |
|
break; |
|
case ObjectType::zCMoverController: |
|
syn = std::make_shared<VMoverController>(); |
|
break; |
|
case ObjectType::oCNpc: |
|
syn = std::make_shared<VNpc>(); |
|
break; |
|
case ObjectType::oCWorld: |
|
syn = std::make_shared<World>(); |
|
break; |
|
case ObjectType::zCMaterial: |
|
syn = std::make_shared<Material>(); |
|
break; |
|
case ObjectType::oCSavegameInfo: |
|
syn = std::make_shared<SaveMetadata>(); |
|
break; |
|
case ObjectType::oCCSManager: |
|
syn = std::make_shared<CutsceneManager>(); |
|
break; |
|
case ObjectType::zCCSPoolItem: |
|
syn = std::make_shared<CutscenePoolItem>(); |
|
break; |
|
case ObjectType::zCCutscene: |
|
syn = std::make_shared<Cutscene>(); |
|
break; |
|
case ObjectType::zCCSCutsceneContext: |
|
syn = std::make_shared<CutsceneContext>(); |
|
break; |
|
case ObjectType::zCCSBlock: |
|
syn = std::make_shared<CutsceneBlock>(); |
|
break; |
|
case ObjectType::zCCSAtomicBlock: |
|
syn = std::make_shared<CutsceneAtomicBlock>(); |
|
break; |
|
case ObjectType::zCCSLib: |
|
syn = std::make_shared<CutsceneLibrary>(); |
|
break; |
|
case ObjectType::oCMsgConversation: |
|
syn = std::make_shared<ConversationMessageEvent>(); |
|
break; |
|
case ObjectType::zCCSProps: |
|
syn = std::make_shared<CutsceneProps>(); |
|
break; |
|
#ifdef ZK_FUTURE |
|
case ObjectType::zCWayNet: |
|
syn = std::make_shared<WayNet>(); |
|
break; |
|
case ObjectType::zCWaypoint: |
|
syn = std::make_shared<WayPoint>(); |
|
break; |
|
#endif |
|
default: |
|
ZKLOGE("ReadArchive", "Unknown object type: %s", obj.class_name.c_str()); |
|
break; |
|
} |
|
|
|
if (syn != nullptr) { |
|
// TODO(lmichaelis): The VOb type/id assignment is a hacky workaround! Create separate types! |
|
if (is_vobject(type)) { |
|
auto vtype = static_cast<VirtualObjectType>(type); |
|
reinterpret_cast<VirtualObject*>(syn.get())->type = vtype; |
|
reinterpret_cast<VirtualObject*>(syn.get())->id = obj.index; |
|
} |
|
|
|
_m_cache.insert_or_assign(obj.index, syn); |
|
syn->load(*this, version); |
|
} |
|
|
|
if (!this->read_object_end()) { |
|
ZKLOGW("ReadArchive", "Object not fully loaded: %s", obj.class_name.data()); |
|
this->skip_object(true); |
|
} |
|
|
|
return syn; |
|
} |
ZenKit currently only implement
oCTouchDamagebut not its basezCTouchDamageon its own. This is an issue, becausezCTouchDamageon its own only contains one damage type ("default") and none of the others, which causes parsing to fail if it's just substituted withoCTouchDamage.ZenKit/src/Archive.cc
Lines 255 to 529 in c3d9975
ZenKit/src/vobs/Misc.cc
Lines 198 to 228 in c3d9975