OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
world.cpp
Go to the documentation of this file.
1#include "world.h"
2
3#include <functional>
4#include <future>
5#include <cctype>
6
7#include <Tempest/Log>
8#include <Tempest/Painter>
9
11#include "graphics/visualfx.h"
13#include "world/objects/npc.h"
14#include "world/objects/item.h"
18#include "game/globaleffects.h"
19#include "game/serialize.h"
20#include "utils/string_frm.h"
21#include "gothic.h"
22#include "focus.h"
23#include "resources.h"
24
25const char* materialTag(ItemMaterial src) {
26 switch(src) {
28 return "WO";
30 return "ST";
32 return "ME";
34 return "LE";
36 return "CL";
38 return "GL";
40 return "UD";
41 }
42 return "UD";
43 }
44
45const char* materialTag(zenkit::MaterialGroup src) {
46 switch(src) {
47 case zenkit::MaterialGroup::UNDEFINED:
48 case zenkit::MaterialGroup::NONE:
49 return "UD";
50 case zenkit::MaterialGroup::METAL:
51 return "ME";
52 case zenkit::MaterialGroup::STONE:
53 return "ST";
54 case zenkit::MaterialGroup::WOOD:
55 return "WO";
56 case zenkit::MaterialGroup::EARTH:
57 return "EA";
58 case zenkit::MaterialGroup::WATER:
59 return "WA";
60 case zenkit::MaterialGroup::SNOW:
61 return "SA"; // sand?
62 }
63 return "UD";
64 }
65
66World::World(GameSession& game, std::string_view file, bool startup, std::function<void(int)> loadProgress)
67 :wname(std::move(file)), game(game), wsound(game,*this), wobj(*this) {
68 const auto* entry = Resources::vdfsIndex().find(wname);
69
70 if(entry == nullptr) {
71 Tempest::Log::e("unable to open Zen-file: \"",wname,"\"");
72 return;
73 }
74
75 try {
76 auto buf = entry->open_read();
77 zenkit::World world;
78 world.load(buf.get(), version().game == 1 ? zenkit::GameVersion::GOTHIC_1
79 : zenkit::GameVersion::GOTHIC_2);
80
81 loadProgress(20);
82 auto& worldMesh = world.world_mesh;
83
84 auto wdynamicFut = std::async(std::launch::async, [&]() {
85 Workers::setThreadName("Loading: BVH thread");
86 return std::unique_ptr<DynamicWorld>(new DynamicWorld(*this,worldMesh));
87 });
88 auto wviewFut = std::async(std::launch::async, [&]() {
89 Workers::setThreadName("Loading: PackedMesh thread");
90 PackedMesh vmesh(worldMesh,PackedMesh::PK_VisualLnd);
91 return std::unique_ptr<WorldView>(new WorldView(*this,vmesh));
92 });
93
94 loadProgress(30);
95
96 {
97 bsp.nodes = std::move(world.world_bsp_tree.nodes);
98 bsp.sectors = std::move(world.world_bsp_tree.sectors);
99 bsp.leaf_node_indices = std::move(world.world_bsp_tree.leaf_node_indices);
100 bsp.sectorsData.resize(bsp.sectors.size());
101 world.world_bsp_tree = zenkit::BspTree();
102 }
103 loadProgress(50);
104
105 wview = wviewFut.get();
106 loadProgress(60);
107
108 wdynamic = wdynamicFut.get();
109 loadProgress(70);
110
111 globFx.reset(new GlobalEffects(*this));
112 wmatrix.reset(new WayMatrix(*this, *world.way_net));
113 for(auto& vob:world.world_vobs)
114 wobj.addRoot(vob,startup);
115
116 wmatrix->buildIndex();
117 loadProgress(100);
118 }
119 catch(...) {
120 Tempest::Log::e("unable to load landscape mesh");
121 throw;
122 }
123 }
124
127
128void World::createPlayer(std::string_view cls) {
129 size_t id = script().findSymbolIndex(cls);
130 if(id==size_t(-1))
131 return;
132 std::string_view waypoint = wmatrix->startPoint().name;
133 auto npc = std::make_unique<Npc>(*this, id, waypoint, NpcProcessPolicy::Player);
134 npcPlayer = wobj.insertPlayer(std::move(npc), waypoint);
135 game.script()->setInstanceNPC("HERO",*npcPlayer);
136 }
137
138void World::insertPlayer(std::unique_ptr<Npc> &&npc, std::string_view waypoint) {
139 if(npc==nullptr)
140 return;
141 npcPlayer = wobj.insertPlayer(std::move(npc),waypoint);
142 game.script()->setInstanceNPC("HERO",*npcPlayer);
143 }
144
146 if(npc==nullptr)
147 return;
149 if(!npcPlayer->isDead()) {
150 npcPlayer->resumeAiRoutine();
151 }
152
154 npc->clearState(true);
155 npc->clearAiQueue();
156
157 for(size_t i=0;i<PERC_Count;++i)
159
160 npcPlayer = npc;
161 }
162
164 // NOTE: level inspector override player stats globaly
165 // lvlInspector.reset(new Npc(*this,script().getSymbolIndex("PC_Levelinspektor"),""));
166
167 // game.script()->inserNpc("Snapper",wmatrix->startPoint().name);
168 }
169
171 fin.setContext(this);
172 fin.setEntry("worlds/",wname,"/world");
173
174 uint32_t sz=0;
175 fin.read(sz);
176 std::string tag;
177 for(size_t i=0;i<sz;++i) {
178 int32_t guild=GIL_NONE;
179 fin.read(tag,guild);
180 if(auto p = portalAt(tag))
181 p->guild = guild;
182 }
183
184 wobj.load(fin);
185 npcPlayer = wobj.findHero();
186 }
187
189 fout.setContext(this);
190 fout.setEntry("worlds/",wname,"/world");
191
192 fout.write(uint32_t(bsp.sectorsData.size()));
193 for(size_t i=0;i<bsp.sectorsData.size();++i) {
194 fout.write(bsp.sectors[i].name,bsp.sectorsData[i].guild);
195 }
196
197 wobj.save(fout);
198 }
199
200uint32_t World::npcId(const Npc *ptr) const {
201 return wobj.npcId(ptr);
202 }
203
204Npc *World::npcById(uint32_t id) {
205 if(id<wobj.npcCount())
206 return &wobj.npc(id);
207 return nullptr;
208 }
209
210uint32_t World::npcCount() const {
211 return uint32_t(wobj.npcCount());
212 }
213
214uint32_t World::mobsiId(const Interactive* ptr) const {
215 return wobj.mobsiId(ptr);
216 }
217
219 if(id<wobj.mobsiCount())
220 return &wobj.mobsi(id);
221 return nullptr;
222 }
223
224uint32_t World::itmId(const void *ptr) const {
225 return wobj.itmId(ptr);
226 }
227
228Item *World::itmById(uint32_t id) {
229 if(id<wobj.itmCount())
230 return &wobj.itm(id);
231 return nullptr;
232 }
233
235 wobj.runEffect(std::move(e));
236 }
237
238void World::stopEffect(const VisualFx& root) {
239 auto* vfx = &root;
240 while(vfx!=nullptr) {
241 globFx->stopEffect(*vfx);
242 vfx = vfx->emFXCreate;
243 }
244 wobj.stopEffect(root);
245 }
246
247GlobalFx World::addGlobalEffect(std::string_view what, uint64_t len, const std::string* argv, size_t argc) {
248 return globFx->startEffect(what,len,argv,argc);
249 }
250
251MeshObjects::Mesh World::addView(std::string_view visual) const {
252 return addView(visual,0,0,0);
253 }
254
255MeshObjects::Mesh World::addView(std::string_view visual, int32_t headTex, int32_t teetTex, int32_t bodyColor) const {
256 return view()->addView(visual,headTex,teetTex,bodyColor);
257 }
258
259MeshObjects::Mesh World::addView(const zenkit::IItem& itm) {
260 return view()->addView(itm.visual,itm.material,0,itm.material);
261 }
262
264 return view()->addView(visual);
265 }
266
267MeshObjects::Mesh World::addAtachView(const ProtoMesh::Attach& visual, const int32_t version) {
268 return view()->addAtachView(visual,version);
269 }
270
271MeshObjects::Mesh World::addStaticView(const ProtoMesh* visual, bool staticDraw) {
272 return view()->addStaticView(visual,staticDraw);
273 }
274
275MeshObjects::Mesh World::addStaticView(std::string_view visual) {
276 return view()->addStaticView(visual);
277 }
278
279MeshObjects::Mesh World::addDecalView(const zenkit::VisualDecal& decal) {
280 return view()->addDecalView(decal);
281 }
282
283LightGroup::Light World::addLight(const zenkit::VLight& vob) {
284 return view()->addLight(vob);
285 }
286
287LightGroup::Light World::addLight(std::string_view preset) {
288 return view()->addLight(preset);
289 }
290
291void World::updateAnimation(uint64_t dt) {
292 wobj.updateAnimation(dt);
293 }
294
298
299std::unique_ptr<Npc> World::takeHero() {
300 return wobj.takeNpc(npcPlayer);
301 }
302
304 return wobj.findItemByInstance(instance,n);
305 }
306
308 return wobj.findNpcByInstance(instance,n);
309 }
310
311std::string_view World::roomAt(const Tempest::Vec3& p) {
312 if(bsp.nodes.empty())
313 return "";
314
315 const auto* node=&bsp.nodes[0];
316
317 while(true) {
318 const auto v = node->plane;
319 float sgn = v.x*p.x + v.y*p.y + v.z*p.z - v.w;
320 uint32_t next = (sgn>0) ? uint32_t(node->front_index) : uint32_t(node->back_index);
321 if(next>=bsp.nodes.size())
322 break;
323
324 node = &bsp.nodes[next];
325 }
326
327 if(node->bbox.min.x <= p.x && p.x <node->bbox.max.x &&
328 node->bbox.min.y <= p.y && p.y <node->bbox.max.y &&
329 node->bbox.min.z <= p.z && p.z <node->bbox.max.z) {
330 return roomAt(*node);
331 }
332
333 return "";
334 }
335
336std::string_view World::roomAt(const zenkit::BspNode& node) {
337 const std::string* ret=nullptr;
338 size_t count=0;
339 auto id = &node-bsp.nodes.data();(void)id;
340
341 for(auto& i:bsp.sectors) {
342 for(auto r:i.node_indices)
343 if(r<bsp.leaf_node_indices.size()){
344 size_t idx = bsp.leaf_node_indices[r];
345 if(idx>=bsp.nodes.size())
346 continue;
347 if(&bsp.nodes[idx]==&node) {
348 ret = &i.name;
349 count++;
350 }
351 }
352 }
353 if(count==1) {
354 // TODO: portals
355 return *ret;
356 }
357 static std::string empty;
358 return empty;
359 }
360
361World::BspSector* World::portalAt(std::string_view tag) {
362 if(tag.empty())
363 return nullptr;
364
365 for(size_t i=0;i<bsp.sectors.size();++i)
366 if(bsp.sectors[i].name==tag)
367 return &bsp.sectorsData[i];
368 return nullptr;
369 }
370
371void World::scaleTime(uint64_t& dt) {
372 globFx->scaleTime(dt);
373 }
374
375void World::tick(uint64_t dt) {
376 static bool doTicks=true;
377 if(!doTicks)
378 return;
379 wobj.tick(dt,dt);
380 wdynamic->tick(dt);
381 wview->tick(dt);
382 if(auto pl = player())
383 wsound.tick(*pl);
384 globFx->tick(dt);
385 }
386
387uint64_t World::tickCount() const {
388 return game.tickCount();
389 }
390
391void World::setDayTime(int32_t h, int32_t min) {
392 gtime now = game.time();
393 auto day = now.day();
394 gtime dayTime = now.timeInDay();
395 gtime next = gtime(h,min);
396
397 if(dayTime<=next){
398 game.setTime(gtime(day,h,min));
399 } else {
400 game.setTime(gtime(day+1,h,min));
401 }
402 wobj.resetPositionToTA();
403 }
404
406 return game.time();
407 }
408
410 Focus ret = def;
411 ret.npc = wobj.validateNpc(ret.npc);
413 ret.item = wobj.validateItem(ret.item);
414
415 return ret;
416 }
417
418Focus World::findFocus(const Npc &pl, const Focus& def) {
419 auto opt = WorldObjects::NoFlg;
420 auto collAlgo = TARGET_COLLECT_FOCUS;
421 auto collType = TARGET_TYPE_ALL;
422 auto& policy = searchPolicy(pl,collAlgo,collType,opt);
423
424 WorldObjects::SearchOpt optNpc {policy.npc_range1, policy.npc_range2, policy.npc_azi, collAlgo, collType, opt};
425 WorldObjects::SearchOpt optMob {policy.mob_range1, policy.mob_range2, policy.mob_azi, collAlgo};
426 WorldObjects::SearchOpt optItm {policy.item_range1, policy.item_range2, policy.item_azi, collAlgo, collType};
427
428 auto n = policy.npc_prio <0 ? nullptr : wobj.findNpcNear (pl,def.npc, optNpc);
429 auto it = policy.item_prio<0 ? nullptr : wobj.findItem (pl,def.item, optItm);
430 auto inter = policy.mob_prio <0 ? nullptr : wobj.findInteractive(pl,def.interactive,optMob);
431 auto ws = pl.weaponState();
432 if(ws==WeaponState::Bow || ws==WeaponState::CBow) {
434 inter = wobj.findInteractive(pl,def.interactive,optMob);
435 }
436
437 if(policy.npc_prio>=policy.item_prio &&
438 policy.npc_prio>=policy.mob_prio) {
439 if(n)
440 return Focus(*n);
441 if(policy.item_prio>=policy.mob_prio && it)
442 return Focus(*it);
443 return inter ? Focus(*inter) : Focus();
444 }
445
446 if(policy.mob_prio>=policy.item_prio &&
447 policy.mob_prio>=policy.npc_prio) {
448 if(inter)
449 return Focus(*inter);
450 if(policy.npc_prio>=policy.item_prio && n)
451 return Focus(*n);
452 return it ? Focus(*it) : Focus();
453 }
454
455 if(policy.item_prio>=policy.mob_prio &&
456 policy.item_prio>=policy.npc_prio) {
457 if(it)
458 return Focus(*it);
459 if(policy.npc_prio>=policy.mob_prio && n)
460 return Focus(*n);
461 return inter ? Focus(*inter) : Focus();
462 }
463
464 return Focus();
465 }
466
468 if(npcPlayer==nullptr || npcPlayer->interactive()!=nullptr)
469 return Focus();
470 return findFocus(*npcPlayer,def);
471 }
472
474 auto opt = WorldObjects::NoFlg;
475 auto collAlgo = TARGET_COLLECT_FOCUS;
476 auto collType = TARGET_TYPE_ALL;
477 auto& policy = searchPolicy(*npcPlayer,collAlgo,collType,opt);
478
479 WorldObjects::SearchOpt optNpc{policy.npc_range1, policy.npc_range2, policy.npc_azi, collAlgo, collType, opt};
480 return wobj.testFocusNpc(*npcPlayer,def,optNpc);
481 }
482
483Interactive *World::availableMob(const Npc &pl, std::string_view name) {
484 return wobj.availableMob(pl,name);
485 }
486
489 optMvMob.rangeMax = 100;
491
492 return wobj.findInteractive(pl,nullptr,optMvMob);
493 }
494
496 wobj.triggerEvent(e);
497 }
498
500 if(e.timeBarrier > this->tickCount()) {
501 triggerEvent(std::move(e));
502 return;
503 }
504
505 bool emitted = wobj.execTriggerEvent(e);
506 if(!emitted) {
507 emitted = wsound.execTriggerEvent(e);
508 }
509
510 if(!emitted) {
511 if(e.target=="EVT_LEFT_ROOM_01_TRAP_MOVER_FOR_DMG_MASTER" ||
512 e.target=="EVT_LEFT_UP_01_TOGGLE_TRIGGER_01" ||
513 e.target=="EVT_RIGHT_ROOM_01_SPAWN_ROT_02_SOUND" ||
514 e.target=="NULL")
515 return; // known problem on dragonisland.zen, skip for now
516 Tempest::Log::d("unable to process trigger: \"",e.target,"\"");
517 }
518 }
519
523
525 wobj.enableTicks(t);
526 }
527
531
533 wobj.setCurrentCs(cs);
534 }
535
537 return wobj.currentCs();
538 }
539
541 if(auto cs = wobj.currentCs())
542 return !cs->isPlayerMovable();
543 return false;
544 }
545
549
553
554void World::triggerChangeWorld(std::string_view world, std::string_view wayPoint) {
555 game.changeWorld(world,wayPoint);
556 }
557
558void World::setMobRoutine(gtime time, std::string_view scheme, int32_t state) {
559 wobj.setMobRoutine(time,scheme,state);
560 }
561
563 wobj.marchInteractives(p);
564 }
565
567 wmatrix->marchPoints(p);
568 }
569
571 wobj.marchCsCameras(p);
572 }
573
575 return game.openDlgOuput(player,npc);
576 }
577
578void World::aiOutputSound(Npc &player, std::string_view msg) {
579 wsound.aiOutput(player.position(),msg);
580 }
581
582bool World::isInDialog() const {
583 return game.isInDialog();
584 }
585
587 return wobj.isTargeted(npc);
588 }
589
590Npc *World::addNpc(std::string_view name, std::string_view at) {
591 size_t id = script().findSymbolIndex(name);
592 if(id==size_t(-1))
593 return nullptr;
594 return wobj.addNpc(id,at);
595 }
596
597Npc *World::addNpc(size_t npcInstance, std::string_view at) {
598 return wobj.addNpc(npcInstance,at);
599 }
600
601Npc* World::addNpc(size_t npcInstance, const Tempest::Vec3& at) {
602 return wobj.addNpc(npcInstance,at);
603 }
604
606 return wobj.removeNpc(npc);
607 }
608
609Item *World::addItem(size_t itemInstance, std::string_view at) {
610 return wobj.addItem(itemInstance,at);
611 }
612
613Item* World::addItem(const zenkit::VItem& vob) {
614 return wobj.addItem(vob);
615 }
616
617Item* World::addItem(size_t itemInstance, const Tempest::Vec3& pos) {
618 return wobj.addItem(itemInstance, pos);
619 }
620
621Item* World::addItemDyn(size_t itemInstance, const Tempest::Matrix4x4& pos, size_t owner) {
622 return wobj.addItemDyn(itemInstance, pos, owner);
623 }
624
625std::unique_ptr<Item> World::takeItem(Item &it) {
626 return wobj.takeItem(it);
627 }
628
630 wobj.removeItem(it);
631 }
632
633size_t World::hasItems(std::string_view tag, size_t itemCls) {
634 return wobj.hasItems(tag,itemCls);
635 }
636
637Bullet& World::shootSpell(const Item &itm, const Npc &npc, const Npc *target) {
638 Tempest::Vec3 dir = {1.f,0.f,0.f};
639 auto pos = npc.position();
640 const VisualFx* vfx = script().spellVfx(itm.spellId());
641 float tgRange = vfx==nullptr ? 0 : vfx->emTrjTargetRange;
642
643 if(target!=nullptr) {
644 auto tgPos = target->centerPosition();
645 if(vfx!=nullptr) {
646 pos = npc.mapBone(vfx->emTrjOriginNode);
647 tgPos = target->mapBone(vfx->emTrjTargetNode);
648 }
649 dir = tgPos-pos;
650 } else {
651 float a = npc.rotationRad()-float(M_PI/2);
652 dir.x = std::cos(a);
653 dir.z = std::sin(a);
654 pos = npc.mapWeaponBone();
655 }
656
657 auto& b = wobj.shootBullet(itm, pos, dir, tgRange, DynamicWorld::spellSpeed);
658 b.setTarget(target);
659 return b;
660 }
661
662Bullet& World::shootBullet(const Item &itm, const Npc &npc, const Npc *target, const Interactive* inter) {
663 Tempest::Vec3 dir = {1.f,0.f,0.f};
664 auto pos = npc.mapWeaponBone();
665
666 if(target!=nullptr) {
667 dir = target->centerPosition() - pos;
668
669 float lxz = std::sqrt(dir.x*dir.x+0*0+dir.z*dir.z);
670 float speed = DynamicWorld::bulletSpeed;
671 float t = lxz/speed;
672
673 dir/=t;
674 dir.y += 0.5f*DynamicWorld::gravity*t;
675 } else
676 if(inter!=nullptr) {
677 auto tgPos = inter->position();
678 dir = tgPos-pos;
679
680 float lxz = std::sqrt(dir.x*dir.x+0*0+dir.z*dir.z);
681 float speed = DynamicWorld::bulletSpeed;
682 float t = lxz/speed;
683
684 dir/=t;
685 dir.y += 0.5f*DynamicWorld::gravity*t;
686 } else {
687 float a = npc.rotationRad()-float(M_PI/2);
688 dir.x = std::cos(a);
689 dir.z = std::sin(a);
690 }
691
692 auto& b = wobj.shootBullet(itm, pos, dir, 0, DynamicWorld::bulletSpeed);
693 b.setTarget(target);
694 return b;
695 }
696
697void World::sendPassivePerc(Npc &self, Npc &other, int32_t perc) {
698 wobj.sendPassivePerc(self,other,nullptr,nullptr,perc);
699 }
700
701void World::sendPassivePerc(Npc& self, Npc& other, Npc& victim, int32_t perc) {
702 wobj.sendPassivePerc(self,other,&victim,nullptr,perc);
703 }
704
705void World::sendPassivePerc(Npc& self, Npc& other, Npc& victim, Item& item, int32_t perc) {
706 wobj.sendPassivePerc(self,other,&victim,&item,perc);
707 }
708
709void World::sendPassivePerc(Npc &self, Npc &other, Item& item, int32_t perc) {
710 wobj.sendPassivePerc(self,other,nullptr,&item,perc);
711 }
712
713void World::sendImmediatePerc(Npc& self, Npc& other, Npc& victim, int32_t perc) {
714 wobj.sendImmediatePerc(self,other,victim,nullptr,perc);
715 }
716
717void World::sendImmediatePerc(Npc& self, Npc& other, Npc& victim, Item& item, int32_t perc) {
718 wobj.sendImmediatePerc(self,other,victim,&item,perc);
719 }
720
721Sound World::addWeaponHitEffect(Npc& src, const Bullet* srcArrow, Npc& reciver) {
722 auto p0 = src.position();
723 auto p1 = reciver.position();
724
725 Tempest::Matrix4x4 pos;
726 pos.identity();
727 pos.translate((p0+p1)*0.5f);
728
729 const char* armor = "FL";
730 if(auto a = reciver.currentArmor()) {
731 auto m = ItemMaterial(a->handle().material);
732 // NOTE: in vanilla only those sfx are defined for armor
734 armor = materialTag(m);
735 }
736
737 if(srcArrow!=nullptr && !srcArrow->isSpell()) {
738 auto m = ItemMaterial(srcArrow->itemMaterial());
739 return addHitEffect(materialTag(m),armor,"IAM",pos);
740 }
741
742 if(auto w = src.inventory().activeWeapon()) {
743 auto m = ItemMaterial(w->handle().material);
744 return addHitEffect(materialTag(m),armor,"IAM",pos);
745 }
746
747 if(src.isMonster())
748 return addHitEffect("JA",armor,"MAM",pos); else
749 return addHitEffect("FI",armor,"MAM",pos);
750 }
751
752Sound World::addLandHitEffect(ItemMaterial src, zenkit::MaterialGroup reciver, const Tempest::Matrix4x4& pos) {
753 // IHI - item hits item
754 // IHL - Item hits Level
755 return addHitEffect(materialTag(src),materialTag(reciver),"IHL",pos);
756 }
757
758Sound World::addWeaponBlkEffect(ItemMaterial src, ItemMaterial reciver, const Tempest::Matrix4x4& pos) {
759 // IAI - item attacks item
760 return addHitEffect(materialTag(src),materialTag(reciver),"IAI",pos);
761 }
762
763Sound World::addHitEffect(std::string_view src, std::string_view dst, std::string_view scheme, const Tempest::Matrix4x4& pos) {
764 Tempest::Vec3 pos3;
765 pos.project(pos3);
766
767 string_frm sound("CS_",scheme,'_',src,'_',dst);
768 auto ret = Sound(*this,::Sound::T_Regular,sound,pos3,2500.f,false);
769
770 string_frm buf("CPFX_",scheme,'_',src,'_',dst);
771 if(Gothic::inst().loadParticleFx(buf,true)==nullptr) {
772 if(dst=="ME")
773 buf = string_frm("CPFX_",scheme,"_METAL");
774 else if(dst=="WO")
775 buf = string_frm("CPFX_",scheme,"_WOOD");
776 else if(dst=="ST")
777 buf = string_frm("CPFX_",scheme,"_STONE");
778 else
779 return ret;
780 }
781 if(Gothic::inst().loadParticleFx(buf,true)==nullptr)
782 return ret;
783
784 Effect e(PfxEmitter(*this,buf),"");
785 e.setObjMatrix(pos);
786 e.setActive(true);
787 runEffect(std::move(e));
788 return ret;
789 }
790
791bool World::isInSfxRange(const Tempest::Vec3& pos) const {
792 return wsound.isInListenerRange(pos,WorldSound::talkRange);
793 }
794
795bool World::isInPfxRange(const Tempest::Vec3& p) const {
796 return wview->isInPfxRange(p);
797 }
798
799void World::addDlgSound(std::string_view s, const Tempest::Vec3& pos, float range, uint64_t& timeLen) {
800 auto sfx = wsound.addDlgSound(s,pos,range,timeLen);
801 sfx.play();
802 }
803
805 wobj.addTrigger(trigger);
806 }
807
809 wobj.addInteractive(inter);
810 }
811
812void World::addStartPoint(const Tempest::Vec3& pos, const Tempest::Vec3& dir, std::string_view name) {
813 wmatrix->addStartPoint(pos,dir,name);
814 }
815
816void World::addFreePoint(const Tempest::Vec3& pos, const Tempest::Vec3& dir, std::string_view name) {
817 wmatrix->addFreePoint(pos,dir,name);
818 }
819
820void World::addSound(const zenkit::VirtualObject& vob) {
821 if(vob.type==zenkit::VirtualObjectType::zCVobSound || vob.type==zenkit::VirtualObjectType::zCVobSoundDaytime) {
822 wsound.addSound(reinterpret_cast<const zenkit::VSound&>(vob));
823 }
824 else if(vob.type==zenkit::VirtualObjectType::oCZoneMusic) {
825 wsound.addZone(reinterpret_cast<const zenkit::VZoneMusic&>(vob));
826 }
827 else if(vob.type==zenkit::VirtualObjectType::oCZoneMusicDefault) {
828 wsound.setDefaultZone(reinterpret_cast<const zenkit::VZoneMusicDefault&>(vob));
829 }
830 }
831
835
836const zenkit::IFocus& World::searchPolicy(const Npc& pl, TargetCollect& collAlgo, TargetType& collType, WorldObjects::SearchFlg& opt) const {
838 collAlgo = TARGET_COLLECT_FOCUS;
839 collType = TARGET_TYPE_ALL;
840
841 switch(pl.weaponState()) {
843 case WeaponState::W1H:
844 case WeaponState::W2H:
846 return game.script()->focusMelee();
847 case WeaponState::Bow:
850 return game.script()->focusRange();
851 case WeaponState::Mage:{
852 if(auto weapon = pl.inventory().activeWeapon()) {
853 int32_t id = weapon->spellId();
854 auto& spl = script().spellDesc(id);
855 collAlgo = TargetCollect(spl.target_collect_algo);
856 collType = TargetType(spl.target_collect_type);
857 }
859 return game.script()->focusMage();
860 }
862 return game.script()->focusNorm();
863 }
864 return game.script()->focusNorm();
865 }
866
867void World::triggerOnStart(bool firstTime) {
868 wobj.triggerOnStart(firstTime);
869 }
870
871const WayPoint *World::findPoint(std::string_view name, bool inexact) const {
872 return wmatrix->findPoint(name,inexact);
873 }
874
875const WayPoint* World::findWayPoint(std::string_view name) const {
876 return wmatrix->findWayPoint(name);
877 }
878
879const WayPoint* World::findWayPoint(const Tempest::Vec3& pos) const {
880 return wmatrix->findWayPoint(pos,[](const WayPoint&){ return true; });
881 }
882
883const WayPoint* World::findWayPoint(const Tempest::Vec3& pos, const std::function<bool(const WayPoint&)>& f) const {
884 return wmatrix->findWayPoint(pos,f);
885 }
886
887const WayPoint* World::findWayPoint(const Tempest::Vec3& pos, std::string_view name) const {
888 return wmatrix->findWayPoint(pos,[name](const WayPoint& wp) -> bool {
889 if(wp.isLocked())
890 return false;
891 if(!wp.checkName(name,false))
892 return false;
893 return true;
894 });
895 }
896
897const WayPoint *World::findFreePoint(const Npc &npc, std::string_view name) const {
898 if(auto p = npc.currentWayPoint()){
899 if(p->isFreePoint() && p->checkName(name)) {
900 return p;
901 }
902 }
903 auto pos = npc.position();
904 pos.y+=npc.translateY();
905
906 return wmatrix->findFreePoint(pos,name,[&npc](const WayPoint& wp) -> bool {
907 if(wp.isLocked())
908 return false;
909 if(!npc.canRayHitPoint(Tempest::Vec3(wp.pos.x,wp.pos.y+10,wp.pos.z),true))
910 return false;
911 return true;
912 });
913 }
914
915const WayPoint *World::findFreePoint(const Tempest::Vec3& pos, std::string_view name) const {
916 return wmatrix->findFreePoint(pos,name,[](const WayPoint& wp) -> bool {
917 if(wp.isLocked())
918 return false;
919 return true;
920 });
921 }
922
923const WayPoint *World::findNextFreePoint(const Npc &npc, std::string_view name) const {
924 auto pos = npc.position();
925 pos.y+=npc.translateY();
926 auto cur = npc.currentWayPoint();
927 if(cur!=nullptr && !cur->checkName(name)) {
928 cur = nullptr;
929 }
930 auto filter = [&](const WayPoint& wp) {
931 if(wp.isLocked() || &wp==cur)
932 return false;
933 if(!npc.canRayHitPoint(Tempest::Vec3(wp.pos.x,wp.pos.y+10,wp.pos.z),true))
934 return false;
935 return true;
936 };
937 auto wp = wmatrix->findFreePoint(pos, name, filter);
938 return wp;
939 }
940
941const WayPoint* World::findNextWayPoint(const Npc &npc) const {
942 auto pos = npc.position();
943 pos.y+=npc.translateY();
944
945 auto nearest = npc.currentWayPoint();
946 if(nearest==nullptr || nearest->isFreePoint()) {
947 nearest = findWayPoint(pos);
948 }
949 auto filter = [&](const WayPoint& wp) {
950 if(!npc.canRayHitPoint(Tempest::Vec3(wp.pos.x,wp.pos.y+10,wp.pos.z),true))
951 return false;
952 return nearest != &wp;
953 };
954 return nearest ? findWayPoint(pos, filter) : nullptr;
955 }
956
957const WayPoint *World::findNextPoint(const WayPoint &pos) const {
958 return wmatrix->findNextPoint(pos.position());
959 }
960
962 return wmatrix->startPoint();
963 }
964
966 return wmatrix->deadPoint();
967 }
968
969void World::detectNpcNear(std::function<void (Npc &)> f) {
970 wobj.detectNpcNear(f);
971 }
972
973void World::detectNpc(const Tempest::Vec3& p, const float r, const std::function<void(Npc&)>& f) {
974 wobj.detectNpc(p.x,p.y,p.z,r,f);
975 }
976
977void World::detectItem(const Tempest::Vec3& p, const float r, const std::function<void(Item&)>& f) {
978 wobj.detectItem(p.x,p.y,p.z,r,f);
979 }
980
981WayPath World::wayTo(const Npc &npc, const WayPoint &end) const {
982 auto npcPos = npc.position();
983 npcPos.y += npc.translateY();
984
985 auto begin = npc.currentWayPoint();
986 if(begin==&end && MoveAlgo::isClose(npc,end)) {
987 return WayPath();
988 }
989 if(begin==&end && !end.isConnected() && npc.canRayHitPoint(end.position()+Tempest::Vec3(0,10,0))) {
990 WayPath ret;
991 ret.add(end);
992 return ret;
993 }
994 if(begin && begin->isConnected() && MoveAlgo::isClose(npc,*begin)) {
995 return wmatrix->wayTo(&begin,1,npcPos,end);
996 }
997 auto near = wmatrix->findWayPoint(npcPos, [&npc](const WayPoint &wp) {
998 if(!npc.canRayHitPoint(Tempest::Vec3(wp.pos.x,wp.pos.y+10,wp.pos.z),true))
999 return false;
1000 return true;
1001 });
1002 if(near==nullptr)
1003 return WayPath();
1004
1005 if(MoveAlgo::isClose(npc,*near) && near==&end)
1006 return WayPath();
1007
1008 std::vector<const WayPoint*> wpoint;
1009 wpoint.push_back(near);
1010 for(auto& i:near->connections()) {
1011 auto p = i.point->position();
1012 if(npc.canRayHitPoint(Tempest::Vec3(p.x,p.y+10,p.z)))
1013 wpoint.push_back(i.point);
1014 }
1015
1016 return wmatrix->wayTo(wpoint.data(),wpoint.size(),npcPos,end);
1017 }
1018
1020 return *game.script();
1021 }
1022
1024 return game.version();
1025 }
1026
1027void World::assignRoomToGuild(std::string_view r, int32_t guildId) {
1028 auto room = std::string(r);
1029 for(auto& i:room)
1030 i = char(std::toupper(i));
1031
1032 if(auto rx=portalAt(room)){
1033 rx->guild=guildId;
1034 return;
1035 }
1036
1037 Tempest::Log::d("room not found: ",room);
1038 }
1039
1040int32_t World::guildOfRoom(const Tempest::Vec3& pos) {
1041 std::string_view tg = roomAt(pos);
1042 if(auto room=portalAt(tg)) {
1043 if(room->guild==GIL_PUBLIC) //FIXME: proper portal implementation
1044 return room->guild;
1045 }
1046 return GIL_NONE;
1047 }
1048
1049int32_t World::guildOfRoom(std::string_view portalName) {
1050 size_t b = portalName.find(':');
1051 if(b==std::string::npos)
1052 return -1;
1053 b++;
1054
1055 size_t e=portalName.find('_');
1056 if(e==std::string::npos || b>e)
1057 return -1;
1058
1059 auto name = portalName.substr(b,e-b);
1060
1061 for(size_t i=0;i<bsp.sectors.size();++i) {
1062 auto& s = bsp.sectors[i].name;
1063 if(s==name)
1064 return bsp.sectorsData[i].guild;
1065 }
1066 return GIL_NONE;
1067 }
ItemMaterial itemMaterial() const
Definition bullet.cpp:94
void setTarget(const Npc *n)
Definition bullet.cpp:90
bool isSpell() const
Definition bullet.cpp:73
bool isPlayerMovable() const
Definition cscamera.cpp:122
static constexpr float bulletSpeed
static constexpr float gravity
static constexpr float spellSpeed
Definition focus.h:10
Npc * npc
Definition focus.h:22
Interactive * interactive
Definition focus.h:21
Item * item
Definition focus.h:23
size_t findSymbolIndex(std::string_view s)
const zenkit::IFocus & focusRange() const
Definition gamescript.h:105
const zenkit::IFocus & focusMage() const
Definition gamescript.h:106
const zenkit::IFocus & focusMelee() const
Definition gamescript.h:104
const zenkit::ISpell & spellDesc(int32_t splId)
const VisualFx * spellVfx(int32_t splId)
void setInstanceNPC(std::string_view name, Npc &npc)
const zenkit::IFocus & focusNorm() const
Definition gamescript.h:103
GameScript * script() const
Definition gamesession.h:46
void changeWorld(std::string_view world, std::string_view wayPoint)
uint64_t tickCount() const
Definition gamesession.h:59
void setTime(gtime t)
bool isInDialog() const
auto version() const -> const VersionInfo &
AiOuputPipe * openDlgOuput(Npc &player, Npc &npc)
gtime time() const
Definition gamesession.h:56
static Gothic & inst()
Definition gothic.cpp:249
Definition item.h:14
int32_t spellId() const
Definition item.cpp:258
static bool isClose(const Npc &npc, const Npc &p, float dist)
Definition movealgo.cpp:709
Definition npc.h:25
void resumeAiRoutine()
Definition npc.cpp:3224
auto mapWeaponBone() const -> Tempest::Vec3
Definition npc.cpp:3374
auto mapBone(std::string_view bone) const -> Tempest::Vec3
Definition npc.cpp:3382
auto weaponState() const -> WeaponState
Definition npc.cpp:3621
float translateY() const
Definition npc.cpp:680
void clearAiQueue()
Definition npc.cpp:4369
auto currentWayPoint() const -> const WayPoint *
Definition npc.h:370
float rotationRad() const
Definition npc.cpp:662
void setPerceptionDisable(PercType t)
Definition npc.cpp:4011
void clearState(bool noFinalize)
Definition npc.cpp:2808
void setProcessPolicy(NpcProcessPolicy t)
Definition npc.cpp:527
bool isDead() const
Definition npc.cpp:3962
auto inventory() const -> const Inventory &
Definition npc.h:330
auto interactive() const -> Interactive *
Definition npc.h:294
auto centerPosition() const -> Tempest::Vec3
Definition npc.cpp:684
auto position() const -> Tempest::Vec3
Definition npc.cpp:628
Item * currentArmor()
Definition npc.cpp:3358
bool isMonster() const
Definition npc.cpp:1227
bool canRayHitPoint(const Tempest::Vec3 pos, bool freeLos=true, float extRange=0.f) const
Definition npc.cpp:4436
static const zenkit::Vfs & vdfsIndex()
void setContext(World *ctx)
Definition serialize.h:68
void write(const Arg &... a)
Definition serialize.h:76
bool setEntry(const Args &... args)
Definition serialize.h:57
void read(Arg &... a)
Definition serialize.h:81
Definition sound.h:5
@ T_Regular
Definition sound.h:8
void play()
Definition sound.cpp:126
std::string target
uint64_t timeBarrier
float emTrjTargetRange
Definition visualfx.h:114
std::string emTrjTargetNode
Definition visualfx.h:113
std::string emTrjOriginNode
Definition visualfx.h:112
Tempest::Vec3 position() const
Definition vob.cpp:57
void add(const WayPoint &p)
Definition waypath.h:15
bool isConnected() const
Definition waypoint.cpp:38
Tempest::Vec3 position() const
Definition waypoint.cpp:52
Tempest::Vec3 pos
Definition waypoint.h:31
bool isLocked() const
Definition waypoint.h:21
bool checkName(std::string_view name, bool inexact=true) const
Definition waypoint.cpp:42
static void setThreadName(const char *threadName)
Definition workers.cpp:66
void resetPositionToTA()
Item * validateItem(Item *def)
void addRoot(const std::shared_ptr< zenkit::VirtualObject > &vob, bool startup)
auto takeItem(Item &it) -> std::unique_ptr< Item >
void addInteractive(Interactive *obj)
void load(Serialize &fout)
void detectNpc(const float x, const float y, const float z, const float r, const std::function< void(Npc &)> &f)
CsCamera * currentCs() const
Interactive & mobsi(size_t i)
void tick(uint64_t dt, uint64_t dtPlayer)
size_t npcCount() const
Item * findItem(const Npc &pl, Item *def, const SearchOpt &opt)
void enableDefTrigger(AbstractTrigger &trigger)
void enableTicks(AbstractTrigger &t)
Item & itm(size_t i)
uint32_t itmId(const void *ptr) const
void addTrigger(AbstractTrigger *trigger)
void updateAnimation(uint64_t dt)
void setMobRoutine(gtime time, std::string_view scheme, int32_t state)
void detectItem(const float x, const float y, const float z, const float r, const std::function< void(Item &)> &f)
void runEffect(Effect &&e)
void removeNpc(Npc &npc)
Npc * findNpcNear(const Npc &pl, Npc *def, const SearchOpt &opt)
void stopEffect(const VisualFx &vfx)
void invalidateVobIndex()
bool isTargeted(Npc &npc)
Interactive * findInteractive(const Npc &pl, Interactive *def, const SearchOpt &opt)
uint32_t npcId(const Npc *ptr) const
Bullet & shootBullet(const Item &itmId, const Tempest::Vec3 &pos, const Tempest::Vec3 &dir, float tgRange, float speed)
bool triggerOnStart(bool firstTime)
Interactive * validateInteractive(Interactive *def)
void marchInteractives(DbgPainter &p) const
uint32_t mobsiId(const void *ptr) const
Item * addItemDyn(size_t itemInstance, const Tempest::Matrix4x4 &pos, size_t owner)
void save(Serialize &fout)
void enableCollizionZone(CollisionZone &z)
const Npc & npc(size_t i) const
Npc * insertPlayer(std::unique_ptr< Npc > &&npc, std::string_view at)
Npc * validateNpc(Npc *def)
Npc * addNpc(size_t itemInstance, std::string_view at)
void setCurrentCs(CsCamera *cs)
void sendPassivePerc(Npc &self, Npc &other, Npc *victim, Item *itm, int32_t perc)
void removeItem(Item &it)
size_t hasItems(std::string_view tag, size_t itemCls)
Npc * findNpcByInstance(size_t instance, size_t n=0)
void sendImmediatePerc(Npc &self, Npc &other, Npc &victim, Item *itm, int32_t perc)
auto takeNpc(const Npc *npc) -> std::unique_ptr< Npc >
bool testFocusNpc(const Npc &pl, Npc *def, const SearchOpt &opt)
bool execTriggerEvent(const TriggerEvent &e)
void disableCollizionZone(CollisionZone &z)
size_t mobsiCount() const
void detectNpcNear(const std::function< void(Npc &)> &f)
Item * findItemByInstance(size_t instance, size_t n=0)
void triggerEvent(const TriggerEvent &e)
Interactive * availableMob(const Npc &pl, std::string_view name)
size_t itmCount() const
void disableTicks(AbstractTrigger &t)
Item * addItem(size_t itemInstance, std::string_view at)
void marchCsCameras(DbgPainter &p) const
void tick(Npc &player)
Sound addDlgSound(std::string_view s, const Tempest::Vec3 &pos, float range, uint64_t &timeLen)
void setDefaultZone(const zenkit::VZoneMusic &vob)
bool isInListenerRange(const Tempest::Vec3 &pos, float sndRgn) const
bool execTriggerEvent(const TriggerEvent &e)
static const float talkRange
Definition worldsound.h:40
void addSound(const zenkit::VSound &vob)
void addZone(const zenkit::VZoneMusic &vob)
void aiOutput(const Tempest::Vec3 &pos, std::string_view outputname)
MeshObjects::Mesh addStaticView(const ProtoMesh *visual, bool staticDraw=false)
MeshObjects::Mesh addDecalView(const zenkit::VisualDecal &vob)
MeshObjects::Mesh addView(std::string_view visual, int32_t headTex, int32_t teethTex, int32_t bodyColor)
MeshObjects::Mesh addAtachView(const ProtoMesh::Attach &visual, const int32_t version)
LightGroup::Light addLight(const zenkit::VLight &vob)
auto version() const -> const VersionInfo &
Definition world.cpp:1023
void sendPassivePerc(Npc &self, Npc &other, int32_t perc)
Definition world.cpp:697
int32_t guildOfRoom(const Tempest::Vec3 &pos)
Definition world.cpp:1040
CsCamera * currentCs() const
Definition world.cpp:536
void save(Serialize &fout)
Definition world.cpp:188
void triggerOnStart(bool firstTime)
Definition world.cpp:867
void addDlgSound(std::string_view s, const Tempest::Vec3 &pos, float range, uint64_t &timeLen)
Definition world.cpp:799
std::vector< zenkit::BspSector > sectors
Definition world.h:207
void runEffect(Effect &&e)
Definition world.cpp:234
void marchCsCameras(DbgPainter &p) const
Definition world.cpp:570
size_t hasItems(std::string_view tag, size_t itemCls)
Definition world.cpp:633
void triggerChangeWorld(std::string_view world, std::string_view wayPoint)
Definition world.cpp:554
void disableCollizionZone(CollisionZone &z)
Definition world.cpp:550
void scaleTime(uint64_t &dt)
Definition world.cpp:371
LightGroup::Light addLight(const zenkit::VLight &vob)
Definition world.cpp:283
void triggerEvent(const TriggerEvent &e)
Definition world.cpp:495
AiOuputPipe * openDlgOuput(Npc &player, Npc &npc)
Definition world.cpp:574
const WayPoint * findNextWayPoint(const Npc &npc) const
Definition world.cpp:941
Interactive * findInteractive(const Npc &pl)
Definition world.cpp:487
bool isTargeted(Npc &npc)
Definition world.cpp:586
void resetPositionToTA()
Definition world.cpp:295
void load(Serialize &fin)
Definition world.cpp:170
MeshObjects::Mesh addAtachView(const ProtoMesh::Attach &visual, const int32_t version)
Definition world.cpp:267
std::string_view roomAt(const Tempest::Vec3 &arr)
Definition world.cpp:311
Interactive * availableMob(const Npc &pl, std::string_view name)
Definition world.cpp:483
Focus validateFocus(const Focus &def)
Definition world.cpp:409
void enableCollizionZone(CollisionZone &z)
Definition world.cpp:546
auto takeHero() -> std::unique_ptr< Npc >
Definition world.cpp:299
WayPath wayTo(const Npc &pos, const WayPoint &end) const
Definition world.cpp:981
uint64_t tickCount() const
Definition world.cpp:387
bool isCutsceneLock() const
Definition world.cpp:540
Npc * addNpc(std::string_view name, std::string_view at)
Definition world.cpp:590
const WayPoint * findNextFreePoint(const Npc &pos, std::string_view name) const
Definition world.cpp:923
void sendImmediatePerc(Npc &self, Npc &other, Npc &victim, int32_t perc)
Definition world.cpp:713
bool isInDialog() const
Definition world.cpp:582
void enableTicks(AbstractTrigger &t)
Definition world.cpp:524
Sound addLandHitEffect(ItemMaterial src, zenkit::MaterialGroup reciver, const Tempest::Matrix4x4 &pos)
Definition world.cpp:752
World()=delete
const WayPoint * findPoint(std::string_view name, bool inexact=true) const
Definition world.cpp:871
uint32_t itmId(const void *ptr) const
Definition world.cpp:224
gtime time() const
Definition world.cpp:405
void detectNpcNear(std::function< void(Npc &)> f)
Definition world.cpp:969
bool testFocusNpc(Npc *def)
Definition world.cpp:473
void invalidateVobIndex()
Definition world.cpp:832
Item * itmById(uint32_t id)
Definition world.cpp:228
void insertPlayer(std::unique_ptr< Npc > &&npc, std::string_view waypoint)
Definition world.cpp:138
Sound addWeaponBlkEffect(ItemMaterial src, ItemMaterial reciver, const Tempest::Matrix4x4 &pos)
Definition world.cpp:758
uint32_t npcId(const Npc *ptr) const
Definition world.cpp:200
uint32_t mobsiId(const Interactive *ptr) const
Definition world.cpp:214
void disableTicks(AbstractTrigger &t)
Definition world.cpp:528
Npc * findNpcByInstance(size_t instance, size_t n=0)
Definition world.cpp:307
bool isInSfxRange(const Tempest::Vec3 &pos) const
Definition world.cpp:791
std::vector< std::uint64_t > leaf_node_indices
Definition world.h:208
WorldSound * sound()
Definition world.h:80
void updateAnimation(uint64_t dt)
Definition world.cpp:291
Item * addItemDyn(size_t itemInstance, const Tempest::Matrix4x4 &pos, size_t owner)
Definition world.cpp:621
void addTrigger(AbstractTrigger *trigger)
Definition world.cpp:804
void removeItem(Item &it)
Definition world.cpp:629
void createPlayer(std::string_view cls)
Definition world.cpp:128
const WayPoint & deadPoint() const
Definition world.cpp:965
void detectItem(const Tempest::Vec3 &p, const float r, const std::function< void(Item &)> &f)
Definition world.cpp:977
Npc * npcById(uint32_t id)
Definition world.cpp:204
~World()
Definition world.cpp:125
std::string_view name() const
Definition world.h:42
void marchPoints(DbgPainter &p) const
Definition world.cpp:566
Item * addItem(size_t itemInstance, std::string_view at)
Definition world.cpp:609
auto takeItem(Item &it) -> std::unique_ptr< Item >
Definition world.cpp:625
void addSound(const zenkit::VirtualObject &vob)
Definition world.cpp:820
GlobalFx addGlobalEffect(std::string_view what, uint64_t len, const std::string *argv, size_t argc)
Definition world.cpp:247
void addFreePoint(const Tempest::Vec3 &pos, const Tempest::Vec3 &dir, std::string_view name)
Definition world.cpp:816
bool isInPfxRange(const Tempest::Vec3 &pos) const
Definition world.cpp:795
void setCurrentCs(CsCamera *cs)
Definition world.cpp:532
void detectNpc(const Tempest::Vec3 &p, const float r, const std::function< void(Npc &)> &f)
Definition world.cpp:973
Interactive * mobsiById(uint32_t id)
Definition world.cpp:218
void stopEffect(const VisualFx &vfx)
Definition world.cpp:238
void tick(uint64_t dt)
Definition world.cpp:375
MeshObjects::Mesh addView(std::string_view visual) const
Definition world.cpp:251
void enableDefTrigger(AbstractTrigger &t)
Definition world.cpp:520
uint32_t npcCount() const
Definition world.cpp:210
const WayPoint * findFreePoint(const Npc &pos, std::string_view name) const
Definition world.cpp:897
const WayPoint & startPoint() const
Definition world.cpp:961
void postInit()
Definition world.cpp:163
void setMobRoutine(gtime time, std::string_view scheme, int32_t state)
Definition world.cpp:558
const WayPoint * findWayPoint(std::string_view name) const
Definition world.cpp:875
void addStartPoint(const Tempest::Vec3 &pos, const Tempest::Vec3 &dir, std::string_view name)
Definition world.cpp:812
void aiOutputSound(Npc &player, std::string_view msg)
Definition world.cpp:578
void setDayTime(int32_t h, int32_t min)
Definition world.cpp:391
MeshObjects::Mesh addStaticView(const ProtoMesh *visual, bool staticDraw)
Definition world.cpp:271
Sound addWeaponHitEffect(Npc &src, const Bullet *srcArrow, Npc &reciver)
Definition world.cpp:721
void setPlayer(Npc *npc)
Definition world.cpp:145
WorldView * view() const
Definition world.h:79
const WayPoint * findNextPoint(const WayPoint &pos) const
Definition world.cpp:957
Item * findItemByInstance(size_t instance, size_t n=0)
Definition world.cpp:303
void assignRoomToGuild(std::string_view room, int32_t guildId)
Definition world.cpp:1027
GameScript & script() const
Definition world.cpp:1019
void marchInteractives(DbgPainter &p) const
Definition world.cpp:562
void removeNpc(Npc &npc)
Definition world.cpp:605
MeshObjects::Mesh addDecalView(const zenkit::VisualDecal &decal)
Definition world.cpp:279
void addInteractive(Interactive *inter)
Definition world.cpp:808
Bullet & shootSpell(const Item &itm, const Npc &npc, const Npc *target)
Definition world.cpp:637
Focus findFocus(const Npc &pl, const Focus &def)
Definition world.cpp:418
void execTriggerEvent(const TriggerEvent &e)
Definition world.cpp:499
Bullet & shootBullet(const Item &itmId, const Npc &npc, const Npc *target, const Interactive *inter)
Definition world.cpp:662
Npc * player() const
Definition world.h:111
gtime timeInDay() const
Definition gametime.h:18
int64_t day() const
Definition gametime.h:17
static CommandLine * instance
@ GIL_PUBLIC
Definition constants.h:27
@ GIL_NONE
Definition constants.h:9
TargetType
Definition constants.h:288
@ TARGET_TYPE_ALL
Definition constants.h:289
TargetCollect
Definition constants.h:277
@ TARGET_COLLECT_FOCUS
Definition constants.h:280
ItemMaterial
Definition constants.h:242
@ MAT_STONE
Definition constants.h:244
@ MAT_WOOD
Definition constants.h:243
@ MAT_METAL
Definition constants.h:245
@ MAT_LEATHER
Definition constants.h:246
@ MAT_CLAY
Definition constants.h:247
@ MAT_GLAS
Definition constants.h:248
@ MAT_COUNT
Definition constants.h:249
PercType
Definition constants.h:396
@ PERC_Count
Definition constants.h:432
const char * materialTag(ItemMaterial src)
Definition world.cpp:25